! ===========================================================================
! "Detective"
! An Interactive MiSTing
! By C.E. Forman ([email protected])
! Created using Unix Inform 5.5
! Original AGT version by Matt Barringer
! (Thanks to Gareth Rees for his help with the code!)
! SILVER SCREEN EDITION!!!
! ===========================================================================
!
! Attention beginning Inform programmers: Commented explanations of various
! text tricks have been inserted throughout the code.  (Never thought a game
! like "Detective" would make a worthwhile programming example, didja?)
!
! ===========================================================================

Switches dxsv5;

! The `Switches' directive pre-sets some compiler options so you don't have
! to when you compile the code.  See section 32 of the Inform 5.5 manual
! for explanations of these.
!
! The following command is the one I use to compile the game on my system
! (it should be typed all on one line):
!
!   inform $large $MAX_STATIC_DATA=8000 $BUFFER_LENGTH=10000 mst3k1.inf
!   mst3k1.z5
!
! (This may vary depending upon your exact configuration.)

!Constant DEBUG;

! If you want a better idea of how this game functions, delete the
! exclamation point from the line above, then re-compile the game to allow
! for the use of debugging commands (see section 26 of the Inform manual).

Constant SILVER_SCREEN;

! The numerous lengthy essays included with the Silver Screen Edition of
! MST3K1 increase the Z-code size by about 30%.  These are not essential
! to the game, and can be eliminated by commenting out the above line.

Constant Story "~Detective~";
Constant Headline "^An Interactive MiSTing^\
                  By C.E. Forman (ceforman@@64worldnet.att.net)^\
                  Created using Unix Inform 5.5^\
                  Original AGT version by Matt Barringer^\
                  (Thanks to Gareth Rees for his help with the code!)^\
                  SILVER SCREEN EDITION!!!^";
Release 101;

! The `@@64' notation is necessary to get an @ symbol (typically reserved
! for Inform assembler) to print.  A partial list appears in `The
! Specification of the Z-Machine.'  Refer to an ASCII table for other
! values.  (Also note my NEW e-mail address!)

Constant MAX_SCORE 355;
Constant ROOM_SCORE 10;

Include "Parser";

! First, some changes to the messages produced by the library.  Using the
! `LibraryMessages' object is neater than having to update the library
! sources by hand, and it makes it possible to upgrade to new versions of
! the library without having to edit each new version to include your
! changes.
!
! The `Attack' message is changed to the AGT default, and some of the
! messages associated with dying are altered so that we can have some
! sarcastic comments after the player has died.  This works better than
! the `AfterLife' entry point, because we can make the quips appear
! _after_ the "*** You have died ***" message.
!
! Note that `LibraryMessages' must be defined before including `VERBLIB.H'.

Object  LibraryMessages "lm"
with   before [;
         Quit: print "KEEP CIRCULATING THE GAME!^^";
         Attack: "It would really make more sense to specify some living \
           thing^to kill. Hostility really requires a target of some \
           sort.";
         Score:
           if (deadflag==0) print "You have so far scored ";
           else {
               if (location == Dead_End_3) {
                   Quip(-1,0,TOM,"WHAT!? Why'd we just die here?",1);
                   Quip(-1,0,CROW,"Oh, I get it! It's a ~dead~ end! See?",1);
                   Quip(-1,0,MIKE,"Matt Barringer made a funny!",2);
               }
               if (deadflag == 2)
                   print "STINGER:^^~I'm supposed to get 20 years but \
                       I'll be out in 2. You can't make me talk^cuz it \
                       don't matter to me.~^^";
               print "In that game you scored ";
           }
           print score, " out of a possible ", MAX_SCORE, ", in ", turns,
               " turn";
           if (turns>1) print "s"; rtrue;
       ];

Include "Verblib";
Include "Grammar";

! Some simple grammar extensions.

[ HelpSub;
   "Sorry, you're on your own here.";
];

Verb "help" "hint"
   *                                                      -> Help;

Verb "shoot" "fire"
   *                                                      -> Attack
   * animate                                              -> Attack
   * "at" animate                                         -> Attack
   * animate "with" noun                                  -> Attack
   * noun "at" animate                                    -> Attack
   * "at" animate "with" noun                             -> Attack;

! All the rooms in "Detective" have certain properties in common, so the
! following class provides them.  In mockery of the AGT parser, all the
! compass directions are set up so that trying to move will print a failure
! message and then print the entire room description again.  There are no
! dark rooms, and all the rooms have << chevrons >> around the room name:
!                                       ^^^^^^^^
! (So THAT's what those greater-than/less-than symbol-type thingies are
! called!  Thanks, Gareth.  Gareth knows some cool words.  Another fave of
! mine is `chirality', meaning the direction in which a spiral coils.)

Class   BarringerRoom
has    light
with   n_to [; print "You can't go north from here!^"; return self; ],
       s_to [; print "You can't go south from here!^"; return self; ],
       e_to [; print "You can't go east from here!^"; return self; ],
       w_to [; print "You can't go west from here!^"; return self; ],
       u_to [; print "You can't go up from here!^"; return self; ],
       d_to [; print "You can't go down from here!^"; return self; ],
       ne_to [; print "You can't go northeast from here!^"; return self; ],
       nw_to [; print "You can't go northwest from here!^"; return self; ],
       se_to [; print "You can't go southeast from here!^"; return self; ],
       sw_to [; print "You can't go southwest from here!^"; return self; ],
       in_to [; print "You can't go in from here!^"; return self; ],
       out_to [; print "You can't go out from here!^"; return self; ],
       short_name [; print "<< ", object self, " >>"; rtrue; ];

! Many rooms are scored, so this subclass will be useful:

Class   ScoredRoom
class  BarringerRoom
has    scored;

! Several of the rooms in the game kill the player the moment he or she
! enters, so this class is defined to deal with those cases.

Class   DeathRoom
has    light
with   each_turn [; deadflag = 1; ],
       short_name [; print "<< ", object self, " >>"; rtrue; ];

! Inform prints `Taken' and `Dropped' when the player takes and drops an
! object, but AGT was somewhat more verbose.  The following class provides
! these extra messages.

Class   BarringerObject
with   after [;
        Take: print_ret "You are now carrying ", (the) self, ".";
        Drop: print_ret "You drop ", (the) self, ".";
       ];

! Not satisfied with my own bashing of "Detective"?  Now you can have Mike
! and the bots shout out your very OWN comments!  Here's how it works:
!
! A printing routine is used since a number of features are tricky to
! implement.  First, for readability, the text should be printed with a
! hanging indent, as in a screenplay, and the Z-machine text-printing
! routines don't do this automatically.  Second, to avoid cluttering up
! the room descriptions, some of the comments should appear the first time
! a description is printed, and others the second time.
!
! Consider the following function call:
!
!     Quip(n,ns,bot,text,ne);
!
! where `n' says how many times to let this go by before printing,
!       `ns' is the number of new-lines before the quip,
!       `bot' says which robot (or character) should produce the quip,
!       `text' is the packed address of the quip itself, and
!       `ne' is the number of new-lines after the quip.
!
! Then a call like:
!
!     Quip(0,2,MIKE,"I'm not wearing any pants!",2);
!
! gets printed the first time the function is called, producing something
! like this (on a very narrow screen):
!
!     MIKE: I'm not wearing
!           any pants!
!
! The second time the function is called, the message isn't printed
! (because it's been seen already).  On the other hand, a call like
!
!     Quip(1,2,MIKE,"I'm not wearing any pants!",2);
!
! gets ignored the first time the function is called, gets printed the
! second time the function is called, and ignored thereafter.
!
! Some quips only ever get printed once during a game (for example, those
! in the introduction, epilogue, and any that appear when the player dies).
! It would be pointless to record how many times these have been seen, so
! they use a first argument to `Quip' of -1.  The same holds true for the
! quips in the essay "On the Not-Quite-Making of MST3K2".
!
! Gareth Rees is to be credited for this excellent system, which easily
! whips my own cheesy technique of setting attributes in each room to
! control the appearance of quips.

Constant MIKE 1;
Constant TOM 2;
Constant CROW 3;
Constant ALL 4;
Constant CROWTOM 5;
Constant MIKECROW 6;
Constant GYPSY 7;
Constant FRANK 8;
Constant DRF 9;
Constant FRANKSVOICE 10;
Constant DRFSVOICE 11;
Constant MAGICVOICE 12;
Constant CONTINUE 13;

! The names of the characters follow.  The dummy name CONTINUE just prints
! six spaces, which is the width of the hanging indent.  It is used to
! split one long speech that would otherwise overflow the print buffer.  An
! alternative would be to make the print buffer longer, but since it's an
! array that must be statically allocated, that wastes space in the Z-code.

Array BotName -->
   "MIKE: " "TOM:  " "CROW: " "ALL:  "
   "CROW & TOM: " "MIKE & CROW: "
   "GYPSY: " "FRANK: " "DR.F: "
   "FRANK'S VOICE: "
   "DR.F'S VOICE: "
   "MAGIC VOICE: "
   "      ";

! The number of characters by which the names overlap the 6-character
! hanging indent.  These numbers are needed to get the length of the first
! printed line correct.

Array BotLength -> 0 0 0 0 6 7 1 1 0 9 8 7 0;

! An array which contains the packed address of every quip seen so far,
! and another array containing the number of times each quip has been seen
! before:

Constant NUMBER_QUIPS 500;             ! Total number of quips in the game

Global NoQuipsSeen = 0;                ! How many quips seen so far
Array QuipsText --> NUMBER_QUIPS;      ! Array of quip text seen
Array QuipsNumber -> NUMBER_QUIPS;     ! Array of number times seen

! What the Quip function does is to see if it has been called before with
! the same text.  If so, it increments the appropriate member of the
! `QuipsNumber' array.  If not, it increases `NoQuipsSeen' by 1, and stores
! the address of the text in the `QuipsText' array, and puts 0 in the
! corresponding place in the `QuipsNumber' array.
!
! The robot names are printed with the proportional font turned off, so
! that the hanging indent will line up, and the function `HangingIndent'
! is called to do that actual printing.

[ Quip
   n      ! the number of times the quip should be ignored before printing
   ns     ! the number of newlines at the start of the quip
   bot    ! the bot (characters) who says the quip
   text   ! the packed address of the text of the quip
   ne     ! the number of newlines at the end of the quip
   i;     ! the quip's index in the `QuipsText' and `QuipsNumber' arrays

   ! If `n' is -1, don't bother to store the quip because it can't
   ! possibly be seen twice.

   if (n == -1) jump QuipPrint;

   ! Have we seen this quip before?  If so, increment the count of times
   ! seen, taking care not to overflow.

   for (i = 0 : i < NoQuipsSeen : i++) {
       if (text == QuipsText-->i) {
           if (QuipsNumber->i < 255)
               QuipsNumber->i = QuipsNumber->i + 1;
           jump QuipFound;
       }
   }

   ! If we haven't seen it before, add it to the array

   if (NoQuipsSeen >= NUMBER_QUIPS) "** Error: out of quip space **";
   i = NoQuipsSeen;
   NoQuipsSeen ++;
   QuipsText-->i = text;
   QuipsNumber->i = 0;

   ! We only print the quip if the number of times it's been seen before
   ! matches the parameter `n'.

   .QuipFound;
   if (QuipsNumber->i ~= n) rfalse;

   ! Now print it

   .QuipPrint;
   for (i = 0 : i < ns : i++) new_line;
   font off;
   print (string) BotName-->(bot-1);
   font on;
   HangingIndent(text,BotLength->(bot-1));
   for (i = 0 : i < ne : i++) new_line;
];

