                           THE C ADVENTURE TOOLKIT
                           =======================

  (a quote from a strange person wearing a rather peculiar orange stetsun)

" Text adventures have now been with us for over a decade, and I strongly
  believe they will be with us for at least another decade. As available 
  hardware has improved, so have adventures. Various forms of graphical 
  adventures have come, and they have gone - but the text adventure is 
  protected by a cult following that will never allow it to die.          "

*******************************************************************************

The C Adventure Toolkit (CAT) is supported on both the IBM PC and Atari ST
families of machines. Both versions are shipped on one 3.5" disk, along with
a cross reference manual (this document) and step by step tutorials. 

The toolkit allows you to define your adventure in a very high level adventure
orientated language, which will then be compiled into C source code that you can
compile into a runnable adventure using your favourite C compiler. The system
has no rigid limitations other than those implied from your C compiler, or
memory limitations. CAT source has been tested on MWC; Sozobon C; and LaserC
on the ST as well as TurboC on the IBM PC. Adventure source can be generated
on the ST and then compiled on the PC, or vice-verser.

The CAT allows any number of characters to be controlled by the user, both
indirectly AND directly. It also allows any number of non player characters 
to interact with each other and/or the player characters. Full compound 
commands are fully acceptable. SCRIPT and VERBOSE modes are supported.

As well as constantly keeping a check on mundane adventure processing 
(such as light sources, compound object weights etc.), CAT provides a very
extensive set of logic control functions with which you can manipulate your
adventure universe to your hearts content.

Because CAT references all objects, rooms, messages and verbs by NAME, and not
number... it is very easy for anyone to look at a CAT source file and know 
instantly what it is doing/affecting. This feature also makes it a lot easier
to write an adventure with CAT, than any other system (no more lists of numbers)

It is a very simple process to convert a CAT adventure to a foreign language.

Registered users of CAT have full rights to sell/distribute any adventures 
that they may have created with the system (see REGISTER.TXT).

*******************************************************************************

Please read the CATINTRO.TXT document for details on how to install CAT, and
what you will need to use it successfully.

This manual is a cross-reference manual. I have provided five step by step
tutorials in the folders CATTUTR1-5 - each of these tutorials builds on the 
topics covered in previous lessons. You should use the tutorials to learn the
syntax of CAT, and then use this document as a future reference. Tutorial
number 5 has a runnable adventure (ADVENT.EXE for PC, ADVENT.PRG for ST).

The rest of this document is ordered alphabetically by keyword.

Advanced users may be interested in the CATEXPRT folder. This details how CAT
logic can be interfaced with custom C code.

*******************************************************************************
* @ADDCOMMAND(obj) * Logic command
******************** 

 Makes obj commandable, and active (allows 'obj, GET HAT'). 

*******************************************************************************
* @ADDCOUNT(cnt,val) * Logic command
**********************

 Add val to counter cnt.

*******************************************************************************
* @ADDPLAYER(obj) * Logic command
******************* 

 Makes obj a player object, and active (allows 'BECOME obj').

*******************************************************************************
* @ADDPOINTS(obj,val) * Logic command
***********************

 Add val to the object points of obj.

*******************************************************************************
* @ADDSTRENGTH(obj,val) * Logic command
*************************

 Add val to the strength of obj.

*******************************************************************************
* @ADDVALUE(obj,val) * Logic command
**********************

 Add val to the value of obj.

*******************************************************************************
* @ADDWEIGHT(obj,val) * Logic command
***********************

 Add val to the weight of obj.

*******************************************************************************
* @BECOME(obj) * Logic command
****************

 Make obj the current player, and the commanding player.

*******************************************************************************
* @BRIEF * Logic command
**********

 Enter BRIEF mode. Long room descriptions will be given the first time a 
 room is entered. After the first visit to a room, only the short description
 will be given, UNLESS the player specifically 'LOOK's.

*******************************************************************************
* CATHELP keyword.. *
*********************

 The program CATHELP has been provided to allow very quick access to this
 document (CATMAN.TXT).

 When you supply keywords to CATHELP, it will scan the manual for headings
 that contain your keywords, and display each of the matching sections.
 You can supply as many keywords as you like.

 For example, the following command would find all topics relating to 
 strings, and messages: CATHELP str msg

 Or this would find details of all definition tokens: CATHELP defin

 Or this would find all details to do with logic: CATHELP logic
 
 Or this command would find the section you are reading now: CATHELP HELP


 CATHELP will look in the current folder, the root folder, the \CAT folder
 and the \CATSRC folder for a CATMAN.TXT file. If it doesn't find the 
 file in any of these folders, it will give up.

     
 If you are running CATHELP from the GEM desktop, then you will have the
 opportunity to type your keywords on the parameters screen.

******************************************************************************
* @CARRIED_WEIGHT(obj) * Logic - return value
************************

 Returns the weight carried by obj. 

******************************************************************************
* CHARACTERS *
**************

 CAT will support any number of characters in your adventure, whether they
 are characters that you can control fully (i.e. BECOME TONY), characters 
 that you can issue commands to (TONY, GIVE THE HAT TO ME), characters that
 are entirely independant of you, or a mixture of the above! This one feature
 sets CAT out from any other adventure development systems.

 An object can be active (@OBJACT) - i.e. alive. 

 An object can be commandable (@OBJCMD) - i.e. the player can get one of 
 his player characters to issue a command to this object. Commandable objects
 are active, by definition.

 An object can be a player object (@OBJPLR) - i.e. the user has full control
 over this object.. it is one of the users entourage in the adventure universe.
 The user can issue 'BECOME object', and from then on all actions will be 
 performed by the selected character. Player objects are active, and commandable
 by definition.

 You can make objects player objects, commandable objects, or active objects
 with the @ADDPLAYER, @ADDCOMMAND, @REVIVE logic tokens. You can remove these
 abilities with @REMOVEPLAYER, @REMOVECOMMAND and @KILL.

 You can find out the current player object with @PLAYER.

 You can find out the commanding object with @CPLAYER - this will be the same
 as @PLAYER, except when one object is commanding another.

 You can find out whether the player is a particular object with @PLAYERIS.

 You can determine whether an object is a player object, commandable or active
 with the @ISPLAYER, @ISCOMMANDABLE and @ISACTIVE logic tokens.

 You can change the current player object, and the commanding player with
 @BECOME.

 You can change the current player object with @CONTROL - this leaves the 
 commanding player unchanged.
 
 When these concepts have sunk in, you will begin to realise that these 
 features can open up whole new dimensions in your adventure games... 
 you could easily have a cast of a dozen characters - all doing their own 
 thing, interacting with each other, or EVEN interacting with you. The 
 possibilities REALLY ARE LIMITLESS! 

 You can easily build logic into your adventure so that Bob will only accept
 commands from Tony, whereas Tony will not accept commands from Bob, but he
 will accept commands from Simon... personality clashes? Pecking order? It's 
 up to you!

******************************************************************************
* @CHECK(C,L,obj) * Logic test
******************* 

  Performs a similar level of checking within CAT logic to that performed by
  verb checking, but this time it is at an object level rather than verb.

  C can be one of: NO_CHECK
                   HERE
                   CARRIED_NOT_WORN
                   WORN
                   AVAIL
                   AVAIL_NOT_WORN
                   CARRIED
                   NOT_CARRIED
                   EXIST

  L can be either @NEED_LIGHT or @NO_LIGHT.

  TRUE will be returned if all the above conditions are passed, otherwise
  FALSE will be returned and an appropriate message printed.

*******************************************************************************
* @CLOSE(obj) * Logic command
***************
 
 Changes the lock type of obj to CLOSED.

******************************************************************************
* @CNOUNIS("text") * Low priority logic test
******************** 

 Returns TRUE if the compound object is a synonym for "text".

 You should avoid this token for the following reasons:
     "text" will not be encrypted.
     @CNOUNNOIS is much faster.

 You should NOT use this token before you have made sure that there is a 
 compound object, with @ISCOMPOUND.

 Only available in low priority processing.

******************************************************************************
* @CNOUNNOIS(obj) * Low priority logic test
******************* 

 Returns TRUE if the compound object number = obj.
 You must use the actual object name, NOT a synonym.

 You should NOT use this token before you have made sure that there is a 
 compound object, with @ISCOMPOUND.

 Only available in low priority processing.

******************************************************************************
* COMPILING *
************* 

 Once your C source has been generated, you will need to copy all the files
 from the \CAT\GENSRC folder into your CSOURCE folder. After this, you can 
 compile your adventure with your favourite C compiler.

 If you are compiling on a PC, you must define PC, and use the large model i.e.
  
   TCC *.c -DPC -ml

 FAILING TO DEFINE PC WHEN COMPILING A PC ADVENTURE WILL RESULT IN FAILURE! 

 Two batch files have been supplied with PC and ST versions of each:
 (ST versions will require a shell program such as Gulam, MSH etc).

 The first batch file (GEN1) generates encrypted C code in CSOURCE, and copies
 all the standard C files from \CAT\GENSRC into CSOURCE.

 The second batch file (GEN2) compiles the C source in CSOURCE, and produces
 the runnable adventure program 'ADVENT' in the current folder.

******************************************************************************
* COMPOUND *
************

 What is a 'compound' command? It's a command that refers to more than one
 object. The following example is NOT a compound command.. It is two 
 non-compound commands 'GET HAT' and 'WEAR HAT'.
 
 GET THE HAT AND WEAR IT.

 The following example IS a compound command, because it refers to more than
 one object:

 TAKE THE HAT FROM THE CHEST.

 We need a mechanism to tell CAT that a verb is a compound verb - so that 
 it does recognise the above example as being compound. A verb can be defined
 as being a 'prepositioner verb' in the verbs definition. I.e. the verb FROM
 has been defined as a prepositioner verb.

 If CAT passes a compound command to low priority logic, the logic test
 @ISCOMPOUND will return TRUE, otherwise it will return FALSE. You should 
 NOT try to refer to the compound verb (@CVERBNOIS) or the compound noun
 (@CNOUNNOIS) until you have established that the command is a compound command
 with the @ISCOMPOUND test.
 
