Camas/mods/weather/init.lua

205 lines
5.5 KiB
Lua
Raw Normal View History

2015-09-01 17:15:24 +02:00
--
-- Weather mod
-- By Kaadmy, for Pixture
--
2019-08-28 17:31:41 +02:00
local S = minetest.get_translator("weather")
2019-09-21 18:16:49 +02:00
local mod_storage = minetest.get_mod_storage()
2015-09-01 17:15:24 +02:00
weather = {}
weather.weather = "clear"
2019-09-21 17:56:38 +02:00
weather.types = {"storm", "clear"}
2015-09-01 17:15:24 +02:00
2019-09-21 17:52:54 +02:00
local sound_handles = {}
2015-09-01 17:15:24 +02:00
local function addvec(v1, v2)
return {x = v1.x + v2.x, y = v1.y + v2.y, z = v1.z + v2.z}
end
local mapseed = minetest.get_mapgen_setting("seed")
local weather_pr=PseudoRandom(mapseed + 2387)
2015-09-01 17:15:24 +02:00
2017-07-03 02:14:15 +02:00
local sound_min_height = -20 -- Below -20m you can't hear weather
local default_cloud_state = nil
local function update_sounds(do_repeat)
2015-12-16 19:01:43 +01:00
if weather.weather == "storm" then
2017-07-03 02:14:15 +02:00
for _, player in ipairs(minetest.get_connected_players()) do
2019-09-21 17:52:54 +02:00
local name = player:get_player_name()
if player:get_pos().y > sound_min_height then
2019-09-21 17:52:54 +02:00
if not sound_handles[name] then
sound_handles[name] = minetest.sound_play(
{ name = "weather_storm" }, { to_player = name, loop = true, fade = 0.5 }
)
end
else
if sound_handles[name] then
minetest.sound_fade(sound_handles[name], -0.5, 0)
2019-09-21 17:52:54 +02:00
sound_handles[name] = nil
end
2017-07-03 02:14:15 +02:00
end
end
2019-09-21 17:52:54 +02:00
else
for _, player in ipairs(minetest.get_connected_players()) do
local name = player:get_player_name()
if sound_handles[name] then
minetest.sound_fade(sound_handles[name], -1.0, 0)
2019-09-21 17:52:54 +02:00
sound_handles[name] = nil
end
end
2015-09-01 17:15:24 +02:00
end
if do_repeat then
2019-09-21 18:19:09 +02:00
minetest.after(3, update_sounds, do_repeat)
end
2015-09-01 17:15:24 +02:00
end
local function setweather_type(type, do_repeat)
2015-09-01 17:15:24 +02:00
local valid = false
for i = 1, #weather.types do
if weather.types[i] == type then
valid = true
end
end
if valid then
weather.weather = type
2019-09-21 18:16:49 +02:00
mod_storage:set_string("weather:weather", weather.weather)
2019-09-21 18:11:54 +02:00
minetest.log("action", "[weather] Weather set to: "..weather.weather)
update_sounds(do_repeat)
2019-06-23 21:05:52 +02:00
return true
else
return false
2015-09-01 17:15:24 +02:00
end
end
minetest.register_globalstep(
2015-09-01 17:15:24 +02:00
function(dtime)
if minetest.settings:get_bool("weather_enable") then
2015-09-01 17:15:24 +02:00
if weather_pr:next(0, 5000) < 1 then
local weathertype = weather_pr:next(0, 19)
2019-09-21 18:11:54 +02:00
-- on avg., every 1800 globalsteps, the weather.weather will change to one of:
2015-09-01 17:15:24 +02:00
-- 13/20 chance of clear weather
2019-09-21 18:11:54 +02:00
-- 7/20 chance or stormy weather
2015-09-01 17:15:24 +02:00
2019-09-21 18:11:54 +02:00
local oldweather = weather.weather
2015-09-01 17:15:24 +02:00
if weathertype < 13 then
weather.weather = "clear"
2019-09-21 18:11:54 +02:00
else
2015-09-01 17:15:24 +02:00
weather.weather = "storm"
end
2019-09-21 18:11:54 +02:00
if oldweather ~= weather.weather then
2019-09-21 18:16:49 +02:00
mod_storage:set_string("weather:weather", weather.weather)
2019-09-21 18:11:54 +02:00
minetest.log("action", "[weather] Weather changed to: "..weather.weather)
update_sounds()
end
2015-09-01 17:15:24 +02:00
end
end
local light = (minetest.get_timeofday() * 2)
2015-09-01 17:15:24 +02:00
if light > 1 then
light = 1 - (light - 1)
2015-09-01 17:15:24 +02:00
end
light = (light * 0.5) + 0.15
local skycol = math.floor(light * 190)
2015-09-01 17:15:24 +02:00
for _, player in ipairs(minetest.get_connected_players()) do
2019-09-21 17:56:38 +02:00
if weather.weather == "storm" then
player:set_sky({r = skycol, g = skycol, b = skycol * 1.2}, "plain", {}, true)
if default_cloud_state == nil then
default_cloud_state = player:get_clouds()
end
player:set_clouds({
density = 0.5,
color = "#a0a0a0f0",
ambient = "#000000",
height = 100,
thickness = 40,
speed = {x = -2, y = 1},
})
2015-09-01 17:15:24 +02:00
player:override_day_night_ratio(light)
else
player:set_sky(nil, "regular", {}, true)
if default_cloud_state ~= nil then
player:set_clouds(default_cloud_state)
end
2015-09-01 17:15:24 +02:00
player:override_day_night_ratio(nil)
end
local p=player:get_pos()
2015-09-01 17:15:24 +02:00
if weather.weather == "storm" then
if minetest.get_node_light({x=p.x, y=p.y+15, z=p.z}, 0.5) == 15 then
local minpos = addvec(player:get_pos(), {x = -15, y = 15, z = -15})
local maxpos = addvec(player:get_pos(), {x = 15, y = 10, z = 15})
minetest.add_particlespawner(
2015-09-01 17:15:24 +02:00
{
amount = 30,
time = 0.5,
minpos = minpos,
maxpos = maxpos,
minvel = {x = 0, y = -20, z = 0},
maxvel = {x = 0, y = -20, z = 0},
minexptime = 0.9,
maxexptime = 1.1,
minsize = 2,
maxsize = 3,
collisiondetection = true,
collision_removal = true,
2015-09-01 17:15:24 +02:00
vertical = true,
texture = "weather_rain.png",
playername = player:get_player_name()
}
)
end
end
end
end
)
minetest.register_privilege(
"weather",
{
2019-08-28 17:31:41 +02:00
description = S("Can change the weather using the /weather command"),
give_to_singleplayer = false
})
2015-09-01 17:15:24 +02:00
minetest.register_chatcommand(
2015-09-01 17:15:24 +02:00
"weather",
{
2019-09-21 17:56:38 +02:00
params = "storm | clear",
2019-08-28 17:31:41 +02:00
description = S("Change the weather"),
privs = {weather = true},
2015-09-01 17:15:24 +02:00
func = function(name, param)
2019-06-23 21:05:52 +02:00
local weather_set = setweather_type(param)
if not weather_set then
2019-09-21 17:56:38 +02:00
return false, S("Incorrect weather. Valid weathers are “storm” and “clear”.")
2019-06-23 21:05:52 +02:00
else
2019-08-28 17:31:41 +02:00
return true, S("Weather changed.")
2019-06-23 21:05:52 +02:00
end
end
})
2015-09-01 17:15:24 +02:00
2019-09-21 17:52:54 +02:00
minetest.register_on_leaveplayer(function(player)
sound_handles[player:get_player_name()] = nil
end)
2019-09-21 18:16:49 +02:00
local loaded_weather = mod_storage:get_string("weather:weather")
if loaded_weather == "" then
setweather_type("clear", true)
else
setweather_type(loaded_weather, true)
end
2015-09-01 17:15:24 +02:00
default.log("mod:weather", "loaded")