From 5a0bf16ea4fbbf298c8db33ccf163d688aa7fb07 Mon Sep 17 00:00:00 2001 From: Krock Date: Sat, 16 May 2026 09:16:40 -0500 Subject: [PATCH 2/2] Add playersettings.reset to fall back to default --- README | 7 +++++++ init.lua | 69 ++++++++++++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 59 insertions(+), 17 deletions(-) diff --git a/README b/README index 294fc18..3dc239f 100644 --- a/README +++ b/README @@ -70,6 +70,13 @@ playersettings.set(player_name,setting_name,new_value) -- 'new_value' is the new value of the setting. -- Changing settings via this interface bypasses the built-in validation (such as range checking on numbers) but NOT any specified onchange or afterchange actions. +To reset a setting: + +playersettings.reset(player_name,setting_name) +-- 'player_name' is the player to change the setting for. +-- 'setting_name' is the name of the setting to reset/clear. +-- This will cause 'playersettings.get' to fall back to the default value. + To get the value of a setting (from another mod): playersettings.get(player_name,setting_name) diff --git a/init.lua b/init.lua index 2bf67fb..86c116a 100644 --- a/init.lua +++ b/init.lua @@ -50,6 +50,8 @@ local function table_concat_escaped(list, delim) return table.concat(esc, delim) end +local setting_get_no_fallback -- (name, setting, require_existence) + function playersettings.openform(player) if type(player) == "string" then player = core.get_player_by_name(player) end local name = player:get_player_name() @@ -64,11 +66,17 @@ function playersettings.openform(player) local technical = playersettings.show_technical_names[name] for _,setting in ipairs(playersettings.settingslist) do local def = playersettings.registered[setting] + local row if technical then - table.insert(list, ("%s (%s)"):format(setting, def.type)) + row = ("%s (%s)"):format(setting, def.type) else - table.insert(list, def.shortdesc) + row = def.shortdesc + end + if (setting_get_no_fallback(name, setting, false)) ~= nil then + -- 'Value is set' indicator + row = row .. " *" end + table.insert(list, row) end settingslist = table_concat_escaped(list, ",") end @@ -155,8 +163,7 @@ function playersettings.handleform(player,form,fields) local settingname, def = get_setting_at(playersettings.highlighted[name]) if def then if fields.breset then - local value = playersettings.getdefault(settingname) - playersettings.set(name, settingname, value) + playersettings.reset(name, settingname) playersettings.openform(player) return end @@ -208,12 +215,20 @@ function playersettings.getdefault(setting) end end -function playersettings.get(name,setting) +--- Return #1: Value or `nil` if no value was found +--- Return #2: Database key +setting_get_no_fallback = function(name, setting, require_existence) CHECK_TYPE("string", name, "player name") CHECK_TYPE("string", setting, "setting name") - assert(playersettings.registered[setting],"No such setting: "..setting) + local key = ("%s|%s"):format(name, setting) + if require_existence then + assert(playersettings.registered[setting],"No such setting: "..setting) + end + return core.deserialize(storage:get_string(key)), key +end - local value = core.deserialize(storage:get_string(string.format("%s|%s",name,setting))) +function playersettings.get(name,setting) + local value = setting_get_no_fallback(name, setting, true) if value ~= nil then return value else @@ -222,13 +237,14 @@ function playersettings.get(name,setting) end function playersettings.set(name,setting,value) - CHECK_TYPE("string", name, "player name") - CHECK_TYPE("string", setting, "setting name") - assert(playersettings.registered[setting],"No such setting: "..setting) - - local old = playersettings.get(name,setting) - if old == value then - return + local old, key = setting_get_no_fallback(name, setting, true) + + -- Compare value without the .get(...) default fallback + local is_different = old ~= value + if old == nil then + local default = playersettings.getdefault(setting) + -- Allow using the default value but do not fire callbacks if they are equal + is_different = value ~= default end local def = playersettings.registered[setting] @@ -238,11 +254,30 @@ function playersettings.set(name,setting,value) return end end - if def.onchange then + if is_different and def.onchange then if not def.onchange(name,old,value) then return end end - storage:set_string(string.format("%s|%s",name,setting),core.serialize(value)) - if def.afterchange then def.afterchange(name,old,value) end + storage:set_string(key,core.serialize(value)) + if is_different and def.afterchange then + def.afterchange(name,old,value) + end +end + +function playersettings.reset(name, setting) + local old, key = setting_get_no_fallback(name, setting, false) + -- ^ 'false': Do not require 'setting' to be defined to allow removing unused settings. + + local def = playersettings.registered[setting] + local default = def and playersettings.getdefault(setting) + local is_different = def and old ~= default + + if is_different and def.onchange then + if not def.onchange(name,old,default) then return end + end + storage:set_string(key, "") + if is_different and def.afterchange then + def.afterchange(name,old,default) + end end function playersettings.register(setting,def) -- cgit v1.2.3