mirror of
				https://gitlab.com/rautars/weather_pack.git
				synced 2025-10-31 00:25:32 +01:00 
			
		
		
		
	Compare commits
	
		
			18 Commits
		
	
	
		
			v0.3
			...
			def185bb40
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | def185bb40 | ||
|  | 28744a162f | ||
|  | eecf3c5524 | ||
|  | 5d8bf1ae1c | ||
|  | 3a315928c4 | ||
|  | 695ef4521b | ||
|  | 7dbab2c033 | ||
|  | 6d21d3ddd1 | ||
|  | f8e1640b9a | ||
|  | 4fad47c4a4 | ||
|  | f79c3e4505 | ||
|  | 5d4745cb27 | ||
|  | da72a58293 | ||
|  | 96bd7176b9 | ||
|  | e90133b30a | ||
|  | 1f07735c44 | ||
|  | 892cfa8b58 | ||
|  | 829605f70d | 
							
								
								
									
										16
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								README.md
									
									
									
									
									
								
							| @@ -2,6 +2,12 @@ weather-pack | |||||||
| ======================= | ======================= | ||||||
| Weather mod for Minetest (http://minetest.net/) | Weather mod for Minetest (http://minetest.net/) | ||||||
|  |  | ||||||
|  | Feedback and Improvements | ||||||
|  | ----------------------- | ||||||
|  | * See newest version at https://github.com/xeranas/weather_pack | ||||||
|  | * Register bugs at https://github.com/xeranas/weather_pack/issues | ||||||
|  | * Questions / Discussion at https://forum.minetest.net/viewtopic.php?p=215869 | ||||||
|  |  | ||||||
| Weathers included | Weathers included | ||||||
| ----------------------- | ----------------------- | ||||||
| * light_rain, rain, heavy_rain | * light_rain, rain, heavy_rain | ||||||
| @@ -19,7 +25,7 @@ Be aware that weather may not be visible for player until player is in right bio | |||||||
|  |  | ||||||
| Dependencies | Dependencies | ||||||
| ----------------------- | ----------------------- | ||||||
| Thunder weather requres [lightning](https://github.com/minetest-mods/lightning) mod. | Thunder weather requires [lightning](https://github.com/minetest-mods/lightning) mod. | ||||||
|  |  | ||||||
| License of source code: | License of source code: | ||||||
| ----------------------- | ----------------------- | ||||||
| @@ -31,12 +37,8 @@ Authors of media files: | |||||||
| xeranas: | xeranas: | ||||||
|  |  | ||||||
|   * `happy_weather_heavy_rain_drops.png` - CC-0 |   * `happy_weather_heavy_rain_drops.png` - CC-0 | ||||||
|   * `happy_weather_light_rain_raindrop_1.png` - CC-0 |   * `happy_weather_light_rain_raindrop_*.png` - CC-0 | ||||||
|   * `happy_weather_light_rain_raindrop_2.png` - CC-0 |   * `happy_weather_light_snow_snowflake_*.png` - CC-0 | ||||||
|   * `happy_weather_light_rain_raindrop_3.png` - CC-0 |  | ||||||
|   * `happy_weather_light_snow_snowflake_1.png` - CC-0 |  | ||||||
|   * `happy_weather_light_snow_snowflake_2.png` - CC-0 |  | ||||||
|   * `happy_weather_light_snow_snowflake_3.png` - CC-0 |  | ||||||
|  |  | ||||||
| inchadney (http://freesound.org/people/inchadney/): | inchadney (http://freesound.org/people/inchadney/): | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,107 +1,140 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
| ------------------------- | ------------------------- | ||||||
| -- Sky Layers: API | -- Sky Layers: Core | ||||||
|  |  | ||||||
| -- License: MIT | -- License: MIT | ||||||
| -- Credits: xeranas | -- Credits: xeranas | ||||||
|  | -- Thanks: Perkovec for colorise utils (github.com/Perkovec/colorise-lua)  | ||||||
| ------------------------- | ------------------------- | ||||||
|  |  | ||||||
| skylayer = {} | local colorise = {} | ||||||
|  |  | ||||||
| -- flag for enable / disable skylayer temporally if needed | colorise.rgb2hex = function (rgb) | ||||||
| skylayer.enabled = true | 	local hexadecimal = '#' | ||||||
|  |  | ||||||
| -- supported skylayer types | 	for key = 1, #rgb do | ||||||
| skylayer.SKY_PLAIN = "plain" | 	    local value = rgb[key]  | ||||||
| skylayer.SKY_SOLID_COLOR = "solid_color" | 		local hex = '' | ||||||
| skylayer.SKY_SKYBOX = "skybox" |  | ||||||
|  |  | ||||||
| -- helps track total dtime | 		while(value > 0)do | ||||||
| local timer = 0 | 			local index = math.fmod(value, 16) + 1 | ||||||
|  | 			value = math.floor(value / 16) | ||||||
|  | 			hex = string.sub('0123456789ABCDEF', index, index) .. hex			 | ||||||
|  | 		end | ||||||
|  |  | ||||||
| local gradient_default_min_value = 0 | 		if(string.len(hex) == 0)then | ||||||
| local gradient_default_max_value = 1000 | 			hex = '00' | ||||||
|  | 		elseif(string.len(hex) == 1)then | ||||||
|  | 			hex = '0' .. hex | ||||||
|  | 		end | ||||||
|  | 		hexadecimal = hexadecimal .. hex | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	return hexadecimal | ||||||
|  | end | ||||||
|  |  | ||||||
|  | local core = {} | ||||||
|  |  | ||||||
|  | core.settings = {} | ||||||
|  |  | ||||||
|  | -- flag to disable skylayer at global step | ||||||
|  | core.settings.enabled = true | ||||||
|  |  | ||||||
|  | -- default gradient interval values | ||||||
|  | core.settings.gradient_default_min_value = 0 | ||||||
|  | core.settings.gradient_default_max_value = 1000 | ||||||
|  |  | ||||||
| -- how often sky will be updated in seconds | -- how often sky will be updated in seconds | ||||||
| skylayer.update_interval = 4 | core.settings.update_interval = 4 | ||||||
|  |  | ||||||
|  | -- helps track total dtime | ||||||
|  | core.timer = 0 | ||||||
|  |  | ||||||
|  | core.default_clouds = nil | ||||||
|  |  | ||||||
| -- keeps player related data such as player itself and own sky layers | -- keeps player related data such as player itself and own sky layers | ||||||
| local sky_players = {} | core.sky_players = {} | ||||||
|  |  | ||||||
| -- adds player to sky layer affected players list | -- adds player to sky layer affected players list | ||||||
| local add_player = function(player) | core.add_player = function(player) | ||||||
| 	local data = {} | 	local data = {} | ||||||
| 	data.id = player:get_player_name() | 	data.id = player:get_player_name() | ||||||
| 	data.player = player | 	data.player = player | ||||||
| 	data.skylayers = {} | 	data.skylayers = {} | ||||||
| 	table.insert(sky_players, data) | 	table.insert(core.sky_players, data) | ||||||
| end | end | ||||||
|  |  | ||||||
| -- remove player from sky layer affected players list | -- remove player from sky layer affected players list | ||||||
| local remove_player = function(player_name) | core.remove_player = function(player_name) | ||||||
| 	if #sky_players == 0 then | 	if #core.sky_players == 0 then | ||||||
| 		return | 		return | ||||||
| 	end | 	end | ||||||
|  | 	for k, player_data in ipairs(core.sky_players) do | ||||||
| 	for k, player_data in ipairs(sky_players) do |  | ||||||
| 		if player_data.id == player_name then | 		if player_data.id == player_name then | ||||||
| 			set_default_sky(player_data.player) | 			reset_sky(player_data.player) | ||||||
| 			table.remove(sky_players, k) | 			table.remove(core.sky_players, k) | ||||||
| 			return | 			return | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| end | end | ||||||
|  |  | ||||||
| local get_player_by_name = function(player_name) | core.get_player_by_name = function(player_name) | ||||||
| 	if player_name == nil then | 	if player_name == nil then | ||||||
| 		return nil | 		return nil | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	if #minetest.get_connected_players() == 0 then | 	if #minetest.get_connected_players() == 0 then | ||||||
| 		return nil | 		return nil | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	for i, player in ipairs(minetest.get_connected_players()) do | 	for i, player in ipairs(minetest.get_connected_players()) do | ||||||
| 		if player:get_player_name() == player_name then | 		if player:get_player_name() == player_name then | ||||||
| 			return player | 			return player | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| end | end | ||||||
|  |  | ||||||
| local get_player_data = function(player_name) | core.get_player_data = function(player_name) | ||||||
| 	if #sky_players == 0 then | 	if #core.sky_players == 0 then | ||||||
| 		return nil | 		return nil | ||||||
| 	end | 	end | ||||||
|  | 	for k, player_data in ipairs(core.sky_players) do | ||||||
| 	for k, player_data in ipairs(sky_players) do |  | ||||||
| 		if player_data.id == player_name then | 		if player_data.id == player_name then | ||||||
| 			return player_data | 			return player_data | ||||||
| 		end | 		end | ||||||
| 	end	 | 	end	 | ||||||
| end | end | ||||||
|  |  | ||||||
| local create_new_player_data = function(player_name) | core.create_new_player_data = function(player_name) | ||||||
| 	local player_data = get_player_data(player_name) | 	local player_data = core.get_player_data(player_name) | ||||||
| 	if player_data == nil then | 	if player_data == nil then | ||||||
| 		local player = get_player_by_name(player_name) | 		local player = core.get_player_by_name(player_name) | ||||||
| 		if player == nil then | 		if player == nil then | ||||||
| 			minetest.log("error", "Fail to resolve player '" .. player_name .. "'") | 			minetest.log("error", "Fail to resolve player '" .. player_name .. "'") | ||||||
| 			return | 			return | ||||||
| 		end | 		end | ||||||
| 		add_player(player) | 		core.add_player(player) | ||||||
| 		return get_player_data(player_name) | 		return core.get_player_data(player_name) | ||||||
| 	end | 	end | ||||||
| 	return player_data | 	return player_data | ||||||
| end | end | ||||||
|  |  | ||||||
| -- sets default / regular sky for player | -- sets default / regular sky for player | ||||||
| local set_default_sky = function(player) | core.reset_sky = function(player) | ||||||
|  | 	core.set_default_sky(player) | ||||||
|  | 	core.set_default_clouds(player) | ||||||
|  | end | ||||||
|  |  | ||||||
|  | core.set_default_sky = function(player) | ||||||
| 	player:set_sky(nil, "regular", nil) | 	player:set_sky(nil, "regular", nil) | ||||||
| end | end | ||||||
|  |  | ||||||
|  | core.set_default_clouds = function(player) | ||||||
|  | 	player:set_clouds(core.default_clouds) | ||||||
|  | end | ||||||
|  |  | ||||||
| -- resolves latest skylayer based on added layer time | -- resolves latest skylayer based on added layer time | ||||||
| local get_latest_layer = function(layers) | core.get_latest_layer = function(layers) | ||||||
| 	if #layers == 0 then | 	if #layers == 0 then | ||||||
| 		return nil | 		return nil | ||||||
| 	end | 	end | ||||||
| @@ -120,7 +153,7 @@ local get_latest_layer = function(layers) | |||||||
| 	return latest_layer | 	return latest_layer | ||||||
| end | end | ||||||
|  |  | ||||||
| local convert_to_rgb = function(minval, maxval, current_val, colors) | core.convert_to_rgb = function(minval, maxval, current_val, colors) | ||||||
| 	local max_index = #colors - 1 | 	local max_index = #colors - 1 | ||||||
| 	local val = (current_val-minval) / (maxval-minval) * max_index + 1.0 | 	local val = (current_val-minval) / (maxval-minval) * max_index + 1.0 | ||||||
| 	local index1 = math.floor(val) | 	local index1 = math.floor(val) | ||||||
| @@ -136,64 +169,154 @@ local convert_to_rgb = function(minval, maxval, current_val, colors) | |||||||
| 	} | 	} | ||||||
| end | end | ||||||
|  |  | ||||||
| -- Returns current layer color in {r, g, b} format | -- Returns current gradient color in {r, g, b} format | ||||||
| local get_current_layer_color = function(layer_data) | core.calculate_current_gradient_color = function(gradient_colors, min_val, max_val) | ||||||
| 	-- min timeofday value 0; max timeofday value 1. So sky color gradient range will be between 0 and 1 * skycolor.max_value. | 	if gradient_colors == nil then return nil end | ||||||
| 	local timeofday = minetest.get_timeofday() | 	local timeofday = minetest.get_timeofday() | ||||||
| 	local min_val = layer_data.gradient_data.min_value |  | ||||||
| 	if min_val == nil then | 	if min_val == nil then | ||||||
| 		min_val = gradient_default_min_value | 		min_val = core.settings.gradient_default_min_value | ||||||
| 	end | 	end | ||||||
| 	local max_val = layer_data.gradient_data.max_value |  | ||||||
| 	if max_val == nil then | 	if max_val == nil then | ||||||
| 		max_val = gradient_default_max_value | 		max_val = core.settings.gradient_default_max_value | ||||||
| 	end | 	end | ||||||
| 	local rounded_time = math.floor(timeofday * max_val) | 	local rounded_time = math.floor(timeofday * max_val) | ||||||
| 	local gradient_colors = layer_data.gradient_data.colors | 	return core.convert_to_rgb(min_val, max_val, rounded_time, gradient_colors) | ||||||
| 	local color = convert_to_rgb(min_val, max_val, rounded_time, gradient_colors) |  | ||||||
| 	return color |  | ||||||
| end | end | ||||||
|  |  | ||||||
| local update_plain_sky = function(player, layer_data) | -- Returns current sky color in {r, g, b} format | ||||||
| 	local color = get_current_layer_color(layer_data) | core.get_current_layer_color = function(gradient_colors, min_val, max_val) | ||||||
| 	player:set_sky(color, "plain", nil) | 	return core.calculate_current_gradient_color(gradient_colors, min_val, max_val) | ||||||
| end | end | ||||||
|  |  | ||||||
| local update_solid_color_sky = function(player, layer_data) | -- Returns current cloud color in hex format | ||||||
| 	player:set_sky(layer_data.color, "plain", nil) | core.get_current_cloud_color = function(gradient_colors, min_val, max_val) | ||||||
|  | 	local rgb_color = core.calculate_current_gradient_color(gradient_colors, min_val, max_val) | ||||||
|  | 	if rgb_color == nil then return nil end | ||||||
|  | 	return colorise.rgb2hex({rgb_color.r, rgb_color.g, rgb_color.b})  | ||||||
| end | end | ||||||
|  |  | ||||||
| local update_skybox_sky = function(player, layer_data) | core.update_sky_details = function(player, sky_layer) | ||||||
| 	player:set_sky(layer_data.skybox[1], layer_data.skybox[2], layer_data.skybox[3]) | 	local sky_data = sky_layer.sky_data | ||||||
|  |  | ||||||
|  | 	if sky_data == nil then  | ||||||
|  | 		if sky_layer.reset_defaults == true then | ||||||
|  | 			core.set_default_sky(player) | ||||||
|  | 			sky_layer.reset_defaults = false | ||||||
|  | 		end | ||||||
|  | 		return | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	local sky_color = core.get_current_layer_color( | ||||||
|  | 		sky_data.gradient_colors,  | ||||||
|  | 		sky_data.gradient_min_value, | ||||||
|  | 		sky_data.gradient_max_value) | ||||||
|  | 	local bgcolor = sky_data.bgcolor | ||||||
|  | 	if sky_color ~= nil then | ||||||
|  | 		bgcolor = sky_color | ||||||
|  | 	end | ||||||
|  | 	local sky_type = "plain" -- default | ||||||
|  | 	if sky_data.type ~= nil then | ||||||
|  | 		sky_type = sky_data.type | ||||||
|  | 	end | ||||||
|  | 	local clouds = sky_layer.clouds_data ~= nil | ||||||
|  | 	if sky_data.clouds ~= nil then | ||||||
|  | 		clouds = sky_data.clouds | ||||||
|  | 	end | ||||||
|  | 	player:set_sky(bgcolor, sky_type, sky_data.textures, clouds)	 | ||||||
| end | end | ||||||
|  |  | ||||||
| local update_sky = function(player, timer) | core.update_clouds_details = function(player, sky_layer) | ||||||
| 	local player_data = get_player_data(player:get_player_name()) | 	local clouds_data = sky_layer.clouds_data | ||||||
|  |  | ||||||
|  | 	if clouds_data == nil then  | ||||||
|  | 		if sky_layer.reset_defaults == true then | ||||||
|  | 			core.set_default_clouds(player) | ||||||
|  | 			sky_layer.reset_defaults = false | ||||||
|  | 		end | ||||||
|  | 		return | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	local cloud_color = core.get_current_cloud_color( | ||||||
|  | 		clouds_data.gradient_colors,  | ||||||
|  | 		clouds_data.gradient_min_value, | ||||||
|  | 		clouds_data.gradient_max_value) | ||||||
|  | 	if cloud_color == nil then | ||||||
|  | 		cloud_color = clouds_data.color | ||||||
|  | 	end | ||||||
|  | 	player:set_clouds({ | ||||||
|  | 		color = cloud_color, | ||||||
|  | 		density = clouds_data.density, | ||||||
|  | 		ambient = clouds_data.ambient, | ||||||
|  | 		height = clouds_data.height, | ||||||
|  | 		thickness = clouds_data.thickness, | ||||||
|  | 		speed = clouds_data.speed}) | ||||||
|  | end | ||||||
|  |  | ||||||
|  | core.update_sky = function(player, timer) | ||||||
|  | 	local player_data = core.get_player_data(player:get_player_name()) | ||||||
| 	if player_data == nil then return end | 	if player_data == nil then return end | ||||||
|  |  | ||||||
| 	local current_layer = get_latest_layer(player_data.skylayers) | 	local current_layer = core.get_latest_layer(player_data.skylayers) | ||||||
| 	if current_layer == nil then | 	if current_layer == nil then | ||||||
| 		return | 		return | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	if current_layer.updated == false or timer >= skylayer.update_interval then | 	if skylayer.update_interval == nil then | ||||||
| 		current_layer.updated = os.time() | 		skylayer.update_interval = core.settings.update_interval | ||||||
| 		 |  | ||||||
| 		if current_layer.layer_type == skylayer.SKY_PLAIN then |  | ||||||
| 			update_plain_sky(player, current_layer.data) |  | ||||||
| 			return |  | ||||||
| 		end |  | ||||||
|  |  | ||||||
| 		if current_layer.layer_type == skylayer.SKY_SOLID_COLOR then |  | ||||||
| 			update_solid_color_sky(player, current_layer.data) |  | ||||||
| 			return |  | ||||||
| 		end |  | ||||||
|  |  | ||||||
| 		if current_layer.layer_type == skylayer.SKY_SKYBOX then |  | ||||||
| 			update_skybox_sky(player, current_layer.data) |  | ||||||
| 			return |  | ||||||
| 		end |  | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
|  | 	if player_data.last_active_layer == nil or player_data.last_active_layer ~= current_layer.name then | ||||||
|  | 		current_layer.reset_defaults = true | ||||||
|  | 	end | ||||||
|  | 	player_data.last_active_layer = current_layer.name | ||||||
|  |  | ||||||
|  | 	if current_layer.updated == false or core.timer >= skylayer.update_interval then | ||||||
|  | 		current_layer.updated = os.time() | ||||||
|  | 		core.update_sky_details(player, current_layer) | ||||||
|  | 		core.update_clouds_details(player, current_layer) | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | minetest.register_on_joinplayer(function(player) | ||||||
|  | 	if core.default_clouds == nil then | ||||||
|  | 		core.default_clouds = player:get_clouds() | ||||||
|  | 	end | ||||||
|  | end) | ||||||
|  |  | ||||||
|  | minetest.register_globalstep(function(dtime) | ||||||
|  | 	if core.settings.enabled == false then | ||||||
|  | 		return | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	if #minetest.get_connected_players() == 0 then | ||||||
|  | 		return | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	-- timer addition calculated outside of players loop  | ||||||
|  | 	core.timer = core.timer + dtime; | ||||||
|  |  | ||||||
|  | 	for k, player in ipairs(minetest.get_connected_players()) do | ||||||
|  | 		core.update_sky(player, core.timer) | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	-- reset timer outside of loop to make sure that all players sky will be updated | ||||||
|  | 	if core.timer >= core.settings.update_interval then | ||||||
|  | 		core.timer = 0 | ||||||
|  | 	end | ||||||
|  | end) | ||||||
|  |  | ||||||
|  | ------------------------- | ||||||
|  | -- Sky Layers: API | ||||||
|  |  | ||||||
|  | -- License: MIT | ||||||
|  | -- Credits: xeranas | ||||||
|  | ------------------------- | ||||||
|  |  | ||||||
|  | skylayer = {} | ||||||
|  |  | ||||||
|  | -- set flag for enable / disable skylayer | ||||||
|  | skylayer.is_enabled = function(enabled) | ||||||
|  | 	core.settings.enabled = enabled | ||||||
| end | end | ||||||
|  |  | ||||||
| skylayer.add_layer = function(player_name, layer) | skylayer.add_layer = function(player_name, layer) | ||||||
| @@ -202,9 +325,9 @@ skylayer.add_layer = function(player_name, layer) | |||||||
| 		return | 		return | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	local player_data = get_player_data(player_name) | 	local player_data = core.get_player_data(player_name) | ||||||
| 	if player_data == nil then | 	if player_data == nil then | ||||||
| 		player_data = create_new_player_data(player_name) | 		player_data = core.create_new_player_data(player_name) | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	if player_data == nil then | 	if player_data == nil then | ||||||
| @@ -217,7 +340,7 @@ skylayer.add_layer = function(player_name, layer) | |||||||
| end | end | ||||||
|  |  | ||||||
| skylayer.remove_layer = function(player_name, layer_name) | skylayer.remove_layer = function(player_name, layer_name) | ||||||
| 	local player_data = get_player_data(player_name) | 	local player_data = core.get_player_data(player_name) | ||||||
| 	if player_data == nil or player_data.skylayers == nil then | 	if player_data == nil or player_data.skylayers == nil then | ||||||
| 		return | 		return | ||||||
| 	end | 	end | ||||||
| @@ -230,36 +353,12 @@ skylayer.remove_layer = function(player_name, layer_name) | |||||||
| 		if layer.name == layer_name then | 		if layer.name == layer_name then | ||||||
| 			table.remove(player_data.skylayers, k) | 			table.remove(player_data.skylayers, k) | ||||||
| 			if #player_data.skylayers == 0 then | 			if #player_data.skylayers == 0 then | ||||||
| 				local player = get_player_by_name(player_name) | 				local player = core.get_player_by_name(player_name) | ||||||
| 				if player ~= nil then | 				if player ~= nil then | ||||||
| 					set_default_sky(player) | 					core.reset_sky(player) | ||||||
| 				end | 				end | ||||||
| 			end | 			end | ||||||
| 			return | 			return | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| end | end | ||||||
|  |  | ||||||
| minetest.register_globalstep(function(dtime) |  | ||||||
| 	if skylayer.enabled == false then |  | ||||||
| 		return |  | ||||||
| 	end |  | ||||||
|  |  | ||||||
| 	if #minetest.get_connected_players() == 0 then |  | ||||||
| 		return |  | ||||||
| 	end |  | ||||||
|  |  | ||||||
| 	-- timer addition calculated outside of players loop  |  | ||||||
| 	timer = timer + dtime; |  | ||||||
|  |  | ||||||
| 	for k, player in ipairs(minetest.get_connected_players()) do |  | ||||||
| 		update_sky(player, timer) |  | ||||||
| 	end |  | ||||||
|  |  | ||||||
| 	-- reset timer outside of loop to make sure that all players sky will be updated |  | ||||||
| 	if timer >= skylayer.update_interval then |  | ||||||
| 		timer = 0 |  | ||||||
| 	end |  | ||||||
| end) |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -67,15 +67,26 @@ end | |||||||
|  |  | ||||||
| local set_sky_box = function(player_name) | local set_sky_box = function(player_name) | ||||||
| 	local sl = {} | 	local sl = {} | ||||||
| 	sl.layer_type = skylayer.SKY_PLAIN |  | ||||||
| 	sl.name = SKYCOLOR_LAYER | 	sl.name = SKYCOLOR_LAYER | ||||||
| 	sl.data = {gradient_data={}} | 	sl.sky_data = { | ||||||
| 	sl.data.gradient_data.colors = { | 		gradient_colors = { | ||||||
| 		{r=0, g=0, b=0}, | 			{r=0, g=0, b=0}, | ||||||
| 		{r=65, g=66, b=78}, | 			{r=85, g=86, b=98}, | ||||||
| 		{r=112, g=110, b=119}, | 			{r=142, g=140, b=149}, | ||||||
| 		{r=65, g=66, b=78}, | 			{r=85, g=86, b=98}, | ||||||
| 		{r=0, g=0, b=0} | 			{r=0, g=0, b=0} | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	sl.clouds_data = { | ||||||
|  | 		gradient_colors = { | ||||||
|  | 			{r=0, g=0, b=0}, | ||||||
|  | 			{r=65, g=66, b=78}, | ||||||
|  | 			{r=112, g=110, b=119}, | ||||||
|  | 			{r=65, g=66, b=78}, | ||||||
|  | 			{r=0, g=0, b=0} | ||||||
|  | 		}, | ||||||
|  | 		speed = {z = 10, y = -40}, | ||||||
|  | 		density = 0.6 | ||||||
| 	} | 	} | ||||||
| 	skylayer.add_layer(player_name, sl) | 	skylayer.add_layer(player_name, sl) | ||||||
| end | end | ||||||
| @@ -191,7 +202,7 @@ heavy_rain.in_area = function(position) | |||||||
| 		return false | 		return false | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	if position.y > -10 then | 	if position.y > -10 and position.y < 120 then | ||||||
| 		return true | 		return true | ||||||
| 	end | 	end | ||||||
| 	return false | 	return false | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								init.lua
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								init.lua
									
									
									
									
									
								
							| @@ -2,13 +2,13 @@ local modpath = minetest.get_modpath("weather_pack"); | |||||||
|  |  | ||||||
| -- If skylayer mod not located then embeded version will be loaded. | -- If skylayer mod not located then embeded version will be loaded. | ||||||
| if minetest.get_modpath("skylayer") == nil then | if minetest.get_modpath("skylayer") == nil then | ||||||
|   dofile(modpath.."/embedded_sky_layer_api.lua") | 	dofile(modpath.."/embedded_sky_layer_api.lua") | ||||||
| end | end | ||||||
|  |  | ||||||
| -- If happy_weather_api mod not located then embeded version will be loaded. | -- If happy_weather_api mod not located then embeded version will be loaded. | ||||||
| if minetest.get_modpath("happy_weather_api") == nil then | if minetest.get_modpath("happy_weather_api") == nil then | ||||||
|   dofile(modpath.."/embedded_happy_weather_api.lua") | 	dofile(modpath.."/embedded_happy_weather_api.lua") | ||||||
|   dofile(modpath.."/commands.lua") | 	dofile(modpath.."/commands.lua") | ||||||
| end | end | ||||||
|  |  | ||||||
| -- Happy Weather utilities | -- Happy Weather utilities | ||||||
| @@ -20,10 +20,12 @@ dofile(modpath.."/heavy_rain.lua") | |||||||
| dofile(modpath.."/snow.lua") | dofile(modpath.."/snow.lua") | ||||||
|  |  | ||||||
| if minetest.get_modpath("lightning") ~= nil then | if minetest.get_modpath("lightning") ~= nil then | ||||||
|   dofile(modpath.."/thunder.lua") | 	dofile(modpath.."/thunder.lua") | ||||||
|    |  | ||||||
|   -- Turn off lightning mod 'auto mode' | 	-- Turn off lightning mod 'auto mode' | ||||||
|   lightning.auto = false | 	lightning.auto = false | ||||||
| end | end | ||||||
|  |  | ||||||
| dofile(modpath.."/abm.lua") | dofile(modpath.."/abm.lua") | ||||||
|  |  | ||||||
|  | minetest.log("action", "[weather_pack] loaded.") | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ | |||||||
| local light_rain = {} | local light_rain = {} | ||||||
| light_rain.last_check = 0 | light_rain.last_check = 0 | ||||||
| light_rain.check_interval = 200 | light_rain.check_interval = 200 | ||||||
|  | light_rain.chance = 0.15 | ||||||
|  |  | ||||||
| -- Weather identification code | -- Weather identification code | ||||||
| light_rain.code = "light_rain" | light_rain.code = "light_rain" | ||||||
| @@ -26,7 +27,7 @@ local SKYCOLOR_LAYER = "happy_weather_light_rain_sky" | |||||||
| light_rain.is_starting = function(dtime, position) | light_rain.is_starting = function(dtime, position) | ||||||
| 	if light_rain.last_check + light_rain.check_interval < os.time() then | 	if light_rain.last_check + light_rain.check_interval < os.time() then | ||||||
| 		light_rain.last_check = os.time() | 		light_rain.last_check = os.time() | ||||||
| 		if math.random() < 0.15 then | 		if math.random() < light_rain.chance then | ||||||
| 			return true | 			return true | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| @@ -57,15 +58,16 @@ end | |||||||
|  |  | ||||||
| local set_sky_box = function(player_name) | local set_sky_box = function(player_name) | ||||||
| 	local sl = {} | 	local sl = {} | ||||||
| 	sl.layer_type = skylayer.SKY_PLAIN |  | ||||||
| 	sl.name = SKYCOLOR_LAYER | 	sl.name = SKYCOLOR_LAYER | ||||||
| 	sl.data = {gradient_data={}} | 	sl.clouds_data = { | ||||||
| 	sl.data.gradient_data.colors = { | 		gradient_colors = { | ||||||
| 		{r=0, g=0, b=0}, | 			{r=50, g=50, b=50}, | ||||||
| 		{r=85, g=86, b=98}, | 			{r=120, g=120, b=120}, | ||||||
| 		{r=152, g=150, b=159}, | 			{r=200, g=200, b=200}, | ||||||
| 		{r=85, g=86, b=98}, | 			{r=120, g=120, b=120}, | ||||||
| 		{r=0, g=0, b=0} | 			{r=50, g=50, b=50} | ||||||
|  | 		}, | ||||||
|  | 		density = 0.6 | ||||||
| 	} | 	} | ||||||
| 	skylayer.add_layer(player_name, sl) | 	skylayer.add_layer(player_name, sl) | ||||||
| end | end | ||||||
| @@ -83,7 +85,7 @@ local remove_rain_sound = function(player) | |||||||
| 	if sound ~= nil then | 	if sound ~= nil then | ||||||
| 		minetest.sound_stop(sound) | 		minetest.sound_stop(sound) | ||||||
| 		sound_handlers[player:get_player_name()] = nil | 		sound_handlers[player:get_player_name()] = nil | ||||||
|   	end | 	end | ||||||
| end | end | ||||||
|  |  | ||||||
| light_rain.add_player = function(player) | light_rain.add_player = function(player) | ||||||
| @@ -98,16 +100,10 @@ end | |||||||
|  |  | ||||||
| -- Random texture getter | -- Random texture getter | ||||||
| local choice_random_rain_drop_texture = function() | local choice_random_rain_drop_texture = function() | ||||||
| 	local texture_name | 	local base_name = "happy_weather_light_rain_raindrop_" | ||||||
| 	local random_number = math.random() | 	local number = math.random(1, 4) | ||||||
| 	if random_number > 0.33 then | 	local extension = ".png" | ||||||
| 		texture_name = "happy_weather_light_rain_raindrop_1.png" | 	return base_name .. number .. extension | ||||||
| 	elseif random_number > 0.66 then |  | ||||||
| 		texture_name = "happy_weather_light_rain_raindrop_2.png" |  | ||||||
| 	else |  | ||||||
| 		texture_name = "happy_weather_light_rain_raindrop_3.png" |  | ||||||
| 	end |  | ||||||
| 	return texture_name; |  | ||||||
| end | end | ||||||
|  |  | ||||||
| local add_rain_particle = function(player) | local add_rain_particle = function(player) | ||||||
| @@ -121,16 +117,16 @@ local add_rain_particle = function(player) | |||||||
|  |  | ||||||
| 	if hw_utils.is_outdoor(random_pos) then | 	if hw_utils.is_outdoor(random_pos) then | ||||||
| 		minetest.add_particle({ | 		minetest.add_particle({ | ||||||
| 		  pos = {x=random_pos.x, y=random_pos.y, z=random_pos.z}, | 			pos = {x=random_pos.x, y=random_pos.y, z=random_pos.z}, | ||||||
| 		  velocity = {x=0, y=-10, z=0}, | 			velocity = {x=0, y=-10, z=0}, | ||||||
| 		  acceleration = {x=0, y=-30, z=0}, | 			acceleration = {x=0, y=-30, z=0}, | ||||||
| 		  expirationtime = 2, | 			expirationtime = 2, | ||||||
| 		  size = math.random(0.5, 3), | 			size = math.random(0.5, 3), | ||||||
| 		  collisiondetection = true, | 			collisiondetection = true, | ||||||
| 		  collision_removal = true, | 			collision_removal = true, | ||||||
| 		  vertical = true, | 			vertical = true, | ||||||
| 		  texture = choice_random_rain_drop_texture(), | 			texture = choice_random_rain_drop_texture(), | ||||||
| 		  playername = player:get_player_name() | 			playername = player:get_player_name() | ||||||
| 		}) | 		}) | ||||||
| 	end | 	end | ||||||
| end | end | ||||||
| @@ -149,7 +145,7 @@ light_rain.in_area = function(position) | |||||||
| 		return false | 		return false | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	if position.y > -10 then | 	if position.y > -10 and position.y < 120 then | ||||||
| 		return true | 		return true | ||||||
| 	end | 	end | ||||||
| 	return false | 	return false | ||||||
|   | |||||||
							
								
								
									
										102
									
								
								rain.lua
									
									
									
									
									
								
							
							
						
						
									
										102
									
								
								rain.lua
									
									
									
									
									
								
							| @@ -9,6 +9,7 @@ | |||||||
| local rain = {} | local rain = {} | ||||||
| rain.last_check = 0 | rain.last_check = 0 | ||||||
| rain.check_interval = 300 | rain.check_interval = 300 | ||||||
|  | rain.chance = 0.1 | ||||||
|  |  | ||||||
| -- Weather identification code | -- Weather identification code | ||||||
| rain.code = "rain" | rain.code = "rain" | ||||||
| @@ -24,14 +25,14 @@ local manual_trigger_end = false | |||||||
| local SKYCOLOR_LAYER = "happy_weather_rain_sky" | local SKYCOLOR_LAYER = "happy_weather_rain_sky" | ||||||
|  |  | ||||||
| rain.is_starting = function(dtime, position) | rain.is_starting = function(dtime, position) | ||||||
|   if rain.last_check + rain.check_interval < os.time() then | 	if rain.last_check + rain.check_interval < os.time() then | ||||||
|     rain.last_check = os.time() | 		rain.last_check = os.time() | ||||||
|     if math.random() < 0.1 then | 		if math.random() < rain.chance then | ||||||
|       happy_weather.request_to_end("light_rain") | 			happy_weather.request_to_end("light_rain") | ||||||
|       happy_weather.request_to_end("heavy_rain") | 			happy_weather.request_to_end("heavy_rain") | ||||||
|       return true | 			return true | ||||||
|     end | 		end | ||||||
|   end | 	end | ||||||
|  |  | ||||||
| 	if manual_trigger_start then | 	if manual_trigger_start then | ||||||
| 		manual_trigger_start = false | 		manual_trigger_start = false | ||||||
| @@ -42,13 +43,13 @@ rain.is_starting = function(dtime, position) | |||||||
| end | end | ||||||
|  |  | ||||||
| rain.is_ending = function(dtime) | rain.is_ending = function(dtime) | ||||||
|   if rain.last_check + rain.check_interval < os.time() then | 	if rain.last_check + rain.check_interval < os.time() then | ||||||
|     rain.last_check = os.time() | 		rain.last_check = os.time() | ||||||
|     if math.random() < 0.6 then | 		if math.random() < 0.6 then | ||||||
|       happy_weather.request_to_start("light_rain") | 			happy_weather.request_to_start("light_rain") | ||||||
|       return true | 			return true | ||||||
|     end | 		end | ||||||
|   end | 	end | ||||||
|  |  | ||||||
| 	if manual_trigger_end then | 	if manual_trigger_end then | ||||||
| 		manual_trigger_end = false | 		manual_trigger_end = false | ||||||
| @@ -62,13 +63,24 @@ local set_sky_box = function(player_name) | |||||||
| 	local sl = {} | 	local sl = {} | ||||||
| 	sl.layer_type = skylayer.SKY_PLAIN | 	sl.layer_type = skylayer.SKY_PLAIN | ||||||
| 	sl.name = SKYCOLOR_LAYER | 	sl.name = SKYCOLOR_LAYER | ||||||
| 	sl.data = {gradient_data={}} | 	sl.sky_data = { | ||||||
| 	sl.data.gradient_data.colors = { | 		gradient_colors = { | ||||||
| 		{r=0, g=0, b=0}, | 			{r=0, g=0, b=0}, | ||||||
| 		{r=85, g=86, b=98}, | 			{r=65, g=66, b=78}, | ||||||
| 		{r=152, g=150, b=159}, | 			{r=112, g=110, b=119}, | ||||||
| 		{r=85, g=86, b=98}, | 			{r=65, g=66, b=78}, | ||||||
| 		{r=0, g=0, b=0} | 			{r=0, g=0, b=0} | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	sl.clouds_data = { | ||||||
|  | 		gradient_colors = { | ||||||
|  | 			{r=10, g=10, b=10}, | ||||||
|  | 			{r=55, g=56, b=68}, | ||||||
|  | 			{r=102, g=100, b=109}, | ||||||
|  | 			{r=55, g=56, b=68}, | ||||||
|  | 			{r=10, g=10, b=10} | ||||||
|  | 		}, | ||||||
|  | 		density = 0.5 | ||||||
| 	} | 	} | ||||||
| 	skylayer.add_layer(player_name, sl) | 	skylayer.add_layer(player_name, sl) | ||||||
| end | end | ||||||
| @@ -86,7 +98,7 @@ local remove_rain_sound = function(player) | |||||||
| 	if sound ~= nil then | 	if sound ~= nil then | ||||||
| 		minetest.sound_stop(sound) | 		minetest.sound_stop(sound) | ||||||
| 		sound_handlers[player:get_player_name()] = nil | 		sound_handlers[player:get_player_name()] = nil | ||||||
|   	end | 	end | ||||||
| end | end | ||||||
|  |  | ||||||
| rain.add_player = function(player) | rain.add_player = function(player) | ||||||
| @@ -101,16 +113,10 @@ end | |||||||
|  |  | ||||||
| -- Random texture getter | -- Random texture getter | ||||||
| local choice_random_rain_drop_texture = function() | local choice_random_rain_drop_texture = function() | ||||||
| 	local texture_name | 	local base_name = "happy_weather_light_rain_raindrop_" | ||||||
| 	local random_number = math.random() | 	local number = math.random(1, 4) | ||||||
|   if random_number > 0.33 then | 	local extension = ".png" | ||||||
|     texture_name = "happy_weather_light_rain_raindrop_1.png" | 	return base_name .. number .. extension | ||||||
|   elseif random_number > 0.66 then |  | ||||||
|     texture_name = "happy_weather_light_rain_raindrop_2.png" |  | ||||||
|   else |  | ||||||
|     texture_name = "happy_weather_light_rain_raindrop_3.png" |  | ||||||
|   end |  | ||||||
| 	return texture_name; |  | ||||||
| end | end | ||||||
|  |  | ||||||
| local add_rain_particle = function(player) | local add_rain_particle = function(player) | ||||||
| @@ -124,16 +130,16 @@ local add_rain_particle = function(player) | |||||||
|  |  | ||||||
| 	if hw_utils.is_outdoor(random_pos) then | 	if hw_utils.is_outdoor(random_pos) then | ||||||
| 		minetest.add_particle({ | 		minetest.add_particle({ | ||||||
| 		  pos = {x=random_pos.x, y=random_pos.y, z=random_pos.z}, | 			pos = {x=random_pos.x, y=random_pos.y, z=random_pos.z}, | ||||||
| 		  velocity = {x=0, y=-15, z=0}, | 			velocity = {x=0, y=-15, z=0}, | ||||||
| 		  acceleration = {x=0, y=-35, z=0}, | 			acceleration = {x=0, y=-35, z=0}, | ||||||
| 		  expirationtime = 2, | 			expirationtime = 2, | ||||||
| 		  size = math.random(1, 6), | 			size = math.random(1, 4), | ||||||
| 		  collisiondetection = true, | 			collisiondetection = true, | ||||||
| 		  collision_removal = true, | 			collision_removal = true, | ||||||
| 		  vertical = true, | 			vertical = true, | ||||||
| 		  texture = choice_random_rain_drop_texture(), | 			texture = choice_random_rain_drop_texture(), | ||||||
| 		  playername = player:get_player_name() | 			playername = player:get_player_name() | ||||||
| 		}) | 		}) | ||||||
| 	end | 	end | ||||||
| end | end | ||||||
| @@ -147,12 +153,12 @@ local display_rain_particles = function(player) | |||||||
| end | end | ||||||
|  |  | ||||||
| rain.in_area = function(position) | rain.in_area = function(position) | ||||||
|   if hw_utils.is_biome_frozen(position) or  | 	if hw_utils.is_biome_frozen(position) or  | ||||||
|     hw_utils.is_biome_dry(position) then | 		hw_utils.is_biome_dry(position) then | ||||||
|     return false | 		return false | ||||||
|   end | 	end | ||||||
|  |  | ||||||
| 	if position.y > -10 then | 	if position.y > -10 and position.y < 120 then | ||||||
| 		return true | 		return true | ||||||
| 	end | 	end | ||||||
| 	return false | 	return false | ||||||
|   | |||||||
							
								
								
									
										77
									
								
								snow.lua
									
									
									
									
									
								
							
							
						
						
									
										77
									
								
								snow.lua
									
									
									
									
									
								
							| @@ -9,6 +9,7 @@ | |||||||
| local snow = {} | local snow = {} | ||||||
| snow.last_check = 0 | snow.last_check = 0 | ||||||
| snow.check_interval = 200 | snow.check_interval = 200 | ||||||
|  | snow.chance = 0.2 | ||||||
|  |  | ||||||
| -- Weather identification code | -- Weather identification code | ||||||
| snow.code = "snow" | snow.code = "snow" | ||||||
| @@ -21,12 +22,12 @@ local manual_trigger_end = false | |||||||
| local SKYCOLOR_LAYER = "happy_weather_snow_sky" | local SKYCOLOR_LAYER = "happy_weather_snow_sky" | ||||||
|  |  | ||||||
| snow.is_starting = function(dtime, position) | snow.is_starting = function(dtime, position) | ||||||
|   if snow.last_check + snow.check_interval < os.time() then | 	if snow.last_check + snow.check_interval < os.time() then | ||||||
|     snow.last_check = os.time() | 		snow.last_check = os.time() | ||||||
|     if math.random() < 0.2 then | 		if math.random() < snow.chance then | ||||||
|       return true | 			return true | ||||||
|     end | 		end | ||||||
|   end | 	end | ||||||
|  |  | ||||||
| 	if manual_trigger_start then | 	if manual_trigger_start then | ||||||
| 		manual_trigger_start = false | 		manual_trigger_start = false | ||||||
| @@ -37,12 +38,12 @@ snow.is_starting = function(dtime, position) | |||||||
| end | end | ||||||
|  |  | ||||||
| snow.is_ending = function(dtime) | snow.is_ending = function(dtime) | ||||||
|   if snow.last_check + snow.check_interval < os.time() then | 	if snow.last_check + snow.check_interval < os.time() then | ||||||
|     snow.last_check = os.time() | 		snow.last_check = os.time() | ||||||
|     if math.random() < 0.5 then | 		if math.random() < 0.5 then | ||||||
|       return true | 			return true | ||||||
|     end | 		end | ||||||
|   end | 	end | ||||||
|  |  | ||||||
| 	if manual_trigger_end then | 	if manual_trigger_end then | ||||||
| 		manual_trigger_end = false | 		manual_trigger_end = false | ||||||
| @@ -54,13 +55,13 @@ end | |||||||
|  |  | ||||||
| local set_sky_box = function(player_name) | local set_sky_box = function(player_name) | ||||||
| 	local sl = {} | 	local sl = {} | ||||||
| 	sl.layer_type = skylayer.SKY_PLAIN |  | ||||||
| 	sl.name = SKYCOLOR_LAYER | 	sl.name = SKYCOLOR_LAYER | ||||||
| 	sl.data = {gradient_data={}} | 	sl.sky_data = { | ||||||
| 	sl.data.gradient_data.colors = { | 		gradient_colors = { | ||||||
| 		{r=0, g=0, b=0}, | 			{r=0, g=0, b=0}, | ||||||
| 		{r=241, g=244, b=249}, | 			{r=231, g=234, b=239}, | ||||||
| 		{r=0, g=0, b=0} | 			{r=0, g=0, b=0} | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	skylayer.add_layer(player_name, sl) | 	skylayer.add_layer(player_name, sl) | ||||||
| end | end | ||||||
| @@ -75,16 +76,10 @@ end | |||||||
|  |  | ||||||
| -- Random texture getter | -- Random texture getter | ||||||
| local choice_random_rain_drop_texture = function() | local choice_random_rain_drop_texture = function() | ||||||
| 	local texture_name | 	local base_name = "happy_weather_light_snow_snowflake_" | ||||||
| 	local random_number = math.random() | 	local number = math.random(1, 3) | ||||||
| 	if random_number > 0.33 then | 	local extension = ".png" | ||||||
| 		texture_name = "happy_weather_light_snow_snowflake_1.png" | 	return base_name .. number .. extension | ||||||
| 	elseif random_number > 0.66 then |  | ||||||
| 		texture_name = "happy_weather_light_snow_snowflake_2.png" |  | ||||||
| 	else |  | ||||||
| 		texture_name = "happy_weather_light_snow_snowflake_3.png" |  | ||||||
| 	end |  | ||||||
| 	return texture_name; |  | ||||||
| end | end | ||||||
|  |  | ||||||
| local add_particle = function(player) | local add_particle = function(player) | ||||||
| @@ -100,9 +95,9 @@ local add_particle = function(player) | |||||||
| 		minetest.add_particle({ | 		minetest.add_particle({ | ||||||
| 			pos = {x=random_pos.x, y=random_pos.y, z=random_pos.z}, | 			pos = {x=random_pos.x, y=random_pos.y, z=random_pos.z}, | ||||||
| 			velocity = {x = math.random(-1,-0.5), y = math.random(-2,-1), z = math.random(-1,-0.5)}, | 			velocity = {x = math.random(-1,-0.5), y = math.random(-2,-1), z = math.random(-1,-0.5)}, | ||||||
|         	acceleration = {x = math.random(-1,-0.5), y=-0.5, z = math.random(-1,-0.5)}, | 			acceleration = {x = math.random(-1,-0.5), y=-0.5, z = math.random(-1,-0.5)}, | ||||||
|         	expirationtime = 2.0, | 			expirationtime = 2.0, | ||||||
|         	size = math.random(0.5, 2), | 			size = math.random(0.5, 2), | ||||||
| 			collisiondetection = true, | 			collisiondetection = true, | ||||||
| 			collision_removal = true, | 			collision_removal = true, | ||||||
| 			vertical = true, | 			vertical = true, | ||||||
| @@ -122,20 +117,20 @@ end | |||||||
|  |  | ||||||
| local particles_number_per_update = 10 | local particles_number_per_update = 10 | ||||||
| snow.render = function(dtime, player) | snow.render = function(dtime, player) | ||||||
|   for i=particles_number_per_update, 1,-1 do | 	for i=particles_number_per_update, 1,-1 do | ||||||
|     display_particles(player) | 		display_particles(player) | ||||||
|   end | 	end | ||||||
| end | end | ||||||
|  |  | ||||||
| snow.in_area = function(position) | snow.in_area = function(position) | ||||||
|   if hw_utils.is_biome_frozen(position) == false then | 	if hw_utils.is_biome_frozen(position) == false then | ||||||
|     return false | 		return false | ||||||
|   end | 	end | ||||||
|  |  | ||||||
|   if position.y > -10 then | 	if position.y > -10 and position.y < 120 then | ||||||
|     return true | 		return true | ||||||
|   end | 	end | ||||||
|   return false | 	return false | ||||||
| end | end | ||||||
|  |  | ||||||
| snow.start = function() | snow.start = function() | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								textures/happy_weather_light_rain_raindrop_4.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								textures/happy_weather_light_rain_raindrop_4.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 256 B | 
| @@ -11,6 +11,7 @@ | |||||||
| local thunder = {} | local thunder = {} | ||||||
| thunder.last_check = 0 | thunder.last_check = 0 | ||||||
| thunder.check_interval = 100 | thunder.check_interval = 100 | ||||||
|  | thunder.chance = 0.8 | ||||||
|  |  | ||||||
| -- Weather identification code | -- Weather identification code | ||||||
| thunder.code = "thunder" | thunder.code = "thunder" | ||||||
| @@ -33,7 +34,7 @@ thunder.is_starting = function(dtime) | |||||||
|  |  | ||||||
| 	if thunder.last_check + thunder.check_interval < os.time() then | 	if thunder.last_check + thunder.check_interval < os.time() then | ||||||
| 		thunder.last_check = os.time() | 		thunder.last_check = os.time() | ||||||
| 		if math.random() < 0.8 and happy_weather.is_weather_active("heavy_rain") then | 		if math.random() < thunder.chance and happy_weather.is_weather_active("heavy_rain") then | ||||||
| 			return true | 			return true | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| @@ -68,8 +69,8 @@ local calculate_thunder_strike_delay = function() | |||||||
| end | end | ||||||
|  |  | ||||||
| thunder.render = function(dtime, player) | thunder.render = function(dtime, player) | ||||||
| 	if happy_weather.is_player_in_weather_area(player:get_player_name(),  | 	local player_name = player:get_player_name() | ||||||
| 		"heavy_rain") == false then | 	if happy_weather.is_player_in_weather_area(player_name, "heavy_rain") == false then | ||||||
| 		return | 		return | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										205
									
								
								utils.lua
									
									
									
									
									
								
							
							
						
						
									
										205
									
								
								utils.lua
									
									
									
									
									
								
							| @@ -6,10 +6,12 @@ | |||||||
| -- Credits: xeranas | -- Credits: xeranas | ||||||
| --------------------------------------- | --------------------------------------- | ||||||
|  |  | ||||||
| if hw_utils == nil then | if not minetest.global_exists("hw_utils") then | ||||||
| 	hw_utils = {} | 	hw_utils = {} | ||||||
| end | end | ||||||
|  |  | ||||||
|  | local mg_name = minetest.get_mapgen_setting("mg_name") | ||||||
|  |  | ||||||
| -- outdoor check based on node light level | -- outdoor check based on node light level | ||||||
| hw_utils.is_outdoor = function(pos, offset_y) | hw_utils.is_outdoor = function(pos, offset_y) | ||||||
| 	if offset_y == nil then | 	if offset_y == nil then | ||||||
| @@ -25,105 +27,154 @@ end | |||||||
| -- checks if player is undewater. This is needed in order to | -- checks if player is undewater. This is needed in order to | ||||||
| -- turn off weather particles generation. | -- turn off weather particles generation. | ||||||
| hw_utils.is_underwater = function(player) | hw_utils.is_underwater = function(player) | ||||||
|     local ppos = player:getpos() | 	local ppos = player:getpos() | ||||||
|     local offset = player:get_eye_offset() | 	local offset = player:get_eye_offset() | ||||||
|     local player_eye_pos = {x = ppos.x + offset.x,  | 	local player_eye_pos = { | ||||||
|                             y = ppos.y + offset.y + 1.5,  | 		x = ppos.x + offset.x,  | ||||||
|                             z = ppos.z + offset.z} | 		y = ppos.y + offset.y + 1.5,  | ||||||
|     local node_level = minetest.get_node_level(player_eye_pos) | 		z = ppos.z + offset.z} | ||||||
|     if node_level == 8 or node_level == 7 then | 	local node_level = minetest.get_node_level(player_eye_pos) | ||||||
|       return true | 	if node_level == 8 or node_level == 7 then | ||||||
|     end | 		return true | ||||||
|     return false | 	end | ||||||
|  | 	return false | ||||||
| end | end | ||||||
|  |  | ||||||
| -- trying to locate position for particles by player look direction for performance reason. | -- trying to locate position for particles by player look direction for performance reason. | ||||||
| -- it is costly to generate many particles around player so goal is focus mainly on front view.   | -- it is costly to generate many particles around player so goal is focus mainly on front view.   | ||||||
| hw_utils.get_random_pos = function(player, offset) | hw_utils.get_random_pos = function(player, offset) | ||||||
|   local look_dir = player:get_look_dir() | 	local look_dir = player:get_look_dir() | ||||||
|   local player_pos = player:getpos() | 	local player_pos = player:getpos() | ||||||
|  |  | ||||||
|   local random_pos_x = 0 | 	local random_pos_x = 0 | ||||||
|   local random_pos_y = 0 | 	local random_pos_y = 0 | ||||||
|   local random_pos_z = 0 | 	local random_pos_z = 0 | ||||||
|  |  | ||||||
|   if look_dir.x > 0 then | 	if look_dir.x > 0 then | ||||||
|     if look_dir.z > 0 then | 		if look_dir.z > 0 then | ||||||
|       random_pos_x = math.random(player_pos.x - offset.back, player_pos.x + offset.front) + math.random() | 			random_pos_x = math.random(player_pos.x - offset.back, player_pos.x + offset.front) + math.random() | ||||||
|       random_pos_z = math.random(player_pos.z - offset.back, player_pos.z + offset.front) + math.random()  | 			random_pos_z = math.random(player_pos.z - offset.back, player_pos.z + offset.front) + math.random()  | ||||||
|     else | 		else | ||||||
|       random_pos_x = math.random(player_pos.x - offset.back, player_pos.x + offset.front) + math.random() | 			random_pos_x = math.random(player_pos.x - offset.back, player_pos.x + offset.front) + math.random() | ||||||
|       random_pos_z = math.random(player_pos.z - offset.front, player_pos.z + offset.back) + math.random() | 			random_pos_z = math.random(player_pos.z - offset.front, player_pos.z + offset.back) + math.random() | ||||||
|     end | 		end | ||||||
|   else | 	else | ||||||
|     if look_dir.z > 0 then | 		if look_dir.z > 0 then | ||||||
|       random_pos_x = math.random(player_pos.x - offset.front, player_pos.x + offset.back) + math.random() | 			random_pos_x = math.random(player_pos.x - offset.front, player_pos.x + offset.back) + math.random() | ||||||
|       random_pos_z = math.random(player_pos.z - offset.back, player_pos.z + offset.front) + math.random() | 			random_pos_z = math.random(player_pos.z - offset.back, player_pos.z + offset.front) + math.random() | ||||||
|     else | 		else | ||||||
|       random_pos_x = math.random(player_pos.x - offset.front, player_pos.x + offset.back) + math.random() | 			random_pos_x = math.random(player_pos.x - offset.front, player_pos.x + offset.back) + math.random() | ||||||
|       random_pos_z = math.random(player_pos.z - offset.front, player_pos.z + offset.back) + math.random() | 			random_pos_z = math.random(player_pos.z - offset.front, player_pos.z + offset.back) + math.random() | ||||||
|     end | 		end | ||||||
|   end | 	end | ||||||
|  |  | ||||||
|   if offset.bottom ~= nil then | 	if offset.bottom ~= nil then | ||||||
|   	random_pos_y = math.random(player_pos.y - offset.bottom, player_pos.y + offset.top) | 		random_pos_y = math.random(player_pos.y - offset.bottom, player_pos.y + offset.top) | ||||||
|   else | 	else | ||||||
|   	random_pos_y = player_pos.y + offset.top | 		random_pos_y = player_pos.y + offset.top | ||||||
|   end | 	end | ||||||
|  |  | ||||||
|    | 	return {x=random_pos_x, y=random_pos_y, z=random_pos_z} | ||||||
|   return {x=random_pos_x, y=random_pos_y, z=random_pos_z} |  | ||||||
| end | end | ||||||
|  |  | ||||||
| local np_temp = { | local np_temp = { | ||||||
|   offset = 50, | 	offset = 50, | ||||||
|   scale = 50, | 	scale = 50, | ||||||
|   spread = {x = 1000, y = 1000, z = 1000}, | 	spread = {x = 1000, y = 1000, z = 1000}, | ||||||
|   seed = 5349, | 	seed = 5349, | ||||||
|   octaves = 3, | 	octaves = 3, | ||||||
|   persist = 0.5, | 	persist = 0.5, | ||||||
|   lacunarity = 2.0 | 	lacunarity = 2.0 | ||||||
| } | } | ||||||
|  |  | ||||||
| local np_humid = { | local np_humid = { | ||||||
|   offset = 50, | 	offset = 50, | ||||||
|   scale = 50, | 	scale = 50, | ||||||
|   spread = {x = 1000, y = 1000, z = 1000}, | 	spread = {x = 1000, y = 1000, z = 1000}, | ||||||
|   seed = 842, | 	seed = 842, | ||||||
|   octaves = 3, | 	octaves = 3, | ||||||
|   persist = 0.5, | 	persist = 0.5, | ||||||
|   lacunarity = 2.0 | 	lacunarity = 2.0 | ||||||
| } | } | ||||||
|  |  | ||||||
| hw_utils.is_biome_frozen = function(position) | local np_biome_v6 = { | ||||||
|   local posx = math.floor(position.x) | 	offset = 0,  | ||||||
|   local posz = math.floor(position.z) | 	scale = 1.0, | ||||||
|   local noise_obj = minetest.get_perlin(np_temp) | 	spread = {x = 500.0, y = 500.0, z = 500.0}, | ||||||
|   local noise_temp = noise_obj:get2d({x = posx, y = posz}) | 	seed = 9130, | ||||||
|  | 	octaves = 3, | ||||||
|  | 	persist = 0.50, | ||||||
|  | 	lacunarity = 2.0 | ||||||
|  | } | ||||||
|  |  | ||||||
|   -- below 35 heat biome considered to be frozen type | local np_humidity_v6 = { | ||||||
|   return noise_temp < 35 | 	offset = 0.5, | ||||||
|  | 	scale = 0.5, | ||||||
|  | 	spread = {x = 500.0, y = 500.0, z = 500.0}, | ||||||
|  | 	seed = 72384, | ||||||
|  | 	octaves = 4, | ||||||
|  | 	persist = 0.66, | ||||||
|  | 	lacunarity = 2.0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | local is_biome_frozen = function(position) | ||||||
|  | 	local posx = math.floor(position.x) | ||||||
|  | 	local posz = math.floor(position.z) | ||||||
|  | 	local noise_obj = minetest.get_perlin(np_temp) | ||||||
|  | 	local noise_temp = noise_obj:get2d({x = posx, y = posz}) | ||||||
|  |  | ||||||
|  | 	-- below 35 heat biome considered to be frozen type | ||||||
|  | 	return noise_temp < 35 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | hw_utils.is_biome_frozen = function(position) | ||||||
|  | 	if mg_name == "v6" then | ||||||
|  | 		return false -- v6 not supported yet. | ||||||
|  | 	end | ||||||
|  | 	return is_biome_frozen(position) | ||||||
|  | end | ||||||
|  |  | ||||||
|  | local is_biome_dry_v6 = function(position) | ||||||
|  | 	local posx = math.floor(position.x) | ||||||
|  | 	local posz = math.floor(position.z) | ||||||
|  | 	local noise_obj = minetest.get_perlin(np_biome_v6) | ||||||
|  | 	local noise_biome = noise_obj:get2d({x = posx, y = posz}) | ||||||
|  | 	-- TODO futher investigation needed towards on biome check for v6 mapgen | ||||||
|  | 	return noise_biome > 0.45 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | local is_biome_dry = function(position) | ||||||
|  | 	local posx = math.floor(position.x) | ||||||
|  | 	local posz = math.floor(position.z) | ||||||
|  | 	local noise_obj = minetest.get_perlin(np_humid) | ||||||
|  | 	local noise_humid = noise_obj:get2d({x = posx, y = posz}) | ||||||
|  |  | ||||||
|  | 	-- below 50 humid biome considered to be dry type (at least by this mod) | ||||||
|  | 	return noise_humid < 50 | ||||||
| end | end | ||||||
|  |  | ||||||
| hw_utils.is_biome_dry = function(position) | hw_utils.is_biome_dry = function(position) | ||||||
|   local posx = math.floor(position.x) | 	if mg_name == "v6" then | ||||||
|   local posz = math.floor(position.z) | 		return false | ||||||
|   local noise_obj = minetest.get_perlin(np_humid) | 	end | ||||||
|   local noise_humid = noise_obj:get2d({x = posx, y = posz}) | 	return is_biome_dry(position) | ||||||
|  | end | ||||||
|  |  | ||||||
|   -- below 50 humid biome considered to be dry type (at least by this mod) | local is_biome_tropic = function(position) | ||||||
|   return noise_humid < 50 | 	local posx = math.floor(position.x) | ||||||
|  | 	local posz = math.floor(position.z) | ||||||
|  | 	local noise_obj = minetest.get_perlin(np_humid) | ||||||
|  | 	local noise_humid = noise_obj:get2d({x = posx, y = posz}) | ||||||
|  | 	noise_obj = minetest.get_perlin(np_temp) | ||||||
|  | 	local noise_temp = noise_obj:get2d({x = posx, y = posz}) | ||||||
|  |  | ||||||
|  | 	-- humid and temp values are taked by testing flying around world (not sure actually) | ||||||
|  | 	return noise_humid > 55 and noise_temp > 80 | ||||||
| end | end | ||||||
|  |  | ||||||
| hw_utils.is_biome_tropic = function(position) | hw_utils.is_biome_tropic = function(position) | ||||||
|   local posx = math.floor(position.x) | 	if mg_name == "v6" then | ||||||
|   local posz = math.floor(position.z) | 		return false -- v6 not supported yet. | ||||||
|   local noise_obj = minetest.get_perlin(np_humid) | 	end | ||||||
|   local noise_humid = noise_obj:get2d({x = posx, y = posz}) | 	return is_biome_tropic(position) | ||||||
|   noise_obj = minetest.get_perlin(np_temp) |  | ||||||
|   local noise_temp = noise_obj:get2d({x = posx, y = posz}) |  | ||||||
|  |  | ||||||
|   -- humid and temp values are taked by testing flying around world (not sure actually) |  | ||||||
|   return noise_humid > 55 and noise_temp > 80 |  | ||||||
| end | end | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user