-- Copyright © 2024 Jaidyn Ann -- -- 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 . fs_themes = {} fs_themes.themes = {} local storage = minetest.get_mod_storage() local modpath = minetest.get_modpath(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("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 = "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 = "No themes are installed!" end return true, ret end } ) minetest.register_chatcommand( "set_theme", { params = "", description = "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, "Theme set!" elseif param ~= "" then return false, string.format("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("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("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