VoxeLibre/mods/CORE/vl_tuning/init.lua

155 lines
4 KiB
Lua

local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
local S = minetest.get_translator(modname)
local storage = minetest.get_mod_storage()
local mod = {}
vl_tuning = mod
-- All registered tunable parameters
local tunables = {}
-- Supported variable types
local tunable_types = {
bool = {
to_string = tostring,
from_string = function(value)
return (value == "true")
end
},
number = {
to_string = tostring,
from_string = tonumber,
},
string = {
to_string = function(v) return v end,
from_string = function(v) return v end,
},
}
-- Tunable metatable functions
local tunable_class = {}
function tunable_class:set(value, no_hook)
local self_type = self.type
if type(value) == "string" then
local new_value = self_type.from_string(value)
if new_value == nil then new_value = self.default end
self[1] = new_value
else
self[1] = value
end
minetest.log("action", "[vl_tuning] Set "..self.setting.." to "..dump(self[1]))
-- Call on_change hook
if not no_hook then
local hook = self.on_change
if hook then hook(self) end
end
-- Persist value
storage:set_string(self.setting,self_type.to_string(self[1]))
end
function tunable_class:get_string()
return self.type.to_string(self[1])
end
function mod.setting(setting, setting_type, def )
-- return the existing setting if it was previously registered. Don't update the definition
local tunable = tunables[setting]
if tunable then return tunable end
assert(setting_type)
assert(def)
-- Setup the tunable data
tunable = table.copy(def)
tunable.setting = setting
tunable.type = tunable_types[setting_type]
tunable[1] = tunable.default
setmetatable(tunable, {__index=tunable_class})
-- Load the setting value from mod storage
local setting_value = storage:get_string(setting)
if setting_value and setting_value ~= "" then
tunable:set(setting_value, true)
minetest.log("action", "[vl_tuning] Loading "..setting.." = "..dump(setting_value).." ("..dump(tunable[1])..")")
end
-- Add to the list of all available settings
tunables[setting] = tunable
-- Provide it so that the current value in [1] can be accessed without having to call into this API again
return tunable
end
minetest.register_chatcommand("set_setting", {
description = S("Admin tool to tune settings and game rules"),
params = S("<setting> <value>"),
privs = { debug = true },
func = function(name, params_raw)
-- Split apart the params
local params = {}
for str in string.gmatch(params_raw, "([^ ]+)") do
params[#params + 1] = str
end
if #params ~= 2 then
return false, S("Usage: /tune <setting> <value>")
end
local tunable = tunables[params[1]]
if not tunable then
return false, S("Setting @1 doesn't exist", params[1])
end
minetest.log("action", "[vl_tuning] "..name.." set ".. params[1] .." to "..params[2])
tunable:set(params[2])
return true
end
})
minetest.register_chatcommand("get_setting", {
description = S("Admin tool to view settings and game rules"),
params = S("<setting>"),
privs = { debug = true },
func = function(name, param)
local tunable = tunables[param]
if tunable then
return true, tunable:get_string()
else
return false, S("Setting @1 doesn't exist", param)
end
end
})
minetest.register_chatcommand("gamerule", {
description = S("Display or set customizable options"),
params = S("<rule> [<value>]"),
privs = { server = true },
func = function(name, params_raw)
-- Split apart the params
local params = {}
for str in string.gmatch(params_raw, "([^ ]+)") do
params[#params + 1] = str
end
if #params < 1 or #params > 2 then
return false, S("Usage: /gamerule <rule> [<value>]")
end
local tunable = tunables["gamerule:"..params[1]]
if not tunable then
return false, S("Game rule @1 doesn't exist", params[1])
end
local value = params[2]
if value then
minetest.log("action", "[vl_tuning] Setting game rule "..params[1].." to "..params[2])
tunable:set(params[2])
return true
else
return true, tunable:get_string()
end
end
})
dofile(modpath.."/settings.lua")