172 lines
4.3 KiB
Lua
172 lines
4.3 KiB
Lua
--[[
|
|
local my_hud = futil.define_hud("my_mod:my_hud", {
|
|
period = 1,
|
|
catchup = nil, -- not currently supported
|
|
name_field = nil, -- in case you want to override the id field
|
|
enabled_by_default = nil, -- set to true to enable by default
|
|
get_hud_data = function()
|
|
-- get data that's identical for all players
|
|
-- passed to get_hud_def
|
|
end,
|
|
get_hud_def = function(player, data)
|
|
return {}
|
|
end,
|
|
})
|
|
|
|
my_hud:toggle_enabled(player)
|
|
]]
|
|
|
|
local f = string.format
|
|
|
|
local ManagedHud = futil.class1()
|
|
|
|
function ManagedHud:_init(hud_name, def)
|
|
self.name = hud_name
|
|
|
|
self._name_field = def.name_field or ((def.type or def.hud_elem_type) == "waypoint" and "text2" or "name")
|
|
self._period = def.period
|
|
self._get_hud_data = def.get_hud_data
|
|
self._get_hud_def = def.get_hud_def
|
|
self._enabled_by_default = def.enabled_by_default
|
|
|
|
self._hud_id_by_player_name = {}
|
|
|
|
self._hud_enabled_key = f("hud_manager:%s_enabled", hud_name)
|
|
self._hud_name = f("hud_manager:%s", hud_name)
|
|
end
|
|
|
|
function ManagedHud:is_enabled(player)
|
|
local meta = player:get_meta()
|
|
local value = meta:get(self._hud_enabled_key)
|
|
if value == nil then
|
|
return self._enabled_by_default
|
|
else
|
|
return minetest.is_yes(value)
|
|
end
|
|
end
|
|
|
|
function ManagedHud:set_enabled(player, value)
|
|
local meta = player:get_meta()
|
|
if minetest.is_yes(value) then
|
|
meta:set_string(self._hud_enabled_key, "y")
|
|
else
|
|
meta:set_string(self._hud_enabled_key, "n")
|
|
end
|
|
end
|
|
|
|
function ManagedHud:toggle_enabled(player)
|
|
local meta = player:get_meta()
|
|
local enabled = not self:is_enabled(player)
|
|
if enabled then
|
|
meta:set_string(self._hud_enabled_key, "y")
|
|
else
|
|
meta:set_string(self._hud_enabled_key, "n")
|
|
end
|
|
return enabled
|
|
end
|
|
|
|
function ManagedHud:update(player, data)
|
|
local is_enabled = self:is_enabled(player)
|
|
local player_name = player:get_player_name()
|
|
local hud_id = self._hud_id_by_player_name[player_name]
|
|
local old_hud_def
|
|
if hud_id then
|
|
old_hud_def = player:hud_get(hud_id)
|
|
if old_hud_def and old_hud_def[self._name_field] == self._hud_name then
|
|
if not is_enabled then
|
|
player:hud_remove(hud_id)
|
|
self._hud_id_by_player_name[player_name] = nil
|
|
return
|
|
end
|
|
else
|
|
-- hud_id is bad
|
|
hud_id = nil
|
|
old_hud_def = nil
|
|
end
|
|
end
|
|
|
|
if is_enabled then
|
|
local new_hud_def = self._get_hud_def(player, data)
|
|
if not new_hud_def then
|
|
if hud_id then
|
|
player:hud_remove(hud_id)
|
|
self._hud_id_by_player_name[player_name] = nil
|
|
end
|
|
return
|
|
elseif new_hud_def[self._name_field] and new_hud_def[self._name_field] ~= self._hud_name then
|
|
error(f("you cannot specify the value of the %q field, this is generated", self._name_field))
|
|
end
|
|
|
|
if old_hud_def then
|
|
for k, v in pairs(new_hud_def) do
|
|
if k == "position" or k == "scale" or k == "align" or k == "offset" then
|
|
v = futil.vector.v2f_to_float_32(v)
|
|
end
|
|
|
|
if not futil.equals(old_hud_def[k], v) and k ~= "type" and k ~= "hud_elem_type" then
|
|
player:hud_change(hud_id, k, v)
|
|
end
|
|
end
|
|
else
|
|
new_hud_def[self._name_field] = self._hud_name
|
|
hud_id = player:hud_add(new_hud_def)
|
|
end
|
|
end
|
|
|
|
self._hud_id_by_player_name[player_name] = hud_id
|
|
end
|
|
|
|
futil.defined_huds = {}
|
|
|
|
function futil.define_hud(hud_name, def)
|
|
if futil.defined_huds[hud_name] then
|
|
error(f("hud %s already exists", hud_name))
|
|
end
|
|
local hud = ManagedHud(hud_name, def)
|
|
futil.defined_huds[hud_name] = hud
|
|
return hud
|
|
end
|
|
|
|
-- TODO: register_hud instead of define_hud, plus alias the old
|
|
|
|
local function update_hud(hud, players)
|
|
local data
|
|
if hud._get_hud_data then
|
|
local is_any_enabled = false
|
|
for i = 1, #players do
|
|
if hud:is_enabled(players[i]) then
|
|
is_any_enabled = true
|
|
break
|
|
end
|
|
end
|
|
if is_any_enabled then
|
|
data = hud._get_hud_data()
|
|
end
|
|
end
|
|
for i = 1, #players do
|
|
hud:update(players[i], data)
|
|
end
|
|
end
|
|
|
|
-- TODO refactor to use futil.register_globalstep for each hud, to allow use of catchup mechanics
|
|
-- ... why would HUD updates need catchup mechanics?
|
|
local elapsed_by_hud_name = {}
|
|
minetest.register_globalstep(function(dtime)
|
|
local players = minetest.get_connected_players()
|
|
if #players == 0 then
|
|
return
|
|
end
|
|
for hud_name, hud in pairs(futil.defined_huds) do
|
|
if hud._period then
|
|
local elapsed = (elapsed_by_hud_name[hud_name] or 0) + dtime
|
|
if elapsed < hud._period then
|
|
elapsed_by_hud_name[hud_name] = elapsed
|
|
else
|
|
elapsed_by_hud_name[hud_name] = 0
|
|
update_hud(hud, players)
|
|
end
|
|
else
|
|
update_hud(hud, players)
|
|
end
|
|
end
|
|
end)
|