Avoid issues with spectators in the future, once players are able to change weapons and optionally play with less than 3 weapons (closes #113)

This commit is contained in:
marco_a 2024-03-17 01:52:52 +01:00
parent b1a309bafd
commit fb8639a9d4
4 changed files with 71 additions and 75 deletions

View File

@ -3,7 +3,10 @@ local S = minetest.get_translator("block_league")
local function get_formspec() end
local function get_weapon_details() end
-- Funzionamento in breve: uso il metadato bl_profile_elem_active per tenere traccia
-- di una stringa equivalente al nome tecnico di un'arma o di un'abilità, senza
-- "block_league:". In caso di un'arma uso i campi del formspec weap e wslot; per
-- le abilità skill e sslot
function block_league.show_profile(p_name)
minetest.get_player_by_name(p_name):get_meta():set_string("bl_profile_elem_active", "")

View File

@ -164,7 +164,6 @@ end
function create_panel(arena, sp_name, p_name, y_offset)
local name = string.len(p_name) < 13 and p_name or string.sub(p_name, 1, 12) .. "..."
local skin = minetest.get_player_by_name(p_name):get_properties().textures[1]
local skin_clean = string.match(skin, "(.*)^%[")
@ -181,9 +180,9 @@ function create_panel(arena, sp_name, p_name, y_offset)
end
local teamID = arena.players[p_name].teamID
local p_weaps = block_league.get_player_weapons(p_name)
if teamID == 1 then
Panel:new("bl_spectate_" .. p_name, {
player = sp_name,
bg = "",
@ -205,17 +204,17 @@ function create_panel(arena, sp_name, p_name, y_offset)
weapon1 = {
scale = { x = 1.4, y = 1.4 },
offset = { x = 60, y = 10 },
text = "bl_smg.png"
text = p_weaps[1] and minetest.registered_nodes[p_weaps[1]].inventory_image
},
weapon2 = {
scale = { x = 1.4, y = 1.4 },
offset = { x = 85, y = 10 },
text = "bl_sword.png"
text = p_weaps[2] and minetest.registered_nodes[p_weaps[2]].inventory_image
},
weapon3 = {
scale = { x = 1.4, y = 1.4 },
offset = { x = 110, y = 10 },
text = "bl_pixelgun.png"
text = p_weaps[3] and minetest.registered_nodes[p_weaps[3]].inventory_image
},
skill = {
scale = { x = 1.4, y = 1.4 },
@ -257,7 +256,6 @@ function create_panel(arena, sp_name, p_name, y_offset)
})
else
Panel:new("bl_spectate_" .. p_name, {
player = sp_name,
bg = "",
@ -279,17 +277,17 @@ function create_panel(arena, sp_name, p_name, y_offset)
weapon1 = {
scale = { x = 1.4, y = 1.4 },
offset = { x = -110, y = 10 },
text = "bl_smg.png"
text = p_weaps[1] and minetest.registered_nodes[p_weaps[1]].inventory_image
},
weapon2 = {
scale = { x = 1.4, y = 1.4 },
offset = { x = -85, y = 10 },
text = "bl_sword.png"
text = p_weaps[2] and minetest.registered_nodes[p_weaps[2]].inventory_image
},
weapon3 = {
scale = { x = 1.4, y = 1.4 },
offset = { x = -60, y = 10 },
text = "bl_pixelgun.png"
text = p_weaps[3] and minetest.registered_nodes[p_weaps[3]].inventory_image
},
skill = {
scale = { x = 1.4, y = 1.4 },

View File

@ -1,29 +1,9 @@
local function get_bullet_count() end
function block_league.HUD_weapons_create(p_name, is_spectator)
local inv = "" -- TODO: cementato. Quando potran cambiare equip con nuove armi, cambiare
local inv = minetest.get_player_by_name(p_name):get_inventory()
local sub_img_elems = {}
local sub_txt_elems = {}
local offset_x = -90
local offset_y
if is_spectator then
local arena = arena_lib.get_arena_by_player(p_name)
local random_p
for pl_name, _ in pairs(arena.players) do
random_p = minetest.get_player_by_name(pl_name)
break
end
inv = random_p:get_inventory()
offset_y = -160
else
inv = minetest.get_player_by_name(p_name):get_inventory()
offset_y = -125
end
local offset_y = is_spectator and -160 or -125
-- mirino
Panel:new("bl_crosshair", {
@ -35,18 +15,19 @@ function block_league.HUD_weapons_create(p_name, is_spectator)
})
-- armi
-- TODO: in futuro, con nuove armi non + possibile usare w_name perché ogni gioc
-- avrà suo equip. Due possibili approcci:
-- 1. trovare modo x usare ID caselle al posto di w_name (ma dovrò fare
-- get_stack(ID):get_name() == w_name ogni volta?)
-- 2. ricreare HUD ogni volta che si cambia gioc seguitə, e mantenere w_name. Non
-- dovrebbe dar problemi con async perché armi non sparano su globalstep, non so
-- però se potrebbe creare casini con gli after invocati dalle armi
for i = 1, 3 do
local w_name = inv:get_stack("main", i):get_name() ~= "" and inv:get_stack("main", i):get_name() or ("NIL" .. i)
local weapon = minetest.registered_nodes[w_name]
local w_name = ""
local weapon = {}
sub_img_elems[w_name .. "_bg"] = {
-- dato che quando entrano, lɜ spettanti non sono ancora dentro alla spettatore,
-- inizializzo stringhe vuote che verranno colmate dal primo on_change_spectated_target
-- (che è istantaneo)
if not is_spectator then
w_name = inv:get_stack("main", i):get_name() ~= "" and inv:get_stack("main", i):get_name() or ""
weapon = minetest.registered_nodes[w_name]
end
sub_img_elems[i .. "_bg"] = {
scale = { x = 2, y = 2 },
offset = { x = offset_x, y = offset_y },
alignment = { x = 0, y = 1 },
@ -55,7 +36,7 @@ function block_league.HUD_weapons_create(p_name, is_spectator)
}
if weapon then
sub_img_elems[w_name .. "_icon"] = {
sub_img_elems[i .. "_icon"] = {
scale = { x = 2, y = 2 },
offset = { x = offset_x, y = offset_y },
alignment = { x = -1, y = 1 },
@ -63,7 +44,7 @@ function block_league.HUD_weapons_create(p_name, is_spectator)
z_index = 1
}
sub_txt_elems[w_name .. "_magazine_txt"] = {
sub_txt_elems[i .. "_magazine_txt"] = {
alignment = { x = 0, y = 1 },
offset = { x = offset_x + 30, y = offset_y + 6 },
text = weapon.magazine or "",
@ -90,10 +71,20 @@ end
function block_league.HUD_weapons_update(arena, p_name, w_name, is_reloading)
local weapon = minetest.registered_nodes[w_name]
local current_magazine = not weapon.magazine and "" or arena.players[p_name].weapons_magazine[w_name]
local inv_main = minetest.get_player_by_name(p_name):get_inventory():get_list("main") -- TODO: per ottimizzare, salva (e solo i nomi) quando entrano
local slot_id
local panel = panel_lib.get_panel(p_name, "bl_weapons")
for i = 1, 3 do
if inv_main[i]:get_name() == w_name then
slot_id = i
end
end
-- se è casella vuota, annulla
if not slot_id then return end
local weapon = minetest.registered_nodes[w_name] or {} -- TODO: è possibile che sia vuota?
local current_magazine = not weapon.magazine and "" or arena.players[p_name].weapons_magazine[w_name]
local bg_pic = ""
if is_reloading then
@ -104,17 +95,37 @@ function block_league.HUD_weapons_update(arena, p_name, w_name, is_reloading)
bg_pic = "bl_hud_bullets_bg.png"
end
local panel = panel_lib.get_panel(p_name, "bl_weapons")
panel:update(nil,
{[w_name .. "_magazine_txt"] = { text = current_magazine }},
{[w_name .. "_bg"] = { text = bg_pic }}
{[slot_id .. "_magazine_txt"] = { text = current_magazine }},
{[slot_id .. "_bg"] = { text = bg_pic }}
)
local icon = weapon.inventory_image or "" -- TODO: è possibile che sia vuota?
for sp_name, _ in pairs(arena_lib.get_player_spectators(p_name)) do
local panel_sp = panel_lib.get_panel(sp_name, "bl_weapons")
panel_sp:update(nil,
{[w_name .. "_magazine_txt"] = { text = current_magazine }},
{[w_name .. "_bg"] = { text = bg_pic }}
{[slot_id .. "_magazine_txt"] = { text = current_magazine }},
{[slot_id .. "_bg"] = { text = bg_pic }, [slot_id .. "_icon"] = {text = icon}}
)
end
end
-- funzione chiamata esclusivamente quando spettanti cambiano giocante seguitə e
-- questə ha un buco nella casella dove lə giocante precedente invece aveva un'arma.
-- In altre parole, svuoto la casella
function block_league.HUD_weapons_update_empty(p_name, empty_id)
for sp_name, _ in pairs(arena_lib.get_player_spectators(p_name)) do
local panel_sp = panel_lib.get_panel(sp_name, "bl_weapons")
panel_sp:update(nil,
{[empty_id .. "_magazine_txt"] = { text = "" }},
{[empty_id .. "_bg"] = { text = "bl_hud_bullets_bg.png" }, [empty_id .. "_icon"] = { text = ""}}
)
end
end
@ -132,25 +143,3 @@ function block_league.HUD_crosshair_update(p_name, w_name, is_reloading)
panel:update({bg = weap.crosshair .. col})
end
----------------------------------------------
---------------FUNZIONI LOCALI----------------
----------------------------------------------
function get_bullet_count(definition, inv)
if not definition.bullet then return end
for i=0,inv:get_size("main"),1 do
local stack = inv:get_stack("main", i)
local item_name = stack:get_name()
if item_name == definition.bullet then
return stack:get_count()
end
end
end

View File

@ -15,8 +15,14 @@ arena_lib.on_change_spectated_target("block_league", function(arena, sp_name, t_
minetest.get_player_by_name(sp_name):hud_set_flags({healthbar = true})
end
for _, weap_name in pairs(block_league.get_player_weapons(t_name)) do
block_league.HUD_weapons_update(arena, t_name, weap_name)
local p_weaps = block_league.get_player_weapons(t_name)
for i = 1, 3 do
if p_weaps[i] then
block_league.HUD_weapons_update(arena, t_name, p_weaps[i])
else
block_league.HUD_weapons_update_empty(t_name, i)
end
end
block_league.HUD_skill_update(sp_name)