! Printing text with a hanging indent: Quip text is printed to an array
! in memory rather than to the screen (using the `output_stream' opcode).
! Then for each line, a breakpoint is determined that prevents a word
! being split over the line.  Then print the appropriate portion of the
! array (using the `print_table' opcode), print the indent, and go back for
! another line.  The indent is printed with the proportional font turned
! off.

Constant MAX_STRING_LENGTH 1000;    ! maximum length of any quip in the game
Array sb -> MAX_STRING_LENGTH;      ! buffer to hold the printed string

[ HangingIndent
   text      ! packed address of text to print
   overlap   ! extent to which first line sticks out over the 6-char indent
   len       ! length of text in characters
   from      ! first character not printed
   width     ! width of screen in characters, less six character indent
   bp        ! break point in string
   start     ! where to start printing from
   n         ! number of characters to print
   flag;     ! 0 iff this is the first line being printed (so omit indent)

   ! String manipulation.  The string starts out in encoded form, so it
   ! is first decoded to the string buffer:

   @output_stream 3 sb;
   print (string) text;
   @output_stream -3;

   ! Set up parameters (recall that the first two bytes of the array `sb'
   ! hold the length).

   width = 0->33 - 6;
   len = sb-->0 + 2;
   from = 2;
   if (len > MAX_STRING_LENGTH) "** Error: string was too long **";

   while (from < len) {
       if (flag == 0) {
         flag = 1;
         bp = from + width - overlap;
       }
       else {
         font off; new_line; spaces 6 + overlap; font on;
         bp = from + width;
       }

       ! See if it can print the rest of the text on one line.

       if (bp >= len) {
           bp = len;
           jump FoundBreakPoint;
       }

       ! Find the best breakpoint, if any.

       for ( : bp >= from : bp--)
           if (sb->bp == ' ')
               jump FoundBreakPoint;

       ! No breakpoint found, so split in the middle of the word.

       bp = from + width;

       ! Print the text from `from' to the breakpoint.

       .FoundBreakPoint;
       start = sb + from;

       n = bp - from;
       @print_table start n 1;

       ! Skip any whitespace.

       from = bp;
       while (sb->from == ' ') from ++;
   }
];

! A couple of special commands appear in the initialization routine.
!
! Line 3 (lookmode = 2;) puts the game into Verbose mode at the start.
! This is necessary so that the comments displayed when the player visits
! rooms a second time are not overlooked.
!
! Line 4 (notify_mode = 0;) turns score notification off, because it
! would just get in the way of the comments.
!
! This WILL be on the test, people.

[ Initialise;
   location = Chiefs_Office;
   lookmode = 2;
   notify_mode = 0;
   TitlePage();
   print "^^^^^^^^^^G...6...5...4...3...2...1...^^[Mike and the bots \
       enter the theater.]^^";
];

! Okay, let's decipher the first room (which is one of the more complex).
! The statements beginning `print' always print the text, so if none of the
! `Quip' statements produce any output, then what results is the original
! room description from "Detective".
!
! Now, the first time the room description is executed, all five of the
! quips have been called zero times, so the second ("Yeaterday?...") and
! fourth ("Tonight...") get printed, but the first, third and fifth are
! ignored (but the `Quip' function remembers that all five quips were
! called).
!
! The second time the room description is executed, all five of the
! quips have been called one time each, so now the second and fourth get
! ignored, but the first ("So is this guy..."), third ("Which would..")
! and fifth ("Uh...") get printed.
!
! The third time the room description is executed, all five of the quips
! have been called twice each, so none of them gets printed, and all the
! player sees is the "Detective" room description.  The same happens the
! fourth time, fifth time and so on.
!
! It's worth taking a look at the numbers of new-lines printed before and
! after each quip; although they look somewhat random, in fact care has
! been taken with each so that the resulting text comes out looking neat,
! with a blank line before and after each set of quips, but no blank
! between quips if there is no "Detective" text between them.
!
! As a final note, don't be confused by the new-line characters (^) that
! appear in the center of the normal `print' strings.  These are included
! to format the text as it appears in the original "Detective", reaching
! only about three-quarters of the way to the edge of the screen.  (If
! you're gonna do a port of "Detective", you may as well be EXACT.  Or
! thoroughly anal.  Take your pick.)

Object  Chiefs_Office "Chief's Office"
class  ScoredRoom
with   describe [;
           print "You are standing in the Chief's office. ";
           Quip(1,2,MIKE,"So is this guy Commissioner Gordon, or what?",2);
           print "He is telling you^~The mayor was murdered yeaterday \
               night^";
           Quip(0,1,MIKE,"Yeaterday? Is that like Veterans' Day?",2);
           print "at 12:03 am. I want you to solve it before we get any \
               bad^publicity ";
           Quip(1,2,CROW,"Which would only serve to counteract the GOOD \
               publicity brought about by the mayor's death!",2);
           print "or the FBI has to come in.~^";
           Quip(0,1,TOM,"Tonight, on ~The X-Files!~",2);
           print "~Yessir!~ You reply. He hands you a sheet of \
               paper.^Once you have read it, go north or west.^";
           Quip(1,1,TOM,"Uh...haven't we been through this already?",1);
           rtrue;
       ],
       w_to Closet_1,
       n_to Outside_1;

Nearby  White_Paper "white paper"
class  BarringerObject
with   name "white" "paper",
       describe [;
           print "^It is a white sheet of paper.^";
           Quip(0,1,MIKE,"Thanks for clearing that up.",1);
           rtrue;
       ],
       description [;
           print "CONFIDENTIAL:^^Detective was created by Matt \
               Barringer.  ";
           Quip(0,2,CROW,"[Snide] Oh, the great Matt Barringer!",1);
           Quip(0,0,TOM,"You never get tired of that line, do you, Crow?",2);
           print "He has worked hard on this^so you better enjoy it.  ";
           Quip(0,2,MIKE,"We've been warned, fellas.",2);
           print "I did have fun making it^though.  But^I'd REALLY \
               appreciate it if you were kind enough to send a \
               postcard^or...dare I even say it?...money...to:^^Matt \
               Barringer^325 Olive Ave^Piedmont^Ca 94611^^";
           Quip(0,0,CROW,"We'll do that, Matt. We'll do that.",2);
           print "Just tell me if you like it or not.  ";
           Quip(0,2,TOM,"We don't, okay? Deal with it.",2);
           print "If you want to talk to me over^a BBS^call the \
               Ghostbuster Central BBS at (510)208-5657.";
           Quip(0,2,MIKE,"Who ya gonna call?^",1);
           Quip(0,0,ALL,"GHOSTBUSTERS!!",1);
           print "^There is an Exile Games message area^and an Exile \
               Games file area.^Have fun.  I WILL give hints out over \
               the BBS to any of my games.^";
           Quip(0,1,TOM,"Oh right, like you'd actually NEED hints to win \
               this game.",1);
           rtrue;
       ];

Object  Closet_1 "Closet"
class  ScoredRoom
with   description [;
           print "You are in a closet.  There is a gun on the floor.  ";
           if (Black_Gun notin self) {
               Quip(0,2,TOM,"Yes, the gun remains here despite the fact \
                   that we've already picked it up.",1);
               Quip(0,0,MIKE,"How DO you do it, Matt Barringer?",2);
           }
           "Better get it.^To exit, go east.";
       ],
       e_to Chiefs_Office;

Nearby  Black_Gun "black gun"
class  BarringerObject
with   name "black" "gun" "pistol",
       describe [;
           print "It is a small black pistol.^";
           Quip(0,1,CROW,"Hey, hey, hey! That's ~African-American \
               pistol!~",1);
           rtrue;
       ],
       description [;
           print "It is a small black pistol.  It has 10 bullets in it.  ";
           if (Man has general)
               Quip(0,2,MIKE,"Oh, it must be auto-reloading.",2);
           print "You must^use them wisely.^";
           Quip(0,1,TOM,"Or not. It's not like it matters.",1);
           rtrue;
       ];

Object  Outside_1 "Outside"
class  ScoredRoom
with   description [;
           print "You are outside in the cold.  To the east is a dead \
               end.  To the^west is the rest of the street.  Papers are \
               blowing around.  It's^amazingly cold for this time of \
               year.^";
           Quip(0,1,MIKE,"[Minnesotan voice] Yah, that kinda weather'll \
               take ya by surprise, all right.",1);
           Quip(0,0,CROW,"[Minnesotan voice] Oh, yah, I remember the \
               summer of '58 when it got ta be this cold.",1);
           Quip(0,0,TOM,"[Minnesotan voice] Yah, we musta got at least 8 \
               feet o' snow that day, and all the streets was closed.",1);
           rtrue;
       ],
       w_to Outside_2,
       s_to [;
           print "You can't go south from here!^";
           Quip(0,1,TOM,"Sorry, folks, it looks like the door just \
               vanished into thin air.",1);
           return self;
       ];

Object  Outside_2 "Outside"
class  ScoredRoom
with   description [;
           print "You are still on the streets.  To the north is a \
               restraunt ";
           Quip(0,2,MIKE,"Uh, I think you mean ~restaurant,~ Matt.",2);
           print "where^the mayor ate often.  To the East is the mayor's \
               home.^";
           Quip(0,1,CROW,"Hey, isn't the _street_ back to the east?",1);
           rtrue;
       ],
       n_to Restaurant,
       e_to [;
           Quip(0,0,CROW,"I thought the _street_ was back this way!",1);
           Quip(0,0,MIKE,"Nope, apparently we were mistaken.",1);
           return Mayors_House;
       ];

Object  Restaurant "Restraunt"
class  DeathRoom
with   description [;
           print "You are about to enter the restraunt when two guys \
               jump you.^The take your wallot and beat you a bit. \
               Then you flash your badge^and that riles them.  Your \
               body was discovered in a river 10 miles away.^";
           Quip(-1,1,MIKE,"Man, that is one rough T.G.I. Friday's!",1);
           rtrue;
       ];

Object  Mayors_House "Mayor's house"
class  ScoredRoom
with   description [;
           print "You are in the house, at the scene of the crime.  You \
               enter ";
           Quip(0,2,TOM,"Didn't it just say we were already IN the \
               house?!",2);
           print "and flash^your badge before a cop.  He admit's you. ";
           Quip(0,2,MIKE,"[As your character] Where's the body?",1);
           Quip(0,0,CROW,"[As the cop] I ate it.",2);
           Quip(1,2,TOM,"But he _already_ admitted us!",1);
           Quip(1,0,CROW,"Why, Mike?! Why does it do this?!",1);
           Quip(1,0,MIKE,"Shhh, it's okay, guys.",2);
           print "To the north is the upstairs^";
           Quip(1,1,CROW,"Gee, you'd think the upstairs would be UP from \
                 here!",2);
           print "to the east is the living room and to the west is the \
               dining room.^";
           Quip(0,1,TOM,"I thought we just CAME from the west!",1);
           Quip(0,0,MIKE,"I don't think this author quite grasped the \
                 concept of a two-way door.",1);
           rtrue;
       ],
      n_to Upstairs_Hallway,
      e_to Living_Room,
      w_to Dining_Room;

Object  Dining_Room "Dining Room"
class  BarringerRoom
has    ~scored
with   description [;
           print "You are in the dining room.  You look around and see a \
               note on the table.^";
           if (Paper_Note notin self) {
               Quip(0,1,MIKE,"The exact same note you picked up only \
                   moments before!",1);
               Quip(0,0,TOM,"It's magic!",2);
           }
           print "You can go back east.^";
           if (self hasnt visited) score = score + 5;
           Quip(0,1,CROW,"Wow! A two-way door! We can go back! Check it \
               out, Mike!",1);
           rtrue;
       ],
       e_to Mayors_House;

Nearby  Paper_Note "paper note"
class  BarringerObject
with   name "paper" "note",
       describe [;
           print "^It is a note.  With writing on it.^";
           Quip(0,1,TOM,"Any questions?",1);
           Quip(0,0,MIKE,"Yeah. Could it technically be considered a \
               note if it _didn't_ have writing on it?",1);
           rtrue;
       ],
       description [;
           print "The note was writen on a computer^";
           Quip(0,1,MIKE,"I think he means it was _typed_ on a \
               computer.",2);
           print "obviously this murder was planned^^and it says:^^";
           Quip(0,0,CROW,"Wait a minute -- the MURDER says something?!",1);
           Quip(0,0,MIKE,"I think he means the note.",1);
           Quip(0,0,TOM,"It's hard to tell with this game.",2);
           print "We have acclaimed Justice! The Justice of the future! \
               Our next hit is the governer! You CAN'T STOP US!^^";
           Quip(0,0,MIKE,"YOU CAN'T HANDLE THE TRUTH!!",1);
           Quip(0,0,CROW,"Well, at least they're being nice and telling \
                 us ahead of time.",2);
           print "The note sounds like the killers are a group^and that \
               they are vigilantes^(look it up). ";
           Quip(0,2,TOM,"Right, this from Matt ~Restraunt~ Barringer.",2);
           print "You are now getting a bit worried.^";
           Quip(0,1,MIKE,"Because you realize this game could \
               potentially spawn a sequel.",1);
           Quip(0,0,CROW,"Say it ain't so, Mike!!",1);
           rtrue;
      ],
      after [;
        Take:
           Quip(0,1,TOM,"I'd like a note, please.",1);
           Quip(0,0,CROW,"Paper or plastic, sir?",1);
           Quip(0,0,TOM,"Paper, please.",2);
      ];

Object  Living_Room "Living Room"
class  ScoredRoom
with   description [;
           print "You are standing in the living room. You see a \
               battered piece of wood^You wonder ~Should I pick this \
               thing up?~^";
           Quip(0,1,MIKE,"Wow, it's like he's reading our minds.",2);
           "Well, wether you do or don't the only way out of the room is \
           back west.";
       ],
       w_to Mayors_House;

Nearby  Wooden_Wood "wooden wood"
class  BarringerObject
with   name "wooden" "wood",
       initial "It is a battered brown piece of wood.",
       description [;
           print "You look at it closely and figure that the guys in the \
               forsenic's lab^would be better at this then you.^";
           Quip(0,1,TOM,"Well, that'd be great if there actually WAS a \
               forensics lab in this game.",1);
           rtrue;
       ],
       after [;
        Take:
           print "You are now carrying the wooden wood.^";
           Quip(0,1,CROW,"Wooden wood -- as opposed to metal wood, stone \
               wood, and plastic wood!",1);
           rtrue;
       ];

Object  Upstairs_Hallway "Upstairs Hallway"
class  ScoredRoom
with   description [;
           print "You are in the hallway of the large house of the \
               mayor. It is an^amazingly large house. ";
           Quip(0,2,CROW,"The house is so large it is amazing.",1);
           Quip(0,0,TOM,"You are amazed by how large the mayor's large \
                 house is.",1);
           Quip(0,0,MIKE,"The amazing largeness of the mayor's large \
                 house amazes you.",2);
           "You can go north, south, east or west.";
       ],
       s_to Mayors_House,
       w_to Closet_2,
       e_to Bathroom,
       n_to Hallway_1;

Object  Closet_2 "Closet"
class  BarringerRoom
with   description [;
           print "You are in a closet. The closet is of the walk in \
               variety, with^about thirty pairs of tennis shoes, ten \
               pairs of heels and about^ninety coats and shirts. ";
           Quip(0,2,TOM,"None of which you can interact with, so don't \
               bother trying.",2);
           print "You start to get claustrophobia. ";
           Quip(0,2,CROW,"Klaustrophobia? Let's play that instead!",2);
           print "Better^get out.^";
           Quip(0,1,TOM,"Of this game.",1);
           rtrue;
       ],
       e_to Upstairs_Hallway;

Object  Bathroom "Bathroom"
class  BarringerRoom
with   description [;
           print "You are in the first bathroom, out of the 5 there is. ";
           Quip(0,2,TOM,"Yes, there IS five bathrooms in this house.",1);
           Quip(0,0,CROW,"I bet the mayor needed all those bathrooms \
               because he had to--",1);
           Quip(0,0,MIKE,"[Grabs Crow's beak and holds it shut.] Not \
               another word, Crow.",2);
           print "You notice^that it is almost as big as your apartment. ";
           Quip(0,2,TOM,"Oh no, don't tell me you play Mitchell in this \
               game!",1);
           Quip(0,0,CROW,"Mitchell -- ask for him by name!",2);
           "You see a knife on the floor^here.";
       ],
       w_to Upstairs_Hallway;

Nearby  Knife "knife"
has    concealed scenery
with   name "knife",
       description [;
           print "You can't see that here.^";
           Quip(0,1,MIKE,"Yes, folks, the knife is right here in plain \
               sight, but you can't see it.",1);
           rtrue;
       ],
       before [;
        Take:
           print "You can't see that here.^";
           Quip(0,1,TOM,"Boy, where's Sergeant Duffy when you need him?",1);
           rtrue;
       ];

Object  Hallway_1 "Hallway"
class  BarringerRoom
with   description [;
           print "You are at the end of the hallway. To the north is a \
               room, while^to the west is the rest of the hallway.^";
           Quip(0,1,CROW,"Except the part that's to the south.",1);
           Quip(1,1,TOM,"Do you know who did it? Have you figured it out \
               yet?",1);
           rtrue;
       ],
       n_to Closet_3,
       w_to Hallway_2;

Object  Closet_3 "Closet"
class  BarringerRoom
with   description [;
           print "You are in a closet. There is no reason to be in \
               here.^";
           Quip(0,1,TOM,"There is no reason to have this room in the \
               game, but we put it here anyway.",2);
           "Go south.";
       ],
       s_to [;
           Quip(0,0,CROW,"Ahh, coming out of the closet!",1);
           Quip(0,0,MIKE,"Stop it, Crow.",1);
           return Hallway_1;
       ];

Object  Hallway_2 "Hallway"
class  BarringerRoom
with   description [;
           print "You are in the hallway. To the north is more hallway, \
               and to the east is^a door marked^~Guests~.^";
           Quip(0,1,CROW,"I'm starting to get really sick of this \
               hallway.",1);
           Quip(0,0,MIKE,"Patience, Crow. It can't go on forever.",1);
           Quip(0,0,CROW,"Tell me about it.",1);
           rtrue;
       ],
       n_to Hallway_3,
       e_to Guest_Room_1;

Object  Guest_Room_1 "Guest Room"
class  BarringerRoom
with   description [;
           print "You are in one of the many guest rooms. It is a nice \
               room, big screen^TV in one corner, 2 king size beds in \
               the back of the room, strategicly^placed so that you can \
               see the TV while comfortably proped up in bed.^You see \
               nothing of intrest, you should go west.^";
           Quip(0,1,TOM,"What?! He described all that just to tell us \
               there's nothing to do here?!?",1);
           Quip(0,0,CROW,"I still say this is Matt's best room \
               description so far.",1);
           Quip(0,0,TOM,"That's still not saying much.",1);
           rtrue;
       ],
       w_to Hallway_2;

Object  Hallway_3 "Hallway"
class  BarringerRoom
with   description [;
           print "You are STILL in the hallway. ";
           Quip(0,2,CROW,"Aaaaarrgh! NO!! Get me outta here!!",2);
           print "There is EVEN MORE hallway to the north,^";
           Quip(0,1,CROW,"That's it. I'm leaving. [Crow tries to get \
               up, but Mike holds him back.]",2);
           "and a room to the west and a room to the east of you.";
       ],
       e_to Closet_4,
       w_to Closet_5,
       n_to Hallway_4;

Object  Closet_4 "Closet"
class  BarringerRoom
with   description [;
           print "You are in a small closet. The room is bare. Why not \
               go east and get^back to the situation at hand?^";
           if (self hasnt visited && Closet_5 hasnt visited) {
               Quip(0,1,TOM,"What the...? We came in here from the WEST!",1);
               Quip(0,0,CROW,"Try going east.",1);
               rtrue;
           }
           if (Hallway_3 hasnt general) {
               give Hallway_3 general;
               Quip(0,1,CROW,"[Ominous] We have entered the mysterious \
                   Closets of Teleportation!",1);
               Quip(0,0,MIKE,"Beam us up, Scotty.",1);
           }
           rtrue;
       ],
       e_to Hallway_3;

Object  Closet_5 "Closet"
class  BarringerRoom
with   description [;
           print "You are in a closet. There is no reason to be in here. \
               Go west.^";
           if (self hasnt visited && Closet_4 hasnt visited) {
               Quip(0,1,TOM,"What the...? We came in here from the EAST!",1);
               Quip(0,0,CROW,"Try going west.",1);
               rtrue;
           }
           if (Hallway_3 hasnt general) {
               give Hallway_3 general;
               Quip(0,1,CROW,"[Ominous] We have entered the mysterious \
                   Closets of Teleportation!",1);
               Quip(0,0,MIKE,"Beam us up, Scotty.",1);
           }
           rtrue;
       ],
       w_to Hallway_3;

Object  Hallway_4 "Hallway"
class  BarringerRoom
with   description [;
           print "You are still in the hallway. ";
           Quip(0,2,CROW,"AAAARRRGGHHH!! MAKE IT STOP, MAKE IT STOP, \
               MAKE IT STOP -- [Mike pats Crow's shoulder reassuringly \
               until he calms down.]",2);
           print "You can go north to where there is a police officer \
               who will let you outside, or you can go east or west.^";
           Quip(0,1,CROW,"North! Go north! Get us out of here!!",1);
           rtrue;
       ],
       e_to Guest_Room_2,
       w_to Bedroom,
       n_to Outside_3;

Object  Guest_Room_2 "Guest Room"
class  BarringerRoom
with   description [;
           print "You are in a guest room.  You see that there isn't \
               much here,^the murderers ransacked the room. ";
           Quip(0,2,MIKE,"Yet for some reason they didn't touch the big \
               screen TV in the OTHER guest room!",2);
           "You can go west.";
       ],
       w_to Hallway_4;

Object  Bedroom "Bedroom"
class  ScoredRoom
with   description [;
           print "You are in the bedroom. You noticed that there was a \
               guard^guarding the stairs to the 3rd story, ";
           Quip(0,2,MIKE,"Yeah, that's what guards typically do. They \
               guard things.",1);
           Quip(0,0,CROW,"Hence the name.",2);
           print "because there is remodelling going^on there. ";
           Quip(0,2,TOM,"And remodelling is far more important than some \
               petty murder investigation.",2);
           "You see nothing of importance. Go east.";
       ],
       e_to Hallway_4;

Object  Outside_3 "Outside"
class  ScoredRoom
with   description [;
           Quip(0,1,CROW,"Oh, thank God that hallway's over with!",2);
           print "You pass the guard. He nods at you. You are now \
               outside standing^on the street. ";
           Quip(1,2,TOM,"Hey, guys, I just thought I'd point out once again \
               how this game blends the room, object, and character \
               descriptions into a muddled mess.",1);
           Quip(1,0,MIKE,"Thanks for the reminder, Tom.",2);
           print "You can go north and east, your choice.^";
           Quip(0,1,MIKE,"It's good when a game lets players make a \
               choice like this.",1);
           Quip(0,0,CROW,"Matt Barringer made a wise creative decision \
               here.",2);
           "To the north is more of the street, and to the east is a \
           video store.";
       ],
       n_to Dead_End_1,
       e_to Video_Store_1;

Object  Dead_End_1 "Dead end"
class  BarringerRoom
with   description [;
           print "You are at a dead end. You can go south, or \
               west. Which way?^";
           Quip(0,1,TOM,"Mike, is it really a dead end if you can go 2 \
               ways?",1);
           rtrue;
       ],
       s_to Outside_3,
       w_to Murderers_Lounge;

Object  Murderers_Lounge "Murderer's lounge"
class  DeathRoom
with   description [;
           print "You are in the so called ~Murderers Lounge~. \
               Unfortunatly,^there ARE murderers here, and when you \
               check around, they get angry.^But, that's life. Ya \
               lose!^";
           Quip(-1,1,TOM,"And that's death.",1);
           Quip(-1,0,CROW,"But it's nice to know that this city has \
               establishments that cater exclusively to criminals.",1);
           Quip(-1,0,MIKE,"No weapon, no criminal record, no service!",1);
           rtrue;
       ];

Object  Video_Store_1 "Video Store"
class  BarringerRoom
with   description [;
           print "You are in a video store called^Brickbuster Video.^";
           Quip(0,1,MIKE,"Let's make it a Brickbuster night!",2);
           print "There are about 3,000 videos here. ";
           Quip(1,2,CROW,"Wonder if they have ~Caligula?~",1);
           Quip(1,0,MIKE,"Crow!",1);
           Quip(1,0,TOM,"Or maybe ~Mandingo.~",1);
           Quip(1,0,MIKE,"Tom!",2);
           print "You can go north, or east.^";
           Quip(0,1,TOM,"But the door you came through has mysteriously \
               disappeared.",1);
           Quip(0,0,MIKE,"Hey, that really deters late-night robberies.",1);
           rtrue;
       ],
       n_to Backroom,
       e_to Video_Store_2;

Object  Backroom "Backroom"
class  BarringerRoom
with   description [;
           print "You are in the backroom of Brickbuster Video. ";
           Quip(0,2,CROW,"[Little kid voice] I hafta go to the backroom!",2);
           print "You see a small video^on the floor, but you dismiss it \
               as having no potential value to the^crime. ";
           Quip(0,2,MIKE,"Boy, _nothing_ in this game is connected to \
               the crime!",1);
           Quip(0,0,CROW,"What crime were we supposed to be \
               investigating, again?",1);
           Quip(0,0,MIKE,"You've got me, Crow.",2);
           "You can go south.";
       ],
       s_to Video_Store_1;

Object  Video_Store_2 "Video Store"
class  ScoredRoom
with   description [;
           print "You are still in the video store. You can go north, or \
               east.^";
           if (Outside_4 has visited)
               Quip(0,1,CROW,"What the...? I thought we were OUTSIDE \
                   before!",1);
           rtrue;
       ],
       n_to Closet_6,
       e_to Outside_4;

Object  Closet_6 "Closet"
class  BarringerRoom
with   description [;
           print "You are in a closet. There is no use for being \
               here. Gotta go south.^";
           Quip(0,1,TOM,"Why do I get the feeling that Matt Barringer is \
               just padding out the game?",1);
           rtrue;
       ],
       s_to Video_Store_2;

Object  Outside_4 "Outside"
class  BarringerRoom
with   description [;
           print "You are outside. You can go north, south, east, or \
               west.^";
           Quip(1,1,MIKE,"You know, it's the vivid descriptions that \
               make this game come alive.",1);
           rtrue;
       ],
       w_to Video_Store_2,
       s_to McDonalds,
       e_to House,
       n_to Outside_5;

Object  McDonalds "McDonalds"
class  ScoredRoom
with   description [;
           Quip(0,1,CROW,"Boy, I could really go for a hamburger \
               sandwich and some French-fried potatoes!",2);
           print "You are in a McDonalds. You pay the guy behind the \
               counter. ";
           Quip(0,2,MIKE,"Shouldn't you have ordered first?",1);
           Quip(0,0,TOM,"Nah, this is fast food. It all tastes the \
               same.",2);
           print "Now there^is a hamburger there. ";
           if (Food_Hamburger notin self) {
               Quip(0,2,TOM,"By an astounding coincidence, it's the same \
                   one you picked up earlier!",1);
               Quip(0,0,CROW,"This could solve the world hunger problem \
                   in no time!",2);
           }
           "When you have picked it up, go north.";
       ],
       n_to [;
           Quip(0,0,CROW,"Hey, Mike, I just noticed that no one killed \
               us in that restaurant.",1);
           Quip(0,0,MIKE,"Those thugs probably find fast-food franchises \
               to be too low-class.",1);
           return Outside_4;
       ];

Nearby  Food_Hamburger "food hamburger"
class  BarringerObject
has    edible
with   name "food" "hamburger" "burger",
       initial "It is a hamburger wrapped in cheap paper.",
       description [;
           print "It is a hamburger. If you eat it you'll have satisfied \
               that little hunger in your stomach. Go North.^";
           Quip(0,1,CROW,"Umm, well, you can go north assuming you're \
               still in the McDonald's.",1);
           rtrue;
       ],
       after [;
        Take:
           print "You are now carrying the food hamburger.";
           Quip(0,2,CROW,"Is that anything like ~wooden wood?~",1);
           Quip(0,0,TOM,"No, ~wooden wood~ is redundant, whereas \
               calling a McDonald's hamburger ~food~ is an oxymoron.",1);
           Quip(0,0,CROW,"Ah.",1);
           rtrue;
        Eat:
           print "The hamburger slides down your throat, and your \
               stomach is quickly full.^";
           Quip(0,1,TOM,"So how many hamburgers can you eat on an empty \
               stomach?",1);
           Quip(0,0,MIKE,"Only one. After that your stomach isn't \
               empty!",1);
           Quip(0,0,TOM,"D'OH!!",1);
           rtrue;
       ];

Object  House "House"
class  DeathRoom
with   description [;
           print "You enter the house. A man charges down the stairs. \
               Before you even have^time to say anything, he shoots \
               you. You lose!^";
           Quip(-1,1,CROW,"Once again, the social effects of listening to \
               Ice-T's ~Cop Killer~ song.",1);
           rtrue;
       ];

Object  Outside_5 "Outside"
class  ScoredRoom
with   description [;
           print "You are still outside. You hit a dead end, then notice \
               that you can go east only.^";
           Quip(0,1,CROW,"Mike, I'm lost. Where are we?",1);
           rtrue;
       ],
       e_to Music_Store_1;

Object  Music_Store_1 "Music Store"
class  ScoredRoom
with   description [;
           print "You are in a music store. ";
           Quip(0,2,CROWTOM,"No! NO!! NO!!",1);
           Quip(0,0,CROW,"Not Mr. B Natural again!",1);
           Quip(0,0,TOM,"Make it stop, Mike!!",2);
           print "You ask the man behind the counter if he^knew any \
               information.^";
           Quip(0,1,MIKE,"So are we just grasping at straws now?",2);
           print "~Uhh...nope! But the guy back there might be able ta \
               help.~^You politly thank him and head to the back. You \
               can only go north.^";
           Quip(0,1,TOM,"So, was that man behind the counter the STAFF \
               of the music store? Staff? Get it?",1);
           Quip(0,0,MIKECROW,"[Groan]",1);
           rtrue;
       ],
       n_to Back_of_Music_Store;

Object  Back_of_Music_Store "Back of Music Store"
class  ScoredRoom
with   description [;
           print "You are in the back of the music store. ";
           Quip(0,2,MIKE,"Just like the name of this room says.",2);
           print "You ask the guy who's looking^at the cool tapes.^";
           if (Man has general)
               Quip(0,1,TOM,"Hey, you know anything about the guy I just \
                   killed? Did he maybe kill the mayor, or something?",2);
           print "He looks up at you.^~Duh.. no...don't t'ink so...lemme \
               see...~^";
           if (Man has general)
               Quip(0,1,TOM,"Well, thanks anyway.",2);
           Quip(0,1,CROW,"So what exactly did we ask him about?",2);
           "You decide that he's no help. To the west there is a dazed \
           looking man^and to the north there is an exit.";
       ],
       w_to Music_Store_2,
       n_to Alley;

Object  Music_Store_2 "Music Store"
class  BarringerRoom
with   description [;
           print "You walk over to the guy. ";
           if (Man has general)
               Quip(0,2,TOM,"He's already dead and gone, but you walk \
                   over to him anyway.",2);
           print "He jumps up with a wild look, and says^Freeze!~ You \
               stop.  He motions you to the exit.^";
           Quip(0,1,MIKE,"So he doesn't want you to move, yet he wants \
               you to leave?",2);
           print "But you know he'll probably just kill you. You NEED to \
               get the weapon^from him or kill him. Best chance: use \
               your gun.^";
           Quip(0,1,CROW,"Assuming you brought it with you, of course.",1);
           rtrue;
       ],
       initial [;
           if (Man hasnt general) StartDaemon(Man);
       ],
       e_to [;
           if (Man hasnt general) {
               print "The man blocks your way and will not let you leave!^";
               return self;
           }
           return Back_of_Music_Store;
       ];

Nearby  Man "man"
has    animate
with   name "dazed" "man" "guy",
       initial [;
           print "He is a dazed guy. ";
           Quip(0,2,MIKE,"The 60's were good to him.",2);
           "He says ~One more minute mom!~";
       ],
       description "He is a dazed guy. He says ~One more minute mom!~",
       number 3,
       daemon [;
           if (self has general) { StopDaemon(self); rtrue; }
           self.number = self.number - 1;
           if (self.number > 0)
               "^The man seems to be getting angrier!";
           deadflag = 1;
           print "^The man seems to calm down for a moment,^but suddenly \
               attacks.^Its mouth opens to reveal^teeth grotesquely \
               out of proportion to the rest^of its body, a fact you \
               notice as those same^teeth tear your flesh into tiny \
               pieces.^";
           Quip(-1,1,TOM,"What the...?",1);
           Quip(-1,0,CROW,"Are we in a different game all of a sudden?!",1);
           Quip(-1,0,MIKE,"Folks, we have no idea what's going on here, \
               so just undo that last move and forget about it.",1);
       ],
       before [;
        Attack:
           if (Black_Gun notin player) rfalse;
           StopDaemon(self);
           give self general;
           remove self;
           print "You aim the gun at the man and pull the trigger.^It's \
               a direct hit!^The man screeches angrily, and writhes in \
               agony and^fades away in a cloud of green smoke.^"; \
           Quip(0,1,CROW,"Oh, so he was the thief from Zork!",1);
           Quip(0,0,MIKE,"Or maybe the troll.",1);
           Quip(0,0,TOM,"So was that supposed to be the exciting part?",1);
           Quip(0,0,CROW,"No, but it _was_ the game's first puzzle.",1);
           Quip(0,0,MIKE,"Boy, Matt Barringer is the Coleman Francis of \
               Interactive Fiction.",1);
           Quip(0,0,TOM,"This makes ~Space Aliens Laughed at my \
               Cardigan~ look like ~Trinity.~",1);
           Quip(0,0,MIKE,"Hey, I kind of liked ~Space Aliens.~",1);
           Quip(0,0,CROW,"So, if ~Space Aliens~ is Infocom on acid, \
               what's this?",1);
           Quip(0,0,TOM,"Oh, this is Infocom drunk and passed out on the \
               couch.",1);
           rtrue;
       ];

! The game's (only) puzzle makes use of a simple daemon (a timer
! attached to an object, which has some effect each turn).  The daemon
! is activated when the player enters the room with the man in it
! (Music_Store_2).  It has a counter of 3 moves.  A message about the
! man getting angrier appears each turn the player is in the room (and
! he can't leave without killing the man first).  Also each turn, the
! timer variable (stored in the Man's `number' property) is decreased
! by one.  When the time runs out, the man attacks and kills the player.
! If the player shoots the man first, the daemon is permanently stopped
! and the man is removed from the room (but he still appears in the
! room description! B-).
!
! (By the way, I've always wished there were a forklift outside the music
! store, so I could use the "Triiiied to kill him with a fooorkliiiift!"
! song.  But there isn't, so I guess you'll never see it here.)

Object  Alley "Alley"
class  ScoredRoom
with   description [;
           print "You are in an alley. A drunken man stagers up to you \
               and says^Boycott FDR~ <HICKUP>.~^You just walk away. ";
           Quip(0,2,MIKE,"What was THAT all about?",2);
           "You can go north, east or west. Your call.";
       ],
       w_to Mob_House,
       e_to Drug_House,
       n_to Police_Station;

Object  Mob_House "Mob House"
class  DeathRoom
with   description [;
           print "You enter the infamous ~Mob House~. ";
           Quip(-1,2,CROW,"Of pancakes.",2);
           print "When you enter a hugh quiets the^room as guys in ugly \
               pin striped suits look over at you. Fearing for^your \
               live, you turn to run away. But before you can do that, a \
               big thug^comes by with a .44 and shoots you in the head. \
               A grisly death, for sure.^";
           Quip(-1,1,MIKE,"Gee, you'd think the Chief would've told you \
               where these places were, so you could avoid them.",1);
           rtrue;
       ];

Object  Drug_House "Drug House"
class  DeathRoom
with   description [;
           print "You are in a druggies house. ";
           Quip(-1,2,CROW,"Of pancakes.",2);
           print "Guys look over at you.^~Hey~ It's a cop! Get 'im!~ One \
               yells. ";
           Quip(-1,2,TOM,"So how come these guys know you're a cop, but \
               the guys who jumped you in the restaurant didn't know \
               until you flashed your badge?",2);
           print "They all grab their guns^and aim' em at you. When the \
               police find you 2 days later, you are^scattered across \
               the room - literally.^";
           Quip(-1,1,TOM,"So why didn't the other cops get shot when they \
               came in?",1);
           rtrue;
       ];

Object  Police_Station "Police Station"
class  ScoredRoom
with   description [;
           print "You are in the 3rd precinct police station. This isn't \
               your station.^";
           Quip(0,1,MIKE,"So don't put your feet up on the desks.",2);
           print "You get admitance from the guy at the desk^and go to \
               the holding cells.^You ask each offender if they know \
               anything. ";
           Quip(0,2,TOM,"Man, you ARE getting desperate!",2);
           Quip(1,2,CROW,"[Rocket J. Squirrel voice] Again?!",2);
           print "You promise a lighter^sentance for the ones who help. ";
           Quip(1,2,MIKE,"Do you have the authority to do that?",2);
           print "But one guy really sets you straight.^~I got caught \
               wit' t'ree ounces o'crack. ";
           Quip(0,2,CROW,"Okay, so we've got crack _and_ FDR. What decade \
                 is this supposed to be?",2);
           print "I'm supposed to get 20 years^but I'll be out in 2.";
           Quip(0,2,TOM,"[As the prisoner] Cuz I've started diggin' this \
               tunnel so I can -- [As if covering his mouth to keep from \
               saying any more] oop -- Damn!",2);
           print "You can't make me talk cuz it don't matter to me.^If I \
               squeal, da guys ";
           Quip(1,2,ALL,"DA Bears!",2);
           "who did it are gonna come lookin' for me. I know^but I ain't \
           gonna tell ya. Now git outta my face.~^You are surprised but \
           used to it.^You can go north to the outside, south to go back \
           to the alley^and west or east to talk to more guys.";
       ],
       s_to Alley,
       e_to Holding_Cells_1,
       w_to Holding_Cells_2,
       n_to Outside_6;

Object  Holding_Cells_1 "Holding Cells"
class  BarringerRoom
with   description [;
           print "You are talking to more guys. But none tell you what \
               you need to know. You can only go west.^";
           if (self hasnt visited && Holding_Cells_2 hasnt visited)
               "^[Tom and Crow simply start snickering at this.]";
           rtrue;
       ],
       w_to Police_Station;

Object  Holding_Cells_2 "Holding Cells"
class  BarringerRoom
with   description [;
           print "You are talking to more guys. But none of them tell \
               you what you need to know. You can only go east.^";
           if (self hasnt visited && Holding_Cells_1 hasnt visited)
               "^[Tom and Crow simply start snickering at this.]";
           rtrue;
       ],
       e_to Police_Station;

Object  Outside_6 "Outside"
class  ScoredRoom
with   description [;
           print "You are outside. It's bitter cold and you pull your \
               jacket around^yourself. To the north is a nice, warm \
               Holiday Inn hotel, where^the killer is rumored to be \
               staying. ";
           Quip(0,2,ALL,"WHAT?!?",1);
           Quip(0,0,CROW,"Where did we hear THAT?!",2);
           print "Or you could go to his favorite^hang out, the Wall, to \
               the west, or to the east is the place where he \
               is^supposed to be working, the Doughnut King.^";
           Quip(0,1,MIKE,"Wow! And we figured all that out just by \
               entering this room!",1);
           Quip(0,0,TOM,"That was first-class detective work!",1);
           rtrue;
       ],
       w_to The_Wall,
       e_to Doughnut_King,
       n_to Holiday_Inn;

Object  The_Wall "The Wall"
class  ScoredRoom
with   description [;
           Quip(0,1,ALL,"[Sing] ~We don't need no ed-u-ca-tion!~",2);
           print "You don't see him here. You ought to go east.^";
           Quip(0,1,CROW,"Wow! We entered a building without getting \
               killed!",1);
           Quip(0,0,TOM,"So how would we recognize the killer if we saw \
               him? We don't even know who he is!",1);
           rtrue;
       ],
       e_to Outside_6;

Object  Doughnut_King "Doughnut King"
class  ScoredRoom
with   description [;
           Quip(0,1,MIKE,"~Cops~ is filmed live on location at Doughnut \
               King!",2);
           print "You are in the Doughnut King, where the greasiest \
               doughnuts on earth^reside. He isn't here, no one seems to \
               be for that matter, so you should^go west.^";
           Quip(0,1,TOM,"You mean no one's here, and they just left the \
               doors wide open?!",1);
           Quip(0,0,CROW,"Cool! Free coffee for everyone!",1);
           Quip(0,0,MIKE,"[Coffee Guy voice] Coffee? I like coffee!",1);
           rtrue;
       ],
       w_to Outside_6;

Object  Holiday_Inn "Holiday Inn"
class  ScoredRoom
with   description [;
           print "You are in the Holiday Inn registration room. You talk \
               to some^suspicious guys, but they don't talk until you \
               hold your gun to there side^~Allright! Allright! I'll \
               talk! He's on the 15th floor! That's all I can^tell \
               ya!~^";
           Quip(0,1,TOM,"Geez, now you ARE acting like Mitchell!",2);
           print "You shove them away. you walk up to the registration \
               desk and show the^woman there your badge. ";
           Quip(1,2,MIKE,"[As your character] See my badge? Got my \
               picture on it and everything. Cool, huh?",2);
           print "She gives you the master ring. ";
           Quip(0,2,CROW,"[Ominous] One Ring to bring them all and in \
               the darkness bind them!",2);
           print "You now have^access to all of the facilitys on the \
               15th floor.";
           Quip(1,2,CROW,"Good thing, too, because you don't think you can \
               hold it much longer.",1);
           Quip(1,0,TOM,"Should've gone back at the mayor's house.",2);
           print "But the problem^is that the 15th floor is the suite \
               level, and there are 30 suites, and^5 pools, 2 saunas and \
               5 game rooms. Big problem! Well,^you have all night. You \
               get a picture of all on the 15th floor,^the people up \
               there have to show there drivers license to be \
               admitted,^and the license is secretly xeroxed. ";
           Quip(0,2,ALL,"WHAT?!?",1);
           Quip(0,0,MIKE,"Uh...folks, we're completely lost here too.",1);
           Quip(0,0,CROW,"At this point the game has finally thrown up \
               its hands and said, ~I just don't know.~",2);
           "You look at them all. Well, better^get started. You see one \
           person who stands out. You get his room^number from the lady. \
           Room 30. Now you have to find it. To get^started, go north.";
       ],
       n_to Holiday_Inn_15th_Floor;

Object  Holiday_Inn_15th_Floor "Holiday Inn 15th Floor"
class  ScoredRoom
with   description [;
           print "You go up the elevator. When you step out, you see the \
               wallpaper^is pink, with little flowers on it. ";
           Quip(0,2,TOM,"You're a detective, so you're trained to notice \
               stuff like that.",2);
           Quip(1,2,MIKE,"Okay, guys, at this point we need to start \
               piecing together the information we've gathered. So let's \
               make a list of what we've learned.",1);
           Quip(1,0,TOM,"Well, we've learned that the mayor has been \
               murdered.",1);
           Quip(1,0,MIKE,"Right. Anything else?",1);
           Quip(1,0,CROW,"Ummm...no, I think Tom pretty much covered \
                 everything.",1);
           Quip(1,0,MIKE,"Okay, let's get moving then.",2);
           "You can go east or west.";
       ],
       e_to Dead_End_2,
       w_to Hallway_5;

Object  Dead_End_2 "Dead End"
class  BarringerRoom
with   description [;
           print "You hit a dead end. There is a fire extinguesher here, \
               but it is of no^importance to you. ";
           Quip(0,2,CROW,"Because we didn't want to spend time \
               implementing it.",1);
           Quip(0,0,MIKE,"I bet Matt Barringer spent a whole hour \
               writing this game.",1);
           Quip(0,0,TOM,"And no time at all testing it.",2);
           "You can only go west.";
       ],
       w_to Holiday_Inn_15th_Floor;

Object  Hallway_5 "Hallway"
class  ScoredRoom
with   description [;
           Quip(0,1,CROWTOM,"No! No! Not MORE hallways!! Aaaaagh!!",2);
           print "You are in the hallway.  You see many \
               doors...1...2...3...4...5...6....7^";
           Quip(0,1,MIKE,"[Looking behind him] Huh? Are the theater \
               doors closing?",2);
           print "boy, you have a long way to go. You can only go \
               north.^";
           Quip(0,1,MIKE,"But you can go north for a long way.",1);
           rtrue;
       ],
       n_to Hallway_6;

Object  Hallway_6 "Hallway"
class  ScoredRoom
with   description [;
           print "You are still in the maze of hallways. You can go west \
               or east.^";
           Quip(0,1,CROW,"Man, these hallways are the I-F equivalent of \
               ~rock climbing.~",1);
           Quip(0,0,ALL,"DEEEEP HURRRRRTING! DEEEEEP HUURRRRRRTING!!",1);
           rtrue;
       ],
       e_to Dead_End_3,
       w_to Hallway_7;

Object  Dead_End_3 "Dead End"
class  DeathRoom
with   description "You are at a dead end. there is nothing to do but go \
           west.";

! This room is a special case.  There's no explanation whatsoever for the
! player's sudden death here, but the comments should appear after the
! "*** You have died ***" message.  See the `LibraryMessages' definition
! near the start of the code for the comments.

Object  Hallway_7 "Hallway"
class  ScoredRoom
with   description [;
           print "You are in the hallway. You see numbers flash by as \
               you run through the^halls. 19..";
           Quip(0,2,CROW,"Hit me.",2);
           print "20..";
           Quip(0,2,CROW,"Hit me.",2);
           print "21..";
           Quip(0,2,CROW,"Hit me.",2);
           print "22.. ";
           Quip(0,2,CROW,"Damn, I'm busted.",1);
           Quip(0,0,TOM,"Can _I_ hit him, Mike? PLEASE??",1);
           Quip(0,0,MIKE,"Sit tight, guys. It's almost over.",2);
           "you are getting close! You can only go north.";
       ],
       n_to Hallway_8;

Object  Hallway_8 "Hallway"
class  ScoredRoom
with   description [;
           print "You are in the hallway. You fell the heat from the \
               sauna to the west,^and to the east is a door marked^~Pool \
               A~. To the north is more hall.^";
           Quip(0,1,TOM,"Man, I'm starting to long for the good old days \
               of Bert I. Gordon, Roger Corman, and Sandy Frank.",1);
           rtrue;
       ],
       e_to Pool,
       w_to Sauna,
       n_to Room_30;

Object  Pool "Pool"
class  DeathRoom
with   description [;
           print "You are in the pool when the killer shoots you from \
               behind! You lose!^";
           Quip(-1,1,CROW,"But we just wanted to check out the room!",1);
           rtrue;
       ];

Object  Sauna "Sauna"
class  DeathRoom
with   description [;
           print "You are in the sauna when from the steam steps the \
               killer. ";
           Quip(-1,2,MIKE,"Man, that killer is EVERYWHERE!",1);
           Quip(-1,0,CROW,"Like God.",1);
           Quip(-1,0,TOM,"Only evil.",1);
           Quip(-1,0,MIKE,"But he does have the same aura of mystery \
               about him.",2);
           print "You realize the guys downstairs must have tipped him \
               off. ";
           Quip(-1,2,CROW,"The first indication that the author has \
               looked back at any of his previous writing!",2);
           print "~So ya thought ya could get me eh?~^He flashes a \
               gun. Well, let's not get into details.";
           Quip(-1,2,TOM,"Yeah, why start now, this close to the end?",2);
           "You lose.";
       ];

Object  Room_30 "Room # 30"
class  BarringerRoom
with   description [;
           print "You enter room 30...after a harrowing gun battle you \
               conk him on the head^and take him in. ";
           Quip(0,2,TOM,"What the...?",1);
           Quip(0,0,CROW,"That's IT?!?",1);
           Quip(0,0,TOM,"We sat through the whole game for THIS?!?!",2);
           Quip(1,2,MIKE,"Yep, this is the kind of ending that you want \
               to read twice.",2);
           print "You get promoted and suddenly, with the ~Jurassic \
               Park~^theme song playing in your head, you feel proud to \
               be an American.^";
           Quip(0,1,TOM,"So you go home and watch the Whitewater \
               hearings and the O.J. Simpson trial until the feeling \
               passes.",1);
           Quip(0,0,CROW,"And now we've got ~Jurassic Park~ and FDR!",2);
           print "For special info about Exile Games, and to leave this \
               darned game, press^up.^"; \
           Quip(0,1,CROW,"Uh, guys...~darned~ isn't exactly the \
               adjective I'd choose here.",1);
           if (self hasnt visited) score = score + 100;
           rtrue;
       ],
       u_to Info;

Object  Info "Info"
class  BarringerRoom
with   description [;
           print "Exile Games is a group of people who like text games.";
           Quip(-1,2,CROW,"But just aren't very good at making them.",2);
           print "We plan to get into graphic games sometime in 1995.";
           Quip(-1,2,TOM,"God help us all.",2);
           print "We don't ask for money, we just want to know if you \
               like it or not.";
           Quip(-1,2,TOM,"For the last time, we don't!",1);
           Quip(-1,0,MIKE,"If I remember right, they DID ask for money \
               way back at the start.",2);
           print "Our support BBS is (510) 208-5657, the Ghostbuster \
               Central BBS>";
           Quip(-1,2,MIKE,"Who ya gonna call?",1);
           Quip(-1,0,ALL,"GHOSTBUSTERS!",2);
           print "We have accounts on CompuServe and Prodigy.^Exile \
               Games is currently made up of:^^Matt Barringer, president \
               and head programmer";
           Quip(-1,2,ALL,"All hail, Matt Barringer!",2);
           print "Nathaniel Smith, advisor";
           Quip(-1,2,TOM,"[As Nathaniel Smith] Hey, guys, let's make a \
               really crappy text adventure with no puzzles in it!",2);
           print "Kurt Somogue, assistent programmer,";
           Quip(-1,2,CROW,"If you ever meet any of these people, please \
               do us all a favor and put them out of their misery.",2);
           print "And all the users of the Ghostbuster Central BBS, who \
               give me ideas!";
           Quip(-1,2,MIKE,"Uh...Matt, buddy, I think it's time you got \
               yourself some new idea people.",2);
           print "*** Congratulations. You have won the game. ***";
           Quip(-1,2,MIKE,"And the crowd goes wild!",1);
           Quip(-1,0,ALL,"[Subdued] Yaaaaay.",1);
           rtrue;
       ],
       each_turn [ h w i;
           deadflag = 2;
           Quip(-1,0,CROW,"So, do you think this game was hard-boiled, \
               like Dr. Forrester said?",1);
           Quip(-1,0,TOM,"No, I personally thought it was over-easy!",1);
           Quip(-1,0,MIKE,"D'OH!!",1);
           Quip(-1,0,CROW,"Lemme at him, Mike! Lemme at him!",2);
           print "[Crow tries to attack Tom, but Mike stops him.]";
           Quip(-1,2,TOM,"So did either of you guys see anything here \
               remotely connected to detectives?",1);
           Quip(-1,0,MIKE,"Nope, can't say I did.",1);
           Quip(-1,0,CROW,"You know, the AGT parser was _ideal_ for \
               making this game.",1);
           Quip(-1,0,MIKE,"I wonder if Matt Barringer ever considered \
               making the killer more realistic. Like, I dunno, maybe \
               giving him a _name_, or something.",1);
           Quip(-1,0,CROW,"I think there are some questions better left \
               unasked.",1);
           Quip(-1,0,MIKE,"That's a good point, Crow.",2);
           print "[Tom sidles over into Mike's lap.]";
           Quip(-1,2,TOM,"Well, c'mon, guys, we gotta go.",1);
           Quip(-1,0,MIKE,"I still liked this game WAY better than \
               ~Leather Goddesses of Phobos 2.~",1);
           Quip(-1,0,TOM,"Oh, yeah, definitely.",1);
           Quip(-1,0,CROW,"Shut up, Servo. That's not funny!",1);
           Quip(-1,0,TOM,"Geez, what's _your_ problem?",2);
           print "[Mike and the bots leave the \
               theater.]^^1...2...3...4...5...6...G...^^[SOL]^^[Mike and \
               the bots are in their usual places.]";
           Quip(-1,2,MIKE,"Well, when you come right down to it, I \
               thought the writing was one of the strong points of this \
               game.",1);
           Quip(-1,0,TOM,"Oh, for me it was the intense and addictive \
               gameplay that just left you begging for more.",1);
           Quip(-1,0,CROW,"You guys are CRAZY, you know that? Just plain \
               no-holds-barred, out-of-your-minds, seats-of-honor-at-the-\
               local-funny-farm-convention CRAZY! This game was \
               terrible! It was torture! I mean, LOOK AT IT!! You get \
               sent to investigate the mayor's murder, but you never see \
               his body or even learn his name, and his house is \
               scattered with weird useless items preceded by stupid \
               adjectives, including a knife that's there but you ",0);
           Quip(-1,1,CONTINUE,"CAN'T EVEN PICK IT UP!! Then you go through \
               about a million hallways that never lead anywhere, closets \
               that TELEPORT YOU AROUND LIKE THE STARCROSS DISKS, AND IN \
               HALF THE ROOMS YOU GET KILLED SIMPLY BY ENTERING THEM, AND \
               WITH ONE OF THEM YOU LEARN EVERYTHING THERE IS TO KNOW \
               ABOUT THE KILLER SIMPLY BY ENTERING IT, AND THEN YOU RUN \
               THROUGH A MILLION _MORE_ STUPID HALLWAYS AND YOU CATCH \
               THE KILLER AND THAT'S THE _END_!!! BUT YOU ONLY CATCH \
               _ONE_ KILLER, AND THERE'S A NOTE IN THE MAYOR'S HOUSE \
               THAT SAYS THEY'RE A _GROUP_ OF VIGILANTES AND THEN MATT \
               BARRINGER TELLS US TO LOOK IT UP WHEN IT'S PAINFULLY \
               OBVIOUS THAT HE HAS AN EVEN SMALLER VOCABULARY THAN THIS \
               GAME!!!!! AND THEN THERE'S THE SCENE IN THE CELLS WHERE \
               YOU JUST ASK EVERYONE IF THEY KNOW ANYTHING!!!! AND THE \
               MUSIC STORE!!! WHAT THE _HELL_ WAS THE POINT OF KILLING \
               THE GUY IN THE MUSIC STORE?!?!? NOTHING MADE _ANY_ \
               SENSE, I TELL YOU!!!!!! AND WHEN IT'S ALL OVER, YOU DON'T \
               EVEN KNOW _WHY_ OR _HOW_ THE KILLER DID IT!!!!!!!",2);
           print "[Crow continues babbling incoherently.]";
           Quip(-1,2,TOM,"Wow, sounds like he's taking this pretty hard.",1);
           Quip(-1,0,MIKE,"Well, I know what \
               will cheer him up. [Goes over to Gypsy at one of the \
               computers.] Gypsy's been working on another game while \
               we've been in the theater.",1);
           Quip(-1,0,GYPSY,"Yaaaay! ~Richard Basehart Adventure II!~ \
               Yaaaaaaay!!",1);
           Quip(-1,0,MIKE,"C'mon, check it out, Crow!",1);
           Quip(-1,0,CROW,"NO!! YOU KEEP THAT THING AWAY FROM ME!! I'M \
               NEVER TOUCHING ANOTHER TEXT ADVENTURE AGAIN -- NEVER, \
               EVER, EVER, AS LONG AS I LIVE, AND YOU CAN'T MAKE ME!!!!",2);
           print "[Crow storms off the set.]";
           Quip(-1,2,MIKE,"Gee, sounds like Crow's a little upset.",2);
           print "[The mads' light flashes.]";
           Quip(-1,2,MIKE,"Well, I hope you're happy, Dr. F, now that \
               you've alienated him from Interactive Fiction forever.",1);
           Quip(-1,0,TOM,"Yeah, how 'bout a little more science and less \
               mystery next time, huh?",2);
           print "[Deep 13]";
           Quip(-1,2,DRF,"Ah, very cute, my little brass lantern. \
               But do you really think you can quit I-F that easily? \
               Your little friend will come back to it, Nelson, and \
               then I'll send him _another_ game like this. And another! \
               And ANOTHER! [Laughs evilly.] Push the button, Frank. \
               [Pause] Frank?",2);
           print "[Dr. Forrester looks around, and sees that Frank has \
               once again donned the Fictionary helmet.]";
           Quip(-1,2,FRANK,"Sorry, but I can't see any 'button' here.",1);
           Quip(-1,0,DRF,"Oh, will you just drop it, Frank?!",1);
           Quip(-1,0,FRANK,"I'm not carrying that.",1);
           Quip(-1,0,DRF,"[Sighs with exasperation, then picks up a game \
               manual and glances at it.] Okay, let's see now... Ah, \
               here it is! The special magic word that'll make Frank \
               push the button. 'XYZZY.'",2);
           print "[Frank hears Dr. F say it, and pushes the button. The \
               screen goes dark.]";

           ! ASCII graphic effect of "pushing the button", centered on
           ! the screen.  Wait for the player to press a key before and
           ! after.

           @read_char 1 i;
           @erase_window $ffff;
           font off;
           h = (0->32 - 3) / 2;
           w = (0->33 - 5) / 2;
           for (i = 0 : i < h - 1 : i++) new_line;
           spaces w; print "@@92 | /^";
           spaces w; print "--o--^";
           spaces w; print "/ | @@92";
           new_line;
           font on;
           @read_char 1 i;
           @erase_window $ffff;

           Quip(-1,3,FRANKSVOICE,"It is now pitch black. You are likely \
               to be eaten by a grue.",1);
           Quip(-1,0,DRFSVOICE,"I'll get you for this, Frank. I swear \
               it.",1);
           return;
      ];

! The title page, printing an ASCII rendering of the MST3K logo, followed
! by the first of many stupid jokes in this game.  (The `@@92' notation
! is needed to print the "\" character, which is normally reserved for text
! wraparound.)

[ TitlePage  w i;
   do {
     @erase_window $ffff;
     font off;
     w = (0->33 - 22) / 2;
     new_line; new_line;
     spaces w + 5; print "_________^";
     spaces w + 3; print "/           @@92^";
     spaces w + 1; print "/     Mystery   @@92^";
     spaces w; print "|      Science    |^";
     spaces w; print "|      Theater    |^";
     spaces w + 1; print "@@92      3000     /^";
     spaces w + 3; print "@@92___________/^^";
     spaces w + 6; print "Presents^^";
     spaces w + 4; print "~Detective~^";
     spaces w + 9; print "by^";
     spaces w + 3; print "Matt Barringer^^^";
     spaces (w / 2) - (w / 8); print "To read some highly amusing stuff, \
         press <1>.^";
     spaces (w / 2) - (w / 8); print "To read the introduction, then play \
         the game, press <2>.^";
     spaces (w / 2) - (w / 8); print "To skip the intro and go straight to \
         the game, press <3>.^^";
     spaces (w / 2) - (w / 8); print "If you require further help, please \
         stay on the line and^";
     spaces (w / 2) - (w / 8); print "an operator will assist you.^";
     font on;
     do { @read_char 1 i; }
     until (i == '1' or '2' or '3');
     @erase_window $ffff;
     font on;

     if (i == '1') {

       #IfDef SILVER_SCREEN;

         ! An example of menuing with Inform.  Note that the page breaks
         ! and wraparounds must appear exactly as shown here, or Inform's
         ! DoMenu() function will make a mess of it.  The menu is only
         ! displayed if the constant SILVER_SCREEN has been defined.

         DoMenu("Welcome to the MST3K1 ~Silver Screen Edition!~^\
                ^     We Begin with Some Legal Crap that Lawyers Will Enjoy\
                ^     Next, a Welcoming Introduction\
                ^     About the Original MST3K1\
                ^     About the MST3K1 Silver Screen Edition\
                ^     An MST3K Primer\
                ^     Other thoughts on ~Detective~\
                ^     On the Not-Quite-Making of MST3K2\
                ^     An Interview with Matt Barringer!!!^",
               #r$MST_Menu, #r$MST_Info);

       #EndIf;

       #IfNDef SILVER_SCREEN;

         @erase_window $ffff;
         print "^^[This game was compiled by someone with no sense of \
             humor, and the amusing essays were left out.]^^[Press a key.]";
         @read_char 1 w;

       #EndIf;

       ! The following lines prevent the "[MORE]" prompt from appearing
       ! every few lines after the menu system is exited (which doesn't
       ! hurt anything, but looks really terrible).  A big MST3K "Hi
       ! Keeba!" to Jools Arnold for sharing this little trick.

       @buffer_mode 1;
       @set_window 0;
       @erase_window -1;
       font on; style roman;
       DrawStatusLine();
     }
   }
   until (i == '2' or '3');
   if (i == '2') Intro();
   rfalse;
];

[ Intro  i;
   @erase_window $ffff;
   print "^^1...2...3...4...5...6...G...^^[SOL]^^[Crow, Gypsy, and Tom \
       Servo are each seated in front of a computer. Mike appears in \
       front of them.]";
   Quip(-1,2,MIKE,"[to Cambot] Oh, hi everyone, and welcome to the \
       Satellite of Love. I'm Mike Nelson. My robots Crow, Tom Servo, \
       and Gypsy recently got ahold of an I-F programming language \
       called Inform, and they're just about to unveil their very first \
       text adventures. Let's take a look.",1);
   Quip(-1,0,CROW,"[Excited] Oh! Oh! Me first! Me first! Oh, oh, oh! Me, \
       me, me!",1);
   Quip(-1,0,MIKE,"Would you like to go first, Crow?",1);
   Quip(-1,0,CROW,"[A bit reluctantly] Ummm...well, I guess so.",1);
   Quip(-1,0,MIKE,"Okay, let's see what you've got. [Reads.] ~The roar of \
       rotating blades thunders in your ears as the chopper descends \
       into the thick undergrowth of the jungle below. Fearlessly, you \
       strap on a belt laced with grenades and sling your M-16 over your \
       shoulder, the urge to kill quickening your pulse until you feel \
       positively invincible. The chopper swings into a landing, and you \
       leap out, determined to rescue the POWs and prove yourself a hero \
       to the proud nation in which you were born and raised.~ Wow, this \
       is really exciting, Crow. Great introduction.",1);
   Quip(-1,0,CROW,"Umm, it's not done yet, Mike.",1);
   Quip(-1,0,MIKE,"Oh, there's more? [Taps the <Enter> key, then \
       continues reading.] ~A squadron of armed enemy troops, dressed in \
       camouflauge, leap out of the surrounding undergrowth. You fire \
       round upon round at them, lacing each body with a string of \
       bullets that shatters bones and sprays the nearby foliage a \
       bright crimson. When the last one drops dead at your feet, you \
       race through the jungle to a village of grass huts, plastering \
       any who dare stand in your way. The earth is stained red with the \
       blood of the enemy!~",1);
   Quip(-1,0,CROW,"[Interrupting] This is my favorite part, right here!",1);
   Quip(-1,0,MIKE,"[Continues reading.] ~Emerging into the village, you \
       dodge gunfire while lobbing grenades at enemy soldiers! \
       Explosions rock the land! Bullets and bodies fly everywhere! The \
       carnage continues for hours. Then, suddenly, a profound \
       silence. You race into the center of the POW camp and smash open \
       the front gates. You lead the prisoners back to the clearing, \
       where the chopper is waiting. You fly back to the states and are \
       awarded the Medal of Honor for your heroism! Congratulations!~",1);
   Quip(-1,0,CROW,"[Pleased] Well? Whadya think?",1);
   Quip(-1,0,MIKE,"Umm, Crow? Don't you think this game could use a few \
       puzzles?",1);
   Quip(-1,0,CROW,"[A little embarassed] Oh yeah, heh heh. I guess I sort \
       of got carried away there. I was watching ~Rambo~ earlier, and \
       one thing led to another...",2);
   print "[The commercial sign light flashes.]";
   Quip(-1,2,MIKE,"We'll be right back.",2);
   print "[It's once again time for the wacky exploits of Mentos, the \
       Freshmaker!]^^[After the commercials, show Mike and the bots, as \
       before.]";
   Quip(-1,2,MIKE,"Well, I thought it was a good first try, Crow.",1);
   Quip(-1,0,CROW,"Really? You really liked it, Mike?",1);
   Quip(-1,0,MIKE,"Of course I did. Now let's see what Gypsy's been up \
       to. [Reads Gypsy's screen.] ~Richard Basehart Adventure, by \
       Gypsy.~",1);
   Quip(-1,0,GYPSY,"Yaaaaay! Richard Basehart! Richard Basehart!",1);
   Quip(-1,0,MIKE,"[Calms Gypsy down, then continues reading.] ~You are \
       standing in Richard Basehart's house. Richard Basehart is here.~ \
       Okay, let's see... [Types.] ~EXAMINE RICHARD BASEHART.~ [Reads.] \
       ~You see nothing special.~ Well, let's try... [Types.] ~TALK TO \
       RICHARD BASEHART.~ [Reads.] ~Nothing happens.~ Hmmm. Would you \
       mind giving me a clue here, Gypsy?",1);
   Quip(-1,0,GYPSY,"~KISS RICHARD BASEHART?~",1);
   Quip(-1,0,MIKE,"[Types.] Okay, ~KISS RICHARD BASEHART.~ [Reads.] It \
       says, ~You win.~",1);
   Quip(-1,0,GYPSY,"Yaaaaaay! Richard Basehart! Richard Basehart! \
       Yaaaaaaay!",1);
   Quip(-1,0,CROW,"That's IT?! Geez, not very good.",2);
   print "[Gypsy starts crying. Mike tries to comfort her.]";
   Quip(-1,2,TOM,"Oh, you're really one to talk, Crow. At least she \
       included some actual interactivity in hers!",1);
   Quip(-1,0,CROW,"Ahh, bite me, Servo!",2);
   print "[The two bots start fighting, but Mike breaks it up.]";
   Quip(-1,2,MIKE,"Cut it out, guys. We still haven't seen Tom's game \
       yet.",2);
   print "[Crow peers at Tom's computer, then laughs.]";
   Quip(-1,2,CROW,"Check this out, Mike! His screen's completely blank! \
       He hasn't typed a thing! [Snickers to himself.]",1);
   Quip(-1,0,TOM,"I can't help it! My arms don't work!!",1);
   Quip(-1,0,CROW,"Loser.",1);
   Quip(-1,0,TOM,"[On the verge of tears.] Shut up, just SHUT UP!!",2);
   print "[They start fighting again. Gypsy continues crying for Richard \
       Basehart. The mads' light begins flashing.]";
   Quip(-1,2,MIKE,"Uh-oh, cool it, guys. Looks like Duncanthrax and \
       Dimwit Flathead are calling.",2);
   print "[Deep 13]^^[Dr. Forrester and TV's Frank are standing in the \
       foreground.]";
   Quip(-1,2,DRF,"Ah, greetings, ~Aunt Jemima.~ I see you and your little \
       friends have discovered the joys of Interactive Fiction. Guess I \
       have no choice but to reveal to you the darker side of it with \
       this week's experiment! But first, the Invention Exchange. \
       Frank?",2);
   print "[Frank pushes a cart with a computer, electronic helmet, and \
       another strange device into the foreground.]";
   Quip(-1,2,FRANK,"Thanks, Steve. Well, Mike, as you know, one of the \
       biggest frustrations with text adventures is the terminology. \
       Let's face it, sometimes you  just can't guess what words the \
       author wants you to use when you type  your commands.",1);
   Quip(-1,0,DRF,"That's why we've come up with this little device I like \
       to call the ~Fictionary.~ Basically, it's a translator that feeds \
       the recognized vocabulary of an adventure game directly into your \
       brain. That way, you always know which words will work and which \
       ones won't.",1);
   Quip(-1,0,FRANK,"See, how it works is, one end of the Fictionary \
       [Indicates the strange device.] has a coax cable running into \
       this cyber-helmet you wear over your head. [Puts the helmet on.] \
       The other end is wired to the hard drive and motherboard of this \
       computer, and it interprets the game file and sends the processed \
       vocabulary directly into your mind.",1);
   Quip(-1,0,DRF,"[To Mike] It's really quite technical, booby, so don't \
       strain your little mind trying to comprehend it.",1);
   Quip(-1,0,FRANK,"Here, check it out.",2);
   print "[Frank switches the machine on, then just stands there.]";
   Quip(-1,2,DRF,"Frank?",1);
   Quip(-1,0,FRANK,"Sorry, but I don't know the word 'Frank.'",1);
   Quip(-1,0,DRF,"[A little alarmed] Frank, what's happening?",1);
   Quip(-1,0,FRANK,"Sorry, but I don't know the word 'happening.'",1);
   Quip(-1,0,DRF,"What the...? [Opens the computer case and looks \
       inside.] Frank, you numbskull, you wired it all wrong! \
       [Explanatory, to Mike and bots.] It's sending the parser itself \
       into his brain. Right now, Frank thinks he's a ZIP interpreter.",1);
   Quip(-1,0,FRANK,"I don't understand. Please try rephrasing that.",1);
   Quip(-1,0,DRF,"[A little embarrassed] As you can see, we still haven't \
       gotten all the bugs worked out...",1);
   Quip(-1,0,FRANK,"I can't go that way.",2);
   print "[Dr. Forrester sighs, and switches the machine off. Frank \
       shakes his head and looks around, disoriented.]^^[SOL]";
   Quip(-1,2,TOM,"Wow. Now THAT'S weird.",2);
   print "[Mike has brought one of the bots' computers into the \
       foreground, and there is a device with two robotic arms connected \
       to the terminal.]";
   Quip(-1,2,MIKE,"Well, Dr. F, here's our invention. Basically, we've \
       come up with a fun new method of measuring force between two \
       objects in contact with each other.",1);
   Quip(-1,0,CROW,"See, you take two objects, such as this box of Wild \
       Rebels cereal and Joey the Lemur, load one into each of these \
       arms here... [Mike does so] ...and run a simple computer \
       program.",2);
   print "[Mike types on the terminal. The two arms begin moving back \
       and forth, rubbing the two objects against each other. A piece of \
       paper slides out of a printer attached to the computer.]";
   Quip(-1,2,MIKE,"As you can see, it analyzes the forces at work and \
       presents you with a whole sheet of raw data based on its \
       observations. We call it ~Interactive Friction!~",1);
   Quip(-1,0,CROW,"And the computer program is a ~SLIP Interpreter!~",1);
   Quip(-1,0,TOM,"What do you think, Sirs?",2);
   print "[Deep 13]";
   Quip(-1,2,FRANK,"~Interactive Friction?~ I don't get it.",1);
   Quip(-1,0,DRF,"[Dismissively] Oh, never mind, Frank. They're just \
       toying with you. [Turns back to face Mike and the bots.] Well, \
       ~Michael Berlyn,~ your experiment today is a little piece of \
       Interactive Tripe with an astoundingly infantile storyline and no \
       puzzles to speak of.",2);
   print "[SOL]";
   Quip(-1,2,TOM,"[Sarcastially, to Crow] Now why does _that_ sound \
       familiar?",1);
   Quip(-1,0,CROW,"Don't make me hurt you, Servo.",2);
   print "[Deep 13]";
   Quip(-1,2,DRF,"[Continuing] It's a hard-boiled little program called \
       ~Detective,~ and it will make you wish you'd never _heard_ of \
       text adventures. And so, as the Implementors say, ~Feel Free~ -- \
       to DIE! [Laughs evilly.] Frank, send them the game.",2);
   print "[While Dr. Forrester has been talking, Frank has slipped the \
       Fictionary helmet onto his head again.]";
   Quip(-1,2,FRANK,"Sorry, but I don't know the word 'game.'",1);
   Quip(-1,0,DRF,"[Sighs.] Frank, do you really want me to kill you a \
       third time today?",1);
   Quip(-1,0,FRANK,"Sorry, but I don't know the word 'today'.",1);
   Quip(-1,0,DRF,"Do you know the word 'PAIN,' Frank? Endless, intense, \
       excruciating PAIN? Now take that thing off and push the button!",1);
   Quip(-1,0,FRANK,"[Looks around.] Sorry, but I can't see any 'button' \
       here.",1);
   Quip(-1,0,DRF,"[Exasperated] Oh, for the love of God...",2);
   print "[He pushes the button himself.]^^[SOL]";
   Quip(-1,2,MIKE,"Oh, we've got MOVIE SIGN!!!",2);
   print "[General chaos ensues.]^^[Press a key.]";
   @read_char 1 i;
   @erase_window $ffff;
];

#IfDef SILVER_SCREEN;

! Menu control

[ MST_Menu;
   switch (menu_item) {
     0: item_width = 23;
        item_name = "Mystery Science Theater 3000, Game 101, Reel 1!";
        return 8;
     1: item_width = 5; item_name = "Legal Crap";
     2: item_width = 8; item_name = "Welcome to MST3K1";
     3: item_width = 6; item_name = "About MST3K1";
     4: item_width = 15; item_name = "About the Silver Screen Edition";
     5: item_width = 3; item_name = "MST 101";
     6: item_width = 9; item_name = "Thoughts on ~Detective~";
     7: item_width = 15; item_name = "The Not-Quite-Making of MST3K2";
     8: item_width = 16; item_name = "Interview with Matt Barringer!!!";
   }
];

! And finally, the menu items.

[ MST_Info i;
   switch (menu_item) {
     1: "^MST3K1 is distributed by the author as freeware, and may be \
        distributed by people other than the author as freeware, provided \
        it really IS distributed as freeware, meaning that no \
        modifications are made and no direct profit is involved. (Right, \
        like anyone would actually pay money for this thing.)^^That said, \
        please excercise your right to distribute MST3K1.  Transfer it to \
        all computer platforms. Give it to relatives, neighbors, friends, \
        enemies, professional acquaintances, and people on the street \
        you've never seen before in your life. Upload it to your favorite \
        archive or BBS. Place a link to it on your Web page. Send it \
        around the world as part of a chain letter. Offer it up as a \
        sacrifice to the deity of your choice. Or don't. See if I care.^^\
        BUT!! Because MST3K1 is free, no warranty of any sort is \
        expressed or implied. All I can say is that I'm reasonably certain \
        it won't send your system plummeting into electronic flatline. \
        Computer software is inherently complex (though not MST3K1 \
        specifically), and I can't predict how it will run on all systems.\
        ^^A number of brand names and/or trademarks are used in MST3K1, \
        but most of them are not identified as such. So I'm offering a \
        plea to those big heartless corporations to just once NOT be big \
        heartless corporations, and don't go suing me trying to wring out \
        money I haven't got. Really, I'd think you'd welcome and \
        appreciate free advertising of your products. I mean, some of you \
        sell people those T-shirts bearing your product name and logo -- \
        and people actually PAY for the privilege of becoming a walking \
        billboard bearing your product! Is that stupid or WHAT?! The only \
        difference is, I'm doing it for free.^^At any rate, I'd better \
        include this one at the very least:^^Mystery Science Theater 3000, \
        the MST logo, and all related characters are trademark and \
        copyright 1995 of Best Brains, Inc. and are used here without \
        permission for satirical purposes only. Think about it, won't you? \
        Thank you.";
     2: "^Submitted for your approval: The MST3K1 Silver Screen Edition, an \
        updated version of an updated version of a satirical version of \
        Matt Barringer's really-not-all-that-good game, ~Detective~, \
        featuring the cast of the cable-television show ~Mystery Science \
        Theater 3000.~ This re-re-rerelease features the original MiSTing \
        of ~Detective~, plus some various essays and writings I've saved \
        over the last year, compiled for your reading pleasure. A stroke \
        of brilliance, or a cheesy attempt to squeeze further publicity \
        from a game that's long past its prime? You decide.";
     3: print "^The original MST3K1 was my entry in the 1995 I-F \
            competition.  The concept itself was stolen not only from the \
            television show ~Mystery Science Theater 3000,~ but from Graeme \
            Cree's review in SPAG #5 of a game by a certain Matt Barringer, \
            entitled ~Detective.~^^Cree suggested that the game would make \
            perfect fodder for the MST3K crew, but I don't think he \
            expected anyone to take his suggestion as seriously as I did. \
            At the time I was working on (SHAMELESS SELF-PROMOTION!!!) ~The \
            Path to Fortune~ with co-author Jeff Cassidy, who also happens \
            to be my cousin, though he'll probably deny it if you ask him.^^\
            MST3K1 came about due to a delay in the delivery of the game \
            text Jeff was writing at the time. It was about two weeks \
            before the competition deadline (I know, I said one week in the \
            SPAG interview, but I was wrong, okay? OKAY!?!) and something \
            was needed to fill my unoccupied time and keep me off the \
            streets.^^Awhile back I'd played Matt Barringer's ~Detective~ \
            myself, and, inspired by Graeme's review, began thinking of the \
            sort of comments I thought Mike and the 'bots would make if \
            they played it. I e-mailed Graeme to ask if it was okay if I \
            swiped his idea. He said it was, and added that it'd make a \
            great entry for the upcoming I-F competition.  I wasn't \
            planning to enter due to lack of time (with ~The Path to \
            Fortune~ getting underway), but as ~Detective~ isn't exactly \
            the most complex piece of software on the archive, I decided a \
            port of it, with MST3K comments added, would indeed work well.";
        print "^^The translation began by playing through the original AGT \
            ~Detective,~ keeping transcripts along the way. It was a pain, \
            and I was constantly restarting because of all the \
            instant-death rooms that kept kicking me right out to the DOS \
            prompt (I will NEVER upgrade to Windows 95, and ya can't make \
            me, so there!). By the time it was all done I was sick of the \
            game, so I relished the opportunity to rip it to shreds. About \
            half the comments in the final version came during my first \
            pass through the transcripts, and the rest popped into mind \
            during the actual programming.^^";
        print "Several people have asked me about my own personal favorite \
            lines from the game, so I'll answer them here. My all-time fave \
            is the part about the amazing largeness of the mayor's \
            amazingly large house. That one popped into my head as I was \
            reading the transcripts, and I laughed so hard it hurt -- I \
            mean, it physically HURT! Second place would have to be the egg \
            joke at the end (~hard-boiled~ vs. ~over-easy~), which is also \
            runner-up in the category of Most Hideously Brilliant I-F Pun \
            of 1995 (second only to Jigsaw's ~absinthe makes the heart grow \
            fonder~). I also like the McDonald's stuff, and the bit about \
            the wallpaper.^^The whole process, from transcripting to \
            programming to testing and debugging, took slightly less than \
            four days. (I was new to Inform at the time.) I uploaded MST3K1 \
            several days before the competition deadline, and received very \
            favorable feedback from the start. MST3K1 ended up taking 4th \
            place in the Inform division, and a total of three reviews of \
            it were printed in SPAG #7 (one by Graeme Cree himself), making \
            it the most reviewed entry of the 1995 competition. That says \
            something, but I'm not sure what.^^";
        "Shortly after the competition, Gareth Rees, having far too much \
        free time on his hands, helped me modify the original MST3K1 source \
        code into a comprehensible format. (Aww, who'm I kidding? He \
        rewrote it completely by himself! If ever you want a good laugh at \
        my expense, dig up the original hideously sloppy and repetitive \
        source code. It should still be in the /competition95 directory at \
        GMD. I think Volker Blasius keeps it around just to humiliate me. \
        Hoo boy was it bad. Bad bad bad bad bad. Matt Barringer himself \
        couldn't have done a worse job of programming.)^^Gareth also wrote \
        a recent SPAG review (issue #8) of MST3K1, but it sort of got \
        off-track, going from the nature of MiSTing to other forms of I-F \
        satire. People do that sometimes. They start talking about one \
        thing and just go off on some irrelevant tangential topic. My \
        grandmother (on my mother's side) does that sometimes. We'll be \
        having dinner, and she'll just say something completely \
        off-the-wall. Like this one time, when the rest of us were talking \
        about some friend of theirs who was in the hospital, she blurted \
        out some nonsense about how wiggly the Jell-O brand gelatin \
        dessert was. Old people are weird. Just thought I'd point that \
        out.  We now return to our regularly scheduled MST3K game.";
     4: "^This release was uploaded to GMD on August 15, the one-year \
        anniversary of the uploading of the original MST3K1. I don't know \
        why I did that, except that Graham Nelson used that technique with \
        Inform 6 and I guess I just didn't want to feel left out.^^This \
        release is identical to the previous release, with a couple of \
        exceptions that make it not identical to the previous release. \
        First, I've revised the title screen a bit, making it look more \
        like the show's logo. Second, I've added the copyright notice, \
        which was accidentally left out when I re-compiled the game with \
        Gareth's code, so technically the show's producers could have sued \
        me during that time. Too late though, it's gone now, nyah nyah \
        nyah! And it's not like I have any money to give you if you DO \
        decide to sue me. Anyway...where were we?...Third, I've added \
        these asinine little essays to the game, including some UseNet \
        posts by fans and one on the not-quite-making of MST3K2, a \
        follow-up to MST3K1 (hence the number 2 appended to the end as \
        opposed to the 1) which I began but never finished.  Fourth and \
        finally, I've replaced the text ~FINAL CLIP~ at the end of the \
        game with the word ~STINGER,~ as that's the term used by the MST3K \
        crew to refer to those little clips they show at the ends of \
        shows. (I learned that from the ~MST3K Amazing Colossal Episode \
        Guide~, the book about the show by the show's writers, which is \
        actually quite a good read.)^^And that's all. In the interest of \
        preserving the game in its original condition, no new comments \
        about ~Detective~ have been added. (Sorry to make you sit through \
        all this other stuff before telling you that.)";
     5: print "^For the uninitiated souls who have never seen MST3K, here's \
            a quick lesson:^^MST3K features a man trapped up in a satellite \
            called the Satellite of Love, forced by evil scientists to \
            watch really bad movies so they can study his reactions.  The \
            characters include:^^";
        style bold; print "Mike Nelson"; style roman;
        print "^Mike is an ordinary man, not from Green Bay, Wisconsin, who \
            was working as a temp for mad scientists Dr Clayton Forrester \
            and TV's Frank (whom I'll get to in a minute). When Joel \
            Robinson (played by Joel Hodgson, the original host of MST3K, \
            who left the show to work on other things -- most recently \
            HBO's ~The TV Wheel~, easily one of the five weirdest damn \
            things I've ever seen in my life) escaped from the Satellite, \
            the mads needed a replacement and sent Mike up to take his \
            place.^^";
        style bold; print "Crow T. Robot"; style roman;
        print "^Crow is a yellow-gold robot with a head made out of a \
            lacrosse helmet and a beak make of a bowling pin cut in half. \
            He has yellow ping-pong balls for eyes and fancies himself a \
            screenwriter.  In the theater, Crow sits on Mike's right, at \
            the far right edge of the screen.^^";
        style bold; print "Tom Servo"; style roman;
        print "^Tom is a short plump robot with a head made from a red \
            gumball machine and a little plastic barrel chest.  His arms \
            are on Slinkies (which hop down stairs, alone or in pairs, and \
            make a slinkety sound (See what I mean about the free \
            advertising?)), and he has a hoverskirt instead of legs. Mike \
            has to carry Tom in and out of the theater, because the air \
            grate in the floor interferes with his hoverskirt. Tom sits on \
            Mike's left.^^";
        style bold; print "Gypsy"; style roman;
        print "^Gypsy is like a big snake, with a big purple head made out \
            of a child's car seat, and a single flashlight for an eye. She \
            has a fondness for Richard Basehart (best known from ~Voyage to \
            the Bottom of the Sea~). Gypsy doesn't watch the movies with \
            Mike, Crow, and Tom, but instead runs the higher functions of \
            the Satellite of Love.^^";
        style bold; print "Cambot"; style roman;
        print "^Cambot films everything on the SOL and in Deep 13 (the lair \
            of the mad scientists). He's hardly ever seen, but helps Mike \
            and the other 'bots with short skits that make fun of some of \
            the movies.^^";
        style bold; print "Dr. Clayton Forrester"; style roman;
        print "^Dr. Forrester is one of the mad scientists in Deep 13. He \
            wears a bright green labcoat and green glasses, and has wild \
            hair and a mustache. Forrester's favorite pastime is watching \
            Mike hurt from the terrible films he's forced to watch. His \
            nemesis is his mother.^^";
        style bold; print "TV's Frank"; style roman;
        "^Frank is Forrester's not-too-bright assistant, picked up by the \
        good doctor at a local Arby's after Dr. Laurence Erhardt \
        (Forrester's original assistant) was reported missing at the start \
        of the show's second season. Frank's trademark is a single curl of \
        hair that hangs down in the center of his forehead. Dr. Forrester \
        uses Frank as the subject of some of his experiments, and has \
        killed him quite a few times.";
     6: print "^I've received quite a bit of feedback on the game, mostly \
            statements of how much people have enjoyed laughing themselves \
            sick over it. Two UseNet posts, though, are worth reprinting \
            here, the first from the other author to do a TV adaption for \
            the 1995 competition, our very own Jacob Weinstein:";
        LineAcross();
        print ">A walkthrough is packaged with the original competition \
            version, mst3k1.zip.^>Look in \
            if-archive/infocom/compilers/examples/mst3k1.zip.^>^>BTW, I was \
            kidding about it being very thorough and tying together all the^\
            >complicated details of the murder.  But you knew that, didn't \
            you?^^Oops. Actually, I didn't. I imagined a very funny walk \
            through that would make up a semi-plausible explanation for all \
            the random plot threads:^^~Yes, it seemed odd to me that, when \
            I picked up the gun, it still seemed to be on the floor. I now \
            realize that the mayor was murdered because he stumbled onto a \
            secret military base, working on a secret project to create \
            holographic weapons imagery. The rogue military officer in \
            charge of the project is headquartered in the local TGI \
            Friday's, which is why the men at the door will kill anybody \
            who tries to enter.^^I began to suspect the presence of the \
            project when I started describing objects to myself with \
            phrases like 'wooden wood.' Obviously, my subconscious was \
            trying to tell me that I couldn't trust my senses, that things \
            weren't what they seemed.^^And when I found a knife -- possibly \
            the murder weapon -- only to have it vanish every time I \
            interacted with it, I _knew_ the local military base must be \
            involved.^^But why, I wondered, did the Mayor have two large \
            beds in the guest bedroom, facing the TV? Perhaps the rumors \
            were true that the Mayor would invite prominent politicos over \
            to his house and, in the middle of the night, startle them by \
            playing videotapes of their deepest secrets over the screen.^^";
        print "But the mayor wasn't just a blackmailer -- he was a \
            blackmailee. Those 10 pairs of high heels in his closet meant \
            only one thing; the stories about his cross-dressing \
            proclivities were true.^^This investigation was getting dirtier \
            by the minute, and I wasn't the only one who knew it. In an \
            attempt to stymie the investigation, the mayor's family was \
            ~remodeling~ the upstairs, and the pressure was on from above \
            not to interfere. Somebody had something to hide. Who? I was \
            going to find out.^^";
        print "There was only one way I could untangle the threads before \
            somebody else cut the whole cloth into little itty bitty pieces \
            of lies. The connection between the mayor and the military base \
            was a crooked music producer named Milt Milton. He had given \
            payola to everybody in town -- including the mayor and the \
            rogue general. If I wanted to find anything out, I was going to \
            have to start there.^^I headed over to the local music store; \
            my contact there always knew something about what Milt was up \
            to.^^But when I got there, I found out that the general had \
            gotten there first. Besides the holographic-weapon project, the \
            base was rumored to be working on creating an army of \
            werewolves -- and my contact had been turned into one. I shot \
            him, and moved on.~^^Yes, that's the sort of thing I was hoping \
            your so-called detailed walkthrough would have. But now I find \
            I've been cruelly tricked, and I'll never know just who shot \
            the mayor.^^  - Jacob";
        LineAcross();
        print "I know, Jacob, I know. But the fact that the killer remains \
            unidentified only reinforces the dark humanistic qualities of \
            ~Detective~ that continue to haunt my worst nightmares. George \
            Caswell elaborates:";
        LineAcross();
        print "> Well, there's always the extreme example of puzzle-less \
            I-F, namely, Matt^> Barringer's ~Detective.~ Then again, it \
            doesn't really have a plot either.^^Oh yeah? There was that guy \
            who died... That guy who was mayor, I think... You were on a \
            quest to provide him some dignity -- since no one could tell \
            who he was, it was decided the only way to provide this poor \
            lost soul with the peace and humanity he so richly deserved in \
            his (poorly-implemented) afterlife was to define him through \
            the circumstances of his death... (Of course, the circumstances \
            of his death could have been as simple as taking a wrong turn \
            going to McDonald's... but...) In the process, the player \
            experiences a great deal of personal growth, sees strange \
            sights and events, gets to passively interact with the \
            Audio-Animatronics which populate the city. He experiences \
            spatial paradoxes, optical illusions, danger, intrigue... he \
            feels the spirit of rebellion against society of the man in the \
            cell, he feels the helplessness of the city which is without \
            its nameless leader, he feels the intense boredom of the guy \
            who gives him a cheeseburger, he feels the bizarre and \
            arbitrary madness of the madman west of north of the video \
            store... He feels the need to ask people, arbitrarily, about \
            the murder... (Remember the video store clerk?) And finally, \
            the personal growth and experience so draws in the player that \
            he can determine where the murderer is...^^(Yes, I'm talking \
            about the same ~Detective~... I'm just going on a sarcastic \
            rant... <g>)";
        LineAcross();
        "Well, DUH!!^^Just kidding, George.  Thanks for a great little \
        post.  You too, Jacob.";
     7: print "^This is the intro to MST3K2, which is about all I did \
            before I decided to call it quits.  At the time, the target \
            for ridicule was ~The Caverns of Chaos~ \
            (ftp.gmd.de://if-archive/games/pc/cavchao2.zip, for those of \
            you who've sunk to the most despairing level of desperate \
            fanaticism).^^I MiSTed the game's intro, and got a few mildly \
            amusing comments on the game itself before realizing that, \
            although its crude IF-THEN-ELSE structure represented the \
            simplest form of branching fiction, the game was so sloppily \
            programmed, with GOTOs and such all over the place, that an \
            exact Inform replica would be virtually impossible. At that \
            point I gave it up, which I suppose is for the best. My \
            observations indicate that most bad I-F is either too \
            sloppily programmed (~Caverns,~ ~Space Aliens Laughed at my \
            Cardigan~) or too minimalist (the truly wretched two-word \
            parser games) to allow for effective MiSTing.^^MST fans will \
            no doubt notice Frank's presence here.  Keep in mind that I \
            wrote this at about the same time as the first, after Frank (on \
            the show) had been taken up to Second Banana Heaven by the \
            Arcangel Torgo, but before any episodes were shown from the \
            seventh season.  Having no real idea of what the seventh season \
            would be like, I stuck with what I did know.^^Okay, I've said \
            my bit.  Here we go:";
        LineAcross();
        print "1...2...3...4...5...6...G...^^[SOL]^^[Crow is typing on a \
            computer.]";
        Quip(-1,2,CROW,"[Calls off to the left.] Okay, it's ready!",2);
        print "[Mike enters.]";
        Quip(-1,2,MIKE,"[To Cambot.] Oh, hi everyone. Mike Nelson here, on \
            the Satellite of Love. Crow T Robot here is just about to show \
            me the latest update of his first I-F adventure.",0);
        Quip(-1,1,CROW,"I think you'll really like it this time. I've added \
            a map and puzzles and everything! See for yourself. [He moves \
            so that Mike can sit.]",0);
        Quip(-1,1,MIKE,"[Reads.] ~The roar of rotating blades thunders in \
            your ears as the chopper descends into the thick undergrowth--~",
            0);
        Quip(-1,1,CROW,"[Interrupting.] I haven't changed the intro.  You \
            can just skip it.",0);
        Quip(-1,1,MIKE,"[Taps <ENTER> a few times.] Okay, let's see...  \
            [Reads.] ~Suddenly, an armed soldier leaps out of the brush and \
            points a rifle at your head.~ [Types.] ~SHOOT SOLDIER.~ \
            [Reads.] ~The soldier collapses in a twisted heap, in a pool of \
            his own blood. Another soldier leaps out of the brush and \
            points a rifle at your head.~ [Thinks a moment, then types.] \
            ~AGAIN.~ [Reads.] ~The soldier collapses in a twisted heap, in \
            a pool if his own blood. Another soldier leaps--~",0);
        Quip(-1,1,CROW,"Well? How's it look?",2);
        print "[The commercial sign light flashes.]";
        Quip(-1,2,MIKE,"[Still reading and typing.] ~ANOTHER soldier leaps \
            out of the brush and--~",0);
        Quip(-1,1,CROW,"[To Cambot.] Umm, we'll be right back.",2);
        print "[Show about 69,105 commercials for shows on Comedy Central.]\
            ^^[Mike and Crow, as before. Crow looks hurt.]";
        Quip(-1,2,MIKE,"C'mon, Crow, it's a good start, but you need to put \
            more variety into your puzzles.",2);
        print "[Tom enters from the right.]";
        Quip(-1,2,CROW,"I guess you're right. But, hey, did I tell you my \
            title? I'm calling it ~Your Mother Wears InfoCombat Boots.~ Get \
            it?",0);
        Quip(-1,1,TOM,"Yeah, but I wish I didn't.",0);
        Quip(-1,1,CROW,"Who asked you, Bubble-Head?",0);
        Quip(-1,1,MIKE,"[Seeing the fight coming and trying to stop it.] \
            Okay, okay, let's not start this again.",0);
        Quip(-1,1,CROW,"[To Tom.] I'll get you later, mister. [Moves to \
            type on the computer.] Check this out, too, Mike. I realized \
            the interactive potential of some of my old screenplays, so I \
            dug 'em out and started adapting them. [Moves aside so Mike can \
            see the screen.] This is my first one. ~Earth vs. Soup \
            Interactive!~",0);
        Quip(-1,1,TOM,"You have GOT to be kidding me. ~Earth vs. Soup \
            INTERACTIVE?!~",0);
        Quip(-1,1,CROW,"Yeah, it's great! I kept the same plot from my \
            screenplay -- the one about the earth being taken over by a \
            giant pot of California Cornucopia Vegetable Jubilee -- but now \
            instead of just watching, you can participate firsthand in the \
            relentless abject terror of it all!",0);
        Quip(-1,1,TOM,"If you two will excuse me, I'm going to go hang \
            myself.",2);
        print "[Tom leaves.  The mads' light flashes.]";
        Quip(-1,2,CROW,"Wanna see it?",0);
        Quip(-1,1,MIKE,"Later, Crow. Right now, Plato and Floyd are \
            calling.",2);
        print "[Mike hits the control.]^^[Deep 13]^^[Dr Forrester is \
            working on something in the background. TV's Frank taps him on \
            the shoulder and points at the screen.]";
        Quip(-1,2,DRF,"[Turning to them.] Ah, hello once again, Perry \
            Simm. You're just in time to witness the unveiling of my latest \
            invention.",0);
        Quip(-1,1,FRANK,"That's right, Your Zorkiness. Y'see, Mike, the \
            good doctor and I have long lamented the fact that the nifty \
            gadgets you find in text adventures aren't available in the \
            real world.",0);
        Quip(-1,1,DRF,"But, being the brilliant intellectuals that we are \
            -- well, I am, anyway... [Frank just looks dazed here.] ...we \
            came up with a real-world incarnation of a classic I-F object, \
            updated for the 90s. [He holds up a sword.] Behold, o \
            insignificant ones, the Sword of Chagrin! [He holds the sword \
            high.]",0);
        Quip(-1,1,FRANK,"[Stepping in front of Dr Forrester to ruin his \
            moment.] See, in the classic Zork Trilogy, your sword would \
            glow blue if you were close to anything immediately \
            life-threatening. But we've modified the concept for today's \
            society, so that the Sword of Chagrin will glow if you're \
            about  to do something really stupid and humiliating, thus \
            giving you a chance  to catch it before you embarrass yourself. \
            Check it out. [He turns and gives the sword back to Dr \
            Forrester. It glows blue in his hand.]",0);
        Quip(-1,1,DRF,"Yes, thank you, Frank. Now, you can't see me clearly \
            at the moment, since I'm behind Frank, but if I step out in the \
            open... [He does so. The sword glows brighter.] ...you'll see \
            that my fly is unzipped. But the blue glow of the Sword of \
            Chagrin has warned me about it, thus...ummm...",2);
        print "[SOL]^^[Mike and Crow are pointing and snickering at Dr F.]\
            ^^[Deep 13]";
        Quip(-1,2,DRF,"...thus...umm...saving me from the embarrassment \
            of...uhh...being seen with my fly unzipped... [He turns away \
            and quickly zips it up, then turns to Frank, who is also \
            snickering.] Aww, shut up, Frank! [He swings the sword at \
            Frank's head, but Frank ducks.]",2);
        print "[SOL]^^[Mike and Crow settle down a bit.]";
        Quip(-1,2,CROW,"Wow, what a co-inky-dink! Our invention this week \
            is also based on the Zork Trilogy!",0);
        Quip(-1,1,MIKE,"That's right, Dr F, and boy are you in for a \
            surprise! [Turns to the left.] C'mon, everyone, Tom, Gypsy, get \
            in here! [Tom and Gypsy arrive.] We got our idea from the \
            vehicles in Zork I and II that move when you give them voice \
            commands. So we reprogrammed the Satellite of Love to accept \
            I-F commands, and now we're coming back to Earth!",2);
        print "[Deep 13]^^[Extreme worry on the faces of Dr F and Frank.]^^\
            [SOL]";
        Quip(-1,2,MIKE,"All right, everybody ready? Good. Okay, Satellite, \
            take us DOWN! [He types this last command on the computer \
            keyboard.]",2);
        print "[A pause. Nothing happens. Then...]";
        Quip(-1,2,MAGICVOICE,"I can't go that way.",0);
        Quip(-1,1,CROW,"What?",0); Quip(-1,2,TOM,"Huh?",0);
        Quip(-1,1,MIKE,"Okay, okay, let's try it another way. [Types.] Take \
            us EAST, over the United States.",2);
        print "[Again, nothing happens.]";
        Quip(-1,2,MAGICVOICE,"I can't go that way.",0);
        Quip(-1,1,MIKE,"Aww, c'mon, no! I worked for months on this!!",2);
        print "[Tom steps in to look at the screen.]";
        Quip(-1,2,TOM,"Bring up the code for a sec, Mike. Let's see...Ah, \
            here's your problem. You've configured the satellite to use the \
            standard text-adventure compass. But we're in space, so \
            directions like ~down~ and ~east~ are completely meaningless!",
            2);
        print "[Mike bangs his head on the table in frustration.]";
        Quip(-1,2,TOM,"Yep, that's the problem all right.  The directional \
            objects are fully integrated into the ship's guidance system. \
            It'll take you months to fix it, Mike.",0);
        Quip(-1,1,CROW,"Aww, and we were so close, too!",0);
        Quip(-1,1,MIKE,"[Makes an effort to compose himself, though the \
            disappointment is tremendous.] Well...well, just you wait, Dr \
            F! We almost had it that time. Next time for sure!",2);
        print "[Deep 13]^^[Dr F and Frank wear smiles of triumph.]";
        Quip(-1,2,FRANK,"Oh, step out of your little fantasy world, \
            Nelson.",0);
        Quip(-1,1,DRF,"And step INTO another one, with this week's \
            experiment, ~The Caverns of Chaos.~ It's an irritating, \
            unpleasant-to-look-at, bug-infested, sloppily-programmed little \
            waste of archive space from the bowels of interactive hell.",0);
        Quip(-1,1,FRANK,"It's a pointless, moronic, insipid hyperfiction \
            fantasy quest packed with instant death and a nonsensical \
            layout, brought to you from the days when BASIC was still \
            considered a real computer language.",0);
        Quip(-1,1,DRF,"You've heard of the two-word parser? Say hello to \
            the one-word parser.",0);
        Quip(-1,1,FRANK,"And on top of all that, it's just really, really \
            bad.",0);
        Quip(-1,1,DRF,"Hope it feeds your worst nightmares, Poopsie! Send \
            'em the game, Frank.",2);
        print "[Frank, holding the Sword of Chagrin, takes a step toward \
            the button...and falls flat on his face, as Dr F has tied his \
            shoelaces together. Dr F holds up Frank's hand, which still \
            clutches the brightly-glowing sword.]";
        Quip(-1,2,DRF,"Sometimes it's just TOO easy.",2);
        print "[He pushes the button himself.]^^[SOL]";
        Quip(-1,2,CROW,"[Trying to console Mike.] Awww, c'mon, Mike. It's \
            not so bad. Say, did I mention I was also thinking of adapting \
            my ~Peter Graves at the University of Minnesota~ script?",2);
        print "[Flashing lights.]";
        Quip(-1,2,MIKE,"Oh, we've got--",0);
        Quip(-1,1,ALL,"MOVIE SIGGGGNNNN!!!",2);
        print "[General chaos ensues.]"; LineAcross();
        print "Most of the comments I did on the game itself are fairly \
            incomprehensible when taken out of context, but one in \
            particular is worth repeating here. The docs packaged with the \
            zip file mention that...^^~The Caverns of Chaos~ is a DnD type \
            text adventure game.^^...and this is repeated at least twice in \
            the docs and once more in the game itself. This was to be the \
            running joke for MST3K2, much like the hallways in ~Detective~ \
            for MST3K1. I'd planned to populate the early stages of the \
            game, where the player travels toward the Caverns of Chaos, \
            with such quips as:";
        Quip(-1,2,MIKE,"Oh, by the way, ~The Caverns of Chaos~ is a DnD \
            type text adventure game.",0);
        Quip(-1,1,CROW,"So, I understand that ~The Caverns of Chaos~ is a \
            DnD type text adventure game?",0);
        Quip(-1,1,TOM,"Did I mention that ~The Caverns of Chaos~ is a DnD \
            type text adventure game? I can't stress that enough!",0);
        Quip(-1,1,MIKE,"For those of you who've just joined us, ~The \
            Caverns of Chaos~ is a DnD type text adventure game.",0);
        Quip(-1,1,CROW,"An example of a DnD type text adventure game would \
            be ~The Caverns of Chaos.~",0);
        Quip(-1,1,MIKE,"A DnD type text adventure game is the type of text \
            adventure game that ~The Caverns of Chaos~ is.",0);
        Quip(-1,1,TOM,"So...WHAT type of text adventure game is ~The \
            Caverns of Chaos?~",2);
        print "During the later stages, whenever the words ~The Caverns of \
            Chaos~ appeared in the game text, I decided I'd have one of the \
            'bots add:";
        Quip(-1,2,CROW,"A DnD type text adventure game.",2);
        print "This would have been particularly amusing on subsequent \
            visits to the game's title screen, which displays...^^";
        for (i = 1 : i < 6 : i++) {
          print "     The Caverns of Chaos"; new_line;
        }
        print "^...in different colors.  With 'bot comments, it would have \
            been:^^";
        for (i = 1 : i < 6 : i++) {
          print "     The Caverns of Chaos^";
          if (i % 2 == 0) print "TOM:";
          else print "CROW:";
          print " A DnD type text adventure game.^";
        }
        new_line; new_line;
        print "But the concept perished before I got that far.^^Another \
            remarkably atrocious piece of code reared its ugly head in the \
            form of a locked door. If the choice was to open the door, the \
            player would then be ASKED if he/she found a particular key \
            several moves back! I kid you not! No variable assignments were \
            used, and instead complete honesty on the part of the player \
            was assumed!! I roared with laughter when I saw THAT!^^Though \
            much of the ending of MST3K1 was written after I'd done the \
            comments made on ~Detective~ (so that I could draw from them), \
            and I'd planned to do the same with MST3K2, I did write the \
            mads' final dialogue in Deep 13:";
        LineAcross();
        Quip(-1,0,MIKE,"Yeah, see, Dr F? Throw us all the bad games you've \
            got! We can take 'em! What do you think, sirs?",2);
        print "[Deep 13]";
        Quip(-1,2,DRF,"I don't understand it, Frank! This game was most \
            miserable piece of dreck on the archive, and look at them! They \
            had a ball with it! This is a major humiliation for us, Frank!",
            0);
        Quip(-1,1,FRANK,"[With sudden realization.] Ohhh! [Holds up the \
            Sword of Chagrin, which is glowing brightly.] So THAT'S why \
            this crazy thing was glowing through the whole experiment! It \
            was trying to warn us! [Laughs.] Boy, this WAS embarrassing! \
            [Meekly.] At least it works, though.",2);
        print "[Furiously, Dr. F grabs the sword from Frank and swings it \
            at him. Frank ducks at the last minute, and the sword hits ~the \
            button.~ The screen goes dark.]";
        LineAcross();
        "And that about wraps it up. I'm C.E. Forman. Thank you for joining \
        me on this inside look at the not-quite-making of MST3K2. If you'd \
        like to learn more about the not-quite-making of MST3K2, visit your \
        local library, which should have many fine books on the subject. \
        Good night, and may God bless.";
     8: print "^Yes, you read right. MST3K1 is proud to present this brief \
            tete-a-tete with the man behind ~Detective~, Mr Matt Barringer!\
            ^^After an exhausting net search, I finally managed to track \
            Matt down. I explained a little about the MST3K game and asked \
            him a couple of questions. Turns out Matt is a huge MST3K fan, \
            is well aware of the quality of his game, and is actually a \
            pretty decent guy, once you get past the fact that he wrote \
            ~Detective.~ He did ask me, though, not to reveal his e-mail \
            address here, and it's the least I can do after all I've put \
            him through.";
        LineAcross();
        print "Q: Okay, first things first.  When did you first hear about \
            the MST3K game?^   What was your initial reaction, and what are \
            your thoughts on it now?^^A: Wow. I got home and read your \
            letter, and I'd have to say that it surprised^   me a bit. I \
            posted that strange, first game of mine on a local BBS and \
            now^   it's on the Internet! I thought it would get tossed out \
            from the BBS. It's^   a bit embarrassing that it's spread out \
            amongst the Internet.^^   Oh well. I wrote that 2 years ago, so \
            I'll have to play it to answer your^   survey thing. I have yet \
            to play MST3000 but I love the show. If you were^   wondering, \
            I don't care that you make fun of it, feel free to make fun \
            of^   it all you like.^^Q: Please tell us a little about \
            yourself and the other members of ~Exile^   Games~, both now \
            and at the time you wrote ~Detective~.^^A: I was 12 or so then \
            (I turn 15 in a few months). I have changed a lot. I'm^   a lot \
            cooler now.^^   I still hang with Kurt [Somogue], he's changed \
            a lot too. Nathaniel^   [Smith], well, we are way too different \
            to even talk now. He moved away a^   few months after...^^Q: \
            What activities currently occupy your time? Are you still \
            interested in^   text adventures?^^A: I skateboard, play the \
            guitar. Listen to music. I'm not involved in text^   games \
            anymore, but I still play the ones others have written every \
            now and^   then. (I gave up after that obviously pathetic one I \
            wrote.)^^";
        print "Q: Could you possibly explain some of the places and \
            situations in ~Detective~^   and any inside jokes associated \
            with them? (In particular, the purpose of the^   dazed guy in \
            the music store has kept me awake many a night.)^^A: Okay, I \
            sped through it just now, to remember what you're talking \
            about,^   but all I can say is that it was all imagination, \
            except that guy at the ^   music store's based after a real \
            life guy who used to work at a really cool^   place in \
            Berkeley.^^Q: Anything else you'd like to add?^^A: I suppose I \
            should tell you that I really don't care. Being insulted about\
            ^   something in my past has little effect on me. And if you \
            need any other^   stupid games, I'd be sorta happy to bring out \
            the old AGT Master edition^   and do some REALLY stupid games \
            (although topping that'd be a bit tough)...";
        LineAcross();
        "Uh, no, that's okay. Thanks again for the interview, Matt, and for \
        making us laugh about love...again. (By the way, I sent Matt a free \
        registration for (SHAMELESS SELF-PROMOTION!!!) ~The Path to \
        Fortune~ as another way of saying thanks for putting up with me.)^^\
        Now if you'll excuse me, I'm going to go have an ice-cold \
        Coca-Cola, my very favorite soft drink. Ahh, so refreshing! Always \
        the real thing. Always Coca-Cola. (Wanna place an ad in my next \
        game? Send it over! (Text only, please.))";
   }
];

! This is used to print the dashed separator line across the screen.

[ LineAcross i;
   print "^^";
   for (i = 1 : i <= 80 : i++) print "-";
   print "^^";
];

#EndIf;

! Are we done yet?  No, one more statement to go...

End;

! NOW we're finished.  (Oh, bite me, it's fun!)