declare {
    distances = {
    };
    MINUTE = 60;
    STEP = 25;
}

global {
    timestamp = -STEP; -- Seconds
    widget_status = 0; -- 0 -- not done; 1 -- late; 2 -- in time
    taggart_status = 0; -- 0 -- not done; 1 -- done
    boys_status = 0; -- 0 -- not done; 1 -- done
    dinner_status = 0; -- 0 -- not done; 1 -- late at all; 2 -- late 30 minutes; 3 -- a bit late; 4 -- not late
    makeup = 0; -- 0 -- not done, 1 -- done
}

function set_distance(sp, dp, di) 
    if not distances[sp] then
        distances[sp] = {};
    end;
    distances[sp][dp] = di;

    if not distances[dp] then
        distances[dp] = {};
    end;
    distances[dp][sp] = di;
end;

set_distance('bedroom', 'workshop', 15 * MINUTE);
set_distance('bedroom', 'dining_hall', 10 * MINUTE);
set_distance('bedroom', 'guard_post', 15 * MINUTE);
set_distance('bedroom', 'west_gate', 15 * MINUTE);

set_distance('workshop', 'dining_hall', 15 * MINUTE);
set_distance('workshop', 'guard_post', 20 * MINUTE);
set_distance('workshop', 'west_gate', 20 * MINUTE);

set_distance('dining_hall', 'guard_post', 20 * MINUTE);
set_distance('dining_hall', 'west_gate', 20 * MINUTE);

set_distance('guard_post', 'west_gate', 10 * MINUTE);

ppath = std.class({
    __path_type = true;
    new = function(_, t)
        if type(t) ~= 'table' then
            std.err("Wrong path argument. Use {} as path argument.", 2)
        end
        
        local n, s, sr, ds = t[1], t[2], t[3], t[4]

        if not ds then
            s, sr, ds = n, s, sr
            n = nil
        end

        local new = {
            true_disp = s;
            src = sr;
            dst = ds;
        }

        for k, v in std.pairs(t) do
            if type(k) == 'string' then
                new[k] = v
            end
        end

        new.nam = n or new.nam

        return std.room(new)
    end;
    disp = function(s)
        local w = s.dst
        if disabled(w) or closed(w) then
            return false
        end
        if s.after ~= nil and visited(w) then
            return std.call(s, 'after')
        end
        return std.call(s, 'true_disp') .. ' (' .. tostring(math.floor(distances[s.src][s.dst] / MINUTE)) ..' ' .. translate_now('main', 'minutes') .. ')';
    end;
    onwalk = function(s, _)
        local w = s.dst
        if not disabled(w) and not closed(w) then
          timestamp = timestamp + distances[s.src][s.dst];
          walk(w)
          if not me():moved() then
            timestamp = timestamp - distances[s.src][s.dst];
          end;
        end
        return false
    end;
}, std.room);

dpath = std.class({
    __path_type = true;
    new = function(_, t)
        if type(t) ~= 'table' then
            std.err("Wrong path argument. Use {} as path argument.", 2)
        end

        local n, s, d, ds = t[1], t[2], t[3], t[4]

        if not ds then
            s, d, ds = n, s, d
            n = nil
        end

        local new = {
            true_disp = s;
            dst = ds;
            distance = d;
        }

        for k, v in std.pairs(t) do
            if type(k) == 'string' then
                new[k] = v
            end
        end

        new.nam = n or new.nam

        return std.room(new)
    end;
    disp = function(s)
        local w = s.dst
        if disabled(w) or closed(w) then
            return false
        end
        if s.after ~= nil and visited(w) then
            return std.call(s, 'after')
        end
        return std.call(s, 'true_disp') .. ' (' .. tostring(math.floor(s.distance / MINUTE)) ..' ' .. translate_now('main', 'minutes') .. ')';
    end;
    onwalk = function(s, _)
        local w = s.dst
        if not disabled(w) and not closed(w) then
          timestamp = timestamp + s.distance;
          walk(w)
          if not me():moved() then
            timestamp = timestamp - s.distance;
          end;
        end
        return false
    end;
}, std.room);

function convert_timestamp(ts)
    if ts == nil then
        ts = timestamp;
    end;

    local hours = math.floor(ts / 3600);
    local minutes = math.floor(ts / 60) - hours * 60;

    hours = hours + 6;

    if hours < 10 then
        hours = '0' .. tostring(hours);
    else
        hours = tostring(hours);
    end;

    if minutes < 10 then
        minutes = '0' .. tostring(minutes);
    else
        minutes = tostring(minutes);
    end;

    return hours .. ':' .. minutes;
end;

stat {
    nam = 'watch';
    disp = function(s)
        return convert_timestamp();
    end;
    inv = 'Мои карманные часы.';
    life = function(s)
        if not here().notime then
            timestamp = timestamp + STEP;
        end;

        if here()^'guard_post' then
            if timestamp == 5 * 60 * MINUTE then
                local taggart = lookup('#taggart')

                if taggart ~= nil then
                    remove(taggart, here());
                    _'#guard':enable();
                    
                    if taggart_status == 1 then
                      pr(translate_now("main", "taggart_leaves"));
                    else
                      pr(translate_now("main", "taggart_arrested"));
                    end;
                end;
            end;
        elseif here()^'dining_hall' then
            if timestamp >= 6 * 60 * MINUTE then
                dinner_status = 4;
                walkin('ending1');
            end;
        elseif here()^'workshop' then
            if timestamp > 180 * MINUTE and lookup('#widget', here()) then
                remove(lookup('#widget', here()), here());
                pr(translate_now("main", "widget_leaves"));
            end;
        end;
    end;
}

menu {
    nam = 'task_list';
    disp = translate('main', 'task_list');
    inv = function(s)
        if dinner_status == 0 then
            pn(translate_now('main', 'task_list_dinner_party'));
        else
            pn(fmt.st(translate_now('main', 'task_list_dinner_party')));
        end;

        if boys_status == 0 then
            pn(translate_now('main', 'task_list_trinket'));
        else
            pn(fmt.st(translate_now('main', 'task_list_trinket')));
        end;

        if widget_status == 0 then
            p(translate_now('main', 'task_list_workshop'));
            pn(translate_now('main', 'task_list_workshop_2'));
        else
            pn(fmt.st(translate_now('main', 'task_list_workshop')));
        end;

        if taggart_status == 0 then
            pn(translate_now('main', 'task_list_key'));
        else
            pn(fmt.st(translate_now('main', 'task_list_key')));
        end;
    end;
}


