Sayer = Proc(str, flag)
{
    If (!flag) {
	$say(str, "\n");
    }
    Return str;
}

$ALL(LDESC) = Proc()
{
    "You shouldn't be here at all.  This is THE COSMIC ALL.\n";
}
$ALL(SDESC) = Proc() { Return Sayer("THE COSMIC ALL", $arg(0)); }

rdsc = Proc() {Return Sayer("Road", $arg(0));}
rldsc = Proc() {"You are on the road.\n";}

road1(SDESC) = rdsc;
road1(LDESC) = Proc()
{
    "You're on a dirt road going east-west.  Tall stalks of "
    "corn grow on either side of the road.\n";
}

road2(SDESC) = rdsc;		road2(LDESC) = rldsc;

road3(SDESC) = Proc() { Return Sayer("Bridge", $arg(0)); }
road3(LDESC) = Proc()
{
    If (dragon.KILLED)
	"You are on a bridge over a swift river.  ";
    Else
	"You are on a bridge over a dry river bed.  ";

    "The river goes north-south, and the road continues east-west.\n";
}

road4(SDESC) = rdsc;		road4(LDESC) = rldsc;
road5(SDESC) = rdsc;		road5(LDESC) = rldsc;

road6(LDESC) = Proc()
{
    "A road from the west forks north and south here.  To the east is a"
    " dense-looking forest; cornfields are seen on the west.\n";
}
road6(SDESC) = Proc() {Return Sayer("Fork in road", $arg(0));}

road7(SDESC) = rdsc;
road7(LDESC)= Proc()
{
    "The road stretches a long way east-west.  A short fence divides the "
    "road from the cornfields beyond.  Please don't tresspass.\n";
}


gdsc = Proc()
{
    "You are somewhere in a cornfield.  The cornstalks are ";
    If (dragon.KILLED)
	"green and healthy.\n";
    Else
	"brown and dry-looking.\n";
}

gsdsc = Proc() {Return Sayer("Cornfield", $arg(0));}
fsdsc = Proc() {Return Sayer("Forest", $arg(0));}

gard1(SDESC) = gsdsc;            gard1(LDESC) = gdsc;
gard2(SDESC) = gsdsc;            gard2(LDESC) = gdsc;

frst1(SDESC) = fsdsc;            frst1(LDESC) = fdsc;

farm1(SDESC) = Proc() {Return Sayer("Farm Entrance", $arg(0));}
farm1 (LDESC) = Proc()
{
    "You are at the entrance on the south side of a rundown "
    "farmhouse.  Someone has painted 'DIE, HEATHENS' on the "
    "front door, which barely stays on its hinges.  Marks of "
    "smoke and flame are visible.  A road runs to the south, "
    "and you may walk around the farmhouse by going east or west.\n";
}

farm2(LDESC) = Proc()
{
    "You are in the entry hall of a long-deserted old farmhouse. "
    "The floor is covered with the dust of years of disuse.  The "
    "front door to the south is open, and there is another room "
    "to the north.  A stairway on the east side of the room goes up.\n";
}
farm2(SDESC) = Proc() { Return Sayer("Entry hall", $arg(0));}

farm3(LDESC) = Proc()
{
    "You are on the east side of the farmhouse.  To the east, a forest "
    "stretches away into the distance.  The entrance to the farmhouse "
    "is to the south.\n";
}
farm3(SDESC) = Proc() {Return Sayer("East of Farmhouse", $arg(0));}

farm4(LDESC) = Proc()
{
    "You are on the west side of the farmhouse.  The cornfields "
    "stretch away forever to the west.  The entrance to the house "
    "is to the south.\n";
}
farm4(SDESC) = Proc() {Return Sayer("West of Farmhouse", $arg(0));}

farm5(LDESC) = Proc()
{
    "You are on the north side of the farmhouse.  A high fence "
    "separates you from the cornfields to the north and west. ";
    $move(insignia, farm5);
}
farm5(SDESC) = Proc()
{
    $move(insignia, farm5);
    Return Sayer("North of Farmhouse", $arg(0));
}


farm6(LDESC) = Proc()
{
    "You are in an old, empty farmhouse kitchen.  All the "
    "cupboards and cabinets are bare (unless you can eat the "
    "thick layer of dust which covers everything).\n";
}
farm6(SDESC) = Proc() {Return Sayer("Kitchen", $arg(0));}