******************************************************************************
* COMPRESSION *
***************

 The GEN program supports switch (-C), which tells it to compress any textual
 words that are more than 4 characters long, into a dictionary. 

 It should be noted that the word 'compression' is notional. Depending on the 
 amount of text in your adventure, you may make the resulting program LARGER
 by compressing! Generally, the more text there is in your adventure, the higher
 the chance that compression will succeed - especially when the same words are
 used many times.

 Using the -C option will cause your generation to take longer, and also your
 finished adventure will run slower. This is because each word of more than
 4 characters has to be 'extracted' from the dictionary before it can be
 displayed/printed. 

******************************************************************************
* @CONFIRM * Logic test
************ 

 Waits for 'Y/y' or 'N/n' to be pressed - determined from the
 contents of messages YES_CHARS and NO_CHARS in ZZRQD.D

 Returns TRUE if 'Y/y' pressed.

*******************************************************************************
* @CONT * Low priority logic command
*********

 Stop processing this command, but keep the command line ready to process the
 next command contained on it. 

 You cannot use @CONT to 'block' room paths (@ROOMPTH) - use @STOP instead. 

*******************************************************************************
* @CONTROL(obj) * Logic command
*****************

 Make obj the current player object, but leave the commanding player as it is.

******************************************************************************
* @COUNT(cnt) * Logic - return value
***************

 Returns the value contained in counter cnt.

******************************************************************************
* COUNTERS * 
************

 CAT provides 500 counters to be used in logic code.
 These are numbered from 0 to 499, and are all initialised to 0 at the start
 of each game - i.e. just before initialisation logic.
 
 Counters 451->499 are reserved for use by the standard files ZZRQD and ZZSTD

 Counter 496 has a special meaning - this is the room where objects 
             should be placed in order to get a score. This defaults to 
             the inventory of the first player character.

 Counter 497 has a special meaning - this is the number of points given
             to the player for things other than object points. You should
             add to this counter if you wish to award extra points.
 
 Counters can be modified with @SETCOUNT, @ADDCOUNT, @SUBCOUNT.
 The value in a counter can be returned with @COUNT.
 
 It is a good idea to refer to counters by object name where appropriate.
 I tend to use counters above 300 for miscellaneous functions, and those 
 below 300 for object related tasks. We can do this because the first object
 is #0, the second is #1 etc. This approach makes a lot more sense, and is 
 far more legible. If we have a counter that says the lamp has run out of
 fuel, it makes sense to SHOW that it is to do with the lamp! E.g.

 @high
 @if @islit(lamp) @do @addcount(lamp,1) @endif
 @if @count(lamp) ge 30 @do @unlight(lamp) @endif

 @low
 @if @verbnois(light) and @nounnois(lamp) and @count(@thisobj) ge 30 @do
    @pmsg(its_out_of_fuel)
    @cont
 @endif

******************************************************************************
* @CPLAYER  * Logic - return value
*************

 Returns the object number of the current player.

******************************************************************************
* @CPLAYERIS(obj) * Logic test
******************* 

 Returns TRUE if the commanding player is obj. If TONY issues the command 
 'BILL, GET THE HAT', then the commanding player will be TONY and the current
 player will be BILL... otherwise the commanding player is the current player.

******************************************************************************
* @CVERBIS("text") * Low priority logic test
********************

 Returns TRUE if the compound verb is a synonym for "text".

 You should avoid this token for the following reasons:
     "text" will not be encrypted.
     @CVERBNOIS is much faster.

 You should NOT use this token before you have made sure that there is a 
 compound verb, with @ISCOMPOUND.

 Only available in low priority processing.

******************************************************************************
* @CVERBNOIS(verb) * Low priority logic test
*******************

 Returns TRUE if the compound verb number = verb.
 You must use the actual verb name, NOT a synonym.

 You should NOT use this token before you have made sure that there is a 
 compound verb, with @ISCOMPOUND.

 Only available in low priority processing.

*******************************************************************************
* DARKNESS *
************

 CAT has a very sophisticated way of automatically checking whether a room 
 is dark or not as follows:

 A room can be defined as being dark via the room definition token @ROOMDRK.

 You can make a dark room light, or a light room dark with @MAKELIGHT,@MAKEDARK
 - this can be viewed as 'switching the light on', or 'opening the window' etc.

 Objects can be defined as being alight with the object definition token
 @OBJLIT, or being lightable with the @OBJLGT object definition token.

 You can light or unlight an object with @LIGHT/@UNLIGHT.

 When you use the @ISDARK logic test, or when CAT checks to see if a room is 
 dark, it does the following:

   1) If the current room is light, then FALSE is returned.

   2) If any object in the current room is alight then FALSE is returned.

   3) If any object in the current room has an in-room, that is neither CLOSED
      nor LOCKED, and any of the objects in this object are alight - then
      FALSE will be returned.

   4) For each of the objects discovered in step 3) above, perform step 3).
      (This is recursive code).

   5) If after checking all possible objects, there are no lit objects
      THEN TRUE will be returned (it is dark).

 The above code effectively means that Bob can be in a dark room. There are
 no immediate sources of light... but Harry is in the same room. Harry is 
 carrying an open chest, which contains an open box, which contains a lit 
 lamp - therefore, the light will emanate to Bob and @ISDARK will return FALSE!
 
*******************************************************************************
* @DO * Logic control
*******

 Signifies the start of a CAT 'Logic command' group.

*******************************************************************************
* @DRINK(obj) * Logic command
***************

 Move obj to the NOWHERE room.

*******************************************************************************
* @DROP(obj) * Logic command
**************

 Move obj to the current players room.

*******************************************************************************
* @EAT(obj) * Logic command
*************

 Move obj to the NOWHERE room.

*******************************************************************************
* EDITOR *
**********

 CAT adventures provide a command line editor, for the user. The following keys
 can be pressed by the users to enter their commands quickly:

     7  8  9
      \ | /     The numeric keypad can be used for directional movement.
                (i.e. 8-North, 3-Southeast etc)
     4- 5 -6 

      / | \     additionally 5-Up and 0-Down.
     1  2  3

      
     [          Repeat last command line

     ]          Delete entire command line

     *          Delete one word from command line

     Ctrl(A)    Repeat last verb
          B     Repeat last noun
          C     Repeat last compound verb
          D     Repeat last compound noun
          E     Examine
          F     Drop
          G     Get
          I     Inventory
          J     Jump
          K     Kill
          L     Look
          N     No
          O     Open
          P     Close
          Q     Quit
          R     Restore
          S     Save
          T     Lock
          U     Unlock
          V     Vocabulary
          W     Whoami
          X     Exits
          Y     Yes
          Z     Copyright line

*******************************************************************************
* @ELSE * Logic control
*********

 Signifies alternative processing for an @IF 'logic control' group.

*******************************************************************************
* ENCRYPTION *
**************

 When you generate your C source from your adventure definition, you can tell
 CAT to encrypt the generated C source code. This is not a sophisticated 
 system, but it ensures that the casual hacker can't read all the secret
 messages etc.

 You can tell CAT to encrypt code by using the '-E' option on the GEN program.

 All text strings will be encrypted, except those in CAT logic.

 When the adventure starts up, it will take a couple of seconds to decrypt
 all the text in the adventure - the title screen will remain on display.

*******************************************************************************
* @ENDCHAR('c') * Logic command
*****************

 The next piece of text that is printed will have character 'c' appended - 
 therefore the following would print 'Hello there!'

 @MSG 	 HELLO
 @MSGTXT Hello there
 @ENDMSG

 @ENDCHAR('!')
 @PMSG(HELLO)

*******************************************************************************
* @ENDGAME * Logic command
************

 Print the score, and turns taken - then end the game.

*******************************************************************************
* @ENDIF * Logic control
**********

 Signifies the end of an @IF/@ELSE 'logic control' group.

 Each @ENDIF must match up to an @IF.

*******************************************************************************
* @ENDMSG * Message definition
***********

 Signifies the end of a message definition.

*******************************************************************************
* @ENDOBJ * Object definition
***********
 
 Signifies the end of an object definition.

*******************************************************************************
* @ENDSTR * String definition
***********

 Signifies the end of a string definition.

*******************************************************************************
* @ENDVERB * Verb definition
************

 Signifies the end of a verb definition.

*******************************************************************************
* @ENTER(obj) * Logic command
***************

 Move the current player to the room pointed to by obj - i.e. the room pointed
 to by @OBJDOOR or @OBJPORTAL. The room is not described on entry.

*******************************************************************************
* @FIRST * Logic control
**********

 Signifies that any following logic is FIRST processing, i.e. it will be 
 executed ONCE as soon as the adventure is loaded - before the title screen
 AND before any decryption has taken place.

******************************************************************************
* @FIRSTOB(room) * Logic - return value
******************

 Returns the number of the first object in room, or -1 if there are no
 objects in room.

*******************************************************************************
* @FVERB("text") * Low priority logic command
******************

 Forces the verb to be "text". For example, in ZZSTD, if the user types 
 'LOOK APPLE' - this is forced to 'EXAMINE APPLE'. In this manner, we only
 need to provide one set of validation logic....

 @IF @VERBNOIS(LOOK) AND @THISOBJ NE -1 @DO @FVERB("EXAMINE") @ENDIF

