#charset "us-ascii"
#include <advlite.h>

//      The Exterior Rear
//
//              behindBuilding
//              footOfPole
//              grassySlope
//              eastSidePath
//              amphitheater
//              onStage
//              backStage
//              wardrobeCloset
//              besideTheCreek
//              footOfCliff
//              danglingFromCliff

rearViewOfStufftown: MultiLoc, Distant 'Stufftown; shopping; center building structure wall'
    "Stufftown looks even less interesting from the rear than it did from
    the front. "
    locationList = [behindBuilding, footOfPole, grassySlope, eastSidePath, amphitheater, footOfCliff]
;

//-----------------------------------------------------------------------------
// behindBuilding
//-----------------------------------------------------------------------------

behindBuilding: ExteriorLocation, Room 'Behind the Building'
    "The ungainly bulk of the shopping center looms over you to the north, broken
    here by a tall but narrow open archway. The ground
    is unpaved and unkempt, but fortunately not muddy. A path extends
    along the base of the building to the west, and another path strikes off
    down a grassy slope to the southeast. "
    regions = [joeFollowingRegion]
    north = narrowPassage
    west = footOfPole
    southeast = grassySlope
;

+ rearArchway: Fixture 'narrow archway; tall; arch'
    "The archway provides access to the interior of Stufftown. "
    dobjFor(GoThrough) asDobjFor(Enter)
    dobjFor(Enter) {
        verify() { logical; }
        action() {
            doInstead(Go, northDir);
        }
    }
;

+ viewOfGrassySlope: Distant 'grassy slope'
    "The grassy slope is to the southeast. "
;

//-----------------------------------------------------------------------------
// footOfPole
//-----------------------------------------------------------------------------

footOfPole: ExteriorLocation, Room 'At the Foot of a Power Pole'
    "A power pole (or, not to be too analytical about it, a thick wooden pole from the
    top of which wires extend in several directions) dominates this isolated spot at
    the rear of Stufftown. <<tJoe.makeFamiliar()>>Just beyond the pole to the south is the edge of an embankment
    so steep that we may as well call it a cliff. A brick-paved path leads west around the corner of the
    building, or you could head east along the base of the structure.
    
    <.p>Mounted on the exterior wall here is a metal box. "
    beforeTravel (traveler, connector) {
        if ((traveler == gPlayerChar) && (scarf.containsPixies)) {
            "Oh, no! As you set off, the pixies escape from the scarf! ";
            scarf.containsPixies = nil;
            invisiblePixies.moveInto(joe);
            flyingPixies.moveInto(nil);
            flyingPixies.flying = true;
            flyingPixies.capturedButAwake = nil;
        }
    }
    allowDescent(stat) {
        if (stat) {
            down = tiedAndDanglingRope;
            footOfCliff.up = lowerEndOfRope;
            lowerEndOfRope.moveInto (footOfCliff);
        }
        else {
            down = nil;
            // Restoring the climb-the-cliff possibility if the rope is pulled back up:
            footOfCliff.up = footOfCliffTravelConnector;
            lowerEndOfRope.moveInto (nil);
        }
    }
    regions = [joeFollowingRegion]
    east = behindBuilding
    west = brickPath
    up = "You climb halfway up the pole, gaze around for a moment at the view, and then manage
        to shimmy back down without getting any splinters in your hands. What an adventure! "
;

+ wires: Decoration 'wires;; wire'
    "The wires are up there at the top of the pole. "
    plural = true
;

+ powerPole: Fixture 'power pole; rough brown (wood) thick wooden; cylinder'
    "The power pole, a thick cylinder of the usual rough brown wood,
    stands quite close to the edge of the cliff.
    <<if ((tiedLocalRope.getOutermostRoom() == footOfPole) || (tiedAndDanglingRope.getOutermostRoom() == footOfPole))>>A
    length of rope has been tied to the base of the pole. "
    dobjFor(Climb) {
        verify() { logical; }
        check() { "You climb halfway up the pole, gaze around for a moment at the view, and then manage
        to shimmy back down without getting any splinters in your hands. What an adventure! ";
        }
    }
    iobjFor(TieTo) {
        verify() { logical; }
    }
