Add API to weather mod

Co-authored-by: Till Affeldt <t.affeldt@tu-braunschweig.de>
This commit is contained in:
sfan5 2024-04-10 18:24:00 +02:00
parent 31133a371e
commit d1ba7c3db3
3 changed files with 75 additions and 45 deletions

@ -1169,3 +1169,21 @@ the log.
* after logging the action, the original callback (if any) is called * after logging the action, the original callback (if any) is called
* `def` See [Node definition] * `def` See [Node definition]
* `name` Description of the node in the log message * `name` Description of the node in the log message
Weather API
-----------
The weather mod will constantly adjust weather effects seen by the player
(that is: cloud parameters and shadow intensity).
These can be influenced using this API.
#### `weather.get = function(player)`
* Returns the current weather effects seen by the player.
It returns a table with two keys:
* `clouds`: A table (or `nil`) with cloud data following the same format as used for `player:set_clouds()`.
* `lighting`: A table (or `nil`) with lighting data following the same format as used for `player:set_lighting()`.
* `player`: ObjectRef of the relevant player
* You can override this function to change the weather effects by simply returning different values.
Setting `clouds` or `lighting` in the result table to `nil` will *prevent* those from changing.

32
mods/weather/api.lua Normal file

@ -0,0 +1,32 @@
local CYCLE = 8 -- Time period of cyclic clouds update in seconds
weather = {}
-- default implementation is empty
function weather.get(player)
return {}
end
local function do_update()
for _, player in ipairs(minetest.get_connected_players()) do
local params = weather.get(player)
assert(params ~= nil, "weather.get() must not return nil")
if params.clouds then
player:set_clouds(params.clouds)
end
if params.lighting then
player:set_lighting(params.lighting)
end
end
end
local function cyclic_update()
do_update()
minetest.after(CYCLE, cyclic_update)
end
minetest.after(0, cyclic_update)
-- Update on player join to instantly alter clouds from the default
minetest.register_on_joinplayer(function(player)
do_update()
end)

@ -1,10 +1,13 @@
-- Always load the API
dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/api.lua")
-- Disable by mapgen or setting -- Disable by mapgen or setting
local mg_name = minetest.get_mapgen_setting("mg_name")
if minetest.settings:get_bool("enable_weather") == false then if minetest.settings:get_bool("enable_weather") == false then
return return
end end
local mg_name = minetest.get_mapgen_setting("mg_name")
if mg_name == "v6" or mg_name == "singlenode" then if mg_name == "v6" or mg_name == "singlenode" then
-- set a default shadow intensity for mgv6 and singlenode -- set a default shadow intensity for mgv6 and singlenode
minetest.register_on_joinplayer(function(player) minetest.register_on_joinplayer(function(player)
@ -14,10 +17,9 @@ if mg_name == "v6" or mg_name == "singlenode" then
return return
end end
-- Parameters -- Default implementation for noise based cloud appearance
local TSCALE = 600 -- Time scale of noise variation in seconds local TSCALE = 600 -- Time scale of noise variation in seconds
local CYCLE = 8 -- Time period of cyclic clouds update in seconds
local np_density = { local np_density = {
offset = 0.5, offset = 0.5,
@ -59,19 +61,11 @@ local np_speedz = {
lacunarity = 2, lacunarity = 2,
} }
-- End parameters
-- Initialise noise objects to nil
local nobj_density = nil local nobj_density = nil
local nobj_thickness = nil local nobj_thickness = nil
local nobj_speedx = nil local nobj_speedx = nil
local nobj_speedz = nil local nobj_speedz = nil
-- Update clouds function
local function rangelim(value, lower, upper) local function rangelim(value, lower, upper)
return math.min(math.max(value, lower), upper) return math.min(math.max(value, lower), upper)
end end
@ -88,7 +82,7 @@ do
end end
end end
local function update_clouds() function weather.get(player)
-- Adjusted time in seconds -- Adjusted time in seconds
local time = math.floor(minetest.get_gametime() - t_offset) local time = math.floor(minetest.get_gametime() - t_offset)
@ -102,7 +96,6 @@ local function update_clouds()
local n_speedx = nobj_speedx:get_2d({x = time, y = 0}) -- -1 to 1 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 local n_speedz = nobj_speedz:get_2d({x = time, y = 0}) -- -1 to 1
for _, player in ipairs(minetest.get_connected_players()) do
-- Fallback to mid-value 50 for very old worlds -- Fallback to mid-value 50 for very old worlds
local humid = minetest.get_humidity(player:get_pos()) or 50 local humid = minetest.get_humidity(player:get_pos()) or 50
-- Default and classic density value is 0.4, make this happen -- Default and classic density value is 0.4, make this happen
@ -114,30 +107,17 @@ local function update_clouds()
-- Range limit density_max to always have occasional -- Range limit density_max to always have occasional
-- small scattered clouds at extreme low humidity. -- small scattered clouds at extreme low humidity.
local density = rangelim(density_max, 0.2, 1.0) * n_density local density = rangelim(density_max, 0.2, 1.0) * n_density
player:set_clouds({
return {
clouds = {
density = density, density = density,
thickness = math.max(math.floor( thickness = math.max(math.floor(
rangelim(32 * humid / 100, 8, 32) * n_thickness rangelim(32 * humid / 100, 8, 32) * n_thickness
), 2), ), 2),
speed = {x = n_speedx * 4, z = n_speedz * 4}, speed = {x = n_speedx * 4, z = n_speedz * 4},
}) },
-- now adjust the shadow intensity lighting = {
player:set_lighting({ shadows = { intensity = 0.7 * (1 - density) } }) shadows = { intensity = 0.7 * (1 - density) }
end }
}
end end
local function cyclic_update()
update_clouds()
minetest.after(CYCLE, cyclic_update)
end
minetest.after(0, cyclic_update)
-- Update on player join to instantly alter clouds from the default
minetest.register_on_joinplayer(function(player)
update_clouds()
end)