168 lines
4.2 KiB
Lua
168 lines
4.2 KiB
Lua
-- Weather mod for Lazarr!
|
|
-- It features rain and lightning.
|
|
-- Lightning is handled by lzr_sky.
|
|
|
|
lzr_weather = {}
|
|
|
|
local RAIN_RESPAWN = 5
|
|
local LIGHTNING_TIMER_MIN = 1
|
|
local LIGHTNING_TIMER_MAX = 35
|
|
local LIGHTNING_DURATION = 0.1
|
|
|
|
-- local weather variables
|
|
local current_weather = "clear"
|
|
local weather_types = {
|
|
"clear",
|
|
"drizzle",
|
|
"rain",
|
|
"storm"
|
|
}
|
|
|
|
local lightning_pr = PseudoRandom(4291990 + minetest.get_us_time())
|
|
|
|
local last_particlespawner
|
|
|
|
local rain_timer = RAIN_RESPAWN
|
|
local lightning_timer = 0
|
|
local next_lightning_at = nil
|
|
|
|
-- Returns the current weather
|
|
function lzr_weather.get_weather()
|
|
return current_weather
|
|
end
|
|
|
|
function lzr_weather.get_weathers()
|
|
return weather_types
|
|
end
|
|
|
|
function lzr_weather.weather_exists(weather)
|
|
for w=1, #weather_types do
|
|
if weather_types[w] == weather then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
-- Set the current weather
|
|
function lzr_weather.set_weather(weather)
|
|
current_weather = weather
|
|
rain_timer = RAIN_RESPAWN
|
|
lightning_timer = 0
|
|
if last_particlespawner then
|
|
minetest.delete_particlespawner(last_particlespawner)
|
|
end
|
|
end
|
|
|
|
minetest.register_globalstep(
|
|
function(dtime)
|
|
-- Clear weather: Nothing to do
|
|
local state = lzr_gamestate.get_state()
|
|
if current_weather == "clear" then
|
|
return
|
|
end
|
|
|
|
-- Storm weather: Occasional lightning
|
|
if current_weather == "storm" then
|
|
lightning_timer = lightning_timer + dtime
|
|
-- Lightning active: turn off lightning sky after LIGHTNING_DURATION
|
|
if lzr_sky.get_lightning() == true then
|
|
if lightning_timer >= LIGHTNING_DURATION then
|
|
lzr_sky.set_lightning(false)
|
|
lightning_timer = 0
|
|
end
|
|
-- Lightning inactive: turn on lightning sky after a random time
|
|
else
|
|
if not next_lightning_at then
|
|
next_lightning_at = lightning_pr:next(LIGHTNING_TIMER_MIN, LIGHTNING_TIMER_MAX)
|
|
end
|
|
if lightning_timer >= next_lightning_at then
|
|
-- Note: The lightning sky remains active until we manually disable it
|
|
lzr_sky.set_lightning(true)
|
|
lightning_timer = 0
|
|
next_lightning_at = lightning_pr:next(LIGHTNING_TIMER_MIN, LIGHTNING_TIMER_MAX)
|
|
end
|
|
end
|
|
end
|
|
|
|
rain_timer = rain_timer + dtime
|
|
if rain_timer < RAIN_RESPAWN then
|
|
return
|
|
end
|
|
rain_timer = 0
|
|
|
|
-- Rainy weather: Spawn rain particles
|
|
local amount, fall_speed, min_size, max_size
|
|
if current_weather == "drizzle" then
|
|
amount = 200
|
|
fall_speed = 15
|
|
min_size = 1.8
|
|
max_size = 1.9
|
|
elseif current_weather == "rain" then
|
|
amount = 600
|
|
fall_speed = 16
|
|
min_size = 2.3
|
|
max_size = 2.6
|
|
elseif current_weather == "storm" then
|
|
amount = 1500
|
|
fall_speed = 20
|
|
min_size = 2.6
|
|
max_size = 3.0
|
|
else
|
|
return
|
|
end
|
|
|
|
local XZ_BUFFER = 4
|
|
local Y_BUFFER = 3
|
|
|
|
local spawn_min, spawn_max
|
|
if lzr_gamestate.get_state() == lzr_gamestate.MENU then
|
|
-- Weather at the "main menu ship" proably needs more work
|
|
spawn_min = {
|
|
x = lzr_globals.MENU_SHIP_POS.x - XZ_BUFFER,
|
|
y = lzr_globals.MENU_SHIP_POS.y + 20,
|
|
z = lzr_globals.MENU_SHIP_POS.z - XZ_BUFFER,
|
|
}
|
|
spawn_max = {
|
|
x = lzr_globals.MENU_SHIP_POS.x + XZ_BUFFER + 20,
|
|
y = lzr_globals.MENU_SHIP_POS.y + 20,
|
|
z = lzr_globals.MENU_SHIP_POS.z + XZ_BUFFER + 35,
|
|
}
|
|
else
|
|
spawn_min = {
|
|
x = lzr_globals.PLAYFIELD_START.x - XZ_BUFFER,
|
|
y = lzr_globals.PLAYFIELD_START.y + lzr_globals.PLAYFIELD_SIZE.y + Y_BUFFER,
|
|
z = lzr_globals.PLAYFIELD_START.z - XZ_BUFFER,
|
|
}
|
|
spawn_max = {
|
|
x = lzr_globals.PLAYFIELD_START.x + lzr_globals.PLAYFIELD_SIZE.x + XZ_BUFFER,
|
|
y = lzr_globals.PLAYFIELD_START.y + lzr_globals.PLAYFIELD_SIZE.y + Y_BUFFER,
|
|
z = lzr_globals.PLAYFIELD_START.z + lzr_globals.PLAYFIELD_SIZE.z + XZ_BUFFER,
|
|
}
|
|
end
|
|
-- Don't spawn particles if area is not loaded yet
|
|
if minetest.get_node_or_nil(spawn_min) == nil or minetest.get_node_or_nil(spawn_max) == nil then
|
|
return
|
|
end
|
|
|
|
last_particlespawner = minetest.add_particlespawner({
|
|
amount = amount,
|
|
time = RAIN_RESPAWN,
|
|
minpos = spawn_min,
|
|
maxpos = spawn_max,
|
|
minvel = {x = 0, y = -fall_speed, z = 0},
|
|
maxvel = {x = 0, y = -fall_speed, z = 0},
|
|
minexptime = 3,
|
|
maxexptime = 3,
|
|
minsize = min_size,
|
|
maxsize = max_size,
|
|
collisiondetection = true,
|
|
collision_removal = true,
|
|
vertical = true,
|
|
texture = "lzr_weather_rain.png",
|
|
})
|
|
|
|
end
|
|
)
|
|
|