cutscene {
    nam = 'intro1';
    disp = translate('menu_locale', 'short_title');
    noinv = true;
    notime = true;
    decor = function(s)
      pncut(translate_now('main', 'intro_1_1_p'), translate_now('main', 'intro_1_1_f'));
      pncut(translate_now('main', 'intro_1_2_p'), translate_now('main', 'intro_1_2_f'));
      prcut(translate_now('main', 'intro_1_3_p'), '');
      p("[code walk('intro2')]");
    end;
}

cutscene {
    nam = 'intro2';
    disp = translate('main', 'yesterday_evening');
    noinv = true;
    notime = true;
    decor = function(s)
      p(translate_now('main', 'intro_2_1'));
      pncut(translate_now('main', 'intro_2_2_p'), translate_now('main', 'intro_2_2_f'));
      pncut(translate_now('main', 'intro_2_3_p'), translate_now('main', 'intro_2_3_f'));
      pncut(translate_now('main', 'intro_2_4_p'), translate_now('main', 'intro_2_4_f'));
      pncut(translate_now('main', 'intro_2_5_p'), translate_now('main', 'intro_2_5_f'));
      pncut(translate_now('main', 'intro_2_6_p'), translate_now('main', 'intro_2_6_f'));
      prcut(translate_now('main', 'continue'), "[code walk('intro3')]");
      p("");
    end;
}

cutscene {
    nam = 'intro3';
    disp = translate('main', 'yesterday_afternoon');
    noinv = true;
    notime = true;
    decor = function(s)
      pn(translate_now('main', 'intro_3_1'));
      pncut(translate_now('main', 'intro_3_2_p'), translate_now('main', 'intro_3_2_f'));
      pcut(translate_now('main', 'intro_3_3_p'), translate_now('main', 'intro_3_3_f'));
      pncut(translate_now('main', 'intro_3_4_p'), translate_now('main', 'intro_3_4_f'));
      prcut(translate_now('main', 'continue'), "[code walk('intro4')]");
    end;
}

cutscene {
    nam = 'intro4';
    disp = translate('main', 'yesterday_morning');
    noinv = true;
    notime = true;
    decor = function(s)
      pcut(translate_now('main', 'intro_4_1_p'), translate_now('main', 'intro_4_1_f'));
      pcut(translate_now('main', 'intro_4_2_p'), translate_now('main', 'intro_4_2_f'));
      pcut(translate_now('main', 'intro_4_3_p'), translate_now('main', 'intro_4_3_f'));
      pncut(translate_now('main', 'intro_4_4_p'), translate_now('main', 'intro_4_4_f'));
      prcut(translate_now('main', 'continue'), "[code walk('intro5')]");
    end;
}


cutscene {
    nam = 'intro5';
    disp = translate('main', 'yesterday_before_sleep');
    noinv = true;
    notime = true;
    decor = function(s)
      p(translate_now('main', 'intro_5_1'));
      pcut(translate_now('main', 'intro_5_2_p'), translate_now('main', 'intro_5_2_f'));
      pcut(translate_now('main', 'intro_5_3_p'), translate_now('main', 'intro_5_3_f'));
      pncut(translate_now('main', 'intro_5_4_p'), translate_now('main', 'intro_5_4_f'));
      prcut(translate_now('main', 'continue'), "[code walk('intro6')]");
    end;
}

cutscene {
    nam = 'intro6';
    disp = translate('menu_locale', 'short_title');
    noinv = true;
    notime = true;
    decor = function(s)
      pncut(translate_now('main', 'intro_6_1_p'), translate_now('main', 'intro_6_1_f'));
      pcut(translate_now('main', 'intro_6_2_p'), translate_now('main', 'intro_6_2_f'));
      pncut(translate_now('main', 'intro_6_3_p'), translate_now('main', 'intro_6_3_f'));
      pncut(translate_now('main', 'intro_6_4_p'), translate_now('main', 'intro_6_4_f'));
      pncut(translate_now('main', 'intro_6_5_p'), translate_now('main', 'intro_6_5_f'));
      prcut(translate_now('main', 'continue'), "[code walk('bedroom')]");
    end;
}

obj {
    nam = 'trinket';
    disp = translate('main', 'trinket_disp');
    inv = translate('main', 'trinket_inv');
}

obj {
    nam = 'notebook';
    disp = translate('main', 'notebook_disp');
    dsc = translate('main', 'notebook_dsc');
    tak = translate('main', 'notebook_tak');
    inv = translate('main', 'notebook_inv');
}:disable();

obj {
    nam = 'key';
    disp = translate('main', 'key_disp');
    inv = translate('main', 'key_inv');
}

room {
    nam = 'bedroom';
    disp = translate('main', 'bedroom_disp');
    dsc = translate('main', 'bedroom_dsc');
    way = {
        ppath {translate('main', 'to_workshop'), 'bedroom', 'workshop'};
        ppath {translate('main', 'to_dining_hall'), 'bedroom', 'dining_hall'};
        ppath {translate('main', 'to_guard_post'), 'bedroom', 'guard_post'};
        ppath {translate('main', 'to_west_gate'), 'bedroom', 'west_gate'};
    };
}: with {
    obj {
        state = 0;
        nam = '#bed';
        dsc = translate('main', 'bedroom_bed_dsc');
        act = function(s)
            p(translate_now('main', 'bedroom_bed_act'));
            if s.state == 0 then
                s.state = 1;
                _'notebook':enable();
                p(translate_now('main', 'bedroom_bed_act_find'));
            end;
        end;
    }:  with {
        'notebook';
    };
    obj {
        nam = '#fireplace';
        dsc =  translate('main', 'bedroom_fireplace_dsc');
        act = translate('main', 'bedroom_fireplace_act');
    };
    obj {
        nam = '#clock';
        dsc = translate('main', 'bedroom_clock_dsc');
        act = function(s)
            return translate_now('main', 'bedroom_clock_act', {time=convert_timestamp(timestamp + STEP)});
        end;
    };
    obj {
        nam = '#wardrobe';
        dsc = translate('main', 'bedroom_wardrobe_dsc');
        act = function(s)
            walkin('wardrobe');
        end;
    };
    obj {
        nam = '#table';
        dsc = translate('main', 'bedroom_table_dsc');
        act = function(s)
            return walkin('table');
        end;
    };
}

