#import "lib.ih"
#import "doors.ih"
#import "debug.ih"
#import "switches.ih"

! Mini-Zork IAGE Implementation
! Ported by R.Rawson-Tetley November 2001 (for what seems like the millionth time)

LibraryMessage 1 "<br><b>MINI-ZORK I: The Great Underground Empire</b>
                 <br>Copyright (c) 1988 Infocom, Inc.
                 <br>All rights reserved.
                 <br>ZORK is a registered trademark of Infocom, Inc.
                 <br>Release 34 / Serial number 871124
                 <br><br><u>IAGE Multiplayer Port by R.Rawson-Tetley
                 <br>For questions and help, mail: [email protected]</u>
                 <br>IAGE Release 011116"

GameCode {
       Name "Mini-Zork I"
       MaxItemsCanCarry 10
       MaxWeightCanCarry 10
       MaxSizeCanCarry 10
       StartingLocation westofhouse
       Verbose yes
       ShowAvailableExits no
       AllowPersist yes
       SinglePlayerGame no
       MaxUsers 128
       OverrideSecondaryNouns "66 68 69"
       UsingIAGECombat yes
       UsingIAGEMoney no
       WideInventoryDisplay no
       RealTimeNPCs no
       PlayersStayDead no
       NPCsStayDead no

       AfterInput: CodeExtend [
               call Zork.customafterinput
       ]

       Initialise: CodeExtend [
               call Zork.initzork
       ]

       AfterInputImmediate: CodeExtend [
               call Zork.inthedark
       ]
}


Item treasure "Treasure Class" {

       OnAction: [

               end

               proc after_insert

                       ' If player has inserted treasure item into
                       ' trophy case and they have not received
                       ' points for it, give them.

                       if ( input.noun2 = trophycase.nounid ) then
                               if ( this.getuserboolean(hadpoints) = false ) then
                                       this.adduserboolean(hadpoints)
                                       call StandardLib.AddScore this.getvalue(points)
                                       end
                               endif
                       endif
               end

               proc before_get

                       ' Points for finding treasure

                       if ( this.getuserboolean(hadpickuppoints) = false ) then
                               this.adduserboolean(hadpickuppoints)
                               call StandardLib.AddScore this.getvalue(pickuppoints)
                               end
                       endif
               end

               ' The initialise routine should be overridden in your subclass
               ' if you want to change the point value of a treasure item (just
               ' redefine the section below and change the 5 to something else).

               proc initialise
                        this.setvalue(points) = 5
                        this.setvalue(pickuppoints) = 2
               end
       ]
}

!=======================================================
! WEST OF HOUSE
!=======================================================
Location westofhouse "West Of House" {
       Nouns "white" "house" "field"
       Examine "The house is a beautiful white colonial. The owners must have been extremely wealthy."
       Description "You are standing in an open field west of a white house,
                    with a boarded front door. You could circle the house to the north or south."
       N_to northofhouse
       S_to southofhouse
       SE_to southofhouse
       NE_to northofhouse

       OnInput: [


                ;go
                       #east
                                currentplayer.print "The door is boarded and you can't remove the boards."
                                end
                        endif
                endif
       ]
}

Item mailbox "a small mailbox"
       Nouns "small" "mailbox" "mail" "box"
       StartsIn westofhouse
       Size 2
       StaticMessage "The small mailbox is securely fastened to the ground."
       has container openable static
}

Item leaflet "a leaflet"
       Nouns "leaflet"
       StartsIn mailbox
       ReadableText "~WELCOME TO ZORK, a game of adventure, danger, and low cunning.
                     No computer should be without one!~
                     <br><br>Note: this ~mini-zork~ contains only a sub-set of the locations,
                     puzzles, and descriptions found in the larger, disk-based version of Zork I.
                     <br><br>This IAGE version was ported by R.Rawson-Tetley.
                     The last update was made on 8th November, 2001.
                     <br>Some notes about this version follow:
                     <br>1. The two mazes were deliberately left out since they are now a highly
                        unfashionable (and indeed irritating!) puzzle.
                     <br>2. This release is only about 50% complete."
       has readable
}


