Add arena status HUD + get_players_in_hub() util
parent
1206232e98
commit
7f2e288f05
|
@ -23,3 +23,5 @@ hub_manager.settings.physics = {
|
|||
sneak_glitch=false,
|
||||
new_move=true
|
||||
}
|
||||
|
||||
hub_manager.settings.MAX_ARENAS_IN_STATUS = 4
|
||||
|
|
2
init.lua
2
init.lua
|
@ -11,5 +11,7 @@ dofile(srcpath .. "/chatcmdbuilder.lua")
|
|||
dofile(srcpath .. "/commands.lua")
|
||||
dofile(srcpath .. "/items.lua")
|
||||
dofile(srcpath .. "/player_manager.lua")
|
||||
dofile(srcpath .. "/deps/arena_lib.lua")
|
||||
dofile(srcpath .. "/HUD/hud_arenastatus.lua")
|
||||
|
||||
minetest.log("action", "[HUB_MANAGER] Mod initialised, running version " .. version)
|
||||
|
|
|
@ -0,0 +1,262 @@
|
|||
local function trim_name() end
|
||||
|
||||
local arenas = {} -- KEY: sorting ID, VALUE: {mod = mod, mg = mg_name, name = a_name, icon = mg_icon, y_off, bg = {...}, amount = {...}}
|
||||
local hidden_panels = {} -- KEY: p_name, VALUE: true
|
||||
local MAX_ARENAS_IN_STATUS = hub_manager.settings.MAX_ARENAS_IN_STATUS
|
||||
local SLOT_DISTANCE = 52
|
||||
|
||||
-- I pannelli si dividono nelle tabelle contenenti le informazioni da mostrare (`arenas`)
|
||||
-- e nella loro resa grafica vera e propria (panel_lib). Ogni volta che un pannello
|
||||
-- viene aggiornato, pesca i dati da `arenas`.
|
||||
-- I pannelli sono gestiti in modo tale che le loro posizioni non si intersechino mai:
|
||||
-- il pannello più in alto sarà sempre il n°1, quello seguente il n°2 ecc. Se l'arena
|
||||
-- associata al primo pannello scompare, le informazioni del pannello n°2 passeranno
|
||||
-- a quest'ultimo e via dicendo, nascondendo quello visibile più in fondo (a meno che
|
||||
-- il numero di `arenas` non superi il numero di pannelli visibili: in quel caso
|
||||
-- otterrà le informazioni dal primo non visibile)
|
||||
|
||||
function hub_manager.HUD_arstatus_create(p_name)
|
||||
|
||||
for i = 1, MAX_ARENAS_IN_STATUS do
|
||||
|
||||
local a_data = arenas[i]
|
||||
local y_off = a_data and a_data.y_off or 0
|
||||
local bg = a_data and a_data.bg.bg or "blank.png"
|
||||
local icon = a_data and a_data.icon or "blank.png"
|
||||
local a_name = a_data and trim_name(a_data.name) or ""
|
||||
local amount = a_data and a_data.amount.p_amount.text or ""
|
||||
|
||||
Panel:new("hubman_arenastatus_" .. i, {
|
||||
player = p_name,
|
||||
position = {x = 1, y = 0.5},
|
||||
offset = {x = 0, y = y_off},
|
||||
bg = bg,
|
||||
bg_scale = {x = 3, y = 3},
|
||||
title = "",
|
||||
sub_img_elems = {
|
||||
icon = {
|
||||
text = icon,
|
||||
offset = {x = -180}
|
||||
}
|
||||
},
|
||||
sub_txt_elems = {
|
||||
arena_name = {
|
||||
text = a_name,
|
||||
alignment = {x = 1},
|
||||
offset = {x = -175}
|
||||
},
|
||||
p_amount = {
|
||||
text = amount,
|
||||
alignment = {x = -1},
|
||||
offset = {x = -5}
|
||||
}
|
||||
}
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
function hub_manager.HUD_arstatus_add(mod, arena)
|
||||
|
||||
local arenas_amnt = #arenas
|
||||
local y_off
|
||||
|
||||
-- calcolo lo scostamento che avrà il pannello. Se sono già visualizzati i pannelli massimi,
|
||||
-- lo accoderò in basso di un'unità. Al contrario, se questo sarà visibile,
|
||||
-- sposterò tutti quelli visibili di mezza unità verso l'alto, accodando quello
|
||||
-- nuovo sempre di mezza unità
|
||||
if arenas_amnt == 0 then
|
||||
y_off = 0
|
||||
else
|
||||
if arenas_amnt >= MAX_ARENAS_IN_STATUS then
|
||||
y_off = arenas[arenas_amnt].y_off + SLOT_DISTANCE
|
||||
else
|
||||
y_off = arenas[arenas_amnt].y_off + SLOT_DISTANCE / 2
|
||||
|
||||
for _, slot in ipairs(arenas) do
|
||||
slot.y_off = slot.y_off - SLOT_DISTANCE / 2
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- aggiungo l'arena nella tabella
|
||||
local bg_img = arena.players_amount < arena.max_players and "hubmanager_arenastatus_join.png" or "hubmanager_arenastatus_nojoin.png"
|
||||
local mg = arena_lib.mods[mod]
|
||||
local a_info = {
|
||||
mod = mod,
|
||||
mg = mg.name,
|
||||
name = arena.name,
|
||||
icon = mg.icon or "hubmanager_mg_missing_icon.png",
|
||||
y_off = y_off,
|
||||
bg = {bg = bg_img},
|
||||
amount = { p_amount = { text = arena.players_amount .. "/" .. arena.max_players }}
|
||||
}
|
||||
|
||||
table.insert(arenas, a_info)
|
||||
|
||||
-- se supera il numero massimo di slot visibili, la grafica non verrebbe aggiornata ugualmente
|
||||
if #arenas > MAX_ARENAS_IN_STATUS then return end
|
||||
|
||||
for i = 1, #arenas do
|
||||
hub_manager.HUD_arstatus_update(i)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
function hub_manager.HUD_arstatus_remove(mg_name, arena_name)
|
||||
|
||||
-- trovo l'ID dell'arena nell'HUD
|
||||
local HUD_ID = hub_manager.get_arenastatus_slot(mg_name, arena_name)
|
||||
|
||||
table.remove(arenas, HUD_ID)
|
||||
|
||||
local arenas_amnt = #arenas
|
||||
|
||||
-- scalo la posizione dei pannelli che venivano dopo quello rimosso. Li muovo
|
||||
-- di mezza unità verso l'alto se quelli visibili cambieranno di numero, o di
|
||||
-- una intera se erano già al completo (ovvero uguali o maggiori di MAX_ARENAS_IN_STATUS)
|
||||
local mov_divisor = arenas_amnt < MAX_ARENAS_IN_STATUS and 2 or 1
|
||||
for i = HUD_ID, arenas_amnt do
|
||||
arenas[i].y_off = arenas[i].y_off - SLOT_DISTANCE / mov_divisor
|
||||
end
|
||||
|
||||
-- se ora ci sono meno slot di quelli massimi..
|
||||
if arenas_amnt < MAX_ARENAS_IN_STATUS then
|
||||
|
||||
-- aggiorno la posizione degli slot che venivano prima
|
||||
for i = 1, HUD_ID -1 do
|
||||
arenas[i].y_off = arenas[i].y_off + SLOT_DISTANCE / 2
|
||||
end
|
||||
|
||||
-- e faccio sparire l'ultimo
|
||||
for pl_name in pairs(hub_manager.get_players_in_hub()) do
|
||||
local panel = panel_lib.get_panel(pl_name, "hubman_arenastatus_" .. arenas_amnt + 1)
|
||||
if panel.visible then
|
||||
panel:hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- se l'HUD già non appariva o se era l'unica rimasta, fermati qua
|
||||
if HUD_ID > MAX_ARENAS_IN_STATUS or arenas_amnt == 0 then return end
|
||||
|
||||
-- se lo slot rimosso era visibile, aggiorno la posizione di tutti quelli visibili
|
||||
for i = 1, arenas_amnt do
|
||||
hub_manager.HUD_arstatus_update(i)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
function hub_manager.HUD_arstatus_update(slot_ID, skip_mgarena, skip_pos, skip_status, skip_amount)
|
||||
|
||||
local slot = arenas[slot_ID]
|
||||
local elem = {}
|
||||
local subtxt_elems = {}
|
||||
local icon = nil
|
||||
local status = nil
|
||||
|
||||
if not skip_mgarena then
|
||||
icon = { icon = { text = slot.icon }}
|
||||
subtxt_elems.arena_name = { text = trim_name(slot.name) }
|
||||
end
|
||||
|
||||
if not skip_pos then
|
||||
elem.offset = { x = 0, y = slot.y_off }
|
||||
end
|
||||
|
||||
local _, arena = arena_lib.get_arena_by_name(slot.mod, slot.name)
|
||||
|
||||
if not skip_status then
|
||||
local bg_img = ""
|
||||
|
||||
if not arena.in_loading and not arena.in_celebration and
|
||||
arena.players_amount < arena.max_players and
|
||||
(arena.in_queue or (arena.in_game and arena_lib.mods[slot.mod].join_while_in_progress)) then
|
||||
bg_img = "hubmanager_arenastatus_join.png"
|
||||
else
|
||||
bg_img = "hubmanager_arenastatus_nojoin.png"
|
||||
end
|
||||
|
||||
elem.bg = bg_img
|
||||
end
|
||||
|
||||
if not skip_amount then
|
||||
subtxt_elems.p_amount = { text = arena.players_amount .. "/" .. arena.max_players }
|
||||
end
|
||||
|
||||
-- se non c'è nessun elemento/sottoelemento da aggiornare, faccio sparire
|
||||
if not next(elem) then
|
||||
elem = nil
|
||||
end
|
||||
|
||||
if not next(subtxt_elems) then
|
||||
subtxt_elems = nil
|
||||
end
|
||||
|
||||
for pl_name in pairs(hub_manager.get_players_in_hub()) do
|
||||
local panel = panel_lib.get_panel(pl_name, "hubman_arenastatus_" .. slot_ID)
|
||||
panel:update(elem, icon, subtxt_elems)
|
||||
|
||||
-- se non era visibile e l'opzione per non vederlo non era abilitata, mostralo
|
||||
if not panel:is_visible() and not hidden_panels[p_name] then
|
||||
panel:show()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
function hub_manager.HUD_arstatus_show(p_name)
|
||||
|
||||
if not hidden_panels[p_name] then return end
|
||||
|
||||
for i = 1, MAX_ARENAS_IN_STATUS do
|
||||
local panel = panel_lib.get_panel(p_name, "hubman_arenastatus_" .. i)
|
||||
panel:show()
|
||||
end
|
||||
|
||||
hidden_panels[p_name] = nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
function hub_manager.HUD_arstatus_hide(p_name)
|
||||
|
||||
if hidden_panels[p_name] then return end
|
||||
|
||||
for i = 1, MAX_ARENAS_IN_STATUS do
|
||||
local panel = panel_lib.get_panel(p_name, "hubman_arenastatus_" .. i)
|
||||
panel:hide()
|
||||
end
|
||||
|
||||
hidden_panels[p_name] = true
|
||||
end
|
||||
|
||||
|
||||
|
||||
function hub_manager.get_arenastatus_slot(mg_name, arena_name)
|
||||
for i = 1, #arenas do
|
||||
if arenas[i].name == arena_name and arenas[i].mg == mg_name then
|
||||
return i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----------------------------------------------
|
||||
---------------FUNZIONI LOCALI----------------
|
||||
----------------------------------------------
|
||||
|
||||
function trim_name(name)
|
||||
if name:len() > 15 then
|
||||
return name:sub(1, 13) .. "..."
|
||||
else
|
||||
return name
|
||||
end
|
||||
end
|
17
src/api.lua
17
src/api.lua
|
@ -29,6 +29,23 @@ end
|
|||
|
||||
|
||||
|
||||
function hub_manager.get_players_in_hub()
|
||||
|
||||
local in_hub = {}
|
||||
local in_game = arena_lib.get_players_in_game()
|
||||
|
||||
for _, pl in pairs(minetest.get_connected_players()) do
|
||||
local pl_name = pl:get_player_name()
|
||||
if not in_game[pl_name] then
|
||||
in_hub[pl_name] = true
|
||||
end
|
||||
end
|
||||
|
||||
return in_hub
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----------------------------------------------
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
arena_lib.register_on_join_queue(function(mg, arena, p_name, has_status_changed)
|
||||
if has_status_changed then
|
||||
local mod = arena_lib.get_mod_by_player(p_name)
|
||||
hub_manager.HUD_arstatus_add(mod, arena)
|
||||
|
||||
elseif arena.in_queue then
|
||||
local slot_ID = hub_manager.get_arenastatus_slot(mg.name, arena.name)
|
||||
local skip_status = arena.players_amount == arena.max_players and true or false
|
||||
|
||||
hub_manager.HUD_arstatus_update(slot_ID, true, true, skip_status)
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
|
||||
arena_lib.register_on_leave_queue(function(mg, arena, p_name, has_status_changed)
|
||||
if has_status_changed then
|
||||
hub_manager.HUD_arstatus_remove(mg.name, arena.name)
|
||||
elseif arena.in_queue then
|
||||
local slot_ID = hub_manager.get_arenastatus_slot(mg.name, arena.name)
|
||||
local skip_status = arena.players_amount < arena.max_players and true or false
|
||||
|
||||
hub_manager.HUD_arstatus_update(slot_ID, true, true, skip_status)
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
|
||||
arena_lib.register_on_load(function(mg, arena)
|
||||
local mg_name = mg.name
|
||||
local slot_ID = hub_manager.get_arenastatus_slot(mg_name, arena.name)
|
||||
|
||||
hub_manager.HUD_arstatus_update(slot_ID, true, true, false, true)
|
||||
|
||||
if slot_ID > hub_manager.settings.MAX_ARENAS_IN_STATUS then return end
|
||||
|
||||
for pl_name in pairs(arena.players) do
|
||||
hub_manager.HUD_arstatus_hide(pl_name)
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
|
||||
arena_lib.register_on_start(function(mg, arena)
|
||||
if not mg.join_while_in_progress or arena.players_amount == arena.max_players then return end
|
||||
|
||||
local slot_ID = hub_manager.get_arenastatus_slot(mg.name, arena.name)
|
||||
hub_manager.HUD_arstatus_update(slot_ID, true, true, false, true)
|
||||
end)
|
||||
|
||||
|
||||
|
||||
arena_lib.register_on_join(function(mg, arena, p_name, as_spectator)
|
||||
local slot_ID = hub_manager.get_arenastatus_slot(mg.name, arena.name)
|
||||
hub_manager.HUD_arstatus_hide(p_name)
|
||||
hub_manager.HUD_arstatus_update(slot_ID)
|
||||
end)
|
||||
|
||||
|
||||
|
||||
arena_lib.register_on_quit(function(mg, arena, p_name, is_spectator, reason)
|
||||
local mg_name = mg.name
|
||||
local slot_ID = hub_manager.get_arenastatus_slot(mg.name, arena.name)
|
||||
|
||||
-- se mostro e aggiorno al tempo stesso, non funziona. Da qui l'attesa di 0.1s
|
||||
minetest.after(0.1, function()
|
||||
hub_manager.HUD_arstatus_update(slot_ID)
|
||||
end)
|
||||
|
||||
if reason == 0 then return end
|
||||
|
||||
hub_manager.HUD_arstatus_show(p_name)
|
||||
end)
|
||||
|
||||
|
||||
|
||||
arena_lib.register_on_end(function(mg, arena, players, winners, spectators, is_forced)
|
||||
|
||||
for pl_name in pairs(players) do
|
||||
hub_manager.HUD_arstatus_show(pl_name)
|
||||
end
|
||||
|
||||
for sp_name in pairs(spectators) do
|
||||
hub_manager.HUD_arstatus_show(sp_name)
|
||||
end
|
||||
|
||||
-- se mostro E aggiorno al tempo stesso, non funziona. Da qui l'attesa di 0.1s
|
||||
minetest.after(0.1, function()
|
||||
hub_manager.HUD_arstatus_remove(mg.name, arena.name)
|
||||
end)
|
||||
end)
|
|
@ -6,7 +6,7 @@ minetest.register_on_joinplayer(function(player)
|
|||
|
||||
hub_manager.set_items(player)
|
||||
hub_manager.set_hub_physics(player)
|
||||
|
||||
hub_manager.HUD_arstatus_create(player:get_player_name())
|
||||
end)
|
||||
|
||||
|
||||
|
@ -21,7 +21,6 @@ minetest.register_on_player_hpchange(function(player, hp_change, reason)
|
|||
end
|
||||
|
||||
return hp_change
|
||||
|
||||
end, true)
|
||||
|
||||
|
||||
|
@ -32,5 +31,4 @@ minetest.register_on_respawnplayer(function(player)
|
|||
|
||||
player:set_pos(hub_manager.get_hub_spawn_point())
|
||||
return true
|
||||
|
||||
end)
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 173 B |
Binary file not shown.
After Width: | Height: | Size: 173 B |
Binary file not shown.
After Width: | Height: | Size: 185 B |
Loading…
Reference in New Issue