room {
    nam = 'table';
    disp = translate('main', 'table_disp');
    dsc = translate('main', 'table_dsc');
    way = {
        path {translate('common_locale', 'back'), function(s) return here():from() end; };
    }
}: with {
    obj {
        nam = '#mirror';
        dsc = translate('main', 'table_mirror_dsc');
        act = function(s)
            if makeup == 0 then
                return translate_now('main', 'table_mirror_act_1');
            else
                return translate_now('main', 'table_mirror_act_2');
            end;
        end;
    };
    obj {
        nam = '#makeup';
        act = function(s)
            if makeup == 0 then
                if have('clothes_dress') then
                    makeup = 1;
                    timestamp = timestamp + 30 * MINUTE;
                    return translate_now('main', 'table_makeup_1');
                else
                    return translate_now('main', 'table_makeup_2');
                end;
            else
                return translate_now('main', 'table_makeup_3');
            end;
        end;
    };
    obj {
        state = 0;
        nam = '#jewelbox';
        dsc = translate('main', 'table_jewelbox_dsc');
        act = function(s)
            if s.state == 0 then
                s.state = 1;
                take('trinket');
                return translate_now('main', 'table_jewelbox_act_1');
            else
                return translate_now('main', 'table_jewelbox_act_2');
            end;
        end;
    };
}

dlg {
    nam = 'wardrobe';
    disp = translate('main', 'wardrobe_disp');
    dsc = translate('main', 'wardrobe_dsc');
    phr = {
        {cond=function(s) return not have('clothes_dress') end, translate('main', 'wardrobe_phr_1'), function(s)
            set_cursor('dress');
            remove('clothes_mech', me());
            remove('clothes_travel', me());
            take('clothes_dress');
            timestamp = timestamp + 10 * MINUTE;
            walkout();
            return translate_now('main', 'wardrobe_done');
        end};
        {cond=function(s) return not have('clothes_mech') end, translate('main', 'wardrobe_phr_2'), function(s)
            set_cursor('mech');
            remove('clothes_dress', me());
            remove('clothes_travel', me());
            take('clothes_mech');
            timestamp = timestamp + 10 * MINUTE;
            walkout();
            if makeup == 1 then
                makeup = 0;
                return translate_now('main', 'wardrobe_makeup_lost');
            else
                return translate_now('main', 'wardrobe_done');
            end;
        end};
        {cond=function(s) return not have('clothes_travel') end, translate('main', 'wardrobe_phr_3'), function(s)
            set_cursor('travel');
            remove('clothes_mech', me());
            remove('clothes_dress', me());
            take('clothes_travel');
            timestamp = timestamp + 10 * MINUTE;
            walkout();
            if makeup == 1 then
                makeup = 0;
                return translate_now('main', 'wardrobe_makeup_lost');
            else
                if _'clothes_travel'.state == 0 then
                    return translate_now('main', 'wardrobe_done') .. ' ' .. translate_now('main', 'wardrobe_done_pocket');
                else
                    return translate_now('main', 'wardrobe_done');
                end;
            end;
        end};
        {cond=function(s) return have('clothes_dress') or have('clothes_mech') or have('clothes_travel') end, translate('main', 'wardrobe_phr_4'), function(s)
            walkout();
            return translate_now('main', 'wardrobe_left');
        end;};
    };
}

obj {
    nam = 'clothes_dress';
    disp = translate('main', 'clothes_dress_disp');
    inv = translate('main', 'clothes_dress_inv');
}

obj {
    nam = 'clothes_mech';
    disp = translate('main', 'clothes_mech_disp');
    inv = translate('main', 'clothes_mech_inv');
}

obj {
    state = 0;
    nam = 'clothes_travel';
    disp = translate('main', 'clothes_travel_disp');
    inv = function(s)
        pr(translate_now('main', 'clothes_travel_inv'));
        if s.state == 0 then
            s.state = 1;
            pr('^' .. translate_now('main', 'clothes_travel_inv_key'));
            take('key');
        end;
    end;
}

room {
    nam = 'workshop';
    disp = translate('main', 'workshop_disp');
    onenter = function(s)
        if have('clothes_dress', me()) then
            pr(translate_now('main', 'workshop_on_enter_dress'));
            return false;
        end;
        if have('clothes_travel', me()) then
            pr(translate_now('main', 'workshop_on_enter_travel'));
            return false;
        end;
        if not have('clothes_travel', me()) and not have('clothes_mech', me()) then
            pr(translate_now('main', 'on_enter_clothes'));
            return false;
        end;
        if (timestamp > 180 * MINUTE) and lookup('#widget', s) then
            remove(lookup('#widget', s), s);
            pr(translate_now('main', 'workshop_on_enter_late'));
        end;
    end;
    dsc = translate('main', 'workshop_dsc');
    way = {
        ppath {translate('main', 'to_bedroom'), 'workshop', 'bedroom'};
        ppath {translate('main', 'to_dining_hall'), 'workshop', 'dining_hall'};
        ppath {translate('main', 'to_guard_post'), 'workshop', 'guard_post'};
        ppath {translate('main', 'to_west_gate'), 'workshop', 'west_gate'};
    };
}:with {
    obj {
        nam = '#workbenches';
        dsc = translate('main', 'workshop_workbenches_dsc');
        act = translate('main', 'workshop_workbenches_act');
    }: with {
        obj {
            nam = '#workers';
            dsc = translate('main', 'workshop_workers_dsc');
            act = translate('main', 'workshop_workers_act');
        };
        obj {
            nam = '#widget';
            dsc = translate('main', 'workshop_widget_dsc');
            act = function(s)
                walkin('widget_dlg');
            end;
        }
    };
    obj {
        nam = '#machinery';
        dsc = translate('main', 'workshop_machinery_dsc');
        act = translate('main', 'workshop_machinery_act');
    };
}