!=======================================================
! NORTH OF HOUSE
!=======================================================
Location northofhouse "North Of House" {
       Nouns "white" "house" "field"
       Examine "The house is a beautiful white colonial. The owners must have been extremely wealthy."
       Description "You are facing the north side of a white house.
                    There is no door here, and all the windows are boarded up.
                    A narrow path winds north through the trees."
       N_to forestpath
       SE_to behindhouse
       SW_to westofhouse

       OnInput: [

               ;go
                       #south
                               currentplayer.print "The windows are all boarded."
                               end
                       endif
               endif
       ]
}

!=======================================================
! SOUTH OF HOUSE
!=======================================================
Location southofhouse "South Of House" {
       Nouns "white" "house" "field"
       Examine "The house is a beautiful white colonial. The owners must have been extremely wealthy."
       Description "You are facing the south side of a white house.
                    There is no door here, and all the windows are boarded."
       NE_to behindhouse
       NW_to westofhouse

       OnInput: [

               ;go
                       #north
                               currentplayer.print "The windows are all boarded."
                               end
                       endif
               endif
       ]
}

!=======================================================
! FOREST PATH
!=======================================================
Location forestpath "Forest Path" {
       Description "This is a path through a dimly lit forest, curving from south to
                    east. A large tree with low branches stands by the edge of the path."
       S_to northofhouse
       E_to forest
       U_to upatree

       OnInput: [

               ;climb
                       currentplayer.currentlocation = upatree.ID
                       game.displaycurrentlocation
               endif
       ]
}


Item pileofleaves "a pile of leaves"
       Nouns "pile" "leaves" "leaf"
       StartsIn forestpath
       Initial "On the ground is a pile of leaves."

       OnAction: [


               ;move,push,pull
                       if ( this.getuserboolean(moved) = false ) then
                                currentplayer.print "In disturbing the leaves, a grating is revealed."
                                printallinexcept forestpath.id currentplayer.index |currentplayer.name & " moves the pile of leaves, revealing " & grating.name & "."|
                                this.adduserboolean(moved)
                                grating.currentlocation = forestpath.id
                       endif
               endif

               end

               proc before_get
                       if ( this.getuserboolean(moved) = false ) then
                                returnvalue = "(Taken) In disturbing the leaves, a grating is revealed."
                                printallinexcept forestpath.id currentplayer.index |currentplayer.name & " moves the pile of leaves, revealing " & grating.name & "."|
                                this.adduserboolean(moved)
                                grating.currentlocation = forestpath.id
                       endif
               end
       ]
}

Item grating "an iron grating" {
       StartsIn limbo
       Nouns "iron" "grating" "grate"
       Initial "There is an iron grating securely fastened into the ground."
       StaticMessage "The iron grating is securely fastened into the ground."
       has static openable

       OnAction: [
               ;open
                       currentplayer.print "The grating is locked."
                       printallinexcept grating.currentlocation currentplayer.index |currentplayer.name & " attempts to open the grating, but it is locked."|
                       end
               endif
       ]
}


!=======================================================
! UP A TREE
!=======================================================
Location upatree "Up a Tree" {
       Description "You are ten feet above the ground, nestled among large branches."
       D_to forestpath
}

Item birdsnest "a bird's nest" {
       StartsIn upatree
       Nouns "bird" "bird's" "nest"
       Initial "Beside you on the branch is a small bird's nest."
}

Item jeweledegg "a jeweled egg" extends treasure {
       StartsIn upatree
       Nouns "jeweled" "jewel" "egg"
       Initial "In the bird's nest is a large egg encrusted with precious jewels,
                apparently scavenged by a childless songbird."
       HasUDB treasure
}


