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 numbers 4, 5 both have runnable programs (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 ********************** Adds val to the value of obj. ******************************************************************************* * @ADDWEIGHT(obj,val) * Logic command *********************** Adds 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. ****************************************************************************** * @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. ****************************************************************************** * @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. 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. ******************************************************************************* * @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. ******************************************************************************* * @ENDROOM * Room definition ************ Signifies the end of a room 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. ****************************************************************************** * @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. -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. 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. ******************************************************************************* * @GET(obj) * Logic command ************* Move obj to the current players in-room (@OBJINRM). ******************************************************************************* * @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). 2) Translate all text in your definition files, and in ZZRQD, ZZSTD. (@MSGTXT, @OBJSHT, @OBJLNG, @ROOMSHT, @ROOMLNG). 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! ****************************************************************************** * @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 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 three distinct flavours of logic processing. These are initialisation logic, low priority logic and high priority logic. These modes can be switched between using the @INIT, @LOW and @HIGH tokens. Initialisation logic is executed ONCE before the first player command. 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. 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) @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. @INIT @LOW @HIGH @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. ******************************************************************************* * @MAKEDARK(room) * Logic command ******************* Make room dark. ******************************************************************************* * @MAKELIGHT(room) * Logic command ******************** Make room light. ******************************************************************************* * MESSAGE DEFINITION * ********************** The following tokens can be used to define messages: @MSG name @MSGTXT text @ENDMSG ******************************************************************************* * @MSG name * Message 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. ******************************************************************************* * @MSGTXT text * Message definition **************** Describes the text behind the message that is currently being defined. You can include 'LF' in messages - this will print a linefeed character. ******************************************************************************* * 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 make 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. ******************************************************************************* * @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. ******************************************************************************* * @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. ******************************************************************************* * @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. ******************************************************************************* * @OPEN(obj) * Logic command ************** Changes the lock type of this object to OPEN. ******************************************************************************* * ORDER OF PROCESSING * *********************** At the start of the game, CAT processes the initialisation logic. This is processed in the order it was read by GEN (from GENLIST). Each time a valid command is found (i.e. @VERBLGT and @VERBCHK passed), then low priority logic will be processed in the order it was read by GEN - 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 will be processed in the order it was read by GEN. 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. ******************************************************************************* * @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 **************** Returns the number of points obj is worth to the player. ******************************************************************************* * @PROOML(room) * Logic command ***************** Print the long description of room. ******************************************************************************* * @PROOMS(room) * Logic command ***************** Print the short description of room. ****************************************************************************** * 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). ****************************************************************************** * @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. You should not place @REMarks in the middle of any logic groups. ******************************************************************************* * @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'. ******************************************************************************* * ROOM DEFINITION * ******************* The following tokens can be used to define rooms: @ROOM name @ROOMDRK @ROOMLNG text @ROOMPNT val @ROOMPTH verbname,roomname.. @ROOMSHT text @ENDROOM ******************************************************************************* * @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. ****************************************************************************** * @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. ******************************************************************************* * @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. ******************************************************************************* * @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! ****************************************************************************** * @STRENGTH(obj) * Logic - return value ****************** Returns the strength of obj. ******************************************************************************* * @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 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!