! To compile, might I suggest: ! -d2 -s -~S -x \$MAX_INDIV_PROP_TABLE_SIZE=30000 \$MAX_PROP_TABLE_SIZE=20000 wumpus2000 Constant Story "Wumpus 2000"; Constant Headline "^The Virulent Labyrinth Of Yob-Shuggoth^ Copyright 2004 by Muffy St. Bernard.^^ ! Type 'help' for tips, hints and special features !^^"; ! Using mazegame.inf code (September 20, 2001) ! Version 1.0 (September 13, 2002) ! Version 1.1 (January 22, 2003) ! Version 1.2 (February 21, 2003) ! Version 1.3 (April 21, 2003) ! Version 1.4 (July 18, 2003) ! TODO: ! Inventory group jewels ! "plug hole" ! "flip coin" ! Mugwump, Schmoo ! "x walls" !---------------------------------------------------------------------------- ! Define global variables !---------------------------------------------------------------------------- Replace Swimsub; ! There's lots of swimming in the game... Replace Attacksub; ! ...and lots of attackin'! Replace FillSub; ! For filling your canteen Replace WaitSub; ! To give you updates while waiting. Replace TieSub; ! For tying your rope Replace RestartSub; ! Because this doesn't work, for some reason. Replace DrawStatusLine; ! For our fancy status line. Constant MAXROOMS = 100; ! The maximum number of rooms in the maze Constant MAXBATTERY = 30; ! Maximum charge level of Glow Bar battery. Constant FILLSROOM = 3; ! Cave size below which water fills room. Constant NO_PLACES = 1; ! So user can't use OBJECT or PLACES verbs. Attribute river; ! Room has a river in it. Attribute sink; ! Object will sink when put in water... Attribute dissolve; ! ...and will be destroyed (must also have sink) Attribute poison; ! Room is poisoned. Attribute frozen; ! Very cold room! Global DISEASE; ! The number of turns of disease left. Global FIRSTROOM; ! To hold the first created room's number. Global SWIMMING = 0; ! Whether you are swimming or not. Global LASTROOM = 0; ! The last room you were in (needs RR!) Global TEST = 0; ! In testing mode? Global SHOWNUM = 0; ! Show room numbers in descriptions? Global REGIONSON = 1; ! Complicate things with regions? Global FORFEIT = 0; ! Have you cheated? Global EXPLORE = 0; ! Toggle for EXPLORE mode. Global ECO = 0; ! Ecosystem Display mode Global KILLED = 0; ! Number of dead creatures. Global RANDSEED = 0; ! Random seed number. Global LOCATION1 = 0; ! Starting location. Global LOCATION100 = 0; ! Deepest room in maze. Global FURNACE = 0; ! Furnace room. Global FREEZER = 0; ! Frozen room. Include "Parser"; Object LibraryMessages with before [x add; ListMiscellany: if (lm_n == 1) rtrue; Score: if (deadflag) { ! Add score bonuses... if (FORFEIT) { print "Your scoring function was disabled"; rtrue; } objectloop (x in player) ! ...for items... add = add + x.monworth; score = score + add / 200; score = score + (player.topstrength - 100); ! ...and topstrength. print "In that game you scored a total of "; } else { if (FORFEIT) { print "Your scoring function is disabled"; rtrue; } print "You have so far scored "; } print score, " point"; if (score ~= 1) print "s"; print " in ", turns, " turn"; if (turns~=1) print "s"; rtrue; ]; Include "Verblib"; !------------------------------------------------------------------------------- ! Set Up Classes !------------------------------------------------------------------------------- Class C_ROOMS (120) with describe [; MoveFloatingObjects(); RoomDisplay(self); if (CaveObjectPresent(self) == FALSE) ! Hack: remove spurious print "^"; ! line breaks. rfalse; ], short_name [; print "A"; ExitSize(self); print ","; RoomWall(self); if (self has frozen) print ", frozen"; if (self has river) print ", watery"; PrintRoomType(self); rtrue; ], depth 0, ! # of feet underground / 2 moist 0, ! Room moistness (0 to 100) fungus 0, ! Amount of fungus (0 to 100) bloody 0, ! Bloodiness of room (0 to ?) speed 0, ! Speed of water, if any. size 3, ! Size of room (1 to 7?) footto 0, ! Which exit prints lead to. footfrom 0, ! Which exit prints lead from. conn 0, ! For connection test. byexit 0, ! Which exit the player is standing by. heat 0, ! Heat level (0 to 400) wind 0, ! Wind level (0 to 100) region 0, ! Region room belongs to regiontype 0, ! Type of region (if any) regiondepth 0, ! Depth of region (if any) x1_to 0, ! Exits. x2_to 0, x3_to 0, x4_to 0, x5_to 0, before [ thedir temp; Go: thedir = noun.door_dir; if (noun == e_obj or w_obj or n_obj or ne_obj or nw_obj or s_obj or se_obj or sw_obj) "You don't have a compass and you were a terrible Scout. The best you can do is number the exits and try to remember them that way: x1, x2, x3, for instance."; if (noun == u_obj) { temp = Shallowest(self); if (temp == self) "There are no exits going upwards from this cave."; noun = ExitToRoom(self, temp); thedir = noun.door_dir; if (SNumExits(self) > 1) print "You pick exit #", noun.num, ".^"; } if (noun == d_obj) { temp = Deepest(self); if (temp == self) "There are no exits going downward from this cave."; noun = ExitToRoom(self, temp); thedir = noun.door_dir; if (SNumExits(self) > 1) print "You pick exit #", noun.num, ".^"; } if (self.thedir == FALSE) "There aren't that many exits."; if (player.topstrength / (Nozero(player.strength / 10)) > 50) { if (random(3) == 1) "You're so weak that you collapse!"; } if (GetToExit(self, thedir) == FALSE) ! Get to the exit? rtrue; if (SWIMMING) { if (SwimThroughExit(self, thedir) == FALSE) rtrue; } else { if (WalkThroughExit(self, thedir) == FALSE) rtrue; } LASTROOM = self; ], after [ i snatch playweigh playworth; Go: ! Keep track of footprints if (LASTROOM && noun provides num && SWIMMING == 0) LASTROOM.footto = noun; else { if (SWIMMING && random(3) == 1) LASTROOM.footto = noun; } objectloop (i in player) { if (i ofclass Rope) ! Holding a rope? { if (i.tiedto > 0) ! Tied to something? { if (i.tiedto == LASTROOM) print "You play the rope out after you.^"; else { if (real_location == i.tiedto) print "You coil the rope up behind you.^"; else { print "You can't stretch the rope any further, so you leave it behind.^"; snatch = i; } } } } } if (snatch) move snatch to LASTROOM; if (SWIMMING) { i = LASTROOM.speed - real_location.speed; if (i > 2) { if (i > 4) print "The river slows dramatically as it enters the next room.^"; else print "The river slows down a bit.^"; } if (i < -2) { if (i < -4) print "The river speeds up suddenly as it flows into the next room!^"; else print "The river speeds up a bit.^"; } } if (Whatlevel(LASTROOM) ~= Whatlevel(real_location)) print "You seem to have crossed into a different part of the cave.^"; rfalse; Inv: playweigh = WeightOf(player); playworth = WorthOf(player); if (playweigh > 0) { print "^You are carrying ", playweigh, " lb"; if (playweigh > 1) print "s"; print " of stuff ("; print WeighPercent(player), "% of your current capacity). "; if (playworth) print "It's all worth about $", WorthOf(player), ".^"; else print "You aren't carrying anything of worth.^"; } ], create [; ! ]; Class Features with description "The cave features are awe-inspiring at first, but soon become mundane.", before [; Examine: rfalse; Eat: "You could never be that hungry."; default: "You have more pressing things to do at the moment."; ], has scenery; Class Chute class Features with short_name "vertical chute", description "Either you underestimate the power of mother nature, or this cave feature wasn't created by strictly natural phenomena. It rises sharply upward into the wall, reminding you more of a slide than something formed by lava flows or dripping water.", name 'vertical' 'chute' 'natural' 'slide' 'tunnel' 'hole' 'smooth' 'sharp' 'featureless', clevel 2, ! Level of chute before [; Take: "It's part of the wall."; ], react_before [; Climb, Enter: if (noun == self) "It's too smooth and it rises too sharply."; ], initial "A smooth, featureless chute juts out of the cave wall.", has ~scenery; Class CaveObject with worth 0, ! Degree of worth, 1 to 100 ! IMPORTANT: Worth of 0 will never be ! sought or taken by creatures! ! Good for skeletons, notes, etc. monworth 0, ! Monetary worth (in dollars) inroom 0, ! For riverbag weight 1, ! In lbs. hoarded 0, ! 1, thieves are not interested! after [; Take: self.hoarded = 0; if (self.worth == 0) self.worth = 50; ], react_after [; Examine: if (noun == self) { print "^"; print (The) self, " weighs about "; if (metaclass(self.weight) == routine) print self.weight(); else print self.weight; print " lb"; if (self.weight > 1) print "s"; print ", and you figure it"; if (self.monworth == 0) print " isn't worth anything, moneywise."; else print "'s worth $", self.monworth, "."; if (self provides strengthbonus) { print " In terms of weaponry, it is "; print WEPercent(self), "% the most powerful weapon you can imagine."; } print "^"; } ], before [; ThrowAt: if (self.weight < 2) { print (The) noun, ", being light, falls far short of ", (the) second, ".^"; keep_silent = TRUE; < drop noun >; keep_silent = FALSE; rtrue; } if (second has animate) { ObjectHits(noun, second); keep_silent = TRUE; < drop noun >; keep_silent = FALSE; rtrue; } print "Clunk! Good aim!^"; keep_silent = TRUE; < drop noun >; keep_silent = FALSE; rtrue; ]; Class Key class CaveObject with name 'key', description "There is nothing remarkable about this key.", worth 100, monworth 1, weight 1, turned 0, before [ x mult; Take: if (self in keyhole && door_iron has open) "You can't remove the key while the door is open."; Turn: if (self notin keyhole) "There's no sense in turning the key unless it's in a keyhole."; if (door_iron has open) "The keys won't turn while the door is open."; print "You turn ", (the) self; if (self.turned) { print " and hear a heavy thump within the door.^"; self.turned = 0; if (door_iron hasnt locked) { print "Something inside the door rams home with a metallic clang.^"; give door_iron locked; } } else { print " and hear a polite click.^"; self.turned = 1; if (children(keyhole) == 3) { mult = 1; objectloop (x in keyhole) mult = mult * x.turned; if (mult) { print "Something inside the door slides back!^"; give door_iron ~locked; } } } rtrue; ], has sink; Class Jewel class CaveObject with name 'jewel', color 1, lightness 1, quality 1, short_name [; switch(self.quality) { 1: print "clear"; 2: print "opaque"; 3: print "milky"; 4: print "shimmery"; 5: print "shiny"; 6: print "dull"; } print " "; switch(self.lightness) { 1: print "dark "; 2: print "light "; } switch(self.color) { 1: print "red"; 2: print "orange"; 3: print "yellow"; 4: print "blue"; 5: print "green"; 6: print "violet"; } print " jewel"; rtrue; ], description [; print "This is a "; self.short_name(); print ". Not being a gemologist, you don't know what it's made of...but it looks unnatural.^"; ], parse_name [ n q l c daword; switch(self.quality) { 1: q = 'clear'; 2: q = 'opaque'; 3: q = 'milky'; 4: q = 'shimmery'; 5: q = 'shiny'; 6: q = 'dull'; } switch(self.lightness) { 1: l = 'dark'; 2: l = 'light'; } switch(self.color) { 1: c = 'red'; 2: c = 'orange'; 3: c = 'yellow'; 4: c = 'blue'; 5: c = 'green'; 6: c = 'violet'; } do { daword = NextWordStopped(); if (daword == q || daword == l || daword == c) n++; if (WordInProperty(daword, self, name)) n++; if (daword == 'jewels') { n++; parser_action = ##PluralFound; } } until (daword == -1); return n; ], worth 1, monworth 1, weight 1, has sink; Class Sensor class CaveObject with description [; print "You know exactly how to operate this device, thanks to the ~Nifty New Gadgets~ column you used to edit. This is a small electronic sensor -- the size and shape of a marble -- which sends information about its surroundings back to a receiver. Without the receiver, however, these sensors might as well BE marbles.^^"; print "This sensor has ~", (string) self.snum,"~ engraved on it.^"; ], snum "foo", name 'small' 'electronic' 'sensor' 'marble', worth 45, monworth 75, weight 3, lasttotal 0, has sink proper; Class Rope class CaveObject with description [; print "A length of rough and sturdy rope, woven by smiling dock-workers and stress-tested by overweight SWAT teams. You could easily tie it to something in the cave (there are a multitude of nooks and crannies around), then depend on it to get you out of subsequent pits or torrents of rushing water. Rope like this is so useful that you'd almost consider marrying it.^^ It is "; if (self.tiedto == 0) "not tied to anything at the moment."; if (self.tiedto == real_location) "tied to a suitable part of this cavern."; "tied to something through exit #", ExitToRoom(real_location, self.tiedto).num, "."; ], name 'length' 'rough' 'sturdy' 'rope' 'woven' 'tested' 'dependable' 'useful', before [ croom thedir; Climb: if (self.tiedto == 0) "It's not tied to anything."; if (self.tiedto == real_location) "There rope doesn't go anywhere."; croom = self.tiedto; if (croom.depth > real_location.depth) "The rope goes down from here, not up."; noun = ExitToRoom(real_location, croom); thedir = noun.door_dir; << Go noun >>; ], after [ croom; Drop: if (self.tiedto == 0) rfalse; croom = self.tiedto; if (croom.depth > real_location.depth) { print "The rope slips down through exit #", ExitToRoom(real_location, croom).num, ".^"; move self to croom; rtrue; } Take: if (self.tiedto) "You pick up the end of the rope."; ], specific "rope", ! For differentiating... short_name [; print (string) self.specific, " ("; if (self.tiedto == real_location) { print "tied to a feature in this cave)"; rtrue; } if (self.tiedto == 0) { print "all coiled up)"; rtrue; } print "dangling from exit #", ExitToRoom(real_location, self.tiedto).num, ")"; rtrue; ], plural "ropes", worth 30, monworth 5, weight 4, tiedto 0, article [; if (self in player) print "your"; else print "a"; ]; Class FoodBar class CaveObject, with description "You can pick these food pellets up at any local variety store. Billed as the ~number one protein source for discriminating astronauts,~ you have to agree. At the very least they're nutritious.", name 'food' 'pellet' 'pellets' 'protein' 'tasty' 'nutritious', short_name "food pellet", plural "food pellets", worth 25, weight 1, monworth 2, before [; Eat: if (actor.hunger > 80) "You aren't hungry enough to eat the whole pellet...those things are filling!"; ], after [; Eat: print "Mmmmm...not too bad!^"; EatFood(actor, 80); move self to objectbag; rtrue; ], has edible sink; Class GinkoBar class CaveObject, with description "Ahh, you'd know these things anywhere: it's a Ginko Bar, long touted as the ~number one strength-booster for weight-lifters who don't mind getting disqualified.~ Made from ground ginko -- a kind of lizard, you think -- they provide three months worth of enhanced physical ability. Eat enough of them and you'll feel the cumulative effects of herbal strength. Just keep in mind that traces will show up in your urine even after you're dead, and they HAVE been known to cause extensive brain damage to small children.", name 'food' 'bar' 'ginko' 'bars' 'strength' 'booster' 'lizard' 'herbal', short_name "ginko bar", plural "ginko bars", worth 45, weight 1, monworth 10, before [; Eat: if (actor.hunger > 80) "Honestly, you can't eat another bite...don't be a glutton!"; Smell: "Smells of ginko."; ], after [; Eat: print "Yum...the taste of Ginko Bars always reminds you of your first reptile-kiss!^^"; EatFood(actor, 30); RaiseStrength(actor, 50); move self to objectbag; rtrue; ], has edible sink; Class SmallRock class CaveObject, with description "A rock is a rock is a rock, but this one is round and it fits nicely into your hand. It's light grey, probably made of granite, and it doesn't look like it came from the walls of the cave.", name 'rock' 'round' 'light' 'grey' 'granite' 'stone' 'small', short_name "small rock", plural "small rocks", worth 3, weight 6, monworth 0, after [; Drop: if (random(6) > 1) "The rock clatters to the ground."; move self to ObjectBag; "The rock shatters into tiny pieces when it hits the ground."; ], has sink; Class LargeRock class CaveObject, with description "Where this rock came from is a mystery -- it's probably feldspar, unlike the walls of the cave -- but it just might be useful. A bit heavy and bulky, but aerodynamic as the dickens.", name 'rock' 'feldspar' 'heavy' 'bulky' 'large' 'big' 'aerodynamic' 'stone', short_name "large rock", plural "large rocks", worth 3, weight 20, monworth 0, after [; Drop: if (random(3) > 1) "The rock drops heavily to the ground."; move self to ObjectBag; "The rock shatters into millions of tiny pieces when it hits the ground."; ], has sink; Class Weapon class CaveObject, with strengthbonus 0, ! Bonus added to strength name 'weapon' has sink; Class Barrel with name 'barrel' 'oozing' 'toxic' 'waste', short_name [; if (self.ooze) { MoveFloatingObjects(); print "oozing barrel"; rtrue; } print "barrel"; rtrue; ], description [; print "Now you know where that toxic waste ended up...some of it is in this barrel, which is covered with warning signs like ~Hazard!~ and ~Danger!~ and ~Open this and you might die!~ Even if you were inclined, you can't see any way to open the barrel, though thanks to being carelessly thrown around there's a small hole in the bottom. On the top of the barrel, somebody has written ~"; print (OozeIncrement(self.clevel) * 100) / 160, " proof.~^"; ], before [; Open: "You can't see any way to open the barrel...it was probably never INTENDED to be opened."; Take, Push, Pull: "You manage to shift it around a bit -- just enough to hear something sloshing around inside -- but you don't have a hope of budging it."; ], each_turn [; move obarrelhole to FindCeiling(self); if (self.ooze) { move oooze to FindCeiling(self); move self to FIndCeiling(self); } ], ooze FALSE, clevel 5, time_left 0, time_out [; if (TestScope(self) && self.ooze == FALSE) print "Some toxic liquid oozes out of the hole in the barrel.^"; self.ooze = TRUE; StartTimer(self, random(10 * self.clevel)); ] has light; Class Corpse, class CaveObject, with name 'corpse' 'body' 'grisly' '.blank' '.blank', crename "undefined", creclass 0, type 0, shuffler 0, short_name "undefined", parse_name [; return -1; ], description [; print "This looks like the corpse of a "; if (self provides shuffler && self.shuffler) { PrintCreName(self); print " "; } print (string) self.crename, "."; if (self.eaten) print " All the choice bits and pieces have been gnawed off of it."; print "^"; ], before [; Attack: "You're too late...it's already dead."; Eat: if (self.eaten) "It's already been picked clean!"; if (actor.hunger > 80) "You're not hungry enough to pick raw flesh off of a corpse...yet."; EatFood(actor, self.weight); self.eaten++; self.weight = self.weight / 2; "It tastes a bit like chicken. Or rather, a chicken that was hatched in the darkest pits of hell."; ], language 1, size 1, eaten 0, weight 50, worth 0, monworth 0, corpseturn 0, body "nada" has sink edible; Class Skeleton, class CaveObject, with name 'skeleton' 'bone' 'bones' 'skull', before [; Eat: "There's little left to eat on the skeleton. Just bones."; Attack: "You're a little too late for that."; Take: if (bone_club in objectbag or riverbag) { print "The thighbone looks like it might be useful...you pick it up.^"; move bone_club to location; << Take bone_club >>; } ], after [; Take: "The skeleton is cumbersome, but you manage to scrape it all together and pick it up."; Drop: "It clatters to the ground."; ], weight 5, worth 0, monworth 15, has sink; Class Note class CaveObject, with name 'note' 'letter' 'scrap' 'of' 'paper', weight 1, worth 0, monworth 0, after [; Eat: "You've tasted better notepaper."; ], has edible sink dissolve; Class Creature ! All creatures must provide... with shuffler 0, ! Shuffle parse & sn? type 1, ! Type # of creature (for parse & sn) crename "blah", ! Text String of creature name. creclass 0, ! Class of creature weight 0, ! Weight of creature strength 0, ! Current strength topstrength 0, ! Highest possible strength lroom 0, ! Last room inhabited speed 33, ! # Chance of move/turn hunger 100, ! How hungry (0 to 100) attackstyle1 "...", ! Attack strings attackstyle2 "...", enterstring "...", ! Coming into a room... leavestring "...", ! ...and leaving it. diestring "...", ! For when it dies. minworth 0, ! Minimum treasure worth ! 0 No treasure ! -1 Fixed treasure maxworth 0, ! Maximum treasure worth ! (if minworth -1, this is item number) hiding 0, ! Hidden in the water. willfight 0, ! For prey: willing to fight? leavecorpse 1, ! Leave a corpse behind? rebirth 10, ! % Chance of rebirth inlevel 0, ! Level it is generated in ! (0 = let designer generate it!) AIStyle 1, ! 1 Fungus eater, prey ! 2 Footprint follower, predator ! 3 Pool hider ! 4 Thief, prey ! 5 Boga ! 6 Cinderbugs ! 7 Compressor ! 8 Baby short_name [; if (self provides shuffler && self.shuffler) { PrintCreName(self); print " "; } print (string) self.crename; if (self ofclass Corpse) print " corpse"; rtrue; ], parse_name [ q n daword; if (parser_action == ##TheSame) return -2; if (self provides hiding && self.hiding) return 0; if (self ofclass Corpse) { if (action == ##Attack && CreaturesPresent(real_location) > 1) return 0; } q = ParseCreName(self); do { daword = NextWordStopped(); if (q && daword == q) n++; if (WordInProperty(daword, self, name)) n++; } until (daword == -1); return n; ], before [; Attack: rfalse; ], react_after [; Examine: if (noun == self) { print "^"; PrintCreCompare(player, self); } ], life [; WakeOther: "It doesn't seem like anything in these caves actually sleeps."; Kiss: print (The) self, " does not consent.^"; rtrue; Give, Show: print (The) self, " is not interested.^"; rtrue; Ask, Tell, Answer, Order: print (The) self, " has no idea what you're talking about.^"; rtrue; ], name 'creature' 'monster' 'beast'; !Class Actions ! with ! startmsg 0, ! currentmsg 0, ! conditions ! [; ! return 0; ! ], ! noisy 0, ! Is the action noisy? ! result 0, ! -20 to 20 ! change FALSE; ! All creatures that are part of their own class should have '.blank' as their first ! name entry, to keep corpses on track... Class Baby ! class Creature, with description "Wah-wah-wah!", name '.blank' 'baby', crename "baby", ! weight 30, ! strength 20, ! topstrength 20, ! attackstyle1 "mushes its gums", ! attackstyle2 "pees", ! enterstring "wobble into the room", ! leavestring "toddles away", ! diestring "grunts and collapses", ! language 1, ! size 1, ! minworth 1, ! maxworth 20, ! prey, ! AIStyle 8, ! speed 15, ! rebirth 0, ! inlevel 3, ! happy 100, ! 0 to 100 ! change 1, ! direction of change ! desire 0, ! action they will probably take ! last 0, ! last action ! desirenum 0, ! 0 to 100 ! life ! [; ! WakeOther: ! "Even if the baby were sleeping, why on earth would you want to do that?"; ! Kiss: ! print (The) self, " does not consent.^"; ! rtrue; ! Give, Show: ! print (The) self, " snatches it away!^"; ! move noun to self; ! rtrue; ! Ask, Tell, Answer, Order: ! print (The) self, " has no idea what you're talking ! about.^"; ! rtrue; ! ], ! short_name ! [; ! switch(self.size) ! { ! 1: print "gaunt"; ! 2: print "bony"; ! 3: print "sinewy"; ! 4: print "flabby"; ! 5: print "chubby"; ! 6: print "plump"; !/ 7: print "fat"; !/ 8: print "obese"; !/ } !/ print " "; !/ switch(self.language) !/ { !/ 1: print "English"; !/ 2: print "Arabic"; !/ 3: print "Spanish"; !/ 4: print "Italian"; !/ 5: print "Greek"; !/ 6: print "Chinese"; !/ 7: print "Indian"; !/ 8: print "Mimac"; !/ 9: print "Russian"; !/ 10: print "Swedish"; !/ } !/ print " baby "; !/ if (self has female) !/ print "girl"; !/ else !/ print "boy"; !/ if (self ofclass Corpse) !/ print " corpse"; !/ rtrue; !/ ], !/ sayhello !/ [ ; !/ switch (self.language) !/ { !/ 1: print "hi"; !/ 2: print "marhaban"; !/ 3: print "hola"; !/ 4: print "buon giorno"; !/ 5: print "kalimera"; !/ 6: print "ni hao"; !/ 7: print "namaste"; !/ 8: print "k'we"; !/ 9: print "zdravstvuite"; !/ 10: print "god dag"; !/ } !/ ], !/ saygoodbye !/ [ ; !/ switch (self.language) !/ { !/ 1: print "bye"; !/ 2: print "il@^a l-liq@^a"; !/ 3: print "adi@'os"; !/ 4: print "arrivederci"; !/ 5: print "yassou"; !/ 6: print "joi gin"; !/ 7: print "accha"; !/ 8: print "nmu'ltes"; !/ 9: print "do svidanja"; !/ 10: print "hejd@oa"; !/ } !/ ], !/ each_turn !/ [ msg; !/ if (self.last == self.desire) !/ { !/ msg = self.last; !/ if (msg && metaclass(msg.currentmsg) == string) !/ print (The) self, " ", (string) msg.currentmsg,".^"; !/ } !/ else !/ self.last = self.desire; !/ ], !/ parse_name !/ [ q l c n daword; !/ if (parser_action == ##TheSame) !/ return -2; !/ if (self ofclass Corpse) !/ { !/ if (action == ##Attack && CreaturesPresent(real_location) > 1) !/ return 0; !/ } !/ switch(self.size) !/ { !/ 1: q = 'gaunt'; !/ 2: q = 'bony'; !/ 3: q = 'sinewy'; !/ 4: q = 'flabby'; !/ 5: q = 'chubby'; !/ 6: q = 'plump'; !/ 7: q = 'fat'; !/ 8: q = 'obese'; !/ } !/ if (self has female) !/ l = 'girl'; !/ else !/ l = 'boy'; !/ switch(self.language) !/ { !/ 1: c = 'English'; !/ 2: c = 'Arabic'; !/ 3: c = 'Spanish'; !/ 4: c = 'Italian'; !/ 5: c = 'Greek'; !/ 6: c = 'Chinese'; !/ 7: c = 'Indian'; !/ 8: c = 'Mimac'; !/ 9: c = 'Russian'; !/ 10: c = 'Swedish'; !/ } !/ do !/ { !/ daword = NextWordStopped(); !/ if (daword == q || daword == l || daword == c) !/ n++; !/ if (WordInProperty(daword, self, name)) !/ n++; !/ } !/ until (daword == -1); !/ return n; !/ ], !/ before !/ [; !/ Take: !/ move self to player; !/ "You pick up the baby."; !/ ], has animate transparent; Class Grubling class Creature, with description "These enormous, pale, bloated grubs ramble endlessly around the caves looking for fungus to eat. They move surprisingly fast, considering they have no arms or legs, and they seem able to perceive their environment without any sensory organs that you can dream of.", name '.blank' '.blank' 'grubling' 'enormous' 'pale' 'bloated' 'grub' 'grubs' 'rambling' 'gaping' 'maw', shuffler 12, crename "grubling", creclass Grubling, weight 70, strength 80, topstrength 80, attackstyle1 "snaps its gaping maw", attackstyle2 "sprays a misty liquid", enterstring "crawl into the room", leavestring "crawls out of the room", diestring "curls up and dies", minworth 1, maxworth 20, prey, AIStyle 1, rebirth 20, inlevel 2, each_turn [; if (self.willfight == FALSE && random(5) == 1) { print (The) self, " "; switch (random(5)) { 1: "inches around the cavern."; 2: "squishes quietly."; 3: "rears up suddenly."; 4: "flattens to the ground."; 5: "emits a gassy odour."; } } ], has animate; Class Rocker class Creature with description "This base, elemental creature is a collection of all cavernous dangers: spiked hands, grinding teeth, shuddering feet and rolling biceps. It's vaguely humanoid, but looks more like a parody of nature and destruction than anything with a higher purpose.", name '.blank' 'rocker' 'rock' 'smasher' 'base' 'elemental' 'spike' 'spikes' 'spiked' 'hand' 'hands' 'grinding' 'teeth' 'shuddering' 'feet' 'foot' 'tooth' 'rolling' 'bicep' 'biceps' 'humanoid' 'parody', shuffler 8, crename "rocker", creclass Rocker, speed 10, weight 250, strength 400, topstrength 400, attackstyle1 "swats its spikey appendages", attackstyle2 "swings its massive arms", enterstring "crash in", leavestring "retreats", diestring "topples to the ground and shatters", minworth 30, maxworth 50, predator, rebirth 8, leavecorpse 0, inlevel 3, AIStyle 2, each_turn [; if (random(5) == 1) { print (The) self, " "; switch (random(5)) { 1: "throws itself against the cave walls."; 2: "chatters its teeth at you."; 3: "flexes its rocky biceps."; 4: "grins like an idiot."; 5: "rocks slowly back and forth, preparing for something..."; } } ], has animate; Class Reptodon class Creature, with description "Somebody has decided to mix an alligator with a mastodon, and invented something far more vicious than either creature. It's all scales, teeth and tusks, with enough nastiness left over for claws and a cruelly whipping tail.", name '.blank' '.blank' 'reptodon' 'alligator' 'mastodon' 'vicious' 'reptile' 'scales' 'teeth' 'eyes' 'reptilian' 'tusk' 'tusks' 'nasty' 'claws' 'cruel' 'tail' 'cruelly' 'whipping' 'tongue' 'articulated' 'head', shuffler 8, crename "reptodon", creclass Reptodon, speed 25, weight 110, strength 200, topstrength 200, attackstyle1 "bares its teeth", attackstyle2 "slaps its articulated tail", enterstring "slither menacingly", leavestring "retreats", diestring "spasms wildly and dies", minworth 20, maxworth 40, predator, rebirth 5, AIStyle 2, inlevel 4, each_turn [; if (random(5) == 1) { print (The) self, " "; switch (random(5)) { 1: "flicks its tail against the walls of the cave."; 2: "hisses."; 3: "rolls its reptilian eyes at you."; 4: "flicks its claws at your face."; 5: "whips around in a quick circle."; } } ], has animate; Class Guard class Creature, with description "This person looks trained in both offense and defense, but at the same time doesn't look particularly interested in doing either. The guard's expression seems to communicate ~Don't mess with me and I won't mess with you.~", name '.blank' '.blank' 'guard' 'trained' 'expression', shuffler 8, crename "guard", creclass Guard, speed 50, weight 150, strength 400, topstrength 400, attackstyle1 "punches", attackstyle2 "kicks", enterstring "march in", leavestring "marches", diestring "drops heavily to the ground", minworth 20, maxworth 90, predator, rebirth 0, AIStyle 13, inlevel 0, goingup 1, each_turn [; if (random(5) == 1) { print (The) self, " "; switch (random(5)) { 1: "tries to stare you down."; 2: "says ~I'm just doing my job, you see.~"; 3: "says ~I'd rather be seeing this on TV.~"; 4: "asks, ~Why can't you just leave us alone?~"; 5: "expressess admiration for your ~gumption.~"; } } ], has animate proper; Class CinderBug class Creature with description "If these little dots of fire weren't moving so offensively, you'd think they were cinders. They don't look smart or particularly dangerous, but they sure are fast.", name '.blank' 'cinder' 'bug' 'cinderbug' 'little' 'dot' 'dots' 'fire' 'offensive' 'offensively' 'moving', shuffler 15, crename "cinderbug", creclass CinderBug, speed 90, weight 1, strength 5, topstrength 25, attackstyle1 "zips", attackstyle2 "darts", enterstring "zip", leavestring "floats", diestring "winks out, leaving nothing behind", minworth 0, prey, AIStyle 6, leavecorpse 0, rebirth 0, inlevel 0, invent [; if (inventory_stage == 2) rtrue; ], each_turn [; if (random(5) == 1) { print (The) self, " "; switch (random(5)) { 1: "bounces off the walls of the cave."; 2: "makes a high-pitched buzzing sound."; 3: "darts towards you."; 4: "draws a figure-eight in the air."; 5: "zooms back and forth, dazzling you."; } } ], has animate light; Class Beetle class Creature with description [; print "This smooth, red beetle is about the size of a dinner plate, and is crouched down in the middle of the cave, staring at you expectantly. A loud ticking noise is coming from inside its belly, which is marked with the words:"; print " ~", (name) self, ".~^"; ], name 'smooth' 'red' 'beetle' 'crouching' 'staring' 'belly' 'loud' 'ticking' 'noise', article "the", crename "beetle", creclass Beetle, speed 25, weight 5, strength 50, topstrength 50, attackstyle1 "nibbles", attackstyle2 "snaps", enterstring "scrabble", leavestring "scuttles", diestring "turns on its back and crumbles away", prey 1, minworth 0, AIStyle 9, leavecorpse 0, rebirth 0, inlevel 0, each_turn [; if (random(5) == 1) { print (The) self, " "; switch (random(5)) { 1: "shifts itself slightly."; 2: "speeds up its ticking sound."; 3: "puffs up threateningly."; 4: "seems to wonder what to do about you."; 5: "makes a quick crackling noise."; } } ], has animate; Class Quickpaw class Creature with description "Shaped like an ape, but extremely pale and with no hair whatsoever...where did this creepy thing come from? Its enormous eyes dart constantly around the cavern, only occasionally resting on you before bouncing away again. The thing looks crazy and depraved, of little relation to its forest-dwelling ancestors.", name 'ape' 'quickpaw' 'thief' 'extremely' 'pale' 'hairless' 'creepy' 'thing' 'enormous' 'eyes' 'crazy' 'depraved' 'completely' 'unnatural' 'claws' 'fangs', shuffler 8, crename "quickpaw", creclass Quickpaw, speed 90, weight 110, strength 150, topstrength 150, attackstyle1 "scratches its claws", attackstyle2 "snaps its fangs", enterstring "slink into the room", leavestring "ducks", diestring "hollers sadly and crumples to the ground", minworth 0, prey, AIStyle 4, pickup 1, rebirth 15, inlevel 3, life [; Show, Give: if (noun provides worth) { print (The) self, " sneers at you, and snatches ", (the) noun, " right out of your hands.^"; move noun to self; } else print (The) self, " isn't interested in ", (the) noun, ".^"; rtrue; ], each_turn [; if (random(5) == 1) { print (The) self, " "; switch (random(5)) { 1: "looks covetously at your possessions."; 2: "hoots wildly."; 3: "grins at you with wild, insane eyes."; 4: "sneaks around the cave."; 5: "lets loose with a stream of incoherent gibberish."; } } ], has animate; [ PrintCreName cre; ! Print names of all creatures if (cre.creclass == Grubling) { switch(cre.type) { 1: print "black"; 2: print "brown"; 3: print "scruffy"; 4: print "scabby"; 5: print "grey"; 6: print "jittery"; 7: print "scary"; 8: print "twitchy"; 9: print "mangy"; 10: print "piebald"; 11: print "sneaky"; 12: print "fast"; } } if (cre.creclass == Rocker) { switch (cre.type) { 1: print "rumbling"; 2: print "grinding"; 3: print "tumbling"; 4: print "groaning"; 5: print "creaking"; 6: print "cracking"; 7: print "stumbling"; 8: print "crashing"; } } if (cre.creclass == Reptodon) { switch (cre.type) { 1: print "writhing"; 2: print "twisty"; 3: print "rattly"; 4: print "hissy"; 5: print "swaying"; 6: print "striking"; 7: print "crawling"; 8: print "hungry"; } } if (cre.creclass == CinderBug) { switch (cre.type) { 1: print "flickering"; 2: print "scintillating"; 3: print "winking"; 4: print "blinking"; 5: print "pulsing"; 6: print "manic"; 7: print "frantic"; 8: print "excitable"; 9: print "whirling"; 10: print "burning"; 11: print "flaming"; 12: print "fiery"; 13: print "hot"; 14: print "darting"; 15: print "flashing"; } } if (cre.creclass == Quickpaw) { switch (cre.type) { 1: print "pale"; 2: print "sickly"; 3: print "albino"; 4: print "jaundiced"; 5: print "quiet"; 6: print "wild"; 7: print "corrupt"; 8: print "greedy"; } } if (cre.creclass == Guard) { switch (cre.type) { 1: print "Dana the"; 2: print "Laurie the"; 3: print "Nikkie the"; 4: print "Frida the"; 5: print "Andy the"; 6: print "Clint the"; 7: print "Nash the"; 8: print "Ryan the"; } } ]; [ ParseCreName cre q; ! Help parse names of creatures if (cre.creclass == Grubling) { switch(cre.type) { 1: q = 'black'; 2: q = 'brown'; 3: q = 'scruffy'; 4: q = 'scabby'; 5: q = 'grey'; 6: q = 'jittery'; 7: q = 'scary'; 8: q = 'twitchy'; 9: q = 'mangy'; 10: q = 'piebald'; 11: q = 'sneaky'; 12: q = 'fast'; } } if (cre.creclass == Rocker) { switch (cre.type) { 1: q = 'rumbling'; 2: q = 'grinding'; 3: q = 'tumbling'; 4: q = 'groaning'; 5: q = 'creaking'; 6: q = 'cracking'; 7: q = 'stumbling'; 8: q = 'crashing'; } } if (cre.creclass == Reptodon) { switch (cre.type) { 1: q = 'writhing'; 2: q = 'twisty'; 3: q = 'rattly'; 4: q = 'hissy'; 5: q = 'swaying'; 6: q = 'striking'; 7: q = 'crawling'; 8: q = 'hungry'; } } if (cre.creclass == CinderBug) { switch (cre.type) { 1: q = 'flickering'; 2: q = 'scintillating'; 3: q = 'winking'; 4: q = 'blinking'; 5: q = 'pulsing'; 6: q = 'manic'; 7: q = 'frantic'; 8: q = 'excitable'; 9: q = 'whirling'; 10: q = 'burning'; 11: q = 'flaming'; 12: q = 'fiery'; 13: q = 'hot'; 14: q = 'darting'; 15: q = 'flashing'; } } if (cre.creclass == Quickpaw) { switch (cre.type) { 1: q = 'pale'; 2: q = 'sickly'; 3: q = 'albino'; 4: q = 'jaundiced'; 5: q = 'quiet'; 6: q = 'wild'; 7: q = 'corrupt'; 8: q = 'greedy'; } } if (cre.creclass == Guard) { switch (cre.type) { 1: q = 'Dana'; 2: q = 'Laurie'; 3: q = 'Nikkie'; 4: q = 'Frida'; 5: q = 'Andy'; 6: q = 'Clint'; 7: q = 'Nash'; 8: q = 'Ryan'; } } return q; ]; !---------------------------------------------------------------------------------------- ! ADVENTURELAND !---------------------------------------------------------------------------------------- ! Your very own custom player...for the sake of generalized code. Object CustomPlayer with attackstyle1 "punch", attackstyle2 "kick", weight 150, speed 100, hiding 0, willfight 1, prey, predator, strength 75, topstrength 100, hunger 100, thirst 100; ! Hardwired locations & objects C_ROOMS EndRoom "The last room!" has light; Object Limbo "Press Enter To Begin" ! First room, for saving. with description "Press Enter To Begin", each_turn [ x; for (x == 1: x < 6: x++) PrintIntro(x, 0); Banner(); PlayerTo(LOCATION1, FALSE); rtrue; ], has light; Object Door_iron "iron door" with d1room 0, d1dir 0, d2room 0, d2dir 0, description [; print "This is not the place you'd expect to find a door, but here it is, snugly built to block this exit. Somebody thought it was important to put the door here"; if (real_location == self.d1room) ", which makes you suspect that going through it would be a good idea. Maybe there's a way out of the cave? There's a curiously-constructed keyhole in the center of the door."; else ". This side of it is completely featureless."; ], name 'door' 'snug' 'sign' 'iron', initial [; if (self has open) "An open door is here."; else { print "A stout iron door blocks exit #"; if (self in self.d1room) print self.d1dir; else print self.d2dir; print "."; } rtrue; ], found_in [; if (real_location == self.d1room or self.d2room) return TRUE; else return FALSE; ], before [; Receive: << Insert noun keyhole >>; Unlock: if (self has locked) "You need to insert each key into the keyhole, and turn all three keys, in order to unlock this door."; else "The door is already unlocked!"; Read: << Examine self >>; ], after [; Open: score = score + 400; print "You've been down here for so long -- and learned to expect so little -- that you can barely believe the sight before your eyes: a deserted utility room containing a ladder with the words 'Emergency Exit' on it. This is the way out of the caverns...no doubt about it.^^ Sure, there might be guards up there, or locked doors, or more puzzles for you to solve. But having defeated the Wumpus and so many other fearsome monsters of the underworld, these are puny obstacles that you barely need think about.^^ You have survived, you have escaped, and both freedom and fame await you. Tomorrow's copy in the newspaper will read: ~A fight to the death with Morristown's most famous monster. And a damning expose of the people responsible for it!~^^ Ready to face the world, you climb the ladder.^^"; deadflag = 2; rtrue; ], react_before [; Go: if (self has open) rfalse; if (self in self.d1room) { if (noun.num == self.d1dir) "The door is blocking that exit!"; } else { if (noun.num == self.d2dir) "The door is blocking that exit!"; } ], has static openable lockable locked transparent; Object keyhole "keyhole" with description [; print "You've never seen a keyhole quite like this. It has three ports, each capable of holding a key."; if (children(self) == 0) " Right now it is empty."; else { print " It holds "; if (key_bronze in self) { print (a) key_bronze; } if (key_lead in self) { if (key_bronze in self) { if (children(self) == 3) print ", "; if (children(self) == 2) print " and "; } print (a) key_lead; } if (key_iron in self) { if (key_bronze in self || key_lead in self) print " and "; print (a) key_iron; } print ".^"; } rtrue; ], before [; Receive: if (noun ofclass Key) rfalse; else "You can't put that in the keyhole!"; ], found_in [; if (real_location == door_iron.d1room) rtrue; ], name 'keyhole' 'hole' 'first' 'second' 'third' 'port' 'ports', has scenery static open container; Key key_bronze "blue key" with name 'blue'; Key key_lead "lead key" with name 'lead'; Key key_iron "red key" with name 'red'; CaveObject Jewelpouch "gem pouch" with description "Using patented 'Gravity Truss' technology (the same material which made varicose veins a thing of the past) this gem pouch can store precious stones in a convenient, secure, and surprisingly light manner.", name 'gem' 'pouch' 'bag' 'sac' 'sack', worth 60, weight 1, monworth 50, numin 0, ! Number of jewels inside before [; Receive: if (noun ofclass Jewel) rfalse; "You need one of those '", (name) noun, " pouches,' not a 'gem pouch.'"; Empty: "This pouch is one of the more secure models...once you've put a gem inside, you'll need to contact an authorized gem de-poucher to get it out again."; Search: "You learned at a very young age not to stick your hands into a gravity truss device."; ], invent [; print (a) self; if (self has open) print " (which is open)"; rtrue; ], after [; Receive: move noun to jewelbag; self.monworth = self.monworth + noun.monworth; self.numin++; self.weight = 1 + (self.numin / 3); ], has container openable; CaveObject Gasmask "gas mask" with description "It looks like it's been through a lot, but this big rubber gas mask might still be useful. If you run into any gas, that is.", name 'big' 'rubber' 'gas' 'mask', worth 70, weight 2, monworth 25, after [; Wear: "You slip the gas mask over your head."; Remove: "You remove the gas mask. It's nice to be able to breathe something other than carbon dioxide again!"; ], react_before [; Eat, Taste, Drink, Tell, Answer, Ask, AskFor, Kiss, Sing, Smell: if (self has worn) "That's impossible to do while you're wearing the gas mask."; ], has sink clothing; CaveObject shoes "spiked shoes" with description "Whoever wore these was either a baseball player or a mountain climber. Playing baseball down here is an unlikely pasttime...but they might help you climb steep slopes.", name 'spiked' 'shoes', worth 50, weight 4, monworth 45, after [; Wear: "Wow! They're your size!"; ], has sink pluralname clothing; CaveObject baseball "baseball" with description "It's dirty and has a big smear of blood on it, but it's more or less intact.", name 'dirty' 'bloody' 'smeared' 'ball' 'baseball' 'intact' 'blood', worth 20, weight 2, monworth 4, has sink; CaveObject Receiver "electronic receiver" with description "This little black box will pick up signals from remote sensors, providing you with updates about any living creatures that might be lurking around. This is a useful device but it doesn't have much of a range, and its signal can be disrupted by occasional bursts of energy from distant stars.", name 'electronic' 'receiver' 'little' 'black' 'box' 'useful' 'device', worth 80, weight 6, monworth 250, after [ x; SwitchOn: objectloop (x ofclass Sensor) { x.lasttotal = 1; ! Power on sensor refresh } ], each_turn [ x y room newtotal; if (self has on) { objectloop (x ofclass Sensor) { room = FindCeiling(x); if (room ofclass C_ROOMS) { newtotal = 0; objectloop (y in room) { if (y ofclass Creature) newtotal = newtotal + y; } if (newtotal ~= x.lasttotal) { x.lasttotal = newtotal; print "BEEP! Sensor ", (string) x.snum, " detects: "; if (CreaturesPresent(room)) { if (real_location == room) print "You..."; objectloop (y in room) { if (y ofclass Creature) print (name) y, "..."; } print "^"; } else print "no living creatures nearby now.^"; } } } } ], has sink switchable; CaveObject Mat "Transmat Mat" with description "Some clever (and rich!) explorer must have figured that a Transmat Mat would be a valuable caving tool. It's a crude, effective, not altogether comfortable rubber mat that acts like a cellular magnet. Matter from organisms previously dissolved by a Transmat Popper -- made by the same somewhat shady organization -- are attracted to this mat, and they will whiz across reasonable distances in order to cluster around it, where they are properly reassembled...usually in the right order.", name 'transmat' 'mat' 'tool' 'crude' 'effective' 'uncomfortable' 'rubber' 'magnet' 'cellular', worth 75, weight 15, monworth 650, before [; Enter: "That wouldn't do any good...travelling on a Transmat Mat is a one-way trip, with the mat at the end. If you're lucky."; ], has ~sink; CaveObject Popper "Transmat Popper" with description "This little button is a miracle of modern technology, and used to be fun for the kids before the unfortunate side- effects were discovered. In layman's terms, pressing the button will dissolve an organism's cells -- and some of its possessions -- and send the resulting goo flying through the air. If there's a Transmat Mat close by the goo will reassemble near it.", name 'transmat' 'popper' 'little' 'button' 'miracle' 'modern' 'technology', worth 85, weight 1, monworth 650, before [ croom room; Push: croom = FindCeiling(self); room = FindCeiling(Mat); print "The Transmat Popper makes a muffled ~zip!~ noise.^"; if (croom == room || room == FALSE) "You feel a funny tug at your innards, but nothing seems to have happened."; print "Reality turns inside-out for a second, and the next thing you know you're somewhere else...^"; if (SWIMMING) LeaveWater(); PlayerTo(room); rtrue; ], has sink; Object pylon "Pylon" EndRoom with name 'pylon'; Object playpen "Playpen" with name 'playpen', has container open openable enterable transparent; CaveObject sprayer "tank sprayer" with description "This is an industrial-strength pest-control sprayer, a large orange tank attached to a squeezeable nozzle. A menacing skull has been printed on the side, above the words ~organophosphate insecticide.~", name 'industrial' 'strength' 'pest' 'control' 'sprayer' 'large' 'orange' 'tank' 'nozzle' 'squeezeable' 'menacing' 'skull' 'insecticide' 'organophosphate', worth 0, weight 35, monworth 40, before [ room x; Squeeze: room = FindCeiling(self); print "White mist hisses out of the nozzle, quickly dispersing throughout the room.^"; give room poison; objectloop (x ofclass Beetle) { if (x in room) { print (The) x, " disintegrates immediately!^"; move x to beetlebag; } } PoisonSurrounding(room); rtrue; ], has sink; Object firstshaft "wide shaft" with description "Looking up at it, you can't believe that you fell out of this shaft. And you REALLY can't believe that you considered -- briefly -- the possibility of climbing back into it again. It's too far above your head and much too wide and smooth to give you any purchase. Whatever it is, it looks like a natural phenomenon. If you weren't in such an unpleasant situation you might stop to ponder how it developed.^^ In any case, there's no way out through the shaft. You'll need to hunt around for another way out.", name 'wide' 'shaft' 'smooth' 'natural' 'entrance' 'way' 'out', before [; Take: "Taking a hole is an interesting idea...but you wouldn't know what to do with it, even if you could somehow take it."; ], react_before [; Climb: if (noun == self) "There's nothing to hold on to in the shaft!"; ], initial "High above your head is the shaft you fell out of."; Skeleton SEntry "brittle skeleton" with description "This skeleton looks like he came in the same way you did, but he had a much less fortunate fate: one of his legs is shattered to pieces. He's obviously been here a long time. You can safely say, having landed on it, that it's the comfiest skeleton you've ever come in contact with.", initial "It appears that this skeleton on the ground has broken your fall.", name 'brittle' 'broken' 'unlucky' 'shattered' 'leg' 'legs' 'pieces' 'old' 'comfy'; Note SEntry_note "scribbled note" with description "Before dying, it looks like the hapless fellow wrote a letter.", name 'written' 'missive' 'scribbled' 'scribbles', text "~Just hours ago, Susie and I were jitterbugging in the pale moonlight. We did not watch our feet, so absorbed were we by our sinful desires. Where did that hole come from? Why haven't the constabulary erected a warning sign?^^ ~Now I'm down here and my leg hurts like the dickens, and Susie has wandered off to find a way out. She believes that as long as she heads in an upwardly direction she will arrive at the surface in a few minutes. I know little of caves so I am forced to agree with her, but in my heart I am troubled.^^ ~Before leaving, she brought me some water she found in a nearby river, claiming it fast enough to be safe from infection, but I fear it was poisoned: I am not well. After escaping these caves, will I ever jitterbug again? In daylight only, I swear!^^ ~As my candle dies -- reserved for a romantic dinner in the garden, and now my only sufficient light -- I believe I hear the sounds of a strange shifting throughout the cave. I recall ancient tales of the evil Wumpus, hidden in a lair beneath the city. I wish Susie had left the walking stick, so I would have something with which to defend myself!^^ ~My goodness! The candle dies and I see the face of--~^", initial "A scrap of paper is lying next to the skeleton."; Skeleton SSusie "crumpled skeleton" with description "The bones of this skeleton are unbroken, so it's difficult to know its history. One thing's for sure, it's been down here awhile.", initial "There is a skeleton lying crumpled up against the wall.", name 'unbroken' 'intact' 'old' 'lying' 'crumpled'; Note SSusie_note "scrawled note" with description "Maybe this note will give you some spelunking tips?", name 'written' 'missive' 'scrawled' 'scrawl' 'scribbled' 'scribbles', text "~The old woodsman down the road always told me: 'Susie, be careful of standing water. It is a haven for mosquitos and it has a deadly poison.' How stupid of me, I did not notice the odour until I had swallowed! And my constitution is poor...^^ ~I pray for rescue, both for me and my poor shattered lover!^^ ~I am sick. Oh how I spew! The cave grublings provide no solace, but at least they do not try to eat me.^^ ~Gasp! I breathe my last!^^ ~No, I think this is my last! Yes it is. GASP!~^", initial "A scrawled note is resting beside the skeleton."; Skeleton SScientist "lanky skeleton" with description "Whoever this person was, they died wrapped up in a pathetic fetal position. Will somebody stumble on your remains in a few years, tucked away like this?", initial "A skeleton is curled into a fetal ball at the edge of the cave.", name 'lanky' 'fetal' 'curled' 'ball'; Note SScientist_note "handwritten note" with description "Somebody has been sure to carefully record their final thoughts in methodical, precise handwriting.", name 'hand' 'written' 'handwritten' 'carefully' 'recorded' 'final' 'thoughts' 'methodical' 'methodically' 'lettered', text "~I should have known, when Chuck and Bert started giving me those 'funny looks,' that the lab management was on to me. They knew I'd been keeping notes, planning to send them to the Senator as soon as I felt it was safe. They probably wondered how I could have turned traitor, why I'd try to put an end to our landmark experiments in radiation and dimensional wrinkling of the unusual creatures in this cave. But when we started experimenting on HUMAN subjects...the poor lost explorers and political exiles...that's when I had to take a stand. That tragic 'Compressor!' We've created a monster, and we dare not contemplate what we've done!^^ So here I am, as helpless as the others. I've wandered away from the exit, trying to find the keys that open the door, but I'm weak from years of sitting on lab stools and eating fast food. I will not survive! It is hopeless! I am forever lost and forgotten!~^", initial "There is a carefully lettered note beside the skeleton."; Skeleton SFranklin "frozen skeleton" with description "This skeleton oozes cold air the way a teabag oozes tea...its marrow must have been steeped in ice for a very long time.", initial "A skeleton is propped up against the wall, arms crossed as though to conserve heat.", name 'frozen' 'oozing' 'cold' 'marrow' 'cold' 'icy' 'sir' 'john' 'franklin' 'captain'; Note SFranklin_note "cold note" with description "Like the skeleton it was found beside, this note gives off a palpable chill.", name 'cold' 'chilly', text "~In my search for the Northwest passage, I must have gotten lost, or perhaps I am under the Curse Of Bouyantly Confident Adventurers: to wander endlessly in search of an impossible goal.^^ But no! I refuse to believe there is no route to China. I know it exists, just as well as I know that I will be the man to find it. And when I am a famous, handsomly-rewarded man, I shall send word to Lady Jane to visit me... though the climate hereabouts is inhospitable.^^ I will continue my search in a few moments, but for the nonce I am horribly tired and in need of rest. It could not hurt to sleep a bit, could it?~^", initial "There is a note beside the skeleton."; ! Junk, treasure, items... FoodBar bar1; FoodBar bar2; FoodBar bar3; FoodBar bar4; FoodBar bar5; FoodBar bar6; GinkoBar gbar1; GinkoBar gbar2; GinkoBar gbar3; GinkoBar gbar4; SmallRock srock1; SmallRock srock2; SmallRock srock3; SmallRock srock4; SmallRock srock5; SmallRock srock6; SmallRock srock7; SmallRock srock8; SmallRock srock9; SmallRock srock10; LargeRock lrock1; LargeRock lrock2; LargeRock lrock3; LargeRock lrock4; LargeRock lrock5; LargeRock lrock6; LargeRock lrock7; LargeRock lrock8; LargeRock lrock9; LargeRock lrock10; Jewel jewel1; Jewel jewel2; Jewel jewel3; Jewel jewel4; Jewel jewel5; Jewel jewel6; Jewel jewel7; Jewel jewel8; Jewel jewel9; Jewel jewel10; Jewel jewel11; Jewel jewel12; Jewel jewel13; Jewel jewel14; Jewel jewel15; Jewel jewel16; Jewel jewel17; Jewel jewel18; Jewel jewel19; Jewel jewel20; Jewel jewel21; Jewel jewel22; Jewel jewel23; Jewel jewel24; Jewel jewel25; Jewel jewel26; Jewel jewel27; Jewel jewel28; Jewel jewel29; Jewel jewel30; Sensor sensor1 "sensor 1" with snum "s1", name 's1'; Sensor sensor2 "sensor 2" with snum "s2", name 's2'; Sensor sensor3 "sensor 3" with snum "s3", name 's3'; Sensor sensor4 "sensor 4" with snum "s4", name 's4'; Sensor sensor5 "sensor 5" with snum "s5", name 's5'; Rope frayed_rope with specific "frayed rope", name 'frayed'; Rope tough_rope with specific "tough rope", name 'tough'; Rope long_rope with specific "long rope", name 'long'; Barrel barrel1 with name 'barrel1', clevel 1; Barrel barrel2 with name 'barrel2', clevel 2; Barrel barrel3 with name 'barrel3', clevel 3; Barrel barrel4 with name 'barrel4', clevel 4; Barrel barrel5 with name 'barrel5', clevel 5; CaveObject penny "penny" with name 'penny' 'shiny' 'coin', descrption "It's a shiny penny, a few years older than you are.", worth 3, weight 1, monworth 0, after [; Drop: print (string) random("Heads!^", "Tails!^"); rtrue; ], has sink; CaveObject feather "ostrich feather" with description "You could understand finding an eagle feather down here somewhere -- it's conceivable that a bird of prey could end up living in the caves. But a bright red ostrich feather? Very strange...", name 'feather' 'bird' 'bright' 'red' 'ostrich', worth 2, weight 1, monworth 0, after [; Drop: "It floats gracefully through the air."; Smell: "~Achoo!~"; ]; CaveObject husk "dried husk" with description "It's impossible to know what sort of animal this husk came from. It's about the size of your hand and has an unpleasant texture.", name 'dried' 'husk' 'unpleasant', worth 1, weight 1, monworth 0; CaveObject pin "safety pin" with description "This pin has been down here so long that it is completely fused together by rust.", name 'safety' 'pin' 'rust' 'rusty', worth 1, weight 1, monworth 0, has sink; CaveObject cloth "scrap of cloth" with description "This looks like it was ripped from somebody's shirt.", name 'scrap' 'of' 'cloth' 'shirt' 'ripped', worth 1, weight 2, monworth 1; CaveObject bottlecap "bottlecap" with description "If you've seen one you've seen them all...unless you're a bottlecap collector (which you aren't).", name 'bottlecap' 'bottle' 'cap', worth 1, weight 1, monworth 1, has sink; CaveObject cardboard "flap of cardboard" with description "You're guessing that this was torn from a box long, long ago.", name 'flap' 'of' 'cardboard' 'box', worth 1, weight 2, monworth 0; CaveObject poptab "pop tab" with description "If you get mutilated down here, enough of these pop tabs might buy you a wheelchair.", name 'pop' 'tab' 'metal', worth 1, weight 1, monworth 1 has sink; CaveObject woodbead "wooden bead" with description "When the creatures in the cave attack you, they probably destroy your jewelry...hence this solitary, well-worn bead.", name 'wood' 'wooden' 'bead' 'solitary', worth 1, weight 1, monworth 1; CaveObject pearl "flawless pearl" with description "This probably came from some old lady's necklace. Since she's not around to claim it you might as well keep it...maybe you'll come across a 'lost & found?'", name 'flawless' 'pearl', worth 15, weight 1, monworth 75, has sink; CaveObject heel "broken heel" with description "It can't be easy running from monsters in high heels. This little plastic wedge is all that's left of what must have been a nice pair of shoes.", name 'broken' 'heel' 'little' 'plastic' 'wedge', worth 5, weight 2, monworth 2, has sink; CaveObject pencap "pen cap" with description "Probably from a magic marker.", name 'pen' 'cap', worth 1, weight 1, monworth 0; CaveObject button "button" with description "It looks like somebody lost the button off their cardigan. Since the button is cheap and ugly, you assume the cardigan was as well, and perhaps even the fellow who wore it.", name 'lost' 'button' 'cardigan' 'cheap' 'ugly', worth 2, weight 1, monworth 0, has ~sink; CaveObject glowbar "Glow Bar" with name 'glow' 'bar' 'light' 'glowbar', description "While a pack of hired thugs were dragging you out of your bed, you grabbed the first thing your hands came into contact with: the little piece of security you keep on your nighttable in defense of bad dreams. The Glow Bar provides just enough light to illuminate spooky closets and dark caverns, but it doesn't last forever...it's best to turn it off when you don't need it. Fortunately, it recharges itself.", when_on "A glowing bar illuminates the cave.", when_off "A deactivated glow bar is here.", weight 4, worth 30, monworth 35, battery MAXBATTERY, each_turn [; if (self has on && EXPLORE == 0) self.battery--; else { if (random(2)==1) { self.battery = self.battery + 4; if (self.battery > MAXBATTERY) self.battery = MAXBATTERY; } } if (TestScope(self) && self has on) { switch (self.battery) { 1: print "Your glow bar sputters and goes out.^"; give self ~on; give self ~light; 2 to 5: print "The light from your glow bar is so faded that you can hardly tell it's on.^"; 6 to 16: if (random(3) == 1) print "Your glow bar flickers for a moment.^"; } } ], before [; SwitchOn: if (self.battery < 6) { self.battery--; "The glow bar refuses to light...it needs some time to recharge."; } ], after [; SwitchOn: give self light; SwitchOff: give self ~light; ], has switchable; CaveObject Canteen "canteen" with name 'simple' 'metal' 'canteen' 'somewhat' 'battered' 'empty' 'full' 'half', short_name [; PrintCanteen(self); print " canteen"; rtrue; ], worth 20, monworth 8, article [; if (self.level == 0 or 1 or 3) print "an"; else print "a"; rtrue; ], weight [; return 5 + (self.level); ], when_open [; print "There is a"; if (self.level == 0 or 1 or 3) print "n "; else print " "; PrintCanteen(self); print " canteen here."; ], description [; print "Thank goodness for this canteen! If you're going to be down here for a while, you'll need a portable source of water. "; print "It is "; PrintCanteen(self); print ".^"; ], contaminated 0, before [; Fill: if (location hasnt river) "There's not enough water around here to fill your canteen with."; if (self.level == 4) "It's already full."; print "You fill your canteen with river water.^"; self.level = 4; if (location.speed < 4) self.contaminated = 1; rtrue; Receive: if (second ~= oriver) "You don't want to put that in your canteen!"; << Fill self >>; Drink: if (self.level == 0) "The canteen is empty!"; if (actor.thirst > 95) "You aren't thirsty."; print "You take a drink of water from the canteen.^"; actor.thirst = 100; self.level--; if (self.contaminated) { print "It was contaminated!^"; DISEASE = 5 + random(5); } rtrue; Empty: if (self.level == 0) "It's already empty!"; print "You empty the canteen.^"; self.contaminated = 0; self.level = 0; rtrue; Open: print "You open the canteen and look inside. It's "; PrintCanteen(self); "."; Close: "It's already closed. You're obsessive-compulsive about never leaving things open."; Smell: if (self.level == 0) "It smells faintly metallic."; if (self.contaminated) "It has a slightly rotten smell."; "It smells relatively clean."; ], level 0, has container open; CaveObject altometer "altometer" with description [; print "By measuring the springiness and degree of 'oomf' in the surrounding atoms, the altometer can tell you exactly how many feet you are below sea-level. You can read the information on a little display screen. Right now it says: ", real_location.depth + 300, ".^"; ], name 'digital' 'altometer' 'information' 'little' 'display' 'screen', text [; print "You are ", real_location.depth + 100, " feet below sea-level.^"; ], worth 50, weight 2, monworth 30, has sink; ! Weapons Weapon spoon "baby spoon" with description "Judging by the duckling carved into the handle, you assume this little tin spoon was meant for a baby...possibly one of the recent missing persons?", name 'duck' 'duckling' 'little' 'tin' 'spoon' 'baby' 'small' 'tiny', attackstyle1 "poke", attackstyle2 "jab", worth 5, weight 1, monworth 1, strengthbonus 20; Weapon bone_club "bone club" with description "Once the foundation of somebody's thigh, now it's just a yellowed piece of bone. Its owner probably doesn't need it anymore.", name 'thigh' 'bone' 'club' 'thighbone' 'yellow' 'yellowed' 'piece' 'of', attackstyle1 "swing", attackstyle2 "twirl", weight 2, worth 17, monworth 2, strengthbonus 40, has ~sink; Weapon walking_stick "walking stick" with description "A walking stick isn't much use down here in the caverns, but it's a pretty thing at least. Somebody lovingly carved and polished it, and probably spent many years carrying it around hiking tours of New Jersey wilderness. That somebody is surely dead by now, so they won't mind if you use it.", name 'sturdy' 'pine' 'walking' 'stick' 'hiking' 'companion' 'carved' 'polished', attackstyle1 "swat", attackstyle2 "swing", weight 3, worth 15, monworth 8, strengthbonus 80, has ~sink; Weapon rock_spear "stone spear" with description "It's a rigid, 3-foot-long rock formation with a wicked point on the end. Leave it to nature -- in the form of hundreds of years of dripping sediment -- to create such a useful weapon. Probably not what she intended, but still...", name 'rock' 'stone' 'spear' 'rigid' 'long' 'formation' 'wicked' 'point' 'end' 'piece', attackstyle1 "thrust", attackstyle2 "jab", weight 8, worth 30, monworth 1, strengthbonus 160; Weapon firepoker "firepoker" with description "This thin, metal instrument works well as both a firepoker AND a weapon, thanks to the pointy end.", name 'thin' 'metal' 'instrument' 'firepoker' 'poker' 'point', attackstyle1 "poke", attackstyle2 "swing", weight 4, worth 40, monworth 8, strengthbonus 250; Weapon rock_knife "rock knife" with description "You're not sure whether this is a primitive artifact or a convincing fakery, but it looks like it could do some damage. It's a short rock cylinder with a tapered end, apparently chipped using stone-age technology.", name 'primitive' 'artifact' 'short' 'rock' 'cylinder' 'tapered' 'knife' 'stone', attackstyle1 "flick", attackstyle2 "jab", worth 30, monworth 5, weight 3, strengthbonus 350; Weapon cattleprod1 "shocking cattle prod" with description "Useful on all sorts of cattle...human, alien, mutant and otherwise! It gives a wicked shock to those it hits.", name 'cattle' 'prod' 'useful' 'wicked' 'shocking', attackstyle1 "zap", attackstyle2 "wave", worth 75, monworth 40, weight 8, strengthbonus 700; Weapon cattleprod2 "zapping cattle prod" with description "Useful on all sorts of cattle...human, alien, mutant and otherwise! It gives a wicked shock to those it hits.", name 'cattle' 'prod' 'useful' 'wicked' 'zapping', attackstyle1 "zap", attackstyle2 "wave", worth 75, monworth 40, weight 8, strengthbonus 700; Weapon icepick "pick" with description "You haven't spent a lot of time around picks in the past, but you can still tell there is something strange about this one. It radiates a feeling of intense cold that permeates everything around it, including you!", name 'pick' 'strange', attackstyle1 "swing", attackstyle2 "swipe", worth 0, monworth 5000, weight 20, strengthbonus 1400, each_turn [; if (self in player && random(5) == 1) { print "You feel deathly cold.^"; ChangeStrength(player, -10); } ]; Weapon superspike "quantum spike" with description "Einstein would have hated this weapon, but faced with the Wumpus he probably would have used it. Touted as a ~revolution in murder,~ it totally changed the way people stab each other. In short, it slides in like butter and uncoils all of the nearby dimensions at the same time, doing a remarkable amount of damage both to the victim and to the space-time continuum. That's probably why most intellectuals prefer it.", name 'spike' 'quantum', attackstyle1 "thrust", attackstyle2 "poke", weight 1, worth 100, monworth 1000, strengthbonus 2000; ! Creatures ! Creatures based on a class should have only a single, descriptive adjective in their ! name... !/Baby baby1; !/ !/Baby baby2; !/ !/Baby baby3; !/ !/Baby baby4; !/ !/Baby baby5; Grubling grubling1; Grubling grubling2; Grubling grubling3; Reptodon reptodon1; Reptodon reptodon2; Rocker rocker1; Rocker rocker2; Cinderbug cinder1; Cinderbug cinder2; Cinderbug cinder3; Cinderbug cinder4; Cinderbug cinder5; Quickpaw quickpaw1; Quickpaw quickpaw2; Guard guard1; Guard guard2; Beetle tb_1 with crename "first beetle", name 'first'; Beetle tb_2 with crename "second beetle", name 'second'; Beetle tb_3 with crename "third beetle", name 'third'; Beetle tb_4 with crename "fourth beetle", name 'fourth'; Beetle tb_5 with crename "fifth beetle", name 'fifth'; Beetle tb_6 with crename "sixth beetle", name 'sixth'; Beetle tb_7 with crename "seventh beetle", name 'seventh'; Beetle tb_8 with crename "eighth beetle", name 'eighth'; Beetle tb_9 with crename "ninth beetle", name 'ninth'; Beetle tb_10 with crename "final beetle", name 'final'; Object Eggsack "eggsac", with description [; print "This bloated sac drags along behind the Wumpus, spawning the many strange creatures that roam these caves. Now it is "; switch (self.countdown) { 0: "hacked to pieces...permanently useless!"; 1: "hideously dilated, about to give birth!"; 2: "swollen almost to bursting."; 3: "growing thick, preparing another discharge."; 4 to 10: "slowly filling up."; 11 to 999: "limp and flacid."; } ], countdown 15, oomf 5, name 'bloated' 'sac' 'sack' 'egg' 'eggsack' 'eggsac' 'useless' 'dilated' 'swollen' 'thick' 'limp' 'flacid', before [; Attack: if (self.oomf == 0) "Like your mother always said, ~No use beating a dead eggsac!~ It's beyond help or harm."; print "You attack the eggsac, doing considerable damage."; self.oomf--; if (self.oomf == 0) { print " It's tough, but there's only so much it can take...the sac collapses with a whoosh of air, permanently useless!"; self.countdown = 0; } if (self.oomf == 1) print " It can't survive too much more...it's just about done for."; print "^"; rtrue; Take: "It's attached to the Wumpus!"; Enter: "A dream for some, but not for out."; ], has scenery; ! Unique creatures must obey the '.blank' '.blank' rule, so that corpses ! will be properly set up. Creature Fish with description "Just a fish.", name '.blank' '.blank' 'fish' '.blank' '.blank', crename "fish", weight 3, strength 80, topstrength 80, enterstring "come swimming in", leavestring "swims away", minworth 0, maxworth 0, predator, AIStyle 12, rebirth 0, inlevel 0, has animate; ! "Boss" Creatures... Creature Hurkle ! Apologies to Theodore Sturgeon & Bob Albrecht with description "Like many of the creatures in these caves, the Hurkle looks to have mutated from a more benign species -- in this case a sort of eyeless sturgeon -- with oversized teeth and four webbed feet. It spends much of its time bobbing around the bottoms of rivers, ponds, and swimming pools, waiting for a chance to strike...and being relatively small and adept at camouflage, it's easy to overlook.", crename "Hurkle", name '.blank' '.blank' 'hurkle' 'fish' 'eyeless' 'oversized' 'teeth' 'webbed' 'feet' 'small', speed 65, weight 15, strength 500, topstrength 500, attackstyle1 "snaps its oversized teeth", attackstyle2 "kicks", enterstring "come bobbing into the room", leavestring "bobs and weaves", diestring "screeches weekly and collapses, dead", minworth 50, maxworth 70, predator, hiding 1, AIStyle 3, rebirth 0, inlevel 0, article "the", has animate; Creature Boga with description "A creature grown fat on fire, the Boga has never left this cave. It is enormously obese and almost featureless, consisting mostly of scaly belly and flapping mouth. It's hard to say whether the Boga was born this way or if it's just gotten lazy. Either way it's one of the ugliest things you've ever seen, and it looks like it's been ugly for for a long time.", crename "Boga", name '.blank' '.blank' 'Boga' 'fat' 'enormous' 'enormously' 'obese' 'featureless' 'scaly' 'scales' 'belly' 'flapping' 'mouth' 'demon' 'stubby' 'arm' 'gristly' 'claw' 'claws', speed 50, weight 700, strength 700, topstrength 700, attackstyle1 "swats its stubby arm", attackstyle2 "swipes its gristly claws", diestring "farts fire, screams, thrashes, and falls back against the wall", minworth 50, maxworth 100, predator, AIStyle 5, rebirth 0, inlevel 0, article "the", each_turn [; if (TestScope(self) && random(5) == 1) { print (The) self, " "; switch (random(5)) { 1: "licks its flapping lips."; 2: "scowls at you."; 3: "glares down at you."; 4: "belches horribly."; 5: "pats its bloated belly."; } } ], has animate light; Creature Compressor with description "The Compressor is a creature with an impossible shape: it is a rickety jumble of limbs that all seem to be fighting against implosion. Atop this are human eyes, staring crazily at you. You wonder if, through some strange and forgotten alchemy, this creature was once a former explorer...like you.", crename "Compressor", name '.blank' '.blank' 'Compressor', speed 33, weight 2000, strength 1200, topstrength 1200, attackstyle1 "scratches its skeletal fingers", attackstyle2 "swipes its bony nails", diestring "explodes into nothingness", enterstring "get sucked into the room", leavestring "shudders", leavecorpse 0, minworth 0, maxworth 0, prey, AIStyle 7, rebirth 1, inlevel 3, article "the", each_turn [; if (TestScope(self) && random(5) == 1) { print (The) self, " "; switch (random(5)) { 1: "spreads its spindly arms, touching the walls of the cave."; 2: "inhales a windy scream."; 3: "scratches at its exposed chest."; 4: "throws its head back and shudders violently."; 5: "spins and twirls in the middle of the cave."; } } ], has animate; Creature Wumpus with description "You never thought the Wumpus would look like this, no matter how it was characterized by the hysterical people of Morristown. A tiny, evil little head peers out at you from the end of a gigantic, insectoid body...insectoid, that is, except for the plump flesh and fur that covers most of it. After years spent brooding down here and drinking radioactive waste, the Wumpus has turned into what all waste-drinking monsters aspire to: a grotesque, mutated and frightfully strong enemy!^^ Dragging behind the Wumpus is a blood-engorged eggsac. Now you know where alll these hideous cave monsters come from...", short_name "Wumpus", crename "Wumpus", name '.blank' '.blank' 'wumpus' 'tiny' 'evil' 'little' 'head' 'gigantic' 'insectoid' 'plump' 'flesh' 'fur' 'grotesque' 'mutated' 'frightfully' 'strong' 'enemy' 'front' 'pincers' 'dripping' 'jaws' 'numberless' 'limbs' 'sucker' 'feet', speed 75, weight 500, strength 2500, topstrength 2500, attackstyle1 "lashes its front pincers", attackstyle2 "gnashes its dripping jaws", diestring "unleashes an anguished scream, then collapses back into itself", enterstring "lumber into the room", leavestring "drags itself", minworth 0, maxworth 0, predator, AIStyle 10, rebirth 0, inlevel 5, article "the", each_turn [; if (TestScope(self) && random(5) == 1) { print (The) self, " "; switch (random(5)) { 1: "rattles its numberless limbs together."; 2: "screeches horrifically."; 3: "proudly displays its famous sucker feet."; 4: "puffs itself up, almost completely filling the cave."; 5: "heaves itself up and down in a rage."; } } ], has animate; Creature Zenman with description "You've heard rumours about the mysterious ~Zen Man,~ a Morristown city official who gave up everything to seek enlightenment in the caves. Well, not only are the rumours true, but the guy is still alive, though he could use a good meal.", short_name "Zen Man", crename "Zen Man", name '.blank' '.blank' 'zen' 'man' 'mysterious' 'zenman' 'stoic', speed 5, weight 80, strength 500, topstrength 500, attackstyle1 "smacks you", attackstyle2 "batters you", diestring "peacefully expires", minworth 0, maxworth 0, prey, AIStyle 11, rebirth 0, inlevel 2, article "the", willhelp 0, life [; WakeOther: "He's not asleep, though it's hard to tell."; Kiss: "Not even this fazes the stoic Zen Man."; Give, Show: if (noun.monworth < 10) "The Zen Man gazes at ", (the) noun, " with contempt. Since discovering that there are no absolutes in the universe except for an object's monetary worth, little trinkets like that are of little interest to him."; move noun to self; self.willhelp++; if (self.willfight) { self.willfight = 0; print "Upon seeing your gift, he immediately calms down. "; } print "The Zen Man takes ", (the) noun, ". He's willing to help you now.^"; rtrue; Tell, Answer, Order: print (The) self, " raises his eyebrows, then lowers them again.^"; rtrue; Ask: if (self.willhelp) { self.willhelp = 0; switch (second) { 'escape', 'exit': "~A tiny mosquito could escape quickly, but humans must use the back door.~"; 'back', 'door': "~The door's distance from the sun is large, but it is only ", (door_iron.d1room).depth+300, " under the earth's surface. The keys, however, are another matter.~"; 'key', 'keys': "~Keys are too important to just leave lying around. Keys are often entrusted to those you trust the most...or to those least likely to give them up!~"; 'feet', 'underground', 'distance', 'sun', 'depth': "~Here in the caves, all points of reference are useless. We orient by depth. A tiny mosquito knows this instinctively, but humans must use the altometer.~"; 'altometer': "~A student asked her master: 'Where can I find the book of mysteries?' The master replied, 'The location of the book is revealed within the book.' One cannot know the depth of an object, if one does not possess the depth-revealing object itself.~"; 'book', 'of', 'mysteries', 'death': "~It's just a parable, don't get hung up on it.~"; 'cave', 'caves', 'labyrinth', 'caverns', 'rock', 'rocks': "~Who put the caves here? How were they formed? Who built the first weapon? How deep is a bowl of soup?~ He rubs his stomach. ~Soup, yum.~"; 'soup': "~It is cruel to talk of soup to a man who hasn't eaten it in years.~"; 'monster', 'monsters', 'creature', 'creatures': "~Many monsters here are the periods in the book of death: easily ignored with only run-on-sentences as the consequences. The Hurkle, Boga and Wumpus, however, are the paper, spine and ink: ignore them at your peril! Without them, there is no book, and without a book there is no final page, no conclusion.~"; 'Wumpus': "~The Wumpus is the mother, giver of life. For those who are into that sort of thing. She lives deep and is loved by many.~"; 'Boga': "~The Boga is friend only to the fireflies. You will find him where it is warmest.~"; 'Hurkle': "~The Hurkle is most elusive! Being mostly fish, it loves hiding in the water. But being lazy, it hates swimming against fast currents. Search and ye shall find.~"; default: self.willhelp = 1; "He gives you an enigmatic look. You suspect he doesn't know what you're asking him about, but that he doesn't want to admit it."; } } else "He's waiting for you to give him something. The Zen Man may be enlightened, but that doesn't mean he's cheap."; ], each_turn [; if (TestScope(self) && random(5) == 1) { print (The) self, " "; switch (random(5)) { 1: "stares passively at you."; 2: "smiles inscrutably."; 3: "quietly hums."; 4: "blinks."; 5: "cocks his head slightly."; } } ], has animate transparent; Corpse corpse1; Corpse corpse2; Corpse corpse3; Corpse corpse4; Corpse corpse5; Corpse corpse6; Corpse corpse7; Corpse corpse8; Corpse corpse9; Corpse corpse10; ! The Baby Actions !/Actions A_CRY !/ with !/ startmsg "starts to cry", !/ currentmsg "is crying", !/ conditions !/ [ cre; !/ return (cre.happy - cre.happy * 2) + 60 + random(10); !/ ], !/ noisy 1, !/ result -5; !/ !/Actions A_SCREAM !/ with !/ startmsg "starts to scream", !/ currentmsg "is screaming", !/ conditions !/ [ cre; !/ return (cre.happy - cre.happy * 2) + 60 + random(10); !/ ], !/ noisy 1, !/ result -10; !/ !/Actions A_LAUGH !/ with !/ startmsg "starts laughing", !/ currentmsg "is laughing", !/ conditions !/ [ cre; !/ return cre.happy - 40 + random(10); !/ ], !/ noisy 1, !/ result 5; !/ !/Actions A_BABBLE !/ with !/ startmsg "begins babbling randomly", !/ currentmsg "is babbling happily", !/ conditions !/ [ cre; !/ return cre.happy - 40 + random(10); !/ ], !/ noisy 1; !/ !/Actions A_THROW !/ with !/ conditions !/ [ cre; !/ if (children(cre)) !/ return random(100); !/ ], !/ result !/ [ cre obj loc; !/ obj = child(cre); !/ loc = FindCeiling(cre); !/ if (TestScope(cre)) !/ print (The) cre, " shrieks and throws ", (the) obj,".^"; !/ move obj to loc; !/ if (loc has river) !/ PutInRiver(obj, loc); !/ cre.happy = cre.happy + 10; !/ ]; !/ !/Actions A_THROWUP !/ with !/ conditions !/ [ cre; !/ if (parent(cre) provides strength) !/ return random(80) + 20; !/ ], !/ result !/ [ cre obj; !/ obj = parent(cre); !/ if (TestScope(cre)) !/ { !/ print (The) cre; !/ if (random(2) == 1) !/ print " throws up"; !/ else !/ print " pees"; !/ print " on "; !/ if (obj == player) !/ print "you.^"; !/ else !/ print (the) obj, ".^"; !/ } !/ cre.happy = cre.happy + 10; !/ ], !/ change TRUE; !/ !/Actions A_EAT !/ with !/ conditions !/ [ cre; !/ if (children(cre)) !/ return random(100); !/ ], !/ result !/ [ cre obj; !/ obj = child(cre); !/ if (obj has edible) !/ { !/ if (TestScope(cre)) !/ print (The) cre, " eats ", (the) obj, ".^"; !/ move obj to objectbag; !/ cre.happy = cre.happy + 10; !/ } !/ else !/ { !/ if (TestScope(cre)) !/ print (The) cre, " chews on ", (the) obj, ".^"; !/ cre.happy = cre.happy - 10; !/ } !/ ]; !/ !/Actions A_WANDER !/ with !/ conditions !/ [ cre loc; !/ loc = FindCeiling(cre); !/ if (parent(cre) == loc || parent(cre) has container) !/ return random(100); !/ ], !/ result !/ [ cre loc cdir; !/ loc = FindCeiling(cre); !/ if (parent(cre) has container) !/ { !/ if (parent(cre) hasnt open) !/ { !/ if (TestScope(cre)) !/ print (The) cre, " struggles to escape ", (the) parent(cre), ".^"; !/ } !/ else !/ { !/ if (TestScope(cre)) !/ { !/ print (The) cre, " wanders out of ", (the) parent(cre); !/ if (cre.happy > 75) !/ { !/ print ", yelling ~"; !/ cre.sayhello(); !/ print ", "; !/ cre.sayhello(); !/ print "!~^"; !/ } !/ else !/ print ".^"; !/ } !/ move cre to loc; !/ } !/ } !/ else !/ { !/ cdir = RandDir(loc); !/ if (TestScope(cre) && cre.happy > 75) !/ { !/ print (The) cre, " yells ~"; !/ cre.saygoodbye(); !/ print "!~^"; !/ } !/ MoveCreature(cre, cdir); !/ if (TestScope(cre) && cre.happy > 75) !/ { !/ print (The) cre, " yells ~"; !/ cre.sayhello(); !/ print "!~^"; !/ } !/ } !/ ]; !/ !/Actions A_STRUGGLE !/ with !/ startmsg "struggles peevishly", !/ currentmsg "is struggling to be put down", !/ conditions !/ [ cre; !/ if (parent(cre) provides strength) !/ return (cre.happy * -1) + 40; !/ ], !/ result -5; !/ !/Actions A_DROOL !/ with !/ startmsg "drools", !/ currentmsg "is absently drooling", !/ conditions !/ [; !/ return random(20); !/ ]; !/ !/Actions A_BURP !/ with !/ startmsg "burps", !/ conditions !/ [; !/ return random(20); !/ ], !/ result 10; !/ !/Actions A_PICKUP !/ with !/ conditions !/ [ cre loc; !/ loc = parent(cre); !/ if (ObIn(loc)) !/ return random(100); !/ ], !/ result !/ [ cre loc pick x; !/ loc = parent(cre); !/ objectloop (x in loc) !/ { !/ if (x ~= cre && x ofclass CaveObject) !/ pick = x; !/ } !/ if (pick) !/ { !/ if (TestScope(cre)) !/ print (The) cre, " picks up ", (the) pick, ".^"; !/ move pick to cre; !/ } !/ else !/ { !/ if (TestScope(cre)) !/ { !/ print (The) cre, " looks around and flexes "; !/ if (cre has female) !/ print "her"; !/ else !/ print "his"; !/ print " little hands.^"; !/ } !/ } !/ ]; !/ !/Actions A_FIGHT !/ with !/ conditions !/ [ cre loc sum; !/ loc = parent(cre); !/ sum = CreaturesPresent(loc); !/ if (sum > 1) !/ return 50 - random(cre.happy); !/ ], !/ result !/ [ cre loc pick x; !/ loc = parent(cre); !/ objectloop (x in loc) !/ { !/ if (x ~= cre && x provides strength) !/ { !/ if (pick == 0 || random(2) == 1) !/ pick = x; !/ } !/ } !/ if (pick) !/ { !/ if (TestScope(cre)) !/ { !/ print (The) cre, " pinches "; !/ if (pick == player) !/ print "you.^"; !/ else !/ print (the) pick, ".^"; !/ } !/ cre.happy = cre.happy + 15; !/ if (pick provides happy) !/ pick.happy = pick.happy - 30; !/ } !/ ]; ! The Daemons! Object CDaemon ! Creature AI with daemon [ i room cdir nomore x snatch; objectloop (i ofclass Creature) ! Sift through creatures { nomore = 0; if (random(100) < i.speed && i notin creaturebag && i notin beetlebag) ! Time to act? { if (i provides prey && i.willfight && random(5) == 1) i.willfight = 0; ! Become passive again room = FindCeiling(i); cdir = 0; if (oooze in room) ! Creatures love ooze! oooze.drinkme(i); if (i.AIStyle == 1) ! Fungus eater, prey { room.fungus = room.fungus - 10; if (room.fungus < 1) { room.fungus = 0; MoveFloatingObjects(); } if (TestScope(i)) print (The) i, " scrapes a large patch of rock out of the wall.^"; if (room.fungus < 1 || random(8) == 1) { cdir = FungusDir(room); if (cdir == 0 || random(5) == 1) { cdir = NewDir(i); if (cdir == 0) cdir = RandDir(room); } MoveCreature(i, cdir); } } if (i.AIStyle == 2) ! Footprint follower, predator { if (i notin real_location) { cdir = FootprintsDir(room); if (cdir) { if (random(5) == 1) print "You get the feeling you're being followed.^"; } if (cdir == 0) { if (Health(i) > 25) cdir = PreyDir(room); if (cdir == 0) cdir = NoPredDir(room); if (cdir == 0) cdir = NewDir(i); if (cdir == 0) cdir = RandDir(room); } MoveCreature(i,cdir); } } if (i.AIStyle == 3) ! Pool lurker { if (i.hiding) { if (player in room && random(3) == 1) print "A stream of bubbles froth in the water, as though something were breathing in there...^"; if (Health(i) > 50) { if (player in room && SWIMMING) { i.hiding = 0; print "An eyeless, amphibious creature jumps out of the water and takes a bite out of you!^"; ChangeStrength(player, 0 - 25); give i ~concealed; } if (CreaturesPresent(room) && random(10) == 1) { i.hiding = 0; give i ~concealed; if (player in room) print "A strange, four-legged fish jumps out of the water and starts scuttling around the cave!^"; Combat(i, PickPrey(i, room)); } } } else { if (Health(i) < 80) { if (IsQuietPool(room) == 0) { cdir = QuietPoolDir(room); if (cdir == 0) cdir = RandDir(room); } else { if (player in room) print "The Hurkle plunges deep into the water and hides itself.^"; i.hiding = 1; give i concealed; } } else { if (CreaturesPresent(room) > 1) { Combat(i, PickPrey(i, room)); } else { cdir = PreyDir(room); if (cdir == 0) cdir = QuietPoolDir(room); if (cdir == 0) cdir = RandDir(room); } } } if (cdir > 0) { MoveCreature(i, cdir); } } if (i.AIStyle == 4) ! Thief, prey { if (Health(i) < 75) ! Wounded { cdir = NoPredDir(room); if (cdir == 0) cdir = RandDir(room); } else ! Healthy { if (WeightOf(i) > i.weight + i.weight / 2) { while (child(i)) { x = child(i); move x to room; if (TestScope(i)) print (The) i, " drops ", (a) x, ".^"; if (room has river) PutInRiver(x, room); } } else cdir = ValObDir(room, i); if (cdir == 0) cdir = NewDir(i); ! NewDir requires i! if (cdir == 0) cdir = RandDir(room); if (WeightOf(i) <= i.weight * 2) { snatch = 0; objectloop (x in room) ! Something to steal? { if (x provides worth && x.worth > 0 && x.hoarded ~= i) { snatch = x; } } if (snatch) { if (snatch provides tiedto && snatch.tiedto > 0) { if (random(100) > 20) { if (testscope(i)) print "The ", (name) i, " tries to untie the rope.^"; else { if (player has snatch) print "Something is tugging on ", (the) snatch, ".^"; } } else { if (testscope(i)) print "The ", (name) i, " unties the rope and coils it up.^"; else { if (player has snatch) print (The) snatch, " is suddenly jerked out of your hands! It disappears up through the exit it was hanging from.^"; } snatch.tiedto = 0; } } else { move snatch to i; snatch.hoarded = i; if (testscope(i)) print "The ", (name) i, " picks up ", (the) snatch,".^"; cdir = 0; } } } } if (cdir > 0) { MoveCreature(i, cdir); } } if (i.AIStyle == 5) ! Boga { snatch = 0; objectloop (x in creaturebag) ! Any Cinderbugs available? { if (x ofclass Cinderbug) snatch = x; } if (snatch) ! Bogapuke { if (TestScope(i)) print (The) i, " belches up ", (a) snatch, "!^"; move snatch to room; snatch.strength = 5; } } if (i.AIStyle == 6) ! Cinderbugs { snatch = 0; changestrength(i, (room.heat / 25) - 8); if (room has river) changestrength (i, -4); objectloop (x in room) ! Any creatures in room? { if (x has animate) { if (x ofclass Cinderbug || x == Boga) { x = x; } else ! Divebomb! { snatch = x; } } } if (snatch) { if (TestScope(i)) { print (The) i, " darts at "; if (snatch == player) print "you"; else print (the) snatch; print " and bursts into a shower of sparks!^"; } ChangeStrength(snatch, i.strength * -1); ChangeStrength(i, -500); } else { if (cdir == WindExitFrom(room) or 0) { cdir = WindExitTo(room); if (cdir == 0 || random(3) == 1) { cdir = RandDir(room); } } } if (cdir > 0 && i notin creaturebag) MoveCreature(i, cdir); } if (i.AIStyle == 7) ! Compressor { if (Health(i) < 25) ! Teleport { if (TestScope(i)) print (The) i, " contracts into a tiny particle and goes whizzing away!^"; move i to RandRoom(5); i.strength = i.topstrength; if (TestScope(i)) print (The) i, " suddenly materializes beside you!^"; } if (Health(i) < 50 && Health(i) > 24) ! Just run. { cdir = NoPredDir(room); i.strength = i.strength + 50; if (cdir == 0) cdir = RandDir(room); } if (Health(i) > 49) ! Healthy { cdir = ValObDir(room, 1000); ! No jewels! if (children(jewelbag) == 0 || cdir == 0) { cdir = NewDir(i); ! NewDir requires i! if (cdir == 0) cdir = RandDir(room); } if (children(jewelbag) > 0) { snatch = 0; objectloop (x in room) { if (x provides worth) { if (x ofclass Jewel) x = x; else snatch = x; } } if (snatch) ! Prepare for alchemy! { nomore = 0; while (ObjNotJewel(room)) { nomore = 0; objectloop (x in room) { if (x provides worth) { if (x ofclass jewel) x = x; else nomore = x; } } if (TestScope(i)) print (The) i, " picks up ", (the) nomore, ".^"; move nomore to i; } while (JewelInRoom(room)) ! Add jewels to mix! { objectloop (x in room) { if (x ofclass Jewel) nomore = x; } if (TestScope(i)) print (The) i, " picks up ", (the) nomore, ".^"; move nomore to i; } Alchemy(i); cdir = 0; } } } if (cdir > 0) { MoveCreature(i, cdir); } } !/ if (i.AIStyle == 8) ! Baby !/ { !/ i.last = i.desire; !/ i.desirenum = 0; !/ i.happy = i.happy + i.change; !/ if (i.happy > 100) !/ i.happy = 100; !/ if (i.happy < 1) !/ i.happy = 1; !/ objectloop (x ofclass Actions) ! Find biggest desire !/ { !/! if (TestScope(i)) !/! print "Testing action #", x, ": "; !/ snatch = x.conditions(i); !/ if (x == i.last) !/ snatch = snatch / 2; !/! if (TestScope(i)) !/! print snatch; !/ if (snatch > i.desirenum) !/ { !/ i.desirenum = snatch; !/ i.desire = x; !/! if (TestScope(i)) !/! print " (chosen)"; !/ } !/! if (TestScope(i)) !/! print ".^"; !/ } !/ snatch = i.desire; !/ if (TestScope(i) && metaclass(snatch.startmsg) == string) !/ print (The) i, " ", (string) snatch.startmsg, ".^"; !/ if (metaclass(snatch.result) == routine) !/ snatch.result(i); !/ else !/ i.happy = i.happy + snatch.result; !/ if (snatch.change) !/ i.change = i.change * -1; !/ } if (i.AIStyle == 9) ! Beetle { snatch = 0; if (room has poison) { if (TestScope(i)) print (The) i, " disintegrates immediately!^"; move i to beetlebag; rtrue; } if (children(beetlebag) < 8) ! Breed first. { objectloop (x in room) ! Explode? { if (x provides prey) { if (x ofclass Beetle) x = x; else snatch = 1; } } } if (snatch) ! Explode! { if (TestScope(i)) { print (The) i, " explodes, spraying guts and exoskeleton all over the room!^"; } else { if (WhatLevel(room) == WhatLevel(real_location)) print "You hear an explosion somewhere in the cave.^"; } room.bloody = room.bloody + 10; move i to beetlebag; objectloop (x in room) ! Do damage { if (x provides strength) { if (TestScope(x)) { if (x == player) print "You are "; else print (The) x, " is "; print "damaged by the explosion!^"; } if (x.strength < 101) ChangeStrength (x, x.strength - (x.strength * 2) + 10); else ChangeStrength (x, (100 - 200)); room.bloody = room.bloody + 10; } } } else { cdir = 0; snatch = 0; objectloop (x in room) ! Other beetles in room? { if (x ofclass Beetle && x ~= i) snatch = 1; } if (snatch) ! Spread! cdir = BeetleEmpty(room); if (cdir == 0) ! Breed! { if (room has poison) { if (TestScope(i)) print (The) i, " gags and coughs, obviously very sick.^"; } else { if (children(beetlebag)) { snatch = 0; objectloop (x in room) { if (x ofclass Beetle) snatch++; } if (snatch == 1) { x = child(beetlebag); move x to room; if (TestScope(i)) { print (The) i, " squirts "; print (a) x, " out of its abdomen!^"; } } } } } } if (cdir) MoveCreature(i, cdir); } if (i.AIStyle == 10) ! Wumpus { ! Must write } if (i.AIStyle == 11) ! Zen Man { ! Must write } if (i.AIStyle == 12) ! Fish { if (player in room) { if (Health(i) < 50) { cdir = WaterRoom(room, 1); } } if (player notin room) { if (Health(i) > 49) { cdir = WaterRoom(room, 2); } } if (cdir == 0 && random(20) == 1) { cdir = WaterRoom(room, 0); } if (random(20) == 1) { if (TestScope(i)) print (The) i, " swims away to an underwater area that you can't reach.^"; move Fish to creaturebag; } else { if (cdir) MoveCreature(i, cdir); } } if (i.AIStyle == 13) ! Guard { if (FindCeiling(player) ~= room) { if (i.goingup) { if ((LOCATION1.conn / 2) < (room.conn)) i.goingup = 0; else { cdir = NextUpDown(room, 1); if (cdir == 0) { i.goingup = 0; } } } else { if (room.conn == 2) { if (random(4) == 1) i.goingup = 1; } else cdir = NextUpDown(room, 0); } } if (cdir) MoveCreature(i, cdir); } } } ]; Object DDaemon ! Dungeon features control with daemon [ i j room picked x cdir croom totheat numheat totmoist nummoist temp; for (j = 1: j <= 3: j++) { room = RandRoom(random(5)); totheat = room.heat * 2; numheat = 2; totmoist = room.moist * 2; nummoist = 2; if (room.fungus < room.moist && room hasnt frozen) ! Fungus grows back { room.fungus = room.fungus * 2; if (room.fungus > room.moist) room.fungus = room.moist; } if (room == FREEZER || room == FURNACE) { room = room; ! Do nothing to these rooms } else { if (FindCeiling(icepick) == room) totheat = totheat - 40; objectloop(i ofclass CompassDirection) ! Update room's heat & moist { temp = i.door_dir; if(i provides dung && room.temp ~= 0) { croom = room.temp; totheat = totheat + croom.heat; numheat++; totmoist = totmoist + croom.moist; nummoist++; if (room has frozen) { if (croom.heat < 1) { give croom frozen; if (FindCeiling(player) == croom) print "Ice crystals are forming on the walls around you!^"; croom.fungus = 0; MoveFloatingObjects(); ! print "*** A ROOM IS NOW FROZEN ***^"; } } } } } ! if (FindCeiling(player) == room) ! Tell player about it. ! { ! if (mentioned == 0) ! Just in case room is picked again. ! { ! if (room.moist - (totmoist / nummoist) > 0) ! print "The air in here seems to be drying out.^"; ! else ! { ! if (room.moist - (totmoist / nummoist) < 0) ! print "The air in here seems more humid than it was a ! second ago.^"; ! } ! if (room.heat - (totheat / numheat) > 0) ! print "It feels a little colder in here than it did a second ! ago.^"; ! else ! { ! if (room.heat - (totheat / numheat) < 0) ! print "This room seems to be heating up.^"; ! } ! } ! mentioned++; ! } room.moist = totmoist / nummoist; if (room.moist > 100) room.moist = 100; if (room has frozen && totheat / numheat > 0 && room ~= FREEZER) { give room ~frozen; if (FindCeiling(player) == room) print "The ice on the wall has melted away.^"; MoveFloatingObjects(); ! print "*** A ROOM IS NO LONGER FROZEN ***^"; } room.heat = totheat / numheat; if (room.heat > 400) room.heat = 400; if (room has poison) ! Poison issues { if (room.fungus) { room.fungus = 0; if (FindCeiling(player) == room) print "The fungus on the walls sizzles away when it comes into contact with the mist.^"; } if (random(100) < room.wind) { give room ~poison; cdir = WindExitTo(room); if (cdir) ! Poison moves { croom = room.(cdir.door_dir); if (FindCeiling(player) == room) { print "The mist in the room disperses and drifts into exit ", cdir.num, ".^"; MoveFloatingObjects(); } give croom poison; if (FindCeiling(player) == croom) { print "A light mist drifts into the room from exit ", ExitToRoom(croom, room).num, ".^"; MoveFloatingObjects(); } } else ! Poison disappears { if (FindCeiling(player) == room) { print "The mist in the room gradually disperses.^"; MoveFloatingObjects(); } } } } } objectloop (i ofclass Chute) { if (6 - (i.clevel) >= random(120)) ! Chute drop? { picked = PickTreasure((i.clevel - 1) * 20, i.clevel * 20); if (picked == 0) ! Scrape the bottom o' barrel. picked = PickTreasure(1, i.clevel*20); if (picked) ! Appropriate item found. { if (TestScope(i)) { print "Suddenly, ", (a) picked, " comes rattling out of the chute.^"; } else { objectloop (x in FindCeiling(player)) { if (x ofclass Chute) print "A rattling noise echoes out of the chute.^"; } } room = FindCeiling(i); ! Item arrives. move picked to room; if (room has river) PutInRiver(picked, room); } } } ]; Object DWeightMonitor ! Adapted from DM4 ex.43 with activate [; StartDaemon(self); ], daemon [ burden item heaviest_weight heaviest_item; burden = WeighPercent(player); if (burden > 100) { heaviest_weight = -1; objectloop(item in player) if (WeightOf(item) > heaviest_weight) { heaviest_weight = WeightOf(item); heaviest_item = item; } if (heaviest_item == nothing) return; print "^You don't have the strength to carry ", (the) heaviest_item, "!^"; ; if (heaviest_item in player) { deadflag = true; "^Unprepared for this, you collapse."; } } if (burden > 85 && random(5) == 1) print "It's difficult carrying all of your stuff around!^"; ]; ! Movable scenery Object obarrelhole "small hole" with name 'hole' 'small' 'big', description "Somebody should have been more careful with the barrel... the hole in the bottom is small, but big enough to be a problem.", before [; Take: "Impossible!"; Enter: "Maybe if you were an ant..."; Receive: "The hole is too small."; ], has scenery; Object oooze "toxic ooze" with name 'toxic' 'ooze' 'bright' 'green' 'pooled' 'bit' 'pool' 'pooled' 'liquid', description "The bright green colour gives it away: this is toxic ooze, no doubt about it.", drinkme [ cre oi top x level; if (cre == player) print "You drink the ooze.^"; else { if (TestScope(self)) print (The) cre, " drinks the green, toxic ooze.^"; } level = WhatLevel(FindCeiling(self)); oi = OozeIncrement(level); top = 100 + oi * 5; if (cre.topstrength >= top) { if (cre == player) print "Sadly, it doesn't seem to have any effect on you. Maybe there's some more powerful stuff around somewhere?^"; } else { if (cre.topstrength + oi < top) RaiseStrength(cre, oi); else RaiseStrength(cre, top - cre.topstrength); } objectloop (x ofclass Barrel) { if (x.clevel == level) x.ooze = FALSE; } remove self; if (cre provides thirst) cre.thirst = 100; ], article "some", before [; Take: "It oozes around your fingers"; Drink: self.drinkme(player); rtrue; Smell: "It has a tantalizing, plasticine-and-earth odour."; ]; Object ofungus "fungus" with name 'glow' 'fungus', description "The fungus appears to be the cave's main source of light; it glows gently. You don't know what sort of nutrients it requires but it does seem to grow only in moist locations.", found_in [; return (location provides fungus && location.fungus > 0); ], before [; Take: "The fungus is too slimy for you to be able to carry it."; Eat: << EatFungus self >>; EatFungus: if (actor.hunger > 99) "You aren't hungry."; real_location.fungus = real_location.fungus - 20; if (real_location.fungus < 1) { print "You eat the last remnants of fungus off the walls.^"; MoveFloatingObjects(); } else print "You eat some fungus off of the walls.^"; EatFood(actor, 50); rtrue; ], has light scenery edible proper; Object oice "ice" with description "It's so cold in here that the walls are draped with sheets of transparent ice.", name 'sheet' 'sheets' 'transparent' 'ice', before [; Take: "It would only end up melting."; Eat: "Low in fat, but not very nutritious!"; ], found_in [; return (real_location == FREEZER || real_location has frozen); ], each_turn [; if (random(3) == 1) { print "You feel like all of your body warmth is being sucked out of you!^"; ChangeStrength(player, -10); } ], has scenery edible proper; Object oriver "river" with name 'river' 'water' 'stream' 'pond' 'swamp' 'stagnant' 'pool' 'motionless' 'sluggish' 'oozing' 'stretching' 'slow' 'moving' 'flowing' 'fast' 'flowing' 'rushing' 'gush' 'gushing' 'lake' 'bursting' 'cascading' 'placid', describe [; DescribeRiver(location); rtrue; ], react_before [; Drop: if (SWIMMING || real_location.size < FILLSROOM) << Insert noun self >>; ], before [ something nothing; Take: "That's not something you can easily carry around."; Search: if (SWIMMING == FALSE) { print"In order to really see what's in the water, you'll need to be swimming in it.^"; rtrue; } print "You search around underwater...^"; something = 1; nothing = 1; while (something) { if (Hurkle in FindCeiling(player) && Hurkle.hiding) { print "You found the Hurkle!^"; Hurkle.hiding = 0; nothing = 0; } something = InRiverBag(real_location); if (something) { move something to location; print "You found ", (a) something, "!^"; nothing = 0; } } if (nothing) print "There's nothing in the water worth worrying about.^"; rtrue; Enter: SwimSub(); rtrue; Drink: if (actor.thirst > 95) "You aren't thirsty.^"; print "You take a drink of water.^"; actor.thirst = 100; if (real_location.speed < 4) { print "It was contaminated! You should know better than to drink from stagnant pools.^"; DISEASE = 5 + random(5); } rtrue; Smell: if (real_location.speed < 4) "It has a slightly rotten smell to it."; "It smells fresh."; ], after [; Receive: if (noun == player) rfalse; PutInRIver(noun, real_location); rtrue; ], each_turn [ x room; if (SWIMMING && parent(Fish) == creaturebag && random(15) == 1) { room = FindCeiling(player); x = SetupFish(room.speed, room.heat); if (x) { move Fish to room; print "Suddenly, ", (a) Fish, " swims at you from out of the depths!^"; } } ], found_in [; return (location has river); ], has container open proper; Object riverbag "riverbag" ! For things dropped in the rivers with name 'riverbag'; Object creaturebag "creaturebag" ! The ghosts of unborn creatures with name 'creaturebag'; Object beetlebag "beetle bag" ! For unused beetles with name 'beetle bag' 'beetlebag'; Object objectbag "objectbag" ! Objects waiting to be placed with name 'objectbag'; Object jewelbag "jewelbag" ! For unused jewels with name 'jewelbag'; Object owind "wind" with name 'wind' 'warm' 'hot' 'light' 'steady' 'breeze' 'blast' 'blowing', describe [; DescribeWind(real_location); rtrue; ], before [; Take: "Your fingers swish through the air, grasping nothing."; Smell: "It's earthy and musty. Not unpleasant, just...primal."; ], found_in [; return (real_location provides wind && real_location.wind > 20); ] has proper; Object fog "fog" with name 'fog' 'thick' 'light' 'moisture', description "The fog is probably due to the large amount of moisture in the air.", found_in [; return (location provides moist && location.moist > 65 && location.size < 6 && location.wind < 35); ], after [; Smell: "The fog is moist and odourless."; ], has scenery; Object ocliff "cliff" with description "Erosion from some long-ago river has created a high, rocky cliff here. You might just be able to climb down it...though getting back up might be difficult!", name 'cliff' 'eroded' 'bed' 'high' 'rocky', before [; ClimbDown, Climb: print "You peer over the edge of the cliff and look for the lowest exit.^"; << Go d_obj >>; ], has scenery; Object opit "pit" with description "Either erosion or some long-ago shift in the bedrock has created a deep pit in this room. You might be able to climb out of it.", name 'pit' 'eroded' 'old' 'deep' 'pit' 'bedrock', before [; Climb, ClimbOut, Exit: print "You go to the edge of the pit and look for the highest exit.^"; << Go u_obj >>; ], has scenery; Object owaterfall "waterfall" with description [ x; x = FindCeiling(self).speed; print "Water "; if (x < 4) print "trickles lazily over the rocks."; else { if (x < 7) print "washes over the rocks."; else print "gushes in a dangerous torrent, down a steep bank of rocks."; } ], name 'waterfall' 'gushing' 'rushing', before [; ClimbDown, Climb: "Descending a waterfall in a graceful manner isn't something you learned in your journalism courses. Best to just swim and pray!"; Eat: "You should eat food, not water."; Drink: "The force of the falling water would be painful!"; ], has scenery; Object poisonmist "poison" with description "A thin sheen of bitter-smelling mist floats throughout the room.", name 'thin' 'sheen' 'bitter' 'smelling' 'smelly' 'mist' 'floating' 'poison' 'poisonous' 'sharp', found_in [; return (location has poison); ], after [; Smell: "The mist smells sharp and bitter, like the inside of a powerful roach motel."; ], has scenery; Object rain "light rain" with name 'rain' 'light' 'moisture' 'heavy', describe [; if (real_location.moist == 90) "A steady rain falls from the unseen roof of the cavern."; "A light rain falls from the obscured cavern roof."; ], description "The rain is cool and refreshing.", found_in [; return (location provides moist && location.moist > 65 && location.size == 6 && location has river); ], has scenery; Object oblood "blood" with name 'blood' 'gore' 'spattered' 'speckled' 'art' 'red' 'splash' 'splashed', description "One of the many spoils of battle: splashes of blood. It's hard to tell exactly who it belongs to.", found_in [; return (location provides bloody && location.bloody > 0); ], before [; Take: "There's no way to take it...it's just sort of splashed everywhere."; Smell: "A rich and bloody odour, like a particularly unclean slaughterhouse."; Drink: << Eat self >>; Eat: if (actor.hunger > 95) "You aren't hungry enough, thank goodness."; if (parent(self).bloody < 20) "There just isn't enough blood around to make it worthwhile."; parent(self).bloody = parent(self).bloody - 19; EatFood(actor, 5); actor.thirst = actor.thirst + 15; if (actor.thirst > 100) actor.thirst = 100; "If you close your eyes you can imagine you're drinking copper-flavoured tomato juice. But you've never had a great imagination. In any case, the blood sure hits the spot."; ], has scenery; Features ocolumns "column" with name 'stalagmite' 'stalagmites' 'stalagtite' 'stalagtites' 'dripping' 'hanging' 'rising' 'beautiful' 'tall' 'stone' 'drapery' 'drape' 'draping' 'like' 'sheet' 'sheets' 'rippled' 'rippling' 'rock' 'hanging' 'long' 'howllow' 'strand' 'strands' 'column' 'columns', before [; Take: if (rock_spear in objectbag or riverbag) { move rock_spear to location; print "With a bit of effort you manage to dislodge a piece of the formation.^"; << Take rock_spear >>; } else "It is firmly attached."; ], react_before [; Climb: if (noun == self) "It is far too slippery to climb."; ]; Features orubble "rubble" with name 'fine' 'sand' 'coarse' 'gravel' 'jumble' 'broken' 'rock' 'stone' 'rubble' 'patch' 'coral' 'pile' 'rocks', before [; Take: "You have no use for that."; Dig: "You doubt you'd find anything."; Search: "You poke around it for a few minutes, but you don't find anything."; ], react_before [; Climb: if (noun == self) "There's no point in climbing around on that."; ]; Features opits "pit" with name 'deep' 'elongated' 'cavity' 'cavities' 'small' 'shallow' 'depression' 'depressions' 'cleft' 'clefts' 'slight' 'tiny' 'fissure' 'fissures' 'pit' 'pits', before [; Search: "You look around for a few minutes, but you don't find anything."; JumpOver: "There's no reason to."; ], react_before [; Climb: if (noun == self) "You can't think of any reason to do that."; ]; Features oridge "ridge" with name 'ridge' 'stone' 'rock' 'diving' 'board', before [; Take: "It is firmly attached."; ], react_before [; Climb: if (noun == self) "There's no point in climbing it."; ]; Features oarc "arc" with name 'long' 'narrow' 'hall' 'stone' 'rock' 'huge' 'arc' 'apex' 'roof' 'smooth' 'dome', before [; Go: if (noun == u_obj) << Climb self >>; ], react_before [; Climb: if (noun == self) "It's far too slippery to climb."; ]; Features oshaft "shaft" with name 'shaft' 'cylindrical' 'high' 'wide' 'featureless', react_before [; Climb: if (noun == self) "You'd never get very far."; ]; Features odrips "drips" with name 'stagnant' 'pool' 'small' 'drop' 'drops' 'steady', before [; Eat: "You should eat food, not water."; Drink: "There isn't enough to drink."; ]; Chute chute2 with clevel 2, name 'daddy'; Chute chute3 with clevel 3; Chute chute4 with clevel 4; Chute chute5 with clevel 5; ! Compass Directions CompassDirection x1_obj "first exit" compass with description [; if (location.x1_to) PrintExit(location, self); else print "There is no such exit.^"; rtrue; ], dung, name 'x1' 'first' 'exit' '1', door_dir x1_to, num 1; CompassDirection x2_obj "second exit" compass with description [; if (location.x2_to) PrintExit(location, self); else print "There is no such exit.^"; rtrue; ], dung, name 'x2' 'second' 'exit' '2', door_dir x2_to, num 2; CompassDirection x3_obj "third exit" compass with description [; if (location.x3_to) PrintExit(location, self); else print "There is no such exit.^"; rtrue; ], dung, name 'x3' 'third' 'exit' '3', door_dir x3_to, num 3; CompassDirection x4_obj "fourth exit" compass with description [; if (location.x4_to) PrintExit(location, self); else print "There is no such exit.^"; rtrue; ], dung, name 'x4' 'fourth' 'exit' '4', door_dir x4_to, num 4; CompassDirection x5_obj "fifth exit" compass with description [; if (location.x5_to) PrintExit(location, self); else print "There is no such exit.^"; rtrue; ], dung, name 'x5' 'fifth' 'exit' '5', door_dir x5_to, num 5; Object OnGoing "OnGoing" ! Turn-by-turn adjustment & status with ! reports. daemon [ i min minpicked x; objectloop (i ofclass Creature) { if (i notin creaturebag && i notin beetlebag) { if (i.strength < i.topstrength) ChangeStrength(i, Percent(i.topstrength, 2)); if (CreaturesPresent(FindCeiling(i)) > 1) { CreatureInRoom(i); } } } if (DISEASE) { DISEASE--; if (DISEASE == 0) { print "You feel a little better now.^"; } else { ChangeStrength(player, Percent(player.topstrength, -4)); if (random(3) == 1) print "You feel sick.^"; } } if (EXPLORE == 0) { player.hunger--; player.thirst--; } if (player.strength < player.topstrength) ChangeStrength(player, Percent(player.topstrength, 2)); switch (player.hunger) { 25 to 45: if (random(4) == 1) print "You are getting hungry.^"; 8 to 24: if (random(2) == 1) print "You are getting weak from hunger!^"; 1 to 7: print "If you don't eat some food soon, you will die.^"; ChangeStrength(player, Percent(player.topstrength, -10)); -50 to 0: print "You have starved to death!^"; deadflag = TRUE; } switch (player.thirst) { 20 to 45: if (random(4) == 1) print "You are getting thirsty.^"; 8 to 19: if (random(2) == 1) print "You are starting to dehydrate!^"; 1 to 7: print "You need water immediately or you will die.^"; ChangeStrength(player, Percent(player.topstrength, 10)); -50 to 0: print "You have died of thirst!^"; deadflag = TRUE; } if (SWIMMING) SwimRoutine(real_location); if (Eggsack.countdown == 1) ! Eggsack rebirth! { if (children(CreatureBag)) { min = 200; minpicked = 0; objectloop (x in CreatureBag) { if (x.rebirth < min) { min = x.rebirth; minpicked = x; } } if (min > 0 && minpicked) Resurrect(minpicked); else { if (real_location == FindCeiling(Eggsack)) print "The Wumpus' eggsack deflates with a disgusting whooshing sound...it was only gas. Whew!^"; } } Eggsack.countdown = 15; if (wumpus.strength < wumpus.topstrength) Eggsack.countdown = 3; } else { if (Eggsack.countdown > 1) Eggsack.countdown--; } ]; Object ears "your ears" ! Glorified variable for LookRoutine with name 'your' 'ears', riverspeed, riverdistant, ! River needs this check due to nature of river isgrubling, ! All others: 0 = none, 1 = distant, 2 = Close isreptodon, ! 3 = in the room. isquickpaw, isboga, isrocker, isbeetle, iscompressor, iswumpus, isguard, !/ isbaby, !/ isbabywhich, !/ isbabyaction ; !------------------------------------------------------------------------------- ! Initialise !------------------------------------------------------------------------------- [ Initialise loc; print "Would you like to restore a saved game? >"; if (YesOrNo()) < Restore >; ChangePlayer(CustomPlayer); ! To allow common properties. lookmode = 2; shownum = 1; TEST = 0; notify_mode = FALSE; move glowbar to player; ! Give player items StartDaemon(Ongoing); DWeightMonitor.activate(); PrintIntro(1, 0); SetupDungeon(); StartDaemon(CDaemon); StartDaemon(DDaemon); location = LOCATION1; ! Place stuff for first room move SEntry_note to location; ! (Must be after SetupDungeon() move SEntry to location; ! or we won't know where location move firstshaft to location; ! is) move canteen to location; move bar1 to location; move bar2 to location; move Popper to location; do ! Place misc stuff loc = RandRoom(1); until (loc ~= location); move Walking_Stick to loc; move SSusie_note to loc; move SSusie to loc; loc = RandRoom(3); move SScientist_note to loc; move SScientist to loc; move Receiver to loc; move Mat to RandRoom(3); move playpen to LOCATION100; move firepoker to zenman; move cattleprod1 to guard1; move cattleprod2 to guard2; move icepick to FREEZER; move SFranklin to FREEZER; move SFranklin_note to FREEZER; Door_iron.d1room = LOCATION100; ! Set up door Door_iron.d1dir = ExitToRoom(LOCATION100, EndRoom).num; Door_iron.d2room = EndRoom; Door_iron.d2dir = ExitToRoom(EndRoom, LOCATION100).num; move key_bronze to Hurkle; ! Place keys move key_iron to Boga; move key_lead to Wumpus; SpillObjectBag(); ! Place some objects in caves "^^^^"; ]; ! ========================================================================= ! ! FUNCTIONS ! ! ========================================================================= [ WeightOf obj t i; ! Return weight of obj & children if (obj == player) ! It's alive! t = t; ! Do nothing else { if (obj provides weight) { if (metaclass(obj.weight) == Routine) t = obj.weight(); else t = obj.weight; } else t = 10; } objectloop (i in obj) t = t + WeightOf(i); return t; ]; [ WorthOf obj t i; ! Return worth of obj & children if (obj == player) t = t; else { if (obj provides monworth) { if (metaclass(obj.monworth) == Routine) t = obj.monworth(); else t = obj.monworth; } } objectloop (i in obj) t = t + WorthOf(i); return t; ]; [ LeaveWater; ! When player leaves water... SWIMMING = 0; if (Fish in location) move Fish to creaturebag; ]; [ SetupFish spee temp; ! Set up fish based on water info if (spee > 7 || random(4) == 1) { Fish.description = "Whenever you saw one of these creatures in the zoo, you referred to them as ~Googly Piranha,~ because they have extremely large and goofy eyes. But now you notice the multiple rows of razor-sharp teeth, stained with flecks of blood and tissue. Wow, you were a really naive kid!"; Fish.crename = "googly piranha"; Fish.&name --> 3 = 'googly'; Fish.&name --> 4 = 'piranha'; Fish.speed = 100; Fish.weight = 1; Fish.strength = 200; Fish.topstrength = 200; Fish.attackstyle1 = "snaps its razor-sharp teeth"; Fish.attackstyle2 = "snaps its razor-sharp teeth"; Fish.diestring = "flips over and dies"; Fish.willfight = 1; } if (spee < 8 && spee > 4 || random(5) == 1) { if (temp < 100) return 0; if (temp > 99 && temp < 251) { Fish.description = "Other than having no eyes, this trout is pretty much what you'd find floating dead in the lakes of New Jersey."; Fish.crename = "blind trout"; Fish.&name --> 3 = 'blind'; Fish.&name --> 4 = 'trout'; Fish.speed = 50; Fish.weight = 6; Fish.strength = 100; Fish.topstrength = 100; Fish.attackstyle1 = "crunches its little teeth"; Fish.attackstyle2 = "crunches its little teeth"; Fish.diestring = "flips over and dies"; Fish.willfight = 0; } else { Fish.description = "You've never seen anything like it in your life! A gorgeous -- and somewhat cocky -- fish with an enormous fan of irridescent feathers trailing behind."; Fish.crename = "sea peacock"; Fish.&name --> 3 = 'sea'; Fish.&name --> 4 = 'peacock'; Fish.speed = 25; Fish.weight = 10; Fish.strength = 200; Fish.topstrength = 200; Fish.attackstyle1 = "lashes its feathers"; Fish.attackstyle2 = "pecks its beak"; Fish.diestring = "unleashes an aquatic squawk and begins floating belly-up"; Fish.willfight = 0; } } if (spee < 5 || random(6) == 1) { if (temp < 30) return 0; if (temp > 99 && temp < 251) { Fish.description = "This fish is sort of like a lamprey...a long eel with teeth instead of a head. But unlike lampreys, you think you can see a pair of eyes peering at you from inside its mouth. It looks very muscular, but not particularly fast."; Fish.crename = "bigmouth sucker"; Fish.&name --> 3 = 'bigmouth'; Fish.&name --> 4 = 'sucker'; Fish.speed = 50; Fish.weight = 7; Fish.strength = 300; Fish.topstrength = 300; Fish.attackstyle1 = "swims forward with its teeth bared"; Fish.attackstyle2 = "beats its body"; Fish.diestring = "twists into a knot and dies"; Fish.willfight = 1; } else { Fish.description = "The caves don't have many poisonous creatures in them, but this is one of them: a jellyfish the size of a dinner plate with long, articulated tentacles snapping at you."; Fish.crename = "acidopod"; Fish.&name --> 3 = 'acidopod'; Fish.&name --> 4 = 'acidopod'; Fish.speed = 50; Fish.weight = 2; Fish.strength = 200; Fish.topstrength = 200; Fish.attackstyle1 = "snaps its tentacles"; Fish.attackstyle2 = "snaps its tentacles"; Fish.diestring = "loses all cohesion, turning into a loose sac of jelly"; Fish.willfight = 1; } } return 1; ]; [ Resurrect cre moveto; ! Resurrect provided creature if (cre ofclass Baby) DefineBaby(cre); if (cre.shuffler) Shufflername(cre); moveto = FindCeiling(Wumpus); move cre to moveto; if (player in moveto) print "With a horrible squishing sound, ", (a) cre, " comes squeezing out of the eggsack!^"; ]; [ EatFood cre amount; ! Provided cre eats food if (cre.hunger < 45) ChangeStrength(cre, amount / 2); cre.hunger = cre.hunger + amount; if (cre.hunger > 100) cre.hunger = 100; ]; [ RaiseStrength cre amount; ! Raise cre's topstrength cre.topstrength = cre.topstrength + amount; ChangeStrength (cre, amount / 2); if (cre == player) { print "You feel stronger! "; print "Using meditative powers taught to you in a weight lifting ashram, you suspect you have reached ", TSPercent(player), "% of your potential maximum strength.^"; } DrawStatusLine(); ]; [ ChangeStrength cre amount attacker; ! Adjust strength of cre if (EXPLORE && cre == player) ! Unusual exceptions rtrue; cre.strength = cre.strength + amount; if (cre.strength > cre.topstrength) cre.strength = cre.topstrength; if (cre.strength < 1) ! Dead now? { !/ if (cre ofclass Baby) ! God looks after babies, the jerk. !/ { !/ cre.strength = 1; !/ cre.happy = 1; !/ rtrue; !/ } if (cre == player) { deadflag = 1; rtrue; } else { if (TestScope(cre)) print "The ", (name) cre, " ", (string) cre.diestring, "!^"; if (attacker == player) { score = score + cre.topstrength / 50; if (cre == Wumpus) score = score + 50; } CreatureDie(cre); } } DrawStatusLine(); ! When do we bother printing updates about strength? if (cre ofclass Cinderbug) rtrue; ! Not when a cinderbug. if (amount < 3 && amount > 0) ! Not during recuperation rtrue; if (TestScope(cre) == FALSE) rtrue; ! (or when out of scope)... if (amount < 0) ! And not until it's important. { if (Health(cre) < 65) PrintStrength(cre); } else { if (Health(cre) > 70) PrintStrength(cre); } ]; [ BloodyRoom room amount; ! Bloody-up room by amount ! (if no amount, just by 2) if (room provides bloody) { if (amount == 0) amount = 2; room.bloody = room.bloody + amount; } ]; [ CreatureDie cre x lowest picked; ! Take care of body disposal KILLED++; lowest = KILLED; while (child(cre)) ! Drop anything carried { x = child(cre); if (TestScope(cre)) print "The ", (name) cre, " drops ", (a) x, ".^"; move x to parent(cre); } if (cre.minworth ~= 0) ! Arrange treasure drop TreasureDrop(cre); if (cre.leavecorpse) { objectloop (x ofclass Corpse) ! Find an available corpse { if (x.corpseturn < lowest) { lowest = x.corpseturn; picked = x; } } move picked to parent(cre); ! Set up corpse picked.type = cre.type; picked.shuffler = cre.shuffler; picked.creclass = cre.creclass; picked.corpseturn = KILLED; ! Place in "queue" picked.body = cre.short_name; ! Name it... picked.&name--> 3 = cre.&name--> 0; picked.&name--> 4 = cre.&name--> 2; picked.weight = cre.weight; picked.crename = cre.crename; picked.short_name = cre.short_name; picked.parse_name = cre.parse_name; if (cre provides language) ! If it's a baby...shame! { picked.language = cre.language; picked.size = cre.size; if (cre has female) give picked female; } if (cre == Fish) PutInRiver(picked, parent(cre)); } if (cre ofclass Beetle) move cre to beetlebag; else move cre to creaturebag; ! Retire & refresh creature if (cre == Wumpus) ! Destroy Eggsack if Wumpus dies { Eggsack.oomf = 0; Eggsack.countdown = 0; } cre.strength = cre.topstrength; cre.willfight = 0; ]; [ TreasureDrop cre picked; ! Arrange treasure drop if (cre.minworth == 0) ! No treasure? return; if (cre.minworth < 0) ! Fixed treasure? { if (TestScope(cre)) print "The ", (name) cre," was carrying ", (a) cre.maxworth, "!^"; move cre.maxworth to parent(cre); } else ! Random treasure. { picked = PickTreasure(cre.minworth, cre.maxworth); if (picked) { if (TestScope(cre)) print "The ", (name) cre," was carrying ", (a) picked, ".^"; move picked to parent(cre); } } ]; [ PickTreasure min max x numobj curnum picknum; ! Pick random treasure based ! on min & max if (max == 0) max = 100; numobj = NumTreasure(min, max); curnum = 0; if (numobj > 0) ! Objects available? { picknum = random(numobj); objectloop (x in objectbag) { if (x.worth >= min && x.worth <= max) { curnum++; if (curnum == picknum) return x; } } } return 0; ! No objects fit criteria. ]; [ NumTreasure min max x numobj; ! Return treasures in objectbag ! between min & max. numobj = 0; if (max == 0) max = 100; objectloop (x in objectbag) { if (x.worth >= min && x.worth <= max) numobj++; } return numobj; ]; [ PrintStrength cre; ! Print Strength info. if (cre == player) print "You are "; else print "The ", (name) cre, " is "; switch(Health(cre)) { 85 to 500: print "in perfect form"; 75 to 84: print "healthy"; 60 to 74: print "slightly injured"; 45 to 59: print "wounded"; 20 to 44: print "badly wounded"; 0 to 19: print "near death"; } print ".^"; ]; ! Combat Routines [ AttackSub; ! Direct from verb (no weapon) if (noun ofclass Creature) Combat(player, noun); else "There's no point in attacking that."; ]; [ AttackWeaponSub; ! Weapon specified if (second ofclass Weapon) Combat (player, noun, second); else { print (The) second, " would not make a useful weapon!^"; rtrue; } ]; [ Combat attacker defender withw ast dst aw dw atry dtry; ! Combat routine, need ! attacker, defender, and ! "with weapon?" ! print (name) attacker, " -vs- ", (name) defender, "!^"; ast = attacker.strength; dst = defender.strength; if (defender.weight > 1) ! Weapons useless against small things { if (withw == FALSE) ! Pick weapon if none aw = PickWeapon(attacker); ! chosen. else aw = withw; } dw = PickWeapon(defender); if (aw) ! Add bonuses (weapons) ast = ast + aw.strengthbonus; if (dw) dst = dst + (dw.strengthbonus * 2); atry = random(ast); ! Attack and defense based on dtry = random(dst); ! strength. if (TestScope(attacker)) { if (attacker == player) ! Lash out... print "You"; else print (The) attacker; if (aw) { if (random(2) == 1) print " ", (string) aw.attackstyle1; else print " ", (string) aw.attackstyle2; if (attacker ~= player) print "s"; print " "; if (attacker == player) print (the) aw; else print (a) aw; } else { if (random(2) == 1) print " ", (string) attacker.attackstyle1; else print " ", (string) attacker.attackstyle2; } if (atry > (ast - (ast / 10))) ! ...really hard? print " viciously"; if (defender == player) print " at you. "; else print " at ", (the) defender, ". "; } if (defender provides willfight) ! Turn prey into fighters! defender.willfight = 1; if (atry > dtry) ! A hit! { if (TestScope(attacker)) { print "Ouch!^"; move oblood to parent(defender); } BloodyRoom(parent(defender)); ! Blood on walls. ChangeStrength(defender, (dtry-atry) / 2, attacker); } else ! A miss. { if (TestScope(attacker)) { if (defender == player) { print "You deflect the blow"; if (dw) { print " with your ", (name) dw; } print "!^"; } else print (The) defender, " dodges the attack.^"; } } if (aw) ! Weapon breaks! { if (random(aw.strengthbonus) < 5) { if (TestScope(attacker)) print (The) aw, " shatters!^"; move aw to objectbag; } } ]; [ PickWeapon cre x bonus we; ! Pick best weapon for cre objectloop (x ofclass weapon) ! Choose weapons { if (x in cre) { if (x.strengthbonus > bonus) { we = x; } } } return we; ]; ! Creature In Room routines [ CreatureInRoom pro room pp; ! pro is not alone! ! (if no pro, pro is player) if (pro == 0) rtrue; ! Let player handle it! room = FindCeiling(pro); ! Put any "Boss Code" before this generalized section if (pro.hiding) ! Stay hidden rtrue; ! (Let AI handle it) if (pro provides Prey) { if (pro.willfight) ! Prey belligerent? Combat(pro, PickPrey(pro, room)); rtrue; } if (PlayerInRoom(room)) ! ...either player... Combat(pro, player); else { pp = PickPrey(pro, room); ! These creatures will never attack each other! if (pro == Boga && pp ofclass Cinderbug) rtrue; if (pro ofclass Cinderbug && pp == Boga) rtrue; if (pro == Wumpus && pp ofclass Beetle) rtrue; if (pro ofclass Beetle && pp ofclass Beetle) rtrue; if (pro ofclass Guard || pp ofclass Guard) rtrue; Combat(pro, pp); ! ...or prey. } ]; ! Exit routines [ GetToExit loc thedir theroom; ! Can player get to exit? ! Require room & direction. theroom = loc.thedir; if (SWIMMING == 0) { if (loc has river && theroom has river) ! Underwater tunnel { print"That exit is partly underwater...you'll need to swim to go through it.^"; rfalse; } } else { if (loc has river && theroom hasnt river) ! Can't swim through { print "You climb out of the water and go through the exit.^"; LeaveWater(); rtrue; } } if (loc has river && loc.size < FILLSROOM) ! Must swim to get there { if (RR(LASTROOM) ~= RR(theroom)) { if (SWIMMING == 0) { print"There is water between you and that exit...you'll need to swim to get there.^"; rfalse; } } } ]; [ SwimThroughExit loc thedir theroom diff; ! Can player use exit? ! Require room & direction. theroom = loc.thedir; diff = loc.depth - theroom.depth; if (diff > 0) ! Water flow issues up... { if ((theroom.speed + loc.speed) / 2 > 7) { if (RopeToExit(loc, thedir)) "You use the rope to help you fight the current."; if (random(13) + (actor.strength / 100) > theroom.speed) { "You manage to swim against the current."; } else { print "You swim against the current, but find yourself pushed back. Maybe if you tried again...^"; rfalse; } } } if (diff < 0) ! ...and down. { if (absl(diff) > 39) { "You are swept down the steep waterslide."; } if (absl(diff) > 9 && absl(diff) < 39) "You swim along with the current."; } ]; [ WalkThroughExit loc thedir theroom diff; ! Can player use exit? ! Require room & direction. theroom = loc.thedir; diff = loc.depth - theroom.depth; if (diff > 0) ! Climb up... { if (diff > 39) { if (shoes in player && shoes has worn) "Your shoes help you climb the steep incline."; if (RopeToExit(loc, thedir)) "You use the rope to get you up the steep incline."; if (random(diff) < 7 + (player.strength / 100)) "You manage to scramble up the steep incline."; else { print "You try to climb the steep incline, but you lose your balance and fall back down!^"; ChangeStrength(player, -7); rfalse; } } if (diff > 9) { "You climb up the incline."; } } if (diff < 0) ! ...slide down. { if (absl(diff) > 39) { if (RopeToExit(loc, thedir)) ! tied rope already there? "You use the rope to keep you from slipping down the steep passage."; if (HaveTiedRope()) "Your rope prevents you from slipping down the slope."; if (shoes in player && shoes has worn) "Your shoes help you get down the steep slope."; if (random(absl(diff)) < 7 + (player.strength / 100)) "You manage to keep your balance as you scramble down the steep slope."; else { print"You trip and fall, sliding all the way to the bottom of the steep slope!^"; ChangeStrength(player, -7); rtrue; } } if (absl(diff) > 9 && absl(diff) < 39) "You slide nimbly down the slope."; } ]; [ ObjectHits obj cre; ! Obj hit cre! if (TestScope(cre)) print (The) obj, " hits ", (the) cre, "!^"; else print "You hear a fleshy thump!^"; if (cre provides willfight) cre.willfight = TRUE; ChangeStrength(cre, 1 - obj.weight); BloodyRoom(parent(cre)); ]; [ PutInRiver obj loc cre stop count temp there sweepdir; ! Put obj in river in loc ! (provide optional cre) if (cre) { if (TestScope(cre)) print (The) cre, " throws ", (a) obj, ".^"; } move obj to loc; ! Make sure it's not in river if (obj provides tiedto && obj.tiedto > 0) "The rope almost slips into the river, but it's tied to something."; if (obj has sink) ! Gone... { if (TestScope(obj)) print (The) obj, " splashes into the water and disappears from sight!^"; if (obj has dissolve) ! ...for good? { if (obj.worth == 0) remove obj; else move obj to objectbag; rtrue; } obj.inroom = loc; ! Move to RiverBag for safe- move obj to riverbag; ! keeping. rtrue; } if (TestScope(obj)) print (The) obj, " splashes into the water.^"; ! It floats... while (stop == 0 && count < 10) { if (FindCeiling(obj).speed > 1) ! ...on the current? { sweepdir = LowestWaterExit(parent(obj)); if (sweepdir) { temp = sweepdir.door_dir; there = parent(obj).temp; if (temp.depth > parent(obj).depth) ! Any downward streams? { if (TestScope(obj)) { print (The) obj, " floats away into exit #", sweepdir.num,".^"; } move obj to there; ! Move to next room. if (TestScope(obj)) print (The) obj, " comes floating into the room on the river.^"; } else ! Nowhere to go. { if (TestScope(obj)) print (The) obj, " floats to the shore.^"; stop++; } } else { if (TestScope(obj)) print (The) obj, " floats to the shore.^"; stop++; } } else ! Stagnant water. { if (TestScope(obj)) print (The) obj, " slowly floats to the shore.^"; stop++; } count++; } ]; ! Display current room [ RoomDisplay loc i temp; ! loc=real_location; if (self hasnt visited) { i = 1; if (SHOWNUM == 0) ! Extra points if no room numbers! i = 2; score = score + (whatlevel(loc) * i); } ! Describe current room print "You are "; if (Absl(SHeight(loc)) > 10) ! Cliff or pit? { if (SHeight(loc) > 0) { if (SWIMMING) { print "swimming at the edge of a waterfall "; move owaterfall to loc; } else { print "standing on a cliff "; move ocliff to loc; } } else { if (SWIMMING) print "swimming in a deep pit "; else print "standing in a pit "; move opit to loc; } } if (loc has visited) ! Deja vu? print "back "; print "in "; if (loc.region && REGIONSON) print "a section of "; if (SHOWNUM) { if (loc.region && REGIONSON) print "room #", RR(loc.region), ", a"; ! Region number else print "room #", RR(loc), ", a"; ! Room number } else print "a"; if (Absl(Shallowest(loc) - Deepest(loc)) > 150) ! Crazy shaft you never see? print " deep, vertical shaft"; else RoomSize(loc); ! Room size print " with"; RoomWall(loc); ! Wall texture print ","; RoomColour(loc); ! Wall colour if (ofungus in loc) ! Fungus...? { if (loc.fungus > 80) print ", fungus-choked"; else { if (loc.fungus > 40) print ", fungus-covered"; else print ", fungus-spotted"; } } print " walls. "; if (loc.fungus < loc.moist) { if (loc.fungus) print "Some of the fungus has been scraped off the wall, but it is slowly growing back. "; else print "The walls look like they've been gouged by something. "; } if (loc.size == 6) ! Roof height? print "The roof of the chamber is too high for you to see. "; if (loc.bloody) { switch (loc.bloody) { 0 to 10: print "There are flecks of blood speckling the walls and floor. "; 11 to 25: print "Small splashes of blood decorate the room. "; 26 to 60: print "The remains of a battle are clear in this room: spatters of blood turn the walls into pieces of expressionistic artwork. "; 61 to 10000: print "The walls and floor of the chamber are coated with a thick sheen of gore. "; } } if (loc.regiontype > 1) ! Is region special? { print " "; PrintRegionType(loc.regiontype); print " "; } if (loc has frozen) print "The walls here are covered with a thin sheen of ice. "; PrintScenery(loc); ! Cave features if (fog in loc || poisonmist in loc) ! Fog? { if (poisonmist in loc) print "There is a sheen of evil-looking mist floating around in the air. "; else { if (loc.moist == 100) print "A thick, wet fog fills the chamber and gives the surroundings a dream-like quality. "; else print "A light fog drifts through the cave. "; } } ! Describe exits print "^^"; objectloop(i in Compass) { temp = i.door_dir; if(i provides dung && loc.temp ~= 0) ! Exit exists? PrintExit(loc, i); ! Describe it. } if (HaveTiedRope()) { objectloop (i in player) { if (i provides tiedto && i.tiedto > 0) { print "^Your ", (string) i.specific; if (i.tiedto == FindCeiling(player)) print " is tied to some feature in this cave.^"; else { print " is tied to exit #"; print ExitToRoom(FindCeiling(player), i.tiedto).num, ".^"; } } } } ]; [ PrintRegionType num; ! Print out region type switch (num) { 2: print "A large, underground lake fills these rooms."; 3: print "This network of rooms is much deeper than the rest, probably carved by some long-ago river."; 4: print "These rooms slowly descend in a funnel-shape."; 5: print "The fungus in this region is growing rampant; it must have found some crucial nutrient in the walls."; 6: print "These rooms are more barren and inhospitable than the rest of the caverns."; 7: print "Judging by the high temperature, these caverns must be heated by some neighbouring fire-shaft."; 8: print "Due to some complex interaction with the temperature of the surrounding caverns, these caves are quite cold."; } ]; [ PrintRegionTypeShort num; ! Print short names switch (num) { 2: print "lake"; 3: print "chasm"; 4: print "valley"; 5: print "garden"; 6: print "wasteland"; 7: print "steam room"; 8: print "icebox"; } ]; [ LookRoutine i j k room temp temp2 temp3; ! Printed at the end of every "look" ! & "z" Should be events that change ! (Sounds, etc.) room = real_location; ! Erase ears object properties. ears.isgrubling = 0; ears.isreptodon = 0; ears.isquickpaw = 0; ears.riverspeed = 0; ears.riverdistant = 0; ears.isboga = 0; ears.isrocker = 0; ears.iscompressor = 0; ears.isbeetle = 0; ears.iswumpus = 0; ears.isguard = 0; !/ ears.isbaby = 0; !/ ears.isbabywhich = 0; !/ ears.isbabyaction = 0; if (room provides heat) { switch (room.heat) { -100 to 15: print "It's freezing cold in this place!^"; ChangeStrength(player, -2); 16 to 35: print "It's a bit chilly in here.^"; 200 to 250: print "It's warm in here.^"; 251 to 300: print "It's hot in here!^"; 301 to 350: print "It's so hot in here that you're sweating profusely.^"; player.thirst--; 351 to 1000: print "You can't bear this heat!^"; player.thirst--; ChangeStrength(player, -4); } } if (room has poison && Gasmask hasnt worn) { if (DISEASE == FALSE) print "Breathing the mist in this room makes you feel sick!^"; DISEASE = DISEASE + 2; } if (room ofclass C_ROOMS) { objectloop (k in room) ! First, check own room... { CheckEars(k, 3); } objectloop (k in player) ! ...and carried objects... { CheckEars(k, 3); } if (playpen in room) { objectloop (k in playpen) ! ...and playpen... { CheckEars(k, 3); } } if (room has river) ears.riverspeed = room.speed; else ears.riverspeed = 0; !/ if (ears.isbaby == 3) !/ { !/ print "You can't hear anything with "; !/ print (the) ears.isbabywhich, " making so much noise!^"; !/ rtrue; !/ } objectloop(i in Compass) ! ...then, check adjacent room... { temp = i.door_dir; temp2 = room.temp; if(ValidDir(room, i)) { objectloop (k in temp2) { CheckEars(k, 2); } if (temp2 has river && temp2.speed > ears.riverspeed) { ears.riverspeed = temp2.speed; ears.riverdistant = 0; } } if (temp2 ofclass C_ROOMS) { objectloop (j in Compass) ! ...and finally, distant rooms. { temp = j.door_dir; temp3 = temp2.temp; if (ValidDir(temp2, j) && temp3 ~= room) { objectloop (k in temp3) { CheckEars(k, 1); } if (temp3 has river && temp3.speed > ears.riverspeed + 1) { ears.riverspeed = temp3.speed; ears.riverdistant = 1; } } } } } if (room hasnt river || room.speed < 9) ! Does waterfall drown everything out? { if (ears.isgrubling == 1 or 2) { print "Something "; if (ears.isgrubling == 1) print "far away "; else print "nearby "; print "is making a larval sucking sound.^"; } if (ears.isreptodon == 1 or 2) { print "You can hear "; if (ears.isreptodon == 1) print "distant "; print "scales scraping "; if (ears.isreptodon == 2) print "loudly "; print "through one of the exits.^"; } if (ears.isrocker == 1 or 2) { print "The ground "; if (ears.isrocker == 1) print "vibrates "; else print "shakes dangerously "; print "to the beat of heavy footsteps.^"; } if (ears.isquickpaw == 1 or 2) { print "You can "; if (ears.isquickpaw == 1) print "barely "; print "hear the soft pattering of feet through one of the exits.^"; } if (ears.isboga == 1 or 2) { print "Something "; if (ears.isboga == 1) print "deep in the caverns "; else print "nearby "; print "is belching loudly.^"; } if (ears.iscompressor == 1 or 2) { print "You can "; if (ears.iscompressor == 1) print "barely hear a distant whooshing sound.^"; else print "hear a loud whooshing noise nearby.^"; } if (ears.isbeetle == 1 or 2) { print "There is a "; if (ears.isbeetle == 1) print "quiet ticking"; else print "loud ticking"; print " coming from one of the exits.^"; } if (ears.isguard == 1 or 2) { print "You can hear the "; if (ears.isguard == 1) print "far-off "; print "sound of marching feet"; if (ears.isguard == 2) print " close by"; print ".^"; } !/ if (ears.isbaby == 1 or 2) !/ { !/ print "You can "; !/ if (ears.isbaby == 1) !/ print "barely "; !/ print "hear a baby through one of the exits...it sounds like it "; !/ print (string) ears.isbabyaction.currentmsg, ".^"; !/ } } if (ears.iswumpus == 1 or 2 && Gasmask hasnt worn) { if (ears.iswumpus == 2) print "A horrible stench is pouring"; else print "An unpleasant odour is drifting"; print " into the cave from somewhere nearby.^"; } if (ears.riverspeed > 3) ! MUST BE THE LAST BLOCK IN ROUTINE { if (room has river && room.speed > ears.riverspeed) return; ! (Due to this) if (ears.riverspeed > 8) { print "The "; if (ears.riverdistant) print "distant "; else print "deafening "; print "sound of a waterfall roars through the chamber.^"; } else { if (ears.riverspeed > 3) { print "You can hear the "; if (ears.riverdistant) print "distant "; print "sound of running water.^"; } } } } ]; [ CheckEars obj distance temp; ! Fill in ears with obj & distance. if (obj ofclass Grubling && ears.isgrubling == 0) ears.isgrubling = distance; if (obj ofclass Reptodon && ears.isreptodon == 0) ears.isreptodon = distance; if (obj ofclass Guard && ears.isguard == 0) ears.isguard = distance; if (obj ofclass quickpaw && ears.isquickpaw == 0) ears.isquickpaw = distance; if (obj == boga && ears.isboga == 0 && distance == 2) ears.isboga = distance; if (obj ofclass Rocker && ears.isrocker == 0) ears.isrocker = distance; if (obj == Compressor && ears.iscompressor == 0) ears.iscompressor = distance; if (obj ofclass Beetle && ears.isbeetle == 0) ears.isbeetle = distance; if (obj == Wumpus && ears.iswumpus == 0) ears.iswumpus = distance; temp = temp; ! To stop compiler bitching !/ if (obj ofclass Baby) !/ { !/ temp = obj.last; !/ if (temp && ears.isbaby == 0 && temp.noisy) !/ { !/ ears.isbaby = distance; !/ ears.isbabyaction = obj.last; !/ ears.isbabywhich = obj; !/ } !/ } ]; [ MoveCreature i cdir room croom test; ! Move creature given creature & exit room = parent(i); croom = room; ! Can creature go there? if (cdir == 0) ! Invalid direction? return 0; if (player in room && cdir == ExitToRoom(room, LASTROOM)) { test = random(300); if (test < i.speed || i.weight < 3) { print (The) i, " slips past you.^"; } else { print (The) i, " tries to escape past you, but you're standing in the way.^"; rtrue; } } ! Yes. if (TestScope(i)) print (The) i, " ", (string) i.leavestring, " into exit ", cdir.num, ".^"; i.lroom = room; move i to room.(cdir.door_dir); if (TestScope(i)) ! ...after moving. { print "You see ", (a) i, " ", (string) i.enterstring, " from exit "; print ExitToRoom(parent(i), croom).num, ".^"; } ]; [ PrintExit loc i croom diff temp; ! Describe exit, receive room# & exit# print "Exit ", i.num; temp = i.door_dir; croom = loc.temp; diff = loc.depth - croom.depth; if (diff > 0) { if (diff > 39) print " rises steeply"; else { if (diff > 19) print " rises"; else { if (diff > 9) print " rises very slightly"; else ExitDescribe(Absl(diff)); } } } else { if (Absl(diff) > 39) print " drops sharply"; else { if (diff > 19) print " swiftly descends"; else { if (Absl(diff) > 9) print " slowly descends"; else ExitDescribe(Absl(diff)); } } } print " toward"; if (WhatLevel(loc) ~= WhatLevel(croom)) { print " some distant"; if (croom hasnt visited) print " unexplored"; print " room. "; } else { if (croom hasnt visited) { print " an unexplored "; if (croom.region && croom.region == loc.region && REGIONSON) print "part of this "; print "room. "; } if (SHOWNUM == 0 && croom has visited) { if (croom.region && croom.region == loc.region && REGIONSON) print " a familiar part of this room."; else print " a"; } else { if (SHOWNUM && croom has visited) { if (croom.region && croom.region == loc.region && REGIONSON) print " a familiar part of this room."; else { if (croom.region) print " room ", RR(croom.region), " (A"; else print " room ", RR(croom), " (A"; } } } if (croom has visited) { if (croom.region && croom.region == loc.region && REGIONSON) croom = croom; else { ExitSize(croom); print ","; if (croom.moist < 26) print " dark"; else RoomWall(croom); if (croom has frozen) print ", frozen"; if (croom has river) print ", watery"; print " chamber."; if (SHOWNUM) print ")"; } } } if (croom == LASTROOM) print " **"; print "^"; ]; [ SwimRoutine loc sweepdir temp there; if (loc.speed > 7 && random(13) + (actor.strength/100) < loc.speed) { if (HaveTiedRope()) { print "The strong current almost washes you off your feet, but your rope saves you!^"; rfalse; } print "The strong current sweeps you off your feet!^"; sweepdir = LowestWaterExit(loc); temp = sweepdir.door_dir; there = loc.temp; if (temp.depth >= loc.depth) { print "Helpless to resist, you are washed into exit #", sweepdir.num,".^^"; PressKeyRandom(); print "^"; << Go sweepdir >>; } else { print "You are brutally smashed against the edge of the river channel.^"; ChangeStrength(player, -10); } } rfalse; ]; [ PrintCanteen obj; ! Print canteen status switch (obj.level) { 0: print "empty"; 1: print "almost empty"; 2: print "half full"; 3: print "almost full"; 4: print "full"; } ]; [ PrintCreCompare cre crewith per; ! Compare strengths ! of cre & crewith print "Compared with ", (the) cre, ", ", (the) crewith," is "; per = PercentTwo (cre.strength, crewith.strength); switch (per) { 0 to 25: print "an easy target"; 26 to 50: print "weaker"; 51 to 125: print "more-or-less equal"; 126 to 150: print "stronger"; 151 to 30000: print "an unbeatable foe"; } print ".^"; ]; [ PrintScenery loc; ! Print scenery info if ((loc + loc.depth) % 10 < 5) ! How common are features? { switch ((loc + loc.speed * loc.moist) % 26) { 1 to 3: if (loc.size < 6) { if (loc.moist > 75) { print "Dripping stalagtites "; move odrips to loc; } else print "Stalagtites "; print "hang from the ceiling"; if (loc.size < 2) print ", almost touching the floor. "; else print " high above. "; } move ocolumns to loc; 4 to 5: print "Stalagmites rise out of the floor, "; if (loc.size < 2) print "almost reaching the roof. "; else print "reaching for the roof of the cave. "; move ocolumns to loc; 6: print "Beautiful stone columns rise from the floor"; if (loc.size == 6) print ", presumably joining with the ceiling far above. "; else print " and join with the cave ceiling. "; move ocolumns to loc; 7 to 8: print "A jumble of broken rock lies on the floor, presumably from a long-ago cave-in. "; move orubble to loc; 9: print "Small, shallow pits "; if (loc.moist > 90) { print "filled with stagnant water "; move odrips to loc; } print "pock the floor here and there. "; move opits to loc; 10: print "Some patches of rock coral decorate the floor and walls. "; move orubble to loc; 11: print "Drapery-like sheets of rippled rock hang down around you. "; move ocolumns to loc; 12: print "A ridge of stone, almost like a diving board, extends over "; if (loc has river) print "the water in the middle of the room. "; else print "a slight depression in the ground. "; move oridge to loc; move opits to loc; 13: if (loc.size < 6) { print "Long, hollow strands of rock hang down from the cavern roof. "; move ocolumns to loc; } 14: print "A huge arc spans the length of the cave"; if (loc.size < 6) print ". "; else print ", its apex out of sight. "; move oarc to loc; 15: if (loc.size == 6) print "The cave is a curiously cylindrical shaft, extending upwards. "; else print "A shaft ascends from the roof of the cave, but it is so wide and featureless that it cannot be climbed. "; if (loc has river) { if (loc.speed > 4) print "A steady stream of water pours down the shaft and into the river below. "; else print "Small drops of water fall out of the shaft and hit the pool below. "; move odrips to loc; } move oshaft to loc; 16: if (loc.size > 2 && loc hasnt river) { print "A deep, elongated cavity runs the length of the cavern. "; move opits to loc; } 17 to 18: print "Shallow clefts mar the walls of the cave. "; move opits to loc; 19: if (loc.size < 6) { print "The roof of the cave is smoothly domed. "; move oarc to loc; } 20 to 21: print "Tiny fissures mar the floor. "; move opits to loc; 22 to 23: if (loc has river && loc.speed > 2) print "Fine sand "; else print "Coarse gravel "; print "covers much of the cave floor. "; move orubble to loc; 24 to 25: if (loc.size > 4) { print "This chamber is so long and narrow that it would be better called a hall. "; move oarc to loc; } } } ]; [ ExitDescribe diff; ! Describe exit from height difference switch (diff % 9) { 0: print " corkscrews"; 1: print " meanders"; 2: print " twists"; 3: print " turns"; 4: print " goes"; 5: print " moves"; 6: print " weaves"; 7: print " curves"; 8: print " stretches"; } ]; [ ExitSize room; ! Print size of exit room switch (room.size) { 0: print " tiny"; 1: print " small"; 2 to 4: print " fair-sized"; 5: print " large"; 6: print " vast"; } ]; [ RoomSize room; ! Print size of given room switch (room.size) { 0: print " tiny, cramped"; 1: print " small"; 2 to 4: print " fair-sized"; 5: print " large"; 6: print " vast"; } PrintRoomType(room); ]; [ PrintRoomType room; if (room.region && REGIONSON) { print " "; if (room.regiontype == 1) print "region"; else PrintRegionTypeShort(room.regiontype); } else { if (SNumExits(room) == 1) print " dead-end"; else { switch (room % 4) { 1: print " cave"; 2: print " cavern"; 3: print " room"; 0: print " chamber"; } } } ]; [ RoomWall room; ! Describe walls of room switch ((room.depth) % 6) { 0: print " pocked"; 1: print " polished"; 2: print " jagged"; 3: print " creased"; 4: print " textured"; 5: print " rough"; } ]; [ RoomColour room; ! Describe wall colours switch (WhatLevel(room)) { 1: print " orange"; 2: print " brown"; 3: print " grey"; 4: print " onyx"; 5: print " crystalline"; } ]; [ DescribeWind loc; ! Describe the wind loc = real_location; if (loc.wind < 20) "An intermittant breeze sturs the air."; print "A"; switch (loc.wind) { 20 to 39: print " light breeze puffs from"; 40 to 55: print " steady breeze blows from"; 56 to 75: print " steady wind blows from"; 76 to 90: print " strong wind rushes from"; 91 to 1000: print " blast of air is blowing from"; } WindPrint(loc); ]; [ DescribeRiver loc; ! Describe river loc = real_location; print "A "; if (WaterExits(loc, 0) == 0) print "stagnant pool lies in the middle of the cavern."; else { if (loc.regiontype == 2) print "huge lake stretches from"; else { switch (loc.speed) { 0 to 1: print "motionless swamp stretches from"; 2 to 3: print "sluggish stream oozes from"; 4 to 6: print "slow-moving river flows from"; 7 to 8: print "fast-flowing river rushes from"; 9 to 10: if (WaterExits(loc, 1) > 0) print "gush of water bursts from"; else { print "waterfall cascades from"; move owaterfall to loc; } } } RiverPrint(loc); } if (loc.size < FILLSROOM) print" It fills the entire room with water."; print "^"; ]; [ WindPrint room; ! Print wind from/to print " exit "; print WindExitFrom(room).num; if (WindExitTo(room)) print " to exit ", WindExitTo(room).num; print ".^"; ]; [ RiverPrint room count i temp temp2 nume; ! Print river from/to nume = WaterExits(room, 1); ! How many higher exits? if (nume == 0) print " an underground source"; else { count = 1; objectloop(i ofclass CompassDirection) ! Loop room's exits { temp = i.door_dir; temp2 = room.temp; if(i provides dung && room.temp ~= 0 && room.temp has river && room.depth > temp2.depth) ! Exits go high w/ river? { print " "; if (count == 1) print "exit"; if (nume > 1 && count == 1) print "s"; print " ",i.num; count++; if (count == nume) print " &"; if (count < nume && nume > 2) print ","; } } } if (room.speed > 1) print ", through the room, and into"; else print " into"; nume = WaterExits(room, -1); ! How many lower exits? if (nume == 0) print " a tiny crack in the wall"; else { count = 1; objectloop(i ofclass CompassDirection) { temp = i.door_dir; temp2 = room.temp; if(i provides dung && room.temp ~= 0 && room.temp has river && room.depth <= temp2.depth) ! Exits go low w/ river? { if (count == 1) print " exit"; if (nume > 1 && count == 1) print "s"; print " ",i.num; count++; if (count == nume) print " &"; if (count < nume && nume > 2) print ","; } } } print "."; ]; [ SetupDungeon x count room croom repeat out down i temp temp2 maxsteps iterate num nroom highest; ! First, create empty rooms. for (x = 1: x <= MAXROOMS: x++) { if (x == 1) FIRSTROOM = C_ROOMS.create(); ! Set FIRSTROOM else C_ROOMS.create(count); count++; } ! Safety net: connect levels together. for (x = 5: x >= 1: x--) { room = RandRoom(x); if (x == 1) { ! Connect top level to surface LOCATION1 = room; room.conn = 1; ! For upcoming connection test room.fungus = 35; room.heat = 100; } else Connect (room, RandRoom(x - 1)); ! Connect level to one above. } ! Comprehensive: connect all rooms within level for (repeat = 1: repeat <= 1: repeat++) ! As comprehensive as you like. { for (out = 1: out <= NRL(): out++) ! Proceed out through the levels. { for (down = 1: down <= 5: down++) ! ...and down the levels. { PickMakeRoom(FR((down - 1) * NRL() + out), 0); } } } ! Extra: connect rooms outside levels for (repeat = 1: repeat <=1: repeat++) ! As extensive as you like { for (room = 1: room <= MAXROOMS: room++) ! Through all the rooms. { if (random(100) < 7) ! ADJUST: > more extra-level connections { PickMakeRoom(FR(room), 2); } } } ! Do connection test count = 0; maxsteps = 0; iterate = 0; highest = 0; repeat = 0; do { for (room = FR(1): room <= FR(MAXROOMS): room++) ! Through all rooms { if (room.conn > 0) ! Is room connected? { if (maxsteps < room.conn) maxsteps = room.conn; ! Find max # steps objectloop(i ofclass CompassDirection) ! Loop room's exits { temp = i.door_dir; if(i provides dung && room.temp ~= 0) ! Exits go anywhere? { temp2 = room.temp.conn; if (temp2 == 0) count++; if (temp2 == 0 || temp2 > room.conn + 1) ! Spread out { room.temp.conn = room.conn + 1; ! connection markers if (room.conn + 1 > highest) { highest = room.conn + 1; repeat = room.temp; } } } } } } iterate++; ! Safety exit } until (count == 99 || iterate == 10); ! print "Furthest room: ", repeat," (", highest,")^"; LOCATION100 = repeat; if (iterate == 10) ! Not all rooms connected. { for (room = FR(1): room <= FR(MAXROOMS): room++) ! Through all rooms { if (room.conn == 0) ! Not connected? { count = 0; do { count++; temp2 = RandRoom(WhatLevel(room)); ! Room in own level? } until (temp2.conn ~= 0 || count > 30); if (temp2.conn == 0) { count = 0; do { count++; temp2 = RandRoom(random(5)); ! Room in any level. } until (temp2.conn ~= 0 || count > 80); } if (temp2.conn == 0) print "No hope.^"; else ! Force connection. { Connect(room, temp2); room.conn = temp2.conn + 1; } } } } ! Apply depths PrintIntro(2, 1); for(iterate = 0:iterate < RANDSEED:iterate++) ! Scoffed from Jim Fisher. random(1); ! Initial depths (based on level, distance from entrance, and random) for (room = FR(1): room <= FR(MAXROOMS): room++) ! Through all rooms { room.depth = (WhatLevel(room) * 50) + (room.conn * 4); room.depth = room.depth + (50 - random(100)); } ! Smooth the depths for (repeat = 1: repeat <= 4: repeat++) ! As many times as you like { for (room = FR(1): room <= FR(MAXROOMS): room++) ! Through all rooms { room.depth = (SSumDepth(room) + room.depth) / (SNumExits(room) + 1); } } ! Some pits for (count = 1: count <= 6: count++) ! Make pits { room = RandRoom(2 + random(3)); ! Pick a room in levels 3 to 5 room.depth = room.depth + 50 + random(100); for (repeat = 1: repeat <= 3: repeat++) ! Wider & wider... { objectloop (i ofclass CompassDirection) ! Make wider pits { temp = i.door_dir; if(i provides dung && room.temp ~= 0) { temp2 = room.temp; temp2.depth = (temp2.depth + room.depth) / 2; } } room = Shallowest(room); ! Move to next room...eat } } ! Build streams ! Start springs x = 0; for (count = 1: count <= 3: count++) ! Make 3 springs { room = RandRoom(random(5)); ! Pick a random room croom = room; ! Store it up for later ! Move down... num = random(4) + 3; for (down = 1: down <= num: down++) ! Go down random steps { if (room hasnt river) x++; give room river; ! Give room necessary room.moist = 20; ! attributes if (Deepest(room) == room) ! Pick next room nroom = SRandom(room); else nroom = Deepest(room); room.speed = room.speed + Absl(room.depth - nroom.depth) / 3; if (room.speed > 10) room.speed = 10; room.moist = room.moist + room.speed * 2; room = nroom; } ! ...and up... room = croom; num = random(4) + 3; for (out = 1: out <= num: out++) ! Go up random steps { if (room hasnt river) x++; give room river; ! Give room necessary room.moist = 20; ! attributes if (Shallowest(room) == room) ! Pick next room nroom = SRandom(room); else nroom = Shallowest(room); room.speed = room.speed + Absl(room.depth - nroom.depth) / 3; if (room.speed > 10) room.speed = 10; room.moist = room.moist + room.speed * 2; room = nroom; } } PrintIntro(3, 1); ! Make wind path ! Pick source room do { room = RandRoom(5); } until (room hasnt river); FURNACE = room; room.heat = 400; room.wind = 100; x = room.wind; croom = room; ! Move up num = random(4) + 16; for (out = 1: out <= num: out++) ! Go up random steps { x = room.wind - (out * 7); if (croom.heat == 0) { croom.wind = x * 2; croom.heat = x * 3; } croom.moist = 20; if (Shallowest(croom) == croom) ! Pick next room { count = 0; do { nroom = SRandom(croom); count++; } until (nroom.wind == 0 || count == 15); } else nroom = Shallowest(croom); croom = nroom; } room = RandRoom(4); FREEZER = room; give room frozen; room.heat = 1; room.moist = 1; room.wind = 1; room.fungus = 0; room.depth = room.depth + 100; objectloop (i ofclass CompassDirection) ! Spread out cold { temp = i.door_dir; if (i provides dung && room.temp ~= 0) { croom = room.temp; give croom frozen; croom.heat = 1; croom.moist = 1; croom.wind = 1; croom.fungus = 0; croom.depth = croom.depth + 50; } } ! Make first level hospitable for (room = FR(1): room <= FR(MAXROOMS/5): room++) { if (room.conn < 7) { room.moist = 80 - (room.conn * 10); room.heat = 100 - (room.conn * 10); room.fungus = room.moist; } } ! Spread out moisture, heat & wind for (repeat = 1: repeat <= 5: repeat++) ! As many times as you like { for (room = FR(1): room <= FR(MAXROOMS): room++) ! Through all rooms { if (room.moist > 0 || room.heat > 0 || room.wind > 0) { objectloop(i ofclass CompassDirection) ! Loop room's exits { temp = i.door_dir; if(i provides dung && room.temp ~= 0) ! Exits go anywhere? { croom = room.temp; ! Define room if (room.moist) croom.moist = croom.moist + room.moist / 8; if (room.heat) croom.heat = croom.heat + room.heat / 4; if (room.wind) croom.wind = croom.wind + room.wind / 5; if (croom.moist > 100) croom.moist = 100; if (croom has frozen) croom.heat = croom.heat /4; if (croom.heat > 400) { if (WhatLevel(croom) == 5) croom.heat = 400; else croom.heat = croom.heat /3; } if (croom.wind > 100) croom.wind = 100; croom.fungus = croom.moist; } } } } FREEZER.heat = 1; FREEZER.moist = 1; FREEZER.wind = 1; FREEZER.fungus = 0; } ! Assign cavern sizes ! Random assignment for (count = 1: count <= 10: count++) ! Pick 20 rooms { room = RandRoom(random(5)); ! Pick a room on any level room.size = 0; ! Tiny room = RandRoom(random(5)); room.size = 6; ! Huge } ! Spread out cave sizes for (repeat = 1: repeat <= 4: repeat++) ! As many times as you like { for (room = FR(1): room <= FR(MAXROOMS): room++) ! Through all rooms { objectloop(i ofclass CompassDirection) ! Loop room's exits { temp = i.door_dir; temp2 = room.temp; if(i provides dung && room.temp ~= 0) ! Exits have chosen size? { croom = room.temp; ! Define room croom.size = croom.size + ((room.size - 3)/2); if (croom.size > 6) croom.size = 6; if (croom.size < 0) croom.size = 0; } } } } ! Define regions for (room = FR(1) + NRL(): room <= FR(MAXROOMS): room++) ! Through all rooms { if (room.region == 0 && room.size > 5 && room ~= FREEZER && room ~= FURNACE) { repeat = NearbyRegion(room); if (repeat) { room.region = repeat.region; ! Adopt nearby region room.regiontype = repeat.regiontype; room.regiondepth = repeat.regiondepth; ApplyRegion(room); } else { if (NearbyVast(room)) { room.region = room; ! Create new region if (WhatLevel(room) > 1 && random(6) < 4) ! Will it be special? { room.regiontype = random(7) + 1; room.regiondepth = room.depth; ApplyRegion(room); } else ! No, mark it normal. { room.regiontype = 1; } objectloop(i ofclass CompassDirection) { temp = i.door_dir; temp2 = room.temp; if (i provides dung && room.temp ~= 0) { if (temp2.size > 5 && WhatLevel(room) == WhatLevel(temp2)) { temp2.region = room; ! Spread region temp2.regiontype = room.regiontype; temp2.regiondepth = room.regiondepth; ApplyRegion(temp2); } } } } } } } PrintIntro(4, 1); ! Some pools... for (count = 1: count <= 5: count++) ! Make 5 pools { room = RandRoom(random(5)); ! Pick a random room give room river; room.moist = room.moist + 20; if (room.moist > 100) room.moist = 100; } ! Place and define creatures objectloop(i ofclass Creature) { if (i.shuffler) ! Set up unique creature name { ShufflerName(i); if (i ofclass Guard) { move i to LOCATION100; if (i.type < 5) give i female; } } if (i.inlevel > 0) move i to RandRoom(i.inlevel); else { if (i == Hurkle) IntoQuietPool(Hurkle); if (i == Boga) move i to FURNACE; if (i ofclass Beetle) move i to beetlebag; } if (parent(i) == nothing) move i to creaturebag; if (i == tb_1) { count = RandRoom(5); move i to count; } if (i ofclass Baby) { DefineBaby(i); move i to playpen; } } move Wumpus to count; move Eggsack to count; ! Place chutes objectloop (i ofclass Chute) { do { count = RandRoom(i.clevel); } until (count hasnt river); move i to RandRoom(i.clevel); } ! Place barrels objectloop (i ofclass Barrel) { move i to RandRoom(i.clevel); StartTimer(i, random(20) * i.clevel); } ! Place objects in objectbag & jewelbag... objectloop(i ofclass CaveObject) { if (parent(i) == nothing && ~~i ofclass Corpse) { if (i ofclass Jewel) move i to jewelbag; else move i to objectbag; } } ! Define jewels and place half of them count = 0; maxsteps = children(jewelbag) / 2; objectloop (i ofclass Jewel) { count++; AlchemyRandom(i); if (count <= maxsteps) { room = RandRoom(random(3) + 2); move i to room; if (room has river && random(2) == 1) PutInRiver(i, room); } } LOCATION1.fungus = 30; Connect(LOCATION100, EndRoom); EndRoom.depth = LOCATION100.depth; ! Set up markers to exit. for (room = FR(1): room <= FR(MAXROOMS): room++) room.conn = 0; EndRoom.conn = 1; LOCATION100.conn = 2; count = 0; maxsteps = 0; iterate = 0; highest = 0; repeat = 0; do { for (room = FR(1): room <= FR(MAXROOMS): room++) ! Through all rooms { if (room.conn > 0) ! Is room connected? { if (maxsteps < room.conn) maxsteps = room.conn; ! Find max # steps objectloop(i ofclass CompassDirection) ! Loop room's exits { temp = i.door_dir; if(i provides dung && room.temp ~= 0) ! Exits go anywhere? { temp2 = room.temp.conn; if (temp2 == 0) count++; if (temp2 == 0 || temp2 > room.conn + 1) ! Spread out { room.temp.conn = room.conn + 1; ! connection markers } } } } } iterate++; ! Safety exit } until (count == 99 || iterate == 20); ]; [ Shufflername cre count temp ; ! Set up unique cre name do { count = 1; cre.type = random(cre.shuffler); objectloop (temp ofclass Creature) { if (temp ~= cre && temp.creclass == cre.creclass) { if (temp.type == cre.type) count = 0; } } } until (count); ]; [ ApplyRegion room i temp temp2; ! Define special regions switch (room.regiontype) { 2: room.depth = room.regiondepth + 30; give room river; room.speed = room.speed / 2; room.moist = 75; room.fungus = 75; 3: room.depth = room.depth + 100; 4: room.depth = room.depth + 25; objectloop (i ofclass CompassDirection) { temp = i.door_dir; if (i provides dung && room.temp ~= 0) { temp2 = room.temp; if (temp2.region == room.region) temp2.depth = (temp2.depth + room.depth) / 2; } } 5: room.moist = 100; room.fungus = 100; room.heat = 225; 6: room.depth = room.regiondepth; give room ~river; room.moist = 0; room.fungus = 0; 7: room.moist = 100; room.wind = 0; room.heat = 325; 8: room.moist = 0; room.wind = 0; room.fungus = 0; room.heat = 0; give room frozen; } ]; [ SpillObjectBag sum x level obj toroom; ! Randomly distribute some objects sum = children(ObjectBag); for (x = 1: x < sum/2: x++) ! Empty half of the objects { level = random(5); ! Pick a random level obj = PilferObjectBag(0, level * 10); ! Pick an object that suits level if (obj == 0) return; ! No applicable objects? toroom = RandRoom(level); move obj to toroom; if (toroom has river && obj.worth < 26) { PutInRiver(obj, toroom); } } ]; [ IntoQuietPool cre croom count; ! Put cre in a quiet pool croom = RandRoom(3); do { if (IsQuietPool(croom)) { move cre to croom; give cre concealed; cre.hiding = 1; rtrue; } count++; croom++; if (croom == FR(MAXROOMS)) croom = FR(1); } until (count == MAXROOMS); ]; [ PilferObjectBag lowest highest sum pick y x; ! Grab object worth lowest to highest sum = 0; ! or 0 if none apply objectloop (x in ObjectBag) ! How many objects meet requirements? { if (x.worth >= lowest && x.worth <= highest) sum++; } if (sum == 0) return 0; ! No applicable objects. pick = random(sum); objectloop (x in ObjectBag) ! Choose random object. { if (x.worth >= lowest && x.worth <= highest) y++; if (y == pick) return x; } ]; [ Alchemy cre x picked numobjs weightobjs worthobjs; while (child(cre)) { x = child(cre); numobjs++; weightobjs = weightobjs + x.weight; worthobjs = worthobjs + x.worth; if (x ofclass Jewel) move x to jewelbag; else { if (x ofclass Corpse) remove x; else move x to objectbag; } } objectloop (x in jewelbag) picked = x; if (picked == 0) rtrue; picked.quality = random(6); picked.lightness = random(2); picked.color = random(6); picked.weight = (weightobjs / numobjs) / 10; if (picked.weight == 0) picked.weight = 1; picked.worth = (1 + worthobjs / numobjs) * 30; picked.monworth = worthobjs; if (TestScope(cre)) { print "There is a blinding flash of light, and ", (the) cre, " screams in pain and loss.^"; print (The) cre, " drops ", (a) picked, ".^"; } move picked to FindCeiling(cre); if (FindCeiling(cre) has river) PutInRiver(picked, FindCeiling(cre)); ]; [ AlchemyRandom picked; ! Give picked random stats. picked.quality = random(6); picked.lightness = random(2); picked.color = random(6); picked.weight = (random(10)); picked.worth = random(100); picked.monworth = 20 + picked.worth * 3; ]; [ DefineBaby; !cre repeat count; ! Create unique baby !/ repeat = 1; !/ while (repeat) !/ { !/ repeat = 0; !/ cre.size = random(8); !/ cre.language = random(10); !/ cre.happy = random(100); !/ if (random(100) > 49) !/ give cre female; !/ else !/ give cre ~female; !/ objectloop (count ofclass Baby) !/ { !/ if (count.size == cre.size && count.language == cre.language && count ~= cre) !/ repeat == 1; !/ } !/ } ]; [ OozeIncrement level; switch (level) { 1: return 10; 2: return 20; 3: return 40; 4: return 80; 5: return 160; } ]; [ PickMakeRoom room type croom count level pass; ! Connect given room with a random room ! Room MUST be FR when sent!!! if (NumCon(room) < 4) ! Any connections available? { count = 0; level = WhatLevel(room); ! Level to attend to switch (type) { 0: croom = RandRoom(level); ! Pick a connecting room in current level 1: croom = RandRoom(random(5)); ! Pick a connecting room in any level 2: if (level == 1) ! Pick a room in adjacent level croom = RandRoom(level + 1); else croom = RandRoom(level - 1); } do { pass = 0; ! Success of loop count++; ! No endless loop! croom++; ! Work way through rooms in level if (type == 0) { if (croom > LLevel(level)) ! Go to first room in level if outside level croom = FLevel(level); } if (room ~= croom && NumCon(croom) < 4 && NotAlreadyCon(room, croom)) pass = 1; ! "Pass" if croom is distinct & connectable } until (pass || count > NRL()); if (pass) { Connect(room, croom); ! Connect rooms if croom is viable. } } ]; [ NotAlreadyCon room croom pass num x tester; ! To stop multiple identical connections pass = 1; num = NumCon(room); for (x = 1: x <= num: x++) { switch (x) { 1: tester = room.x1_to; 2: tester = room.x2_to; 3: tester = room.x3_to; 4: tester = room.x4_to; 5: tester = room.x5_to; } if (tester == croom) pass = 0; } return pass; ]; [ Connect room croom x rfrom rto; ! Connect given rooms (must be possible!) for (x = 1: x <= 2: x++) ! Reduce code redundancy. { if (x == 1) { rfrom = room; rto = croom; } else { rfrom = croom; rto = room; } switch (FirstCon(rfrom)) { 1: rfrom.x1_to = rto; 2: rfrom.x2_to = rto; 3: rfrom.x3_to = rto; 4: rfrom.x4_to = rto; 5: rfrom.x5_to = rto; } } ]; [ DrawStatusLine width posa posb; @split_window 1; @set_window 1; @set_cursor 1 1; style reverse; width = 0->33; posa = width-14; posb = width-13; spaces width; @set_cursor 1 2; if (SHOWNUM) { if (real_location.region) print "Room #", RR(real_location.region); else print "Room #", RR(real_location); } if (FORFEIT == 0) { @set_cursor 1 posa; print " Score: ", score; } @set_cursor 2 1; spaces width; @set_cursor 2 2; if (location == thedark) print (name) location; else { FindVisibilityLevels(); if (visibility_ceiling == location) print (name) location; else print (The) visibility_ceiling; } @set_cursor 2 posa; print "Health: ", Health(player), "%"; @set_cursor 1 1; style roman; @set_window 0; ]; [ PrintIntro part anykey; if (anykey) { PressKeyRandom(); print "^^"; } switch (part) { 1: print "^Some people love exploring caves, and some people get a sick thrill out of falling. But you're not one of them.^^ Since childhood you've had a fear of heights, depths, and quick trips in between; those dreams about endless drops into bottomless pits still haunt you, especially when you've had a bit to drink. You were also one of those kids who was CONVINCED that the boogeyman lurked under the basement steps, down there in the cold and clammy darkness. Nope, you are definitely NOT a fan of these two exotic pleasures of falling and darkness, which is why you're not thrilled about being thrown into a deep, forbidding shaft. If the fall lasts long enough maybe you'll get a chance to ponder what's at the bottom of it all, and what you left behind on the surface...^^"; 2: print "To be fair you HAVE plumbed these depths, though not in a very heroic way. You've done research and talked to people, mainly. When you devoted last week's editorial to exposing the shady dealings of New Jersey public officials, you thought you'd be given a promotion. Maybe the newspaper chain would bump you up to some big city assignment, get you away from the little Morristown rag you'd been working on for seven years.^^ Apparently, the one thing you DIDN'T find out in your research was that those public officials OWN the newspaper chain, and that they're even more ruthless and immoral than you'd thought. Now, after being dragged out of bed and dumped into the pit itself, it looks like that promotion is a long way off.^^"; 3: print "But what IS in this pit? You've read facts about it in geological surveys. You've heard all the local folklore about the mythical creatures lurking down there -- the Wumpus was probably the most colourful monster of the bunch -- and you know for a fact that the city's been dumping toxic waste into it for years. Leave it to a bunch of suburban fat-cats to arrange a billion-dollar waste-disposal contract, and then just hire some local thugs to dump the stuff into a hole under Morristown. Could that toxic junk be leaking into the city's water supply? Lots of people are speculating, but nobody has had the courage to actually go DOWN there to check it out.^^"; 4: print "Well, looks like you've been reluctantly nominated. If you survive the fall, you might get a chance to solve these mysteries...and maybe win a Pulitzer Prize to boot! You've been falling for a long time, and it's almost time to land...for better or for worse.^^ And hey, maybe that Wumpus thing is really friendly?^^"; } ]; ! ----------------------------- Meta mappin' functions [ Surrounding room iteration endit lastroom i newroom; ! Sonar surrounding room print "^Room #", RR(room),", ", SnumExits(room), " exits.^"; if (iteration == endit) { print "...(Back to)...^"; rtrue; } for (i = 1: i <= SNumExits(room): i++) { switch (i) { 1: newroom = room.x1_to; 2: newroom = room.x2_to; 3: newroom = room.x3_to; 4: newroom = room.x4_to; 5: newroom = room.x5_to; } if (newroom ~= lastroom) { print "Exit #", i," goes to..."; Surrounding(newroom, iteration + 1, endit, room); } } ]; ! ------------------------Function calls. [ CreaturesPresent room x count; ! Return number of creatures for room objectloop (x in room) ! Don't include hidden creatures! { if (x ofclass Creature || x == player) { if (x.hiding == 0) count++; } } return count; ]; [ PlayerInRoom room; ! Is player in given room? if (FindCeiling(player) == room) return TRUE; return FALSE; ]; [ PickPrey cre room x count sum weakness weakest; ! Return prey for cre in room sum = CreaturesPresent(room); ! Don't include hidden creatures! count = 1; weakness = 9999; ! Returns weakest prey objectloop (x in room) { if (x provides strength && x ~= cre && x.hiding == 0) { if (x.strength < weakness) { weakness = x.strength; weakest = x; } } } return weakest; ]; [ PickCreature room x picknum num; ! Return random creature in room ! Don't include hidden creatures! picknum = random(CreaturesPresent(room)); objectloop (x in room) { if (x provides strength && x.hiding == 0) { num++; if (num == picknum) return x; } } ]; [ JewelInRoom room x; ! Is there a jewel in room? objectloop (x in room) { if (x ofclass Jewel) rtrue; } rfalse; ]; [ ObjNotJewel room x; ! Are there non-jewel obj in room? objectloop (x in room) { if (x provides worth) { if (x ofclass Jewel) x = x; else rtrue; } } rfalse; ]; [ PreyDir room c temp temp2 r; ! Return a room with prey (or 0) ! Don't include hidden creatures! objectloop (c ofclass CompassDirection) { temp = c.door_dir; if (ValidDir(room, c)) { temp2 = room.temp; if (player in temp2) ! Is player in there? return c; objectloop (r in temp2) ! Is prey in there? { if (r > 0 && r provides prey && r.hiding == 1) return c; } } } return 0; ! No prey found. ]; [ ValidDir room cdir temp; ! Valid direction from room? temp = cdir.door_dir; if (cdir provides dung) ! Dungeon exit? { if (room.temp ~= 0) ! Goes somewhere? { return TRUE; } } return FALSE; ]; [ NoPredDir room c temp temp2 r disq; ! Return a room with no predator ! (or 0) objectloop (c ofclass CompassDirection) { temp = c.door_dir; if (ValidDir(room, c)) { temp2 = room.temp; disq = 0; objectloop (r in temp2) ! Is predator in there? { if (r > 0 && r provides predator) disq = 1; ! Disqualified } if (disq == FALSE) return c; } } return 0; ]; [ BeetleEmpty room c temp temp2 r disq; ! Return a room without beetles objectloop (c ofclass CompassDirection) ! or poison (or 0) { temp = c.door_dir; if (ValidDir(room, c)) { temp2 = room.temp; disq = 0; if (temp2 has poison) disq = 1; else { objectloop (r in temp2) { if (r ofclass Beetle) disq = 1; } } if (disq == FALSE) return c; } } return 0; ]; [ PoisonSurrounding room c temp temp2; ! Poison surrounding rooms objectloop (c ofclass CompassDirection) { temp = c.door_dir; if (ValidDir(room, c)) { temp2 = room.temp; give temp2 poison; } } ]; [ ValObDir room nohoard c temp temp2 r best pick; ! Return room with most valuable ! object (or 0). Nohoard can be provided objectloop (c ofclass CompassDirection) ! Does not include worth of 0 or rope! { ! nohoard 1000 = no jewels! temp = c.door_dir; if (ValidDir(room, c)) { temp2 = room.temp; objectloop (r in temp2) ! Object in there? { if (r provides worth && r.worth > 0) { if (r.worth > best) { if (nohoard == 0 || nohoard ~= r.hoarded) { if (nohoard == 1000 && r ofclass Jewel) r = r; else { pick = c; best = r.worth; } } } } } } } return pick; ]; [ NewDir cre room c temp temp2 picknum num; ! Return not LASTROOM (or 0) room = parent(cre); ! REQUIRES cre!!! picknum = random(SNumExits(room)-1); objectloop (c ofclass CompassDirection) { temp = c.door_dir; if (ValidDir(room, c)) { temp2 = room.temp; if (cre.lroom ~= temp2) { num++; if (num == picknum) { return c; } } } } return 0; ]; [ FootprintsDir room; ! Return the direction with footprints return room.footto; ]; [ RandDir room cdir i num count pick temp; ! Return random direction count = 0; ! From given room num = SNumExits(room); pick = random(num); ! Pick a random exit number objectloop (i ofclass CompassDirection) { temp = i.door_dir; if (ValidDir(room, i)) { count++; if (count == pick) { cdir = i; } } } return cdir; ]; [ FungusDir room cdir i num temp temp2; ! Return the direction with > fungus num = room.fungus; cdir = 0; objectloop (i ofclass CompassDirection) { temp = i.door_dir; if (ValidDir(room, i)) { temp2 = room.temp; if (temp.fungus > num) { num = temp2.fungus; cdir = i; } } } return cdir; ]; [ QuietPoolDir room cdir i temp; ! Return the direction with quiet pool ! or 0 if there aren't any. cdir = 0; objectloop (i ofclass CompassDirection) { temp = i.door_dir; if (ValidDir(room, i)) { if (IsQuietPool(temp)) { cdir = i; } } } return cdir; ]; [ WaterRoom room cond cdir i temp temp2; ! Return dir to water room meeting cond cdir = 0; objectloop (i ofclass CompassDirection) { temp = i.door_dir; if (ValidDir(room, i)) { temp2 = room.temp; if (temp2 has river) { if (cond == 2 && FindCeiling(player) == temp2) return i; if (cond == 1 && FindCeiling(player) ~= temp2) return i; if (cond == 0 && random(2) == 1) cdir = i; if (cond == 0 && cdir == 0) cdir = i; } } } return cdir; ]; [ NearbyRegion room i temp temp2; ! A region nearby? objectloop (i ofclass CompassDirection) { temp = i.door_dir; if (ValidDir(room, i)) { temp2 = room.temp; if (temp2.region > 0 && WhatLevel(room) == WhatLevel(temp2)) return temp2; } } rfalse; ]; [ NearbyVast room i temp temp2; ! A vast room nearby? objectloop (i ofclass CompassDirection) { temp = i.door_dir; if (ValidDir(room, i)) { temp2 = room.temp; if (temp2.size > 5 && WhatLevel(room) == WhatLevel(temp2)) rtrue; } } rfalse; ]; [ WindExitFrom room i c num temp temp2 choice d; ! Return the direction to ! faster wind (from room) choice = 0; d = -100; num = SNumExits(room); for (i = 1: i <= num: i++) { objectloop (c ofclass CompassDirection) { temp = c.door_dir; if (ValidDir(room, c)) { temp2 = room.temp; if (temp2.wind >= d) { if (temp2.wind > d || random(2) == 1) { choice = c; d = temp2.wind; } } } } } return choice; ]; [ IsQuietPool room; ! Is there a quiet pool in room? if (room has river && room.speed < 7) return TRUE; return FALSE; ]; [ WindExitTo room i c num temp temp2 choice d; ! Return the direction to ! slower wind (from room) choice = 0; d = room.wind; num = SNumExits(room); for (i = 1: i <= num: i++) { objectloop (c ofclass CompassDirection) { temp = c.door_dir; if (ValidDir(room, c)) { temp2 = room.temp; if (temp2.wind < d && temp2.wind > 0) { choice = c; d = temp2.wind; } } } } return choice; ]; [ LowestWaterExit room i c num temp temp2 choice d; ! Return the direction to ! lowest water exit ! From given room choice = 0; d = 0; num = WaterExits(room, 0); for (i = 1: i <= num: i++) { objectloop (c ofclass CompassDirection) { temp = c.door_dir; if (ValidDir(room, c)) { temp2 = room.temp; if (room.temp has river) { if (temp2.depth > d) { choice = c; d = temp2.depth; } } } } } return choice; ]; [ NextUpDown room dir c temp temp2 best bestnum; ! Return up or down room ! dir 1 = up, dir 0 = down bestnum = room.conn; objectloop (c ofclass CompassDirection) { temp = c.door_dir; if (ValidDir(room, c)) { temp2 = room.temp; if (dir == 1) { if (temp2.conn >= bestnum) { bestnum = temp2.conn; best = c; } if (temp2.conn == bestnum && random(2) == 1) { bestnum = temp2.conn; best = c; } } if (dir == 0) { if (temp2.conn < bestnum) { bestnum = temp2.conn; best = c; } } } } return best; ]; [ WaterExits room type i num temp temp2;! Return the number of water exits ! From given room and type ! -1 lower, 0 all, 1 higher num = 0; objectloop (i ofclass CompassDirection) { temp = i.door_dir; if (ValidDir(room, i)) { temp2 = room.temp; if (room.temp has river) { switch (type) { -1: if (temp2.depth >= room.depth) num++; 0: num++; 1: if (temp2.depth < room.depth) num++; } } } } return num; ]; [ SRandom room croom i num pick temp; ! Return random surrounding room croom = room; ! From given room num = SNumExits(room); pick = random(num); ! Pick a random exit number num = 0; objectloop (i ofclass CompassDirection) { temp = i.door_dir; if (ValidDir(room, i)) { num++; if (num == pick) croom = temp; } } return croom; ]; [ Shallowest room croom i shall temp temp2; ! Return shallowest nearby room ! (Or self if current is shallowest) croom = room; shall = room.depth; objectloop (i ofclass CompassDirection) { temp = i.door_dir; if (ValidDir(room, i)) { temp2 = room.temp.depth; if (temp2 < shall) { croom = room.temp; shall = temp2; } } } return croom; ]; [ ExitToRoom room croom i temp; ! Discern exit# to get from room ! to croom. objectloop (i ofclass CompassDirection) { temp = i.door_dir; if (i provides dung) { if (room.temp == croom) { return i; } } } ]; [ HaveTiedRope i; ! Does player have a tied rope? objectloop (i in player) { if (i provides tiedto && i.tiedto > 0) rtrue; } rfalse; ]; [ RopeToExit room thedir i temp; ! Is there a rope to that exit? ! (Requires room & thedir) objectloop (i ofclass Rope) { if (i in room || i in player) ! Holding rope or rope in room { if (i.tiedto) { if (ExitToRoom(room, i.tiedto).door_dir == thedir) rtrue; } } else ! Or rope in destination room { ! Mainly for "falling into room" stuff temp = room.thedir; if (i in temp) { if (i.tiedto == room) rtrue; } } } rfalse; ]; [ Deepest room croom i deep temp temp2; ! Return deepest nearby room ! (Or self if current is deepest) croom = room; deep = room.depth; objectloop (i ofclass CompassDirection) { temp = i.door_dir; if (ValidDir(room, i)) { temp2 = room.temp.depth; if (temp2 > deep) { croom = room.temp; deep = temp2; } } } return croom; ]; [ SHeight room; ! Return relative height of given room return (SSumDepth(room) / SNumExits(room)) - room.depth; ]; [ SSumDepth room temp temp2 sum i; ! Return sum of surrounding depths for given room sum = 0; objectloop(i ofclass CompassDirection) ! Loop room's exits { temp = i.door_dir; if(ValidDir(room, i)) ! Exit goes anywhere? { temp2 = room.temp.depth; ! Get other room's depth sum = sum + temp2; ! Add depths together } } return sum; ]; [ SNumExits room temp num i; ! Return number of exits for given room num = 0; objectloop(i in compass) ! Loop room's exits { temp = i.door_dir; if(ValidDir(room, i)) ! Exit goes anywhere? { num++; } } return num; ]; [ FirstCon room num; ! Return first available connection for given room num = 6; if (room.x5_to == 0) num = 5; if (room.x4_to == 0) num = 4; if (room.x3_to == 0) num = 3; if (room.x2_to == 0) num = 2; if (room.x1_to == 0) num = 1; return num; ]; [ NumCon room count; ! Return number of connections for given room count = 0; if (room.x1_to ~= 0) count++; if (room.x2_to ~= 0) count++; if (room.x3_to ~= 0) count++; if (room.x4_to ~= 0) count++; if (room.x5_to ~= 0) count++; return count; ]; [ FR room; ! Return room number corrected for FIRSTROOM return (FIRSTROOM + room - 1); ]; [ RR room; ! Return room number without FIRSTROOM (start at 1) return (room - FIRSTROOM + 1); ]; [ NRL; ! Return number of rooms in each level return (MAXROOMS / 5); ]; [ WhatLevel room; ! Return level number of given room **FR first** return ((room - FIRSTROOM) / NRL() + 1); ]; [ FLevel level; ! Return the first room of given level return FR((level - 1) * NRL() + 1); ]; [ LLevel level; ! Return the last room of given level return (FLevel(level) + NRL() - 1); ]; [ RandRoom level; ! Return a random room in given level return FLevel(level) + random(NRL()) - 1; ]; [ Absl num; if (num < 0) num = num * (-1); return num; ]; [ Nozero num; ! We don't want no stinkin' zero! if (num == 0) num = 1; return num; ]; [ InRiverBag loc x; ! An appropriate item in the riverbag? objectloop (x in riverbag) ! requires location. { if (x.inroom == loc) return x; } return 0; ]; [ CaveObjectPresent loc x; ! CaveObject in loc (for spurious line breaks) if (loc has river || owind in loc) return 0; objectloop (x in loc) { if (x hasnt scenery && x hasnt concealed && x ~= player) return 1; } return 0; ! Line break ]; [ Health cre; ! Return health of provided creature if (cre.strength > 300) return (cre.strength * 10) / (cre.topstrength / 10); return (cre.strength * 100) / cre.topstrength; ]; [ TSPercent cre; ! Return percentage of creature's topstrength if (cre.topstrength > 300) return (cre.topstrength * 10) / 100; return (cre.topstrength * 100) / 1000; ]; [ PercentTwo one two; ! Return two's percentage of one return ((two * 10) / (one) * 10); ]; [ WeighPercent cre; ! Return percentage of weight caried return (WeightOf(cre) * 100) / (cre.strength / 2); ]; [ Percent top per; ! Return per of top return ((top * per) / 100); ]; [ WEPercent obj; ! Return percentage of weapon's strengthbonus if (obj.strengthbonus > 300) return (obj.strengthbonus * 10) / 200; return (obj.strengthbonus * 100) / 2000; ]; [ PressKeyRandom k t; ! Wait for keypress... print "Press any key to continue > "; @read_char 1 1 Interrupt -> k; for(t=0:t"; rtrue; } ]; [ FindCeiling obj; ! Find the room the object is in! do { if (parent(obj) == nothing) rfalse; if (parent(obj) ofclass C_ROOMS) return parent(obj); obj = parent(obj); } until (parent(obj) == nothing); rfalse; ]; ! ------------------------Grammar routines. [ ReadSub; if (metaclass(noun.text) == string) print (string) noun.text; else noun.text(); ]; [ WaitSub; ! Update sounds, etc. LookRoutine(); if (player.strength + 2 < player.topstrength) ChangeStrength(player, 2); if (AfterRoutines()==1) rtrue; ]; [ SonarSub; Surrounding(real_location, 1, 4); ]; [ FillSub; "Now is not the time to worry about things like that."; ]; [ GoFishSub; if (FindCeiling(player) has river) "You were never very good at fishing."; "You'd need lots of water to do that."; ]; [ FillFromSub; if (noun ~= canteen) << Fill noun >>; if (second == oriver) << Fill canteen >>; else "You can't fill your canteen with that!"; ]; [ SqueezeThroughSub; if (noun == sprayer) "The sprayer doesn't have enough power to do that sort of thing. It's meant for exterminating bugs, not for covert assassination!"; "You can't do that."; ]; [ SqueezeAtSub; if (noun == sprayer) "The sprayer doesn't have a directed spray...it's meant to poison entire rooms, not to target unlucky individuals."; "You can't do that."; ]; [ ThrowThroughSub temp croom cre; temp = second.door_dir; croom = real_location.temp; if (croom == 0) "There aren't that many exits."; if (noun.weight < 2) { print (The) noun, ", being light, falls far short of the exit.^"; keep_silent = TRUE; < drop noun >; keep_silent = FALSE; rtrue; } if (noun provides tiedto) { if (noun.tiedto > 0 && noun.tiedto ~= real_location) "The rope gets tangled up and doesn't make it to the exit."; } print "You throw ", (the) noun, " through exit #", second.num, ".^"; move noun to croom; if (CreaturesPresent(croom) > 0) { cre = PickCreature(croom); if (cre.weight > 5) ObjectHits(noun, cre); } if (croom has river) { print "You hear a distant splash.^"; PutInRiver(noun, croom); } ]; [ SwimSub; if (SWIMMING) { print "You are already swimming.^"; } else { if (real_location has river) { print "You step into the water.^"; SWIMMING = 1; SwimRoutine(real_location); } else { print "There's no water here to swim in.^"; } } ]; [ SwimStopSub; if (SWIMMING) { print "You climb out of the water.^"; LeaveWater(); } else { print "You're not in the water.^"; } ]; [ GoNumSub i temp temp2 chosen; ! Form "Go (num)" if (FR(noun) == real_location) "You are already in that room."; objectloop(i in Compass) { temp = i.door_dir; temp2 = real_location.temp; if(real_location.temp == FR(noun)) chosen = i; if(ValidDir(real_location, i) && temp2.region == FR(noun)) chosen = i; } if (chosen) <>; "No exits lead to that room."; ]; [ JumptoSub; ! Form "Jumpto (num)" if (FR(noun) ofclass C_ROOMS) PlayerTo (FR(noun), 0); else "That's not a valid room!"; ForfeitSub(); rtrue; ]; [ ReturnSub; ! Retrace if (LASTROOM == real_location || LASTROOM == 0) "You can't seem to retrace your steps."; noun = RR(LASTROOM); inp1 = 1; GoNumSub(); ]; [ ShowNumOnSub; SHOWNUM = 1; "Room numbers are turned ON."; ]; [ ShowNumOffSub; SHOWNUM = 0; "Room numbers are turned OFF."; ]; [ ExploreOnSub; EXPLORE = 1; print "Exploration mode turned ON.^"; ForfeitSub(); rtrue; ]; [ ExploreOffSub; EXPLORE = 0; "Exploration mode turned OFF."; ]; [ EcoOnSub; ECO = 1; print "Ecosystem display ON.^"; ForfeitSub(); rtrue; ]; [ EcoOffSub; ECO = 0; "Ecosystem display OFF.^"; ]; [ NomonsterSub x; ! Remove all monsters objectloop (x ofclass Creature) { while (child(x)) move child(x) to FindCeiling(x); ! Drop their stuff... move x to creaturebag; ! Move them away } StopDaemon(CDaemon); ! Stop their AI Eggsack.oomf = 0; Eggsack.countdown = 0; ! Neutralize Eggsack print "Gosh, it's quiet around here all of a sudden...^"; ForfeitSub(); ]; [ ForfeitSub; if (FORFEIT == 0) print "Your score function is now disabled.^"; FORFEIT = 1; ]; [ RestartSub; "Every day we ask ourselves, ~Wouldn't it be nice to be able to do it all over again?~ Sadly, that's just not the way life is."; ]; [ HelpSub; if (noun) { switch (noun) { 1: print "WUMPUS 2000 INTRODUCTION^^ The caverns you've been dropped into consist of 100 interconnecting caves on five different levels. Each cave is connected to at least one other cave by one or more exits. In some cases, the caves are actually parts of larger 'regions' within the caverns, and sometimes these regions have features which make them distinctive.^^ The object of the game is to find the exit and manage to escape through it. To do this, you'll need to build up your strength and supplies, fight the cavern denizens, and actually find the exit itself. Your final score will depend upon the amount of exploration you've done, the monetary worth of your possessions, and how successful you were in escaping.^^ While playing the game it's important to keep an eye on your health (which is displayed on the status bar). Your health determines your effectiveness in combat, how well you can traverse difficult passageways, and how much weight you can carry. Your health is displayed as a percentage of your current maximum health... 100% health is very different for a player whose maximum health is low, as it is in the beginning of the game. Certain objects in the cave will increase your maximum health or your current health.^^ As you move around the caves you will often hear sounds through the exits, telling you which creatures are nearby and how close they are. If a louder noise interferes with a quieter one, though, you will not be told about the quieter one.^"; 2: print "MOVING AROUND THE CAVES^^ Each room has at least one exit leading to another room. All exits are referred to as 'x' followed by the exit number...for instance, exit one is 'x1'. Simply typing that will start you in the direction of that exit.^^ If you have been through one of the exits previously, you can also refer to the room number it leads to. For instance, you can type ~go 24~ to move to room 24 (provided there is a room in that direction). You can also type ~back~ to retrace your footsteps (~**~ will appear next to the exit you last came from).^^ Regions are slightly more difficult to navigate, as they are actually single large rooms with multiple sections within them. For that reason they are referred to by a common room number, and the clues you are given about the other sections of the regions are more ambiguous.^^ If an exit leads to another level in the cave, you will not be told anything about the room at the other end as it is too far away.^^ Just because there is an exit to another room doesn't mean you can reach it. If there is water between you and it you must ~swim~ to get there (use ~exit~ to finish swimming, though this is done automatically if you move to a room without water). If the exit is particularly steep you might have trouble climbing it...this will depend on your strength and the steepness of the incline.^^ Resting will restore your strength if you are not in a very cold or hot room, but keep in mind that the rest of the caves are active even when you aren't...^"; 3: print "OBJECTS^^ The caverns are full of objects, either naturally ocurring or left there by previous explorers. They can be picked up and used... though not only by you!^^ There is no limit to the number of objects you can carry, but you must always keep track of their total weight. The amount of weight you can carry depends on your current strength, and if you become injured you may begin to drop things. Examining an object will tell you its weight and monetary value. The total weight and value of your objects is also shown in your inventory.^^ Food and weapons are important to keep track of. Weapons will increase your ability to attack creatures, defend against attacks, and will also increase the damage you can do. Examining a weapon will tell you how effective a weapon it is, compared to the best kind you could possibly find.^^ You may also find ropes in the caves. These ropes can be tied to features in the cave (a simple ~tie rope~ is the best way to do this), and can help you deal with steep passages or rushing water. Ropes can only stretch between two rooms, and are only useful to you if you are holding on to one.^"; 4: print "CREATURES & COMBAT^^ While some of the creatures in the caves do not wish to harm you (and some may even help you), most of them are either predators or are downright evil, and all of them will attack if they are wounded. Some are effective bloodhounds and will follow your footsteps throughout the caves...crossing a river will sometimes throw them off.^^ You can attack these monsters, and the results of your attacks will depend on your strength, the strength of the monster, and any weapons that the two of you are using. You can choose to attack with a specific weapon. If you do not specify a weapon and you are currently carrying one, the most effective weapon will be automatically used. Keep in mind, however, that weapons aren't useful against smaller monsters.^^ Some monsters carry objects, which they will leave behind when they are killed.^"; 5: print "SPECIAL COMMANDS^^ Here are a few commands available to help you configure your game:^^ ~shownum on/off~ will either show or hide the room numbers. This is on by default. If you want a really challenging game, give it a try.^^ ~explore on/off~ toggles the exploration mode, which is normally off. This mode will allow you to explore the caves without ever getting hungry, thirsty, or injured by creatures, and it will keep your glow bar's battery from running down. Turning this on will forfeit your score.^^ ~boost~ will give your strength and glow bar battery a temporary lift, and will also remove your hunger and thirst. This will also forfeit your score.^^ ~nomonsters~ will clear all of the monsters out of the caves (except for the fish), giving you a relatively quiet game. It will forfeit your score as well.^^ ~prepare~ will set up a game for others to play in the future. If you want to create a pre-made game with maps and information that you can give to others: begin a new game, save it immediately, explore the caves and map them. Then, restore your game (so that the player is back at the beginning) and type ~prepare.~ This will put the game in a prepared state and save it. Then, when a user restores it, all of the opening text will be displayed, giving your saved game a proper introduction (so it doesn't look like it was restored). This was how the sample game was prepared.^"; default: print "There is no topic number ", noun, ".^"; } } else print "WUMPUS 2000 HELP^^ There are several different help topics available. To access them, type ~help~ and then the number of the topic you'd like to read. For instance, to learn how to get around in the caves, type ~help 2.~^^ 1. Wumpus 2000 Introduction^ 2. Moving Around The Caves^ 3. Objects^ 4. Creatures & Combat^ 5. Special Commands^"; ]; [ TieSub; if (noun provides tiedto) { if (noun.tiedto > 0) "It's already tied to something! You'll need to untie it first."; noun.tiedto = real_location; "You tie it to a suitable part of the cave."; } "You can't tie that!"; ]; [ TieSpecificSub; if (noun provides tiedto) print "You search around for something better to tie it to.^"; TieSub(); rtrue; ]; [ UntieSub; if (noun provides tiedto) { if (noun.tiedto == 0) "It isn't tied to anything!"; noun.tiedto = 0; "You untie the rope."; } "That's not something you can tie or untie!"; ]; [ BendSub; if (noun provides weight) { if (noun.weight < 5) "You bend ", (the) noun, " a bit, which is amusing."; else "Bending ", (the) noun, " seems a waste of time and strength."; } "That's not something you can bend."; ]; [ ClimbDownSub; "You can't climb that!"; ]; [ ClimbOutSub; "You can't climb out of that!"; ]; [ SurviveSub; player.strength = player.topstrength * 2; player.thirst = 100; player.hunger = 100; glowbar.BATTERY = MAXBATTERY; print "You feel very secure, all of a sudden...^"; ForfeitSub(); ]; [ PrepareSub; PlayerTo(Limbo); << Save >>; ]; [ IsFungus; if (noun == ofungus) { rtrue; } rfalse; ]; [ IsRiver; if (noun == oriver) { rtrue; } rfalse; ]; [ IsNote; if (noun provides text) { rtrue; } print "There's nothing to read on that.^"; rfalse; ]; [ EatFungusSub; "Never look at this message!^"; ]; ! ---------------------------------------------------------------------------- ! Grammar ! ! The grammar section includes the file "Grammar" and will later include ! extensions to the standard grammar library. ! ---------------------------------------------------------------------------- Include "Grammar"; Verb meta 'shownum' 'sn' * 'on' -> ShowNumOn * 'off' -> ShowNumOff * -> ShowNumOn; Verb meta 'sonar' * -> Sonar; Verb meta 'explore' * 'on' -> ExploreOn * 'off' -> ExploreOff * -> ExploreOn; Verb meta 'ecosystem' * 'on' -> EcoOn * 'off' -> EcoOff * -> EcoOn; Verb meta 'nomonster' * -> Nomonster; Verb meta 'boost' * -> Survive; Verb meta 'prepare' * -> Prepare; Extend 'go' * number -> GoNum * 'to' number -> GoNum * 'to' 'room' number -> GoNum * 'to' 'room' 'number' number -> GoNum * 'to' 'number' number -> GoNum * 'number' number -> GoNum * 'back' -> Return * 'fish' -> GoFish * 'fishing' -> GoFish; Verb meta 'jumpto' * number -> Jumpto; Verb 'return' 'back' * -> Return; Verb meta 'help' 'h' '?' * -> Help * number -> Help; Extend 'attack' replace * creature -> Attack * noun -> Attack * creature 'with' held -> AttackWeapon * noun 'with' held -> Attack; Extend 'swim' * 'in' noun=IsRiver -> Swim * 'in' 'the' noun=IsRiver -> Swim * 'across' noun=IsRiver -> Swim * 'across' 'the' noun=IsRiver -> Swim; Extend 'throw' replace * multiheld -> Drop * multiheld 'in' / 'into' / 'down' / 'through' / 'at' noun=ADirection -> ThrowThrough * multiexcept 'in'/'into'/'down' noun -> Insert * multiexcept 'on'/'onto' noun -> PutOn * held 'at'/'against'/'on'/'onto' noun -> ThrowAt; Verb 'fire' 'spray' * noun -> Squeeze * noun 'in' / 'into' / 'down' / 'through' / 'at' noun=ADirection -> SqueezeThrough * noun 'at' / 'on' / 'onto' noun -> SqueezeAt; Extend 'squeeze' * noun 'in' / 'into' / 'down' / 'through' / 'at' noun=ADirection -> SqueezeThrough * noun 'at' / 'on' / 'onto' noun -> SqueezeAt; Extend 'leave' first * noun=IsRiver -> SwimStop; Extend 'exit' first * noun=IsRiver -> SwimStop; Extend 'eat' first * noun=IsFungus -> EatFungus; Extend 'climb' * 'into' noun -> Climb * 'down' noun -> ClimbDown * 'out' 'of' noun=IsRiver -> SwimStop * 'out' 'of' noun -> ClimbOut * 'out' noun=IsRiver -> SwimStop; Verb 'descend' * noun -> ClimbDown; Verb 'stop' 'cease' 'finish' * 'swimming' -> SwimStop; Verb 'fish' * -> GoFish * 'in' noun=IsRiver -> GoFish * 'from' noun=IsRiver -> GoFish; Extend 'drink' * 'from' noun -> Drink * 'water' 'from' noun -> Drink; Extend 'fill' * noun 'with'/'from' noun -> FillFrom; Extend 'read' replace * noun=IsNote -> Read * 'about' topic 'in' noun -> Consult * topic 'in' noun -> Consult; Extend 'eat' replace * noun -> Eat; Extend 'tie' replace * noun -> Tie * 'up' noun -> Tie * noun 'to' noun -> TieSpecific * 'up' noun 'to' noun -> TieSpecific; Verb 'untie' 'loosen' 'release' 'coil' * noun -> Untie * 'up' noun -> Untie * noun 'from' noun -> Untie; Verb 'bend' * noun -> Bend; Extend 'dig' * 'in' noun -> Dig * 'in' 'the' noun -> Dig;