-- $Name: Дракон и башня -- $Version: 1.0 -- $Author: Khaelenmore Thaal -- $Info: Небольшая игра, спонтанно пришедшая в голову game.act = 'Я не знаю, что с этим сделать. '; game.use = function(s) local l = { 'Это не имеет смысла. ', 'Я не понимаю, что с этим делать. ', 'Мне незачем это делать. ', 'Это пустая трата времени. ', 'Это ни к чему не приведет. ', 'Бессмысленно. ', }; return l[rnd(#l)]; end; game.inv = 'Это предмет. Он существует. '; instead.notitle = function() return here().notitle; end; require "fmt" require "noinv" require 'snd' require 'keys' require "timer" require "theme" require "decor" require "prefs" require 'utils' require "dire/theme" require "locale" 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; end; function get_font_scale() 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; end; instead.nosave = function() return here().nosave end instead.noautosave = function() return here().noautosave end fmt.para = true; 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 } include "tutorial" include "computer_parts" include "solarscale" include "tower" include "forest" include "ending" local menu = { 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 = 'Игра Дракон и Башня требует чтобы настройка "собственные темы игр" была включена. Она не будет работать без этой настройки. Пожалуйста, измените настройки и перезапустите или загрузите игру. '; }; } function get_sprite(path) if not menu_sprites[path] then menu_sprites[path] = sprite.new(path):scale(diretheme.get_scale(), diretheme.get_scale(), diretheme.get_smooth()); end; return menu_sprites[path]; end; function stop_menu() 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; end; game.afterwalk = function() dprint(from().nam, '->', here().nam); 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; end; function cat_list(list, sep) local rval; 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; 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; 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, frames=1, 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, frames=1, 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, frames=1, 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, frames=1, click=true }; end; if #buttons == 5 then D { buttons[4], 'img', get_sprite('images/title/' .. buttons[4] .. '.' .. get_language() .. '.png'), x=ox + (278 + button_dx / 2) * scale, y=oy + (515 + button_dy) * scale, frames=1, click=true }; D { buttons[5], 'img', get_sprite('images/title/' .. buttons[5] .. '.' .. get_language() .. '.png'), x=ox + (519 - button_dx / 2) * scale, y=oy + (515 + button_dy) * scale, frames=1, 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, diretheme.get_smooth()):tosprite(), x=ox - 9 * scale, y=oy - 6 * scale, w=w + 18 * scale, h=h + 12 * scale, background=true, frames=1, 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, frames=1, z=0}; end; if with_text then D {'textbg', 'img', get_sprite('images/title/text_background.png'), x=ox + 100 * scale, y=oy + (126 + button_dy) * scale, frames=1}; 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(25); 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; } 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 = [[Гулким эхом разносятся мои шаги под сводами древних пещер. Неровные тени пляшут в дрожащем магическом свете. В руке я держу фрагмент карты, бережно хранимый с незапамятных времен. Развернув старинный свиток, я внимательно осматриваю нанесенные на него обозначения: лес, горная цепь, дорога и отмеченная крестом деревушка. Настало время найти это место! ^Мое тело расплывается туманом и собирается в облике человека. Быстрым шагом я направляюсь к небольшой дверце в одной из стен. В комнате нет ничего, кроме каменного стола и стоящего на нем ноутбука -- совершенно необходимой в наше время вещи. Даже для дракона. Хорошая картографическая программа и правильно сформулированный запрос творят чудеса -- уже через несколько минут я вылетаю из пещеры в своем истинном обличии, расправив крылья навстречу ветру. ]]; } 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; dsc = [[ Автор игры: Khaelenmore Thaal^ Графика: Sabra Naikomy^ Музыка: Khaelenmore Thaal^ Благодарности:^ ]]; } obj { nam = 'empty'; dsc = '^'; } function format_settings(name, value) return fmt.tab('50%', 'center') .. fmt.nb(translate_now(menu, 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; }:with { obj { nam = '#system_settings'; dsc = function(s) return fmt.c(fmt.b('{[' .. translate_now(menu, 'system_settings') .. ']}^^')); end; act = function(s) instead.menu('settings'); end; }; obj { nam = '#language'; dsc = function(s) local l = translate_now(menu, 'auto_option'); pn(fmt.c(fmt.b(translate_now(menu, '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, 'graphic_scale')) .. ' {[' .. translate_now(menu, 'auto_option') .. ']}')) local t = ''; if graphic_scale > 1 then t = t .. '{#g_less|<<} '; else t = t .. '<< '; end; local l = translate_now(menu, 'auto_option') .. ' (' .. tostring(graphic_scale * 100) .. '%)'; if prefs.graphic_scale then l = tostring(graphic_scale * 100) .. '%'; end; 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, 'font_scale')) .. ' {[' .. translate_now(menu, '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, '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, 'inventory_scale')) .. ' {[' .. translate_now(menu, '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, '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, '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, 'text_alignment')))); local t = ''; if prefs.text_alignment == 1 then t = t .. translate_now(menu, 'text_alignment_justify') .. ' | '; else t = t .. '{#align_just|' .. translate_now(menu, 'text_alignment_justify') .. '} | '; end; if prefs.text_alignment == 2 then t = t .. translate_now(menu, 'text_alignment_left'); else t = t .. '{#align_left|' .. translate_now(menu, '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, 'padding')))); local t = ''; if prefs.text_padding == 1 then t = t .. translate_now(menu, 'normal') .. ' | '; else t = t .. '{#pad_norm|' .. translate_now(menu, 'normal') .. '} | '; end; if prefs.text_padding == 2 then t = t .. translate_now(menu, 'extended'); else t = t .. '{#pad_large|' .. translate_now(menu, '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, 'interval')))); local t = ''; if prefs.text_interval == 1 then t = t .. translate_now(menu, 'normal') .. ' | '; else t = t .. '{#int_norm|' .. translate_now(menu, 'normal') .. '} | '; end; if prefs.text_interval == 2 then t = t .. translate_now(menu, 'extended'); else t = t .. '{#int_large|' .. translate_now(menu, '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'; nam = 'resolution_warning'; title = translate(menu, 'warning'); decor = translate(menu, 'resolution_warning'); onenter = stop_menu; }: with { obj { nam = '#sysset'; dsc = function(s) return '{' .. translate_now(menu, 'system_settings') .. '}'; end; act = function(s) instead.menu(); end; } } room { nosave = true; noautosave = true; theme = 'black'; nam = 'theme_warning'; title = translate(menu, 'warning'); decor = translate(menu, 'theme_warning'); onenter = stop_menu; }: with { obj { nam = '#sysset'; dsc = function(s) return '{' .. translate_now(menu, 'system_settings') .. '}'; end; act = function(s) instead.menu(); end; } } function set_theme(t) -- 640x480 is the base size -- For lesser sizes -- enable downscaling -- Integer upscaling if effective resolution is no less than 640x480 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 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; print(t, scale, font_scale); 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, frames=1, 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, frames=1, click=true, z=-1 }; elseif t == 'terminal' then theme.set('snd.click', ''); diretheme.set_background('#181E37', 255, 'images/tower_theme/background.png', {mode=2}); 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 = 800, hmin = 568, wmax = 800, 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; 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; walk('terminal'); 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; end; function init() print('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; end;