!% -~S
!% $OMIT_UNUSED_ROUTINES=1
!% $ZCODE_LESS_DICT_DATA=1
!% $MAX_ABBREVS=96
!% $ZCODE_MAX_INLINE_STRING=1000
!!% $OMIT_SYMBOL_TABLE=1 ! Saves space, only possible without DEBUG mode

! The very first lines of the main source code file for a game can
! contain compiler options, like the lines above. -~S disables
! strict error checking. This is otherwise used in z5 and z8 games by
! default. While useful for debugging, it adds ~10 KB to the story file
! size and it makes the game slower.
! $OMIT_UNUSED_ROUTINES=1 makes the compiler remove all routines which
! aren't used. This can save some space.
! $ZCODE_LESS_DICT_DATA=1 removes an empty data byte for every dictionary word.

! This game is meant to be compiled with Inform v6.42 and PunyInform v5.12 (or a very late v5.11 dev)

Abbreviate "3, 2, 1 and ACTION!~";
Abbreviate " station commander";
Abbreviate "mass spectrometer";
Abbreviate "the Russian";
Abbreviate "a little ";
Abbreviate "Mr Martin";
Abbreviate " protocol";
Abbreviate " of the ";
Abbreviate " already";
Abbreviate "I don't ";
Abbreviate " can't ";
Abbreviate "ed to ";
Abbreviate ", but ";
Abbreviate " today";
Abbreviate " from ";
Abbreviate " about";
Abbreviate ", Mike";
Abbreviate "ou're ";
Abbreviate " scene";
Abbreviate " your ";
Abbreviate ", and ";
Abbreviate "Sergey";
Abbreviate " think";
Abbreviate " like ";
Abbreviate " with ";
Abbreviate "really";
Abbreviate "Keith";
Abbreviate " you ";
Abbreviate "hat's";
Abbreviate "Nadia";
Abbreviate " and ";
Abbreviate "Steve";
Abbreviate "ould ";
Abbreviate " time";
Abbreviate "just ";
Abbreviate "have ";
Abbreviate " some";
Abbreviate " what";
Abbreviate " the ";
Abbreviate " good";
Abbreviate "thing";
Abbreviate "been ";
Abbreviate "There";
Abbreviate "Billy";
Abbreviate " that";
Abbreviate " look";
Abbreviate "game";
Abbreviate " of ";
Abbreviate " for";
Abbreviate "tion";
Abbreviate "door";
Abbreviate "her ";
Abbreviate " you";
Abbreviate " is ";
Abbreviate "The ";
Abbreviate "not ";
Abbreviate " to ";
Abbreviate " out";
Abbreviate "ight";
Abbreviate "It's";
Abbreviate " are";
Abbreviate "talk";
Abbreviate "'ve ";
Abbreviate "ing ";
Abbreviate "here";
Abbreviate "know";
Abbreviate "his ";
Abbreviate "n't ";
Abbreviate "I'm ";
Abbreviate "You ";
Abbreviate "'s ";
Abbreviate "lea";
Abbreviate " a ";
Abbreviate "ver";
Abbreviate ". H";
Abbreviate "sta";
Abbreviate " on";
Abbreviate " it";
Abbreviate "ed ";
Abbreviate "You";
Abbreviate ": ~";
Abbreviate " ha";
Abbreviate "ing";
Abbreviate ". I";
Abbreviate "an ";
Abbreviate "ly ";
Abbreviate "ter";
Abbreviate "ll ";
Abbreviate "the";
Abbreviate " in";
Abbreviate "e.";
Abbreviate "^^";
Abbreviate "d.";
Abbreviate "I ";
Abbreviate ", ";
Abbreviate ". ";

Constant Story      "Mars, 2049 AD";
Constant Headline   "^An interactive meta-tale of life on Mars. For help and credits, type HELP.^";
Release 7;
Serial "250110";

Array UUID_ARRAY string "UUID://F4481A38-8FA9-42D0-8593-D90FC5CFCE7D//";
#Ifdef UUID_ARRAY;#Endif;

Constant STATUSLINE_SCORE; Statusline score;

Constant MAX_SCORE = 100;

! Uncomment to add optional features to PunyInform
!Constant DEBUG;
Constant CUSTOM_ABBREVIATIONS;
Constant OPTIONAL_NO_DARKNESS;
Constant OPTIONAL_ALLOW_WRITTEN_NUMBERS;
Constant OPTIONAL_EXTENDED_METAVERBS;
Constant OPTIONAL_EXTENDED_VERBSET;
Constant OPTIONAL_FLEXIBLE_INVENTORY;
Constant OPTIONAL_PRINT_SCENERY_CONTENTS;
Constant OPTIONAL_SIMPLE_DOORS;
Constant OPTIONAL_MANUAL_SCOPE;
Constant OPTIONAL_MANUAL_SCOPE_BOOST;
#IfV5;
Constant OPTIONAL_PROVIDE_UNDO;
#Endif;
!Constant RUNTIME_ERRORS = 0; ! 0, 1 or 2. 0 = smallest file, 2 = most info

! Define any library constants you need here, like MAX_SCORE, AMUSING_PROVIDED,
! MAX_CARRIED, SACK_OBJECT,  etc.
Constant MAX_TIMERS = 6;
Constant MAX_SCOPE = 35;
Constant MAX_FLOATING_OBJECTS = 10;

Constant INITIAL_LOCATION_VALUE = Quarters;

Include "globals.h";

! Define your attributes, common properties and global variables here, if any

Constant S_BEFORE_START  = 0;
Constant S_INTRO         = 1;
Constant S_BEFORE_FILMING= 2;
Constant S_SCENE_1       = 3;
Constant S_INTERLUDE_1   = 4;
Constant S_SCENE_2       = 5;
Constant S_INTERLUDE_2   = 6;
Constant S_SCENE_3       = 7;
Constant S_AFTER_FILMING = 8;

Global game_scene = S_BEFORE_START;
Global bell_rung = -10;
Global nadia_attitude = 50;
Global sergey_attitude = 50;
Global steve_delay = 0;
Global scene_over = false;
Global scene_can_be_over = false;
Global score_1 = 0;
Global score_2 = 0;
Global score_3 = 0;
Global score_total = 0;

Constant STR_REALLY_LEAVE = "Mr Martin looks at you pleadingly. Do you still want to leave?^>";
Constant STR_STAY = "You think better of it and stay.";
Constant STR_CUT = "Mr Martin shouts ~CUT!~ behind you as you leave.^^";
Constant STR_A_TOTAL_DISASTER = "a total disaster - you didn't even finish the scene!^^";

! Define the entry point routines you need here, like Amusing, DarkToDark etc.


Include "ext_menu.h";

Constant FLAG_COUNT = 80;

Constant F_FULLY_AWAKE = 1;
Constant F_HAS_SAT_UP = 2;
Constant F_SEEN_BOTTLES = 3;
Constant F_SEEN_TINA = 4;
Constant F_PARTY_GONE = 5;
Constant F_DIRECTOR_INTRO = 6;
Constant F_SCENE_1_PREMATURE_EXIT = 7;
Constant F_LINDA_IS_FREE = 8;
Constant F_KEITH_IS_FREE = 9;
Constant F_DIRECTOR_IS_FREE = 10;
Constant F_SCENE_1 = 11;
Constant F_SCENE_2 = 12;
Constant F_SCENE_3 = 13;
Constant F_BEFORE_FILMING = 14;
Constant F_INTERLUDE_1 = 15;
Constant F_INTERLUDE_2 = 16;
Constant F_AFTER_FILMING = 17;
Constant F_INTRO = 18;
Constant F_NADIA_HAD_BAD_KISS 19;
Constant F_NADIA_HAD_GOOD_KISS 20;
Constant F_SCENE_2_PREMATURE_EXIT = 21;
Constant F_DIRECTOR_TALKED_ABOUT_SCENE_2 22;
Constant F_DIRECTOR_TALKED_ABOUT_SCENE_3 23;
Constant F_IVAN_IS_FREE = 24;
Constant F_SCENE_3_PREMATURE_EXIT = 25;
Constant F_PRINTED_SUMMARY = 26;

! Flags which can be set by talk_menu must have ID in the range 32-299
Constant F_EXAMINE_SPECTROMETER = 32;
Constant F_NADIA_ADMITTED_CONTACT 33;
Constant F_STEVE_IS_INFORMED 34;
Constant F_SERGEY_ADMITTED_CONTACT 35;

Include "ext_flags.h";

Constant TM_MSG_TOPICS_DEPLETED "With that, the conversation comes to a natural end.";

Include "ext_talk_menu.h"; ! Note: Also include ext_flags.h to allow use of flags

#Ifv3;
Constant QUOTE_V3_SCREEN_WIDTH 40;
#Endif;
Include "ext_quote_box.h";

Array quote_start static --> 6 32
       "          Mars, 2049 AD"
       ""
       "Mankind has put its faith in"
       "you. This is your time to shine."
       "Your time to make a difference."
       "Now go out there and do it.";

[ CS_DEFAULT_MSG;
       if(game_scene == S_SCENE_1 or S_SCENE_2 or S_SCENE_3)
               "Keep in mind: The future of mankind is depending on you! There are more important things to tend to.";
       "You need to focus on your job, make sure the next scene will be great.";
];

![ SceneryReply p_msg p_arg_1 p_id_or_routine;
!
!];

Include "ext_cheap_scenery.h";

Constant MSG_LOOK_BEFORE_ROOMNAME 1000;
Constant MSG_STRONG_DEFAULT 1001;

[ LibraryMessages p_msg p_1 p_2;
       switch(p_msg) {
       MSG_STRONG_DEFAULT:
               if(game_scene == S_SCENE_1 or S_SCENE_2 or S_SCENE_3)
                       "This is a family friendly show. We can't have none of that.";
               "Mr Martin has had to remind you a few times already, that that kind
                       of language isn't acceptable on set.";
       MSG_LOOK_BEFORE_ROOMNAME:
               if(location == Quarters && FlagIsSet(F_FULLY_AWAKE)) {
                       if(FlagIsClear(F_SEEN_BOTTLES)) {
                               p_1 = p_2;
                               SetFlag(F_SEEN_BOTTLES);
                               "Right, there was a party last night. You kind of wish there hadn't been.^";
                       }
                       if(Tina in location && FlagIsClear(F_SEEN_TINA))
                               "Oh, wait, it's all coming back to you now... The girl! She was at
                                       the party.^";
               }
       }
];

[ UpdateScore;
       ! Pull in attitudes to expected range, just in case
       if(nadia_attitude < 10) nadia_attitude = 10;
       if(nadia_attitude > 80) nadia_attitude = 80;
       if(steve_delay < 0) steve_delay = 0;
       if(steve_delay > 40) steve_delay = 40;
       if(sergey_attitude < 30) sergey_attitude = 30;
       if(sergey_attitude > 80) sergey_attitude = 80;

       score_1 = ((nadia_attitude - 10) * 5) / 7 + 50 * FlagIsSet(F_NADIA_ADMITTED_CONTACT);
       score_2 = steve_delay + steve_delay / 4 + 50 * FlagIsSet(F_STEVE_IS_INFORMED);
       score_3 = sergey_attitude - 30 + 50 * FlagIsSet(F_SERGEY_ADMITTED_CONTACT);

       if(game_scene < S_SCENE_1 || FlagIsSet(F_SCENE_1_PREMATURE_EXIT)) score_1 = 0;
       if(game_scene < S_SCENE_2 || FlagIsSet(F_SCENE_2_PREMATURE_EXIT)) score_2 = 0;
       if(game_scene < S_SCENE_3 || FlagIsSet(F_SCENE_3_PREMATURE_EXIT)) score_3 = 0;

       score_total =   score_1 + score_2 + score_3;
];

[ SummarizeDay;
       new_line;

       UpdateScore();

       if(game_scene < S_SCENE_1) {
               print "We didn't even get to the first scene before you screwed it up.^^";
               jump _done;
       }

       print "Your scene with Nadia was ";
       if(FlagIsSet(F_SCENE_1_PREMATURE_EXIT)) {
               print (string) STR_A_TOTAL_DISASTER;
       } else if(score_1 < 30) {
               print "a bit of a disaster really.^^";
       } else if(score_1 < 60) {
               print "a success, to some extent, even if I know you can do better than that.^^";
       } else if(score_1 < 100) {
               print "pretty good really. Not your very best work, but it'll do.^^";
       } else {
               print "great! You got the information out of her, while
                       strengthening your relation. That's how it's done!^^";
       }

       if(game_scene < S_SCENE_2) {
               print "And we never got to the next scene, which is a shame.^^";
               jump _done;
       }

       print "Your scene with Steve was ";
       if(FlagIsSet(F_SCENE_2_PREMATURE_EXIT)) {
               print (string) STR_A_TOTAL_DISASTER;
       } else if(score_2 < 30) {
               print "pretty much a disaster.^^";
       } else if(score_2 < 60) {
               print "a partial success. I know you can do better.^^";
       } else if(score_2 < 100) {
               print "actually pretty good.^^";
       } else {
               print "great! You gave him the information he wanted,
                       while maintaining your integrity. Good job!^^";
       }

       if(game_scene < S_SCENE_3) {
               print "And we never got to the final scene, which is a shame.^^";
               jump _done;
       }

       print "Your scene with Sergey was ";
       if(FlagIsSet(F_SCENE_3_PREMATURE_EXIT)) {
               print (string) STR_A_TOTAL_DISASTER;
       } else if(score_3 < 30) {
               print "sort of a disaster.^^";
       } else if(score_3 < 60) {
               print "a success to some extent, but overall it wasn't good enough. You can do a lot better.^^";
       } else if(score_3 < 100) {
               print "pretty good, I think.^^";
       } else {
               print "great! You got Sergey to admit that he broke protocol, he
                       promised not to do it again, and you built a better relation.
                       Now that's what I call a top notch result!^^";
       }

_done;

       print "All in all, I think your performance today was ";
       if(score_total < 20)
               print "an absolute disgrace";
       else if(score_total < 60)
               print "among the worst I've seen in my career";
       else if(score_total < 100)
               print "nothing to be proud of";
       else if(score_total < 150)
               print "sub-par";
       else if(score_total < 200)
               print "not without merit";
       else if(score_total < 250)
               print "quite good, but far from perfect";
       else if(score_total < 300)
               print "really good. You just need to work on the details";
       else
               print "absolutely amazing";
       print ".
       ^^As we agreed on earlier, you'll get pay according to your performance, up to $300 per day.
       For today's performance, I";
       if(score_total == 0) print "'m afraid I can't pay you anything at all";
       else if(score_total >= 300) print "'m happy to pay you the full $", score_total;
       else print " can pay you $", score_total;
       ".~";
];

