#import "lib.ih"
#import "doors.ih"
#import "pushable.ih"

LibraryMessage 1 "<br><b>~Ruins~</b>
		  <br><i>An Interactive Worked Example</i>
		  <br>Copyright(c)1999 by Angela M. Horns."

! ---------------------------------------------------------------------------- !
!       This version created by R.Rawson-Tetley in October 2001, from
!	Roger Firth's Inform recreation of this game, quoted in Edition 4/1
!	of the Inform Designer's Manual.
!       
!                       PLAYER
!                             lamp,dictionary,map
!                       GREAT PLAZA
!                           | mushroom,packing-case,camera,newspaper,steps
!                           |
!                           |
!                       SQUARE CHAMBER -------------------- WORMCAST
!                           | inscriptions,sunlight,(key)         eggsac
!                           |
!                           |
!                       STOOPED CORRIDOR
!                           | statuette,door
!                           |
!                           |
!   UPPER CANYON        SHRINE
!       | ball           /     \ paintings,altar,mask,(priest)
!       |     ----------         ----------
!       |   /                               \
!   XIBALBÁ                                 ANTECHAMBER
!       | stela                                 | cage,skeletons,(warthog)
!       |                                       |
!       |                                       |
!   LOWER CANYON                            BURIAL SHAFT
!       | chasm                                   honeycomb
!       |
!       |
!   PUMICE LEDGE
!         bone
!
! ---------------------------------------------------------------------------- !

! Intro
LibraryMessage 200 "<bgcolor gray><font color=white><clearscreen><br>
		    &nbsp;      <b>RUINS</b>
		    <font color=black><br><bgcolor lightgray><br>
		    <br>         ~But Alligator was not digging the bottom of the hole
		    <br>        Which was to be his grave,
		    <br>        But rather he was digging his own hole
		    <br>        As a shelter for himself~
		    <br>
		    <br>        -- from the Popol Vuh
		    <br><bgcolor gray><br>
		    <font size=2 color=white>
		    <br>[ Please press SPACE to begin.]
		    <waitkey><br>
		    <clearscreen>
		    <br>Days of searching, days of thirsty hacking through the briars of
         	    the forest, but at last your patience was rewarded. A discovery!"

GameCode {
	Name "Ruins"
	MaxItemsCanCarry 7
	Verbose yes
	WideInventoryDisplay yes
	SinglePlayerGame yes
	OverrideSecondaryNouns "66 68 69"
	ShowAvailableExits no
	StartingLocation forest
	AllowPersist yes
	
	Initialise: CodeExtend [
		addverb 201 photo
		addverb 201 photograph
	]
	
	Start: Override [

		' Show the intro screen
		message(200).show
	
		' Give starting objects to the player
		map.currentlocation = currentplayer.containerlocation
		dictionary.currentlocation = currentplayer.containerlocation
		sodiumlamp.currentlocation = currentplayer.containerlocation
	
		' Show the game version, the library version
		' and output the start location to the player
		game.displayversion
		call StandardLib.DisplayLibraryVersion
		game.displaycurrentlocation
				
		' default male/female pronouns
		call NPCPronouns.init
	]
	
	Score: Override [
		var outs = |"You have scored " & currentplayer.score & " (out of a possible 25) in " & currentplayer.turns & " turns, earning you the rank of "|
		if ( currentplayer.score = 25 ) then 
			outs = |outs & "Director of the Carnegie Institution."|
			currentplayer.print outs
			end
		endif
		if ( currentplayer.score >= 20 ) then 
			outs = |outs & "Archaeologist."|
			currentplayer.print outs
			end
		endif
		if ( currentplayer.score >= 10 ) then 
			outs = |outs & "Curiosity-seeker."|
			currentplayer.print outs
			end
		endif
		if ( currentplayer.score >= 5 ) then 
			outs = |outs & "Explorer."|
			currentplayer.print outs
			end
		endif
		outs = |outs & "Tourist."|
		currentplayer.print outs
	]
	
	AfterInputImmediate: CodeExtend [
	
	         call DarkDaemon.inthedark
 
              	if ( currentplayer.getvalue(warthog) = 1 ) then 
              		;go,look,examine,smell,search,jump
              			end
              		endif
             		#n,s,e,w,u,d,ne,nw,se,sw
             			end
             		endif
              		;eat
              			currentplayer.print "You haven't the knack of snuffling up to food yet."
              			end
              		endif
              		;inventory
              			currentplayer.print "You are empty-handed."
              			end
              		endif
              		currentplayer.print "Warthogs can't do anything so involved. If it weren't for the nocturnal eyesight and the lost weight, they'd be worse off all round than people."
              		end
              	endif
	
	
		;photo
			if ( camera.currentlocation <> currentplayer.containerlocation ) then
				currentplayer.print |"Not without the use of your camera" & "."|
				end
			endif
			if ( input.noun = 4 ) or ( input.noun = |1000000 + currentplayer.index| ) then
				currentplayer.print "Best not. You haven't shaved since Mexico."
				end
			endif
			if ( currentplayer.itemscarried > 1 ) then
				currentplayer.print "Photography is a cumbersome business, needing the use of both hands. You'll have to put everything else down."
				end
			endif
			if ( currentplayer.currentlocation = forest.id ) then
				currentplayer.print "In this rain-soaked forest, best not."
				end
			endif
			if ( currentplayer.cansee = false ) then 
				currentplayer.print "It is far too dark."
				end
		        endif
		endif
	        
	]
}

! -----------------------------------------------------------------------------
! Treasure class definition
!

