mirror of https://github.com/goraph/17rooms
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
574 lines
25 KiB
574 lines
25 KiB
-- Доступное пространство имён для объектов - все имена объектов должны начинаться с "room4_" или "kladovka_" |
|
-- Все описания можно менять |
|
-- Задача: Игрок должен открыть люк в пол предметом bonekey, он может придти в локацию как с ним, так и без него |
|
|
|
global { song = 0 } |
|
|
|
Verb { |
|
"#play", |
|
"игр/ать,поигр/ать", |
|
"Play", |
|
"на {noun}/пр,held : Play", |
|
} |
|
|
|
mp.msg.Play = {} |
|
function mp:Play(w) |
|
if not w then |
|
p "На чём ты хочешь играть?"; |
|
return; |
|
end |
|
if mp:check_touch() then |
|
return |
|
end |
|
if mp:check_held(w) then |
|
return |
|
end |
|
p(mp.msg.Play.PLAY) |
|
end |
|
--"может" |
|
mp.msg.Play.PLAY = "{#Me/им} не {#word/может,#me} играть на {#first/пр}." |
|
|
|
room { |
|
nam = "room4_kladovka"; |
|
title = "Кладовка"; |
|
transported = false, |
|
dsc = function(s) |
|
local v = "" |
|
if from() ^ "room4_ostrov" and s:once() then |
|
v = "Я увидела своё отражение, стоящее в кладовке. Затем мир покачнулся, и я снова оказалась в тесной комнате.^^" |
|
end |
|
return v .. "Тесная неинтересная комната. К западу кухня, на востоке прихожая." |
|
end; |
|
onenter = function(s) |
|
if not s.transported then |
|
s.transported = true |
|
move(me(), "room4_ostrov"); |
|
place("room4_dolphin", "room4_mirror") |
|
place("room4_crab", "room4_mirror") |
|
place("room4_frog", "room4_mirror") |
|
end |
|
end; |
|
w_to = "room6_kitchen"; |
|
e_to = function(s) |
|
if _'room3_hall'.west == 0 then |
|
p 'Ты толкнула дверь и оказалась в прихожей. Оказывается, здесь есть проход! Теперь ходить между помещениями будет куда удобней!'; |
|
_'room3_hall'.west = 1; |
|
end; |
|
return 'room3_hall'; |
|
end; |
|
d_to = function(s) |
|
if _"room4_hatch":has "open" then |
|
return "room5_podval" |
|
elseif _"room4_hatch":has "locked" then |
|
p "Люк заперт." |
|
else |
|
p "Люк закрыт." |
|
end |
|
end; |
|
before_Listen = "Ничего не слышно."; |
|
before_Smell = "Ничем не пахнет."; |
|
obj = { |
|
nam = "room4_bonekey", |
|
obj { |
|
-- Упростил. Зеркало это один объект, находящийся в двух комнатах сразу. |
|
-"зеркало|стекло"; |
|
nam = "room4_mirror"; |
|
seen = false, |
|
dsc = function(s) |
|
-- Проверяем откуда мы на зеркало смотрим (из кладовки или с острова) и выводим подходящее описание |
|
if here() ^ "room4_kladovka" then |
|
return "На стене висит старинное зеркало."; |
|
else |
|
return "Прямо в воздухе висит старинное зеркало."; |
|
end |
|
end; |
|
description = function(s) |
|
-- Та же фигня, что и в dsc |
|
if here() ^ "room4_kladovka" then |
|
return [[Большое зеркало в старинной бронзовой раме, представляющей собой осьминога, растопырившего щупальца.]]; |
|
else |
|
return [[Большое зеркало в бронзовой раме по краю которой располагаются чеканные фигурки: змеи, краба и дельфина.]]; |
|
end |
|
end; |
|
before_Search = function(s) |
|
-- s:once() возвращает true только один раз. Так что при первом осмотре попадаем на остров, а потом не попадаем |
|
if not s.seen then |
|
if where("room4_sapfir") ^ "room4_dolphin" and where("room4_rybin") ^ "room4_crab" and where("room4_izymryd") ^ "room4_frog" then |
|
s.seen = true |
|
move(me(), "room4_kladovka") |
|
disable("room4_dolphin") |
|
disable("room4_crab") |
|
disable("room4_frog") |
|
mp.score=mp.score+1 |
|
else |
|
--"посмотреть" |
|
return "Моё отражение в зеркале выглядит как обычно. Ничего странного не происходит." |
|
end |
|
else |
|
return "Меня закрутило, завертело и втянуло прямо в зеркало. Я снова оказалась в кладовке. Ну и чудеса..." |
|
end |
|
end; |
|
-- Добавим описаний. Парсер же |
|
before_Take = "Слишком большое и тяжёлое. Невозможно сдвинуть."; |
|
before_Smell = "Пахнет морем. Странно, но так и есть."; |
|
before_Taste = "Это не съедобно."; |
|
before_Touch = "Гладкое и прохладное."; |
|
}: attr "static", |
|
-- Для парсера модельку лучше поподробнее :) |
|
-- Я бы ещё источник света добавил для красоты %) |
|
obj { |
|
-"стена|стены"; |
|
description = "Стены покрыты пыльной штукатуркой."; |
|
before_Take = "Взять стены? Как?"; |
|
before_Smell = "Пахнет пылью."; |
|
-- {#word...} это ещё одна магия метапарсера. Позволяет автоматически выводить глагол в нужной форме. |
|
-- В основном применяется в библиотеках. Если не нравится, вписуй хардкод :) |
|
before_Taste = "{#Me/им} не {#word/хотеть,#me,нст} пробовать стены на вкус."; |
|
before_Touch = "Шершавые и пыльные стены."; |
|
}:attr "scenery", |
|
obj { |
|
-"пол"; |
|
-- По аналогии со стенами |
|
description = "Каменный пол. Здесь явно не заморачивались с ремонтом."; |
|
before_Take = "Взять пол невозможно"; |
|
before_Smell = "Пахнет пылью."; |
|
before_Taste = "{#Me/им} не {#word/хотеть,#me,нст} пробовать камни пола на вкус."; |
|
before_Touch = "Прохладный, слегка неровный камень."; |
|
}:attr "scenery", |
|
obj { |
|
-"потолок"; |
|
description = "Потолок покрыт голубой краской."; |
|
before_Take = "Взять потолок невозможно"; |
|
before_Smell = "Не могу допрыгнуть, чтобы понюхать."; |
|
before_Taste = "Не дотянусь."; |
|
before_Touch = "Увы, не дотянусь."; |
|
}:attr "scenery", |
|
}; |
|
} |
|
|
|
door { |
|
-"люк"; |
|
nam = "room4_hatch"; |
|
when_closed = "В полу виден закрытый люк."; |
|
when_open = "В полу находится открытый люк."; |
|
with_key = "bonekey"; |
|
door_to = function(s) |
|
if here() ^ "room4_kladovka" then |
|
-- Горафу надо сказать, что сюда нужно вписнуть комнату как в d_to кладовки |
|
return "room5_podval" |
|
else |
|
return "room4_kladovka" |
|
end |
|
end; |
|
found_in = { |
|
"room4_kladovka", |
|
-- Горафу надо сказать, что сюда нужно вписнуть комнату как в d_to кладовки |
|
-- "room5_podval", |
|
}; |
|
after_Unlock = function(s) |
|
remove('bonekey'); |
|
mp.score=mp.score+1; |
|
p "Ты отпираешь люк вниз, избавляясь от костяного ключа."; |
|
end; |
|
}:attr "openable,lockable,locked,static" |
|
|
|
function mermaid_sing() |
|
local songs = { |
|
[[Юные девы в царстве подводном^ |
|
Живут наслаждаясь, не зная забот.^ |
|
Песни поют о народе свободном.^ |
|
В тёмных глубинах ведут хоровод.]], |
|
[[Юные девы в царстве подводном^ |
|
Жемчугом любят себя украшать,^ |
|
Что перламутром богат бесподобным,^ |
|
И под луной может нежно мерцать.]], |
|
[[Юные девы из царства подводного^ |
|
Мужчин завлекают песней любви.^ |
|
Чарами голоса - дара природного,^ |
|
Страсти огонь разжигают в крови.]], |
|
[[Юные девы из царства подводного^ |
|
Губят ночною порой корабли.^ |
|
Из-за желанья познать, неуёмного,^ |
|
Секреты и тайны верхней земли.]], |
|
} |
|
song = song + 1 |
|
if song > #songs then |
|
song = 1 |
|
end |
|
return "Раздаётся завораживающая песня русалки:^"..songs[song] |
|
end |
|
|
|
room { |
|
nam = "room4_ostrov"; |
|
title = "За зеркалом"; |
|
dsc = function(s) |
|
local v = "" |
|
if s:once() then |
|
-- Сообщение при первом посещении комнаты |
|
-- {#Me/падеж} вписует ГГ в соответствие с pl.word (задаётся в init() в main3.lua) |
|
v = "Всего лишь мельком я увидела своё отражение в старинном зеркале, и меня завертело, закружило, ослепило... Проморгавшись, я поняла, что оказалась совсем в другом месте.^^" |
|
end |
|
return v .. "Маленький остров, представляющий собой цветочную поляну, окружённую водой." |
|
end; |
|
before_Default = function(s, ev, w, wh) |
|
if wh == _'room4_gems' then |
|
p"Камнями лучше распоряжаться по отдельности."; |
|
else |
|
return false; |
|
end; |
|
end; |
|
obj = { |
|
"room4_mirror", |
|
obj { |
|
-"цветы|розы/но"; |
|
nam = "room4_flowers"; |
|
dsc = "Весь остров в цветах."; |
|
description = [[Прекрасные алые розы.]]; |
|
["before_Take,Tear"] = function(s) |
|
mp:xaction('Take', _'room4_flower'); |
|
end; |
|
before_Give = function(s, w) |
|
mp:xaction('Give', _'room4_flower', w); |
|
end; |
|
before_Show = function(s, w) |
|
mp:xaction('Show', _'room4_flower', w); |
|
end; |
|
}: attr "static", |
|
obj { |
|
-"флейта|дудка|дудочка|дуда"; |
|
nam = "room4_fluet"; |
|
init_dsc = "В траве лежит флейта."; |
|
description = [[Изящная флейта, искусно вырезанная из слоновой кости.]]; |
|
-- Следующую строку с комментарием не удаляй. Она добавляет слово "брать" в словарь игры |
|
--"брать" |
|
Show = function(s, w) |
|
if w ^ "room4_mermaid" then |
|
return "Русалка смеётся, и делает жест, будто играет на флейте." |
|
end; |
|
return false; |
|
end; |
|
after_Take = "{#Me/им} {#word/брать,#me,нст} флейту."; |
|
before_Smell = "Пахнет цветами."; |
|
--"хотеть" |
|
before_Taste = "{#Me/им} не {#word/хотеть,#me,нст} пробовать флейту на вкус."; |
|
before_Touch = "Гладкая и приятная на ощупь."; |
|
["Blow,Use,Play"] = function(s) |
|
mp:check_held(s); |
|
if s:once() then |
|
mp.score=mp.score+1 |
|
enable "room4_mermaid" |
|
return "На переливы флейты из воды вынырнула настоящая русалка." |
|
else |
|
return mermaid_sing(); |
|
end |
|
end; |
|
}, |
|
obj { |
|
-"цветок|роза/но"; |
|
nam = "room4_flower"; |
|
dsc = false, |
|
donated = false, |
|
description = "Прекрасная алая роза."; |
|
["before_Take,Tear"] = function(s) |
|
if have(s) or s.donated then |
|
-- if s.once then |
|
-- Объясняем, что больше одного цветка не нужно или что-то такое |
|
return "{#Me/дт} больше не нужны цветы. Да и жаль рвать такую красоту." |
|
else |
|
take(s) |
|
--"сорвать" |
|
return "{#Me/им} {#word/сорвать,#me,прш} цветок." |
|
end |
|
end; |
|
Show = function(s, w) |
|
if w ^ "room4_mermaid" then |
|
return "Русалка радостно кивает, и показывает на свои волосы." |
|
end; |
|
|
|
return false; |
|
end; |
|
before_Give = function(s, w) |
|
if w ^ "room4_mermaid" then |
|
if not s.donated then |
|
mp.score=mp.score+1 |
|
s.donated = true |
|
place(s, here()) |
|
s:attr "scenery" |
|
take "room4_sapfir" |
|
take "room4_rybin" |
|
take "room4_izymryd" |
|
enable "room4_gems" |
|
p "Я даю русалке цветок. Она мило краснеет и забирает розу, тут же украшая ею свои волосы. Взамен она протягивает мне три драгоценных камня: изумруд, сапфир и рубин. Я с благодарностью принимаю их." |
|
else |
|
return "Русалке больше не нужны цветы." |
|
end |
|
else |
|
return "Кому-кому?" |
|
end |
|
end; |
|
}, |
|
-- Тоже моделька для антуражу. См. стены в кладовке :) |
|
obj { |
|
-"небо"; |
|
description = "Ясное синее небо, ни облачка."; |
|
before_Take = "Взять небо? Как это возможно?"; |
|
before_Smell = "Пахнет ветром и морем."; |
|
before_Taste = "Не дотянусь."; |
|
before_Touch = "Жаль, не дотянусь."; |
|
}:attr "scenery", |
|
obj { |
|
-"солнце"; |
|
description = "Яркое солнце, аж глазам больно на него смотреть."; |
|
before_Take = "Жаль нельзя запихнуть его в карман. Было бы здорово иметь своё карманное солнце."; |
|
before_Smell = "Отсюда я не могу понять, чем пахнет солнце."; |
|
before_Taste = "Не дотянусь."; |
|
before_Touch = "Жаль, не дотянусь."; |
|
}:attr "scenery", |
|
obj { |
|
-"земля"; |
|
description = "Земля заросла цветами. Присмотревшись, я замечаю среди кустов роз человеческие кости."; |
|
before_Take = "Мне не нужен здешний дёрн."; |
|
before_Smell = "Пахнет цветами и травой."; |
|
before_Taste = "Не хочу даже пробовать."; |
|
before_Touch = "Немного влажная, будто не так давно шёл дождь. Или был прилив, мхм..."; |
|
}:attr "scenery", |
|
obj { |
|
-"трава"; |
|
description = "Земля заросла цветами. Присмотревшись, я замечаю в траве человеческие кости."; |
|
before_Take = "Мне не нужна трава."; |
|
before_Smell = "Пахнет цветами и травой."; |
|
before_Taste = "Не хочу даже пробовать."; |
|
before_Touch = "Немного влажная, будто не так давно шёл дождь."; |
|
}:attr "scenery", |
|
obj { |
|
-"человеческие кости|кости/мн,но|человеческие останки|останки"; |
|
description = "Множество человеческих костей. Да это могильник!"; |
|
before_Take = "Фу, я не буду к этому прикасаться."; |
|
before_Smell = "Я не буду это нюхать!"; |
|
before_Taste = "Не хочу даже пробовать."; |
|
before_Touch = "Ни за что к этому не прикоснусь."; |
|
}:attr "scenery", |
|
obj { |
|
-"море|вода "; |
|
description = "Синее море, абсолютно прозрачное на мелководье. Красота неописуемая."; |
|
before_Take = "Мне некуда налить воды."; |
|
before_Smell = "Пахнет свежестью и морскими водорослями."; |
|
before_Taste = "На вкус вода солёная, ничего особенного, да и жажду этим не утолишь."; |
|
before_Touch = "Вода ледяная, бррр... Странно, при такой-то жаре."; |
|
}:attr "scenery", |
|
obj { |
|
-"рама|фигурки,животные/од"; |
|
description = "Бронзовая старинная рама. Украшена фигурками змеи, краба и дельфина."; |
|
before_Take = "Невозможно оторвать раму от зеркала."; |
|
before_Smell = "Пахнет металлом."; |
|
before_Taste = "На вкус, как металл."; |
|
before_Touch = "Прохладный металл."; |
|
before_Receive = "Лучше вставлять в каждую фигурку по отдельности."; |
|
}:attr "scenery", |
|
obj { |
|
-"драгоценные камни|камни|драгоценный камень|камень"; |
|
nam = "room4_gems"; |
|
description = "Красивые драгоценные камни, что дала мне русалка."; |
|
before_Show = function(s, w) |
|
if w ^ "room4_mermaid" then |
|
return "Русалка кивает, и показывает пальчиком на висящее в воздухе зеркало." |
|
end; |
|
return "Камнями лучше распоряжаться по отдельности."; |
|
end; |
|
before_Take = function(s) |
|
if have "room4_izymryd" or have "room4_rybin" or have "room4_sapfir" then |
|
return "Они уже у меня." |
|
else |
|
return false |
|
end |
|
end; |
|
before_Smell = "Пахнет красотой."; |
|
before_Taste = "На вкус, как стекло."; |
|
before_Touch = "Прохладные с идеальной огранкой."; |
|
before_Default = function(s, ev, w) |
|
if ev == 'Exam' then |
|
return false; |
|
end; |
|
p"Камнями лучше распоряжаться по отдельности."; |
|
end; |
|
}:attr "scenery":disable(), |
|
obj { |
|
-"русалка|ресницы|глаза|волосы|грудь"; |
|
nam = "room4_mermaid"; |
|
description = "Прекрасная русалка с длинными русыми волосами и большими томными глазами, обрамлёнными длинными пушистыми ресницами. Грудь прикрыта большими раковинами, скрепленными жемчугом. Морская дева по пояс высунулась из воды, и с интересом вас рассматривает."; |
|
["Talk,Listen"] = function(s) |
|
return [[Я пытаюсь поговорить с русалкой, но в ответ она лишь поёт:^ |
|
ПрОклятое зеркало старого капитана^ |
|
Затягивает всех, смотрящихся в стекло,^ |
|
На остров одинокий средь злого океана,^ |
|
Что стал могилой жуткой однажды для него.^ |
|
Тот капитан - колдун, ловушку душ поставил,^ |
|
Со Смертью заключив ужасный договор^ |
|
За тысячу людей, что в бездну он отправил^ |
|
Воскреснет вновь пират, продолжит свой террор.]]; |
|
end; |
|
before_Remove = function(s, w) |
|
mp:xaction('Take',s); |
|
end; |
|
life_Give = function(s, w) |
|
-- Очередная магия метапарсера для генерации фраз |
|
--"нужен" |
|
local things = { |
|
[[Русалка брезгливо скривила губки. ]], |
|
[[Русалка недовольно шлёпнула хвостом по воде, обдав меня дождём солёных брызг. ]], |
|
[[Русалка отрицательно покачала головой. ]], |
|
} |
|
local r = rnd(#things) |
|
return things[r].."Ей не {#word/нужен,#second} {#second}." |
|
end; |
|
Kiss = "Русалка уклонилась от прикосновений, смущённо хихикнула и погрозила мне пальчиком."; |
|
-- Методы возвращают объекты. Так что их можно "стакать" :) |
|
}:attr "static,animate":disable(), |
|
}; |
|
} |
|
|
|
obj { |
|
-"сапфир"; |
|
nam = "room4_sapfir"; |
|
found_in = "emptyroom"; |
|
description = [[Синий полупрозрачный драгоценный камень.]]; |
|
before_Insert = function(s, w) |
|
if not w ^ "room4_dolphin" then |
|
if w ^ "room4_crab" or w ^ "room4_frog" then |
|
return "Камень никак не хочет держаться в углублении." |
|
else |
|
return false |
|
end |
|
end |
|
place(s, w) |
|
s:attr "scenery" |
|
--"вставить" |
|
return "{#Me/им} вставляешь сапфир в углубление." |
|
end; |
|
Show = function(s, w) |
|
if w ^ "room4_mermaid" then |
|
return "Русалка кивает, и показывает пальчиком на висящее в воздухе зеркало." |
|
end; |
|
return false; |
|
end; |
|
} |
|
|
|
obj { |
|
-"рубин"; |
|
nam = "room4_rybin"; |
|
found_in = "emptyroom"; |
|
description = [[Сияющий красный драгоценный камень.]]; |
|
before_Insert = function(s, w) |
|
if not w ^ "room4_crab" then |
|
if w ^ "room4_dolphin" or w ^ "room4_frog" then |
|
return "Камень слишком большой и не влезает в углубление." |
|
else |
|
return false |
|
end |
|
end |
|
place(s, w) |
|
s:attr "scenery" |
|
return "{#Me/им} вставляешь рубин в углубление." |
|
end; |
|
Show = function(s, w) |
|
if w ^ "room4_mermaid" then |
|
return "Русалка кивает, и показывает пальчиком на висящее в воздухе зеркало." |
|
end; |
|
return false; |
|
end; |
|
} |
|
|
|
obj { |
|
-"изумруд"; |
|
nam = "room4_izymryd"; |
|
found_in = "emptyroom"; |
|
description = [[Зелёный блестящий драгоценный камень.]]; |
|
before_Insert = function(s, w) |
|
if not w ^ "room4_frog" then |
|
if w ^ "room4_crab" or w ^ "room4_dolphin" then |
|
return "Камень не подходит по форме к этому углублению." |
|
else |
|
return false |
|
end |
|
end |
|
place(s, w) |
|
s:attr "scenery" |
|
return "{#Me/им} вставляешь изумруд в углубление." |
|
end; |
|
Show = function(s, w) |
|
if w ^ "room4_mermaid" then |
|
return "Русалка кивает, и показывает пальчиком на висящее в воздухе зеркало." |
|
end; |
|
return false; |
|
end; |
|
} |
|
|
|
obj { |
|
-- Уточнение /но сообщает парсеру, что дельфин у нас неодушевлённый |
|
-"отверстие в фигурке дельфина/но|углубление в фигурке дельфин/но|дельфин/но"; |
|
nam = "room4_dolphin"; |
|
description = function(s) |
|
if where "room4_sapfir" ^ "room4_dolphin" then |
|
return "Бронзовая фигурка дельфина с переливающимся сапфиром во лбу." |
|
else |
|
return "Бронзовая фигурка дельфина с маленьким углублением во лбу." |
|
end |
|
end; |
|
-- При передаче объекта в объект у объекта-приёмника вызываются методы *_Recieve |
|
before_LetIn = function(s, w) |
|
--"подходит" |
|
return "{#Second/им} не {#word/подходит,#second} по форме." |
|
end; |
|
}:attr "static,container,open" |
|
|
|
obj { |
|
-"отверстие в фигурке краба/но|углубление в фигурке краба/но|краб/но|углубление/но"; |
|
nam = "room4_crab"; |
|
description = function(s) |
|
if where "room4_rybin" ^ "room4_crab" then |
|
return "Бронзовая фигурка краба с сияющим рубином в середине панциря." |
|
else |
|
return "Бронзовая фигурка краба с маленьким углублением в середине панциря." |
|
end |
|
end; |
|
before_LetIn = function(s, w) |
|
--"подходит" |
|
return "{#Second/им} не {#word/подходит,#second} по форме." |
|
end; |
|
}:attr "static,container,open" |
|
|
|
obj { |
|
-"отверстие в фигурке змеи/но|углубление в фигурке змеи/но|змея/но"; |
|
nam = "room4_frog"; |
|
description = function(s) |
|
if where "room4_izymryd" ^ "room4_frog" then |
|
return "Бронзовая змея, с похожим на каплю блестящего яда, изумрудом во рту." |
|
else |
|
return "Бронзовая змея с маленьким углублением во рту." |
|
end |
|
end; |
|
before_LetIn = function(s, w) |
|
--"подходит" |
|
return "{#Second/им} не {#word/подходит,#second} по форме." |
|
end; |
|
}:attr "static,container,open" |
|
-- |
|
-- |
|
-- |
|
|
|
obj { |
|
-"костяной ключ,ключ"; |
|
nam = "bonekey"; |
|
description = "Костяной ключ."; |
|
found_in = { 'room14_box1' }; |
|
score=false; |
|
after_Take = function(s) |
|
if not s.score then |
|
mp.score=mp.score+1; |
|
end; |
|
_'bonekey'.score=true; |
|
return false; |
|
end; |
|
} |
|
|
|
game.hint_verbs = { "#Exam", "#Walk", "#Take", "#Drop" }
|
|
|