!=======================================================
! FOREST
!=======================================================
Location forest "Forest" {
       Description "This is a dimly lit forest, with large trees all around."
       E_to forestedge
       W_to forestpath
}

!=======================================================
! FOREST EDGE
!=======================================================
Location forestedge "Forest Edge" {
       Description "Paths lead into the forest to the west and northwest.
                    Also, a well-marked path extends east."
       E_to canyonview
       W_to forest
}

!=======================================================
! CANYON VIEW
!=======================================================
Location canyonview "Canyon View" {
       Description "You are atop the west wall of a great canyon, offering a marvelous view of
                    the mighty Frigid River below. Across the canyon, the walls of the
                    White Cliffs join the mighty ramparts of the Flathead Mountains.
                    To the north, Aragain Falls may be seen, complete with rainbow.
                    Even further upstream, the river flows out of a great dark cavern.
                    To the west is an immense forest, stretching for miles.
                    It seems possible to climb down into the canyon from here."
       W_to forestedge
       D_to canyonbottom
}

!=======================================================
! CANYON BOTTOM
!=======================================================
Location canyonbottom "Canyon Bottom" {
       Description "The walls of the river canyon may be climbable here. To the northeast is a narrow path."
       NE_to endofrainbow
       U_to canyonview
}

!=======================================================
! END OF RAINBOW
!=======================================================
Location endofrainbow "End Of Rainbow" {
       Description "You are on a small, rocky beach by the Frigid River, below the falls.
                    A rainbow crosses over the falls to the east and a narrow path continues to the southwest."
       SW_to canyonbottom

       OnInput: [
               ;go
                       #east
                               currentplayer.print "Can you walk on water vapour?"
                               end
                       endif
               endif
       ]
}

!=======================================================
! BEHIND HOUSE
!=======================================================
Location behindhouse "Behind House"
       Nouns "white" "house" "field"
       Examine "The house is a beautiful white colonial. The owners must have been extremely wealthy."
       Description "You are behind the white house. Paths lead into the forest to the east and northeast."
       N_to northofhouse
       S_to southofhouse
       E_to forest
       W_to kitchen
       NE_to forest
       NW_to northofhouse
       SW_to southofhouse

       OnInput: [

               ;go
                       #w,in
                               if ( kitchenouterwindow.openclosestate = false ) then
                                       currentplayer.print "The window is closed."
                                       end
                               endif
                       endif

                       #in
                               currentplayer.currentlocation = kitchen.ID
                               printallinexcept currentplayer.currentlocation currentplayer.index |currentplayer.name & " climbs into the house through the window."|
                               game.displaycurrentlocation
                       endif
               endif

       ]

       OnDisplay: [
               call LockableTwoWayDoors.displaydoor kitchenouterwindow.ID
       ]
}

Item kitchenouterwindow "a small window" {
       StartsIn behindhouse
       Nouns "small" "window"
       ReadableText "In one corner of the house is a small window which is closed."
       Initial "In one corner of the house is a small window which is open."
       has openable scenery

       OnAction: [
               call LockableTwoWayDoors.doorhandler kitcheninnerwindow.ID kitchenouterwindow.ID 0
       ]
}


!=======================================================
! KITCHEN
!=======================================================
Location kitchen "Kitchen" {
       Description "You are in the kitchen of the white house. A table has been used
                    recently for the preparation of food. A passage leads west,
                    a dark staircase leads upward and a chimney leads down."
       E_to behindhouse
       W_to livingroom
       U_to attic

       OnInput: [

               ;go
                       #e,out
                               if ( kitcheninnerwindow.openclosestate = false ) then
                                       currentplayer.print "The window is closed."
                                       end
                               endif
                       endif

                       #out
                               currentplayer.currentlocation = behindhouse.ID
                               printallinexcept currentplayer.currentlocation currentplayer.index |currentplayer.name & " climbs out of the window."|
                               game.displaycurrentlocation
                       endif

                       #d
                               currentplayer.print "Only Santa Claus climbs down chimneys."
                       endif

               endif
       ]

       OnDisplay: [
               call LockableTwoWayDoors.displaydoor kitcheninnerwindow.ID
       ]
}

