
local function light_gain(player)
    local light = minetest.get_natural_light(vector.offset(player:get_pos(), 0, 0.5, 0), 0.5)
    if not light then return 0 end
    light = math.min(light, 14)
    light = math.max(light / 14, 0.0001)
    return light
end

local rain_spawn_size = 30

local function start_weather(player, meta, from_weather)
    if meta.active then return end
    meta.active = true

    meta.particlespawners[#meta.particlespawners+1] = minetest.add_particlespawner({
        amount = 200,
        time = 0,
        collisiondetection = true,
        collision_removal = true,
        object_collision = false,
        attached = player, -- to object ref
        vertical = true, -- If true face player using y axis only:-- If true face player using y axis only:
        texture = "br_weather_snow_1.png",
        texpool = {
            {
                name = "br_weather_snow_1.png",
                alpha_tween = {
                    0.0, 1.0,
                    style = "pulse",
                }
            },
            {
                name = "br_weather_snow_2.png",
                alpha_tween = {
                    0.0, 1.0,
                    style = "pulse",
                }
            },
        },
        playername = player:get_player_name(), -- only to this player
        glow = 0,
        minpos = vector.new(-rain_spawn_size*0.5, 25, -rain_spawn_size*0.3),
        maxpos = vector.new(rain_spawn_size*0.5, 35, rain_spawn_size*0.7),
        minvel = vector.new(-4, -8, -4),
        maxvel = vector.new( 4, -8, 4),
        minacc = {x=0, y=0, z=0},
        maxacc = {x=0, y=0, z=0},
        minexptime = 8,
        maxexptime = 8,
        minsize = 0.75,
        maxsize = 0.75,
    })
    -- big in dist
    local default = {
        amount = 30,
        time = 0,
        -- collisiondetection = true,
        -- collision_removal = true,
        object_collision = false,
        attached = player, -- to object ref
        vertical = true, -- If true face player using y axis only:-- If true face player using y axis only:
        texture = "br_weather_snow_sheet_1.png",
        texpool = {
            {
                name = "br_weather_snow_sheet_1.png",
                alpha_tween = {
                    0.0, 1.0,
                    style = "pulse",
                    reps = 1,
                }
            },
            {
                name = "br_weather_snow_sheet_2.png",
                alpha_tween = {
                    0.0, 1.0,
                    style = "pulse",
                    reps = 1,
                }
            },
        },
        playername = player:get_player_name(), -- only to this player
        glow = 0,
        minpos = vector.new(-rain_spawn_size*0.7, 20, -rain_spawn_size*1.0),
        maxpos = vector.new( rain_spawn_size*0.7, 20,  rain_spawn_size*1.0),
        minvel = vector.new(-2, -7, -1),
        maxvel = vector.new( 2, -7, 1),
        minacc = {x=0, y=0, z=0},
        maxacc = {x=0, y=0, z=0},
        minexptime = 8,
        maxexptime = 8,
        minsize = 240,
        maxsize = 240,
    }
    local distmin = 0.8
    local distmax = 2
    local ymin = 20
    local tmp = table.copy(default)
    -- front
    tmp.amount = 30
    tmp.minpos = vector.new(rain_spawn_size*-distmax, ymin,  rain_spawn_size*distmin)
    tmp.maxpos = vector.new(rain_spawn_size* distmax, ymin+10,  rain_spawn_size*distmax)
    meta.particlespawners[#meta.particlespawners+1] = minetest.add_particlespawner(tmp)
    -- behind
    tmp.amount = 10
    tmp.minpos = vector.new(rain_spawn_size*-distmax, ymin,  rain_spawn_size*-distmax)
    tmp.maxpos = vector.new(rain_spawn_size* distmax, ymin+10,  rain_spawn_size*-distmin)
    meta.particlespawners[#meta.particlespawners+1] = minetest.add_particlespawner(tmp)
    -- left
    tmp.amount = 6
    tmp.minpos = vector.new(rain_spawn_size*-distmax, ymin,  rain_spawn_size*-distmin)
    tmp.maxpos = vector.new(rain_spawn_size*-distmin, ymin+10,  rain_spawn_size* distmin)
    meta.particlespawners[#meta.particlespawners+1] = minetest.add_particlespawner(tmp)
    -- right
    tmp.amount = 6
    tmp.minpos = vector.new(rain_spawn_size* distmin, ymin,  rain_spawn_size*-distmin)
    tmp.maxpos = vector.new(rain_spawn_size* distmax, ymin+10,  rain_spawn_size* distmin)
    meta.particlespawners[#meta.particlespawners+1] = minetest.add_particlespawner(tmp)
    -- sky
    br_weather.request_sky(player, {
        base_color = "#e3e3e3",
        type = "regular",
        clouds = true,
        sky_color = {
            day_sky = br_weather.color(105, 110, 115),
            day_horizon = br_weather.color(105, 110, 115),
            dawn_sky = br_weather.color(93, 93, 95),
            dawn_horizon = br_weather.color(100, 87, 102),
            night_sky = br_weather.color(50, 41, 72),
            night_horizon = br_weather.color(50, 41, 71),
            indoors = br_weather.color(59, 59, 59),
            fog_sun_tint = br_weather.color(38, 57, 101),
            fog_moon_tint = br_weather.color(38, 57, 101),
            fog_tint_type = "custom",
        },
        fog = {
            fog_start = 0.4,
        },
    })
    player:set_clouds({
        density = 1.0,
        thickness = 20,
        ambient = "#111111",
        color = "#555555ee",
        height = 100,
        speed = {x=4, z=2}
    })
    player:set_sun({
        visible = true,
        texture = "blank.png",
        sunrise_visible = true,
    })
    player:set_moon({
        visible = true,
        texture = "blank.png",
    })
    br_weather.request_lighting(player, 0.38)
end

local function stop_weather(player, meta, to_weather)
    if not meta.active then return end
    meta.active = false
    for i, id in ipairs(meta.particlespawners) do
        minetest.delete_particlespawner(id)
    end
    meta.particlespawners = {}
end

br_weather.register_weather("heavy_snow", {
    biomes = {"default"},
    chance = 70,
    min_duration = 120, -- sec1
    max_duration = 300,
    light_factor = 0.8,
    on_enter_weather = function(player, meta, from_weather)
        start_weather(player, meta, from_weather)
    end,
    on_leave_weather = function(player, meta, to_weather)
        stop_weather(player, meta, to_weather)
        player:set_clouds()
        player:set_moon()
        player:set_sun()
    end,
    on_step = function(player, meta, dtime)
        meta.update_tick = (meta.update_tick or 1) - dtime
        if meta.update_tick <= 0 then
            meta.update_tick = 1
            local light = light_gain(player)
            if light < 0.1 then stop_weather(player, meta, "nil") return
            else start_weather(player, meta, "nil") end
        end
    end,
    next_weather = {
        ["snow"] = 0.5,
        ["light_rain"] = 0.2,
    },
    fallbacks = {
        "heavy_rain",
        "light_rain",
        "clear",
    },
})

