local mod_name = minetest.get_current_modname()
local mod_path = minetest.get_modpath(mod_name)

local function sch(name)
    return (mod_path .. "/schematics/" .. name .. ".mts")
end

local level = 96

local l96_pattern = {}

local function l96_pattern_add(def)
    for i=1, def.prevalence or 1 do
        l96_pattern[#l96_pattern+1] = def.pattern
    end
end
l96_pattern_add({
    prevalence = 9,
    pattern = {
        {"SW","SS","SS","SE","TV"},
        {"WW","OO","OO","EE","TV"},
        {"WW","ST","OO","EE","TV"},
        {"NW","NN","NN","NE","TV"},
        {"TH","TH","TH","TH","TX"},
    },
})
l96_pattern_add({
    prevalence = 6,
    pattern = {
        {"SW","SS","SS","SE","TV"},
        {"WW","ST","OO","NE","TV"},
        {"WY","OO","EE","PP","TV"},
        {"NW","NN","NE","PP","TV"},
        {"TH","TH","TH","TH","TX"},
    },
})
l96_pattern_add({
    prevalence = 1,
    pattern = {
        {"SW","SE","PP","PP","TV"},
        {"WY","EE","PP","PP","TV"},
        {"WW","EE","PP","PP","TV"},
        {"NW","NE","PP","PP","TV"},
        {"TH","TH","TH","TH","TX"},
    },
})
l96_pattern_add({
    prevalence = 1,
    pattern = {
        {"PP","PP","PP","SW","SE"},
        {"SW","SE","PP","NW","NE"},
        {"WY","EE","PP","PP","PP"},
        {"NW","NE","PP","PP","PP"},
        {"TH","TH","TH","TH","TX"},
    },
})
l96_pattern_add({
    prevalence = 2,
    pattern = {
        {"SW","SS","SS","SE","TV"},
        {"WW","OO","OO","EE","TV"},
        {"WW","OO","ST","EE","TV"},
        {"NW","NN","OO","EE","TV"},
        {"PP","PP","NW","NE","TX"},
    },
})
l96_pattern_add({
    prevalence = 3,
    pattern = {
        {"PP","PP","PP","PP","TV"},
        {"PP","PP","PP","PP","TV"},
        {"PP","PP","PP","PP","TV"},
        {"PP","PP","PP","PP","TV"},
        {"TH","TH","TH","TH","TX"},
    },
})

local length = 5
local width = 5
local function l96_glitchy_version(x, z, perlin)
    local len = 2
    local roughness = 21964.27896 * vector.distance(vector.new(x, 0, z), vector.new(0, 0, 0))
    local variant = math.floor(perlin.variant.data3d[x%len+1][2][z%len+1] * roughness) % #l96_pattern + 1
    return "ALL"
    --l96_pattern[variant][z%length+1][x%width+1]
end

local light_noise = PerlinNoise({
    offset = 0.5,
    scale = 0.5,
    spread = {x = 60, y = 60, z = 60},
    seed = 654643 + core.get_mapgen_setting("seed"),
    octaves = 3,
    persist = 0.2,
    lacunarity = 2.0,
})
local light_nodes = {
    "br_core:ceiling_light_0",
    "br_core:ceiling_light_1",
    "br_core:ceiling_light_2",
    "br_core:ceiling_light_3",
    "br_core:emergency_light_0",
    "br_core:emergency_light_1",
}
local light_cids = {}
core.register_on_mods_loaded(function()
    for i, name in ipairs(light_nodes) do
        light_cids[core.get_content_id(name)] = name
    end
end)

-- streets
br_core.register_level({
    level = level,
    desc = "Level 96 streets",
    danger = 2,
    grace_dist = 5,
    biome = {},
    segsize = 16,
    base_height = 10,
    on_generate = function(self, pos, perlin)
        local x, z = pos.x, pos.z
        local roughness = 21964.27896
        local variant = math.floor(perlin.variant.data3d[2][2][2] * roughness) % #l96_pattern + 1

        -- weird "doesn't care about walls" version
        if vector.distance(pos, vector.new(0,0,0)) > 500
        and x%60 > 6 and z%60 > 6 then
            return l96_glitchy_version(x, z, perlin)
        end

        return l96_pattern[variant][z%length+1][x%width+1]
    end,
    sun = {
        visible = true,
        texture = "blank.png",
        sunrise_visible = false,
    },
    moon = {
        visible = false,
    },
    clouds = {
        density = 0.6,
        thickness = 2.3,
        ambient = "#fff",
        color = "#ffffff20",
        height = level * br_core.level_height - br_core.offset + 100,
        speed = {x=2.7, z=3}
    },
    sky = {
		base_color = "#ffffff",
		type = "regular",
		clouds = true,
		sky_color = {
			day_sky = "#80aed9" ,
			day_horizon = "#8086a1",
			dawn_sky = "#979" ,
			dawn_horizon = "#fb9",
			night_sky = "#263965" ,
			night_horizon = "#263965",
			indoors = "#263965",
			fog_sun_tint = "#263965",
			fog_moon_tint = "#263965",
			fog_tint_type = "custom",
		},
        fog = {
            fog_start = -1,
            fog_distance = -1,
        },
	},
    after_generated = function(pos, cid)
        if not light_cids[cid] then return end
        local v = light_noise:get_3d(vector.floor(pos / 16) * 16)
        if (v < 0.3) then
            local node = core.get_node(pos)
            node.name = node.name .. "_off"
            if core.registered_nodes[node.name] then
                core.set_node(pos, node)
            end
        end
        return false
    end,
})
local l96pl = {}
local l96timer = -1
br_core.register_on_level_enter(function(player, from_level, to_level)
    if to_level == level then
        l96pl[player] = true
        player:override_day_night_ratio(1)
    end
end)
br_core.register_on_level_exit(function(player, from_level, to_level)
    if from_level == level then
        l96pl[player] = nil
        player:override_day_night_ratio(1)
    end
end)


minetest.register_globalstep(function(dtime)
    local day_period = 600
    if l96timer == -1 then
        l96timer = world_storage:get_key("l167timer") or (day_period * 0.1)
    end
    if (math.floor(l96timer + dtime) ~= math.floor(l96timer)) then
        world_storage:set_key("l167timer", l96timer)
    end
    l96timer = (l96timer + dtime) % day_period
    for player,_ in pairs(l96pl) do
        if player and player.is_player and player:is_player() then
            local val = math.sin(l96timer / day_period * 3.14) * 1.4 - 0.2
            val = math.max(0, math.min(1, val)) * 0.7
            player:override_day_night_ratio(val)
        end
    end
end)
br_core.register_biome({
    level = level,
    desc = "Level 96",
    name = "NW",
    danger = 2,
    on_generate = nil,
    segheight = 8,
    schems = {
        {name=sch("96_underground_0"), vertical_segments={1}},
        --
        {name=sch("96_corner_0"), rotation=2, vertical_segments={0,1,1,1,1,1,1,1,1,0}, prevalence=3},
        {name=sch("96_corner_1"), rotation=2, vertical_segments={0,1,1,1,1,1,1,1,1,0}, prevalence=3},
        {name=sch("96_corner_2"), rotation=2, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_corner_3"), rotation=2, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
    }
})
br_core.register_biome({
    level = level,
    desc = "Level 96",
    name = "NE",
    danger = 2,
    on_generate = nil,
    segheight = 8,
    schems = {
        {name=sch("96_underground_0"), vertical_segments={1}},
        --
        {name=sch("96_corner_0"), rotation=3, vertical_segments={0,1,1,1,1,1,1,1,1,0}, prevalence=3},
        {name=sch("96_corner_1"), rotation=3, vertical_segments={0,1,1,1,1,1,1,1,1,0}, prevalence=3},
        {name=sch("96_corner_2"), rotation=3, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_corner_3"), rotation=3, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
    }
})
br_core.register_biome({
    level = level,
    desc = "Level 96",
    name = "SE",
    danger = 2,
    on_generate = nil,
    segheight = 8,
    schems = {
        {name=sch("96_underground_0"), vertical_segments={1}},
        --
        {name=sch("96_corner_0"), rotation=0, vertical_segments={0,1,1,1,1,1,1,1,1,0}, prevalence=3},
        {name=sch("96_corner_1"), rotation=0, vertical_segments={0,1,1,1,1,1,1,1,1,0}, prevalence=3},
        {name=sch("96_corner_2"), rotation=0, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_corner_3"), rotation=0, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
    }
})
br_core.register_biome({
    level = level,
    desc = "Level 96",
    name = "SW",
    danger = 2,
    on_generate = nil,
    segheight = 8,
    schems = {
        {name=sch("96_underground_0"), vertical_segments={1}},
        --
        {name=sch("96_corner_0"), rotation=1, vertical_segments={0,1,1,1,1,1,1,1,1,0}, prevalence=3},
        {name=sch("96_corner_1"), rotation=1, vertical_segments={0,1,1,1,1,1,1,1,1,0}, prevalence=3},
        {name=sch("96_corner_2"), rotation=1, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_corner_3"), rotation=1, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
    }
})
br_core.register_biome({
    level = level,
    desc = "Level 96",
    name = "NN",
    danger = 2,
    on_generate = nil,
    segheight = 8,
    schems = {
        {name=sch("96_underground_0"), vertical_segments={1}},
        --
        {name=sch("96_wall_0"), rotation=2, vertical_segments={0,1,1,1,1,1,1,1,1,0}, prevalence = 2},
        {name=sch("96_wall_1"), rotation=2, vertical_segments={0,1,1,1,1,1,1,1,1,0}, prevalence = 2},
        {name=sch("96_wall_2"), rotation=2, vertical_segments={0,1,1,1,1,1,1,1,1,0}, prevalence = 2},
        {name=sch("96_wall_2_portal"), rotation=2, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_wall_3"), rotation=2, vertical_segments={0,1,1,1,1,1,1,1,1,0}, prevalence = 2},
        {name=sch("96_wall_4"), rotation=2, vertical_segments={0,1,1,1,1,1,1,1,1,0}, prevalence = 2},
        {name=sch("96_wall_entrance_0"), rotation=2, vertical_segments={0,1,0,0,0,0,0,0,0,0}},
        {name=sch("96_wall_entrance_1"), rotation=2, vertical_segments={0,1,0,0,0,0,0,0,0,0}},
        {name=sch("96_stair_continuous_wall_0"), rotation=0, vertical_segments={0,1}, skip_above=8, prevalence = 2},
    }
})
br_core.register_biome({
    level = level,
    desc = "Level 96",
    name = "EE",
    danger = 2,
    on_generate = nil,
    segheight = 8,
    schems = {
        {name=sch("96_underground_0"), rotation=3, vertical_segments={1}},
        --
        {name=sch("96_wall_0"), rotation=3, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_wall_1"), rotation=3, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_wall_2"), rotation=3, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_wall_2_portal"), rotation=3, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_wall_3"), rotation=3, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_wall_4"), rotation=3, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_wall_entrance_0"), rotation=3, vertical_segments={0,1,0,0,0,0,0,0,0,0}},
        {name=sch("96_wall_entrance_1"), rotation=3, vertical_segments={0,1,0,0,0,0,0,0,0,0}},
        {name=sch("96_stair_continuous_wall_0"), rotation=1, vertical_segments={0,1}, skip_above=8},
    }
})
br_core.register_biome({
    level = level,
    desc = "Level 96",
    name = "SS",
    danger = 2,
    on_generate = nil,
    segheight = 8,
    schems = {
        {name=sch("96_underground_0"), vertical_segments={1}},
        --
        {name=sch("96_wall_0"), rotation=0, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_wall_1"), rotation=0, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_wall_2"), rotation=0, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_wall_2_portal"), rotation=0, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_wall_3"), rotation=0, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_wall_4"), rotation=0, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_wall_entrance_0"), rotation=0, vertical_segments={0,1,0,0,0,0,0,0,0,0}},
        {name=sch("96_wall_entrance_1"), rotation=0, vertical_segments={0,1,0,0,0,0,0,0,0,0}},
        {name=sch("96_stair_continuous_wall_0"), rotation=2, vertical_segments={0,1}, skip_above=8},
    }
})
br_core.register_biome({
    level = level,
    desc = "Level 96",
    name = "WW",
    danger = 2,
    on_generate = nil,
    segheight = 8,
    schems = {
        {name=sch("96_underground_0"), vertical_segments={1}},
        --
        {name=sch("96_wall_0"), rotation=1, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_wall_1"), rotation=1, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_wall_2"), rotation=1, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_wall_2_portal"), rotation=1, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_wall_3"), rotation=1, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_wall_4"), rotation=1, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_wall_entrance_0"), rotation=1, vertical_segments={0,1,0,0,0,0,0,0,0,0}},
        {name=sch("96_wall_entrance_1"), rotation=1, vertical_segments={0,1,0,0,0,0,0,0,0,0}},
        {name=sch("96_stair_continuous_wall_0"), rotation=3, vertical_segments={0,1}, skip_above=8},
    }
})
br_core.register_biome({
    level = level,
    desc = "Level 96",
    name = "WY",
    danger = 2,
    on_generate = nil,
    segheight = 8,
    schems = {
        {name=sch("96_underground_0"), vertical_segments={1}},
        --
        {name=sch("96_stair_continuous_wall_0"), rotation=3, vertical_segments={0,1}, skip_above=8},
    }
})
br_core.register_biome({
    level = level,
    desc = "Level 96",
    name = "TV",
    danger = 2,
    on_generate = nil,
    segheight = 8,
    schems = {
        {name=sch("96_underground_0"), vertical_segments={1}},
        {name=sch("air"), rotation=0, vertical_segments={0,0,1,1,1,1,1,1,1,0}},
        --
        {name=sch("96_road_0"), rotation=0, vertical_segments={0,1,0,0,0,0,0,0,0,0}},
    }
})
br_core.register_biome({
    level = level,
    desc = "Level 96",
    name = "TH",
    danger = 2,
    on_generate = nil,
    segheight = 8,
    schems = {
        {name=sch("96_underground_0"), vertical_segments={1}},
        {name=sch("air"), rotation=0, vertical_segments={0,0,1,1,1,1,1,1,1,0}},
        --
        {name=sch("96_road_0"), rotation=1, vertical_segments={0,1,0,0,0,0,0,0,0,0}},
    }
})
br_core.register_biome({
    level = level,
    desc = "Level 96",
    name = "TX",
    danger = 2,
    on_generate = nil,
    segheight = 8,
    schems = {
        {name=sch("96_underground_0"), vertical_segments={1}},
        {name=sch("air"), rotation=0, vertical_segments={0,0,1,1,1,1,1,1,1,0}},
        --
        {name=sch("96_crossroad_0"), rotation=0, vertical_segments={0,1,0,0,0,0,0,0,0,0}},
    }
})
br_core.register_biome({
    level = level,
    desc = "Level 96",
    name = "OO",
    danger = 2,
    on_generate = nil,
    segheight = 8,
    schems = {
        {name=sch("96_underground_0"), vertical_setruegments={1}},
        {name=sch("air"), rotation=0, vertical_segments={0,0,0,0,0,0,0,0,0,1}},
        --
        {name=sch("96_middle_0"), free_rotation=true, vertical_segments={0,1,1,1,1,1,1,1,1,0}, prevalence=1},
        {name=sch("96_middle_1"), free_rotation=true, vertical_segments={0,1,1,1,1,1,1,1,1,0}, prevalence=1},
        {name=sch("96_middle_2"), free_rotation=true, vertical_segments={0,1,1,1,1,1,1,1,1,0}, prevalence=3},
        {name=sch("96_middle_3"), free_rotation=true, vertical_segments={0,1,1,1,1,1,1,1,1,0}, prevalence=1},
        {name=sch("96_middle_4"), free_rotation=true, vertical_segments={0,1,1,1,1,1,1,1,1,0}, prevalence=1},
        {name=sch("96_middle_0_portal"), free_rotation=true, vertical_segments={0,1,1,1,1,1,1,1,1,0}},
        {name=sch("96_stair_0"), free_rotation=true, vertical_segments={0,1,1,1,1,1,1,1,0,0}, skip_above=1, prevalence=3},
    }
})
br_core.register_biome({
    level = level,
    desc = "Level 96",
    name = "PP",
    danger = 2,
    on_generate = nil,
    segheight = 8,
    schems = {
        {name=sch("96_underground_0"), vertical_segments={1}},
        {name=sch("air"), rotation=0, vertical_segments={0,0,1,1,1,1,1,1,1,0}},
        --
        {name=sch("96_park_0"), vertical_segments={0,1}},
    }
})
br_core.register_biome({
    level = level,
    desc = "Level 96",
    name = "ST",
    danger = 2,
    on_generate = nil,
    segheight = 8,
    schems = {
        {name=sch("96_underground_0"), vertical_segments={1}},
        {name=sch("air"), rotation=0, vertical_segments={0,0,1,1,1,1,1,1,1,0}},
        --
        {name=sch("96_stair_continuous_0"), vertical_segments={0,1}, skip_above=8},
    }
})
br_core.register_biome({
    level = level,
    desc = "Level 96",
    name = "ALL",
    danger = 2,
    on_generate = nil,
    segheight = 8,
    schems = {
        {name=sch("96_underground_0"), vertical_segments={1}},
        --
        {name=sch("96_stair_continuous_0"), vertical_segments={0,1}, skip_above=8, prevalence=9},
        {name=sch("96_blank_ruin"), vertical_segments={0,0,0,0,0,0,0,0,0,1}, prevalence=3},
        {name=sch("96_blank_ruin"), vertical_segments={0,0,0,0,0,0,0,0,1,0}, prevalence=8, skip_above=1},
        {name=sch("96_blank_ruin"), vertical_segments={0,0,0,0,0,0,0,1,0,0}, prevalence=5, skip_above=2},
        --
        {name=sch("96_blank_ruin"), vertical_segments={0,0,0,0,0,1,0,0,0,0}, prevalence=9, skip_above=4},
        --
        {name=sch("96_blank_ruin"), vertical_segments={1,0,0,0,0,0,0,0,0,0}, prevalence=5, skip_above=9},
        {name=sch("96_blank_ruin"), vertical_segments={0,0,1,0,0,0,0,0,0,0}, prevalence=5, skip_above=8},
            {name=sch("96_blank_ruin"), vertical_segments={1}, prevalence=2, skip_above=9, can_generate=function(pos)
            if (pos.x % 60 < 12) and (pos.z % 60 < 12) then return false
            else return true end
        end},
        --
        {name=sch("96_corner_0"), vertical_segments={0,1,1,1,1,1,1,1,1,1}},
        {name=sch("96_middle_0"), free_rotation=true, vertical_segments={1,1,1,1,1,1,1,1,1,1}, prevalence=1},
        {name=sch("96_middle_1"), free_rotation=true, vertical_segments={1,1,1,1,1,1,1,1,1,1}, prevalence=1},
        {name=sch("96_middle_2"), free_rotation=true, vertical_segments={1,1,1,1,1,1,1,1,1,1}, prevalence=3},
        {name=sch("96_middle_0_portal"), free_rotation=true, vertical_segments={1,1,1,1,1,1,1,1,1,1}},
        --
        {name=sch("96_stair_0"), free_rotation=true, vertical_segments={1,1,1,1,1,1,1,1,0,0}, skip_above=1, prevalence=3},
        {name=sch("96_stair_0"), free_rotation=true, vertical_segments={1,0,0,0,0,0,0,0,0,0}, prevalence=3, skip_above=1},
    }
})