dlg {
    nam = 'widget_dlg';
    disp = translate('main', 'widget_dlg_disp');
    noinv = true;
    notime = true;
    enter =  translate('main', 'widget_dlg_enter');
    phr = {
        {translate('main', 'widget_dlg_phr_1'), function(s)
            if timestamp >= 150 * MINUTE then
                walkout();
                return translate_now('main', 'widget_dlg_phr_1_r1');
            else
                return translate_now('main', 'widget_dlg_phr_1_r2');
            end;
        end,
            {cond=function(s) return have('notebook', me()); end, translate('main', 'widget_dlg_phr_2'), function(s) 
                remove('notebook', me());
                walk('widgets_lesson');
            end};
            {translate('main', 'widget_dlg_phr_3'), function(s) walkout(); end};
        };
        {translate('main', 'widget_dlg_phr_4'), function(s) walkout(); end};
    };
}

cutscene {
    nam = 'widgets_lesson';
    disp = translate('main', 'workshop_disp');
    noinv = true;
    notime = true;
    decor = function(s)
        local intime = timestamp < 60 * MINUTE;
        local duration = 120 * MINUTE;

        if timestamp < 30 * MINUTE then
          timestamp = 30 * MINUTE;
        end;

        if intime then
          widget_status = 2;
          pn(translate_now('main', 'widgets_lesson_1a'));
          pncut(translate_now('main', 'widgets_lesson_2a_p'), translate_now('main', 'widgets_lesson_2a_f'));
        else
          widget_status = 1;
          pn(translate_now('main', 'widgets_lesson_1b'));
          pncut(translate_now('main', 'widgets_lesson_2b_p'), translate_now('main', 'widgets_lesson_2b_f'));
        end;

        pncut(translate_now('main', 'widgets_lesson_3_p'), translate_now('main', 'widgets_lesson_3_f'));
        pcut(translate_now('main', 'widgets_lesson_4_p'), translate_now('main', 'widgets_lesson_4_f'));
        pcut(translate_now('main', 'widgets_lesson_5_p'), translate_now('main', 'widgets_lesson_5_f'));
        pncut(translate_now('main', 'widgets_lesson_6_p'), translate_now('main', 'widgets_lesson_6_f'));
        pncut(translate_now('main', 'widgets_lesson_7_p'), translate_now('main', 'widgets_lesson_7_f'));
        pncut(translate_now('main', 'widgets_lesson_8_p'), translate_now('main', 'widgets_lesson_8_f'));
        p(translate_now('main', 'widgets_lesson_9'));
        
        timestamp = timestamp + duration;
        remove(lookup('#widget', 'workshop'), 'workshop');
        
        if intime then
          p(translate_now('main', 'widgets_lesson_10a'));
          pncut(translate_now('main', 'widgets_lesson_11a_p'), translate_now('main', 'widgets_lesson_11a_f'));
          pncut(translate_now('main', 'widgets_lesson_12a_p'), translate_now('main', 'widgets_lesson_12a_f'));
      else
          p(translate_now('main', 'widgets_lesson_10b'));
          pncut(translate_now('main', 'widgets_lesson_11b_p'), translate_now('main', 'widgets_lesson_11b_f'));
          pncut(translate_now('main', 'widgets_lesson_12b_p'), translate_now('main', 'widgets_lesson_12b_f'));
        end;

        prcut(translate_now('main', 'continue'), '[code walk("workshop")]');
    end;
}

room {
    nam = 'dining_hall';
    disp = translate('main', 'dining_hall_disp');
    dsc = translate('main', 'dining_hall_dsc');
    onenter = function(s)
        if have('clothes_travel', me()) then
            pr(translate_now('main', 'dining_hall_on_enter_travel'));
            return false;
        end;
        if have('clothes_mech', me()) then
            pr(translate_now('main', 'dining_hall_on_enter_mech'));
            return false;
        end;
        if makeup == 0 then
            pr(translate_now('main', 'dining_hall_on_enter_makeup'));
            return false;
        end;
        if not have('clothes_dress', me()) and not have('clothes_mech', me()) then
            pr(translate_now('main', 'on_enter_clothes'));
            return false;
        end;
    end;
    enter = function(s)
        if timestamp > 6 * 60 * MINUTE then
            if timestamp > 8 * 60 * MINUTE then
                dinner_status = 1;
            elseif timestamp > (6 * 60 + 30) * MINUTE then
                dinner_status = 2;
            else
                dinner_status = 3;
            end;
            walkin('ending1');
        end;
    end;
    way = {
        ppath {translate('main', 'to_bedroom'), 'dining_hall', 'bedroom'};
        ppath {translate('main', 'to_workshop'), 'dining_hall', 'workshop'};
        ppath {translate('main', 'to_guard_post'), 'dining_hall', 'guard_post'};
        ppath {translate('main', 'to_west_gate'), 'dining_hall', 'west_gate'};
    };
}: with {
    obj {
        nam = '#tables';
        dsc = translate('main', 'dining_hall_tables_dsc');
        act = translate('main', 'dining_hall_tables_act');
    };
    obj {
        nam = '#servants';
        dsc = translate('main', 'dining_hall_servants_dsc');
        act = translate('main', 'dining_hall_servants_act');
    };
    obj {
        nam = '#chandeliers';
        dsc = translate('main', 'dining_hall_chandeliers_dsc');
        act = translate('main', 'dining_hall_chandeliers_act');
    };
    obj {
        nam = '#wait';
        dsc = translate('main', 'dining_hall_wait_dsc');
        act = function(s)
            dinner_status = 4;
            walkin('ending1');
        end;
    };
}