;

+ brickPath: PathPassage
    'brick-paved path; brick paved'
    "The brick path leads westward. At the corner of the building it turns right and disappears
    from view. "
    destination = employeeParking
    getFacets = [brickPath2]
    travelDesc = "You make your way westward and turn to the north as you round the corner of the building. "
;

+ cliffFromTop: Fixture 'cliff;; precipice slope'
    "The cliff is nearly vertical. Peering over it, you can see that the drop is at least
    twenty feet.<<if (tiedAndDanglingRope.getOutermostRoom() == footOfPole)>> A rope is tied
    to the pole and dangling over the edge of the cliff.<<end>> "
    iobjFor(LowerOver) {
        verify() { logical; }
    }
;

// Note: The junction box is in its own file.

//-----------------------------------------------------------------------------
// grassySlope
//-----------------------------------------------------------------------------

drivingRange: MultiLoc, Decoration 'driving range'
    "Scattered across the driving range are quite a lot of golf balls. "
    locationList = [grassySlope, eastSidePath]
;

// Note (1/19/18): You need to be able to TRY to take a single ball here.

grassySlope: ExteriorLocation, Room 'Grassy Slope'
    "The grass here is
    rather long, as if it hasn't been mown in a month or two. A square patch of bare dirt suggests
    that someone has had the idea of adding a flowerbed, but hasn't yet gotten around to planting
    anything.
    
    <.p>A path meanders down a gentle hill from the northwest, where the brooding bulk of Stufftown
    squats. Another path heads straight north along the side of the building. 
    
    <.p>Off to the south is a curious little building, whose near side is open in what looks
    rather like a stage. Between you and the building is a small semicircular amphitheater.
    
    <.p>On the east, the grassy slope is bordered by an extremely high open-mesh fence. A scatter of
    little white balls on the far side of the fence leaves no doubt that Stufftown's immediate neighbor
    to the east is a driving range. "
    northwest = behindBuilding
    south: TravelConnector {
        travelBarriers = [wagonBarrier]
        destination = amphitheater
    }
    north = eastSidePath
;

+ slopeLongGrass: Fixture 'long grass; unmown green tall unkempt'
    "The grass is long and unkempt. It clearly hasn't been mowed for a while. "
    dobjFor(Search) {
        verify() {}
        check() {
            "You find nothing in the long grass<<if (golfBall.notYetFound)>> --- but you notice there\'s another patch
            of long grass off to the north<<end>>. ";
        }
    }
;

+ slopeGolfBalls: Fixture 'golf balls; white; ball; them'
    "The golf balls are scattered across the driving range. "
    dobjFor(Push) asDobjFor(Take)
    dobjFor(Feel) asDobjFor(Take)
    dobjFor(PutIn) asDobjFor(Take)
    dobjFor(Take) {
        verify() {}
        check() {
            "The golf balls are completely out of reach on the far side of the high mesh
            fence.<<if golfBall.notYetFound>> However, it's at least possible that one of
            them flew clean over the fence at some point and landed nearby in the long
            grass. ";
        }
    }
;

+ Decoration 'curious little building; ; stage'
    "The little building houses the stage below the amphitheater. "
;

+ Decoration 'amphitheater; small semicircular'
    "The amphitheater is small. Nobody is sitting there, and there's no performance
    in progress. "
;

+ slopeFence: Fixture 'open-mesh fence'
    "The fence is easily 30 feet high. Through it you can see a scatter of golf balls. "
    dobjFor(LookThrough) {
        verify() {}
        action() {
            "Looking through the fence you see a scatter of golf balls. ";
        }
    }
    cannotClimbMsg = 'It\'s too high (and also quite likely too flimsy) to climb. '
