!------------------------------------------------------------------------- ! $Id: gue.inf,v 1.1 2000/08/20 17:29:34 neilc Exp $ ! gue.inf -- A component of the Inform 6 port of Ditch Day Drifter. ! ! The file contains the source code for the underground sections of the ! CalTech campus and the Great Undergraduate Excavation Project. ! ------------------------------------------------------------------------- ! ------------------------------------------------------------------------- ! ! -- Table of Contents -- ! ! HALLWAYS (3) ! Hallway 1 (3.1) ! Hallway 2 (3.2) ! Hallway 3 (3.3) ! Laundry Room (3.4) ! washing machine (3.4.1) ! blue jeans (3.4.1.1) ! master key (3.4.1.1.1) ! Hallway 4 (3.5) ! Hallway 5 (3.6) ! Hallway 6 (3.7) ! Storage Room (3.8) ! guard (3.8.1) ! attributes, name, description, initial, act (3.8.1a) ! greet, number, tied_to (3.8.1b) ! react_before (3.8.1c) ! react_after, orders (3.8.1d) ! life (3.8.1e) ! each_turn, before (3.8.1f) ! memo pad (3.8.1.1) ! card table (3.8.2) ! empty glass (3.8.2.1) ! tunnel door (3.8.3) ! ! STEAM TUNNELS (4) ! tunnel pipes (4.*) ! ! TunnelRoom class (I) ! DarkTunnelRoom class (J) ! ! Tunnel 1 (4.1) ! Tunnel 2 (4.2) ! Tunnel 3 (4.3) ! Tunnel 4 (4.4) ! Tunnel 5 (4.4) ! Tunnel 6 (4.6) ! Tunnel 7 (4.7) ! tight passage (4.7.1) ! Tunnel 8 (4.8) ! control unit (4.8.1) ! control keypad (4.8.1.1) ! control display (4.8.1.2) ! control button (4.8.1.3) ! Tunnel 9 (4.9) ! Tunnel 10 (4.10) ! Tunnel 11 (4.11) ! chute top (4.11.1) ! Tunnel 12 (4.12) ! Tunnel 13 (4.13) ! Tunnel Storage (4.14) ! rope (4.14.1) ! Top of Pit (4.15) ! pit top (4.15.1) ! railing (4.15.2) ! ! GREAT UNDERGRADUATE EXCAVATION (5) ! Huge Cavern (5.1) ! pit rope (5.1.1) ! pit plaque (5.1.2) ! Chute Room (5.2) ! chute bottom (5.2.1) ! Machine Room (5.3) ! machine (5.3.1) ! machine button (5.3.1.1) ! Machine Storage (5.4) ! Mr. Happy Gear (5.4.1) ! Bank (5.5) ! Vault Room (5.6) ! safe (5.6.1) ! deposit slot (5.6.1.1) ! DarbCard (5.6.1.2) ! Insurance Office (5.7) ! Tunnel (5.8) ! Subway Station 1 (5.9) ! rail car (5.9.1) ! coolant guage (5.9.1.1) ! coolant hole (5.9.1.2) ! ignition button (5.9.1.3) ! rail car instructions (5.9.1.4) ! tunnel mouth (5.9-11.2) ! Rail Tunnel (5.10) ! Subway Station 2 (5.11) ! Computer Center (5.12) ! computer equipment (5.12.1) ! A Million Random Digits (5.12.2) ! Bio Hall 1 (5.13) ! Bio Lab (5.14) ! strange equipment (5.14.1) ! lab bench (5.14.2) ! CloneMaster (5.14.2.1) ! CloneMaster button (5.14.2.1.1) ! funnel (5.14.2.2) ! cabinet (5.14.3) ! ! ChemItem class (K) ! ! GF-XQ3 (5.14.3.1) ! GF-XQ9 (5.14.3.2) ! Poly Red (5.14.3.3) ! Poly Blue (5.14.3.4) ! Compound T99 (5.14.3.5) ! Compount T30 (5.14.3.6) ! Bio Hall 2 (5.15) ! slime creature (5.15.1) ! slime (5.15.1.1) ! Bio Office (5.16) ! bio desk (5.16.1) ! The Great Seal of the Omega (5.16.1.1) ! Spaceship Room (5.17) ! spaceship (5.17.1) ! warp motivator socket (5.17.1.1) ! Spaceship Interior (5.18) ! launch button (5.18.1) ! ! ------------------------------------------------------------------------- ! (3) HALLWAYS ! (3.1) Hallway 1 Object Hall1 "Hallway" has light with description "You are at the west end of a basement hallway. A stairway leads up.", u_to Courtyard, e_to Hall2, ; ! (3.2) Hallway 2 Object Hall2 "Hallway" has light with description "You are in an east-west hallway in the basement. Another hallway goes off to the north.", w_to Hall1, e_to Hall3, n_to Hall4, ; ! (3.3) Hallway 3 Object Hall3 "Hallway" has light with description "You are at the east end of a hallway in the basement. A passage leads north.", w_to Hall2, n_to Laundry, ; ! (3.4) Laundry Room Object Laundry "Laundry Room" has light with description "You are in the laundry room. There is a washing machine against one wall. The exit is to the south.", s_to Hall3, out_to Hall3, ; ! (3.4.1) washing machine Object washing_machine "washing machine" Laundry has scenery container openable with name 'washing-machine' 'washing' 'machine' 'laundry' 'washer', before [; SwitchOn, SwitchOff: "", (The) self, " seems to be out of order."; ], ; ! (3.4.1.1) blue jeans Object jeans "blue jeans" washing_machine has pluralname with ! name 'pockets' 'pocket' 'blue' 'jeans' 'pants' 'pair' 'of', parse_name [ wd count; wd=NextWord(); if (wd == 'pair') { wd=NextWord(); if (wd == 'of') { count=count+2; wd=NextWord(); } } while (wd == 'pockets' or 'pocket' or 'blue' or 'jeans' or 'pants') { count++; wd=NextWord(); } return count; ], article "a pair of", before [; Examine, Search: if (master_key has moved) "It's an ordinary pair of jeans."; print "It looks like an ordinary pair of jeans, though not your size. As you inspect them, you notice a key fall out of them"; if (jeans in player || jeans in location) { move master_key to real_location; print " and to the ground.^"; } else { move master_key to parent(self); if (parent(self) has container) print " into"; else print " onto"; print " the ", (name) parent(self), ".^"; } if (guard in location) guard.act(master_key); rtrue; Wear: "They're not your size."; Receive: if (noun == master_key) "It is too late to put it back."; "That won't fit in the pocket."; ], ; ! (3.4.1.1.1) master key ! Unlocks the tunnel door. Object master_key "master key" class Crawlable with name 'master' 'key' 'master_key', ! ------------------------------------------------------------------------- ! This before routine is pretty funny considering the number of sensible ! actions this game prevents you from doing. ! ------------------------------------------------------------------------- before [; Take: if (self hasnt moved) { print "*Some* adventure games would try to impose their authors' misguided sense of ethics on you at this point, telling you that you don't feel like picking up the key, or you don't have time to do that, or that it's against the rules to even possess a master key, much less steal one from some other student's pants that you happened to find in a laundry, or even more likely that you are unable to take the key while wearing that dress. However, you're the player, and you're in charge around here, so I'll let you make your own judgments about what's ethical and proper here... "; } ! It "falls through" to the end of the before routine - it returns false ! and the normal Take action proceeds. Imbedded routines (routines ! contained in objects) return false by default, while non-imbedded ! routines (stand-alone routines) return true by default. ], ; ! (3.5) Hallway 4 Object Hall4 "Hallway" has light with description "You are in a north-south hallway in the basement.", s_to Hall2, n_to Hall5, ; ! (3.6) Hallway 5 Object Hall5 "Hallway" has light with description "You are at a corner in the basement hallway. You can go east or south.", s_to Hall4, e_to Hall6, ; ! (3.7) Hallway 6 Object Hall6 "Hallway" has light with description "You are at the east end of a basement hallway. To the north is a ~storage room,~ which everyone knows is actually an entrance to the steam tunnels.", w_to Hall5, n_to Storage, ; ! (3.8) Storage Room Object Storage "Storage Room" has light ! general if Lloyd has visited. with description [; print "You are in a large storage room. There really hasn't been anything stored here for a long time (at least, not anything that anybody wants to ever see again). The exit is to the south. To the north lies a door, which is "; if (tunnel_door has open) "open. "; else print "closed. "; "A small card table is sitting in front of the door."; ], s_to Hall6, n_to tunnel_door, ; ! (3.8.1) guard Object guard "guard" Storage ! ------------------------------------------------------------------------- ! The guard is transparent so you can see his memo pad. ! ------------------------------------------------------------------------- ! (3.8.1a) has animate transparent ! general if he is asleep with name 'caltech' 'cop' 'pig' 'fuzz' 'guard' 'security' 'man', description [; print "The guard is a member of the CalTech Cops, the elite corps of dedicated men and women that keeps the campus safe from undesirables, e.g., the students. "; if (self has general) "Currently, the guard is fast asleep, which is quite typical."; else ""; ], initial [; if (self hasnt general) "A guard is sitting at the card table in front of the door. He watches you carefully, evidently thinking that you might be planning to try to go through the door."; "A guard is slumped over a small card table in front of the steam tunnel entrance, evidently fast asleep. How typical."; ], act [ obj; switch (obj) { master_key: if (self hasnt general) move master_key to card_table; self.number=1; "^Spotting the key, the guard snatches it up and drops it on the card table. ~I've been wondering where that was!~ he snorts."; default: "^The guard doesn't know the security measures required under these circumstances."; } ], ! (3.8.1b) greet [; if (self has general) "The guard's sleeping form does not reply."; else { self.number=1; "~Hi,~ says the guard, with no enthusiasm."; } ], ! The number property will hold: ! 1 - The guard has already done something interesting this turn. ! 0 - The guard hasnt done anything interesting this turn. number 0, tied_to [; if (self has general) "That hardly seems necessary."; "The guard grins at you. ~You're that type, eh? Well, okay, maybe after my shift is over. Not! Now quit bothering me.~"; ], ! (3.8.1c) react_before [; ! The guard won't let players near the door to the tunnels. Enter, Open, Unlock: if (noun == tunnel_door && self hasnt general) { self.number=1; "The guard won't let you near the door."; } ! The guard prevents players from taking some things (unless he is ! asleep). Go: if (noun == n_obj && self hasnt general) { self.number=1; "The guard won't let you near the door."; } Take: if (noun == empty_glass && self hasnt general) { self.number=1; "The guard won't let you. ~Get your own,~ he says."; } if (noun == memo_pad && self has general) "The guard is passed out on top of his memo pad, so you can't budge it."; ! The guard only prevents players from taking the master key if he ! already found it and stuck it on the card table for safe keeping. if (master_key in card_table && noun == master_key && self hasnt general) { self.number=1; "~This key is for authorized personnel only,~ says the guard, temporarily thwarting you."; } ! I think the memo pad makes a nice red herring. Push, Pull, Turn: if (noun == memo_pad && self has general) "The guard is passed out on top of the memo pad, so you can't move it."; Examine: if (noun == memo_pad && self has general) "The guard is passed out on top of his memo pad, so you can't see it."; ! The guard doesn't let players pour liquid nitrogen into his empty ! glass. PourInto: if (second == empty_glass && noun ofclass LiquidNitrogen && self hasnt general) { self.number=1; "The guard glowers at you until you desist."; } ! The guard will occasionally interpret the player placing things on ! the table to mean that the player intends to give the object to him. PutOn: if (self hasnt general && second == card_table && noun == cup && toxicola in cup) <>; if (self hasnt general && second == card_table && noun == master_key) <>; PourOnto: if (second == self && noun ofclass LiquidNitrogen) <>; Search: ! So the comatose guard appears to be slumped on the table. if (self has general && noun == card_table) print "The guard is slumped over the card table. "; Hello: return self.greet(); ], ! (3.8.1d) ! If the player drops the master key in front of the guard, he may snatch ! it away. react_after [; Drop: if (self hasnt general && noun == master_key) { print "You drop the master key on the floor.^"; self.act(master_key); rtrue; } ], orders [; Hello: return self.greet(); Give: switch(noun) { memo_pad: "~It's mine,~ he says, clutching the memo pad to his chest."; master_key: if (master_key notin card_table) "The guard looks up sharply, but does not reply."; "~Since my job is to keep you out of the steam tunnels, I can't very well give you this key,~ says the guard."; } Unlock: if (noun == tunnel_door && second == master_key) { self.number=1; if (master_key in card_table) "He looks at you in disbelief. ~You must be joking! No students are allowed in the steam tunnels, including you.~"; "~I'd love to help you,~ says the guard, ~but I've lost my key.~"; } ], ! (3.8.1e) life [; Give: ! Players can't give things to a sleeping guard. if (self has general) "The guard appears to be fast asleep."; ! Players can give the master key back to the guard and it is ! stupid, though not fatal, to do so. if (noun == master_key) { self.number=1; move master_key to card_table; "The guard looks chagrined. ~I've been wondering where that thing was!~ he exclaims. ~I'll just leave it here on the table where it will be safe.~"; } ! Bribing an NPC? Shocking! if (noun == one_dollar) { self.number=1; "The guard looks at you sternly. ~You should be ashamed of yourself -- trying to bribe a member of the elite CalTech Cops!~ he admonishes you, refusing your offer."; } ! He doesn't want an empty coffee cup. He already has an empty ! glass, after all. if (noun~=cup || toxicola notin cup) { self.number=1; "The guard doesn't appear interested."; } ! An interesting exercise for the reader might be to allow the ! coffee to be poured into the empty glass, and having that work ! just as well. if (noun==cup) { give self general; ! The guard falls asleep. self.each_turn=NULL; ! Get rid of the guard's each_turn routine. remove toxicola; move cup to card_table; score=score + 10; "The guard happily accepts your offer. ~ToxiCola(tm)! My favorite!~ he says appreciatively, not knowing the evil deed that you have in mind. He quickly drinks the entire cup of ToxiCola(tm). ~Wow! Just the caffeine pickup I needed,~ he says happily.^^After a few moments, though, he looks rather queasy. ~That caffeine just doesn't last long enough,~ he says, just before he passes out, slumping over the card table."; } WakeOther: if (self has general) "The guard is in a caffeine-deprivation induced stupor. He won't be waking up any time soon."; Attack: if (self has general) "You've done enough harm to the guard."; else "If you want to harm the guard, you'll need to be sneakier than that."; ThrowAt: if (noun == flask) <>; if (((noun == cup && toxicola in cup) || noun == master_key) && self hasnt general) { print "The guard catches it out of the air. "; <>; } Ask: if (self has general) rfalse; ! A crude way to parse out discussion topics. switch (second) { 'key', 'master_key': if (master_key in card_table) "He puts his hand over the key protectively. ~Try to put it out of your mind,~ he urges you."; else "The guard looks up sharply, but does not reply."; 'caltech', 'cops', 'cop', 'himself', 'guard', 'guards': "~We're just your average, everyday, ordinary kind of Cops,~ he explains. ~Prick us, and we smack some whup-ass down on ya.~"; 'steam', 'tunnels', 'door', 'tunnel': "The guard sighs and says, ~Nobody's allowed in there... especially nosey Ditch Day revellers.~"; 'me', 'myself', 'students': "~College students can be really annoying,~ he says, glaring meaningfully in your direction."; 'drink', 'toxicola', 'thirst', 'thirsty', 'thermos', 'empty', 'glass': "~I forgot my thermos,~ he says. ~And this stupid empty glass is making me thirsty.~"; 'memo', 'pad', 'notes': "~It's mine,~ he says, clutching the memo pad to his chest."; 'ditch', 'day': "~I hate it. We're already over-worked, what with the Pope's visit next week.~"; 'pope', 'pope^s', 'visit': "~I'm hoping for some small dispensation.~"; 'jeans', 'pants': if (jeans in player) <>; "~Leave me out of your life's plan,~ says the guard."; default: "~I don't feel like discussing that right now.~"; } Answer: if (noun == 'hello' or 'hi' or 'greetings' or 'salutations') return self.greet(); self.number=1; "~I'll make a note of it,~ says the guard."; Show: self.number=1; switch(noun) { master_key: print "You show the master key to the guard.^"; self.act(master_key); rtrue; jeans: "~Those are clearly not your size,~ says the guard. ~You college kids are always trying to get into each other's pants!~"; default: "The guard ignores you and your ", (name) noun, "."; } ], ! (3.8.1f) ! The guard's number property is used as a flag to prevent him from doing ! too many interesting things in one turn. If it is set to 1, he has ! already done something interesting this turn and the each_turn routine ! won't print anything. each_turn [; if (self.number == 1) { self.number=0; return; } switch (random(5)) { 1: "^The guard eyes you warily."; 2: "^The guard looks at his empty glass, probably wishing he had something to drink."; 3: "^The guard flips purposefully through the pages of his memo pad."; 4: "^The guard writes something down on his memo pad, glancing up from time to time to eye you suspiciously."; 5: "^The guard picks up his empty glass and starts to drink, then realizes it is empty and puts it back down."; } ], before [; Push, Take, Turn: if (self has general) "The CalTech Cop is much too heavy for you to move."; else "~Fat chance,~ says the guard."; LookUnder: if (self has general) "He's lying on his memo-pad."; ], ; ! (3.8.1.1) memo pad Object memo_pad "guard's memo pad" guard with name 'memo' 'pad' 'guard^s' 'corner', article "the", description "The guard won't let you see it.", ; ! (3.8.2) card table Object card_table "card table" Storage has scenery supporter with name 'card' 'table', description [; if (children(self) == 0) rfalse; ShowCont(self); new_line; rtrue; ], ; ! (3.8.2.1) empty glass Object empty_glass "empty glass" card_table with name 'empty' 'glass' 'emptiness', ! Some interpreters cannot successfully guess between 'an' and 'a' for an ! indirect article, so it is best to specify 'an' when it is necessary. article "an", description "You see nothing special about the empty glass (unless you you admire emptiness).", invent [; if (inventory_stage == 2) rtrue; ], poured_into "If you did that the empty glass wouldn't be empty any more.", react_before [; Insert, Transfer: if (second == self) "If you did that the empty glass wouldn't be empty any more."; Search: "It's empty."; ], ; ! (3.8.3) tunnel door ! A simple lockable two-way door. Object tunnel_door "tunnel door" has door ~open scenery openable lockable locked with name 'tunnel' 'door', with_key master_key, door_dir [; if (location == Storage) return n_to; else return s_to; ], door_to [; if (location == Storage) return Tunnel1; else return Storage; ], found_in Storage Tunnel1, ; ! (4) STEAM TUNNELS ! (4.*) tunnel pipes ! ------------------------------------------------------------------------- ! This object is similar to the orange trees ["surface.inf":2.1-2.1]. It ! is a single object, which, through the found_in property, seems to be ! present in several locations. In addition, it uses a timer to print the ! random messages that appear from time to time in the steam tunnels, as ! well as provides something for players to manipulate. ! ------------------------------------------------------------------------- Object tunnel_pipes "pipes" has scenery pluralname with name 'pipe' 'pipes', description "The pipes range from very small copper tubes, only an inch around, to huge asbestos-covered cylinders, over two feet in diameter. Many of the larger pipes are marked ~STEAM - 300 PSI.~", ! An object with a timer must provide a time_left property, and a time_out ! property. The time_left property, maintained by the library, holds the ! number of turns before the timer goes off. The time_out property will ! be called on the turn that the timer reaches 0. time_left 0, ! This will start the timer when players enter the steam tunnels. react_after [; Go: if ((location == Tunnel1 && noun == n_obj or tunnel_door) || (location == Tunnel13 && noun == s_obj)) StartTimer(self, 0); ], ! The time_out property is called when the timer runs out. time_out [; new_line; ! This resets the timer to a random number between 1 and 5. ! This way, one of the messages below will appear randomly every 1 ! to 5 turns. StartTimer(self, random(5)); switch (random(5)) { 1: "The rumbling sound suddenly becomes very loud, then, after a few moments, dies down to background levels again."; 2: "A series of clanking noises, like marbles rolling through the steam pipes, starts in the distance, then comes closer and closer, until it seems to pass right overhead. It disappears into the distance."; 3: "A very loud bang suddenly reverberates through the tunnel."; 4: "One of the pipes starts to hiss wildly. After a few moments, it fades back into the background sounds."; 5: "A loud buzzing sound, like an overloaded electrical circuit, emanates from somewhere nearby. After a few moments it is gone."; } ], found_in [; if (location ofclass TunnelRoom) rtrue; ! If you leave the steam tunnels, the messages stop appearing. else { StopTimer(self); rfalse; } ], ; ! (I) TunnelRoom class Class TunnelRoom has light with short_name "Steam Tunnel", before [; Listen: "There's a low rumbling sound."; ], ; ! (J) DarkTunnelRoom class Class DarkTunnelRoom class TunnelRoom has ~light; ! (4.1) Tunnel 1 Object Tunnel1 class TunnelRoom with description "You are in a steam tunnel. It is very hot and dry in here. The place has a strange musty odor; the air is very still, but there are distant sounds of all sorts that vibrate through the pipes. The pipes all seem to be hissing quietly, and a low rumbling sound constantly reverberates through the tunnel. Occasionally a distant clang or thud or crack emanates from the pipes.^^The steam tunnel runs east and west. A small passage leads south.", s_to tunnel_door, e_to Tunnel2, w_to Tunnel3, ; ! (4.2) Tunnel 2 Object Tunnel2 class TunnelRoom with description "You are at the east end of the steam tunnel.", w_to Tunnel1, ; ! (4.3) Tunnel 3 Object Tunnel3 class TunnelRoom with description "You are in an east-west section of the steam tunnels.", e_to Tunnel1, w_to Tunnel4, ; ! (4.4) Tunnel 4 Object Tunnel4 class TunnelRoom with description "You are at a T-intersection of two sections of steam tunnel; tunnels go off to the north, south, and east.", e_to Tunnel3, n_to Tunnel5, s_to Tunnel6, ; ! (4.5) Tunnel 5 Object Tunnel5 class DarkTunnelRoom with description "You are at a corner in the steam tunnel. You can go west and south.", w_to Tunnel7, s_to Tunnel4, ; ! (4.6) Tunnel 6 Object Tunnel6 class TunnelRoom with description "You are at a corner in the steam tunnel. You can go west and north.", w_to Tunnel8, n_to Tunnel4, ; ! (4.7) Tunnel 7 Object Tunnel7 class DarkTunnelRoom with description "You are in an east-west section of the steam tunnel. A very small passage between some steam pipes leads north, but it would be a tight squeeze.", e_to Tunnel5, w_to Tunnel9, ! n_to tight_passage, n_to [ just_checking; if (just_checking) return tight_passage; if (tight_passage.cant_crawl_through()) rtrue; else { tight_passage.crawl_message(); return tight_passage; } ], before [; Enter: if (noun == tight_passage) <>; ], ; ! (4.7.1) tight passage Object tight_passage "tight passage" has scenery door open with name 'tight' 'passage' 'narrow' 'crawl' 'very' 'small', description "It's fairly tight, but it looks like you'll fit. Barely.", ! Checks the player's possessions and prints a helpful refusal and returns ! true if any of them are not crawlable. cant_crawl_through [ obj; objectloop (obj in player) { if (~~ obj ofclass Crawlable) "You'll never get through carrying ", (a) obj, "."; ! rtrue } rfalse; ], crawl_message [; if (real_location == Tunnel7) print "You lay down on one of the pipes and start to snake through the passage. For a moment, you think you're stuck, but you manage to wriggle your way through. You emerge on the north side of the narrow crawl.^"; else print "Going through the crawl southbound is just as difficult as it was coming north, you observe.^"; ], door_dir [; if (real_location == Tunnel7) return n_to; else return s_to; ], door_to [; if (real_location == Tunnel7) return Tunnel12; else return Tunnel7; ], found_in Tunnel7 Tunnel12, ; ! (4.8) Tunnel 8 Object Tunnel8 class TunnelRoom has general ! if the control for this room is on with description [; print "You are in an east-west section of the steam tunnel. On the wall is a control unit"; if (self hasnt general) { print ". It is quite dark in this section of the tunnel; the only illumination is coming from the control unit's display"; if (TestScope(flashlight) && flashlight has light) print " (and from the flashlight, of course)"; } "."; ], e_to Tunnel6, w_to Tunnel10, ; ! (4.8.1) control unit Object control_unit "control unit" Tunnel8 has scenery with name 'control' 'unit', description [; print "The control unit is quite modern and high-tech looking, in stark contrast to the tunnels around it. It consists of a keypad (which allows entry of arbitrary numbers), a large green button and a display screen. The unit is labeled ~Station 2.~ "; return control_display.description(); ], ! Displayed on the screen, and entered using the keypad. number 322, ! To discover what object the control unit number refers to. objref [; switch(self.number) { 322: return Tunnel8; 612: return mazeequip; 293: return Tunnel9; default: return 0; } ], ; ! (4.8.1.1) control keypad Object control_pad "keypad" Tunnel8 has scenery with name 'key' 'pad' 'keypad' 'cheesy' 'membrane', description "It's one of those cheesy membrane keypads like on a microwave oven or the new Enterprise's control panels. It allows you to type numbers made up of digits from 0 to 9.", typed_on [; ! inp1 is set to 1 if a number was entered by the player. If so, the ! number is stored in the 'noun' variable. if (inp1 ~= 1) "The keypad only allows entry of the digits 0-9."; ! Numbers higher than 999 have the highest order digit dropped since ! the display has only three places. if (noun > 999) noun=noun%1000; control_unit.number=noun; print "As you type the number sequence, the display screen is updated. "; return control_display.description(); ], before [; LookUnder: "You can't do that without breaking it."; ], ; ! (4.8.1.2) control display Object control_display "display screen" Tunnel8 has scenery with name 'screen' 'display', description [ i j; ! Get the control unit number and what it refers to. i=control_unit.number; j=control_unit.objref(); print "The screen is currently displaying: ~"; EmphasisStyleText(); ! ["misc.inf":12.6] ! Print leading zeroes if necessary. if (i <= 99) print "0"; if (i <= 9) print "0"; print i; NormalStyleText(); ! ["misc.inf":12.7] print " : "; EmphasisStyleText(); ! If the control unit number refers to nothing print '???' instead of ! "ON" or "OFF". if (j ~= 0) { if (j has general) print "ON"; else print "OFF"; } else print "???"; NormalStyleText(); "~."; ], before [; LookUnder: "You can't do that without breaking it."; ], ; ! (4.8.1.3) control button Object control_button "green button" Tunnel8 has scenery with name 'green' 'button', before [ i; Push: ! Pushing the button toggles the 'general' attribute of whichever ! object is referred to by the control unit number. ! ! Tunnel8: Light control for Tunnel8. ! Tunnel9: Light control for the DarkTunnelRoom class. ! mazeequip: Toggles the 'confuse the maze' machine on and off. i=control_unit.objref(); if (i ~= 0) { print "The display is updated as you press the button. "; ! general == ON, ~general == OFF. ! Toggle the general attribute. if (i has general) give i ~general; else give i general; control_display.description(); if (i == Tunnel8) { print "^The lights in the tunnel "; if (i has general) "come on."; else { print "go out, leaving only the display screen's light "; if (TestScope(flashlight) && flashlight has light) print "(and the flashlight of course) "; "for illumination."; } } if (i == Tunnel9) ! Toggle the lights in all the dark tunnel rooms. You can't just ! say "give DarkTunnelRoom" general, since attributes of class ! objects are not dynamically inherited. Attributes are only ! inherited when a new instance of a class is created. objectloop(i ofclass DarkTunnelRoom) if (i has light) give i ~light; else give i light; rtrue; } else "The unit beeps. Nothing else appears to happen."; LookUnder: "Under the button is the control panel, which it is firmly attached to."; ], ; ! (4.9) Tunnel 9 Object Tunnel9 class DarkTunnelRoom ! has general if the control unit reference 293 is ON. All the lights in ! the DarkTunnelRoom class rooms are on if this room has general. with description "You are at a corner in the steam tunnel. You can go east or south.", e_to Tunnel7, s_to Tunnel11, ; ! (4.10) Tunnel 10 Object Tunnel10 class TunnelRoom with description "You are at a corner in the steam tunnel. You can go east or north.", e_to Tunnel8, n_to Tunnel11, ; ! (4.11) Tunnel 11 Object Tunnel11 class TunnelRoom with description "You are in a north-south section of the steam tunnels. Set into one of the walls is a large chute.", n_to Tunnel9, s_to Tunnel10, before [; Go: if (noun == w_obj or d_obj or in_obj) <>; ], ; ! (4.11.1) chute top Object -> chute "chute" has scenery container open with name 'large' 'chute' 'top', description "The chute is large enough for anything you're carrying, but not nearly big enough for you. You can't tell where it goes except down.", poured_into [; switch (noun) { bottled_ln: remove bottled_ln; "You empty the bottle into the chute. The liquid nitrogen evaporates into a fleeting cloud of steam."; original_ln: "You pour some liquid nitrogen into the chute, but the liquid evaporates before it can flow very far down the chute."; } ], before [; Receive: move noun to ChuteRoom; print "You put ", (the) noun, " into the chute, and it slides away into the darkness"; ! To prevent things like "a feather" from creating "a soft thud". if (~~ noun ofclass Crawlable) print ". After a few moments you hear a soft thud"; "."; Search: <>; Enter: "The chute is too small for you."; ], ; ! (4.12) Tunnel 12 Object Tunnel12 class TunnelRoom with description [; if (self has visited) "You are in an east-west section of the steam tunnels. A narrow passage between some steam pipes might allow you to go south."; else { "You are in another steam tunnel, but this one is substantially different from the tunnels you have been in so far. This tunnel is much wider, less cluttered; it looks like it was built more recently than the south tunnels. The tunnel itself runs east and west, and passing back to the south is evidently possible, given your presence here."; } ], e_to Tunnel13, w_to PitTop, ! s_to tight_passage, s_to [ just_checking; if (just_checking) return tight_passage; if (tight_passage.cant_crawl_through()) rtrue; else { tight_passage.crawl_message(); return tight_passage; } ], before [; Enter: if (noun == tight_passage) <>; ], ; ! (4.13) Tunnel 13 Object Tunnel13 class TunnelRoom with description "You are at the east end of a steam tunnel. A passage leads north, and another leads south.", w_to Tunnel12, n_to OutsideMaze, s_to StorageRoom, ; ! (4.14) Tunnel Storage Object StorageRoom "Storage Room" has light with description "You are in a small storage room. The exit lies north.", n_to Tunnel13, ; ! (4.14.1) rope ! ------------------------------------------------------------------------- ! The rope isn't very thoroughly implemented. It can only be tied to one ! thing in the entire game. After you have climbed down the rope it cannot ! even be untied again -- this hopefully helps mask its lack of ! interactivity. ! ------------------------------------------------------------------------- Object -> rope "rope" with name 'rope' 'true', ! 'true' is for easier debugging. number 0, describe [; if (self.number ~= 0) rtrue; ], description [; if (self.number ~= 0) "It's tied to ", (the) self.number, "."; "You see nothing special about the rope."; ], before [; Tie: if (self.number ~= 0) "It's already tied to ", (the) second, "."; Take: if (self.number ~= 0) "You'll have to untie it first."; Climb: if (self.number == 0) "Climbing the rope, in its present configuration, would get you nowhere."; if (self.number == railing) { switch (location) { PitTop: <>; PitBottom: <>; } } ClimbDown: <>; ClimbUp: if (self.number == railing) "You can't climb up the rope from here."; <>; Untie: if (self.number == 0) "The rope isn't tied to anything."; else { if (PitBottom has visited) "The knot has become too tight for you to untie."; print "You untie the rope and pick it up.^"; self.number=0; SilentAction(##Take, self); rtrue; } Pull: if (self.number ~= 0) "You give the rope a firm pull. It appears to be safely attached."; ], ; ! (4.15) Top of Pit Object PitTop class TunnelRoom with short_name "Top of Pit", description [; print "You are in a large open area in the steam tunnels. In the center of the room is a large pit, around which is a protective railing. A steam tunnel is to the east. "; if (rope.number == railing) print "A rope is tied to the railing and extends down into the pit."; new_line; rtrue; ], d_to [ just_checking; if (just_checking) return PitBottom; if (rope.number ~= railing) "You'd probably break your neck if you tried that."; else { print "You climb down the rope...^"; return PitBottom; } ], before [; Jump: "You'd probably break your neck."; Climb: if (noun == d_obj) <>; ], e_to Tunnel12, ! d_to PitBottom ; ! (4.15.1) pit top Object pit "pit" PitTop has scenery container open enterable with name 'pit', description "The pit is large and deep.", poured_into [; if (noun == bottled_ln) { remove bottled_ln; print "You empty the bottle into the pit, but the liquid nitrogen evaporates"; } else print "You pour some liquid nitrogen into the pit, but it appears to evaporate"; " before it reaches the bottom."; ], before [; Receive: move noun to PitBottom; print_ret (The) noun, " rapidly falls out of sight."; Enter: <>; JumpInto: "Suicide isn't the answer."; JumpOver: "The pit is much too large and deep for that."; Take: "That doesn't seem likely."; Push, Pull, Turn: "A ~pit~ is really just nomenclature for the idea that signifies an arbitrary sector of empty space. So you can't manipulate it."; LookUnder: "There's no such place."; Search: if (rope.number == railing) "There's a rope dangling down into the pit."; "The pit is quite deep and you can't see to the bottom."; ], put_under [; <>; ], ; ! (4.15.2) railing Object railing "rail" PitTop has scenery with name 'rail' 'railing', tied_to [; move rope to PitTop; rope.number=self; "You tie one end of the rope to the railing, and lower the other end into the pit. It appears to extend to the bottom of the pit."; ], before [; JumpOver: "You'd probably break your neck."; ], ; ! (5) GREAT UNDERGRADUATE EXCAVATION ! (5.1) Huge Cavern Object PitBottom "Huge Cavern" has light with description "You are in a huge and obviously artificial cavern. The cave has apparently been dug out over a long period of time; some parts look very old, and other areas look comparatively recent. A small bronze plaque affixed to one of the older walls reads, ~Great Undergraduate Excavation - 1982.~ From high above, a small opening in the ceiling casts a dim glow over the vast chamber. A rope extends from the opening above. Passages of various ages lead north, south, east, west, southeast, and southwest.", before [; Climb: if (noun == u_obj) <>; ], u_to [ just_checking; if (just_checking) return PitTop; print "It's a long climb, but you somehow manage it.^"; if (pit_rope in player) move pit_rope to PitBottom; return PitTop; ], w_to MachineShop, sw_to InsuranceOffice, ! u_to PitTop, n_to Cave, e_to BioHall1, se_to ChuteRoom, s_to Bank, ; ! (5.1.1) pit rope Object pit_rope "rope" PitBottom has scenery with name 'dangling' 'rope' 'substance', description "It's dangling down from the chamber above.", react_before [; Go: if (pit_rope in player && noun == s_obj or e_obj or se_obj or n_obj or sw_obj or w_obj) "You'll have to drop the rope first."; ], put_under [; <>; ], before [; Tie: "This end of the rope is coated with an experimental polymer that prevents you from making any knots."; Untie: "You can't untie it from down here."; Pull: "You pull the rope. It seems sturdy enough."; Insert, PutOn, Transfer: "You'll have to untie the rope first."; Climb: <>; ClimbDown: "You can only climb up the rope from here."; ClimbUp: <>; Take: move pit_rope to player; "You grab the rope."; LookUnder: print "Under the rope is... everything in this room.^"; LookSub(); rtrue; ], ; ! (5.1.2) pit plaque Object pit_plaque "plaque" PitBottom has scenery with name 'plaque' 'bronze', description "Great Undergraduate Excavation - 1982", ; ! (5.2) Chute Room Object ChuteRoom "Chute Room" has light with description "You are in a small room with exits to the northwest and south. The bottom of a large chute opens into the room.", nw_to PitBottom, s_to ShipRoom, before [; Go: if (noun == e_obj or in_obj or u_obj) <>; ], ; ! (5.2.1) chute bottom Object -> chute_bottom "chute" has scenery container open with name 'chute' 'bottom', poured_into "This is the bottom of the chute; you can't pour things into it.", before [; Receive: "This is the bottom of the chute; you can't put objects into it."; Search: "You can't quite see to the top of the chute."; Enter: "This is the bottom of the chute; you can't enter it. Besides, it's too small for you."; ], ; ! (5.3) Machine Shop Object MachineShop "Machine Shop" has light with description "You are in the machine shop. It appears that this huge chamber was once used to build and maintain the equipment that was used to create the Great Undergraduate Excavation. Though most of the equipment is gone now, one very large and strange machine dominates the center of the room. The exit is east, and a small passage leads north.", e_to PitBottom, out_to PitBottom, n_to MachineStorage, ; ! (5.3.1) machine Object -> machine "machine" has scenery with name 'machine', description "The machine is unlike anything you've seen before. It's not at all clear what its purpose is. The only feature that looks like it might do anything useful is a large red button labeled ~DANGER!~", ; ! (5.3.1.1) machine button Object -> machine_button "red button" has scenery with name 'red' 'button', before [; Push: print "As you push the button, the machine starts making horrible noises and flinging huge metal rods in all directions. Enormous clouds of smoke rise from the machine as it flails about. After a few minutes of this behavior, you think to step back from the machine. You're not fast enough, though. Before you can escape it, a stray metal bar flings itself against your thumb, creating a sensation not unlike intense pain. "; if (lloyd in location) lloyd.act(machine); new_line; rtrue; LookUnder: "~DANGER!~"; ], ; ! (5.4) Machine Storage Object MachineStorage "Storage Closet" with description "You are in a small storage closet off the machine shop. The exit is south.", s_to MachineShop, out_to MachineShop, ; ! (5.4.1) Mr. Happy Gear Object -> happy_gear "gear" class Treasure with name 'happy' 'mister' 'gear', description "It's an ordinary gear, about an inch in diameter. The only notable feature is that it has holes cut in such a manner that it looks like a happy face.", ; ! (5.5) Bank Object Bank "Bank" has light with description "You're in what was once the Great Undergraduate Excavation's bank. It doesn't appear to get much use any more. The exit is north, and a small passage leads south.", n_to PitBottom, s_to BankVault, ; ! (5.6) Vault Room Object BankVault "Vault Room" has light with description "The feature dominating this room is the bank's safe. The only exit is north.", n_to Bank, ; ! (5.6.1) safe Object bank_safe "safe" BankVault has container ~open scenery ! general if it is blasted open with name 'safe' 'vault' 'door', description [; if (self has general) { print "The safe looks as though it has suffered some sort of intense trauma lately; the door is just barely hanging on its hinges, leaving the contents of the safe quite exposed. "; ShowCont(self); new_line; rtrue; } else "The safe is huge, like the type you might find in a bank. The only notable features are a huge metal door (quite closed), and a large slot labeled ~Night Deposit slot.~"; ], before [; Open: if (self hasnt general) "You can't open such a secure safe without resorting to some sort of drastic action."; else "The safe is already open and likely to stay that way."; Close: if (self has general) "You close the safe but the door falls back open again."; else "The safe is closed and likely to stay that way."; Receive: if (self hasnt open) "The safe is closed. You might try the slot."; LookUnder, Push, Pull, Take: "The huge safe is much too heavy."; ], ; ! (5.6.1.1) deposit slot Object bank_slot "night deposit slot" BankVault has scenery container open with name 'slot' 'night' 'deposit', description "The slot is very large, big enough to put a large sack of money into. Unfortunately, you won't have much luck extracting anything from the slot, since it has been carefully constructed to allow items to enter, but not to leave.", poured_into [; switch (noun) { bottled_ln: remove noun; print "You empty the bottle "; original_ln: print "You pour some liquid nitrogen "; } "into the slot. Shortly, a cloud of chilly steam emerges and floats away."; ], before [; Receive: move noun to bank_safe; print (The) noun, " disappears into the deposit slot"; if (bank_safe has open) " and pops out the other side, landing softly in the safe."; else "."; Search: if (bank_safe has open) "The slot designed in a cunning fashion so that items can only be inserted from the outside."; else "You can't see anything in the slot."; ], ; ! (5.6.1.2) DarbCard Object darbcard "card" bank_safe class Crawlable Treasure with name 'darbcard' 'darb' 'card', description "You see nothing special about the DarbCard." ; ! (5.7) Insurance Office Object InsuranceOffice "Insurance Office" has light with description [; print "You are in an insurance office. Like most insurance offices, the area is rather nondescript. The exit is northeast."; if (lloyd.number == 0) lloyd.act(InsuranceOffice); new_line; rtrue; ], ne_to PitBottom, out_to PitBottom, ; ! (5.8) Tunnel Object Cave "Tunnel" has light with description "You're in a north-south tunnel. The tunnel slopes steeply downward to the north.", n_to SubwayStation1, d_to SubwayStation1, s_to PitBottom, u_to PitBottom, ; ! (5.9) Subway Station 1 Object SubwayStation1 "Subway Station" has light with description "You're in a very large musty chamber deep underground. In the center of the room is a small rail car. Strangely, the car is sitting on the floor; there are no rails under the car, or, indeed, in the station at all. You look around, and notice about three meters up the east wall is a round tunnel. A passage leads south.", s_to Cave, before [; Go: if (noun == e_obj) <>; ], ; ! (5.9.1) rail car Object railcar "rail car" SubwayStation1 has scenery container open enterable ! general if it is broken with name 'rail' 'car' 'railcar' 'rail-car', description [; print "This is a small rail car, big enough for a couple of people. It has a small control panel, which consists of a green button, a gauge, and a small hole labeled ~Coolant.~ "; if (funnel in rail_hole) print "The hole seems to contain a funnel. "; rail_meter.description(); ! Since the player can enter the car, I take care not to provide ! useless information, e.g., "In the car you can also see yourself." ! However, I wanted to make the 'note' as easy to find as possible, so ! the rail car divulges its contents upon examination, unless the only ! thing to see is the player. The CONCEALED_BIT is used for the ! WriteListFrom call to prevent the player from seeing himself, e.g., ! "In the car you can see yourself and a small note." if ((children(self) && player notin self) || children(self) > 1) { print "^In the rail car you can also see "; WriteListFrom(child(self), CONCEAL_BIT+ENGLISH_BIT+RECURSE_BIT+PARTINV_BIT); "."; } ], react_before [; Exit: if (player notin self || rail_button hasnt general) rfalse; else "Please wait until the rail car has come to a complete and final stop, and the captain has turned off the ~Fasten Seat Belt~ sign. (Actually, I made up the part about the ~Fasten Seat Belt~ sign, but you'll have to wait until the car has stopped nonetheless."; ], number 0, destination 0, daemon [; if (location ~= RailTunnel) { ! The next three lines, which move the rail car, were copied from the ! part of the GoSub routine in "verblibm.h" that actually moves the ! player when it is in a vehicle. I couldn't use the PlayerTo ! routine here because there was no easy way to get the rail car to ! move along with the player using PlayerTo. MoveFloatingObjects() ! had to be called to make sure that the tunnel is correctly in ! place. ! move railcar to RailTunnel; ! location=RailTunnel; ! MoveFloatingObjects(); PlayerTo(RailTunnel, 1); move railcar to RailTunnel; move player to railcar; "^The car rises to about three meters off the floor. It then starts to accelerate toward the tunnel, and plunges into the tunnel with a rush of air."; } else if (self.number > 0) { self.number--; "^The car races down the tunnel at terrifying speed."; } else { ! move railcar to self.destination; ! location=self.destination; ! MoveFloatingObjects(); PlayerTo(self.destination, 1); move railcar to self.destination; move player to railcar; StopDaemon(self); give rail_button ~general; "^The car starts to decelerate sharply. After a few more seconds, it emerges into a station and glides to a halt. It slowly descends to the ground; once settled, the hum of its engine gradually disappears."; } ], ! ------------------------------------------------------------------------- ! I'm using add_to_scope here so that the rail_hole, the rail_button, and ! the rail_meter will be part of the railcar. I can't make them children of ! the rail car because the rail car is a container. The parser would ! incorrectly assume that the meter, the hole, and the button were "in" the ! rail car. ! ------------------------------------------------------------------------- add_to_scope rail_hole rail_meter rail_button, ; ! (5.9.1.1) coolant gauge Object rail_meter "gauge" has scenery with name 'gauge' 'guage' 'meter', description [; print "The gauge is not labeled with any units you recognize, but the arc is divided into regions colored green, yellow, and red. The needle is currently in the "; if (rail_hole has general) print "green"; else print "red"; " section of the scale."; ], ! There's a bug in AttemptToTakeObject (verblibm.h) that causes an object ! zero error if you try to take an object with no parent (like this one). before [; Take: print_ret (The) self, " is firmly attached to the control panel."; ], ; ! (5.9.1.2) coolant hole Object rail_hole "hole" has scenery container open ! general if filled with liquid nitrogen with name 'hole' 'tank', description [; if (funnel in self) "A funnel is in the hole."; if (self has general) "Wisps of water vapor rise from the hole."; "The hole is labeled ~Coolant.~ It's about an inch or so in diameter."; ], poured_into [; if (self has general) "The tank is already full."; switch (noun) { original_ln: if (funnel notin self) "The hole is too small; most if not all of the liquid nitrogen you pour spills all around, rather than into the hole."; else { give self general; "You carefully pour some liquid nitrogen into the funnel. It doesn't take very much before the tank is full."; } bottled_ln: give self general; remove bottled_ln; "You carefully pour the contents of the bottle into the hole."; } ], before [; Receive: if (noun == funnel) { move funnel to self; "A perfect fit."; } if (noun == bottlecap) "You could put it in there, but you could never get it back out again."; print_ret (The) noun, " won't fit in the hole."; Take: "It is very difficult to hold a hole."; ], ; ! (5.9.1.3) ignition button Object rail_button "green button" has scenery ! general if it has been pushed and the car is still active with name 'green' 'button' 'ignition', before [; Push: ! An "if - else if - else" structure works like a switch statement, ! but it can have more complicated mutually exclusive dependencies ! than a regular switch statement. For a generic switch statement to ! be applicable, all the conditions must result from the state of ! one calculation, which sometimes isn't powerful enough. ! This is to help players who have entered this unwinnable state to ! see the error of their ways. if (railcar has general) { print "Nothing happens."; ! A hint for the doomed... if (random_book in ComputerCenter) print " The rail car is toast, and so are your chances of winning this game."; new_line; rtrue; } ! This is a little cop-out to avoid having to code the rail car ! moving by itself into the tunnel. It also helps avoid another ! unwinnable state. else if (player notin railcar) "It is hard to reach the button from outside the rail car."; ! A tiny little cop-out. What *should* the button do after the car ! has taken off? else if (self has general) "Nothing happens. Perhaps that is because you have already pushed the button quite recently."; else if (rail_hole has general) { ! Set the trip timer. railcar.number=3; ! Set the destination. if (location == SubwayStation1) railcar.destination=SubwayStation2; else railcar.destination=SubwayStation1; ! Set the daemon running. StartDaemon(railcar); ! Alert the button that it has been pushed and that it hasn't yet ! reset. give self general; "A low-frequency hum sounds from within the rail car. After a few moments, the car starts to levitate off the track."; } else { ! How's this for an unwinnable state? It will inconvenience rash ! button-pushers. give railcar general; "A low-frequency hum sounds from within the rail car. It grows in strength, and soon starts to vibrate the whole car. You smell the familiar odor of burning electronic components. Suddenly, a bright light flashes underneath the rail car, a cloud of thick black smoke rises, and the humming stops. It appears you have toasted the rail car."; } LookUnder: "A rail car. Yup. That's it."; Turn: "Um, you might try pushing it instead."; Take: print_ret (The) self, " is firmly attached to the control panel."; ], ; ! (5.9.1.4) rail car instructions Object small_note "small note" railcar class Crawlable with name 'small' 'note', description [; font off; print " !!!! CalTach Floating Car Company !!!!^ ^ Hello, Drifter!^ ^ Instructions for use: ^^ Be sure to check your coolant level. ^ Push the ignition to initiate lift-off.^ ^ Please keep your hands and other ^ extremities in the vehicle at all times.^"; font on; rtrue; ], ; ! (5.9-11.2) tunnel mouth Object tunnel_mouth "tunnel" has scenery with name 'round' 'tunnel', before [; Enter: "The tunnel is too high up the wall. You won't be able to enter it without benefit of the rail car."; Search: "You aren't tall enough to see inside the tunnel."; ], ! Since the tunnel_mouth is not a container, it doesn't get benefit of ! the Receive fake action. Using a react_before routine avoids the bother ! of making the tunnel_mouth a container. react_before [; Insert, PourInto, Transfer: if (second == self) "The tunnel is too high up the wall."; ], found_in SubwayStation1 SubwayStation2, ; ! (5.10) Rail Tunnel Object RailTunnel "Tunnel" has light with description "The tunnel is rather nondescript.", ; ! (5.11) Subway Station 2 Object SubwayStation2 "Subway Station" has light with description "You're in a subway station. About three meters up the west wall is a tunnel; a passage (at ground level) leads south. A rail car is sitting on the floor in the center of the room.", before [; Go: if (noun == w_obj) <>; ], s_to ComputerCenter, ; ! (5.12) Computer Center Object ComputerCenter "Computer Center" has light with description "You're in the computer room. Unfortunately, all the equipment here is hopelessly out of date and doesn't interest you in the least. The exit is north.", n_to SubwayStation2, out_to SubwayStation2, ; ! (5.12.1) computer equipment Object -> computer_equipment "computer equipment" has scenery with description "The equipment is all very outdated. It's not the least bit interesting.", article "some", ! This before routine rejects every action except Examine. before [; Examine: rfalse; default: "The computer equipment isn't important."; ], ; ! (5.12.2) A Million Random Digits Object -> random_book "book" class Treasure with name 'book' 'million' 'random' 'digits', description "The book is entitled ~A Million Random Digits.~ In flipping through the book, you find that it is, in fact, a million random digits, nicely tabulated and individually numbered from 0 to 999,999 (computer people always start numbering at 0).", ; ! (5.13) Bio Hall 1 Object BioHall1 "Hall" has light with description "You are in an east-west hallway. A passage labeled ~Bio Lab~ leads south.", w_to PitBottom, e_to BioHall2, s_to BioLab, in_to BioLab, ; ! (5.14) Bio Lab Object BioLab "Bio Lab" has light with description [; print "You are in the Biology Lab. All sorts of strange equipment is scattered around the room. A lab bench is in the center of the room, and on one wall is a cabinet. "; if (cabinet has open) ShowCont(cabinet); ! ["misc.inf":12.4] "A passage leads north."; ], n_to BioHall1, out_to BioHall1, ; ! (5.14.1) strange equipment Object strange_equipment "strange equipment" BioLab has scenery with name 'strange' 'equipment', article "some", description "The equipment is entirely unfamiliar to you.", before [; Examine: rfalse; default: "The strange equipment isn't important."; ], ; ! (5.14.2) lab bench Object lab_bench "lab bench" BioLab has scenery supporter with name 'bench' 'lab', description [; print "The bench is topped with one of those strange black rubber surfaces that seemingly all scientific lab benches have. "; ShowCont(self); ! ["misc.inf":12.4] new_line; rtrue; ], ; ! (5.14.2.1) CloneMaster Object clone_master "CloneMaster" lab_bench has container open with name 'master' 'clone' 'clonemaster' 'clone-master' 'receptacle', description [; print "The CloneMaster is a simple machine. It consists of a button marked ~Clone~ and a small receptacle. "; ShowCont(self); ! ["misc.inf":12.4] new_line; rtrue; ], before [; Receive: if (~~ noun ofclass Crawlable) "", (The) noun, " won't fit in the CloneMaster."; ], add_to_scope clone_button, ; ! (5.14.2.1.1) CloneMaster button Object clone_button "clone button" with name 'clone' 'button', before [; Push: if (slime in clone_master) { remove slime; print "The CloneMaster clicks and whirs for several seconds. "; ! The components necessary to make a female slime creature are... if (gfxq3 in clone_master && polyblue in clone_master && compoundT99 in clone_master && children(clone_master) == 3) { print "A monstrous female version (again, don't ask how you know it's female) leaps from the tiny machine"; ! Note that the bio_creature is immobile, so this quick test ! will suffice to see if he is in scope. if (location == BioHall2) { remove bio_creature; ". The two monsters look at each other with passion in their mutant eyes. They run to each other with open arms, seemingly in slow motion. They embrace, engage in some mushy behavior, and then run away together to elope."; } else ", looks around, and, seeing nothing of interest, runs off."; } ! All other possible chemical combinations result in a male slime ! creature. else "An exact duplicate of the monstrous creature whose slime you placed in the CloneMaster leaps forth from the tiny machine. He looks at you menacingly for a moment, then runs off into the distance, never to be seen again."; } else "Nothing happens."; Take: "The button is a part of the CloneMaster."; ], ; ! (5.14.2.2) funnel Object funnel "funnel" lab_bench with name 'funnel', react_before [; Insert, Transfer: if (second == self && (~~ (noun ofclass LiquidNitrogen || noun == toxicola))) "The funnel is for liquids only."; ], poured_into [ i; ! The funnel routs anything poured into it to its parent. Note that ! the only two liquids in this game are the cola and the liquid ! nitrogen. The cola can never be poured out of the cup, so the funnel ! doesn't need to concern itself with the cola. i=parent(self); if (i hasnt container) { if (noun == bottled_ln) remove noun; "The liquid nitrogen pours through the funnel, lands nowhere in particular, and evaporates."; } else <>; ], ; ! (5.14.3) cabinet Object cabinet "cabinet" BioLab has scenery container openable with name 'cabinet', ; ! (K) ChemItem class Class ChemItem class Crawlable has proper with ! The '//p' suffix in a dictionary word (a word in single quotes) denotes ! a word that is considered plural by the parser. name 'lump' 'lumps//p' 'label' 'goo' 'chemical' 'chemicals//p', ! The list_together property will list all objects with the same ! list_together property together in inventories and room listings. list_together "chemicals", description [; "It's a small lump of goo. The only identification is a label reading ~", (name) self, ".~"; ], ; ! (5.14.3.1) GF-XQ3 Object gfxq3 "GF-XQ3" cabinet class ChemItem with name 'genetic' 'factor' 'gf-xq3' 'gf' 'xq3', ; ! (5.14.3.2) GF-XQ9 Object gfxq9 "GF-XQ9" cabinet class ChemItem with name 'genetic' 'factor' 'gf-xq9' 'gf' 'xq9', ; ! (5.14.3.3) Poly Red Object polyred "Poly Red" cabinet class ChemItem with name 'polymerase' 'poly' 'red', ; ! (5.14.3.4) Poly Blue Object polyblue "Poly Blue" cabinet class ChemItem with name 'polymerase' 'poly' 'blue', ; ! (5.14.3.5) Compound T99 Object compoundT99 "Compound T99" cabinet class ChemItem with name 'compounds//p' 'compound' 'T99', ; ! (5.14.3.6) Compound T30 Object compoundT30 "Compound T30" cabinet class ChemItem with name 'compounds//p' 'compound' 'T30', ; ! (5.15) Bio Hall 2 Object BioHall2 "Hall" has light with description "You are at the east end of an east-west hallway. A doorway leads east.", w_to BioHall1, e_to BioOffice, in_to BioOffice, ; ! (5.15.1) slime creature Object -> bio_creature "creature" has animate with ! This parse_name routine is intended to allow "creature" or "monster" to ! refer to the bio_creature, but "slime", "slimy", "leathery", can only be ! prepositional modifiers. This will help differentiate the monster from ! the glob of slime that will shortly appear. ! ! This is a good prototype of a common parse_name routine that implements, ! in a sense, adjectives and nouns. Adjectives must come first, and must ! be followed by at least one noun. parse_name [ wd adj_count noun_count; wd=NextWord(); while (wd == 'slime' or 'slimy' or 'slimey' or 'leathery' or 'green' or 'bright') { wd=NextWord(); adj_count++; } while (wd == 'creature' or 'monster') { wd=NextWord(); noun_count++; } if (noun_count > 0) return adj_count + noun_count; else return 0; ], description "It looks like the result of a biological experiment that failed (or succeeded, depending on who performed the experiment).", describe "^An enormous creature is blocking the hallway to the east. He (please don't press for details as to how you know, but ~he~ is the appropriate pronoun here) appears to be part human, but exactly what part is not clear. The creature's leathery skin is a bright green and is largely covered with a thick translucent slime.", react_before [; Go: if (noun == e_obj) { if (parent(slime) == 0) { move slime to player; give slime worn; "The creature grabs you and pushes you back, depositing a huge glob of slime on you in the process."; } else "The creature won't let you pass."; } ], each_turn [; new_line; switch (random(5)) { 1: "The creature roars a huge roar in your general direction."; 2: "The creature menaces you."; 3: "In a tender moment, the creature produces a magazine and opens up centerfold. He looks longingly at the picture. After a few moments, he notices you again, and puts away the magazine; as he's putting it away, you see that it's a copy of ~Playmutant.~"; 4: "The creature looks at you warily."; 5: "The creature growls at you, showing his enormous pointy fangs."; } ], ; ! (5.15.1.1) slime Object slime "glob of slime" class Crawlable ! The slime is clothing even though it isn't actually 'worn' in the ! typical sense. It is convenient to let the library routines take care of ! the 'worn' state of the slime. has clothing with name 'glob' 'slime', ! It had to have a parse name routine to keep it distinguishable from the ! slime creature. It was also convenient to allow the word 'of' without ! having it appear in a name property. parse_name [ wd; wd=NextWord(); if (wd == 'slime') return 1; if (wd == 'glob') { if (NextWord() ~= 'of' && NextWord() ~= 'slime') return 1; else return 3; } return 0; ], before [; Wear: "No, thank you."; ], ; ! (5.16) Bio Office Object BioOffice "Bio Office" has light with description "You are in the Biology Office. A large desk dominates the room. The exit is west.", w_to BioHall2, out_to BioHall2, ; ! (5.16.1) bio desk Object -> bio_desk class SimpleDesk with name 'large', ; ! (5.16.1.1) The Great Seal of the Omega Object ->-> omega "rubber stamp" class Treasure with ! The phrase 'the great seal of the omega" is troublesome enough that I ! used a parse_name routine. I wanted to avoid putting 'of' and ! 'the' into an item's name property. parse_name [ wd count; wd=NextWord(); while(wd == 'seal' or 'omega' or 'stamp' or 'great' or 'rubber' or 'approved' or 'treasure' or 'treasures') { if (wd == 'seal') { if (NextWord() == 'of') { count++; if (NextWord() == 'the') count++; else wn--; } else wn--; } if (wd == 'treasures') parser_action=##PluralFound; count++; wd=NextWord(); } return count; ], description "The Great Seal is a large rubber stamp about an inch and a half square. The stamp consists of a large circle that is filled by a giant capital omega, under which is the word ~Approved.~ Around the outside of the circle, the words ~The Great Seal of the Omega~ are inscribed.", ; ! (5.17) Spaceship Room Object ShipRoom "Spaceship Room" has light with description "This is a very large cave dominated by a tall spaceship. High above, a vertical tunnel leads upward; it is evidently a launch tube for the spaceship. The exit is north.", n_to ChuteRoom, in_to ShipInterior, u_to "The tunnel is far too high above to climb.", ; ! (5.17.1) spaceship Object -> space_ship "spaceship" has static with name 'spaceship' 'space' 'ship' 'door' 'tall' 'gray' 'metal' 'cylinder', description [; print "The spaceship is a tall gray metal cylinder with a pointed nosecone high above, and three large fins at the bottom. A large socket "; if (motivator in ship_receptacle) print "on the side contains a warp motivator. "; else print "is on the side (the socket is currently empty). The socket is labeled ~insert warp motivator here.~ "; "^^You can enter the spaceship through an open door."; ], before [; Enter: <>; ], ; ! (5.17.1.1) warp motivator socket Object -> ship_receptacle "socket" has scenery container open with name 'socket', before [; Receive: if (noun == motivator) { move motivator to self; "It fits snugly."; } else "It doesn't fit."; ], ; ! (5.18) Ship Interior Object ShipInterior "Spaceship" has light with description "You are in the cockpit of the spaceship. The control panel is quite simple; the only feature that interests you at the moment is a button labeled ~Launch~.", out_to ShipRoom, ; ! (5.18.1) launch button Object -> launch_button "launch button" has scenery with name 'button' 'launch', before [; Push: if (motivator in ship_receptacle) { print "The ship's engines start to come to life. ~Launch sequence engaged,~ the mechanical computer voice announces. "; if (lloyd in location) lloyd.act(launch_button); deadflag=2; score=score + 10; "^^The hatch closes automatically, sealing you into the space vessel. The engines become louder and louder. The computer voice announces, ~Launch in five... four... three... two... one... liftoff!~ The engines blast the ship into orbit.^^You realize that the time has come to set course for ~Deep Space Drifter,~ another fine TADS adventure, by Mike Roberts and Scott McAdams."; } "The ship's computer voice announces from a hidden speaker, ~Error: no warp motivator installed.~"; ], ;