1 !% $MAX_STATIC_DATA=150000
4 !============================================================================
6 ! This program was written by Toby Ord (half sick of shadows) and has been
7 ! released into the public domain, so you are legally free to be distribute
8 ! and modify it as you see fit. So long as you do so in good faith and with good
9 ! taste (or sufficient taste) then you have my blessing.
11 ! Oh, and apologies for the messy code! It was my first program in Inform.
13 Constant Story "All Things Devours";
16 "^Written for IFComp 2004 by half sick of shadows.^
17 This is the post-competition release.^
18 It is in the public domain and may thus be freely copied or modified.^
19 First-time players should type 'about'.^";
22 Release 3; ! post-competition release, (plus 1 bugfix)
25 Replace DrawStatusLine;
29 !============================================================================
30 ! Constants and Globals
33 Constant DEATH_MENTION_UNDO;
35 ! EARLIEST_TIME is a time before which no action can happen
36 ! (can't time travel to before this time)
37 ! start_time is when the player arrives.
38 ! From ten seconds earlier,
39 ! the player is outside (and can interfere with escape attempts at this time)
40 ! <<< thus the EARLIEST_TIME must be at least ten seconds before start_time >>>
41 ! FINAL_TIME is when the security team arrive and any attempt to stay beyond this
42 ! will get you caught.
44 ! the time units are 5 second blocks
46 Global my_time; ! used instead of the_time to allow sub-minute turns
48 ! the timeline has the player in a non-specified 'limbo' from EARLIEST_TIME to
50 Constant EARLIEST_TIME = ((4 * 60) + 13) * 12 + 11;
51 Constant FINAL_TIME = ((4 * 60) + 23) * 12 + 0;
53 Global start_time = ((4 * 60) + 17) * 12 + 0;
54 Global early_guard_time = EARLIEST_TIME; ! but this changes in the challenge mode
56 Constant CHALLENGE_EARLY_GUARD_TIME = ((4 * 60) + 15) * 12 + 11;
59 ! the times of the two military experiments, if allowed to happen
61 Constant EXPERIMENT1_TIME = (( 9 * 60) + 27) * 12 + 3;
62 Constant EXPERIMENT2_TIME = ((11 * 60) + 33) * 12 + 9;
64 Constant GAME_LENGTH = FINAL_TIME - EARLIEST_TIME;
66 Constant LATER_ = -1; ! A constant to represent a later time
68 Constant DEFAULT_SIREN_TIMEOUT = 16; ! the time before the guard arrives
69 Constant CHALLENGE_SIREN_TIMEOUT = 11; ! 1:20 vs. 0:55
71 Constant TIME_BEFORE_DRAGGED_OFF = 4; ! the time between arrest and removal
73 Constant MAX_TIME_TRAVELS = 2;
75 ! ***************** Important ********************
76 ! This MUST be set to be equal to 2 to the power of MAX_TIME_TRAVELS
78 Constant MAX_ITEM_COPIES = 4;
80 ! Constants for death states
82 Constant ACCELERATED_ = 4; ! brought about the premature destruction of Boston
83 Constant USELESS_ = 5; ! achieved nothing of consequence
84 Constant DELAYED_ = 6; ! delayed the destruction by blowing up prototype
85 Constant SAVED_DEAD_ = 7; ! saved the city but died
86 Constant SAVED_CAUGHT_ = 8; ! saved the city but caught
87 Constant SAVED_FREE_ = 9; ! saved the city and free
88 Constant SAVED_FREE_CHALLENGE_ = 10; ! saved the city and free and completed the challenge
89 ! Constants for object states
92 Constant UNKNOWN_ = -1;
97 ! Potentially dangerous actions:
101 !Constant OPEN_ = 2; Not needed since defined above
102 Constant UNLOCK_ = 3;
103 Constant X_CCTV_ = 4;
104 Constant X_UPSTAIRS_CORRIDOR_ = 5;
105 Constant X_UPSTAIRS_LANDING_ = 6;
106 Constant X_GROUND_CORRIDOR_ = 7;
107 Constant X_FOYER_ = 8;
108 Constant X_BASEMENT_CORRIDOR_ = 9;
109 Constant X_BASEMENT_LANDING_ = 10;
110 Constant X_BALCONY_ = 11;
111 Constant TAKE_FLASHLIGHT_ = 12;
112 Constant BLOW_BASEMENT_LIGHT_ = 13;
113 Constant SING_ = 14; ! these are not dangerous in the same way
114 Constant SHOUT_ = 15; ! but need to be caught and replayed
116 Global time_travelled;
117 Global last_travel_time;
124 Global d_killed_by_bomb;
125 Global d_injured_by_bomb;
126 Global d_fs_hears_bomb;
127 Global d_fs_killed_by_bomb;
128 Global d_destroyed_notes;
129 Global d_destroyed_prototype;
131 !! The moveable items (which can be taken back in time):
133 Array bomb --> MAX_ITEM_COPIES;
134 Array id_card --> MAX_ITEM_COPIES;
135 Array equipment_key --> MAX_ITEM_COPIES;
136 Array deutsch_key --> MAX_ITEM_COPIES;
137 Array flashlight --> MAX_ITEM_COPIES;
138 Array battery --> MAX_ITEM_COPIES;
139 Array cable --> MAX_ITEM_COPIES;
140 Array crowbar --> MAX_ITEM_COPIES;
141 Array notes --> MAX_ITEM_COPIES;
143 Array former_self --> MAX_TIME_TRAVELS;
146 !! The locations of various things at various times
147 !! These contain an immense amount of info:
148 !! Location of each copy of that item at each time for each run through
149 !! Amongst other things, this allows one to recreate the world at a given time
151 Array player_loc --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1);
153 Array bomb_loc --> (GAME_LENGTH + 1) *
154 (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1);
155 Array id_card_loc --> (GAME_LENGTH + 1) *
156 (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1);
157 Array equipment_key_loc --> (GAME_LENGTH + 1) *
158 (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1);
159 Array deutsch_key_loc --> (GAME_LENGTH + 1) *
160 (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1);
161 Array flashlight_loc --> (GAME_LENGTH + 1) *
162 (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1);
163 Array battery_loc --> (GAME_LENGTH + 1) *
164 (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1);
165 Array cable_loc --> (GAME_LENGTH + 1) *
166 (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1);
167 Array crowbar_loc --> (GAME_LENGTH + 1) *
168 (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1);
169 Array notes_loc --> (GAME_LENGTH + 1) *
170 (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1);
172 !! The states of various things at various times
174 Global prototype_fixed_time = UNKNOWN_;
175 Global siren_start_time = UNKNOWN_;
177 Array flashlight_state --> (GAME_LENGTH + 1) *
178 (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1);
179 Array bomb_setting --> (GAME_LENGTH + 1) *
180 (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1);
182 !! activity_target is used to distinguish which door was (dangerously) locked/unlocked/opened
184 Array dangerous_activity --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1);
185 Array activity_target --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1);
187 Array siren_state --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1);
188 Array panel_setting --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1);
189 Array ground_equipment_light --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1);
190 Array basement_equipment_light --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1);
192 Array main_doors_state --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1);
193 Array basement_door_state --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1);
194 Array ground_door_state --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1);
195 Array upstairs_door_state --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1);
196 Array balcony_door_state --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1);
197 Array conference_window_state --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1);
198 Array deutsch_door_state --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1);
199 Array basement_equipment_door_state --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1);
200 Array ground_equipment_door_state --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1);
202 Array main_doors_smashed --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1);
203 Array basement_door_smashed --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1);
204 Array ground_door_smashed --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1);
205 Array upstairs_door_smashed --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1);
206 Array balcony_door_smashed --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1);
209 Global poem_interleaving = false;
210 Global initialising = true;
211 Global first_turn = true;
212 Global challenge = false;
213 Global siren_timeout = DEFAULT_SIREN_TIMEOUT;
214 Global instant_action_this_turn = false;
215 Global warned_of_jump = false;
216 Global id_card_used = false;
217 Global have_looked_at_bench = false;
218 Global prototype_seen = false;
220 !============================================================================
226 Object LibraryMessages
229 if (real_location == balcony) {
233 "You jump on the spot, fruitlessly.";
235 if ((siren_start_time ~= UNKNOWN_) && (siren_start_time < my_time))
237 else if (Get2D(dangerous_activity, time_travelled-1, my_time-EARLIEST_TIME) == SHOUT_)
239 else if (Get2D(dangerous_activity, time_travelled-1, my_time-EARLIEST_TIME) == SING_)
242 "You can hear nothing but a soft electric hum.";
244 "You have no source of flame.";
246 "You sing out a few clear notes.";
249 "It is not clear what you are trying to refer to with 'all'.";
255 !============================================================================
264 initialising = false;
267 instant_action_this_turn = true;
270 for (t=0 : t<time_travelled : t++) {
271 if ((former_self-->t notin limbo) &&
272 ((siren_start_time == UNKNOWN_) || (siren_start_time > my_time))) {
274 print "You sing out a few clear notes.^";
278 print (Nearby) 0, "your former self hears the muffled sounds of your
279 singing.^^Something of an anticlimactic way to kill
280 so many millions of people...^";
281 print "^Time unravels...^";
286 Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,SING_);
291 if (instant_action_this_turn) {
292 instant_action_this_turn = false;
295 MoveFloatingObjects();
297 if (time_travelled > 0) {
298 for(i=0 : i < Exp(2,time_travelled-1) : i++) {
299 MoveObject(bomb, bomb_loc, i);
300 MoveObject(id_card, id_card_loc, i);
301 MoveObject(equipment_key, equipment_key_loc, i);
302 MoveObject(deutsch_key, deutsch_key_loc, i);
303 MoveObject(flashlight, flashlight_loc, i);
304 MoveObject(battery, battery_loc, i);
305 MoveObject(cable, cable_loc, i);
306 MoveObject(crowbar, crowbar_loc, i);
307 MoveObject(notes, notes_loc, i);
310 if (my_time == prototype_fixed_time)
311 prototype.fixed = true;
314 MaybeSetFlashlights();
315 MaybeSetPanel(panel_setting);
316 MaybeSetBasementLight(basement_equipment_light);
317 MaybeSetGroundLight(ground_equipment_light);
318 MaybeSetAutomaticDoor(main_doors, main_doors_state);
319 MaybeSetAutomaticDoor(basement_door, basement_door_state);
320 MaybeSetAutomaticDoor(ground_door, ground_door_state);
321 MaybeSetAutomaticDoor(upstairs_door, upstairs_door_state);
323 MaybeBreakDoor(main_doors, main_doors_smashed);
324 MaybeBreakDoor(basement_door, basement_door_smashed);
325 MaybeBreakDoor(ground_door, ground_door_smashed);
326 MaybeBreakDoor(upstairs_door, upstairs_door_smashed);
327 MaybeBreakDoor(balcony_door, balcony_door_smashed);
332 !-- from here down paradox may occur and we need to be able to stop if one occurs if (~~d_paradox)...
334 for(t=0 : t < time_travelled : t++)
337 MaybeSetManualDoor(balcony_door, balcony_door_state);
338 MaybeSetManualDoor(conference_window, conference_window_state);
339 MaybeSetManualDoor(deutsch_door, deutsch_door_state);
340 MaybeSetManualDoor(basement_equipment_door, basement_equipment_door_state);
341 MaybeSetManualDoor(ground_equipment_door, ground_equipment_door_state);
345 MaybeCloseAutomaticDoor(main_doors);
346 MaybeCloseAutomaticDoor(basement_door);
347 MaybeCloseAutomaticDoor(ground_door);
348 MaybeCloseAutomaticDoor(upstairs_door);
352 ObserveFlashlights();
355 ObserveBasementLight(basement_equipment_light);
356 ObserveGroundLight(ground_equipment_light);
357 ObserveAutomaticDoor(main_doors, main_doors_state);
358 ObserveAutomaticDoor(basement_door, basement_door_state);
359 ObserveAutomaticDoor(ground_door, ground_door_state);
360 ObserveAutomaticDoor(upstairs_door, upstairs_door_state);
361 ObserveManualDoor(balcony_door, balcony_door_state);
362 ObserveManualDoor(conference_window, conference_window_state);
363 ObserveManualDoor(deutsch_door, deutsch_door_state);
364 ObserveManualDoor(basement_equipment_door, basement_equipment_door_state);
365 ObserveManualDoor(ground_equipment_door, ground_equipment_door_state);
367 ObserveBrokenDoor(main_doors, main_doors_smashed);
368 ObserveBrokenDoor(basement_door, basement_door_smashed);
369 ObserveBrokenDoor(ground_door, ground_door_smashed);
370 ObserveBrokenDoor(upstairs_door, upstairs_door_smashed);
371 ObserveBrokenDoor(balcony_door, balcony_door_smashed);
373 CheckPassiveParadox();
374 CheckActiveParadox();
377 if (siren_start_time ~= UNKNOWN_) {
378 if (my_time - siren_start_time == 1)
379 print "^A piercing siren rings out.^";
380 if (my_time - siren_start_time > 1) {
381 if (my_time - siren_start_time <= siren_timeout)
382 print "^The siren wails.^";
387 if ((my_time > FINAL_TIME) && (~~Stopped()))
391 if (main_doors.just_closed) main_doors.closing_message();
392 if (basement_door.just_closed) basement_door.closing_message();
393 if (ground_door.just_closed) ground_door.closing_message();
394 if (upstairs_door.just_closed) upstairs_door.closing_message();
404 Examine: return false;
405 Listen: return false;
407 print_ret "You cannot do that from here.";
409 has scenery concealed static;
413 Examine: return false;
415 print_ret "You cannot do that to all of ", (the) self, " at once.";
417 has scenery concealed static;
421 Examine: return false;
423 print_ret "You don't need to worry about ", (the) self, ".";
425 has scenery concealed static;
430 Take,Pull,Push,PushDir:
431 print_ret (The) self, " is too heavy for that.";
433 has static supporter;
438 Take,Pull,Push,PushDir:
439 print_ret (The) self, " is locked in place.";
442 "Like most automatic doors, this one closes of its own accord.";
444 if (AmHolding(crowbar)) {
445 print "You swing the crowbar firmly into the door. It shudders,
446 a star of cracks reaching out from the point of impact,
447 but the glass stays in place.^";
453 "You don't have anything heavy enough to smash the door with.";
459 to_close_at UNKNOWN_,
461 if (self hasnt open) {
462 give self open ~locked;
463 if (self in LocationOf(player))
464 print "The door slides open with a soft rattle.^";
466 self.to_close_at = t;
469 give self ~open locked;
470 self.to_close_at = UNKNOWN_;
471 self.just_closed = true;
474 if ((~~Stopped()) && (self in LocationOf(player)))
475 "The automatic door softly slides closed.";
477 has static door openable locked;
480 with name 'door' 'to' 'the',
483 print_ret (The) self, " is locked in place.";
485 if (AmHolding(crowbar)) {
486 print "You swing the crowbar firmly into the door,
487 but it barely leaves a mark.^";
491 "You don't have anything heavy enough to break the door with.";
494 Go: if (noun.door_dir() == self.door_dir())
495 return self.open_by_myself();
496 if (noun.door_dir() == out_to) !! XX hack, going 'out' always uses door in this game
497 return self.open_by_myself();
499 if (noun == self) return self.open_by_myself();
504 print "(first opening ", (the) self, ")^";
513 if (Stopped()) return true;
516 has static door openable lockable;
523 print "On the other side of the door, your former self hears you turn the
525 print "^Time unravels...^";
533 print "On the other side, your former self sees the door open in front
535 print "^Time unravels...^";
543 print "On the other side, your former self sees the door close in front
545 print "^Time unravels...^";
549 [OpenManualDoor door ks;
550 if (door has locked) {
551 if (door.with_key_type == nothing
552 || ~~AmHolding(door.with_key_type))
553 "Try as you might, none of your keys will unlock the door.";
554 print "(first unlocking ", (the) door, ")^";
557 <Unlock door (GetHeld(door.with_key_type))>;
563 if (Stopped()) return true;
566 Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,OPEN_);
567 Put2D(activity_target,time_travelled,my_time-EARLIEST_TIME,door);
571 [UnlockManualDoor door key;
572 Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,UNLOCK_);
573 Put2D(activity_target,time_travelled,my_time-EARLIEST_TIME,door);
574 if (door has locked) {
575 if ( IsOfType(key,door.with_key_type) ) {
578 print (The) key, " turns smoothly in the lock.^";
582 "It does not fit in the lock.";
587 [LockManualDoor door key ks;
589 print "(first closing ", (the) door, ")^";
597 if (Stopped()) return true;
599 Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,LOCK_);
600 Put2D(activity_target,time_travelled,my_time-EARLIEST_TIME,door);
601 if (door hasnt locked) {
602 if ( IsOfType(key,door.with_key_type) ) {
605 print (The) key, " turns smoothly in the lock.^";
609 "It does not fit in the lock.";
616 with name 'door' 'to' 'the',
619 print_ret (The) self, " is locked in place.";
621 if (IsOfType(second,crowbar))
624 if (AmHolding(crowbar)) {
625 print "You swing the crowbar firmly into the door,
626 but it barely leaves a mark.^";
630 "You don't have anything heavy enough to break the door with.";
632 "The door is locked.";
636 with_key_type nothing,
637 has static door openable lockable locked;
640 !============================================================================
642 ! the moveable objects (defined as classes)
643 ! with trailing _ to avoid ambiguity with individual item names
646 Class Bomb_(MAX_ITEM_COPIES)
647 with short_name "timed explosive device",
648 plural "timed explosive devices",
650 print "A length of steel pipe filled with powder and fused with a digital timer.
651 Not your most elegant piece of work, but it will
652 hopefully do the job.^";
653 t = (self.time_value - my_time) * 5 + self.left_over_seconds;
654 if (self.time_value == NA_)
655 print "^You have not yet set the timer.^";
658 print "^On the timer's small LED screen, the number 0
659 blinks out at you.^";
661 print "^On the timer's small LED screen, the numbers ";
662 for (i = t+4 : (i>t) && (i>0) : i--)
668 print "... blink out at you insistently, illuminating
669 the room with faint blue-green flashes.^";
673 name 'time' 'timed' 'explosive' 'device' 'bomb' 'timebomb' 'C4'
674 'timer' 'digital' 'pipe'
675 'devices//p' 'bombs//p' 'timebombs//p' 'timers//p',
680 print "To set the explosive device,
681 you need to specify a number of seconds,
682 for example, with 'set timer to 30'.^";
685 if (self.time_value ~= NA_) {
686 print "(first resetting the timer)^";
687 self.time_value = NA_;
689 if (second > 0 && second <= 100) {
690 self.time_value = my_time + (second/5);
691 self.left_over_seconds = second%5;
692 print "Time until detonation: ", (self.time_value - my_time) * 5
693 + self.left_over_seconds;
695 if (parent(self) == player)
696 print "(you probably don't want to be carrying the device
697 when that occurs...)^";
700 print "Your timer only accepts between 1 and
705 if (self.time_value ~= NA_) {
706 self.time_value = NA_;
707 "You reset the timer.";
710 "The timer is not currently set.";
714 Class IDCard_(MAX_ITEM_COPIES)
715 with short_name "ID card",
717 description "Natalie Williams.^
719 Doctoral Student, MIT^
721 On the right is a familiar photo of you, back when you
723 A black magnetic stripe runs the width of the reverse.",
724 name 'id' 'card' 'cards',
726 if (second == id_slot){
727 if (second in foyer or upstairs_landing) {
728 "The slot emits a small beep and your card is rejected.";
730 if (second in basement_landing) {
731 if (~~id_card_used) {
732 print "You swipe your card through the slot, and hold your breath.^";
733 basement_door.open_self(my_time+1);
734 print "Perfect. Just as you'd hoped.
735 The bastards hadn't even thought to disable your card.^";
739 basement_door.open_self(my_time+1);
743 if (second == ground_door or upstairs_door
744 && player in foyer or upstairs_landing) {
745 "The slot emits a small beep and your card is rejected.";
747 if ((second == basement_door) && (player in basement_landing)) {
748 basement_door.open_self(my_time+1);
754 Class Crowbar_(MAX_ITEM_COPIES)
755 with short_name "crowbar",
757 name 'crow' 'bar' 'crowbar' 'black' 'crowbars//p' 'bars//p',
758 description "A curved black crowbar.",
761 Class Flashlight_(MAX_ITEM_COPIES)
762 with short_name "flashlight",
763 plural "flashlights",
764 name 'flashlight' 'torch' 'flashlights//p' 'torches//p'
765 'flash' 'metallic' 'blue' 'metallic-blue',
766 description "A small metallic-blue flashlight.",
771 "That's already on.";
772 if (BatteriesContained(self) == 2) {
774 if (real_location == basement_equipment ||
775 (real_location == ground_equipment && ground_equipment.lit == false)) {
777 instant_action_this_turn = false;
781 "A thin beam of icy light shines forth.";
783 if (BatteriesContained(self) == 1) {
784 "The switch clicks, but no light is forthcoming.
785 It looks as if you will need two batteries.";
787 if (BatteriesContained(self) == 0) {
788 "The switch clicks, but no light is forthcoming.
789 Not surprising considering flashlights usually need batteries.";
792 if (player in basement_equipment)
793 MoveMoveableChildren(basement_equipment,basement_equipment_gloom);
794 else if ((player in ground_equipment) && (ground_light_switch hasnt on))
795 MoveMoveableChildren(ground_equipment,ground_equipment_gloom);
797 if (~~IsOfType(noun,battery))
798 print_ret (The) noun, " won't fit in the flashlight.";
800 Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,TAKE_FLASHLIGHT_);
806 print "As you remove the battery, the light fails.^";
808 if (player in basement_equipment)
809 MoveMoveableChildren(basement_equipment,basement_equipment_gloom);
810 else if ((player in ground_equipment) && (ground_light_switch hasnt on))
811 MoveMoveableChildren(ground_equipment,ground_equipment_gloom);
815 has container open switchable;
817 Class Battery_(MAX_ITEM_COPIES)
818 with short_name "battery",
820 name 'battery' 'batteries//p' 'AA',
821 description "An AA sized battery.",
828 Class Cable_(MAX_ITEM_COPIES)
829 with short_name "length of ribbon cable",
830 plural "lengths of ribbon cable",
831 name 'cable' 'wire' 'cables//p' 'wires//p' 'ribbon' 'length' 'lengths//p' 'of',
832 description "A 10cm length of ribbon cable. It will do nicely.",
835 if (second == control_panel or prototype)
837 if (second == nothing)
838 if (real_location == deutsch_lab or prototype_interior)
841 "There is nothing here that you could attach the cable to.";
843 "You cannot attach the cable to that.";
847 Class Notes_(MAX_ITEM_COPIES)
848 with short_name "collection of notes",
849 plural "collections of notes",
850 name 'collection' 'notes' 'collections//p',
851 description "Your research notes. The hundred or so pages here comprise
852 everything you have written so far. It would not be easy for
853 someone else to turn the scribbles herein into another working
854 prototype, but it may just be possible.",
857 "You look determinedly at the thick bundle of papers, but there is no
858 way that you could eat more than a couple of pages. You had better think
859 of something a little more sensible.";
861 "There are about a hundred pages and there is no way that you could tear them
866 Class EquipmentKey_(MAX_ITEM_COPIES)
867 with short_name "worn brass key",
868 plural "worn brass keys",
869 name 'key' 'equipment' 'brass' 'worn' 'keys//p',
870 description "A well worn brass key. It opens the various
871 equipment rooms in the complex.",
874 Class DeutschKey_(MAX_ITEM_COPIES)
875 with short_name "bright steel key",
876 plural "bright steel keys",
877 name 'key' 'deutsch' 'steel' 'bright' 'keys//p',
878 description "A bright steel key. It unlocks the door to the Deutsch lab, downstairs.",
881 Class FormerSelf_(MAX_ITEM_COPIES)
882 with short_name "your former self",
883 plural "your former selves",
884 name 'self' 'former' 'past' 'selves//p',
885 description "She looks strangely familiar.",
886 has animate proper container concealed;
889 !===============================================================================
890 ! The one-of-a-kind moveable objects
892 Object myselfobj "(self object)"
894 short_name "yourself",
895 description "Dark hair frames a warm face. Despite the anxiety written now in your
896 tense brow, the confidence of youth and vibrancy of intellect are clear.
897 There is a depth in your clear green eyes.",
902 has concealed animate proper transparent;
905 Object skeleton_key "skeleton key (fake item to neaten code)"
907 name 'key' 'skeleton',
908 description "A skeleton key. And I thought they were make-believe!",
912 !===============================================================================
915 !-----------------------------------------------
916 ! Generic props and sights:
919 with name 'wall' 'walls',
921 if (location ~= prototype_interior)
929 with name 'floor' 'ground' 'carpet',
930 description "The floor is covered by a thin carpet in a dark but warm gray.",
932 if ((location ~= balcony) && (location ~= prototype_interior))
939 Prop ceiling "ceiling"
942 if (location ~= prototype_interior)
949 Sight darkness "darkness"
950 with name 'darkness' 'dark' 'gloom',
951 description "You cannot see what lies in the darkness.",
957 "It is not clear what you mean.";
964 Sight shadows "shadows"
965 with name 'shadows' 'shadow' 'corners' 'cobwebs',
966 description "Shadows fill the corners of the rooms like old cobwebs.",
972 "It is not clear what you mean.";
979 Sight complex "complex"
980 with name 'complex' 'building' 'surface' 'surfaces' 'texture' 'textures',
981 description "The building has modern but ultimately shallow feel.
982 There is a preoccupation with surfaces and textures.
983 Almost everything is coloured with dark, yet somewhat warm, shades of gray,
984 darkened further by the midnight gloom.",
990 "It is not clear what you mean.";
998 with name 'lights' 'light' 'fluorescent',
999 description "Most of the overhead lights are currently off, leaving the complex in dim half-light.",
1002 "Switching on the overhead lights would alert security to your presence, and besides, you
1003 can see clearly enough in the gloom.";
1006 if ((location ~= balcony) && (location ~= prototype_interior) &&
1007 (location ~= basement_equipment) && (location ~= ground_equipment))
1014 Prop stairs "stairs"
1015 with name 'stairs' 'staircase',
1018 if (self in foyer or basement_landing)
1020 if (self in upstairs_landing)
1021 "You are already at the top of the stairs.";
1023 found_in basement_landing foyer upstairs_landing,
1026 !-----------------------------------------------
1027 ! Item-related props and sights:
1029 Prop beam "flashlight beam"
1030 with name 'beam' 'blue-white' 'blue' 'white',
1031 description "A thin icy beam that cuts through the darkness.",
1040 Prop photo "photograph"
1041 with name 'photo' 'photograph' 'long' 'hair',
1042 description "You look young, bright and proud of
1043 your new position at the lab.",
1045 if (AmHolding(id_card) || IsIn(id_card,real_location))
1052 Prop stripe "magnetic stripe"
1053 with name 'stripe' 'magnetic' 'reverse' 'back',
1054 description "It is the type of magnetic stripe found on the back of a regular credit card,
1055 but is used to open the automatic doors in the building.",
1057 if (AmHolding(id_card) || IsIn(id_card,real_location))
1064 !-----------------------------------------------
1069 "A darkened foyer, presided over by a security desk near the north wall.
1070 Floating above it in the capacious darkness is
1071 a small landing. A set of stairs both rises up to meet it
1072 and stretches downwards into the dark.",
1073 u_to upstairs_landing,
1074 d_to basement_landing,
1077 cant_go "The only exits are the automatic doors to the north and south,
1078 and the staircases up and down.",
1079 lower_name "the foyer",
1082 Furniture security_desk "security desk" foyer
1083 with description "A large black desk equipped with four CCTV screens showing
1084 live feeds from around the complex. ",
1087 print "A large black desk equipped with four CCTV screens showing
1088 live feeds from around the complex. ";
1089 cctv_screens.display();
1090 print "There are also four buttons, labeled 'basement',
1091 'first', 'second' and 'alarm'.^";
1094 name 'desk' 'security' 'black' 'table',
1097 Object cctv_screens "CCTV images" foyer
1099 print "These screens flash images from the corridors and grounds
1104 name 'images' 'CCTV' 'screen' 'screens' 'feed' 'feeds' 'image',
1106 Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_CCTV_);
1108 if ((my_time == start_time - 1) || (my_time == start_time - 2))
1109 print "On one of the screens you see your former self approaching the
1111 if (IsIn(former_self,ground_corridor))
1112 print "On one of the screens you see your former self in the first
1114 if (IsIn(former_self,upstairs_corridor))
1115 print "On one of the screens you see your former self in the second
1117 if (IsIn(former_self,basement_corridor))
1118 print "On one of the screens you see your former self in the basement
1121 has scenery concealed;
1124 Object alarm_button "alarm button" foyer
1125 with description "A discrete black button carefully labeled 'alarm'.",
1126 name 'alarm' '^alarm^' 'button' 'black' 'labeled' 'marked',
1132 "The button is set into a vertical surface, making it impossible
1133 to place objects on top of it.";
1135 has scenery concealed;
1137 Object first_button "'first' button" foyer
1138 with description "A small black button carefully labeled 'first'.",
1139 name 'first' '^first^' 'floor' 'button' 'black' 'labeled' 'marked',
1141 ground_door.open_self(my_time+1);
1142 ground_door.known_exterior_opening = true;
1145 "The button is set into a vertical surface, making it impossible
1146 to place objects on top of it.";
1148 has scenery concealed;
1150 Object basement_button "'basement' button" foyer
1151 with description "A small black button carefully labeled 'basement'.",
1152 name 'basement' '^basement^' 'floor' 'button' 'black' 'labeled' 'marked',
1154 basement_door.open_self(my_time+1);
1155 "Nothing obvious happens.";
1157 "The button is set into a vertical surface, making it impossible
1158 to place objects on top of it.";
1160 has scenery concealed;
1162 Object second_button "'second' button" foyer
1163 with description "A small black button carefully labeled 'second'.",
1164 name 'second' '^second^' 'floor' 'button' 'black' 'labeled' 'marked',
1166 upstairs_door.open_self(my_time+1);
1167 "Nothing obvious happens.";
1169 "The button is set into a vertical surface, making it impossible
1170 to place objects on top of it.";
1172 has scenery concealed;
1174 Sight upstairs_landing_from_foyer "upstairs landing" foyer
1175 with description "The landing above is lost in shadow.",
1176 name 'upstairs' 'landing',
1179 Sight outside_from_foyer "outside" foyer
1180 with description "The grounds are empty and still on this frosty night.",
1181 name 'grounds' 'outside' 'night',
1184 Sight ground_corridor_from_foyer "corridor" foyer
1185 with description [;<<Examine ground_door>>;],
1189 !-----------------------------------------------
1191 Room basement_landing "Basement Landing"
1192 with name 'landing',
1194 "A cramped space at the bottom of the stairs.
1195 A corridor can be seen to the north through the automatic door,
1196 and the stairs lead back up to the foyer.",
1199 cant_go "The only exits are north and up.",
1200 lower_name "the basement landing",
1203 Sight foyer_from_basement_landing "foyer" basement_landing
1204 with description "You cannot see the foyer properly from here.",
1205 name 'foyer' 'upstairs',
1208 !-----------------------------------------------
1210 Room upstairs_landing "Upstairs Landing"
1211 with name 'landing',
1213 "A small landing, hanging in the still darkness above the foyer.",
1216 cant_go "The only exits are north and down.",
1217 lower_name "the upstairs landing",
1220 Sight foyer_from_upstairs_landing "Foyer" upstairs_landing
1222 Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_FOYER_);
1223 if (IsIn(former_self,foyer)) {
1224 "From the shadowy landing, you can just make out your former
1225 self alone in the foyer.";
1228 "From the shadowy landing, you can see much of the empty
1229 foyer stretching out below you.";
1234 !-----------------------------------------------
1236 Room ground_corridor "First Floor Corridor"
1237 with name 'first' 'floor' 'ground' 'corridor',
1239 print "A long north-south corridor, much the same as
1240 those on the other floors. ";
1241 print "Three gray doors line the eastern wall. The first two have small
1242 glass windows, peering into darkened laboratories. The third ";
1243 if (ground_equipment_door has open)
1244 print "is open onto an equipment room.^";
1246 print "is plain and leads to a small equipment room. All three are closed.^";
1249 se_to saunders_door,
1251 ne_to ground_equipment_door,
1252 cant_go "The only exits are the three doors lining
1253 the corridor (south-east, east and north-east) and the automatic door
1254 back to the foyer (south).",
1255 lower_name "the first floor corridor",
1258 FakeDoor saunders_door "door to the Saunders Lab" ground_corridor
1259 with name 'door' 'grey' 'gray' 'saunders' 'first' 'lab' 'se' 'south-east',
1260 description "A gray door with a small glass window,
1261 looking into a darkened lab.
1262 A small plaque reads: 'Saunders Lab'.",
1265 FakeDoor pooley_door "door to the Pooley Lab" ground_corridor
1266 with name 'door' 'grey' 'gray' 'pooley' 'second' 'lab' 'e\\' 'east',
1267 description "A gray door with a small glass window,
1268 looking into a darkened lab.
1269 A small plaque reads: 'Pooley Lab'.",
1272 Prop door_window "small glass window"
1273 with name 'small' 'glass' 'window' 'windows',
1274 description "You can't see anything of interest through the glass.",
1277 print_ret (The) self, " is fixed in the door.";
1279 if (IsOfType(second,crowbar))
1282 "The embedded window does not open.";
1284 "The embedded window does not open.";
1286 if (AmHolding(crowbar)) {
1287 print "You swing the crowbar firmly into the small window,
1288 but it barely leaves a mark.^";
1292 "You don't have anything heavy enough to break the window with.";
1296 found_in ground_corridor basement_corridor,
1297 has scenery concealed lockable;
1299 PluralSight doors_in_ground_corridor "doors" ground_corridor
1302 print "There are three doors on the eastern wall of the corridor,
1303 the first two (to the south-east and east) lead to the Saunders
1304 and Pooley labs. The third (to the north-east) ";
1305 if (ground_equipment_door has open)
1306 print "is open and ";
1307 print "leads to a small equipment room. To the south, the plate glass
1308 automatic door to the foyer ";
1309 if (ground_door has open)
1310 print "lies open.^";
1312 print "stands closed.^";
1316 !-----------------------------------------------
1318 Room basement_corridor "Basement Corridor"
1319 with name 'basement' 'corridor',
1321 print "A long north-south corridor, much the same as
1322 those on the other floors. ";
1323 print "Three gray doors line the eastern wall. The first two have small
1324 glass windows, peering into darkened laboratories. The third ";
1325 if (basement_equipment_door has open)
1326 print "is open onto an equipment room.^^";
1328 print "is plain and leads to a small equipment room. All three are closed.^^";
1329 if (deutsch_door has open)
1330 print "At the north end is an
1331 open door leading to the Deutsch lab.^";
1333 print "At the north end a fourth door leads to
1339 ne_to basement_equipment_door,
1341 cant_go "The only exits are to the Deutsch lab (north) the three doors lining
1342 the corridor (south-east, east and north-east) and the automatic door
1343 back to the landing (south).",
1344 lower_name "the basement corridor",
1347 FakeDoor bostrom_door "door to the Bostrom Lab" basement_corridor
1348 with name 'door' 'grey' 'gray' 'bostrom' 'first' 'lab' 'se' 'south-east',
1349 description "A gray door with a small glass window,
1350 looking into a darkened lab.
1351 A small plaque reads: 'Bostrom Lab'.",
1354 FakeDoor wallace_door "door to the Wallace Lab" basement_corridor
1355 with name 'door' 'grey' 'gray' 'wallace' 'second' 'lab' 'e\\' 'east',
1356 description "A gray door with a small glass window,
1357 looking into a darkened lab.
1358 A small plaque reads: 'Wallace Lab'.",
1361 PluralSight doors_in_basement_corridor "doors" basement_corridor
1364 print "There are three doors on the eastern wall of the corridor,
1365 the first two (to the south-east and east) lead to the Bostrom
1366 and Wallace labs. The third (to the north-east) ";
1367 if (basement_equipment_door has open)
1368 print "is open and ";
1369 print "leads to a small equipment room. At the north end is the ";
1370 if (deutsch_door has open)
1372 print "door to the Deutsch lab. ";
1373 print "To the south, the plate glass automatic door to the landing ";
1374 if (basement_door has open)
1375 print "lies open.^";
1377 print "stands closed.^";
1381 !-----------------------------------------------
1383 Room upstairs_corridor "Second Floor Corridor"
1385 "A long north-south corridor, much the same as
1386 those on the other floors. Three plain gray doors line the eastern wall.",
1388 ne_to conference_door,
1389 e_to butterfield_door,
1392 cant_go "The only exits are to the balcony (north) the three doors lining
1393 the corridor (south-east, east and north-east) and the automatic door
1394 back to the landing (south).",
1395 lower_name "the second floor corridor",
1398 FakeDoor brown_door "door to Dr Brown's office" upstairs_corridor
1399 with name 'door' 'grey' 'gray' 'brown' 'office' 'brown^s' 'Dr' 'first' 'se' 'south-east',
1400 description "A simple gray door.
1401 A small plaque reads: 'Dr Brown'.",
1404 FakeDoor butterfield_door "door to Professor Butterfield's office" upstairs_corridor
1405 with name 'door' 'office' 'grey' 'gray' 'butterfield' 'butterfield^s' 'Prof' 'second'
1407 description "A simple gray door.
1408 A small plaque reads: 'Prof Butterfield'.",
1411 FakeDoor conference_door "door to the conference room" upstairs_corridor
1412 with name 'door' 'grey' 'gray' 'conference' 'third' 'ne' 'north-east',
1413 description "A plain gray door.
1414 A small plaque reads: 'Conference Room'.",
1415 found_in upstairs_corridor conference_room,
1418 PluralSight doors_in_upstairs_corridor "doors" upstairs_corridor
1421 print "There are three doors on the eastern wall of the corridor,
1422 the first two (to the south-east and east) lead to Dr Brown
1423 and Professor Butterfield's offices. The third (to the north-east)
1424 leads to the conference room. At the north end is the ";
1425 if (balcony_door has open)
1427 print "glass door to the balcony. ";
1428 print "To the south, the plate glass automatic door to the landing ";
1429 if (upstairs_door has open)
1430 print "lies open.^";
1432 print "stands closed.^";
1436 !-----------------------------------------------
1438 Room deutsch_lab "The Deutsch Laboratory"
1439 with name 'lab' 'deutsch' 'laboratory',
1441 if (self hasnt visited) {
1442 print "The lab is order and chaos. By the dim blue-green light of a few swirling
1443 screen savers, you can see the cluttered benches of your colleagues, frozen in the
1444 mess of academic creativity. Frozen exactly as they were when badges were flashed,
1445 when we looked on in disbelief as they took control of the lab. Yours however, is clean.
1446 The books and papers are in neat stacks. They have been working here.^
1448 Nearby, against the north wall is the prototype, a six foot cylinder of brushed steel cladding.
1449 The door has been taken off and is nowhere to be seen. They have been working on it too.
1450 You wince at the sight.^";
1452 if (deutsch_door has open)
1453 print "^To the south, the door to the lab lies open.^";
1455 print "^To the south, the door to the lab stands closed.^";
1459 print "The lab is order and chaos. By the dim blue-green light of a few swirling
1460 screen savers, you can see the cluttered benches of your colleagues, frozen in the
1461 mess of academic creativity. Yours however, is clean.
1462 The books and papers are in neat stacks. They have been working here.^
1464 Nearby, against the north wall is the prototype, a six foot cylinder of brushed steel cladding.
1465 They have been working on it too.
1466 The door has been taken off and is nowhere to be seen.^";
1468 if (deutsch_door has open)
1469 "^To the south, the door to the lab lies open.";
1471 "^To the south, the door to the lab stands closed.";
1473 out_to deutsch_door,
1475 in_to prototype_interior,
1476 cant_go "The only exits are to the south and in to the prototype.",
1477 lower_name "the Deutsch laboratory",
1481 Object prototype "prototype"
1483 if (~~prototype_seen) {
1484 prototype_seen = true;
1485 print "You had built the prototype to get a strong negative result,
1486 to show that the standard model of Quantum Mechanics
1487 led to demonstrably false claims involving reverse causation. You were mistaken.
1488 One by one, your experiments showed your preliminary calculations to have been correct.
1489 When the military removed you from your project, only one aspect
1490 remained untested -- an aspect
1491 you had been loath to test before you could predict the results -- inconsistent observation.^
1493 What would happen if anomalies were observed by those in the original
1494 time-line? Your prior experiments had heavily shielded the prototype from outside interaction
1495 to avoid the very possibility. And as the calculations came out time and again,
1496 that is the only reason you are alive today.
1497 When an observer in the original time-line has an anomalous observation, the wave
1498 function of the temporally relocated object collapses and the relocation retrospectively fails,
1499 preserving chronological consistency. There is just one side effect:
1500 total transformation of the object's mass into a burst of photons -- pure energy.^
1502 You tried to tell them over and again. They assumed you were merely jealous of the takeover.
1503 Now, the night before their scheduled 'first main experiment', you have come to
1504 put an end to it all. To destroy your prototype and avoid tomorrow's nightmare.^
1506 The prototype itself is a six foot tall, four foot wide cylinder, clad with
1507 brushed steel. The frame and door were fitted with quantum shielding
1508 to prevent decoherence of the wave function, but now the door has been
1509 removed and any use of the machine is potentially disastrous.^";
1512 print "The prototype is a six foot tall, four foot wide cylinder clad with
1513 brushed steel. The frame and door were fitted with quantum shielding
1514 to prevent decoherence of the wave function, but now the door has been
1515 removed and any use of the machine is potentially disastrous.^";
1517 "^On close inspection, it appears that an attempt is in progress
1518 to move the control panel so that it can be operated from the inside.
1519 As it is, the prototype is currently not functioning, but you think
1520 you could probably complete the modification within a minute or two.";
1523 name 'prototype' 'time' 'machine' 'six' 'foot' 'cylinder',
1528 if (self in deutsch_lab)
1529 "The prototype has been modified so that the only way to operate it is
1530 to enter it and use the internal control panel.";
1531 if (self in prototype_interior)
1532 <<Set control_panel>>;
1535 "You will need to complete the partial modifications to use the prototype.";
1538 if (self in deutsch_lab)
1539 "The prototype has been modified so that the only way to operate it is
1540 to enter it and use the internal control panel.";
1541 if (self in prototype_interior)
1542 <<SetTo control_panel second>>;
1545 "You will need to complete the partial modifications to use the prototype.";
1548 if (self in deutsch_lab)
1549 "The prototype has been modified so that the only way to operate it is
1550 to enter it and use the internal control panel.";
1551 if (self in prototype_interior) {
1552 print "(pressing the silver button)^";
1553 <<Push silver_button>>;
1557 "You will need to complete the partial modifications to use the prototype.";
1561 if (real_location == prototype_interior)
1565 if (second == nothing) {
1567 "It is already fixed.";
1568 if (AmHolding(cable)) {
1569 if (self in deutsch_lab) {
1570 print "(first entering the prototype)^";
1573 if (Stopped()) return true;
1576 move GetHeld(cable) to limbo;
1577 print "You begin work completing the modifications...^";
1578 for (t=0 : t<10 : t++) {
1580 if (Stopped()) return true;
1583 prototype_fixed_time = my_time;
1584 print "After a minute or so, you are done.^";
1588 "After a few moments, you realise that completing the modification
1589 will require a ribbon cable to connect the components. You know the
1590 type of cable well, but don't have any in the lab right now.
1591 Still, the equipment room in the corridor should have one.";
1595 "It won't be enough to smash the prototype by hand as there are too many
1596 circuits buried away inside that would not be harmed.
1597 Besides, that is why you brought the bomb.";
1599 if (self in deutsch_lab) {
1600 print "(first entering the prototype)^";
1609 if (IsOfType(noun,cable))
1610 if ((second == self) || (second == control_panel))
1612 if (second == self) {
1614 "It wont fit. Obviously. What were you thinking? It is a prototype
1615 chrono-transference device, not some kind of TARDIS.";
1616 if (self in deutsch_lab) {
1617 move noun to prototype_interior;
1618 print "You reach in and place ", (the) noun, " inside the prototype.^";
1625 found_in deutsch_lab prototype_interior,
1626 has scenery concealed;
1628 Furniture bench "your bench" deutsch_lab
1629 with description "Your bench has clearly been used recently, and not by you.",
1632 print "Your bench has clearly been used recently, and not by you.
1633 Your books and papers are neatly piled to one side, leaving
1634 the largest expanse of bare desk you have ever seen here.^";
1635 if (~~have_looked_at_bench) {
1636 have_looked_at_bench = true;
1637 "^You suddenly notice that your research notes are not here.
1638 You were sure they would be -- and would thus be destroyed in the blast.
1639 This is bad. Very bad.";
1645 name 'bench' 'your' 'benches' 'table' 'desk',
1648 Prop books "text books" deutsch_lab
1649 with description "A few texts on Quantum Mechanics and String Theory
1650 that have served you very well.",
1651 name 'books' 'book' 'texts',
1654 Prop papers "papers" deutsch_lab
1656 print "A collection of photocopied journal papers that you had been reading
1658 if (~~have_looked_at_bench) {
1659 have_looked_at_bench = true;
1660 "^You suddenly notice that your research notes are not here.
1661 You were sure they would be -- and would thus be destroyed in the blast.
1662 This is bad. Very bad.";
1666 name 'papers' 'photocopies' 'stack' 'stacks',
1669 Prop screen_savers "screen savers" deutsch_lab
1670 with description "Abstract, organic shapes leave glowing phosphor trails as they swirl around
1671 and through themselves.",
1672 name 'screen' 'screens' 'saver' 'savers' 'computer' 'computers' 'light' 'violet' 'green' 'blue'
1673 'blue-green' 'swirling',
1676 Prop cladding "cladding" deutsch_lab
1677 with name 'cladding' 'steel' 'brushed' 'frame' 'hatch',
1680 Prop mess "mess" deutsch_lab
1681 with description "The usual academic mess -- open books, coffee stained mugs, sprawling papers
1682 -- frozen in time.",
1683 name 'mess' 'chaos',
1686 Sight control_panel_from_lab "control panel" deutsch_lab
1687 with description "You cannot see the control panel clearly from here, and would need to enter the prototype.",
1688 name 'control' 'panel',
1693 "You cannot see the control panel clearly from here, and would need to enter the prototype.";
1695 "You would have to enter the prototype to do that.";
1699 !-----------------------------------------------
1701 Room prototype_interior "Inside the prototype"
1703 if (prototype.fixed) {
1704 print "The interior of the prototype is cramped and dark.
1705 On the wall you see the control panel with a small LED timer
1706 set to ", control_panel.time_value, " seconds, and a silver button.
1707 Through the open hatch you can see some of the Deutsch lab.^";
1710 "The interior of the prototype is cramped and dark.
1711 On the wall you can see the half-installed control panel.
1712 Through the open hatch you can see some of the Deutsch lab.";
1714 name 'prototype' 'time' 'machine' 'interior',
1716 lower_name "the prototype",
1717 cant_go "The only exit is out to the Deutsch lab.",
1720 Object control_panel "control panel" prototype_interior
1721 with name 'control' 'panel' 'led' 'timer' 'time' 'screen',
1723 print "A brushed steel control panel with a blue LED timer, set to ",
1724 control_panel.time_value, " seconds, and a shiny silver button.^";
1731 if (prototype.fixed)
1732 "To set the control panel,
1733 you need to specify a number of seconds,
1734 for example, with 'set panel to 75'.";
1736 "You won't be able to set the control panel
1737 until you complete the modifications.";
1739 if (prototype.fixed) {
1740 if (second > 0 && second <= 500) {
1741 self.time_value = second;
1742 "You quickly type the number in to the control panel.";
1745 "The prototype's control panel only accepts
1746 between 1 and 500 seconds.";
1750 "You won't be able to set the control panel
1751 until you complete the modifications.";
1754 print "(pressing the silver button)^";
1755 <<Push silver_button>>;
1758 "You will need to complete the partial modifications to use the prototype.";
1760 has scenery concealed;
1762 Object silver_button "silver button" prototype_interior
1763 with name 'button' 'silver' 'silvered',
1764 description "A silvered button.",
1765 before [old_value t;
1767 if (prototype.fixed) {
1768 if (control_panel.time_value == 0)
1769 "The control panel emits a small beep and the number '0'
1770 flashes out at you. Perhaps you should set it first.";
1771 else if (time_travelled < MAX_TIME_TRAVELS) {
1772 old_value = control_panel.time_value;
1773 TravelThroughTime(control_panel.time_value);
1776 for (t=0 : t < time_travelled : t++)
1777 if ((Get2D(player_loc,t,my_time-EARLIEST_TIME) == deutsch_lab) ||
1778 (Get2D(player_loc,t,my_time-EARLIEST_TIME) == prototype_interior))
1779 "You hold your breath and activate the prototype.";
1780 ! this is needed to avoid silly message below, then death
1781 if ((old_value % 5) ~= 0)
1782 "You pause for a moment after pressing the button,
1783 carefully resynchronizing yourself with the
1784 five second turn increments.";
1786 "You hold your breath and activate the prototype.";
1792 "The button won't work
1793 until you complete the modifications.";
1795 "The button is set into a vertical surface, making it impossible
1796 to place objects on top of it.";
1798 has scenery concealed;
1800 Sight deutsch_lab_from_prototype "Deutsch lab" prototype_interior
1801 with description "You can't make out much of interest from here, just a few benches
1802 under the shifting blue-violet-green light.",
1803 name 'deutsch' 'lab' 'hatch' 'bench' 'benches',
1806 Prop surface "inside surface" prototype_interior
1807 with name 'walls' 'interior' 'surface' 'ceiling' 'floor' 'ground',
1808 description "The interior of the prototype is clad
1809 in smooth brushed steel.",
1811 !-----------------------------------------------
1813 Room basement_equipment "Basement Equipment Room"
1814 with name 'equipment' 'room',
1817 MoveMoveableChildren(basement_equipment_gloom,self);
1818 print "By the thin blue-white beam of your flashlight, you
1819 see the crowded shelves of the equipment room.^";
1820 if (basement_equipment_door has open)
1821 print "^To the west, the door to the corridor lies open.^";
1823 print "^To the west, the door to the corridor stands closed.^";
1826 MoveMoveableChildren(self,basement_equipment_gloom);
1827 if (basement_equipment_door has open)
1828 print "It is almost completely dark. Some faint light spills
1829 in from the west through the open door, allowing you to just
1830 discern the outlines of a series of shelves. By the door is
1833 print "You are in complete darkness.^";
1836 out_to basement_equipment_door,
1837 w_to basement_equipment_door,
1838 sw_to [;<<Go w_obj>>;],
1839 cant_go "The only exit is westwards, back to the corridor.",
1842 lower_name "the basement equipment room",
1845 ! A behind-the-scenes 'room' to store the items that should be hidden while the
1846 ! basement equipment room is in darkness
1848 Room basement_equipment_gloom "Dark Basement Equipment Room"
1849 with name 'equipment' 'room' 'dark',
1850 lower_name "the dark basement equipment room",
1853 Object basement_light_switch "light switch" basement_equipment
1854 with name 'switch' 'light' 'lights',
1857 <<SwitchOn basement_light_switch>>;
1860 Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,BLOW_BASEMENT_LIGHT_);
1863 "The fluorescent lights flicker hopefully, strobing rapidly across the
1864 scattered equipment. Then darkness. You blink away the after-images
1865 and are left with only the faint torchlight.";
1867 "The fluorescent lights flicker hopefully, strobing rapidly across the
1868 scattered equipment. Then darkness. Nothing but a few fleeting
1869 after-images of the cluttered room.";
1872 "Click. Nothing happens.";
1876 MoveMoveableChildren(basement_equipment,basement_equipment_gloom);
1880 if (~~(FlashLit())) {
1881 move noun to basement_equipment_gloom;
1884 if (basement_equipment.lit || FlashLit()) {
1885 MoveMoveableChildren(basement_equipment_gloom,basement_equipment);
1889 has static scenery concealed switchable;
1891 !-----------------------------------------------
1893 Room ground_equipment "First Floor Equipment Room"
1894 with name 'equipment' 'room',
1897 MoveMoveableChildren(ground_equipment_gloom,self);
1898 print "By the flickering fluorescent lights, you
1899 see the crowded shelves of the equipment room.^";
1900 if (ground_equipment_door has open)
1901 print "^To the west, the door to the corridor lies open.^";
1903 print "^To the west, the door to the corridor stands closed.^";
1907 MoveMoveableChildren(ground_equipment_gloom,self);
1908 print "By the thin blue-white beam of your flashlight, you
1909 see the crowded shelves of the equipment room.^";
1910 if (ground_equipment_door has open)
1911 print "^To the west, the door to the corridor lies open.^";
1913 print "^To the west, the door to the corridor stands closed.^";
1916 MoveMoveableChildren(self,ground_equipment_gloom);
1917 if (ground_equipment_door has open)
1918 print "It is almost completely dark. Some faint light spills
1919 in from the west through the open door, allowing you to just
1920 discern the outlines of a series of shelves. By the door is
1923 print "You are in complete darkness.^";
1927 out_to ground_equipment_door,
1928 w_to ground_equipment_door,
1929 sw_to [;<<Go w_obj>>;],
1930 cant_go "The only exit is westwards, back to the corridor.",
1933 lower_name "the first floor equipment room",
1936 Room ground_equipment_gloom "Dark First Floor Equipment Room"
1937 with name 'equipment' 'room' 'dark',
1938 lower_name "the dark first floor equipment room",
1941 Object ground_light_switch "light switch" ground_equipment
1942 with name 'switch' 'light' 'lights',
1945 if (~~ground_equipment.lit) {
1946 <<SwitchOn ground_light_switch>>;
1949 <<SwitchOff ground_light_switch>>;
1952 if (~~ground_equipment.lit) {
1953 ground_equipment.lit = true;
1955 print "The lights come on after a brief flicker.^";
1957 instant_action_this_turn = false;
1961 if (ground_equipment.lit) {
1962 ground_equipment.lit = false;
1965 "The lights flicker briefly, then go out,
1966 leaving you in the faint torchlight.";
1968 MoveMoveableChildren(ground_equipment,ground_equipment_gloom);
1969 "The lights flicker briefly, then go out,
1970 leaving you in the darkness.";
1976 if (~~(ground_equipment.lit))
1977 MoveMoveableChildren(ground_equipment,ground_equipment_gloom);
1981 if (~~(ground_equipment.lit || FlashLit())) {
1982 move noun to ground_equipment_gloom;
1985 if ((ground_equipment.lit) || FlashLit()) {
1986 MoveMoveableChildren(ground_equipment_gloom,ground_equipment);
1989 has static scenery concealed switchable;
1991 Prop shelves "shelves"
1992 with name 'shelf' 'shelves' 'equipment' 'series' 'outlines' 'outline' 'clutter' 'cluttered',
1994 if (((parent(self)).lit) || (Flashlit()))
1995 "The shelves are filled with assorted lab equipment, but nothing of use
1998 "You cannot make out any of the objects on the dark shelves.";
2000 found_in ground_equipment basement_equipment,
2003 Prop fluoro_light "fluorescent lights"
2004 with name 'fluoro' 'fluorescent' 'flicker' 'flickering' 'tube',
2006 if ((parent(self)).lit)
2007 "The fluorescent tubes flicker brightly.";
2009 "You can just make out a dark fluorescent tube in the ceiling above.";
2011 found_in ground_equipment basement_equipment,
2014 !-----------------------------------------------
2016 Room balcony "Balcony"
2017 with name 'balcony',
2019 "A wide balcony, looking out over the sleeping city. Below you, a lawn slopes gently away
2020 into the gloom, a few silhouetted trees marking the edge of the modest grounds. Above, the
2021 clear sky is a deep black, dusted with glinting stars.",
2022 d_to [;Jumped(); return true;],
2023 n_to [;Jumped(); return true;],
2025 se_to conference_window,
2026 in_to conference_window,
2028 if (conference_window has open)
2029 "The only exits are the door back to the corridor (to the south)
2030 and the window into the conference room (to the south-east).";
2032 "The only exit is the door back to the corridor (to the south).";
2034 lower_name "the balcony",
2037 Prop balcony_floor "floor" balcony
2038 with name 'floor' 'ground' 'tiles',
2039 description "The floor is covered in white tiles.",
2042 Prop railing "railing" balcony
2043 with name 'rail' 'railing' 'hand' 'handrail',
2046 Sight trees "trees" balcony
2047 with name 'tree' 'trees' 'silhouette' 'silhouettes' 'cypress' 'cypresses' 'conifer' 'conifers',
2048 description "The trees are some kind of tall conifer, cypress perhaps. You have fond
2049 memories of dozing under them one afternoon last summer.",
2052 Sight grounds "grounds" balcony
2053 with name 'lawn' 'slope' 'slopes' 'grounds' 'grass' 'gloom',
2054 description "The grounds are little more than a well-kept lawn and a few tall trees, but
2055 every night the security guard has to give them a brief inspection.",
2058 Sight guard "guard" balcony
2059 with name 'guard' 'security' 'guards',
2060 description "There is no sign of the security guard.",
2064 with name 'stars' 'star' 'black' 'dust' 'constellations',
2065 description "The stars are a beautiful spray of glinting jewels in the blackness above.",
2066 found_in balcony conference_room,
2070 with name 'night' 'starry',
2071 description "Outside, it is one of the finest fall nights you can recall.",
2072 found_in balcony conference_room,
2076 with name 'city' 'boston' 'town' 'light' 'rooftops' 'roofs' 'skyscrapers' 'buildings' 'building',
2077 description "Before you, lie the rooftops and skyscrapers of your home town. Here and there
2078 a small yellow light glows, but for now Boston sleeps.",
2079 found_in balcony conference_room,
2083 !-----------------------------------------------
2085 Room conference_room "Conference Room"
2086 with name 'conference',
2087 description "A rather slick but soulless affair. A large table of dark polished wood
2088 takes pride of place and is surrounded by a half-dozen chairs.",
2089 n_to conference_window,
2090 nw_to conference_window,
2091 out_to conference_window,
2092 w_to conference_door,
2093 cant_go "The only exits are the door to the west and the window to the north.",
2094 lower_name "the conference room",
2097 Sight conference_room_sight "room" conference_room
2098 with name 'room' 'conference',
2099 description "A rather slick but soulless affair.",
2106 Furniture conference_table "conference table" conference_room
2107 with description "A large round table of dark polished wood.",
2108 name 'table' 'round' 'large' 'polished' 'dark' 'wood',
2111 Furniture chair "chair" conference_room
2112 with description "Each chair is of a rather elegant, modern design
2113 in the same dark wood as the table.",
2114 name 'chair' 'chairs' 'seat' 'seats',
2115 has scenery concealed;
2117 !-----------------------------------------------
2119 Room outside "Outside"
2120 with description "Outside the lab, the street is quiet.",
2122 lower_name "the night",
2125 !-----------------------------------------------
2128 with description "The waiting place for unrealised items.",
2129 lower_name "the night",
2133 !------------------------------------------------------------------------
2138 AutomaticDoor main_doors "main doors" foyer
2141 print "Through the open doors, you can see the quiet grounds.
2142 On the right hand side is a green button.^";
2145 if (self.smashed) print "cracked ";
2146 print "plate glass sliding doors,
2147 through which you can see the quiet grounds.
2148 On the right hand side is a green button.^";
2150 when_closed "To the south is a set of automatic doors leading
2151 out into the inky night.",
2152 when_open "To the south is an open set of automatic doors leading
2153 out into the inky night.",
2154 name 'doors' 'main' 'south' 'plate' 'glass' 'sliding' 'set' 'auto',
2155 door_to [;Escaped(); return true;],
2158 if (self hasnt open) {
2159 give self open ~locked;
2160 if (self in LocationOf(player))
2161 print "The main doors open onto the night.^";
2163 self.to_close_at = t;
2164 if ((player in foyer) && (my_time < start_time-1) && (my_time >= start_time-3)) {
2168 print "Outside, your former self darts quickly towards the main doors.
2169 When she sees them open, she breaks her stride
2170 and lets out a shocked gasp.^";
2171 print "^Time unravels...^";
2176 if ((~~Stopped()) && (self in LocationOf(player)))
2177 "The main doors softly slide closed.";
2181 print "(pressing the green exit button)^";
2182 <<Push exit_button>>;
2184 if (IsOfType(second,crowbar))
2187 "You cannot open the door with that.";
2189 if (self hasnt open) {
2190 print "(first pressing the green exit button)^";
2193 if (Stopped()) return true;
2198 if (noun == s_to && self hasnt open)
2204 AutomaticDoor ground_door "automatic door"
2206 if (self in foyer) {
2207 Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_GROUND_CORRIDOR_);
2209 if (self.smashed) print "cracked ";
2210 print "plate glass sliding door,
2211 through which you can see a dim corridor. ";
2212 if (IsIn(former_self,ground_corridor))
2213 print "In the shadows stands your past self. ";
2214 print "On the right hand side is a slot for an ID card.^";
2216 if (self in ground_corridor) {
2217 Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_FOYER_);
2219 if (self.smashed) print "cracked ";
2220 print "plate glass sliding door,
2221 through which you can see the darkened foyer. ";
2222 if (IsIn(former_self,foyer))
2223 print "In the shadows stands your past self. ";
2224 print "On the right hand side is a green button.^";
2229 "In the north wall is a closed
2231 if (self in ground_corridor)
2232 "To the south is a closed automatic door, leading back
2238 "In the north wall is an open
2240 if (self in ground_corridor)
2241 "To the south is an open automatic door, leading back
2245 name 'north' 'door' 'automatic' 'auto' 'plate' 'glass' 'sliding',
2248 return ground_corridor;
2249 if (self in ground_corridor)
2256 if (self in ground_corridor)
2262 if (IsOfType(second,crowbar))
2264 else if (IsOfType(second,id_card) && (self in foyer))
2265 <<Insert second id_slot>>;
2267 "You cannot open the door with that.";
2270 if (self.known_exterior_opening == 0)
2271 "There is no obvious way to get
2272 the automatic door to open.";
2274 print "You press the button marked 'first'.^";
2275 <<Push first_button>>;
2277 if (self in ground_corridor) {
2278 print "(pressing the green exit button)^";
2279 <<Push exit_button>>;
2282 if (self in ground_corridor && self hasnt open) {
2283 print "(first pressing the green exit button)^";
2286 if (Stopped()) return true;
2289 if (self in foyer && self hasnt open) {
2290 if (self.known_exterior_opening == true) {
2291 print "(first pressing the button marked 'first')^";
2292 <Push first_button>;
2294 if (Stopped()) return true;
2298 "There is no obvious way to get
2299 the automatic door to open.";
2304 if (noun == n_to && self in foyer && self hasnt open)
2306 if (noun == s_to && self in ground_corridor && self hasnt open)
2309 known_exterior_opening,
2310 found_in foyer ground_corridor,
2314 AutomaticDoor basement_door "automatic door"
2316 if (self in basement_landing) {
2317 Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_BASEMENT_CORRIDOR_);
2319 if (self.smashed) print "cracked ";
2320 print "plate glass sliding door,
2321 through which you can see a dim corridor. ";
2322 if (IsIn(former_self,basement_corridor))
2323 print "In the shadows stands your past self. ";
2324 print "On the right hand side is a slot for an ID card.^";
2326 if (self in basement_corridor) {
2327 Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_BASEMENT_LANDING_);
2329 if (self.smashed) print "cracked ";
2330 print "plate glass sliding door,
2331 through which you can see the small basement landing. ";
2332 if (IsIn(former_self,basement_landing))
2333 print "In the shadows stands your past self. ";
2334 print "On the right hand side is a green button.^";
2337 name 'door' 'automatic' 'auto' 'plate' 'glass' 'sliding',
2339 if (self in basement_landing)
2340 "To the north is a closed automatic door.";
2341 if (self in basement_corridor)
2342 "To the south is a closed automatic door, leading back
2347 if (self in basement_landing)
2348 "To the north is an open automatic door.";
2349 if (self in basement_corridor)
2350 "To the south is an open automatic door, leading back
2355 if (self in basement_landing)
2356 return basement_corridor;
2357 if (self in basement_corridor)
2358 return basement_landing;
2362 if (self in basement_landing)
2364 if (self in basement_corridor)
2370 if (IsOfType(second,crowbar))
2372 else if (IsOfType(second,id_card) && (self in basement_landing))
2373 <<Insert second id_slot>>;
2375 "You cannot open the door with that.";
2377 if (self in basement_landing) {
2378 if ( AmHolding(id_card) ) {
2379 print "(inserting your ID card)^";
2380 <<Insert (GetHeld(id_card)) id_slot>>;
2383 "You would need you ID card to do that.";
2385 if (self in basement_corridor) {
2386 print "(pressing the green exit button)^";
2387 <<Push exit_button>>;
2390 if (self in basement_corridor && self hasnt open) {
2391 print "(first pressing the green exit button)^";
2394 if (Stopped()) return true;
2397 if (self in basement_landing && self hasnt open) {
2398 if ( AmHolding(id_card) ) {
2399 print "(first inserting your ID card)^";
2400 <Insert (GetHeld(id_card)) id_slot>;
2402 if (Stopped()) return true;
2406 "You would need you ID card to do that.";
2410 if (noun == n_to && self in basement_landing && self hasnt open)
2412 if (noun == s_to && self in basement_corridor && self hasnt open)
2415 known_exterior_opening,
2416 found_in basement_landing basement_corridor,
2420 AutomaticDoor upstairs_door "automatic door"
2422 if (self in upstairs_landing) {
2423 Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_UPSTAIRS_CORRIDOR_);
2425 if (self.smashed) print "cracked ";
2426 print "plate glass sliding door,
2427 through which you can see a dim corridor. ";
2428 if (IsIn(former_self,upstairs_corridor))
2429 print "In the shadows stands your past self. ";
2430 print "On the right hand side is a slot for an ID card.^";
2432 if (self in upstairs_corridor) {
2433 Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_UPSTAIRS_LANDING_);
2435 if (self.smashed) print "cracked ";
2436 print "plate glass sliding door,
2437 through which you can see the upper part of the darkened foyer. ";
2438 if (IsIn(former_self,upstairs_landing))
2439 print "In the shadows of the landing stands your past self. ";
2440 print "On the right hand side is a green button.^";
2443 name 'door' 'automatic' 'auto' 'plate' 'glass' 'sliding',
2445 if (self in upstairs_landing)
2446 "On the north wall lies a closed automatic door.";
2447 if (self in upstairs_corridor)
2448 "To the south is a closed automatic door, leading back
2452 if (self in upstairs_landing)
2453 "On the north wall lies an open automatic door.";
2454 if (self in upstairs_corridor)
2455 "To the south is an open automatic door, leading back
2459 if (self in upstairs_landing)
2460 return upstairs_corridor;
2461 if (self in upstairs_corridor)
2462 return upstairs_landing;
2465 if (self in upstairs_landing)
2467 if (self in upstairs_corridor)
2472 if (IsOfType(second,crowbar))
2474 else if (IsOfType(second,id_card) && (self in upstairs_landing))
2475 <<Insert second id_slot>>;
2477 "You cannot open the door with that.";
2479 if (self in upstairs_landing)
2480 if (AmHolding(id_card)) {
2481 print "(inserting your ID card)^";
2482 <<Insert (GetHeld(id_card)) id_slot>>;
2484 if (self in upstairs_corridor) {
2485 print "(pressing the green exit button)^";
2486 <<Push exit_button>>;
2489 if (self in upstairs_corridor && self hasnt open) {
2490 print "(first pressing the green exit button)^";
2492 if (self has open) {
2494 if (Stopped()) return true;
2499 if (self in upstairs_landing && self hasnt open) {
2500 "There is no obvious way to get the automatic door to open.";
2504 if (noun == s_to && self in upstairs_corridor && self hasnt open)
2507 found_in upstairs_landing upstairs_corridor,
2510 Object exit_button "green exit button"
2511 with description "A green button beside the door.",
2512 name 'green' 'button',
2514 if (self in ground_corridor) {
2515 ground_door.open_self(my_time+1);
2517 if (self in upstairs_corridor) {
2519 "Nothing happens -- the button must be broken.";
2521 upstairs_door.open_self(my_time+1);
2523 if (self in basement_corridor) {
2524 basement_door.open_self(my_time+1);
2526 if (self in foyer) {
2527 main_doors.open_self(my_time+1);
2531 "The button is set into a vertical surface, making it impossible
2532 to place objects on top of it.";
2534 found_in ground_corridor upstairs_corridor basement_corridor foyer,
2535 has scenery concealed;
2537 Object id_slot "ID card slot"
2538 with description "A narrow slot to the right of the door.
2539 The doors are coded so that only those with legitimate
2540 business can use their card to gain entrance.",
2543 found_in foyer upstairs_landing basement_landing,
2544 has scenery concealed;
2547 ManualDoor ground_equipment_door "door to the equipment room"
2548 with name 'door' 'equipment' 'room' 'grey' 'gray' 'third' 'plain' 'ne' 'north-east',
2550 "A simple gray door.",
2552 if (self in ground_corridor)
2553 return ground_equipment;
2554 if (self in ground_equipment)
2555 return ground_corridor;
2558 if (self in ground_corridor)
2560 if (self in ground_equipment)
2565 if (((self in ground_equipment) && IsIn(former_self,ground_corridor)) ||
2566 ((self in ground_corridor) && IsIn(former_self,ground_equipment)) ) {
2571 if (((self in ground_equipment) && IsIn(former_self,ground_corridor)) ||
2572 ((self in ground_corridor) && IsIn(former_self,ground_equipment)) ) {
2577 return (OpenManualDoor(self,second));
2579 if (IsOfType(second,crowbar))
2581 if (((self in ground_equipment) && IsIn(former_self,ground_corridor)) ||
2582 ((self in ground_corridor) && IsIn(former_self,ground_equipment)) ) {
2583 LockUnlockParadox();
2587 return (UnlockManualDoor(self,second));
2589 if (((self in ground_equipment) && IsIn(former_self,ground_corridor)) ||
2590 ((self in ground_corridor) && IsIn(former_self,ground_equipment)) ) {
2591 LockUnlockParadox();
2595 return (LockManualDoor(self,second));
2597 with_key_type equipment_key,
2598 found_in ground_corridor ground_equipment,
2601 ManualDoor basement_equipment_door "door to the equipment room"
2602 with name 'door' 'equipment' 'room' 'grey' 'gray' 'third' 'plain' 'ne' 'north-east',
2604 "A simple gray door.",
2606 if (self in basement_corridor)
2607 return basement_equipment;
2608 if (self in basement_equipment)
2609 return basement_corridor;
2613 if (self in basement_corridor)
2615 if (self in basement_equipment)
2620 if (((self in basement_equipment) && IsIn(former_self,basement_corridor)) ||
2621 ((self in basement_corridor) && IsIn(former_self,basement_equipment)) ) {
2626 if (((self in basement_equipment) && IsIn(former_self,basement_corridor)) ||
2627 ((self in basement_corridor) && IsIn(former_self,basement_equipment)) ) {
2632 return (OpenManualDoor(self,second));
2634 if (IsOfType(second,crowbar))
2636 if (((self in basement_equipment) && IsIn(former_self,basement_corridor)) ||
2637 ((self in basement_corridor) && IsIn(former_self,basement_equipment)) ) {
2638 LockUnlockParadox();
2642 return (UnlockManualDoor(self,second));
2644 if (((self in basement_equipment) && IsIn(former_self,basement_corridor)) ||
2645 ((self in basement_corridor) && IsIn(former_self,basement_equipment)) ) {
2646 LockUnlockParadox();
2650 return (LockManualDoor(self,second));
2652 with_key_type equipment_key,
2653 found_in basement_corridor basement_equipment,
2656 ManualDoor deutsch_door "door to the Deutsch lab"
2657 with name 'door' 'deutsch' 'lab' 'fourth' 'north' 'n\\',
2659 if (self in basement_corridor)
2660 "A gray door with a small glass window,
2661 looking into the darkened lab.";
2662 if (self in deutsch_lab)
2663 "A gray door with a small glass window,
2664 looking into the darkened corridor.";
2667 if (self in basement_corridor)
2669 if (self in deutsch_lab)
2670 return basement_corridor;
2673 if (self in basement_corridor)
2675 if (self in deutsch_lab)
2680 if (((self in deutsch_lab) && IsIn(former_self,basement_corridor)) ||
2681 ((self in basement_corridor) && IsIn(former_self,deutsch_lab)) ) {
2686 if (((self in deutsch_lab) && IsIn(former_self,basement_corridor)) ||
2687 ((self in basement_corridor) && IsIn(former_self,deutsch_lab)) ) {
2692 return (OpenManualDoor(self,second));
2694 if (IsOfType(second,crowbar))
2696 if (((self in deutsch_lab) && IsIn(former_self,basement_corridor)) ||
2697 ((self in basement_corridor) && IsIn(former_self,deutsch_lab)) ) {
2698 LockUnlockParadox();
2702 return (UnlockManualDoor(self,second));
2704 if (((self in deutsch_lab) && IsIn(former_self,basement_corridor)) ||
2705 ((self in basement_corridor) && IsIn(former_self,deutsch_lab)) ) {
2706 LockUnlockParadox();
2710 return (LockManualDoor(self,second));
2712 with_key_type deutsch_key,
2713 found_in basement_corridor deutsch_lab,
2716 ManualDoor balcony_door "balcony door"
2717 with name 'door' 'balcony' 'n\\' 'north' 'glass',
2719 if (self in upstairs_corridor) {
2720 Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_BALCONY_);
2722 if (self.smashed) print "cracked ";
2723 print "glass door looking out onto the balcony. ";
2724 if (IsIn(former_self,balcony))
2725 print "In the shadows you can see your past self.^";
2729 if (self in balcony) {
2730 Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_UPSTAIRS_CORRIDOR_);
2732 if (self.smashed) print "cracked ";
2733 print "glass door looking into the upstairs corridor. ";
2734 if (IsIn(former_self,upstairs_corridor))
2735 print "In the shadows you can see your past self.^";
2741 if (self in balcony)
2742 "To the south, the door to the upstairs corridor stands closed.";
2744 "At the north end of the corridor is a closed glass door leading out
2748 if (self in balcony)
2749 "To the south, the door to the upstairs corridor lies open.";
2751 "At the north end of the corridor is an open glass door leading out
2755 if (self in upstairs_corridor)
2757 if (self in balcony)
2758 return upstairs_corridor;
2762 if (self in upstairs_corridor)
2764 if (self in balcony)
2769 if (((self in balcony) && IsIn(former_self,upstairs_corridor)) ||
2770 ((self in upstairs_corridor) && IsIn(former_self,balcony)) ) {
2775 if (((self in balcony) && IsIn(former_self,upstairs_corridor)) ||
2776 ((self in upstairs_corridor) && IsIn(former_self,balcony)) ) {
2781 return (OpenManualDoor(self,second));
2783 if (IsOfType(second,crowbar))
2785 if (((self in balcony) && IsIn(former_self,upstairs_corridor)) ||
2786 ((self in upstairs_corridor) && IsIn(former_self,balcony)) ) {
2787 LockUnlockParadox();
2791 return (UnlockManualDoor(self,second));
2793 if (((self in balcony) && IsIn(former_self,upstairs_corridor)) ||
2794 ((self in upstairs_corridor) && IsIn(former_self,balcony)) ) {
2795 LockUnlockParadox();
2799 return (LockManualDoor(self,second));
2801 if (AmHolding(crowbar)) {
2802 print "You swing the crowbar firmly into the door. It shudders,
2803 cracks reaching out from the point of impact, but the glass
2805 self.smashed = true;
2810 "You don't have anything heavy enough to smash the door with.";
2815 with_key_type nothing,
2816 found_in upstairs_corridor balcony,
2819 Object conference_window "window into the conference room"
2820 with name 'window' 'glass' 'tinted' 'remains' 'shards',
2822 if (self in balcony) {
2824 "The remains of a plate glass window that has been smashed in with
2825 something heavy. Large shards of glass still protrude from the edges,
2826 framing the murky interior of the conference room.";
2827 else if (FlashLit())
2828 "My God! It's full of stars.";
2830 "A plate glass window looking into the murky interior of an conference room.";
2832 if (self in conference_room) {
2833 Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_BALCONY_);
2835 print "The remains of a plate glass window that has been smashed in with
2836 something heavy. Large shards of glass still protrude from the edges,
2837 framing the starry night beyond. ";
2839 "A plate glass window looking out into the starry night. ";
2840 if (IsIn(former_self,balcony))
2841 print "Against the stars, you can just make out the silhouette of your
2848 if (self in balcony)
2849 "To the south-east is a large, tinted glass window.";
2850 if (self in conference_room)
2851 "To the north is a large plate glass window, amazingly intact.";
2855 if (self in balcony)
2856 "To the south-east, lie the shattered remains of a window, opening into
2857 a murky conference room.";
2859 if (self in conference_room)
2860 "To the north, lie the shattered remains of a window, open to
2864 if (self in balcony)
2865 return conference_room;
2866 if (self in conference_room)
2871 if (self in balcony)
2873 if (self in conference_room)
2879 if (second == nothing)
2880 "The window appears to be locked from the inside.";
2882 if (IsOfType(second, crowbar))
2884 else if (second ~= nothing)
2885 "You cannot get the window open with that.";
2887 "You cannot find the lock.";
2889 if (AmHolding(crowbar)) {
2891 "The window is already thoroughly broken.";
2893 print "You swing the crowbar firmly into the window and it shatters with
2899 "You don't have anything heavy enough to smash the window with.";
2903 with_key_type nothing,
2904 found_in balcony conference_room,
2905 has static locked door lockable;
2909 !============================================================================
2914 !----------------------------------------------------
2916 ! Entry point functions:
2919 ! Puts the time in HH:MM:SS format on the status line
2921 [ DrawStatusLine width pos;
2935 PrintShortName(location);
2938 print (PrintTime) my_time;
2947 "There is no score in this game.";
2950 [ ChooseObjects obj code;
2952 if (obj has scenery)
2953 return 2; ! exclude scenery from 'get all' commands
2954 if (action_to_be == ##Take && obj has static)
2955 return 2; ! exclude scenery from 'get all' commands
2958 if (action_to_be == ##Insert && obj in player) ! prefer to insert into held objects
2959 return 3; ! particularly important with all
2960 ! these duplicates...
2961 if (action_to_be == ##Close && (obj has openable) && (obj has open))
2963 if (action_to_be == ##Open && (obj has openable) && (obj hasnt open))
2965 if (action_to_be == ##Lock && (obj has lockable) && (obj hasnt locked))
2967 if (action_to_be == ##Unlock && (obj has lockable) && (obj has locked))
2969 if (action_to_be == ##LockSimple && (obj has lockable) && (obj hasnt locked))
2971 if (action_to_be == ##UnlockSimple && (obj has lockable) && (obj has locked))
2973 if (action_to_be == ##Take && obj has static) ! prefer to get non-statics
2975 if (obj hasnt scenery) ! prefer non-scenery in general
2982 lookmode = 2; ! 'verbose'
2984 my_time = start_time;
2990 for (i=0 : i < MAX_ITEM_COPIES : i++) {
2991 bomb-->i = Bomb_.create();
2992 id_card-->i = IDCard_.create();
2993 equipment_key-->i = EquipmentKey_.create();
2994 deutsch_key-->i = DeutschKey_.create();
2995 flashlight-->i = Flashlight_.create();
2996 battery-->i = Battery_.create();
2997 cable-->i = Cable_.create();
2998 crowbar-->i = Crowbar_.create();
2999 notes-->i = Notes_.create();
3002 move bomb-->0 to player;
3003 move id_card-->0 to player;
3004 move deutsch_key-->0 to player;
3005 move equipment_key-->0 to deutsch_lab;
3006 move flashlight-->0 to deutsch_lab;
3007 move battery-->0 to ground_equipment_gloom;
3008 move cable-->0 to ground_equipment_gloom;
3009 move crowbar-->0 to basement_equipment_gloom;
3010 move notes-->0 to conference_table;
3012 for (i=1 : i < MAX_ITEM_COPIES : i++) {
3013 move bomb-->i to limbo;
3014 move id_card-->i to limbo;
3015 move equipment_key-->i to limbo;
3016 move deutsch_key-->i to limbo;
3017 move flashlight-->i to limbo;
3018 move battery-->i to limbo;
3019 move cable-->i to limbo;
3020 move crowbar-->i to limbo;
3021 move notes-->i to limbo;
3024 for (i=0 : i < MAX_TIME_TRAVELS : i++) {
3025 former_self-->i = FormerSelf_.create();
3026 move former_self-->i to limbo;
3035 The plan now is simple: go to your lab, plant the bomb, and run.
3036 The prototype will be destroyed. The military will have no way to
3037 continue the experiment. No-one will die.^
3039 The guard is out securing the grounds. The building is empty. You have six minutes.^
3045 !----------------------------------------------------
3050 !! Initialises the first self's history for all items
3051 !! First wipe's the history clean with all locations as 'limbo'
3052 !! Next updates pre-start_time histories of all items and the player
3053 !! Then updates the states with the proper pasts and UNKNOWN futures
3056 for (t = EARLIEST_TIME : t <= FINAL_TIME : t++) {
3057 for (i=0 : i < MAX_ITEM_COPIES : i++) {
3058 Put3D(bomb_loc, 0, (t - EARLIEST_TIME),
3060 Put3D(id_card_loc, 0, (t - EARLIEST_TIME),
3062 Put3D(equipment_key_loc, 0, (t - EARLIEST_TIME),
3064 Put3D(deutsch_key_loc, 0, (t - EARLIEST_TIME),
3066 Put3D(flashlight_loc, 0, (t - EARLIEST_TIME),
3068 Put3D(battery_loc, 0, (t - EARLIEST_TIME),
3070 Put3D(cable_loc, 0, (t - EARLIEST_TIME),
3072 Put3D(crowbar_loc, 0, (t - EARLIEST_TIME),
3074 Put3D(notes_loc, 0, (t - EARLIEST_TIME),
3077 Put3D(flashlight_state, 0, (t - EARLIEST_TIME),
3079 Put3D(bomb_setting, 0, (t - EARLIEST_TIME),
3084 for (t = EARLIEST_TIME : t <= start_time : t++) {
3085 Put3D(bomb_loc, 0, (t - EARLIEST_TIME),
3086 0, parent(bomb-->0) );
3087 Put3D(id_card_loc, 0, (t - EARLIEST_TIME),
3088 0, parent(id_card-->0) );
3089 Put3D(equipment_key_loc, 0, (t - EARLIEST_TIME),
3090 0, parent(equipment_key-->0) );
3091 Put3D(deutsch_key_loc, 0, (t - EARLIEST_TIME),
3092 0, parent(deutsch_key-->0) );
3093 Put3D(flashlight_loc, 0, (t - EARLIEST_TIME),
3094 0, parent(flashlight-->0) );
3095 Put3D(battery_loc, 0, (t - EARLIEST_TIME),
3096 0, parent(battery-->0) );
3097 Put3D(cable_loc, 0, (t - EARLIEST_TIME),
3098 0, parent(cable-->0) );
3099 Put3D(crowbar_loc, 0, (t - EARLIEST_TIME),
3100 0, parent(crowbar-->0) );
3101 Put3D(notes_loc, 0, (t - EARLIEST_TIME),
3102 0, parent(notes-->0) );
3104 for (t = EARLIEST_TIME : t < start_time : t++) {
3105 Put2D(player_loc, 0, (t - EARLIEST_TIME), limbo);
3107 Put2D(player_loc, 0, start_time - EARLIEST_TIME, foyer);
3109 for (t = EARLIEST_TIME : t <= start_time : t++) {
3110 for (s=0 : s < MAX_TIME_TRAVELS : s++) {
3111 Put2D(dangerous_activity, s, (t - EARLIEST_TIME), NONE_);
3112 Put2D(activity_target, s, (t - EARLIEST_TIME), nothing);
3113 Put2D(siren_state, s, (t - EARLIEST_TIME), false);
3114 Put2D(panel_setting, s, (t - EARLIEST_TIME), 0);
3115 Put2D(basement_equipment_light, s, (t - EARLIEST_TIME), false);
3116 Put2D(ground_equipment_light, s, (t - EARLIEST_TIME), false);
3117 Put2D(main_doors_state, s, (t - EARLIEST_TIME), LOCKED_);
3118 Put2D(basement_door_state, s, (t - EARLIEST_TIME), LOCKED_);
3119 Put2D(ground_door_state, s, (t - EARLIEST_TIME), LOCKED_);
3120 Put2D(upstairs_door_state, s, (t - EARLIEST_TIME), LOCKED_);
3121 Put2D(balcony_door_state, s, (t - EARLIEST_TIME), CLOSED_);
3122 Put2D(conference_window_state, s, (t - EARLIEST_TIME), LOCKED_);
3123 Put2D(deutsch_door_state, s, (t - EARLIEST_TIME), LOCKED_);
3124 Put2D(basement_equipment_door_state, s, (t - EARLIEST_TIME), LOCKED_);
3125 Put2D(ground_equipment_door_state, s, (t - EARLIEST_TIME), LOCKED_);
3127 Put2D(main_doors_smashed, s, (t - EARLIEST_TIME), false);
3128 Put2D(basement_door_smashed, s, (t - EARLIEST_TIME), false);
3129 Put2D(ground_door_smashed, s, (t - EARLIEST_TIME), false);
3130 Put2D(upstairs_door_smashed, s, (t - EARLIEST_TIME), false);
3131 Put2D(balcony_door_smashed, s, (t - EARLIEST_TIME), false);
3133 for (i=0 : i < MAX_ITEM_COPIES : i++) {
3134 Put3D(flashlight_state, 0, (t - EARLIEST_TIME),
3136 Put3D(bomb_setting, 0, (t - EARLIEST_TIME),
3142 for (t = start_time+1 : t <= FINAL_TIME : t++) {
3143 for (s=0 : s < MAX_TIME_TRAVELS : s++) {
3144 Put2D(dangerous_activity, s, (t - EARLIEST_TIME), NONE_);
3145 Put2D(activity_target, s, (t - EARLIEST_TIME), nothing);
3146 Put2D(siren_state, s, (t - EARLIEST_TIME), UNKNOWN_);
3147 Put2D(panel_setting, s, (t - EARLIEST_TIME), UNKNOWN_);
3148 Put2D(basement_equipment_light, s, (t - EARLIEST_TIME), UNKNOWN_);
3149 Put2D(ground_equipment_light, s, (t - EARLIEST_TIME), UNKNOWN_);
3150 Put2D(main_doors_state, s, (t - EARLIEST_TIME), UNKNOWN_);
3151 Put2D(basement_door_state, s, (t - EARLIEST_TIME), UNKNOWN_);
3152 Put2D(ground_door_state, s, (t - EARLIEST_TIME), UNKNOWN_);
3153 Put2D(upstairs_door_state, s, (t - EARLIEST_TIME), UNKNOWN_);
3154 Put2D(balcony_door_state, s, (t - EARLIEST_TIME), UNKNOWN_);
3155 Put2D(conference_window_state, s, (t - EARLIEST_TIME), UNKNOWN_);
3156 Put2D(deutsch_door_state, s, (t - EARLIEST_TIME), UNKNOWN_);
3157 Put2D(basement_equipment_door_state, s, (t - EARLIEST_TIME), UNKNOWN_);
3158 Put2D(ground_equipment_door_state, s, (t - EARLIEST_TIME), UNKNOWN_);
3160 Put2D(main_doors_smashed, s, (t - EARLIEST_TIME), UNKNOWN_);
3161 Put2D(basement_door_smashed, s, (t - EARLIEST_TIME), UNKNOWN_);
3162 Put2D(ground_door_smashed, s, (t - EARLIEST_TIME), UNKNOWN_);
3163 Put2D(upstairs_door_smashed, s, (t - EARLIEST_TIME), UNKNOWN_);
3164 Put2D(balcony_door_smashed, s, (t - EARLIEST_TIME), UNKNOWN_);
3170 !! Update the time, remove the old objects that don't travel,
3171 !! create new objects, move them to the appropriate places
3173 [TravelThroughTime time_amount t s i j;
3175 last_travel_time = my_time;
3177 time_amount = time_amount / 5; ! round down to nearest five seconds
3178 if (time_amount == 0)
3181 my_time = my_time - time_amount;
3183 if (my_time < early_guard_time) {
3187 print (Nearby) 0, "the guard gives the inside corridors a last look before
3188 heading out. A small sound from the Deutsch lab. He turns.^";
3189 print "^Time unravels...^";
3194 !! replace those items the player brought with them
3196 FixBombSettings(time_amount);
3197 FixFlashlightStates();
3199 for (j=0 : j < Exp(2,time_travelled) : j++) {
3200 ReplaceTravellingItem(bomb, j);
3201 ReplaceTravellingItem(id_card, j);
3202 ReplaceTravellingItem(equipment_key, j);
3203 ReplaceTravellingItem(deutsch_key, j);
3204 ReplaceTravellingItem(flashlight, j);
3206 ReplaceTravellingItem(cable, j);
3207 ReplaceTravellingItem(crowbar, j);
3208 ReplaceTravellingItem(notes, j);
3210 !! tricky battery issues, since they can be in flashlights
3211 !! if other items could be in containers this would hurt here too
3213 if (PlayerHas(battery-->j)) {
3214 if (battery-->j in player)
3215 move battery-->(j+Exp(2,time_travelled)) to player;
3217 for (i=0 : i < Exp(2,time_travelled) : i++)
3218 if (battery-->j in (flashlight-->i))
3219 move (battery-->(j+Exp(2,time_travelled))) to (flashlight-->(i+Exp(2,time_travelled)));
3222 else if (LocationOf(battery-->j) == prototype_interior) {
3223 if (battery-->j in prototype_interior)
3224 move battery-->(j+Exp(2,time_travelled)) to prototype_interior;
3226 for (i=0 : i < Exp(2,time_travelled) : i++)
3227 if (battery-->j in flashlight-->i)
3228 move battery-->(j+Exp(2,time_travelled)) to
3229 flashlight-->(i+Exp(2,time_travelled));
3235 !! move all the old items and selves into limbo
3237 for (t=0 : t < Exp(2,time_travelled) : t++) {
3238 move bomb-->t to limbo;
3239 move id_card-->t to limbo;
3240 move equipment_key-->t to limbo;
3241 move deutsch_key-->t to limbo;
3242 move flashlight-->t to limbo;
3243 move battery-->t to limbo;
3244 move cable-->t to limbo;
3245 move crowbar-->t to limbo;
3246 move notes-->t to limbo;
3249 for (t=0 : t < time_travelled : t++)
3250 move former_self-->t to limbo;
3253 !! fix up history of immediate past self so 'player' becomes appropriate former self
3255 for (s = EARLIEST_TIME : s <= FINAL_TIME : s++) {
3256 for (t=0 : t < Exp(2,time_travelled) : t++) {
3257 if (Get3D(bomb_loc, time_travelled, (s - EARLIEST_TIME), t) == player)
3258 Put3D(bomb_loc, time_travelled, (s - EARLIEST_TIME), t,
3259 former_self-->time_travelled);
3260 if (Get3D(id_card_loc, time_travelled, (s - EARLIEST_TIME), t) == player)
3261 Put3D(id_card_loc, time_travelled, (s - EARLIEST_TIME), t,
3262 former_self-->time_travelled);
3263 if (Get3D(equipment_key_loc, time_travelled, (s - EARLIEST_TIME), t) == player)
3264 Put3D(equipment_key_loc, time_travelled, (s - EARLIEST_TIME), t,
3265 former_self-->time_travelled);
3266 if (Get3D(deutsch_key_loc, time_travelled, (s - EARLIEST_TIME), t) == player)
3267 Put3D(deutsch_key_loc, time_travelled, (s - EARLIEST_TIME), t,
3268 former_self-->time_travelled);
3269 if (Get3D(flashlight_loc, time_travelled, (s - EARLIEST_TIME), t) == player)
3270 Put3D(flashlight_loc, time_travelled, (s - EARLIEST_TIME), t,
3271 former_self-->time_travelled);
3272 if (Get3D(battery_loc, time_travelled, (s - EARLIEST_TIME), t) == player)
3273 Put3D(battery_loc, time_travelled, (s - EARLIEST_TIME), t,
3274 former_self-->time_travelled);
3275 if (Get3D(cable_loc, time_travelled, (s - EARLIEST_TIME), t) == player)
3276 Put3D(cable_loc, time_travelled, (s - EARLIEST_TIME), t,
3277 former_self-->time_travelled);
3278 if (Get3D(crowbar_loc, time_travelled, (s - EARLIEST_TIME), t) == player)
3279 Put3D(crowbar_loc, time_travelled, (s - EARLIEST_TIME), t,
3280 former_self-->time_travelled);
3281 if (Get3D(notes_loc, time_travelled, (s - EARLIEST_TIME), t) == player)
3282 Put3D(notes_loc, time_travelled, (s - EARLIEST_TIME), t,
3283 former_self-->time_travelled);
3287 !! recreate the world as it was for most recent former self
3288 !! (ie move a lot of old items and selves back to the world)
3289 !! (fix states of doors and machine)
3291 for (i=0 : i < Exp(2,time_travelled) : i++) {
3292 move bomb-->i to Get3D(bomb_loc,time_travelled,my_time-EARLIEST_TIME,i);
3293 move id_card-->i to Get3D(id_card_loc,time_travelled,my_time-EARLIEST_TIME,i);
3294 move equipment_key-->i to Get3D(equipment_key_loc,time_travelled,my_time-EARLIEST_TIME,i);
3295 move deutsch_key-->i to Get3D(deutsch_key_loc,time_travelled,my_time-EARLIEST_TIME,i);
3296 move flashlight-->i to Get3D(flashlight_loc,time_travelled,my_time-EARLIEST_TIME,i);
3297 move battery-->i to Get3D(battery_loc,time_travelled,my_time-EARLIEST_TIME,i);
3298 move cable-->i to Get3D(cable_loc,time_travelled,my_time-EARLIEST_TIME,i);
3299 move crowbar-->i to Get3D(crowbar_loc,time_travelled,my_time-EARLIEST_TIME,i);
3300 move notes-->i to Get3D(notes_loc,time_travelled,my_time-EARLIEST_TIME,i);
3302 for (t=0 : t <= time_travelled : t++) {
3303 if (Get2D(player_loc,t,my_time-EARLIEST_TIME) == nothing)
3304 move former_self-->t to limbo;
3306 move former_self-->t to Get2D(player_loc,t,my_time-EARLIEST_TIME);
3309 if (my_time < prototype_fixed_time)
3310 prototype.fixed = false;
3314 SetPanel(panel_setting);
3315 SetBasementLight(basement_equipment_light);
3316 SetGroundLight(ground_equipment_light);
3317 SetAutomaticDoor(main_doors, main_doors_state);
3318 SetAutomaticDoor(basement_door, basement_door_state);
3319 SetAutomaticDoor(ground_door, ground_door_state);
3320 SetAutomaticDoor(upstairs_door, upstairs_door_state);
3321 SetManualDoor(balcony_door, balcony_door_state);
3322 SetManualDoor(conference_window, conference_window_state);
3323 SetManualDoor(deutsch_door, deutsch_door_state);
3324 SetManualDoor(basement_equipment_door, basement_equipment_door_state);
3325 SetManualDoor(ground_equipment_door, ground_equipment_door_state);
3327 SetBrokenDoor(main_doors, main_doors_smashed);
3328 SetBrokenDoor(basement_door, basement_door_smashed);
3329 SetBrokenDoor(ground_door, ground_door_smashed);
3330 SetBrokenDoor(upstairs_door, upstairs_door_smashed);
3331 SetBrokenDoor(balcony_door, balcony_door_smashed);
3333 !! initialise the history for the new self from the most recent self
3335 for (t = EARLIEST_TIME : t <= FINAL_TIME : t++) {
3336 for (i=0 : i < MAX_ITEM_COPIES : i++) {
3337 Put3D(bomb_loc, time_travelled+1, (t - EARLIEST_TIME), i,
3338 Get3D(bomb_loc, time_travelled, (t - EARLIEST_TIME), i));
3339 Put3D(id_card_loc, time_travelled+1, (t - EARLIEST_TIME), i,
3340 Get3D(id_card_loc, time_travelled, (t - EARLIEST_TIME), i));
3341 Put3D(equipment_key_loc, time_travelled+1, (t - EARLIEST_TIME), i,
3342 Get3D(equipment_key_loc, time_travelled, (t - EARLIEST_TIME), i));
3343 Put3D(deutsch_key_loc, time_travelled+1, (t - EARLIEST_TIME), i,
3344 Get3D(deutsch_key_loc, time_travelled, (t - EARLIEST_TIME), i));
3345 Put3D(flashlight_loc, time_travelled+1, (t - EARLIEST_TIME), i,
3346 Get3D(flashlight_loc, time_travelled, (t - EARLIEST_TIME), i));
3347 Put3D(battery_loc, time_travelled+1, (t - EARLIEST_TIME), i,
3348 Get3D(battery_loc, time_travelled, (t - EARLIEST_TIME), i));
3349 Put3D(cable_loc, time_travelled+1, (t - EARLIEST_TIME), i,
3350 Get3D(cable_loc, time_travelled, (t - EARLIEST_TIME), i));
3351 Put3D(crowbar_loc, time_travelled+1, (t - EARLIEST_TIME), i,
3352 Get3D(crowbar_loc, time_travelled, (t - EARLIEST_TIME), i));
3353 Put3D(notes_loc, time_travelled+1, (t - EARLIEST_TIME), i,
3354 Get3D(notes_loc, time_travelled, (t - EARLIEST_TIME), i));
3356 Put3D(bomb_setting, time_travelled+1, (t - EARLIEST_TIME), i,
3357 Get3D(bomb_setting, time_travelled, (t - EARLIEST_TIME), i));
3358 Put3D(flashlight_state, time_travelled+1, (t - EARLIEST_TIME), i,
3359 Get3D(flashlight_state, time_travelled, (t - EARLIEST_TIME), i));
3361 Put2D(dangerous_activity, time_travelled+1, (t - EARLIEST_TIME),
3362 Get2D(dangerous_activity, time_travelled, (t - EARLIEST_TIME)));
3363 Put2D(activity_target, time_travelled+1, (t - EARLIEST_TIME),
3364 Get2D(activity_target, time_travelled, (t - EARLIEST_TIME)));
3365 Put2D(siren_state, time_travelled+1, (t - EARLIEST_TIME),
3366 Get2D(siren_state, time_travelled, (t - EARLIEST_TIME)));
3367 Put2D(panel_setting, time_travelled+1, (t - EARLIEST_TIME),
3368 Get2D(panel_setting, time_travelled, (t - EARLIEST_TIME)));
3369 Put2D(basement_equipment_light, time_travelled+1, (t - EARLIEST_TIME),
3370 Get2D(basement_equipment_light, time_travelled, (t - EARLIEST_TIME)));
3371 Put2D(ground_equipment_light, time_travelled+1, (t - EARLIEST_TIME),
3372 Get2D(ground_equipment_light, time_travelled, (t - EARLIEST_TIME)));
3373 Put2D(main_doors_state, time_travelled+1, (t - EARLIEST_TIME),
3374 Get2D(main_doors_state, time_travelled, (t - EARLIEST_TIME)));
3375 Put2D(basement_door_state, time_travelled+1, (t - EARLIEST_TIME),
3376 Get2D(basement_door_state, time_travelled, (t - EARLIEST_TIME)));
3377 Put2D(ground_door_state, time_travelled+1, (t - EARLIEST_TIME),
3378 Get2D(ground_door_state, time_travelled, (t - EARLIEST_TIME)));
3379 Put2D(upstairs_door_state, time_travelled+1, (t - EARLIEST_TIME),
3380 Get2D(upstairs_door_state, time_travelled, (t - EARLIEST_TIME)));
3381 Put2D(balcony_door_state, time_travelled+1, (t - EARLIEST_TIME),
3382 Get2D(balcony_door_state, time_travelled, (t - EARLIEST_TIME)));
3383 Put2D(conference_window_state, time_travelled+1, (t - EARLIEST_TIME),
3384 Get2D(conference_window_state, time_travelled, (t - EARLIEST_TIME)));
3385 Put2D(deutsch_door_state, time_travelled+1, (t - EARLIEST_TIME),
3386 Get2D(deutsch_door_state, time_travelled, (t - EARLIEST_TIME)));
3387 Put2D(basement_equipment_door_state, time_travelled+1, (t - EARLIEST_TIME),
3388 Get2D(basement_equipment_door_state, time_travelled, (t - EARLIEST_TIME)));
3389 Put2D(ground_equipment_door_state, time_travelled+1, (t - EARLIEST_TIME),
3390 Get2D(ground_equipment_door_state, time_travelled, (t - EARLIEST_TIME)));
3392 Put2D(main_doors_smashed, time_travelled+1, (t - EARLIEST_TIME),
3393 Get2D(main_doors_smashed, time_travelled, (t - EARLIEST_TIME)));
3394 Put2D(basement_door_smashed, time_travelled+1, (t - EARLIEST_TIME),
3395 Get2D(basement_door_smashed, time_travelled, (t - EARLIEST_TIME)));
3396 Put2D(ground_door_smashed, time_travelled+1, (t - EARLIEST_TIME),
3397 Get2D(ground_door_smashed, time_travelled, (t - EARLIEST_TIME)));
3398 Put2D(upstairs_door_smashed, time_travelled+1, (t - EARLIEST_TIME),
3399 Get2D(upstairs_door_smashed, time_travelled, (t - EARLIEST_TIME)));
3400 Put2D(balcony_door_smashed, time_travelled+1, (t - EARLIEST_TIME),
3401 Get2D(balcony_door_smashed, time_travelled, (t - EARLIEST_TIME)));
3409 [ReplaceTravellingItem thing_type i;
3410 if (PlayerHas(thing_type-->i))
3411 move thing_type-->(i+Exp(2,time_travelled)) to player;
3412 else if (LocationOf(thing_type-->i) == prototype_interior)
3413 move thing_type-->(i+Exp(2,time_travelled)) to prototype_interior;
3417 [FixBombSettings time_amount i;
3418 for (i=0 : i < Exp(2,time_travelled) : i++) {
3419 if (PlayerHas(bomb-->i) || (LocationOf(bomb-->i) == prototype_interior))
3420 if ((bomb-->i).time_value ~= NA_)
3421 (bomb-->(i+Exp(2,time_travelled))).time_value
3422 = (bomb-->i).time_value - time_amount;
3423 (bomb-->i).time_value = NA_;
3427 [FixFlashlightStates i;
3428 for (i=0 : i < Exp(2,time_travelled) : i++) {
3429 if (PlayerHas(flashlight-->i) || (LocationOf(flashlight-->i) == prototype_interior)) {
3430 if (flashlight-->i has on)
3431 give flashlight-->(i+Exp(2,time_travelled)) on;
3433 give flashlight-->(i+Exp(2,time_travelled)) ~on;
3435 give flashlight-->i ~on;
3440 !----------------------------------------------------
3442 ! Little utility functions:
3445 [IsOfType thing thing_type i;
3446 for (i=0 : i < MAX_ITEM_COPIES : i++)
3447 if (thing_type-->i == thing)
3452 [AmHolding thing_type i;
3453 for (i=0 : i < MAX_ITEM_COPIES : i++)
3454 if (thing_type-->i ~= nothing && thing_type-->i in player)
3459 [GetHeld thing_type i;
3460 for (i=0 : i < MAX_ITEM_COPIES : i++)
3461 if (thing_type-->i ~= nothing && thing_type-->i in player)
3462 return thing_type-->i;
3466 [IsIn thing_type loc i;
3467 for (i=0 : i < MAX_ITEM_COPIES : i++)
3468 if (thing_type-->i ~= nothing && thing_type-->i in loc)
3473 [GetFrom thing_type loc i;
3474 for (i=0 : i < MAX_ITEM_COPIES : i++)
3475 if (thing_type-->i ~= nothing && thing_type-->i in loc)
3476 return thing_type-->i;
3480 ![Present thing_type t;
3481 ! for (t=0 : t < MAX_ITEM_COPIES : t++)
3482 ! if (thing_type-->t ~= nothing && thing_type-->t in real_location)
3487 ![GetPresent thing_type t;
3488 ! for (t=0 : t < MAX_ITEM_COPIES : t++)
3489 ! if (thing_type-->t ~= nothing && thing_type-->t in real_location)
3490 ! return thing_type-->t;
3494 [BatteriesContained thing batteries i;
3496 for (i=0 : i < MAX_ITEM_COPIES : i++)
3497 if (battery-->i ~= nothing && battery-->i in thing)
3503 if (siren_start_time == UNKNOWN_ || siren_start_time > my_time)
3504 siren_start_time = my_time;
3507 [MoveMoveableChildren old_loc new_loc x y;
3508 while (child(old_loc)) {
3511 if ((y hasnt static) && (y ~= player)) {
3514 while (sibling(y)) {
3516 if ((y hasnt static) && (y ~= player)) {
3532 return LocationOf(parent(x));
3538 if (parent(x) == player)
3540 return PlayerHas(parent(x));
3544 for (i=0 : i < MAX_ITEM_COPIES : i++) {
3545 if (flashlight-->i ~= nothing && (flashlight-->i in player or real_location)
3546 && flashlight-->i has on)
3556 print (t/720), ":", ((t/12)%60)/10, (t/12)%10, ":", ((t%12)/2);
3562 if (t/(720*12) == 0)
3569 print (t/720), ":", ((t/12)%60)/10, (t/12)%10;
3571 if (t/(720*12) == 0)
3578 InformLibrary.end_turn_sequence();
3581 !! x == run_through, y == time_index
3583 [Put2D array x y thing;
3584 array-->((x * (GAME_LENGTH+1)) + y) = thing;
3587 !! x == run_through, y == time_index
3590 return array-->((x * (GAME_LENGTH+1)) + y);
3593 !! x == run_through, y == time_index, z == thing_number
3595 [Put3D array x y z thing;
3596 array-->( (z*(MAX_TIME_TRAVELS+1) + x)*(GAME_LENGTH+1) + y ) = thing;
3599 !! x == run_through, y == time_index, z == thing_number
3602 return array-->( (z*(MAX_TIME_TRAVELS+1) + x)*(GAME_LENGTH+1) + y );
3607 for (i=0 : i<e : i++)
3608 result = result * b;
3612 !----------------------------------------------------
3614 ! 'Observe' functions: (these make note of current state of things)
3618 for (i=0 : i < MAX_ITEM_COPIES : i++) {
3619 Put3D(bomb_setting, time_travelled, (my_time - EARLIEST_TIME), i, (bomb-->i).time_value);
3623 [ObserveFlashlights i;
3624 for (i=0 : i < MAX_ITEM_COPIES : i++) {
3625 Put3D(flashlight_state, time_travelled, (my_time - EARLIEST_TIME), i, flashlight-->i has on);
3629 [ObserveSiren siren_on;
3630 siren_on = (siren_start_time ~= UNKNOWN_) && (siren_start_time < my_time);
3631 Put2D(siren_state, time_travelled, my_time - EARLIEST_TIME, siren_on);
3635 Put2D(panel_setting, time_travelled, my_time - EARLIEST_TIME, control_panel.time_value);
3638 [ObserveGroundLight light_array;
3639 Put2D(light_array, time_travelled, my_time - EARLIEST_TIME, ground_equipment.lit);
3642 [ObserveBasementLight light_array;
3643 Put2D(light_array, time_travelled, my_time - EARLIEST_TIME, basement_light_switch.blown);
3646 [ObserveBrokenDoor door door_smashed;
3647 Put2D(door_smashed, time_travelled, my_time - EARLIEST_TIME, door.smashed);
3650 [ObserveManualDoor door door_state door_status;
3651 if (door has locked)
3652 door_status = LOCKED_;
3655 door_status = OPEN_;
3657 door_status = CLOSED_;
3659 Put2D(door_state, time_travelled, my_time - EARLIEST_TIME, door_status);
3662 [ObserveAutomaticDoor door door_state door_status;
3663 if (door has locked)
3666 door_status = door.to_close_at;
3667 Put2D(door_state, time_travelled, my_time - EARLIEST_TIME, door_status);
3670 [ObserveLocations i;
3671 Put2D(player_loc, time_travelled, (my_time - EARLIEST_TIME), parent(player));
3672 for (i=0 : i < MAX_ITEM_COPIES : i++) {
3673 Put3D(bomb_loc, time_travelled, (my_time - EARLIEST_TIME),
3674 i, parent(bomb-->i) );
3675 Put3D(id_card_loc, time_travelled, (my_time - EARLIEST_TIME),
3676 i, parent(id_card-->i) );
3677 Put3D(equipment_key_loc, time_travelled, (my_time - EARLIEST_TIME),
3678 i, parent(equipment_key-->i) );
3679 Put3D(deutsch_key_loc, time_travelled, (my_time - EARLIEST_TIME),
3680 i, parent(deutsch_key-->i) );
3681 Put3D(flashlight_loc, time_travelled, (my_time - EARLIEST_TIME),
3682 i, parent(flashlight-->i) );
3683 Put3D(battery_loc, time_travelled, (my_time - EARLIEST_TIME),
3684 i, parent(battery-->i) );
3685 Put3D(cable_loc, time_travelled, (my_time - EARLIEST_TIME),
3686 i, parent(cable-->i) );
3687 Put3D(crowbar_loc, time_travelled, (my_time - EARLIEST_TIME),
3688 i, parent(crowbar-->i) );
3689 Put3D(notes_loc, time_travelled, (my_time - EARLIEST_TIME),
3690 i, parent(notes-->i) );
3694 !----------------------------------------------------
3696 ! 'Set' functions: (these take care of certain former actions every turn)
3699 [SetBombs setting_now i;
3700 for (i=0 : i < Exp(2,time_travelled) : i++) {
3701 setting_now = Get3D(bomb_setting,time_travelled,my_time-EARLIEST_TIME,i);
3702 (bomb-->i).time_value = setting_now;
3706 [SetFlashlights setting_now i;
3707 for (i=0 : i < Exp(2,time_travelled) : i++) {
3708 setting_now = Get3D(flashlight_state,time_travelled,my_time-EARLIEST_TIME,i);
3709 if (setting_now == true)
3710 give flashlight-->i on;
3712 give flashlight-->i ~on;
3716 [SetPanel setting_array setting_now;
3717 setting_now = Get2D(setting_array, time_travelled, my_time - EARLIEST_TIME);
3718 control_panel.time_value = setting_now;
3721 [SetBasementLight setting_array setting_now;
3722 setting_now = Get2D(setting_array, time_travelled, my_time - EARLIEST_TIME);
3723 basement_light_switch.blown = setting_now;
3726 [SetGroundLight setting_array setting_now;
3727 setting_now = Get2D(setting_array, time_travelled, my_time - EARLIEST_TIME);
3728 ground_equipment.lit = setting_now;
3730 give ground_light_switch on;
3732 give ground_light_switch ~on;
3735 [SetManualDoor door door_state door_status;
3736 door_status = Get2D(door_state, time_travelled, my_time - EARLIEST_TIME);
3737 if (door_status == LOCKED_) {
3741 if (door_status == CLOSED_) {
3745 if (door_status == OPEN_) {
3749 if (door_status == UNKNOWN_) {
3750 print "Error: unknown door status needing to be set for some reason.";
3754 [SetAutomaticDoor door door_state door_status;
3755 door_status = Get2D(door_state, time_travelled, my_time - EARLIEST_TIME);
3756 if (door_status == UNKNOWN_) {
3757 give door ~open locked;
3759 if (door_status > 0) {
3760 give door open ~locked;
3761 door.to_close_at = door_status;
3765 [SetBrokenDoor door door_smashed door_status;
3766 door_status = Get2D(door_smashed, time_travelled, my_time - EARLIEST_TIME);
3767 if (door_status == UNKNOWN_) {
3768 door.smashed = false;
3770 if (door_status == true) {
3771 door.smashed = true;
3773 if (door_status == false) {
3774 door.smashed = false;
3778 [MoveFormerSelf run_through loc_next;
3779 loc_next = Get2D(player_loc, run_through, my_time - EARLIEST_TIME);
3782 if (d_destroyed_prototype && ((former_self-->run_through) in limbo) &&
3783 (loc_next == prototype_interior)) {
3787 print (PrintTime) (my_time), "^^";
3788 print "Back in the Deutsch lab, the debris from the prototype
3789 lies smoldering on the floor and no past self appears.^";
3790 print "^Time unravels...^";
3793 else if (d_destroyed_prototype && (my_time == start_time)) {
3797 print (PrintTime) (my_time), "^^";
3798 print "Elsewhere, your past self enters the foyer and smells the
3799 bitter smoke from a recent explosion.^";
3800 print "^Time unravels...^";
3804 if (loc_next == nothing)
3805 move former_self-->run_through to limbo;
3807 move former_self-->run_through to loc_next;
3810 ! if ((~~d_paradox) && (~~d_escaped) && (~~d_caught))
3811 ! print "<<< former self (", run_through, ") is in: ", (name) loc_next, " >>>^";
3815 !! Moves an object around according to the actions of former selves
3816 !! Uses the item histories to work out when an item was moved, but since
3817 !! that copy of the item may have been swapped for another (which is fine)
3818 !! we must get the first available copy in the right location to be safe.
3819 !! Also, we don't want to remove all normal objects when someone time-travels
3820 !! so, since this only happens when the player is not present and no other moving
3821 !! happens when the player is not present, we can get around it by only moving
3822 !! objects when a former self is present in the same location.
3824 [MoveObject thing_type thing_loc i loc_now loc_next;
3825 loc_now = Get3D(thing_loc,time_travelled-1,my_time-EARLIEST_TIME-1,i);
3826 loc_next = Get3D(thing_loc,time_travelled-1,my_time-EARLIEST_TIME,i);
3827 if (loc_now ~= loc_next) {
3828 if (IsIn(thing_type, loc_now)) {
3829 if (IsIn(former_self,LocationOf(GetFrom(thing_type, loc_now)))) {
3830 ! print "<<< Moving ", (name) thing_type-->i, " (", i, ") in ", (name) loc_now,
3831 ! " to ", (name) loc_next, " >>>^";
3832 move GetFrom(thing_type, loc_now) to loc_next;
3835 !! handle the odd case of object left in prototype when button pressed
3836 if (LocationOf(GetFrom(thing_type, loc_now)) == prototype_interior) {
3837 ! print "<<< Moving ", (name) thing_type-->i, " (", i, ") in ", (name) loc_now,
3838 ! " to ", (name) loc_next, " >>>^";
3839 move GetFrom(thing_type, loc_now) to loc_next;
3841 else if ((loc_now == basement_equipment_gloom) || (loc_now == ground_equipment_gloom)) {
3842 ! print "<<< Moving ", (name) thing_type-->i, " (", i, ") in ", (name) loc_now,
3843 ! " to ", (name) loc_next, " >>>^";
3844 move GetFrom(thing_type, loc_now) to loc_next;
3847 ! print "<<< Ignoring ", (name) thing_type-->0, " in ", (name) loc_now,
3848 ! " (wanted to move it to ", (name) loc_next, ") >>>^";
3853 ! print "<<< Missing ", (name) thing_type-->0, " in ", (name) loc_now,
3854 ! " (wanted to move it to ", (name) loc_next, ") >>>^";
3858 !----------------------------------------------------
3860 ! 'Maybe' functions: (these take care of former actions)
3863 [MaybeExplodeBombs i;
3864 for (i=0 : i < MAX_ITEM_COPIES : i++)
3865 if (bomb-->i ~= nothing) {
3866 if (LocationOf(bomb-->i) ~= limbo) {
3867 if (((bomb-->i).time_value == my_time - 1) &&
3868 ((bomb-->i).left_over_seconds == 0))
3870 else if (((bomb-->i).time_value == my_time - 2) &&
3871 ((bomb-->i).left_over_seconds ~=0))
3878 if (Get2D(dangerous_activity, time_travelled-1, my_time-EARLIEST_TIME-1) == SING_)
3879 if (player notin limbo)
3880 "You hear muffled singing from somewhere in the building.";
3884 if (Get2D(dangerous_activity, time_travelled-1, my_time-EARLIEST_TIME-1) == SHOUT_)
3885 if (player notin limbo)
3886 "You hear muffled shouting from somewhere in the building.";
3889 !!! a little tricky to ensure that when two bombs are in same room that the one set
3890 !!! has the same original setting as it should (ie is indistinguishable from former one)
3892 [MaybeSetBombs setting_now setting_next loc_now b i j;
3893 for (i=0 : i < Exp(2,time_travelled-1) : i++) {
3894 setting_now = Get3D(bomb_setting,time_travelled-1,my_time-EARLIEST_TIME-1,i);
3895 setting_next = Get3D(bomb_setting,time_travelled-1,my_time-EARLIEST_TIME,i);
3896 loc_now = Get3D(bomb_loc,time_travelled-1,my_time-EARLIEST_TIME-1,i);
3897 if (setting_now ~= setting_next) {
3898 if (IsIn(bomb, loc_now)) {
3899 if (IsIn(former_self,LocationOf(GetFrom(bomb, loc_now)))) {
3900 for (j=0 : j < MAX_ITEM_COPIES : j++)
3901 if ((bomb-->j ~= nothing) && (bomb-->j in loc_now))
3902 if ((bomb-->j).time_value == setting_now)
3904 ! print "<<< setting bomb (via maybeset) >>>^";
3906 b.time_value = setting_next;
3908 ! print "<<<Missing bomb of former time setting.>>>^";
3912 ! print "<<<Missing ", (name) bomb-->0, " in ", (name) loc_now,
3913 ! " (wanted to set it to ", setting_next, ")>>>^";
3918 !!! a little tricky to ensure that when two flashlights are in same room that the one set
3919 !!! has the same original setting as it should (ie is indistinguishable from former one)
3921 [MaybeSetFlashlights setting_now setting_next loc_now f i j;
3922 for (i=0 : i < Exp(2,time_travelled-1) : i++) {
3923 setting_now = Get3D(flashlight_state,time_travelled-1,my_time-EARLIEST_TIME-1,i);
3924 setting_next = Get3D(flashlight_state,time_travelled-1,my_time-EARLIEST_TIME,i);
3925 loc_now = Get3D(flashlight_loc,time_travelled-1,my_time-EARLIEST_TIME-1,i);
3926 if (setting_now ~= setting_next) {
3927 if (IsIn(flashlight, loc_now)) {
3928 if (IsIn(former_self,LocationOf(GetFrom(flashlight, loc_now)))) {
3929 for (j=0 : j < MAX_ITEM_COPIES : j++)
3930 if ((flashlight-->j ~= nothing) && (flashlight-->j in loc_now))
3931 if ((flashlight-->j has on) == setting_now)
3933 ! print "<<< setting flashlight (via maybeset) >>>^";
3935 if (setting_next == true)
3941 ! print "<<<Missing flashlight of former time setting.>>>^";
3945 ! print "<<<Missing ", (name) flashlight-->0, " in ", (name) loc_now,
3946 ! " (wanted to set it to ", setting_next, ")>>>^";
3951 [MaybeSetPanel setting_array setting_now setting_next;
3952 setting_now = Get2D(setting_array, time_travelled - 1, my_time - EARLIEST_TIME - 1);
3953 setting_next = Get2D(setting_array, time_travelled - 1, my_time - EARLIEST_TIME);
3954 if (setting_next ~= UNKNOWN_ && setting_next ~= setting_now) {
3955 control_panel.time_value = setting_next;
3959 [MaybeSetBasementLight setting_array setting_now setting_next;
3960 setting_now = Get2D(setting_array, time_travelled - 1, my_time - EARLIEST_TIME - 1);
3961 setting_next = Get2D(setting_array, time_travelled - 1, my_time - EARLIEST_TIME);
3962 if (setting_next ~= UNKNOWN_ && setting_next ~= setting_now) {
3963 basement_light_switch.blown = setting_next;
3967 [MaybeSetGroundLight setting_array setting_now setting_next;
3968 setting_now = Get2D(setting_array, time_travelled - 1, my_time - EARLIEST_TIME - 1);
3969 setting_next = Get2D(setting_array, time_travelled - 1, my_time - EARLIEST_TIME);
3970 if (setting_next ~= UNKNOWN_ && setting_next ~= setting_now) {
3971 ground_equipment.lit = setting_next;
3973 give ground_light_switch on;
3975 give ground_light_switch ~on;
3979 [MaybeCloseAutomaticDoor door;
3980 if (door.just_closed)
3981 door.just_closed = false;
3983 if (door.to_close_at == my_time - 1)
3987 !! Opens/closes/locks/unlocks doors for the past self and catches paradoxes that could not
3988 !! be seen, but where the locked/unlocked state of the door differs and interferes with the action.
3989 !! Also works when the former self unlocks an unlocked door or locks
3990 !! a locked door, but this door had the converse state and the key actually turns.
3992 [MaybeSetManualDoor door door_state past_door_status_now past_door_status_next
3993 present_door_status_now the_action t;
3995 for (t=0 : t<time_travelled : t++) {
3997 past_door_status_now = Get2D(door_state, t, my_time - EARLIEST_TIME - 1);
3998 past_door_status_next = Get2D(door_state, t, my_time - EARLIEST_TIME);
4000 present_door_status_now = Get2D(door_state, time_travelled, my_time - EARLIEST_TIME - 1);
4002 the_action = Get2D(dangerous_activity, t, my_time - EARLIEST_TIME - 1);
4004 !-- if there was a locking/unlocking, check for paradox:
4005 if (Get2D(activity_target, t, my_time - EARLIEST_TIME - 1) == door) {
4006 if (the_action == UNLOCK_) {
4007 if ((present_door_status_now == CLOSED_) && (past_door_status_now == LOCKED_)) {
4011 print (Nearby) 0, "your past self attempts to unlock ", (the) door,
4012 " but finds it already unlocked.^";
4013 print "^Time unravels...^";
4016 else if ((present_door_status_now == LOCKED_) && (past_door_status_now == CLOSED_)) {
4020 print (Nearby) 0, "your past self foolishly attempts to unlock ", (the) door,
4021 " and succeeds where you had originally found it already unlocked.^";
4022 print "^Time unravels...^";
4026 if (the_action == LOCK_) {
4027 if ((present_door_status_now == CLOSED_) && (past_door_status_now == LOCKED_)) {
4031 print (Nearby) 0, "your past self foolishly attempts to lock ", (the) door,
4032 " and succeeds where you had originally found it already locked.^";
4033 print "^Time unravels...^";
4036 if ((present_door_status_now == LOCKED_) && (past_door_status_now == CLOSED_)) {
4040 print (Nearby) 0, "your past self attempts to lock ", (the) door,
4041 " but finds it already locked.^";
4042 print "^Time unravels...^";
4046 if (the_action == OPEN_) {
4047 if ((present_door_status_now == CLOSED_) && (past_door_status_now == LOCKED_)) {
4051 print (Nearby) 0, "your past self foolishly attempts to open ", (the) door,
4052 " and succeeds where you had originally found it locked.^";
4053 print "^Time unravels...^";
4056 if ((present_door_status_now == LOCKED_) && (past_door_status_now == CLOSED_)) {
4060 print (Nearby) 0, "your past self attempts to open ", (the) door,
4061 " but finds it locked.^";
4062 print "^Time unravels...^";
4068 !-- if there should be a state change, do it:
4070 if ((past_door_status_now ~= past_door_status_next) && (past_door_status_next ~= UNKNOWN_)) {
4071 if (past_door_status_now == present_door_status_now) {
4072 if (past_door_status_next == LOCKED_) {
4075 if (door in real_location)
4076 print "You hear someone locking the ", (name) door, ".^";
4078 if (past_door_status_next == CLOSED_) {
4081 if (door in real_location && past_door_status_now == LOCKED_)
4082 print "You hear someone unlocking the ", (name) door, ".^";
4083 if (door in real_location && past_door_status_now == OPEN_)
4084 print "Someone closes ", (name) door, ".^";
4086 if (past_door_status_next == OPEN_) {
4089 if (door in real_location)
4090 print "Someone opens the ", (name) door, ".^";
4099 [MaybeSetAutomaticDoor door door_state door_status_now door_status_next;
4100 door_status_now = Get2D(door_state, time_travelled - 1, my_time - EARLIEST_TIME - 1);
4101 door_status_next = Get2D(door_state, time_travelled - 1, my_time - EARLIEST_TIME);
4102 if (door_status_next == my_time) {
4103 door.open_self(my_time);
4105 if ((door == main_doors) && (my_time == start_time - 1)) {
4106 door.open_self(my_time);
4110 [MaybeBreakDoor door door_smashed door_smashed_next;
4111 door_smashed_next = Get2D(door_smashed, time_travelled - 1, my_time - EARLIEST_TIME);
4112 if (door_smashed_next && (~~door.smashed)) {
4113 door.smashed = true;
4117 !----------------------------------------------------
4119 ! 'Check' functions: (these check for paradoxes, both active and passive)
4122 [CheckActiveParadox t action_de_jour trouble i j k flash_i_batteries flash_j_loc flash_j_batteries
4123 past_count present_count too_heavy;
4124 action_de_jour = Get2D(dangerous_activity, t, my_time-EARLIEST_TIME-1);
4127 for (t=0 : t < time_travelled : t++) {
4129 switch (action_de_jour) {
4131 if (player in upstairs_corridor or ground_corridor or basement_corridor)
4133 X_UPSTAIRS_CORRIDOR_:
4134 if (player in upstairs_corridor)
4136 X_UPSTAIRS_LANDING_:
4137 if (player in upstairs_landing)
4140 if (player in ground_corridor)
4143 if (player in foyer)
4145 X_BASEMENT_CORRIDOR_:
4146 if (player in basement_corridor)
4148 X_BASEMENT_LANDING_:
4149 if (player in basement_landing)
4152 if (player in balcony)
4155 for (i=0 : i<MAX_ITEM_COPIES : i++) {
4156 if ((flashlight-->i) in (former_self-->t)) {
4157 flash_i_batteries = BatteriesContained(flashlight-->i);
4160 for (j=0 : j < MAX_ITEM_COPIES : j++)
4161 if ((flashlight-->j) in (former_self-->t))
4162 if (BatteriesContained(flashlight-->j) == flash_i_batteries)
4164 for (j=0 : j < MAX_ITEM_COPIES : j++) {
4165 flash_j_loc = Get3D(flashlight_loc,t,my_time-EARLIEST_TIME,j);
4166 flash_j_batteries = 0;
4167 for (k=0 : k<MAX_ITEM_COPIES : k++) {
4168 if (Get3D(battery_loc,t,my_time-EARLIEST_TIME,k) == (flashlight-->j))
4169 flash_j_batteries++;
4171 if (flash_j_loc == former_self-->t)
4172 if (flash_j_batteries == flash_i_batteries)
4175 if (present_count ~= past_count) {
4176 too_heavy = (past_count < present_count);
4181 BLOW_BASEMENT_LIGHT_:
4182 if (Get2D(basement_equipment_light, time_travelled, my_time-EARLIEST_TIME-1) == true)
4189 switch (action_de_jour) {
4191 print "In the foyer, your past self glances at a CCTV screen and sees you in the
4192 shadowed corridor.^";
4193 X_UPSTAIRS_CORRIDOR_:
4194 if (former_self-->t in balcony)
4195 print "From the chilly balcony, your former self looks through the glass door
4196 and sees you in the shadowed corridor.^";
4198 print "From the upstairs landing, your former self looks through the glass
4199 and sees you in the shadowed corridor.^";
4200 X_UPSTAIRS_LANDING_:
4201 print "From the second floor corridor, your former self looks through the glass door
4202 and sees you in the shadowy landing.^";
4204 print "From within the foyer, your former self looks through
4205 the glass door and sees you in the shadowed corridor.^";
4207 if (former_self-->t in upstairs_landing)
4208 print "From the landing above, your former self looks down
4211 print "From the first floor corridor, your former self looks through
4212 the glass door and sees you.^";
4213 X_BASEMENT_CORRIDOR_:
4214 print "From the basement landing, your former self looks through the glass door
4215 and sees you in the shadowed corridor.^";
4216 X_BASEMENT_LANDING_:
4217 print "From the basement corridor, your former self looks through the glass door
4218 and sees you in the shadowy landing.^";
4220 if (former_self-->t in upstairs_corridor)
4221 print "From the second floor corridor, your former self looks through the glass door
4222 and sees you on the chilly balcony.^";
4224 print "From within the darkened conference room, your former self looks out
4225 and sees you on the chilly balcony.^";
4228 print (Nearby) 0, "your past self picks up a flashlight, but finds it
4231 print (Nearby) 0, "your past self picks up a flashlight, but finds it
4233 BLOW_BASEMENT_LIGHT_:
4234 print "In the basement equipment room, your past self switches on the light
4235 but there is no flicker, for it has already blown.^";
4237 if ((action_de_jour >= X_CCTV_) && (action_de_jour <= X_BALCONY_))
4238 print "^This is one of the all time most embarrassing ways
4239 to destroy the city of Boston.^";
4240 print "^Time unravels...^";
4248 [CheckPassiveParadox t;
4249 for (t=0 : t < time_travelled : t++)
4250 if (LocationOf(former_self-->t) ~= limbo) {
4251 CheckPlayerInRoom(t);
4252 CheckStateOfSiren(t);
4254 CheckStateOfDoors(t);
4256 CheckStateOfGroundLight(t);
4258 CheckQuantityInRoom(bomb,bomb_loc,t);
4259 CheckQuantityInRoom(id_card,id_card_loc,t);
4260 CheckQuantityInRoom(equipment_key,equipment_key_loc,t);
4261 CheckQuantityInRoom(deutsch_key,deutsch_key_loc,t);
4262 CheckQuantityInRoom(flashlight,flashlight_loc,t);
4263 CheckQuantityInRoom(battery,battery_loc,t);
4264 CheckQuantityInRoom(cable,cable_loc,t);
4265 CheckQuantityInRoom(crowbar,crowbar_loc,t);
4266 CheckQuantityInRoom(notes,notes_loc,t);
4268 CheckStateOfFlashlights(t);
4270 if (former_self-->t in foyer)
4271 CheckObjectsOnDesk(security_desk,t);
4272 if (former_self-->t in conference_room) {
4273 CheckObjectsOnDesk(conference_table,t);
4274 CheckObjectsOnDesk(chair,t);
4276 if (former_self-->t in deutsch_lab)
4277 CheckObjectsOnDesk(bench,t);
4278 if (former_self-->t in prototype_interior)
4279 CheckTimeOnPanel(t);
4281 CheckTimesOnBombs(t);
4285 [CheckStateOfDoors t fs_loc;
4286 fs_loc = LocationOf(former_self-->t);
4290 CheckStateOfDoor(main_doors, main_doors_state, t, fs_loc);
4291 CheckStateOfDoor(ground_door, ground_door_state, t, fs_loc);
4292 CheckBrokenDoor(main_doors, main_doors_smashed, t, fs_loc);
4293 CheckBrokenDoor(ground_door, ground_door_smashed, t, fs_loc);
4295 CheckStateOfDoor(ground_door, ground_door_state, t, fs_loc);
4296 CheckBrokenDoor(ground_door, ground_door_smashed, t, fs_loc);
4297 CheckStateOfDoor(ground_equipment_door, ground_equipment_door_state, t, fs_loc);
4299 CheckStateOfDoor(ground_equipment_door, ground_equipment_door_state, t, fs_loc);
4301 CheckStateOfDoor(basement_door, basement_door_state, t, fs_loc);
4302 CheckBrokenDoor(basement_door, basement_door_smashed, t, fs_loc);
4304 CheckStateOfDoor(basement_door, basement_door_state, t, fs_loc);
4305 CheckBrokenDoor(basement_door, basement_door_smashed, t, fs_loc);
4306 CheckStateOfDoor(basement_equipment_door, basement_equipment_door_state, t, fs_loc);
4307 CheckStateOfDoor(deutsch_door, deutsch_door_state, t, fs_loc);
4309 CheckStateOfDoor(deutsch_door, deutsch_door_state, t, fs_loc);
4311 CheckStateOfDoor(deutsch_door, deutsch_door_state, t, fs_loc);
4313 CheckStateOfDoor(upstairs_door, upstairs_door_state, t, fs_loc);
4314 CheckBrokenDoor(upstairs_door, upstairs_door_smashed, t, fs_loc);
4316 CheckStateOfDoor(upstairs_door, upstairs_door_state, t, fs_loc);
4317 CheckStateOfDoor(balcony_door, balcony_door_state, t, fs_loc);
4318 CheckBrokenDoor(upstairs_door, upstairs_door_smashed, t, fs_loc);
4319 CheckBrokenDoor(balcony_door, balcony_door_smashed, t, fs_loc);
4321 CheckStateOfDoor(balcony_door, balcony_door_state, t, fs_loc);
4322 CheckBrokenDoor(balcony_door, balcony_door_smashed, t, fs_loc);
4323 CheckStateOfDoor(conference_window, conference_window_state, t, fs_loc);
4325 CheckStateOfDoor(conference_window, conference_window_state, t, fs_loc);
4331 ! this is a tiny bit of a hack, using the fact that OPEN_ is higher than CLOSED_, LOCKED_.
4332 ! and the fact that automatic doors which are open have values higher than OPEN_.
4334 [CheckStateOfDoor door door_state t fs_loc past_door_state fs_loc_last_turn;
4335 past_door_state = Get2D(door_state,t,my_time-EARLIEST_TIME);
4336 fs_loc_last_turn = Get2D(player_loc,t,my_time-EARLIEST_TIME-1);
4339 if ((past_door_state >= OPEN_) && (door hasnt open)) {
4343 print (Nearby) 0, "your former self enters ", (TheLower) fs_loc,
4344 " and sees ", (the) door, " pulled closed.^";
4345 print "^Time unravels...^";
4348 else if ((past_door_state < OPEN_) && (door has open)) {
4352 if (door ~= conference_window) {
4353 if (fs_loc_last_turn ~= fs_loc)
4354 print (Nearby) 0, "your former self enters ", (TheLower) fs_loc,
4355 " and sees ", (the) door, " standing open.^";
4357 print (Nearby) 0, "your former self standing in ", (TheLower) fs_loc,
4358 " sees ", (the) door, " open.^";
4361 print (Nearby) 0, "your former self enters ", (TheLower) fs_loc,
4362 " and sees the shattered conference room window.^";
4363 print "^Time unravels...^";
4370 [CheckBrokenDoor door door_smashed t fs_loc past_door_smashed_now past_door_smashed_next;
4371 past_door_smashed_now = Get2D(door_smashed,t,my_time-EARLIEST_TIME-1);
4372 past_door_smashed_next = Get2D(door_smashed,t,my_time-EARLIEST_TIME);
4374 if ((~~past_door_smashed_next) && door.smashed) {
4378 if (past_door_smashed_now)
4379 print "In ", (TheLower) fs_loc, ", your former self sees the web of cracks in ",
4382 print "In ", (TheLower) fs_loc, ", your former self hears the crack of your
4383 crowbar smashing into ",
4385 print "^Time unravels...^";
4392 [CheckTimesOnBombs t i j bomb_i_time bomb_j_time bomb_j_loc
4393 past_count present_count fs_loc;
4395 fs_loc = LocationOf(former_self-->t);
4398 for (i=0 : i < MAX_ITEM_COPIES : i++) {
4399 if (LocationOf(bomb-->i) == fs_loc) {
4400 bomb_i_time = (bomb-->i).time_value;
4403 for (j=0 : j < MAX_ITEM_COPIES : j++)
4404 if (LocationOf(bomb-->j) == fs_loc)
4405 if ((bomb-->j).time_value == bomb_i_time)
4407 for (j=0 : j < MAX_ITEM_COPIES : j++) {
4408 bomb_j_loc = Get3D(bomb_loc,t,my_time-EARLIEST_TIME,j);
4409 bomb_j_time = Get3D(bomb_setting,t,my_time-EARLIEST_TIME,j);
4410 if (((bomb_j_loc == fs_loc) || (parent(bomb_j_loc) == fs_loc)))
4411 if (bomb_j_time == bomb_i_time)
4414 if (past_count ~= present_count) {
4418 print (Nearby) 0, "your former self enters ", (TheLower) fs_loc,
4419 " and sees a different value flashing on the explosive device's
4421 print "^Time unravels...^";
4430 [CheckStateOfFlashlights t i present_flashlights_on past_flashlights_on
4431 fs_loc flash_loc flash_state;
4432 fs_loc = LocationOf(former_self-->t);
4434 for (i=0 : i < MAX_ITEM_COPIES : i++) {
4435 flash_loc = Get3D(flashlight_loc,t,my_time-EARLIEST_TIME,i);
4436 flash_state = Get3D(flashlight_state,t,my_time-EARLIEST_TIME,i);
4437 if (flash_state && ((flash_loc == fs_loc) || (parent(flash_loc) == fs_loc)))
4438 past_flashlights_on++;
4439 if ((flashlight-->i has on) && (LocationOf(flashlight-->i) == fs_loc))
4440 present_flashlights_on++;
4442 if (past_flashlights_on ~= present_flashlights_on) {
4446 if (past_flashlights_on < present_flashlights_on)
4447 print (Nearby) 0, "your former self enters ", (TheLower) fs_loc,
4448 " and sees a thin white beam of light shining where once
4451 print (Nearby) 0, "your former self enters ", (TheLower) fs_loc,
4452 " and sees only darkness where once a thin white beam of light
4454 print "^Time unravels...^";
4460 ! only need to check if in corridor with open door as this will catch all cases
4462 [CheckStateOfGroundLight t past_ground_light_state;
4463 past_ground_light_state = Get2D(ground_equipment_light,t,my_time-EARLIEST_TIME);
4466 if ((ground_light_switch has on) ~= past_ground_light_state) {
4467 if ((former_self-->t in ground_corridor) && (ground_equipment_door has open)) {
4471 if (ground_light_switch has on) {
4472 if (Get2D(ground_equipment_door_state,t,my_time-EARLIEST_TIME-1)==OPEN_)
4473 print (Nearby) 0, "your former self enters the first floor corridor
4474 and sees a pool of light spilling from the equipment room.^";
4476 print (Nearby) 0, "your former self opens the door to the first floor
4477 equipment room and bright fluorescent light
4481 if (Get2D(ground_equipment_door_state,t,my_time-EARLIEST_TIME-1)==OPEN_)
4482 print (Nearby) 0, "your former self enters the first floor corridor
4483 but does not see a pool of light spilling from the
4486 print (Nearby) 0, "your former self opens the door to the first floor
4487 equipment room but no bright fluorescent light
4490 print "^Time unravels...^";
4496 [CheckStateOfSiren t past_state siren_on;
4497 past_state = Get2D(siren_state,t,my_time-EARLIEST_TIME);
4498 siren_on = (siren_start_time ~= UNKNOWN_) && (siren_start_time < my_time);
4501 if (past_state ~= siren_on) {
4502 if (my_time - siren_start_time == 1)
4503 print "^A piercing siren rings out.^";
4504 if (my_time - siren_start_time > 1)
4505 print "^The siren wails.^";
4509 print (Nearby) 0, "your former self cringes from the sound of the siren.^";
4510 print "^Time unravels...^";
4516 !! Only checks the bare contents of the room, not the containers, states etc.
4518 [CheckQuantityInRoom thing_type thing_loc t i present_count past_count;
4523 for (i=0 : i < Exp(2,t+1) : i++) {
4524 if (parent(thing_type-->i) == LocationOf(former_self-->t))
4526 if (Get3D(thing_loc,t,my_time-EARLIEST_TIME,i) == LocationOf(former_self-->t))
4529 if (past_count ~= present_count) {
4533 print "Entering ", (TheLower) LocationOf(former_self-->t),
4534 " your past self looks quickly about. ";
4535 if (past_count > present_count)
4536 print "Unlike the last time, her gaze passes straight over the place
4537 where ", (the) thing_type-->0,
4540 print "As her glance falls upon ", (the) thing_type-->0,
4541 " a moment of worry passes over her features.^";
4542 print "^Time unravels...^";
4548 [CheckPlayerInRoom t player_loc_now player_loc_next fs_loc_now fs_loc_next;
4550 player_loc_now = Get2D(player_loc,time_travelled,my_time-EARLIEST_TIME-1);
4551 player_loc_next = Get2D(player_loc,time_travelled,my_time-EARLIEST_TIME);
4552 fs_loc_now = Get2D(player_loc,t,my_time-EARLIEST_TIME-1);
4553 fs_loc_next = Get2D(player_loc,t,my_time-EARLIEST_TIME);
4555 if ((player_loc_next == fs_loc_next)) {
4556 if (player_loc_now == nothing) {
4560 print "Someone appears beside you in the cramped chamber.
4561 Soft hair and anxious eyes. It is you.^";
4562 print "^Time unravels...^";
4565 else if (player_loc_now ~= player_loc_next) { !! if the player had moved...
4569 print "As you enter ", (TheLower) player_loc_next,
4570 " you see your former self standing before you.
4571 Hearing your soft footfall, she turns. Horror fills her eyes.^";
4572 print "^Time unravels...^";
4575 else if (fs_loc_now ~= fs_loc_next) { !! if the former self had moved...
4579 print "You turn at the sound of footsteps. It is you.^";
4580 print "^Time unravels...^";
4584 print "Error, former self saw player but neither had moved.^";
4586 else if ((player_loc_next == fs_loc_now) && (player_loc_now == fs_loc_next)) {
4590 print "As you enter ", (TheLower) player_loc_next,
4591 ", your eyes catch upon a figure coming towards you.
4592 She pauses, fear all about her.^";
4593 print "^Time unravels...^";
4596 else if ((player_loc_next == deutsch_lab) && (fs_loc_next == prototype_interior)) {
4600 print "Hunched inside the prototype, your former self sees you through the open
4602 print "^Time unravels...^";
4605 else if ((player_loc_next == prototype_interior) && (fs_loc_next == deutsch_lab)) {
4609 print "As your past self looks around, her eyes catch on
4610 something inside the prototype.^";
4611 print "^Time unravels...^";
4617 [CheckObjectsOnDesk desk t;
4618 CheckObjectOnDesk(desk, t, bomb, bomb_loc);
4619 CheckObjectOnDesk(desk, t, id_card, id_card_loc);
4620 CheckObjectOnDesk(desk, t, equipment_key, equipment_key_loc);
4621 CheckObjectOnDesk(desk, t, deutsch_key, deutsch_key_loc);
4622 CheckObjectOnDesk(desk, t, flashlight, flashlight_loc);
4623 CheckObjectOnDesk(desk, t, battery, battery_loc);
4624 CheckObjectOnDesk(desk, t, cable, cable_loc);
4625 CheckObjectOnDesk(desk, t, crowbar, crowbar_loc);
4626 CheckObjectOnDesk(desk, t, notes, notes_loc);
4629 [CheckObjectOnDesk desk t thing_type thing_loc present_count past_count i;
4631 for (i=0 : i < Exp(2,t+1) : i++) {
4632 if (thing_type-->i in desk)
4634 if (Get3D(thing_loc,t,my_time-EARLIEST_TIME,i) == desk)
4637 if (past_count ~= present_count) {
4641 print "Entering ", (TheLower) LocationOf(former_self-->t),
4642 " your past self looks quickly about. ";
4643 if (past_count > present_count)
4644 print "Unlike the last time, her gaze passes straight over the place
4645 on ", (the) desk, " where ", (the) thing_type-->0,
4648 print "As her glance falls upon ", (the) thing_type-->0,
4649 " a moment of worry passes over her features.^";
4650 print "^Time unravels...^";
4656 [CheckTimeOnPanel t old_setting;
4657 old_setting = Get2D(panel_setting, t, my_time-EARLIEST_TIME);
4659 if (control_panel.time_value ~= old_setting) {
4663 print "Entering the prototype, your past self glances at the control panel,
4664 seeing ", control_panel.time_value, " instead of ", old_setting, ".^";
4665 print "^Time unravels...^";
4671 !----------------------------------------------------
4673 ! Endgame functions:
4679 !-- Initial method of being caught:
4681 if (my_time > FINAL_TIME)
4682 print "^A quick noise from behind, then a strong grip on your wrist.
4683 The guard is back -- time has slipped away from you.^";
4684 else if ((siren_start_time ~= UNKNOWN_) && (my_time - siren_start_time > siren_timeout))
4685 print "^As the siren shrieks out around you, you catch a glimpse of movement.
4686 A sudden jolt, then you are wrestled to the ground. Security has arrived.^";
4688 print "Error: unknown reason for being caught^";
4690 !-- Allow a small amount of time for bomb to explode before player dragged off...
4692 for (t=0 : (t<TIME_BEFORE_DRAGGED_OFF) && (my_time<FINAL_TIME) && (~~d_exploded) : t++) {
4693 IncTime(); ! as it happens, this can lead to bomb-explosion, but not paradox
4696 if (~~d_exploded) ! make sure player is dragged off
4701 if (~~warned_of_jump) {
4702 print "It is a large drop and you are not at all sure that you could make it
4703 without serious injury.^";
4704 warned_of_jump = true;
4710 !-- Initial method of being caught:
4712 print "You hit the ground hard and collapse. Your right ankle sears with pain.
4713 Before you can stand, you see the security guard running swiftly towards you.^";
4721 print "^Deaf to your protests, the guard ";
4722 if (AmHolding(bomb) && ((GetHeld(bomb)).time_value ~= NA_))
4723 print "disarms your bomb, ";
4724 print "handcuffs you and forces you
4725 into a dark sedan. You speed through the chill Boston night, head held in your hands,
4726 almost oblivious to the blur of the suburbs rushing past.^";
4729 move player to limbo;
4731 !-- Allow some more time for bomb to explode
4732 !-- and for paradoxes to occur
4734 for (t=0 : (my_time<FINAL_TIME) && (~~d_exploded) && (~~d_paradox) : t++) {
4738 MaybeExplodeBombAfterwards();
4742 !-- Consequences of being caught:
4745 print "^Half an hour later, the car pulls up outside a non-descript building and you
4746 are dragged inside";
4747 if (AmHolding(notes))
4748 print ", the notes are taken from you and you are ";
4751 print "thrown into a small cell to await questioning.^";
4754 if (d_destroyed_prototype && d_destroyed_notes) {
4755 print "^The months that follow are a nightmare. Solitary confinement, sleepless nights,
4756 merciless interrogations. Eventually, you are taken before a civilian court and
4757 tried for treason. A drawn-out trial, a guilty verdict, prison. Ambitions falter and
4758 then fade. Still, as the months and then years pass, they do not bring the disaster
4759 you had so feared and you cling, anxiously, longingly, to the dream that it was you who brought
4760 this about, that your sacrifice was not in vain.^";
4763 deadflag = SAVED_CAUGHT_;
4765 ! else if (d_destroyed_prototype && AmHolding(notes)) {
4767 else if (d_destroyed_prototype) {
4768 print "^The days that follow are a nightmare. Solitary confinement, sleepless nights,
4769 merciless interrogations. All that keeps you going is the small hope that your actions
4770 were not in vain.^";
4772 print "With your research notes at hand, the military scientists painstakingly rebuild the
4773 prototype and prepare it for testing.^";
4775 ! else if (d_destroyed_notes) {
4778 ! else if (AmHolding(notes)) {
4785 ! else if (AmHolding(bomb) && AmHolding(notes)) {
4788 ! else if (AmHolding(bomb)) {
4791 ! else if (AmHolding(notes)) {
4798 if ((~~d_destroyed_prototype) || (~~d_destroyed_notes))
4803 [InBlastRadius thing bomb;
4804 if (LocationOf(thing) == LocationOf(bomb))
4806 if ((LocationOf(bomb) == deutsch_lab) && (LocationOf(thing) == prototype_interior))
4808 if ((LocationOf(bomb) == prototype_interior) && (LocationOf(thing) == deutsch_lab))
4813 [MaybeExplodeBombAfterwards i j;
4815 for (i=0 : i<MAX_ITEM_COPIES : i++)
4816 if (((bomb-->i).time_value >= FINAL_TIME) && ~~(bomb-->i in player)) {
4818 if (LocationOf(bomb-->i) == deutsch_lab or prototype_interior)
4819 d_destroyed_prototype = true;
4820 for (j=0 : j < MAX_ITEM_COPIES : j++)
4821 if (InBlastRadius(notes-->j,bomb-->i))
4822 d_destroyed_notes = true;
4835 if ((~~(d_escaped || d_detained)) && InBlastRadius(player,bomb-->i) )
4836 d_killed_by_bomb = true;
4837 if (~~(d_escaped || d_detained))
4838 d_injured_by_bomb = true;
4839 if (LocationOf(bomb-->i) == deutsch_lab or prototype_interior)
4840 d_destroyed_prototype = true;
4841 for (j=0 : j < MAX_ITEM_COPIES : j++)
4842 if (InBlastRadius(notes-->j,bomb-->i))
4843 d_destroyed_notes = true;
4844 for (t=0 : t < time_travelled : t++)
4845 if (InBlastRadius(former_self-->t, bomb-->i)) {
4846 d_fs_killed_by_bomb = true;
4849 for (t=0 : t < time_travelled : t++)
4850 if ((LocationOf(former_self-->t) ~= limbo)) {
4851 d_fs_hears_bomb = true;
4855 !-- Consequences of explosion
4857 if (d_killed_by_bomb == true) {
4858 print "^The bomb detonates. A wall of force rips through the room with savage
4859 power, killing you immediately.^";
4860 if (~~d_fs_hears_bomb) {
4861 for (t=0 : (my_time<FINAL_TIME) && (~~d_paradox) : t++) {
4865 if ((~~d_paradox) && d_destroyed_prototype && d_destroyed_notes) {
4868 deadflag = SAVED_DEAD_;
4874 else if (d_injured_by_bomb) {
4875 print "^The bomb detonates. You are knocked to the floor by the force of the
4876 explosion and your ears ring. ";
4877 if (~~d_fs_hears_bomb) {
4878 print "Stunned, you lie prone on the floor as
4879 the siren wails and the reek of smoke stings your nostrils.^^
4880 Before you recover your senses, security is upon you.^";
4887 if (d_fs_killed_by_bomb) {
4889 if (d_detained || d_escaped)
4890 print "Across town, the bomb detonates.
4891 The explosion tears into your former self and she falls lifeless to
4894 print (Nearby) 0, "the explosion tears into your former self and she falls lifeless to
4896 print "^Time unravels...^";
4899 else if (d_fs_hears_bomb) {
4901 if (d_detained || d_escaped)
4902 print "Across town, the bomb detonates.
4903 Your former self is brought to her knees by the sudden blast,
4904 the horror of understanding written in her eyes.^";
4906 print (Nearby) 0, "your former self is brought to her knees by the sudden blast,
4907 the horror of understanding written in her eyes.^";
4908 print "^Time unravels...^";
4918 move player to outside;
4920 !-- result of escaping:
4924 if (my_time >= FINAL_TIME - 3) {
4925 print "The night beckons you from the open doors, but as you rush
4926 forwards to meet it your hopes fail you -- security has arrived.^";
4930 else if ((siren_start_time ~= UNKNOWN_) && (my_time - siren_start_time > siren_timeout - 2)) {
4931 print "The night beckons you from the open doors, but as you rush
4932 forwards to meet it your hopes fail you. With the siren shrieking out around you,
4933 security has arrived.^";
4938 !-- Deal with the true escapes:
4941 move player to limbo;
4943 print "You slip out into the night, darting quickly through the Cambridge
4944 shadows until you reach the quiet corner where you left your car.
4945 Exhausted, you gently start the cold motor and roll off towards the
4948 !-- Step through the rest of the time to check for paradox and/or explosion
4950 for (t=0 : (my_time<FINAL_TIME) && (~~d_paradox) : t++) {
4954 MaybeExplodeBombAfterwards();
4962 if (d_destroyed_prototype && d_destroyed_notes) {
4963 print "^Days, months, years run by.
4964 You find a new name, a new life.
4965 Fresh challenges are gladly met and life proceeds with full force in its
4966 new and welcome direction.
4967 Only now and then do you stop on a chill starry night and
4968 wonder whether you were right, what really would have happened.^";
4971 deadflag = SAVED_FREE_;
4973 else if (d_destroyed_prototype && AmHolding(notes) && challenge) {
4974 print "^Days, months, years run by.
4975 You find a new name, a new life.
4977 Eventually, you look again at your time-stained research notes
4978 and think of the possibilities.^^
4979 The inconsistencies are the key; the freed energy.
4980 Maybe now, without the shadow of military interests, you could
4981 make something of this.^";
4984 deadflag = SAVED_FREE_CHALLENGE_;
4986 else if (d_destroyed_prototype && AmHolding(notes)) {
4987 print "^Days, months, years run by.
4988 You find a new name, a new life.
4989 Fresh challenges are gladly met and life proceeds with full force in its
4990 new and welcome direction.
4991 Only now and then do you stop on a chill starry night and
4992 wonder whether you were right, what really would have happened.^";
4995 deadflag = SAVED_FREE_;
4997 else if (d_destroyed_prototype) {
4998 print "^Days run by. You find a new name, begin a new life.
4999 You hope, pray, that all you have done will stop them, that the
5000 catastrophe will not come.^";
5002 print "With your research notes at hand, the military scientists painstakingly rebuild the
5003 prototype and prepare it for testing.^";
5004 deadflag = DELAYED_;
5006 ! else if (d_destroyed_notes) {
5007 ! print "^Escape: ~d-prototype + d-notes.^";
5009 ! else if (AmHolding(notes)) {
5010 ! print "^Escape: useless explosion + holding notes.^";
5013 print "^Morning finds you in a truck-stop cafe, near Woodstock, NY. You sit there,
5014 anxiously watching the morning news as you sip your bitter coffee.^";
5017 ! else if (AmHolding(bomb) && AmHolding(notes)) {
5018 ! print "^Escape: holding bomb + notes.^";
5020 ! else if (AmHolding(bomb)) {
5021 ! print "^Escape: holding bomb.^";
5023 ! else if (AmHolding(notes)) {
5024 ! print "^Escape: holding notes.^";
5027 print "^Morning finds you in a truck-stop cafe, near Woodstock, NY. You sit there,
5028 anxiously watching the morning news as you sip your bitter coffee.^";
5031 if (~~(d_destroyed_prototype && (d_destroyed_notes || AmHolding(notes)))) {
5038 ! tests whether something has happened to stop the player continuing their actions
5041 if (d_paradox || d_caught || d_exploded || d_escaped)
5055 [Devours given_time explosion_time;
5058 if (given_time == LATER_) {
5059 if (d_destroyed_prototype) {
5060 print "Monday 1st November 2004^^";
5061 explosion_time = EXPERIMENT2_TIME;
5062 deadflag = DELAYED_;
5065 print "Wednesday 13th October 2004^^";
5066 explosion_time = EXPERIMENT1_TIME;
5067 deadflag = USELESS_;
5071 print "Tuesday 12th October 2004^^";
5072 deadflag = ACCELERATED_;
5073 explosion_time = last_travel_time;
5076 !my_time = explosion_time; ! these lines would update the status line time
5079 if (poem_interleaving) {
5080 print "At precisely ", (PrintShortTime) explosion_time, " this morning ";
5083 print "This thing all things devours: ";
5086 print "a catastrophe of unprecedented scale occurred. ";
5089 print "birds, beasts, trees, flowers; ";
5092 print "An immense explosion -- that could only have been atomic in nature -- ";
5095 print "gnaws iron, bites steel; ";
5098 print "tore through the city and suburbs of Boston MA, destroying all in its path. ";
5101 print "grinds hard stones to meal; ";
5104 print "Casualties will number in the millions and martial law has been declared. ";
5107 print "slays king, ruins town; ";
5110 print "The military is mobilizing for war with the as yet unknown enemy. ";
5113 print "and beats high mountain down. ";
5119 print "At precisely ", (PrintShortTime) explosion_time, " this morning
5120 a catastrophe of unprecedented scale occurred.
5121 An immense explosion -- that could only have been atomic in nature --
5122 tore through the city and suburbs of Boston MA, destroying all in its path.
5123 Casualties are expected to number in the millions. The President has declared
5124 a state of emergency across the nation and
5125 the military is mobilizing for a possible war with the as yet unknown enemy.^^";
5127 print "This thing all things devours:^";
5128 print "birds, beasts, trees, flowers;^";
5129 print "gnaws iron, bites steel;^";
5130 print "grinds hard stones to meal;^";
5131 print "slays king, ruins town;^";
5132 print "and beats high mountain down.^";
5148 ACCELERATED_: print "You have failed";
5149 USELESS_: print "You have failed";
5150 DELAYED_: print "You have failed";
5151 SAVED_DEAD_: print "Success, but at such a cost";
5152 SAVED_CAUGHT_: print "Success, but at such a cost";
5153 SAVED_FREE_: print "Success. Final, lasting success.";
5154 SAVED_FREE_CHALLENGE_: print "Success and, perhaps, a new hope.";
5159 if (~~(player in limbo))
5162 print "Back at the lab, ";
5166 print (string) room.lower_name;
5171 !============================================================================
5173 ! Include "../Contrib/Scenic";
5176 !============================================================================
5178 ! Standard and extended grammar
5185 !----------------------------------------------------------------------------
5188 instant_action_this_turn = true;
5189 print "^All Things Devours is a short piece of interactive fiction, leaning strongly
5190 towards the text-adventure end of the spectrum. It explores an all-too-familiar
5191 science fiction paradigm in what I hope is a rather refreshing and satisfying manner.
5192 However, due to the intrinsic nature of its subject matter, it is more cruel
5193 than one might hope for a modern piece of interactive fiction. In particular,
5194 any move you make may put things into an unwinnable state. You are therefore encouraged
5195 to save frequently, and also to realise that you will probably have to start over several times
5196 to find the most satisfactory ending.^^
5197 Hints, reviews and more can be found at http://amirrorclear.net/flowers/game/devours/^";
5202 * 'devours' -> About
5203 * 'all' 'things' 'devours' -> About
5207 instant_action_this_turn = true;
5208 print_ret "Hints and a walkthrough are located at http://amirrorclear.net/flowers/game/devours/^
5209 You might also want to try the 'about' command.^^
5210 If you are unfamiliar with text adventures, then you may want to
5211 learn the basics first at an introductory website such as
5212 http://brasslantern.org/beginners/"; ];
5214 Verb 'walkthrough' 'walkthru' 'hint' 'hints' 'help'
5218 instant_action_this_turn = true;
5219 print_ret "Written by half sick of shadows for IFComp 2004.^
5220 Beta tested by Stephen Bond.^
5221 Special thanks go to those who submitted detailed bug reports and suggestions
5222 during the competition, notably: Peter Eckersley, Oliver Nash,
5223 Hugo Thorvaldsen and Evin Robertson.^
5225 No rights are reserved by the author:
5226 this work is in the public domain and may be freely copied and modified.";
5232 [ InterleavingOnSub;
5233 instant_action_this_turn = true;
5234 poem_interleaving = true;
5235 "The ending will now be in the original, interleaved, style.";
5238 [ InterleavingOffSub;
5239 instant_action_this_turn = true;
5240 poem_interleaving = false;
5241 "The ending will now be in the standard style.";
5245 * 'on' -> InterleavingOn
5246 * 'off' -> InterleavingOff;
5248 [ ResetSub; print_ret "It is not clear what you are trying to do."; ];
5250 Verb 'reset' 'stop' 'halt' 'defuse'
5254 * noun 'in' noun -> Insert
5255 * noun 'through' noun -> Insert;
5257 [ CompleteModificationsSub;
5258 if ((real_location == deutsch_lab) || (real_location == prototype_interior))
5261 "You would need to be near the prototype to do that.";
5264 Verb 'complete' 'finish'
5265 * 'modifications' -> CompleteModifications
5266 * 'work' -> CompleteModifications
5267 * 'changes' -> CompleteModifications
5268 * 'alteration' -> CompleteModifications;
5271 if ((noun == prototype) || (noun == control_panel) || (noun == nothing)) {
5272 if ((real_location == deutsch_lab) || (real_location == prototype_interior))
5275 "You would need to be near the prototype to do that.";
5277 "It is not clear what you are trying to do.";
5280 Verb 'modify' 'change' 'alter'
5294 Extend 'switch' first
5297 [ SwingAtSub; if (second == nothing)
5298 print_ret "You swing ", (the) noun, " through the air, harmlessly.";
5299 else if (IsOfType(noun, crowbar))
5301 else if ((second == conference_window) || (second ofclass AutomaticDoor)) {
5302 print_ret (The) noun, " bounces harmlessly off the ",
5309 Extend 'swing' first
5311 * held 'at' noun -> SwingAt
5312 * held 'into' noun -> SwingAt
5313 * held 'through' noun -> SwingAt;
5316 [ AttackWithSub; if (IsOfType(second, crowbar))
5318 else if ((noun == conference_window) || (noun ofclass AutomaticDoor)) {
5319 if (second == nothing)
5320 print_ret "You are not strong enough to break ",
5321 (the) noun, " by yourself.";
5323 print_ret (The) second, " is not heavy enough to break ",
5331 * noun 'with' 'fist' -> AttackWith
5332 * noun 'with' 'foot' -> AttackWith
5333 * noun 'with' 'hand' -> AttackWith
5334 * noun 'with' held -> AttackWith;
5336 [ JumpDownSub; if (real_location == balcony)
5338 else if ((real_location == upstairs_landing) || (real_location == foyer)) {
5339 print "You hit the ground hard. Maybe you should have used the stairs.^";
5343 "There is nothing to jump down to.";
5347 * 'down' -> JumpDown;
5349 [ ClimbDownSub; if (real_location == balcony)
5351 else if ((real_location == upstairs_landing) || (real_location == foyer))
5354 "There is nothing to climb down to.";
5357 Extend 'climb' first
5358 * 'down' -> ClimbDown;
5361 if (noun has lockable) {
5362 if (noun.with_key_type == nothing)
5363 "You do not have the key.";
5364 k = GetHeld(noun.with_key_type);
5366 "You do not have the key.";
5370 "That doesn't seem to be something you can lock.";
5375 * noun -> LockSimple;
5378 [ UnlockSimpleSub k;
5379 if (noun has lockable) {
5380 if (noun.with_key_type == nothing)
5381 "You do not have the key.";
5382 k = GetHeld(noun.with_key_type);
5384 "You do not have the key.";
5388 "That doesn't seem to be something you can unlock.";
5392 Extend 'unlock' first
5393 * noun -> UnlockSimple;
5396 "You will have to be more specific about your action.";
5406 if (parent(noun) ~= p)
5407 if (noun ofclass Bomb_)
5408 if (noun.time_value == NA_)
5409 "(you may also want to set the timer)";
5414 <Insert noun second>;
5415 if (parent(noun) ~= p)
5416 if (noun ofclass Bomb_)
5417 if (noun.time_value == NA_)
5418 "(you may also want to set the timer)";
5423 <PutOn noun second>;
5424 if (parent(noun) ~= p)
5425 if (noun ofclass Bomb_)
5426 if (noun.time_value == NA_)
5427 "(you may also want to set the timer)";
5432 * noun 'in' noun -> PlantIn
5433 * noun 'on' noun -> PlantOn;
5440 instant_action_this_turn = true;
5441 "That didn't take long.";
5444 instant_action_this_turn = true;
5445 "If you could do that, you wouldn't have built the prototype.";
5447 print "Time passes.^";
5452 for (t=1 : t<noun/5 : t++)
5456 print "Indeed you pause for slightly longer than you had planned,
5457 carefully resynchronizing yourself with the
5458 five second turn increments.^";
5463 instant_action_this_turn = true;
5464 "That didn't take long.";
5466 print "Time passes.^";
5468 instant_action_this_turn = true;
5469 "If you could do that, you wouldn't have built the prototype.";
5471 for (t=1 : t<noun : t++)
5475 [ WaitUntilSub time_in_turns t;
5476 time_in_turns = noun / 5 - my_time;
5477 if (time_in_turns > FINAL_TIME - my_time)
5478 time_in_turns = FINAL_TIME - my_time + 2;
5480 if (time_in_turns == 0 && (noun%5 ==0)) {
5481 instant_action_this_turn = true;
5482 "That didn't take long.";
5484 if (time_in_turns < 0) {
5485 instant_action_this_turn = true;
5486 "If you could do that, you wouldn't have built the prototype.";
5488 print "Time passes.^";
5490 if (time_in_turns > 0)
5493 for (t=1 : t<time_in_turns : t++)
5498 print "Indeed you pause for slightly longer than you had planned,
5499 carefully resynchronizing yourself with the
5500 five second turn increments.^";
5503 [ HoursMinsSecsWordToTime hour minute second word;
5504 if (hour >= 24) return -1;
5505 if (minute >= 60) return -1;
5506 if (second >= 60) return -1;
5507 if (hour > 4) return 18000; ! this is to avoid integer overflow
5511 return (hour*60 + minute) * 60 + second;
5514 ! based on the code from the DM4.
5515 ! looks for a time in the format 2:39 or 4:17:18
5517 [ TimeOfDay first_word second_word at length colons illegal_char digits hr mn se i;
5518 first_word = NextWordStopped();
5519 if (first_word == -1)
5521 at = WordAddress(wn-1);
5522 length = WordLength(wn-1);
5523 for (i=0: i<length: i++) {
5525 ':': if (colons == 0 && digits>0 && i<length-1) {
5529 else if (colons == 1 && digits==2 && i<length-1) {
5534 illegal_char = true;
5535 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
5538 illegal_char = true;
5539 default: illegal_char = true;
5542 if (length < 3 || length > 8 || illegal_char || colons == 0)
5544 for (i=0: at->i~=':': i++, hr=hr*10)
5545 hr = hr + at->i - '0';
5547 mn = ((at->(i+1) - '0') * 10) + at->(i+2) - '0';
5550 se = ((at->(i+1) - '0') * 10) + at->(i+2) - '0';
5552 second_word = NextWordStopped();
5553 parsed_number = HoursMinsSecsWordToTime(hr, mn, se, second_word);
5554 if (parsed_number == -1) return GPR_FAIL; if (second_word ~= 'pm' or 'am') wn--;
5559 * number -> WaitSeconds
5560 * number 'seconds' -> WaitSeconds
5561 * number 'second' -> WaitSeconds
5562 * number 'turns' -> WaitTurns
5563 * number 'turn' -> WaitTurns
5564 * 'until' TimeOfDay -> WaitUntil;
5568 print "You shout loudly.^";
5569 for (t=0 : t<time_travelled : t++) {
5570 if ((former_self-->t notin limbo) &&
5571 ((siren_start_time == UNKNOWN_) || (siren_start_time > my_time))) {
5576 print (Nearby) 0, "your former self hears the muffled sounds of your
5577 shouting.^^Something of an anticlimactic way to kill
5578 so many millions of people...^";
5579 print "^Time unravels...^";
5584 Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,SHOUT_);
5589 Extend only 'shout' replace
5599 * 'up' noun -> Attack;
5601 Extend 'remove' first ! so that 'remove battery' works
5602 * multiinside -> Remove;
5605 if (noun == alarm_button || noun == basement_button || noun == first_button ||
5606 noun == second_button || noun == silver_button || noun == exit_button ) {
5607 "The button is set into a vertical surface,
5608 making it impossible to hold it down with another object.";
5611 "It is not clear what that is supposed to accomplish.";
5614 Extend 'hold' first ! so that 'remove battery' works
5615 * 'down' noun -> Push
5616 * 'down' noun 'with' noun -> HoldDownWith
5617 * 'down' noun 'using' noun -> HoldDownWith;
5620 instant_action_this_turn = true;
5622 "The challenge has already been initiated.";
5625 siren_timeout = CHALLENGE_SIREN_TIMEOUT;
5626 early_guard_time = CHALLENGE_EARLY_GUARD_TIME;
5627 "The game is now in its most challenging form.
5628 Three key elements have been changed to make success considerably
5629 more difficult. This challenge is not
5630 required for a successful completion of the game. It is just here
5631 for those who, upon finishing, wish there was a little bit more.^
5633 If you do want to take up the challenge, then remember to initiate this
5634 mode each time you begin play.";
5637 "The challenge can only be initiated in the first turn.";
5641 instant_action_this_turn = true;
5643 siren_timeout = DEFAULT_SIREN_TIMEOUT;
5644 early_guard_time = EARLIEST_TIME;
5645 "The game is now at its standard difficulty.";
5651 * 'mode' 'on' -> Challenge
5652 * 'off' -> EndChallenge
5653 * 'mode' 'off' -> EndChallenge;
5655 Verb 'start' 'begin' 'initiate'
5656 * 'challenge' -> Challenge
5657 * 'challenge' 'mode' -> Challenge;
5660 * 'challenge' -> EndChallenge
5661 * 'challenge' 'mode' -> EndChallenge;
5663 !============================================================================