Item treasure "Treasure Class" {

	OnAction: [
	
		;photo
			if ( this.movedfromoriginallocation = true ) then
				currentplayer.print "What, and fake the archaeological record?"
				end
			endif
			if ( this.getuserboolean(photoinsitu) = true ) then 
				currentplayer.print "Not again."
				end
			endif
			currentplayer.print |"You set up the elephantine, large-format, wet-plate camera, adjust the sodium lamp and make a patient exposure of the " & this.thename & "."|
			this.adduserboolean(photoinsitu)
		endif
		
		end

		proc before_insert
		
			if ( input.noun2 = packingcase.nounid ) then 
				call StandardLib.AddScore this.getvalue(culturalvalue)
				
				if ( currentplayer.score = 25 ) then
					currentplayer.print |"As you carefully pack away the " & this.thename & ", a red-tailed macaw flutters down from the tree-tops, feathers heavy in the recent rain, the sound of its beating wings almost deafening, stone falling against stone... As the skies clear, a crescent moon rises above a peaceful jungle. It is the end of March, 1938, and it is time to go home."|
					call StandardLib.Won
					end
				else
					returnvalue = "Safely packed away."
					end
				endif
			endif
		end
	
	
		proc initialise
			this.setvalue(culturalvalue) = 5
			end
		end
	
		proc before_get
			if ( this.currentlocation = packingcase.containerlocation ) then
				returnvalue = "Unpacking such a priceless artifact had best wait until the Carnegie Intitution can do it."
				cancelevent
				end
			endif
			if ( this.getuserboolean(photoinsitu) = false ) then 
				returnvalue = "This is the 1930s, not the bad old days. Taking an artifact without recording its context is simply looting."
				cancelevent
				end
			endif
		end
		
		proc before_remove
			if ( this.currentlocation = packingcase.containerlocation ) then
				returnvalue = "Unpacking such a priceless artifact had best wait until the Carnegie Intitution can do it."
				cancelevent
				end
			endif
			if ( this.getuserboolean(photoinsitu) = false ) then 
				returnvalue = "This is the 1930s, not the bad old days. Taking an artifact without recording its context is simply looting."
				cancelevent
				end
			endif
		end		
	]
}


! ---------------------------------------------------------------------------- !
!       The game begins in the GRAND PLAZA.
!
Location forest "~Great Plaza~" {
	Description "Or so your notes call this low escarpment of limestone, but the rainforest has claimed it back. Dark olive trees crowd in on all sides, the air steams with the mist of a warm recent rain, midges hang in the air. ~Structure 10~ is a shambles of masonry which might once have been a burial pyramid, and little survives except stone-cut steps leading down into darkness below."
	
	OnInput: [
		;go
			#u
				currentplayer.print "The trees are spiny and you'd cut your hands to ribbons trying to climb them."
				end
			endif
			#in
				currentplayer.currentlocation = steps.id
				game.displaycurrentlocation
				end
			endif
			#d
				if ( steps.getuserboolean(rubblefilled) = true ) then 
					currentplayer.print |"Rubble blocks the way after only a few steps" & "."|
					end
				else
					currentplayer.currentlocation = squarechamber.id
					game.displaycurrentlocation
					end
				endif
			endif
			#n,s,e,w,ne,nw,se,sw
				currentplayer.print "The rainforest is dense, and you haven't hacked through it for days to abandon your discovery now. Really, you need a good few artifacts to take back to civilization before you can justify giving up the expedition."
				end
			endif
		endif
		;listen
			currentplayer.print "Howler monkeys, bats, parrots, macaw."
			end
		endif
	
	]
}

Item mushroom "a speckled mushroom" {
	StartsIn forest
	Nouns "speckled" "mushroom" "fungus" "toadstool"
        Initial "A speckled mushroom grows out of the sodden earth, on a long stalk."
        Description "The mushroom is capped with blotches, and you aren't at all sure it's not a toadstool."
        has edible
        
        OnAction: [
        
        	;eat
        		steps.removeuserboolean(rubblefilled)
        		currentplayer.print "You nibble at one corner, unable to trace the source of an acrid taste, distracted by the flight of a macaw overhead which seems to burst out of the sun, the sound of the beating of its wings almost deafening, stone falling against stone."
        		end
        	endif
        	end
        	proc before_get 
        		if ( this.getuserboolean(picked) = true ) then 
        			returnvalue = "You pick up the slowly-disintegrating mushroom."
        		else
        			this.adduserboolean(picked)
        			returnvalue = "You pick the mushroom, neatly cleaving its thin stalk."
        		endif
        	end
        	proc before_drop
        		returnvalue = "The mushroom drops to the ground, battered slightly."
        		end
        	endif
        ]
}

Item packingcase "a packing case" {
	Nouns "packing" "case" "box" "strongbox"
	StartsIn forest
	Size 2
	Initial "Your packing case rests here, ready to hold any important cultural finds you might make, for shipping back to civilisation."
	StaticMessage "The case is too heavy to bother moving, as long as your expedition is still incomplete."
	has static container open openable
}

Item camera "a wet-plate camera"
	StartsIn packingcase
	Nouns "wet-plate" "plate" "wet" "camera"
	Description "A cumbersome, sturdy, stubborn wooden-framed wet plate model: like all archaeologists, you have a love-hate relationship with your camera."
}

Item newspaper "a month-old newspaper"
	StartsIn packingcase
	Nouns "times" "newspaper" "paper" "month-old" "old"
        Description "~The Times~ for 26 February, 1938, at once damp and brittle after a month's exposure to the climate, which is much the way you feel yourself. Perhaps there is fog in London. Perhaps there are bombs."
	ReadableText "~The Times~ for 26 February, 1938, at once damp and brittle after a month's exposure to the climate, which is much the way you feel yourself. Perhaps there is fog in London. Perhaps there are bombs."
	has readable
}

