!% -SD !% !============================================================================ Constant Story "MYSTERY HOUSE"; Constant Headline "^...Taken Over^"; !============================================================================ !! This is a reimplementation of Mystery House !! by Roberta and Ken Williams, 1980 !! offered to the pubic domain, 1987 !! !! The code (ready for your modifications) is part of !! !! http://turbulence.org/Works/mystery/ !! !! Mystery House Taken Over, March 2005 !! by Nick Montfort, Dan Shiovitz, Emily Short, !! and the Mystery House Occupation Force !! offered to the public domain, March 2005 !! !! !! Mystery House Taken Over is a 2004 commission of New Radio and !! Performing Arts, Inc., (aka Ether-Ore) for its Turbulence web site. It !! was made possible with funding from the Andy Warhol Foundation for the !! Visual Arts. !============================================================================ ! MYSTERY HOUSE Constants !============================================================================ ! Determines the number of turns that elapse before the "it is getting dark" ! message begins to appear; original number is 20. Constant TWILIGHT = 20; ! Determines the number of turns that elapse before darkness falls. ! Original number is Constant NIGHTFALL = 40; ! Determines the number of turns for which the fire will burn in the Dining ! Room before killing the player; original number is 2 Constant FIRE_DURATION = 2; ! Determines the number of turns for which the match will burn; ! original number is 4 Constant MATCH_DURATION = 4; ! Determines the number of shots in the gun; original number is 1. Constant AMMUNITION = 1; ! Determines the number of turns you have before Daisy kills you; orig is 2. Constant DAISY_PATIENCE = 2; ! Indicates objects that appear in the picture but not in the text room ! description. Most picturescenery is minimally implemented in the original. Attribute picturescenery; ! This is screen management for the graphical version; if you don't ! have some familiarity with Glulx, you should probably leave it alone. #ifdef TARGET_GLULX; Include "gwindefs"; #endif; Include "Parser"; ! This is screen management for the graphical version; if you don't ! have some familiarity with Glulx, you should probably leave it alone. #ifdef TARGET_GLULX; Include "gwincls"; Include "gwindows"; #endif; Global parse_exemption; !============================================================================ ! SCREEN MANAGEMENT ! ! We rely on GWindows, by L. Ross Raszewski, to handle the graphical screen ! aspect under Glulx. ! !============================================================================ ! For historical reasons, this list is not in the world's most logical order ! -- but that shouldn't matter. If you put an image of the correct name ! in the directory with the files and then run blorb with the provided ! resource file, your new image will automatically replace the older one. ! ! You should not have to touch this section, but if you must... ! ! If you want to remove an image completely and have removed all references ! to it, you can remove its constant declaration here and remove it from the ! blorb file, for some very slight savings in space. ! ! You can add images here if you add them in the blorb file as well. Start ! numbering your new images at 150. ! There are no 18-23, 29, 46, 60, 86, 104, 118. Constant front_yardPIC = 1; Constant front_door1PIC = 2; Constant at_stairwayPIC = 3; Constant attic1PIC = 4; Constant attic4PIC = 5; Constant back_yard1PIC = 6; Constant basement1PIC = 7; Constant bathroom1PIC = 8; Constant boys_bedroomPIC = 9; Constant cabinet1PIC = 10; Constant cemetaryPIC = 11; Constant chest1PIC = 12; Constant dining_room1PIC = 13; Constant doorwayPIC = 14; Constant entry_hall2PIC = 15; Constant entry_hall1PIC = 16; Constant forestPIC = 17; Constant junctionPIC = 24; Constant hole1PIC = 25; Constant kitchen1PIC = 26; Constant kitchen2PIC = 27; Constant large_bedroom1PIC = 28; Constant note1PIC = 30; Constant note2PIC = 31; Constant note3PIC = 32; Constant note4PIC = 33; Constant nurseryPIC = 34; Constant on_stairwayPIC = 35; Constant pantryPIC= 36; Constant passagewayPIC= 37; Constant refrigerator1PIC= 38; Constant side_yard1PIC= 39; Constant sink1PIC= 40; Constant small_bedroomPIC= 41; Constant storage_room1PIC= 42; Constant study1PIC= 43; Constant study2PIC= 44; Constant titlePIC= 45; Constant towerPIC= 47; Constant trapdoorPIC= 48; Constant treePIC= 49; Constant treetopPIC= 50; Constant tunnelPIC= 51; Constant chest2PIC = 52; Constant dining_room2 = 53; Constant hole2PIC = 54; Constant library1PIC = 55; Constant sink2PIC = 56; Constant crawlspacePIC = 57; Constant refrigerator2PIC = 58; Constant cabinet2PIC = 59; Constant note_itemPIC = 61; Constant front_door2PIC = 62; Constant dining_room3PIC = 63; Constant kitchen3PIC = 64; Constant kitchen4PIC = 65; Constant kitchen5PIC = 66; Constant kitchen6PIC = 67; Constant kitchen7PIC = 68; Constant kitchen8PIC = 69; Constant kitchen9PIC = 70; Constant kitchen10PIC = 71; Constant kitchen11PIC = 135; Constant kitchen12PIC = 73; Constant kitchen13PIC = 74; Constant kitchen14PIC = 75; Constant kitchen15PIC = 76; Constant dining_room5PIC = 77; Constant dining_room6PIC = 78; Constant dining_room7PIC = 79; Constant dining_room8PIC = 80; Constant attic2PIC = 81; Constant study3PIC = 82; Constant back_yard2PIC = 83; Constant back_yard3PIC = 84; Constant back_yard4PIC = 85; Constant storage_room2PIC = 87; Constant side_yard2PIC = 88; Constant kitchen16PIC = 89; Constant kitchen17PIC = 90; Constant kitchen18PIC = 91; Constant kitchen19PIC = 92; Constant kitchen20PIC = 93; Constant kitchen21PIC = 94; Constant kitchen22PIC = 95; Constant kitchen23PIC = 96; Constant kitchen24PIC = 97; Constant attic3PIC = 98; Constant cemetary6PIC = 99; Constant library2PIC = 101; Constant candle_itemPIC = 102; Constant pitcher2_itemPIC = 103; Constant butterknife_itemPIC = 105; Constant key_itemPIC = 106; Constant skeletonkey_itemPIC = 107; Constant basement8PIC = 108; Constant picture_itemPIC = 109; Constant sledgehammer_itemPIC = 110; Constant gun_itemPIC = 111; Constant cemetary2PIC = 112; Constant cemetary5PIC = 113; Constant cemetary4PIC = 114; Constant cemetary3PIC = 115; Constant dagger_itemPIC = 116; Constant towel_itemPIC = 117; Constant basement2PIC = 119; Constant basement6PIC = 120; Constant basement7PIC = 121; Constant basement4PIC = 122; Constant basement5PIC = 123; Constant large_bedroom2PIC = 124; Constant dining_room4PIC = 125; Constant matches_itemPIC = 126; Constant pitcher1_itemPIC = 127; Constant bathroom2PIC = 128; Constant jewels_itemPIC = 129; Constant brick_itemPIC = 130; Constant basement3PIC = 131; Constant shovel_itemPIC = 132; Constant attic5PIC = 133; Constant attic6PIC = 134; #ifdef TARGET_GLULX; Constant SETWIDTH = 560; Constant SETHEIGHT = 310; WindowPair root; Textbuffer mainwin "mainwin" root; WindowPair imageswindows "imageswindows" root; Graphwin picwin "picwin" imageswindows with split 70, ! % of the screen that goes to the graphics split_dir winmethod_Above image titlePIC, real_width 0 0, real_height 0 0, update [ ; self.redraw(); ], ! This somewhat heinous set of instructions centers the ! image against a black background and scales so that it ! is as large as possible without losing proportionality redraw [ ima w h x y margin marginh obj spr top ; if (ima == 0) { if (self.closeup && self.closeup provides image && (self.closeup).image()) { if (TestScope(self.closeup)) ima = (self.closeup).image(); else ima = location.image(); } else ima = location.image(); } glk_image_get_info(ima,self.&real_width,self.&real_height); w = self.&real_width-->0; h = self.&real_height-->0; if (h == 0) { rfalse; } ! just in case graphics are missing; otherwise, crashes ! wipe the screen to black (you can change this to a white-wipe) ! by setting the second number to 1, or do other things if you ! get fancy with it glk_window_set_background_color(self.winid,0); glk_window_clear(self.winid); ! stop there, not drawing any picture, if it has gotten dark if (Darkness_Daemon has general) rfalse; ! figure out at what proportion to draw the chosen image, and ! draw it scaled to fit in the window without distortion -- ! if you want it to do this, uncomment this portion and remove the ! second portion ! x = (100*self.height)/h; ! size of the actual image ! y = (w*x)/100; ! margin = (self.width-y)/2; ! gwin_image_draw(self.winid,ima,margin,0,y,self.height); ! draw image centered in window at the set height and width. ! if you want not to do this, remove this portion. margin = (self.width-SETWIDTH)/2; marginh = (self.height-SETHEIGHT)/2; gwin_image_draw(self.winid,ima,margin,marginh,SETWIDTH,SETHEIGHT); ], closeup 0, has general; ! The original MH draws objects in a room directly over the room ! picture. We chose to be inaccurate about this part of the ! reproduction because making overlays look good puts a lot of ! restrictions on the artist -- a separate window for items in the ! room seemed a good compromise to allow people to add their own ! images without undue technical fuss. Graphwin ->-> portablewin, with image titlePIC, split 50, ! pixel height of window split_dir winmethod_Below, real_width 0 0, real_height 0 0, update [ ; self.redraw(); ], ! This somewhat heinous set of instructions centers the ! image against a black background and scales so that it ! is as large as possible without losing proportionality redraw [ w h x y margin obj spr top ima offset; offset = 0; ! wipe window glk_window_set_background_color(self.winid,0); glk_window_clear(self.winid); if (Darkness_Daemon has general) rfalse; objectloop(obj in location && obj provides sprite) { spr = obj.sprite(); glk_image_get_info(spr,self.&real_width,self.&real_height); w = self.&real_width-->0; h = self.&real_height-->0; gwin_image_draw(self.winid,spr,offset,0,w,h); offset = offset + w; } ], closeup 0, has general abssplit; [ InitGWindows; Active_UI=root; Main_GWindow=mainwin; ]; #endif; !============================================================================ ! TWO-WORD PARSER ! ! This parser emulates the original two-word parser of MHTO by accepting ! exactly one verb and one noun (with a few weird formations such as WATER ! ON). As a result, it is substantially inferior to the original Inform ! parser. ! ! There are a couple of ways in which this does not try to be true to the ! original, though. In particular, it leaves in UNDO and OOPS (which Inform ! catches early before regular parsing, for assorted reasons -- they could ! be torn out, but they add a great deal to playability). Similarly, the ! original Mystery House requires all input to be in upper case and ! refuses to recognize lower case input. This again seemed too dreary ! to bother reproducing. ! ! If you prefer a more sophisticated full-sentence parser, REMOVE THIS ! ENTIRE SECTION down to 'LIBRARY DEFAULTS'. The result should still ! compile and run, but with the addition of more recognized commands. ! (You will then have to add appropriate responses for those commands. You ! will also need to add a name to the front door that distinguishes it ! from other doors leading off the entry hall -- otherwise it will be ! hard to tell it from those when it comes to opening and unlocking it.) ! !============================================================================ Verb 'xxxxxxx' * -> EmptyVerb; [ EmptyVerbSub; rtrue; ]; ! If the verb is recognized, assign an action. If it isn't, ! print a generic not-understood message. [ BeforeParsing bpverb bpnoun index; if (parse_exemption) rfalse; ! pick up the first two words wn = 1; bpverb = NextWordStopped(); ! print (address) bpverb; wn = 2; bpnoun = NextWordStopped(); ! print (address) bpnoun; if (bpnoun == NULL) index = 1; if (InterpretVerb(bpverb, index)) { RemapBuffer(); rtrue; } if (index == 1) { RemapBuffer(); if (bpverb == 'look') "THERE IS NOTHING SPECIAL"; else "I DONT UNDERSTAND WHAT YOU MEAN"; } if (InterpretNoun(bpnoun)) { RemapBuffer(); rtrue; } ]; [ InterpretVerb bpverb index; switch(bpverb) { ! lie is there presumably for the case of LIE DOWN, but the original ! game does not actually check to see whether the second word is ! in fact down 'drink', 'sip', 'taste': action = ##Drink; 'use', 'with': action = ##Use; 'shoot', 'fire': action = ##Shoot; 'press', 'push', 'turn', 'push', 'slide', 'move': action = ##Push; 'faucet', 'turn', 'water', 'on': action = ##TurnOnWater; 'off': action = ##TurnOffWater; 'unlight': action = ##Blow; 'look', 'examine': action = ##Examine; 'light', 'strike': action = ##Burn; 'lift', 'take', 'get': action = ##Take; 'dump', 'drop', 'set', 'leave': action = ##Drop; 'kill', 'slay': action = ##Attack; 'eat', 'consume': action = ##Eat; 'wipe', 'rub', 'remove': action = ##Rub; 'flush': action = ##Flush; 'open': action = ##Open; 'close', 'shut': action = ##Close; 'unlock', 'unlatch': action = ##UnlockEasy; 'break', 'tear', 'bust': action = ##Attack; 'pour': action = ##Pour; 'read': action = ##Read; 'talk', 'speak': action = ##Answer; 'go': action = ##Go; 'unscrew', 'unbolt', 'loosen': action = ##Loosen; ! intransitive verbs should execute immediately without further ! checks, unless a noun was supplied, in which case they should ! fall through to the next stage 'save', 'store': if (index == 1) <>; else action = ##save; 'restore': if (index == 1) <>; else action = ##restore; 'quit', 'bye', 'stop': if (index == 1) <>; 'jump', 'leap': if (index == 1) <>; 'u//', 'up', 'climb', 'ascend': if (index == 1) <>; else action = ##climb; 'd//', 'down', 'descend': if (index == 1) <>; else "I DONT UNDERSTAND WHAT YOU MEAN"; 'n//', 'north': if (index == 1) <>; else "I DONT UNDERSTAND WHAT YOU MEAN"; 'w//', 'west': if (index == 1) <>; else "I DONT UNDERSTAND WHAT YOU MEAN"; 's//', 'south': if (index == 1) <>; else "I DONT UNDERSTAND WHAT YOU MEAN"; 'e//', 'east': if (index == 1) <>; else "I DONT UNDERSTAND WHAT YOU MEAN"; 'help': if (index == 1) <>; 'inventory', 'inven', 'carrying': if (index == 1) <>; 'sleep', 'rest', 'retire', 'lie': if (index == 1) <>; 'fuck', 'suck', 'shit', 'cunt': if (index == 1) <>; ! A score command is recorded among the source code for MHTO but ! if it is typed in the game, nothing happens. 'score': "I DONT UNDERSTAND WHAT YOU MEAN"; ! counter-intuitively, the original game understands "RUN STAIRS" ! but not "RUN NORTH" 'enter', 'run', 'exit', 'leave', 'walk': action = ##go; default: print "I DONT KNOW HOW TO "; ReprintWord(1); " SOMETHING"; } rfalse; ]; [ InterpretNoun bpnoun x matched in_scope matched_scope ; ! start by trying to match the word against a noun in the game, ! noting whether the object is something found in sight. objectloop(x) { if (WordInProperty(bpnoun,x,name)) { in_scope = TestScope(x); if (in_scope) { ! uh oh! there's more than one thing in scope of that name! ! this shouldn't happen in the original version. ! But, in fact, MHTO doesn't really worry about this too much; ! it just selects one of the options, unless the options ! are doors. if (matched_scope == 1) { if (matched has door && action == ##Go) "WHICH DIRECTION?"; } matched = x; matched_scope = 1; } if (in_scope == 0 && matched_scope == 0) { matched = x; matched_scope = 0; } } } switch(action) { ##restore: if (bpnoun == 'game') <>; ##save: if (bpnoun == 'game') <>; ##turnonwater: if (bpnoun == 'off') <>; <>; ##Examine: #ifdef TARGET_GLULX; picwin.closeup = 0; #endif; if (bpnoun == 'room' or 'around') <>; if (matched == location) { ! (Total hack here) if (location == Tunnel) "IT IS LONG"; <>; } #ifdef TARGET_GLULX; if (matched && matched provides image && matched.image()) { ! don't do closeups of portable objects if (~~(matched ofclass Note)) picwin.closeup = matched; } #endif; ##Read: #ifdef TARGET_GLULX; if (matched in player && matched ofclass Note) { picwin.closeup = matched; } #endif; ##UnlockEasy, ##Open: ! This is because the disambiguation at this one point ! would get ugly otherwise. if (bpnoun == 'door' or 'doorway' && location == EntryHall) { matched = FrontDoor; } ##Drop: #ifdef TARGET_GLULX; if (matched in player && matched == picwin.closeup) { picwin.closeup = 0; } #endif; ##Go: if (matched && matched hasnt enterable && matched notin compass && matched hasnt door) { "I DONT UNDERSTAND WHAT YOU MEAN"; } switch(bpnoun) { 'u//', 'up', 'climb', 'ascend': <>; 'd//', 'down', 'descend': <>; 'n//', 'north': <>; 'w//', 'west': <>; 's//', 'south': <>; 'e//', 'east': <>; } } ! give error message for the case that the action is known but the ! noun is not if (matched == 0) { print "I DONT KNOW HOW TO "; ReprintWord(1); print " A "; ReprintWord(2); new_line; rtrue; } ! give error message for the case that the noun *is* known, but ! not physically present if (matched && matched_scope == 0) { if (action == ##examine) "THERE IS NOTHING SPECIAL"; else "I DONT SEE IT HERE"; } else { ! we have identified a viable action and its noun; therefore ! perform the action and return true <<(action) matched>>; } rfalse; ]; ! replace the buffer contents with a dummy verb to cancel Inform's ! regularly-scheduled parsing actions [ RemapBuffer i; PrintToBuffer(buffer, 7, "xxxxxxx"); Tokenise__(buffer, parse); ]; [ ReprintWord i j k l m x; i--; #ifdef TARGET_GLULX; j = parse-->(i*2 + 1); #ifnot; ! TARGET_GLULX j = parse-->(i*3 + 1); #endif; ! TARGET_ k = WordAddress(i+1); l = WordLength(i+1); for (m=0 : mm; if (x > 96) x = x - 32; ! force UPPER CASE print (char) x; } ! The original always padded out the verb printing to eight characters. ! To get rid of this (it looks like "I DONT KNOW HOW TO LOOK A MAT") ! remove the last line here ("I DONT KNOW HOW TO LOOK A MAT", instead) for (m=m:m<8:m++) print " "; ]; !============================================================================ ! LIBRARY DEFAULTS !============================================================================ ! Library messages replaces Inform-standard messages with custom Mystery House ! messages. To get back the original Inform message set, simply delete this ! entire object. Object LibraryMessages, with before [ x; Close: switch(lm_n) { 2: if (lm_o has door) print "THE DOOR IS CLOSED^"; <>; default: <>; } Drop: <>; Examine: switch (lm_n) { 2: "THERE IS NOTHING SPECIAL"; default: "I DONT UNDERSTAND WHAT YOU MEAN"; } Go: switch(lm_n) { 1: print "You'll have to get "; if (lm_o has supporter) print "off "; else print "out of "; print_ret (the) lm_o, " first."; 2: "YOU CANT GO IN THAT DIRECTION."; 3, 4, 5: if (lm_o has locked) "IT IS LOCKED"; else "THE DOOR IS CLOSED"; 6: print "You can't, since ", (the) lm_o; if (lm_o has pluralname) " lead nowhere."; else " leads nowhere."; default: "I DONT UNDERSTAND WHAT YOU MEAN"; } Inv: switch(lm_n) { 1: <>; 2: "YOU ARE CARRYING"; } ListMiscellany: rfalse; ! This is unfaithful to MHTO, for the simple ! reason that MHTO avoids listing contents of things for the most ! part -- it just shows you a picture. But instead of going with ! the rather elegant Inform version, we've substituted a ! Scott-Adams-esque list of objects. ! Bracketing in this response indicates that YOU CAN SEE does not ! appear in the original Mystery House. Look: switch(lm_n) { 4,5,6: print "[YOU CAN SEE: "; objectloop(x in lm_o) { if (x hasnt scenery && x hasnt concealed && x ~= player) print (name) x, " "; } print "]^"; rtrue; } Miscellany: switch(lm_n) { 4: "CONGRATULATIONS YOU HAVE BEATEN ADVENTURE AND ARE DECLARED A GURU WIZARD"; ! winning message 5: "WOULD YOU LIKE TO PLAY AGAIN"; 10: "?"; } Open: switch (lm_n) { 2: "IT IS LOCKED"; 3: print "IT IS OPEN^"; <>; 4, 5: <>; ! successful actions are frequently not commented other than ! by redrawing the room image default: "I DONT UNDERSTAND WHAT YOU MEAN"; } Prompt: print "--------------- ENTER COMMAND?"; rtrue; Quit: rtrue; Search: switch (lm_n) { 5: "THE ", (name) lm_o, " IS CLOSED"; 6, 7: print "[IN ", (name) lm_o, ":] "; objectloop(x in lm_o) { print (name) x, " "; } new_line; rtrue; } Sleep: "I FEEL MUCH MORE RESTED NOW"; Take: switch (lm_n) { 1: <>; ! successful actions are frequently not commented other than ! by redrawing the room image 3: "I DONT KNOW WHAT YOU MEAN"; 5: "I DONT SEE IT HERE"; 10: "IT DOES NOT REMOVE"; 11: "IT DOESNT MOVE."; default: "I DONT UNDERSTAND WHAT YOU MEAN"; } Unlock: switch (lm_n) { 3: "YOU HAVE NOTHING TO UNLOCK IT WITH"; 4: "OK"; default: "I DONT UNDERSTAND WHAT YOU MEAN"; } save, restore: rtrue; default: if (deadflag == 0) "I DONT UNDERSTAND WHAT YOU MEAN"; ]; ! To get back standard Inform behavior for any of these, remove both the ! replace command and the subsequent routine of the same name. Replace InvSub; Replace QuitSub; Replace StrongSub; Replace ScoreSub; Replace LookSub; Include "VerbLib"; [ ScoreSub; rfalse; ]; ! Here is another piece of game behavior you may want to rip out -- ! the original MH dumps the player unceremoniously back to the shell ! if he has the folly to use a rude word, without even offering a chance ! to save or restart. [ StrongSub; print "IF YOU FEEL THAT WAY I REFUSE TO PLAY WITH YOU..."; <>; ]; ! Inventory in the original MH is EXTREMELY bare... [ InvSub x; objectloop(x in player) { print (name) x, "^"; } <>; ]; ! With a charming egotism, MH interprets every answer that is not "NO" ! as "YES": of COURSE you would like to play again! [ QuitSub j; parse_exemption = 1; print "WOULD YOU LIKE TO PLAY AGAIN"; if (NotNo() == 0) { print "THANK YOU FOR PLAYING HI-RES ADVENTURE. . . GOOD-BYE"; KeyboardPrimitive(buffer, parse); #ifdef TARGET_ZCODE; if (location == nothing || parent(player) == nothing) read buffer parse; else read buffer parse DrawStatusLine; j = parse->1; #ifnot; ! TARGET_GLULX; KeyboardPrimitive(buffer, parse); j = parse-->0; #endif; ! TARGET_ if (j) { ! player hit return parse_exemption = 0; } quit; } else { parse_exemption = 0; @restart; } ]; [ NotNo i j; for (::) { #ifdef TARGET_ZCODE; if (location == nothing || parent(player) == nothing) read buffer parse; else read buffer parse DrawStatusLine; j = parse->1; #ifnot; ! TARGET_GLULX; KeyboardPrimitive(buffer, parse); j = parse-->0; #endif; ! TARGET_ if (j) { ! at least one word entered i = parse-->1; if (i == NO1__WD or NO2__WD or NO3__WD) rfalse; } rtrue; } ]; ! Finally, MH does not include the name of the room entered. Cutting ! this section and "replace LookSub" above will restore normal Inform ! behavior. [ LookSub allow_abbrev visibility_levels i j k nl_flag; if (parent(player) == 0) return RunTimeError(10); .MovedByInitial; if (location == thedark) { visibility_ceiling = thedark; NoteArrival(); } else { visibility_levels = FindVisibilityLevels(); if (visibility_ceiling == location) { NoteArrival(); if (visibility_ceiling ~= location) jump MovedByInitial; } } ! Printing the top line: e.g. ! Octagonal Room (on the table) (as Frodo) !--- this part is all gone!! --- ! The room description (if visible) if (lookmode < 3 && visibility_ceiling == location) { if ((allow_abbrev ~= 1) || (lookmode == 2) || (location hasnt visited)) { if (location.&describe ~= 0) RunRoutines(location, describe); else { if (location.description == 0) RunTimeError(11, location); else PrintOrRun(location, description); } } } if (visibility_ceiling == location) nl_flag = 1; if (visibility_levels == 0) Locale(thedark); else { for (i=player,j=visibility_levels : j>0: j--,i=parent(i)) give i workflag; for (j=visibility_levels : j>0 : j--) { for (i=player,k=0 : k>; } ], description [; "YOU ARE IN THE FRONT YARD OF A LARGE ABANDONED VICTORIAN HOUSE. STONE STEPS LEAD UP TO A WIDE PORCH"; ], u_to FrontStairs; Object fronttree "TREE" FrontYard, with name "TREE", description [; "THERE IS A FOREST"; ], has picturescenery static; Object FrontStairs "STAIRS", with name "stairs" "steps" "stairway", found_in [; if (location == FrontYard or Porch) rtrue; rfalse; ], before [; climb: if (location == FrontYard) <>; else "I DONT UNDERSTAND WHAT YOU MEAN"; ], door_dir [; if (location == FrontYard) return u_to; return d_to; ], door_to [; if (location == FrontYard) return Porch; return FrontYard; ], has scenery open ~openable door; Room Porch "PORCH", with name "HOUSE", image [; if (FrontDoor has open) return front_door2PIC; return front_door1PIC; ], description [; "YOU ARE ON THE PORCH. STONE STEPS LEAD DOWN TO THE FRONT YARD"; ], d_to FrontStairs, in_to FrontDoor; Object FrontDoor "front door", with found_in EntryHall Porch, name "door" "doorway", door_dir [; if (location == EntryHall) return n_to; else return in_to; ], door_to [; if (location == EntryHall) return Porch; else return EntryHall; ], with_key Skeleton_Key, has scenery openable lockable door; Room EntryHall "ENTRY HALL", with image [; if (people in self) { return entry_hall2PIC; } return entry_hall1PIC; ], initial [; if (self hasnt visited) { give FrontDoor locked; give FrontDoor ~open; "THE DOOR HAS BEEN CLOSED AND LOCKED"; } else { ClearEntry(); } ], description [; "YOU ARE IN AN ENTRY HALL. DOORWAYS GO EAST, WEST AND SOUTH. A STAIRWAY GOES UP"; ], e_to EntryHallLibDoor, w_to EntryHallKitchenDoor, s_to DiningRoom, n_to FrontDoor, u_to EntryHallStairs; Object EntryHallKitchenDoor "front door", with found_in EntryHall Kitchen, name "door" "doorway", door_dir [; if (location == EntryHall) return w_to; else return e_to; ], door_to [; if (location == EntryHall) return Kitchen; else return EntryHall; ], has scenery ~openable open door; Room Library "LIBRARY", with image [; if (SideYardDoor has open) return library2PIC; return library1PIC; ], description [; "YOU ARE IN THE OLD, DUSTY LIBRARY"; ], w_to EntryHallLibDoor, e_to SideYardDoor; Object EntryHallLibDoor "door", with name "door" "doorway", found_in [; if (location == EntryHall or Library) rtrue; rfalse; ], door_dir [; if (location == EntryHall) return e_to; return w_to; ], door_to [; if (location == EntryHall) return Library; return EntryHall; ], has scenery ~openable open door; Object SideYardDoor "door", with name "door" "doorway", found_in [; if (location == SideYard or Library) rtrue; rfalse; ], door_dir [; if (location == SideYard) return w_to; return e_to; ], door_to [; if (location == SideYard) return Library; return SideYard; ], has scenery openable door; Room SideYard "SIDE YARD", with image [; if (SideYardDoor hasnt open) return side_yard2PIC; return side_yard1PIC; ], description [; "YOU ARE IN THE SIDE YARD. YOU CAN FOLLOW THE FENCE TO THE SOUTH"; ], w_to SideYardDoor, s_to BackYard; Room BackYard "BACK YARD", with image [; if (Gate has open) { if (BackYardDoor has open) return back_yard4PIC; return back_yard3PIC; } else { if (BackYardDoor has open) return back_yard2PIC; return back_yard1PIC; } ], description [; "YOU ARE IN THE FENCED BACK YARD. THE FENCE FOLLOWS THE SIDE OF THE HOUSE TO THE NORTH. THERE IS A DEAD BODY HERE"; ], n_to SideYard, nw_to BackYardDoor, e_to Gate; Object Gate "GATE", with name "GATE", found_in BackYard Cemetary, door_dir [; if (location == Cemetary) return w_to; else return e_to; ], door_to [; if (location == BackYard) return Cemetary; else return BackYard; ], has static picturescenery openable door; Room Cemetary "CEMETARY", with image [; if (JoeGravedigger notin location && JoeCorpse in location) { if (Gate hasnt open) { if (shovel has moved) return cemetary3PIC; return cemetary2PIC; } if (shovel hasnt moved) return cemetary5PIC; else return cemetary4PIC; } if (Gate hasnt open) return cemetary6PIC; return CemetaryPIC; ], description [; "YOU ARE IN A SMALL FENCED CEMETARY. THERE ARE SIX NEWLY DUG GRAVES"; ], w_to Gate; Room Kitchen "KITCHEN", with image [ x; ! This picture has five variables: the openness of the door, ! fridge, and cabinet, whether or not the cabinet is ! pushed out, and whether the hole has been made. ! Since nested if-statements would be a pain with so many ! options, we use a slightly different approach. if (Kitchen_Door has open) x = x + 1; if (cabinet has general) x = x + 2; if (cabinet has open) x = x + 4; if (refrigerator has open) x = x + 8; if (Hole_Kitchen in Kitchen) x = x + 16; switch(x) { 0: return Kitchen1PIC; ! everything is where it starts 1: return kitchen3PIC; ! door open, everything else closed 2: return Kitchen2PIC; ! cabinet moved, everything closed 3: return kitchen16PIC; ! door open, cabinet moved, everything else closed 4: return kitchen4PIC; ! cabinet open, everything else closed 5: return kitchen8PIC; ! cabinet open and door open 6: return kitchen17PIC; ! cabinet open and moved 7: return kitchen12PIC; ! cabinet open and moved, door open 8: return kitchen5PIC; ! refrigerator open, all else closed 9: return kitchen6PIC; ! fridge and door open 10: return kitchen14PIC; ! fridge open and cabinet moved 11: return kitchen13PIC; ! fridge open, cabinet moved, door open 12: return kitchen7PIC; ! fridge open, cabinet open 13: return kitchen9PIC; ! fridge open, cabinet open, door open 14: return kitchen11PIC; ! fridge open, cabinet open, cabinet moved 15: return kitchen10PIC; ! all open, cabinet moved 18: return kitchen19PIC; ! hole in wall, cab moved, all else closed 19: return kitchen20PIC; ! hole in wall, cab moved, door open 22: return kitchen21PIC; ! hole in wall, cab moved, cab open 23: return kitchen18PIC; ! hole in wall, cab moved, door open, cab open 26: return kitchen22PIC; ! hole in wall, cab moved, fridge open 27: return kitchen23PIC; ! hole in wall, cab moved, fridge open, door open 30: return kitchen24PIC; ! hole in wall, everything open but door 31: return kitchen15PIC; ! hole in wall, everything open } ! A completely different, and perhaps saner, way to handle this ! problem would be to divide the room image into sections and ! draw piecemeal. We did not do that in this case, though, because ! it would have forced all contributors to use exactly the same ! proportions in their images. ], description [; "YOU ARE IN THE KITCHEN. THERE IS A REFRIGERATOR, STOVE AND CABINET"; ], in_to [; if (Hole_Kitchen in Kitchen) return Hole_Kitchen; rfalse; ], w_to Kitchen_Door, e_to EntryHallKitchenDoor; Object Kitchen_Door "DOOR (WEST)", with short_name [; if (location == Kitchen) print "DOOR (WEST)"; else print "DOOR (UP)"; rtrue; ], name "DOOR" "DOORWAY", found_in Kitchen Forest_1, door_to [; if (location == Kitchen) return Forest_1; return Kitchen; ], door_dir [; if (location == Forest_1) return u_to; return w_to; ], react_before [; go: if (noun == u_obj && location == Forest_1 && self hasnt open) { "THE KITCHEN DOOR IS CLOSED"; } ], before [; enter: if (self hasnt open && location == Forest_1) "THE KITCHEN DOOR IS CLOSED"; ], after [; open: if (location == Forest_1) "THE KITCHEN DOOR IS OPEN"; ], has static picturescenery door openable ~open; Room DiningRoom "DINING ROOM", with number 0, image [; if (CandleUnlit hasnt moved) { if (BackYardDoor has open) return dining_room3PIC; return dining_room1PIC; } else { if (Fire in DiningRoom) { if (BackYardDoor has open) return dining_room5PIC; else return dining_room6PIC; } if (Hole in DiningRoom) { if (BackYardDoor has open) return dining_room8PIC; return dining_room7PIC; } if (BackYardDoor has open) return dining_room4PIC; return dining_room2; } ], before [; if (CandleLit in player && self hasnt general) { if (self.number == 1) { self.number = 2; rfalse; } give self general; StartDaemon(fire); move Fire to location; "YOU TRIP OVER RUG AND FALL. OH,OH, YOU STARTED A FIRE WITH YOUR CANDLE!"; } ], description [; "YOU ARE IN THE DINING ROOM"; ], n_to EntryHall, S_to BackYardDoor; Object BackYardDoor "DOOR", with name "door" "doorway", found_in [; if (location == BackYard or DiningRoom) rtrue; rfalse; ], door_dir [; if (location == BackYard) return nw_to; return S_to; ], door_to [; if (location == BackYard) return DiningRoom; return BackYard; ], has static picturescenery openable door; !============================================================================ ! Upstairs area Room Junction "JUNCTION", with image [; return junctionPIC; ], description [; "YOU ARE AT THE JUNCTION OF AN EAST/WEST HALLWAY AND A NORTH/SOUTH HALLWAY"; ], d_to EntryHallStairs, e_to Doorway_3, w_to Doorway_1, n_to Stairway_1; Object EntryHallStairs "STAIRS", with found_in Junction EntryHall, name "stairs" "steps" "stairway", before [; climb: if (location == EntryHall) <>; else "I DONT UNDERSTAND WHAT YOU MEAN"; ], door_dir [; if (location == Junction) return d_to; return u_to; ], door_to [; if (location == Junction) return EntryHall; return Junction; ], has scenery open ~openable door; Room Doorway_1 "DOORWAY", with image [; return doorwayPIC; ], description [; "THERE IS A DOORWAY HERE"; ], e_to Junction, w_to Doorway_2, n_to NurseryDoor; Object NurseryDoor "DOOR", with name "door" "doorway", found_in [; if (location == Nursery or Doorway_1) rtrue; rfalse; ], door_dir [; if (location == Nursery) return s_to; return n_to; ], door_to [; if (location == Nursery) return Doorway_1; return Nursery; ], has scenery ~openable open door; Room Nursery "NURSERY", with image [; return nurseryPIC; ], description [; "YOU ARE IN AN OLD NURSERY. THERE IS A DEAD BODY HERE"; ], s_to Doorway_1; Room Doorway_2 "DOORWAY", with image [; return doorwayPIC; ], description [; "THERE IS A DOORWAY HERE"; ], e_to Doorway_1, n_to BoysBedroomDoor; Object BoysBedroomDoor "door", with name "door" "doorway", found_in [; if (location == BoysBedroom or Doorway_2) rtrue; rfalse; ], door_dir [; if (location == BoysBedroom) return s_to; return n_to; ], door_to [; if (location == BoysBedroom) return Doorway_2; return BoysBedroom; ], has scenery ~openable open door; Room BoysBedroom "BOYS BEDROOM", with image [; ! includes NOTE return boys_bedroomPIC; ], description [; "YOU ARE IN A BOYS BEDROOM"; ], s_to Doorway_2; Room Doorway_3 "DOORWAY", with image [; return doorwayPIC; ], description [; "THERE IS A DOORWAY HERE"; ], w_to Junction, e_to Doorway_4, n_to LargeBedroomDoor; Object LargeBedroomDoor "DOOR", with name "door" "doorway", found_in [; if (location == LargeBedroom or Doorway_3) rtrue; rfalse; ], door_dir [; if (location == LargeBedroom) return s_to; return n_to; ], door_to [; if (location == LargeBedroom) return Doorway_3; return LargeBedroom; ], has scenery ~openable open door; Room LargeBedroom "LARGE BEDROOM", with image [; if (dagger has moved) return large_bedroom2PIC; return large_bedroom1PIC; ], initial [; if (self hasnt visited) { move dagger to self; "A DAGGER IS THROWN AT YOU FROM OUTSIDE THE ROOM. IT MISSES!"; } ], description [; "YOU ARE IN A LARGE BEDROOM"; ], s_to Doorway_3; Room Doorway_4 "DOORWAY", with image [; return doorwayPIC; ], description [; "THERE IS A DOORWAY HERE"; ], w_to Doorway_3, n_to SmallBedroomDoor; Object SmallBedroomDoor "door", with name "door" "doorway", found_in [; if (location == SmallBedroom or Doorway_4) rtrue; rfalse; ], door_dir [; if (location == SmallBedroom) return s_to; return n_to; ], door_to [; if (location == SmallBedroom) return Doorway_4; return SmallBedroom; ], has scenery ~openable open door; Room SmallBedroom "SMALL BEDROOM", with image [; return small_bedroomPIC; ], description [; "YOU ARE IN A SMALL BEDROOM. THERE IS A DEAD BODY HERE"; ], s_to Doorway_4; Room Stairway_1 "STAIRWAY", with image [; return at_stairwayPIC; ], description [; "YOU ARE AT A STAIRWAY"; ], s_to Junction, u_to AtticStairs, n_to Doorway_5; Object AtticStairs "STAIRS", with found_in Attic Stairway_1, name "stairs" "steps" "stairway", before [; climb: if (location == Stairway_1) <>; else "I DONT UNDERSTAND WHAT YOU MEAN"; ], door_dir [; if (location == Attic) return d_to; return u_to; ], door_to [; if (location == Attic) return Stairway_1; return Attic; ], has static picturescenery open ~openable door; Room Doorway_5 "DOORWAY", with image [; return doorwayPIC; ], description [; "THERE IS A DOORWAY HERE"; ], s_to Stairway_1, in_to StudyDoor; Object StudyDoor "door", with name "door" "doorway", found_in [; if (location == Study or Doorway_5) rtrue; rfalse; ], door_dir [; if (location == Study) return out_to; return in_to; ], door_to [; if (location == Study) return Doorway_5; return Study; ], has scenery ~openable open door; Room Study "STUDY", with image [; if (SecretDoor in location) return study2PIC; if (button in location) return study3PIC; return study1PIC; ], description [; "YOU ARE IN THE STUDY"; ], ne_to [; if (SecretDoor in location) return SecretDoor; rfalse; ], e_to BathroomDoor, n_to Doorway_5; Room Bathroom "BATHROOM", with image [; if (towel hasnt moved) return bathroom1PIC; return bathroom2PIC; ], description [; "YOU ARE IN THE BATHROOM. THERE IS A DEAD BODY HERE."; ], w_to BathroomDoor; Object BathroomDoor "DOOR", with name "door" "doorway", found_in [; if (location == Study or Bathroom) rtrue; rfalse; ], door_dir [; if (location == Study) return e_to; return w_to; ], door_to [; if (location == Study) return Bathroom; return Study; ], has open ~openable static picturescenery door; Room StorageRoom "STORAGE ROOM", with image [; if (trunk has open) return storage_room2PIC; return storage_room1PIC; ], description [; "YOU ARE IN A STORAGE ROOM"; ], w_to StorageRoomDoor; Object StorageRoomDoor "door", with name "door" "doorway", found_in [; if (location == StorageRoom or Attic) rtrue; rfalse; ], door_dir [; if (location == StorageRoom) return w_to; return e_to; ], door_to [; if (location == StorageRoom) return Attic; return StorageRoom; ], has door ~openable scenery open; Room Attic "ATTIC", with image [; ! actually, we should have a third picture here for the present ! but closed trap door if (trapdoor hasnt concealed) { if (trapdoor has open) { if (hammer hasnt moved) return attic5PIC; else return attic4PIC; } else { if (hammer hasnt moved) return attic6PIC; else return attic3PIC; } } else { if (hammer hasnt moved) return attic1PIC; return attic2PIC; } ], description [; "YOU ARE IN THE ATTIC"; ], d_to AtticStairs, e_to StorageRoomDoor, u_to trapdoor; Object trapdoor "TRAPDOOR", with name "trapdoor", before [; default: if (self has concealed) "WHAT TRAPDOOR?"; ], found_in [; if (location == Attic or Tower) rtrue; rfalse; ], door_dir [; if (location == Attic) return u_to; return d_to; ], door_to [; if (location == Attic) return Tower; return Attic; ], has door openable static picturescenery concealed; Room Tower "TOWER", with image [; return towerPIC; ], initial [; if (Daisy hasnt general && Daisy in Tower) { StartDaemon(Daisy); } ], description [; "YOU ARE IN THE TOWER"; ], d_to trapdoor; !============================================================================ ! Tunnel and tree Room PineTreeTop "TOP OF A VERY TALL PINE TREE", with image [; return treetopPIC; ], description [; "YOU ARE AT THE TOP OF A VERY TALL PINE TREE"; ], before [; go: if (noun == Porch) ! equivalent to >GO HOUSE { "YOU HAD BETTER CLIMB DOWN FIRST"; } ], d_to PineTreeBase; Room PineTreeBase "BASE OF A VERY TALL PINE TREE", with image [; return treePIC; ], description [; "THERE IS A VERY TALL PINE TREE IN FRONT OF YOU"; ], u_to PineTreeTop, d_to Forest_5, s_to Tunnel; Room Tunnel "TUNNEL", with name "TUNNEL", image [; return tunnelPIC; ], description [; "YOU ARE AT THE SOUTH END OF A NORTH/SOUTH TUNNEL"; ], n_to PineTreeBase, out_to Hole_Basement; !============================================================================ ! Forest Maze Class ForestRoom, class room, with short_name "FOREST", image [; return ForestPIC; ], description [; "YOU ARE IN A FOREST"; ]; ForestRoom Forest_1, with u_to Kitchen_Door, n_to Forest_2, s_to Forest_4, e_to Forest_8, w_to Forest_6; ForestRoom Forest_2, with n_to Forest_3, s_to Forest_2, e_to Forest_1, w_to Forest_2; ForestRoom Forest_3, with n_to Forest_4, s_to Forest_3, e_to Forest_2; ForestRoom Forest_4, with n_to Forest_5, s_to Forest_7, e_to Forest_3, w_to Forest_1; ForestRoom Forest_5, with n_to Forest_6, s_to Forest_5, e_to Forest_4, w_to Forest_8; ForestRoom Forest_6, with n_to Forest_7, s_to Forest_1, e_to Forest_5, w_to Forest_8; ForestRoom Forest_7, with n_to Forest_8, s_to Forest_7, e_to Forest_6, w_to Forest_4; ForestRoom Forest_8, with n_to Forest_1, s_to Forest_6, e_to Forest_7, w_to Forest_5; !============================================================================ ! Basement and pantry area Room SmallPantry "SMALL PANTRY", with image [; return pantryPIC; ], description [; "YOU ARE IN A SMALL PANTRY"; ], in_to Hole_Pantry, d_to PassageStairs; Object PassageStairs "STAIRS", with name "STAIRS" "STEPS" "STAIRWAY", before [; climb: if (location == Passage) <>; else "I DONT UNDERSTAND WHAT YOU MEAN"; ], found_in [; if (location == SmallPantry or Passage) rtrue; rfalse; ], door_dir [; if (location == Passage) return u_to; return d_to; ], door_to [; if (location == Passage) return SmallPantry; return Passage; ], has open ~openable door scenery; Room Passage "PASSAGE", with image [; return passagewayPIC; ], description [; "YOU ARE AT THE NORTH END OF A NARROW NORTH/SOUTH PASSAGEWAY"; ], u_to PassageStairs, s_to MoistBasement; Room MoistBasement "MOIST BASEMENT", with image [ x; if (Algae hasnt general) { if (Skeleton_Key has moved) return basement8PIC; else return basement1PIC; } if (Brick in Moistbasement && Brick hasnt general) { if (Skeleton_Key has moved) return basement2PIC; else return basement3PIC; } if (Jewels has moved) { if (Skeleton_Key has moved) return basement7PIC; else return basement6PIC; } if (Brick has general) { if (Skeleton_Key has moved) return basement5PIC ; else return basement4PIC; } ], description [; print "YOU ARE IN A MOIST BASEMENT. "; if (Algae in location) print "ALGAE COVERS THE WALLS. "; "THERE IS A DEAD BODY HERE."; ], n_to Passage, in_to Hole_Basement, u_to MoistStairs; Object MoistStairs "STAIRS", with name "steps" "stairs" "stairway", before [; climb: if (location == MoistBasement) <>; else "I DONT UNDERSTAND WHAT YOU MEAN"; ], found_in [; if (location == Stairway_2 or MoistBasement) rtrue; rfalse; ], door_to [; if (location == Stairway_2) return MoistBasement; return Stairway_2; ], door_dir [; if (location == Stairway_2) return d_to; return u_to; ], has door open ~openable scenery; Room Stairway_2 "STAIRWAY", with image [; return on_stairwayPIC; ], description [; "YOU ARE ON A STAIRWAY"; ], u_to MustyStairs, d_to MoistStairs; Room MustyCrawlspace "MUSTY CRAWLSPACE", with image [; return crawlspacePIC; ], description [; "YOU ARE IN A MUSTY CRAWLSPACE"; ], d_to MustyStairs; Object MustyStairs "STAIRS", with name "steps" "stairs" "stairway", before [; climb: if (location == Stairway_2) <>; else "I DONT UNDERSTAND WHAT YOU MEAN"; ], found_in [; if (location == MustyCrawlspace or Stairway_2) rtrue; rfalse; ], door_to [; if (location == MustyCrawlspace) return Stairway_2; return MustyCrawlspace; ], door_dir [; if (location == MustyCrawlspace) return d_to; return u_to; ], has door open ~openable scenery; !============================================================================ ! Objects ! ! Objects except for the stairs (which are listed in place as though they were ! doors) are implemented in the same order in which they appear on the MHOK ! list, with the same names (or as close as Inform will accept). Class Note, with name "NOTE" "MEMO" "LETTER" "PAPER", sprite [; return note_itemPIC; ], description [; if (self notin player) "IM NOT CARRYING THAT"; "THERE IS WRITING ON IT"; ]; Note Note_1 "NOTE" EntryHall, with image [; return note1PIC; ], text [; "VALUABLE JEWELS ARE HIDDEN IN THIS HOUSE. FINDERS-KEEPERS."; ]; Note Note_2 "NOTE" Library, with image [; return note2PIC; ], text [; "7 - 6 = 1. THEN I AM DONE!"; ]; Note Note_3 "NOTE" BoysBedroom, with image [; return note3PIC; ], text [; "YOU WILL NEVER FIND IT! IT'S ALL MINE!!"; ]; Note Note_4 "NOTE" Tower, with image [; return note4PIC; ], text [; "IT'S IN THE BASEMENT!"; ]; Object WelcomeMat "WELCOME MAT" Porch, with name "WELCOME", ! 'mat' is not listed in the original has static picturescenery; Object CandleUnlit "UNLIT CANDLE" DiningRoom, with name "CANDLE", sprite [; return candle_itemPIC; ], before [; burn: if (self notin player) "YOU DONT HAVE IT"; if (~~(IndirectlyContains(player, matches))) "YOU HAVE NOTHING TO LIGHT IT WITH"; else { remove self; ! This is a hacky device to prevent the dining room from ! catching fire at the very first moment that you light ! the candle. if (location == DiningRoom) DiningRoom.number = 1; move CandleLit to player; "OK"; } ]; Object CandleLit "LIT CANDLE", with name "CANDLE", sprite [; return candle_itemPIC; ], has light; Object Fire "FIRE", with name "FIRE", number 0, death_by_fire [; print "THE FIRE IS OUT OF CONTROL. YOU ARE DEAD^"; <>; ], before [; examine: self.death_by_fire(); rtrue; ], react_before [; go: self.death_by_fire(); rtrue; pour: if (noun == JugFull) { StopDaemon(self); remove self; remove JugFull; move JugEmpty to player; move Hole to location; print "THE FIRE IS OUT^THE PITCHER IS EMPTY^"; <>; } ], daemon [; ! nothing happens until you go to the dining room with the lit candle ! or try to move when you have it lit there if (location ~= DiningRoom) rfalse; self.number++; if (self in location && self.number > FIRE_DURATION) { self.death_by_fire(); rtrue; } ], has scenery; Object Cabinet "CABINET" Kitchen, with name "CABINET" "CUPBOARD", image [; if (self hasnt open) rfalse; if (matches notin self) return cabinet2PIC; return cabinet1PIC; ], description [; if (self has open) <>; "IT IS UNLOCKED"; ], before [; take: "IT'S TOO HEAVY TO LIFT"; push: if (self has general) { "IT WON'T MOVE ANY FARTHER"; } else { give self general; "THE WALL IS BRICKED UP BEHIND IT"; } ], has container openable scenery; Object Wall "wall" Kitchen, with name "wall", before [; attack: if (Hammer notin player) { "YOU HAVE NOTHING STRONG ENOUGH"; } else { move Hole_Kitchen to location; give Hole_Pantry open; "THE BRICKS BREAK APART LEAVING A LARGE HOLE"; } ], has scenery; Object Hole_Kitchen "HOLE", with name "HOLE", door_to SmallPantry, door_dir in_to, has door open ~openable static picturescenery; ! Unlike the candle, the matches don't change their description when you ! happen to have a lit one, nor are they implemented as two separate objects. Object Matches "MATCHES" Cabinet, with name "MATCHES" "MATCH", number 0, sprite [; return matches_itemPIC; ], before [; burn: ! NB. that this code restarts the fuse if you light ! an already-lit match. This is true to the original. self.number = 0; give self light; StartDaemon(self); "OK"; ], daemon [; self.number++; if (self.number == MATCH_DURATION) { give self ~light; StopDaemon(self); "THE MATCH WENT OUT"; } ], has pluralname; Object Stove "stove" Kitchen, with name "STOVE" "RANGE" "PORCH", before [; burn: print "THE STOVE EXPLODES, YOU ARE DEAD^"; <>; ], has scenery; Object Refrigerator "REFRIGERATOR" Kitchen, with name "REFRIGERA" "FRIDGE" "ICEBOX" "REFRIDGE", image [; if (self hasnt open) rfalse; if (JugEmpty in self) return refrigerator1PIC; else return refrigerator2PIC; ], has scenery container openable; Object JugEmpty "EMPTY PITCHER" Refrigerator, with name "PITCHER", article "AN", sprite [; return pitcher1_itemPIC; ]; Object JugFull "PITCHER FULL OF WATER", with name "PITCHER" "WATER", sprite [; return pitcher2_itemPIC; ], before [; drink: remove self; move JugEmpty to player; "OK"; ]; Object Sink "SINK" Kitchen, with name "SINK" "FAUCET" "TAP", image [; if (Butterknife in self) return sink1PIC; return sink2PIC; ], description [; if (Butterknife in self) "THERE IS A BUTTERKNIFE HERE"; else rfalse; ], has container open ~openable scenery; Object Butterknife "BUTTERKNIFE" Sink, with name "BUTTERKNI", sprite [; return butterknife_itemPIC; ], before [; use: ! The original game makes no distinction in answer if the ! picture has already been loosened if (picture in location) { give picture general; "THE PICTURE IS LOOSE"; } ]; Object Water "water", with name "water" "LIQUID", article "some", before [; take: if (JugEmpty notin player) "YOU HAVE NO CONTAINER"; else { remove JugEmpty; move JugFull to player; "YOUR PITCHER IS FULL"; } drink: "OK"; pour: if (JugFull notin Player) "I SEE NO WATER"; remove JugFull; move JugEmpty to player; "THE PITCHER IS EMPTY"; ], has edible; Object Hole "HOLE", ! The hole in the carpet with name "hole", image [; if (small_key in self) return hole1PIC; return hole2PIC; ], has container open ~openable; ! Appears in the hole in the carpet, and opens the chest with the gun ! in it. Object Small_Key "SMALL KEY" Hole, with name "key", sprite [; return key_itemPIC; ]; Object Skeleton_Key "SKELETON KEY" MoistBasement, with name "key", sprite [; return skeletonkey_itemPIC; ], initial [; "THERE IS A SKELETON KEY HERE"; ]; ! will be thrown at you in the large bedroom Object Dagger "DAGGER", with name "DAGGER", sprite [; return dagger_itemPIC; ], before [; use: if (location == Tower) { if (Daisy hasnt general) { print "DAISY STABBED YOU. YOU ARE DEAD^"; <>; } else { "DAISY IS ALREADY DEAD"; } } ]; Object Towel "TOWEL" Bathroom, with name "TOWEL" "CLOTH", sprite [; return towel_itemPIC; ]; ! using the butterknife on the picture will loosen it, ! allowing you to take it Object Picture "PICTURE" Study, with name "PICTURE" "PORTRAIT" "BOLTS", sprite [; return picture_itemPIC; ], description [; "ITS NICE BUT NOT EXACTLY MY CUP OF TEA. THANX FOR THE LOOK THOUGH."; ], before [; loosen: "WITH WHAT?"; take: if (self hasnt general) { print "IT IS FASTENED TO THE WALL WITH FOUR BOLTS^"; rtrue; } else { give self ~scenery; rfalse; } ], after [; take: move Button to location; "THERE IS A BUTTON ON THE WALL"; ], has picturescenery; ! hidden behind picture Object Button "BUTTON", with name "BUTTON" "KNOB", before [; push: move SecretDoor to location; give SecretDoor open; give SecretDoor ~absent; "PART OF THE WALL OPENS"; ], has scenery; Object SecretDoor "WALL", with name "WALL", found_in MustyCrawlspace Study, door_to [; if (location == Study) return MustyCrawlspace; return Study; ], door_dir [; if (location == Study) return ne_to; return s_to; ], react_before [; enter: if (noun == self && location == Study && self hasnt general) { give self general; print "THE WALL CLOSES BEHIND YOU WITH A BANG^"; } go: if (location == Study && self hasnt general && noun == ne_obj or self) { give self general; print "THE WALL CLOSES BEHIND YOU WITH A BANG^"; } ], before [; open: if (location == MustyCrawlspace) "IT WON'T OPEN"; ], react_after [; go: if (self has general) { give self ~open absent; remove self; rfalse; } ], has door open ~openable absent; Object Hammer "SLEDGEHAMMER" Attic, with name "HAMMER" "SLEDGEHAM", sprite [; return sledgehammer_itemPIC; ], has picturescenery; Object Ladder "LADDER" Attic, with name "LADDER", before [; climb: if (location == Attic) { if (trapdoor has concealed) "YOU CLIMB UP BUMP YOUR HEAD ON THE CEILING AND FALL, DAZED BUT ALIVE."; else <>; } ], has static picturescenery; Object Tree "TREE" PineTreeBase, with name "tree" "trees", before [; climb: <>; ], has scenery; Object Telescope "TELESCOPE" PineTreeTop, with name "telescope", image [; ! trapdoor as seen through telescope return trapdoorPIC; ], description [; give trapdoor ~concealed; "YOU ARE LOOKING THROUGH THE ATTIC WINDOW. YOU SEE A TRAPDOOR IN THE ATTIC CEILING"; ], before [; ! this will only be interesting if the MH two-word parser is TURNED ! OFF. Otherwise LOOK TELESCOPE is the only viable command anyway. ! This accounts for LOOK THROUGH as well. search: <>; ], has static picturescenery; Object Algae "algae" MoistBasement, with name "algae", before [; rub: ! If the player doesn't have the towel, refuse if (IndirectlyContains(player, towel) == 0) "YOU HAVE NOTHING TO WIPE IT WITH"; if (self has general) rfalse; ! don't do this more than once give self general; move Brick to MoistBasement; ! reveal the brick "THE WALL IS EXPOSED. THERE IS A LOOSE BRICK"; ], has scenery; Object Hole_Basement "HOLE" MoistBasement, with name "hole", found_in [; if (location == MoistBasement or Tunnel) rtrue; rfalse; ], door_to [; if (location == MoistBasement) return Tunnel; return MoistBasement; ], door_dir [; if (location == MoistBasement) return in_to; return out_to; ], has static picturescenery door open ~openable; ! visible only after you have moved the algae Object Brick "BRICK", with name "BRICKS" "BRICK", sprite [; return Brick_itemPIC; ], description [; "IT IS LOOSE"; ], after [; take: if (self has general) rfalse; ! don't do this more than once give self general; move Jewels to MoistBasement; "YOU HAVE FOUND THE JEWELS!"; ]; ! visible only after you have moved the algae Object Jewels "JEWELS", with name "JEWELS" "GEMS" "TREASURE" "DIAMONDS", sprite [; return jewels_itemPIC; ], description [; "THEY ARE JEWELS, ALL RIGHT!"; ], has pluralname; Object Shovel "SHOVEL" cemetary, with name "SHOVEL" "SPADE", sprite [; return shovel_itemPIC; ]; Object Trunk "TRUNK" StorageRoom, with name "TRUNK" "CHEST", image [; if (gun in self) return chest1PIC; return chest2PIC; ], with_key Small_Key, has static picturescenery container openable lockable locked; Object Gun "GUN" Trunk, with name "GUN" "PISTOL", number AMMUNITION, sprite [; return gun_itemPIC; ], description [; ! NB: this is a bug preserved from the original game. Even when ! the gun has been shot, it is described as containing one bullet. "THERE IS ONE BULLET IN THE GUN"; ], before [; ! Trying to shoot the gun when you don't have it gives you ! YOU ARE NOT CARRYING IT shoot, use: if (self.number > 0) { self.number--; if (Daisy in Tower && location == Tower) { give Daisy general; if (self.number == 0) print "YOUR GUN IS EMPTY^"; "DAISY IS NOW DEAD"; } if (JoeGravedigger in location && location == Cemetary) { remove JoeGravedigger; move JoeCorpse to location; print "THERE IS A DEAD BODY HERE^"; if (self.number == 0) "YOUR GUN IS EMPTY"; else { new_line; rtrue; } } if (self.number == 0) "YOUR GUN IS NOW EMPTY"; } else { if (Daisy in location && location == Tower && Daisy has general) { "DAISY IS ALREADY DEAD"; } "YOUR GUN IS EMPTY"; } ]; !-- SOME additional scenery not on the original list Object Books "BOOKS" Library, with name "books", has static picturescenery; Object Shelves "SHELVES" Library, with name "SHELVES" "BOOKSHELF" "BOOKSHELV", description [; "THERE ARE NOT MANY BOOKS LEFT"; ], has static picturescenery; Object Sofa "SOFA" Library, with name "COUCH" "SOFA" "DAVENPOR" "DIVAN", has static picturescenery; Object Fireplace "FIREPLACE" Library, with name "FIREPLACE" "CHIMNEY", has static picturescenery; Object Fence "FENCE", with name "fence", found_in SideYard BackYard, before [; climb: "IT IS TOO HIGH"; ], has scenery; Object Grave "GRAVES" Cemetary, with name "GRAVES" "GRAVE", before [; go: ! Joe intervenes if he's around if (TestScope(JoeGravedigger)) { print "YOU FALL IN ONE AND JOE BURIES YOU. YOU ARE DEAD^"; <>; } "YOU FALL IN ONE AND CLIMB OUT AGAIN"; ], has container enterable static picturescenery; Object Tombstone "TOMBSTONE" Cemetary, with name "GRAVESTONE" "TOMBSTONE", description [; "THE WRITING IS WORN DOWN"; ], text [; <>; ], has static picturescenery; Object Lamp "LAMP" DiningRoom, with name "LAMP", before [; take: "IT IS FASTENED DOWN"; burn: "THERE IS NO WICK"; ], has static picturescenery; Object Rug "RUG" DiningRoom, with name "RUG" "CARPET", has scenery picturescenery; Object Rocker "ROCKER" Nursery, with name "ROCKER" "CHAIR", has static picturescenery; Object Crib "CRIB" Nursery, with name "CRADLE" "CRIB", has static picturescenery; ! Many of the objects in the bedrooms -- cabinets, beds, etc -- appear to ! be implemented effectively as a single object which can be (minimally) ! viewed from all bedrooms. The Inform implementation treats each as its own ! object in order to allow the author more room for customization of the ! furnishings. Object NurseryCabinet "CABINET" Nursery, with name "CABINET" "CUPBOARD" "DRAWERS", has static picturescenery; Object BoyBed "BED" BoysBedroom, with name "BED" "MATTRESS", has static picturescenery; Object BoyCabinet "CABINET" BoysBedroom, with name "CABINET" "CUPBOARD" "DRAWERS", has static picturescenery; Object BoyDesk "DESK" BoysBedroom, with name "DESK" "TABLE", has scenery picturescenery; Object LargeBed "BED" LargeBedroom, with name "BED" "MATTRESS", has static picturescenery; Object LargeCabinet "CABINET" LargeBedroom, with name "CABINET" "CUPBOARD" "DRAWERS", has static picturescenery; Object LargeDesk "DESK" LargeBedroom, with name "DESK" "TABLE", has scenery picturescenery; Object SmallBed "BED" SmallBedroom, with name "BED" "MATTRESS", has static picturescenery; Object SmallCabinet "CABINET" SmallBedroom, with name "CABINET" "CUPBOARD" "DRAWERS", has static picturescenery; Object SmallDesk "DESK" SmallBedroom, with name "DESK" "TABLE", has scenery picturescenery; Object OutsideWindows "WINDOW" FrontYard, with name "WINDOW", found_in FrontYard BoysBedroom SmallBedroom Tower, description [; "WINDOWS ARE BOARDED UP EXCEPT THE ATTIC WINDOW"; ], before [; go: self.description(); rtrue; ], has enterable scenery picturescenery; Object AtticWindow "WINDOW" Attic, with name "WINDOW", description [; "YOU SEE A FOREST"; ], before [; go: print "YOU FALL TO EARTH. LUCKILY YOU HAVE ONLY MINOR INJURIES.^ UNFORTUNATELY THE AMBULANCE DRIVER SMASHS INTO A VOLKWAGEN. NO SURVIVORS.^YOU ARE DEAD.^"; <>; ], has enterable static picturescenery; Object boxes "BOX" StorageRoom, with name "BOXES" "BOX", has static picturescenery; Object StudyDesk "DESK" Study, with name "DESK" "TABLE", has static picturescenery; Object StudyChair "CHAIR" Study, with name "CHAIR", has static picturescenery; Object Hole_Pantry "HOLE" SmallPantry, with name "hole", react_before [; go: if ((noun == in_to || noun == self) && self hasnt open) "YOU GO IN THE HOLE BUT CANNOT CONTINUE AND HAVE TO RETURN."; enter: if (noun == self && self hasnt open) "YOU GO IN THE HOLE BUT CANNOT CONTINUE AND HAVE TO RETURN."; ], door_dir in_to, door_to Kitchen, has door static ~openable ~open picturescenery; Object Toilet "TOILET" Bathroom, with name "TOILET" "POTTY" "JOHN", before [; flush: "OK"; ], has static picturescenery; Object Shower "SHOWER" Bathroom, with name "SHOWER", before [; take: "THANK YOU. I LOVE TO FEEL CLEAN. THATS MUCH BETTER."; ], has static picturescenery; Object BathroomSink "SINK" Bathroom, with name "SINK" "FAUCET" "TAP", after [; switchon: move BathroomWater to self; "WATER IS RUNNING INTO THE SINK"; switchoff: if (BathroomWater in self) remove water; "OK"; ], has switchable container open ~openable static picturescenery; Object BathroomWater "WATER", with name "WATER" "LIQUID", article "some", before [; take: if (JugEmpty notin player) "YOU HAVE NO CONTAINER"; else { remove JugEmpty; move JugFull to player; "YOUR PITCHER IS FULL"; } drink: "OK"; pour: if (JugFull notin Player) "I SEE NO WATER"; remove JugFull; move JugEmpty to player; "THE PITCHER IS EMPTY"; ], has edible; !============================================================================ ! The NPCs Object People EntryHall, with name "people", description [; "THE PEOPLE WERE EXPLAINED AT THE BEGINNING OF THE GAME."; ], has scenery picturescenery; NPC Tom "TOM" EntryHall, with name "Tom", has male; Corpse TomCorpse "Tom's body" MoistBasement, with description [; "IT IS TOM, THE PLUMBER. HE SEEMS TO HAVE BEEN STABBED. THERE IS A DAISY IN HIS HAND"; ]; ! Held by Tom's corpse Object flower "DAISY" MoistBasement, with name "FLOWER" "DAISY", has scenery; NPC Sam "SAM" EntryHall, with name "Sam", has male; Corpse SamCorpse "Sam's body" BackYard, with description [; "IT IS SAM, THE MECHANIC. HE HAS BEEN HIT IN THE HEAD BY A BLUNT OBJECT"; ]; NPC Sally "SALLY" EntryHall, with name "Sally", has female; Corpse SallyCorpse "Sally's body" SmallBedroom, with description [; "IT IS SALLY, THE SEAMSTRESS. SHE HAS A LARGE LUMP ON HER HEAD. THERE IS A BLOND HAIR ON HER DRESS"; ]; NPC DrGreen "DR. GREEN" EntryHall, with name "dr" "green" "doctor", has male; Corpse GreenCorpse "Dr. Green's body" Nursery, with description [; "IT IS DR. GREEN. IT APPEARS HE HAS BEEN STABBED"; ]; NPC Joe "JOE" EntryHall, with name "Joe", has male; NPC JoeGravedigger "JOE" Cemetary, with name "Joe", description [; "IT IS JOE, THE GRAVEDIGGER. HE HAS JUST FINISHED DIGGING THE SIX GRAVES"; ], react_before [; take: if (noun == shovel) "JOE WON'T LET YOU"; ], before [; ask, tell, answer: "HE DOESN'T TALK MUCH"; ], life [; attack: "WITH WHAT?"; ]; Corpse JoeCorpse "Joe's body", with description [; "IT IS JOE, THE GRAVEDIGGER"; ]; NPC Bill "BILL" EntryHall, with name "Bill", has male; Corpse BillCorpse "Bill's body" Bathroom, with description [; "IT IS BILL, THE BUTCHER. HE HAS BEEN STRANGLED WITH A PAIR OF PANTYHOSE"; ]; NPC Daisy "DAISY" EntryHall, with name "Daisy", react_before [; take: if (noun == Note_4 && self hasnt general) "DAISY WON'T LET YOU"; ], number 0, daemon [; ! Prevent Daisy from rising from the dead to kill you again if (self has general) { StopDaemon(self); rtrue; } ! Make Daisy kill after a couple of moves in the attic if (self in location) { self.number++; if (self.number > DAISY_PATIENCE) { print "DAISY STABBED YOU. YOU ARE DEAD^"; <>; } } ], life [; attack: "WITH WHAT?"; ], description [; if (self has general) "SHE IS DEAD"; if (location == Tower) "SHE IS GOING TO KILL YOU"; rfalse; ], has female; [ ClearEntry; remove Bill; remove Joe; remove DrGreen; remove Sally; remove Sam; remove Tom; remove People; move Daisy to Tower; ]; !============================================================================ ! Entry point routines Object Darkness_Daemon, with found_in [; rtrue; ], react_before [; if (Matches in player && Matches has light) rfalse; if (self.number > NIGHTFALL && TestScope(CandleLit)==0) { if (action == ##quit) rfalse; rtrue; } ], number 0, daemon [; self.number++; if (self.number > NIGHTFALL) { if (CandleLit in player) rfalse; give self general; "IT IS DARK, YOU CAN'T SEE"; } if (self.number > TWILIGHT) "IT IS GETTING DARK"; ], has scenery; [ Initialise; ! sets the starting room of the game -- if you remove this, you should ! replace it with another location = ... instruction location = FrontYard; ! like the VERBOSE command -- sets the computer to print a room ! description every time you enter lookmode = 2; ! starts the countdown to darkness -- remove this line to prevent ! darkness from occurring in the game at all. StartDaemon(Darkness_Daemon); ! turns off proportional fonts, creating a monospace effect as in ! the original game font off; #ifdef TARGET_GLULX; picwin.redraw(titlePIC); #endif; ! duplicate of the original start-up screen print "MYSTERY HOUSE^^SIERRA ON-LINE INC^^ ENTER G FOR GAME OR I FOR INSTRUCTIONS^^^^"; if (GOrI()) FullInstructions(); ]; Constant I__WD = 'i//'; [ GOrI i j; for (::) { #ifdef TARGET_ZCODE; if (location == nothing || parent(player) == nothing) read buffer parse; else read buffer parse DrawStatusLine; j = parse->1; #ifnot; ! TARGET_GLULX; KeyboardPrimitive(buffer, parse); j = parse-->0; #endif; ! TARGET_ if (j) { ! at least one word entered i = parse-->1; if (i == I__WD) rtrue; } rfalse; } ]; [ Pause j; for (::) { #ifdef TARGET_ZCODE; if (location == nothing || parent(player) == nothing) read buffer parse; else read buffer parse DrawStatusLine; j = parse->1; #ifnot; ! TARGET_GLULX; KeyboardPrimitive(buffer, parse); j = parse-->0; #endif; ! TARGET_ rtrue; } ]; [ FullInstructions; Instructions(); Pause(); Instructions2(); Pause(); Instructions3(); Pause(); Instructions4(); Pause(); Instructions5(); Pause(); Instructions6(); Pause(); print "^^^^"; ]; [ Instructions; print "INSTRUCTIONS FOR HI-RES ADVENTURE^^"; print "ADVENTURE IS ONE OF THE MOST FACINATING AND CHALLENGING GAMES AVAILABLE FOR YOUR APPLE COMPUTER. WINNING IS QUITE A CHALLENGE IN A GAME WHERE IT MAY TAKE HOURS TO MOVE AND WEEKS TO SOLVE A PUZZLE. HI-RES ADVENTURE #1 ('MYSTERY HOUSE') TAKES PLACE IN AN OLD HOUSE WITH MANY ROOMS. AS YOU ENTER THE HOUSE, SEVEN OTHER PERSONS WILL BE IN THE LIVING ROOM. EVENTUALLY THEY ARE DISPERSED THROUGHOUT THE HOUSE AND YOU START FINDING THEM - DEAD! YOU MUST FIND THE KILLER BEFORE HE(SHE?) ENDS UP KILLING YOU.^^"; print "PRESS RETURN TO CONTINUE^^"; ]; [ Instructions2; print "YOU PROGRESS THROUGH THE HOUSE BY PROVIDING TWO WORD COMMANDS WHICH USUALLY CONTAIN A VERB AND THEN A NOUN BUT AREN'T ALWAYS IN THAT ORDER. EXAMPLES ARE 'WATER ON' AND 'OPEN DOOR'. IF A SET OF WORDS DOESNT SEEM TO BE WORKING TRY DIFFERENT TERMINOLOGY^^"; print "IF YOU SHOULD FIND A STAIRCASE YOU MAY TRY 'UP STAIRS' OR 'GO STAIRS'. SOME OF THE ACTIONS YOU CAN TAKE ARE GET, DROP, GO, LOOK, READ, CLIMB MOVE, HIT, KILL ETC.^^"; print "PRESS RETURN TO CONTINUE^^"; ]; [ Instructions3; print "A NOTE OF CAUTION: CARRYING MORE THAN ONE NOTE MAY BE CONFUSING AS THE COMPUTER WILL ARBITRARILY DECIDE WHICH ONE TO READ OR DROP.^^"; print "SHOULD YOU WISH TO REVIEW PAST COMMANDS YOU MAY PRESS RETURN WITHOUT TYPING TO FLIP/FLOP BETWEEN GRAPHICS AND TEXT.^^"; print "IF YOUR COPY SHOULD EVER FAIL TO LOAD (OR GET MUNCHED BY A HUNGRY DISK DRIVE) SEND IT WITH FIVE DOLLARS TO:^^"; print " ON-LINE SYSTEMS^"; print " 36575 MUDGE RANCH ROAD^"; print " COARSEGOLD CA. 93614^^"; print "PRESS RETURN TO CONTINUE^^"; ]; [ Instructions4; print "YOU MAY GO IN THE DIRECTIONS NORTH, SOUTH, EAST, WEST, UP AND DOWN. TYPE NORTH OR N TO GO NORTH. THE OTHER DIRECTIONS MAY ALSO BE ABBREVIATED AS WELL. WHEN YOUR WAY IS BLOCKED AND YOU CAN'T USE DIRECTIONS TO MOVE YOU MAY HAVE TO REFER TO THE ACTUAL OBJECT IN YOUR WAY. IN THESE CASES, YOU COULD TYPE 'GO DOOR', 'GO HOLE', 'GO GATE' ETC.^^"; print "PRESS RETURN TO CONTINUE^^"; ]; [ Instructions5; print "IN GENERAL THE TOP OF THE SCREEN IS NORTH, THE BOTTOM IS SOUTH, THE LEFT SIDE IS WEST AND THE RIGHT SIDE IS EAST. BECAUSE OF THE DIFFICULTY OF DRAWING DOORWAYS TO THE SOUTH OR THE BOTTOM OF THE SCREEN, THERE ARE ONE OR TWO ROOMS WHERE THE DOORWAYS DO NOT MATCH UP TO THE NORMAL DIRECTIONS.^^"; print "IF YOU WANT A CLOSER LOOK AT SOMETHING SAY LOOK (OBJECT). TO RETURN TO THE MAIN VIEW SAY LOOK ROOM.^^"; print "SAVE GAME AND RESTORE GAME MAY ALSO BE USED.^^"; print "PRESS RETURN TO CONTINUE^^"; ]; [ Instructions6; print "AT THE START OF THE GAME THERE WILL BE SEVEN OTHER PEOPLE IN THE HOUSE WITH YOU. THEIR NAMES, OCCUPATIONS, AND HAIRCOLOR ARE AS FOLLOWS:^^"; font off; print "TOM SAM SALLY^"; print "BLOND BRUNETTE REDHEAD^"; print "PLUMBER MECHANIC SEAMSTRESS^^"; print "DR. GREEN JOE BILL^"; print "BRUNETTE BRUNETTE BLOND^"; print "SURGEON GRAVEDIGGER BUTCHER^^"; print "DAISY^"; print "BLOND^"; print "COOK^^"; font on; print "PRESS RETURN TO BEGIN PLAY^^"; ]; !============================================================================ ! Standard and extended grammar Include "Grammar"; !============================================================================ ! Special Mystery House commands Extend "look" * noun -> Examine * "room" -> Look; Verb "water" * "on" -> TurnOnWater * "off" -> TurnOffWater; [ TurnOnWaterSub; if (location == Kitchen) { move water to sink; "WATER IS RUNNING INTO THE SINK"; } else { "I SEE NO WATER"; } ]; [ TurnOFFWaterSub; if (location == Kitchen) { if (water in sink) remove water; "OK"; } else { "I SEE NO WATER"; } ]; Verb "pour" * noun -> Pour; [ PourSub; "I DON'T UNDERSTAND YOU"; ]; Verb "use" "WITH" * noun -> Use; [ UseSub; "I DON'T UNDERSTAND WHAT YOU MEAN"; ]; Verb "help" * topic -> Help; [ HelpSub; if (location ofclass ForestRoom) "IF ONLY I COULD TELL IF I'D BEEN HERE BEFORE..."; "TRY GOING IN SOME DIRECTION^ EX:NORTH,SOUTH,EAST,WEST,UP,DOWN"; ]; Verb "shoot" "fire" * noun -> Shoot; [ ShootSub; "I DON'T UNDERSTAND WHAT YOU MEAN"; ]; Verb "flush" * noun -> Flush; [ FlushSub; "I DON'T UNDERSTAND WHAT YOU MEAN"; ]; Extend only "read" first * noun -> Read; [ ReadSub; if (noun provides text) { if (noun in player) noun.text(); else "IM NOT CARRYING THAT"; } else <>; ]; Extend "unlock" first * noun -> UnlockEasy; [ UnlockEasySub key; if (noun provides with_key) key = noun.with_key; if (key && key in player) { give noun ~locked; "OK"; } else { "YOU HAVE NOTHING TO UNLOCK IT WITH"; } ]; Extend only "remove" replace * noun -> Rub; Extend only "unscrew" replace * noun -> Loosen; Verb "loosen" "unbolt" * noun -> Loosen; [ LoosenSub; "I DONT UNDERSTAND WHAT YOU MEAN"; ]; Extend "look" * "room"/"around" -> Look; !============================================================================