room {
    nam = 'guard_post';
    disp = translate('main', 'guard_post_disp');
    onenter = function(s)
        if have('clothes_dress', me()) or have('clothes_mech', me()) then
            pr(translate_now('main', 'on_enter_recognised'));
            return false;
        end;
        if not have('clothes_travel') then
            pr(translate_now('main', 'on_enter_clothes'));
            return false;
        end;
        
        if timestamp > 5 * 60 * MINUTE then
            local taggart = lookup('#taggart', 'guard_post');
            if taggart ~= nil then
                remove(taggart, 'guard_post');
                lookup('#guard', 'guard_post'):enable();
                if taggart_status == 0 then
                  pr(translate_now('main', 'guard_post_on_enter_late'));
                end;
            end;
        end;
    end;
    enter = function(s)
        if taggart_status == 0 and timestamp <= 5 * 60 * MINUTE then
            walkin('taggart_dlg');
        end;
    end;
    dsc = translate('main', 'guard_post_dsc');
    way = {
        ppath {translate('main', 'to_bedroom'), 'guard_post', 'bedroom'};
        ppath {translate('main', 'to_workshop'), 'guard_post', 'workshop'};
        ppath {translate('main', 'to_dining_hall'), 'guard_post', 'dining_hall'};
        ppath {translate('main', 'to_west_gate'), 'guard_post', 'west_gate'};
    };
}: with {
    obj {
        nam = '#door';
        dsc = translate('main', 'guard_post_door_dsc');
        act = translate('main', 'guard_post_door_act');
    };
    obj {
        nam = '#table';
        dsc = translate('main', 'guard_post_table_dsc');
        act = translate('main', 'guard_post_table_act');
    }: with {
        obj {
            nam = '#chair';
            dsc = translate('main', 'guard_post_chair_dsc');
            act = translate('main', 'guard_post_chair_act');
        }: with {
            obj {
                nam = '#taggart';
                dsc = translate('main', 'guard_post_taggart_dsc');
                act = function(s)
                    if taggart_status == 0 then
                        walkin('taggart_dlg');
                    else
                        return translate_now('main', 'guard_post_taggart_act')
                    end;
                end;
            };
            obj {
                nam = '#guard';
                dsc = translate('main', 'guard_post_guard_dsc');
                act = translate('main', 'guard_post_guard_act');
            }:disable();
        }
    }
}

dlg {
    nam = 'taggart_dlg';
    disp = translate('main', 'taggart_dlg_disp');
    noinv = true;
    notime = true;
    enter = translate('main', 'taggart_dlg_enter');
    phr = {
        {cond=function(s) return have('key'); end, translate('main', 'taggart_dlg_phr_1'), function(s)
            taggart_status = 1;
            remove('key');
            walkout();
            return translate_now('main', 'taggart_dlg_phr_1_r');
        end};
        {translate('main', 'taggart_dlg_phr_2'), function(s)
            walkout();
            return translate_now('main', 'taggart_dlg_phr_2_r');
        end};
    };
}

room {
    nam = 'west_gate';
    disp = translate('main', 'west_gate_disp');
    dsc = translate('main', 'west_gate_dsc');
    onenter = function(s)
        if have('clothes_dress', me()) or have('clothes_mech', me()) then
            pr(translate_now('main', 'on_enter_recognised'));
            return false;
        end;
        if not have('clothes_travel') then
            pr(translate_now('main', 'on_enter_clothes'));
            return false;
        end;
    end;
    way = {
        ppath {translate('main', 'to_bedroom'), 'west_gate', 'bedroom'};
        ppath {translate('main', 'to_workshop'), 'west_gate', 'workshop'};
        ppath {translate('main', 'to_dining_hall'), 'west_gate', 'dining_hall'};
        ppath {translate('main', 'to_guard_post'), 'west_gate', 'guard_post'};
        path {translate('main', 'to_outside'), 'west_gate_outside'};
    };
}: with {
    obj {
        nam = '#guards';
        dsc = translate('main', 'west_gate_guards_dsc');
        act = translate('main', 'west_gate_guards_act');
    };
    obj {
        nam = '#gate';
        dsc = translate('main', 'west_gate_gate_dsc');
        act = translate('main', 'west_gate_gate_act');
    };
    obj {
        nam = '#servants';
        dsc = translate('main', 'west_gate_servants_dsc');
        act = translate('main', 'west_gate_servants_act');
    };
    obj {
        nam = '#boxes';
        dsc = translate('main', 'west_gate_boxes_dsc');
        act = translate('main', 'west_gate_boxes_act');
    };
}

room {
    nam = 'west_gate_outside';
    disp = translate('main', 'west_gate_outside_disp');
    dsc = translate('main', 'west_gate_outside_dsc');
    way = {
        path {translate('main', 'to_palace'), 'west_gate'};
        dpath {translate('main', 'to_forest'), 40 * MINUTE, 'forest'};
    }
}: with {
    obj {
        nam = '#gate';
        dsc = translate('main', 'west_gate_gate_dsc');
        act = translate('main', 'west_gate_outside_gate_act');
    };
    obj {
        nam = '#servants';
        dsc = translate('main', 'west_gate_servants_dsc');
        act = translate('main', 'west_gate_servants_act');
    };
    obj {
        nam = '#guards';
        dsc = translate('main', 'west_gate_guards_dsc');
        act = translate('main', 'west_gate_outside_guards_act');
    };
}

room {
    nam = 'forest';
    disp = translate('main', 'forest_disp');
    dsc = translate('main', 'forest_dsc');
    way = {
        dpath {translate('main', 'to_palace'), 40 * MINUTE, 'west_gate_outside'};
    }
}: with {
    obj {
        nam = "#trees";
        dsc = translate('main', 'forest_trees_dsc');
        act = translate('main', 'forest_trees_act');
    };
    obj {
        nam = "#forest";
        act = translate('main', 'forest_forest_act');
    };
    obj {
        nam = '#grass';
        dsc = translate('main', 'forest_grass_dsc');
        act = translate('main', 'forest_grass_act');
    };
    obj {
        nam = '#boys';
        dsc = translate('main', 'forest_boys_dsc');
        act = translate('main', 'forest_boys_act');
    };
    obj {
        nam = '#thoughts';
        act = translate('main', 'forest_thoughts_act');
    };
    obj {
        nam = '#fred_and_will';
        dsc = translate('main', 'forest_fred_and_will_dsc');
        act = function(s)
            if _('boys_dlg').state == 0 then
                walkin('boys_dlg');
            else
                pr(translate_now('main', 'forest_fred_and_will_act'));
            end;
        end;
    };
}

dlg {
    state = 0;
    nam = 'boys_dlg';
    noinv = true;
    notime = true;
    disp = translate('main', 'boys_dlg_disp');
    enter = translate('main', 'boys_dlg_enter');
    phr = {
        {translate('main', 'boys_dlg_phr_1'), function(s)
            if here().state == 0 then
                here().state = 1;
                return translate_now('main', 'boys_dlg_phr_1_r1');
            else
                return translate_now('main', 'boys_dlg_phr_1_r2');
            end;
        end;
        };
        {translate('main', 'boys_dlg_phr_2'), function(s)
            if here().state == 0 then
                here().state = 1;
                return translate_now('main', 'boys_dlg_phr_2_r1');
            else
                return translate_now('main', 'boys_dlg_phr_2_r2');
            end;
        end};
        {cond=function(s) return have('trinket') end, translate('main', 'boys_dlg_phr_3'), function(s)
            remove('trinket', me());
            boys_status = 1;
            if here().state == 0 then
                here().state = 1;
                return translate_now('main', 'boys_dlg_phr_3_r1');
            else
                return translate_now('main', 'boys_dlg_phr_3_r2');
            end;
        end, 
            {translate('main', 'boys_dlg_phr_4'), function(s)
                remove(lookup('#fred_and_will', 'forest'), 'forest');
                walkout();
                return translate_now('main', 'boys_dlg_phr_4_r');
            end}
        };
    };
}