Item kitcheninnerwindow "a small window" {
       StartsIn kitchen
       Nouns "small" "window"
       ReadableText "To the east is a small window which is closed."
       Initial "To the east is a small window which is open."
       has openable scenery

       OnAction: [
               call LockableTwoWayDoors.doorhandler kitcheninnerwindow.ID kitchenouterwindow.ID 0
       ]
}

Item glassbottle "a glass bottle" {
       Nouns "glass" "bottle"
       StartsIn kitchen
       Initial "A glass bottle is sitting on the table."
       has transparent container
}

Item quantitywater "a quantity of water" {
       Nouns "quantity" "water"
       StartsIn glassbottle
       has edible

       OnAction: [

               ;drink,eat
                       currentplayer.print "That hit the spot."
                       printallinexcept currentplayer.currentlocation currentplayer.index |currentplayer.name & " drinks a quantity of water."|
                       this.currentlocation = limbo
                       currentplayer.hitpoints = |currentplayer.hitpoints + 5|
                       end
               endif

               end

               proc before_get
                       returnvalue = "It slips through your fingers."
                       printallinexcept currentplayer.currentlocation currentplayer.index |currentplayer.name & " empties away a quantity of water."|
                       this.currentlocation = limbo
                       cancelevent
                       end
               end
       ]
}

Item brownsack "a brown sack" {
       Nouns "brown" "sack"
       StartsIn kitchen
       Size 2
       Initial "On the table is an elongated brown sack, smelling of hot peppers."
       has container openable
}

Item clovegarlic "a clove of garlic" {
       Nouns "clove" "garlic"
       StartsIn brownsack
       has edible

       OnAction: [

               ;eat
                       currentplayer.print "You won't make friends this way, but nobody around here is too friendly anyhow. Gulp!"
                       printallinexcept currentplayer.currentlocation currentplayer.index |currentplayer.name & " eats a clove of garlic."|
                       currentplayer.hitpoints = |currentplayer.hitpoints + 5|
                       this.currentlocation = limbo
                       end
               endif
       ]
}

Item lunch "a lunch" {
       Nouns "lunch" "food"
       StartsIn brownsack
       has edible

       OnAction: [
               ;eat
                       currentplayer.print "That hit the spot."
                       printallinexcept currentplayer.currentlocation currentplayer.index |currentplayer.name & " eats " & this.name & "."|
                       currentplayer.hitpoints = |currentplayer.hitpoints + 10|
                       this.currentlocation = limbo
                       end
               endif
       ]
}


!=======================================================
! ATTIC
!=======================================================
Location attic "Attic" {
       Description "This is the attic. The only exit is the stairway down."
       D_to kitchen
       has darkness
}

Item coilrope "a coil of rope" {
       Nouns "coil" "large" "rope"
       StartsIn attic
       Initial "A large coil of rope is lying in the corner."
}

Item knife "a nasty knife" {
       StartsIn attic
       Nouns "nasty" "knife"
       DamageIndicator 30
       has weapon
}



!=======================================================
! LIVING ROOM
!=======================================================
Location livingroom "Living Room" {
       Description "The living room opens to the east. To the west is a wooden door,
                    above which is strange gothic lettering. The door is nailed shut."
       E_to kitchen
       D_to cellar

       OnInput: [

               ;go
                       #down
                               if ( rug.getuserboolean(moved) = false ) then
                                       currentplayer.print "You can't go that way."
                                       end
                               endif
                               if ( trapdoor.openclosestate = false ) then
                                       currentplayer.print "The trapdoor is in the way."
                               else
                                        currentplayer.currentlocation = cellar.id
                                        currentplayer.print "The trap door crashes shut, and you hear someone barring it."
                                        trapdoor.openclosestate = false
                                        game.displaycurrentlocation
                               endif
                       endif

                       #west
                               currentplayer.print "The door is nailed shut."
                       endif
               endif
       ]
}