[ EndOfDay;
       print "^Mr Martin takes you aside. ~Mike, we need to talk about
               your performance today.^";
       SummarizeDay();
       SetFlag(F_PRINTED_SUMMARY);

       deadflag = GS_WIN;
       if(game_scene < S_AFTER_FILMING ||
                       score_total < 200 ||
                       AnyFlagIsSet(F_SCENE_1_PREMATURE_EXIT, F_SCENE_2_PREMATURE_EXIT, F_SCENE_3_PREMATURE_EXIT) ||
                       AnyFlagIsClear(F_NADIA_ADMITTED_CONTACT, F_STEVE_IS_INFORMED, F_SERGEY_ADMITTED_CONTACT))
               deadflag = GS_DEATHMESSAGE;

];

[ DeathMessage;
       print "You have been fired";
];

[ AfterLife;
       if(FlagIsSet(F_PRINTED_SUMMARY))
               return;

       print "^And that, Mr Martin explains in no uncertain terms,
               marks the end of your involvement in this project.
               You head to the dressing room to change back into
               your normal clothes, take a last short stroll around the
               premises, and head for the exit.^";

       print "^As you're about to leave the studio grounds, Mr Martin comes
               walking, and approaches you:^^
               ~Hey Mike, I just wanted to give you some feedback on how
               things went today.^";

       SummarizeDay();
];

[ ChooseObjects p_obj p_flag;
       if(p_obj == SilverBlanket && p_flag == 1) return 2;
       rfalse;
];

#Ifv3;
[ BeforeParsing _i;
       for(_i = NumberWords(): _i > 0 : _i--)
               if(WordValue(_i) == 'bottle' && WordLength(_i) == 7 && WordAddress(_i)->6 == 's')
                       (parse-2)-->(_i + _i) = 'jars//p';
];
#Endif;

Include "puny.h";

Include "ext_waittime.h";

[SetScene p_scene;
#Ifdef DEBUG;
       if(p_scene < game_scene)
               print "**** ERROR: Tried to decrease game_scene^";
       if(p_scene < S_BEFORE_START || p_scene > S_AFTER_FILMING) {
               print "**** ERROR: Tried to set game_scene to illegal value: ",p_scene,"^";
               return;
       }
#Endif;
       UpdateScore();
       while(game_scene < p_scene) {
               game_scene++;
               waittime_waiting = false;
               scene_over = false;
               scene_can_be_over = false;
               switch(game_scene) {
               S_INTRO:
                       SetFlag(F_DIRECTOR_IS_FREE, F_KEITH_IS_FREE, F_LINDA_IS_FREE);
                       SetFlag(F_IVAN_IS_FREE, F_INTRO);
               S_BEFORE_FILMING:
                       SetFlag(-F_INTRO, F_BEFORE_FILMING);
               S_SCENE_1:
                       ClearFlag(F_DIRECTOR_IS_FREE, F_LINDA_IS_FREE);
                       SetFlag(-F_BEFORE_FILMING, F_SCENE_1);
               S_INTERLUDE_1:
                       if(FlagIsClear(F_SCENE_1_PREMATURE_EXIT))
                               score = score + 4 + (nadia_attitude - 10) / 5;
                       SetFlag(F_DIRECTOR_IS_FREE, F_LINDA_IS_FREE);
                       SetFlag(-F_SCENE_1, F_INTERLUDE_1);
                       ClearFlag(F_NADIA_HAD_BAD_KISS, F_NADIA_HAD_GOOD_KISS);
               S_SCENE_2:
                       ClearFlag(F_DIRECTOR_IS_FREE, F_KEITH_IS_FREE);
                       SetFlag(-F_INTERLUDE_1, F_SCENE_2);
               S_INTERLUDE_2:
                       if(FlagIsClear(F_SCENE_2_PREMATURE_EXIT))
                               score = score + 4 + (steve_delay + steve_delay) / 5;
                       SetFlag(F_DIRECTOR_IS_FREE, F_KEITH_IS_FREE);
                       SetFlag(-F_SCENE_2, F_INTERLUDE_2);
               S_SCENE_3:
                       ClearFlag(F_DIRECTOR_IS_FREE, F_IVAN_IS_FREE);
                       SetFlag(-F_INTERLUDE_2, F_SCENE_3);
               S_AFTER_FILMING:
                       if(FlagIsClear(F_SCENE_3_PREMATURE_EXIT))
                               score = score + 4 + (sergey_attitude - 30) * 3 / 10;
                       SetFlag(F_DIRECTOR_IS_FREE, F_IVAN_IS_FREE);
                       SetFlag(-F_SCENE_3, F_AFTER_FILMING);
               }
       }
];


[ UseTalkSub;
       "To communicate with people, try ~TALK TO <someone>~.";
];

Extend 'ask' replace
       * topic -> UseTalk;
Extend 'say' replace
       * topic -> UseTalk;
Extend 'tell' replace
       * topic -> UseTalk;
Verb 'question'
       * topic -> UseTalk;

[ ActSub;
       if(game_scene == S_SCENE_1 or S_SCENE_2 or S_SCENE_3)
               "You have to say exactly what you want to do. As long as you don't leave
                       the room, it's all part of the scene.";
       "But the cameras aren't even rolling!";
];

Verb 'act'
       * -> Act
       * topic -> Act;

Extend 'put'
       * 'finger' 'on' noun -> Touch
       * 'my' 'finger' 'on' noun -> Touch;

Extend only 'sit'
       * 'up' -> Exit;

Extend 'look'
       * 'into' noun -> Search;

Verb 'tug'
       * noun -> Pull
       * 'at'/'on' noun -> Pull;

Verb 'start'
       * noun -> SwitchOn;

Verb 'stop'
       * noun -> SwitchOff;

[ UseSub;
       "You need to be more specific.";
];

Verb 'use' 'utilize' 'utilise'
       * noun -> Use;

[ FoldSub;
       "That seems both hard and pointless.";
];

Verb 'fold'
       * noun -> Fold;

[ CoverSub;
       "I'm not sure how to do that.";
];

Extend only 'cover' replace
       * noun                     -> Cover
       * noun 'with'/'using' noun -> Cover;

Extend 'put'
       * noun 'under' noun -> PutUnder;

[ PutUnderSub;
       "Is that the best you can think of?";
];

Verb 'xyzzy' 'plugh'
       * -> Xyzzy;

[ XyzzySub;
       "Groovy! You just visited a friend at Cal State the other week, and were shown
               this new game on a computer, that apparently everyone is playing, and in
               the game just uttering ~", (VerbName) verb_word,
               "~ would make magical stuff happen. You wish it would
               work here too. Maybe it works on Mars?";
];

#Ifdef DEBUG;

[ Magic1Sub;
       SetFlag(F_FULLY_AWAKE, F_HAS_SAT_UP, F_SEEN_BOTTLES);
       SetFlag(F_SEEN_TINA, F_PARTY_GONE);
       remove Tina;
       remove TequilaBottle;
       remove GrenadineBottle;
       give QuartersDoor ~absent;
       scope_modified = true;
       SetScene(S_INTRO);
       MoveFloatingObjects();
       StartDaemon(Director);
       PlayerTo(Quarters,2);
];

[ Magic2Sub;
       SetFlag(F_FULLY_AWAKE, F_HAS_SAT_UP, F_SEEN_BOTTLES);
       SetFlag(F_SEEN_TINA, F_PARTY_GONE);
       remove Tina;
       remove TequilaBottle;
       remove GrenadineBottle;
       give QuartersDoor ~absent;
       scope_modified = true;
       SetScene(S_INTERLUDE_1);
       move Director to PropRoom;
       move Linda to PropRoom;
       move Keith to PropRoom;
       move Ivan to PropRoom;
       MoveFloatingObjects();
       StartDaemon(Director);
       PlayerTo(Quarters,2);
];

Verb meta 'magic'
       *     -> Magic1
       * '1' -> Magic1
       * '2' -> Magic2;

[ AttitudeSub;
       print "nadia_attitude: ", nadia_attitude, "^";
       print "steve_delay: ", steve_delay, "^";
       print "sergey_attitude: ", sergey_attitude, "^";
];

Verb meta 'attitude'
       * -> Attitude;


#Endif;

[ RingSub;
       "You can't ring ", (ThatOrThose) noun,"!";
];

Verb 'ring'
       * noun -> Ring;

[ HelpItems;
   print "Pick a headline to learn more:^^";
   print "      Instructions^";
   print "      Endings (SPOILERS)^";
   print "      About this game^";
   print "      Game credits^";
   print "      License^";
];

[ HelpMenu;
   switch(menu_item) {
   0: item_width=20; item_name="Help and Information"; return 5;
   1: item_width=12; item_name="Instructions";
   2: item_width=18; item_name="Endings (SPOILERS)";
   3: item_width=14; item_name="About this game";
   4: item_width=12; item_name="Game credits";
   5: item_width=12; item_name="License";
   }
];

[ HelpInfo;
       switch(menu_item) {
       1: "You play this game like any old Infocom game.
               ^^Common commands include EXAMINE, SEARCH, OPEN, CLOSE, PUSH, PULL, TURN, KISS, SAVE, RESTORE and QUIT. You can ask someone to do something like this:
               ^^BOB, TAKE THE BOOK
               ^BOB, GO NORTH
               ^^Some less common commands which are supported by this game:
               ^^TALK TO MR MARTIN
               ^WAIT UNTIL 10:00
               ^WAIT FIVE MINUTES
               ^WAIT 1 HOUR
               ^^For some objects, this game makes a difference between adjectives and nouns,
                       and for those objects you have to use at least one of the nouns when
                       referring to an object.
                       E.g. to examine a red shirt you can say EXAMINE SHIRT or EXAMINE RED SHIRT,
                       but not EXAMINE RED. ";
       2: "When the game ends, you get a summary of how the recording day went. If you've
                       done good enough, you'll avoid getting fired, and thus win the game. To get
                       the best possible outcome however, you need to achieve the goals of each
                       scene. If you succeed perfectly, Mr Martin will say your performance in
                       that scene was great, and he won't indicate that you could have done it
                       better in any way.";
       3: "I developed this game in the fall of 2024, for PunyComp 2024.
                       I was inspired by Ryan Veeder's game Craverly Heights, and I was interested
                       in making a game mainly driven by dialog.";
       4: "Johan Berntsson, Stefan Vogt, Marco Innocenti and Agust Antonsson Lindgren
                       provided invaluable playtesting and advice.
                       ^^I have received feedback and bug reports, which helped me improve the game,
                       from Jenny Grahn Lindstrom, Michael Bub and Mathbrush.
                       ^^This game uses the PunyInform library, which Johan Berntsson and I have developed.
                       This library, correctly used, lets authors write games using modern tools and
                       have them run smoothly on 8-bit computers, as well as modern computers. The library
                       can be found at https://github.com/johanberntsson/PunyInform.
                       ^^PunyInform uses the marvellous Inform 6 programming language, and derives a lot of code
                       and design from the accompanying Inform 6 standard library, both
                       created by Graham Nelson.
                       ^^I used the wonderful zabbrev utility by Henrik Asman to find the best abbreviations:
                       https://github.com/heasm66/zabbrev";
       5: "This game can be distributed freely in unaltered form, as long as no profit is involved. The game
                       file can be used to build disk images or binaries that include a Z-code interpreter.
                       The homepage of the game, where the sourcecode can also be found,
                       is https://fredrikr.itch.io/mars2049ad
                       ^^I do not accept payment for this game. Regardless how you feel about the game, I would
                       really appreciate if you could rate the game on IFDB: https://ifdb.org";
   }
];

[ HelpSub;
   DoMenu(HelpItems, HelpMenu, HelpInfo);
];

Verb meta 'help' 'menu' 'credits' 'about' 'license'
       * -> Help;

#Ifv5;
Property adj_name;
Property noun_name;
#Ifnot;
Property individual adj_name;
Property individual noun_name;
#Endif;

#Ifv5;
[MatchNameList p_obj p_prop _w _matched _an _count _i;
   _an = p_obj.&p_prop;
   if(_an == 0) {wn++; return 0; }
   _count = p_obj.#p_prop;
       @log_shift _count (-1) -> _count; ! Divide by 2
   while(true) {
               _w = NextWord();
               @scan_table _w _an _count -> _i ?_MNL_match;
               return _matched;
_MNL_match;
               _matched++;
   }
];
#Ifnot;
[MatchNameList p_obj p_prop _w _matched _base _an _count _i;
   _an = p_obj.&p_prop;
   if(_an == 0) {wn++; return 0; }
   _count = p_obj.#p_prop / 2;
   while(true) {
               _w = NextWord();
       _base = _matched;
       for(_i = 0 : _i < _count : _i++)
           if(_w == _an-->_i) { _matched++; break; }
       if(_matched == _base) return _matched;
   }
];
#Endif;

Class AdjObject
   with
       parse_name [ _adj _noun;
           _adj = MatchNameList(self, adj_name);
           wn--;
           _noun = MatchNameList(self, noun_name);
           if(_noun) return _noun + _adj;
       ];


Class LightRoom
!       has light
       ;

