mirror of
				https://gitlab.com/rautars/weather_pack.git
				synced 2025-10-31 16:45:23 +01:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			master
			...
			def185bb40
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | def185bb40 | 
| @@ -4,8 +4,8 @@ Weather mod for Minetest (http://minetest.net/) | ||||
|  | ||||
| Feedback and Improvements | ||||
| ----------------------- | ||||
| * See newest version at https://gitlab.com/zombiebot/weather_pack | ||||
| * Register bugs at https://gitlab.com/zombiebot/weather_pack/issues | ||||
| * 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 | ||||
|   | ||||
| @@ -11,7 +11,6 @@ happy_weather = {} | ||||
| -- Local variables which helps organize active and deactive weahers | ||||
| local registered_weathers = {} | ||||
| local active_weathers = {} | ||||
| local meta_plawpos = {} -- meta about Player Last Active Weaher Position | ||||
| 
 | ||||
| ------------------------------------ | ||||
| -- Local helper / utility methods -- | ||||
| @@ -80,44 +79,6 @@ local is_player_affected = function(affected_players, player_name) | ||||
| 	end | ||||
| end | ||||
| 
 | ||||
| 
 | ||||
| local remove_meta_plawpos = function(weather_code, player_name) | ||||
| 	if #meta_plawpos == 0 then | ||||
| 		return | ||||
| 	end | ||||
| 
 | ||||
| 	for k, meta_ in ipairs(meta_plawpos) do | ||||
| 		if (meta_.name == player_name and meta_.code == weather_code) then | ||||
| 			table.remove(meta_plawpos, k) | ||||
| 		end | ||||
| 	end | ||||
| end | ||||
| 
 | ||||
| local add_meta_plawpos = function(weather_code, player) | ||||
| 	local meta = {} | ||||
| 	meta.code = weather_code | ||||
| 	meta.pos = player:getpos() | ||||
| 	meta.name = player:get_player_name() | ||||
| 	 | ||||
| 	remove_meta_plawpos(weather_code, player:get_player_name()) | ||||
| 	table.insert(meta_plawpos, meta) | ||||
| end | ||||
| 
 | ||||
| local get_meta_plawpos = function(weather_code, player_name) | ||||
| 	if #meta_plawpos == 0 then | ||||
| 		return nil | ||||
| 	end | ||||
| 
 | ||||
| 	for k, meta_ in ipairs(meta_plawpos) do | ||||
| 		if (meta_.name == player_name and meta_.code == weather_code) then | ||||
| 			return meta_.pos | ||||
| 		end | ||||
| 	end | ||||
| 
 | ||||
| 	return nil | ||||
| end | ||||
| 
 | ||||
| 
 | ||||
| --------------------------- | ||||
| -- Weather API functions -- | ||||
| --------------------------- | ||||
| @@ -218,7 +179,7 @@ local weather_remove_player = function(weather_obj, player) | ||||
| 	weather_obj.remove_player(player) | ||||
| end | ||||
| 
 | ||||
| -- Weather in_area method nil-safe wrapper | ||||
| -- Weather remove_player method nil-safe wrapper | ||||
| local weather_in_area = function(weather_obj, position) | ||||
| 	if weather_obj.in_area == nil then | ||||
| 		return true | ||||
| @@ -263,36 +224,14 @@ local prepare_starting = function(weather_obj) | ||||
| 	add_active_weather(weather_obj) | ||||
| end | ||||
| 
 | ||||
| local MAX_DISTANCE_FROM_WEATHER = 35 | ||||
| 
 | ||||
| -- This function aims to remove weather flickering effect when player walks on biome edge. | ||||
| -- To accomlish that extra distance is applied before removing player from weather affection. | ||||
| local is_outside_recent_weather = function(weather_code, player) | ||||
| 	local pos = get_meta_plawpos(weather_code, player:get_player_name()) | ||||
| 	if pos == nil then | ||||
| 		return false | ||||
| 	end | ||||
| 
 | ||||
| 	local ppos = player:getpos() | ||||
| 	local d = ((ppos.x - pos.x)^2 + (ppos.y - pos.y)^2 + (ppos.z - pos.z)^2)^0.5 | ||||
| 	return MAX_DISTANCE_FROM_WEATHER - d < 0 | ||||
| end | ||||
| 
 | ||||
| 
 | ||||
| -- While still active weather can or can not affect players based on area they are | ||||
| local render_if_in_area = function(weather_obj, dtime, player) | ||||
| 	if is_player_affected(weather_obj.affected_players, player:get_player_name()) then | ||||
| 		if weather_in_area(weather_obj, player:getpos()) then | ||||
| 			weather_render(weather_obj, dtime, player) | ||||
| 			add_meta_plawpos(weather_obj.code, player) | ||||
| 		else | ||||
| 			if (is_outside_recent_weather(weather_obj.code, player)) then | ||||
| 				weather_remove_player(weather_obj, player) | ||||
| 				remove_player(weather_obj.affected_players, player:get_player_name()) | ||||
| 			-- render weather until player will be completely outside weather range | ||||
| 			else | ||||
| 				weather_render(weather_obj, dtime, player) | ||||
| 			end | ||||
| 			weather_remove_player(weather_obj, player) | ||||
| 			remove_player(weather_obj.affected_players, player:get_player_name()) | ||||
| 		end | ||||
| 	else | ||||
| 		if weather_in_area(weather_obj, player:getpos()) then | ||||
| @@ -326,7 +265,7 @@ minetest.register_globalstep(function(dtime) | ||||
| 
 | ||||
| 		-- Loop through connected players | ||||
| 		for ii, player in ipairs(minetest.get_connected_players()) do | ||||
| 
 | ||||
| 			 | ||||
| 			-- Weaher is active checking if it about to end | ||||
| 			if weather_.active then  | ||||
| 				if weather_is_ending(weather_, dtime) or deactivate_weather then | ||||
| @@ -341,7 +280,7 @@ minetest.register_globalstep(function(dtime) | ||||
| 
 | ||||
| 			-- Weaher is not active checking if it about to start | ||||
| 			else | ||||
| 				if weather_is_starting(weather_, dtime, player:getpos()) then | ||||
| 				if weather_.is_starting(dtime, player:getpos()) then | ||||
| 					activate_weather = true | ||||
| 				end | ||||
| 			end	 | ||||
							
								
								
									
										23
									
								
								init.lua
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								init.lua
									
									
									
									
									
								
							| @@ -2,35 +2,30 @@ local modpath = minetest.get_modpath("weather_pack"); | ||||
|  | ||||
| -- If skylayer mod not located then embeded version will be loaded. | ||||
| if minetest.get_modpath("skylayer") == nil then | ||||
| 	dofile(modpath.."/lib_sky_layer_api.lua") | ||||
| 	dofile(modpath.."/embedded_sky_layer_api.lua") | ||||
| end | ||||
|  | ||||
| -- If happy_weather_api mod not located then embeded version will be loaded. | ||||
| if minetest.get_modpath("happy_weather_api") == nil then | ||||
| 	dofile(modpath.."/lib_happy_weather_api.lua") | ||||
| 	dofile(modpath.."/embedded_happy_weather_api.lua") | ||||
| 	dofile(modpath.."/commands.lua") | ||||
| end | ||||
|  | ||||
| legacy_MT_version = false | ||||
| if minetest.get_humidity == nil then | ||||
| 	minetest.log("warning", "MOD [weather_pack]: Old Minetest version detected, some mod features will not work.") | ||||
| 	legacy_MT_version = true | ||||
| end | ||||
|  | ||||
| -- Happy Weather utilities | ||||
| dofile(modpath.."/utils.lua") | ||||
|  | ||||
| dofile(modpath.."/weathers/light_rain.lua") | ||||
| dofile(modpath.."/weathers/rain.lua") | ||||
| dofile(modpath.."/weathers/heavy_rain.lua") | ||||
| dofile(modpath.."/weathers/snow.lua") | ||||
| dofile(modpath.."/weathers/snowstorm.lua") | ||||
| dofile(modpath.."/light_rain.lua") | ||||
| dofile(modpath.."/rain.lua") | ||||
| dofile(modpath.."/heavy_rain.lua") | ||||
| dofile(modpath.."/snow.lua") | ||||
|  | ||||
| if minetest.get_modpath("lightning") ~= nil then | ||||
| 	dofile(modpath.."/weathers/thunder.lua") | ||||
| 	dofile(modpath.."/thunder.lua") | ||||
|  | ||||
| 	-- Turn off lightning mod 'auto mode' | ||||
| 	lightning.auto = false | ||||
| end | ||||
|  | ||||
| dofile(modpath.."/abm.lua") | ||||
|  | ||||
| minetest.log("action", "[weather_pack] loaded.") | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 97 KiB | 
							
								
								
									
										88
									
								
								utils.lua
									
									
									
									
									
								
							
							
						
						
									
										88
									
								
								utils.lua
									
									
									
									
									
								
							| @@ -77,29 +77,80 @@ hw_utils.get_random_pos = function(player, offset) | ||||
| 	return {x=random_pos_x, y=random_pos_y, z=random_pos_z} | ||||
| end | ||||
|  | ||||
| local np_temp = { | ||||
| 	offset = 50, | ||||
| 	scale = 50, | ||||
| 	spread = {x = 1000, y = 1000, z = 1000}, | ||||
| 	seed = 5349, | ||||
| 	octaves = 3, | ||||
| 	persist = 0.5, | ||||
| 	lacunarity = 2.0 | ||||
| } | ||||
|  | ||||
| local np_humid = { | ||||
| 	offset = 50, | ||||
| 	scale = 50, | ||||
| 	spread = {x = 1000, y = 1000, z = 1000}, | ||||
| 	seed = 842, | ||||
| 	octaves = 3, | ||||
| 	persist = 0.5, | ||||
| 	lacunarity = 2.0 | ||||
| } | ||||
|  | ||||
| local np_biome_v6 = { | ||||
| 	offset = 0,  | ||||
| 	scale = 1.0, | ||||
| 	spread = {x = 500.0, y = 500.0, z = 500.0}, | ||||
| 	seed = 9130, | ||||
| 	octaves = 3, | ||||
| 	persist = 0.50, | ||||
| 	lacunarity = 2.0 | ||||
| } | ||||
|  | ||||
| local np_humidity_v6 = { | ||||
| 	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) | ||||
| 	if legacy_MT_version then | ||||
| 		return false; | ||||
| 	end | ||||
| 	local heat = minetest.get_heat(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 heat < 35 | ||||
| 	return noise_temp < 35 | ||||
| end | ||||
|  | ||||
| hw_utils.is_biome_frozen = function(position) | ||||
| 	if mg_name == "v6" then | ||||
| 		return false -- v6 not supported. | ||||
| 		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) | ||||
| 	if legacy_MT_version then | ||||
| 		return false; | ||||
| 	end | ||||
| 	local humidity = minetest.get_humidity(position) | ||||
| 	local heat = minetest.get_heat(position) | ||||
| 	return humidity < 50 and heat > 65 | ||||
| 	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 | ||||
|  | ||||
| hw_utils.is_biome_dry = function(position) | ||||
| @@ -110,14 +161,15 @@ hw_utils.is_biome_dry = function(position) | ||||
| end | ||||
|  | ||||
| local is_biome_tropic = function(position) | ||||
| 	if legacy_MT_version then | ||||
| 		return false; | ||||
| 	end | ||||
| 	local humidity = minetest.get_humidity(position) | ||||
| 	local heat = minetest.get_heat(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}) | ||||
| 	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 humidity > 55 and heat > 70 | ||||
| 	return noise_humid > 55 and noise_temp > 80 | ||||
| end | ||||
|  | ||||
| hw_utils.is_biome_tropic = function(position) | ||||
|   | ||||
| @@ -1,203 +0,0 @@ | ||||
| ---------------------------- | ||||
| -- Happy Weather: Snowfall | ||||
|  | ||||
| -- License: MIT | ||||
|  | ||||
| -- Credits: xeranas | ||||
| ---------------------------- | ||||
|  | ||||
| local snowstorm = {} | ||||
|  | ||||
| -- Weather identification code | ||||
| snowstorm.code = "snowstorm" | ||||
| snowstorm.last_check = 0 | ||||
| snowstorm.check_interval = 300 | ||||
| snowstorm.chance = 0.05 | ||||
|  | ||||
| -- Keeps sound handler references | ||||
| local sound_handlers = {} | ||||
|  | ||||
| -- Manual triggers flags | ||||
| local manual_trigger_start = false | ||||
| local manual_trigger_end = false | ||||
|  | ||||
| -- Skycolor layer id | ||||
| local SKYCOLOR_LAYER = "happy_weather_snowstorm_sky" | ||||
|  | ||||
| local set_weather_sound = function(player)  | ||||
| 	return minetest.sound_play("happy_weather_snowstorm", { | ||||
| 		object = player, | ||||
| 		max_hear_distance = 2, | ||||
| 		loop = true, | ||||
| 	}) | ||||
| end | ||||
|  | ||||
| local remove_weather_sound = function(player) | ||||
| 	local sound = sound_handlers[player:get_player_name()] | ||||
| 	if sound ~= nil then | ||||
| 		minetest.sound_stop(sound) | ||||
| 		sound_handlers[player:get_player_name()] = nil | ||||
| 	end | ||||
| end | ||||
|  | ||||
| snowstorm.is_starting = function(dtime, position) | ||||
| 	if snowstorm.last_check + snowstorm.check_interval < os.time() then | ||||
| 		snowstorm.last_check = os.time() | ||||
| 		if math.random() < snowstorm.chance then | ||||
| 			return true | ||||
| 		end | ||||
| 	end | ||||
|  | ||||
| 	if manual_trigger_start then | ||||
| 		manual_trigger_start = false | ||||
| 		return true | ||||
| 	end | ||||
| 	 | ||||
| 	return false | ||||
| end | ||||
|  | ||||
| snowstorm.is_ending = function(dtime) | ||||
| 	if manual_trigger_end then | ||||
| 		manual_trigger_end = false | ||||
| 		return true | ||||
| 	end | ||||
|  | ||||
| 	return false | ||||
| end | ||||
|  | ||||
| local set_sky_box = function(player_name) | ||||
| 	local sl = {} | ||||
| 	sl.layer_type = skylayer.SKY_PLAIN | ||||
| 	sl.name = SKYCOLOR_LAYER | ||||
| 	sl.sky_data = { | ||||
| 		gradient_colors = { | ||||
| 			{r=0, g=0, b=0}, | ||||
| 			{r=231, g=234, b=239}, | ||||
| 			{r=0, g=0, b=0} | ||||
| 		} | ||||
| 	} | ||||
| 	skylayer.add_layer(player_name, sl) | ||||
| end | ||||
|  | ||||
| snowstorm.in_area = function(position) | ||||
| 	if hw_utils.is_biome_frozen(position) == false then | ||||
| 		return false | ||||
| 	end | ||||
|  | ||||
| 	if position.y > 30 and position.y < 140 then | ||||
| 		return true | ||||
| 	end | ||||
| 	return false | ||||
| end | ||||
|  | ||||
| snowstorm.add_player = function(player) | ||||
| 	sound_handlers[player:get_player_name()] = set_weather_sound(player) | ||||
| 	set_sky_box(player:get_player_name()) | ||||
| end | ||||
|  | ||||
| snowstorm.remove_player = function(player) | ||||
| 	remove_weather_sound(player) | ||||
| 	skylayer.remove_layer(player:get_player_name(), SKYCOLOR_LAYER) | ||||
| end | ||||
|  | ||||
| local rain_drop_texture = "happy_weather_snowstorm.png" | ||||
|  | ||||
| local sign = function (number) | ||||
| 	if number >= 0 then | ||||
| 		return 1 | ||||
| 	else | ||||
| 		return -1 | ||||
| 	end | ||||
| end | ||||
|  | ||||
| local add_wide_range_rain_particle = function(player) | ||||
| 	local offset = { | ||||
| 		front = 7, | ||||
| 		back = 4, | ||||
| 		top = 3, | ||||
| 		bottom = 0 | ||||
| 	} | ||||
|  | ||||
| 	local random_pos = hw_utils.get_random_pos(player, offset) | ||||
| 	local p_pos = player:getpos() | ||||
|  | ||||
| 	local look_dir = player:get_look_dir() | ||||
|  | ||||
| 	if hw_utils.is_outdoor(random_pos) then | ||||
| 		minetest.add_particle({ | ||||
| 			pos = {x=random_pos.x, y=random_pos.y, z=random_pos.z}, | ||||
| 		  	velocity = {x = sign(look_dir.x) * -10, y = -1, z = sign(look_dir.z) * -10}, | ||||
| 		  	acceleration = {x = sign(look_dir.x) * -10, y = -1, z = sign(look_dir.z) * -10}, | ||||
| 		  	expirationtime = 0.3, | ||||
| 		  	size = 30, | ||||
| 		  	collisiondetection = true, | ||||
| 		  	texture = "happy_weather_snowstorm.png", | ||||
| 		  	playername = player:get_player_name() | ||||
| 		}) | ||||
| 	end | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Random texture getter | ||||
| local choice_random_rain_drop_texture = function() | ||||
| 	local base_name = "happy_weather_light_snow_snowflake_" | ||||
| 	local number = math.random(1, 3) | ||||
| 	local extension = ".png" | ||||
| 	return base_name .. number .. extension | ||||
| end | ||||
|  | ||||
| local add_snow_particle = function(player) | ||||
| 	local offset = { | ||||
| 		front = 5, | ||||
| 		back = 2, | ||||
| 		top = 4 | ||||
| 	} | ||||
|  | ||||
| 	local random_pos = hw_utils.get_random_pos(player, offset) | ||||
|  | ||||
| 	if hw_utils.is_outdoor(random_pos) then | ||||
| 		minetest.add_particle({ | ||||
| 			pos = {x=random_pos.x, y=random_pos.y, z=random_pos.z}, | ||||
| 			velocity = {x = math.random(-5,-2.5), y = math.random(-10,-5), z = math.random(-5,-2.5)}, | ||||
| 			acceleration = {x = math.random(-5,-2.5), y=-2.5, z = math.random(-5,-2.5)}, | ||||
| 			expirationtime = 2.0, | ||||
| 			size = math.random(1, 3), | ||||
| 			collisiondetection = true, | ||||
| 			collision_removal = true, | ||||
| 			vertical = true, | ||||
| 			texture = choice_random_rain_drop_texture(), | ||||
| 			playername = player:get_player_name() | ||||
| 		}) | ||||
| 	end | ||||
| end | ||||
|  | ||||
| local display_particles = function(player) | ||||
| 	if hw_utils.is_underwater(player) then | ||||
| 		return | ||||
| 	end | ||||
|  | ||||
| 	local particles_number_per_update = 3 | ||||
| 	for i=particles_number_per_update, 1,-1 do | ||||
| 		add_wide_range_rain_particle(player) | ||||
| 	end | ||||
|  | ||||
| 	local snow_particles_number_per_update = 10 | ||||
| 	for i=snow_particles_number_per_update, 1,-1 do | ||||
| 		add_snow_particle(player) | ||||
| 	end | ||||
| end | ||||
|  | ||||
| snowstorm.render = function(dtime, player) | ||||
| 	display_particles(player) | ||||
| end | ||||
|  | ||||
| snowstorm.start = function() | ||||
| 	manual_trigger_start = true | ||||
| end | ||||
|  | ||||
| snowstorm.stop = function() | ||||
| 	manual_trigger_end = true | ||||
| end | ||||
|  | ||||
| happy_weather.register_weather(snowstorm) | ||||
|  | ||||
		Reference in New Issue
	
	Block a user