******************************************************************************
* GEN *
*******

 The main program (GEN.TTP on an ST, or GEN.EXE on a PC), processes your
 adventure definition, and generates C code for your adventure program. 

 When GEN starts up, it looks in the current folder for a file called 
 'GENLIST'. The GENLIST file should contain the names of each definition file
 that is to be used to generate the adventure source. These definition files 
 can have any names, but it would be advisable to use the standard extendor '.d'
 e.g. - file1.d, file2.d file3.d. You can use any number of definition files
 to create your adventure.

 Each line in the GENLIST file can contain a simple file name, or a file 
 with a pathname, and optionally a drive - so a typical GENLIST file may be:

   OBJECTS.D
   ROOMS.D
   MESSAGES.D
   LOGIC.D
   A:\MYSTDS.D
   \CAT\STD\ZZRQD.D 
   \CAT\STD\ZZSTD.D  
                        
 The next thing GEN will do is look for a sub-folder from the current folder,
 called CSOURCE. This is where the generated C code will be placed.  

 If all is okay, GEN will begin it's work. As it works, GEN will display any
 potential errors it encounters on the screen, and these will also be written
 to the file 'GENOUT.TXT'.

 The GEN program has the following command line options:

   -Spath   - use this to specify the source folder. This option is useful if
              you are using GEN via the GEM desktop on the ST. The option
              forces GEN to change directory to the selected folder - i.e.
              the folder where your GENLIST lives. The -S option does not
              allow a drive to be specified.

   -L       - This tells GEN to list the definition source as it processes it.

   -V       - This tells GEN to give a verbose list of all possible errors 
              it discovers. By default, GEN only reports the more rare and
              possibly hazardous errors.

   -E       - This tells GEN to encrypt the code it produces, safe from 
              prying eyes. You should always use this option when producing
              a finished copy of your adventure.

   -C       - This tells GEN to compress the text in your adventure.
              WARNING: compressing adventures with small amounts of text may
                       result in LARGER programs being generated. Compression
                       will be most successful in games with a lot of text.

   -I       - This tells GEN to print the names of all the items that are
              defined. By default, GEN only reports those items that are
              defined but are not directly referred to.

   -F       - This tells GEN to do full logic checks. i.e. it makes sure that
              low priority logic is only used in low priority logic, that 
              logic tests are not used in commands, that logic tokens are
              recognised tokens, etc. This switch is additional to -V.
   
   -R       - Perform a report only run. Do not write any files. This is FAST,
              and allows you to easily check the syntax of your source.

   -Dpath   - Specify the destination path (override default of CSOURCE).
              This can include a drivespec. The path should be direct i.e.
              -DF:\output or relative to the folder to where the GENLIST file
              lives i.e. -Dtest\output. This option is useful if you want to
              direct the output to a ramdrive - much faster!

   -Apath   - Autocopy GENSRC files to destination folder. By default, the 
              GENSRC files will be copied from \CAT\GENSRC, but you can 
              optionally specify the folder where GEN can find GENSRC files.
              The folder can include a drivespec.
 
 GEN -E -I -F
   would look for a GENLIST in the current folder, encrypt all output, and
   produce a list of all the items that were defined. Full logic checking will
   be performed.

 GEN -S\ADVENT -V -L
   would look for a GENLIST in the folder \ADVENT. It would list the definition
   files as it processed them, and give a verbose list of ALL errors. It would
   not encrypt the generated C source. Only those items that are defined but
   not directly referred to will be listed. Full logic checking will not be 
   performed.
 
 GEN -R
   would look for a GENLIST in the current folder, and perform a report run.

 GEN -A -E
   would look for a GENLIST in the current folder, encrypt all output and
   automatically copy the GENSRC files from \CAT\GENSRC.

 GEN -AA:\CAT\GENSRC -S\AWE -Df:\ 
   would look for a GENLIST in \AWE. Output would be created in F:\ - GENSRC
   files would be automatically copied to F:\ from A:\CAT\GENSRC.


 Additionally, GEN switches can be specified in your GENLIST file. Any switches 
 included in the GENLIST file will override conflicting switches from the
 command line.

     For example, the following GENLIST will automatically copy GENSRC from
     \CAT\GENSRC, and output will be encrypted.

     -e
     -a 
     \cattutr5\first.d
     \cattutr1\tutor1.d
     \cattutr2\tutor2.d
     \cattutr3\tutor3.d
     \cattutr4\tutor4.d
     \cattutr5\tutor5.d
     \cat\std\zzstd.d
     \cat\std\zzrqd.d
     \cattutr5\last.d

*******************************************************************************
* @GET(obj) * Logic command
*************

 Move obj to the current players in-room (@OBJINRM).

*******************************************************************************
* @GETSTR(str,size,sep) * Logic command
*************************

 Waits for the user to enter a string, and stores it in str.
 size is a value that defines the maximum number of characters to allow.
 sep can be 1-allow separators, or 0-do not allow separators i.e.

   @Rem get up to 50 characters from the user, allowing separators.

   @GETSTR(mystr,50,1)

 Always be sure that you to do not write past the end of any string.
 
*******************************************************************************
* @GOTO(room) * Logic command
***************

 Move the current player to room. The room will be described.

*******************************************************************************
* @HIDE(obj) * Logic command
**************

 Hide obj - hidden objects will not be shown in inventory lists, room
            descriptions etc. Hidden objects are not picked up by ALL variants
            (e.g. 'GET ALL').

*******************************************************************************
* @HIGH * Logic control
*********

 Signifies that any following logic is HIGH priority processing.

*******************************************************************************
* @IF * Logic control
*******

 Signifies the start of an @IF 'logic control' group.

 Each @IF must match up to an @ENDIF.

*******************************************************************************
* @INIT * Logic control
*********

 Signifies that any following logic is INITialisation processing.

*******************************************************************************
* @INVENTORY * Logic command
**************

 Prints a list of the current players inventory.

******************************************************************************
* @ISACTIVE(obj) * Logic test
******************

 Returns TRUE if obj is active (i.e. alive)

******************************************************************************
* @ISAVAIL(obj) * Logic test
*****************

 Returns TRUE if obj is available (i.e. @ISHERE(obj) or @ISCARRIED(obj))

******************************************************************************
* @ISBOX(obj) * Logic test
***************

 Returns TRUE if obj has an in-room, but is not active.

******************************************************************************
* @ISCARRIED(obj) * Logic test
*******************

 Returns TRUE if obj is being carried by the current player.

******************************************************************************
* @ISCARRIEDANY(obj) * Logic test
**********************

 Returns TRUE if obj is carried by any object. 

******************************************************************************
* @ISCARRIEDBY(obja,objb) * Logic test
***************************

 Returns TRUE if obja is carried by objb. 

 This is identical to @ISIN.

******************************************************************************
* @ISCLOSED(obj) * Logic test
******************

 Returns TRUE if obj is closed.

******************************************************************************
* @ISCOMMANDABLE(obj) * Logic test
***********************

 Returns TRUE if obj is commandable, AND active.
 (i.e. can user type 'obj, GET HAT')

******************************************************************************
* @ISCOMPOUND * Low priority logic test
***************

 Returns TRUE if command is compound i.e. 'TAKE x FROM y'.

 Only available in low priority processing.

******************************************************************************
* @ISDARK * Logic test
***********

 Returns TRUE if it is dark in the current players current room, and there
 are no sources of light available.

******************************************************************************
* @ISDRINKABLE(obj) * Logic test
*********************

 Returns TRUE if obj is drinkable.

******************************************************************************
* @ISEDIBLE(obj) * Logic test
******************

 Returns TRUE if obj is edible.

******************************************************************************
* @ISEXIT(obj) * Logic test
****************

 Returns TRUE if obj is an exit
 (i.e. obj has either @OBJDOOR or @OBJPORTAL defined)

******************************************************************************
* @ISHERE(obj) * Logic test
****************

 Returns TRUE if obj is in the same room as the current player.

******************************************************************************
* @ISHIDDEN(obj) * Logic test
******************

 Returns TRUE if obj is hidden.

******************************************************************************
* @ISIN(obja,objb) * Logic test
********************

 Returns TRUE if obja is inside objb. I.e. is obja in the @OBJINRM of objb?

 This logic test is identical to @ISCARRIEDBY.
                                 
******************************************************************************
* @ISLIGHT(obj) * Logic test
*****************

 Returns TRUE if obj is a light source.

******************************************************************************
* @ISLIT(obj) * Logic test
***************

 Returns TRUE if obj is alight.

******************************************************************************
* @ISLOCKED(obj) * Logic test
******************

 Returns TRUE if obj is locked.

******************************************************************************
* @ISMOVABLE(obj) * Logic test
*******************

 Returns TRUE if obj is movable.

******************************************************************************
* @ISOPEN(obj) * Logic test
****************

 Returns TRUE if obj is open.

******************************************************************************
* @ISPATH(verb) * Logic test
*****************

 Returns TRUE if verb is a valid path.
 (i.e. if verb has been defined as a @ROOMPTH from this room)

******************************************************************************
* @ISPLAYER(obj) * Logic test
******************

 Returns TRUE if obj is a player object, AND active.
 (i.e. can user type 'BECOME obj')

******************************************************************************
* @ISREADABLE(obj) * Logic test
********************

 Returns TRUE if obj is readable.

******************************************************************************
* @ISWEARABLE(obj) * Logic test
********************

 Returns TRUE if obj is wearable.

******************************************************************************
* @ISWITH(obja,objb) * Logic test
**********************

 Returns TRUE if obja is in the same room as objb.

******************************************************************************
* @ISWORN(obj) * Logic test
****************

 Returns TRUE if obj is worn.

******************************************************************************
* @ISWORNANY(obj) * Logic test
*******************

 Returns TRUE if obj is worn by any object.

******************************************************************************
* @ISWORNBY(obja,objb) * Logic test
************************

 Returns TRUE if obja is worn by objb.

