2019-05-18 00:44:56 +01:00

173 lines
4.1 KiB
Lua

-- Parameters
local YLIMIT = 0 -- Set to world's water level or level of lowest open area,
-- calculations are disabled below this y.
local GSCYCLE = 0.5 -- Globalstep cycle (seconds)
local FLAKES = 32 -- Snowflakes per cycle
local DROPS = 96 -- Raindrops per cycle
local RAINGAIN = 0.12 -- Rain sound volume
local COLLIDE = true -- Whether particles collide with nodes
-- Globalstep function
local handles = {}
local timer = 0
minetest.register_globalstep(function(dtime)
timer = timer + dtime
if timer < GSCYCLE then
return
end
timer = 0
for _, player in ipairs(minetest.get_connected_players()) do
local player_name = player:get_player_name()
local ppos = player:get_pos()
local pposy = math.floor(ppos.y) + 2 -- Precipitation when swimming
if pposy >= YLIMIT then
local weather = atmos.get_weather(ppos)
local precip, freeze, hail
if weather == "snow" then
precip = true
freeze = true
hail = false
elseif weather == "rain" then
precip = true
freeze = false
hail = false
elseif weather == "storm" then
precip = true
freeze = false
hail = false
elseif weather == "hail" then
precip = true
freeze = false
hail = true
end
-- Check if player is outside
local outside = minetest.get_node_light({x=ppos.x, y=ppos.y + 1, z=ppos.z}, 0.5) == 15
if not precip or not outside or freeze then
if handles[player_name] then
-- Stop sound if playing
minetest.sound_stop(handles[player_name])
handles[player_name] = nil
end
end
if precip and outside then
-- Precipitation
if freeze then
-- Snowfall
for flake = 1, FLAKES do
minetest.add_particle({
pos = {
x = ppos.x - 24 + math.random(0, 47),
y = ppos.y + 8 + math.random(0, 8),
z = ppos.z - 20 + math.random(0, 47)
},
vel = {
x = 0.0,
y = -2.0,
z = -1.0
},
acc = {x = 0, y = 0, z = 0},
expirationtime = 8.5,
size = 2.8,
collisiondetection = COLLIDE,
collision_removal = true,
vertical = false,
texture = "snowdrift_snowflake" .. math.random(1, 4) .. ".png",
playername = player:get_player_name()
})
end
elseif hail then
for flake = 1, DROPS-48 do
minetest.add_particle({
pos = {
x = ppos.x - 8 + math.random(0, 16),
y = ppos.y + 8 + math.random(0, 8),
z = ppos.z - 8 + math.random(0, 16)
},
vel = {
x = 0.0,
y = -15.0,
z = 0.0
},
acc = {x = 0, y = 0, z = 0},
expirationtime = 2.1,
size = 2.8,
collisiondetection = COLLIDE,
collision_removal = true,
vertical = true,
texture = "snowdrift_hailstone.png",
playername = player:get_player_name()
})
end
else
-- Rainfall
for flake = 1, DROPS do
minetest.add_particle({
pos = {
x = ppos.x - 8 + math.random(0, 16),
y = ppos.y + 8 + math.random(0, 8),
z = ppos.z - 8 + math.random(0, 16)
},
vel = {
x = 0.0,
y = -10.0,
z = 0.0
},
acc = {x = 0, y = 0, z = 0},
expirationtime = 2.1,
size = 2.8,
collisiondetection = COLLIDE,
collision_removal = true,
vertical = true,
texture = "snowdrift_raindrop.png",
playername = player:get_player_name()
})
end
if not handles[player_name] then
-- Start sound if not playing
local handle = minetest.sound_play(
"snowdrift_rain",
{
to_player = player_name,
gain = RAINGAIN,
loop = true,
}
)
if handle then
handles[player_name] = handle
end
end
end
end
elseif handles[player_name] then
-- Stop sound when player goes under y limit
minetest.sound_stop(handles[player_name])
handles[player_name] = nil
end
end
end)
-- Stop sound and remove player handle on leaveplayer
minetest.register_on_leaveplayer(function(player)
local player_name = player:get_player_name()
if handles[player_name] then
minetest.sound_stop(handles[player_name])
handles[player_name] = nil
end
end)