Improve classic textures, imprive Climate API compatability, store less data overall

This commit is contained in:
Till Affeldt 2020-04-24 01:38:13 +02:00
parent 46471862e9
commit 77f6c3695c
13 changed files with 195 additions and 56 deletions

View File

@ -6,9 +6,7 @@ Make sure you have the latest version installed or [update your game](https://ww
## Dependencies ## Dependencies
This mod has no hard dependencies whatsoever, so you can use it as you will. This mod has no hard dependencies whatsoever, so you can use it as you will.
However, I do recommend using the [skylayer](https://gitlab.com/rautars/skylayer) mod. If you are also using *climate_api* then it will use the included skybox registration instead of overriding the player configuration. Thus, moon_phases will will be compatible with your weather packs.
With the Minetest's new sky API it is likely for more mods to change the sky configuration,
possibly resulting in conflict. This utility mod can help circumvent these issues if both mods use it.
## Commands ## Commands
This mod comes with two commands to print or change the current moon phase. This mod comes with two commands to print or change the current moon phase.

106
ca_weathers/moon_phases.lua Normal file
View File

@ -0,0 +1,106 @@
local name = "moon_phases:phase"
local mod_climate_api = minetest.get_modpath("climate_api") ~= nil
local GSCYCLE = 0.5 -- global step cycle
local DEFAULT_LENGTH = 4 -- default cycle length
local DEFAULT_STYLE = "realistic" -- default texture style
local PHASE_COUNT = 8 -- number of phases to go through
-- retrieve mod configuration
local PHASE_LENGTH = minetest.settings:get("moon_phases_cycle") or DEFAULT_LENGTH
local TEXTURE_STYLE = minetest.settings:get("moon_phases_style") or DEFAULT_STYLE
local moon_phases = {}
local state = minetest.get_mod_storage()
local phase = 1
-- return the current moon phase
function moon_phases.get_phase()
return phase
end
-- set the current moon phase
-- @param phase int Phase between 1 and PHASE_COUNT
function moon_phases.set_phase(nphase)
phase = math.floor(tonumber(nphase))
if (not nphase) or nphase < 1 or nphase > PHASE_COUNT then
return false
end
local day = params.day_count
local date_offset = state:get_int("date_offset")
local progress = (day + date_offset - 1) % PHASE_LENGTH + 1
local phase_offset = (nphase - phase + PHASE_COUNT) % PHASE_COUNT
local add_offset = (phase_offset * PHASE_LENGTH) - progress
if add_offset == 0 then add_offset = nil end
phase = nphase
state:set_int("date_offset", add_offset)
end
-- set the moon's texture style for the given player
function moon_phases.set_style(player, style)
if style ~= "classic" and style ~= "realistic" then
return false
end
local meta_data = player:get_meta()
if style == DEFAULT_STYLE then style = nil end
meta_data:set_string("moon_phases:texture_style", style)
return true
end
-- calculate the current sky layout for a given player
local function generate_effects(params)
local override = {}
local time = params.time
local day = params.day_count
local date_offset = state:get_int("date_offset")
day = day + date_offset
if time > 0.5 then
day = day + 1
end
local meta_data = params.player:get_meta()
local style = meta_data:get_string("moon_phases:texture_style")
if style ~= "classic" and style ~= "realistic" then
style = TEXTURE_STYLE
end
phase = ((math.ceil(day / PHASE_LENGTH) - 1) % PHASE_COUNT) + 1
override["climate_api:skybox"] = {
moon_data = {
texture = "moon_" .. phase .. "_" .. style .. ".png",
scale = 0.8
}
}
return override
end
local function update_sky(player)
local params = {}
params.time = minetest.get_timeofday()
params.day_count = minetest.get_day_count()
params.player = player
local sky = generate_effects(params)
player:set_moon(sky.moon_data)
end
local timer = 0
local function handle_time_progression(dtime)
timer = timer + dtime
if timer < GSCYCLE then return end
for _, player in ipairs(minetest.get_connected_players()) do
update_sky(player)
end
timer = 0
end
if mod_climate_api then
-- register moon cycles as weather preset
climate_api.register_weather(name, {}, generate_effects)
else
-- set the moon texture of newly joined player
minetest.register_on_joinplayer(update_sky)
-- check for changes and update player skies
minetest.register_globalstep(handle_time_progression)
end

137
init.lua
View File

@ -1,96 +1,132 @@
local mod_climate_api = minetest.get_modpath("climate_api") ~= nil
local mod_skylayer = minetest.get_modpath("skylayer") ~= nil local mod_skylayer = minetest.get_modpath("skylayer") ~= nil
local modpath = minetest.get_modpath("moon_phases"); local modpath = minetest.get_modpath("moon_phases");
local GSCYCLE = 0.5 -- global step cycle local GSCYCLE = 0.5 -- global step cycle
local DEFAULT_LENGTH = 4 -- default cycle length local DEFAULT_LENGTH = 4 -- default cycle length
local DEFAULT_STYLE = "realistic" -- default texture style local DEFAULT_STYLE = "classic" -- default texture style
local PHASE_COUNT = 8 -- number of phases to go through
-- retrieve mod configuration
local PHASE_LENGTH = 4--minetest.settings:get("moon_phases_cycle") or DEFAULT_LENGTH
local TEXTURE_STYLE = minetest.settings:get("moon_phases_style") or DEFAULT_STYLE
local sky_color = {
"#1d293aff",
"#1c4b8dff",
nil,
"#579dffff",
nil,
"#1c4b8dff",
"#1d293aff",
"#000000ff"
}
local horizon_color = {
"#243347ff",
"#235fb3ff",
nil,
"#73aeffff",
nil,
"#3079dfff",
"#173154ff",
"#000000ff"
}
moon_phases = {} moon_phases = {}
local state = minetest.get_mod_storage() local state = minetest.get_mod_storage()
if not state:contains("day") then
state:from_table({fields = { -- calculate current moon phase from date
day = 1, -- and stored date offset
phase = 1, local function calculate_phase()
change_time = 1 local time = minetest.get_timeofday()
}}) local day = minetest.get_day_count() + state:get_int("date_offset")
if time > 0.5 then
day = day + 1
end
return ((math.ceil(day / PHASE_LENGTH) - 1) % PHASE_COUNT) + 1
end end
-- retrieve mod configuration local phase = 1
local PHASE_LENGTH = minetest.settings:get("moon_phases_cycle") or DEFAULT_LENGTH
local TEXTURE_STYLE = minetest.settings:get("moon_phases_style") or DEFAULT_STYLE -- return the current moon phase
function moon_phases.get_phase()
return phase
end
-- set the moon texture of a player to the given phase -- set the moon texture of a player to the given phase
local function set_texture(player, phase) local function set_texture(player, phase)
local sl = {} if not player.get_stars then return end -- check for new sky API
local meta_data = player:get_meta() local meta_data = player:get_meta()
local style = meta_data:get_string("moon_phases:texture_style") local style = meta_data:get_string("moon_phases:texture_style")
if style ~= "classic" and style ~= "realistic" then if style ~= "classic" and style ~= "realistic" then
style = TEXTURE_STYLE style = TEXTURE_STYLE
end end
local texture = "moon_" .. phase .. "_" .. style .. ".png" local texture = "moon_" .. phase .. "_" .. style .. ".png"
sl.name = "moon_phases:custom" local name = "moon_phases:cycle"
sl.moon_data = { local sky = {}
sky.sky_data = {
type = "regular",
sky_color = {
night_sky = sky_color[phase],
night_horizon = horizon_color[phase]
}
}
sky.moon_data = {
visible = true, visible = true,
texture = texture, texture = texture,
scale = 0.8 scale = 0.8
} }
if mod_skylayer then local playername = player:get_player_name()
skylayer.add_layer(player:get_player_name(), sl) if mod_climate_api then
sky.priority = 0
climate_api.skybox.add_layer(playername, name, sky)
elseif mod_skylayer then
sky.name = name
skylayer.add_layer(playername, sky)
else else
player:set_moon(sl.moon_data) player:set_sky(sky.sky_data)
end player:set_moon(sky.moon_data)
end
-- update moon textures of all online players
local function update_textures()
local phase = state:get_int("phase")
for _, player in ipairs(minetest.get_connected_players()) do
set_texture(player, phase)
end end
end end
-- check for day changes -- check for day changes
local function handle_time_progression() local function handle_time_progression()
local time = minetest.get_timeofday() local n_phase = calculate_phase()
local day = state:get_int("day") if n_phase ~= phase then
local phase = state:get_int("phase") phase = n_phase
local change_time = state:get_int("change_time") == 1 minetest.log(dump2(phase, "htp: phase"))
if time >= 0.5 and change_time then minetest.log(dump2(n_phase, "htp: n_phase"))
day = day + 1 for _, player in ipairs(minetest.get_connected_players()) do
state:set_int("day", day) set_texture(player, phase)
if day % PHASE_LENGTH == 0 then
state:set_int("phase", (phase % 8) + 1)
state:set_int("change_time", 0)
update_textures()
end end
elseif time < 0.5 and not change_time then
state:set_int("change_time", 1)
end end
end end
-- return the current moon phase
function moon_phases.get_phase()
return state:get_int("phase")
end
-- set the current moon phase -- set the current moon phase
-- @param phase int Phase between 1 and 8 -- @param phase int Phase between 1 and PHASE_COUNT
function moon_phases.set_phase(phase) function moon_phases.set_phase(nphase)
phase = math.floor(tonumber(phase)) nphase = math.floor(tonumber(nphase))
if (not phase) or phase < 1 or phase > 8 then if (not nphase) or nphase < 1 or nphase > PHASE_COUNT then
return false return false
end end
state:set_int("phase", phase) local day = minetest.get_day_count()
update_textures() local date_offset = state:get_int("date_offset")
local progress = (day + date_offset) % PHASE_LENGTH
local phase_offset = (nphase - phase + PHASE_COUNT) % PHASE_COUNT
local add_offset = ((phase_offset * PHASE_LENGTH) + date_offset - progress)
state:set_int("date_offset", add_offset)
handle_time_progression()
return true return true
end end
-- set the moon's texture style for the given player -- set the moon's texture style for the given player
function moon_phases.set_style(player, style) function moon_phases.set_style(player, style)
if style ~= "classic" and style ~= "realistic" then if style ~= nil and style ~= "classic" and style ~= "realistic" then
return false return false
end end
--if style == DEFAULT_STYLE then style = nil end
local meta_data = player:get_meta() local meta_data = player:get_meta()
meta_data:set_string("moon_phases:texture_style", style) meta_data:set_string("moon_phases:texture_style", style)
set_texture(player, state:get_int("phase")) set_texture(player, state:get_int("phase"))
@ -99,12 +135,11 @@ end
-- set the moon texture of newly joined player -- set the moon texture of newly joined player
minetest.register_on_joinplayer(function(player) minetest.register_on_joinplayer(function(player)
local phase = state:get_int("phase")
set_texture(player, phase) set_texture(player, phase)
end) end)
-- check for day changes and call handlers -- check for day changes and call handlers
local timer = 0 local timer = math.huge
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
timer = timer + dtime timer = timer + dtime
if timer < GSCYCLE then return end if timer < GSCYCLE then return end

View File

@ -10,4 +10,4 @@ square vanilla themed 16x16px textures
Requires at least Minetest 5.2.0 Requires at least Minetest 5.2.0
""" """
optional_depends = skylayer optional_depends = climate_api, skylayer

View File

@ -1,2 +1,2 @@
moon_phases_cycle (Change moon phase every X days) int 4 moon_phases_cycle (Change moon phase every X days) int 4
moon_phases_style (Choose a default texture style) enum realistic classic,realistic moon_phases_style (Choose a default texture style) enum classic classic,realistic

Binary file not shown.

Before

Width:  |  Height:  |  Size: 610 B

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 638 B

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 576 B

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 B

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 545 B

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 602 B

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 620 B

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 B

After

Width:  |  Height:  |  Size: 5.7 KiB