Compare Revisions
Swap
Showing 9 commits
Merge Ancestor: f1f0cb90e9ae
9 arbtttrn6 29f7b758474b
24 days ago
8 silverwing c62400235fb9
1 month ago
7 silverwing 1618d535edeb
1 month ago
6 silverwing fe55249ac6dc
3 months ago
5 silverwing d48d28a36615
3 months ago
4 silverwing c8e64e6c731b
3 months ago
3 silverwing ce9c27846237
3 months ago
2 silverwing 5c191e4545a6
4 months ago
1 silverwing 86a247740e00
4 months ago
27 files changed:
TRANSLATION
Show inline comments
 
deleted file
TRANSLATORS
Show inline comments
 
new file 100644
 
En. Instructions for Translators
 

	
 
Copy the language file from which you are going to translate, name it with the target language code.
 
Add the language code and it's name into "locale.lua" to "lang_list" variable.
 

	
 
1. Curly braces ({}) are used to denote clickable text. There are two variants of usage {text} and {tag|text}, in the first case, just translate the text within the braces; in the second case, please keep the part before "|" character as is. I recommend putting articles inside the braces if they are not separated from the noun by other words. Important: If important links are removed or tags are misspelled, the game will break, so please check after translating.
 
2. Variables are marked by "%" character on both sides. Put them to the place accordingly to the language rules, but pay attention to the comments. Sometimes they pass text in specific case, so you may need to mind word ordering.
 
3. Names of objects and locations should be written as titles (follow your language rules, ex. Title Case in English) (these keys are usually named *_disp).
 
4. "^" character denotes line break. Usually should be kept at the same place in the translation. You may want to split lines in terminal_locale to be no longer than 63 characters.
 
5. Keys, ending in "disp2" are always in nominative case and are lower-case, "disp3" -- accusative case, lower-case. If an article is needed, keep it as part of the translation.
 

	
 
After the translation is complete, send it to us in any reasonable way (for example, use inbox@silverwing.one email). Take note that we may not be able to properly check the translation, but we will check that the game works with it before releasing it.
 

	
 
Ru. Инструкции для переводчиков
 

	
 
Скопируйте файл языка, с которого вы планируете переводить игру, назовите его кодом целевого языка.
 
Добавьте код и название языка в "locale.lua" в переменную "lang_list".
 

	
 
1. Фигурные скобки ({}) используются для обозначения активного текста. Есть два варианта их использования: {текст} и {tag|текст}, в первом случае просто переведите фрагмент текста внутри скобок; во-втором, часть до символа "|" следует оставить как есть. Артикли рекомендуется оставлять внутри скобок, если они не отделены об существительного другими словами. Важно! При отсутствии необходимых ссылок или неправильных тегах, игра может стать неработоспособной, поэтому проверяйте игру после перевода.
 
2. Знаками "%" выделены переменные. Вставляйте их на подходящее место с учетом правил языка, однако учтите дополнительные комментарии -- возможно вам придется построить предложение определенным образом.
 
3. Названия объектов и локаций следует записывать как заголовки (следуйте правилам языка, например Title Case на английском) (обычно эти ключи названы *_disp). 
 
4. Символ ^ используется для указания переноса строки. Как правило, вам следует оставлять его на том же месте в переводе. Вам потребуется разделять строки в terminal_locale чтобы они были не длиннее 63 символов.
 
5. Ключи, оканчивающиеся на "disp2" всегда именительный падеж, нижний регистр, "disp3" -- винительный падеж, нижний регистр. Если со словом должен использоваться артикль -- добавьте его в перевод.
 

	
 
После завершения перевода отправьте его нам любым удобным способом (например используйте почту inbox@silverwing.one). Обратите внимание, что мы можем не иметь возможности подтвердить качество перевода, но перед выпуском, мы убедимся что игра работает с ним. 
ending.lua
Show inline comments
 
global {
 
	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' or theme == 'bwm' 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' or theme == 'bwm'  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, position, hide_textbg)
 
  --[[
 
    position: nil or 0 -- center, 1 -- bottom-left
 
  ]]
 
  --frames, process, delay, frame_nr
 
  
 
	local scale = diretheme.get_scale();
 
	
 
  local unscaled_sw, unscaled_sh = diretheme.get_scaled_screen();
 
  
 
  local unscaled_w = 960;
 
  local unscaled_h = 600;
 
  
 
	local ox = math.floor((unscaled_sw - unscaled_w) / 2);
 
  local oy = math.floor((unscaled_sh - unscaled_h) / 2);
 

	
 
  if position == 1 then
 
    if ox < 0 then
 
      ox = 0;
 
    end;
 
    if oy < 0 then
 
      oy = unscaled_sh - unscaled_h;
 
    end;
 
  end;
 
  
 
  if hide_textbg then
 
    D {'textbg'};
 
  else
 
    local sw, sh = diretheme.get_screen();
 
    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 tbg, tbg_slice = make_tbg_slice(scale, theme);
 
    dire_draw_9(tbg, textbg, {x = 0; y = 0; w = tw; h = th}, {parts=tbg_slice});
 
    D {'textbg', 'img', textbg:sprite(), x=tx, y=ty, w=tw, h=th, z=0, background=true};
 
  end;
 
  
 
  local themebg = pixels.new(unscaled_sw, unscaled_sh);
 
  local bgtile = pixels.new('images/' .. theme .. '_theme/background.png');
 
  dire_draw_tile(bgtile, themebg, {x=0, y=0, w=unscaled_sw, h=unscaled_sh}, {xoffset=-1, yoffset=-1});
 
  
 
  if (ox > 0) or (oy > 0) then
 
    --Don't bother painting border if it's not visible (Effective screen < 960x600)
 
    local tbg, tbg_slice = make_tbg_slice(1, theme);
 
    local bgframe, fdx, fdy, frw, frh = make_ending_frame(1, theme, tbg, tbg_slice);
 
    dire_draw_center(bgframe, themebg, {x = ox - fdx, y = oy - fdy, w = frw, h = frh});
 
  end;
 
  
 
  dire_draw_center(pixels.new(image), themebg, {x = ox, y = oy, w = 960, h = 600});
 
  
 
  local bgcolor = '#89C6AE';
 
  if theme == 'bwm' then
 
    bgcolor = '#B2B2B2';
 
  elseif theme == 'bwt' then
 
    bgcolor = '#1F1F1F';
 
  elseif theme == 'tower' then
 
    bgcolor = '#181E37';
 
  end;
 
  
 
  diretheme.set_background(bgcolor, 255, themebg, {mode=1, scale = true});
 
end;
 

	
 
function ending_room(s)
 
  s.nofollow = true;
 
  s.noinv = true;
 
  s.nosave = true;
 
  s.noautosave = true;
 
  s.notitle = true;
 
  if not s.disp then
 
    s.disp = translate("ending_locale", 'game_end');
 
  end;
 
  
 
  return room(s);
 
end;
 

	
 
--[[
 
1. Leaving the tower
 
]]
 
room {
 
	state = 0;
 
  {
 
    state = 0;
 
  };
 
	nam = 'ending_left';
 
	nofollow = true;
 
	theme = 'ending_outside';
 
	disp = translate("ending_locale", 'game_end');
 
	noinv = true;
 
	notitle = true;
 
  nosave = true;
 
  noautosave = true;
 
	themeInit = function(s)
 
    local scale = diretheme.get_scale();
 
    local width, height = diretheme.get_scaled_screen();
 
    local dx = math.floor((width - 960) / 2);
 
    local dy = math.floor((height - 600) / 2);
 
    
 
		show_ending('main', 'images/endings/tower_left_bg.png');
 
		timer:set(25);
 
    
 
    animation_set({
 
      {type="delay", delay=2000};
 
      {
 
          type="image", 
 
          image=get_sprite('images/endings/tower_left_bg.png'),
 
          x = dx * scale,
 
          y = dy * scale,
 
          w = 960 * scale,
 
          h = 600 * scale,
 
          background = true
 
        };
 
      {
 
          type="anim",
 
          image=get_sprite('images/endings/tower_left_frames.png'),
 
          x = dx * scale,
 
          y = dy * scale,
 
          w = 960 * scale, 
 
          h = 600 * scale, 
 
          frames=6,
 
          delay=500,
 
          frame_data = {
 
            {};
 
            {x=0, y=318, w=51, h=16,  dx=444, dy=246};
 
            {x=0, y=276, w=51, h=42,  dx=444, dy=246};
 
            {x=0, y=202, w=51, h=74,  dx=444, dy=246};
 
            {x=0, y=108, w=51, h=94,  dx=444, dy=246};
 
            {x=0, y=0,   w=51, h=108, dx=444, dy=246};
 
          };
 
        };
 
    }, true);
 
	end;
 
	onenter = function(s)
 
		s.state = s.state + 1;
 
		if s.state == 1 then
 
			p(translate_now("ending_locale", 'left_state_1'));
 
			return false;
 
		elseif s.state == 2 then
 
			p(translate_now("ending_locale", 'left_state_2'));
 
			return false;
 
		elseif s.state == 3 then
 
			p(translate_now("ending_locale", 'left_state_3'));
 
			return false;
 
		end;
 
    
 
    if irradiated then
 
      snd.music('sound/bgm_ending_forest_irradiated.ogg');
 
    else
 
      snd.music('sound/bgm_ending_forest.ogg');
 
    end;
 
    
 
    enableSmoke('images/endings/tower_left_bg.png');
 
	end;
 
  onexit = function(s)
 
    fading.enabled = false;
 
  end;
 
	dsc = function(s)
 
		p(translate_now("ending_locale", 'left_part_1'));
 
		if solarscale_with_me then
 
			p(translate_now("ending_locale", 'left_part_1_solarscale'));
 
		end;
 
	end;
 
  way = {
 
		path {translate("common_locale", 'continue'), 'ending_left_2'};
 
	};
 
}
 

	
 
room {
 
  nam = 'ending_left_2';
 
  nofollow = true;
 
  nosave = true;
 
  noautosave = true;
 
  theme = function(s)
 
    if irradiated then
 
      return 'ending_outside_bw';
 
    else
 
      return 'ending_outside';
 
    end;
 
  end;
 
	disp = translate("ending_locale", 'game_end');
 
	noinv = true;
 
	notitle = true;
 
  themeInit = function(s)
 
    if irradiated then
 
      show_ending('bwm', 'images/endings/tower_left_closed_bw.png');
 
    else
 
      show_ending('main', 'images/endings/tower_left_closed.png');
 
    end;
 
    
 
    animation_set(false);
 
	end;
 
	dsc = function(s)
 
		pn(translate_now("ending_locale", 'left_part_2'));
 
		if solarscale_with_me then
 
			pn(translate_now("ending_locale", 'solarscale_lost'));
 
		end;
 
    if irradiated then
 
      p(translate_now("ending_locale", 'irradiated'));
 
    end;
 
	end;
 
  way = {
 
    path {translate("common_locale", 'continue'), function(s)
 
        if irradiated then
 
          _'ending_credits'.etype = 'leftbw';
 
        else
 
          _'ending_credits'.etype = 'left';
 
        end;
 
        return 'ending_credits';
 
    end};
 
  };
 
}
 

	
 
--[[
 
2. Destroying the tower
 
]]
 

	
 
room {
 
	nam = 'ending_formatted';
 
	disp = translate("ending_locale", 'game_end');
 
	theme = 'ending_outside';
 
	nofollow = true;
 
	noinv = true;
 
	notitle = true;
 
	theme = 'ending_outside';
 
  nosave = true;
 
  noautosave = true;
 
	themeInit = function(s)
 
		show_ending('main', 'images/endings/tower_ruin.png');
 
    timer:set(25);
 
	end;
 
  onenter = function(s)
 
    if irradiated then
 
      snd.music('sound/bgm_ending_forest_irradiated.ogg');
 
    else
 
      snd.music('sound/bgm_ending_forest.ogg');
 
    end;
 
  end;
 
  onexit = function(s)
 
    fading.enabled = false;
 
  end;
 
	dsc = function(s)
 
		if solarscale_with_me then
 
			p(translate_now("ending_locale", 'formatted_solarscale'));
 
		else
 
			p(translate_now("ending_locale", 'formatted_alone'));
 
		end;
 
	end;
 
  way = {
 
		path {translate("common_locale", 'continue'), 'ending_formatted_2'};
 
	};
 
}
 

	
 
room {
 
  nam = 'ending_formatted_2';
 
  nofollow = true;
 
  theme = function(s)
 
    if irradiated then
 
      return 'ending_outside_bw';
 
    else
 
      return 'ending_outside';
 
    end;
 
  end;
 
  nosave = true;
 
  noautosave = true;
 
	disp = translate("ending_locale", 'game_end');
 
	noinv = true;
 
	notitle = true;
 
  themeInit = function(s)
 
    if irradiated then
 
      return show_ending('bwm', 'images/endings/tower_ruin_bw.png');
 
    else
 
      return show_ending('main', 'images/endings/tower_ruin.png');
 
    end;
 
	end;
 
	dsc = function(s)
 
		pn(translate_now("ending_locale", 'formatted_2'));
 
		if solarscale_with_me then
 
			pn(translate_now("ending_locale", 'solarscale_lost'));
 
		end;
 
    if irradiated then
 
      p(translate_now("ending_locale", 'irradiated'));
 
    end;
 
	end;
 
  way = {
 
    path {translate("common_locale", 'continue'), function(s)
 
        if irradiated then
 
          _'ending_credits'.etype = 'formatbw';
 
        else
 
          _'ending_credits'.etype = 'format';
 
        end;
 
        return 'ending_credits';
 
    end};
 
  };
 
}
 

	
 
--[[
 
3. True ending stage 1
 
]]
 

	
 
-- 3a. With solarscale
 

	
 
ending_room {
 
  nam = 'ending_dissolving_tower_solarscale';
 
  theme = 'ending_outside';
 
  dsc = translate("ending_locale", 'ending_dissolving_tower_solarscale');
 
  onenter = function(s)
 
    enableSmoke('images/endings/crater_edge/tower_solarscale.png', 1);
 
  end;
 
  themeInit = function(s)
 
    local scale = diretheme.get_scale();
 
    local width, height = diretheme.get_scaled_screen();
 
    local dx = math.floor((width - 960) / 2);
 
    local dy = math.floor((height - 600) / 2);
 
    
 
    if dx < 0 then
 
      dx = 0;
 
    end;
 
    
 
    if dy < 0 then
 
      dy = height - 600;
 
    end;
 
    
 
		show_ending('main', 'images/endings/crater_edge/tower_solarscale.png', 1);
 
    animation_set({
 
        {type="delay", delay=2000};
 
        {
 
          type="anim", 
 
          image=get_sprite('images/endings/crater_edge/tower_animation.png'),
 
          x = (dx + 445) * scale,
 
          y = (dy + 311) * scale,
 
          w = 40 * scale,
 
          h = 94 * scale,
 
          frames = 14,
 
          delay = 150,
 
        };
 
    }, true);
 
    timer:set(25);
 
	end;
 
  onexit = function(s)
 
    fading.enabled = false;
 
  end;
 
  way = {
 
		path {translate("common_locale", 'continue'), 'ending_solarscale_flies_away'};
 
	};
 
}
 

	
 
room {
 
	nam = 'ending_solarscale_pre';
 
	theme = 'tower';
 
	disp = translate("tower_locale", 'tower_level_4_room_2_disp');
 
  nofollow = true;
 
	noinv = true;
 
  nosave = true;
 
  noautosave = true;
 
  pic = 'images/tower_level_4_room_2_light.png';
 
  dsc = translate("ending_locale", 'ending_solarscale_pre');
 
	way = {
 
		path {translate("common_locale", 'continue'), 'ending_solarscale_dlg'};
 
	};
 
}
 

	
 
local solarscale_convince = function(s)
 
  _'ending_solarscale_dlg'.weight = _'ending_solarscale_dlg'.weight + 1;
 
  if _'ending_solarscale_dlg'.weight >= 5 then
 
    walk('ending_solarscale_stays');
 
  elseif _'ending_solarscale_dlg'.weight >= 3 then
 
    return translate_now("ending_locale", "true_solarscale_convince_level_3");
 
  elseif _'ending_solarscale_dlg'.weight >= 2 then
 
    return translate_now("ending_locale", "true_solarscale_convince_level_2");
 
  elseif _'ending_solarscale_dlg'.weight == 1 then
 
    return translate_now("ending_locale", "true_solarscale_convince_level_1");
 
  end;
 
end;
 

	
 
dlg {
 
  weight = 0;
 
	nam = 'ending_solarscale_dlg';
 
	nofollow = true;
 
	theme = 'tower';
 
	noinv = true;
 
	disp = translate("solarscale_locale", 'disp');
 
  nosave = true;
 
  noautosave = true;
 
  pic = 'images/tower_level_4_room_2_light.png;images/characters/solarscale_tower_dusk.png';
 
	enter = translate("ending_locale", 'true_solarscale_dlg_enter');
 
	phr = {
 
		{translate("ending_locale", "true_solarscale_dlg_1"), function(s)
 
			walk('ending_solarscale_leaving_hold');
 
		end};
 
		{translate("ending_locale", "true_solarscale_dlg_2"), translate("ending_locale", "true_solarscale_dlg_2_response"), next='#convince'};
 
		{translate("ending_locale", "true_solarscale_dlg_end"), function(s)
 
			walk('ending_solarscale_leaving_farewell');
 
		end};
 
    {false, '#convince', 
 
      {translate("ending_locale", "true_solarscale_dlg_1"), function(s)
 
        walk('ending_solarscale_leaving_hold');
 
      end};
 
      {cond=function(s) return _'ending_solarscale_dlg'.weight > 0 end; translate("ending_locale", "true_solarscale_dlg_end"), function(s)
 
        walk('ending_solarscale_leaving_farewell')
 
      end};
 
      {translate("ending_locale", "true_solarscale_dlg_3"), solarscale_convince},
 
      {cond=function(s) return _'solarscale_ally'.after_discussed end; translate("ending_locale", "true_solarscale_dlg_4"), solarscale_convince},
 
      {cond=function(s) return had_tea and tea_answer_1 == 1 and tea_answer_2 == 1 and tea_answer_3 == 1 end; translate("ending_locale", "true_solarscale_dlg_5"), solarscale_convince},
 
      {cond=function(s) return solarscale_tower end; translate("ending_locale", "true_solarscale_dlg_6"), solarscale_convince},
 
      {cond=function(s) return solarscale_helps < 2 end; translate("ending_locale", "true_solarscale_dlg_7"), solarscale_convince};
 
      {cond=function(s) return solarscale_glade_visited end; translate("ending_locale", "true_solarscale_dlg_8"), solarscale_convince};
 
    };
 
	};
 
}
 

	
 
room {
 
  nam = 'ending_solarscale_stays';
 
  nofollow = true;
 
	theme = 'tower';
 
  nosave = true;
 
  noautosave = true;
 
  noinv = true;
 
  disp = translate("solarscale_locale", 'disp');
 
  pic = 'images/tower_level_4_room_2_light.png;images/characters/solarscale_tower_dusk.png';
 
  decor = translate("ending_locale", "true_solarscale_convince_level_4");
 
  way = {
 
		path {translate("common_locale", 'continue'), 'ending_solarscale_stays_part_2'};
 
	};
 
};
 

	
 
room {
 
	nam = 'ending_solarscale_stays_part_2';
 
	notitle = true;
 
	nofollow = true;
 
	theme = 'ending_outside';
 
	noinv = true;
 
	disp = translate("ending_locale", 'game_end');
 
  nosave = true;
 
  noautosave = true;
 
	dsc = translate("ending_locale", 'true_solarscale_stays');
 
  onenter = function(s)
 
    solarscale_stays = true;
 
    enableSmoke('images/endings/crater_edge/crater_edge.png', 1);
 
  end;
 
  themeInit = function(s)
 
    local scale = diretheme.get_scale();
 
    local width, height = diretheme.get_scaled_screen();
 
    local dx = math.floor((width - 960) / 2);
 
    local dy = math.floor((height - 600) / 2);
 
    
 
    if dx < 0 then
 
      dx = 0;
 
    end;
 
    
 
    if dy < 0 then
 
      dy = height - 600;
 
    end;
 
    
 
		show_ending('main', 'images/endings/crater_edge/crater_edge.png', 1);
 
    animation_set({
 
        {type="delay", delay=2000};
 
        {
 
          type="anim", 
 
          image=get_sprite('images/endings/crater_edge/tower_animation.png'),
 
          x = (dx + 445) * scale,
 
          y = (dy + 311) * scale,
 
          w = 40 * scale,
 
          h = 94 * scale,
 
          frames = 14,
 
          delay = 150,
 
        };
 
    }, true);
 
  
 
    timer:set(25);
 
	end;
 
  onexit = function(s)
 
    fading.enabled = false;
 
  end;
 
	way = {
 
		path {translate("common_locale", 'continue'), 'ending_welcome'};
 
	};
 
};
 

	
 
room {
 
  nam = 'ending_solarscale_leaving_farewell';
 
  nofollow = true;
 
	theme = 'tower';
 
  nosave = true;
 
  noautosave = true;
 
  noinv = true;
 
  disp = translate("tower_locale", 'tower_level_4_room_2_disp');
 
  pic = 'images/tower_level_4_room_2_light.png';
 
  decor =  translate("ending_locale", "true_solarscale_dlg_end_response");
 
  way = {
 
		path {translate("common_locale", 'continue'), 'ending_solarscale_leaving_part_2'};
 
	};
 
};
 

	
 
room {
 
  nam = 'ending_solarscale_leaving_hold';
 
  nofollow = true;
 
	theme = 'tower';
 
  nosave = true;
 
  noautosave = true;
 
  noinv = true;
 
  pic = 'images/tower_level_4_room_2_light.png';
 
  disp = translate("tower_locale", 'tower_level_4_room_2_disp');
 
  decor =  translate("ending_locale", "true_solarscale_dlg_1_response");
 
  way = {
 
		path {translate("common_locale", 'continue'), 'ending_solarscale_leaving_part_2'};
 
	};
 
};
 

	
 
room {
 
	nam = 'ending_solarscale_leaving_part_2';
 
	notitle = true;
 
	nofollow = true;
 
	noinv = true;
 
	disp = translate("ending_locale", 'game_end');
 
  theme = 'ending_outside';
 
  nosave = true;
 
  noautosave = true;
 
  onenter = function(s)
 
    enableSmoke('images/endings/tower_left_bg.png');
 
  end;
 
  themeInit = function(s)
 
    local scale = diretheme.get_scale();
 
    local width, height = diretheme.get_scaled_screen();
 
    local dx = math.floor((width - 960) / 2);
 
    local dy = math.floor((height - 600) / 2);
 
    
 
		show_ending('main', 'images/endings/tower_left_bg.png');
 
    animation_set({
 
        {type="delay", delay=2000};
 
        {
 
          type="image", 
 
          image=get_sprite('images/endings/tower_left_bg.png'),
 
          x = dx * scale,
 
          y = dy * scale,
 
          w = 960 * scale,
 
          h = 600 * scale,
 
          background = true
 
        };
 
        {
 
          type="anim",
 
          image=get_sprite('images/endings/solarscale_left_frames.png'),
 
          x = dx * scale,
 
          y = dy * scale,
 
          w = 960 * scale,
 
          h = 600 * scale,
 
          frames = 15,
 
          delay = 100,
 
          background = true,
 
          frame_data = {
 
            {},
 
            {x=214, y=326, w=8,   h=8,   dx=467, dy=294},
 
            {x=214, y=309, w=28,  h=17,  dx=458, dy=288},
 
            {x=49,  y=518, w=44,  h=18,  dx=449, dy=295},
 
            {x=0,   y=518, w=49,  h=24,  dx=445, dy=293},
 
            {x=214, y=272, w=43,  h=37,  dx=447, dy=293},
 
            {x=153, y=505, w=73,  h=47,  dx=431, dy=296},
 
            {x=0,   y=342, w=153, h=59,  dx=388, dy=288},
 
            {x=0,   y=272, w=214, h=70,  dx=364, dy=272},
 
            {x=0,   y=401, w=142, h=117, dx=396, dy=229},
 
            {x=153, y=342, w=102, h=163, dx=422, dy=144},
 
            {x=0,   y=0,   w=257, h=163, dx=347, dy=50},
 
            {x=0,   y=163, w=257, h=109, dx=347, dy=0},
 
            {x=93,  y=518, w=22,  h=31,  dx=462, dy=0},
 
            {}
 
          };
 
        };
 
        {
 
          type="anim",
 
          image=get_sprite('images/endings/tower_left_frames.png'),
 
          x = dx * scale,
 
          y = dy * scale,
 
          w = 960 * scale, 
 
          h = 600 * scale, 
 
          frames=6,
 
          delay=500,
 
          frame_data = {
 
            {};
 
            {x=0, y=318, w=51, h=16,  dx=444, dy=246};
 
            {x=0, y=276, w=51, h=42,  dx=444, dy=246};
 
            {x=0, y=202, w=51, h=74,  dx=444, dy=246};
 
            {x=0, y=108, w=51, h=94,  dx=444, dy=246};
 
            {x=0, y=0,   w=51, h=108, dx=444, dy=246};
 
          };
 
        };
 
    }, true);
 
  
 
    timer:set(25);
 
  end;
 
  onexit = function(s)
 
    fading.enabled = false;
 
  end;
 
  pic = 'images/tower_level_4_room_2_light.png';
 
  decor = translate("ending_locale", 'true_solarscale_leaving');
 
	way = {
 
		path {translate("common_locale", 'continue'), 'ending_dissolving_tower_solarscale_alt'};
 
	};
 
}
 

	
 
room {
 
  nam = 'ending_dissolving_tower_solarscale_alt';
 
  notitle = true;
 
	nofollow = true;
 
	theme = 'ending_outside';
 
  noinv = true;
 
  notitle = true;
 
  nosave = true;
 
  noautosave = true;
 
  disp = translate("ending_locale", 'game_end');
 
  themeInit = function(s)
 
    local scale = diretheme.get_scale();
 
    local width, height = diretheme.get_scaled_screen();
 
    local dx = math.floor((width - 960) / 2);
 
    local dy = math.floor((height - 600) / 2);
 
    
 
    if dx < 0 then
 
      dx = 0;
 
    end;
 
    
 
    if dy < 0 then
 
      dy = height - 600;
 
    end;
 
    
 
		show_ending('main', 'images/endings/crater_edge/tower_solarscale.png', 1);
 
    animation_set({
 
        {type="delay", delay=2000};
 
        {
 
          type="anim", 
 
          image=get_sprite('images/endings/crater_edge/tower_animation.png'),
 
          x = (dx + 445) * scale,
 
          y = (dy + 311) * scale,
 
          w = 40 * scale,
 
          h = 94 * scale,
 
          frames = 14,
 
          delay = 150,
 
        };
 
    }, true);
 
    timer:set(25);
 
	end;
 
  dsc = translate("ending_locale", 'ending_dissolving_tower_solarscale_alt');
 
  way = {
 
		path {translate("common_locale", 'continue'), 'ending_solarscale_flies_away'};
 
	};
 
};
 

	
 
room {
 
  nam = 'ending_solarscale_flies_away';
 
  notitle = true;
 
	nofollow = true;
 
	theme = 'ending_outside';
 
  noinv = true;
 
  notitle = true;
 
  nosave = true;
 
  noautosave = true;
 
  disp = translate("ending_locale", 'game_end');
 
  themeInit = function(s)
 
    local scale = diretheme.get_scale();
 
    local width, height = diretheme.get_scaled_screen();
 
    local dx = math.floor((width - 960) / 2);
 
    local dy = math.floor((height - 600) / 2);
 
    
 
    if dx < 0 then
 
      dx = 0;
 
    end;
 
    
 
    if dy < 0 then
 
      dy = height - 600;
 
    end;
 
    
 
		show_ending('main', 'images/endings/crater_edge/solarscale.png', 1);
 
    animation_set({
 
        {type="delay", delay=2000};
 
        {
 
          type="image", 
 
          image=get_sprite('images/endings/crater_edge/crater_edge_no_tower.png'),
 
          x = dx * scale,
 
          y = dy * scale,
 
          w = 960 * scale,
 
          h = 600 * scale,
 
          background = true
 
        };
 
        {
 
          type="anim",
 
          image=get_sprite("images/endings/crater_edge/solarscale_frames.png");
 
          x = dx * scale,
 
          y = dy * scale,
 
          w = 960 * scale,
 
          h = 600 * scale,
 
          frames = 28,
 
          delay = 125,
 
          background = true,
 
          frame_data = {
 
            --fx, fy, w, h, dx, dy
 
            {x=653, y=0,    w=154, h=384, dx=0,   dy=216};
 
            {x=494, y=658,  w=226, h=400, dx=0,   dy=200};
 
            {x=0,   y=658,  w=494, h=406, dx=0,   dy=194};
 
            {x=0,   y=0,    w=653, h=280, dx=0,   dy=290};
 
            {x=0,   y=280,  w=647, h=378, dx=0,   dy=222};
 
            {x=0,   y=1064, w=481, h=280, dx=89,  dy=320};
 
            {x=481, y=1064, w=299, h=239, dx=226, dy=361};
 
            {x=365, y=1344, w=326, h=214, dx=241, dy=386};
 
            {x=0,   y=1344, w=365, h=228, dx=270, dy=372};
 
            {x=365, y=1558, w=209, h=119, dx=354, dy=397};
 
            {x=0,   y=1572, w=155, h=103, dx=407, dy=395};
 
            {x=653, y=472,  w=119, h=54,  dx=427, dy=389};
 
            {x=653, y=384,  w=136, h=88,  dx=457, dy=339};
 
            {x=653, y=526,  w=71,  h=41,  dx=520, dy=253};
 
            {x=789, y=397,  w=15,  h=27,  dx=583, dy=210};
 
            {x=724, y=526,  w=25,  h=18,  dx=609, dy=168};
 
            {x=789, y=424,  w=12,  h=7,   dx=627, dy=133};
 
            {x=647, y=280,  w=5,   h=2,   dx=664, dy=81};
 
            {x=772, y=472,  w=32,  h=35,  dx=666, dy=47};
 
            {x=647, y=282,  w=3,   h=3,   dx=665, dy=80};
 
            {x=690, y=567,  w=20,  h=37,  dx=659, dy=73};
 
            {x=653, y=567,  w=37,  h=27,  dx=650, dy=68};
 
            {x=653, y=594,  w=27,  h=25,  dx=654, dy=69};
 
            {x=789, y=384,  w=17,  h=13,  dx=658, dy=75};
 
            {x=789, y=431,  w=11,  h=11,  dx=661, dy=76};
 
            {x=800, y=431,  w=7,   h=7,   dx=663, dy=78};
 
            {x=650, y=282,  w=1,   h=1,   dx=666, dy=81};
 
            {};
 
          };
 
        };
 
    }, true);
 
	end;
 
  dsc = translate("ending_locale", 'true_solarscale_outside_part_2');
 
  way = {
 
		path {translate("common_locale", 'continue'), 'ending_welcome'};
 
	};
 
}
 

	
 
ending_room {
 
  nam = 'ending_welcome';
 
  theme = 'ending_inside';
 
  themeInit = function(s)
 
    local scale = diretheme.get_scale();
 
    local uwidth, uheight = diretheme.get_screen();
 
    local width, height = diretheme.get_scaled_screen();
 
    local pic_dx = math.floor((width - 960) / 2);
 
    local pic_dy = math.floor((height - 600) / 2);
 
    local dx = 0;
 
    local dy = 0;
 
    if width > 960 then
 
      dx = math.floor((width - 960) / 2);
 
      width = 960;
 
      pic_dx = 0;
 
    end;
 
    if height > 600 then
 
      dy = math.floor((height - 600) / 2);
 
      height = 600;
 
      pic_dy = 0;
 
    end;
 
    
 
    local src, dst, newsrc;
 
    if solarscale_stays then
 
      src = sprite.new('images/endings/pre_space_1_solarscale.png');
 
      dst = sprite.new('images/endings/pre_space_2_solarscale.png');
 
    else
 
      src = sprite.new('images/endings/pre_space_1.png');
 
      dst = sprite.new('images/endings/pre_space_2.png');
 
    end;
 
    newsrc = sprite.new(width, height);
 
    src:copy(-pic_dx, -pic_dy, width, height, newsrc, 0, 0);
 
    
 
    local alpha = 1;
 
    local part = 0;
 
    local partcount = 10;
 
    local partheight = math.floor(600 / partcount);
 
    local parts = {};
 
    
 
    for i = 1, partcount do
 
      parts[i] = sprite.new(width, partheight);
 
      dst:copy(-pic_dx, (i - 1) * partheight, width, partheight, parts[i], 0, 0);
 
    end;    
 
    
 
    local process = function(s)
 
      src:copy(-pic_dx, part * partheight, width, partheight, newsrc, 0, pic_dy + part * partheight);
 
      
 
      if alpha < 255 then
 
        dst:draw(-pic_dx, part * partheight, width, partheight, newsrc, 0, pic_dy + part * partheight, alpha);
 
      else
 
        dst:copy(-pic_dx, part * partheight, width, partheight, newsrc, 0, pic_dy + part * partheight);
 
      end;
 
      
 
      part = part + 1
 
      if part >= partcount then
 
        part = 0
 
        alpha = alpha + 2
 
        if alpha > 255 then
 
          s.process = nil
 
          -- TODO End
 
        end;
 
        
 
        if scale ~= 1 then
 
          s.sprite = newsrc:scale(scale, scale, false);
 
        else
 
          newsrc:copy(s.sprite, 0, 0);
 
        end;
 
        
 
        return false;
 
      end;
 
      
 
      return true;
 
    end;
 

	
 
    if solarscale_stays then
 
      show_ending('tower', 'images/endings/pre_space_1_solarscale.png');
 
    else
 
      show_ending('tower', 'images/endings/pre_space_1.png');
 
    end;
 
    local spr
 
    if scale ~= 1 then
 
      spr = newsrc:scale(scale, scale, false);
 
    else
 
      spr = newsrc:dup();
 
    end;
 
      
 
    animation_set({
 
      {type="image", image=spr, x=dx * scale, y=dy * scale, w=width * scale, h=height * scale, process=process, delay=25, background=true};
 
    });
 
    spr = nil;  -- remove reference
 
    timer:set(25);
 
	end;
 
  dsc = translate("ending_locale", 'ending_welcome');
 
  way = {
 
		path {translate("common_locale", 'continue'), function(s)
 
        if solarscale_stays then
 
          return 'ending_solarscale_flight';
 
        else
 
          return 'ending_space_1';
 
        end;
 
    end};
 
	};
 
};
 

	
 