Item steps "stone-cut steps"
	Nouns "steps" "stone" "stairs" "stone-cut" "pyramid" "burial" "structure" "ten" "10"	
	StartsIn forest
	OnAction: [
		;examine
			if ( this.getuserboolean(rubblefilled) = true ) then 
				currentplayer.print |"Rubble blocks the way after only a few steps" & "."|
				end
			endif
			if ( this.getuserboolean(visitedsquare) = true ) then 
				currentplayer.print "The cracked and worn steps descend into a dim chamber. Yours might have been the first feet to have trodden them for five hundred years. On the top step is inscribed the glyph Q1."
				end
			else
				currentplayer.print "The cracked and worn steps descend into a dim chamber. Yours might be the first feet to have trodden them for five hundred years. On the top step is inscribed the glyph Q1."
				end
			endif
        
        	endif
        	end
        	proc initialise
        		this.adduserboolean(rubblefilled)
        	end
        ]
        
        has scenery
}

Item forestmist "a low mist"
	StartsIn forest
  	Nouns "low" "swirling" "mist"
        Description "The mist has an aroma reminiscent of tortilla.",
        has scenery
        OnAction: [
        	;smell
        		currentplayer.print this.defaultexamine
        		end
        	endif
        	currentplayer.print "The mist is too insubstantial."
        ]
}
        
        
! ---------------------------------------------------------------------------- !
!       The SQUARE CHAMBER.
!
Location squarechamber "Square Chamber" {
	Nouns "lintelled" "lintel" "lintels" "doorways"
        Description "A sunken, gloomy stone chamber, ten yards across. A shaft of sunlight cuts in from the steps above, giving the chamber a diffuse light, but in the shadows low lintelled doorways to east and south lead into the deeper darkness of the Temple."
        U_to forest
        E_to wormcast
        S_to corridor
	has light
	
	OnInput: [
		
		#u
			if ( eggsac.currentlocation = currentplayer.containerlocation ) then
				currentplayer.print "The moment that natural light falls upon the eggsac, it bubbles obscenely and distends. Before you can throw it away, it bursts into a hundred tiny, birth-hungry insects..."
				call StandardLib.Dead
				end
			endif
		endif
		
		;put
			if ( input.noun = eggsac.nounid ) and ( input.noun2 = sunlight.nounid ) then
				currentplayer.print "You drop the eggsac into the glare of the shaft of sunlight. It bubbles obscenely, distends and then bursts into a hundred tiny insects which run in all directions into the darkness. Only spatters of slime and a curious yellow-stone key remain on the chamber floor."
				stonekey.currentlocation = currentplayer.currentlocation
				eggsac.currentlocation = 0
				end
			endif
		endif

	]
	
	OnDisplay: [
		if ( steps.getuserboolean(beendown) = false ) then
			steps.adduserboolean(beendown)
		endif
	]

}

Item carvedinscriptions "carved inscriptions" {
	StartsIn squarechamber
	Nouns "carved" "inscriptions" "carvings" "marks" "markings" "symbols" "moving" "scuttling" "crowd"
        Initial "Carved inscriptions crowd the walls, floor and ceiling."
        Description "Each time you look at the carvings closely, they seem to be still. But you have the uneasy feeling when you look away that they're scuttling, moving about. Two glyphs are prominent: Arrow and Circle."
        StaticMessage "Don't be ridiculous."
	has static
}

Item sunlight "a shaft of sunlight" {
	StartsIn squarechamber
	Nouns "shaft" "of" "sunlight" "sun" "light" "beam" "sunbeam" "ray" "rays" "sun's" "sunlit" "air" "motes" "dust"
        Description "Motes of dust glimmer in the shaft of sunlit air, so that it seems almost solid."
        StaticMessage "It's only an insubstantial shaft of sunlight."
        has static scenery
}

Item chambermist "a low mist"
	StartsIn squarechamber
  	Nouns "low" "swirling" "mist"
        Description "The mist has an aroma reminiscent of tortilla.",
        has scenery
        OnAction: [
        	;smell
        		currentplayer.print this.defaultexamine
        		end
        	endif
        	currentplayer.print "The mist is too insubstantial."
        ]
}

! ---------------------------------------------------------------------------- !
!       The STOOPED CORRIDOR.
!

Location corridor "Stooped Corridor" {
	Description "A low, square-cut corridor, running north to south,
		     stooping you over."
		     
	N_to squarechamber
	S_to shrine
	has darkness
	
	OnDisplay: [
		' Display the door
		call LockableTwoWayDoors.displaydoor stonedoorcorr.id
	]
	
	OnInput: [
		' Block player if the door is closed
		;go,push
			#s
				if ( stonedoorcorr.openclosestate = false ) then 
					currentplayer.print "The door is in the way."
				endif
			endif
		endif
	]
}

Item statuette "a pygmy statuette" extends treasure {
	StartsIn corridor
	Nouns "snake" "mayan" "pygmy" "spirit" "precious" "statuette" "statue"
	Initial "A precious Mayan statuette rests here!"
	Description "A menacing, almost cartoon-like statuette of a pygmy spirit
	             with a snake around its neck."
}
	             
Item stonedoorcorr "a stone door" {
	StartsIn corridor
	Nouns "door" "massive" "big" "stone" "yellow"
	Description "It's just a big stone door."
	ReadableText "The passage is barred by a massive door of yellow stone."
	Initial "The great yellow stone door is open."
	HasUDB locked
	has static openable invisible
	OnAction: [
		call LockableTwoWayDoors.doorhandler stonedoorcorr.id stonedoorshrine.id stonekey.id
	]
}
	