******************************************************************************
* ITEM LIST *
*************

 When the GEN program runs, it builds a list of all the defined items.
 (verbs, objects, messages, rooms).
 
 By default, GEN will print a list of all those items that are not referred
 to directly in definitions, or logic. If you use the -I switch on the GEN
 program, it will list ALL items, and signify any that are not directly
 referred to. 

 In the item list, object names will be preceded with 'O_', verbs with 'V_',
 messages with 'M_' and rooms with 'R_'. This is the way CAT holds the names
 internally.

 It is quite normal for objects to not be referred to. Objects will remain 
 unreferenced unless your logic refers to the object specifically... since
 CAT provides so much processing automatically, it is normally the case
 that there are more objects that you do NOT need to refer to!

 Messages will all normally be referred to, except when you have referred to
 them indirectly i.e. @PMSG(@COUNT(305)). You should know which messages you
 have referred to indirectly - any that remain are not required and can be 
 removed!

 If you see any rooms that are not referred to - this is a cause for concern.
 If a room isn't referred to, it implies that the room can never be visited -
 which in turn implies that you do not need the room! The over-ruling and
 rare exception to this is when a room is only referred to indirectly.
 i.e. @GOTO(@COUNT(343))

 The GEN program will also give a list of all those items that HAVE been 
 referred to, but that have not been defined. If you have ANY items in this 
 list, your adventure will not compile!

*******************************************************************************
* @KILL(obj) * Logic command
**************

 Makes obj inactive - i.e. not alive.
       (this will also make @ISPLAYER(obj) and @ISCOMMANDABLE(obj) fail)

*******************************************************************************
* LANGUAGES * converting CAT adventures to a foreign language!
*************

 It is a very easy procedure to fully convert CAT adventures to foreign
 languages. Perform the following steps:

 1) First of all, remember - DO NOT CHANGE ANY NAMES...
    (@OBJ, @ROOM, @MSG, @VERB, @STR).

 2) Translate all text in your definition files, and in ZZRQD, ZZSTD.
    (@MSGTXT, @OBJSHT, @OBJLNG, @ROOMSHT, @ROOMLNG, @STRTXT). Note: The messages
    YES_CHARS and NO_CHARS in ZZRQD determine the keypresses to be checked
    for when @CONFIRM is used (standard is 'Yy' for Yes and 'Nn' for No).

 3) For each object to be translated, leave the original name the same 
    (i.e. @OBJ) - add synonyms for the foreign versions - you can remove
    the English synonyms - BUT only if you know you haven't used these
    synonyms in @NOUNIS or @CNOUNIS! ZZSTD/ZZRQD do not use @NOUNIS/@CNOUNIS.

 4) For each verb to be translated, leave the original name the same 
    (i.e. @VERB) - add synonyms for the foreign versions - you can remove
    the English synonyms - BUT only if you know you haven't used these 
    synonyms in @VERBIS or @CVERBIS! ZZSTD/ZZRQD do not use @VERBIS/@CVERBIS.

 5) PLEASE send me a copy of your translated ZZSTD/ZZRQD files, so that
    I can send a copy to all registered users of CAT.

 6) Regenerate your adventure, and you're done!

*******************************************************************************
* @LAST * Logic control
*********

 Signifies that any following logic is LAST processing, i.e. it will be
 executed ONCE just before the adventure program ends.

******************************************************************************
* @LASTOB(room) * Logic - return value
*****************

 Returns the number of the last object in room, or -1 if there are no
 objects in room.

*******************************************************************************
* @LC * Logic control
*******

 This token can be used to ensure that each @IF has a matching @ENDIF, and
 that each @WHILE has a matching @WEND. The @LC token should only be used 
 at points where you think there are no @IF/@WHILEs remaining open.

*******************************************************************************
* @LF * Logic command
*******

 Print a linefeed character (same as @NEWLINE).

*******************************************************************************
* LIGHT *
*********

 See darkness.
 
*******************************************************************************
* @LIGHT(obj) * Logic command
***************

 Make obj a light source, and lit.

*******************************************************************************
* LIMITATIONS *
***************

 CAT has the following limitiations:
 -----------------------------------

 Maximum length of text strings                 = 255 characters
 (possibly higher dependant on C compiler)
 
 Maximum number of messages                     = 32767

 Maximum number of objects                      = 32767

 Maximum number of rooms                        = 32766

 Maximum number of verbs                        = 32767

 Maximum number of active objects               = 32767

 Maximum number of commandable objects          = 32767

 Maximum number of player objects               = 32767

 Maximum number of strings                      = 100

 
 Note: It should be obvious from the above that the CAT system itself is
       very flexible and will allow potentially HUGE adventures to be created..
       the only limiting factors that need be considered are any specific
       contraints on program size from your C compiler, and also the amount
       of memory available.

*******************************************************************************
* @LOAD * Logic command
*********

 Ask for an 8 character filename, and load saved game. (extendor is .SAV)

*******************************************************************************
* @LOCK(obj) * Logic command
**************

 Change the lock type of obj to LOCKED.

*******************************************************************************
* @LOCKTYPE(obj) * Logic - return value
******************

 Returns the lock type of obj. I.e. LOCKED, CLOSED, OPEN, NO_LOCK.

*******************************************************************************
* LOGIC *
*********

 CAT supports five distinct flavours of logic processing. These are
 first time round logic, initialisation logic, low priority logic, high
 priority logic and last time round logic. These modes can be switched between
 using the @FIRST, @INIT, @LOW, @HIGH and @LAST tokens.

 First time round logic is executed ONCE PER LOAD OF THE PROGRAM - before the
 title is printed AND before decryption takes place. This can be used for 
 system level initialisation.

 Initialisation logic is executed ONCE PER GAME before the first player command.
 This can be used to initialise the game status, or display a welcome screen.

 Low priority logic is executed ONCE FOR EACH VALID COMMAND that it stripped
 from the command line that the user entered. Only low priority logic has
 the ability to interrogate the commands that the user enters.

 High priority logic is executed after every turn, regardless of whether 
 successful or not. This can be used to code events that are not directly
 related to the players command.

 Last time round logic is executed ONCE PER LOAD OF THE PROGRAM, just before
 the program ends and returns to the calling program, or the operating system.
 This can be used to restore the original state of the system.

 You can alter the flow of CAT logic by using logic control tokens and 
 logic comparison tokens.

*******************************************************************************
* LOGIC COMMANDS *
******************

 CAT logic commands do whatever they are told to do. No checking is performed
 - they presume that any checking that was required has already been made.

 The following tokens can be used to instruct CAT logic to perform a task:

   Available in any logic mode
   ---------------------------
   @ADDCOMMAND(obj)
   @ADDPLAYER(obj)
   @ADDSTRENGTH(obj,val)
   @ADDVALUE(obj,val)
   @ADDWEIGHT(obj,val)
   @BECOME(obj)
   @BRIEF
   @CLOSE(obj)
   @CONTROL(obj)
   @DRINK(obj)
   @DROP(obj)
   @EAT(obj)
   @ENDCHAR('c')
   @ENDGAME
   @ENTER(obj)
   @GET(obj)
   @GOTO(room)
   @HIDE(obj)
   @INVENTORY
   @KILL(obj)
   @LF
   @LIGHT(obj)
   @LOAD
   @LOCK(obj)
   @LOOK
   @MAKEDARK(room)
   @MAKELIGHT(room)
   @NEWLINE
   @OPEN(obj)
   @PAUSE(sec)
   @PCONTENTS(obj)
   @PEXITS
   @PMSG(msg)
   @POBJL(obj)
   @POBJS(obj)
   @PROOML(room)
   @PROOMS(room)
   @PNUM(val)
   @RAMLOAD
   @RAMSAVE
   @READ(obj)
   @REMOVE(obj)
   @REMOVECOMMAND(obj)
   @REMOVEPLAYER(obj)
   @REVIVE(obj)
   @SAVE
   @SCRIPT
   @SETSTRENGTH(obj,val)
   @SETVALUE(obj,val)
   @SETWEIGHT(obj,val)
   @SUBSTRENGTH(obj,val)
   @SUBVALUE(obj,val)
   @SUBWEIGHT(obj,val)
   @SWAP(obja,objb)
   @UNHIDE(obj)
   @UNLIGHT(obj)
   @UNLOCK(obj)
   @UNSCRIPT
   @VERBOSE
   @VOCAB
   @WAITKEY
   @WEAR(obj)
   @WHOAMI

   Low priority logic only
   -----------------------
   @CONT
   @FVERB("text")
   @STOP

******************************************************************************
* LOGIC COMPARISONS *
********************* 

 The following can be used to compare values returned by CAT logic, in 
 conjunction with logic control tokens:

 	Equals                          EQ              ==
     	Does not equal                  NE              !=
	Is less than                    LT              <
 	Is less than or equal to        LE              <=
	Is greater than                 GT              >
	Is greater than or equal to     GE              >=
	Or                              OR              ||
	And                             AND             &&
	Not				NOT             !

 Whenever you use NOT, you should protect the condition with ( and ).
 i.e. @IF (NOT @PLAYERIS(BOB)) @DO

*******************************************************************************
* LOGIC CONTROL *
*****************

 The following tokens can be used in conjuction with logic comparison tokens to 
 affect the flow of CAT logic.

   @FIRST
   @INIT
   @LOW
   @HIGH
   @LAST

   @IF
   @ELSE
   @ENDIF
   @WHILE
   @WEND
   @DO
   @LC

*******************************************************************************
* LOGIC RETURN VALUES *
***********************

 The following tokens can be used to return values to CAT logic:

   Available in any logic mode
   ---------------------------
   @CARRIED_WEIGHT(obj)
   @COUNT(cnt)
   @CPLAYER 
   @FIRSTOB(room)
   @LASTOB(room)
   @MSGNO(msg)
   @OBJINRM(obj)
   @OBJKEY(obj)
   @OBJLCK(obj)
   @OBJNO(obj)
   @OBJRM(obj)
   @PLAYER
   @POINTS(obj)
   @RANDOM(x)
   @ROOMNO(room)
   @SCORE 
   @SIZE(obj)
   @STRENGTH(obj)
   @THISROOM
   @TURNS 
   @VALUE(obj)
   @VERBPATH(verb)
   @WEIGHT(obj)
   
   Low priority logic only
   -----------------------
   @THISCOBJ 
   @THISCVERB
   @THISOBJ 
   @THISVERB

