From fd370b27419ad98da4c43f3aa19dab4b6fc268d4 Mon Sep 17 00:00:00 2001 From: Till Affeldt Date: Sat, 11 Mar 2023 00:11:12 +0100 Subject: [PATCH] Implement API to disable weather --- mods/weather/init.lua | 110 ++++++++++++++++++++++++++++++++---------- 1 file changed, 85 insertions(+), 25 deletions(-) diff --git a/mods/weather/init.lua b/mods/weather/init.lua index 0214af27..d420aff0 100644 --- a/mods/weather/init.lua +++ b/mods/weather/init.lua @@ -1,21 +1,12 @@ --- Disable by mapgen or setting - +-- Check whether mod should be active local mg_name = minetest.get_mapgen_setting("mg_name") -if minetest.settings:get_bool("enable_weather") == false then - return -end +local mod_enabled = minetest.settings:get_bool("enable_weather", true) +local randomize_clouds = mod_enabled and mg_name ~= "v6" and mg_name ~= "singlenode" -if mg_name == "v6" or mg_name == "singlenode" then - -- set a default shadow intensity for mgv6 and singlenode - minetest.register_on_joinplayer(function(player) - player:set_lighting({ shadows = { intensity = 0.33 } }) - end) - - return -end +weather = {} +local playerlist = {} -- Parameters - local TSCALE = 600 -- Time scale of noise variation in seconds local CYCLE = 8 -- Time period of cyclic clouds update in seconds @@ -61,7 +52,6 @@ local np_speedz = { -- End parameters - -- Initialise noise objects to nil local nobj_density = nil @@ -69,7 +59,6 @@ local nobj_thickness = nil local nobj_speedx = nil local nobj_speedz = nil - -- Update clouds function local function rangelim(value, lower, upper) @@ -79,7 +68,7 @@ end local os_time_0 = os.time() local t_offset = math.random(0, 300000) -local function update_clouds() +local function update_clouds(players) -- Time in seconds. -- Add random time offset to avoid identical behaviour each server session. local time = os.difftime(os.time(), os_time_0) - t_offset @@ -94,7 +83,7 @@ local function update_clouds() local n_speedx = nobj_speedx:get_2d({x = time, y = 0}) -- -1 to 1 local n_speedz = nobj_speedz:get_2d({x = time, y = 0}) -- -1 to 1 - for _, player in ipairs(minetest.get_connected_players()) do + for _, player in ipairs(players) do -- Fallback to mid-value 50 for very old worlds local humid = minetest.get_humidity(player:get_pos()) or 50 -- Default and classic density value is 0.4, make this happen @@ -114,22 +103,93 @@ local function update_clouds() speed = {x = n_speedx * 4, z = n_speedz * 4}, }) -- now adjust the shadow intensity - player:set_lighting({ shadows = { intensity = 0.7 * (1 - density) } }) + player:set_lighting({ + shadows = { intensity = 0.7 * (1 - density) } + }) end end - -local function cyclic_update() - update_clouds() - minetest.after(CYCLE, cyclic_update) +local function purge_effects(player) + -- reset potentially touched values to their defaults + if randomize_clouds then + player:set_clouds({ + density = 0.4, + thickness = 16, + speed = { x = 0, z = -2 } + }) + end + player:set_lighting({ + shadows = { intensity = 0 } + }) end +-- Define API hooks -minetest.after(0, cyclic_update) +-- override to set state for newly joined players +weather.enable_on_join = true +-- returns bool for whether weather is active +-- returns nil if player is offline or weather is disabled +weather.get_enabled = function(player) + return playerlist[player] +end + +-- override weather generation for individual player +weather.set_enabled = function(player, enable) + if enable == playerlist[player] then + return + end + playerlist[player] = enable + if enable then + if randomize_clouds then + update_clouds({player}) + end + else + purge_effects(player) + end +end + +-- End API hooks + +-- skip event registration if mod is disabled +if not mod_enabled then + return +end + +if update_clouds then + local function cyclic_update() + local players = {} + for player, state in pairs(playerlist) do + if state then + table.insert(players, player) + end + end + update_clouds(players) + minetest.after(CYCLE, cyclic_update) + end + minetest.after(0, cyclic_update) +end -- Update on player join to instantly alter clouds from the default minetest.register_on_joinplayer(function(player) - update_clouds() + if weather.enable_on_join then + playerlist[player] = true + if randomize_clouds then + update_clouds({player}) + else + -- set a default shadow intensity for mgv6 and singlenode + player:set_lighting({ + shadows = { + intensity = 0.33 + } + }) + end + else + playerlist[player] = false + end +end) + +minetest.register_on_leaveplayer(function(player) + table.remove(player) end)