Item woodendoor "a wooden door" {
       StartsIn livingroom
       Nouns "wooden" "door"
       Description "The engravings translate to ~This space intentionally left blank.~"
       ReadableText "The engravings translate to ~This space intentionally left blank.~"
       has readable scenery

       OnAction: [
               ;open
                       currentplayer.print "It won't open."
                       printallinexcept currentplayer.currentlocation currentplayer.index |currentplayer.name & "attempts to open the wooden door."|
                       end
               endif
       ]
}

Item trophycase "a glass trophy case" {
       StartsIn livingroom
       Nouns "glass" "trophy" "case"
       Size 2
       StaticMessage "The trophy case is fixed to the wall."
       has transparent openable container static
}

Item rug "an oriental rug" {
       Nouns "oriental" "rug"
       StartsIn livingroom
       Initial "There is a large oriental rug in the center of the room."
       StaticMessage "The rug is too heavy to lift, but you noticed an irregularity beneath it."
       has static

       OnAction: [

               ;move,push,pull
                       if ( this.getuserboolean(moved) = false ) then
                                currentplayer.print "You drag the rug to one side of the room, revealing a closed trap door."
                                printallinexcept currentplayer.currentlocation currentplayer.index |currentplayer.name & " drags the rug to one side of the room, revealing a closed trap door."|
                                this.description = "A large oriental rug has been dragged to one side of the room."
                                this.adduserboolean(moved)
                                trapdoor.currentlocation = this.currentlocation
                       endif
               endif
       ]
}

Item trapdoor "a trap door" {
       Nouns "trap" "door"
       StartsIn limbo
       StaticMessage "A valiant attempt."
       has openable static

       OnAction: [

               ;open
                       if ( this.openclosestate = false ) then
                                currentplayer.print "The door reluctantly opens to reveal a rickety staircase descending into darkness."
                                printallinexcept currentplayer.currentlocation currentplayer.index |currentplayer.name & " opens the trapdoor, revealing a rickety staircase descending into darkness."|
                                this.openclosestate = true
                       endif
               endif
       ]
}

Item brasslantern "a brass lantern" {
       Nouns "brass" "lantern" "lamp"
       StartsIn livingroom
       Initial "A battery-powered brass lantern is on the trophy case."
       has lightsource
}

Item sword "a sword" {
       Initial "Above the trophy case hangs an elvish sword of great antiquity."
       Nouns "sword"
       StartsIn livingroom
       DamageIndicator 40
       has weapon
}


!=======================================================
! CELLAR
!=======================================================
Location cellar "Cellar" {
       Description "You are in a dark, damp cellar with narrow passageways to the
                    north and east. On the west is the bottom of a steep metal ramp which is unclimbable."
       N_to trollroom
       E_to studio
       has darkness

       OnInput: [

               ;go
                       #west
                               currentplayer.print "You try to ascend the ramp, but slide back down."
                               end
                       endif
               endif
       ]
}

!=======================================================
! TROLL ROOM
!=======================================================
Location trollroom "Troll Room" {
       Description "This is a small room with passages to the east, northeast and south,
                    and a forbidding hole leading west. Bloodstains and deep scratches
                    (perhaps made by an axe) mar the walls."
       S_to cellar
       has darkness

       OnInput: [

               #east,northeast
                       if ( troll.currentlocation = trollroom.id ) then
                               currentplayer.print "The troll fends you off with a menacing gesture!"
                       endif
               endif
       ]
}