;

// The dirtPatch object is now in PDhelmet.t.

//-----------------------------------------------------------------------------
// eastSidePath
//-----------------------------------------------------------------------------

eastSidePath: ExteriorLocation, Room 'East of Stufftown'
    "This narrow and little-trafficked path appears to go nowhere at all; a thick stand of
    unmown grass crowds in on it. The mass of the
    shopping center is close enough to touch on the west, and the high mesh fence of the 
    driving range is to the east. On the north the path ends at a blank brick wall. The
    only obvious exit is back to the south. "
    south = grassySlope
;

+ Decoration 'brick wall; blank'
    "The brick wall blocks any further progress northward. "
;

+ eastSideFence: Fixture 'open-mesh fence'
    "The fence is at least 30 feet high. Through it you can see a scatter of golf balls. "
    dobjFor(LookThrough) {
        verify() {}
        action() {
            "Looking through the fence you see a scatter of golf balls. ";
        }
    }
    cannotClimbMsg = 'It\'s too high (and also quite likely too flimsy) to climb. '
;

+ eastLongGrass: Fixture 'long grass; unmown green tall unkempt'
    "The grass grows up long and unkempt on both sides of the path. It hasn't been mowed for a while. "
    dobjFor(LookIn) {
        verify() {}
        check() {
            if (!golfBall.notYetFound) "There seems to be nothing else in the tall grass. ";
        }
        action() {
            pathGolfBalls.replaceVocab ('golf balls; white; ; them');
            golfBall.notYetFound = nil;
            golfBall.moveInto(gPlayerChar);
            golfBallAch.awardPointsOnce();
            "Hidden in the tall grass you notice the white gleam of a golf ball, which you pick up. ";
        }
    }
;

+ eastPathItself: Decoration 'overgrown path'
    "The path is all but overgrown by the long grass. It ends, just to the north, at a blank brick
    wall. "
;

+ pathGolfBalls: Fixture 'golf balls; white; ball; them'
    "The golf balls are scattered across the driving range. "
    dobjFor(Push) asDobjFor(Take)
    dobjFor(Feel) asDobjFor(Take)
    dobjFor(PutIn) asDobjFor(Take)
    dobjFor(Take) {
        verify() {}
        check() {
            "The golf balls are completely out of reach on the far side of the high mesh
            fence.<<if golfBall.notYetFound>> However, it's at least possible that one of
            them flew clean over the fence at some point and landed nearby in the long
            grass. ";
        }
    }
;

//-----------------------------------------------------------------------------
// amphitheater
//-----------------------------------------------------------------------------

amphitheater: ExteriorLocation, Room 'Pocket Amphitheater'
    "This semicircular amphitheater is almost small enough, it seems, to fit in your pocket.
    A few rows of benches face a tiny stage, to the south from here. Standing directly behind the
    stage is a narrow, spindly-looking building. The path up the grassy
    slope toward Stufftown is to the north. "
    north = grassySlope
    up asExit(north)
    south = onStage
;

+ Decoration 'benches;; bench'
    "The benches face the stage. "
    plural = true
;

+ Decoration 'tiny stage'
    "The stage is a few steps away to the south. "
;

+ Decoration 'narrow building; spindly spindly-looking looking'
    "The building is directly behind the stage. It would appear to house the backstage area. "
;

//-----------------------------------------------------------------------------
// onStage
//-----------------------------------------------------------------------------

onStage: ExteriorLocation, Room 'On the Stage'
    "The stage is larger than a postage stamp, but not a great deal larger. Trying
    to stage a swordfight scene on it would be a mistake, as one of the actors would
    be bound to tumble off into the audience. The amphitheater area is a few steps down
    to the north, and a gap to the south can only lead backstage. "
    name = 'stage'
    north = amphitheater
    down asExit(north)
    south = backStage
;