*******************************************************************************
* LOGIC TESTS *
***************

 The following tokens can be used to perform TRUE/FALSE tests in CAT logic.

   Available in any logic mode
   ---------------------------
   @CHECK(C,L,obj)
   @CONFIRM
   @CPLAYERIS(obj)
   @ISACTIVE(obj)
   @ISAVAIL(obj)
   @ISBOX(obj)
   @ISCARRIED(obj)
   @ISCARRIEDANY(obj)
   @ISCARRIEDBY(obja,objb)
   @ISCLOSED(obj)
   @ISCOMMANDABLE(obj)
   @ISDARK
   @ISDRINKABLE(obj)
   @ISEDIBLE(obj)
   @ISEXIT(obj)
   @ISHERE(obj)
   @ISHIDDEN(obj)
   @ISIN(obja,objb)
   @ISLIGHT(obj)
   @ISLIT(obj)
   @ISLOCKED(obj)
   @ISMOVABLE(obj)
   @ISOPEN(obj)
   @ISPATH(verb)
   @ISPLAYER(obj)
   @ISREADABLE(obj)
   @ISWEARABLE(obj)
   @ISWITH(obja,objb)
   @ISWORN(obj)
   @ISWORNANY(obj)
   @ISWORNBY(obja,objb)
   @OBJHASL(obj)
   @OBJROOMIS(room,obj)
   @PLAYERIS(obj)
   @ROOMIS(room)
   
   Low priority logic only
   -----------------------
   @CNOUNIS("text")
   @CNOUNNOIS(obj)
   @CVERBIS("text")
   @CVERBNOIS(verb)
   @ISCOMPOUND
   @NOUNIS("text")
   @NOUNNOIS(obj)
   @VERBIS("text")
   @VERBNOIS(verb)

*******************************************************************************
* @LOOK * Logic command
*********

 Print a long room description for the current players room.
 List any non-hidden objects.

*******************************************************************************
* @LOW * Logic control
********

 Signifies that any following logic is LOW priority processing.

*******************************************************************************
* MACROS * Macros within text
**********

@rem As well as 'LF', other macros can be included in any piece of text - these
     will be expanded whenever the text is displayed as follows:

     $1, $2, $3, $4 etc. - replaced with value in 1st, 2nd, 3rd, 4th string etc.

     #1, #2, #3, #4 etc. - replaced with value of 1st, 2nd, 3rd, 4th counter etc

     $A                  - replaced with the actor, from command line.

     $V                  - replaced with verb, from command line.

     $VC                 - replaced with compound verb, from command line.

     $N                  - replaced with noun, from command line.

     $NC                 - replaced with compound noun, from command line.

@rem For example, the following would print:

     BOB: "I have no time to PUT KEY IN BED" ...

     (If the user issued the command 'bob, put the key in the bed')

     @str    tmp_str		@Rem String number 11 (1-10 already defined)
     @strtxt I have no
     @endstr

     @msg    tmp_msg
     @msgtxt $A: "$11 time to $V $N $VC $NC" ...
     @endmsg

     @low
        @if @playeris(bob) @do 
           @pmsg(tmp_msg)
        @endif

*******************************************************************************
* @MAKEDARK(room) * Logic command
*******************

 Make room dark.

*******************************************************************************
* @MAKELIGHT(room) * Logic command
********************

 Make room light.

*******************************************************************************
* MESSAGE (msg) DEFINITION *
****************************

 The following tokens can be used to define messages:

   @MSG name
   @MSGTXT text
   @ENDMSG
 
*******************************************************************************
* @MSG name * Message (msg) definition
*************

 Starts the definition of a message, where 'name' is the name of the message.
 See NAMES for more details.

******************************************************************************
* @MSGNO(msg) * Logic - return value
***************

 Returns the message number of msg.

*******************************************************************************
* @MSGTOSTR(msg,str) * Logic command
**********************

 Copy msg into str.

 Always be sure that you to do not write past the end of any string.
 
 You should always use @STRNO to pass the second parameter as a string, or 
 otherwise GEN will presume that it refers to an object. For example:

   @MSGTOSTR(msg,@STRNO(str))

*******************************************************************************
* @MSGTXT text * Message (msg) definition
****************

 Describes the text behind the message that is currently being defined.
 
 You can include 'LF' in messages - this will print a linefeed character.
 See MACROS for additional information.

*******************************************************************************
* NAMES *
*********

 CAT allows all references to objects, verbs, rooms and messages to be made
 by NAME - rather than number. This means you can refer to the master_bedroom
 rather than room number 56, or the You_have_died message rather than message
 number 264. This feature is a tremendous advantage when developing, or indeed
 when viewing another authors CAT source code.

 All names allow each of the letters of the alphabet (A through Z). No 
 differentiation is made between upper and lower case. The underbar character
 (_) is allowed in names, and it has a different meaning for each type of item:

 Rooms
 -----
 No special meaning.

 Messages
 --------
 No special meaning.

 Verbs
 -----
 Used to define two word verbs, for example 'PUT ON' for 'WEAR' would 
 be given the name PUT_ON. You can only use ONE underbar in a verb name. The
 user doesn't know that the underbar is there, and cannot enter one - he just
 knows that he wants to 'PUT ON' something.

 Objects
 -------
 Used to QUALIFY objects, for example a 'RED KEY' would be called RED_KEY.
 You can only use ONE underbar in an object name. The user doesn't know that
 the underbar is there, and cannot enter one - he just knows he wants to refer
 to a 'RED KEY'. See QUALIFIERS for more details.

*******************************************************************************
* @NEWLINE * Logic command
************

 Print a linefeed character (same as @LF).

******************************************************************************
* @NOUNIS("text") * Low priority logic test
******************* 
 
 Returns TRUE if the object is a synonym for "text".

 You should avoid this token for the following reasons:
     "text" will not be encrypted.
     @NOUNNOIS is much faster.

 Only available in low priority processing.

******************************************************************************
* @NOUNNOIS(obj) * Low priority logic test
******************

 Returns TRUE if the object number = obj.
 You must use the actual verb name, NOT a synonym.

 Only available in low priority processing.

*******************************************************************************
* NOUNS *
*********

 Within CAT, a noun is just a users reference to an object. 

*******************************************************************************
* @NUMTOSTR(val,str) * Logic command
**********************

 Convert val to a string, and store it in str.

 Always be sure that you to do not write past the end of any string.
 
 You should always use @STRNO to pass the second parameter as a string, or 
 otherwise GEN will presume that it refers to an object. For example:

   @NUMTOSTR(123,@STRNO(str))

*******************************************************************************
* @OBJ name * Object definition
*************

 Starts the definition of an object, where 'name' is the name of the object.
 See NAMES for more details.

*******************************************************************************
* @OBJACT * Object definition
***********

 Sets the object to ACTIVE, i.e. 'alive'. By default, the player can give 
 things to active objects. An object will automatically default to being 
 active if it is defined with either @OBJPLR or @OBJCMD. The default is 
 not-active.

 All active objects should have an in-room defined (their inventory).

*******************************************************************************
* @OBJCMD * Object definition
***********

 Sets the object to commandable. If an object is commandable, the user can
 command the object with 'object, GET HAT'. If @OBJCMD is selected, @OBJACT
 is automatically selected. The default is not-commandable.

 All commandable objects should have an in-room defined (their inventory).

*******************************************************************************
* @OBJDOOR roomname1,roomname2 * Object definition
********************************

 Makes the object a door between the rooms roomname1 and roomname2. By default,
 objects are not doors.

 CAT automatically sorts out which room a door should be in - because a door
 is effectively in TWO rooms, it has to be moved to where it is currently
 needed. Whenever a player enters a room, CAT checks to see if there should
 be any doors here. If an object is a door, you needn't bother with @OBJROOM.

*******************************************************************************
* @OBJDRINK val * Object definition
*****************

 Makes the object drinkable, where the players strength will be affected by
 val if he does drink it. The default is non-drinkable.

*******************************************************************************
* @OBJEAT val * Object definition
***************

 Makes the object edible, where the players strength will be affected by val
 if he does eat it. The default is non-edible.

******************************************************************************
* OBJECT DEFINITION *
*********************

 The following tokens are available to define objects:

   @OBJ name
   @OBJACT
   @OBJCMD
   @OBJDOOR roomname1,roomname2
   @OBJDRINK val
   @OBJEAT val
   @OBJHIDE
   @OBJINRM roomname
   @OBJKEY objname
   @OBJLCK open/closed/locked
   @OBJLGT
   @OBJLIT
   @OBJLNG text
   @OBJNGT
   @OBJPLR
   @OBJPNT val
   @OBJPORTAL roomname
   @OBJREAD msgname
   @OBJROOM roomname
   @OBJSHT text
   @OBJSTR val
   @OBJSYN synname..
   @OBJVAL val
   @OBJWEAR
   @OBJWGT val
   @OBJWORN
   @ENDOBJ

******************************************************************************
* @OBJHASL(obj) * Logic test
*****************

 Returns TRUE if obj has any long text defined, as defined by @OBJLNG.

*******************************************************************************
* @OBJHIDE * Object definition
************

 Makes the object hidden. Hidden objects are not displayed in inventory lists,
 or room descriptions, they will not be picked up by 'ALL' variants, BUT the
 player can still interact with them in the same way as any other object - 
 if he realises they are there! The default is not-hidden.

*******************************************************************************
* @OBJINRM roomname * Object definition
*********************

 Defines the objects in-room - the room in which objects that are carried by
 this object will be placed. The default @OBJINRM for an object is NOWHERE - 
 this means that the object does not have an in-room.

 If an object doesn't have an @OBJINRM, then it cannot hold/contain anything.

