From 17dc9a8247c35b9710741d0f23d502e7d66d37ba Mon Sep 17 00:00:00 2001 From: cheapie Date: Fri, 5 Mar 2021 00:00:01 -0600 Subject: Add initial content --- init.lua | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 init.lua (limited to 'init.lua') diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..814431e --- /dev/null +++ b/init.lua @@ -0,0 +1,176 @@ +local storage = minetest.get_mod_storage() + +playersettings = {} + +playersettings.registered = {} + +playersettings.settingslist = {} + +playersettings.highlighted = {} + +playersettings.form = "formspec_version[4]".. + "size[15,15]" .. + "button[12.5,13.5;2,1;quit;Save and Exit]".. + "textlist[0.5,0.5;7,14;settinglist;%s;%d;false]".. + "label[8,2;%s]".. + "label[8,3;%s]".. + "%s" + +function playersettings.openform(player) + if type(player) == "string" then player = minetest.get_player_by_name(player) end + local name = player:get_player_name() + if #playersettings.settingslist < 1 then + local form = "formspec_version[4]size[12,3]label[0.5,1;No settings currently exist.]label[0.5,1.5;To use the settings menu, one or more mods that provide some settings must be installed.]button_exit[5,2;2,1;quit;Close]" + minetest.show_formspec(name,"playersettings:nosettings",form) + return + end + if not playersettings.highlighted[name] then playersettings.highlighted[name] = 1 end + local settingslist = "" + for _,setting in ipairs(playersettings.settingslist) do + settingslist = settingslist..minetest.formspec_escape(playersettings.registered[setting].shortdesc).."," + end + settingslist = settingslist:sub(1,-2) + local settingname = playersettings.settingslist[playersettings.highlighted[name]] + local def = playersettings.registered[settingname] + local extras = "" + if def.type == "boolean" then + extras = "checkbox[8,8;checkbox;Enabled;%s]" + extras = extras:format(playersettings.get(name,settingname) and "true" or "false") + elseif def.type == "string" then + extras = "field[8,8;6,1;field;Enter value:;%s]label[8,9.5;Allowed values: %s]field_close_on_enter[field;false]" + extras = extras:format(minetest.formspec_escape(playersettings.get(name,settingname)),minetest.formspec_escape(def.values or "any string")) + elseif def.type == "number" then + extras = "field[8,8;6,1;field;Enter value:;%s]label[8,9.5;Allowed values: %s]field_close_on_enter[field;false]" + local allowed = "any number" + if def.min and def.max then + allowed = "numbers "..def.min.." to "..def.max + elseif def.max then + allowed = "numbers up to "..def.max + elseif def.min then + allowed = "numbers "..def.min.." and up" + end + if def.integer then + allowed = allowed.." (whole numbers only)" + end + extras = extras:format(minetest.formspec_escape(playersettings.get(name,settingname)),allowed) + elseif def.type == "enum" then + extras = "dropdown[8,8;6,1;dropdown;%s;%d;false]" + local choices = "" + local current = playersettings.get(name,settingname) + local selected = 1 + for k,v in ipairs(def.values) do + choices = choices..minetest.formspec_escape(v).."," + if v == current then selected = k end + end + choices = choices:sub(1,-2) + extras = extras:format(choices,selected) + end + local form = playersettings.form:format(settingslist,playersettings.highlighted[name],minetest.formspec_escape(def.shortdesc),minetest.formspec_escape(def.longdesc),extras) + minetest.show_formspec(name,"playersettings:settings",form) +end + +function playersettings.handleform(player,form,fields) + if form ~= "playersettings:settings" then return end + local name = player:get_player_name() + local settingname = playersettings.settingslist[playersettings.highlighted[name]] + local def = playersettings.registered[settingname] + if def.type == "boolean" and fields.checkbox then + playersettings.set(name,settingname,fields.checkbox == "true") + elseif def.type == "enum" and fields.dropdown then + playersettings.set(name,settingname,fields.dropdown) + elseif def.type == "number" and fields.field then + local value = tonumber(fields.field) + if value + and ((not def.max) or (value <= def.max)) + and ((not def.min) or (value >= def.min)) then + if def.integer then value = math.floor(value) end + playersettings.set(name,settingname,value) + end + elseif def.type == "string" and fields.field then + playersettings.set(name,settingname,fields.field) + end + if fields.settinglist then + local exp = minetest.explode_textlist_event(fields.settinglist) + if exp.type == "CHG" then + playersettings.highlighted[name] = exp.index + playersettings.openform(player) + end + end + if fields.quit then + minetest.close_formspec(name,"playersettings:settings") + end +end + +function playersettings.getdefault(setting) + local def = playersettings.registered[setting] + if def.default ~= nil then return def.default end + if def.type == "boolean" then + return false + elseif def.type == "number" then + return def.min or 0 + elseif def.type == "string" then + return "" + end +end + +function playersettings.get(name,setting) + assert(type(name) == "string",string.format("Invalid player name (expected string, got %s)",type(name))) + assert(type(setting) == "string",string.format("Invalid setting name (expected string, got %s)",type(setting))) + assert(playersettings.registered[setting],"No such setting: "..setting) + local value = minetest.deserialize(storage:get_string(string.format("%s|%s",name,setting))) + if value then + return value + else + return playersettings.getdefault(setting) + end +end + +function playersettings.set(name,setting,value) + assert(type(name) == "string",string.format("Invalid player name (expected string, got %s)",type(name))) + assert(type(setting) == "string",string.format("Invalid setting name (expected string, got %s)",type(setting))) + assert(playersettings.registered[setting],"No such setting: "..setting) + local old = playersettings.get(name,setting) + local def = playersettings.registered[setting] + if def.onchange then + if not def.onchange(name,old,value) then return end + end + storage:set_string(string.format("%s|%s",name,setting),minetest.serialize(value)) + if def.afterchange then def.afterchange(name,old,value) end +end + +function playersettings.register(setting,def) + assert(type(setting) == "string",string.format("Invalid setting name (expected string, got %s)",type(setting))) + assert(not playersettings.registered[setting],string.format("Setting %s already defined",setting)) + assert(type(def) == "table",string.format("Invalid setting definition (expected table, got %s)",type(def))) + table.insert(playersettings.settingslist,setting) + table.sort(playersettings.settingslist) + playersettings.registered[setting] = def +end + +function playersettings.onjoin(player) + local name = player:get_player_name() + for setting,def in pairs(playersettings.registered) do + if type(def.onjoin) == "function" then + def.onjoin(name,playersettings.get(name,setting)) + end + end +end + +if minetest.get_modpath("unified_inventory") then + unified_inventory.register_button("playersettings", + { + action = playersettings.openform, + tooltip = "Settings", + type = "image", + image = "playersettings_settings_button.png" + } + ) +end + +minetest.register_chatcommand("settings",{ + description = "Open player settings menu", + func = playersettings.openform, +}) + +minetest.register_on_joinplayer(playersettings.onjoin) +minetest.register_on_player_receive_fields(playersettings.handleform) -- cgit v1.2.3