cutscene {
    nam = 'ending1';
    disp = translate('menu_locale', 'short_title');
    noinv = true;
    notime = true;
    decor = function(s)
      if dinner_status == 1 then
        p(translate_now('main', 'ending_1_very_late_1_1'));
        pncut(translate_now('main', 'ending_1_very_late_1_2_p'), translate_now('main', 'ending_1_very_late_1_2_f'));
        pncut(translate_now('main', 'ending_1_very_late_2_p'), translate_now('main', 'ending_1_very_late_2_f'));
        pncut(translate_now('main', 'ending_1_very_late_3_p'), translate_now('main', 'ending_1_very_late_3_f') .. ' ' .. translate_now('main', 'ending_1_father_angry'));
        pcut(translate_now('main', 'ending_1_punishment_1_p'), translate_now('main', 'ending_1_punishment_1_f'));
        pcut(translate_now('main', 'ending_1_punishment_2_p'), translate_now('main', 'ending_1_punishment_2_f'));
        pcut(translate_now('main', 'ending_1_punishment_3_p'), translate_now('main', 'ending_1_punishment_3_f'));
        pcut(translate_now('main', 'ending_1_punishment_4_p'), translate_now('main', 'ending_1_punishment_4_f') .. ' ' .. translate_now('main', 'ending_1_very_late_punishment'));
        pcut(translate_now('main', 'ending_1_punishment_5_p'), translate_now('main', 'ending_1_punishment_5_f'));
        pcut(translate_now('main', 'ending_1_punishment_6_p'), translate_now('main', 'ending_1_punishment_6_f'));
        pcut(translate_now('main', 'ending_1_punishment_7_p'), translate_now('main', 'ending_1_punishment_7_f'));
        pcut(translate_now('main', 'ending_1_punishment_8_p'), translate_now('main', 'ending_1_punishment_8_f'));
        pncut(translate_now('main', 'ending_1_punishment_9_p'), translate_now('main', 'ending_1_punishment_9_f'));
      elseif dinner_status == 2 then
        pcut(translate_now('main', 'ending_1_late_1_p'), translate_now('main', 'ending_1_late_1_f'));
        pcut(translate_now('main', 'ending_1_late_2_p'), translate_now('main', 'ending_1_late_2_f'));
        pcut(translate_now('main', 'ending_1_late_3_p'), translate_now('main', 'ending_1_late_3_f'));
        pncut(translate_now('main', 'ending_1_late_4_p'), translate_now('main', 'ending_1_late_4_f'));
        pcut(translate_now('main', 'ending_1_late_5_p'), translate_now('main', 'ending_1_late_5_f'));
        pncut(translate_now('main', 'ending_1_late_6_p'), translate_now('main', 'ending_1_late_6_f')  .. ' ' .. translate_now('main', 'ending_1_father_angry'));
        pcut(translate_now('main', 'ending_1_punishment_1_p'), translate_now('main', 'ending_1_punishment_1_f'));
        pcut(translate_now('main', 'ending_1_punishment_2_p'), translate_now('main', 'ending_1_punishment_2_f'));
        pcut(translate_now('main', 'ending_1_punishment_3_p'), translate_now('main', 'ending_1_punishment_3_f'));
        pcut(translate_now('main', 'ending_1_punishment_4_p'), translate_now('main', 'ending_1_punishment_4_f') .. ' ' .. translate_now('main', 'ending_1_late_punishment'));
        pcut(translate_now('main', 'ending_1_punishment_5_p'), translate_now('main', 'ending_1_punishment_5_f'));
        pcut(translate_now('main', 'ending_1_punishment_6_p'), translate_now('main', 'ending_1_punishment_6_f'));
        pcut(translate_now('main', 'ending_1_punishment_7_p'), translate_now('main', 'ending_1_punishment_7_f'));
        pcut(translate_now('main', 'ending_1_punishment_8_p'), translate_now('main', 'ending_1_punishment_8_f'));
        pncut(translate_now('main', 'ending_1_punishment_9_p'), translate_now('main', 'ending_1_punishment_9_f'));
      elseif dinner_status == 3 then
        p(translate_now('main', 'ending_1_little_late_1_1')); 
        pcut(translate_now('main', 'ending_1_little_late_1_2_p'), translate_now('main', 'ending_1_little_late_1_2_f'));
        pcut(translate_now('main', 'ending_1_little_late_2_p'), translate_now('main', 'ending_1_little_late_2_f'));
        pcut(translate_now('main', 'ending_1_little_late_3_p'), translate_now('main', 'ending_1_little_late_3_f'));
        pncut(translate_now('main', 'ending_1_little_late_4_p'), translate_now('main', 'ending_1_little_late_4_f'));
        pcut(translate_now('main', 'ending_1_little_late_5_p'), translate_now('main', 'ending_1_little_late_5_f'));
        pcut(translate_now('main', 'ending_1_little_late_6_p'), translate_now('main', 'ending_1_little_late_6_f'));
        pcut(translate_now('main', 'ending_1_little_late_7_p'), translate_now('main', 'ending_1_little_late_7_f'));
        pncut(translate_now('main', 'ending_1_little_late_8_p'), translate_now('main', 'ending_1_little_late_8_f'));
      elseif dinner_status == 4 then
        pcut(translate_now('main', 'ending_1_intime_1_p'), translate_now('main', 'ending_1_intime_1_f'));
        pcut(translate_now('main', 'ending_1_intime_2_p'), translate_now('main', 'ending_1_intime_2_f'));
        pcut(translate_now('main', 'ending_1_intime_3_p'), translate_now('main', 'ending_1_intime_3_f')); 
        pcut(translate_now('main', 'ending_1_intime_4_p'), translate_now('main', 'ending_1_intime_4_f'));
        pcut(translate_now('main', 'ending_1_intime_5_p'), translate_now('main', 'ending_1_intime_5_f'));
        pcut(translate_now('main', 'ending_1_intime_6_p'), translate_now('main', 'ending_1_intime_6_f'));
        pncut(translate_now('main', 'ending_1_intime_7_p'),translate_now('main', 'ending_1_intime_7_f'));
      end;
      
      prcut('^' .. translate_now('main', 'continue'), "[code walk('ending2')]");
    end;
}

