minetest-skygen/init.lua

251 lines
9.6 KiB
Lua

-- Dont forget to set cloud radius to 26 in minetest's settings
skygen = {}
skygen.start = 1
skygen.save_timer = 0
skygen.save_interval = 1000
skygen.sky_state = {}
skygen.active = true
skygen.event = "none"
skygen.scale_sun_moon = "true"
skygen.events = {"test"} -- Add event names here
skygen.skybox_names = {"test_sky"} -- Add skybox names here
skygen.skyboxes = {}
skygen.event_data = {}
skygen.save_file = minetest.get_worldpath() .. "/skygen"
skygen.event_save_file = minetest.get_worldpath() .. "/skygen_event"
skygen.colorize_stars = true
skygen.default_star_params = {
visible = "true",
count = 1000,
star_color = "#ebebff69",
scale = 1,
}
local path = minetest.get_modpath("skygen")
local skybox_path = minetest.get_modpath("skygen") .. "/skyboxes"
dofile(path.."/colors.lua")
dofile(path.."/biome.lua")
dofile(path.."/skybox.lua")
dofile(path.."/events.lua")
for i=1,#skygen.skybox_names do
dofile(skybox_path .. "/" .. skygen.skybox_names[i] .. "/skydef.lua")
end
function skygen.load_saves()
local event_input = io.open(skygen.event_save_file, "r")
if not event_input then
return
else
skygen.event = event_input:read("*a")
end
event_input:close()
local input = io.open(skygen.save_file, "r")
if not input then
return
end
-- Iterate over all recorded states in the format "player state skybox" for each line
for name, state, skybox in input:read("*a"):gmatch("([%w_-]+)%s([%w_-]+)%s([%w_-]+)[\r\n]") do
if state == "skybox" then
state = "skybox_reset"
elseif state == "inactive" then
state = "inactive_reset"
end
skygen.sky_state[name] = state
skygen.skybox_status[name] = skybox
end
input:close()
end
function skygen.save()
local data = {}
local output = io.open(skygen.save_file, "w")
if output then
local s = ""
for i, v in pairs(skygen.sky_state) do
s = skygen.skybox_status[i]
if not s then
s = "none"
end
table.insert(data, string.format("%s %s %s\n", i, v, s))
end
output:write(table.concat(data))
io.close(output)
return true
end
return true
end
function skygen.event_save()
local data = {}
local output = io.open(skygen.event_save_file, "w")
if output then
output:write(skygen.event)
io.close(output)
return true
end
return true
end
skygen.load_saves()
minetest.register_on_shutdown(function()
skygen.save()
skygen.event_save()
end)
minetest.register_on_leaveplayer(function(player)
if skygen.sky_state[player:get_player_name()] == "skybox" then
skygen.sky_state[player:get_player_name()] = "skybox_reset"
elseif skygen.sky_state[player:get_player_name()] == "inactive" then
skygen.sky_state[player:get_player_name()] = "inactive_reset"
end
end)
skygen.sky_globalstep = function(players)
for i=1, #players do
local player = players[i]
local player_name = player:get_player_name()
if (skygen.sky_state[player_name] == "skybox_reset") then -- Player has reconnected in the meantime and the skybox has to be set anew
skygen.set_skybox(player, skygen.skybox_status[player:get_player_name()])
elseif (skygen.sky_state[player_name] == "inactive_reset") then
skygen.deactivate(player_name)
elseif (skygen.sky_state[player_name] == "skybox") or (skygen.sky_state[player_name] == "inactive") then
else
local biome_data = skygen.fetch_biome(player)
local biome_name = biome_data[1]
local previous_biome_name = skygen.previous_biome[player_name]
if (skygen.sky_state[player_name] == nil) then
skygen.sky_state[player_name] = "biome"
end
if skygen.sky_state[player_name] == "transition" then
elseif biome_name == previous_biome_name then
skygen.set_clouds(player, biome_name) -- Cause minetest resets them every now and then
elseif previous_biome_name == nil then
skygen.previous_biome[player_name] = biome_name
skygen.set_sky(player, biome_name)
skygen.set_all(player, biome_name)
else
--minetest.chat_send_player(player_name, "Change Init: " .. previous_biome_name .. " to " .. biome_name) -- Debug
skygen.set_sky(player, biome_name)
skygen.init_transition(player, previous_biome_name, biome_name)
end
end
end
end
minetest.register_globalstep(function()
local players = minetest.get_connected_players()
if skygen.start == 1 then -- Build the virtual table
skygen.start = 0
for i=1, #skygen.biome_names do
local biome_name = skygen.biome_names[i]
local biome_colors = skygen.biomes[biome_name].colors
biome_colors[5] = skygen.colorize(biome_colors[2], biome_colors[3], 0.75) -- Dawn
biome_colors[6] = skygen.colorize(biome_colors[1], biome_colors[3], 0.75) -- Dawn Horizon
biome_colors[7] = skygen.colorize(biome_colors[1], biome_colors[4], 0.75) -- Night
biome_colors[8] = skygen.colorize(biome_colors[2], biome_colors[4], 0.75) -- Night Horizon
end
if skygen.event == "none" then
skygen.sky_globalstep(players)
else
for i=1,#skygen.events do
if skygen.event == skygen.events[i] then
for i=1, #skygen.biome_names do
local biome_name = skygen.biome_names[i]
local biome_colors = skygen.biomes[biome_name].colors
local event_biome_colors = {}
event_biome_colors[1] = skygen.colorize(biome_colors[1], skygen.event_data[skygen.event].color, 0.75) -- Day
event_biome_colors[2] = skygen.colorize(biome_colors[2], skygen.event_data[skygen.event].color, 0.75) -- Day Horizon
event_biome_colors[3] = skygen.colorize(biome_colors[3], skygen.event_data[skygen.event].color_sun, 0.75) -- Sun
event_biome_colors[4] = skygen.colorize(biome_colors[4], skygen.event_data[skygen.event].color_moon, 0.75) -- Moon
event_biome_colors[5] = skygen.colorize(biome_colors[5], skygen.event_data[skygen.event].color_sun, 0.75) -- Dawn
event_biome_colors[6] = skygen.colorize(biome_colors[6], skygen.event_data[skygen.event].color_sun, 0.75) -- Dawn Horizon
event_biome_colors[7] = skygen.colorize(biome_colors[7], skygen.event_data[skygen.event].color_night, 0.75) -- Night
event_biome_colors[8] = skygen.colorize(biome_colors[8], skygen.event_data[skygen.event].color_night, 0.75) -- Night Horizon
skygen.biomes[biome_name].event_colors = event_biome_colors
end
end
end
skygen.sky_globalstep(players)
end
else
skygen.sky_globalstep(players)
if (skygen.save_timer > skygen.save_interval) then
skygen.save()
skygen.event_save()
skygen.save_timer = 0
else
skygen.save_timer = skygen.save_timer + 1
end
end
end)
skygen.deactivate = function(player)
skygen.sky_state[player] = "inactive"
local player_obj = minetest.get_player_by_name(player)
player_obj:set_sky()
player_obj:set_sun()
player_obj:set_stars(skygen.default_star_params)
player_obj:set_moon()
player_obj:set_clouds()
player_obj:override_day_night_ratio(nil)
end
minetest.register_chatcommand("skygen", {
params = "<state> <skybox>",
description = "SkyGen settings; \"off\" to disable; \"biome\" for default; \"skybox skybox_name\" for skybox mode",
func = function(name, param)
local parameters = {}
local p = 1
for iterator in param:gmatch("%g+") do
parameters[p] = iterator
p = p + 1
end
if parameters[1] == "off" then
skygen.deactivate(name)
minetest.chat_send_player(name, "The sky is now set to be Minetest default")
elseif parameters[1] == "biome" then
skygen.biome_mode(name)
minetest.chat_send_player(name, "The sky is now set to be biome-adaptive")
elseif parameters[1] == "skybox" then
for i=1, #skygen.skybox_names do
if skygen.skybox_names[i] == parameters[2] then
local sky_description = skygen.skyboxes[parameters[2]].description
skygen.set_skybox(minetest.get_player_by_name(name), parameters[2])
minetest.chat_send_player(name, "The sky is now set to be a skybox, " .. sky_description)
end
end
end
end
})
minetest.register_chatcommand("skygen_event", {
params = "<event_name>",
description = "Initiate an event",
privs = {server=true},
func = function(name, param)
if param == "deactivate" then
if skygen.event ~= "none" then
local previous_event = skygen.event_data[skygen.event].description
minetest.chat_send_all("The " .. previous_event .. " has ended!")
skygen.event = "none"
skygen.start = 1
end
else
for i=1,#skygen.events do
if skygen.events[i] == param then
local new_event = skygen.event_data[param].description
skygen.event = param
skygen.start = 1
minetest.chat_send_all("The " .. new_event .. " has arrived!")
end
end
end
end
})