! ===========================================================================
! "Detective"
! An Interactive MiSTing
! By C.E. Forman (ceforman@worldnet.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!!!
! ===========================================================================
!
! 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!)

