127 lines
3.9 KiB
Lua
127 lines
3.9 KiB
Lua
-- Copyright © 2024 Jaidyn Ann <jadedctrl@posteo.at>
|
||
--
|
||
-- This program is free software: you can redistribute it and/or
|
||
-- modify it under the terms of the GNU Lesser General Public License
|
||
-- as published by the Free Software Foundation, either version 3 of
|
||
-- the License, or (at your option) any later version.
|
||
--
|
||
-- This program is distributed in the hope that it will be useful,
|
||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
-- GNU Lesser General Public License for more details.
|
||
--
|
||
-- You should have received a copy of the GNU Lesser General Public License
|
||
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||
|
||
fs_themes = {}
|
||
fs_themes.themes = {}
|
||
|
||
local storage = minetest.get_mod_storage()
|
||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||
local S = minetest.get_translator(minetest.get_current_modname());
|
||
|
||
|
||
-- Set a player’s theme by a registered theme’s name.
|
||
-- If dont_save is provided, the player’s default theme won’t change.
|
||
function fs_themes.set_theme(player, theme_name, dont_save)
|
||
if not fs_themes.themes[theme_name] then
|
||
minetest.log("warning", string.format(S("Theme “%s” was not found."), theme_name))
|
||
return false
|
||
elseif not dont_save then
|
||
storage:set_string(player:get_player_name(), theme_name)
|
||
end
|
||
|
||
player:set_formspec_prepend(fs_themes.themes[theme_name])
|
||
return true
|
||
end
|
||
|
||
|
||
-- Register a theme, given a name and a formspec string.
|
||
function fs_themes.register_theme(name, formspec_str)
|
||
fs_themes.themes[name] = formspec_str
|
||
return true
|
||
end
|
||
|
||
|
||
minetest.register_chatcommand(
|
||
"themes",
|
||
{
|
||
description = S("Lists available GUI (Formspecs) themes."),
|
||
func = function(name, param)
|
||
local ret = nil
|
||
for name,fs in pairs(fs_themes.themes) do
|
||
if ret == nil then
|
||
ret = name
|
||
else
|
||
ret = ret .. ", " .. name
|
||
end
|
||
end
|
||
if ret == nil then
|
||
ret = S("No themes are installed!")
|
||
end
|
||
return true, ret
|
||
end
|
||
}
|
||
)
|
||
|
||
|
||
minetest.register_chatcommand(
|
||
"set_theme",
|
||
{
|
||
params = S("<theme_name>"),
|
||
description = S("Sets your theme for GUI (Formspecs) windows."),
|
||
func = function(name, param)
|
||
if fs_themes.set_theme(minetest.get_player_by_name(name), param) then
|
||
return true, S("Theme set!")
|
||
elseif param ~= "" then
|
||
return false, string.format(S("No such theme “%s”."), param)
|
||
else
|
||
return false
|
||
end
|
||
end
|
||
}
|
||
)
|
||
|
||
|
||
-- Whenever a player joins, set their formspecs theme.
|
||
minetest.register_on_joinplayer(
|
||
function(player)
|
||
local player_name = player:get_player_name()
|
||
local default_theme = minetest.settings:get("fs_default_theme")
|
||
local player_theme = storage:get_string(player_name)
|
||
|
||
-- Set the “default” theme (inherited from whatever mods load before fs_themes)
|
||
if not fs_themes.themes["default"] then
|
||
fs_themes.themes["default"] = player:get_formspec_prepend()
|
||
end
|
||
|
||
-- If a player has a preferred theme we cannot use, complain & use default.
|
||
if player_theme ~= "" and not fs_themes.set_theme(player, player_theme) then
|
||
minetest.chat_send_player(
|
||
player_name,
|
||
string.format(S("The theme “%s” no longer exists! Resetting preference."), player_theme))
|
||
player_theme = ""
|
||
storage:set_string(player_name, "")
|
||
end
|
||
|
||
if player_theme == "" and default_theme and default_theme ~= "" then
|
||
fs_themes.set_theme(player, default_theme)
|
||
end
|
||
end
|
||
)
|
||
|
||
|
||
-- Register all themes in the ./themes/ directory, one by one.
|
||
local theme_dir_path = modpath .. "/themes/"
|
||
local theme_file_paths = minetest.get_dir_list(theme_dir_path, false)
|
||
for _, file_name in pairs(theme_file_paths) do
|
||
local fs_file, open_err = io.open(theme_dir_path .. file_name, "r")
|
||
if fs_file == nil then
|
||
minetest.log("warning", string.format(S("Theme “%s” could not be opened: %s"), name, open_err))
|
||
return false
|
||
end
|
||
|
||
local fs_file_contents = fs_file:read("*all")
|
||
fs_themes.register_theme(file_name, fs_file_contents)
|
||
end
|