******************************************************************************
* @OBJINRM(obj) * Logic - return value
*****************

 Returns the in-room for obj, or NOWHERE if the object has no in-room.

*******************************************************************************
* @OBJKEY objname * Object definition
*******************

 Defines the object that is required to lock/unlock this object.
 
 @OBJKEY has no effect if the object has no @OBJLCK defined.

 The default for @OBJKEY is NO_KEY - i.e. object cannot be locked/unlocked.

******************************************************************************
* @OBJKEY(obj) * Logic - return value
****************

 Returns the number of the object required to lock/unlock obj, or NO_KEY
 if obj does not have a lock.

*******************************************************************************
* @OBJLCK open/closed/locked * Object definition
******************************

 Defines the object lock type of the object (OPEN/CLOSED/LOCKED/NO_LOCK).
 The default of NO_LOCK means that the object cannot be locked/closed/opened.

 Just because an object doesn't have a lock type, that DOESN'T mean that the
 player can't enter it/put things in it - if OBJDOOR/OBJPORTAL/OBJINRM are 
 defined - for example a doorway, or a pond.

******************************************************************************
* @OBJLCK(obj) * Logic - return value
****************

 Returns the lock type of obj. Could be any of: LOCKED, CLOSED, OPEN, NO_LOCK.
 NO_LOCK means that the object cannot be locked/unlocked/open/closed.

*******************************************************************************
* @OBJLGT * Object definition
***********

 Defines the object as being a lightsource, but not currently lit.
 The default is non-lightsource.

*******************************************************************************
* @OBJLIT * Object definition
***********

 Defines the object as being a lightsource, AND being lit.
 The default is not-lit.

*******************************************************************************
* @OBJLNG text * Object definition
****************

 Describes the long text for the object.
 Blank text will be added if this is omitted. When the object is examined,
 the user will be told 'You don't see anything unusual'.

 You can include 'LF' in object text - this will print a linefeed character.
 See MACROS for additional information.

*******************************************************************************
* @OBJNGT * Object definition
***********

 Signifies that the object cannot be taken/dropped/given. This is a derivation
 of @OBJWGT. It effectively gives the object a weight of 32767 - which is a 
 special value and should be avoided!

******************************************************************************
* @OBJNO(obj) * Logic - return value
***************

 Returns the object number of obj.

*******************************************************************************
* @OBJPLR * Object definition
***********

 Defines the object as being a player object i.e. user can 'BECOME object'.
 If @OBJPLR is selected, @OBJCMD and @OBJACT will automatically be selected.
 
 All player objects should have an in-room defined (their inventory).

*******************************************************************************
* @OBJPNT val * Object definition
***************

 Defines the number of points that the object is worth. The default is 0.

*******************************************************************************
* @OBJPORTAL roomname * Object definition
***********************

 Describes the room that the current player will be moved to if he ENTERs this
 object. By default, the object is not a portal.

*******************************************************************************
* @OBJREAD msgname * Object definition
********************

 Makes this object readable. Message msgname will be displayed if the player
 reads this object. By default, objects are not readable.

******************************************************************************
* @OBJRM(obj) * Logic - return value
***************

 Returns the room number that obj is currently in.

*******************************************************************************
* @OBJROOM roomname * Object definition
*********************

 Defines the starting room for the object. The default starting room for an 
 object is the NOWHERE room.

******************************************************************************
* @OBJROOMIS(room,obj) * Logic test
************************

 Returns TRUE if obj is in room.

*******************************************************************************
* @OBJSHT text * Object definition
****************

 Describes the short text for the object. This should always be given, if 
 the object can ever be seen.

 You can include 'LF' in object text - this will print a linefeed character.
 See MACROS for additional information.

*******************************************************************************
* @OBJSTR val * Object definition
***************

 Defines the strength of the object. The default is 0. You should be careful
 to define an @OBJSTR for any object that has an in-room (players,boxes etc) -
 or they will not be able to carry anything!

*******************************************************************************
* @OBJSYN synname.. * Object definition
*********************

 Describes synonyms for the object. An object may have many synonyms. The 
 default is that an object has no synonyms. Object synonyms are like object 
 names - see NAMES for further details.

*******************************************************************************
* @OBJVAL val * Object definition
***************

 Defines the value of this object, the default being 0.

*******************************************************************************
* @OBJWEAR * Object definition
************

 Makes this object wearable, but not worn. The default is not wearable.

*******************************************************************************
* @OBJWGT val * Object definition
***************

 Defines the weight of this object. The default weight is 0. 

*******************************************************************************
* @OBJWORN * Object definition
************

 Makes this object wearable, AND worn. The default is not worn.

*******************************************************************************
* @OLTOSTR(obj,str) * Logic command
*********************

 Copy object long text into str.

 Always be sure that you to do not write past the end of any string.
 
 You should always use @STRNO to pass the second parameter as a string, or 
 otherwise GEN will presume that it refers to an object. For example:

   @OLTOSTR(obj,@STRNO(str))

*******************************************************************************
* @OPEN(obj) * Logic command
**************

 Changes the lock type of this object to OPEN.

*******************************************************************************
* ORDER OF PROCESSING *
***********************

 All modes of logic are processed in the order that they were encountered
 by GEN - therefore the order of files in your GENLIST can be important.

 First time round logic will be processed as soon as the program loads.
 This will only happen ONCE - as soon as the program is loaded.

   At the start of each game, CAT processes initialisation logic. 

   Each time a valid command is found (i.e. @VERBLGT and @VERBCHK passed),
   then low priority logic will be processed - UNTIL either an @STOP or an
   @CONT token is processed. If @STOP is found, the command line will be
   scrapped, if @CONT is found, the command line is kept.

   If low priority logic was not stopped by @STOP, then CAT will check to see
   if the verb is a valid path from the room - and if it is then the player will
   be moved to whichever room the path leads to.

   After each command (whether valid or not), high priority logic is processed.

   CAT will continue to find another command on the command line, or request
   a new command line if the current line has been exhausted or scrapped.
 
 Just before the program ends, last time round logic is executed.

*******************************************************************************
* @OSTOSTR(obj,str) * Logic command
*********************

 Copy object short text into str.

 Always be sure that you to do not write past the end of any string.
 
 You should always use @STRNO to pass the second parameter as a string, or 
 otherwise GEN will presume that it refers to an object. For example:

   @OSTOSTR(obj,@STRNO(str))

*******************************************************************************
* @PAUSE(sec) * Logic command
***************

 Pause processing for sec seconds.

*******************************************************************************
* @PCONTENTS(obj) * Logic command
*******************

 Prints all objects that are in the in-room of obj.

*******************************************************************************
* @PEXITS * Logic command
***********

 Print all the obvious exits leading from the current players room.
 (i.e. @ROOMPTHs).

******************************************************************************
* @PLAYER * Logic - return value
***********

 Returns the object number of the current player.

******************************************************************************
* @PLAYERIS(obj) * Logic test
******************

 Returns TRUE if the current player is obj.

******************************************************************************
* PLAYERS *
***********

 See characters.

*******************************************************************************
* @PMSG(msg) * Logic command
**************
 
 Print the message called msg.
 
*******************************************************************************
* @PNUM(val) * Logic command
**************

 Print the integer value val.

*******************************************************************************
* @POBJL(obj) * Logic command
***************

 Print the long description of obj.

*******************************************************************************
* @POBJS(obj) * Logic command
***************

 Print the short description of obj.

******************************************************************************
* @POINTS(obj) * Logic - return value
****************

******************************************************************************
* PORTABILILITY * Porting CAT adventures to another compiler/computer
***************** 

 In theory, it should be a relatively easy job to convert CAT adventures to
 work with another compiler or machine. All machine specific code can be found
 in \cat\gensrc\portab.i - this has been commented as to its' purpose in life,
 so C programmers should be able to determine what is required.

*******************************************************************************
* @PROOML(room) * Logic command
*****************

 Print the long description of room.

*******************************************************************************
* @PROOMS(room) * Logic command
*****************

 Print the short description of room.

*******************************************************************************
* @PSTR(str) * Logic command
**************

 Print the text contained in str.

******************************************************************************
* QUALIFIERS *
**************

     Qualifiers
     ---------- 

     You can have any number of objects with the same unqualified name
     (i.e. RED KEY, GREEN KEY, YELLOW KEY), as long as their qualifiers are
     unique, i.e. a RED key, a BLUE key, a YELLOW key etc. Note however, that
     if you have a qualified object, you cannot have an unqualified object of
     the same name, i.e. you could not have a red key and a key.

     CAT will do the following if the player gives an unqualified name:
     
        If there is more than one object available with this unqualified name,
        then each of the objects will be listed and the player will be asked
        to be more specific.
        
        If there is only one object available with this unqualified name, then
        CAT will presume that this is the object the player is refering to.
        
        If there are no objects available with this unqualified name, but
        there are some in the adventure universe (i.e. in any room other than
        NOWHERE), then CAT will presume that the player is refering to the 
        first one of these it can find.

        If there are no objects in the adventure universe with this
        unqualified name, then CAT will presume that the player is refering to
        the first object of the same name that is in the NOWHERE room.
        
     Qualified objects are very easy to define, The underbar (_) separates 
     the qualifier, and the unqualified name. (see NAMES).


     Dummy qualifiers
     ----------------

     It is possible to give an object a two character qualifier (aa->zz).
     Within CAT, you must always refer to the object with it's qualified name,
     but the player will never see the qualifier. This allows several objects
     that 'seem' to have the same name.

     CAT will regard any two character qualifier as a 'dummy' qualifier.

     For example, you may want 'a door' to appear in different rooms.
     You may define one door as AA_DOOR, and the other as AB_DOOR.

     Dummy qualifiers will only work if each of the objects with a dummy
     qualifier can NEVER be in the same room as any other object with the
     same unqualified name. If two such objects did happen to be in 
     the same room, the player would not be able to qualify them, but CAT
     would insist that the player was more specific! Uno problema!
     OBJNGT is a good way of ensuring this rule is met. 

     Using dummy qualifiers, you COULD have a RED DOOR and a DOOR, as
     long as they are in different rooms. The RED door would be defined as 
     RED_DOOR, and the DOOR would be defined as AA_DOOR, XY_DOOR, BQ_DOOR etc.
     (the player would never see the AA, XY, BQ etc).

