add weather depending on position/biome

This commit is contained in:
cora 2021-09-26 06:08:01 +02:00
parent 7bd4d75c3f
commit 015b29aa60
4 changed files with 65 additions and 37 deletions

View File

@ -62,7 +62,8 @@ 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.
function mcl_weather.is_underwater(ppos) function mcl_weather.is_underwater(player)
local ppos=player:get_pos()
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 = {x = ppos.x + offset.x,
y = ppos.y + offset.y + 1.5, y = ppos.y + offset.y + 1.5,
@ -74,8 +75,9 @@ function mcl_weather.is_underwater(ppos)
return false return false
end end
function mcl_weather.pos_has_weather(pos) function mcl_weather.player_has_weather(player)
if mcl_weather.is_outdoor(pos) and not mcl_weather.is_underwater(pos) then local pos=player:get_pos()
if mcl_weather.is_outdoor(pos) and not mcl_weather.is_underwater(player) then
return true return true
end end
return false return false
@ -98,10 +100,8 @@ function mcl_weather.add_particlespawners_player(name,spawners)
if not spawners then return end if not spawners then return end
local player = minetest.get_player_by_name(name) local player = minetest.get_player_by_name(name)
if not player then return end if not player then return end
if players.particlespawners[name] == nil then if players.particlespawners[name] ~= nil then return end
players.particlespawners[name]={} players.particlespawners[name]={}
end
for k,v in ipairs(spawners) do for k,v in ipairs(spawners) do
v.playername=name v.playername=name
v.attached=player v.attached=player
@ -109,14 +109,14 @@ function mcl_weather.add_particlespawners_player(name,spawners)
end end
end end
function mcl_weather.delete_particlespawners_player(player) function mcl_weather.delete_particlespawners_player(name)
if players.particlespawners[player] == nil then if players.particlespawners[name] == nil then
players.particlespawners[player]={} players.particlespawners[name]={}
end end
for k,v in ipairs(players.particlespawners[player]) do for k,v in ipairs(players.particlespawners[name]) do
minetest.delete_particlespawner(v) minetest.delete_particlespawner(v)
end end
players.particlespawners[player]=nil players.particlespawners[name]=nil
end end
local function doplayers(func,players) local function doplayers(func,players)
@ -144,11 +144,6 @@ end
function mcl_weather.start_weather_player(name,def) function mcl_weather.start_weather_player(name,def)
local player=minetest.get_player_by_name(name) local player=minetest.get_player_by_name(name)
if not mcl_worlds.has_weather(player:get_pos()) then
players.weatheractive[name] = false
return
end
if def.start_player then def.start_player(name) end
mcl_weather.add_particlespawners_player(name,def.particlespawners) mcl_weather.add_particlespawners_player(name,def.particlespawners)
if def.skycolor then if def.skycolor then
local player=minetest.get_player_by_name(name) local player=minetest.get_player_by_name(name)
@ -161,7 +156,6 @@ function mcl_weather.start_weather_player(name,def)
end end
function mcl_weather.stop_weather_player(name,def) function mcl_weather.stop_weather_player(name,def)
if def.clear_player then def.clear_player(name) end
mcl_weather.delete_particlespawners_player(name) mcl_weather.delete_particlespawners_player(name)
if def.skycolor then if def.skycolor then
local player=minetest.get_player_by_name(name) local player=minetest.get_player_by_name(name)
@ -170,27 +164,28 @@ function mcl_weather.stop_weather_player(name,def)
if def.sound then if def.sound then
mcl_weather.remove_sound(name,def.sound) mcl_weather.remove_sound(name,def.sound)
end end
players.weatheractive[name] = false
end end
function mcl_weather.start_weather(def) function mcl_weather.start_weather(def)
if def.start then def.start() end if def.start then def.start() end
if def.skylayer then if def.skylayer then
mcl_weather.skycolor.add_layer("weather",def.skylayer) mcl_weather.skycolor.add_layer("weather",def.skylayer)
mcl_weather.skycolor.update_sky_color() mcl_weather.skycolor.update_sky_color()
end end
doplayers(function(name) doplayers(function(name)
mcl_weather.start_weather_player(name,def) if def.start_player == nil or not def.start_player(name) then
mcl_weather.start_weather_player(name,def)
end
end) end)
end end
function mcl_weather.stop_weather(def) function mcl_weather.stop_weather(def)
if def.clear then def.clear() end if def.clear then def.clear() end
if def.clear_player then doplayers(def.clear_player) end
doplayers(function(name) doplayers(function(name)
mcl_weather.stop_weather_player(name,def) mcl_weather.stop_weather_player(name,def)
end) end)
if def.clear_player then doplayers(def.clear_player) end
if def.skylayer then if def.skylayer then
mcl_weather.skycolor.remove_layer("weather") mcl_weather.skycolor.remove_layer("weather")
mcl_weather.skycolor.update_sky_color() mcl_weather.skycolor.update_sky_color()
@ -218,14 +213,24 @@ end
function mcl_weather.tick() function mcl_weather.tick()
doplayers(function(name,player) doplayers(function(name,player)
local pos=player:get_pos() local pos=player:get_pos()
if players.weatheractive[name] and not mcl_weather.pos_has_weather(pos) then local cdef=mcl_weather.get_weatherdef(mcl_weather.current)
mcl_weather.stop_weather_player(name,mcl_weather.get_weatherdef(mcl_weather.current)) if players.weatheractive[name] then
elseif not players.weatheractive[name] and mcl_weather.pos_has_weather(pos) then if ( cdef.at_pos ~= nil and not cdef.at_pos(pos) ) or not mcl_weather.player_has_weather(player) then
mcl_weather.start_weather_player(name,mcl_weather.get_weatherdef(mcl_weather.current)) mcl_weather.stop_weather_player(name,cdef)
--mcl_weather.delete_particlespawners_player(name)
players.weatheractive[name] = false
end
else
if ( cdef.at_pos == nil or cdef.at_pos(pos)) and mcl_weather.player_has_weather(player) then
mcl_weather.start_weather_player(name,cdef)
--mcl_weather.add_particlespawners_player(name,cdef.particlespawners)
players.weatheractive[name] = true
end
end end
end) end)
minetest.after(interval,mcl_weather.tick) minetest.after(interval,mcl_weather.tick)
end end
mcl_weather.tick()
mcl_worlds.register_on_dimension_change(function(player, dimension) mcl_worlds.register_on_dimension_change(function(player, dimension)
if mcl_worlds.has_weather(player:get_pos()) then if mcl_worlds.has_weather(player:get_pos()) then
@ -257,7 +262,7 @@ minetest.register_chatcommand("weather", {
if (param == "") then if (param == "") then
return false, S("Error: No weather specified.") return false, S("Error: No weather specified.")
end end
local player=minetest.get_player_by_name(name)
local new_weather, duration local new_weather, duration
local parse1, parse2 = string.match(param, "(%w+) ?(%d*)") local parse1, parse2 = string.match(param, "(%w+) ?(%d*)")
if parse1 then if parse1 then
@ -285,7 +290,7 @@ minetest.register_chatcommand("weather", {
def.min_duration=duration def.min_duration=duration
def.max_duration=duration def.max_duration=duration
end end
mcl_weather.start_weather(def) mcl_weather.change(param,true)
return true return true
end end
return false, S("Error: Invalid weather specified. Use “clear”, “rain”, “snow” or “thunder”.") return false, S("Error: Invalid weather specified. Use “clear”, “rain”, “snow” or “thunder”.")

View File

@ -85,8 +85,14 @@ mcl_weather.register_weather("rain",{
} }
}, },
start = function() mcl_weather.rain.raining = true end, start = function() mcl_weather.rain.raining = true end,
start_player = function(name) end, start_player = function(name) end,
clear = function() mcl_weather.rain.raining = false end clear = function() mcl_weather.rain.raining = false end,
at_pos = function(pos)
local biome=minetest.get_biome_data(pos)
if mcl_worlds.has_weather(pos) and biome.heat > 15 and biome.heat < 95 then
return true
end
end
}) })
if mcl_weather.allow_abm then if mcl_weather.allow_abm then

View File

@ -17,16 +17,16 @@ mcl_weather.register_weather("snow",{
{r=0, g=0, b=0}}, {r=0, g=0, b=0}},
particlespawners = { particlespawners = {
{ {
amount = 30, amount = 99,
time = 0, time = 0,
minpos = vector.new(-15,5,-15), minpos = vector.new(-15,-5,-15),
maxpos =vector.new(15,10,15), maxpos =vector.new(15,10,15),
minvel = vector.new(0,-1,0), minvel = vector.new(0,-1,0),
maxvel = vector.new(0,-4,0), maxvel = vector.new(0,-4,0),
minacc = vector.new(0,-1,0), minacc = vector.new(0,-1,0),
maxacc = vector.new(0,-4,0), maxacc = vector.new(0,-4,0),
minexptime = 1, minexptime = 2,
maxexptime = 1, maxexptime = 5,
minsize = 0.5, minsize = 0.5,
maxsize = 5, maxsize = 5,
collisiondetection = true, collisiondetection = true,
@ -57,6 +57,17 @@ mcl_weather.register_weather("snow",{
} }
}, },
start = function() end, start = function() end,
start_player = function(name) end, start_player = function(name)
clear = function() end local player=minetest.get_player_by_name(name)
if not mcl_weather.snow.at_pos(player:get_pos()) then
return true
end
end,
clear = function() end,
at_pos = function(pos)
local biome=minetest.get_biome_data(pos)
if mcl_worlds.has_weather(pos) and biome.heat < 15 then
return true
end
end
}) })

View File

@ -90,8 +90,14 @@ mcl_weather.register_weather("thunder",{
start = function() start = function()
do_thunder(true) do_thunder(true)
end, end,
start_player = function(name) end, start_player = function(name) end,
clear = function() clear = function()
mcl_weather.skycolor.remove_layer("lightning") mcl_weather.skycolor.remove_layer("lightning")
end,
at_pos = function(pos)
local biome=minetest.get_biome_data(pos)
if mcl_worlds.has_weather(pos) and biome.heat > 15 and biome.heat < 95 then
return true
end
end end
}) })