lzr_sky = {} local DEFAULT_STARS = { visible = true, star_color = "#FFFFFF80", count = 2000, } local DEFAULT_SUN = { visible = true, sunrise_visible = true, } local DEFAULT_MOON = { visible = true, } local DEFAULT_FOG = { fog_distance = -1, fog_start = -1, } -- Start and end of the day in timeofday values. local TIMEOFDAY_DAY_START = 0.3 local TIMEOFDAY_DAY_END = 0.7 -- Start and end of the night in timeofday values. -- (wraps around) local TIMEOFDAY_NIGHT_START = 0.85 local TIMEOFDAY_NIGHT_END = 0.15 -- Check the timeofday to reset every this many seconds local TIMEOFDAY_RESET_TIME = 5.0 -- True if the special lightning sky is currently acitve local lightning_active = false -- Currently active sky local current_sky local registered_skies = {} local function register_sky(name, def) registered_skies[name] = def end function lzr_sky.sky_exists(skyname) return registered_skies[skyname] ~= nil end function lzr_sky.get_skies() local list = {} for id, _ in pairs(registered_skies) do table.insert(list, id) end table.sort(list) return list end -- Check if the timeofday for given sky is within the -- sky's permissible timeofday values. If not, reset it -- to the start. local function reset_timeofday(sky) local skydef = registered_skies[sky] if not skydef then return end local tod_start = skydef.timeofday_start local tod_end = skydef.timeofday_end local tod = minetest.get_timeofday() if tod_start < tod_end then if tod < tod_start or tod > tod_end then minetest.log("info", "[lzr_sky] Resetting timeofday for day sky "..sky) minetest.set_timeofday(tod_start) end else if tod < tod_start and tod > tod_end then minetest.log("info", "[lzr_sky] Resetting timeofday for night sky "..sky) minetest.set_timeofday(tod_start) end end end function lzr_sky.set_sky(skyname) local player = minetest.get_player_by_name("singleplayer") local skydef = registered_skies[skyname] -- Don't set sky if it's a sky already in use. -- Done to reduce unneccessary network packages. if current_sky == skyname then return end reset_timeofday(skyname) local skyskydef = table.copy(skydef.sky) if lightning_active and skyskydef.sky_color then -- Lightning takes precedence on the sky color. -- When the lightning is over, the real sky -- color is applied. skyskydef.sky_color.type = nil skyskydef.sky_color.day_sky = nil skyskydef.sky_color.day_horizon = nil skyskydef.sky_color.dawn_sky = nil skyskydef.sky_color.dawn_horizon = nil skyskydef.sky_color.night_sky = nil skyskydef.sky_color.night_horizon = nil end player:set_sky(skyskydef) player:set_clouds(skydef.clouds) player:set_sun(skydef.sun) player:set_moon(skydef.moon) player:set_stars(skydef.stars) -- Lightning takes precendence for day night ratio if not lightning_active then player:override_day_night_ratio(skydef.day_night_ratio) end -- Remember skyname for later current_sky = skyname minetest.log("action", "[lzr_sky] Sky set to "..skyname) end function lzr_sky.get_sky() return current_sky end function lzr_sky.get_lightning() return lightning_active end function lzr_sky.set_lightning(active) local player = minetest.get_player_by_name("singleplayer") if active then -- Activate flash lightning_active = true player:override_day_night_ratio(1) player:set_sky({ type = "plain", base_color = "#ffffff", }) minetest.log("info", "[lzr_sky] Lightning activated!") else -- Deactivate flash lightning_active = false local skydef = registered_skies[current_sky] -- (Re-)Apply the sky and day/night ratio of the current sky if skydef then player:set_sky(skydef.sky) end player:override_day_night_ratio(skydef.day_night_ratio) minetest.log("verbose", "[lzr_sky] Lightning deactivated!") end end -- Regularily check if the timeofday falls into the permissble range -- of timeofday values for the current sky and if not, reset -- it. This code is a workaround for the fact we cannot yet -- cleanly halt the day-night cycle without screwing up -- player settings. -- What this does it providing an acceptable solution for two cases: -- 1) time_speed is positive: The sun/moon will travel as usual, -- and as soon it reaches timeofday_end, it wraps back to timeofday_start, -- essentially "skipping" a few hours. -- 2) time_speed is 0: There is no effect. -- -- This solution works fine for day and night but is a bit weird -- for dawn and dusk. -- -- What we ACTUALLY want is that the sun is always static. -- but this solution was determined to be the "next best" one -- without too much disruption. -- TODO: Halt the day-night cycle entirely without hacks as soon -- Minetest allows us to do so. local timer = TIMEOFDAY_RESET_TIME minetest.register_globalstep(function(dtime) timer = timer + dtime if timer >= TIMEOFDAY_RESET_TIME then timer = 0 reset_timeofday(current_sky) end end) register_sky("bright_blue", { sky = { type = "regular", sky_color = { day_sky="#3d4caa", day_horizon="#55aaff", }, fog = DEFAULT_FOG, }, clouds = { height = 100, thickness = 20, density = 0.3, color = "#FFFFFF", }, stars = DEFAULT_STARS, sun = DEFAULT_SUN, moon = DEFAULT_MOON, timeofday_start = TIMEOFDAY_DAY_START, timeofday_end= TIMEOFDAY_DAY_END, }) register_sky("tropical_dawn", { sky = { type = "regular", sky_color = { day_sky="#d20000", day_horizon="#ff6c09", }, fog = DEFAULT_FOG, }, clouds = { height = 100, thickness = 20, density = 0.3, color = "#ff6600a5", }, day_night_ratio = 0.95, stars = DEFAULT_STARS, sun = DEFAULT_SUN, moon = DEFAULT_MOON, timeofday_start = TIMEOFDAY_DAY_START, timeofday_end = TIMEOFDAY_DAY_END, }) register_sky("ocean_evening", { sky = { type = "regular", sky_color = { day_sky="#3d374d", day_horizon="#5a2a34", dawn_sky="#3d374d", dawn_horizon="#5a2a34", night_sky="#3d374d", night_horizon="#5a2a34", }, fog = DEFAULT_FOG, }, clouds = { height = 100, thickness = 20, density = 0.3, color = "#8e6164ff", }, day_night_ratio = 0.8, stars = DEFAULT_STARS, sun = DEFAULT_SUN, moon = DEFAULT_MOON, timeofday_start = TIMEOFDAY_DAY_START, timeofday_end = TIMEOFDAY_DAY_END, }) register_sky("ocean_morning", { sky = { type = "regular", sky_color = { day_sky="#5184a2", day_horizon="#ffb754", }, fog = DEFAULT_FOG, }, clouds = { height = 100, thickness = 20, density = 0.3, color = "#ffffff8a", }, day_night_ratio = 0.9, stars = DEFAULT_STARS, sun = DEFAULT_SUN, moon = DEFAULT_MOON, timeofday_start = TIMEOFDAY_DAY_START, timeofday_end = TIMEOFDAY_DAY_END, }) register_sky("ominous_fog", { sky = { type = "regular", sky_color = { day_sky="#e7deff", day_horizon="#e1deff", }, fog = { fog_distance = 30, fog_start = 0.2, }, }, clouds = { height = 100, thickness = 20, density = 0.3, color = "#ffffff8a", }, stars = { visible = false }, sun = { visible = false, sunrise_visible = false }, moon = { visible = false }, timeofday_start = TIMEOFDAY_DAY_START, timeofday_end = TIMEOFDAY_DAY_END, }) register_sky("storm_clouds", { sky = { type = "regular", sky_color = { day_sky="#808080", day_horizon="#808080", }, fog = { fog_distance = 60, fog_start = 0.2, }, }, clouds = { height = 100, thickness = 40, density = 0.7, color = "#808080aa", }, stars = { visible = false }, sun = { visible = false, sunrise_visible = false }, moon = { visible = false }, timeofday_start = TIMEOFDAY_DAY_START, timeofday_end = TIMEOFDAY_DAY_END, day_night_ratio = 0.7, }) register_sky("starry_night", { sky = { type = "regular", sky_color = { day_sky="#000020", day_horizon="#000020", dawn_sky="#000020", dawn_horizon="#000020", night_sky="#000020", night_horizon="#000020", }, fog = DEFAULT_FOG, }, clouds = { height = 100, thickness = 10, density = 0.1, color = "#ffffff45", }, day_night_ratio = 0.6, stars = DEFAULT_STARS, sun = { visible = false, sunrise_visible = false }, moon = DEFAULT_MOON, timeofday_start = TIMEOFDAY_NIGHT_START, timeofday_end = TIMEOFDAY_NIGHT_END, })