Add hud_events mod (#825)

* Add hud_events

Reuses the HUD API provided by hud_scores

* Fix luacheck
This commit is contained in:
Xenon 2021-03-12 17:29:46 +01:00 committed by GitHub
parent 30e9ac02fb
commit 6fb0510b73
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 185 additions and 0 deletions

View file

@ -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] = <hud_event_element>,
[2] = <hud_event_element>,
[3] = <hud_event_element>
...
},
["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)

View file

@ -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)

View file

@ -0,0 +1,3 @@
name = hud_events
description = API for displaying events on HUD
depends = hudkit