ending_room {
 
  nam = 'ending_solarscale_flight';
 
  theme = 'ending_inside';
 
  themeInit = function(s)
 
    local scale = diretheme.get_scale();
 
    local width, height = diretheme.get_scaled_screen();
 
    local dx = math.floor((width - 960) / 2);
 
    local dy = math.floor((height - 600) / 2);
 
    
 
    show_ending('tower', 'images/endings/solarscale/solarscale_first.png');
 
    animation_set({
 
        {type="delay", delay=2000};
 
        {
 
          type="image",
 
          image="images/endings/solarscale/solarscale_bg.png",
 
          x = dx * scale,
 
          y = dy * scale,
 
          w = 960 * scale,
 
          h = 600 * scale,
 
          background = true
 
        },
 
        {
 
          type="anim", 
 
          image=get_sprite("images/endings/solarscale/solarscale_frames.png"),
 
          x = dx * scale,
 
          y = dy * scale,
 
          w = 960 * scale,
 
          h = 600 * scale,
 
          frames = 70,
 
          delay={
 
            150, 150, 150, 150, 150,
 
            150, 150, 150, 150, 150,
 
            150, 150, 150, 150, 150,
 
            150, 150, 150, 150, 150,
 
            150, 150, 150, 150, 150, 
 
            150, 150, 150, 200, 100, 
 
            100, 200, 200, 250, 250, 
 
            150, 150, 150, 200, 150,
 
            150, 200, 200, 200, 200, 
 
            200, 200, 150, 150, 100, 
 
            100, 100, 100, 100, 100, 
 
            100, 100, 100, 100, 100, 
 
            100, 100, 100, 100, 100, 
 
            150, 150, 150, 150, 150,
 
          },
 
          frame_data = {
 
            {x=1106, y=1385, w=592, h=454, dx=368, dy=146},
 
            {x=0   , y=2294, w=592, h=453, dx=368, dy=147},
 
            {x=3037, y=924 , w=558, h=459, dx=402, dy=141},
 
            {x=592 , y=1840, w=479, h=449, dx=481, dy=151},
 
            {x=4181, y=0   , w=485, h=459, dx=475, dy=141},
 
            {x=4107, y=3124, w=571, h=342, dx=373, dy=258},
 
            {x=0   , y=3199, w=840, h=311, dx=120, dy=289},
 
            {x=2226, y=3194, w=667, h=329, dx=253, dy=271},
 
            {x=2795, y=2747, w=588, h=408, dx=372, dy=192},
 
            {x=3383, y=3124, w=724, h=348, dx=192, dy=243},
 
            {x=840 , y=3199, w=606, h=288, dx=215, dy=287},
 
            {x=548 , y=719 , w=186, h=188, dx=439, dy=88},
 
            {x=1692, y=3335, w=220, h=81 , dx=573, dy=34},
 
            {x=355 , y=1656, w=104, h=161, dx=788, dy=121},
 
            {x=355 , y=1424, w=152, h=232, dx=616, dy=199},
 
            {x=1446, y=3335, w=246, h=134, dx=349, dy=330},
 
            {x=548 , y=504 , w=296, h=215, dx=43 , dy=248},
 
            {x=1500, y=2881, w=183, h=94 , dx=122, dy=68},
 
            {x=1500, y=2747, w=164, h=134, dx=343, dy=69},
 
            {x=1446, y=3199, w=259, h=136, dx=392, dy=178},
 
            {x=0   , y=1424, w=355, h=338, dx=366, dy=53},
 
            {x=0   , y=0   , w=845, h=504, dx=115, dy=96},
 
            {x=3383, y=2747, w=615, h=377, dx=345, dy=223},
 
            {x=3998, y=2747, w=599, h=375, dx=361, dy=225},
 
            {x=2226, y=2747, w=569, h=447, dx=391, dy=153},
 
            {x=519 , y=1385, w=587, h=455, dx=373, dy=145},
 
            {x=1698, y=1385, w=592, h=454, dx=368, dy=146},
 
            {x=1106, y=1839, w=592, h=454, dx=368, dy=146},
 
            {x=1698, y=1839, w=592, h=454, dx=368, dy=146},
 
            {x=2630, y=1383, w=467, h=457, dx=414, dy=143},
 
            {x=0   , y=2747, w=469, h=452, dx=433, dy=148},
 
            {x=548 , y=926 , w=521, h=459, dx=355, dy=141},
 
            {x=4156, y=1839, w=521, h=453, dx=355, dy=147},
 
            {x=3313, y=2294, w=533, h=453, dx=367, dy=147},
 
            {x=3846, y=2294, w=533, h=453, dx=367, dy=147},
 
            {x=4138, y=1383, w=531, h=453, dx=370, dy=147},
 
            {x=2779, y=2294, w=534, h=453, dx=370, dy=147},
 
            {x=1705, y=2293, w=537, h=453, dx=370, dy=147},
 
            {x=2242, y=2294, w=537, h=453, dx=370, dy=147},
 
            {x=1705, y=2746, w=521, h=453, dx=355, dy=147},
 
            {x=2111, y=926 , w=519, h=459, dx=357, dy=141},
 
            {x=0   , y=965 , w=519, h=459, dx=357, dy=141},
 
            {x=4150, y=924 , w=516, h=459, dx=360, dy=141},
 
            {x=1184, y=2293, w=521, h=454, dx=354, dy=146},
 
            {x=4133, y=463 , w=519, h=459, dx=357, dy=141},
 
            {x=1069, y=926 , w=521, h=459, dx=356, dy=141},
 
            {x=1590, y=926 , w=521, h=459, dx=356, dy=141},
 
            {x=469 , y=2747, w=469, h=452, dx=433, dy=148},
 
            {x=3097, y=1383, w=467, h=457, dx=414, dy=143},
 
            {x=845 , y=0   , w=560, h=463, dx=352, dy=137},
 
            {x=1405, y=0   , w=560, h=463, dx=352, dy=137},
 
            {x=1965, y=0   , w=560, h=463, dx=352, dy=137},
 
            {x=2525, y=0   , w=560, h=463, dx=352, dy=137},
 
            {x=3085, y=0   , w=548, h=463, dx=366, dy=137},
 
            {x=3633, y=0   , w=548, h=463, dx=366, dy=137},
 
            {x=845 , y=463 , w=548, h=463, dx=366, dy=137},
 
            {x=1393, y=463 , w=548, h=463, dx=366, dy=137},
 
            {x=3037, y=463 , w=548, h=461, dx=366, dy=139},
 
            {x=3585, y=463 , w=548, h=461, dx=366, dy=139},
 
            {x=0   , y=504 , w=548, h=461, dx=366, dy=139},
 
            {x=1941, y=463 , w=548, h=463, dx=366, dy=137},
 
            {x=2489, y=463 , w=548, h=463, dx=366, dy=137},
 
            {x=3595, y=924 , w=555, h=459, dx=370, dy=141},
 
            {x=3564, y=1383, w=574, h=456, dx=365, dy=144},
 
            {x=938 , y=2747, w=562, h=451, dx=377, dy=149},
 
            {x=3564, y=1839, w=592, h=454, dx=368, dy=146},
 
            {x=2290, y=1840, w=592, h=454, dx=368, dy=146},
 
            {x=2882, y=1840, w=592, h=454, dx=368, dy=146},
 
            {x=0   , y=1840, w=592, h=454, dx=368, dy=146},
 
            {x=592 , y=2293, w=592, h=454, dx=368, dy=146}
 
          }
 
        };
 
    });
 
    timer:set(25);
 
  end;
 
  dsc = translate("ending_locale", 'ending_solarscale_flight');
 
  way = {
 
		path {translate("common_locale", 'continue'), 'ending_space_1'};
 
	};
 
}
 

	
 
ending_room {
 
  nam = 'ending_space_1';
 
  theme = 'ending_inside';
 
  themeInit = function(s)
 
    if solarscale_stays then
 
      show_ending('tower', 'images/endings/solarscale/solarscale_first.png');
 
    else
 
      show_ending('tower', 'images/endings/space.png');
 
    end;
 
    animation_set(false);
 
	end;
 
  dsc = function(s)
 
		if solarscale_stays then
 
			pr(translate_now("ending_locale", 'true_step_1_solarscale'));
 
    else
 
      pr(translate_now("ending_locale", 'true_step_1_alone'));
 
		end;
 
    pn();
 
    pr(translate_now("ending_locale", 'true_step_1'));
 
	end;
 
  way = {
 
		path {translate("common_locale", 'continue'), function(s)
 
      if irradiated then
 
        return 'ending_space_2_irradiated';
 
      else
 
        return 'ending_space_2';
 
      end;
 
    end};
 
  }
 
};
 

	
 
room {
 
	nam = 'ending_space_2';
 
	disp = translate("ending_locale", 'game_end');
 
	noinv = true;
 
	notitle = true;
 
	nofollow = true;
 
  nosave = true;
 
  noautosave = true;
 
	theme = 'ending_inside';
 
  themeInit = function(s)
 
		if solarscale_stays then
 
      show_ending('tower', 'images/endings/solarscale/solarscale_first.png');
 
    else
 
      show_ending('tower', 'images/endings/space.png');
 
    end;
 
    timer:set(25);
 
	end;
 
	dsc = function(s)
 
    if solarscale_stays then
 
      return translate_now("ending_locale", 'true_step_2_solarscale');
 
    else
 
      return translate_now("ending_locale", 'true_step_2_alone');
 
    end;
 
  end;
 
  way = {
 
    path {translate("common_locale", 'continue'), function(s)
 
        if solarscale_stays then
 
          _'ending_credits'.etype = 'main_solarscale';
 
        else
 
          _'ending_credits'.etype = 'main';
 
        end;
 
        return 'ending_credits';
 
    end};
 
  };
 
};
 

	
 
room {
 
	nam = 'ending_space_2_irradiated';
 
	disp = translate("ending_locale", 'game_end');
 
	noinv = true;
 
	notitle = true;
 
	nofollow = true;
 
  nosave = true;
 
  noautosave = true;
 
	theme = 'ending_inside_bw';
 
  themeInit = function(s)
 
		show_ending('bwt', 'images/endings/space_bw.png');
 
	end;
 
	dsc = translate("ending_locale", 'true_step_2_irradiated');
 
  way = {
 
    path {translate("common_locale", 'continue'), function(s)
 
        _'ending_credits'.etype = 'bwm';
 
        return 'ending_credits';
 
    end};
 
  };
 
};
 

	
 
room {
 
	nam = 'ending_credits';
 
	disp = translate("ending_locale", 'thank_you_for_playing');
 
	noinv = true;
 
	nofollow = true;
 
  nosave = true;
 
  noautosave = true;
 
  etype = false; -- main, mbw, left, leftbw, format, formatbw
 
	theme = function(s)
 
    if s.etype == 'main' or s.etype == 'main_solarscale' then
 
      return 'credits_inside';
 
    elseif s.etype == 'bwm' then
 
      return 'credits_inside_bw';
 
    elseif s.etype == 'left' or s.etype == 'format' then
 
      return 'credits_outside';
 
    elseif s.etype == 'leftbw' or s.etype == 'formatbw' then
 
      return 'credits_outside_bw';  
 
    else
 
      error('Unexpected ending');
 
    end;
 
  end;
 
  themeInit = function(s)
 
    if s.etype == 'main' then
 
      show_ending('tower', 'images/endings/space_credits.png', 0, true);
 
    elseif s.etype == 'main_solarscale' then
 
      show_ending('bwt', 'images/endings/solarscale_credits.png', 0, true);
 
    elseif s.etype == 'bwm' then
 
      show_ending('bwt', 'images/endings/space_bw.png', 0, true);
 
    elseif s.etype == 'left' then
 
      show_ending('main', 'images/endings/tower_left_credits.png', 0, true);
 
    elseif s.etype == 'format' then
 
      show_ending('main', 'images/endings/tower_ruin_credits.png', 0, true);
 
    elseif s.etype == 'leftbw' then
 
      show_ending('bwm', 'images/endings/tower_left_bw_credits.png', 0, true);
 
    elseif s.etype == 'formatbw' then
 
      show_ending('bwm', 'images/endings/tower_ruin_bw_credits.png', 0, true);
 
    else
 
      error('Unexpected ending');
 
    end;
 
		timer:set(25);
 
    
 
    if s.etype == 'main' and not irradiated then
 
      prefs.completed = true;
 
    end;
 
    fmt.para = false;
 
	end;  
 
  themeDispose = function(s)
 
    fmt.para = true;
 
  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://github.com/instead-hub/instead/}^' ..
 
			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_closed_beta') .. ': ' .. closed_beta_participants.. '^^'..
 
			translate_now("menu_locale", 'credits_thanks');
 
	end;
 
  way = {
 
    path {translate("ending_locale", 'show_menu'), 'reset'};
 
  };
 
}
 

	
 
room {
 
  nam = 'reset';
 
  onenter = function(s)
 
    std.gamefile('main3.lua', true);
 
    return false;
 
  end;
 
};
 
\ No newline at end of file
forest.lua
Show inline comments
 
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;
 

	
 
	solarscale_helps = 2;
 
	solarscale_glade_visited = false;
 
	pc_status = false;
 
	village_visited = false;
 
	candle_taken = false;
 
  tower_seen = false;
 
  tower_accept_level = 0; --0 -- no contanct, 1 -- level 3 reached, 2 -- level 4 completed, 3 -- complete acceptance
 
  tea_answer_1 = 0; --0 -- not spoken or not correct, 1 -- correct, 2 -- don't know
 
  tea_answer_2 = 0; --0 -- not spoken or not correct, 1 -- correct, 2 -- don't know
 
  tea_answer_3 = 0; --0 -- not spoken or not correct, 1 -- correct, 2 -- don't know
 
  solarscale_tower = false;
 
  had_tea = false;
 
  
 
  library_word = '';
 
  library_book_map = {};
 
  
 
  password1 = '';
 
  password2 = '';
 
  
 
  level_1_target = '434';
 
  
 
  opening_catalyst = 'green_catalyst';
 
  light_catalyst = 'blue_catalyst';
 
  enrichment_catalyst = 'red_catalyst';
 
}
 

	
 
obj {
 
	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');
 
}
 

	
 
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');
 
}
 

	
 
obj {
 
  nam = 'old_map';
 
  disp = translate("forest_locale", 'old_map_disp');
 
  disp2 = translate("forest_locale", 'old_map_disp2');
 
  disp3 = translate("forest_locale", 'old_map_disp3');
 
  inv = function(s)
 
    p(translate_now("forest_locale", 'old_map_inv'));
 
    if village_visited then
 
      p(translate_now("forest_locale", 'old_map_inv_visited'));
 
      if _('fly_west_from_village'):disabled() then
 
        p(translate_now("forest_locale", 'old_map_inv_visited_village'));
 
      end;
 
    else
 
      p(translate_now("forest_locale", 'old_map_inv_not_visited'));
 
    end;
 
  end;
 
}
 

	
 
room {
 
	nam = 'above_forest';
 
	pic = 'images/above_forest.png';
 
	disp = translate("forest_locale", 'above_forest');
 
	theme = 'main';
 
	decor = function(s)
 
		p(translate_now("forest_locale", 'above_forest_decor'));
 
		if not village_visited then
 
			p(translate_now("forest_locale", 'above_forest_decor_village'));
 
		end;
 
	end;
 
	enter = function(s)
 
    if not have('old_map') then
 
      take('old_map');
 
    end;
 
		if here():from()^'intro_start' or here():from()^'intro_settings' or here():from()^'intro_info' then
 
			stop_menu();
 
		end;
 
		if here():from()^'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'));
 
			p(translate_now("forest_locale", 'above_forest_road_act'));
 

	
 
			if not village_visited then
 
				pr(translate_now("forest_locale", 'above_forest_road_act_village'));
 
				p(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'));
 
			p(translate_now("forest_locale", 'above_forest_glade_act'));
 
			if _'#down':disabled() then
 
				_'#down':enable();
 
				pr(translate_now("forest_locale", 'above_forest_glade_act_first'));
 
				p(translate_now("forest_locale", 'above_forest_glade_act_first'));
 
			end;
 
		end;
 
	};
 
	'mountains';
 
	'wind';
 
	'sun';
 
	'clouds';
 
}
 

	
 
room {
 
	nam = 'forest_glade';
 
	pic = function(s)
 
		if lookup('#flowers', 'forest_glade').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 = translate("forest_locale", 'forest_glade_enter');
 
	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();
 
}
 

	
 
