doorbell = obj {
 nam = 'дверной звонок',
 act = function() return goto('hall') end,
};

hall_puzzle = obj {
 nam = 'Мозаика в холле',
 act = [[На каждый кусочек мозаики наклеена тонкая серебряная плёнка. Спустя примерно двести кусочков это будет портрет того, кто собрал загадку.]],
};
hall_sofa = obj {
 nam = 'Диван в холле',
 act = [[Красный широкий диван для гостей. С первого взгляда он выглядит нормально, но в определённое время суток тени оконных витражей совмещаются с тенью самого дивана, и на полу возникает ужасающий монстр, готовый съесть гостя заживо. К счастью, это продолжается не более минуты, и только в солнечный день. Но я в любом случае нахожу это насмехательством.]],
};
hall_mirrors = obj {
 nam = 'зеркала',
 act = [[Я смотрю в зеркала и вижу очень уставшего от загадок человека.]]
};
hall_table = obj {
 nam = 'Стол в холле',
 act = [[Низенький столик, на котором стоит шахматная доска с незаконченной партией. Я уверен, что позиция просто гениальна, но мне противно даже смотреть на доску.]]
};
hall_body = obj{
 nam = 'Тело горничной',
 _seen = false,
 _taken = false,
 _rest = false,
 act = function()
  if not (hall_body._seen) then
   hall_body._seen = true;
   lifeon('mplayer');
   return [[На каминных углях тлеет женское тело. Я узнал её -- это горничная Петра. Бедная девушка. На ней совершенно нет одежды, а на шее краснеет тонкая линия. Вдобавок она скрючена в неестественной позе, и вся выпачкана в саже и золе. Нет, я не в силах смотреть на это.^^Чёрт побери, да ведь он решил меня подставить! Он убил свою горничную и наверняка рассовал по углам какие-нибудь улики на меня. Он хочет играть. Ладно, маньяк, я сыграю в твою игру -- но тебе это не пройдёт даром, будь уверен.^^
   Словно бы оглашая начало игры, оживает невидимый проигрыватель, и комната заполняется музыкой.]]
  end;
  if not (hall_body._taken) then
   hall_body._taken = true;
   return [[Я осторожно осматриваю тело, пытаясь не трогать его. Да, она действительно мертва. В этом нет сомнения. И -- конечно же -- на ноге недостаёт одной чёрной туфли и один из ногтей обломан. Не говоря уже о том, что она лежит совершенно голой. Что-то мне подсказывает, что я могу найти свой платок рядом с её одеждой. О господи, её ноги наверняка уже превратились в угольки! Нет, лучше не смотреть лишний раз в эту сторону. А где может лежать туфля? И что может лежать рядом с нею? Я не успокоюсь, пока не найду всё.]]
  end;
  if not (hall_body._rest) then
   hall_body._rest = true;
   return [[Я читаю молитву над телом девушки. Я надеюсь, что её душе хотя бы стало приятнее.]];
  end
  return [[Мёртвое тело очень гармонично вписывается в окружающий дурдом. Я стараюсь не смотреть в ту сторону; мне нужно сохранить мысли ясными и спокойными.]];
 end,
}
automobile = obj{
 nam = 'автомобиль',
 dsc = [[Передо мной стоит {автомобиль}. Со сверкающего бока на меня смотрят буквы: «А.М.»]],
 act = function()
  if not (hall_body._seen) then return [[Стоп. Я не трус. Что-то мне подсказывает, что просто сбежать -- не выход. Нужно вернуться и посмотреть, куда это ведёт.]]; end
  if(
   (taken(handkerchief) or handkerchief._destroyed or crossword_puzzle._destroyed) and
   (taken(nail) or nail._destroyed) and
   (taken(golden_string) or golden_string._destroyed) and
   (taken(shoe) or shoe._destroyed) and
   (taken(clothes) or clothes._destroyed)
  ) then
   return goto('game_over');
  end
  return [[Я запрыгиваю в машину, но тут вспоминаю, что где-то в доме всё ещё может лежать мой платок. А вдруг? Нет, я не могу просто уехать. Я должен убедиться.]]
 end,
 obj = {},
 --use = function(this, that)
 -- TODO: push to obj
 -- inv():del(that);
 -- return [[Как хорошо иметь вместительный багажник!]]
 --end
 --в багажник можно класть вещи
}
stair = obj{
 nam = 'лестница',
 dsc = 'Я замечаю приставную {лестницу}, лежащую под одним из кустов.',
 act = [[За кустами следит садовник -- из местных, он бывает раз в неделю или реже. Но лестницей никогда не пользуется. Стараясь не оставлять следов на траве, я подхожу и издалека осматриваю лестницу. Ничего примечательного. Куда бы она... А! Окно на втором этаже открыто как раз над этим кустом.]]
}
broken_window = obj{
 nam = 'разбитое окно',
 dsc = [[Одно из окон {открыто}.]],
 act = [[Один из кусочков витража чётко вырезан. Окно открыли снаружи. Но внизу видны только аккуратные зелёные кусты.]]
}
dining_table = obj{
 nam = 'обеденный стол',
 dsc = [[В центре комнаты стоит огромный обеденный {стол}.]],
 act = [[Огромный стол -- я думаю, на 12 персон -- накрыт белоснежной скатертью.]]
}
small_cup = obj{
 nam = 'маленькая чашка',
 dsc = [[На столе стоят {маленькая} и ]],
 act = [[На боку чашки нарисована цифра 3. Ненавижу загадки.]]
}
big_cup = obj{
 nam = 'большая чашка',
 dsc = [[{большая} чашки.]],
 act = [[На боку чашки нарисована цифра 5. Я не притронусь к ней.]]
}
plate = obj{
 nam = 'пластина',
 dsc = [[Одно из зеркал разбито, и на его месте стоит стальная {пластина}.]],
 act = [[Совершенно гладкий прямой кусок стали. Ни одной щербинки.]]
}
wrong_mirrors = obj {
 nam = 'кривые зеркала',
 _broken = false,
 act = [[Никогда не понимал, что такого люди находят в кривых зеркалах. Тем более я не понимаю того извращенца, что смотрит в них во время каждого обеда.]],
 obj = {plate}
};
cupboard = obj {
 nam = 'кухонный шкаф',
 act = [[Я тщательно порылся в шкафу, но не нашёл ничего особенного.]]
};
oven = obj {
 nam = 'духовка',
 act = [[Пуста.]]
};
fridge = obj {
 nam = 'холодильник',
 act = [[Совершенно пуст. Невероятно.]]
};
master_toilet = obj {
 nam = 'унитаз хозяина',
 act = [[Нет, он не золотой и даже правильной формы. Обычная керамическая сантехника.]]
};
master_sink = obj {
 nam = 'раковина хозяина',
 act = [[Я умываю руки и лицо. Весь этот дурдом серьёзно действует на нервы.]]
};
wooden_bath = obj {
 nam = 'деревянная бадья',
 _seen = false,
 _taken = false,
 act = function()
  if not (wooden_bath._seen) then
   wooden_bath._seen = true;
   return [[В центре ванной стоит огромная деревянная бадья, прихваченная двумя золотыми обручами.]];
  end
  if not (wooden_bath._taken) then
   wooden_bath._taken = true;
   take('golden_string');
   return [[Тщательно осмотрев обручи, я нашёл за одним из них позолоченную длинную струну. На ней есть засохшие капли крови.]];
  end
  return [[Нет, я не намерен сегодня купаться.]]
 end
};
bath = obj {
 nam = 'ванна',
 act = [[Не могу не представить её божественное тело в этой изящной ванне... прекрасная картинка.^^Мы познакомились по работе; я тогда был всего второй раз в Англии, и ещё не думал о том, чтобы здесь поселиться. Мне нужна была переводчица, и один из друзей подсказал Люду. Потом я встретил Петю, и мы быстро сдружились -- может быть, потому что он оказался моим земляком. Он и мечтать не мог услышать родную русскую речь на этом краю земли. ^^ Он был успешным скульптором, а она -- переводчицей. Каждый день я забирал её с собой, и мы делали вместе всё, что только приходило в голову. Она была так счастлива! А потом я отвозил её домой, и её светлое лицо мрачнело от одного вида этих бесконечных каменистых полей.^^Я не знаю, почему я подумал об этом. Давно прошедшие дела.]]
};
toilet = obj {
 nam = 'унитаз хозяйки',
 act = function()
  if not taken(clothes) and not(clothes._destroyed) then
   take('clothes');
   return [[Подняв стульчак, я обнаружил плавающую одежду. Похоже, она принадлежала горничной.]];
  end
  return [[Я не люблю возиться с унитазами.]]
 end
};
sink = obj {
 nam = 'раковина',
 act = [[Раковина не выглядит как-то особенно.]]
};
bookcases = obj {
 nam = 'книжные шкафы',
 act = [[Словари и альбомы с фотографиями.]]
};
royal = obj {
 nam = 'рояль',
 act = [[Довольно странно видеть рояль в такой маленькой комнате; обычно их ставят в залы с хорошей акустикой.^^Я исполняю короткую мелодию, но одна из клавиш падает без сопротивления и звука. Открыв крышку, я нахожу, что одной из золочёных струн не хватает.]]
};
computer = obj {
 nam = 'компьютер',
 act = [[Компьютер не запускается; отсутствует жёсткий диск. Жаль, а я уже надеялся посмотреть какие-нибудь эскизы.]]
};
wood = obj {
 nam = 'дрова',
 _seen = false,
 act = function()
  if not wood._seen then
   wood._seen = true
   take(shoe);
   take(white);
   return [[За горой дровишек я нахожу чёрную женскую туфлю. Внутри неё лежит белый платок. О боже!]];
  end
  return [[Гора дров -- запас для камина. Камин стоит только для настроения; насколько я знаю, отопление тут устроено как-то иначе.]]
 end
};
meds = obj {
 nam = 'склянки',
 act = [[Я не хочу даже подходить к этим склянкам. На них нет надписей, а по виду в них может быть что угодно. Например, яд, смертельный для всякого, кто подойдёт ближе десяти метров.]]
};
white = obj {
 nam = 'белый платок',
 inv = function()
  take('nail');
  inv():del('white');
  return [[Нет, это -- не мой платок; он совершенно бел. Раскрыв его, я нахожу обломок чёрного ногтя.]]
 end,
 use = 'Мне кажется, в платок что-то завёрнуто.'
};
acid_bath = obj {
 nam = 'ванна с кислотой',
 act = [[Я очень рад тому, что эта жидкость не может проесть стенки из железа. Но я на всякий случай буду обходить её подальше.]]
};
wine = obj {
 nam = 'вино',
 act = [[Очень дешёвое вино неизвестного розлива. Уникальная редкость. Внутрь не употреблять ни за что.]]
};
shoe = obj {
 nam = 'женская туфля',
 _destroyed = false,
 inv = [[Я плохо знал эту девушку, но она точно не заслужила такой смерти.]],
 use = function (this, that)
  if (that == toilet or that == master_toilet) then return [[Не просовывается.]] end;
  if (that == acid_bath) then
   inv():del('shoe');
   shoe._destroyed = true;
   return [[Я кидаю туфлю в кислотную ванну, и на дне остаётся лишь горочка мелких гвоздиков.]]
  end
  if (that == stair) then return [[Я не буду подходить к этой лестнице.]]; end
  if (that == computer) then return [[Этой грудой железа я вообще не хочу заниматься.]] end
  
  if (that == royal) then return [[Я не собираюсь играть ноктюрн мокрой одежды.]]end
  if (that == acid_bath) then
   clothes._destroyed = true;
   inv():del('clothes');
   return [[Я бросаю предметы по одному; с тихим шипением на дно ванны падают пуговицы.]];
  end;

  if (that == wrong_mirrors) then
   if not (wrong_mirrors._broken) then
    wrong_mirrors._broken = true;
    dining_room.obj:add(plate);
    return [[Я размахиваюсь и запускаю туфлю в одно из зеркал. Оно рассыпается на море осколков. За зеркалом находится сплошная стальная пластина.]];
   end
   return [[Нет, бить стёкла уже достаточно.]]
  end
  if (that == broken_window) then return [[Оно уже разбито.]]; end
  if (that == sink or that == master_sink) then return [[Я немного не понимаю... куда толкать?]] end;
  if (that == wooden_bath or that == bath) then return [[Зачем?]] end;
  if (that == bookcase) then return [[Такое в книгах не прячут.]] end
  if (that == wood) then return [[Не лучшее место для хранения.]] end
  if (that == meds) then return [[Зачем?]] end
  
  return [[Не стоит несерьёзно относиться к таким вещам.]];
 end
};
nail = obj{
 nam = 'ноготь',
 inv = [[Как тяжело нести его в кармане! Нет, он, конечно, лёгкий, но при одной мысли о... Нет, всё, не буду думать.]],
 _destroyed = false,
 use = function (this, that)
  if (that == toilet or that == master_toilet) then return [[Я предпочитаю более радикальные средства.]] end;
  if (that == acid_bath) then
   inv():del('nail');
   nail._destroyed = true;
   return [[Я кидаю ноготь в кислотную ванну, и он растворяется на моих глазах.]]
  end
  if (that == hall_mirrors or that == wrong_mirrors) then return [[Я скребу ногтём по зеркалу. Душераздирающий звук. Никто не реагирует.]] end
  if (that == hall_body) then return [[Я не смогу прикрепить его на место.]]; end
  if (that == stair) then return [[Я не буду подходить к этой лестнице.]]; end
  if (that == computer) then return [[Этой грудой железа я вообще не хочу заниматься.]] end
  
  if (that == royal) then return [[Обычно подобными играют на гитарах... или я неправ?]]end
  if (that == hall_puzzle) then return [[Зачем портить мозаику? Тем более, что она не собрана.]]; end
  if (that == wine) then
   nail._destroyed = true;
   inv():del('nail');
   return [[Я разбиваю несколько бутылок и бросаю в тёмную жидкость тёмный ноготь. Она могла сломать его и здесь.]]
  end
  if (that == crossword_puzzle) then return [[Я пытаюсь открыть книгу ногтем, но ничего не получается.]] end
  if (that == oven) then
   nail._destroyed = true;
   inv():del('nail');
   return [[Я кладу ноготь в духовку и включаю её на полную мощность. Через несколько минут должны остаться одни угольки.]]
  end
  return [[Не стоит несерьёзно относиться к таким вещам.]];
 end
}
clothes = obj {
 nam = 'мокрая одежда',
 inv = [[Вряд ли мне понадобится её высушивать. Скорее, уничтожить.]],
 _destroyed = false,
 use = function (this, that)
  if (that == toilet or that == master_toilet) then return [[У кого-то это уже не получилось. К тому же, кто знает как устроена местная канализация? Если я что-то делаю -- я хочу быть уверенным, что получу нужный результат.]] end;
  if (that == crossword_puzzle) then return [[Я протираю мокрой одеждой книгу.]] end
  if (that == oven) then return [[Я не собираюсь ни высушивать одежду, ни поджигать дом. Во всяком случае, пока.]] end --было бы нечестно сделать такой быстрый вариант прохождения
  if (that == hall_body) then return [[Боюсь, это лишнее.]]; end
  if (that == stair) then return [[Я не буду подходить к этой лестнице.]]; end
  if (that == computer) then return [[Этой грудой железа я вообще не хочу заниматься.]] end
  
  if (that == royal) then return [[Я не собираюсь играть ноктюрн мокрой одежды.]]end
  if (that == acid_bath) then
   clothes._destroyed = true;
   inv():del('clothes');
   return [[Я бросаю предметы по одному; с тихим шипением на дно ванны падают пуговицы.]];
  end;
  if (that == hall_puzzle) then return [[Я протёр мозаику мокрой одеждой.]]; end
  if (that == hall_sofa) then return [[Я протёр диван мокрой одеждой.]]; end
  if (that == hall_mirrors or that == wrong_mirrors) then return [[Я вытер зеркала мокрой одеждой.]]; end
  if (that == hall_table or that == dining_table) then return [[Я протёр стол мокрой одеждой.]]; end
  if (that == automobile) then return [[Вряд ли мне нужно чистить машину.]]; end
  if (that == broken_window) then return [[В окне мокрая одежда будет смотреться ещё хуже.]]; end
  if (that == small_cup or that == big_cup) then return [[Связать их вместе? Зачем они мне?]] end
  if (that == cupboard) then return [[Нет, там её моментально найдут.]]; end
  if (that == fridge) then return [[Холодной она мне не нужна.]] end
  if (that == sink or that == master_sink) then return [[Я немного не понимаю... куда толкать?]] end;
  if (that == wooden_bath or that == bath) then return [[Она и так уже мокрая.]] end;
  if (that == bookcase) then return [[Такое в книгах не прячут.]] end
  if (that == wood) then return [[Не лучшее место для хранения.]] end
  if (that == meds) then return [[Зачем?]] end
  if (that == wine) then return [[Мне всё равно, какого цвета будет эта одежда. Даже если я вымочу её всю в вине, это не поможет.]] end
  
  return [[Мне надо всего лишь уничтожить одежду. Я не хочу отвлекаться на всякий бред.]];
 end
};
crossword_puzzle = obj {
 nam = 'Книга-загадка',
 _destroyed = false,
 dsc = [[На диване лежит закрытая {книга}.]],
 act = [[Среди обломков я могу различить остатки моего платка. Да, я узнаю синюю кайму. Нет, мне стоило надёжнее проверять вещи после визитов сюда. Хорошо ещё, что я оставил всего лишь платок.]],
 tak = [[Я беру книгу и раскрываю её. Это вопросник! Проклятое изобретение Петра. Надо выбрать правильный вопрос, учитывая его значение, положение и ещё чёрт-знает-что, вплоть до времени года. Разгадав загадку, я смогу открыть потайное отделение и взять то, что в нём лежит. Не сомневаюсь, что это -- что-нибудь однозначно меня порочащее. Наверняка там и лежит платок! Ненавижу загадки.]],
 use = function (this, that)
  if (that == toilet or that == master_toilet) then return [[Не влезает.]] end;
  if (that == broken_window) then
   inv():del('crossword_puzzle');
   crossword_puzzle._destroyed = true;
   crossword_puzzle.tak = false;
   crossword_puzzle.dsc = 'Рядом с дорожкой лежат обломки {книги-загадки}. Проклятая штукенция.';
   outside.obj:add('crossword_puzzle');
   return [[Я выкидываю книгу из окна, и она приземляется на один из камней в саду. Если внутри действительно был пузырёк с кислотой, то платок безнадёжно испорчен.]];
  end
  if (that == acid_bath) then
   crossword_puzzle._destroyed = true;
   inv():del('crossword_puzzle');
   return [[Ненавижу загадки.]];
  end
  if (that == clothes) then return [[Я бью мокрую одежду книгой. Редкостный идиотизм.]] end
  if (that == hall_body) then return [[Нет, ей уже не поможешь.]]; end
  if (that == stair) then return [[Я не буду подходить к этой лестнице.]]; end
  if (that == hall_mirrors or that == wrong_mirrors) then return [[Даже в зеркалах это выглядит как тарабарщина.]]; end
  if (that == computer) then return [[Этой грудой железа я вообще не хочу заниматься.]] end
  return [[В другое время.]];
 end,
 inv = function() if (here() ~= puzzle_solving) then return goto('puzzle_solving') end end,
};
golden_string = obj {
 nam = 'золотая струна',
 inv = [[Позолоченная длинная струна, на которой ещё остались капли крови.]],
 use = function (this, that)
  if (that == toilet or that == master_toilet) then return [[Очень сильно сомневаюсь, что она исчезнет таким способом. В лучшем случае, она может застрять где-то в трубах внутри дома. Я не хочу оставлять Петру ни единого шанса.]] end;
  if (that == royal) then return [[Я не умею ставить струны. Тем более, я её не настрою.]]end
  if (that == acid_bath) then return [[Струна сделана из стали. Вряд ли кислота возьмёт её.]]end
  if (that == crossword_puzzle) then return [[Я пытаюсь взломать книгу струной, но ничего не выходит.]] end
  if (that == hall_body) then return [[Да, именно так она и встретила конец. Ужасная смерть.]]; end
  if (that == hall_puzzle) then return [[Я не хочу украшать мозаики струнами.]]; end
  if (that == hall_sofa) then return [[Я сосредоточенно царапаю диван струной. Чувствую себя полным идиотом.]]; end
  if (that == hall_mirrors or that == wrong_mirrors) then return [[Даже не представляю себе.]]; end
  if (that == hall_table or that == dining_table) then return [[Если долго-долго пилить одну из ножек, она может отломаться. Дурацкий план, лучше не тратить на него время.]]; end
  if (that == automobile) then return [[Вряд ли мне нужно натягивать струны в машине.]]; end
  if (that == stair) then return [[Я не буду подходить к этой лестнице.]]; end
  if (that == broken_window) then return [[Если я выброшу струну в окно, она просто останется лежать на земле. И там её заметит каждый.]]; end
  if (that == small_cup or that == big_cup) then return [[Связать их вместе? Зачем они мне?]] end
  if (that == cupboard) then return [[Нет, там её моментально найдут.]]; end
  if (that == oven) then return [[Я сомневаюсь, что бытовая духовка сможет расплавить стальную струну.]]; end
  if (that == fridge) then return [[Холодной она мне не нужна.]] end
  if (that == sink or that == master_sink) then return [[Я немного не понимаю... куда толкать?]] end;
  if (that == wooden_bath or that == bath) then return [[Я не хочу купать струну.]] end;
  if (that == bookcase) then return [[Спрятать в книгах? А вдруг найдут?]] end
  if (that == computer) then return [[Этой грудой железа я вообще не хочу заниматься.]] end
  if (that == wood) then return [[Не лучшее место для хранения.]] end
  if (that == meds) then return [[Эм...нет, лучше не надо.]] end
  if (that == wine) then return [[Даже это вино кто-то иногда пьёт.]] end
  return [[Пожалуй, я не буду тратить время на это.]];
 end
};
handkerchief = obj{
 nam = 'именной платок',
 inv = [[Наконец-то он снова со мной! Да, это он: белый платок с подписью «Андрей Макаров» в углу. Нет, мне стоило надёжнее проверять вещи после визитов сюда. Хорошо ещё, что я оставил всего лишь платок.]]
}