! ---------------------------------------------------------------------------- !
!       The SHRINE.
!
Location shrine "Shrine" {
  	Description "This magnificent Shrine shows signs of being hollowed out from
                    already-existing limestone caves, especially in the western of the
                    two long eaves to the south."
        N_to corridor
        SE_to antechamber
        has darkness
        
        OnDisplay: [
        	call LockableTwoWayDoors.displaydoor stonedoorshrine.id
        ]
        
        OnInput: [
        	;go
	        	#sw
	        		if ( this.SW <> junction.id ) then 
		        		currentplayer.print "The eaves taper out into a crevice which would wind further if it weren't jammed tight with icicles. The glyph of the Crescent is not quite obscured by ice."
		        		end
		        	endif
	        	endif
	        	#n
	        		if ( stonedoorshrine.openclosestate = false ) then 
	        			currentplayer.print "The door is in the way."
	        		endif
	        	endif
	        endif
        ]
}
        
Item paintings "the paintings" {
	StartsIn shrine
  	Nouns "painting" "paintings" "lord" "captive"
        Initial "Vividly busy paintings, of the armoured Lord trampling on a
                 captive, are almost too bright to look at, the graffiti of an
                 organised mob."
        Description "The flesh on the bodies is blood-red. The markers of the Long Count
                     date the event to 10 baktun 4 katun 0 tun 0 uinal 0 kin, the sort
                     of anniversary when one Lord would finally decapitate a captured
                     rival who had been ritually tortured over a period of some years,
                     in the Balkanised insanity of the Maya city states."
        StaticMessage "That's hardly portable."
  	has static
}

Item stonetable "a slab altar" {
	StartsIn shrine
  	Nouns "stone" "table" "slab" "altar" "great"
        Initial "A great stone slab of a table, or altar, dominates the Shrine."
        StaticMessage "That's hardly portable."
  	has supporter static sit stand lay
}

Item mask "a jade mosaic face-mask" extends treasure {
	StartsIn stonetable
	Nouns "jade" "mosaic" "face-mask" "mask" "face"
        Initial "Resting on the altar is a jade mosaic face-mask."
        Description "How exquisite it would look in the Museum."
        has wearable
        
        OnAction: [
        
        	;wear
        		if ( this.currentlocation <> currentplayer.containerlocation ) then 
        			currentplayer.print "(taking the jade mosaic face-mask first)"
        			this.currentlocation = currentplayer.containerlocation
        			currentplayer.outputtoplayer = false
        		endif
        	
        		priest.currentlocation = shrine.id
        		if ( currentplayer.currentlocation = shrine.id ) then 
        			currentplayer.print "Looking through the obsidian eyeslits of the mosaic mask, a ghostly presence reveals itself: a mummified calendrical priest, attending your word."
        			currentplayer.outputtoplayer = false
        			end 
        		endif
        	endif
        	
        	;disrobe,remove
        		priest.currentlocation = 0
        	endif
        ]
}

Item stonedoorshrine "a stone door" {
	StartsIn shrine
	Nouns "door" "massive" "big" "stone" "yellow"
	Description "It's just a big stone door."
	ReadableText "The passage is barred by a massive door of yellow stone."
	Initial "The great yellow stone door is open."
	HasUDB locked
	has static openable invisible
	OnAction: [
		call LockableTwoWayDoors.doorhandler stonedoorcorr.id stonedoorshrine.id stonekey.id
	]
}

! ---------------------------------------------------------------------------- !
!       The WORMCAST.
!
Location wormcast "Wormcast" {
  	Description "A disturbed place of hollows carved like a spider's web, strands of
             empty space hanging in stone. The only burrows wide enough to crawl
             through begin by running northeast, south and upwards."
        W_to squarechamber
        
        OnInput: [
        	;go
        		#s,ne,u
        			currentplayer.print "The wormcast becomes slippery around you, as though your body-heat is melting long hardened resins, and you shut your eyes tightly as you burrow through darkness.<br>"
				if ( eggsac.currentlocation = currentplayer.containerlocation ) then 
					currentplayer.currentlocation = squarechamber.id
					game.displaycurrentlocation
					end
				else
					' Choose randomly from the corridor, forest and square chamber
					var rnum = |3 * random + 1 + makeinteger|
					if ( rnum = 1 ) then 
						currentplayer.currentlocation = corridor.id
						game.displaycurrentlocation
						end
					endif
					if ( rnum = 2 ) then
						currentplayer.currentlocation = forest.id
						game.displaycurrentlocation
						end
					endif
					if ( rnum = 3 ) then 
						currentplayer.currentlocation = squarechamber.id
						game.displaycurrentlocation
						end
					endif
				endif
			endif
			#n,se,sw,e,w,d,nw
				if ( currentplayer.getvalue(warthog) = 0 ) then 
					currentplayer.print "Though you begin to feel certain that something lies behind and through the wormcast, this way must be an animal-run at best: it's far too narrow for your armchair-archaeologist's paunch."
					end
				else
					currentplayer.print "The wormcast becomes slippery around your warthog body, and you squeal involuntarily as you burrow through the darkness, falling finally southwards to...<br>"
					currentplayer.currentlocation = burialshaft.id
					game.displaycurrentlocation
				endif
			endif
		endif		
		
		' If player drops something take it to the square chamber
		;drop
			var imid = getitemfromnoun input.noun
			if ( imid <> 0 ) then 
				currentplayer.print |"The " & item(imid).thename & " slips through one of the burrows and is quickly lost from sight."|
				item(imid).currentlocation = squarechamber.id
				end
			endif
		endif
        ]				
}

Item eggsac "a glistening white eggsac" {
	Nouns "egg" "sac" "eggs" "eggsac"
	StartsIn wormcast
	Initial "A glistening white eggsac, like a clump of frogspawn the size of a
                 beach ball, has adhered itself to something in a crevice in one
                 wall."
                 
        OnAction: [
        
        	end
        	proc before_get
        		returnvalue = "Oh my."
        	end
        ]
}

! ---------------------------------------------------------------------------- !
!       The ANTECHAMBER.
!
Location antechamber "Antechamber" {
  	Description "The southeastern eaves of the Shrine make a curious antechamber."
        NW_to shrine
        has darkness       
}

