! To compile, might I suggest:
! -d2 -s -~S -x \$MAX_INDIV_PROP_TABLE_SIZE=30000 \$MAX_PROP_TABLE_SIZE=20000 wumpus2000

Constant Story "Wumpus 2000";
Constant Headline "^The Virulent Labyrinth Of Yob-Shuggoth^
                                       Copyright 2004 by Muffy St. Bernard.^^
                                       ! Type 'help' for tips, hints and special features !^^";

! Using mazegame.inf code (September 20, 2001)
! Version 1.0   (September 13, 2002)
! Version 1.1   (January 22, 2003)
! Version 1.2   (February 21, 2003)
! Version 1.3   (April 21, 2003)
! Version 1.4   (July 18, 2003)
!       TODO:
!                       Inventory group jewels
!                       "plug hole"
!                       "flip coin"
!                       Mugwump, Schmoo
!                       "x walls"


!----------------------------------------------------------------------------
!  Define global variables
!----------------------------------------------------------------------------

Replace Swimsub;                                ! There's lots of swimming in the game...
Replace Attacksub;                              ! ...and lots of attackin'!
Replace FillSub;                                ! For filling your canteen
Replace WaitSub;                                ! To give you updates while waiting.
Replace TieSub;                                 ! For tying your rope
Replace RestartSub;                             ! Because this doesn't work, for some reason.
Replace DrawStatusLine;                 ! For our fancy status line.

Constant MAXROOMS = 100;                ! The maximum number of rooms in the maze
Constant MAXBATTERY = 30;               ! Maximum charge level of Glow Bar battery.
Constant FILLSROOM = 3;                 ! Cave size below which water fills room.
Constant NO_PLACES = 1;                 ! So user can't use OBJECT or PLACES verbs.

Attribute river;                                ! Room has a river in it.
Attribute sink;                                 ! Object will sink when put in water...
Attribute dissolve;                             ! ...and will be destroyed (must also have sink)
Attribute poison;                               ! Room is poisoned.
Attribute frozen;                               ! Very cold room!

Global DISEASE;                                 ! The number of turns of disease left.
Global FIRSTROOM;                               ! To hold the first created room's number.
Global SWIMMING = 0;                    ! Whether you are swimming or not.
Global LASTROOM = 0;                    ! The last room you were in (needs RR!)
Global TEST = 0;                                ! In testing mode?
Global SHOWNUM = 0;                             ! Show room numbers in descriptions?
Global REGIONSON = 1;                   ! Complicate things with regions?
Global FORFEIT = 0;                             ! Have you cheated?
Global EXPLORE = 0;                             ! Toggle for EXPLORE mode.
Global ECO = 0;                                 ! Ecosystem Display mode
Global KILLED = 0;                              ! Number of dead creatures.
Global RANDSEED = 0;                    ! Random seed number.
Global LOCATION1 = 0;                   ! Starting location.
Global LOCATION100 = 0;                 ! Deepest room in maze.
Global FURNACE = 0;                             ! Furnace room.
Global FREEZER = 0;                             ! Frozen room.

Include "Parser";

Object LibraryMessages
       with
               before
               [x add;
                       ListMiscellany:
                               if (lm_n == 1)
                                       rtrue;
                       Score:
                               if (deadflag)
                               {                                                                                       ! Add score bonuses...
                                       if (FORFEIT)
                                       {
                                               print "Your scoring function was disabled";
                                               rtrue;
                                       }
                                       objectloop (x in player)                                ! ...for items...
                                               add = add + x.monworth;
                                       score = score + add / 200;
                                       score = score + (player.topstrength - 100);             ! ...and topstrength.
                                       print "In that game you scored a total of ";
                               }
                               else
                               {
                                       if (FORFEIT)
                                       {
                                               print "Your scoring function is disabled";
                                               rtrue;
                                       }
                                       print "You have so far scored ";
                               }
                               print score, " point";
                               if (score ~= 1)
                                       print "s";
                               print " in ", turns, " turn";
                               if (turns~=1)
                                       print "s";
                               rtrue;
               ];

Include "Verblib";

!-------------------------------------------------------------------------------
! Set Up Classes
!-------------------------------------------------------------------------------

Class C_ROOMS (120)
       with
               describe
               [;
                       MoveFloatingObjects();
                       RoomDisplay(self);
                       if (CaveObjectPresent(self) == FALSE)   ! Hack: remove spurious
                               print "^";                                                      ! line breaks.
                       rfalse;
               ],
               short_name
               [;
                       print "A";
                       ExitSize(self);
                       print ",";
                       RoomWall(self);
                       if (self has frozen)
                               print ", frozen";
                       if (self has river)
                               print ", watery";
                       PrintRoomType(self);
                       rtrue;
               ],
               depth 0,                                                        ! # of feet underground / 2
               moist 0,                                                        ! Room moistness (0 to 100)
               fungus 0,                                                       ! Amount of fungus (0 to 100)
               bloody 0,                                                       ! Bloodiness of room (0 to ?)
               speed 0,                                                        ! Speed of water, if any.
               size 3,                                                         ! Size of room (1 to 7?)
               footto 0,                                                       ! Which exit prints lead to.
               footfrom 0,                                                     ! Which exit prints lead from.
               conn 0,                                                         ! For connection test.
               byexit 0,                                                       ! Which exit the player is standing by.
               heat 0,                                                         ! Heat level (0 to 400)
               wind 0,                                                         ! Wind level (0 to 100)
               region 0,                                                       ! Region room belongs to
               regiontype 0,                                           ! Type of region (if any)
               regiondepth 0,                                          ! Depth of region (if any)
               x1_to 0,                                                        ! Exits.
               x2_to 0,
               x3_to 0,
               x4_to 0,
               x5_to 0,
               before
               [ thedir temp;
                       Go:
                               thedir = noun.door_dir;
                               if (noun == e_obj or w_obj or n_obj or ne_obj or nw_obj
                                       or s_obj or se_obj or sw_obj)
                                       "You don't have a compass and you were a terrible
                                               Scout.  The best you can do is number the exits
                                               and try to remember them that way: x1, x2,
                                               x3, for instance.";

                               if (noun == u_obj)
                               {
                                       temp = Shallowest(self);
                                       if (temp == self)
                                               "There are no exits going upwards from this
                                               cave.";
                                       noun = ExitToRoom(self, temp);
                                       thedir = noun.door_dir;
                                       if (SNumExits(self) > 1)
                                               print "You pick exit #", noun.num, ".^";
                               }

                               if (noun == d_obj)
                               {
                                       temp = Deepest(self);
                                       if (temp == self)
                                               "There are no exits going downward from this cave.";
                                       noun = ExitToRoom(self, temp);
                                       thedir = noun.door_dir;
                                       if (SNumExits(self) > 1)
                                               print "You pick exit #", noun.num, ".^";
                               }

                               if (self.thedir == FALSE)
                                       "There aren't that many exits.";

                               if (player.topstrength / (Nozero(player.strength / 10)) > 50)
                               {
                                       if (random(3) == 1)
                                               "You're so weak that you collapse!";
                               }

                               if (GetToExit(self, thedir) == FALSE)   ! Get to the exit?
                                       rtrue;

                               if (SWIMMING)
                               {
                                       if (SwimThroughExit(self, thedir) == FALSE)
                                               rtrue;
                               }
                               else
                               {
                                       if (WalkThroughExit(self, thedir) == FALSE)
                                               rtrue;
                               }

                               LASTROOM = self;
               ],
               after
               [ i snatch playweigh playworth;
                       Go:                                                             ! Keep track of footprints
                               if (LASTROOM && noun provides num && SWIMMING == 0)
                                       LASTROOM.footto = noun;
                               else
                               {
                                       if (SWIMMING && random(3) == 1)
                                               LASTROOM.footto = noun;
                               }

                               objectloop (i in player)
                               {
                                       if (i ofclass Rope)             ! Holding a rope?
                                       {
                                               if (i.tiedto > 0)       ! Tied to something?
                                               {
                                                       if (i.tiedto == LASTROOM)
                                                               print "You play the rope out after you.^";
                                                       else
                                                       {
                                                               if (real_location == i.tiedto)
                                                                       print "You coil the rope up behind you.^";
                                                               else
                                                               {
                                                                       print "You can't stretch the rope any further, so you
                                                                               leave it behind.^";
                                                                       snatch = i;
                                                               }
                                                       }
                                               }
                                       }
                               }
                               if (snatch)
                                       move snatch to LASTROOM;

                               if (SWIMMING)
                               {
                                       i = LASTROOM.speed - real_location.speed;
                                       if (i > 2)
                                       {
                                               if (i > 4)
                                                       print "The river slows dramatically as it enters the next room.^";
                                               else
                                                       print "The river slows down a bit.^";
                                       }
                                       if (i < -2)
                                       {
                                               if (i < -4)
                                                       print "The river speeds up suddenly as it flows into the next room!^";
                                               else
                                                       print "The river speeds up a bit.^";
                                       }
                               }

                               if (Whatlevel(LASTROOM) ~= Whatlevel(real_location))
                                       print "You seem to have crossed into a different part of
                                               the cave.^";
                               rfalse;
                       Inv:
                               playweigh = WeightOf(player);
                               playworth = WorthOf(player);
                               if (playweigh > 0)
                               {
                                       print "^You are carrying ", playweigh, " lb";
                                       if (playweigh > 1)
                                               print "s";
                                       print " of stuff (";
                                       print WeighPercent(player), "% of your current capacity).  ";
                                       if (playworth)
                                               print "It's all worth about $", WorthOf(player), ".^";
                                       else
                                               print "You aren't carrying anything of worth.^";
                               }
               ],
               create
               [;
!
               ];

Class Features
       with
               description "The cave features are awe-inspiring at first, but soon
                       become mundane.",
               before
               [;
                       Examine:
                               rfalse;
                       Eat:
                               "You could never be that hungry.";
                       default:
                               "You have more pressing things to do at the moment.";
               ],
       has
               scenery;

Class Chute
       class
               Features
       with
               short_name "vertical chute",
               description "Either you underestimate the power of mother nature, or this
                       cave feature wasn't created by strictly natural phenomena.  It rises
                       sharply upward into the wall, reminding you more of a slide than
                       something formed by lava flows or dripping water.",
               name 'vertical' 'chute' 'natural' 'slide' 'tunnel' 'hole' 'smooth' 'sharp'
                       'featureless',
               clevel 2,                                                               ! Level of chute
               before
               [;
                       Take:
                               "It's part of the wall.";
               ],
               react_before
               [;
                       Climb, Enter:
                               if (noun == self)
                                       "It's too smooth and it rises too sharply.";
               ],
               initial "A smooth, featureless chute juts out of the cave wall.",
       has
               ~scenery;

Class CaveObject
       with
               worth 0,                                                                ! Degree of worth, 1 to 100
                                                                                               ! IMPORTANT: Worth of 0 will never be
                                                                                               ! sought or taken by creatures!
                                                                                               ! Good for skeletons, notes, etc.
               monworth 0,                                                             ! Monetary worth (in dollars)
               inroom 0,                                                               ! For riverbag
               weight 1,                                                               ! In lbs.
               hoarded 0,                                                              ! 1, thieves are not interested!
               after
               [;
                       Take:
                               self.hoarded = 0;
                               if (self.worth == 0)
                                       self.worth = 50;
               ],
               react_after
               [;
                       Examine:
                               if (noun == self)
                               {
                                       print "^";
                                       print (The) self, " weighs about ";
                                       if (metaclass(self.weight) == routine)
                                               print self.weight();
                                       else
                                               print self.weight;
                                       print " lb";
                                       if (self.weight > 1)
                                               print "s";
                                       print ", and you figure it";
                                       if (self.monworth == 0)
                                               print " isn't worth anything, moneywise.";
                                       else
                                               print "'s worth $", self.monworth, ".";
                                       if (self provides strengthbonus)
                                       {
                                               print "  In terms of weaponry, it is ";
                                               print WEPercent(self), "% the most powerful weapon you
                                                       can imagine.";
                                       }
                                       print "^";
                               }
               ],
               before
               [;
                       ThrowAt:
                               if (self.weight < 2)
                               {
                                       print (The) noun, ", being light, falls far short of ",
                                               (the) second, ".^";
                                       keep_silent = TRUE;
                                       < drop noun >;
                                       keep_silent = FALSE;
                                       rtrue;
                               }
                               if (second has animate)
                               {
                                       ObjectHits(noun, second);
                                       keep_silent = TRUE;
                                       < drop noun >;
                                       keep_silent = FALSE;
                                       rtrue;
                               }
                               print "Clunk!  Good aim!^";
                               keep_silent = TRUE;
                               < drop noun >;
                               keep_silent = FALSE;
                               rtrue;
               ];

Class Key
       class CaveObject
       with
               name 'key',
               description "There is nothing remarkable about this key.",
               worth 100,
               monworth 1,
               weight 1,
               turned 0,
               before
               [ x mult;
                       Take:
                               if (self in keyhole && door_iron has open)
                                       "You can't remove the key while the door is open.";
                       Turn:
                               if (self notin keyhole)
                                       "There's no sense in turning the key unless it's in a keyhole.";
                               if (door_iron has open)
                                       "The keys won't turn while the door is open.";
                               print "You turn ", (the) self;
                               if (self.turned)
                               {
                                       print " and hear a heavy thump within the door.^";
                                       self.turned = 0;
                                       if (door_iron hasnt locked)
                                       {
                                               print "Something inside the door rams home with a metallic clang.^";
                                               give door_iron locked;
                                       }
                               }
                               else
                               {
                                       print " and hear a polite click.^";
                                       self.turned = 1;
                                       if (children(keyhole) == 3)
                                       {
                                               mult = 1;
                                               objectloop (x in keyhole)
                                                       mult = mult * x.turned;
                                               if (mult)
                                               {
                                                       print "Something inside the door slides back!^";
                                                       give door_iron ~locked;
                                               }
                                       }
                               }
                               rtrue;
               ],
       has
               sink;

Class Jewel
       class CaveObject
       with
               name 'jewel',
               color 1,
               lightness 1,
               quality 1,
               short_name
               [;
                       switch(self.quality)
                       {
                               1:      print "clear";
                               2:      print "opaque";
                               3:      print "milky";
                               4:      print "shimmery";
                               5:      print "shiny";
                               6:      print "dull";
                       }
                       print " ";
                       switch(self.lightness)
                       {
                               1:      print "dark ";
                               2:      print "light ";
                       }
                       switch(self.color)
                       {
                               1:      print "red";
                               2:      print "orange";
                               3:      print "yellow";
                               4:      print "blue";
                               5:      print "green";
                               6:      print "violet";
                       }
                       print " jewel";
                       rtrue;
               ],
               description
               [;
                       print "This is a ";
                       self.short_name();
                       print ".  Not being a gemologist, you don't know what it's made of...but it
                               looks unnatural.^";
               ],
               parse_name
               [ n q l c daword;
                       switch(self.quality)
                       {
                               1:      q = 'clear';
                               2:      q = 'opaque';
                               3:      q = 'milky';
                               4:      q = 'shimmery';
                               5:      q = 'shiny';
                               6:      q = 'dull';
                       }
                       switch(self.lightness)
                       {
                               1:      l = 'dark';
                               2:      l = 'light';
                       }
                       switch(self.color)
                       {
                               1:      c = 'red';
                               2:      c = 'orange';
                               3:      c = 'yellow';
                               4:      c = 'blue';
                               5:      c = 'green';
                               6:      c = 'violet';
                       }
                       do
                       {
                               daword = NextWordStopped();
                               if (daword == q || daword == l || daword == c)
                                       n++;
                               if (WordInProperty(daword, self, name))
                                       n++;
                               if (daword == 'jewels')
                               {
                                       n++;
                                       parser_action = ##PluralFound;
                               }
                       }
                       until (daword == -1);
                       return n;
               ],
               worth 1,
               monworth 1,
               weight 1,
       has
               sink;

Class Sensor
       class CaveObject
       with
               description
               [;
                       print "You know exactly how to operate this device, thanks to the ~Nifty New
                       Gadgets~ column you used to edit.  This is a small electronic sensor -- the size and
                       shape of a marble -- which sends information about its surroundings back
                       to a receiver.  Without the receiver, however, these sensors might as well BE
                       marbles.^^";
                       print "This sensor has ~", (string) self.snum,"~ engraved on it.^";
               ],
               snum "foo",
               name 'small' 'electronic' 'sensor' 'marble',
               worth 45,
               monworth 75,
               weight 3,
               lasttotal 0,
       has
               sink proper;

Class Rope
       class CaveObject
       with
               description
               [;
                       print "A length of rough
                       and sturdy rope, woven by smiling dock-workers and stress-tested by overweight
                       SWAT teams.  You could easily tie it to something in the cave (there
                       are a multitude of nooks and crannies around), then
                       depend on it to get you out of subsequent pits or torrents of rushing
                       water.  Rope like this is so useful that you'd almost consider marrying
                       it.^^
                       It is ";
                       if (self.tiedto == 0)
                               "not tied to anything at the moment.";
                       if (self.tiedto == real_location)
                               "tied to a suitable part of this cavern.";
                       "tied to something through exit #",
                               ExitToRoom(real_location, self.tiedto).num,
                               ".";
               ],
               name 'length' 'rough' 'sturdy' 'rope' 'woven' 'tested' 'dependable' 'useful',
               before
               [ croom thedir;
                       Climb:
                               if (self.tiedto == 0)
                                       "It's not tied to anything.";
                               if (self.tiedto == real_location)
                                       "There rope doesn't go anywhere.";
                               croom = self.tiedto;
                               if (croom.depth > real_location.depth)
                                       "The rope goes down from here, not up.";
                               noun = ExitToRoom(real_location, croom);
                               thedir = noun.door_dir;
                               << Go noun >>;
               ],
               after
               [ croom;
                       Drop:
                               if (self.tiedto == 0)
                                       rfalse;
                               croom = self.tiedto;
                               if (croom.depth > real_location.depth)
                               {
                                       print "The rope slips down through exit #",
                                               ExitToRoom(real_location, croom).num, ".^";
                                       move self to croom;
                                       rtrue;
                               }
                       Take:
                               if (self.tiedto)
                                       "You pick up the end of the rope.";
               ],
               specific "rope",                                                        ! For differentiating...
               short_name
               [;
                       print (string) self.specific, " (";
                       if (self.tiedto == real_location)
                       {
                               print "tied to a feature in this cave)";
                               rtrue;
                       }
                       if (self.tiedto == 0)
                       {
                               print "all coiled up)";
                               rtrue;
                       }
                       print "dangling from exit #", ExitToRoom(real_location, self.tiedto).num, ")";
                       rtrue;
               ],
               plural "ropes",
               worth 30,
               monworth 5,
               weight 4,
               tiedto 0,
               article
               [;
                       if (self in player)
                               print "your";
                       else
                               print "a";
               ];

Class FoodBar
       class
               CaveObject,
       with
               description "You can pick these food pellets up at any local variety
                       store.  Billed as the ~number one protein source for
                       discriminating astronauts,~ you have to agree.  At the very
                       least they're nutritious.",
               name 'food' 'pellet' 'pellets' 'protein' 'tasty' 'nutritious',
               short_name "food pellet",
               plural "food pellets",
               worth 25,
               weight 1,
               monworth 2,
               before
               [;
                       Eat:
                               if (actor.hunger > 80)
                               "You aren't hungry enough to eat the whole pellet...those things
                                       are filling!";
               ],
               after
               [;
                       Eat:
                               print "Mmmmm...not too bad!^";
                               EatFood(actor, 80);
                               move self to objectbag;
                               rtrue;
               ],
       has
               edible sink;

Class GinkoBar
       class
               CaveObject,
       with
               description "Ahh, you'd know these things anywhere: it's a Ginko Bar,
                       long touted as the ~number one strength-booster for weight-lifters
                       who don't mind getting disqualified.~  Made from ground ginko --
                       a kind of lizard, you think -- they provide three months worth
                       of enhanced physical ability.  Eat enough of them and you'll feel
                       the cumulative effects of herbal strength.  Just keep in mind that
                       traces will show up in your urine even after you're dead, and they
                       HAVE been known to cause extensive brain damage to small children.",
               name 'food' 'bar' 'ginko' 'bars' 'strength' 'booster' 'lizard'
                       'herbal',
               short_name "ginko bar",
               plural "ginko bars",
               worth 45,
               weight 1,
               monworth 10,
               before
               [;
                       Eat:
                               if (actor.hunger > 80)
                               "Honestly, you can't eat another bite...don't be a glutton!";
                       Smell:
                               "Smells of ginko.";
               ],
               after
               [;
                       Eat:
                               print "Yum...the taste of Ginko Bars always reminds you of
                                       your first reptile-kiss!^^";
                               EatFood(actor, 30);
                               RaiseStrength(actor, 50);
                               move self to objectbag;
                               rtrue;
               ],
       has
               edible sink;

Class SmallRock
       class
               CaveObject,
       with
               description "A rock is a rock is a rock, but this one is round and it
                       fits nicely into your hand.  It's light grey, probably made of
                       granite, and
                       it doesn't look like it came from the walls of the cave.",
               name 'rock' 'round' 'light' 'grey' 'granite' 'stone' 'small',
               short_name "small rock",
               plural "small rocks",
               worth 3,
               weight 6,
               monworth 0,
               after
               [;
                       Drop:
                               if (random(6) > 1)
                                       "The rock clatters to the ground.";
                               move self to ObjectBag;
                               "The rock shatters into tiny pieces when it hits the ground.";
               ],
       has
               sink;

Class LargeRock
       class
               CaveObject,
       with
               description "Where this rock came from is a mystery -- it's probably
                       feldspar, unlike the walls of the cave -- but it just might be
                       useful.  A bit heavy and bulky, but aerodynamic as the dickens.",
               name 'rock' 'feldspar' 'heavy' 'bulky' 'large' 'big' 'aerodynamic'
                       'stone',
               short_name "large rock",
               plural "large rocks",
               worth 3,
               weight 20,
               monworth 0,
               after
               [;
                       Drop:
                               if (random(3) > 1)
                                       "The rock drops heavily to the ground.";
                               move self to ObjectBag;
                               "The rock shatters into millions of tiny pieces when it hits
                                       the ground.";
               ],
       has
               sink;

Class Weapon
       class
               CaveObject,
       with
               strengthbonus 0,                                                ! Bonus added to strength
               name 'weapon'
       has
               sink;

Class Barrel
       with
               name 'barrel' 'oozing' 'toxic' 'waste',
               short_name
               [;
                       if (self.ooze)
                       {
                               MoveFloatingObjects();
                               print "oozing barrel";
                               rtrue;
                       }
                       print "barrel";
                       rtrue;
               ],
               description
               [;
                       print "Now you know where that toxic waste ended up...some of it is in
                               this barrel, which is covered with warning signs like ~Hazard!~ and
                               ~Danger!~ and ~Open this and you might die!~  Even if you were
                               inclined, you can't see any way to open the barrel, though thanks
                               to being carelessly thrown around there's a small
                               hole in the bottom.  On the top of the barrel, somebody has written ~";
                       print (OozeIncrement(self.clevel) * 100) / 160, " proof.~^";
               ],
               before
               [;
                       Open:
                               "You can't see any way to open the barrel...it was probably never
                                       INTENDED to be opened.";
                       Take, Push, Pull:
                               "You manage to shift it around a bit -- just enough to hear something
                                       sloshing around inside -- but you don't have a hope of budging it.";
               ],
               each_turn
               [;
                       move obarrelhole to FindCeiling(self);
                       if (self.ooze)
                       {
                               move oooze to FindCeiling(self);
                               move self to FIndCeiling(self);
                       }
               ],
               ooze FALSE,
               clevel 5,
               time_left 0,
               time_out
               [;
                       if (TestScope(self) && self.ooze == FALSE)
                               print "Some toxic liquid oozes out of the hole in the barrel.^";
                       self.ooze = TRUE;
                       StartTimer(self, random(10 * self.clevel));
               ]
       has
               light;

Class Corpse,
       class
               CaveObject,
       with
               name 'corpse' 'body' 'grisly' '.blank' '.blank',
               crename "undefined",
               creclass 0,
               type 0,
               shuffler 0,
               short_name "undefined",
               parse_name
               [;
                       return -1;
               ],
               description
               [;
                       print "This looks like the corpse of a ";
                       if (self provides shuffler && self.shuffler)
                       {
                               PrintCreName(self);
                               print " ";
                       }
                       print (string) self.crename, ".";
                       if (self.eaten)
                               print "  All the choice bits and pieces have been gnawed
                               off of it.";
                       print "^";
               ],
               before
               [;
                       Attack:
                               "You're too late...it's already dead.";
                       Eat:
                               if (self.eaten)
                                       "It's already been picked clean!";
                               if (actor.hunger > 80)
                                       "You're not hungry enough to pick raw flesh off of a
                                       corpse...yet.";
                               EatFood(actor, self.weight);
                               self.eaten++;
                               self.weight = self.weight / 2;
                               "It tastes a bit like chicken.  Or rather, a chicken that was
                               hatched in the darkest pits of hell.";
               ],
               language 1,
               size 1,
               eaten 0,
               weight 50,
               worth 0,
               monworth 0,
               corpseturn 0,
               body "nada"
       has
               sink edible;

Class Skeleton,
       class
               CaveObject,
       with
               name 'skeleton' 'bone' 'bones' 'skull',
               before
               [;
                       Eat:
                               "There's little left to eat on
                               the skeleton.  Just bones.";
                       Attack:
                               "You're a little too late for that.";
                       Take:
                               if (bone_club in objectbag or riverbag)
                               {
                                       print "The thighbone looks like it might be
                                               useful...you pick it up.^";
                                       move bone_club to location;
                                       << Take bone_club >>;
                               }
               ],
               after
               [;
                       Take:
                               "The skeleton is cumbersome, but you manage to scrape
                                       it all together and pick it up.";
                       Drop:
                               "It clatters to the ground.";
               ],
               weight 5,
               worth 0,
               monworth 15,
       has
               sink;

Class Note
       class
               CaveObject,
       with
               name 'note' 'letter' 'scrap' 'of' 'paper',
               weight 1,
               worth 0,
               monworth 0,
               after
               [;
                       Eat:
                               "You've tasted better notepaper.";
               ],
       has
               edible sink dissolve;

