forked from luanti-org/minetest_game
		
	Add API to weather mod
Co-authored-by: Till Affeldt <t.affeldt@tu-braunschweig.de>
This commit is contained in:
		
							
								
								
									
										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 | ||||
|  * `def`     See [Node definition] | ||||
|  * `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 | ||||
|  | ||||
| local mg_name = minetest.get_mapgen_setting("mg_name") | ||||
| if minetest.settings:get_bool("enable_weather") == false then | ||||
| 	return | ||||
| end | ||||
|  | ||||
| local mg_name = minetest.get_mapgen_setting("mg_name") | ||||
| if mg_name == "v6" or mg_name == "singlenode" then | ||||
| 	-- set a default shadow intensity for mgv6 and singlenode | ||||
| 	minetest.register_on_joinplayer(function(player) | ||||
| @@ -14,10 +17,9 @@ if mg_name == "v6" or mg_name == "singlenode" then | ||||
| 	return | ||||
| end | ||||
|  | ||||
| -- Parameters | ||||
| -- Default implementation for noise based cloud appearance | ||||
|  | ||||
| local TSCALE = 600 -- Time scale of noise variation in seconds | ||||
| local CYCLE = 8 -- Time period of cyclic clouds update in seconds | ||||
|  | ||||
| local np_density = { | ||||
| 	offset = 0.5, | ||||
| @@ -59,19 +61,11 @@ local np_speedz = { | ||||
| 	lacunarity = 2, | ||||
| } | ||||
|  | ||||
| -- End parameters | ||||
|  | ||||
|  | ||||
| -- Initialise noise objects to nil | ||||
|  | ||||
| local nobj_density = nil | ||||
| local nobj_thickness = nil | ||||
| local nobj_speedx = nil | ||||
| local nobj_speedz = nil | ||||
|  | ||||
|  | ||||
| -- Update clouds function | ||||
|  | ||||
| local function rangelim(value, lower, upper) | ||||
| 	return math.min(math.max(value, lower), upper) | ||||
| end | ||||
| @@ -88,7 +82,7 @@ do | ||||
| 	end | ||||
| end | ||||
|  | ||||
| local function update_clouds() | ||||
| function weather.get(player) | ||||
| 	-- Adjusted time in seconds | ||||
| 	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_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 | ||||
| 		local humid = minetest.get_humidity(player:get_pos()) or 50 | ||||
| 		-- Default and classic density value is 0.4, make this happen | ||||
| 		-- at humidity midvalue 50 when n_density is at midvalue 0.5. | ||||
| 		-- density_max = 0.25 at humid = 0. | ||||
| 		-- density_max = 0.8 at humid = 50. | ||||
| 		-- density_max = 1.35 at humid = 100. | ||||
| 		local density_max = 0.8 + ((humid - 50) / 50) * 0.55 | ||||
| 		-- Range limit density_max to always have occasional | ||||
| 		-- small scattered clouds at extreme low humidity. | ||||
| 		local density = rangelim(density_max, 0.2, 1.0) * n_density | ||||
| 		player:set_clouds({ | ||||
| 	-- 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 | ||||
| 	-- at humidity midvalue 50 when n_density is at midvalue 0.5. | ||||
| 	-- density_max = 0.25 at humid = 0. | ||||
| 	-- density_max = 0.8 at humid = 50. | ||||
| 	-- density_max = 1.35 at humid = 100. | ||||
| 	local density_max = 0.8 + ((humid - 50) / 50) * 0.55 | ||||
| 	-- Range limit density_max to always have occasional | ||||
| 	-- small scattered clouds at extreme low humidity. | ||||
| 	local density = rangelim(density_max, 0.2, 1.0) * n_density | ||||
|  | ||||
| 	return { | ||||
| 		clouds = { | ||||
| 			density = density, | ||||
| 			thickness = math.max(math.floor( | ||||
| 				rangelim(32 * humid / 100, 8, 32) * n_thickness | ||||
| 				), 2), | ||||
| 			speed = {x = n_speedx * 4, z = n_speedz * 4}, | ||||
| 		}) | ||||
| 		-- now adjust the shadow intensity | ||||
| 		player:set_lighting({ shadows = { intensity = 0.7 * (1 - density) } }) | ||||
| 	end | ||||
| 		}, | ||||
| 		lighting = { | ||||
| 			shadows = { intensity = 0.7 * (1 - density) } | ||||
| 		} | ||||
| 	} | ||||
| 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) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user