farm7(LDESC) = Proc()
{
    "You are in the upstairs bedroom of the farmhouse.  All the "
    "windows are boarded up, and nobody has slept here for years. "
    "To the east is an exit leading to the entry hall below.  ";
    If (bed.OPENED) {
        "In the middle of the room is an old, rickety bed.  The west wall ";
	If (panel.OPENED)
	    "has a panel missing, revealing a secret stairway down.\n";
	Else
	    "seems to have a loose panel.\n";
    }
    Else {
        "Against the west wall is an old, rickety bed (which may be "
        "why nobody has slept here for years).\n";
    }
}
farm7(SDESC) = Proc() {Return Sayer("Bedroom", $arg(0));}

PanL = Proc()                  // Try to go through panel
{
    If (panel.OPENED) {
	$move($ME, cel01);
	"You descend into the gloom...\n";
    }
    Else If ($loc($ME) == farm7) {
	cg();
	$exit(1);
    }
}


town1(SDESC) = Proc() {Return Sayer("Town", $arg(0));}
town1(LDESC) = Proc()
{
    "You are at the northern end of a one-horse town.  Although the buildings "
    "are in good shape, all seem deserted.  You can't even find one horse. "
    "To the east is an old smithy.  On the west side of the street is an "
    "abandoned hotel.  The street runs north and south.\n";
}

town2(SDESC) = Proc() {Return Sayer("Business District", $arg(0));}
town2(LDESC) = Proc()
{
    "You are at the southern end of a one-horse town.  This is the "
    "business district.  On the east side of the street is an old "
    "building with a tastefully lettered sign, 'Arpa-Citizen's Savings'. "
    "To the west is the legendary 'Packet Inn'.  The street runs "
    "north-south.\n";
}

town3(SDESC) = Proc() {Return Sayer("Blacksmith's Shop", $arg(0));}
town3(LDESC) = Proc()
{
    "You're in what is left of a once-thriving blacksmith's shop. "
    "Long ago abandoned, nothing much of interest remains.\n";
}

town4(SDESC) = Proc() {Return Sayer("Flophouse", $arg(0));}
town4(LDESC) = Proc()
{
    "You're in the Flophouse hotel.  Never worth the visit even in "
    "its heyday, a quick search reveals nothing but a lot of dusty rooms.\n";
}

town5(SDESC) = Proc() {Return Sayer("Bank", $arg(0));}
town5(LDESC) = Proc()
{
    "You are in the ancient and venerable institution of Arpa-Citizen's "
    "Savings (there's a branch in your town).  The lobby is tastefully "
    "decorated in marble.  The only feature is a strange sweet-smelling "
    "well in the center of the room.  A mysterious plaque on the side "
    "reads:\n"
    "\t'Drop your bits here!'\n";
}
TWN5y = Proc()
{
    $ME.HAS = $ME.HAS - Dobj.WEIGH;
    $move(Dobj, $loc($ME));
    "A strange glowing network of lights appears, and you can read:\n";
    If (Dobj.POINT) {
	SCORE = SCORE + Dobj.POINT;
	$move(Dobj, $ALL);
	"\tYour account is now at $" $str(SCORE) ".\n"
	"\tThank you for letting Arpa-Citizen's be your host.\n";
    }
    Else {
	"\tYour deposit is worthless";
	If ($pct(25)) {
	    ", but thanks for the trinket!\n";
	    $move(Dobj, $ALL);
	}
	Else {
	    "!  Keep it!\n";
	}
    }
    "The Arpa network mercifully disappears.\n";
}

town6(SDESC)  = Proc() {Return Sayer("Packet Inn", $arg(0));}
town6(LDESC)  = Proc()
{
    "You are at that famous old saloon, the Packet Inn.  Thousands "
    "of the local adventurers drank 'till they were totally zorked in "
    "this colorful old haunt.  A little wandering convinces you that "
    "nothing much is to be seen.\n";
}

/**** DUNGEON PROPER ****/
cel01(LDESC) = Proc()
{
    "You are in a secret cellar below the farmhouse.  In the "
    "corner of one wall is a strange insignia composed of red "
    "and green squares, joined at the corners.  Passages "
    "lead to north and west.  An old stairway leads up and out.\n";
    $move(insignia, cel01);
}
cel01(SDESC) = Proc()
{
    $move(insignia, cel01);
    Return Sayer("Secret Cellar", $arg(0));
}