room {
 
	nam = 'above_near_village';
 
	disp = translate("forest_locale", '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'));
 
			p(translate_now("forest_locale", 'above_near_village_village'));
 
			if not village_visited then
 
				village_visited = true;
 
				pr(translate_now("forest_locale", 'village_unvisited'));
 
				p(translate_now("forest_locale", 'village_unvisited'));
 
			end;
 
		end;
 
	};
 
	'mountains';
 
	'wind';
 
	'sun';
 
	'clouds';
 
};
 

	
 
room {
 
	nam = 'above_village';
 
	pic = 'images/above_village.png';
 
	disp = translate("forest_locale", 'above_village');
 
	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'));
 
			p(translate_now("forest_locale", 'above_village_village'));
 
			if not village_visited then
 
				village_visited = true;
 
				pr(translate_now("forest_locale", 'village_unvisited'));
 
				p(translate_now("forest_locale", 'village_unvisited'));
 
			end;
 
		end;
 
	};
 
	'mountains';
 
	'wind';
 
	'sun';
 
	'clouds';
 
};
 

	
 
obj {
 
	nam = 'sun';
 
	act = translate("forest_locale", 'sun');
 
};
 

	
 
obj {
 
	nam = 'sun_transformed';
 
	act = translate("forest_locale", 'sun_transformed');
 
};
 

	
 
obj {
 
	nam = 'clouds';
 
	act = translate("forest_locale", 'clouds');
 
};
 

	
 
obj {
 
	nam = 'wind';
 
	act = translate("forest_locale", 'wind');
 
};
 

	
 
obj {
 
	nam = 'mountains';
 
	act = translate("forest_locale", 'mountains');
 
};
 

	
 
room {
 
	nam = 'above_west';
 
	disp = translate("forest_locale", 'above_west');
 
	pic = 'images/above_west.png';
 
	theme = 'main';
 
	decor = translate("forest_locale", 'above_west_decor');
 
	way = {
 
		path {"#east", translate("forest_locale", 'transition_east_to_the_village'), 'above_village'};
 
		path {"#west", translate("forest_locale", 'transition_west_to_the_crater'), 'above_crater'}:disable();
 
	}
 
}: with {
 
	obj {
 
		nam = '#village';
 
		act = translate("forest_locale", 'above_west_village');
 
	};
 
	obj {
 
		nam = '#mountains';
 
		act = translate("forest_locale", 'above_west_mountains');
 
	};
 
	obj {
 
		nam = '#mountaintops';
 
		act = translate("forest_locale", 'above_west_mountaintops');
 
	};
 
	obj {
 
		nam = '#mountainslopes';
 
		act = translate("forest_locale", 'above_west_mountainslopes');
 
	};
 
	obj {
 
		nam = '#crater';
 
		act = function(s)
 
			_'#west':enable();
 
			return translate_now("forest_locale", 'above_west_crater');
 
		end;
 
	};
 
	'clouds';
 
	'sun';
 
}
 

	
 
room {
 
	nam = 'above_crater';
 
	pic = 'images/above_crater.png';
 
	theme = 'main';
 
	onenter = function(s)
 
		if here()^'inside_crater_glade' then
 
			p(translate_now("forest_locale", 'above_crater_enter'));
 
		end;
 
	end;
 
	disp = translate("forest_locale", 'above_crater');
 
	decor = translate("forest_locale", 'above_crater_decor');
 
	way = {
 
		path {"#east", translate("forest_locale", 'transition_east'), 'above_west'};
 
		path {"#down", translate("forest_locale", 'transition_land'), 'inside_crater_glade'}:disable();
 
	}
 
}: with {
 
	obj {
 
		nam = '#crater';
 
		act = translate("forest_locale", 'above_crater_crater');
 
	};
 
	obj {
 
		nam = '#tower';
 
		act = translate("forest_locale", 'above_crater_tower');
 
	};
 
	obj {
 
		nam = '#trees';
 
		act = translate("forest_locale", 'above_crater_trees');
 
	};
 
	obj {
 
		nam = '#glade';
 
		act = function(s)
 
			_'#down':enable();
 
			return translate_now("forest_locale", 'above_crater_glade');
 
		end;
 
	};
 
	'wind';
 
	'sun';
 
	'clouds';
 
}
 

	
 
room {
 
	nam = 'village_no_way';
 
	onenter = function(s)
 
		if solarscale_with_me then
 
			p(translate_now("forest_locale", 'village_no_way_solarscale'));
 
		else
 
			p(translate_now("forest_locale", 'village_no_way_alone'));
 
		end;
 
		return false;
 
	end;
 
}
 

	
 
room {
 
	nam = 'near_village';
 
	disp = translate("forest_locale", 'near_village');
 
	pic = 'images/near_village.png';
 
	theme = 'main';
 
	onenter = function(s)
 
		if here()^'above_near_village' then
 
			p(translate_now("forest_locale", 'near_village_enter'));
 
		end;
 
	end;
 
	decor = translate("forest_locale", 'near_village_decor');
 
	way = {
 
		path {"#up", translate("forest_locale", 'transition_fly'), 'above_near_village'};
 
		path {"#north", translate("forest_locale", 'transition_north_to_the_village'), 'village_south'};
 
	}
 
}: with {
 
	obj {
 
		nam = '#road';
 
		act = translate("forest_locale", 'near_village_road');
 
	};
 
	obj {
 
		nam = '#forest';
 
		act = translate("forest_locale", 'near_village_forest');
 
	};
 
	obj {
 
		nam = '#village';
 
		act = function(s)
 
			p(translate_now("forest_locale", 'near_village_village'));
 
			if not village_visited then
 
				village_visited = true;
 
				p(translate_now("forest_locale", 'village_unvisited'));
 
			end;
 
		end;
 
	};
 
	'sun_transformed';
 
	'clouds';
 
}
 

	
 
room {
 
	nam = 'village_south';
 
	disp = translate("forest_locale", 'village_south');
 
	pic='images/village_south.png';
 
	theme = 'main';
 
	enter = function(s)
 
		if not village_visited then
 
			village_visited = true;
 
			p(translate_now("forest_locale", 'village_unvisited'));
 
		end;
 
	end;
 
	nofollow = function(s)
 
		if here():from()^'near_village' then
 
			return translate_now("solarscale_locale", 'follow_refuse') .. ' ' ..translate_now("solarscale_locale", 'follow_refuse_village');
 
		else
 
			return true;
 
		end;
 
	end;
 
	decor = translate("forest_locale", 'village_south_decor');
 
	way = {
 
		path {'#south', translate("forest_locale", 'transition_south_to_the_forest'), 'near_village'};
 
		path {'#in', translate("forest_locale", 'transition_inside_hut'), 'foresters_hut'};
 
		path {'#north', translate("forest_locale", 'transition_north_to_the_townhall'), 'village_center'};
 
	};
 
}:with {
 
	obj {
 
		nam = '#road';
 
		act = translate("forest_locale", 'village_south_road');
 
	};
 
	obj {
 
		nam = '#village';
 
		act = translate("forest_locale", 'village_south_village');
 
	};
 
	obj {
 
		nam = '#foresters_car';
 
		act = translate("forest_locale", 'village_south_car');
 
	};
 
	obj {
 
		nam = '#foresters_hut_out';
 
		act = translate("forest_locale", 'village_south_hut');
 
	};
 
	'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 = translate("forest_locale", 'foresters_hut');
 
	enter = function(s)
 
		if s.state == 0 then
 
			s.state = 1;
 
			return translate_now("forest_locale", 'foresters_hut_enter');
 
		end;
 
	end;
 
	decor = translate("forest_locale", 'foresters_hut_decor');
 
	way = {
 
		path {'#out', translate("forest_locale", 'transition_out'), 'village_south'};
 
	}
 
}:with {
 
	obj {
 
		nam = '#sofa';
 
		act = translate("forest_locale", 'foresters_hut_sofa');
 
	};
 
	obj {
 
		nam = '#cupboard';
 
		act = translate("forest_locale", 'foresters_hut_cupboard');
 
	};
 
	obj {
 
		nam = '#table';
 
		act = translate("forest_locale", 'foresters_hut_table');
 
	};
 
	obj {
 
		nam = '#chairs';
 
		act = translate("forest_locale", 'foresters_hut_chairs');
 
	};
 
	obj {
 
		nam = '#radio';
 
		act = translate("forest_locale", 'foresters_hut_radio');
 
	};
 
	obj {
 
		bought = false;
 
		nam = 'forester';
 
		dsc = translate("forest_locale", 'foresters_hut_forester');
 
		act = function(s)
 
			walkin('forester_dlg');
 
		end;
 
		used = function(s, o)
 
			if o^'raspberry_pie' then
 
				return translate_now("forest_locale", 'foresters_hut_forester_pie');
 
			else
 
				return translate_now("forest_locale", 'foresters_hut_not_interested');
 
			end;
 
		end;
 
	};
 
	obj {
 
		nam = 'rope';
 
		disp = translate("forest_locale", 'foresters_hut_rope_disp');
 
		dsc = translate("forest_locale", 'foresters_hut_rope');
 
		act = function(s)
 
			if _('forester').bought then
 
				p(translate_now("forest_locale", 'foresters_hut_rope_taken'));
 
				take('rope')
 
			else
 
				p(translate_now("forest_locale", 'foresters_hut_rope_not_taken'));
 
			end;
 
		end;
 
		inv = translate("forest_locale", 'foresters_hut_rope_inv');
 
	};
 
}
 

	
 
dlg {
 
	nam = 'forester_dlg';
 
	disp = translate("forest_locale", 'forester_dlg_disp');
 
	theme = 'main';
 
	pic = 'images/characters/forester.png';
 
	enter = translate("forest_locale", 'forester_dlg_enter');
 
	phr = {
 
		{translate("forest_locale", 'common_dlg_greet'), translate("forest_locale", 'forester_dlg_greet_response'),
 
			{translate("forest_locale", 'common_dlg_places'), translate("forest_locale", 'forester_dlg_places_response')};
 
		},
 
		{cond=function(s) return where('rope') and where('rope')^'foresters_hut' and not _('forester').bought end, translate("forest_locale", 'forester_dlg_rope'), function(s)
 
			p(translate_now("forest_locale", 'forester_dlg_rope_response'));
 
			raspberry_pie_status = 1;
 
		end},
 
		{cond=function(s) return have 'raspberry_pie' end, translate("forest_locale", 'forester_dlg_pie'), function(s)
 
			remove('raspberry_pie', pl);
 
			p(translate_now("forest_locale", 'forester_dlg_pie_response'));
 
			raspberry_pie_status = 2;
 
			_('forester').bought = 1;
 
		end},
 
		{true, translate("forest_locale", 'common_dlg_bye'), function(s)
 
			p(translate_now("forest_locale", 'forester_dlg_farewell_response'));
 
			walkout();
 
		end}
 
	}
 
}
 

	
 
room {
 
	nam = 'village_center';
 
	nofollow = true;
 
	pic = 'images/village_center.png';
 
	theme = 'main';
 
	disp = translate("forest_locale", 'village_center');
 
	decor = function(s)
 
    p(translate_now("forest_locale", 'village_center_decor'));
 
    p(translate_now("forest_locale", 'village_all_decor'));
 
  end;
 
	way = {
 
		 path {translate("forest_locale", 'transition_south_to_hut'), 'village_south'};
 
		 path {'#down', translate("forest_locale", 'transition_inside_well'), 'inside_well'}:disable();
 
		 path {translate("forest_locale", 'transition_inside_town_hall'), 'townhall'};
 
		 path {translate("forest_locale", 'transition_inside_tavern'), 'tavern'};
 
		 path {translate("forest_locale", 'transition_north_to_library'), 'village_north'};
 
	};
 
}: with {
 
	obj {
 
		nam = '#townhall';
 
		act = translate("forest_locale", 'village_center_townhall');
 
	};
 
	obj {
 
		nam = '#music';
 
		act = translate("forest_locale", 'village_center_music');
 
	};
 
	obj {
 
		nam = '#tavern';
 
		act = translate("forest_locale", 'village_center_tavern');
 
	};
 
	obj {
 
		nam = '#library';
 
		act = translate("forest_locale", 'village_center_library');
 

	
 
	};
 
	obj {
 
		known = false;
 
		nam = 'village_well';
 
		dsc = function(s)
 
      p(translate_now("forest_locale", 'village_well_dsc'));
 
			if _('inside_well').state then
 
				p(translate_now("forest_locale", 'village_well_dsc_rope'));
 
			end;
 
		end;
 
		act = function(s)
 
			if s.known then
 
				_'#down':enable();
 
				p(translate_now("forest_locale", 'village_well_act_key'));
 
			else
 
				p(translate_now("forest_locale", 'village_well_act'));
 
			end;
 
		end;
 
		used = function(s, o)
 
			if o^'rope' then
 
        _'#down':enable();
 
				_('inside_well').state = true;
 
				remove('rope', pl);
 
				p(translate_now("forest_locale", 'village_well_used'));
 
			else
 
				return false;
 
			end;
 
		end;
 
	};
 
	obj {
 
		nam = 'maid';
 
		dsc = function(s)
 
      p(translate_now("forest_locale", 'village_maid_dsc'));
 
			if _('maid_dlg').flower then
 
				p(translate_now("forest_locale", 'village_maid_flower'));
 
			end;
 
		end;
 
		act = function(s)
 
			if _('maid_dlg').flower and (raspberry_pie_status == 0 or raspberry_pie_status == 2) then
 
				return translate_now("forest_locale", 'maid_dlg_enter') .. ' ' .. translate_now("forest_locale", 'village_maid_act_no_dlg');
 
			else
 
				walkin('maid_dlg');
 
			end;
 
		end;
 
		used = function(s, o)
 
			if o^'flower' then
 
				return translate_now("forest_locale", 'village_maid_used_flower');
 
			else
 
				return translate_now("forest_locale", 'village_maid_used_other');
 
			end;
 
		end;
 
	};
 
	'sun_transformed';
 
	'clouds';
 
}
 

	
 
