Implement dynamic cloud sizes, adjust cycle lengths

This commit is contained in:
Till Affeldt 2020-04-13 16:53:32 +02:00
parent 47530bb07e
commit fdc457bd09
9 changed files with 86 additions and 24 deletions

12
TODO.md
View File

@ -1,12 +1,8 @@
# TODO # TODO
## Required for MVP ## Required for MVP
- Fix obvious bugs that prevent weathers from being selected
- Test if day progression works
- Test non-random heat and humidity values - Test non-random heat and humidity values
- Fix noise function - Re-implement sounds into new engine
- Implement sounds
- Test if sky changes are working
- Implement start/end events - Implement start/end events
- Make sure all weather presets are working - Make sure all weather presets are working
- Implement chat commands - Implement chat commands
@ -20,13 +16,17 @@
- Add license information to source files - Add license information to source files
- Write helpful README - Write helpful README
- Find good values for weather conditions - Find good values for weather conditions
- Make switches between effects more smooth - Set effects on player join
## Nice to have ## Nice to have
- Write documentation on how to add weathers and effects - Write documentation on how to add weathers and effects
- Register *Moon Phases* as a weather preset using the *skybox* effect - Register *Moon Phases* as a weather preset using the *skybox* effect
- Assign meta data (like "downfall", "wind", etc.) to weather presets - Assign meta data (like "downfall", "wind", etc.) to weather presets
- Fog effects - Fog effects
- 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
- Ability to register environment conditions dynamically (like the heat)
## Future Plans & Ideas ## Future Plans & Ideas
- Complete season system - Complete season system

54
ca_effects/clouds.lua Normal file
View File

@ -0,0 +1,54 @@
if not climate_mod.settings.skybox then return end
if not minetest.get_modpath("skylayer") then return end
local SKYBOX_NAME = "climate_api:clouds"
local function set_clouds(player, clouds)
sky = { name = SKYBOX_NAME, cloud_data = clouds }
skylayer.add_layer(player:get_player_name(), sky)
end
local function remove_cloud_layer(player)
skylayer.remove_layer(player:get_player_name(), SKYBOX_NAME)
end
local function accumulate(current, incoming, fn)
if type(incoming) ~= "nil" and type(current) == "nil" then
return incoming
elseif type(incoming) ~= "nil" then
return fn(current, incoming)
end
return current
end
local function handle_effect(player_data)
for playername, data in pairs(player_data) do
local player = minetest.get_player_by_name(playername)
local data = player.get_meta()
local current_size = data.get_float("climate_api:cloud_size")
local current_speed_x = data.get_float("climate_api:cloud_speed_x")
local current_speed_z = data.get_float("climate_api:cloud_speed_z")
local clouds = {}
for weather, value in pairs(data) do
clouds.size = accumulate(clouds.size, data.size, function(a, b) return a * b end)
clouds.speed = accumulate(clouds.speed, data.speed, vector.multiply)
if type(data.color) ~= "nil" then
clouds.color = data.color
end
end
set_clouds(player, clouds)
end
end
local function remove_effect(player_data)
for playername, data in ipairs(player_data) do
local player = minetest.get_player_by_name(playername)
remove_cloud_layer(player)
end
end
climate_api.register_effect("climate_api:clouds", handle_effect, "tick")
climate_api.register_effect("climate_api:clouds", remove_effect, "end")
climate_api.set_effect_cycle("climate_api:clouds", climate_api.LONG_CYCLE)

View File

@ -11,4 +11,4 @@ local function update_effect(player_data)
end end
climate_api.register_effect("climate_api:sound", update_effect, "change") climate_api.register_effect("climate_api:sound", update_effect, "change")
climate_api.set_effect_cycle("climate_api:skybox", climate_api.LONG_CYCLE) climate_api.set_effect_cycle("climate_api:skybox", climate_api.MEDIUM_CYCLE)

View File

@ -42,3 +42,4 @@ dofile(modpath.."/lib/main.lua")
-- import predefined environment effects -- import predefined environment effects
dofile(modpath .. "/ca_effects/particles.lua") dofile(modpath .. "/ca_effects/particles.lua")
dofile(modpath .. "/ca_effects/skybox.lua") dofile(modpath .. "/ca_effects/skybox.lua")
dofile(modpath .. "/ca_effects/clouds.lua")

View File

@ -1,8 +1,9 @@
local api = {} local api = {}
api.SHORT_CYCLE = 0.03 -- for particles and fast animations api.SHORT_CYCLE = 0.03 -- for particles and fast animations
api.DEFAULT_CYCLE = 0.1 -- for most effect types api.DEFAULT_CYCLE = 0.1 -- for most effect types
api.LONG_CYCLE = 0.5 -- for write operations and skybox changes api.MEDIUM_CYCKE = 2.0 -- for ressource intensive tasks
api.LONG_CYCLE = 5.0 -- for write operations and skybox changes
climate_mod.weathers = {} climate_mod.weathers = {}
climate_mod.effects = {} climate_mod.effects = {}

View File

@ -22,7 +22,7 @@ function utility.merge_tables(a, b)
end end
-- see https://en.wikipedia.org/wiki/Logistic_function -- see https://en.wikipedia.org/wiki/Logistic_function
function utility.logistic_growth(value, max, growth, midpoint) function utility.sigmoid(value, max, growth, midpoint)
return max / (1 + math.exp(-growth * (value - midpoint))) return max / (1 + math.exp(-growth * (value - midpoint)))
end end

View File

@ -1,16 +1,14 @@
local default_state = {
heat = 1,
humidity = 1,
wind_x = 0.5,
wind_z = 0.5,
time_last_check = 0,
time_current_day = 1
}
local state = minetest.get_mod_storage() local state = minetest.get_mod_storage()
if not state:contains("time_last_check") then if not state:contains("noise_timer") then
state:from_table({ fields = default_state }) state:from_table({
heat_random = 1,
humidity_random = 1,
humidity_base = 50,
wind_x = 0.5,
wind_z = 0.5,
noise_timer = math.random(0, 300000)
})
end end
return state return state

View File

@ -8,7 +8,7 @@ end
local function get_heat_calendar() local function get_heat_calendar()
-- European heat center in August instead of June -- European heat center in August instead of June
local day = minetest.get_day_count() local day = minetest.get_day_count()
local progression = (day + 61) / 365 local progression = ((day + 61) % 365) / 365
return climate_api.utility.normalized_cycle(progression) * 0.6 + 0.7 return climate_api.utility.normalized_cycle(progression) * 0.6 + 0.7
end end

View File

@ -4,6 +4,14 @@ author = TestificateMods
release = 1 release = 1
optional_depends = skylayer, player_monoids, playerphysics optional_depends = skylayer, player_monoids, playerphysics
description = """ description = """
The ultimate weather mod with support not only for rain, snow, and hail, A powerful engine for weather presets and visual effects.
but also seasons, dynamic puddles and snow layers, wind, regrowing fruit and much more. Use the regional climate to set up different effects for different regions.
Control where your effects are activated based on temperature, humidity, wind,
position, light level or a completely custom activator.
Climate API provides temperature and humidity values on a block-per-block basis
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.
Climate API requires additional weather packs in order to function.
Try regional_weather for the best experience.
""" """