Class Creature                                                                  ! All creatures must provide...
       with
               shuffler 0,                                                             ! Shuffle parse & sn?
               type 1,                                                                 ! Type # of creature (for parse & sn)
               crename "blah",                                                 ! Text String of creature name.
               creclass 0,                                                             ! Class of creature
               weight 0,                                                               ! Weight of creature
               strength 0,                                                             ! Current strength
               topstrength 0,                                                  ! Highest possible strength
               lroom 0,                                                                ! Last room inhabited
               speed 33,                                                               ! # Chance of move/turn
               hunger 100,                                                             ! How hungry (0 to 100)
               attackstyle1 "...",                                             ! Attack strings
               attackstyle2 "...",
               enterstring "...",                                              ! Coming into a room...
               leavestring "...",                                              ! ...and leaving it.
               diestring "...",                                                ! For when it dies.
               minworth 0,                                                             ! Minimum treasure worth
                                                                                               ! 0 No treasure
                                                                                               ! -1 Fixed treasure
               maxworth 0,                                                             ! Maximum treasure worth
                                                                                               ! (if minworth -1, this is item number)
               hiding 0,                                                               ! Hidden in the water.
               willfight 0,                                                    ! For prey: willing to fight?
               leavecorpse 1,                                                  ! Leave a corpse behind?
               rebirth 10,                                                             ! % Chance of rebirth
               inlevel 0,                                                              ! Level it is generated in
                                                                                               ! (0 = let designer generate it!)
               AIStyle 1,                                                              ! 1 Fungus eater, prey
                                                                                               ! 2 Footprint follower, predator
                                                                                               ! 3 Pool hider
                                                                                               ! 4 Thief, prey
                                                                                               ! 5 Boga
                                                                                               ! 6 Cinderbugs
                                                                                               ! 7 Compressor
                                                                                               ! 8 Baby
               short_name
               [;
                       if (self provides shuffler && self.shuffler)
                       {
                               PrintCreName(self);
                               print " ";
                       }
                       print (string) self.crename;
                       if (self ofclass Corpse)
                               print " corpse";
                       rtrue;
               ],
               parse_name
               [ q n daword;
                       if (parser_action == ##TheSame)
                               return -2;
                       if (self provides hiding && self.hiding)
                               return 0;
                       if (self ofclass Corpse)
                       {
                               if (action == ##Attack && CreaturesPresent(real_location) > 1)
                                       return 0;
                       }
                       q = ParseCreName(self);
                       do
                       {
                               daword = NextWordStopped();
                               if (q && daword == q)
                                       n++;
                               if (WordInProperty(daword, self, name))
                                       n++;
                       }
                       until (daword == -1);
                       return n;
               ],
               before
               [;
                       Attack:
                               rfalse;
               ],
               react_after
               [;
                       Examine:
                               if (noun == self)
                               {
                                       print "^";
                                       PrintCreCompare(player, self);
                               }
               ],
               life
               [;
                       WakeOther:
                               "It doesn't seem like anything in these caves actually sleeps.";
                       Kiss:
                               print (The) self, " does not consent.^";
                               rtrue;
                       Give, Show:
                               print (The) self, " is not interested.^";
                               rtrue;
                       Ask, Tell, Answer, Order:
                               print (The) self, " has no idea what you're talking
                                       about.^";
                               rtrue;
               ],
               name 'creature' 'monster' 'beast';

!Class Actions
!       with
!               startmsg 0,
!               currentmsg 0,
!               conditions
!               [;
!                       return 0;
!               ],
!               noisy 0,                                                                        ! Is the action noisy?
!               result 0,                                                                       ! -20 to 20
!               change FALSE;

! All creatures that are part of their own class should have '.blank' as their first
! name entry, to keep corpses on track...

Class Baby
!       class Creature,
       with
               description "Wah-wah-wah!",
               name '.blank' 'baby',
               crename "baby",
!               weight 30,
!               strength 20,
!               topstrength 20,
!               attackstyle1 "mushes its gums",
!               attackstyle2 "pees",
!               enterstring "wobble into the room",
!               leavestring "toddles away",
!               diestring "grunts and collapses",
!               language 1,
!               size 1,
!               minworth 1,
!               maxworth 20,
!               prey,
!               AIStyle 8,
!               speed 15,
!               rebirth 0,
!               inlevel 3,
!               happy 100,                                                                                      ! 0 to 100
!               change 1,                                                                                       ! direction of change
!               desire 0,                                                                                       ! action they will probably take
!               last 0,                                                                                         ! last action
!               desirenum 0,                                                                            ! 0 to 100
!               life
!               [;
!                       WakeOther:
!                               "Even if the baby were sleeping, why on earth would you want to do that?";
!                       Kiss:
!                               print (The) self, " does not consent.^";
!                               rtrue;
!                       Give, Show:
!                               print (The) self, " snatches it away!^";
!                               move noun to self;
!                               rtrue;
!                       Ask, Tell, Answer, Order:
!                               print (The) self, " has no idea what you're talking
!                                       about.^";
!                               rtrue;
!               ],
!               short_name
!               [;
!                       switch(self.size)
!                       {
!                               1:      print "gaunt";
!                               2:      print "bony";
!                               3:      print "sinewy";
!                               4:      print "flabby";
!                               5:      print "chubby";
!                               6:      print "plump";
!/                              7:      print "fat";
!/                              8:      print "obese";
!/                      }
!/                      print " ";
!/                      switch(self.language)
!/                      {
!/                              1:      print "English";
!/                              2:      print "Arabic";
!/                              3:      print "Spanish";
!/                              4:      print "Italian";
!/                              5:      print "Greek";
!/                              6:      print "Chinese";
!/                              7:      print "Indian";
!/                              8:      print "Mimac";
!/                              9:      print "Russian";
!/                              10:     print "Swedish";
!/                      }
!/                      print " baby ";
!/                      if (self has female)
!/                              print "girl";
!/                      else
!/                              print "boy";
!/                      if (self ofclass Corpse)
!/                              print " corpse";
!/                      rtrue;
!/              ],
!/              sayhello
!/              [ ;
!/                      switch (self.language)
!/                      {
!/                              1:      print "hi";
!/                              2:      print "marhaban";
!/                              3:      print "hola";
!/                              4:      print "buon giorno";
!/                              5:      print "kalimera";
!/                              6:      print "ni hao";
!/                              7:      print "namaste";
!/                              8:      print "k'we";
!/                              9:      print "zdravstvuite";
!/                              10:     print "god dag";
!/                      }
!/              ],
!/              saygoodbye
!/              [ ;
!/                      switch (self.language)
!/                      {
!/                              1:      print "bye";
!/                              2:      print "il@^a l-liq@^a";
!/                              3:      print "adi@'os";
!/                              4:      print "arrivederci";
!/                              5:      print "yassou";
!/                              6:      print "joi gin";
!/                              7:      print "accha";
!/                              8:      print "nmu'ltes";
!/                              9:      print "do svidanja";
!/                              10:     print "hejd@oa";
!/                      }
!/              ],
!/              each_turn
!/              [ msg;
!/                      if (self.last == self.desire)
!/                      {
!/                              msg = self.last;
!/                              if (msg && metaclass(msg.currentmsg) == string)
!/                                      print (The) self, " ", (string) msg.currentmsg,".^";
!/                      }
!/                      else
!/                              self.last = self.desire;
!/              ],
!/              parse_name
!/              [ q l c n daword;
!/                      if (parser_action == ##TheSame)
!/                              return -2;
!/                      if (self ofclass Corpse)
!/                      {
!/                              if (action == ##Attack && CreaturesPresent(real_location) > 1)
!/                                      return 0;
!/                      }
!/                      switch(self.size)
!/                      {
!/                              1:      q = 'gaunt';
!/                              2:      q = 'bony';
!/                              3:      q = 'sinewy';
!/                              4:      q = 'flabby';
!/                              5:      q = 'chubby';
!/                              6:      q = 'plump';
!/                              7:      q = 'fat';
!/                              8:      q = 'obese';
!/                      }
!/                      if (self has female)
!/                              l = 'girl';
!/                      else
!/                              l = 'boy';
!/                      switch(self.language)
!/                      {
!/                              1:      c = 'English';
!/                              2:      c = 'Arabic';
!/                              3:      c = 'Spanish';
!/                              4:      c = 'Italian';
!/                              5:      c = 'Greek';
!/                              6:      c = 'Chinese';
!/                              7:      c = 'Indian';
!/                              8:      c = 'Mimac';
!/                              9:      c = 'Russian';
!/                              10:     c = 'Swedish';
!/                      }
!/                      do
!/                      {
!/                              daword = NextWordStopped();
!/                              if (daword == q || daword == l || daword == c)
!/                                      n++;
!/                              if (WordInProperty(daword, self, name))
!/                                      n++;
!/                      }
!/                      until (daword == -1);
!/                      return n;
!/              ],
!/              before
!/              [;
!/                      Take:
!/                              move self to player;
!/                              "You pick up the baby.";
!/              ],
       has
               animate transparent;

Class Grubling
       class Creature,
       with
               description "These enormous, pale, bloated grubs ramble endlessly around the
                       caves looking for fungus to eat.  They move surprisingly fast, considering
                       they have no arms or legs, and they seem able to perceive their environment
                       without any sensory organs that you can dream of.",
               name '.blank' '.blank' 'grubling' 'enormous' 'pale' 'bloated' 'grub' 'grubs'
                       'rambling' 'gaping' 'maw',
               shuffler 12,
               crename "grubling",
               creclass Grubling,
               weight 70,
               strength 80,
               topstrength 80,
               attackstyle1 "snaps its gaping maw",
               attackstyle2 "sprays a misty liquid",
               enterstring "crawl into the room",
               leavestring "crawls out of the room",
               diestring "curls up and dies",
               minworth 1,
               maxworth 20,
               prey,
               AIStyle 1,
               rebirth 20,
               inlevel 2,
               each_turn
               [;
                       if (self.willfight == FALSE && random(5) == 1)
                       {
                               print (The) self, " ";
                               switch (random(5))
                               {
                                       1:
                                               "inches around the cavern.";
                                       2:
                                               "squishes quietly.";
                                       3:
                                               "rears up suddenly.";
                                       4:
                                               "flattens to the ground.";
                                       5:
                                               "emits a gassy odour.";
                               }
                       }
               ],
       has
               animate;

Class Rocker
       class Creature
       with
               description "This base, elemental creature is a collection of all cavernous
                       dangers:
                       spiked hands, grinding teeth, shuddering feet and rolling biceps.  It's
                       vaguely humanoid, but looks more like a parody of nature and destruction
                       than anything with a higher purpose.",
               name '.blank' 'rocker' 'rock' 'smasher' 'base' 'elemental' 'spike' 'spikes' 'spiked'
                       'hand' 'hands' 'grinding' 'teeth' 'shuddering' 'feet' 'foot' 'tooth'
                       'rolling' 'bicep' 'biceps' 'humanoid' 'parody',
               shuffler 8,
               crename "rocker",
               creclass Rocker,
               speed 10,
               weight 250,
               strength 400,
               topstrength 400,
               attackstyle1 "swats its spikey appendages",
               attackstyle2 "swings its massive arms",
               enterstring "crash in",
               leavestring "retreats",
               diestring "topples to the ground and shatters",
               minworth 30,
               maxworth 50,
               predator,
               rebirth 8,
               leavecorpse 0,
               inlevel 3,
               AIStyle 2,
               each_turn
               [;
                       if (random(5) == 1)
                       {
                               print (The) self, " ";
                               switch (random(5))
                               {
                                       1:
                                               "throws itself against the cave walls.";
                                       2:
                                               "chatters its teeth at you.";
                                       3:
                                               "flexes its rocky biceps.";
                                       4:
                                               "grins like an idiot.";
                                       5:
                                               "rocks slowly back and forth, preparing for something...";
                               }
                       }
               ],
       has
               animate;

Class Reptodon
       class Creature,
       with
               description "Somebody has decided to mix an alligator with a mastodon, and invented
                       something far more vicious than either creature.  It's all scales, teeth and
                       tusks, with enough nastiness left over for claws and a cruelly whipping
                       tail.",
               name '.blank' '.blank' 'reptodon' 'alligator' 'mastodon' 'vicious' 'reptile'
                       'scales' 'teeth' 'eyes' 'reptilian'
                       'tusk' 'tusks' 'nasty' 'claws' 'cruel' 'tail' 'cruelly'
                       'whipping' 'tongue' 'articulated' 'head',
               shuffler 8,
               crename "reptodon",
               creclass Reptodon,
               speed 25,
               weight 110,
               strength 200,
               topstrength 200,
               attackstyle1 "bares its teeth",
               attackstyle2 "slaps its articulated tail",
               enterstring "slither menacingly",
               leavestring "retreats",
               diestring "spasms wildly and dies",
               minworth 20,
               maxworth 40,
               predator,
               rebirth 5,
               AIStyle 2,
               inlevel 4,
               each_turn
               [;
                       if (random(5) == 1)
                       {
                               print (The) self, " ";
                               switch (random(5))
                               {
                                       1:
                                               "flicks its tail against the walls of the cave.";
                                       2:
                                               "hisses.";
                                       3:
                                               "rolls its reptilian eyes at you.";
                                       4:
                                               "flicks its claws at your face.";
                                       5:
                                               "whips around in a quick circle.";
                               }
                       }
               ],
       has
               animate;

Class Guard
       class Creature,
       with
               description "This person looks trained in both offense and defense, but at
                       the same time doesn't look particularly interested in doing either.  The
                       guard's expression seems to communicate ~Don't mess with me and I won't
                       mess with you.~",
               name '.blank' '.blank' 'guard' 'trained' 'expression',
               shuffler 8,
               crename "guard",
               creclass Guard,
               speed 50,
               weight 150,
               strength 400,
               topstrength 400,
               attackstyle1 "punches",
               attackstyle2 "kicks",
               enterstring "march in",
               leavestring "marches",
               diestring "drops heavily to the ground",
               minworth 20,
               maxworth 90,
               predator,
               rebirth 0,
               AIStyle 13,
               inlevel 0,
               goingup 1,
               each_turn
               [;
                       if (random(5) == 1)
                       {
                               print (The) self, " ";
                               switch (random(5))
                               {
                                       1:
                                               "tries to stare you down.";
                                       2:
                                               "says ~I'm just doing my job, you see.~";
                                       3:
                                               "says ~I'd rather be seeing this on TV.~";
                                       4:
                                               "asks, ~Why can't you just leave us alone?~";
                                       5:
                                               "expressess admiration for your ~gumption.~";
                               }
                       }
               ],
       has
               animate proper;

Class CinderBug
       class Creature
       with
               description "If these little dots of fire weren't moving so offensively,
                       you'd think they were cinders.  They don't look smart or particularly
                       dangerous, but they sure are fast.",
               name '.blank' 'cinder' 'bug' 'cinderbug' 'little' 'dot' 'dots' 'fire'
                       'offensive' 'offensively' 'moving',
               shuffler 15,
               crename "cinderbug",
               creclass CinderBug,
               speed 90,
               weight 1,
               strength 5,
               topstrength 25,
               attackstyle1 "zips",
               attackstyle2 "darts",
               enterstring "zip",
               leavestring "floats",
               diestring "winks out, leaving nothing behind",
               minworth 0,
               prey,
               AIStyle 6,
               leavecorpse 0,
               rebirth 0,
               inlevel 0,
               invent
               [;
                       if (inventory_stage == 2)
                               rtrue;
               ],
               each_turn
               [;
                       if (random(5) == 1)
                       {
                               print (The) self, " ";
                               switch (random(5))
                               {
                                       1:
                                               "bounces off the walls of the cave.";
                                       2:
                                               "makes a high-pitched buzzing sound.";
                                       3:
                                               "darts towards you.";
                                       4:
                                               "draws a figure-eight in the air.";
                                       5:
                                               "zooms back and forth, dazzling you.";
                               }
                       }
               ],
       has
               animate light;

Class Beetle
       class Creature
       with
               description
               [;
                       print "This smooth, red beetle is about the size of a dinner plate, and is
                               crouched down in the middle of the cave, staring at you expectantly.  A loud
                               ticking noise is coming from inside its belly, which is marked with the words:";
                       print " ~", (name) self, ".~^";
               ],
               name 'smooth' 'red' 'beetle' 'crouching' 'staring' 'belly' 'loud' 'ticking'
                       'noise',
               article "the",
               crename "beetle",
               creclass Beetle,
               speed 25,
               weight 5,
               strength 50,
               topstrength 50,
               attackstyle1 "nibbles",
               attackstyle2 "snaps",
               enterstring "scrabble",
               leavestring "scuttles",
               diestring "turns on its back and crumbles away",
               prey 1,
               minworth 0,
               AIStyle 9,
               leavecorpse 0,
               rebirth 0,
               inlevel 0,
               each_turn
               [;
                       if (random(5) == 1)
                       {
                               print (The) self, " ";
                               switch (random(5))
                               {
                                       1:
                                               "shifts itself slightly.";
                                       2:
                                               "speeds up its ticking sound.";
                                       3:
                                               "puffs up threateningly.";
                                       4:
                                               "seems to wonder what to do about you.";
                                       5:
                                               "makes a quick crackling noise.";
                               }
                       }
               ],
       has
               animate;

Class Quickpaw
       class Creature
       with
               description "Shaped like an ape, but extremely pale and with no hair
                       whatsoever...where did this creepy thing come from?  Its enormous
                       eyes dart constantly around the cavern, only occasionally resting
                       on you before bouncing away again.  The thing looks crazy and
                       depraved, of little relation to its forest-dwelling ancestors.",
               name 'ape' 'quickpaw' 'thief' 'extremely' 'pale'
                       'hairless' 'creepy' 'thing' 'enormous' 'eyes' 'crazy' 'depraved'
                       'completely' 'unnatural' 'claws' 'fangs',
               shuffler 8,
               crename "quickpaw",
               creclass Quickpaw,
               speed 90,
               weight 110,
               strength 150,
               topstrength 150,
               attackstyle1 "scratches its claws",
               attackstyle2 "snaps its fangs",
               enterstring "slink into the room",
               leavestring "ducks",
               diestring "hollers sadly and crumples to the ground",
               minworth 0,
               prey,
               AIStyle 4,
               pickup 1,
               rebirth 15,
               inlevel 3,
               life
               [;
                       Show, Give:
                               if (noun provides worth)
                               {
                                       print (The) self, " sneers at you, and snatches ", (the) noun,
                                               " right out of your hands.^";
                                       move noun to self;
                               }
                               else
                                       print (The) self, " isn't interested in ", (the) noun, ".^";
                               rtrue;
               ],
               each_turn
               [;
                       if (random(5) == 1)
                       {
                               print (The) self, " ";
                               switch (random(5))
                               {
                                       1:
                                               "looks covetously at your possessions.";
                                       2:
                                               "hoots wildly.";
                                       3:
                                               "grins at you with wild, insane eyes.";
                                       4:
                                               "sneaks around the cave.";
                                       5:
                                               "lets loose with a stream of incoherent gibberish.";
                               }
                       }
               ],
       has
               animate;

[ PrintCreName cre;                                                                     ! Print names of all creatures
       if (cre.creclass == Grubling)
       {
               switch(cre.type)
               {
                       1:      print "black";
                       2:      print "brown";
                       3:      print "scruffy";
                       4:      print "scabby";
                       5:      print "grey";
                       6:      print "jittery";
                       7:      print "scary";
                       8:      print "twitchy";
                       9:      print "mangy";
                       10:     print "piebald";
                       11:     print "sneaky";
                       12:     print "fast";
               }
       }
       if (cre.creclass == Rocker)
       {
               switch (cre.type)
               {
                       1:      print "rumbling";
                       2:      print "grinding";
                       3:      print "tumbling";
                       4:      print "groaning";
                       5:      print "creaking";
                       6:      print "cracking";
                       7:      print "stumbling";
                       8:      print "crashing";
               }
       }
       if (cre.creclass == Reptodon)
       {
               switch (cre.type)
               {
                       1:      print "writhing";
                       2:      print "twisty";
                       3:      print "rattly";
                       4:      print "hissy";
                       5:      print "swaying";
                       6:      print "striking";
                       7:      print "crawling";
                       8:      print "hungry";
               }
       }
       if (cre.creclass == CinderBug)
       {
               switch (cre.type)
               {
                       1:      print "flickering";
                       2:      print "scintillating";
                       3:      print "winking";
                       4:      print "blinking";
                       5:      print "pulsing";
                       6:      print "manic";
                       7:      print "frantic";
                       8:      print "excitable";
                       9:      print "whirling";
                       10:     print "burning";
                       11:     print "flaming";
                       12:     print "fiery";
                       13:     print "hot";
                       14:     print "darting";
                       15:     print "flashing";
               }
       }
       if (cre.creclass == Quickpaw)
       {
               switch (cre.type)
               {
                       1:      print "pale";
                       2:      print "sickly";
                       3:      print "albino";
                       4:      print "jaundiced";
                       5:      print "quiet";
                       6:      print "wild";
                       7:      print "corrupt";
                       8:      print "greedy";
               }
       }
       if (cre.creclass == Guard)
       {
               switch (cre.type)
               {
                       1:      print "Dana the";
                       2:      print "Laurie the";
                       3:      print "Nikkie the";
                       4:      print "Frida the";
                       5:      print "Andy the";
                       6:      print "Clint the";
                       7:      print "Nash the";
                       8:      print "Ryan the";
               }
       }
];

[ ParseCreName cre q;                                                           ! Help parse names of creatures
       if (cre.creclass == Grubling)
       {
               switch(cre.type)
               {
                       1:      q = 'black';
                       2:      q = 'brown';
                       3:      q = 'scruffy';
                       4:      q = 'scabby';
                       5:      q = 'grey';
                       6:      q = 'jittery';
                       7:      q = 'scary';
                       8:      q = 'twitchy';
                       9:      q = 'mangy';
                       10:     q = 'piebald';
                       11:     q = 'sneaky';
                       12:     q = 'fast';
               }
       }
       if (cre.creclass == Rocker)
       {
               switch (cre.type)
               {
                       1:      q = 'rumbling';
                       2:      q = 'grinding';
                       3:      q = 'tumbling';
                       4:      q = 'groaning';
                       5:      q = 'creaking';
                       6:      q = 'cracking';
                       7:      q = 'stumbling';
                       8:      q = 'crashing';
               }
       }
       if (cre.creclass == Reptodon)
       {
               switch (cre.type)
               {
                       1:      q = 'writhing';
                       2:      q = 'twisty';
                       3:      q = 'rattly';
                       4:      q = 'hissy';
                       5:      q = 'swaying';
                       6:      q = 'striking';
                       7:      q = 'crawling';
                       8:      q = 'hungry';
               }
       }
       if (cre.creclass == CinderBug)
       {
               switch (cre.type)
               {
                       1:      q = 'flickering';
                       2:      q = 'scintillating';
                       3:      q = 'winking';
                       4:      q = 'blinking';
                       5:      q = 'pulsing';
                       6:      q = 'manic';
                       7:      q = 'frantic';
                       8:      q = 'excitable';
                       9:      q = 'whirling';
                       10:     q = 'burning';
                       11:     q = 'flaming';
                       12:     q = 'fiery';
                       13:     q = 'hot';
                       14:     q = 'darting';
                       15:     q = 'flashing';
               }
       }
       if (cre.creclass == Quickpaw)
       {
               switch (cre.type)
               {
                       1:      q = 'pale';
                       2:      q = 'sickly';
                       3:      q = 'albino';
                       4:      q = 'jaundiced';
                       5:      q = 'quiet';
                       6:      q = 'wild';
                       7:      q = 'corrupt';
                       8:      q = 'greedy';
               }
       }
       if (cre.creclass == Guard)
       {
               switch (cre.type)
               {
                       1:      q = 'Dana';
                       2:      q = 'Laurie';
                       3:      q = 'Nikkie';
                       4:      q = 'Frida';
                       5:      q = 'Andy';
                       6:      q = 'Clint';
                       7:      q = 'Nash';
                       8:      q = 'Ryan';
               }
       }
       return q;
];

!----------------------------------------------------------------------------------------
!   ADVENTURELAND
!----------------------------------------------------------------------------------------

! Your very own custom player...for the sake of generalized code.

Object CustomPlayer
       with
               attackstyle1 "punch",
               attackstyle2 "kick",
               weight 150,
               speed 100,
               hiding 0,
               willfight 1,
               prey,
               predator,
               strength 75,
               topstrength 100,
               hunger 100,
               thirst 100;

! Hardwired locations & objects

C_ROOMS EndRoom "The last room!"
       has
               light;

Object Limbo "Press Enter To Begin"                     ! First room, for saving.
       with
               description "Press Enter To Begin",
               each_turn
               [ x;
                       for (x == 1: x < 6: x++)
                               PrintIntro(x, 0);
                       Banner();
                       PlayerTo(LOCATION1, FALSE);
                       rtrue;
               ],
       has
               light;

Object Door_iron "iron door"
       with
               d1room 0,
               d1dir 0,
               d2room 0,
               d2dir 0,
               description
               [;
                       print "This is not the place you'd expect to find a door, but
                               here it is, snugly built to block this exit.  Somebody thought it
                               was important to put the door here";
                       if (real_location == self.d1room)
                               ", which makes you suspect that
                                       going through it would be a good idea.  Maybe there's a way out of
                                       the cave?  There's a curiously-constructed keyhole in the center
                                       of the door.";
                       else
                               ".  This side of it is completely featureless.";
               ],
               name 'door' 'snug' 'sign' 'iron',
               initial
               [;
                       if (self has open)
                               "An open door is here.";
                       else
                       {
                               print "A stout iron door blocks exit #";
                               if (self in self.d1room)
                                       print self.d1dir;
                               else
                                       print self.d2dir;
                               print ".";
                       }
                       rtrue;
               ],
               found_in
               [;
                       if (real_location == self.d1room or self.d2room)
                               return TRUE;
                       else
                               return FALSE;
               ],
               before
               [;
                       Receive:
                               << Insert noun keyhole >>;
                       Unlock:
                               if (self has locked)
                                       "You need to insert each key into the keyhole, and turn all three
                                               keys, in order to unlock this door.";
                               else
                                       "The door is already unlocked!";
                       Read:
                               << Examine self >>;
               ],
               after
               [;
                       Open:
                               score = score + 400;
                               print "You've been down here for so long -- and learned to expect so
                                       little -- that you can barely believe the sight before your eyes:
                                       a deserted utility room containing a ladder with the words
                                       'Emergency Exit' on it.  This is the way out of the caverns...no
                                       doubt about it.^^
                                       Sure, there might be guards up there, or locked doors, or more
                                       puzzles for you to solve.  But having defeated the Wumpus and so
                                       many other fearsome monsters of the underworld, these are puny
                                       obstacles that you barely need think about.^^
                                       You have survived, you have escaped, and both freedom and fame
                                       await you.  Tomorrow's copy in the newspaper will read: ~A
                                       fight to the death with Morristown's most famous monster.  And
                                       a damning expose of the people responsible for it!~^^
                                       Ready to face the world, you climb the ladder.^^";
                               deadflag = 2;
                               rtrue;
               ],
               react_before
               [;
                       Go:
                               if (self has open)
                                       rfalse;
                               if (self in self.d1room)
                               {
                                       if (noun.num == self.d1dir)
                                               "The door is blocking that exit!";
                               }
                               else
                               {
                                       if (noun.num == self.d2dir)
                                               "The door is blocking that exit!";
                               }
               ],
       has
               static openable lockable locked transparent;

Object keyhole "keyhole"
       with
               description
               [;
                       print "You've never seen a keyhole quite like this.  It has three
                               ports, each capable of holding a key.";
                       if (children(self) == 0)
                               " Right now it is empty.";
                       else
                       {
                               print " It holds ";
                               if (key_bronze in self)
                               {
                                       print (a) key_bronze;
                               }
                               if (key_lead in self)
                               {
                                       if (key_bronze in self)
                                       {
                                               if (children(self) == 3)
                                                       print ", ";
                                               if (children(self) == 2)
                                                       print " and ";
                                       }
                                       print (a) key_lead;
                               }
                               if (key_iron in self)
                               {
                                       if (key_bronze in self || key_lead in self)
                                               print " and ";
                                       print (a) key_iron;
                               }
                               print ".^";
                       }
                       rtrue;
               ],
               before
               [;
                       Receive:
                               if (noun ofclass Key)
                                       rfalse;
                               else
                                       "You can't put that in the keyhole!";
               ],
               found_in
               [;
                       if (real_location == door_iron.d1room)
                               rtrue;
               ],
               name 'keyhole' 'hole' 'first' 'second' 'third' 'port' 'ports',
       has
               scenery static open container;

Key key_bronze "blue key"
       with
               name 'blue';

Key key_lead "lead key"
       with
               name 'lead';

Key key_iron "red key"
       with
               name 'red';

CaveObject Jewelpouch "gem pouch"
       with
               description "Using patented 'Gravity Truss' technology (the same material
                       which made varicose veins a thing of the past) this gem pouch can store
                       precious stones in a convenient, secure, and surprisingly light manner.",
               name 'gem' 'pouch' 'bag' 'sac' 'sack',
               worth 60,
               weight 1,
               monworth 50,
               numin 0,                                                                                ! Number of jewels inside
               before
               [;
                       Receive:
                               if (noun ofclass Jewel)
                                       rfalse;
                               "You need one of those '", (name) noun, " pouches,' not a
                                       'gem pouch.'";
                       Empty:
                               "This pouch is one of the more secure models...once you've put a
                                       gem inside, you'll need to contact an authorized gem de-poucher
                                       to get it out again.";
                       Search:
                               "You learned at a very young age not to stick your hands into a
                                       gravity truss device.";
               ],
               invent
               [;
                       print (a) self;
                       if (self has open)
                               print " (which is open)";
                       rtrue;
               ],
               after
               [;
                       Receive:
                               move noun to jewelbag;
                               self.monworth = self.monworth + noun.monworth;
                               self.numin++;
                               self.weight = 1 + (self.numin / 3);
               ],
       has
               container openable;

CaveObject Gasmask "gas mask"
       with
               description "It looks like it's been through a lot, but this big rubber gas
                       mask might still be useful.  If you run into any gas, that is.",
               name 'big' 'rubber' 'gas' 'mask',
               worth 70,
               weight 2,
               monworth 25,
               after
               [;
                       Wear:
                               "You slip the gas mask over your head.";
                       Remove:
                               "You remove the gas mask.  It's nice to be able to breathe something
                                       other than carbon dioxide again!";
               ],
               react_before
               [;
                       Eat, Taste, Drink, Tell, Answer, Ask, AskFor, Kiss, Sing, Smell:
                               if (self has worn)
                                       "That's impossible to do while you're wearing the gas mask.";
               ],
       has
               sink clothing;

CaveObject shoes "spiked shoes"
       with
               description "Whoever wore these was either a baseball player or a mountain
                       climber.  Playing baseball down here is an unlikely pasttime...but
                       they might help you climb steep slopes.",
               name 'spiked' 'shoes',
               worth 50,
               weight 4,
               monworth 45,
               after
               [;
                       Wear:
                               "Wow!  They're your size!";
               ],
       has
               sink pluralname clothing;

CaveObject baseball "baseball"
       with
               description "It's dirty and has a big smear of blood on it, but it's more
                       or less intact.",
               name 'dirty' 'bloody' 'smeared' 'ball' 'baseball' 'intact' 'blood',
               worth 20,
               weight 2,
               monworth 4,
       has
               sink;

CaveObject Receiver "electronic receiver"
       with
               description "This little black box will pick up signals from remote
                       sensors, providing you with updates about any living creatures
                       that might be lurking around.  This is a useful device but it
                       doesn't have much of a range, and its signal can be disrupted
                       by occasional bursts of energy from distant stars.",
               name 'electronic' 'receiver' 'little' 'black' 'box' 'useful'
                       'device',
               worth 80,
               weight 6,
               monworth 250,
               after
               [ x;
                       SwitchOn:
                               objectloop (x ofclass Sensor)
                               {
                                       x.lasttotal = 1;                                ! Power on sensor refresh
                               }
               ],
               each_turn
               [ x y room newtotal;
                       if (self has on)
                       {
                               objectloop (x ofclass Sensor)
                               {
                                       room = FindCeiling(x);
                                       if (room ofclass C_ROOMS)
                                       {
                                               newtotal = 0;
                                               objectloop (y in room)
                                               {
                                                       if (y ofclass Creature)
                                                               newtotal = newtotal + y;
                                               }
                                               if (newtotal ~= x.lasttotal)
                                               {
                                                       x.lasttotal = newtotal;
                                                       print "BEEP!  Sensor ", (string) x.snum, " detects: ";
                                                       if (CreaturesPresent(room))
                                                       {
                                                               if (real_location == room)
                                                                       print "You...";
                                                               objectloop (y in room)
                                                               {
                                                                       if (y ofclass Creature)
                                                                               print (name) y, "...";
                                                               }
                                                               print "^";
                                                       }
                                                       else
                                                               print "no living creatures nearby now.^";
                                               }
                                       }
                               }
                       }
               ],
               has
                       sink switchable;

CaveObject Mat "Transmat Mat"
       with
               description "Some clever (and rich!) explorer must have figured
                       that a Transmat Mat would be a valuable caving tool.  It's
                       a crude, effective, not altogether comfortable rubber mat
                       that acts like a cellular magnet.  Matter from
                       organisms previously dissolved by a Transmat Popper -- made
                       by the same somewhat shady organization -- are attracted
                       to this mat, and they will whiz across reasonable distances
                       in order to cluster around it, where they are properly
                       reassembled...usually in the right order.",
               name 'transmat' 'mat' 'tool' 'crude' 'effective' 'uncomfortable'
                       'rubber' 'magnet' 'cellular',
               worth 75,
               weight 15,
               monworth 650,
               before
               [;
                       Enter:
                               "That wouldn't do any good...travelling on a Transmat Mat
                               is a one-way trip, with the mat at the end.  If you're
                               lucky.";
               ],
       has
               ~sink;

CaveObject Popper "Transmat Popper"
       with
               description "This little button is a miracle of modern technology,
                       and used to be fun for the kids before the unfortunate side-
                       effects were discovered.  In layman's terms, pressing the button
                       will dissolve an organism's cells -- and some of its possessions
                       -- and send the resulting goo flying through the air.
                       If there's a Transmat Mat close by the goo will reassemble near it.",
               name 'transmat' 'popper' 'little' 'button' 'miracle' 'modern'
                       'technology',
               worth 85,
               weight 1,
               monworth 650,
               before
               [ croom room;
                       Push:
                               croom = FindCeiling(self);
                               room = FindCeiling(Mat);
                               print "The Transmat Popper makes a muffled ~zip!~ noise.^";
                               if (croom == room || room == FALSE)
                                       "You feel a funny tug at your innards, but nothing
                                       seems to have happened.";
                               print "Reality turns inside-out for a second, and the next thing
                               you know you're somewhere else...^";
                               if (SWIMMING)
                                       LeaveWater();
                               PlayerTo(room);
                               rtrue;
               ],
       has
               sink;

Object pylon "Pylon" EndRoom
       with
               name 'pylon';

Object playpen "Playpen"
       with
               name 'playpen',
       has
               container open openable enterable transparent;

CaveObject sprayer "tank sprayer"
       with
               description "This is an industrial-strength pest-control sprayer, a large
                       orange tank attached to a squeezeable nozzle.  A menacing skull has
                       been printed on the side, above the words ~organophosphate
                       insecticide.~",
               name 'industrial' 'strength' 'pest' 'control' 'sprayer' 'large' 'orange'
                       'tank' 'nozzle' 'squeezeable' 'menacing' 'skull' 'insecticide'
                       'organophosphate',
               worth 0,
               weight 35,
               monworth 40,
               before
               [ room x;
                       Squeeze:
                               room = FindCeiling(self);
                               print "White mist hisses out of the nozzle, quickly dispersing
                                       throughout the room.^";
                               give room poison;
                               objectloop (x ofclass Beetle)
                               {
                                       if (x in room)
                                       {
                                               print (The) x, " disintegrates immediately!^";
                                               move x to beetlebag;
                                       }
                               }
                               PoisonSurrounding(room);
                               rtrue;
               ],
       has
               sink;

Object firstshaft "wide shaft"
       with
               description "Looking up at it, you can't believe that you fell out
                       of this shaft.  And you REALLY can't believe that
                       you considered -- briefly -- the possibility of climbing back
                       into it again.  It's too far above your head and much too wide
                       and
                       smooth to give you any purchase.  Whatever it is, it looks like
                       a natural phenomenon.  If you weren't in such an unpleasant
                       situation you might stop to ponder how it developed.^^
                       In any case, there's no way out through the shaft.  You'll need
                       to hunt around for another way out.",
               name 'wide' 'shaft' 'smooth' 'natural' 'entrance' 'way' 'out',
               before
               [;
                       Take:
                               "Taking a hole is an interesting idea...but you wouldn't
                               know what to do with it, even if you could somehow
                               take it.";
               ],
               react_before
               [;
                       Climb:
                               if (noun == self)
                                       "There's nothing to hold on to in the shaft!";
               ],
               initial "High above your head is the shaft you fell out of.";

Skeleton SEntry "brittle skeleton"
       with
               description "This skeleton looks like he came in the same way
                       you did, but he had a much less fortunate fate: one of his
                       legs is shattered to pieces.  He's obviously been here
                       a long time.  You can safely say, having landed on it, that it's
                       the comfiest skeleton you've ever come in contact with.",
               initial "It appears that this skeleton on the ground has broken
                       your fall.",
               name 'brittle' 'broken' 'unlucky' 'shattered' 'leg' 'legs'
                       'pieces' 'old' 'comfy';

Note SEntry_note "scribbled note"
       with
               description "Before dying, it looks like the hapless fellow
                       wrote a letter.",
               name 'written' 'missive' 'scribbled' 'scribbles',
               text "~Just hours ago, Susie and I were jitterbugging in the
                       pale moonlight.  We did not watch our feet, so absorbed
                       were we by our sinful desires.  Where did that hole come
                       from?  Why haven't the constabulary erected a warning sign?^^
                       ~Now I'm down here and my leg hurts like the dickens, and
                       Susie has wandered off to find a way out.  She believes
                       that as long as she heads in an upwardly direction she will
                       arrive at the surface in a few minutes.  I know little of
                       caves so I am forced to agree with her, but in my heart
                       I am troubled.^^
                       ~Before leaving, she brought me some water she found in a
                       nearby river, claiming it fast enough to be safe from
                       infection, but I fear it was poisoned: I am not well.  After
                       escaping these caves, will I ever jitterbug again?  In daylight
                       only, I swear!^^
                       ~As my candle dies -- reserved for a romantic dinner in
                       the garden, and now my only sufficient light -- I believe I
                       hear the sounds of a strange shifting throughout the cave.  I
                       recall ancient tales of the evil Wumpus, hidden in a lair
                       beneath the city.  I wish Susie had left the walking stick,
                       so I would have something with which to defend myself!^^
                       ~My goodness!  The candle dies and I see the face of--~^",
               initial "A scrap of paper is lying next to the skeleton.";

Skeleton SSusie "crumpled skeleton"
       with
               description "The bones of this skeleton are unbroken, so it's
                       difficult to know its history.  One thing's for sure, it's
                       been down here awhile.",
               initial "There is a skeleton lying crumpled up against the
                       wall.",
               name 'unbroken' 'intact' 'old' 'lying' 'crumpled';

Note SSusie_note "scrawled note"
       with
               description "Maybe this note will give you some spelunking
                       tips?",
               name 'written' 'missive' 'scrawled' 'scrawl' 'scribbled' 'scribbles',
               text "~The old woodsman down the road always told me: 'Susie,
                       be careful of standing water.  It is a haven for mosquitos
                       and it has a deadly poison.'  How stupid of me, I did not
                       notice the odour until I had swallowed!  And my constitution
                       is poor...^^
                       ~I pray for rescue, both for me and my poor shattered lover!^^
                       ~I am sick.  Oh how I spew!  The cave grublings provide no solace,
                       but at least they do not try to eat me.^^
                       ~Gasp!  I breathe my last!^^
                       ~No, I think this is my last!  Yes it is.  GASP!~^",
               initial "A scrawled note is resting beside the skeleton.";

Skeleton SScientist "lanky skeleton"
       with
               description "Whoever this person was, they died wrapped up in a pathetic
                       fetal position.  Will somebody stumble on your remains in a few years,
                       tucked away like this?",
               initial "A skeleton is curled into a fetal ball at the edge of the cave.",
               name 'lanky' 'fetal' 'curled' 'ball';

Note SScientist_note "handwritten note"
       with
               description "Somebody has been sure to carefully record their final thoughts
                       in methodical, precise handwriting.",
               name 'hand' 'written' 'handwritten' 'carefully' 'recorded' 'final' 'thoughts'
                       'methodical' 'methodically' 'lettered',
               text "~I should have known, when Chuck and Bert started giving me those 'funny
                       looks,' that the lab management was on to me.  They knew I'd been keeping
                       notes, planning to send them to the Senator as soon as I felt it was safe.
                       They probably wondered how I could have turned traitor, why I'd try to put
                       an end
                       to our landmark
                       experiments in radiation and dimensional wrinkling of the unusual
                       creatures in this cave.  But when we started experimenting on HUMAN
                       subjects...the poor lost explorers and political exiles...that's when
                       I had to take a stand.  That tragic 'Compressor!'  We've created a monster,
                       and we dare not contemplate what we've done!^^
                       So here I am, as helpless as the others.  I've wandered away from the exit,
                       trying to find the keys that open the door, but I'm weak from years of sitting on
                       lab stools and eating fast food.  I will not survive!  It is hopeless!  I am
                       forever lost and forgotten!~^",
               initial "There is a carefully lettered note beside the skeleton.";

Skeleton SFranklin "frozen skeleton"
       with
               description "This skeleton oozes cold air the way a teabag oozes tea...its marrow
                       must have been steeped in ice for a very long time.",
               initial "A skeleton is propped up against the wall, arms crossed as though to
                       conserve heat.",
               name 'frozen' 'oozing' 'cold' 'marrow' 'cold' 'icy' 'sir' 'john' 'franklin'
                       'captain';

Note SFranklin_note "cold note"
       with
               description "Like the skeleton it was found beside, this note gives off a
                       palpable chill.",
               name 'cold' 'chilly',
               text "~In my search for the Northwest passage, I must have gotten lost, or
                       perhaps I am under the Curse Of Bouyantly Confident Adventurers: to wander
                       endlessly in search of an impossible goal.^^
                       But no!  I refuse to believe there is no route to China.  I know it exists,
                       just as well as I know that I will be the man to find it.  And when I am
                       a famous, handsomly-rewarded man, I shall send word to Lady Jane to visit me...
                       though the climate hereabouts is inhospitable.^^
                       I will continue my search in a few moments, but for the nonce I am horribly
                       tired and in need of rest.  It could not hurt to sleep a bit, could it?~^",
               initial "There is a note beside the skeleton.";

! Junk, treasure, items...

FoodBar bar1;

FoodBar bar2;

FoodBar bar3;

FoodBar bar4;

FoodBar bar5;

FoodBar bar6;

GinkoBar gbar1;

GinkoBar gbar2;

GinkoBar gbar3;

GinkoBar gbar4;

SmallRock srock1;

SmallRock srock2;

SmallRock srock3;

SmallRock srock4;

SmallRock srock5;

SmallRock srock6;

SmallRock srock7;

SmallRock srock8;

SmallRock srock9;

SmallRock srock10;

LargeRock lrock1;

LargeRock lrock2;

LargeRock lrock3;

LargeRock lrock4;

LargeRock lrock5;

LargeRock lrock6;

LargeRock lrock7;

LargeRock lrock8;

LargeRock lrock9;

LargeRock lrock10;

Jewel jewel1;

Jewel jewel2;

Jewel jewel3;

Jewel jewel4;

Jewel jewel5;

Jewel jewel6;

Jewel jewel7;

Jewel jewel8;

Jewel jewel9;

Jewel jewel10;

Jewel jewel11;

Jewel jewel12;

Jewel jewel13;

Jewel jewel14;

Jewel jewel15;

Jewel jewel16;

Jewel jewel17;

Jewel jewel18;

Jewel jewel19;

Jewel jewel20;

Jewel jewel21;

Jewel jewel22;

Jewel jewel23;

Jewel jewel24;

Jewel jewel25;

Jewel jewel26;

Jewel jewel27;

Jewel jewel28;

Jewel jewel29;

Jewel jewel30;

Sensor sensor1 "sensor 1"
       with
               snum "s1",
               name 's1';

Sensor sensor2 "sensor 2"
       with
               snum "s2",
               name 's2';

Sensor sensor3 "sensor 3"
       with
               snum "s3",
               name 's3';

Sensor sensor4 "sensor 4"
       with
               snum "s4",
               name 's4';

Sensor sensor5 "sensor 5"
       with
               snum "s5",
               name 's5';

Rope frayed_rope
       with
               specific "frayed rope",
               name 'frayed';

Rope tough_rope
       with
               specific "tough rope",
               name 'tough';

Rope long_rope
       with
               specific "long rope",
               name 'long';

Barrel barrel1
       with
               name 'barrel1',
               clevel 1;

Barrel barrel2
       with
               name 'barrel2',
               clevel 2;

Barrel barrel3
       with
               name 'barrel3',
               clevel 3;

Barrel barrel4
       with
               name 'barrel4',
               clevel 4;

Barrel barrel5
       with
               name 'barrel5',
               clevel 5;

CaveObject penny "penny"
       with
               name 'penny' 'shiny' 'coin',
               descrption "It's a shiny penny, a few years older than you are.",
               worth 3,
               weight 1,
               monworth 0,
               after
               [;
                       Drop:
                               print (string) random("Heads!^", "Tails!^");
                               rtrue;
               ],
       has
               sink;

CaveObject feather "ostrich feather"
       with
               description "You could understand finding an eagle feather down here
                       somewhere -- it's conceivable that a bird of prey could end up
                       living in the caves.  But a bright red ostrich feather?  Very
                       strange...",
               name 'feather' 'bird' 'bright' 'red' 'ostrich',
               worth 2,
               weight 1,
               monworth 0,
               after
               [;
                       Drop:
                               "It floats gracefully through the air.";
                       Smell:
                               "~Achoo!~";
               ];

CaveObject husk "dried husk"
       with
               description "It's impossible to know what sort of animal this husk came
                       from.  It's about the size of your hand and has an unpleasant texture.",
               name 'dried' 'husk' 'unpleasant',
               worth 1,
               weight 1,
               monworth 0;

CaveObject pin "safety pin"
       with
               description "This pin has been down here so long that it is completely fused
                       together by rust.",
               name 'safety' 'pin' 'rust' 'rusty',
               worth 1,
               weight 1,
               monworth 0,
       has
               sink;

CaveObject cloth "scrap of cloth"
       with
               description "This looks like it was ripped from somebody's shirt.",
               name 'scrap' 'of' 'cloth' 'shirt' 'ripped',
               worth 1,
               weight 2,
               monworth 1;

CaveObject bottlecap "bottlecap"
       with
               description "If you've seen one you've seen them all...unless you're a bottlecap
                       collector (which you aren't).",
               name 'bottlecap' 'bottle' 'cap',
               worth 1,
               weight 1,
               monworth 1,
       has
               sink;

CaveObject cardboard "flap of cardboard"
       with
               description "You're guessing that this was torn from a box long, long ago.",
               name 'flap' 'of' 'cardboard' 'box',
               worth 1,
               weight 2,
               monworth 0;

CaveObject poptab "pop tab"
       with
               description "If you get mutilated down here, enough of these pop tabs might
                       buy you a wheelchair.",
               name 'pop' 'tab' 'metal',
               worth 1,
               weight 1,
               monworth 1
       has
               sink;

CaveObject woodbead "wooden bead"
       with
               description "When the creatures in the cave attack you, they probably destroy
                       your jewelry...hence this solitary, well-worn bead.",
               name 'wood' 'wooden' 'bead' 'solitary',
               worth 1,
               weight 1,
               monworth 1;

CaveObject pearl "flawless pearl"
       with
               description "This probably came from some old lady's necklace.  Since she's not
                       around to claim it you might as well keep it...maybe you'll come across a
                       'lost & found?'",
               name 'flawless' 'pearl',
               worth 15,
               weight 1,
               monworth 75,
       has
               sink;

CaveObject heel "broken heel"
       with
               description "It can't be easy running from monsters in high heels.  This little
                       plastic wedge is all that's left of what must have been a nice pair of
                       shoes.",
               name 'broken' 'heel' 'little' 'plastic' 'wedge',
               worth 5,
               weight 2,
               monworth 2,
       has
               sink;

CaveObject pencap "pen cap"
       with
               description "Probably from a magic marker.",
               name 'pen' 'cap',
               worth 1,
               weight 1,
               monworth 0;

CaveObject button "button"
       with
               description "It looks like somebody lost the button
                       off their cardigan.  Since the button is cheap and ugly,
                       you assume the cardigan was as well, and perhaps even the fellow
                       who wore it.",
               name 'lost' 'button' 'cardigan' 'cheap' 'ugly',
               worth 2,
               weight 1,
               monworth 0,
       has
               ~sink;

CaveObject glowbar "Glow Bar"
       with
               name 'glow' 'bar' 'light' 'glowbar',
               description "While a pack of hired thugs were dragging you out of your bed,
                       you grabbed the first thing your hands came into contact with: the
                       little piece of security you keep on your nighttable in defense of bad
                       dreams.  The Glow Bar provides just enough light to illuminate spooky
                       closets and dark
                       caverns, but it doesn't last forever...it's best to turn it off when
                       you don't need it.  Fortunately, it recharges itself.",
               when_on "A glowing bar illuminates the cave.",
               when_off "A deactivated glow bar is here.",
               weight 4,
               worth 30,
               monworth 35,
               battery MAXBATTERY,
               each_turn
               [;
                       if (self has on && EXPLORE == 0)
                               self.battery--;
                       else
                       {
                               if (random(2)==1)
                               {
                                       self.battery = self.battery + 4;
                                       if (self.battery > MAXBATTERY)
                                               self.battery = MAXBATTERY;
                               }
                       }
                       if (TestScope(self) && self has on)
                       {
                               switch (self.battery)
                               {
                                       1:
                                               print "Your glow bar sputters and goes out.^";
                                               give self ~on;
                                               give self ~light;
                                       2 to 5:
                                               print "The light from your glow bar is so faded
                                                       that you can hardly tell it's on.^";
                                       6 to 16:
                                               if (random(3) == 1)
                                                       print "Your glow bar flickers for a moment.^";
                               }
                       }
               ],
               before
               [;
                       SwitchOn:
                               if (self.battery < 6)
                               {
                                       self.battery--;
                                       "The glow bar refuses to light...it needs
                                               some time to recharge.";
                               }
               ],
               after
               [;
                       SwitchOn:
                               give self light;
                       SwitchOff:
                               give self ~light;
               ],
       has
               switchable;

CaveObject Canteen "canteen"
       with
               name
                       'simple' 'metal' 'canteen' 'somewhat' 'battered' 'empty' 'full' 'half',
               short_name
               [;
                       PrintCanteen(self);
                       print " canteen";
                       rtrue;
               ],
               worth 20,
               monworth 8,
               article
               [;
                       if (self.level == 0 or 1 or 3)
                               print "an";
                       else
                               print "a";
                       rtrue;
               ],
               weight
               [;
                       return 5 + (self.level);
               ],
               when_open
               [;
                       print "There is a";
                       if (self.level == 0 or 1 or 3)
                               print "n ";
                       else
                               print " ";
                       PrintCanteen(self);
                       print " canteen here.";
               ],
               description
               [;
                       print "Thank goodness for this canteen!  If you're going to be down here for
                               a while, you'll need a portable source of water.  ";
                       print "It is ";
                       PrintCanteen(self);
                       print ".^";
               ],
               contaminated 0,
               before
               [;
                       Fill:
                               if (location hasnt river)
                                       "There's not enough water around here to fill your
                                               canteen with.";
                               if (self.level == 4)
                                       "It's already full.";
                               print "You fill your canteen with river water.^";
                               self.level = 4;
                               if (location.speed < 4)
                                       self.contaminated = 1;
                               rtrue;
                       Receive:
                               if (second ~= oriver)
                                       "You don't want to put that in your canteen!";
                               << Fill self >>;
                       Drink:
                               if (self.level == 0)
                                       "The canteen is empty!";
                               if (actor.thirst > 95)
                                       "You aren't thirsty.";
                               print "You take a drink of water from the canteen.^";
                               actor.thirst = 100;
                               self.level--;
                               if (self.contaminated)
                               {
                                       print "It was contaminated!^";
                                       DISEASE = 5 + random(5);
                               }
                               rtrue;
                       Empty:
                               if (self.level == 0)
                                       "It's already empty!";
                               print "You empty the canteen.^";
                               self.contaminated = 0;
                               self.level = 0;
                               rtrue;
                       Open:
                               print "You open the canteen and look inside.  It's ";
                               PrintCanteen(self);
                               ".";
                       Close:
                               "It's already closed.  You're obsessive-compulsive about never
                                       leaving things open.";
                       Smell:
                               if (self.level == 0)
                                       "It smells faintly metallic.";
                               if (self.contaminated)
                                       "It has a slightly rotten smell.";
                               "It smells relatively clean.";
               ],
               level 0,
       has
               container open;

CaveObject altometer "altometer"
       with
               description
               [;
                       print "By measuring the springiness and degree of 'oomf' in the
                       surrounding atoms,
                       the altometer can tell you exactly how many feet you are below
                       sea-level.  You can read the information on a little display
                       screen.  Right now it says: ", real_location.depth + 300,
                       ".^";
               ],
               name 'digital' 'altometer' 'information' 'little' 'display'
                       'screen',
               text
               [;
                       print "You are ", real_location.depth + 100,
                       " feet below sea-level.^";
               ],
               worth 50,
               weight 2,
               monworth 30,
       has
               sink;

! Weapons

Weapon spoon "baby spoon"
       with
               description "Judging by the duckling carved into the handle, you assume
                       this little tin spoon was meant for a baby...possibly one of the
                       recent missing persons?",
               name 'duck' 'duckling' 'little' 'tin' 'spoon' 'baby' 'small' 'tiny',
               attackstyle1 "poke",
               attackstyle2 "jab",
               worth 5,
               weight 1,
               monworth 1,
               strengthbonus 20;

Weapon bone_club "bone club"
       with
               description "Once the foundation of somebody's thigh, now it's just a
                       yellowed piece of bone.  Its owner probably doesn't need
                       it anymore.",
               name 'thigh' 'bone' 'club' 'thighbone' 'yellow' 'yellowed' 'piece' 'of',
               attackstyle1 "swing",
               attackstyle2 "twirl",
               weight 2,
               worth 17,
               monworth 2,
               strengthbonus 40,
       has
               ~sink;

Weapon walking_stick "walking stick"
       with
               description "A walking stick isn't much use down here in the caverns,
                       but it's a pretty thing at least.  Somebody lovingly carved and
                       polished it, and probably spent many years carrying it around
                       hiking tours of New Jersey wilderness.  That somebody is surely
                       dead by now, so they won't mind if you use it.",
               name 'sturdy' 'pine' 'walking' 'stick' 'hiking' 'companion' 'carved'
                       'polished',
               attackstyle1 "swat",
               attackstyle2 "swing",
               weight 3,
               worth 15,
               monworth 8,
               strengthbonus 80,
       has
               ~sink;

Weapon rock_spear "stone spear"
       with
               description "It's a rigid, 3-foot-long rock formation with a wicked
                       point on the end.  Leave it to nature -- in the form of hundreds
                       of years of dripping sediment -- to create such a useful weapon.
                       Probably not what she intended, but still...",
               name 'rock' 'stone' 'spear' 'rigid' 'long' 'formation' 'wicked'
                       'point' 'end' 'piece',
               attackstyle1 "thrust",
               attackstyle2 "jab",
               weight 8,
               worth 30,
               monworth 1,
               strengthbonus 160;

Weapon firepoker "firepoker"
       with
               description "This thin, metal instrument works well as both a firepoker
                       AND a weapon, thanks to the pointy end.",
               name 'thin' 'metal' 'instrument' 'firepoker' 'poker' 'point',
               attackstyle1 "poke",
               attackstyle2 "swing",
               weight 4,
               worth 40,
               monworth 8,
               strengthbonus 250;

Weapon rock_knife "rock knife"
       with
               description "You're not sure whether this is a primitive artifact or a
                       convincing fakery, but it looks like it could do some damage.  It's
                       a short rock cylinder with a tapered end, apparently chipped using
                       stone-age technology.",
               name 'primitive' 'artifact' 'short' 'rock' 'cylinder' 'tapered' 'knife'
                       'stone',
               attackstyle1 "flick",
               attackstyle2 "jab",
               worth 30,
               monworth 5,
               weight 3,
               strengthbonus 350;

Weapon cattleprod1 "shocking cattle prod"
       with
               description "Useful on all sorts of cattle...human, alien, mutant and
                       otherwise!  It gives a wicked shock to those it hits.",
               name 'cattle' 'prod' 'useful' 'wicked' 'shocking',
               attackstyle1 "zap",
               attackstyle2 "wave",
               worth 75,
               monworth 40,
               weight 8,
               strengthbonus 700;

Weapon cattleprod2 "zapping cattle prod"
       with
               description "Useful on all sorts of cattle...human, alien, mutant and
                       otherwise!  It gives a wicked shock to those it hits.",
               name 'cattle' 'prod' 'useful' 'wicked' 'zapping',
               attackstyle1 "zap",
               attackstyle2 "wave",
               worth 75,
               monworth 40,
               weight 8,
               strengthbonus 700;

Weapon icepick "pick"
       with
               description "You haven't spent a lot of time around picks in the past, but
                       you can still tell there is something strange about this one.  It
                       radiates a feeling of intense cold that permeates everything around it,
                       including you!",
               name 'pick' 'strange',
               attackstyle1 "swing",
               attackstyle2 "swipe",
               worth 0,
               monworth 5000,
               weight 20,
               strengthbonus 1400,
               each_turn
               [;
                       if (self in player && random(5) == 1)
                       {
                               print "You feel deathly cold.^";
                               ChangeStrength(player, -10);
                       }
               ];

Weapon superspike "quantum spike"
       with
               description "Einstein would have hated this weapon, but faced with the Wumpus
                       he probably would have used it.  Touted as a ~revolution in murder,~
                       it totally changed the way people stab each other.  In short, it slides
                       in like butter and uncoils all of the nearby dimensions at the same time,
                       doing a remarkable amount of damage both to the victim and to the space-time
                       continuum.  That's probably why most intellectuals prefer it.",
               name 'spike' 'quantum',
               attackstyle1 "thrust",
               attackstyle2 "poke",
               weight 1,
               worth 100,
               monworth 1000,
               strengthbonus 2000;

! Creatures

! Creatures based on a class should have only a single, descriptive adjective in their
! name...

!/Baby baby1;
!/
!/Baby baby2;
!/
!/Baby baby3;
!/
!/Baby baby4;
!/
!/Baby baby5;

Grubling grubling1;

Grubling grubling2;

Grubling grubling3;

Reptodon reptodon1;

Reptodon reptodon2;

Rocker rocker1;

Rocker rocker2;

Cinderbug cinder1;

Cinderbug cinder2;

Cinderbug cinder3;

Cinderbug cinder4;

Cinderbug cinder5;

Quickpaw quickpaw1;

Quickpaw quickpaw2;

Guard guard1;

Guard guard2;

Beetle tb_1
       with
               crename "first beetle",
               name 'first';

Beetle tb_2
       with
               crename "second beetle",
               name 'second';

Beetle tb_3
       with
               crename "third beetle",
               name 'third';

Beetle tb_4
       with
               crename "fourth beetle",
               name 'fourth';

Beetle tb_5
       with
               crename "fifth beetle",
               name 'fifth';

Beetle tb_6
       with
               crename "sixth beetle",
               name 'sixth';

Beetle tb_7
       with
               crename "seventh beetle",
               name 'seventh';

Beetle tb_8
       with
               crename "eighth beetle",
               name 'eighth';

Beetle tb_9
       with
               crename "ninth beetle",
               name 'ninth';

Beetle tb_10
       with
               crename "final beetle",
               name 'final';

Object Eggsack "eggsac",
       with
               description
               [;
                       print "This bloated sac drags along behind the Wumpus, spawning the many strange
                               creatures that roam these caves.  Now it is ";
                       switch (self.countdown)
                       {
                               0:      "hacked to pieces...permanently useless!";
                               1:      "hideously dilated, about to give birth!";
                               2:      "swollen almost to bursting.";
                               3:      "growing thick, preparing another discharge.";
                               4 to 10:
                                       "slowly filling up.";
                               11 to 999:
                                       "limp and flacid.";
                       }
               ],
               countdown 15,
               oomf 5,
               name 'bloated' 'sac' 'sack' 'egg' 'eggsack' 'eggsac' 'useless' 'dilated' 'swollen'
                       'thick' 'limp' 'flacid',
               before
               [;
                       Attack:
                               if (self.oomf == 0)
                                       "Like your mother always said, ~No use beating a dead eggsac!~
                                       It's beyond help or harm.";
                               print "You attack the eggsac, doing considerable damage.";
                               self.oomf--;
                               if (self.oomf == 0)
                               {
                                       print " It's tough, but there's only so much it can take...the sac
                                               collapses with a whoosh of air, permanently useless!";
                                       self.countdown = 0;
                               }
                               if (self.oomf == 1)
                                       print " It can't survive too much more...it's just about done for.";
                               print "^";
                               rtrue;
                       Take:
                               "It's attached to the Wumpus!";
                       Enter:
                               "A dream for some, but not for out.";
               ],
       has
               scenery;


! Unique creatures must obey the '.blank' '.blank' rule, so that corpses
! will be properly set up.

Creature Fish
       with
               description "Just a fish.",
               name '.blank' '.blank' 'fish' '.blank' '.blank',
               crename "fish",
               weight 3,
               strength 80,
               topstrength 80,
               enterstring "come swimming in",
               leavestring "swims away",
               minworth 0,
               maxworth 0,
               predator,
               AIStyle 12,
               rebirth 0,
               inlevel 0,
       has
               animate;

! "Boss" Creatures...

Creature Hurkle                         ! Apologies to Theodore Sturgeon & Bob Albrecht
       with
               description "Like many of the creatures in these caves, the Hurkle looks
                       to have mutated from a more benign species -- in this case a sort of
                       eyeless sturgeon -- with oversized teeth and four webbed feet.
                       It spends much of its time bobbing around the
                       bottoms of rivers, ponds, and swimming pools, waiting for a chance to
                       strike...and being relatively small and adept at camouflage, it's
                       easy to overlook.",
               crename "Hurkle",
               name '.blank' '.blank' 'hurkle' 'fish' 'eyeless' 'oversized' 'teeth'
                       'webbed' 'feet' 'small',
               speed 65,
               weight 15,
               strength 500,
               topstrength 500,
               attackstyle1 "snaps its oversized teeth",
               attackstyle2 "kicks",
               enterstring "come bobbing into the room",
               leavestring "bobs and weaves",
               diestring "screeches weekly and collapses, dead",
               minworth 50,
               maxworth 70,
               predator,
               hiding 1,
               AIStyle 3,
               rebirth 0,
               inlevel 0,
               article "the",
       has
               animate;

Creature Boga
       with
               description "A creature grown fat on fire, the Boga has never left this cave.
                       It is enormously obese and almost featureless, consisting mostly of scaly belly
                       and flapping mouth.  It's hard to say whether the Boga was born this way or if
                       it's just gotten lazy.  Either way it's one of the ugliest things you've
                       ever seen, and it looks like it's been ugly for for a long time.",
               crename "Boga",
               name '.blank' '.blank' 'Boga' 'fat' 'enormous' 'enormously' 'obese'
                       'featureless' 'scaly' 'scales' 'belly' 'flapping' 'mouth' 'demon'
                       'stubby' 'arm' 'gristly' 'claw' 'claws',
               speed 50,
               weight 700,
               strength 700,
               topstrength 700,
               attackstyle1 "swats its stubby arm",
               attackstyle2 "swipes its gristly claws",
               diestring "farts fire, screams, thrashes, and falls back against the wall",
               minworth 50,
               maxworth 100,
               predator,
               AIStyle 5,
               rebirth 0,
               inlevel 0,
               article "the",
               each_turn
               [;
                       if (TestScope(self) && random(5) == 1)
                       {
                               print (The) self, " ";
                               switch (random(5))
                               {
                                       1:
                                               "licks its flapping lips.";
                                       2:
                                               "scowls at you.";
                                       3:
                                               "glares down at you.";
                                       4:
                                               "belches horribly.";
                                       5:
                                               "pats its bloated belly.";
                               }
                       }
               ],
       has
               animate light;

Creature Compressor
       with
               description "The Compressor is a creature with an impossible shape: it is a rickety
                       jumble of limbs that all seem to be fighting against implosion.  Atop this are
                       human eyes, staring crazily at you.  You wonder if, through some strange and
                       forgotten alchemy, this creature was once a former explorer...like you.",
               crename "Compressor",
               name '.blank' '.blank' 'Compressor',
               speed 33,
               weight 2000,
               strength 1200,
               topstrength 1200,
               attackstyle1 "scratches its skeletal fingers",
               attackstyle2 "swipes its bony nails",
               diestring "explodes into nothingness",
               enterstring "get sucked into the room",
               leavestring "shudders",
               leavecorpse 0,
               minworth 0,
               maxworth 0,
               prey,
               AIStyle 7,
               rebirth 1,
               inlevel 3,
               article "the",
               each_turn
               [;
                       if (TestScope(self) && random(5) == 1)
                       {
                               print (The) self, " ";
                               switch (random(5))
                               {
                                       1:      "spreads its spindly arms, touching the walls of the cave.";
                                       2:      "inhales a windy scream.";
                                       3:      "scratches at its exposed chest.";
                                       4:      "throws its head back and shudders violently.";
                                       5:      "spins and twirls in the middle of the cave.";
                               }
                       }
               ],
       has
               animate;

Creature Wumpus
       with
               description "You never thought the Wumpus would look like this, no matter
                       how it was characterized by the hysterical people of Morristown.
                       A tiny, evil little head peers out at you from the end of a
                       gigantic, insectoid body...insectoid, that is, except for the plump
                       flesh and fur that covers most of it.  After years spent brooding down
                       here and drinking radioactive waste, the Wumpus has turned into what
                       all waste-drinking monsters aspire to: a grotesque, mutated and
                       frightfully strong enemy!^^
                       Dragging behind the Wumpus is a blood-engorged eggsac.  Now you know
                       where alll these hideous cave monsters come from...",
               short_name "Wumpus",
               crename "Wumpus",
               name '.blank' '.blank' 'wumpus' 'tiny' 'evil' 'little' 'head' 'gigantic'
                       'insectoid' 'plump' 'flesh' 'fur' 'grotesque' 'mutated' 'frightfully'
                       'strong' 'enemy' 'front' 'pincers' 'dripping' 'jaws' 'numberless' 'limbs'
                       'sucker' 'feet',
               speed 75,
               weight 500,
               strength 2500,
               topstrength 2500,
               attackstyle1 "lashes its front pincers",
               attackstyle2 "gnashes its dripping jaws",
               diestring "unleashes an anguished scream, then collapses back into itself",
               enterstring "lumber into the room",
               leavestring "drags itself",
               minworth 0,
               maxworth 0,
               predator,
               AIStyle 10,
               rebirth 0,
               inlevel 5,
               article "the",
               each_turn
               [;
                       if (TestScope(self) && random(5) == 1)
                       {
                               print (The) self, " ";
                               switch (random(5))
                               {
                                       1:      "rattles its numberless limbs together.";
                                       2:      "screeches horrifically.";
                                       3:      "proudly displays its famous sucker feet.";
                                       4:      "puffs itself up, almost completely filling the cave.";
                                       5:      "heaves itself up and down in a rage.";
                               }
                       }
               ],
       has
               animate;

Creature Zenman
       with
               description "You've heard rumours about the mysterious ~Zen Man,~ a Morristown
                       city official who gave up everything to seek enlightenment in the caves.
                       Well, not only are the rumours true, but the guy is still alive, though
                       he could use a good meal.",
               short_name "Zen Man",
               crename "Zen Man",
               name '.blank' '.blank' 'zen' 'man' 'mysterious' 'zenman' 'stoic',
               speed 5,
               weight 80,
               strength 500,
               topstrength 500,
               attackstyle1 "smacks you",
               attackstyle2 "batters you",
               diestring "peacefully expires",
               minworth 0,
               maxworth 0,
               prey,
               AIStyle 11,
               rebirth 0,
               inlevel 2,
               article "the",
               willhelp 0,
               life
               [;
                       WakeOther:
                               "He's not asleep, though it's hard to tell.";
                       Kiss:
                               "Not even this fazes the stoic Zen Man.";
                       Give, Show:
                               if (noun.monworth < 10)
                                       "The Zen Man gazes at ", (the) noun, " with contempt.  Since
                                               discovering that there are no absolutes in the universe
                                               except for an object's monetary worth, little trinkets
                                               like that are of
                                               little interest to him.";
                               move noun to self;
                               self.willhelp++;
                               if (self.willfight)
                               {
                                       self.willfight = 0;
                                       print "Upon seeing your gift, he immediately calms down.  ";
                               }
                               print "The Zen Man takes ", (the) noun, ".  He's willing to help
                                       you now.^";
                               rtrue;
                       Tell, Answer, Order:
                               print (The) self, " raises his eyebrows, then lowers them again.^";
                               rtrue;
                       Ask:
                               if (self.willhelp)
                               {
                                       self.willhelp = 0;
                                       switch (second)
                                       {
                                               'escape', 'exit':
                                                       "~A tiny mosquito could escape quickly, but humans must use the
                                                               back door.~";
                                               'back', 'door':
                                                       "~The door's distance from the sun is large, but it is only ",
                                                               (door_iron.d1room).depth+300, " under the earth's surface.
                                                               The keys, however, are another matter.~";
                                               'key', 'keys':
                                                       "~Keys are too important to just leave lying around.  Keys are
                                                               often entrusted to those you trust the most...or to those
                                                               least likely to give them up!~";
                                               'feet', 'underground', 'distance', 'sun', 'depth':
                                                       "~Here in the caves, all points of reference are useless.  We
                                                               orient by depth.  A tiny mosquito knows this instinctively,
                                                               but humans must use the altometer.~";
                                               'altometer':
                                                       "~A student asked her master: 'Where can I find the book of
                                                               mysteries?'  The master replied, 'The location of the book
                                                               is revealed within the book.'  One cannot know the depth
                                                               of an object, if one does not possess the depth-revealing
                                                               object itself.~";
                                               'book', 'of', 'mysteries', 'death':
                                                       "~It's just a parable, don't get hung up on it.~";
                                               'cave', 'caves', 'labyrinth', 'caverns', 'rock', 'rocks':
                                                       "~Who put the caves here?  How were they formed?  Who built
                                                               the first weapon?  How deep is a bowl of soup?~  He rubs
                                                               his stomach.  ~Soup, yum.~";
                                               'soup':
                                                       "~It is cruel to talk of soup to a man who hasn't eaten it
                                                               in years.~";
                                               'monster', 'monsters', 'creature', 'creatures':
                                                       "~Many monsters here are the periods in the book of death:
                                                               easily ignored with only run-on-sentences as the
                                                               consequences.  The Hurkle, Boga and Wumpus, however, are
                                                               the paper, spine and ink: ignore them at your peril!
                                                               Without them, there is no book, and without a book there
                                                               is no final page, no conclusion.~";
                                               'Wumpus':
                                                       "~The Wumpus is the mother, giver of life.  For those who
                                                               are into that sort of thing.  She lives deep and is
                                                               loved by many.~";
                                               'Boga':
                                                       "~The Boga is friend only to the fireflies.  You will find
                                                               him where it is warmest.~";
                                               'Hurkle':
                                                       "~The Hurkle is most elusive!  Being mostly fish, it loves
                                                               hiding in the water.  But being lazy, it hates swimming
                                                               against fast currents.  Search and ye shall find.~";
                                               default:
                                                       self.willhelp = 1;
                                                       "He gives you an enigmatic look.  You suspect he doesn't know
                                                               what you're asking him about, but that he doesn't want
                                                               to admit it.";
                                       }
                               }
                               else
                                       "He's waiting for you to give him something.  The Zen Man may be
                                               enlightened, but that doesn't mean he's cheap.";
               ],
               each_turn
               [;
                       if (TestScope(self) && random(5) == 1)
                       {
                               print (The) self, " ";
                               switch (random(5))
                               {
                                       1:      "stares passively at you.";
                                       2:      "smiles inscrutably.";
                                       3:      "quietly hums.";
                                       4:      "blinks.";
                                       5:      "cocks his head slightly.";
                               }
                       }
               ],
       has
               animate transparent;

Corpse corpse1;

Corpse corpse2;

Corpse corpse3;

Corpse corpse4;

Corpse corpse5;

Corpse corpse6;

Corpse corpse7;

Corpse corpse8;

Corpse corpse9;

Corpse corpse10;

! The Baby Actions

!/Actions A_CRY
!/      with
!/              startmsg "starts to cry",
!/              currentmsg "is crying",
!/              conditions
!/              [ cre;
!/                      return (cre.happy - cre.happy * 2) + 60 + random(10);
!/              ],
!/              noisy 1,
!/              result -5;
!/
!/Actions A_SCREAM
!/      with
!/              startmsg "starts to scream",
!/              currentmsg "is screaming",
!/              conditions
!/              [ cre;
!/                      return (cre.happy - cre.happy * 2) + 60 + random(10);
!/              ],
!/              noisy 1,
!/              result -10;
!/
!/Actions A_LAUGH
!/      with
!/              startmsg "starts laughing",
!/              currentmsg "is laughing",
!/              conditions
!/              [ cre;
!/                      return cre.happy - 40 + random(10);
!/              ],
!/              noisy 1,
!/              result 5;
!/
!/Actions A_BABBLE
!/      with
!/              startmsg "begins babbling randomly",
!/              currentmsg "is babbling happily",
!/              conditions
!/              [ cre;
!/                      return cre.happy - 40 + random(10);
!/              ],
!/              noisy 1;
!/
!/Actions A_THROW
!/      with
!/              conditions
!/              [ cre;
!/                      if (children(cre))
!/                              return random(100);
!/              ],
!/              result
!/              [ cre obj loc;
!/                      obj = child(cre);
!/                      loc = FindCeiling(cre);
!/                      if (TestScope(cre))
!/                              print (The) cre, " shrieks and throws ", (the) obj,".^";
!/                      move obj to loc;
!/                      if (loc has river)
!/                              PutInRiver(obj, loc);
!/                      cre.happy = cre.happy + 10;
!/              ];
!/
!/Actions A_THROWUP
!/      with
!/              conditions
!/              [ cre;
!/                      if (parent(cre) provides strength)
!/                              return random(80) + 20;
!/              ],
!/              result
!/              [ cre obj;
!/                      obj = parent(cre);
!/                      if (TestScope(cre))
!/                      {
!/                              print (The) cre;
!/                              if (random(2) == 1)
!/                                      print " throws up";
!/                              else
!/                                      print " pees";
!/                              print " on ";
!/                              if (obj == player)
!/                                      print "you.^";
!/                              else
!/                                      print (the) obj, ".^";
!/                      }
!/                      cre.happy = cre.happy + 10;
!/              ],
!/              change TRUE;
!/
!/Actions A_EAT
!/      with
!/              conditions
!/              [ cre;
!/                      if (children(cre))
!/                              return random(100);
!/              ],
!/              result
!/              [ cre obj;
!/                      obj = child(cre);
!/                      if (obj has edible)
!/                      {
!/                              if (TestScope(cre))
!/                                      print (The) cre, " eats ", (the) obj, ".^";
!/                              move obj to objectbag;
!/                              cre.happy = cre.happy + 10;
!/                      }
!/                      else
!/                      {
!/                              if (TestScope(cre))
!/                                      print (The) cre, " chews on ", (the) obj, ".^";
!/                              cre.happy = cre.happy - 10;
!/                      }
!/              ];
!/
!/Actions A_WANDER
!/      with
!/              conditions
!/              [ cre loc;
!/                      loc = FindCeiling(cre);
!/                      if (parent(cre) == loc || parent(cre) has container)
!/                              return random(100);
!/              ],
!/              result
!/              [ cre loc cdir;
!/                      loc = FindCeiling(cre);
!/                      if (parent(cre) has container)
!/                      {
!/                              if (parent(cre) hasnt open)
!/                              {
!/                                      if (TestScope(cre))
!/                                              print (The) cre, " struggles to escape ", (the) parent(cre), ".^";
!/                              }
!/                              else
!/                              {
!/                                      if (TestScope(cre))
!/                                      {
!/                                              print (The) cre, " wanders out of ", (the) parent(cre);
!/                                              if (cre.happy > 75)
!/                                              {
!/                                                      print ", yelling ~";
!/                                                      cre.sayhello();
!/                                                      print ", ";
!/                                                      cre.sayhello();
!/                                                      print "!~^";
!/                                              }
!/                                              else
!/                                                      print ".^";
!/                                      }
!/                                      move cre to loc;
!/                              }
!/                      }
!/                      else
!/                      {
!/                              cdir = RandDir(loc);
!/                              if (TestScope(cre) && cre.happy > 75)
!/                              {
!/                                      print (The) cre, " yells ~";
!/                                      cre.saygoodbye();
!/                                      print "!~^";
!/                              }
!/                              MoveCreature(cre, cdir);
!/                              if (TestScope(cre) && cre.happy > 75)
!/                              {
!/                                      print (The) cre, " yells ~";
!/                                      cre.sayhello();
!/                                      print "!~^";
!/                              }
!/                      }
!/              ];
!/
!/Actions A_STRUGGLE
!/      with
!/              startmsg "struggles peevishly",
!/              currentmsg "is struggling to be put down",
!/              conditions
!/              [ cre;
!/                      if (parent(cre) provides strength)
!/                              return (cre.happy * -1) + 40;
!/              ],
!/              result -5;
!/
!/Actions A_DROOL
!/      with
!/              startmsg "drools",
!/              currentmsg "is absently drooling",
!/              conditions
!/              [;
!/                      return random(20);
!/              ];
!/
!/Actions A_BURP
!/      with
!/              startmsg "burps",
!/              conditions
!/              [;
!/                      return random(20);
!/              ],
!/              result 10;
!/
!/Actions A_PICKUP
!/      with
!/              conditions
!/              [ cre loc;
!/                      loc = parent(cre);
!/                      if (ObIn(loc))
!/                              return random(100);
!/              ],
!/              result
!/              [ cre loc pick x;
!/                      loc = parent(cre);
!/                      objectloop (x in loc)
!/                      {
!/                              if (x ~= cre && x ofclass CaveObject)
!/                                      pick = x;
!/                      }
!/                      if (pick)
!/                      {
!/                              if (TestScope(cre))
!/                                      print (The) cre, " picks up ", (the) pick, ".^";
!/                              move pick to cre;
!/                      }
!/                      else
!/                      {
!/                              if (TestScope(cre))
!/                              {
!/                                      print (The) cre, " looks around and flexes ";
!/                                      if (cre has female)
!/                                              print "her";
!/                                      else
!/                                              print "his";
!/                                      print " little hands.^";
!/                              }
!/                      }
!/              ];
!/
!/Actions A_FIGHT
!/      with
!/              conditions
!/              [ cre loc sum;
!/                      loc = parent(cre);
!/                      sum = CreaturesPresent(loc);
!/                      if (sum > 1)
!/                              return 50 - random(cre.happy);
!/              ],
!/              result
!/              [ cre loc pick x;
!/                      loc = parent(cre);
!/                      objectloop (x in loc)
!/                      {
!/                              if (x ~= cre && x provides strength)
!/                              {
!/                                      if (pick == 0 || random(2) == 1)
!/                                              pick = x;
!/                              }
!/                      }
!/                      if (pick)
!/                      {
!/                              if (TestScope(cre))
!/                              {
!/                                      print (The) cre, " pinches ";
!/                                      if (pick == player)
!/                                              print "you.^";
!/                                      else
!/                                              print (the) pick, ".^";
!/                              }
!/                              cre.happy = cre.happy + 15;
!/                              if (pick provides happy)
!/                                      pick.happy = pick.happy - 30;
!/                      }
!/              ];

! The Daemons!

Object CDaemon                                                                          ! Creature AI
       with
               daemon
               [ i room cdir nomore x snatch;
                       objectloop (i ofclass Creature)                                 ! Sift through creatures
                       {
                               nomore = 0;
                               if (random(100) < i.speed && i notin creaturebag && i notin beetlebag)  ! Time to act?
                               {
                                       if (i provides prey && i.willfight && random(5) == 1)
                                               i.willfight = 0;                                ! Become passive again
                                       room = FindCeiling(i);
                                       cdir = 0;
                                       if (oooze in room)                                      ! Creatures love ooze!
                                               oooze.drinkme(i);
                                       if (i.AIStyle == 1)                                     ! Fungus eater, prey
                                       {
                                               room.fungus = room.fungus - 10;
                                               if (room.fungus < 1)
                                               {
                                                       room.fungus = 0;
                                                       MoveFloatingObjects();
                                               }
                                               if (TestScope(i))
                                                       print (The) i, " scrapes a large patch of rock
                                                               out of the wall.^";
                                               if (room.fungus < 1 || random(8) == 1)
                                               {
                                                       cdir = FungusDir(room);
                                                       if (cdir == 0 || random(5) == 1)
                                                       {
                                                               cdir = NewDir(i);
                                                               if (cdir == 0)
                                                                       cdir = RandDir(room);
                                                       }
                                                       MoveCreature(i, cdir);
                                               }
                                       }
                                       if (i.AIStyle == 2)                                     ! Footprint follower, predator
                                       {
                                               if (i notin real_location)
                                               {
                                                       cdir = FootprintsDir(room);
                                                       if (cdir)
                                                       {
                                                               if (random(5) == 1)
                                                                       print "You get the feeling you're being followed.^";
                                                       }
                                                       if (cdir == 0)
                                                       {
                                                               if (Health(i) > 25)
                                                                       cdir = PreyDir(room);
                                                               if (cdir == 0)
                                                                       cdir = NoPredDir(room);
                                                               if (cdir == 0)
                                                                       cdir = NewDir(i);
                                                               if (cdir == 0)
                                                                       cdir = RandDir(room);
                                                       }
                                                       MoveCreature(i,cdir);
                                               }
                                       }
                                       if (i.AIStyle == 3)                                     ! Pool lurker
                                       {
                                               if (i.hiding)
                                               {
                                                       if (player in room && random(3) == 1)
                                                               print "A stream of bubbles froth in the water, as though
                                                                       something were breathing in there...^";
                                                       if (Health(i) > 50)
                                                       {
                                                               if (player in room && SWIMMING)
                                                               {
                                                                       i.hiding = 0;
                                                                       print "An eyeless, amphibious creature jumps out of the
                                                                               water and takes a bite out of you!^";
                                                                       ChangeStrength(player, 0 - 25);
                                                                       give i ~concealed;
                                                               }
                                                               if (CreaturesPresent(room) && random(10) == 1)
                                                               {
                                                                       i.hiding = 0;
                                                                       give i ~concealed;
                                                                       if (player in room)
                                                                               print "A strange, four-legged fish jumps out of the water
                                                                                       and starts scuttling around the cave!^";
                                                                       Combat(i, PickPrey(i, room));
                                                               }
                                                       }
                                               }
                                               else
                                               {
                                                       if (Health(i) < 80)
                                                       {
                                                               if (IsQuietPool(room) == 0)
                                                               {
                                                                       cdir = QuietPoolDir(room);
                                                                       if (cdir == 0)
                                                                               cdir = RandDir(room);
                                                               }
                                                               else
                                                               {
                                                                       if (player in room)
                                                                               print "The Hurkle plunges deep into the
                                                                                       water and hides itself.^";
                                                                       i.hiding = 1;
                                                                       give i concealed;
                                                               }
                                                       }
                                                       else
                                                       {
                                                               if (CreaturesPresent(room) > 1)
                                                               {
                                                                       Combat(i, PickPrey(i, room));
                                                               }
                                                               else
                                                               {
                                                                       cdir = PreyDir(room);
                                                                       if (cdir == 0)
                                                                               cdir = QuietPoolDir(room);
                                                                       if (cdir == 0)
                                                                               cdir = RandDir(room);
                                                               }
                                                       }

                                               }
                                               if (cdir > 0)
                                               {
                                                       MoveCreature(i, cdir);
                                               }
                                       }
                                       if (i.AIStyle == 4)                                                     ! Thief, prey
                                       {
                                               if (Health(i) < 75)             ! Wounded
                                               {
                                                       cdir = NoPredDir(room);
                                                       if (cdir == 0)
                                                               cdir = RandDir(room);
                                               }
                                               else                                    ! Healthy
                                               {
                                                       if (WeightOf(i) > i.weight + i.weight / 2)
                                                       {
                                                               while (child(i))
                                                               {
                                                                       x = child(i);
                                                                       move x to room;
                                                                       if (TestScope(i))
                                                                               print (The) i, " drops ", (a) x, ".^";
                                                                       if (room has river)
                                                                               PutInRiver(x, room);
                                                               }
                                                       }
                                                       else
                                                               cdir = ValObDir(room, i);
                                                       if (cdir == 0)
                                                               cdir = NewDir(i);               ! NewDir requires i!
                                                       if (cdir == 0)
                                                               cdir = RandDir(room);
                                                       if (WeightOf(i) <= i.weight * 2)
                                                       {
                                                               snatch = 0;
                                                               objectloop (x in room)          ! Something to steal?
                                                               {
                                                                       if (x provides worth && x.worth > 0
                                                                               && x.hoarded ~= i)
                                                                       {
                                                                               snatch = x;
                                                                       }
                                                               }
                                                               if (snatch)
                                                               {
                                                                       if (snatch provides tiedto && snatch.tiedto > 0)
                                                                       {
                                                                               if (random(100) > 20)
                                                                               {
                                                                                       if (testscope(i))
                                                                                               print "The ", (name) i, " tries to untie
                                                                                                       the rope.^";
                                                                                       else
                                                                                       {
                                                                                               if (player has snatch)
                                                                                                       print "Something is tugging on ",
                                                                                                               (the) snatch, ".^";
                                                                                       }
                                                                               }
                                                                               else
                                                                               {
                                                                                       if (testscope(i))
                                                                                               print "The ", (name) i, " unties the rope
                                                                                                       and coils it up.^";
                                                                                       else
                                                                                       {
                                                                                               if (player has snatch)
                                                                                                       print (The) snatch, " is suddenly
                                                                                                               jerked out of your hands!  It
                                                                                                               disappears up through the exit
                                                                                                               it was hanging from.^";
                                                                                       }
                                                                                       snatch.tiedto = 0;
                                                                               }
                                                                       }
                                                                       else
                                                                       {
                                                                               move snatch to i;
                                                                               snatch.hoarded = i;
                                                                               if (testscope(i))
                                                                                       print "The ", (name) i, " picks up ",
                                                                                               (the) snatch,".^";
                                                                               cdir = 0;
                                                                       }
                                                               }
                                                       }
                                               }
                                               if (cdir > 0)
                                               {
                                                       MoveCreature(i, cdir);
                                               }
                                       }
                                       if (i.AIStyle == 5)                                     ! Boga
                                       {
                                               snatch = 0;
                                               objectloop (x in creaturebag)           ! Any Cinderbugs available?
                                               {
                                                       if (x ofclass Cinderbug)
                                                               snatch = x;
                                               }
                                               if (snatch)                                                     ! Bogapuke
                                               {
                                                       if (TestScope(i))
                                                               print (The) i, " belches up ", (a) snatch, "!^";
                                                       move snatch to room;
                                                       snatch.strength = 5;
                                               }
                                       }
                                       if (i.AIStyle == 6)                                     ! Cinderbugs
                                       {
                                               snatch = 0;
                                               changestrength(i, (room.heat / 25) - 8);
                                               if (room has river)
                                                       changestrength (i, -4);
                                               objectloop (x in room)                          ! Any creatures in room?
                                               {
                                                       if (x has animate)
                                                       {
                                                               if (x ofclass Cinderbug || x == Boga)
                                                               {
                                                                       x = x;
                                                               }
                                                               else                                            ! Divebomb!
                                                               {
                                                                       snatch = x;
                                                               }
                                                       }
                                               }
                                               if (snatch)
                                               {
                                                       if (TestScope(i))
                                                       {
                                                               print (The) i, " darts at ";
                                                               if (snatch == player)
                                                                       print "you";
                                                               else
                                                                       print (the) snatch;
                                                               print " and bursts into a shower of sparks!^";
                                                       }
                                                       ChangeStrength(snatch, i.strength * -1);
                                                       ChangeStrength(i, -500);
                                               }
                                               else
                                               {
                                                       if (cdir == WindExitFrom(room) or 0)
                                                       {
                                                               cdir = WindExitTo(room);
                                                               if (cdir == 0 || random(3) == 1)
                                                               {
                                                                       cdir = RandDir(room);
                                                               }
                                                       }
                                               }
                                               if (cdir > 0 && i notin creaturebag)
                                                       MoveCreature(i, cdir);
                                       }
                                       if (i.AIStyle == 7)                                                     ! Compressor
                                       {
                                               if (Health(i) < 25)             ! Teleport
                                               {
                                                       if (TestScope(i))
                                                               print (The) i, " contracts into a tiny particle and goes
                                                                       whizzing away!^";
                                                       move i to RandRoom(5);
                                                       i.strength = i.topstrength;
                                                       if (TestScope(i))
                                                               print (The) i, " suddenly materializes beside you!^";
                                               }
                                               if (Health(i) < 50 && Health(i) > 24)           ! Just run.
                                               {
                                                       cdir = NoPredDir(room);
                                                       i.strength = i.strength + 50;
                                                       if (cdir == 0)
                                                               cdir = RandDir(room);
                                               }
                                               if (Health(i) > 49)                                     ! Healthy
                                               {
                                                       cdir = ValObDir(room, 1000);            ! No jewels!
                                                       if (children(jewelbag) == 0 || cdir == 0)
                                                       {
                                                               cdir = NewDir(i);                       ! NewDir requires i!
                                                               if (cdir == 0)
                                                                       cdir = RandDir(room);
                                                       }
                                                       if (children(jewelbag) > 0)
                                                       {
                                                               snatch = 0;
                                                               objectloop (x in room)
                                                               {
                                                                       if (x provides worth)
                                                                       {
                                                                               if (x ofclass Jewel)
                                                                                       x = x;
                                                                               else
                                                                                       snatch = x;
                                                                       }
                                                               }
                                                               if (snatch)                                     ! Prepare for alchemy!
                                                               {
                                                                       nomore = 0;
                                                                       while (ObjNotJewel(room))
                                                                       {
                                                                               nomore = 0;
                                                                               objectloop (x in room)
                                                                               {
                                                                                       if (x provides worth)
                                                                                       {
                                                                                               if (x ofclass jewel)
                                                                                                       x = x;
                                                                                               else
                                                                                                       nomore = x;
                                                                                       }
                                                                               }
                                                                               if (TestScope(i))
                                                                                       print (The) i, " picks up ",
                                                                                               (the) nomore, ".^";
                                                                               move nomore to i;
                                                                       }
                                                                       while (JewelInRoom(room))       ! Add jewels to mix!
                                                                       {
                                                                               objectloop (x in room)
                                                                               {
                                                                                       if (x ofclass Jewel)
                                                                                               nomore = x;
                                                                               }
                                                                               if (TestScope(i))
                                                                                       print (The) i, " picks up ", (the) nomore, ".^";
                                                                               move nomore to i;
                                                                       }
                                                                       Alchemy(i);
                                                                       cdir = 0;
                                                               }
                                                       }
                                               }
                                               if (cdir > 0)
                                               {
                                                       MoveCreature(i, cdir);
                                               }
                                       }
!/                                      if (i.AIStyle == 8)                                                     ! Baby
!/                                      {
!/                                              i.last = i.desire;
!/                                              i.desirenum = 0;
!/                                              i.happy = i.happy + i.change;
!/                                              if (i.happy > 100)
!/                                                      i.happy = 100;
!/                                              if (i.happy < 1)
!/                                                      i.happy = 1;
!/                                              objectloop (x ofclass Actions)                  ! Find biggest desire
!/                                              {
!/!                                                     if (TestScope(i))
!/!                                                             print "Testing action #", x, ": ";
!/                                                      snatch = x.conditions(i);
!/                                                      if (x == i.last)
!/                                                              snatch = snatch / 2;
!/!                                                     if (TestScope(i))
!/!                                                             print snatch;
!/                                                      if (snatch > i.desirenum)
!/                                                      {
!/                                                              i.desirenum = snatch;
!/                                                              i.desire = x;
!/!                                                             if (TestScope(i))
!/!                                                                     print " (chosen)";
!/                                                      }
!/!                                                     if (TestScope(i))
!/!                                                             print ".^";
!/                                              }
!/                                              snatch = i.desire;
!/                                              if (TestScope(i) && metaclass(snatch.startmsg) == string)
!/                                                      print (The) i, " ", (string) snatch.startmsg, ".^";
!/                                              if (metaclass(snatch.result) == routine)
!/                                                      snatch.result(i);
!/                                              else
!/                                                      i.happy = i.happy + snatch.result;
!/                                              if (snatch.change)
!/                                                      i.change = i.change * -1;
!/                                      }
                                       if (i.AIStyle == 9)                                                     ! Beetle
                                       {
                                               snatch = 0;
                                               if (room has poison)
                                               {
                                                       if (TestScope(i))
                                                               print (The) i, " disintegrates immediately!^";
                                                       move i to beetlebag;
                                                       rtrue;
                                               }
                                               if (children(beetlebag) < 8)                    ! Breed first.
                                               {
                                                       objectloop (x in room)                                          ! Explode?
                                                       {
                                                               if (x provides prey)
                                                               {
                                                                       if (x ofclass Beetle)
                                                                               x = x;
                                                                       else
                                                                               snatch = 1;
                                                               }
                                                       }
                                               }
                                               if (snatch)                                                                     ! Explode!
                                               {
                                                       if (TestScope(i))
                                                       {
                                                               print (The) i, " explodes, spraying guts and exoskeleton
                                                                       all over the room!^";
                                                       }
                                                       else
                                                       {
                                                               if (WhatLevel(room) == WhatLevel(real_location))
                                                                       print "You hear an explosion somewhere in the cave.^";
                                                       }
                                                       room.bloody = room.bloody + 10;
                                                       move i to beetlebag;
                                                       objectloop (x in room)                                  ! Do damage
                                                       {
                                                               if (x provides strength)
                                                               {
                                                                       if (TestScope(x))
                                                                       {
                                                                               if (x == player)
                                                                                       print "You are ";
                                                                               else
                                                                                       print (The) x, " is ";
                                                                               print "damaged by the explosion!^";
                                                                       }
                                                                       if (x.strength < 101)
                                                                               ChangeStrength (x, x.strength - (x.strength * 2) + 10);
                                                                       else
                                                                               ChangeStrength (x, (100 - 200));
                                                                       room.bloody = room.bloody + 10;
                                                               }
                                                       }
                                               }
                                               else
                                               {
                                                       cdir = 0;
                                                       snatch = 0;
                                                       objectloop (x in room)                  ! Other beetles in room?
                                                       {
                                                               if (x ofclass Beetle && x ~= i)
                                                                       snatch = 1;
                                                       }
                                                       if (snatch)                                                     ! Spread!
                                                               cdir = BeetleEmpty(room);
                                                       if (cdir == 0)                                          ! Breed!
                                                       {
                                                               if (room has poison)
                                                               {
                                                                       if (TestScope(i))
                                                                               print (The) i, " gags and coughs, obviously very
                                                                                       sick.^";
                                                               }
                                                               else
                                                               {
                                                                       if (children(beetlebag))
                                                                       {
                                                                               snatch = 0;
                                                                               objectloop (x in room)
                                                                               {
                                                                                       if (x ofclass Beetle)
                                                                                               snatch++;
                                                                               }
                                                                               if (snatch == 1)
                                                                               {
                                                                                       x = child(beetlebag);
                                                                                       move x to room;
                                                                                       if (TestScope(i))
                                                                                       {
                                                                                               print (The) i, " squirts ";
                                                                                               print (a) x, " out of its abdomen!^";
                                                                                       }
                                                                               }
                                                                       }
                                                               }
                                                       }
                                               }
                                               if (cdir)
                                                       MoveCreature(i, cdir);
                                       }
                                       if (i.AIStyle == 10)                                                    ! Wumpus
                                       {
                                               ! Must write
                                       }
                                       if (i.AIStyle == 11)                                                    ! Zen Man
                                       {
                                               ! Must write
                                       }
                                       if (i.AIStyle == 12)                                                    ! Fish
                                       {
                                               if (player in room)
                                               {
                                                       if (Health(i) < 50)
                                                       {
                                                               cdir = WaterRoom(room, 1);
                                                       }
                                               }
                                               if (player notin room)
                                               {
                                                       if (Health(i) > 49)
                                                       {
                                                               cdir = WaterRoom(room, 2);
                                                       }
                                               }
                                               if (cdir == 0 && random(20) == 1)
                                               {
                                                       cdir = WaterRoom(room, 0);
                                               }
                                               if (random(20) == 1)
                                               {
                                                       if (TestScope(i))
                                                               print (The) i, " swims away to an underwater area that
                                                                       you can't reach.^";
                                                       move Fish to creaturebag;
                                               }
                                               else
                                               {
                                                       if (cdir)
                                                               MoveCreature(i, cdir);
                                               }
                                       }
                                       if (i.AIStyle == 13)                                                    ! Guard
                                       {
                                               if (FindCeiling(player) ~= room)
                                               {
                                                       if (i.goingup)
                                                       {
                                                               if ((LOCATION1.conn / 2) < (room.conn))
                                                                       i.goingup = 0;
                                                               else
                                                               {
                                                                       cdir = NextUpDown(room, 1);
                                                                       if (cdir == 0)
                                                                       {
                                                                               i.goingup = 0;
                                                                       }
                                                               }
                                                       }
                                                       else
                                                       {
                                                               if (room.conn == 2)
                                                               {
                                                                       if (random(4) == 1)
                                                                               i.goingup = 1;
                                                               }
                                                               else
                                                                       cdir = NextUpDown(room, 0);
                                                       }
                                               }
                                               if (cdir)
                                                       MoveCreature(i, cdir);
                                       }
                               }
                       }
               ];

Object DDaemon                                                          ! Dungeon features control
       with
               daemon
               [ i j room picked x cdir croom totheat numheat totmoist nummoist temp;
                       for (j = 1: j <= 3: j++)
                       {
                               room = RandRoom(random(5));
                               totheat = room.heat * 2;
                               numheat = 2;
                               totmoist = room.moist * 2;
                               nummoist = 2;
                               if (room.fungus < room.moist && room hasnt frozen)      ! Fungus grows back
                               {
                                       room.fungus = room.fungus * 2;
                                       if (room.fungus > room.moist)
                                               room.fungus = room.moist;
                               }
                               if (room == FREEZER || room == FURNACE)
                               {
                                       room = room;
                                       ! Do nothing to these rooms
                               }
                               else
                               {
                                       if (FindCeiling(icepick) == room)
                                               totheat = totheat - 40;
                                       objectloop(i ofclass CompassDirection)          ! Update room's heat & moist
                                       {
                                               temp = i.door_dir;

                                               if(i provides dung && room.temp ~= 0)
                                               {
                                                       croom = room.temp;
                                                       totheat = totheat + croom.heat;
                                                       numheat++;
                                                       totmoist = totmoist + croom.moist;
                                                       nummoist++;
                                                       if (room has frozen)
                                                       {
                                                               if (croom.heat < 1)
                                                               {
                                                                       give croom frozen;
                                                                       if (FindCeiling(player) == croom)
                                                                               print "Ice crystals are forming on the walls around
                                                                                       you!^";
                                                                       croom.fungus = 0;
                                                                       MoveFloatingObjects();
!                                                                       print "*** A ROOM IS NOW FROZEN ***^";
                                                               }
                                                       }
                                               }
                                       }
                               }
!                       if (FindCeiling(player) == room)                        ! Tell player about it.
!                       {
!                                       if (mentioned == 0)                     ! Just in case room is picked again.
!                                       {
!                                               if (room.moist - (totmoist / nummoist) > 0)
!                                                       print "The air in here seems to be drying out.^";
!                                               else
!                                               {
!                                                       if (room.moist - (totmoist / nummoist) < 0)
!                                                               print "The air in here seems more humid than it was a
!                                                                       second ago.^";
!                                               }
!                                               if (room.heat - (totheat / numheat) > 0)
!                                                       print "It feels a little colder in here than it did a second
!                                                               ago.^";
!                                               else
!                                               {
!                                                       if (room.heat - (totheat / numheat) < 0)
!                                                               print "This room seems to be heating up.^";
!                                               }
!                                       }
!                                       mentioned++;
!                               }

                               room.moist = totmoist / nummoist;
                               if (room.moist > 100)
                                       room.moist = 100;
                               if (room has frozen && totheat / numheat > 0 && room ~= FREEZER)
                               {
                                       give room ~frozen;
                                       if (FindCeiling(player) == room)
                                               print "The ice on the wall has melted away.^";
                                       MoveFloatingObjects();
!                                       print "*** A ROOM IS NO LONGER FROZEN ***^";
                               }
                               room.heat = totheat / numheat;
                               if (room.heat > 400)
                                       room.heat = 400;

                               if (room has poison)                            ! Poison issues
                               {
                                       if (room.fungus)
                                       {
                                               room.fungus = 0;
                                               if (FindCeiling(player) == room)
                                                       print "The fungus on the walls sizzles away when it comes
                                                               into contact with the mist.^";
                                       }
                                       if (random(100) < room.wind)
                                       {
                                               give room ~poison;
                                               cdir = WindExitTo(room);
                                               if (cdir)                                       ! Poison moves
                                               {
                                                       croom = room.(cdir.door_dir);
                                                       if (FindCeiling(player) == room)
                                                       {
                                                               print "The mist in the room disperses and drifts into
                                                                       exit ", cdir.num, ".^";
                                                               MoveFloatingObjects();
                                                       }
                                                       give croom poison;
                                                       if (FindCeiling(player) == croom)
                                                       {
                                                               print "A light mist drifts into the room from
                                                                       exit ", ExitToRoom(croom, room).num, ".^";
                                                               MoveFloatingObjects();
                                                       }
                                               }
                                               else                                            ! Poison disappears
                                               {
                                                       if (FindCeiling(player) == room)
                                                       {
                                                               print "The mist in the room gradually disperses.^";
                                                               MoveFloatingObjects();
                                                       }
                                               }
                                       }
                               }
                       }

                       objectloop (i ofclass Chute)
                       {
                               if (6 - (i.clevel) >= random(120))      ! Chute drop?
                               {
                                       picked = PickTreasure((i.clevel - 1) * 20, i.clevel * 20);
                                       if (picked == 0)                                ! Scrape the bottom o' barrel.
                                               picked = PickTreasure(1, i.clevel*20);
                                       if (picked)                                             ! Appropriate item found.
                                       {
                                               if (TestScope(i))
                                               {
                                                       print "Suddenly, ", (a) picked, " comes rattling out of the chute.^";
                                               }
                                               else
                                               {
                                                       objectloop (x in FindCeiling(player))
                                                       {
                                                               if (x ofclass Chute)
                                                                       print "A rattling noise echoes out of the chute.^";
                                                       }
                                               }
                                               room = FindCeiling(i);          ! Item arrives.
                                               move picked to room;
                                               if (room has river)
                                                       PutInRiver(picked, room);
                                       }
                               }
                       }
               ];

Object DWeightMonitor                                           ! Adapted from DM4 ex.43
       with
               activate
               [;
                       StartDaemon(self);
               ],
               daemon
               [ burden item heaviest_weight heaviest_item;
                       burden = WeighPercent(player);
                       if (burden > 100)
                       {
                               heaviest_weight = -1;
                               objectloop(item in player)
                               if (WeightOf(item) > heaviest_weight)
                               {
                                       heaviest_weight = WeightOf(item);
                                       heaviest_item = item;
                               }
                               if (heaviest_item == nothing)
                                       return;
                               print "^You don't have the strength to
                                       carry ", (the) heaviest_item, "!^";
                               <Drop heaviest_item>;
                               if (heaviest_item in player)
                               {
                                       deadflag = true;
                                       "^Unprepared for this, you collapse.";
                               }
                       }
                       if (burden > 85 && random(5) == 1)
                               print "It's difficult carrying all of your stuff around!^";
];

! Movable scenery

Object obarrelhole "small hole"
       with
               name 'hole' 'small' 'big',
               description "Somebody should have been more careful with the barrel... the
                       hole in the bottom is small, but big enough to be a problem.",
               before
               [;
                       Take:
                               "Impossible!";
                       Enter:
                               "Maybe if you were an ant...";
                       Receive:
                               "The hole is too small.";
               ],
       has
               scenery;

Object oooze "toxic ooze"
       with
               name 'toxic' 'ooze' 'bright' 'green' 'pooled' 'bit' 'pool' 'pooled' 'liquid',
               description "The bright green colour gives it away: this is toxic ooze, no
                       doubt about it.",
               drinkme
               [ cre oi top x level;
                       if (cre == player)
                               print "You drink the ooze.^";
                       else
                       {
                               if (TestScope(self))
                                       print (The) cre, " drinks the green, toxic ooze.^";
                       }
                       level = WhatLevel(FindCeiling(self));
                       oi = OozeIncrement(level);
                       top = 100 + oi * 5;
                       if (cre.topstrength >= top)
                       {
                               if (cre == player)
                                       print "Sadly, it doesn't seem to have any effect on you.  Maybe
                                               there's some more powerful stuff around somewhere?^";
                       }
                       else
                       {
                               if (cre.topstrength + oi < top)
                                       RaiseStrength(cre, oi);
                               else
                                       RaiseStrength(cre, top - cre.topstrength);
                       }
                       objectloop (x ofclass Barrel)
                       {
                               if (x.clevel == level)
                                       x.ooze = FALSE;
                       }
                       remove self;
                       if (cre provides thirst)
                               cre.thirst = 100;
               ],
               article "some",
               before
               [;
                       Take:
                               "It oozes around your fingers";
                       Drink:
                               self.drinkme(player);
                               rtrue;
                       Smell:
                               "It has a tantalizing, plasticine-and-earth odour.";
               ];

Object ofungus "fungus"
       with
               name 'glow' 'fungus',
               description
                       "The fungus appears to be the cave's main source of light; it glows
                       gently.  You don't know what sort of nutrients it requires but it
                       does seem to grow only in moist locations.",
               found_in
               [;
                       return (location provides fungus && location.fungus > 0);
               ],
               before
               [;
                       Take:
                               "The fungus is too slimy for you to be able to carry it.";
                       Eat:
                               << EatFungus self >>;
                       EatFungus:
                               if (actor.hunger > 99)
                                       "You aren't hungry.";
                               real_location.fungus = real_location.fungus - 20;
                               if (real_location.fungus < 1)
                               {
                                       print "You eat the last remnants of fungus off the walls.^";
                                       MoveFloatingObjects();
                               }
                               else
                                       print "You eat some fungus off of the walls.^";
                               EatFood(actor, 50);
                               rtrue;
               ],
       has
               light scenery edible proper;

Object oice "ice"
       with
               description "It's so cold in here that the walls are draped with sheets
                       of transparent ice.",
               name 'sheet' 'sheets' 'transparent' 'ice',
               before
               [;
                       Take:
                               "It would only end up melting.";
                       Eat:
                               "Low in fat, but not very nutritious!";
               ],
               found_in
               [;
                       return (real_location == FREEZER || real_location has frozen);
               ],
               each_turn
               [;
                       if (random(3) == 1)
                       {
                               print "You feel like all of your body warmth is being sucked out
                                       of you!^";
                               ChangeStrength(player, -10);
                       }
               ],
       has
               scenery edible proper;

Object oriver "river"
       with
               name 'river' 'water' 'stream' 'pond' 'swamp' 'stagnant' 'pool'
                       'motionless' 'sluggish' 'oozing' 'stretching' 'slow' 'moving'
                       'flowing' 'fast' 'flowing' 'rushing' 'gush' 'gushing' 'lake'
                       'bursting' 'cascading' 'placid',
               describe
               [;
                       DescribeRiver(location);
                       rtrue;
               ],
               react_before
               [;
                       Drop:
                               if (SWIMMING || real_location.size < FILLSROOM)
                                       << Insert noun self >>;
               ],
               before
               [ something nothing;
                       Take:
                               "That's not something you can easily carry around.";
                       Search:
                               if (SWIMMING == FALSE)
                               {
                                       print"In order to really see what's in the water, you'll
                                               need to be swimming in it.^";
                                       rtrue;
                               }
                               print "You search around underwater...^";
                               something = 1;
                               nothing = 1;
                               while (something)
                               {
                                       if (Hurkle in FindCeiling(player) && Hurkle.hiding)
                                       {
                                               print "You found the Hurkle!^";
                                               Hurkle.hiding = 0;
                                               nothing = 0;
                                       }
                                       something = InRiverBag(real_location);
                                       if (something)
                                       {
                                               move something to location;
                                               print "You found ", (a) something, "!^";
                                               nothing = 0;
                                       }
                               }
                               if (nothing)
                                       print "There's nothing in the water worth worrying about.^";
                               rtrue;
                       Enter:
                               SwimSub();
                               rtrue;
                       Drink:
                               if (actor.thirst > 95)
                                       "You aren't thirsty.^";
                               print "You take a drink of water.^";
                               actor.thirst = 100;
                               if (real_location.speed < 4)
                               {
                                       print "It was contaminated!  You should know better than
                                               to drink from stagnant pools.^";
                                       DISEASE = 5 + random(5);
                               }
                               rtrue;
                       Smell:
                               if (real_location.speed < 4)
                                       "It has a slightly rotten smell to it.";
                               "It smells fresh.";
               ],
               after
               [;
                       Receive:
                               if (noun == player)
                                       rfalse;
                               PutInRIver(noun, real_location);
                               rtrue;
               ],
               each_turn
               [ x room;
                       if (SWIMMING && parent(Fish) == creaturebag && random(15) == 1)
                       {
                               room = FindCeiling(player);
                               x = SetupFish(room.speed, room.heat);
                               if (x)
                               {
                                       move Fish to room;
                                       print "Suddenly, ", (a) Fish, " swims at you from out of
                                               the depths!^";
                               }
                       }
               ],
               found_in
               [;
                       return (location has river);
               ],
       has
               container open proper;

Object riverbag "riverbag"                                      ! For things dropped in the rivers
       with
               name 'riverbag';

Object creaturebag "creaturebag"                        ! The ghosts of unborn creatures
       with
               name 'creaturebag';

Object beetlebag "beetle bag"                           ! For unused beetles
       with
               name 'beetle bag' 'beetlebag';

Object objectbag "objectbag"                            ! Objects waiting to be placed
       with
               name 'objectbag';

Object jewelbag "jewelbag"                                      ! For unused jewels
       with
               name 'jewelbag';

Object owind "wind"
       with
               name 'wind' 'warm' 'hot' 'light' 'steady' 'breeze' 'blast'
                       'blowing',
               describe
               [;
                       DescribeWind(real_location);
                       rtrue;
               ],
               before
               [;
                       Take:
                               "Your fingers swish through the air, grasping nothing.";
                       Smell:
                               "It's earthy and musty.  Not unpleasant, just...primal.";
               ],
               found_in
               [;
                       return (real_location provides wind && real_location.wind > 20);
               ]
       has
               proper;

Object fog "fog"
       with
               name 'fog' 'thick' 'light' 'moisture',
               description "The fog is probably due to the large amount of moisture in the air.",
               found_in
               [;
                       return (location provides moist && location.moist > 65 &&
                               location.size < 6 && location.wind < 35);
               ],
               after
               [;
                       Smell:
                               "The fog is moist and odourless.";
               ],
       has
               scenery;

Object ocliff "cliff"
       with
               description "Erosion from some long-ago river has created a high, rocky cliff here.
                       You might just be able to climb down it...though getting back up might be
                       difficult!",
               name 'cliff' 'eroded' 'bed' 'high' 'rocky',
               before
               [;
                       ClimbDown, Climb:
                               print "You peer over the edge of the cliff and look for the lowest exit.^";
                               << Go d_obj >>;
               ],
       has
               scenery;

Object opit "pit"
       with
               description "Either erosion or some long-ago shift in the bedrock has created
                       a deep pit in this room.  You might be able to climb out of it.",
               name 'pit' 'eroded' 'old' 'deep' 'pit' 'bedrock',
               before
               [;
                       Climb, ClimbOut, Exit:
                               print "You go to the edge of the pit and look for the highest exit.^";
                               << Go u_obj >>;
               ],
       has
               scenery;

Object owaterfall "waterfall"
       with
               description
               [ x;
                       x = FindCeiling(self).speed;
                       print "Water ";
                       if (x < 4)
                               print "trickles lazily over the rocks.";
                       else
                       {
                               if (x < 7)
                                       print "washes over the rocks.";
                               else
                                       print "gushes in a dangerous torrent, down a steep bank of rocks.";
                       }
               ],
               name 'waterfall' 'gushing' 'rushing',
               before
               [;
                       ClimbDown, Climb:
                               "Descending a waterfall in a graceful manner isn't something you learned
                                       in your journalism courses.  Best to just swim and pray!";
                       Eat:
                               "You should eat food, not water.";
                       Drink:
                               "The force of the falling water would be painful!";
               ],
       has
               scenery;

Object poisonmist "poison"
       with
               description "A thin sheen of bitter-smelling mist floats throughout the room.",
               name 'thin' 'sheen' 'bitter' 'smelling' 'smelly' 'mist' 'floating' 'poison'
                       'poisonous' 'sharp',
               found_in
               [;
                       return (location has poison);
               ],
               after
               [;
                       Smell:
                               "The mist smells sharp and bitter, like the inside of a powerful
                               roach motel.";
               ],
       has
               scenery;

Object rain "light rain"
       with
               name 'rain' 'light' 'moisture' 'heavy',
               describe
               [;
                       if (real_location.moist == 90)
                               "A steady rain falls from the unseen roof of the cavern.";
                       "A light rain falls from the obscured cavern roof.";
               ],
               description "The rain is cool and refreshing.",
               found_in
               [;
                       return (location provides moist && location.moist > 65 &&
                               location.size == 6 && location has river);
               ],
       has
               scenery;

Object oblood "blood"
       with
               name 'blood' 'gore' 'spattered' 'speckled' 'art' 'red' 'splash' 'splashed',
               description "One of the many spoils of battle: splashes of blood.  It's hard
                       to tell exactly who it belongs to.",
               found_in
               [;
                       return (location provides bloody && location.bloody > 0);
               ],
               before
               [;
                       Take:
                               "There's no way to take it...it's just sort of splashed everywhere.";
                       Smell:
                               "A rich and bloody odour, like a particularly unclean slaughterhouse.";
                       Drink:
                               << Eat self >>;
                       Eat:
                               if (actor.hunger > 95)
                                       "You aren't hungry enough, thank goodness.";
                               if (parent(self).bloody < 20)
                                       "There just isn't enough blood around to make it worthwhile.";
                               parent(self).bloody = parent(self).bloody - 19;
                               EatFood(actor, 5);
                               actor.thirst = actor.thirst + 15;
                               if (actor.thirst > 100)
                                       actor.thirst = 100;
                               "If you close your eyes you can imagine you're drinking copper-flavoured
                                       tomato juice.  But you've never had a great imagination.  In any case,
                                       the blood sure hits the spot.";
               ],
       has
               scenery;

Features ocolumns "column"
       with
               name 'stalagmite' 'stalagmites' 'stalagtite' 'stalagtites' 'dripping' 'hanging'
                       'rising' 'beautiful' 'tall' 'stone' 'drapery' 'drape' 'draping' 'like' 'sheet'
                       'sheets' 'rippled' 'rippling' 'rock' 'hanging' 'long' 'howllow' 'strand'
                       'strands' 'column' 'columns',
               before
               [;
                       Take:
                               if (rock_spear in objectbag or riverbag)
                               {
                                       move rock_spear to location;
                                       print "With a bit of effort you manage to dislodge a piece of the
                                               formation.^";
                                       << Take rock_spear >>;
                               }
                               else
                                       "It is firmly attached.";
               ],
               react_before
               [;
                       Climb:
                               if (noun == self)
                                       "It is far too slippery to climb.";
               ];

Features orubble "rubble"
       with
               name 'fine' 'sand' 'coarse' 'gravel' 'jumble' 'broken' 'rock' 'stone' 'rubble'
                       'patch' 'coral' 'pile' 'rocks',
               before
               [;
                       Take:
                               "You have no use for that.";
                       Dig:
                               "You doubt you'd find anything.";
                       Search:
                               "You poke around it for a few minutes, but you don't find anything.";
               ],
               react_before
               [;
                       Climb:
                               if (noun == self)
                                       "There's no point in climbing around on that.";
               ];

Features opits "pit"
       with
               name 'deep' 'elongated' 'cavity' 'cavities' 'small' 'shallow' 'depression'
                       'depressions' 'cleft' 'clefts' 'slight' 'tiny' 'fissure' 'fissures' 'pit'
                       'pits',
               before
               [;
                       Search:
                               "You look around for a few minutes, but you don't find anything.";
                       JumpOver:
                               "There's no reason to.";
               ],
               react_before
               [;
                       Climb:
                               if (noun == self)
                                       "You can't think of any reason to do that.";
               ];

Features oridge "ridge"
       with
               name 'ridge' 'stone' 'rock' 'diving' 'board',
               before
               [;
                       Take:
                               "It is firmly attached.";
               ],
               react_before
               [;
                       Climb:
                               if (noun == self)
                                       "There's no point in climbing it.";
               ];

Features oarc "arc"
       with
               name 'long' 'narrow' 'hall' 'stone' 'rock' 'huge' 'arc' 'apex' 'roof'
                       'smooth' 'dome',
               before
               [;
                       Go:
                               if (noun == u_obj)
                                       << Climb self >>;
               ],
               react_before
               [;
                       Climb:
                               if (noun == self)
                                       "It's far too slippery to climb.";
               ];

Features oshaft "shaft"
       with
               name 'shaft' 'cylindrical' 'high' 'wide' 'featureless',
               react_before
               [;
                       Climb:
                               if (noun == self)
                                       "You'd never get very far.";
               ];

Features odrips "drips"
       with
               name 'stagnant' 'pool' 'small' 'drop' 'drops' 'steady',
               before
               [;
                       Eat:
                               "You should eat food, not water.";
                       Drink:
                               "There isn't enough to drink.";
               ];

Chute chute2
       with
               clevel 2,
               name 'daddy';

Chute chute3
       with
               clevel 3;

Chute chute4
       with
               clevel 4;

Chute chute5
       with
               clevel 5;

! Compass Directions

CompassDirection x1_obj "first exit" compass
       with
               description
               [;
                       if (location.x1_to)
                               PrintExit(location, self);
                       else
                               print "There is no such exit.^";
                       rtrue;
               ],
               dung,
               name 'x1' 'first' 'exit' '1', door_dir x1_to, num 1;

CompassDirection x2_obj "second exit" compass
       with
               description
               [;
                       if (location.x2_to)
                               PrintExit(location, self);
                       else
                               print "There is no such exit.^";
                       rtrue;
               ],
               dung,
               name 'x2' 'second' 'exit' '2', door_dir x2_to, num 2;

CompassDirection x3_obj "third exit" compass
       with
               description
               [;
                       if (location.x3_to)
                               PrintExit(location, self);
                       else
                               print "There is no such exit.^";
                       rtrue;
               ],
               dung,
               name 'x3' 'third' 'exit' '3', door_dir x3_to, num 3;

CompassDirection x4_obj "fourth exit" compass
       with
               description
               [;
                       if (location.x4_to)
                               PrintExit(location, self);
                       else
                               print "There is no such exit.^";
                       rtrue;
               ],
               dung,
               name 'x4' 'fourth' 'exit' '4', door_dir x4_to, num 4;

CompassDirection x5_obj "fifth exit" compass
       with
               description
               [;
                       if (location.x5_to)
                               PrintExit(location, self);
                       else
                               print "There is no such exit.^";
                       rtrue;
               ],
               dung,
               name 'x5' 'fifth' 'exit' '5', door_dir x5_to, num 5;

Object OnGoing "OnGoing"                                        ! Turn-by-turn adjustment & status
       with                                                                    ! reports.
               daemon
               [ i min minpicked x;
                       objectloop (i ofclass Creature)
                       {
                               if (i notin creaturebag && i notin beetlebag)
                               {
                                       if (i.strength < i.topstrength)
                                               ChangeStrength(i, Percent(i.topstrength, 2));
                                       if (CreaturesPresent(FindCeiling(i)) > 1)
                                       {
                                               CreatureInRoom(i);
                                       }
                               }
                       }
                       if (DISEASE)
                       {
                               DISEASE--;
                               if (DISEASE == 0)
                               {
                                       print "You feel a little better now.^";
                               }
                               else
                               {
                                       ChangeStrength(player, Percent(player.topstrength, -4));
                                       if (random(3) == 1)
                                               print "You feel sick.^";
                               }
                       }
                       if (EXPLORE == 0)
                       {
                               player.hunger--;
                               player.thirst--;
                       }
                       if (player.strength < player.topstrength)
                               ChangeStrength(player, Percent(player.topstrength, 2));
                       switch (player.hunger)
                       {
                               25 to 45:
                                       if (random(4) == 1)
                                               print "You are getting hungry.^";
                               8 to 24:
                                       if (random(2) == 1)
                                               print "You are getting weak from hunger!^";
                               1 to 7:
                                       print "If you don't eat some food soon, you will die.^";
                                       ChangeStrength(player, Percent(player.topstrength, -10));
                               -50 to 0:
                                       print "You have starved to death!^";
                                       deadflag = TRUE;
                       }
                       switch (player.thirst)
                       {
                               20 to 45:
                                       if (random(4) == 1)
                                               print "You are getting thirsty.^";
                               8 to 19:
                                       if (random(2) == 1)
                                               print "You are starting to dehydrate!^";
                               1 to 7:
                                       print "You need water immediately or you will die.^";
                                       ChangeStrength(player, Percent(player.topstrength, 10));
                               -50 to 0:
                                       print "You have died of thirst!^";
                                       deadflag = TRUE;
                       }
                       if (SWIMMING)
                               SwimRoutine(real_location);
                       if (Eggsack.countdown == 1)                             ! Eggsack rebirth!
                       {
                               if (children(CreatureBag))
                               {
                                       min = 200;
                                       minpicked = 0;
                                       objectloop (x in CreatureBag)
                                       {
                                               if (x.rebirth < min)
                                               {
                                                       min = x.rebirth;
                                                       minpicked = x;
                                               }

                                       }
                                       if (min > 0 && minpicked)
                                               Resurrect(minpicked);
                                       else
                                       {
                                               if (real_location == FindCeiling(Eggsack))
                                                       print "The Wumpus' eggsack deflates with a disgusting whooshing
                                                               sound...it was only gas.  Whew!^";
                                       }
                               }
                               Eggsack.countdown = 15;
                               if (wumpus.strength < wumpus.topstrength)
                                       Eggsack.countdown = 3;
                       }
                       else
                       {
                               if (Eggsack.countdown > 1)
                                       Eggsack.countdown--;
                       }
               ];

Object ears "your ears"                 ! Glorified variable for LookRoutine
       with
               name 'your' 'ears',
               riverspeed,
               riverdistant,                   ! River needs this check due to nature of river
               isgrubling,                                     ! All others: 0 = none, 1 = distant, 2 = Close
               isreptodon,                             !                         3 = in the room.
               isquickpaw,
               isboga,
               isrocker,
               isbeetle,
               iscompressor,
               iswumpus,
               isguard,
!/              isbaby,
!/              isbabywhich,
!/              isbabyaction
               ;

!-------------------------------------------------------------------------------
! Initialise
!-------------------------------------------------------------------------------

[ Initialise loc;
       print "Would you like to restore a saved game? >";
       if (YesOrNo())
               < Restore >;
       ChangePlayer(CustomPlayer);                                     ! To allow common properties.
       lookmode = 2;
       shownum = 1;
       TEST = 0;
       notify_mode = FALSE;
       move glowbar to player;                                         ! Give player items
       StartDaemon(Ongoing);
       DWeightMonitor.activate();

       PrintIntro(1, 0);

       SetupDungeon();
       StartDaemon(CDaemon);
       StartDaemon(DDaemon);
       location = LOCATION1;                                           ! Place stuff for first room
       move SEntry_note to location;                           ! (Must be after SetupDungeon()
       move SEntry to location;                                        ! or we won't know where location
       move firstshaft to location;                            ! is)
       move canteen to location;
       move bar1 to location;
       move bar2 to location;
       move Popper to location;
       do                                                                                      ! Place misc stuff
               loc = RandRoom(1);
       until (loc ~= location);
       move Walking_Stick to loc;
       move SSusie_note to loc;
       move SSusie to loc;
       loc = RandRoom(3);
       move SScientist_note to loc;
       move SScientist to loc;
       move Receiver to loc;
       move Mat to RandRoom(3);
       move playpen to LOCATION100;
       move firepoker to zenman;
       move cattleprod1 to guard1;
       move cattleprod2 to guard2;
       move icepick to FREEZER;
       move SFranklin to FREEZER;
       move SFranklin_note to FREEZER;
       Door_iron.d1room = LOCATION100;                         ! Set up door
       Door_iron.d1dir = ExitToRoom(LOCATION100, EndRoom).num;
       Door_iron.d2room = EndRoom;
       Door_iron.d2dir = ExitToRoom(EndRoom, LOCATION100).num;
       move key_bronze to Hurkle;                                      ! Place keys
       move key_iron to Boga;
       move key_lead to Wumpus;
       SpillObjectBag();                                                       ! Place some objects in caves
       "^^^^";
];

! =========================================================================
!
!        FUNCTIONS
!
! =========================================================================

[ WeightOf obj t i;                                                             ! Return weight of obj & children
       if (obj == player)                                              ! It's alive!
               t = t;                                                          ! Do nothing
       else
       {
               if (obj provides weight)
               {
                       if (metaclass(obj.weight) == Routine)
                               t = obj.weight();
                       else
                               t = obj.weight;
               }
               else
                       t = 10;
       }
       objectloop (i in obj)
               t = t + WeightOf(i);
       return t;
];

[ WorthOf obj t i;                                                      ! Return worth of obj & children
       if (obj == player)
               t = t;
       else
       {
               if (obj provides monworth)
               {
                       if (metaclass(obj.monworth) == Routine)
                               t = obj.monworth();
                       else
                               t = obj.monworth;
               }
       }
       objectloop (i in obj)
               t = t + WorthOf(i);
       return t;
];

[ LeaveWater;                                                                   ! When player leaves water...
       SWIMMING = 0;
       if (Fish in location)
               move Fish to creaturebag;
];

[ SetupFish spee temp;                                                  ! Set up fish based on water info
       if (spee > 7 || random(4) == 1)
       {
               Fish.description = "Whenever you saw one of these creatures in the zoo, you
                       referred to them as ~Googly Piranha,~ because they have extremely large
                       and goofy eyes.  But now you notice the multiple rows of razor-sharp
                       teeth, stained with flecks of blood and tissue.  Wow, you were a really
                       naive kid!";
               Fish.crename = "googly piranha";
               Fish.&name --> 3 = 'googly';
               Fish.&name --> 4 = 'piranha';
               Fish.speed = 100;
               Fish.weight = 1;
               Fish.strength = 200;
               Fish.topstrength = 200;
               Fish.attackstyle1 = "snaps its razor-sharp teeth";
               Fish.attackstyle2 = "snaps its razor-sharp teeth";
               Fish.diestring = "flips over and dies";
               Fish.willfight = 1;
       }
       if (spee < 8 && spee > 4 || random(5) == 1)
       {
               if (temp < 100)
                       return 0;
               if (temp > 99 && temp < 251)
               {
                       Fish.description = "Other than having no eyes, this trout is pretty much
                               what you'd find floating dead in the lakes of New Jersey.";
                       Fish.crename = "blind trout";
                       Fish.&name --> 3 = 'blind';
                       Fish.&name --> 4 = 'trout';
                       Fish.speed = 50;
                       Fish.weight = 6;
                       Fish.strength = 100;
                       Fish.topstrength = 100;
                       Fish.attackstyle1 = "crunches its little teeth";
                       Fish.attackstyle2 = "crunches its little teeth";
                       Fish.diestring = "flips over and dies";
                       Fish.willfight = 0;
               }
               else
               {
                       Fish.description = "You've never seen anything like it in your life!  A
                               gorgeous -- and somewhat cocky -- fish with an enormous fan of
                               irridescent feathers trailing behind.";
                       Fish.crename = "sea peacock";
                       Fish.&name --> 3 = 'sea';
                       Fish.&name --> 4 = 'peacock';
                       Fish.speed = 25;
                       Fish.weight = 10;
                       Fish.strength = 200;
                       Fish.topstrength = 200;
                       Fish.attackstyle1 = "lashes its feathers";
                       Fish.attackstyle2 = "pecks its beak";
                       Fish.diestring = "unleashes an aquatic squawk and begins floating belly-up";
                       Fish.willfight = 0;
               }
       }
       if (spee < 5 || random(6) == 1)
       {
               if (temp < 30)
                       return 0;
               if (temp > 99 && temp < 251)
               {
                       Fish.description = "This fish is sort of like a lamprey...a long eel with
                               teeth instead of a head.  But unlike lampreys, you think you can see
                               a pair of eyes peering at you from inside its mouth.  It looks very
                               muscular, but not particularly fast.";
                       Fish.crename = "bigmouth sucker";
                       Fish.&name --> 3 = 'bigmouth';
                       Fish.&name --> 4 = 'sucker';
                       Fish.speed = 50;
                       Fish.weight = 7;
                       Fish.strength = 300;
                       Fish.topstrength = 300;
                       Fish.attackstyle1 = "swims forward with its teeth bared";
                       Fish.attackstyle2 = "beats its body";
                       Fish.diestring = "twists into a knot and dies";
                       Fish.willfight = 1;
               }
               else
               {
                       Fish.description = "The caves don't have many poisonous creatures in them,
                               but this is one of them: a jellyfish the size of a dinner plate
                               with long, articulated tentacles snapping at you.";
                       Fish.crename = "acidopod";
                       Fish.&name --> 3 = 'acidopod';
                       Fish.&name --> 4 = 'acidopod';
                       Fish.speed = 50;
                       Fish.weight = 2;
                       Fish.strength = 200;
                       Fish.topstrength = 200;
                       Fish.attackstyle1 = "snaps its tentacles";
                       Fish.attackstyle2 = "snaps its tentacles";
                       Fish.diestring = "loses all cohesion, turning into a loose sac of jelly";
                       Fish.willfight = 1;
               }
       }
       return 1;
];

[ Resurrect cre moveto;                                                 ! Resurrect provided creature
       if (cre ofclass Baby)
               DefineBaby(cre);
       if (cre.shuffler)
               Shufflername(cre);
       moveto = FindCeiling(Wumpus);
       move cre to moveto;
       if (player in moveto)
               print "With a horrible squishing sound, ", (a) cre, " comes squeezing out of the
                       eggsack!^";
];

[ EatFood cre amount;                                                   ! Provided cre eats food
       if (cre.hunger < 45)
               ChangeStrength(cre, amount / 2);
       cre.hunger = cre.hunger + amount;
       if (cre.hunger > 100)
               cre.hunger = 100;
];

[ RaiseStrength cre amount;                                             ! Raise cre's topstrength
       cre.topstrength = cre.topstrength + amount;
       ChangeStrength (cre, amount / 2);
       if (cre == player)
       {
               print "You feel stronger!  ";
               print "Using meditative powers taught to you in a weight lifting ashram, you
                       suspect you have reached ", TSPercent(player), "% of your potential
                       maximum strength.^";
       }
       DrawStatusLine();
];

[ ChangeStrength cre amount attacker;                   ! Adjust strength of cre
       if (EXPLORE && cre == player)                           ! Unusual exceptions
               rtrue;
       cre.strength = cre.strength + amount;
       if (cre.strength > cre.topstrength)
               cre.strength = cre.topstrength;

       if (cre.strength < 1)                                           ! Dead now?
       {
!/              if (cre ofclass Baby)                                   ! God looks after babies, the jerk.
!/              {
!/                      cre.strength = 1;
!/                      cre.happy = 1;
!/                      rtrue;
!/              }
               if (cre == player)
               {
                       deadflag = 1;
                       rtrue;
               }
               else
               {
                       if (TestScope(cre))
                               print "The ", (name) cre, " ", (string) cre.diestring, "!^";
                       if (attacker == player)
                       {
                               score = score + cre.topstrength / 50;
                               if (cre == Wumpus)
                                       score = score + 50;
                       }
                       CreatureDie(cre);
               }
       }

       DrawStatusLine();

       ! When do we bother printing updates about strength?

       if (cre ofclass Cinderbug)
               rtrue;                                                                  ! Not when a cinderbug.
       if (amount < 3 && amount > 0)                           ! Not during recuperation
               rtrue;
       if (TestScope(cre) == FALSE)
               rtrue;                                                                  ! (or when out of scope)...

       if (amount < 0)                                                         ! And not until it's important.
       {
               if (Health(cre) < 65)
                       PrintStrength(cre);
       }
       else
       {
               if (Health(cre) > 70)
                       PrintStrength(cre);
       }
];

[ BloodyRoom room amount;                                               ! Bloody-up room by amount
                                                                                               ! (if no amount, just by 2)
       if (room provides bloody)
       {
               if (amount == 0)
                       amount = 2;
               room.bloody = room.bloody + amount;
       }
];

[ CreatureDie cre x lowest picked;                      ! Take care of body disposal
       KILLED++;
       lowest = KILLED;

       while (child(cre))                                                      ! Drop anything carried
       {
               x = child(cre);
               if (TestScope(cre))
                       print "The ", (name) cre, " drops ", (a) x, ".^";
               move x to parent(cre);
       }

       if (cre.minworth ~= 0)                                          ! Arrange treasure drop
               TreasureDrop(cre);

       if (cre.leavecorpse)
       {
               objectloop (x ofclass Corpse)                           ! Find an available corpse
               {
                       if (x.corpseturn < lowest)
                       {
                               lowest = x.corpseturn;
                               picked = x;
                       }
               }

               move picked to parent(cre);                                     ! Set up corpse

               picked.type = cre.type;
               picked.shuffler = cre.shuffler;
               picked.creclass = cre.creclass;
               picked.corpseturn = KILLED;                                             ! Place in "queue"
               picked.body = cre.short_name;                                   ! Name it...
               picked.&name--> 3 = cre.&name--> 0;
               picked.&name--> 4 = cre.&name--> 2;
               picked.weight = cre.weight;
               picked.crename = cre.crename;
               picked.short_name = cre.short_name;
               picked.parse_name = cre.parse_name;
               if (cre provides language)                                              ! If it's a baby...shame!
               {
                       picked.language = cre.language;
                       picked.size = cre.size;
                       if (cre has female)
                               give picked female;
               }
               if (cre == Fish)
                       PutInRiver(picked, parent(cre));
       }
       if (cre ofclass Beetle)
               move cre to beetlebag;
       else
               move cre to creaturebag;                                        ! Retire & refresh creature
       if (cre == Wumpus)                                                              ! Destroy Eggsack if Wumpus dies
       {
               Eggsack.oomf = 0;
               Eggsack.countdown = 0;
       }
       cre.strength = cre.topstrength;
       cre.willfight = 0;
];

[ TreasureDrop cre picked;
                                                                               ! Arrange treasure drop
       if (cre.minworth == 0)                                          ! No treasure?
               return;

       if (cre.minworth < 0)                                           ! Fixed treasure?
       {
               if (TestScope(cre))
                       print "The ", (name) cre," was carrying ", (a) cre.maxworth, "!^";
               move cre.maxworth to parent(cre);
       }
       else                                                                            ! Random treasure.
       {
               picked = PickTreasure(cre.minworth, cre.maxworth);
               if (picked)
               {
                       if (TestScope(cre))
                               print "The ", (name) cre," was carrying ", (a) picked, ".^";
                       move picked to parent(cre);
               }
       }
];

[ PickTreasure min max x numobj curnum picknum; ! Pick random treasure based
                                                                                               ! on min & max
       if (max == 0)
               max = 100;
       numobj = NumTreasure(min, max);
       curnum = 0;

       if (numobj > 0)                                                 ! Objects available?
       {
               picknum = random(numobj);
               objectloop (x in objectbag)
               {
                       if (x.worth >= min && x.worth <= max)
                       {
                               curnum++;
                               if (curnum == picknum)
                                       return x;
                       }
               }
       }
       return 0;                                                               ! No objects fit criteria.
];

[ NumTreasure min max x numobj;                                 ! Return treasures in objectbag
                                                                                               ! between min & max.
       numobj = 0;
       if (max == 0)
               max = 100;

       objectloop (x in objectbag)
       {
               if (x.worth >= min && x.worth <= max)
                       numobj++;
       }

       return numobj;
];

[ PrintStrength cre;                                                    ! Print Strength info.

       if (cre == player)
               print "You are ";
       else
               print "The ", (name) cre, " is ";

       switch(Health(cre))
       {
               85 to 500:
                       print "in perfect form";
               75 to 84:
                       print "healthy";
               60 to 74:
                       print "slightly injured";
               45 to 59:
                       print "wounded";
               20 to 44:
                       print "badly wounded";
               0 to 19:
                       print "near death";
       }

       print ".^";
];

                               ! Combat Routines

[ AttackSub;                                                            ! Direct from verb (no weapon)
       if (noun ofclass Creature)
               Combat(player, noun);
       else
               "There's no point in attacking that.";
];

[ AttackWeaponSub;                                                      ! Weapon specified
       if (second ofclass Weapon)
               Combat (player, noun, second);
       else
       {
               print (The) second, " would not make a useful weapon!^";
               rtrue;
       }
];

[ Combat attacker defender withw ast dst aw dw atry dtry;
                                                                                               ! Combat routine, need
                                                                                               ! attacker, defender, and
                                                                                               ! "with weapon?"
!       print (name) attacker, " -vs- ", (name) defender, "!^";
       ast = attacker.strength;
       dst = defender.strength;

       if (defender.weight > 1)                                        ! Weapons useless against small things
       {
               if (withw == FALSE)                                                     ! Pick weapon if none
                       aw = PickWeapon(attacker);                              ! chosen.
               else
                       aw = withw;
       }

       dw = PickWeapon(defender);

       if (aw)                                                                         ! Add bonuses (weapons)
               ast = ast + aw.strengthbonus;
       if (dw)
               dst = dst + (dw.strengthbonus * 2);

       atry = random(ast);                                                     ! Attack and defense based on
       dtry = random(dst);                                                     ! strength.

       if (TestScope(attacker))
       {
               if (attacker == player)                                         ! Lash out...
                       print "You";
               else
                       print (The) attacker;

               if (aw)
               {
                       if (random(2) == 1)
                               print " ", (string) aw.attackstyle1;
                       else
                               print " ", (string) aw.attackstyle2;
                       if (attacker ~= player)
                               print "s";
                       print " ";
                       if (attacker == player)
                               print (the) aw;
                       else
                               print (a) aw;
               }
               else
               {
                       if (random(2) == 1)
                               print " ", (string) attacker.attackstyle1;
                       else
                               print " ", (string) attacker.attackstyle2;
               }

               if (atry > (ast - (ast / 10)))                                  ! ...really hard?
                       print " viciously";

               if (defender == player)
                       print " at you.  ";
               else
                       print " at ", (the) defender, ".  ";
       }

       if (defender provides willfight)        ! Turn prey into fighters!
               defender.willfight = 1;

       if (atry > dtry)                                                ! A hit!
       {
               if (TestScope(attacker))
               {
                       print "Ouch!^";
                       move oblood to parent(defender);
               }
               BloodyRoom(parent(defender));           ! Blood on walls.
               ChangeStrength(defender, (dtry-atry) / 2, attacker);
       }
       else                                                                    ! A miss.
       {
               if (TestScope(attacker))
               {
                       if (defender == player)
                       {
                               print "You deflect the blow";
                               if (dw)
                               {
                                       print " with your ", (name) dw;
                               }
                               print "!^";
                       }
                       else
                               print (The) defender, " dodges the attack.^";
               }
       }
       if (aw)                                                                 ! Weapon breaks!
       {
               if (random(aw.strengthbonus) < 5)
               {
                       if (TestScope(attacker))
                               print (The) aw, " shatters!^";
                       move aw to objectbag;
               }
       }
];


[ PickWeapon cre x bonus we;                                    ! Pick best weapon for cre

       objectloop (x ofclass weapon)                           ! Choose weapons
       {
               if (x in cre)
               {
                       if (x.strengthbonus > bonus)
                       {
                               we = x;
                       }
               }
       }

       return we;
];




                               ! Creature In Room routines

[ CreatureInRoom pro room pp;                           ! pro is not alone!
                                                                                       ! (if no pro, pro is player)
       if (pro == 0)
               rtrue;                                                          ! Let player handle it!
       room = FindCeiling(pro);

       ! Put any "Boss Code" before this generalized section

       if (pro.hiding)                                                                                 ! Stay hidden
               rtrue;                                                                                          ! (Let AI handle it)

       if (pro provides Prey)
       {
               if (pro.willfight)                                                                      ! Prey belligerent?
                       Combat(pro, PickPrey(pro, room));
               rtrue;
       }

       if (PlayerInRoom(room))                                                         ! ...either player...
               Combat(pro, player);
       else
       {
               pp = PickPrey(pro, room);

               ! These creatures will never attack each other!

               if (pro == Boga && pp ofclass Cinderbug)
                       rtrue;
               if (pro ofclass Cinderbug && pp == Boga)
                       rtrue;
               if (pro == Wumpus && pp ofclass Beetle)
                       rtrue;
               if (pro ofclass Beetle && pp ofclass Beetle)
                       rtrue;
               if (pro ofclass Guard || pp ofclass Guard)
                       rtrue;
               Combat(pro, pp);                                                                ! ...or prey.
       }
];

                               ! Exit routines

[ GetToExit loc thedir theroom;                                 ! Can player get to exit?
                                                                                               ! Require room & direction.
       theroom = loc.thedir;

       if (SWIMMING == 0)
       {
               if (loc has river && theroom has river)         ! Underwater tunnel
               {
                       print"That exit is partly underwater...you'll need to swim to
                               go through it.^";
                       rfalse;
               }
       }
       else
       {
               if (loc has river && theroom hasnt river)       ! Can't swim through
               {
                       print "You climb out of the water and go through the
                               exit.^";
                       LeaveWater();
                       rtrue;
               }
       }
       if (loc has river && loc.size < FILLSROOM)              ! Must swim to get there
       {
               if (RR(LASTROOM) ~= RR(theroom))
               {
                       if (SWIMMING == 0)
                       {
                               print"There is water between you and that exit...you'll need
                                       to swim to get there.^";
                               rfalse;
                       }
               }
       }
];

[ SwimThroughExit loc thedir theroom diff;              ! Can player use exit?
                                                                                               ! Require room & direction.
       theroom = loc.thedir;
       diff = loc.depth - theroom.depth;

       if (diff > 0)                                                           ! Water flow issues up...
       {
               if ((theroom.speed + loc.speed) / 2 > 7)
               {
                       if (RopeToExit(loc, thedir))
                               "You use the rope to help you fight the current.";
                       if (random(13) + (actor.strength / 100) > theroom.speed)
                       {
                               "You manage to swim against the current.";
                       }
                       else
                       {
                               print "You swim against the current, but find yourself
                                       pushed back.  Maybe if you tried again...^";
                               rfalse;
                       }
               }
       }
       if (diff < 0)                                                           ! ...and down.
       {
               if (absl(diff) > 39)
               {
                       "You are swept down the steep waterslide.";
               }
               if (absl(diff) > 9 && absl(diff) < 39)
                       "You swim along with the current.";
       }
];

[ WalkThroughExit loc thedir theroom diff;              ! Can player use exit?
                                                                                               ! Require room & direction.
       theroom = loc.thedir;
       diff = loc.depth - theroom.depth;

       if (diff > 0)                                                           ! Climb up...
       {
               if (diff > 39)
               {
                       if (shoes in player && shoes has worn)
                               "Your shoes help you climb the steep incline.";
                       if (RopeToExit(loc, thedir))
                               "You use the rope to get you up the steep incline.";
                       if (random(diff) < 7 + (player.strength / 100))
                               "You manage to scramble up the steep incline.";
                       else
                       {
                               print "You try to climb the steep incline, but you lose your
                                       balance and fall back down!^";
                               ChangeStrength(player, -7);
                               rfalse;
                       }
               }
               if (diff > 9)
               {
                       "You climb up the incline.";
               }
       }
       if (diff < 0)                                                           ! ...slide down.
       {
               if (absl(diff) > 39)
               {
                       if (RopeToExit(loc, thedir))            ! tied rope already there?
                               "You use the rope to keep you from slipping down the steep
                                       passage.";
                       if (HaveTiedRope())
                               "Your rope prevents you from slipping down the
                                       slope.";
                       if (shoes in player && shoes has worn)
                               "Your shoes help you get down the steep slope.";
                       if (random(absl(diff)) < 7 + (player.strength / 100))
                               "You manage to keep your balance as you scramble
                                       down the steep slope.";
                       else
                       {
                               print"You trip and fall, sliding all the way to the
                                       bottom of the steep slope!^";
                               ChangeStrength(player, -7);
                               rtrue;
                       }
               }
               if (absl(diff) > 9 && absl(diff) < 39)
                       "You slide nimbly down the slope.";
       }
];

[ ObjectHits obj cre;                                                           ! Obj hit cre!
       if (TestScope(cre))
               print (The) obj, " hits ", (the) cre, "!^";
       else
               print "You hear a fleshy thump!^";
       if (cre provides willfight)
               cre.willfight = TRUE;
       ChangeStrength(cre, 1 - obj.weight);
       BloodyRoom(parent(cre));
];

[ PutInRiver obj loc cre stop count temp there sweepdir;
                                                                                                       ! Put obj in river in loc
                                                                                                       ! (provide optional cre)
       if (cre)
       {
               if (TestScope(cre))
                       print (The) cre, " throws ", (a) obj, ".^";
       }

       move obj to loc;                                                                ! Make sure it's not in river

       if (obj provides tiedto && obj.tiedto > 0)
               "The rope almost slips into the river, but it's tied to something.";

       if (obj has sink)                                                               ! Gone...
       {
               if (TestScope(obj))
                       print (The) obj, " splashes into the water and disappears
                               from sight!^";
               if (obj has dissolve)                                           ! ...for good?
               {
                       if (obj.worth == 0)
                               remove obj;
                       else
                               move obj to objectbag;
                       rtrue;
               }
               obj.inroom = loc;                                                       ! Move to RiverBag for safe-
               move obj to riverbag;                                           ! keeping.
               rtrue;
       }
       if (TestScope(obj))
               print (The) obj, " splashes into the water.^";  ! It floats...
       while (stop == 0 && count < 10)
       {
               if (FindCeiling(obj).speed > 1)                                 ! ...on the current?
               {
                       sweepdir = LowestWaterExit(parent(obj));
                       if (sweepdir)
                       {
                               temp = sweepdir.door_dir;
                               there = parent(obj).temp;
                               if (temp.depth > parent(obj).depth)             ! Any downward streams?
                               {
                                       if (TestScope(obj))
                                       {
                                               print (The) obj, " floats away into exit #",
                                                       sweepdir.num,".^";
                                       }
                                       move obj to there;                                      ! Move to next room.
                                       if (TestScope(obj))
                                               print (The) obj, " comes floating into the room on the
                                                       river.^";
                               }
                               else                                                                    ! Nowhere to go.
                               {
                                       if (TestScope(obj))
                                               print (The) obj, " floats to the shore.^";
                                       stop++;
                               }
                       }
                       else
                       {
                               if (TestScope(obj))
                                       print (The) obj, " floats to the shore.^";
                               stop++;
                       }
               }
               else                                                                            ! Stagnant water.
               {
                       if (TestScope(obj))
                               print (The) obj, " slowly floats to the shore.^";
                       stop++;
               }
               count++;
       }
];

                               ! Display current room

[ RoomDisplay loc i temp;
!       loc=real_location;

       if (self hasnt visited)
       {
               i = 1;
               if (SHOWNUM == 0)                                                       ! Extra points if no room numbers!
                       i = 2;
               score = score + (whatlevel(loc) * i);
       }

       ! Describe current room

       print "You are ";
       if (Absl(SHeight(loc)) > 10)                                    ! Cliff or pit?
       {
               if (SHeight(loc) > 0)
               {
                       if (SWIMMING)
                       {
                               print "swimming at the edge of a waterfall ";
                               move owaterfall to loc;
                       }
                       else
                       {
                               print "standing on a cliff ";
                               move ocliff to loc;
                       }
               }
               else
               {
                       if (SWIMMING)
                               print "swimming in a deep pit ";
                       else
                               print "standing in a pit ";
                       move opit to loc;
               }
       }
       if (loc has visited)                                                    ! Deja vu?
               print "back ";
       print "in ";
       if (loc.region && REGIONSON)
               print "a section of ";
       if (SHOWNUM)
       {
               if (loc.region && REGIONSON)
                       print "room #", RR(loc.region), ", a";          ! Region number
               else
                       print "room #", RR(loc), ", a";                 ! Room number
       }
       else
               print "a";

       if (Absl(Shallowest(loc) - Deepest(loc)) > 150) ! Crazy shaft you never see?
               print " deep, vertical shaft";
       else
               RoomSize(loc);                                                          ! Room size
       print " with";
       RoomWall(loc);                                                                  ! Wall texture
       print ",";
       RoomColour(loc);                                                                ! Wall colour
       if (ofungus in loc)                                                             ! Fungus...?
       {
               if (loc.fungus > 80)
                       print ", fungus-choked";
               else
               {
                       if (loc.fungus > 40)
                               print ", fungus-covered";
                       else
                               print ", fungus-spotted";
               }
       }
       print " walls.  ";

       if (loc.fungus < loc.moist)
       {
               if (loc.fungus)
                       print "Some of the fungus has been scraped off the wall, but it is slowly
                               growing back.  ";
               else
                       print "The walls look like they've been gouged by something.  ";
       }

       if (loc.size == 6)                                                              ! Roof height?
               print "The roof of the chamber is too high for you to see.  ";

       if (loc.bloody)
       {
               switch (loc.bloody)
               {
                       0 to 10:
                               print "There are flecks of blood speckling the walls and
                                       floor.  ";
                       11 to 25:
                               print "Small splashes of blood decorate the room.  ";
                       26 to 60:
                               print "The remains of a battle are clear in this room:
                                       spatters of blood turn the walls into pieces of
                                       expressionistic artwork.  ";
                       61 to 10000:
                               print "The walls and floor of the chamber are coated with
                                       a thick sheen of gore.  ";
               }
       }

       if (loc.regiontype > 1)                                         ! Is region special?
       {
               print " ";
               PrintRegionType(loc.regiontype);
               print " ";
       }

       if (loc has frozen)
               print "The walls here are covered with a thin sheen of ice.  ";

       PrintScenery(loc);                                                              ! Cave features

       if (fog in loc || poisonmist in loc)                                                            ! Fog?
       {
               if (poisonmist in loc)
                       print "There is a sheen of evil-looking mist floating around in the air.  ";
               else
               {
                       if (loc.moist == 100)
                               print "A thick, wet fog fills the chamber and gives the surroundings
                                       a dream-like quality.  ";
                       else
                               print "A light fog drifts through the cave.  ";
               }
       }

       ! Describe exits

       print "^^";
       objectloop(i in Compass)
       {
               temp = i.door_dir;
               if(i provides dung && loc.temp ~= 0)            ! Exit exists?
                       PrintExit(loc, i);                                              ! Describe it.
       }
       if (HaveTiedRope())
       {
               objectloop (i in player)
               {
                       if (i provides tiedto && i.tiedto > 0)
                       {
                               print "^Your ", (string) i.specific;
                               if (i.tiedto == FindCeiling(player))
                                       print " is tied to some feature in this cave.^";
                               else
                               {
                                       print " is tied to exit #";
                                       print ExitToRoom(FindCeiling(player), i.tiedto).num, ".^";
                               }
                       }
               }
       }
];

[ PrintRegionType num;                                  ! Print out region type
       switch (num)
       {
               2:
                       print "A large, underground lake fills these rooms.";
               3:
                       print "This network of rooms is much deeper than the rest, probably carved
                               by some long-ago river.";
               4:
                       print "These rooms slowly descend in a funnel-shape.";
               5:
                       print "The fungus in this region is growing rampant; it must have found some
                               crucial nutrient in the walls.";
               6:
                       print "These rooms are more barren and inhospitable than the rest of the
                               caverns.";
               7:
                       print "Judging by the high temperature, these caverns must be heated by some
                               neighbouring fire-shaft.";
               8:
                       print "Due to some complex interaction with the temperature of the surrounding
                               caverns, these caves are quite cold.";
       }
];

[ PrintRegionTypeShort num;                             ! Print short names
       switch (num)
       {
               2:
                       print "lake";
               3:
                       print "chasm";
               4:
                       print "valley";
               5:
                       print "garden";
               6:
                       print "wasteland";
               7:
                       print "steam room";
               8:
                       print "icebox";
       }
];

[ LookRoutine i j k room temp temp2 temp3;
                                                                               ! Printed at the end of every "look"
                                                                               ! & "z" Should be events that change
                                                                               ! (Sounds, etc.)
       room = real_location;

       ! Erase ears object properties.

       ears.isgrubling = 0;
       ears.isreptodon = 0;
       ears.isquickpaw = 0;
       ears.riverspeed = 0;
       ears.riverdistant = 0;
       ears.isboga = 0;
       ears.isrocker = 0;
       ears.iscompressor = 0;
       ears.isbeetle = 0;
       ears.iswumpus = 0;
       ears.isguard = 0;
!/      ears.isbaby = 0;
!/      ears.isbabywhich = 0;
!/      ears.isbabyaction = 0;

       if (room provides heat)
       {
               switch (room.heat)
               {
                       -100 to 15:
                               print "It's freezing cold in this place!^";
                               ChangeStrength(player, -2);
                       16 to 35:
                               print "It's a bit chilly in here.^";
                       200 to 250:
                               print "It's warm in here.^";
                       251 to 300:
                               print "It's hot in here!^";
                       301 to 350:
                               print "It's so hot in here that you're sweating profusely.^";
                               player.thirst--;
                       351 to 1000:
                               print "You can't bear this heat!^";
                               player.thirst--;
                               ChangeStrength(player, -4);
               }
       }

       if (room has poison && Gasmask hasnt worn)
       {
               if (DISEASE == FALSE)
                       print "Breathing the mist in this room makes you feel sick!^";
               DISEASE = DISEASE + 2;
       }

       if (room ofclass C_ROOMS)
       {
               objectloop (k in room)                  ! First, check own room...
               {
                       CheckEars(k, 3);
               }

               objectloop (k in player)                ! ...and carried objects...
               {
                       CheckEars(k, 3);
               }

               if (playpen in room)
               {
                       objectloop (k in playpen)       ! ...and playpen...
                       {
                               CheckEars(k, 3);
                       }
               }

               if (room has river)
                       ears.riverspeed = room.speed;
               else
                       ears.riverspeed = 0;

!/              if (ears.isbaby == 3)
!/              {
!/                      print "You can't hear anything with ";
!/                      print (the) ears.isbabywhich, " making so much noise!^";
!/                      rtrue;
!/              }

               objectloop(i in Compass)                ! ...then, check adjacent room...
               {
                       temp = i.door_dir;
                       temp2 = room.temp;
                       if(ValidDir(room, i))
                       {
                               objectloop (k in temp2)
                               {
                                       CheckEars(k, 2);
                               }

                               if (temp2 has river && temp2.speed > ears.riverspeed)
                               {
                                       ears.riverspeed = temp2.speed;
                                       ears.riverdistant = 0;
                               }
                       }
                       if (temp2 ofclass C_ROOMS)
                       {
                               objectloop (j in Compass)               ! ...and finally, distant rooms.
                               {
                                       temp = j.door_dir;
                                       temp3 = temp2.temp;
                                       if (ValidDir(temp2, j) && temp3 ~= room)
                                       {
                                               objectloop (k in temp3)
                                               {
                                                       CheckEars(k, 1);
                                               }

                                               if (temp3 has river && temp3.speed > ears.riverspeed + 1)
                                               {
                                                       ears.riverspeed = temp3.speed;
                                                       ears.riverdistant = 1;
                                               }
                                       }
                               }
                       }
               }

               if (room hasnt river || room.speed < 9) ! Does waterfall drown everything out?
               {
                       if (ears.isgrubling == 1 or 2)
                       {
                               print "Something ";
                               if (ears.isgrubling == 1)
                                       print "far away ";
                               else
                                       print "nearby ";
                               print "is making a larval sucking sound.^";
                       }
                       if (ears.isreptodon == 1 or 2)
                       {
                               print "You can hear ";
                               if (ears.isreptodon == 1)
                                       print "distant ";
                               print "scales scraping ";
                               if (ears.isreptodon == 2)
                                       print "loudly ";
                               print "through one of the exits.^";
                       }
                       if (ears.isrocker == 1 or 2)
                       {
                               print "The ground ";
                               if (ears.isrocker == 1)
                                       print "vibrates ";
                               else
                                       print "shakes dangerously ";
                               print "to the beat of heavy footsteps.^";
                       }
                       if (ears.isquickpaw == 1 or 2)
                       {
                               print "You can ";
                               if (ears.isquickpaw == 1)
                                       print "barely ";
                               print "hear the soft pattering of feet through one of the exits.^";
                       }
                       if (ears.isboga == 1 or 2)
                       {
                               print "Something ";
                               if (ears.isboga == 1)
                                       print "deep in the caverns ";
                               else
                                       print "nearby ";
                               print "is belching loudly.^";
                       }
                       if (ears.iscompressor == 1 or 2)
                       {
                               print "You can ";
                               if (ears.iscompressor == 1)
                                       print "barely hear a distant whooshing sound.^";
                               else
                                       print "hear a loud whooshing noise nearby.^";
                       }
                       if (ears.isbeetle == 1 or 2)
                       {
                               print "There is a ";
                               if (ears.isbeetle == 1)
                                       print "quiet ticking";
                               else
                                       print "loud ticking";
                               print " coming from one of the exits.^";
                       }
                       if (ears.isguard == 1 or 2)
                       {
                               print "You can hear the ";
                               if (ears.isguard == 1)
                                       print "far-off ";
                               print "sound of marching feet";
                               if (ears.isguard == 2)
                                       print " close by";
                               print ".^";
                       }
!/                      if (ears.isbaby == 1 or 2)
!/                      {
!/                              print "You can ";
!/                              if (ears.isbaby == 1)
!/                                      print "barely ";
!/                              print "hear a baby through one of the exits...it sounds like it ";
!/                              print (string) ears.isbabyaction.currentmsg, ".^";
!/                      }
               }

               if (ears.iswumpus == 1 or 2 && Gasmask hasnt worn)
               {
                       if (ears.iswumpus == 2)
                               print "A horrible stench is pouring";
                       else
                               print "An unpleasant odour is drifting";
                       print " into the cave from somewhere nearby.^";
               }
               if (ears.riverspeed > 3)                ! MUST BE THE LAST BLOCK IN ROUTINE
               {
                       if (room has river && room.speed > ears.riverspeed)
                               return;                                 ! (Due to this)
                       if (ears.riverspeed > 8)
                       {
                               print "The ";
                               if (ears.riverdistant)
                                       print "distant ";
                               else
                                       print "deafening ";
                               print "sound of a waterfall roars through the chamber.^";
                       }
                       else
                       {
                               if (ears.riverspeed > 3)
                               {
                                       print "You can hear the ";
                                       if (ears.riverdistant)
                                               print "distant ";
                                       print "sound of running water.^";
                               }
                       }
               }
       }
];

[ CheckEars obj distance temp;                                  ! Fill in ears with obj & distance.
       if (obj ofclass Grubling && ears.isgrubling == 0)
               ears.isgrubling = distance;
       if (obj ofclass Reptodon && ears.isreptodon == 0)
               ears.isreptodon = distance;
       if (obj ofclass Guard && ears.isguard == 0)
               ears.isguard = distance;
       if (obj ofclass quickpaw && ears.isquickpaw == 0)
               ears.isquickpaw = distance;
       if (obj == boga && ears.isboga == 0 && distance == 2)
               ears.isboga = distance;
       if (obj ofclass Rocker && ears.isrocker == 0)
               ears.isrocker = distance;
       if (obj == Compressor && ears.iscompressor == 0)
               ears.iscompressor = distance;
       if (obj ofclass Beetle && ears.isbeetle == 0)
               ears.isbeetle = distance;
       if (obj == Wumpus && ears.iswumpus == 0)
               ears.iswumpus = distance;

       temp = temp;                                                            ! To stop compiler bitching
!/      if (obj ofclass Baby)
!/      {
!/              temp = obj.last;
!/              if (temp && ears.isbaby == 0 && temp.noisy)
!/              {
!/                      ears.isbaby = distance;
!/                      ears.isbabyaction = obj.last;
!/                      ears.isbabywhich = obj;
!/              }
!/      }
];

[ MoveCreature i cdir room croom test;          ! Move creature given creature & exit

       room = parent(i);
       croom = room;

       ! Can creature go there?

       if (cdir == 0)                                                  ! Invalid direction?
               return 0;

       if (player in room && cdir == ExitToRoom(room, LASTROOM))
       {
               test = random(300);
               if (test < i.speed || i.weight < 3)
               {
                       print (The) i, " slips past you.^";
               }
               else
               {
                       print (The) i, " tries to escape past you, but you're standing in the way.^";
                       rtrue;
               }
       }

       ! Yes.

       if (TestScope(i))
               print (The) i, " ", (string) i.leavestring, " into exit ", cdir.num, ".^";

       i.lroom = room;
       move i to room.(cdir.door_dir);

       if (TestScope(i))                                               ! ...after moving.
       {
               print "You see ", (a) i, " ", (string) i.enterstring, " from exit ";
               print ExitToRoom(parent(i), croom).num, ".^";
       }
];

[ PrintExit loc i croom diff temp;              ! Describe exit, receive room# & exit#
       print "Exit ", i.num;
       temp = i.door_dir;
       croom = loc.temp;
       diff = loc.depth - croom.depth;
       if (diff > 0)
       {
               if (diff > 39)
                       print " rises steeply";
               else
               {
                       if (diff > 19)
                               print " rises";
                       else
                       {
                               if (diff > 9)
                                       print " rises very slightly";
                               else
                                       ExitDescribe(Absl(diff));
                       }
               }
       }
       else
       {
               if (Absl(diff) > 39)
                       print " drops sharply";
               else
               {
                       if (diff > 19)
                               print " swiftly descends";
                       else
                       {
                               if (Absl(diff) > 9)
                                       print " slowly descends";
                               else
                                       ExitDescribe(Absl(diff));
                       }
               }
       }
       print " toward";
       if (WhatLevel(loc) ~= WhatLevel(croom))
       {
               print " some distant";
               if (croom hasnt visited)
                       print " unexplored";
               print " room.  ";
       }
       else
       {
               if (croom hasnt visited)
               {
                       print " an unexplored ";
                       if (croom.region && croom.region == loc.region && REGIONSON)
                               print "part of this ";
                       print "room.  ";
               }
               if (SHOWNUM == 0 && croom has visited)
               {
                       if (croom.region && croom.region == loc.region && REGIONSON)
                               print " a familiar part of this room.";
                       else
                               print " a";
               }
               else
               {
                       if (SHOWNUM && croom has visited)
                       {
                               if (croom.region && croom.region == loc.region && REGIONSON)
                                       print " a familiar part of this room.";
                               else
                               {
                                       if (croom.region)
                                               print " room ", RR(croom.region), " (A";
                                       else
                                               print " room ", RR(croom), " (A";
                               }
                       }
               }
               if (croom has visited)
               {
                       if (croom.region && croom.region == loc.region && REGIONSON)
                               croom = croom;
                       else
                       {
                               ExitSize(croom);
                               print ",";
                               if (croom.moist < 26)
                                       print " dark";
                               else
                                       RoomWall(croom);
                               if (croom has frozen)
                                       print ", frozen";
                               if (croom has river)
                                       print ", watery";
                               print " chamber.";
                               if (SHOWNUM)
                                       print ")";
                       }
               }
       }
       if (croom == LASTROOM) print " **";
       print "^";
];

[ SwimRoutine loc sweepdir temp there;
       if (loc.speed > 7 && random(13) + (actor.strength/100) < loc.speed)
       {
               if (HaveTiedRope())
               {
                       print "The strong current almost washes you off your feet, but your
                               rope saves you!^";
                       rfalse;
               }
               print "The strong current sweeps you off your feet!^";
               sweepdir = LowestWaterExit(loc);
               temp = sweepdir.door_dir;
               there = loc.temp;
               if (temp.depth >= loc.depth)
               {
                       print "Helpless to resist, you are washed into exit #",
                               sweepdir.num,".^^";
                       PressKeyRandom();
                       print "^";
                       << Go sweepdir >>;
               }
               else
               {
                       print "You are brutally smashed against the edge of the
                               river channel.^";
                       ChangeStrength(player, -10);
               }
       }
       rfalse;
];

[ PrintCanteen obj;                                                                                     ! Print canteen status
       switch (obj.level)
       {
               0:
                       print "empty";
               1:
                       print "almost empty";
               2:
                       print "half full";
               3:
                       print "almost full";
               4:
                       print "full";
       }
];

[ PrintCreCompare cre crewith per;                                                      ! Compare strengths
                                                                                                                       ! of cre & crewith
       print "Compared with ", (the) cre, ", ", (the) crewith," is ";
       per = PercentTwo (cre.strength, crewith.strength);
       switch (per)
       {
               0 to 25:
                       print "an easy target";
               26 to 50:
                       print "weaker";
               51 to 125:
                       print "more-or-less equal";
               126 to 150:
                       print "stronger";
               151 to 30000:
                       print "an unbeatable foe";
       }
       print ".^";
];


[ PrintScenery loc;                                                                                     ! Print scenery info
       if ((loc + loc.depth) % 10 < 5)                                 ! How common are features?
       {
               switch ((loc + loc.speed * loc.moist) % 26)
               {
                       1 to 3:
                               if (loc.size < 6)
                               {
                                       if (loc.moist > 75)
                                       {
                                               print "Dripping stalagtites ";
                                               move odrips to loc;
                                       }
                                       else
                                               print "Stalagtites ";
                                       print "hang from the ceiling";
                                       if (loc.size < 2)
                                               print ", almost touching the floor.  ";
                                       else
                                               print " high above.  ";
                               }
                               move ocolumns to loc;
                       4 to 5:
                               print "Stalagmites rise out of the floor, ";
                               if (loc.size < 2)
                                       print "almost reaching the roof.  ";
                               else
                                       print "reaching for the roof of the cave.  ";
                               move ocolumns to loc;
                       6:
                               print "Beautiful stone columns rise from the floor";
                               if (loc.size == 6)
                                       print ", presumably joining with the ceiling far above.  ";
                               else
                                       print " and join with the cave ceiling.  ";
                               move ocolumns to loc;
                       7 to 8:
                               print "A jumble of broken rock lies on the floor, presumably
                                       from a long-ago cave-in.  ";
                               move orubble to loc;
                       9:
                               print "Small, shallow pits ";
                               if (loc.moist > 90)
                               {
                                       print "filled with stagnant water ";
                                       move odrips to loc;
                               }
                               print "pock the floor here and there.  ";
                               move opits to loc;
                       10:
                               print "Some patches of rock coral decorate the floor and
                                       walls.  ";
                               move orubble to loc;
                       11:
                               print "Drapery-like sheets of rippled rock hang down around you.  ";
                               move ocolumns to loc;
                       12:
                               print "A ridge of stone, almost like a diving board, extends over ";
                               if (loc has river)
                                       print "the water in the middle of the room.  ";
                               else
                                       print "a slight depression in the ground.  ";
                               move oridge to loc;
                               move opits to loc;
                       13:
                               if (loc.size < 6)
                               {
                                       print "Long, hollow strands of rock hang down from the
                                               cavern roof.  ";
                                       move ocolumns to loc;
                               }
                       14:
                               print "A huge arc spans the length of the cave";
                               if (loc.size < 6)
                                       print ".  ";
                               else
                                       print ", its apex out of sight.  ";
                               move oarc to loc;
                       15:
                               if (loc.size == 6)
                                       print "The cave is a curiously cylindrical shaft, extending
                                               upwards.  ";
                               else
                                       print "A shaft ascends from the roof of the cave, but it is so
                                               wide and featureless that it cannot be climbed.  ";
                               if (loc has river)
                               {
                                       if (loc.speed > 4)
                                               print "A steady stream of water pours down the shaft and into
                                                       the river below.  ";
                                       else
                                               print "Small drops of water fall out of the shaft and hit
                                                       the pool below.  ";
                                       move odrips to loc;
                               }
                               move oshaft to loc;
                       16:
                               if (loc.size > 2 && loc hasnt river)
                                       {
                                               print "A deep, elongated cavity runs the length of the
                                                       cavern.  ";
                                               move opits to loc;
                                       }
                       17 to 18:
                               print "Shallow clefts mar the walls of the cave.  ";
                               move opits to loc;
                       19:
                               if (loc.size < 6)
                               {
                                       print "The roof of the cave is smoothly domed.  ";
                                       move oarc to loc;
                               }
                       20 to 21:
                               print "Tiny fissures mar the floor.  ";
                               move opits to loc;
                       22 to 23:
                               if (loc has river && loc.speed > 2)
                                       print "Fine sand ";
                               else
                                       print "Coarse gravel ";
                               print "covers much of the cave floor.  ";
                               move orubble to loc;
                       24 to 25:
                               if (loc.size > 4)
                               {
                                       print "This chamber is so long and narrow that it would
                                               be better called a hall.  ";
                                       move oarc to loc;
                               }
               }
       }
];

[ ExitDescribe diff;                                                            ! Describe exit from height difference
       switch (diff % 9)
       {
               0:      print " corkscrews";
               1:      print " meanders";
               2:      print " twists";
               3:      print " turns";
               4:      print " goes";
               5:      print " moves";
               6:      print " weaves";
               7:      print " curves";
               8:      print " stretches";
       }
];

[ ExitSize room;                                                                                ! Print size of exit room
       switch (room.size)
       {
               0:      print " tiny";
               1:      print " small";
               2 to 4: print " fair-sized";
               5:      print " large";
               6:      print " vast";
       }
];

[ RoomSize room;                                                                                ! Print size of given room
       switch (room.size)
       {
               0:      print " tiny, cramped";
               1:      print " small";
               2 to 4: print " fair-sized";
               5:      print " large";
               6:      print " vast";
       }
       PrintRoomType(room);
];

[ PrintRoomType room;
       if (room.region && REGIONSON)
       {
               print " ";
               if (room.regiontype == 1)
                       print "region";
               else
                       PrintRegionTypeShort(room.regiontype);
       }
       else
       {
               if (SNumExits(room) == 1)
                       print " dead-end";
               else
               {
                       switch (room % 4)
                       {
                               1:      print " cave";
                               2:      print " cavern";
                               3:      print " room";
                               0:      print " chamber";
                       }
               }
       }
];

[ RoomWall room;                                                                                ! Describe walls of room
       switch ((room.depth) % 6)
       {
               0:      print " pocked";
               1:      print " polished";
               2:      print " jagged";
               3:      print " creased";
               4:      print " textured";
               5:      print " rough";
       }
];

[ RoomColour room;                                                                              ! Describe wall colours
       switch (WhatLevel(room))
       {
               1: print " orange";
               2: print " brown";
               3: print " grey";
               4: print " onyx";
               5: print " crystalline";
       }
];

[ DescribeWind loc;                                                                             ! Describe the wind
       loc = real_location;
       if (loc.wind < 20)
               "An intermittant breeze sturs the air.";
       print "A";
       switch (loc.wind)
       {
               20 to 39:
                       print " light breeze puffs from";
               40 to 55:
                       print " steady breeze blows from";
               56 to 75:
                       print " steady wind blows from";
               76 to 90:
                       print " strong wind rushes from";
               91 to 1000:
                       print " blast of air is blowing from";
       }
       WindPrint(loc);
];

[ DescribeRiver loc;                                                                    ! Describe river
       loc = real_location;
       print "A ";
       if (WaterExits(loc, 0) == 0)
               print "stagnant pool lies in the middle of the cavern.";
       else
       {
               if (loc.regiontype == 2)
                       print "huge lake stretches from";
               else
               {
                       switch (loc.speed)
                       {
                               0 to 1: print "motionless swamp stretches from";
                               2 to 3: print "sluggish stream oozes from";
                               4 to 6: print "slow-moving river flows from";
                               7 to 8: print "fast-flowing river rushes from";
                               9 to 10:
                                       if (WaterExits(loc, 1) > 0)
                                               print "gush of water bursts from";
                                       else
                                       {
                                               print "waterfall cascades from";
                                               move owaterfall to loc;
                                       }
                       }
               }
               RiverPrint(loc);
       }
       if (loc.size < FILLSROOM)
               print"  It fills the entire room with water.";
       print "^";
];

[ WindPrint room;                                                                               ! Print wind from/to
       print " exit ";
       print WindExitFrom(room).num;
       if (WindExitTo(room))
               print " to exit ", WindExitTo(room).num;
       print ".^";
];

[ RiverPrint room count i temp temp2 nume;                              ! Print river from/to
       nume = WaterExits(room, 1);                                                     ! How many higher exits?
       if (nume == 0)
               print " an underground source";
       else
       {
               count = 1;
               objectloop(i ofclass CompassDirection)                  ! Loop room's exits
               {
                       temp = i.door_dir;
                       temp2 = room.temp;

                       if(i provides dung && room.temp ~= 0
                               && room.temp has river && room.depth > temp2.depth)
                                                                                                               ! Exits go high w/ river?
                       {
                               print " ";
                               if (count == 1)
                                       print "exit";
                               if (nume > 1 && count == 1)
                                       print "s";
                               print " ",i.num;
                               count++;
                               if (count == nume)
                                       print " &";
                               if (count < nume && nume > 2)
                                       print ",";
                       }
               }
       }
       if (room.speed > 1)
               print ", through the room, and into";
       else
               print " into";

       nume = WaterExits(room, -1);                                            ! How many lower exits?
       if (nume == 0)
               print " a tiny crack in the wall";
       else
       {
               count = 1;
               objectloop(i ofclass CompassDirection)
               {
                       temp = i.door_dir;
                       temp2 = room.temp;

                       if(i provides dung && room.temp ~= 0
                               && room.temp has river && room.depth <= temp2.depth)
                                                                                                               ! Exits go low w/ river?
                       {
                               if (count == 1)
                                       print " exit";
                               if (nume > 1 && count == 1)
                                       print "s";
                               print " ",i.num;
                               count++;
                               if (count == nume)
                                       print " &";
                               if (count < nume && nume > 2)
                                       print ",";
                       }
               }
       }
       print ".";
];

[ SetupDungeon x count room croom repeat out down i temp temp2 maxsteps iterate num nroom
                               highest;

       ! First, create empty rooms.

       for (x = 1: x <= MAXROOMS: x++)
       {
               if (x == 1)
                       FIRSTROOM = C_ROOMS.create();           ! Set FIRSTROOM
               else
                       C_ROOMS.create(count);
               count++;
       }

       ! Safety net: connect levels together.

       for (x = 5: x >= 1: x--)
       {
               room = RandRoom(x);
               if (x == 1)
               {
                                                                                                               ! Connect top level to surface
                       LOCATION1 = room;
                       room.conn = 1;                                                          ! For upcoming connection test
                       room.fungus = 35;
                       room.heat = 100;
               }
               else
                       Connect (room, RandRoom(x - 1));                        ! Connect level to one above.
       }

       ! Comprehensive: connect all rooms within level

       for (repeat = 1: repeat <= 1: repeat++)         ! As comprehensive as you like.
       {
               for (out = 1: out <= NRL(): out++)              ! Proceed out through the levels.
               {
                       for (down = 1: down <= 5: down++)       ! ...and down the levels.
                       {
                               PickMakeRoom(FR((down - 1) * NRL() + out), 0);
                       }
               }
       }

       ! Extra: connect rooms outside levels

       for (repeat = 1: repeat <=1: repeat++)                  ! As extensive as you like
       {
               for (room = 1: room <= MAXROOMS: room++)        ! Through all the rooms.
               {
                       if (random(100) < 7)                                    ! ADJUST: > more extra-level connections
                       {
                               PickMakeRoom(FR(room), 2);
                       }
               }
       }

       ! Do connection test

       count = 0;
       maxsteps = 0;
       iterate = 0;
       highest = 0;
       repeat = 0;
       do
       {
               for (room = FR(1): room <= FR(MAXROOMS): room++)        ! Through all rooms
               {
                       if (room.conn > 0)                                                                      ! Is room connected?
                       {
                               if (maxsteps < room.conn)
                                       maxsteps = room.conn;                                           ! Find max # steps
                               objectloop(i ofclass CompassDirection)                  ! Loop room's exits
                               {
                                       temp = i.door_dir;

                                       if(i provides dung && room.temp ~= 0)           ! Exits go anywhere?
                                       {
                                               temp2 = room.temp.conn;
                                               if (temp2 == 0)
                                                       count++;
                                               if (temp2 == 0 || temp2 > room.conn + 1)        ! Spread out
                                               {
                                                       room.temp.conn = room.conn + 1;                 ! connection markers
                                                       if (room.conn + 1 > highest)
                                                       {
                                                               highest = room.conn + 1;
                                                               repeat = room.temp;
                                                       }
                                               }

                                       }
                               }
                       }
               }
               iterate++;                                                                                              ! Safety exit
       }
       until (count == 99 || iterate == 10);

!       print "Furthest room: ", repeat," (", highest,")^";
       LOCATION100 = repeat;

       if (iterate == 10)                                                              ! Not all rooms connected.
       {
               for (room = FR(1): room <= FR(MAXROOMS): room++)        ! Through all rooms
               {
                       if (room.conn == 0)                                                             ! Not connected?
                       {
                               count = 0;
                               do
                               {
                                       count++;
                                       temp2 = RandRoom(WhatLevel(room));              ! Room in own level?
                               }
                               until (temp2.conn ~= 0 || count > 30);
                               if (temp2.conn == 0)
                               {
                                       count = 0;
                                       do
                                       {
                                               count++;
                                               temp2 = RandRoom(random(5));            ! Room in any level.
                                       }
                                       until (temp2.conn ~= 0 || count > 80);
                               }
                               if (temp2.conn == 0)
                                       print "No hope.^";
                               else                                                                            ! Force connection.
                               {
                                       Connect(room, temp2);
                                       room.conn = temp2.conn + 1;
                               }
                       }
               }
       }

       ! Apply depths

       PrintIntro(2, 1);

       for(iterate = 0:iterate < RANDSEED:iterate++)                   ! Scoffed from Jim Fisher.
               random(1);

       ! Initial depths (based on level, distance from entrance, and random)

       for (room = FR(1): room <= FR(MAXROOMS): room++)        ! Through all rooms
       {
               room.depth = (WhatLevel(room) * 50) + (room.conn * 4);
               room.depth = room.depth + (50 - random(100));
       }

   ! Smooth the depths

       for (repeat = 1: repeat <= 4: repeat++)                         ! As many times as you like
       {
               for (room = FR(1): room <= FR(MAXROOMS): room++)        ! Through all rooms
               {
                       room.depth = (SSumDepth(room) + room.depth) / (SNumExits(room) + 1);
               }
       }

       ! Some pits

       for (count = 1: count <= 6: count++)                            ! Make pits
       {
               room = RandRoom(2 + random(3));                         ! Pick a room in levels 3 to 5
               room.depth = room.depth + 50 + random(100);
               for (repeat = 1: repeat <= 3: repeat++)                 ! Wider & wider...
               {
                       objectloop (i ofclass CompassDirection)         ! Make wider pits
                       {
                               temp = i.door_dir;

                               if(i provides dung && room.temp ~= 0)
                               {
                                       temp2 = room.temp;
                                       temp2.depth = (temp2.depth + room.depth) / 2;
                               }
                       }
                       room = Shallowest(room);                                                ! Move to next room...eat
               }
       }

       ! Build streams

       ! Start springs

       x = 0;
       for (count = 1: count <= 3: count++)                            ! Make 3 springs
       {
               room = RandRoom(random(5));                                             ! Pick a random room
               croom = room;                                                                   ! Store it up for later

               ! Move down...

               num = random(4) + 3;
               for (down = 1: down <= num: down++)                             ! Go down random steps
               {
                       if (room hasnt river)
                               x++;
                       give room river;                                                        ! Give room necessary
                       room.moist = 20;                                                        ! attributes
                       if (Deepest(room) == room)                                      ! Pick next room
                               nroom = SRandom(room);
                       else
                               nroom = Deepest(room);
                       room.speed = room.speed + Absl(room.depth - nroom.depth) / 3;
                       if (room.speed > 10)
                               room.speed = 10;
                       room.moist = room.moist + room.speed * 2;
                       room = nroom;
               }

               ! ...and up...

               room = croom;
               num = random(4) + 3;
               for (out = 1: out <= num: out++)                                ! Go up random steps
               {
                       if (room hasnt river)
                               x++;
                       give room river;                                                        ! Give room necessary
                       room.moist = 20;                                                        ! attributes
                       if (Shallowest(room) == room)                           ! Pick next room
                               nroom = SRandom(room);
                       else
                               nroom = Shallowest(room);
                       room.speed = room.speed + Absl(room.depth - nroom.depth) / 3;
                       if (room.speed > 10)
                               room.speed = 10;
                       room.moist = room.moist + room.speed * 2;
                       room = nroom;
               }
       }

       PrintIntro(3, 1);

       ! Make wind path

       ! Pick source room

       do
       {
               room = RandRoom(5);
       }
       until (room hasnt river);

       FURNACE = room;
       room.heat = 400;
       room.wind = 100;

       x = room.wind;
       croom = room;

       ! Move up

       num = random(4) + 16;

       for (out = 1: out <= num: out++)                                ! Go up random steps
       {
               x = room.wind - (out * 7);
               if (croom.heat == 0)
               {
                       croom.wind = x * 2;
                       croom.heat = x * 3;
               }
               croom.moist = 20;
               if (Shallowest(croom) == croom)                         ! Pick next room
               {
                       count = 0;
                       do
                       {
                               nroom = SRandom(croom);
                               count++;
                       }
                       until (nroom.wind == 0 || count == 15);
               }
               else
                       nroom = Shallowest(croom);
               croom = nroom;
       }

       room = RandRoom(4);
       FREEZER = room;
       give room frozen;
       room.heat = 1;
       room.moist = 1;
       room.wind = 1;
       room.fungus = 0;
       room.depth = room.depth + 100;

       objectloop (i ofclass CompassDirection)                                         ! Spread out cold
       {
               temp = i.door_dir;

               if (i provides dung && room.temp ~= 0)
               {
                       croom = room.temp;
                       give croom frozen;
                       croom.heat = 1;
                       croom.moist = 1;
                       croom.wind = 1;
                       croom.fungus = 0;
                       croom.depth = croom.depth + 50;
               }
       }

       ! Make first level hospitable

       for (room = FR(1): room <= FR(MAXROOMS/5): room++)
       {
               if (room.conn < 7)
               {
                       room.moist = 80 - (room.conn * 10);
                       room.heat = 100 - (room.conn * 10);
                       room.fungus = room.moist;
               }
       }

       ! Spread out moisture, heat & wind

       for (repeat = 1: repeat <= 5: repeat++)                         ! As many times as you like
       {
               for (room = FR(1): room <= FR(MAXROOMS): room++)        ! Through all rooms
               {
                       if (room.moist > 0 || room.heat > 0 || room.wind > 0)
                       {
                               objectloop(i ofclass CompassDirection)                  ! Loop room's exits
                               {
                                       temp = i.door_dir;

                                       if(i provides dung && room.temp ~= 0)           ! Exits go anywhere?
                                       {
                                               croom = room.temp;                                              ! Define room
                                               if (room.moist)
                                                       croom.moist = croom.moist + room.moist / 8;
                                               if (room.heat)
                                                       croom.heat = croom.heat + room.heat / 4;
                                               if (room.wind)
                                                       croom.wind = croom.wind + room.wind / 5;
                                               if (croom.moist > 100)
                                                       croom.moist = 100;
                                               if (croom has frozen)
                                                       croom.heat = croom.heat /4;
                                               if (croom.heat > 400)
                                               {
                                                       if (WhatLevel(croom) == 5)
                                                               croom.heat = 400;
                                                       else
                                                               croom.heat = croom.heat /3;
                                               }
                                               if (croom.wind > 100)
                                                       croom.wind = 100;
                                               croom.fungus = croom.moist;
                                       }
                               }
                       }
               }
               FREEZER.heat = 1;
               FREEZER.moist = 1;
               FREEZER.wind = 1;
               FREEZER.fungus = 0;
       }

       ! Assign cavern sizes

       ! Random assignment

       for (count = 1: count <= 10: count++)                           ! Pick 20 rooms
       {
               room = RandRoom(random(5));                             ! Pick a room on any level
               room.size = 0;                                                  ! Tiny
               room = RandRoom(random(5));
               room.size = 6;                                                  ! Huge
       }

       ! Spread out cave sizes

       for (repeat = 1: repeat <= 4: repeat++)                         ! As many times as you like
       {
               for (room = FR(1): room <= FR(MAXROOMS): room++)        ! Through all rooms
               {
                       objectloop(i ofclass CompassDirection)                  ! Loop room's exits
                       {
                               temp = i.door_dir;
                               temp2 = room.temp;

                               if(i provides dung && room.temp ~= 0)           ! Exits have chosen size?
                               {
                                       croom = room.temp;                                              ! Define room
                                       croom.size = croom.size + ((room.size - 3)/2);
                                       if (croom.size > 6)
                                               croom.size = 6;
                                       if (croom.size < 0)
                                               croom.size = 0;
                               }
                       }
               }
       }

       ! Define regions

       for (room = FR(1) + NRL(): room <= FR(MAXROOMS): room++)        ! Through all rooms
       {
               if (room.region == 0 && room.size > 5 && room ~= FREEZER && room ~= FURNACE)
               {
                       repeat = NearbyRegion(room);
                       if (repeat)
                       {
                               room.region = repeat.region;                            ! Adopt nearby region
                               room.regiontype = repeat.regiontype;
                               room.regiondepth = repeat.regiondepth;
                               ApplyRegion(room);
                       }
                       else
                       {
                               if (NearbyVast(room))
                               {
                                       room.region = room;                                             ! Create new region
                                       if (WhatLevel(room) > 1 && random(6) < 4)       ! Will it be special?
                                       {
                                               room.regiontype = random(7) + 1;
                                               room.regiondepth = room.depth;
                                               ApplyRegion(room);
                                       }
                                       else                                                                    ! No, mark it normal.
                                       {
                                               room.regiontype = 1;
                                       }
                                       objectloop(i ofclass CompassDirection)
                                       {
                                               temp = i.door_dir;
                                               temp2 = room.temp;
                                               if (i provides dung && room.temp ~= 0)
                                               {
                                                       if (temp2.size > 5 && WhatLevel(room) == WhatLevel(temp2))
                                                       {
                                                               temp2.region = room;            ! Spread region
                                                               temp2.regiontype = room.regiontype;
                                                               temp2.regiondepth = room.regiondepth;
                                                               ApplyRegion(temp2);
                                                       }
                                               }
                                       }
                               }
                       }
               }
       }

       PrintIntro(4, 1);

       ! Some pools...

       for (count = 1: count <= 5: count++)                            ! Make 5 pools
       {
               room = RandRoom(random(5));                                             ! Pick a random room
               give room river;
               room.moist = room.moist + 20;
               if (room.moist > 100)
                       room.moist = 100;
       }

       ! Place and define creatures

       objectloop(i ofclass Creature)
       {
               if (i.shuffler)                                                 ! Set up unique creature name
               {
                       ShufflerName(i);
                       if (i ofclass Guard)
                       {
                               move i to LOCATION100;
                               if (i.type < 5)
                                       give i female;
                       }
               }

               if (i.inlevel > 0)
                       move i to RandRoom(i.inlevel);
               else
               {
                       if (i == Hurkle)
                               IntoQuietPool(Hurkle);
                       if (i == Boga)
                               move i to FURNACE;
                       if (i ofclass Beetle)
                               move i to beetlebag;
               }
               if (parent(i) == nothing)
                       move i to creaturebag;
               if (i == tb_1)
               {
                       count = RandRoom(5);
                       move i to count;
               }
               if (i ofclass Baby)
               {
                       DefineBaby(i);
                       move i to playpen;
               }
       }
       move Wumpus to count;
       move Eggsack to count;

       ! Place chutes

       objectloop (i ofclass Chute)
       {
               do
               {
                       count = RandRoom(i.clevel);
               }
               until (count hasnt river);
               move i to RandRoom(i.clevel);
       }

       ! Place barrels

       objectloop (i ofclass Barrel)
       {
               move i to RandRoom(i.clevel);
               StartTimer(i, random(20) * i.clevel);
       }

       ! Place objects in objectbag & jewelbag...

       objectloop(i ofclass CaveObject)
       {
               if (parent(i) == nothing && ~~i ofclass Corpse)
               {
                       if (i ofclass Jewel)
                               move i to jewelbag;
                       else
                               move i to objectbag;
               }
       }

       ! Define jewels and place half of them

       count = 0;
       maxsteps = children(jewelbag) / 2;
       objectloop (i ofclass Jewel)
       {
               count++;
               AlchemyRandom(i);
               if (count <= maxsteps)
               {
                       room = RandRoom(random(3) + 2);
                       move i to room;
                       if (room has river && random(2) == 1)
                               PutInRiver(i, room);
               }
       }

       LOCATION1.fungus = 30;
       Connect(LOCATION100, EndRoom);
       EndRoom.depth = LOCATION100.depth;

       ! Set up markers to exit.

       for (room = FR(1): room <= FR(MAXROOMS): room++)
               room.conn = 0;

       EndRoom.conn = 1;
       LOCATION100.conn = 2;

       count = 0;
       maxsteps = 0;
       iterate = 0;
       highest = 0;
       repeat = 0;

       do
       {
               for (room = FR(1): room <= FR(MAXROOMS): room++)        ! Through all rooms
               {
                       if (room.conn > 0)                                                                      ! Is room connected?
                       {
                               if (maxsteps < room.conn)
                                       maxsteps = room.conn;                                           ! Find max # steps
                               objectloop(i ofclass CompassDirection)                  ! Loop room's exits
                               {
                                       temp = i.door_dir;

                                       if(i provides dung && room.temp ~= 0)           ! Exits go anywhere?
                                       {
                                               temp2 = room.temp.conn;
                                               if (temp2 == 0)
                                                       count++;
                                               if (temp2 == 0 || temp2 > room.conn + 1)        ! Spread out
                                               {
                                                       room.temp.conn = room.conn + 1;                 ! connection markers
                                               }

                                       }
                               }
                       }
               }
               iterate++;                                                                                              ! Safety exit
       }
       until (count == 99 || iterate == 20);
];

[ Shufflername cre count temp ;                                                                 ! Set up unique cre name
       do
       {
               count = 1;
               cre.type = random(cre.shuffler);
               objectloop (temp ofclass Creature)
               {
                       if (temp ~= cre && temp.creclass == cre.creclass)
                       {
                               if (temp.type == cre.type)
                                       count = 0;
                       }
               }
       }
       until (count);
];

[ ApplyRegion room i temp temp2;                                                                ! Define special regions
       switch (room.regiontype)
       {
               2:
                       room.depth = room.regiondepth + 30;
                       give room river;
                       room.speed = room.speed / 2;
                       room.moist = 75;
                       room.fungus = 75;
               3:
                       room.depth = room.depth + 100;
               4:
                       room.depth = room.depth + 25;
                       objectloop (i ofclass CompassDirection)
                       {
                               temp = i.door_dir;
                               if (i provides dung && room.temp ~= 0)
                               {
                                       temp2 = room.temp;
                                       if (temp2.region == room.region)
                                               temp2.depth = (temp2.depth + room.depth) / 2;
                               }
                       }
               5:
                       room.moist = 100;
                       room.fungus = 100;
                       room.heat = 225;
               6:
                       room.depth = room.regiondepth;
                       give room ~river;
                       room.moist = 0;
                       room.fungus = 0;
               7:
                       room.moist = 100;
                       room.wind = 0;
                       room.heat = 325;
               8:
                       room.moist = 0;
                       room.wind = 0;
                       room.fungus = 0;
                       room.heat = 0;
                       give room frozen;
       }
];

[ SpillObjectBag sum x level obj toroom;                                ! Randomly distribute some objects
       sum = children(ObjectBag);
       for (x = 1: x < sum/2: x++)                                     ! Empty half of the objects
       {
               level = random(5);                                              ! Pick a random level
               obj = PilferObjectBag(0, level * 10);   ! Pick an object that suits level
               if (obj == 0)
                       return;                                                         ! No applicable objects?
               toroom = RandRoom(level);
               move obj to toroom;
               if (toroom has river && obj.worth < 26)
               {
                       PutInRiver(obj, toroom);
               }
       }
];

[ IntoQuietPool cre croom count;                                        ! Put cre in a quiet pool
       croom = RandRoom(3);
       do
       {
               if (IsQuietPool(croom))
               {
                       move cre to croom;
                       give cre concealed;
                       cre.hiding = 1;
                       rtrue;
               }
               count++;
               croom++;
               if (croom == FR(MAXROOMS))
                       croom = FR(1);
       }
       until (count == MAXROOMS);
];

[ PilferObjectBag lowest highest sum pick y x;                  ! Grab object worth lowest to highest
       sum = 0;                                                                                        ! or 0 if none apply
       objectloop (x in ObjectBag)                                             ! How many objects meet requirements?
       {
               if (x.worth >= lowest && x.worth <= highest)
                       sum++;
       }
       if (sum == 0)
               return 0;                                                                       ! No applicable objects.
       pick = random(sum);
       objectloop (x in ObjectBag)                                             ! Choose random object.
       {
               if (x.worth >= lowest && x.worth <= highest)
                       y++;
               if (y == pick)
                       return x;
       }
];

[ Alchemy cre x picked numobjs weightobjs worthobjs;
       while (child(cre))
       {
               x = child(cre);
               numobjs++;
               weightobjs = weightobjs + x.weight;
               worthobjs = worthobjs + x.worth;
               if (x ofclass Jewel)
                       move x to jewelbag;
               else
               {
                       if (x ofclass Corpse)
                               remove x;
                       else
                               move x to objectbag;
               }
       }
       objectloop (x in jewelbag)
               picked = x;
       if (picked == 0)
               rtrue;
       picked.quality = random(6);
       picked.lightness = random(2);
       picked.color = random(6);
       picked.weight = (weightobjs / numobjs) / 10;
       if (picked.weight == 0)
               picked.weight = 1;
       picked.worth = (1 + worthobjs / numobjs) * 30;
       picked.monworth = worthobjs;
       if (TestScope(cre))
       {
               print "There is a blinding flash of light, and ", (the) cre, " screams in pain and
                       loss.^";
               print (The) cre, " drops ", (a) picked, ".^";
       }
       move picked to FindCeiling(cre);
       if (FindCeiling(cre) has river)
               PutInRiver(picked, FindCeiling(cre));
];

[ AlchemyRandom picked;                                 ! Give picked random stats.
       picked.quality = random(6);
       picked.lightness = random(2);
       picked.color = random(6);
       picked.weight = (random(10));
       picked.worth = random(100);
       picked.monworth = 20 + picked.worth * 3;
];

[ DefineBaby; !cre repeat count;                                                ! Create unique baby
!/      repeat = 1;
!/      while (repeat)
!/      {
!/              repeat = 0;
!/              cre.size = random(8);
!/              cre.language = random(10);
!/              cre.happy = random(100);
!/              if (random(100) > 49)
!/                      give cre female;
!/              else
!/                      give cre ~female;
!/              objectloop (count ofclass Baby)
!/              {
!/                      if (count.size == cre.size && count.language == cre.language && count ~= cre)
!/                              repeat == 1;
!/              }
!/      }
];

[ OozeIncrement level;
       switch (level)
       {
               1:      return 10;
               2:      return 20;
               3:      return 40;
               4:      return 80;
               5:      return 160;
       }
];

[ PickMakeRoom room type croom count level pass;                ! Connect given room with a random room
                                                                                                               ! Room MUST be FR when sent!!!
       if (NumCon(room) < 4)                                                           ! Any connections available?
       {
               count = 0;
               level = WhatLevel(room);                                ! Level to attend to
               switch (type)
               {
                       0:
                               croom = RandRoom(level);                        ! Pick a connecting room in current level
                       1:
                               croom = RandRoom(random(5));            ! Pick a connecting room in any level
                       2:
                               if (level == 1)                                         ! Pick a room in adjacent level
                                       croom = RandRoom(level + 1);
                               else
                                       croom = RandRoom(level - 1);
               }
               do
               {
                       pass = 0;                                                       ! Success of loop
                       count++;                                                        ! No endless loop!
                       croom++;                                                        ! Work way through rooms in level
                       if (type == 0)
                       {
                               if (croom > LLevel(level))                      ! Go to first room in level if outside level
                                       croom = FLevel(level);
                       }
                       if (room ~= croom && NumCon(croom) < 4 && NotAlreadyCon(room, croom))
                               pass = 1;                                               ! "Pass" if croom is distinct & connectable
               }
               until (pass || count > NRL());
               if (pass)
               {
                       Connect(room, croom);                           ! Connect rooms if croom is viable.
               }
       }
];

[ NotAlreadyCon room croom pass num x tester;   ! To stop multiple identical connections
       pass = 1;
       num = NumCon(room);

       for (x = 1: x <= num: x++)
       {
               switch (x)
               {
                       1:
                               tester = room.x1_to;
                       2:
                               tester = room.x2_to;
                       3:
                               tester = room.x3_to;
                       4:
                               tester = room.x4_to;
                       5:
                               tester = room.x5_to;
               }
               if (tester == croom)
                       pass = 0;
       }
       return pass;
];

[ Connect room croom x rfrom rto;                               ! Connect given rooms (must be possible!)

       for (x = 1: x <= 2: x++)                                        ! Reduce code redundancy.
       {
               if (x == 1)
               {
                       rfrom = room;
                       rto = croom;
               }
               else
               {
                       rfrom = croom;
                       rto = room;
               }

               switch (FirstCon(rfrom))
               {
                       1:      rfrom.x1_to = rto;
                       2:      rfrom.x2_to = rto;
                       3:      rfrom.x3_to = rto;
                       4:      rfrom.x4_to = rto;
                       5:      rfrom.x5_to = rto;
               }
       }
];

[ DrawStatusLine width posa posb;
       @split_window 1;
       @set_window 1;
       @set_cursor 1 1;
       style reverse;
       width = 0->33;
       posa = width-14;
       posb = width-13;
       spaces width;
       @set_cursor 1 2;
       if (SHOWNUM)
       {
               if (real_location.region)
                       print "Room #", RR(real_location.region);
               else
                       print "Room #", RR(real_location);
       }
       if (FORFEIT == 0)
       {
               @set_cursor 1 posa;
               print " Score: ", score;
       }
       @set_cursor 2 1;
       spaces width;
       @set_cursor 2 2;
       if (location == thedark)
               print (name) location;
       else
       {
               FindVisibilityLevels();
               if (visibility_ceiling == location)
                       print (name) location;
               else
                       print (The) visibility_ceiling;
       }
       @set_cursor 2 posa;
       print "Health: ", Health(player), "%";
       @set_cursor 1 1;
       style roman;
       @set_window 0;
];

[ PrintIntro part anykey;

       if (anykey)
       {
               PressKeyRandom();
               print "^^";
       }
       switch (part)
       {
               1:
                       print "^Some people love exploring caves, and some people get a sick thrill
                       out of falling.  But you're not one of them.^^
                       Since childhood you've had a fear of heights, depths, and quick trips in
                       between; those dreams about endless drops into bottomless pits still haunt you,
                       especially when you've had a bit to drink.  You were also one of those kids
                       who was CONVINCED that the boogeyman lurked under the basement steps, down
                       there in the cold and clammy darkness.  Nope, you are definitely NOT a fan
                       of these two exotic pleasures of falling and darkness, which is why you're
                       not thrilled about being thrown into a deep, forbidding shaft.  If the
                       fall lasts long enough maybe you'll get a chance to ponder what's at the
                       bottom of it all, and what you left behind on the surface...^^";
               2:
                       print "To be fair you HAVE plumbed these depths, though not in a very
                       heroic way.  You've done research and talked to people, mainly.  When you
                       devoted last week's editorial to exposing the shady dealings of New Jersey
                       public officials, you thought you'd be given
                       a promotion.  Maybe the newspaper chain would bump you up to some big city
                       assignment, get you away from the little Morristown rag you'd been working
                       on for seven years.^^
                       Apparently, the one thing you DIDN'T find out in your research was that
                       those public officials OWN the newspaper chain, and that they're even more
                       ruthless and
                       immoral than you'd thought.  Now, after being dragged out of bed
                       and dumped into the pit itself, it looks like that promotion is a long way
                       off.^^";
               3:
                       print "But what IS in this pit?  You've read facts about it in geological
                       surveys.  You've heard all the local folklore about the mythical creatures
                       lurking down there -- the Wumpus was probably the most colourful monster of
                       the bunch -- and you know for a fact that the city's been dumping toxic waste
                       into it for years.  Leave it to a bunch of suburban fat-cats to arrange a
                       billion-dollar
                       waste-disposal contract, and then just hire some local thugs to dump the stuff
                       into a hole under Morristown.  Could that toxic junk be leaking into the
                       city's water supply?  Lots of people are speculating, but nobody has had
                       the courage to actually go DOWN there to check it out.^^";
               4:
                       print "Well, looks like you've been reluctantly nominated.  If you survive the
                       fall,
                       you might get a chance to solve these mysteries...and maybe win a Pulitzer
                       Prize to boot!  You've been falling for a
                       long time, and it's almost time to land...for better or for worse.^^
                       And hey, maybe that Wumpus thing is really friendly?^^";
       }
];

! ----------------------------- Meta mappin' functions

[ Surrounding room iteration endit lastroom i newroom;  ! Sonar surrounding room
       print "^Room #", RR(room),", ", SnumExits(room), " exits.^";
       if (iteration == endit)
       {
               print "...(Back to)...^";
               rtrue;
       }

       for (i = 1: i <= SNumExits(room): i++)
       {
               switch (i)
               {
                       1:
                               newroom = room.x1_to;
                       2:
                               newroom = room.x2_to;
                       3:
                               newroom = room.x3_to;
                       4:
                               newroom = room.x4_to;
                       5:
                               newroom = room.x5_to;
               }
               if (newroom ~= lastroom)
               {
                       print "Exit #", i," goes to...";
                       Surrounding(newroom, iteration + 1, endit, room);
               }
       }
];

! ------------------------Function calls.

[ CreaturesPresent room x count;                                ! Return number of creatures for room
       objectloop (x in room)                                          ! Don't include hidden creatures!
       {
               if (x ofclass Creature || x == player)
               {
                       if (x.hiding == 0)
                               count++;
               }
       }
       return count;
];

[ PlayerInRoom room;                                                    ! Is player in given room?
       if (FindCeiling(player) == room)
               return TRUE;
       return FALSE;
];

[ PickPrey cre room x count sum weakness weakest;       ! Return prey for cre in room
       sum = CreaturesPresent(room);                                   ! Don't include hidden creatures!
       count = 1;
       weakness = 9999;                                                                ! Returns weakest prey

       objectloop (x in room)
       {
               if (x provides strength && x ~= cre && x.hiding == 0)
               {
                       if (x.strength < weakness)
                       {
                               weakness = x.strength;
                               weakest = x;
                       }
               }
       }
       return weakest;
];

[ PickCreature room x picknum num;                                      ! Return random creature in room
                                                                                                       ! Don't include hidden creatures!
       picknum = random(CreaturesPresent(room));

       objectloop (x in room)
       {
               if (x provides strength && x.hiding == 0)
               {
                       num++;
                       if (num == picknum)
                               return x;
               }
       }
];

[ JewelInRoom room x;                                                           ! Is there a jewel in room?
       objectloop (x in room)
       {
               if (x ofclass Jewel)
                       rtrue;
       }
       rfalse;
];

[ ObjNotJewel room x;                                                           ! Are there non-jewel obj in room?
       objectloop (x in room)
       {
               if (x provides worth)
               {
                       if (x ofclass Jewel)
                               x = x;
                       else
                               rtrue;
               }
       }
       rfalse;
];

[ PreyDir room c temp temp2 r;                                  ! Return a room with prey (or 0)
                                                                                               ! Don't include hidden creatures!
       objectloop (c ofclass CompassDirection)
       {
               temp = c.door_dir;

               if (ValidDir(room, c))
               {
                       temp2 = room.temp;

                       if (player in temp2)                                    ! Is player in there?
                               return c;

                       objectloop (r in temp2)                                 ! Is prey in there?
                       {
                               if (r > 0 && r provides prey && r.hiding == 1)
                                       return c;
                       }
               }
       }
       return 0;                                                                               ! No prey found.
];

[ ValidDir room cdir temp;                                                      ! Valid direction from room?
       temp = cdir.door_dir;
       if (cdir provides dung)                                         ! Dungeon exit?
       {
               if (room.temp ~= 0)                                             ! Goes somewhere?
               {
                       return TRUE;
               }
       }
       return FALSE;
];

[ NoPredDir room c temp temp2 r disq;                   ! Return a room with no predator
                                                                                               ! (or 0)
       objectloop (c ofclass CompassDirection)
       {
               temp = c.door_dir;

               if (ValidDir(room, c))
               {
                       temp2 = room.temp;
                       disq = 0;

                       objectloop (r in temp2)                         ! Is predator in there?
                       {
                               if (r > 0 && r provides predator)
                                       disq = 1;                                       ! Disqualified
                       }
                       if (disq == FALSE)
                               return c;
               }
       }
       return 0;
];

[ BeetleEmpty room c temp temp2 r disq;                         ! Return a room without beetles
       objectloop (c ofclass CompassDirection)                 ! or poison (or 0)
       {
               temp = c.door_dir;
               if (ValidDir(room, c))
               {
                       temp2 = room.temp;
                       disq = 0;

                       if (temp2 has poison)
                               disq = 1;
                       else
                       {
                               objectloop (r in temp2)
                               {
                                       if (r ofclass Beetle)
                                               disq = 1;
                               }
                       }
                       if (disq == FALSE)
                               return c;
               }
       }
       return 0;
];

[ PoisonSurrounding room c temp temp2;                  ! Poison surrounding rooms
       objectloop (c ofclass CompassDirection)
       {
               temp = c.door_dir;
               if (ValidDir(room, c))
               {
                       temp2 = room.temp;
                       give temp2 poison;
               }
       }
];

[ ValObDir room nohoard c temp temp2 r best pick;               ! Return room with most valuable
                                                                                               ! object (or 0).  Nohoard can be provided
       objectloop (c ofclass CompassDirection)         ! Does not include worth of 0 or rope!
       {                                                                                       ! nohoard 1000 = no jewels!
               temp = c.door_dir;
               if (ValidDir(room, c))
               {
                       temp2 = room.temp;

                       objectloop (r in temp2)                         ! Object in there?
                       {
                               if (r provides worth && r.worth > 0)
                               {
                                       if (r.worth > best)
                                       {
                                               if (nohoard == 0 || nohoard ~= r.hoarded)
                                               {
                                                       if (nohoard == 1000 && r ofclass Jewel)
                                                               r = r;
                                                       else
                                                       {
                                                               pick = c;
                                                               best = r.worth;
                                                       }
                                               }
                                       }
                               }
                       }
               }
       }
       return pick;
];

[ NewDir cre room c temp temp2 picknum num;                     ! Return not LASTROOM (or 0)
       room = parent(cre);                                                             ! REQUIRES cre!!!
       picknum = random(SNumExits(room)-1);
       objectloop (c ofclass CompassDirection)
       {
               temp = c.door_dir;
               if (ValidDir(room, c))
               {
                       temp2 = room.temp;

                       if (cre.lroom ~= temp2)
                       {
                               num++;
                               if (num == picknum)
                               {
                                       return c;
                               }
                       }
               }
       }
       return 0;
];

[ FootprintsDir room;                                           ! Return the direction with footprints
       return room.footto;
];

[ RandDir room cdir i num count pick temp;      ! Return random direction
       count = 0;                                                              ! From given room
       num = SNumExits(room);
       pick = random(num);                                     ! Pick a random exit number

       objectloop (i ofclass CompassDirection)
       {
               temp = i.door_dir;
               if (ValidDir(room, i))
               {
                       count++;
                       if (count == pick)
                       {
                               cdir = i;
                       }
               }
       }
       return cdir;
];

[ FungusDir room cdir i num temp temp2;         ! Return the direction with > fungus

       num = room.fungus;
       cdir = 0;
       objectloop (i ofclass CompassDirection)
       {
               temp = i.door_dir;
               if (ValidDir(room, i))
               {
                       temp2 = room.temp;
                       if (temp.fungus > num)
                       {
                               num = temp2.fungus;
                               cdir = i;
                       }
               }
       }
       return cdir;
];

[ QuietPoolDir room cdir i temp;                        ! Return the direction with quiet pool
                                                                                       ! or 0 if there aren't any.
       cdir = 0;
       objectloop (i ofclass CompassDirection)
       {
               temp = i.door_dir;
               if (ValidDir(room, i))
               {
                       if (IsQuietPool(temp))
                       {
                               cdir = i;
                       }
               }
       }
       return cdir;
];

[ WaterRoom room cond cdir i temp temp2;        ! Return dir to water room meeting cond
       cdir = 0;
       objectloop (i ofclass CompassDirection)
       {
               temp = i.door_dir;
               if (ValidDir(room, i))
               {
                       temp2 = room.temp;
                       if (temp2 has river)
                       {
                               if (cond == 2 && FindCeiling(player) == temp2)
                                       return i;
                               if (cond == 1 && FindCeiling(player) ~= temp2)
                                       return i;
                               if (cond == 0 && random(2) == 1)
                                       cdir = i;
                               if (cond == 0 && cdir == 0)
                                       cdir = i;
                       }
               }
       }
       return cdir;
];

[ NearbyRegion room i temp temp2;                                               ! A region nearby?
       objectloop (i ofclass CompassDirection)
       {
               temp = i.door_dir;
               if (ValidDir(room, i))
               {
                       temp2 = room.temp;
                       if (temp2.region > 0 && WhatLevel(room) == WhatLevel(temp2))
                               return temp2;
               }
       }
       rfalse;
];

[ NearbyVast room i temp temp2;                                                 ! A vast room nearby?
       objectloop (i ofclass CompassDirection)
       {
               temp = i.door_dir;
               if (ValidDir(room, i))
               {
                       temp2 = room.temp;
                       if (temp2.size > 5 && WhatLevel(room) == WhatLevel(temp2))
                               rtrue;
               }
       }
       rfalse;
];

[ WindExitFrom room i c num temp temp2 choice d;                ! Return the direction to
                                                                                                               ! faster wind (from room)
       choice = 0;
       d = -100;
       num = SNumExits(room);
       for (i = 1: i <= num: i++)
       {
               objectloop (c ofclass CompassDirection)
               {
                       temp = c.door_dir;
                       if (ValidDir(room, c))
                       {
                               temp2 = room.temp;
                               if (temp2.wind >= d)
                               {
                                       if (temp2.wind > d || random(2) == 1)
                                       {
                                               choice = c;
                                               d = temp2.wind;
                                       }
                               }
                       }
               }
       }
       return choice;
];

[ IsQuietPool room;                                                                             ! Is there a quiet pool in room?
       if (room has river && room.speed < 7)
               return TRUE;
       return FALSE;
];

[ WindExitTo room i c num temp temp2 choice d;                  ! Return the direction to
                                                                                                               ! slower wind (from room)
       choice = 0;
       d = room.wind;
       num = SNumExits(room);
       for (i = 1: i <= num: i++)
       {
               objectloop (c ofclass CompassDirection)
               {
                       temp = c.door_dir;
                       if (ValidDir(room, c))
                       {
                               temp2 = room.temp;
                               if (temp2.wind < d && temp2.wind > 0)
                               {
                                       choice = c;
                                       d = temp2.wind;
                               }
                       }
               }
       }
       return choice;
];

[ LowestWaterExit room i c num temp temp2 choice d;             ! Return the direction to
                                                                                                               ! lowest water exit
                                                                                                               ! From given room
       choice = 0;
       d = 0;
       num = WaterExits(room, 0);
       for (i = 1: i <= num: i++)
       {
               objectloop (c ofclass CompassDirection)
               {
                       temp = c.door_dir;
                       if (ValidDir(room, c))
                       {
                               temp2 = room.temp;
                               if (room.temp has river)
                               {
                                       if (temp2.depth > d)
                                       {
                                               choice = c;
                                               d = temp2.depth;
                                       }
                               }
                       }
               }
       }
       return choice;
];

[ NextUpDown room dir c temp temp2 best bestnum;                ! Return up or down room
                                                                                                               ! dir 1 = up, dir 0 = down
       bestnum = room.conn;

       objectloop (c ofclass CompassDirection)
       {
               temp = c.door_dir;
               if (ValidDir(room, c))
               {
                       temp2 = room.temp;
                       if (dir == 1)
                       {
                               if (temp2.conn >= bestnum)
                               {
                                       bestnum = temp2.conn;
                                       best = c;
                               }
                               if (temp2.conn == bestnum && random(2) == 1)
                               {
                                       bestnum = temp2.conn;
                                       best = c;
                               }
                       }
                       if (dir == 0)
                       {
                               if (temp2.conn < bestnum)
                               {
                                       bestnum = temp2.conn;
                                       best = c;
                               }
                       }
               }
       }
       return best;
];

[ WaterExits room type i num temp temp2;! Return the number of water exits
                                                                               ! From given room and type
                                                                               ! -1 lower, 0 all, 1 higher
       num = 0;
       objectloop (i ofclass CompassDirection)
       {
               temp = i.door_dir;
               if (ValidDir(room, i))
               {
                       temp2 = room.temp;
                       if (room.temp has river)
                       {
                               switch (type)
                               {
                                       -1:     if (temp2.depth >= room.depth)
                                                       num++;
                                       0:      num++;
                                       1:      if (temp2.depth < room.depth)
                                                       num++;
                               }
                       }
               }
       }
       return num;
];

[ SRandom room croom i num pick temp;   ! Return random surrounding room
       croom = room;                                           ! From given room
       num = SNumExits(room);
       pick = random(num);                                     ! Pick a random exit number
       num = 0;

       objectloop (i ofclass CompassDirection)
       {
               temp = i.door_dir;
               if (ValidDir(room, i))
               {
                       num++;
                       if (num == pick)
                               croom = temp;
               }
       }
       return croom;
];

[ Shallowest room croom i shall temp temp2;             ! Return shallowest nearby room
                                                                                               ! (Or self if current is shallowest)
       croom = room;
       shall = room.depth;

       objectloop (i ofclass CompassDirection)
       {
               temp = i.door_dir;
               if (ValidDir(room, i))
               {
                       temp2 = room.temp.depth;
                       if (temp2 < shall)
                       {
                               croom = room.temp;
                               shall = temp2;
                       }
               }
       }
       return croom;
];

[ ExitToRoom room croom i temp;                                 ! Discern exit# to get from room
                                                                                               ! to croom.
       objectloop (i ofclass CompassDirection)
       {
               temp = i.door_dir;
               if (i provides dung)
               {
                       if (room.temp == croom)
                       {
                               return i;
                       }
               }
       }
];

[ HaveTiedRope i;                                                               ! Does player have a tied rope?
       objectloop (i in player)
       {
               if (i provides tiedto && i.tiedto > 0)
                       rtrue;
       }
       rfalse;
];

[ RopeToExit room thedir i temp;                                ! Is there a rope to that exit?
                                                                                               ! (Requires room & thedir)
       objectloop (i ofclass Rope)
       {
               if (i in room || i in player)                   ! Holding rope or rope in room
               {
                       if (i.tiedto)
                       {
                               if (ExitToRoom(room, i.tiedto).door_dir == thedir)
                                       rtrue;
                       }
               }
               else                                                                    ! Or rope in destination room
               {                                                                               ! Mainly for "falling into room" stuff
                       temp = room.thedir;
                       if (i in temp)
                       {
                               if (i.tiedto == room)
                                       rtrue;
                       }
               }
       }
       rfalse;
];

[ Deepest room croom i deep temp temp2; ! Return deepest nearby room
                                                                               ! (Or self if current is deepest)
       croom = room;
       deep = room.depth;

       objectloop (i ofclass CompassDirection)
       {
               temp = i.door_dir;
               if (ValidDir(room, i))
               {
                       temp2 = room.temp.depth;
                       if (temp2 > deep)
                       {
                               croom = room.temp;
                               deep = temp2;
                       }
               }
       }
       return croom;
];

[ SHeight room;                                                 ! Return relative height of given room
       return (SSumDepth(room) / SNumExits(room)) - room.depth;
];

[ SSumDepth room temp temp2 sum i;              ! Return sum of surrounding depths for given room
       sum = 0;
       objectloop(i ofclass CompassDirection)                  ! Loop room's exits
       {
               temp = i.door_dir;

               if(ValidDir(room, i))           ! Exit goes anywhere?
               {
                       temp2 = room.temp.depth;                                ! Get other room's depth
                       sum = sum + temp2;                                              ! Add depths together
               }
       }
       return sum;
];

[ SNumExits room temp num i;                            ! Return number of exits for given room
       num = 0;
       objectloop(i in compass)                        ! Loop room's exits
       {
               temp = i.door_dir;
               if(ValidDir(room, i))           ! Exit goes anywhere?
               {
                       num++;
               }
       }
       return num;
];

[ FirstCon room num;                    ! Return first available connection for given room
       num = 6;
       if (room.x5_to == 0)
               num = 5;
       if (room.x4_to == 0)
               num = 4;
       if (room.x3_to == 0)
               num = 3;
       if (room.x2_to == 0)
               num = 2;
       if (room.x1_to == 0)
               num = 1;
       return num;
];

[ NumCon room count;                    ! Return number of connections for given room
       count = 0;
       if (room.x1_to ~= 0)
               count++;
       if (room.x2_to ~= 0)
               count++;
       if (room.x3_to ~= 0)
               count++;
       if (room.x4_to ~= 0)
               count++;
       if (room.x5_to ~= 0)
               count++;
       return count;
];

[ FR room;                                              ! Return room number corrected for FIRSTROOM
       return (FIRSTROOM + room - 1);
];

[ RR room;                                              ! Return room number without FIRSTROOM (start at 1)
       return (room - FIRSTROOM + 1);
];

[ NRL;                                                  ! Return number of rooms in each level
       return (MAXROOMS / 5);
];

[ WhatLevel room;                               ! Return level number of given room **FR first**
       return ((room - FIRSTROOM) / NRL() + 1);
];

[ FLevel level;                                 ! Return the first room of given level
       return FR((level - 1) * NRL() + 1);
];

[ LLevel level;                                 ! Return the last room of given level
       return (FLevel(level) + NRL() - 1);
];

[ RandRoom level;                               ! Return a random room in given level
       return FLevel(level) + random(NRL()) - 1;
];

[ Absl num;
       if (num < 0)
               num = num * (-1);
       return num;
];

[ Nozero num;                                   ! We don't want no stinkin' zero!
       if (num == 0)
               num = 1;
       return num;
];

[ InRiverBag loc x;                             ! An appropriate item in the riverbag?
       objectloop (x in riverbag)      ! requires location.
       {
               if (x.inroom == loc)
                       return x;
       }
       return 0;
];

[ CaveObjectPresent loc x;              ! CaveObject in loc (for spurious line breaks)
       if (loc has river || owind in loc)
               return 0;
       objectloop (x in loc)
       {
               if (x hasnt scenery && x hasnt concealed && x ~= player)
                       return 1;
       }
       return 0;                                               ! Line break
];

[ Health cre;                                   ! Return health of provided creature
       if (cre.strength > 300)
               return (cre.strength * 10) / (cre.topstrength / 10);
       return (cre.strength * 100) / cre.topstrength;
];

[ TSPercent cre;                                ! Return percentage of creature's topstrength
       if (cre.topstrength > 300)
               return (cre.topstrength * 10) / 100;
       return (cre.topstrength * 100) / 1000;
];

[ PercentTwo one two;                   ! Return two's percentage of one
       return ((two * 10) / (one) * 10);
];

[ WeighPercent cre;                             ! Return percentage of weight caried
       return (WeightOf(cre) * 100) / (cre.strength / 2);
];

[ Percent top per;                              ! Return per of top
       return ((top * per) / 100);
];

[ WEPercent obj;                                ! Return percentage of weapon's strengthbonus
       if (obj.strengthbonus > 300)
               return (obj.strengthbonus * 10) / 200;
       return (obj.strengthbonus * 100) / 2000;
];

[ PressKeyRandom k t;                   ! Wait for keypress...
       print "Press any key to continue > ";
       @read_char 1 1 Interrupt -> k;
       for(t=0:t<randseed:t++)                                         ! Scoffed from Jim Fisher.
               random(1);
       return;
];

[ Interrupt;                                    ! ...and increment random seed in the meantime.
       RANDSEED++;
       rfalse;
];

[ AfterPrompt x;                                ! To handle "prepared" games
       if (player in Limbo)
       {
               for (x == 1: x < 6: x++)
                       PrintIntro(x, 0);
               Banner();
               PlayerTo(LOCATION1, FALSE);
               print"^>";
               rtrue;
       }
];

[ FindCeiling obj;                              ! Find the room the object is in!
       do
       {
               if (parent(obj) == nothing)
                       rfalse;
               if (parent(obj) ofclass C_ROOMS)
                       return parent(obj);
               obj = parent(obj);
       }
       until (parent(obj) == nothing);
       rfalse;
];

! ------------------------Grammar routines.

[ ReadSub;
       if (metaclass(noun.text) == string)
               print (string) noun.text;
       else
               noun.text();
];

[ WaitSub;                                                              ! Update sounds, etc.
       LookRoutine();
       if (player.strength + 2 < player.topstrength)
               ChangeStrength(player, 2);
       if (AfterRoutines()==1)
               rtrue;
];

[ SonarSub;
       Surrounding(real_location, 1, 4);
];

[ FillSub;
       "Now is not the time to worry about things like that.";
];

[ GoFishSub;
       if (FindCeiling(player) has river)
               "You were never very good at fishing.";
       "You'd need lots of water to do that.";
];

[ FillFromSub;
       if (noun ~= canteen)
               << Fill noun >>;
       if (second == oriver)
               << Fill canteen >>;
       else
               "You can't fill your canteen with that!";
];

[ SqueezeThroughSub;
       if (noun == sprayer)
               "The sprayer doesn't have enough power to do that sort of thing.  It's
                       meant for exterminating bugs, not for covert assassination!";
       "You can't do that.";
];

[ SqueezeAtSub;
       if (noun == sprayer)
               "The sprayer doesn't have a directed spray...it's meant to poison entire
                       rooms, not to target unlucky individuals.";
       "You can't do that.";
];

[ ThrowThroughSub temp croom cre;
       temp = second.door_dir;
       croom = real_location.temp;
       if (croom == 0)
               "There aren't that many exits.";
       if (noun.weight < 2)
       {
               print (The) noun, ", being light, falls far short of the exit.^";
               keep_silent = TRUE;
               < drop noun >;
               keep_silent = FALSE;
               rtrue;
       }

       if (noun provides tiedto)
       {
               if (noun.tiedto > 0 && noun.tiedto ~= real_location)
                       "The rope gets tangled up and doesn't make it to the exit.";
       }

       print "You throw ", (the) noun, " through exit #", second.num, ".^";
       move noun to croom;
       if (CreaturesPresent(croom) > 0)
       {
               cre = PickCreature(croom);
               if (cre.weight > 5)
                       ObjectHits(noun, cre);
       }
       if (croom has river)
       {
               print "You hear a distant splash.^";
               PutInRiver(noun, croom);
       }
];

[ SwimSub;
       if (SWIMMING)
       {
               print "You are already swimming.^";
       }
       else
       {
               if (real_location has river)
               {
                       print "You step into the water.^";
                       SWIMMING = 1;
                       SwimRoutine(real_location);
               }
               else
               {
                       print "There's no water here to swim in.^";
               }
       }
];

[ SwimStopSub;
       if (SWIMMING)
       {
               print "You climb out of the water.^";
               LeaveWater();
       }
       else
       {
               print "You're not in the water.^";
       }
];

[ GoNumSub i temp temp2 chosen;                                 ! Form "Go (num)"
       if (FR(noun) == real_location)
               "You are already in that room.";
       objectloop(i in Compass)
       {
               temp = i.door_dir;
               temp2 = real_location.temp;
               if(real_location.temp == FR(noun))
                       chosen = i;
               if(ValidDir(real_location, i) && temp2.region == FR(noun))
                       chosen = i;
       }

       if (chosen)
               <<Go chosen>>;
       "No exits lead to that room.";
];

[ JumptoSub;                                                                    ! Form "Jumpto (num)"
       if (FR(noun) ofclass C_ROOMS)
               PlayerTo (FR(noun), 0);
       else
               "That's not a valid room!";
       ForfeitSub();
       rtrue;
];

[ ReturnSub;                                                                    ! Retrace
       if (LASTROOM == real_location || LASTROOM == 0)
               "You can't seem to retrace your steps.";
       noun = RR(LASTROOM);
       inp1 = 1;
       GoNumSub();
];

[ ShowNumOnSub;
       SHOWNUM = 1;
       "Room numbers are turned ON.";
];

[ ShowNumOffSub;
       SHOWNUM = 0;
       "Room numbers are turned OFF.";
];

[ ExploreOnSub;
       EXPLORE = 1;
       print "Exploration mode turned ON.^";
       ForfeitSub();
       rtrue;
];

[ ExploreOffSub;
       EXPLORE = 0;
       "Exploration mode turned OFF.";
];

[ EcoOnSub;
       ECO = 1;
       print "Ecosystem display ON.^";
       ForfeitSub();
       rtrue;
];

[ EcoOffSub;
       ECO = 0;
       "Ecosystem display OFF.^";
];

[ NomonsterSub x;                                                               ! Remove all monsters
       objectloop (x ofclass Creature)
       {
               while (child(x))
                       move child(x) to FindCeiling(x);        ! Drop their stuff...
               move x to creaturebag;                                  ! Move them away
       }
       StopDaemon(CDaemon);                                            ! Stop their AI
       Eggsack.oomf = 0;
       Eggsack.countdown = 0;                                          ! Neutralize Eggsack
       print "Gosh, it's quiet around here all of a sudden...^";
       ForfeitSub();
];

[ ForfeitSub;
       if (FORFEIT == 0)
               print "Your score function is now disabled.^";
       FORFEIT = 1;
];

[ RestartSub;
       "Every day we ask ourselves, ~Wouldn't it be nice to be able to do it all over again?~
               Sadly, that's just not the way life is.";
];

[ HelpSub;
       if (noun)
       {
               switch (noun)
               {
                       1:
                               print "WUMPUS 2000 INTRODUCTION^^
                                       The caverns you've been dropped into consist of 100 interconnecting
                                       caves on five different levels.  Each cave is connected to at least
                                       one other cave by one or more exits.  In some cases, the caves are
                                       actually parts of larger 'regions' within the caverns, and
                                       sometimes these regions have features which make them distinctive.^^
                                       The object of the game is to find the exit and manage to escape
                                       through it.  To do this, you'll need to build up your strength and
                                       supplies, fight the cavern denizens, and actually find the exit
                                       itself.  Your final score will depend upon the amount of
                                       exploration you've done, the monetary worth of your possessions,
                                       and how successful you were in escaping.^^
                                       While playing the game it's important to keep an eye on your
                                       health (which is displayed on the status bar).  Your health
                                       determines your effectiveness in combat, how well you can traverse
                                       difficult passageways, and how much weight you can carry.  Your
                                       health is displayed as a percentage of your current maximum health...
                                       100% health is very different for a player whose maximum health is
                                       low, as it is in the beginning of the game.
                                       Certain objects in the cave will increase your maximum health or your
                                       current health.^^
                                       As you move around the caves you will often hear sounds through
                                       the exits, telling you which creatures are nearby and how close
                                       they are.  If a louder noise interferes with a quieter one, though,
                                       you will not be told about the quieter one.^";
                       2:
                               print "MOVING AROUND THE CAVES^^
                                       Each room has at least one exit leading to another room.  All exits
                                       are referred to as 'x' followed by the exit number...for instance,
                                       exit one is 'x1'.  Simply typing that will start you in the direction
                                       of that exit.^^
                                       If you have been through one of the exits previously, you can also
                                       refer to the room number it leads to.  For instance, you can type
                                       ~go 24~ to move to room 24 (provided there is a room in that
                                       direction).  You can also type ~back~ to retrace your footsteps
                                       (~**~ will appear next to the exit you last came from).^^
                                       Regions are slightly more difficult to navigate, as they are actually
                                       single large rooms with multiple sections within them.  For that
                                       reason they are referred to by a common room number, and the
                                       clues you are given about the other sections of the regions are more
                                       ambiguous.^^
                                       If an exit leads to another level in the cave, you will not be told
                                       anything about the room at the other end as it is too far away.^^
                                       Just because there is an exit to another room doesn't mean you can
                                       reach it.  If there is water between you and it you must ~swim~ to
                                       get there (use ~exit~ to finish swimming, though this is done
                                       automatically if you move to a room without water).  If the exit
                                       is particularly steep you might have trouble climbing it...this will
                                       depend on your strength and the steepness of the incline.^^
                                       Resting will restore your strength if you are not in a very
                                       cold or hot room, but keep in mind that the rest of the caves
                                       are active even when you aren't...^";
                       3:
                               print "OBJECTS^^
                                       The caverns are full of objects, either naturally ocurring or left
                                       there by previous explorers.  They can be picked up and used...
                                       though not only by you!^^
                                       There is no limit to the number of objects you can carry, but
                                       you must always keep track of their total weight.  The amount of
                                       weight you can carry depends on your current strength, and if
                                       you become injured you may begin to drop things.  Examining an
                                       object will tell you its weight and monetary value.  The total
                                       weight and value of your objects is also shown in your inventory.^^
                                       Food and weapons are important to keep track of.  Weapons
                                       will increase your ability to attack creatures, defend against
                                       attacks, and will also increase the damage you can do.  Examining
                                       a weapon will tell you how effective a weapon it is, compared to
                                       the best kind you could possibly find.^^
                                       You may also find ropes in the caves.  These ropes can be tied to
                                       features in the cave (a simple ~tie rope~ is the best way to do
                                       this), and can help you deal with steep passages or rushing
                                       water.  Ropes can only stretch between two rooms, and are only
                                       useful to you if you are holding on to one.^";
                       4:
                               print "CREATURES & COMBAT^^
                                       While some of the creatures in the caves do not wish to harm you
                                       (and some may even help you), most of them are either predators
                                       or are downright evil, and all of them will attack if they are
                                       wounded.  Some are effective bloodhounds and will follow your
                                       footsteps throughout the caves...crossing a river will sometimes
                                       throw them off.^^
                                       You can attack these monsters, and the
                                       results of your attacks will depend on your strength, the
                                       strength of the monster, and any weapons that the two of you
                                       are using.  You can choose to attack with a specific weapon.  If
                                       you do not specify a weapon and you are currently carrying one,
                                       the most effective weapon will be automatically used.  Keep in mind,
                                       however, that weapons aren't useful against smaller monsters.^^
                                       Some monsters carry objects, which they will leave behind when
                                       they are killed.^";
                       5:
                               print "SPECIAL COMMANDS^^
                                       Here are a few commands available to help you configure your
                                       game:^^
                                       ~shownum on/off~ will either show or hide the room numbers.  This
                                       is on by default.  If you want a really challenging game, give it
                                       a try.^^
                                       ~explore on/off~ toggles the exploration mode, which is normally
                                       off.  This mode will allow you to explore the caves without
                                       ever getting hungry, thirsty, or injured by creatures, and it will
                                       keep your glow bar's battery from running down.  Turning
                                       this on will forfeit your score.^^
                                       ~boost~ will give your strength and glow bar battery a temporary
                                       lift, and will also remove your hunger and thirst.  This will
                                       also forfeit your score.^^
                                       ~nomonsters~ will clear all of the monsters out of the caves (except
                                       for the fish), giving
                                       you a relatively quiet game.  It will forfeit your score
                                       as well.^^
                                       ~prepare~ will set up a game for others to play in the future.
                                       If you want to create a pre-made game with maps and information
                                       that you can give to others: begin a new game, save it immediately,
                                       explore the caves and map them.  Then, restore your game (so that
                                       the player is back at the beginning) and type ~prepare.~  This
                                       will put the game in a prepared state and save it.  Then, when a
                                       user restores it, all of the opening text will be displayed, giving
                                       your saved game a proper introduction (so it doesn't look like it
                                       was restored).  This was how the sample game was prepared.^";
                       default:
                               print "There is no topic number ", noun, ".^";
               }
       }
       else
               print "WUMPUS 2000 HELP^^
                       There are several different help topics available.  To access them,
                       type ~help~ and then the number of the topic you'd like to read.  For
                       instance, to learn how to get around in the caves, type ~help 2.~^^
                       1. Wumpus 2000 Introduction^
                       2. Moving Around The Caves^
                       3. Objects^
                       4. Creatures & Combat^
                       5. Special Commands^";
];

[ TieSub;
       if (noun provides tiedto)
       {
               if (noun.tiedto > 0)
                       "It's already tied to something!  You'll need to untie it first.";
               noun.tiedto = real_location;
               "You tie it to a suitable part of the cave.";
       }
       "You can't tie that!";
];

[ TieSpecificSub;
       if (noun provides tiedto)
               print "You search around for something better to tie it to.^";
       TieSub();
       rtrue;
];

[ UntieSub;
       if (noun provides tiedto)
       {
               if (noun.tiedto == 0)
                       "It isn't tied to anything!";
               noun.tiedto = 0;
               "You untie the rope.";
       }
       "That's not something you can tie or untie!";
];

[ BendSub;
       if (noun provides weight)
       {
               if (noun.weight < 5)
                       "You bend ", (the) noun, " a bit, which is amusing.";
               else
                       "Bending ", (the) noun, " seems a waste of time and strength.";
       }
       "That's not something you can bend.";
];

[ ClimbDownSub;
       "You can't climb that!";
];

[ ClimbOutSub;
       "You can't climb out of that!";
];

[ SurviveSub;
       player.strength = player.topstrength * 2;
       player.thirst = 100;
       player.hunger = 100;
       glowbar.BATTERY = MAXBATTERY;
       print "You feel very secure, all of a sudden...^";
       ForfeitSub();
];

[ PrepareSub;
       PlayerTo(Limbo);
       << Save >>;
];

[ IsFungus;
       if (noun == ofungus)
       {
               rtrue;
       }
       rfalse;
];

[ IsRiver;
       if (noun == oriver)
       {
               rtrue;
       }
       rfalse;
];

[ IsNote;
       if (noun provides text)
       {
               rtrue;
       }
       print "There's nothing to read on that.^";
       rfalse;
];

[ EatFungusSub;
       "Never look at this message!^";
];

! ----------------------------------------------------------------------------
! Grammar
!
! The grammar section includes the file "Grammar" and will later include
! extensions to the standard grammar library.
! ----------------------------------------------------------------------------

Include "Grammar";

Verb meta 'shownum' 'sn'
       * 'on'                                                                                          -> ShowNumOn
       * 'off'                                                                                         -> ShowNumOff
       *                                                                                                       -> ShowNumOn;

Verb meta 'sonar'
       *                                                                                                       -> Sonar;

Verb meta 'explore'
       * 'on'                                                                                          -> ExploreOn
       * 'off'                                                                                         -> ExploreOff
       *                                                                                                       -> ExploreOn;

Verb meta 'ecosystem'
       * 'on'                                                                                          -> EcoOn
       * 'off'                                                                                         -> EcoOff
       *                                                                                                       -> EcoOn;

Verb meta 'nomonster'
       *                                                                                                       -> Nomonster;

Verb meta 'boost'
       *                                                                                                       -> Survive;

Verb meta 'prepare'
       *                                                                                                       -> Prepare;

Extend 'go'
       * number                                                                                        -> GoNum
       * 'to' number                                                                           -> GoNum
       * 'to' 'room' number                                                            -> GoNum
       * 'to' 'room' 'number' number                                           -> GoNum
       * 'to' 'number' number                                                          -> GoNum
       * 'number' number                                                                       -> GoNum
       * 'back'                                                                                        -> Return
       * 'fish'                                                                                        -> GoFish
       * 'fishing'                                                                                     -> GoFish;

Verb meta 'jumpto'
       * number                                                                                        -> Jumpto;

Verb 'return' 'back'
       *                                                                                                       -> Return;

Verb meta 'help' 'h' '?'
       *                                                                                                       -> Help
       * number                                                                                        -> Help;

Extend 'attack' replace
       * creature                                                                                      -> Attack
       * noun                                                                                          -> Attack
       * creature 'with' held                                                          -> AttackWeapon
       * noun 'with' held                                                                      -> Attack;

Extend 'swim'
       * 'in' noun=IsRiver                                                                     -> Swim
       * 'in' 'the' noun=IsRiver                                                       -> Swim
       * 'across' noun=IsRiver                                                         -> Swim
       * 'across' 'the' noun=IsRiver                                           -> Swim;

Extend 'throw' replace
       * multiheld                                                                                     -> Drop
       * multiheld 'in' / 'into' / 'down' / 'through'
               / 'at' noun=ADirection                                                  -> ThrowThrough
       * multiexcept 'in'/'into'/'down' noun                           -> Insert
       * multiexcept 'on'/'onto' noun                                          -> PutOn
       * held 'at'/'against'/'on'/'onto' noun                          -> ThrowAt;

Verb 'fire' 'spray'
       * noun                                                                                          -> Squeeze
       * noun 'in' / 'into' / 'down' / 'through'
               / 'at' noun=ADirection                                                  -> SqueezeThrough
       * noun 'at' / 'on' / 'onto' noun                                        -> SqueezeAt;

Extend 'squeeze'
       * noun 'in' / 'into' / 'down' / 'through'
               / 'at' noun=ADirection                                                  -> SqueezeThrough
       * noun 'at' / 'on' / 'onto' noun                                        -> SqueezeAt;

Extend 'leave' first
       * noun=IsRiver                                                                          -> SwimStop;

Extend 'exit' first
       * noun=IsRiver                                                                          -> SwimStop;

Extend 'eat' first
       * noun=IsFungus                                                                         -> EatFungus;

Extend 'climb'
       * 'into' noun                                                                           -> Climb
       * 'down' noun                                                                           -> ClimbDown
       * 'out' 'of' noun=IsRiver                                                       -> SwimStop
       * 'out' 'of' noun                                                                       -> ClimbOut
       * 'out' noun=IsRiver                                                            -> SwimStop;

Verb 'descend'
       * noun                                                                                          -> ClimbDown;

Verb 'stop' 'cease' 'finish'
       * 'swimming'                                                                            -> SwimStop;

Verb 'fish'
       *                                                                                                       -> GoFish
       * 'in' noun=IsRiver                                                                     -> GoFish
       * 'from' noun=IsRiver                                                           -> GoFish;

Extend 'drink'
       * 'from' noun                                                                           -> Drink
       * 'water' 'from' noun                                                           -> Drink;

Extend 'fill'
       * noun 'with'/'from' noun                                                       -> FillFrom;

Extend 'read' replace
       * noun=IsNote                                                                           -> Read
       * 'about' topic 'in' noun                                                       -> Consult
       * topic 'in' noun                                                                       -> Consult;

Extend 'eat' replace
       * noun                                                                                          -> Eat;

Extend 'tie' replace
       * noun                                                                  -> Tie
       * 'up' noun                                                                                     -> Tie
   * noun 'to' noun                                                    -> TieSpecific
   * 'up' noun 'to' noun                                                               -> TieSpecific;

Verb 'untie' 'loosen' 'release' 'coil'
       * noun                                                                                          -> Untie
       * 'up' noun                                                                                     -> Untie
       * noun 'from' noun                                                                      -> Untie;

Verb 'bend'
       * noun                                                                                          -> Bend;

Extend 'dig'
       * 'in'  noun                                                                            -> Dig
       * 'in' 'the' noun                                                                       -> Dig;