-- 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 )