| !% +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 : t<time_travelled : t++) { | |
| if ((former_self-->t 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: | |
| <<Examine self>>; | |
| ], | |
| 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; | |
| <Open self>; | |
| 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; | |
| <Unlock door (GetHeld(door.with_key_type))>; | |
| 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; | |
| <Close door>; | |
| 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 self>>; | |
| 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)) { | |
| <Look>; | |
| 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: | |
| <<Take noun>>; | |
| ], | |
| 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) | |
| <<Tie prototype>>; | |
| if (second == nothing) | |
| if (real_location == deutsch_lab or prototype_interior) | |
| <<Tie prototype>>; | |
| 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) | |
| <<Go u_obj>>; | |
| 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 [;<<Examine ground_door>>;], | |
| 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)) | |
| <<Attack self>>; | |
| 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: | |
| <<Examine self>>; | |
| ], | |
| 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) | |
| <<Set control_panel>>; | |
| } | |
| 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) | |
| <<SetTo control_panel second>>; | |
| } | |
| 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)^"; | |
| <<Push silver_button>>; | |
| } | |
| } | |
| else | |
| "You will need to complete the partial modifications to use the prototype."; | |
| Enter: | |
| <<Go in_obj>>; | |
| Exit: | |
| if (real_location == prototype_interior) | |
| <<Go out_obj>>; | |
| 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)^"; | |
| <Go in_obj>; | |
| 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)^"; | |
| <<Go in_obj>>; | |
| } | |
| else | |
| <<Look>>; | |
| ], | |
| react_before[; | |
| Insert: | |
| if (~~(self.fixed)) | |
| if (IsOfType(noun,cable)) | |
| if ((second == self) || (second == control_panel)) | |
| <<Tie prototype>>; | |
| 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 | |
| <<Drop noun>>; | |
| } | |
| ], | |
| 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: | |
| <<Examine self>>; | |
| ], | |
| 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: | |
| <<Tie prototype>>; | |
| 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: | |
| <<Tie prototype>>; | |
| 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)^"; | |
| <<Push 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 [;<<Go w_obj>>;], | |
| 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 basement_light_switch>>; | |
| 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 [;<<Go w_obj>>;], | |
| 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) { | |
| <<SwitchOn ground_light_switch>>; | |
| } | |
| else { | |
| <<SwitchOff ground_light_switch>>; | |
| } | |
| SwitchOn: | |
| if (~~ground_equipment.lit) { | |
| ground_equipment.lit = true; | |
| give self on; | |
| print "The lights come on after a brief flicker.^"; | |
| <Look>; | |
| 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: | |
| <<Go n_obj>>; | |
| ], | |
| 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)^"; | |
| <<Push exit_button>>; | |
| Unlock: | |
| if (IsOfType(second,crowbar)) | |
| <<Attack self>>; | |
| else | |
| "You cannot open the door with that."; | |
| Enter: | |
| if (self hasnt open) { | |
| print "(first pressing the green exit button)^"; | |
| <Push exit_button>; | |
| IncTime(); | |
| if (Stopped()) return true; | |
| <<Go s_obj>>; | |
| } | |
| ], | |
| react_before [; Go: | |
| if (noun == s_to && self hasnt open) | |
| <<Enter self>>; | |
| ], | |
| 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)) | |
| <<Attack self>>; | |
| else if (IsOfType(second,id_card) && (self in foyer)) | |
| <<Insert second id_slot>>; | |
| 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'.^"; | |
| <<Push first_button>>; | |
| } | |
| if (self in ground_corridor) { | |
| print "(pressing the green exit button)^"; | |
| <<Push exit_button>>; | |
| } | |
| Enter: | |
| if (self in ground_corridor && self hasnt open) { | |
| print "(first pressing the green exit button)^"; | |
| <Push exit_button>; | |
| IncTime(); | |
| if (Stopped()) return true; | |
| <<Go s_obj>>; | |
| } | |
| if (self in foyer && self hasnt open) { | |
| if (self.known_exterior_opening == true) { | |
| print "(first pressing the button marked 'first')^"; | |
| <Push first_button>; | |
| IncTime(); | |
| if (Stopped()) return true; | |
| <<Go n_obj>>; | |
| } | |
| 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) | |
| <<Enter self>>; | |
| if (noun == s_to && self in ground_corridor && self hasnt open) | |
| <<Enter self>>; | |
| ], | |
| 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)) | |
| <<Attack self>>; | |
| else if (IsOfType(second,id_card) && (self in basement_landing)) | |
| <<Insert second id_slot>>; | |
| else | |
| "You cannot open the door with that."; | |
| Open: | |
| if (self in basement_landing) { | |
| if ( AmHolding(id_card) ) { | |
| print "(inserting your ID card)^"; | |
| <<Insert (GetHeld(id_card)) id_slot>>; | |
| } | |
| else | |
| "You would need you ID card to do that."; | |
| } | |
| if (self in basement_corridor) { | |
| print "(pressing the green exit button)^"; | |
| <<Push exit_button>>; | |
| } | |
| Enter: | |
| if (self in basement_corridor && self hasnt open) { | |
| print "(first pressing the green exit button)^"; | |
| <Push exit_button>; | |
| IncTime(); | |
| if (Stopped()) return true; | |
| <<Go s_obj>>; | |
| } | |
| if (self in basement_landing && self hasnt open) { | |
| if ( AmHolding(id_card) ) { | |
| print "(first inserting your ID card)^"; | |
| <Insert (GetHeld(id_card)) id_slot>; | |
| IncTime(); | |
| if (Stopped()) return true; | |
| <<Go n_obj>>; | |
| } | |
| else | |
| "You would need you ID card to do that."; | |
| } | |
| ], | |
| react_before [; Go: | |
| if (noun == n_to && self in basement_landing && self hasnt open) | |
| <<Enter self>>; | |
| if (noun == s_to && self in basement_corridor && self hasnt open) | |
| <<Enter self>>; | |
| ], | |
| 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)) | |
| <<Attack self>>; | |
| else if (IsOfType(second,id_card) && (self in upstairs_landing)) | |
| <<Insert second id_slot>>; | |
| else | |
| "You cannot open the door with that."; | |
| Open: | |
| if (self in upstairs_landing) | |
| if (AmHolding(id_card)) { | |
| print "(inserting your ID card)^"; | |
| <<Insert (GetHeld(id_card)) id_slot>>; | |
| } | |
| if (self in upstairs_corridor) { | |
| print "(pressing the green exit button)^"; | |
| <<Push exit_button>>; | |
| } | |
| Enter: | |
| if (self in upstairs_corridor && self hasnt open) { | |
| print "(first pressing the green exit button)^"; | |
| <Push exit_button>; | |
| if (self has open) { | |
| IncTime(); | |
| if (Stopped()) return true; | |
| <<Go s_obj>>; | |
| } | |
| 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) | |
| <<Enter self>>; | |
| ], | |
| 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)) | |
| <<Attack self>>; | |
| 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)) | |
| <<Attack self>>; | |
| 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)) | |
| <<Attack self>>; | |
| 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)) | |
| <<Attack self>>; | |
| 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: | |
| <<Examine self>>; | |
| ], | |
| 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)) | |
| <<Attack self>>; | |
| 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: | |
| <<Examine self>>; | |
| ], | |
| 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 : i<e : i++) | |
| result = result * b; | |
| return result; | |
| ]; | |
| !---------------------------------------------------- | |
| ! | |
| ! 'Observe' functions: (these make note of current state of things) | |
| [ObserveBombs i; | |
| for (i=0 : i < MAX_ITEM_COPIES : i++) { | |
| Put3D(bomb_setting, time_travelled, (my_time - EARLIEST_TIME), i, (bomb-->i).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 "<<<Missing bomb of former time setting.>>>^"; | |
| } | |
| } | |
| ! else | |
| ! print "<<<Missing ", (name) bomb-->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 "<<<Missing flashlight of former time setting.>>>^"; | |
| } | |
| } | |
| ! else | |
| ! print "<<<Missing ", (name) flashlight-->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 : t<time_travelled : t++) { | |
| past_door_status_now = Get2D(door_state, t, my_time - EARLIEST_TIME - 1); | |
| past_door_status_next = Get2D(door_state, t, my_time - EARLIEST_TIME); | |
| present_door_status_now = Get2D(door_state, time_travelled, my_time - EARLIEST_TIME - 1); | |
| the_action = Get2D(dangerous_activity, t, my_time - EARLIEST_TIME - 1); | |
| !-- if there was a locking/unlocking, check for paradox: | |
| if (Get2D(activity_target, t, my_time - EARLIEST_TIME - 1) == door) { | |
| if (the_action == UNLOCK_) { | |
| if ((present_door_status_now == CLOSED_) && (past_door_status_now == LOCKED_)) { | |
| d_paradox = true; | |
| deadflag = 3; | |
| Seperator(); | |
| print (Nearby) 0, "your past self attempts to unlock ", (the) door, | |
| " but finds it already unlocked.^"; | |
| print "^Time unravels...^"; | |
| Devours(my_time); | |
| } | |
| else if ((present_door_status_now == LOCKED_) && (past_door_status_now == CLOSED_)) { | |
| d_paradox = true; | |
| deadflag = 3; | |
| Seperator(); | |
| print (Nearby) 0, "your past self foolishly attempts to unlock ", (the) door, | |
| " and succeeds where you had originally found it already unlocked.^"; | |
| print "^Time unravels...^"; | |
| Devours(my_time); | |
| } | |
| } | |
| if (the_action == LOCK_) { | |
| if ((present_door_status_now == CLOSED_) && (past_door_status_now == LOCKED_)) { | |
| d_paradox = true; | |
| deadflag = 3; | |
| Seperator(); | |
| print (Nearby) 0, "your past self foolishly attempts to lock ", (the) door, | |
| " and succeeds where you had originally found it already locked.^"; | |
| print "^Time unravels...^"; | |
| Devours(my_time); | |
| } | |
| if ((present_door_status_now == LOCKED_) && (past_door_status_now == CLOSED_)) { | |
| d_paradox = true; | |
| deadflag = 3; | |
| Seperator(); | |
| print (Nearby) 0, "your past self attempts to lock ", (the) door, | |
| " but finds it already locked.^"; | |
| print "^Time unravels...^"; | |
| Devours(my_time); | |
| } | |
| } | |
| if (the_action == OPEN_) { | |
| if ((present_door_status_now == CLOSED_) && (past_door_status_now == LOCKED_)) { | |
| d_paradox = true; | |
| deadflag = 3; | |
| Seperator(); | |
| print (Nearby) 0, "your past self foolishly attempts to open ", (the) door, | |
| " and succeeds where you had originally found it locked.^"; | |
| print "^Time unravels...^"; | |
| Devours(my_time); | |
| } | |
| if ((present_door_status_now == LOCKED_) && (past_door_status_now == CLOSED_)) { | |
| d_paradox = true; | |
| deadflag = 3; | |
| Seperator(); | |
| print (Nearby) 0, "your past self attempts to open ", (the) door, | |
| " but finds it locked.^"; | |
| print "^Time unravels...^"; | |
| Devours(my_time); | |
| } | |
| } | |
| } | |
| !-- if there should be a state change, do it: | |
| if (~~d_paradox) { | |
| if ((past_door_status_now ~= past_door_status_next) && (past_door_status_next ~= UNKNOWN_)) { | |
| if (past_door_status_now == present_door_status_now) { | |
| if (past_door_status_next == LOCKED_) { | |
| give door ~open; | |
| give door locked; | |
| if (door in real_location) | |
| print "You hear someone locking the ", (name) door, ".^"; | |
| } | |
| if (past_door_status_next == CLOSED_) { | |
| give door ~open; | |
| give door ~locked; | |
| if (door in real_location && past_door_status_now == LOCKED_) | |
| print "You hear someone unlocking the ", (name) door, ".^"; | |
| if (door in real_location && past_door_status_now == OPEN_) | |
| print "Someone closes ", (name) door, ".^"; | |
| } | |
| if (past_door_status_next == OPEN_) { | |
| give door open; | |
| give door ~locked; | |
| if (door in real_location) | |
| print "Someone opens the ", (name) door, ".^"; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| ]; | |
| [MaybeSetAutomaticDoor door door_state door_status_now door_status_next; | |
| door_status_now = Get2D(door_state, time_travelled - 1, my_time - EARLIEST_TIME - 1); | |
| door_status_next = Get2D(door_state, time_travelled - 1, my_time - EARLIEST_TIME); | |
| if (door_status_next == my_time) { | |
| door.open_self(my_time); | |
| } | |
| if ((door == main_doors) && (my_time == start_time - 1)) { | |
| door.open_self(my_time); | |
| } | |
| ]; | |
| [MaybeBreakDoor door door_smashed door_smashed_next; | |
| door_smashed_next = Get2D(door_smashed, time_travelled - 1, my_time - EARLIEST_TIME); | |
| if (door_smashed_next && (~~door.smashed)) { | |
| door.smashed = true; | |
| } | |
| ]; | |
| !---------------------------------------------------- | |
| ! | |
| ! 'Check' functions: (these check for paradoxes, both active and passive) | |
| [CheckActiveParadox t action_de_jour trouble i j k flash_i_batteries flash_j_loc flash_j_batteries | |
| past_count present_count too_heavy; | |
| action_de_jour = Get2D(dangerous_activity, t, my_time-EARLIEST_TIME-1); | |
| trouble = false; | |
| for (t=0 : t < time_travelled : t++) { | |
| if (~~d_paradox) { | |
| switch (action_de_jour) { | |
| X_CCTV_: | |
| if (player in upstairs_corridor or ground_corridor or basement_corridor) | |
| trouble = true; | |
| X_UPSTAIRS_CORRIDOR_: | |
| if (player in upstairs_corridor) | |
| trouble = true; | |
| X_UPSTAIRS_LANDING_: | |
| if (player in upstairs_landing) | |
| trouble = true; | |
| X_GROUND_CORRIDOR_: | |
| if (player in ground_corridor) | |
| trouble = true; | |
| X_FOYER_: | |
| if (player in foyer) | |
| trouble = true; | |
| X_BASEMENT_CORRIDOR_: | |
| if (player in basement_corridor) | |
| trouble = true; | |
| X_BASEMENT_LANDING_: | |
| if (player in basement_landing) | |
| trouble = true; | |
| X_BALCONY_: | |
| if (player in balcony) | |
| trouble = true; | |
| TAKE_FLASHLIGHT_: | |
| for (i=0 : i<MAX_ITEM_COPIES : i++) { | |
| if ((flashlight-->i) 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 : k<MAX_ITEM_COPIES : k++) { | |
| if (Get3D(battery_loc,t,my_time-EARLIEST_TIME,k) == (flashlight-->j)) | |
| 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 : (t<TIME_BEFORE_DRAGGED_OFF) && (my_time<FINAL_TIME) && (~~d_exploded) : t++) { | |
| IncTime(); ! as it happens, this can lead to bomb-explosion, but not paradox | |
| } | |
| if (~~d_exploded) ! make sure player is dragged off | |
| DragPlayerOff(); | |
| ]; | |
| [Jumped; | |
| if (~~warned_of_jump) { | |
| print "It is a large drop and you are not at all sure that you could make it | |
| without serious injury.^"; | |
| warned_of_jump = true; | |
| return true; | |
| } | |
| d_caught = true; | |
| !-- Initial method of being caught: | |
| print "You hit the ground hard and collapse. Your right ankle sears with pain. | |
| Before you can stand, you see the security guard running swiftly towards you.^"; | |
| DragPlayerOff(); | |
| ]; | |
| [DragPlayerOff t; | |
| print "^Deaf to your protests, the guard "; | |
| if (AmHolding(bomb) && ((GetHeld(bomb)).time_value ~= NA_)) | |
| print "disarms your bomb, "; | |
| print "handcuffs you and forces you | |
| into a dark sedan. You speed through the chill Boston night, head held in your hands, | |
| almost oblivious to the blur of the suburbs rushing past.^"; | |
| d_detained = true; | |
| move player to limbo; | |
| !-- Allow some more time for bomb to explode | |
| !-- and for paradoxes to occur | |
| for (t=0 : (my_time<FINAL_TIME) && (~~d_exploded) && (~~d_paradox) : t++) { | |
| IncTime(); | |
| } | |
| MaybeExplodeBombAfterwards(); | |
| deadflag = 3; | |
| !-- Consequences of being caught: | |
| if (~~d_paradox) { | |
| print "^Half an hour later, the car pulls up outside a non-descript building and you | |
| are dragged inside"; | |
| if (AmHolding(notes)) | |
| print ", the notes are taken from you and you are "; | |
| else | |
| print " then "; | |
| print "thrown into a small cell to await questioning.^"; | |
| if (d_exploded) { | |
| if (d_destroyed_prototype && d_destroyed_notes) { | |
| print "^The months that follow are a nightmare. Solitary confinement, sleepless nights, | |
| merciless interrogations. Eventually, you are taken before a civilian court and | |
| tried for treason. A drawn-out trial, a guilty verdict, prison. Ambitions falter and | |
| then fade. Still, as the months and then years pass, they do not bring the disaster | |
| you had so feared and you cling, anxiously, longingly, to the dream that it was you who brought | |
| this about, that your sacrifice was not in vain.^"; | |
| my_time = NA_; | |
| DrawStatusLine(); | |
| deadflag = SAVED_CAUGHT_; | |
| } | |
| ! else if (d_destroyed_prototype && AmHolding(notes)) { | |
| ! } | |
| else if (d_destroyed_prototype) { | |
| print "^The days that follow are a nightmare. Solitary confinement, sleepless nights, | |
| merciless interrogations. All that keeps you going is the small hope that your actions | |
| were not in vain.^"; | |
| Seperator(); | |
| print "With your research notes at hand, the military scientists painstakingly rebuild the | |
| prototype and prepare it for testing.^"; | |
| } | |
| ! else if (d_destroyed_notes) { | |
| ! print " "; | |
| ! } | |
| ! else if (AmHolding(notes)) { | |
| ! print " "; | |
| ! } | |
| ! else { | |
| ! print " "; | |
| ! } | |
| } | |
| ! else if (AmHolding(bomb) && AmHolding(notes)) { | |
| ! print " "; | |
| ! } | |
| ! else if (AmHolding(bomb)) { | |
| ! print " "; | |
| ! } | |
| ! else if (AmHolding(notes)) { | |
| ! print " "; | |
| ! } | |
| ! else { | |
| ! print " "; | |
| ! } | |
| if ((~~d_destroyed_prototype) || (~~d_destroyed_notes)) | |
| MilitaryTest(); | |
| } | |
| ]; | |
| [InBlastRadius thing bomb; | |
| if (LocationOf(thing) == LocationOf(bomb)) | |
| return true; | |
| if ((LocationOf(bomb) == deutsch_lab) && (LocationOf(thing) == prototype_interior)) | |
| return true; | |
| if ((LocationOf(bomb) == prototype_interior) && (LocationOf(thing) == deutsch_lab)) | |
| return true; | |
| return false; | |
| ]; | |
| [MaybeExplodeBombAfterwards i j; | |
| if (~~d_exploded) | |
| for (i=0 : i<MAX_ITEM_COPIES : i++) | |
| if (((bomb-->i).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) && (~~d_paradox) : t++) { | |
| IncTime(); | |
| } | |
| deadflag = 3; | |
| if ((~~d_paradox) && d_destroyed_prototype && d_destroyed_notes) { | |
| my_time = NA_; | |
| DrawStatusLine(); | |
| deadflag = SAVED_DEAD_; | |
| } | |
| else | |
| MilitaryTest(); | |
| } | |
| } | |
| else if (d_injured_by_bomb) { | |
| print "^The bomb detonates. You are knocked to the floor by the force of the | |
| explosion and your ears ring. "; | |
| if (~~d_fs_hears_bomb) { | |
| print "Stunned, you lie prone on the floor as | |
| the siren wails and the reek of smoke stings your nostrils.^^ | |
| Before you recover your senses, security is upon you.^"; | |
| DragPlayerOff(); | |
| } | |
| else | |
| print "^"; | |
| } | |
| if (d_fs_killed_by_bomb) { | |
| Seperator(); | |
| if (d_detained || d_escaped) | |
| print "Across town, the bomb detonates. | |
| The explosion tears into your former self and she falls lifeless to | |
| the ground.^"; | |
| else | |
| print (Nearby) 0, "the explosion tears into your former self and she falls lifeless to | |
| the ground.^"; | |
| print "^Time unravels...^"; | |
| Devours(my_time); | |
| } | |
| else if (d_fs_hears_bomb) { | |
| Seperator(); | |
| if (d_detained || d_escaped) | |
| print "Across town, the bomb detonates. | |
| Your former self is brought to her knees by the sudden blast, | |
| the horror of understanding written in her eyes.^"; | |
| else | |
| print (Nearby) 0, "your former self is brought to her knees by the sudden blast, | |
| the horror of understanding written in her eyes.^"; | |
| print "^Time unravels...^"; | |
| Devours(my_time); | |
| } | |
| ]; | |
| [Escaped t; | |
| d_escaped = true; | |
| move player to outside; | |
| !-- result of escaping: | |
| print "^"; | |
| if (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<FINAL_TIME) && (~~d_paradox) : t++) { | |
| IncTime(); | |
| } | |
| MaybeExplodeBombAfterwards(); | |
| deadflag = 3; | |
| !-- Final wrap-up: | |
| if (~~d_paradox) { | |
| if (d_exploded) { | |
| if (d_destroyed_prototype && d_destroyed_notes) { | |
| print "^Days, months, years run by. | |
| You find a new name, a new life. | |
| Fresh challenges are gladly met and life proceeds with full force in its | |
| new and welcome direction. | |
| Only now and then do you stop on a chill starry night and | |
| wonder whether you were right, what really would have happened.^"; | |
| my_time = NA_; | |
| DrawStatusLine(); | |
| deadflag = SAVED_FREE_; | |
| } | |
| else if (d_destroyed_prototype && AmHolding(notes) && challenge) { | |
| print "^Days, months, years run by. | |
| You find a new name, a new life. | |
| You travel abroad. | |
| Eventually, you look again at your time-stained research notes | |
| and think of the possibilities.^^ | |
| The inconsistencies are the key; the freed energy. | |
| Maybe now, without the shadow of military interests, you could | |
| make something of this.^"; | |
| my_time = NA_; | |
| DrawStatusLine(); | |
| deadflag = SAVED_FREE_CHALLENGE_; | |
| } | |
| else if (d_destroyed_prototype && AmHolding(notes)) { | |
| print "^Days, months, years run by. | |
| You find a new name, a new life. | |
| Fresh challenges are gladly met and life proceeds with full force in its | |
| new and welcome direction. | |
| Only now and then do you stop on a chill starry night and | |
| wonder whether you were right, what really would have happened.^"; | |
| my_time = NA_; | |
| DrawStatusLine(); | |
| deadflag = SAVED_FREE_; | |
| } | |
| else if (d_destroyed_prototype) { | |
| print "^Days run by. You find a new name, begin a new life. | |
| You hope, pray, that all you have done will stop them, that the | |
| catastrophe will not come.^"; | |
| Seperator(); | |
| print "With your research notes at hand, the military scientists painstakingly rebuild the | |
| prototype and prepare it for testing.^"; | |
| deadflag = DELAYED_; | |
| } | |
| ! else if (d_destroyed_notes) { | |
| ! print "^Escape: ~d-prototype + d-notes.^"; | |
| ! } | |
| ! else if (AmHolding(notes)) { | |
| ! print "^Escape: useless explosion + holding notes.^"; | |
| ! } | |
| else { | |
| print "^Morning finds you in a truck-stop cafe, near Woodstock, NY. You sit there, | |
| anxiously watching the morning news as you sip your bitter coffee.^"; | |
| } | |
| } | |
| ! else if (AmHolding(bomb) && AmHolding(notes)) { | |
| ! print "^Escape: holding bomb + notes.^"; | |
| ! } | |
| ! else if (AmHolding(bomb)) { | |
| ! print "^Escape: holding bomb.^"; | |
| ! } | |
| ! else if (AmHolding(notes)) { | |
| ! print "^Escape: holding notes.^"; | |
| ! } | |
| else { | |
| print "^Morning finds you in a truck-stop cafe, near Woodstock, NY. You sit there, | |
| anxiously watching the morning news as you sip your bitter coffee.^"; | |
| } | |
| if (~~(d_destroyed_prototype && (d_destroyed_notes || AmHolding(notes)))) { | |
| MilitaryTest(); | |
| } | |
| } | |
| } | |
| ]; | |
| ! tests whether something has happened to stop the player continuing their actions | |
| [Stopped; | |
| if (d_paradox || d_caught || d_exploded || d_escaped) | |
| return true; | |
| else | |
| return false; | |
| ]; | |
| [Seperator; | |
| print "^*******^^"; | |
| ]; | |
| [MilitaryTest; | |
| Devours(LATER_); | |
| ]; | |
| [Devours given_time explosion_time; | |
| Seperator(); | |
| if (given_time == LATER_) { | |
| if (d_destroyed_prototype) { | |
| print "Monday 1st November 2004^^"; | |
| explosion_time = EXPERIMENT2_TIME; | |
| deadflag = DELAYED_; | |
| } | |
| else { | |
| print "Wednesday 13th October 2004^^"; | |
| explosion_time = EXPERIMENT1_TIME; | |
| deadflag = USELESS_; | |
| } | |
| } | |
| else { | |
| print "Tuesday 12th October 2004^^"; | |
| deadflag = ACCELERATED_; | |
| explosion_time = last_travel_time; | |
| } | |
| !my_time = explosion_time; ! these lines would update the status line time | |
| !DrawStatusLine(); | |
| if (poem_interleaving) { | |
| print "At precisely ", (PrintShortTime) explosion_time, " this morning "; | |
| PoemStyleOn(); | |
| print "This thing all things devours: "; | |
| PoemStyleOff(); | |
| print "a catastrophe of unprecedented scale occurred. "; | |
| PoemStyleOn(); | |
| print "birds, beasts, trees, flowers; "; | |
| PoemStyleOff(); | |
| print "An immense explosion -- that could only have been atomic in nature -- "; | |
| PoemStyleOn(); | |
| print "gnaws iron, bites steel; "; | |
| PoemStyleOff(); | |
| print "tore through the city and suburbs of Boston MA, destroying all in its path. "; | |
| PoemStyleOn(); | |
| print "grinds hard stones to meal; "; | |
| PoemStyleOff(); | |
| print "Casualties will number in the millions and martial law has been declared. "; | |
| PoemStyleOn(); | |
| print "slays king, ruins town; "; | |
| PoemStyleOff(); | |
| print "The military is mobilizing for war with the as yet unknown enemy. "; | |
| PoemStyleOn(); | |
| print "and beats high mountain down. "; | |
| PoemStyleOff(); | |
| print "^"; | |
| } | |
| else { | |
| print "At precisely ", (PrintShortTime) explosion_time, " this morning | |
| a catastrophe of unprecedented scale occurred. | |
| An immense explosion -- that could only have been atomic in nature -- | |
| tore through the city and suburbs of Boston MA, destroying all in its path. | |
| Casualties are expected to number in the millions. The President has declared | |
| a state of emergency across the nation and | |
| the military is mobilizing for a possible war with the as yet unknown enemy.^^"; | |
| PoemStyleOn(); | |
| print "This thing all things devours:^"; | |
| print "birds, beasts, trees, flowers;^"; | |
| print "gnaws iron, bites steel;^"; | |
| print "grinds hard stones to meal;^"; | |
| print "slays king, ruins town;^"; | |
| print "and beats high mountain down.^"; | |
| PoemStyleOff(); | |
| } | |
| ]; | |
| [PoemStyleOn; | |
| style bold; | |
| ]; | |
| [PoemStyleOff; | |
| style roman; | |
| ]; | |
| [ DeathMessage; | |
| switch (deadflag) { | |
| ACCELERATED_: print "You have failed"; | |
| USELESS_: print "You have failed"; | |
| DELAYED_: print "You have failed"; | |
| SAVED_DEAD_: print "Success, but at such a cost"; | |
| SAVED_CAUGHT_: print "Success, but at such a cost"; | |
| SAVED_FREE_: print "Success. Final, lasting success."; | |
| SAVED_FREE_CHALLENGE_: print "Success and, perhaps, a new hope."; | |
| } | |
| ]; | |
| [Nearby; | |
| if (~~(player in limbo)) | |
| print "Nearby, "; | |
| else | |
| print "Back at the lab, "; | |
| ]; | |
| [TheLower room; | |
| print (string) room.lower_name; | |
| ]; | |
| !============================================================================ | |
| ! Include "../Contrib/Scenic"; | |
| !============================================================================ | |
| ! Standard and extended grammar | |
| Include "Grammar"; | |
| !---------------------------------------------------------------------------- | |
| [ AboutSub; | |
| instant_action_this_turn = true; | |
| print "^All Things Devours is a short piece of interactive fiction, leaning strongly | |
| towards the text-adventure end of the spectrum. It explores an all-too-familiar | |
| science fiction paradigm in what I hope is a rather refreshing and satisfying manner. | |
| However, due to the intrinsic nature of its subject matter, it is more cruel | |
| than one might hope for a modern piece of interactive fiction. In particular, | |
| any move you make may put things into an unwinnable state. You are therefore encouraged | |
| to save frequently, and also to realise that you will probably have to start over several times | |
| to find the most satisfactory ending.^^ | |
| Hints, reviews and more can be found at http://devours.amirrorclear.net^"; | |
| ]; | |
| Verb 'about' | |
| * 'game' -> 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)) | |
| <<Tie prototype>>; | |
| 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)) | |
| <<Tie prototype>>; | |
| 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) | |
| <<SwitchOff noun>>; | |
| else | |
| <<SwitchOn noun>>; | |
| ]; | |
| 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)) | |
| <<Attack second>>; | |
| else if ((second == conference_window) || (second ofclass AutomaticDoor)) { | |
| print_ret (The) noun, " bounces harmlessly off the ", | |
| (the) second, "."; | |
| } | |
| else | |
| <<Attack noun>>; | |
| ]; | |
| Extend 'swing' first | |
| * held -> SwingAt | |
| * held 'at' noun -> SwingAt | |
| * held 'into' noun -> SwingAt | |
| * held 'through' noun -> SwingAt; | |
| [ AttackWithSub; if (IsOfType(second, crowbar)) | |
| <<Attack noun>>; | |
| 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 | |
| <<Attack noun>>; | |
| ]; | |
| 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.^"; | |
| <<Go d_obj>>; | |
| } | |
| 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)) | |
| <<Go d_obj>>; | |
| 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."; | |
| <<Lock noun k>>; | |
| } | |
| 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."; | |
| <<Unlock noun k>>; | |
| } | |
| 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); | |
| <Drop 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); | |
| <Insert noun second>; | |
| 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); | |
| <PutOn noun second>; | |
| 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<noun/5 : t++) | |
| IncTime(); | |
| if (~~deadflag) | |
| if (noun%5 ~= 0) | |
| print "Indeed you pause for slightly longer than you had planned, | |
| carefully resynchronizing yourself with the | |
| five second turn increments.^"; | |
| ]; | |
| [ WaitTurnsSub t; | |
| if (noun == 0) { | |
| instant_action_this_turn = true; | |
| "That didn't take long."; | |
| } | |
| print "Time passes.^"; | |
| if (noun < 0) { | |
| instant_action_this_turn = true; | |
| "If you could do that, you wouldn't have built the prototype."; | |
| } | |
| for (t=1 : t<noun : t++) | |
| IncTime(); | |
| ]; | |
| [ WaitUntilSub time_in_turns t; | |
| time_in_turns = noun / 5 - my_time; | |
| if (time_in_turns > 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<time_in_turns : t++) | |
| IncTime(); | |
| if (~~deadflag) | |
| if (noun%5 ~= 0) | |
| print "Indeed you pause for slightly longer than you had planned, | |
| carefully resynchronizing yourself with the | |
| five second turn increments.^"; | |
| ]; | |
| [ HoursMinsSecsWordToTime hour minute second word; | |
| if (hour >= 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: i<length: i++) { | |
| switch (at->i) { | |
| ':': if (colons == 0 && digits>0 && i<length-1) { | |
| colons = 1; | |
| digits = 0; | |
| } | |
| else if (colons == 1 && digits==2 && i<length-1) { | |
| colons = 2; | |
| digits = 0; | |
| } | |
| else | |
| illegal_char = true; | |
| '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': | |
| digits = digits+1; | |
| if (digits > 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 : t<time_travelled : t++) { | |
| if ((former_self-->t 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; | |
| !============================================================================ | |
Xet Storage Details
- Size:
- 221 kB
- Xet hash:
- 1b55ebc4d0a6fb42d3ba98d816bd85415cae1400c8d798dba19e0037c194d570
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.