Spectators share the same HPs of the player they're spectating

master
Zughy 2022-01-27 22:07:31 +01:00
parent 86d8467fac
commit 1f16ea2dd0
4 changed files with 35 additions and 8 deletions

View File

@ -1,4 +1,4 @@
local version = "5.1.1"
local version = "5.2.0-dev"
local modpath = minetest.get_modpath("arena_lib")
local srcpath = modpath .. "/src"

View File

@ -718,9 +718,6 @@ function operations_before_entering_arena(mod_ref, mod, arena, arena_ID, p_name)
arena_lib.store_inventory(player)
end
-- li curo
player:set_hp(minetest.PLAYER_MAX_HP_DEFAULT)
-- salvo la hotbar se c'è la spettatore o la hotbar personalizzata
if mod_ref.spectate_mode or mod_ref.hotbar then
players_temp_storage[p_name].hotbar_slots = player:hud_get_hotbar_itemcount()
@ -796,6 +793,9 @@ function operations_before_playing_arena(mod_ref, arena, p_name)
-- agganciati al giocatore, sennò cadono nel vuoto)
player:set_detach()
-- li curo
player:set_hp(minetest.PLAYER_MAX_HP_DEFAULT)
-- assegno eventuali proprietà giocatori
for k, v in pairs(mod_ref.player_properties) do
if type(v) == "table" then

View File

@ -99,9 +99,17 @@ minetest.register_on_player_hpchange(function(player, hp_change, reason)
-- se non è in partita, annullo
if not mod then return hp_change end
-- se è spettatore, annullo
if arena_lib.is_player_spectating(p_name) and reason.type ~= "respawn" then
return 0
-- se è spettatore, annullo a meno che non abbia cambiato giocatore seguito
-- o che il giocatore seguito non abbia subito un danno (che usano set_hp).
-- Questo lo rende vulnerabile anche a cose come /kill, ma l'uccisione dello
-- spettatore viene comunque gestita senza problemi da arena_lib, giusto in
-- caso qualche amministratore sia particolarmente simpatico o un minigioco
-- si sia scordato di filtrare (per esempio) gli spettatori dal danno di una
-- abilità ad area. Quando torna in vita, gli hp gli vengono impostati da
-- find_and_spectate_player (questo spiega perché venga curato anche se
-- ignora il tipo "respawn")
if arena_lib.is_player_spectating(p_name) then
return reason.type == "set_hp" and hp_change or 0
end
-- se un tipo di danno è disabilitato, annullo
@ -111,6 +119,21 @@ minetest.register_on_player_hpchange(function(player, hp_change, reason)
end
end
-- aggiorna la vita di ogni spettatore che seguiva quel giocatore..
if arena_lib.is_player_spectated(p_name) then
for sp_name, _ in pairs(arena_lib.get_player_spectators(p_name)) do
local spectator = minetest.get_player_by_name(sp_name)
-- TODO: capire se può essere sistemato a livello motore di gioco: al momento
-- devo ritardare di uno step o non aggiorna la vita fino al prossimo richiamo
minetest.after(0.1, function()
-- ..se lo spettatore non è stato ucciso per chissà quale arcano motivo
if spectator and spectator:get_hp() > 0 then
spectator:set_hp(player:get_hp() > 0 and player:get_hp() or 1)
end
end)
end
end
return hp_change
end, true)
@ -120,7 +143,7 @@ end, true)
minetest.register_on_dieplayer(function(player, reason)
local p_name = player:get_player_name()
if not arena_lib.is_player_in_arena(p_name) then return end
if not arena_lib.is_player_in_arena(p_name) or arena_lib.is_player_spectating(p_name) then return end
local mod_ref = arena_lib.mods[arena_lib.get_mod_by_player(p_name)]
local arena = arena_lib.get_arena_by_player(p_name)
@ -145,6 +168,9 @@ minetest.register_on_respawnplayer(function(player)
if not arena_lib.is_player_spectating(p_name) then
player:set_pos(arena_lib.get_random_spawner(arena, arena.players[p_name].teamID))
else
arena_lib.find_and_spectate_player(p_name)
end
return true
end)

View File

@ -306,6 +306,7 @@ function set_spectator(spectator, p_name, i, prev_spectated)
local target = minetest.get_player_by_name(p_name)
spectator:set_attach(target, "", {x=0, y=-5, z=-20}, {x=0, y=0, z=0})
spectator:set_hp(target:get_hp() > 0 and target:get_hp() or 1)
spectator:get_meta():set_int("arenalib_watchID", i)
arena_lib.HUD_send_msg("hotbar", sp_name, S("Currently spectating: @1", p_name))