-- junk and occasional supplies
br_core.set_loot_table(level, 0, {
    node_names = {"br_core:loot_crate"},
    max_items = 4,
    items = {
        br_core.loot.list.junk(5),
        br_core.loot.list.junk(5),
        br_core.loot.list.food(32),
        br_core.loot.list.food(32),
        br_core.loot.list.drinks(32),
        br_core.loot.list.drinks(32),
        {items = {"br_core:key_2 1"}, rarity = 22},
        {items = {"br_core:key_3 1"}, rarity = 22},
    },
})
-- food
br_core.set_loot_table(level, 1, {
    node_names = {"br_core:loot_crate"},
    max_items = 8,
    items = {
        br_core.loot.list.food(23),
        br_core.loot.list.food(23),
        br_core.loot.list.food(23),
    },
})
-- drinks
br_core.set_loot_table(level, 2, {
    node_names = {"br_core:loot_crate"},
    max_items = 8,
    items = {
        br_core.loot.list.drinks(8),
        br_core.loot.list.drinks(8),
        br_core.loot.list.drinks(8),
    },
})
-- tools and supplies
br_core.set_loot_table(level, 3, {
    node_names = {"br_core:loot_crate"},
    max_items = 8,
    items = {
        br_core.loot.list.tools(3),
        br_core.loot.list.junk(3),
        br_core.loot.list.junk(3),
        {items = {"br_core:key_2 1"}, rarity = 22},
        {items = {"br_core:key_3 1"}, rarity = 22},
    },
})
-- jackpot
br_core.set_loot_table(level, 4, {
    node_names = {"br_core:loot_crate"},
    max_items = 16,
    items = {
        br_core.loot.list.food(6),
        br_core.loot.list.food(6),
        br_core.loot.list.drinks(6),
        br_core.loot.list.drinks(6),
        br_core.loot.list.tools(4),
        {items = {"br_core:key_2 1"}, rarity = 8},
        {items = {"br_core:key_3 1"}, rarity = 14},
        {items = {"br_core:key_4 1"}, rarity = 14},
        br_core.loot.list.junk(5),
        br_core.loot.list.junk(5),
        br_core.loot.list.junk(5),
    },
})
-- keys
br_core.set_loot_table(level, 8, {
    node_names = {"br_core:loot_crate"},
    max_items = 8,
    items = {
        {items = {"br_core:key_2 1"}, rarity = 8},
        {items = {"br_core:key_3 1"}, rarity = 14},
        {items = {"br_core:key_4 1"}, rarity = 14},
        br_core.loot.list.junk(8),
        br_core.loot.list.junk(8),
        br_core.loot.list.tools(8),
    },
})

br_core.add_loot_ore(level, {
    wherein = "br_core:loot_area_0",
    node_name = "br_core:loot_crate_0",
    rarity = 4,
})

br_core.add_loot_ore(level, {
    wherein = "br_core:loot_area_1",
    node_name = "br_core:loot_crate_1",
    rarity = 4,
})

br_core.add_loot_ore(level, {
    wherein = "br_core:loot_area_2",
    node_name = "br_core:loot_crate_2",
    rarity = 4,
})

br_core.add_loot_ore(level, {
    wherein = "br_core:loot_area_3",
    node_name = "br_core:loot_crate_3",
    rarity = 4,
})
