diff --git a/decor.lua b/decor.lua --- a/decor.lua +++ b/decor.lua @@ -1027,7 +1027,7 @@ function decor:draw_bg() if not self.bgsprite or self.bgr ~= r then self.bgr = r; self.bgsprite = sprite.new(r); - if string.sub(r, 1, 3) == 'spr' then + if string.sub(r, 1, 4) == 'spr:' then self.bgsprite = self.bgsprite:dup(); end; end; @@ -1040,7 +1040,7 @@ function decor:render() if not decor.dirty then return end - decor.dirty = false + decor.dirty = false after_list = {} for _, v in pairs(self.objects) do local z = v.z or 0 diff --git a/dire/layout.lua b/dire/layout.lua --- a/dire/layout.lua +++ b/dire/layout.lua @@ -158,15 +158,15 @@ local function constraint_to_rect(constr y = canvas.h - bby - h; end; end; - + if constraint.dx then x = x + constraint.dx; end; - + if constraint.dy then y = y + constraint.dy; end; - + x = x + canvas.x; y = y + canvas.y; diff --git a/dire/theme.lua b/dire/theme.lua --- a/dire/theme.lua +++ b/dire/theme.lua @@ -224,7 +224,7 @@ local function apply_font(data, prefix) else theme.reset(prefix .. '.fnt.name'); end; - + if data and data.size then local size = data.size; @@ -424,12 +424,12 @@ local function apply_inv(px, leftof, rig else theme.reset('inv.mode'); end; - - if area.height then - theme.set('inv.fnt.height', area.height); - else - theme.reset('inv.fnt.height'); - end; + + if area.height then + theme.set('inv.fnt.height', area.height); + else + theme.reset('inv.fnt.height'); + end; return rect; end; @@ -508,12 +508,12 @@ local function apply_menu(px, leftof, ri theme.reset('menu.bw'); end; - if area.height then - theme.set('menu.fnt.height', area.height); - else - theme.reset('menu.fnt.height'); - end; - + if area.height then + theme.set('menu.fnt.height', area.height); + else + theme.reset('menu.fnt.height'); + end; + apply_font(area.text, 'menu'); return rect; @@ -735,8 +735,8 @@ diretheme.get_canvas = function() end; diretheme.set_canvas = function(canvas) - theme_changed = true; - local width = tonumber(theme.get('scr.w')); + theme_changed = true; + local width = tonumber(theme.get('scr.w')); local height = tonumber(theme.get('scr.h')); if canvas then default_canvas = direlayout.constraint_to_rect(canvas, {x=0, y=0, w=width, h=height}); diff --git a/ending.lua b/ending.lua --- a/ending.lua +++ b/ending.lua @@ -1,131 +1,131 @@ global { - solarscale_stays = false + solarscale_stays = false } function make_tbg_slice(scale, theme) - local src = pixels.new('images/' .. theme .. '_theme/text_bg.png'):scale(scale); - local tbg, tbg_slice - local frw, frh, fdx, fdy - if theme == 'main' then - tbg, tbg_slice = dire_slice_9(src, { - x = 9 * scale, - y = 6 * scale, - w = 96 * scale, - h = 96 * scale - }); - else - tbg, tbg_slice = dire_slice_9(src, { - x = 6 * scale, - y = 6 * scale, - w = 128 * scale, - h = 128 * scale - }); - end; - - return tbg, tbg_slice; + local src = pixels.new('images/' .. theme .. '_theme/text_bg.png'):scale(scale); + local tbg, tbg_slice + local frw, frh, fdx, fdy + if theme == 'main' then + tbg, tbg_slice = dire_slice_9(src, { + x = 9 * scale, + y = 6 * scale, + w = 96 * scale, + h = 96 * scale + }); + else + tbg, tbg_slice = dire_slice_9(src, { + x = 6 * scale, + y = 6 * scale, + w = 128 * scale, + h = 128 * scale + }); + end; + + return tbg, tbg_slice; end; function make_ending_frame(scale, theme, tbg, tbg_slice) - local fdx, fdy, frw, frh; - - - if theme == 'main' then - frw = 978 * scale; - frh = 612 * scale; - fdx = 9 * scale; - fdy = 6 * scale; - else - frw = 970 * scale; - frh = 610 * scale; - fdx = 5 * scale; - fdy = 5 * scale; - end; - - local bgframe = pixels.new(frw, frh); - dire_draw_9(tbg, bgframe, {x = 0; y = 0; w = frw; h = frh}, {parts=tbg_slice}); - return bgframe, fdx, fdy, frw, frh; + local fdx, fdy, frw, frh; + + + if theme == 'main' then + frw = 978 * scale; + frh = 612 * scale; + fdx = 9 * scale; + fdy = 6 * scale; + else + frw = 970 * scale; + frh = 610 * scale; + fdx = 5 * scale; + fdy = 5 * scale; + end; + + local bgframe = pixels.new(frw, frh); + dire_draw_9(tbg, bgframe, {x = 0; y = 0; w = frw; h = frh}, {parts=tbg_slice}); + return bgframe, fdx, fdy, frw, frh; end; function show_ending(theme, image, frames, process) - local scale = diretheme.get_scale(); - - local w = 960 * scale; - local h = 600 * scale; - local sw, sh = diretheme.get_screen(); - local ox = math.floor((sw - w) / 2); - local oy = math.floor((sh - h) / 2) - - local tbg, tbg_slice = make_tbg_slice(scale, theme); - - local tx = 24 * scale; - local tw = sw - tx - 24 * scale; - if tw > 600 * scale then - tw = 600 * scale; - tx = (sw - tw) / 2; - end; - - local th = 160 * scale; - local ty = sh - th - 24 * scale; - - local textbg = pixels.new(tw, th); - --local bgframe = pixels.new(frw, frh); - dire_draw_9(tbg, textbg, {x = 0; y = 0; w = tw; h = th}, {parts=tbg_slice}); - --dire_draw_9(tbg, bgframe, {x = 0; y = 0; w = frw; h = frh}, {parts=tbg_slice}); - local bgframe, fdx, fdy, frw, frh = make_ending_frame(scale, theme, tbg, tbg_slice); - D {'bgframe', 'img', bgframe:sprite(), x=ox - fdx, y=oy - fdy, w=frw * scale, h=frh * scale, z=2, background=true}; - - D {'background', 'img', get_sprite(image), x=ox, y=oy, w=w, h=h, z=1, background=true, process=process, frames=frames, animated=frames > 1, delay=250}; - D {'textbg', 'img', textbg:sprite(), x=tx, y=ty, w=tw, h=th, z=0, background=true}; + local scale = diretheme.get_scale(); + + local w = 960 * scale; + local h = 600 * scale; + local sw, sh = diretheme.get_screen(); + local ox = math.floor((sw - w) / 2); + local oy = math.floor((sh - h) / 2) + + local tbg, tbg_slice = make_tbg_slice(scale, theme); + + local tx = 24 * scale; + local tw = sw - tx - 24 * scale; + if tw > 600 * scale then + tw = 600 * scale; + tx = (sw - tw) / 2; + end; + + local th = 160 * scale; + local ty = sh - th - 24 * scale; + + local textbg = pixels.new(tw, th); + --local bgframe = pixels.new(frw, frh); + dire_draw_9(tbg, textbg, {x = 0; y = 0; w = tw; h = th}, {parts=tbg_slice}); + --dire_draw_9(tbg, bgframe, {x = 0; y = 0; w = frw; h = frh}, {parts=tbg_slice}); + local bgframe, fdx, fdy, frw, frh = make_ending_frame(scale, theme, tbg, tbg_slice); + D {'bgframe', 'img', bgframe:sprite(), x=ox - fdx, y=oy - fdy, w=frw * scale, h=frh * scale, z=2, background=true}; + + D {'background', 'img', get_sprite(image), x=ox, y=oy, w=w, h=h, z=1, background=true, process=process, frames=frames, animated=frames > 1, delay=250}; + D {'textbg', 'img', textbg:sprite(), x=tx, y=ty, w=tw, h=th, z=0, background=true}; end; --[[ 1. Leaving the tower ]] room { - state = 0; - nam = 'ending_left'; - nofollow = true; - theme = 'ending_outside'; - disp = 'Конец игры'; - noinv = true; - notitle = true; - themeInit = function(s) - show_ending('main', 'images/endings/tower_left.png', 6, function (v) - if v.frame_nr == 5 then - v.animated = false; - end; - end); - timer:set(25); - end; - themeDispose = function(s) - D {'bgframe'}; - D {'background'}; - D {'textbg'}; - timer:stop(); - end; - onenter = function(s) - s.state = s.state + 1; - if s.state == 1 then - pr 'Я делаю шаг в сторону двери, но что-то останавливает меня. Что, если второго шанса не будет?'; - return false; - elseif s.state == 2 then - pr 'Я продолжаю двигаться к выходу, В моей голове возникает изображение двери башни, захлопывающейся за мной. '; - return false; - elseif s.state == 3 then - pr 'Я продолжаю двигаться к выходу из башни, воздух словно сгущается передо мной, не желая выпускать. Темнота вокруг меня становится осязаемой, как будто башня начинает отторгать меня. '; - return false; - end; - end; - dsc = function(s) - pr [[Я выхожу из башни, и массивная каменная плита опускается за мной, навеки закрывая путь внутрь. ]] - if solarscale_with_me then - pr [[Соларскейл задумчиво смотрит на меня и на башню. Некоторое время мы тщательно изучаем ее со всех сторон, но в конце концов, отчаявшись, отправляемся каждый своей дорогой. ]]; - end; - pr [[^Столетие за столетием я возвращался к этому месту, но гладкий черный камень все также оставался неприступен для меня. ]]; - if solarscale_with_me then - pr [[Не удалось мне найти и Соларскейл -- сколько ни пытался, я не смог обнаружить никаких следов прекрасной драконессы. ]]; - end; - end; + state = 0; + nam = 'ending_left'; + nofollow = true; + theme = 'ending_outside'; + disp = 'Конец игры'; + noinv = true; + notitle = true; + themeInit = function(s) + show_ending('main', 'images/endings/tower_left.png', 6, function (v) + if v.frame_nr == 5 then + v.animated = false; + end; + end); + timer:set(25); + end; + themeDispose = function(s) + D {'bgframe'}; + D {'background'}; + D {'textbg'}; + timer:stop(); + end; + onenter = function(s) + s.state = s.state + 1; + if s.state == 1 then + pr 'Я делаю шаг в сторону двери, но что-то останавливает меня. Что, если второго шанса не будет?'; + return false; + elseif s.state == 2 then + pr 'Я продолжаю двигаться к выходу, В моей голове возникает изображение двери башни, захлопывающейся за мной. '; + return false; + elseif s.state == 3 then + pr 'Я продолжаю двигаться к выходу из башни, воздух словно сгущается передо мной, не желая выпускать. Темнота вокруг меня становится осязаемой, как будто башня начинает отторгать меня. '; + return false; + end; + end; + dsc = function(s) + pr [[Я выхожу из башни, и массивная каменная плита опускается за мной, навеки закрывая путь внутрь. ]] + if solarscale_with_me then + pr [[Соларскейл задумчиво смотрит на меня и на башню. Некоторое время мы тщательно изучаем ее со всех сторон, но в конце концов, отчаявшись, отправляемся каждый своей дорогой. ]]; + end; + pr [[^Столетие за столетием я возвращался к этому месту, но гладкий черный камень все также оставался неприступен для меня. ]]; + if solarscale_with_me then + pr [[Не удалось мне найти и Соларскейл -- сколько ни пытался, я не смог обнаружить никаких следов прекрасной драконессы. ]]; + end; + end; } --[[ @@ -133,28 +133,28 @@ 2. Destroying the tower ]] room { - nam = 'ending_formatted'; - disp = 'Конец игры'; - theme = 'tower'; - nofollow = true; - noinv = true; - notitle = true; - theme = 'ending_outside'; - themeInit = function(s) - show_ending('main', 'images/endings/tower_ruin.png', 1); - end; - themeDispose = function(s) - D {'bgframe'}; - D {'background'}; - D {'textbg'}; - end; - dsc = function(s) - if solarscale_with_me then - pr [[Я отошел от компьютера и в этот момент ощутил неуловимое изменение, произошедшее в башне. Мир вокруг нас с Соларскейл начал расплываться и вскоре мы оказались в лесу. Повсюду валялись обломки черного камня, только что составлявшего башню, хотя узнать ее в них было бы непросто. Переглянувшись с драконессой, мы попрощались и отправились каждый своей дорогой. ^Столетие за столетием я возвращался к этому месту, но не находил ничего, кроме забытых всеми осколков черного камня. Неизвестной для меня осталась и судьба Соларскейл -- сколько ни пытался, я не смог найти никаких следов прекрасной драконессы. ]]; - else - pr [[Я отошел от компьютера и в этот момент ощутил неуловимое изменение, произошедшее в башне. Мир вокруг меня начал расплываться и вскоре я оказался в лесу. Повсюду валялись обломки черного камня, только что составлявшего башню, хотя узнать ее в них было бы непросто. Вздохнув, я расправил крылья и отправился домой. ^Столетие за столетием я возвращался к этому месту, но не находил ничего, кроме забытых всеми осколков черного камня. ]]; - end; - end; + nam = 'ending_formatted'; + disp = 'Конец игры'; + theme = 'tower'; + nofollow = true; + noinv = true; + notitle = true; + theme = 'ending_outside'; + themeInit = function(s) + show_ending('main', 'images/endings/tower_ruin.png', 1); + end; + themeDispose = function(s) + D {'bgframe'}; + D {'background'}; + D {'textbg'}; + end; + dsc = function(s) + if solarscale_with_me then + pr [[Я отошел от компьютера и в этот момент ощутил неуловимое изменение, произошедшее в башне. Мир вокруг нас с Соларскейл начал расплываться и вскоре мы оказались в лесу. Повсюду валялись обломки черного камня, только что составлявшего башню, хотя узнать ее в них было бы непросто. Переглянувшись с драконессой, мы попрощались и отправились каждый своей дорогой. ^Столетие за столетием я возвращался к этому месту, но не находил ничего, кроме забытых всеми осколков черного камня. Неизвестной для меня осталась и судьба Соларскейл -- сколько ни пытался, я не смог найти никаких следов прекрасной драконессы. ]]; + else + pr [[Я отошел от компьютера и в этот момент ощутил неуловимое изменение, произошедшее в башне. Мир вокруг меня начал расплываться и вскоре я оказался в лесу. Повсюду валялись обломки черного камня, только что составлявшего башню, хотя узнать ее в них было бы непросто. Вздохнув, я расправил крылья и отправился домой. ^Столетие за столетием я возвращался к этому месту, но не находил ничего, кроме забытых всеми осколков черного камня. ]]; + end; + end; } --[[ @@ -164,85 +164,85 @@ 3. True ending stage 1 -- 3a. With solarscale room { - nam = 'ending_solarscale_pre'; - nofollow = true; - theme = 'tower'; - disp = 'Башня, серверная'; - noinv = true; - dsc = [[В сознании моем звучит мягкий, спокойный и, кажется, давно знакомый голос: "Добро пожаловать домой". Стены начинают растворяться, открывая вид на бескрайние просторы вселенной и в - этот момент я чувствую легкое прикосновение, возвращающее меня к реальности. ]]; - way = { - path {'Продолжить', 'ending_solarscale_dlg'}; - }; + nam = 'ending_solarscale_pre'; + nofollow = true; + theme = 'tower'; + disp = 'Башня, серверная'; + noinv = true; + dsc = [[В сознании моем звучит мягкий, спокойный и, кажется, давно знакомый голос: "Добро пожаловать домой". Стены начинают растворяться, открывая вид на бескрайние просторы вселенной и в + этот момент я чувствую легкое прикосновение, возвращающее меня к реальности. ]]; + way = { + path {'Продолжить', 'ending_solarscale_dlg'}; + }; } dlg { - nam = 'ending_solarscale_dlg'; - nofollow = true; - theme = 'tower'; - noinv = true; - disp = 'Соларскейл'; - enter = [[Я оборачиваюсь.Соларскейл произносит слова прощания: "Мне пора уходить. Счастливого путешествия! Надеюсь, мы еще увидимся". ]]; - phr = { - {"[Схватить Соларскейл за руку]", function(s) - walk('ending_solarscale_leaving'); - return [[Я слышу в голове голос: "Оставь ее. У нее свой путь". От удивления я разжимаю руку. Этого оказывается достаточно. ]]; - end}; - {"Вы не хотите остаться?", function(s) - if solarscale_helps >= 2 and _'solarscale_ally'.tea_given then - solarscale_stays = true; - walk('ending_solarcale_stays'); - return 'Соларскейл на мгновение замирает, а потом с искрами в глазах отвечает: "Конечно, хочу!"'; - else - walk('ending_solarscale_leaving'); - return 'Соларскейл печально опускает голову: "Меня ждут дома. Мне нужно лететь". ' - end; - end}; - {"Что же, не буду вас задерживать. До новых встреч. ", function(s) - walk('ending_solarscale_leaving') - return false; - end}; - }; + nam = 'ending_solarscale_dlg'; + nofollow = true; + theme = 'tower'; + noinv = true; + disp = 'Соларскейл'; + enter = [[Я оборачиваюсь.Соларскейл произносит слова прощания: "Мне пора уходить. Счастливого путешествия! Надеюсь, мы еще увидимся". ]]; + phr = { + {"[Схватить Соларскейл за руку]", function(s) + walk('ending_solarscale_leaving'); + return [[Я слышу в голове голос: "Оставь ее. У нее свой путь". От удивления я разжимаю руку. Этого оказывается достаточно. ]]; + end}; + {"Вы не хотите остаться?", function(s) + if solarscale_helps >= 2 and _'solarscale_ally'.tea_given then + solarscale_stays = true; + walk('ending_solarcale_stays'); + return 'Соларскейл на мгновение замирает, а потом с искрами в глазах отвечает: "Конечно, хочу!"'; + else + walk('ending_solarscale_leaving'); + return 'Соларскейл печально опускает голову: "Меня ждут дома. Мне нужно лететь". ' + end; + end}; + {"Что же, не буду вас задерживать. До новых встреч. ", function(s) + walk('ending_solarscale_leaving') + return false; + end}; + }; } room { - nam = 'ending_solarcale_stays'; - notitle = true; - nofollow = true; - theme = 'ending_inside'; - noinv = true; - disp = 'Конец игры'; - dsc = [[Мое восприятие изменяется. Я ощущаю, как башня медленно растворяется в воздухе. Соларскейл с изумлением глядит на то, как башня адаптируется под нас -- меняются размеры и расположение комнат, появляются и исчезают предметы окружения и стены. ]]; - way = { - path {'Продолжить', 'true_ending_step_1'}; - }; + nam = 'ending_solarcale_stays'; + notitle = true; + nofollow = true; + theme = 'ending_inside'; + noinv = true; + disp = 'Конец игры'; + dsc = [[Мое восприятие изменяется. Я ощущаю, как башня медленно растворяется в воздухе. Соларскейл с изумлением глядит на то, как башня адаптируется под нас -- меняются размеры и расположение комнат, появляются и исчезают предметы окружения и стены. ]]; + way = { + path {'Продолжить', 'true_ending_step_1'}; + }; }; room { - nam = 'ending_solarscale_leaving'; - notitle = true; - nofollow = true; - theme = 'ending_inside'; - noinv = true; - disp = 'Конец игры'; - dsc = [[Я не успеваю моргнуть и глазом, как Соларскейл покидает башню. Кажется, я вижу собственными глазами, как драконесса вылетает через проем на первом этаже. Тяжелая каменная плита опускается за ней. Я вижу, как Соларскейл оборачивается, глядя на башню. Ее чешуя сияет в лучах заходящего Солнца, а изумрудно-зеленые глаза смотрят на меня. Мое восприятие изменяется. Я ощущаю, как башня медленно растворяется в воздухе, а драконесса отворачивается и продолжает свой путь. ]]; - way = { - path {'Продолжить', 'true_ending_step_1'}; - }; + nam = 'ending_solarscale_leaving'; + notitle = true; + nofollow = true; + theme = 'ending_inside'; + noinv = true; + disp = 'Конец игры'; + dsc = [[Я не успеваю моргнуть и глазом, как Соларскейл покидает башню. Кажется, я вижу собственными глазами, как драконесса вылетает через проем на первом этаже. Тяжелая каменная плита опускается за ней. Я вижу, как Соларскейл оборачивается, глядя на башню. Ее чешуя сияет в лучах заходящего Солнца, а изумрудно-зеленые глаза смотрят на меня. Мое восприятие изменяется. Я ощущаю, как башня медленно растворяется в воздухе, а драконесса отворачивается и продолжает свой путь. ]]; + way = { + path {'Продолжить', 'true_ending_step_1'}; + }; } -- 3b. Without solarscale room { - nam = 'ending_no_solarscale'; - notitle = true; - nofollow = true; - theme = 'ending_inside'; - noinv = true; - disp = 'Конец игры'; - dsc = 'На одной из вершин на краю кратере сидела золотая драконесса. Ее чешуя сверкала в лучах заходящего Солнца, а изумрудно-зеленые глаза смотрели в центр кратера на медленно растворяющуюся в воздухе черную башню. Как только башня полностью исчезла, драконесса расправила тонкие сияющие крылья и поднялась в небеса. '; - way = { - path {'Продолжить', 'true_ending_step_1'}; - }; + nam = 'ending_no_solarscale'; + notitle = true; + nofollow = true; + theme = 'ending_inside'; + noinv = true; + disp = 'Конец игры'; + dsc = 'На одной из вершин на краю кратере сидела золотая драконесса. Ее чешуя сверкала в лучах заходящего Солнца, а изумрудно-зеленые глаза смотрели в центр кратера на медленно растворяющуюся в воздухе черную башню. Как только башня полностью исчезла, драконесса расправила тонкие сияющие крылья и поднялась в небеса. '; + way = { + path {'Продолжить', 'true_ending_step_1'}; + }; } --[[ @@ -253,85 +253,85 @@ 4c. Irradiated ]] room { - nam = 'true_ending_step_1'; - disp = 'Конец игры'; - noinv = true; - notitle = true; - nofollow = true; - theme = 'ending_inside'; - themeInit = function(s) - show_ending('tower', 'images/endings/space.png', 1); - timer:set(25); - end; - themeDispose = function(s) - D {'bgframe'}; - D {'background'}; - D {'textbg'}; - timer:stop(); - end; - dsc = function(s) - pr [[ - Перед моим взором раскинулась бескрайняя вселенная. Все дороги и все миры открыты передо мной. По своему желанию я могу оказаться в любом месте в любое время. Я поднимаюсь на вершину башни и мысленно отдаю команду отправляться в путь. - ]]; - if solarscale_stays then - pr [[Соларскейл же немедленно начинает исследовать внутренние пространства башни. ]]; - end; - end; - way = { - path {'Продолжить', 'true_ending_step_2'}; - }; + nam = 'true_ending_step_1'; + disp = 'Конец игры'; + noinv = true; + notitle = true; + nofollow = true; + theme = 'ending_inside'; + themeInit = function(s) + show_ending('tower', 'images/endings/space.png', 1); + timer:set(25); + end; + themeDispose = function(s) + D {'bgframe'}; + D {'background'}; + D {'textbg'}; + timer:stop(); + end; + dsc = function(s) + pr [[ + Перед моим взором раскинулась бескрайняя вселенная. Все дороги и все миры открыты передо мной. По своему желанию я могу оказаться в любом месте в любое время. Я поднимаюсь на вершину башни и мысленно отдаю команду отправляться в путь. + ]]; + if solarscale_stays then + pr [[Соларскейл же немедленно начинает исследовать внутренние пространства башни. ]]; + end; + end; + way = { + path {'Продолжить', 'true_ending_step_2'}; + }; } room { - nam = 'true_ending_step_2'; - disp = 'Конец игры'; - noinv = true; - notitle = true; - nofollow = true; - theme = 'ending_inside'; - dsc = function(s) - pr [[Сперва меня удивляет, насколько легко и чутко башня реагирует на нас, меняя размеры, расположение и даже количество комнат, но вскоре я привыкаю к тому, что за дверью всегда находится именно то, что я ищу. ]] - if solarscale_stays then - pr [[И как бы далеко ни отдалялись мы с Соларскейл, мы всегда непостижимым образом находились рядом.]]; - end; - end; - way = { - path {'Продолжить', 'true_ending_step_3'}; - }; + nam = 'true_ending_step_2'; + disp = 'Конец игры'; + noinv = true; + notitle = true; + nofollow = true; + theme = 'ending_inside'; + dsc = function(s) + pr [[Сперва меня удивляет, насколько легко и чутко башня реагирует на нас, меняя размеры, расположение и даже количество комнат, но вскоре я привыкаю к тому, что за дверью всегда находится именно то, что я ищу. ]] + if solarscale_stays then + pr [[И как бы далеко ни отдалялись мы с Соларскейл, мы всегда непостижимым образом находились рядом.]]; + end; + end; + way = { + path {'Продолжить', 'true_ending_step_3'}; + }; } room { - nam = 'true_ending_step_3'; - disp = 'Конец игры'; - noinv = true; - notitle = true; - nofollow = true; - theme = 'ending_inside'; - dsc = function(s) - if solarscale_stays then - pr [[Тысячелетие за тысячелетием мы путешествуем по мирам, собирая их знания и сохраняя самое ценное их наследие. Вскоре время и пространство перестают иметь для нас всякое значение. ]]; - elseif irradiated then - pr [[Тысячелетие за тысячелетием я путешествую по мирам, собирая их знания, помогая нуждающимся и сохраняя самое ценное их наследие. Несмотря на все это, странное ощущение не дает мне покоя -- словно дни мои медленно истекают и путешествие мое не будет вечным. ]]; - else - pr [[Тысячелетие за тысячелетием я путешествую по мирам, собирая их знания, помогая нуждающимся и сохраняя самое ценное их наследие. Вскоре время и пространство перестают иметь для меня всякое значение. ]]; - end; - - end; - way = { - path {'Продолжить', 'ending_credits'}; - }; + nam = 'true_ending_step_3'; + disp = 'Конец игры'; + noinv = true; + notitle = true; + nofollow = true; + theme = 'ending_inside'; + dsc = function(s) + if solarscale_stays then + pr [[Тысячелетие за тысячелетием мы путешествуем по мирам, собирая их знания и сохраняя самое ценное их наследие. Вскоре время и пространство перестают иметь для нас всякое значение. ]]; + elseif irradiated then + pr [[Тысячелетие за тысячелетием я путешествую по мирам, собирая их знания, помогая нуждающимся и сохраняя самое ценное их наследие. Несмотря на все это, странное ощущение не дает мне покоя -- словно дни мои медленно истекают и путешествие мое не будет вечным. ]]; + else + pr [[Тысячелетие за тысячелетием я путешествую по мирам, собирая их знания, помогая нуждающимся и сохраняя самое ценное их наследие. Вскоре время и пространство перестают иметь для меня всякое значение. ]]; + end; + + end; + way = { + path {'Продолжить', 'ending_credits'}; + }; } room { - nam = 'ending_credits'; - disp = 'Спасибо за игру'; - noinv = true; - nofollow = true; - notitle = true; - theme = 'ending_inside'; - dsc = [[ - Автор игры: Khaelenmore Thaal^ - Графика: Sabra Naikomy^ - Музыка: Khaelenmore Thaal - ]]; + nam = 'ending_credits'; + disp = 'Спасибо за игру'; + noinv = true; + nofollow = true; + notitle = true; + theme = 'ending_inside'; + dsc = [[ + Автор игры: Khaelenmore Thaal^ + Графика: Sabra Naikomy^ + Музыка: Khaelenmore Thaal + ]]; } diff --git a/fading.lua b/fading.lua --- a/fading.lua +++ b/fading.lua @@ -13,7 +13,7 @@ local f = std.obj { effect = false; defeffect = false; nam = '@fading'; - enabled = false; + enabled = false; } function f.effects.fadeblack(s, src, dst) @@ -84,7 +84,7 @@ function f.effects.move_down(s, src, dst end function f.effects.animate(s, src, dst) - s.animate(s.step, src, dst); + s.animate(s.step, src, dst); end; local scr, scr2 @@ -162,20 +162,20 @@ std.mod_cmd(function(cmd) end, -1) std.mod_init(function() f.change { 'crossfade', max = 8 }; - - local oldrender = sprite.render_callback() - sprite.render_callback(function() - if f.started and not sprite.direct() then - if oldrender then - oldrender() - end - sprite.direct(true) - sprite.scr():copy(scr2) - scr:copy(sprite.scr()) - elseif not f.started and oldrender then - oldrender() - end - end) + + local oldrender = sprite.render_callback() + sprite.render_callback(function() + if f.started and not sprite.direct() then + if oldrender then + oldrender() + end + sprite.direct(true) + sprite.scr():copy(scr2) + scr:copy(sprite.scr()) + elseif not f.started and oldrender then + oldrender() + end + end) end) diff --git a/forest.lua b/forest.lua --- a/forest.lua +++ b/forest.lua @@ -1,1417 +1,1438 @@ global { - raspberry_pie_status = 0; - seen_ring_librarian = false; - seen_ring_box = false; - power_on = false; - irradiated = false; - rods_raised = false; - rods_enriched = false; - candles_solved = false; - solarscale_with_me = false; + raspberry_pie_status = 0; + seen_ring_librarian = false; + seen_ring_box = false; + power_on = false; + irradiated = false; + rods_raised = false; + rods_enriched = false; + candles_solved = false; + solarscale_with_me = false; - solarscale_helps = 2; - solarscale_glade_visited = false; - pc_status = false; - village_visited = false; - candle_taken = false; + solarscale_helps = 2; + solarscale_glade_visited = false; + pc_status = false; + village_visited = false; + candle_taken = false; } obj { - nam = 'raspberry_pie'; - disp = translate(forest_locale, 'raspberry_pie'); - inv = translate(forest_locale, 'raspberry_pie_inv'); + nam = 'raspberry_pie'; + disp = translate(forest_locale, 'raspberry_pie'); + inv = translate(forest_locale, 'raspberry_pie_inv'); } obj { - nam = 'flower'; - disp =translate(forest_locale, 'flower'); - inv = translate(forest_locale, 'flower_inv'); + nam = 'flower'; + disp =translate(forest_locale, 'flower'); + inv = translate(forest_locale, 'flower_inv'); } obj { - nam = 'lock'; - disp = translate(forest_locale, 'lock'); - disp2 = translate(forest_locale, 'lock_disp2'); - disp3 = translate(forest_locale, 'lock_disp3'); - inv = translate(forest_locale, 'lock_inv'); + nam = 'lock'; + disp = translate(forest_locale, 'lock'); + disp2 = translate(forest_locale, 'lock_disp2'); + disp3 = translate(forest_locale, 'lock_disp3'); + inv = translate(forest_locale, 'lock_inv'); } room { - nam = 'above_forest'; - pic = 'images/above_forest.png'; - disp = translate(forest_locale, 'above_forest'); - theme = 'main'; - decor = function(s) - pr(translate_now(forest_locale, 'above_forest_decor')); - if not village_visited then - pr(translate_now(forest_locale, 'above_forest_decor_village')); - end; - end; - enter = function(s) - if here():from()^'intro_start' or here():from()^'intro_settings' or here():from()^'intro_info' then - stop_menu(); - end; - if here()^'forest_glade' then - pr(translate_now(forest_locale, 'above_forest_enter')); - end; - snd.music('sound/bgm_forest.ogg'); - end; - way = { - path {"#down", translate(forest_locale, 'transition_land'), 'forest_glade'}:disable(); - path {"#north", translate(forest_locale, 'transition_north_along_road'), 'above_near_village'}; - } + nam = 'above_forest'; + pic = 'images/above_forest.png'; + disp = translate(forest_locale, 'above_forest'); + theme = 'main'; + decor = function(s) + pr(translate_now(forest_locale, 'above_forest_decor')); + if not village_visited then + pr(translate_now(forest_locale, 'above_forest_decor_village')); + end; + end; + enter = function(s) + if here():from()^'intro_start' or here():from()^'intro_settings' or here():from()^'intro_info' then + stop_menu(); + end; + if here()^'forest_glade' then + pr(translate_now(forest_locale, 'above_forest_enter')); + end; + snd.music('sound/bgm_forest.ogg'); + end; + way = { + path {"#down", translate(forest_locale, 'transition_land'), 'forest_glade'}:disable(); + path {"#north", translate(forest_locale, 'transition_north_along_road'), 'above_near_village'}; + } }:with { - obj { - nam = '#thicket'; - act = translate(forest_locale, 'above_forest_thicket_act'); - }; - obj { - nam = '#road'; - act = function(s) - pr(translate_now(forest_locale, 'above_forest_road_act')); + obj { + nam = '#thicket'; + act = translate(forest_locale, 'above_forest_thicket_act'); + }; + obj { + nam = '#road'; + act = function(s) + pr(translate_now(forest_locale, 'above_forest_road_act')); - if not village_visited then - pr(translate_now(forest_locale, 'above_forest_road_act_village')); - end; - end; - }; - obj { - nam = '#powerlines'; - act = translate(forest_locale, 'above_forest_powerlines_act'); - }; - obj { - nam = '#glade'; - act = function(s) - pr(translate_now(forest_locale, 'above_forest_glade_act')); - if _'#down':disabled() then - _'#down':enable(); - pr(translate_now(forest_locale, 'above_forest_glade_act_first')); - end; - end; - }; - 'mountains'; - 'wind'; - 'sun'; - 'clouds'; + if not village_visited then + pr(translate_now(forest_locale, 'above_forest_road_act_village')); + end; + end; + }; + obj { + nam = '#powerlines'; + act = translate(forest_locale, 'above_forest_powerlines_act'); + }; + obj { + nam = '#glade'; + act = function(s) + pr(translate_now(forest_locale, 'above_forest_glade_act')); + if _'#down':disabled() then + _'#down':enable(); + pr(translate_now(forest_locale, 'above_forest_glade_act_first')); + end; + end; + }; + 'mountains'; + 'wind'; + 'sun'; + 'clouds'; } room { - nam = 'forest_glade'; - pic = function(s) - if _('#flowers').state == 1 then - return 'images/forest_glade.png'; - else - return 'images/forest_glade.png;images/forest_glade_flower.png@269,201'; - end; - end; - disp = translate(forest_locale, 'forest_glade'); - theme = 'main'; - onenter = function(s) - pr(translate_now(forest_locale, 'forest_glade_enter')); - if solarscale_with_me and not solarscale_glade_visited then - solarscale_glade_visited = true; - pr(translate_now(forest_locale, 'forest_glade_solarscale')); - end; - end; - decor = translate(forest_locale, 'forest_glade_decor'); - way = { - path {'#up', translate(forest_locale, 'transition_fly'), 'above_forest'}; - } + nam = 'forest_glade'; + pic = function(s) + if _('#flowers').state == 1 then + return 'images/forest_glade.png'; + else + return 'images/forest_glade.png;images/forest_glade_flower.png@269,201'; + end; + end; + disp = translate(forest_locale, 'forest_glade'); + theme = 'main'; + onenter = function(s) + pr(translate_now(forest_locale, 'forest_glade_enter')); + if solarscale_with_me and not solarscale_glade_visited then + solarscale_glade_visited = true; + pr(translate_now(forest_locale, 'forest_glade_solarscale')); + end; + end; + decor = translate(forest_locale, 'forest_glade_decor'); + way = { + path {'#up', translate(forest_locale, 'transition_fly'), 'above_forest'}; + } }: with { - obj { - nam = '#thicket'; - act = translate(forest_locale, 'forest_glade_thicket'); - }; - obj { - nam = '#birds'; - act = translate(forest_locale, 'forest_glade_birds'); - }; - obj { - nam = '#grass'; - act = function(s) - _'#flowers':enable(); - return translate_now(forest_locale, 'forest_glade_grass'); - end; - }; - obj { - state = 0; - nam = '#flowers'; - act = function(s) - if s.state == 0 then - take('flower'); - s.state = 1; - return translate_now(forest_locale, 'forest_glade_flowers_first'); - else - return translate_now(forest_locale, 'forest_glade_flowers'); - end; - end; - }:disable(); + obj { + nam = '#thicket'; + act = translate(forest_locale, 'forest_glade_thicket'); + }; + obj { + nam = '#birds'; + act = translate(forest_locale, 'forest_glade_birds'); + }; + obj { + nam = '#grass'; + act = function(s) + _'#flowers':enable(); + return translate_now(forest_locale, 'forest_glade_grass'); + end; + }; + obj { + state = 0; + nam = '#flowers'; + act = function(s) + if s.state == 0 then + take('flower'); + s.state = 1; + return translate_now(forest_locale, 'forest_glade_flowers_first'); + else + return translate_now(forest_locale, 'forest_glade_flowers'); + end; + end; + }:disable(); } room { - nam = 'above_near_village'; - disp = translate(forest_locale, 'above_near_village'); - pic = 'images/above_near_village.png'; - theme = 'main'; - onenter = function(s) - if here()^'near_village' then - return translate_now(forest_locale, 'above_near_village_enter'); - end; - end; - decor = translate(forest_locale, 'above_near_village_decor'); - way = { - path {"#south", translate(forest_locale, 'transition_south_along_road'), 'above_forest'}; - path {"#down", translate(forest_locale, 'transition_land'), 'near_village'}; - path {"#north", translate(forest_locale, 'transition_north_to_the_village'), 'above_village'}; - } + nam = 'above_near_village'; + disp = translate(forest_locale, 'above_near_village'); + pic = 'images/above_near_village.png'; + theme = 'main'; + onenter = function(s) + if here()^'near_village' then + return translate_now(forest_locale, 'above_near_village_enter'); + end; + end; + decor = translate(forest_locale, 'above_near_village_decor'); + way = { + path {"#south", translate(forest_locale, 'transition_south_along_road'), 'above_forest'}; + path {"#down", translate(forest_locale, 'transition_land'), 'near_village'}; + path {"#north", translate(forest_locale, 'transition_north_to_the_village'), 'above_village'}; + } }: with { - obj { - nam = '#road'; - act = translate(forest_locale, 'above_near_village_road'); - }; - obj { - nam = '#thicket'; - act = translate(forest_locale, 'above_near_village_thicket'); - }; - obj { - nam = '#village'; - act = function(s) - pr(translate_now(forest_locale, 'above_near_village_village')); - if not village_visited then - village_visited = true; - pr(translate_now(forest_locale, 'village_unvisited')); - end; - end; - }; - 'mountains'; - 'wind'; - 'sun'; - 'clouds'; + obj { + nam = '#road'; + act = translate(forest_locale, 'above_near_village_road'); + }; + obj { + nam = '#thicket'; + act = translate(forest_locale, 'above_near_village_thicket'); + }; + obj { + nam = '#village'; + act = function(s) + pr(translate_now(forest_locale, 'above_near_village_village')); + if not village_visited then + village_visited = true; + pr(translate_now(forest_locale, 'village_unvisited')); + end; + end; + }; + 'mountains'; + 'wind'; + 'sun'; + 'clouds'; }; room { - nam = 'above_village'; - pic = 'images/above_village.png'; - disp = 'Над деревней'; - theme = 'main'; - decor = translate(forest_locale, 'above_village_decor'); - way = { - path {"#south", translate(forest_locale, 'transition_south_along_road'), 'above_near_village'}; - path {"#down", translate(forest_locale, 'transition_land'), 'village_no_way'}; - path {"fly_west_from_village", translate(forest_locale, 'transition_west'), 'above_west'}:disable(); - } + nam = 'above_village'; + pic = 'images/above_village.png'; + disp = 'Над деревней'; + theme = 'main'; + decor = translate(forest_locale, 'above_village_decor'); + way = { + path {"#south", translate(forest_locale, 'transition_south_along_road'), 'above_near_village'}; + path {"#down", translate(forest_locale, 'transition_land'), 'village_no_way'}; + path {"fly_west_from_village", translate(forest_locale, 'transition_west'), 'above_west'}:disable(); + } }: with { - obj { - nam = '#thicket'; - act = translate(forest_locale, 'above_village_thicket'); - }; - obj { - nam = '#road'; - act = translate(forest_locale, 'above_village_road'); - }; - obj { - nam = '#village'; - act = function(s) - pr(translate_now(forest_locale, 'above_village_village')); - if not village_visited then - village_visited = true; - pr(translate_now(forest_locale, 'village_unvisited')); - end; - end; - }; - 'mountains'; - 'wind'; - 'sun'; - 'clouds'; + obj { + nam = '#thicket'; + act = translate(forest_locale, 'above_village_thicket'); + }; + obj { + nam = '#road'; + act = translate(forest_locale, 'above_village_road'); + }; + obj { + nam = '#village'; + act = function(s) + pr(translate_now(forest_locale, 'above_village_village')); + if not village_visited then + village_visited = true; + pr(translate_now(forest_locale, 'village_unvisited')); + end; + end; + }; + 'mountains'; + 'wind'; + 'sun'; + 'clouds'; }; obj { - nam = 'sun'; - act = 'Теплые лучи солнца приятно согревают мою чешую, пробиваясь сквозь тонкие перистые облака. '; + nam = 'sun'; + act = 'Теплые лучи солнца приятно согревают мою чешую, пробиваясь сквозь тонкие перистые облака. '; }; obj { - nam = 'sun_transformed'; - act = 'Теплые лучи солнца пробиваются сквозь тонкие перистые облака и заливают все вокруг золотистым светом.'; + nam = 'sun_transformed'; + act = 'Теплые лучи солнца пробиваются сквозь тонкие перистые облака и заливают все вокруг золотистым светом.'; }; obj { - nam = 'clouds'; - act = 'Пронзаемые лучами солнца словно копьями, тонкие перистые облака неспешно проплывают надо мной, повинуясь воздушным течениям. '; + nam = 'clouds'; + act = 'Пронзаемые лучами солнца словно копьями, тонкие перистые облака неспешно проплывают надо мной, повинуясь воздушным течениям. '; }; obj { - nam = 'wind'; - act = 'Легкий ветерок дует с востока, принося желанную прохладу. Его мягкое дыхание едва колышет вершины деревьев и заставляет тонкие облака медленно плыть на запад. '; + nam = 'wind'; + act = 'Легкий ветерок дует с востока, принося желанную прохладу. Его мягкое дыхание едва колышет вершины деревьев и заставляет тонкие облака медленно плыть на запад. '; }; obj { - nam = 'mountains'; - act = 'Горная цепь вспарывает лесной ковер к западу от меня. Редкие деревья отчаянно цепляются за каменистые склоны, словно стремясь заживить эту гигантскую рану. '; + nam = 'mountains'; + act = 'Горная цепь вспарывает лесной ковер к западу от меня. Редкие деревья отчаянно цепляются за каменистые склоны, словно стремясь заживить эту гигантскую рану. '; }; room { - nam = 'above_west'; - disp = 'К западу от деревни'; - pic = 'images/above_west.png'; - theme = 'main'; - decor = [[{#village|Деревня} осталась далеко на востоке. Подо мной проносятся острые {#mountaintops|вершины} и каменистые {#mountainslopes|склоны}, усеянные валунами, а вдалеке на западе я вижу огромный {#crater|кратер}. Лучи яркого летнего {sun|солнца}, проникающие сквозь тонкие перистые {clouds|облака}, падают на мою чешую, согревая ее. ]]; - way = { - path {"#east", 'На восток, к деревне', 'above_village'}; - path {"#west", 'На запад, к кратеру', 'above_crater'}:disable(); - } + nam = 'above_west'; + disp = 'К западу от деревни'; + pic = 'images/above_west.png'; + theme = 'main'; + decor = [[{#village|Деревня} осталась далеко на востоке. Подо мной проносятся острые {#mountaintops|вершины} и каменистые {#mountainslopes|склоны}, усеянные валунами, а вдалеке на западе я вижу огромный {#crater|кратер}. Лучи яркого летнего {sun|солнца}, проникающие сквозь тонкие перистые {clouds|облака}, падают на мою чешую, согревая ее. ]]; + way = { + path {"#east", 'На восток, к деревне', 'above_village'}; + path {"#west", 'На запад, к кратеру', 'above_crater'}:disable(); + } }: with { - obj { - nam = '#village'; - act = 'Отсюда я все еще могу разглядеть важнейшие здания деревни: ратушу, трактир и библиотеку. Из трубы трактира поднимается едва заметный дымок, а на крыльце его сидит девушка. '; - }; - obj { - nam = '#mountains'; - act = 'Отсюда я могу рассмотреть горные пики внизу. Немногие из них достаточно высоки, чтобы коснуться облаков, лишь часть из них покрыта блестящим на солнце снегом. Большинство представляет собой не более чем голые камни, за которые тут и там отчаянно пытаются цепляться немногочисленные молодые ели. '; - }; - obj { - nam = '#mountaintops'; - act = 'Вершины гор нацелены вверх, словно наконечники копий. Большая часть их -- не более чем серые камни, лишенные растительность, но самые высокие покрыты ослепительно-белым снегом, сверкающим в ярких лучах летнего солнца. '; - }; - obj { - nam = '#mountainslopes'; - act = 'Крутые склоны и отвесные скалы кажутся практически безжизненными. Лишь немногие деревья осмеливаются пустить свои корни на этих каменных громадах, устремившихся в небеса. '; - }; - obj { - nam = '#crater'; - act = function(s) - _'#west':enable(); - return 'Громадный кратер, километров десять в диаметре. Судя по растущему внутри редкому леску, образовался он достаточно давно. В самом его центре я вижу черную башню. '; - end; - }; - 'clouds'; - 'sun'; + obj { + nam = '#village'; + act = 'Отсюда я все еще могу разглядеть важнейшие здания деревни: ратушу, трактир и библиотеку. Из трубы трактира поднимается едва заметный дымок, а на крыльце его сидит девушка. '; + }; + obj { + nam = '#mountains'; + act = 'Отсюда я могу рассмотреть горные пики внизу. Немногие из них достаточно высоки, чтобы коснуться облаков, лишь часть из них покрыта блестящим на солнце снегом. Большинство представляет собой не более чем голые камни, за которые тут и там отчаянно пытаются цепляться немногочисленные молодые ели. '; + }; + obj { + nam = '#mountaintops'; + act = 'Вершины гор нацелены вверх, словно наконечники копий. Большая часть их -- не более чем серые камни, лишенные растительность, но самые высокие покрыты ослепительно-белым снегом, сверкающим в ярких лучах летнего солнца. '; + }; + obj { + nam = '#mountainslopes'; + act = 'Крутые склоны и отвесные скалы кажутся практически безжизненными. Лишь немногие деревья осмеливаются пустить свои корни на этих каменных громадах, устремившихся в небеса. '; + }; + obj { + nam = '#crater'; + act = function(s) + _'#west':enable(); + return 'Громадный кратер, километров десять в диаметре. Судя по растущему внутри редкому леску, образовался он достаточно давно. В самом его центре я вижу черную башню. '; + end; + }; + 'clouds'; + 'sun'; } room { - nam = 'above_crater'; - pic = 'images/above_crater.png'; - theme = 'main'; - onenter = function(s) - if here()^'inside_crater_glade' then - p [[Я взмываю в небо, уже на лету заканчивая превращение. Мои могучие крылья поднимают меня над землей. ]]; - end; - end; - disp = 'Над кратером'; - decor = [[Я пролетаю над огромным {#crater|кратером}, затерянным среди гор. В центре кратера возвышается {#tower|башня}, но я не смогу там приземлиться из-за {#trees|деревьев}. Я замечаю небольшую {#glade|полянку} всего в нескольких сотнях метров от башни. ]]; - way = { - path {"#east", 'На восток', 'above_west'}; - path {"#down", 'Приземлиться', 'inside_crater_glade'}:disable(); - } + nam = 'above_crater'; + pic = 'images/above_crater.png'; + theme = 'main'; + onenter = function(s) + if here()^'inside_crater_glade' then + p [[Я взмываю в небо, уже на лету заканчивая превращение. Мои могучие крылья поднимают меня над землей. ]]; + end; + end; + disp = 'Над кратером'; + decor = [[Я пролетаю над огромным {#crater|кратером}, затерянным среди гор. В центре кратера возвышается {#tower|башня}, но я не смогу там приземлиться из-за {#trees|деревьев}. Я замечаю небольшую {#glade|полянку} всего в нескольких сотнях метров от башни. ]]; + way = { + path {"#east", 'На восток', 'above_west'}; + path {"#down", 'Приземлиться', 'inside_crater_glade'}:disable(); + } }: with { - obj { - nam = '#crater'; - act = 'Когда-то в незапамятные времена здесь упал довольно крупный метеорит. За прошедшее время кратер успел зарости лесом, но планета все еще не загладила этот ужасный шрам на своей поверхности. '; - }; - obj { - nam = '#tower'; - act = 'Башня из черного камня возвышается над лесом, располагаясь в самом центре исполинского кратера. Основание ее представляет собой правильный шестиугольник. Она стоит строго вертикально, окруженная со всех сторон лесом, словно не замечающим ее присутствия. '; - }; - obj { - nam = '#trees'; - act = 'Деревья растут достаточно редко, чтобы позволить солнечным лучам достигать земли, однако приземлиться среди них все еще проблематично. '; - }; - obj { - nam = '#glade'; - act = function(s) - _'#down':enable(); - return 'Небольшая полянка совсем недалеко от башни. Eсли я приземлюсь здесь и превращусь, то без труда доберусь до башни. '; - end; - }; - 'wind'; - 'sun'; - 'clouds'; + obj { + nam = '#crater'; + act = 'Когда-то в незапамятные времена здесь упал довольно крупный метеорит. За прошедшее время кратер успел зарости лесом, но планета все еще не загладила этот ужасный шрам на своей поверхности. '; + }; + obj { + nam = '#tower'; + act = 'Башня из черного камня возвышается над лесом, располагаясь в самом центре исполинского кратера. Основание ее представляет собой правильный шестиугольник. Она стоит строго вертикально, окруженная со всех сторон лесом, словно не замечающим ее присутствия. '; + }; + obj { + nam = '#trees'; + act = 'Деревья растут достаточно редко, чтобы позволить солнечным лучам достигать земли, однако приземлиться среди них все еще проблематично. '; + }; + obj { + nam = '#glade'; + act = function(s) + _'#down':enable(); + return 'Небольшая полянка совсем недалеко от башни. Eсли я приземлюсь здесь и превращусь, то без труда доберусь до башни. '; + end; + }; + 'wind'; + 'sun'; + 'clouds'; } room { - nam = 'village_no_way'; - onenter = function(s) - if solarscale_with_me then - p [[Местным жителям не очень понравится, если посреди их деревни вдруг приземлятся два дракона. ]]; - else - p [[Местным жителям не очень понравится, если посреди их деревни вдруг приземлится дракон. ]]; - end; - return false; - end; + nam = 'village_no_way'; + onenter = function(s) + if solarscale_with_me then + p [[Местным жителям не очень понравится, если посреди их деревни вдруг приземлятся два дракона. ]]; + else + p [[Местным жителям не очень понравится, если посреди их деревни вдруг приземлится дракон. ]]; + end; + return false; + end; } room { - nam = 'near_village'; - disp = 'К югу от деревни'; - pic = 'images/near_village.png'; - theme = 'main'; - onenter = function(s) - if here()^'above_near_village' then - p [[Я мягко опускаюсь на землю. Едва мои ноги касаются земли, я начинаю превращаться. Тело мое расплывается туманом, который вскоре собирается в облике обычного человека. Горящие ярким огнем глаза я предусмотрительно скрываю за темными очками. ]]; - end; - end; - decor = [[Я стою на старой асфальтовой {#road|дороге} где-то посреди древнего {#forest|леса}. В нескольких километрах к северу от меня находится небольшая {#village|деревушка}. Яркое летнее {sun_transformed|солнце} пробивается сквозь проплывающие высоко в небе {clouds|облака}. ]]; - way = { - path {"#up", 'Взлететь', 'above_near_village'}; - path {"#north", 'На север, в деревню', 'village_south'}; - } + nam = 'near_village'; + disp = 'К югу от деревни'; + pic = 'images/near_village.png'; + theme = 'main'; + onenter = function(s) + if here()^'above_near_village' then + p [[Я мягко опускаюсь на землю. Едва мои ноги касаются земли, я начинаю превращаться. Тело мое расплывается туманом, который вскоре собирается в облике обычного человека. Горящие ярким огнем глаза я предусмотрительно скрываю за темными очками. ]]; + end; + end; + decor = [[Я стою на старой асфальтовой {#road|дороге} где-то посреди древнего {#forest|леса}. В нескольких километрах к северу от меня находится небольшая {#village|деревушка}. Яркое летнее {sun_transformed|солнце} пробивается сквозь проплывающие высоко в небе {clouds|облака}. ]]; + way = { + path {"#up", 'Взлететь', 'above_near_village'}; + path {"#north", 'На север, в деревню', 'village_south'}; + } }: with { - obj { - nam = '#road'; - act = 'Серый неровный асфальт всеми забытой дороги иссечен многочисленными трещинами. '; - }; - obj { - nam = '#forest'; - act = 'Легкий ветерок качает вершины стоящих по сторонам дороги деревьев, разнося насыщенный аромат хвойного леса. '; - }; - obj { - nam = '#village'; - act = function(s) - pr 'Ухоженные бревенчатые домики местных жителей утопают в зелени. Отсюда я вижу стоящие в центре деревни крупные здания ратуши и трактира. '; - if not village_visited then - village_visited = true; - pr [[Деревня определенно не заброшена. ]]; - end; - end; - }; - 'sun_transformed'; - 'clouds'; + obj { + nam = '#road'; + act = 'Серый неровный асфальт всеми забытой дороги иссечен многочисленными трещинами. '; + }; + obj { + nam = '#forest'; + act = 'Легкий ветерок качает вершины стоящих по сторонам дороги деревьев, разнося насыщенный аромат хвойного леса. '; + }; + obj { + nam = '#village'; + act = function(s) + pr 'Ухоженные бревенчатые домики местных жителей утопают в зелени. Отсюда я вижу стоящие в центре деревни крупные здания ратуши и трактира. '; + if not village_visited then + village_visited = true; + pr [[Деревня определенно не заброшена. ]]; + end; + end; + }; + 'sun_transformed'; + 'clouds'; } room { - nam = 'village_south'; - disp = 'Деревня, юг'; - pic='images/village_south.png'; - theme = 'main'; - enter = function(s) - if not village_visited then - village_visited = true; - pr [[Эта деревня определенно не заброшена. ]]; - end; - end; - nofollow = function(s) - if here():from()^'near_village' then - return 'Соларскейл отказывается следовать за мной и со словами: "Я не могу изменять форму, и не думаю, что местные жители будут рады меня видеть. Я подожду вас здесь", -- усаживается на траву неподалеку. '; - else - return true; - end; - end; - decor = [[Я стою на {#road|дороге} в южной части {#village|деревни}. Чуть поодаль расположилась {#foresters_hut_out|избушка} лесника. У входа припаркован старый {#foresters_car|пикап}. Лучи {sun_transformed|солнца}, пробивающиеся сквозь тонкие {clouds|облака}, заливают все вокруг золотистым светом. ]]; - way = { - path {'#south', 'На юг, в лес', 'near_village'}; - path {'#in', 'В дом лесника', 'foresters_hut'}; - path {'#north', 'На север, к ратуше', 'village_center'}; - }; + nam = 'village_south'; + disp = 'Деревня, юг'; + pic='images/village_south.png'; + theme = 'main'; + enter = function(s) + if not village_visited then + village_visited = true; + pr [[Эта деревня определенно не заброшена. ]]; + end; + end; + nofollow = function(s) + if here():from()^'near_village' then + return 'Соларскейл отказывается следовать за мной и со словами: "Я не могу изменять форму, и не думаю, что местные жители будут рады меня видеть. Я подожду вас здесь", -- усаживается на траву неподалеку. '; + else + return true; + end; + end; + decor = [[Я стою на {#road|дороге} в южной части {#village|деревни}. Чуть поодаль расположилась {#foresters_hut_out|избушка} лесника. У входа припаркован старый {#foresters_car|пикап}. Лучи {sun_transformed|солнца}, пробивающиеся сквозь тонкие {clouds|облака}, заливают все вокруг золотистым светом. ]]; + way = { + path {'#south', 'На юг, в лес', 'near_village'}; + path {'#in', 'В дом лесника', 'foresters_hut'}; + path {'#north', 'На север, к ратуше', 'village_center'}; + }; }:with { - obj { - nam = '#road'; - act = 'Мне, привыкшему к ровному полу в моей пещере, очень непривычно идти по старому полуразрушенному асфальту. Тут и там сквозь трещины в нем пробиваются тонкие стебельки молодой травы. ' - }; - obj { - nam = '#village'; - act = 'Аккуратные деревянные домики местных жителей утопают в зелени. Отсюда я вижу расположенные в центре деревни здания ратуши и трактира. Из трубы последнего поднимается тонкая струйка дыма. '; - }; - obj { - nam = '#foresters_car'; - act = 'Этому автомобилю, должно быть, не менее десяти лет -- модель очень старая, кузов местами подкрашен, кое-где видны небольшие вмятины. Однако, на машине нет и следа ржавчины, зеркала и фары в полном порядке, лобовое стекло сияет чистотой. '; - }; - obj { - nam = '#foresters_hut_out'; - act = 'Крепкая деревянная изба, почерневшая от старости и слегка покосившаяся, но все еще достаточно прочная. При должном уходе, она простоит еще не один десяток лет. '; - }; - 'sun_transformed'; - 'clouds'; + obj { + nam = '#road'; + act = 'Мне, привыкшему к ровному полу в моей пещере, очень непривычно идти по старому полуразрушенному асфальту. Тут и там сквозь трещины в нем пробиваются тонкие стебельки молодой травы. ' + }; + obj { + nam = '#village'; + act = 'Аккуратные деревянные домики местных жителей утопают в зелени. Отсюда я вижу расположенные в центре деревни здания ратуши и трактира. Из трубы последнего поднимается тонкая струйка дыма. '; + }; + obj { + nam = '#foresters_car'; + act = 'Этому автомобилю, должно быть, не менее десяти лет -- модель очень старая, кузов местами подкрашен, кое-где видны небольшие вмятины. Однако, на машине нет и следа ржавчины, зеркала и фары в полном порядке, лобовое стекло сияет чистотой. '; + }; + obj { + nam = '#foresters_hut_out'; + act = 'Крепкая деревянная изба, почерневшая от старости и слегка покосившаяся, но все еще достаточно прочная. При должном уходе, она простоит еще не один десяток лет. '; + }; + 'sun_transformed'; + 'clouds'; } room { - state = 0; - nam = 'foresters_hut'; - pic = function(s) - if _'rope':where() == here() then - return 'images/foresters_hut.png;images/foresters_hut_rope.png@8,160'; - else - return 'images/foresters_hut.png'; - end; - end; - theme = 'main'; - nofollow = true; - disp = 'Дом лесника'; - enter = function(s) - if s.state == 0 then - s.state = 1; - return 'Войдя в неосвещенное помещение, я с трудом сдерживаюсь, чтобы не снять очки и не выдать себя. Привыкнув к темноте, я осматриваюсь. '; - end; - end; - decor = [[Несмотря на яркий солнечный день, внутри избушки лесника царит полумрак. Напротив входа расположен большой мягкий {#sofa|диван}. В углу разместился большой крепкий {#cupboard|шкаф}, а у окна стоит {#table|стол}, застеленный клеенкой, с несколькими {#chairs|стульями} вокруг. На столе стоит {#radio|радиоприемник}.]]; - way = { - path {'#out', 'На улицу', 'village_south'}; - } + state = 0; + nam = 'foresters_hut'; + pic = function(s) + if _'rope':where() == here() then + return 'images/foresters_hut.png;images/foresters_hut_rope.png@8,160'; + else + return 'images/foresters_hut.png'; + end; + end; + theme = 'main'; + nofollow = true; + disp = 'Дом лесника'; + enter = function(s) + if s.state == 0 then + s.state = 1; + return 'Войдя в неосвещенное помещение, я с трудом сдерживаюсь, чтобы не снять очки и не выдать себя. Привыкнув к темноте, я осматриваюсь. '; + end; + end; + decor = [[Несмотря на яркий солнечный день, внутри избушки лесника царит полумрак. Напротив входа расположен большой мягкий {#sofa|диван}. В углу разместился большой крепкий {#cupboard|шкаф}, а у окна стоит {#table|стол}, застеленный клеенкой, с несколькими {#chairs|стульями} вокруг. На столе стоит {#radio|радиоприемник}.]]; + way = { + path {'#out', 'На улицу', 'village_south'}; + } }:with { - obj { - nam = '#sofa'; - act = 'Старинный диван с выцветшей и потертой обивкой все еще манит домашним уютом. '; - }; - obj { - nam = '#cupboard'; - act = 'Должно быть, этому шкафу не один десяток лет. Бронзовые ручки покрыты патиной, а на рассохшейся дверце я замечаю несколько глубоких трещин. '; - }; - obj { - nam = '#table'; - act = 'Массивный дубовый стол застелен старой выцветшей клеенкой с узором из цветочков и каких-то завитков. '; - }; - obj { - nam = '#chairs'; - act = 'Старые деревянные стулья, очевидно, сделанные местным мастером. Простые, но устойчивые и прочные. Такие прослужат не одно десятилетие. '; - }; - obj { - nam = '#radio'; - act = [[Старинный радиоприемник. Такие перестали выпускать лет двадцать назад. Судя по всему, он все еще прекрасно работает. Лампочка питания горит, однако громкость выкручена в минимум. ]]; - }; - obj { - bought = false; - nam = 'forester'; - dsc = 'На диване сидит {лесник}, глядя на меня. '; - act = function(s) - walkin('forester_dlg'); - end; - used = function(s, o) - if o^'raspberry_pie' then - return 'Я не могу просто всучить ему пирог. Надо подойти и поговорить. '; - else - return 'Не думаю, что ему это интересно. '; - end; - end; - }; - obj { - nam = 'rope'; - disp = 'Веревка'; - dsc = 'На шкафу лежит {моток веревки}. '; - act = function(s) - if _('forester').bought then - p 'Я забираю веревку. ' - take('rope') - else - p 'Хозяин будет недоволен, если я возьму это без разрешения. '; - end; - end; - inv = [[Моток крепкой веревки. ]]; - }; + obj { + nam = '#sofa'; + act = 'Старинный диван с выцветшей и потертой обивкой все еще манит домашним уютом. '; + }; + obj { + nam = '#cupboard'; + act = 'Должно быть, этому шкафу не один десяток лет. Бронзовые ручки покрыты патиной, а на рассохшейся дверце я замечаю несколько глубоких трещин. '; + }; + obj { + nam = '#table'; + act = 'Массивный дубовый стол застелен старой выцветшей клеенкой с узором из цветочков и каких-то завитков. '; + }; + obj { + nam = '#chairs'; + act = 'Старые деревянные стулья, очевидно, сделанные местным мастером. Простые, но устойчивые и прочные. Такие прослужат не одно десятилетие. '; + }; + obj { + nam = '#radio'; + act = [[Старинный радиоприемник. Такие перестали выпускать лет двадцать назад. Судя по всему, он все еще прекрасно работает. Лампочка питания горит, однако громкость выкручена в минимум. ]]; + }; + obj { + bought = false; + nam = 'forester'; + dsc = 'На диване сидит {лесник}, глядя на меня. '; + act = function(s) + walkin('forester_dlg'); + end; + used = function(s, o) + if o^'raspberry_pie' then + return 'Я не могу просто всучить ему пирог. Надо подойти и поговорить. '; + else + return 'Не думаю, что ему это интересно. '; + end; + end; + }; + obj { + nam = 'rope'; + disp = 'Веревка'; + dsc = 'На шкафу лежит {моток веревки}. '; + act = function(s) + if _('forester').bought then + p 'Я забираю веревку. ' + take('rope') + else + p 'Хозяин будет недоволен, если я возьму это без разрешения. '; + end; + end; + inv = [[Моток крепкой веревки. ]]; + }; } dlg { - nam = 'forester_dlg'; - disp = 'Лесник'; - theme = 'main'; - pic = 'images/characters/forester.png'; - enter = [[Бородатый, косматый мужчина неопределенного возраста сидит на диване, пронзительно глядя мне в глаза. Одет он в брезентовые куртку и штаны и, кажется, не испытывает никаких проблем по поводу жары. ]]; - phr = { - {'Добрый день. Я впервые в вашей деревне. ', 'Лесник резко меняет выражение лица -- в глазах сверкает веселая искорка и кажется, что под бородой скрывается искренняя улыбка: "Добро пожаловать, мы всегда рады гостям!"', - {'Вы знаете какие-нибудь местные достопримечательности?', 'Лесник не задумываясь отвечает: "Говорят, такого собрания книг, как в нашей библиотеке, больше нигде нет". '}; - }, - {cond=function(s) return where('rope')^'foresters_hut' and not _('forester').bought end, 'Могу я взять у вас веревку?', function(s) - p 'Лесник задумчиво чешет бороду. Потом предлагает: "Мы с трактирщиком на днях повздорили, теперь он отказывается продавать мне что-либо кроме хлеба и воды. С удовольствием обменяю моток веревки на кусок малинового пирога". ' - raspberry_pie_status = 1; - end}, - {cond=function(s) return have 'raspberry_pie' end, '[Дать леснику малиновый пирог] Я принес пирог. Могу я взять веревку?', function(s) - remove('raspberry_pie', pl); - p 'Лесник берет у вас пирог и, откусив от него немного, произносит: "Забирайте".' - raspberry_pie_status = 2; - _('forester').bought = 1; - end}, - {true, 'До свидания.', function(s) - p 'Лесник прощается со мной: "Увидимся". ' - walkout(); - end} - } + nam = 'forester_dlg'; + disp = 'Лесник'; + theme = 'main'; + pic = 'images/characters/forester.png'; + enter = [[Бородатый, косматый мужчина неопределенного возраста сидит на диване, пронзительно глядя мне в глаза. Одет он в брезентовые куртку и штаны и, кажется, не испытывает никаких проблем по поводу жары. ]]; + phr = { + {'Добрый день. Я впервые в вашей деревне. ', 'Лесник резко меняет выражение лица -- в глазах сверкает веселая искорка и кажется, что под бородой скрывается искренняя улыбка: "Добро пожаловать, мы всегда рады гостям!"', + {'Вы знаете какие-нибудь местные достопримечательности?', 'Лесник не задумываясь отвечает: "Говорят, такого собрания книг, как в нашей библиотеке, больше нигде нет". '}; + }, + {cond=function(s) return where('rope')^'foresters_hut' and not _('forester').bought end, 'Могу я взять у вас веревку?', function(s) + p 'Лесник задумчиво чешет бороду. Потом предлагает: "Мы с трактирщиком на днях повздорили, теперь он отказывается продавать мне что-либо кроме хлеба и воды. С удовольствием обменяю моток веревки на кусок малинового пирога". ' + raspberry_pie_status = 1; + end}, + {cond=function(s) return have 'raspberry_pie' end, '[Дать леснику малиновый пирог] Я принес пирог. Могу я взять веревку?', function(s) + remove('raspberry_pie', pl); + p 'Лесник берет у вас пирог и, откусив от него немного, произносит: "Забирайте".' + raspberry_pie_status = 2; + _('forester').bought = 1; + end}, + {true, 'До свидания.', function(s) + p 'Лесник прощается со мной: "Увидимся". ' + walkout(); + end} + } } room { - nam = 'village_center'; - nofollow = true; - pic = 'images/village_center.png'; - theme = 'main'; - disp = 'Деревня, центр'; - decor = [[Я стою на небольшой площади перед деревенской {#townhall|ратушей}. В другом конце площади стоит {#tavern|трактир}. На севере я замечаю какое-то большое одноэтажное {#library|здание}. Сквозь тонкие перистые {clouds|облака} пробиваются яркие лучи летнего {sun_transformed|солнца}. ]]; - way = { - path {'На юг, к дому лесника', 'village_south'}; - path {'#down', 'В колодец', 'inside_well'}:disable(); - path {'В ратушу', 'townhall'}; - path {'В трактир', 'tavern'}; - path {'На север, к библиотеке', 'village_north'}; - }; + nam = 'village_center'; + nofollow = true; + pic = 'images/village_center.png'; + theme = 'main'; + disp = 'Деревня, центр'; + decor = [[Я стою на небольшой площади перед деревенской {#townhall|ратушей}. В другом конце площади стоит {#tavern|трактир}. На севере я замечаю какое-то большое одноэтажное {#library|здание}. Сквозь тонкие перистые {clouds|облака} пробиваются яркие лучи летнего {sun_transformed|солнца}. ]]; + way = { + path {'На юг, к дому лесника', 'village_south'}; + path {'#down', 'В колодец', 'inside_well'}:disable(); + path {'В ратушу', 'townhall'}; + path {'В трактир', 'tavern'}; + path {'На север, к библиотеке', 'village_north'}; + }; }: with { - obj { - nam = '#townhall'; - act = 'Двухэтажное здание ратуши -- одно из самых крупных и старых в деревне. Большую часть фасада занимают огромные, высотой в оба этажа, окна. Изнутри здания доносится {#music|музыка}. '; - }; - obj { - nam = '#music'; - act = 'Я останавливаюсь, чтобы прислушаться к доносящейся из ратуши музыке. Незнакомая мелодия звучит очень приятно. '; - }; - obj { - nam = '#tavern'; - act = 'Трактир не уступает ратуше ни возрастом, ни солидностью. Из трубы здания поднимается едва заметный дымок. '; - }; - obj { - nam = '#library'; - act = 'Отсюда я могу разглядеть вывеску библиотеки на здании. '; + obj { + nam = '#townhall'; + act = 'Двухэтажное здание ратуши -- одно из самых крупных и старых в деревне. Большую часть фасада занимают огромные, высотой в оба этажа, окна. Изнутри здания доносится {#music|музыка}. '; + }; + obj { + nam = '#music'; + act = 'Я останавливаюсь, чтобы прислушаться к доносящейся из ратуши музыке. Незнакомая мелодия звучит очень приятно. '; + }; + obj { + nam = '#tavern'; + act = 'Трактир не уступает ратуше ни возрастом, ни солидностью. Из трубы здания поднимается едва заметный дымок. '; + }; + obj { + nam = '#library'; + act = 'Отсюда я могу разглядеть вывеску библиотеки на здании. '; - }; - obj { - known = false; - nam = 'village_well'; - dsc = function(s) - if _('inside_well').state then - return 'В центре площади расположен {колодец}. Вокруг одного из выступающих камней закреплена веревка, уходящая в него. '; - else - return 'В центре площади расположен {колодец}. '; - end; - end; - act = function(s) - if s.known then - _'#down':enable(); - p [[При виде колодца, мне в голову приходят слова "ключ там, где вода", выгравированные на кольце. Пусть воды здесь уже давно нет, это лишь облегчает задачу. ]]; - else - p [[Старый высохший колодец. ]]; - end; - end; - used = function(s, o) - if s.known and o^'rope' then - _('inside_well').state = true; - remove('rope', pl); - p 'Я привязываю веревку к выступающему камню. По ней я смогу выбраться из колодца. '; - else - return false; - end; - end; - }; - obj { - nam = 'maid'; - dsc = function(s) - if _('maid_dlg').flower then - return 'На крыльце трактира сидит молодая {девушка}. В руке она держит красивый цветок с небесно-голубыми лепестками. '; - else - return 'На крыльце трактира сидит молодая {девушка}. '; - end; - end; - act = function(s) - if _('maid_dlg').flower and (raspberry_pie_status == 0 or raspberry_pie_status == 2) then - return [[Длинные каштановые волосы ниспадают на плечи девушки, карие глаза смотрят куда-то вдаль. Уголки рта приподняты в легкой улыбке. Она одета в простое голубое платье. Мне больше ничего от нее не нужно. ]]; - else - walkin('maid_dlg'); - end; - end; - used = function(s, o) - if o^'flower' then - return 'Лучше сначала подойти и поговорить. '; - else - return 'Вряд ли ей это будет интересно. '; - end; - end; - }; - 'sun_transformed'; - 'clouds'; + }; + obj { + known = false; + nam = 'village_well'; + dsc = function(s) + if _('inside_well').state then + return 'В центре площади расположен {колодец}. Вокруг одного из выступающих камней закреплена веревка, уходящая в него. '; + else + return 'В центре площади расположен {колодец}. '; + end; + end; + act = function(s) + if s.known then + _'#down':enable(); + p [[При виде колодца, мне в голову приходят слова "ключ там, где вода", выгравированные на кольце. Пусть воды здесь уже давно нет, это лишь облегчает задачу. ]]; + else + p [[Старый высохший колодец. ]]; + end; + end; + used = function(s, o) + if s.known and o^'rope' then + _('inside_well').state = true; + remove('rope', pl); + p 'Я привязываю веревку к выступающему камню. По ней я смогу выбраться из колодца. '; + else + return false; + end; + end; + }; + obj { + nam = 'maid'; + dsc = function(s) + if _('maid_dlg').flower then + return 'На крыльце трактира сидит молодая {девушка}. В руке она держит красивый цветок с небесно-голубыми лепестками. '; + else + return 'На крыльце трактира сидит молодая {девушка}. '; + end; + end; + act = function(s) + if _('maid_dlg').flower and (raspberry_pie_status == 0 or raspberry_pie_status == 2) then + return [[Длинные каштановые волосы ниспадают на плечи девушки, карие глаза смотрят куда-то вдаль. Уголки рта приподняты в легкой улыбке. Она одета в простое голубое платье. Мне больше ничего от нее не нужно. ]]; + else + walkin('maid_dlg'); + end; + end; + used = function(s, o) + if o^'flower' then + return 'Лучше сначала подойти и поговорить. '; + else + return 'Вряд ли ей это будет интересно. '; + end; + end; + }; + 'sun_transformed'; + 'clouds'; } dlg { - nam = 'maid_dlg'; - disp = 'Девушка'; - theme = 'main'; - pic = function(s) - if s.flower then - return 'images/characters/maid_glad.png'; - else - return 'images/characters/maid_sad.png'; - end; - end; - flower = false; - pie = false; - work_asked = false; - pie_asked = false; - enter = function(s) - if _('maid_dlg').flower then - return [[Молодая девушка сидит на крыльце трактира. Ее длинные каштановые волосы ниспадают на плечи, карие глаза смотрят куда-то вдаль. Уголки рта приподняты в легкой улыбке. Она одета в простое голубое платье. Когда я подхожу, она поднимает свой взгляд и тепло улыбается мне. В руке она держит красивый цветок с небесно-голубыми лепестками. ]]; - else - return [[Молодая девушка сидит на крыльце трактира. Ее длинные каштановые волосы ниспадают на плечи, карие глаза смотрят куда-то вдаль. Уголки рта приподняты в легкой улыбке. Она одета в простое голубое платье. Когда я подхожу, она поднимает свой взгляд и приветливо, но немного грустно, улыбается. Ее тонкие бледные руки лежат на подоле платья почти не двигаясь. ]]; - end; - end; - phr = { - {cond=function(s) return not _('maid_dlg').flower end, "Добрый день. Я впервые в вашей деревне. ", 'Девушка поднимает глаза и смущенно отвечает: "Простите, я вас не заметила. Помогу, чем смогу". ', - {'Вы знаете какие-нибудь местные достопримечательности?', 'Вопрос ставит девушку в тупик. Она краснеет и молчит, не зная, что ответить. Через некоторое время она спрашивает: "Здесь хорошо, не правда ли?"', - {'Да, мне здесь нравится. ', 'Девушка продолжает: "В нашем лесу растут очень красивые цветы. Раньше мы ходили с лесником и я собирала букет для себя, но в этом году у меня почти нет времени -- надо помогать отцу в трактире". Она грустно вздыхает. ', only=true, - { - cond=function(s) return have 'flower' end, - '[Дать девушке цветок] Вот, возьмите. ', - function(s) - _('maid_dlg').flower = 1; - remove('flower', pl); - p 'Девушка засияла. Тепло улыбнувшись вам, она произносит: "Спасибо!"' - end - }; - { - '[Промолчать]', - 'Девушка спрашивает: "Так что вы хотели?"' - } - }; - }; - }; - {cond=function(s) return not _('maid_dlg').work_asked end, 'Вы работаете в трактире?', function(s) - _('maid_dlg').work_asked = true; - return 'Девушка молча кивает. ' - end}; - { - cond=function(s) return _('maid_dlg').pie_asked and have 'flower' end, - '[Дать девушке цветок] Вот, возьмите. ', - function(s) - _('maid_dlg').flower = 1; - remove('flower', pl); - raspberry_pie_status = 2; - take 'raspberry_pie' - p 'Девушка соскакивает с места и со словами "Сейчас вернусь!" убегает в трактир. Через несколько минут она возвращается с куском восхитительно пахнущего малинового пирога.' - end - }; - { - cond=function(s) return _('maid_dlg').work_asked and not _('maid_dlg').pie_asked and _('maid_dlg').flower and raspberry_pie_status == 1; end; - 'Вы можете принести мне кусок малинового пирога?', - function(s) - raspberry_pie_status = 2; - take 'raspberry_pie' - p 'Девушка соскакивает с места и со словами "Сейчас вернусь!" убегает в трактир. Через несколько минут она возвращается с куском восхитительно пахнущего малинового пирога.' - end; - }; - { - cond=function(s) return _('maid_dlg').work_asked and not _('maid_dlg').pie_asked and not _('maid_dlg').flower and raspberry_pie_status == 1; end; - 'Вы можете принести мне кусок малинового пирога?', - 'Девушка смеется: "Наш пирог настолько знаменит, что люди приезжают из дальних краев, чтобы попробовать его! Почему бы вам не попросить у моего отца?"', only=true, - { - 'У меня нет с собой денег. ', function(s) - _('maid_dlg').pie_asked = 1; - p 'Девушка удивленно спрашивает: "Как же вы сюда добрались тогда?"^Немного подумав, она предлагает: "Знаете, я поделюсь с вами пирогом, если вы выполните небольшую мою прихоть. Многого не прошу, просто... -- она делает неловкую паузу, -- принесите мне цветок из нашего леса. Обычно мы ходим с лесником и я набираю их себе вдоволь, но в этот раз он слишком занят. Что скажете?"' - end, only=true, - { - cond=function(s) return have 'flower' end, - '[Дать девушке цветок] Вот, возьмите. ', - function(s) - _('maid_dlg').flower = 1; - remove('flower', pl); - raspberry_pie_status = 2; - take 'raspberry_pie' - p 'Девушка соскакивает с места и со словами "Сейчас вернусь!" убегает в трактир. Через несколько минут она возвращается с куском восхитительно пахнущего малинового пирога.' - end - }; - {"Согласен. ", 'Девушка улыбается: "Договорились". '}; - {"Мне надо подумать. ", 'Девушка пожимает плечами: "Как хотите. Пирог и вправду очень вкусный". '}; - }, - { - 'Хорошо, я попрошу у него. ', 'Девушка молча смотрит на меня. ' - } - }; - { - 'Я пойду. ', function(s) - p 'Девушка кивает, слегка улыбнувшись. ' - walkout(); - end - } - } + nam = 'maid_dlg'; + disp = 'Девушка'; + theme = 'main'; + pic = function(s) + if s.flower then + return 'images/characters/maid_glad.png'; + else + return 'images/characters/maid_sad.png'; + end; + end; + flower = false; + pie = false; + work_asked = false; + pie_asked = false; + enter = function(s) + if _('maid_dlg').flower then + return [[Молодая девушка сидит на крыльце трактира. Ее длинные каштановые волосы ниспадают на плечи, карие глаза смотрят куда-то вдаль. Уголки рта приподняты в легкой улыбке. Она одета в простое голубое платье. Когда я подхожу, она поднимает свой взгляд и тепло улыбается мне. В руке она держит красивый цветок с небесно-голубыми лепестками. ]]; + else + return [[Молодая девушка сидит на крыльце трактира. Ее длинные каштановые волосы ниспадают на плечи, карие глаза смотрят куда-то вдаль. Уголки рта приподняты в легкой улыбке. Она одета в простое голубое платье. Когда я подхожу, она поднимает свой взгляд и приветливо, но немного грустно, улыбается. Ее тонкие бледные руки лежат на подоле платья почти не двигаясь. ]]; + end; + end; + phr = { + {cond=function(s) return not _('maid_dlg').flower end, "Добрый день. Я впервые в вашей деревне. ", 'Девушка поднимает глаза и смущенно отвечает: "Простите, я вас не заметила. Помогу, чем смогу". ', + {'Вы знаете какие-нибудь местные достопримечательности?', 'Вопрос ставит девушку в тупик. Она краснеет и молчит, не зная, что ответить. Через некоторое время она спрашивает: "Здесь хорошо, не правда ли?"', + {'Да, мне здесь нравится. ', 'Девушка продолжает: "В нашем лесу растут очень красивые цветы. Раньше мы ходили с лесником и я собирала букет для себя, но в этом году у меня почти нет времени -- надо помогать отцу в трактире". Она грустно вздыхает. ', only=true, + { + cond=function(s) return have 'flower' end, + '[Дать девушке цветок] Вот, возьмите. ', + function(s) + _('maid_dlg').flower = 1; + remove('flower', pl); + p 'Девушка засияла. Тепло улыбнувшись вам, она произносит: "Спасибо!"' + end + }; + { + '[Промолчать]', + 'Девушка спрашивает: "Так что вы хотели?"' + } + }; + }; + }; + {cond=function(s) return not _('maid_dlg').work_asked end, 'Вы работаете в трактире?', function(s) + _('maid_dlg').work_asked = true; + return 'Девушка молча кивает. ' + end}; + { + cond=function(s) return _('maid_dlg').pie_asked and have 'flower' end, + '[Дать девушке цветок] Вот, возьмите. ', + function(s) + _('maid_dlg').flower = 1; + remove('flower', pl); + raspberry_pie_status = 2; + take 'raspberry_pie' + p 'Девушка соскакивает с места и со словами "Сейчас вернусь!" убегает в трактир. Через несколько минут она возвращается с куском восхитительно пахнущего малинового пирога.' + end + }; + { + cond=function(s) return _('maid_dlg').work_asked and not _('maid_dlg').pie_asked and _('maid_dlg').flower and raspberry_pie_status == 1; end; + 'Вы можете принести мне кусок малинового пирога?', + function(s) + raspberry_pie_status = 2; + take 'raspberry_pie' + p 'Девушка соскакивает с места и со словами "Сейчас вернусь!" убегает в трактир. Через несколько минут она возвращается с куском восхитительно пахнущего малинового пирога.' + end; + }; + { + cond=function(s) return _('maid_dlg').work_asked and not _('maid_dlg').pie_asked and not _('maid_dlg').flower and raspberry_pie_status == 1; end; + 'Вы можете принести мне кусок малинового пирога?', + 'Девушка смеется: "Наш пирог настолько знаменит, что люди приезжают из дальних краев, чтобы попробовать его! Почему бы вам не попросить у моего отца?"', only=true, + { + 'У меня нет с собой денег. ', function(s) + _('maid_dlg').pie_asked = 1; + p 'Девушка удивленно спрашивает: "Как же вы сюда добрались тогда?"^Немного подумав, она предлагает: "Знаете, я поделюсь с вами пирогом, если вы выполните небольшую мою прихоть. Многого не прошу, просто... -- она делает неловкую паузу, -- принесите мне цветок из нашего леса. Обычно мы ходим с лесником и я набираю их себе вдоволь, но в этот раз он слишком занят. Что скажете?"' + end, only=true, + { + cond=function(s) return have 'flower' end, + '[Дать девушке цветок] Вот, возьмите. ', + function(s) + _('maid_dlg').flower = 1; + remove('flower', pl); + raspberry_pie_status = 2; + take 'raspberry_pie' + p 'Девушка соскакивает с места и со словами "Сейчас вернусь!" убегает в трактир. Через несколько минут она возвращается с куском восхитительно пахнущего малинового пирога.' + end + }; + {"Согласен. ", 'Девушка улыбается: "Договорились". '}; + {"Мне надо подумать. ", 'Девушка пожимает плечами: "Как хотите. Пирог и вправду очень вкусный". '}; + }, + { + 'Хорошо, я попрошу у него. ', 'Девушка молча смотрит на меня. ' + } + }; + { + 'Я пойду. ', function(s) + p 'Девушка кивает, слегка улыбнувшись. ' + walkout(); + end + } + } } room { - nam = 'tavern'; - pic = function(s) - if raspberry_pie_status == 2 then - return 'images/tavern.png'; - else - return 'images/tavern.png;images/tavern_pie.png@181,124'; - end; - end; - disp = 'Деревня, трактир'; - theme = 'main'; - nofollow = true; - decor = [[Просторный зал трактира встречает вас теплом и уютом. Помещение залито солнечным светом, проникающим через многочисленные {#windows|окна} в бревенчатых {#walls|стенах}. Повсюду расставлены крепкие деревянные {#tables|столы}, на удивление хорошо сделанные. C потолка свисают электрические {#lights|люстры}. Над {#fireplace|очагом} в дальнем конце висит {#cauldron|котелок}, от которого поднимается ароматный пар. ]]; - way = { - path {'#outside', 'На улицу', 'village_center'}; - }; + nam = 'tavern'; + pic = function(s) + if raspberry_pie_status == 2 then + return 'images/tavern.png'; + else + return 'images/tavern.png;images/tavern_pie.png@181,124'; + end; + end; + disp = 'Деревня, трактир'; + theme = 'main'; + nofollow = true; + decor = [[Просторный зал трактира встречает вас теплом и уютом. Помещение залито солнечным светом, проникающим через многочисленные {#windows|окна} в бревенчатых {#walls|стенах}. Повсюду расставлены крепкие деревянные {#tables|столы}, на удивление хорошо сделанные. C потолка свисают электрические {#lights|люстры}. Над {#fireplace|очагом} в дальнем конце висит {#cauldron|котелок}, от которого поднимается ароматный пар. ]]; + way = { + path {'#outside', 'На улицу', 'village_center'}; + }; }: with { - obj { - nam = '#windows'; - act = 'Большие окна легко пропускают в помещение свет. Светло-зеленые занавески, висящие на всех окнах, раскрыты. '; - }; - obj { - nam = '#tables'; - act = 'Устойчивые тяжелые столы, расчитанные на трех-четырех человек каждый, накрыты белоснежными скатертями. '; - }; - obj { - nam = '#walls'; - act = 'Бревенчатые стены трактира создают теплую атмосферу старины и уюта. '; - }; - obj { - nam = '#lights'; - act = 'Лампы под тонкими пластиковыми абажурами сейчас выключены. '; - }; - obj { - nam = '#fireplace'; - act = 'Несмотря на жаркий летний день, в очаге пылает огонь. '; - }; - obj { - nam = '#cauldron'; - act = 'Ароматное жаркое бурлит в котелке -- сюда еще не пришли современные газовые или электрические плиты, а, может быть, хозяин просто предпочитает готовить по-старинке. '; - }; - obj { - nam = 'tavernkeeper'; - dsc = [[За начищенной до блеска барной стойкой скучает {трактирщик}. ]]; - act = function(s) - walkin 'tavernkeeper_dlg' - end; - } + obj { + nam = '#windows'; + act = 'Большие окна легко пропускают в помещение свет. Светло-зеленые занавески, висящие на всех окнах, раскрыты. '; + }; + obj { + nam = '#tables'; + act = 'Устойчивые тяжелые столы, расчитанные на трех-четырех человек каждый, накрыты белоснежными скатертями. '; + }; + obj { + nam = '#walls'; + act = 'Бревенчатые стены трактира создают теплую атмосферу старины и уюта. '; + }; + obj { + nam = '#lights'; + act = 'Лампы под тонкими пластиковыми абажурами сейчас выключены. '; + }; + obj { + nam = '#fireplace'; + act = 'Несмотря на жаркий летний день, в очаге пылает огонь. '; + }; + obj { + nam = '#cauldron'; + act = 'Ароматное жаркое бурлит в котелке -- сюда еще не пришли современные газовые или электрические плиты, а, может быть, хозяин просто предпочитает готовить по-старинке. '; + }; + obj { + nam = 'tavernkeeper'; + dsc = [[За начищенной до блеска барной стойкой скучает {трактирщик}. ]]; + act = function(s) + walkin 'tavernkeeper_dlg' + end; + } } dlg { - nam = 'tavernkeeper_dlg'; - noinv = true; - title = 'Трактирщик'; - pic = 'images/characters/tavernkeeper.png'; - theme = 'main'; - enter = [[За барной стойкой я вижу тучного мужчину с густой черной бородой. Его темные глаза весело смотрят на меня. Он громогласно вопрошает: "Чего изволите, гость дорогой?"]]; - phr = { - {'Добрый день. Я впервые в вашей деревне. ', 'Трактирщик улыбается и предлагает свои услуги: "Добро пожаловать! В моем трактире вы всегда можете остановиться на ночь и не останетесь без сытного горячего ужина!"', - {'Благодарю, но у меня нет с собой денег.', 'Трактирщик пожимает плечами: "Бесплатно мы не обслуживаем". '}; - {'Вы знаете какие-нибудь местные достопримечательности?', 'Трактирщик уверенно отвечает: "Обязательно попробуйте наш малиновый пирог! Уверяю, вы не пробовали ничего вкуснее!"'}; - }; - {cond=function(s) return raspberry_pie_status == 1; end, "Я могу приобрести у вас малиновый пирог?", 'Трактирщик тянется к пирогу со словами: "Всего сто пятьдесят монет и он ваш!"', - {'К сожалению, у меня нет с собой денег. Мы можем договориться?', 'Трактирщик возвращается на место и говорит: "Так не пойдет. Пирог продается только за деньги". '} - }; - {true, 'До свидания.', function(s) - p 'Трактирщик бодро отвечает: "Заходите еще!" ' - walkout(); - end}; - }; + nam = 'tavernkeeper_dlg'; + noinv = true; + title = 'Трактирщик'; + pic = 'images/characters/tavernkeeper.png'; + theme = 'main'; + enter = [[За барной стойкой я вижу тучного мужчину с густой черной бородой. Его темные глаза весело смотрят на меня. Он громогласно вопрошает: "Чего изволите, гость дорогой?"]]; + phr = { + {'Добрый день. Я впервые в вашей деревне. ', 'Трактирщик улыбается и предлагает свои услуги: "Добро пожаловать! В моем трактире вы всегда можете остановиться на ночь и не останетесь без сытного горячего ужина!"', + {'Благодарю, но у меня нет с собой денег.', 'Трактирщик пожимает плечами: "Бесплатно мы не обслуживаем". '}; + {'Вы знаете какие-нибудь местные достопримечательности?', 'Трактирщик уверенно отвечает: "Обязательно попробуйте наш малиновый пирог! Уверяю, вы не пробовали ничего вкуснее!"'}; + }; + {cond=function(s) return raspberry_pie_status == 1; end, "Я могу приобрести у вас малиновый пирог?", 'Трактирщик тянется к пирогу со словами: "Всего сто пятьдесят монет и он ваш!"', + {'К сожалению, у меня нет с собой денег. Мы можем договориться?', 'Трактирщик возвращается на место и говорит: "Так не пойдет. Пирог продается только за деньги". '} + }; + {true, 'До свидания.', function(s) + p 'Трактирщик бодро отвечает: "Заходите еще!" ' + walkout(); + end}; + }; +} + +room { + nam = 'townhall'; + pic='images/townhall.png'; + theme = 'main'; + title = 'Ратуша'; + nofollow = true; + decor = [[Я стою в просторном зале ратуши. С {#ceiling|потолка} свисает несколько больших хрустальных {#chandelier|люстр}. Сейчас в помещении царит полумрак – {#curtains|занавески} закрыты и сквозь них пробивается совсем немного света. В центре зала стоит огромный дубовый {#table|стол}, по периметру которого расставлены массивные {#chairs|стулья}. В кресле в дальнем конце стола дремлет пожилой {#head|мужчина}. ]]; + onexit = function(s) + if have 'oil' then + p [[Вряд ли местным жителям понравится, если я буду красть их вещи. Масло надо вернуть. ]]; + return false; + end; + end; + way = { + path {'#out', 'На улицу', 'village_center'}; + }; +}: with { + obj { + nam = '#ceiling'; + act = 'Высокий потолок скрывается во тьме, однако мне, с моим драконьим зрением, не составляет труда разглядеть его хорошо обработанные и ровные доски. '; + }; + obj { + nam = '#chandelier'; + act = 'Позолоченные кронштейн и рожки удерживают лампы и множество подвесок, украшающих люстры. Сейчас они выключены, но стоит зажечь свет, и искрящиеся отблески засверкают, отражаясь от хрусталя и преломляясь в нем. '; + }; + obj { + nam = '#curtains'; + act = 'Выцветшие занавески закрыты, преграждая свету путь в помещение. Старая ткань все еще сохраняет свою плотность и прочность.'; + }; + obj { + nam = '#table'; + act = 'На полированной поверхности стола видны многочисленные царапины, оставленные посетителями за долгие годы. Массивный и тяжелый, он стоит как влитой и прослужит еще немало лет. '; + }; + obj { + nam = '#chairs'; + act = 'Простые, но крепкие стулья столь же стары, как и остальная мебель здесь. Я не сомневаюсь, что они прослужат еще много лет. '; + }; + obj { + nam = '#head'; + act = [[Нет ни малейшего смысла его будить -- пусть себе спит. ]]; + }; + obj { + flask = true; + nam = 'cabinet'; + dsc = [[Рядом со входом стоит небольшая крепкая {тумбочка}, на которой стоит {record_player|проигрыватель}, воспроизводящий неизвестную мне мелодию. ]]; + act = function(s) + if s.flask then + return [[Внутри тумбочки я обнаруживаю несколько {records|пластинок}, коробочку с {parts|запчастями} и {oil|флакончик с машинным маслом}. ]]; + else + return [[Внутри тумбочки я обнаруживаю несколько {records|пластинок} и коробочку с {parts|запчастями}]]; + end; + end; + used = function(s, o) + if o == _('oil') then + s.flask = true; + remove(o, pl); + put(o, 'townhall'); + return 'Я возвращаю флакончик на место. '; + end; + end; + }:with { + obj { + nam = 'records'; + act = [[Нескольпо грампластинок. Ни исполнители, ни альбомы мне совершенно не знакомы. ]]; + }; + obj { + nam = 'parts'; + act = [[Запасные детали для проигрывателя, бережно расфасованные по небольшим коробочкам и пакетикам. ]]; + }; + obj { + nam = 'oil'; + disp = 'Флакончик с маслом'; + tak = function(s) + _('cabinet').flask = false; + return 'Я беру флакончик с маслом. '; + end; + inv = 'Почти полный флакончик с машинным маслом. '; + }; + obj { + nam = 'record_player'; + act = [[Проигрыватель в идеальном состоянии, несмотря на почтенный возраст. Старая заезженная пластинка обильно потрескивает, однако музыка мне определенно нравится. К сожалению, она мне совершенно незнакома. ]]; + }; + }; } room { - nam = 'townhall'; - pic='images/townhall.png'; - theme = 'main'; - title = 'Ратуша'; - nofollow = true; - decor = [[Я стою в просторном зале ратуши. С {#ceiling|потолка} свисает несколько больших хрустальных {#chandelier|люстр}. Сейчас в помещении царит полумрак – {#curtains|занавески} закрыты и сквозь них пробивается совсем немного света. В центре зала стоит огромный дубовый {#table|стол}, по периметру которого расставлены массивные {#chairs|стулья}. В кресле в дальнем конце стола дремлет пожилой {#head|мужчина}. ]]; - onexit = function(s) - if have 'oil' then - p [[Вряд ли местным жителям понравится, если я буду красть их вещи. Масло надо вернуть. ]]; - return false; - end; - end; - way = { - path {'#out', 'На улицу', 'village_center'}; - }; -}: with { - obj { - nam = '#ceiling'; - act = 'Высокий потолок скрывается во тьме, однако мне, с моим драконьим зрением, не составляет труда разглядеть его хорошо обработанные и ровные доски. '; - }; - obj { - nam = '#chandelier'; - act = 'Позолоченные кронштейн и рожки удерживают лампы и множество подвесок, украшающих люстры. Сейчас они выключены, но стоит зажечь свет, и искрящиеся отблески засверкают, отражаясь от хрусталя и преломляясь в нем. '; - }; - obj { - nam = '#curtains'; - act = 'Выцветшие занавески закрыты, преграждая свету путь в помещение. Старая ткань все еще сохраняет свою плотность и прочность.'; - }; - obj { - nam = '#table'; - act = 'На полированной поверхности стола видны многочисленные царапины, оставленные посетителями за долгие годы. Массивный и тяжелый, он стоит как влитой и прослужит еще немало лет. '; - }; - obj { - nam = '#chairs'; - act = 'Простые, но крепкие стулья столь же стары, как и остальная мебель здесь. Я не сомневаюсь, что они прослужат еще много лет. '; - }; - obj { - nam = '#head'; - act = [[Нет ни малейшего смысла его будить -- пусть себе спит. ]]; - }; - obj { - flask = true; - nam = 'cabinet'; - dsc = [[Рядом со входом стоит небольшая крепкая {тумбочка}, на которой стоит {record_player|проигрыватель}, воспроизводящий неизвестную мне мелодию. ]]; - act = function(s) - if s.flask then - return [[Внутри тумбочки я обнаруживаю несколько {records|пластинок}, коробочку с {parts|запчастями} и {oil|флакончик с машинным маслом}. ]]; - else - return [[Внутри тумбочки я обнаруживаю несколько {records|пластинок} и коробочку с {parts|запчастями}]]; - end; - end; - used = function(s, o) - if o == _('oil') then - s.flask = true; - remove(o, pl); - put(o, 'townhall'); - return 'Я возвращаю флакончик на место. '; - end; - end; - }:with { - obj { - nam = 'records'; - act = [[Нескольпо грампластинок. Ни исполнители, ни альбомы мне совершенно не знакомы. ]]; - }; - obj { - nam = 'parts'; - act = [[Запасные детали для проигрывателя, бережно расфасованные по небольшим коробочкам и пакетикам. ]]; - }; - obj { - nam = 'oil'; - disp = 'Флакончик с маслом'; - tak = function(s) - _('cabinet').flask = false; - return 'Я беру флакончик с маслом. '; - end; - inv = 'Почти полный флакончик с машинным маслом. '; - }; - obj { - nam = 'record_player'; - act = [[Проигрыватель в идеальном состоянии, несмотря на почтенный возраст. Старая заезженная пластинка обильно потрескивает, однако музыка мне определенно нравится. К сожалению, она мне совершенно незнакома. ]]; - }; - }; + state = false; + nofollow = true; + nam = 'inside_well'; + theme = 'main'; + pic = 'images/village_center.png'; + disp = 'В колодце'; + onenter = function(s) + if not s.state then + p [[Вряд ли я смогу выбраться, если просто спрыгну внутрь. ]]; + return false; + end; + end; + dsc = 'Я стою на дне колодца. Внутренняя его часть выложена камнем. Здесь царит полумрак и мне приходится снять очки, чтобы хорошо видеть. Несмотря на то, что колодец давно высох, здесь все еще очень влажно. '; + way = { + path {'Наверх', 'village_center'}; + } +}:with { + obj { + nam = 'loose_rock'; + dsc = [[Мое внимание привлекает {один из камней}, заметно выступающий из кладки. ]]; + act = function(s) + p [[Я легко вынимаю камень. Под ним, в небольшом углублении, спрятан металлический ключик. Удивительно, но влажность почти не повредила ему. ]]; + take('hidden_key'); + s:disable(); + end; + } +} + +obj { + nam = 'hidden_key'; + disp = 'Ключик'; + disp2 = 'ключик'; + disp3 = 'ключик'; + inv = [[Старый металлический ключик, найденный мной в колодце. ]]; } room { - state = false; - nofollow = true; - nam = 'inside_well'; - theme = 'main'; - pic = 'images/village_center.png'; - disp = 'В колодце'; - onenter = function(s) - if not s.state then - p [[Вряд ли я смогу выбраться, если просто спрыгну внутрь. ]]; - return false; - end; - end; - dsc = 'Я стою на дне колодца. Внутренняя его часть выложена камнем. Здесь царит полумрак и мне приходится снять очки, чтобы хорошо видеть. Несмотря на то, что колодец давно высох, здесь все еще очень влажно. '; - way = { - path {'Наверх', 'village_center'}; - } -}:with { - obj { - nam = 'loose_rock'; - dsc = [[Мое внимание привлекает {один из камней}, заметно выступающий из кладки. ]]; - act = function(s) - p [[Я легко вынимаю камень. Под ним, в небольшом углублении, спрятан металлический ключик. Удивительно, но влажность почти не повредила ему. ]]; - take('hidden_key'); - s:disable(); - end; - } -} - -obj { - nam = 'hidden_key'; - disp = 'Ключик'; - disp2 = 'ключик'; - disp3 = 'ключик'; - inv = [[Старый металлический ключик, найденный мной в колодце. ]]; + nam = 'village_north'; + pic = 'images/village_north.png'; + disp = 'Деревня, север'; + theme = 'main'; + nofollow = true; + decor = [[Я стою на северном краю {#village|деревни}. Узенькая {#road|дорожка} ведет прямо к зданию {#library|библиотеки}, стоящему на самом краю деревни. За ним я вижу лишь бескрайний {#forest|лес} и тянующуюся дальше на север {#mountains|горную цепь}. Сквозь тонкие перистые {clouds|облака} пробиваются яркие лучи летнего {sun_transformed|солнца}. ]]; + way = { + path {'#south', 'На юг, к ратуше', 'village_center'}; + path {'#in', 'В библиотеку', 'library'}; + }; +}: with { + obj { + nam = '#village'; + act = 'Деревня, раскинувшаяся к югу от меня, выглядит спящей -- ухоженные домики, укрытые в листве, пустые дорожки между ними. Лишь на крыльце трактира я вижу одинокую девушку в голубом платье. '; + }; + obj { + nam = '#road'; + act = 'Асфальт здесь еще более потрескавшийся чем в остальных местах. Кое-где свкозь трещины пробиваются тонкие стебельки травы. '; + }; + obj { + nam = '#forest'; + act = 'Лес начинается почти сразу за библиотекой. Здесь деревья еще не так часты, как чуть дальше к северу, где чаща становится совершенно непролазной. Воздух наполнен ароматом хвои, а со всех сторон доносится пение птиц. '; + }; + obj { + nam = '#library'; + act = 'Высокое и просторное, здание вместило под своей крышей огромное количество книг. Несмотря на почтенный возраст, здание сохранилось практически идеально, благодаря прекрасному уходу. Широкие двустворчатые двери приоткрыты, приглашая гостей. '; + }; + obj { + nam = '#mountains'; + act = 'Большая часть горной цепи скрыта от моего взора деревьями. Отсюда я вижу лишь несколько высочайших пиков. '; + }; + 'sun_transformed'; + 'clouds'; } room { - nam = 'village_north'; - pic = 'images/village_north.png'; - disp = 'Деревня, север'; - theme = 'main'; - nofollow = true; - decor = [[Я стою на северном краю {#village|деревни}. Узенькая {#road|дорожка} ведет прямо к зданию {#library|библиотеки}, стоящему на самом краю деревни. За ним я вижу лишь бескрайний {#forest|лес} и тянующуюся дальше на север {#mountains|горную цепь}. Сквозь тонкие перистые {clouds|облака} пробиваются яркие лучи летнего {sun_transformed|солнца}. ]]; - way = { - path {'#south', 'На юг, к ратуше', 'village_center'}; - path {'#in', 'В библиотеку', 'library'}; - }; -}: with { - obj { - nam = '#village'; - act = 'Деревня, раскинувшаяся к югу от меня, выглядит спящей -- ухоженные домики, укрытые в листве, пустые дорожки между ними. Лишь на крыльце трактира я вижу одинокую девушку в голубом платье. '; - }; - obj { - nam = '#road'; - act = 'Асфальт здесь еще более потрескавшийся чем в остальных местах. Кое-где свкозь трещины пробиваются тонкие стебельки травы. '; - }; - obj { - nam = '#forest'; - act = 'Лес начинается почти сразу за библиотекой. Здесь деревья еще не так часты, как чуть дальше к северу, где чаща становится совершенно непролазной. Воздух наполнен ароматом хвои, а со всех сторон доносится пение птиц. '; - }; - obj { - nam = '#library'; - act = 'Высокое и просторное, здание вместило под своей крышей огромное количество книг. Несмотря на почтенный возраст, здание сохранилось практически идеально, благодаря прекрасному уходу. Широкие двустворчатые двери приоткрыты, приглашая гостей. '; - }; - obj { - nam = '#mountains'; - act = 'Большая часть горной цепи скрыта от моего взора деревьями. Отсюда я вижу лишь несколько высочайших пиков. '; - }; - 'sun_transformed'; - 'clouds'; + nam = 'library'; + pic = 'images/library.png'; + disp = 'Библиотека'; + theme = 'main'; + nofollow = true; + decor = [[Внутреннее пространство библиотеки представляет собой просторный зал, уставленный книжными {library_shelves|стеллажами}. Между ними то и дело встречаются уютные {#tables|столики} с расположенными вокруг {#chairs|креслами} и стоящими неподалеку {#lamps|торшерами}. {#windows|Окон} в здании немного и предпочтение отдается искусственному освещению. К стене у входа прибита небольшая {#library_notice|табличка}. ]]; + way = { + path {'#out', 'На улицу', 'village_north'}; + path {'library_hidden_path', 'В потайную комнату', 'library_hidden_room'}:disable(); + }; +}:with { + obj { + nam = 'librarian'; + dsc = [[По залу ходит пожилой {человек} с книгой в руках. ]]; + act = function(s) + walkin 'librarian_dlg' + end; + used = function(s, o) + if o^'box' then + return 'Наверное, есть смысл спросить, прежде чем совать ему это в руки. '; + else + return 'Вряд ли это сможет его заинтересовать. '; + end; + end; + }; + obj { + nam = '#tables'; + act = 'Небольшие круглые столики на бронзовых ножках услужливо расставлены по залу. '; + }; + obj { + nam = '#chairs'; + act = 'Удобные мягкие кресла, предназначенные для посетилей. '; + }; + obj { + nam = '#lamps'; + act = 'Около каждого кресла стоит торшер с голубым абажуром в форме усеченного конуса. Сейчас они все выключены -- днем света достаточно даже из немногочисленных окон, да и посетителей кроме меня нет. '; + }; + obj { + nam = '#windows'; + act = 'Легкие бежевые занавески на больших прозрачных окнах распахнуты. На севере и востоке я вижу лишь бескрайний лес. За деревьями на западе тянется горная гряда. Через окна на юге открывается вид на деревню. '; + }; + obj { + state = 0; + nam = 'library_shelves'; + act = function(s) + if s.state == 0 then + p [[Я долго блуждаю в лабиринте полок и стеллажей. У меня ушло бы больше года только на то, чтобы ознакомиться с названиями книг собранных здесь. Интересно, откуда в этом захолустье такие сокровища? Наконец, я останавливаюсь у {library_the_shelf|одной из полок}. ]]; + else + p [[В этот раз, я без труда нахожу ту самую {library_the_shelf|полку}. ]]; + end; + end; + }, + obj { + nam = 'library_the_shelf'; + act = function(s) + if _'library_shelves'.state == 0 then + pr [[На первый взгляд, полка ничем не примечательна. Лишь осмотрев ее, я понимаю, что именно привлекло мое внимание: на гладкой поверхности аккуратными и ровными буквами вырезано слово "biography". Это определенно имеет какой-то смысл. ]]; + end; + _'library_shelves'.state = 1; + walkin('library_shelf_puzzle'); + end; + }; + obj { + nam = '#library_notice'; + act = function(s) + walkin('library_notice_inside') + end; + } } room { - nam = 'library'; - pic = 'images/library.png'; - disp = 'Библиотека'; - theme = 'main'; - nofollow = true; - decor = [[Внутреннее пространство библиотеки представляет собой просторный зал, уставленный книжными {library_shelves|стеллажами}. Между ними то и дело встречаются уютные {#tables|столики} с расположенными вокруг {#chairs|креслами} и стоящими неподалеку {#lamps|торшерами}. {#windows|Окон} в здании немного и предпочтение отдается искусственному освещению. К стене у входа прибита небольшая {#library_notice|табличка}. ]]; - way = { - path {'#out', 'На улицу', 'village_north'}; - path {'library_hidden_path', 'В потайную комнату', 'library_hidden_room'}:disable(); - }; -}:with { - obj { - nam = 'librarian'; - dsc = [[По залу ходит пожилой {человек} с книгой в руках. ]]; - act = function(s) - walkin 'librarian_dlg' - end; - used = function(s, o) - if o^'box' then - return 'Наверное, есть смысл спросить, прежде чем совать ему это в руки. '; - else - return 'Вряд ли это сможет его заинтересовать. '; - end; - end; - }; - obj { - nam = '#tables'; - act = 'Небольшие круглые столики на бронзовых ножках услужливо расставлены по залу. '; - }; - obj { - nam = '#chairs'; - act = 'Удобные мягкие кресла, предназначенные для посетилей. '; - }; - obj { - nam = '#lamps'; - act = 'Около каждого кресла стоит торшер с голубым абажуром в форме усеченного конуса. Сейчас они все выключены -- днем света достаточно даже из немногочисленных окон, да и посетителей кроме меня нет. '; - }; - obj { - nam = '#windows'; - act = 'Легкие бежевые занавески на больших прозрачных окнах распахнуты. На севере и востоке я вижу лишь бескрайний лес. За деревьями на западе тянется горная гряда. Через окна на юге открывается вид на деревню. '; - }; - obj { - state = 0; - nam = 'library_shelves'; - act = function(s) - if s.state == 0 then - p [[Я долго блуждаю в лабиринте полок и стеллажей. У меня ушло бы больше года только на то, чтобы ознакомиться с названиями книг собранных здесь. Интересно, откуда в этом захолустье такие сокровища? Наконец, я останавливаюсь у {library_the_shelf|одной из полок}. ]]; - else - p [[В этот раз, я без труда нахожу ту самую {library_the_shelf|полку}. ]]; - end; - end; - }, - obj { - nam = 'library_the_shelf'; - act = function(s) - if _'library_shelves'.state == 0 then - pr [[На первый взгляд, полка ничем не примечательна. Лишь осмотрев ее, я понимаю, что именно привлекло мое внимание: на гладкой поверхности аккуратными и ровными буквами вырезано слово "biography". Это определенно имеет какой-то смысл. ]]; - end; - _'library_shelves'.state = 1; - walkin('library_shelf_puzzle'); - end; - }; - obj { - nam = '#library_notice'; - act = function(s) - walkin('library_notice_inside') - end; - } + nam = 'library_notice_inside'; + pic = 'images/library.png'; + disp = 'Библиотека'; + theme = 'main'; + decor = [[ + Старая металлическая табличка содержит список правил пользования библиотекой:^ + 1. Вы можете взять любые книги. Все взятые книги вы обязаны вернуть сами или кто-то должен сделать это за вас. ^ + 2. Вы можете принести любую книгу и оставить ее здесь.^ + 3. Вы можете самостоятельно поставить книгу на место, используя таблицу размещения или передать ее библиотекарю.^ + 4. В пределах полки ставьте книги в алфавитном порядке.^^ + Вокруг слова "алфавитном" в последнем правиле, я замечаю практически стершиеся следы старой краски, словно когда-то оно было выделено цветом. + ]]; + way = { + path {"Назад", 'library'}; + }; +} + +dlg { + ring = 0; + nam = 'librarian_dlg'; + pic = 'images/characters/librarian.png'; + theme = 'main'; + noinv = true; + title = 'Библиотекарь'; + enter = function(s) + seen_ring_librarian = true; + return [[Передо мной стоит пожилой человек в старом темно-сером костюме. На шее он носит темно-синий галстук-бабочку. Из нагрудного кармана торчит уголок тщательно выглаженного носового платка. На указательном пальце правой руки старика я замечаю кольцо с драгоценным камнем. Интересно, как оно оказалось в такой глуши? В левой руке он держит толстенную книгу, названия которой я, к сожалению, не вижу. На носу библиотекаря сидят очки в роговой оправе. Подбородок его гладко выбрит, а короткие волосы совершенно седы. Серые глаза спокойно смотрят на меня, а рот слегка приоткрыт в дружелюбной улыбке. ]]; + end; + phr = { + {'Добрый день. Я впервые в вашей деревне. ', 'Мужчина почтительно кивает и произносит: "Добро пожаловать! Чем скромный библиотекарь может помочь вам?"', + {'Вы знаете какие-нибудь местные достопримечательности?', 'Библиотекарь пожимает плечами: "Не думаю, что здесь есть на что смотреть". ', + {'Ваша библиотека даст фору любой другой, которую я видел. Как вам удалось собрать столько книг?', 'Библиотекарь с улыбкой отвечает: "Это дело рук многих поколений. Отсюда не так просто добраться до цивилизации. Многие из этих книг были привезены сюда странниками, другие собирали мои предшественники. В любом случае, не стесняйтесь брать любую из них. Главное -- не забудьте вернуть". '} + }, + {'Откуда у вас это кольцо?', 'Старик демонстрирует мне свое кольцо -- я с интересам разглядываю произведение ювелирного искусства -- золотое колечко, украшенное причудливой резьбой, инкрустировано крупным изумрудом -- около четырех миллиметров в диаметре. Убрав руку, он поясняет: "Это кольцо хранится здесь с незапамятных времен. Мне передал его мой предшественник, а я передам его тому, кто будет хранить эту библиотеку после меня". '} + }, + {cond=function(s) return seen_ring_box; end, 'Могу я взглянуть на ваше кольцо?', function(s) + _('village_well').known = 1; + return 'Библиотекарь, не говоря ни слова, снимает кольцо с пальца и протягивает мне. Я внимательно осматриваю драгоценность. На внутренней стороне выгравирована надпись: "Ключ там, где вода". Я возвращаю кольцо владельцу и он надевает его обратно. ' + end}; + {true, 'До свидания.', function(s) + p 'Старик кивает: "Всего хорошего". ' + walkout(); + end} + } } room { - nam = 'library_notice_inside'; - pic = 'images/library.png'; - disp = 'Библиотека'; - theme = 'main'; - decor = [[ - Старая металлическая табличка содержит список правил пользования библиотекой:^ - 1. Вы можете взять любые книги. Все взятые книги вы обязаны вернуть сами или кто-то должен сделать это за вас. ^ - 2. Вы можете принести любую книгу и оставить ее здесь.^ - 3. Вы можете самостоятельно поставить книгу на место, используя таблицу размещения или передать ее библиотекарю.^ - 4. В пределах полки ставьте книги в алфавитном порядке.^^ - Вокруг слова "алфавитном" в последнем правиле, я замечаю практически стершиеся следы старой краски, словно когда-то оно было выделено цветом. - ]]; - way = { - path {"Назад", 'library'}; - }; -} + nam = 'library_shelf_puzzle'; + nofollow = true; + disp = 'Библиотека'; + theme = 'main'; + pic = function(s) + local pic = 'images/library/library_no_books_bg.png'; + for index, book in ipairs(_'shelf'.obj) do + pic = pic .. ';images/library/library_book' .. tostring(book.book) .. '.png@' .. tostring(35 * index - 33) .. ',63'; + end; + return pic; + end; + way = { + path {'#back', 'Отойти от стеллажа', 'library'}; + }; + book_map = {6, 1, 4, 8, 2, 3, 7, 5, 9}; +}:with { + obj { + nam = 'shelf'; + dsc = function(s) + local count = #s.obj; + if count > 1 then + p [[На {shelf|полке} стоят несколько книг: ]]; + elseif count == 1 then + p [[На {shelf|полке} стоит книга: ]]; + else + p [[{shelf|Полка} пуста.]]; + end; + end; + act = [[На гладком дереве полки вырезаны буквы "biography". ]]; + used = function(s, o) + pl:need_scene(); + local book_map = _'library_shelf_puzzle'.book_map; + + if o.book then + remove(o, pl); + put(o, s); + p [[Я ставлю книгу на полку. ]]; -dlg { - ring = 0; - nam = 'librarian_dlg'; - pic = 'images/characters/librarian.png'; - theme = 'main'; - noinv = true; - title = 'Библиотекарь'; - enter = function(s) - seen_ring_librarian = true; - return [[Передо мной стоит пожилой человек в старом темно-сером костюме. На шее он носит темно-синий галстук-бабочку. Из нагрудного кармана торчит уголок тщательно выглаженного носового платка. На указательном пальце правой руки старика я замечаю кольцо с драгоценным камнем. Интересно, как оно оказалось в такой глуши? В левой руке он держит толстенную книгу, названия которой я, к сожалению, не вижу. На носу библиотекаря сидят очки в роговой оправе. Подбородок его гладко выбрит, а короткие волосы совершенно седы. Серые глаза спокойно смотрят на меня, а рот слегка приоткрыт в дружелюбной улыбке. ]]; - end; - phr = { - {'Добрый день. Я впервые в вашей деревне. ', 'Мужчина почтительно кивает и произносит: "Добро пожаловать! Чем скромный библиотекарь может помочь вам?"', - {'Вы знаете какие-нибудь местные достопримечательности?', 'Библиотекарь пожимает плечами: "Не думаю, что здесь есть на что смотреть". ', - {'Ваша библиотека даст фору любой другой, которую я видел. Как вам удалось собрать столько книг?', 'Библиотекарь с улыбкой отвечает: "Это дело рук многих поколений. Отсюда не так просто добраться до цивилизации. Многие из этих книг были привезены сюда странниками, другие собирали мои предшественники. В любом случае, не стесняйтесь брать любую из них. Главное -- не забудьте вернуть". '} - }, - {'Откуда у вас это кольцо?', 'Старик демонстрирует мне свое кольцо -- я с интересам разглядываю произведение ювелирного искусства -- золотое колечко, украшенное причудливой резьбой, инкрустировано крупным изумрудом -- около четырех миллиметров в диаметре. Убрав руку, он поясняет: "Это кольцо хранится здесь с незапамятных времен. Мне передал его мой предшественник, а я передам его тому, кто будет хранить эту библиотеку после меня". '} - }, - {cond=function(s) return seen_ring_box; end, 'Могу я взглянуть на ваше кольцо?', function(s) - _('village_well').known = 1; - return 'Библиотекарь, не говоря ни слова, снимает кольцо с пальца и протягивает мне. Я внимательно осматриваю драгоценность. На внутренней стороне выгравирована надпись: "Ключ там, где вода". Я возвращаю кольцо владельцу и он надевает его обратно. ' - end}; - {true, 'До свидания.', function(s) - p 'Старик кивает: "Всего хорошего". ' - walkout(); - end} - } + if #s.obj== 9 then + for i = 1, 9 do + if book_map[s.obj[i].book] ~= i then + return; + end; + end; + p [[Стеллаж поворачивается, открывая проход в ранее скрытое помещение. ]]; + disable 'library_shelves' + enable 'library_hidden_path' + walkout() + end; + else + return false; + end; + end; + }:with { + obj { + book = 1; + --book = 6; + nam = 'book_1'; + disp = 'История мира, том 1'; + dsc = '{"История мира, том 1"}'; + tak = 'Я беру книгу с полки. '; + inv = 'Довольно старое издание одной из самых распространенных книг по общемировой истории. '; + }, + obj { + book = 2; + --book = 1; + nam = 'book_2'; + disp = 'История мира, том 2'; + dsc = '{"История мира, том 2"}'; + tak = 'Я беру книгу с полки. '; + inv = 'Довольно старое издание одной из самых распространенных книг по общемировой истории. '; + }, + obj { + book = 3; + --book = 4; + nam = 'book_3'; + disp = 'История мира, том 3'; + dsc = '{"История мира, том 3"}'; + tak = 'Я беру книгу с полки. '; + inv = 'Довольно старое издание одной из самых распространенных книг по общемировой истории. '; + }, + obj { + book = 4; + --book = 8; + nam = 'book_4'; + disp = 'История мира, том 4'; + dsc = '{"История мира, том 4"}'; + tak = 'Я беру книгу с полки. '; + inv = 'Довольно старое издание одной из самых распространенных книг по общемировой истории. '; + }, + obj { + book = 5; + --book = 2; + nam = 'book_5'; + disp = 'История мира, том 5'; + dsc = '{"История мира, том 5"}'; + tak = 'Я беру книгу с полки. '; + inv = 'Довольно старое издание одной из самых распространенных книг по общемировой истории. '; + }, + obj { + book = 6; + --book = 3; + nam = 'book_6'; + disp = 'История мира, том 6'; + dsc = '{"История мира, том 6"}'; + tak = 'Я беру книгу с полки. '; + inv = 'Довольно старое издание одной из самых распространенных книг по общемировой истории. '; + }, + obj { + book = 7; + --book = 7; + nam = 'book_7'; + disp = 'История мира, том 7'; + dsc = '{"История мира, том 7"}'; + tak = 'Я беру книгу с полки. '; + inv = 'Довольно старое издание одной из самых распространенных книг по общемировой истории. '; + }, + obj { + book = 8; + --book = 5; + nam = 'book_8'; + disp = 'История мира, том 8'; + dsc = '{"История мира, том 8"}'; + tak = 'Я беру книгу с полки. '; + inv = 'Довольно старое издание одной из самых распространенных книг по общемировой истории. '; + }, + obj { + book = 9; + --book = 9; + nam = 'book_9'; + disp = 'История мира, том 9'; + dsc = '{"История мира, том 9"}'; + tak = 'Я беру книгу с полки. '; + inv = 'Довольно старое издание одной из самых распространенных книг по общемировой истории. '; + } + } } room { - nam = 'library_shelf_puzzle'; - nofollow = true; - disp = 'Библиотека'; - theme = 'main'; - way = { - path {'#back', 'Отойти от стеллажа', 'library'}; - }; + nam = 'library_hidden_room'; + pic = 'images/library.png'; + disp = 'Библиотека, потайная комната'; + theme = 'main'; + nofollow = true; + decor = [[Эту библиотеку определенно проектировал кто-то невероятно талантливый. Я мог бы исходить здание вдоль и поперек, исследовать и измерить каждый уголок, но все равно не догадался бы, что здесь скрыта эта комнатушка. Здесь нет ничего, кроме маленького {#table|столика}. ]]; + way = { + path {'В главный зал', 'library'}; + }; }:with { - obj { - nam = 'shelf'; - dsc = function(s) - if #s.obj > 1 then - p [[На {shelf|полке} стоят несколько книг: ]]; - elseif #s.obj == 1 then - p [[На {shelf|полке} стоит книга: ]]; - else - p [[{shelf|Полка} пуста.]]; - end; - end; - act = [[На гладком дереве полки вырезаны буквы "biography". ]]; - used = function(s, o) - pl:need_scene(); - if o.book then - remove(o, pl); - put(o, s); - p [[Я ставлю книгу на полку. ]]; - if #s.obj == 9 then - for i=1, 9 do - if s.obj[i].book ~= i then - return; - end; - end; - p [[Стеллаж поворачивается, открывая мне доступ в ранее скрытое помещение. ]]; - disable 'library_shelves' - enable 'library_hidden_path' - walkout() - end; - else - return false; - end; - end; - }:with { - obj { - book = 6; - nam = 'book_1'; - disp = 'История мира, том 1'; - dsc = '{"История мира, том 1"}'; - tak = 'Я беру книгу с полки. '; - inv = 'Довольно старое издание одной из самых распространенных книг по общемировой истории. '; - }, - obj { - book = 1; - nam = 'book_2'; - disp = 'История мира, том 2'; - dsc = '{"История мира, том 2"}'; - tak = 'Я беру книгу с полки. '; - inv = 'Довольно старое издание одной из самых распространенных книг по общемировой истории. '; - }, - obj { - book = 4; - nam = 'book_3'; - disp = 'История мира, том 3'; - dsc = '{"История мира, том 3"}'; - tak = 'Я беру книгу с полки. '; - inv = 'Довольно старое издание одной из самых распространенных книг по общемировой истории. '; - }, - obj { - book = 8; - nam = 'book_4'; - disp = 'История мира, том 4'; - dsc = '{"История мира, том 4"}'; - tak = 'Я беру книгу с полки. '; - inv = 'Довольно старое издание одной из самых распространенных книг по общемировой истории. '; - }, - obj { - book = 2; - nam = 'book_5'; - disp = 'История мира, том 5'; - dsc = '{"История мира, том 5"}'; - tak = 'Я беру книгу с полки. '; - inv = 'Довольно старое издание одной из самых распространенных книг по общемировой истории. '; - }, - obj { - book = 3; - nam = 'book_6'; - disp = 'История мира, том 6'; - dsc = '{"История мира, том 6"}'; - tak = 'Я беру книгу с полки. '; - inv = 'Довольно старое издание одной из самых распространенных книг по общемировой истории. '; - }, - obj { - book = 7; - nam = 'book_7'; - disp = 'История мира, том 7'; - dsc = '{"История мира, том 7"}'; - tak = 'Я беру книгу с полки. '; - inv = 'Довольно старое издание одной из самых распространенных книг по общемировой истории. '; - }, - obj { - book = 5; - nam = 'book_8'; - disp = 'История мира, том 8'; - dsc = '{"История мира, том 8"}'; - tak = 'Я беру книгу с полки. '; - inv = 'Довольно старое издание одной из самых распространенных книг по общемировой истории. '; - }, - obj { - book = 9; - nam = 'book_9'; - disp = 'История мира, том 9'; - dsc = '{"История мира, том 9"}'; - tak = 'Я беру книгу с полки. '; - inv = 'Довольно старое издание одной из самых распространенных книг по общемировой истории. '; - } - } + obj { + nam = '#table'; + act = 'Небольшой круглый столик на бронзовой ножке, такой же как и те, что расставлены по всей библиотеке. '; + }; + obj { + oiled = false; + opened = false; + lock_taken = false; + nam = 'box'; + disp = 'Шкатулка'; + disp2 = 'шкатулка'; + disp3 = 'шкатулку'; + dsc = [[На столе стоит изящно украшенная {шкатулка}. ]]; + tak = "Я забираю шкатулку. "; + inv = function(s) + seen_ring_box = true; + if s.lock_taken then + p [[Старинная шкатулка. На дне ее выгравировано кольцо с камнем. ]]; + elseif s.opened then + s.lock_taken = true; + p [[Я снимаю замок со шкатулки. ]]; + take('lock'); + remove('box', pl); + elseif seen_ring_librarian then + p [[Очень старая шкатулка. Я могу только догадываться, что скрывается внутри. На дне шкатулки выгравировано кольцо с камнем. Кажется, я где-то уже видел его. ]]; + else + p [[Очень старая шкатулка. Я могу только догадываться, что скрывается внутри. На дне шкатулки выгравировано кольцо с камнем. ]]; + end; + end; + used = function(s, o) + if o^'hidden_key' then + if s.oiled then + s.opened = true; + take('map'); + p [[Ключ с трудом поворачивается и замок открывается. Внутри лежит небольшой свиток. Я забираю его. ]]; + else + p [[За долгое время неиспользования, замок успел заржаветь и сейчас ключ в нем не повернуть. ]]; + end; + elseif o^'oil' then + if not s.oiled then + s.oiled = true; + p [[Я капаю немного масла в замок. Этого должно хватить, чтобы смазать механизм и заставить его работать. ]]; + else + p [[Замок уже смазан. ]] + end; + end; + end; + } +} + +obj { + nam = 'map'; + disp = 'Карта'; + disp2 = 'карта'; + disp3 = 'карту'; + inv = function(s) + p [[Очень старая карта, указывающая на место в горах, к западу от деревни. Это совсем недалеко -- минут десять полета. ]]; + _('fly_west_from_village'):enable(); + end; +} + +room { + nam = 'inside_crater_glade'; + pic = 'images/inside_crater_glade.png'; + disp = 'Кратер, полянка'; + theme = 'main'; + onenter = function(s) + if here()^'above_crater' then + p [[Еще не коснувшись земли, я начинаю превращение. Окутанное туманом, мое тело резко устремляется вниз. Через мгновение я оказываюсь на поляне в облике человека. Мои глаза излучают яркий свет, но мне не от кого прятаться -- очки остаются в нагрудном кармане. ]]; + end; + end; + decor = [[Небольшая круглая полянка посреди редкого лиственного {#forest|леса}. В центре ее стоит огромный старый {#oak|дуб} с раскидистой кроной. Изумрудно зеленая {#grass|трава} достигает мне до пояса. Невесть кем протоптанная {#path|тропинка}, ведет к {#tower|башне} в центре {#crater|кратера}. ]]; + way = { + path {"#up", "Взлететь", "above_crater"}; + path {"По тропинке", "inside_crater_path"}; + } +}: with { + obj { + nam = '#forest'; + act = 'В тени раскидистых вязов и стройных буков резвятся белки, зайцы и другие мелкие зверьки. Издалека доносятся стук дятла и пение птиц. '; + }; + obj { + nam = '#oak'; + act = 'Исполинское древо произрастает в самом центре поляны. Легкий ветерок шелестит в его ветвях, покрытых густой зеленой листвой. В огромном дупле спит филин. '; + }; + obj { + nam = '#grass'; + act = 'Дикая трава поднимается высоко, ничем и никем не сдерживаемая. '; + }; + obj { + nam = '#path'; + act = 'Кто-то аккуратно вытоптал в густой траве узенькую тропку, ведущую прямиком к башне. '; + }; + obj { + nam = '#tower'; + act = 'Башня из черного камня возвышается над лесом, словно маяк, установленный для любого, оказавшегося здесь. '; + }; + obj { + nam = '#crater'; + act = 'Находясь здесь, практически в самом центре громадной воронки, я не вижу ничего, что отличало бы этот лес и ландшафт от других, виденных мной. '; + }; } room { - nam = 'library_hidden_room'; - pic = 'images/library.png'; - disp = 'Библиотека, потайная комната'; - theme = 'main'; - nofollow = true; - decor = [[Эту библиотеку определенно проектировал кто-то невероятно талантливый. Я мог бы исходить здание вдоль и поперек, исследовать и измерить каждый уголок, но все равно не догадался бы, что здесь скрыта эта комнатушка. Здесь нет ничего, кроме маленького {#table|столика}. ]]; - way = { - path {'В главный зал', 'library'}; - }; -}:with { - obj { - nam = '#table'; - act = 'Небольшой круглый столик на бронзовой ножке, такой же как и те, что расставлены по всей библиотеке. '; - }; - obj { - oiled = false; - opened = false; - lock_taken = false; - nam = 'box'; - disp = 'Шкатулка'; - disp2 = 'шкатулка'; - disp3 = 'шкатулку'; - dsc = [[На столе стоит изящно украшенная {шкатулка}. ]]; - tak = "Я забираю шкатулку. "; - inv = function(s) - seen_ring_box = true; - if s.lock_taken then - p [[Старинная шкатулка. На дне ее выгравировано кольцо с камнем. ]]; - elseif s.opened then - s.lock_taken = true; - p [[Я снимаю замок со шкатулки. ]]; - take('lock'); - remove('box', pl); - elseif seen_ring_librarian then - p [[Очень старая шкатулка. Я могу только догадываться, что скрывается внутри. На дне шкатулки выгравировано кольцо с камнем. Кажется, я где-то уже видел его. ]]; - else - p [[Очень старая шкатулка. Я могу только догадываться, что скрывается внутри. На дне шкатулки выгравировано кольцо с камнем. ]]; - end; - end; - used = function(s, o) - if o^'hidden_key' then - if s.oiled then - s.opened = true; - take('map'); - p [[Ключ с трудом поворачивается и замок открывается. Внутри лежит небольшой свиток. Я забираю его. ]]; - else - p [[За долгое время неиспользования, замок успел заржаветь и сейчас ключ в нем не повернуть. ]]; - end; - elseif o^'oil' then - if not s.oiled then - s.oiled = true; - p [[Я капаю немного масла в замок. Этого должно хватить, чтобы смазать механизм и заставить его работать. ]]; - else - p [[Замок уже смазан. ]] - end; - end; - end; - } + nam = 'inside_crater_path'; + pic = function(s) + local p = 'images/inside_crater_path.png'; + if here()^where('solarscale') then + p = p .. ';images/characters/solarscale_on_rock.png'; + end; + return p; + end; + disp = 'Кратер, тропинка'; + theme = 'main'; + decor = [[Узкая тропинка, невесть кем протоптанная в густой {#grass|траве}, ведет к центру {#crater|кратера}. Солнечный свет пробивается сквозь листву, образуя причудливый узор из теней повсюду – на стволах {#trees|деревьев}, на траве и на самой тропинке. Далеко впереди виднеется {#tower|башня}. ]]; + exit = function(s, t) + if t^'crater_near_tower' and seen('solarscale', s) then + remove('solarscale', where('solarscale')); + pr [[Я продолжаю свой путь, так и не поговорив с драконессой. Она расправляет крылья и улетает.]]; + end; + end; + way = { + path {"К поляне", "inside_crater_glade"}; + path {"К башне", "crater_near_tower"}; + }; +}: with { + obj { + nam = '#grass'; + act = 'Здесь, лишенная излишков солнечного света, трава гораздо ниже, чем на полянке. Тем не менее она все такого же насыщенного изумрудного цвета. '; + }; + obj { + nam = '#crater'; + act = 'Даже находясь здесь, у самого центра громадной воронки, я не вижу никаких следов падения -- погода и лес делают свое дело и методично заживляют огромный шрам на теле Земли. '; + }; + obj { + nam = '#trees'; + act = 'Высокие деревья с раскидистыми кронами едва качаются от легкого ветерка. В сплетениях корней устраивает свои жилища мелкая живность, а на ветвях сидят всевозможные птицы. '; + }; + obj { + nam = '#tower'; + act = 'Отсюда я уже могу разглядеть черное высокое строение, возвышающееся над лесом. '; + }; + obj { + nam = '#stump'; + dsc = function(s) + pr 'Неподалеку от меня лежит огромный {валун}'; + if seen('solarscale', here()) then + pr(','); + else + pr('.') + end; + end; + act = 'Валун наполовину врос в землю, судя по всему, он лежит здесь очень давно. Должно быть, это один из крупных обломков, оказавшихся здесь после образования кратера. '; + }; + obj { + nam = 'solarscale'; + dsc = 'на котором примостилась небольшая золотая {драконесса}.'; + act = function(s) + walkin('solarscale_dlg'); + end; + } } -obj { - nam = 'map'; - disp = 'Карта'; - disp2 = 'карта'; - disp3 = 'карту'; - inv = function(s) - p [[Очень старая карта, указывающая на место в горах, к западу от деревни. Это совсем недалеко -- минут десять полета. ]]; - _('fly_west_from_village'):enable(); - end; -} - -room { - nam = 'inside_crater_glade'; - pic = 'images/inside_crater_glade.png'; - disp = 'Кратер, полянка'; - theme = 'main'; - onenter = function(s) - if here()^'above_crater' then - p [[Еще не коснувшись земли, я начинаю превращение. Окутанное туманом, мое тело резко устремляется вниз. Через мгновение я оказываюсь на поляне в облике человека. Мои глаза излучают яркий свет, но мне не от кого прятаться -- очки остаются в нагрудном кармане. ]]; - end; - end; - decor = [[Небольшая круглая полянка посреди редкого лиственного {#forest|леса}. В центре ее стоит огромный старый {#oak|дуб} с раскидистой кроной. Изумрудно зеленая {#grass|трава} достигает мне до пояса. Невесть кем протоптанная {#path|тропинка}, ведет к {#tower|башне} в центре {#crater|кратера}. ]]; - way = { - path {"#up", "Взлететь", "above_crater"}; - path {"По тропинке", "inside_crater_path"}; - } -}: with { - obj { - nam = '#forest'; - act = 'В тени раскидистых вязов и стройных буков резвятся белки, зайцы и другие мелкие зверьки. Издалека доносятся стук дятла и пение птиц. '; - }; - obj { - nam = '#oak'; - act = 'Исполинское древо произрастает в самом центре поляны. Легкий ветерок шелестит в его ветвях, покрытых густой зеленой листвой. В огромном дупле спит филин. '; - }; - obj { - nam = '#grass'; - act = 'Дикая трава поднимается высоко, ничем и никем не сдерживаемая. '; - }; - obj { - nam = '#path'; - act = 'Кто-то аккуратно вытоптал в густой траве узенькую тропку, ведущую прямиком к башне. '; - }; - obj { - nam = '#tower'; - act = 'Башня из черного камня возвышается над лесом, словно маяк, установленный для любого, оказавшегося здесь. '; - }; - obj { - nam = '#crater'; - act = 'Находясь здесь, практически в самом центре громадной воронки, я не вижу ничего, что отличало бы этот лес и ландшафт от других, виденных мной. '; - }; +dlg { + nam = 'solarscale_dlg'; + disp = 'Соларскейл'; + theme = 'main'; + pic = 'images/inside_crater_path.png;images/characters/solarscale.png'; + enter = [[Драконесса с сияющими золотом чешуйками и излучающими яркий свет изумрудами глаз сидит на камне, слегка приоткрыв пасть с двумя рядами ровных сверкающих зубов. Крылья ее сложены за спиной, а руки -- скрещены на груди. Она приветливо смотрит на меня. Ее рост составляет всего около метра -- очевидно, она из расы драконов небольшого размера. Драконесса не спускает с меня взгляд, улыбаясь: "Добрый день, путник. Меня зовут Соларскейл. Что привело вас в эти края?"]]; + phr = { + {'#q1', "Могу задать вам тот же вопрос.", 'Соларскейл отвечает: "Я возвращаюсь домой после долгого странствия. Просто остановилась здесь передохнуть". '}; + {'#q2', "Вы не встречали поблизости ничего необычного?", 'Соларскейл приподнимает крылья и задумчиво касается подбородка рукой: "Не припомню ничего интересного... Кроме башни из странного камня. Я не смогла попасть внутрь, но, может быть, у вас получится. Просто следуйте по этой тропинке". '}; + {cond=function(s) return closed('#q2') end, 'Расскажите больше о башне. ', 'Соларскейл продолжает: "Башня выглядит вырезанной из цельного куска камня, я не смогла найти ни единого отверстия, ни единого стыка в ней. Я даже не уверена, что внутри нее в принципе есть что-то кроме камня". '}; + {cond=function(s) return closed('#q2'); end; "Я собираюсь отправиться к башне. Вы не составите мне компанию?", function(s) + walkout(); + solarscale_with_me = true; + remove('solarscale', where('solarscale')); + put('solarscale_ally', here()); + lifeon(_'solarscale_ally'); + return 'Соларскейл поднимается в воздух и отвечает: "Почему нет? Я никуда не спешу". '; + end}; + {function(s) + if not closed('#q2') then + return "Прошу прощения, но у меня нет времени разговаривать. " + else + return 'Благодарю за помощь. Мне пора. '; + end; + end, function(s) + walkout(); + remove('solarscale', where('solarscale')); + return 'Соларскейл поднимается в воздух и прощается: "Что же, тогда я продолжу свой путь. Всего вам доброго".^ Драконесса улетает, оставляя меня одного. '; + end}; + }; } room { - nam = 'inside_crater_path'; - pic = function(s) - local p = 'images/inside_crater_path.png'; - if here()^where('solarscale') then - p = p .. ';images/characters/solarscale_on_rock.png'; - end; - return p; - end; - disp = 'Кратер, тропинка'; - theme = 'main'; - decor = [[Узкая тропинка, невесть кем протоптанная в густой {#grass|траве}, ведет к центру {#crater|кратера}. Солнечный свет пробивается сквозь листву, образуя причудливый узор из теней повсюду – на стволах {#trees|деревьев}, на траве и на самой тропинке. Далеко впереди виднеется {#tower|башня}. ]]; - exit = function(s, t) - if t^'crater_near_tower' and seen('solarscale', s) then - remove('solarscale', where('solarscale')); - pr [[Я продолжаю свой путь, так и не поговорив с драконессой. Она расправляет крылья и улетает.]]; - end; - end; - way = { - path {"К поляне", "inside_crater_glade"}; - path {"К башне", "crater_near_tower"}; - }; -}: with { - obj { - nam = '#grass'; - act = 'Здесь, лишенная излишков солнечного света, трава гораздо ниже, чем на полянке. Тем не менее она все такого же насыщенного изумрудного цвета. '; - }; - obj { - nam = '#crater'; - act = 'Даже находясь здесь, у самого центра громадной воронки, я не вижу никаких следов падения -- погода и лес делают свое дело и методично заживляют огромный шрам на теле Земли. '; - }; - obj { - nam = '#trees'; - act = 'Высокие деревья с раскидистыми кронами едва качаются от легкого ветерка. В сплетениях корней устраивает свои жилища мелкая живность, а на ветвях сидят всевозможные птицы. '; - }; - obj { - nam = '#tower'; - act = 'Отсюда я уже могу разглядеть черное высокое строение, возвышающееся над лесом. '; - }; - obj { - nam = '#stump'; - dsc = function(s) - pr 'Неподалеку от меня лежит огромный {валун}'; - if seen('solarscale', here()) then - pr(','); - else - pr('.') - end; - end; - act = 'Валун наполовину врос в землю, судя по всему, он лежит здесь очень давно. Должно быть, это один из крупных обломков, оказавшихся здесь после образования кратера. '; - }; - obj { - nam = 'solarscale'; - dsc = 'на котором примостилась небольшая золотая {драконесса}.'; - act = function(s) - walkin('solarscale_dlg'); - end; - } + nam = 'crater_near_tower'; + pic = 'images/crater_near_tower.png'; + disp = 'Кратер, у входа в башню'; + theme = 'main'; + decor = [[Тропинка выводит меня к зияющему чернотой проему в одной из стен {#tower|башни}, построенной из незнакомого мне черного материала. {#grass|Трава} подступает к самому подножию башни. Раскидистые кроны {#trees|деревьев} практически полностью закрывают собой небо. Лучи {#sun|солнца} пробиваются сквозь листву и падая на траву, тропинку и стены башни, образуют причудливый узор. ]]; + way = { + path {"По тропинке", "inside_crater_path"}; + path {"В башню", "tower_level_1"}; + }; +}:with { + obj { + nam = '#tower'; + act = 'Основание башни имеет форму правильного шестиугольника. Непонятно, насколько глубоко оно уходит в землю. Гладкая матовая поверхность на ощупь оказывается холодной и гладкой как стекло. Я не вижу и не ощущаю никаких стыков, словно башня вырезана из единого куска породы. Стены ее отвесно поднимаются ввысь, а вершина скрыта за кронами деревьев. '; + }; + obj { + nam = '#grass'; + act = 'Густая зеленая трава произрастает повсюду в этом лесу. '; + }; + obj { + nam = '#trees'; + act = 'Деревья растут практически у самой башни. Они, должно быть, появились здесь уже после ее появления, но кто знает, каким образом эта башня оказалась здесь. '; + }; + obj { + nam = '#sun'; + act = 'Яркое летнее солнце озаряет своими лучами лес. '; + }; } - -dlg { - nam = 'solarscale_dlg'; - disp = 'Соларскейл'; - theme = 'main'; - pic = 'images/inside_crater_path.png;images/characters/solarscale.png'; - enter = [[Драконесса с сияющими золотом чешуйками и излучающими яркий свет изумрудами глаз сидит на камне, слегка приоткрыв пасть с двумя рядами ровных сверкающих зубов. Крылья ее сложены за спиной, а руки -- скрещены на груди. Она приветливо смотрит на меня. Ее рост составляет всего около метра -- очевидно, она из расы драконов небольшого размера. Драконесса не спускает с меня взгляд, улыбаясь: "Добрый день, путник. Меня зовут Соларскейл. Что привело вас в эти края?"]]; - phr = { - {'#q1', "Могу задать вам тот же вопрос.", 'Соларскейл отвечает: "Я возвращаюсь домой после долгого странствия. Просто остановилась здесь передохнуть". '}; - {'#q2', "Вы не встречали поблизости ничего необычного?", 'Соларскейл приподнимает крылья и задумчиво касается подбородка рукой: "Не припомню ничего интересного... Кроме башни из странного камня. Я не смогла попасть внутрь, но, может быть, у вас получится. Просто следуйте по этой тропинке". '}; - {cond=function(s) return closed('#q2') end, 'Расскажите больше о башне. ', 'Соларскейл продолжает: "Башня выглядит вырезанной из цельного куска камня, я не смогла найти ни единого отверстия, ни единого стыка в ней. Я даже не уверена, что внутри нее в принципе есть что-то кроме камня". '}; - {cond=function(s) return closed('#q2'); end; "Я собираюсь отправиться к башне. Вы не составите мне компанию?", function(s) - walkout(); - solarscale_with_me = true; - remove('solarscale', where('solarscale')); - put('solarscale_ally', here()); - lifeon(_'solarscale_ally'); - return 'Соларскейл поднимается в воздух и отвечает: "Почему нет? Я никуда не спешу". '; - end}; - {function(s) - if not closed('#q2') then - return "Прошу прощения, но у меня нет времени разговаривать. " - else - return 'Благодарю за помощь. Мне пора. '; - end; - end, function(s) - walkout(); - remove('solarscale', where('solarscale')); - return 'Соларскейл поднимается в воздух и прощается: "Что же, тогда я продолжу свой путь. Всего вам доброго".^ Драконесса улетает, оставляя меня одного. '; - end}; - }; -} - -room { - nam = 'crater_near_tower'; - pic = 'images/crater_near_tower.png'; - disp = 'Кратер, у входа в башню'; - theme = 'main'; - decor = [[Тропинка выводит меня к зияющему чернотой проему в одной из стен {#tower|башни}, построенной из незнакомого мне черного материала. {#grass|Трава} подступает к самому подножию башни. Раскидистые кроны {#trees|деревьев} практически полностью закрывают собой небо. Лучи {#sun|солнца} пробиваются сквозь листву и падая на траву, тропинку и стены башни, образуют причудливый узор. ]]; - way = { - path {"По тропинке", "inside_crater_path"}; - path {"В башню", "tower_level_1"}; - }; -}:with { - obj { - nam = '#tower'; - act = 'Основание башни имеет форму правильного шестиугольника. Непонятно, насколько глубоко оно уходит в землю. Гладкая матовая поверхность на ощупь оказывается холодной и гладкой как стекло. Я не вижу и не ощущаю никаких стыков, словно башня вырезана из единого куска породы. Стены ее отвесно поднимаются ввысь, а вершина скрыта за кронами деревьев. '; - }; - obj { - nam = '#grass'; - act = 'Густая зеленая трава произрастает повсюду в этом лесу. '; - }; - obj { - nam = '#trees'; - act = 'Деревья растут практически у самой башни. Они, должно быть, появились здесь уже после ее появления, но кто знает, каким образом эта башня оказалась здесь. '; - }; - obj { - nam = '#sun'; - act = 'Яркое летнее солнце озаряет своими лучами лес. '; - }; -} diff --git a/locale.lua b/locale.lua --- a/locale.lua +++ b/locale.lua @@ -1,71 +1,71 @@ declare { - language = '' + language = '' } local lang_map = { - ['ru'] = 'ru', - ['by'] = 'ru', - ['uk'] = 'ru' + ['ru'] = 'ru', + ['by'] = 'ru', + ['uk'] = 'ru' } function translate(table, key) - return function() - local lang = language - if lang == '' then - if lang_map[LANG] then - lang = lang_map[LANG]; - else + return function() + local lang = language + if lang == '' then + if lang_map[LANG] then + lang = lang_map[LANG]; + else - lang = 'en'; - end; - end; - if table[key][lang] ~= nil then - return table[key][lang]; - else - return key - end - end; + lang = 'en'; + end; + end; + if table[key][lang] ~= nil then + return table[key][lang]; + else + return key + end + end; end; function translate_now(table, key) - local lang = language - if lang == '' then - if lang_map[LANG] then - lang = lang_map[LANG]; - else - lang = 'en'; - end; - end; - if table[key][lang] ~= nil then - return table[key][lang]; - else - return key; - end + local lang = language + if lang == '' then + if lang_map[LANG] then + lang = lang_map[LANG]; + else + lang = 'en'; + end; + end; + if table[key][lang] ~= nil then + return table[key][lang]; + else + return key; + end end; function set_language(lng) - language = lng; - prefs.language = lng; - prefs:store(); + language = lng; + prefs.language = lng; + prefs:store(); end; function get_language() - if language and language ~= '' then - return language; - elseif lang_map[LANG] then - return lang_map[LANG]; - else - return 'en'; - end; + if language and language ~= '' then + return language; + elseif lang_map[LANG] then + return lang_map[LANG]; + else + return 'en'; + end; end; std.mod_init(function() - prefs:load(); - if prefs.language then - language = prefs.language; - else - prefs.language = ''; - end; + prefs:load(); + if prefs.language then + language = prefs.language; + else + prefs.language = ''; + end; end) diff --git a/main3.lua b/main3.lua --- a/main3.lua +++ b/main3.lua @@ -19,65 +19,65 @@ require "fading" game.act = translate(main_locale, 'empty_act'); game.use = function(s) - local l = { - 'empty_use_1', - 'empty_use_2', - 'empty_use_3', - 'empty_use_4', - 'empty_use_5', - 'empty_use_6', - }; + local l = { + 'empty_use_1', + 'empty_use_2', + 'empty_use_3', + 'empty_use_4', + 'empty_use_5', + 'empty_use_6', + }; - return translate_now(main_locale, l[rnd(#l)]); + return translate_now(main_locale, l[rnd(#l)]); end; game.inv = translate(main_locale, 'empty_inv'); instead.notitle = function() - return here().notitle; + return here().notitle; end; function get_graphic_scale() - local rval = prefs.graphic_scale; - - if not rval then - local w, h = diretheme.get_screen(); - local wsrec = math.floor(w / 800); - rval = math.floor(h / 540); - if wsrec < rval then - rval = wsrec; - end; - - if rval < 1 then - rval = 1; - end; - end; - - return rval; + local rval = prefs.graphic_scale; + + if not rval then + local w, h = diretheme.get_screen(); + local wsrec = math.floor(w / 800); + rval = math.floor(h / 540); + if wsrec < rval then + rval = wsrec; + end; + + if rval < 1 then + rval = 1; + end; + end; + + return rval; end; function get_font_scale() - local rval = prefs.font_scale; - if not rval then - rval = get_graphic_scale() * 100; - end; - - return rval; + local rval = prefs.font_scale; + if not rval then + rval = get_graphic_scale() * 100; + end; + + return rval; end; function get_inventory_font_scale() - local rval = prefs.inventory_scale; - if not rval then - rval = get_font_scale(); - end; - return rval; + local rval = prefs.inventory_scale; + if not rval then + rval = get_font_scale(); + end; + return rval; end; instead.nosave = function() - return here().nosave + return here().nosave end instead.noautosave = function() - return here().noautosave + return here().noautosave end fmt.para = true; @@ -85,39 +85,39 @@ std.strip_call = false; std.phrase_show = false; declare { - current_theme = false, - sounds = { - ['bubble'] = snd.new('sound/bubble.ogg'); - ['potion'] = snd.new('sound/potion.ogg'); - ['error_beep'] = snd.new('sound/error_beep.ogg'); - ['long_beep'] = snd.new('sound/long_beep.ogg'); - ['short_beep'] = snd.new('sound/short_beep.ogg'); - ['note_c'] = snd.new('sound/c.ogg'); - ['note_d'] = snd.new('sound/d.ogg'); - ['note_e'] = snd.new('sound/e.ogg'); - ['note_f'] = snd.new('sound/f.ogg'); - ['note_g'] = snd.new('sound/g.ogg'); - ['note_a'] = snd.new('sound/a.ogg'); - ['note_b'] = snd.new('sound/b.ogg'); - ['wind_gust_1'] = snd.new('sound/wind_blow_1.ogg'); - ['wind_gust_2'] = snd.new('sound/wind_blow_2.ogg'); - ['wind_gust_3'] = snd.new('sound/wind_blow_3.ogg'); - ['open_door'] = snd.new('sound/open_door.ogg'); - ['pc_startup'] = snd.new('sound/pc_startup.ogg'); - ['keyboard1'] = snd.new('sound/keyboard1.ogg'); - ['keyboard2'] = snd.new('sound/keyboard2.ogg'); - ['keyboard3'] = snd.new('sound/keyboard3.ogg'); - ['keyboard4'] = snd.new('sound/keyboard4.ogg'); - ['keyboard5'] = snd.new('sound/keyboard5.ogg'); - }, - gusts = { - 'wind_gust_1'; - 'wind_gust_2'; - 'wind_gust_3'; - }, - menu_sprites = { - }, - in_game = false + current_theme = false, + sounds = { + ['bubble'] = snd.new('sound/bubble.ogg'); + ['potion'] = snd.new('sound/potion.ogg'); + ['error_beep'] = snd.new('sound/error_beep.ogg'); + ['long_beep'] = snd.new('sound/long_beep.ogg'); + ['short_beep'] = snd.new('sound/short_beep.ogg'); + ['note_c'] = snd.new('sound/c.ogg'); + ['note_d'] = snd.new('sound/d.ogg'); + ['note_e'] = snd.new('sound/e.ogg'); + ['note_f'] = snd.new('sound/f.ogg'); + ['note_g'] = snd.new('sound/g.ogg'); + ['note_a'] = snd.new('sound/a.ogg'); + ['note_b'] = snd.new('sound/b.ogg'); + ['wind_gust_1'] = snd.new('sound/wind_blow_1.ogg'); + ['wind_gust_2'] = snd.new('sound/wind_blow_2.ogg'); + ['wind_gust_3'] = snd.new('sound/wind_blow_3.ogg'); + ['open_door'] = snd.new('sound/open_door.ogg'); + ['pc_startup'] = snd.new('sound/pc_startup.ogg'); + ['keyboard1'] = snd.new('sound/keyboard1.ogg'); + ['keyboard2'] = snd.new('sound/keyboard2.ogg'); + ['keyboard3'] = snd.new('sound/keyboard3.ogg'); + ['keyboard4'] = snd.new('sound/keyboard4.ogg'); + ['keyboard5'] = snd.new('sound/keyboard5.ogg'); + }, + gusts = { + 'wind_gust_1'; + 'wind_gust_2'; + 'wind_gust_3'; + }, + menu_sprites = { + }, + in_game = false } include "tutorial" @@ -128,1789 +128,1789 @@ include "forest" include "ending" function get_sprite(path) - local s = diretheme.get_scale(); - - if not menu_sprites[path] then - menu_sprites[path] = pixels.new(path):scale(s, s):sprite(); - end; - - return menu_sprites[path]; + local s = diretheme.get_scale(); + + if not menu_sprites[path] then + menu_sprites[path] = pixels.new(path):scale(s, s):sprite(); + end; + + return menu_sprites[path]; end; function stop_menu() - D {'bgframe'}; - D {'background'}; - D {'title'}; + D {'bgframe'}; + D {'background'}; + D {'title'}; end; game.ondecor = function(s, name, press, x, y, btn) - if press then - if name == 'settings_open' then - in_game = true; - walk('intro_settings'); - return true; - end; - end; - return false; + if press then + if name == 'settings_open' then + in_game = true; + walk('intro_settings'); + return true; + end; + end; + return false; end; game.afterwalk = function() - dprint(from().nam, '->', here().nam); + dprint(from().nam, '->', here().nam); - if from().themeDispose then - from():themeDispose(); - end; + if from().themeDispose then + from():themeDispose(); + end; - if here().themeInit then - here():themeInit(); - end; - - if here().theme ~= nil and here().theme ~= current_theme then - dprint('Switch theme', current_theme, '->', here().theme); - set_theme(std.call(here(), 'theme')); - end; + if here().themeInit then + here():themeInit(); + end; + + if here().theme ~= nil and here().theme ~= current_theme then + dprint('Switch theme', current_theme, '->', here().theme); + set_theme(std.call(here(), 'theme')); + end; end; function cat_list(list, sep) - local rval; + local rval; - if sep == nil then - sep = ''; - end; + if sep == nil then + sep = ''; + end; - for i, v in ipairs(list) do - if rval then - rval = rval .. sep .. v; - else - rval = v; - end; - end; + for i, v in ipairs(list) do + if rval then + rval = rval .. sep .. v; + else + rval = v; + end; + end; - return rval; + return rval; end; function init_menu(with_text, buttons) - local scale = diretheme.get_scale(); - - local w = 960 * scale; - local h = 600 * scale; - local sw, sh = diretheme.get_screen(); - local ox = math.floor((sw - w) / 2); - local oy = math.floor((sh - h) / 2) - - local button_dy = 0; - local button_dx = 0; - if sh < 520 * scale then - button_dy = -50; - button_dx = 20; - end; - - local btop = 515; - - if #buttons == 5 then - btop = 435; - end; - - print(sh); - if sh <= 560 * scale then - btop = btop - 20; - end; - - if #buttons == 1 then - D { - buttons[1], - 'img', - get_sprite('images/title/' .. buttons[1] .. '.' .. get_language() .. '.png'), - x=ox + 398 * scale, - y=oy + (btop + button_dy) * scale, - click=true - }; - else - D { - buttons[1], - 'img', - get_sprite('images/title/' .. buttons[1] .. '.' .. get_language() .. '.png'), - x=ox + (157 + button_dx) * scale, - y=oy + (btop + button_dy) * scale, - click=true - }; - D { - buttons[2], - 'img', - get_sprite('images/title/' .. buttons[2] .. '.' .. get_language() .. '.png'), - x=ox + 398 * scale, - y=oy + (btop + button_dy) * scale, - click=true - }; - D { - buttons[3], - 'img', - get_sprite('images/title/' .. buttons[3] .. '.' .. get_language() .. '.png'), - x=ox + (639 - button_dx) * scale, - y=oy + (btop + button_dy) * scale, - click=true - }; - end; - - if #buttons == 5 then - btop = btop + 80 - D { - buttons[4], - 'img', - get_sprite('images/title/' .. buttons[4] .. '.' .. get_language() .. '.png'), - x=ox + (278 + button_dx / 2) * scale, - y=oy + (btop + button_dy) * scale, - click=true - }; - - D { - buttons[5], - 'img', - get_sprite('images/title/' .. buttons[5] .. '.' .. get_language() .. '.png'), - x=ox + (519 - button_dx / 2) * scale, - y=oy + (btop + button_dy) * scale, - click=true - }; - end; - - local bgframe_pixels = pixels.new('images/main_theme/text_bg.png'); - local tbg, tbg_slice; - tbg, tbg_slice = dire_slice_9(bgframe_pixels, { - x = 9, - y = 6, - w = 96, - h = 96 - }); - - local bgframe = pixels.new(978, 612); - dire_draw_9(tbg, bgframe, {x = 0; y = 0; w = 978; h = 612}, {parts=tbg_slice}); - D {'bgframe', 'img', bgframe:scale(scale, scale):sprite(), x=ox - 9 * scale, y=oy - 6 * scale, w=w + 18 * scale, h=h + 12 * scale, background=true, z=2}; - - if not D('background') then - D {'background', 'img', get_sprite('images/title/bg_animate.png'), x=ox, y=oy, w=w, h=h, frames=16, z=1, delay=200, animated=true, background=true}; - end; - if not D('title') then - D {'title', 'img', get_sprite('images/title/title.png'), x=ox + 230 * scale, y=oy + 88 * scale, z=0}; - end; - - if with_text then - D {'textbg', 'img', get_sprite('images/title/text_background.png'), x=ox + 180 * scale, y=oy + (126 + button_dy) * scale}; - if sh < 520 * scale then - D {'title'} - else - D('title').y = oy + 40 * scale; - end; - else - D('title').y = oy + 88 * scale; - end; - - timer:set(100); + local scale = diretheme.get_scale(); + + local w = 960 * scale; + local h = 600 * scale; + local sw, sh = diretheme.get_screen(); + local ox = math.floor((sw - w) / 2); + local oy = math.floor((sh - h) / 2) + + local button_dy = 0; + local button_dx = 0; + if sh < 520 * scale then + button_dy = -50; + button_dx = 20; + end; + + local btop = 515; + + if #buttons == 5 then + btop = 435; + end; + + print(sh); + if sh <= 560 * scale then + btop = btop - 20; + end; + + if #buttons == 1 then + D { + buttons[1], + 'img', + get_sprite('images/title/' .. buttons[1] .. '.' .. get_language() .. '.png'), + x=ox + 398 * scale, + y=oy + (btop + button_dy) * scale, + click=true + }; + else + D { + buttons[1], + 'img', + get_sprite('images/title/' .. buttons[1] .. '.' .. get_language() .. '.png'), + x=ox + (157 + button_dx) * scale, + y=oy + (btop + button_dy) * scale, + click=true + }; + D { + buttons[2], + 'img', + get_sprite('images/title/' .. buttons[2] .. '.' .. get_language() .. '.png'), + x=ox + 398 * scale, + y=oy + (btop + button_dy) * scale, + click=true + }; + D { + buttons[3], + 'img', + get_sprite('images/title/' .. buttons[3] .. '.' .. get_language() .. '.png'), + x=ox + (639 - button_dx) * scale, + y=oy + (btop + button_dy) * scale, + click=true + }; + end; + + if #buttons == 5 then + btop = btop + 80 + D { + buttons[4], + 'img', + get_sprite('images/title/' .. buttons[4] .. '.' .. get_language() .. '.png'), + x=ox + (278 + button_dx / 2) * scale, + y=oy + (btop + button_dy) * scale, + click=true + }; + + D { + buttons[5], + 'img', + get_sprite('images/title/' .. buttons[5] .. '.' .. get_language() .. '.png'), + x=ox + (519 - button_dx / 2) * scale, + y=oy + (btop + button_dy) * scale, + click=true + }; + end; + + local bgframe_pixels = pixels.new('images/main_theme/text_bg.png'); + local tbg, tbg_slice; + tbg, tbg_slice = dire_slice_9(bgframe_pixels, { + x = 9, + y = 6, + w = 96, + h = 96 + }); + + local bgframe = pixels.new(978, 612); + dire_draw_9(tbg, bgframe, {x = 0; y = 0; w = 978; h = 612}, {parts=tbg_slice}); + D {'bgframe', 'img', bgframe:scale(scale, scale):sprite(), x=ox - 9 * scale, y=oy - 6 * scale, w=w + 18 * scale, h=h + 12 * scale, background=true, z=2}; + + if not D('background') then + D {'background', 'img', get_sprite('images/title/bg_animate.png'), x=ox, y=oy, w=w, h=h, frames=16, z=1, delay=200, animated=true, background=true}; + end; + if not D('title') then + D {'title', 'img', get_sprite('images/title/title.png'), x=ox + 230 * scale, y=oy + 88 * scale, z=0}; + end; + + if with_text then + D {'textbg', 'img', get_sprite('images/title/text_background.png'), x=ox + 180 * scale, y=oy + (126 + button_dy) * scale}; + if sh < 520 * scale then + D {'title'} + else + D('title').y = oy + 40 * scale; + end; + else + D('title').y = oy + 88 * scale; + end; + + timer:set(100); end; room { - nam = 'main'; - notitle = true; - nosave = true; - noautosave = true; - noinv = true; - nofading = true; - disp = ''; - theme = 'menu'; - onenter = function(s) - in_game = false; - end; - themeInit = function(s) - init_menu(false, {'start', 'load', 'about', 'settings', 'quit'}); - end; - themeDispose = function(s) - D {'start'}; - D {'load'}; - D {'about'}; - D {'settings'}; - D {'quit'}; - timer:stop(); - end; - ondecor = function(s, name, press, x, y, btn) - if press then - if name == 'start' then - walk('intro_start'); - return true; - elseif name == 'load' then - instead.menu('load'); - return true; - elseif name == 'about' then - walk('intro_info'); - return true; - elseif name == 'settings' then - walk('intro_settings'); - return true; - elseif name == 'quit' then - instead.menu('exit'); - return true; - end; - end; - return false; - end; - enter = function(s) - snd.music('sound/bgm_intro.ogg'); - end; + nam = 'main'; + notitle = true; + nosave = true; + noautosave = true; + noinv = true; + nofading = true; + disp = ''; + theme = 'menu'; + onenter = function(s) + in_game = false; + end; + themeInit = function(s) + init_menu(false, {'start', 'load', 'about', 'settings', 'quit'}); + end; + themeDispose = function(s) + D {'start'}; + D {'load'}; + D {'about'}; + D {'settings'}; + D {'quit'}; + timer:stop(); + end; + ondecor = function(s, name, press, x, y, btn) + if press then + if name == 'start' then + walk('intro_start'); + return true; + elseif name == 'load' then + instead.menu('load'); + return true; + elseif name == 'about' then + walk('intro_info'); + return true; + elseif name == 'settings' then + walk('intro_settings'); + return true; + elseif name == 'quit' then + instead.menu('exit'); + return true; + end; + end; + return false; + end; + enter = function(s) + snd.music('sound/bgm_intro.ogg'); + end; } room { - nam = 'intro_start'; - notitle = true; - nosave = true; - noautosave = true; - noinv = true; - nofading = true; - disp = ''; - theme = 'menu'; - themeInit = function(s) - init_menu(true, {'back', 'tutorial', 'start'}); - end; - themeDispose = function(s) - D {'back'}; - D {'tutorial'}; - D {'start'}; - D {'textbg'}; - timer:stop(); - end; - ondecor = function(s, name, press, x, y, btn) - if press then - if name == 'start' then - walk('above_forest'); - in_game = true; - return true; - elseif name == 'tutorial' then - walk('tutorial_start'); - in_game = true; - return true; - elseif name == 'back' then - walk('main'); - return true; - end; - end; - return false; - end; - dsc = translate(menu_locale, 'intro'); + nam = 'intro_start'; + notitle = true; + nosave = true; + noautosave = true; + noinv = true; + nofading = true; + disp = ''; + theme = 'menu'; + themeInit = function(s) + init_menu(true, {'back', 'tutorial', 'start'}); + end; + themeDispose = function(s) + D {'back'}; + D {'tutorial'}; + D {'start'}; + D {'textbg'}; + timer:stop(); + end; + ondecor = function(s, name, press, x, y, btn) + if press then + if name == 'start' then + walk('above_forest'); + in_game = true; + return true; + elseif name == 'tutorial' then + walk('tutorial_start'); + in_game = true; + return true; + elseif name == 'back' then + walk('main'); + return true; + end; + end; + return false; + end; + dsc = translate(menu_locale, 'intro'); } room { - nam = 'intro_info'; - notitle = true; - nosave = true; - noautosave = true; - noinv = true; - nofading = true; - disp = ''; - theme = 'menu'; - themeInit = function(s) - init_menu(true, {'back'}); - end; - themeDispose = function(s) - D {'start'}; - D {'back'}; - D {'settings'}; - D {'textbg'}; - timer:stop(); - end; - ondecor = function(s, name, press, x, y, btn) - if press then - if name == 'back' then - if in_game then - walk('menu'); - else - walk('main'); - end; - return true; - end; - end; - return false; - end; - decor = function(s) - return translate_now(menu_locale, 'credits_author') .. ': Khaelenmore Thaal^' .. - translate_now(menu_locale, 'credits_art') .. ': Sabra Naikomy^' .. - translate_now(menu_locale, 'credits_music') .. ': Khaelenmore Thaal^' .. - translate_now(menu_locale, 'credits_engine') .. ': INSTEAD ' .. translate_now(menu_locale, 'credits_engine_author') .. ' {$link https://instead.hugeping.ru/}^' .. - translate_now(menu_locale, 'credits_sounds') .. ': {$link https://freesound.org/} CC-0^' .. - translate_now(menu_locale, 'credits_fonts') .. ': VileR {$link https://int10h.org/oldschool-pc-fonts/} CC-BY-SA 4.0^' .. - translate_now(menu_locale, 'credits_thanks') .. ':'; - end; + nam = 'intro_info'; + notitle = true; + nosave = true; + noautosave = true; + noinv = true; + nofading = true; + disp = ''; + theme = 'menu'; + themeInit = function(s) + init_menu(true, {'back'}); + end; + themeDispose = function(s) + D {'start'}; + D {'back'}; + D {'settings'}; + D {'textbg'}; + timer:stop(); + end; + ondecor = function(s, name, press, x, y, btn) + if press then + if name == 'back' then + if in_game then + walk('menu'); + else + walk('main'); + end; + return true; + end; + end; + return false; + end; + decor = function(s) + return translate_now(menu_locale, 'credits_author') .. ': Khaelenmore Thaal^' .. + translate_now(menu_locale, 'credits_art') .. ': Sabra Naikomy^' .. + translate_now(menu_locale, 'credits_music') .. ': Khaelenmore Thaal^' .. + translate_now(menu_locale, 'credits_engine') .. ': INSTEAD ' .. translate_now(menu_locale, 'credits_engine_author') .. ' {$link https://instead.hugeping.ru/}^' .. + translate_now(menu_locale, 'credits_sounds') .. ': {$link https://freesound.org/} CC-0^' .. + translate_now(menu_locale, 'credits_fonts') .. ': VileR {$link https://int10h.org/oldschool-pc-fonts/} CC-BY-SA 4.0^' .. + translate_now(menu_locale, 'credits_thanks') .. ':'; + end; } obj { - nam = 'empty'; - dsc = '^'; + nam = 'empty'; + dsc = '^'; } function format_settings(name, value) - return fmt.tab('50%', 'center') .. fmt.nb(translate_now(menu_locale, name)) .. '^{' .. fmt.tab('50%', 'center') .. fmt.nb(value) .. '}^^'; + return fmt.tab('50%', 'center') .. fmt.nb(translate_now(menu_locale, name)) .. '^{' .. fmt.tab('50%', 'center') .. fmt.nb(value) .. '}^^'; end; room { - nam = 'intro_settings'; - nofollow = true; - notitle = true; - nosave = true; - noautosave = true; - noinv = true; - nofading = true; - disp = ''; - theme = 'menu'; - themeInit = function(s) - init_menu(true, {'back'}); - end; - themeDispose = function(s) - D {'start'}; - D {'about'}; - D {'back'}; - D {'textbg'}; - timer:stop(); - end; - ondecor = function(s, name, press, x, y, btn) - if press then - if name == 'back' then - if in_game then - stop_menu(); - walk(from()); - else - walk('main'); - end; - return true; - end; - end; - return false; - end; + nam = 'intro_settings'; + nofollow = true; + notitle = true; + nosave = true; + noautosave = true; + noinv = true; + nofading = true; + disp = ''; + theme = 'menu'; + themeInit = function(s) + init_menu(true, {'back'}); + end; + themeDispose = function(s) + D {'start'}; + D {'about'}; + D {'back'}; + D {'textbg'}; + timer:stop(); + end; + ondecor = function(s, name, press, x, y, btn) + if press then + if name == 'back' then + if in_game then + stop_menu(); + walk(from()); + else + walk('main'); + end; + return true; + end; + end; + return false; + end; }:with { - obj { - nam = '#system_settings'; - dsc = function(s) - return fmt.c(fmt.b('{[' .. translate_now(menu_locale, 'system_settings') .. ']}^^')); - end; - act = function(s) - instead.menu('settings'); - end; - }; - obj { - nam = '#language'; - dsc = function(s) - local l = translate_now(menu_locale, 'auto_option'); - + obj { + nam = '#system_settings'; + dsc = function(s) + return fmt.c(fmt.b('{[' .. translate_now(menu_locale, 'system_settings') .. ']}^^')); + end; + act = function(s) + instead.menu('settings'); + end; + }; + obj { + nam = '#language'; + dsc = function(s) + local l = translate_now(menu_locale, 'auto_option'); + - pn(fmt.c(fmt.b(translate_now(menu_locale, 'language')))); - - local t = ''; - if language == '' then - t = t .. l .. ' | '; - else - t = t .. '{#l_auto|'.. l .. '} | '; - end; - - - if language == 'ru' then - t = t .. 'Русский | '; - else - t = t .. '{#l_ru|Русский} | '; - end; - - if language == 'en' then - t = t .. 'English'; - else - t = t .. '{#l_en|English}'; - end; - - pn(fmt.c(t) .. '^') - end; - }: with { - obj { - nam = '#l_auto'; - act = function(s) - set_language(''); - walk(here()); - end; - }; - obj { - nam = '#l_en'; - act = function(s) - set_language('en'); - walk(here()); - end; - }; - obj { - nam = '#l_ru'; - act = function(s) - set_language('ru'); - walk(here()); - end; - }; - }; - obj { - nam = '#graphics_scale'; - dsc = function(s) - local graphic_scale = get_graphic_scale(); - - pn(fmt.c(fmt.b(translate_now(menu_locale, 'graphic_scale')) .. ' {[' .. translate_now(menu_locale, 'auto_option') .. ']}')) - - local t = ''; - - if graphic_scale > 1 then - t = t .. '{#g_less|<<} '; - else - t = t .. '<< '; - end; + pn(fmt.c(fmt.b(translate_now(menu_locale, 'language')))); + + local t = ''; + if language == '' then + t = t .. l .. ' | '; + else + t = t .. '{#l_auto|'.. l .. '} | '; + end; + + + if language == 'ru' then + t = t .. 'Русский | '; + else + t = t .. '{#l_ru|Русский} | '; + end; + + if language == 'en' then + t = t .. 'English'; + else + t = t .. '{#l_en|English}'; + end; + + pn(fmt.c(t) .. '^') + end; + }: with { + obj { + nam = '#l_auto'; + act = function(s) + set_language(''); + walk(here()); + end; + }; + obj { + nam = '#l_en'; + act = function(s) + set_language('en'); + walk(here()); + end; + }; + obj { + nam = '#l_ru'; + act = function(s) + set_language('ru'); + walk(here()); + end; + }; + }; + obj { + nam = '#graphics_scale'; + dsc = function(s) + local graphic_scale = get_graphic_scale(); + + pn(fmt.c(fmt.b(translate_now(menu_locale, 'graphic_scale')) .. ' {[' .. translate_now(menu_locale, 'auto_option') .. ']}')) + + local t = ''; + + if graphic_scale > 1 then + t = t .. '{#g_less|<<} '; + else + t = t .. '<< '; + end; - local l = translate_now(menu_locale, 'auto_option') .. ' (' .. tostring(graphic_scale * 100) .. '%)'; - - - if prefs.graphic_scale then - l = tostring(graphic_scale * 100) .. '%'; - end; + local l = translate_now(menu_locale, 'auto_option') .. ' (' .. tostring(graphic_scale * 100) .. '%)'; + + + if prefs.graphic_scale then + l = tostring(graphic_scale * 100) .. '%'; + end; - t = t .. l; + t = t .. l; - local w, h = diretheme.get_screen(); - - local wsmax = math.floor(w / 640); - local smax = math.floor(h / 480); - if wsmax < smax then - smax = wsmax; - end; - - if smax < 1 then - smax = 1; - end; - - if graphic_scale < smax then - t = t .. ' {#g_more|>>}'; - else - t = t .. ' >>'; - end; - - pn(fmt.c(t) .. '^'); - end; - act = function(s) - prefs.graphic_scale = false; - prefs:store(); - - set_theme(std.call(here(), 'theme')); - menu_sprites = {}; - here():themeDispose(); - stop_menu(); - here():themeInit(); - walk(here()); - end; - }: with { - obj { - nam = '#g_less'; - act = function(s) - prefs.graphic_scale = get_graphic_scale() - 1; - - prefs:store(); - - set_theme(std.call(here(), 'theme')); - menu_sprites = {}; - here():themeDispose(); - stop_menu(); - here():themeInit(); - walk(here()); - end; - }; - obj { - nam = '#g_more'; - act = function(s) - prefs.graphic_scale = get_graphic_scale() + 1; - - prefs:store(); - - set_theme(std.call(here(), 'theme')); - menu_sprites = {}; - here():themeDispose(); - stop_menu(); - here():themeInit(); - walk(here()); - end; - }; - }; - obj { - nam = '#font_scale'; - dsc = function(s) - local graphic_scale = get_graphic_scale(); - local font_scale = get_font_scale(); - - pn(fmt.c(fmt.b(translate_now(menu_locale, 'font_scale')) .. ' {[' .. translate_now(menu_locale, 'auto_option') .. ']}')); - - local t = ''; - - if font_scale > 50 then - t = t .. '{#f_less|<<} '; - else - t = t .. '<< '; - end; - - if prefs.font_scale then - t = t .. tostring(font_scale) .. '%'; - else - t = t .. translate_now(menu_locale, 'auto_option') .. ' (' .. tostring(font_scale) .. '%)'; - end; - - - if font_scale < graphic_scale * 200 then - t = t .. ' {#f_more|>>}'; - else - t = t .. ' >>'; - end; - - pn(fmt.c(t) .. '^'); - end; - act = function(s) - prefs.font_scale = false; - - prefs:store(); - set_theme(std.call(here(), 'theme')); - walk(here()); - end; - }: with { - obj { - nam = '#f_less'; - act = function(s) - prefs.font_scale = get_font_scale() - 10; - - prefs:store(); - set_theme(std.call(here(), 'theme')); - walk(here()); - end; - }; - obj { - nam = '#f_more'; - act = function(s) - prefs.font_scale = get_font_scale() + 10; - - prefs:store(); - set_theme(std.call(here(), 'theme')); - walk(here()); - end; - }; - }; - obj { - nam = '#inv_font_scale'; - dsc = function(s) - local graphic_scale = get_graphic_scale(); - local font_scale = get_inventory_font_scale(); - - pn(fmt.c(fmt.b(translate_now(menu_locale, 'inventory_scale')) .. ' {[' .. translate_now(menu_locale, 'auto_option') .. ']}')); - - local t = ''; - - if font_scale > 50 then - t = t .. '{#if_less|<<} '; - else - t = t .. '<< '; - end; - - if prefs.inventory_scale then - t = t .. tostring(font_scale) .. '%'; - else - t = t .. translate_now(menu_locale, 'auto_option') .. ' (' .. tostring(font_scale) .. '%)'; - end; - - - if font_scale < graphic_scale * 200 then - t = t .. ' {#if_more|>>}'; - else - t = t .. ' >>'; - end; - - pn(fmt.c(t) .. '^'); - end; - act = function(s) - prefs.inventory_scale = false; - - prefs:store(); - set_theme(std.call(here(), 'theme')); - walk(here()); - end; - }: with { - obj { - nam = '#if_less'; - act = function(s) - prefs.inventory_scale = get_inventory_font_scale() - 10; - - prefs:store(); - set_theme(std.call(here(), 'theme')); - walk(here()); - end; - }; - obj { - nam = '#if_more'; - act = function(s) - prefs.inventory_scale = get_inventory_font_scale() + 10; - - prefs:store(); - set_theme(std.call(here(), 'theme')); - walk(here()); - end; - }; - }; - obj { - nam = '#text_width'; - dsc = function(s) - pn(fmt.c(fmt.b(translate_now(menu_locale, 'text_width')))); - local t = ''; - if prefs.text_width > 40 then - t = t .. '{#fw_less|<<} '; - else - t = t .. '<< '; - end; + local w, h = diretheme.get_screen(); + + local wsmax = math.floor(w / 640); + local smax = math.floor(h / 480); + if wsmax < smax then + smax = wsmax; + end; + + if smax < 1 then + smax = 1; + end; + + if graphic_scale < smax then + t = t .. ' {#g_more|>>}'; + else + t = t .. ' >>'; + end; + + pn(fmt.c(t) .. '^'); + end; + act = function(s) + prefs.graphic_scale = false; + prefs:store(); + + set_theme(std.call(here(), 'theme')); + menu_sprites = {}; + here():themeDispose(); + stop_menu(); + here():themeInit(); + walk(here()); + end; + }: with { + obj { + nam = '#g_less'; + act = function(s) + prefs.graphic_scale = get_graphic_scale() - 1; + + prefs:store(); + + set_theme(std.call(here(), 'theme')); + menu_sprites = {}; + here():themeDispose(); + stop_menu(); + here():themeInit(); + walk(here()); + end; + }; + obj { + nam = '#g_more'; + act = function(s) + prefs.graphic_scale = get_graphic_scale() + 1; + + prefs:store(); + + set_theme(std.call(here(), 'theme')); + menu_sprites = {}; + here():themeDispose(); + stop_menu(); + here():themeInit(); + walk(here()); + end; + }; + }; + obj { + nam = '#font_scale'; + dsc = function(s) + local graphic_scale = get_graphic_scale(); + local font_scale = get_font_scale(); + + pn(fmt.c(fmt.b(translate_now(menu_locale, 'font_scale')) .. ' {[' .. translate_now(menu_locale, 'auto_option') .. ']}')); + + local t = ''; + + if font_scale > 50 then + t = t .. '{#f_less|<<} '; + else + t = t .. '<< '; + end; + + if prefs.font_scale then + t = t .. tostring(font_scale) .. '%'; + else + t = t .. translate_now(menu_locale, 'auto_option') .. ' (' .. tostring(font_scale) .. '%)'; + end; + + + if font_scale < graphic_scale * 200 then + t = t .. ' {#f_more|>>}'; + else + t = t .. ' >>'; + end; + + pn(fmt.c(t) .. '^'); + end; + act = function(s) + prefs.font_scale = false; + + prefs:store(); + set_theme(std.call(here(), 'theme')); + walk(here()); + end; + }: with { + obj { + nam = '#f_less'; + act = function(s) + prefs.font_scale = get_font_scale() - 10; + + prefs:store(); + set_theme(std.call(here(), 'theme')); + walk(here()); + end; + }; + obj { + nam = '#f_more'; + act = function(s) + prefs.font_scale = get_font_scale() + 10; + + prefs:store(); + set_theme(std.call(here(), 'theme')); + walk(here()); + end; + }; + }; + obj { + nam = '#inv_font_scale'; + dsc = function(s) + local graphic_scale = get_graphic_scale(); + local font_scale = get_inventory_font_scale(); + + pn(fmt.c(fmt.b(translate_now(menu_locale, 'inventory_scale')) .. ' {[' .. translate_now(menu_locale, 'auto_option') .. ']}')); + + local t = ''; + + if font_scale > 50 then + t = t .. '{#if_less|<<} '; + else + t = t .. '<< '; + end; + + if prefs.inventory_scale then + t = t .. tostring(font_scale) .. '%'; + else + t = t .. translate_now(menu_locale, 'auto_option') .. ' (' .. tostring(font_scale) .. '%)'; + end; + + + if font_scale < graphic_scale * 200 then + t = t .. ' {#if_more|>>}'; + else + t = t .. ' >>'; + end; + + pn(fmt.c(t) .. '^'); + end; + act = function(s) + prefs.inventory_scale = false; + + prefs:store(); + set_theme(std.call(here(), 'theme')); + walk(here()); + end; + }: with { + obj { + nam = '#if_less'; + act = function(s) + prefs.inventory_scale = get_inventory_font_scale() - 10; + + prefs:store(); + set_theme(std.call(here(), 'theme')); + walk(here()); + end; + }; + obj { + nam = '#if_more'; + act = function(s) + prefs.inventory_scale = get_inventory_font_scale() + 10; + + prefs:store(); + set_theme(std.call(here(), 'theme')); + walk(here()); + end; + }; + }; + obj { + nam = '#text_width'; + dsc = function(s) + pn(fmt.c(fmt.b(translate_now(menu_locale, 'text_width')))); + local t = ''; + if prefs.text_width > 40 then + t = t .. '{#fw_less|<<} '; + else + t = t .. '<< '; + end; - t = t .. tostring(prefs.text_width) .. '%'; - - if prefs.text_width < 100 then - t = t .. ' {#fw_more|>>}'; - else - t = t .. ' >>'; - end; - - pn(fmt.c(t) .. '^'); - end; - act = function(s) - if not prefs.text_width then - prefs.text_width = 100; - end; - - prefs.text_width = prefs.text_width + 20; - - if prefs.text_width > 100 then - prefs.text_width = 40; - end; - - prefs:store(); - - walk(here()); - end; - }: with { - obj { - nam = '#fw_less'; - act = function(s) - prefs.text_width = prefs.text_width - 10; - - prefs:store(); - set_theme(std.call(here(), 'theme')); - walk(here()); - end; - }; - obj { - nam = '#fw_more'; - act = function(s) - prefs.text_width = prefs.text_width + 10; - - prefs:store(); - set_theme(std.call(here(), 'theme')); - walk(here()); - end; - }; - }; - obj { - nam = '#text_alignment'; - dsc = function(s) - pn(fmt.c(fmt.b(translate_now(menu_locale, 'text_alignment')))); - - local t = ''; - - if prefs.text_alignment == 1 then - t = t .. translate_now(menu_locale, 'text_alignment_justify') .. ' | '; - else - t = t .. '{#align_just|' .. translate_now(menu_locale, 'text_alignment_justify') .. '} | '; - end; - - - if prefs.text_alignment == 2 then - t = t .. translate_now(menu_locale, 'text_alignment_left'); - else - t = t .. '{#align_left|' .. translate_now(menu_locale, 'text_alignment_left') .. '}'; - end; - pn(fmt.c(t) .. '^'); - end; - }: with { - obj { - nam = '#align_just'; - act = function(s) - prefs.text_alignment = 1; - - prefs:store(); - set_theme(std.call(here(), 'theme')); - walk(here()); - end; - }; - obj { - nam = '#align_left'; - act = function(s) - prefs.text_alignment = 2; - - prefs:store(); - set_theme(std.call(here(), 'theme')); - walk(here()); - end; - }; - }; - obj { - nam = '#padding'; - dsc = function(s) - pn(fmt.c(fmt.b(translate_now(menu_locale, 'padding')))); - - local t = ''; - - if prefs.text_padding == 1 then - t = t .. translate_now(menu_locale, 'normal') .. ' | '; - else - t = t .. '{#pad_norm|' .. translate_now(menu_locale, 'normal') .. '} | '; - end; - - - if prefs.text_padding == 2 then - t = t .. translate_now(menu_locale, 'extended'); - else - t = t .. '{#pad_large|' .. translate_now(menu_locale, 'extended') .. '}'; - end; - pn(fmt.c(t) .. '^'); - end; - }: with { - obj { - nam = '#pad_norm'; - act = function(s) - prefs.text_padding = 1; - - prefs:store(); - set_theme(std.call(here(), 'theme')); - walk(here()); - end; - }; - obj { - nam = '#pad_large'; - act = function(s) - prefs.text_padding = 2; - - prefs:store(); - set_theme(std.call(here(), 'theme')); - walk(here()); - end; - }; - }; - obj { - nam = '#interval'; - dsc = function(s) - pn(fmt.c(fmt.b(translate_now(menu_locale, 'interval')))); - - local t = ''; - - if prefs.text_interval == 1 then - t = t .. translate_now(menu_locale, 'normal') .. ' | '; - else - t = t .. '{#int_norm|' .. translate_now(menu_locale, 'normal') .. '} | '; - end; - - - if prefs.text_interval == 2 then - t = t .. translate_now(menu_locale, 'extended'); - else - t = t .. '{#int_large|' .. translate_now(menu_locale, 'extended') .. '}'; - end; - pn(fmt.c(t) .. '^'); - end; - }: with { - obj { - nam = '#int_norm'; - act = function(s) - prefs.text_interval = 1; - - prefs:store(); - set_theme(std.call(here(), 'theme')); - walk(here()); - end; - }; - obj { - nam = '#int_large'; - act = function(s) - prefs.text_interval = 2; - - prefs:store(); - set_theme(std.call(here(), 'theme')); - walk(here()); - end; - }; - }; + t = t .. tostring(prefs.text_width) .. '%'; + + if prefs.text_width < 100 then + t = t .. ' {#fw_more|>>}'; + else + t = t .. ' >>'; + end; + + pn(fmt.c(t) .. '^'); + end; + act = function(s) + if not prefs.text_width then + prefs.text_width = 100; + end; + + prefs.text_width = prefs.text_width + 20; + + if prefs.text_width > 100 then + prefs.text_width = 40; + end; + + prefs:store(); + + walk(here()); + end; + }: with { + obj { + nam = '#fw_less'; + act = function(s) + prefs.text_width = prefs.text_width - 10; + + prefs:store(); + set_theme(std.call(here(), 'theme')); + walk(here()); + end; + }; + obj { + nam = '#fw_more'; + act = function(s) + prefs.text_width = prefs.text_width + 10; + + prefs:store(); + set_theme(std.call(here(), 'theme')); + walk(here()); + end; + }; + }; + obj { + nam = '#text_alignment'; + dsc = function(s) + pn(fmt.c(fmt.b(translate_now(menu_locale, 'text_alignment')))); + + local t = ''; + + if prefs.text_alignment == 1 then + t = t .. translate_now(menu_locale, 'text_alignment_justify') .. ' | '; + else + t = t .. '{#align_just|' .. translate_now(menu_locale, 'text_alignment_justify') .. '} | '; + end; + + + if prefs.text_alignment == 2 then + t = t .. translate_now(menu_locale, 'text_alignment_left'); + else + t = t .. '{#align_left|' .. translate_now(menu_locale, 'text_alignment_left') .. '}'; + end; + pn(fmt.c(t) .. '^'); + end; + }: with { + obj { + nam = '#align_just'; + act = function(s) + prefs.text_alignment = 1; + + prefs:store(); + set_theme(std.call(here(), 'theme')); + walk(here()); + end; + }; + obj { + nam = '#align_left'; + act = function(s) + prefs.text_alignment = 2; + + prefs:store(); + set_theme(std.call(here(), 'theme')); + walk(here()); + end; + }; + }; + obj { + nam = '#padding'; + dsc = function(s) + pn(fmt.c(fmt.b(translate_now(menu_locale, 'padding')))); + + local t = ''; + + if prefs.text_padding == 1 then + t = t .. translate_now(menu_locale, 'normal') .. ' | '; + else + t = t .. '{#pad_norm|' .. translate_now(menu_locale, 'normal') .. '} | '; + end; + + + if prefs.text_padding == 2 then + t = t .. translate_now(menu_locale, 'extended'); + else + t = t .. '{#pad_large|' .. translate_now(menu_locale, 'extended') .. '}'; + end; + pn(fmt.c(t) .. '^'); + end; + }: with { + obj { + nam = '#pad_norm'; + act = function(s) + prefs.text_padding = 1; + + prefs:store(); + set_theme(std.call(here(), 'theme')); + walk(here()); + end; + }; + obj { + nam = '#pad_large'; + act = function(s) + prefs.text_padding = 2; + + prefs:store(); + set_theme(std.call(here(), 'theme')); + walk(here()); + end; + }; + }; + obj { + nam = '#interval'; + dsc = function(s) + pn(fmt.c(fmt.b(translate_now(menu_locale, 'interval')))); + + local t = ''; + + if prefs.text_interval == 1 then + t = t .. translate_now(menu_locale, 'normal') .. ' | '; + else + t = t .. '{#int_norm|' .. translate_now(menu_locale, 'normal') .. '} | '; + end; + + + if prefs.text_interval == 2 then + t = t .. translate_now(menu_locale, 'extended'); + else + t = t .. '{#int_large|' .. translate_now(menu_locale, 'extended') .. '}'; + end; + pn(fmt.c(t) .. '^'); + end; + }: with { + obj { + nam = '#int_norm'; + act = function(s) + prefs.text_interval = 1; + + prefs:store(); + set_theme(std.call(here(), 'theme')); + walk(here()); + end; + }; + obj { + nam = '#int_large'; + act = function(s) + prefs.text_interval = 2; + + prefs:store(); + set_theme(std.call(here(), 'theme')); + walk(here()); + end; + }; + }; } room { - nosave = true; - noautosave = true; - theme = 'black'; + nosave = true; + noautosave = true; + theme = 'black'; nam = 'resolution_warning'; - title = translate(menu_locale, 'warning'); + title = translate(menu_locale, 'warning'); decor = translate(menu_locale, 'resolution_warning'); - onenter = stop_menu; + onenter = stop_menu; }: with { - obj { - nam = '#sysset'; - dsc = function(s) return '{' .. translate_now(menu_locale, 'system_settings') .. '}'; end; - act = function(s) - instead.menu(); - end; - } + obj { + nam = '#sysset'; + dsc = function(s) return '{' .. translate_now(menu_locale, 'system_settings') .. '}'; end; + act = function(s) + instead.menu(); + end; + } } room { - nosave = true; - noautosave = true; - theme = 'black'; + nosave = true; + noautosave = true; + theme = 'black'; nam = 'theme_warning'; - title = translate(menu_locale, 'warning'); + title = translate(menu_locale, 'warning'); decor = translate(menu_locale, 'theme_warning'); - onenter = stop_menu; + onenter = stop_menu; }: with { - obj { - nam = '#sysset'; - dsc = function(s) return '{' .. translate_now(menu_locale, 'system_settings') .. '}'; end; - act = function(s) - instead.menu(); - end; - } + obj { + nam = '#sysset'; + dsc = function(s) return '{' .. translate_now(menu_locale, 'system_settings') .. '}'; end; + act = function(s) + instead.menu(); + end; + } } function set_theme(t) - -- 640x480 is the base size - -- Lesser sizes are forbidden - D {'settings_open'}; + -- 640x480 is the base size + -- Lesser sizes are forbidden + D {'settings_open'}; - local width = tonumber(theme.get('scr.w')); - local height = tonumber(theme.get('scr.h')); - - local scale = get_graphic_scale(); - local font_scale = get_font_scale(); - local inv_scale = prefs.inventory_scale; + local width = tonumber(theme.get('scr.w')); + local height = tonumber(theme.get('scr.h')); + + local scale = get_graphic_scale(); + local font_scale = get_font_scale(); + local inv_scale = prefs.inventory_scale; - local max_scale_x = math.floor(width / 640); - local max_scale_y = math.floor(height / 480); - - if max_scale_x > 0 and max_scale_y > 0 then - local max_scale; - if max_scale_x > max_scale_y then - max_scale = max_scale_y; - else - max_scale = max_scale_x; - end; - if scale > max_scale then - scale = max_scale; - prefs.graphic_scale = false; - end; - end; - - if font_scale > 200 * scale then - font_scale = scale; - prefs.font_scale = font_scale * 100 - else - font_scale = font_scale / 100; - end; - - if not inv_scale then - inv_scale = scale; - else - inv_scale = inv_scale / 100; - end; - - local text_align; - - if prefs.text_alignment == 1 then - text_align = 'justify'; - elseif prefs.text_alignment == 2 then - text_align = 'left'; - end; - - local hpadding = 0; - local vpadding = 0; - - if prefs.text_padding == 2 then - hpadding = 24; - vpadding = 12; - end; - - local interval = '1.0'; - - if prefs.text_interval == 2 then - interval = '1.5'; - end; - - local canvas = diretheme.get_canvas(); - - diretheme.set_canvas({rmax = 2, rmin = 1}); - diretheme.set_scale(scale); + local max_scale_x = math.floor(width / 640); + local max_scale_y = math.floor(height / 480); + + if max_scale_x > 0 and max_scale_y > 0 then + local max_scale; + if max_scale_x > max_scale_y then + max_scale = max_scale_y; + else + max_scale = max_scale_x; + end; + if scale > max_scale then + scale = max_scale; + prefs.graphic_scale = false; + end; + end; + + if font_scale > 200 * scale then + font_scale = scale; + prefs.font_scale = font_scale * 100 + else + font_scale = font_scale / 100; + end; + + if not inv_scale then + inv_scale = scale; + else + inv_scale = inv_scale / 100; + end; + + local text_align; + + if prefs.text_alignment == 1 then + text_align = 'justify'; + elseif prefs.text_alignment == 2 then + text_align = 'left'; + end; + + local hpadding = 0; + local vpadding = 0; + + if prefs.text_padding == 2 then + hpadding = 24; + vpadding = 12; + end; + + local interval = '1.0'; + + if prefs.text_interval == 2 then + interval = '1.5'; + end; + + local canvas = diretheme.get_canvas(); + + diretheme.set_canvas({rmax = 2, rmin = 1}); + diretheme.set_scale(scale); - current_theme = t; - fmt.para = true; - if t == 'menu' then - diretheme.set_background('#89C6AE', 255, 'images/main_theme/background.png', {mode=2, scale=true}); - if height < 520 * scale then - diretheme.set_text_area({ - rect = { - ty = -95 + vpadding, - wmax = 538 - hpadding * 2, - hmax = 322 - vpadding * 2, - ay = 0 - }, - text = { - color = '#001008', - size = math.floor(16 * font_scale), - noscale = true - }, - uppos = {ax=1, x = 15, y = 65, ay=-1}; - downpos = {ax=1, x = 15, y = -20, ay=1}; - contentrect = {wf=prefs.text_width / 100}; - bg = ''; - scaleui = 3, - height = interval, - align=text_align - }, true); - else - diretheme.set_text_area({ - rect = { - ty = -10 + vpadding, - wmax = 538 - hpadding * 2, - hmax = 322 - vpadding * 2, - ay = 0 - }, - text = { - color = '#001008', - size = math.floor(16 * font_scale), - noscale = true - }, - uppos = {ax=1, x = 15, y = 65, ay=-1}; - downpos = {ax=1, x = 15, y = -20, ay=1}; - contentrect = {wf=prefs.text_width / 100}; - bg = ''; - scaleui = 3, - height = interval, - align=text_align - }, true); - end; - - diretheme.set_inventory_area({ - rect = { - wmax = 1, - hmax = 1, - x = 0; - y = 0; - ax = -1; - ay = -1; - height = interval, - scaleui = 3 - } - }, true) - diretheme.set_menu({ - button = { - image = 'images/main_theme/menu.png', - options = { - mode = 1, - scale = true - } - }, - buttonrect = { - x = width + 1, - y = 0, - w = 50, - h = 16 - }, - text = { - size = math.floor(15 * font_scale), - noscale = true - }, - height = interval, - scaleui = 3 - }, true); - elseif t == 'main' then - diretheme.set_background('#89C6AE', 255, 'images/main_theme/background.png', {mode=2, scale = true}); - - local image_bg; - if canvas.w < 800 * scale then - image_bg = 'images/main_theme/picture_bg_small.png'; - else - image_bg = 'images/main_theme/picture_bg.png'; - end; - - diretheme.set_image_area({ - leftof='inv', - topof='text', - rect = { - ax = 0, - maxw = 584, - maxh = 265, - minw = 584, - minh = 265 - }, - contentrect = { - ax = 0, - ay = -1, - ty = 11, - wmin = 320, - hmin = 240, - wmax = 320, - hmax = 240 - }, - bg = { - image = image_bg, - options = { - mode = 1, - scale = true - } - }, - mode = 'float' - }, true); - - diretheme.set_text_area({ - leftof='inv', - rect = { - lx = 7, - ty = 266, - rx = 8, - by = 2, - ax = 1, - ay = 1 - }, - contentrect = { - lx = 21 + hpadding, - rx = 21 + hpadding, - ty = 14 + vpadding, - by = 14 + vpadding, - wf=prefs.text_width / 100 - }, - uppos = {ax=1, x = 12, y = 0, ay=-1}, - downpos = {ax=1, x = 12, y = 0, ay=1}, - up = 'images/main_theme/arrow_up.png', - down = 'images/main_theme/arrow_down.png', - bg = { - image = 'images/main_theme/text_bg.png', - options = { - mode = 6, - drawmethod = 2, - slice = { - x = 9, - y = 6, - w = 96, - h = 96 - }, - scale = true - } - }, - text = { - color = '#001008', - link = '#00605D', - alink = '#008070', - size = math.floor(16 * font_scale), - noscale = true - }, - scaleui = 3, - height = interval, - align=text_align - }, true); - diretheme.set_inventory_area({ - rect = { - rx = 2, - y = 2, - wmax = 208, - wmin = 208, - ty = 2, - by = 2, - ax = 1 - }, - contentrect = { - lx = 25, - rx = 25, - ty = 40, - by = 40 - }, - uppos = {ax=1, x = 8, y = 0, ay=-1}, - downpos = {ax=1, x = 8, y = 0, ay=1}, - up = 'images/main_theme/arrow_up.png', - down = 'images/main_theme/arrow_down.png', - bg = { - image = function(tpx, rect) - local top = pixels.new('images/main_theme/inv_top.png'):scale(scale, scale, false); - local mid = pixels.new('images/main_theme/inv_mid.png'):scale(scale, scale, false); - local bottom = pixels.new('images/main_theme/inv_bottom.png'):scale(scale, scale, false); - - dire_draw_tile(mid, tpx, { x=rect.x + 11 * scale, y=rect.y + 10 * scale, w=rect.w - 22 * scale, h = rect.h - 20 * scale}, {}); - dire_draw_center(top, tpx, {x=rect.x, y=rect.y, w=208 * scale, h=60 * scale}); - dire_draw_center(bottom, tpx, {x=rect.x, y=rect.y + rect.h - 60 * scale, w=208 * scale, h=60 * scale}); - end, - options = {scale = true} - }, - text = { - color = '#403426', - link = '#403426', - alink = '#61503A', - size = math.floor(16 * inv_scale), - noscale = true - }, - height = interval, - }, true); - diretheme.set_menu({ - button = { - image = 'images/main_theme/menu.png', - options = { - mode = 1, - scale = true - } - }, - buttonrect = { - wmin = 50, - wmax = 50, - hmin = 16, - hmax = 16, - by = 12, - ay = 1, - rx = 81, - ax = 1 - }, - text = { - size = math.floor(15 * font_scale), - noscale = true - }, - height = interval, - scaleui = 3 - }, true); - D { - 'settings_open', - 'img', - get_sprite('images/main_theme/settings.png'), - x=width - 33 * scale, - y=height - 30 * scale, - click=true, - z=-1 - }; - elseif t == 'tower' then - theme.reset('snd.click'); - diretheme.set_background('#181E37', 255, 'images/tower_theme/background.png', {mode=2, scale=true}); - - local image_bg; - if canvas.w < 800 * scale then - image_bg = 'images/tower_theme/picture_bg_small.png'; - else - image_bg = 'images/tower_theme/picture_bg.png'; - end; - - diretheme.set_image_area({ - leftof='inv', - topof='text', - rect = { - ax = 0, - maxw = 584, - maxh = 258, - minw = 584, - minh = 258 - }, - contentrect = { - ax = 0, - ay = -1, - ty = 12, - wmin = 320, - hmin = 240, - wmax = 320, - hmax = 240 - }, - bg = { - image = image_bg, - options = { - mode = 1, - scale = true - } - }, - mode = 'float' - }, true); - - diretheme.set_text_area({ - leftof='inv', - rect = { - lx = 7, - ty = 266, - rx = 8, - by = 2, - ax = 1, - ay = 1 - }, - contentrect = { - lx = 21 + hpadding, - rx = 21 + hpadding, - ty = 14 + vpadding, - by = 14 + vpadding, - wf=prefs.text_width / 100 - }, - bg = { - image = 'images/tower_theme/text_bg.png', - options = { - mode = 6, - drawmethod = 2, - slice = { - x = 6, - y = 6, - w = 128, - h = 128 - }, - scale = true - } - }, - text = { - color = '#8bbeae', - link = '#abdece', - alink = '#9bcebe', - size = math.floor(16 * font_scale), - noscale = true - }, - up = 'images/tower_theme/arrow_up.png', - down = 'images/tower_theme/arrow_down.png', - uppos = {ax=1, x = 16, y = 0, ay=-1}, - downpos = {ax=1, x = 16, y = 0, ay=1}, - scaleui=3, - align=text_align, - height = interval - }); - diretheme.set_inventory_area({ - rect = { - rx = 2, - y = 2, - wmax = 208, - wmin = 208, - ty = 2, - by = 2, - ax = 1 - }, - contentrect = { - lx = 12, - rx = 16, - ty = 10, - by = 40 - }, - bg = { - image = 'images/tower_theme/inv_bg.png', - options = { - mode = 6, - drawmethod = 2, - slice = { - x = 7, - y = 11, - w = 194, - h = 38 - }, - scale = true - } - }, - text = { - color = '#6b9e8e', - link = '#9bcebe', - alink = '#Bbeede', - size = math.floor(16 * inv_scale), - noscale = true - }, - height = interval, - up = 'images/tower_theme/arrow_up.png', - down = 'images/tower_theme/arrow_down.png', - uppos = {ax=1, x = 8, y = 0, ay=-1}, - downpos = {ax=1, x = 8, y = 0, ay=1} - }); - diretheme.set_menu({ - button = { - image = 'images/tower_theme/menu.png', - options = { - mode = 1, - scale = true - }, - }, - buttonrect = { - wmin = 50, - wmax = 50, - hmin = 16, - hmax = 16, - by = 20, - ay = 1, - rx = 81, - ax = 1 - }, - text = { - size = math.floor(15 * font_scale), - noscale = true - }, - height = interval, - scaleui = 3 - }); - - D { - 'settings_open', - 'img', - get_sprite('images/tower_theme/settings.png'), - x=width - 35 * scale, - y=height - 37 * scale, - click=true, - z=-1 - }; - elseif t == 'terminal' then - theme.set('snd.click', ''); - - local px = pixels.new(width / scale, height / scale); - local src = pixels.new('images/terminal/table_tiles.png'); - - local tabletop = height - 422 - if tabletop < 335 then - tabletop = 335; - end; - - dire_draw_tile(src, px, { - w = width, - h = 422, - x = 0, - y = tabletop - }, {offset = -1}); - - diretheme.set_background('#181E37', 255, px, {mode=1}); - diretheme.set_image_area({ - rect = { - lx = width + 1, - ax = 1, - wmax = 584, - hmax = 258, - wmin = 584, - hmin = 258 - }, - bg = {}, - mode = 'float' - }, true); - - local ty - if here().ticks ~= nil and here().ticks < 128 and here().graphical then - ty = 72 - else - ty = 2 - end; - - diretheme.set_text_area({ - rect = { - ty = 0, - by = 189, - wmin = 808, - hmin = 568, - wmax = 808, - hmax = 568, - ax = 0, - ay = 1 - }, - contentrect = { - wmax = 569, - hmax = 390, - ty = ty, - ax = 0, - ay = -2, - dx = -16 - }, - bg = { - image = 'images/terminal/bg_text.png', - options = { - mode = 1, - scale = true - } - }, - text = { - font = 'fonts/vga.ttf', - color = '#D0FFFF', - link = '#abdece', - alink = '#9bcebe', - size = 16 - }, - }, true); - diretheme.set_inventory_area({ - rect = { - lx = width + 1, - y = 2, - wmax = 208, - wmin = 208, - ty = 2, - by = 2, - ax = 1 - }, - contentrect = { - lx = 12, - rx = 12, - ty = 10, - by = 40 - }, - bg = {}, - }, true); - diretheme.set_menu({ - button = { - image = 'images/tower_theme/menu.png', - options = { - mode = 1 - } - }, - buttonrect = { - x = width + 1, - y = 0, - w = 50, - h = 16 - }, - text = { - size = math.floor(15 * font_scale), - noscale = true - }, - scaleui = 3 - }, true); - elseif t == 'ending_outside' then - diretheme.set_background('#89C6AE', 255, 'images/main_theme/background.png', {mode=2, scale=true}); - - diretheme.set_text_area({ - rect = { - lx = 24, - rx = 24, - wmax = 600, - hmax = 160, - by = 24, - ay = 1 - }, - contentrect = { - lx = 18 + hpadding, - rx = 18 + hpadding, - ty = 14 + vpadding, - by = 14 + vpadding, - wf = prefs.text_width / 100 - }, - text = { - color = '#001008', - size = math.floor(16 * font_scale), - noscale = true - }, - text = { - color = '#001008', - link = '#00605D', - alink = '#008070', - size = math.floor(16 * font_scale), - noscale = true - }, - uppos = {ax=1, x = 12, y = 0, ay=-1}; - downpos = {ax=1, x = 12, y = 0, ay=1}; - bg = ''; - scaleui = 3, - height = interval, - align=text_align, - bg = { - image = 'images/main_theme/text_bg.png', - options = { - mode = 6, - drawmethod = 2, - slice = { - x = 9, - y = 6, - w = 96, - h = 96 - }, - scale = true - } - }, - }, true); - - diretheme.set_inventory_area({ - rect = { - wmax = 1, - hmax = 1, - x = 0; - y = 0; - ax = -1; - ay = -1; - height = interval, - scaleui = 3 - } - }, true) - diretheme.set_menu({ - button = { - image = 'images/main_theme/menu.png', - options = { - mode = 1, - scale = true - } - }, - buttonrect = { - x = width + 1, - y = 0, - w = 50, - h = 16 - }, - text = { - size = math.floor(15 * font_scale), - noscale = true - }, - height = interval, - scaleui = 3 - }, true); - elseif t == 'ending_inside' then - diretheme.set_background('#181E37', 255, 'images/tower_theme/background.png', {mode=2}); - - diretheme.set_text_area({ - rect = { - lx = 24, - rx = 24, - wmax = 600, - hmax = 160, - by = 24, - ay = 1 - }, - contentrect = { - lx = 18 + hpadding, - rx = 18 + hpadding, - ty = 14 + vpadding, - by = 14 + vpadding, - wf = prefs.text_width / 100 - }, - text = { - color = '#001008', - size = math.floor(16 * font_scale), - noscale = true - }, - text = { - color = '#8bbeae', - link = '#abdece', - alink = '#9bcebe', - size = math.floor(16 * font_scale), - noscale = true - }, - uppos = {ax=1, x = 12, y = 0, ay=-1}; - downpos = {ax=1, x = 12, y = 0, ay=1}; - bg = ''; - scaleui = 3, - height = interval, - align=text_align, - bg = { - image = 'images/tower_theme/text_bg.png', - options = { - mode = 6, - drawmethod = 2, - slice = { - x = 6, - y = 6, - w = 128, - h = 128 - }, - scale = true - } - }, - }, true); - - diretheme.set_inventory_area({ - rect = { - wmax = 1, - hmax = 1, - x = 0; - y = 0; - ax = -1; - ay = -1; - height = interval, - scaleui = 3 - } - }, true) - diretheme.set_menu({ - button = { - image = 'images/main_theme/menu.png', - options = { - mode = 1, - scale = true - } - }, - buttonrect = { - x = width + 1, - y = 0, - w = 50, - h = 16 - }, - text = { - size = math.floor(15 * font_scale), - noscale = true - }, - height = interval, - scaleui = 3 - }, true); - elseif t == 'black' then - fmt.para = false; - diretheme.set_background('#000000', 255); - diretheme.set_text_area({ - rect = { - wmax = 600, - hmax = 400, - ax = 0, - ay = 0 - }, - align = 'center'; - text = { - font = 'fonts/vga.ttf', - color = '#D0FFFF', - link = '#abdece', - alink = '#9bcebe', - size = 16 - }, - }, true); - diretheme.set_inventory_area({ - rect = { - wmax = 1, - hmax = 1, - x = 0; - y = 0; - ax = -1; - ay = -1; - height = interval, - scaleui = 3 - } - }, true); - diretheme.set_menu({ - button = { - image = 'images/main_theme/menu.png', - options = { - mode = 1, - scale = true - } - }, - buttonrect = { - x = width + 1, - y = 0, - w = 50, - h = 16 - }, - text = { - size = math.floor(15 * font_scale), - noscale = true - }, - height = interval, - scaleui = 3 - }, true); - end; + current_theme = t; + fmt.para = true; + if t == 'menu' then + diretheme.set_background('#89C6AE', 255, 'images/main_theme/background.png', {mode=2, scale=true}); + if height < 520 * scale then + diretheme.set_text_area({ + rect = { + ty = -95 + vpadding, + wmax = 538 - hpadding * 2, + hmax = 322 - vpadding * 2, + ay = 0 + }, + text = { + color = '#001008', + size = math.floor(16 * font_scale), + noscale = true + }, + uppos = {ax=1, x = 15, y = 65, ay=-1}; + downpos = {ax=1, x = 15, y = -20, ay=1}; + contentrect = {wf=prefs.text_width / 100}; + bg = ''; + scaleui = 3, + height = interval, + align=text_align + }, true); + else + diretheme.set_text_area({ + rect = { + ty = -10 + vpadding, + wmax = 538 - hpadding * 2, + hmax = 322 - vpadding * 2, + ay = 0 + }, + text = { + color = '#001008', + size = math.floor(16 * font_scale), + noscale = true + }, + uppos = {ax=1, x = 15, y = 65, ay=-1}; + downpos = {ax=1, x = 15, y = -20, ay=1}; + contentrect = {wf=prefs.text_width / 100}; + bg = ''; + scaleui = 3, + height = interval, + align=text_align + }, true); + end; + + diretheme.set_inventory_area({ + rect = { + wmax = 1, + hmax = 1, + x = 0; + y = 0; + ax = -1; + ay = -1; + height = interval, + scaleui = 3 + } + }, true) + diretheme.set_menu({ + button = { + image = 'images/main_theme/menu.png', + options = { + mode = 1, + scale = true + } + }, + buttonrect = { + x = width + 1, + y = 0, + w = 50, + h = 16 + }, + text = { + size = math.floor(15 * font_scale), + noscale = true + }, + height = interval, + scaleui = 3 + }, true); + elseif t == 'main' then + diretheme.set_background('#89C6AE', 255, 'images/main_theme/background.png', {mode=2, scale = true}); + + local image_bg; + if canvas.w < 800 * scale then + image_bg = 'images/main_theme/picture_bg_small.png'; + else + image_bg = 'images/main_theme/picture_bg.png'; + end; + + diretheme.set_image_area({ + leftof='inv', + topof='text', + rect = { + ax = 0, + maxw = 584, + maxh = 265, + minw = 584, + minh = 265 + }, + contentrect = { + ax = 0, + ay = -1, + ty = 11, + wmin = 320, + hmin = 240, + wmax = 320, + hmax = 240 + }, + bg = { + image = image_bg, + options = { + mode = 1, + scale = true + } + }, + mode = 'float' + }, true); + + diretheme.set_text_area({ + leftof='inv', + rect = { + lx = 7, + ty = 266, + rx = 8, + by = 2, + ax = 1, + ay = 1 + }, + contentrect = { + lx = 21 + hpadding, + rx = 21 + hpadding, + ty = 14 + vpadding, + by = 14 + vpadding, + wf=prefs.text_width / 100 + }, + uppos = {ax=1, x = 12, y = 0, ay=-1}, + downpos = {ax=1, x = 12, y = 0, ay=1}, + up = 'images/main_theme/arrow_up.png', + down = 'images/main_theme/arrow_down.png', + bg = { + image = 'images/main_theme/text_bg.png', + options = { + mode = 6, + drawmethod = 2, + slice = { + x = 9, + y = 6, + w = 96, + h = 96 + }, + scale = true + } + }, + text = { + color = '#001008', + link = '#00605D', + alink = '#008070', + size = math.floor(16 * font_scale), + noscale = true + }, + scaleui = 3, + height = interval, + align=text_align + }, true); + diretheme.set_inventory_area({ + rect = { + rx = 2, + y = 2, + wmax = 208, + wmin = 208, + ty = 2, + by = 2, + ax = 1 + }, + contentrect = { + lx = 25, + rx = 25, + ty = 40, + by = 40 + }, + uppos = {ax=1, x = 8, y = 0, ay=-1}, + downpos = {ax=1, x = 8, y = 0, ay=1}, + up = 'images/main_theme/arrow_up.png', + down = 'images/main_theme/arrow_down.png', + bg = { + image = function(tpx, rect) + local top = pixels.new('images/main_theme/inv_top.png'):scale(scale, scale, false); + local mid = pixels.new('images/main_theme/inv_mid.png'):scale(scale, scale, false); + local bottom = pixels.new('images/main_theme/inv_bottom.png'):scale(scale, scale, false); + + dire_draw_tile(mid, tpx, { x=rect.x + 11 * scale, y=rect.y + 10 * scale, w=rect.w - 22 * scale, h = rect.h - 20 * scale}, {}); + dire_draw_center(top, tpx, {x=rect.x, y=rect.y, w=208 * scale, h=60 * scale}); + dire_draw_center(bottom, tpx, {x=rect.x, y=rect.y + rect.h - 60 * scale, w=208 * scale, h=60 * scale}); + end, + options = {scale = true} + }, + text = { + color = '#403426', + link = '#403426', + alink = '#61503A', + size = math.floor(16 * inv_scale), + noscale = true + }, + height = interval, + }, true); + diretheme.set_menu({ + button = { + image = 'images/main_theme/menu.png', + options = { + mode = 1, + scale = true + } + }, + buttonrect = { + wmin = 50, + wmax = 50, + hmin = 16, + hmax = 16, + by = 12, + ay = 1, + rx = 81, + ax = 1 + }, + text = { + size = math.floor(15 * font_scale), + noscale = true + }, + height = interval, + scaleui = 3 + }, true); + D { + 'settings_open', + 'img', + get_sprite('images/main_theme/settings.png'), + x=width - 33 * scale, + y=height - 30 * scale, + click=true, + z=-1 + }; + elseif t == 'tower' then + theme.reset('snd.click'); + diretheme.set_background('#181E37', 255, 'images/tower_theme/background.png', {mode=2, scale=true}); + + local image_bg; + if canvas.w < 800 * scale then + image_bg = 'images/tower_theme/picture_bg_small.png'; + else + image_bg = 'images/tower_theme/picture_bg.png'; + end; + + diretheme.set_image_area({ + leftof='inv', + topof='text', + rect = { + ax = 0, + maxw = 584, + maxh = 258, + minw = 584, + minh = 258 + }, + contentrect = { + ax = 0, + ay = -1, + ty = 12, + wmin = 320, + hmin = 240, + wmax = 320, + hmax = 240 + }, + bg = { + image = image_bg, + options = { + mode = 1, + scale = true + } + }, + mode = 'float' + }, true); + + diretheme.set_text_area({ + leftof='inv', + rect = { + lx = 7, + ty = 266, + rx = 8, + by = 2, + ax = 1, + ay = 1 + }, + contentrect = { + lx = 21 + hpadding, + rx = 21 + hpadding, + ty = 14 + vpadding, + by = 14 + vpadding, + wf=prefs.text_width / 100 + }, + bg = { + image = 'images/tower_theme/text_bg.png', + options = { + mode = 6, + drawmethod = 2, + slice = { + x = 6, + y = 6, + w = 128, + h = 128 + }, + scale = true + } + }, + text = { + color = '#8bbeae', + link = '#abdece', + alink = '#9bcebe', + size = math.floor(16 * font_scale), + noscale = true + }, + up = 'images/tower_theme/arrow_up.png', + down = 'images/tower_theme/arrow_down.png', + uppos = {ax=1, x = 16, y = 0, ay=-1}, + downpos = {ax=1, x = 16, y = 0, ay=1}, + scaleui=3, + align=text_align, + height = interval + }); + diretheme.set_inventory_area({ + rect = { + rx = 2, + y = 2, + wmax = 208, + wmin = 208, + ty = 2, + by = 2, + ax = 1 + }, + contentrect = { + lx = 12, + rx = 16, + ty = 10, + by = 40 + }, + bg = { + image = 'images/tower_theme/inv_bg.png', + options = { + mode = 6, + drawmethod = 2, + slice = { + x = 7, + y = 11, + w = 194, + h = 38 + }, + scale = true + } + }, + text = { + color = '#6b9e8e', + link = '#9bcebe', + alink = '#Bbeede', + size = math.floor(16 * inv_scale), + noscale = true + }, + height = interval, + up = 'images/tower_theme/arrow_up.png', + down = 'images/tower_theme/arrow_down.png', + uppos = {ax=1, x = 8, y = 0, ay=-1}, + downpos = {ax=1, x = 8, y = 0, ay=1} + }); + diretheme.set_menu({ + button = { + image = 'images/tower_theme/menu.png', + options = { + mode = 1, + scale = true + }, + }, + buttonrect = { + wmin = 50, + wmax = 50, + hmin = 16, + hmax = 16, + by = 20, + ay = 1, + rx = 81, + ax = 1 + }, + text = { + size = math.floor(15 * font_scale), + noscale = true + }, + height = interval, + scaleui = 3 + }); + + D { + 'settings_open', + 'img', + get_sprite('images/tower_theme/settings.png'), + x=width - 35 * scale, + y=height - 37 * scale, + click=true, + z=-1 + }; + elseif t == 'terminal' then + theme.set('snd.click', ''); + + local px = pixels.new(width / scale, height / scale); + local src = pixels.new('images/terminal/table_tiles.png'); + + local tabletop = height - 422 + if tabletop < 335 then + tabletop = 335; + end; + + dire_draw_tile(src, px, { + w = width, + h = 422, + x = 0, + y = tabletop + }, {offset = -1}); + + diretheme.set_background('#181E37', 255, px, {mode=1}); + diretheme.set_image_area({ + rect = { + lx = width + 1, + ax = 1, + wmax = 584, + hmax = 258, + wmin = 584, + hmin = 258 + }, + bg = {}, + mode = 'float' + }, true); + + local ty + if here().ticks ~= nil and here().ticks < 128 and here().graphical then + ty = 72 + else + ty = 2 + end; + + diretheme.set_text_area({ + rect = { + ty = 0, + by = 189, + wmin = 808, + hmin = 568, + wmax = 808, + hmax = 568, + ax = 0, + ay = 1 + }, + contentrect = { + wmax = 569, + hmax = 390, + ty = ty, + ax = 0, + ay = -2, + dx = -16 + }, + bg = { + image = 'images/terminal/bg_text.png', + options = { + mode = 1, + scale = true + } + }, + text = { + font = 'fonts/vga.ttf', + color = '#D0FFFF', + link = '#abdece', + alink = '#9bcebe', + size = 16 + }, + }, true); + diretheme.set_inventory_area({ + rect = { + lx = width + 1, + y = 2, + wmax = 208, + wmin = 208, + ty = 2, + by = 2, + ax = 1 + }, + contentrect = { + lx = 12, + rx = 12, + ty = 10, + by = 40 + }, + bg = {}, + }, true); + diretheme.set_menu({ + button = { + image = 'images/tower_theme/menu.png', + options = { + mode = 1 + } + }, + buttonrect = { + x = width + 1, + y = 0, + w = 50, + h = 16 + }, + text = { + size = math.floor(15 * font_scale), + noscale = true + }, + scaleui = 3 + }, true); + elseif t == 'ending_outside' then + diretheme.set_background('#89C6AE', 255, 'images/main_theme/background.png', {mode=2, scale=true}); + + diretheme.set_text_area({ + rect = { + lx = 24, + rx = 24, + wmax = 600, + hmax = 160, + by = 24, + ay = 1 + }, + contentrect = { + lx = 18 + hpadding, + rx = 18 + hpadding, + ty = 14 + vpadding, + by = 14 + vpadding, + wf = prefs.text_width / 100 + }, + text = { + color = '#001008', + size = math.floor(16 * font_scale), + noscale = true + }, + text = { + color = '#001008', + link = '#00605D', + alink = '#008070', + size = math.floor(16 * font_scale), + noscale = true + }, + uppos = {ax=1, x = 12, y = 0, ay=-1}; + downpos = {ax=1, x = 12, y = 0, ay=1}; + bg = ''; + scaleui = 3, + height = interval, + align=text_align, + bg = { + image = 'images/main_theme/text_bg.png', + options = { + mode = 6, + drawmethod = 2, + slice = { + x = 9, + y = 6, + w = 96, + h = 96 + }, + scale = true + } + }, + }, true); + + diretheme.set_inventory_area({ + rect = { + wmax = 1, + hmax = 1, + x = 0; + y = 0; + ax = -1; + ay = -1; + height = interval, + scaleui = 3 + } + }, true) + diretheme.set_menu({ + button = { + image = 'images/main_theme/menu.png', + options = { + mode = 1, + scale = true + } + }, + buttonrect = { + x = width + 1, + y = 0, + w = 50, + h = 16 + }, + text = { + size = math.floor(15 * font_scale), + noscale = true + }, + height = interval, + scaleui = 3 + }, true); + elseif t == 'ending_inside' then + diretheme.set_background('#181E37', 255, 'images/tower_theme/background.png', {mode=2}); + + diretheme.set_text_area({ + rect = { + lx = 24, + rx = 24, + wmax = 600, + hmax = 160, + by = 24, + ay = 1 + }, + contentrect = { + lx = 18 + hpadding, + rx = 18 + hpadding, + ty = 14 + vpadding, + by = 14 + vpadding, + wf = prefs.text_width / 100 + }, + text = { + color = '#001008', + size = math.floor(16 * font_scale), + noscale = true + }, + text = { + color = '#8bbeae', + link = '#abdece', + alink = '#9bcebe', + size = math.floor(16 * font_scale), + noscale = true + }, + uppos = {ax=1, x = 12, y = 0, ay=-1}; + downpos = {ax=1, x = 12, y = 0, ay=1}; + bg = ''; + scaleui = 3, + height = interval, + align=text_align, + bg = { + image = 'images/tower_theme/text_bg.png', + options = { + mode = 6, + drawmethod = 2, + slice = { + x = 6, + y = 6, + w = 128, + h = 128 + }, + scale = true + } + }, + }, true); + + diretheme.set_inventory_area({ + rect = { + wmax = 1, + hmax = 1, + x = 0; + y = 0; + ax = -1; + ay = -1; + height = interval, + scaleui = 3 + } + }, true) + diretheme.set_menu({ + button = { + image = 'images/main_theme/menu.png', + options = { + mode = 1, + scale = true + } + }, + buttonrect = { + x = width + 1, + y = 0, + w = 50, + h = 16 + }, + text = { + size = math.floor(15 * font_scale), + noscale = true + }, + height = interval, + scaleui = 3 + }, true); + elseif t == 'black' then + fmt.para = false; + diretheme.set_background('#000000', 255); + diretheme.set_text_area({ + rect = { + wmax = 600, + hmax = 400, + ax = 0, + ay = 0 + }, + align = 'center'; + text = { + font = 'fonts/vga.ttf', + color = '#D0FFFF', + link = '#abdece', + alink = '#9bcebe', + size = 16 + }, + }, true); + diretheme.set_inventory_area({ + rect = { + wmax = 1, + hmax = 1, + x = 0; + y = 0; + ax = -1; + ay = -1; + height = interval, + scaleui = 3 + } + }, true); + diretheme.set_menu({ + button = { + image = 'images/main_theme/menu.png', + options = { + mode = 1, + scale = true + } + }, + buttonrect = { + x = width + 1, + y = 0, + w = 50, + h = 16 + }, + text = { + size = math.floor(15 * font_scale), + noscale = true + }, + height = interval, + scaleui = 3 + }, true); + end; end; function start(load) - dprint('start', load); - local w, h = diretheme.get_screen(); - local name = theme.name(); - if here() ~= _'theme_warning' and here() ~= _'resolution_warning' then - if name ~= '.' then - walkin('theme_warning'); - end; - - if w < 640 or h < 480 then - walkin('resolution_warning'); - end; - end; - - diretheme.set_cursor({ - x = 2, - y = 2, - normal = 'images/cursor.png', - active = 'images/cursor_active.png', - scale = false; - }); - - diretheme.set_canvas({ - lx = 0, ty = 0, rx = 0, by = 0, rmin = 1.2, rmax = 1.8 - }); - set_theme(std.call(here(), 'theme')); - - if load then - if here().themeInit then - here():themeInit(); - end; + dprint('start', load); + local w, h = diretheme.get_screen(); + local name = theme.name(); + if here() ~= _'theme_warning' and here() ~= _'resolution_warning' then + if name ~= '.' then + walkin('theme_warning'); + end; + + if w < 640 or h < 480 then + walkin('resolution_warning'); + end; + end; + + diretheme.set_cursor({ + x = 2, + y = 2, + normal = 'images/cursor.png', + active = 'images/cursor_active.png', + scale = false; + }); + + diretheme.set_canvas({ + lx = 0, ty = 0, rx = 0, by = 0, rmin = 1.2, rmax = 1.8 + }); + set_theme(std.call(here(), 'theme')); + + if load then + if here().themeInit then + here():themeInit(); + end; - if here().onboot then - here():onboot(); - end; - else - - local computer_parts = { - 'cvx-rst-i3sb', - 'mcpu70-cvx-7mhz', - 'rst-m16-16mb', - 'tva-rx1', - 'fna-100-10mbs_1', - 'kbc-s' - }; - - local bpi = rnd(#computer_parts); - _(computer_parts[bpi]).status = false; - computer_parts[bpi] = computer_parts[#computer_parts]; - computer_parts[#computer_parts] = nil; + if here().onboot then + here():onboot(); + end; + else + + local computer_parts = { + 'cvx-rst-i3sb', + 'mcpu70-cvx-7mhz', + 'rst-m16-16mb', + 'tva-rx1', + 'fna-100-10mbs_1', + 'kbc-s' + }; + + local bpi = rnd(#computer_parts); + _(computer_parts[bpi]).status = false; + computer_parts[bpi] = computer_parts[#computer_parts]; + computer_parts[#computer_parts] = nil; - bpi = rnd(#computer_parts); - _(computer_parts[bpi]).status = false; - --]] - - -- Debug - --solarscale_with_me = true; - --[[ - _('terminal_boot').graphical = false; - _('terminal_boot').network = true; - _('tva-rx1').nam = 'gva-rx4' - walk('terminal_boot_failure'); - --]] - --walk('ending_formatted'); - - --timer:set(25); - --_'ending_left'.state = 4; - --walk('tower_level_1'); - --walk('true_ending_step_1'); - --_('tva-rx1').nam = 'gva-rx4' - -- walk('inside_crater_path'); - --power_on = true; - - --take('lock'); - --power_on = true; - --walk('tower_level_1_room_2'); - --take('hidden_key'); - --_('fly_west_from_village'):enable(); - --_('level_1_up'):enable(); - --_('level_1_next_room'):enable(); - --_('level_1_main_room'):enable(); - --_('level_2_up'):enable(); - --_('level_2_next_room'):enable(); - --_('level_2_main_room'):enable(); - --_('level_3_up'):enable(); - --_('level_3_next_room'):enable(); - --_('level_3_main_room'):enable(); - --_('level_4_next_room'):enable(); - --_'tower_level_3_room_2'.light = true; - --solarscale_with_me = true; - --remove('solarscale', where('solarscale')); - --put('solarscale_ally', here()); - --lifeon(_'solarscale_ally'); - --power_on = true; - --walk('tower_level_1_room_2'); - end; + bpi = rnd(#computer_parts); + _(computer_parts[bpi]).status = false; + --]] + + -- Debug + --solarscale_with_me = true; + --[[ + _('terminal_boot').graphical = false; + _('terminal_boot').network = true; + _('tva-rx1').nam = 'gva-rx4' + walk('terminal_boot_failure'); + --]] + --walk('ending_formatted'); + + --timer:set(25); + --_'ending_left'.state = 4; + walk('library_shelf_puzzle'); + --walk('true_ending_step_1'); + --_('tva-rx1').nam = 'gva-rx4' + -- walk('inside_crater_path'); + --power_on = true; + + --take('lock'); + --power_on = true; + --walk('tower_level_1_room_2'); + --take('hidden_key'); + --_('fly_west_from_village'):enable(); + --_('level_1_up'):enable(); + --_('level_1_next_room'):enable(); + --_('level_1_main_room'):enable(); + --_('level_2_up'):enable(); + --_('level_2_next_room'):enable(); + --_('level_2_main_room'):enable(); + --_('level_3_up'):enable(); + --_('level_3_next_room'):enable(); + --_('level_3_main_room'):enable(); + --_('level_4_next_room'):enable(); + --_'tower_level_3_room_2'.light = true; + --solarscale_with_me = true; + --remove('solarscale', where('solarscale')); + --put('solarscale_ally', here()); + --lifeon(_'solarscale_ally'); + --power_on = true; + --walk('tower_level_1_room_2'); + end; end; function init() - if not prefs.graphic_scale then - prefs.graphic_scale = false; - end; - - if not prefs.font_scale then - prefs.font_scale = false; - end; - - if not prefs.inventory_scale then - prefs.inventory_scale = false; - end; - - - if not prefs.text_alignment then - prefs.text_alignment = 1; - end; - - if not prefs.text_padding then - prefs.text_padding = 1; - end; - - if not prefs.text_interval then - prefs.text_interval = 1; - end; - - if not prefs.text_width then - prefs.text_width = 100; - end; + if not prefs.graphic_scale then + prefs.graphic_scale = false; + end; + + if not prefs.font_scale then + prefs.font_scale = false; + end; + + if not prefs.inventory_scale then + prefs.inventory_scale = false; + end; + + + if not prefs.text_alignment then + prefs.text_alignment = 1; + end; + + if not prefs.text_padding then + prefs.text_padding = 1; + end; + + if not prefs.text_interval then + prefs.text_interval = 1; + end; + + if not prefs.text_width then + prefs.text_width = 100; + end; end; diff --git a/solarscale.lua b/solarscale.lua --- a/solarscale.lua +++ b/solarscale.lua @@ -175,7 +175,7 @@ dlg { _'solarscale_ally'.tea_given = true; remove('tea', pl); return 'Соларскейл залпом выпивает чай и с улыбкой смотрит на меня: "Благодарю!"' - end}; + end}; {cond=function(s) return here():from()^'tower_level_1' and have('tower_box') and not _('tower_level_1').keys_taken and _('level_1_up'):disabled() end, 'У вас есть идеи, что мы должны сделать?', 'Соларскейл подлетает ко мне: "Я могу взглянуть на шкатулку, что вы только что подняли?" ', only=true; {'[Протянуть шкатулку Соларскейл] Да, конечно. ', 'Соларскейл берет шкатулку и внимательно осматривает, прежде чем вернуть ее мне. Наконец, она изрекает: "Четыре замочные скважины... Наверное, и ключи должны быть где-то здесь". '}; diff --git a/terminal.lua b/terminal.lua --- a/terminal.lua +++ b/terminal.lua @@ -1,1047 +1,1047 @@ function DS (data) - local scale = diretheme.get_scale(); - data[3] = get_sprite(data[3]); - data['x'] = data['x'] * scale; - data['y'] = data['y'] * scale; - data['w'] = data['w'] * scale; - data['h'] = data['h'] * scale; - D(data); + local scale = diretheme.get_scale(); + data[3] = get_sprite(data[3]); + data['x'] = data['x'] * scale; + data['y'] = data['y'] * scale; + data['w'] = data['w'] * scale; + data['h'] = data['h'] * scale; + D(data); end; function terminal_theme(s) - if s.ticks ~= nil and s.ticks < 128 and s.graphical then - diretheme.set_text_area({ - contentrect = { - wmax = 569, - hmax = 390, - ty = 72, - ax = 0, - ay = -2, - dx = -16 - }; - }); - else - diretheme.set_text_area({ - contentrect = { - wmax = 569, - hmax = 390, - ty = 2, - ax = 0, - ay = -2, - dx = -16 - }; - }); - end; - std.kh_leave_spaces = true; - fmt.para = false; + if s.ticks ~= nil and s.ticks < 128 and s.graphical then + diretheme.set_text_area({ + contentrect = { + wmax = 569, + hmax = 390, + ty = 72, + ax = 0, + ay = -2, + dx = -16 + }; + }); + else + diretheme.set_text_area({ + contentrect = { + wmax = 569, + hmax = 390, + ty = 2, + ax = 0, + ay = -2, + dx = -16 + }; + }); + end; + std.kh_leave_spaces = true; + fmt.para = false; end; function getscreen(graphical) - local d = D('terminal_screen'); - if not d or d.graphical ~= graphical then - local scale = diretheme.get_scale(); - local sw, sh = diretheme.get_screen(); - sw = math.floor(sw / scale); - sh = math.floor(sh / scale); - local x = math.floor((sw - 569) / 2 - 16); - local y = math.max(sh - 736, 25); - local h = 320; - if graphical then - y = y + 70; - h = h - 70; - end; - d = D {'terminal_screen', 'simple_txt', {}, w = 569 * scale, h = h * scale, x = x * scale, y = y * scale, color = '#D0FFFF', color_link = '#abdece', color_alink = '#9bcebe', background=true, z=1000, font = 'fonts/vga.ttf', size=16 * scale, graphical = graphical, bgcolor='#000000'}; - end; - - return d; + local d = D('terminal_screen'); + if not d or d.graphical ~= graphical then + local scale = diretheme.get_scale(); + local sw, sh = diretheme.get_screen(); + sw = math.floor(sw / scale); + sh = math.floor(sh / scale); + local x = math.floor((sw - 569) / 2 - 16); + local y = math.max(sh - 736, 25); + local h = 320; + if graphical then + y = y + 70; + h = h - 70; + end; + d = D {'terminal_screen', 'simple_txt', {}, w = 569 * scale, h = h * scale, x = x * scale, y = y * scale, color = '#D0FFFF', color_link = '#abdece', color_alink = '#9bcebe', background=true, z=1000, font = 'fonts/vga.ttf', size=16 * scale, graphical = graphical, bgcolor='#000000'}; + end; + + return d; end; function terminal_untheme(s) - std.kh_leave_spaces = false; - fmt.para = true; + std.kh_leave_spaces = false; + fmt.para = true; end; local function btn_anim_process(v) - if v.animated == 1 then - v.animated = true; - elseif v.frame_nr == 0 then - v.animated = false; - end; + if v.animated == 1 then + v.animated = true; + elseif v.frame_nr == 0 then + v.animated = false; + end; end; local function shift_anim_process(v) - if v.frame_nr == 2 then - v.animated = false; - end; + if v.frame_nr == 2 then + v.animated = false; + end; end; local keymapping = { - ['`'] = '~', - ['1'] = '!', - ['2'] = '@', - ['3'] = '#', - ['4'] = '$', - ['5'] = '%', - ['6'] = '\\^', - ['7'] = '&', - ['8'] = '*', - ['9'] = '(', - ['0'] = ')', - ['-'] = '_', - ['='] = '+', - ['q'] = 'Q', - ['w'] = 'W', - ['e'] = 'E', - ['r'] = 'R', - ['t'] = 'T', - ['y'] = 'Y', - ['u'] = 'U', - ['i'] = 'I', - ['o'] = 'O', - ['p'] = 'P', - ['['] = '{', - [']'] = '}', - ['\\'] = '|', - ['a'] = 'A', - ['s'] = 'S', - ['d'] = 'D', - ['f'] = 'F', - ['g'] = 'G', - ['h'] = 'H', - ['j'] = 'J', - ['k'] = 'K', - ['l'] = 'L', - [';'] = ':', - ["'"] = '"', - ['z'] = 'Z', - ['x'] = 'X', - ['c'] = 'C', - ['v'] = 'V', - ['b'] = 'B', - ['n'] = 'N', - ['m'] = 'M', - [','] = '.', - ['.'] = ',', - ['/'] = '?', + ['`'] = '~', + ['1'] = '!', + ['2'] = '@', + ['3'] = '#', + ['4'] = '$', + ['5'] = '%', + ['6'] = '\\^', + ['7'] = '&', + ['8'] = '*', + ['9'] = '(', + ['0'] = ')', + ['-'] = '_', + ['='] = '+', + ['q'] = 'Q', + ['w'] = 'W', + ['e'] = 'E', + ['r'] = 'R', + ['t'] = 'T', + ['y'] = 'Y', + ['u'] = 'U', + ['i'] = 'I', + ['o'] = 'O', + ['p'] = 'P', + ['['] = '{', + [']'] = '}', + ['\\'] = '|', + ['a'] = 'A', + ['s'] = 'S', + ['d'] = 'D', + ['f'] = 'F', + ['g'] = 'G', + ['h'] = 'H', + ['j'] = 'J', + ['k'] = 'K', + ['l'] = 'L', + [';'] = ':', + ["'"] = '"', + ['z'] = 'Z', + ['x'] = 'X', + ['c'] = 'C', + ['v'] = 'V', + ['b'] = 'B', + ['n'] = 'N', + ['m'] = 'M', + [','] = '.', + ['.'] = ',', + ['/'] = '?', }; local key_sounds = { - 'keyboard1', 'keyboard2', 'keyboard3', 'keyboard4', 'keyboard5' + 'keyboard1', 'keyboard2', 'keyboard3', 'keyboard4', 'keyboard5' } local handled_keys = Set { - '`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 'backspace','shift', - 'q', 'w', 'e', 'r', 't', 'y', 'u','i', 'o', 'p', '[', ']', '\\', - 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', "'", 'return', - 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', - 'space', 'left', 'right', 'up', 'down', 'left shift' + '`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 'backspace','shift', + 'q', 'w', 'e', 'r', 't', 'y', 'u','i', 'o', 'p', '[', ']', '\\', + 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', "'", 'return', + 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', + 'space', 'left', 'right', 'up', 'down', 'left shift' } local release_handled_keys = Set { - 'left shift' + 'left shift' } local mapping_decor_key = { - btn_backquote = '`'; - btn_1 = '1'; - btn_2 = '2'; - btn_3 = '3'; - btn_4 = '4'; - btn_5 = '5'; - btn_6 = '6'; - btn_7 = '7'; - btn_8 = '8'; - btn_9 = '9'; - btn_0 = '0'; - btn_minus = '-'; - btn_backspace = 'backspace'; - - btn_q = 'q'; - btn_w = 'w'; - btn_e = 'e'; - btn_r = 'r'; - btn_t = 't'; - btn_y = 'y'; - btn_u = 'u'; - btn_i = 'i'; - btn_o = 'o'; - btn_p = 'p'; - btn_left_bracket = '['; - btn_right_bracket = ']'; - btn_equal = '='; + btn_backquote = '`'; + btn_1 = '1'; + btn_2 = '2'; + btn_3 = '3'; + btn_4 = '4'; + btn_5 = '5'; + btn_6 = '6'; + btn_7 = '7'; + btn_8 = '8'; + btn_9 = '9'; + btn_0 = '0'; + btn_minus = '-'; + btn_backspace = 'backspace'; + + btn_q = 'q'; + btn_w = 'w'; + btn_e = 'e'; + btn_r = 'r'; + btn_t = 't'; + btn_y = 'y'; + btn_u = 'u'; + btn_i = 'i'; + btn_o = 'o'; + btn_p = 'p'; + btn_left_bracket = '['; + btn_right_bracket = ']'; + btn_equal = '='; - btn_a = 'a'; - btn_s = 's'; - btn_d = 'd'; - btn_f = 'f'; - btn_g = 'g'; - btn_h = 'h'; - btn_j = 'j'; - btn_k = 'k'; - btn_l = 'l'; - btn_semicolon = ';'; - btn_enter = 'return'; + btn_a = 'a'; + btn_s = 's'; + btn_d = 'd'; + btn_f = 'f'; + btn_g = 'g'; + btn_h = 'h'; + btn_j = 'j'; + btn_k = 'k'; + btn_l = 'l'; + btn_semicolon = ';'; + btn_enter = 'return'; - btn_z = 'z'; - btn_x = 'x'; - btn_c = 'c'; - btn_v = 'v'; - btn_b = 'b'; - btn_n = 'n'; - btn_m = 'm'; - btn_comma = ','; - btn_slash = '/'; - btn_backslash = '\\'; - btn_quote = '\''; - btn_space = 'space'; + btn_z = 'z'; + btn_x = 'x'; + btn_c = 'c'; + btn_v = 'v'; + btn_b = 'b'; + btn_n = 'n'; + btn_m = 'm'; + btn_comma = ','; + btn_slash = '/'; + btn_backslash = '\\'; + btn_quote = '\''; + btn_space = 'space'; }; local back_mapping_decor_key = {}; for k, v in pairs(mapping_decor_key) do - back_mapping_decor_key[v] = k; + back_mapping_decor_key[v] = k; end; room { - { - _keyts = 0; - _key = 0; - }; - - nam = 'terminal'; - disp = ''; - nofollow = true; - nofading = true; - path = 'C:\\'; - entry = ''; - noinv = true; - status = 'command'; - theme = 'terminal'; - format_percent = 0; - dy = 0; - mx = false; - my = false; - - keysfilter = function(s, press, key) - return handled_keys[key] ~= nil; -- ловим все нажатия - end; - - query_formatter = function(s, path, entry) - if s.status == 'command' then - return s.path .. '>' .. s.entry .. '_'; - elseif s.status == 'crypt' or s.status == 'connect' then - return 'Пароль:' .. entry .. '_'; - elseif s.status == 'format' then - return "Введите 'Yes' для подтверждения:" .. entry .. '_'; - elseif s.status == 'wait_format' then - return "Форматирование: " .. tostring(s.format_percent) .. '%'; - elseif s.status == 'format_done' then - end; - return ''; - end; - - command_preprocessor = function(s, command) - if s.status == 'crypt' then - s.status = 'command'; - s:push('Пароль:' .. command); - --s:push('Password:' .. command); - if command == 'Ancient_Tower_9021' then - s:push('Omega_Micron_Terra_1337'); - s:push(''); - else - s:push('Не удалось расшифровать ключ. Неверный пароль'); - --s:push('Unable to decrypt key. Invalid password'); - s:push(''); - end; - s.entry = ''; - return true; - elseif s.status == 'connect' then - s.entry = ''; - s.status = 'command'; - s:push('Пароль:' .. command); - --s:push('Password:' .. command); - if command == 'Omega_Micron_Terra_1337' then - if solarscale_with_me then - walk('ending_solarscale_pre'); - else - walk('ending_no_solarscale'); - end; - else - s:push('Неверный пароль'); - --s:push('Invalid password'); - end; - - return true; - elseif s.status == 'format' then - s.status = 'format'; - s.entry = ''; - s:push("Введите 'Yes' для подтверждения:" .. command); - --s:push("Type 'Yes' to confirm:" .. command); - if command:lower() == 'yes' then - s.status = 'wait_format'; - timer:set(25); - else - s:push('Операция отменена'); - s.status = 'command'; - --s:push('Operation cancelled'); - end; - - return true; - elseif s.status == 'wait_format' then - s.entry = ''; - return true; - end; - end; - timer = function(s) - local w, h = diretheme.get_screen(); - local scale = diretheme.get_scale(); - h = h / scale; - + { + _keyts = 0; + _key = 0; + }; + + nam = 'terminal'; + disp = ''; + nofollow = true; + nofading = true; + path = 'C:\\'; + entry = ''; + noinv = true; + status = 'command'; + theme = 'terminal'; + format_percent = 0; + dy = 0; + mx = false; + my = false; + + keysfilter = function(s, press, key) + return handled_keys[key] ~= nil; -- ловим все нажатия + end; + + query_formatter = function(s, path, entry) + if s.status == 'command' then + return s.path .. '>' .. s.entry .. '_'; + elseif s.status == 'crypt' or s.status == 'connect' then + return 'Пароль:' .. entry .. '_'; + elseif s.status == 'format' then + return "Введите 'Yes' для подтверждения:" .. entry .. '_'; + elseif s.status == 'wait_format' then + return "Форматирование: " .. tostring(s.format_percent) .. '%'; + elseif s.status == 'format_done' then + end; + return ''; + end; + + command_preprocessor = function(s, command) + if s.status == 'crypt' then + s.status = 'command'; + s:push('Пароль:' .. command); + --s:push('Password:' .. command); + if command == 'Ancient_Tower_9021' then + s:push('Omega_Micron_Terra_1337'); + s:push(''); + else + s:push('Не удалось расшифровать ключ. Неверный пароль'); + --s:push('Unable to decrypt key. Invalid password'); + s:push(''); + end; + s.entry = ''; + return true; + elseif s.status == 'connect' then + s.entry = ''; + s.status = 'command'; + s:push('Пароль:' .. command); + --s:push('Password:' .. command); + if command == 'Omega_Micron_Terra_1337' then + if solarscale_with_me then + walk('ending_solarscale_pre'); + else + walk('ending_no_solarscale'); + end; + else + s:push('Неверный пароль'); + --s:push('Invalid password'); + end; + + return true; + elseif s.status == 'format' then + s.status = 'format'; + s.entry = ''; + s:push("Введите 'Yes' для подтверждения:" .. command); + --s:push("Type 'Yes' to confirm:" .. command); + if command:lower() == 'yes' then + s.status = 'wait_format'; + timer:set(25); + else + s:push('Операция отменена'); + s.status = 'command'; + --s:push('Operation cancelled'); + end; + + return true; + elseif s.status == 'wait_format' then + s.entry = ''; + return true; + end; + end; + timer = function(s) + local w, h = diretheme.get_screen(); + local scale = diretheme.get_scale(); + h = h / scale; + - if h < 540 then - local x, y, b = instead.mouse_pos(); - if s.my ~= y then - s.mx = x; - s.my = y; + if h < 540 then + local x, y, b = instead.mouse_pos(); + if s.my ~= y then + s.mx = x; + s.my = y; - local max = 359; - local min = h - 191; - local h3 = h / 3; - local py; - if y < h3 then - py = 0; - elseif y < min then - py = (y - h3) / (min - h3); - else - py = 1; - end; - - py = math.round(py * (max - min)); - if s.dy ~= py then - s.dy = py; - s:makekeyboard(); - return; - end; - end; - end; + local max = 359; + local min = h - 191; + local h3 = h / 3; + local py; + if y < h3 then + py = 0; + elseif y < min then + py = (y - h3) / (min - h3); + else + py = 1; + end; + + py = math.round(py * (max - min)); + if s.dy ~= py then + s.dy = py; + s:makekeyboard(); + return; + end; + end; + end; - if s.status == 'wait_format' then - if s.format_percent < 100 then - s.format_percent = s.format_percent + 1; - local d = getscreen(false); - d:replace_line(s:query_formatter(s.path, s.entry)); - else - s.status = 'format_done'; - s:push('Форматирование завершено'); - --s:push('Formatting complete'); - end; - return; - elseif s.status == 'format_done' then - if s.dormat_percent == 100 then - s:push("Сбой системы: Критический файл не найден"); - --s:push("System failure: Critical file not found"); - end; - - s.format_percent = s.format_percent + 1; - if s.format_percent > 150 then - timer:stop(); - walk('terminal_boot_failure'); - end; - return; - end; - return false; - end; - push = function(s, line) - local d = getscreen(false); - d:replace_line(line); - if s.query_formatter then - d:insert_line(s:query_formatter(s.path, s.entry)); - else - d:insert_line(s.path .. '>' .. s.entry .. '_'); - end; - end; - enter = function(s) - s.history = {}; - s:process_directory_structure(s.directory_structure['C:']); - s:push('Запуск TOWER OS 1.0...'); - --s:push('Starting TOWER OS 1.0...'); - s:push(''); - s:push('TOWER OS Версия 1.0'); - --s:push('TOWER OS Version 1.0'); - s:push(''); - s:push("Введите 'HELP' для вывода списка доступных команд"); - --s:push("Type 'HELP' to list available commands"); - s:push(''); + if s.status == 'wait_format' then + if s.format_percent < 100 then + s.format_percent = s.format_percent + 1; + local d = getscreen(false); + d:replace_line(s:query_formatter(s.path, s.entry)); + else + s.status = 'format_done'; + s:push('Форматирование завершено'); + --s:push('Formatting complete'); + end; + return; + elseif s.status == 'format_done' then + if s.dormat_percent == 100 then + s:push("Сбой системы: Критический файл не найден"); + --s:push("System failure: Critical file not found"); + end; + + s.format_percent = s.format_percent + 1; + if s.format_percent > 150 then + timer:stop(); + walk('terminal_boot_failure'); + end; + return; + end; + return false; + end; + push = function(s, line) + local d = getscreen(false); + d:replace_line(line); + if s.query_formatter then + d:insert_line(s:query_formatter(s.path, s.entry)); + else + d:insert_line(s.path .. '>' .. s.entry .. '_'); + end; + end; + enter = function(s) + s.history = {}; + s:process_directory_structure(s.directory_structure['C:']); + s:push('Запуск TOWER OS 1.0...'); + --s:push('Starting TOWER OS 1.0...'); + s:push(''); + s:push('TOWER OS Версия 1.0'); + --s:push('TOWER OS Version 1.0'); + s:push(''); + s:push("Введите 'HELP' для вывода списка доступных команд"); + --s:push("Type 'HELP' to list available commands"); + s:push(''); - s:makekeyboard(); - end; - makekeyboard = function(s) - local width, height = diretheme.get_screen(); - local scale = diretheme.get_scale(); - width = width / scale; - height = height / scale; + s:makekeyboard(); + end; + makekeyboard = function(s) + local width, height = diretheme.get_screen(); + local scale = diretheme.get_scale(); + width = width / scale; + height = height / scale; - local x = math.floor((width - 800) / 2); - local y = height - 191; - if y < 359 then - y = 359; - end; + local x = math.floor((width - 800) / 2); + local y = height - 191; + if y < 359 then + y = 359; + end; - if s.dy then - y = y - s.dy; - end; + if s.dy then + y = y - s.dy; + end; - DS {'keyboard_bg', 'img', 'images/terminal/keyboard_bg.png', x=x - 116, y=y - 2, w=1036, h=191, z=-90}; - -- Keyboard row 1 - -- D {'btn_backquote', 'img', 'images/terminal/keyboard/btn_backquote.png', x=x + 67, y=y, w=64, h=46, frames=3, z=-100, delay=50, process=btn_anim_process, click=true}; - DS {'btn_1', 'img', 'images/terminal/keyboard/btn_1.png', x=x + 119, y=y, w=58, h=46, frames=3, z=-101, delay=50, process=btn_anim_process, click=true}; - DS {'btn_2', 'img', 'images/terminal/keyboard/btn_2.png', x=x + 167, y=y, w=55, h=46, frames=3, z=-102, delay=50, process=btn_anim_process, click=true}; - DS {'btn_3', 'img', 'images/terminal/keyboard/btn_3.png', x=x + 215, y=y, w=51, h=46, frames=3, z=-103, delay=50, process=btn_anim_process, click=true}; - DS {'btn_4', 'img', 'images/terminal/keyboard/btn_4.png', x=x + 260, y=y, w=49, h=46, frames=3, z=-104, delay=50, process=btn_anim_process, click=true}; - DS {'btn_5', 'img', 'images/terminal/keyboard/btn_5.png', x=x + 307, y=y, w=44, h=46, frames=3, z=-105, delay=50, process=btn_anim_process, click=true}; - DS {'btn_6', 'img', 'images/terminal/keyboard/btn_6.png', x=x + 351, y=y, w=47, h=46, frames=3, z=-105, delay=50, process=btn_anim_process, click=true}; - DS {'btn_7', 'img', 'images/terminal/keyboard/btn_7.png', x=x + 398, y=y, w=48, h=46, frames=3, z=-104, delay=50, process=btn_anim_process, click=true}; - DS {'btn_8', 'img', 'images/terminal/keyboard/btn_8.png', x=x + 444, y=y, w=48, h=46, frames=3, z=-103, delay=50, process=btn_anim_process, click=true}; - DS {'btn_9', 'img', 'images/terminal/keyboard/btn_9.png', x=x + 486, y=y, w=51, h=46, frames=3, z=-102, delay=50, process=btn_anim_process, click=true}; - DS {'btn_0', 'img', 'images/terminal/keyboard/btn_0.png', x=x + 529, y=y, w=55, h=46, frames=3, z=-101, delay=50, process=btn_anim_process, click=true}; - -- DS {'btn_minus', 'img', 'images/terminal/keyboard/btn_minus.png', x=x + 574, y=y, w=58, h=46, frames=3, z=-100, delay=50, process=btn_anim_process, click=true}; - DS {'btn_backspace', 'img', 'images/terminal/keyboard/btn_backspace.png', x=x + 619, y=y, w=109, h=46, frames=3, z=-99, delay=50, process=btn_anim_process, click=true}; + DS {'keyboard_bg', 'img', 'images/terminal/keyboard_bg.png', x=x - 116, y=y - 2, w=1036, h=191, z=-90}; + -- Keyboard row 1 + -- D {'btn_backquote', 'img', 'images/terminal/keyboard/btn_backquote.png', x=x + 67, y=y, w=64, h=46, frames=3, z=-100, delay=50, process=btn_anim_process, click=true}; + DS {'btn_1', 'img', 'images/terminal/keyboard/btn_1.png', x=x + 119, y=y, w=58, h=46, frames=3, z=-101, delay=50, process=btn_anim_process, click=true}; + DS {'btn_2', 'img', 'images/terminal/keyboard/btn_2.png', x=x + 167, y=y, w=55, h=46, frames=3, z=-102, delay=50, process=btn_anim_process, click=true}; + DS {'btn_3', 'img', 'images/terminal/keyboard/btn_3.png', x=x + 215, y=y, w=51, h=46, frames=3, z=-103, delay=50, process=btn_anim_process, click=true}; + DS {'btn_4', 'img', 'images/terminal/keyboard/btn_4.png', x=x + 260, y=y, w=49, h=46, frames=3, z=-104, delay=50, process=btn_anim_process, click=true}; + DS {'btn_5', 'img', 'images/terminal/keyboard/btn_5.png', x=x + 307, y=y, w=44, h=46, frames=3, z=-105, delay=50, process=btn_anim_process, click=true}; + DS {'btn_6', 'img', 'images/terminal/keyboard/btn_6.png', x=x + 351, y=y, w=47, h=46, frames=3, z=-105, delay=50, process=btn_anim_process, click=true}; + DS {'btn_7', 'img', 'images/terminal/keyboard/btn_7.png', x=x + 398, y=y, w=48, h=46, frames=3, z=-104, delay=50, process=btn_anim_process, click=true}; + DS {'btn_8', 'img', 'images/terminal/keyboard/btn_8.png', x=x + 444, y=y, w=48, h=46, frames=3, z=-103, delay=50, process=btn_anim_process, click=true}; + DS {'btn_9', 'img', 'images/terminal/keyboard/btn_9.png', x=x + 486, y=y, w=51, h=46, frames=3, z=-102, delay=50, process=btn_anim_process, click=true}; + DS {'btn_0', 'img', 'images/terminal/keyboard/btn_0.png', x=x + 529, y=y, w=55, h=46, frames=3, z=-101, delay=50, process=btn_anim_process, click=true}; + -- DS {'btn_minus', 'img', 'images/terminal/keyboard/btn_minus.png', x=x + 574, y=y, w=58, h=46, frames=3, z=-100, delay=50, process=btn_anim_process, click=true}; + DS {'btn_backspace', 'img', 'images/terminal/keyboard/btn_backspace.png', x=x + 619, y=y, w=109, h=46, frames=3, z=-99, delay=50, process=btn_anim_process, click=true}; - -- Keyboard row 2 - DS {'btn_q', 'img', 'images/terminal/keyboard/btn_q.png', x=x + 81, y=y + 26, w=61, h=46, frames=3, z=-110, delay=50, process=btn_anim_process, click=true}; - DS {'btn_w', 'img', 'images/terminal/keyboard/btn_w.png', x=x + 130, y=y + 26, w=59, h=46, frames=3, z=-111, delay=50, process=btn_anim_process, click=true}; - DS {'btn_e', 'img', 'images/terminal/keyboard/btn_e.png', x=x + 180, y=y + 26, w=57, h=46, frames=3, z=-112, delay=50, process=btn_anim_process, click=true}; - DS {'btn_r', 'img', 'images/terminal/keyboard/btn_r.png', x=x + 230, y=y + 26, w=53, h=46, frames=3, z=-113, delay=50, process=btn_anim_process, click=true}; - DS {'btn_t', 'img', 'images/terminal/keyboard/btn_t.png', x=x + 278, y=y + 26, w=50, h=46, frames=3, z=-114, delay=50, process=btn_anim_process, click=true}; - DS {'btn_y', 'img', 'images/terminal/keyboard/btn_y.png', x=x + 327, y=y + 26, w=45, h=46, frames=3, z=-115, delay=50, process=btn_anim_process, click=true}; - DS {'btn_u', 'img', 'images/terminal/keyboard/btn_u.png', x=x + 373, y=y + 26, w=52, h=46, frames=3, z=-115, delay=50, process=btn_anim_process, click=true}; - DS {'btn_i', 'img', 'images/terminal/keyboard/btn_i.png', x=x + 423, y=y + 26, w=52, h=46, frames=3, z=-114, delay=50, process=btn_anim_process, click=true}; - DS {'btn_o', 'img', 'images/terminal/keyboard/btn_o.png', x=x + 471, y=y + 26, w=50, h=46, frames=3, z=-113, delay=50, process=btn_anim_process, click=true}; - DS {'btn_p', 'img', 'images/terminal/keyboard/btn_p.png', x=x + 514, y=y + 26, w=58, h=46, frames=3, z=-112, delay=50, process=btn_anim_process, click=true}; - -- DS {'btn_left_bracket', 'img', 'images/terminal/keyboard/btn_left_bracket.png', x=x + 562, y=y + 26, w=60, h=46, frames=3, z=-111, delay=50, process=btn_anim_process, click=true}; - -- DS {'btn_right_bracket', 'img', 'images/terminal/keyboard/btn_right_bracket.png', x=x + 610, y=y + 26, w=62, h=46, frames=3, z=-110, delay=50, process=btn_anim_process, click=true}; - -- DS {'btn_equal', 'img', 'images/terminal/keyboard/btn_equal.png', x=x + 656, y=y + 26, w=65, h=46, frames=3, z=-109, delay=50, process=btn_anim_process, click=true}; - - -- Keyboard row 3 - DS {'btn_a', 'img', 'images/terminal/keyboard/btn_a.png', x=x + 81, y=y + 52, w=69, h=55, frames=3, z=-120, delay=50, process=btn_anim_process, click=true}; - DS {'btn_s', 'img', 'images/terminal/keyboard/btn_s.png', x=x + 135, y=y + 52, w=67, h=55, frames=3, z=-121, delay=50, process=btn_anim_process, click=true}; - DS {'btn_d', 'img', 'images/terminal/keyboard/btn_d.png', x=x + 191, y=y + 52, w=61, h=55, frames=3, z=-122, delay=50, process=btn_anim_process, click=true}; - DS {'btn_f', 'img', 'images/terminal/keyboard/btn_f.png', x=x + 244, y=y + 52, w=58, h=55, frames=3, z=-123, delay=50, process=btn_anim_process, click=true}; - DS {'btn_g', 'img', 'images/terminal/keyboard/btn_g.png', x=x + 296, y=y + 52, w=53, h=55, frames=3, z=-124, delay=50, process=btn_anim_process, click=true}; - DS {'btn_h', 'img', 'images/terminal/keyboard/btn_h.png', x=x + 346, y=y + 52, w=55, h=55, frames=3, z=-125, delay=50, process=btn_anim_process, click=true}; - DS {'btn_j', 'img', 'images/terminal/keyboard/btn_j.png', x=x + 401, y=y + 52, w=56, h=55, frames=3, z=-124, delay=50, process=btn_anim_process, click=true}; - DS {'btn_k', 'img', 'images/terminal/keyboard/btn_k.png', x=x + 452, y=y + 52, w=55, h=55, frames=3, z=-123, delay=50, process=btn_anim_process, click=true}; - DS {'btn_l', 'img', 'images/terminal/keyboard/btn_l.png', x=x + 500, y=y + 52, w=60, h=55, frames=3, z=-122, delay=50, process=btn_anim_process, click=true}; - -- DS {'btn_semicolon', 'img', 'images/terminal/keyboard/btn_semicolon.png', x=x + 549, y=y + 52, w=65, h=55, frames=3, z=-121, delay=50, process=btn_anim_process, click=true}; - DS {'btn_enter', 'img', 'images/terminal/keyboard/btn_enter.png', x=x + 599, y=y + 52, w=124, h=55, frames=3, z=-120, delay=50, process=btn_anim_process, click=true}; + -- Keyboard row 2 + DS {'btn_q', 'img', 'images/terminal/keyboard/btn_q.png', x=x + 81, y=y + 26, w=61, h=46, frames=3, z=-110, delay=50, process=btn_anim_process, click=true}; + DS {'btn_w', 'img', 'images/terminal/keyboard/btn_w.png', x=x + 130, y=y + 26, w=59, h=46, frames=3, z=-111, delay=50, process=btn_anim_process, click=true}; + DS {'btn_e', 'img', 'images/terminal/keyboard/btn_e.png', x=x + 180, y=y + 26, w=57, h=46, frames=3, z=-112, delay=50, process=btn_anim_process, click=true}; + DS {'btn_r', 'img', 'images/terminal/keyboard/btn_r.png', x=x + 230, y=y + 26, w=53, h=46, frames=3, z=-113, delay=50, process=btn_anim_process, click=true}; + DS {'btn_t', 'img', 'images/terminal/keyboard/btn_t.png', x=x + 278, y=y + 26, w=50, h=46, frames=3, z=-114, delay=50, process=btn_anim_process, click=true}; + DS {'btn_y', 'img', 'images/terminal/keyboard/btn_y.png', x=x + 327, y=y + 26, w=45, h=46, frames=3, z=-115, delay=50, process=btn_anim_process, click=true}; + DS {'btn_u', 'img', 'images/terminal/keyboard/btn_u.png', x=x + 373, y=y + 26, w=52, h=46, frames=3, z=-115, delay=50, process=btn_anim_process, click=true}; + DS {'btn_i', 'img', 'images/terminal/keyboard/btn_i.png', x=x + 423, y=y + 26, w=52, h=46, frames=3, z=-114, delay=50, process=btn_anim_process, click=true}; + DS {'btn_o', 'img', 'images/terminal/keyboard/btn_o.png', x=x + 471, y=y + 26, w=50, h=46, frames=3, z=-113, delay=50, process=btn_anim_process, click=true}; + DS {'btn_p', 'img', 'images/terminal/keyboard/btn_p.png', x=x + 514, y=y + 26, w=58, h=46, frames=3, z=-112, delay=50, process=btn_anim_process, click=true}; + -- DS {'btn_left_bracket', 'img', 'images/terminal/keyboard/btn_left_bracket.png', x=x + 562, y=y + 26, w=60, h=46, frames=3, z=-111, delay=50, process=btn_anim_process, click=true}; + -- DS {'btn_right_bracket', 'img', 'images/terminal/keyboard/btn_right_bracket.png', x=x + 610, y=y + 26, w=62, h=46, frames=3, z=-110, delay=50, process=btn_anim_process, click=true}; + -- DS {'btn_equal', 'img', 'images/terminal/keyboard/btn_equal.png', x=x + 656, y=y + 26, w=65, h=46, frames=3, z=-109, delay=50, process=btn_anim_process, click=true}; + + -- Keyboard row 3 + DS {'btn_a', 'img', 'images/terminal/keyboard/btn_a.png', x=x + 81, y=y + 52, w=69, h=55, frames=3, z=-120, delay=50, process=btn_anim_process, click=true}; + DS {'btn_s', 'img', 'images/terminal/keyboard/btn_s.png', x=x + 135, y=y + 52, w=67, h=55, frames=3, z=-121, delay=50, process=btn_anim_process, click=true}; + DS {'btn_d', 'img', 'images/terminal/keyboard/btn_d.png', x=x + 191, y=y + 52, w=61, h=55, frames=3, z=-122, delay=50, process=btn_anim_process, click=true}; + DS {'btn_f', 'img', 'images/terminal/keyboard/btn_f.png', x=x + 244, y=y + 52, w=58, h=55, frames=3, z=-123, delay=50, process=btn_anim_process, click=true}; + DS {'btn_g', 'img', 'images/terminal/keyboard/btn_g.png', x=x + 296, y=y + 52, w=53, h=55, frames=3, z=-124, delay=50, process=btn_anim_process, click=true}; + DS {'btn_h', 'img', 'images/terminal/keyboard/btn_h.png', x=x + 346, y=y + 52, w=55, h=55, frames=3, z=-125, delay=50, process=btn_anim_process, click=true}; + DS {'btn_j', 'img', 'images/terminal/keyboard/btn_j.png', x=x + 401, y=y + 52, w=56, h=55, frames=3, z=-124, delay=50, process=btn_anim_process, click=true}; + DS {'btn_k', 'img', 'images/terminal/keyboard/btn_k.png', x=x + 452, y=y + 52, w=55, h=55, frames=3, z=-123, delay=50, process=btn_anim_process, click=true}; + DS {'btn_l', 'img', 'images/terminal/keyboard/btn_l.png', x=x + 500, y=y + 52, w=60, h=55, frames=3, z=-122, delay=50, process=btn_anim_process, click=true}; + -- DS {'btn_semicolon', 'img', 'images/terminal/keyboard/btn_semicolon.png', x=x + 549, y=y + 52, w=65, h=55, frames=3, z=-121, delay=50, process=btn_anim_process, click=true}; + DS {'btn_enter', 'img', 'images/terminal/keyboard/btn_enter.png', x=x + 599, y=y + 52, w=124, h=55, frames=3, z=-120, delay=50, process=btn_anim_process, click=true}; - -- Keyboard row 4 - DS {'btn_z', 'img', 'images/terminal/keyboard/btn_z.png', x=x + 89, y=y + 86, w=74, h=59, frames=3, z=-130, delay=50, process=btn_anim_process, click=true}; - DS {'btn_x', 'img', 'images/terminal/keyboard/btn_x.png', x=x + 147, y=y + 86, w=70, h=59, frames=3, z=-131, delay=50, process=btn_anim_process, click=true}; - DS {'btn_c', 'img', 'images/terminal/keyboard/btn_c.png', x=x + 205, y=y + 86, w=64, h=59, frames=3, z=-132, delay=50, process=btn_anim_process, click=true}; - DS {'btn_v', 'img', 'images/terminal/keyboard/btn_v.png', x=x + 261, y=y + 86, w=61, h=59, frames=3, z=-133, delay=50, process=btn_anim_process, click=true}; - DS {'btn_b', 'img', 'images/terminal/keyboard/btn_b.png', x=x + 318, y=y + 86, w=53, h=59, frames=3, z=-134, delay=50, process=btn_anim_process, click=true}; - DS {'btn_n', 'img', 'images/terminal/keyboard/btn_n.png', x=x + 372, y=y + 86, w=60, h=59, frames=3, z=-134, delay=50, process=btn_anim_process, click=true}; - DS {'btn_m', 'img', 'images/terminal/keyboard/btn_m.png', x=x + 429, y=y + 86, w=61, h=59, frames=3, z=-133, delay=50, process=btn_anim_process, click=true}; - -- DS {'btn_comma', 'img', 'images/terminal/keyboard/btn_comma.png', x=x + 483, y=y + 86, w=62, h=59, frames=3, z=-132, delay=50, process=btn_anim_process, click=true}; - -- DS {'btn_slash', 'img', 'images/terminal/keyboard/btn_slash.png', x=x + 534, y=y + 86, w=69, h=59, frames=3, z=-131, delay=50, process=btn_anim_process, click=true}; - -- DS {'btn_backslash', 'img', 'images/terminal/keyboard/btn_backslash.png', x=x + 589, y=y + 86, w=74, h=59, frames=3, z=-130, delay=50, process=btn_anim_process, click=true}; - DS {'btn_quote', 'img', 'images/terminal/keyboard/btn_quote.png', x=x + 643, y=y + 86, w=78, h=59, frames=3, z=-129, delay=50, process=btn_anim_process, click=true}; + -- Keyboard row 4 + DS {'btn_z', 'img', 'images/terminal/keyboard/btn_z.png', x=x + 89, y=y + 86, w=74, h=59, frames=3, z=-130, delay=50, process=btn_anim_process, click=true}; + DS {'btn_x', 'img', 'images/terminal/keyboard/btn_x.png', x=x + 147, y=y + 86, w=70, h=59, frames=3, z=-131, delay=50, process=btn_anim_process, click=true}; + DS {'btn_c', 'img', 'images/terminal/keyboard/btn_c.png', x=x + 205, y=y + 86, w=64, h=59, frames=3, z=-132, delay=50, process=btn_anim_process, click=true}; + DS {'btn_v', 'img', 'images/terminal/keyboard/btn_v.png', x=x + 261, y=y + 86, w=61, h=59, frames=3, z=-133, delay=50, process=btn_anim_process, click=true}; + DS {'btn_b', 'img', 'images/terminal/keyboard/btn_b.png', x=x + 318, y=y + 86, w=53, h=59, frames=3, z=-134, delay=50, process=btn_anim_process, click=true}; + DS {'btn_n', 'img', 'images/terminal/keyboard/btn_n.png', x=x + 372, y=y + 86, w=60, h=59, frames=3, z=-134, delay=50, process=btn_anim_process, click=true}; + DS {'btn_m', 'img', 'images/terminal/keyboard/btn_m.png', x=x + 429, y=y + 86, w=61, h=59, frames=3, z=-133, delay=50, process=btn_anim_process, click=true}; + -- DS {'btn_comma', 'img', 'images/terminal/keyboard/btn_comma.png', x=x + 483, y=y + 86, w=62, h=59, frames=3, z=-132, delay=50, process=btn_anim_process, click=true}; + -- DS {'btn_slash', 'img', 'images/terminal/keyboard/btn_slash.png', x=x + 534, y=y + 86, w=69, h=59, frames=3, z=-131, delay=50, process=btn_anim_process, click=true}; + -- DS {'btn_backslash', 'img', 'images/terminal/keyboard/btn_backslash.png', x=x + 589, y=y + 86, w=74, h=59, frames=3, z=-130, delay=50, process=btn_anim_process, click=true}; + DS {'btn_quote', 'img', 'images/terminal/keyboard/btn_quote.png', x=x + 643, y=y + 86, w=78, h=59, frames=3, z=-129, delay=50, process=btn_anim_process, click=true}; - local shift_frame = 0; - if keys:state('shift') then - shift_frame = 2; - end; + local shift_frame = 0; + if keys:state('shift') then + shift_frame = 2; + end; - DS {'btn_shift', 'img', 'images/terminal/keyboard/btn_shift.png', x=x + 94, y=y + 125, w=139, h=64, frames=3, z=-140, delay=50, process=shift_anim_process, click=true, frame_nr=shift_frame}; - DS {'btn_space', 'img', 'images/terminal/keyboard/btn_space.png', x=x + 222, y=y + 125, w=494, h=64, frames=3, z=-141, delay=50, process=btn_anim_process, click=true}; + DS {'btn_shift', 'img', 'images/terminal/keyboard/btn_shift.png', x=x + 94, y=y + 125, w=139, h=64, frames=3, z=-140, delay=50, process=shift_anim_process, click=true, frame_nr=shift_frame}; + DS {'btn_space', 'img', 'images/terminal/keyboard/btn_space.png', x=x + 222, y=y + 125, w=494, h=64, frames=3, z=-141, delay=50, process=btn_anim_process, click=true}; - DS {'panel_1', 'img', 'images/terminal/keyboard/panel_1.png', x=x + 62, y=y + 37, w=677, h=16, z=-108}; - DS {'panel_2', 'img', 'images/terminal/keyboard/panel_2.png', x=x + 77, y=y + 62, w=648, h=12, z=-119}; - DS {'panel_3', 'img', 'images/terminal/keyboard/panel_3.png', x=x + 78, y=y + 94, w=652, h=20, z=-128}; - DS {'panel_4', 'img', 'images/terminal/keyboard/panel_4.png', x=x + 78, y=y + 131, w=652, h=23, z=-139}; - DS {'panel_5', 'img', 'images/terminal/keyboard/panel_5.png', x=x, y=y + 181, w=800, h=10, z=-149}; + DS {'panel_1', 'img', 'images/terminal/keyboard/panel_1.png', x=x + 62, y=y + 37, w=677, h=16, z=-108}; + DS {'panel_2', 'img', 'images/terminal/keyboard/panel_2.png', x=x + 77, y=y + 62, w=648, h=12, z=-119}; + DS {'panel_3', 'img', 'images/terminal/keyboard/panel_3.png', x=x + 78, y=y + 94, w=652, h=20, z=-128}; + DS {'panel_4', 'img', 'images/terminal/keyboard/panel_4.png', x=x + 78, y=y + 131, w=652, h=23, z=-139}; + DS {'panel_5', 'img', 'images/terminal/keyboard/panel_5.png', x=x, y=y + 181, w=800, h=10, z=-149}; - if keys:state('shift') then - DS {'btn_backquote', 'img', 'images/terminal/keyboard/btn_tilde.png', x=x + 67, y=y, w=64, h=46, frames=3, z=-100, delay=50, process=btn_anim_process, click=true}; - DS {'btn_minus', 'img', 'images/terminal/keyboard/btn_underscore.png', x=x + 574, y=y, w=58, h=46, frames=3, z=-100, delay=50, process=btn_anim_process, click=true}; - DS {'btn_left_bracket', 'img', 'images/terminal/keyboard/btn_left_curly.png', x=x + 562, y=y + 26, w=60, h=46, frames=3, z=-111, delay=50, process=btn_anim_process, click=true}; - DS {'btn_right_bracket', 'img', 'images/terminal/keyboard/btn_right_curly.png', x=x + 610, y=y + 26, w=62, h=46, frames=3, z=-110, delay=50, process=btn_anim_process, click=true}; - DS {'btn_equal', 'img', 'images/terminal/keyboard/btn_plus.png', x=x + 656, y=y + 26, w=65, h=46, frames=3, z=-109, delay=50, process=btn_anim_process, click=true}; - DS {'btn_semicolon', 'img', 'images/terminal/keyboard/btn_colon.png', x=x + 549, y=y + 52, w=65, h=55, frames=3, z=-121, delay=50, process=btn_anim_process, click=true}; - DS {'btn_comma', 'img', 'images/terminal/keyboard/btn_dot.png', x=x + 483, y=y + 86, w=62, h=59, frames=3, z=-132, delay=50, process=btn_anim_process, click=true}; - DS {'btn_slash', 'img', 'images/terminal/keyboard/btn_question.png', x=x + 534, y=y + 86, w=69, h=59, frames=3, z=-131, delay=50, process=btn_anim_process, click=true}; - DS {'btn_backslash', 'img', 'images/terminal/keyboard/btn_vertical.png', x=x + 589, y=y + 86, w=74, h=59, frames=3, z=-130, delay=50, process=btn_anim_process, click=true}; - else - DS {'btn_backquote', 'img', 'images/terminal/keyboard/btn_backquote.png', x=x + 67, y=y, w=64, h=46, frames=3, z=-100, delay=50, process=btn_anim_process, click=true}; - DS {'btn_minus', 'img', 'images/terminal/keyboard/btn_minus.png', x=x + 574, y=y, w=58, h=46, frames=3, z=-100, delay=50, process=btn_anim_process, click=true}; - DS {'btn_left_bracket', 'img', 'images/terminal/keyboard/btn_left_bracket.png', x=x + 562, y=y + 26, w=60, h=46, frames=3, z=-111, delay=50, process=btn_anim_process, click=true}; - DS {'btn_right_bracket', 'img', 'images/terminal/keyboard/btn_right_bracket.png', x=x + 610, y=y + 26, w=62, h=46, frames=3, z=-110, delay=50, process=btn_anim_process, click=true}; - DS {'btn_equal', 'img', 'images/terminal/keyboard/btn_equal.png', x=x + 656, y=y + 26, w=65, h=46, frames=3, z=-109, delay=50, process=btn_anim_process, click=true}; - DS {'btn_semicolon', 'img', 'images/terminal/keyboard/btn_semicolon.png', x=x + 549, y=y + 52, w=65, h=55, frames=3, z=-121, delay=50, process=btn_anim_process, click=true}; - DS {'btn_comma', 'img', 'images/terminal/keyboard/btn_comma.png', x=x + 483, y=y + 86, w=62, h=59, frames=3, z=-132, delay=50, process=btn_anim_process, click=true}; - DS {'btn_slash', 'img', 'images/terminal/keyboard/btn_slash.png', x=x + 534, y=y + 86, w=69, h=59, frames=3, z=-131, delay=50, process=btn_anim_process, click=true}; - DS {'btn_backslash', 'img', 'images/terminal/keyboard/btn_backslash.png', x=x + 589, y=y + 86, w=74, h=59, frames=3, z=-130, delay=50, process=btn_anim_process, click=true}; - end; - end; - onexit = function(s) - D {'keyboard_bg'}; - -- Keyboard row 1 - D {'btn_backquote'}; - D {'btn_1'}; - D {'btn_2'}; - D {'btn_3'}; - D {'btn_4'}; - D {'btn_5'}; - D {'btn_6'}; - D {'btn_7'}; - D {'btn_8'}; - D {'btn_9'}; - D {'btn_0'}; - D {'btn_minus'}; - D {'btn_backspace'}; + if keys:state('shift') then + DS {'btn_backquote', 'img', 'images/terminal/keyboard/btn_tilde.png', x=x + 67, y=y, w=64, h=46, frames=3, z=-100, delay=50, process=btn_anim_process, click=true}; + DS {'btn_minus', 'img', 'images/terminal/keyboard/btn_underscore.png', x=x + 574, y=y, w=58, h=46, frames=3, z=-100, delay=50, process=btn_anim_process, click=true}; + DS {'btn_left_bracket', 'img', 'images/terminal/keyboard/btn_left_curly.png', x=x + 562, y=y + 26, w=60, h=46, frames=3, z=-111, delay=50, process=btn_anim_process, click=true}; + DS {'btn_right_bracket', 'img', 'images/terminal/keyboard/btn_right_curly.png', x=x + 610, y=y + 26, w=62, h=46, frames=3, z=-110, delay=50, process=btn_anim_process, click=true}; + DS {'btn_equal', 'img', 'images/terminal/keyboard/btn_plus.png', x=x + 656, y=y + 26, w=65, h=46, frames=3, z=-109, delay=50, process=btn_anim_process, click=true}; + DS {'btn_semicolon', 'img', 'images/terminal/keyboard/btn_colon.png', x=x + 549, y=y + 52, w=65, h=55, frames=3, z=-121, delay=50, process=btn_anim_process, click=true}; + DS {'btn_comma', 'img', 'images/terminal/keyboard/btn_dot.png', x=x + 483, y=y + 86, w=62, h=59, frames=3, z=-132, delay=50, process=btn_anim_process, click=true}; + DS {'btn_slash', 'img', 'images/terminal/keyboard/btn_question.png', x=x + 534, y=y + 86, w=69, h=59, frames=3, z=-131, delay=50, process=btn_anim_process, click=true}; + DS {'btn_backslash', 'img', 'images/terminal/keyboard/btn_vertical.png', x=x + 589, y=y + 86, w=74, h=59, frames=3, z=-130, delay=50, process=btn_anim_process, click=true}; + else + DS {'btn_backquote', 'img', 'images/terminal/keyboard/btn_backquote.png', x=x + 67, y=y, w=64, h=46, frames=3, z=-100, delay=50, process=btn_anim_process, click=true}; + DS {'btn_minus', 'img', 'images/terminal/keyboard/btn_minus.png', x=x + 574, y=y, w=58, h=46, frames=3, z=-100, delay=50, process=btn_anim_process, click=true}; + DS {'btn_left_bracket', 'img', 'images/terminal/keyboard/btn_left_bracket.png', x=x + 562, y=y + 26, w=60, h=46, frames=3, z=-111, delay=50, process=btn_anim_process, click=true}; + DS {'btn_right_bracket', 'img', 'images/terminal/keyboard/btn_right_bracket.png', x=x + 610, y=y + 26, w=62, h=46, frames=3, z=-110, delay=50, process=btn_anim_process, click=true}; + DS {'btn_equal', 'img', 'images/terminal/keyboard/btn_equal.png', x=x + 656, y=y + 26, w=65, h=46, frames=3, z=-109, delay=50, process=btn_anim_process, click=true}; + DS {'btn_semicolon', 'img', 'images/terminal/keyboard/btn_semicolon.png', x=x + 549, y=y + 52, w=65, h=55, frames=3, z=-121, delay=50, process=btn_anim_process, click=true}; + DS {'btn_comma', 'img', 'images/terminal/keyboard/btn_comma.png', x=x + 483, y=y + 86, w=62, h=59, frames=3, z=-132, delay=50, process=btn_anim_process, click=true}; + DS {'btn_slash', 'img', 'images/terminal/keyboard/btn_slash.png', x=x + 534, y=y + 86, w=69, h=59, frames=3, z=-131, delay=50, process=btn_anim_process, click=true}; + DS {'btn_backslash', 'img', 'images/terminal/keyboard/btn_backslash.png', x=x + 589, y=y + 86, w=74, h=59, frames=3, z=-130, delay=50, process=btn_anim_process, click=true}; + end; + end; + onexit = function(s) + D {'keyboard_bg'}; + -- Keyboard row 1 + D {'btn_backquote'}; + D {'btn_1'}; + D {'btn_2'}; + D {'btn_3'}; + D {'btn_4'}; + D {'btn_5'}; + D {'btn_6'}; + D {'btn_7'}; + D {'btn_8'}; + D {'btn_9'}; + D {'btn_0'}; + D {'btn_minus'}; + D {'btn_backspace'}; - -- Keyboard row 2 - D {'btn_q'}; - D {'btn_w'}; - D {'btn_e'}; - D {'btn_r'}; - D {'btn_t'}; - D {'btn_y'}; - D {'btn_u'}; - D {'btn_i'}; - D {'btn_o'}; - D {'btn_p'}; - D {'btn_left_bracket'}; - D {'btn_right_bracket'}; - D {'btn_equal'}; + -- Keyboard row 2 + D {'btn_q'}; + D {'btn_w'}; + D {'btn_e'}; + D {'btn_r'}; + D {'btn_t'}; + D {'btn_y'}; + D {'btn_u'}; + D {'btn_i'}; + D {'btn_o'}; + D {'btn_p'}; + D {'btn_left_bracket'}; + D {'btn_right_bracket'}; + D {'btn_equal'}; - D {'btn_a'}; - D {'btn_s'}; - D {'btn_d'}; - D {'btn_f'}; - D {'btn_g'}; - D {'btn_h'}; - D {'btn_j'}; - D {'btn_k'}; - D {'btn_l'}; - D {'btn_semicolon'}; - D {'btn_enter'}; + D {'btn_a'}; + D {'btn_s'}; + D {'btn_d'}; + D {'btn_f'}; + D {'btn_g'}; + D {'btn_h'}; + D {'btn_j'}; + D {'btn_k'}; + D {'btn_l'}; + D {'btn_semicolon'}; + D {'btn_enter'}; - D {'btn_z'}; - D {'btn_x'}; - D {'btn_c'}; - D {'btn_v'}; - D {'btn_b'}; - D {'btn_n'}; - D {'btn_m'}; - D {'btn_comma'}; - D {'btn_slash'}; - D {'btn_backslash'}; - D {'btn_quote'}; + D {'btn_z'}; + D {'btn_x'}; + D {'btn_c'}; + D {'btn_v'}; + D {'btn_b'}; + D {'btn_n'}; + D {'btn_m'}; + D {'btn_comma'}; + D {'btn_slash'}; + D {'btn_backslash'}; + D {'btn_quote'}; - D {'btn_shift'}; - D {'btn_space'}; + D {'btn_shift'}; + D {'btn_space'}; - D {'panel_1'}; - D {'panel_2'}; - D {'panel_3'}; - D {'panel_4'}; - D {'panel_5'}; + D {'panel_1'}; + D {'panel_2'}; + D {'panel_3'}; + D {'panel_4'}; + D {'panel_5'}; - D {'terminal_screen'}; - end; - shift_buttons = function(s) - local width = tonumber(theme.get('scr.w')); - local height = tonumber(theme.get('scr.h')); - local scale = diretheme.get_scale(); - width = width / scale; - height = height / scale; + D {'terminal_screen'}; + end; + shift_buttons = function(s) + local width = tonumber(theme.get('scr.w')); + local height = tonumber(theme.get('scr.h')); + local scale = diretheme.get_scale(); + width = width / scale; + height = height / scale; - local x = math.floor((width - 800) / 2); - local y = height - 191; - if y < 359 then - y = 359; - end; + local x = math.floor((width - 800) / 2); + local y = height - 191; + if y < 359 then + y = 359; + end; - if s.dy then - y = y - s.dy; - end; + if s.dy then + y = y - s.dy; + end; - if keys:state('shift') then - DS {'btn_backquote', 'img', 'images/terminal/keyboard/btn_tilde.png', x=x + 67, y=y, w=64, h=46, frames=3, z=-100, delay=50, process=btn_anim_process, click=true}; - DS {'btn_minus', 'img', 'images/terminal/keyboard/btn_underscore.png', x=x + 574, y=y, w=58, h=46, frames=3, z=-100, delay=50, process=btn_anim_process, click=true}; - DS {'btn_left_bracket', 'img', 'images/terminal/keyboard/btn_left_curly.png', x=x + 562, y=y + 26, w=60, h=46, frames=3, z=-111, delay=50, process=btn_anim_process, click=true}; - DS {'btn_right_bracket', 'img', 'images/terminal/keyboard/btn_right_curly.png', x=x + 610, y=y + 26, w=62, h=46, frames=3, z=-110, delay=50, process=btn_anim_process, click=true}; - DS {'btn_equal', 'img', 'images/terminal/keyboard/btn_plus.png', x=x + 656, y=y + 26, w=65, h=46, frames=3, z=-109, delay=50, process=btn_anim_process, click=true}; - DS {'btn_semicolon', 'img', 'images/terminal/keyboard/btn_colon.png', x=x + 549, y=y + 52, w=65, h=55, frames=3, z=-121, delay=50, process=btn_anim_process, click=true}; - DS {'btn_comma', 'img', 'images/terminal/keyboard/btn_dot.png', x=x + 483, y=y + 86, w=62, h=59, frames=3, z=-132, delay=50, process=btn_anim_process, click=true}; - DS {'btn_slash', 'img', 'images/terminal/keyboard/btn_question.png', x=x + 534, y=y + 86, w=69, h=59, frames=3, z=-131, delay=50, process=btn_anim_process, click=true}; - DS {'btn_backslash', 'img', 'images/terminal/keyboard/btn_vertical.png', x=x + 589, y=y + 86, w=74, h=59, frames=3, z=-130, delay=50, process=btn_anim_process, click=true}; - else - DS {'btn_backquote', 'img', 'images/terminal/keyboard/btn_backquote.png', x=x + 67, y=y, w=64, h=46, frames=3, z=-100, delay=50, process=btn_anim_process, click=true}; - DS {'btn_minus', 'img', 'images/terminal/keyboard/btn_minus.png', x=x + 574, y=y, w=58, h=46, frames=3, z=-100, delay=50, process=btn_anim_process, click=true}; - DS {'btn_left_bracket', 'img', 'images/terminal/keyboard/btn_left_bracket.png', x=x + 562, y=y + 26, w=60, h=46, frames=3, z=-111, delay=50, process=btn_anim_process, click=true}; - DS {'btn_right_bracket', 'img', 'images/terminal/keyboard/btn_right_bracket.png', x=x + 610, y=y + 26, w=62, h=46, frames=3, z=-110, delay=50, process=btn_anim_process, click=true}; - DS {'btn_equal', 'img', 'images/terminal/keyboard/btn_equal.png', x=x + 656, y=y + 26, w=65, h=46, frames=3, z=-109, delay=50, process=btn_anim_process, click=true}; - DS {'btn_semicolon', 'img', 'images/terminal/keyboard/btn_semicolon.png', x=x + 549, y=y + 52, w=65, h=55, frames=3, z=-121, delay=50, process=btn_anim_process, click=true}; - DS {'btn_comma', 'img', 'images/terminal/keyboard/btn_comma.png', x=x + 483, y=y + 86, w=62, h=59, frames=3, z=-132, delay=50, process=btn_anim_process, click=true}; - DS {'btn_slash', 'img', 'images/terminal/keyboard/btn_slash.png', x=x + 534, y=y + 86, w=69, h=59, frames=3, z=-131, delay=50, process=btn_anim_process, click=true}; - DS {'btn_backslash', 'img', 'images/terminal/keyboard/btn_backslash.png', x=x + 589, y=y + 86, w=74, h=59, frames=3, z=-130, delay=50, process=btn_anim_process, click=true}; - end; - end; - onboot = function(s) - s:process_directory_structure(s.directory_structure['C:']); - s:makekeyboard(); - end; - ondecor = function(s, name, press, x, y, btn) - if not press then - if name == 'btn_shift' then - if keys:state('shift') then - keys:event(false, 'shift'); - D(name).frame_nr = 0; - else - keys:event(true, 'shift'); - D(name).animated = 1; - sounds[key_sounds[rnd(#key_sounds)]]:play(); - end; - s:shift_buttons(); - return false; - end; + if keys:state('shift') then + DS {'btn_backquote', 'img', 'images/terminal/keyboard/btn_tilde.png', x=x + 67, y=y, w=64, h=46, frames=3, z=-100, delay=50, process=btn_anim_process, click=true}; + DS {'btn_minus', 'img', 'images/terminal/keyboard/btn_underscore.png', x=x + 574, y=y, w=58, h=46, frames=3, z=-100, delay=50, process=btn_anim_process, click=true}; + DS {'btn_left_bracket', 'img', 'images/terminal/keyboard/btn_left_curly.png', x=x + 562, y=y + 26, w=60, h=46, frames=3, z=-111, delay=50, process=btn_anim_process, click=true}; + DS {'btn_right_bracket', 'img', 'images/terminal/keyboard/btn_right_curly.png', x=x + 610, y=y + 26, w=62, h=46, frames=3, z=-110, delay=50, process=btn_anim_process, click=true}; + DS {'btn_equal', 'img', 'images/terminal/keyboard/btn_plus.png', x=x + 656, y=y + 26, w=65, h=46, frames=3, z=-109, delay=50, process=btn_anim_process, click=true}; + DS {'btn_semicolon', 'img', 'images/terminal/keyboard/btn_colon.png', x=x + 549, y=y + 52, w=65, h=55, frames=3, z=-121, delay=50, process=btn_anim_process, click=true}; + DS {'btn_comma', 'img', 'images/terminal/keyboard/btn_dot.png', x=x + 483, y=y + 86, w=62, h=59, frames=3, z=-132, delay=50, process=btn_anim_process, click=true}; + DS {'btn_slash', 'img', 'images/terminal/keyboard/btn_question.png', x=x + 534, y=y + 86, w=69, h=59, frames=3, z=-131, delay=50, process=btn_anim_process, click=true}; + DS {'btn_backslash', 'img', 'images/terminal/keyboard/btn_vertical.png', x=x + 589, y=y + 86, w=74, h=59, frames=3, z=-130, delay=50, process=btn_anim_process, click=true}; + else + DS {'btn_backquote', 'img', 'images/terminal/keyboard/btn_backquote.png', x=x + 67, y=y, w=64, h=46, frames=3, z=-100, delay=50, process=btn_anim_process, click=true}; + DS {'btn_minus', 'img', 'images/terminal/keyboard/btn_minus.png', x=x + 574, y=y, w=58, h=46, frames=3, z=-100, delay=50, process=btn_anim_process, click=true}; + DS {'btn_left_bracket', 'img', 'images/terminal/keyboard/btn_left_bracket.png', x=x + 562, y=y + 26, w=60, h=46, frames=3, z=-111, delay=50, process=btn_anim_process, click=true}; + DS {'btn_right_bracket', 'img', 'images/terminal/keyboard/btn_right_bracket.png', x=x + 610, y=y + 26, w=62, h=46, frames=3, z=-110, delay=50, process=btn_anim_process, click=true}; + DS {'btn_equal', 'img', 'images/terminal/keyboard/btn_equal.png', x=x + 656, y=y + 26, w=65, h=46, frames=3, z=-109, delay=50, process=btn_anim_process, click=true}; + DS {'btn_semicolon', 'img', 'images/terminal/keyboard/btn_semicolon.png', x=x + 549, y=y + 52, w=65, h=55, frames=3, z=-121, delay=50, process=btn_anim_process, click=true}; + DS {'btn_comma', 'img', 'images/terminal/keyboard/btn_comma.png', x=x + 483, y=y + 86, w=62, h=59, frames=3, z=-132, delay=50, process=btn_anim_process, click=true}; + DS {'btn_slash', 'img', 'images/terminal/keyboard/btn_slash.png', x=x + 534, y=y + 86, w=69, h=59, frames=3, z=-131, delay=50, process=btn_anim_process, click=true}; + DS {'btn_backslash', 'img', 'images/terminal/keyboard/btn_backslash.png', x=x + 589, y=y + 86, w=74, h=59, frames=3, z=-130, delay=50, process=btn_anim_process, click=true}; + end; + end; + onboot = function(s) + s:process_directory_structure(s.directory_structure['C:']); + s:makekeyboard(); + end; + ondecor = function(s, name, press, x, y, btn) + if not press then + if name == 'btn_shift' then + if keys:state('shift') then + keys:event(false, 'shift'); + D(name).frame_nr = 0; + else + keys:event(true, 'shift'); + D(name).animated = 1; + sounds[key_sounds[rnd(#key_sounds)]]:play(); + end; + s:shift_buttons(); + return false; + end; - s:onkey(true, mapping_decor_key[name]); - return; - end; + s:onkey(true, mapping_decor_key[name]); + return; + end; - return false; - end; - themeDispose = terminal_untheme; - history = {}; - dsc = ''; - onkey = function(s, press, key) - if not press and not release_handled_keys[key] then - s._keyts = 0; - return false; - end; + return false; + end; + themeDispose = terminal_untheme; + history = {}; + dsc = ''; + onkey = function(s, press, key) + if not press and not release_handled_keys[key] then + s._keyts = 0; + return false; + end; - local ticks = instead.ticks(); - - if s._key == key and ticks - s._keyts < 100 or key == 'return' and keys:state('alt') then - return false; - end; + local ticks = instead.ticks(); + + if s._key == key and ticks - s._keyts < 100 or key == 'return' and keys:state('alt') then + return false; + end; - s._key = key; - s._keyts = ticks; + s._key = key; + s._keyts = ticks; - if key == 'left shift' then - if press then - if D('btn_shift').frame_nr ~= 2 then - D('btn_shift').frame_nr = 2; - sounds[key_sounds[rnd(#key_sounds)]]:play(); - end; - else - D('btn_shift').frame_nr = 0; - end; - s:shift_buttons(); - return; - end; - - sounds[key_sounds[rnd(#key_sounds)]]:play(); - - local name = back_mapping_decor_key[key]; - - if name then - D(name).animated = 1; - D(name).__delay = instead.ticks() - D(name).delay; - end; - - if key == 'backspace' or key == 'left' then - if s.entry:sub(#s.entry, #s.entry) == '^' then - s.entry = s.entry:sub(1, #s.entry - 2); - else - s.entry = s.entry:sub(1, #s.entry - 1); - end; - elseif key == 'right' or key == 'up' or key == 'down' then - elseif key == 'space' then - if #s.entry + #s.path + 3 > 63 then - sounds['error_beep']:play(); - return; - end; - s.entry = s.entry .. ' '; - elseif key == 'return' then - local r = false; - - if s.command_preprocessor then - r = s:command_preprocessor(s.entry); - end; - - if not r then - r = s:process_command(s.entry) - s:call_command(r[1], r[2]); - s.entry = ''; - end; - else - if #s.entry + #s.path + 3 > 63 then - sounds['error_beep']:play(); - return; - end; - - if keys:state('shift') then - key = keymapping[key]; - end; - s.entry = s.entry .. key; - end; - local d = getscreen(false); - if s.query_formatter then - d:replace_line(s:query_formatter(s.path, s.entry)); - else - d:replace_line(s.path .. '>' .. s.entry .. '_'); - end; - end; - process_command = function(s, str) - s:push(s.path .. '>' .. str); - - local rval = {} - - for i in string.gmatch(str, "%S+") do - if (#rval > 0) then - if rval[2] then - rval[2] = rval[2] .. ' ' .. i; - else - rval[2] = i; - end; - else - rval[1] = i; - end; - - end; - - return rval; - end; - { - directory_structure = { - ['C:'] = { - ['DOCS'] = { - ['PASSWORD.TXT'] = function(s, command, args) - if command == 'PRINT.COM' then - s:push('Ошибка: Нельзя вывести двоичные данные'); - --s:push('Error: Unable to print binary data'); - else - s:push('Bad command or file name'); - end; - end; - ['CRYPT.COM'] = function(s, command, args) - if command == 'PRINT.COM' then - s:push('Ошибка: Нельзя вывести двоичные данные'); - --s:push('Error: Unable to print binary data'); - elseif command == '' then - if not args then - s:push('Применение: CRYPT [файл] [файл ключа]'); - --s:push('Usage: CRYPT [filename] [key_file]'); - s:push('Расшифровать зашифрованный файл'); - --s:push('Decrypts an encrypted file'); - else - local new_args = {}; - for i in string.gmatch(args, "%S+") do - if i and i ~= '' then - new_args[#new_args + 1] = i; - end; - end; + if key == 'left shift' then + if press then + if D('btn_shift').frame_nr ~= 2 then + D('btn_shift').frame_nr = 2; + sounds[key_sounds[rnd(#key_sounds)]]:play(); + end; + else + D('btn_shift').frame_nr = 0; + end; + s:shift_buttons(); + return; + end; + + sounds[key_sounds[rnd(#key_sounds)]]:play(); + + local name = back_mapping_decor_key[key]; + + if name then + D(name).animated = 1; + D(name).__delay = instead.ticks() - D(name).delay; + end; + + if key == 'backspace' or key == 'left' then + if s.entry:sub(#s.entry, #s.entry) == '^' then + s.entry = s.entry:sub(1, #s.entry - 2); + else + s.entry = s.entry:sub(1, #s.entry - 1); + end; + elseif key == 'right' or key == 'up' or key == 'down' then + elseif key == 'space' then + if #s.entry + #s.path + 3 > 63 then + sounds['error_beep']:play(); + return; + end; + s.entry = s.entry .. ' '; + elseif key == 'return' then + local r = false; + + if s.command_preprocessor then + r = s:command_preprocessor(s.entry); + end; + + if not r then + r = s:process_command(s.entry) + s:call_command(r[1], r[2]); + s.entry = ''; + end; + else + if #s.entry + #s.path + 3 > 63 then + sounds['error_beep']:play(); + return; + end; + + if keys:state('shift') then + key = keymapping[key]; + end; + s.entry = s.entry .. key; + end; + local d = getscreen(false); + if s.query_formatter then + d:replace_line(s:query_formatter(s.path, s.entry)); + else + d:replace_line(s.path .. '>' .. s.entry .. '_'); + end; + end; + process_command = function(s, str) + s:push(s.path .. '>' .. str); + + local rval = {} + + for i in string.gmatch(str, "%S+") do + if (#rval > 0) then + if rval[2] then + rval[2] = rval[2] .. ' ' .. i; + else + rval[2] = i; + end; + else + rval[1] = i; + end; + + end; + + return rval; + end; + { + directory_structure = { + ['C:'] = { + ['DOCS'] = { + ['PASSWORD.TXT'] = function(s, command, args) + if command == 'PRINT.COM' then + s:push('Ошибка: Нельзя вывести двоичные данные'); + --s:push('Error: Unable to print binary data'); + else + s:push('Bad command or file name'); + end; + end; + ['CRYPT.COM'] = function(s, command, args) + if command == 'PRINT.COM' then + s:push('Ошибка: Нельзя вывести двоичные данные'); + --s:push('Error: Unable to print binary data'); + elseif command == '' then + if not args then + s:push('Применение: CRYPT [файл] [файл ключа]'); + --s:push('Usage: CRYPT [filename] [key_file]'); + s:push('Расшифровать зашифрованный файл'); + --s:push('Decrypts an encrypted file'); + else + local new_args = {}; + for i in string.gmatch(args, "%S+") do + if i and i ~= '' then + new_args[#new_args + 1] = i; + end; + end; - if #new_args > 2 then - s:push('Применение: CRYPT [файл] [файл ключа]'); - --s:push('Usage: CRYPT [filename] [key_file]'); - s:push('Расшифровать зашифрованный файл'); - --s:push('Decrypts an encrypted file'); - return - elseif #new_args < 2 then - s:push('Ключ не указан в файле настроек. Укажите вручную'); - --s:push('Key is not specified in config file. Specify manually'); - return; - end; - local name, path; - name, path = s:walk_directory(new_args[1], true); - - if name ~= nil and path == 'C:\\DOCS\\PASSWORD.TXT' then - name, path = s:walk_directory(new_args[2], true); - if name ~= nil and path == 'C:\\DOCS\\KEY.TXT' then - s:push('Файл ключа защищен паролем'); - s.status = 'crypt'; - return true; - else - s:push('Неверный файл ключа'); - end; - - else - s:push('Файл не зашифрован'); - --s:push('File is not encrypted');]] - end; - end; - end; - end; - ['CRYPT.CFG'] = function(s, command, args) - if command == 'PRINT.COM' then - s:push('[MAIN]'); - s:push('ALGORITHM=AES'); - s:push('[RSA]'); - s:push('HARDWARE=FALSE'); - s:push(';KEY=KEY.TXT'); - else - s:push('Некорректное имя команды или файла'); - --s:push('Bad command or file name'); - end; - end; - ['KEY.TXT'] = function(s, command, args) - if command == 'PRINT.COM' then - s:push('Ошибка: Нельзя вывести двоичные данные'); - --s:push('Error: Unable to print binary data'); - else - s:push('Некорректное имя команды или файла'); - --s:push('Bad command or file name'); - end; - end; - }, - ['SYSTEM'] = { - ['CONNECT.EXE'] = function(s, command, args) - if command == 'PRINT.COM' then - s:push('Ошибка: Нельзя вывести двоичные данные'); - --s:push('Error: Unable to print binary data'); - elseif command == '' then - s.status = 'connect'; - return true; - end; - end; - ['FORMAT.COM'] = function(s, command, args) - if command == 'PRINT.COM' then - s:push('Ошибка: Нельзя вывести двоичные данные'); - --s:push('Error: Unable to print binary data'); - elseif command == '' then - if args and args:lower() == 'c:' then - s.status = 'format'; - return true; - elseif args and string.match(args, "^[A-z]:$") == args then - s:push('Неверное устройство'); - --s:push('Invalid drive specification'); - else - s:push('Применение: FORMAT [диск]'); - s:push('Отформатировать дисковое устройство'); - s:push('Осторожно: Данные будут удалены'); - --s:push('Usage: FORMAT [drive]'); - --s:push('Format disk drives. Use with care. Data loss inevitable'); - end; - end; - end; - ['HELP.COM'] = function(s, command, args) - if command == 'PRINT.COM' then - s:push('Ошибка: Нельзя вывести двоичные данные'); - --s:push('Error: Unable to print binary data'); - elseif command == '' then - s:push('CD - Сменить директорию'); - s:push('DIR - Вывести содержимое текущей директории'); - s:push('X: - Сменить диск на X'); - s:push('CONNECT - Подключиться к основному интерфейсу башни'); - s:push('FORMAT - Отформатировать диск. Осторожно: Данные будут удалены'); - s:push('HELP - Показать это сообщение'); - s:push('PRINT - Вывести содержимое текстового файла'); - s:push('EXIT - Выключить терминал'); - s:push('Вы можете запускать файлы .COM и .EXE указав путь к ним как'); - s:push('имя команды'); --- s:push('CD - Change directory'); --- s:push('DIR - List current directory'); --- s:push('X: - Switch to drive X'); --- s:push('CONNECT - Connect to the main tower interface'); --- s:push('FORMAT - Format disk drives. Use with care. Data loss inevitable'); --- s:push('HELP - Show this message'); --- s:push('PRINT - Print contents of a text file'); --- s:push('EXIT - Turn the terminal off'); - end; - end; - ['PRINT.COM'] = function(s, command, args) - if command == 'PRINT.COM' then - s:push('Ошибка: Нельзя вывести двоичные данные'); - --s:push('Error: Unable to print binary data'); - elseif command == '' then - if args then - local cmd = s:walk_directory(args:upper(), true); - if type(cmd) == 'function' then - cmd(s, 'PRINT.COM', '') - else - s:push('Ошибка: Невозможно вывести несуществующий файл'); - --s:push('Error: Unable to print non-existing file'); - end; - else - s:push('Применение: PRINT [имя файла]'); - s:push('Вывести содержимое текстового файла'); - -- s:push('Usage: PRINT [filename]'); - -- s:push('Prints contents of a text file'); - end; - end; - end; - }, - ['AUTOEXEC.BAT'] = function(s, command, args) - if command == 'PRINT.COM' then - s:push('SET PATH C:\\SYSTEM'); - --s:push('REM CONNECT.EXE - So I may use the main OS interface'); - s:push('REM CONNECT.EXE - Для доступа к командной строке'); - elseif command == '' then - s:push('Некорректное имя команды или файла'); - -- s:push('Bad command or file name'); - end; - end; - ['CONFIG.SYS'] = function(s, command, args) - if command == 'PRINT.COM' then - s:push('DEVICE=C:\\SYSTEM\\HIMEM.SYS'); - s:push('DOS=HIGH,UMB'); - s:push('FILES=30'); - s:push('STACKS=0,0'); - s:push('BUFFERS=20'); - s:push('DEVICE=C:\\SYSTEM\\EMM386.EXE'); - s:push('DEVICE=C:\\SYSTEM\\TOWER.SYS'); - elseif command == '' then - s:push('Некорректное имя команды или файла'); - -- s:push('Bad command or file name'); - end; - end; - ['COMMAND.COM'] = function(s, command, args) - if command == 'PRINT.COM' then - s:push('Ошибка: Нельзя вывести двоичные данные'); - --s:push('Error: Unable to print binary data'); - elseif command == '' then - s:push('Уже запущен'); - --s:push('Already started'); - end; - end; - ['HELLO.TXT'] = function(s, command, args) - if command == 'PRINT.COM' then - s:push('Приветствую, дорогой друг!'); - s:push('Я всего лишь отключил основную оболочку, CONNECT.EXE.'); - s:push('Просто запусти ее, чтобы войти в систему.'); - s:push('В дальнейшем, когда ты разберешься с системой, сможешь '); - s:push('снова перестать ей пользоваться.'); - s:push('Пароль от основного интерфейса -- в папке DOCS в файле'); - s:push('PASSWORD.TXT. Разумеется, он зашифрован. '); - elseif command == '' then - s:push('Некорректное имя команды или файла'); - -- s:push('Bad command or file name'); - end; - end; - } - }; - }; - process_directory_structure = function(s, current, parent) - current['.'] = current; - current['..'] = parent; - for k,v in pairs(current) do - if k ~= '.' and k ~= '..' and type(v) == 'table' then - s:process_directory_structure(v, current); - end; - end; - end; - walk_directory = function(s, path, no_replace) - local location = s.directory_structure; - - if path:sub(1, 2):upper() ~= 'C:' then - path = s.path .. path; - end; - - local spath = {}; - - for part in string.gmatch(path, "[^\\\\]+") do - part = part:upper(); - if part == '.' then - elseif part == '..' then - spath[#spath] = nil; - else - spath[#spath + 1] = part; - end; - local oloc = location; - location = location[part]; - if not no_replace then - if location == nil then - location = oloc[part .. '.COM']; - end; - if location == nil then - location = oloc[part .. '.EXE']; - end; - end; + if #new_args > 2 then + s:push('Применение: CRYPT [файл] [файл ключа]'); + --s:push('Usage: CRYPT [filename] [key_file]'); + s:push('Расшифровать зашифрованный файл'); + --s:push('Decrypts an encrypted file'); + return + elseif #new_args < 2 then + s:push('Ключ не указан в файле настроек. Укажите вручную'); + --s:push('Key is not specified in config file. Specify manually'); + return; + end; + local name, path; + name, path = s:walk_directory(new_args[1], true); + + if name ~= nil and path == 'C:\\DOCS\\PASSWORD.TXT' then + name, path = s:walk_directory(new_args[2], true); + if name ~= nil and path == 'C:\\DOCS\\KEY.TXT' then + s:push('Файл ключа защищен паролем'); + s.status = 'crypt'; + return true; + else + s:push('Неверный файл ключа'); + end; + + else + s:push('Файл не зашифрован'); + --s:push('File is not encrypted');]] + end; + end; + end; + end; + ['CRYPT.CFG'] = function(s, command, args) + if command == 'PRINT.COM' then + s:push('[MAIN]'); + s:push('ALGORITHM=AES'); + s:push('[RSA]'); + s:push('HARDWARE=FALSE'); + s:push(';KEY=KEY.TXT'); + else + s:push('Некорректное имя команды или файла'); + --s:push('Bad command or file name'); + end; + end; + ['KEY.TXT'] = function(s, command, args) + if command == 'PRINT.COM' then + s:push('Ошибка: Нельзя вывести двоичные данные'); + --s:push('Error: Unable to print binary data'); + else + s:push('Некорректное имя команды или файла'); + --s:push('Bad command or file name'); + end; + end; + }, + ['SYSTEM'] = { + ['CONNECT.EXE'] = function(s, command, args) + if command == 'PRINT.COM' then + s:push('Ошибка: Нельзя вывести двоичные данные'); + --s:push('Error: Unable to print binary data'); + elseif command == '' then + s.status = 'connect'; + return true; + end; + end; + ['FORMAT.COM'] = function(s, command, args) + if command == 'PRINT.COM' then + s:push('Ошибка: Нельзя вывести двоичные данные'); + --s:push('Error: Unable to print binary data'); + elseif command == '' then + if args and args:lower() == 'c:' then + s.status = 'format'; + return true; + elseif args and string.match(args, "^[A-z]:$") == args then + s:push('Неверное устройство'); + --s:push('Invalid drive specification'); + else + s:push('Применение: FORMAT [диск]'); + s:push('Отформатировать дисковое устройство'); + s:push('Осторожно: Данные будут удалены'); + --s:push('Usage: FORMAT [drive]'); + --s:push('Format disk drives. Use with care. Data loss inevitable'); + end; + end; + end; + ['HELP.COM'] = function(s, command, args) + if command == 'PRINT.COM' then + s:push('Ошибка: Нельзя вывести двоичные данные'); + --s:push('Error: Unable to print binary data'); + elseif command == '' then + s:push('CD - Сменить директорию'); + s:push('DIR - Вывести содержимое текущей директории'); + s:push('X: - Сменить диск на X'); + s:push('CONNECT - Подключиться к основному интерфейсу башни'); + s:push('FORMAT - Отформатировать диск. Осторожно: Данные будут удалены'); + s:push('HELP - Показать это сообщение'); + s:push('PRINT - Вывести содержимое текстового файла'); + s:push('EXIT - Выключить терминал'); + s:push('Вы можете запускать файлы .COM и .EXE указав путь к ним как'); + s:push('имя команды'); +-- s:push('CD - Change directory'); +-- s:push('DIR - List current directory'); +-- s:push('X: - Switch to drive X'); +-- s:push('CONNECT - Connect to the main tower interface'); +-- s:push('FORMAT - Format disk drives. Use with care. Data loss inevitable'); +-- s:push('HELP - Show this message'); +-- s:push('PRINT - Print contents of a text file'); +-- s:push('EXIT - Turn the terminal off'); + end; + end; + ['PRINT.COM'] = function(s, command, args) + if command == 'PRINT.COM' then + s:push('Ошибка: Нельзя вывести двоичные данные'); + --s:push('Error: Unable to print binary data'); + elseif command == '' then + if args then + local cmd = s:walk_directory(args:upper(), true); + if type(cmd) == 'function' then + cmd(s, 'PRINT.COM', '') + else + s:push('Ошибка: Невозможно вывести несуществующий файл'); + --s:push('Error: Unable to print non-existing file'); + end; + else + s:push('Применение: PRINT [имя файла]'); + s:push('Вывести содержимое текстового файла'); + -- s:push('Usage: PRINT [filename]'); + -- s:push('Prints contents of a text file'); + end; + end; + end; + }, + ['AUTOEXEC.BAT'] = function(s, command, args) + if command == 'PRINT.COM' then + s:push('SET PATH C:\\SYSTEM'); + --s:push('REM CONNECT.EXE - So I may use the main OS interface'); + s:push('REM CONNECT.EXE - Для доступа к командной строке'); + elseif command == '' then + s:push('Некорректное имя команды или файла'); + -- s:push('Bad command or file name'); + end; + end; + ['CONFIG.SYS'] = function(s, command, args) + if command == 'PRINT.COM' then + s:push('DEVICE=C:\\SYSTEM\\HIMEM.SYS'); + s:push('DOS=HIGH,UMB'); + s:push('FILES=30'); + s:push('STACKS=0,0'); + s:push('BUFFERS=20'); + s:push('DEVICE=C:\\SYSTEM\\EMM386.EXE'); + s:push('DEVICE=C:\\SYSTEM\\TOWER.SYS'); + elseif command == '' then + s:push('Некорректное имя команды или файла'); + -- s:push('Bad command or file name'); + end; + end; + ['COMMAND.COM'] = function(s, command, args) + if command == 'PRINT.COM' then + s:push('Ошибка: Нельзя вывести двоичные данные'); + --s:push('Error: Unable to print binary data'); + elseif command == '' then + s:push('Уже запущен'); + --s:push('Already started'); + end; + end; + ['HELLO.TXT'] = function(s, command, args) + if command == 'PRINT.COM' then + s:push('Приветствую, дорогой друг!'); + s:push('Я всего лишь отключил основную оболочку, CONNECT.EXE.'); + s:push('Просто запусти ее, чтобы войти в систему.'); + s:push('В дальнейшем, когда ты разберешься с системой, сможешь '); + s:push('снова перестать ей пользоваться.'); + s:push('Пароль от основного интерфейса -- в папке DOCS в файле'); + s:push('PASSWORD.TXT. Разумеется, он зашифрован. '); + elseif command == '' then + s:push('Некорректное имя команды или файла'); + -- s:push('Bad command or file name'); + end; + end; + } + }; + }; + process_directory_structure = function(s, current, parent) + current['.'] = current; + current['..'] = parent; + for k,v in pairs(current) do + if k ~= '.' and k ~= '..' and type(v) == 'table' then + s:process_directory_structure(v, current); + end; + end; + end; + walk_directory = function(s, path, no_replace) + local location = s.directory_structure; + + if path:sub(1, 2):upper() ~= 'C:' then + path = s.path .. path; + end; + + local spath = {}; + + for part in string.gmatch(path, "[^\\\\]+") do + part = part:upper(); + if part == '.' then + elseif part == '..' then + spath[#spath] = nil; + else + spath[#spath + 1] = part; + end; + local oloc = location; + location = location[part]; + if not no_replace then + if location == nil then + location = oloc[part .. '.COM']; + end; + if location == nil then + location = oloc[part .. '.EXE']; + end; + end; - if location == nil then - return nil, nil - end; - end; - return location, cat_list(spath, '\\'); - end; - call_command = function(s, command, args) - local r = false; - if command == '' or not command then - return - elseif command:lower() == 'dir' then - local rval = {}; - - local subdir = s:walk_directory(s.path); - local sort = function(s1, s2) - if type(subdir[s1]) == 'function' and type(subdir[s2]) == 'table' then - return false; - elseif type(subdir[s1]) == 'table' and type(subdir[s2]) == 'function' then - return true; - end; - return s1 < s2; - end; - - for k, v in pairs(subdir) do - rval[#rval + 1] = k; - end; - - table.sort(rval, sort); - - for i, v in ipairs(rval) do - s:push(v); - end; - elseif command:lower() == 'cd' then - if args then - args = args:upper(); - local dir, path = s:walk_directory(args) - if type(dir) == 'table' then - s.path = path .. '\\'; - else - s:push("'" .. args.. "' is not a directory"); - end; - else - s:push('Использование: CD [путь]'); - end; - elseif command:lower() == 'ver' then - s:push('TOWER OS Версия 1.0'); - --s:push('TOWER OS Version 1.0'); - elseif command:lower() == 'exit' then - walk('tower_level_4_room_2'); - elseif command:lower() == 'help' or command:lower() == 'help.com' then - r = s.directory_structure['C:']['SYSTEM']['HELP.COM'](s, '', args); - elseif command:lower() == 'print' or command:lower() == 'print.com' then - r = s.directory_structure['C:']['SYSTEM']['PRINT.COM'](s, '', args); - elseif command:lower() == 'format' or command:lower() == 'format.com' then - r = s.directory_structure['C:']['SYSTEM']['FORMAT.COM'](s, '', args); - elseif command:lower() == 'connect' or command:lower() == 'connect.exe' then - r = s.directory_structure['C:']['SYSTEM']['CONNECT.EXE'](s, '', args); - elseif #command == 2 and command:sub(2, 2) == ':' then - if (s.directory_structure[command]) then - s.path = command:upper() .. '\\'; - else - s:push('Неверное устройство'); - --s:push('Invalid drive specification'); - end; - else - local cmd = s:walk_directory(command:upper()) - if type(cmd) == 'function' then - r = cmd(s, '', args); - else - s:push('Некорректное имя команды или файла'); - -- s:push('Bad command or file name'); - end; - end; - if not r then - s:push(''); - end; - end; + if location == nil then + return nil, nil + end; + end; + return location, cat_list(spath, '\\'); + end; + call_command = function(s, command, args) + local r = false; + if command == '' or not command then + return + elseif command:lower() == 'dir' then + local rval = {}; + + local subdir = s:walk_directory(s.path); + local sort = function(s1, s2) + if type(subdir[s1]) == 'function' and type(subdir[s2]) == 'table' then + return false; + elseif type(subdir[s1]) == 'table' and type(subdir[s2]) == 'function' then + return true; + end; + return s1 < s2; + end; + + for k, v in pairs(subdir) do + rval[#rval + 1] = k; + end; + + table.sort(rval, sort); + + for i, v in ipairs(rval) do + s:push(v); + end; + elseif command:lower() == 'cd' then + if args then + args = args:upper(); + local dir, path = s:walk_directory(args) + if type(dir) == 'table' then + s.path = path .. '\\'; + else + s:push("'" .. args.. "' is not a directory"); + end; + else + s:push('Использование: CD [путь]'); + end; + elseif command:lower() == 'ver' then + s:push('TOWER OS Версия 1.0'); + --s:push('TOWER OS Version 1.0'); + elseif command:lower() == 'exit' then + walk('tower_level_4_room_2'); + elseif command:lower() == 'help' or command:lower() == 'help.com' then + r = s.directory_structure['C:']['SYSTEM']['HELP.COM'](s, '', args); + elseif command:lower() == 'print' or command:lower() == 'print.com' then + r = s.directory_structure['C:']['SYSTEM']['PRINT.COM'](s, '', args); + elseif command:lower() == 'format' or command:lower() == 'format.com' then + r = s.directory_structure['C:']['SYSTEM']['FORMAT.COM'](s, '', args); + elseif command:lower() == 'connect' or command:lower() == 'connect.exe' then + r = s.directory_structure['C:']['SYSTEM']['CONNECT.EXE'](s, '', args); + elseif #command == 2 and command:sub(2, 2) == ':' then + if (s.directory_structure[command]) then + s.path = command:upper() .. '\\'; + else + s:push('Неверное устройство'); + --s:push('Invalid drive specification'); + end; + else + local cmd = s:walk_directory(command:upper()) + if type(cmd) == 'function' then + r = cmd(s, '', args); + else + s:push('Некорректное имя команды или файла'); + -- s:push('Bad command or file name'); + end; + end; + if not r then + s:push(''); + end; + end; } diff --git a/tower.lua b/tower.lua --- a/tower.lua +++ b/tower.lua @@ -136,1015 +136,1015 @@ 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; + 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; + 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 = 'Обыкновенный чайный пакетик. '; + nam = 'teabag'; + disp = 'Чайный пакетик'; + disp2 = 'чайный пакетик'; + disp3 = 'чайный пакетик'; + inv = 'Обыкновенный чайный пакетик. '; } obj { - nam = 'tea'; - disp = 'Чашка с чаем'; - disp2 = 'чашка с чаем'; - disp3 = 'Чашку с чаем'; - inv = 'Миниатюрная фарфоровая чашечка, наполненная ароматным напитком. '; + 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; + 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; + 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; + 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; + if o^'potion_open' then + return 'Здесь нет замка, чтобы вылить в него зелье. '; + end; - return false; - end; - }; + return false; + end; + }; } room { - nam = 'inside_box'; - disp = 'Шкатулка'; - nofollow = true; - value = function(s) - local sum = 0; + 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_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_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_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 _('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'}; - }; + 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); + 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 .. ' в скважину и поворачиваю его. Число на счетчике изменяется. '); + 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); + 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 .. ' в скважину и поворачиваю его. Число на счетчике изменяется. '); + 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); + 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 .. ' в скважину и поворачиваю его. Число на счетчике изменяется. '); + 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); + 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 .. ' в скважину и поворачиваю его. Число на счетчике изменяется. '); + 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; - }; + 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(); - }; + 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(); + 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} - }; + 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; + 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'); + 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 = 'В котле сейчас находятся: '; + 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;}; - } + 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(); - }; + 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 = 'Широкая и пологая лестница из черного гладкого камня, ведущая на следующий этаж башни. '; - } - }; + 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'}; - }; + 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'); - }; + 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; + 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'); - }; + _('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; + 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'); - }; + _('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; + 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'); - }; + _('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; + 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'); - }; + _('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; + 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 = [[На столе я замечаю следующий текст:^ + _('tower_level_3_table').solved = true; + walkout(); + _('level_3_up'):enable(); + pr 'Легкий щелчок дает мне понять, что дверь на следующий этаж башни открыта. '; + end; + end; + }; + obj { + nam = '#hint'; + act = [[На столе я замечаю следующий текст:^ Пятеро их, у каждого цвет свой: белый, алый, лазурный, зеленый и черный.^ Четверым дано время: полдень, полночь, рассвет и закат, пятый – вне времени.^ Четверым дан сезон: осень, лето, весна и зима, пятый – вне времени.^ @@ -1158,1951 +1158,1951 @@ room { Луна убывает на севере, белый закат пребывает на юге.^ Черный – в центре, окружен он рассветом, закатом, полночью и полднем.^ Лев алый весенний рассвет собой воплощает.]]; - } + } } obj { - nam = 'figure_wolf'; - disp = 'Фигурка волка'; - disp2 = 'фигурка волка'; - disp3 = 'фигурку волка'; - inv = 'Фигурка волка, рыщущего в поисках добычи из неизвестного мне серебристого металла. Очень красивая и детально проработанная, она закреплена на шестиугольном основании из того же металла. '; + nam = 'figure_wolf'; + disp = 'Фигурка волка'; + disp2 = 'фигурка волка'; + disp3 = 'фигурку волка'; + inv = 'Фигурка волка, рыщущего в поисках добычи из неизвестного мне серебристого металла. Очень красивая и детально проработанная, она закреплена на шестиугольном основании из того же металла. '; } obj { - nam = 'figure_tiger'; - disp = 'Фигурка тигра'; - disp2 = 'фигурка тигра'; - disp3 = 'фигурку тигра'; - inv = 'Фигурка бегущего тигра из неизвестного мне серебристого металла. Очень красивая и детально проработанная, она закреплена на шестиугольном основании из того же металла. '; + nam = 'figure_tiger'; + disp = 'Фигурка тигра'; + disp2 = 'фигурка тигра'; + disp3 = 'фигурку тигра'; + inv = 'Фигурка бегущего тигра из неизвестного мне серебристого металла. Очень красивая и детально проработанная, она закреплена на шестиугольном основании из того же металла. '; } obj { - nam = 'figure_lion'; - disp = 'Фигурка льва'; - disp2 = 'фигурка льва'; - disp3 = 'фигурку льва'; - inv = 'Фигурка льва, стоящего с гордо поднятой головой и смотрящего куда-то вдаль. Сделана из неизвестного мне серебристого металла. Очень красивая и детально проработанная, она закреплена на шестиугольном основании из того же металла.'; + nam = 'figure_lion'; + disp = 'Фигурка льва'; + disp2 = 'фигурка льва'; + disp3 = 'фигурку льва'; + inv = 'Фигурка льва, стоящего с гордо поднятой головой и смотрящего куда-то вдаль. Сделана из неизвестного мне серебристого металла. Очень красивая и детально проработанная, она закреплена на шестиугольном основании из того же металла.'; } obj { - nam = 'figure_knight'; - disp = 'Фигурка рыцаря'; - disp2 = 'фигурка рыцаря'; - disp3 = 'фигурку рыцаря'; - inv = 'Фигурка рыцаря в полном доспехе, стоящего, опершись на громадный двуручный меч. Сделана из неизвестного мне серебристого металла. Очень красивая и детально проработанная, она закреплена на шестиугольном основании из того же металла.'; + nam = 'figure_knight'; + disp = 'Фигурка рыцаря'; + disp2 = 'фигурка рыцаря'; + disp3 = 'фигурку рыцаря'; + inv = 'Фигурка рыцаря в полном доспехе, стоящего, опершись на громадный двуручный меч. Сделана из неизвестного мне серебристого металла. Очень красивая и детально проработанная, она закреплена на шестиугольном основании из того же металла.'; } obj { - nam = 'figure_tower'; - disp = 'Фигурка башни'; - disp2 = 'фигурка башни'; - disp3 = 'фигурку башни'; - inv = 'Фигурка высокой шестиугольной башни -- уменьшенной копии той, в которой я сейчас нахожусь. Сделана из неизвестного мне серебристого металла. Фигурка настолько проработана, она закреплена на шестиугольном основании из того же металла.'; + 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; + 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; - }; + 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 .. '. '); + return obj { + nam = 'candle_' .. note; + dsc = '{' .. title .. '}^'; + act = function(s) + sounds[filename]:play(); + pr('Я зажигаю свечу. Откуда-то издали доносится нота ' .. note_lang .. '. '); - s:disable(); + s:disable(); - if here().notestack[here().playindex] ~= index then - _('tower_candelabra').timerstate = 1; - here().playindex = 1; - timer:set(300); + 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(); + _'candle_c':enable(); + _'candle_d':enable(); + _'candle_e':enable(); + _'candle_f':enable(); + _'candle_g':enable(); + _'candle_a':enable(); + _'candle_b':enable(); - pr 'Неведомо откуда взявшийся порыв ветра гасит зажженные свечи. '; + pr 'Неведомо откуда взявшийся порыв ветра гасит зажженные свечи. '; - local candelabra = _'tower_candelabra'; + local candelabra = _'tower_candelabra'; - pr '^В темноте раздается последовательность звуков: '; - for i = 1, 6 do - pr(candelabra.notes[candelabra.notestack[i]][1] .. ', '); - end; + 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(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 [[Дверца в дальнем конце комнаты распахивается от резкого порыва ветра. ]]; + pr [[Дверца в дальнем конце комнаты распахивается от резкого порыва ветра. ]]; - local ns = { - gusts[rnd(#gusts)]; - 'open_door'; - }; - stop_sound(); - play_sound(ns, 600); + local ns = { + gusts[rnd(#gusts)]; + 'open_door'; + }; + stop_sound(); + play_sound(ns, 600); - walkout(); - end; - end; - end; - }; + 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; + 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}; + 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; + 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); + 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 'Едва мой взгляд падает на канделябр, как в темноте раздается последовательность звуков: '; + 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'}; - }; + 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' }; - }; + 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; + 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; - }; + 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 = {} + 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 > 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; + if sound_data[sound_index] then + sounds[sound_data[sound_index]]:play(); + end; - sound_index = sound_index + 1; - end; + sound_index = sound_index + 1; + end; - return false; + 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; + 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; + 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}; + { + 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; + 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(); + 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; + 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; + 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 [[Вентилятор в блоке питания начинает шуметь, но экран не включается. Я слышу последовательность звуковых сигналов: один длинный и два коротких. ]]; + 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 "cpu"; + else + pr [[Я включаю компьютер. Вентилятор в блоке питания начинает шуметь, но экран не включается. Я слышу последовательность звуковых сигналов: один длинный и два коротких. ]]; - return; - end - end; + 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; + 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 [[Вентилятор в блоке питания начинает шуметь, но экран не включается. Я слышу последовательность звуковых сигналов: один короткий и два длинных. ]]; + 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 "ram"; + else + pr [[Я включаю компьютер. Вентилятор в блоке питания начинает шуметь, но экран не включается. Я слышу последовательность звуковых сигналов: один короткий и два длинных. ]]; - return; - end; - end; + 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; + -- 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 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'); + 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'; + pc_status = 'ok'; - if not from_solarscale then - walkin('terminal_boot'); - end; - end; - way = { - path {'Назад', 'tower_level_4_room_2'} - } + 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'); + 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 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; + if s.device then + take(s.device); + s.device = false; - cpu:disable(); - ram:disable(); - slot1:disable(); - slot2:disable(); - slot3:disable(); - slot4:disable(); + cpu:disable(); + ram:disable(); + slot1:disable(); + slot2:disable(); + slot3:disable(); + slot4:disable(); - return 'Я забираю материнскую плату. '; - end; - end; + 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 }; + 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 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; + if s.device then + return 'Сперва необходимо убрать установленную плату. '; + end; - cpu:enable(); - ram:enable(); + cpu:enable(); + ram:enable(); - for i = 1, o.slots do - slots[i]:enable(); - end; + 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; + 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; + 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; + 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; + 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; + motherboard = motherboard.device; - if (motherboard.ram == 'RST' and o.slot == 'RDT') or - (motherboard.ram == 'RKT' and o.slot ~= 'RKT') - then - return 'Память не подходит. '; - end; + 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 = '#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 = '#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 = '#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; + }; + 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; - }; + 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(); - }; + 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'; + 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'}; - } + 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; - } + 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;}; - }; + 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'}; - }; + 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; - }; - }; + 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'}; - }; + 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; - } + 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(); - }; + 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_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 = 'Небольшой железный ключик. Головка украшена резным узором. '; + 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 = 'Я бегло просматриваю платы. Ни один чип не промаркирован известным мне производителем. О назначении плат я могу догадываться только по разъемам на них. Я забираю коробку с собой. '; + 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;}; - } + 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', + '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', + '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', + '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', + 'tva-rx2', + 'gva-rx2', + 'gva-rx4', - 'fna-200-20mbs', - 'fna-100-10mbs_2', - 'fna-50-5mbs', + 'fna-200-20mbs', + 'fna-100-10mbs_2', + 'fna-50-5mbs', - 'kbc-s_2', - 'kbc-r', - 'kbc-p' + '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'}; - } + 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 = [[ - В обычных ситуациях обслуживание не требуется, однако вам может потребоваться замена комплектующих терминала на более производительные. ^ - Важно: Перед проведением любых операций отключите терминал от сети!^^ + 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^ + -- Перед заменой материнской платы отключите все устройства от нее^ + -- Открутите все винты, держащие материнскую плату(см. приложение 6)^ + -- Извлеките материнскую плату^ + -- Установите новую плату на место текущей^ + -- Прикрутите винты для закрепления платы внутри корпуса (см. приложение 6)^ + -- Установите совместимые процессор, память, контроллер клавиатуры, видеоадаптер и сетевой адаптер^^ - Замена процессора:^ - -- Извлеките старый процессор^ - -- Установите новый процессор^ - Важно: На текущий момент материнские платы форм-фактора DTMB1 выпускаются с разъемами центральных процессоров CAX, CVX и CRX. Сохраняется обратная совместимость плат со старыми процессорами, таким образом:^ - -- Процессор CAX можно установить на платы с разъемами CAX, CVX и CRX^ - -- Процессор CVX можно установить на платы с разъемами CVX и CRX^ - -- Процессор CRX можно установить на платы с разъемом CRX^^ + Замена процессора:^ + -- Извлеките старый процессор^ + -- Установите новый процессор^ + Важно: На текущий момент материнские платы форм-фактора 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 выпускаются с разъемами модулей памяти RKT, RST, RDT. Сохраняется обратная совместимость плат со старыми модулями памяти, таким образом:^ + -- Память RKT можно установить на платы с разъемами RKT, RST и RDT^ + -- Память RST можно установить на платы с разъемами RST и RDT^ + -- Память RDT можно установить на платы с разъемом RDT^^ - Замена устройств расширения: - -- Извлеките старое устройство^ - -- Установите новое устройство^ - На текущий момент материнские платы форм-фактора DTMB1 выпускаются с разъемами ISB, вы можете использовать только ISB совместимые устройства с данными платами.^^ + Замена устройств расширения: + -- Извлеките старое устройство^ + -- Установите новое устройство^ + На текущий момент материнские платы форм-фактора 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'}; - } + Маркировки совместимых устройств:^ + 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'}; - } + 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 = function(s) - terminal_theme(s); - timer:set(25); - end; - 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); + ticks = 0; + ram = 0; + nam = 'terminal_boot'; + disp = ''; + nofollow = true; + noinv = true; + nofading = true; + network = false; + graphical = false; + theme = 'terminal'; + themeInit = function(s) + terminal_theme(s); + timer:set(25); + end; + 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(); - 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, background=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 - 193; - if y < 596 then - y = 596; - end; - - local top = height - 193; - if top < 357 then - top = 357; - end; + s.ticks = 0; + s.ram = 0; + stop_sound(); + 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, background=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 - 193; + if y < 596 then + y = 596; + end; + + local top = height - 193; + if top < 357 then + top = 357; + end; - local delta = math.ceil((y - top) / 9) * scale; - top = top * scale; - - DS {'keyboard', 'img', 'images/terminal/keyboard.png', x=x - 116, y=y - 2, w=1036, h=191, z=0, 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; - end; - end}; - end; - onexit = function(s) - D {'logo'}; - D {'keyboard'}; - D {'terminal_screen'}; - end; - timer = function(s) - if s.ticks ~= 33 then - s.ticks = s.ticks + 1; - else - local ram = lookup('#ram', _'system_unit').device; + local delta = math.ceil((y - top) / 9) * scale; + top = top * scale; + + DS {'keyboard', 'img', 'images/terminal/keyboard.png', x=x - 116, y=y - 2, w=1036, h=191, z=0, 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; + end; + end}; + end; + onexit = function(s) + D {'logo'}; + D {'keyboard'}; + D {'terminal_screen'}; + end; + timer = function(s) + if s.ticks ~= 33 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 >= 200 then - walk('tower_level_4_room_2'); - end; - end; - - s:makescreen(); - end; - dsc = ''; - txt = {}; - makescreen = function(s) - local d = getscreen(s.graphical and s.ticks < 128); - 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 - d:insert_line(translate_now(terminal_locale, 'bios')); - end; + 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 >= 200 then + walk('tower_level_4_room_2'); + end; + end; + + s:makescreen(); + end; + dsc = ''; + txt = {}; + makescreen = function(s) + local d = getscreen(s.graphical and s.ticks < 128); + 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 + d:insert_line(translate_now(terminal_locale, 'bios')); + end; - if s.ticks == 8 then - d:insert_line(translate_now(terminal_locale, 'motherboard') .. ' : ' .. motherboard.name); - end; + if s.ticks == 8 then + d:insert_line(translate_now(terminal_locale, 'motherboard') .. ' : ' .. motherboard.name); + end; - if s.ticks == 16 then - d:insert_line(translate_now(terminal_locale, 'cpu') .. ' : ' .. cpu.name .. ' @ ' .. cpu.speed .. '.0' .. translate_now(terminal_locale, 'mhz')); - end; + if s.ticks == 16 then + d:insert_line(translate_now(terminal_locale, 'cpu') .. ' : ' .. cpu.name .. ' @ ' .. cpu.speed .. '.0' .. translate_now(terminal_locale, 'mhz')); + end; - if s.ticks == 24 then - d:insert_line(translate_now(terminal_locale, 'ram') .. ' : '.. ram.name); - end; + if s.ticks == 24 then + d:insert_line(translate_now(terminal_locale, 'ram') .. ' : '.. ram.name); + end; - if s.ticks == 32 then - d:insert_line(tostring(s.ram) .. translate_now(terminal_locale, 'kilobytes')) - end; + if s.ticks == 32 then + d:insert_line(tostring(s.ram) .. translate_now(terminal_locale, 'kilobytes')) + end; - if s.ticks == 33 then - d:replace_line(tostring(s.ram) .. translate_now(terminal_locale, 'kilobytes')) - end; + if s.ticks == 33 then + d:replace_line(tostring(s.ram) .. translate_now(terminal_locale, 'kilobytes')) + end; - if s.ticks == 34 then - d:replace_line(tostring(s.ram) .. translate_now(terminal_locale, 'kilobytes')); - end; + if s.ticks == 34 then + d:replace_line(tostring(s.ram) .. translate_now(terminal_locale, 'kilobytes')); + end; - if s.ticks == 40 then - d:replace_line(tostring(s.ram) .. translate_now(terminal_locale, 'kilobytes') .. ' ' .. translate_now(terminal_locale, 'success')); - d:insert_line(' '); - end; + if s.ticks == 40 then + d:replace_line(tostring(s.ram) .. translate_now(terminal_locale, 'kilobytes') .. ' ' .. translate_now(terminal_locale, 'success')); + d:insert_line(' '); + end; - if s.ticks == 48 then - d:insert_line(translate_now(terminal_locale, 'keyboard') .. ' : '); - end; + if s.ticks == 48 then + d:insert_line(translate_now(terminal_locale, 'keyboard') .. ' : '); + end; - if s.ticks == 56 then - d:replace_line(translate_now(terminal_locale, 'keyboard') .. ' : ' .. translate_now(terminal_locale, 'success')) - end; + if s.ticks == 56 then + d:replace_line(translate_now(terminal_locale, 'keyboard') .. ' : ' .. translate_now(terminal_locale, 'success')) + end; - if s.ticks == 64 then - d:insert_line(translate_now(terminal_locale, 'disk') .. ' : '); - end; + if s.ticks == 64 then + d:insert_line(translate_now(terminal_locale, 'disk') .. ' : '); + end; - if s.ticks == 72 then - d:replace_line(translate_now(terminal_locale, 'disk') .. ' : ' .. translate_now(terminal_locale, 'missing')); - end; + if s.ticks == 72 then + d:replace_line(translate_now(terminal_locale, 'disk') .. ' : ' .. translate_now(terminal_locale, 'missing')); + end; - if s.ticks == 80 then - d:insert_line(translate_now(terminal_locale, 'network') .. ' : '); - end; + if s.ticks == 80 then + d:insert_line(translate_now(terminal_locale, 'network') .. ' : '); + end; - if s.ticks == 88 then - if s.network then - d:replace_line(translate_now(terminal_locale, 'network') .. ' : ' .. translate_now(terminal_locale, 'success')); - else - d:replace_line(translate_now(terminal_locale, 'network') .. ' : ' .. translate_now(terminal_locale, 'missing')); - end; - d:insert_line(' '); - end; + if s.ticks == 88 then + if s.network then + d:replace_line(translate_now(terminal_locale, 'network') .. ' : ' .. translate_now(terminal_locale, 'success')); + else + d:replace_line(translate_now(terminal_locale, 'network') .. ' : ' .. translate_now(terminal_locale, 'missing')); + end; + d:insert_line(' '); + end; - if s.ticks == 104 then - d:insert_line(translate_now(terminal_locale, 'boot_from')); - end; + if s.ticks == 104 then + d:insert_line(translate_now(terminal_locale, 'boot_from')); + end; - if s.network then - if s.ticks == 112 then - d:replace_line(translate_now(terminal_locale, 'boot_from') .. translate_now(terminal_locale, 'network_2')); - end; + if s.network then + if s.ticks == 112 then + d:replace_line(translate_now(terminal_locale, 'boot_from') .. translate_now(terminal_locale, 'network_2')); + end; - if s.ticks == 120 then - d:replace_line(translate_now(terminal_locale, 'boot_from') .. translate_now(terminal_locale, 'network_2') .. '...'); - end; - else - if s.ticks == 112 then - d:replace_line(translate_now(terminal_locale, 'boot_from') .. translate_now(terminal_locale, 'no_device')); - end; - end; - elseif s.ticks == 128 then - d:drop_all(); - d:insert_line(translate_now(terminal_locale, 'tower_os_line_1')); - d:insert_line(' '); - else - if s.ticks == 136 then - d:insert_line(translate_now(terminal_locale, 'tower_os_line_2')); - d:insert_line(' '); - end; + if s.ticks == 120 then + d:replace_line(translate_now(terminal_locale, 'boot_from') .. translate_now(terminal_locale, 'network_2') .. '...'); + end; + else + if s.ticks == 112 then + d:replace_line(translate_now(terminal_locale, 'boot_from') .. translate_now(terminal_locale, 'no_device')); + end; + end; + elseif s.ticks == 128 then + d:drop_all(); + d:insert_line(translate_now(terminal_locale, 'tower_os_line_1')); + d:insert_line(' '); + else + if s.ticks == 136 then + d:insert_line(translate_now(terminal_locale, 'tower_os_line_2')); + d:insert_line(' '); + end; - if s.ticks == 144 then - d:insert_line(translate_now(terminal_locale, 'tower_os_line_3')); - d:insert_line(' '); - end; - end; - end; + if s.ticks == 144 then + d:insert_line(translate_now(terminal_locale, 'tower_os_line_3')); + d:insert_line(' '); + end; + end; + end; } room { - ticks = 0; - ram = 0; - nam = 'terminal_boot_failure'; - theme = 'terminal'; - disp = ''; - noinv = true; - nofading = true; - nofollow = true; - graphical = false; - themeInit = function(s) - terminal_theme(s); - timer:set(25); - 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); + ticks = 0; + ram = 0; + nam = 'terminal_boot_failure'; + theme = 'terminal'; + disp = ''; + noinv = true; + nofading = true; + nofollow = true; + graphical = false; + themeInit = function(s) + terminal_theme(s); + timer:set(25); + 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.graphical = _('terminal_boot').graphical; - s.ticks = 0; - s.ram = 0; - stop_sound(); - 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, background=false, 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; + s.graphical = _('terminal_boot').graphical; + s.ticks = 0; + s.ram = 0; + stop_sound(); + 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, background=false, 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 - 193; - if y < 596 then - y = 596; - end; - - DS {'keyboard', 'img', 'images/terminal/keyboard.png', x=x - 116, y=y - 2, w=1036, h=191, z=0}; - end; - onexit = function(s) - local realscale = diretheme.get_scale(); + local x = math.floor((width - 800) / 2); + + local y = height - 193; + if y < 596 then + y = 596; + end; + + DS {'keyboard', 'img', 'images/terminal/keyboard.png', x=x - 116, y=y - 2, w=1036, h=191, z=0}; + end; + onexit = function(s) + local realscale = diretheme.get_scale(); - local w, h = diretheme.get_screen(); - local ws = math.ceil(w / realscale); - local hs = math.ceil(h / realscale); - local animscale = math.max(math.ceil(w / 960), math.ceil(h / 600)); - local adx = math.floor(w - animscale * 960) / 2; - local ady = math.floor(h - animscale * 600) / 2; + local w, h = diretheme.get_screen(); + local ws = math.ceil(w / realscale); + local hs = math.ceil(h / realscale); + local animscale = math.max(math.ceil(w / 960), math.ceil(h / 600)); + local adx = math.floor(w - animscale * 960) / 2; + local ady = math.floor(h - animscale * 600) / 2; - local bg = pixels.new(ws, hs):scale(realscale); - - --bg, frame, pic - local bgg = pixels.new('images/main_theme/background.png'):scale(realscale); - dire_draw_tile(bgg, bg, {x=0, y=0, w=w, h=h}, {xoffset = -1, yoffset = -1}); + local bg = pixels.new(ws, hs):scale(realscale); + + --bg, frame, pic + local bgg = pixels.new('images/main_theme/background.png'):scale(realscale); + dire_draw_tile(bgg, bg, {x=0, y=0, w=w, h=h}, {xoffset = -1, yoffset = -1}); - local pic = pixels.new('images/endings/tower_ruin.png'):scale(realscale); - local px, py, ps = pic:size(); - local bdx = math.floor((w - px) / 2); - local bdy = math.floor((h - py) / 2); + local pic = pixels.new('images/endings/tower_ruin.png'):scale(realscale); + local px, py, ps = pic:size(); + local bdx = math.floor((w - px) / 2); + local bdy = math.floor((h - py) / 2); - local tbg, tbg_slice = make_tbg_slice(realscale, 'main'); - local bgframe, fdx, fdy, frw, frh = make_ending_frame(realscale, 'main', tbg, tbg_slice); - bgframe:copy(bg, bdx - fdx, bdy - fdy); + local tbg, tbg_slice = make_tbg_slice(realscale, 'main'); + local bgframe, fdx, fdy, frw, frh = make_ending_frame(realscale, 'main', tbg, tbg_slice); + bgframe:copy(bg, bdx - fdx, bdy - fdy); - pic:copy(bg, bdx, bdy); + pic:copy(bg, bdx, bdy); - fading.change { - 'animate', - animate = function(step, src, dst) - if step % 2 == 1 then - step = math.floor(step / 2) - if step < 38 then - local pxx = pixels.new('images/endings/smoke/smoke' .. tostring(step) .. '.png'):scale(animscale); - src:copy(sprite.scr(), 0, 0); - pxx:draw_spr(sprite.scr(), adx, ady); - else - local pxx = pixels.new('images/endings/smoke/smoke' .. tostring(75 - step) .. '.png'):scale(animscale); - bg:copy_spr(sprite.scr(), 0, 0); - pxx:draw_spr(sprite.scr(), adx, ady); - end; - end; - end; - max = 148 - }; - fading.enabled = true; + fading.change { + 'animate', + animate = function(step, src, dst) + if step % 2 == 1 then + step = math.floor(step / 2) + if step < 38 then + local pxx = pixels.new('images/endings/smoke/smoke' .. tostring(step) .. '.png'):scale(animscale); + src:copy(sprite.scr(), 0, 0); + pxx:draw_spr(sprite.scr(), adx, ady); + else + local pxx = pixels.new('images/endings/smoke/smoke' .. tostring(75 - step) .. '.png'):scale(animscale); + bg:copy_spr(sprite.scr(), 0, 0); + pxx:draw_spr(sprite.scr(), adx, ady); + end; + end; + end; + max = 148 + }; + fading.enabled = true; - D {'terminal_screen'}; - D {'keyboard'}; - D {'logo'}; - end; - timer = function(s) - if s.ticks ~= 33 then - s.ticks = s.ticks + 1; - else - local ram = lookup('#ram', _'system_unit').device; + D {'terminal_screen'}; + D {'keyboard'}; + D {'logo'}; + end; + timer = function(s) + if s.ticks ~= 33 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; + 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'}; - end; - if s.ticks >= 200 then - walk('ending_formatted'); - return; - end; + if s.ticks == 128 then + D {'logo'}; + end; + if s.ticks >= 200 then + walk('ending_formatted'); + return; + end; - s:makescreen(); - end; - dsc = ''; - txt = ''; - makescreen = function(s) - local d = getscreen(s.graphical and s.ticks < 128); - 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; + s:makescreen(); + end; + dsc = ''; + txt = ''; + makescreen = function(s) + local d = getscreen(s.graphical and s.ticks < 128); + 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 - d:insert_line(translate_now(terminal_locale, 'bios')); - end; + if s.ticks == 1 then + d:insert_line(translate_now(terminal_locale, 'bios')); + end; - if s.ticks == 8 then - d:insert_line(translate_now(terminal_locale, 'motherboard') .. ' : ' .. motherboard.name); - end; + if s.ticks == 8 then + d:insert_line(translate_now(terminal_locale, 'motherboard') .. ' : ' .. motherboard.name); + end; - if s.ticks == 16 then - d:insert_line(translate_now(terminal_locale, 'cpu') .. ' : ' .. cpu.name .. ' @ ' .. cpu.speed .. '.0' .. translate_now(terminal_locale, 'mhz')); - end; + if s.ticks == 16 then + d:insert_line(translate_now(terminal_locale, 'cpu') .. ' : ' .. cpu.name .. ' @ ' .. cpu.speed .. '.0' .. translate_now(terminal_locale, 'mhz')); + end; - if s.ticks == 24 then - d:insert_line(translate_now(terminal_locale, 'ram') .. ' : '.. ram.name); - end; + if s.ticks == 24 then + d:insert_line(translate_now(terminal_locale, 'ram') .. ' : '.. ram.name); + end; - if s.ticks == 32 then - d:insert_line(tostring(s.ram) .. translate_now(terminal_locale, 'kilobytes')) - end; + if s.ticks == 32 then + d:insert_line(tostring(s.ram) .. translate_now(terminal_locale, 'kilobytes')) + end; - if s.ticks == 33 then - d:replace_line(tostring(s.ram) .. translate_now(terminal_locale, 'kilobytes')) - end; + if s.ticks == 33 then + d:replace_line(tostring(s.ram) .. translate_now(terminal_locale, 'kilobytes')) + end; - if s.ticks == 34 then - d:replace_line(tostring(s.ram) .. translate_now(terminal_locale, 'kilobytes')); - end; + if s.ticks == 34 then + d:replace_line(tostring(s.ram) .. translate_now(terminal_locale, 'kilobytes')); + end; - if s.ticks == 40 then - d:replace_line(tostring(s.ram) .. translate_now(terminal_locale, 'kilobytes') .. ' ' .. translate_now(terminal_locale, 'success')); - d:insert_line(' '); - end; + if s.ticks == 40 then + d:replace_line(tostring(s.ram) .. translate_now(terminal_locale, 'kilobytes') .. ' ' .. translate_now(terminal_locale, 'success')); + d:insert_line(' '); + end; - if s.ticks == 48 then - d:insert_line(translate_now(terminal_locale, 'keyboard') .. ' : '); - end; + if s.ticks == 48 then + d:insert_line(translate_now(terminal_locale, 'keyboard') .. ' : '); + end; if s.ticks == 56 then - d:replace_line(translate_now(terminal_locale, 'keyboard') .. ' : ' .. translate_now(terminal_locale, 'success')) - end; + d:replace_line(translate_now(terminal_locale, 'keyboard') .. ' : ' .. translate_now(terminal_locale, 'success')) + end; - if s.ticks == 64 then - d:insert_line(translate_now(terminal_locale, 'disk') .. ' : '); - end; + if s.ticks == 64 then + d:insert_line(translate_now(terminal_locale, 'disk') .. ' : '); + end; - if s.ticks == 72 then - d:replace_line(translate_now(terminal_locale, 'disk') .. ' : ' .. translate_now(terminal_locale, 'missing')); - end; + if s.ticks == 72 then + d:replace_line(translate_now(terminal_locale, 'disk') .. ' : ' .. translate_now(terminal_locale, 'missing')); + end; - if s.ticks == 80 then - d:insert_line(translate_now(terminal_locale, 'network') .. ' : '); - end; + if s.ticks == 80 then + d:insert_line(translate_now(terminal_locale, 'network') .. ' : '); + end; - if s.ticks == 88 then - if s.network then - d:replace_line(translate_now(terminal_locale, 'network') .. ' : ' .. translate_now(terminal_locale, 'success')); - else - d:replace_line(translate_now(terminal_locale, 'network') .. ' : ' .. translate_now(terminal_locale, 'missing')); - end; - d:insert_line(' '); - end; + if s.ticks == 88 then + if s.network then + d:replace_line(translate_now(terminal_locale, 'network') .. ' : ' .. translate_now(terminal_locale, 'success')); + else + d:replace_line(translate_now(terminal_locale, 'network') .. ' : ' .. translate_now(terminal_locale, 'missing')); + end; + d:insert_line(' '); + end; - if s.ticks == 104 then - d:insert_line(translate_now(terminal_locale, 'boot_from')); - end; + if s.ticks == 104 then + d:insert_line(translate_now(terminal_locale, 'boot_from')); + end; - if s.ticks == 112 then - d:replace_line(translate_now(terminal_locale, 'boot_from') .. translate_now(terminal_locale, 'network_2')); - end; + if s.ticks == 112 then + d:replace_line(translate_now(terminal_locale, 'boot_from') .. translate_now(terminal_locale, 'network_2')); + end; - if s.ticks == 120 then - d:replace_line(translate_now(terminal_locale, 'boot_from') .. translate_now(terminal_locale, 'network_2') .. '...'); - end; - else - -- pr [[No bootable medium found]]; - d:drop_all(); - d:insert_line(translate_now(terminal_locale, 'no_bootable_medium_found')); - end; - end; + if s.ticks == 120 then + d:replace_line(translate_now(terminal_locale, 'boot_from') .. translate_now(terminal_locale, 'network_2') .. '...'); + end; + else + -- pr [[No bootable medium found]]; + d:drop_all(); + d:insert_line(translate_now(terminal_locale, 'no_bootable_medium_found')); + end; + end; } diff --git a/translation.lua b/translation.lua --- a/translation.lua +++ b/translation.lua @@ -1,684 +1,684 @@ declare { - common_locale = { - back = { - en = "Back"; - ru = "Незад"; - }; - continue = { - en = "Continue"; - ru = "Продолжить"; - }; - }; - link_locale = { - copied = { - en = 'Copied'; - ru = 'Скопировано'; - } - }, - main_locale = { - empty_use_1 = { - en = 'It makes no sense. '; - ru = 'Это не имеет смысла. '; - }, - empty_use_2 = { - en = 'I don\'t understand what to do with this. '; - ru = 'Я не понимаю, что с этим делать. '; - }, - empty_use_3 = { - en = 'I have no reason to do this. '; - ru = 'Мне незачем это делать. '; - }, - empty_use_4 = { - en = 'It\'s a loss of time. '; - ru = 'Это пустая трата времени. '; - }, - empty_use_5 = { - en = 'This will not lead to anything. '; - ru = 'Это ни к чему не приведет. '; - }, - empty_use_6 = { - en = 'It\'s pointless. '; - ru = 'Бессмысленно.'; - }, - empty_act = { - en = 'I don\'t know what to do with this. '; - ru = 'Я не знаю, что с этим сделать. '; - }, - empty_inv = { - en = 'This is an item. It exists. '; - ru = 'Это предмет. Он существует. '; - }; - }; - menu_locale = { - system_settings = { - en = "System settings", - ru = "Системные настройки" - }, - language = { - en = "Language", - ru = "Язык" - }, - auto_option = { - en = "Auto", - ru = "Авто" - }, - graphic_scale = { - en = 'Graphics scale'; - ru = 'Масштаб графики'; - }, - font_scale = { - en = 'Font scale'; - ru = 'Масштаб шрифта'; - }, - inventory_scale = { - en = 'Inventory font scale'; - ru = 'Масштаб шрифта инвентаря'; - }, - text_width = { - en = 'Text width'; - ru = 'Ширина текста'; - }; - text_alignment = { - en = 'Text alignment'; - ru = 'Выравнивание текста'; - }; - aspect_ratio = { - en = 'Aspect ratio'; - ru = 'Соотношение сторон'; - }; - text_alignment_left = { - en = 'Left'; - ru = 'По левому краю'; - }; - text_alignment_justify = { - en = 'Justify'; - ru = 'По ширине'; - }; - padding = { - en = 'Padding'; - ru = 'Отступ'; - }; - interval = { - en = 'Line interval'; - ru = 'Межстрочный интервал'; - }; - normal = { - en = 'Normal'; - ru = 'Обычный'; - }; - extended = { - en = 'Large'; - ru = 'Увеличенный'; - }; - resolution_warning = { - en = 'A Dragon and the Tower requires resolution of at least 640x480. The game may not run properly on a lower resolution. Please ensure that your configuration is correct and your computer supports that resolution. After that please restart or load the game. '; - ru = 'Игра Дракон и Башня требует разрешение не менее 640х480. Игра может не работать корректно с более низким разрешением. Пожалуйста, убедитесь, что ваши настройки корректны и ваш компьютер поддерживает данное разрешение, после чего перезапустите или загрузите игру. '; - }; - warning = { - en = 'Warning'; - ru = 'Предупреждение'; - }; - theme_warning = { - en = 'A Dragon and the Tower requires custom game themes to be enabled. It will not work without this option enabled. Please change your settings and restart or load the game. '; - ru = 'Игра Дракон и Башня требует чтобы настройка "собственные темы игр" была включена. Она не будет работать без этой настройки. Пожалуйста, измените настройки и перезапустите или загрузите игру. '; - }; - intro = { - en = 'My footsteps resonate under the arches of ancient caverns. Irregular shadows dance in glimmering magical light. In my hand I hold a fragment of a map, carefully stored for millennia. Unwrapping the ancient scroll, I closely examine the markings on it: a forest, a mountain range, a road and a village, marked with a cross. Time to find this place! ^My body dissipates to fog and rebuilds in a human form. Quickly I go to a small door in one of the walls. There is nothing in the room, besides a stone desk and a laptop on it -- an absolutely essential thing in this time. Even for a dragon. A good mapping software and a proper query can do wonders -- couple of minutes later I fly out of the cave in my true form, spreading my wings to the wind. '; - ru = 'Гулким эхом разносятся мои шаги под сводами древних пещер. Неровные тени пляшут в дрожащем магическом свете. В руке я держу фрагмент карты, бережно хранимый с незапамятных времен. Развернув старинный свиток, я внимательно осматриваю нанесенные на него обозначения: лес, горная цепь, дорога и отмеченная крестом деревушка. Настало время найти это место! ^Мое тело расплывается туманом и собирается в облике человека. Быстрым шагом я направляюсь к небольшой дверце в одной из стен. В комнате нет ничего, кроме каменного стола и стоящего на нем ноутбука -- совершенно необходимой в наше время вещи. Даже для дракона. Хорошая картографическая программа и правильно сформулированный запрос творят чудеса -- уже через несколько минут я вылетаю из пещеры в своем истинном обличии, расправив крылья навстречу ветру. '; - }; - credits_author = { - en = 'Author'; - ru = 'Автор игры'; - }; - credits_art= { - en = 'Art'; - ru = 'Графика'; - }; - credits_music = { - en = 'Music'; - ru = 'Музыка'; - }; - credits_sounds = { - en = 'Sounds'; - ru = 'Звуки'; - }; - credits_fonts= { - en = 'Fonts'; - ru = 'Шрифты'; - }; - credits_thanks = { - en = 'Special thanks'; - ru = 'Благодарности'; - }; - credits_engine = { - en = 'Engine'; - ru = 'Движок'; - }; - credits_engine_author = { - en = 'Peter Kosyh'; - ru = 'Пётр Косых'; - }; - }, - terminal_locale = { - no_bootable_medium_found = { - en = 'No bootable medium found'; - ru = 'Загрузочное устройство недоступно'; - }, - bios = { - en = 'TOWER BIOS 1.0'; - ru = 'TOWER BIOS 1.0'; - }, - motherboard = { - en = 'Motherboard'; - ru = 'Система'; - }, - mhz = { - en = 'MHz'; - ru = 'МГц'; - }, - cpu = { - en = 'CPU'; - ru = 'ЦПУ'; - }, - ram = { - en = 'RAM'; - ru = 'Память'; - }, - kilobytes = { - en = 'KB'; - ru = 'КБ'; - }, - keyboard = { - en = 'Keyboard'; - ru = 'Клавиатура'; - }, - success = { - en = 'OK'; - ru = 'OK'; - }, - missing = { - en = 'Not installed'; - ru = 'Отсутствует'; - }, - disk = { - en = 'HDD'; - ru = 'Диск'; - }, - network = { - en = 'Network'; - ru = 'Сеть'; - }, - boot_from = { - en = 'Boot from '; - ru = 'Загрузка с '; - }, - network_2 = { - en = 'network'; - ru = 'сети'; - }, - no_device = { - en = 'none'; - ru = 'отсутствует'; - }, - tower_os_line_1 = { - en = 'Starting TOWER OS 1.0...'; - ru = 'Запуск TOWER OS 1.0...'; - }; - tower_os_line_2 = { - en = 'TOWER OS Version 1.0'; - ru = 'TOWER OS Версия 1.0'; - }; - tower_os_line_3 = { - en = "Type 'HELP' to list available commands"; - ru = "Введите 'HELP' для вывода списка доступных команд"; - }; - no_bootable_medium = { - en = 'No bootable medium found'; - ru = 'Загрузочное устройство недоступно'; - }; - }, - tutorial_locale = { - tutorial_key = { - en = "Key"; - ru = "Ключик"; - }; - tutorial_key_inv = { - en = "A small key The box it opens should be somewhere in the treasury. "; - ru = "Небольшой ключик от шкатулки. Она должна быть где-то в сокровищнице. "; - }; - tutorial_box_hint = { - en = "To open the box with the key, use it on the box. Click on the key and then on the box. "; - ru = "Для того чтобы открыть шкатулку ключом используйте его на шкатулке. Щелкните на ключ, а затем на шкатулку. "; - }; - tutorial_key_inv_look_for_box = { - en = "Try to find the box to continue. Remember that you can inspect items repeatedly. "; - ru = "Попробуйте найти шкатулку, чтобы продолжить. Помните, что вы можете повторно осматривать объекты. "; - }; - tutorial_disk = { - en = "Disk with maps"; - ru = "Дискета с картами"; - }; - tutorial_disk_inv = { - en = "A mapping program I purchased just some days ago. It has quite advanced features compared to the previous version. "; - ru = "Картографическая программа, приобретенная мной всего несколько дней назад. Обладает довольно продвинутыми возможностями поиска в сравнении с предыдущей версией. "; - }; - tutorial_box = { - en = "Box"; - ru = "Шкатулка"; - }; - tutorial_box_inv = { - en = "A small box. It's locked. "; - ru = "Небольшая шкатулка. Она заперта на замок. "; - }; - tutorial_box_used = { - en = "I open the box and take a map from it. "; - ru = "Я открываю шкатулку и достаю из нее карту. "; - }; - tutorial_box_used_hint = { - en = "Examine the map to continue. "; - ru = "Осмотрите карту, чтобы продолжить. "; - }; - tutorial_map = { - en = "Map"; - ru = "Карта"; - }; - tutorial_map_inv = { - en = "An ancient map of a small plot of land. A careful cross marks something, but I don't know what it is. "; - ru = 'Старинная карта небольшого участка земли. Аккуратная отметка в виде креста указывает на что-то, но я не знаю, на что именно.'; - }; - tutorial_map_hint_leave_treasury = { - en = "Return to the main hall and go to study from there. "; - ru = "Вернитесь в главный зал и перейдите оттуда в кабинет."; - }; - tutorial_map_hint_find_disk = { - en = "Find a floppy disk with the mapping program in the treasury. "; - ru = "Найдите в сокровищнице дискету с картографической программой."; - }; - tutorial_map_hint_go_to_study = { - en = "Go to study to continue. "; - ru = "Перейдите в кабинет, чтобы продолжить."; - }; - tutorial_start = { - en = "Welcome!"; - ru = "Добро пожаловать!"; - }; - tutorial_start_decor = { - en = [[ - Welcome to the game of "A Dragon and the Tower". This section will get you acquanted with the game and teach you how to play it. ^ - The game consists of rooms, each of them has title and description. Besides that a room can contain objects you can interact with. ^ - This is also a room. It is called "Welcome!" and you are reading it's description right now. - ]]; - ru = [[ - Добро пожаловать в игру "Дракон и Башня". Этот раздел познакомит вас с игрой и научит в нее играть. ^ + common_locale = { + back = { + en = "Back"; + ru = "Незад"; + }; + continue = { + en = "Continue"; + ru = "Продолжить"; + }; + }; + link_locale = { + copied = { + en = 'Copied'; + ru = 'Скопировано'; + } + }, + main_locale = { + empty_use_1 = { + en = 'It makes no sense. '; + ru = 'Это не имеет смысла. '; + }, + empty_use_2 = { + en = 'I don\'t understand what to do with this. '; + ru = 'Я не понимаю, что с этим делать. '; + }, + empty_use_3 = { + en = 'I have no reason to do this. '; + ru = 'Мне незачем это делать. '; + }, + empty_use_4 = { + en = 'It\'s a loss of time. '; + ru = 'Это пустая трата времени. '; + }, + empty_use_5 = { + en = 'This will not lead to anything. '; + ru = 'Это ни к чему не приведет. '; + }, + empty_use_6 = { + en = 'It\'s pointless. '; + ru = 'Бессмысленно.'; + }, + empty_act = { + en = 'I don\'t know what to do with this. '; + ru = 'Я не знаю, что с этим сделать. '; + }, + empty_inv = { + en = 'This is an item. It exists. '; + ru = 'Это предмет. Он существует. '; + }; + }; + menu_locale = { + system_settings = { + en = "System settings", + ru = "Системные настройки" + }, + language = { + en = "Language", + ru = "Язык" + }, + auto_option = { + en = "Auto", + ru = "Авто" + }, + graphic_scale = { + en = 'Graphics scale'; + ru = 'Масштаб графики'; + }, + font_scale = { + en = 'Font scale'; + ru = 'Масштаб шрифта'; + }, + inventory_scale = { + en = 'Inventory font scale'; + ru = 'Масштаб шрифта инвентаря'; + }, + text_width = { + en = 'Text width'; + ru = 'Ширина текста'; + }; + text_alignment = { + en = 'Text alignment'; + ru = 'Выравнивание текста'; + }; + aspect_ratio = { + en = 'Aspect ratio'; + ru = 'Соотношение сторон'; + }; + text_alignment_left = { + en = 'Left'; + ru = 'По левому краю'; + }; + text_alignment_justify = { + en = 'Justify'; + ru = 'По ширине'; + }; + padding = { + en = 'Padding'; + ru = 'Отступ'; + }; + interval = { + en = 'Line interval'; + ru = 'Межстрочный интервал'; + }; + normal = { + en = 'Normal'; + ru = 'Обычный'; + }; + extended = { + en = 'Large'; + ru = 'Увеличенный'; + }; + resolution_warning = { + en = 'A Dragon and the Tower requires resolution of at least 640x480. The game may not run properly on a lower resolution. Please ensure that your configuration is correct and your computer supports that resolution. After that please restart or load the game. '; + ru = 'Игра Дракон и Башня требует разрешение не менее 640х480. Игра может не работать корректно с более низким разрешением. Пожалуйста, убедитесь, что ваши настройки корректны и ваш компьютер поддерживает данное разрешение, после чего перезапустите или загрузите игру. '; + }; + warning = { + en = 'Warning'; + ru = 'Предупреждение'; + }; + theme_warning = { + en = 'A Dragon and the Tower requires custom game themes to be enabled. It will not work without this option enabled. Please change your settings and restart or load the game. '; + ru = 'Игра Дракон и Башня требует чтобы настройка "собственные темы игр" была включена. Она не будет работать без этой настройки. Пожалуйста, измените настройки и перезапустите или загрузите игру. '; + }; + intro = { + en = 'My footsteps resonate under the arches of ancient caverns. Irregular shadows dance in glimmering magical light. In my hand I hold a fragment of a map, carefully stored for millennia. Unwrapping the ancient scroll, I closely examine the markings on it: a forest, a mountain range, a road and a village, marked with a cross. Time to find this place! ^My body dissipates to fog and rebuilds in a human form. Quickly I go to a small door in one of the walls. There is nothing in the room, besides a stone desk and a laptop on it -- an absolutely essential thing in this time. Even for a dragon. A good mapping software and a proper query can do wonders -- couple of minutes later I fly out of the cave in my true form, spreading my wings to the wind. '; + ru = 'Гулким эхом разносятся мои шаги под сводами древних пещер. Неровные тени пляшут в дрожащем магическом свете. В руке я держу фрагмент карты, бережно хранимый с незапамятных времен. Развернув старинный свиток, я внимательно осматриваю нанесенные на него обозначения: лес, горная цепь, дорога и отмеченная крестом деревушка. Настало время найти это место! ^Мое тело расплывается туманом и собирается в облике человека. Быстрым шагом я направляюсь к небольшой дверце в одной из стен. В комнате нет ничего, кроме каменного стола и стоящего на нем ноутбука -- совершенно необходимой в наше время вещи. Даже для дракона. Хорошая картографическая программа и правильно сформулированный запрос творят чудеса -- уже через несколько минут я вылетаю из пещеры в своем истинном обличии, расправив крылья навстречу ветру. '; + }; + credits_author = { + en = 'Author'; + ru = 'Автор игры'; + }; + credits_art= { + en = 'Art'; + ru = 'Графика'; + }; + credits_music = { + en = 'Music'; + ru = 'Музыка'; + }; + credits_sounds = { + en = 'Sounds'; + ru = 'Звуки'; + }; + credits_fonts= { + en = 'Fonts'; + ru = 'Шрифты'; + }; + credits_thanks = { + en = 'Special thanks'; + ru = 'Благодарности'; + }; + credits_engine = { + en = 'Engine'; + ru = 'Движок'; + }; + credits_engine_author = { + en = 'Peter Kosyh'; + ru = 'Пётр Косых'; + }; + }, + terminal_locale = { + no_bootable_medium_found = { + en = 'No bootable medium found'; + ru = 'Загрузочное устройство недоступно'; + }, + bios = { + en = 'TOWER BIOS 1.0'; + ru = 'TOWER BIOS 1.0'; + }, + motherboard = { + en = 'Motherboard'; + ru = 'Система'; + }, + mhz = { + en = 'MHz'; + ru = 'МГц'; + }, + cpu = { + en = 'CPU'; + ru = 'ЦПУ'; + }, + ram = { + en = 'RAM'; + ru = 'Память'; + }, + kilobytes = { + en = 'KB'; + ru = 'КБ'; + }, + keyboard = { + en = 'Keyboard'; + ru = 'Клавиатура'; + }, + success = { + en = 'OK'; + ru = 'OK'; + }, + missing = { + en = 'Not installed'; + ru = 'Отсутствует'; + }, + disk = { + en = 'HDD'; + ru = 'Диск'; + }, + network = { + en = 'Network'; + ru = 'Сеть'; + }, + boot_from = { + en = 'Boot from '; + ru = 'Загрузка с '; + }, + network_2 = { + en = 'network'; + ru = 'сети'; + }, + no_device = { + en = 'none'; + ru = 'отсутствует'; + }, + tower_os_line_1 = { + en = 'Starting TOWER OS 1.0...'; + ru = 'Запуск TOWER OS 1.0...'; + }; + tower_os_line_2 = { + en = 'TOWER OS Version 1.0'; + ru = 'TOWER OS Версия 1.0'; + }; + tower_os_line_3 = { + en = "Type 'HELP' to list available commands"; + ru = "Введите 'HELP' для вывода списка доступных команд"; + }; + no_bootable_medium = { + en = 'No bootable medium found'; + ru = 'Загрузочное устройство недоступно'; + }; + }, + tutorial_locale = { + tutorial_key = { + en = "Key"; + ru = "Ключик"; + }; + tutorial_key_inv = { + en = "A small key The box it opens should be somewhere in the treasury. "; + ru = "Небольшой ключик от шкатулки. Она должна быть где-то в сокровищнице. "; + }; + tutorial_box_hint = { + en = "To open the box with the key, use it on the box. Click on the key and then on the box. "; + ru = "Для того чтобы открыть шкатулку ключом используйте его на шкатулке. Щелкните на ключ, а затем на шкатулку. "; + }; + tutorial_key_inv_look_for_box = { + en = "Try to find the box to continue. Remember that you can inspect items repeatedly. "; + ru = "Попробуйте найти шкатулку, чтобы продолжить. Помните, что вы можете повторно осматривать объекты. "; + }; + tutorial_disk = { + en = "Disk with maps"; + ru = "Дискета с картами"; + }; + tutorial_disk_inv = { + en = "A mapping program I purchased just some days ago. It has quite advanced features compared to the previous version. "; + ru = "Картографическая программа, приобретенная мной всего несколько дней назад. Обладает довольно продвинутыми возможностями поиска в сравнении с предыдущей версией. "; + }; + tutorial_box = { + en = "Box"; + ru = "Шкатулка"; + }; + tutorial_box_inv = { + en = "A small box. It's locked. "; + ru = "Небольшая шкатулка. Она заперта на замок. "; + }; + tutorial_box_used = { + en = "I open the box and take a map from it. "; + ru = "Я открываю шкатулку и достаю из нее карту. "; + }; + tutorial_box_used_hint = { + en = "Examine the map to continue. "; + ru = "Осмотрите карту, чтобы продолжить. "; + }; + tutorial_map = { + en = "Map"; + ru = "Карта"; + }; + tutorial_map_inv = { + en = "An ancient map of a small plot of land. A careful cross marks something, but I don't know what it is. "; + ru = 'Старинная карта небольшого участка земли. Аккуратная отметка в виде креста указывает на что-то, но я не знаю, на что именно.'; + }; + tutorial_map_hint_leave_treasury = { + en = "Return to the main hall and go to study from there. "; + ru = "Вернитесь в главный зал и перейдите оттуда в кабинет."; + }; + tutorial_map_hint_find_disk = { + en = "Find a floppy disk with the mapping program in the treasury. "; + ru = "Найдите в сокровищнице дискету с картографической программой."; + }; + tutorial_map_hint_go_to_study = { + en = "Go to study to continue. "; + ru = "Перейдите в кабинет, чтобы продолжить."; + }; + tutorial_start = { + en = "Welcome!"; + ru = "Добро пожаловать!"; + }; + tutorial_start_decor = { + en = [[ + Welcome to the game of "A Dragon and the Tower". This section will get you acquanted with the game and teach you how to play it. ^ + The game consists of rooms, each of them has title and description. Besides that a room can contain objects you can interact with. ^ + This is also a room. It is called "Welcome!" and you are reading it's description right now. + ]]; + ru = [[ + Добро пожаловать в игру "Дракон и Башня". Этот раздел познакомит вас с игрой и научит в нее играть. ^ Игра состоит из комнат, у каждой из которых есть название и описание. Кроме того, в комнате могут находиться объекты, с которыми вы можете взаимодействовать. ^ Это тоже комната. Она называется "Добро пожаловать!", а описание ее вы сейчас читаете. - ]]; - }; - tutorial_start_decor_hint = { - en = 'We propose you to play a small prologue to A Dragon and the Tower. We will mark instructions and comments with a bold font. Press "Continue" to begin the prologue. '; - ru = 'Мы предлагаем вам сыграть в небольшой пролог к Дракону и Башне. Жирным шрифтом мы будем выделять инструкции и комментарии. Нажмите "Продолжить", чтобы начать пролог. '; - }; - tutorial_lair = { - en = "Lair, Main Hall"; - ru = "Логово, главный зал"; - }; - tutorial_lair_decor_1 = { - en = "My lair is a network of small {#caves|caves}"; - ru = "Мое логово представляет собой сеть из нескольких {#caves|пещер}"; - }; - tutorial_lair_decor_hint_caves = { - en = "Click highlighted text to inspect the caves"; - ru = "Нажмите на подсвеченный текст, чтобы осмотреть пещеры"; - }; - tutorial_lair_decor_2 = { - en = "Now I stand in the largest of them. Rough walls and tall arches of stone are filled with sunlight, through an enourmous {#exit|opening in the ceiling}. "; - ru = "Сейчас я нахожусь в самой большой из них. Неровные стены и высокие каменные своды освещены солнцем, свет которого свободно проникает через огромное {#exit|отверстие в потолке}. "; - }; - tutorial_lair_decor_hint_treasury = { - en = 'Separated from the rest of the text are transition links. Transitions "To Treasury" and "To Study" are available to you now. Go to the treasury to continue. '; - ru = 'Отдельно от основного текста находятся ссылки-переходы. Сейчас вам доступны переходы "В сокровищницу" и "В кабинет". Перейдите в сокровищницу, чтобы продолжить. '; - }; - tutorial_lair_decor_hint_study = { - en = "Go to the study to continue. "; - ru = "Перейдите в кабинет, чтобы продолжить. "; - }; - tutorial_lair_enter_start = { - en = "I awaken and open my eyes. Quickly glancing around the lair I begin transformation. My body dissipates in gray smoke and rebuilds again, taking human appearance. "; - ru = "Я просыпаюсь и открываю глаза. Бегло осмотрев логово, я начинаю превращаться. Мое тело расплывается серым дымом и собирается вновь, уже в облике человека."; - }; - tutorial_lair_enter_treasury = { - en = "I have not yet finished my affairs here. "; - ru = "Я еще не закончил свои дела здесь. "; - }; - tutorial_lair_enter_disk = { - en = "You need to find the floppy disk with a mapping program to continue. "; - ru = "Вам необходимо найти дискету с картографической программой, чтобы продолжить. "; - }; - tutorial_to_treasury = { - en = "To Treasury"; - ru = "В сокровищницу"; - }; - tutorial_to_study = { - en = "To Study"; - ru = "В кабинет"; - }; - tutorial_to_main_hall = { - en = 'To Main Hall'; - ru = 'В главный зал'; - }; - tutorial_to_main_menu = { - en = 'To Main Menu'; - ru = 'В главное меню'; - }; - tutorial_to_game = { - en = 'Start Game'; - ru = 'Начать игру'; - }; - tutorial_lair_caves_act = { - en = "I found these caves centuries ago. I had to widen some of the passages, but overall I kept their natural appearance. "; - ru = "Я нашел эту сеть пещер несколько столетий назад. Часть проходов пришлось расширить, но в остальном я сохранил естественные их формы. "; - }; - tutorial_lair_caves_act_hint = { - en = "Click on the objects to interact with them. Some of them you can take or use, others -- only inspect. "; - ru = "Щелкайте на объекты для взаимодействия с ними. Некоторые объекты вы сможете взять с собой или использовать, другие -- только осмотреть. "; - }; - tutorial_lair_exit_act = { - en = 'A large opening I made to freely leave and return to my lair. It is, of course, not the only exit from my home. '; - ru = 'Огромное отверстие, которое я проделал для того чтобы свободно покидать и возвращаться в свое логово. Разумеется, это не единственный выход из моего дома. '; - }; - tutorial_treasury = { - en = 'Lair, Treasury'; - ru = 'Логово, сокровищница'; - }; - tutorial_treasury_no_enter = { - en = "I have nothing to do there. "; - ru = "Мне там больше нечего делать. "; - }; - tutorial_treasury_decor = { - en = 'Here I keep the most precious stuff I have. Shelves with various {#items|items} are positioned along the walls. In the center of the hall there are several large {#chests|chests}. '; - ru = 'Здесь я храню самые ценные из имеющихся у меня вещей. Вдоль стен расположены стеллажи, на которых лежат различные {#items|предметы}. В центре зала стоят несколько огромных {#chests|сундуков}. '; - }; - tutorial_treasury_decor_hint_map = { - en = 'To succeed in this game, you will need to carefully read texts and examine places you visit. Try to find a map. '; - ru = 'Для достижения успеха в игре, вам придется внимательно читать тексты и осматривать места, где вы находитесь. Попробуйте найти карту. '; - }; - tutorial_treasury_decor_hint_leave = { - en = 'Leave the treasury to continue. '; - ru = 'Для продолжения покиньте сокровищницу. '; - }; - tutorial_treasury_items_act= { - en = 'I glance at the shelves with all kinds of stuff: {#books|books}, {#scrolls|scrolls}, {#records|vinyl records}, {#disks|floppy disks}, {#paintings|paintings} and lots of other things. '; - ru = 'Я бегло оглядываю стеллажи, заполненные всевозможными предметами: {#books|книгами}, {#scrolls|свитками}, {#records|виниловыми пластинками}, {#disks|дискетами}, {#paintings|картинами} и много чем еще. '; - }; - tutorial_treasury_chests_act_key = { - en = 'Upon one of the chests I find a small key. I take it. '; - ru = 'На одном из сундуков лежит небольшой ключик. Я забираю его с собой. '; - }; - tutorial_treasury_chests_act_key_hint = { - en = 'You have taken the key and it has appeared in your inventory. Examine it by clicking on it two times. '; - ru = 'Вы взяли ключик и он появился в инвентаре. Осмотрите его. Для этого щелкните по нему два раза. '; - }; - tutorial_treasury_chests_act_box = { - en = 'In one of the chests I find a small box. '; - ru = 'В одном из сундуков я нахожу небольшую шкатулку. '; - }; - tutorial_treasury_chests_act_default = { - en = 'My treasure!'; - ru = 'Мои сокровища!'; - }; - tutorial_treasury_books = { - en = 'A collection of books I gathered for centuries of my life in this world. '; - ru = 'Коллекция книг, собранная мной за сотни лет жизни в этом мире. '; - }; - tutorial_treasury_scrolls = { - en = 'Scrolls with various writings of this world. I do not have everything I would like to -- I did not have the chance to get a lot of things. '; - ru = 'Свитки с различными писаниями этого мира. Их не так много, как хотелось бы -- многие вещи я не успел заполучить. '; - }; - tutorial_treasury_scrolls_no_map = { - en = 'I do not see the map I look for among them. '; - ru = 'Интересующей меня карты я среди них не вижу.'; - }; - tutorial_treasury_records = { - en = 'A relatively recent invention, but widespread enough. I have gathered a number of records, most valuable to me. '; - ru = 'Относительно недавнее изобретение, однако получившее широкое распространение. Я собрал некоторое количество наиболее интересных мне записей. '; - }; - tutorial_treasury_disks = { - en = 'Standard 3.5 and 5.25 inch floppy disks with software for my laptop. '; - ru = 'Стандартные трех- и пятидюймовые дискеты с программами для моего ноутбука. '; - }; - tutorial_treasury_disks_default = { - en = 'Even being a dragon I have to keep up to date. '; - ru = 'Даже мне, дракону, приходится идти в ногу со временем. '; - }; - tutorial_treasury_disks_found = { - en = 'I easily find the one I seek. '; - ru = 'Я легко нахожу среди них искомую.'; - }; - tutorial_treasury_disks_hint = { - en = 'Time to use the items I found. Leave the treasury to continue. '; - ru = 'Самое время использовать найденные предметы. Покиньте сокровищницу. '; - }; - tutorial_treasury_paintings = { - en = 'Mostly reproductions of works I find most intriguing. '; - ru = 'Это в основном репродукции наиболее интересных мне работ. '; - }; - tutorial_study = { - en = 'Lair, Study'; - ru = 'Логово, кабинет'; - }; - tutorial_study_decor = { - en = 'A small round cave about three meters high and no more than three in diameter. Near the wall I have placed a desk, on which a {#laptop|a laptop} rests. It\'s time to find the place I seek. '; - ru = 'Небольшая круглая пещерка, около трех метров высотой и не более трех метров в диаметре. У стены я поместил стол, на котором сейчас покоится {#laptop|ноутбук}. Настало время узнать, где же находится это место.'; - }; - tutorial_study_decor_hint = { - en = 'To complete the tutorial, use the disk with maps on a laptop. To do that, click once on the object in inventory, and then on the object in the room. '; - ru = 'Чтобы закончить обучение, используйте дискету с картами на ноутбук. Для этого нажмите один раз на предмет в инвентаре, а потом на предмет в комнате. '; - }; - tutorial_study_enter = { - en = 'I don\'t need to go there yet. '; - ru = 'Мне пока сюда не нужно. '; - }; - tutorial_study_enter_hint = { - en = 'Actions of your character will not be always successful. Carefully read the texts to understand, why the game does not let you perform certain actions. '; - ru = 'Не всегда действия вашего персонажа будут успешны. Внимательно читайте тексты, чтобы понять, почему игра не позволяет вам выполнить то или иное действие. '; - }; - tutorial_study_laptop_act = { - en = 'A laptop I bought couple of years ago. It does not have modern CD-ROM drive and it\'s not the most powerful by current standards, but it is enough for my needs. '; - ru = 'Ноутбук, купленный пару лет назад. В нем нет новомодного привода для компакт-дисков, и он не очень производительный по текущим меркам, но для моих нужд его вполне хватает.'; - }; - tutorial_end = { - en = 'Congratulations!'; - ru = 'Поздравляем!'; - }; - tutorial_end_decor = { - en = 'I insert the disk and turn on the laptop. Having started the mapping program I begin the search. A proper query can do wonders and, a few minutes later, I fly out of the cave in my true form, spreading my wings to the wind. '; - ru = 'Я вставляю дискету и включаю ноутбук. Запустив картографическую программу, я начинаю поиск нужного места. Правильно сформулированный запрос творит чудеса, и уже через несколько минут я выбегаю из пещеры в своем истинном обличии, расправив крылья навстречу ветру.'; - }; - tutorial_end_decor_hint = { - en = 'Congratulations! You have completed the tutorial and now can start the main game. Be prepared to act and think on your own. There will be no more hints. '; - ru = 'Поздравляем! Вы успешно завершили обучение и можете начинать основную игру. Будьте готовы действовать и думать самостоятельно. Подсказок больше не будет. '; - }; - }; - forest_locale = { - raspberry_pie = { - en = 'Raspberry pie'; - ru = 'Малиновый пирог'; - }; - raspberry_pie_inv = { - en = 'I inhale marvelous aroma of a fresh raspberry pie. Unfortunately, I cannot eat it, but I will definitely return here once to get a piece for myself. '; - ru = 'Я вдыхаю восхитительный аромат свежего малинового пирога. К сожалению, я не могу его съесть, но я точно вернусь сюда когда-нибудь за кусочком для себя. '; - }; - flower = { - en = 'Flower'; - ru = 'Цветок'; - }; - flower_inv = { - en = 'A small, but beautiful flower with thin and long sky-blue petals. '; - ru = 'Небольшой, но очень красивый цветок с тонкими вытянутыми лепестками небесно-голубого цвета.'; - }; - lock = { - en = 'Padlock'; - ru = 'Замок'; - }; - lock_disp2 = { - en = 'padlock'; - ru = 'замок'; - }; - lock_disp3 = { - en = 'padlock'; - ru = 'замок'; - }; - lock_inv = { - en = 'A small metal padlock, very old and thoroughly rusted. '; - ru = 'Небольшой металлический замочек, очень старый и изрядно проржавевший.'; - }; - above_forest = { - en = 'Above the Forest'; - ru = 'Над лесом'; - }; - above_forest_decor = { - en = [[Occasionally flapping my wings, I soar above {#thicket|the thicket} below. To the west I see {mountains|a mountain range}, extending south and north as far as I can see. An old asphalted {#road|road} writhes below like a narrow stream. Along it stretches {#powerlines|a power line}. A bit aside from the road I can see a small {#glade|glade}. Cool {wind|wind} touches my scales and bright summer {sun|sun} seeps through thin fleecy {clouds|clouds}. ]]; - ru = [[Изредка взмахивая крыльями, я парю над раскинувшейся внизу {#thicket|чащей}. На западе я вижу {mountains|горную цепь}, протянувшуюся на юг и на север до самого горизонта. Тонкой струйкой внизу извивается старая асфальтированная {#road|дорога}. Вдоль нее тянутся линии {#powerlines|электропередач}. Чуть в стороне от дороги я могу разглядеть небольшую {#glade|полянку}. Прохладный {wind|ветерок} ласкает чешую, а яркое летнее {sun|солнце} пробивается сквозь тонкие перистые {clouds|облака}. ]]; - }; - above_forest_decor_village = { - en = 'The village I seek should be somewhere nearby. '; - ru = 'Деревня, что я ищу, должна быть где-то здесь. '; - }; - above_forest_enter = { - en = 'With a quick flap of my wings I rise from the Earth and rush into the sky. '; - ru = 'Резко взмахнув крыльями, я отрываюсь от земли и устремляюсь ввысь. '; - }; - transition_land = { - en = 'Land'; - ru = 'Приземлиться'; - }; - transition_south_along_road = { - en = 'South, Along the Road'; - ru = 'На юг, вдоль дороги'; - }; - transition_north_along_road = { - en = 'North, Along the Road'; - ru = 'На север, вдоль дороги'; - }; - transition_north_to_the_village= { - en = 'North, to the Village'; - ru = 'На север, к деревне'; - }; - transition_fly = { - en = 'Take Off'; - ru = 'Взлететь'; - }; - transition_west = { - en = 'West'; - ru = 'На запад'; - }; - above_forest_thicket_act = { - en = 'Ancient forests cover the land like a green blanket. Mild wind barely sways the treetops. Even here, hundreds of meters above ground, I sense a slight scent of conifer. '; - ru = 'Древние леса зеленым ковром покрывают землю. Вершины деревьев едва покачиваются от легкого ветерка. Даже здесь, на высоте нескольких сотен метров, я ощущаю легкий запах хвои. '; - }; - above_forest_road_act = { - en = 'Cracked asphalt looks like a dry riverbed. Road is deserted, as if this place has been uninhabited long ago. '; - ru = 'Потрескавшийся асфальт напоминает русло засохшей реки. Дорога пустынна, словно это место давно покинуто людьми. '; - }; - above_forest_road_act_village = { - en = 'What if I find only lifeless windows of empty houses there?'; - ru = 'Что если меня ждут лишь безжизненные окна пустых домов?'; - }; - above_forest_powerlines_act = { - en = 'Towers are positioned along the road on equal distance from each other. Thick high-voltage cables are stretched between them. '; - ru = 'Вышки установлены вдоль дороги на равных расстояниях друг от друга, Между ними натянуты толстые высоковольтные провода. '; - }; - above_forest_glade_act = { - en = 'A small glade, covered with a patchwork of flowers and grass. '; - ru = 'Небольшая полянка, усеянная пестрым ковром из цветов и трав. '; - }; - above_forest_glade_act_first = { - en = 'A great place to take some rest. '; - ru = 'Отличное место чтобы передохнуть. '; - }; - forest_glade = { - en = 'Glade'; - ru = 'Поляна'; - }; - forest_glade_enter = { - en = 'I land on a small glade inside forest. There is no need to hide, so I stay in my real form. '; - ru = 'Я приземляюсь на небольшой полянке в лесу. Здесь нет нужды прятаться, поэтому я остаюсь в истинном обличии. '; - }; - forest_glade_solarscale = { - en = 'Solarscale touches ground near me. Thrilled and entusiastic she starts examining local flora. "What a beauty!" -- she exclaims. '; - ru = 'Соларскейл опускается на землю неподалеку от меня. С воодушевлением и трепетом она начинает разглядывать местные растения. "Какая красота!" -- восклицает она. '; - }; - forest_glade_decor = { - en = 'I stand in the middle of a small glade, surronded with a wall of {#thciket|trees}. It is calm and quiet here. I can only hear leaves rustling and {#birds|birds} singing. Mild wind barely sways the treetops. Emerald-green {#grass|grass} reaches my heels. '; - ru = 'Я стою посреди небольшой полянки, со всех сторон окруженной стеной {#thicket|леса}. Здесь тихо и спокойно. Я слышу только шелест листвы и пение {#birds|птиц}. Легкий ветерок еле заметно качает вершины {#thicket|деревьев}. Изумрудно-зеленая {#grass|трава} достигает моих пяток. '; - }; - forest_glade_thicket = { - en = 'Trees surround the glade with a solid wall, like vigilant sentinels, keeping watch over this place. '; - ru = 'Деревья окружают поляну сплошной стеной, словно бдительные стражи, охраняющие покой этого места. '; - }; - forest_glade_birds = { - en = 'From deep within forest I hear a multitude of chirping birds, but I don\'t see any of them nearby. '; - ru = 'Где-то в глубине леса я слышу щебетание множества птиц, однако я не вижу ни одной поблизости. '; - }; - forest_glade_grass = { - en = 'Thick high grass covers the whole glade. It would reach average human\'s waist, but for me it barely touches heels. Here and there I can see tiny patches of {#flowers|flowers} hidden in it. '; - ru = 'Высокая густая трава покрывает всю поляну. Человеку она была бы по пояс, но мне она едва достигает пяток. Тут и там я замечаю небольшие скопления {#flowers|цветов}, скрытые в ней. '; - }; - forest_glade_flowers_first = { - en = 'Unusual flowers with elongated sky-blue petals catch my attention. They grow on the edge of the glade. I pick one and take it with me. Some magic and it will never wither. '; - ru = 'Мое внимание привлекают необычные цветы с вытянутыми лепестками небесно-голубого цвета, растущие на краю поляны. Я срываю один и забираю с собой. Немного магии, и он уже никогда не завянет. '; - }; - forest_glade_flowers = { - en = 'Quite a lot of nice flowers grows here. '; - ru = 'Здесь растет немало красивых цветов. '; - }; - above_near_village = { - en = 'South of the Village'; - ru = 'К югу от деревни'; - }; - above_near_village_enter = { - en = 'A fog surrounds my body and in a moment, not a nameless stranger, but a mighty dragon is standing on the road. With a flap of wings, I leave the Earth far below. '; - ru = 'Мое тело окутывает туман и через мгновение на дороге уже стоит не безымянный странник, а могучий дракон. Взмахнув крыльями, я оставляю землю далеко внизу. '; - }; - above_near_village_decor = { - en = 'Wings carry me above the forest {#road|road}. I have travelled a dozen kilometers but seemingly nothing has changed at all: a neverending {#thicket|thicket} still lies below, and {mountains|the mountain range} still stretches far away. To the north, near the horizon I notice a small {#village|village}. '; - ru = 'Крылья несут меня над лесной {#road|дорогой}. Я пролетел с десяток километров, но, кажется, не изменилось вообще ничего: внизу все так же расстилается бескрайняя {#thicket|чаща}, а {mountains|горная цепь} на западе продолжает тянуться вдаль. На севере, у самого горизонта, я замечаю небольшую {#village|деревушку}. '; - }; - above_near_village_road = { - en = 'Road looks long unused. Asphalt has cracked in a lot of places, and green stalks have started to grow through it. '; - ru = 'Дорога выглядит давно не используемой. Асфальт во многих местах потрескался, и сквозь него кое-где пробиваются зеленые стебельки.'; - }; - above_near_village_thicket = { - en = 'Looks like the forest is endless. A mild wind sways the treetops, raising thick conifer scent, noticeable even here, hundreds of meters above ground. '; - ru = 'Кажется, лесу нет конца и края. Легкий ветерок колышет вершины деревьев, поднимая густой хвойный аромат, ощутимый даже здесь, на высоте нескольких сотен метров. '; - }; - above_near_village_village = { - en = 'From here I can see a tavern and a town hall in the center of the village. Around them little houses are scattered, surrounded by greenery. '; - ru = 'Отсюда я могу разглядеть трактир и ратушу в центре деревни. Вокруг них разбросаны утопающие в зелени домики. '; - }; - village_unvisited = { - en = 'The village is definitely inhabited. '; - ru = 'Деревня определенно не заброшена. '; - }; - above_village = { - en = 'Above the Village'; - ru = 'Над деревней'; - }; - above_village_decor = { - en = 'Thin fleecy {clouds|clouds} keep floating above me, barely covering {sun|the sun} and below stretches an endless sea of {#thicket|forest}, cut by {mountains|the mountain range} to the west. Old asphalted {#road|road} leads to {#village|the village} below me. '; - ru = 'Надо мной все так же проплывают тонкие перистые {clouds|облака}, едва прикрывая собой {sun|солнце}, а внизу простирается бескрайнее море {#thicket|леса}, взрезанное на западе {mountains|горной грядой}. Старая асфальтированная {#road|дорога} ведет в {#village|деревню}, расположенную подо мной. '; - }; - above_village_thicket = { - en = 'Thick conifer forest surrounds a small village from all sides, trying to devour it without success. '; - ru = 'Густой хвойный лес плотным кольцом обступает небольшую деревеньку со всех сторон, безуспешно пытаясь поглотить ее. '; - }; - above_village_road = { - en = 'Obviously locals rarely use this way. Road is empty and asphalt does not get due maintenance. '; - ru = 'Очевидно, местные жители нечасто пользуются этим путем. Дорога пустует, а асфальт не получает должного ремонта. '; - }; - above_village_village = { - en = 'From here I can see the village surrounded by greenery. In it\'s center lies a square, near it town hall and a tavern are situated. On the north of the village a library is located. '; - ru = 'Отсюда я могу хорошо разглядеть утопающую в зелени деревню. В центре ее расстилается площадь, рядом с которой находятся ратуша и трактир. На севере деревни располагается библиотека. '; - }; - }; + ]]; + }; + tutorial_start_decor_hint = { + en = 'We propose you to play a small prologue to A Dragon and the Tower. We will mark instructions and comments with a bold font. Press "Continue" to begin the prologue. '; + ru = 'Мы предлагаем вам сыграть в небольшой пролог к Дракону и Башне. Жирным шрифтом мы будем выделять инструкции и комментарии. Нажмите "Продолжить", чтобы начать пролог. '; + }; + tutorial_lair = { + en = "Lair, Main Hall"; + ru = "Логово, главный зал"; + }; + tutorial_lair_decor_1 = { + en = "My lair is a network of small {#caves|caves}"; + ru = "Мое логово представляет собой сеть из нескольких {#caves|пещер}"; + }; + tutorial_lair_decor_hint_caves = { + en = "Click highlighted text to inspect the caves"; + ru = "Нажмите на подсвеченный текст, чтобы осмотреть пещеры"; + }; + tutorial_lair_decor_2 = { + en = "Now I stand in the largest of them. Rough walls and tall arches of stone are filled with sunlight, through an enourmous {#exit|opening in the ceiling}. "; + ru = "Сейчас я нахожусь в самой большой из них. Неровные стены и высокие каменные своды освещены солнцем, свет которого свободно проникает через огромное {#exit|отверстие в потолке}. "; + }; + tutorial_lair_decor_hint_treasury = { + en = 'Separated from the rest of the text are transition links. Transitions "To Treasury" and "To Study" are available to you now. Go to the treasury to continue. '; + ru = 'Отдельно от основного текста находятся ссылки-переходы. Сейчас вам доступны переходы "В сокровищницу" и "В кабинет". Перейдите в сокровищницу, чтобы продолжить. '; + }; + tutorial_lair_decor_hint_study = { + en = "Go to the study to continue. "; + ru = "Перейдите в кабинет, чтобы продолжить. "; + }; + tutorial_lair_enter_start = { + en = "I awaken and open my eyes. Quickly glancing around the lair I begin transformation. My body dissipates in gray smoke and rebuilds again, taking human appearance. "; + ru = "Я просыпаюсь и открываю глаза. Бегло осмотрев логово, я начинаю превращаться. Мое тело расплывается серым дымом и собирается вновь, уже в облике человека."; + }; + tutorial_lair_enter_treasury = { + en = "I have not yet finished my affairs here. "; + ru = "Я еще не закончил свои дела здесь. "; + }; + tutorial_lair_enter_disk = { + en = "You need to find the floppy disk with a mapping program to continue. "; + ru = "Вам необходимо найти дискету с картографической программой, чтобы продолжить. "; + }; + tutorial_to_treasury = { + en = "To Treasury"; + ru = "В сокровищницу"; + }; + tutorial_to_study = { + en = "To Study"; + ru = "В кабинет"; + }; + tutorial_to_main_hall = { + en = 'To Main Hall'; + ru = 'В главный зал'; + }; + tutorial_to_main_menu = { + en = 'To Main Menu'; + ru = 'В главное меню'; + }; + tutorial_to_game = { + en = 'Start Game'; + ru = 'Начать игру'; + }; + tutorial_lair_caves_act = { + en = "I found these caves centuries ago. I had to widen some of the passages, but overall I kept their natural appearance. "; + ru = "Я нашел эту сеть пещер несколько столетий назад. Часть проходов пришлось расширить, но в остальном я сохранил естественные их формы. "; + }; + tutorial_lair_caves_act_hint = { + en = "Click on the objects to interact with them. Some of them you can take or use, others -- only inspect. "; + ru = "Щелкайте на объекты для взаимодействия с ними. Некоторые объекты вы сможете взять с собой или использовать, другие -- только осмотреть. "; + }; + tutorial_lair_exit_act = { + en = 'A large opening I made to freely leave and return to my lair. It is, of course, not the only exit from my home. '; + ru = 'Огромное отверстие, которое я проделал для того чтобы свободно покидать и возвращаться в свое логово. Разумеется, это не единственный выход из моего дома. '; + }; + tutorial_treasury = { + en = 'Lair, Treasury'; + ru = 'Логово, сокровищница'; + }; + tutorial_treasury_no_enter = { + en = "I have nothing to do there. "; + ru = "Мне там больше нечего делать. "; + }; + tutorial_treasury_decor = { + en = 'Here I keep the most precious stuff I have. Shelves with various {#items|items} are positioned along the walls. In the center of the hall there are several large {#chests|chests}. '; + ru = 'Здесь я храню самые ценные из имеющихся у меня вещей. Вдоль стен расположены стеллажи, на которых лежат различные {#items|предметы}. В центре зала стоят несколько огромных {#chests|сундуков}. '; + }; + tutorial_treasury_decor_hint_map = { + en = 'To succeed in this game, you will need to carefully read texts and examine places you visit. Try to find a map. '; + ru = 'Для достижения успеха в игре, вам придется внимательно читать тексты и осматривать места, где вы находитесь. Попробуйте найти карту. '; + }; + tutorial_treasury_decor_hint_leave = { + en = 'Leave the treasury to continue. '; + ru = 'Для продолжения покиньте сокровищницу. '; + }; + tutorial_treasury_items_act= { + en = 'I glance at the shelves with all kinds of stuff: {#books|books}, {#scrolls|scrolls}, {#records|vinyl records}, {#disks|floppy disks}, {#paintings|paintings} and lots of other things. '; + ru = 'Я бегло оглядываю стеллажи, заполненные всевозможными предметами: {#books|книгами}, {#scrolls|свитками}, {#records|виниловыми пластинками}, {#disks|дискетами}, {#paintings|картинами} и много чем еще. '; + }; + tutorial_treasury_chests_act_key = { + en = 'Upon one of the chests I find a small key. I take it. '; + ru = 'На одном из сундуков лежит небольшой ключик. Я забираю его с собой. '; + }; + tutorial_treasury_chests_act_key_hint = { + en = 'You have taken the key and it has appeared in your inventory. Examine it by clicking on it two times. '; + ru = 'Вы взяли ключик и он появился в инвентаре. Осмотрите его. Для этого щелкните по нему два раза. '; + }; + tutorial_treasury_chests_act_box = { + en = 'In one of the chests I find a small box. '; + ru = 'В одном из сундуков я нахожу небольшую шкатулку. '; + }; + tutorial_treasury_chests_act_default = { + en = 'My treasure!'; + ru = 'Мои сокровища!'; + }; + tutorial_treasury_books = { + en = 'A collection of books I gathered for centuries of my life in this world. '; + ru = 'Коллекция книг, собранная мной за сотни лет жизни в этом мире. '; + }; + tutorial_treasury_scrolls = { + en = 'Scrolls with various writings of this world. I do not have everything I would like to -- I did not have the chance to get a lot of things. '; + ru = 'Свитки с различными писаниями этого мира. Их не так много, как хотелось бы -- многие вещи я не успел заполучить. '; + }; + tutorial_treasury_scrolls_no_map = { + en = 'I do not see the map I look for among them. '; + ru = 'Интересующей меня карты я среди них не вижу.'; + }; + tutorial_treasury_records = { + en = 'A relatively recent invention, but widespread enough. I have gathered a number of records, most valuable to me. '; + ru = 'Относительно недавнее изобретение, однако получившее широкое распространение. Я собрал некоторое количество наиболее интересных мне записей. '; + }; + tutorial_treasury_disks = { + en = 'Standard 3.5 and 5.25 inch floppy disks with software for my laptop. '; + ru = 'Стандартные трех- и пятидюймовые дискеты с программами для моего ноутбука. '; + }; + tutorial_treasury_disks_default = { + en = 'Even being a dragon I have to keep up to date. '; + ru = 'Даже мне, дракону, приходится идти в ногу со временем. '; + }; + tutorial_treasury_disks_found = { + en = 'I easily find the one I seek. '; + ru = 'Я легко нахожу среди них искомую.'; + }; + tutorial_treasury_disks_hint = { + en = 'Time to use the items I found. Leave the treasury to continue. '; + ru = 'Самое время использовать найденные предметы. Покиньте сокровищницу. '; + }; + tutorial_treasury_paintings = { + en = 'Mostly reproductions of works I find most intriguing. '; + ru = 'Это в основном репродукции наиболее интересных мне работ. '; + }; + tutorial_study = { + en = 'Lair, Study'; + ru = 'Логово, кабинет'; + }; + tutorial_study_decor = { + en = 'A small round cave about three meters high and no more than three in diameter. Near the wall I have placed a desk, on which a {#laptop|a laptop} rests. It\'s time to find the place I seek. '; + ru = 'Небольшая круглая пещерка, около трех метров высотой и не более трех метров в диаметре. У стены я поместил стол, на котором сейчас покоится {#laptop|ноутбук}. Настало время узнать, где же находится это место.'; + }; + tutorial_study_decor_hint = { + en = 'To complete the tutorial, use the disk with maps on a laptop. To do that, click once on the object in inventory, and then on the object in the room. '; + ru = 'Чтобы закончить обучение, используйте дискету с картами на ноутбук. Для этого нажмите один раз на предмет в инвентаре, а потом на предмет в комнате. '; + }; + tutorial_study_enter = { + en = 'I don\'t need to go there yet. '; + ru = 'Мне пока сюда не нужно. '; + }; + tutorial_study_enter_hint = { + en = 'Actions of your character will not be always successful. Carefully read the texts to understand, why the game does not let you perform certain actions. '; + ru = 'Не всегда действия вашего персонажа будут успешны. Внимательно читайте тексты, чтобы понять, почему игра не позволяет вам выполнить то или иное действие. '; + }; + tutorial_study_laptop_act = { + en = 'A laptop I bought couple of years ago. It does not have modern CD-ROM drive and it\'s not the most powerful by current standards, but it is enough for my needs. '; + ru = 'Ноутбук, купленный пару лет назад. В нем нет новомодного привода для компакт-дисков, и он не очень производительный по текущим меркам, но для моих нужд его вполне хватает.'; + }; + tutorial_end = { + en = 'Congratulations!'; + ru = 'Поздравляем!'; + }; + tutorial_end_decor = { + en = 'I insert the disk and turn on the laptop. Having started the mapping program I begin the search. A proper query can do wonders and, a few minutes later, I fly out of the cave in my true form, spreading my wings to the wind. '; + ru = 'Я вставляю дискету и включаю ноутбук. Запустив картографическую программу, я начинаю поиск нужного места. Правильно сформулированный запрос творит чудеса, и уже через несколько минут я выбегаю из пещеры в своем истинном обличии, расправив крылья навстречу ветру.'; + }; + tutorial_end_decor_hint = { + en = 'Congratulations! You have completed the tutorial and now can start the main game. Be prepared to act and think on your own. There will be no more hints. '; + ru = 'Поздравляем! Вы успешно завершили обучение и можете начинать основную игру. Будьте готовы действовать и думать самостоятельно. Подсказок больше не будет. '; + }; + }; + forest_locale = { + raspberry_pie = { + en = 'Raspberry pie'; + ru = 'Малиновый пирог'; + }; + raspberry_pie_inv = { + en = 'I inhale marvelous aroma of a fresh raspberry pie. Unfortunately, I cannot eat it, but I will definitely return here once to get a piece for myself. '; + ru = 'Я вдыхаю восхитительный аромат свежего малинового пирога. К сожалению, я не могу его съесть, но я точно вернусь сюда когда-нибудь за кусочком для себя. '; + }; + flower = { + en = 'Flower'; + ru = 'Цветок'; + }; + flower_inv = { + en = 'A small, but beautiful flower with thin and long sky-blue petals. '; + ru = 'Небольшой, но очень красивый цветок с тонкими вытянутыми лепестками небесно-голубого цвета.'; + }; + lock = { + en = 'Padlock'; + ru = 'Замок'; + }; + lock_disp2 = { + en = 'padlock'; + ru = 'замок'; + }; + lock_disp3 = { + en = 'padlock'; + ru = 'замок'; + }; + lock_inv = { + en = 'A small metal padlock, very old and thoroughly rusted. '; + ru = 'Небольшой металлический замочек, очень старый и изрядно проржавевший.'; + }; + above_forest = { + en = 'Above the Forest'; + ru = 'Над лесом'; + }; + above_forest_decor = { + en = [[Occasionally flapping my wings, I soar above {#thicket|the thicket} below. To the west I see {mountains|a mountain range}, extending south and north as far as I can see. An old asphalted {#road|road} writhes below like a narrow stream. Along it stretches {#powerlines|a power line}. A bit aside from the road I can see a small {#glade|glade}. Cool {wind|wind} touches my scales and bright summer {sun|sun} seeps through thin fleecy {clouds|clouds}. ]]; + ru = [[Изредка взмахивая крыльями, я парю над раскинувшейся внизу {#thicket|чащей}. На западе я вижу {mountains|горную цепь}, протянувшуюся на юг и на север до самого горизонта. Тонкой струйкой внизу извивается старая асфальтированная {#road|дорога}. Вдоль нее тянутся линии {#powerlines|электропередач}. Чуть в стороне от дороги я могу разглядеть небольшую {#glade|полянку}. Прохладный {wind|ветерок} ласкает чешую, а яркое летнее {sun|солнце} пробивается сквозь тонкие перистые {clouds|облака}. ]]; + }; + above_forest_decor_village = { + en = 'The village I seek should be somewhere nearby. '; + ru = 'Деревня, что я ищу, должна быть где-то здесь. '; + }; + above_forest_enter = { + en = 'With a quick flap of my wings I rise from the Earth and rush into the sky. '; + ru = 'Резко взмахнув крыльями, я отрываюсь от земли и устремляюсь ввысь. '; + }; + transition_land = { + en = 'Land'; + ru = 'Приземлиться'; + }; + transition_south_along_road = { + en = 'South, Along the Road'; + ru = 'На юг, вдоль дороги'; + }; + transition_north_along_road = { + en = 'North, Along the Road'; + ru = 'На север, вдоль дороги'; + }; + transition_north_to_the_village= { + en = 'North, to the Village'; + ru = 'На север, к деревне'; + }; + transition_fly = { + en = 'Take Off'; + ru = 'Взлететь'; + }; + transition_west = { + en = 'West'; + ru = 'На запад'; + }; + above_forest_thicket_act = { + en = 'Ancient forests cover the land like a green blanket. Mild wind barely sways the treetops. Even here, hundreds of meters above ground, I sense a slight scent of conifer. '; + ru = 'Древние леса зеленым ковром покрывают землю. Вершины деревьев едва покачиваются от легкого ветерка. Даже здесь, на высоте нескольких сотен метров, я ощущаю легкий запах хвои. '; + }; + above_forest_road_act = { + en = 'Cracked asphalt looks like a dry riverbed. Road is deserted, as if this place has been uninhabited long ago. '; + ru = 'Потрескавшийся асфальт напоминает русло засохшей реки. Дорога пустынна, словно это место давно покинуто людьми. '; + }; + above_forest_road_act_village = { + en = 'What if I find only lifeless windows of empty houses there?'; + ru = 'Что если меня ждут лишь безжизненные окна пустых домов?'; + }; + above_forest_powerlines_act = { + en = 'Towers are positioned along the road on equal distance from each other. Thick high-voltage cables are stretched between them. '; + ru = 'Вышки установлены вдоль дороги на равных расстояниях друг от друга, Между ними натянуты толстые высоковольтные провода. '; + }; + above_forest_glade_act = { + en = 'A small glade, covered with a patchwork of flowers and grass. '; + ru = 'Небольшая полянка, усеянная пестрым ковром из цветов и трав. '; + }; + above_forest_glade_act_first = { + en = 'A great place to take some rest. '; + ru = 'Отличное место чтобы передохнуть. '; + }; + forest_glade = { + en = 'Glade'; + ru = 'Поляна'; + }; + forest_glade_enter = { + en = 'I land on a small glade inside forest. There is no need to hide, so I stay in my real form. '; + ru = 'Я приземляюсь на небольшой полянке в лесу. Здесь нет нужды прятаться, поэтому я остаюсь в истинном обличии. '; + }; + forest_glade_solarscale = { + en = 'Solarscale touches ground near me. Thrilled and entusiastic she starts examining local flora. "What a beauty!" -- she exclaims. '; + ru = 'Соларскейл опускается на землю неподалеку от меня. С воодушевлением и трепетом она начинает разглядывать местные растения. "Какая красота!" -- восклицает она. '; + }; + forest_glade_decor = { + en = 'I stand in the middle of a small glade, surronded with a wall of {#thciket|trees}. It is calm and quiet here. I can only hear leaves rustling and {#birds|birds} singing. Mild wind barely sways the treetops. Emerald-green {#grass|grass} reaches my heels. '; + ru = 'Я стою посреди небольшой полянки, со всех сторон окруженной стеной {#thicket|леса}. Здесь тихо и спокойно. Я слышу только шелест листвы и пение {#birds|птиц}. Легкий ветерок еле заметно качает вершины {#thicket|деревьев}. Изумрудно-зеленая {#grass|трава} достигает моих пяток. '; + }; + forest_glade_thicket = { + en = 'Trees surround the glade with a solid wall, like vigilant sentinels, keeping watch over this place. '; + ru = 'Деревья окружают поляну сплошной стеной, словно бдительные стражи, охраняющие покой этого места. '; + }; + forest_glade_birds = { + en = 'From deep within forest I hear a multitude of chirping birds, but I don\'t see any of them nearby. '; + ru = 'Где-то в глубине леса я слышу щебетание множества птиц, однако я не вижу ни одной поблизости. '; + }; + forest_glade_grass = { + en = 'Thick high grass covers the whole glade. It would reach average human\'s waist, but for me it barely touches heels. Here and there I can see tiny patches of {#flowers|flowers} hidden in it. '; + ru = 'Высокая густая трава покрывает всю поляну. Человеку она была бы по пояс, но мне она едва достигает пяток. Тут и там я замечаю небольшие скопления {#flowers|цветов}, скрытые в ней. '; + }; + forest_glade_flowers_first = { + en = 'Unusual flowers with elongated sky-blue petals catch my attention. They grow on the edge of the glade. I pick one and take it with me. Some magic and it will never wither. '; + ru = 'Мое внимание привлекают необычные цветы с вытянутыми лепестками небесно-голубого цвета, растущие на краю поляны. Я срываю один и забираю с собой. Немного магии, и он уже никогда не завянет. '; + }; + forest_glade_flowers = { + en = 'Quite a lot of nice flowers grows here. '; + ru = 'Здесь растет немало красивых цветов. '; + }; + above_near_village = { + en = 'South of the Village'; + ru = 'К югу от деревни'; + }; + above_near_village_enter = { + en = 'A fog surrounds my body and in a moment, not a nameless stranger, but a mighty dragon is standing on the road. With a flap of wings, I leave the Earth far below. '; + ru = 'Мое тело окутывает туман и через мгновение на дороге уже стоит не безымянный странник, а могучий дракон. Взмахнув крыльями, я оставляю землю далеко внизу. '; + }; + above_near_village_decor = { + en = 'Wings carry me above the forest {#road|road}. I have travelled a dozen kilometers but seemingly nothing has changed at all: a neverending {#thicket|thicket} still lies below, and {mountains|the mountain range} still stretches far away. To the north, near the horizon I notice a small {#village|village}. '; + ru = 'Крылья несут меня над лесной {#road|дорогой}. Я пролетел с десяток километров, но, кажется, не изменилось вообще ничего: внизу все так же расстилается бескрайняя {#thicket|чаща}, а {mountains|горная цепь} на западе продолжает тянуться вдаль. На севере, у самого горизонта, я замечаю небольшую {#village|деревушку}. '; + }; + above_near_village_road = { + en = 'Road looks long unused. Asphalt has cracked in a lot of places, and green stalks have started to grow through it. '; + ru = 'Дорога выглядит давно не используемой. Асфальт во многих местах потрескался, и сквозь него кое-где пробиваются зеленые стебельки.'; + }; + above_near_village_thicket = { + en = 'Looks like the forest is endless. A mild wind sways the treetops, raising thick conifer scent, noticeable even here, hundreds of meters above ground. '; + ru = 'Кажется, лесу нет конца и края. Легкий ветерок колышет вершины деревьев, поднимая густой хвойный аромат, ощутимый даже здесь, на высоте нескольких сотен метров. '; + }; + above_near_village_village = { + en = 'From here I can see a tavern and a town hall in the center of the village. Around them little houses are scattered, surrounded by greenery. '; + ru = 'Отсюда я могу разглядеть трактир и ратушу в центре деревни. Вокруг них разбросаны утопающие в зелени домики. '; + }; + village_unvisited = { + en = 'The village is definitely inhabited. '; + ru = 'Деревня определенно не заброшена. '; + }; + above_village = { + en = 'Above the Village'; + ru = 'Над деревней'; + }; + above_village_decor = { + en = 'Thin fleecy {clouds|clouds} keep floating above me, barely covering {sun|the sun} and below stretches an endless sea of {#thicket|forest}, cut by {mountains|the mountain range} to the west. Old asphalted {#road|road} leads to {#village|the village} below me. '; + ru = 'Надо мной все так же проплывают тонкие перистые {clouds|облака}, едва прикрывая собой {sun|солнце}, а внизу простирается бескрайнее море {#thicket|леса}, взрезанное на западе {mountains|горной грядой}. Старая асфальтированная {#road|дорога} ведет в {#village|деревню}, расположенную подо мной. '; + }; + above_village_thicket = { + en = 'Thick conifer forest surrounds a small village from all sides, trying to devour it without success. '; + ru = 'Густой хвойный лес плотным кольцом обступает небольшую деревеньку со всех сторон, безуспешно пытаясь поглотить ее. '; + }; + above_village_road = { + en = 'Obviously locals rarely use this way. Road is empty and asphalt does not get due maintenance. '; + ru = 'Очевидно, местные жители нечасто пользуются этим путем. Дорога пустует, а асфальт не получает должного ремонта. '; + }; + above_village_village = { + en = 'From here I can see the village surrounded by greenery. In it\'s center lies a square, near it town hall and a tavern are situated. On the north of the village a library is located. '; + ru = 'Отсюда я могу хорошо разглядеть утопающую в зелени деревню. В центре ее расстилается площадь, рядом с которой находятся ратуша и трактир. На севере деревни располагается библиотека. '; + }; + }; } diff --git a/tutorial.lua b/tutorial.lua --- a/tutorial.lua +++ b/tutorial.lua @@ -21,8 +21,8 @@ obj { nam = 'tutorial_box'; disp = translate(tutorial_locale, 'tutorial_box'); inv = function(s) - return translate_now(tutorial_locale, 'tutorial_box_inv') .. '^' .. fmt.b(translate_now(tutorial_locale, 'tutorial_box_hint')); - end; + return translate_now(tutorial_locale, 'tutorial_box_inv') .. '^' .. fmt.b(translate_now(tutorial_locale, 'tutorial_box_hint')); + end; used = function(s, o) if o ^ 'tutorial_key' then take('tutorial_map'); @@ -59,11 +59,11 @@ room { if here():from()^'intro_start' or here():from()^'intro_settings' or here():from()^'intro_info' then stop_menu(); end; - snd.music('sound/bgm_forest.ogg'); + snd.music('sound/bgm_forest.ogg'); end; decor = function(s) - return translate_now(tutorial_locale, 'tutorial_start_decor') .. '^' .. fmt.b(translate_now(tutorial_locale, 'tutorial_start_decor_hint')); - end; + return translate_now(tutorial_locale, 'tutorial_start_decor') .. '^' .. fmt.b(translate_now(tutorial_locale, 'tutorial_start_decor_hint')); + end; way = { path {translate(common_locale, "back"), 'main'}; path {translate(common_locale, "continue"), 'tutorial_lair'}; @@ -176,8 +176,8 @@ room { obj { nam = '#scrolls'; act = function(s) - pr(translate_now(tutorial_locale, 'tutorial_treasury_scrolls')); - + pr(translate_now(tutorial_locale, 'tutorial_treasury_scrolls')); + if not have('tutorial_map') then return translate_now(tutorial_locale, 'tutorial_treasury_scrolls_no_map'); end; @@ -191,7 +191,7 @@ room { state = 0; nam = '#disks'; act = function(s) - pr(translate_now(tutorial_locale, 'tutorial_treasury_disks')); + pr(translate_now(tutorial_locale, 'tutorial_treasury_disks')); if s.state == 1 or not have('tutorial_map') then pr(translate_now(tutorial_locale, 'tutorial_treasury_disks_default')); else @@ -219,8 +219,8 @@ room { end; end; decor = function(s) - return translate_now(tutorial_locale, 'tutorial_study_decor') .. '^' .. fmt.b(translate_now(tutorial_locale, 'tutorial_study_decor_hint')); - end; + return translate_now(tutorial_locale, 'tutorial_study_decor') .. '^' .. fmt.b(translate_now(tutorial_locale, 'tutorial_study_decor_hint')); + end; }: with { obj { nam = '#laptop'; diff --git a/utils.lua b/utils.lua --- a/utils.lua +++ b/utils.lua @@ -1,15 +1,15 @@ declare { - keysfilter = false; + keysfilter = false; } function keys:filter(press, key) - local rval; - if here().keysfilter then - return here():keysfilter(press, key); - end; - if keysfilter then - return keysfilter(press, key); - end; + local rval; + if here().keysfilter then + return here():keysfilter(press, key); + end; + if keysfilter then + return keysfilter(press, key); + end; end --[[