LightRoom Quarters "Crew Quarters"
       with
               description [;
                       if(FlagIsSet(F_FULLY_AWAKE)) {
                               print "Comfortable beds line the brown walls. A chair stands next to Nadia's bed.";
                               if(player in YourBed) print " You're lying on yours.";
                               print " A sliding door is set in the east wall.";
                               if(EntertainmentSystem in location) {
                                       print " An entertainment system sits on the west wall.";
                                       if(EntertainmentSystem has open) {
                                               print " It has swung open, revealing an exit to the west.";
                                       }
                               }
                               "";
                       }
                       "Your eyes are open, there's enough light (more than enough, actually!),
                       and yet you can barely make out the contours of the room!";
               ],
               before [;
                       if(turns>=0 && FlagIsClear(F_FULLY_AWAKE) && deadflag == GS_PLAYING &&
                                       action ~= ##Look or ##Examine or ##Wait or ##WaitMoves or
                                       ##WaitUntil or ##WaitHours or ##WaitMinutes or ##Xyzzy &&
                                       (action ~= ##Open or ##Close || noun ~= Eyes))
                               "Oh no, the room just spins! You need to get your bearings.";
                       Wait, WaitMoves, WaitUntil, WaitHours, WaitMinutes:
                               rfalse;
                       Look, Examine:
                               if(turns>=0 && FlagIsClear(F_FULLY_AWAKE)) {
                                       SetFlag(F_FULLY_AWAKE);
                                       move TequilaBottle to location;
                                       move GrenadineBottle to location;
                                       move NadiasBed to location;
                                       move StevesBed to location;
                                       give EntertainmentSystem ~absent;
                                       give QuartersDoor ~absent;
                                       MoveFloatingObjects(); ! Sets scope_modified
                                       print "You concentrate, and begin to see things more clearly...^^";
                                       <<Look>>;
                               }
                               if(player in YourBed && action == ##Examine && noun in EntertainmentSystem)
                                       "You can't get a good view of it from here.";
                       Cover:
                               if(second == SilverBlanket)
                                       <<PutUnder noun second>>;
                       PutUnder:
                               if(second == YourBed or NadiasBed or StevesBed)
                                       "The beds are integrated into the floor. There is no space under them.";
                               if(second == SilverBlanket) {
                                       if(noun == player)
                                               "Mr Martin is already upset with you. You showing up as a ghost may be too
                                                       much for him right now.";
                                       if(noun == Tina)
                                               "She seems to be fine as it is.";
                                       "It's a very thin blanket. It would just look suspicious.";
                               }
                       default:
                               if(player in YourBed && noun ~= 0 or Directions &&
                                               IndirectlyContains(YourBed, noun) == false &&
                                               parent(noun) ~= nothing or PlayerParts && noun ~= Tina)
                                       "You can't reach it from here.";
               ],
               after [;
                       Exit:
                               if(FlagIsClear(F_HAS_SAT_UP)) {
                                       print "Slowly, you crawl out of bed, and get to your feet...^^";
                                       StartDaemon(Director);
                                       SetFlag(F_HAS_SAT_UP);
                                       move Tina to location;
                                       move SilverBlanket to location;
                                       scope_modified = true;
                                       score++;
                                       <<Look>>;
                               }
               ],
               w_to [;
                       if(EntertainmentSystem has general) return EntertainmentSystem;
                       "There's no obvious exit in that direction.";
               ],
               e_to QuartersDoor,
               cheap_scenery
                       5 'crew' 'crew^s' 'quarter' 'quarters' 'quarter^s'
                               "It's a nice place to hang out and get some rest when you have
                                       free time, and of course to sleep."
                       3 'contour' 'contours//p' 'room'
                               [; Examine:
                                       "There are several beds.";
                               ]
                       CS_THEM 'comfortable' 'beds//p'
                               "There are beds for eight people."
                       3 'white' 'aluminium' 'chair'
                               [;
                                       Examine: "A simple white chair, all made of aluminium.";
                                       Enter: "You never sit on that chair. It looks too fragile.";
                               ]
                       4 'silvery' 'shine' 'shiny' 'fabric'
                               "If they tried to make the living quarters feel like home, this is one place where there's room
                                       for improvement, for sure."
                       CS_THEM 'brown' 'walls'
                               [; Examine: "The walls have been imprinted with a pattern of large flowers,
                                       in a few different shades of brown. It's meant to remind the crew of
                                       their homes on earth.";
                               ];

Class Bed
       class AdjObject,
       with
               noun_name 'bed',
               description [;
                       print "It's comfortable enough. The fabric has a silvery shine to it.";
                       if(PrintContents(" On the bed ", self, ISARE_BIT)) ".";
                       new_line;
               ],
       has proper static scenery supporter enterable;

Object -> YourBed "your bed"
       class Bed,
       with
               adj_name 'my' 'your';

Object NadiasBed "Nadia's bed"
       class Bed,
       with
               noun_name 'bed' 'nadia^s' 'nadias';

Object StevesBed "Steve's bed"
       class Bed,
       with
               noun_name 'bed' 'steve^s' 'steves';

LightRoom PropRoom "Prop Room"
       with
               description "This is where the smaller things that are needed pretty much every
                       day are stored. Two large shelves are filled with all sorts of gadgets.
                       Sliding doors leads north, east and west, while a normal door leads south.
                       A bell hangs on the wall.",
               number -1,
               before [;
                       Go:
                               if(selected_direction == s_to) {
                                       if(game_scene == S_AFTER_FILMING)
                                               "You can't leave now, Mr Martin will want to talk to you first!";
                                       if(self.number == turns - 1)
                                               give self general;
                                       self.number = turns;
                                       if(self hasnt general) {
                                               "You can't just leave, you're not done for today!";
                                       }
                                       give self general;
                                       if(OutsideDoor has open) {
                                               deadflag = GS_DEATHMESSAGE;
                                               print "You finally decide you've had enough of this.^";
                                       }
                               }
               ],
               n_to OfficeDoor,
               w_to QuartersDoor,
               e_to LabDoor,
               s_to OutsideDoor,
               cheap_scenery
                       'wooden' 'bracket' "It's a simple and not very beautiful construction, but it does
                                       the job of holding the bell up."
                       16 'large' 'shelf' 'shelves//p' 'prop' 'props//p' 'gadget' 'gadgets//p'
                               [; Examine: "It's fascinating how many props you need for a production like this.";
                                       Search: "There's nothing that you need there.";
                                       default: "All of the gadgets on the shelves will be needed at some point.
                                               Better not mess with them.";
                               ]
                       11 'sliding' 'doors//p'
                               [; default: "There's a sliding crew's quarters door to the west and a sliding lab door to the east.
                                                       Also, there's a non-sliding door leading outside to the south.";
                               ];

Object -> Bell "bell"
       with
               name 'brass' 'bell',
               description "The bell is made of brass. It hangs from a wooden bracket on the west wall.",
               describe [; rtrue; ],
               before [;
                       Turn: "The bell can't turn.";
                       Ring, Pull, Push:
                               if(self hasnt general) {
                                       give self general;
                                       "Oh, you pulled that stunt yesterday. That's part of the reason things are so
                                               tense between you and Mr Martin today. Nobody but Mr Martin rings the bell.";
                               }
                               deadflag = GS_DEATHMESSAGE;
                               "You decide to give in to the temptation, and ring the bell: ~Ding ding ding~";
                ],
       has static;

LightRoom Lab "Laboratory"
       with
               description "A quite busy area, with a few different workbenches for various tasks. One is
                       full of advanced electronic equipment, another has camera equipment and microscopes, while
                       a third has vials, test tubes, as well as machines for chemical analysis. A sliding door
                       is set in the west wall.",
               w_to LabDoor,
               before [;
                       Go:
                               if(selected_direction == w_to && game_scene == S_SCENE_1) {
                                       if(true ~= scene_over or scene_can_be_over) {
                                               if(self hasnt general) {
                                                       give self general;
                                                       "You start to walk out, but Mr Martin gives you an angry look, beckoning you to return
                                                               to the scene.";
                                               }
                                               print (string) STR_REALLY_LEAVE;
                                               if(YesOrNo()==false)
                                                       print_ret (string) STR_STAY;
                                               SetFlag(F_SCENE_1_PREMATURE_EXIT);
                                       }
                                       print (string) STR_CUT;
                                       SetScene(S_INTERLUDE_1);
                                       Director.number = -1;
                               }
               ],
               cheap_scenery
                       'lab' 'laboratory' "The lab is impressively well-equipped, considering how little
                               cargo space you supposedly had on the ship when you got here."
                       5 'machines//p' 'machine' 'for' 'chemical' 'analysis'
                               "There are several. The only one your character is supposed to know how to use
                                       properly is the mass spectrometer."
                       5 'vial' 'vials//p' 'test' 'tube' 'tubes//p'
                               "You don't know the first thing about chemistry, but the test tubes and vials sure look authentic to you."
                       5 'microscope' 'microscopes' 'camera' 'electronic' 'equipment'
                               "All of the equipment looks great, but once you get close it's obvious that they're just props."
                       3 'workbench' 'work' 'bench'
                               "Unlike most props, the workbenches are pretty sturdy.";

Object -> MassSpectrometer "mass spectrometer"
       with
               name 'mass' 'spectrometer',
               describe [; rtrue; ],
               before [;
                       Use, SwitchOn, Push:
                               "The mass spectrometer is always on. To use it, you just need to look at it.";
                       Search, Examine:
                               if(game_scene == S_SCENE_1) {
                                       if(FlagIsSet(F_EXAMINE_SPECTROMETER) || scene_can_be_over)
                                               scene_over = true;
                                       "You lean over the machine, and pretend to take a good look at the display, where
                                               row upon row of meaningless numbers are slowly scrolling by.";
                               }
                               "You glance at the display which, as expected, is empty.";
               ],
       has static;

LightRoom Office "Office"
       with
               description [;
                       print "The center of administration and communication, where you usually
                               don't spend much time. A large desk stands in the middle of the room. A door leads south,
                               while another leads north. ";
                       if(game_scene == S_SCENE_2)
                               "Steve has made it very clear that the door to the north
                                       is strictly off-limits to you, as it leads to the station commander's private room.";
                       "The door to the north leads to the set for the Russian station.";
               ],
               before [;
                       Go:
                               if(game_scene == S_SCENE_2) {
                                       if(selected_direction == n_to)
                                               "There's no way you're entering the station commander's private room.";
                                       if(selected_direction == s_to) {
                                               if(true ~= scene_over or scene_can_be_over) {
                                                       if(self hasnt general) {
                                                               give self general;
                                                               "You start to walk out, but Mr Martin shakes his head in despair.";
                                                       }
                                                       print (string) STR_REALLY_LEAVE;
                                                       if(YesOrNo()==false)
                                                               print_ret (string) STR_STAY;
                                                       SetFlag(F_SCENE_2_PREMATURE_EXIT);
                                               }
                                               print (string) STR_CUT;
                                               SetScene(S_INTERLUDE_2);
                                               Director.number = -1;
                                       }
                               }
               ],
               n_to RussianStationDoor,
               s_to OfficeDoor,
               cheap_scenery
                       32 'large' 'lightweight' 'foldable' 'desk' 'table'
                               "Like everything here, it's lightweight and foldable."
                       3 'white' 'aluminium' 'chair'
                               [;
                                       Examine: "A simple white chair, all made of aluminium.";
                                       Enter: "Uhm, that's Steve's chair. You don't sit on it. Besides, you think
                                               it might break under your weight.";
                               ];

LightRoom RussianStation "Russian Station"
       with
               description "The rather large central chamber of the Russian station, which works as a
                       lab, a storage room, and the crew's quarters. There are beds, desks and a chair
                       here. A door leads south.",
               before [;
                       Go:
                               if(selected_direction == s_to && game_scene == S_SCENE_3) {
                                       if(true ~= scene_over or scene_can_be_over) {
                                               if(self hasnt general) {
                                                       give self general;
                                                       "You start to walk out, but Mr Martin shakes his head in despair.";
                                               }
                                               print (string) STR_REALLY_LEAVE;
                                               if(YesOrNo()==false)
                                                       print_ret (string) STR_STAY;
                                               SetFlag(F_SCENE_3_PREMATURE_EXIT);
                                       }
                                       print (string) STR_CUT;
                                       SetScene(S_AFTER_FILMING);
                                       Director.number = -1;
                               }
               ],
               s_to RussianStationDoor,
               cheap_scenery
                       'russian' 'station'
                               "The station looks more modern than you had expected."
                       3 'red' 'aluminium' 'chair'
                               [;
                                       Examine: "A simple red chair, all made of aluminium.";
                                       Enter: "You're not tired.";
                               ]
                       4 'golden' 'fabric' 'bed' 'beds//p'
                               "The beds have all been made, and are covered in a golden fabric."
                       CS_PARSE_NAME
                               [ _word _count;
                                       _word = NextWord();
                                       if(_word == 'reading' or 'writing') {
                                               _count++;
                                               _word = NextWord();
                                       }
                                       if(_word == 'and' && _count) {
                                               _count++;
                                               _word = NextWord();
                                       }
                                       if(_word == 'reading' or 'writing') {
                                               _count++;
                                               _word = NextWord();
                                       }
                                       if(_word == 'desk') {
                                               _count++;
                                       }
                                       return _count;
                               ] "It's a clean desk, with just the necessary stuff for doing a bit of
                                       writing and, of course, reading."
                       'desks//p''tables//p'
                               "There are several desks with equipment, and one seems to be for reading and writing."
                       1 'equipment'
                               "They seem to have just about the same kind of equipment as you do, only
                                       it looks bulkier, but also tougher.";

Class SlidingDoor
       with
               describe [; rtrue; ],
               description [;
                       print_ret (The) self, " is a pale light blue, and it's closed as usual.";
               ],
               before [;
                       Open, Close: "It can't be operated manually. It opens automatically when you approach it, and closes
                               once you've passed through it.";
               ],
       has static door open;

SlidingDoor QuartersDoor "crew's quarters door"
       with
               parse_name [_word _count _def;
                       _word = NextWord();
                       while(_word == 'crew' or 'crew^s' or 'quarter' or 'quarters' or 'quarter^s' or 'sliding' or 'door' ||
                                       (_word == 'east' or 'e//' && location == Quarters) ||
                                       (_word == 'west' or 'w//' && location == PropRoom)) {
                               _count++;
                               if(_word == 'sliding' or 'door' or 'east' or 'e//' or 'west' or 'w//') _def++;
                               _word = NextWord();
                       }
                       if(location == PropRoom)
                               return _count;
                       if(_def)
                               return _count;
               ],
               found_in Quarters PropRoom,
               door_dir (e_to) (w_to),
       has absent;

SlidingDoor LabDoor "lab door"
       with
               parse_name [_word _count _def;
                       _word = NextWord();
                       while(_word == 'lab' or 'laboratory' or 'sliding' or 'door' ||
                                       (_word == 'east' or 'e//' && location == PropRoom) ||
                                       (_word == 'west' or 'w//' && location == Lab)) {
                               _count++;
                               if(_word == 'sliding' or 'door' or 'east' or 'e//' or 'west' or 'w//') _def++;
                               _word = NextWord();
                       }
                       if(location == PropRoom)
                               return _count;
                       if(_def)
                               return _count;
               ],
               found_in Lab PropRoom,
               door_dir (w_to) (e_to);

SlidingDoor OfficeDoor "office door"
       with
               parse_name [_word _count _def;
                       _word = NextWord();
                       while(_word == 'office' or 'sliding' or 'door' ||
                                       (_word == 'north' or 'n//' && location == PropRoom) ||
                                       (_word == 'south' or 's//' && location == Office)) {
                               _count++;
                               if(_word == 'sliding' or 'door' or 'north' or 'n//' or 'south' or 's//') _def++;
                               _word = NextWord();
                       }
                       if(location == PropRoom)
                               return _count;
                       if(_def)
                               return _count;
               ],
               found_in Office PropRoom,
               door_dir (s_to) (n_to);

SlidingDoor RussianStationDoor "Russian station door"
       with
               short_name [;
                       if(game_scene == S_SCENE_2) {
                               print "door to the station commander's room";
                               rtrue;
                       }
               ],
               description [;
                       if(location == RussianStation)
                               "The door is a dark red, and it's closed as usual.";
                       self.SlidingDoor::description();
               ],
               parse_name_scene_2 [_word _count _def;
                       _word = NextWord();
                       while(_word == 'door' or 'to' or 'the' or 'station' or 'commander^s' or
                                       'commanders' or 'private' or 'room' or 'north' or 'n//')  {
                               _count++;
                               if(_word == 'sliding' or 'door' or 'north' or 'n//' or
                                       'commander^s' or 'commanders' or 'private') _def++;
                               _word = NextWord();
                       }
                       if(_def)
                               return _count;
               ],
               parse_name [_word _count _def;
                       if(game_scene == S_SCENE_2)
                               return self.parse_name_scene_2();
                       _word = NextWord();
                       while(_word == 'russian' or 'station' or 'sliding' or 'door' ||
                                       (_word == 'north' or 'n//' && location == Office) ||
                                       (_word == 'south' or 's//' && location == RussianStation)) {
                               _count++;
                               if(_word == 'sliding' or 'door' or 'north' or 'n//' or 'south' or 's//') _def++;
                               _word = NextWord();
                       }
                       if(location == Office)
                               return _count;
                       if(_def)
                               return _count;
               ],
               found_in RussianStation Office,
               door_dir (s_to) (n_to);

AdjObject OutsideDoor "door that leads outside"
       with
               noun_name 'non-sliding' 'nonsliding' 'normal' 'black' 'front'
                       'south' 's//' 'door' 'that' 'leads' 'leading' 'to' 'the' 'outside',
               description "The door is a clean black color. It looks like a front door you
                       would expect to find in a home.",
               describe [; rtrue; ],
               found_in OutsidePropRoom PropRoom,
               door_dir (n_to) (s_to),
       has door static openable;

Object EntertainmentSystem "entertainment system"
       with
               article [; if(location == Quarters) print "an"; else print "a"; rtrue; ],
               short_name [; if(location == Backlot) { print "door"; rtrue; } ],
               parse_name [ _count;
                       if(location == Quarters)
                               while(NextWord() == 'entertainment' or 'system' or 'bulky' or 'panel') _count++;
                       else
                               while(NextWord() == 'grey' or 'gray' or 'stage' or 'door') _count++;
                       return _count;
               ],
               describe [; rtrue; ],
               description [;
                       if(location == Backlot)
                               "It's been painted gray, and rather sloppily so.";
                       give ControlWheel ~concealed;
                       give SelectLever ~concealed;
                       print "It's like a rather bulky panel protruding from the western wall.
                               It looks a bit like a jukebox, with a wheel and a select lever to control it.";
                       if(self has open)
                               "^^The panel has swung to the side, revealing an exit to the west.";
                       "";
               ],
               before [;
                       if(location ~= Quarters) rfalse;
                       SwitchOn, SwitchOff:
                               "You'd need to tell me exactly how to do that.";
                       Take, Remove:
                               if(self has open)
                                       "Now that's just absurd.";
                               "No chance! It does sway a little as you tug at it though.";
                       Search, Touch:
                               "It feels fake. While it looks sturdy, the surface wiggles a bit when
                                       you touch it, as if it's just a thin plastic facade.";
                       Open:
                               if(self has open)
                                       "The panel has already been swung to the side, revealing an exit leading west.";
                               give self open;
                               if(self hasnt general) {
                                       ! First time the door is opened, so this marks the discovery of the hidden exit!
                                       score = score + 3;
                                       give self general;
                               }
                               scope_modified = true;
                               MoveFloatingObjects();
                               "The panel swings to the side, revealing an exit leading west.";
                       Pull:
                               if(self hasnt open) <<Open self>>;
                               "The panel wiggles a little.";
                       Push:
                               if(self has open) <<Close self>>;
                               "The panel wiggles a little.";
                       Close:
                               if(self hasnt open) {
                                       if(verb_word == 'move')
                                               <<Open self>>;
                                       "The panel isn't open.";
                               }
                               give self ~open;
                               scope_modified = true;
                               MoveFloatingObjects();
                               "The panel closes quietly.";
                       Turn:
                               if(self has open)
                                       <<Close self>>;
                               <<Open self>>;
               ],
               found_in Backlot Quarters,
               door_dir (e_to) (w_to),
       has door static transparent openable absent;

Object -> ControlWheel "control wheel"
       with
               name 'control' 'wheel',
       description "It's a disc, probably screwed or glued to the panel.",
       before [;
               Turn, Push, Pull:
                       "It doesn't move. It looks like it's just a protruding disc, rather than
                               an actual control wheel.";
       ],
       has static concealed;

Object -> SelectLever "select lever"
       with
               name 'select' 'lever' 'little' 'stick',
               description "It's like a little stick that's been glued to the panel.",
       before [;
               Turn, Push, Pull:
                       "It won't budge at all. It doesn't actually look like a lever up close,
                               more like a little stick that's been glued to the panel.";
       ],
       has static concealed;

LightRoom Backlot "Backlot"
       with
               description [;
                       print "A generic Mars landscape, with red sand covering the ground. A somewhat
                               believable cliff, 4-5 metres high, looms to the east. ";
                       if(EntertainmentSystem has open)
                               "A door stands open in the cliffside.";
                       else
                               "While not really visible to anyone who hasn't seen it open, there's a door
                                       set in the cliffside.";
               ],
               e_to EntertainmentSystem,
               cant_go "This is not the time to go exploring.";

Object -> TrashCan "trash can"
       with
               name 'trash' 'can' 'hole',
               description "The trash can is pretty big, with a hole high up.",
               invent [;
                       if(inventory_stage == 2) rtrue;
               ],
               before [;
                       Receive:
                               if(~~(noun ofclass EmptyBottle))
                                       "That's not trash!";
                       Take, Remove, Turn, Push, Pull:
                               "You're hired as an actor, someone else has the job of emptying the garbage cans around here.";
                       Search:
                               "You can't see what's inside.";
                       Enter:
                               "The opening is way too small.";
               ],
               after [;
                       Receive:
                               if(noun ofclass EmptyBottle) {
                                       remove noun;
                                       scope_modified = true;
                                       print_ret (The) noun, " disappears into the darkness of the trash can.";
                               }
                               "Better not throw that away. You might need it.";
               ],
       has container open static;

Class EmptyBottle
       with
               before [;
                       Drink:
                               "No thanks! You had quite enough yesterday.";
                       Receive:
                               "You need to get rid of the bottle, not fill it!";
               ],
               after [;
                       Insert:
                               if(second == TrashCan)
                                       score = score + 3;
                       Drop:
                               if(location == Backlot)
                                       score = score + 3;
                       Take:
                               if(location == Backlot)
                                       score = score - 3;
               ],
       has container transparent open;


EmptyBottle TequilaBottle "tequila bottle"
       class AdjObject,
       with
               adj_name 'empty',
               noun_name 'bottle' 'bottles//p' 'jar' 'jars//p' 'tequila',
               description "It's some cheap brand. Whatever you could find at the closest liquor store yesterday.",
               invent [;
                       if(inventory_stage == 2) {
                               print " (empty)";
                               rtrue;
                       }
               ];

EmptyBottle GrenadineBottle "grenadine bottle"
       class AdjObject,
       with
               adj_name 'half' 'empty' 'half-empty' 'halfempty',
               noun_name 'bottle' 'bottles//p' 'jar' 'jars//p' 'grenadine' 'label',
               description "Someone spilled a bit on the label. Doesn't matter, you just need to get rid of the bottle now.",
               before [;
                       Search: "There's some grenadine in the bottle. You sure don't feel like drinking it.";
                       Drink, Empty: "Better leave it be.";
               ],
               invent [;
                       if(inventory_stage == 2) {
                               print " (half-empty)";
                               rtrue;
                       }
               ];

Object SilverBlanket "silver blanket"
       with
               name 'silver' 'blanket',
               description "It's warm, but not very nice or comfy.",
               describe [; rtrue; ],
               before [;
                       Take, Remove, Pull, Push, Turn, Fold:
                               if(Tina.awake)
                                       "You pick it up, fold it neatly and put it on the bed.";
                               "But she looks so comfortable!";
               ];

! ------------------------------------------------------------------------------
!       Tina
! ------------------------------------------------------------------------------

[ SetTinaName;
       ! The proper attribute is used to signal that the player knows their name
       ! *and* it removes the article, so we don't get "the Tina"
       give Tina proper;
];

[ TinaPerformExit;
       give EntertainmentSystem open;
       print "~Okay, I'll slip out. Talk to you later!~^";
       MovePerson(Tina, Backlot);
       remove Tina;
       scope_modified = true;
       MaybePartyGone();
       score = score + 13;
];

Constant ID_LEAVE = 300;

[ TinaLeaveLine;
       if(EntertainmentSystem has general)
               print "Yeah, that's probably a good idea.";
       else
               print "Well sure, but I can't just stroll out into the next room, can I?
                       Someone will see me, and you'll be in all sorts of trouble. Are you sure
                       there isn't another way out?";
];

[ TinaLeaveDo;
       if(EntertainmentSystem has general) {
               print "^", (The) Tina, " takes a last look to make sure she hasn't left any personal items.^^";
               talk_menu_talking = false;
               TinaPerformExit();
       }
];

Array tina_talk_array -->
       30 "Name"
               TM_ADD_BEFORE_AND_AFTER
               "Feeling extremely awkward, you decide to just bite the bullet."
               "Sorry, but I can't remember your name."
               "She looks a bit offended at first, but then she just gives out a quiet giggle."
               "It's Tina, dummy!" SetTinaName
       30 "Last night"
               "Hey, this may seem like a strange question, but do you recall what happened last night?"
               "Well, sure I do! You invited me over for a party. Your friends were here, but they left kinda early."
                       1 3
       0 "Sleeping" "So, um... did you get some sleep?"
               "Me? Yeah, I'm okay. You had a lot to drink, and fell asleep.
                       I didn't feel like trying to get home in the middle of the night,
                       so I just went to sleep next to you." 1
       0 "Drink" "Oh right, i do remember drinking something... What was it?" "Really, you don't remember? You were
               making that drink that's all the rave now - Tequila Sunrise, and you were good at it!"
       0 ID_LEAVE "You should leave"
               "I think you'd better go now."
               TinaLeaveLine
                       TinaLeaveDo
       TM_END;

[ TinaBefore;
       Talk:
               if(GetTopicStatus(self, ID_LEAVE) == TM_STALE)
                       ReActivateTopic(Tina, ID_LEAVE);
               rfalse;
       Pull, Push:
               print "She gives you a playful push back";
               if(EntertainmentSystem has general) {
                       print ", with a giggle: ~I get it, you've
                               got other things to tend to!~
                               ^^She looks around to make sure she hasn't left any personal items.^^";
                       TinaPerformExit();
                       rtrue;
               }
               ".";
       PushDir:
               if(selected_direction == e_to)
                       "~Are you trying to push me out where there's people? You'll just get in trouble!~";
               if(selected_direction == w_to && EntertainmentSystem has general)
                       <<Push self>>;
               "~Stop it, you want to push me into a wall?~";
       default:
               rfalse;
];

[ TinaGetBottle;
       move noun to self;
       scope_modified = true;
       score = score + 3;
       "~Sure, I'll get rid of it for you.~ she giggles.";
];

[ TinaOrders;
       Go:
               if(self in Quarters) {
                       if(selected_direction == e_to) {
                               "~I think I heard someone out there. Isn't there another way out?~";
                       }
                       if(selected_direction == w_to) {
                               if(EntertainmentSystem hasnt general)
                                       "~What are you talking about? There's just a wall there.~";
                               TinaPerformExit();
                               rtrue;
                       }
                       "~There's just nowhere to go in that direction!~";
               }
               "~I'm fine where I am thanks!~";
       Take:
               if(noun in Tina)
                       "~Well I already have ", (ThatOrThose) noun, "!~ she giggles.";
               if(noun ofclass EmptyBottle) {
                       TinaGetBottle();
                       rtrue;
!                       move noun to self;
!                       scope_modified = true;
!                       score = score + 3;
!                       "~Sure, I'll get rid of it for you.~ she giggles.";
               }
               "~I don't need ", (ThatOrThose) noun, ".~";
       NotUnderstood:
               "~Come again?~";
       default:
               print (string) self.&wont_do-->self.number;
               self.number++;
               if(2*self.number >= self.#wont_do) self.number = 0;
               new_line;
               rtrue;
];

Object Tina "girl"
       with
               name 'girl' 'tina',
               short_name [;
                       if(self has proper) { print "Tina"; rtrue; }
               ],
               describe [;
                       SetFlag(F_SEEN_TINA);
                       if(self.awake) {
                               new_line;
                               if(self has proper) print (name) self;
                               else print "A girl";
                               print " is here, ";
                               if(self hasnt general) {
                                       give self general;
                                       "dressed more for a beach party than for space exploration.";
                               }
                               "wearing quite casual clothing.";
                       } else {
                               print "^Wrapped in a silver blanket, a girl lies sound asleep ";
                               if(player in YourBed)
                                       "next to you.";
                               "on your bed.";
                       }
               ],
               react_before [;
                       ! Capture all actions where Tina/girl is noun or second, while she's asleep
                       if(self.awake == 0 && self == noun or second) {
!                               if(action == Examine) rfalse;
                               if(action == ##Search or ##Take or ##Push or ##PushDir or ##Pull or
                                       ##Turn or ##Attack or ##Kiss or ##WakeOther or ##Touch) {
                                       self.awake = 1;
                                       move SilverBlanket to YourBed;
                                       self.before = TinaBefore;
                                       self.orders = TinaOrders;
                                       "The girl opens her eyes and looks surprised.^^
                                               She slips out of bed, fully awake but with a confused look on her face.";
                               }
                               if(action == ##Talk or ##Give or ##Show)
                                       "There's no reaction from the girl. She's still sound asleep.";
                       }
               ],
               before 0,
               life [;
                       if(self.awake == 0) <<Talk self>>;
               Give:
                       if(~~(noun ofclass EmptyBottle))
                               "~Hey, what am I supposed to do with that? You hang on to it!~";
                       TinaGetBottle();
                       rtrue;
!                       move noun to self;
!                       scope_modified = true;
!                       "~Sure, I'll get rid of it for you.~ she giggles.";
               Kiss: "You're not that close, you think.";
               ],
               orders 0,
               number 0,
               wont_do
                       "~Now look, I should probably get out of here.~"
                       "~I really don't think this is the time. How can I get out of here unnoticed?~"
                       "~Shouldn't you worry less about that and more about getting me out of here, before any of the bigwigs show up?~",
               description [;
                       print "She has blond hair down to her shoulders. ";
                       if(PrintContents("In her hands you can see ", self)) ".";
                       "";
               ],
               awake 0,
               talk_array tina_talk_array,
       has animate female transparent;

[ MaybePartyGone;
       if(superparent(TequilaBottle) ~= Quarters && superparent(GrenadineBottle) ~= Quarters &&
                       Tina in nothing)
               SetFlag(F_PARTY_GONE);
];

[ PartyDetected p_seen_girl;
       print "^Mr Martin ";
       if(Director notin location)
               print "comes striding in, and he looks like he's about to burst. He ";
       print "turns to you: ~What the heck, Mike? I thought we were on the same page here,
               that you would show a more professional attitude towards your work, and
               you immediately go and do THIS? Drinking liquor, at the studio?";
       if(p_seen_girl)
               print " And on top of that, you let some random girl in, and let her spend the night here!";
       print " What were you thinking?~
               ^^Mr Martin looks down, shakes his head, and says
               ~Look Mike, I'm gonna have to let you go. We'll get a different actor and re-record
               your scenes in the first episode. Get your stuff, and leave.~^";
       deadflag = GS_DEATHMESSAGE;
];

[ RingBell;
       bell_rung = turns;
       if(location == PropRoom)
               print "^Mr Martin rings the bell";
       else
               print "^From the prop room you hear";
       ": ~Ding ding ding~";
];

! Returns true if a party was detected
[ LookForParty _loc;
       _loc = superparent(Director);
       if(superparent(Tina) == _loc) {
               PartyDetected(true);
               rtrue;
       }
       if(_loc == superparent(TequilaBottle) or superparent(GrenadineBottle)) {
               PartyDetected(false);
               rtrue;
       }
       rfalse;
];

[ DirectorIntro;
       if(FlagIsClear(F_DIRECTOR_INTRO)) {
               SetFlag(F_DIRECTOR_INTRO);
               waittime_waiting = false;
               "^~Mike, there you are!~ says Mr Martin, ~Things got a
                       little heated yesterday, but let's look forward. Let's make
                       a great episode today, and build from there.~";
       }
];

Array direction_inverse_array static -> 0 2 1 4 3 6 5 8 7;

[ MovePerson p_person p_destination _i _loc _val;
       if(p_person in p_destination) return;
       _loc = parent(p_person);
       move p_person to p_destination;
       if(location ~= _loc or p_destination) return;

       if(location == p_destination)
               waittime_waiting = false;
       scope_modified = true;
       if(_loc ~= nothing) {
               for(_i = 1 : _i <= DIRECTION_COUNT : _i++) {
                       _val = _loc.(direction_properties_array->_i);
                       if(_val > Directions && _val <= top_object &&
                                       _val has door && _val.#found_in > 3) {
                               if(_val.&found_in-->0 == _loc)
                                       _val = _val.&found_in-->1;
                               else
                                       _val = _val.&found_in-->0;
                       }
                       if(_val == p_destination)
                               break;
               }
               if(_i <= DIRECTION_COUNT) {
                       if(player in _loc)
                               "^", (The) p_person, " goes ", (string) direction_name_array-->_i, ".";
                       if(player in p_destination)
                               "^", (The) p_person, " enters from the ", (string) direction_name_array-->(direction_inverse_array->_i), ".";
               }
       }
       if(player in _loc)
               "^", (The) p_person, " leaves.";
       if(player in p_destination)
               "^", (The) p_person, " appears.";
];

LightRoom OutsidePropRoom "Outside"
       with
               description "You're outside.",
               n_to OutsideDoor;


! ------------------------------------------------------------------------------
!       Director, Mr Martin
! ------------------------------------------------------------------------------

Constant ID_DIRECTOR_PLAN = 300;

Array director_talk_free -->
       30 "Yesterday"
               "Should we have a talk about what happened yesterday?"
               "Let's not. We need to look forward, and make this work."
       30 "The series"
               TM_ADD_AFTER
               "Mr Martin, what do think this series is really about?"
               "Mr Martin looks interested and a little surprised to
                       get this question from you."
               "That's a good question, Mike. On the surface it's obviously a science
                       fiction drama, about this small crew, millions of miles from home.
                       But then again, this crew is just a group of people, having their
                       doubts and insecurities, and their dynamic as a group. For the
                       most part, it could really have been set in Victorian England
                       instead."
               "Mr Martin smiles at his own analysis."
       TM_END;

Array director_talk_before_scene_1 -->
       30 "Plan for today"
               "So, what's your plan for today?"
               "We have three scenes to shoot, that's all." 1 3 4
       0 "First scene"
               "What can you tell me about the first scene?"
               "In the first scene, Billy sure walks the tightrope. He's eager to
                               prove his worth to Steve, but at the same time he wants
                               to stay on the good side of Nadia." 1
       0 "Script"
               "I don't think I've received the script for this scene."
               "Mike, you're an actor, right? In my experience, we can't get the
                       needed dynamic and emotion out of a material like this with a
                       script. A script would just limit you. You know what the scene is
                       about, now it's time to get into character and think:
                       What would Billy have done?"
       0 "Second scene"
               "What about the second scene?"
               "You'll talk to Steve. He'll want to see some results. But let's worry
                       about that later - right now you need to focus on your scene with
                       Nadia."
       0 "Third scene"
               "For the third scene, I'm meeting the Russians?"
               "Yeah, well one of them anyway. You'll pop over to the Russian base to
                       meet Sergey and talk about cooperation."
       TM_END;

Array director_talk_before_scene_2 -->
       30 "Plan for today"
               "So, what's your plan for the rest of the day?"
               "Well, we have two scenes left to shoot - Your meeting with Steve, and your
                       visit to the Russian base." 1 4
       0 "Meeting with Steve"
               "What's with this meeting with Steve?"
               "You've had a bit of a run-in with Steve, and now you're eager to show him
                       that you can be useful, that he can trust you. He has asked you to
                       find out if Nadia has talked to the Russians, and if so, what they've
                       talked about." 1 2
       0 "Giving Steve information"
               "So I just hand over any information I have to Steve?"
               "Well actually no. While you want to give him the information, you want to
                       make sure that he values you as an ally, that he understands he needs
                       you on his side. So you don't want to give up the information too easily."
       0 "Nadia meeting the Russians"
               "Why does Steve care whether Nadia met the Russians or not?"
               "Steve has a pragmatic view of the Russians. You'll need to work with them,
                       but Steve must be in on it."
       0 "Scene 3"
               "So after this scene, I'm off to the Russian base?"
               "Yeah, but let's focus on the scene at hand now."
       TM_END;

Array director_talk_before_scene_3 -->
       30 ID_DIRECTOR_PLAN "Plan for today"
               "So, what's your plan for the rest of the day?"
               "Well, we only have one scene left to shoot. Let's make it good!"
       TM_END;

Array director_talk_array -->
       TM_MAYBE_ADD_LIST F_DIRECTOR_IS_FREE director_talk_free
       TM_MAYBE_ADD_LIST F_BEFORE_FILMING director_talk_before_scene_1
       TM_MAYBE_ADD_LIST F_INTERLUDE_1 director_talk_before_scene_2
       TM_MAYBE_ADD_LIST F_INTERLUDE_2 director_talk_before_scene_3
       TM_END;

Object -> Director "Mr Martin"
       with
               name 'director' 'mr' 'martin',
               description [;
                       if(self has general)
                               "Mr Martin wears casual but carefully matched clothes,
                                       well-polished boots, and his grey
                                       hair really suits him.";
                       give self general;
                       "Mr Martin is an experienced director, and he looks the
                       part. He's actually mostly known for cranking out B-movies with
                       a lot of action, but he's been known to make everything from
                       highbrow costume dramas to intense thrillers. He has mostly grey
                       hair and a seriously receding hairline. From what you hear,
                       women still find him really attractive though, and you're not
                       surprised - he has a lot of charisma. He wears a stylish red
                       track suit over a Sex Pistols T-shirt, and a pair of black,
                       well-polished boots.";
               ],
               number 0,
               before [;
                       Talk:
                               if(game_scene == S_INTRO)
                                       "~Not right now, Mike. I need to get ready for the morning meeting.~";
                               if(game_scene == S_AFTER_FILMING)
                                       "~This is not a good time, Mike. I need to wrap things up here.~";
                               if(game_scene == S_SCENE_1 or S_SCENE_2 or S_SCENE_3)
                                       "Mr Martin quietly shakes his head, horrified that's you're about
                                               to start to talk to him in the middle of a scene.";

               ],
               orders [;
                               if(game_scene == S_SCENE_1 or S_SCENE_2 or S_SCENE_3)
                                       "Mr Martin puts his index finger to his lips as if to hush you, but says nothing.";
                       default:
                               "Mr Martin looks at you with a puzzled expression: ~I'm the director
                                       here. You know that, right?~";
               ],
               life [;
                       Kiss, Attack:
                               "You don't have the nerve.";
               ],
               daemon [;
                       switch(game_scene) {
                       S_INTRO:
                               if(FlagIsClear(F_PARTY_GONE)) {
                                       MaybePartyGone();
                                       if(LookForParty()) return;
                               }
                               if(self in location)
                                       DirectorIntro();
                               self.number++;
                               ! If all is good, fast-forward
                               if(self.number > 2 && self.number < 30 &&
                                               parent(player) ~= Quarters or Backlot && FlagIsSet(F_PARTY_GONE))
                                       self.number = 30;
                               switch(self.number) {
                                       2:      move self to PropRoom;
                                               waittime_waiting = false;
                                               if(player in PropRoom) {
                                                       scope_modified = true;
                                                       print "^The front door opens and Mr Martin, the director, enters.
                                                               You suddenly remember the argument you had yesterday. He was pretty
                                                               upset, and you definitely think he considered firing you on the
                                                               spot. If he figures out that you threw a party here,
                                                               or that you had a girl staying over, you are history!^";
                                               } else
                                                       print "^From the next room, you hear someone entering from the
                                                               outside. You instantly recognize the heavy boots of Mr Martin,
                                                               the director. Oh no, he was on the verge of firing you yesterday.
                                                               If he figures out that you threw a party here,
                                                               or that you had a girl staying over, you are history!^";
                                       30:     MovePerson(self, Quarters);
                                               if(LookForParty()) return;
                                       31:     MovePerson(self, PropRoom);
                                       32:     StartDaemon(Linda);
                                               StartDaemon(Keith);
                                               StartDaemon(Ivan);
                                               RingBell();
                               }
                               if(self in location)
                                       DirectorIntro();
                               if(self in PropRoom && Linda in PropRoom && Keith in PropRoom && player in PropRoom) {
                                       SetScene(S_BEFORE_FILMING);
                                       self.number = 10;
                                       waittime_waiting = false;
                                       "^Mr Martin clears his throat. ~Okay, everyone's here,
                                               let's get this day started! We have three scenes to
                                               shoot today. You'll have a lot of freedom in creating
                                               these scenes. I'll give you an overview of each scene,
                                               and you take it from there, okay?

                                               ^^So, scene one: Billy, played by Mike of course, has
                                               had a conversation with Steve, where Steve aired his
                                               concerns that Nadia may be getting too friendly with
                                               the Russians, possibly even leaking secrets. Billy
                                               finds Nadia, played by Linda, in the Lab, and should
                                               try to find out if she's been meeting up with any of
                                               the Russians without telling Steve about it. Also,
                                               Billy wants Nadia to like him, so he has to be careful.

                                               ^^Then for scene two, Billy will be meeting Steve to
                                               discuss his findings.

                                               ^^Finally, for scene three, Billy will be heading over
                                               to the Russian base to meet Sergey, played by Ivan.~

                                               ^^Any questions? If not, Mike and Linda, just meet me on the Lab set
                                               when you're ready to shoot the first scene!~";
                               }
                       S_BEFORE_FILMING:
                               self.number--;
                               if(self.number < 1) {
                                       if(self notin Lab) {
                                               if(self in location)
                                                       print "^Mr Martin turns towards you: ~It's time, Mike.
                                                               Now get in there and show us what you can do!~^";
                                               MovePerson(self, Lab);
                                       }
                                       if(location == Lab) {
                                               waittime_waiting = false;
                                               print "^Mr Martin turns towards you: ~Mike and Linda, do
                                                       your thing. Play out the scene, and when you're all done,
                                                       Mike examines the mass spectrometer - that's our cue to end the
                                                       scene. Here we go: 3, 2, 1 and ACTION!~^";
                                               SetScene(S_SCENE_1);
                                       }
                               }

                       S_SCENE_1:
                               if(scene_over) {
                                       SetScene(S_INTERLUDE_1);
                                       self.number = -1;
                                       "^Mr Martin shouts ~And CUT!~";
                               }
                       S_INTERLUDE_1:
                               if(self.number++ == 3 && self in Lab) {
                                       MovePerson(self, PropRoom);
                                       self.number = 0;
                               }
                               if(self.number > 3 && FlagIsClear(F_DIRECTOR_TALKED_ABOUT_SCENE_2)) {
                                       if(self in PropRoom && player in PropRoom) {
                                               self.number = 0;
                                               StartDaemon(Keith);
                                               SetFlag(F_DIRECTOR_TALKED_ABOUT_SCENE_2);
                                               waittime_waiting = false;
                                               "^Mr Martin turns to you and Keith:
                                                       ~It's time for your scene, guys! Steve, portrayed by Keith,
                                                       is in the office, writing a memo or something.
                                                       Billy enters the room. There's a lot of tension here.
                                                       Steve and Billy have clashed a bit lately, and Billy wants
                                                       to make sure Steve knows he can rely on Billy,
                                                       but also that Steve knows he needs Billy as an ally.
                                                       So it's essential that Billy keeps his integrity -
                                                       he's not Steve's puppet.
                                                       You take it from there, guys. I know you've got this!
                                                       Meet me in the Office set when you're ready.~";
                                       }
                               } else if (FlagIsSet(F_DIRECTOR_TALKED_ABOUT_SCENE_2)) {
                                       if(self.number == 8)
                                               MovePerson(self, Office);
                                       if(location == Office && self in Office && Keith in Office) {
                                               waittime_waiting = false;
                                               print "^Mr Martin looks excitedly at you: ~Keith, Mike, give us all
                                                       you've got! Just play your parts until you've achieved what you can
                                                       with the scene, then Mike exits through the south door, and we end
                                                       the scene. All clear? Good. 3, 2, 1 and ACTION!~
                                                       ^^Steve, holding a pen, looks up from his desk with
                                                               a thoughtful expression: ~Thanks for coming Billy!~^";
                                               SetScene(S_SCENE_2);
                                               if(FlagIsSet(F_NADIA_ADMITTED_CONTACT))
                                                       InactivateTopic(Keith, ID_NO_RUSSIANS);
                                               else
                                                       InactivateTopic(Keith, ID_RUSSIANS);
                                       }
                               }
                       S_SCENE_2:
                               if(scene_over) {
                                       SetScene(S_INTERLUDE_2);
                                       self.number = -1;
                                       "^Mr Martin shouts ~And CUT!~";
                               }
                       S_INTERLUDE_2:
                               if(self.number < 0 && self in Office) {
                                       MovePerson(self, PropRoom);
                                       self.number = 0;
                               }
                               if(FlagIsClear(F_DIRECTOR_TALKED_ABOUT_SCENE_3)) {
                                       if(self in PropRoom && player in PropRoom) {
                                               StartDaemon(Ivan);
                                               waittime_waiting = false;
                                               SetFlag(F_DIRECTOR_TALKED_ABOUT_SCENE_3);
                                               print "^Mr Martin addresses you and Ivan:
                                                       ~Time for the last scene for today.
                                                       Billy enters the Russian base, where
                                                       he meets Sergey. Billy wants to ";
                                               if(FlagIsSet(F_NADIA_ADMITTED_CONTACT))
                                                       print "address the fact that Nadia and Sergey met,
                                                               without clearing this with their station commanders,";
                                               else
                                                       print "check if Sergey has met up with Nadia, or
                                                               if he thinks anyone else from their crew has,";
                                               " but at the same time, he wants to encourage more cooperation
                                                       between the two crews. All clear?
                                                       Just go in there and do your magic!
                                                       Recording starts on the Russian base set
                                                       when you're ready.~";
                                       }
                               } else {
                                       if(self.number++ == 8)
                                               MovePerson(self, RussianStation);
                                       if(self.number == 7)
                                               MovePerson(self, Office);
                                       if(location == RussianStation && self in RussianStation && Ivan in RussianStation) {
                                               print "^Mr Martin looks excitedly at you: ~Ivan, Mike, show us
                                                       what you can do! You just act out the scene until you're done,
                                                       then Mike exits the room, and we cut. Ready? 3, 2, 1 and ACTION!~
                                                       ^^Sergey is repairing some equipment at a desk. As you approach him, he
                                                               looks up and greets you with a smile: ~Welcome friend, how can I
                                                               help you?~^";
                                               SetScene(S_SCENE_3);
                                       }
                               }
                       S_SCENE_3:
                               if(scene_over) {
                                       SetScene(S_AFTER_FILMING);
                                       self.number = -1;
                                       "^Mr Martin shouts ~And CUT!~";
                               }
                       S_AFTER_FILMING:
                               switch(parent(self)) {
                               RussianStation:
                                       MovePerson(self, Office);
                                       self.number = 0;
                               Office:
                                       MovePerson(self, PropRoom);
                               PropRoom:
                                       if(location == PropRoom)
                                               EndOfDay();
                               }
                       }
               ],
               talk_array director_talk_array,
       has animate proper transparent;

AdjObject -> -> DirectorClothes "Mr Martin's clothes"
       with
               adj_name 'mr' 'martins' 'martin^s' 'pair' 'of',
               noun_name 'stylish' 'red' 'track' 'suit' 'sex' 'pistols' 'tshirt' 't-shirt' 'clothes'
                       'black' 'well-polished' 'wellpolished' 'well' 'polished' 'boots',
               description "Mr Martin's clothes are impeccable, yet they look so casual.",
               before [;
                       Search, Take, Pull, Turn, Push, Attack, Touch, Kiss:
                               "You wouldn't dare.";
               ],
       has scenery proper;

! ------------------------------------------------------------------------------
!       Talk routines used for several actors
! ------------------------------------------------------------------------------

[ EndOfSceneTalk; talk_menu_talking = false; scene_over = true; ];
[ SceneCanBeOver; scene_can_be_over = true; ];

! ------------------------------------------------------------------------------
!       Linda
! ------------------------------------------------------------------------------

[ NadiaAttitudeUp; nadia_attitude = nadia_attitude + 10; if(nadia_attitude > 100) nadia_attitude = 100; ];
[ NadiaAttitudeDown; nadia_attitude = nadia_attitude - 10; if(nadia_attitude < 0) nadia_attitude = 0; ];
[ NadiaAdmit; score = score + 11; ];

Array linda_talk_free -->
       30 "How are you?"
               "Hey Linda, how are you doing today?"
               "I'm fine Mike. Look, I'm here to work. Let's just do our scene, okay?"
       TM_END;

Array linda_talk_scene_1 -->
       30 "Need help?"
               "Hey Nadia, you need some help?"
               "Well thanks Billy, I could actually use an extra pair of hands for today's work." 1
       0 "Today's work"
               "So, what are we doing today?"
               "I've collected some drill cores at the foot of the Eisenhower mountains.
                       I want to check the composition of the
                       soil at different depths." 1 2
       0 "Drill cores"
               "Getting drill cores was a great idea! In the words of the Fonz from that ancient
                       TV-series: Fantastic plan... fantastic plan!
                       I can't wait to see what we'll find."
               "Well thank you, and I'm glad you want to help out! I've fed an extract from the first
                       core into the mass spectrometer
                       over there. I suggest you take a look." NadiaAttitudeUp F_EXAMINE_SPECTROMETER
       0 "Who helped you drill?"
               TM_ADD_AFTER
               "Now wait a minute - the drill rig takes at least two people to operate... Who else was with you?"
               "Nadia's eyes widen, then narrow."
               "Did you come here to help me or to interrogate me? Oh wait, did Steve ask you to talk to me?"
               "She does not look happy."
               NadiaAttitudeDown TM_INACTIVATE (-1) 1 2
       0 "I'm on your side"
               TM_ADD_BEFORE_AND_AFTER
               "You look at her with your most convincing puppy eyes."
               "Hey, I'm on your side! I was just surprised that you had been using the drill rig without asking me to help out."
               "Nadia looks coldly at you at first, but then her expression softens."
               "Oh I know you look out for me Billy, I really do! And I look out for you. I just have this feeling that Steve doesn't trust me, and it's taking its toll. I'm sorry for lashing out."
               "She looks at you, seeking reassurance."
                       TM_INACTIVATE 1 NadiaAttitudeUp SceneCanBeOver 2 3
       0 "I can ask any question I like"
               TM_ADD_BEFORE_AND_AFTER
               "You look her sternly in the eyes."
               "Now look, I can ask any question I like."
               "Nadia stares at you defiantly. You think you see her lower lip shiver slightly, with anger."
               "Well if that's how it's gonna be, I don't need your help! You go somewhere else, where I don't have to see you!"
               NadiaAttitudeDown EndOfSceneTalk
       0 "Mind your manners"
               TM_ADD_AFTER
               "Okay, apology accepted. Just mind your manners, will you?"
               "Nadia looks taken aback."
               "...okay, sure. Let's just get on with our job now, okay?" TM_INACTIVATE 1 EndOfSceneTalk
       0 "We're a team"
               "Look, we're a team here. We're gonna be here for a long time. We have to
                       work together, and we have to trust each other. I know Steve thinks highly of you."
               "Thank you Billy, I know you're right. And since you asked, I did talk to Sergey
                       at the Russian station the other day, and they had been planning to drill
                       around there as well, so we did it together. I sure hope I wasn't
                       out of line."
                       NadiaAttitudeUp TM_INACTIVATE (-1) F_NADIA_ADMITTED_CONTACT NadiaAdmit 1 2
       0 "You're in trouble!"
               TM_ADD_AFTER
               "You talked to the Russians without getting permission from Steve? Wow, now you're in trouble, that's for sure!"
               "Nadia's eyes turn hard."
               "You talk like you're my friend, but you're just Steve's lap dog! Get out of my sight!"
                       NadiaAttitudeDown EndOfSceneTalk
       0 "We'll work this out"
               TM_ADD_BEFORE_AND_AFTER
               "You give Nadia a compassionate look."
               "Oh, that's not quite according to protocol... but we're all learning here. I'll talk to Steve about it.
                       I know you didn't mean to break protocol, and you'll be careful not do it again, right?"
               "Nadia looks humbled and a bit scared."
               "Oh no, I really messed up, didn't I? Talk to Steve, will you? I think that'll put him in a better mood
                       before I talk to him. Now, let's get on with our work."
                       NadiaAttitudeUp SceneCanBeOver TM_INACTIVATE (-1)
       TM_END;

Array linda_talk_array -->
       TM_MAYBE_ADD_LIST F_LINDA_IS_FREE linda_talk_free
       TM_MAYBE_ADD_LIST F_SCENE_1 linda_talk_scene_1
       TM_END;

Object -> Linda "Linda"
       with
               name 'linda' 'nadia',
               short_name [;
                       if(FlagIsSet(F_LINDA_IS_FREE))
                               rfalse;
                       print "Nadia"; ! Character name
                       rtrue;
               ],
               description [;
                       if(FlagIsSet(F_LINDA_IS_FREE)) {
                               if(self has general)
                                       "Linda has her silvery indoor space clothes on. Her long
                                               black hair frames her face.";
                               give self general;
                               "Linda is a few years older than you, about 28 you think. You
                                       talked to her a bit yesterday, and she said her mother is
                                       Polish. Evidently, her accent sounds Russian enough to
                                       Americans, and this has helped her land a number of roles
                                       as tough, powerful Russian women. She has an intense
                                       energy about her, amplified by her striking good looks,
                                       with black hair, fair skin and big, dark brown eyes. She's
                                       wearing the silvery space-wear that the producers think
                                       everyone should be wearing on Mars.";
                       }
                       "You give Nadia a long, meaningful glance, taking in the female
                               energy that she's constantly radiating. Her velvety black
                               hair falls so naturally around the clear features
                               of her light-skinned face. The big brown eyes are secretive,
                               yet inviting. She's soft as a kitty, in both
                               appearance and voice, but if someone steps out of line, you
                               know all too well that her claws come out, her voice deepens
                               to a growl, and whoever messed up better tread very carefully.
                               Talk about beauty and the beast - she's both.";
               ],
               before_onscreen [;
               ],
               life_onscreen [;
                       Kiss:
                               if(nadia_attitude < 50) {
                                       NadiaAttitudeDown();
                                       if(FlagIsSet(F_NADIA_HAD_BAD_KISS)) {
                                               NadiaAttitudeDown();
                                               scene_over = true;
                                               "Nadia hits you hard over the ear, then shouts:
                                                       ~Get off me, loser!~";
                                       }
                                       SetFlag(F_NADIA_HAD_BAD_KISS);
                                       "Nadia pulls away, avoiding your kiss, and gives you a
                                               light slap across the face.";
                               }
                               "Nadia smiles and quietly avoids your kiss.";
                       Attack:
                               NadiaAttitudeDown();
                               NadiaAttitudeDown();
                               scene_over = true;
                               "Nadia deflects your attack with ease, kicks you in the shin and shouts
                                       ~What the heck, Billy?~";
               ],
               orders_onscreen [;
               default:
                       "Nadia gives you a serious look: ~Oh Billy, you know I can't do that!~";
               ],
               before [;
                       if(FlagIsClear(F_LINDA_IS_FREE))
                               return self.before_onscreen();
                       Talk:
                               if(game_scene == S_INTRO)
                                       "~Sorry, Mike, I think Mr Martin is about to talk. Let's chat later.~";
               ],
               life [;
                       if(FlagIsClear(F_LINDA_IS_FREE))
                               return self.life_onscreen();
                       Kiss:
                               "Linda looks surprised, and pushes you away: ~What the hell, Mike?
                                       The cameras aren't rolling!~";
                       Attack:
                               "Linda evades your attack, looking surprised and angry: ~What's
                                       your problem, Mike?~";
               ],
               orders [;
                       if(FlagIsClear(F_LINDA_IS_FREE))
                               return self.orders_onscreen();
                       default:
                               "~You don't get to tell me what to do, Mike.~";
               ],
               daemon [;
                       switch(game_scene) {
                       S_INTRO:
                               if(bell_rung == turns - 2 && self notin PropRoom) {
                                       MovePerson(self, PropRoom);
                                       self.number = 7;
                               }
                       S_BEFORE_FILMING:
                               self.number--;
                               if(self.number == 0)
                                       MovePerson(self, Lab);
                       S_INTERLUDE_1:
                               if(self.number < 0)
                                       self.number = 0;
                               self.number++;
                               if(self.number == 3) {
                                       MovePerson(self, PropRoom);
                                       StopDaemon(self);
                                       self.number = 0;
                               }
                       S_INTERLUDE_2:
                               if(self.number++ == 3) {
                                       self.number = 0;
                                       MovePerson(self, Quarters);
                               }
                       S_AFTER_FILMING:
                               if(self.number++ == 3) {
                                       self.number = 0;
                                       MovePerson(self, PropRoom);
                               }
                       }
               ],
               number -1,
               talk_array linda_talk_array,
       has animate female proper transparent;

AdjObject -> -> LindaClothes "Linda's clothes"
       with
               short_name [;
                       if(FlagIsSet(F_LINDA_IS_FREE))
                               rfalse;
                       print "Nadia's clothes"; ! Character name
                       rtrue;
               ],
               adj_name 'lindas' 'linda^s' 'nadias' 'nadia^s',
               noun_name 'clothes' 'silver' 'silvery' 'space' 'wear' 'space-wear' 'spacewear',
               description [;
                       print_ret (The) self, " have a shiny, metal-like appearance. On her, still
                               look comfortable.";
               ],
               before [;
                       Search, Take, Pull, Turn, Push, Attack, Touch, Kiss:
                               "That'd be a serious invasion of her personal space.";
               ],
       has scenery proper pluralname;

! ------------------------------------------------------------------------------
!       Keith
! ------------------------------------------------------------------------------

Constant ID_TALKED_TO_NADIA 300;
Constant ID_RUSSIANS 301;
Constant ID_NO_RUSSIANS 302;

[ SteveDelay; steve_delay = steve_delay + 10; ];
[ SteveDelayDown; if(steve_delay >= 10) steve_delay = steve_delay - 10;];
[ SteveInformed; score = score + 3; ];

Array keith_talk_free -->
       30 "Motivation"
               "What drives you as an actor, Keith?"
               "This is just a job to me, you know. Sure, I started out with a lot of
                       dreams and ambition, but the movie industry grinds you down. Now
                       I'm just trying to do a good job so I can get home to my girl,
                       take her out to eat, maybe go to a concert - hey, we're actually
                       gonna see Lynyrd Skynyrd in November - and just have a good
                       time really."
       TM_END;

Array keith_talk_scene_2 -->
       30 "The weather"
               TM_ADD_AFTER
               "You know Steve, the dust storms are really horrible. They get me down.
                       I can't help but wonder if people will ever want to live here."
               "Steve looks disappointed, but quickly regains his composure."
               "Yeah, the weather is challenging at times. But don't you think we have
                       more pressing topics to discuss?" SteveDelay
       30 ID_TALKED_TO_NADIA "I talked to Nadia"
               "I spent some time with Nadia."
               "Oh that's great, Billy! So, what are your thoughts?" TM_INACTIVATE (-1) SteveDelay 1
       0 "Nadia is great"
               "I really think Nadia is a great person. She's smart, she's interesting, and
                       she can contribute a lot to the mission."
               "I fully agree Billy. But can we get to the point - what did you find out from talking to her?"
                       1 SteveDelay
       0 "I don't like your tone"
               TM_ADD_BEFORE
               "You look Steve in the eyes."
               "Now I don't like your tone, Steve. We're having a conversation here, you can't
                       order me around."
               "Well Billy, technically I can. Don't forget who's in charge here."
                       SteveDelayDown
       30 ID_RUSSIANS "Nadia talked to the Russians"
               TM_ADD_AFTER
               "Nadia freely admitted to talking to the Russians, but with no ill intent."
               "Steve looks surprised."
               "Did she now? What else did she say?" SteveDelay TM_INACTIVATE ID_TALKED_TO_NADIA TM_INACTIVATE (-1)
       30 ID_RUSSIANS "Nadia worked with Sergey"
               "Nadia talked to Sergey, seeking cooperation really, and they ended up drilling
                       together, as both had planned on drilling in the same area. She didn't think
                       it would be a problem, but we talked about it, and she'll be sure to run
                       things by you from now on."
               "Well okay, sounds like she's got her act together. Good work Billy, and thanks for the update!"
                       F_STEVE_IS_INFORMED SteveInformed EndOfSceneTalk
       30 ID_NO_RUSSIANS "Maybe she talked to the Russians"
               TM_ADD_BEFORE_AND_AFTER
               "You look down, collecting your thoughts."
               "Er... I think Nadia may have talked to the Russians, but I can't say for sure."
               "Steve gives out a sigh."
               "Well, I figured out that much already. I was kinda hoping you'd be able to get
                       some information out of her. I understand now that I was expecting too much from you."
                       "Steve looks back down at his desk."
                       EndOfSceneTalk
       TM_END;

Array keith_talk_array -->
       TM_MAYBE_ADD_LIST F_KEITH_IS_FREE keith_talk_free
       TM_MAYBE_ADD_LIST F_SCENE_2 keith_talk_scene_2
       TM_END;


Object -> Keith "Keith"
       with
               name 'keith' 'steve',
               short_name [;
                       if(FlagIsSet(F_KEITH_IS_FREE))
                               rfalse;
                       print "Steve"; ! Character name
                       rtrue;
               ],
               description [;
                       if(FlagIsSet(F_KEITH_IS_FREE)) {
                               if(self has general)
                                       "Keith has blond hair and a thin mustache. He's wearing
                                               silvery pants, an orange shirt and orange sneakers.";
                               give self general;
                               "Keith is a handsome man in his mid thirties. His thick blond
                                       hair and elegant mustache both help in making him look like
                                       a leader, just like he should for the role he's playing on
                                       screen. His clothes for the day are the stylish but relaxed
                                       standard issue silvery pants and an orange shirt,
                                       paired with orange sneakers.";
                       }
                       "You stop for a moment, to have a good look at Steve. While you
                               may wish you were the leader of this expedition, deep down you
                               know Steve is the natural choice. He has the knowledge, the
                               confidence, and the raw masculinity to lead the group, no
                               matter what comes your way. His blond hair sways a little
                               as he looks around, and the thin mustache just seals the
                               deal.";
               ],
               before_onscreen [;
               ],
               life_onscreen [;
                       Kiss:
                               SteveDelayDown();
                               "Steve stops you and gives you an angry look: ~Keep your distance, Billy!~";
                       Attack:
                               SteveDelayDown();
                               scene_over = true;
                               "Steve avoids your attack, gives you a hard punch to the gut
                                       and shouts ~You've got a problem, Billy?~";
               ],
               orders_onscreen [;
                       default:
                               "~I'm the commander of this station, Billy. You don't get to give me orders.~";
               ],
               before [;
                       if(FlagIsClear(F_KEITH_IS_FREE))
                               return self.before_onscreen();
                       Talk:
                               if(game_scene == S_INTRO)
                                       "~Yeah, let's talk Mike, but not right now. Mr Martin is preparing to tell us about the day.~";
               ],
               life [;
                       if(FlagIsClear(F_KEITH_IS_FREE))
                               return self.life_onscreen();
                       Kiss:
                               "Keith deflects your move and gives you a hard push: ~Are you on drugs, Mike?
                                       I'm not into that, and you know it!~";
                       Attack:
                               "Keith blocks your attack and pushes you away: ~Get out of my face, Mike!~";
               ],
               orders [;
                       if(FlagIsClear(F_KEITH_IS_FREE))
                               return self.orders_onscreen();
                       default:
                               "~Why don't you do it yourself, Mike?~";
               ],
               daemon [;
                       switch(game_scene) {
                       S_INTRO:
                               if(bell_rung == turns - 4 && self notin PropRoom) {
                                       MovePerson(self, PropRoom);
                                       StopDaemon(self);
                               }
                       S_INTERLUDE_1:
                               self.number++;
                               if(self.number == 5)
                                       MovePerson(self, Office);
                       S_INTERLUDE_2:
                               if(self in Office && random(3) == 1) {
                                       MovePerson(self, PropRoom);
                                       StopDaemon(self);
                               }
                       }
               ],
               number 0,
               talk_array keith_talk_array,
       has animate proper transparent;

AdjObject -> -> KeithClothes "Keith's clothes"
       with
               short_name [;
                       if(FlagIsSet(F_KEITH_IS_FREE))
                               rfalse;
                       print "Steve's clothes"; ! Character name
                       rtrue;
               ],
               adj_name 'keiths' 'keith^s' 'steves' 'steve^s',
               noun_name 'stylish' 'but' 'relaxed' 'clothes' 'standard' 'issue' 'standard-issue' 'standardissue'
                       'silvery' 'pants' 'orange' 'shirt' 'sneakers',
               description [;
                       print_ret (The) self, " look great on him, but so would almost any clothes.";
               ],
               before [;
                       Search, Take, Pull, Turn, Push, Attack, Touch, Kiss:
                               "That wouldn't end well for you.";
               ],
       has scenery proper pluralname;


AdjObject -> -> KeithHair "Keith's hair"
       with
               adj_name 'keith^s' 'keiths' 'thick' 'blonde' 'blond',
               noun_name 'hair',
               short_name [;
                       if(FlagIsSet(F_KEITH_IS_FREE))
                               rfalse;
                       print "Steve's hair"; ! In-character name
                       rtrue;
               ],
               description [;
                       if(FlagIsSet(F_KEITH_IS_FREE))
                               "Keith's hair is a thing of beauty. You'd love to put your hands in that mane and
                                       ruffle it up good, but that will forever remain a fantasy.";
                       "Steve has so much authority, and you know his perfect hair is an integral
                               part of that authority. It's powerful.";
               ],
               before [;
                       Search:
                               "You find it very attractive.";
                       Take, Pull, Turn, Push, Attack, Touch, Kiss:
                               "You know his hair is off-limits.";
               ],
       has proper static;

AdjObject -> -> KeithMustache "Keith's mustache"
       with
               adj_name 'keith^s' 'keiths' 'thin' 'elegant',
               noun_name 'mustache' 'moustache' 'mustasche' 'moustasche',
               short_name [;
                       if(FlagIsSet(F_KEITH_IS_FREE))
                               rfalse;
                       print "Steve's mustache"; ! In-character name
                       rtrue;
               ],
               description [;
                       if(FlagIsSet(F_KEITH_IS_FREE))
                               "Keith's mustache is thin, but oh so powerful.";
                       "Steve wears that mustache like a true leader.";
               ],
               before [;
                       Search:
                               "You find it very attractive.";
                       Take, Pull, Turn, Push, Attack, Touch, Kiss:
                               "You know his mustache is off-limits.";
               ],
       has proper static;

AdjObject KeithPen "cheap plastic pen" Keith
       with
               article [;
                       if(FlagIsSet(F_KEITH_IS_FREE))
                               print "a";
                       else
                               print "an";
               ],
               short_name [;
                       if(FlagIsSet(F_KEITH_IS_FREE))
                               rfalse;
                       print "advanced space pen"; ! In-character name
                       rtrue;
               ],
               adj_name 'cheap' 'silvery' 'advanced' 'space',
               noun_name 'plastic' 'pen',
               description [;
                       if(FlagIsSet(F_KEITH_IS_FREE))
                               "It's a cheap pen, made from silvery plastic. You've seen them sell for
                                       30 cents down at Kmart.";
                       "It's an advanced space pen. It always produces a perfect result, even in zero-gravity.";
               ];

! ------------------------------------------------------------------------------
!       Ivan
! ------------------------------------------------------------------------------

Constant ID_IVAN_ADMIT 300;
Constant ID_IVAN_NO_ADMIT 301;
Constant ID_IVAN_ADMIT_2 303;
Constant ID_IVAN_NO_ADMIT_2 304;

[ SergeyAttitudeUp; sergey_attitude = sergey_attitude + 10; if(sergey_attitude > 100) sergey_attitude = 100; ];
[ SergeyAttitudeDown; sergey_attitude = sergey_attitude - 10; if(sergey_attitude < 0) sergey_attitude = 0; ];
[ SergeyOnInvestigate;
       if(FlagIsSet(F_NADIA_ADMITTED_CONTACT))
               ActivateTopic(Ivan, ID_IVAN_ADMIT_2);
       else
               ActivateTopic(Ivan, ID_IVAN_NO_ADMIT_2);
];
[ SergeyOffInvestigate; InactivateTopic(Ivan, ID_IVAN_ADMIT_2); InactivateTopic(Ivan, ID_IVAN_NO_ADMIT_2); ];
[ SergeyAdmit; score = score + 6; ];


[SergeyInquiryReply;
       if(sergey_attitude > 60) {
               SergeyAttitudeUp();
               print "Ah yes, I'm sorry, we did meet, and I for one didn't think about clearing
                       it with my commander first. I'll make sure to follow protocol in the future.
                       Thanks for reminding me!";
               return;
       }
       SergeyAttitudeDown();
       print "Well yes, but is it such a big deal? Anyway, okay, I'll check in with my commander
               next time.";
];

Array ivan_talk_free -->
       30 "Acting background"
               "I think I've seen you in a movie, but I can't remember which one."
               "I doubt it. I've mostly been in plays, mostly Off-Off-Broadway.
                       I've been an extra in a few television series though. I was a
                       janitor in episode 3 of the first season of Kojak - One for
                       the Morgue. Maybe you saw that."
               "Ivan looks a little proud."
       TM_END;



Array ivan_talk_scene_3 -->
       30 ID_IVAN_NO_ADMIT "Accuse"
               TM_ADD_AFTER
               "Hey Sergey, I'm pretty sure you've been talking to Nadia, and neither
                       of you bothered clearing it with your station commanders.
                       That's just wrong, and you know it. You have to follow protocol, or
                       there will be consequences!"
               "Sergey raises his eyebrows, then he looks hurt."
               "I have no idea what you're talking about. I welcome you
                       as a guest, and you start accusing me? Get out of my face!"
                       SergeyAttitudeDown SergeyAttitudeDown TM_INACTIVATE 2 EndOfSceneTalk
       30 ID_IVAN_ADMIT "Accuse"
               TM_ADD_AFTER
               "Hey Sergey, I've talked to Nadia. She admitted to
                       meeting up with you, and neither of you bothered clearing it
                       with your station commanders. That's just wrong, and you know it.
                       You have to follow protocol, or
                       there will be consequences!"
               "Sergey looks a little shocked."
               "Yes, about that... I wasn't thinking. I'll be sure to follow protocol
                       next time."
                       F_SERGEY_ADMITTED_CONTACT SergeyAdmit SergeyAttitudeDown TM_INACTIVATE 1 EndOfSceneTalk
       30 "Greetings"
               "It's good to see you, Sergey. I want to thank you and your station commander
                       for letting me visit your station on short notice."
               "Welcome, my friend. We are glad to have you. Now what can I do for you?"
                       4 SergeyOnInvestigate SergeyAttitudeUp TM_INACTIVATE ID_IVAN_NO_ADMIT TM_INACTIVATE ID_IVAN_ADMIT
       0 ID_IVAN_ADMIT_2 "Accuse"
               "We know you met Nadia, without following protocol and clearing it with
                       your station commanders. Going forward, we can't have any more of that."
               "Yes, okay, I'll make sure to follow protocol next time."
               F_SERGEY_ADMITTED_CONTACT SergeyAdmit SergeyOffInvestigate SergeyAttitudeDown SceneCanBeOver
       0 ID_IVAN_NO_ADMIT_2 "Accuse"
               "You met Nadia, didn't you, without getting clearance from either station commander?
                       That's not acceptable you know."
               "I don't know what you're talking about."
               SergeyOffInvestigate SergeyAttitudeDown SergeyAttitudeDown SceneCanBeOver
       0 ID_IVAN_ADMIT_2 ID_IVAN_NO_ADMIT_2 "Did you meet Nadia?"
               "Hey Sergey, I was just wondering... Did you meet up with Nadia recently? You know
                       we need to check in with our station commanders before any meetings, right?"
               SergeyInquiryReply
               F_SERGEY_ADMITTED_CONTACT SergeyAdmit SergeyOffInvestigate SceneCanBeOver
       0 "Amazing space station"
               "I haven't actually been inside your station before, and I must say
                       I was curious. It looks like an amazing research facility!"
               "Well thank you! Yes, it's working as designed, and we're generally quite
                       happy with it." SergeyAttitudeUp SceneCanBeOver
       TM_END;

Array ivan_talk_array -->
       TM_MAYBE_ADD_LIST F_IVAN_IS_FREE ivan_talk_free
       TM_MAYBE_ADD_LIST F_SCENE_3 ivan_talk_scene_3
       TM_END;

Object -> Ivan "Ivan"
       with
               name 'ivan' 'sergey',
               short_name [;
                       if(FlagIsSet(F_IVAN_IS_FREE))
                               rfalse;
                       print "Sergey"; ! Character name
                       rtrue;
               ],
               description [;
                       if(FlagIsSet(F_IVAN_IS_FREE)) {
                               if(self has general)
                                       "Ivan is quite muscular, with brown hair and green eyes. He's wearing
                                               golden pants, a green T-shirt and black boots.";
                               give self general;
                               "Ivan is built like a tank - he looks both strong and sturdy.
                                       He is about your age, 22-23. There's something about his
                                       brown hair that makes it look artificial, but you can't put
                                       your finger on it. His dark green T-shirt match the golden pants,
                                       and the black boots complete the look. He speaks with a New
                                       York accent, if you had to guess you'd say he's from Queens.";
                       }
                       if(self has moved)
                               "Sergey looks and sounds Russian, with his golden pants, green T-shirt
                                       and black boots.";
                       give self moved;
                       "You find yourself staring at Sergey, just a little longer than what's
                               socially acceptable. His muscular build fascinates you, and his
                               brown hair just emphasizes his raw energy. His English is good,
                               and you have no problem understanding him despite his rather
                               heavy Russian accent. He wears golden pants, a green T-shirt
                               and black boots.";
               ],
               before_onscreen [;
               ],
               life_onscreen [;
                       Kiss:
                               if(sergey_attitude >= 50)
                                       "Sergey gives you a polite kiss on the cheek.";
                       Attack:
                               SergeyAttitudeDown();
                               scene_over = true;
                               "Sergey blocks your attack, then throws a lightning-fast punch to your gut,
                                       that has you gasping for air as you bend over in pain. Sergey smiles:
                                               ~So, you want to fight, American?~";
               ],
               orders_onscreen [;
                       default:
                               "Sergey laughs: ~That's not how it works here, American. You can't give me orders. But let's talk, shall we?~";
               ],
               before [;
                       if(FlagIsClear(F_IVAN_IS_FREE))
                               return self.before_onscreen();
                       Talk:
                               if(game_scene == S_INTRO)
                                       "~Yeah, we should definitely talk, but later. Mr Martin is about to talk.~";
               ],
               life [;
                       if(FlagIsClear(F_IVAN_IS_FREE))
                               return self.life_onscreen();
                       Kiss, Attack:
                               "Ivan reacts immediately, giving you a hard slap before you've even touched him.
                                       ~Enough of that, Mike!~";
               ],
               orders [;
                       if(FlagIsClear(F_IVAN_IS_FREE))
                               return self.orders_onscreen();
                       default:
                               "~That's not gonna happen, Mike.~";
               ],
               daemon [;
                       switch(game_scene) {
                       S_INTRO:
                               if(bell_rung == turns - 2 && self notin PropRoom) {
                                       MovePerson(self, PropRoom);
                                       StopDaemon(self);
                               }
                       S_INTERLUDE_2:
                               self.number++;
                               if(self.number == 5)
                                       MovePerson(self, Office);
                               if(self.number == 6) {
                                       MovePerson(self, RussianStation);
                                       if(FlagIsSet(F_NADIA_ADMITTED_CONTACT))
                                               InactivateTopic(self, ID_IVAN_NO_ADMIT);
                                       else
                                               InactivateTopic(self, ID_IVAN_ADMIT);
                               }
                       S_AFTER_FILMING:
                               if(random(2) == 1) {
                                       switch(parent(self)) {
                                       RussianStation:
                                               MovePerson(self, Office);
                                               self.number = 0;
                                       Office:
                                               MovePerson(self, PropRoom);
                                       }
                               }
                       }
               ],
               number 0,
               talk_array ivan_talk_array,
       has animate proper transparent;

AdjObject -> -> IvanClothes "Ivan's clothes"
       with
               short_name [;
                       if(FlagIsSet(F_IVAN_IS_FREE))
                               rfalse;
                       print "Sergey's clothes"; ! Character name
                       rtrue;
               ],
               adj_name 'ivans' 'ivan^s' 'sergeys' 'sergey^s',
               noun_name 'golden' 'pants' 'green' 'tshirt' 't-shirt' 'clothes' 'black' 'boots',
               description [;
                       print_ret (The) self, " exhibit the same powerful energy that he does.";
               ],
               before [;
                       Search, Take, Pull, Turn, Push, Attack, Touch, Kiss:
                               "You're pretty sure he wouldn't appreciate that.";
               ],
       has scenery proper pluralname;


! ------------------------------------------------------------------------------
!       Player parts etc
! ------------------------------------------------------------------------------


AdjObject DigitalWatch "digital watch" selfobj
       with
               adj_name 'digital',
               noun_name 'watch',
               show_mode 0,
               show_time [ p_intro _hour _minute _time;
                       if(p_intro)
                               print "The watch shows: ";
                       if(self.show_mode)
                               "WED 28 SEP 1977";
                       _time = the_time + 1; if(_time > 1439) _time = 0;
                       _hour = _time / 60;
                       _minute = _time % 60;
                       if(_hour < 10) print "0";
                       print _hour, ":";
                       if(_minute < 10) print "0";
                       print _minute,"^";
               ],
               description [;
                       if(self has general) {
                               print "It has a button on the right-hand side. ";
                               self.show_time(true);
                               rtrue;
                       }
                       give self general;
                       print "It's a neat watch, and wearing a digital watch really feels like wearing the future.
                               On the right-hand side is a single button.^^";
                       self.show_time(true);
               ],
               daemon [;
                       the_time++;
                       if(the_time < 1440) rtrue;
                       deadflag = GS_DEATHMESSAGE;
                       "^Mr Martin comes up to you: ~What's going on, Mike? It's midnight, and
                               we're still not done here. Let's call it a day.~";
               ],
       has worn transparent;

Object WatchButton "watch button" DigitalWatch
       with
               parse_name [_word _count _def _suffix;
                       _word = NextWord();
                       while(_word == 'digital' or 'watch') {
                               _count++;
                               _word = NextWord();
                       }
                       if(_word == 'button') {
                               _count++;
                               _def = 1;
                               _word = NextWord();
                       }
                       if(_word == 'on' or 'of' or 'for') {
                               _suffix = 1;
                               _word = NextWord();
                               if(_word == 'the') {
                                       _suffix++;
                                       _word = NextWord();
                               }
                               if(_word == 'digital') {
                                       _suffix++;
                                       _word = NextWord();
                               }
                               if(_word == 'watch') {
                                       _suffix++;
                                       _count = _count + _suffix;
                               }
                       }
                       if(_def)
                               return _count;
               ],
               before [;
                       Push:
                               DigitalWatch.show_mode = 1 - DigitalWatch.show_mode;
                               print "A quiet beep is heard. The display changes to: ";
                               DigitalWatch.show_time();
                               rtrue;
               ],
       has static;


Object PlayerParts "(plyprts)";

AdjObject -> Eyes "eyes"
       with
               article "your",
               adj_name 'my',
               noun_name 'eye' 'eyes',
               description "Not that you can see them, but you know they are blue.",
               before [;
                       Open:
                               "Your eyes are already open.";
                       Close:
                               "You aren't sleepy.";
                       Take, Remove, Transfer:
                               "That's absurd!";
               ],
       has scenery pluralname;

AdjObject -> Jeans "jeans"
       with
               article "a pair of",
               adj_name 'my' 'tight' 'blue' 'pair' 'of',
               noun_name 'jeans',
               description "They're a good looking pair of jeans. Blue and tight, just as you like them.
                       It was your idea that Billy would wear them, and it was surprisingly
                       easy to convince Mr Martin that they'd be right for the series.",
               before [;
                       Open, Close, Take, Remove, Drop, Wear, Disrobe:
                               "You don't have time to play with your clothes, and this is definitely not the
                                       right time to change them.";
               ],
       has scenery pluralname;

AdjObject -> Shirt "shirt"
       with
               adj_name 'my' 'stylish' 'yellow' 'nylon',
               noun_name 'shirt',
               description "It's a nice shirt, in a thin yellow fabric.
                       You'd be happy to wear it outside the studio as well.",
               before [;
                       return Jeans.before();
               ],
       has scenery;


[ PlayerDescription;
       if(game_scene == S_SCENE_1 or S_SCENE_2 or S_SCENE_3)
               "Billy is dressed for a day on base. Tight blue jeans and a comfortable
                       yet stylish yellow nylon shirt.";
       "You look like you feel, basically. Not great. You're wearing tight blue jeans and a yellow nylon shirt.";
];

[ PlayerAddToScope;
       ScopeWithin(PlayerParts);
];

[ PlayerParseName _count;
       while(NextWord() == 'me' or 'myself' or 'self' or 'mike' or 'billy' or 'michael'  or  'william') _count++;
       return _count;
];

[Initialise;
       location = YourBed;
       player.description = PlayerDescription;
       player.add_to_scope = PlayerAddToScope;
       player.parse_name = PlayerParseName;
       SetTime(9*60, 1);
       StartDaemon(DigitalWatch);
       SetScene(S_INTRO);

       print "^^";
       QuoteBox(quote_start);
       print "^^
       In May 2044, the Soviet Union established Krasnyy Zamok, the very first base on Mars.
       Three years later, after all sorts of technical difficulties, USA established The
       Freedom Base. And here you are, a farm boy from Idaho, an essential part of the crew.
       Or at least, that's the story.^";
];