******************************************************************************
* @RAMLOAD * Logic command
************

 Load a previously saved game position from RAM. This command will fail with
 a suitable message if there is no saved game position in RAM.

******************************************************************************
* @RAMSAVE * Logic command
************

 Save the game position to RAM. If there is insufficient memory available,
 this command will fail with a suitable message.

******************************************************************************
* @RANDOM(x) * Logic - return value
**************

 Returns a random value between 1 and x inclusive.

*******************************************************************************
* @READ(obj) * Logic command
**************

 Prints the message attached to this object, defined via @OBJREAD.

*******************************************************************************
* @REM text * Remark
*************

 Any following text is a remark.

*******************************************************************************
* @REMOVE(obj) * Logic command
****************

 Make obj wearable, but not worn.

*******************************************************************************
* @REMOVECOMMAND(obj) * Logic command
***********************

 Remove command from obj (i.e. do not allow 'obj, GET HAT'). 

*******************************************************************************
* @REMOVEPLAYER(obj) * Logic command
**********************

 Make obj a non-player object (i.e. do not allow 'BECOME obj').

*******************************************************************************
* @REVIVE(obj) * Logic command
****************

 Make obj active - 'alive'.

*******************************************************************************
* @RLTOSTR(room,str) * Logic command
**********************

 Copy room long text into str.

 Always be sure that you to do not write past the end of any string.
 
 You should always use @STRNO to pass the second parameter as a string, or 
 otherwise GEN will presume that it refers to an object. For example:

   @RLTOSTR(obj,@STRNO(str))

*******************************************************************************
* ROOM DEFINITION *
*******************

 The following tokens can be used to define rooms:

   @ROOM name
   @ROOMDRK
   @ROOMLNG text
   @ROOMPNT val
   @ROOMPTH verbname,roomname..
   @ROOMSHT text
   @ENDROOM

 CAT automatically supplies a room called NOWHERE. Objects in the NOWHERE room
 are effectively out of the adventure universe. You should not create any 
 paths that lead into the NOWHERE room!

*******************************************************************************
* @ROOM name * Room definition
**************

 Starts the definition of a room, where 'name' is the name of the room.
 See NAMES for more details.

*******************************************************************************
* @ROOMDRK * Room definition
************

 Defines the room as being dark. The default is light.

******************************************************************************
* @ROOMIS(room) * Logic test
*****************

 Returns TRUE if the current room is room.

*******************************************************************************
* @ROOMLNG text * Room definition
*****************

 Describes the long text for the room. If you give no long text for a room,
 the short text will be used.

 You can include 'LF' in room text - this will print a linefeed character.
 See MACROS for additional information.

******************************************************************************
* @ROOMNO(room) * Logic - return value
*****************

 Returns the room number of room.

*******************************************************************************
* @ROOMPNT val * Room definition
****************

 Defines the number of points the player will be awarded when he enters this 
 room AND it is not dark. The default is 0 points.

*******************************************************************************
* @ROOMPTH verbname,roomname.. * Room definition
********************************

 Defines the paths leading from the room (verbname), and the rooms to which 
 they lead. There may be many paths leading from one room. The default is that
 there are no paths leading from a room.

*******************************************************************************
* @ROOMSEEN(room) * Logic test
*******************

 Returns TRUE, if a long description has been displayed for room, or FALSE
 if the long description has not been displayed.

*******************************************************************************
* @ROOMSHT text * Room definition
*****************

 Describes the short text for the room. You should always define a short 
 description for a room, if the room can EVER be visited.

 You can include 'LF' in room text - this will print a linefeed character.
 See MACROS for additional information.

*******************************************************************************
* @RSTOSTR(room,str) * Logic command
**********************

 Copy room short text into str.

 Always be sure that you to do not write past the end of any string.
 
 You should always use @STRNO to pass the second parameter as a string, or 
 otherwise GEN will presume that it refers to an object. For example:

   @RSTOSTR(obj,@STRNO(str))

*******************************************************************************
* @SAVE * Logic command
*********

 Ask for an 8 character filename, and save game position. (extendor is .SAV)

******************************************************************************
* @SCORE  * Logic - return value
***********

 Returns the current score.

******************************************************************************
* SCORING *
***********

 A room can be given a number of points with @ROOMPNT. When the player enters
 this room and it is not dark, he will be awarded these points.

 An object can be given a number of points with @OBJPNT. When the player puts
 this object in the designated object points room, then the player will be 
 awarded a score.
 
   By default, the object points room will be the in-room of the first 
   player object. You can change this by setting counter 496 to the number
   of another room - i.e. @SETCOUNT(496,@ROOMNO(IN_BED)) will change the object
   points room to IN_BED - the objects have to be in the bed for the player
   to qualify for the points.

 In addition to the above, you can award the player points for completing 
 tasks, or deduct points when help is given etc. These arbitrary points are 
 stored in counter 497 - i.e. @ADDCOUNT(497,10) would add 10 to the players
 score, and @SUBCOUNT(497,1) would deduct 1 from the players score.

*******************************************************************************
* @SCRIPT * Logic command
***********

 Start script mode - all output will be echoed to the printer.

*******************************************************************************
* @SETCOUNT(cnt,val) * Logic command
**********************

 Set counter cnt to val.

*******************************************************************************
* @SETPOINTS(obj,val) * Logic command
***********************

 Set the object points of obj to val.

*******************************************************************************
* @SETSTRENGTH(obj,val) * Logic command
*************************

 Set the strength of obj to val.

*******************************************************************************
* @SETVALUE(obj,val) * Logic command
**********************

 Set the value of obj to val.

*******************************************************************************
* @SETWEIGHT(obj,val) * Logic command
***********************

 Set the weight of obj to val.

******************************************************************************
* @SIZE(obj) * Logic - return value
**************

 Returns the size of obj. This is the basic weight of the object - 
                          not including carried weight.

*******************************************************************************
* @STOP * Low priority logic command
*********

 Stop processing this command, and kill the rest of the command. 

 @STOP can be used to stop players from taking an exit defined as a @ROOMPTH -
       there may be a huge green slime monster in the way!

*******************************************************************************
* @STR name * String definition
*************

 Starts the definition of a string, where 'name' is the name of the string.
 See NAMES for more details.

******************************************************************************
* @STRADDC(str,c) * Logic command
*******************

 Add character c onto the end of str.

 Always be sure that you to do not write past the end of any string.
 
*******************************************************************************
* @STRASC(str) * Logic - return value
****************

 Returns the ascii value of the first character in str.

******************************************************************************
* @STRCAP(str) * Logic command
****************

 Convert the first character of str to upper case.

******************************************************************************
* @STRCAT(str1,str2) * Logic command
**********************

 Concatenates str2 onto the end of str1.

 Always be sure that you to do not write past the end of any string.
 
 You should always use @STRNO to pass the second parameter as a string, or 
 otherwise GEN will presume that it refers to an object. For example:

   @STRCAT(str1,@STRNO(str2))

******************************************************************************
* @STRCLR(str) * Logic command
****************

 Clear str.

******************************************************************************
* @STRCMP(str1,str2) * Logic - return value
**********************

 Compares str1 and str2. Returns 0 if the strings match, <0 if str1 is less
 than str2, or >0 if str1 is greater than str2.

 You should always use @STRNO to pass the second parameter as a string, or 
 otherwise GEN will presume that it refers to an object. For example:

   @STRCMP(str1,@STRNO(str2))

******************************************************************************
* @STRCPY(str1,str2) * Logic command
**********************

 Copy str2 into str1.

 Always be sure that you to do not write past the end of any string.
 
 You should always use @STRNO to pass the second parameter as a string, or 
 otherwise GEN will presume that it refers to an object. For example:

   @STRCPY(str1,@STRNO(str2))

******************************************************************************
* @STRENGTH(obj) * Logic - return value
******************

 Returns the strength of obj.

******************************************************************************
* @STRFCHR(str,c) * Logic - return value
*******************

 Returns the position of the first occurence of character c in str, or -1 if
 no matches. 
 
 Remember, the first character of a string is in position 0, and so on.

******************************************************************************
* @STRFSTR(str1,str2) * Logic - return value
***********************

 Returns the position of the first occurence of str2 in str1, or -1 if
 no matches. 

 Remember, the first character of a string is in position 0, and so on.

 You should always use @STRNO to pass the second parameter as a string, or 
 otherwise GEN will presume that it refers to an object. For example:

   @STRFSTR(str1,@STRNO(str2))

******************************************************************************
* STRING DEFINITION *
*********************

 The following tokens are available to define strings:

   @STR name
   @STRSIZE val
   @STRTXT text
   @ENDSTR

 Ten strings are created for you automatically by GEN. These ten strings are 
 the only strings that will be saved with saved game positions - so you should
 use these strings to hold variable information that is relevant to the current
 state of the game. You can of course define your own strings, but you should 
 only use these to contain permanent unchanging data, or temporary data.
 The ten automatic strings have names and sizes as follows:
 
   S1       200 characters
   S2       200 characters
   S3       100 characters
   S4       100 characters
   S5       100 characters 
   S6       100 characters
   S7        50 characters
   S8        50 characters
   S9        50 characters
   S10       50 characters
 
   *** WARNINGS ***

   When referring to a CAT string, you are actually referring to a number,
   it is therefore very important that you do not use standard C functions 
   to access them - always use the CAT logic tokens.

   The first character of a string is in position 0, and NOT 1.

   With any string functions where a string name appears anywhere other than
   as the first parameter, you must use @STRNO to convert the parameter
   to a string - otherwise CAT will presume the parameter is the number of
   an object. I.e.

      @rem Copy characters 10-14 from MY_STRING into S1.

      @STRPCPY(s1,@strno(my_string),10,5)

   It is your responsibility to ensure that you do not write past the end
   of any given string - i.e. if a string is defined with @STRSIZE 50, 
   then make sure it never contains more that 50 characters. 
   IF THIS HAPPENS, UNPREDICTABLE RESULTS MAY OCCUR!