+ Decoration 'amphitheater; ; benches'
    "The benches of the amphitheater are a few steps down to the north. Gazing out at
    them, you suffer the briefest possible frisson of stage fright. Blessedly, the benches
    are not populated by spectators. "
;

+ Decoration 'gap'
    "The gap seems to allow access to the backstage area. "
    decorationActions = [Examine, Enter]
    dobjFor(Enter) {
        verify() {}
        action() {
            doInstead (Go, southDir);
        }
    }
;

//-----------------------------------------------------------------------------
// backStage
//-----------------------------------------------------------------------------

backStage: ExteriorLocation, Room 'Backstage'
    "The backstage area of the little theater is high-ceilinged, but affords
    no more elbow room than the stage itself.
    A clutter of props renders the footing treacherous. A boxy enclosure with a door is built
    into the west wall. The stage itself is to the north. "
    west = wardrobeClosetDoorOutside
    north = onStage
;

+ Decoration 'props; tawdry; clutter'
    "The props are rather tawdry, but there's nothing among them to detain you. "
    plural = true
;

+ wardrobeClosetDoorOutside: Door 'door of the enclosure'
    "The door is narrow-but solid-looking. It's built into the boxy enclosure on the
    west side of the backstage area. "
    otherSide = wardrobeClosetDoorInside
    isOpen = true
;

wardrobeClosetExterior: Fixture, Enterable 'boxy enclosure; wardrobe; closet'
    "The boxy enclosure is built into the east wall, and appears to be about the size
    of a standard closet. Its walls extend up for eight feet or so, but stop well short
    of the ceiling. "
    connector = wardrobeClosetDoorOutside
;

//-----------------------------------------------------------------------------
// wardrobeCloset
//-----------------------------------------------------------------------------

// The door's inside is initially nowhere. It can't be put in the room and kept hidden, because
// the player has to be able to examine and move the planks.

// The plank door is a holdover from Ballerina. The various navigation traps become more interesting
// if it doesn't exist at all. For now, let's remove it. Perhaps later consider putting it in the
// backstage rather than the closet.

//plankDoorInside: Door 'unfinished planks; outside bare; exit gap opening wall plank board boards wood; them'
//    "The planks behind the clothing rack are bare wood, and ill-fitting. <<if (isHidden)>>In fact, you
//    can see a little daylight through one of the cracks between the boards<<else>>One of the planks
//    has been pushed aside, leaving an opening through which you might be able to crawl<<end>>. "
//    otherSide = plankDoorOutside
//    dobjFor(Open) {
//        verify() { logical; }
//        check() {
//            "You have already pushed the plank aside. ";
//        }
//    }
//    dobjFor(Close) {
//        verify() { logical; }
//        check() { "You have a go at tugging the plank back into place, but it's firmly stuck. "; }
//    }
//;

wardrobeCloset: ExteriorLocation, Room 'In the Wardrobe Closet'
    "This tiny chamber is mostly occupied by a rack of clothing along the west wall, above which is
    a shelf cluttered with various smaller items. The door is in the east wall.<<springTrap()>> "
    trapSprung = nil
    springTrap() {
        if (trapSprung) return;
        trapSprung = true;
        wardrobeClosetDoorInside.makeLocked(true);
        wardrobeClosetDoorInside.makeOpen(nil);
        "<.p>As you enter the little chamber, the door slams shut! ";
    }
    east = wardrobeClosetDoorInside
    out asExit(east)
    // west = plankDoorInside
;

