Implement more logical weather transitions

This commit is contained in:
Wuzzy 2017-11-12 06:57:11 +01:00
parent 15b96ff7cf
commit f0e0e754b0
4 changed files with 47 additions and 36 deletions

View File

@ -160,8 +160,8 @@ rain.make_weather = function()
if rain.init_done == false then if rain.init_done == false then
rain.raining = true rain.raining = true
rain.set_sky_box() rain.set_sky_box()
rain.init_done = true
rain.set_particles_mode(weather.mode) rain.set_particles_mode(weather.mode)
rain.init_done = true
end end
for _, player in ipairs(minetest.get_connected_players()) do for _, player in ipairs(minetest.get_connected_players()) do
@ -238,10 +238,14 @@ end
if weather.reg_weathers.rain == nil then if weather.reg_weathers.rain == nil then
weather.reg_weathers.rain = { weather.reg_weathers.rain = {
chance = 15,
clear = rain.clear, clear = rain.clear,
-- 10min - 20min -- 10min - 20min
min_duration = 600, min_duration = 600,
max_duration = 1200, max_duration = 1200,
transitions = {
[65] = "none",
[70] = "snow",
[100] = "thunder",
}
} }
end end

View File

@ -83,11 +83,15 @@ end)
-- register snow weather -- register snow weather
if weather.reg_weathers.snow == nil then if weather.reg_weathers.snow == nil then
weather.reg_weathers.snow = { weather.reg_weathers.snow = {
chance = 10,
clear = snow.clear, clear = snow.clear,
-- 10min - 20min -- 10min - 20min
min_duration = 600, min_duration = 600,
max_duration = 1200, max_duration = 1200,
transitions = {
[65] = "none",
[80] = "rain",
[100] = "thunder",
}
} }
end end

View File

@ -49,10 +49,12 @@ end
-- register thunderstorm weather -- register thunderstorm weather
if weather.reg_weathers.thunder == nil then if weather.reg_weathers.thunder == nil then
weather.reg_weathers.thunder = { weather.reg_weathers.thunder = {
chance = 5,
clear = thunder.clear, clear = thunder.clear,
-- 10min - 20min -- 10min - 20min
min_duration = 600, min_duration = 600,
max_duration = 1200, max_duration = 1200,
transitions = {
[100] = "rain",
}
} }
end end

View File

@ -5,9 +5,6 @@ weather = {
-- player list for saving player meta info -- player list for saving player meta info
players = {}, players = {},
-- time when weather should be re-calculated
next_check = nil,
-- default weather recalculation interval -- default weather recalculation interval
check_interval = 300, check_interval = 300,
@ -30,12 +27,24 @@ weather = {
allow_abm = true, allow_abm = true,
} }
weather.reg_weathers["none"] = {
min_duration = weather.min_duration,
max_duration = weather.max_duration,
transitions = {
[50] = "rain",
[100] = "snow",
},
clear = function() end,
}
weather.get_rand_end_time = function(min_duration, max_duration) weather.get_rand_end_time = function(min_duration, max_duration)
local r
if min_duration ~= nil and max_duration ~= nil then if min_duration ~= nil and max_duration ~= nil then
return minetest.get_gametime() + math.random(min_duration, max_duration); r = math.random(min_duration, max_duration);
else else
return minetest.get_gametime() + math.random(weather.min_duration, weather.max_duration); r = math.random(weather.min_duration, weather.max_duration);
end end
return minetest.get_gametime() + r
end end
-- Returns true if pos is outdoor. -- Returns true if pos is outdoor.
@ -105,30 +114,28 @@ minetest.register_globalstep(function(dtime)
if weather.end_time == nil then if weather.end_time == nil then
weather.end_time = weather.get_rand_end_time() weather.end_time = weather.get_rand_end_time()
end end
if weather.next_check == nil then -- recalculate weather
weather.next_check = minetest.get_gametime() + weather.check_interval if weather.end_time <= minetest.get_gametime() then
end weather.set_random_weather(weather.state, weather.reg_weathers[weather.state])
-- recalculate weather only when there aren't currently any
if (weather.state ~= "none") then
if (weather.end_time ~= nil and weather.end_time <= minetest.get_gametime()) then
weather.reg_weathers[weather.state].clear()
weather.state = "none"
end
elseif (weather.next_check <= minetest.get_gametime()) then
for weather_name, weather_meta in pairs(weather.reg_weathers) do
weather.set_random_weather(weather_name, weather_meta)
end
end end
end) end)
-- sets random weather (which could be 'regular' (no weather)). -- sets random weather (which could be 'regular' (no weather)).
weather.set_random_weather = function(weather_name, weather_meta) weather.set_random_weather = function(weather_name, weather_meta)
if (weather_meta ~= nil and weather_meta.chance ~= nil) then if (weather_meta ~= nil) then
local transitions = weather_meta.transitions
local random_roll = math.random(0,100) local random_roll = math.random(0,100)
if (random_roll <= weather_meta.chance) then local new_weather
weather.state = weather_name for v, weather in pairs(transitions) do
weather.end_time = weather.get_rand_end_time(weather_meta.min_duration, weather_meta.max_duration) if random_roll < v then
weather.next_check = minetest.get_gametime() + weather.check_interval new_weather = weather
break
end
end
if new_weather then
weather.state = new_weather
weather.end_time = weather.get_rand_end_time(weather.reg_weathers[weather.state].min_duration, weather.reg_weathers[weather.state].max_duration)
weather.reg_weathers[weather_name].clear()
end end
end end
end end
@ -150,9 +157,7 @@ minetest.register_chatcommand("weather", {
end end
local success = false local success = false
if (param == "clear") then if (param == "clear") then
if (weather.state ~= nil and weather.reg_weathers[weather.state] ~= nil) then weather.reg_weathers[weather.state].clear()
weather.reg_weathers[weather.state].clear()
end
weather.state = "none" weather.state = "none"
weather.end_time = weather.get_rand_end_time() weather.end_time = weather.get_rand_end_time()
success = true success = true
@ -180,9 +185,7 @@ minetest.register_chatcommand("toggledownfall", {
func = function(name, param) func = function(name, param)
-- Currently rain/thunder/snow: Set weather to clear -- Currently rain/thunder/snow: Set weather to clear
if weather.state ~= "none" then if weather.state ~= "none" then
if (weather.state ~= nil and weather.state ~= "none" and weather.reg_weathers[weather.state] ~= nil) then weather.reg_weathers[weather.state].clear()
weather.reg_weathers[weather.state].clear()
end
weather.state = "none" weather.state = "none"
weather.end_time = weather.get_rand_end_time() weather.end_time = weather.get_rand_end_time()
@ -190,9 +193,7 @@ minetest.register_chatcommand("toggledownfall", {
else else
local new = { "rain", "thunder", "snow" } local new = { "rain", "thunder", "snow" }
local r = math.random(1, #new) local r = math.random(1, #new)
if (weather.state ~= nil and weather.state ~= "none" and weather.reg_weathers[weather.state] ~= nil) then weather.reg_weathers[weather.state].clear()
weather.reg_weathers[weather.state].clear()
end
weather.state = new[r] weather.state = new[r]
local weather_meta = weather.reg_weathers[weather.state] local weather_meta = weather.reg_weathers[weather.state]
weather.end_time = weather.get_rand_end_time(weather_meta.min_duration, weather_meta.max_duration) weather.end_time = weather.get_rand_end_time(weather_meta.min_duration, weather_meta.max_duration)