; ----------------------------------------------------
;                  actions.txt file
; ----------------------------------------------------

; this is where all the ROUTINES live. 
; they can be called by ROOMs, OJBECTS and VERBS in the adventure.txt file
;
; each routine begins with a < and ends with a > 
; with the declaration line <ROUTINE and then the name of the routine being the first line
; the routine name must be exactly as it appears in the matching ROOM, OBJECT or VERB's
; (ACTION ...) sub entry. ; eg, <ROUTINE CLOSE_ROUTINE

; the > at the end of the routine can append the final line of the routine, or it can be
; on its own after a carriage return at the end of the routine (can help reading when long
; lines push the > off the right hand edge of the screen.
;
; then each sub-entry for that routine follows. Each must be enclosed in normal brackets ( )
; an entry can go on for one or more lines, but it must begin with ( and end with )

; ----------------------------------------------------
; valid sub-entries for a ROUTINE
; ----------------------------------------------------

; an entry can be one of the following:

; - a call to another routine (ROUTINE ANOTHER_ROUTINE)
;   in this case, ANOTHER_ROUTINE must be a valid routine in the actions.txt file
;   note that the called routine could pass, and the rest of this routine won't run
;
; - a condition (IF condition THEN actions)
;
; - an action:
;   SETFLAG, UNSETFLAG, SETROOM, TELL, INC.CARRED, DEC.CARRIED, SHOW_INVENTORY, REDESCRIBE
;
; a condition must begin with (IF and a space, then one or more things to check to see if 
; they're true or false. If there is more than one test, each test must be separated with either 
; an AND or OR.

; LIMITATION NOTE - the tests are done left to right and you *can't* bracket tests
; eg (IF (A AND B) OR C ...
; so don't mix and match ANDs and ORs on a single IF line or you might get unexpected results.
; if necessary, split more complicated tests down into separate IF conditions.
; this sometimes means repeating yourself. Sorry about that. 
;

; after the test(s) there must be a THEN after which follows the actions the parser must do when
; the test(s) have passed.
;
; you can do equality and inequality tests on VERBs, ROOMs, OBJECTS and INDIRECTS.

; note there MUST NOT BE ANY SPACES!!! either side of the "=" or "<>" - at best the parser will
; throw a syntax error, at worst it'll hang.

; ----------------------------------------------------
; examples of valid tests
; ----------------------------------------------------

; (IF VERB=... if player has typed the verb... (must be followed by a valid verb to check)
;
; (IF OBJECT=... if player has typed the object... (must be followed by a valid object to check)

; (IF INDIRECT=... if player has included the indirect obect ... (must be followed by a valid
;                  object to check). Note that if a player's input contains only one recognised
;                  OBJECT, that object is the direct object. There can only be an INDIRECT 
;                  if the parser recognises a second OBJECT in the input string. The first object
;                  to appear in the string is the direct object (OBJECT) and the second object to
;                  appear in the string is the INDIRECT.

; (IF ROOM.PLAYER=... if the player is currently in room...
; (IF ROOM.THIS=... if the object the player entered is currently in room ...
; (IF ROOM.XXX=... if the object specified is currently in room ... XXX must be a valid object.
;
;     an OBJECT's ROOM value must be a valid ROOM, or it can have the value NONE, which means it 
;     doesn't physically exist in the game - can't be picked up, carried etc, but the parser will
;     still process it.
;     an object can also have a valid room value CARRIED, this means the player is carrying that 
;     object.
;     it should go without saying, but the PLAYER can *never* have the ROOM value NONE or CARRIED.

; testing flags: note that there is no equality (=) or inequality (<>) in testing flags.
; the two tests IF FLAGSET and IF FLAGUNSET do the job of = and <>
; for example, if you wanted to test if the OPEN flag was NOT set for a particular object, you
; would write (IF FLAGUNSET.THIS OPEN ....

; (IF FLAGSET.THIS XYZ if the OBJECT typed in by the player has the XYZ flag set
; (IF FLAGSET.anyOBJ/ROOM XYZ if the OBJECT or ROOM specified has the XYZ flag set
;
; (IF FLAGUNSET.THIS XYZ if the OBJECT typed in by the player does not have the XYZ flag set
; (IF FLAGUNSET.anyOBJ/ROOM XYZ if the OBJECT or ROOM specified does not have the XYZ flag set
;
; (IF EXCEEDCARRY if the SIZE of the object typed in PLUS the current carried SIZE 
; is greater than player's max carry
;
; In routines that deal with two objects, .THIS references the main object and
; .INDIRECT references the indirect object. 
;
;     "switch light on" - this has a verb ("switch") and two objects:
;     "light" is the  .THIS object, and "on" is the .INDIRECT object.
;     NOTE: order of objects matters!
;     using the sample ROUTINES below, if the player typed in "switch on light", 
;     the parser would return SWITCH as the verb,
;     "on" as the .THIS object, and "light" as the .INDIRECT object.
;
;     "tie rope to pole" - VERB is "tie" ; .THIS is "rope" ; .INDIRECT is "pole"
;     "tie pole to rope" - VERB is "tie" ; .THIS is "pole" ; .INDIRECT is "rope"
;    
; EXAMPLES OF ACTIONS:
; --------------------
; SETFLAG.THIS XYZ - sets specified "XYZ" flag for the object typed in
; SETFLAG.anyOBJ/ROOM XYZ - sets specified "XYZ" flag for a specified object or room
;
; UNSETFLAG.THIS XYZ - unsets specified "XYZ" flag for the object typed in by player
; UNSETFLAG.TRAPDOOR XYZ - unsets specified "XYZ" flag for a specified object / room
;
; SETROOM.THIS ROOMXYZ - sets the location of the object typed in
; SETROOM.anyOBJ ROOMXYZ - sets the location of a specified OBJECT (mustn't be a door object)
;   ROOMXYZ must be a valid ROOM or ROOM.PLAYER
;   setting an object location to CARRIED moves the item into the player's inventory
;
; INC.CARRIED SIZE.THIS - increases the amount the player is carrying by the SIZE of the object typed in
; DEC.CARRIED SIZE.THIS - decreases the amount the player is carrying by the SIZE of the object typed in
;
; ~not implemented yet SETSIZE.THIS - sets the size value of the object typed in by player - must be followed by a numerical value
; ~not implemented yet SETSIZE.LAMP - sets the size value of a specified object - must be followed by a numerical value
;
; ~not implemented yet: MAXCARRY - sets the maximum amount the player can carry - must be followed by a numerical value)
; ~not implemented yet: INC.CARRIED 000 - increases the amount the player is carrying - must be followed by a numerical value 
;
; ~not implemented yet: DEC.CARRIED 000 - decreases the amount the player is carrying - must be followed by a numerical value
;
; ~not implemented yet: INC.SCORE 000  - increases the score of the player - must be followed by a numerical value
; ~not implemented yet: DEC.SCORE 000
;
; TELL "Words words words." - this puts the words up on screen
; you can optionally include the "%" character and the parser will replace it with the 
; object that the player has typed in. 
;
; ADDITIONAL NOTES
; there can be more than one assignment after the THEN
; there is only one pair of brackets around the whole condition:
;   (IF test AND test THEN
;      action
;      action
;      action)
; the last action must be terminated by a close bracket ) 
; then the next condition must begin again with an open bracket
; as mentioned at the top of this file, once all the sub-items for a routine are done,
; the whole routine must be closed with a greater than sign >
;
; the first (IF ....) test to succeed will be carried out by the parser,
; the routine will terminate and all the following (IFs..) in that routine will not be executed
; so the order of the (IF...) conditions matters!!!
;
;
;
; -----------------SAMPLE CODE STARTS HERE-------------------
;

<ROUTINE LIVING_ROOM_ROUTINE
  (IF FLAGSET.TRAPDOOR OPEN THEN
    TELL "The rug is folded back revealing an open trapdoor in the middle of the floor. A rusty ladder leads down into the darkness.")
  (IF FLAGSET.PERSIAN_RUG LIFTED AND FLAGUNSET.TRAPDOOR OPEN THEN
    TELL "The rug is folded back revealing a trapdoor in the middle of the floor.")
  (IF FLAGSET.LIVING_ROOM CYCLOPS_GONE THEN
    TELL "The door to the west has been ripped off its hinges and there is no sign of the cyclops.")
  (IF FLAGUNSET.LIVING_ROOM CYCLOPS_GONE THEN
    TELL "There is a menacing looking cyclops guarding the door to the west. It glares at you.")
>

<ROUTINE KITCHEN_ROUTINE
  (IF FLAGSET.CUPBOARD OPEN THEN
    TELL "The cupboard door is open wide.")
>

<ROUTINE PERSIAN_RUG_ROUTINE
  (IF ROOM.THIS<>ROOM.PLAYER THEN
    TELL "What rug?")
  (IF VERB=LIFT AND FLAGSET.THIS LIFTED THEN
    TELL "You lift the rug again and move it around a bit as best as you can. The trapdoor is still visible.")
  (IF VERB=LIFT THEN
    TELL "You heave at the corner of the rug, and manage to lift a corner back. You see a trapdoor revealed underneath the rug!"
    SETFLAG.THIS LIFTED)
>

<ROUTINE CYCLOPS_ROUTINE
  (IF VERB=GET THEN
    TELL "I wouldn't try that if I were you.")

  (TELL "Probably best not to mess with the cyclops. It looks like it's ready for a fight.")
>

<ROUTINE GET_ROUTINE
  (IF OBJECT=NULL THEN
    (TELL "I don't understand what you want me to get.")
  (IF ROOM.THIS=CARRIED THEN
    (TELL "But you're already carrying it.")
  (IF ROOM.THIS<>ROOM.PLAYER THEN
    TELL "I can't see any % here to pick up.")
  (IF SIZE.THIS=100 THEN
    TELL "There's no way I can pick that up!")
  (IF EXCEEDCARRY THEN
    TELL "You can't pick it up, you are encumbered. You could try dropping some other things first.")
  (TELL "You pick up the %."
    SETROOM.THIS=CARRIED
    INC.CARRIED SIZE.THIS
    SETFLAG.THIS REMOVED)
>

<ROUTINE DROP_ROUTINE
  (IF ROOM.THIS<>CARRIED THEN
     TELL "But you're not carrying the %.")
  (TELL "You drop the %."
    SETROOM.THIS=ROOM.PLAYER
    DEC.CARRIED SIZE.THIS)
>

<ROUTINE CUPBOARD_ROUTINE
  (IF VERB=OPEN AND FLAGUNSET.THIS=LOCKED AND FLAGUNSET.THIS=OPEN AND ROOM.NOTE=NONE THEN
    TELL "You swing the doors open wide, and on the otherwise bare shelves, you notice a little note inside."
    SETROOM.NOTE=KITCHEN
    SETFLAG.THIS=OPEN)
  (ROUTINE OPEN_CLOSE_ROUTINE)
  (IF VERB=LOCK AND ROOM.IRON_KEY<>CARRIED THEN
    TELL "But you're not carrying the cupboard door key.")
  (IF VERB=LOCK AND FLAGSET.THIS OPEN THEN
    TELL "You gently close the cupboard door, and twist the decorative iron key in the lock. It clunks satisfyingly."
    UNSETFLAG.THIS OPEN
    SETFLAG.THIS LOCKED)
  (IF VERB=LOCK AND FLAGSET.THIS LOCKED THEN
    TELL "The key won't turn. It must be locked already.")
  (IF VERB=LOCK THEN
    TELL "You twist the decorative iron key in the lock. It clunks satisfyingly."
    SETFLAG.THIS LOCKED)

  (IF VERB=UNLOCK AND ROOM.IRON_KEY<>CARRIED THEN
    TELL "But you're not carrying the cupboard door key.")
  (IF VERB=UNLOCK AND FLAGSET.THIS OPEN THEN
    TELL "But the cupboard is already open.")
  (IF VERB=UNLOCK AND FLAGUNSET.THIS LOCKED THEN
    TELL "But the cupboard is already unlocked.")
  (IF VERB=UNLOCK THEN
    TELL "You twist the decorative iron key in the lock. It clunks satisfyingly."
    UNSETFLAG.THIS LOCKED)>    

<ROUTINE TRAPDOOR_ROUTINE
  (ROUTINE OPEN_CLOSE_ROUTINE)
  (IF VERB=LOCK AND ROOM.TRAPDOOR_KEY<>CARRIED THEN
     TELL "But you're not carrying the trapdoor key.")
  (IF VERB=LOCK AND FLAGSET.THIS OPEN THEN
     TELL "You swing the trapdoor closed, and twist the key in the lock. It clunks satisfyingly."
     UNSETFLAG.THIS OPEN
     SETFLAG.THIS LOCKED)
  (IF VERB=LOCK AND FLAGSET.THIS LOCKED THEN
     TELL "The key won't turn. It must be locked already.")
  (IF VERB=LOCK THEN
     TELL "You twist the key in the lock. It clunks satisfyingly."
     SETFLAG.THIS LOCKED)

  (IF VERB=UNLOCK AND ROOM.TRAPDOOR_KEY<>CARRIED THEN
     TELL "But you're not carrying the trapdoor key.")
  (IF VERB=UNLOCK AND FLAGSET.THIS OPEN THEN
     TELL "But it's already open.")
  (IF VERB=UNLOCK AND FLAGUNSET.THIS LOCKED THEN
     TELL "But it's already unlocked.")
  (IF VERB=UNLOCK THEN
     TELL "You twist the key in the lock. It clunks satisfyingly."
     UNSETFLAG.THIS LOCKED)>

<ROUTINE OPEN_CLOSE_ROUTINE
  (IF VERB=LIFT AND FLAGSET.THIS LOCKED THEN
    TELL "It won't open - if must be locked.")
  (IF VERB=OPEN AND FLAGSET.THIS LOCKED THEN
    TELL "It won't open - it must be locked.")
  (IF VERB=OPEN AND FLAGSET.THIS OPEN THEN
    TELL "It is already open.")
  (IF VERB=LIFT AND FLAGSET.THIS OPEN THEN
    TELL "It is already open.")
  (IF VERB=OPEN THEN
    TELL "You open the %."
    SETFLAG.THIS OPEN)
  (IF VERB=LIFT THEN
    TELL "You open the %."
    SETFLAG.THIS OPEN)

  (IF VERB=CLOSE AND FLAGSET.THIS OPEN THEN
    UNSETFLAG.THIS OPEN
    TELL "You close the %.")
  (IF VERB=CLOSE THEN
    TELL "The % is already closed.")>

<ROUTINE OPEN_ROUTINE
  (TELL "I don't know how to open that.")>

<ROUTINE CLOSE_ROUTINE
  (TELL "I don't know how to close a %.")>

<ROUTINE INVENTORY_ROUTINE
  (SHOW_INVENTORY)>

<ROUTINE LANTERN_ROUTINE
  (IF VERB=SWITCH AND ROOM.THIS<>ROOM.PLAYER AND ROOM.THIS<>CARRIED THEN
    TELL "What lantern?")
  (IF VERB=SWITCH AND INDIRECT=ON AND FLAGSET.THIS LIT THEN
    TELL "The lantern is already lit.")
  (IF VERB=SWITCH AND INDIRECT=ON THEN
    SETFLAG.THIS LIT
    TELL "You switch the lantern on.")
  (IF VERB=SWITCH AND INDIRECT=OFF AND FLAGUNSET.THIS LIT THEN
    TELL "The lantern is already off.")
  (IF VERB=SWITCH AND INDIRECT=OFF THEN
    TELL "You switch the lantern off."
    UNSETFLAG.THIS LIT)
>

<ROUTINE SAY_ROUTINE
  (IF OBJECT=PLUGH AND ROOM.PLAYER=LIVING_ROOM AND FLAGUNSET.LIVING_ROOM CYCLOPS_GONE THEN
    SETFLAG.LIVING_ROOM CYCLOPS_GONE
    TELL "Looking the cyclops in the eye, you utter the word 'plugh'. The cyclops cries out in mortal fear, and turns around, ripping the door behind it from its hinges and legs it into the passage beyond.")
  (TELL "You say 'plugh'. Nothing happens.")
>

<ROUTINE LOOK_ROUTINE
  (REDESCRIBE)>


<ROUTINE LIFT_ROUTINE
  (TELL "I'm not sure how to lift that.")>  


<ROUTINE NOTE_ROUTINE
  (IF VERB=READ OR VERB=EXAMINE AND ROOM.THIS=CARRIED THEN
    TELL "Written in a scribbled handwriting, the note bears the words 'the cyclops is terrified of the word plugh.'")
  (IF VERB=READ OR VERB=EXAMINE AND ROOM.THIS=ROOM.PLAYER THEN
    TELL "Written in a scribbled handwriting, the note bears the words 'the cyclops is terrified of the word plugh.'")
>

<ROUTINE EXAMINE_ROUTINE
  (IF OBJECT=CYCLOPS THEN
    TELL "The cyclops is about 10 feet tall. He stoops slightly to stop his head hitting the ceiling."
    TELL "Apart from the occasional grunt, he says nothing and does nothing. He watches you intently."
    TELL "He stands right up against the wooden door to the west, preventing anyone from opening it.")

  (IF OBJECT=CUPBOARD THEN
    TELL "It is a sturdy wooden cabinet, with solid wooden doors.")

  (IF OBJECT=DEBRIS THEN
    SETROOM.TRAPDOOR_KEY=STRANGE_PASSAGE
    TELL "Lying hidden amongst the debris, you find a small, rusty key.")

  (IF OBJECT=TRAPDOOR AND FLAGUNSET.PERSIAN_RUG LIFTED THEN
    TELL "I can't see any trapdoor here.")
  (IF OBJECT=TRAPDOOR THEN
    TELL "It is a sturdy timber trapdoor, with a large recessed hoop to lift so it can be swung open. There is a small keyhole just beneath the hoop.")

  (TELL "I'm sorry, I haven't been given words to describe that.")
>


<ROUTINE READ_ROUTINE
  (IF ROOM.THIS<>CARRIED AND ROOM.THIS<>ROOM.PLAYER THEN
  (TELL "I can't see any % here to read.")

  (TELL "I don't know how to read that.")
>



EOF!

; -----------END OF SAMPLE CODE--------------

; the EOF! must exist at the end of the file, with a carriage return (enter key)
; for the parser to recognise the end of the file

; flags recognised by the parser:
; ~not implemented yet: INVISIBLE (an object cannot be seen, and will not be written up, even if it is in the room with the player

; special location values:
; if the location of an object is set to CARRIED, this denotes it is being carried
; if the location of an object is set to NONE, this denotes it does not exist in the world
; (eg, after a food item has been eaten, or for words like xyzzy or plugh!)