cutscene {
    nam = 'ending2';
    disp = translate('menu_locale', 'short_title');
    noinv = true;
    notime = true;
    decor = function(s)
      if widget_status == 0 then
        if dinner_status < 3 then
          p(translate_now('main', 'ending_2_any_late_0'));
          pncut(translate_now('main', 'ending_2_any_late_1_p'), translate_now('main', 'ending_2_any_late_1_f'));
          p(translate_now('main', 'ending_2_missed_late_1_f'));
          pncut(translate_now('main', 'ending_2_missed_late_2_p'), translate_now('main', 'ending_2_missed_late_2_f'));
          pncut(translate_now('main', 'ending_2_missed_late_3_p'), translate_now('main', 'ending_2_missed_late_3_f'));
        else
          p(translate_now('main', 'ending_2_any_intime_0'));
          pcut(translate_now('main', 'ending_2_any_intime_1_p'), translate_now('main', 'ending_2_any_intime_1_f'));
          pcut(translate_now('main', 'ending_2_any_intime_2_p'), translate_now('main', 'ending_2_any_intime_2_f'));
          pcut(translate_now('main', 'ending_2_any_intime_3_p'), translate_now('main', 'ending_2_any_intime_3_f'));
          p(translate_now('main', 'ending_2_missed_intime_3_f'));
          pncut(translate_now('main', 'ending_2_missed_intime_4_p'), translate_now('main', 'ending_2_missed_intime_4_f'));
          pncut(translate_now('main', 'ending_2_missed_intime_5_p'), translate_now('main', 'ending_2_missed_intime_5_f'));
        end;
      elseif widget_status == 1 then
        if dinner_status < 3 then
          p(translate_now('main', 'ending_2_any_late_0'));
          pncut(translate_now('main', 'ending_2_any_late_1_p'), translate_now('main', 'ending_2_any_late_1_f'));
          p(translate_now('main', 'ending_2_late_late_1_f'));
          pncut(translate_now('main', 'ending_2_late_late_2_p'), translate_now('main', 'ending_2_late_late_2_f'));
          pncut(translate_now('main', 'ending_2_late_late_3_p'), translate_now('main', 'ending_2_late_late_3_f'));
        else
          p(translate_now('main', 'ending_2_any_intime_0'));
          pcut(translate_now('main', 'ending_2_any_intime_1_p'), translate_now('main', 'ending_2_any_intime_1_f'));
          pcut(translate_now('main', 'ending_2_any_intime_2_p'), translate_now('main', 'ending_2_any_intime_2_f'));
          pcut(translate_now('main', 'ending_2_any_intime_3_p'), translate_now('main', 'ending_2_any_intime_3_f'));
          p(translate_now('main', 'ending_2_late_intime_3_f'));
          
          pcut(translate_now('main', 'ending_2_late_intime_4_p'), translate_now('main', 'ending_2_late_intime_4_f'));
          pcut(translate_now('main', 'ending_2_late_intime_5_p'), translate_now('main', 'ending_2_late_intime_5_f'));
          pncut(translate_now('main', 'ending_2_late_intime_6_p'), translate_now('main', 'ending_2_late_intime_6_f'));
        end;
      elseif widget_status == 2 then
        if dinner_status < 3 then
          p(translate_now('main', 'ending_2_any_late_0'));
          pncut(translate_now('main', 'ending_2_any_late_1_p'), translate_now('main', 'ending_2_any_late_1_f'));
          p(translate_now('main', 'ending_2_intime_late_1_f'));
          
          pncut(translate_now('main', 'ending_2_intime_late_2_p'), translate_now('main', 'ending_2_intime_late_2_f'));
          pcut(translate_now('main', 'ending_2_intime_late_3_p'), translate_now('main', 'ending_2_intime_late_3_f'));
          pncut(translate_now('main', 'ending_2_intime_late_4_p'), translate_now('main', 'ending_2_intime_late_4_f'));
        else
          p(translate_now('main', 'ending_2_any_intime_0'));
          pcut(translate_now('main', 'ending_2_any_intime_1_p'), translate_now('main', 'ending_2_any_intime_1_f'));
          pcut(translate_now('main', 'ending_2_any_intime_2_p'), translate_now('main', 'ending_2_any_intime_2_f'));
          pcut(translate_now('main', 'ending_2_any_intime_3_p'), translate_now('main', 'ending_2_any_intime_3_f'));
          p(translate_now('main', 'ending_2_intime_intime_3_f'));
  
          pncut(translate_now('main', 'ending_2_intime_intime_4_p'), translate_now('main', 'ending_2_intime_intime_4_f'));
          pncut(translate_now('main', 'ending_2_intime_intime_5_p'), translate_now('main', 'ending_2_intime_intime_5_f'));
        end;
      end;

      prcut('^' .. translate_now('main', 'continue'), "[code walk('ending3')]");
    end;
}

cutscene {
    nam = 'ending3';
    disp = translate('menu_locale', 'short_title');
    noinv = true;
    notime = true;
    decor = function(s)
        if taggart_status == 0 then
          p(translate_now('main', 'ending_3_late_0'));
          pcut(translate_now('main', 'ending_3_late_1_p'), translate_now('main', 'ending_3_late_1_f'));
          pcut(translate_now('main', 'ending_3_late_2_p'), translate_now('main', 'ending_3_late_2_f'));
          pcut(translate_now('main', 'ending_3_late_3_p'), translate_now('main', 'ending_3_late_3_f'));
          pcut(translate_now('main', 'ending_3_late_4_p'), translate_now('main', 'ending_3_late_4_f'));
          pcut(translate_now('main', 'ending_3_late_5_p'), translate_now('main', 'ending_3_late_5_f'));
          pcut(translate_now('main', 'ending_3_late_6_p'), translate_now('main', 'ending_3_late_6_f'));
          pcut(translate_now('main', 'ending_3_late_7_p'), translate_now('main', 'ending_3_late_7_f'));
          pcut(translate_now('main', 'ending_3_late_8_p'), translate_now('main', 'ending_3_late_8_f'));
          pncut(translate_now('main', 'ending_3_late_9_p'), translate_now('main', 'ending_3_late_9_f'));
        elseif taggart_status == 1 then
          if dinner_status < 3 then
            p(translate_now('main', 'ending_3_intime_late_0'));
            pncut(translate_now('main', 'ending_3_intime_late_1_p'), translate_now('main', 'ending_3_intime_late_1_f'));
            pncut(translate_now('main', 'ending_3_intime_late_2_p'), translate_now('main', 'ending_3_intime_late_2_f'));
          else
            p(translate_now('main', 'ending_3_intime_intime_0'));
            pcut(translate_now('main', 'ending_3_intime_intime_1_p'), translate_now('main', 'ending_3_intime_intime_1_f'));
            pncut(translate_now('main', 'ending_3_intime_intime_2_p'), translate_now('main', 'ending_3_intime_intime_2_f'));
          end;
        end;

        prcut('^' .. translate_now('main', 'continue'), "[code walk('ending4')]");
    end;
}

