mirror of
https://github.com/t-affeldt/climate_api.git
synced 2025-05-01 00:41:45 -04:00
Compare commits
31 commits
Author | SHA1 | Date | |
---|---|---|---|
|
85e4553f2a | ||
|
8b846b23dc | ||
|
8e3ce58015 | ||
|
04cfef309a | ||
|
2093eea77f | ||
|
c23277284a | ||
|
5448e04d85 | ||
|
79233a2cb1 | ||
|
f3f0eaac2a | ||
|
0dd5c74d42 | ||
|
d1c70e904b | ||
|
7d299edb5b | ||
|
bf2d4e09ca | ||
|
4d0b080dd5 | ||
|
eff85fbd2b | ||
|
5635ab4daa | ||
|
e8f4048670 | ||
|
dd769dfdd0 | ||
|
710a1d717b | ||
|
59bf43aa28 | ||
|
a56116e8ab | ||
|
cd98798880 | ||
|
a3d4dd446d | ||
|
80d661f33a | ||
|
5fe30aa051 | ||
|
db2c2ae001 | ||
|
beb75254bf | ||
|
dbce69be3b | ||
|
06f337b23e | ||
|
082c789d6e | ||
|
de512c172c |
24 changed files with 497 additions and 151 deletions
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**Desktop (please complete the following information):**
|
||||||
|
- OS: [e.g. iOS]
|
||||||
|
- Browser [e.g. chrome, safari]
|
||||||
|
- Version [e.g. 22]
|
||||||
|
|
||||||
|
**Smartphone (please complete the following information):**
|
||||||
|
- Device: [e.g. iPhone6]
|
||||||
|
- OS: [e.g. iOS8.1]
|
||||||
|
- Browser [e.g. stock browser, safari]
|
||||||
|
- Version [e.g. 22]
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
*.code-workspace
|
76
CODE_OF_CONDUCT.md
Normal file
76
CODE_OF_CONDUCT.md
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
In the interest of fostering an open and welcoming environment, we as
|
||||||
|
contributors and maintainers pledge to making participation in our project and
|
||||||
|
our community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||||
|
level of experience, education, socio-economic status, nationality, personal
|
||||||
|
appearance, race, religion, or sexual identity and orientation.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to creating a positive environment
|
||||||
|
include:
|
||||||
|
|
||||||
|
* Using welcoming and inclusive language
|
||||||
|
* Being respectful of differing viewpoints and experiences
|
||||||
|
* Gracefully accepting constructive criticism
|
||||||
|
* Focusing on what is best for the community
|
||||||
|
* Showing empathy towards other community members
|
||||||
|
|
||||||
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||||
|
advances
|
||||||
|
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or electronic
|
||||||
|
address, without explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Our Responsibilities
|
||||||
|
|
||||||
|
Project maintainers are responsible for clarifying the standards of acceptable
|
||||||
|
behavior and are expected to take appropriate and fair corrective action in
|
||||||
|
response to any instances of unacceptable behavior.
|
||||||
|
|
||||||
|
Project maintainers have the right and responsibility to remove, edit, or
|
||||||
|
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||||
|
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||||
|
permanently any contributor for other behaviors that they deem inappropriate,
|
||||||
|
threatening, offensive, or harmful.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies both within project spaces and in public spaces
|
||||||
|
when an individual is representing the project or its community. Examples of
|
||||||
|
representing a project or community include using an official project e-mail
|
||||||
|
address, posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event. Representation of a project may be
|
||||||
|
further defined and clarified by project maintainers.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported by contacting the project team at t.affeldt@tu-braunschweig.de. All
|
||||||
|
complaints will be reviewed and investigated and will result in a response that
|
||||||
|
is deemed necessary and appropriate to the circumstances. The project team is
|
||||||
|
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||||
|
Further details of specific enforcement policies may be posted separately.
|
||||||
|
|
||||||
|
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||||
|
faith may face temporary or permanent repercussions as determined by other
|
||||||
|
members of the project's leadership.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||||
|
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see
|
||||||
|
https://www.contributor-covenant.org/faq
|
|
@ -43,7 +43,7 @@ local function check_hit(player, ray)
|
||||||
)
|
)
|
||||||
origin = vector.add(origin, windpos)
|
origin = vector.add(origin, windpos)
|
||||||
end
|
end
|
||||||
local ray = minetest.raycast(origin, ppos)
|
ray = minetest.raycast(origin, ppos)
|
||||||
local obj = ray:next()
|
local obj = ray:next()
|
||||||
-- found nothing
|
-- found nothing
|
||||||
if obj == nil then return false end
|
if obj == nil then return false end
|
||||||
|
|
|
@ -14,6 +14,8 @@ 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)
|
||||||
local player = minetest.get_player_by_name(pname)
|
local player = minetest.get_player_by_name(pname)
|
||||||
|
if player == nil then return end
|
||||||
|
|
||||||
if handles[pname] == nil then handles[pname] = {} end
|
if handles[pname] == nil then handles[pname] = {} end
|
||||||
if handles[pname][weather] ~= nil then
|
if handles[pname][weather] ~= nil then
|
||||||
player:hud_remove(handles[pname][weather])
|
player:hud_remove(handles[pname][weather])
|
||||||
|
@ -48,9 +50,11 @@ local function apply_hud(pname, weather, hud)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function remove_hud(pname, weather, hud)
|
local function remove_hud(pname, weather, hud)
|
||||||
if handles[pname] == nil or handles[pname][weather] == nil then return end
|
|
||||||
local handle = handles[pname][weather]
|
|
||||||
local player = minetest.get_player_by_name(pname)
|
local player = minetest.get_player_by_name(pname)
|
||||||
|
if player == nil then return end
|
||||||
|
if handles[pname] == nil or handles[pname][weather] == nil then return end
|
||||||
|
|
||||||
|
local handle = handles[pname][weather]
|
||||||
player:hud_remove(handle)
|
player:hud_remove(handle)
|
||||||
handles[pname][weather] = nil
|
handles[pname][weather] = nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -165,7 +165,7 @@ local function parse_config(player, particles)
|
||||||
|
|
||||||
-- correct spawn coordinates to adjust for player movement
|
-- correct spawn coordinates to adjust for player movement
|
||||||
if config.adjust_for_velocity then
|
if config.adjust_for_velocity then
|
||||||
local velocity = player:get_player_velocity()
|
local velocity = player:get_velocity()
|
||||||
config.minpos = vector.add(config.minpos, velocity)
|
config.minpos = vector.add(config.minpos, velocity)
|
||||||
config.maxpos = vector.add(config.maxpos, velocity)
|
config.maxpos = vector.add(config.maxpos, velocity)
|
||||||
end
|
end
|
||||||
|
|
|
@ -41,3 +41,4 @@ 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(EFFECT_NAME, climate_api.LONG_CYCLE)
|
49
init.lua
49
init.lua
|
@ -25,24 +25,41 @@ end
|
||||||
|
|
||||||
-- load settings from config file
|
-- load settings from config file
|
||||||
climate_mod.settings = {
|
climate_mod.settings = {
|
||||||
damage = get_setting_bool("damage", true),
|
damage = get_setting_bool("damage", true),
|
||||||
raycast = get_setting_bool("raycast", true),
|
raycast = get_setting_bool("raycast", true),
|
||||||
particles = get_setting_bool("particles", true),
|
particles = get_setting_bool("particles", true),
|
||||||
skybox = get_setting_bool("skybox", true),
|
skybox = get_setting_bool("skybox", true),
|
||||||
sound = get_setting_bool("sound", true),
|
sound = get_setting_bool("sound", true),
|
||||||
hud_overlay = get_setting_bool("hud_overlay", true),
|
hud_overlay = get_setting_bool("hud_overlay", true),
|
||||||
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),
|
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),
|
tick_speed = get_setting_number("tick_speed", 1),
|
||||||
volume = get_setting_number("volume", 1)
|
volume = get_setting_number("volume", 1),
|
||||||
|
ceiling_checks = get_setting_number("ceiling_checks", 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
climate_mod.i18n = minetest.get_translator("climate_api")
|
||||||
|
|
||||||
|
-- attempt to disable MTG weather mod
|
||||||
|
if climate_mod.settings.skybox and minetest.get_modpath("weather") then
|
||||||
|
if weather ~= nil and weather.get ~= nil then
|
||||||
|
weather.get = function(player)
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
elseif minetest.settings:get_bool("enable_weather") then
|
||||||
|
-- old version with no API support
|
||||||
|
-- warn about clouds being overriden by MTG weather
|
||||||
|
minetest.log("warning", "[Regional Weather] " ..
|
||||||
|
climate_mod.i18n("Disable MTG weather for the best experience. Check the forum for more information."))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- initialize empty registers
|
-- initialize empty registers
|
||||||
climate_mod.weathers = {}
|
climate_mod.weathers = {}
|
||||||
climate_mod.effects = {}
|
climate_mod.effects = {}
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
local mod_player_monoids = minetest.get_modpath("player_monoids") ~= nil
|
|
||||||
local mod_playerphysics = minetest.get_modpath("playerphysics") ~= nil
|
|
||||||
local mod_pova = minetest.get_modpath("pova") ~= nil
|
|
||||||
|
|
||||||
local utility = {}
|
local utility = {}
|
||||||
|
|
||||||
function utility.rangelim(value, min, max)
|
function utility.rangelim(value, min, max)
|
||||||
|
|
125
lib/commands.lua
125
lib/commands.lua
|
@ -1,3 +1,5 @@
|
||||||
|
local S = climate_mod.i18n
|
||||||
|
|
||||||
-- parse heat values into readable format
|
-- parse heat values into readable format
|
||||||
-- also convert to Celsius if configured
|
-- also convert to Celsius if configured
|
||||||
local function parse_heat(heat)
|
local function parse_heat(heat)
|
||||||
|
@ -13,13 +15,13 @@ end
|
||||||
|
|
||||||
-- register weather privilege in order to modify the weather status
|
-- register weather privilege in order to modify the weather status
|
||||||
minetest.register_privilege("weather", {
|
minetest.register_privilege("weather", {
|
||||||
description = "Make changes to the current weather",
|
description = S("Make changes to the current weather"),
|
||||||
give_to_singleplayer = false
|
give_to_singleplayer = false
|
||||||
})
|
})
|
||||||
|
|
||||||
-- display general information on current weather
|
-- display general information on current weather
|
||||||
minetest.register_chatcommand("weather", {
|
minetest.register_chatcommand("weather", {
|
||||||
description ="Display weather information",
|
description = S("Display weather information"),
|
||||||
func = function(playername)
|
func = function(playername)
|
||||||
local player = minetest.get_player_by_name(playername)
|
local player = minetest.get_player_by_name(playername)
|
||||||
local ppos = player:get_pos()
|
local ppos = player:get_pos()
|
||||||
|
@ -29,137 +31,138 @@ minetest.register_chatcommand("weather", {
|
||||||
local humidity = math.floor(climate_api.environment.get_humidity(ppos) * 100) / 100
|
local humidity = math.floor(climate_api.environment.get_humidity(ppos) * 100) / 100
|
||||||
local msg = ""
|
local msg = ""
|
||||||
if #weathers > 0 then
|
if #weathers > 0 then
|
||||||
msg = msg .. "The following weather presets are active for you: "
|
msg = msg .. S("The following weather presets are active for you:") .. " "
|
||||||
for _, weather in ipairs(weathers) do
|
for _, weather in ipairs(weathers) do
|
||||||
msg = msg .. weather .. ", "
|
msg = msg .. weather .. ", "
|
||||||
end
|
end
|
||||||
msg = msg:sub(1, #msg-2) .. "\n"
|
msg = msg:sub(1, #msg-2) .. "\n"
|
||||||
else
|
else
|
||||||
msg = msg .. "Your sky is clear. No weather presets are currently active.\n"
|
msg = msg .. S("Your sky is clear. No weather presets are currently active.") .. "\n"
|
||||||
end
|
end
|
||||||
if #effects > 0 then
|
if #effects > 0 then
|
||||||
msg = msg .. "As a result, the following environment effects are applied: "
|
msg = msg .. S("As a result, the following environment effects are applied:") .. " "
|
||||||
for _, effect in ipairs(effects) do
|
for _, effect in ipairs(effects) do
|
||||||
msg = msg .. effect .. ", "
|
msg = msg .. effect .. ", "
|
||||||
end
|
end
|
||||||
msg = msg:sub(1, #msg-2) .. "\n"
|
msg = msg:sub(1, #msg-2) .. "\n"
|
||||||
end
|
end
|
||||||
local heat_desc
|
local heat_desc
|
||||||
if heat > 80 then heat_desc = "scorching"
|
if heat > 80 then heat_desc = S("scorching")
|
||||||
elseif heat > 50 then heat_desc = "pleasant"
|
elseif heat > 50 then heat_desc = S("pleasant")
|
||||||
else heat_desc = "chilly" end
|
else heat_desc = S("chilly") end
|
||||||
msg = msg .. "It is a " .. heat_desc .. " " .. parse_heat(heat) .. " right now and "
|
msg = msg .. S("It is a @1 @2 right now and humidity is at @3%.", heat_desc, parse_heat(heat), humidity) .. "\n"
|
||||||
msg = msg .. "humidity is at " .. humidity .. "%.\n"
|
|
||||||
minetest.chat_send_player(playername, msg)
|
minetest.chat_send_player(playername, msg)
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
-- set base heat to increase or decrease global climate temperatures
|
-- set base heat to increase or decrease global climate temperatures
|
||||||
minetest.register_chatcommand("set_base_heat", {
|
minetest.register_chatcommand("set_base_heat", {
|
||||||
params = "<heat>",
|
params = S("<heat>"),
|
||||||
description = "Override the weather algorithm's base heat",
|
description = S("Override the weather algorithm's base heat"),
|
||||||
privs = { weather = true },
|
privs = { weather = true },
|
||||||
func = function(playername, param)
|
func = function(playername, param)
|
||||||
if param == nil or param == "" then
|
if param == nil or param == "" then
|
||||||
minetest.chat_send_player(playername, "Provide a number to modify the base heat")
|
minetest.chat_send_player(playername, S("Provide a number to modify the base heat"))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if param == "auto" then param = 0 end
|
if param == "auto" then param = 0 end
|
||||||
climate_mod.settings.heat = tonumber(param)
|
climate_mod.settings.heat = tonumber(param) or 0
|
||||||
minetest.chat_send_player(playername, "Base heat changed")
|
minetest.chat_send_player(playername, S("Base heat changed"))
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
-- override global heat levels with given value
|
-- override global heat levels with given value
|
||||||
minetest.register_chatcommand("set_heat", {
|
minetest.register_chatcommand("set_heat", {
|
||||||
params = "<heat>",
|
params = S("<heat>"),
|
||||||
description = "Override the weather algorithm's base heat",
|
description = S("Override the weather algorithm's heat"),
|
||||||
privs = { weather = true },
|
privs = { weather = true },
|
||||||
func = function(playername, param)
|
func = function(playername, param)
|
||||||
if param == nil or param == "" then
|
if param == nil or param == "" then
|
||||||
minetest.chat_send_player(playername, "Provide a number to modify the base heat")
|
minetest.chat_send_player(playername, S("Provide a number to modify the heat"))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if param == "auto" then
|
if param == "auto" then
|
||||||
climate_mod.forced_enviroment.heat = nil
|
climate_mod.forced_enviroment.heat = nil
|
||||||
minetest.chat_send_player(playername, "Heat value reset")
|
minetest.chat_send_player(playername, S("Heat value reset"))
|
||||||
else
|
else
|
||||||
climate_mod.forced_enviroment.heat = tonumber(param)
|
climate_mod.forced_enviroment.heat = tonumber(param) or 0
|
||||||
minetest.chat_send_player(playername, "Heat value changed")
|
minetest.chat_send_player(playername, S("Heat value changed"))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
-- set base heat to increase or decrease global climate humidity
|
-- set base heat to increase or decrease global climate humidity
|
||||||
minetest.register_chatcommand("set_base_humidity", {
|
minetest.register_chatcommand("set_base_humidity", {
|
||||||
params = "<humidity>",
|
params = S("<humidity>"),
|
||||||
description = "Override the weather algorithm's base humidity",
|
description = S("Override the weather algorithm's base humidity"),
|
||||||
privs = { weather = true },
|
privs = { weather = true },
|
||||||
func = function(playername, param)
|
func = function(playername, param)
|
||||||
|
if param == "auto" then param = 0 end
|
||||||
if param == nil or param == "" then
|
if param == nil or param == "" then
|
||||||
minetest.chat_send_player(playername, "Provide a number to modify the base humidity")
|
minetest.chat_send_player(playername, S("Provide a number to modify the base humidity"))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if param == "auto" then param = 0 end
|
climate_mod.settings.humidity = tonumber(param) or 0
|
||||||
climate_mod.settings.humidity = tonumber(param)
|
minetest.chat_send_player(playername, S("Base humidity changed"))
|
||||||
minetest.chat_send_player(playername, "Base humidity changed")
|
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
-- override global humidity with given value
|
-- override global humidity with given value
|
||||||
minetest.register_chatcommand("set_humidity", {
|
minetest.register_chatcommand("set_humidity", {
|
||||||
params = "<humidity>",
|
params = S("<humidity>"),
|
||||||
description = "Override the weather algorithm's base humidity",
|
description = S("Override the weather algorithm's humidity"),
|
||||||
privs = { weather = true },
|
privs = { weather = true },
|
||||||
func = function(playername, param)
|
func = function(playername, param)
|
||||||
if param == nil or param == "" then
|
if param == nil or param == "" then
|
||||||
minetest.chat_send_player(playername, "Provide a number to modify the base humidity")
|
minetest.chat_send_player(playername, S("Provide a number to modify the humidity"))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if param == "auto" then
|
if param == "auto" then
|
||||||
climate_mod.forced_enviroment.humidity = nil
|
climate_mod.forced_enviroment.humidity = nil
|
||||||
minetest.chat_send_player(playername, "Humidity value reset")
|
minetest.chat_send_player(playername, S("Humidity value reset"))
|
||||||
else
|
else
|
||||||
climate_mod.forced_enviroment.humidity = tonumber(param)
|
climate_mod.forced_enviroment.humidity = tonumber(param) or 0
|
||||||
minetest.chat_send_player(playername, "Humidity value changed")
|
minetest.chat_send_player(playername, S("Humidity value changed"))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
-- override wind direction and speed with given values
|
-- override wind direction and speed with given values
|
||||||
minetest.register_chatcommand("set_wind", {
|
minetest.register_chatcommand("set_wind", {
|
||||||
params = "<wind>",
|
params = S("<wind>"),
|
||||||
description = "Override the weather algorithm's windspeed",
|
description = S("Override the weather algorithm's windspeed"),
|
||||||
privs = { weather = true },
|
privs = { weather = true },
|
||||||
func = function(playername, param)
|
func = function(playername, param)
|
||||||
if param == nil or param == "" then
|
if param == nil or param == "" then
|
||||||
minetest.chat_send_player(playername, "Provide a number to modify the base humidity")
|
minetest.chat_send_player(playername, S("Provide a vector of two numbers to modify the wind"))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local arguments = {}
|
local arguments = {}
|
||||||
for w in param:gmatch("%S+") do table.insert(arguments, w) end
|
for w in param:gmatch("%S+") do table.insert(arguments, w) end
|
||||||
local wind_x = arguments[1]
|
local arg1 = arguments[1]
|
||||||
local wind_z = arguments[2]
|
local wind_x = tonumber(arguments[1])
|
||||||
if wind_x == "auto" then
|
local wind_z = tonumber(arguments[2])
|
||||||
|
if arg1 == "auto" then
|
||||||
climate_mod.forced_enviroment.wind = nil
|
climate_mod.forced_enviroment.wind = nil
|
||||||
|
minetest.chat_send_player(playername, S("Wind reset"))
|
||||||
elseif wind_x == nil or wind_z == nil then
|
elseif wind_x == nil or wind_z == nil then
|
||||||
minetest.chat_send_player(playername, "Invalid wind configuration")
|
minetest.chat_send_player(playername, S("Invalid wind configuration"))
|
||||||
else
|
else
|
||||||
climate_mod.forced_enviroment.wind = vector.new({
|
climate_mod.forced_enviroment.wind = vector.new({
|
||||||
x = tonumber(wind_x),
|
x = wind_x,
|
||||||
y = 0,
|
y = 0,
|
||||||
z = tonumber(wind_z)
|
z = wind_z
|
||||||
})
|
})
|
||||||
|
minetest.chat_send_player(playername, S("Wind changed"))
|
||||||
end
|
end
|
||||||
minetest.chat_send_player(playername, "Wind changed")
|
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
-- display current mod config
|
-- display current mod config
|
||||||
minetest.register_chatcommand("weather_settings", {
|
minetest.register_chatcommand("weather_settings", {
|
||||||
description = "Print the active Climate API configuration",
|
description = S("Print the active Climate API configuration"),
|
||||||
func = function(playername)
|
func = function(playername)
|
||||||
minetest.chat_send_player(playername, "Current Settings\n================")
|
minetest.chat_send_player(playername, S("Current Settings") .. "\n================")
|
||||||
for setting, value in pairs(climate_mod.settings) do
|
for setting, value in pairs(climate_mod.settings) do
|
||||||
minetest.chat_send_player(playername, dump2(value, setting))
|
minetest.chat_send_player(playername, dump2(value, setting))
|
||||||
end
|
end
|
||||||
|
@ -168,15 +171,15 @@ minetest.register_chatcommand("weather_settings", {
|
||||||
|
|
||||||
-- force a weather preset or disable it
|
-- force a weather preset or disable it
|
||||||
minetest.register_chatcommand("set_weather", {
|
minetest.register_chatcommand("set_weather", {
|
||||||
params ="<weather> <status>",
|
params = S("<weather> <status>"),
|
||||||
description ="Turn the specified weather preset on or off for all players or reset it to automatic",
|
description = S("Turn the specified weather preset on or off for all players or reset it to automatic"),
|
||||||
privs = { weather = true },
|
privs = { weather = true },
|
||||||
func = function(playername, param)
|
func = function(playername, param)
|
||||||
local arguments = {}
|
local arguments = {}
|
||||||
for w in param:gmatch("%S+") do table.insert(arguments, w) end
|
for w in param:gmatch("%S+") do table.insert(arguments, w) end
|
||||||
local weather = arguments[1]
|
local weather = arguments[1]
|
||||||
if weather == nil or climate_mod.weathers[weather] == nil then
|
if weather == nil or climate_mod.weathers[weather] == nil then
|
||||||
minetest.chat_send_player(playername, "Unknown weather preset")
|
minetest.chat_send_player(playername, S("Unknown weather preset"))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local status
|
local status
|
||||||
|
@ -190,19 +193,19 @@ minetest.register_chatcommand("set_weather", {
|
||||||
elseif arguments[2] == "auto" then
|
elseif arguments[2] == "auto" then
|
||||||
status = nil
|
status = nil
|
||||||
else
|
else
|
||||||
minetest.chat_send_player(playername, "Invalid weather status. Set the preset to either on, off or auto.")
|
minetest.chat_send_player(playername, S("Invalid weather status. Set the preset to either on, off or auto."))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
climate_mod.forced_weather[weather] = status
|
climate_mod.forced_weather[weather] = status
|
||||||
minetest.chat_send_player(playername, "Weather " .. weather .. " successfully set to " .. arguments[2])
|
minetest.chat_send_player(playername, S("Weather @1 successfully set to @2", weather, arguments[2]))
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
-- list all weather presets and whether they have been forced or disabled
|
-- list all weather presets and whether they have been forced or disabled
|
||||||
minetest.register_chatcommand("weather_status", {
|
minetest.register_chatcommand("weather_status", {
|
||||||
description = "Prints which weather presets are enforced or disabled",
|
description = S("Prints which weather presets are enforced or disabled"),
|
||||||
func = function(playername)
|
func = function(playername)
|
||||||
minetest.chat_send_player(playername, "Current activation rules:\n================")
|
minetest.chat_send_player(playername, S("Current activation rules:") .. "\n================")
|
||||||
for weather, _ in pairs(climate_mod.weathers) do
|
for weather, _ in pairs(climate_mod.weathers) do
|
||||||
local status = "auto"
|
local status = "auto"
|
||||||
if climate_mod.forced_weather[weather] == true then
|
if climate_mod.forced_weather[weather] == true then
|
||||||
|
@ -217,9 +220,9 @@ minetest.register_chatcommand("weather_status", {
|
||||||
|
|
||||||
-- show all environment influences and their values for the executing player
|
-- show all environment influences and their values for the executing player
|
||||||
minetest.register_chatcommand("weather_influences", {
|
minetest.register_chatcommand("weather_influences", {
|
||||||
description = "Prints which weather influences cause your current weather",
|
description = S("Prints which weather influences cause your current weather"),
|
||||||
func = function(playername)
|
func = function(playername)
|
||||||
minetest.chat_send_player(playername, "Current influences rules:\n================")
|
minetest.chat_send_player(playername, S("Current influences rules:") .. "\n================")
|
||||||
local player = minetest.get_player_by_name(playername)
|
local player = minetest.get_player_by_name(playername)
|
||||||
local influences = climate_mod.trigger.get_player_environment(player)
|
local influences = climate_mod.trigger.get_player_environment(player)
|
||||||
for influence, value in pairs(influences) do
|
for influence, value in pairs(influences) do
|
||||||
|
@ -227,3 +230,17 @@ minetest.register_chatcommand("weather_influences", {
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
|
-- used to debug downfall
|
||||||
|
minetest.register_chatcommand("explain_humidity", {
|
||||||
|
description = S("Explains how the humidity value got calculated"),
|
||||||
|
func = function(playername)
|
||||||
|
local base = climate_mod.settings.humidity
|
||||||
|
local biome = minetest.get_humidity((minetest.get_player_by_name(playername)):get_pos())
|
||||||
|
local random = climate_mod.state:get_float("humidity_random");
|
||||||
|
local random_base = climate_mod.state:get_float("humidity_base");
|
||||||
|
minetest.chat_send_player(playername, dump2(base, "base"))
|
||||||
|
minetest.chat_send_player(playername, dump2(biome, "biome"))
|
||||||
|
minetest.chat_send_player(playername, dump2(random, "random"))
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
|
@ -9,7 +9,7 @@ function environment.get_heat(pos)
|
||||||
local height = climate_api.utility.rangelim((-pos.y + 10) / 15, -10, 10)
|
local height = climate_api.utility.rangelim((-pos.y + 10) / 15, -10, 10)
|
||||||
local time = climate_api.utility.normalized_cycle(minetest.get_timeofday()) * 0.6 + 0.7
|
local time = climate_api.utility.normalized_cycle(minetest.get_timeofday()) * 0.6 + 0.7
|
||||||
local random = climate_mod.state:get_float("heat_random");
|
local random = climate_mod.state:get_float("heat_random");
|
||||||
return (base + biome + height) * time * random
|
return base + ((biome + height) * time * random)
|
||||||
end
|
end
|
||||||
|
|
||||||
function environment.get_humidity(pos)
|
function environment.get_humidity(pos)
|
||||||
|
@ -19,8 +19,7 @@ function environment.get_humidity(pos)
|
||||||
local base = climate_mod.settings.humidity
|
local base = climate_mod.settings.humidity
|
||||||
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");
|
return base + ((biome * 0.7 + 40 * 0.3) * random)
|
||||||
return (base + biome * 0.7 + random_base * 0.3) * random
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function environment.get_wind(pos)
|
function environment.get_wind(pos)
|
||||||
|
|
|
@ -10,7 +10,7 @@ climate_api.register_influence("humidity",
|
||||||
climate_api.environment.get_humidity
|
climate_api.environment.get_humidity
|
||||||
)
|
)
|
||||||
|
|
||||||
climate_api.register_influence("base_humidity",
|
climate_api.register_influence("biome_humidity",
|
||||||
minetest.get_humidity
|
minetest.get_humidity
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -50,14 +50,31 @@ end)
|
||||||
|
|
||||||
climate_api.register_influence("light", function(pos)
|
climate_api.register_influence("light", function(pos)
|
||||||
pos = vector.add(pos, {x = 0, y = 1, z = 0})
|
pos = vector.add(pos, {x = 0, y = 1, z = 0})
|
||||||
return minetest.env:get_node_light(pos)
|
return minetest.get_node_light(pos) or 0
|
||||||
end)
|
end)
|
||||||
|
|
||||||
climate_api.register_influence("daylight", function(pos)
|
climate_api.register_influence("daylight", function(pos)
|
||||||
pos = vector.add(pos, {x = 0, y = 1, z = 0})
|
pos = vector.add(pos, {x = 0, y = 1, z = 0})
|
||||||
return minetest.env:get_node_light(pos, 0.5)
|
return minetest.get_natural_light(pos, 0.5) or 0
|
||||||
|
end)
|
||||||
|
|
||||||
|
climate_api.register_influence("indoors", function(pos)
|
||||||
|
pos = vector.add(pos, {x = 0, y = 1, z = 0})
|
||||||
|
local daylight = minetest.get_natural_light(pos, 0.5) or 0
|
||||||
|
-- max light is 15 but allow adjacent nodes to still be outdoors
|
||||||
|
-- to reduce effect switching on and off when walking underneath single nodes
|
||||||
|
if daylight < 14 then return true end
|
||||||
|
|
||||||
|
for i = 1, climate_mod.settings.ceiling_checks do
|
||||||
|
local lpos = vector.add(pos, {x = 0, y = i, z = 0})
|
||||||
|
local node = minetest.get_node_or_nil(lpos)
|
||||||
|
if node ~= nil and node.name ~= "air" and node.name ~= "ignore" then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
end)
|
end)
|
||||||
|
|
||||||
climate_api.register_global_influence("time",
|
climate_api.register_global_influence("time",
|
||||||
minetest.get_timeofday()
|
minetest.get_timeofday
|
||||||
)
|
)
|
19
lib/main.lua
19
lib/main.lua
|
@ -1,9 +1,12 @@
|
||||||
local GSCYCLE = 0.03 * climate_mod.settings.tick_speed -- only process event loop after this amount of time
|
local GSCYCLE = 0.06 * climate_mod.settings.tick_speed -- only process event loop after this amount of time
|
||||||
local WORLD_CYCLE = 15.00 * climate_mod.settings.tick_speed -- only update global environment influences after this amount of time
|
local WORLD_CYCLE = 30.00 * climate_mod.settings.tick_speed -- only update global environment influences after this amount of time
|
||||||
|
|
||||||
local gs_timer = 0
|
local gs_timer = 0
|
||||||
local world_timer = 0
|
local world_timer = 0
|
||||||
minetest.register_globalstep(function(dtime)
|
minetest.register_globalstep(function(dtime)
|
||||||
|
local player_list = minetest.get_connected_players()
|
||||||
|
if #player_list == 0 then return end
|
||||||
|
|
||||||
gs_timer = gs_timer + dtime
|
gs_timer = gs_timer + dtime
|
||||||
world_timer = world_timer + dtime
|
world_timer = world_timer + dtime
|
||||||
|
|
||||||
|
@ -15,8 +18,18 @@ minetest.register_globalstep(function(dtime)
|
||||||
climate_mod.global_environment = climate_mod.trigger.get_global_environment()
|
climate_mod.global_environment = climate_mod.trigger.get_global_environment()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local previous_effects = table.copy(climate_mod.current_effects)
|
local previous_effects = table.copy(climate_mod.current_effects)
|
||||||
local current_effects = climate_mod.trigger.get_active_effects()
|
-- skip weather changes for offline players
|
||||||
|
for effect, data in pairs(previous_effects) do
|
||||||
|
for playername, _ in pairs(data) do
|
||||||
|
if not minetest.get_player_by_name(playername) then
|
||||||
|
previous_effects[effect][playername] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local current_effects = climate_mod.trigger.get_active_effects(player_list)
|
||||||
|
|
||||||
for name, effect in pairs(climate_mod.effects) do
|
for name, effect in pairs(climate_mod.effects) do
|
||||||
local cycle = climate_mod.cycles[name].timespan * climate_mod.settings.tick_speed
|
local cycle = climate_mod.cycles[name].timespan * climate_mod.settings.tick_speed
|
||||||
|
|
|
@ -38,13 +38,13 @@ elseif mod_pova then
|
||||||
local override = {}
|
local override = {}
|
||||||
override[effect] = (value * default) - default
|
override[effect] = (value * default) - default
|
||||||
pova.add_override(playername, id, override)
|
pova.add_override(playername, id, override)
|
||||||
pova.do_override(playername)
|
pova.do_override(player)
|
||||||
end
|
end
|
||||||
|
|
||||||
function physics.remove(id, player, effect)
|
function physics.remove(id, player, effect)
|
||||||
local playername = player:get_player_name()
|
local playername = player:get_player_name()
|
||||||
pova.del_override(playername, id)
|
pova.del_override(playername, id)
|
||||||
pova.do_override(playername)
|
pova.do_override(player)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- fallback to vanilla override as last resort
|
-- fallback to vanilla override as last resort
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
local mod_lighting_monoid = minetest.get_modpath("lighting_monoid") ~= nil
|
||||||
|
|
||||||
local default_sky = {
|
local default_sky = {
|
||||||
sky_data = {
|
sky_data = {
|
||||||
base_color = nil,
|
base_color = nil,
|
||||||
|
@ -42,6 +44,10 @@ local default_sky = {
|
||||||
count = 1000,
|
count = 1000,
|
||||||
star_color = "#ebebff69",
|
star_color = "#ebebff69",
|
||||||
scale = 1
|
scale = 1
|
||||||
|
},
|
||||||
|
light_data = {
|
||||||
|
shadow_intensity = 0.33,
|
||||||
|
saturation = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,12 +70,17 @@ end
|
||||||
|
|
||||||
local function set_skybox(playername, sky)
|
local function set_skybox(playername, sky)
|
||||||
local player = minetest.get_player_by_name(playername)
|
local player = minetest.get_player_by_name(playername)
|
||||||
if not player.get_stars then return end
|
if player == nil or not player.get_stars then return end
|
||||||
player:set_sky(sky.sky_data)
|
player:set_sky(sky.sky_data)
|
||||||
player:set_clouds(sky.cloud_data)
|
player:set_clouds(sky.cloud_data)
|
||||||
player:set_moon(sky.moon_data)
|
player:set_moon(sky.moon_data)
|
||||||
player:set_sun(sky.sun_data)
|
player:set_sun(sky.sun_data)
|
||||||
player:set_stars(sky.star_data)
|
player:set_stars(sky.star_data)
|
||||||
|
local lighting = {
|
||||||
|
shadows = { intensity = sky.light_data.shadow_intensity },
|
||||||
|
saturation = sky.light_data.saturation
|
||||||
|
}
|
||||||
|
lighting_monoid:add_change(player, lighting, "climate_api:merged_lighting")
|
||||||
end
|
end
|
||||||
|
|
||||||
function skybox.update(playername)
|
function skybox.update(playername)
|
||||||
|
@ -85,7 +96,7 @@ function skybox.update(playername)
|
||||||
if right.priority == nil then right.priority = 1 end
|
if right.priority == nil then right.priority = 1 end
|
||||||
return left.priority < right.priority
|
return left.priority < right.priority
|
||||||
end)
|
end)
|
||||||
for i=1,#numbered_layers do
|
for i = 1, #numbered_layers do
|
||||||
sky = merge_tables(sky, numbered_layers[i])
|
sky = merge_tables(sky, numbered_layers[i])
|
||||||
end
|
end
|
||||||
set_skybox(playername, sky)
|
set_skybox(playername, sky)
|
||||||
|
|
|
@ -19,7 +19,6 @@ soundloop.play = function(player, sound, fade)
|
||||||
if sounds[player] == nil then sounds[player] = {} end
|
if sounds[player] == nil then sounds[player] = {} end
|
||||||
if sounds[player][sound.name] == nil then
|
if sounds[player][sound.name] == nil then
|
||||||
step = sound.gain / fade
|
step = sound.gain / fade
|
||||||
start_gain = 0
|
|
||||||
elseif sounds[player][sound.name] ~= sound.gain then
|
elseif sounds[player][sound.name] ~= sound.gain then
|
||||||
minetest.sound_stop(sounds[player][sound.name].handle)
|
minetest.sound_stop(sounds[player][sound.name].handle)
|
||||||
start_gain = sounds[player][sound.name].gain
|
start_gain = sounds[player][sound.name].gain
|
||||||
|
|
|
@ -9,7 +9,7 @@ function trigger.get_global_environment()
|
||||||
end
|
end
|
||||||
|
|
||||||
function trigger.get_position_environment(pos)
|
function trigger.get_position_environment(pos)
|
||||||
local env = table.copy(climate_mod.global_environment)
|
local env = trigger.get_global_environment()
|
||||||
for influence, func in pairs(climate_mod.influences) do
|
for influence, func in pairs(climate_mod.influences) do
|
||||||
env[influence] = func(pos)
|
env[influence] = func(pos)
|
||||||
end
|
end
|
||||||
|
@ -18,6 +18,7 @@ end
|
||||||
|
|
||||||
function trigger.get_player_environment(player)
|
function trigger.get_player_environment(player)
|
||||||
local ppos = player:get_pos()
|
local ppos = player:get_pos()
|
||||||
|
if ppos == nil then return end
|
||||||
local env = trigger.get_position_environment(ppos)
|
local env = trigger.get_position_environment(ppos)
|
||||||
env.player = player
|
env.player = player
|
||||||
return env
|
return env
|
||||||
|
@ -26,15 +27,24 @@ end
|
||||||
function trigger.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 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 value ~= nil and goal > value
|
||||||
elseif condition:sub(1, 4) == "has_" then
|
elseif condition:sub(1, 4) == "has_" then
|
||||||
if type(value) == "nil" then return false end
|
if value == nil then return false end
|
||||||
for _, g in ipairs(goal) do
|
for _, g in ipairs(goal) do
|
||||||
if value == g then return true end
|
if value == g then return true end
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
|
elseif condition:sub(1, 4) == "not_" then
|
||||||
|
if value == nil then return true end
|
||||||
|
if type(goal) ~= "table" then
|
||||||
|
return value ~= goal
|
||||||
|
end
|
||||||
|
for _, g in ipairs(goal) do
|
||||||
|
if value == g then return false end
|
||||||
|
end
|
||||||
|
return true
|
||||||
else
|
else
|
||||||
value = env[condition]
|
value = env[condition]
|
||||||
return type(value) == "nil" or goal == value
|
return type(value) == "nil" or goal == value
|
||||||
|
@ -58,7 +68,7 @@ local function is_weather_active(player, weather, env)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_weather_effects(player, weather_config, env)
|
local function get_weather_effects(player, weather_config, env)
|
||||||
local config = {}
|
local config
|
||||||
local effects = {}
|
local effects = {}
|
||||||
if type(weather_config.effects) == "function" then
|
if type(weather_config.effects) == "function" then
|
||||||
config = weather_config.effects(env)
|
config = weather_config.effects(env)
|
||||||
|
@ -66,39 +76,41 @@ local function get_weather_effects(player, weather_config, env)
|
||||||
config = weather_config.effects
|
config = weather_config.effects
|
||||||
end
|
end
|
||||||
for effect, value in pairs(config) do
|
for effect, value in pairs(config) do
|
||||||
if type(climate_mod.effects[effect]) ~= "nil" then
|
if climate_mod.effects[effect] ~= nil then
|
||||||
effects[effect] = value
|
effects[effect] = value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return effects
|
return effects
|
||||||
end
|
end
|
||||||
|
|
||||||
function trigger.get_active_effects()
|
function trigger.get_active_effects(players)
|
||||||
local environments = {}
|
local environments = {}
|
||||||
for _, player in ipairs(minetest.get_connected_players()) do
|
|
||||||
environments[player:get_player_name()] = trigger.get_player_environment(player)
|
|
||||||
end
|
|
||||||
|
|
||||||
local effects = {}
|
local effects = {}
|
||||||
climate_mod.current_weather = {}
|
climate_mod.current_weather = {}
|
||||||
for wname, wconfig in pairs(climate_mod.weathers) do
|
|
||||||
for _, player in ipairs(minetest.get_connected_players()) do
|
for _, player in ipairs(players) do
|
||||||
local pname = player:get_player_name()
|
local pname = player:get_player_name()
|
||||||
local env = environments[pname]
|
local hp = player:get_hp()
|
||||||
if is_weather_active(player, wname, env) then
|
-- skip weather presets for dead players
|
||||||
if type(climate_mod.current_weather[pname]) == "nil" then
|
if hp ~= nil and hp > 0 then
|
||||||
climate_mod.current_weather[pname] = {}
|
local env = trigger.get_player_environment(player)
|
||||||
end
|
environments[pname] = env
|
||||||
table.insert(climate_mod.current_weather[pname], wname)
|
for wname, wconfig in pairs(climate_mod.weathers) do
|
||||||
local player_effects = get_weather_effects(player, wconfig, env)
|
if is_weather_active(player, wname, env) then
|
||||||
for effect, value in pairs(player_effects) do
|
if climate_mod.current_weather[pname] == nil then
|
||||||
if type(effects[effect]) == "nil" then
|
climate_mod.current_weather[pname] = {}
|
||||||
effects[effect] = {}
|
|
||||||
end
|
end
|
||||||
if type(effects[effect][pname]) == "nil" then
|
table.insert(climate_mod.current_weather[pname], wname)
|
||||||
effects[effect][pname] = {}
|
local player_effects = get_weather_effects(player, wconfig, env)
|
||||||
|
for effect, value in pairs(player_effects) do
|
||||||
|
if type(effects[effect]) == "nil" then
|
||||||
|
effects[effect] = {}
|
||||||
|
end
|
||||||
|
if type(effects[effect][pname]) == "nil" then
|
||||||
|
effects[effect][pname] = {}
|
||||||
|
end
|
||||||
|
effects[effect][pname][wname] = value
|
||||||
end
|
end
|
||||||
effects[effect][pname][wname] = value
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
local world = {}
|
local world = {}
|
||||||
|
local BASE_TIME = 0.2 * climate_mod.settings.time_spread
|
||||||
|
|
||||||
local WIND_SPREAD = 600
|
local WIND_SPREAD = 600
|
||||||
local WIND_SCALE = 2
|
local WIND_SCALE = 2
|
||||||
local HEAT_SPREAD = 400
|
local HEAT_SPREAD = 400
|
||||||
local HEAT_SCALE = 0.3
|
local HEAT_SCALE = 0.3
|
||||||
local HUMIDITY_SPREAD = 150
|
local HUMIDITY_SPREAD = 150
|
||||||
local HUMIDITY_SCALE = 0.5
|
local HUMIDITY_SCALE = 1
|
||||||
local HUMIDITY_BASE_SPREAD = 800
|
local HUMIDITY_TIMESCALE = 1
|
||||||
local HUMIDITY_BASE_SCALE = 40
|
|
||||||
|
|
||||||
local nobj_wind_x
|
local nobj_wind_x
|
||||||
local nobj_wind_z
|
local nobj_wind_z
|
||||||
|
@ -17,7 +17,7 @@ local nobj_humidity_base
|
||||||
|
|
||||||
local pn_wind_speed_x = {
|
local pn_wind_speed_x = {
|
||||||
offset = 0,
|
offset = 0,
|
||||||
scale = WIND_SCALE * climate_mod.settings.time_spread,
|
scale = WIND_SCALE,
|
||||||
spread = {x = WIND_SPREAD, y = WIND_SPREAD, z = WIND_SPREAD},
|
spread = {x = WIND_SPREAD, y = WIND_SPREAD, z = WIND_SPREAD},
|
||||||
seed = 31441,
|
seed = 31441,
|
||||||
octaves = 2,
|
octaves = 2,
|
||||||
|
@ -27,7 +27,7 @@ local pn_wind_speed_x = {
|
||||||
|
|
||||||
local pn_wind_speed_z = {
|
local pn_wind_speed_z = {
|
||||||
offset = 0,
|
offset = 0,
|
||||||
scale = WIND_SCALE * climate_mod.settings.time_spread,
|
scale = WIND_SCALE,
|
||||||
spread = {x = WIND_SPREAD, y = WIND_SPREAD, z = WIND_SPREAD},
|
spread = {x = WIND_SPREAD, y = WIND_SPREAD, z = WIND_SPREAD},
|
||||||
seed = 938402,
|
seed = 938402,
|
||||||
octaves = 2,
|
octaves = 2,
|
||||||
|
@ -37,9 +37,9 @@ local pn_wind_speed_z = {
|
||||||
|
|
||||||
local pn_heat = {
|
local pn_heat = {
|
||||||
offset = 1,
|
offset = 1,
|
||||||
scale = HEAT_SCALE * climate_mod.settings.time_spread,
|
scale = HEAT_SCALE,
|
||||||
spread = {x = HEAT_SPREAD, y = HEAT_SPREAD, z = HEAT_SPREAD},
|
spread = {x = HEAT_SPREAD, y = HEAT_SPREAD, z = HEAT_SPREAD},
|
||||||
seed = 24,
|
seed = 235896,
|
||||||
octaves = 2,
|
octaves = 2,
|
||||||
persist = 0.5,
|
persist = 0.5,
|
||||||
lacunarity = 2
|
lacunarity = 2
|
||||||
|
@ -47,22 +47,13 @@ local pn_heat = {
|
||||||
|
|
||||||
local pn_humidity = {
|
local pn_humidity = {
|
||||||
offset = 1,
|
offset = 1,
|
||||||
scale = HUMIDITY_SCALE * climate_mod.settings.time_spread,
|
scale = HUMIDITY_SCALE,
|
||||||
spread = {x = HUMIDITY_SPREAD, y = HUMIDITY_SPREAD, z = HUMIDITY_SPREAD},
|
spread = {x = HUMIDITY_SPREAD, y = HUMIDITY_SPREAD, z = HUMIDITY_SPREAD},
|
||||||
seed = 8374061,
|
seed = 8374061,
|
||||||
octaves = 3,
|
|
||||||
persist = 0.5,
|
|
||||||
lacunarity = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
local pn_humidity_base = {
|
|
||||||
offset = 50,
|
|
||||||
scale = HUMIDITY_BASE_SCALE * climate_mod.settings.time_spread,
|
|
||||||
spread = {x = HUMIDITY_BASE_SPREAD, y = HUMIDITY_BASE_SPREAD, z = HUMIDITY_BASE_SPREAD},
|
|
||||||
seed = 3803465,
|
|
||||||
octaves = 2,
|
octaves = 2,
|
||||||
persist = 0.5,
|
persist = 0.5,
|
||||||
lacunarity = 2
|
lacunarity = 2,
|
||||||
|
flags = "noeased"
|
||||||
}
|
}
|
||||||
|
|
||||||
local function update_wind(timer)
|
local function update_wind(timer)
|
||||||
|
@ -82,14 +73,12 @@ end
|
||||||
|
|
||||||
local function update_humidity(timer)
|
local function update_humidity(timer)
|
||||||
nobj_humidity = nobj_humidity or minetest.get_perlin(pn_humidity)
|
nobj_humidity = nobj_humidity or minetest.get_perlin(pn_humidity)
|
||||||
local n_humidity = nobj_humidity:get_2d({x = timer, y = 0})
|
local n_humidity = nobj_humidity:get_2d({x = timer * HUMIDITY_TIMESCALE, y = 0})
|
||||||
climate_mod.state:set_float("humidity_random", n_humidity)
|
climate_mod.state:set_float("humidity_random", n_humidity)
|
||||||
nobj_humidity_base = nobj_humidity_base or minetest.get_perlin(pn_humidity_base)
|
|
||||||
local n_humidity_base = nobj_humidity_base:get_2d({x = timer, y = 0})
|
|
||||||
climate_mod.state:set_float("humidity_base", n_humidity_base)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function world.update_status(timer)
|
function world.update_status(timer)
|
||||||
|
timer = math.floor(timer * BASE_TIME)
|
||||||
update_wind(timer)
|
update_wind(timer)
|
||||||
update_heat(timer)
|
update_heat(timer)
|
||||||
update_humidity(timer)
|
update_humidity(timer)
|
||||||
|
|
44
locale/climate_api.de.tr
Normal file
44
locale/climate_api.de.tr
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# textdomain: climate_api
|
||||||
|
Make changes to the current weather=Ändere das aktuelle Wetter
|
||||||
|
Display weather information=Betrachte Informationen zum Wetter
|
||||||
|
The following weather presets are active for you:=Die folgenden Wetterklassen sind gerade aktiv
|
||||||
|
Your sky is clear. No weather presets are currently active.=Der Himmel ist klar. Es sind keine Wetterklassen aktiv.
|
||||||
|
As a result, the following environment effects are applied:=Deshalb werden die folgenden Umwelt-Effekte dargestellt:
|
||||||
|
scorching=stechend heiße
|
||||||
|
pleasant=angenehme
|
||||||
|
chilly=kühle
|
||||||
|
It is a @1 @2 right now and humidity is at @3%.=Es sind gerade @1 @2 und die Luftfeuchtigkeit liegt bei @3%.
|
||||||
|
<heat>=
|
||||||
|
Override the weather algorithm's base heat=Überschreibe die Standard-Temperatur
|
||||||
|
Provide a number to modify the base heat=Gebe eine Zahl an, um die Standard-Temperatur anzupassen
|
||||||
|
Base heat changed=Die Standard-Temperatur wurde geändert
|
||||||
|
Override the weather algorithm's heat=Überschreibe die tatsächliche Temperatur
|
||||||
|
Provide a number to modify the heat=Gebe eine Zahl an, um die Temperatur anzupassen
|
||||||
|
Heat value reset=Die Temperatur wurde zurückgesetzt
|
||||||
|
Heat value changed=Die Temperatur wurde geändert
|
||||||
|
<humidity>=
|
||||||
|
Override the weather algorithm's base humidity=Überschreibe die Standard-Luftfeuchtigkeit
|
||||||
|
Provide a number to modify the base humidity=Gebe eine Zahl an, um die Standard-Temperatur anzupassen
|
||||||
|
Base humidity changed=Die Standard-Luftfeuchtigkeit wurde geändert
|
||||||
|
Override the weather algorithm's humidity=Überschreibe die tatsächliche Luftfeuchtigkeit
|
||||||
|
Provide a number to modify the humidity=Gebe eine Zahl an, um die Luftfeuchtigkeit anzupassen
|
||||||
|
Humidity value reset=Die Luftfeuchtigkeit wurde zurückgesetzt
|
||||||
|
Humidity value changed=Die Luftfeuchtigkeit wurde geändert
|
||||||
|
<wind>=
|
||||||
|
Override the weather algorithm's windspeed=Überschreibe die Windgeschwindigkeit
|
||||||
|
Provide a vector of two numbers to modify the wind=Gebe einen Vektor aus zwei Zahlen an, um die Windgeschwindigkeit anzupassen
|
||||||
|
Wind reset=Der Wind wurde zurückgesetzt
|
||||||
|
Invalid wind configuration=Fehlerhafte Windkonfiguration
|
||||||
|
Wind changed=Der Wind wurde geändert
|
||||||
|
Print the active Climate API configuration=Betrachte die Einstellungen für Climate API
|
||||||
|
Current Settings=Aktuelle Einstellungen
|
||||||
|
<weather> <status>=
|
||||||
|
Turn the specified weather preset on or off for all players or reset it to automatic=Schalte für alle Spieler die angegebene Wetterklasse an, aus oder schalte sie auf automatisch
|
||||||
|
Unknown weather preset=Unbekannte Wetterklasse
|
||||||
|
Invalid weather status. Set the preset to either on, off or auto.=Unbekannter Status. Setze die Wetterklasse entweder auf on, off oder auto
|
||||||
|
Weather @1 successfully set to @2=Wetter @1 wurde erfolgreich auf @2 gesetzt
|
||||||
|
Prints which weather presets are enforced or disabled=Betrachte, welche Wetterklassen erzwungen oder deaktiviert sind
|
||||||
|
Current activation rules:=Aktuelle Aktivierungsregeln
|
||||||
|
Prints which weather influences cause your current weather=Betrachte, welche Umwelteinflüsse das aktuelle Wetter hervorrufen
|
||||||
|
Current influences rules:=Aktuelle Einflussfaktoren
|
||||||
|
Explains how the humidity value got calculated=
|
44
locale/climate_api.eo.tr
Normal file
44
locale/climate_api.eo.tr
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# textdomain: climate_api
|
||||||
|
Make changes to the current weather=Ŝanĝi la nunan veteron
|
||||||
|
Display weather information=Montri veterajn informojn
|
||||||
|
The following weather presets are active for you:=La jenaj veteragordoj estas ŝaltitaj por vi:
|
||||||
|
Your sky is clear. No weather presets are currently active.=La suno brilas. Neniu veteragordo estas ŝaltita.
|
||||||
|
As a result, the following environment effects are applied:=Pro tio, la jenaj efikoj estas aktivaj:
|
||||||
|
scorching=Varmas
|
||||||
|
pleasant=Komfortas
|
||||||
|
chilly=Malvarmas
|
||||||
|
It is a @1 @2 right now and humidity is at @3%.=@1 je @2 ĝuste nun, kun aermalsekeco je @3 gradoj.
|
||||||
|
<heat>=<varm>
|
||||||
|
Override the weather algorithm's base heat=Anstataŭigi la bazan varmecon de la vetera algoritmo
|
||||||
|
Provide a number to modify the base heat=Doni nombron anstataŭiguntan la bazan varmecon
|
||||||
|
Base heat changed=Baza varmeco ŝanĝita
|
||||||
|
Override the weather algorithm's heat=Anstataŭigi la varmecon de la vetera algoritmo
|
||||||
|
Provide a number to modify the heat=Doni nombron anstataŭiguntan la varmecon
|
||||||
|
Heat value reset=Varmeco malagordita
|
||||||
|
Heat value changed=Varmeco ŝanĝita
|
||||||
|
<humidity>=<aermalsek>
|
||||||
|
Override the weather algorithm's base humidity=Anstataŭigi la bazan aermalsekecon de la vetera algoritmo
|
||||||
|
Provide a number to modify the base humidity=Doni nombron anstataŭiguntan la bazan aermalsekecon
|
||||||
|
Base humidity changed=Baza aermalsekeco ŝanĝita
|
||||||
|
Override the weather algorithm's humidity=Anstataŭigi la aermalsekecon de la vetera algoritmo
|
||||||
|
Provide a number to modify the humidity=Doni nombron anstataŭiguntan la aermalsekecon
|
||||||
|
Humidity value reset=Aermalsekeco malagordita
|
||||||
|
Humidity value changed=Aermalsekeca ŝanĝita
|
||||||
|
<wind>=<vent>
|
||||||
|
Override the weather algorithm's windspeed=Anstataŭigi la ventforton de la vetera algoritmo
|
||||||
|
Provide a vector of two numbers to modify the wind=Doni nombroparon anstataŭiguntan la ventoforton
|
||||||
|
Wind reset=Ventoforto malagordita
|
||||||
|
Invalid wind configuration=Nevalida ventagordo
|
||||||
|
Wind changed=Vento ŝanĝita
|
||||||
|
Print the active Climate API configuration=Presi la nunan agordon por Climate API
|
||||||
|
Current Settings=Nunaj Agordoj
|
||||||
|
<weather> <status>=<veter> <ŝaltec>
|
||||||
|
Turn the specified weather preset on or off for all players or reset it to automatic=Agordi veteragordon por ĉiuj ludantoj: «on» (ŝalti), «off» (malŝalti), «reset» (malfari)
|
||||||
|
Unknown weather preset=Nekonata veteragordo
|
||||||
|
Invalid weather status. Set the preset to either on, off or auto.=Nevalida veterostato. Agordu la veteragordon al «on» (ŝalti), «off» (malŝalti), aŭ «auto» (memagi).
|
||||||
|
Weather @1 successfully set to @2=Vetero @1 sukcese agordita al @2
|
||||||
|
Prints which weather presets are enforced or disabled=Listigas veterstatojn laŭ ŝaltiteco
|
||||||
|
Current activation rules:=Nunaj aktivigaj reguloj:
|
||||||
|
Prints which weather influences cause your current weather=Presas la influojn kiuj venigis la nunan veteron
|
||||||
|
Current influences rules:=Nunaj influaj reguloj:
|
||||||
|
Explains how the humidity value got calculated=Klarigas kiel la aermalseka valoro kalkuliĝis
|
44
locale/template.txt
Normal file
44
locale/template.txt
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# textdomain: climate_api
|
||||||
|
Make changes to the current weather=
|
||||||
|
Display weather information=
|
||||||
|
The following weather presets are active for you:=
|
||||||
|
Your sky is clear. No weather presets are currently active.=
|
||||||
|
As a result, the following environment effects are applied:=
|
||||||
|
scorching=
|
||||||
|
pleasant=
|
||||||
|
chilly=
|
||||||
|
It is a @1 @2 right now and humidity is at @3%.=
|
||||||
|
<heat>=
|
||||||
|
Override the weather algorithm's base heat=
|
||||||
|
Provide a number to modify the base heat=
|
||||||
|
Base heat changed=
|
||||||
|
Override the weather algorithm's heat=
|
||||||
|
Provide a number to modify the heat=
|
||||||
|
Heat value reset=
|
||||||
|
Heat value changed=
|
||||||
|
<humidity>=
|
||||||
|
Override the weather algorithm's base humidity=
|
||||||
|
Provide a number to modify the base humidity=
|
||||||
|
Base humidity changed=
|
||||||
|
Override the weather algorithm's humidity=
|
||||||
|
Provide a number to modify the humidity=
|
||||||
|
Humidity value reset=
|
||||||
|
Humidity value changed=
|
||||||
|
<wind>=
|
||||||
|
Override the weather algorithm's windspeed=
|
||||||
|
Provide a vector of two numbers to modify the wind=
|
||||||
|
Wind reset=
|
||||||
|
Invalid wind configuration=
|
||||||
|
Wind changed=
|
||||||
|
Print the active Climate API configuration=
|
||||||
|
Current Settings=
|
||||||
|
<weather> <status>=
|
||||||
|
Turn the specified weather preset on or off for all players or reset it to automatic=
|
||||||
|
Unknown weather preset=
|
||||||
|
Invalid weather status. Set the preset to either on, off or auto.=
|
||||||
|
Weather @1 successfully set to @2=
|
||||||
|
Prints which weather presets are enforced or disabled=
|
||||||
|
Current activation rules:=
|
||||||
|
Prints which weather influences cause your current weather=
|
||||||
|
Current influences rules:=
|
||||||
|
Explains how the humidity value got calculated=
|
4
mod.conf
4
mod.conf
|
@ -1,8 +1,8 @@
|
||||||
name = climate_api
|
name = climate_api
|
||||||
title = Climate API
|
title = Climate API
|
||||||
author = TestificateMods
|
author = TestificateMods
|
||||||
release = 10000
|
depends = lighting_monoid
|
||||||
optional_depends = player_monoids, playerphysics, pova
|
optional_depends = player_monoids, playerphysics, pova, weather
|
||||||
description = """
|
description = """
|
||||||
A powerful engine for weather presets and visual effects.
|
A powerful engine for weather presets and visual effects.
|
||||||
Use the regional climate to set up different effects for different regions.
|
Use the regional climate to set up different effects for different regions.
|
||||||
|
|
|
@ -19,6 +19,10 @@ climate_api_block_updates (Dynamically modify nodes) bool true
|
||||||
# Only applied if climate_api_damage is also set to true.
|
# Only applied if climate_api_damage is also set to true.
|
||||||
climate_api_raycast (Include wind speed in damage checks) bool true
|
climate_api_raycast (Include wind speed in damage checks) bool true
|
||||||
|
|
||||||
|
# Increase this number if you notice snow or rain inside large glass domes.
|
||||||
|
# Decrease this number if you notice lag spikes or overall reduced game performance.
|
||||||
|
ceiling_checks (Check x nodes on outdoor test) int 10 0 50
|
||||||
|
|
||||||
|
|
||||||
[Weather Effects]
|
[Weather Effects]
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue