diff --git a/ROADMAP.md b/ROADMAP.md index bef6808..f65ba33 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -2,13 +2,10 @@ ## Required for Beta - Write helpful README -- Refactor skybox effect and implement ranking system - Rework Moon Phases mod to be compatible and to include varying sky brightness ## Planned for first release -- Set effects on player join - Improve value structures of particle effects -- Make sounds adjust to changes by weather presets - Find good values for weather conditions - Write documentation on how to add weathers and effects - Ability to register global influences that are the same for any position @@ -16,10 +13,8 @@ ## Nice to have - Assign meta data (like "downfall", "wind", etc.) to weather presets - 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 - Generate wind based on speed and yaw instead of x and z values -- A flag indicating wind direction ## Future Plans & Ideas - Complete season system @@ -46,4 +41,5 @@ - swimming will cool down - standing near fire will warm up - craftable warm clothes - - metal armor will worsen heat issues \ No newline at end of file + - metal armor will worsen heat issues +- A flag indicating wind direction \ No newline at end of file diff --git a/ca_effects/skybox.lua b/ca_effects/skybox.lua index 08e9e5c..bce8b78 100644 --- a/ca_effects/skybox.lua +++ b/ca_effects/skybox.lua @@ -1,45 +1,31 @@ if not climate_mod.settings.skybox then return end local EFFECT_NAME = "climate_api:skybox" -local modpath = minetest.get_modpath(minetest.get_current_modname()) -local sky_defaults = dofile(modpath .. "/lib/sky_defaults.lua") -local function set_skybox(player, sky) - 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 - -local function remove_skybox(player) - if not player.get_stars then return end - player:set_sky(sky_defaults.sky_data) - player:set_clouds(sky_defaults.cloud_data) - player:set_moon(sky_defaults.moon_data) - player:set_sun(sky_defaults.sun_data) - player:set_stars(sky_defaults.star_data) -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 = table.copy(sky_defaults) - for weather, value in pairs(data) do - sky = climate_api.utility.merge_tables(sky, value) +local function handle_effect(player_data, prev_data) + for playername, data in pairs(prev_data) do + for weather, _ in pairs(data) do + if player_data[playername] == nil or player_data[playername][weather] == nil then + climate_api.skybox.remove_layer(playername, weather) + 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 local function remove_effect(player_data) for playername, data in pairs(player_data) do - local player = minetest.get_player_by_name(playername) - remove_skybox(player) + for weather, _ in pairs(data) do + climate_api.skybox.remove_layer(playername, weather) + end end end climate_api.register_effect(EFFECT_NAME, handle_effect, "tick") climate_api.register_effect(EFFECT_NAME, remove_effect, "stop") ---climate_api.set_effect_cycle("climate_api:skybox", climate_api.LONG_CYCLE) \ No newline at end of file +climate_api.set_effect_cycle("climate_api:skybox", climate_api.MEDIUM_CYCLE) \ No newline at end of file diff --git a/init.lua b/init.lua index a7e6f81..cf8eec7 100644 --- a/init.lua +++ b/init.lua @@ -27,6 +27,7 @@ climate_mod.settings = { wind = get_setting_bool("wind", true), seasons = get_setting_bool("seasons", true), fahrenheit = get_setting_bool("fahrenheit", false), + block_updates = get_setting_bool("block_updates", true), heat = get_setting_number("heat_base", 0), humidity = get_setting_number("humidity_base", 0), time_spread = get_setting_number("time_spread", 1), @@ -49,6 +50,7 @@ climate_mod.forced_wind = nil climate_mod.state = dofile(modpath .. "/lib/datastorage.lua") climate_api = dofile(modpath .. "/lib/api.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 = dofile(modpath .. "/lib/influences.lua") diff --git a/lib/api.lua b/lib/api.lua index afc4b16..f799ad6 100644 --- a/lib/api.lua +++ b/lib/api.lua @@ -38,6 +38,8 @@ function api.register_influence(name, func) end function api.register_abm(config) + if not climate_mod.settings.block_updates then return end + local conditions = config.conditions local action = config.action local pos_override = config.pos_override diff --git a/lib/environment.lua b/lib/environment.lua index 3a8d2ee..9330352 100644 --- a/lib/environment.lua +++ b/lib/environment.lua @@ -5,13 +5,6 @@ local function get_heat_time() return climate_api.utility.normalized_cycle(time) * 0.6 + 0.7 end -local function get_heat_calendar() - -- 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) return climate_api.utility.rangelim((-y + 10) / 15, -10, 10) end @@ -21,9 +14,8 @@ function environment.get_heat(pos) local biome = minetest.get_heat(pos) local height = get_heat_height(pos.y) local time = get_heat_time() - local date = get_heat_calendar() local random = climate_mod.state:get_float("heat_random"); - return (base + biome + height) * time * date * random + return (base + biome + height) * time * random end function environment.get_humidity(pos) diff --git a/lib/sky_defaults.lua b/lib/sky_defaults.lua deleted file mode 100644 index 0f37578..0000000 --- a/lib/sky_defaults.lua +++ /dev/null @@ -1,46 +0,0 @@ -return { - 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 - } -} \ No newline at end of file diff --git a/lib/skybox_merger.lua b/lib/skybox_merger.lua new file mode 100644 index 0000000..4da1afd --- /dev/null +++ b/lib/skybox_merger.lua @@ -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 = "", + tonemap = "sun_tonemap.png", + sunrise = "sunrisebg.png", + sunrise_visible = true, + scale = 1 + }, + moon_data = { + visible = true, + texture = "", + 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 \ No newline at end of file diff --git a/lib/world.lua b/lib/world.lua index 7419e97..7763cc4 100644 --- a/lib/world.lua +++ b/lib/world.lua @@ -2,11 +2,11 @@ local world = {} local WIND_SPREAD = 600 local WIND_SCALE = 2 -local HEAT_SPREAD = 200 +local HEAT_SPREAD = 400 local HEAT_SCALE = 0.3 -local HUMIDITY_SPREAD = 60 +local HUMIDITY_SPREAD = 150 local HUMIDITY_SCALE = 0.5 -local HUMIDITY_BASE_SPREAD = 600 +local HUMIDITY_BASE_SPREAD = 800 local HUMIDITY_BASE_SCALE = 40 local nobj_wind_x diff --git a/screenshot.2.png b/screenshot.2.png deleted file mode 100644 index 71a55b1..0000000 Binary files a/screenshot.2.png and /dev/null differ diff --git a/screenshot.3.png b/screenshot.3.png deleted file mode 100644 index 2f3c7a8..0000000 Binary files a/screenshot.3.png and /dev/null differ diff --git a/settingtypes.txt b/settingtypes.txt index 2ec012a..f5c1c5f 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -1,13 +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_skybox (Allow weather effects to modify the skybox) bool true -climate_api_sound (Allow weather presets to play ambient sounds) bool true -climate_api_hud_overlay (Allow weather presets to display a HUD overlay) bool true -climate_api_wind (Allow wind to angle rainfall) bool true -climate_api_seasons (Change global temperature based on an annual cycle) bool true + +# If set to true, weather effects are allowed to modify a player's sky. +# This includes skybox, sun, moon, and clouds (also used for fog effects). +# Running this mod on Minetest 5.1.2 or earlier versions will automatically disable this feature. +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 + +# 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_time_spread (Regulates how quickly the weather changes) float 1 0.1 10 -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 + +# 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 -climate_api_volume (Volume of sound effects) float 1 0 10 \ No newline at end of file + + +[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 + +# 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