From 6fb0510b735c29a0b81667b0fd9211bde9277701 Mon Sep 17 00:00:00 2001 From: Xenon <36995016+xenonca@users.noreply.github.com> Date: Fri, 12 Mar 2021 17:29:46 +0100 Subject: [PATCH] Add hud_events mod (#825) * Add hud_events Reuses the HUD API provided by hud_scores * Fix luacheck --- mods/other/hud_events/README.md | 57 +++++++++++++++ mods/other/hud_events/init.lua | 125 ++++++++++++++++++++++++++++++++ mods/other/hud_events/mod.conf | 3 + 3 files changed, 185 insertions(+) create mode 100644 mods/other/hud_events/README.md create mode 100644 mods/other/hud_events/init.lua create mode 100644 mods/other/hud_events/mod.conf diff --git a/mods/other/hud_events/README.md b/mods/other/hud_events/README.md new file mode 100644 index 0000000..dae8219 --- /dev/null +++ b/mods/other/hud_events/README.md @@ -0,0 +1,57 @@ +# `hud_events` + +Forked and edited from `hud_score` by ANAND (ClobberXD), licensed under the LGPLv2.1+ license. + +`hud_events` provides an API to display HUD event elements which can be used to +display various hints and messages. + +## Methods + +- `hud_event.new(name, event_def)`: Adds a new HUD event element to player `name`. + - `name` [string]: Player name + - `event_def` [table]: HUD event element definition. See below. + +## HUD event element definition + +HUD event element definition table, passed to `hud_event.new`. + +Example definition: + +```lua +{ + name = "ctf_bandages:healing", -- Can be any arbitrary string + color = "0x00FF00", -- Should be compatible with Minetest's HUD def + value = "x has healed y", -- The actual event to be displayed + -- Field `time` is automatically added by `hud_event.new` + -- to keep track of element expiry +} +``` + +## `players` table + +This is a table of tables, indexed by player names. This table holds the HUD +data of all online players. Each sub-table is a list of HUD event elements, +which are added by `hud_event.new`. + +```lua +local players = { + ["name"] = { + [1] = , + [2] = , + [3] = + ... + }, + ["name2"] = { + ... + }, + ... +} +``` + +## Changes + +Changes that have been made compared to the original `hud_score` mod. Lines mentioned underneath refer to the lines in the `hud_events`' init.lua file. +- replaced all occurences of `score` with `event` (10th March 2021) +- changed variables and arguments in the lines 5, 6 and 36 (10th march 2021) +- edited and added arguments in line 39 and 40 (10th march 2021) +- deleted an `if` statement after line 28 (10th march 2021) diff --git a/mods/other/hud_events/init.lua b/mods/other/hud_events/init.lua new file mode 100644 index 0000000..b2fc3d8 --- /dev/null +++ b/mods/other/hud_events/init.lua @@ -0,0 +1,125 @@ +hud_event = {} +local hud = hudkit() + +local players = {} +local duration = 7 +local max = 3 +local next_check = 10000000 + +local function update(name) + local player = minetest.get_player_by_name(name) + if not player then + return + end + + -- Handle all elements marked for deletion + -- and rebuild table + local temp = {} + for _, def in ipairs(players[name]) do + if def.delete then + if hud:exists(player, def.name) then + hud:remove(player, def.name) + end + else + table.insert(temp, def) + end + end + + for i, def in ipairs(temp) do + local text = tostring(def.value) + if hud:exists(player, def.name) then + hud:change(player, def.name, "text", text) + hud:change(player, def.name, "offset", {x = 0, y = i * 20}) + else + hud:add(player, def.name, { + hud_elem_type = "text", + alignment = {x = 0, y = 0}, + position = {x = 0.5, y = 0.7}, + offset = {x = 0, y = i * 20}, + number = tonumber(def.color), + text = text, + z_index = -200 + }) + end + end + players[name] = temp +end + +function hud_event.new(name, def) + -- Verify HUD event element def + if not name or not def or type(def) ~= "table" or + not def.name or not def.value or not def.color then + error("hud_event: Invalid HUD event element definition", 2) + end + + local player = minetest.get_player_by_name(name) + if not player then + return + end + + -- Store element expiration time in def.time + -- and append event element def to players[name] + def.time = os.time() + duration + if next_check > duration then + next_check = duration + end + + -- If a HUD event element with the same name exists already, + -- reuse it instead of creating a new element + local is_new = true + for i, hud_event_spec in ipairs(players[name]) do + if hud_event_spec.name == def.name then + is_new = false + players[name][i] = def + break + end + end + + if is_new then + table.insert(players[name], def) + end + + -- If more than `max` active elements, mark oldest element for deletion + if #players[name] > max then + players[name][1].delete = true + end + + update(name) +end + +minetest.register_globalstep(function(dtime) + next_check = next_check - dtime + if next_check > 0 then + return + end + + next_check = 10000000 + + -- Loop through HUD score elements of all players + -- and remove them if they've expired + for name, hudset in pairs(players) do + local modified = false + for i, def in pairs(hudset) do + local rem = def.time - os.time() + if rem <= 0 then + def.delete = true + modified = true + elseif rem < next_check then + next_check = rem + end + end + + -- If a player's hudset was modified, update player's HUD + if modified then + update(name) + end + end +end) + +minetest.register_on_joinplayer(function(player) + players[player:get_player_name()] = {} +end) + +minetest.register_on_leaveplayer(function(player) + players[player:get_player_name()] = nil +end) diff --git a/mods/other/hud_events/mod.conf b/mods/other/hud_events/mod.conf new file mode 100644 index 0000000..e91b4e4 --- /dev/null +++ b/mods/other/hud_events/mod.conf @@ -0,0 +1,3 @@ +name = hud_events +description = API for displaying events on HUD +depends = hudkit