cutscene {
    show_menu = false;
    nam = 'ending4';
    disp = translate('menu_locale', 'short_title');
    noinv = true;
    notime = true;
    decor = function(s)
        if boys_status == 0 then
            if taggart_status == 0 then
                p(translate_now('main', 'ending_4_no_taggart_0'));
                pcut(translate_now('main', 'ending_4_no_taggart_1_p'), translate_now('main', 'ending_4_no_taggart_1_f'));
                pcut(translate_now('main', 'ending_4_no_taggart_2_p'), translate_now('main', 'ending_4_no_taggart_2_f'));
                pn(translate_now('main', 'ending_4_missed_no_taggart_3_f'));
            elseif dinner_status < 3 then
                pcut(translate_now('main', 'ending_4_missed_dinner_late_1_p'), translate_now('main', 'ending_4_missed_dinner_late_1_f'));
                pcut(translate_now('main', 'ending_4_missed_dinner_late_2_p'), translate_now('main', 'ending_4_missed_dinner_late_2_f'));
                p(translate_now('main', 'ending_4_missed_2_f'));
                pncut(translate_now('main', 'ending_4_missed_3_p'), translate_now('main', 'ending_4_missed_3_f'));
            else
                p(translate_now('main', 'ending_4_missed_dinner_intime_0'));
                pcut(translate_now('main', 'ending_4_missed_dinner_intime_1_p'), translate_now('main', 'ending_4_missed_dinner_intime_1_f'));
                pcut(translate_now('main', 'ending_4_missed_dinner_intime_2_p'), translate_now('main', 'ending_4_missed_dinner_intime_2_f'));
                p(translate_now('main', 'ending_4_missed_2_f'));
                pncut(translate_now('main', 'ending_4_missed_3_p'), translate_now('main', 'ending_4_missed_3_f'));
            end;
        elseif boys_status == 1 then
            if taggart_status == 0 then
                p(translate_now('main', 'ending_4_no_taggart_0'));
                pcut(translate_now('main', 'ending_4_no_taggart_1_p'), translate_now('main', 'ending_4_no_taggart_1_f'));
                pcut(translate_now('main', 'ending_4_no_taggart_2_p'), translate_now('main', 'ending_4_no_taggart_2_f'));
                pcut(translate_now('main', 'ending_4_done_no_taggart_3_p'), translate_now('main', 'ending_4_done_no_taggart_3_f'));
                pcut(translate_now('main', 'ending_4_done_no_taggart_4_p'), translate_now('main', 'ending_4_done_no_taggart_4_f'));
                pcut(translate_now('main', 'ending_4_done_no_taggart_5_p'), translate_now('main', 'ending_4_done_no_taggart_5_f'));
                pncut(translate_now('main', 'ending_4_done_no_taggart_6_p'), translate_now('main', 'ending_4_done_no_taggart_6_f'));
            elseif dinner_status < 3 then
                pcut(translate_now('main', 'ending_4_done_dinner_late_1_p'), translate_now('main', 'ending_4_done_dinner_late_1_f'));
                pcut(translate_now('main', 'ending_4_done_dinner_late_2_p'), translate_now('main', 'ending_4_done_dinner_late_2_f'));
                pcut(translate_now('main', 'ending_4_done_dinner_late_3_p'), translate_now('main', 'ending_4_done_dinner_late_3_f'));
                pcut(translate_now('main', 'ending_4_done_dinner_late_4_p'), translate_now('main', 'ending_4_done_dinner_late_4_f'));
                pcut(translate_now('main', 'ending_4_done_dinner_late_5_p'), translate_now('main', 'ending_4_done_dinner_late_5_f'));
                pcut(translate_now('main', 'ending_4_done_common_1_p'), translate_now('main', 'ending_4_done_common_1_f'));
                pncut(translate_now('main', 'ending_4_done_common_2_p'), translate_now('main', 'ending_4_done_common_2_f'));
            else
                p(translate_now('main', 'ending_4_done_dinner_intime_0'));
                pcut(translate_now('main', 'ending_4_done_dinner_intime_1_p'), translate_now('main', 'ending_4_done_dinner_intime_1_f'));
                pcut(translate_now('main', 'ending_4_done_dinner_intime_2_p'), translate_now('main', 'ending_4_done_dinner_intime_2_f'));
                pcut(translate_now('main', 'ending_4_done_dinner_intime_3_p'), translate_now('main', 'ending_4_done_dinner_intime_3_f'));
                pcut(translate_now('main', 'ending_4_done_common_1_p'), translate_now('main', 'ending_4_done_common_1_f'));
                pncut(translate_now('main', 'ending_4_done_common_2_p'), translate_now('main', 'ending_4_done_common_2_f'));
            end;
        end;

        pn('[code here().show_menu = true]');
        
        for i = 1, 21 do
          prcut(translate_now('main', 'the_end_' .. tostring(i)), '')
        end;
        pr(translate_now('main', 'the_end_22'))
    end;
    after_decor = function(s)
      if s.show_menu then
        return '^^{#reset|' .. translate_now("main", 'main_menu') .. '}';
      end;
    end;
}: with {
  obj {
    nam = '#reset';
    act = function(s)
      music_player:reset();
      std.gamefile('main3.lua', true);
      return;
    end;
  };
}
