Add type annotations to vl_tuning, convert minetest->core in vl_tuning, remove last remnants of [1] value accesses, fix several issues uncoverted by type checking, rename some fields

This commit is contained in:
teknomunk 2025-01-01 07:43:18 -06:00
parent fee35e79c4
commit 427f2cf847
9 changed files with 85 additions and 50 deletions

View file

@ -3,6 +3,7 @@
"diagnostics": { "disable": ["lowercase-global"] }, "diagnostics": { "disable": ["lowercase-global"] },
"diagnostics.globals": [ "diagnostics.globals": [
"minetest", "minetest",
"core",
"dump", "dump",
"dump2", "dump2",
"Raycast", "Raycast",
@ -18,5 +19,6 @@
"AreaStore", "AreaStore",
"vector" "vector"
], ],
"workspace.library": ["/usr/share/luanti/luanti-lls-definitions/library", "/usr/share/luanti/builtin"],
"workspace.ignoreDir": [".luacheckrc"] "workspace.ignoreDir": [".luacheckrc"]
} }

View file

@ -1,8 +1,8 @@
local modname = "vl_tuning" local modname = "vl_tuning"
local modpath = minetest.get_modpath(modname) local modpath = core.get_modpath(modname)
local S = minetest.get_translator(modname) local S = core.get_translator(modname)
local F = function(f) return minetest.formspec_escape(S(f)) end local F = function(f) return core.formspec_escape(S(f)) end
local FE = minetest.formspec_escape local FE = core.formspec_escape
local mod = vl_tuning local mod = vl_tuning
local function bool_to_string(value) local function bool_to_string(value)
@ -18,12 +18,12 @@ local function formspec_for_setting(y, name)
local fs = {} local fs = {}
table.insert(fs, "label[0,"..(y+0.15)..";"..FE(name).."]") table.insert(fs, "label[0,"..(y+0.15)..";"..FE(name).."]")
table.insert(fs, "hypertext[0.15,"..(y+0.25)..";14.85,0.65;;"..FE("<style color=black>"..(setting.description or "").."</style>").."]") table.insert(fs, "hypertext[0.15,"..(y+0.25)..";14.85,0.65;;"..FE("<style color=black>"..setting.description.."</style>").."]")
if setting_type == "bool" then if setting_type == "bool" then
table.insert(fs, "checkbox[17,"..(y+0.15)..";"..FE(name)..";;"..bool_to_string(setting[1]).."]") table.insert(fs, "checkbox[17,"..(y+0.15)..";"..FE(name)..";;"..bool_to_string(setting.getter()).."]")
elseif setting_type == "number" then elseif setting_type == "number" then
table.insert(fs, "field[15,"..y..";2.5,0.75;"..FE(name)..";;"..string.format("%.4g", setting[1]).."]") table.insert(fs, "field[15,"..y..";2.5,0.75;"..FE(name)..";;"..string.format("%.4g", setting.getter()).."]")
table.insert(fs, "field_close_on_enter["..FE(name)..";false]") table.insert(fs, "field_close_on_enter["..FE(name)..";false]")
elseif setting_type == "string" then elseif setting_type == "string" then
end end
@ -66,12 +66,12 @@ function vl_tuning.show_formspec(player_name, tab)
"scrollbar[18.75,0.75;0.75,9.25;vertical;settings;0]", "scrollbar[18.75,0.75;0.75,9.25;vertical;settings;0]",
}) })
minetest.show_formspec(player_name, "vl_tuning:settings", formspec) core.show_formspec(player_name, "vl_tuning:settings", formspec)
end end
minetest.register_on_player_receive_fields(function(player, formname, fields) core.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "vl_tuning:settings" then return end if formname ~= "vl_tuning:settings" then return end
minetest.log("action",dump({ core.log("action",dump({
player = player, player = player,
fields = fields, fields = fields,
formname = formname, formname = formname,
@ -86,12 +86,11 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
if fields.quit or (not fields.tab or fields.old_tab == fields.tab) then return end if fields.quit or (not fields.tab or fields.old_tab == fields.tab) then return end
minetest.log("Seting settings formspec")
mod.show_formspec(player:get_player_name(), fields.tab) mod.show_formspec(player:get_player_name(), fields.tab)
end) end)
minetest.register_chatcommand("settings",{ core.register_chatcommand("settings",{
func = function(player_name, param) func = function(player_name, _)
dofile(modpath.."/gui.lua") dofile(modpath.."/gui.lua")
mod.show_formspec(player_name) mod.show_formspec(player_name)
end end

View file

@ -1,13 +1,14 @@
local modname = minetest.get_current_modname() local modname = core.get_current_modname()
local modpath = minetest.get_modpath(modname) local modpath = core.get_modpath(modname)
local S = minetest.get_translator(modname) local S = core.get_translator(modname)
local storage = minetest.get_mod_storage() local storage = core.get_mod_storage()
local mod = {} local mod = {}
vl_tuning = mod vl_tuning = mod
local DEBUG = false local DEBUG = false
-- All registered tunable parameters -- All registered tunable parameters
--- @type table<string, vl_tuning.Setting>
local tunables = {} local tunables = {}
vl_tuning.registered_settings = tunables vl_tuning.registered_settings = tunables
@ -30,11 +31,26 @@ local tunable_types = {
} }
-- Tunable metatable functions -- Tunable metatable functions
---@class (exact) vl_tuning.Setting
---@field name string
---@field setting_type "string"|"number"|"bool"
---@field description string
---@field default? string|integer|boolean
---@field set fun(self : vl_tuning.Setting, value, no_hook : boolean?)
---@field setter fun(value)
---@field getter fun() : string|boolean|number
---@field from_string fun(value : string)
---@field to_string fun(value : any)
---@field on_change? fun(self : vl_tuning.Setting)
---@field getter fun()
local tunable_class = {} local tunable_class = {}
---@param self vl_tuning.Setting
---@param value any
---@param no_hook? boolean
function tunable_class:set(value, no_hook) function tunable_class:set(value, no_hook)
local self_type = self.type
if type(value) == "string" then if type(value) == "string" then
local new_value = self_type.from_string(value) local new_value = self.from_string(value)
if new_value == nil then new_value = self.default end if new_value == nil then new_value = self.default end
self.setter(new_value) self.setter(new_value)
@ -43,7 +59,7 @@ function tunable_class:set(value, no_hook)
end end
if DEBUG then if DEBUG then
minetest.log("action", "[vl_tuning] Set "..self.setting.." to "..dump(self.getter())) core.log("action", "[vl_tuning] Set "..self.name.." to "..dump(self.getter()))
end end
-- Call on_change hook -- Call on_change hook
@ -53,50 +69,66 @@ function tunable_class:set(value, no_hook)
end end
-- Persist value -- Persist value
storage:set_string(self.setting,self_type.to_string(self.getter())) storage:set_string(self.name,self.to_string(self.getter()))
end end
function tunable_class:get_string() function tunable_class:get_string()
return self.type.to_string(self.getter()) return self.to_string(self.getter())
end end
function mod.setting(setting, setting_type, def ) ---@class vl_tuning.SettingDef
---@field set fun(value : any)
---@field get fun(): string|boolean|number
---@field default any
---@field description? string
---@param name string
---@param p_type? "bool"|"number"|"string"
---@param def? vl_tuning.SettingDef
---@return vl_tuning.Setting?
function mod.setting(name, p_type, def )
-- return the existing setting if it was previously registered. Don't update the definition -- return the existing setting if it was previously registered. Don't update the definition
local tunable = tunables[setting] local tunable = tunables[name]
if tunable then return tunable end if tunable then return tunable end
assert(setting_type) assert(p_type)
assert(def) assert(def)
assert(type(def.set) == "function", "Tunable requires set method") assert(type(def.set) == "function", "Tunable requires set method")
assert(type(def.get) == "function", "Tunable required get method") assert(type(def.get) == "function", "Tunable required get method")
-- Setup the tunable data -- Setup the tunable data
tunable = table.copy(def) ---@type vl_tuning.Setting
tunable.setting = setting tunable = {
tunable.setter = def.set name = name,
tunable.getter = def.get setting_type = p_type,
tunable.type = tunable_types[setting_type] description = def.description or "",
tunable.setting_type = setting_type setter = def.set,
if tunable.default then getter = def.get,
tunable.set(tunable.default) set = tunable_class.set,
get_string = tunable_class.get_string,
from_string = tunable_types[p_type].from_string,
to_string = tunable_types[p_type].to_string,
}
if def.default then
tunable:set(def.default)
end end
setmetatable(tunable, {__index=tunable_class}) setmetatable(tunable, {__index=tunable_class})
-- Load the setting value from mod storage -- Load the setting value from mod storage
local setting_value = storage:get_string(setting) local setting_value = storage:get_string(name)
if setting_value and setting_value ~= "" then if setting_value and setting_value ~= "" then
tunable:set(setting_value, true) tunable:set(setting_value, true)
if DEBUG then if DEBUG then
minetest.log("action", "[vl_tuning] Loading "..setting.." = "..dump(setting_value).." ("..dump(tunable[1])..")") core.log("action", "[vl_tuning] Loading "..name.." = "..dump(setting_value).." ("..dump(tunable.getter())..")")
end end
end end
-- Add to the list of all available settings -- Add to the list of all available settings
tunables[setting] = tunable tunables[name] = tunable
-- Provide it so that the current value in [1] can be accessed without having to call into this API again -- Provide it so that the current value can be retrieved from result.getter()
return tunable return tunable
end end
minetest.register_chatcommand("set_setting", { core.register_chatcommand("set_setting", {
description = S("Admin tool to tune settings and game rules"), description = S("Admin tool to tune settings and game rules"),
params = S("<setting> <value>"), params = S("<setting> <value>"),
privs = { debug = true }, privs = { debug = true },
@ -117,17 +149,17 @@ minetest.register_chatcommand("set_setting", {
end end
if DEBUG then if DEBUG then
minetest.log("action", "[vl_tuning] "..name.." set ".. params[1] .." to "..params[2]) core.log("action", "[vl_tuning] "..name.." set ".. params[1] .." to "..params[2])
end end
tunable:set(params[2]) tunable:set(params[2])
return true return true
end end
}) })
minetest.register_chatcommand("get_setting", { core.register_chatcommand("get_setting", {
description = S("Admin tool to view settings and game rules"), description = S("Admin tool to view settings and game rules"),
params = S("<setting>"), params = S("<setting>"),
privs = { debug = true }, privs = { debug = true },
func = function(name, param) func = function(_, param)
local tunable = tunables[param] local tunable = tunables[param]
if tunable then if tunable then
return true, tunable:get_string() return true, tunable:get_string()
@ -137,11 +169,11 @@ minetest.register_chatcommand("get_setting", {
end end
}) })
minetest.register_chatcommand("gamerule", { core.register_chatcommand("gamerule", {
description = S("Display or set customizable options"), description = S("Display or set customizable options"),
params = S("<rule> [<value>]"), params = S("<rule> [<value>]"),
privs = { server = true }, privs = { server = true },
func = function(name, params_raw) func = function(_, params_raw)
-- Split apart the params -- Split apart the params
local params = {} local params = {}
for str in string.gmatch(params_raw, "([^ ]+)") do for str in string.gmatch(params_raw, "([^ ]+)") do
@ -160,7 +192,7 @@ minetest.register_chatcommand("gamerule", {
local value = params[2] local value = params[2]
if value then if value then
if DEBUG then if DEBUG then
minetest.log("action", "[vl_tuning] Setting game rule "..params[1].." to "..params[2]) core.log("action", "[vl_tuning] Setting game rule "..params[1].." to "..params[2])
end end
tunable:set(params[2]) tunable:set(params[2])
return true return true

View file

@ -297,7 +297,7 @@ mcl_events.register_event("raid",{
health_max = 1, health_max = 1,
exclusive_to_area = 128, exclusive_to_area = 128,
enable_bossbar = true, enable_bossbar = true,
cond_start = function(self) cond_start = function(_)
if gamerule_disableRaids then return false end if gamerule_disableRaids then return false end
--minetest.log("Cond start raid") --minetest.log("Cond start raid")

View file

@ -3,7 +3,6 @@ local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname) local modpath = minetest.get_modpath(modname)
local S = minetest.get_translator(modname) local S = minetest.get_translator(modname)
local mods_loaded = false
local NIGHT_VISION_RATIO = 0.45 local NIGHT_VISION_RATIO = 0.45
local DEBUG = false local DEBUG = false

View file

@ -238,8 +238,9 @@ minetest.register_on_leaveplayer(function(player)
end) end)
local keep_inventory = vl_tuning.setting("gamerule:keepInventory") local keep_inventory = vl_tuning.setting("gamerule:keepInventory")
assert(keep_inventory)
minetest.register_on_dieplayer(function(player) minetest.register_on_dieplayer(function(player)
if not keep_inventory[1] then if not keep_inventory:getter() then
mcl_experience.throw_xp(player:get_pos(), mcl_experience.get_xp(player)) mcl_experience.throw_xp(player:get_pos(), mcl_experience.get_xp(player))
mcl_experience.set_xp(player, 0) mcl_experience.set_xp(player, 0)
end end

View file

@ -96,7 +96,7 @@ local nether_portal_survival_delay = 4
vl_tuning.setting("gamerule:playersNetherPortalDefaultDelay", "number", { vl_tuning.setting("gamerule:playersNetherPortalDefaultDelay", "number", {
default = 4, default = 4,
set = function(val) nether_portal_survival_delay = val end, set = function(val) nether_portal_survival_delay = val end,
get = function() return nether_portal_survive_delay end, get = function() return nether_portal_survival_delay end,
}) })
-- Speeds up the search by allowing some non-air nodes to be replaced when -- Speeds up the search by allowing some non-air nodes to be replaced when

View file

@ -435,9 +435,10 @@ minetest.register_globalstep(function(dtime)
end) end)
local keep_inventory = vl_tuning.setting("gamerule:keepInventory") local keep_inventory = vl_tuning.setting("gamerule:keepInventory")
assert(keep_inventory)
minetest.register_on_dieplayer(function(player) minetest.register_on_dieplayer(function(player)
remove_shield_hud(player) remove_shield_hud(player)
if not keep_inventory[1] then if not keep_inventory.getter() then
remove_shield_entity(player, 1) remove_shield_entity(player, 1)
remove_shield_entity(player, 2) remove_shield_entity(player, 2)
end end

View file

@ -736,8 +736,9 @@ end
init() init()
local keep_inventory = vl_tuning.setting("gamerule:keepInventory") local keep_inventory = vl_tuning.setting("gamerule:keepInventory")
assert(keep_inventory)
minetest.register_on_respawnplayer(function(player) minetest.register_on_respawnplayer(function(player)
if not keep_inventory[1] then if not keep_inventory.getter() then
mcl_skins.update_player_skin(player) -- ensures players have their cape again after dying with an elytra mcl_skins.update_player_skin(player) -- ensures players have their cape again after dying with an elytra
end end
end) end)