+ wardrobeClosetDoorInside: Door 'wardrobe closet door'
    "The closet door is equipped with a latch plate, in which is a keyhole. "
    otherSide = wardrobeClosetDoorOutside
    lockability = indirectLockable
    isLocked = true
    hasBeenUnlocked = nil
    dobjFor(Unlock) {
        verify() {}
        check() {
            if (!isLocked) "You've already unlocked the door. ";
            else "There ought to be some way to do that, oughtn't there? Have you taken
                a good look around? ";
        }
    }
    dobjFor(OpenWith) {
        verify() {}
        check() {
            if (isOpen) "The door is already open. ";
            else if (gIobj && (gIobj == hatpin))
                "You can't open the door with the hatpin, but you might be able to unlock it. ";
            else "{The iobj} can't be used for opening the door. ";
        }
    }
    dobjFor(UnlockWith) {
        verify() {}
        check() {
            if (!isLocked) "You've already unlocked the door. ";
            else if (gIobj && gIobj != hatpin) "You give it a try, but no joy. ";
        }
        action() {
            doInstead (PutIn, hatpin, latchKeyhole);
        }
    }
;

++ latchPlate: Component 'latch plate; ; latchplate'
    "In the latch plate is a little keyhole. "
    dobjFor(PutIn) {
        verify() {}
        check() {
            if (gDobj == hatpin) "Your aim is poor. Try putting the pin in the keyhole. ";
            else "The latch plate can't contain things. The keyhole, on the other hand.... ";
        }
    }
;

+++ latchKeyhole: Component, RestrictedContainer '(latch) keyhole; (closet) little round key; lock opening hole'
    "The keyhole is a little round opening, not a slot. "
    disambigName = 'closet door keyhole'
    allowedContents = [hatpin]
    dobjFor(UnlockWith) {
        verify() {}
        check() {
            if (gIobj && (gIobj != hatpin))
                "You can't unlock anything with {that iobj}. ";
        }
        action() {
            doInstead (PutIn, gIobj, self);
        }
    }
    iobjFor(PutIn) {
        verify() {}
        check() {
            if (gDobj != hatpin) "{The subj dobj} won't fit in the keyhole. ";
            else if (!wardrobeClosetDoorInside.isLocked) "You've already unlocked the door. ";
        }
        action() {
             "You insert the hatpin in the keyhole and twiddle it around a bit. With a
            satisfying <i>snap,</i> the latch springs back and the door swings open. 
             The hatpin has gotten a bit bent in the process, however. It's not likely to
             be of any further use, so you toss it aside. ";
            hatpin.moveInto(nil);
            wardrobeClosetDoorInside.makeLocked(nil);
            wardrobeClosetDoorInside.makeOpen(true);
            wardrobeClosetDoorInside.hasBeenUnlocked = true;
            wardrobeAch.awardPointsOnce();
        }
    }      
;

+wardrobeRack: Fixture 'wardrobe rack'
    "The rack is a jumble of costumes in all sorts of styles and sizes. Riffling
    through the clothing quickly, however, you find no prom dress, and nothing else
    of interest either. "
    dobjFor(Search) {
        verify() {}
        check() {}
        action() { doInstead(Search, wardrobeRackClothing); }
    }
;

++ wardrobeRackClothing: Decoration 'clothing; assorted; clothes jumble costume costumes'
    "The costumes are colorful and varied, but not, for the most part, important
    to you. "
    dobjFor(Take) {
        verify() {
            logicalRank (120);
        }
        check() {
            "The clothing on the rack is not important. ";
        }
    }
    dobjFor(Search) {
        verify() {
            logicalRank (120);
        }
        check() {
            "You paw through the costumes for a minute, but without finding anything
            useful --- certainly nothing resembling a prom dress, worse luck. ";
        }
    }
    decorationActions = [Examine, Take, Search]
;

+ wardrobeShelf: Surface, Fixture 'high shelf'
    "The high shelf is a jumbled repository of wigs, hats, and other paraphernalia
    of stagecraft. "
    hiddenIn = [armyHelmet, pairOfShoes, scarf]
    dobjFor(Examine) {
        action() {
            if(hiddenIn.length > 0)                
                moveHidden(&hiddenIn, self);
            inherited;
        }
    }
;