dlg {
 
	nam = 'maid_dlg';
 
	disp = translate("forest_locale", 'maid_dlg');
 
	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)
 
    p(translate_now("forest_locale", 'maid_dlg_enter'));
 
		if _('maid_dlg').flower then
 
			p(translate_now("forest_locale", 'maid_dlg_enter_with_flower'));
 
      p(translate_now("forest_locale", 'village_maid_flower'));
 
		else
 
			p(translate_now("forest_locale", 'maid_dlg_enter_no_flower'));
 
		end;
 
	end;
 
	phr = {
 
		{cond=function(s) return not _('maid_dlg').flower end, translate("forest_locale", 'common_dlg_greet'), translate("forest_locale", 'maid_dlg_greet_response'),
 
			{translate("forest_locale", 'common_dlg_places'), translate("forest_locale", 'maid_dlg_places_response'),
 
				{translate("forest_locale", 'maid_dlg_places_like'), translate("forest_locale", 'maid_dlg_places_like_response'), only=true,
 
					{
 
						cond=function(s) return have 'flower' end,
 
						translate("forest_locale", 'maid_dlg_flower'),
 
						function(s)
 
							_('maid_dlg').flower = 1;
 
							remove('flower', pl);
 
							p(translate_now("forest_locale", 'maid_dlg_flower_response'));
 
						end
 
					};
 
					{
 
						translate("common_locale", 'dlg_keep_silent'),
 
						translate("forest_locale", 'maid_dlg_silent_response')
 
					}
 
				};
 
			};
 
		};
 
		{cond=function(s) return not _('maid_dlg').work_asked end, translate("forest_locale", 'maid_dlg_tavern'), function(s)
 
			_('maid_dlg').work_asked = true;
 
			return translate_now("forest_locale", 'maid_dlg_tavern_response');
 
		end};
 
		{
 
			cond=function(s) return _('maid_dlg').pie_asked and have 'flower' end,
 
			translate("forest_locale", 'maid_dlg_flower'),
 
			function(s)
 
				_('maid_dlg').flower = 1;
 
				remove('flower', pl);
 
				raspberry_pie_status = 2;
 
				take 'raspberry_pie'
 
				p(translate_now("forest_locale", 'maid_dlg_pie_response'));
 
			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;
 
			translate("forest_locale", 'maid_dlg_pie'),
 
			function(s)
 
				raspberry_pie_status = 2;
 
				take 'raspberry_pie'
 
				p(translate_now("forest_locale", 'maid_dlg_pie_response'));
 
			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;
 
			translate("forest_locale", 'maid_dlg_pie'),
 
			translate("forest_locale", 'maid_dlg_pie_fail_response'), only=true,
 
			{
 
				translate("forest_locale", 'maid_dlg_no_money'), function(s)
 
					_('maid_dlg').pie_asked = 1;
 
					p(translate_now("forest_locale", 'maid_dlg_no_money_response'));
 
				end, only=true,
 
				{
 
					cond=function(s) return have 'flower' end,
 
					translate("forest_locale", 'maid_dlg_flower'),
 
					function(s)
 
						_('maid_dlg').flower = 1;
 
						remove('flower', pl);
 
						raspberry_pie_status = 2;
 
						take('raspberry_pie');
 
						p(translate_now("forest_locale", 'maid_dlg_pie_response'));
 
					end
 
				};
 
        {translate("forest_locale", 'maid_dlg_flower_agree'), translate("forest_locale", 'maid_dlg_flower_agree_response')};
 
				{translate("forest_locale", 'maid_dlg_flower_think'), translate("forest_locale", 'maid_dlg_flower_think_response')};
 
			},
 
			{
 
				translate("forest_locale", 'maid_dlg_pie_ask'), translate("forest_locale", 'maid_dlg_pie_ask_response')
 
			}
 
		};
 
		{
 
			translate("forest_locale", 'maid_dlg_bye'), function(s)
 
			p(translate_now("forest_locale", 'maid_dlg_bye_response'));
 
			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 = translate("forest_locale", 'tavern');
 
	theme = 'main';
 
	nofollow = true;
 
	decor = translate("forest_locale", 'tavern_decor');
 
	way = {
 
		path {'#outside', translate("forest_locale", 'transition_out'), 'village_center'};
 
	};
 
}: with {
 
	obj {
 
		nam = '#windows';
 
		act = translate("forest_locale", 'tavern_windows');
 
	};
 
	obj {
 
		nam = '#tables';
 
		act = translate("forest_locale", 'tavern_tables');
 
	};
 
	obj {
 
		nam = '#walls';
 
		act = translate("forest_locale", 'tavern_walls');
 
	};
 
	obj {
 
		nam = '#lights';
 
		act = translate("forest_locale", 'tavern_lights');
 
	};
 
	obj {
 
		nam = '#fireplace';
 
		act = translate("forest_locale", 'tavern_fireplace');
 
	};
 
	obj {
 
		nam = '#cauldron';
 
		act = translate("forest_locale", 'tavern_cauldron');
 
	};
 
	obj {
 
		nam = 'tavernkeeper';
 
		dsc = translate("forest_locale", 'tavern_keeper');
 
		act = function(s)
 
			walkin 'tavernkeeper_dlg'
 
		end;
 
	}
 
}
 

	
 
dlg {
 
	nam = 'tavernkeeper_dlg';
 
	noinv = true;
 
	title = translate("forest_locale", 'tavernkeeper_dlg');
 
	pic = 'images/characters/tavernkeeper.png';
 
	theme = 'main';
 
	enter = translate("forest_locale", 'tavernkeeper_dlg_enter');
 
	phr = {
 
		{translate("forest_locale", 'common_dlg_greet'), translate("forest_locale", 'tavernkeeper_dlg_greet_response'),
 
			{translate("forest_locale", 'tavernkeeper_dlg_money'), translate("forest_locale", 'tavernkeeper_dlg_money_response')};
 
			{translate("forest_locale", 'common_dlg_places'), translate("forest_locale", 'tavernkeeper_dlg_places_response')};
 
		};
 
		{cond=function(s) return raspberry_pie_status == 1; end, translate("forest_locale", 'tavernkeeper_dlg_pie'), translate("forest_locale", 'tavernkeeper_dlg_pie_response'),
 
			{translate("forest_locale", 'tavernkeeper_dlg_pie_2'), translate("forest_locale", 'tavernkeeper_dlg_pie_response_2')}
 
		};
 
		{true, translate("forest_locale", 'common_dlg_bye'), function(s)
 
			p(translate_now("forest_locale", 'tavernkeeper_dlg_bye_response'));
 
			walkout();
 
		end};
 
	};
 
}
 

	
 
room {
 
	nam = 'townhall';
 
	pic='images/townhall.png';
 
	theme = 'main';
 
	title = translate("forest_locale", 'townhall');
 
	nofollow = true;
 
	decor = translate("forest_locale", 'townhall_decor');
 
	onexit = function(s)
 
		if have 'oil' then
 
			p(translate_now("forest_locale", 'townhall_onexit'));
 
			return false;
 
		end;
 
	end;
 
	way = {
 
		path {'#out', translate("forest_locale", 'transition_out'), 'village_center'};
 
	};
 
}: with {
 
	obj {
 
		nam = '#ceiling';
 
		act = translate("forest_locale", 'townhall_ceiling');
 
	};
 
	obj {
 
		nam = '#chandelier';
 
		act = translate("forest_locale", 'townhall_chandelier');
 
	};
 
	obj {
 
		nam = '#curtains';
 
		act = translate("forest_locale", 'townhall_curtains');
 
	};
 
	obj {
 
		nam = '#table';
 
		act = translate("forest_locale", 'townhall_table');
 
	};
 
	obj {
 
		nam = '#chairs';
 
		act = translate("forest_locale", 'townhall_chairs');
 
	};
 
	obj {
 
		nam = '#head';
 
		act = translate("forest_locale", 'townhall_head');
 
	};
 
	obj {
 
		flask = true;
 
		nam = 'cabinet';
 
		dsc = translate("forest_locale", 'townhall_cabinet');
 
		act = function(s)
 
			if s.flask then
 
				return translate_now("forest_locale", 'townhall_cabinet_act_oil');
 
			else
 
				return translate_now("forest_locale", 'townhall_cabinet_act');
 
			end;
 
		end;
 
		used = function(s, o)
 
			if o == _('oil') then
 
				s.flask = true;
 
				remove(o, pl);
 
				put(o, 'townhall');
 
				return translate_now("forest_locale", 'townhall_cabinet_used_oil');
 
			end;
 
		end;
 
	}:with {
 
		obj {
 
			nam = 'records';
 
			act = translate("forest_locale", 'townhall_cabinet_records');
 
		};
 
		obj {
 
			nam = 'parts';
 
			act = translate("forest_locale", 'townhall_cabinet_parts');
 
		};
 
		obj {
 
			nam = 'oil';
 
			disp = translate("forest_locale", 'townhall_cabinet_oil');
 
			tak = function(s)
 
				_('cabinet').flask = false;
 
				return translate_now("forest_locale", 'townhall_cabinet_oil_tak');
 
			end;
 
			inv = translate("forest_locale", 'townhall_cabinet_oil_inv');
 
		};
 
		obj {
 
			nam = 'record_player';
 
			act = translate("forest_locale", 'townhall_cabinet_record_player');
 
		};
 
	};
 
}
 

	
 
room {
 
	state = false;
 
	nofollow = true;
 
	nam = 'inside_well';
 
	theme = 'tower';
 
	pic = 'images/oldwell.png';
 
	disp = translate("forest_locale", 'inside_well');
 
	onenter = function(s)
 
		if not s.state then
 
			p(translate_now("forest_locale", 'inside_well_enter'));
 
			return false;
 
		end;
 
	end;
 
	decor = translate("forest_locale", 'inside_well_decor');
 
	way = {
 
		path {translate("forest_locale", 'transition_up'), 'village_center'};
 
	}
 
}:with {
 
	obj {
 
		nam = 'loose_rock';
 
		dsc = translate("forest_locale", 'inside_well_loose_rock');
 
		act = function(s)
 
			p(translate_now("forest_locale", 'inside_well_loose_rock_act'));
 
			take('hidden_key');
 
			s:disable();
 
		end;
 
	}
 
}
 

	
 
obj {
 
	nam = 'hidden_key';
 
	disp = translate("forest_locale", 'hidden_key_disp');
 
	disp2 = translate("forest_locale", 'hidden_key_disp2');
 
	disp3 = translate("forest_locale", 'hidden_key_disp3');
 
	inv = translate("forest_locale", 'hidden_key_inv');
 
}
 

	
 
room {
 
	nam = 'village_north';
 
	pic = 'images/village_north.png';
 
	disp = translate("forest_locale", 'village_north');
 
	theme = 'main';
 
	nofollow = true;
 
	decor = function(s)
 
      p(translate_now("forest_locale", 'village_north_decor'));
 
      p(translate_now("forest_locale", 'village_all_decor'));
 
  end;
 
	way = {
 
		path {'#south', translate("forest_locale", 'transition_south_to_town_hall'), 'village_center'};
 
		path {'#in', translate("forest_locale", 'transition_inside_library'), 'library'};
 
	};
 
}: with {
 
	obj {
 
		nam = '#village';
 
		act = translate("forest_locale", 'village_north_village');
 
	};
 
	obj {
 
		nam = '#road';
 
		act = translate("forest_locale", 'village_north_road');
 
	};
 
	obj {
 
		nam = '#forest';
 
		act = translate("forest_locale", 'village_north_forest');
 
	};
 
	obj {
 
		nam = '#library';
 
		act = translate("forest_locale", 'village_north_library');
 
	};
 
	obj {
 
		nam = '#mountains';
 
		act = translate("forest_locale", 'village_north_mountains');
 
	};
 
	'sun_transformed';
 
	'clouds';
 
}
 

	
 
room {
 
	nam = 'library';
 
	pic = 'images/library.png';
 
	disp = translate("forest_locale", 'library');
 
	theme = 'main';
 
	nofollow = true;
 
	decor = translate("forest_locale", 'library_decor');
 
	way = {
 
		path {'#out', translate("forest_locale", 'transition_out'), 'village_north'};
 
		path {'library_hidden_path', translate("forest_locale", 'transition_to_hidden_room'), 'library_hidden_room'}:disable();
 
	};
 
}:with {
 
	obj {
 
		nam = 'librarian';
 
		dsc = translate("forest_locale", 'library_librarian');
 
		act = function(s)
 
			walkin 'librarian_dlg'
 
		end;
 
		used = function(s, o)
 
			if o^'box' then
 
				return translate_now("forest_locale", 'library_librarian_used_box');
 
			else
 
				return translate_now("forest_locale", 'library_librarian_used_other');
 
			end;
 
		end;
 
	};
 
	obj {
 
		nam = '#tables';
 
		act = translate("forest_locale", 'library_tables');
 
	};
 
	obj {
 
		nam = '#chairs';
 
		act = translate("forest_locale", 'library_chairs');
 
	};
 
	obj {
 
		nam = '#lamps';
 
		act = translate("forest_locale", 'library_lamps');
 
	};
 
	obj {
 
		nam = '#windows';
 
		act = translate("forest_locale", 'library_windows');
 
	};
 
	obj {
 
		state = 0;
 
		nam = 'library_shelves';
 
		act = function(s)
 
			if s.state == 0 then
 
				p(translate_now("forest_locale", 'library_shelves_act_first'));
 
			else
 
				p(translate_now("forest_locale", 'library_shelves_act'));
 
			end;
 
		end;
 
	},
 
	obj {
 
		nam = 'library_the_shelf';
 
		act = function(s)
 
			if	_'library_shelves'.state == 0 then
 
				p(translate_now("forest_locale", 'library_the_shelf_act', {word=library_word}));
 
			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_notice_inside';
 
	pic = 'images/library.png';
 
	disp = translate("forest_locale", 'library');
 
	theme = 'main';
 
  nofollow = true;
 
	decor = translate("forest_locale", 'library_notice_inside_decor');
 
	way = {
 
		path {translate("common_locale", 'back'), 'library'};
 
	};
 
}
 

	
 
dlg {
 
	ring = 0;
 
	nam = 'librarian_dlg';
 
	pic = 'images/characters/librarian.png';
 
	theme = 'main';
 
	noinv = true;
 
	title = translate("forest_locale", 'librarian_dlg');
 
	enter = function(s)
 
		seen_ring_librarian = true;
 
		return translate_now("forest_locale", 'librarian_dlg_enter');
 
	end;
 
	phr = {
 
		{translate("forest_locale", 'common_dlg_greet'), translate("forest_locale", 'librarian_dlg_greet_response'),
 
			{translate("forest_locale", 'common_dlg_places'), translate("forest_locale", 'librarian_dlg_places_response'),
 
				{translate("forest_locale", 'librarian_dlg_library'), translate("forest_locale", 'librarian_dlg_library_response')};
 
        {translate("forest_locale", 'librarian_dlg_library_old'), translate("forest_locale", 'librarian_dlg_library_old_response')};
 
			},
 
			{translate("forest_locale", 'librarian_dlg_ring'), translate("forest_locale", 'librarian_dlg_ring_response')}
 
		},
 
		{cond=function(s) return seen_ring_box; end, translate("forest_locale", 'librarian_dlg_ring_look'), function(s)
 
			_('village_well').known = 1;
 
			return translate_now("forest_locale", 'librarian_dlg_ring_look_response');
 
		end};
 
		{true, translate("forest_locale", 'common_dlg_bye'), function(s)
 
			p(translate_now("forest_locale", 'librarian_dlg_bye_response'));
 
			walkout();
 
		end}
 
	}
 
}
 

	
 
function book(number) 
 
  return obj {
 
    book = number;
 
    nam = 'book_' .. tostring(number);
 
    disp = translate("forest_locale", 'library_shelf_book_disp', {number=number});
 
    dsc = function(s)
 
      return '{"' .. translate_now("forest_locale", 'library_shelf_book_disp', {number=number}) .. '"}';
 
    end;
 
    tak = translate("forest_locale", 'library_shelf_book_tak');
 
    inv = translate("forest_locale", 'library_shelf_book_inv');
 
    used = function(s, o)
 
      if o.book and where(s)^'shelf' then     
 
        local t = _'shelf'.obj;
 
        local idx = 9;
 
        for i = 1, #t do
 
          if t[i] == s then
 
            idx = i;
 
            break;
 
          end;
 
        end;
 
        
 
        remove(o, pl);
 
        _'shelf'.obj:add(o, idx);
 
        p(translate_now("forest_locale", 'library_shelf_puzzle_used_book'));
 
        if #t == 9 then
 
					for i = 1, 9 do
 
						if library_book_map[t[i].book] ~= i then
 
							return;
 
						end;
 
					end;
 
					p(translate_now("forest_locale", 'library_shelf_puzzle_used_book_success'));
 
					disable 'library_shelves'
 
					enable 'library_hidden_path'
 
					walkout()
 
				end;
 
      else
 
        return false;
 
      end;
 
    end;
 
  };
 
end;
 

	
 
room {
 
	nam = 'library_shelf_puzzle';
 
	nofollow = true;
 
	disp = translate("forest_locale", 'library');
 
	theme = 'main';
 
  onexit = function(s)
 
    if have('book_1') or have('book_2') or have('book_3') or have('book_4') or have('book_5') or have('book_6') or have('book_7') or have('book_8')or have('book_9') then
 
      p(translate_now("forest_locale", 'leave_books_message'));
 
      return false;
 
    end;
 
  end;
 
	pic = function(s)
 
		local pic = 'images/library/library_bg_' .. library_word.. '.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', translate("forest_locale", 'transition_away_from_bookstand'), 'library'};
 
	};
 
}:with {
 
	obj {
 
		nam = 'shelf';
 
		dsc = function(s)
 
			local count = #s.obj;
 
			if count > 1 then
 
				p(translate_now("forest_locale", 'library_shelf_puzzle_shelf_multiple'));
 
			elseif count == 1 then
 
				p(translate_now("forest_locale", 'library_shelf_puzzle_shelf_single'));
 
			else
 
				p(translate_now("forest_locale", 'library_shelf_puzzle_shelf_none'));
 
			end;
 
		end;
 
		act = function(s)
 
      return translate_now("forest_locale", 'library_shelf_puzzle_shelf_act', {word=library_word});
 
    end;
 
		used = function(s, o)		
 
			if o.book then
 
				remove(o, pl);
 
				_'shelf'.obj:add(o);
 
				p(translate_now("forest_locale", 'library_shelf_puzzle_used_book'));
 

	
 
				if #s.obj == 9 then
 
					for i = 1, 9 do
 
						if library_book_map[s.obj[i].book] ~= i then
 
							return;
 
						end;
 
					end;
 
					p(translate_now("forest_locale", 'library_shelf_puzzle_used_book_success'));
 
					disable 'library_shelves'
 
					enable 'library_hidden_path'
 
					walkout()
 
				end;
 
			else
 
				return false;
 
			end;
 
		end;
 
	}:with {
 
		book(1),
 
		book(2),
 
		book(3),
 
		book(4),
 
		book(5),
 
		book(6),
 
		book(7),
 
		book(8),
 
		book(9),
 
	}
 
}
 

	
 
