From 4eae95fa47c377e37ab911877f1f85148699c81d Mon Sep 17 00:00:00 2001 From: cora Date: Sun, 30 Jan 2022 20:09:58 +0100 Subject: [PATCH 1/7] let snow use particlespawners --- mods/ENVIRONMENT/mcl_weather/snow.lua | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/mods/ENVIRONMENT/mcl_weather/snow.lua b/mods/ENVIRONMENT/mcl_weather/snow.lua index 9f89a3a0a..f01d1d1b7 100644 --- a/mods/ENVIRONMENT/mcl_weather/snow.lua +++ b/mods/ENVIRONMENT/mcl_weather/snow.lua @@ -5,6 +5,26 @@ mcl_weather.snow = {} mcl_weather.snow.particles_count = 15 mcl_weather.snow.init_done = false +local psdef= { + amount = 99, + time = 0, --stay on til we turn it off + minpos = vector.new(-15,-5,-15), + maxpos =vector.new(15,10,15), + minvel = vector.new(0,-1,0), + maxvel = vector.new(0,-4,0), + minacc = vector.new(0,-1,0), + maxacc = vector.new(0,-4,0), + minexptime = 1, + maxexptime = 1, + minsize = 0.5, + maxsize = 5, + collisiondetection = true, + collision_removal = true, + object_collision = true, + vertical = true, + glow = 1 +} + -- calculates coordinates and draw particles for snow weather function mcl_weather.snow.add_snow_particles(player) mcl_weather.rain.last_rp_count = 0 @@ -75,9 +95,13 @@ minetest.register_globalstep(function(dtime) for _, player in pairs(get_connected_players()) do if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos())) then + mcl_weather.remove_spawners_player(player) return false end - mcl_weather.snow.add_snow_particles(player) + for i=1,2 do + psdef.texture="weather_pack_snow_snowflake"..i..".png" + mcl_weather.add_spawner_player(player,"snow"..i,psdef) + end end end) From 1e4494e85ddc725dbb5c5c7e1c26eed580282fb8 Mon Sep 17 00:00:00 2001 From: cora Date: Sun, 30 Jan 2022 21:15:51 +0100 Subject: [PATCH 2/7] let rain and thunder use particlespawners --- mods/ENVIRONMENT/mcl_weather/rain.lua | 100 ++++++++++++++++---------- 1 file changed, 63 insertions(+), 37 deletions(-) diff --git a/mods/ENVIRONMENT/mcl_weather/rain.lua b/mods/ENVIRONMENT/mcl_weather/rain.lua index 220b61006..191062bcd 100644 --- a/mods/ENVIRONMENT/mcl_weather/rain.lua +++ b/mods/ENVIRONMENT/mcl_weather/rain.lua @@ -1,5 +1,5 @@ -local PARTICLES_COUNT_RAIN = 30 -local PARTICLES_COUNT_THUNDER = 45 +local PARTICLES_COUNT_RAIN = 100 +local PARTICLES_COUNT_THUNDER = 300 local get_connected_players = minetest.get_connected_players @@ -19,6 +19,45 @@ mcl_weather.rain = { init_done = false, } +local update_sound={} +local vel=math.random(0,3) +local falling_speed=math.random(10,15) +local size = math.random(1,3) +local psdef= { + amount = mcl_weather.rain.particles_count, + time=0, + minpos = vector.new(-6,3,-6), + maxpos = vector.new(6,15,6), + minvel = vector.new(-vel,-falling_speed,-vel), + maxvel = math.random(vel,-falling_speed+vel,vel), + minacc = vector.new(0,0,0), + maxacc = vector.new(0,-0.4,0), + minexptime = 0.5, + maxexptime = 2, + minsize = size, + maxsize= size*2, + collisiondetection = true, + collision_removal = true, + vertical = true, +} +local psdef_backsplash= { + amount = 10, + time=0, + minpos = vector.new(-3,-1,-3), + maxpos = vector.new(3,0,3), + minvel = vector.new(-vel,falling_speed*2,-vel), + maxvel = math.random(vel,falling_speed*2+vel,vel), + minacc = vector.new(0,0,0), + maxacc = vector.new(0,0,0), + minexptime = 0.1, + maxexptime = 0.2, + minsize = size*0.1, + maxsize= size*0.5, + collisiondetection = true, + collision_removal = true, + vertical = true, +} +local textures = {"weather_pack_rain_raindrop_1.png", "weather_pack_rain_raindrop_2.png", "weather_pack_rain_raindrop_1.png"} function mcl_weather.rain.sound_handler(player) return minetest.sound_play("weather_rain", { @@ -44,42 +83,18 @@ function mcl_weather.rain.set_sky_box() end end --- creating manually parctiles instead of particles spawner because of easier to control --- spawn position. +-- no no no NO NO f*.. no. no manual particle creatin' PLS!! this sends EVERY particle over the net. function mcl_weather.rain.add_rain_particles(player) - mcl_weather.rain.last_rp_count = 0 - for i=mcl_weather.rain.particles_count, 1,-1 do - local random_pos_x, random_pos_y, random_pos_z = mcl_weather.get_random_pos_by_player_look_dir(player) - if mcl_weather.is_outdoor({x=random_pos_x, y=random_pos_y, z=random_pos_z}) then - mcl_weather.rain.last_rp_count = mcl_weather.rain.last_rp_count + 1 - minetest.add_particle({ - pos = {x=random_pos_x, y=random_pos_y, z=random_pos_z}, - velocity = {x=0, y=-10, z=0}, - acceleration = {x=0, y=-30, z=0}, - expirationtime = 1.0, - size = math.random(0.5, 3), - collisiondetection = true, - collision_removal = true, - vertical = true, - texture = mcl_weather.rain.get_texture(), - playername = player:get_player_name() - }) - end + mcl_weather.rain.last_rp_count = mcl_weather.rain.particles_count + for k,v in pairs(textures) do + psdef.texture=v + mcl_weather.add_spawner_player(player,"rain"..k,psdef) end -end - --- Simple random texture getter -function mcl_weather.rain.get_texture() - local texture_name - local random_number = math.random() - if random_number > 0.33 then - texture_name = "weather_pack_rain_raindrop_1.png" - elseif random_number > 0.66 then - texture_name = "weather_pack_rain_raindrop_2.png" - else - texture_name = "weather_pack_rain_raindrop_3.png" + psdef_backsplash.texture=textures[math.random(1,#textures)] + local l=mcl_weather.add_spawner_player(player,"rainbacksplash",psdef_backsplash) + if l then + update_sound[player:get_player_name()]=true end - return texture_name; end -- register player for rain weather. @@ -89,6 +104,7 @@ function mcl_weather.rain.add_player(player) local player_meta = {} player_meta.origin_sky = {player:get_sky()} mcl_weather.players[player:get_player_name()] = player_meta + update_sound[player:get_player_name()]=true end end @@ -99,6 +115,7 @@ function mcl_weather.rain.remove_player(player) if player_meta and player_meta.origin_sky then player:set_clouds({color="#FFF0F0E5"}) mcl_weather.players[player:get_player_name()] = nil + update_sound[player:get_player_name()]=true end end @@ -119,6 +136,7 @@ end) -- have few seconds delay before each check to avoid on/off sound too often -- when player stay on 'edge' where sound should play and stop depending from random raindrop appearance. function mcl_weather.rain.update_sound(player) + if not update_sound[player:get_player_name()] then return end local player_meta = mcl_weather.players[player:get_player_name()] if player_meta then if player_meta.sound_updated and player_meta.sound_updated + 5 > minetest.get_gametime() then @@ -136,6 +154,7 @@ function mcl_weather.rain.update_sound(player) player_meta.sound_updated = minetest.get_gametime() end + update_sound[player:get_player_name()]=false end -- rain sound removed from player. @@ -158,7 +177,8 @@ function mcl_weather.rain.clear() for _, player in pairs(get_connected_players()) do mcl_weather.rain.remove_sound(player) mcl_weather.rain.remove_player(player) - end + mcl_weather.remove_spawners_player(player) + end end minetest.register_globalstep(function(dtime) @@ -177,8 +197,10 @@ function mcl_weather.rain.make_weather() end for _, player in pairs(get_connected_players()) do - if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos())) then + local pos=player:get_pos() + if mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(pos) or not mcl_weather.is_outdoor(pos) then mcl_weather.rain.remove_sound(player) + mcl_weather.remove_spawners_player(player) return false end mcl_weather.rain.add_player(player) @@ -190,8 +212,12 @@ end -- Switch the number of raindrops: "thunder" for many raindrops, otherwise for normal raindrops function mcl_weather.rain.set_particles_mode(mode) if mode == "thunder" then + psdef.amount=PARTICLES_COUNT_THUNDER + psdef_backsplash.amount=PARTICLES_COUNT_THUNDER mcl_weather.rain.particles_count = PARTICLES_COUNT_THUNDER else + psdef.amount=PARTICLES_COUNT_RAIN + psdef_backsplash.amount=PARTICLES_COUNT_RAIN mcl_weather.rain.particles_count = PARTICLES_COUNT_RAIN end end From d2861c5955b6eaad55db6d54a3b9201d0f098ddb Mon Sep 17 00:00:00 2001 From: cora Date: Mon, 31 Jan 2022 00:22:16 +0100 Subject: [PATCH 3/7] remove unneccessary particle logic --- mods/ENVIRONMENT/mcl_weather/snow.lua | 25 ---------------- mods/ENVIRONMENT/mcl_weather/weather_core.lua | 30 ------------------- 2 files changed, 55 deletions(-) diff --git a/mods/ENVIRONMENT/mcl_weather/snow.lua b/mods/ENVIRONMENT/mcl_weather/snow.lua index f01d1d1b7..4d9fda928 100644 --- a/mods/ENVIRONMENT/mcl_weather/snow.lua +++ b/mods/ENVIRONMENT/mcl_weather/snow.lua @@ -25,31 +25,6 @@ local psdef= { glow = 1 } --- calculates coordinates and draw particles for snow weather -function mcl_weather.snow.add_snow_particles(player) - mcl_weather.rain.last_rp_count = 0 - for i=mcl_weather.snow.particles_count, 1,-1 do - local random_pos_x, _, random_pos_z = mcl_weather.get_random_pos_by_player_look_dir(player) - local random_pos_y = math.random() + math.random(player:get_pos().y - 1, player:get_pos().y + 7) - if minetest.get_node_light({x=random_pos_x, y=random_pos_y, z=random_pos_z}, 0.5) == 15 then - mcl_weather.rain.last_rp_count = mcl_weather.rain.last_rp_count + 1 - minetest.add_particle({ - pos = {x=random_pos_x, y=random_pos_y, z=random_pos_z}, - velocity = {x = math.random(-100,100)*0.001, y = math.random(-300,-100)*0.004, z = math.random(-100,100)*0.001}, - acceleration = {x = 0, y=0, z = 0}, - expirationtime = 8.0, - size = 1, - collisiondetection = true, - collision_removal = true, - object_collision = false, - vertical = false, - texture = mcl_weather.snow.get_texture(), - playername = player:get_player_name() - }) - end - end -end - function mcl_weather.snow.set_sky_box() mcl_weather.skycolor.add_layer( "weather-pack-snow-sky", diff --git a/mods/ENVIRONMENT/mcl_weather/weather_core.lua b/mods/ENVIRONMENT/mcl_weather/weather_core.lua index 34f69406d..c2cf96ba7 100644 --- a/mods/ENVIRONMENT/mcl_weather/weather_core.lua +++ b/mods/ENVIRONMENT/mcl_weather/weather_core.lua @@ -92,36 +92,6 @@ function mcl_weather.is_underwater(player) return false end --- 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. -function mcl_weather.get_random_pos_by_player_look_dir(player) - local look_dir = player:get_look_dir() - local player_pos = player:get_pos() - - local random_pos_x, random_pos_y, random_pos_z - - if look_dir.x > 0 then - if look_dir.z > 0 then - random_pos_x = math.random() + math.random(player_pos.x - 2.5, player_pos.x + 5) - random_pos_z = math.random() + math.random(player_pos.z - 2.5, player_pos.z + 5) - else - random_pos_x = math.random() + math.random(player_pos.x - 2.5, player_pos.x + 5) - random_pos_z = math.random() + math.random(player_pos.z - 5, player_pos.z + 2.5) - end - else - if look_dir.z > 0 then - random_pos_x = math.random() + math.random(player_pos.x - 5, player_pos.x + 2.5) - random_pos_z = math.random() + math.random(player_pos.z - 2.5, player_pos.z + 5) - else - random_pos_x = math.random() + math.random(player_pos.x - 5, player_pos.x + 2.5) - random_pos_z = math.random() + math.random(player_pos.z - 5, player_pos.z + 2.5) - end - end - - random_pos_y = math.random() + math.random(player_pos.y + 10, player_pos.y + 15) - return random_pos_x, random_pos_y, random_pos_z -end - local t, wci = 0, mcl_weather.check_interval minetest.register_globalstep(function(dtime) From dc24f45cfad627d0d3b99b87470d56173164a3b7 Mon Sep 17 00:00:00 2001 From: cora Date: Mon, 31 Jan 2022 00:22:46 +0100 Subject: [PATCH 4/7] add indoor detection for snow --- mods/ENVIRONMENT/mcl_weather/snow.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ENVIRONMENT/mcl_weather/snow.lua b/mods/ENVIRONMENT/mcl_weather/snow.lua index 4d9fda928..8de38ea98 100644 --- a/mods/ENVIRONMENT/mcl_weather/snow.lua +++ b/mods/ENVIRONMENT/mcl_weather/snow.lua @@ -69,7 +69,7 @@ minetest.register_globalstep(function(dtime) end for _, player in pairs(get_connected_players()) do - if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos())) then + if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos()) or not mcl_weather.is_outoor(player:get_pos())) then mcl_weather.remove_spawners_player(player) return false end From c146426c5cf4bfb6db3e07d13ff770951d9338dd Mon Sep 17 00:00:00 2001 From: cora Date: Mon, 31 Jan 2022 00:35:26 +0100 Subject: [PATCH 5/7] fix snow not being properly removed --- mods/ENVIRONMENT/mcl_weather/snow.lua | 3 +- mods/ENVIRONMENT/mcl_weather/weather_core.lua | 29 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/mods/ENVIRONMENT/mcl_weather/snow.lua b/mods/ENVIRONMENT/mcl_weather/snow.lua index 8de38ea98..b60283127 100644 --- a/mods/ENVIRONMENT/mcl_weather/snow.lua +++ b/mods/ENVIRONMENT/mcl_weather/snow.lua @@ -43,6 +43,7 @@ end function mcl_weather.snow.clear() mcl_weather.skycolor.remove_layer("weather-pack-snow-sky") mcl_weather.snow.init_done = false + mcl_weather.remove_all_spawners() end -- Simple random texture getter @@ -69,7 +70,7 @@ minetest.register_globalstep(function(dtime) end for _, player in pairs(get_connected_players()) do - if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos()) or not mcl_weather.is_outoor(player:get_pos())) then + if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos()) or not mcl_weather.is_outdoor(player:get_pos())) then mcl_weather.remove_spawners_player(player) return false end diff --git a/mods/ENVIRONMENT/mcl_weather/weather_core.lua b/mods/ENVIRONMENT/mcl_weather/weather_core.lua index c2cf96ba7..f7316bcfb 100644 --- a/mods/ENVIRONMENT/mcl_weather/weather_core.lua +++ b/mods/ENVIRONMENT/mcl_weather/weather_core.lua @@ -47,6 +47,35 @@ local function save_weather() end minetest.register_on_shutdown(save_weather) +local particlespawners={} +function mcl_weather.add_spawner_player(pl,id,ps) + local name=pl:get_player_name() + if not particlespawners[name] then + particlespawners[name] = {} + end + if not particlespawners[name][id] then + ps.playername =name + ps.attached = pl + particlespawners[name][id]=minetest.add_particlespawner(ps) + return particlespawners[name][id] + end +end +function mcl_weather.remove_spawners_player(pl) + local name=pl:get_player_name() + if not particlespawners[name] then return end + for k,v in pairs(particlespawners[name]) do + minetest.delete_particlespawner(v) + end + particlespawners[name] = nil + return true +end + +function mcl_weather.remove_all_spawners() + for k,v in pairs(minetest.get_connected_players()) do + mcl_weather.remove_spawners_player(v) + end +end + function mcl_weather.get_rand_end_time(min_duration, max_duration) local r if min_duration and max_duration then From 53715212a210d31b965f1f9d482cba528d6fc700 Mon Sep 17 00:00:00 2001 From: cora Date: Mon, 31 Jan 2022 21:35:21 +0100 Subject: [PATCH 6/7] remove unnecessary on_dimensionchange --- mods/ENVIRONMENT/mcl_weather/rain.lua | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/mods/ENVIRONMENT/mcl_weather/rain.lua b/mods/ENVIRONMENT/mcl_weather/rain.lua index 191062bcd..f21bbc13c 100644 --- a/mods/ENVIRONMENT/mcl_weather/rain.lua +++ b/mods/ENVIRONMENT/mcl_weather/rain.lua @@ -29,7 +29,7 @@ local psdef= { minpos = vector.new(-6,3,-6), maxpos = vector.new(6,15,6), minvel = vector.new(-vel,-falling_speed,-vel), - maxvel = math.random(vel,-falling_speed+vel,vel), + maxvel = vector.new(vel,-falling_speed+vel,vel), minacc = vector.new(0,0,0), maxacc = vector.new(0,-0.4,0), minexptime = 0.5, @@ -119,19 +119,6 @@ function mcl_weather.rain.remove_player(player) end end -mcl_worlds.register_on_dimension_change(function(player, dimension) - if dimension ~= "overworld" and dimension ~= "void" then - mcl_weather.rain.remove_sound(player) - mcl_weather.rain.remove_player(player) - elseif dimension == "overworld" then - mcl_weather.rain.update_sound(player) - if mcl_weather.rain.raining then - mcl_weather.rain.add_rain_particles(player) - mcl_weather.rain.add_player(player) - end - end -end) - -- adds and removes rain sound depending how much rain particles around player currently exist. -- have few seconds delay before each check to avoid on/off sound too often -- when player stay on 'edge' where sound should play and stop depending from random raindrop appearance. From 7f1bb7af92841ca3d12ce3dc69238995b8bd0b42 Mon Sep 17 00:00:00 2001 From: cora Date: Sat, 25 Sep 2021 02:06:39 +0200 Subject: [PATCH 7/7] replace nether dust particles with p. spawners mcl2 uses add_particle for nether dust resulting in a 10-fold increase in network traffic when in the nether. Nether dust is not configurable making it impossible to turn this off for server admins. this commit replaces the add_particle method with particle spawners --- mods/ENVIRONMENT/mcl_weather/nether_dust.lua | 86 +++++++++++++------- 1 file changed, 58 insertions(+), 28 deletions(-) diff --git a/mods/ENVIRONMENT/mcl_weather/nether_dust.lua b/mods/ENVIRONMENT/mcl_weather/nether_dust.lua index d328dae21..4ab9e4081 100644 --- a/mods/ENVIRONMENT/mcl_weather/nether_dust.lua +++ b/mods/ENVIRONMENT/mcl_weather/nether_dust.lua @@ -1,36 +1,66 @@ mcl_weather.nether_dust = {} -mcl_weather.nether_dust.particles_count = 99 +mcl_weather.nether_dust.particlespawners = {} --- calculates coordinates and draw particles for Nether dust -function mcl_weather.nether_dust.add_dust_particles(player) - for i=mcl_weather.nether_dust.particles_count, 1,-1 do - local rpx, rpy, rpz = mcl_weather.get_random_pos_by_player_look_dir(player) - minetest.add_particle({ - pos = {x = rpx, y = rpy - math.random(6, 18), z = rpz}, - velocity = {x = math.random(-30,30)*0.01, y = math.random(-15,15)*0.01, z = math.random(-30,30)*0.01}, - acceleration = {x = math.random(-50,50)*0.02, y = math.random(-20,20)*0.02, z = math.random(-50,50)*0.02}, - expirationtime = 3, - size = math.random(6,20)*0.01, - collisiondetection = false, - object_collision = false, - vertical = false, - glow = math.random(0,minetest.LIGHT_MAX), - texture = "mcl_particles_nether_dust"..tostring(i%3+1)..".png", - playername = player:get_player_name() - }) +local psdef= { + amount = 150, + time = 0, + minpos = vector.new(-15,-15,-15), + maxpos =vector.new(15,15,15), + minvel = vector.new(-0.3,-0.15,-1), + maxvel = vector.new(0.3,0.15,0.3), + minacc = vector.new(-1,-0.4,-1), + maxacc = vector.new(1,0.4,1), + minexptime = 1, + maxexptime = 10, + minsize = 0.2, + maxsize = 0.7, + collisiondetection = false, + collision_removal = false, + object_collision = false, + vertical = false +} + +local function check_player(player) + local name=player:get_player_name() + if mcl_worlds.has_dust(player:get_pos()) and not mcl_weather.nether_dust.particlespawners[name] then + return true + end +end + +mcl_weather.nether_dust.add_particlespawners = function(player) + local name=player:get_player_name(name) + mcl_weather.nether_dust.particlespawners[name]={} + psdef.playername = name + psdef.attached = player + psdef.glow = math.random(0,minetest.LIGHT_MAX) + for i=1,3 do + psdef.texture="mcl_particles_nether_dust"..i..".png" + mcl_weather.nether_dust.particlespawners[name][i]=minetest.add_particlespawner(psdef) end end -local timer = 0 -minetest.register_globalstep(function(dtime) - timer = timer + dtime - if timer < 0.7 then return end - timer = 0 - - for _, player in pairs(minetest.get_connected_players()) do - if not mcl_worlds.has_dust(player:get_pos()) then - return false +mcl_weather.nether_dust.delete_particlespawners = function(player) + local name=player:get_player_name(name) + if mcl_weather.nether_dust.particlespawners[name] then + for i=1,3 do + minetest.delete_particlespawner(mcl_weather.nether_dust.particlespawners[name][i]) end - mcl_weather.nether_dust.add_dust_particles(player) + mcl_weather.nether_dust.particlespawners[name]=nil + end +end + +mcl_worlds.register_on_dimension_change(function(player, dimension) + if check_player(player) then + return mcl_weather.nether_dust.add_particlespawners(player) + end + mcl_weather.nether_dust.delete_particlespawners(player) +end) + +minetest.register_on_joinplayer(function(player) + if check_player(player) then + mcl_weather.nether_dust.add_particlespawners(player) end end) +minetest.register_on_leaveplayer(function(player) + mcl_weather.nether_dust.delete_particlespawners(player) +end)