Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
1057342ac6 | |||
e24b0340e5 | |||
c9d0cfca21 | |||
d1bdf92937 | |||
0c5c9f0d15 | |||
a6cfca7745 | |||
241a0a82c1 | |||
18045b1943 |
@ -8,8 +8,12 @@ Climate API provides temperature and humidity values on a block-per-block basis
|
|||||||
that follow the seasons, day / night cycle and random changes.
|
that follow the seasons, day / night cycle and random changes.
|
||||||
Make it rain, change the sky or poison the player - it's up to you.
|
Make it rain, change the sky or poison the player - it's up to you.
|
||||||
|
|
||||||
|
## Assets
|
||||||
|
- Sun and moon textures: *CC BY-SA (3.0)* by Cap
|
||||||
|
|
||||||
## Assets in screenshots
|
## Assets in screenshots
|
||||||
- All screenshots and editing by me: *CC BY-SA (4.0)*
|
- Screenshots and editing by me: *CC BY-SA (3.0)*
|
||||||
|
- Logos and artwork: *CC BY-SA (3.0)* by Cap
|
||||||
- Lato Font (for the Logo): *OFL* by Łukasz Dziedzic from http://www.latofonts.com/lato-free-fonts/
|
- Lato Font (for the Logo): *OFL* by Łukasz Dziedzic from http://www.latofonts.com/lato-free-fonts/
|
||||||
- Liberation Fonts (for the text): *OFL*, see https://github.com/liberationfonts/liberation-fonts
|
- Liberation Fonts (for the text): *OFL*, see https://github.com/liberationfonts/liberation-fonts
|
||||||
- Used texture pack: Polygonia (128px edition) *CC BY-SA (4.0)* by Lokrates. See https://forum.minetest.net/viewtopic.php?f=4&t=19043
|
- Used texture pack: Polygonia (128px edition) *CC BY-SA (4.0)* by Lokrates. See https://forum.minetest.net/viewtopic.php?f=4&t=19043
|
26
ROADMAP.md
@ -1,30 +1,19 @@
|
|||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
## Required for MVP
|
|
||||||
- Find good values for weather conditions
|
|
||||||
- Make sure all weather presets are working
|
|
||||||
|
|
||||||
## Required for Beta
|
## Required for Beta
|
||||||
- Ability to register environment conditions dynamically (like the heat)
|
- Write helpful README
|
||||||
|
|
||||||
## Planned for first release
|
## Planned for first release
|
||||||
- Improve test_condition function
|
- Improve value structures of particle effects
|
||||||
- Write helpful README
|
- Find good values for weather conditions
|
||||||
- Set effects on player join
|
- Write documentation on how to add weathers and effects
|
||||||
- Improve value structures of particle and skybox effects
|
- Ability to register global influences that are the same for any position
|
||||||
- Make sounds adjust to changes by weather presets
|
|
||||||
- Ability to force set a wind speed via chat commands
|
|
||||||
|
|
||||||
## Nice to have
|
## Nice to have
|
||||||
- Write documentation on how to add weathers and effects
|
|
||||||
- Assign meta data (like "downfall", "wind", etc.) to weather presets
|
- Assign meta data (like "downfall", "wind", etc.) to weather presets
|
||||||
- Fog effects
|
|
||||||
- Optimize performance by replacing some particles with animated texture planes
|
- Optimize performance by replacing some particles with animated texture planes
|
||||||
- Make switches between effects more smooth
|
|
||||||
- Adjust size of particle boxes based on player speed
|
- Adjust size of particle boxes based on player speed
|
||||||
- Create conditions for time of day, annual progression, biome filters
|
- Generate wind based on speed and yaw instead of x and z values
|
||||||
- Fork lightning so that it uses skylayer
|
|
||||||
- Support for sail boats mod
|
|
||||||
|
|
||||||
## Future Plans & Ideas
|
## Future Plans & Ideas
|
||||||
- Complete season system
|
- Complete season system
|
||||||
@ -51,4 +40,5 @@
|
|||||||
- swimming will cool down
|
- swimming will cool down
|
||||||
- standing near fire will warm up
|
- standing near fire will warm up
|
||||||
- craftable warm clothes
|
- craftable warm clothes
|
||||||
- metal armor will worsen heat issues
|
- metal armor will worsen heat issues
|
||||||
|
- A flag indicating wind direction
|
@ -4,9 +4,25 @@ local EFFECT_NAME = "climate_api:hud_overlay"
|
|||||||
|
|
||||||
local handles = {}
|
local handles = {}
|
||||||
local function apply_hud(pname, weather, hud)
|
local function apply_hud(pname, weather, hud)
|
||||||
if handles[pname] == nil then handles[pname] = {} end
|
|
||||||
if handles[pname][weather] ~= nil then return end
|
|
||||||
local player = minetest.get_player_by_name(pname)
|
local player = minetest.get_player_by_name(pname)
|
||||||
|
if handles[pname] == nil then handles[pname] = {} end
|
||||||
|
if handles[pname][weather] ~= nil then
|
||||||
|
player:hud_remove(handles[pname][weather])
|
||||||
|
end
|
||||||
|
|
||||||
|
local file
|
||||||
|
if hud.color_correction then
|
||||||
|
local pos = vector.add(player:get_pos(), {x = 0, y = 1, z = 0})
|
||||||
|
local light = math.floor(math.max(minetest.env:get_node_light(pos) / 15, 0.2) * 256)
|
||||||
|
local shadow = 256 - light
|
||||||
|
|
||||||
|
local dark_file = hud.file .. "^[multiply:#000000ff^[opacity:" .. shadow
|
||||||
|
local light_file = hud.file .. "^[opacity:" .. light
|
||||||
|
file = "(" .. light_file .. ")^(" .. dark_file .. ")"
|
||||||
|
else
|
||||||
|
file = hud.file
|
||||||
|
end
|
||||||
|
|
||||||
local handle = player:hud_add({
|
local handle = player:hud_add({
|
||||||
name = weather,
|
name = weather,
|
||||||
hud_elem_type = "image",
|
hud_elem_type = "image",
|
||||||
@ -14,7 +30,7 @@ local function apply_hud(pname, weather, hud)
|
|||||||
alignment = {x = 1, y = 1},
|
alignment = {x = 1, y = 1},
|
||||||
scale = { x = -100, y = -100},
|
scale = { x = -100, y = -100},
|
||||||
z_index = hud.z_index,
|
z_index = hud.z_index,
|
||||||
text = hud.file,
|
text = file,
|
||||||
offset = {x = 0, y = 0}
|
offset = {x = 0, y = 0}
|
||||||
})
|
})
|
||||||
handles[pname][weather] = handle
|
handles[pname][weather] = handle
|
||||||
@ -39,7 +55,12 @@ end
|
|||||||
local function handle_effect(player_data, prev_data)
|
local function handle_effect(player_data, prev_data)
|
||||||
for playername, data in pairs(player_data) do
|
for playername, data in pairs(player_data) do
|
||||||
for weather, value in pairs(data) do
|
for weather, value in pairs(data) do
|
||||||
if prev_data[playername][weather] == nil then
|
if prev_data[playername][weather] == nil
|
||||||
|
or value.color_correction == true
|
||||||
|
or prev_data[playername][weather].color_correction == true
|
||||||
|
or value.file ~= prev_data[playername][weather].file
|
||||||
|
or value.z_index ~= prev_data[playername][weather].z_index
|
||||||
|
then
|
||||||
apply_hud(playername, weather, value)
|
apply_hud(playername, weather, value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -11,44 +11,58 @@ end
|
|||||||
|
|
||||||
local function spawn_particles(player, particles)
|
local function spawn_particles(player, particles)
|
||||||
local ppos = player:getpos()
|
local ppos = player:getpos()
|
||||||
local wind_x = climate_mod.state:get_float("wind_x")
|
local wind = climate_api.environment.get_wind()
|
||||||
local wind_z = climate_mod.state:get_float("wind_z")
|
|
||||||
local wind = vector.new(wind_x, 0, wind_z)
|
|
||||||
local wind_pos = vector.multiply(wind, -1)
|
|
||||||
local wind_speed = vector.length(wind)
|
|
||||||
|
|
||||||
local amount = particles.amount * climate_mod.settings.particle_count
|
local amount = particles.amount * climate_mod.settings.particle_count
|
||||||
local texture = get_particle_texture(particles)
|
local texture = get_particle_texture(particles)
|
||||||
|
|
||||||
local minp = vector.add(vector.add(ppos, particles.min_pos), wind_pos)
|
|
||||||
local maxp = vector.add(vector.add(ppos, particles.max_pos), wind_pos)
|
|
||||||
|
|
||||||
local vel = vector.new({
|
local vel = vector.new({
|
||||||
x = wind.x,
|
x = wind.x,
|
||||||
y = -particles.falling_speed,
|
y = -particles.falling_speed,
|
||||||
z = wind.z
|
z = wind.z
|
||||||
})
|
})
|
||||||
local acc = vector.new({x=0, y=0, z=0})
|
|
||||||
|
|
||||||
local exp = particles.exptime
|
if particles.acceleration == nil then
|
||||||
local vertical = math.abs(vector.normalize(vel).y) >= 0.6
|
particles.acceleration = vector.new({x=0, y=0, z=0})
|
||||||
|
end
|
||||||
|
|
||||||
|
local wind_pos = vector.multiply(
|
||||||
|
vector.normalize(vel),
|
||||||
|
-vector.length(wind)
|
||||||
|
)
|
||||||
|
wind_pos.y = 0
|
||||||
|
local minp = vector.add(vector.add(ppos, particles.min_pos), wind_pos)
|
||||||
|
local maxp = vector.add(vector.add(ppos, particles.max_pos), wind_pos)
|
||||||
|
|
||||||
|
if particles.time == nil then
|
||||||
|
particles.time = 0.5
|
||||||
|
end
|
||||||
|
|
||||||
|
if particles.vertical == nil then
|
||||||
|
particles.vertical = math.abs(vector.normalize(vel).y) >= 0.6
|
||||||
|
end
|
||||||
|
|
||||||
|
if particles.size ~= nil then
|
||||||
|
particles.min_size = particles.size
|
||||||
|
particles.max_size = particles.size
|
||||||
|
end
|
||||||
|
|
||||||
minetest.add_particlespawner({
|
minetest.add_particlespawner({
|
||||||
amount = amount,
|
amount = amount,
|
||||||
time = 0.5,
|
time = particles.time,
|
||||||
minpos = minp,
|
minpos = minp,
|
||||||
maxpos = maxp,
|
maxpos = maxp,
|
||||||
minvel = vel,
|
minvel = vel,
|
||||||
maxvel = vel,
|
maxvel = vel,
|
||||||
minacc = acc,
|
minacc = particles.acceleration,
|
||||||
maxacc = acc,
|
maxacc = particles.acceleration,
|
||||||
minexptime = exp,
|
minexptime = particles.exptime,
|
||||||
maxexptime = exp,
|
maxexptime = particles.exptime,
|
||||||
minsize = particles.size,
|
minsize = particles.min_size,
|
||||||
maxsize = particles.size,
|
maxsize = particles.max_size,
|
||||||
collisiondetection = true,
|
collisiondetection = true,
|
||||||
collision_removal = true,
|
collision_removal = true,
|
||||||
vertical = vertical,
|
vertical = particles.vertical,
|
||||||
texture = texture,
|
texture = texture,
|
||||||
player = player:get_player_name()
|
player = player:get_player_name()
|
||||||
})
|
})
|
||||||
|
@ -2,46 +2,30 @@ if not climate_mod.settings.skybox then return end
|
|||||||
|
|
||||||
local EFFECT_NAME = "climate_api:skybox"
|
local EFFECT_NAME = "climate_api:skybox"
|
||||||
|
|
||||||
local function set_skybox(player, sky)
|
local function handle_effect(player_data, prev_data)
|
||||||
if sky.sky_data ~= nil then
|
for playername, data in pairs(prev_data) do
|
||||||
player:set_sky(sky.sky_data)
|
for weather, _ in pairs(data) do
|
||||||
end
|
if player_data[playername] == nil or player_data[playername][weather] == nil then
|
||||||
if sky.cloud_data ~= nil then
|
climate_api.skybox.remove_layer(playername, weather)
|
||||||
player:set_clouds(sky.cloud_data)
|
end
|
||||||
end
|
|
||||||
if sky.moon_data ~= nil then
|
|
||||||
player:set_moon(sky.moon_data)
|
|
||||||
end
|
|
||||||
if sky.sun_data ~= nil then
|
|
||||||
player:set_sun(sky.sun_data)
|
|
||||||
end
|
|
||||||
if sky.stars_data ~= nil then
|
|
||||||
player:set_sun(sky.stars_data)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function remove_skybox(player)
|
|
||||||
player:set_sky({ type = "regular", clouds = true})
|
|
||||||
end
|
|
||||||
|
|
||||||
local function handle_effect(player_data)
|
|
||||||
for playername, data in pairs(player_data) do
|
|
||||||
local player = minetest.get_player_by_name(playername)
|
|
||||||
local sky = {}
|
|
||||||
for weather, value in pairs(data) do
|
|
||||||
climate_api.utility.merge_tables(sky, value)
|
|
||||||
end
|
end
|
||||||
set_skybox(player, sky)
|
end
|
||||||
|
for playername, data in pairs(player_data) do
|
||||||
|
for weather, value in pairs(data) do
|
||||||
|
climate_api.skybox.add_layer(playername, weather, value)
|
||||||
|
end
|
||||||
|
climate_api.skybox.update_skybox(playername)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function remove_effect(player_data)
|
local function remove_effect(player_data)
|
||||||
for playername, data in pairs(player_data) do
|
for playername, data in pairs(player_data) do
|
||||||
local player = minetest.get_player_by_name(playername)
|
for weather, _ in pairs(data) do
|
||||||
remove_skybox(player)
|
climate_api.skybox.remove_layer(playername, weather)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
climate_api.register_effect(EFFECT_NAME, handle_effect, "tick")
|
climate_api.register_effect(EFFECT_NAME, handle_effect, "tick")
|
||||||
climate_api.register_effect(EFFECT_NAME, remove_effect, "stop")
|
climate_api.register_effect(EFFECT_NAME, remove_effect, "stop")
|
||||||
--climate_api.set_effect_cycle("climate_api:skybox", climate_api.LONG_CYCLE)
|
climate_api.set_effect_cycle("climate_api:skybox", climate_api.MEDIUM_CYCLE)
|
@ -1,29 +1,23 @@
|
|||||||
if not climate_mod.settings.sound then return end
|
if not climate_mod.settings.sound then return end
|
||||||
|
|
||||||
local EFFECT_NAME = "climate_api:sound"
|
local EFFECT_NAME = "climate_api:sound"
|
||||||
|
local FADE_DURATION = climate_api.LONG_CYCLE
|
||||||
|
|
||||||
local handles = {}
|
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||||
local function start_sound(pname, weather, sound)
|
local soundloop = dofile(modpath .. "/lib/soundloop.lua")
|
||||||
if handles[pname] == nil then handles[pname] = {} end
|
|
||||||
if handles[pname][weather] ~= nil then return end
|
local function start_sound(pname, sound)
|
||||||
local handle = minetest.sound_play(sound, {
|
return soundloop.play(pname, sound, FADE_DURATION)
|
||||||
to_player = pname,
|
|
||||||
loop = true
|
|
||||||
})
|
|
||||||
handles[pname][weather] = handle
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function stop_sound(pname, weather, sound)
|
local function stop_sound(pname, sound)
|
||||||
if handles[pname] == nil or handles[pname][weather] == nil then return end
|
return soundloop.stop(pname, sound, FADE_DURATION)
|
||||||
local handle = handles[pname][weather]
|
|
||||||
minetest.sound_stop(handle)
|
|
||||||
handles[pname][weather] = nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function start_effect(player_data)
|
local function start_effect(player_data)
|
||||||
for playername, data in pairs(player_data) do
|
for playername, data in pairs(player_data) do
|
||||||
for weather, value in pairs(data) do
|
for weather, value in pairs(data) do
|
||||||
start_sound(playername, weather, value)
|
start_sound(playername, value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -32,7 +26,7 @@ local function handle_effect(player_data, prev_data)
|
|||||||
for playername, data in pairs(player_data) do
|
for playername, data in pairs(player_data) do
|
||||||
for weather, value in pairs(data) do
|
for weather, value in pairs(data) do
|
||||||
if prev_data[playername][weather] == nil then
|
if prev_data[playername][weather] == nil then
|
||||||
start_sound(playername, weather, value)
|
start_sound(playername, value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -40,17 +34,16 @@ local function handle_effect(player_data, prev_data)
|
|||||||
for playername, data in pairs(prev_data) do
|
for playername, data in pairs(prev_data) do
|
||||||
for weather, value in pairs(data) do
|
for weather, value in pairs(data) do
|
||||||
if player_data[playername][weather] == nil then
|
if player_data[playername][weather] == nil then
|
||||||
stop_sound(playername, weather, value)
|
stop_sound(playername, value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function stop_effect(prev_data)
|
local function stop_effect(prev_data)
|
||||||
minetest.log(dump2(prev_data, "stop_effect"))
|
|
||||||
for playername, data in pairs(prev_data) do
|
for playername, data in pairs(prev_data) do
|
||||||
for weather, value in pairs(data) do
|
for weather, value in pairs(data) do
|
||||||
stop_sound(playername, weather, value)
|
stop_sound(playername, value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -58,4 +51,4 @@ end
|
|||||||
climate_api.register_effect(EFFECT_NAME, start_effect, "start")
|
climate_api.register_effect(EFFECT_NAME, start_effect, "start")
|
||||||
climate_api.register_effect(EFFECT_NAME, handle_effect, "tick")
|
climate_api.register_effect(EFFECT_NAME, handle_effect, "tick")
|
||||||
climate_api.register_effect(EFFECT_NAME, stop_effect, "stop")
|
climate_api.register_effect(EFFECT_NAME, stop_effect, "stop")
|
||||||
climate_api.set_effect_cycle(EFFECT_NAME, climate_api.LONG_CYCLE)
|
climate_api.set_effect_cycle(EFFECT_NAME, climate_api.MEDIUM_CYCLE)
|
8
init.lua
@ -27,10 +27,13 @@ climate_mod.settings = {
|
|||||||
wind = get_setting_bool("wind", true),
|
wind = get_setting_bool("wind", true),
|
||||||
seasons = get_setting_bool("seasons", true),
|
seasons = get_setting_bool("seasons", true),
|
||||||
fahrenheit = get_setting_bool("fahrenheit", false),
|
fahrenheit = get_setting_bool("fahrenheit", false),
|
||||||
|
block_updates = get_setting_bool("block_updates", true),
|
||||||
heat = get_setting_number("heat_base", 0),
|
heat = get_setting_number("heat_base", 0),
|
||||||
humidity = get_setting_number("humidity_base", 0),
|
humidity = get_setting_number("humidity_base", 0),
|
||||||
time_spread = get_setting_number("time_spread", 1),
|
time_spread = get_setting_number("time_spread", 1),
|
||||||
particle_count = get_setting_number("particle_count", 1)
|
particle_count = get_setting_number("particle_count", 1),
|
||||||
|
tick_speed = get_setting_number("tick_speed", 1),
|
||||||
|
volume = get_setting_number("volume", 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
-- initiate empty registers
|
-- initiate empty registers
|
||||||
@ -41,11 +44,14 @@ climate_mod.influences = {}
|
|||||||
climate_mod.current_weather = {}
|
climate_mod.current_weather = {}
|
||||||
climate_mod.current_effects = {}
|
climate_mod.current_effects = {}
|
||||||
climate_mod.forced_weather = {}
|
climate_mod.forced_weather = {}
|
||||||
|
climate_mod.forced_wind = nil
|
||||||
|
|
||||||
-- import core API
|
-- import core API
|
||||||
climate_mod.state = dofile(modpath .. "/lib/datastorage.lua")
|
climate_mod.state = dofile(modpath .. "/lib/datastorage.lua")
|
||||||
climate_api = dofile(modpath .. "/lib/api.lua")
|
climate_api = dofile(modpath .. "/lib/api.lua")
|
||||||
climate_api.utility = dofile(modpath .. "/lib/api_utility.lua")
|
climate_api.utility = dofile(modpath .. "/lib/api_utility.lua")
|
||||||
|
climate_api.skybox = dofile(modpath .. "/lib/skybox_merger.lua")
|
||||||
|
dofile(modpath .. "/lib/influences.lua")
|
||||||
climate_api.environment = dofile(modpath .. "/lib/environment.lua")
|
climate_api.environment = dofile(modpath .. "/lib/environment.lua")
|
||||||
--climate_api = dofile(modpath .. "/lib/influences.lua")
|
--climate_api = dofile(modpath .. "/lib/influences.lua")
|
||||||
climate_mod.world = dofile(modpath .. "/lib/world.lua")
|
climate_mod.world = dofile(modpath .. "/lib/world.lua")
|
||||||
|
22
lib/api.lua
@ -17,7 +17,7 @@ end
|
|||||||
function api.register_effect(name, handler, htype)
|
function api.register_effect(name, handler, htype)
|
||||||
-- check for valid handler types
|
-- check for valid handler types
|
||||||
if htype ~= "start" and htype ~= "tick" and htype ~= "stop" then
|
if htype ~= "start" and htype ~= "tick" and htype ~= "stop" then
|
||||||
minetest.log("warning", "[Climate API] Invalid effect handler type: " .. htype)
|
minetest.log("warning", "[Climate API] Effect " .. dump(name) .. " uses invalid callback type: " .. dump(htype))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
-- create effect handler registry if not existent yet
|
-- create effect handler registry if not existent yet
|
||||||
@ -33,11 +33,13 @@ function api.set_effect_cycle(name, cycle)
|
|||||||
climate_mod.cycles[name].timespan = cycle
|
climate_mod.cycles[name].timespan = cycle
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[function api.register_influence(name, func)
|
function api.register_influence(name, func)
|
||||||
climate_mod.influences[name] = func
|
climate_mod.influences[name] = func
|
||||||
end]]
|
end
|
||||||
|
|
||||||
function api.register_abm(config)
|
function api.register_abm(config)
|
||||||
|
if not climate_mod.settings.block_updates then return end
|
||||||
|
|
||||||
local conditions = config.conditions
|
local conditions = config.conditions
|
||||||
local action = config.action
|
local action = config.action
|
||||||
local pos_override = config.pos_override
|
local pos_override = config.pos_override
|
||||||
@ -52,19 +54,9 @@ function api.register_abm(config)
|
|||||||
return action(pos, node, env)
|
return action(pos, node, env)
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.log(dump2(env, "env"))
|
|
||||||
minetest.log(dump2(conditions, "conditions"))
|
|
||||||
|
|
||||||
for condition, goal in pairs(conditions) do
|
for condition, goal in pairs(conditions) do
|
||||||
local value = env[condition:sub(5)]
|
local is_applicable = climate_mod.trigger.test_condition(condition, env, goal)
|
||||||
if condition:sub(1, 4) == "min_" then
|
if not is_applicable then return end
|
||||||
if type(value) == "nil" or goal > value then return end
|
|
||||||
elseif condition:sub(1, 4) == "max_" then
|
|
||||||
if type(value) == "nil" or goal <= value then return end
|
|
||||||
else
|
|
||||||
value = env[condition]
|
|
||||||
if type(value) == "nil" or goal ~= value then return end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
return action(pos, node, env)
|
return action(pos, node, env)
|
||||||
end
|
end
|
||||||
|
@ -77,6 +77,32 @@ minetest.register_chatcommand("set_humidity", {
|
|||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_chatcommand("set_wind", {
|
||||||
|
params = "<wind>",
|
||||||
|
description = "Override the weather algorithm's windspeed",
|
||||||
|
privs = { weather = true },
|
||||||
|
func = function(playername, param)
|
||||||
|
if param == nil or param == "" then
|
||||||
|
minetest.chat_send_player(playername, "Provide a number to modify the base humidity")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local arguments = {}
|
||||||
|
for w in param:gmatch("%S+") do table.insert(arguments, w) end
|
||||||
|
local wind_x = arguments[1]
|
||||||
|
local wind_z = arguments[2]
|
||||||
|
if wind_x == "auto" then
|
||||||
|
climate_mod.forced_wind = nil
|
||||||
|
else
|
||||||
|
climate_mod.forced_wind = vector.new({
|
||||||
|
x = tonumber(wind_x),
|
||||||
|
y = 0,
|
||||||
|
z = tonumber(wind_z)
|
||||||
|
})
|
||||||
|
end
|
||||||
|
minetest.chat_send_player(playername, "Wind changed")
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
minetest.register_chatcommand("weather_settings", {
|
minetest.register_chatcommand("weather_settings", {
|
||||||
description = "Print the active Climate API configuration",
|
description = "Print the active Climate API configuration",
|
||||||
func = function(playername)
|
func = function(playername)
|
||||||
@ -130,3 +156,15 @@ minetest.register_chatcommand("weather_status", {
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_chatcommand("weather_influences", {
|
||||||
|
description = "Prints which weather influences cause your current weather",
|
||||||
|
func = function(playername)
|
||||||
|
minetest.chat_send_player(playername, "Current influences rules:\n================")
|
||||||
|
local player = minetest.get_player_by_name(playername)
|
||||||
|
local influences = climate_mod.trigger.get_player_environment(player)
|
||||||
|
for influence, value in pairs(influences) do
|
||||||
|
minetest.chat_send_player(playername, dump2(value, influence))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
@ -5,13 +5,6 @@ local function get_heat_time()
|
|||||||
return climate_api.utility.normalized_cycle(time) * 0.6 + 0.7
|
return climate_api.utility.normalized_cycle(time) * 0.6 + 0.7
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_heat_calendar()
|
|
||||||
-- European heat center in August instead of June
|
|
||||||
local day = minetest.get_day_count()
|
|
||||||
local progression = ((day + 61) % 365) / 365
|
|
||||||
return climate_api.utility.normalized_cycle(progression) * 0.6 + 0.7
|
|
||||||
end
|
|
||||||
|
|
||||||
local function get_heat_height(y)
|
local function get_heat_height(y)
|
||||||
return climate_api.utility.rangelim((-y + 10) / 15, -10, 10)
|
return climate_api.utility.rangelim((-y + 10) / 15, -10, 10)
|
||||||
end
|
end
|
||||||
@ -21,9 +14,8 @@ function environment.get_heat(pos)
|
|||||||
local biome = minetest.get_heat(pos)
|
local biome = minetest.get_heat(pos)
|
||||||
local height = get_heat_height(pos.y)
|
local height = get_heat_height(pos.y)
|
||||||
local time = get_heat_time()
|
local time = get_heat_time()
|
||||||
local date = get_heat_calendar()
|
|
||||||
local random = climate_mod.state:get_float("heat_random");
|
local random = climate_mod.state:get_float("heat_random");
|
||||||
return (base + biome + height) * time * date * random
|
return (base + biome + height) * time * random
|
||||||
end
|
end
|
||||||
|
|
||||||
function environment.get_humidity(pos)
|
function environment.get_humidity(pos)
|
||||||
@ -31,16 +23,18 @@ function environment.get_humidity(pos)
|
|||||||
local biome = minetest.get_humidity(pos)
|
local biome = minetest.get_humidity(pos)
|
||||||
local random = climate_mod.state:get_float("humidity_random");
|
local random = climate_mod.state:get_float("humidity_random");
|
||||||
local random_base = climate_mod.state:get_float("humidity_base");
|
local random_base = climate_mod.state:get_float("humidity_base");
|
||||||
--[[for _, player in ipairs(minetest.get_connected_players()) do
|
|
||||||
local pname = player:get_player_name()
|
|
||||||
minetest.chat_send_player(pname, dump2(biome, "biome"))
|
|
||||||
minetest.chat_send_player(pname, dump2(random_base, "random_base"))
|
|
||||||
minetest.chat_send_player(pname, dump2(random, "random"))
|
|
||||||
minetest.chat_send_player(pname, dump2((base + biome * 0.7 + random_base * 0.3) * random, "total"))
|
|
||||||
end]]
|
|
||||||
return (base + biome * 0.7 + random_base * 0.3) * random
|
return (base + biome * 0.7 + random_base * 0.3) * random
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function environment.get_wind()
|
||||||
|
if climate_mod.forced_wind ~= nil then
|
||||||
|
return climate_mod.forced_wind
|
||||||
|
end
|
||||||
|
local wind_x = climate_mod.state:get_float("wind_x")
|
||||||
|
local wind_z = climate_mod.state:get_float("wind_z")
|
||||||
|
return vector.new({ x = wind_x, y = 0, z = wind_z })
|
||||||
|
end
|
||||||
|
|
||||||
function environment.get_weather_presets(player)
|
function environment.get_weather_presets(player)
|
||||||
local pname = player:get_player_name()
|
local pname = player:get_player_name()
|
||||||
local weathers = climate_mod.current_weather[pname]
|
local weathers = climate_mod.current_weather[pname]
|
||||||
|
@ -1,30 +1,54 @@
|
|||||||
climate_api.register_influence("heat", function(player)
|
climate_api.register_influence("heat", function(pos)
|
||||||
return climate_mod.get_heat(player:get_pos())
|
return climate_api.environment.get_heat(pos)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
climate_api.register_influence("humidity", function(player)
|
climate_api.register_influence("base_heat", function(pos)
|
||||||
return climate_mod.get_humidity(player:get_pos())
|
return minetest.get_heat(pos)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
climate_api.register_influence("windspeed", function(player)
|
climate_api.register_influence("humidity", function(pos)
|
||||||
local wind_x = climate_mod.state:get_float("wind_x")
|
return climate_api.environment.get_humidity(pos)
|
||||||
local wind_z = climate_mod.state:get_float("wind_z")
|
|
||||||
return vector.length({x = wind_x, y = 0, z = wind_z})
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
climate_api.register_influence("wind_x", function(player)
|
climate_api.register_influence("base_humidity", function(pos)
|
||||||
return climate_mod.state:get_float("wind_x")
|
return minetest.get_humidity(pos)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
climate_api.register_influence("wind_z", function(player)
|
climate_api.register_influence("biome", function(pos)
|
||||||
return climate_mod.state:get_float("wind_z")
|
local data = minetest.get_biome_data(pos)
|
||||||
|
local biome = minetest.get_biome_name(data.biome)
|
||||||
|
return biome
|
||||||
end)
|
end)
|
||||||
|
|
||||||
climate_api.register_influence("height", function(player)
|
climate_api.register_influence("windspeed", function(_)
|
||||||
local ppos = player:get_pos()
|
local wind = climate_api.environment.get_wind()
|
||||||
return ppos.y
|
return vector.length(wind)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
climate_api.register_influence("light", function(player)
|
climate_api.register_influence("wind_yaw", function(_)
|
||||||
return minetest.env:get_node_light(player:get_pos(), 0.5)
|
local wind = climate_api.environment.get_wind()
|
||||||
|
if vector.length(wind) == 0 then return 0 end
|
||||||
|
return minetest.dir_to_yaw(wind)
|
||||||
|
end)
|
||||||
|
|
||||||
|
climate_api.register_influence("height", function(pos)
|
||||||
|
return pos.y
|
||||||
|
end)
|
||||||
|
|
||||||
|
climate_api.register_influence("light", function(pos)
|
||||||
|
pos = vector.add(pos, {x = 0, y = 1, z = 0})
|
||||||
|
return minetest.env:get_node_light(pos)
|
||||||
|
end)
|
||||||
|
|
||||||
|
climate_api.register_influence("daylight", function(pos)
|
||||||
|
pos = vector.add(pos, {x = 0, y = 1, z = 0})
|
||||||
|
return minetest.env:get_node_light(pos, 0.5)
|
||||||
|
end)
|
||||||
|
|
||||||
|
climate_api.register_influence("time", function(_)
|
||||||
|
return minetest.get_timeofday()
|
||||||
|
end)
|
||||||
|
|
||||||
|
climate_api.register_influence("day_count", function(_)
|
||||||
|
return minetest.get_day_count()
|
||||||
end)
|
end)
|
@ -1,5 +1,5 @@
|
|||||||
local GSCYCLE = 0.03
|
local GSCYCLE = 0.03 * climate_mod.settings.tick_speed
|
||||||
local WORLD_CYCLE = 2
|
local WORLD_CYCLE = 2 * climate_mod.settings.tick_speed
|
||||||
|
|
||||||
local gs_timer = 0
|
local gs_timer = 0
|
||||||
local world_timer = 0
|
local world_timer = 0
|
||||||
@ -20,7 +20,8 @@ minetest.register_globalstep(function(dtime)
|
|||||||
local current_effects = climate_mod.trigger.get_active_effects()
|
local current_effects = climate_mod.trigger.get_active_effects()
|
||||||
|
|
||||||
for name, effect in pairs(climate_mod.effects) do
|
for name, effect in pairs(climate_mod.effects) do
|
||||||
if climate_mod.cycles[name].timespan < climate_mod.cycles[name].timer + dtime then
|
local cycle = climate_mod.cycles[name].timespan * climate_mod.settings.tick_speed
|
||||||
|
if cycle < climate_mod.cycles[name].timer + dtime then
|
||||||
climate_mod.cycles[name].timer = 0
|
climate_mod.cycles[name].timer = 0
|
||||||
climate_mod.current_effects[name] = current_effects[name]
|
climate_mod.current_effects[name] = current_effects[name]
|
||||||
climate_mod.trigger.call_handlers(name, current_effects[name], previous_effects[name])
|
climate_mod.trigger.call_handlers(name, current_effects[name], previous_effects[name])
|
||||||
|
109
lib/skybox_merger.lua
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
local default_sky = {
|
||||||
|
sky_data = {
|
||||||
|
base_color = nil,
|
||||||
|
type = "regular",
|
||||||
|
textures = nil,
|
||||||
|
clouds = true,
|
||||||
|
sky_color = {
|
||||||
|
day_sky = "#8cbafa",
|
||||||
|
day_horizon = "#9bc1f0",
|
||||||
|
dawn_sky = "#b4bafa",
|
||||||
|
dawn_horizon = "#bac1f0",
|
||||||
|
night_sky = "#006aff",
|
||||||
|
night_horizon = "#4090ff",
|
||||||
|
indoors = "#646464",
|
||||||
|
fog_tint_type = "default"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cloud_data = {
|
||||||
|
density = 0.4,
|
||||||
|
color = "#fff0f0e5",
|
||||||
|
ambient = "#000000",
|
||||||
|
height = 120,
|
||||||
|
thickness = 16,
|
||||||
|
speed = {x=0, z=-2}
|
||||||
|
},
|
||||||
|
sun_data = {
|
||||||
|
visible = true,
|
||||||
|
texture = "sun.png",
|
||||||
|
tonemap = "sun_tonemap.png",
|
||||||
|
sunrise = "sunrisebg.png",
|
||||||
|
sunrise_visible = true,
|
||||||
|
scale = 1
|
||||||
|
},
|
||||||
|
moon_data = {
|
||||||
|
visible = true,
|
||||||
|
texture = "moon.png",
|
||||||
|
tonemap = "moon_tonemap.png",
|
||||||
|
scale = 1
|
||||||
|
},
|
||||||
|
star_data = {
|
||||||
|
visible = true,
|
||||||
|
count = 1000,
|
||||||
|
star_color = "#ebebff69",
|
||||||
|
scale = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local skybox = {}
|
||||||
|
local layers = {}
|
||||||
|
|
||||||
|
-- from https://stackoverflow.com/a/29133654
|
||||||
|
-- merges two tables together
|
||||||
|
-- if in conflict, b will override values of a
|
||||||
|
local function merge_tables(a, b)
|
||||||
|
if type(a) == "table" and type(b) == "table" then
|
||||||
|
for k,v in pairs(b) do
|
||||||
|
if type(v)=="table" and type(a[k] or false)=="table" then
|
||||||
|
merge_tables(a[k],v)
|
||||||
|
else a[k]=v end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return a
|
||||||
|
end
|
||||||
|
|
||||||
|
local function set_skybox(playername, sky)
|
||||||
|
local player = minetest.get_player_by_name(playername)
|
||||||
|
if not player.get_stars then return end
|
||||||
|
player:set_sky(sky.sky_data)
|
||||||
|
player:set_clouds(sky.cloud_data)
|
||||||
|
player:set_moon(sky.moon_data)
|
||||||
|
player:set_sun(sky.sun_data)
|
||||||
|
player:set_stars(sky.star_data)
|
||||||
|
end
|
||||||
|
|
||||||
|
function skybox.update_skybox(playername)
|
||||||
|
local p_layers = layers[playername]
|
||||||
|
local sky = table.copy(default_sky)
|
||||||
|
if p_layers == nil then p_layers = {} end
|
||||||
|
local numbered_layers = {}
|
||||||
|
for layer, values in pairs(p_layers) do
|
||||||
|
table.insert(numbered_layers, values)
|
||||||
|
end
|
||||||
|
table.sort(numbered_layers, function(left, right)
|
||||||
|
if left.priority == nil then left.priority = 1 end
|
||||||
|
if right.priority == nil then right.priority = 1 end
|
||||||
|
return left.priority < right.priority
|
||||||
|
end)
|
||||||
|
for i=1,#numbered_layers do
|
||||||
|
sky = merge_tables(sky, numbered_layers[i])
|
||||||
|
end
|
||||||
|
set_skybox(playername, sky)
|
||||||
|
end
|
||||||
|
|
||||||
|
function skybox.add_layer(playername, name, sky)
|
||||||
|
if layers[playername] == nil then layers[playername] = {} end
|
||||||
|
layers[playername][name] = sky
|
||||||
|
end
|
||||||
|
|
||||||
|
function skybox.remove_layer(playername, name)
|
||||||
|
if layers[playername] == nil or layers[playername][name] == nil then return end
|
||||||
|
layers[playername][name] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_on_leaveplayer(function(player)
|
||||||
|
local playername = player:get_player_name()
|
||||||
|
layers[playername] = nil
|
||||||
|
end)
|
||||||
|
|
||||||
|
return skybox
|
57
lib/soundloop.lua
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
local soundloop = {}
|
||||||
|
local sounds = {}
|
||||||
|
|
||||||
|
local function parse_sound(sound)
|
||||||
|
if type(sound) == "string" then
|
||||||
|
return { name = sound, gain = 1, pitch = 1 }
|
||||||
|
end
|
||||||
|
if sound.gain == nil then sound.gain = 1 end
|
||||||
|
if sound.pitch == nil then sound.pitch = 1 end
|
||||||
|
return sound
|
||||||
|
end
|
||||||
|
|
||||||
|
soundloop.play = function(player, sound, fade)
|
||||||
|
sound = parse_sound(sound)
|
||||||
|
if fade == nil then fade = 1 end
|
||||||
|
local step
|
||||||
|
local handle
|
||||||
|
local start_gain
|
||||||
|
if sounds[player] == nil then sounds[player] = {} end
|
||||||
|
if sounds[player][sound.name] == nil then
|
||||||
|
step = sound.gain / fade
|
||||||
|
start_gain = 0
|
||||||
|
elseif sounds[player][sound.name] ~= sound.gain then
|
||||||
|
minetest.sound_stop(sounds[player][sound.name].handle)
|
||||||
|
start_gain = sounds[player][sound.name].gain
|
||||||
|
local change = sound.gain - start_gain
|
||||||
|
step = change / fade
|
||||||
|
else
|
||||||
|
return
|
||||||
|
end
|
||||||
|
handle = minetest.sound_play(sound.name, {
|
||||||
|
to_player = player,
|
||||||
|
loop = true,
|
||||||
|
gain = 0
|
||||||
|
})
|
||||||
|
sounds[player][sound.name] = {
|
||||||
|
gain = sound.gain,
|
||||||
|
handle = handle
|
||||||
|
}
|
||||||
|
minetest.sound_fade(handle, step, sound.gain)
|
||||||
|
return handle
|
||||||
|
end
|
||||||
|
|
||||||
|
soundloop.stop = function(player, sound, fade)
|
||||||
|
sound = parse_sound(sound)
|
||||||
|
if sounds[player] == nil or sounds[player][sound.name] == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if fade == nil then fade = 1 end
|
||||||
|
local handle = sounds[player][sound.name].handle
|
||||||
|
local step = -sounds[player][sound.name].gain / fade
|
||||||
|
minetest.sound_fade(handle, step, 0)
|
||||||
|
sounds[player][sound.name].gain = 0
|
||||||
|
minetest.after(fade, minetest.sound_stop, handle)
|
||||||
|
end
|
||||||
|
|
||||||
|
return soundloop
|
@ -4,7 +4,7 @@ function trigger.get_position_environment(pos)
|
|||||||
local wind_x = climate_mod.state:get_float("wind_x")
|
local wind_x = climate_mod.state:get_float("wind_x")
|
||||||
local wind_z = climate_mod.state:get_float("wind_z")
|
local wind_z = climate_mod.state:get_float("wind_z")
|
||||||
|
|
||||||
local env = {}
|
--[[local env = {}
|
||||||
env.pos = pos
|
env.pos = pos
|
||||||
env.height = pos.y
|
env.height = pos.y
|
||||||
env.wind = vector.new(wind_x, 0, wind_z)
|
env.wind = vector.new(wind_x, 0, wind_z)
|
||||||
@ -13,7 +13,11 @@ function trigger.get_position_environment(pos)
|
|||||||
env.humidity = climate_api.environment.get_humidity(pos)
|
env.humidity = climate_api.environment.get_humidity(pos)
|
||||||
env.time = minetest.get_timeofday()
|
env.time = minetest.get_timeofday()
|
||||||
env.date = minetest.get_day_count()
|
env.date = minetest.get_day_count()
|
||||||
env.light = minetest.get_node_light(vector.add(pos, vector.new({x=0,y=1,z=0})), 0.5)
|
env.light = minetest.get_node_light(vector.add(pos, vector.new({x=0,y=1,z=0})), 0.5)]]
|
||||||
|
local env = {}
|
||||||
|
for influence, func in pairs(climate_mod.influences) do
|
||||||
|
env[influence] = func(pos)
|
||||||
|
end
|
||||||
return env
|
return env
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -24,15 +28,21 @@ function trigger.get_player_environment(player)
|
|||||||
return env
|
return env
|
||||||
end
|
end
|
||||||
|
|
||||||
local function test_condition(condition, env, goal)
|
function trigger.test_condition(condition, env, goal)
|
||||||
local value = env[condition:sub(5)]
|
local value = env[condition:sub(5)]
|
||||||
if condition:sub(1, 4) == "min_" then
|
if condition:sub(1, 4) == "min_" then
|
||||||
return type(value) ~= "nil" and goal <= value
|
return type(value) ~= "nil" and goal <= value
|
||||||
elseif condition:sub(1, 4) == "max_" then
|
elseif condition:sub(1, 4) == "max_" then
|
||||||
return type(value) ~= "nil" and goal > value
|
return type(value) ~= "nil" and goal > value
|
||||||
else
|
elseif condition:sub(1, 4) == "has_" then
|
||||||
Minetest.log("warning", "[Climate API] Invalid effect condition")
|
if type(value) == "nil" then return false end
|
||||||
|
for _, g in ipairs(goal) do
|
||||||
|
if value == g then return true end
|
||||||
|
end
|
||||||
return false
|
return false
|
||||||
|
else
|
||||||
|
value = env[condition]
|
||||||
|
return type(value) ~= "nil" and goal == value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -45,7 +55,7 @@ local function is_weather_active(player, weather, env)
|
|||||||
return config.conditions(env)
|
return config.conditions(env)
|
||||||
end
|
end
|
||||||
for condition, goal in pairs(config.conditions) do
|
for condition, goal in pairs(config.conditions) do
|
||||||
if not test_condition(condition, env, goal) then
|
if not trigger.test_condition(condition, env, goal) then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -145,7 +155,6 @@ function trigger.call_handlers(name, effect, prev_effect)
|
|||||||
|
|
||||||
-- remaining table lists ending effects
|
-- remaining table lists ending effects
|
||||||
if has_stops then
|
if has_stops then
|
||||||
minetest.log(dump2(name, "AAAAAAAAAAA"))
|
|
||||||
for _, handler in ipairs(climate_mod.effects[name]["stop"]) do
|
for _, handler in ipairs(climate_mod.effects[name]["stop"]) do
|
||||||
handler(stops)
|
handler(stops)
|
||||||
end
|
end
|
||||||
|
@ -2,11 +2,11 @@ local world = {}
|
|||||||
|
|
||||||
local WIND_SPREAD = 600
|
local WIND_SPREAD = 600
|
||||||
local WIND_SCALE = 2
|
local WIND_SCALE = 2
|
||||||
local HEAT_SPREAD = 200
|
local HEAT_SPREAD = 400
|
||||||
local HEAT_SCALE = 0.3
|
local HEAT_SCALE = 0.3
|
||||||
local HUMIDITY_SPREAD = 60
|
local HUMIDITY_SPREAD = 150
|
||||||
local HUMIDITY_SCALE = 0.5
|
local HUMIDITY_SCALE = 0.5
|
||||||
local HUMIDITY_BASE_SPREAD = 600
|
local HUMIDITY_BASE_SPREAD = 800
|
||||||
local HUMIDITY_BASE_SCALE = 40
|
local HUMIDITY_BASE_SCALE = 40
|
||||||
|
|
||||||
local nobj_wind_x
|
local nobj_wind_x
|
||||||
|
2
mod.conf
@ -1,7 +1,7 @@
|
|||||||
name = climate_api
|
name = climate_api
|
||||||
title = Climate API
|
title = Climate API
|
||||||
author = TestificateMods
|
author = TestificateMods
|
||||||
release = 1
|
release = 2
|
||||||
optional_depends = skylayer, player_monoids, playerphysics
|
optional_depends = skylayer, player_monoids, playerphysics
|
||||||
description = """
|
description = """
|
||||||
A powerful engine for weather presets and visual effects.
|
A powerful engine for weather presets and visual effects.
|
||||||
|
BIN
screenshot.2.png
Before Width: | Height: | Size: 2.0 MiB |
BIN
screenshot.3.png
Before Width: | Height: | Size: 2.0 MiB |
BIN
screenshot.png
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.6 MiB |
@ -1,11 +1,62 @@
|
|||||||
|
[Features]
|
||||||
|
|
||||||
|
# If set to true, weather effects (like rain) are allowed to render particles.
|
||||||
|
# Deactivating this feature will prevent some presets from being visible.
|
||||||
|
# For performance considerations it is recommended to decrease the amount of particles instead.
|
||||||
climate_api_particles (Show particle effects) bool true
|
climate_api_particles (Show particle effects) bool true
|
||||||
climate_api_skybox (Allow weather effects to modify the skybox) bool true
|
|
||||||
climate_api_sound (Allow weather presets to play ambient sounds) bool true
|
# If set to true, weather effects are allowed to modify a player's sky.
|
||||||
climate_api_hud_overlay (Allow weather presets to display a HUD overlay) bool true
|
# This includes skybox, sun, moon, and clouds (also used for fog effects).
|
||||||
climate_api_wind (Allow wind to angle rainfall) bool true
|
# Running this mod on Minetest 5.1.2 or earlier versions will automatically disable this feature.
|
||||||
climate_api_seasons (Change global temperature based on an annual cycle) bool true
|
climate_api_skybox (Override the skybox) bool true
|
||||||
|
|
||||||
|
# If set to true, weather effects are allowed to play sound loops.
|
||||||
|
# You can also adjust sound levels instead of deactivating this feature completely.
|
||||||
|
# Setting this value to false will be slightly more performant than setting the volume to zero.
|
||||||
|
climate_api_sound (Play ambient sound loops) bool true
|
||||||
|
|
||||||
|
# If set to true, weather effects are allowed to render an image on top of the gameplay.
|
||||||
|
# This is usually an optional effect used to increase immersion (like a frozen-over camera in a snow storm).
|
||||||
|
climate_api_hud_overlay (Display HUD overlays) bool true
|
||||||
|
|
||||||
|
# If set to true, weather packs are allowed to register node update handlers.
|
||||||
|
# These can be used to dynamically place snow layers, melt ice, or hydrate soil.
|
||||||
|
climate_api_block_updates (Dynamically modify nodes) bool true
|
||||||
|
|
||||||
|
|
||||||
|
[Environment]
|
||||||
|
|
||||||
|
# This value will be added to all biome's base temperatures before applying random modifiers.
|
||||||
|
# Every unit here will increase the global base heat by one degree Fahrenheit.
|
||||||
|
# Negative values will cool down global base heat respectively.
|
||||||
climate_api_heat_base (Global base temperature) float 0
|
climate_api_heat_base (Global base temperature) float 0
|
||||||
|
|
||||||
|
# This value will be added to all biome's base humidity before applying random modifiers.
|
||||||
|
# Every unit here will increase the global base humidity by one percent.
|
||||||
|
# Negative values will dry up global base humidity respectively.
|
||||||
climate_api_humidity_base (Global base humidity) float 0
|
climate_api_humidity_base (Global base humidity) float 0
|
||||||
climate_api_time_spread (Regulates how quickly the weather changes) float 1 0.1 10
|
|
||||||
|
# This value regulates how quickly environment factors like heat, humidity and wind are changing.
|
||||||
|
# A value of 2 will double the speed at which weather presets change.
|
||||||
|
# A value of 0.5 will half the speed respectively.
|
||||||
|
climate_api_time_spread (Time rate of weather changes) float 1 0.1 10
|
||||||
|
|
||||||
|
# This value regulates how often weather presets are recalculated.
|
||||||
|
# Higher values will result in smoother transitions between effects as well as faster response times to traveling players.
|
||||||
|
# Lower values will significantly increase overall performance at the cost of rougher looking effects.
|
||||||
|
climate_api_tick_speed (Update speed of weather effects) float 1 0.1 10
|
||||||
|
|
||||||
|
|
||||||
|
[Preferences]
|
||||||
|
|
||||||
|
# This value regulated how many particles will be spawned.
|
||||||
|
# A value of 1 will use the recommended amount of particles.
|
||||||
|
# Lower values can possible increase performance.
|
||||||
climate_api_particle_count (Multiplicator for used particles) float 1 0.1 2
|
climate_api_particle_count (Multiplicator for used particles) float 1 0.1 2
|
||||||
climate_api_fahrenheit (Show degrees in Fahrenheit instead of Celsius) bool false
|
|
||||||
|
# If set to true, temperature information in /weather command will be displayed in Fahrenheit.
|
||||||
|
climate_api_fahrenheit (Show degrees in Fahrenheit instead of Celsius) bool false
|
||||||
|
|
||||||
|
# This value regulates overall sound volume.
|
||||||
|
# A value of 2 will double the volume whereas a value of 0.5 will reduce the volume by half.
|
||||||
|
climate_api_volume (Volume of sound effects) float 1 0 10
|
||||||
|
Before Width: | Height: | Size: 2.2 MiB |
BIN
textures/moon.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
textures/sun.png
Normal file
After Width: | Height: | Size: 1.2 KiB |