room {
 
	nam = 'library_hidden_room';
 
	pic = function(s)
 
    if where('box')^here() then
 
      return 'images/library_hidden_room_box.png';
 
    else
 
      return 'images/library_hidden_room.png';
 
    end;
 
  end;
 
	disp = translate("forest_locale", 'library_hidden_room');
 
	theme = 'main';
 
	nofollow = true;
 
	decor = translate("forest_locale", 'library_hidden_room_decor');
 
	way = {
 
		path {translate("forest_locale", 'transition_to_main_hall'), 'library'};
 
	};
 
}:with {
 
	obj {
 
		nam = '#table';
 
		act = translate("forest_locale", 'library_hidden_room_table');
 
	};
 
	obj {
 
		oiled = false;
 
		opened = false;
 
		lock_taken = false;
 
		nam = 'box';
 
		disp = translate("forest_locale", 'box_disp');
 
		disp2 = translate("forest_locale", 'box_disp2');
 
		disp3 = translate("forest_locale", 'box_disp3');
 
		dsc = translate("forest_locale", 'box_dsc');
 
		tak = translate("forest_locale", 'box_tak');
 
		inv = function(s)
 
			seen_ring_box = true;
 
			if s.lock_taken then
 
				p(translate_now("forest_locale", 'box_inv_without_lock'));
 
			elseif s.opened then
 
				s.lock_taken = true;
 
				p(translate_now("forest_locale", 'box_inv_take_lock'));
 
				take('lock');
 
				remove('box', pl);
 
			else
 
        p(translate_now("forest_locale", 'box_inv'));
 
        if seen_ring_librarian then
 
          p(translate_now("forest_locale", 'box_inv_known'));
 
        end;
 
			end;
 
		end;
 
		used = function(s, o)
 
			if o^'hidden_key' then
 
				if s.oiled then
 
					s.opened = true;
 
					take('map');
 
					p(translate_now("forest_locale", 'box_used_key_success'));
 
				else
 
					p(translate_now("forest_locale", 'box_used_key_failed'));
 
				end;
 
			elseif o^'oil' then
 
				if not s.oiled then
 
					s.oiled = true;
 
					p(translate_now("forest_locale", 'box_used_key_oil'));
 
				else
 
					p(translate_now("forest_locale", 'box_used_key_oil2'));
 
				end;
 
			end;
 
		end;
 
	}
 
}
 

	
 
obj {
 
	nam = 'map';
 
	disp = translate("forest_locale", 'map_disp');
 
	disp2 = translate("forest_locale", 'map_disp2');
 
	disp3 = translate("forest_locale", 'map_disp3');
 
	inv = function(s)
 
		p(translate_now("forest_locale", 'map_inv'));
 
		_('fly_west_from_village'):enable();
 
	end;
 
}
 

	
 
room {
 
	nam = 'inside_crater_glade';
 
	pic = 'images/inside_crater_glade.png';
 
	disp = translate("forest_locale", 'inside_crater_glade');
 
	theme = 'main';
 
	onenter = function(s)
 
		if here()^'above_crater' then
 
			p(translate_now("forest_locale", 'inside_crater_glade_on_enter'));
 
		end;
 
	end;
 
	decor = translate("forest_locale", 'inside_crater_glade_decor');
 
	way = {
 
		path {translate("forest_locale", 'transition_fly'), "above_crater"};
 
		path {translate("forest_locale", 'transition_along_the_path'), "inside_crater_path"};
 
	}
 
}: with {
 
	obj {
 
		nam = '#forest';
 
		act = translate("forest_locale", 'inside_crater_glade_forest');
 
	};
 
	obj {
 
		nam = '#oak';
 
		act = translate("forest_locale", 'inside_crater_glade_oak');
 
	};
 
	obj {
 
		nam = '#grass';
 
		act = translate("forest_locale", 'inside_crater_glade_grass');
 
	};
 
	obj {
 
		nam = '#path';
 
		act = translate("forest_locale", 'inside_crater_glade_path');
 
	};
 
	obj {
 
		nam = '#tower';
 
		act = translate("forest_locale", 'inside_crater_glade_tower');
 
	};
 
	obj {
 
		nam = '#crater';
 
		act = translate("forest_locale", 'inside_crater_glade_crater');
 
	};
 
}
 

	
 
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 = translate("forest_locale", 'inside_crater_path');
 
	theme = 'main';
 
	decor = translate("forest_locale", 'inside_crater_path_decor');
 
	exit = function(s, t)
 
		if t^'crater_near_tower' and seen('solarscale', s) then
 
			remove('solarscale', where('solarscale'));
 
			p(translate_now("forest_locale", 'inside_crater_path_exit'));
 
		end;
 
	end;
 
	way = {
 
		path {translate("forest_locale", 'transition_to_glade'), "inside_crater_glade"};
 
		path {translate("forest_locale", 'transition_to_tower'), "crater_near_tower"};
 
	};
 
}: with {
 
	obj {
 
		nam = '#grass';
 
		act = translate("forest_locale", 'inside_crater_path_grass');
 
	};
 
	obj {
 
		nam = '#crater';
 
		act = translate("forest_locale", 'inside_crater_path_crater')
 
	};
 
	obj {
 
		nam = '#trees';
 
		act = translate("forest_locale", 'inside_crater_path_trees')
 
	};
 
	obj {
 
		nam = '#tower';
 
		act = translate("forest_locale", 'inside_crater_path_tower')
 
	};
 
	obj {
 
		nam = '#stump';
 
		dsc = function(s)
 
			if seen('solarscale', here()) then
 
				p(translate_now("forest_locale", 'inside_crater_path_stump_with_solarscale'));
 
			else
 
				p(translate_now("forest_locale", 'inside_crater_path_stump'));
 
			end;
 
		end;
 
		act = translate("forest_locale", 'inside_crater_path_stump_act');
 
	};
 
	obj {
 
		nam = 'solarscale';
 
		act = function(s)
 
			walkin('solarscale_dlg');
 
		end;
 
	}
 
}
 

	
 
dlg {
 
	nam = 'solarscale_dlg';
 
	disp = translate("solarscale_locale", 'disp');
 
	theme = 'main';
 
	pic = 'images/inside_crater_path.png;images/characters/solarscale.png';
 
	enter = translate("solarscale_locale", 'first_dlg_enter');
 
  convince = 0;
 
  open_q45 = false;
 
	phr = {
 
    {only=true, '#q1', translate("solarscale_locale", 'first_dlg_dragon'), translate("solarscale_locale", 'first_dlg_dragon_response'),
 
      {translate("solarscale_locale", 'first_dlg_dragon_admit'), function(s) 
 
        _('solarscale_dlg').convince = _('solarscale_dlg').convince + 1;
 
        return translate_now("solarscale_locale", 'first_dlg_dragon_admit_response');
 
      end};
 
      {translate("solarscale_locale", 'first_dlg_dragon_question'), translate("solarscale_locale", 'first_dlg_dragon_question_response')};
 
      {translate("solarscale_locale", 'first_dlg_dragon_decline'), function(s) 
 
        _('solarscale_dlg').convince = _('solarscale_dlg').convince - 1;
 
        return translate_now("solarscale_locale", 'first_dlg_dragon_decline_response');
 
      end};
 
    };
 
    {only=true, '#q2', translate("solarscale_locale", 'first_dlg_about_map'), function(s)
 
        _('solarscale_dlg').convince = _('solarscale_dlg').convince + 1;
 
        _('solarscale_ally').tower_know_discussed = true;
 
        return translate_now("solarscale_locale", 'first_dlg_about_map_response');
 
    end, 
 
      {translate("solarscale_locale", 'first_dlg_about_map_1'), translate("solarscale_locale", 'first_dlg_about_map_1_response')};
 
      {translate("solarscale_locale", 'first_dlg_about_map_2'), translate("solarscale_locale", 'first_dlg_about_map_1_response')};
 
      {translate("solarscale_locale", 'first_dlg_about_map_3'), function(s)
 
          disable('#q3');
 
          _('solarscale_dlg').open_q45 = true;
 
          return translate_now("solarscale_locale", 'first_dlg_about_map_3_response');
 
      end};
 
    };
 
    {'#q3', translate("solarscale_locale", 'first_dlg_unusual'), function(s)
 
        _('solarscale_dlg').open_q45 = true;
 
        return translate_now("solarscale_locale", 'first_dlg_unusual_response');
 
    end};
 
    {cond=function(s) return _('solarscale_dlg').open_q45 end, '#q4', translate("solarscale_locale", 'first_dlg_tower'), translate("solarscale_locale", 'first_dlg_tower_response')};
 
    {cond=function(s) return _('solarscale_dlg').open_q45 end, '#q5', translate("solarscale_locale", 'first_dlg_tower_join'), function(s)
 
      if _('solarscale_dlg').convince >= 3 then
 
        walkout();
 
        solarscale_with_me = true;
 
        remove('solarscale', where('solarscale'));
 
        put('solarscale_ally', here());
 
        lifeon(_'solarscale_ally');
 
        return translate_now("solarscale_locale", 'first_dlg_tower_join_response_success_1');
 
      else
 
        return translate_now("solarscale_locale", 'first_dlg_tower_join_response_fail');
 
      end;
 
    end;
 
      {translate("solarscale_locale", 'first_dlg_tower_join_1'), function(s)
 
        _('solarscale_dlg').convince = _('solarscale_dlg').convince + 1;
 
        if _('solarscale_dlg').convince >= 3 then
 
          walkout();
 
          solarscale_with_me = true;
 
          remove('solarscale', where('solarscale'));
 
          put('solarscale_ally', here());
 
          lifeon(_'solarscale_ally');
 
          return translate_now("solarscale_locale", 'first_dlg_tower_join_response_success_1');
 
        else
 
          return translate_now("solarscale_locale", 'first_dlg_tower_join_response_fail_1');
 
        end;
 
      end;};
 
      {translate("solarscale_locale", 'first_dlg_tower_join_2'), translate("solarscale_locale", 'first_dlg_tower_join_response_2')};
 
      {translate("solarscale_locale", 'first_dlg_tower_join_3'), function(s)
 
        _('solarscale_dlg').convince = _('solarscale_dlg').convince + 1;
 
        if _('solarscale_dlg').convince >= 3 then
 
          walkout();
 
          solarscale_with_me = true;
 
          remove('solarscale', where('solarscale'));
 
          put('solarscale_ally', here());
 
          lifeon(_'solarscale_ally');
 
          return translate_now("solarscale_locale", 'first_dlg_tower_join_response_success_3');
 
        else
 
          return translate_now("solarscale_locale", 'first_dlg_tower_join_response_fail_3');
 
        end;
 
      end;};
 
      {translate("solarscale_locale", 'first_dlg_tower_bye_thanks'), function(s)
 
        walkout();
 
        remove('solarscale', where('solarscale'));
 
        return translate_now("solarscale_locale", 'first_dlg_tower_bye_response');
 
      end};
 
    };
 
    {'#q6', function(s)
 
        if not closed('#q3') then
 
          return translate_now("solarscale_locale", 'first_dlg_tower_bye_no_time');
 
        else 
 
          return translate_now("solarscale_locale", 'first_dlg_tower_bye_thanks');
 
        end;
 
    end, function(s)
 
			walkout();
 
			remove('solarscale', where('solarscale'));
 
			return translate_now("solarscale_locale", 'first_dlg_tower_bye_response');
 
		end};
 
  }
 
}
 

	
 
room {
 
	nam = 'crater_near_tower';
 
	pic = 'images/crater_near_tower.png';
 
	disp = translate("forest_locale", 'crater_near_tower');
 
	theme = 'main';
 
	decor = translate("forest_locale", 'crater_near_tower_decor');
 
  enter = function(s)
 
    tower_seen = true;
 
  end;
 
	way = {
 
		path {translate("forest_locale", 'transition_along_the_path'), "inside_crater_path"};
 
		path {translate("forest_locale", 'transition_inside_tower'), "tower_level_1"};
 
	};
 
}:with {
 
	obj {
 
		nam = '#tower';
 
		act = translate("forest_locale", 'crater_near_tower_tower');
 
	};
 
	obj {
 
		nam = '#grass';
 
		act = translate("forest_locale", 'crater_near_tower_grass');
 
	};
 
	obj {
 
		nam = '#trees';
 
		act = translate("forest_locale", 'crater_near_tower_trees');
 
	};
 
	obj {
 
		nam = '#sun';
 
		act = translate("forest_locale", 'crater_near_tower_sun');
 
	};
 
}
images/candles/1/candles_blow_out_short.png
Show inline comments
 
binary diff not shown
Show images
images/candles/1/candles_flame.png
Show inline comments
 
binary diff not shown
Show images
images/candles/1/candles_flame_start.png
Show inline comments
 
binary diff not shown
Show images
images/candles/2/candles_blow_out_short.png
Show inline comments
 
binary diff not shown
Show images
images/candles/2/candles_flame.png
Show inline comments
 
binary diff not shown
Show images
images/candles/2/candles_flame_start.png
Show inline comments
 
binary diff not shown
Show images
images/candles/3/candles_blow_out_short.png
Show inline comments
 
binary diff not shown
Show images
images/candles/3/candles_flame.png
Show inline comments
 
binary diff not shown
Show images
images/candles/3/candles_flame_start.png
Show inline comments
 
binary diff not shown
Show images
images/candles/4/candles_blow_out_short.png
Show inline comments
 
binary diff not shown
Show images
images/candles/4/candles_flame.png
Show inline comments
 
binary diff not shown
Show images
images/candles/4/candles_flame_start.png
Show inline comments
 
binary diff not shown
Show images
images/candles/5/candles_blow_out_short.png
Show inline comments
 
binary diff not shown
Show images
images/candles/5/candles_flame.png
Show inline comments
 
binary diff not shown
Show images
images/candles/5/candles_flame_start.png
Show inline comments
 
binary diff not shown
Show images
images/candles/6/candles_blow_out_short.png
Show inline comments
 
binary diff not shown
Show images
images/candles/6/candles_flame.png
Show inline comments
 
binary diff not shown
Show images
images/candles/6/candles_flame_start.png
Show inline comments
 
binary diff not shown
Show images
images/candles/7/candles_blow_out_short.png
Show inline comments
 
binary diff not shown
Show images
images/candles/7/candles_flame.png
Show inline comments
 
binary diff not shown
Show images
images/candles/7/candles_flame_start.png
Show inline comments
 
binary diff not shown
Show images
images/main_theme/inv_bottom.png
Show inline comments
 
binary diff not shown
Show images
main3.lua
Show inline comments
 
-- $Name: A Dragon and the Tower$
 
-- $Version: 1.0.4$
 
-- $Author: Khaelenmore Thaal & Sabra Naikomy$
 
-- $Info: A tiny illustrated text adventure$
 

	
 
require "lib/link"
 
require "noinv"
 
require 'snd'
 
require 'keys'
 
require "timer"
 
require "theme"
 
require "lib/decor"
 
require "prefs"
 
require 'lib/utils'
 
require "lib/dire/theme"
 
require "lib/locale"
 
require "lib/fading"
 
require "lib/smoke"
 

	
 
declare({
 
    closed_beta_participants = 'arbtttrn6, De@th K!d, Fehatt, Lesha Pak, Łukasz Sawicki, Niko Flang, Oleg Bosh, Terracon, Андрей Лобанов';
 
})
 

	
 
fmt.quotes = false;
 
fmt.filter = function(r)
 
    local utf8 = (std.ref 'game'.codepage == 'UTF-8' or std.ref 'game'.codepage == 'utf-8')
 
    
 
    if utf8 then
 
        r = r:gsub('"([^"]*)"', translate_now("common_locale", 'quotes'));
 
    end;
 
    
 
    return r;
 
end;
 

	
 
game.act = translate('main_locale', 'empty_act');
 
game.use = function(s)
 
	return translate_now('main_locale', random_phrase({
 
    'empty_use_1',
 
		'empty_use_2',
 
		'empty_use_3',
 
		'empty_use_4',
 
		'empty_use_5'
 
  }));
 
end;
 
game.inv = translate("main_locale", 'empty_inv');
 

	
 
instead.notitle = function()
 
	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
 
    if diretheme.get_inches() < 7 then
 
      -- On a screen smaller than 7 inch
 
      wsrec = math.floor(w / 640);
 
      rval = math.floor(h / 480);
 
    else
 
      wsrec = math.floor(w / 800);
 
      rval = math.floor(h / 540);
 
    end;
 
    
 
    if wsrec < rval then
 
      rval = wsrec;
 
    end;
 
    
 
		if rval < 1 then
 
      rval = 1;
 
    end;
 
	end;
 
	
 
	return rval;
 
end;
 

	
 
function get_cursor_scale()
 
  local rval = prefs.cursor_scale;
 
  
 
  if not rval then
 
    rval = get_graphic_scale();
 
  end;
 
  
 
  return rval;
 
end;
 

	
 
function get_font_scale()
 
	local rval = prefs.font_scale;
 
	if not rval then
 
		rval = get_graphic_scale() * 100;
 
    
 
    if diretheme.get_inches() < 7 then
 
      rval = rval + math.floor(rval / 2);
 
    end;
 
	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
 

	
 
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');
 
    ['irradiated'] = snd.new('sound/irradiated.ogg');
 
	},
 
	gusts = {
 
		'wind_gust_1';
 
		'wind_gust_2';
 
		'wind_gust_3';
 
	},
 
	menu_sprites = {
 
	},
 
  last_location = false
 
}
 

	
 
global {
 
  in_game = false,
 
}
 

	
 
include "tutorial"
 
include "computer_parts"
 
include "solarscale"
 
include "tower"
 
include "forest"
 
include "ending"
 

	
 
function get_sprite(path, transparent)
 
	local s = diretheme.get_scale();
 
	
 
	if not menu_sprites[path] then
 
    if s ~= 1 then
 
      menu_sprites[path] = pixels.new(path):scale(s, s):sprite();
 
    else
 
      menu_sprites[path] = sprite.new(path);
 
    end;
 
    if transparent then
 
      menu_sprites[path]:colorkey(transparent);
 
    end;
 
	end;
 
	
 
	return menu_sprites[path];
 
end;
 

	
 
