e71667a461
"0" is a valid stored value, but this also causes inv:is_empty() to return true. To check whether there is truly no value stored yet, test the size of the inventory instead.
112 lines
2.9 KiB
Lua
112 lines
2.9 KiB
Lua
--[[
|
|
|
|
Persistent player attributes
|
|
|
|
]]
|
|
|
|
-- change this to inject into other module
|
|
local M = bewarethedark
|
|
|
|
M.persistent_player_attributes = {}
|
|
local PPA = M.persistent_player_attributes
|
|
|
|
--[[
|
|
Helper functions that take care of the conversions *and* the
|
|
clamping for us
|
|
]]
|
|
|
|
local function _count_for_val(value, def)
|
|
local count = math.floor((value - def.min) / (def.max - def.min) * 65535)
|
|
if count < 0 then count = 0 end
|
|
if count > 65535 then count = 65535 end
|
|
return count
|
|
end
|
|
local function _val_for_count(count, def)
|
|
local value = count / 65535 * (def.max - def.min) + def.min
|
|
if value < def.min then value = def.min end
|
|
if value > def.max then value = def.max end
|
|
return value
|
|
end
|
|
-- end helper functions
|
|
|
|
-- the stash of registered attributes
|
|
|
|
PPA.defs = {--[[
|
|
name = {
|
|
name = "mymod_attr1",
|
|
min = 0,
|
|
max = 10,
|
|
default = 5,
|
|
},
|
|
]]}
|
|
|
|
PPA.read_cache = {--[[
|
|
player_name = {
|
|
attr1 = value1,
|
|
attr2 = value2,
|
|
},
|
|
]]}
|
|
|
|
--[[
|
|
How to register a new attribute, with named parameters:
|
|
PPA.register({ name = "mymod_attr1", min = 0, ... })
|
|
]]
|
|
|
|
PPA.register = function(def)
|
|
PPA.defs[def.name] = {
|
|
name = def.name,
|
|
min = def.min or 0.0,
|
|
max = def.max or 1.0,
|
|
default = def.default or def.min or 0.0,
|
|
}
|
|
end
|
|
|
|
-- The on_joinplayer handler
|
|
|
|
PPA.on_joinplayer = function(player)
|
|
local inv = player:get_inventory()
|
|
local player_name = player:get_player_name()
|
|
PPA.read_cache[player_name] = {}
|
|
for name, def in pairs(PPA.defs) do
|
|
if inv:get_size(name) == 0 then
|
|
inv:set_size(name, 1)
|
|
-- set default value
|
|
inv:set_stack(name, 1, ItemStack({ name = ":", count = _count_for_val(def.default, def) }))
|
|
-- cache default value
|
|
PPA.read_cache[player_name][name] = def.default
|
|
end
|
|
end
|
|
end
|
|
|
|
minetest.register_on_joinplayer(PPA.on_joinplayer)
|
|
|
|
|
|
--[[ get an attribute, procedural style:
|
|
local attr1 = PPA.get_value(player, "mymod_attr1")
|
|
]]
|
|
|
|
PPA.get_value = function(player, name)
|
|
local player_name = player:get_player_name()
|
|
if PPA.read_cache[player_name][name] == nil then
|
|
local def = PPA.defs[name]
|
|
local inv = player:get_inventory()
|
|
local count = inv:get_stack(name, 1):get_count()
|
|
PPA.read_cache[player_name][name] = _val_for_count(count, def)
|
|
end
|
|
return PPA.read_cache[player_name][name]
|
|
end
|
|
|
|
--[[ set an attribute, procedural style:
|
|
PPA.set_value(player, "mymod_attr1", attr1)
|
|
]]
|
|
|
|
PPA.set_value = function(player, name, value)
|
|
local def = PPA.defs[name]
|
|
local inv = player:get_inventory()
|
|
local player_name = player:get_player_name()
|
|
if value > def.max then value = def.max end
|
|
if value < def.min then value = def.min end
|
|
PPA.read_cache[player_name][name] = value
|
|
inv:set_stack(name, 1, ItemStack({ name = ":", count = _count_for_val(value, def) }))
|
|
end
|