Item cage "an iron cage" {
	StartsIn antechamber
	Initial "override me"
	Nouns "iron" "cage" "bars" "barred" "frame" "glyphs"
        Description "The glyphs read: Bird Arrow Warthog."
        has enterable transparent container open openable static
        
        OnAction: [

		;get,go
			#in
				currentplayer.print "The skeletons inhabiting the cage come alive, locking bony hands about you, crushing and pummelling. You lose consciousness, and when you recover something grotesque and impossible has occurred...<br>"
				currentplayer.setvalue(warthog) = 1
				skeletons.currentlocation = 0
				warthoglight.currentlocation = currentplayer.containerlocation
				game.displaycurrentlocation
			endif
		endif
		
		;go
			#d
				if ( this.getvalue(flooropen) = 1 ) then 
					currentplayer.currentlocation = burialshaft.id
					game.displaycurrentlocation
					end
				endif
			endif
		endif
            
        	end
        	proc before_displayinitial
        	
        		' IAGE handles sublocations in a different way to Inform
        		' - we just override the display description for the object
        		' in the main location according to where we are. The normal
        		' library will take care of the rest.
        		
        		' Show inner desc if we are inside the cage
        		if ( currentplayer.stateitem = cage.id ) then 
        			if ( this.getvalue(flooropen) = 1 ) then 
	        			returnvalue = "From the floor of the cage, an open earthen pit cuts down into the burial chamber."
	        			cancelevent
        				end
        			else
	        			returnvalue = "The bars of the cage surround you."
	        			cancelevent
        				end
        			endif
        		endif
        	        
        	        ' Otherwise, show the outer description.
			if ( this.openclosestate = true ) then 
        			returnvalue = "An iron-barred cage, large enough to stoop over inside, looms ominously here, its door open. There are some glyphs on the frame."
	        		cancelevent
	        		end
        		else
        			returnvalue = "The iron cage is closed."
        			cancelevent
        			end
        		endif

        	end
        ]
}

Item skeletons "deranged skeletons" {
	Nouns "skeletons" "skeleton" "bone" "skull" "bones" "skulls"
	StartsIn cage
}

! ---------------------------------------------------------------------------- !
!       The BURIAL SHAFT.
!
Location burialshaft "Burial Shaft" {
  	Description "In your eventual field notes, this will read:
             ~A corbel-vaulted crypt with an impacted earthen plug as seal
             above, and painted figures conjecturally representing the Nine
             Lords of the Night. Dispersed bones appear to be those of one
             elderly man and several child sacrifices, while other funerary
             remains include jaguar paws.~ (In field notes, it is essential
             not to give any sense of when you are scared witless.)"
        N_to wormcast
        
        OnInput: [
        
        	;go
	        	#u
	        		if ( cage.getvalue(flooropen) = 0 ) then 
		        		cage.setvalue(flooropen) = 1
		        		currentplayer.setvalue(warthog) = 0
		        		currentplayer.print "Making a mighty warthog-leap, you butt at the earthen-plug seal above the chamber, collapsing your world in ashes and earth. Something lifeless and terribly heavy falls on top of you: you lose consciousness, and when you recover, something impossible and grotesque has happened...<br>"
		        		warthog.currentlocation = this.id
		        		warthoglight.currentlocation = 0
		        		game.displaycurrentlocation
		        		end
		        	else
		        		' If the floor is already open, take the player up to the cage
		       			currentplayer.currentlocation = antechamber.id
		        		currentplayer.stateitem = cage.id
		        		currentplayer.state = 5
		        		game.displaycurrentlocation
		        		end
		        	endif
		        endif
		        
		        #d,s,e,w,ne,nw,se,sw
		        	currentplayer.print "The architects of this chamber were less than generous in providing exits. Some warthog seems to have burrowed in from the north, though."
		        	end
		        endif
		endif
	
		;jump
			if ( cage.getvalue(flooropen) = 0 ) then 
				cage.setvalue(flooropen) = 1
	        		currentplayer.setvalue(warthog) = 0
	        		currentplayer.print "Making a mighty warthog-leap, you butt at the earthen-plug seal above the chamber, collapsing your world in ashes and earth. Something lifeless and terribly heavy falls on top of you: you lose consciousness, and when you recover, something impossible and grotesque has happened..."
	        		warthog.currentlocation = this.id
	        		warthoglight.currentlocation = 0
	        		game.displaycurrentlocation
	        		end
			endif
		endif
        ]
}

Item honeycomb "an ancient honeycomb" extends treasure {
  	
  	StartsIn burialshaft
  	Nouns "ancient" "old" "honey" "honeycomb"
        Initial "An exquisitely preserved, ancient honeycomb rests here!"
        Description "Perhaps some kind of funerary votive offering."
        has edible       
        
        OnAction: [
        
        	;eat
        		currentplayer.print "Perhaps the most expensive meal of your life. The honey tastes odd, perhaps because it was used to store the entrails of the Lord buried here, but still like honey."
        		end
        	endif
        ]
}

! ---------------------------------------------------------------------------- !
!       The UPPER/NORTH CANYON.
!
Location canyonn "Upper End of Canyon" {
  	Description "The higher, broader northern end of the canyon rises only to an
             	     uneven wall of volcanic karst."
        S_to junction
        d_to junction
  	has light
}

