#charset "us-ascii"

#include <adv3.h>
#include <en_us.h>
#include "AHA.h"

/* 
 *   This is the section of the afterlife the PC first encounters after 
 *   passing out in the lecture, before finding a way into hell. It is also 
 *   the part to which he returns after passing through hell and rescuing 
 *   Felicity.
 */


modify defaultSky
    vocabWords = 'uniform pale grey gray -'
    desc = "The sky is a uniform pale grey, neither light nor dark. "
;

Unthing 'grey clouds' 'clouds' @defaultSky
    'The sky is simply a uniform grey; you can discern no clouds in it. '
    isPlural = true  
;

modify defaultGround
    vocabWords = 'solid - '
;

limbo: OutdoorRoom 'Grey Limbo' 'the grey limbo'
    "The greyness of this limbo seems almost tangible; it's not like the
    shifting greyness of thick fog, it's rather the relentless blank greyness
    of absolute nothingness all around -- but not quite all around. In the
    distance towards the direction you arbitrarily label <q>north</q> is a
    faint orange glow, and there's solid ground beneath your feet. "
    up: NoTravelMessage { "Dead you may be, but fly you cannot. " }
    down: NoTravelMessage { "Strange though it may seem, the ground seems solid
        under your feet, and you cannot burrow through it. " }
    cannotGoThatWayMsg = 'You wander aimlessly around in the grey nothingness,
        unsure whether you end up in the same place or another, since here all
        places look alike, since all alike seem to be no place. '
    cannotGoThatWay() { reportFailure(cannotGoThatWayMsg); }
    north: TravelMessage, StopEventList {  -> hellsGate
        "<<doScript()>>"
        eventList = [
            'You trudge through the grey limbo towards the orange glow for what
            seems an eternity, until you start to become afraid that it may be
            no more than an illusion designed to torment you. Eventually,
            however, the glow grows visibly closer, and starts to resolve
            itself into a glowing brazier. Then, at last, you are out of the
            limbo and standing by a huge gate. ',
            
            'You trudge through the grey limbo back towards the orange glow of
            the brazier. ' 
        ]      
    }
    out asExit(north)
    vocabWords = 'grey limbo/void'
    thinkHere() 
    {
        "You think you'd rather be somewhere else; the orange glow to the north
        looks the best bet. ";
    }   
    roomAfterAction()
    {
        if(gActionIs(Jump))
            "Gravity seems to be functioning normally here, at least. ";
        if(gActionIs(Yell))
            "The sound of your <<gVerbName>> is swallowed up by the 
            all-embracing nothingness that surrounds you. ";
    }
    northLook = "In the distance to the north is a faint orange glow. "
    defaultLook(dir) { "To the <<dir.name>> is nothing but blank greyness. "; }
    
;


+ PresentLater, SimpleNoise 'faint north n intermittent banging sound' 
    'banging sound'
    "A faint, intermittent banging sound comes from the north. "
    initiallyPresent = true
    plKey = 'demon'
;

+ orangeGlow: Distant 'faint orange merest hint/glow/light' 'faint orange glow'
    "It's only just barely discernible, the merest hint of an orange light to
    the north. "
    dobjFor(Follow) remapTo(North)
    dobjFor(Enter) remapTo(North)  
;

+ Decoration 'relentless blank absolute greyness/nothingness' 'blank greyness'
    "The blank greyness surrounds you on every side, and seems almost totally
    devoid of qualities, being as close to non-being as anything perceptible
    can be. "
    notImportantMsg = 'The blank greyness is so close to being nothing that there is
        nothing {you/he} can do with it. '    
;

+ Unthing 'thick grey fog' 'fog'
    'What surrounds you is not fog; it is less substantial and more uniform
    than fog would be. '
;

//==============================================================================

hellsGate: OutdoorRoom 'Hell\'s Gate' 'Hell\'s Gate'
    "A huge gate, studded with iron spikes, is set into a steep rocky slope
    that bars the way north. Carved into the rock above the gate are the words
    ABANDON HOPE ALL YE THAT ENTER HER. Between this grim rock face and the
    endless grey limbo to the south a narrow path straggles along the foot of
    the hillside to east and west. To one side of the gate stands a large iron
    brazier, filled with glowing coals that cast an eerie orange light.
    <<woodenLadder.isIn(self) ? 'Next to the brazier a long wooden ladder leans
        against the pediment of the gate. ' : ''>>"
    south = limbo
    north = studdedGate
    east = pipeside
    west: TravelMessage {
        -> (gameMain.symmetry ? fissureEdge : chasmEdge)
        "You trudge westwards along the base of the rocky hillside for what
        seems a very long time -- though it's not clear what meaning time has
        here -- until eventually the path bends towards the north and starts to
        ascend the hill. <<gameMain.symmetry?  '' : 'Although the path is
            pretty rugged and quite steep in places, you continue to struggle
            up it until you eventually reach the summit. '>>"
    }
    thinkHere()
    {
        if(demon.isIn(self))
            "It's hard to tell which is odder -- the gate or the demon. ";
        else
            "You wonder where the demon went. ";
    }
    northLook = "A huge gate stands directly to the north. "
    eastLook = "A narrow path meanders off to the east. "
    westLook = "A narrow path runs along the base of the hillside to the west. "
    northwestLook = "The hillside soars up on the west side of the gate. "
    northeastLook = "To the east of the gate is a sheer rock face. "
    defaultLook(dir)
    {
        "There's nothing to the <<dir.name>> but the grey limbo. ";
    }
;

+ studdedGate : IndirectLockable, Door 'huge massive studded gate' 'huge gate'
    "The massive gate is some twenty feet high and twice as wide. Not only is
    it covered with iron spikes, it looks strong enough to withstand an army. A
    large notice has been fixed to the centre of the gate, at just about eye
    level. "
    openStatus = 'The gate is firmly closed' // This gate never opens. 
    cannotClimbMsg = 'You\'re not that keen to get into hell, and those spikes
        look really mean. '
    cannotUnlockMsg = 'There doesn\'t seem to be any way to unlock it. '
;

++ gateNotice: Component 'large notice/sign' 'large notice'
    "The notice on the gate reads:\b  
    STRICTLY NO ADMITTANCE -- \n 
    HELL CLOSED FOR DEMYTHOLOGIZATION<.reveal demyth>"   
    nothingBehindMsg = &cannotSeeBehindMsg
;

++ Component 'sharp solid iron spikes/spike' 'iron spikes'
    "Sharp iron spikes cover both the front and top of the gate, as if hell
    were so popular that attempts to get in had to be actively discouraged. "
    shouldNotBreakMsg = 'Chance would be a fine thing; there\'s no way you can
        break those solid iron spikes. '
    uselessToAttackMsg = 'You could end up impaling yourself on them, but that
        would do more damage to you than to them. ' 
    isPlural = true
;

+ Heavy 'large iron glowing brazier/legs/bowl' 'iron brazier'
    "The iron brazier is basically a large bowl mounted on three legs; the bowl
    is filled with glowing orange coals. "  
    shouldNotBreakMsg = '\'Twould be far better just to leave it there
        undamaged, continuing to provide heat and light. Besides, you\'ve
        nothing to break it with. ' 
    uselessToAttackMsg = (shouldNotBreakMsg)
    feelDesc = "It's <i>very</i> hot! "
    lookInDesc = "It's full of glowing coals. "
    cannotSitOnMsg = 'You\'d rather not fry your buttocks today. ' 
    cannotStandOnMsg = 'It looks too hot for that. '
    notAContainerMsg = (gIobj == self ? &noReasonToBurnMsg : nil)  
    notASurfaceMsg = (gIobj == self ? &noReasonToBurnMsg : nil)
    cannotExtinguishMsg = 'Why would you want to do that? The brazier is
        the best source of light and heat for miles around. '   
;

+ CustomFixture 'glowing orange coal/coals' 'glowing orange coals'
    "The orange coals glowing in the brazier seem to be the principal source
    of both heat and light round here. "
    isPlural = true
    cannotTakeMsg = 'They look burning hot -- you\'d do better to leave
        them alone; whatever the state of your health you can still feel pain. '
    feelDesc = "You can feel the heat by just putting your hand near them;
        you obviously don't want to touch them. "
    cannotExtinguishMsg = 'Even if you had something to hand to do that with,
        which you don\'t, it would probably be a bad idea -- that brazier is
        the only thing providing heat and light round here. '
    verifyDobjBurn() { illogicalAlready('The coals are already burning. '); }
    cannotSitOnMsg = 'You haven\'t had the proper training to ignore the   
        pain that would surely result. '
    cannotStandOnMsg = (cannotSitOnMsg) 
    notAContainerMsg = (gIobj == self ? &noReasonToBurnMsg : nil)
    notASurfaceMsg = (gIobj == self ? &noReasonToBurnMsg : nil)
    cannotEatMsg = 'The coals are burning hot, rock hard, and totally
        indigestible; apart from that, eating them would be an excellent idea
        -- like hell!'
    tasteDesc = "You don't want to risk burning your mouth. "
;

++ SimpleOdor 'warm smell/burning' 'smell of burning'
    "A warm smell of burning rises from the coals. "
;

+ Distant 'large stone rock (gate) pediment/lintel/(gate)' 'lintel'
    "The gate lintel is a large stone pediment with an inscription
    carved on it. "
;

++ gateLettering : Component 'incised carved lettering/inscription/words' 
    'lettering'
    "The lettering on the lintel of the gate reads ALL HOPE ABANDON YE WHO
    ENTER HER [<i>sic</i>]. You surmise that a final E has been chipped away by
    the workdemon. "
    nothingBehindMsg = &cannotLookBehindMsg
;

+ woodenLadder: PresentLater, Heavy, Platform 'long wooden ladder' 'ladder'
    "It's leaning against the lintel of the gate. "
    cannotClimbMsg = 'You\'ve no reason to climb the ladder: the demon may look
        harmless enough, but there\'s no point in putting it to the test by
        invading his personal space. '
    cannotMoveMsg = &needlesslyUnpleasantMsg
    shouldNotBreakMsg = 'That would be a senseless act of vandalism, even if
        you could manage it. It would also quite literally bring an enraged
        demon down on your head. All things considered that\'s probably a bad
        idea. '
    bulkCapacity = 12
    noRoomToStandMsg = (cannotClimbMsg) 
    initiallyPresent = true
    plKey = 'demon'
;

+ demonTools : PresentLater, Decoration 'hammer/mallet/chisel/tools' 'tools'
    "The demon is holding a mallet in one hand and a chisel in the other. "
    isPlural = true
    initiallyPresent = true
    plKey = 'demon'
    notImportantMsg = 'The demon doesn\'t look like he\'s about to let you
        meddle with his tools. '
;

+ Fixture 'narrow east-west path' 'narrow path'
    "The narrow path runs east-west between the foot of the hillside and the
    endless grey limbo. "
    dobjFor(Follow)
    {
        verify() { }
        action() {
            "Do you want to go east or west? ";
        }     
    }
    dobjFor(Take) maybeRemapTo(gVerbName=='take', Follow, self)
    cannotTakeMsg = &cannotPickUpMsg
;

+ Fixture 'steep grim rock rocky impenetrable (foot)/hillside/slope/(face)/barrier' 
    'hillside'
    "The steep rocky slope towers up on either side of the massive gate,
    forming an impenetrable barrier. "
    cannotClimbMsg = 'It\'s far too steep to climb. '
;

+ Vaporous 'eerie (orange) light/glow' 'eerie orange light'
    "The main source of light round here seems to be the brazier, which casts
    an eerie orange glow over everything around. "
;


MultiLoc, Enterable ->limbo 'endless featureless grey limbo' 'endless grey limbo'
    "It's almost featureless, being as close to non-being as anything that
    exists can be. "
    locationList = [pipeside, hellsGate]
#ifdef __DEBUG
    verifyDobjPow() { nonObvious; }
#endif
;

//==============================================================================

pipeside : OutdoorRoom 'Narrow Path' 'the narrow path'
    "The narrow path from the west finally peters out here, fading into the
    grey limbo to east and south. <<northLook>>"
    west = hellsGate
    south = limbo
    southwest asExit(south)
    southeast asExit(east)
    in : TravelConnector {
        dobjFor(TravelVia) remapTo(Enter, pipe)
        isConnectorListed = nil
    }
    east: FakeConnector { "You wander off into the grey limbo, but the sheer
        neverending nothingness of it soons becomes oppressive, so you turn
        back and gratefully return to the oasis of somethingness. " }
    thinkHere() { nestedAction(ThinkAbout, pipe); }  
    northLook = "To the north the rough rocky hillside rises almost vertically,
        forming an impenetrable barrier; just above ground level a pipe juts
        out horizontally between the rocks. "
    northwestLook = "That way you see more of the rocky hillside. "
    northeastLook = (northwestLook)
    westLook = "A narrow path runs west from here along the base of the
        hillside. "
    defaultLook(dir) { "There's nothing to the <<dir.name>> but the grey
        limbo. "; }
;

+ pipe : EntryPortal 'large round blackened black steel old flue pipe/soot' 'pipe'
    "The pipe is large -- just about large enough to crawl into at any rate --
    with a round cross-section. It appears to be made of steel, though in
    places the steel has become blackened with soot. "
    connector : TravelMessage {
        -> insideBoiler
        "<<knife.isIn(gPlayerChar) ? 'You decide you need both hands free for
            this task, and you don\'t want to risk cutting yourself, so before
            you start you toss the knife aside. ' : ''>> You
        <<knife.isIn(gPlayerChar) ? 'then ' : ''>>crawl cautiously into the
        pipe, but your caution proves fruitless, for after inching forward the
        first couple of feet down the dark pipe, you find -- too late to do
        anything about it -- that it suddenly bends from horizontal to
        vertical. Before you can stop yourself you are sliding down it at
        breakneck speed, only to be ejected at the far end. You just start
        wondering if you're ever going to be able to find a way to get to the
        golden glow when you land with a bone-rattling bump. <<achieve()>>"
        canTravelerPass(traveler)  {  return pipeCable.hasBeenCut;   }
        explainTravelBarrier(traveler)
        {
            "You peer into the pipe, and decide you probably could just about
            crawl into it, except for the fact that a thin wire cable stretches
            across its diameter, about about six inches in from the mouth of
            the pipe. <<pipeCable.discover()>><.reveal pipe-cable>";
        }
        achieve { achievement.awardPointsOnce; knife.moveInto(nil); }
        achievement: Achievement { +1 "sliding down the flue pipe" }
        travelBarrier = [pipeBlock]
    }
    dobjFor(Board) asDobjFor(Enter)
    iobjFor(ThrowInto)
    {
        verify() {}
        check() 
        {
            failCheck('It occurs to you that if you throw {the dobj/him} into
                the pipe you might not be able to retrieve it, so you
                desist. ');
        }
    }
    
    
    blocked = nil
    
    
    cannotStandOnMsg = 'You probably could clamber up onto the top surface of
        the pipe, but it would serve no conceivable purpose; it wouldn\'t help
        much in climbing up the hillside, for instance. '
    cannotSitOnMsg = 'You try sitting on top of the pipe for a moment or two,
        but find it such an uncomfortable perch that you quickly get off it again. '
    cannotCleanMsg = 'It could probably do with a good clean, but you don\'t
        have the wherewithal. '
    cannotClimbMsg = (cannotStandOnMsg)
    nothingBehindMsg = &cannotSeeBehindMsg
    lookInDesc
    {
        if(blocked)
        {
            "About six inches in from the mouth is a wire grating that
            completely blocks the pipe. ";
            if(!wireGrating.isIn(self))
                wireGrating.makePresent();
        }
        else if(pipeCable.isIn(self))
        {
            pipeCable.discover();
            if(pipeCable.hasBeenCut)
                "A cable, now severed in two, dangles down the inside of the
                pipe. ";
            else
                "A thin wire cable stretches across the internal diameter of
                the pipe. ";
        }
    }
;

++ wireGrating : PresentLater, CustomFixture 
    'sturdy wire welded circle/grating/grille' 
    'wire grating'
    "The grating looks pretty sturdy, and it completely blocks entrance to the
    pipe for anything much larger than an earwig. "
    cannotTakeMsg = 'You can\'t budge it; it\'s too firmly welded in place. '
;

++ pipeCable : Hidden, CustomFixture 'thin wire cable' 'thin wire cable'
    "The thin wire cable <<hasBeenCut ? 'has been cut near the middle' :
      'stretches across the inside diameter of the pipe'>>. "
    hasBeenCut = nil
    dobjFor(CutWith)
    {
        verify() 
        {
            if(hasBeenCut)
                illogicalAlready(alreadyCutMsg); 
        }
        action()
        {
            "You manage to cut through the cable with {the iobj/him}. ";
            hasBeenCut = true;
            cmdDict.addWord(self, 'severed', &adjective);
        }
    }   
    cannotTakeMsg = 'It\'s too firmly attached: you can\'t budge it. '
    shouldNotBreakMsg = (hasBeenCut ? alreadyCutMsg :
                         'It\'s too tough; you can\'t make any impression on it. ')
    uselessToAttackMsg = 'This achieves nothing. '
    alreadyCutMsg = 'The wire has already been cut. '
;

+ Fixture 'impenetrable rough rocky vertical hillside/barrier' 
    'rough rocky hillside'
    "It's almost vertical, and soars way above your head. "
    cannotClimbMsg = 'It is too steep, and you are not sufficiently agile. '
    nothingBehindMsg = &cannotLookBehindMsg
;

+ Decoration 'rocks' 'rocks'
    "They're firmly embedded in the hillside, with a pipe sticking out of them
    near the foot. "
    isPlural = true
    nothingBehindMsg = &cannotLookBehindMsg
;


pipeBlock : TravelBarrier
    canTravelerPass(traveler) { return !pipe.blocked; }
    explainTravelBarrier(traveler)
    {
        "Since you last went that way the pipe has been blocked by a circle of
        wire grating welded about six inches inside the mouth of the pipe. ";
        if(!wireGrating.isIn(self))
            wireGrating.makePresent;
    }
;

//==============================================================================

/* 
 *   The following location is available only when gameMain.symmetry is 
 *   true; it provides an extra location between Hell's Gate and the chasm 
 *   edge to allow more symmetrical exits when travelling between them
 */

fissureEdge: OutdoorRoom 'Bend in Path' 'the bend in the path'
    "A deep fissure just to the west of here forces the path from the east to
    make a sharp turn north up the steep hillside. <<southLook>>"
    south: FakeConnector { "You wander a short distance into the grey limbo,
        until it becomes almost impossible to take your bearings. At that point
        you stop, anxious not to lose you way, and especially anxious not to
        blunder into the fissure. After a few increasingly nerve-racking
        minutes you finally manage to find your way back out. " }
    southeast asExit(south)
    east = fissurePathEast
    north = fissurePathNorth  
    up asExit(north)
    southLook = "To the south is the ubiquitous grey limbo, into which the
        fissure runs. "
    westLook = "A short way to the west a deep north-south fissure cuts across
        the ground. "
    northwestLook = "Directly to the northwest the fissure slices into
        the foot of the hillside. "
    northLook = "To the north the path from the east turns sharply to
        the right and struggles bravely up the hillside. "
    eastLook = "To the east the path runs along the foot of the steep
        hillside. "
    downLook = "You look down at the bubbling hot lava at the bottom of the
        fissure, and then quickly retreat from the heat. "
    west : NoTravelMessage { "A few paces to the west take you right to the
        edge of the fissure, which is full of steaming red lava. You quickly
        retreat from the heat. " }
    roomBeforeAction
    {
        if(gActionIs(JumpOffI))
            replaceAction(Enter, deepFissure);
    }
    throwDests = [[westDirection, deepFissure]]
    thinkHere = "You can see why the path is forced to turn north here: there's
        no way anyone could get across that fissure. <<chasm.seen ? 'It\'s
            clearly a continuation of the chasm you saw to the north, and no
            more crossable than that is. ' : ''>>"
;

+ fissurePathEast: TravelWithMessage, PathPassage
    'narrow east (e) path*paths' 'path east'
    "The path to the east straggles along the foot of the hillside. " 
    destination = hellsGate
    travelDesc = "You retrace your steps back along the hillside for what seems
        an age (or two), until you eventually arrive back at the gate. "
;

+ fissurePathNorth: TravelWithMessage, PathPassage
    'narrow steep (n) north path*paths' 'path north'
    "The narrow path to the north struggles bravely up the steep hillside. "
    destination = chasmEdge
    travelDesc = "Although the path is pretty rugged and quite steep in places, 
        you manage to struggle up it until you eventually reach the summit. "
    dobjFor(Climb) asDobjFor(TravelVia)
    dobjFor(ClimbUp) asDobjFor(TravelVia)
;

+ deepFissure : Fixture 'deep fissure' 'deep fissure'
    "The fissure, which is about a hundred feet wide and a hundred deep, runs
    north-south, effectively blocking the way west. At its bottom runs a stream
    of steaming red lava. "
    iobjFor(ThrowInto)
    {
        verify() { }
        check()
        {
            if(gDobj == knife)
                failCheck('If you throw the knife into the fissure you almost
                    certainly won\'t be able to retrieve it, and you\'d rather
                    hang on to it for now. ');
        }
        action()
        {
            "{You/he} throw{s} {the dobj/he} into the fissure, where
            {it dobj/he} rapidly fall{s} into the steaming lava and
            disappear{s} out of sight. ";
            gDobj.moveInto(nil);
        }
    }
    cannotCrossMsg = 'It\'s far too wide for you to jump over, and there\'s quite
        obviously no other way to cross it here. '
    cannotJumpOverMsg = (cannotCrossMsg)
    cannotEnterMsg = 'The fissure is full of boiling hot lava, which you\'d
        fall straight into. Whatever your state of health, life or death, you
        can feel the heat of the lava from here, and you\'re quite sure that
        falling into it would be an extremely painful experience. You also have
        no idea how you\'d get back out again, even supposing you survived to
        make the attempt. '
    dobjFor(Follow) remapTo(South)
;

+ Distant 'steaming livid bubbling sluggish red hot stream/lava' 'lava'
    "The livid red lava twenty feet below bubbles along in a sluggish stream. "
    iobjFor(ThrowInto) remapTo(ThrowInto, DirectObject, deepFissure)
    dobjFor(Smell) { verify() { } }
    dobjFor(Enter) remapTo(Enter, deepFissure)
;

++ SimpleOdor 'heat/sulphur/sulfur/whiff/smell/odour/odor' 'heat'
    "The lava smells hot and sulphurous. "
;

+ Fixture 'steep foot/hillside/hill/mountain/mountainside/slope' 'hillside'
    "The hillside rises sharply to the north, and continues to east and west,
    except where the fissure slices through it. "
    dobjFor(Climb) remapTo(TravelVia, fissurePathNorth)
    dobjFor(ClimbUp) remapTo(TravelVia, fissurePathNorth)
;

+ Enterable ->(fissureEdge.south) 'ubiquitous featureless grey limbo' 
    'grey limbo'
    "The grey limbo to the south is as featureless here as elsewhere. "
;

//==============================================================================
class ChasmRoom : OutdoorRoom
    roomBeforeAction
    {
        if(gActionIs(JumpOffI))
            replaceAction(Enter, chasm);
    }
    throwDests = [[westDirection, chasm], [southwestDirection, chasm],
        [northwestDirection, chasm]]
;

rockGround : Floor 'solid rock/ground/floor' 'ground'
    "The ground beneath your feet is solid rock. "
;

chasmEdge : ChasmRoom 'Edge of Chasm' 'the edge of the chasm'
    "<<westLook>><<northLook>><<southLook>> "
    south = edgePathDown
    west: NoTravelMessage {
        "There's no way you can cross that chasm from here; one step further
        west will send you plunging straight into the boiling lava below. "
    }
    east: NoTravelMessage {
        "The steep, rocky hillside blocks your path; and it's too steep to climb. "
    }
    southeast asExit(south) 
    down asExit(south)
    north = chasmEdgePath    
    
    thinkHere()
    {
        "You think that you'd really, really like to find a way to reach that
        glorious golden city. ";
    }
    roomParts = [rockGround, defaultSky]
    westLook = "At your feet a deep, wide chasm makes progress to the west
        totally out of the question. Somewhere far to the west on the other
        side of the chasm, at a distance impossible to judge, is a shimmering,
        golden glow; but since the chasm plunges down several hundred feet to a
        river of hissing, bubbling lava there's clearly no way of reaching it
        from here. "
    northLook = "To the north, the narrow path continues along the ledge
        between the chasm and the steep, rocky hillside, towards a thin black
        line stretching across the chasm in the distance. "
    southLook = "To the south an equally narrow path leads back down the
        hillside. "
    downLook = "You peer down the chasm down to the bubbling lava far below,
        and then step smartly back from the brink. "
    defaultLook(dir)
    {
        if(dir is in (southwestDirection, northwestDirection))
            "You don't see much across the chasm. ";
        else
            "The steep rocky hillside rises up to the east. ";
    }
;

+ chasmEdgePath: TravelWithMessage, PathPassage 'narrow north (n) path/ledge*paths' 
    'narrow path north'
    "The narrow path runs north along the ledge. "
    travelDesc = "You edge your way carefully along the narrow, treacherous
        ledge, ever conscious of the sheer drop down into the deadly lava just
        to your left. As you walk, the thin line across the chasm slowly
        resolves itself into a flimsy rope bridge, which you eventually
        reach. "
    nothingBehindMsg = &unclearWhatBehindMsg
    disambigName = 'path north'
;

+ edgePathDown : TravelWithMessage, PathPassage 
    'equally narrow down south (s) path*paths' 
    'narrow path south'
    "The narrow path south leads back down the hillside. "
    dobjFor(ClimbDown) asDobjFor(TravelVia)
    travelDesc = "You clamber down the steep path, occasionally missing your
        footing, but always recovering it just in time, until the path levels
        out and turns to the east<<gameMain.symmetry ? '' : '; thereafter the
            going gets easier, but it\'s still a long trudge between the barren
            hillside and the grey limbo before you reach a significant
            landmark'>>. "
    destination = (gameMain.symmetry ? fissureEdge : hellsGate)
    disambigName = 'path south'
;

+ distantGlow : Distant 'shimmering distant vague beautiful yellow golden 
    glow/city/blob' 
    'golden glow'
    "It's hard to make out exactly what the golden glow is, since it
    <EM>will</EM> keep shimmering. At one moment it looks like a vague golden
    blob, at the next it looks like a beautiful city, a place of ultimate
    felicity and bliss. Your heart leaps at the sight (at least it would if it
    were still beating), and you feel filled with a sense of deep yearning, as
    if failure to reach the golden city would be the ultimate loss, tragic
    beyond all reckoning. "
;

+ blackLine : Distant 'narrow thin shallow flimsy rope black
    line/bridge/parabola/cable' 
    'narrow black line'
    desc()
    {
        if(ropeBridge.seen)
            "From here it just looks line a black line stretched across the
            chasm in a shallow parabola, but you now know it to be the rope
            bridge.";
        else
            "It's hard to make out what it is from here; it's simply a black
            line strung across the chasm in a shallow parabola -- some sort of
            cable perhaps. It would be too much to expect it to be a bridge you
            could actually cross. ";
    }
;

+ Fixture 'steep sheer rough rocky hillside' 'steep rocky hillside'
    "The rocky hillside rises sheer to the east -- rough, but without any
    handholds or footholds you'd care to try. "
    cannotClimbMsg = 'There\'s no way you\'re even going to attempt it. '
    nothingBehindMsg = &cannotLookBehindMsg
;

+ Distant 'far other barren rocky opposite side/(chasm)/(rock)' 'far side'
    "Immediately abutting the chasm the far side seems to consist of little but
    barren rock, but every time you look across your eyes are immediately
    drawn to the golden glow in the distance. "
;

grammar nounPhrase(pathNorth) :
    ('narrow' | ) 'path' ('north' | 'n')
    : SpecialNounPhraseProd
    getMatchList = [chasmEdgePath, fissurePathNorth]
    getAdjustedTokens =
    ['path', &noun, 'north', &adjective]
;

grammar nounPhrase(pathSouth) :
    ('narrow' | ) 'path' ('south' | 's')
    : SpecialNounPhraseProd
    getMatchList = [edgePathDown]
    getAdjustedTokens =
    ['path', &noun, 'south', &adjective]
;

grammar nounPhrase(pathEast) :
    ('narrow' | ) 'path' ('east' | 'e')
    : SpecialNounPhraseProd
    getMatchList = [fissurePathEast]
    getAdjustedTokens =
    ['path', &noun, 'south', &adjective]
;

chasm : MultiLoc, Fixture 'deep wide chasm chasm/walls/edge/bottom' 'chasm'
    "The chasm is well over a hundred feet wide, and several hundred feet deep.
    Its walls are absolutely sheer -- once over the edge there would be no way
    back up. Deep down at the bottom of the chasm runs a river of boiling red
    lava. "
    locationList = [chasmEdge, ropeLedge, farSide]
    dobjFor(Cross)
    {
        verify()
        {
            if(!gActor.isIn(ropeLedge))
                illogical('There\'s no way across the chasm from here. ');
        }
        action()
        {
            replaceAction(West);
        }
    }
    iobjFor(ThrowInto)
    {
        verify() { }
        check() {
            if(gDobj == knife)
                failCheck('If you throw the knife into the chasm it\'ll almost
                    certainly be lost for good, but you decide to hang on to it for now.' );
        }
        action() {
            "{You/he} toss{es} {the dobj/him} over the edge of the chasm, and watch{es}
            it fall until it hits the stream of lava below, where {it dobj/he} sink{s}
            rapidly out of sight. ";
            gDobj.moveInto(nil);
        }
    }
    iobjFor(ThrowAt) remapTo(ThrowInto, DirectObject, self)
    dobjFor(JumpDown) asDobjFor(Enter)
    cannotJumpOverMsg = 'It\'s way too wide, you\'d never make it. And one look
        at the boiling lava a hundred yards or so below is quite enough to convince
        you that a failed attempt is <i>definitely</i> not worth making. '
    cannotEnterMsg = 'You really don\'t want to do that. For one thing, it\'s
        pretty obvious that there\'d be no way back up. And for another, that boiling
        lava at the bottom of the chasm looks hot and dangerous; whether or not it could 
        actually do you any harm might be a theoretically debatable matter, but you
        viscerally shrink from the undoubtedly painful and possibly deadly results
        of falling into it; for whether you are already dead or just experiencing
        near-death, you are still quite capable of experiencing pain. '
    nothingBehindMsg = 'Behind the chasm is the far side. '
;

MultiLoc, Distant 'running red ruddy boiling hissing bubbling steaming river/lava' 
    'lava'
    "The lava bubbles and hisses, sending out continual smoke and fumes and
    occasional jets of molten rock. "
    locationList = [chasmEdge, ropeLedge, farSide]
    dobjFor(Smell) { verify() { inherited Thing; }  }
    iobjFor(ThrowInto) remapTo(ThrowInto, DirectObject, chasm)
    iobjFor(ThrowAt) remapTo(ThrowInto, DirectObject, chasm)  
    dobjFor(Enter) remapTo(Enter, chasm)   
;

+ Odor 'strong whiff/sulfur/sulphur' 'whiff of sulphur'
    descWithSource = "A strong whiff of sulphur rises from the boiling lava. "
    descWithoutSource = (descWithSource)
    sourceDesc = (descWithSource)
    hereWithSource = "You catch a strong whiff of sulphur. "
    isAmbient = nil
    displaySchedule = [2, 2, 4, 4, 8]
;

MultiLoc, Distant 'occasional molten rock/jet/jets' 'jets of molten rock'
    "From time to time jets of molten rock spume up from the bubbling lava at
    the bottom of the chasm, though fortunately the chasm is far too deep for
    them to reach you. "
    locationList = [chasmEdge, ropeLedge, farSide] 
    isPlural = true
;


MultiLoc, Vaporous 'sulphurous sulfurous continuous smoke/fumes' 'fumes'
    "The fumes rising from the lava smell strongly of sulphur. "
    isPlural = true
    dobjFor(Smell) asDobjFor(Examine)
    locationList = [chasmEdge, ropeLedge, farSide] 
;

//==============================================================================

ropeLedge: ChasmRoom 'Ledge by Bridge' 'the ledge by the bridge'
    "The ledge path from the south comes to an abrupt end by a flimsy rope
    bridge stretching westwards across the chasm. A sheer wall of rock makes
    progress further north totally out of the question, but a rough flight of
    stairs has been cut into the rock face to the east. The heat rising from
    the chasm is palpable here; indeed, a haze partly shrouds the bridge,
    making it hard to discern what exactly lies on the far side. "
    south = ropeLedgePath
    west : OneWayRoomConnector {
        -> farSide
        canTravelerPass(traveler) { return ropeBridge.isHeld; }
        explainTravelBarrier(traveler)
        {
            "The rope bridge looks far too unsafe to cross in its present
            state; if you try you'll almost certainly be pitched into the
            boiling lava. ";
        }
        noteTraversal(traveler)
        {
            if(traveler.contents.length > 0)
            {
                "Before setting out, you decide you\'d best lighten your load
                as much as you can, so you start by dropping everything you'\re
                carrying.\b";
                foreach(local cur in traveler.contents)
                    if(!cur.ofKind(NonPortable))
                    cur.moveInto(traveler.location);
            }
            "Gingerly, you step on to the wobbly rope bridge, clutching at the
            side-rope in a desperate attempt to keep your balance.<.p>
            <q>Hurry up!</q> Felicity urges you on, <q>I can't hold this rope
            for ever!</q><.p>
            You turn back to glance at her, but she waves you impatiently on.
            Gritting your teeth, you take another couple of steps, while the
            bridge sways alarmingly beneath you, and you are all too aware of
            the boiling lava bubbling a hundred feet below.<.p>
            <q>For goodness's sake, hurry <i>up</i>!</q> Felicity calls.<.p>
            You take a deep breath and plunge on, gathering speed as you become
            more used to the motion of the bridge, and your feet find more
            confidence in their step. By the time you reach the middle of the
            bridge you are almost running, so that you complete the second half
            of the crossing much more rapidly than the first, and arrive
            panting and shaking at the other side.<.p>";
        }
    }
    north : NoTravelMessage { "A sheer rock face cuts off any progress in that
        direction. " }
    east = cliffStairs
    up asExit(east)
    roomParts = [rockGround, defaultSky]
    thinkHere()
    {
        if(ropeBridge.isHeld)
            "To cross or not to cross, that is the question. ";
        else
            "You wish there were some way to fix that rope bridge. ";
    }
    downLook = (chasmEdge.downLook)
    northLook = "To the north is a sheer wall of rock. "
    eastLook = "A rough flight up steps leads up the rock face to the east. "
    southLook = "A path leads back along the ledge to the south. "
    westLook = "A flimsy rope bridge stretches over the chasm to the west. "
    northeastLook = "Directly to the northeast is the corner formed by the
        north and east rock faces. "
    southeastLook = "A steep rock face runs along the east side of the
        narrow ledge. "
    southwestLook = "The chasm runs along the west side of the narrow ledge. "
;

+ Fixture 'corner' 'corner'
    "<<location.northeastLook>>"
;

+ ropeLedgePath : PathPassage ->chasmEdgePath 'narrow ledge path/ledge' 'path'
    "The narrow path runs southwards along the ledge between the hillside and the
    edge of the chasm. "
    nothingBehindMsg = &unclearWhatBehindMsg
;


+ cliffStairs : TravelWithMessage, StairwayUp 
    'steep narrow rough uneven flight/stairs/steps' 
    'flight of stairs'
    "The steep flight of narrow steps is cut into the eastern cliff. "
    travelDesc = "The stairs are narrow and uneven, but you manage to clamber
        up them, arriving on another ledge about twenty feet above the first. "
    nothingBehindMsg = &cannotLookBehindMsg
;


+ ropeBridge : Fixture 'flimsy rope (free) end/rope/bridge/ropes' 'rope bridge'
    "The rope bridge is basically three lengths of rope strung across the chasm
    supporting a kind of netting in between. One of the ropes is tied firmly to
    an iron post driven into the solid rock, but the matching rope on the other
    side flaps free; it looks like the post it should be attached to has gone
    missing, since there is nothing left but the hole in the ground where it
    should be. A closer examination of the free end of the rope suggests that
    it may have been cut. "
    isHeld = nil
    dobjFor(Cross) remapTo(TravelVia, ropeLedge.west)
    dobjFor(WalkOn) remapTo(TravelVia, ropeLedge.west)
    dobjFor(Enter) remapTo(TravelVia, ropeLedge.west)
    dobjFor(StandOn) remapTo(TravelVia, ropeLedge.west)
    dobjFor(Pull) maybeRemapTo(isReady, Take, self)
    isReady = (felicity.isIn(getOutermostRoom))
    dobjFor(Take)
    {
        verify()
        {
            if(!isReady)
                illogicalNow('Grabbing hold of the rope bridge isn\'t going to
                    achieve much right now. ');
        }
        check() {}
        action()
        {
            if(isHeld == felicity)
            {
                "You take the loose rope end from Felicity's grasp.\b
                <q>You go across,</q> you insist, <q>I didn't pull you out of
                the swamp just to leave you here!</q>\b
                <q>But... </q> she starts to protest.\b
                <q>But me no buts!</q> you interrupt. <q>You go; be reasonable,
                Felicity, I'm stronger than you and you're lighter than me. So
                when it comes down to it there's a better chance that I'll be
                able to keep hold of the rope while you cross than <i>vice
                versa</i>, and since it makes best sense for the person with
                the best chance of getting safely to the other side to cross,
                it must be you that goes!</q>\b
                She ponders this for a moment, then says, <q>You really think
                so?</q><.p>";
                felicity.initiateConversation(nil, 'really-think-so');
            }
            else
            {
                "You take hold of the loose rope end and give it a firm tug.\b
                <q>I wonder...</q> you start to speculate.\b
                <q>No time to play with that now!</q> Felicity interrupts
                briskly, <q>you were going to show me a better view of that
                golden glow; I can't see it from here, so lead on!</q> ";
            }
        }
    }
    achievement: Achievement { +1 "making Felicity cross the bridge" }
    dobjFor(Drop)
    {
        preCond = [touchObj]
        verify()
        {
            if(isHeld==nil)
                inherited;
        }
        check()
        {
            if(felicity.curConvNode.name == 'really-think-so')
            {
                reportFailure('This would not be a good time to do that. ');
                exit;
            }
        }
        action()
        {
            "{You/he} let{s} go of the rope bridge. ";
            isHeld = nil;
        }
    }
    dobjFor(CutWith)
    {
        verify() { }
        action() {
            "It takes a surprising amount of effort, but you eventually manage
            to chop through the securing rope with {the iobj/him}, and you then
            step back to watch the fruit of your labours as the severed rope
            bridge falls across the chasm, until what's left of it is left
            dangling down the far side.\b
            At that point, it dawns on you that you have probably just
            destroyed your one and only chance of ever reaching that glorious
            golden glow on the far side.<.p>";
            finishGameMsg('YOU WANDER IN LIMBO FOR ALL ETERNITY',
                          [finishOptionUndo]);
        }
        
    }
    
    shouldNotBreakMsg = 'You want to repair the bridge, not break it! '
    cannotDetachMsg = 'The rope bridge only just hanging on to this side of the
        chasm as it is -- you don\'t want to lose it altogether! Besides, after
        fumbling with the knot for a few minutes you discover it\'s so
        diabolically cunning that you probably couldn\'t untie it even if you
        wanted to. '
    cannotUnfastenMsg = (cannotDetachMsg)
    cannotAttachMsg = (cannotFastenMsg)
    cannotFastenMsg = 'The free end of the rope (or that part of it you can reach
        without stepping onto the bridge) is too thick and too short for {you/him} 
        to be able to tie a knot with it. '
    nothingBehindMsg = &unclearWhatBehindMsg
    feelDesc = "It feels rather ropy. "
;

++ Component 'diabolically convoluted cunning knot' 'knot'
    "The knot with which the rope end is tied to the solitary post is so
    diabolically convoluted that it defies simple description. However hard you
    try you can't find any loose end you could begin to work on, and the
    attempt to work out how the knot is threaded simply sends you brain into
    knots. "
    dobjFor(LookIn) asDobjFor(Examine)
    dobjFor(CutWith) remapTo(CutWith, ropeBridge, IndirectObject)
    cannotUnfastenMsg = (location.cannotDetachMsg)
    cannotDetachMsg = (location.cannotDetachMsg)
    nothingBehindMsg = &unclearWhatBehindMsg
;

++ Component 'fine strong kind/netting' 'netting'
    "The netting slung across the rope bridge looks fine enough and strong
    enough to afford a reasonably secure crossing on foot<<ropeBridge.isHeld ==
      nil ?' -- if only all three of the supporting ropes were adequately
          secured' : ''>>. "
    cannotDetachMsg = 'The last thing you want to do is to detach that netting
        from the support ropes. ' 
;

+ CustomImmovable 'solitary iron metal post/pole' 'iron post'
    "A solitary iron post is driven firmly into the solid rock; one of the
    ropes supporting the bridge is tied securely to it. "
    cannotTakeMsg = 'The post seems to be firmly anchored in the rock -- you can\'t
        budge it. '
    feelDesc = "The metal is cold to your touch, but it also feels firm and
        strong. You don't think there\'s any danger it would give way. "
    cannotDetachMsg = (cannotTakeMsg)
    shouldNotBreakMsg = 'Fortunately it\'s a pretty sturdy post and not likely
        to break easily. '
    cannotUnscrewMsg = (cannotTakeMsg)
    cannotUnfastenMsg = (cannotTakeMsg)
;

+ missingPost: Unthing 'missing post' 'missing post'
    'It\'s nowhere to be seen. '
;

+ Fixture 'small round hole' 'hole'
    "There's a small round hole in the rock at roughly the point you'd expect
    the second post to be. "
    notAContainerMsg = '{The dobj/he} do{es}n\'t fit in the hole. '
;

+ Fixture 'sheer (eastern) (northern) (north) rock face/cliff/wall/rock' 
    'sheer rock face'
    "To the north the rock face is sheer and vertical, plainly impassible and 
    unclimbable. To the east a flight of steps has been cut into the rock. "
    dobjFor(Climb)
    {
        verify() { nonObvious; }
        action() {
            desc; " So you climb the steps. ";
            replaceAction(Climb, cliffStairs);
        }
    }
    nothingBehindMsg = &cannotLookBehindMsg
;

+ Vaporous 'palpable heat' 'palpable heat'
    "It's almost hot enough to be uncomfortable; it no doubt comes from the
    steaming lava below, and is perhaps trapped here by the corner in the rock
    face. "
    dobjFor(Feel) asDobjFor(Examine)
    dobjFor(Smell) remapTo(SmellImplicit)
    isQualifiedName = true
;

+ Vaporous 'thin haze' 'thin haze'
    "The haze is quite thin, only partially shrouding the bridge. It doesn't
    stop you seeing that the bridge reaches the far side of the chasm, but it
    makes is hard to discern what lies beyond that. "
    dobjFor(Smell) remapTo(SmellImplicit)
    dobjFor(LookThrough) asDobjFor(Examine)
    dobjFor(LookIn) asDobjFor(Examine)
;

+ Distant 'far other opposite side/(chasm)' 'far side'
    "The thin haze rising from the chasm makes it hard to discern what lies on
    the far side. "
;

//==============================================================================

cliffGardenNorthWall: RoomPart 'n north sheer northern cliff cliff/(foot)/wall*walls' 
    'north wall'
    "The cliff wall to the north is sheer and unclimbable, <<cliffDoor.isOpen ?
      'but the entrance to a cave has been cut into' : 'but a large rectangular
          stone leans against'>> its foot. "
;


cliffGarden : OutdoorRoom 'Cliff Garden' 'the cliff garden'
    "Sheer walls of rock enclose this area to north, south and east, making the
    ledge effectively a small walled garden, though there's not much to it
    apart from the scraggy grass and a solitary apple tree. A large rectangular
    stone <<cliffDoor.isOpen ? 'has been toppled to one side, revealing a cave
        entrance' : 'lies flat against the northern cliff wall'>>.
    <<westLook>><<southwestLook>>"
    vocabWords = '(cliff) garden'
    north = cliffDoor
    west = cliffStairsDown
    down asExit(west)
    out : ConditionalConnector
    {
        -> cliffStairsDown
        ": west or north"
        @(cliffDoor.isOpen)
    }
    roomParts = static inherited + cliffGardenNorthWall + defaultSouthWall
    + defaultEastWall
    thinkHere = "It seems an odd spot to find even so scraggy an apology for a
        garden. But you do not ponder this long, for your thoughts keep turning
        to the distant golden glow. "
    westLook = "To the west is a sheer drop, but a steep flight of stone steps
        leads down the cliff face. "
    southwestLook = "Off to the southwest gleams a faint golden glow. "
    nothingBehindMsg = 'Behind the garden is are the rock walls that enclose it. '
;

+ cliffStairsDown : TravelWithMessage, StairwayDown ->cliffStairs 
    'steep narrow (stone) flight/stairs/steps'  'flight of stairs'
    "The stone steps lead sharply down the cliff face. "  
    travelDesc = "You clamber awkwardly down the narrow stone steps<<
          felicity.curState.ofKind(FelicityTravelState) ? 
          ', and Felicity clambers down after you' : ''>>."
    nothingBehindMsg = &cannotLookBehindMsg
;

+ Heavy 'large rectangular rough hard solid flat stone' 'large rectangular stone'
    "It's about six feet high and three feet wide. "
    cannotTakeMsg = 'The large stone is obviously far too heavy for anyone to
        lift. '
    cannotMoveMsg = 'The large rectangular stone is far too massive for one
        person to move. '
    shouldNotBreakMsg = 'It looks far too solid to break with anything you have
        to hand. '
    cannotOpenMsg = (cannotMoveMsg)
    nothingThroughMsg = 'It\'s hardly transparent. '
    feelDesc = "It feels rough, solid and hard. "
    nothingBehindMsg = &cannotSeeBehindMsg
    nothingUnderMsg = 'You can\'t actually see under the large stone, but you
        suspect that anything that did happen to be under it would be pretty
        crushed. '
    futileToKnockOnMsg = 'This proves painful for your knuckles but otherwise
        achieves little. '
    cutNoEffectMsg = '{The iobj/he} make{s} not the slightest impression on
        {the dobj/him}. '
    uselessToAttackMsg 
    {
        local str, kick = (gVerbName == 'kick');
        str = (kick ? 'Kicking' : 'Striking') + ' the stone ';
        str += (kick ? '' : 'with your bare hands') + ' hurts you
            a lot more than it hurts the stone. ';
        return str;    
    }
;

+ cliffDoor : HiddenDoor ->mountainDoor 'cave entrance/cave' 'cave entrance'
    "The cave entrance is a round hole in the northern wall. "  
;

+ faintGlow: Distant 'faint golden tantalizing glow/light/variation' 
    'faint golden glow'
    "From this distance it's hardly more than a tantalizing variation in the
    light. "
;

+ wintryTree: Fixture 'solitary stunted wintry apple tree/trunk' 'apple tree'
    "The tree looks pretty wintry, its branches are bare, and as apple trees go
    this is a pretty stunted specimen, but at least it clings tenaciously to
    life here. "
    dobjFor(Climb)
    {
        verify() {}
        check() {}
        action() {
            "You manage to clamber up into the branches, but you find nothing
            of interest there. You also find the view from the top of the tree
            to be no significant improvement on the view from the bottom.
            Concluding that the entire exercise has achieved little, and
            finding the top of the tree to be a less than luxurious perch, you
            climb back down again. ";
        }
    }
    dobjFor(ClimbUp) asDobjFor(Climb)
    shouldNotBreak = 'This is no time for acts of senseless vandalism. '
    cutNoEffectMsg = '{The iobj/he} {is} clearly not up to the task of
        cutting through the trunk of the tree. '
;

++ Component 'bare gnarled sturdy twisty twisted branch*branches' 'branches'
    "They look totally bare. "
    isPlural = true
    shouldNotBreakMsg = 'They\'re all rather too sturdy to break easily, and
        rather too gnarled and twisty to be of much use even if you did manage
        to break one off. '
    dobjFor(Climb) remapTo(Climb, location)
    dobjFor(ClimbUp) remapTo(Climb, location)
    cutNoEffectMsg = 'The branches are all rather to sturdy to be severed with
        {the iobj/him}, and even supposing you eventually managed to chop one
        off, the branches are all too gnarled and twisted to be off any use, so
        it really doesn\'t seem worth the effort. '
;

++ knife: Thing 'sharp nine-inch nine inch knife/blade' 'knife'
    "It's a nine-inch blade with a rough wooden handle. "
    initSpecialDesc = "A knife has been plunged into the trunk of the tree. "
    iobjFor(CutWith) { verify() { } preCond = [objHeld] }
    iobjFor(AttackWith) remapTo(CutWith, DirectObject, self)   
    dobjFor(Pull) maybeRemapTo(isInInitState, Take, self)
    dobjFor(ThrowAt)
    {
        action()
        {
            if(gIobj.ofKind(Actor))
                replaceAction(CutWith, gIobj, self);
            else
                inherited;
        }
    }
    dobjFor(Examine)
    {
        action()
        {
            inherited;
            if(!ropeBridge.described)
                "<.p>Looking at the knife it occurs to you that it might be a
                good idea to take a closer look at the rope-bridge. ";
        }
    }
    
;

+++ Component 'rough worn wooden handle' 'rough wooden handle'
    "It looks pretty worn, but otherwise there's nothing special about it. "
    dobjFor(Pull) maybeRemapTo(!knife.moved, Take, knife)
    cannotMoveMsg = 'It\'s firmly attached to the blade. '
;


+ Unthing 'apples/apple/fruit' 'apples'
    'There are no apples here; the tree is bare. '
    isPlural = true
;

+ RoomPartItem, Decoration 'scraggy thin barely green grass/soil' 'scraggy grass'
    "The scraggy grass, barely green, clings to some vague approximation to
    life in the thin soil. "
    isMassNoun = true
    initNominalRoomPartLocation = defaultGround
    initSpecialDesc = desc
;

//============================================================================

fsGround : defaultGround
    desc = "It's covered with dead grass and beds of rotting flowers. "
;

farSide : ChasmRoom 'Dead Garden' 'the dead garden'
    "Running alongside the deep chasm to the east, this area is covered with
    dead and dying vegetation: brown grass turning black, dead trees grey with
    age, and beds of rotting flowers. To the north lies the (by now inevitable)
    cave entrance, while off to the southwest you see a bright golden glow. "  
    east: NoTravelMessage 
    { 
        "There's no way you'll cross that bridge again. " 
        getApparentDestination(origin, actor) { return backBridge; }
        backBridge: Room { destName = 'back across the bridge' }
    }
    south: NoTravelMessage { "You could walk south along the edge of the chasm,
        but there seems little point and you just can't be bothered. Only the
        glow to the southwest seems worth aiming for now. " }
    west: NoTravelMessage { "There's nothing that way but a barren wilderness;
        you could probably walk across it for days, but there seems to be no
        point, especially with that golden glow beckoning you to the
        southwest. " }
    southwest = goldenGlow
    north = deadCave
    in asExit(north)
    enterRoom(traveler)
    {
        if(felicity.isIn(ropeLedge))
        {
            "<.p>You turn back to wave at Felicity on the far side of the
            chasm. To your horror, she seems to take that as a signal to follow
            you, and steps onto the bridge.\b
            <q>No, Felicity, no!</q> you shout, signalling frantically, <q>Go
            back!</q>\b
            But either she doesn't hear you, or she chooses to ignore you; she
            continues to stagger along the violently swaying bridge, which is
            no longer anchored at the far end. ";
            inputManager.pauseForMore(true);
            "<.p>For a moment, you almost think she might make it. But then, as
            she reaches about a third of the way across, the treacherous rope
            bridge twists under her, throwing her off. For a moment she almost
            manages to grab hold of the flailing ropes, but she misses, and you
            watch in horror as she plunges yard by yard towards the molten lava
            below, screaming your name all the way down. You find yourself
            shouting her name in return, but it's hopeless, of course. Nothing
            can arrest her fall, and you watch in sickening helplessness,
            scarcely aware of your own yelling, as her body slowly turns end
            over end and her long blonde hair streams out in the slipstream of
            her fall. Then finally, terribly, her long fall is over as she
            strikes the glowing lava and lets out one final shriek of agony
            before sinking out of sight, her scorched blonde hair being the
            last part of her to disappear. ";
            felicity.moveInto(nil);
        }
    }
    thinkHere = "You think this feels the bleakest place on earth -- at least
        it would be if it was on earth. There seems nothing for it now but to
        go and investigate the golden glow, and to hope that it lives up to its
        promise. "
    roomParts = [fsGround, defaultSky] 
    downLook = (chasmEdge.downLook)
    eastLook = "Directly to the east is the deep chasm, across which the broken
        rope bridge stretches uselessly. "
    northLook = "A cave entrance lies directly to the north. "
    southwestLook = "Off to the southwest beckons a bright golden glow. "
    southLook = "The rocky ledge continues south alongside the chasm for as far
        south as you can see. "
    southeastLook = "The broad chasm runs south as far as you can see. "
    defaultLook(dir) { "That way lies nothing but a barren wasteland. "; } 
    throwDests = [ [eastDirection, chasm], [southeastDirection, chasm],
        [northeastDirection, chasm] ]
    roomAfterAction()
    {
        if(gActionIs(Yell))
            "No one answers; no one hears the anguish in your cry but you. ";
    }
    roomBeforeAction
    {
        if(gActionIs(Down))
            replaceAction(ClimbDown, brokenBridge);
    }
;

+ brokenBridge: Fixture 'broken rope bridge' 'rope bridge'
    "This end of the rope bridge looks securely anchored. Unfortunately, the
    far end has come loose, so the bridge hangs down the side of the chasm. "
    dobjFor(Cross) remapTo(TravelVia, farSide.east)
    nothingBehindMsg = 'Depending on your point of view, behind the broken rope
        bridge is either the chasm or its wall. '
    dobjFor(Pull)
    {
        verify() {}
        action()
        {
            "You pull the rope bridge up a short way, but run out of energy and
            enthusiasm for the task long before you pull its whole length up 
            onto the ledge, so you just let it drop again. ";
        }
    }
    cannotMoveMsg = 'Waggling the rope bridge around won\'t achieve much. '
    dobjFor(ClimbDown)
    {
        verify()
        {
            if(climbed)
                illogicalAlready('You\'ve already tried that once -- you don\'t
                    feel like trying it again. ');
        }
        action()
        {
            climbed = true;
            "With great hesitation, you grasp the rope in both hands and slowly
            begin a nerve-racking descent. With every yard you descend you feel
            the heat rising from below growing ever hotter. After four or five
            yards your hands feel sore, your arms tired, and you wonder how
            much longer you can hang on. You look down at the bubbling lava in
            terror, and wonder what possessed you to attempt anything so
            foolish, for there is surely nothing you can achieve by this mad
            descent. Even if you were to make it safely to the foot of the rope
            -- and you don't believe you can -- there's nothing you can do for
            Felicity now. The notion that you could somehow pluck her out from
            beneath the surface of the lava flow and haul her up to safety is
            sheer madness. You'd never find her down there, and you'd no more
            survive the attempt than she survived the fall.\b Slowly,
            painfully, inch by inch, you manage to climb back up again, every
            few feet fearing that your overtired arms will give out and that
            you'll end up plunging into the steaming red mass below. But
            survival instinct takes over, and somehow you manage to keep on
            climbing up, inch by agonizing inch. At last you reach the top and
            collapse onto the ground, trembling from reaction, and vowing
            <i>never</i> to risk anything so foolish ever again.";
            gActor.makePosture(lying);
        }
    }
    climbed = nil
;

+ Enterable -> deadCave 'round cave entrance' 'cave entrance'
    "This entrance is roughly round. It's easily large enough to
    walk through. "
    nothingBehindMsg = 'It would be a fair guess that behind the cave entrance
        lies a cave. '
;

+ Distant 'bright celestial golden glow/city' 'bright golden glow'
    "From here the golden glow looks just like a bright celestial city
    beckoning you on to the southwest. "
    dobjFor(Enter) remapTo(TravelVia, goldenGlow)
;

+ Decoration 'sparse brown black dead grass*vegetation' 'grass'
    "The sparse, brown grass looks long since dead, a mere mocking remnant of
    past vitality. "
    isMassNoun = true
;

+ Decoration 'dead stunted grey gray trio/trees/bark/branches*vegetation' 'dead trees'
    "A trio of stunted trees stands near the centre of the dead garden, their
    branches as bare as midwinter, their bark as grey as ash. "
    isPlural = true
;

++ Component 'bare branches' 'branches'
    "They look totally bare. "
    isPlural = true
;

+ Decoration 'rotting dead beds/flowers*vegetation' 'beds of rotting flowers'
    "All colour has faded from the dead flowers, which seem to be in a
    permanent state of decay. "
    isPlural = true
;

+ SimpleNoise 'silence' 'silence'
    "Utter silence, apart from the occasional hiss and bubbling from the lava
    down at the bottom of the chasm. "
;

+ SimpleOdor 'sulphorous sulfurous fumes/decay/stench' 'fumes'
    "The sulphurous fumes mingle with the smell of decay to create an
    near-overwhelming stench of death. "
    isPlural = true
;

+ Unthing 'blonde felicity/woman' 'felicity'
    'You\'ve lost her: she\'s gone for good. '
;

//==============================================================================

dcNorthWall : RoomPart 'rough rocky north n wall*walls' 'north wall'
    "There's nothing special about it, apart from the fact that it's opposite
    the entrance. "
;

dcSouthWall : RoomPart 'rough rocky south s wall*walls' 'south wall'
    "The south wall is pierced by the entrance to the cave. "
;

dcEastWall : RoomPart 'rough rocky east e wall*walls' 'east wall'
    "There's a loculus (or niche) in the east wall. "
;

dcWestWall : RoomPart 'rough rocky west w wall*walls' 'west wall'
    "A flat shelf lies hard against the west wall of the cave. "
;

deadCave : Room 'Dead Cave' 'the dead cave'
    "There is nothing here but rough rocky walls and a flat shelf of rock to
    one side and a small loculus (niche) to the other. "
    south = farSide
    out asExit(south)
    outLook = "The cave looks out over a dead garden. "
    roomParts = [defaultFloor, defaultCeiling, dcNorthWall, dcSouthWall,
        dcEastWall, dcWestWall]
    thinkHere = "What a desolate and depressing spot this feels! "
;

+ Platform, Fixture 'flat bare top shelf/rock/surface' 'flat shelf of rock'
    "The flat shelf lies to one side of the cave exit; it is utterly bare. "
    reachableObjects = [dcWestWall]
;

+ smallNiche : Container, Fixture 'small loculus/niche' 'loculus'
    "The niche is at about chest-height; it's just about large enough for an
    ossuary, but would be too small for a skeleton. "
    nothingBehindMsg = &cannotLookBehindMsg
;

++ OpenableContainer 'small plain (stone) limestone box/ossuary*ossuaries' 
    'small ossuary'
    "It's a very plain stone box. "
    dobjFor(Open)
    {
        verify() {
            if(isIn(smallNiche))
                illogicalNow('{You/he} can\'t open the ossuary while it\'s in
                    the niche. ');
            inherited;
        }
    }
;

+++ Readable 'small scroll' 'small scroll'
    "The scroll is blank apart from the words <<toGreek('pasan elpida
        katalipe')>>, which you have no difficulty in translating as <q>all
    hope abandon</q>. "
;

+ ExitPortal ->farSide '(cave) small round entrance/exit/opening' 'entrance'
    "The entrance to the cave is a small round opening to the south. "
;

goldenGlow : OutdoorRoom 'Barren Plain' 'the barren plain'
    "There is nothing here but a barren, rocky plain, stretching off to the
    horizon in all directions. "
    northeast = farSide
    enterRoom(traveler)
    {
        "As you arrive, you find that the golden glow is, after all, no
        celestial city, but an illusion caused by a huge swarm of hellish
        fireflies. For a brief moment they arrange themselves into a mocking
        imitation of a fall of long golden hair framing an angelic face; then
        they disperse into the night, leaving you utterly alone in the
        gathering gloom.<.p>";
        if(agrath.seen)
            "Somewhere in the distance you hear faint laughter. It lasts just
            long enough for you to recognize as Agrath's laugh, then it, too,
            fades into the night.<.p>";      
        
        finishGameMsg('YOU HAVE LOST ALL HOPE', [finishOptionUndo, finishOptionRetry, 
            finishOptionFullScore]);
    }
    enteringRoom(traveler)
    {
        "You walk for what seems like miles and miles and miles towards the
        golden glow across an endless rocky plain. Only the sight of that
        golden city, gradually growing closer, prompts you to continue your
        weary journey. It does seem strange to you that so paradisal a place
        should be set in such bleak surroundings, but as you advance across the
        barren plain, the golden glow slowly resolves itself into walls and
        towers and palaces and banners, beckoning you ever on as the sole
        source of light while night gradually falls around you.<.p>
        At last, you arrive at your destination, your heart leaping in
        anticipation at what the great golden city will hold in store for
        you...";
        inputManager.pauseForMore(true);
    }
;