function get_button(button_name)
 
  local path = 'images/title/' .. button_name .. '.' .. get_language() .. '.png';
 
  if menu_sprites[path] then
 
    return menu_sprites[path];
 
  end;
 
  
 
  local sprite = nil;
 
  
 
  --Check if file exists(only used here, so not moved to function)
 
  local f = io.open(path, 'r');  
 
  if f then
 
    f:close();
 
    sprite = get_sprite(path, 'fuchsia')
 
  end;
 
  
 
  if not sprite then
 
    local path = 'images/title/' .. button_name .. '.' .. get_default_language() .. '.png';
 
    sprite = get_sprite(path, 'fuchsia');
 
  end;
 
  return sprite
 
end;
 

	
 
function stop_menu()
 
	D {'bgframe'};
 
	D {'background'};
 
	D {'bganim'};
 
	D {'title'};
 
end;
 

	
 
game.ondecor = function(s, name, press, x, y, btn)
 
	if press then
 
		if name == 'settings_open' then
 
			in_game = true;
 
			walkin('intro_settings');
 
			return true;
 
		end;
 
	end;
 
	return false;
 
end;
 

	
 
game.afterwalk = function()
 
  if last_location then
 
    dprint(last_location, '->', here().nam);
 
    
 
    if _(last_location).themeDispose then
 
      _(last_location):themeDispose();
 
    end;
 
  end;
 
	
 
  local theme = std.call(here(), 'theme');
 
  
 
  if theme == nil then
 
    error("Theme is unset here: " .. tostring(here().nam));
 
  end;
 
  
 
	if theme ~= nil and theme ~= current_theme then
 
		dprint('Switch theme', current_theme, '->', theme);
 
		set_theme(theme);
 
	end;
 
  
 
  if here().themeInit then
 
		here():themeInit();
 
	end;
 
  
 
  last_location = here().nam;
 
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 sh <= 560 * scale then
 
		btop = btop - 20;
 
	end;
 
	
 
	if #buttons == 1 then
 
		D {
 
			buttons[1], 
 
			'img', 
 
      get_button(buttons[1]),
 
			x=ox + 398 * scale, 
 
			y=oy + (btop + button_dy) * scale,
 
			click=true,
 
      background=true,
 
      z=3
 
		};
 
	else
 
		D {
 
			buttons[1], 
 
			'img', 
 
			get_button(buttons[1]),
 
			x=ox + (157 + button_dx) * scale, 
 
			y=oy + (btop + button_dy) * scale,
 
			click=true,
 
      background=true,
 
      z=3
 
		};
 
		D {
 
			buttons[2], 
 
			'img', 
 
			get_button(buttons[2]),
 
			x=ox + 398 * scale,
 
			y=oy + (btop + button_dy) * scale,
 
			click=true,
 
      background=true,
 
      z=3
 
		};
 
		D {
 
			buttons[3], 
 
			'img', 
 
			get_button(buttons[3]),
 
			x=ox + (639 - button_dx) * scale,
 
			y=oy + (btop + button_dy) * scale,
 
			click=true,
 
      background=true,
 
      z=3
 
		};
 
	end;
 
	
 
	if #buttons == 5 then
 
		btop = btop + 80
 
		D {
 
			buttons[4], 
 
			'img', 
 
			get_button(buttons[4]),
 
			x=ox + (278 + button_dx / 2) * scale, 
 
			y=oy + (btop + button_dy) * scale,
 
			click=true,
 
      background=true,
 
      z=3
 
		};
 
		
 
		D {
 
			buttons[5], 
 
			'img', 
 
			get_button(buttons[5]),
 
			x=ox + (519 - button_dx / 2) * scale, 
 
			y=oy + (btop + button_dy) * scale,
 
			click=true,
 
      background=true,
 
      z=3
 
		};
 
	end;
 
	
 
  if sw > w or sh > h then
 
    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=5};
 
end;
 
  
 
  if not D('background') then
 
    D {'background', 'img', get_sprite('images/title/bg.png'), x=ox, y=oy, z=4, background=true};
 
  end;
 

	
 
	if not D('bganim') then
 
		D {'bganim', 'img', get_sprite('images/title/bg_frames.png'), x=ox, y=oy, w=w, h=h, frames=16, z=3, delay=200, animated=true, background=true, frame_data=scale_frame_data({
 
       {},
 
       {x=0, y=0, w=960, h=302, dx=0, dy=0},
 
       {x=960, y=0, w=960, h=302, dx=0, dy=0},
 
       {x=1920, y=0, w=960, h=302, dx=0, dy=0},
 
       {x=2880, y=0, w=960, h=302, dx=0, dy=0},
 
       {x=0, y=302, w=960, h=302, dx=0, dy=0},
 
       {x=960, y=302, w=960, h=302, dx=0, dy=0},
 
       {x=1920, y=302, w=960, h=302, dx=0, dy=0},
 
       {x=2880, y=302, w=960, h=302, dx=0, dy=0},
 
       {x=0, y=604, w=960, h=302, dx=0, dy=0},
 
       {x=960, y=604, w=960, h=302, dx=0, dy=0},
 
       {x=1920, y=604, w=960, h=302, dx=0, dy=0},
 
       {x=2880, y=604, w=960, h=302, dx=0, dy=0},
 
       {x=0, y=906, w=960, h=302, dx=0, dy=0},
 
       {x=960, y=906, w=960, h=302, dx=0, dy=0},
 
       {x=1920, y=906, w=960, h=302, dx=0, dy=0}
 
    })};
 
	end;
 
	if not D('title') then
 
		D {'title', 'img', get_sprite('images/title/title.png', 'fuchsia'), x=ox + 230 * scale, y=oy + 88  * scale, z=2, background=true};
 
	end;
 
	
 
	if with_text then
 
		D {'textbg', 'img', get_sprite('images/title/text_background.png', 'fuchsia'), x=ox + 180 * scale, z=1, y=oy + (126 + button_dy) * scale, background=true};
 
		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)
 
    if prefs.completed then
 
      snd.music('sound/bgm_credits.ogg');
 
    else
 
      snd.music('sound/bgm_intro.ogg');
 
    end;
 
	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;
 
	decor = 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://github.com/instead-hub/instead/}^' ..
 
			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_closed_beta') .. ': ' .. closed_beta_participants .. '^^'..
 
			translate_now("menu_locale", 'credits_thanks');
 
	end;
 
}
 

	
 