Item hugeball "a huge pumice-stone ball" {
	StartsIn canyonn
  	Nouns "huge" "pumice" "pumice-stone" "stone" "ball"
        Initial "A huge pumice-stone ball rests here, eight feet wide."
        Description "A good eight feet across, though fairly lightweight."
        StaticMessage "There's a lot of stone in an eight-foot sphere."
        has static
        
        OnAction: [
        
        	;pull,turn
        		currentplayer.print "It wouldn't be so very hard to get rolling."
        		end
        	endif	
        	
        	;push
        		#ne
        			if ( currentplayer.currentlocation = junction.id ) then 
        				currentplayer.print "The Shrine entrance is far less than eight feet wide."
        				end
        			endif
        		endif
        		if ( input.adverb = 0 ) then 
        			currentplayer.print "It wouldn't be so very hard to get rolling."
        			end
        		endif
        		#n,u
        			currentplayer.print "You strain to push the ball uphill."
        		endif
        		#s,d
        			currentplayer.print "The ball is hard to stop once underway."
        		endif
        		call PushableItems.before_push this.id
        		end
        	endif
	]
}



! ---------------------------------------------------------------------------- !
!       The XIBALBÁ/JUNCTION.
!
Location junction "Xibalba" {
  	Description "Fifty metres beneath rainforest, and the sound of water is
             everywhere: these deep, eroded limestone caves extend like
             taproots. A slither northeast by a broad collapsed column of
             ice-covered rock leads back to the Shrine, while a kind of canyon
             floor extends uphill to the north and downwards to south,
             pale white like shark's teeth in the diffused light from the
             sodium lamp above."
        NE_to shrine
        N_to canyonn
        U_to canyonn
        S_to canyons
        D_to canyons
 	has light
}

Item stela "a stela" extends treasure {
	StartsIn junction
	Nouns "stela" "boundary" "stone" "marker"
        Initial "A modest-sized stela, or boundary stone, rests on a ledge at head height."
        Description "The carvings appear to warn that the boundary of Xibalba,
             Place of Fright, is near. The Bird glyph is prominent."
}

! ---------------------------------------------------------------------------- !
!       The LOWER/SOUTH CANYON.
!
Location canyons "Lower End of Canyon" {
  	Description "At the lower, and narrower, southern end, the canyon stops dead at
             a chasm of vertiginous blackness. Nothing can be seen or heard
             from below."
        N_to junction
        U_to junction
        
        OnDisplay: [
		if ( hugeball.getuserboolean(plugginggap) = false ) and ( hugeball.currentlocation = this.id ) then 
			hugeball.currentlocation = 0
			this.S = onball.id
			this.description = "The southern end of the canyon now continues onto the pumice-stone ball, wedged into the chasm."
			currentplayer.print "The pumice-stone ball rolls out of control down the last few feet of the canyon before shuddering into the jaws of the chasm, bouncing back a little and catching you a blow on the side of the forehead. You slump forward, bleeding, and... the pumice-stone shrinks, or else your hand grows, because you seem now to be holding it, staring at Alligator, son of seven-Macaw, across the ball-court of the Plaza, the heads of his last opponents impaled on spikes, a congregation baying for your blood, and there is nothing to do but to throw anyway, and... but this is all nonsense, and you have a splitting headache."
			end
		endif
	]
        
        OnInput: [
        
        	#s,d
        		if ( this.S <> onball.id ) then 
	        		currentplayer.print "Into the chasm?"
	        		end
	        	endif
        	endif
        ]
  	has light
}

Item chasm "a horrifying chasm" {
	StartsIn canyons
	Nouns "blackness" "chasm" "pit" "horrifying" "bottomless"
	has scenery
	
	OnAction: [
	
		;jump
			#in
				currentplayer.print "You plummet through the silent void of darkness, cracking your skull against an outcrop of rock. Amidst the pain and redness you dimly make out the God with the Owl-Headdress..."
				call StandardLib.CustomDeath "You have been captured"
				end
			endif
			
			#over
				currentplayer.print "It's far too wide."
				end
			endif
		endif
		
		;search
			currentplayer.print "The chasm is deep and murky"
			end
		endif
		
		;put,drop,throw
			#in
				if ( input.noun2 = this.nounid ) then 
					var imid = getitemfromnoun input.noun
					if ( imid <> 0 ) then 
						currentplayer.print |"The " & item(imid).thename & " tumbles silently into the darkness of the chasm."|
						item(imid).currentlocation = 0
						end
					endif
				endif
			endif
		endif
		
		end
	]
}

! ---------------------------------------------------------------------------- !
!       The PUMICE LEDGE.
!
Location onball "Pumice-Stone Ledge" {
  	Description "An impromptu ledge formed by the pumice-stone ball, wedged into
             place in the chasm. The canyon nevertheless ends here."
        N_to canyons
        D_to canyons
        U_to canyons
	has light
}

Item incisedbone "an incised bone" extends treasure {
	StartsIn onball
	Nouns "incised" "carved" "bone"
        Initial "Of all the sacrificial goods thrown into the chasm, perhaps
             nothing will be reclaimed: nothing but an incised bone, lighter
             than it looks, which projects from a pocket of wet silt in the
             canyon wall."
        Description "A hand holding a brush pen appears from the jaws of Itzamna,
             inventor of writing, in his serpent form."
}



