mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2024-09-12 08:42:10 +02:00
Recent changes set the default colors to some pretty psychedelic ones. The stated purpose was debugging, but in absense of any actual debugging code other than v6 mapgen inadvertently assuming that role, more sensible colors were reinstated. If debugging code is desired, it should probably be added to the main parts of mcl_weather.
346 lines
11 KiB
Lua
346 lines
11 KiB
Lua
local mods_loaded = false
|
|
local NIGHT_VISION_RATIO = 0.45
|
|
|
|
local water_color = "#0b4880"
|
|
|
|
local mg_name = minetest.get_mapgen_setting("mg_name")
|
|
|
|
function mcl_weather.set_sky_box_clear(player, sky, fog)
|
|
local pos = player:get_pos()
|
|
if minetest.get_item_group(minetest.get_node(vector.new(pos.x,pos.y+1.5,pos.z)).name, "water") ~= 0 then return end
|
|
local sc = {
|
|
day_sky = "#7BA4FF",
|
|
day_horizon = "#C0D8FF",
|
|
dawn_sky = "#B4BAFA",
|
|
dawn_horizon = "#BAC1F0",
|
|
night_sky = "#000000",
|
|
night_horizon = "#4A6790",
|
|
}
|
|
if sky then
|
|
sc.day_sky = sky
|
|
end
|
|
if fog then
|
|
sc.day_horizon = fog
|
|
end
|
|
player:set_sky({
|
|
type = "regular",
|
|
sky_color = sc,
|
|
clouds = true,
|
|
})
|
|
end
|
|
|
|
function mcl_weather.set_sky_color(player, def)
|
|
local pos = player:get_pos()
|
|
if minetest.get_item_group(minetest.get_node(vector.offset(pos, 0, 1.5, 0)).name, "water") ~= 0 then return end
|
|
player:set_sky({
|
|
type = def.type,
|
|
sky_color = def.sky_color,
|
|
clouds = def.clouds,
|
|
})
|
|
end
|
|
|
|
mcl_weather.skycolor = {
|
|
-- Should be activated before do any effect.
|
|
active = true,
|
|
|
|
-- To skip update interval
|
|
force_update = true,
|
|
|
|
-- Update interval.
|
|
update_interval = 3,
|
|
|
|
-- Main sky colors: starts from midnight to midnight.
|
|
-- Please do not set directly. Use add_layer instead.
|
|
colors = {},
|
|
|
|
-- min value which will be used in color gradient, usualy its first user given color in 'pure' color.
|
|
min_val = 0,
|
|
|
|
-- number of colors while constructing gradient of user given colors
|
|
max_val = 1000,
|
|
|
|
-- Table for tracking layer order
|
|
layer_names = {},
|
|
|
|
-- To layer to colors table
|
|
add_layer = function(layer_name, layer_color, instant_update)
|
|
mcl_weather.skycolor.colors[layer_name] = layer_color
|
|
table.insert(mcl_weather.skycolor.layer_names, layer_name)
|
|
mcl_weather.skycolor.force_update = true
|
|
end,
|
|
|
|
current_layer_name = function()
|
|
return mcl_weather.skycolor.layer_names[#mcl_weather.skycolor.layer_names]
|
|
end,
|
|
|
|
-- Retrieve layer from colors table
|
|
retrieve_layer = function()
|
|
local last_layer = mcl_weather.skycolor.current_layer_name()
|
|
return mcl_weather.skycolor.colors[last_layer]
|
|
end,
|
|
|
|
-- Remove layer from colors table
|
|
remove_layer = function(layer_name)
|
|
for k, name in pairs(mcl_weather.skycolor.layer_names) do
|
|
if name == layer_name then
|
|
table.remove(mcl_weather.skycolor.layer_names, k)
|
|
mcl_weather.skycolor.force_update = true
|
|
return
|
|
end
|
|
end
|
|
end,
|
|
|
|
-- Wrapper for updating day/night ratio that respects night vision
|
|
override_day_night_ratio = function(player, ratio)
|
|
local meta = player:get_meta()
|
|
local has_night_vision = meta:get_int("night_vision") == 1
|
|
local arg
|
|
-- Apply night vision only for dark sky
|
|
local is_dark = minetest.get_timeofday() > 0.8 or minetest.get_timeofday() < 0.2 or mcl_weather.state ~= "none"
|
|
local pos = player:get_pos()
|
|
local dim = mcl_worlds.pos_to_dimension(pos)
|
|
if has_night_vision and is_dark and dim ~= "nether" and dim ~= "end" then
|
|
if ratio == nil then
|
|
arg = NIGHT_VISION_RATIO
|
|
else
|
|
arg = math.max(ratio, NIGHT_VISION_RATIO)
|
|
end
|
|
else
|
|
arg = ratio
|
|
end
|
|
player:override_day_night_ratio(arg)
|
|
end,
|
|
|
|
-- Update sky color. If players not specified update sky for all players.
|
|
update_sky_color = function(players)
|
|
-- Override day/night ratio as well
|
|
players = mcl_weather.skycolor.utils.get_players(players)
|
|
for _, player in ipairs(players) do
|
|
local pos = player:get_pos()
|
|
local dim = mcl_worlds.pos_to_dimension(pos)
|
|
local has_weather = (mcl_worlds.has_weather(pos) and (mcl_weather.state == "snow" or mcl_weather.state =="rain" or mcl_weather.state == "thunder") and mcl_weather.has_snow(pos)) or ((mcl_weather.state =="rain" or mcl_weather.state == "thunder") and mcl_weather.has_rain(pos))
|
|
if minetest.get_item_group(minetest.get_node(vector.new(pos.x,pos.y+1.5,pos.z)).name, "water") ~= 0 then
|
|
player:set_sky({ type = "regular",
|
|
sky_color = {
|
|
day_sky = water_color,
|
|
day_horizon = water_color,
|
|
dawn_sky = water_color,
|
|
dawn_horizon = water_color,
|
|
night_sky = water_color,
|
|
night_horizon = water_color,
|
|
},
|
|
clouds = true,
|
|
})
|
|
end
|
|
if dim == "overworld" then
|
|
local biomesky
|
|
local biomefog
|
|
if mg_name ~= "v6" and mg_name ~= "singlenode" then
|
|
local biome = minetest.get_biome_name(minetest.get_biome_data(player:get_pos()).biome)
|
|
biomesky = minetest.registered_biomes[biome]._mcl_skycolor
|
|
biomefog = minetest.registered_biomes[biome]._mcl_fogcolor
|
|
end
|
|
if (mcl_weather.state == "none") then
|
|
-- Clear weather
|
|
mcl_weather.set_sky_box_clear(player,biomesky,biomefog)
|
|
player:set_sun({visible = true, sunrise_visible = true})
|
|
player:set_moon({visible = true})
|
|
player:set_stars({visible = true})
|
|
mcl_weather.skycolor.override_day_night_ratio(player, nil)
|
|
elseif not has_weather then
|
|
local day_color = mcl_weather.skycolor.get_sky_layer_color(0.15)
|
|
local dawn_color = mcl_weather.skycolor.get_sky_layer_color(0.27)
|
|
local night_color = mcl_weather.skycolor.get_sky_layer_color(0.1)
|
|
mcl_weather.set_sky_color(player, {
|
|
type = "regular",
|
|
sky_color = {
|
|
day_sky = day_color,
|
|
day_horizon = day_color,
|
|
dawn_sky = dawn_color,
|
|
dawn_horizon = dawn_color,
|
|
night_sky = night_color,
|
|
night_horizon = night_color,
|
|
},
|
|
clouds = true,
|
|
})
|
|
player:set_sun({visible = false, sunrise_visible = false})
|
|
player:set_moon({visible = false})
|
|
player:set_stars({visible = false})
|
|
elseif has_weather then
|
|
-- Weather skies
|
|
local day_color = mcl_weather.skycolor.get_sky_layer_color(0.5)
|
|
local dawn_color = mcl_weather.skycolor.get_sky_layer_color(0.75)
|
|
local night_color = mcl_weather.skycolor.get_sky_layer_color(0)
|
|
mcl_weather.set_sky_color(player, {
|
|
type = "regular",
|
|
sky_color = {
|
|
day_sky = day_color,
|
|
day_horizon = day_color,
|
|
dawn_sky = dawn_color,
|
|
dawn_horizon = dawn_color,
|
|
night_sky = night_color,
|
|
night_horizon = night_color,
|
|
},
|
|
clouds = true,
|
|
})
|
|
player:set_sun({visible = false, sunrise_visible = false})
|
|
player:set_moon({visible = false})
|
|
player:set_stars({visible = false})
|
|
|
|
local lf = mcl_weather.get_current_light_factor()
|
|
if mcl_weather.skycolor.current_layer_name() == "lightning" then
|
|
mcl_weather.skycolor.override_day_night_ratio(player, 1)
|
|
elseif lf then
|
|
local w = minetest.get_timeofday()
|
|
local light = (w * (lf*2))
|
|
if light > 1 then
|
|
light = 1 - (light - 1)
|
|
end
|
|
light = (light * lf) + 0.15
|
|
mcl_weather.skycolor.override_day_night_ratio(player, light)
|
|
else
|
|
mcl_weather.skycolor.override_day_night_ratio(player, nil)
|
|
end
|
|
end
|
|
elseif dim == "end" then
|
|
local t = "mcl_playerplus_end_sky.png"
|
|
player:set_sky({ type = "skybox",
|
|
base_color = "#000000",
|
|
textures = {t,t,t,t,t,t},
|
|
clouds = false,
|
|
})
|
|
player:set_sun({visible = false , sunrise_visible = false})
|
|
player:set_moon({visible = false})
|
|
player:set_stars({visible = false})
|
|
mcl_weather.skycolor.override_day_night_ratio(player, 0.5)
|
|
elseif dim == "nether" then
|
|
local nether_sky = {
|
|
Nether = "#300808",
|
|
BasaltDelta = "#685F70",
|
|
SoulsandValley = "#1B4745",
|
|
CrimsonForest = "#330303",
|
|
WarpedForest = "#1A051A"
|
|
}
|
|
local biometint = nether_sky[minetest.get_biome_name(minetest.get_biome_data(player:get_pos()).biome)]
|
|
|
|
mcl_weather.set_sky_color(player, {
|
|
type = "regular",
|
|
sky_color = {
|
|
day_sky = "#300808",
|
|
day_horizon = biometint,
|
|
dawn_sky = "#300808",
|
|
dawn_horizon = biometint,
|
|
night_sky = "#300808",
|
|
night_horizon = biometint,
|
|
},
|
|
clouds = false,
|
|
})
|
|
player:set_sun({visible = false , sunrise_visible = false})
|
|
player:set_moon({visible = false})
|
|
player:set_stars({visible = false})
|
|
mcl_weather.skycolor.override_day_night_ratio(player, nil)
|
|
elseif dim == "void" then
|
|
player:set_sky({ type = "plain",
|
|
base_color = "#000000",
|
|
clouds = false,
|
|
})
|
|
player:set_sun({visible = false, sunrise_visible = false})
|
|
player:set_moon({visible = false})
|
|
player:set_stars({visible = false})
|
|
end
|
|
end
|
|
end,
|
|
|
|
-- Returns current layer color in {r, g, b} format
|
|
get_sky_layer_color = function(timeofday)
|
|
if #mcl_weather.skycolor.layer_names == 0 then
|
|
return nil
|
|
end
|
|
|
|
-- min timeofday value 0; max timeofday value 1. So sky color gradient range will be between 0 and 1 * mcl_weather.skycolor.max_val.
|
|
local rounded_time = math.floor(timeofday * mcl_weather.skycolor.max_val)
|
|
local color = mcl_weather.skycolor.utils.convert_to_rgb(mcl_weather.skycolor.min_val, mcl_weather.skycolor.max_val, rounded_time, mcl_weather.skycolor.retrieve_layer())
|
|
return color
|
|
end,
|
|
|
|
utils = {
|
|
convert_to_rgb = function(minval, maxval, current_val, colors)
|
|
local max_index = #colors - 1
|
|
local val = (current_val-minval) / (maxval-minval) * max_index + 1.0
|
|
local index1 = math.floor(val)
|
|
local index2 = math.min(math.floor(val)+1, max_index + 1)
|
|
local f = val - index1
|
|
local c1 = colors[index1]
|
|
local c2 = colors[index2]
|
|
return {r=math.floor(c1.r + f*(c2.r - c1.r)), g=math.floor(c1.g + f*(c2.g-c1.g)), b=math.floor(c1.b + f*(c2.b - c1.b))}
|
|
end,
|
|
|
|
-- Simply getter. Ether returns user given players list or get all connected players if none provided
|
|
get_players = function(players)
|
|
if players == nil or #players == 0 then
|
|
if mods_loaded then
|
|
players = minetest.get_connected_players()
|
|
elseif players == nil then
|
|
players = {}
|
|
end
|
|
end
|
|
return players
|
|
end,
|
|
|
|
-- Returns first player sky color. I assume that all players are in same color layout.
|
|
get_current_bg_color = function()
|
|
local players = mcl_weather.skycolor.utils.get_players(nil)
|
|
if players[1] then
|
|
return players[1]:get_sky(true).sky_color
|
|
end
|
|
return nil
|
|
end
|
|
},
|
|
|
|
}
|
|
|
|
local timer = 0
|
|
minetest.register_globalstep(function(dtime)
|
|
if mcl_weather.skycolor.active ~= true or #minetest.get_connected_players() == 0 then
|
|
return
|
|
end
|
|
|
|
if mcl_weather.skycolor.force_update then
|
|
mcl_weather.skycolor.update_sky_color()
|
|
mcl_weather.skycolor.force_update = false
|
|
return
|
|
end
|
|
|
|
-- regular updates based on iterval
|
|
timer = timer + dtime;
|
|
if timer >= mcl_weather.skycolor.update_interval then
|
|
mcl_weather.skycolor.update_sky_color()
|
|
timer = 0
|
|
end
|
|
|
|
end)
|
|
|
|
local function initsky(player)
|
|
|
|
if player.set_lighting then
|
|
player:set_lighting({ shadows = { intensity = tonumber(minetest.settings:get("mcl_default_shadow_intensity") or 0.33) } })
|
|
end
|
|
|
|
if (mcl_weather.skycolor.active) then
|
|
mcl_weather.skycolor.force_update = true
|
|
end
|
|
|
|
player:set_clouds(mcl_worlds:get_cloud_parameters() or {height=mcl_worlds.layer_to_y(127), speed={x=-2, z=0}, thickness=4, color="#FFF0FEF"})
|
|
end
|
|
|
|
minetest.register_on_joinplayer(initsky)
|
|
minetest.register_on_respawnplayer(initsky)
|
|
|
|
mcl_worlds.register_on_dimension_change(function(player)
|
|
mcl_weather.skycolor.update_sky_color({player})
|
|
end)
|
|
|
|
minetest.register_on_mods_loaded(function()
|
|
mods_loaded = true
|
|
end)
|