From 6ffd3850df09d889f0ae57e3b974aaca2291eadb Mon Sep 17 00:00:00 2001 From: flux <25628292+fluxionary@users.noreply.github.com> Date: Wed, 9 Feb 2022 14:45:06 -0800 Subject: [PATCH] fix hud update bugs (huds which didn't disappear) --- notify.lua | 119 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 82 insertions(+), 37 deletions(-) diff --git a/notify.lua b/notify.lua index bf546bb..0c15c0e 100644 --- a/notify.lua +++ b/notify.lua @@ -1,5 +1,7 @@ local mod_name = minetest.get_current_modname() -local huds = {} +local hud_name = ("%s_feedback"):format(mod_name) + +local hud_info_by_player_name = {} local hud_timeout_seconds = 3 -- defaults @@ -14,20 +16,7 @@ local notify = {} notify.__index = notify setmetatable(notify, notify) -local function hud_remove(player, playername) - local hud = huds[playername] - if not hud then return end - if os.time() < hud_timeout_seconds + hud.time then - return - end - if player and player.hud_remove then - player:hud_remove(hud.id) - end - huds[playername] = nil -end - -local function hud_create(player, message, params) - local playername = player:get_player_name() +local function get_hud_def(message, params) local def = type(params) == "table" and params or {} def.position = def.position or position def.alignment = def.alignment or alignment @@ -37,16 +26,53 @@ local function hud_create(player, message, params) def.direction = def.direction or direction def.text = message or def.text def.hud_elem_type = def.hud_elem_type or "text" - def.name = mod_name .. "_feedback" - if player and player.hud_add then - local id = player:hud_add(def) - huds[playername] = { - id = id, - time = os.time(), - } - end + def.name = hud_name + + return def end +local function hud_create(player, player_name, message, params) + local def = get_hud_def(message, params) + + local id = player:hud_add(def) + hud_info_by_player_name[player_name] = { + id = id, + timeout = os.time() + hud_timeout_seconds, + } +end + +local function hud_update(player, player_name, hud_id, message, params) + local def = get_hud_def(message, params) + + for key, value in pairs(def) do + player:hud_change(hud_id, key, value) + end + + hud_info_by_player_name[player_name] = { + id = hud_id, + timeout = os.time() + hud_timeout_seconds, + } +end + +minetest.register_globalstep(function() + local now = os.time() + + for player_name, hud_info in pairs(hud_info_by_player_name) do + if now > hud_info.timeout then + local player = minetest.get_player_by_name(player_name) + + if player then + local hud_def = player:hud_get(hud_info.id) + if hud_def and hud_def.name == hud_name then + player:hud_remove(hud_info.id) + end + end + + hud_info_by_player_name[player_name] = nil + end + end +end) + notify.warn = function(player, message) notify(player, message, {color = warning_color }) end @@ -59,25 +85,44 @@ end notify.error = notify.err +local function is_valid_player(player) + return player + and player.get_player_name + and player.hud_get + and player.hud_add + and player.hud_change + and player.hud_remove +end + notify.__call = function(self, player, message, params) - local playername + local player_name if type(player) == "string" then - playername = player - player = minetest.get_player_by_name(playername) - elseif player and player.get_player_name then - playername = player:get_player_name() - else + player_name = player + player = minetest.get_player_by_name(player_name) + + elseif is_valid_player(player) then + player_name = player:get_player_name() + end + + if not player and player_name then return end - message = "[" .. mod_name .. "] " .. message - local hud = huds[playername] - if hud and player.hud_remove then - player:hud_remove(hud.id) + + message = ("[%s] %s"):format(mod_name, message) + + local hud_info = hud_info_by_player_name[player_name] + local hud_def + + if hud_info then + hud_def = player:hud_get(hud_info.id) + end + + if hud_def and hud_def.name == hud_name then + hud_update(player, player_name, hud_info.id, message, params) + + else + hud_create(player, player_name, message, params) end - hud_create(player, message, params) - minetest.after(hud_timeout_seconds, function() - hud_remove(player, playername) - end) end return notify