weather = {} -- Special (unnatural) weather types must be listed last local weathers = { "snow", "rain", "storm", "none", "locusts", "pennies" } -- NormalWeatherTypes = Number of normal weather types -- TotalWeatherTypes = Total number of weather types local NormalWeatherTypes = 4 local TotalWeatherTypes = 6 -- =================================================================== local function numsetzero (name) return (tonumber (minetest.setting_get (name))) or 0 end -- =================================================================== local snow_particles_count = numsetzero ("snow_particles_count" ) if snow_particles_count < 2 then snow_particles_count = 2 end if snow_particles_count > 25 then snow_particles_count = 25 end -- =================================================================== local snow_particles_range = numsetzero ("snow_particles_range" ) if snow_particles_range < 5 then snow_particles_range = 5 end if snow_particles_range > 50 then snow_particles_range = 50 end -- =================================================================== local winter_wonderland = minetest.setting_getbool ("winter_wonderland" ) -- =================================================================== local apply_weather = function (player, pos, weather_type) if weather_type == nil then return end if weather_type == "locust" then weather_type = "locusts" end if weather_type == "penny" then weather_type = "pennies" end if weather_type == "normal" or weather_type == "regular" then weather_type = "none" end local pos = player:getpos() if pos.y > 1000 then return end if pos.y < -10 then return end local tod = minetest.get_timeofday() * 24000 if weather_type == "snow" or weather_type == "locusts" or weather_type == "pennies" then if tod >= 6000 and tod <= 19000 then codersky.set_sky (player, { r=178, g=193, b=208 }, "plain", nil, false) else codersky.set_sky (player, nil, "regular", nil, false) end local weather_particles_range = 10 local weather_particles_count = 15 if weather_type == "snow" then if snow_particles_count ~= nil then weather_particles_count = snow_particles_count end if snow_particles_range ~= nil then weather_particles_range = snow_particles_range end end for ii = 1, weather_particles_count do local texture if weather_type == "locusts" then texture = "weather_locusts.png" elseif weather_type == "pennies" then texture = "weather_pennies_" .. math.random (1,2) .. ".png" else texture = "weather_snow_" .. math.random (1,2) .. ".png" end minetest.add_particle ({ pos = { x=pos.x+math.random (-weather_particles_range , weather_particles_range) , y=pos.y+math.random (12, 17) , z=pos.z+math.random (-weather_particles_range , weather_particles_range) , } , velocity = { x=math.random (-5, 5) / 10 , y=math.random (-4, -6) , z=math.random (-5, 5) / 10 , } , acceleration = { x=math.random (-1, 1) /10 , y=math.random (-5, -10) /10 , z=math.random (-1, 1) /10 , } , expirationtime = 3, size = math.random (3, 5), collisiondetection = true, collision_removal = true, vertical = false, texture = texture , glow = 0 }) end elseif weather_type == "rain" then if tod >= 6000 and tod <= 19000 then codersky.set_sky (player, { r=148, g=148, b=148 }, "plain", nil, false) else codersky.set_sky (player, nil, "regular", nil, false) end for ii = 1, 15 do minetest.add_particle ({ pos = { x=pos.x+math.random(-10,10), y=pos.y+math.random(12,17), z=pos.z+math.random(-10,10)}, velocity = {x=0, y=math.random(-15,-20), z=0}, acceleration = {x=0, y=-1, z=0}, expirationtime = 2, size = math.random(3,5), collisiondetection = true, collision_removal = true, vertical = true, texture = "weather_rain_"..math.random(1,2)..".png", glow = 0 }) end elseif weather_type == "storm" then if tod >= 6000 and tod <= 19000 then codersky.set_sky (player, { r=101, g=101, b=101 }, "plain", nil, false) else codersky.set_sky (player, nil, "regular", nil, false) end for ii = 1, 30 do minetest.add_particle ({ pos = {x=pos.x+math.random(-10,10), y=pos.y+math.random(12,17), z=pos.z+math.random(-10,10)}, velocity = {x=0, y=math.random(-25,-30), z=0}, acceleration = {x=0, y=-1, z=0}, expirationtime = 2, size = math.random(3,5), collisiondetection = true, collision_removal = true, vertical = true, texture = "weather_rain_3.png", glow = 0 }) if minetest.get_modpath ("lightning") and math.random (1,2000) == 1 then lightning.strike() end end elseif weather_type == "none" then codersky.set_sky (player, nil, "regular", nil, false) end end -- =================================================================== local function setweather (param) local ii for ii = 1, TotalWeatherTypes do if weathers [ii] == param then weather.current = ii weather.weather = param end end end -- =================================================================== minetest.register_globalstep (function (dtime) if math.random (1, 4) ~= 4 then return end if winter_wonderland then if weather.weather ~= "snow" then setweather ("snow") end elseif math.random (1, 5000) == 1 then local num = math.random (1, NormalWeatherTypes) weather.current = num weather.weather = weathers [num] end for _, player in ipairs (minetest.get_connected_players()) do local pos = player:getpos() -- Should weather occur at current position? local display_weather = true if pos.y <= -20 or pos.y >= 1000 then display_weather = false end -- apply weather effect if display_weather then apply_weather (player, pos, weather.weather) else apply_weather (player, pos, "none") end end end) -- =================================================================== minetest.register_privilege ("weather", { description = "Allows control of weather" , give_to_singleplayer = false }) -- =================================================================== local table_setweather = { params = "" , description = "Sets weather to the given type", privs = { weather = true } , func = function (name, param) if param == "normal" then param = "none" end setweather (param) end , } minetest.register_chatcommand ("setweather" , table_setweather) minetest.register_chatcommand ("weather" , table_setweather) -- =================================================================== minetest.register_chatcommand ("rain", { params = nil , description = "Sets weather to rain" , privs = { weather = true } , func = function (name, param) setweather ("rain") end , }) -- =================================================================== minetest.register_chatcommand ("snow", { params = nil , description = "Sets weather to snow" , privs = { weather = true } , func = function (name, param) setweather ("snow") end , }) -- =================================================================== minetest.register_chatcommand ("storm", { params = nil , description = "Sets weather to storm" , privs = { weather = true } , func = function (name, param) setweather ("storm") end , }) -- =================================================================== minetest.register_chatcommand ("regular", { params = nil , description = "Sets weather to normal" , privs = { weather = true } , func = function (name, param) setweather ("none") end , }) -- =================================================================== local table_locusts = { params = nil , description = "Plague of Locusts" , privs = { weather = true } , func = function (name, param) setweather ("locusts") end , } minetest.register_chatcommand ("locust" , table_locusts) minetest.register_chatcommand ("locusts" , table_locusts) -- =================================================================== local table_pennies = { params = nil , description = "Pennies from Heaven" , privs = { weather = true } , func = function (name, param) setweather ("pennies") end , } minetest.register_chatcommand ("pennies" , table_pennies) minetest.register_chatcommand ("penny" , table_pennies)