!% +code_path=../../Games/devours !% $MAX_STATIC_DATA=150000 !============================================================================ ! This program was written by Toby Ord (half sick of shadows) and has been ! released into the public domain, so you are legally free to be distribute ! and modify it as you see fit. So long as you do so in good faith and with good ! taste (or sufficient taste) then you have my blessing. ! ! Oh, and apologies for the messy code! It was my first program in Inform. Constant Story "All Things Devours"; Constant Headline "^Written for IFComp 2004 by half sick of shadows.^ This is the post-competition release.^ It is in the public domain and may thus be freely copied or modified.^ First-time players should type 'about'.^"; Release 3; ! post-competition release, (plus 1 bugfix) Replace DrawStatusLine; Replace ScoreSub; !============================================================================ ! Constants and Globals ! Constant DEATH_MENTION_UNDO; ! EARLIEST_TIME is a time before which no action can happen ! (can't time travel to before this time) ! start_time is when the player arrives. ! From ten seconds earlier, ! the player is outside (and can interfere with escape attempts at this time) ! <<< thus the EARLIEST_TIME must be at least ten seconds before start_time >>> ! FINAL_TIME is when the security team arrive and any attempt to stay beyond this ! will get you caught. ! the time units are 5 second blocks Global my_time; ! used instead of the_time to allow sub-minute turns ! the timeline has the player in a non-specified 'limbo' from EARLIEST_TIME to Constant EARLIEST_TIME = ((4 * 60) + 13) * 12 + 11; Constant FINAL_TIME = ((4 * 60) + 23) * 12 + 0; Global start_time = ((4 * 60) + 17) * 12 + 0; Global early_guard_time = EARLIEST_TIME; ! but this changes in the challenge mode Constant CHALLENGE_EARLY_GUARD_TIME = ((4 * 60) + 15) * 12 + 11; ! the times of the two military experiments, if allowed to happen Constant EXPERIMENT1_TIME = (( 9 * 60) + 27) * 12 + 3; Constant EXPERIMENT2_TIME = ((11 * 60) + 33) * 12 + 9; Constant GAME_LENGTH = FINAL_TIME - EARLIEST_TIME; Constant LATER_ = -1; ! A constant to represent a later time Constant DEFAULT_SIREN_TIMEOUT = 16; ! the time before the guard arrives Constant CHALLENGE_SIREN_TIMEOUT = 11; ! 1:20 vs. 0:55 Constant TIME_BEFORE_DRAGGED_OFF = 4; ! the time between arrest and removal Constant MAX_TIME_TRAVELS = 2; ! ***************** Important ******************** ! This MUST be set to be equal to 2 to the power of MAX_TIME_TRAVELS Constant MAX_ITEM_COPIES = 4; ! Constants for death states Constant ACCELERATED_ = 4; ! brought about the premature destruction of Boston Constant USELESS_ = 5; ! achieved nothing of consequence Constant DELAYED_ = 6; ! delayed the destruction by blowing up prototype Constant SAVED_DEAD_ = 7; ! saved the city but died Constant SAVED_CAUGHT_ = 8; ! saved the city but caught Constant SAVED_FREE_ = 9; ! saved the city and free Constant SAVED_FREE_CHALLENGE_ = 10; ! saved the city and free and completed the challenge ! Constants for object states Constant NA_ = -2; Constant UNKNOWN_ = -1; Constant LOCKED_ = 0; Constant CLOSED_ = 1; Constant OPEN_ = 2; ! Potentially dangerous actions: Constant NONE_ = 0; Constant LOCK_ = 1; !Constant OPEN_ = 2; Not needed since defined above Constant UNLOCK_ = 3; Constant X_CCTV_ = 4; Constant X_UPSTAIRS_CORRIDOR_ = 5; Constant X_UPSTAIRS_LANDING_ = 6; Constant X_GROUND_CORRIDOR_ = 7; Constant X_FOYER_ = 8; Constant X_BASEMENT_CORRIDOR_ = 9; Constant X_BASEMENT_LANDING_ = 10; Constant X_BALCONY_ = 11; Constant TAKE_FLASHLIGHT_ = 12; Constant BLOW_BASEMENT_LIGHT_ = 13; Constant SING_ = 14; ! these are not dangerous in the same way Constant SHOUT_ = 15; ! but need to be caught and replayed Global time_travelled; Global last_travel_time; Global d_paradox; Global d_caught; Global d_detained; Global d_escaped; Global d_exploded; Global d_killed_by_bomb; Global d_injured_by_bomb; Global d_fs_hears_bomb; Global d_fs_killed_by_bomb; Global d_destroyed_notes; Global d_destroyed_prototype; !! The moveable items (which can be taken back in time): Array bomb --> MAX_ITEM_COPIES; Array id_card --> MAX_ITEM_COPIES; Array equipment_key --> MAX_ITEM_COPIES; Array deutsch_key --> MAX_ITEM_COPIES; Array flashlight --> MAX_ITEM_COPIES; Array battery --> MAX_ITEM_COPIES; Array cable --> MAX_ITEM_COPIES; Array crowbar --> MAX_ITEM_COPIES; Array notes --> MAX_ITEM_COPIES; Array former_self --> MAX_TIME_TRAVELS; !! The locations of various things at various times !! These contain an immense amount of info: !! Location of each copy of that item at each time for each run through !! Amongst other things, this allows one to recreate the world at a given time Array player_loc --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1); Array bomb_loc --> (GAME_LENGTH + 1) * (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1); Array id_card_loc --> (GAME_LENGTH + 1) * (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1); Array equipment_key_loc --> (GAME_LENGTH + 1) * (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1); Array deutsch_key_loc --> (GAME_LENGTH + 1) * (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1); Array flashlight_loc --> (GAME_LENGTH + 1) * (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1); Array battery_loc --> (GAME_LENGTH + 1) * (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1); Array cable_loc --> (GAME_LENGTH + 1) * (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1); Array crowbar_loc --> (GAME_LENGTH + 1) * (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1); Array notes_loc --> (GAME_LENGTH + 1) * (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1); !! The states of various things at various times Global prototype_fixed_time = UNKNOWN_; Global siren_start_time = UNKNOWN_; Array flashlight_state --> (GAME_LENGTH + 1) * (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1); Array bomb_setting --> (GAME_LENGTH + 1) * (MAX_ITEM_COPIES) * (MAX_TIME_TRAVELS + 1); !! activity_target is used to distinguish which door was (dangerously) locked/unlocked/opened Array dangerous_activity --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1); Array activity_target --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1); Array siren_state --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1); Array panel_setting --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1); Array ground_equipment_light --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1); Array basement_equipment_light --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1); Array main_doors_state --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1); Array basement_door_state --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1); Array ground_door_state --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1); Array upstairs_door_state --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1); Array balcony_door_state --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1); Array conference_window_state --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1); Array deutsch_door_state --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1); Array basement_equipment_door_state --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1); Array ground_equipment_door_state --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1); Array main_doors_smashed --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1); Array basement_door_smashed --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1); Array ground_door_smashed --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1); Array upstairs_door_smashed --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1); Array balcony_door_smashed --> (GAME_LENGTH + 1) * (MAX_TIME_TRAVELS + 1); Global poem_interleaving = false; Global initialising = true; Global first_turn = true; Global challenge = false; Global siren_timeout = DEFAULT_SIREN_TIMEOUT; Global instant_action_this_turn = false; Global warned_of_jump = false; Global id_card_used = false; Global have_looked_at_bench = false; Global prototype_seen = false; !============================================================================ Include "Parser"; Object LibraryMessages with before [; Jump: if (real_location == balcony) { Jumped(); return true; } "You jump on the spot, fruitlessly."; Listen: if ((siren_start_time ~= UNKNOWN_) && (siren_start_time < my_time)) return true; else if (Get2D(dangerous_activity, time_travelled-1, my_time-EARLIEST_TIME) == SHOUT_) return true; else if (Get2D(dangerous_activity, time_travelled-1, my_time-EARLIEST_TIME) == SING_) return true; else "You can hear nothing but a soft electric hum."; Burn: "You have no source of flame."; Sing: "You sing out a few clear notes."; Miscellany: if (lm_n == 44) "It is not clear what you are trying to refer to with 'all'."; ]; Include "VerbLib"; !============================================================================ ! Object classes Class Room with before [t; Inv, Look: if (initialising) { initialising = false; return false; } instant_action_this_turn = true; return false; Sing: for (t=0 : tt notin limbo) && ((siren_start_time == UNKNOWN_) || (siren_start_time > my_time))) { print "You sing out a few clear notes.^"; d_paradox = true; deadflag = 3; Seperator(); print (Nearby) 0, "your former self hears the muffled sounds of your singing.^^Something of an anticlimactic way to kill so many millions of people...^"; print "^Time unravels...^"; Devours(my_time); return true; } } Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,SING_); return false; ], each_turn [t i; first_turn = false; if (instant_action_this_turn) { instant_action_this_turn = false; return true; } MoveFloatingObjects(); my_time++; if (time_travelled > 0) { for(i=0 : i < Exp(2,time_travelled-1) : i++) { MoveObject(bomb, bomb_loc, i); MoveObject(id_card, id_card_loc, i); MoveObject(equipment_key, equipment_key_loc, i); MoveObject(deutsch_key, deutsch_key_loc, i); MoveObject(flashlight, flashlight_loc, i); MoveObject(battery, battery_loc, i); MoveObject(cable, cable_loc, i); MoveObject(crowbar, crowbar_loc, i); MoveObject(notes, notes_loc, i); } if (my_time == prototype_fixed_time) prototype.fixed = true; MaybeSetBombs(); MaybeSetFlashlights(); MaybeSetPanel(panel_setting); MaybeSetBasementLight(basement_equipment_light); MaybeSetGroundLight(ground_equipment_light); MaybeSetAutomaticDoor(main_doors, main_doors_state); MaybeSetAutomaticDoor(basement_door, basement_door_state); MaybeSetAutomaticDoor(ground_door, ground_door_state); MaybeSetAutomaticDoor(upstairs_door, upstairs_door_state); MaybeBreakDoor(main_doors, main_doors_smashed); MaybeBreakDoor(basement_door, basement_door_smashed); MaybeBreakDoor(ground_door, ground_door_smashed); MaybeBreakDoor(upstairs_door, upstairs_door_smashed); MaybeBreakDoor(balcony_door, balcony_door_smashed); MaybeSing(); MaybeShout(); !-- from here down paradox may occur and we need to be able to stop if one occurs if (~~d_paradox)... for(t=0 : t < time_travelled : t++) MoveFormerSelf(t); MaybeSetManualDoor(balcony_door, balcony_door_state); MaybeSetManualDoor(conference_window, conference_window_state); MaybeSetManualDoor(deutsch_door, deutsch_door_state); MaybeSetManualDoor(basement_equipment_door, basement_equipment_door_state); MaybeSetManualDoor(ground_equipment_door, ground_equipment_door_state); } MaybeCloseAutomaticDoor(main_doors); MaybeCloseAutomaticDoor(basement_door); MaybeCloseAutomaticDoor(ground_door); MaybeCloseAutomaticDoor(upstairs_door); ObserveLocations(); ObserveBombs(); ObserveFlashlights(); ObserveSiren(); ObservePanel(); ObserveBasementLight(basement_equipment_light); ObserveGroundLight(ground_equipment_light); ObserveAutomaticDoor(main_doors, main_doors_state); ObserveAutomaticDoor(basement_door, basement_door_state); ObserveAutomaticDoor(ground_door, ground_door_state); ObserveAutomaticDoor(upstairs_door, upstairs_door_state); ObserveManualDoor(balcony_door, balcony_door_state); ObserveManualDoor(conference_window, conference_window_state); ObserveManualDoor(deutsch_door, deutsch_door_state); ObserveManualDoor(basement_equipment_door, basement_equipment_door_state); ObserveManualDoor(ground_equipment_door, ground_equipment_door_state); ObserveBrokenDoor(main_doors, main_doors_smashed); ObserveBrokenDoor(basement_door, basement_door_smashed); ObserveBrokenDoor(ground_door, ground_door_smashed); ObserveBrokenDoor(upstairs_door, upstairs_door_smashed); ObserveBrokenDoor(balcony_door, balcony_door_smashed); CheckPassiveParadox(); CheckActiveParadox(); if (~~(Stopped())) { if (siren_start_time ~= UNKNOWN_) { if (my_time - siren_start_time == 1) print "^A piercing siren rings out.^"; if (my_time - siren_start_time > 1) { if (my_time - siren_start_time <= siren_timeout) print "^The siren wails.^"; else CaughtInside(); } } if ((my_time > FINAL_TIME) && (~~Stopped())) CaughtInside(); } if (main_doors.just_closed) main_doors.closing_message(); if (basement_door.just_closed) basement_door.closing_message(); if (ground_door.just_closed) ground_door.closing_message(); if (upstairs_door.just_closed) upstairs_door.closing_message(); MaybeExplodeBombs(); ], has light; Class Sight with before [; Examine: return false; Listen: return false; default: print_ret "You cannot do that from here."; ], has scenery concealed static; Class PluralSight with before [; Examine: return false; default: print_ret "You cannot do that to all of ", (the) self, " at once."; ], has scenery concealed static; Class Prop with before [; Examine: return false; default: print_ret "You don't need to worry about ", (the) self, "."; ], has scenery concealed static; Class Furniture with before [; Take,Pull,Push,PushDir: print_ret (The) self, " is too heavy for that."; ], has static supporter; Class AutomaticDoor with before [; Take,Pull,Push,PushDir: print_ret (The) self, " is locked in place."; Lock: Close: "Like most automatic doors, this one closes of its own accord."; Attack: if (AmHolding(crowbar)) { print "You swing the crowbar firmly into the door. It shudders, a star of cracks reaching out from the point of impact, but the glass stays in place.^"; self.smashed = true; StartSiren(); return true; } else "You don't have anything heavy enough to smash the door with."; Search: <>; ], just_closed false, smashed false, to_close_at UNKNOWN_, open_self [t; if (self hasnt open) { give self open ~locked; if (self in LocationOf(player)) print "The door slides open with a soft rattle.^"; } self.to_close_at = t; ], close_self [; give self ~open locked; self.to_close_at = UNKNOWN_; self.just_closed = true; ], closing_message [; if ((~~Stopped()) && (self in LocationOf(player))) "The automatic door softly slides closed."; ], has static door openable locked; Class ManualDoor with name 'door' 'to' 'the', before [; Take,PushDir: print_ret (The) self, " is locked in place."; Attack: if (AmHolding(crowbar)) { print "You swing the crowbar firmly into the door, but it barely leaves a mark.^"; return true; } else "You don't have anything heavy enough to break the door with."; ], react_before [; Go: if (noun.door_dir() == self.door_dir()) return self.open_by_myself(); if (noun.door_dir() == out_to) !! XX hack, going 'out' always uses door in this game return self.open_by_myself(); Enter: if (noun == self) return self.open_by_myself(); ], open_by_myself [ ks; if (self has open) rfalse; print "(first opening ", (the) self, ")^"; ks = keep_silent; keep_silent = true; ; keep_silent = ks; if (self hasnt open) rtrue; else { IncTime(); if (Stopped()) return true; } ], has static door openable lockable; [LockUnlockParadox; d_paradox = true; deadflag = 3; Seperator(); print "On the other side of the door, your former self hears you turn the key in the lock.^"; print "^Time unravels...^"; Devours(my_time); ]; [OpenParadox; d_paradox = true; deadflag = 3; Seperator(); print "On the other side, your former self sees the door open in front of her.^"; print "^Time unravels...^"; Devours(my_time); ]; [CloseParadox; d_paradox = true; deadflag = 3; Seperator(); print "On the other side, your former self sees the door close in front of her.^"; print "^Time unravels...^"; Devours(my_time); ]; [OpenManualDoor door ks; if (door has locked) { if (door.with_key_type == nothing || ~~AmHolding(door.with_key_type)) "Try as you might, none of your keys will unlock the door."; print "(first unlocking ", (the) door, ")^"; ks = keep_silent; keep_silent = true; ; keep_silent = ks; if (door has locked) return true; else { IncTime(); if (Stopped()) return true; } } Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,OPEN_); Put2D(activity_target,time_travelled,my_time-EARLIEST_TIME,door); return false; ]; [UnlockManualDoor door key; Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,UNLOCK_); Put2D(activity_target,time_travelled,my_time-EARLIEST_TIME,door); if (door has locked) { if ( IsOfType(key,door.with_key_type) ) { give door ~locked; if (~~keep_silent) print (The) key, " turns smoothly in the lock.^"; return true; } else "It does not fit in the lock."; } return false; ]; [LockManualDoor door key ks; if (door has open) { print "(first closing ", (the) door, ")^"; ks = keep_silent; keep_silent = true; ; keep_silent = ks; if (door has open) rtrue; IncTime(); if (Stopped()) return true; } Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,LOCK_); Put2D(activity_target,time_travelled,my_time-EARLIEST_TIME,door); if (door hasnt locked) { if ( IsOfType(key,door.with_key_type) ) { give door locked; if (~~keep_silent) print (The) key, " turns smoothly in the lock.^"; return true; } else "It does not fit in the lock."; } return false; ]; Class FakeDoor with name 'door' 'to' 'the', before [; Take,PushDir: print_ret (The) self, " is locked in place."; Unlock: if (IsOfType(second,crowbar)) <>; Attack: if (AmHolding(crowbar)) { print "You swing the crowbar firmly into the door, but it barely leaves a mark.^"; return true; } else "You don't have anything heavy enough to break the door with."; Enter: "The door is locked."; ], door_to nothing, door_dir nothing, with_key_type nothing, has static door openable lockable locked; !============================================================================ ! the moveable objects (defined as classes) ! with trailing _ to avoid ambiguity with individual item names Class Bomb_(MAX_ITEM_COPIES) with short_name "timed explosive device", plural "timed explosive devices", description [t i; print "A length of steel pipe filled with powder and fused with a digital timer. Not your most elegant piece of work, but it will hopefully do the job.^"; t = (self.time_value - my_time) * 5 + self.left_over_seconds; if (self.time_value == NA_) print "^You have not yet set the timer.^"; else { if (t == -4) print "^On the timer's small LED screen, the number 0 blinks out at you.^"; else { print "^On the timer's small LED screen, the numbers "; for (i = t+4 : (i>t) && (i>0) : i--) print i, ", "; if (t < 0) print 0; else print t; print "... blink out at you insistently, illuminating the room with faint blue-green flashes.^"; } } ], name 'time' 'timed' 'explosive' 'device' 'bomb' 'timebomb' 'C4' 'timer' 'digital' 'pipe' 'devices//p' 'bombs//p' 'timebombs//p' 'timers//p', time_value NA_, left_over_seconds 0, before [; Set: print "To set the explosive device, you need to specify a number of seconds, for example, with 'set timer to 30'.^"; return true; SetTo: if (self.time_value ~= NA_) { print "(first resetting the timer)^"; self.time_value = NA_; } if (second > 0 && second <= 100) { self.time_value = my_time + (second/5); self.left_over_seconds = second%5; print "Time until detonation: ", (self.time_value - my_time) * 5 + self.left_over_seconds; print " seconds.^"; if (parent(self) == player) print "(you probably don't want to be carrying the device when that occurs...)^"; } else { print "Your timer only accepts between 1 and 100 seconds.^"; } return true; Reset: if (self.time_value ~= NA_) { self.time_value = NA_; "You reset the timer."; } else "The timer is not currently set."; ], has ; Class IDCard_(MAX_ITEM_COPIES) with short_name "ID card", plural "ID cards", description "Natalie Williams.^ Deutsch Lab.^ Doctoral Student, MIT^ ^ On the right is a familiar photo of you, back when you wore your hair long. A black magnetic stripe runs the width of the reverse.", name 'id' 'card' 'cards', before[; Insert: if (second == id_slot){ if (second in foyer or upstairs_landing) { "The slot emits a small beep and your card is rejected."; } if (second in basement_landing) { if (~~id_card_used) { print "You swipe your card through the slot, and hold your breath.^"; basement_door.open_self(my_time+1); print "Perfect. Just as you'd hoped. The bastards hadn't even thought to disable your card.^"; id_card_used = true; } else basement_door.open_self(my_time+1); return true; } } if (second == ground_door or upstairs_door && player in foyer or upstairs_landing) { "The slot emits a small beep and your card is rejected."; } if ((second == basement_door) && (player in basement_landing)) { basement_door.open_self(my_time+1); return true; } ], has ; Class Crowbar_(MAX_ITEM_COPIES) with short_name "crowbar", plural "crowbars", name 'crow' 'bar' 'crowbar' 'black' 'crowbars//p' 'bars//p', description "A curved black crowbar.", has; Class Flashlight_(MAX_ITEM_COPIES) with short_name "flashlight", plural "flashlights", name 'flashlight' 'torch' 'flashlights//p' 'torches//p' 'flash' 'metallic' 'blue' 'metallic-blue', description "A small metallic-blue flashlight.", capacity 2, before [; SwitchOn: if (self has on) "That's already on."; if (BatteriesContained(self) == 2) { give self on; if (real_location == basement_equipment || (real_location == ground_equipment && ground_equipment.lit == false)) { ; instant_action_this_turn = false; return true; } else "A thin beam of icy light shines forth."; } if (BatteriesContained(self) == 1) { "The switch clicks, but no light is forthcoming. It looks as if you will need two batteries."; } if (BatteriesContained(self) == 0) { "The switch clicks, but no light is forthcoming. Not surprising considering flashlights usually need batteries."; } SwitchOff: if (player in basement_equipment) MoveMoveableChildren(basement_equipment,basement_equipment_gloom); else if ((player in ground_equipment) && (ground_light_switch hasnt on)) MoveMoveableChildren(ground_equipment,ground_equipment_gloom); Receive: if (~~IsOfType(noun,battery)) print_ret (The) noun, " won't fit in the flashlight."; Take: Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,TAKE_FLASHLIGHT_); return false; ], after [; LetGo: if (self has on) { print "As you remove the battery, the light fails.^"; give self ~on; if (player in basement_equipment) MoveMoveableChildren(basement_equipment,basement_equipment_gloom); else if ((player in ground_equipment) && (ground_light_switch hasnt on)) MoveMoveableChildren(ground_equipment,ground_equipment_gloom); return false; } ], has container open switchable; Class Battery_(MAX_ITEM_COPIES) with short_name "battery", plural "batteries", name 'battery' 'batteries//p' 'AA', description "An AA sized battery.", before [; Remove: <>; ], has; Class Cable_(MAX_ITEM_COPIES) with short_name "length of ribbon cable", plural "lengths of ribbon cable", name 'cable' 'wire' 'cables//p' 'wires//p' 'ribbon' 'length' 'lengths//p' 'of', description "A 10cm length of ribbon cable. It will do nicely.", before[; Tie: if (second == control_panel or prototype) <>; if (second == nothing) if (real_location == deutsch_lab or prototype_interior) <>; else "There is nothing here that you could attach the cable to."; else "You cannot attach the cable to that."; ], has; Class Notes_(MAX_ITEM_COPIES) with short_name "collection of notes", plural "collections of notes", name 'collection' 'notes' 'collections//p', description "Your research notes. The hundred or so pages here comprise everything you have written so far. It would not be easy for someone else to turn the scribbles herein into another working prototype, but it may just be possible.", before[; Eat: "You look determinedly at the thick bundle of papers, but there is no way that you could eat more than a couple of pages. You had better think of something a little more sensible."; Attack, Cut: "There are about a hundred pages and there is no way that you could tear them up in time."; ], has; Class EquipmentKey_(MAX_ITEM_COPIES) with short_name "worn brass key", plural "worn brass keys", name 'key' 'equipment' 'brass' 'worn' 'keys//p', description "A well worn brass key. It opens the various equipment rooms in the complex.", has; Class DeutschKey_(MAX_ITEM_COPIES) with short_name "bright steel key", plural "bright steel keys", name 'key' 'deutsch' 'steel' 'bright' 'keys//p', description "A bright steel key. It unlocks the door to the Deutsch lab, downstairs.", has; Class FormerSelf_(MAX_ITEM_COPIES) with short_name "your former self", plural "your former selves", name 'self' 'former' 'past' 'selves//p', description "She looks strangely familiar.", has animate proper container concealed; !=============================================================================== ! The one-of-a-kind moveable objects Object myselfobj "(self object)" with short_name "yourself", description "Dark hair frames a warm face. Despite the anxiety written now in your tense brow, the confidence of youth and vibrancy of intellect are clear. There is a depth in your clear green eyes.", capacity 100, number 0, orders 0, weakness 0, has concealed animate proper transparent; Object skeleton_key "skeleton key (fake item to neaten code)" with name 'key' 'skeleton', description "A skeleton key. And I thought they were make-believe!", has; !=============================================================================== ! The rooms !----------------------------------------------- ! Generic props and sights: Prop walls "walls" with name 'wall' 'walls', found_in [; if (location ~= prototype_interior) return true; else return false; ], has ; Prop floor "floor" with name 'floor' 'ground' 'carpet', description "The floor is covered by a thin carpet in a dark but warm gray.", found_in [; if ((location ~= balcony) && (location ~= prototype_interior)) return true; else return false; ], has ; Prop ceiling "ceiling" with name 'ceiling', found_in [; if (location ~= prototype_interior) return true; else return false; ], has ; Sight darkness "darkness" with name 'darkness' 'dark' 'gloom', description "You cannot see what lies in the darkness.", before [; Examine: Listen: return false; default: "It is not clear what you mean."; ], found_in [; return true; ], has ; Sight shadows "shadows" with name 'shadows' 'shadow' 'corners' 'cobwebs', description "Shadows fill the corners of the rooms like old cobwebs.", before [; Examine: Listen: return false; default: "It is not clear what you mean."; ], found_in [; return true; ], has ; Sight complex "complex" with name 'complex' 'building' 'surface' 'surfaces' 'texture' 'textures', description "The building has modern but ultimately shallow feel. There is a preoccupation with surfaces and textures. Almost everything is coloured with dark, yet somewhat warm, shades of gray, darkened further by the midnight gloom.", before [; Examine: Listen: return false; default: "It is not clear what you mean."; ], found_in [; return true; ], has ; Prop lights "lights" with name 'lights' 'light' 'fluorescent', description "Most of the overhead lights are currently off, leaving the complex in dim half-light.", before [; SwitchOn: "Switching on the overhead lights would alert security to your presence, and besides, you can see clearly enough in the gloom."; ], found_in [; if ((location ~= balcony) && (location ~= prototype_interior) && (location ~= basement_equipment) && (location ~= ground_equipment)) return true; else return false; ], has ; Prop stairs "stairs" with name 'stairs' 'staircase', before [; Climb: if (self in foyer or basement_landing) <>; if (self in upstairs_landing) "You are already at the top of the stairs."; ], found_in basement_landing foyer upstairs_landing, has ; !----------------------------------------------- ! Item-related props and sights: Prop beam "flashlight beam" with name 'beam' 'blue-white' 'blue' 'white', description "A thin icy beam that cuts through the darkness.", found_in [; if (Flashlit()) return true; else return false; ], has ; Prop photo "photograph" with name 'photo' 'photograph' 'long' 'hair', description "You look young, bright and proud of your new position at the lab.", found_in [; if (AmHolding(id_card) || IsIn(id_card,real_location)) return true; else return false; ], has ; Prop stripe "magnetic stripe" with name 'stripe' 'magnetic' 'reverse' 'back', description "It is the type of magnetic stripe found on the back of a regular credit card, but is used to open the automatic doors in the building.", found_in [; if (AmHolding(id_card) || IsIn(id_card,real_location)) return true; else return false; ], has ; !----------------------------------------------- Room foyer "Foyer" with name 'foyer', description "A darkened foyer, presided over by a security desk near the north wall. Floating above it in the capacious darkness is a small landing. A set of stairs both rises up to meet it and stretches downwards into the dark.", u_to upstairs_landing, d_to basement_landing, n_to ground_door, s_to main_doors, cant_go "The only exits are the automatic doors to the north and south, and the staircases up and down.", lower_name "the foyer", has ; Furniture security_desk "security desk" foyer with description "A large black desk equipped with four CCTV screens showing live feeds from around the complex. ", before [; Examine: print "A large black desk equipped with four CCTV screens showing live feeds from around the complex. "; cctv_screens.display(); print "There are also four buttons, labeled 'basement', 'first', 'second' and 'alarm'.^"; return true; ], name 'desk' 'security' 'black' 'table', has scenery; Object cctv_screens "CCTV images" foyer with description [; print "These screens flash images from the corridors and grounds of the complex. "; self.display(); print "^"; ], name 'images' 'CCTV' 'screen' 'screens' 'feed' 'feeds' 'image', display [; Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_CCTV_); if ((my_time == start_time - 1) || (my_time == start_time - 2)) print "On one of the screens you see your former self approaching the complex. "; if (IsIn(former_self,ground_corridor)) print "On one of the screens you see your former self in the first floor corridor. "; if (IsIn(former_self,upstairs_corridor)) print "On one of the screens you see your former self in the second floor corridor. "; if (IsIn(former_self,basement_corridor)) print "On one of the screens you see your former self in the basement corridor. "; ], has scenery concealed; Object alarm_button "alarm button" foyer with description "A discrete black button carefully labeled 'alarm'.", name 'alarm' '^alarm^' 'button' 'black' 'labeled' 'marked', before [; Push: StartSiren(); return true; Receive: "The button is set into a vertical surface, making it impossible to place objects on top of it."; ], has scenery concealed; Object first_button "'first' button" foyer with description "A small black button carefully labeled 'first'.", name 'first' '^first^' 'floor' 'button' 'black' 'labeled' 'marked', before [; Push: ground_door.open_self(my_time+1); ground_door.known_exterior_opening = true; return true; Receive: "The button is set into a vertical surface, making it impossible to place objects on top of it."; ], has scenery concealed; Object basement_button "'basement' button" foyer with description "A small black button carefully labeled 'basement'.", name 'basement' '^basement^' 'floor' 'button' 'black' 'labeled' 'marked', before [; Push: basement_door.open_self(my_time+1); "Nothing obvious happens."; Receive: "The button is set into a vertical surface, making it impossible to place objects on top of it."; ], has scenery concealed; Object second_button "'second' button" foyer with description "A small black button carefully labeled 'second'.", name 'second' '^second^' 'floor' 'button' 'black' 'labeled' 'marked', before [; Push: upstairs_door.open_self(my_time+1); "Nothing obvious happens."; Receive: "The button is set into a vertical surface, making it impossible to place objects on top of it."; ], has scenery concealed; Sight upstairs_landing_from_foyer "upstairs landing" foyer with description "The landing above is lost in shadow.", name 'upstairs' 'landing', has ; Sight outside_from_foyer "outside" foyer with description "The grounds are empty and still on this frosty night.", name 'grounds' 'outside' 'night', has ; Sight ground_corridor_from_foyer "corridor" foyer with description [;<>;], name 'corridor', has ; !----------------------------------------------- Room basement_landing "Basement Landing" with name 'landing', description "A cramped space at the bottom of the stairs. A corridor can be seen to the north through the automatic door, and the stairs lead back up to the foyer.", u_to foyer, n_to basement_door, cant_go "The only exits are north and up.", lower_name "the basement landing", has ; Sight foyer_from_basement_landing "foyer" basement_landing with description "You cannot see the foyer properly from here.", name 'foyer' 'upstairs', has ; !----------------------------------------------- Room upstairs_landing "Upstairs Landing" with name 'landing', description "A small landing, hanging in the still darkness above the foyer.", d_to foyer, n_to upstairs_door, cant_go "The only exits are north and down.", lower_name "the upstairs landing", has ; Sight foyer_from_upstairs_landing "Foyer" upstairs_landing with description [; Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_FOYER_); if (IsIn(former_self,foyer)) { "From the shadowy landing, you can just make out your former self alone in the foyer."; } else "From the shadowy landing, you can see much of the empty foyer stretching out below you."; ], name 'foyer', has ; !----------------------------------------------- Room ground_corridor "First Floor Corridor" with name 'first' 'floor' 'ground' 'corridor', description [; print "A long north-south corridor, much the same as those on the other floors. "; print "Three gray doors line the eastern wall. The first two have small glass windows, peering into darkened laboratories. The third "; if (ground_equipment_door has open) print "is open onto an equipment room.^"; else print "is plain and leads to a small equipment room. All three are closed.^"; ], s_to ground_door, se_to saunders_door, e_to pooley_door, ne_to ground_equipment_door, cant_go "The only exits are the three doors lining the corridor (south-east, east and north-east) and the automatic door back to the foyer (south).", lower_name "the first floor corridor", has ; FakeDoor saunders_door "door to the Saunders Lab" ground_corridor with name 'door' 'grey' 'gray' 'saunders' 'first' 'lab' 'se' 'south-east', description "A gray door with a small glass window, looking into a darkened lab. A small plaque reads: 'Saunders Lab'.", has locked scenery; FakeDoor pooley_door "door to the Pooley Lab" ground_corridor with name 'door' 'grey' 'gray' 'pooley' 'second' 'lab' 'e\\' 'east', description "A gray door with a small glass window, looking into a darkened lab. A small plaque reads: 'Pooley Lab'.", has locked scenery; Prop door_window "small glass window" with name 'small' 'glass' 'window' 'windows', description "You can't see anything of interest through the glass.", before [; Take,PushDir: print_ret (The) self, " is fixed in the door."; Unlock: if (IsOfType(second,crowbar)) <>; else "The embedded window does not open."; Open: "The embedded window does not open."; Attack: if (AmHolding(crowbar)) { print "You swing the crowbar firmly into the small window, but it barely leaves a mark.^"; return true; } else "You don't have anything heavy enough to break the window with."; Search: <>; ], found_in ground_corridor basement_corridor, has scenery concealed lockable; PluralSight doors_in_ground_corridor "doors" ground_corridor with name 'doors', description [; print "There are three doors on the eastern wall of the corridor, the first two (to the south-east and east) lead to the Saunders and Pooley labs. The third (to the north-east) "; if (ground_equipment_door has open) print "is open and "; print "leads to a small equipment room. To the south, the plate glass automatic door to the foyer "; if (ground_door has open) print "lies open.^"; else print "stands closed.^"; ], has pluralname; !----------------------------------------------- Room basement_corridor "Basement Corridor" with name 'basement' 'corridor', description [; print "A long north-south corridor, much the same as those on the other floors. "; print "Three gray doors line the eastern wall. The first two have small glass windows, peering into darkened laboratories. The third "; if (basement_equipment_door has open) print "is open onto an equipment room.^^"; else print "is plain and leads to a small equipment room. All three are closed.^^"; if (deutsch_door has open) print "At the north end is an open door leading to the Deutsch lab.^"; else print "At the north end a fourth door leads to the Deutsch lab.^"; ], s_to basement_door, se_to bostrom_door, e_to wallace_door, ne_to basement_equipment_door, n_to deutsch_door, cant_go "The only exits are to the Deutsch lab (north) the three doors lining the corridor (south-east, east and north-east) and the automatic door back to the landing (south).", lower_name "the basement corridor", has ; FakeDoor bostrom_door "door to the Bostrom Lab" basement_corridor with name 'door' 'grey' 'gray' 'bostrom' 'first' 'lab' 'se' 'south-east', description "A gray door with a small glass window, looking into a darkened lab. A small plaque reads: 'Bostrom Lab'.", has locked scenery; FakeDoor wallace_door "door to the Wallace Lab" basement_corridor with name 'door' 'grey' 'gray' 'wallace' 'second' 'lab' 'e\\' 'east', description "A gray door with a small glass window, looking into a darkened lab. A small plaque reads: 'Wallace Lab'.", has locked scenery; PluralSight doors_in_basement_corridor "doors" basement_corridor with name 'doors', description [; print "There are three doors on the eastern wall of the corridor, the first two (to the south-east and east) lead to the Bostrom and Wallace labs. The third (to the north-east) "; if (basement_equipment_door has open) print "is open and "; print "leads to a small equipment room. At the north end is the "; if (deutsch_door has open) print "open "; print "door to the Deutsch lab. "; print "To the south, the plate glass automatic door to the landing "; if (basement_door has open) print "lies open.^"; else print "stands closed.^"; ], has pluralname; !----------------------------------------------- Room upstairs_corridor "Second Floor Corridor" with description "A long north-south corridor, much the same as those on the other floors. Three plain gray doors line the eastern wall.", n_to balcony_door, ne_to conference_door, e_to butterfield_door, se_to brown_door, s_to upstairs_door, cant_go "The only exits are to the balcony (north) the three doors lining the corridor (south-east, east and north-east) and the automatic door back to the landing (south).", lower_name "the second floor corridor", has ; FakeDoor brown_door "door to Dr Brown's office" upstairs_corridor with name 'door' 'grey' 'gray' 'brown' 'office' 'brown^s' 'Dr' 'first' 'se' 'south-east', description "A simple gray door. A small plaque reads: 'Dr Brown'.", has locked scenery; FakeDoor butterfield_door "door to Professor Butterfield's office" upstairs_corridor with name 'door' 'office' 'grey' 'gray' 'butterfield' 'butterfield^s' 'Prof' 'second' 'e\\' 'east', description "A simple gray door. A small plaque reads: 'Prof Butterfield'.", has locked scenery; FakeDoor conference_door "door to the conference room" upstairs_corridor with name 'door' 'grey' 'gray' 'conference' 'third' 'ne' 'north-east', description "A plain gray door. A small plaque reads: 'Conference Room'.", found_in upstairs_corridor conference_room, has locked scenery; PluralSight doors_in_upstairs_corridor "doors" upstairs_corridor with name 'doors', description [; print "There are three doors on the eastern wall of the corridor, the first two (to the south-east and east) lead to Dr Brown and Professor Butterfield's offices. The third (to the north-east) leads to the conference room. At the north end is the "; if (balcony_door has open) print "open "; print "glass door to the balcony. "; print "To the south, the plate glass automatic door to the landing "; if (upstairs_door has open) print "lies open.^"; else print "stands closed.^"; ], has pluralname; !----------------------------------------------- Room deutsch_lab "The Deutsch Laboratory" with name 'lab' 'deutsch' 'laboratory', description [; if (self hasnt visited) { print "The lab is order and chaos. By the dim blue-green light of a few swirling screen savers, you can see the cluttered benches of your colleagues, frozen in the mess of academic creativity. Frozen exactly as they were when badges were flashed, when we looked on in disbelief as they took control of the lab. Yours however, is clean. The books and papers are in neat stacks. They have been working here.^ ^ Nearby, against the north wall is the prototype, a six foot cylinder of brushed steel cladding. The door has been taken off and is nowhere to be seen. They have been working on it too. You wince at the sight.^"; if (deutsch_door has open) print "^To the south, the door to the lab lies open.^"; else print "^To the south, the door to the lab stands closed.^"; return true; } print "The lab is order and chaos. By the dim blue-green light of a few swirling screen savers, you can see the cluttered benches of your colleagues, frozen in the mess of academic creativity. Yours however, is clean. The books and papers are in neat stacks. They have been working here.^ ^ Nearby, against the north wall is the prototype, a six foot cylinder of brushed steel cladding. They have been working on it too. The door has been taken off and is nowhere to be seen.^"; if (deutsch_door has open) "^To the south, the door to the lab lies open."; else "^To the south, the door to the lab stands closed."; ], out_to deutsch_door, s_to deutsch_door, in_to prototype_interior, cant_go "The only exits are to the south and in to the prototype.", lower_name "the Deutsch laboratory", has proper; Object prototype "prototype" with description [; if (~~prototype_seen) { prototype_seen = true; print "You had built the prototype to get a strong negative result, to show that the standard model of Quantum Mechanics led to demonstrably false claims involving reverse causation. You were mistaken. One by one, your experiments showed your preliminary calculations to have been correct. When the military removed you from your project, only one aspect remained untested -- an aspect you had been loath to test before you could predict the results -- inconsistent observation.^ ^ What would happen if anomalies were observed by those in the original time-line? Your prior experiments had heavily shielded the prototype from outside interaction to avoid the very possibility. And as the calculations came out time and again, that is the only reason you are alive today. When an observer in the original time-line has an anomalous observation, the wave function of the temporally relocated object collapses and the relocation retrospectively fails, preserving chronological consistency. There is just one side effect: total transformation of the object's mass into a burst of photons -- pure energy.^ ^ You tried to tell them over and again. They assumed you were merely jealous of the takeover. Now, the night before their scheduled 'first main experiment', you have come to put an end to it all. To destroy your prototype and avoid tomorrow's nightmare.^ ^ The prototype itself is a six foot tall, four foot wide cylinder, clad with brushed steel. The frame and door were fitted with quantum shielding to prevent decoherence of the wave function, but now the door has been removed and any use of the machine is potentially disastrous.^"; } else print "The prototype is a six foot tall, four foot wide cylinder clad with brushed steel. The frame and door were fitted with quantum shielding to prevent decoherence of the wave function, but now the door has been removed and any use of the machine is potentially disastrous.^"; if (~~(self.fixed)) "^On close inspection, it appears that an attempt is in progress to move the control panel so that it can be operated from the inside. As it is, the prototype is currently not functioning, but you think you could probably complete the modification within a minute or two."; return true; ], name 'prototype' 'time' 'machine' 'six' 'foot' 'cylinder', fixed, before [t; Set: if (self.fixed) { if (self in deutsch_lab) "The prototype has been modified so that the only way to operate it is to enter it and use the internal control panel."; if (self in prototype_interior) <>; } else "You will need to complete the partial modifications to use the prototype."; SetTo: if (self.fixed) { if (self in deutsch_lab) "The prototype has been modified so that the only way to operate it is to enter it and use the internal control panel."; if (self in prototype_interior) <>; } else "You will need to complete the partial modifications to use the prototype."; SwitchOn: if (self.fixed) { if (self in deutsch_lab) "The prototype has been modified so that the only way to operate it is to enter it and use the internal control panel."; if (self in prototype_interior) { print "(pressing the silver button)^"; <>; } } else "You will need to complete the partial modifications to use the prototype."; Enter: <>; Exit: if (real_location == prototype_interior) <>; Tie: if (~~d_paradox) { if (second == nothing) { if (self.fixed) "It is already fixed."; if (AmHolding(cable)) { if (self in deutsch_lab) { print "(first entering the prototype)^"; ; IncTime(); if (Stopped()) return true; print "^"; } move GetHeld(cable) to limbo; print "You begin work completing the modifications...^"; for (t=0 : t<10 : t++) { IncTime(); if (Stopped()) return true; } self.fixed = true; prototype_fixed_time = my_time; print "After a minute or so, you are done.^"; return true; } else "After a few moments, you realise that completing the modification will require a ribbon cable to connect the components. You know the type of cable well, but don't have any in the lab right now. Still, the equipment room in the corridor should have one."; } } Attack: "It won't be enough to smash the prototype by hand as there are too many circuits buried away inside that would not be harmed. Besides, that is why you brought the bomb."; Search: if (self in deutsch_lab) { print "(first entering the prototype)^"; <>; } else <>; ], react_before[; Insert: if (~~(self.fixed)) if (IsOfType(noun,cable)) if ((second == self) || (second == control_panel)) <>; if (second == self) { if (noun == self) "It wont fit. Obviously. What were you thinking? It is a prototype chrono-transference device, not some kind of TARDIS."; if (self in deutsch_lab) { move noun to prototype_interior; print "You reach in and place ", (the) noun, " inside the prototype.^"; return true; } else <>; } ], found_in deutsch_lab prototype_interior, has scenery concealed; Furniture bench "your bench" deutsch_lab with description "Your bench has clearly been used recently, and not by you.", before [; Examine: print "Your bench has clearly been used recently, and not by you. Your books and papers are neatly piled to one side, leaving the largest expanse of bare desk you have ever seen here.^"; if (~~have_looked_at_bench) { have_looked_at_bench = true; "^You suddenly notice that your research notes are not here. You were sure they would be -- and would thus be destroyed in the blast. This is bad. Very bad."; } return true; Search: <>; ], name 'bench' 'your' 'benches' 'table' 'desk', has scenery proper; Prop books "text books" deutsch_lab with description "A few texts on Quantum Mechanics and String Theory that have served you very well.", name 'books' 'book' 'texts', has; Prop papers "papers" deutsch_lab with description [; print "A collection of photocopied journal papers that you had been reading a few weeks ago.^"; if (~~have_looked_at_bench) { have_looked_at_bench = true; "^You suddenly notice that your research notes are not here. You were sure they would be -- and would thus be destroyed in the blast. This is bad. Very bad."; } return true; ], name 'papers' 'photocopies' 'stack' 'stacks', has; Prop screen_savers "screen savers" deutsch_lab with description "Abstract, organic shapes leave glowing phosphor trails as they swirl around and through themselves.", name 'screen' 'screens' 'saver' 'savers' 'computer' 'computers' 'light' 'violet' 'green' 'blue' 'blue-green' 'swirling', has; Prop cladding "cladding" deutsch_lab with name 'cladding' 'steel' 'brushed' 'frame' 'hatch', has; Prop mess "mess" deutsch_lab with description "The usual academic mess -- open books, coffee stained mugs, sprawling papers -- frozen in time.", name 'mess' 'chaos', has; Sight control_panel_from_lab "control panel" deutsch_lab with description "You cannot see the control panel clearly from here, and would need to enter the prototype.", name 'control' 'panel', before [; Push: <>; Examine: "You cannot see the control panel clearly from here, and would need to enter the prototype."; default: "You would have to enter the prototype to do that."; ], has; !----------------------------------------------- Room prototype_interior "Inside the prototype" with description [; if (prototype.fixed) { print "The interior of the prototype is cramped and dark. On the wall you see the control panel with a small LED timer set to ", control_panel.time_value, " seconds, and a silver button. Through the open hatch you can see some of the Deutsch lab.^"; } else "The interior of the prototype is cramped and dark. On the wall you can see the half-installed control panel. Through the open hatch you can see some of the Deutsch lab."; ], name 'prototype' 'time' 'machine' 'interior', out_to deutsch_lab, lower_name "the prototype", cant_go "The only exit is out to the Deutsch lab.", has proper; Object control_panel "control panel" prototype_interior with name 'control' 'panel' 'led' 'timer' 'time' 'screen', description [; print "A brushed steel control panel with a blue LED timer, set to ", control_panel.time_value, " seconds, and a shiny silver button.^"; ], time_value, before [; Push: <>; Set: if (prototype.fixed) "To set the control panel, you need to specify a number of seconds, for example, with 'set panel to 75'."; else "You won't be able to set the control panel until you complete the modifications."; SetTo: if (prototype.fixed) { if (second > 0 && second <= 500) { self.time_value = second; "You quickly type the number in to the control panel."; } else { "The prototype's control panel only accepts between 1 and 500 seconds."; } } else "You won't be able to set the control panel until you complete the modifications."; SwitchOn: if (self.fixed) { print "(pressing the silver button)^"; <>; } else "You will need to complete the partial modifications to use the prototype."; ], has scenery concealed; Object silver_button "silver button" prototype_interior with name 'button' 'silver' 'silvered', description "A silvered button.", before [old_value t; Push: if (prototype.fixed) { if (control_panel.time_value == 0) "The control panel emits a small beep and the number '0' flashes out at you. Perhaps you should set it first."; else if (time_travelled < MAX_TIME_TRAVELS) { old_value = control_panel.time_value; TravelThroughTime(control_panel.time_value); if (deadflag) return true; for (t=0 : t < time_travelled : t++) if ((Get2D(player_loc,t,my_time-EARLIEST_TIME) == deutsch_lab) || (Get2D(player_loc,t,my_time-EARLIEST_TIME) == prototype_interior)) "You hold your breath and activate the prototype."; ! this is needed to avoid silly message below, then death if ((old_value % 5) ~= 0) "You pause for a moment after pressing the button, carefully resynchronizing yourself with the five second turn increments."; else "You hold your breath and activate the prototype."; } else "Nothing happens."; } else "The button won't work until you complete the modifications."; Receive: "The button is set into a vertical surface, making it impossible to place objects on top of it."; ], has scenery concealed; Sight deutsch_lab_from_prototype "Deutsch lab" prototype_interior with description "You can't make out much of interest from here, just a few benches under the shifting blue-violet-green light.", name 'deutsch' 'lab' 'hatch' 'bench' 'benches', has; Prop surface "inside surface" prototype_interior with name 'walls' 'interior' 'surface' 'ceiling' 'floor' 'ground', description "The interior of the prototype is clad in smooth brushed steel.", has ; !----------------------------------------------- Room basement_equipment "Basement Equipment Room" with name 'equipment' 'room', description [; if (FlashLit()) { MoveMoveableChildren(basement_equipment_gloom,self); print "By the thin blue-white beam of your flashlight, you see the crowded shelves of the equipment room.^"; if (basement_equipment_door has open) print "^To the west, the door to the corridor lies open.^"; else print "^To the west, the door to the corridor stands closed.^"; } else { MoveMoveableChildren(self,basement_equipment_gloom); if (basement_equipment_door has open) print "It is almost completely dark. Some faint light spills in from the west through the open door, allowing you to just discern the outlines of a series of shelves. By the door is a light switch.^"; else print "You are in complete darkness.^"; } ], out_to basement_equipment_door, w_to basement_equipment_door, sw_to [;<>;], cant_go "The only exit is westwards, back to the corridor.", lit false, has_been_lit false, lower_name "the basement equipment room", has ; ! A behind-the-scenes 'room' to store the items that should be hidden while the ! basement equipment room is in darkness Room basement_equipment_gloom "Dark Basement Equipment Room" with name 'equipment' 'room' 'dark', lower_name "the dark basement equipment room", has ; Object basement_light_switch "light switch" basement_equipment with name 'switch' 'light' 'lights', before [; Push: <>; SwitchOn: if (~~self.blown) { Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,BLOW_BASEMENT_LIGHT_); self.blown = true; if (FlashLit()) "The fluorescent lights flicker hopefully, strobing rapidly across the scattered equipment. Then darkness. You blink away the after-images and are left with only the faint torchlight."; else "The fluorescent lights flicker hopefully, strobing rapidly across the scattered equipment. Then darkness. Nothing but a few fleeting after-images of the cluttered room."; } else "Click. Nothing happens."; ], react_before [; Go: MoveMoveableChildren(basement_equipment,basement_equipment_gloom); ], react_after [; Drop: if (~~(FlashLit())) { move noun to basement_equipment_gloom; } Go: if (basement_equipment.lit || FlashLit()) { MoveMoveableChildren(basement_equipment_gloom,basement_equipment); } ], blown false, has static scenery concealed switchable; !----------------------------------------------- Room ground_equipment "First Floor Equipment Room" with name 'equipment' 'room', description [; if (self.lit) { MoveMoveableChildren(ground_equipment_gloom,self); print "By the flickering fluorescent lights, you see the crowded shelves of the equipment room.^"; if (ground_equipment_door has open) print "^To the west, the door to the corridor lies open.^"; else print "^To the west, the door to the corridor stands closed.^"; } else { if (FlashLit()) { MoveMoveableChildren(ground_equipment_gloom,self); print "By the thin blue-white beam of your flashlight, you see the crowded shelves of the equipment room.^"; if (ground_equipment_door has open) print "^To the west, the door to the corridor lies open.^"; else print "^To the west, the door to the corridor stands closed.^"; } else { MoveMoveableChildren(self,ground_equipment_gloom); if (ground_equipment_door has open) print "It is almost completely dark. Some faint light spills in from the west through the open door, allowing you to just discern the outlines of a series of shelves. By the door is a light switch.^"; else print "You are in complete darkness.^"; } } ], out_to ground_equipment_door, w_to ground_equipment_door, sw_to [;<>;], cant_go "The only exit is westwards, back to the corridor.", lit false, has_been_lit false, lower_name "the first floor equipment room", has ; Room ground_equipment_gloom "Dark First Floor Equipment Room" with name 'equipment' 'room' 'dark', lower_name "the dark first floor equipment room", has ; Object ground_light_switch "light switch" ground_equipment with name 'switch' 'light' 'lights', before [; Push: if (~~ground_equipment.lit) { <>; } else { <>; } SwitchOn: if (~~ground_equipment.lit) { ground_equipment.lit = true; give self on; print "The lights come on after a brief flicker.^"; ; instant_action_this_turn = false; return true; } SwitchOff: if (ground_equipment.lit) { ground_equipment.lit = false; give self ~on; if (FlashLit()) "The lights flicker briefly, then go out, leaving you in the faint torchlight."; else { MoveMoveableChildren(ground_equipment,ground_equipment_gloom); "The lights flicker briefly, then go out, leaving you in the darkness."; } } ], react_before [; Go: if (~~(ground_equipment.lit)) MoveMoveableChildren(ground_equipment,ground_equipment_gloom); ], react_after [; Drop: if (~~(ground_equipment.lit || FlashLit())) { move noun to ground_equipment_gloom; } Go: if ((ground_equipment.lit) || FlashLit()) { MoveMoveableChildren(ground_equipment_gloom,ground_equipment); } ], has static scenery concealed switchable; Prop shelves "shelves" with name 'shelf' 'shelves' 'equipment' 'series' 'outlines' 'outline' 'clutter' 'cluttered', description [; if (((parent(self)).lit) || (Flashlit())) "The shelves are filled with assorted lab equipment, but nothing of use to you now."; else "You cannot make out any of the objects on the dark shelves."; ], found_in ground_equipment basement_equipment, has ; Prop fluoro_light "fluorescent lights" with name 'fluoro' 'fluorescent' 'flicker' 'flickering' 'tube', description [; if ((parent(self)).lit) "The fluorescent tubes flicker brightly."; else "You can just make out a dark fluorescent tube in the ceiling above."; ], found_in ground_equipment basement_equipment, has ; !----------------------------------------------- Room balcony "Balcony" with name 'balcony', description "A wide balcony, looking out over the sleeping city. Below you, a lawn slopes gently away into the gloom, a few silhouetted trees marking the edge of the modest grounds. Above, the clear sky is a deep black, dusted with glinting stars.", d_to [;Jumped(); return true;], n_to [;Jumped(); return true;], s_to balcony_door, se_to conference_window, in_to conference_window, cant_go [; if (conference_window has open) "The only exits are the door back to the corridor (to the south) and the window into the conference room (to the south-east)."; else "The only exit is the door back to the corridor (to the south)."; ], lower_name "the balcony", has ; Prop balcony_floor "floor" balcony with name 'floor' 'ground' 'tiles', description "The floor is covered in white tiles.", has ; Prop railing "railing" balcony with name 'rail' 'railing' 'hand' 'handrail', has ; Sight trees "trees" balcony with name 'tree' 'trees' 'silhouette' 'silhouettes' 'cypress' 'cypresses' 'conifer' 'conifers', description "The trees are some kind of tall conifer, cypress perhaps. You have fond memories of dozing under them one afternoon last summer.", has ; Sight grounds "grounds" balcony with name 'lawn' 'slope' 'slopes' 'grounds' 'grass' 'gloom', description "The grounds are little more than a well-kept lawn and a few tall trees, but every night the security guard has to give them a brief inspection.", has ; Sight guard "guard" balcony with name 'guard' 'security' 'guards', description "There is no sign of the security guard.", has ; Sight stars "stars" with name 'stars' 'star' 'black' 'dust' 'constellations', description "The stars are a beautiful spray of glinting jewels in the blackness above.", found_in balcony conference_room, has ; Sight night "night" with name 'night' 'starry', description "Outside, it is one of the finest fall nights you can recall.", found_in balcony conference_room, has ; Sight city "city" with name 'city' 'boston' 'town' 'light' 'rooftops' 'roofs' 'skyscrapers' 'buildings' 'building', description "Before you, lie the rooftops and skyscrapers of your home town. Here and there a small yellow light glows, but for now Boston sleeps.", found_in balcony conference_room, has ; !----------------------------------------------- Room conference_room "Conference Room" with name 'conference', description "A rather slick but soulless affair. A large table of dark polished wood takes pride of place and is surrounded by a half-dozen chairs.", n_to conference_window, nw_to conference_window, out_to conference_window, w_to conference_door, cant_go "The only exits are the door to the west and the window to the north.", lower_name "the conference room", has ; Sight conference_room_sight "room" conference_room with name 'room' 'conference', description "A rather slick but soulless affair.", before [; Exit: <>; ], has ; Furniture conference_table "conference table" conference_room with description "A large round table of dark polished wood.", name 'table' 'round' 'large' 'polished' 'dark' 'wood', has scenery; Furniture chair "chair" conference_room with description "Each chair is of a rather elegant, modern design in the same dark wood as the table.", name 'chair' 'chairs' 'seat' 'seats', has scenery concealed; !----------------------------------------------- Room outside "Outside" with description "Outside the lab, the street is quiet.", n_to main_doors, lower_name "the night", has ; !----------------------------------------------- Room limbo "Night" with description "The waiting place for unrealised items.", lower_name "the night", has ; !------------------------------------------------------------------------ ! ! Door stuff ! AutomaticDoor main_doors "main doors" foyer with description [; if (self has open) print "Through the open doors, you can see the quiet grounds. On the right hand side is a green button.^"; else print "A pair of "; if (self.smashed) print "cracked "; print "plate glass sliding doors, through which you can see the quiet grounds. On the right hand side is a green button.^"; ], when_closed "To the south is a set of automatic doors leading out into the inky night.", when_open "To the south is an open set of automatic doors leading out into the inky night.", name 'doors' 'main' 'south' 'plate' 'glass' 'sliding' 'set' 'auto', door_to [;Escaped(); return true;], door_dir s_to, open_self [t; if (self hasnt open) { give self open ~locked; if (self in LocationOf(player)) print "The main doors open onto the night.^"; } self.to_close_at = t; if ((player in foyer) && (my_time < start_time-1) && (my_time >= start_time-3)) { d_paradox = true; deadflag = 3; Seperator(); print "Outside, your former self darts quickly towards the main doors. When she sees them open, she breaks her stride and lets out a shocked gasp.^"; print "^Time unravels...^"; Devours(my_time); } ], closing_message [; if ((~~Stopped()) && (self in LocationOf(player))) "The main doors softly slide closed."; ], before [; Open: print "(pressing the green exit button)^"; <>; Unlock: if (IsOfType(second,crowbar)) <>; else "You cannot open the door with that."; Enter: if (self hasnt open) { print "(first pressing the green exit button)^"; ; IncTime(); if (Stopped()) return true; <>; } ], react_before [; Go: if (noun == s_to && self hasnt open) <>; ], has pluralname; AutomaticDoor ground_door "automatic door" with description [; if (self in foyer) { Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_GROUND_CORRIDOR_); print "A "; if (self.smashed) print "cracked "; print "plate glass sliding door, through which you can see a dim corridor. "; if (IsIn(former_self,ground_corridor)) print "In the shadows stands your past self. "; print "On the right hand side is a slot for an ID card.^"; } if (self in ground_corridor) { Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_FOYER_); print "A "; if (self.smashed) print "cracked "; print "plate glass sliding door, through which you can see the darkened foyer. "; if (IsIn(former_self,foyer)) print "In the shadows stands your past self. "; print "On the right hand side is a green button.^"; } ], when_closed [; if (self in foyer) "In the north wall is a closed automatic door."; if (self in ground_corridor) "To the south is a closed automatic door, leading back to the foyer."; ], when_open [; if (self in foyer) "In the north wall is an open automatic door."; if (self in ground_corridor) "To the south is an open automatic door, leading back to the foyer."; ], name 'north' 'door' 'automatic' 'auto' 'plate' 'glass' 'sliding', door_to [; if (self in foyer) return ground_corridor; if (self in ground_corridor) return foyer; ], door_dir [; if (self in foyer) return n_to; if (self in ground_corridor) return s_to; ], before [; Unlock: if (IsOfType(second,crowbar)) <>; else if (IsOfType(second,id_card) && (self in foyer)) <>; else "You cannot open the door with that."; Open: if (self in foyer) if (self.known_exterior_opening == 0) "There is no obvious way to get the automatic door to open."; else { print "You press the button marked 'first'.^"; <>; } if (self in ground_corridor) { print "(pressing the green exit button)^"; <>; } Enter: if (self in ground_corridor && self hasnt open) { print "(first pressing the green exit button)^"; ; IncTime(); if (Stopped()) return true; <>; } if (self in foyer && self hasnt open) { if (self.known_exterior_opening == true) { print "(first pressing the button marked 'first')^"; ; IncTime(); if (Stopped()) return true; <>; } else { "There is no obvious way to get the automatic door to open."; } } ], react_before [; Go: if (noun == n_to && self in foyer && self hasnt open) <>; if (noun == s_to && self in ground_corridor && self hasnt open) <>; ], known_exterior_opening, found_in foyer ground_corridor, has ; AutomaticDoor basement_door "automatic door" with description [; if (self in basement_landing) { Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_BASEMENT_CORRIDOR_); print "A "; if (self.smashed) print "cracked "; print "plate glass sliding door, through which you can see a dim corridor. "; if (IsIn(former_self,basement_corridor)) print "In the shadows stands your past self. "; print "On the right hand side is a slot for an ID card.^"; } if (self in basement_corridor) { Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_BASEMENT_LANDING_); print "A "; if (self.smashed) print "cracked "; print "plate glass sliding door, through which you can see the small basement landing. "; if (IsIn(former_self,basement_landing)) print "In the shadows stands your past self. "; print "On the right hand side is a green button.^"; } ], name 'door' 'automatic' 'auto' 'plate' 'glass' 'sliding', when_closed [; if (self in basement_landing) "To the north is a closed automatic door."; if (self in basement_corridor) "To the south is a closed automatic door, leading back to the landing."; ], when_open [; if (self in basement_landing) "To the north is an open automatic door."; if (self in basement_corridor) "To the south is an open automatic door, leading back to the landing."; ], door_to [; if (self in basement_landing) return basement_corridor; if (self in basement_corridor) return basement_landing; ], door_dir [; if (self in basement_landing) return n_to; if (self in basement_corridor) return s_to; ], before [; Unlock: if (IsOfType(second,crowbar)) <>; else if (IsOfType(second,id_card) && (self in basement_landing)) <>; else "You cannot open the door with that."; Open: if (self in basement_landing) { if ( AmHolding(id_card) ) { print "(inserting your ID card)^"; <>; } else "You would need you ID card to do that."; } if (self in basement_corridor) { print "(pressing the green exit button)^"; <>; } Enter: if (self in basement_corridor && self hasnt open) { print "(first pressing the green exit button)^"; ; IncTime(); if (Stopped()) return true; <>; } if (self in basement_landing && self hasnt open) { if ( AmHolding(id_card) ) { print "(first inserting your ID card)^"; ; IncTime(); if (Stopped()) return true; <>; } else "You would need you ID card to do that."; } ], react_before [; Go: if (noun == n_to && self in basement_landing && self hasnt open) <>; if (noun == s_to && self in basement_corridor && self hasnt open) <>; ], known_exterior_opening, found_in basement_landing basement_corridor, has ; AutomaticDoor upstairs_door "automatic door" with description [; if (self in upstairs_landing) { Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_UPSTAIRS_CORRIDOR_); print "A "; if (self.smashed) print "cracked "; print "plate glass sliding door, through which you can see a dim corridor. "; if (IsIn(former_self,upstairs_corridor)) print "In the shadows stands your past self. "; print "On the right hand side is a slot for an ID card.^"; } if (self in upstairs_corridor) { Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_UPSTAIRS_LANDING_); print "A "; if (self.smashed) print "cracked "; print "plate glass sliding door, through which you can see the upper part of the darkened foyer. "; if (IsIn(former_self,upstairs_landing)) print "In the shadows of the landing stands your past self. "; print "On the right hand side is a green button.^"; } ], name 'door' 'automatic' 'auto' 'plate' 'glass' 'sliding', when_closed [; if (self in upstairs_landing) "On the north wall lies a closed automatic door."; if (self in upstairs_corridor) "To the south is a closed automatic door, leading back to the landing."; ], when_open [; if (self in upstairs_landing) "On the north wall lies an open automatic door."; if (self in upstairs_corridor) "To the south is an open automatic door, leading back to the landing."; ], door_to [; if (self in upstairs_landing) return upstairs_corridor; if (self in upstairs_corridor) return upstairs_landing; ], door_dir [; if (self in upstairs_landing) return n_to; if (self in upstairs_corridor) return s_to; ], before [; Unlock: if (IsOfType(second,crowbar)) <>; else if (IsOfType(second,id_card) && (self in upstairs_landing)) <>; else "You cannot open the door with that."; Open: if (self in upstairs_landing) if (AmHolding(id_card)) { print "(inserting your ID card)^"; <>; } if (self in upstairs_corridor) { print "(pressing the green exit button)^"; <>; } Enter: if (self in upstairs_corridor && self hasnt open) { print "(first pressing the green exit button)^"; ; if (self has open) { IncTime(); if (Stopped()) return true; <>; } return true; } if (self in upstairs_landing && self hasnt open) { "There is no obvious way to get the automatic door to open."; } ], react_before [; Go: if (noun == s_to && self in upstairs_corridor && self hasnt open) <>; ], found_in upstairs_landing upstairs_corridor, has ; Object exit_button "green exit button" with description "A green button beside the door.", name 'green' 'button', before [; Push: if (self in ground_corridor) { ground_door.open_self(my_time+1); } if (self in upstairs_corridor) { if (challenge) "Nothing happens -- the button must be broken."; else upstairs_door.open_self(my_time+1); } if (self in basement_corridor) { basement_door.open_self(my_time+1); } if (self in foyer) { main_doors.open_self(my_time+1); } return true; Receive: "The button is set into a vertical surface, making it impossible to place objects on top of it."; ], found_in ground_corridor upstairs_corridor basement_corridor foyer, has scenery concealed; Object id_slot "ID card slot" with description "A narrow slot to the right of the door. The doors are coded so that only those with legitimate business can use their card to gain entrance.", name 'slot', found_in foyer upstairs_landing basement_landing, has scenery concealed; ManualDoor ground_equipment_door "door to the equipment room" with name 'door' 'equipment' 'room' 'grey' 'gray' 'third' 'plain' 'ne' 'north-east', description "A simple gray door.", door_to [; if (self in ground_corridor) return ground_equipment; if (self in ground_equipment) return ground_corridor; ], door_dir [; if (self in ground_corridor) return ne_to; if (self in ground_equipment) return w_to; ], before [; Close: if (((self in ground_equipment) && IsIn(former_self,ground_corridor)) || ((self in ground_corridor) && IsIn(former_self,ground_equipment)) ) { CloseParadox(); return true; } Open: if (((self in ground_equipment) && IsIn(former_self,ground_corridor)) || ((self in ground_corridor) && IsIn(former_self,ground_equipment)) ) { OpenParadox(); return true; } else return (OpenManualDoor(self,second)); Unlock: if (IsOfType(second,crowbar)) <>; if (((self in ground_equipment) && IsIn(former_self,ground_corridor)) || ((self in ground_corridor) && IsIn(former_self,ground_equipment)) ) { LockUnlockParadox(); return true; } else return (UnlockManualDoor(self,second)); Lock: if (((self in ground_equipment) && IsIn(former_self,ground_corridor)) || ((self in ground_corridor) && IsIn(former_self,ground_equipment)) ) { LockUnlockParadox(); return true; } else return (LockManualDoor(self,second)); ], with_key_type equipment_key, found_in ground_corridor ground_equipment, has locked scenery; ManualDoor basement_equipment_door "door to the equipment room" with name 'door' 'equipment' 'room' 'grey' 'gray' 'third' 'plain' 'ne' 'north-east', description "A simple gray door.", door_to [; if (self in basement_corridor) return basement_equipment; if (self in basement_equipment) return basement_corridor; ], door_dir [; if (self in basement_corridor) return ne_to; if (self in basement_equipment) return w_to; ], before [; Close: if (((self in basement_equipment) && IsIn(former_self,basement_corridor)) || ((self in basement_corridor) && IsIn(former_self,basement_equipment)) ) { CloseParadox(); return true; } Open: if (((self in basement_equipment) && IsIn(former_self,basement_corridor)) || ((self in basement_corridor) && IsIn(former_self,basement_equipment)) ) { OpenParadox(); return true; } else return (OpenManualDoor(self,second)); Unlock: if (IsOfType(second,crowbar)) <>; if (((self in basement_equipment) && IsIn(former_self,basement_corridor)) || ((self in basement_corridor) && IsIn(former_self,basement_equipment)) ) { LockUnlockParadox(); return true; } else return (UnlockManualDoor(self,second)); Lock: if (((self in basement_equipment) && IsIn(former_self,basement_corridor)) || ((self in basement_corridor) && IsIn(former_self,basement_equipment)) ) { LockUnlockParadox(); return true; } else return (LockManualDoor(self,second)); ], with_key_type equipment_key, found_in basement_corridor basement_equipment, has locked scenery; ManualDoor deutsch_door "door to the Deutsch lab" with name 'door' 'deutsch' 'lab' 'fourth' 'north' 'n\\', description [; if (self in basement_corridor) "A gray door with a small glass window, looking into the darkened lab."; if (self in deutsch_lab) "A gray door with a small glass window, looking into the darkened corridor."; ], door_to [; if (self in basement_corridor) return deutsch_lab; if (self in deutsch_lab) return basement_corridor; ], door_dir [; if (self in basement_corridor) return n_to; if (self in deutsch_lab) return s_to; ], before [; Close: if (((self in deutsch_lab) && IsIn(former_self,basement_corridor)) || ((self in basement_corridor) && IsIn(former_self,deutsch_lab)) ) { CloseParadox(); return true; } Open: if (((self in deutsch_lab) && IsIn(former_self,basement_corridor)) || ((self in basement_corridor) && IsIn(former_self,deutsch_lab)) ) { OpenParadox(); return true; } else return (OpenManualDoor(self,second)); Unlock: if (IsOfType(second,crowbar)) <>; if (((self in deutsch_lab) && IsIn(former_self,basement_corridor)) || ((self in basement_corridor) && IsIn(former_self,deutsch_lab)) ) { LockUnlockParadox(); return true; } else return (UnlockManualDoor(self,second)); Lock: if (((self in deutsch_lab) && IsIn(former_self,basement_corridor)) || ((self in basement_corridor) && IsIn(former_self,deutsch_lab)) ) { LockUnlockParadox(); return true; } else return (LockManualDoor(self,second)); ], with_key_type deutsch_key, found_in basement_corridor deutsch_lab, has locked scenery; ManualDoor balcony_door "balcony door" with name 'door' 'balcony' 'n\\' 'north' 'glass', description [; if (self in upstairs_corridor) { Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_BALCONY_); print "A "; if (self.smashed) print "cracked "; print "glass door looking out onto the balcony. "; if (IsIn(former_self,balcony)) print "In the shadows you can see your past self.^"; else print "^"; } if (self in balcony) { Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_UPSTAIRS_CORRIDOR_); print "A "; if (self.smashed) print "cracked "; print "glass door looking into the upstairs corridor. "; if (IsIn(former_self,upstairs_corridor)) print "In the shadows you can see your past self.^"; else print "^"; } ], when_closed [; if (self in balcony) "To the south, the door to the upstairs corridor stands closed."; else "At the north end of the corridor is a closed glass door leading out to the balcony."; ], when_open [; if (self in balcony) "To the south, the door to the upstairs corridor lies open."; else "At the north end of the corridor is an open glass door leading out to the balcony."; ], door_to [; if (self in upstairs_corridor) return balcony; if (self in balcony) return upstairs_corridor; ], door_dir [; if (self in upstairs_corridor) return n_to; if (self in balcony) return s_to; ], before [; Close: if (((self in balcony) && IsIn(former_self,upstairs_corridor)) || ((self in upstairs_corridor) && IsIn(former_self,balcony)) ) { CloseParadox(); return true; } Open: if (((self in balcony) && IsIn(former_self,upstairs_corridor)) || ((self in upstairs_corridor) && IsIn(former_self,balcony)) ) { OpenParadox(); return true; } else return (OpenManualDoor(self,second)); Unlock: if (IsOfType(second,crowbar)) <>; if (((self in balcony) && IsIn(former_self,upstairs_corridor)) || ((self in upstairs_corridor) && IsIn(former_self,balcony)) ) { LockUnlockParadox(); return true; } else return (UnlockManualDoor(self,second)); Lock: if (((self in balcony) && IsIn(former_self,upstairs_corridor)) || ((self in upstairs_corridor) && IsIn(former_self,balcony)) ) { LockUnlockParadox(); return true; } else return (LockManualDoor(self,second)); Attack: if (AmHolding(crowbar)) { print "You swing the crowbar firmly into the door. It shudders, cracks reaching out from the point of impact, but the glass stays in place.^"; self.smashed = true; StartSiren(); return true; } else "You don't have anything heavy enough to smash the door with."; Search: <>; ], smashed false, with_key_type nothing, found_in upstairs_corridor balcony, has ; Object conference_window "window into the conference room" with name 'window' 'glass' 'tinted' 'remains' 'shards', description [; if (self in balcony) { if (self has open) "The remains of a plate glass window that has been smashed in with something heavy. Large shards of glass still protrude from the edges, framing the murky interior of the conference room."; else if (FlashLit()) "My God! It's full of stars."; else "A plate glass window looking into the murky interior of an conference room."; } if (self in conference_room) { Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_BALCONY_); if (self has open) print "The remains of a plate glass window that has been smashed in with something heavy. Large shards of glass still protrude from the edges, framing the starry night beyond. "; else "A plate glass window looking out into the starry night. "; if (IsIn(former_self,balcony)) print "Against the stars, you can just make out the silhouette of your past self.^"; else print "^"; } ], when_closed [; if (self in balcony) "To the south-east is a large, tinted glass window."; if (self in conference_room) "To the north is a large plate glass window, amazingly intact."; ], when_open [; if (self in balcony) "To the south-east, lie the shattered remains of a window, opening into a murky conference room."; if (self in conference_room) "To the north, lie the shattered remains of a window, open to the starry night."; ], door_to [; if (self in balcony) return conference_room; if (self in conference_room) return balcony; ], door_dir [; if (self in balcony) return se_to; if (self in conference_room) return n_to; ], before [; Open: if (second == nothing) "The window appears to be locked from the inside."; Unlock: if (IsOfType(second, crowbar)) <>; else if (second ~= nothing) "You cannot get the window open with that."; else "You cannot find the lock."; Attack: if (AmHolding(crowbar)) { if (self has open) "The window is already thoroughly broken."; give self open; print "You swing the crowbar firmly into the window and it shatters with a loud crash.^"; StartSiren(); return true; } else "You don't have anything heavy enough to smash the window with."; Search: <>; ], with_key_type nothing, found_in balcony conference_room, has static locked door lockable; !============================================================================ ! ! Functions: ! !---------------------------------------------------- ! ! Entry point functions: ! Puts the time in HH:MM:SS format on the status line [ DrawStatusLine width pos; ! @split_window 0; ! return; @split_window 1; @set_window 1; @set_cursor 1 1; style reverse; width = 0->33; pos = width-20; spaces (width); @set_cursor 1 2; PrintShortName(location); @set_cursor 1 pos; print (PrintTime) my_time; @set_cursor 1 1; style roman; @set_window 0; ]; [ ScoreSub; if (deadflag == 0) "There is no score in this game."; ]; [ ChooseObjects obj code; if (code < 2) { if (obj has scenery) return 2; ! exclude scenery from 'get all' commands if (action_to_be == ##Take && obj has static) return 2; ! exclude scenery from 'get all' commands rfalse; } if (action_to_be == ##Insert && obj in player) ! prefer to insert into held objects return 3; ! particularly important with all ! these duplicates... if (action_to_be == ##Close && (obj has openable) && (obj has open)) return 3; if (action_to_be == ##Open && (obj has openable) && (obj hasnt open)) return 3; if (action_to_be == ##Lock && (obj has lockable) && (obj hasnt locked)) return 3; if (action_to_be == ##Unlock && (obj has lockable) && (obj has locked)) return 3; if (action_to_be == ##LockSimple && (obj has lockable) && (obj hasnt locked)) return 3; if (action_to_be == ##UnlockSimple && (obj has lockable) && (obj has locked)) return 3; if (action_to_be == ##Take && obj has static) ! prefer to get non-statics return 1; if (obj hasnt scenery) ! prefer non-scenery in general return 2; return 1; ]; [ Initialise i; lookmode = 2; ! 'verbose' my_time = start_time; location = foyer; player = myselfobj; for (i=0 : i < MAX_ITEM_COPIES : i++) { bomb-->i = Bomb_.create(); id_card-->i = IDCard_.create(); equipment_key-->i = EquipmentKey_.create(); deutsch_key-->i = DeutschKey_.create(); flashlight-->i = Flashlight_.create(); battery-->i = Battery_.create(); cable-->i = Cable_.create(); crowbar-->i = Crowbar_.create(); notes-->i = Notes_.create(); } move bomb-->0 to player; move id_card-->0 to player; move deutsch_key-->0 to player; move equipment_key-->0 to deutsch_lab; move flashlight-->0 to deutsch_lab; move battery-->0 to ground_equipment_gloom; move cable-->0 to ground_equipment_gloom; move crowbar-->0 to basement_equipment_gloom; move notes-->0 to conference_table; for (i=1 : i < MAX_ITEM_COPIES : i++) { move bomb-->i to limbo; move id_card-->i to limbo; move equipment_key-->i to limbo; move deutsch_key-->i to limbo; move flashlight-->i to limbo; move battery-->i to limbo; move cable-->i to limbo; move crowbar-->i to limbo; move notes-->i to limbo; } for (i=0 : i < MAX_TIME_TRAVELS : i++) { former_self-->i = FormerSelf_.create(); move former_self-->i to limbo; } InitHistory(); "^ ^ You're in.^ ^ The plan now is simple: go to your lab, plant the bomb, and run. The prototype will be destroyed. The military will have no way to continue the experiment. No-one will die.^ ^ The guard is out securing the grounds. The building is empty. You have six minutes.^ ^ "; ]; !---------------------------------------------------- ! ! Major tasks: !! Initialises the first self's history for all items !! First wipe's the history clean with all locations as 'limbo' !! Next updates pre-start_time histories of all items and the player !! Then updates the states with the proper pasts and UNKNOWN futures [InitHistory t i s; for (t = EARLIEST_TIME : t <= FINAL_TIME : t++) { for (i=0 : i < MAX_ITEM_COPIES : i++) { Put3D(bomb_loc, 0, (t - EARLIEST_TIME), i, limbo ); Put3D(id_card_loc, 0, (t - EARLIEST_TIME), i, limbo ); Put3D(equipment_key_loc, 0, (t - EARLIEST_TIME), i, limbo ); Put3D(deutsch_key_loc, 0, (t - EARLIEST_TIME), i, limbo ); Put3D(flashlight_loc, 0, (t - EARLIEST_TIME), i, limbo ); Put3D(battery_loc, 0, (t - EARLIEST_TIME), i, limbo ); Put3D(cable_loc, 0, (t - EARLIEST_TIME), i, limbo ); Put3D(crowbar_loc, 0, (t - EARLIEST_TIME), i, limbo ); Put3D(notes_loc, 0, (t - EARLIEST_TIME), i, limbo ); Put3D(flashlight_state, 0, (t - EARLIEST_TIME), i, UNKNOWN_ ); Put3D(bomb_setting, 0, (t - EARLIEST_TIME), i, UNKNOWN_ ); } } for (t = EARLIEST_TIME : t <= start_time : t++) { Put3D(bomb_loc, 0, (t - EARLIEST_TIME), 0, parent(bomb-->0) ); Put3D(id_card_loc, 0, (t - EARLIEST_TIME), 0, parent(id_card-->0) ); Put3D(equipment_key_loc, 0, (t - EARLIEST_TIME), 0, parent(equipment_key-->0) ); Put3D(deutsch_key_loc, 0, (t - EARLIEST_TIME), 0, parent(deutsch_key-->0) ); Put3D(flashlight_loc, 0, (t - EARLIEST_TIME), 0, parent(flashlight-->0) ); Put3D(battery_loc, 0, (t - EARLIEST_TIME), 0, parent(battery-->0) ); Put3D(cable_loc, 0, (t - EARLIEST_TIME), 0, parent(cable-->0) ); Put3D(crowbar_loc, 0, (t - EARLIEST_TIME), 0, parent(crowbar-->0) ); Put3D(notes_loc, 0, (t - EARLIEST_TIME), 0, parent(notes-->0) ); } for (t = EARLIEST_TIME : t < start_time : t++) { Put2D(player_loc, 0, (t - EARLIEST_TIME), limbo); } Put2D(player_loc, 0, start_time - EARLIEST_TIME, foyer); for (t = EARLIEST_TIME : t <= start_time : t++) { for (s=0 : s < MAX_TIME_TRAVELS : s++) { Put2D(dangerous_activity, s, (t - EARLIEST_TIME), NONE_); Put2D(activity_target, s, (t - EARLIEST_TIME), nothing); Put2D(siren_state, s, (t - EARLIEST_TIME), false); Put2D(panel_setting, s, (t - EARLIEST_TIME), 0); Put2D(basement_equipment_light, s, (t - EARLIEST_TIME), false); Put2D(ground_equipment_light, s, (t - EARLIEST_TIME), false); Put2D(main_doors_state, s, (t - EARLIEST_TIME), LOCKED_); Put2D(basement_door_state, s, (t - EARLIEST_TIME), LOCKED_); Put2D(ground_door_state, s, (t - EARLIEST_TIME), LOCKED_); Put2D(upstairs_door_state, s, (t - EARLIEST_TIME), LOCKED_); Put2D(balcony_door_state, s, (t - EARLIEST_TIME), CLOSED_); Put2D(conference_window_state, s, (t - EARLIEST_TIME), LOCKED_); Put2D(deutsch_door_state, s, (t - EARLIEST_TIME), LOCKED_); Put2D(basement_equipment_door_state, s, (t - EARLIEST_TIME), LOCKED_); Put2D(ground_equipment_door_state, s, (t - EARLIEST_TIME), LOCKED_); Put2D(main_doors_smashed, s, (t - EARLIEST_TIME), false); Put2D(basement_door_smashed, s, (t - EARLIEST_TIME), false); Put2D(ground_door_smashed, s, (t - EARLIEST_TIME), false); Put2D(upstairs_door_smashed, s, (t - EARLIEST_TIME), false); Put2D(balcony_door_smashed, s, (t - EARLIEST_TIME), false); for (i=0 : i < MAX_ITEM_COPIES : i++) { Put3D(flashlight_state, 0, (t - EARLIEST_TIME), i, false ); Put3D(bomb_setting, 0, (t - EARLIEST_TIME), i, NA_ ); } } } for (t = start_time+1 : t <= FINAL_TIME : t++) { for (s=0 : s < MAX_TIME_TRAVELS : s++) { Put2D(dangerous_activity, s, (t - EARLIEST_TIME), NONE_); Put2D(activity_target, s, (t - EARLIEST_TIME), nothing); Put2D(siren_state, s, (t - EARLIEST_TIME), UNKNOWN_); Put2D(panel_setting, s, (t - EARLIEST_TIME), UNKNOWN_); Put2D(basement_equipment_light, s, (t - EARLIEST_TIME), UNKNOWN_); Put2D(ground_equipment_light, s, (t - EARLIEST_TIME), UNKNOWN_); Put2D(main_doors_state, s, (t - EARLIEST_TIME), UNKNOWN_); Put2D(basement_door_state, s, (t - EARLIEST_TIME), UNKNOWN_); Put2D(ground_door_state, s, (t - EARLIEST_TIME), UNKNOWN_); Put2D(upstairs_door_state, s, (t - EARLIEST_TIME), UNKNOWN_); Put2D(balcony_door_state, s, (t - EARLIEST_TIME), UNKNOWN_); Put2D(conference_window_state, s, (t - EARLIEST_TIME), UNKNOWN_); Put2D(deutsch_door_state, s, (t - EARLIEST_TIME), UNKNOWN_); Put2D(basement_equipment_door_state, s, (t - EARLIEST_TIME), UNKNOWN_); Put2D(ground_equipment_door_state, s, (t - EARLIEST_TIME), UNKNOWN_); Put2D(main_doors_smashed, s, (t - EARLIEST_TIME), UNKNOWN_); Put2D(basement_door_smashed, s, (t - EARLIEST_TIME), UNKNOWN_); Put2D(ground_door_smashed, s, (t - EARLIEST_TIME), UNKNOWN_); Put2D(upstairs_door_smashed, s, (t - EARLIEST_TIME), UNKNOWN_); Put2D(balcony_door_smashed, s, (t - EARLIEST_TIME), UNKNOWN_); } } ]; !! Update the time, remove the old objects that don't travel, !! create new objects, move them to the appropriate places [TravelThroughTime time_amount t s i j; last_travel_time = my_time; time_amount = time_amount / 5; ! round down to nearest five seconds if (time_amount == 0) time_amount = 1; my_time = my_time - time_amount; if (my_time < early_guard_time) { d_paradox = true; deadflag = 3; Seperator(); print (Nearby) 0, "the guard gives the inside corridors a last look before heading out. A small sound from the Deutsch lab. He turns.^"; print "^Time unravels...^"; Devours(my_time); return true; } !! replace those items the player brought with them FixBombSettings(time_amount); FixFlashlightStates(); for (j=0 : j < Exp(2,time_travelled) : j++) { ReplaceTravellingItem(bomb, j); ReplaceTravellingItem(id_card, j); ReplaceTravellingItem(equipment_key, j); ReplaceTravellingItem(deutsch_key, j); ReplaceTravellingItem(flashlight, j); ReplaceTravellingItem(cable, j); ReplaceTravellingItem(crowbar, j); ReplaceTravellingItem(notes, j); !! tricky battery issues, since they can be in flashlights !! if other items could be in containers this would hurt here too if (PlayerHas(battery-->j)) { if (battery-->j in player) move battery-->(j+Exp(2,time_travelled)) to player; else { for (i=0 : i < Exp(2,time_travelled) : i++) if (battery-->j in (flashlight-->i)) move (battery-->(j+Exp(2,time_travelled))) to (flashlight-->(i+Exp(2,time_travelled))); } } else if (LocationOf(battery-->j) == prototype_interior) { if (battery-->j in prototype_interior) move battery-->(j+Exp(2,time_travelled)) to prototype_interior; else for (i=0 : i < Exp(2,time_travelled) : i++) if (battery-->j in flashlight-->i) move battery-->(j+Exp(2,time_travelled)) to flashlight-->(i+Exp(2,time_travelled)); } } !! move all the old items and selves into limbo for (t=0 : t < Exp(2,time_travelled) : t++) { move bomb-->t to limbo; move id_card-->t to limbo; move equipment_key-->t to limbo; move deutsch_key-->t to limbo; move flashlight-->t to limbo; move battery-->t to limbo; move cable-->t to limbo; move crowbar-->t to limbo; move notes-->t to limbo; } for (t=0 : t < time_travelled : t++) move former_self-->t to limbo; !! fix up history of immediate past self so 'player' becomes appropriate former self for (s = EARLIEST_TIME : s <= FINAL_TIME : s++) { for (t=0 : t < Exp(2,time_travelled) : t++) { if (Get3D(bomb_loc, time_travelled, (s - EARLIEST_TIME), t) == player) Put3D(bomb_loc, time_travelled, (s - EARLIEST_TIME), t, former_self-->time_travelled); if (Get3D(id_card_loc, time_travelled, (s - EARLIEST_TIME), t) == player) Put3D(id_card_loc, time_travelled, (s - EARLIEST_TIME), t, former_self-->time_travelled); if (Get3D(equipment_key_loc, time_travelled, (s - EARLIEST_TIME), t) == player) Put3D(equipment_key_loc, time_travelled, (s - EARLIEST_TIME), t, former_self-->time_travelled); if (Get3D(deutsch_key_loc, time_travelled, (s - EARLIEST_TIME), t) == player) Put3D(deutsch_key_loc, time_travelled, (s - EARLIEST_TIME), t, former_self-->time_travelled); if (Get3D(flashlight_loc, time_travelled, (s - EARLIEST_TIME), t) == player) Put3D(flashlight_loc, time_travelled, (s - EARLIEST_TIME), t, former_self-->time_travelled); if (Get3D(battery_loc, time_travelled, (s - EARLIEST_TIME), t) == player) Put3D(battery_loc, time_travelled, (s - EARLIEST_TIME), t, former_self-->time_travelled); if (Get3D(cable_loc, time_travelled, (s - EARLIEST_TIME), t) == player) Put3D(cable_loc, time_travelled, (s - EARLIEST_TIME), t, former_self-->time_travelled); if (Get3D(crowbar_loc, time_travelled, (s - EARLIEST_TIME), t) == player) Put3D(crowbar_loc, time_travelled, (s - EARLIEST_TIME), t, former_self-->time_travelled); if (Get3D(notes_loc, time_travelled, (s - EARLIEST_TIME), t) == player) Put3D(notes_loc, time_travelled, (s - EARLIEST_TIME), t, former_self-->time_travelled); } } !! recreate the world as it was for most recent former self !! (ie move a lot of old items and selves back to the world) !! (fix states of doors and machine) for (i=0 : i < Exp(2,time_travelled) : i++) { move bomb-->i to Get3D(bomb_loc,time_travelled,my_time-EARLIEST_TIME,i); move id_card-->i to Get3D(id_card_loc,time_travelled,my_time-EARLIEST_TIME,i); move equipment_key-->i to Get3D(equipment_key_loc,time_travelled,my_time-EARLIEST_TIME,i); move deutsch_key-->i to Get3D(deutsch_key_loc,time_travelled,my_time-EARLIEST_TIME,i); move flashlight-->i to Get3D(flashlight_loc,time_travelled,my_time-EARLIEST_TIME,i); move battery-->i to Get3D(battery_loc,time_travelled,my_time-EARLIEST_TIME,i); move cable-->i to Get3D(cable_loc,time_travelled,my_time-EARLIEST_TIME,i); move crowbar-->i to Get3D(crowbar_loc,time_travelled,my_time-EARLIEST_TIME,i); move notes-->i to Get3D(notes_loc,time_travelled,my_time-EARLIEST_TIME,i); } for (t=0 : t <= time_travelled : t++) { if (Get2D(player_loc,t,my_time-EARLIEST_TIME) == nothing) move former_self-->t to limbo; else move former_self-->t to Get2D(player_loc,t,my_time-EARLIEST_TIME); } if (my_time < prototype_fixed_time) prototype.fixed = false; SetBombs(); SetFlashlights(); SetPanel(panel_setting); SetBasementLight(basement_equipment_light); SetGroundLight(ground_equipment_light); SetAutomaticDoor(main_doors, main_doors_state); SetAutomaticDoor(basement_door, basement_door_state); SetAutomaticDoor(ground_door, ground_door_state); SetAutomaticDoor(upstairs_door, upstairs_door_state); SetManualDoor(balcony_door, balcony_door_state); SetManualDoor(conference_window, conference_window_state); SetManualDoor(deutsch_door, deutsch_door_state); SetManualDoor(basement_equipment_door, basement_equipment_door_state); SetManualDoor(ground_equipment_door, ground_equipment_door_state); SetBrokenDoor(main_doors, main_doors_smashed); SetBrokenDoor(basement_door, basement_door_smashed); SetBrokenDoor(ground_door, ground_door_smashed); SetBrokenDoor(upstairs_door, upstairs_door_smashed); SetBrokenDoor(balcony_door, balcony_door_smashed); !! initialise the history for the new self from the most recent self for (t = EARLIEST_TIME : t <= FINAL_TIME : t++) { for (i=0 : i < MAX_ITEM_COPIES : i++) { Put3D(bomb_loc, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(bomb_loc, time_travelled, (t - EARLIEST_TIME), i)); Put3D(id_card_loc, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(id_card_loc, time_travelled, (t - EARLIEST_TIME), i)); Put3D(equipment_key_loc, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(equipment_key_loc, time_travelled, (t - EARLIEST_TIME), i)); Put3D(deutsch_key_loc, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(deutsch_key_loc, time_travelled, (t - EARLIEST_TIME), i)); Put3D(flashlight_loc, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(flashlight_loc, time_travelled, (t - EARLIEST_TIME), i)); Put3D(battery_loc, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(battery_loc, time_travelled, (t - EARLIEST_TIME), i)); Put3D(cable_loc, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(cable_loc, time_travelled, (t - EARLIEST_TIME), i)); Put3D(crowbar_loc, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(crowbar_loc, time_travelled, (t - EARLIEST_TIME), i)); Put3D(notes_loc, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(notes_loc, time_travelled, (t - EARLIEST_TIME), i)); Put3D(bomb_setting, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(bomb_setting, time_travelled, (t - EARLIEST_TIME), i)); Put3D(flashlight_state, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(flashlight_state, time_travelled, (t - EARLIEST_TIME), i)); } Put2D(dangerous_activity, time_travelled+1, (t - EARLIEST_TIME), Get2D(dangerous_activity, time_travelled, (t - EARLIEST_TIME))); Put2D(activity_target, time_travelled+1, (t - EARLIEST_TIME), Get2D(activity_target, time_travelled, (t - EARLIEST_TIME))); Put2D(siren_state, time_travelled+1, (t - EARLIEST_TIME), Get2D(siren_state, time_travelled, (t - EARLIEST_TIME))); Put2D(panel_setting, time_travelled+1, (t - EARLIEST_TIME), Get2D(panel_setting, time_travelled, (t - EARLIEST_TIME))); Put2D(basement_equipment_light, time_travelled+1, (t - EARLIEST_TIME), Get2D(basement_equipment_light, time_travelled, (t - EARLIEST_TIME))); Put2D(ground_equipment_light, time_travelled+1, (t - EARLIEST_TIME), Get2D(ground_equipment_light, time_travelled, (t - EARLIEST_TIME))); Put2D(main_doors_state, time_travelled+1, (t - EARLIEST_TIME), Get2D(main_doors_state, time_travelled, (t - EARLIEST_TIME))); Put2D(basement_door_state, time_travelled+1, (t - EARLIEST_TIME), Get2D(basement_door_state, time_travelled, (t - EARLIEST_TIME))); Put2D(ground_door_state, time_travelled+1, (t - EARLIEST_TIME), Get2D(ground_door_state, time_travelled, (t - EARLIEST_TIME))); Put2D(upstairs_door_state, time_travelled+1, (t - EARLIEST_TIME), Get2D(upstairs_door_state, time_travelled, (t - EARLIEST_TIME))); Put2D(balcony_door_state, time_travelled+1, (t - EARLIEST_TIME), Get2D(balcony_door_state, time_travelled, (t - EARLIEST_TIME))); Put2D(conference_window_state, time_travelled+1, (t - EARLIEST_TIME), Get2D(conference_window_state, time_travelled, (t - EARLIEST_TIME))); Put2D(deutsch_door_state, time_travelled+1, (t - EARLIEST_TIME), Get2D(deutsch_door_state, time_travelled, (t - EARLIEST_TIME))); Put2D(basement_equipment_door_state, time_travelled+1, (t - EARLIEST_TIME), Get2D(basement_equipment_door_state, time_travelled, (t - EARLIEST_TIME))); Put2D(ground_equipment_door_state, time_travelled+1, (t - EARLIEST_TIME), Get2D(ground_equipment_door_state, time_travelled, (t - EARLIEST_TIME))); Put2D(main_doors_smashed, time_travelled+1, (t - EARLIEST_TIME), Get2D(main_doors_smashed, time_travelled, (t - EARLIEST_TIME))); Put2D(basement_door_smashed, time_travelled+1, (t - EARLIEST_TIME), Get2D(basement_door_smashed, time_travelled, (t - EARLIEST_TIME))); Put2D(ground_door_smashed, time_travelled+1, (t - EARLIEST_TIME), Get2D(ground_door_smashed, time_travelled, (t - EARLIEST_TIME))); Put2D(upstairs_door_smashed, time_travelled+1, (t - EARLIEST_TIME), Get2D(upstairs_door_smashed, time_travelled, (t - EARLIEST_TIME))); Put2D(balcony_door_smashed, time_travelled+1, (t - EARLIEST_TIME), Get2D(balcony_door_smashed, time_travelled, (t - EARLIEST_TIME))); } time_travelled++; return true; ]; [ReplaceTravellingItem thing_type i; if (PlayerHas(thing_type-->i)) move thing_type-->(i+Exp(2,time_travelled)) to player; else if (LocationOf(thing_type-->i) == prototype_interior) move thing_type-->(i+Exp(2,time_travelled)) to prototype_interior; ]; [FixBombSettings time_amount i; for (i=0 : i < Exp(2,time_travelled) : i++) { if (PlayerHas(bomb-->i) || (LocationOf(bomb-->i) == prototype_interior)) if ((bomb-->i).time_value ~= NA_) (bomb-->(i+Exp(2,time_travelled))).time_value = (bomb-->i).time_value - time_amount; (bomb-->i).time_value = NA_; } ]; [FixFlashlightStates i; for (i=0 : i < Exp(2,time_travelled) : i++) { if (PlayerHas(flashlight-->i) || (LocationOf(flashlight-->i) == prototype_interior)) { if (flashlight-->i has on) give flashlight-->(i+Exp(2,time_travelled)) on; else give flashlight-->(i+Exp(2,time_travelled)) ~on; } give flashlight-->i ~on; } ]; !---------------------------------------------------- ! ! Little utility functions: [IsOfType thing thing_type i; for (i=0 : i < MAX_ITEM_COPIES : i++) if (thing_type-->i == thing) return true; return false; ]; [AmHolding thing_type i; for (i=0 : i < MAX_ITEM_COPIES : i++) if (thing_type-->i ~= nothing && thing_type-->i in player) return true; return false; ]; [GetHeld thing_type i; for (i=0 : i < MAX_ITEM_COPIES : i++) if (thing_type-->i ~= nothing && thing_type-->i in player) return thing_type-->i; return false; ]; [IsIn thing_type loc i; for (i=0 : i < MAX_ITEM_COPIES : i++) if (thing_type-->i ~= nothing && thing_type-->i in loc) return true; return false; ]; [GetFrom thing_type loc i; for (i=0 : i < MAX_ITEM_COPIES : i++) if (thing_type-->i ~= nothing && thing_type-->i in loc) return thing_type-->i; return false; ]; ![Present thing_type t; ! for (t=0 : t < MAX_ITEM_COPIES : t++) ! if (thing_type-->t ~= nothing && thing_type-->t in real_location) ! return true; ! return false; !]; ![GetPresent thing_type t; ! for (t=0 : t < MAX_ITEM_COPIES : t++) ! if (thing_type-->t ~= nothing && thing_type-->t in real_location) ! return thing_type-->t; ! return false; !]; [BatteriesContained thing batteries i; batteries = 0; for (i=0 : i < MAX_ITEM_COPIES : i++) if (battery-->i ~= nothing && battery-->i in thing) batteries++; return batteries; ]; [StartSiren; if (siren_start_time == UNKNOWN_ || siren_start_time > my_time) siren_start_time = my_time; ]; [MoveMoveableChildren old_loc new_loc x y; while (child(old_loc)) { x = nothing; y = child(old_loc); if ((y hasnt static) && (y ~= player)) { x = y; } while (sibling(y)) { y = sibling(y); if ((y hasnt static) && (y ~= player)) { x = y; } } if (x ~= nothing) { move x to new_loc; } else break; } ]; [ LocationOf x; if (parent(x) == 0) return x; else return LocationOf(parent(x)); ]; [ PlayerHas x; if (parent(x) == 0) return false; if (parent(x) == player) return true; return PlayerHas(parent(x)); ]; [ Flashlit i; for (i=0 : i < MAX_ITEM_COPIES : i++) { if (flashlight-->i ~= nothing && (flashlight-->i in player or real_location) && flashlight-->i has on) return true; } return false; ]; [PrintTime t; if (t == NA_) return true; print (t/720), ":", ((t/12)%60)/10, (t/12)%10, ":", ((t%12)/2); if ((t%2) == 0) print "0"; else print "5"; if (t/(720*12) == 0) print " am"; else print " pm"; ]; [PrintShortTime t; print (t/720), ":", ((t/12)%60)/10, (t/12)%10; if (t/(720*12) == 0) print " am"; else print " pm"; ]; [IncTime; InformLibrary.end_turn_sequence(); ]; !! x == run_through, y == time_index [Put2D array x y thing; array-->((x * (GAME_LENGTH+1)) + y) = thing; ]; !! x == run_through, y == time_index [Get2D array x y; return array-->((x * (GAME_LENGTH+1)) + y); ]; !! x == run_through, y == time_index, z == thing_number [Put3D array x y z thing; array-->( (z*(MAX_TIME_TRAVELS+1) + x)*(GAME_LENGTH+1) + y ) = thing; ]; !! x == run_through, y == time_index, z == thing_number [Get3D array x y z; return array-->( (z*(MAX_TIME_TRAVELS+1) + x)*(GAME_LENGTH+1) + y ); ]; [Exp b e i result; result = 1; for (i=0 : ii).time_value); } ]; [ObserveFlashlights i; for (i=0 : i < MAX_ITEM_COPIES : i++) { Put3D(flashlight_state, time_travelled, (my_time - EARLIEST_TIME), i, flashlight-->i has on); } ]; [ObserveSiren siren_on; siren_on = (siren_start_time ~= UNKNOWN_) && (siren_start_time < my_time); Put2D(siren_state, time_travelled, my_time - EARLIEST_TIME, siren_on); ]; [ObservePanel; Put2D(panel_setting, time_travelled, my_time - EARLIEST_TIME, control_panel.time_value); ]; [ObserveGroundLight light_array; Put2D(light_array, time_travelled, my_time - EARLIEST_TIME, ground_equipment.lit); ]; [ObserveBasementLight light_array; Put2D(light_array, time_travelled, my_time - EARLIEST_TIME, basement_light_switch.blown); ]; [ObserveBrokenDoor door door_smashed; Put2D(door_smashed, time_travelled, my_time - EARLIEST_TIME, door.smashed); ]; [ObserveManualDoor door door_state door_status; if (door has locked) door_status = LOCKED_; else { if (door has open) door_status = OPEN_; else door_status = CLOSED_; } Put2D(door_state, time_travelled, my_time - EARLIEST_TIME, door_status); ]; [ObserveAutomaticDoor door door_state door_status; if (door has locked) door_status = 0; else door_status = door.to_close_at; Put2D(door_state, time_travelled, my_time - EARLIEST_TIME, door_status); ]; [ObserveLocations i; Put2D(player_loc, time_travelled, (my_time - EARLIEST_TIME), parent(player)); for (i=0 : i < MAX_ITEM_COPIES : i++) { Put3D(bomb_loc, time_travelled, (my_time - EARLIEST_TIME), i, parent(bomb-->i) ); Put3D(id_card_loc, time_travelled, (my_time - EARLIEST_TIME), i, parent(id_card-->i) ); Put3D(equipment_key_loc, time_travelled, (my_time - EARLIEST_TIME), i, parent(equipment_key-->i) ); Put3D(deutsch_key_loc, time_travelled, (my_time - EARLIEST_TIME), i, parent(deutsch_key-->i) ); Put3D(flashlight_loc, time_travelled, (my_time - EARLIEST_TIME), i, parent(flashlight-->i) ); Put3D(battery_loc, time_travelled, (my_time - EARLIEST_TIME), i, parent(battery-->i) ); Put3D(cable_loc, time_travelled, (my_time - EARLIEST_TIME), i, parent(cable-->i) ); Put3D(crowbar_loc, time_travelled, (my_time - EARLIEST_TIME), i, parent(crowbar-->i) ); Put3D(notes_loc, time_travelled, (my_time - EARLIEST_TIME), i, parent(notes-->i) ); } ]; !---------------------------------------------------- ! ! 'Set' functions: (these take care of certain former actions every turn) [SetBombs setting_now i; for (i=0 : i < Exp(2,time_travelled) : i++) { setting_now = Get3D(bomb_setting,time_travelled,my_time-EARLIEST_TIME,i); (bomb-->i).time_value = setting_now; } ]; [SetFlashlights setting_now i; for (i=0 : i < Exp(2,time_travelled) : i++) { setting_now = Get3D(flashlight_state,time_travelled,my_time-EARLIEST_TIME,i); if (setting_now == true) give flashlight-->i on; else give flashlight-->i ~on; } ]; [SetPanel setting_array setting_now; setting_now = Get2D(setting_array, time_travelled, my_time - EARLIEST_TIME); control_panel.time_value = setting_now; ]; [SetBasementLight setting_array setting_now; setting_now = Get2D(setting_array, time_travelled, my_time - EARLIEST_TIME); basement_light_switch.blown = setting_now; ]; [SetGroundLight setting_array setting_now; setting_now = Get2D(setting_array, time_travelled, my_time - EARLIEST_TIME); ground_equipment.lit = setting_now; if (setting_now) give ground_light_switch on; else give ground_light_switch ~on; ]; [SetManualDoor door door_state door_status; door_status = Get2D(door_state, time_travelled, my_time - EARLIEST_TIME); if (door_status == LOCKED_) { give door ~open; give door locked; } if (door_status == CLOSED_) { give door ~open; give door ~locked; } if (door_status == OPEN_) { give door open; give door ~locked; } if (door_status == UNKNOWN_) { print "Error: unknown door status needing to be set for some reason."; } ]; [SetAutomaticDoor door door_state door_status; door_status = Get2D(door_state, time_travelled, my_time - EARLIEST_TIME); if (door_status == UNKNOWN_) { give door ~open locked; } if (door_status > 0) { give door open ~locked; door.to_close_at = door_status; } ]; [SetBrokenDoor door door_smashed door_status; door_status = Get2D(door_smashed, time_travelled, my_time - EARLIEST_TIME); if (door_status == UNKNOWN_) { door.smashed = false; } if (door_status == true) { door.smashed = true; } if (door_status == false) { door.smashed = false; } ]; [MoveFormerSelf run_through loc_next; loc_next = Get2D(player_loc, run_through, my_time - EARLIEST_TIME); if (~~d_paradox) { if (d_destroyed_prototype && ((former_self-->run_through) in limbo) && (loc_next == prototype_interior)) { d_paradox = true; deadflag = 3; Seperator(); print (PrintTime) (my_time), "^^"; print "Back in the Deutsch lab, the debris from the prototype lies smoldering on the floor and no past self appears.^"; print "^Time unravels...^"; Devours(my_time); } else if (d_destroyed_prototype && (my_time == start_time)) { d_paradox = true; deadflag = 3; Seperator(); print (PrintTime) (my_time), "^^"; print "Elsewhere, your past self enters the foyer and smells the bitter smoke from a recent explosion.^"; print "^Time unravels...^"; Devours(my_time); } else { if (loc_next == nothing) move former_self-->run_through to limbo; else move former_self-->run_through to loc_next; } ! if ((~~d_paradox) && (~~d_escaped) && (~~d_caught)) ! print "<<< former self (", run_through, ") is in: ", (name) loc_next, " >>>^"; } ]; !! Moves an object around according to the actions of former selves !! Uses the item histories to work out when an item was moved, but since !! that copy of the item may have been swapped for another (which is fine) !! we must get the first available copy in the right location to be safe. !! Also, we don't want to remove all normal objects when someone time-travels !! so, since this only happens when the player is not present and no other moving !! happens when the player is not present, we can get around it by only moving !! objects when a former self is present in the same location. [MoveObject thing_type thing_loc i loc_now loc_next; loc_now = Get3D(thing_loc,time_travelled-1,my_time-EARLIEST_TIME-1,i); loc_next = Get3D(thing_loc,time_travelled-1,my_time-EARLIEST_TIME,i); if (loc_now ~= loc_next) { if (IsIn(thing_type, loc_now)) { if (IsIn(former_self,LocationOf(GetFrom(thing_type, loc_now)))) { ! print "<<< Moving ", (name) thing_type-->i, " (", i, ") in ", (name) loc_now, ! " to ", (name) loc_next, " >>>^"; move GetFrom(thing_type, loc_now) to loc_next; } else { !! handle the odd case of object left in prototype when button pressed if (LocationOf(GetFrom(thing_type, loc_now)) == prototype_interior) { ! print "<<< Moving ", (name) thing_type-->i, " (", i, ") in ", (name) loc_now, ! " to ", (name) loc_next, " >>>^"; move GetFrom(thing_type, loc_now) to loc_next; } else if ((loc_now == basement_equipment_gloom) || (loc_now == ground_equipment_gloom)) { ! print "<<< Moving ", (name) thing_type-->i, " (", i, ") in ", (name) loc_now, ! " to ", (name) loc_next, " >>>^"; move GetFrom(thing_type, loc_now) to loc_next; } ! else { ! print "<<< Ignoring ", (name) thing_type-->0, " in ", (name) loc_now, ! " (wanted to move it to ", (name) loc_next, ") >>>^"; ! } } } ! else ! print "<<< Missing ", (name) thing_type-->0, " in ", (name) loc_now, ! " (wanted to move it to ", (name) loc_next, ") >>>^"; } ]; !---------------------------------------------------- ! ! 'Maybe' functions: (these take care of former actions) [MaybeExplodeBombs i; for (i=0 : i < MAX_ITEM_COPIES : i++) if (bomb-->i ~= nothing) { if (LocationOf(bomb-->i) ~= limbo) { if (((bomb-->i).time_value == my_time - 1) && ((bomb-->i).left_over_seconds == 0)) ExplodeBomb(i); else if (((bomb-->i).time_value == my_time - 2) && ((bomb-->i).left_over_seconds ~=0)) ExplodeBomb(i); } } ]; [MaybeSing; if (Get2D(dangerous_activity, time_travelled-1, my_time-EARLIEST_TIME-1) == SING_) if (player notin limbo) "You hear muffled singing from somewhere in the building."; ]; [MaybeShout; if (Get2D(dangerous_activity, time_travelled-1, my_time-EARLIEST_TIME-1) == SHOUT_) if (player notin limbo) "You hear muffled shouting from somewhere in the building."; ]; !!! a little tricky to ensure that when two bombs are in same room that the one set !!! has the same original setting as it should (ie is indistinguishable from former one) [MaybeSetBombs setting_now setting_next loc_now b i j; for (i=0 : i < Exp(2,time_travelled-1) : i++) { setting_now = Get3D(bomb_setting,time_travelled-1,my_time-EARLIEST_TIME-1,i); setting_next = Get3D(bomb_setting,time_travelled-1,my_time-EARLIEST_TIME,i); loc_now = Get3D(bomb_loc,time_travelled-1,my_time-EARLIEST_TIME-1,i); if (setting_now ~= setting_next) { if (IsIn(bomb, loc_now)) { if (IsIn(former_self,LocationOf(GetFrom(bomb, loc_now)))) { for (j=0 : j < MAX_ITEM_COPIES : j++) if ((bomb-->j ~= nothing) && (bomb-->j in loc_now)) if ((bomb-->j).time_value == setting_now) b = bomb-->j; ! print "<<< setting bomb (via maybeset) >>>^"; if (b ~= nothing) b.time_value = setting_next; ! else ! print "<<>>^"; } } ! else ! print "<<0, " in ", (name) loc_now, ! " (wanted to set it to ", setting_next, ")>>>^"; } } ]; !!! a little tricky to ensure that when two flashlights are in same room that the one set !!! has the same original setting as it should (ie is indistinguishable from former one) [MaybeSetFlashlights setting_now setting_next loc_now f i j; for (i=0 : i < Exp(2,time_travelled-1) : i++) { setting_now = Get3D(flashlight_state,time_travelled-1,my_time-EARLIEST_TIME-1,i); setting_next = Get3D(flashlight_state,time_travelled-1,my_time-EARLIEST_TIME,i); loc_now = Get3D(flashlight_loc,time_travelled-1,my_time-EARLIEST_TIME-1,i); if (setting_now ~= setting_next) { if (IsIn(flashlight, loc_now)) { if (IsIn(former_self,LocationOf(GetFrom(flashlight, loc_now)))) { for (j=0 : j < MAX_ITEM_COPIES : j++) if ((flashlight-->j ~= nothing) && (flashlight-->j in loc_now)) if ((flashlight-->j has on) == setting_now) f = flashlight-->j; ! print "<<< setting flashlight (via maybeset) >>>^"; if (f ~= nothing) { if (setting_next == true) give f on; else give f ~on; } ! else ! print "<<>>^"; } } ! else ! print "<<0, " in ", (name) loc_now, ! " (wanted to set it to ", setting_next, ")>>>^"; } } ]; [MaybeSetPanel setting_array setting_now setting_next; setting_now = Get2D(setting_array, time_travelled - 1, my_time - EARLIEST_TIME - 1); setting_next = Get2D(setting_array, time_travelled - 1, my_time - EARLIEST_TIME); if (setting_next ~= UNKNOWN_ && setting_next ~= setting_now) { control_panel.time_value = setting_next; } ]; [MaybeSetBasementLight setting_array setting_now setting_next; setting_now = Get2D(setting_array, time_travelled - 1, my_time - EARLIEST_TIME - 1); setting_next = Get2D(setting_array, time_travelled - 1, my_time - EARLIEST_TIME); if (setting_next ~= UNKNOWN_ && setting_next ~= setting_now) { basement_light_switch.blown = setting_next; } ]; [MaybeSetGroundLight setting_array setting_now setting_next; setting_now = Get2D(setting_array, time_travelled - 1, my_time - EARLIEST_TIME - 1); setting_next = Get2D(setting_array, time_travelled - 1, my_time - EARLIEST_TIME); if (setting_next ~= UNKNOWN_ && setting_next ~= setting_now) { ground_equipment.lit = setting_next; if (setting_next) give ground_light_switch on; else give ground_light_switch ~on; } ]; [MaybeCloseAutomaticDoor door; if (door.just_closed) door.just_closed = false; if (~~deadflag) if (door.to_close_at == my_time - 1) door.close_self(); ]; !! Opens/closes/locks/unlocks doors for the past self and catches paradoxes that could not !! be seen, but where the locked/unlocked state of the door differs and interferes with the action. !! Also works when the former self unlocks an unlocked door or locks !! a locked door, but this door had the converse state and the key actually turns. [MaybeSetManualDoor door door_state past_door_status_now past_door_status_next present_door_status_now the_action t; for (t=0 : ti) in (former_self-->t)) { flash_i_batteries = BatteriesContained(flashlight-->i); past_count = 0; present_count = 0; for (j=0 : j < MAX_ITEM_COPIES : j++) if ((flashlight-->j) in (former_self-->t)) if (BatteriesContained(flashlight-->j) == flash_i_batteries) present_count++; for (j=0 : j < MAX_ITEM_COPIES : j++) { flash_j_loc = Get3D(flashlight_loc,t,my_time-EARLIEST_TIME,j); flash_j_batteries = 0; for (k=0 : kj)) flash_j_batteries++; } if (flash_j_loc == former_self-->t) if (flash_j_batteries == flash_i_batteries) past_count++; } if (present_count ~= past_count) { too_heavy = (past_count < present_count); trouble = true; } } } BLOW_BASEMENT_LIGHT_: if (Get2D(basement_equipment_light, time_travelled, my_time-EARLIEST_TIME-1) == true) trouble = true; } if (trouble) { d_paradox = true; deadflag = 3; Seperator(); switch (action_de_jour) { X_CCTV_: print "In the foyer, your past self glances at a CCTV screen and sees you in the shadowed corridor.^"; X_UPSTAIRS_CORRIDOR_: if (former_self-->t in balcony) print "From the chilly balcony, your former self looks through the glass door and sees you in the shadowed corridor.^"; else print "From the upstairs landing, your former self looks through the glass and sees you in the shadowed corridor.^"; X_UPSTAIRS_LANDING_: print "From the second floor corridor, your former self looks through the glass door and sees you in the shadowy landing.^"; X_GROUND_CORRIDOR_: print "From within the foyer, your former self looks through the glass door and sees you in the shadowed corridor.^"; X_FOYER_: if (former_self-->t in upstairs_landing) print "From the landing above, your former self looks down and sees you.^"; else print "From the first floor corridor, your former self looks through the glass door and sees you.^"; X_BASEMENT_CORRIDOR_: print "From the basement landing, your former self looks through the glass door and sees you in the shadowed corridor.^"; X_BASEMENT_LANDING_: print "From the basement corridor, your former self looks through the glass door and sees you in the shadowy landing.^"; X_BALCONY_: if (former_self-->t in upstairs_corridor) print "From the second floor corridor, your former self looks through the glass door and sees you on the chilly balcony.^"; else print "From within the darkened conference room, your former self looks out and sees you on the chilly balcony.^"; TAKE_FLASHLIGHT_: if (too_heavy) print (Nearby) 0, "your past self picks up a flashlight, but finds it strangely heavy.^"; else print (Nearby) 0, "your past self picks up a flashlight, but finds it strangely light.^"; BLOW_BASEMENT_LIGHT_: print "In the basement equipment room, your past self switches on the light but there is no flicker, for it has already blown.^"; } if ((action_de_jour >= X_CCTV_) && (action_de_jour <= X_BALCONY_)) print "^This is one of the all time most embarrassing ways to destroy the city of Boston.^"; print "^Time unravels...^"; Devours(my_time); } } } ]; [CheckPassiveParadox t; for (t=0 : t < time_travelled : t++) if (LocationOf(former_self-->t) ~= limbo) { CheckPlayerInRoom(t); CheckStateOfSiren(t); CheckStateOfDoors(t); CheckStateOfGroundLight(t); CheckQuantityInRoom(bomb,bomb_loc,t); CheckQuantityInRoom(id_card,id_card_loc,t); CheckQuantityInRoom(equipment_key,equipment_key_loc,t); CheckQuantityInRoom(deutsch_key,deutsch_key_loc,t); CheckQuantityInRoom(flashlight,flashlight_loc,t); CheckQuantityInRoom(battery,battery_loc,t); CheckQuantityInRoom(cable,cable_loc,t); CheckQuantityInRoom(crowbar,crowbar_loc,t); CheckQuantityInRoom(notes,notes_loc,t); CheckStateOfFlashlights(t); if (former_self-->t in foyer) CheckObjectsOnDesk(security_desk,t); if (former_self-->t in conference_room) { CheckObjectsOnDesk(conference_table,t); CheckObjectsOnDesk(chair,t); } if (former_self-->t in deutsch_lab) CheckObjectsOnDesk(bench,t); if (former_self-->t in prototype_interior) CheckTimeOnPanel(t); CheckTimesOnBombs(t); } ]; [CheckStateOfDoors t fs_loc; fs_loc = LocationOf(former_self-->t); switch (fs_loc) { foyer: CheckStateOfDoor(main_doors, main_doors_state, t, fs_loc); CheckStateOfDoor(ground_door, ground_door_state, t, fs_loc); CheckBrokenDoor(main_doors, main_doors_smashed, t, fs_loc); CheckBrokenDoor(ground_door, ground_door_smashed, t, fs_loc); ground_corridor: CheckStateOfDoor(ground_door, ground_door_state, t, fs_loc); CheckBrokenDoor(ground_door, ground_door_smashed, t, fs_loc); CheckStateOfDoor(ground_equipment_door, ground_equipment_door_state, t, fs_loc); ground_equipment: CheckStateOfDoor(ground_equipment_door, ground_equipment_door_state, t, fs_loc); basement_landing: CheckStateOfDoor(basement_door, basement_door_state, t, fs_loc); CheckBrokenDoor(basement_door, basement_door_smashed, t, fs_loc); basement_corridor: CheckStateOfDoor(basement_door, basement_door_state, t, fs_loc); CheckBrokenDoor(basement_door, basement_door_smashed, t, fs_loc); CheckStateOfDoor(basement_equipment_door, basement_equipment_door_state, t, fs_loc); CheckStateOfDoor(deutsch_door, deutsch_door_state, t, fs_loc); deutsch_lab: CheckStateOfDoor(deutsch_door, deutsch_door_state, t, fs_loc); prototype_interior: CheckStateOfDoor(deutsch_door, deutsch_door_state, t, fs_loc); upstairs_landing: CheckStateOfDoor(upstairs_door, upstairs_door_state, t, fs_loc); CheckBrokenDoor(upstairs_door, upstairs_door_smashed, t, fs_loc); upstairs_corridor: CheckStateOfDoor(upstairs_door, upstairs_door_state, t, fs_loc); CheckStateOfDoor(balcony_door, balcony_door_state, t, fs_loc); CheckBrokenDoor(upstairs_door, upstairs_door_smashed, t, fs_loc); CheckBrokenDoor(balcony_door, balcony_door_smashed, t, fs_loc); balcony: CheckStateOfDoor(balcony_door, balcony_door_state, t, fs_loc); CheckBrokenDoor(balcony_door, balcony_door_smashed, t, fs_loc); CheckStateOfDoor(conference_window, conference_window_state, t, fs_loc); conference_room: CheckStateOfDoor(conference_window, conference_window_state, t, fs_loc); default: return false; } ]; ! this is a tiny bit of a hack, using the fact that OPEN_ is higher than CLOSED_, LOCKED_. ! and the fact that automatic doors which are open have values higher than OPEN_. [CheckStateOfDoor door door_state t fs_loc past_door_state fs_loc_last_turn; past_door_state = Get2D(door_state,t,my_time-EARLIEST_TIME); fs_loc_last_turn = Get2D(player_loc,t,my_time-EARLIEST_TIME-1); if (~~d_paradox) { if ((past_door_state >= OPEN_) && (door hasnt open)) { d_paradox = true; deadflag = 3; Seperator(); print (Nearby) 0, "your former self enters ", (TheLower) fs_loc, " and sees ", (the) door, " pulled closed.^"; print "^Time unravels...^"; Devours(my_time); } else if ((past_door_state < OPEN_) && (door has open)) { d_paradox = true; deadflag = 3; Seperator(); if (door ~= conference_window) { if (fs_loc_last_turn ~= fs_loc) print (Nearby) 0, "your former self enters ", (TheLower) fs_loc, " and sees ", (the) door, " standing open.^"; else print (Nearby) 0, "your former self standing in ", (TheLower) fs_loc, " sees ", (the) door, " open.^"; } else print (Nearby) 0, "your former self enters ", (TheLower) fs_loc, " and sees the shattered conference room window.^"; print "^Time unravels...^"; Devours(my_time); } } ]; [CheckBrokenDoor door door_smashed t fs_loc past_door_smashed_now past_door_smashed_next; past_door_smashed_now = Get2D(door_smashed,t,my_time-EARLIEST_TIME-1); past_door_smashed_next = Get2D(door_smashed,t,my_time-EARLIEST_TIME); if (~~d_paradox) { if ((~~past_door_smashed_next) && door.smashed) { d_paradox = true; deadflag = 3; Seperator(); if (past_door_smashed_now) print "In ", (TheLower) fs_loc, ", your former self sees the web of cracks in ", (the) door, ".^"; else print "In ", (TheLower) fs_loc, ", your former self hears the crack of your crowbar smashing into ", (the) door, ".^"; print "^Time unravels...^"; Devours(my_time); } } ]; [CheckTimesOnBombs t i j bomb_i_time bomb_j_time bomb_j_loc past_count present_count fs_loc; fs_loc = LocationOf(former_self-->t); if (~~d_paradox) { for (i=0 : i < MAX_ITEM_COPIES : i++) { if (LocationOf(bomb-->i) == fs_loc) { bomb_i_time = (bomb-->i).time_value; past_count = 0; present_count = 0; for (j=0 : j < MAX_ITEM_COPIES : j++) if (LocationOf(bomb-->j) == fs_loc) if ((bomb-->j).time_value == bomb_i_time) present_count++; for (j=0 : j < MAX_ITEM_COPIES : j++) { bomb_j_loc = Get3D(bomb_loc,t,my_time-EARLIEST_TIME,j); bomb_j_time = Get3D(bomb_setting,t,my_time-EARLIEST_TIME,j); if (((bomb_j_loc == fs_loc) || (parent(bomb_j_loc) == fs_loc))) if (bomb_j_time == bomb_i_time) past_count++; } if (past_count ~= present_count) { d_paradox = true; deadflag = 3; Seperator(); print (Nearby) 0, "your former self enters ", (TheLower) fs_loc, " and sees a different value flashing on the explosive device's timer.^"; print "^Time unravels...^"; Devours(my_time); } } } } ]; [CheckStateOfFlashlights t i present_flashlights_on past_flashlights_on fs_loc flash_loc flash_state; fs_loc = LocationOf(former_self-->t); if (~~d_paradox) { for (i=0 : i < MAX_ITEM_COPIES : i++) { flash_loc = Get3D(flashlight_loc,t,my_time-EARLIEST_TIME,i); flash_state = Get3D(flashlight_state,t,my_time-EARLIEST_TIME,i); if (flash_state && ((flash_loc == fs_loc) || (parent(flash_loc) == fs_loc))) past_flashlights_on++; if ((flashlight-->i has on) && (LocationOf(flashlight-->i) == fs_loc)) present_flashlights_on++; } if (past_flashlights_on ~= present_flashlights_on) { d_paradox = true; deadflag = 3; Seperator(); if (past_flashlights_on < present_flashlights_on) print (Nearby) 0, "your former self enters ", (TheLower) fs_loc, " and sees a thin white beam of light shining where once was darkness.^"; else print (Nearby) 0, "your former self enters ", (TheLower) fs_loc, " and sees only darkness where once a thin white beam of light was shining.^"; print "^Time unravels...^"; Devours(my_time); } } ]; ! only need to check if in corridor with open door as this will catch all cases [CheckStateOfGroundLight t past_ground_light_state; past_ground_light_state = Get2D(ground_equipment_light,t,my_time-EARLIEST_TIME); if (~~d_paradox) if ((ground_light_switch has on) ~= past_ground_light_state) { if ((former_self-->t in ground_corridor) && (ground_equipment_door has open)) { d_paradox = true; deadflag = 3; Seperator(); if (ground_light_switch has on) { if (Get2D(ground_equipment_door_state,t,my_time-EARLIEST_TIME-1)==OPEN_) print (Nearby) 0, "your former self enters the first floor corridor and sees a pool of light spilling from the equipment room.^"; else print (Nearby) 0, "your former self opens the door to the first floor equipment room and bright fluorescent light spills over her.^"; } else { if (Get2D(ground_equipment_door_state,t,my_time-EARLIEST_TIME-1)==OPEN_) print (Nearby) 0, "your former self enters the first floor corridor but does not see a pool of light spilling from the equipment room.^"; else print (Nearby) 0, "your former self opens the door to the first floor equipment room but no bright fluorescent light spills over her.^"; } print "^Time unravels...^"; Devours(my_time); } } ]; [CheckStateOfSiren t past_state siren_on; past_state = Get2D(siren_state,t,my_time-EARLIEST_TIME); siren_on = (siren_start_time ~= UNKNOWN_) && (siren_start_time < my_time); if (~~d_paradox) if (past_state ~= siren_on) { if (my_time - siren_start_time == 1) print "^A piercing siren rings out.^"; if (my_time - siren_start_time > 1) print "^The siren wails.^"; d_paradox = true; deadflag = 3; Seperator(); print (Nearby) 0, "your former self cringes from the sound of the siren.^"; print "^Time unravels...^"; Devours(my_time); } ]; !! Only checks the bare contents of the room, not the containers, states etc. [CheckQuantityInRoom thing_type thing_loc t i present_count past_count; present_count = 0; past_count = 0; if (~~d_paradox) { for (i=0 : i < Exp(2,t+1) : i++) { if (parent(thing_type-->i) == LocationOf(former_self-->t)) present_count++; if (Get3D(thing_loc,t,my_time-EARLIEST_TIME,i) == LocationOf(former_self-->t)) past_count++; } if (past_count ~= present_count) { d_paradox = true; deadflag = 3; Seperator(); print "Entering ", (TheLower) LocationOf(former_self-->t), " your past self looks quickly about. "; if (past_count > present_count) print "Unlike the last time, her gaze passes straight over the place where ", (the) thing_type-->0, " had lain.^"; else print "As her glance falls upon ", (the) thing_type-->0, " a moment of worry passes over her features.^"; print "^Time unravels...^"; Devours(my_time); } } ]; [CheckPlayerInRoom t player_loc_now player_loc_next fs_loc_now fs_loc_next; player_loc_now = Get2D(player_loc,time_travelled,my_time-EARLIEST_TIME-1); player_loc_next = Get2D(player_loc,time_travelled,my_time-EARLIEST_TIME); fs_loc_now = Get2D(player_loc,t,my_time-EARLIEST_TIME-1); fs_loc_next = Get2D(player_loc,t,my_time-EARLIEST_TIME); if ((player_loc_next == fs_loc_next)) { if (player_loc_now == nothing) { d_paradox = true; deadflag = 3; Seperator(); print "Someone appears beside you in the cramped chamber. Soft hair and anxious eyes. It is you.^"; print "^Time unravels...^"; Devours(my_time); } else if (player_loc_now ~= player_loc_next) { !! if the player had moved... d_paradox = true; deadflag = 3; Seperator(); print "As you enter ", (TheLower) player_loc_next, " you see your former self standing before you. Hearing your soft footfall, she turns. Horror fills her eyes.^"; print "^Time unravels...^"; Devours(my_time); } else if (fs_loc_now ~= fs_loc_next) { !! if the former self had moved... d_paradox = true; deadflag = 3; Seperator(); print "You turn at the sound of footsteps. It is you.^"; print "^Time unravels...^"; Devours(my_time); } else print "Error, former self saw player but neither had moved.^"; } else if ((player_loc_next == fs_loc_now) && (player_loc_now == fs_loc_next)) { d_paradox = true; deadflag = 3; Seperator(); print "As you enter ", (TheLower) player_loc_next, ", your eyes catch upon a figure coming towards you. She pauses, fear all about her.^"; print "^Time unravels...^"; Devours(my_time); } else if ((player_loc_next == deutsch_lab) && (fs_loc_next == prototype_interior)) { d_paradox = true; deadflag = 3; Seperator(); print "Hunched inside the prototype, your former self sees you through the open hatch.^"; print "^Time unravels...^"; Devours(my_time); } else if ((player_loc_next == prototype_interior) && (fs_loc_next == deutsch_lab)) { d_paradox = true; deadflag = 3; Seperator(); print "As your past self looks around, her eyes catch on something inside the prototype.^"; print "^Time unravels...^"; Devours(my_time); } ]; [CheckObjectsOnDesk desk t; CheckObjectOnDesk(desk, t, bomb, bomb_loc); CheckObjectOnDesk(desk, t, id_card, id_card_loc); CheckObjectOnDesk(desk, t, equipment_key, equipment_key_loc); CheckObjectOnDesk(desk, t, deutsch_key, deutsch_key_loc); CheckObjectOnDesk(desk, t, flashlight, flashlight_loc); CheckObjectOnDesk(desk, t, battery, battery_loc); CheckObjectOnDesk(desk, t, cable, cable_loc); CheckObjectOnDesk(desk, t, crowbar, crowbar_loc); CheckObjectOnDesk(desk, t, notes, notes_loc); ]; [CheckObjectOnDesk desk t thing_type thing_loc present_count past_count i; if (~~d_paradox) { for (i=0 : i < Exp(2,t+1) : i++) { if (thing_type-->i in desk) present_count++; if (Get3D(thing_loc,t,my_time-EARLIEST_TIME,i) == desk) past_count++; } if (past_count ~= present_count) { d_paradox = true; deadflag = 3; Seperator(); print "Entering ", (TheLower) LocationOf(former_self-->t), " your past self looks quickly about. "; if (past_count > present_count) print "Unlike the last time, her gaze passes straight over the place on ", (the) desk, " where ", (the) thing_type-->0, " had lain.^"; else print "As her glance falls upon ", (the) thing_type-->0, " a moment of worry passes over her features.^"; print "^Time unravels...^"; Devours(my_time); } } ]; [CheckTimeOnPanel t old_setting; old_setting = Get2D(panel_setting, t, my_time-EARLIEST_TIME); if (~~d_paradox) if (control_panel.time_value ~= old_setting) { d_paradox = true; deadflag = 3; Seperator(); print "Entering the prototype, your past self glances at the control panel, seeing ", control_panel.time_value, " instead of ", old_setting, ".^"; print "^Time unravels...^"; Devours(my_time); } ]; !---------------------------------------------------- ! ! Endgame functions: [CaughtInside t; d_caught = true; !-- Initial method of being caught: if (my_time > FINAL_TIME) print "^A quick noise from behind, then a strong grip on your wrist. The guard is back -- time has slipped away from you.^"; else if ((siren_start_time ~= UNKNOWN_) && (my_time - siren_start_time > siren_timeout)) print "^As the siren shrieks out around you, you catch a glimpse of movement. A sudden jolt, then you are wrestled to the ground. Security has arrived.^"; else print "Error: unknown reason for being caught^"; !-- Allow a small amount of time for bomb to explode before player dragged off... for (t=0 : (ti).time_value >= FINAL_TIME) && ~~(bomb-->i in player)) { d_exploded = true; if (LocationOf(bomb-->i) == deutsch_lab or prototype_interior) d_destroyed_prototype = true; for (j=0 : j < MAX_ITEM_COPIES : j++) if (InBlastRadius(notes-->j,bomb-->i)) d_destroyed_notes = true; } ]; [ExplodeBomb i j t; if (d_exploded) return true; d_exploded = true; !-- what exploded? if ((~~(d_escaped || d_detained)) && InBlastRadius(player,bomb-->i) ) d_killed_by_bomb = true; if (~~(d_escaped || d_detained)) d_injured_by_bomb = true; if (LocationOf(bomb-->i) == deutsch_lab or prototype_interior) d_destroyed_prototype = true; for (j=0 : j < MAX_ITEM_COPIES : j++) if (InBlastRadius(notes-->j,bomb-->i)) d_destroyed_notes = true; for (t=0 : t < time_travelled : t++) if (InBlastRadius(former_self-->t, bomb-->i)) { d_fs_killed_by_bomb = true; d_paradox = true; } for (t=0 : t < time_travelled : t++) if ((LocationOf(former_self-->t) ~= limbo)) { d_fs_hears_bomb = true; d_paradox = true; } !-- Consequences of explosion if (d_killed_by_bomb == true) { print "^The bomb detonates. A wall of force rips through the room with savage power, killing you immediately.^"; if (~~d_fs_hears_bomb) { for (t=0 : (my_time= FINAL_TIME - 3) { print "The night beckons you from the open doors, but as you rush forwards to meet it your hopes fail you -- security has arrived.^"; d_caught = true; DragPlayerOff(); } else if ((siren_start_time ~= UNKNOWN_) && (my_time - siren_start_time > siren_timeout - 2)) { print "The night beckons you from the open doors, but as you rush forwards to meet it your hopes fail you. With the siren shrieking out around you, security has arrived.^"; d_caught = true; DragPlayerOff(); } !-- Deal with the true escapes: else { move player to limbo; print "You slip out into the night, darting quickly through the Cambridge shadows until you reach the quiet corner where you left your car. Exhausted, you gently start the cold motor and roll off towards the interstate.^"; !-- Step through the rest of the time to check for paradox and/or explosion for (t=0 : (my_time About * 'devours' -> About * 'all' 'things' 'devours' -> About * -> About; [ WalkthroughSub; instant_action_this_turn = true; print_ret "Hints and a walkthrough are located at http://devours.amirrorclear.net^ You might also want to try the 'about' command.^^ If you are unfamiliar with text adventures, then you may want to learn the basics first at an introductory website such as http://brasslantern.org/beginners/"; ]; Verb 'walkthrough' 'walkthru' 'hint' 'hints' 'help' * -> Walkthrough; [ CreditsSub; instant_action_this_turn = true; print_ret "Written by half sick of shadows for IFComp 2004.^ Beta tested by Stephen Bond.^ Special thanks go to those who submitted detailed bug reports and suggestions during the competition, notably: Peter Eckersley, Oliver Nash, Hugo Thorvaldsen and Evin Robertson.^ ^ No rights are reserved by the author: this work is in the public domain and may be freely copied and modified."; ]; Verb 'credits' * -> Credits; [ InterleavingOnSub; instant_action_this_turn = true; poem_interleaving = true; "The ending will now be in the original, interleaved, style."; ]; [ InterleavingOffSub; instant_action_this_turn = true; poem_interleaving = false; "The ending will now be in the standard style."; ]; Verb 'interleaving' * 'on' -> InterleavingOn * 'off' -> InterleavingOff; [ ResetSub; print_ret "It is not clear what you are trying to do."; ]; Verb 'reset' 'stop' 'halt' 'defuse' * noun -> Reset; Verb 'swipe' * noun 'in' noun -> Insert * noun 'through' noun -> Insert; [ CompleteModificationsSub; if ((real_location == deutsch_lab) || (real_location == prototype_interior)) <>; else "You would need to be near the prototype to do that."; ]; Verb 'complete' 'finish' * 'modifications' -> CompleteModifications * 'work' -> CompleteModifications * 'changes' -> CompleteModifications * 'alteration' -> CompleteModifications; [ ModifySub; if ((noun == prototype) || (noun == control_panel) || (noun == nothing)) { if ((real_location == deutsch_lab) || (real_location == prototype_interior)) <>; else "You would need to be near the prototype to do that."; } "It is not clear what you are trying to do."; ]; Verb 'modify' 'change' 'alter' * -> Modify * noun -> Modify; [ SwitchSub; if (noun has on) <>; else <>; ]; Verb 'flick' 'flip' * noun -> Switch; Extend 'switch' first * noun -> Switch; [ SwingAtSub; if (second == nothing) print_ret "You swing ", (the) noun, " through the air, harmlessly."; else if (IsOfType(noun, crowbar)) <>; else if ((second == conference_window) || (second ofclass AutomaticDoor)) { print_ret (The) noun, " bounces harmlessly off the ", (the) second, "."; } else <>; ]; Extend 'swing' first * held -> SwingAt * held 'at' noun -> SwingAt * held 'into' noun -> SwingAt * held 'through' noun -> SwingAt; [ AttackWithSub; if (IsOfType(second, crowbar)) <>; else if ((noun == conference_window) || (noun ofclass AutomaticDoor)) { if (second == nothing) print_ret "You are not strong enough to break ", (the) noun, " by yourself."; else print_ret (The) second, " is not heavy enough to break ", (the) noun, "."; } else <>; ]; Extend 'attack' * noun 'with' 'fist' -> AttackWith * noun 'with' 'foot' -> AttackWith * noun 'with' 'hand' -> AttackWith * noun 'with' held -> AttackWith; [ JumpDownSub; if (real_location == balcony) Jumped(); else if ((real_location == upstairs_landing) || (real_location == foyer)) { print "You hit the ground hard. Maybe you should have used the stairs.^"; <>; } else "There is nothing to jump down to."; ]; Extend 'jump' first * 'down' -> JumpDown; [ ClimbDownSub; if (real_location == balcony) Jumped(); else if ((real_location == upstairs_landing) || (real_location == foyer)) <>; else "There is nothing to climb down to."; ]; Extend 'climb' first * 'down' -> ClimbDown; [ LockSimpleSub k; if (noun has lockable) { if (noun.with_key_type == nothing) "You do not have the key."; k = GetHeld(noun.with_key_type); if (k == nothing) "You do not have the key."; <>; } else "That doesn't seem to be something you can lock."; ]; Extend 'lock' first * noun -> LockSimple; [ UnlockSimpleSub k; if (noun has lockable) { if (noun.with_key_type == nothing) "You do not have the key."; k = GetHeld(noun.with_key_type); if (k == nothing) "You do not have the key."; <>; } else "That doesn't seem to be something you can unlock."; ]; Extend 'unlock' first * noun -> UnlockSimple; [ UseSub; "You will have to be more specific about your action."; ]; Verb 'use' * -> Use * noun -> Use; [ PlantSub p; p = parent(noun); ; if (parent(noun) ~= p) if (noun ofclass Bomb_) if (noun.time_value == NA_) "(you may also want to set the timer)"; ]; [ PlantInSub p; p = parent(noun); ; if (parent(noun) ~= p) if (noun ofclass Bomb_) if (noun.time_value == NA_) "(you may also want to set the timer)"; ]; [ PlantOnSub p; p = parent(noun); ; if (parent(noun) ~= p) if (noun ofclass Bomb_) if (noun.time_value == NA_) "(you may also want to set the timer)"; ]; Verb 'plant' * noun -> Plant * noun 'in' noun -> PlantIn * noun 'on' noun -> PlantOn; Extend 'look' * noun -> Examine; [ WaitSecondsSub t; if (noun == 0) { instant_action_this_turn = true; "That didn't take long."; } if (noun < 0) { instant_action_this_turn = true; "If you could do that, you wouldn't have built the prototype."; } print "Time passes.^"; if (noun%5 ~= 0) { if (noun/5 > 0) IncTime(); } for (t=1 : t FINAL_TIME - my_time) time_in_turns = FINAL_TIME - my_time + 2; if (time_in_turns == 0 && (noun%5 ==0)) { instant_action_this_turn = true; "That didn't take long."; } if (time_in_turns < 0) { instant_action_this_turn = true; "If you could do that, you wouldn't have built the prototype."; } print "Time passes.^"; if (noun%5 ~= 0) { if (time_in_turns > 0) IncTime(); } for (t=1 : t= 24) return -1; if (minute >= 60) return -1; if (second >= 60) return -1; if (hour > 4) return 18000; ! this is to avoid integer overflow if (word == 'pm') return 18000; return (hour*60 + minute) * 60 + second; ]; ! based on the code from the DM4. ! looks for a time in the format 2:39 or 4:17:18 [ TimeOfDay first_word second_word at length colons illegal_char digits hr mn se i; first_word = NextWordStopped(); if (first_word == -1) return GPR_FAIL; at = WordAddress(wn-1); length = WordLength(wn-1); for (i=0: ii) { ':': if (colons == 0 && digits>0 && i 2) illegal_char = true; default: illegal_char = true; } } if (length < 3 || length > 8 || illegal_char || colons == 0) return GPR_FAIL; for (i=0: at->i~=':': i++, hr=hr*10) hr = hr + at->i - '0'; hr = hr/10; mn = ((at->(i+1) - '0') * 10) + at->(i+2) - '0'; if (colons == 2) { i = i+3; se = ((at->(i+1) - '0') * 10) + at->(i+2) - '0'; } second_word = NextWordStopped(); parsed_number = HoursMinsSecsWordToTime(hr, mn, se, second_word); if (parsed_number == -1) return GPR_FAIL; if (second_word ~= 'pm' or 'am') wn--; return GPR_NUMBER; ]; Extend 'wait' * number -> WaitSeconds * number 'seconds' -> WaitSeconds * number 'second' -> WaitSeconds * number 'turns' -> WaitTurns * number 'turn' -> WaitTurns * 'until' TimeOfDay -> WaitUntil; [ ShoutSub t; print "You shout loudly.^"; for (t=0 : tt notin limbo) && ((siren_start_time == UNKNOWN_) || (siren_start_time > my_time))) { d_paradox = true; deadflag = 3; Seperator(); print (Nearby) 0, "your former self hears the muffled sounds of your shouting.^^Something of an anticlimactic way to kill so many millions of people...^"; print "^Time unravels...^"; Devours(my_time); return true; } } Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,SHOUT_); MaybeSing(); return true; ]; Extend only 'shout' replace * -> Shout * topic -> Shout; Verb 'yell' * -> Shout * topic -> Shout; Verb 'tear' * noun -> Attack * 'up' noun -> Attack; Extend 'remove' first ! so that 'remove battery' works * multiinside -> Remove; [ HoldDownWithSub; if (noun == alarm_button || noun == basement_button || noun == first_button || noun == second_button || noun == silver_button || noun == exit_button ) { "The button is set into a vertical surface, making it impossible to hold it down with another object."; } else "It is not clear what that is supposed to accomplish."; ]; Extend 'hold' first ! so that 'remove battery' works * 'down' noun -> Push * 'down' noun 'with' noun -> HoldDownWith * 'down' noun 'using' noun -> HoldDownWith; [ ChallengeSub; instant_action_this_turn = true; if (challenge) "The challenge has already been initiated."; if (first_turn) { challenge = true; siren_timeout = CHALLENGE_SIREN_TIMEOUT; early_guard_time = CHALLENGE_EARLY_GUARD_TIME; "The game is now in its most challenging form. Three key elements have been changed to make success considerably more difficult. This challenge is not required for a successful completion of the game. It is just here for those who, upon finishing, wish there was a little bit more.^ ^ If you do want to take up the challenge, then remember to initiate this mode each time you begin play."; } else "The challenge can only be initiated in the first turn."; ]; [ EndChallengeSub; instant_action_this_turn = true; challenge = false; siren_timeout = DEFAULT_SIREN_TIMEOUT; early_guard_time = EARLIEST_TIME; "The game is now at its standard difficulty."; ]; Verb 'challenge' * -> Challenge * 'on' -> Challenge * 'mode' 'on' -> Challenge * 'off' -> EndChallenge * 'mode' 'off' -> EndChallenge; Verb 'start' 'begin' 'initiate' * 'challenge' -> Challenge * 'challenge' 'mode' -> Challenge; Verb 'end' * 'challenge' -> EndChallenge * 'challenge' 'mode' -> EndChallenge; !============================================================================