include "terminal" obj { nam = 'tower_key_0'; value = 1; disp = 'Красный ключ'; disp2 = 'красный ключ'; disp3 = 'красный ключ'; dsc = 'Небольшой ключ из красноватого металла. '; } obj { nam = 'tower_key_1'; value = 2; disp = 'Золотой ключ'; disp2 = 'золотой ключ'; disp3 = 'золотой ключ'; dsc = 'Небольшой ключ из золотистого металла. '; } obj { nam = 'tower_key_2'; value = 3; disp = 'Синий ключ'; disp2 = 'синий ключ'; disp3 = 'синий ключ'; dsc = 'Небольшой ключ из синеватого металла. '; } obj { nam = 'tower_key_3'; value = 4; disp = 'Зеленый ключ'; disp2 = 'зеленый ключ'; disp3 = 'зеленый ключ'; dsc = 'Небольшой ключ из зеленоватого металла. '; } obj { nam = 'tower_level_2_key'; disp = 'Серебряный ключик'; inv = 'Маленький серебряный ключик с изысканной резной головкой. '; } obj { nam = 'tower_hint_1'; disp = 'Клочок бумаги'; inv = 'Небольшой клочок бумаги, на которой моим почерком написано число 434. '; } obj { nam = 'flask'; disp = 'Флакончик'; disp2 = 'флакончик'; disp3 = 'флакончик'; inv = 'Небольшой стеклянный флакончик, сейчас он пуст. '; } obj { nam = 'potion_open'; disp = 'Зелье открытия'; disp2 = 'зелье открытия'; disp3 = 'зелье открытия'; inv = 'Сваренное мной зелье открытия пахнет ржавым металлом и имеет неприятный рыжевато-серый цвет. Пробирка горячая на ощупь. '; } obj { nam = 'potion_light'; disp = 'Зелье света'; disp2 = 'зелье света'; disp3 = 'зелье света'; inv = function(s) if here()^'tower_level_3_room_2' then remove('potion_light', pl); here().light = true; _'#door':enable(); _'#shelves':enable(); _'level_3_room_2_down':enable() _'#darkness':disable(); return 'Я открываю флакончик с зельем света. Жидкость тут же начинает испаряться и воздух вокруг начинает светиться. '; else return 'Сваренное мной зелье света совершенно прозрачно и источает легкий аромат свежести, как воздух после грозы. '; end; end; } obj { nam = 'candle'; disp = 'Свечка'; disp2 = 'свечка'; disp3 = 'свечку'; inv = 'Небольшая свечка из тусклого белого воска. В ней нет совершенно ничего необычного. '; } obj { nam = 'potion_enrichment'; disp = 'Зелье обогащения'; disp2 = 'зелье обогащения'; disp3 = 'зелье обогащения'; inv = 'Сваренное мной зелье обогащения сияет словно настоящее золото. Когда я встряхиваю пробирку, мне слышится в ней звон монет. '; } obj { nam = 'emerald'; disp = 'Изумруд'; disp2 = 'изумруд'; disp3 = 'изумруд'; inv = 'Небольшой, изящно ограненный изумруд. Очень красивый. '; } obj { nam = 'password_note'; disp = 'Записка'; inv = 'В записке написано только: "Ancient_Tower_9021". '; } obj { nam = 'tool_box'; dsc = 'На одной из полок я вижу коробочку с {набором отверток}. '; disp = 'Набор отверток'; disp2 = 'набор отверток'; disp3 = 'набор отверток'; inv = 'Набор отверток для электроники. Нигде на коробке нет никаких отметок о производителе. Отвертки при это очень качественно изготовлены и прекрасно сохранились. '; }; --[[ 1. В шкафу взять чайник и чашку 2. В чайник налить воды из крана 3. Чайник поставить на плиту, чтобы он вскипел(эл-во должно быть включено) 4. Из шкафчика достать чай 5. Чай поместить в чашку 6. Налить воды в чашку - Чашку с водой/чаем и чайник нельзя бросить в котел ]] obj { state = 0; -- 0 - empty, 1 - cold water, 2 - hot water nam = 'kettle'; disp = function(s) if s.state == 0 then return 'Чайник'; elseif s.state == 1 then return 'Чайник с водой'; elseif s.state == 2 then return 'Чайник с кипятком'; end; end; disp2 = 'чайник'; disp3 = 'чайник'; inv = function(s) if s.state == 0 then return 'Самый обычный металлический чайник. Сейчас он пуст. '; elseif s.state == 1 then return 'Самый обычный металлический чайник. Сейчас он полон холодной воды. '; elseif s.state == 2 then return 'Самый обычный металлический чайник. Сейчас он наполнен кипятком. '; end; end; } obj { has_tea = false; has_water = false; nam = 'cup'; disp = function(s) if s.has_tea then return 'Чашка с пакетиком' elseif s.has_water then return 'Чашка с водой'; else return 'Пустая чашка'; end; end; disp2 = 'чашка'; disp3 = 'чашку'; inv = function(s) if s.has_tea then return 'Миниатюрная фарфоровая чашечка. Внутри лежит чайный пакетик. '; elseif s.has_water then return 'Миниатюрная фарфоровая чашечка, наполненная горячей водой. '; else return 'Миниатюрная фарфоровая чашечка. '; end; end; used = function(s, o) if o ^ 'kettle' then if o.state == 2 then if s.has_water then return 'В чашке уже достаточно воды. '; end; s.has_water = true; pr 'Я наливаю воду в чашку. '; elseif o.state == 1 then return 'В холодной воде чай не заварится. '; else return 'А что я хочу налить из пустого чайника? '; end; elseif o ^ 'teabag' then s.has_tea = true; remove('teabag', pl); pr 'Я кладу пакетик в чашку. '; else return false end; if s.has_tea and s.has_water then remove('cup', pl); take('tea'); return 'Чай готов! '; end; end; } obj { nam = 'teabag'; disp = 'Чайный пакетик'; disp2 = 'чайный пакетик'; disp3 = 'чайный пакетик'; inv = 'Обыкновенный чайный пакетик. '; } obj { nam = 'tea'; disp = 'Чашка с чаем'; disp2 = 'чашка с чаем'; disp3 = 'Чашку с чаем'; inv = 'Миниатюрная фарфоровая чашечка, наполненная ароматным напитком. '; } room { keys_taken = false; theme = 'tower'; nam = 'tower_level_1'; pic = 'images/tower_level_1.png'; disp = 'Башня, первый этаж'; decor = [[Башня встречает меня давящей темнотой и прохладой. Черные {#walls|стены} и {#ceiling|потолок} зала тонут во мраке. В зале стоят четыре огромных {#tables|стола}, покрытых белыми скатертями. На каждом стоят по три красивых серебряных {#candelabra|канделябра}. У столов расставлены массивные деревянные {#chairs|стулья}. ]]; way = { path {"Покинуть башню", "ending_left"}; path {"level_1_next_room", "В соседнюю комнату", "tower_level_1_room_2"}:disable(); path {"level_1_up", "Наверх", "tower_level_2"}:disable(); }; enter = function(s) snd.music('sound/bgm_tower.ogg'); end; }: with { obj { nam = '#walls'; act = 'Холодные и безжизненные стены кажутся чуждыми этому миру. Одно прикосновение к этой гладкой, напоминающей стекло на ощупь, поверхности вызывает у меня невольное содрогание. '; }; obj { nam = '#ceiling'; act = 'Черный сводчатый потолок скрыт в темноте. До него около четырех метров -- невероятно высоко для человека, но недостаточно для моего истинного обличия. '; }; obj { state = 0; nam = '#tables'; act = function(s) pr 'Массивные столы из черного дерева покрыты белыми, расшитыми серебром скатертями. Пыли на столах нет, словно их накрыли совсем недавно. За каждым из них можно уместить несколько десятков человек. '; if s.state == 0 then s.state = 1; pr 'На одном из столов стоит шкатулка. '; _'tower_box':enable(); end; end; }; obj { state = 0; nam = '#candelabra'; act = function(s) pr 'Изящные серебряные канделябры совершенно одинаковы. На каждом из них установлено по три свечи, дающих слабый мерцающий свет, явно недостаточный для того чтобы осветить зал. '; if s.state == 0 then s.state = 1; pr 'Я замечаю связку ключей, лежащую у одного из канделябров. ' _'#keys':enable(); else if not candle_taken then s.state = 2; take('candle'); candle_taken = true; pr 'Немного подумав, я забираю одну из свечей. '; else if s.state == 2 then pr 'Одна из свеч отсутствует. '; end; end; end; end; }; obj { nam = '#chairs'; act = 'Старинные стулья с резными спинками выглядят одновременно массивными и изящными. '; }; obj { nam = '#keys'; dsc = 'Рядом с одним из канделябров лежит {связка ключей}. '; act = function(s) here().keys_taken = true; take('tower_key_0'); take('tower_key_1'); take('tower_key_2'); take('tower_key_3'); remove('#keys', here()); return "Я забираю ключи себе. "; end; }:disable(); obj { nam = 'tower_box'; disp = 'Шкатулка'; dsc = 'На одном из столов лежит небольшая украшенная серебром {шкатулка}. '; tak = function(s) take('tower_hint_1'); return 'Я забираю шкатулку себе. Под ней я обнаруживаю небольшой клочок бумаги. Я прихватываю и его. '; end; inv = function(s) if here()^'inside_box' then return 'Я уже рассматриваю шкатулку. '; end; walkin('inside_box'); end; }:disable(); obj { state = false; nam = '#tower_1_door'; dsc = function(s) if s.state then return 'Массивная {дверь} из того же материала, что и стены, открыта. За ней виднеется {#stairwell|лестница} на следующий этаж башни. '; else return 'Массивная {дверь} из того же материала, что и стены, преграждает проход в остальные помещения башни. '; end; end; act = function(s) if s.state then return 'Дверь открыта, за ней я вижу лестницу, сделанную из того же материала, что и стены башни. '; else return 'Дверь заперта. Я замечаю в ней небольшую замочную скважину, обрамленную серебром. '; end; end; used = function(s, o) if o^'hidden_key' or o^'tower_key_0' or o^'tower_key_1' or o^'tower_key_2' or o^'tower_key_3' then return 'Ключ не подходит. '; elseif o^'tower_level_2_key' then remove('tower_level_2_key', pl); s.state = true; enable('level_1_up'); return 'Я вставляю ключ в скважину. Замок работает идеально, и ключ поворачивается очень легко. Дверь открывается почти без усилий, открывая проход на следующий этаж. '; end; end; }:with { obj { nam = '#stairwell'; act = 'Широкая и пологая лестница из черного гладкого камня, ведущая на следующий этаж башни. '; } }; obj { nam = '#tower_1_kitchen_door'; dsc = 'В одной из стен есть еще одна {дверца}. '; act = function(s) if not _'level_1_next_room':disabled() then return 'Дверь слегка приоткрыта. '; else return 'Неприметная деревянная дверца. Она заперта. Я не вижу никаких способов открыть ее. '; end; end; used = function(s, o) if o^'tower_level_2_key' or o^'tower_key_0' or o^'tower_key_1' or o^'tower_key_2' or o^'tower_key_3' or o^'hidden_key' then return 'Здесь некуда вставить ключ. '; end; if o^'potion_open' then return 'Здесь нет замка, чтобы вылить в него зелье. '; end; return false; end; }; } room { nam = 'inside_box'; disp = 'Шкатулка'; nofollow = true; value = function(s) local sum = 0; if _('keyhole_1').key then sum = sum + _('keyhole_1').value * _('keyhole_1').key.value; end; if _('keyhole_2').key then sum = sum + _('keyhole_2').value * _('keyhole_2').key.value; end; if _('keyhole_3').key then sum = sum + _('keyhole_3').value * _('keyhole_3').key.value; end; if _('keyhole_4').key then sum = sum + _('keyhole_4').value * _('keyhole_4').key.value; end; if sum < 10 then return '00' .. tostring(sum); elseif sum < 100 then return '0' .. tostring(sum); else return tostring(sum); end; end; test = function(s) return s:value() == '434'; end; decor = function(s) return [[Небольшая деревянная шкатулка, украшенная тонкими серебряными орнаментами. В одной из граней шкатулки я вижу обрамленный в серебряную рамочку счетчик с цифрами: "]] .. s:value() .. [[". Под счетчиком я вижу четыре замочные скважины. ]]; end; way = { path {"Назад", 'tower_level_1'}; }; }:with { obj { nam = 'keyhole_1'; value = 125; key = false; dsc = function(s) if s.key then return '{' .. s.key.disp .. '} вставлен в первую скважину. ^'; else return '{Первая скважина} пуста. ^'; end; end; used = function(s, o) if o^'tower_key_0' or o^'tower_key_1' or o^'tower_key_2' or o^'tower_key_3' then s.key = o; remove(o, pl); pl:need_scene(true); pr('Я вставляю ' .. o.disp2 .. ' в скважину и поворачиваю его. Число на счетчике изменяется. '); if _('inside_box'):test() then remove('tower_box', pl); remove('tower_hint_1', pl); take('tower_level_2_key'); pr('В коробочке что-то щелкает и она открыватся. Внутри вы находите небольшой серебряный ключик. '); walkout(); end; end; end; act = function(s) pl:need_scene(true); if s.key then local key = s.key; take(key); s.key = false; return 'Я вытаскиваю ' .. key.disp2 .. ' из скважины. '; else return 'Небольшая замочная скважина. '; end; end; }; obj { nam = 'keyhole_2'; value = 25; key = false; dsc = function(s) if s.key then return '{' .. s.key.disp .. '} вставлен во вторую скважину. ^'; else return '{Вторая скважина} пуста. ^'; end; end; used = function(s, o) if o^'tower_key_0' or o^'tower_key_1' or o^'tower_key_2' or o^'tower_key_3' then s.key = o; remove(o, pl); pl:need_scene(true); pr('Я вставляю ' .. o.disp2 .. ' в скважину и поворачиваю его. Число на счетчике изменяется. '); if _('inside_box'):test() then remove('tower_box', pl); remove('tower_hint_1', pl); take('tower_level_2_key'); pr('В коробочке что-то щелкает и она открыватся. Внутри вы находите небольшой серебряный ключик. '); walkout(); end; end; end; act = function(s) pl:need_scene(true); if s.key then local key = s.key; take(key); s.key = false; return 'Я вытаскиваю ' .. key.disp2 .. ' из скважины. '; else return 'Небольшая замочная скважина. '; end; end; }; obj { nam = 'keyhole_3'; value = 5; key = false; dsc = function(s) if s.key then return '{' .. s.key.disp .. '} вставлен в третью скважину. ^'; else return '{Третья скважина} пуста. ^'; end; end; used = function(s, o) if o^'tower_key_0' or o^'tower_key_1' or o^'tower_key_2' or o^'tower_key_3' then s.key = o; remove(o, pl); pl:need_scene(true); pr('Я вставляю ' .. o.disp2 .. ' в скважину и поворачиваю его. Число на счетчике изменяется. '); if _('inside_box'):test() then remove('tower_box', pl); remove('tower_hint_1', pl); take('tower_level_2_key'); pr('В коробочке что-то щелкает и она открыватся. Внутри вы находите небольшой серебряный ключик. '); walkout(); end; end; end; act = function(s) pl:need_scene(true); if s.key then local key = s.key; take(key); s.key = false; return 'Я вытаскиваю ' .. key.disp2 .. ' из скважины. '; else return 'Небольшая замочная скважина. '; end; end; }; obj { nam = 'keyhole_4'; value = 1; key = false; dsc = function(s) if s.key then return '{' .. s.key.disp .. '} вставлен в четвертую скважину. '; else return '{Четвертая скважина} пуста. ^'; end; end; used = function(s, o) if o^'tower_key_0' or o^'tower_key_1' or o^'tower_key_2' or o^'tower_key_3' then s.key = o; remove(o, pl); pl:need_scene(true); pr('Я вставляю ' .. o.disp3 .. ' в скважину и поворачиваю его. Число на счетчике изменяется. '); if _('inside_box'):test() then remove('tower_box', pl); remove('tower_hint_1', pl); take('tower_level_2_key'); pr('В коробочке что-то щелкает и она открыватся. Внутри вы находите небольшой серебряный ключик. '); walkout(); end; end; end; act = function(s) pl:need_scene(true); if s.key then local key = s.key; take(key); s.key = false; return 'Я вытаскиваю ' .. key.disp3 .. ' из скважины. '; else return 'Небольшая замочная скважина. '; end; end; }; } room { nam = 'tower_level_2'; pic = 'images/tower_level_2_l.png'; disp = 'Башня, второй этаж'; theme = 'tower'; decor = [[Второй этаж башни представляет собой алхимическую лабораторию. Вдоль {#walls|стен} расположены {#tables|столы} и {#racks|стеллажи}. Над некоторыми столами висят {#cabinets|шкафчики}. В центре зала установлен громадный {tower_cauldron|котел}, под которым пылает {#fire|огонь}. ]]; way = { path {"Вниз", "tower_level_1"}; path {"level_2_next_room", "В соседнюю комнату", "tower_level_2_room_2"}:disable(); path {"level_2_up", "Наверх", "tower_level_3"}:disable(); }; }:with { obj { nam = '#walls'; act = 'Холодные и безжизненные стены кажутся чуждыми этому миру. Одно прикосновение к этой гладкой, напоминающей стекло на ощупь, поверхности вызывает у меня невольное содрогание. '; }; obj { state = 0; nam = '#tables'; act = function(s) pr 'Тяжелые столешницы из черного камня покоятся на прочных и устойчивых ножках. Столы уставлены всевозможными алхимическими приборами, пробирками и колбочками. '; if s.state == 0 then s.state = 1; _'red_catalyst':enable(); pr [[На одном из столов я замечаю пробирку с красной жидкостью.]]; end; end; }; obj { state = 0; nam = '#racks'; act = function(s) pr 'Прочные деревянные стеллажи заполнены пробирками, колбочками и пузырьками. К сожалению, большинство из них пусты. '; if s.state == 0 then s.state = 1; _'blue_catalyst':enable(); pr [[На одной из полок я обнаруживаю пробирку с синей жидкостью. ]]; end; end; }; obj { state = 0; nam = '#cabinets'; act = function(s) pr 'Большая часть шкафчиков пуста, не считая различных алхимических приборов. '; if s.state == 0 then s.state = 1; _'green_catalyst':enable(); pr 'В одном из шкафчиков я обнаруживаю пробирку с зеленой жидкостью. '; end; end; }; obj { nam = '#fire'; act = 'Яркий огонь, кажется, совсем не греет. Свет от него едва разгоняет наполняющую зал тьму. '; }; obj { nam = 'alchemy_book'; dsc = 'На одном из столов лежит раскрытая {книга}. '; act = function(s) walkin('alchemy_book_dlg'); end; }; obj { nam = 'tower_cauldron'; act = function() walkin('cauldron_inside'); end; used = function(s, o) pl:need_scene(true); table.insert(_('cauldron_inside').state, o); remove(o, pl); sounds['bubble']:play(); pr ('Я помещаю '.. o.disp3 .. ' в котел. '); if _('cauldron_inside'):check_potion() then sounds['potion']:play(); pr ('Зелье готово!'); end; end; }; obj { state = false; nam = '#tower_2_door'; dsc = function(s) if s.state then return 'Массивная {дверь} открыта. За ней виднеется {#stairwell|лестница} на следующий этаж башни. '; else return 'Массивная {дверь} преграждает проход в остальные помещения башни. '; end; end; act = function(s) if s.state then return 'Дверь сделана из того же материала, что и стены. Сейчас она открыта, за ней я вижу лестницу, сделанную из того же материала, что и стены башни. '; else return 'Дверь сделана из того же материала, что и стены. Сейчас она заперта. Я замечаю в ней небольшую замочную скважину, обрамленная серебром. '; end; end; used = function(s, o) if o^'hidden_key' then return 'Ключ не подходит. '; elseif o^'potion_open' then remove('potion_open', pl); s.state = true; enable('level_2_up'); take('flask'); return 'Я выливаю зелье в замок и его моментально съедает ржавчина. Путь свободен. '; end; end; }: with { obj { nam = '#stairwell'; act = 'Широкая и пологая лестница из черного гладкого камня, ведущая на следующий этаж башни. '; } }; obj { nam = 'red_catalyst'; dsc = 'На одном из столов стоит {пробирка с красной жидкостью}. '; disp = 'Красный катализатор'; disp2 = 'красный катализатор'; disp3 = 'красный катализатор'; tak = 'На пробирку наклеен кусочек бумаги с надписью "Катализатор". Я забираю пробирку себе. '; inv = 'Пробирка с красной жидкостью, подписанная словом "Катализатор". '; }:disable(); obj { nam = 'green_catalyst'; dsc = 'В одном из шкафчиков есть {пробирка с зеленой жидкостью}. '; disp = 'Зеленый катализатор'; disp2 = 'зеленый катализатор'; disp3 = 'зеленый катализатор'; tak = 'На пробирку наклеен кусочек бумаги с надписью "Катализатор". Я забираю пробирку себе. '; inv = 'Пробирка с зеленой жидкостью, подписанная словом "Катализатор". '; }:disable(); obj { nam = 'blue_catalyst'; dsc = 'На одной из полок стоит {пробирка с синей жидкостью}. '; disp = 'Синий катализатор'; disp2 = 'синий катализатор'; disp3 = 'синий катализатор'; tak = 'На пробирку наклеен кусочек бумаги с надписью "Катализатор". Я забираю пробирку себе. '; inv = 'Пробирка с синей жидкостью, подписанная словом "Катализатор". '; }:disable(); } dlg { nam = 'alchemy_book_dlg'; pic = 'images/tower_level_2_l.png'; disp = 'Алхимическая книга'; enter = 'Передо мной лежит раскрытая на оглавлении книга алхимических рецептов. Некоторые из них привлекают мое внимание. '; phr = { {always=true, "Открытие", "Состав: ключ, замок, зеленый катализатор. ^^Зелье вылить в замок, который необходимо открыть. "}; {always=true, "Свет", "Состав: Свеча, стекло, синий катализатор. ^^Зелье вылить на поверхность предмета или употребить внутрь. Эффект длится от одного до трех часов. "}; {always=true, "Обогащение", "Состав: драгоценный металл, драгоценный камень, красный катализатор. ^^Выпейте это зелье и вы обогатитесь. Осторожно, радиактивно!"}; {always=true, "[Отойти от книги]", function() walkout(); end} }; } dlg { state = {}; potion = false; hideinv = true; nam = 'cauldron_inside'; pic = 'images/tower_level_2_l.png'; disp = 'Котел'; check_potion = function(s) if #s.state == 3 then if has_object(s.state, 'lock') and has_object(s.state, 'hidden_key') and has_object(s.state, 'green_catalyst') then s.potion = _('potion_open'); return true; elseif has_object(s.state, 'candle') and has_object(s.state, 'flask') and has_object(s.state, 'blue_catalyst') then s.potion = _('potion_light'); return true; elseif has_object(s.state, 'silver_fork') and has_object(s.state, 'emerald') and has_object(s.state, 'red_catalyst') then s.potion = _('potion_enrichment'); return true; end; end; return false; end; enter = function(s) if s.potion then enable('#take_potion'); disable('#take_all'); return 'В котле приготовлено ' .. s.potion.disp2 .. '. '; elseif #s.state == 0 then disable('#take_potion'); disable('#take_all'); return 'Котел полон кипящей воды. '; elseif #s.state == 1 then disable('#take_potion'); enable('#take_all'); return 'В котле сейчас находится ' .. s.state[1].disp2 .. '. '; else disable('#take_potion'); enable('#take_all'); local dsc = 'В котле сейчас находятся: '; for i = 1, #s.state do dsc = dsc .. s.state[i].disp2; if i < #s.state then dsc = dsc .. ', '; end; end; return dsc .. '. '; end; end; phr = { {'#take_potion', '[Забрать зелье]', function(s) local potion = _('cauldron_inside').potion; _('cauldron_inside').state = {}; take(potion); _('cauldron_inside').potion = false; pr "Я набираю получившееся зелье в пробирку. "; walkout(); end}; {'#take_all', '[Забрать все из котла]', function(s) local state = _('cauldron_inside').state; _('cauldron_inside').state = {}; for i = 1, #state do take(state[i]); end; walkout(); end}; {always=true, '[Отойти от котла]', function(s) walkout(); end;}; } } room { nam = 'tower_level_3'; theme = 'tower'; disp = 'Башня, третий этаж'; pic = 'images/tower_level_3.png'; decor = [[Третий этаж представляет собой чей-то уютный кабинет. В помещении царит полумрак. Вдоль одной из стен установлены {#bookshelves|книжные полки}, а в стену напротив них вмонтирован пылающий {#fireplace|камин}. Чуть поодаль от него стоит старое {#rockchair|кресло-качалка}. В центре комнаты расположен массивный деревянный {tower_level_3_table|стол}.]]; way = { path {"Вниз", "tower_level_2"}; path {"level_3_next_room", "В соседнюю комнату", "tower_level_3_room_2"}:disable(); path {"level_3_up", "Наверх", "tower_level_4"}:disable(); }; }:with { obj { nam = '#bookshelves'; act = 'Я пробегаю взглядом по корешкам книг. Многие из них очень старые, некоторые из них написаны на неизвестных мне языках. Здесь есть как художественные произведения, так и труды философов и ученых разных эпох. '; }; obj { nam = '#fireplace'; act = 'Несмотря на пылающий в камине огонь, в помещении царят полумрак и прохлада. Весело потрескивающие угольки и мерцающие на стенах тени от пляшущего пламени расслабляют и успокаивают. '; }; obj { nam = '#rockchair'; act = 'Старинное кресло-качалка из дуба с мягкой гобеленовой обивкой. Кресло в превосходном состоянии -- на нем нет ни единой царапинки или потертости, обивка так же выглядит как новая.'; }; obj { nam = 'level_3_room_2_door'; dsc = 'За одной из книжных полок скрывается небольшая {дверца}. '; act = 'Я не заметил бы ее, если бы не знал, что она там есть. '; }:disable(); obj { solved = false; nam = 'tower_level_3_table'; act = function(s) if s.solved then return 'Огромный стол занимает значительное пространство в центре комнаты. Полированная поверхность блестит в мерцающем свете камина. В поверхности стола так же есть пять шестиугольных углублений, четыре из которых отмечены сторонами света: NW, NE, SE, SW, а еще одна, в центре, оставлена без отметки. В каждом углублении стоит небольшая фигурка из серебристого металла. По периметру стола витиеватым почерком нанесена какая-то надпись. '; else walkin('tower_level_3_table_in'); end; end; }; obj { nam = '#tower_3_door'; dsc = function(s) if _'level_3_up':disabled() then return 'Массивная {дверь} из того же материала, что и стены, заперта. '; else return 'Массивная {дверь} из того же материала, что и стены, открыта. За ней виднеется {#stairwell|лестница} на следующий этаж башни. '; end; end; act = function(s) if _'level_3_up':disabled() then return 'Дверь заперта. Я не вижу в ней никаких отверстий. '; else return 'Дверь открыта, за ней я вижу {#stairwell|лестницу}, сделанную из того же материала, что и стены башни.'; end; end; }: with { obj { nam = '#stairwell'; act = 'Широкая и пологая лестница из черного гладкого камня, ведущая на следующий этаж башни. '; } }; } room { nam = 'tower_level_3_table_in'; theme = 'tower'; nofollow = true; disp = 'Башня, третий этаж'; decor = [[Огромный стол занимает значительное пространство в центре комнаты. Полированная поверхность блестит в мерцающем свете камина. В поверхности стола так же есть пять шестиугольных углублений, четыре из которых отмечены сторонами света: NW, NE, SE, SW, а еще одна, в центре, оставлена без отметки. По периметру стола витиеватым почерком нанесена какая-то {#hint|надпись}. ]]; way = { path {"Назад", 'tower_level_3'}; }; }:with { obj { nam = '#figures'; dsc = 'На нем стоят {пять фигурок} из серебристого металла. ^'; act = function(s) take('figure_wolf'); take('figure_tiger'); take('figure_lion'); take('figure_knight'); take('figure_tower'); remove('#figures', here()); return 'Я поднимаю фигурки со стола. '; end; }; obj { item = false; target = 'figure_wolf'; nam = '#north_west'; dsc = function(s) if s.item then return 'В углубении NW стоит {' .. s.item.disp2 .. '}. ^'; else return '{Углубление NW} пусто. ^'; end; end; act = function(s) if s.item then local t = s.item; take(s.item); s.item = false; return 'Я забираю ' .. t.disp3 .. ' из углубления'; else return 'Небольшое шестиугольное углубление. '; end; end; used = function(s, o) if s.item then return 'В углублении уже стоит ' .. s.item.disp2; elseif o^'figure_wolf' or o^'figure_lion' or o^'figure_tower' or o^'figure_knight' or o^'figure_tiger' then s.item = o; pr('Я помещаю ' .. o.disp3 .. ' в углубление. '); remove(o, pl); local niches = { _('#north_west'); _('#north_east'); _('#middle'); _('#south_west'); _('#south_east'); }; for i = 1, #niches do if not niches[i].item or niches[i].item.nam ~= niches[i].target then return; end; end; _('tower_level_3_table').solved = true; walkout(); _('level_3_up'):enable(); pr 'Легкий щелчок дает мне понять, что дверь на следующий этаж башни открыта. '; end; end; }; obj { item = false; target = 'figure_lion'; nam = '#north_east'; dsc = function(s) if s.item then return 'В углубении NE стоит {' .. s.item.disp2 .. '}. ^'; else return '{Углубление NE} пусто. ^'; end; end; act = function(s) if s.item then local t = s.item; take(s.item); s.item = false; return 'Я забираю ' .. t.disp3 .. ' из углубления'; else return 'Небольшое шестиугольное углубление. '; end; end; used = function(s, o) if s.item then return 'В углублении уже стоит ' .. s.item.disp2; elseif o^'figure_wolf' or o^'figure_lion' or o^'figure_tower' or o^'figure_knight' or o^'figure_tiger' then s.item = o; pr('Я помещаю ' .. o.disp3 .. ' в углубление. '); remove(o, pl); local niches = { _('#north_west'); _('#north_east'); _('#middle'); _('#south_west'); _('#south_east'); }; for i = 1, #niches do if not niches[i].item or niches[i].item.nam ~= niches[i].target then return; end; end; _('tower_level_3_table').solved = true; walkout(); _('level_3_up'):enable(); pr 'Легкий щелчок дает мне понять, что дверь на следующий этаж башни открыта. '; end; end; }; obj { item = false; target = 'figure_tower'; nam = '#middle'; dsc = function(s) if s.item then return 'В центральном углубении стоит {' .. s.item.disp2 .. '}. ^'; else return '{Центральное углубление} пусто. ^'; end; end; act = function(s) if s.item then local t = s.item; take(s.item); s.item = false; return 'Я забираю ' .. t.disp3 .. ' из углубления'; else return 'Небольшое шестиугольное углубление. '; end; end; used = function(s, o) if s.item then return 'В углублении уже стоит ' .. s.item.disp2; elseif o^'figure_wolf' or o^'figure_lion' or o^'figure_tower' or o^'figure_knight' or o^'figure_tiger' then s.item = o; pr('Я помещаю ' .. o.disp3 .. ' в углубление. '); remove(o, pl); local niches = { _('#north_west'); _('#north_east'); _('#middle'); _('#south_west'); _('#south_east'); }; for i = 1, #niches do if not niches[i].item or niches[i].item.nam ~= niches[i].target then return; end; end; _('tower_level_3_table').solved = true; walkout(); _('level_3_up'):enable(); pr 'Легкий щелчок дает мне понять, что дверь на следующий этаж башни открыта. '; end; end; }; obj { item = false; target = 'figure_knight'; nam = '#south_west'; dsc = function(s) if s.item then return 'В углубении SW стоит {' .. s.item.disp2 .. '}. ^'; else return '{Углубление SW} пусто. ^'; end; end; act = function(s) if s.item then local t = s.item; take(s.item); s.item = false; return 'Я забираю ' .. t.disp3 .. ' из углубления'; else return 'Небольшое шестиугольное углубление. '; end; end; used = function(s, o) if s.item then return 'В углублении уже стоит ' .. s.item.disp2; elseif o^'figure_wolf' or o^'figure_lion' or o^'figure_tower' or o^'figure_knight' or o^'figure_tiger' then s.item = o; pr('Я помещаю ' .. o.disp3 .. ' в углубление. '); remove(o, pl); local niches = { _('#north_west'); _('#north_east'); _('#middle'); _('#south_west'); _('#south_east'); }; for i = 1, #niches do if not niches[i].item or niches[i].item.nam ~= niches[i].target then return; end; end; _('tower_level_3_table').solved = true; walkout(); _('level_3_up'):enable(); pr 'Легкий щелчок дает мне понять, что дверь на следующий этаж башни открыта. '; end; end; }; obj { item = false; target = 'figure_tiger'; nam = '#south_east'; dsc = function(s) if s.item then return 'В углубении SE стоит {' .. s.item.disp2 .. '}. ^'; else return '{Углубление SE} пусто. ^'; end; end; act = function(s) if s.item then local t = s.item; take(s.item); s.item = false; return 'Я забираю ' .. t.disp3 .. ' из углубления'; else return 'Небольшое шестиугольное углубление. '; end; end; used = function(s, o) if s.item then return 'В углублении уже стоит ' .. s.item.disp2; elseif o^'figure_wolf' or o^'figure_lion' or o^'figure_tower' or o^'figure_knight' or o^'figure_tiger' then s.item = o; pr('Я помещаю ' .. o.disp3 .. ' в углубление. '); remove(o, pl); local niches = { _('#north_west'); _('#north_east'); _('#middle'); _('#south_west'); _('#south_east'); }; for i = 1, #niches do if not niches[i].item or niches[i].item.nam ~= niches[i].target then return; end; end; _('tower_level_3_table').solved = true; walkout(); _('level_3_up'):enable(); pr 'Легкий щелчок дает мне понять, что дверь на следующий этаж башни открыта. '; end; end; }; obj { nam = '#hint'; act = [[На столе я замечаю следующий текст:^ Пятеро их, у каждого цвет свой: белый, алый, лазурный, зеленый и черный.^ Четверым дано время: полдень, полночь, рассвет и закат, пятый – вне времени.^ Четверым дан сезон: осень, лето, весна и зима, пятый – вне времени.^ Четверым даны луны: растущая, полная, убывающая и новая, пятый – вне времени.^ Четверо к пятому, в центре стоящему, обращены.^ На северо-западе место полной луны. Владения новой, зеленой – напротив ее.^ Тигр в полдень бродит по землям своим.^ Зима не на юге, но и не на востоке. Весна не на западе.^ Башня – вне времени, лишь цвет ей присущ.^ Волк в полночь обходит владенья свои, тот что летом владеет – напротив его.^ Луна убывает на севере, белый закат пребывает на юге.^ Черный – в центре, окружен он рассветом, закатом, полночью и полднем.^ Лев алый весенний рассвет собой воплощает.]]; } } obj { nam = 'figure_wolf'; disp = 'Фигурка волка'; disp2 = 'фигурка волка'; disp3 = 'фигурку волка'; inv = 'Фигурка волка, рыщущего в поисках добычи из неизвестного мне серебристого металла. Очень красивая и детально проработанная, она закреплена на шестиугольном основании из того же металла. '; } obj { nam = 'figure_tiger'; disp = 'Фигурка тигра'; disp2 = 'фигурка тигра'; disp3 = 'фигурку тигра'; inv = 'Фигурка бегущего тигра из неизвестного мне серебристого металла. Очень красивая и детально проработанная, она закреплена на шестиугольном основании из того же металла. '; } obj { nam = 'figure_lion'; disp = 'Фигурка льва'; disp2 = 'фигурка льва'; disp3 = 'фигурку льва'; inv = 'Фигурка льва, стоящего с гордо поднятой головой и смотрящего куда-то вдаль. Сделана из неизвестного мне серебристого металла. Очень красивая и детально проработанная, она закреплена на шестиугольном основании из того же металла.'; } obj { nam = 'figure_knight'; disp = 'Фигурка рыцаря'; disp2 = 'фигурка рыцаря'; disp3 = 'фигурку рыцаря'; inv = 'Фигурка рыцаря в полном доспехе, стоящего, опершись на громадный двуручный меч. Сделана из неизвестного мне серебристого металла. Очень красивая и детально проработанная, она закреплена на шестиугольном основании из того же металла.'; } obj { nam = 'figure_tower'; disp = 'Фигурка башни'; disp2 = 'фигурка башни'; disp3 = 'фигурку башни'; inv = 'Фигурка высокой шестиугольной башни -- уменьшенной копии той, в которой я сейчас нахожусь. Сделана из неизвестного мне серебристого металла. Фигурка настолько проработана, она закреплена на шестиугольном основании из того же металла.'; } room { nam = 'tower_level_4'; theme = 'tower'; disp = 'Башня, четвертый этаж'; pic = 'images/tower_level_4.png'; decor = [[Я нахожусь в просторной комнате. Как и в других помещениях башни, черные {#walls|стены} лишены окон. В центре комнаты расположена роскошная {#bed|кровать} с тяжелым балдахином из плотной черной ткани, украшенной серебряными нитями. Рядом с кроватью стоит небольшой круглый {#table|столик} с серебряным {#candelabra|канделябром} на нем. ]]; way = { path {"Вниз", "tower_level_3"}; path {"level_4_next_room", "В соседнюю комнату", "tower_level_4_room_2"}:disable(); }; enter = function(s) snd.music('sound/bgm_tower.ogg'); end; }: with { obj { nam = '#walls'; act = 'Гладкие стены из неизвестного мне черного камня. На плитах нет никаких следов времени -- ни единой царапины, ни единого скола, ни единой выщербины. '; }; obj { nam = '#bed'; act = 'Огромная кровать накрыта белоснежной простыней, расшитой серебром. У изголовья лежит большая подушка в белой наволочке с кружевами. Для человека кровать крайне просторна, но она все еще слишком мала для дракона... Да и драконы не спят в кроватях... '; }; obj { nam = '#table'; act = 'Небольшой столик из роскошного черного дерева держится на единственной массивной ножке. '; }; obj { nam = '#candelabra'; state = 0; act = function(s) if candles_solved then if not candle_taken then s.state = 1; take('candle'); candle_taken = true; return 'Немного подумав, я забираю одну из свечей. '; else if s.state == 0 then return 'Изящный серебряный канделябр на семь свечей. Сейчас свечи не горят. '; else return 'Изящный серебряный канделябр на семь свечей. Сейчас свечи не горят. Одна из свечей отсутствует. '; end; end; else walkin('tower_candelabra'); end; end; }; obj { nam = '#tower_4_door'; dsc = function(s) if _'level_4_next_room':disabled() then return 'В дальней стене расположена небольшая деревянная {дверца}. '; else return 'Деревянная {дверь} в дальнем конце зала открыта. '; end; end; act = function(s) if _'level_4_next_room':disabled() then return 'Дверь заперта. Я не вижу никаких способов открыть ее. '; else return 'Дверь открыта, за ней я вижу просторный зал, уставленный высокими стойками с серверами.'; end; end; }; } function candle(title, note, index, note_lang, filename) return obj { nam = 'candle_' .. note; dsc = '{' .. title .. '}^'; act = function(s) sounds[filename]:play(); pr('Я зажигаю свечу. Откуда-то издали доносится нота ' .. note_lang .. '. '); s:disable(); if here().notestack[here().playindex] ~= index then _('tower_candelabra').timerstate = 1; here().playindex = 1; timer:set(300); _'candle_c':enable(); _'candle_d':enable(); _'candle_e':enable(); _'candle_f':enable(); _'candle_g':enable(); _'candle_a':enable(); _'candle_b':enable(); pr 'Неведомо откуда взявшийся порыв ветра гасит зажженные свечи. '; local candelabra = _'tower_candelabra'; pr '^В темноте раздается последовательность звуков: '; for i = 1, 6 do pr(candelabra.notes[candelabra.notestack[i]][1] .. ', '); end; pr(candelabra.notes[candelabra.notestack[7]][1], '. '); else here().playindex = here().playindex + 1; if here().playindex > 7 then candles_solved = true; _('level_4_next_room'):enable(); _('tower_candelabra').timerstate = 4; pr [[Дверца в дальнем конце комнаты распахивается от резкого порыва ветра. ]]; local ns = { gusts[rnd(#gusts)]; 'open_door'; }; stop_sound(); play_sound(ns, 600); walkout(); end; end; end; }; end; room { notes = { {'до', 'note_c'}; {'ре', 'note_d'}; {'ми', 'note_e'}; {'фа', 'note_f'}; {'соль', 'note_g'}; {'ля', 'note_a'}; {'си', 'note_b'}; }; text = ''; notestack = {}; notesequence = {}; playindex = 1; timerstate = 3; nam = 'tower_candelabra'; disp = 'Башня, четвертый этаж'; theme = 'tower'; nofollow = true; dsc = [[Изящный канделябр на семь свечей. ]]; timer = function(s) snd.music('sound/amb_tower.ogg'); if s.timerstate == 1 then s.timerstate = 2; sounds[gusts[rnd(#gusts)]]:play(); timer:set(1500); elseif s.timerstate == 2 then s.timerstate = 3; stop_sound(); play_sound(s.notesequence, 600, false); elseif s.timerstate == 4 then s.timerstate = 5; sounds[gusts[rnd(#gusts)]]:play(); timer:set(300); elseif s.timerstate == 5 then s.timerstate = 3; sounds['open_door']:play(); end; return false; end; enter = function(s) snd.music('sound/bgm_tower.ogg'); if #s.notestack == 0 then local ns = {1,2,3,4,5,6,7}; for i = 1, 7 do local idx = rnd(#ns); table.insert(s.notestack, ns[idx]); table.insert(s.notesequence, s.notes[ns[idx]][2]); ns[idx] = ns[8 - i]; ns[8 - i] = nil; end; end; if #s.notesequence == 0 then s.notesequence = {false, false, false}; for i = 1, 7 do table.insert(s.notesequence, s.notes[s.notestack[i]][2]); end; end; stop_sound(); play_sound(table.copy(s.notesequence), 600); pr 'Едва мой взгляд падает на канделябр, как в темноте раздается последовательность звуков: '; for i = 1, 6 do pr(s.notes[s.notestack[i]][1] .. ', '); end; pr(s.notes[s.notestack[7]][1], '. '); end; obj = { candle('Зажечь первую свечу', 'c', 1, 'до', 'note_c'); candle('Зажечь вторую свечу', 'd', 2, 'ре', 'note_d'); candle('Зажечь третью свечу', 'e', 3, 'ми', 'note_e'); candle('Зажечь четвертую свечу', 'f', 4, 'фа', 'note_f'); candle('Зажечь пятую свечу', 'g', 5, 'соль', 'note_g'); candle('Зажечь шестую свечу', 'a', 6, 'ля', 'note_a'); candle('Зажечь седьмую свечу', 'b', 7, 'си', 'note_b'); }; way = { path {'Назад', 'tower_level_4'}; }; } room { nam = 'tower_level_4_room_2'; disp = 'Башня, серверная'; theme = 'tower'; pic = function(s) if power_on then return 'images/tower_level_4_room_2_light.png'; else return 'images/tower_level_4_room_2_dark.png'; end; end; decor = [[Вдоль стен зала установлены стойки с {#servers|серверами}. В центре зала стоит массивный деревянный {#table|стол}, на котором стоит старый {#computer|компьютер}. Перед столом стоит тяжелое старинное {#armchair|кресло}. Неподалеку от стола находится {#ladder|лестница}, ведущая на нижние уровни башни. ]]; way = { path { 'В дверь', 'tower_level_4' }; path { 'Вниз', 'tower_level_3_room_2' }; }; }: with { obj { nam = '#ladder'; act = 'Прочная металлическая лестница закреплена здесь и уходит вертикально вниз. '; }; obj { nam = '#servers'; act = function(s) if power_on then return [[Сотни, если не тысячи серверов. Понятия не имею, зачем они здесь. Ровный гул работающих вентиляторов и легкое потрескивание жестких дисков говорят о том, что машины сейчас работают. Мерцающие лампочки отражают процессы происходяшие в них. ]]; else return [[Сотни, если не тысячи серверов. Понятия не имею, зачем они здесь. Сейчас они обесточены. ]]; end; end; }; obj { nam = '#table'; act = [[Крепкий дубовый стол на массивных резных ножках. На полированной поверхности нет ни единой царапины. Большую часть стола занимает компьютер. Рядом с клавиатурой лежит {#manual|руководство пользователя}. ]]; }; obj { nam = '#armchair'; act = 'Уютное старинное кресло на колесиках с мягкой гобеленовой обивкой, на которой нет ни малейших следов использования или времени. Резные спинка и подлокотники из черного дерева выглядят совершенно новыми. '; }; obj { assembled = true; nam = '#computer'; act = function(s) if s.assembled then if power_on then return _('system_unit'):check(); else return 'Внешний вид компьютера напоминает о начале 80х. Дисководы отсутствуют. Эмблема "TETS-1" на системном блоке мне ни о чем не говорит. Провода питания и локальной сети уходят куда-то под пол. На системном блоке стоит небольшой {#monitor|монитор}. Сейчас компьютер выключен -- нет электричества. '; end; else walkin('system_unit'); end; end; used = function(s, o) if o^'tool_box' then s.assembled = not s.assembled; end; if s.assembled then return [[Я собираю корпус обратно и подключаю все необходимые провода. ]]; else return [[Я отключаю все провода и, открутив несколько винтов, снимаю крышку корпуса. ]]; end; end; }; obj { nam = '#monitor'; act = 'Небольшой монитор с электронно-лучевой трубкой. Диагональ экрана составляет около 8 дюймов, справа от него я вижу ручки регулировки яркости и контрастности. '; }; obj { nam = '#manual'; act = function(s) walkin('terminal_manual'); end; }; } declare { sound_index = 1; sound_data = {} } function game:timer() if #sound_data > 0 then if sound_index > #sound_data then sound_data = {}; timer:stop(); return false; end; if sound_data[sound_index] then sounds[sound_data[sound_index]]:play(); end; sound_index = sound_index + 1; end; return false; end; function play_sound(data, speed, immediate) timer:stop(); sound_index = 1; sound_data = data; if #sound_data > 0 then if immediate then if sound_data[sound_index] then sounds[sound_data[sound_index]]:play(); end; sound_index = sound_index + 1; end; timer:set(speed); end; end; function stop_sound() timer:stop(); sound_data = {}; sound_index = 1; end; room { { data = false; sound_index = 1; }; pic = function(s) if power_on then return 'images/tower_level_4_room_2_light.png'; else return 'images/tower_level_4_room_2_dark.png'; end; end; theme = 'tower'; nam = 'system_unit'; nofollow = true; disp = 'Системный блок'; decor = 'Я заглядываю внутрь системного блока и осматриваю установленные в нем компоненты. Довольно легко я определяю где находится оперативная память, процессор, платы расширения. Маркировки чипов и типы разъемов, однако, вне этой башни мне не встречались. '; enter = function(s) local motherboard = lookup('#motherboard', _'system_unit'); local cpu = lookup('#cpu', _'system_unit'); local ram = lookup('#ram', _'system_unit'); local slot1 = lookup('#slot1', _'system_unit'); local slot2 = lookup('#slot2', _'system_unit'); local slot3 = lookup('#slot3', _'system_unit'); local slot4 = lookup('#slot4', _'system_unit'); local slots = {slot1, slot2, slot3, slot4}; local min = 1; if motherboard.device then min = motherboard.device.slots + 1; cpu:enable(); ram:enable(); else cpu:disable(); ram:disable(); end; for i = 1, min - 1 do slots[i]:enable(); end; for i = min, #slots do slots[i]:disable(); end; end; check = function(s, from_solarscale) local motherboard = lookup('#motherboard', _'system_unit'); local cpu = lookup('#cpu', _'system_unit'); local ram = lookup('#ram', _'system_unit'); local slot1 = lookup('#slot1', _'system_unit'); local slot2 = lookup('#slot2', _'system_unit'); local slot3 = lookup('#slot3', _'system_unit'); local slot4 = lookup('#slot4', _'system_unit'); local slots = {slot1, slot2, slot3, slot4}; stop_sound(); sounds["pc_startup"]:play(); if not motherboard.device or not motherboard.device.status then pc_status = 'fail'; if from_solarscale then pr [[Вентилятор в блоке питания начинает шуметь, но экран не включается. Я не слышу никаких звуковых сигналов. ]]; return 'motherboard'; else pr [[Я включаю компьютер. Вентилятор в блоке питания начинает шуметь, но экран не включается. Я не слышу никаких звуковых сигналов. ]]; return; end; end; local cpu_valid = false; if cpu.device and cpu.device.status then if motherboard.device.cpu == 'CAX' then cpu_valid = motherboard.device.cpu == cpu.device.slot; elseif motherboard.device.cpu == 'CVX' then cpu_valid = cpu.device.slot == 'CVX' or cpu.device.slot == 'CAX'; elseif motherboard.device.cpu == 'CRX' then cpu_valid = cpu.device.slot ~= 'CXX'; end; end; if not cpu_valid then play_sound({false, false, false, false, 'long_beep', false, 'short_beep', 'short_beep'}, 300); pc_status = 'fail'; if from_solarscale then pr [[Вентилятор в блоке питания начинает шуметь, но экран не включается. Я слышу последовательность звуковых сигналов: один длинный и два коротких. ]]; return "cpu"; else pr [[Я включаю компьютер. Вентилятор в блоке питания начинает шуметь, но экран не включается. Я слышу последовательность звуковых сигналов: один длинный и два коротких. ]]; return; end end; local ram_valid = false; if ram.device and ram.device.status then if motherboard.device.ram == 'RKT' then ram_valid = ram.device.slot == 'RKT'; elseif motherboard.device.ram == 'RST' then ram_valid = ram.device.slot == 'RKT' or ram.device.slot == 'RST'; elseif motherboard.device.ram == 'RDT' then ram_valid = true; end; end; if not ram_valid then play_sound({false, false, false, false, 'short_beep', 'long_beep', false, 'long_beep'}, 300); pc_status = 'fail'; if from_solarscale then pr [[Вентилятор в блоке питания начинает шуметь, но экран не включается. Я слышу последовательность звуковых сигналов: один короткий и два длинных. ]]; return "ram"; else pr [[Я включаю компьютер. Вентилятор в блоке питания начинает шуметь, но экран не включается. Я слышу последовательность звуковых сигналов: один короткий и два длинных. ]]; return; end; end; -- Now we need to find video, keyboard and network local video; local keyboard; local network; for i = 1, motherboard.device.slots do if slots[i].device then if slots[i].device.ptype == 'video' then video = slots[i].device; elseif slots[i].device.ptype == 'keyboard' then keyboard = slots[i].device; elseif slots[i].device.ptype == 'network' then network = slots[i].device; end; end; end; if not video or not video.status then play_sound({false, false, false, false, 'long_beep', false, 'short_beep', 'long_beep'}, 300); pc_status = 'fail'; if from_solarscale then pr [[Вентилятор в блоке питания начинает шуметь, но экран не включается. Я слышу последовательность звуковых сигналов: один длинный, один короткий и еще один длинный. ]]; return "video"; else pr [[Я включаю компьютер. Вентилятор в блоке питания начинает шуметь, но экран не включается. Я слышу последовательность звуковых сигналов: один длинный, один короткий и еще один длинный. ]]; return; end; end; if not keyboard or not keyboard.status then play_sound({false, false, false, false, 'long_beep', false, 'long_beep', false, 'long_beep'}, 300); pc_status = 'fail'; if from_solarscale then pr [[Вентилятор в блоке питания начинает шуметь, но экран не включается. Я слышу последовательность звуковых сигналов: три длинных. ]]; return "keyboard"; else pr [[Я включаю компьютер. Вентилятор в блоке питания начинает шуметь, но экран не включается. Я слышу последовательность звуковых сигналов: три длинных. ]]; return; end; end; _('terminal_boot').network = (network and network.status); _('terminal_boot').graphical = (video.nam == 'gva-rx4'); pc_status = 'ok'; if not from_solarscale then walkin('terminal_boot'); end; end; way = { path {'Назад', 'tower_level_4_room_2'} } }:with { obj { nam = '#motherboard'; device = _'cvx-rst-i3sb'; dsc = function(s) if s.device then return '{Материнская плата: ' .. s.device.name .. '}^'; else return '{Материнская плата: Не установлена}^'; end; end; act = function(s) local cpu= lookup('#cpu', _'system_unit'); local ram = lookup('#ram', _'system_unit'); local slot1 = lookup('#slot1', _'system_unit'); local slot2 = lookup('#slot2', _'system_unit'); local slot3 = lookup('#slot3', _'system_unit'); local slot4 = lookup('#slot4', _'system_unit'); if cpu.device or ram.device or slot1.device or slot2.device or slot3.device or slot4.device then return 'Сперва необходимо отключить все устройства. '; end; if s.device then take(s.device); s.device = false; cpu:disable(); ram:disable(); slot1:disable(); slot2:disable(); slot3:disable(); slot4:disable(); return 'Я забираю материнскую плату. '; end; end; used = function(s, o) if o.part and o.ptype == 'motherboard' then local cpu= lookup('#cpu', _'system_unit'); local ram = lookup('#ram', _'system_unit'); local slot1 = lookup('#slot1', _'system_unit'); local slot2 = lookup('#slot2', _'system_unit'); local slot3 = lookup('#slot3', _'system_unit'); local slot4 = lookup('#slot4', _'system_unit'); local slots = { slot1, slot2, slot3, slot4 }; if cpu.device or ram.device or slot1.device or slot2.device or slot3.device or slot4.device then return 'Сперва необходимо отключить все устройства. '; end; if s.device then return 'Сперва необходимо убрать установленную плату. '; end; cpu:enable(); ram:enable(); for i = 1, o.slots do slots[i]:enable(); end; remove(o, pl); s.device = o; return 'Я устанавливаю материнскую плату. '; end; end; }; obj { nam = '#cpu'; device = _'mcpu70-cvx-7mhz'; dsc = function(s) if s.device then return '{Процессор: ' .. s.device.name .. '}^'; else return '{Процессор: Не установлен}^'; end; end; act = function(s) if s.device then take(s.device); s.device = false; return 'Я забираю процессор. '; end; end; used = function(s, o) local motherboard = lookup('#motherboard', _'system_unit'); if o.part and o.ptype == 'cpu' and motherboard.device then if s.device then return 'Сперва необходимо убрать установленный процессор. '; end; motherboard = motherboard.device; if (motherboard.cpu == 'CVX' and (o.slot == 'CRX' or o.slot == 'CXX')) or (motherboard.cpu == 'CRX' and o.slot == 'CXX') or (motherboard.cpu == 'CAX' and o.slot ~= 'CAX') then return 'Процессор не подходит. '; end; remove(o, pl); s.device = o; return 'Я устанавливаю процессор. '; end; end; }; obj { nam = '#ram'; device = _'rst-m16-16mb'; dsc = function(s) if s.device then return '{Оперативная память: ' .. s.device.name .. '}^'; else return '{Оперативная память: Не установлена}^'; end; end; act = function(s) if s.device then take(s.device); s.device = false; return 'Я забираю память. '; end; end; used = function(s, o) local motherboard = lookup('#motherboard', _'system_unit'); if o.part and o.ptype == 'ram' and motherboard.device then if s.device then return 'Сперва необходимо убрать установленную память. '; end; motherboard = motherboard.device; if (motherboard.ram == 'RST' and o.slot == 'RDT') or (motherboard.ram == 'RKT' and o.slot ~= 'RKT') then return 'Память не подходит. '; end; remove(o, pl); s.device = o; return 'Я устанавливаю память. '; end; end; }; obj { nam = '#slot1'; device = _'tva-rx1'; dsc = function(s) if s.device then return '{Слот расширения: ' .. s.device.name .. '}^'; else return '{Слот расширения: Плата не установлена}^'; end; end; act = function(s) if s.device then take(s.device); s.device = false; return 'Я забираю устройство. '; end; end; used = function(s, o) local motherboard = lookup('#motherboard', _'system_unit'); if o.part and (o.ptype == 'video' or o.ptype == 'network' or o.ptype == 'keyboard') and motherboard.device then if s.device then return 'Сперва необходимо убрать установленную плату '; end; remove(o, pl); s.device = o; return 'Я устанавливаю плату. '; end; end; }; obj { nam = '#slot2'; device = _'kbc-s'; dsc = function(s) if s.device then return '{Слот расширения: ' .. s.device.name .. '}^'; else return '{Слот расширения: Плата не установлена}^'; end; end; act = function(s) if s.device then take(s.device); s.device = false; return 'Я забираю устройство. '; end; end; used = function(s, o) local motherboard = lookup('#motherboard', _'system_unit'); if o.part and (o.ptype == 'video' or o.ptype == 'network' or o.ptype == 'keyboard') and motherboard.device then if s.device then return 'Сперва необходимо убрать установленную плату '; end; remove(o, pl); s.device = o; return 'Я устанавливаю плату. '; end; end; }; obj { nam = '#slot3'; device = _'fna-100-10mbs_1'; dsc = function(s) if s.device then return '{Слот расширения: ' .. s.device.name .. '}^'; else return '{Слот расширения: Плата не установлена}^'; end; end; act = function(s) if s.device then take(s.device); s.device = false; return 'Я забираю устройство. '; end; end; used = function(s, o) local motherboard = lookup('#motherboard', _'system_unit'); if o.part and (o.ptype == 'video' or o.ptype == 'network' or o.ptype == 'keyboard') and motherboard.device then if s.device then return 'Сперва необходимо убрать установленную плату '; end; remove(o, pl); s.device = o; return 'Я устанавливаю плату. '; end; end; }; obj { nam = '#slot4'; device = false; dsc = function(s) if s.device then return '{Слот расширения: ' .. s.device.name .. '}^'; else return '{Слот расширения: Плата не установлена}^'; end; end; act = function(s) if s.device then take(s.device); s.device = false; return 'Я забираю устройство. '; end; end; used = function(s, o) local motherboard = lookup('#motherboard', _'system_unit'); if o.part and (o.ptype == 'video' or o.ptype == 'network' or o.ptype == 'keyboard') and motherboard.device then if s.device then return 'Сперва необходимо убрать установленную плату '; end; remove(o, pl); s.device = o; return 'Я устанавливаю плату. '; end; end; }; } room { light = false; nam = 'tower_level_3_room_2'; disp = 'Башня, Склад'; theme = 'tower'; pic = function(s) if power_on then return 'images/tower_level_3_room_2_power.png'; elseif s.light then return 'images/tower_level_3_room_2_light.png'; else return 'images/tower_level_3_room_2_dark.png'; end; end; decor = function(s) if s.light then return 'Помещение представляет собой колоссальных размеров склад. Рядом со мной находится {#ladder|лестница}, ведущая вверх. Точно такая же {#ladder_down|лестница}, но ведущая вниз расположена чуть поодаль. {#floor|Пол} здесь точно такой же как и в других помещениях башни. {#walls|Стены} отсюда практически не видны, скрытые многочисленными {#shelves|стеллажами}. {#ceiling|Потолок} зала расположен на высоте около пяти метров. '; else return 'Помещение представляет собой колоссальных размеров склад. В {#darkness|темноте} я могу различить лишь несколько {#shelves|стеллажей} неподалеку от себя. Рядом со мной находится {#ladder|лестница}, ведущая вверх. '; end; end; way = { path {'Наверх', 'tower_level_4_room_2'}; path {'level_3_main_room', 'В кабинет', 'tower_level_3'}:disable(); path {'level_3_room_2_down', 'Вниз', 'tower_level_2_room_2'}:disable(); }; }:with { obj { nam = '#ladder'; act = 'Прочная металлическая лестница уходит вертикально вверх на соседние этажи башни. '; }; obj { nam = '#ladder_down'; act = 'Прочная металлическая лестница уходит вертикально вниз на соседние этажи башни. '; }; obj { nam = '#floor'; act = 'Ровные каменные плиты вырезаны с потрясающей точностью и выглядят так, будто их только что сюда положили -- на них нет ни малейшего изъяна, ни единой царапины или выбоины. '; }; obj { nam = '#walls'; act = 'Я уверен, что если смогу добраться до стены, то увижу точно такую же гладкую поверхность черного камня, как и везде. '; }; obj { nam = '#ceiling'; act = function(s) if power_on then return 'На черном каменном потолке укреплены многочисленные лампы, излучающие яркий белый свет, позволяющий легко разглядеть все вокруг. '; else return 'На черном каменном потолке укреплены многочисленные лампы, но сейчас они не горят. '; end; end; }; obj { nam = '#darkness'; used = function(s, o) if o^'potion_light' then remove('potion_light', pl); here().light = true; _'#door':enable(); _'#shelves':enable(); _'level_3_room_2_down':enable() s:disable(); return 'Я открываю флакончик с зельем света и выплескивая жидкость в воздух. Она практически мгновенно обращается в светящийся пар, заполняющий все вокруг. '; elseif o^'candle' then return 'Свеча едва разгоняет мрак. Нужно что-то посильнее, чтобы нормально ориентироваться здесь. '; end; return false; end; act = [[Здесь слишком темно, чтобы что-либо разглядеть. ]]; }; obj { nam = '#door'; dsc = function(s) if _ 'level_3_main_room':disabled() then return 'В одной из стен расположена небольшая {дверь}, запертая на засов. '; else return 'В одной из стен расположена небольшая {дверь}. '; end; end; act = function(s) if _ 'level_3_main_room':disabled() then _ 'level_3_main_room':enable(); _('level_3_next_room', 'tower_level_3'):enable(); _('level_3_room_2_door', 'tower_level_3'):enable(); return [[Я отодвигаю засов. Теперь путь свободен. Дверь ведет в кабинет, расположенный на третьем этаже башни. ]]; else return [[За приоткрытой дверью я вижу кабинет. ]]; end; end; }:disable(); obj { state = 0; nam = '#shelves'; act = function(s) if not here().light then return [[Здесь слишком темно, чтобы что-либо разглядеть. ]]; elseif s.state == 0 then s.state = 1; take('tool_box'); take('emerald'); _'part_box':enable(); return [[Я осматриваю стеллажи в поисках чего-либо интересного. Я забираю с полок небольшой изумруд искусной огранки и набор отверток. Кроме всего прочего я примечаю коробку, полную запасных плат для компьютера. ]]; else return [[Больше я не вижу здесь ничего, что может мне пригодиться прямо сейчас. ]]; end; end; }; 'part_box'; } room { nam = 'tower_level_2_room_2'; theme = 'tower'; pic = function(s) if power_on then return 'images/tower_level_2_room_2_light.png'; else return 'images/tower_level_2_room_2_dark.png'; end; end; disp = 'Башня, комната управления'; onenter = function(s) if have('protection_suit', pl) then put('protection_suit', 'tower_level_2_airlock_cabinet'); remove('protection_suit', pl); return 'Я снимаю костюм радиационной защиты и оставляю его в шкафчике. '; end; end; decor = function(s) if power_on then return 'Совершенно крошечная комната. Каменные {#walls|стены}, {#floor|пол} и {#ceiling|потолок} ничем не отличаются от таковых в других комнатах. Несколько {#lamps|ламп} на потолке дают яркий белый свет. '; else return 'Совершенно крошечная комната. Каменные {#walls|стены}, {#floor|пол} и {#ceiling|потолок} ничем не отличаются от таковых в других комнатах. На потолке горят красные {#emergency_lamps|лампы} аварийного света. '; end; end; way = { path {'Наверх', 'tower_level_3_room_2'}; path {'В шлюз', 'tower_level_2_airlock'}; path {'level_2_main_room', 'В лабораторию', 'tower_level_2'}:disable(); path {'Вниз', 'tower_level_1_room_2'}; } }:with { obj { nam = '#walls'; act = 'Черные каменные стены, гладкие и холодные. Блоки, составляющие их, идеально подогнаны друг к другу. '; }; obj { nam = '#floor'; act = 'Ровные каменные плиты пола в идеальном состоянии, как и везде в этой башне. '; }; obj { nam = '#ceiling'; act = 'Потолок здесь расположен необычно низко -- я даже могу дотянуться до него рукой. Он такой же холодный и гладкий на ощупь, как и стены. '; }; obj { nam = '#lamps'; act = 'Несколько ламп дневного света расположены на потолке. '; }; obj { nam = '#emergency_lamps'; act = 'В слабом свете аварийных ламп, башня кажется еще более таинственной и ненастоящей. '; }; obj { nam = '#reactor_door'; dsc = 'В одной из стен комнаты расположена прямоугольная {дверь} с нанесенным на нее знаком радиационной опасности. '; act = 'Тяжелая и очень толстая дверь. Не стоит открывать ее на время большее, чем необходимо. '; }; obj { nam = '#control_panel'; dsc = [[Рядом с дверью расположена {панель управления}. ]]; act = function(s) walkin('reactor_control_panel'); end; }; obj { nam = '#next_door'; dsc = function(s) if _'level_2_main_room':disabled() then return 'В стене напротив панели управления расположена небольшая каменная {дверь}, закрытая на щеколду. '; else return 'В стене напротив панели управления расположена небольшая каменная {дверь}. '; end; end; act = function(s) if _'level_2_main_room':disabled() then _'level_2_main_room':enable(); _'level_2_next_room':enable(); return 'Я отодвигаю щеколду и открываю дверь. '; else return 'Через приоткрытую дверь я вижу алхимическую лабораторию. '; end; end; } } dlg { theme = 'tower'; nam = 'reactor_control_panel'; disp = 'Панель управления реактором'; pic = function(s) if power_on then return 'images/tower_level_2_room_2_light.png'; else return 'images/tower_level_2_room_2_dark.png'; end; end; enter = [[Передо мной расположена панель управления реактором. На небольшом алфавитно-цифровом дисплее светится надпись: "Введите команду". ]]; phr = { {always=true, '[Диагностика]', function(s) pn [[Я нажимаю кнопку диагностики и через некоторое время на экране высвечиваются результаты: ]]; pn [[Температура реактора в норме. ]]; pn [[Автоматическая система управления в норме. ]]; pn [[Ручная система управления в норме. ]]; if rods_raised then pn [[Производительность: 0%]]; pn [[Топливные стержни подняты. Диагностика невозможна. Включен режим энергосбережения. ]]; elseif rods_enriched then pn [[Производительность: 101%]]; pn [[Топливные стержни в норме. ]]; else pn [[Производительность: 1%]]; pn [[Топливные стержни требуют замены. Включен режим энергосбережения. ]]; end; end;}; {cond=function(s) return not rods_raised; end; always=true; '[Извлечь топливные стержни]', function(s) rods_raised = true; power_on = false; return [[Из камеры реактора доносится ровный гул, изрядно заглушенный толстыми стенами. ]]; end;}; {cond=function(s) return rods_raised; end; always=true; '[Погрузить топливные стержни]', function(s) rods_raised = false; pr [[Из камеры реактора доносится ровный гул, изрядно заглушенный толстыми стенами. ]]; if rods_enriched then power_on = true; end; end;}; {'[Отойти от панели управления]', function(s) walkout(); end;}; }; } room { theme = 'tower'; nam = 'tower_level_2_airlock'; pic = function(s) if power_on then return 'images/tower_level_2_room_2_light.png'; else return 'images/tower_level_2_room_2_dark.png'; end; end; disp = 'Башня, шлюз'; dsc = 'Свинцовые {#walls|стены} этой каморки предназначены для защиты находящихся в ней от мощного радиационного излучения. На {#ceiling|потолке} расположена единственная {#lamp|лампа}, дающая слабый красноватый свет. Думаю, что не стоит здесь задерживаться. '; way = { path {'В комнату управления', 'tower_level_2_room_2'}; path {'В реактор', 'tower_level_2_reactor'}; }; }: with { obj { nam = '#walls'; act = 'Металл, из которого сделаны эти стены, значительно снижает уровень радиации внутри, однако он не блокирует ее полностью. Лучше здесь не задерживаться. '; }; obj { nam = '#ceiling'; act = 'Свинцовый потолок находится на высоте около двух метров. Металл значительно снижает уровень радиации внутри, однако он не блокирует ее полностью. Лучше здесь не задерживаться. '; }; obj { nam = '#lamp'; act = 'Лампа аварийного света, такая же как и в комнате управления. '; }; obj { nam = 'tower_level_2_airlock_cabinet'; dsc = 'У одной из стен установлен небольшой свинцовый {шкафчик}. '; act = 'Судя по табличке на шкафчике, он предназначен для хранения защитного костюма. '; used = function(s, o) if o^'protection_suit' then put('protection_suit', 'tower_level_2_airlock_cabinet'); remove('protection_suit', pl); return 'Я снимаю костюм радиационной защиты и оставляю его в шкафчике. '; end; end; }:with { obj { nam = 'protection_suit'; disp = 'Костюм рад. защиты'; dsc = 'В нем стоит серебристый {костюм радиационной защиты}.'; tak = 'Я надеваю защитный костюм. '; inv = function(s) if here()^'tower_level_2_reactor' then return 'Я не стану снимать защитный костюм здесь. Это небезопасно. '; else put('protection_suit', here()); remove('protection_suit', pl) return 'Я снимаю костюм радиационной защиты. '; end; end; }; }; } room { theme = 'tower'; nam = 'tower_level_2_reactor'; theme = 'tower'; pic = function(s) if rods_raised then if not rods_enriched then return 'images/tower_level_2_reactor_rods_up.png'; end; return 'images/tower_level_2_reactor_rods_enriched.png'; elseif power_on then return 'images/tower_level_2_reactor_on.png'; else return 'images/tower_level_2_reactor_off.png'; end; end; nofollow = function(s) if here():from()^'tower_level_2_airlock' then return 'Соларскейл отказывается следовать за мной и со словами: "Здесь все придется сделать вам. У нас нет защитного костюма для меня", -- вылетает в основную комнату. '; else return true; end; end; disp = 'Башня, реактор'; onenter = function(s) if not have('protection_suit', pl) then if solarscale_with_me then pr [[Соларскейл преграждает мне путь. "Я вас туда не пропущу без защитного костюма. Это опасно", -- констатирует она. ]]; return false; else irradiated = true; return 'Здесь пахнет озоном, на языке ощущается легкий металлический привкус. '; end; end; end; way = { path {'В шлюз', 'tower_level_2_airlock'}; }; }: with { obj { nam = '#reactor_rods'; dsc = function(s) if rods_raised then return '{Топливные стержни} реактора сейчас подняты и я могу получить к ним доступ. '; else return '{Топливные стержни} реактора сейчас опущены. '; end; end; act = function(s) if rods_raised then return 'Длинные металлические стержни, должно быть, внутри них находятся топливные элементы для работы реактора. Я не могу оценить их состояние на глаз. '; else return 'Надо поднять стержни, чтобы я мог их осмотреть. '; end; end; used = function(s, o) if o^'potion_enrichment' and rods_raised then remove('potion_enrichment', pl); rods_enriched = true; return 'Я выливаю зелье на топливный стержень. С виду ничего не изменилось. '; else return false; end; end; } } room { theme = 'tower'; nam = 'tower_level_1_room_2'; disp = 'Башня, кухня'; pic = 'images/tower_level_1_room_2.png'; decor = [[По периметру этой просторной комнаты расположена узкая {#tabletop|столешница} из черного камня, под которой расположились всевозможные {#cabinets1|шкафчики}. Над столешницей находятся навесные {#cabinets2|шкафы}. В углу стоит старинный {#fridge|холодильник}. В углу напротив стоит электрическая {#stove|плита}. Рядом с плитой находится {#kitchen_sink|раковина}. В помещении царит такой же тихий и уютный полумрак, что и в большинстве помещений башни. ]]; way = { path {'Наверх', 'tower_level_2_room_2'}; path {'level_1_main_room', 'В гостиную', 'tower_level_1'}:disable(); }; }: with { obj { nam = '#kitchen_sink'; act = 'Полированная поверхность каменной раковины, врезанной в столешницу блестит в свете электрических ламп. '; used = function(s, o) if o ^ 'kettle' then if o.state == 0 then o.state = 1; return 'Я наполняю чайник водой. '; else return 'Чайник уже полон. '; end; end; end; }; obj { nam = '#tabletop'; act = 'Столешница сделана из того же материала, что и стены. Прочность этого холодного и гладкого камня не вызывает сомнений. '; }; obj { state = 0; nam = '#cabinets1'; act = function(s) if _'solarscale_ally'.tea_asked and s.state == 0 then s.state = 1; take('teabag'); return 'В одном из шкафов обнаруживается коробочка чая. Я беру один пакетик. '; end; return 'В шкафах только посуда и различные столовые приборы. '; end; }; obj { state = 0; nam = '#cabinets2'; act = function(s) if s.state < 3 then if s.state == 0 then s.state = 1; take('password_note'); return 'В одном из шкафчиков я обнаруживаю кем-то оставленную записку. Я забираю ее себе. '; elseif _'solarscale_ally'.tea_asked then if s.state == 1 then s.state = 2; take('kettle'); return 'В одном из шкафчиков я нахожу чайник. '; elseif s.state == 2 then s.state = 3; take('cup'); return 'В одном из шкафчиков я нахожу небольшую фарфоровую чашечку. '; end; end; end; return 'В шкафах только посуда и различные столовые приборы. '; end; }; obj { nam = '#fridge'; act = 'Такие холодильники были в ходу в 60-е. Но этот выглядит словно вчера сошел с конвеера. Заглянув внутрь, я обнаруживаю пустые полки. '; }; obj { nam = '#stove'; act = 'Электрическая плита на четыре конфорки с электрической же духовкой. Со своими электронными элементами управления она выглядит слишком современной для этого места. '; used = function(s, o) if o ^ 'kettle' then if power_on then if o.state == 0 then pr [[Бессмысленно кипятить пустой чайник. ]]; elseif o.state == 2 then pr [[Вода в чайнике уже горячая. ]]; else o.state = 2; pr [[Я ставлю чайник на плиту и через несколько минут вода в нем закипает. ]]; end; else pr [[Без электричества ничего не получится. ]]; end; end; end; }; obj { nam = 'silver_fork'; disp = 'Серебряная вилка'; disp2 = 'серебряная вилка'; disp3 = 'серебряную вилку'; inv = 'Изящная серебряная вилка. Должно быть она недешево обошлась владельцу этой башни. '; dsc = 'На одном из столов лежит кем-то забытая {серебряная вилка}. '; tak = 'Интересно, почему ее не убрали в шкаф. Я забираю вилку с собой. '; }; obj { state = 0; nam = '#door'; dsc = 'В одной из стен расположена небольшая деревянная {дверца}. '; act = function(s) if s.state == 0 then return 'Дверца заперта. Резной узор украшает железную накладку замка. '; else return 'За приоткрытой дверцей я вижу гостиную башни. '; end; end; used = function(s, o) if o^'kitchen_key' then s.state = 1; remove('kitchen_key', pl); _'level_1_main_room':enable(); _'level_1_next_room':enable(); return 'Я открываю дверь ключиком. '; end; end; }; obj { key_taken = false; nam = '#hook'; dsc = function(s) if s.key_taken then return 'Рядом с дверью в стену вбит небольшой медный {крючок}. '; else return 'На медном крючке рядом с дверью висит {железный ключик}. '; end; end; act = function(s) if s.key_taken then return [[Ключок пуст. ]]; else take('kitchen_key'); s.key_taken = true; return [[Я забираю ключик. ]]; end; end; } } obj { nam = 'kitchen_key'; disp = 'Железный ключик'; inv = 'Небольшой железный ключик. Головка украшена резным узором. '; }; obj { nam = 'part_box'; disp = 'Коробка с запчастями'; disp2 = 'коробка с запчастями'; disp3 = 'коробку с запчастями'; inv = function(s) walkin('part_box_inside'); end; used = function(s, o) if o.part then remove(o, pl); put(o, 'part_box_inside'); return 'Я кладу деталь в коробку. '; end; end; dsc = 'На одном из стеллажей стоит {коробка} с запасными платами для компьютера. '; tak = 'Я бегло просматриваю платы. Ни один чип не промаркирован известным мне производителем. О назначении плат я могу догадываться только по разъемам на них. Я забираю коробку с собой. '; }:disable(); room { nam = 'part_box_inside'; theme = 'tower'; nofollow = true; pic = function(s) return from():pic(); end; disp = 'Коробка с запчастями'; dsc = 'Большая коробка, внутри нее я вижу следующие детали: '; way = { path {'Назад', function(s) return here():from() end;}; } }:with { 'cax-rkt-i2sb', 'cax-rkt-i3sb', 'cax-rst-i2sb', 'cax-rst-i3sb', 'cvx-rst-i2sb', 'cvx-rst-i4sb', 'cvx-rdt-i2sb', 'crx-rst-i3sb', 'crx-rdt-i2sb', 'crx-rdt-i3sb', 'cpu20-cax-2mhz', 'cpu40-cax-4mhz', 'mcpu50-cvx-5mhz', 'mcpu70-cvx-7mhz_2', 'rcpu100-crx-10mhz', 'rcpu200-crx-20mhz', 'xcpu100-cxx-100mhz', 'rkt-m20-2mb', 'rkt-m40-4mb', 'rst-m8-8mb', 'rst-m16-16mb_2', 'rdt-m32-32mb', 'rdt-m64-64mb', 'tva-rx2', 'gva-rx2', 'gva-rx4', 'fna-200-20mbs', 'fna-100-10mbs_2', 'fna-50-5mbs', 'kbc-s_2', 'kbc-r', 'kbc-p' } room { nam = 'terminal_manual'; theme = 'tower'; pic = function(s) if power_on then return 'images/tower_level_4_room_2_light.png'; else return 'images/tower_level_4_room_2_dark.png'; end; end; nofollow = true; disp = 'Руководство пользователя терминала TETS-1'; dsc = [[ Содержание:^ 1. Комплект поставки^ 2. Подключение^ 3. Использование^ 4. {@walk service_manual|Обслуживание и ремонт}^ 5. {@walk troubleshooting_manual|Решение проблем}^ ]]; way = { path {'Назад', 'tower_level_4_room_2'}; } } room { nam = 'service_manual'; theme = 'tower'; nofollow = true; disp = 'Обслуживание и ремонт'; pic = function(s) if power_on then return 'images/tower_level_4_room_2_light.png'; else return 'images/tower_level_4_room_2_dark.png'; end; end; dsc = [[ В обычных ситуациях обслуживание не требуется, однако вам может потребоваться замена комплектующих терминала на более производительные. ^ Важно: Перед проведением любых операций отключите терминал от сети!^^ Замена материнской платы: ^ -- Вы можете использовать любую материнскую плату формата DTMB1^ -- Перед заменой материнской платы отключите все устройства от нее^ -- Открутите все винты, держащие материнскую плату(см. приложение 6)^ -- Извлеките материнскую плату^ -- Установите новую плату на место текущей^ -- Прикрутите винты для закрепления платы внутри корпуса (см. приложение 6)^ -- Установите совместимые процессор, память, контроллер клавиатуры, видеоадаптер и сетевой адаптер^^ Замена процессора:^ -- Извлеките старый процессор^ -- Установите новый процессор^ Важно: На текущий момент материнские платы форм-фактора DTMB1 выпускаются с разъемами центральных процессоров CAX, CVX и CRX. Сохраняется обратная совместимость плат со старыми процессорами, таким образом:^ -- Процессор CAX можно установить на платы с разъемами CAX, CVX и CRX^ -- Процессор CVX можно установить на платы с разъемами CVX и CRX^ -- Процессор CRX можно установить на платы с разъемом CRX^^ Замена оперативной памяти:^ -- Извлеките старый модуль памяти^ -- Установите новый модуль памяти^ Важно: На текущий момент материнские платы форм-фактора DTMB1 выпускаются с разъемами модулей памяти RKT, RST, RDT. Сохраняется обратная совместимость плат со старыми модулями памяти, таким образом:^ -- Память RKT можно установить на платы с разъемами RKT, RST и RDT^ -- Память RST можно установить на платы с разъемами RST и RDT^ -- Память RDT можно установить на платы с разъемом RDT^^ Замена устройств расширения: -- Извлеките старое устройство^ -- Установите новое устройство^ На текущий момент материнские платы форм-фактора DTMB1 выпускаются с разъемами ISB, вы можете использовать только ISB совместимые устройства с данными платами.^^ Маркировки совместимых устройств:^ 1. Материнские платы^ Материнские платы формата DTMB1 имеют маркировку вида <ЦП>-<Память>-I<Кол-во разъемов>SB. Пример: CAX-RKT-I2SB -- материнская плата для процессора CAX, поддерживающая память RKT и имеющая два разъема дополнительных устройств.^ 2. Процессоры^ Процессор обычно имеет маркировку CPU<Индекс>-<Разъем>-<Частота>, где X -- буква, означающая поколение ЦП. Поколение ЦП не влияет на совместимость и им можно пренебречь. Пример: MCPU50-CVX-5MHz -- процессоры поколения M с частотой 5МГц и разъемом CVX.^ 3. Память^ Память обычно имеет маркировку <Разъем>-M<Индекс>-<Объем>. Пример: RST-M8-8MB -- модуль объемом 8 мегабайт для разъема RST.^ 4. Видеоадаптеры^ На текущий момент существует два типа видеоадаптеров для терминалов TETS-1: серия TVA представляет собой адаптер с возможностью только текстового вывода, серия GVA -- адаптер с возможностью графического вывода.^ 5. Сетевые адаптеры^ Сетевые адаптеры для тарминалов TETS-1 имеют маркировку FNA-<Индекс>-<Скорость>.^ 5. Контроллер клавиатуры^ Контроллеры клавиатуры для тарминалов TETS-1 имеют маркировку KBC-<Поколение>. ]]; way = { path {'Назад', 'terminal_manual'}; } } room { nam = 'troubleshooting_manual'; theme = 'tower'; nofollow = true; pic = function(s) if power_on then return 'images/tower_level_4_room_2_light.png'; else return 'images/tower_level_4_room_2_dark.png'; end; end; disp = 'Решение проблем'; dsc = [[ Проблема: ОС не загружается. Нет изображения на экране. Нет звукового сигнала^ Причина: Отсутствие питания или неисправность материнской платы^ Решение: ^ 1. Проверьте питание^ 2. Замените материнскую плату^^ Проблема: ОС не загружается. Нет изображения на экране. Звуковые сигналы: длинный-короткий-короткий^ Причина: Неисправность или отсутствие центрального процессора^ Решение: ^ 1. Установите или замените центральный процессор^^ Проблема: ОС не загружается. Нет изображения на экране. Звуковые сигналы: короткий-длинный-длинный^ Причина: Неисправность или отсутствие оперативной памяти^ Решение: ^ 1. Установите или замените оперативную память^^ Проблема: ОС не загружается. Нет изображения на экране. Звуковые сигналы: длинный-короткий-длинный^ Причина: Неисправность или отсутствие видеоадаптера^ Решение: ^ 1. Установите или замените видеоадаптер^^ Проблема: ОС не загружается. Нет изображения на экране. Звуковые сигналы: длинный-длинный-длинный^ Причина: Неисправность или отсутствие контроллера клавиатуры^ Решение: ^ 1. Установите или замените контроллер клавиатуры^^ Проблема: ОС не загружается. Сообщение на экране: Booting from None^ Причина: Отсутствие совместимого устройства загрузки^ Решение: ^ 1. Установите совместимое устройство загрузки(сетевой адаптер серии FNA)^^ ]]; way = { path {'Назад', 'terminal_manual'}; } } room { ticks = 0; ram = 0; nam = 'terminal_boot'; disp = ''; nofollow = true; noinv = true; nofading = true; network = false; graphical = false; theme = 'terminal'; themeInit = terminal_theme; ondecor = function(s, name, press, x, y, btn, act) if act == '@back' then walk('tower_level_4_room_2'); end; end; onenter = function(s) local scale = diretheme.get_scale(); local width, height = diretheme.get_screen(); width = math.floor(width / scale); height = math.floor(height / scale); s.ticks = 0; s.ram = 0; stop_sound(); timer:set(25); local rc = 0; if s.graphical then D {'logo', 'img', get_sprite('images/terminal/pc_anim.png'), x = math.max(math.floor((width - 640) / 2) + 20, 20) * scale, y = math.max(height - 734, 26) * scale, w=64 * scale, h=64 * scale, frames = 24, z = 1, delay = 175, animated=true, process=function(d) if d.frame_nr == 8 and rc < 2 then d.frame_nr = 0; rc = rc + 1; elseif d.frame_nr == 9 then rc = 0; end; end}; end; local x = math.floor((width - 800) / 2); local y = height - 191; if y < 598 then y = 598; end; local top = height - 191; if top < 359 then top = 359; end; local delta = math.ceil((y - top) / 9) * scale; top = top * scale; D {'keyboard', 'img', get_sprite('images/terminal/keyboard.png'), x = x * scale, y = y * scale, w=800 * scale, h=191 * scale, z = 0, frames = 1, delay=100, process=function(d) if s.ticks >= 128 and delta > 0 then d.y = d.y - delta; delta = delta - scale; if d.y < top then d.y = top; end; print(d.y, delta, top); end; end}; end; onexit = function(s) D {'logo'}; D {'keyboard'}; D {'terminal_screen'}; end; timer = function(s) if s.ticks ~= 32 then s.ticks = s.ticks + 1; else local ram = lookup('#ram', _'system_unit').device; s.ram = s.ram + ram.size * 16; if s.ram > ram.size * 1024 then s.ram = ram.size * 1024; s.ticks = s.ticks + 1; end; end; if s.network then if s.ticks == 128 then D {'logo'}; terminal_theme(s); end; if s.ticks >= 156 then walk('terminal'); end; else if s.ticks > 127 then s.ticks = 127; end; end; s:makescreen(); end; dsc = ''; txt = ''; makescreen = function(s) local st = nil; if s.ticks < 128 then local motherboard = lookup('#motherboard', _'system_unit').device; local cpu= lookup('#cpu', _'system_unit').device; local ram = lookup('#ram', _'system_unit').device; if s.ticks == 1 then s.txt = translate_now(terminal_locale, 'bios') .. '\n'; st = s.txt; end; if s.ticks == 8 then s.txt = s.txt .. translate_now(terminal_locale, 'motherboard') .. ' : ' .. motherboard.name .. '\n'; st = s.txt; end; if s.ticks == 16 then s.txt = s.txt .. translate_now(terminal_locale, 'cpu') .. ' : ' .. cpu.name .. ' @ ' .. cpu.speed .. '.0' .. translate_now(terminal_locale, 'mhz') .. '\n'; st = s.txt; end; if s.ticks == 24 then s.txt = s.txt .. translate_now(terminal_locale, 'ram') .. ' : '.. ram.name .. '\n'; st = s.txt; end; if s.ticks == 32 then st = s.txt .. tostring(s.ram) .. translate_now(terminal_locale, 'kilobytes'); end; if s.ticks == 33 then s.txt = s.txt .. tostring(s.ram) .. translate_now(terminal_locale, 'kilobytes'); st = s.txt; end; if s.ticks == 40 then s.txt = s.txt .. ' ' .. translate_now(terminal_locale, 'success') .. '\n\n'; st = s.txt; end; if s.ticks == 48 then s.txt = s.txt .. translate_now(terminal_locale, 'keyboard') .. ' : '; st = s.txt; end; if s.ticks == 56 then s.txt = s.txt .. translate_now(terminal_locale, 'success') .. '\n'; st = s.txt; end; if s.ticks == 64 then s.txt = s.txt .. translate_now(terminal_locale, 'disk') .. ' : '; st = s.txt; end; if s.ticks == 72 then s.txt = s.txt .. translate_now(terminal_locale, 'missing') .. '\n'; st = s.txt; end; if s.ticks == 80 then s.txt = s.txt .. translate_now(terminal_locale, 'network') .. ' : '; st = s.txt; end; if s.ticks == 88 then if s.network then s.txt = s.txt .. translate_now(terminal_locale, 'success') .. '\n\n'; else s.txt = s.txt .. translate_now(terminal_locale, 'missing') .. '\n\n'; end; st = s.txt; end; if s.ticks == 104 then s.txt = s.txt .. translate_now(terminal_locale, 'boot_from'); st = s.txt; end; if s.network then if s.ticks == 112 then s.txt = s.txt .. translate_now(terminal_locale, 'network_2'); st = s.txt; end; if s.ticks == 120 then s.txt = s.txt .. '...'; st = s.txt; end; else if s.ticks == 112 then s.txt = s.txt .. '{@back|' .. translate_now(terminal_locale, 'no_device') .. '}'; st = s.txt; end; end; elseif s.ticks == 128 then s.txt = translate_now(terminal_locale, 'tower_os_line_1') .. '\n\n'; st = s.txt; else if s.ticks == 136 then s.txt = s.txt .. translate_now(terminal_locale, 'tower_os_line_2') .. '\n\n'; st = s.txt; end; if s.ticks == 144 then s.txt = s.txt .. translate_now(terminal_locale, 'tower_os_line_3') .. '\n\n'; st = s.txt; end; end; if st ~= nil then makescreen(st, s.graphical and s.ticks < 128); end; end; } room { ticks = 0; ram = 0; nam = 'terminal_boot_failure'; theme = 'terminal'; disp = ''; noinv = true; nofading = true; nofollow = true; graphical = false; themeInit = terminal_theme; onenter = function(s) local scale = diretheme.get_scale(); local width, height = diretheme.get_screen(); width = math.floor(width / scale); height = math.floor(height / scale); s.graphical = _('terminal_boot').graphical; s.ticks = 0; s.ram = 0; stop_sound(); timer:set(25); local rc = 0; if s.graphical then D {'logo', 'img', get_sprite('images/terminal/pc_anim.png'), x = math.max(math.floor((width - 640) / 2) + 20, 20) * scale, y = math.max(height - 734, 26) * scale, w=64 * scale, h=64 * scale, frames = 24, z = 1, delay = 175, animated=true, process=function(d) if d.frame_nr == 8 and rc < 2 then d.frame_nr = 0; rc = rc + 1; elseif d.frame_nr == 9 then rc = 0; end; end}; end; local x = math.floor((width - 800) / 2); local y = height - 191; if y < 598 then y = 598; end; local top = height - 191; D {'keyboard', 'img', 'images/terminal/keyboard.png', x = x, y = y, w=800, h=191, z = 0, frames = 1, delay=100}; end; onexit = function(s) D {'terminal_screen'}; D {'keyboard'}; D {'logo'}; end; timer = function(s) if s.ticks ~= 32 then s.ticks = s.ticks + 1; else local ram = lookup('#ram', _'system_unit').device; s.ram = s.ram + ram.size * 16; if s.ram > ram.size * 1024 then s.ram = ram.size * 1024; s.ticks = s.ticks + 1; end; end; if s.ticks == 128 then D {'logo'}; terminal_theme(s); end; if s.ticks >= 200 then walk('ending_formatted'); end; s:makescreen(); end; dsc = ''; txt = ''; makescreen = function(s) local st = nil; if s.ticks < 128 then local motherboard = lookup('#motherboard', _'system_unit').device; local cpu= lookup('#cpu', _'system_unit').device; local ram = lookup('#ram', _'system_unit').device; if s.ticks == 1 then s.txt = translate_now(terminal_locale, 'bios') .. '\n'; st = s.txt; end; if s.ticks == 8 then s.txt = s.txt .. translate_now(terminal_locale, 'motherboard') .. ' : ' .. motherboard.name .. '\n'; st = s.txt; end; if s.ticks == 16 then s.txt = s.txt .. translate_now(terminal_locale, 'cpu') .. ' : ' .. cpu.name .. ' @ ' .. cpu.speed .. '.0' .. translate_now(terminal_locale, 'mhz') .. '\n'; st = s.txt; end; if s.ticks == 24 then s.txt = s.txt .. translate_now(terminal_locale, 'ram') .. ' : '.. ram.name .. '\n'; st = s.txt; end; if s.ticks == 32 then st = s.txt .. tostring(s.ram) .. translate_now(terminal_locale, 'kilobytes'); end; if s.ticks == 33 then s.txt = s.txt .. tostring(s.ram) .. translate_now(terminal_locale, 'kilobytes'); st = s.txt; end; if s.ticks == 40 then s.txt = s.txt .. ' ' .. translate_now(terminal_locale, 'success') .. '\n\n'; st = s.txt; end; if s.ticks == 48 then s.txt = s.txt .. translate_now(terminal_locale, 'keyboard') .. ' : '; st = s.txt; end; if s.ticks == 56 then s.txt = s.txt .. translate_now(terminal_locale, 'success') .. '\n'; st = s.txt; end; if s.ticks == 64 then s.txt = s.txt .. translate_now(terminal_locale, 'disk') .. ' : '; st = s.txt; end; if s.ticks == 72 then s.txt = s.txt .. translate_now(terminal_locale, 'missing') .. '\n'; st = s.txt; end; if s.ticks == 80 then s.txt = s.txt .. translate_now(terminal_locale, 'network') .. ' : '; st = s.txt; end; if s.ticks == 88 then if s.network then s.txt = s.txt .. translate_now(terminal_locale, 'success') .. '\n\n'; else s.txt = s.txt .. translate_now(terminal_locale, 'missing') .. '\n\n'; end; st = s.txt; end; if s.ticks == 104 then s.txt = s.txt .. translate_now(terminal_locale, 'boot_from'); st = s.txt; end; if s.ticks == 112 then s.txt = s.txt .. translate_now(terminal_locale, 'network_2'); st = s.txt; end; if s.ticks == 120 then s.txt = s.txt .. '...'; st = s.txt; end; else -- pr [[No bootable medium found]]; st = 'Загрузочное устройство недоступно'; end; if st ~= nil then makescreen(st, s.graphical and s.ticks < 128); end; end; }