! 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;
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...
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 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
"^^^^";
];
[ 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!^";
];
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;
}
];
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 (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.";
}
];
[ 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;
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);
}
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;
[ 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;
];
[ 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;
}
}
}
];
[ 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 "^";
];
[ 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 (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;
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;
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;
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);
}
}
[ 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));
];
[ 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);
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
[ 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;
];
[ 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;
];
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;
[ 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;
];
[ 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;
];
[ 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();
];
[ 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();
];
[ 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.
! ----------------------------------------------------------------------------