obj {
 
	nam = 'empty';
 
	dsc = '^';
 
}
 

	
 
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();
 
					walkback();
 
				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');
 
			
 

	
 
			pn(fmt.c(fmt.b(translate_now("menu_locale", 'language'))));
 
			
 
			local t;
 
			if get_language_saved() == '' then
 
				t = l;
 
			else
 
				t = '{#l_auto|'.. l .. '}';
 
			end;
 
			
 
      for i, language in ipairs(get_language_list()) do
 
        if get_language_saved() == language[1] then
 
          t = t .. ' | ' .. language[2];
 
        else
 
          t = t .. ' | ' .. '{@set_language ' .. language[1] .. '|' .. language[2] .. '}';
 
        end;
 
      end;
 
		
 
			pn(fmt.c(t) .. '^')
 
		end;
 
	}: with {
 
		obj {
 
			nam = '#l_auto';
 
			act = function(s)
 
				set_language('');
 
				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;
 

	
 
			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 = '#cursor_scale';
 
		dsc = function(s)
 
			local cursor_scale = get_cursor_scale();
 
			
 
			pn(fmt.c(fmt.b(translate_now("menu_locale", 'cursor_scale')) .. ' {[' .. translate_now("menu_locale", 'auto_option') .. ']}'))
 
		
 
			local t = '';
 
			
 
			if cursor_scale > 1 then
 
				t = t .. '{#cursor_less|<<} ';
 
			else
 
				t = t .. '<< ';
 
			end;
 

	
 
			local l = translate_now("menu_locale", 'auto_option') .. ' (' .. tostring(cursor_scale * 100) .. '%)';
 
			
 
			if prefs.cursor_scale then
 
				l = tostring(cursor_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 cursor_scale < smax then
 
				t = t .. ' {#cursor_more|>>}';
 
			else
 
				t = t .. ' >>';
 
			end;
 
		
 
			pn(fmt.c(t) .. '^');
 
		end;
 
		act = function(s)
 
			prefs.cursor_scale = false;
 
			prefs:store();
 
		
 
			set_theme(std.call(here(), 'theme'));
 
			menu_sprites = {};
 
			here():themeDispose();
 
			stop_menu();
 
			here():themeInit();
 
			walk(here());
 
		end;
 
	}: with {
 
		obj {
 
			nam = '#cursor_less';
 
			act = function(s)
 
				prefs.cursor_scale = get_cursor_scale() - 1;
 
				
 
				prefs:store();
 
		
 
				set_theme(std.call(here(), 'theme'));
 
				menu_sprites = {};
 
				here():themeDispose();
 
				stop_menu();
 
				here():themeInit();
 
				walk(here());
 
			end;
 
		};
 
		obj {
 
			nam = '#cursor_more';
 
			act = function(s)
 
				prefs.cursor_scale = get_cursor_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;
 
		};
 
	};
 
  obj {
 
    nam = '#textinput';
 
    dsc = function(s)
 
      pn(fmt.c(fmt.b(translate_now("menu_locale", 'use_text_input'))));
 
      
 
      local t = '';
 
      if prefs.text_input then
 
        t = '{#ti_disable|' .. translate_now("menu_locale", 'disable') .. '} | ' .. translate_now("menu_locale", 'enable');
 
			else
 
				t = translate_now("menu_locale", 'disable') .. ' | {#ti_enable|' .. translate_now("menu_locale", 'enable') .. '}';
 
			end;
 
      
 
      pn(fmt.c(t) .. '^');
 
    end;
 
  }: with {
 
    obj {
 
      nam = '#ti_disable';
 
      act = function(s)
 
        prefs.text_input = false;
 
        prefs:store();
 
        walk(here());
 
      end;
 
    };
 
    obj {
 
      nam = '#ti_enable';
 
      act = function(s)
 
        prefs.text_input = true;
 
        prefs:store();
 
        walk(here());
 
      end;
 
    };
 
  };
 
}
 

	
 
room {
 
	nosave = true;
 
	noautosave = true;
 
  nofollow = true;
 
	theme = 'black';
 
  noinv = true;
 
	nam = 'resolution_warning';
 
	title = translate("menu_locale", 'warning');
 
	decor = translate("menu_locale", 'resolution_warning');
 
	onenter = stop_menu;
 
}: with {
 
	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;
 
  nofollow = true;
 
	theme = 'black';
 
  noinv = true;
 
	nam = 'theme_warning';
 
	title = translate("menu_locale", 'warning');
 
	decor = translate("menu_locale", 'theme_warning');
 
	onenter = stop_menu;
 
}: with {
 
	obj {
 
		nam = '#sysset';
 
		dsc = function(s) return '{' .. translate_now("menu_locale", 'system_settings') .. '}'; end;
 
		act = function(s)
 
			instead.menu();
 
		end;
 
	}
 
}
 

	
 
function set_theme(t)  
 
  -- resetting defaults
 
  fmt.para = true;
 
  std.scene_delim = '^^';
 
  theme.set('snd.click', 'sound/click.wav');
 
  
 
	D {'settings_open'};
 

	
 
  local tname, tcolor_text, tcolor_link, tcolor_alink;
 

	
 
  local width, height = diretheme.get_screen();
 
	
 
  -- 640x480 is the base size
 
	local scale = get_graphic_scale();
 
	local max_scale_x = math.floor(width / 640);
 
	local max_scale_y = math.floor(height / 480);
 
	-- Fail-safe for too small screen
 
  if max_scale_x < 1 then max_scale_x = 1; end;
 
  if max_scale_y < 1 then max_scale_y = 1; end;
 
	  
 
  local max_scale = math.min(max_scale_x, max_scale_y);
 
  
 
  if scale > max_scale then
 
    scale = max_scale;
 
    prefs.graphic_scale = false;
 
  end;
 
  
 
  local cursor_scale = get_cursor_scale();
 
  if cursor_scale > 2 * max_scale then
 
    cursor_scale = 2 * max_scale;
 
  end;
 
  
 
	local font_scale = get_font_scale() / 100;
 
	if font_scale > 2 * scale then
 
		font_scale = scale;
 
		prefs.font_scale = font_scale * 100
 
	end;
 
	
 
  local inv_scale = get_inventory_font_scale() / 100;
 
	
 
	local text_align = 'justify';
 
	if prefs.text_alignment == 2 then
 
		text_align = 'left';
 
	end;
 
	
 
	local hpadding, vpadding = 0, 0;
 
	if prefs.text_padding == 2 then
 
		hpadding, vpadding = 24, 12;
 
	end;
 
	
 
	local interval = '1.0';
 
	if prefs.text_interval == 2 then
 
		interval = '1.5';
 
	end;
 
	
 
	local canvas = diretheme.set_canvas({rmax = 2, rmin = 1});
 
	diretheme.set_scale(scale);
 

	
 
  local scaled_width, scaled_height = diretheme.get_scaled_screen();
 

	
 
	current_theme = t;
 
  local tvariant = 0;
 
  if t:match("_bw$") then
 
    t = t:gsub("_bw$", "");
 
    tvariant = 1;
 
  end;
 
  
 
  -- Most text area settings are per-theme
 
  local text_area = {};
 
  
 
  -- Hide inventory by default
 
  local inventory = {
 
    rect = {
 
      lx = width + 1,
 
      y = 0,
 
      wmax = 1,
 
      wmin = 1,
 
      ty = 2,
 
      by = 2,
 
      ax = 1
 
    }
 
  };
 
  
 
  -- And image
 
  local image_area = {
 
    rect = {
 
      lx = width + 1,
 
      ax = 1,
 
      wmax = 584,
 
      hmax = 258,
 
      wmin = 584,
 
      hmin = 258
 
    };
 
    bg = {};
 
    mode = 'float';
 
  };
 
  
 
  -- Preset colors
 
  local theme_directory = nil;
 
  local text_color, link_color, alink_color;
 
  local inv_color, inv_link, inv_alink;
 
  if t == 'terminal' or t == 'black' then
 
    diretheme.set_canvas({
 
      lx = 0, ty = 0, rx = 0, by = 0
 
    });
 
    text_color = '#D0FFFF';
 
    link_color = '#ABDECE';
 
    alink_color = '#9BCEBE';  
 
    theme_directory = 'images/tower_theme';
 
    
 
    text_area.text = {
 
      font = 'fonts/vga.ttf',
 
      color = text_color,
 
      link = link_color,
 
      alink = alink_color,
 
      size = 16
 
    };
 
  else
 
    canvas = diretheme.set_canvas({
 
      lx = 0, ty = 0, rx = 0, by = 0, rmin = 1.2, rmax = 1.8
 
    });
 
    
 
    if t == 'menu' or t == 'main' or t == 'ending_outside' or t == 'credits_outside' then
 
      inv_color = '#403426';
 
      inv_link = '#403426';
 
      inv_alink = '#61503A';
 
      
 
      if tvariant == 0 then
 
        text_color = '#000504';
 
        link_color = '#80382A';
 
        alink_color = '#80605D';
 
        theme_directory = 'images/main_theme';
 
      else
 
        text_color = '#040404';
 
        link_color = '#434343';
 
        alink_color = '#585858';
 
        theme_directory = 'images/bwm_theme';
 
      end;
 
      
 
      text_area.uppos = {ax=1, x = 12, y = 0, ay=-1};
 
      text_area.downpos = {ax=1, x = 12, y = 0, ay=1};
 
      text_area.bg = {
 
        image = theme_directory .. '/text_bg.png',
 
        options = {
 
          mode = 6,
 
          drawmethod = 2,
 
          slice = {
 
            x = 9,
 
            y = 6,
 
            w = 96,
 
            h = 96
 
          },
 
          scale = true
 
        }
 
      };
 
    elseif t == 'tower' or t == 'ending_inside' or t == 'credits_inside' then
 
      inv_color = '#6b9e8e';
 
      inv_link = '#9bcebe';
 
      inv_alink = '#Bbeede';
 
      
 
      if tvariant == 0 then
 
        text_color = '#93DDCD';
 
        link_color = '#E0F0EA';
 
        alink_color = '#FFFFFF';
 
        theme_directory = 'images/tower_theme';
 
      else
 
        text_color = '#ADADAD';
 
        link_color = '#CDCDCD';
 
        alink_color = '#BDBDBD';
 
        theme_directory = 'images/bwt_theme';
 
      end;
 
      
 
      text_area.uppos = {ax=1, x = 16, y = 0, ay=-1};
 
      text_area.downpos = {ax=1, x = 16, y = 0, ay=1};
 
      text_area.bg = {
 
        image = theme_directory .. '/text_bg.png',
 
        options = {
 
          mode = 6,
 
          drawmethod = 2,
 
          slice = {
 
            x = 6,
 
            y = 6,
 
            w = 128,
 
            h = 128
 
          },
 
          scale = true
 
        }
 
      };
 
    end;
 
    
 
    if t == 'ending_inside' or t == 'ending_outside' then
 
      canvas = diretheme.set_canvas({
 
        lx = 0, ty = 0, rx = 0, by = 0
 
      });
 
    end;
 
  
 
    text_area.align = text_align;
 
    text_area.height = interval;
 
    text_area.scaleui = true;
 
    text_area.up = theme_directory .. '/arrow_up.png';
 
    text_area.down = theme_directory .. '/arrow_down.png';
 
    text_area.text = {
 
      font = 'fonts/{sans,sans-b,sans-i,sans-bi}.ttf',
 
      color = text_color,
 
      link = link_color,
 
      alink = alink_color,
 
      size = math.floor(16 * font_scale),
 
      noscale = true
 
    };
 
    
 
    inventory.up = theme_directory .. '/arrow_up.png';
 
    inventory.down = theme_directory .. '/arrow_down.png';
 
    inventory.uppos = {ax=1, x = 8, y = 0, ay=-1};
 
    inventory.downpos = {ax=1, x = 8, y = 0, ay=1};
 
    inventory.text = {
 
      color = inv_color,
 
      link = inv_link,
 
      alink = inv_alink,
 
      size = math.floor(16 * inv_scale),
 
      noscale = true
 
    };
 
    inventory.height = interval;
 
  end;
 
  
 
  if t == 'main' or t == 'tower' then
 
    std.scene_delim = '^' .. fmt.c(fmt.img(theme_directory .. '/line_separator.png')) .. '^'
 
  end;
 
  
 
 -- And menu, but need theme_directory to have proper button image
 
  local menu = {
 
    button = {
 
      image = theme_directory ..'/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 = true;
 
  };
 
  
 
  local cursor, active_cursor = 'images/cursor.png', 'images/cursor_active.png';
 
  if tvariant == 1 then
 
    cursor, active_cursor = 'images/cursor_bw.png', 'images/cursor_active_bw.png'
 
  end;
 
  
 
  diretheme.set_cursor({
 
		x = 2,
 
		y = 2,
 
		normal = cursor,
 
		active = active_cursor,
 
    scale = true;
 
		scalefactor = cursor_scale;
 
	});
 
  
 
	if t == 'menu' then
 
		diretheme.set_background('#89C6AE', 255, 'images/main_theme/background.png', {mode=2, scale=true});
 
    local padding_delta = -10;
 
    if height < 520 * scale then
 
      padding_delta = -95;
 
    end;
 
    
 
    text_area.rect = {
 
      ty = padding_delta + vpadding,
 
      wmax = 538 - hpadding * 2,
 
      hmax = 322 - vpadding * 2,
 
      ay = 0
 
    };
 
    text_area.text = text_area.text;
 
    text_area.uppos = {ax=1, x = 15, y = 65, ay=-1};
 
    text_area.downpos = {ax=1, x = 15, y = -20, ay=1};
 
    text_area.contentrect = {wf=prefs.text_width / 100};
 
    text_area.bg = '';
 
	elseif t == 'main' then
 
		diretheme.set_background('#89C6AE', 255, 'images/main_theme/background.png', {mode=2, scale = true});
 
		
 
		local image_bg = 'images/main_theme/picture_bg.png';
 
		if canvas.w < 800 * scale then
 
			image_bg = 'images/main_theme/picture_bg_small.png';
 
		end;
 
		
 
    image_area.leftof = 'inv';
 
    image_area.topof = 'text';
 
    image_area.rect = {
 
      ax = 0,
 
      wmax = 584,
 
      hmax = 265,
 
      wmin = 584,
 
      hmin = 265
 
    };
 
    image_area.contentrect = {
 
      ax = 0,
 
      ay = -1,
 
      ty = 11,
 
      wmin = 320,
 
      hmin = 240,
 
      wmax = 320,
 
      hmax = 240
 
    };
 
    image_area.bg = {
 
      image = image_bg,
 
      options = {
 
        mode = 1,
 
        scale = true
 
      }
 
    };
 
		
 
    text_area.leftof = 'inv';
 
    text_area.rect = {
 
      lx = 7,
 
      ty = 266,
 
      rx = 8,
 
      by = 2,
 
      ax = 1,
 
      ay = 1
 
    };
 
    text_area.contentrect = {
 
      lx = 21 + hpadding,
 
      rx = 21 + hpadding,
 
      ty = 14 + vpadding,
 
      by = 14 + vpadding,
 
      wf=prefs.text_width / 100
 
    };
 
    
 
		inventory.rect = {
 
      rx = 2,
 
      y = 2,
 
      wmax = 208,
 
      wmin = 208,
 
      ty = 2,
 
      by = 2,
 
      ax = 1
 
    };
 
    inventory.contentrect = {
 
      lx = 25,
 
      rx = 25,
 
      ty = 40,
 
      by = 40
 
    };
 
    inventory.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}
 
    };
 

	
 
    menu.buttonrect = {
 
      wmin = 50,
 
      wmax = 50,
 
      hmin = 16,
 
      hmax = 16,
 
      by = 12,
 
      ay = 1,
 
      rx = 81,
 
      ax = 1
 
    };
 

	
 
		D {
 
			'settings_open', 
 
			'img', 
 
			get_sprite('images/main_theme/settings.png'),
 
			'raw',
 
			x=canvas.x + canvas.w - 33 * scale, 
 
			y=canvas.y + canvas.h - 30 * scale, 
 
			click=true,
 
			z=-1,
 
      background=true
 
      xc=0,
 
      yc=0,
 
      w=24 * scale,
 
      h=22 * scale,
 
			click=true
 
		};
 
	elseif t == 'tower' then
 
		diretheme.set_background('#181E37', 255, 'images/tower_theme/background.png', {mode=2, scale=true});
 
		
 
		local image_bg = 'images/tower_theme/picture_bg.png';
 
		if canvas.w < 800 * scale then
 
			image_bg = 'images/tower_theme/picture_bg_small.png';
 
		end;
 
		
 
    image_area.leftof='inv';
 
    image_area.topof='text';
 
    image_area.rect = {
 
      ax = 0,
 
      maxw = 584,
 
      maxh = 258,
 
      minw = 584,
 
      minh = 258
 
    };
 
    image_area.contentrect = {
 
      ax = 0,
 
      ay = -1,
 
      ty = 12,
 
      wmin = 320,
 
      hmin = 240,
 
      wmax = 320,
 
      hmax = 240
 
    };
 
    image_area.bg = {
 
      image = image_bg,
 
      options = {
 
        mode = 1,
 
        scale = true
 
      }
 
    };
 
		
 
    text_area.leftof = 'inv';
 
    text_area.rect = {
 
      lx = 7,
 
      ty = 266,
 
      rx = 8,
 
      by = 2,
 
      ax = 1,
 
      ay = 1
 
    };
 
    text_area.contentrect = {
 
      lx = 21 + hpadding,
 
      rx = 21 + hpadding,
 
      ty = 14 + vpadding,
 
      by = 14 + vpadding,
 
      wf = prefs.text_width / 100
 
    };
 
  
 
    inventory.rect = {
 
      rx = 2,
 
      y = 2,
 
      wmax = 208,
 
      wmin = 208,
 
      ty = 2,
 
      by = 2,
 
      ax = 1
 
    };
 
    inventory.contentrect = {
 
      lx = 12,
 
      rx = 16,
 
      ty = 10,
 
      by = 40
 
    };
 
    inventory.bg = {
 
      image = 'images/tower_theme/inv_bg.png',
 
      options = {
 
        mode = 6,
 
        drawmethod = 2,
 
        slice = {
 
          x = 7,
 
          y = 11,
 
          w = 194,
 
          h = 38
 
        }, 
 
        scale = true
 
      }
 
      image = function(tpx, rect)
 
        local bg = pixels.new('images/tower_theme/inv_bg.png'):scale(scale, scale, false);
 
        local icon = pixels.new('images/tower_theme/settings.png'):scale(scale, scale, false);
 
        
 
        local tbg, tbg_slice = dire_slice_9(bg, {
 
          x = 7 * scale,
 
          y = 11 * scale,
 
          w = 194 * scale,
 
          h = 38 * scale
 
        })
 
        
 
        dire_draw_9(tbg, tpx, rect, {parts=tbg_slice});
 
        
 
        dire_draw_center(icon, tpx, {x = rect.x + rect.w - 33 * scale, y = rect.y + rect.h - 35 * scale, w = 24 * scale, h = 22 * scale});
 
      end
 
    };
 
    
 
    menu.buttonrect = {
 
      wmin = 50,
 
      wmax = 50,
 
      hmin = 16,
 
      hmax = 16,
 
      by = 20,
 
      ay = 1,
 
      rx = 81,
 
      ax = 1
 
    };
 
		
 
		D {
 
			'settings_open', 
 
			'img', 
 
			get_sprite('images/tower_theme/settings.png'),
 
			'raw', 
 
			x=canvas.x + canvas.w - 35 * scale, 
 
			y=canvas.y + canvas.h - 37 * scale,
 
			click=true,
 
			z=-1,
 
      background=true
 
      xc=0,
 
      yc=0,
 
      w=24 * scale,
 
      h=22 * scale,
 
			click=true
 
		};
 
	elseif t == 'terminal' then
 
		theme.set('snd.click', '');
 
		
 
    local upshift = 0;
 
    if height / scale < 540 then
 
      upshift = 19;
 
    end;
 
    
 
    local px = pixels.new(scaled_width, scaled_height);
 
		local tiles_src = pixels.new('images/terminal/table_tiles.png');
 
    local backdrop_src = pixels.new('images/terminal/backdrop.png');
 
		
 
		local tabletop = scaled_height - 422 - upshift
 
		if tabletop < 335 - upshift then
 
			tabletop = 335 - upshift;
 
		end;
 
		
 
		dire_draw_tile(tiles_src, px, {
 
			w = scaled_width,
 
			h = 422,
 
			x = 0,
 
			y = tabletop
 
		}, {xoffset = -1, yoffxet = -1});
 

	
 
    dire_draw_tile(backdrop_src, px, {
 
			w = scaled_width,
 
			h = tabletop,
 
			x = 0,
 
			y = 0
 
		}, {xoffset = -1, yoffset = -2});
 
		
 
		diretheme.set_background('#181E37', 255, px, {mode=5});
 
		
 
		local ty
 
		if here().ticks ~= nil and here().ticks < 128 and here().graphical then
 
			ty = 72
 
		else
 
			ty = 2
 
		end;		
 

	
 
    text_area.rect = {
 
      ty = 0 - upshift,
 
      by = 189,
 
      wmin = 808,
 
      hmin = 568,
 
      wmax = 808,
 
      hmax = 568,
 
      ax = 0,
 
      ay = 1
 
    };
 
    text_area.contentrect = {
 
      wmax = 569,
 
      hmax = 390,
 
      ty = ty,
 
      ax = 0,
 
      ay = -2,
 
      dx = -16
 
    };
 
    text_area.bg = {
 
      image = 'images/terminal/bg_text.png',
 
      options = {
 
        mode = 1,
 
        scale = true
 
      }
 
    };
 
	elseif t == 'ending_outside' then
 
		diretheme.set_background('#89C6AE', 255, theme_directory .. '/background.png', {mode=2, scale=true});
 
		
 
    text_area.rect = {
 
      lx = 24,
 
      rx = 24,
 
      wmax = 600,
 
      hmax = 160,
 
      by = 24,
 
      ay = 1
 
    };
 
    text_area.contentrect = {
 
      lx = 18 + hpadding,
 
      rx = 18 + hpadding,
 
      ty = 14 + vpadding,
 
      by = 14 + vpadding,
 
      wf = prefs.text_width / 100
 
    };
 
	elseif t == 'ending_inside' then
 
		diretheme.set_background('#181E37', 255, theme_directory .. '/background.png', {mode=2});
 
		
 
    text_area.rect = {
 
      lx = 24,
 
      rx = 24,
 
      wmax = 600,
 
      hmax = 160,
 
      by = 24,
 
      ay = 1
 
    };
 
    text_area.contentrect = {
 
      lx = 18 + hpadding,
 
      rx = 18 + hpadding,
 
      ty = 14 + vpadding,
 
      by = 14 + vpadding,
 
      wf = prefs.text_width / 100
 
    };
 
  elseif t == 'credits_outside' or t == 'credits_inside' then
 
    -- text scaled on top of picture
 
    text_area.rect = {
 
      wmax = 960,
 
      hmax = 600
 
    };
 
    text_area.bg = {};
 
    text_area.align = 'center';
 
    text_area.content_rect = {
 
      wf = prefs.text_width / 100
 
    };
 
	elseif t == 'black' then    
 
		fmt.para = false;
 
		diretheme.set_background('#000000', 255);
 
		
 
		text_area.rect = {
 
      wmax = 600,
 
      hmax = 400,
 
      ax = 0,
 
      ay = 0
 
    };
 
    text_area.align = 'center';
 
	end;
 
  
 
  diretheme.set_image_area(image_area, true);
 
  diretheme.set_text_area(text_area, true);
 
  diretheme.set_inventory_area(inventory, true);
 
  
 
  diretheme.set_menu(menu, true);
 
end;
 

	
 
function start(load)
 
	dprint('start', load);
 
  last_location = here().nam;
 
	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');
 
      
 
      game:reaction(false);
 
      local r = game:display(true);
 
      game:lastdisp(r);
 
		end;
 
		
 
		if w < 640 or h < 480 then
 
			walkin('resolution_warning');
 
      
 
      game:reaction(false);
 
      local r = game:display(true);
 
      game:lastdisp(r);
 
		end;
 
	end;
 
  
 
	set_theme(std.call(here(), 'theme'));
 
	
 
  diretheme.set_theme();
 
  
 
	if load then
 
		if here().themeInit then
 
			here():themeInit();
 
		end;
 

	
 
		if here().onboot then
 
			here():onboot();
 
		end;
 
	else
 
    local words = {
 
      "biography",
 
      "algorithm",
 
      "chemistry",
 
      "discovery",
 
      "exploring",
 
      "machinery",
 
      "porcelain",
 
      "something",
 
      "wonderful"
 
    };    
 
    
 
    local maps = {
 
      {6, 1, 4, 8, 2, 3, 7, 5, 9};
 
      {1, 3, 8, 6, 2, 9, 4, 5, 7};
 
      {1, 3, 2, 5, 4, 8, 6, 7, 9};
 
      {4, 1, 7, 2, 5, 8, 3, 6, 9};
 
      {1, 9, 7, 4, 8, 5, 3, 6, 2};
 
      {2, 3, 7, 4, 5, 1, 6, 8, 9};
 
      {7, 4, 5, 8, 6, 9, 2, 1, 3};
 
      {4, 9, 6, 7, 3, 8, 2, 1, 5};
 
      {4, 5, 7, 9, 3, 2, 6, 8, 1};
 
    };
 
    
 
    local wordIndex = rnd(#words);
 
    
 
    library_word = words[wordIndex];
 
    library_book_map = maps[wordIndex];
 
    
 
    local keys = {1,2,3,4};
 
    for i = 0, 3 do
 
      local index = rnd(#keys);
 
      _('tower_key_' .. tostring(i)).value = keys[index];
 
      keys[index] = keys[#keys];
 
      keys[#keys] = nil;
 
    end;
 
    
 
    local keyholes = {125, 25, 5, 1};
 
    for i = 1, 4 do
 
      local index = rnd(#keyholes);
 
      _('keyhole_' .. tostring(i)).value = keyholes[index];
 
      keyholes[index] = keyholes[#keyholes];
 
      keyholes[#keyholes] = nil;
 
    end;
 
    
 
    keyholes = {125, 25, 5, 1};
 
    local value = 0;
 
    for i = 1, 4 do 
 
      local index = rnd(#keyholes);
 
      value = value + keyholes[index] * i;
 
      keyholes[index] = keyholes[#keyholes];
 
      keyholes[#keyholes] = nil;
 
    end;
 
    level_1_target = tostring(value);
 
    
 
    local catalysts = {
 
      'red_catalyst';
 
      'green_catalyst';
 
      'blue_catalyst';
 
      'turquoise_catalyst';
 
      'yellow_catalyst';
 
      'purple_catalyst';
 
    };
 
    
 
    local index = rnd(#catalysts);
 
    opening_catalyst = catalysts[index];
 
    catalysts[index] = catalysts[#catalysts];
 
    catalysts[#catalysts] = nil;
 
    
 
    index = rnd(#catalysts);
 
    light_catalyst = catalysts[index];
 
    catalysts[index] = catalysts[#catalysts];
 
    catalysts[#catalysts] = nil;
 
    
 
    index = rnd(#catalysts);
 
    enrichment_catalyst = catalysts[index];
 
    
 
    password1 = make_password();
 
    password2 = make_password();
 
    
 
    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
 
	end;
 
end;
 

	
 
function init()   
 
	if not prefs.graphic_scale then
 
		prefs.graphic_scale = false;
 
	end;
 
  
 
  if not prefs.cursor_scale then
 
		prefs.cursor_scale = false;
 
	end;
 
  
 
  if not prefs.text_input then
 
    prefs.text_input = true;
 
  end;
 
  
 
  if not prefs.completed then
 
		prefs.completed = 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;

Changeset was too big and was cut off... Show full diff