cel02(LDESC) = Proc()
{
    "You are in a cool cave, once used for the storage of rare "
    "wines.  A cool breeze from the caves to the north keeps this cave "
    "at an even temperature the year round.  Exits can be seen "
    "to the north, south, and east.\n";
}
cel02(SDESC) = Proc() {Return Sayer("Cool Cave", $arg(0));}

/* cel03 was moved to after cel08 */


cel04(LDESC) = Proc()
{
    "This is a small temple to Elbereth, Queen of the Stars.  The walls "
    "glow with a warm iridescence of their own.  They are covered "
    "with murals depicting the kindling of the stars at the Beginning of "
    "Days.  In the corner someone has added an insignia consisting of red "
    "and white squares joined at the corners.  Passages lead east and west, "
    "and a stairway to the north leads down into darkness.\n";
    $move(insignia, cel04);
}
cel04(SDESC) = Proc()
{
    $move(insignia, cel04);
    Return Sayer("Temple", $arg(0));
}
cel04(LIGHT)=TRUE;


cel05(LDESC) = Proc()
{
    If (dragon.KILLED) {
	"You are in a very wet cave.  Puddles of extremely cold water "
	"are everywhere.";
    }
    Else {
	"You are in an icy cave.  All the walls are covered with thick "
	"layers of ice.";
	$move(ice, cel05);
    }
    "  The cave continues north and south, and there is a side tunnel leading ";
    "to the northeast.\n";
}
cel05(SDESC) = Proc()
{
    If (dragon.KILLED) {
	Return Sayer("Wet Cave", $arg(0));
    }
    Else {
	$move(ice, cel05);
	Return Sayer("Ice Cave", $arg(0));
    }
}

cel06(LDESC) = Proc()
{
    "You have reached a large cavern";
    If (!dragon.KILLED) {
	" of ice.  You cannot see "
	"the roof, but you are sure it is covered with icicles.\n";
	$move(ice, cel06);
    }
    Else {
	".  You cannot see the roof, and it looks like something has "
	"melted, covering the floor with puddles.\n";
    }
    "There are exits east and southwest.\n";
}
cel06(SDESC) = Proc()
{
    If (!dragon.KILLED) {
	$move(ice, cel06);
    }
    Return Sayer("Great Cavern", $arg(0));
}


cel07(LDESC) = Proc()
{
    "You are in a tiny side room where the ice dragon ";
    If (dragon.KILLED) "kept"; Else "keeps";
    " his single prize treasure.  You may leave through a western doorway.\n";
}
cel07(SDESC) = Proc() {Return Sayer("Treasure Room", $arg(0));}

cel08(LDESC) = Proc()
{
    "You are in an old abandoned room, once the resident of a frustrated "
    "artist.  A huge mural depicting ";
    If (dragon.KILLED)
	"a gentle green field ";
    Else
	"a barren wasteland ";
    "covers the west wall.  A dim glow comes from the corridor to the east. "
    "Vandals have apparently been here too, for on the painting is drawn "
    "a strange insignia consisting of red and blue squares, joined at "
    "the corners.\n";
    $move(insignia, cel08);
}
cel08(SDESC) = Proc()
{
    $move(insignia, cel08);
    Return Sayer("Artist's Retreat", $arg(0));
}

cel03(LDESC) = Proc()
{
    If (dragon.KILLED) {
	"You are standing on the south bank of a turbulent underground "
	"river.  The only way to go is back south.\n";
    }
    Else {
	"You are standing on a frozen underground river.  The "
	"source of the river seems to have been to the west, and "
	"you can walk that way on the ice.  However, to the "
	"northeast, the river forms a frozen waterfall you can "
	"slide down.\n";
	$move(ice, cel03);
    }
}
cel03(SDESC) = Proc()
{
    If (dragon.KILLED) {
	Return Sayer("Bank of Underground River", $arg(0));
    }
    Else {
	$move(ice, cel03);
	Return Sayer("Top of Frozen Fall", $arg(0));
    }
}

