1
0
mirror of https://github.com/t-affeldt/regional_weather.git synced 2025-06-28 22:56:02 +02:00

5 Commits

19 changed files with 272 additions and 182 deletions

View File

@ -25,6 +25,7 @@ The following mods are recommended to be installed alongside Regional Weather:
- [Lightning](https://github.com/minetest-mods/lightning): Adds to heavy rain by enabling additional lightning effects
- [Farming](https://github.com/minetest/minetest_game/tree/master/mods/farming) (as part of MTG) or [Farming Redo](https://forum.minetest.net/viewtopic.php?t=9019): Add farmland and crops to grow food. Farmland wil turn wet during rain effects.
- [Fire](https://github.com/minetest/minetest_game/tree/master/mods/fire) (as part of MTG): Adds fires that can be caused by lightning strikes and other effects and will be extinguished during rain effects.
- [Pedology](https://forum.minetest.net/viewtopic.php?f=11&t=9429) Adds a lot of nodes with dynamic wetness and dryness states.
- [Ambience](https://notabug.org/TenPlus1/ambience): Plays some nice ambient sound effects based on where you are.
For easier installation, you can get a lot of these mods as part of my [Climate Modpack](https://github.com/t-affeldt/climate).
@ -35,8 +36,6 @@ Go to ``Settings → All Settings → Mods → regional_weather`` to change them
Also check out the options inside the ``climate_api`` section for additional configuration options, including performance tweaks and feature switches.
### Features
- ``Cause player damage`` (default true):
If set to true, sand storms and hail will damage affected players over time.
- ``Place snow layers`` (default true):
If set to true, snow layers will stack up during snowy weather.
- ``Freeze river water`` (default true):
@ -50,6 +49,9 @@ Also check out the options inside the ``climate_api`` section for additional con
- ``Extinguish fire`` (bool true):
If set to true, fires will be extinguished during rain showers.
Requires *fire* mod.
- ``Wetten pedology nodes`` (default true):
If set to true, rain will wetten or dry nodes from pedology mod.
Requires *pedology* mod.
### World Configuration
- ``Maximum height of weather effects`` (default 120):
@ -58,6 +60,10 @@ Also check out the options inside the ``climate_api`` section for additional con
- ``Minimum height of weather effects`` (default -50):
No visual effects will be applied below this height.
This will prevent unwanted visuals within large underground caves.
- ``Cloud height`` (default 120)
Average height of cloud bases
- ``Cloud height variation`` (default 40)
Maxmial variation of cloud height from base value
## License information
### Source Code

View File

@ -8,7 +8,14 @@ local BLOCK_NAME = "regional_weather:ice"
minetest.register_node(BLOCK_NAME, {
tiles = {"(default_ice.png^[colorize:#ffffff:50)^[opacity:200"},
paramtype = "light",
groups = {cracky = 3, cools_lava = 1, slippery = 3, dig_immediate = 2},
groups = {
cracky = 3,
cools_lava = 1,
slippery = 3,
dig_immediate = 2,
melts = 1
},
freezemelt = "default:river_water_source",
sounds = default.node_sound_glass_defaults(),
use_texture_alpha = true,
drop = "",

28
abms/pedology.lua Normal file
View File

@ -0,0 +1,28 @@
if not regional_weather.settings.pedology
or not minetest.get_modpath("pedology")
then return end
climate_api.register_abm({
label = "wetten or dry pedology nodes",
nodenames = { "group:sucky" },
neighbors = { "air" },
interval = 25,
chance = 30,
catch_up = false,
conditions = {
min_height = regional_weather.settings.min_height,
max_height = regional_weather.settings.max_height,
min_heat = 25,
min_light = 15
},
action = function (pos, node, env)
local wetness = minetest.get_item_group(node.name, "wet") or 0
if wetness < 2 and env.humidity > 55 then
pedology.wetten(pos)
elseif wetness > 0 and wetness < 3 and env.humidity < 40 then
pedology.dry(pos)
end
end
})

View File

@ -2,6 +2,16 @@ local BLOCK_PREFIX = "regional_weather:puddle_"
local VARIANT_COUNT = 39
local MIN_DISTANCE = 4
local GROUND_COVERS = {
"group:soil",
"group:stone",
"group:sand",
"group:wood",
"default:permafrost",
"default:permafrost_with_moss",
"default:permafrost_with_stones"
}
if not regional_weather.settings.puddles then
for i=1,VARIANT_COUNT do
for r=0,270,90 do
@ -17,74 +27,68 @@ local node_box = {
}
for i = 1,VARIANT_COUNT do
for rotation = 0,270,90 do
for flip = 0,1 do
local name = BLOCK_PREFIX .. i .. "_" .. rotation
local index = i
if i < 10 then index = "0" .. i end
local texture = "weather_puddle_" .. index .. ".png^[opacity:128"
if flip == 1 or rotation > 0 then
texture = texture .. "^[transform"
end
if flip == 1 then
name = name .. "_flipped"
texture = texture .. "FX"
end
if rotation > 0 then
texture = texture .. "R" .. rotation
end
minetest.register_node(name, {
tiles = { texture },
drawtype = "nodebox",
pointable = false,
buildable_to = true,
floodable = true,
walkable = false,
sunlight_propagates = true,
paramtype = "light",
use_texture_alpha = true,
node_box = node_box,
groups = {
not_in_creative_inventory = 1,
crumbly = 3,
attached_node = 1,
slippery = 1,
flora = 1,
water = 1,
regional_weather_puddle = 1
},
drop = "",
sounds = {
footstep = {
name = "weather_puddle",
gain = 0.8
}
}
})
for flip = 0,1 do
local name = BLOCK_PREFIX .. i
local index = i
if i < 10 then index = "0" .. i end
local texture = "weather_puddle_" .. index .. ".png^[opacity:128"
if flip == 1 then
name = name .. "_flipped"
texture = texture .. "^[transformFX"
end
minetest.register_node(name, {
tiles = { texture },
drawtype = "nodebox",
pointable = false,
buildable_to = true,
floodable = true,
walkable = false,
sunlight_propagates = true,
paramtype = "light",
paramtype2 = "facedir",
use_texture_alpha = true,
node_box = node_box,
groups = {
not_in_creative_inventory = 1,
crumbly = 3,
attached_node = 1,
slippery = 1,
flora = 1,
water = 1,
weather_puddle = 1
},
drop = "",
sounds = {
footstep = {
name = "weather_puddle",
gain = 0.8
}
}
})
end
end
minetest.register_alias("regional_weather:puddle", BLOCK_PREFIX .. "14_0")
minetest.register_alias("regional_weather:puddle", BLOCK_PREFIX .. "14")
local function get_random_puddle()
local index = math.random(1, VARIANT_COUNT)
local rotation = math.random(0, 3) * 90
local flip = math.random(0, 1)
local name = BLOCK_PREFIX .. index .. "_" .. rotation
local name = BLOCK_PREFIX .. index
if flip == 1 then
name = name .. "_flipped"
end
return name
local param2 = minetest.dir_to_facedir(minetest.yaw_to_dir(rotation))
return { name = name, param2 = param2 }
end
-- Makes Puddles when raining
climate_api.register_abm({
label = "create rain puddles",
nodenames = { "group:soil", "group:stone" },
nodenames = GROUND_COVERS,
neighbors = { "air" },
interval = 15,
chance = 50,
interval = 8,
chance = 150,
catch_up = false,
conditions = {
@ -101,9 +105,8 @@ climate_api.register_abm({
action = function (pos, node, env)
if minetest.get_node(pos).name ~= "air" then return end
if minetest.find_node_near(pos, MIN_DISTANCE, "group:regional_weather_puddle") then return end
local puddle_name = get_random_puddle()
minetest.set_node(pos, {name = puddle_name})
if minetest.find_node_near(pos, MIN_DISTANCE, "group:weather_puddle") then return end
minetest.set_node(pos, get_random_puddle())
end
})

View File

@ -77,7 +77,7 @@ climate_api.register_abm({
end,
action = function (pos, node, env)
if minetest.get_node(pos).name ~= "air" then return end
if node.name ~= "air" then return end
local base = minetest.get_node(vector.add(pos, {x=0, y=-1, z=0})).name
local is_soil = minetest.get_item_group(base, "soil") or 0
local is_stone = minetest.get_item_group(base, "stone") or 0
@ -109,8 +109,7 @@ climate_api.register_abm({
},
action = function (pos, node, env)
local node_name = minetest.get_node(pos).name
local value = minetest.get_item_group(node_name, "regional_weather_snow_cover")
local value = minetest.get_item_group(node.name, "regional_weather_snow_cover")
if value == nil then value = 0 end
if value < 5 then
minetest.set_node(pos, { name = BLOCK_PREFIX .. (value + 1) })
@ -130,8 +129,7 @@ climate_api.register_abm({
},
action = function (pos, node, env)
local node_name = minetest.get_node(pos).name
local value = minetest.get_item_group(node_name, "regional_weather_snow_cover")
local value = minetest.get_item_group(node.name, "regional_weather_snow_cover")
if value == nil then value = 0 end
if value > 1 then
minetest.set_node(pos, { name = BLOCK_PREFIX .. (value - 1) })

View File

@ -1,22 +0,0 @@
if not minetest.is_yes(minetest.settings:get_bool("enable_damage"))
or not regional_weather.settings.damage then return end
local EFFECT_NAME = "regional_weather:damage"
local rng = PcgRandom(7819792)
local function handle_effect(player_data)
for playername, data in pairs(player_data) do
local player = minetest.get_player_by_name(playername)
local hp = player:get_hp()
for weather, dmg in pairs(data) do
if rng:next(1, dmg.chance) == 1 then
hp = hp - dmg.value
end
end
player:set_hp(hp, "weather damage")
end
end
climate_api.register_effect(EFFECT_NAME, handle_effect, "tick")
climate_api.set_effect_cycle(EFFECT_NAME, climate_api.MEDIUM_CYCLE)

View File

@ -1,8 +1,14 @@
--[[
# Lightning Effect
Use this effect to cause lightning strikes.
Requires lightning mod in order to function. Uses default lightning configuration.
Expects an integer indicating a chance (between 0 and 1) for lightning to strike (per cycle and player).
]]
if not minetest.get_modpath("lightning") then return end
local EFFECT_NAME = "regional_weather:lightning"
local LIGHTNING_CHANCE = 20
lightning.auto = false
local rng = PcgRandom(82492402425)
@ -32,8 +38,15 @@ end
local function handle_effect(player_data)
for playername, data in pairs(player_data) do
local random = rng:next(1, LIGHTNING_CHANCE)
if random == 1 then
local chance = 0
for weather, value in pairs(data) do
if type(value) ~= "number" then
value = 1/20
end
chance = chance + value - (chance * value)
end
local random = math.random()
if random <= chance then
local player = minetest.get_player_by_name(playername)
local ppos = player:get_pos()
local position = choose_pos(ppos)

View File

@ -1,3 +1,9 @@
--[[
# Player Speed Effect
Use this effect to modify a player's movement speed.
Expects a numeric value that will be multiplied with the current speed physics.
]]
local EFFECT_NAME = "regional_weather:speed_buff"
local function handle_effect(player_data)
@ -7,14 +13,14 @@ local function handle_effect(player_data)
for weather, value in pairs(data) do
product = product * value
end
climate_api.utility.add_physics(EFFECT_NAME, player, "speed", product)
climate_api.player_physics.add(EFFECT_NAME, player, "speed", product)
end
end
local function remove_effect(player_data)
for playername, data in ipairs(player_data) do
local player = minetest.get_player_by_name(playername)
climate_api.utility.remove_physics(EFFECT_NAME, player, "speed")
climate_api.player_physics.remove(EFFECT_NAME, player, "speed")
end
end

View File

@ -1,19 +1,36 @@
local name = "regional_weather:ambient"
local CLOUD_SPEED = 1.8
local conditions = {}
-- see https://en.wikipedia.org/wiki/Cloud_base
local function calc_cloud_height(heat, humidity, dewpoint)
local base = regional_weather.settings.cloud_height
-- much lower scale like 20 instead of 1000 fitting for Minetest
local scale = regional_weather.settings.cloud_scale
local spread = heat - dewpoint
local variation = spread / 4.4 * scale * 0.3
return base + climate_api.utility.rangelim(variation, -scale, scale)
end
local function generate_effects(params)
local override = {}
local wind = climate_api.environment.get_wind()
local cloud_height = calc_cloud_height(params.heat, params.humidity, params.dewpoint)
local wind = climate_api.environment.get_wind({ x = 0, y = cloud_height, z = 0 })
local skybox = {priority = 10}
skybox.cloud_data = {
density = climate_api.utility.rangelim(params.humidity / 100, 0.25, 0.75),
speed = vector.multiply(wind, CLOUD_SPEED),
thickness = climate_api.utility.rangelim(params.base_humidity * 0.2, 1, 18)
density = climate_api.utility.rangelim(params.humidity / 100, 0.15, 0.65),
speed = wind,
thickness = climate_api.utility.rangelim(params.base_humidity * 0.2, 1, 18),
height = cloud_height,
ambient = "#0f0f1050"
}
if params.height > -100 and params.humidity > 40 then
skybox.cloud_data.color = "#b2a4a4b0"
end
if params.height > -100 and params.humidity > 65 then
skybox.sky_data = {
type = "regular",
@ -27,6 +44,8 @@ local function generate_effects(params)
night_horizon = "#315d9b"
}
}
skybox.cloud_data.color = "#828e97b5"
skybox.cloud_data.ambient = "#20212250"
end
override["climate_api:skybox"] = skybox

View File

@ -3,6 +3,7 @@ local name = "regional_weather:hail"
local conditions = {
min_height = regional_weather.settings.min_height,
max_height = regional_weather.settings.max_height,
min_heat = 30,
max_heat = 45,
min_humidity = 65,
min_windspeed = 2.5,
@ -11,9 +12,14 @@ local conditions = {
local effects = {}
effects["regional_weather:damage"] = {
chance = 15,
value = 3
effects["climate_api:damage"] = {
rarity = 15,
value = 3,
check = {
type = "raycast",
height = 7,
velocity = 20
}
}
effects["climate_api:sound"] = {
@ -21,18 +27,21 @@ effects["climate_api:sound"] = {
gain = 1
}
effects["climate_api:particles"] = {
min_pos = {x=-9, y=7, z=-9},
max_pos = {x= 9, y=7, z= 9},
falling_speed=20,
amount=6,
exptime=0.7,
size=1,
textures = {}
}
effects["regional_weather:lightning"] = 1 / 30
for i = 1,5,1 do
effects["climate_api:particles"].textures[i] = "weather_hail" .. i .. ".png"
local textures = {}
for i = 1,5 do
textures[i] = "weather_hail" .. i .. ".png"
end
effects["climate_api:particles"] = {
boxsize = { x = 18, y = 0, z = 18 },
v_offset = 7,
velocity = 20,
amount = 6,
expirationtime = 0.7,
texture = textures,
glow = 5
}
climate_api.register_weather(name, conditions, effects)

View File

@ -34,14 +34,15 @@ local conditions = {
local effects = {}
effects["climate_api:particles"] = {
min_pos = {x=-12, y=-4, z=-12},
max_pos = {x= 12, y= 1, z= 12},
falling_speed = -0.1,
acceleration = {x=0,y=-0.03,z=0},
amount = 1,
exptime = 5,
boxsize = { x = 24, y = 0, z = 24 },
vbox = 5,
v_offset = -1,
velocity = -0.1,
acceleration = -0.03,
expirationtime = 5,
size = 0.8,
texture = "weather_pollen.png"
texture = "weather_pollen.png",
glow = 2
}
climate_api.register_weather(name, conditions, effects)

View File

@ -17,14 +17,15 @@ effects["climate_api:sound"] = {
}
effects["climate_api:particles"] = {
min_pos = {x=-9, y=8, z=-9},
max_pos = {x= 9, y=6, z= 9},
exptime = 1.1,
boxsize = { x = 18, y = 2, z = 18 },
v_offset = 6,
expirationtime = 1.6,
size = 2,
amount = 15,
falling_speed = 6,
acceleration={x=0, y=-0.05, z=0},
texture = "weather_raindrop.png"
velocity = 6,
acceleration = 0.05,
texture = "weather_raindrop.png",
glow = 5
}
climate_api.register_weather(name, conditions, effects)

View File

@ -10,24 +10,34 @@ local conditions = {
local effects = {}
effects["climate_api:skybox"] = {
cloud_data = {
color = "#5e676eb5"
},
priority = 11
}
effects["climate_api:sound"] = {
name = "weather_rain_heavy",
gain = 1
}
effects["regional_weather:lightning"] = 1 / 20
effects["climate_api:particles"] = {
min_pos = {x=-9, y=7, z=-9},
max_pos = {x= 9, y=7, z= 9},
falling_speed=7,
amount=17,
exptime=0.8,
min_size=25,
max_size=35,
textures={
boxsize = { x = 18, y = 0, z = 18 },
v_offset = 7,
velocity = 7,
amount = 17,
expirationtime = 1.2,
minsize = 25,
maxsize = 35,
texture = {
"weather_rain.png",
"weather_rain.png",
"weather_rain_medium.png"
}
},
glow = 5
}
climate_api.register_weather(name, conditions, effects)

View File

@ -24,22 +24,28 @@ effects["climate_api:hud_overlay"] = {
color_correction = true
}
effects["regional_weather:damage"] = {
chance = 3,
value = 1
effects["climate_api:damage"] = {
rarity = 3,
value = 1,
check = {
type = "raycast",
height = 0,
velocity = 0.3
}
}
effects["climate_api:particles"] = {
min_pos = {x=-5, y=-4, z=-5},
max_pos = {x= 5, y= 4.5, z= 5},
falling_speed=1.2,
acceleration={x=0,y=0.8,z=0},
amount=40,
exptime=1.8,
size=20,
textures={
boxsize = { x = 8, y = 4.5, z = 8 },
velocity = 0.6,
acceleration = -0.2,
amount = 12,
expirationtime = 0.7,
size = 25,
texture = {
"weather_sandstorm.png",
"weather_sandstorm.png^[transformR180"
"weather_sandstorm.png^[transformFY",
"weather_sandstorm.png^[transformR180",
"weather_sandstorm.png^[transformFYR180"
}
}

View File

@ -11,19 +11,20 @@ local conditions = {
local effects = {}
effects["climate_api:particles"] = {
min_pos = {x=-12, y=2, z=-12},
max_pos = {x= 12, y=8, z= 12},
amount = 4,
exptime = 7,
size = 1,
falling_speed = 0.85,
acceleration = {x=0, y=0.06, z=0},
textures = {}
}
local textures = {}
for i = 1,12,1 do
effects["climate_api:particles"].textures[i] = "weather_snowflake" .. i .. ".png"
textures[i] = "weather_snowflake" .. i .. ".png"
end
effects["climate_api:particles"] = {
boxsize = { x = 24, y = 6, z = 24 },
v_offset = 2,
amount = 4,
expirationtime = 7,
velocity = 0.85,
acceleration = -0.06,
texture = textures,
glow = 6
}
climate_api.register_weather(name, conditions, effects)

View File

@ -10,6 +10,13 @@ local conditions = {
local effects = {}
effects["climate_api:skybox"] = {
cloud_data = {
color = "#5e676eb5"
},
priority = 11
}
effects["climate_api:hud_overlay"] = {
file = "weather_hud_frost.png",
z_index = -100,
@ -17,24 +24,14 @@ effects["climate_api:hud_overlay"] = {
}
effects["climate_api:particles"] = {
min_pos = {x=-8, y=3, z=-8},
max_pos = {x= 8, y=6, z= 8},
exptime=6,
size=10,
texture="weather_snow.png"
boxsize = { x = 14, y = 3, z = 14 },
v_offset = 3,
expirationtime = 7.5,
size = 15,
amount = 6,
velocity = 0.75,
texture = "weather_snow.png",
glow = 6
}
local function generate_effects(params)
local avg_humidity = 55
local intensity = params.humidity / avg_humidity
local override = {}
override["climate_api:particles"] = {
amount = 16 * math.min(intensity, 1.5),
falling_speed = 1 / math.min(intensity, 1.3)
}
return climate_api.utility.merge_tables(effects, override)
end
climate_api.register_weather(name, conditions, generate_effects)
climate_api.register_weather(name, conditions, effects)

View File

@ -15,14 +15,16 @@ end
regional_weather = {}
regional_weather.settings = {}
regional_weather.settings.damage = get_setting_bool("damage", true)
regional_weather.settings.snow = get_setting_bool("snow_layers", true)
regional_weather.settings.puddles = get_setting_bool("puddles", true)
regional_weather.settings.soil = get_setting_bool("soil", true)
regional_weather.settings.fire = get_setting_bool("fire", true)
regional_weather.settings.ice = get_setting_bool("ice", true)
regional_weather.settings.pedology = get_setting_bool("pedology", true)
regional_weather.settings.max_height = get_setting_number("max_height", 120)
regional_weather.settings.min_height = get_setting_number("min_height", -50)
regional_weather.settings.cloud_height= get_setting_number("cloud_height", 120)
regional_weather.settings.cloud_scale = get_setting_number("cloud_scale", 40)
-- warn about clouds being overriden by MTG weather
if climate_mod.settings.skybox
@ -46,7 +48,6 @@ dofile(modpath.."/ca_weathers/snow_heavy.lua")
dofile(modpath.."/ca_weathers/storm.lua")
-- register environment effects
dofile(modpath.."/ca_effects/damage.lua")
dofile(modpath.."/ca_effects/lightning.lua")
dofile(modpath.."/ca_effects/speed_buff.lua")
@ -55,4 +56,5 @@ dofile(modpath .. "/abms/puddle.lua")
dofile(modpath .. "/abms/snow_cover.lua")
dofile(modpath .. "/abms/fire.lua")
dofile(modpath .. "/abms/ice.lua")
dofile(modpath .. "/abms/pedology.lua")
dofile(modpath .. "/abms/soil.lua")

View File

@ -1,9 +1,9 @@
name = regional_weather
title = Regional Weather
author = TestificateMods
release = 1
release = 100000
depends = climate_api
optional_depends = default, lightning, farming, fire
optional_depends = default, lightning, farming, fire, pedology
description = """
Not every biome is the same and neither should their weather be.
Regional Weather controls it's effects with the local climate in mind.

View File

@ -1,8 +1,5 @@
[Features]
# If set to true, sand storms and hail will damage affected players over time.
regional_weather_damage (Cause player damage) bool true
# If set to true, snow layers will stack up during snowy weather.
regional_weather_snow_layers (Place snow layers) bool true
@ -19,13 +16,21 @@ regional_weather_soil (Hydrate farmland) bool true
# If set to true, fires will be extinguished during rain showers.
regional_weather_fire (Extinguish fire) bool true
# If set to true, rain will wetten or dry nodes from pedology mod.
regional_weather_pedology (Wetten pedology nodes) bool true
[World Configuration]
# No visual effects will be applied below this height.
# This will prevent unwanted visuals within large underground caves.
regional_weather_min_height (Minimum height of weather effects) int -50
# No visual effects will be applied above this height.
# This value defaults to normal cloud height (120 nodes above sea level).
regional_weather_max_height (Maximum height of weather effects) int 120
# No visual effects will be applied below this height.
# This will prevent unwanted visuals within large underground caves.
regional_weather_min_height (Minimum height of weather effects) int -50
# Average height of cloud bases
regional_weather_cloud_height (Cloud height) int 120
# Maxmial variation of cloud height from base value
regional_weather_cloud_scale (Cloud height variation) int 40