*******************************************************************************
* @STRLEN(str) * Logic - return value
****************

 Returns the length of str.

******************************************************************************
* @STRLOW(str) * Logic command
****************

 Convert str to lower case.

*******************************************************************************
* @STRNO(str) * Logic - return value
***************

 Returns the string number of str.

*******************************************************************************
* @STRNUM(str) * Logic - return value
****************

 Returns the integer value contained in str, or an undefined result if 
 str does not contain a number.

******************************************************************************
* @STRPCPY(str1,str2,start,len) * Logic command
*********************************

 Copy part of str2 into str1.
     start=start position in str2.
     len= number of characters to copy.

 Remember, the first character of a string is in position 0, and so on.

 Always be sure that you to do not write past the end of any string.
 
 You should always use @STRNO to pass the second parameter as a string, or 
 otherwise GEN will presume that it refers to an object. For example:

   @STRPCPY(str1,@STRNO(str2),10,2)

*******************************************************************************
* @STRSIZE val * String definition 
****************

 Defines the size in characters of the string that is currently being defined.

 The default size for a string is 254 characters, and this is also the 
 maximum size for a single string.

*******************************************************************************
* @STRTXT text * String definition
****************

 Describes the initial text for the string that is currently being defined.
 By defauly, a string is blank.
 
 You can include 'LF' in strings - this will print as a linefeed character.
 See MACROS for additional information.

******************************************************************************
* @STRUPP(str) * Logic command
****************

 Convert str to upper case.

*******************************************************************************
* @SUBCOUNT(cnt,val) * Logic command
**********************

 Subtract val from counter cnt.

*******************************************************************************
* @SUBPOINTS(obj,val) * Logic command
***********************

 Subtract val from the object points of obj.

*******************************************************************************
* @SUBSTRENGTH(obj,val) * Logic command
*************************

 Subtract val from the strength of obj.

*******************************************************************************
* @SUBVALUE(obj,val) * Logic command
**********************

 Subtract val from the value of obj.

*******************************************************************************
* @SUBWEIGHT(obj,val) * Logic command
***********************

 Subtract weight from the weight of obj.

*******************************************************************************
* @SWAP(obja,objb) * Logic command
********************

 Swap the rooms of obja and objb.

******************************************************************************
* @THISCOBJ * Low priority logic - return value
*************

 Return the number of the compound object referred to by the user, or -1 if 
 no object was referred to.

 You should only use this after you have determined that the command is 
 compound via the @ISCOMPOUND token.

 Only available in low priority logic.
 
******************************************************************************
* @THISCVERB * Low priority logic - return value
**************

 Returns the number of the compound verb referred to by the user, or -1 if
 no compound verb was used.

 You should only use this after you have determined that the command is 
 compound via the @ISCOMPOUND token.

 Only available in low priority logic.

******************************************************************************
* @THISOBJ * Low priority logic - return value
************

 Returns the number of the object referred to by the user, or -1 if no
 object was referred to.

 Only available in low priority logic.

******************************************************************************
* @THISROOM * Logic - return value
*************

 Returns the room number of the current players current room.

******************************************************************************
* @THISVERB * Low priority logic - return value
*************

 Returns the number of the verb referred to by the user, or -1 if no verb
 was used. (should never happen!)

 Only available in low priority logic.

******************************************************************************
* TITLE *
*********

 When your adventure starts up, it will look in the current directory for 
 a file called TITLE.TXT. If it finds this file, it will centre the text
 lines and display them on screen whilst decryption is taking place.

 You can use this feature to include your own little welcome screen. 
 For an example, see TITLE.TXT in the \CATTUTR5 folder.

******************************************************************************
* TOKENS *
**********

 When CAT reads a definition file, it looks for 'tokens', and other words. 
 A token is just a word that CAT recognises. CAT tokens generally begin with
 the @ character. For example, the following line contains the token '@OBJPNT',
 and the word '500'.

 @OBJPNT 500

******************************************************************************
* @TOROOM(room,obj) * Logic command
*********************

 Move obj to room. 
 
******************************************************************************
* @TURNS  * Logic - return value
***********

 Returns the number of turns taken.

*******************************************************************************
* @UNHIDE(obj) * Logic command
****************

 Unhide obj - hidden objects will not be shown in inventory lists, room
              descriptions etc. Hidden objects are not picked up by ALL
              variants (e.g. 'GET ALL').

*******************************************************************************
* @UNLIGHT(obj) * Logic command
*****************

 Make obj a light source, but NOT alight.

*******************************************************************************
* @UNLOCK(obj) * Logic command
****************

 Change the lock type of obj to CLOSED.

*******************************************************************************
* @UNSCRIPT * Logic command
*************

 End script mode - output will not be echoed to the printer.

******************************************************************************
* @VALUE(obj) * Logic - return value
***************

 Returns the value of obj.

*******************************************************************************
* VERB DEFINITION *
*******************

 The following tokens can be used to define verbs:

   @VERB name
   @VERBCHK type
   @VERBLGT
   @VERBPREP
   @VERBSYN synname..
   @ENDVERB

*******************************************************************************
* @VERB name * Verb definition
**************

 Starts the definition of a verb, where 'name' is the name of the verb.
 See NAMES for further details.

*******************************************************************************
* @VERBCHK type * Verb definition
***************** 

  Defines verb checking for the verb. Only one @VERBCHK can be defined for 
  each verb, the default being NO_CHECK.

  'type' can be one of: NO_CHECK
                        HERE
                        CARRIED_NOT_WORN
                        WORN
                        AVAIL
                        AVAIL_NOT_WORN
                        CARRIED
                        NOT_CARRIED
                        EXIST

   If the users command contains a verb that has verb checking selected, CAT
   will perform verb checking. If the object on the command line does not 
   pass the checks specified for the verb, then an appropriate message will be 
   displayed, and control will NOT be passed to low priority logic.

   When 'ALL' is used, CAT uses VERBCHK to intelligently determine which
   objects should be included in the ALL list.

******************************************************************************
* @VERBIS("text") * Low priority logic test
******************* 
 
 Returns TRUE if the verb is a synonym for "text".

 You should avoid this token for the following reasons:
     "text" will not be encrypted.
     @VERBNOIS is much faster.

 Only available in low priority processing.

*******************************************************************************
* @VERBLGT * Verb definition
************

 Specifies that it must be light for the user to use this verb. If the user
 tries to use this verb when it is dark, he will be given an appropriate 
 message, and control will NOT be passed to low priority logic.

******************************************************************************
* @VERBNOIS(verb) * Low priority logic test
*******************

 Returns TRUE if the verb number = verb. You must use the actual verb name,
 NOT a synonym.

 Only available in low priority processing.

*******************************************************************************
* @VERBOSE * Logic command
************

 Enter VERBOSE mode. Long room descriptions will always be given.  
 
******************************************************************************
* @VERBPATH(verb) * Logic - return value
*******************

  Returns the room number that verb would lead to, or -1 if verb is  
  not a valid @ROOMPTH from the current room.

*******************************************************************************
* @VERBPREP * Verb definition
*************

 Defines the verb as being a prepositioner verb. 'TO' and 'WITH' are examples
 of prepositioner verbs. A verb must be defined as a prepositioner verb if 
 it should be allowed as the second part of a compound command.
 (i.e. 'GIVE THE HAT TO BOB')

*******************************************************************************
* @VERBSYN synname.. * Verb definition
**********************

 Defines synonyms for the verb. A verb can have many synonyms. Verb synonyms 
 follow the same rules as verb names - see NAMES for more details.

*******************************************************************************
* @VOCAB * Logic command
**********

 Prints a list of all the accepted verbs.

*******************************************************************************
* @WAITKEY * Logic command
************

 Waits for a key to be pressed.

*******************************************************************************
* @WEAR(obj) * Logic command
**************

 Makes the object wearable, AND worn.

******************************************************************************
* WEIGHT *
**********

 CAT will automatically update compound object weights, i.e. the weight of
 each object will be the basic weight of the object, PLUS any objects that
 object is carrying, plus any objects that those objects may be carrying etc.
 
 The total weight of an object can be determined by @WEIGHT.
 
 The basic weight of an object can be determined by @SIZE.
 
 The carried weight of an object can be determined by @CARRIED_WEIGHT.
 
 Objects defined with @OBJNGT will have an effective weight of zero - 
 i.e. these objects are ignored when calculating weights.

******************************************************************************
* @WEIGHT(obj) * Logic - return value
****************

 Returns the weight of obj.

*******************************************************************************
* @WEND * Logic control
*********

 Signifies the end of an @WHILE 'logic control' group.

 Each @WEND must match up to an @WHILE.

*******************************************************************************
* @WHILE * Logic control
**********

 Signifies the start of an @WHILE 'logic control' group.

 Each @WHILE must match up to an @WEND.

 @WHILE groups will repeat until the test conditions fail.

*******************************************************************************
* @WHOAMI * Logic command
***********

 Print 'You are', and the short description of the current player.

*******************************************************************************
* ZZRQD * 
*********

 This is a standard definition file for CAT. Any definitions in this file
 are referred to internally by CAT. You should not change any NAMES in this 
 file, but you can change synonyms and text.

*******************************************************************************
* ZZSTD *
*********

 This is the standard definition file for CAT. It provides all generic 
 CAT logic. You can change this file, or add to it as required.

*******************************************************************************
* ZZZZZZZZZZZZZZZZZ * 
*********************

 Time for bed!

