форк від mtcontrib/weather_pack
		
	Порівняти коміти
	
		
			9 Коміти
		
	
	
		
			def185bb40
			...
			master
		
	
	| Автор | SHA1 | Дата | |
|---|---|---|---|
| 00b36224ed | |||
|  | fa9e15628d | ||
|  | d9c26aba55 | ||
|  | 2a8c2d0566 | ||
|  | 0efa6f9e44 | ||
|  | c6987629e5 | ||
|  | 9bb9a6cecb | ||
|  | 5e4a9a46cb | ||
|  | bb53648a69 | 
| @@ -4,8 +4,8 @@ Weather mod for Minetest (http://minetest.net/) | |||||||
|  |  | ||||||
| Feedback and Improvements | Feedback and Improvements | ||||||
| ----------------------- | ----------------------- | ||||||
| * See newest version at https://github.com/xeranas/weather_pack | * See newest version at https://gitlab.com/zombiebot/weather_pack | ||||||
| * Register bugs at https://github.com/xeranas/weather_pack/issues | * Register bugs at https://gitlab.com/zombiebot/weather_pack/issues | ||||||
| * Questions / Discussion at https://forum.minetest.net/viewtopic.php?p=215869 | * Questions / Discussion at https://forum.minetest.net/viewtopic.php?p=215869 | ||||||
|  |  | ||||||
| Weathers included | Weathers included | ||||||
|   | |||||||
							
								
								
									
										21
									
								
								init.lua
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								init.lua
									
									
									
									
									
								
							| @@ -2,25 +2,32 @@ 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.."/lib_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.."/lib_happy_weather_api.lua") | ||||||
| 	dofile(modpath.."/commands.lua") | 	dofile(modpath.."/commands.lua") | ||||||
| end | 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 | -- Happy Weather utilities | ||||||
| dofile(modpath.."/utils.lua") | dofile(modpath.."/utils.lua") | ||||||
|  |  | ||||||
| dofile(modpath.."/light_rain.lua") | dofile(modpath.."/weathers/light_rain.lua") | ||||||
| dofile(modpath.."/rain.lua") | dofile(modpath.."/weathers/rain.lua") | ||||||
| dofile(modpath.."/heavy_rain.lua") | dofile(modpath.."/weathers/heavy_rain.lua") | ||||||
| dofile(modpath.."/snow.lua") | dofile(modpath.."/weathers/snow.lua") | ||||||
|  | dofile(modpath.."/weathers/snowstorm.lua") | ||||||
|  |  | ||||||
| if minetest.get_modpath("lightning") ~= nil then | if minetest.get_modpath("lightning") ~= nil then | ||||||
| 	dofile(modpath.."/thunder.lua") | 	dofile(modpath.."/weathers/thunder.lua") | ||||||
|  |  | ||||||
| 	-- Turn off lightning mod 'auto mode' | 	-- Turn off lightning mod 'auto mode' | ||||||
| 	lightning.auto = false | 	lightning.auto = false | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ happy_weather = {} | |||||||
| -- Local variables which helps organize active and deactive weahers | -- Local variables which helps organize active and deactive weahers | ||||||
| local registered_weathers = {} | local registered_weathers = {} | ||||||
| local active_weathers = {} | local active_weathers = {} | ||||||
|  | local meta_plawpos = {} -- meta about Player Last Active Weaher Position | ||||||
| 
 | 
 | ||||||
| ------------------------------------ | ------------------------------------ | ||||||
| -- Local helper / utility methods -- | -- Local helper / utility methods -- | ||||||
| @@ -79,6 +80,44 @@ local is_player_affected = function(affected_players, player_name) | |||||||
| 	end | 	end | ||||||
| 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 -- | -- Weather API functions -- | ||||||
| --------------------------- | --------------------------- | ||||||
| @@ -179,7 +218,7 @@ local weather_remove_player = function(weather_obj, player) | |||||||
| 	weather_obj.remove_player(player) | 	weather_obj.remove_player(player) | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| -- Weather remove_player method nil-safe wrapper | -- Weather in_area method nil-safe wrapper | ||||||
| local weather_in_area = function(weather_obj, position) | local weather_in_area = function(weather_obj, position) | ||||||
| 	if weather_obj.in_area == nil then | 	if weather_obj.in_area == nil then | ||||||
| 		return true | 		return true | ||||||
| @@ -224,14 +263,36 @@ local prepare_starting = function(weather_obj) | |||||||
| 	add_active_weather(weather_obj) | 	add_active_weather(weather_obj) | ||||||
| end | 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 | -- 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) | local render_if_in_area = function(weather_obj, dtime, player) | ||||||
| 	if is_player_affected(weather_obj.affected_players, player:get_player_name()) then | 	if is_player_affected(weather_obj.affected_players, player:get_player_name()) then | ||||||
| 		if weather_in_area(weather_obj, player:getpos()) then | 		if weather_in_area(weather_obj, player:getpos()) then | ||||||
| 			weather_render(weather_obj, dtime, player) | 			weather_render(weather_obj, dtime, player) | ||||||
|  | 			add_meta_plawpos(weather_obj.code, player) | ||||||
| 		else | 		else | ||||||
| 			weather_remove_player(weather_obj, player) | 			if (is_outside_recent_weather(weather_obj.code, player)) then | ||||||
| 			remove_player(weather_obj.affected_players, player:get_player_name()) | 				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 | ||||||
| 		end | 		end | ||||||
| 	else | 	else | ||||||
| 		if weather_in_area(weather_obj, player:getpos()) then | 		if weather_in_area(weather_obj, player:getpos()) then | ||||||
| @@ -280,7 +341,7 @@ minetest.register_globalstep(function(dtime) | |||||||
| 
 | 
 | ||||||
| 			-- Weaher is not active checking if it about to start | 			-- Weaher is not active checking if it about to start | ||||||
| 			else | 			else | ||||||
| 				if weather_.is_starting(dtime, player:getpos()) then | 				if weather_is_starting(weather_, dtime, player:getpos()) then | ||||||
| 					activate_weather = true | 					activate_weather = true | ||||||
| 				end | 				end | ||||||
| 			end	 | 			end	 | ||||||
							
								
								
									
										
											BIN
										
									
								
								sounds/happy_weather_snowstorm.ogg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								sounds/happy_weather_snowstorm.ogg
									
									
									
									
									
										Normal file
									
								
							
										
											Бінарний файл не відображається.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								textures/happy_weather_snowstorm.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								textures/happy_weather_snowstorm.png
									
									
									
									
									
										Normal file
									
								
							
										
											Бінарний файл не відображається.
										
									
								
							| Після Ширина: | Висота: | Розмір: 97 KiB | 
							
								
								
									
										88
									
								
								utils.lua
									
									
									
									
									
								
							
							
						
						
									
										88
									
								
								utils.lua
									
									
									
									
									
								
							| @@ -77,80 +77,29 @@ hw_utils.get_random_pos = function(player, offset) | |||||||
| 	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 = { |  | ||||||
| 	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) | local is_biome_frozen = function(position) | ||||||
| 	local posx = math.floor(position.x) | 	if legacy_MT_version then | ||||||
| 	local posz = math.floor(position.z) | 		return false; | ||||||
| 	local noise_obj = minetest.get_perlin(np_temp) | 	end | ||||||
| 	local noise_temp = noise_obj:get2d({x = posx, y = posz}) | 	local heat = minetest.get_heat(position) | ||||||
|  |  | ||||||
| 	-- below 35 heat biome considered to be frozen type | 	-- below 35 heat biome considered to be frozen type | ||||||
| 	return noise_temp < 35 | 	return heat < 35 | ||||||
| end | end | ||||||
|  |  | ||||||
| hw_utils.is_biome_frozen = function(position) | hw_utils.is_biome_frozen = function(position) | ||||||
| 	if mg_name == "v6" then | 	if mg_name == "v6" then | ||||||
| 		return false -- v6 not supported yet. | 		return false -- v6 not supported. | ||||||
| 	end | 	end | ||||||
| 	return is_biome_frozen(position) | 	return is_biome_frozen(position) | ||||||
| end | 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 is_biome_dry = function(position) | ||||||
| 	local posx = math.floor(position.x) | 	if legacy_MT_version 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}) | 	local humidity = minetest.get_humidity(position) | ||||||
|  | 	local heat = minetest.get_heat(position) | ||||||
| 	-- below 50 humid biome considered to be dry type (at least by this mod) | 	return humidity < 50 and heat > 65 | ||||||
| 	return noise_humid < 50 |  | ||||||
| end | end | ||||||
|  |  | ||||||
| hw_utils.is_biome_dry = function(position) | hw_utils.is_biome_dry = function(position) | ||||||
| @@ -161,15 +110,14 @@ hw_utils.is_biome_dry = function(position) | |||||||
| end | end | ||||||
|  |  | ||||||
| local is_biome_tropic = function(position) | local is_biome_tropic = function(position) | ||||||
| 	local posx = math.floor(position.x) | 	if legacy_MT_version 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}) | 	local humidity = minetest.get_humidity(position) | ||||||
| 	noise_obj = minetest.get_perlin(np_temp) | 	local heat = minetest.get_heat(position) | ||||||
| 	local noise_temp = noise_obj:get2d({x = posx, y = posz}) |  | ||||||
|  |  | ||||||
| 	-- humid and temp values are taked by testing flying around world (not sure actually) | 	-- humid and temp values are taked by testing flying around world (not sure actually) | ||||||
| 	return noise_humid > 55 and noise_temp > 80 | 	return humidity > 55 and heat > 70 | ||||||
| end | end | ||||||
|  |  | ||||||
| hw_utils.is_biome_tropic = function(position) | hw_utils.is_biome_tropic = function(position) | ||||||
|   | |||||||
							
								
								
									
										203
									
								
								weathers/snowstorm.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										203
									
								
								weathers/snowstorm.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,203 @@ | |||||||
|  | ---------------------------- | ||||||
|  | -- 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) | ||||||
|  |  | ||||||
		Посилання в новій задачі
	
	Block a user