cel09(LDESC) = Proc()
{
    "You are at the southern end of a dry river gorge.  The source "
    "of the river was once a waterfall to the south, but for some reason "
    "it seems frozen solid.  The riverbed continues north.  There is "
    "a large crack in the waterfall to the south.\n";
    $move(ice, cel09);
}
cel09(SDESC) = Proc()
{
    $move(ice, cel09);
    Return Sayer("Southern Gorge", $arg(0));
}

cel10(LDESC) = Proc()
{
    "You are in a dark cave.  The low-hanging stalactites and tall "
    "stalagmites cast eerily human-like shadows on the craggy walls. "
    "A roughly-hewn stairway to the south is lit by a dim illumination "
    "from above, while a slimy pit in the middle of the room leads "
    "down into even inkier blackness.";
    If (dragon.KILLED)
	"  The pit is full of very cold water.";
    "\n";
}
cel10(SDESC) = Proc() {Return Sayer("Shadowy Cave", $arg(0));}

cel11(LDESC) = Proc()
{
    If	(See(<clear crystal>, $cont($loc($ME))) & <clear crystal>.LIGHT) {
	"You are in an impossibly dark cave.  Only the light from your "
	"magic crystal makes it possible to see, even dimly, here.  You "
	"can make out a tunnel leading leading west, and another leading "
	"east.  No other exits are visible.  A large pit lies in the "
	"middle of the cave.\n";
    }
    Else {
	"It's mighty dark in here!";
	If (See(globe, $cont($loc($ME))) & globe.LIGHT) {
	    "  Even your glowing globe is barely visible!";
	}
	"\n";
	Dark = TRUE;
    }
}

cel11(SDESC) = Proc()
{
    If (!(See(<clear crystal>, $cont($loc($ME))) & <clear crystal>.LIGHT)) {
        Dark = TRUE;
    }
    Return Sayer("DARK Cave", $arg(0));
}

cel12(LDESC) = Proc()
{
    "You are in a small chamber which is not quite as dark as the DARK "
    "cave to the west.  There are no other exits.\n";
}
cel12(SDESC) = Proc() {Return Sayer("Small Chamber", $arg(0));}

VAR
    BSaid;

cel13(LDESC) = Proc()
{
    "You are on a large underground lake of ice, thick enough "
    "to walk on.  To the west you can dimly make out a cavern "
    "entrance; to the east is an icy river you can walk on.  ";
    If (cel13.HOLED) {
        "In the middle of the lake is a hole; icy water sloshes about "
        "two feet below the ice.";
    }
    "\n";
    BSaid = FALSE;
    $move(ice, cel13);
}
cel13(SDESC) = Proc()
{
    BSaid = FALSE;
    $move(ice, cel13);
    Return Sayer("Icy Lake", $arg(0));
}

BDesc = Proc()
{
    If (wetsuit.WORN) {
	"Luckily, your wetsuit enables you to breathe down here.\n";
    }
    Else If (!BSaid) {
	"You can't hold your breath for long...\n";
	BSaid = TRUE;
    }
}

cel14(LDESC) = Proc()
{
    "You are under the ice of a frozen lake.  You can barely make out exits "
    "to the east and west.  ";
    If (cel13.HOLED) {
	"There is a hole in the ice above you.\n";
    }
    Else {
	"A diffuse light comes through the ice above.\n";
    }
    BDesc();
    $move(ice, cel14);
}
cel14(SDESC) = Proc()
{
    $move(ice, cel14);
    Return Sayer("Underwater", $arg(0));
}

cel15(LDESC) = Proc()
{
    "You are on a sandy beach in a small ice cave.  A small pool of water "
    "comes up to the beach from the east, and a quick survey of the place "
    "shows that it is completely covered by the stony roof.  You can walk up "
    "to the back of the cave to the south, but the pool seems to be the only "
    "other exit.\n";
    BSaid = FALSE;
}
cel15(SDESC) = Proc()
{
    BSaid = FALSE;
    Return Sayer("Sandy Beach", $arg(0));
}

cel16(LDESC) = Proc()
{
    "You are at the back of a small ice cave.  A sandy shore slopes down "
    "to a blue pool of water to the north.  To the east is a small crawlway "
    "leading into inky blackness.\n";
}
cel16(SDESC) = Proc() {Return Sayer("Back of Cave", $arg(0));}