Character troll "The Troll"
       StartsIn trollroom
       Initial "A troll, brandishing a bloody axe, blocks all passages out of the room."
       Nouns "troll"
       TimerInterval 5000
       DamageIndicator 5
       HitPoints 50
       has autoattack attackwhenattacked

       OnTalk: [
               currentplayer.print "The troll does not have much to say."
       ]

       OnAction: [
               call NPCPronouns.male this.id
       ]
}

Item bloodyaxe "a bloody axe" {
       Nouns "bloody" "axe"
       StartsIn limbo
       DamageIndicator 35
       has weapon

       OnAction: [
               end
               proc initialise
                       this.currentlocation = troll.containerlocation
               end
       ]
}


!=======================================================
! STUDIO
!=======================================================
Location studio "Studio" {
       Description "This was once an artist's studio. The walls are splattered
                    with paints of 69 different colors. To the west is a doorway
                    (also covered with paint). A dark and narrow chimney leads up from a
                    fireplace; although you might be able to get up it,
                    it seems unlikely you could get back down."
       W_to cellar
       has darkness

       OnInput: [
               ;go
                       #up
                               if ( currentplayer.itemscarried > 7 ) then
                                       currentplayer.print "You are carrying too much to fit up the chimney."
                                       end
                               endif
                               currentplayer.currentlocation = kitchen.id
                               game.displaycurrentlocation
                               end
                       endif
               endif
       ]
}

Item painting "a painting" extends treasure {
       Initial "On the far wall is a painting of unparalleled beauty."
       HasUDB treasure
       StartsIn studio
       Nouns "painting" "paint"

       OnAction: [

               ;smash,break,burn
                       currentplayer.print "Don't be a vandal!"
               endif
       ]
}

Character thief "The Gentleman Thief"
       Nouns "thief" "gentleman"
       Initial "Someone carrying a large bag is casually leaning against the wall.
                It is clear that the bag will be taken only over his dead body."
       Description "The thief carries a large bag and a vicious stiletto,
                    whose blade is aimed menacingly in your direction."
       HitPoints 40
       TimerInterval 4000
       has attackwhenattacked

       OnTimer: [


               var i = 1
               var cbi

               while ( i < |currentplayer.count + 1| ) then
                       cbi = playerarray(i).getfirstboolitem(treasure)
                       if ( cbi > 0 ) and ( playerarray(i).currentlocation = thief.currentlocation ) then
                               playerarray(i).print "The thief pauses to relieve you of some valuables."
                               printallinexcept playerarray(i).currentlocation playerarray(i).index |"The thief relieves" & playerarray(i).name & " of some valuables."|
                               item(cbi).currentlocation = |300000 + thief.id|
                       endif
                       i = |i + 1|
               endwhile
       ]

       OnTalk: [
               currentplayer.print "The Gentleman Thief ignores you."
       ]

       OnAction: [
               call NPCPronouns.male this.id
       ]
}





!==========================================================
! Zork specific code
!==========================================================
Module Zork {

' Module containing code specific to this game
proc customafterinput

   ' Special "what is a grue" message
   ;what
       #is
               if ( input.noun = 999 ) then
                       currentplayer.print "The grue is a sinister, lurking presence in the dark places of the earth. Its favourite diet is adventurers, but its insatiable appetite is tempered by its fear of light."
                       end
               endif
       endif
   endif

end


proc initzork

       ' Add noun for our grue
       addnoun 999 grue

       ' Set thief to wandering around and start him in the studio
       thief.AIMode = 2
       thief.currentlocation = studio.id

end

' Daemon that runs when players are in the dark
proc inthedark

       if ( currentplayer.cansee = false ) then

               currentplayer.setvalue(darkdaemon) = currentplayer.getvalue(darkdaemon)_+_1

               if ( currentplayer.getvalue(darkdaemon) = 4 ) then
                       currentplayer.print "Oh no! A lurking grue slithered into the room and devoured you!"
                       call StandardLib.Dead
                       end
               endif

       else
               currentplayer.setvalue(darkdaemon) = 0
       endif
end

}