Aaron Suen 4d47ab2e75 NC API dependency simplification.
Treat all API mods as a "layer", and use the new
nc_api_all registration to indicate that a mod depends
on the NC API (which ALL NC mods assume they do).
This means that each non-API mod does not need to
worry about which API mods it really needs and which
it does not, nor will they need to be updated for any
internal API restructures.

This is a game, not a modpack, so all mods will be
loaded anyway, and we only care about order.  That
means that we don't really need to worry about
having excess dependencies because any mod we
don't actually need will be needed by something that's
loaded anyway.  If somebody wants to reuse a
component elsewhere, they're likely to need to do
some work to untangle it anyway, because of the
amount that NodeCore mechanics interact and
interdepend.
2020-01-05 12:59:12 -05:00

147 lines
3.3 KiB
Lua

-- LUALOCALS < ---------------------------------------------------------
local error, minetest, nodecore, pairs, string, type
= error, minetest, nodecore, pairs, string, type
local string_gmatch, string_rep
= string.gmatch, string.rep
-- LUALOCALS > ---------------------------------------------------------
nodecore.amcoremod()
local huds = {}
local myprops = {
label = true,
ttl = true,
quick = true
}
local function copytbl(t)
local u = {}
for k, v in pairs(t) do u[k] = type(v) == "table" and copytbl(v) or v end
return u
end
local function differ(a, b)
if type(a) == "table" and type(b) == "table" then
for k, v in pairs(a) do
if differ(b[k], v) then return true end
end
for k, v in pairs(b) do
if differ(a[k], v) then return true end
end
return
end
return a ~= b
end
local function updatehud(player, entry, phuds, dtime)
if entry.ttl then
if entry.ttl <= 0 then
if entry.id then player:hud_remove(entry.id) end
phuds[entry.label] = nil
return
end
entry.ttl = entry.ttl - dtime
end
if entry.id then
for k, v in pairs(entry.new) do
if (not myprops[k]) and differ(v, entry.old[k]) then
player:hud_change(entry.id, k, v)
entry.old[k] = v
end
end
else
entry.id = player:hud_add(entry.new)
entry.old = copytbl(entry.new)
end
end
local function hud_params(player, def)
if not (def and def.label) then return error("missing HUD label") end
local pname
if type(player) == "string" then
pname = player
player = minetest.get_player_by_name(pname)
else
pname = player:get_player_name()
end
if not player then return error("missing player") end
return player, pname, def
end
local function hud_set(player, def)
local pname
player, pname, def = hud_params(player, def)
local phuds = huds[pname]
if not phuds then
phuds = {}
huds[pname] = phuds
end
local entry = phuds[def.label]
if not entry then
entry = {label = def.label}
phuds[def.label] = entry
end
entry.new = def
entry.ttl = def.ttl or entry.ttl
if def.quick then return updatehud(player, entry, phuds, 0) end
end
nodecore.hud_set = hud_set
function nodecore.hud_set_multiline(player, def, trans)
local pname
player, pname, def = hud_params(player, def)
local lines = {}
def.text = def.text or ""
for str in string_gmatch(def.text, "[^\r\n]+") do
lines[#lines + 1] = trans and trans(str) or str
end
for i = 1, #lines do
lines[i] = string_rep(" \n", i - 1) .. lines[i]
.. string_rep("\n ", #lines - i)
end
for i = 1, #lines do
local t = copytbl(def)
t.text = lines[i]
t.label = def.label .. ":" .. i
hud_set(player, t)
end
local phuds = huds[pname]
if not phuds then
phuds = {}
huds[pname] = phuds
end
local i = #lines + 1
while phuds[def.label .. ":" .. i] do
hud_set(player, {
label = def.label .. ":" .. i,
ttl = 0,
quick = def.quick
})
i = i + 1
end
end
minetest.after(0, function()
minetest.register_globalstep(function(dtime)
for _, player in pairs(minetest.get_connected_players()) do
local pname = player:get_player_name()
local phuds = huds[pname]
if phuds then
for _, entry in pairs(phuds) do
updatehud(player, entry, phuds, dtime)
end
end
end
end)
end)
minetest.register_on_leaveplayer(function(player)
huds[player:get_player_name()] = nil
end)