cel17(LDESC) = Proc()
{
    "You are in a stream under a ceiling of ice.  The stream "
    "leads northeast, and to the west you can see more light.\n";
    BDesc();
    $move(ice, cel17);
}
cel17(SDESC) = Proc()
{
    $move(ice, cel17);
    Return Sayer("In Stream", $arg(0));
}

cel18(LDESC) = Proc()
{
    "You are in a hollow spot behind a frozen waterfall to the north. "
    "Above you, a ceiling of ice gradually lowers to meet a dark "
    "body of water to the southwest.  There is a large crack in the "
    "waterfall.\n";
    $move(ice, cel18);
    BSaid = FALSE;
}
cel18(SDESC) = Proc()
{
    BSaid = FALSE;
    $move(ice, cel18);
    Return Sayer("Hollow Spot", $arg(0));
}

cel19(LDESC) = Proc()
{
    "You are at the source of a frozen stream which flows out of the "
    "rock to the west.  The stream continues to the east.\n";
    $move(ice, cel19);
}
cel19(SDESC) = Proc()
{
    $move(ice, cel19);
    Return Sayer("Source of Frozen Stream", $arg(0));
}

cel20(LDESC) = Proc()
{
    "You are in what was once a study.  The furniture has "
    "been smashed to splinters, and none of the papers or "
    "books remain intact.  The only exit is to the west.\n";
}
cel20(SDESC) = Proc() {Return Sayer("Study", $arg(0));}

cel21(LDESC) = Proc()
{
    If (RiverLoc == GRATELOC) {
        "You have reached a point where a bridge crosses the dry river bed. "
        "The river bed is blocked by a large iron grate to the south.\n";
    }
    Else If (RiverLoc == BEND1LOC) {
        "You are at a sharp bend where the dry river bed coming from the "
        "south turns to the west.\n";
    }
    Else If ((RiverLoc > BEND1LOC) & (RiverLoc <BEND2LOC)) {
	"You are in a dry river bed that runs east-west.\n";
    }
    Else If (RiverLoc == BEND2LOC) {
        "You are at a sharp bend where the dry river bed coming from "
        "the east turns to the south.\n";
    }
    Else {
	"You are in a dry river bed that runs north-south.\n";
    }
}
cel21(SDESC) = Proc()
{
    If (RiverLoc == GRATELOC) {
	Return Sayer("Under Bridge", $arg(0));
    }
    Else If ((RiverLoc == BEND1LOC) | (RiverLoc == BEND2LOC)) {
	Return Sayer("Bend in River", $arg(0));
    }
    Else {
	Return Sayer("Dry River Bed", $arg(0));
    }
}

desert(LDESC) = Proc()
{
    "You are lost in the middle of a vast desert.  The terrain "
    "is the same, no matter which way you look.  The heat "
    "is tremendous, and you have no water.  In other words, "
    "you're in trouble!\n";
}
desert(SDESC) = Proc() {Return Sayer("Desert", $arg(0));}

field(LDESC) = Proc()
{
    "You are in the middle of a grassy field.  Above you is a beautiful "
    "blue sky in which fleecy white clouds make pretty shapes.  The sound "
    "of birds fills the air.  A path leads north to a large building built "
    "of white marble, with hundreds of columns and sculptures about.\n";
}
field(SDESC) = Proc() {Return Sayer("Grassy Field", $arg(0));}

ENDGAME = Proc()
{
    "As you approach the building, a robed figure emerges from the door of "
    "the building.  He looks at you and says, \"I am the former owner of the "
    "farm and of the cellar below.  You have shown great merit in your "
    "struggle to solve my puzzles.  ";
    If ($cont($ME)) {
        "However, you must shun all things wordly before you "
        "can enter here.  Return to your world and come back when you have "
        "attained this.\"\n";
    }
    Else If (SCORE < PMAX) {
        "Unfortunately, you have failed to return all misplaced "
        "treasures to their proper location.  Consider this:  a penny saved "
        "is a penny earned!\"\n";
    }
    Else {
        "You have also wisely shed yourself "
        "of damaging worldly affectations, and have honorably satisfied your "
        "obligations.  Come and join our circle of philosophers!\" "
        "\n\tThe robed figure escorts you into the building.  You have "
        "finished the game!\n";
	$spec(QUIT);
    }
    "The robed figure waves his arms, and you are transported to...\n";
    $move($ME, road1);
    GO = TRUE;
}