++ wardrobeShelfStuff: Decoration 'wigs and hats;; items paraphernalia stuff; them'
    "The wigs and hats are colorful and varied, but not, for the most part,
    important to you. Not today, anyway. "
    dobjFor(Examine) {
        action() {
            if (wardrobeShelf.hiddenIn.length > 0) doInstead (Examine, wardrobeShelf);
            else inherited;
        }
    }
;

//-----------------------------------------------------------------------------
// besideTheCreek
//-----------------------------------------------------------------------------

besideTheCreek: ExteriorLocation, Room 'Beside the Creek'
    "A rather wide and rambunctious creek gurgles along from east to west here.
    Travel further south is blocked by the creek, but you can go north to the
    base of the cliff, at the top of which squats the brooding bulk of Stufftown.
    To the east is the wall of what appears to have been at one time a barn. "
    north = footOfCliff
;

+ creekWater: Fixture 'creek; wide gurgling; water river stream'
    "The creek is gurgling along, as creeks are wont to do. "
    vocabLikelihood = 10
    iobjFor(FillWith) {
        verify() {}
        check() {
            "There's no need to fill anything with water from the creek. ";
        }
    }
;

+ Decoration 'wall; ; barn'
    "The wall of the building (which might or might not be a barn) is
    remarkable only in that it entirely prevents your traveling further
    to the east. "
;

//-----------------------------------------------------------------------------
// footOfCliff
//-----------------------------------------------------------------------------

cliffBarrier: TravelBarrier
    canTravelerPass(traveler, connector) {
        if (gPlayerChar.contents.length() > 2) return nil;
        return true;
    }
    explainTravelBarrier (T, C) {
        "You can't climb the cliff while carrying anything. ";
    }
    destination = footOfPole
;

footOfCliffTravelConnector: TravelConnector 
    destination = footOfPole
        travelDesc = "You manage to scramble up the cliff, using a few very insecure
            handholds and toeholds. "
        travelBarriers = [cliffBarrier]
;

footOfCliff: ExteriorLocation, Room 'At the Foot of a Cliff'
    "A sheer wall of rock --- essentially, a cliff --- stretches <<cliffAch.awardPointsOnce()>>above
    you to the north.
    Set in the base of the cliff is a badly rusted metal door. To the south, a creek
    meanders from east to west.<<if (lowerEndOfRope.location == footOfCliff)>> A rope is
    dangling down the cliff.<<end>> "
    
    dobjFor(Climb) {
        verify() {}
        action() {
            doInstead(Go, upDir);
        }
    }
    
    south = besideTheCreek
    north = rustyDoorExterior 
    up = footOfCliffTravelConnector
;

+ rustyDoorExterior: Door 'rusty metal door'
    "The door seems to be made of iron, or possibly of some metal that is more
    prone to corrosion, as it's badly rusted. "
    dobjFor(Close) {
        verify() {}
        check() {
            if (!isOpen) "The door isn\'t open. ";
            else "Maybe just leave it open. Letting a little fresh air inside
                couldn\'t hurt. ";
        }
    }
    isLocked = true
    lockability = indirectLockable
    otherSide = rustyDoorInterior
;

++ rustyKeyhole: Component 'large keyhole'
    "It\'s an ordinary-looking keyhole. "
    dobjFor(PutIn) {
        verify() {}
        check() {
            "That doesn\'t seem to fit the keyhole. ";
        }
    }
;

++ rustyHandle: Component 'handle'
    "It\'s just an ordinary-looking handle. "
    dobjFor(Pull) {
        verify() {}
        check() {
            if (rustyDoorExterior.isOpen) "No need --- the door is open. ";
            "You give the handle a tug, but the door won\'t budge. ";
        }
    }
;

+ faceOfCliff: Fixture 'cliff; ; face'
    "The face of the cliff is not quite vertical, but it's worse than steep. There
    are perhaps a few handholds and footholds, but they're widely spaced and don't
    look perfectly trustworthy. "
    dobjFor(Climb) {
        verify() {}
        action() {
            doInstead(Go, upDir);
        }
    }
;

