mirror of
https://github.com/minetest/minetest_game.git
synced 2024-11-08 08:43:51 +01:00
Add API to weather mod
Co-authored-by: Till Affeldt <t.affeldt@tu-braunschweig.de>
This commit is contained in:
parent
31133a371e
commit
d1ba7c3db3
18
game_api.txt
18
game_api.txt
@ -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
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,42 +96,28 @@ 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
|
-- at humidity midvalue 50 when n_density is at midvalue 0.5.
|
||||||
-- at humidity midvalue 50 when n_density is at midvalue 0.5.
|
-- density_max = 0.25 at humid = 0.
|
||||||
-- density_max = 0.25 at humid = 0.
|
-- density_max = 0.8 at humid = 50.
|
||||||
-- density_max = 0.8 at humid = 50.
|
-- density_max = 1.35 at humid = 100.
|
||||||
-- density_max = 1.35 at humid = 100.
|
local density_max = 0.8 + ((humid - 50) / 50) * 0.55
|
||||||
local density_max = 0.8 + ((humid - 50) / 50) * 0.55
|
-- 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)
|
|
||||||
|
Loading…
Reference in New Issue
Block a user