! ---------------------------------------------------------------------------- !
!       Objects which are moved into position as the game proceeds
!
Item sodiumlamp "a sodium lamp" {
  	Nouns "sodium" "lamp" "heavy"
  	Initial "must have initial description to override"
  	has lightsource
  	
  	OnAction: [
  	
  		;examine
  			var oput = "It is a heavy-duty archaeologist's lamp, "
  			if ( this.islit = false ) then 
  				oput = |oput & "currently off."|
  			else
  				if ( this.getvalue(batterypower) < 10 ) then 
  					oput = |oput & "glowing a dim yellow."|
  				else
  					oput = |oput & "blazing with brilliant yellow light."|
  				endif
  			endif
  			currentplayer.print oput
  		endif
  		
  		;switch
  			#on
	  			if ( this.getvalue(batterypower) = 0 ) then 
	  				currentplayer.print "Unfortunately, the battery seems to be dead."
	  				end
	  			endif
	  		endif
	  	endif
	  	
  		;light
  			if ( this.getvalue(batterypower) = 0 ) then 
  				currentplayer.print "Unfortunately, the battery seems to be dead."
  				end
  			endif
  		endif
  		
  		;push
  			#sw
  				if ( currentplayer.currentlocation = shrine.id ) then 
  					currentplayer.print "The nearest you can do is to push the sodium lamp to the very lip of the Shrine, where the cave floor falls away."
  					end
				endif
			endif
			call PushableItems.before_push this.id
			end
		endif
  	
  	
  	
  		end
  		proc initialise
  			this.setvalue(batterypower) = 100
  		end
  		proc before_get
  			if ( this.islit = true ) then 
  				returnvalue = "The bulb's too delicate and the metal handle's too hot to lift the lamp while it's switched on."
  				cancelevent
  			endif
  		end
  		proc before_displayinitial
  			if ( this.islit = true ) then 
  				returnvalue = "The sodium lamp squats on the ground, burning away."
  				cancelevent
  				end
  			else
  				returnvalue = "The sodium lamp squats heavily on the ground."
  				cancelevent
  				end
  			endif
  		end
  		proc each_turn
  		  	
  		  	' This means that our custom description will always be used
  			this.movedfromoriginallocation = false
  			
  			' Battery daemon
  			if ( this.islit = true ) then 
  				var batp = this.getvalue(batterypower)
  				batp = |batp - 1|
  				this.setvalue(batterypower) = batp
  				if ( batp = 10 ) then 
  					currentplayer.print "The sodium lamp is getting dimmer!"
  					end
  				endif
  				if ( batp = 5 ) then 
  					currentplayer.print "The sodium lamp can't last much longer."
  					end
  				endif
  				if ( batp = 0 ) then 
  					currentplayer.print "The sodium lamp fades and suddenly dies."
  					this.islit = false
  					game.displaycurrentlocation
  					end
  				endif
  			endif
  		end
  	]
}

Item dictionary "Waldeck's Mayan dictionary" {
	Nouns "dictionary" "local" "guide" "book" "mayan" "waldeck" "waldeck's"
	Description "Compiled from the unreliable lithographs of the legendary raconteur
             and explorer ~Count~ Jean Frederic Maximilien Waldeck
             (1766??-1875), this guide contains what little is known of the
             glyphs used in the local ancient dialect."
             
        OnAction: [
        
        	;consult
        	
        		if ( input.noun2 = 0 ) then 
        			currentplayer.print "Try ~consult dictionary about -name of glyph-~."
        			end
        		endif
        		
        		var lookupnoun = input.snoun2
        		
        		if ( lookupnoun = "q1" ) then 
        			currentplayer.print "(This is one glyph you have memorised!)<br><br>Q1: ~sacred site~."
        			end
        		endif
        		
        		if ( lookupnoun = "crescent" ) then 
        			currentplayer.print "Crescent: believed pronounced ~xibalba~, though its meaning is unknown."
        			end
        		endif
        		
        		if ( lookupnoun = "arrow" ) then 
        			currentplayer.print "Arrow: ~journey; becoming~."
        			end
        		endif
        		
        		if ( lookupnoun = "skull" ) then 
        			currentplayer.print "Skull: ~death, doom; fate (not nec. bad)~."
        			end
        		endif
        		
        		if ( lookupnoun = "circle" ) then 
        			currentplayer.print "Circle: ~the Sun; also life, lifetime~."
        			end
        		endif
        		
        		if ( lookupnoun = "jaguar" ) then 
        			currentplayer.print "Jaguar: ~lord~."
        			end
        		endif
        		
        		if ( lookupnoun = "monkey" ) then 
        			currentplayer.print "Monkey: ~priest?~."
        			end
        		endif
        		
        		if ( lookupnoun = "bird" ) then 
        			if ( this.getvalue(correct) = 0 ) then 
        				currentplayer.print "Bird: ~rich, affluent?~."
        				end
        			else
        				currentplayer.print "Bird: ~dead as a stone~."
        				end
        			endif
        		endif
        		
        		currentplayer.print "That glyph is so far unrecorded."
        	endif
        ]
}

! This may seem a little odd - I am using an item here that represents the available
! glyphs for looking up in the dictionary. This way we have a fast test to see
! what is understood and what is not without resorting to using input.contains or
! an ask statement and parsing it ourselves. This is a useful trick.
Item glyphs "the dictionary glyphs" {
	StartsIn limbo
	Nouns "q1" "crescent" "arrow" "skull" "circle" "jaguar" "monkey" "bird"
}
                    
                    
Item map "a sketch-map of Quintana Roo" {
  	Nouns "map" "sketch" "sketch-map" "quintana" "roo"
        Description "This map marks little more than the creek which brought you
             here, off the south-east edge of Mexico and into deepest
             rainforest, broken only by this raised plateau."
}

Item stonekey "a stone key" {
	StartsIn limbo
	Nouns "stone" "key"
}

