!% $MAX_STATIC_DATA=150000 !% $MAX_STATIC_STRINGS=20000 !============================================================================ ! 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. !===========================================================================! ! ВСЕ В ПРОШЛОМ ! ! ! ! Тоби Орд ! ! ! ! Перевод с английского, адаптация для Glulx и обложка Алексея Галкина ! ! , 2022 год. ! ! ! ! Release 2 / Serial number 220224 ! ! ! ! 12+ ! !===========================================================================! ! TODO ! - не работает команда "ждать до чч:мм:сс" ! - незапертые автоматические двери не открываются при движении на них (баг RInform?) ! - не выводится описание дверей в коридоре первого этажа по команде "о двери" ! - "дверь в аппаратную" не распознается Constant Story "Все в прошлом"; Constant Headline "^Оригинальная игра «All Things Devours» написана на IFComp 2004 (постконкурсная версия, Release 3 / Serial number 050325). ^Автор — Тоби Орд (Toby Ord ). ^Перевод с английского, адаптация для Glulx и обложка Алексея Галкина , 2022 год.^ ^Если вы играете в первый раз наберите «об игре». Для получения информации об оригинале и русскоязычной версии наберите «автор».^^"; !Release 1; ! конкурсная версия ЗОК-2022 Release 2; ! обновленная конкурсная версия 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 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; !============================================================================ Property Acc; Property Pre; Include "Parser"; Object LibraryMessages with before [; Jump: if (real_location == balcony) { Jumped(); return true; } "Ты глупо подпрыгиваешь на месте."; 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 "Ты слышишь только тихий электрический гул."; Burn: "У тебя нет источника огня."; Sing: "Ты напеваешь себе какую-то мелодию."; Miscellany: if (lm_n == 44) "Непонятно, на что ты ссылаешься."; ]; Include "VerbLib"; !============================================================================ ! Object classes Class Room with before [t; Inv, Look: if (initialising) { initialising = false; return false; } instant_action_this_turn = true; return false; Sing: for (t=0 : tt notin limbo) && ((siren_start_time == UNKNOWN_) || (siren_start_time > my_time))) { print "Ты напеваешь себе какую-то мелодию.^"; d_paradox = true; deadflag = 3; Seperator(); print (Nearby) 0, "другая ты слышит приглушенные звуки твоего пения.^^Какой-то странный способ убить миллионы людей...^"; print "^Время распадается...^"; 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 "^Пронзительно звучит сирена.^"; if (my_time - siren_start_time > 1) { if (my_time - siren_start_time <= siren_timeout) print "^Завывает сирена.^"; 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 "Ты не можешь сделать это отсюда."; ], has scenery concealed static; Class PluralSight with before [; Examine: return false; default: print_ret "Ты не можешь делать это со всеми ", (cIns) self, " сразу."; ], has scenery concealed static; Class Prop with before [; Examine: return false; default: print_ret "Тебе не нужно беспокоиться о ", (cPre) self, "."; ], has scenery concealed static; Class Furniture with before [; Take,Pull,Push,PushDir: print_ret (CCNom) self, " слишком тяжел", (AEnd) self, " для этого."; ], has static supporter; Class AutomaticDoor with before [; Take,Pull,Push,PushDir: print_ret (CCNom) self, " закреплен", (SAEnd) self, " на месте."; Lock: Close: "Как и большинство автоматических дверей эта закрывается автоматически."; Attack: if (AmHolding(crowbar)) { print "Ты крепко прикладываешься ломом к двери. Она вздрагивает, в месте удара появляются трещины, но стекло остается на месте.^"; self.smashed = true; StartSiren(); return true; } else "У тебя нет ничего достаточно тяжелого, чтобы сломать дверь."; Search: <>; ], just_closed false, smashed false, to_close_at UNKNOWN_, open_self [t; if (self hasnt open) { give self open ~locked; if (self in LocationOf(player)) print "С тихим шумом, двери раздвигаются.^"; } 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))) "Створка автоматической двери тихо закрывается."; ], has static door openable locked; Class ManualDoor with name 'двер', before [; Take,PushDir: print_ret (CCNom) self, " закреплен", (SAEnd) self, " на месте."; Attack: if (AmHolding(crowbar)) { print "Ты крепко прикладываешься ломом к двери, но он лишь оставляет на ней отметину.^"; return true; } else "У тебя нет ничего достаточно тяжелого, чтобы сломать дверь."; ], 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 "(сперва открывая ", (CAcc) self, ")^"; ks = keep_silent; keep_silent = true; ; keep_silent = ks; if (self hasnt open) rtrue; else { IncTime(); if (Stopped()) return true; } ], has static door openable lockable; [LockUnlockParadox; d_paradox = true; deadflag = 3; Seperator(); print "С другой стороны двери другая ты слышит, как ты поворачиваешь ключ в замке.^"; print "^Время распадается...^"; Devours(my_time); ]; [OpenParadox; d_paradox = true; deadflag = 3; Seperator(); print "С другой стороны, другая ты видит, как перед ней открывается дверь.^"; print "^Время распадается...^"; Devours(my_time); ]; [CloseParadox; d_paradox = true; deadflag = 3; Seperator(); print "С другой стороны, другая ты видит, как перед ней закрывается дверь.^"; print "^Время распадается...^"; Devours(my_time); ]; [OpenManualDoor door ks; if (door has locked) { if (door.with_key_type == nothing || ~~AmHolding(door.with_key_type)) "Как бы ты не старалась, ни одним из твоих ключей не открыть эту дверь."; print "(сперва отпирая ", (cAcc) door, ")^"; ks = keep_silent; keep_silent = true; ; keep_silent = ks; if (door has locked) return true; else { IncTime(); if (Stopped()) return true; } } Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,OPEN_); Put2D(activity_target,time_travelled,my_time-EARLIEST_TIME,door); return false; ]; [UnlockManualDoor door key; Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,UNLOCK_); Put2D(activity_target,time_travelled,my_time-EARLIEST_TIME,door); if (door has locked) { if ( IsOfType(key,door.with_key_type) ) { give door ~locked; if (~~keep_silent) print "Ключ плавно поворачивается в замке.^"; return true; } else "Не подходит к замку."; } return false; ]; [LockManualDoor door key ks; if (door has open) { print "(сперва закрывая ", (cAcc) door, ")^"; ks = keep_silent; keep_silent = true; ; keep_silent = ks; if (door has open) rtrue; IncTime(); if (Stopped()) return true; } Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,LOCK_); Put2D(activity_target,time_travelled,my_time-EARLIEST_TIME,door); if (door hasnt locked) { if ( IsOfType(key,door.with_key_type) ) { give door locked; if (~~keep_silent) print "Ключ плавно поворачивается в замке.^"; return true; } else "Не подходит к замку."; } return false; ]; Class FakeDoor with name 'двер', before [; Take,PushDir: print_ret (CCNom) self, " крепко закреплена."; Unlock: if (IsOfType(second,crowbar)) <>; Attack: if (AmHolding(crowbar)) { print "Ты крепко прикладываешься ломом к двери, но он лишь оставляет на ней отметину.^"; return true; } else "У тебя нет ничего достаточно тяжелого, чтобы сломать дверь."; Enter: "Дверь заперта."; ], door_to nothing, door_dir nothing, with_key_type nothing, has female 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 "взрывное устройство с таймером", plural "взрывные устройства с таймерами", description [t i; print "Стальная трубка, наполненная порохом и подсоединенная к цифровому таймеру. Не слишком элегантная работа, но должно сработать.^"; t = (self.time_value - my_time) * 5 + self.left_over_seconds; if (self.time_value == NA_) print "^Ты еще не установила таймер.^"; else { if (t == -4) print "^На маленьком ЖК-дисплее таймера мигает цифра «0».^"; else { print "^На маленьком ЖК-дисплее таймера числа «"; for (i = t+4 : (i>t) && (i>0) : i--) print i, ", "; if (t < 0) print 0; else print t; print "...» методично сменяют друг друга, освещая комнату слабыми сине-зелеными вспышками.^"; } } ], name 'таймер' 'взрывн' 'устройств' 'бомб' 'C4' 'цифр' 'труб' 'диспле' 'порох' 'жк', time_value NA_, left_over_seconds 0, before [; Set: print "Чтобы установить таймер необходимо указать число секунд, например @<<установить таймер на 30@>>.^"; return true; SetTo: if (self.time_value ~= NA_) { print "(сперва сбрасывая таймер)^"; self.time_value = NA_; } if (second > 0 && second <= 100) { self.time_value = my_time + (second/5); self.left_over_seconds = second%5; print "Время до взрыва: ", (self.time_value - my_time) * 5 + self.left_over_seconds; print " секунд.^"; if (parent(self) == player) print "(вероятно, ты не захочешь, чтобы эта штука было при тебе, когда это произойдет...)^"; } else { print "Таймер может быть установлен на время в интервале от 1 до 100 секунд.^"; } return true; Reset: if (self.time_value ~= NA_) { self.time_value = NA_; "Ты сбрасываешь таймер."; } else "Таймер не установлен."; ], has neuter; Class IDCard_(MAX_ITEM_COPIES) with short_name "пропуск", plural "пропуска", description "Натали Уильямс.^ Лаборатория Дойча.^ Докторант, МТИ^ ^ Справа — твое фото, когда ты еще носила длинные волосы. С обратной стороны — черная магнитная полоса, проходящая по всей ширине карты.", name 'пропуск' 'карт', before[; Insert: if (second == id_slot){ if (second in foyer or upstairs_landing) { "Из отверстия раздается короткий писк. Твой пропуск не сработал."; } if (second in basement_landing) { if (~~id_card_used) { print "Ты вставляешь пропуск в отверстие и замираешь.^"; basement_door.open_self(my_time+1); print "Превосходно. Прямо как ты мечтала. Эти мерзавцы даже не подумали заблокировать твой пропуск.^"; 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) { "Из отверстия раздается короткий писк. Твой пропуск не сработал."; } if ((second == basement_door) && (player in basement_landing)) { basement_door.open_self(my_time+1); return true; } ], has male; Class Crowbar_(MAX_ITEM_COPIES) with short_name "лом", plural "ломы", name 'лом' 'черн' 'изогнут', description "Изогнутый черный лом.", has male; Class Flashlight_(MAX_ITEM_COPIES) with short_name "фонарик", plural "фонарики", name 'фонар' 'ламп' 'голуб' 'фонарик' 'металлик', description "Небольшой фонарик цвета голубой металлик.", capacity 2, before [; SwitchOn: if (self has on) "Уже включен."; if (BatteriesContained(self) == 2) { give self on; if (real_location == basement_equipment || (real_location == ground_equipment && ground_equipment.lit == false)) { ; instant_action_this_turn = false; return true; } else "Тонкий луч холодного белого света освещает пространство впереди."; } if (BatteriesContained(self) == 1) { "Переключатель щелкает, но свет не загорается. Похоже, нужны две батарейки."; } if (BatteriesContained(self) == 0) { "Переключатель щелкает, но свет не загорается. Не удивительно, если учесть, что для работы фонарику обычно требуются батарейки."; } 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 "Это не подходит для фонарика."; Take: Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,TAKE_FLASHLIGHT_); return false; ], after [; LetGo: if (self has on) { print "Как только ты вытаскиваешь батарейку свет гаснет.^"; 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 male container open switchable; Class Battery_(MAX_ITEM_COPIES) with short_name "батарейка", plural "батарейки", name 'батаре' 'батарейк' 'пальчиков', description "Пальчиковая батарейка.", before [; Remove: <>; ], has female; Class Cable_(MAX_ITEM_COPIES) with short_name "плоский кабель", plural "плоские кабели", name 'кабел' 'провод' 'шнур' 'плоск' 'кус', description "Десятисантиметровый кусок плоского кабеля. Отлично подойдет.", before[; Tie: if (second == control_panel or prototype) <>; if (second == nothing) if (real_location == deutsch_lab or prototype_interior) <>; else "Нет ничего к чему бы ты могла подсоединить этот кабель."; else "Ты не можешь подсоединить к этому кабель."; ], has male; Class Notes_(MAX_ITEM_COPIES) with short_name "коллекция записей", plural "коллекции записей", name 'коллекци' 'запис', casegen [ beg end csID; switch (csID) { csNom: print "коллекция записей"; rtrue; csGen: print "коллекции записей"; rtrue; csDat: print "коллекции записей"; rtrue; csAcc: print "коллекцию записей"; rtrue; csIns: print "коллекцией записей"; rtrue; csPre: print "коллекции записей"; rtrue; } ], description "Твои исследовательские записи. Сто или больше страниц содержат все над чем ты так долго работала. Будет непросто превратить эти каракули в еще один работающий прототип, но не невозможно.", before[; Eat: "Ты полная решимости смотришь на тонкую стопку страниц, но понимаешь, что не сможешь съесть больше пары из них. Тебе лучше подумать о чем-то более реализуемом."; Attack, Cut: "Здесь около сотни страниц и ты не успеешь порвать их все за короткое время."; ], has female; Class EquipmentKey_(MAX_ITEM_COPIES) with short_name "старый латунный ключ", plural "старые латунные ключи", name 'ключ' 'оборудован' 'латунн' 'стар', description "Старый латунный ключ. Открывает различные комнаты с оборудованием.", has male; Class DeutschKey_(MAX_ITEM_COPIES) with short_name "яркий стальной ключ", plural "яркие стальные ключи", name 'ключ' 'дойч' 'стальн' 'ярк', description "Яркий стальной ключ. Открывает дверь в лабораторию Дойча внизу.", has male; Class FormerSelf_(MAX_ITEM_COPIES) with short_name "другая ты", plural "вы из прошлого", name 'ты' 'друг' 'прошл', description "Она выглядит странно знакомой.", has female animate container concealed; !=============================================================================== ! The one-of-a-kind moveable objects Object myselfobj "(self object)" with short_name "ты", description "Темные волосы обрамляют разгоряченное лицо. Несмотря на тревогу, отраженную на твоем напряженном лбу уверенность юности и живость интеллекта очевидны. В ясных зеленых глазах скрывается глубина.", capacity 100, number 0, orders 0, weakness 0, has female concealed animate transparent; Object skeleton_key "ключ/ от всех дверей (fake предмет, чтобы привести в порядок код)" with name 'ключ' 'от' 'всех' 'двер', description "Ключ от всех дверей. И я думал, что они были понарошку!", has male; !=============================================================================== ! The rooms !----------------------------------------------- ! Generic props and sights: Prop walls "стен/а" with name 'стен', found_in [; if (location ~= prototype_interior) return true; else return false; ], has female; Prop floor "пол/" with name 'пол' 'земл' 'ковер' 'ковр', description "Пол покрывает тонкий ковер темно-серого цвета.", found_in [; if ((location ~= balcony) && (location ~= prototype_interior)) return true; else return false; ], has male; Prop ceiling "потол/о/к/" with name 'потолок' 'потолк', casegen [ beg end csID; return ICVowel (csID, beg, end, 'о', 0); ], found_in [; if (location ~= prototype_interior) return true; else return false; ], has male; Sight darkness "темнот/а" with name 'темнот' 'мглу', description "Ты не видишь, что находится в темноте.", before [; Examine: Listen: return false; default: "Непонятно, что ты имеешь в виду."; ], found_in [; return true; ], has female; Sight shadows "/тени" with name 'тени' 'тень' 'углы' 'угол', casegen [ beg end csID; switch (csID) { csNom: print "тени"; rtrue; csGen: print "тенями"; rtrue; csDat: print "теням"; rtrue; csAcc: print "тени"; rtrue; csIns: print "тенями"; rtrue; csPre: print "тенях"; rtrue; } ], description "Тени покрывают углы комнат как старая паутина.", before [; Examine: Listen: return false; default: "Непонятно, что ты имеешь в виду."; ], found_in [; return true; ], has pluralname; Sight complex "комплекс/" with name 'комплекс' 'здание' 'поверхност' 'текстур', description "Здание имеет современный, но, в общем, непримечательный вид. Много внимания уделено поверхностям и текстурам. Почти все окрашено в темный цвет с небольшими оттенками серого, затемненного полуночным мраком.", before [; Examine: Listen: return false; default: "Непонятно, что ты имеешь в виду."; ], found_in [; return true; ], has male; Prop lights "/лампы" with name 'ламп' 'свет', casegen [ beg end csID; switch (csID) { csNom: print "лампы"; rtrue; csGen: print "ламп"; rtrue; csDat: print "лампам"; rtrue; csAcc: print "лампы"; rtrue; csIns: print "лампами"; rtrue; csPre: print "лампах"; rtrue; } ], description "Большинство ламп на потолке выключены, оставляя комплекс в полумраке.", before [; SwitchOn: "Включение ламп сообщит охране о твоем присутствии, а, кроме того, тебе все и так видно."; ], found_in [; if ((location ~= balcony) && (location ~= prototype_interior) && (location ~= basement_equipment) && (location ~= ground_equipment)) return true; else return false; ], has pluralname; Prop stairs "лестниц/а" with name 'лестниц' 'ступен', before [; Climb: if (self in foyer or basement_landing) <>; if (self in upstairs_landing) "Ты уже наверху."; ], found_in basement_landing foyer upstairs_landing, has female; !----------------------------------------------- ! Item-related props and sights: Prop beam "луч/ фонарика" with name 'луч' 'фонарик', description "Тонкий холодный луч фонаря разрезает темноту.", found_in [; if (Flashlit()) return true; else return false; ], has male; Prop photo "фотографи/я" with name 'фото' 'фотографи' 'длинн' 'волос', description "Ты выглядишь молодо, ярко, и гордишься своей новой должностью в лаборатории.", found_in [; if (AmHolding(id_card) || IsIn(id_card,real_location)) return true; else return false; ], has female; Prop stripe "магнитн/ая полос/а" with name 'полос' 'магнитн' 'обратн', description "Это магнитная полоса, какую можно найти на любой кредитной карте, но эта используется для открытия автоматических дверей в здании.", found_in [; if (AmHolding(id_card) || IsIn(id_card,real_location)) return true; else return false; ], has female; !----------------------------------------------- Room foyer "Фойе" with name 'фойе', description "Полутемное фойе со столом охраны у северной стены. Над столом наверху в заполняющей все темноте располагается небольшая площадка. Одна из лестниц ведет к ней, а другая спускается вниз в темноту.", u_to upstairs_landing, d_to basement_landing, n_to ground_door, s_to main_doors, cant_go "Единственные выходы — автоматические двери на севере и на юге, и по лестнице — наверх и вниз.", Acc "фойе", Pre "фойе", has ; Furniture security_desk "стол/ охраны" foyer with description "Большой черный стол с четырьмя установленными в нем экранами видеонаблюдения, показывающие разные участки комплекса в прямом эфире.", before [; Examine: print "Большой черный стол с четырьмя установленными в нем экранами видеонаблюдения, показывающие разные участки комплекса в прямом эфире. "; cctv_screens.display(); print "Здесь также находятся четыре кнопки с надписями: «подвал», «первый», «второй» и «тревога».^"; return true; ], name 'охран' 'черн' 'стол', has male scenery; Object cctv_screens "экран/ы видеонаблюдения" foyer with description [; print "На этих экранах — коридоры и территория вокруг комплекса. "; self.display(); print "^"; ], name 'экран' 'видео' 'трансляци' 'запис' 'видеонаблюдени', display [; Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_CCTV_); if ((my_time == start_time - 1) || (my_time == start_time - 2)) print "На одном из экранов ты видишь другую себя, приближающуюся к зданию. "; if (IsIn(former_self,ground_corridor)) print "На одном из экранов ты видишь другую себя в коридоре первого этажа. "; if (IsIn(former_self,upstairs_corridor)) print "На одном из экранов ты видишь другую себя в коридоре второго этажа. "; if (IsIn(former_self,basement_corridor)) print "На одном из экранов ты видишь другую себя в коридоре подвала. "; ], has pluralname scenery concealed; Object alarm_button "кнопк/а «тревога»" foyer with description "Отдельно расположенная черная кнопка с аккуратной надписью «тревога».", name 'тревог' 'кнопк' 'черн' 'надпис', before [; Push: StartSiren(); return true; Receive: "Кнопка установлена на вертикальной поверхности, поэтому положить на нее что-либо невозможно."; ], has female scenery concealed; Object first_button "кнопк/а «первый»" foyer with description "Маленькая черная кнопка с аккуратной надписью «первый».", name 'первы' 'этаж' 'кнопк' 'черн' 'надпис', before [; Push: ground_door.open_self(my_time+1); ground_door.known_exterior_opening = true; return true; Receive: "Кнопка установлена на вертикальной поверхности, поэтому положить на нее что-либо невозможно."; ], has female scenery concealed; Object basement_button "кнопк/а «подвал»" foyer with description "Маленькая черная кнопка с аккуратной надписью «подвал».", name 'подвал' 'кнопк' 'черн' 'надпис', before [; Push: basement_door.open_self(my_time+1); "Ничего заметного не произошло."; Receive: "Кнопка установлена на вертикальной поверхности, поэтому положить на нее что-либо невозможно."; ], has female scenery concealed; Object second_button "кнопк/а «второй»" foyer with description "Маленькая черная кнопка с аккуратной надписью «второй».", name 'второй' 'кнопк' 'черн' 'надпис', before [; Push: upstairs_door.open_self(my_time+1); "Ничего заметного не произошло."; Receive: "Кнопка установлена на вертикальной поверхности, поэтому положить на нее что-либо невозможно."; ], has female scenery concealed; Sight upstairs_landing_from_foyer "лестничн/ая площадк/а наверху" foyer with description "Лестничная площадка наверху теряется в тени.", name 'upstairs' 'лестничн' 'площадк' 'верх', has female; Sight outside_from_foyer "снаружи" foyer with description "Снаружи пусто и тихо в эту морозную ночь.", name 'наруж' 'ночь', has neuter; Sight ground_corridor_from_foyer "коридор/" foyer with description [;<>;], name 'corridor', has male; !----------------------------------------------- Room basement_landing "Лестничная площадка подвала" with name 'подвал', description "Тесное пространство внизу лестницы. За автоматической дверью коридор уходит на север, а лестница ведет наверх в фойе.", u_to foyer, n_to basement_door, cant_go "Единственные выходы — на север и вверх.", Acc "подвал", Pre "подвале", has ; Sight foyer_from_basement_landing "фойе" basement_landing with description "Отсюда не получится рассмотреть фойе.", name 'фойе', has neuter; !----------------------------------------------- Room upstairs_landing "Лестничная площадка наверху" with name 'площадк', description "Маленькая лестничная площадка висит над фойе в неподвижной темноте.", d_to foyer, n_to upstairs_door, cant_go "Единственные выходы — на север и вниз.", Acc "лестничную площадку наверху", Pre "лестничной площадке наверху", has ; Sight foyer_from_upstairs_landing "фойе" upstairs_landing with description [; Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_FOYER_); if (IsIn(former_self,foyer)) { "С полутемной лестничной площадки ты различаешь другую себя одну в фойе."; } else "С полутемной лестничной площадки ты видишь большую часть пустого фойе под собой."; ], name 'фойе', has neuter; !----------------------------------------------- Room ground_corridor "Коридор первого этажа" with name 'перв' 'этаж' 'коридор', description [; print "Длинный коридор, ведущий на север и юг, почти такой же как на других этажах. "; print "Три серые двери расположены в восточной стене. У первых двух есть маленькие стеклянные окна, смотрящие в погруженные во тьму лаборатории. Третья — "; if (ground_equipment_door has open) print "открыта в аппаратную.^"; else print "без окна и ведет в маленькую аппаратную. Все три двери закрыты.^"; ], s_to ground_door, se_to saunders_door, e_to pooley_door, ne_to ground_equipment_door, cant_go "Единственные выходы — три двери в восточной стене (северо-восток, восток и юго-восток) и автоматическая дверь в фойе (юг).", Acc "коридор первого этажа", Pre "коридоре первого этажа", has ; PluralSight doors_in_ground_corridor "двер/и" ground_corridor with name 'двер' 'коридор' 'восточн' 'стен' 'три', description [; print "В восточной стене коридора расположены три двери. Первые две (на юго-востоке и востоке) ведут в лаборатории Саундерса и Пули. Третья (на северо-востоке) "; if (ground_equipment_door has open) print "открыта и "; print "ведет в маленькую аппаратную. На юге — стеклянная автоматическая дверь в фойе "; if (ground_door has open) print "открыта.^"; else print "закрыта.^"; ], has pluralname; FakeDoor saunders_door "двер/ь в лабораторию Саундерса" ground_corridor with name 'сера' 'серу' 'саундерс' 'перв' 'лаборатори' 'юго-восто' 'двер' 'юв', description "Серая дверь с маленьким стеклянным окном, смотрящим в погруженную во тьму лабораторию. Небольшая табличка гласит: «Лаборатория Саундерса».", has female locked scenery; FakeDoor pooley_door "двер/ь в лабораторию Пули" ground_corridor with name 'сера' 'серу' 'пули' 'втор' 'лаборатори' 'восто' 'двер' 'в', description "Серая дверь с маленьким стеклянным окном, смотрящим в погруженную во тьму лабораторию. Небольшая табличка гласит: «Лаборатория Пули».", has female locked scenery; Prop door_window "маленьк/ое стеклянн/ое окн/о" with name 'маленьк' 'стеклян' 'окно' 'окну' 'окошк', description "Ты не можешь рассмотреть сквозь стекло ничего интересного.", before [; Take,PushDir: print_ret (CCNom) self, " закреплено в двери."; Unlock: if (IsOfType(second,crowbar)) <>; else "Окно на двери не открывается."; Open: "Окно на двери не открывается."; Attack: if (AmHolding(crowbar)) { print "Ты крепко прикладываешься ломом к маленькому окну, но он лишь оставляет на ней отметину.^"; return true; } else "У тебя нет ничего достаточно тяжелого, чтобы разбить окно."; Search: <>; ], found_in ground_corridor basement_corridor, has neuter scenery concealed lockable; !----------------------------------------------- Room basement_corridor "Коридор подвала" with name 'подвал' 'коридор', description [; print "Длинный коридор, ведущий на север и юг, почти такой же как на других этажах. "; print "Три серые двери расположены в восточной стене. У первых двух есть маленькие стеклянные окна, смотрящие в погруженные во тьму лаборатории. Третья — "; if (basement_equipment_door has open) print "открыта в аппаратную.^^"; else print "без окна и ведет в маленькую аппаратную. Все три двери закрыты.^^"; if (deutsch_door has open) print "В северном конце коридора находится открытая дверь в лабораторию Дойча.^"; else print "В северном конце коридора четвертая дверь ведет в лабораторию Дойча.^"; ], s_to basement_door, se_to bostrom_door, e_to wallace_door, ne_to basement_equipment_door, n_to deutsch_door, cant_go "Единственные выходы — в лабораторию Дойча (север), три двери в восточной стене (юго-восток, восток и северо-восток) и автоматическая дверь, назад на лестничную площадку (юг).", Acc "коридор подвала", Pre "коридоре подвала", has ; FakeDoor bostrom_door "двер/ь в лабораторию Бустрема" basement_corridor with name 'двер' 'серы' 'серу' 'бустрем' 'перв' 'лаборатори' 'юго-восто' 'юв', description "Серая дверь с маленьким стеклянным окном, смотрящим в погруженную во тьму лабораторию. Небольшая табличка гласит: «Лаборатория Бустрема».", has female locked scenery; FakeDoor wallace_door "двер/ь в лабораторию Уоллеса" basement_corridor with name 'двер' 'серы' 'серу' 'уоллес' 'втор' 'лаборатори' 'восто' 'в', description "Серая дверь с маленьким стеклянным окном, смотрящим в погруженную во тьму лабораторию. Небольшая табличка гласит: «Лаборатория Уоллеса».", has female locked scenery; PluralSight doors_in_basement_corridor "двер/и" basement_corridor with name 'двер' 'стен' 'восточн' 'коридор' 'три', description [; print "В восточной стене коридора расположены три двери. Первые две (на юго-востоке и востоке) ведут в лаборатории Бустрема и Уоллеса. Третья (на северо-востоке) "; if (basement_equipment_door has open) print "открыта и "; print "ведет в маленькую аппаратную. В северном конце — "; if (deutsch_door has open) print "открытая "; print "дверь в лабораторию Дойча. "; print "На юге — стеклянная автоматическая дверь на лестничную площадку "; if (basement_door has open) print "открыта.^"; else print "закрыта.^"; ], has pluralname; !----------------------------------------------- Room upstairs_corridor "Коридор второго этажа" with description "Длинный коридор, ведущий на север и юг, почти такой же как на других этажах. Три серые двери расположены в восточной стене", n_to balcony_door, ne_to conference_door, e_to butterfield_door, se_to brown_door, s_to upstairs_door, cant_go "Единственные выходы — на балкон (север), три двери по коридору (юго-восток, восток и северо-восток) и автоматическая дверь на лестничную площадку (юг).", Acc "коридор второго этажа", Pre "коридоре второго этажа", has ; FakeDoor brown_door "двер/ь в офис доктора Брауна" upstairs_corridor with name 'двер' 'серы' 'серу' 'браун' 'офис' 'перв' 'юго-восто', description "Простая серая дверь. Маленькая табличка гласит: «Доктор Браун».", has female locked scenery; FakeDoor butterfield_door "двер/ь в офис профессора Баттерфилда" upstairs_corridor with name 'двер' 'офис' 'серы' 'серу' 'баттерфилд' 'профессор' 'втор' 'восто', description "Простая серая дверь. Маленькая табличка гласит: «Профессор Баттерфилд».", has female locked scenery; FakeDoor conference_door "двер/ь в конференц-зал" upstairs_corridor with name 'двер' 'серы' 'серу' 'конференц-зал' 'трет' 'северо-восток', description "Простая серая дверь. Маленькая табличка гласит: «Конференц-зал».", found_in upstairs_corridor conference_room, has locked scenery; PluralSight doors_in_upstairs_corridor "двер/и" upstairs_corridor with name 'двер' 'стен' 'восточн' 'коридор' 'три', description [; print "В восточной стене коридора расположены три двери. Первые две (на юго-востоке и востоке) ведут в офисы доктора Брауна и профессора Баттерфилда. Третья (на северо-востоке) ведет в конференц-зал. В северном конце — "; if (balcony_door has open) print "открытая "; print "стеклянная дверь на балкон. "; print "На юге — стеклянная автоматическая дверь на лестничную площадку "; if (upstairs_door has open) print "открыта.^"; else print "закрыта.^"; ], has pluralname; !----------------------------------------------- Room deutsch_lab "Лаборатория Дойча" with name 'лаборатори' 'дойч', description [; if (self hasnt visited) { print "Лаборатория — это порядок и хаос. Тусклый сине-зеленый свет нескольких кружащихся заставок компьютеров позволяет тебе различить захламленные столы коллег, оставленные в творческом беспорядке. Оставленные в точности такими какими были, когда засверкали значки и вы, не веря в происходящее, смотрели как они взяли под свой контроль лабораторию. Твой стол, однако, чист. Книги и бумаги сложены в аккуратные стопки. Они поработали здесь.^ ^ Рядом у северной стены — прототип, шестифутовый цилиндр из матовой стали. Дверца снята и ее нигде не видно. Они поработали и над ней. Тебя передергивает от увиденного.^"; if (deutsch_door has open) print "^На юге — открытая дверь в лабораторию.^"; else print "^На юге — закрытая дверь в лабораторию.^"; return true; } print "Лаборатория — это порядок и хаос. Тусклый сине-зеленый свет нескольких кружащихся заставок позволяет тебе различить захламленные столы коллег, оставленные в творческом беспорядке. Оставленные в точности такими какими были, когда засверкали значки и вы, не веря в происходящее, смотрели как они взяли под свой контроль лабораторию. Твой стол, однако, чист. Книги и бумаги сложены в аккуратные стопки. Они поработали здесь.^ ^ Рядом у северной стены — прототип, шестифутовый цилиндр из матовой стали. Дверца снята и ее нигде не видно. Они поработали и над ней.^"; if (deutsch_door has open) "^На юге — открытая дверь в лабораторию."; else "^На юге — закрытая дверь в лабораторию."; ], out_to deutsch_door, s_to deutsch_door, in_to prototype_interior, cant_go "Единственные выходы — на юг и в прототип.", Acc "лабораторию Дойча", Pre "лаборатории Дойча", has ; Object prototype "прототип/" with description [; if (~~prototype_seen) { prototype_seen = true; print "Ты построила прототип, намереваясь получить строго отрицательный результат, чтобы показать, что стандартная модель квантовой механики ведет к заведомо ложным утверждениям с обратной причинно-следственной связью. Ты ошибалась. Снова и снова твои эксперименты показывали, что расчеты были верные. Когда военные отстранили тебя от твоего проекта только один аспект остался непроверенным. Аспект, который ты не хотела проверять прежде чем смогла бы предсказать результат — непоследовательное наблюдение.^^Что случится, если аномалии будут наблюдаться теми, кто находится в исходной ветке событий? Во время твоих предыдущих экспериментов прототип был надежно защищен от внешнего воздействия, чтобы избежать саму такую возможность. И поскольку расчеты повторялись снова и снова, это единственная причина, по которой ты сегодня жива. Когда наблюдатель в исходной ветке событий производит наблюдение аномалии волновая функция временно перемещенного объекта коллапсирует и перемещение ретроспективно не удается, сохраняя хронологическую последовательность событий. Есть только один побочный эффект: полное преобразование массы объекта в выброс фотонов — чистую энергию.^^Ты пыталась им объяснить снова и снова. Они просто решили, что ты никак не можешь смириться с тем, что лишилась проекта. И вот, в ночь перед их запланированным «первым главным экспериментом», ты пришла положить всему этому конец. Уничтожить прототип и избежать завтрашнего кошмара.^^Сам прототип представляет собой цилиндр из матовой стали, шесть футов в высоту и четыре фута в ширину. Корпус и дверца были построены с квантовым экранированием для предотвращения декогеренции волновой функции. Но сейчас дверца убрана и любое использование машины может быть потенциально катастрофическим...^"; } else print "Сам прототип представляет собой цилиндр из матовой стали, шесть футов в высоту и четыре фута в ширину. Корпус и дверца были построены с квантовым экранированием для предотвращения декогеренции волновой функции. Но сейчас дверца убрана и любое использование машины может быть потенциально катастрофическим...^"; if (~~(self.fixed)) "^При ближайшем рассмотрении ты обнаруживаешь, что панель управления пытались переместить, чтобы ею можно было управлять изнутри. Как бы то ни было, прототип в настоящее время не функционирует, но ты думаешь, что смогла бы, вероятно, завершить все начатые изменения в течение минуты или двух."; return true; ], name 'прототип' 'врем' 'машин' 'шестифутов' 'четырехфутов' 'цилиндр', fixed, before [t; Set: if (self.fixed) { if (self in deutsch_lab) "Прототип изменен таким образом, что единственный способ им управлять — забраться в него и использовать внутреннюю панель управления."; if (self in prototype_interior) <>; } else "Тебе нужно закончить начатые изменения, чтобы использовать прототип."; SetTo: if (self.fixed) { if (self in deutsch_lab) "Прототип изменен таким образом, что единственный способ им управлять — забраться в него и использовать внутреннюю панель управления."; if (self in prototype_interior) <>; } else "Тебе нужно закончить начатые изменения, чтобы использовать прототип."; SwitchOn: if (self.fixed) { if (self in deutsch_lab) "Прототип изменен таким образом, что единственный способ им управлять — забраться в него и использовать внутреннюю панель управления."; if (self in prototype_interior) { print "(нажимая серебристую кнопку)^"; <>; } } else "Тебе нужно закончить начатые изменения, чтобы использовать прототип."; Enter: <>; Exit: if (real_location == prototype_interior) <>; Tie: if (~~d_paradox) { if (second == nothing) { if (self.fixed) "Уже исправлено."; if (AmHolding(cable)) { if (self in deutsch_lab) { print "(сперва заходя в прототип)^"; ; IncTime(); if (Stopped()) return true; print "^"; } move GetHeld(cable) to limbo; print "Ты приступаешь к незавершенной работе по модификации...^"; for (t=0 : t<10 : t++) { IncTime(); if (Stopped()) return true; } self.fixed = true; prototype_fixed_time = my_time; print "Спустя минуту или около того ты заканчиваешь работу.^"; return true; } else "Спустя несколько мгновений ты понимаешь, что для завершения изменений тебе необходим плоский кабель для соединения компонентов. Тебе хорошо известен этот кабель, но в лаборатории такого нет. Однако в аппаратной в коридоре он должен быть."; } } Attack: "Просто сломать прототип недостаточно, так как внутри скрыто слишком много микросхем, которые тебе не достать. Поэтому ты захватила с собой бомбу."; Search: if (self in deutsch_lab) { print "(сперва заходя в прототип)^"; <>; } else <>; ], react_before[; Insert: if (~~(self.fixed)) if (IsOfType(noun,cable)) if ((second == self) || (second == control_panel)) <>; if (second == self) { if (noun == self) "Не подходит. Очевидно. О чем ты думала? Это прототип хронотранспортного устройства, а не ТАРДИС."; if (self in deutsch_lab) { move noun to prototype_interior; print "Ты кладешь ", (GenIt) noun, " в прототип.^"; return true; } else <>; } ], found_in deutsch_lab prototype_interior, has male scenery concealed; Furniture bench "тво/е рабоч/ее мест/о" deutsch_lab with description "Твое рабочее место использовалось явно недавно, и не тобой.", before [; Examine: print "Твое рабочее место использовалось явно недавно, и не тобой. Книги и бумаги аккуратно сложены в одну сторону, оставляя на столе самое большое пустое пространство, какое ты когда-либо на нем видела.^"; if (~~have_looked_at_bench) { have_looked_at_bench = true; "^Ты внезапно замечаешь, что твоих исследовательских записей нет. Ты была уверена, что они здесь, и что они будут уничтожены взрывом. Это плохо. Очень плохо."; } return true; Search: <>; ], name 'рабоч' 'мест' 'стол' 'пространств', has neuter scenery; Prop books "учебник/и" deutsch_lab with description "Несколько учебников по квантовой механике и теории струн, которые все это время служили тебе верой и правдой.", name 'книг' 'учебник', has pluralname; Prop papers "бумаг/и" deutsch_lab with description [; print "Коллекция ксерокопий журнальных статей, которые ты читала несколько недель назад.^"; if (~~have_looked_at_bench) { have_looked_at_bench = true; "^Ты внезапно заметила, что твоих исследовательских записей нет. Ты была уверена, что они здесь, и что они будут уничтожены взрывом. Это плохо. Очень плохо."; } return true; ], name 'бумаг' 'ксерокопи' 'стат', has pluralname; Prop screen_savers "/заставки" deutsch_lab with description "Плавные абстрактные формы оставляют светящиеся следы на экране, вращаясь вокруг и через себя.", casegen [ beg end csID; switch (csID) { csNom: print "заставки"; rtrue; csGen: print "заставки"; rtrue; csDat: print "заставкам"; rtrue; csAcc: print "заставки"; rtrue; csIns: print "заставками"; rtrue; csPre: print "заставках"; rtrue; } ], name 'заставк' 'экран' 'скринсейвер' 'компьютер' 'фиолетов' 'зелен' 'голуб', has pluralname; Prop cladding "корпус/" deutsch_lab with name 'облицовк' 'сталь' 'матов' 'корпус' 'люк', has male; Prop mess "беспоряд/о/к/" deutsch_lab with description "Обычный творческий беспорядок: раскрытые книги, пятна-круги от кофе, разбросанные бумаги — все словно застыло во времени.", name 'беспоряд' 'хаос', casegen [ beg end csID; return ICVowel (csID, beg, end, 'о', 0); ], has male; Sight control_panel_from_lab "панел/ь управления" deutsch_lab with description "Отсюда плохо видна панель управления. Нужно зайти в прототип.", name 'панел' 'управлени', before [; Push: <>; Examine: "Отсюда плохо видна панель управления. Нужно зайти в прототип."; default: "Для этого нужно зайти в прототип."; ], has female; !----------------------------------------------- Room prototype_interior "Внутри прототипа" with description [; if (prototype.fixed) { print "Внутри прототипа темно и тесно. На стенке ты видишь панель управления с небольшим ЖК-таймером, установленным на «", control_panel.time_value, "» и серебристую кнопку. Через открытый люк тебе видна часть лаборатории.^"; } else "Внутри прототипа темно и тесно. На стенке ты видишь не до конца установленную панель управления. Через открытый люк тебе видна часть лаборатории."; ], name 'прототип' 'врем' 'машин' 'интерьер', out_to deutsch_lab, Acc "прототип", Pre "прототипе", cant_go "Единственный выход — наружу, в лабораторию Дойча.", has ; Object control_panel "панел/ь управления" prototype_interior with name 'управлени' 'панел' 'таймер' 'врем' 'экран', description [; print "Панель управления из матовой стали с голубым ЖК-таймером, установленным на ", control_panel.time_value, " секунд и блестящей серебристой кнопкой.^"; ], time_value, before [; Push: <>; Set: if (prototype.fixed) "Чтобы установить время на панели управления тебе нужно указать число секунд, например, «установить панель на 75»."; else "Ты не сможешь установить время на панели управления, до тех пор, пока не завершишь начатые изменения."; SetTo: if (prototype.fixed) { if (second > 0 && second <= 500) { self.time_value = second; "Ты быстро вводишь число на панели управления."; } else { "Допустимые значения: от 1 до 500 секунд."; } } else "Ты не сможешь установить время на панели управления, до тех пор, пока не завершишь начатые изменения."; SwitchOn: if (self.fixed) { print "(нажимая на серебристую кнопку)^"; <>; } else "Тебе нужно завершить начатые изменения, чтобы воспользоваться прототипом."; ], has female scenery concealed; Object silver_button "серебрист/ая кнопк/а" prototype_interior with name 'кнопк' 'серебр', description "Серебристая кнопка.", before [old_value t; Push: if (prototype.fixed) { if (control_panel.time_value == 0) "Панель управления издает короткий писк и на экране загорается цифра «0». Возможно, тебе стоит сперва установить время."; 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)) "Ты затаила дыхание и активировала прототип."; ! this is needed to avoid silly message below, then death if ((old_value % 5) ~= 0) "После нажатия на кнопку ты еще немного постояла в ожидании."; else "Ты затаила дыхание и активировала прототип."; } else "Ничего не происходит."; } else "Кнопка не будет работать до тех пор, пока ты не завершишь начатые изменения."; Receive: "Кнопка установлена на вертикальной поверхности, поэтому положить на нее что-либо невозможно."; ], has female scenery concealed; Sight deutsch_lab_from_prototype "Лаборатори/я Дойча" prototype_interior with description "Тебе не удается отсюда много разглядеть. Только несколько рабочих мест под меняющимся сине-фиолетово-зеленым светом.", name 'дойч' 'лаборатор' 'стол' 'люк' 'мест', has female; Prop surface "внутренн/яя поверхност/ь" prototype_interior with name 'стен' 'интерьер' 'поверхност' 'потол' 'пол', description "Изнутри прототип обшит гладкой матовой сталью.", has female; !----------------------------------------------- Room basement_equipment "Аппаратная в подвале" with name 'аппаратн' 'комнат', description [; if (FlashLit()) { MoveMoveableChildren(basement_equipment_gloom,self); print "Тонкий бело-голубой луч твоего фонарика вырывает из тьмы забитые полки.^"; if (basement_equipment_door has open) print "^На западе — открытая дверь в коридор.^"; else print "^На западе — закрытая дверь в коридор.^"; } else { MoveMoveableChildren(self,basement_equipment_gloom); if (basement_equipment_door has open) print "Тут почти ничего не видно. Немного света проникает через открытую дверь, позволяя различить очертания полок. У двери расположен выключатель.^"; else print "Ты в полной темноте.^"; } ], out_to basement_equipment_door, w_to basement_equipment_door, sw_to [;<>;], cant_go "Единственный выход — в коридор на западе.", lit false, has_been_lit false, Acc "аппаратную в подвале", Pre "аппаратной в подвале", 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 "Темная аппаратная в подвале" with name 'аппаратн' 'комнат' 'темн', Acc "темную аппаратную в подвале", Pre "темной аппаратной в подвале", has ; Object basement_light_switch "выключател/ь" basement_equipment with name 'выключатель' 'выключателем' 'свет', before [; Push: <>; SwitchOn: if (~~self.blown) { Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,BLOW_BASEMENT_LIGHT_); self.blown = true; if (FlashLit()) "Флуоресцентные лампы обнадеживающе мигают, выхватывая из тьмы разбросанное оборудование. Потом темнота. Ты моргаешь и детали комнаты исчезают с сетчатки. Ты остаешься в полумраке."; else "Флуоресцентные лампы обнадеживающе мигают, выхватывая из тьмы разбросанное оборудование. Потом темнота. Не остается ничего кроме нескольких исчезающих образов захламленной комнаты на сетчатке."; } else "«Щелк». Ничего не произошло."; ], 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 male static scenery concealed switchable; !----------------------------------------------- Room ground_equipment "Аппаратная на первом этаже" with name 'аппаратн' 'комнат', description [; if (self.lit) { MoveMoveableChildren(ground_equipment_gloom,self); print "Мигающие флуоресцентные лампы освещают забитые полки в аппаратной.^"; if (ground_equipment_door has open) print "^На западе — открытая дверь в коридор.^"; else print "^На западе — закрытая дверь в коридор.^"; } else { if (FlashLit()) { MoveMoveableChildren(ground_equipment_gloom,self); print "Тонкий бело-голубой луч твоего фонарика вырывает из тьмы забитые полки.^"; if (ground_equipment_door has open) print "^На западе — открытая дверь в коридор.^"; else print "^На западе — закрытая дверь в коридор.^"; } else { MoveMoveableChildren(self,ground_equipment_gloom); if (ground_equipment_door has open) print "Тут почти ничего не видно. Немного света проникает через открытую дверь, позволяя различить очертания полок. У двери расположен выключатель.^"; else print "Ты в полной темноте.^"; } } ], out_to ground_equipment_door, w_to ground_equipment_door, sw_to [;<>;], cant_go "Единственный выход — в коридор на западе.", lit false, has_been_lit false, Acc "аппаратную на первом этаже", Pre "аппаратной на первом этаже", has ; Room ground_equipment_gloom "Темная аппаратная на первом этаже" with name 'аппаратн' 'комнат' 'темн', Acc "темную аппаратную на первом этаже", Pre "темной аппаратной на первом этаже", has ; Object ground_light_switch "выключател/ь" ground_equipment with name 'выключатель' 'выключателем' 'свет', before [; Push: if (~~ground_equipment.lit) { <>; } else { <>; } SwitchOn: if (~~ground_equipment.lit) { ground_equipment.lit = true; give self on; print "После короткого мигания свет загорается.^"; ; instant_action_this_turn = false; return true; } SwitchOff: if (ground_equipment.lit) { ground_equipment.lit = false; give self ~on; if (FlashLit()) "Моргнув пару раз, лампы гаснут, и ты оказываешься в полумраке."; else { MoveMoveableChildren(ground_equipment,ground_equipment_gloom); "Моргнув пару раз, лампы гаснут, и ты оказываешься в темноте."; } } ], 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 male static scenery concealed switchable; Prop shelves "/полки" with name 'полк' 'оборудован' 'предмет' 'очертани' 'беспоряд', casegen [ beg end csID; switch (csID) { csNom: print "полки"; rtrue; csGen: print "полок"; rtrue; csDat: print "полкам"; rtrue; csAcc: print "полки"; rtrue; csIns: print "полками"; rtrue; csPre: print "полках"; rtrue; } ], description [; if (((parent(self)).lit) || (Flashlit())) "Полки заполнены разным лабораторным оборудованием, но ничего из этого тебе сейчас не нужно."; else "Ты не можешь разглядеть ни одни из предметов на темных полках."; ], found_in ground_equipment basement_equipment, has pluralname; Prop fluoro_light "/флуоресцентные_лампы" with name 'флуоресцентн' 'мигающ' 'ламп' 'трубк', casegen [ beg end csID; switch (csID) { csNom: print "флуоресцентные лампы"; rtrue; csGen: print "флуоресцентных ламп"; rtrue; csDat: print "флуоресцентным лампам"; rtrue; csAcc: print "флуоресцентные лампы"; rtrue; csIns: print "флуоресцентными лампами"; rtrue; csPre: print "флуоресцентных лампах"; rtrue; } ], description [; if ((parent(self)).lit) "Флуоресцентные лампы ярко мигают."; else "Ты различаешь темную флуоресцентную лампу на потолке."; ], found_in ground_equipment basement_equipment, has pluralname; !----------------------------------------------- Room balcony "Балкон" with name 'балкон', description "Широкий балкон с видом на спящий город. Внизу под тобой газон постепенно теряется во тьме. Силуэты деревьев отмечают границу небольшой территории. Над тобой — ясное ночное небо, усыпанное сверкающими звездами.", 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) "Единственные выходы — коридор (юг) и окно в конференц-зал (юго-восток)."; else "Единственный выход — коридор (юг)."; ], Acc "балкон", Pre "балконе", has ; Prop balcony_floor "пол/" balcony with name 'пол' 'плитк', description "Пол покрывает белая плитка.", has male; Prop railing "/перила" balcony with name 'перил' 'поруч' 'рукоятк', casegen [ beg end csID; switch (csID) { csNom: print "перила"; rtrue; csGen: print "перил"; rtrue; csDat: print "перилам"; rtrue; csAcc: print "перила"; rtrue; csIns: print "перилами"; rtrue; csPre: print "перилах"; rtrue; } ], has pluralname; Sight trees "/деревья" balcony with name 'дерев' 'силуэт' 'кипарис' 'хвойн', casegen [ beg end csID; switch (csID) { csNom: print "деревья"; rtrue; csGen: print "деревьев"; rtrue; csDat: print "деревьям"; rtrue; csAcc: print "деревья"; rtrue; csIns: print "деревьями"; rtrue; csPre: print "деревьях"; rtrue; } ], description "Какие-то высокие хвойные деревья, возможно, кипарисы. Ты любишь вспоминать как спала под ними прошлым летом.", has pluralname; Sight grounds "территор/ия" balcony with name 'лужайк' 'земл' 'газон' 'мрак', description "Территория простирается немного дальше ухоженного газона и нескольких высоких деревьев, и каждую ночь охранник все тщательно проверяет.", has female; Sight guard "охран/а" balcony with name 'охран', description "Нет никаких признаков охраны.", has female; Sight stars "/звезды" with name 'звезд' 'черн' 'вуал' 'созвезди', casegen [ beg end csID; switch (csID) { csNom: print "звезды"; rtrue; csGen: print "звезд"; rtrue; csDat: print "звездам"; rtrue; csAcc: print "звезды"; rtrue; csIns: print "звездами"; rtrue; csPre: print "звездах"; rtrue; } ], description "Звезды - это прекрасная россыпь сверкающих драгоценных камней на черной вуали неба.", found_in balcony conference_room, has pluralname; Sight night "ноч/ь" with name 'ноч' 'звездн', description "Снаружи — одна из лучших осенних ночей, какую ты только можешь вспомнить.", found_in balcony conference_room, has female; Sight city "город/" with name 'город' 'бостон' 'огон' 'крыш' 'небоскреб', description "Под тобой лежат крыши и небоскребы твоего родного города. Тут и там уже зажглись маленькие желтые огоньки, но пока еще Бостон спит.", found_in balcony conference_room, has male; !----------------------------------------------- Room conference_room "Конференц-зал" with name 'конференц-зал', description "Довольно приятное, но неживое место. Большой стол из темного полированного дерева занимает почетное место и окружен полудюжиной стульев.", n_to conference_window, nw_to conference_window, out_to conference_window, w_to conference_door, cant_go "Единственные выходы — дверь на западе и окно на севере.", Acc "конференц-зал", Pre "конференц-зале", has ; Sight conference_room_sight "комнат/а" conference_room with name 'комнат' 'конференц-зал', description "Довольно приятное, но неживое место.", before [; Exit: <>; ], has female; Furniture conference_table "стол/" conference_room with description "Большой круглый стол из темного полированного дерева.", name 'стол' 'кругл' 'больш' 'полирован' 'темн' 'дерев', has male scenery; Furniture chair "стул/" conference_room with description "Каждый стул выполнен в элегантном современном стиле из того же темного дерева, что и стол.", name 'стул' 'седен' 'кресл', has male scenery concealed; !----------------------------------------------- Room outside "Снаружи" with description "За пределами лаборатории улица лежит в тишине.", n_to main_doors, Acc "ночь", Pre "ночи", has ; !----------------------------------------------- Room limbo "Ночь" with description "Место ожидания для нереализованных предметов.", Acc "ночь", Pre "ночи", has ; !------------------------------------------------------------------------ ! ! Door stuff ! AutomaticDoor main_doors "/главныедвери" foyer with description [; if (self has open) print "Через открытые двери ты видишь спящую территорию. С правой стороны находится зеленая кнопка.^"; else print "Пара "; if (self.smashed) print "разбитых "; print "стеклянных раздвижных дверей, сквозь которые ты видишь спящую территорию. С правой стороны находится зеленая кнопка.^"; ], when_closed "За главными дверьми на юге раскинулась черная ночь.", when_open "На юге — главные двери, открытые в черную ночь.", casegen [ beg end csID; switch (csID) { csNom: print "главные двери"; rtrue; csGen: print "главных дверей"; rtrue; csDat: print "главным дверям"; rtrue; csAcc: print "главные двери"; rtrue; csIns: print "главными дверями"; rtrue; csPre: print "главных дверях"; rtrue; } ], name 'двер' 'главн' 'юг' 'стеклянн' 'раздвижн', 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 "Главные двери открываются в ночь.^"; } 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 "Снаружи, другая ты быстро устремляется к главным дверям. Когда она обнаруживает, что они открыты, то останавливается на полушаге и издает шокированный вздох.^"; print "^Время распадается...^"; Devours(my_time); } ], closing_message [; if ((~~Stopped()) && (self in LocationOf(player))) "Главные двери тихо сдвигаются."; ], before [; Open: print "(нажимая на зеленую кнопку выхода)^"; <>; Unlock: if (IsOfType(second,crowbar)) <>; else "Ты не можешь открыть этим дверь."; Enter: if (self hasnt open) { print "(сперва нажимая зеленую кнопку выхода)^"; ; IncTime(); if (Stopped()) return true; <>; } ], react_before [; Go: if (noun == s_to && self hasnt open) <>; ], has pluralname; AutomaticDoor ground_door "автоматическ/ая двер/ь" with description [; if (self in foyer) { Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_GROUND_CORRIDOR_); if (self.smashed) print "Треснувшая стеклянная раздвижная дверь, "; else print "Стеклянная раздвижная дверь, "; print "за которой виден тусклый коридор. "; if (IsIn(former_self,ground_corridor)) print "В тени стоит другая ты. "; print "С правой стороны находится щель для пропуска.^"; } if (self in ground_corridor) { Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_FOYER_); if (self.smashed) print "Треснувшая стеклянная раздвижная дверь, "; else print "Стеклянная раздвижная дверь, "; print "за которой видно темное фойе. "; if (IsIn(former_self,foyer)) print "В тени стоит другая ты. "; print "С правой стороны находится зеленая кнопка.^"; } ], when_closed [; if (self in foyer) "В северной стене — закрытая автоматическая дверь."; if (self in ground_corridor) "На юге — закрытая автоматическая дверь, ведущая в фойе."; ], when_open [; if (self in foyer) "В северной стене — открытая автоматическая дверь."; if (self in ground_corridor) "На юге — открытая автоматическая дверь, ведущая в фойе."; ], name 'север' 'автоматическ' 'авто' 'стеклянн' 'двер' 'раздвижн', door_to [; if (self in foyer) return ground_corridor; if (self in ground_corridor) return foyer; ], door_dir [; if (self in foyer) return n_to; if (self in ground_corridor) return s_to; ], before [; Unlock: if (IsOfType(second,crowbar)) <>; else if (IsOfType(second,id_card) && (self in foyer)) <>; else "Ты не можешь открыть этим дверь."; Open: if (self in foyer) if (self.known_exterior_opening == 0) "Нет очевидного способа открыть автоматическую дверь."; else { print "Ты нажимаешь кнопку с надписью «первый».^"; <>; } if (self in ground_corridor) { print "(нажимая зеленую кнопку выхода)^"; <>; } Enter: if (self in ground_corridor && self hasnt open) { print "(сперва нажимая зеленую кнопку выхода)^"; ; IncTime(); if (Stopped()) return true; <>; } if (self in foyer && self hasnt open) { if (self.known_exterior_opening == true) { print "(сперва нажимая кнопку с надписью «первый»)^"; ; IncTime(); if (Stopped()) return true; <>; } else { "Нет очевидного способа открыть автоматическую дверь."; } } ], react_before [; Go: if (noun == n_to && self in foyer && self hasnt open) <>; if (noun == s_to && self in ground_corridor && self hasnt open) <>; ], known_exterior_opening, found_in foyer ground_corridor, has female; AutomaticDoor basement_door "автоматическ/ая двер/ь" with description [; if (self in basement_landing) { Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_BASEMENT_CORRIDOR_); if (self.smashed) print "Треснувшая стеклянная раздвижная дверь, "; else print "Стеклянная раздвижная дверь, "; print "за которой виден тусклый коридор. "; if (IsIn(former_self,basement_corridor)) print "В тени стоит другая ты. "; print "С правой стороны находится щель для пропуска.^"; } if (self in basement_corridor) { Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_BASEMENT_LANDING_); if (self.smashed) print "Треснувшая стеклянная раздвижная дверь, "; else print "Стеклянная раздвижная дверь, "; print "за которой видна небольшая лестничная площадка подвала. "; if (IsIn(former_self,basement_landing)) print "В тени стоит другая ты. "; print "С правой стороны находится зеленая кнопка.^"; } ], name 'двер' 'авто' 'стеклянн' 'автоматическ' 'раздвижн', when_closed [; if (self in basement_landing) "На севере — закрытая автоматическая дверь."; if (self in basement_corridor) "На юге — закрытая автоматическая дверь, ведущая на лестничную площадку."; ], when_open [; if (self in basement_landing) "На севере — открытая автоматическая дверь."; if (self in basement_corridor) "На юге — открытая автоматическая дверь, ведущая на лестничную площадку."; ], door_to [; if (self in basement_landing) return basement_corridor; if (self in basement_corridor) return basement_landing; ], door_dir [; if (self in basement_landing) return n_to; if (self in basement_corridor) return s_to; ], before [; Unlock: if (IsOfType(second,crowbar)) <>; else if (IsOfType(second,id_card) && (self in basement_landing)) <>; else "Ты не можешь открыть этим дверь."; Open: if (self in basement_landing) { if ( AmHolding(id_card) ) { print "(вставляя пропуск)^"; <>; } else "Чтобы это сделать тебе нужен твой пропуск."; } if (self in basement_corridor) { print "(нажимая зеленую кнопку выхода)^"; <>; } Enter: if (self in basement_corridor && self hasnt open) { print "(сперва нажимая зеленую кнопку выхода)^"; ; IncTime(); if (Stopped()) return true; <>; } if (self in basement_landing && self hasnt open) { if ( AmHolding(id_card) ) { print "(сперва вставляя пропуск)^"; ; IncTime(); if (Stopped()) return true; <>; } else "Чтобы это сделать тебе нужен пропуск."; } ], react_before [; Go: if (noun == n_to && self in basement_landing && self hasnt open) <>; if (noun == s_to && self in basement_corridor && self hasnt open) <>; ], known_exterior_opening, found_in basement_landing basement_corridor, has female; AutomaticDoor upstairs_door "автоматическ/ая двер/ь" with description [; if (self in upstairs_landing) { Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_UPSTAIRS_CORRIDOR_); if (self.smashed) print "Треснувшая стеклянная раздвижная дверь, "; else print "Стеклянная раздвижная дверь, "; print "за которой виден тусклый коридор. "; if (IsIn(former_self,upstairs_corridor)) print "В тени стоит другая ты. "; print "С правой стороны находится щель для пропуска.^"; } if (self in upstairs_corridor) { Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_UPSTAIRS_LANDING_); if (self.smashed) print "Треснувшая стеклянная раздвижная дверь, "; else print "Стеклянная раздвижная дверь, "; print "за которой видна верхняя часть полутемного фойе. "; if (IsIn(former_self,upstairs_landing)) print "В тени стоит другая ты. "; print "С правой стороны находится зеленая кнопка.^"; } ], name 'двер' 'авто' 'стеклянн' 'автоматическ' 'раздвижн', when_closed [; if (self in upstairs_landing) "В северной стене — закрытая автоматическая дверь."; if (self in upstairs_corridor) "В южной стене — закрытая автоматическая дверь, ведущая на лестничную площадку."; ], when_open [; if (self in upstairs_landing) "В северной стене — открытая автоматическая дверь."; if (self in upstairs_corridor) "На юге — открытая автоматическая дверь, ведущая на лестничную площадку."; ], door_to [; if (self in upstairs_landing) return upstairs_corridor; if (self in upstairs_corridor) return upstairs_landing; ], door_dir [; if (self in upstairs_landing) return n_to; if (self in upstairs_corridor) return s_to; ], before [; Unlock: if (IsOfType(second,crowbar)) <>; else if (IsOfType(second,id_card) && (self in upstairs_landing)) <>; else "Ты не можешь открыть этим дверь."; Open: if (self in upstairs_landing) if (AmHolding(id_card)) { print "(вставляя пропуск)^"; <>; } if (self in upstairs_corridor) { print "(нажимая зеленую кнопку выхода)^"; <>; } Enter: if (self in upstairs_corridor && self hasnt open) { print "(сперва нажимая зеленую кнопку выхода)^"; ; if (self has open) { IncTime(); if (Stopped()) return true; <>; } return true; } if (self in upstairs_landing && self hasnt open) { "Нет очевидного способа открыть автоматическую дверь."; } ], react_before [; Go: if (noun == s_to && self in upstairs_corridor && self hasnt open) <>; ], found_in upstairs_landing upstairs_corridor, has female; Object exit_button "зелен/ая кнопк/а выхода" with description "Зеленая кнопка рядом с дверью.", name 'зелен' 'кнопк', before [; Push: if (self in ground_corridor) { ground_door.open_self(my_time+1); } if (self in upstairs_corridor) { if (challenge) "Ничего не происходит. Должно быть, кнопка сломана."; 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: "Кнопка установлена на вертикальной поверхности, поэтому положить на нее что-либо невозможно."; ], found_in ground_corridor upstairs_corridor basement_corridor foyer, has female scenery concealed; Object id_slot "щел/ь для пропуска" with description "Узкая щель справа от двери. Двери запрограммированы таким образом, что только те, у кого имеется разрешение могут использовать свой пропуск для входа.", name 'слот' 'щель' 'отверст', found_in foyer upstairs_landing basement_landing, has female scenery concealed; ManualDoor ground_equipment_door "двер/ь в аппаратную" with name 'двер' 'аппаратн' 'комнат' 'в' 'серы' 'серу' 'треть' 'прост' 'северо-восто', description "Простая серая дверь.", door_to [; if (self in ground_corridor) return ground_equipment; if (self in ground_equipment) return ground_corridor; ], door_dir [; if (self in ground_corridor) return ne_to; if (self in ground_equipment) return w_to; ], before [; Close: if (((self in ground_equipment) && IsIn(former_self,ground_corridor)) || ((self in ground_corridor) && IsIn(former_self,ground_equipment)) ) { CloseParadox(); return true; } Open: if (((self in ground_equipment) && IsIn(former_self,ground_corridor)) || ((self in ground_corridor) && IsIn(former_self,ground_equipment)) ) { OpenParadox(); return true; } else return (OpenManualDoor(self,second)); Unlock: if (IsOfType(second,crowbar)) <>; if (((self in ground_equipment) && IsIn(former_self,ground_corridor)) || ((self in ground_corridor) && IsIn(former_self,ground_equipment)) ) { LockUnlockParadox(); return true; } else return (UnlockManualDoor(self,second)); Lock: if (((self in ground_equipment) && IsIn(former_self,ground_corridor)) || ((self in ground_corridor) && IsIn(former_self,ground_equipment)) ) { LockUnlockParadox(); return true; } else return (LockManualDoor(self,second)); ], with_key_type equipment_key, found_in ground_corridor ground_equipment, has female locked scenery; ManualDoor basement_equipment_door "двер/ь в аппаратную" with name 'двер' 'аппаратн' 'комн' 'серу' 'сера' 'треть' 'в' 'прост' 'северо-восто', description "Простая серая дверь.", door_to [; if (self in basement_corridor) return basement_equipment; if (self in basement_equipment) return basement_corridor; ], door_dir [; if (self in basement_corridor) return ne_to; if (self in basement_equipment) return w_to; ], before [; Close: if (((self in basement_equipment) && IsIn(former_self,basement_corridor)) || ((self in basement_corridor) && IsIn(former_self,basement_equipment)) ) { CloseParadox(); return true; } Open: if (((self in basement_equipment) && IsIn(former_self,basement_corridor)) || ((self in basement_corridor) && IsIn(former_self,basement_equipment)) ) { OpenParadox(); return true; } else return (OpenManualDoor(self,second)); Unlock: if (IsOfType(second,crowbar)) <>; if (((self in basement_equipment) && IsIn(former_self,basement_corridor)) || ((self in basement_corridor) && IsIn(former_self,basement_equipment)) ) { LockUnlockParadox(); return true; } else return (UnlockManualDoor(self,second)); Lock: if (((self in basement_equipment) && IsIn(former_self,basement_corridor)) || ((self in basement_corridor) && IsIn(former_self,basement_equipment)) ) { LockUnlockParadox(); return true; } else return (LockManualDoor(self,second)); ], with_key_type equipment_key, found_in basement_corridor basement_equipment, has female locked scenery; ManualDoor deutsch_door "двер/ь в лабораторию Дойча" with name 'двер' 'дойч' 'лаборатор' 'четверт' 'север', description [; if (self in basement_corridor) "Серая дверь с маленьким стеклянным окном, смотрящим в погруженную во тьму лабораторию."; if (self in deutsch_lab) "Серая дверь с маленьким стеклянным окном, смотрящим в погруженный во тьму коридор."; ], door_to [; if (self in basement_corridor) return deutsch_lab; if (self in deutsch_lab) return basement_corridor; ], door_dir [; if (self in basement_corridor) return n_to; if (self in deutsch_lab) return s_to; ], before [; Close: if (((self in deutsch_lab) && IsIn(former_self,basement_corridor)) || ((self in basement_corridor) && IsIn(former_self,deutsch_lab)) ) { CloseParadox(); return true; } Open: if (((self in deutsch_lab) && IsIn(former_self,basement_corridor)) || ((self in basement_corridor) && IsIn(former_self,deutsch_lab)) ) { OpenParadox(); return true; } else return (OpenManualDoor(self,second)); Unlock: if (IsOfType(second,crowbar)) <>; if (((self in deutsch_lab) && IsIn(former_self,basement_corridor)) || ((self in basement_corridor) && IsIn(former_self,deutsch_lab)) ) { LockUnlockParadox(); return true; } else return (UnlockManualDoor(self,second)); Lock: if (((self in deutsch_lab) && IsIn(former_self,basement_corridor)) || ((self in basement_corridor) && IsIn(former_self,deutsch_lab)) ) { LockUnlockParadox(); return true; } else return (LockManualDoor(self,second)); ], with_key_type deutsch_key, found_in basement_corridor deutsch_lab, has female locked scenery; ManualDoor balcony_door "/балконнд" with name 'двер' 'балкон' 'север' 'стеклянн', casegen [ beg end csID; switch (csID) { csNom: print "балконная дверь"; rtrue; csGen: print "балконной двери"; rtrue; csDat: print "балконной двери"; rtrue; csAcc: print "балконную дверь"; rtrue; csIns: print "балконной дверью"; rtrue; csPre: print "балконной двери"; rtrue; } ], description [; if (self in upstairs_corridor) { Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_BALCONY_); if (self.smashed) print "Треснувшая стеклянная дверь "; else print "Стеклянная дверь "; print "на балкон. "; if (IsIn(former_self,balcony)) print "В тени ты видишь другую себя.^"; else print "^"; } if (self in balcony) { Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_UPSTAIRS_CORRIDOR_); if (self.smashed) print "Треснувшая стеклянная дверь "; else print "Стеклянная дверь "; print "в коридор второго этажа. "; if (IsIn(former_self,upstairs_corridor)) print "В тени ты видишь другую себя.^"; else print "^"; } ], when_closed [; if (self in balcony) "На юге дверь в коридор закрыта."; else "В северном конце коридора — закрытая стеклянная дверь на балкон."; ], when_open [; if (self in balcony) "На юге дверь в коридор открыта."; else "В северном конце коридора — открытая стеклянная дверь на балкон."; ], door_to [; if (self in upstairs_corridor) return balcony; if (self in balcony) return upstairs_corridor; ], door_dir [; if (self in upstairs_corridor) return n_to; if (self in balcony) return s_to; ], before [; Close: if (((self in balcony) && IsIn(former_self,upstairs_corridor)) || ((self in upstairs_corridor) && IsIn(former_self,balcony)) ) { CloseParadox(); return true; } Open: if (((self in balcony) && IsIn(former_self,upstairs_corridor)) || ((self in upstairs_corridor) && IsIn(former_self,balcony)) ) { OpenParadox(); return true; } else return (OpenManualDoor(self,second)); Unlock: if (IsOfType(second,crowbar)) <>; if (((self in balcony) && IsIn(former_self,upstairs_corridor)) || ((self in upstairs_corridor) && IsIn(former_self,balcony)) ) { LockUnlockParadox(); return true; } else return (UnlockManualDoor(self,second)); Lock: if (((self in balcony) && IsIn(former_self,upstairs_corridor)) || ((self in upstairs_corridor) && IsIn(former_self,balcony)) ) { LockUnlockParadox(); return true; } else return (LockManualDoor(self,second)); Attack: if (AmHolding(crowbar)) { print "Ты крепко прикладываешься ломом к двери. Оно вздрагивает, в месте удара появляются трещины, но стекло остается на месте.^"; self.smashed = true; StartSiren(); return true; } else "У тебя нет ничего достаточно тяжелого, чтобы сломать дверь."; Search: <>; ], smashed false, with_key_type nothing, found_in upstairs_corridor balcony, has ; Object conference_window "окн/о в конференц-зал" with name 'окно' 'стекл' 'tinted' 'remains' 'оскол', description [; if (self in balcony) { if (self has open) "Останки оконного стекла, разбитого чем-то тяжелым. Из краев до сих пор торчат большие осколки, дополняя мрачный интерьер конференц-зала."; else if (FlashLit()) "Ох, сколько в нем звезд!"; else "Сквозь окно виден мрачный интерьер конференц-зала."; } if (self in conference_room) { Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,X_BALCONY_); if (self has open) print "Останки оконного стекла, разбитого чем-то тяжелым. Из краев до сих пор торчат большие осколки, обрамляя звездное небо. "; else "За окном — звездная ночь. "; if (IsIn(former_self,balcony)) print "На фоне звезд ты различаешь силуэт другой себя.^"; else print "^"; } ], when_closed [; if (self in balcony) "На юго-востоке — большое тонированное окно."; if (self in conference_room) "На севере — большое стеклянное удивительно целое окно."; ], when_open [; if (self in balcony) "На юго-востоке лежат разбитые останки окна, глядящего в мрачный конференц-зал."; if (self in conference_room) "На севере лежат разбитые останки окна, глядящего в звездную ночь."; ], 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) "Похоже, окно заперто изнутри."; Unlock: if (IsOfType(second, crowbar)) <>; else if (second ~= nothing) "Ты не сможешь открыть этим окно."; else "Ты не можешь найти замок."; Attack: if (AmHolding(crowbar)) { if (self has open) "Окно уже достаточно «обработано»."; give self open; print "Ты крепко прикладываешься ломом к окну, и оно с громким звоном разбивается.^"; StartSiren(); return true; } else "У тебя нет ничего достаточно тяжелого, чтобы разбить окно."; Search: <>; ], with_key_type nothing, found_in balcony conference_room, has neuter static locked door lockable; !============================================================================ ! ! Functions: ! !---------------------------------------------------- ! ! Entry point functions: ! Puts the time in HH:MM:SS format on the status line [ InitGlkWindow winrock; switch (winrock) { GG_STATUSWIN_ROCK: glk_stylehint_set(gg_statuswin, style_User1, stylehint_ReverseColor, 1); gg_statuswin_size = 1; ! or however many lines you want } rfalse; ! leaving out this line will lead to a messy crash! ]; [ DrawStatusLine width; ! If we have no status window, we must not try to redraw it. if (gg_statuswin == 0) return; ! If there is no player location, we shouldn't try either. if (location == nothing || parent(player) == nothing) return; glk_window_get_size(gg_statuswin, gg_arguments, gg_arguments+4); width = gg_arguments-->0; glk_set_window(gg_statuswin); glk_window_clear(gg_statuswin); glk_set_style(style_User1); spaces width; glk_window_move_cursor(gg_statuswin, 3, 0); PrintShortName(location); glk_window_move_cursor(gg_statuswin, width-14, 0); print " ", (PrintTime) my_time, " "; glk_set_style(style_Normal); glk_set_window(gg_mainwin); ]; [ ScoreSub; if (deadflag == 0) "В этой игре не ведется счет."; ]; [ 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(); bomb-->i-->3 = "взрывн/ое устройств/о с таймером"; id_card-->i = IDCard_.create(); id_card-->i-->3 = "пропуск/"; equipment_key-->i = EquipmentKey_.create(); equipment_key-->i-->3 = "стар/ый латунн/ый ключ/"; deutsch_key-->i = DeutschKey_.create(); deutsch_key-->i-->3 = "ярк/ий стальн/ой ключ/"; flashlight-->i = Flashlight_.create(); flashlight-->i-->3 = "фонарик/"; battery-->i = Battery_.create(); battery-->i-->3 = "батарейк/а"; cable-->i = Cable_.create(); cable-->i-->3 = "плоск/ий кабел/ь"; crowbar-->i = Crowbar_.create(); crowbar-->i-->3 = "лом/"; notes-->i = Notes_.create(); notes-->i-->3 = "/коллекция_записей"; } 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(); former_self-->i-->3 = "друг/ая Натали Уильямс"; move former_self-->i to limbo; } InitHistory(); glk_set_style(style_Emphasized); print "12+"; glk_set_style(style_Normal); "^ ^ Ты внутри.^ ^ План простой: заходишь в свою лабораторию, устанавливаешь бомбу и убегаешь. Прототип будет уничтожен. У военных не будет возможности продолжить эксперимент. Никто не погибнет.^ ^ Охрана снаружи патрулирует территорию. В здании пусто. У тебя шесть минут.^ ^ "; ]; !---------------------------------------------------- ! ! 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, "охранник бросает последний взгляд на коридор прежде чем уйти. Негромкий звук доносится из лаборатории Дойча. Он поворачивается.^"; print "^Время распадается...^"; Devours(my_time); return true; } !! replace those items the player brought with them FixBombSettings(time_amount); FixFlashlightStates(); for (j=0 : j < Exp(2,time_travelled) : j++) { ReplaceTravellingItem(bomb, j); ReplaceTravellingItem(id_card, j); ReplaceTravellingItem(equipment_key, j); ReplaceTravellingItem(deutsch_key, j); ReplaceTravellingItem(flashlight, j); ReplaceTravellingItem(cable, j); ReplaceTravellingItem(crowbar, j); ReplaceTravellingItem(notes, j); !! tricky battery issues, since they can be in flashlights !! if other items could be in containers this would hurt here too if (PlayerHas(battery-->j)) { if (battery-->j in player) move battery-->(j+Exp(2,time_travelled)) to player; else { for (i=0 : i < Exp(2,time_travelled) : i++) if (battery-->j in (flashlight-->i)) move (battery-->(j+Exp(2,time_travelled))) to (flashlight-->(i+Exp(2,time_travelled))); } } else if (LocationOf(battery-->j) == prototype_interior) { if (battery-->j in prototype_interior) move battery-->(j+Exp(2,time_travelled)) to prototype_interior; else for (i=0 : i < Exp(2,time_travelled) : i++) if (battery-->j in flashlight-->i) move battery-->(j+Exp(2,time_travelled)) to flashlight-->(i+Exp(2,time_travelled)); } } !! move all the old items and selves into limbo for (t=0 : t < Exp(2,time_travelled) : t++) { move bomb-->t to limbo; move id_card-->t to limbo; move equipment_key-->t to limbo; move deutsch_key-->t to limbo; move flashlight-->t to limbo; move battery-->t to limbo; move cable-->t to limbo; move crowbar-->t to limbo; move notes-->t to limbo; } for (t=0 : t < time_travelled : t++) move former_self-->t to limbo; !! fix up history of immediate past self so 'player' becomes appropriate former self for (s = EARLIEST_TIME : s <= FINAL_TIME : s++) { for (t=0 : t < Exp(2,time_travelled) : t++) { if (Get3D(bomb_loc, time_travelled, (s - EARLIEST_TIME), t) == player) Put3D(bomb_loc, time_travelled, (s - EARLIEST_TIME), t, former_self-->time_travelled); if (Get3D(id_card_loc, time_travelled, (s - EARLIEST_TIME), t) == player) Put3D(id_card_loc, time_travelled, (s - EARLIEST_TIME), t, former_self-->time_travelled); if (Get3D(equipment_key_loc, time_travelled, (s - EARLIEST_TIME), t) == player) Put3D(equipment_key_loc, time_travelled, (s - EARLIEST_TIME), t, former_self-->time_travelled); if (Get3D(deutsch_key_loc, time_travelled, (s - EARLIEST_TIME), t) == player) Put3D(deutsch_key_loc, time_travelled, (s - EARLIEST_TIME), t, former_self-->time_travelled); if (Get3D(flashlight_loc, time_travelled, (s - EARLIEST_TIME), t) == player) Put3D(flashlight_loc, time_travelled, (s - EARLIEST_TIME), t, former_self-->time_travelled); if (Get3D(battery_loc, time_travelled, (s - EARLIEST_TIME), t) == player) Put3D(battery_loc, time_travelled, (s - EARLIEST_TIME), t, former_self-->time_travelled); if (Get3D(cable_loc, time_travelled, (s - EARLIEST_TIME), t) == player) Put3D(cable_loc, time_travelled, (s - EARLIEST_TIME), t, former_self-->time_travelled); if (Get3D(crowbar_loc, time_travelled, (s - EARLIEST_TIME), t) == player) Put3D(crowbar_loc, time_travelled, (s - EARLIEST_TIME), t, former_self-->time_travelled); if (Get3D(notes_loc, time_travelled, (s - EARLIEST_TIME), t) == player) Put3D(notes_loc, time_travelled, (s - EARLIEST_TIME), t, former_self-->time_travelled); } } !! recreate the world as it was for most recent former self !! (ie move a lot of old items and selves back to the world) !! (fix states of doors and machine) for (i=0 : i < Exp(2,time_travelled) : i++) { move bomb-->i to Get3D(bomb_loc,time_travelled,my_time-EARLIEST_TIME,i); move id_card-->i to Get3D(id_card_loc,time_travelled,my_time-EARLIEST_TIME,i); move equipment_key-->i to Get3D(equipment_key_loc,time_travelled,my_time-EARLIEST_TIME,i); move deutsch_key-->i to Get3D(deutsch_key_loc,time_travelled,my_time-EARLIEST_TIME,i); move flashlight-->i to Get3D(flashlight_loc,time_travelled,my_time-EARLIEST_TIME,i); move battery-->i to Get3D(battery_loc,time_travelled,my_time-EARLIEST_TIME,i); move cable-->i to Get3D(cable_loc,time_travelled,my_time-EARLIEST_TIME,i); move crowbar-->i to Get3D(crowbar_loc,time_travelled,my_time-EARLIEST_TIME,i); move notes-->i to Get3D(notes_loc,time_travelled,my_time-EARLIEST_TIME,i); } for (t=0 : t <= time_travelled : t++) { if (Get2D(player_loc,t,my_time-EARLIEST_TIME) == nothing) move former_self-->t to limbo; else move former_self-->t to Get2D(player_loc,t,my_time-EARLIEST_TIME); } if (my_time < prototype_fixed_time) prototype.fixed = false; SetBombs(); SetFlashlights(); SetPanel(panel_setting); SetBasementLight(basement_equipment_light); SetGroundLight(ground_equipment_light); SetAutomaticDoor(main_doors, main_doors_state); SetAutomaticDoor(basement_door, basement_door_state); SetAutomaticDoor(ground_door, ground_door_state); SetAutomaticDoor(upstairs_door, upstairs_door_state); SetManualDoor(balcony_door, balcony_door_state); SetManualDoor(conference_window, conference_window_state); SetManualDoor(deutsch_door, deutsch_door_state); SetManualDoor(basement_equipment_door, basement_equipment_door_state); SetManualDoor(ground_equipment_door, ground_equipment_door_state); SetBrokenDoor(main_doors, main_doors_smashed); SetBrokenDoor(basement_door, basement_door_smashed); SetBrokenDoor(ground_door, ground_door_smashed); SetBrokenDoor(upstairs_door, upstairs_door_smashed); SetBrokenDoor(balcony_door, balcony_door_smashed); !! initialise the history for the new self from the most recent self for (t = EARLIEST_TIME : t <= FINAL_TIME : t++) { for (i=0 : i < MAX_ITEM_COPIES : i++) { Put3D(bomb_loc, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(bomb_loc, time_travelled, (t - EARLIEST_TIME), i)); Put3D(id_card_loc, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(id_card_loc, time_travelled, (t - EARLIEST_TIME), i)); Put3D(equipment_key_loc, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(equipment_key_loc, time_travelled, (t - EARLIEST_TIME), i)); Put3D(deutsch_key_loc, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(deutsch_key_loc, time_travelled, (t - EARLIEST_TIME), i)); Put3D(flashlight_loc, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(flashlight_loc, time_travelled, (t - EARLIEST_TIME), i)); Put3D(battery_loc, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(battery_loc, time_travelled, (t - EARLIEST_TIME), i)); Put3D(cable_loc, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(cable_loc, time_travelled, (t - EARLIEST_TIME), i)); Put3D(crowbar_loc, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(crowbar_loc, time_travelled, (t - EARLIEST_TIME), i)); Put3D(notes_loc, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(notes_loc, time_travelled, (t - EARLIEST_TIME), i)); Put3D(bomb_setting, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(bomb_setting, time_travelled, (t - EARLIEST_TIME), i)); Put3D(flashlight_state, time_travelled+1, (t - EARLIEST_TIME), i, Get3D(flashlight_state, time_travelled, (t - EARLIEST_TIME), i)); } Put2D(dangerous_activity, time_travelled+1, (t - EARLIEST_TIME), Get2D(dangerous_activity, time_travelled, (t - EARLIEST_TIME))); Put2D(activity_target, time_travelled+1, (t - EARLIEST_TIME), Get2D(activity_target, time_travelled, (t - EARLIEST_TIME))); Put2D(siren_state, time_travelled+1, (t - EARLIEST_TIME), Get2D(siren_state, time_travelled, (t - EARLIEST_TIME))); Put2D(panel_setting, time_travelled+1, (t - EARLIEST_TIME), Get2D(panel_setting, time_travelled, (t - EARLIEST_TIME))); Put2D(basement_equipment_light, time_travelled+1, (t - EARLIEST_TIME), Get2D(basement_equipment_light, time_travelled, (t - EARLIEST_TIME))); Put2D(ground_equipment_light, time_travelled+1, (t - EARLIEST_TIME), Get2D(ground_equipment_light, time_travelled, (t - EARLIEST_TIME))); Put2D(main_doors_state, time_travelled+1, (t - EARLIEST_TIME), Get2D(main_doors_state, time_travelled, (t - EARLIEST_TIME))); Put2D(basement_door_state, time_travelled+1, (t - EARLIEST_TIME), Get2D(basement_door_state, time_travelled, (t - EARLIEST_TIME))); Put2D(ground_door_state, time_travelled+1, (t - EARLIEST_TIME), Get2D(ground_door_state, time_travelled, (t - EARLIEST_TIME))); Put2D(upstairs_door_state, time_travelled+1, (t - EARLIEST_TIME), Get2D(upstairs_door_state, time_travelled, (t - EARLIEST_TIME))); Put2D(balcony_door_state, time_travelled+1, (t - EARLIEST_TIME), Get2D(balcony_door_state, time_travelled, (t - EARLIEST_TIME))); Put2D(conference_window_state, time_travelled+1, (t - EARLIEST_TIME), Get2D(conference_window_state, time_travelled, (t - EARLIEST_TIME))); Put2D(deutsch_door_state, time_travelled+1, (t - EARLIEST_TIME), Get2D(deutsch_door_state, time_travelled, (t - EARLIEST_TIME))); Put2D(basement_equipment_door_state, time_travelled+1, (t - EARLIEST_TIME), Get2D(basement_equipment_door_state, time_travelled, (t - EARLIEST_TIME))); Put2D(ground_equipment_door_state, time_travelled+1, (t - EARLIEST_TIME), Get2D(ground_equipment_door_state, time_travelled, (t - EARLIEST_TIME))); Put2D(main_doors_smashed, time_travelled+1, (t - EARLIEST_TIME), Get2D(main_doors_smashed, time_travelled, (t - EARLIEST_TIME))); Put2D(basement_door_smashed, time_travelled+1, (t - EARLIEST_TIME), Get2D(basement_door_smashed, time_travelled, (t - EARLIEST_TIME))); Put2D(ground_door_smashed, time_travelled+1, (t - EARLIEST_TIME), Get2D(ground_door_smashed, time_travelled, (t - EARLIEST_TIME))); Put2D(upstairs_door_smashed, time_travelled+1, (t - EARLIEST_TIME), Get2D(upstairs_door_smashed, time_travelled, (t - EARLIEST_TIME))); Put2D(balcony_door_smashed, time_travelled+1, (t - EARLIEST_TIME), Get2D(balcony_door_smashed, time_travelled, (t - EARLIEST_TIME))); } time_travelled++; return true; ]; [ReplaceTravellingItem thing_type i; if (PlayerHas(thing_type-->i)) move thing_type-->(i+Exp(2,time_travelled)) to player; else if (LocationOf(thing_type-->i) == prototype_interior) move thing_type-->(i+Exp(2,time_travelled)) to prototype_interior; ]; [FixBombSettings time_amount i; for (i=0 : i < Exp(2,time_travelled) : i++) { if (PlayerHas(bomb-->i) || (LocationOf(bomb-->i) == prototype_interior)) if ((bomb-->i).time_value ~= NA_) (bomb-->(i+Exp(2,time_travelled))).time_value = (bomb-->i).time_value - time_amount; (bomb-->i).time_value = NA_; } ]; [FixFlashlightStates i; for (i=0 : i < Exp(2,time_travelled) : i++) { if (PlayerHas(flashlight-->i) || (LocationOf(flashlight-->i) == prototype_interior)) { if (flashlight-->i has on) give flashlight-->(i+Exp(2,time_travelled)) on; else give flashlight-->(i+Exp(2,time_travelled)) ~on; } give flashlight-->i ~on; } ]; !---------------------------------------------------- ! ! Little utility functions: [IsOfType thing thing_type i; for (i=0 : i < MAX_ITEM_COPIES : i++) if (thing_type-->i == thing) return true; return false; ]; [AmHolding thing_type i; for (i=0 : i < MAX_ITEM_COPIES : i++) if (thing_type-->i ~= nothing && thing_type-->i in player) return true; return false; ]; [GetHeld thing_type i; for (i=0 : i < MAX_ITEM_COPIES : i++) if (thing_type-->i ~= nothing && thing_type-->i in player) return thing_type-->i; return false; ]; [IsIn thing_type loc i; for (i=0 : i < MAX_ITEM_COPIES : i++) if (thing_type-->i ~= nothing && thing_type-->i in loc) return true; return false; ]; [GetFrom thing_type loc i; for (i=0 : i < MAX_ITEM_COPIES : i++) if (thing_type-->i ~= nothing && thing_type-->i in loc) return thing_type-->i; return false; ]; ![Present thing_type t; ! for (t=0 : t < MAX_ITEM_COPIES : t++) ! if (thing_type-->t ~= nothing && thing_type-->t in real_location) ! return true; ! return false; !]; ![GetPresent thing_type t; ! for (t=0 : t < MAX_ITEM_COPIES : t++) ! if (thing_type-->t ~= nothing && thing_type-->t in real_location) ! return thing_type-->t; ! return false; !]; [BatteriesContained thing batteries i; batteries = 0; for (i=0 : i < MAX_ITEM_COPIES : i++) if (battery-->i ~= nothing && battery-->i in thing) batteries++; return batteries; ]; [StartSiren; if (siren_start_time == UNKNOWN_ || siren_start_time > my_time) siren_start_time = my_time; ]; [MoveMoveableChildren old_loc new_loc x y; while (child(old_loc)) { x = nothing; y = child(old_loc); if ((y hasnt static) && (y ~= player)) { x = y; } while (sibling(y)) { y = sibling(y); if ((y hasnt static) && (y ~= player)) { x = y; } } if (x ~= nothing) { move x to new_loc; } else break; } ]; [ LocationOf x; if (parent(x) == 0) return x; else return LocationOf(parent(x)); ]; [ PlayerHas x; if (parent(x) == 0) return false; if (parent(x) == player) return true; return PlayerHas(parent(x)); ]; [ Flashlit i; for (i=0 : i < MAX_ITEM_COPIES : i++) { if (flashlight-->i ~= nothing && (flashlight-->i in player or real_location) && flashlight-->i has on) return true; } return false; ]; [PrintTime t; if (t == NA_) return true; print (t/720), ":", ((t/12)%60)/10, (t/12)%10, ":", ((t%12)/2); if ((t%2) == 0) print "0"; else print "5"; if (t/(720*12) == 0) print " am"; else print " pm"; ]; [PrintShortTime t; print (t/720), ":", ((t/12)%60)/10, (t/12)%10; if (t/(720*12) == 0) print ""; ! am else print " пополудни"; ! pm ]; [IncTime; InformLibrary.end_turn_sequence(); ]; !! x == run_through, y == time_index [Put2D array x y thing; array-->((x * (GAME_LENGTH+1)) + y) = thing; ]; !! x == run_through, y == time_index [Get2D array x y; return array-->((x * (GAME_LENGTH+1)) + y); ]; !! x == run_through, y == time_index, z == thing_number [Put3D array x y z thing; array-->( (z*(MAX_TIME_TRAVELS+1) + x)*(GAME_LENGTH+1) + y ) = thing; ]; !! x == run_through, y == time_index, z == thing_number [Get3D array x y z; return array-->( (z*(MAX_TIME_TRAVELS+1) + x)*(GAME_LENGTH+1) + y ); ]; [Exp b e i result; result = 1; for (i=0 : ii).time_value); } ]; [ObserveFlashlights i; for (i=0 : i < MAX_ITEM_COPIES : i++) { Put3D(flashlight_state, time_travelled, (my_time - EARLIEST_TIME), i, flashlight-->i has on); } ]; [ObserveSiren siren_on; siren_on = (siren_start_time ~= UNKNOWN_) && (siren_start_time < my_time); Put2D(siren_state, time_travelled, my_time - EARLIEST_TIME, siren_on); ]; [ObservePanel; Put2D(panel_setting, time_travelled, my_time - EARLIEST_TIME, control_panel.time_value); ]; [ObserveGroundLight light_array; Put2D(light_array, time_travelled, my_time - EARLIEST_TIME, ground_equipment.lit); ]; [ObserveBasementLight light_array; Put2D(light_array, time_travelled, my_time - EARLIEST_TIME, basement_light_switch.blown); ]; [ObserveBrokenDoor door door_smashed; Put2D(door_smashed, time_travelled, my_time - EARLIEST_TIME, door.smashed); ]; [ObserveManualDoor door door_state door_status; if (door has locked) door_status = LOCKED_; else { if (door has open) door_status = OPEN_; else door_status = CLOSED_; } Put2D(door_state, time_travelled, my_time - EARLIEST_TIME, door_status); ]; [ObserveAutomaticDoor door door_state door_status; if (door has locked) door_status = 0; else door_status = door.to_close_at; Put2D(door_state, time_travelled, my_time - EARLIEST_TIME, door_status); ]; [ObserveLocations i; Put2D(player_loc, time_travelled, (my_time - EARLIEST_TIME), parent(player)); for (i=0 : i < MAX_ITEM_COPIES : i++) { Put3D(bomb_loc, time_travelled, (my_time - EARLIEST_TIME), i, parent(bomb-->i) ); Put3D(id_card_loc, time_travelled, (my_time - EARLIEST_TIME), i, parent(id_card-->i) ); Put3D(equipment_key_loc, time_travelled, (my_time - EARLIEST_TIME), i, parent(equipment_key-->i) ); Put3D(deutsch_key_loc, time_travelled, (my_time - EARLIEST_TIME), i, parent(deutsch_key-->i) ); Put3D(flashlight_loc, time_travelled, (my_time - EARLIEST_TIME), i, parent(flashlight-->i) ); Put3D(battery_loc, time_travelled, (my_time - EARLIEST_TIME), i, parent(battery-->i) ); Put3D(cable_loc, time_travelled, (my_time - EARLIEST_TIME), i, parent(cable-->i) ); Put3D(crowbar_loc, time_travelled, (my_time - EARLIEST_TIME), i, parent(crowbar-->i) ); Put3D(notes_loc, time_travelled, (my_time - EARLIEST_TIME), i, parent(notes-->i) ); } ]; !---------------------------------------------------- ! ! 'Set' functions: (these take care of certain former actions every turn) [SetBombs setting_now i; for (i=0 : i < Exp(2,time_travelled) : i++) { setting_now = Get3D(bomb_setting,time_travelled,my_time-EARLIEST_TIME,i); (bomb-->i).time_value = setting_now; } ]; [SetFlashlights setting_now i; for (i=0 : i < Exp(2,time_travelled) : i++) { setting_now = Get3D(flashlight_state,time_travelled,my_time-EARLIEST_TIME,i); if (setting_now == true) give flashlight-->i on; else give flashlight-->i ~on; } ]; [SetPanel setting_array setting_now; setting_now = Get2D(setting_array, time_travelled, my_time - EARLIEST_TIME); control_panel.time_value = setting_now; ]; [SetBasementLight setting_array setting_now; setting_now = Get2D(setting_array, time_travelled, my_time - EARLIEST_TIME); basement_light_switch.blown = setting_now; ]; [SetGroundLight setting_array setting_now; setting_now = Get2D(setting_array, time_travelled, my_time - EARLIEST_TIME); ground_equipment.lit = setting_now; if (setting_now) give ground_light_switch on; else give ground_light_switch ~on; ]; [SetManualDoor door door_state door_status; door_status = Get2D(door_state, time_travelled, my_time - EARLIEST_TIME); if (door_status == LOCKED_) { give door ~open; give door locked; } if (door_status == CLOSED_) { give door ~open; give door ~locked; } if (door_status == OPEN_) { give door open; give door ~locked; } if (door_status == UNKNOWN_) { print "Ошибка: неизвестный статус двери следует установить."; } ]; [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 "В лаборатории Дойча останки прототипа тлеют на полу. Другая ты не появляется.^"; print "^Время распадается...^"; Devours(my_time); } else if (d_destroyed_prototype && (my_time == start_time)) { d_paradox = true; deadflag = 3; Seperator(); print (PrintTime) (my_time), "^^"; print "В другом месте ты из прошлого входит в фойе и вдыхает едкий дым от недавнего взрыва.^"; print "^Время распадается...^"; 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) "Ты слышишь приглушенное пение откуда-то из здания."; ]; [MaybeShout; if (Get2D(dangerous_activity, time_travelled-1, my_time-EARLIEST_TIME-1) == SHOUT_) if (player notin limbo) "Ты слышишь приглушенное пение откуда-то из здания."; ]; !!! a little tricky to ensure that when two bombs are in same room that the one set !!! has the same original setting as it should (ie is indistinguishable from former one) [MaybeSetBombs setting_now setting_next loc_now b i j; for (i=0 : i < Exp(2,time_travelled-1) : i++) { setting_now = Get3D(bomb_setting,time_travelled-1,my_time-EARLIEST_TIME-1,i); setting_next = Get3D(bomb_setting,time_travelled-1,my_time-EARLIEST_TIME,i); loc_now = Get3D(bomb_loc,time_travelled-1,my_time-EARLIEST_TIME-1,i); if (setting_now ~= setting_next) { if (IsIn(bomb, loc_now)) { if (IsIn(former_self,LocationOf(GetFrom(bomb, loc_now)))) { for (j=0 : j < MAX_ITEM_COPIES : j++) if ((bomb-->j ~= nothing) && (bomb-->j in loc_now)) if ((bomb-->j).time_value == setting_now) b = bomb-->j; ! print "<<< setting bomb (via maybeset) >>>^"; if (b ~= nothing) b.time_value = setting_next; ! else ! print "<<>>^"; } } ! else ! print "<<0, " in ", (name) loc_now, ! " (wanted to set it to ", setting_next, ")>>>^"; } } ]; !!! a little tricky to ensure that when two flashlights are in same room that the one set !!! has the same original setting as it should (ie is indistinguishable from former one) [MaybeSetFlashlights setting_now setting_next loc_now f i j; for (i=0 : i < Exp(2,time_travelled-1) : i++) { setting_now = Get3D(flashlight_state,time_travelled-1,my_time-EARLIEST_TIME-1,i); setting_next = Get3D(flashlight_state,time_travelled-1,my_time-EARLIEST_TIME,i); loc_now = Get3D(flashlight_loc,time_travelled-1,my_time-EARLIEST_TIME-1,i); if (setting_now ~= setting_next) { if (IsIn(flashlight, loc_now)) { if (IsIn(former_self,LocationOf(GetFrom(flashlight, loc_now)))) { for (j=0 : j < MAX_ITEM_COPIES : j++) if ((flashlight-->j ~= nothing) && (flashlight-->j in loc_now)) if ((flashlight-->j has on) == setting_now) f = flashlight-->j; ! print "<<< setting flashlight (via maybeset) >>>^"; if (f ~= nothing) { if (setting_next == true) give f on; else give f ~on; } ! else ! print "<<>>^"; } } ! else ! print "<<0, " in ", (name) loc_now, ! " (wanted to set it to ", setting_next, ")>>>^"; } } ]; [MaybeSetPanel setting_array setting_now setting_next; setting_now = Get2D(setting_array, time_travelled - 1, my_time - EARLIEST_TIME - 1); setting_next = Get2D(setting_array, time_travelled - 1, my_time - EARLIEST_TIME); if (setting_next ~= UNKNOWN_ && setting_next ~= setting_now) { control_panel.time_value = setting_next; } ]; [MaybeSetBasementLight setting_array setting_now setting_next; setting_now = Get2D(setting_array, time_travelled - 1, my_time - EARLIEST_TIME - 1); setting_next = Get2D(setting_array, time_travelled - 1, my_time - EARLIEST_TIME); if (setting_next ~= UNKNOWN_ && setting_next ~= setting_now) { basement_light_switch.blown = setting_next; } ]; [MaybeSetGroundLight setting_array setting_now setting_next; setting_now = Get2D(setting_array, time_travelled - 1, my_time - EARLIEST_TIME - 1); setting_next = Get2D(setting_array, time_travelled - 1, my_time - EARLIEST_TIME); if (setting_next ~= UNKNOWN_ && setting_next ~= setting_now) { ground_equipment.lit = setting_next; if (setting_next) give ground_light_switch on; else give ground_light_switch ~on; } ]; [MaybeCloseAutomaticDoor door; if (door.just_closed) door.just_closed = false; if (~~deadflag) if (door.to_close_at == my_time - 1) door.close_self(); ]; !! Opens/closes/locks/unlocks doors for the past self and catches paradoxes that could not !! be seen, but where the locked/unlocked state of the door differs and interferes with the action. !! Also works when the former self unlocks an unlocked door or locks !! a locked door, but this door had the converse state and the key actually turns. [MaybeSetManualDoor door door_state past_door_status_now past_door_status_next present_door_status_now the_action t; for (t=0 : ti) in (former_self-->t)) { flash_i_batteries = BatteriesContained(flashlight-->i); past_count = 0; present_count = 0; for (j=0 : j < MAX_ITEM_COPIES : j++) if ((flashlight-->j) in (former_self-->t)) if (BatteriesContained(flashlight-->j) == flash_i_batteries) present_count++; for (j=0 : j < MAX_ITEM_COPIES : j++) { flash_j_loc = Get3D(flashlight_loc,t,my_time-EARLIEST_TIME,j); flash_j_batteries = 0; for (k=0 : kj)) flash_j_batteries++; } if (flash_j_loc == former_self-->t) if (flash_j_batteries == flash_i_batteries) past_count++; } if (present_count ~= past_count) { too_heavy = (past_count < present_count); trouble = true; } } } BLOW_BASEMENT_LIGHT_: if (Get2D(basement_equipment_light, time_travelled, my_time-EARLIEST_TIME-1) == true) trouble = true; } if (trouble) { d_paradox = true; deadflag = 3; Seperator(); switch (action_de_jour) { X_CCTV_: print "В фойе другая ты смотрит в экран видеонаблюдения и видит тебя в темном коридоре.^"; X_UPSTAIRS_CORRIDOR_: if (former_self-->t in balcony) print "С холодного балкона другая ты смотрит сквозь стеклянную дверь и видит тебя в темном коридоре.^"; else print "С площадки у лестницы другая ты смотрит сквозь стекло и видит тебя в темном коридоре.^"; X_UPSTAIRS_LANDING_: print "Из коридора второго этажа другая ты смотрит сквозь стеклянную дверь и видит тебя на полутемной лестничной площадке.^"; X_GROUND_CORRIDOR_: print "Из фойе другая ты смотрит сквозь стеклянную дверь и видит тебя в темном коридоре.^"; X_FOYER_: if (former_self-->t in upstairs_landing) print "С площадки наверху другая ты смотрит вниз и видит тебя.^"; else print "Из коридора первого этажа другая ты смотрит сквозь стеклянную дверь и видит тебя.^"; X_BASEMENT_CORRIDOR_: print "С лестничной площадки подвала другая ты смотрит сквозь стеклянную дверь и видит тебя в темном коридоре.^"; X_BASEMENT_LANDING_: print "Из коридора подвала другая ты смотрит сквозь стеклянную дверь и видит тебя на темной лестничной площадке.^"; X_BALCONY_: if (former_self-->t in upstairs_corridor) print "Из коридора второго этажа другая ты смотрит сквозь стеклянную дверь и видит тебя на холодном балконе.^"; else print "Из темного конференц-зала выглядывает другая ты и видит тебя на холодном балконе.^"; TAKE_FLASHLIGHT_: if (too_heavy) print (Nearby) 0, "другая ты поднимает фонарик, но обнаруживает, что он вдруг стал тяжелым.^"; else print (Nearby) 0, "другая ты поднимает фонарик, но обнаруживает, что он вдруг стал легким.^"; BLOW_BASEMENT_LIGHT_: print "В аппаратной подвала другая ты включает выключатель, но лампы не мигают, поскольку уже перегорели.^"; } if ((action_de_jour >= X_CCTV_) && (action_de_jour <= X_BALCONY_)) print "^Это один из самых глупых способов уничтожить Бостон.^"; print "^Время распадается...^"; 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, "другая ты заходит в ", (string) fs_loc.Acc, " и видит, что ", (CNom) door, " закрыта.^"; print "^Время распадается...^"; 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, "другая ты заходит в ", (string) fs_loc.Acc, " и видит открытую ", (CAcc) door, ".^"; else print (Nearby) 0, "другая ты в ", (string) fs_loc.Pre, " видит, что ", (CNom) door, " открыта.^"; } else print (Nearby) 0, "другая ты заходит в ", (string) fs_loc.Acc, " и видит разбитое окно.^"; print "^Время распадается...^"; 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 "В ", (string) fs_loc.Pre, ", другая ты видит трещину в ", (CPre) door, ".^"; else print "В ", (string) fs_loc.Pre, ", другая ты слышит звуки удара лома о ", (CAcc) door, ".^"; print "^Время распадается...^"; 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, "другая ты заходит в ", (string) fs_loc.Acc, " и видит меняющиеся цифры, вспыхивающие на таймере взрывного устройства.^"; print "^Время распадается...^"; 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, "другая ты заходит в ", (string) fs_loc.Acc, " и видит тонкий белый луч света там, где только что была темнота.^"; else print (Nearby) 0, "другая ты заходит в ", (string) fs_loc.Acc, " и обнаруживает темноту, там, где только что был луч света.^"; print "^Время распадается...^"; 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, "другая ты заходит в коридор первого этажа и видит свет, струящийся из-за двери аппаратной.^"; else print (Nearby) 0, "другая ты открывает дверь в аппаратную на первом этаже, и яркий свет флуоресцентных ламп внезапно освещает ее.^"; } else { if (Get2D(ground_equipment_door_state,t,my_time-EARLIEST_TIME-1)==OPEN_) print (Nearby) 0, "другая ты заходит в коридор первого этажа, но не обнаруживает на полу света из аппаратной.^"; else print (Nearby) 0, "другая ты открывает дверь в аппаратную на первом этаже, но обнаруживает, что свет не включен.^"; } print "^Время распадается...^"; 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 "^Пронзительно звучит сирена.^"; if (my_time - siren_start_time > 1) print "^Сирена завывает.^"; d_paradox = true; deadflag = 3; Seperator(); print (Nearby) 0, "другая ты вздрагивает от звука сирены.^"; print "^Время распадается...^"; 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 "Зайдя в ", (string) LocationOf(former_self-->t).Acc, " другая ты быстро оглядывается. "; if (past_count > present_count) print "В отличии от прошлого раза, ее взгляд проходит прямо над тем местом, где лежал", (VPEnd) thing_type-->0, (CNom) thing_type-->0, ".^"; else print "Когда ее взгляд падает на ", (CAcc) thing_type-->0, ", на ее лице появляется тревога.^"; print "^Время распадается...^"; 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 "Кто-то возникает позади тебя в тесной комнате. Мягкие волосы и встревоженные глаза. Это ты.^"; print "^Время распадается...^"; Devours(my_time); } else if (player_loc_now ~= player_loc_next) { !! if the player had moved... d_paradox = true; deadflag = 3; Seperator(); print "Как только ты заходишь в ", (string) player_loc_next.Acc, ", то видишь перед собой другую себя. Услышав твои тихие шаги, она оборачивается. Ее глаза наполняются ужасом.^"; print "^Время распадается...^"; Devours(my_time); } else if (fs_loc_now ~= fs_loc_next) { !! if the former self had moved... d_paradox = true; deadflag = 3; Seperator(); print "Ты оборачиваешься на звук шагов. Это ты.^"; print "^Время распадается...^"; Devours(my_time); } else print "Ошибка, другая ты увидела игрока, но никто из вас не двигался.^"; } else if ((player_loc_next == fs_loc_now) && (player_loc_now == fs_loc_next)) { d_paradox = true; deadflag = 3; Seperator(); print "Как только ты заходишь в ", (string) player_loc_next.Acc, ", твои глаза видят приближающуюся фигуру. Она останавливается, страх охватывает ее.^"; print "^Время распадается...^"; Devours(my_time); } else if ((player_loc_next == deutsch_lab) && (fs_loc_next == prototype_interior)) { d_paradox = true; deadflag = 3; Seperator(); print "Согнувшись внутри прототипа другая ты замечает тебя из открытого люка.^"; print "^Время распадается...^"; Devours(my_time); } else if ((player_loc_next == prototype_interior) && (fs_loc_next == deutsch_lab)) { d_paradox = true; deadflag = 3; Seperator(); print "Как только другая ты начинает осматриваться ее взгляд останавливается на каком-то предмете внутри прототипа.^"; print "^Время распадается...^"; 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 "Зайдя в ", (string) LocationOf(former_self-->t).Acc, " другая ты быстро оглядывается. "; if (past_count > present_count) print "В отличии от прошлого раза, ее взгляд проходит прямо над тем местом на ", (CPre) desk, ", где лежал ", (VPEnd) thing_type-->0, " ", (CNom) thing_type-->0, ".^"; else print "Когда ее взгляд падает на ", (CAcc) thing_type-->0, " на ее лице появляется тревога.^"; print "^Время распадается...^"; 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 "Зайдя в прототип другая ты бросает взгляд на панель управления и видит «", control_panel.time_value, "» вместо «", old_setting, "».^"; print "^Время распадается...^"; Devours(my_time); } ]; !---------------------------------------------------- ! ! Endgame functions: [CaughtInside t; d_caught = true; !-- Initial method of being caught: if (my_time > FINAL_TIME) print "^Небольшой шум позади. Чужая рука крепко хватает тебя за запястье. Вернулся охранник. Время ускользнуло от тебя.^"; else if ((siren_start_time ~= UNKNOWN_) && (my_time - siren_start_time > siren_timeout)) print "^Сквозь вой сирены ты замечаешь движение. Внезапный толчок и ты оказываешься на полу. Прибыла охрана.^"; else print "Ошибка: неизвестная причина по которой тебя схватили^"; !-- Allow a small amount of time for bomb to explode before player dragged off... for (t=0 : (ti).time_value >= FINAL_TIME) && ~~(bomb-->i in player)) { d_exploded = true; if (LocationOf(bomb-->i) == deutsch_lab or prototype_interior) d_destroyed_prototype = true; for (j=0 : j < MAX_ITEM_COPIES : j++) if (InBlastRadius(notes-->j,bomb-->i)) d_destroyed_notes = true; } ]; [ExplodeBomb i j t; if (d_exploded) return true; d_exploded = true; !-- what exploded? if ((~~(d_escaped || d_detained)) && InBlastRadius(player,bomb-->i) ) d_killed_by_bomb = true; if (~~(d_escaped || d_detained)) d_injured_by_bomb = true; if (LocationOf(bomb-->i) == deutsch_lab or prototype_interior) d_destroyed_prototype = true; for (j=0 : j < MAX_ITEM_COPIES : j++) if (InBlastRadius(notes-->j,bomb-->i)) d_destroyed_notes = true; for (t=0 : t < time_travelled : t++) if (InBlastRadius(former_self-->t, bomb-->i)) { d_fs_killed_by_bomb = true; d_paradox = true; } for (t=0 : t < time_travelled : t++) if ((LocationOf(former_self-->t) ~= limbo)) { d_fs_hears_bomb = true; d_paradox = true; } !-- Consequences of explosion if (d_killed_by_bomb == true) { print "^Бомба взрывается. С дикой силой взрывная волна прокатывается по комнате, мгновенно убивая тебя.^"; if (~~d_fs_hears_bomb) { for (t=0 : (my_time= FINAL_TIME - 3) { print "Ночь манит тебя из-за открытых дверей, но когда ты выбегаешь, чтобы встретить ее твои мечты рушит прибывшая охрана.^"; d_caught = true; DragPlayerOff(); } else if ((siren_start_time ~= UNKNOWN_) && (my_time - siren_start_time > siren_timeout - 2)) { print "Ночь манит тебя из-за открытых дверей, но когда ты выбегаешь, чтобы встретить ее мечты рушатся. На звуки сирены прибегает охрана.^"; d_caught = true; DragPlayerOff(); } !-- Deal with the true escapes: else { move player to limbo; print "Ты ускользаешь в ночь, мчишься по ночному Кембриджу, пока, наконец, не добираешься до тихого местечка, где ты оставила машину. Измученная, осторожно заводишь холодный мотор и выезжаешь к автостраде.^"; !-- Step through the rest of the time to check for paradox and/or explosion for (t=0 : (my_time About; Object "об игре" VerbDepot with name 'об'; [ WalkthroughSub; instant_action_this_turn = true; print_ret "Советы и прохождение можно найти на сайте: https://www.amirrorclear.net/flowers/game/devours/index.html.^ Вы также можете воспользоваться командой «об игре».^^ Если вы не знакомы с текстовыми приключенческими играми, рекомендуем посетить тематические сайты, например http://brasslantern.org/beginners/ или https://ifiction.ru"; ]; Verb 'прохождени' 'подсказк' 'совет' 'помощь' * -> Walkthrough; Object "прохождение" VerbDepot with name 'прохождени' 'подсказк' 'совет' 'помощь'; [ CreditsSub; instant_action_this_turn = true; print "Автор — Тоби Орд (Toby Ord )^Написано на IFComp 2004 (постконкурсная версия).^ Бета-тестирование — Стивен Бонд (Stephen Bond).^ Особая благодарность тем, кто прислал подробные отчеты об ошибках и предложения во время конкурса, особенно: Питеру Экерсли (Peter Eckersley), Оливеру Нэшу (Oliver Nash), Хьюго Торвальдсену (Hugo Thorvaldsen) и Эвину Робертсону (Evin Robertson).^ ^Оригинальная игра «All Things Devours» (Release 3 / Serial number 050325) находится в общественном достоянии и может свободно копироваться и модифицироваться.^ "; glk_set_style(style_Emphasized); print "^Информация о русскоязычной версии"; glk_set_style(style_Normal); "^Перевод с английского, адаптация для Glulx и обложка Алексея Галкина, 2022 год.^ ^Release 2 / Serial number 220224^ ^Ваши пожелания, информацию об ошибках и вопросы можно оставлять на форуме любителей интерактивной литературы. Вы можете найти меня под ником johnbrown.^ ^Выражаю благодарность otistdog с intfiction.org за консультацию по работе Inform; techniX, Khaelenmore c ifiction.ru — за сообщения об ошибках в игре и неточностях в переводе.^ ^Приятной игры! "; ]; Verb 'автор' 'перевод' * -> Credits; Object "автор" VerbDepot with name 'автор' 'перевод'; [ ResetSub; print_ret "Непонятно, что ты пытаешься сделать."; ]; Verb 'сброс' 'стоп' 'останов' 'обезвред' 'деактивир' 'разминир' * noun -> Reset; Object "сброс" VerbDepot with name 'сброс' 'стоп' 'останов' 'обезвред' 'деактивир' 'разминир'; Verb 'вест' * noun 'по'/'в' noun -> Insert; Object "провести" VerbDepot with name 'вест'; [ CompleteModificationsSub; if ((real_location == deutsch_lab) || (real_location == prototype_interior)) <>; else "Тебе нужно быть рядом с прототипом, чтобы сделать это."; ]; Verb 'завершить' * 'изменения'/'работу'/'изменения'/'модификацию'/'перестройку'/'переделку' -> CompleteModifications; Object "завершить" VerbDepot with name 'завершить'; Extend 'конч' * 'изменения'/'работу'/'изменения'/'модификацию'/'перестройку'/'переделку' -> CompleteModifications; [ ModifySub; if ((noun == prototype) || (noun == control_panel) || (noun == nothing)) { if ((real_location == deutsch_lab) || (real_location == prototype_interior)) <>; else "Для этого тебе нужно быть рядом с прототипом."; } "Непонятно, что ты хочешь сделать."; ]; Verb 'чин' 'мен' 'ремонтиров' 'модифициров' * -> Modify * noun -> Modify; Object "модифицировать" VerbDepot with name 'чин' 'мен' 'ремонтиров' 'модифициров'; [ SwitchSub; if (noun has on) <>; else <>; ]; Verb 'щелк' 'переключить' 'включить' 'выключить' * noun -> Switch; Object "переключить" VerbDepot with name 'щелк' 'переключить' 'включить' 'выключить'; !Extend 'switch' first ! * noun -> Switch; ![ SwingAtSub; if (second == nothing) ! print_ret "Ты рассекаешь ", (CIns) noun, " воздух."; ! else if (IsOfType(noun, crowbar)) ! <>; ! else if ((second == conference_window) || (second ofclass AutomaticDoor)) { ! print_ret (CNom) noun, " отскакивает от ", ! (CAcc) second, ", не причинив вреда."; ! } ! else ! <>; !]; !Extend 'удар' first ! * held -> SwingAt ! * held noun -> SwingAt ! * held 'в'/'о'/'об'/'по' noun -> SwingAt; !Extend 'swing' first ! * held -> SwingAt ! * held 'at' noun -> SwingAt ! * held 'into' noun -> SwingAt ! * held 'through' noun -> SwingAt; [ AttackWithSub; if (IsOfType(second, crowbar)) <>; else if ((noun == conference_window) || (noun ofclass AutomaticDoor)) { if (second == nothing) print_ret "Ты недостаточно сильная, чтобы сломать ", (CAcc) noun, "."; else print_ret (CCNom) second, " недостаточно крепк", (AEnd) second, ", чтобы сломать ", (CAcc) noun, "."; } else <>; ]; Extend 'атаков' * noun 'кулаком'/'рукой'/'ногой' -> AttackWith * 'по'/'об'/'в' noun held -> AttackWith * cIns_held cAcc_noun -> AttackWith * cIns_held 'по'/'об'/'в' cDat_noun -> AttackWith reverse * cAcc_noun cIns_held -> AttackWith; [ JumpDownSub; if (real_location == balcony) Jumped(); else if ((real_location == upstairs_landing) || (real_location == foyer)) { print "Ты сильно ударяешься о пол. Возможно, тебе стоило воспользоваться лестницей.^"; <>; } else "Отсюда нельзя спрыгнуть."; ]; Extend 'прыг' first * 'вниз' -> JumpDown; [ ClimbDownSub; if (real_location == balcony) Jumped(); else if ((real_location == upstairs_landing) || (real_location == foyer)) <>; else "Отсюда нельзя спуститься."; ]; Extend 'лез' first * 'вниз' -> ClimbDown; [ LockSimpleSub k; if (noun has lockable) { if (noun.with_key_type == nothing) "У тебя нет ключа."; k = GetHeld(noun.with_key_type); if (k == nothing) "У тебя нет ключа."; <>; } else "Ты не можешь это запереть."; ]; Extend 'запер' first * noun -> LockSimple; [ UnlockSimpleSub k; if (noun has lockable) { if (noun.with_key_type == nothing) "У тебя нет ключа."; k = GetHeld(noun.with_key_type); if (k == nothing) "У тебя нет ключа."; <>; } else "Ты не можешь это отпереть."; ]; Extend 'отпер' first * noun -> UnlockSimple; [ UseSub; "Нужно указать конкретное действие."; ]; Verb 'пользоват' 'воспользоват' * -> Use * noun -> Use; Object "использовать" VerbDepot with name 'пользоват' 'воспользоват'; [ PlantSub p; p = parent(noun); ; if (parent(noun) ~= p) if (noun ofclass Bomb_) if (noun.time_value == NA_) "(ты также можешь захотеть установить таймер)"; ]; [ PlantInSub p; p = parent(noun); ; if (parent(noun) ~= p) if (noun ofclass Bomb_) if (noun.time_value == NA_) "(ты также можешь захотеть установить таймер)"; ]; [ PlantOnSub p; p = parent(noun); ; if (parent(noun) ~= p) if (noun ofclass Bomb_) if (noun.time_value == NA_) "(ты также можешь захотеть установить таймер)"; ]; Extend 'установ' * noun -> Plant * noun 'в' noun -> PlantIn * noun 'на' noun -> PlantOn; !Extend 'смотр' ! * noun -> Examine; [ WaitSecondsSub t; if (noun == 0) { instant_action_this_turn = true; "Это не заняло много времени."; } if (noun < 0) { instant_action_this_turn = true; "Если бы ты могла это сделать, то не построила бы прототип."; } print "Проходит время.^"; if (noun%5 ~= 0) { if (noun/5 > 0) IncTime(); } for (t=1 : t FINAL_TIME - my_time) time_in_turns = FINAL_TIME - my_time + 2; if (time_in_turns == 0 && (noun%5 ==0)) { instant_action_this_turn = true; "Это не заняло много времени."; } if (time_in_turns < 0) { instant_action_this_turn = true; "Если бы ты могла сделать это, то не построила бы прототип."; } print "Проходит время.^"; if (noun%5 ~= 0) { if (time_in_turns > 0) IncTime(); } for (t=1 : t= 24) return -1; if (minute >= 60) return -1; if (second >= 60) return -1; if (hour > 4) return 18000; ! this is to avoid integer overflow if (word == 'pm') return 18000; return (hour*60 + minute) * 60 + second; ]; ! based on the code from the DM4. ! looks for a time in the format 2:39 or 4:17:18 [ TimeOfDay first_word second_word at length colons illegal_char digits hr mn se i; first_word = NextWordStopped(); if (first_word == -1) return GPR_FAIL; at = WordAddress(wn-1); length = WordLength(wn-1); for (i=0: ii) { ':': if (colons == 0 && digits>0 && i 2) illegal_char = true; default: illegal_char = true; } } if (length < 3 || length > 8 || illegal_char || colons == 0) return GPR_FAIL; for (i=0: at->i~=':': i++, hr=hr*10) hr = hr + at->i - '0'; hr = hr/10; mn = ((at->(i+1) - '0') * 10) + at->(i+2) - '0'; if (colons == 2) { i = i+3; se = ((at->(i+1) - '0') * 10) + at->(i+2) - '0'; } second_word = NextWordStopped(); parsed_number = HoursMinsSecsWordToTime(hr, mn, se, second_word); if (parsed_number == -1) return GPR_FAIL; if (second_word ~= 'pm' or 'am') wn--; return GPR_NUMBER; ]; Extend 'жд' * number -> WaitSeconds * number 'секунд'/'сек'/'с' -> WaitSeconds * number 'ходов'/'ход'/'хода' -> WaitTurns * 'до' TimeOfDay -> WaitUntil; [ ShoutSub t; print "Ты громко кричишь.^"; for (t=0 : tt notin limbo) && ((siren_start_time == UNKNOWN_) || (siren_start_time > my_time))) { d_paradox = true; deadflag = 3; Seperator(); print (Nearby) 0, "другая ты слышит приглушенные звуки твоего пения.^^Какой-то странный способ убить миллионы людей...^"; print "^Время распадается...^"; Devours(my_time); return true; } } Put2D(dangerous_activity,time_travelled,my_time-EARLIEST_TIME,SHOUT_); MaybeSing(); return true; ]; Verb 'крич' 'крикн' 'ор' 'воп' * -> Shout * topic -> Shout; Object "кричать" VerbDepot with name 'крич' 'крикн' 'ор' 'воп'; Verb 'рв' 'разорв' * noun -> Attack; Object "рвать" VerbDepot with name 'рв' 'разорв'; !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 ) { "Кнопка установлена на вертикальной поверхности, поэтому положить на нее что-либо невозможно."; } else "Непонятно, что ты хочешь сделать."; ]; Extend 'дав' first ! so that 'remove battery' works * 'на' noun -> Push * noun -> Push * noun noun -> HoldDownWith * 'на' noun noun -> HoldDownWith * 'на' noun 'используя'/'с помощью' noun -> HoldDownWith * noun 'используя'/'с помощью' noun -> HoldDownWith; Verb 'жать' * 'на' noun -> Push * noun -> Push * noun noun -> HoldDownWith * 'на' noun noun -> HoldDownWith * 'на' noun 'используя'/'с помощью' noun -> HoldDownWith * noun 'используя'/'с помощью' noun -> HoldDownWith; Object "прижать" VerbDepot with name 'жать'; [ ChallengeSub; instant_action_this_turn = true; if (challenge) "Режим испытания уже запущен."; if (first_turn) { challenge = true; siren_timeout = CHALLENGE_SIREN_TIMEOUT; early_guard_time = CHALLENGE_EARLY_GUARD_TIME; "Игра установлена на максимальную сложность. Были изменены три ключевые элемента и теперь выиграть будет значительно сложнее. Победа в данном режиме не требуется для успешного завершения игры. Он предназначен для тех, кто, пройдя игру, захочет дополнительной сложности.^ ^ Если вы хотите запустить игру в данном режиме не забудьте установить его в самом начале игры."; } else "Режим испытания может быть установлен только в первый ход."; ]; [ EndChallengeSub; instant_action_this_turn = true; challenge = false; siren_timeout = DEFAULT_SIREN_TIMEOUT; early_guard_time = EARLIEST_TIME; "Сейчас игра на обычной сложности."; ]; Verb 'испытание' * -> Challenge * 'вкл'/'включить' -> Challenge * 'выкл'/'выключить' -> EndChallenge; Object "испытание" VerbDepot with name 'испытание'; Extend 'нач' * 'испытание' -> Challenge * 'режим испытания' -> Challenge; Extend 'завершить' * 'испытание' -> EndChallenge * 'режим' 'испытания' -> EndChallenge; !============================================================================