Add rainy weather support and storm_clouds sky
This commit is contained in:
parent
90d008effe
commit
9f933f4cbb
@ -24,6 +24,7 @@ All levels by Wuzzy.
|
||||
|
||||
- Water, wood, tree, stone, tools, hand, gold block, wooden chest, locked wooden chest, ship lightbox, player textures, crates, seaweed, purple coral, crab grass, fire, candle (standing, wall, wield) come from “PixelBOX” texture pack by jp (CC0)
|
||||
- Hanging candle by Wuzzy (CC0)
|
||||
- Raindrop by Wuzzy (CC0)
|
||||
- Textures in `lzr_decor` mod made by jp (CC0)
|
||||
- Barricade, dark chest made by jp (CC0)
|
||||
- Skulls by Mikita "rudzik8" Wiśniewski (CC BY-SA 3.0)
|
||||
|
@ -29,6 +29,9 @@ local TIMEOFDAY_NIGHT_END = 0.15
|
||||
-- Check the timeofday to reset every this many seconds
|
||||
local TIMEOFDAY_RESET_TIME = 5.0
|
||||
|
||||
-- True if the special lightning sky is currently acitve
|
||||
local lightning_active = false
|
||||
|
||||
-- Currently active sky
|
||||
local current_sky
|
||||
|
||||
@ -87,12 +90,27 @@ function lzr_sky.set_sky(skyname)
|
||||
reset_timeofday(skyname)
|
||||
|
||||
local skyskydef = table.copy(skydef.sky)
|
||||
if lightning_active and skyskydef.sky_color then
|
||||
-- Lightning takes precedence on the sky color.
|
||||
-- When the lightning is over, the real sky
|
||||
-- color is applied.
|
||||
skyskydef.sky_color.type = nil
|
||||
skyskydef.sky_color.day_sky = nil
|
||||
skyskydef.sky_color.day_horizon = nil
|
||||
skyskydef.sky_color.dawn_sky = nil
|
||||
skyskydef.sky_color.dawn_horizon = nil
|
||||
skyskydef.sky_color.night_sky = nil
|
||||
skyskydef.sky_color.night_horizon = nil
|
||||
end
|
||||
player:set_sky(skyskydef)
|
||||
player:set_clouds(skydef.clouds)
|
||||
player:set_sun(skydef.sun)
|
||||
player:set_moon(skydef.moon)
|
||||
player:set_stars(skydef.stars)
|
||||
player:override_day_night_ratio(skydef.day_night_ratio)
|
||||
-- Lightning takes precendence for day night ratio
|
||||
if not lightning_active then
|
||||
player:override_day_night_ratio(skydef.day_night_ratio)
|
||||
end
|
||||
|
||||
-- Remember skyname for later
|
||||
current_sky = skyname
|
||||
@ -104,6 +122,34 @@ function lzr_sky.get_sky()
|
||||
return current_sky
|
||||
end
|
||||
|
||||
function lzr_sky.get_lightning()
|
||||
return lightning_active
|
||||
end
|
||||
|
||||
function lzr_sky.set_lightning(active)
|
||||
local player = minetest.get_player_by_name("singleplayer")
|
||||
if active then
|
||||
-- Activate flash
|
||||
lightning_active = true
|
||||
player:override_day_night_ratio(1)
|
||||
player:set_sky({
|
||||
type = "plain",
|
||||
base_color = "#ffffff",
|
||||
})
|
||||
minetest.log("info", "[lzr_sky] Lightning activated!")
|
||||
else
|
||||
-- Deactivate flash
|
||||
lightning_active = false
|
||||
local skydef = registered_skies[current_sky]
|
||||
-- (Re-)Apply the sky and day/night ratio of the current sky
|
||||
if skydef then
|
||||
player:set_sky(skydef.sky)
|
||||
end
|
||||
player:override_day_night_ratio(skydef.day_night_ratio)
|
||||
minetest.log("verbose", "[lzr_sky] Lightning deactivated!")
|
||||
end
|
||||
end
|
||||
|
||||
-- Regularily check if the timeofday falls into the permissble range
|
||||
-- of timeofday values for the current sky and if not, reset
|
||||
-- it. This code is a workaround for the fact we cannot yet
|
||||
@ -135,6 +181,7 @@ end)
|
||||
|
||||
register_sky("bright_blue", {
|
||||
sky = {
|
||||
type = "regular",
|
||||
sky_color = {
|
||||
day_sky="#3d4caa",
|
||||
day_horizon="#55aaff",
|
||||
@ -155,6 +202,7 @@ register_sky("bright_blue", {
|
||||
})
|
||||
register_sky("tropical_dawn", {
|
||||
sky = {
|
||||
type = "regular",
|
||||
sky_color = {
|
||||
day_sky="#d20000",
|
||||
day_horizon="#ff6c09",
|
||||
@ -176,6 +224,7 @@ register_sky("tropical_dawn", {
|
||||
})
|
||||
register_sky("ocean_evening", {
|
||||
sky = {
|
||||
type = "regular",
|
||||
sky_color = {
|
||||
day_sky="#3d374d",
|
||||
day_horizon="#5a2a34",
|
||||
@ -201,6 +250,7 @@ register_sky("ocean_evening", {
|
||||
})
|
||||
register_sky("ocean_morning", {
|
||||
sky = {
|
||||
type = "regular",
|
||||
sky_color = {
|
||||
day_sky="#5184a2",
|
||||
day_horizon="#ffb754",
|
||||
@ -222,6 +272,7 @@ register_sky("ocean_morning", {
|
||||
})
|
||||
register_sky("ominous_fog", {
|
||||
sky = {
|
||||
type = "regular",
|
||||
sky_color = {
|
||||
day_sky="#e7deff",
|
||||
day_horizon="#e1deff",
|
||||
@ -243,8 +294,34 @@ register_sky("ominous_fog", {
|
||||
timeofday_start = TIMEOFDAY_DAY_START,
|
||||
timeofday_end = TIMEOFDAY_DAY_END,
|
||||
})
|
||||
register_sky("storm_clouds", {
|
||||
sky = {
|
||||
type = "regular",
|
||||
sky_color = {
|
||||
day_sky="#808080",
|
||||
day_horizon="#808080",
|
||||
},
|
||||
fog = {
|
||||
fog_distance = 60,
|
||||
fog_start = 0.2,
|
||||
},
|
||||
},
|
||||
clouds = {
|
||||
height = 100,
|
||||
thickness = 40,
|
||||
density = 0.7,
|
||||
color = "#808080aa",
|
||||
},
|
||||
stars = { visible = false },
|
||||
sun = { visible = false, sunrise_visible = false },
|
||||
moon = { visible = false },
|
||||
timeofday_start = TIMEOFDAY_DAY_START,
|
||||
timeofday_end = TIMEOFDAY_DAY_END,
|
||||
day_night_ratio = 0.7,
|
||||
})
|
||||
register_sky("starry_night", {
|
||||
sky = {
|
||||
type = "regular",
|
||||
sky_color = {
|
||||
day_sky="#000020",
|
||||
day_horizon="#000020",
|
||||
|
27
mods/lzr_weather/API.md
Normal file
27
mods/lzr_weather/API.md
Normal file
@ -0,0 +1,27 @@
|
||||
# `lzr_weather` API
|
||||
|
||||
This mod adds rain and lightning. The weather can *only* be changed by API calls.
|
||||
Weather is independent from the sky, and no sound effects are included;
|
||||
those are supposed to be done by other mods.
|
||||
|
||||
## Weather types
|
||||
|
||||
The following weather types are available:
|
||||
|
||||
* `"clear"`: Clear weather (does nothing)
|
||||
* `"drizzle"`: Light rain
|
||||
* `"rain"`: Medium rain
|
||||
* `"storm"`: Heavy rain and occassional lightning
|
||||
|
||||
## Functions
|
||||
|
||||
The following functions are available:
|
||||
|
||||
### `lzr_weather.get_weather()`
|
||||
|
||||
Returns the current weather as a string.
|
||||
|
||||
### `lzr_weather.set_weather(weather_type)`
|
||||
|
||||
Set the weather to the specified weather type.
|
||||
|
154
mods/lzr_weather/init.lua
Normal file
154
mods/lzr_weather/init.lua
Normal file
@ -0,0 +1,154 @@
|
||||
-- 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
|
||||
|
||||
-- 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
|
||||
)
|
||||
|
2
mods/lzr_weather/mod.conf
Normal file
2
mods/lzr_weather/mod.conf
Normal file
@ -0,0 +1,2 @@
|
||||
name = lzr_weather
|
||||
depends = lzr_globals, lzr_sky
|
BIN
mods/lzr_weather/textures/lzr_weather_rain.png
Normal file
BIN
mods/lzr_weather/textures/lzr_weather_rain.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 150 B |
Loading…
x
Reference in New Issue
Block a user