Character priest "a mummified priest" {
	StartsIn limbo
	Nouns "mummified" "priest"
        Initial "Behind the slab, a mummified priest stands waiting,
             barely alive at best, impossibly venerable."
        Description "He is desiccated and hangs together only by will-power. Though his
             first language is presumably local Mayan, you have the curious
             instinct that he will understand your speech."
        
        OnAction: [
        	
        	;ask
        		var seln = input.snoun2
        		
        		if ( seln = "dictionary" ) or ( seln = "book" ) then 
        			if ( dictionary.getvalue(correct) = 0 ) then 
        				currentplayer.print "~The ~bird~ glyph... very funny.~"
        				end
        			else
        				currentplayer.print "~A dictionary? Really?~"
        				end
        			endif
        		endif
        		
        		if ( seln = "glyph" ) or ( seln = "glyphs" ) or ( seln = "mayan" ) or ( seln = "dialect" ) then 
        			currentplayer.print "~In our culture, the Priests are ever literate.~"
        			end
        		endif
        		
        		if ( seln = "lord" ) or ( seln = "tomb" ) or ( seln = "shrine" ) or ( seln = "temple" ) then 
        			currentplayer.print "~This is a private matter.~"
        			end
        		endif
        		
        		if ( seln = "paintings" ) then 
        			currentplayer.print "The calendrical priest frowns. ~10 baktun, 4 katun, that makes 1,468,800 days since the beginning of time: in your calendar 19 January 909.~"
        			end
        		endif
        		
        		if ( seln = "ruins" ) then 
        			currentplayer.print "~The ruins will ever defeat thieves. In the underworld, looters are tortured through eternity.~ A pause. ~As are archaeologists.~"
        			end
        		endif
        		
        		if ( seln = "web" ) or ( seln = "wormcast" ) then 
        			currentplayer.print "~No man can pass the Wormcast.~"
        			end
        		endif
        		
        		if ( seln = "xibalba" ) then 
        			if ( shrine.SW = junction.id ) then 
        				currentplayer.print "The priest shakes his bony finger."
        				end
        			else
        				currentplayer.print "The priest extends one bony finger southwest toward the icicles, which vanish like frost as he speaks. ~Xibalba, the Underworld.~"
        				shrine.SW = junction.id
        				end
        			endif
        		endif
        		
        		currentplayer.print "You must find your own answer."
        	endif
        	
        	;tell
        		currentplayer.print "The priest has no interest in your sordid life."
        		end
        	endif
        	
        	;attack,kiss
        		this.currentlocation = 0
        		currentplayer.print "The priest desiccates away into dust until nothing remains, not a breeze nor a bone."
        		end
        	endif
        	
        	;show,give
        		if ( input.noun = dictionary.nounid ) and ( dictionary.getvalue(correct) = 0 ) then 
        			currentplayer.print "The priest reads a little of the book, laughing in a hollow, whispering way. Unable to restrain his mirth, he scratches in a correction somewhere before returning the book."
        			dictionary.setvalue(correct) = 1
        			end
        		endif
        		if ( input.noun = newspaper.nounid ) then 
        			currentplayer.print "He looks at the date. ~12 baktun 16 katun 4 tun 1 uinal 12 kin~, he declares before browsing the front page. ~Ah. Progress, I see.~"
        			end
        		endif
        		currentplayer.print "The priest is not interested in earthly things."
        		end
        	endif
        ]
        
        OnTalk: [
        
        	;go
        		currentplayer.print "~I must not leave the Shrine.~"
        		end
        	endif
        	currentplayer.print "~It is not your orders I serve.~"
        ]
}

! Same trick again - I am using a dummy object for the priests range
! of understandings.
Item priestwords "the priest's words" {
	StartsIn limbo
	Nouns "dictionary" "book" "glyph" "glyphs" "mayan" "dialect" "lord" "tomb" "shrine" "temple" "paintings" "ruins" "web" "wormcast" "xibalba"
}


Character warthog "Warthog" {
	Nouns "wart" "hog" "warthog"
        Initial "A warthog snuffles and grunts about in the ashes."
        Description "Muddy and grunting."
}
Item warthoglight "warthog light" {
	has light lightsource
}



! -----------------------------------------------------------------------------
! Stuff for dealing with the dark
!
Item soundoftinyclaws "a sound of tiny claws" {
	StartsIn limbo
	Nouns "tiny" "claws" "sound" "scuttling" "scuttle" "things" "creatures" "monsters" "insects"
	StaticMessage "The creatures evade you, chittering."
	has static
	OnAction: [
	        ;listen
        		currentplayer.print "How intelligent they sound, for mere insects."
        		end
        	endif
        	;touch,taste
        		currentplayer.print "You wouldn't want to. Really."
        		end
        	endif
        	;smell
        		currentplayer.print "You can only smell your own fear."
        		end
        	endif
        	;attack
        		currentplayer.print "They easily evade your flailing about."
        		end
        	endif
        	currentplayer.print "The creatures evade you, chittering."
        ]
}

Module DarkDaemon {
 
proc inthedark
 
 	if ( currentplayer.cansee = false ) then
 	
 		soundoftinyclaws.currentlocation = currentplayer.currentlocation
 
 		currentplayer.setvalue(darkturns) = |currentplayer.getvalue(darkturns) + 1|
 		var dtur = currentplayer.getvalue(darkturns)
 
 		if ( dtur = 1 ) then
 			currentplayer.print "Somewhere, tiny claws are scuttling."
 			currentplayer.outputtoplayer = false
 			end
 		endif
 
 		if ( dtur = 2 ) then
 			currentplayer.print "The scuttling draws a little nearer, and your breathing grows loud and hoarse."
 			currentplayer.outputtoplayer = false
 			end
 		endif
 
 		if ( dtur = 3 ) then
 			currentplayer.print "The perspiration of terror runs off your brow. The creatures are almost here!"
 			currentplayer.outputtoplayer = false
 			end
 		endif
 
 		if ( dtur = 4 ) then
 			currentplayer.print "You feel a tickling at your extremities and kick outward, shaking something chitinous off. Their sound alone is a menacing rasp."
 			currentplayer.outputtoplayer = false
 			end
 		endif
 
 		if ( dtur = 5 ) then
 			currentplayer.print "Suddenly there is a tiny pain, of a hypodermic-sharp fang at your calf. Almost at once your limbs go into spasm your shoulders and knee-joints lock, your tongue swells..."
 			call StandardLib.Dead
 			end
 		endif
 
 	else
 		currentplayer.setvalue(darkturns) = 0
 		soundoftinyclaws.currentlocation = 0
 	endif
 end
 }