From 1f16ea2dd003e4488ccbb77bf682aa4f77f59302 Mon Sep 17 00:00:00 2001 From: Zughy <4279489-marco_a@users.noreply.gitlab.com> Date: Thu, 27 Jan 2022 22:07:31 +0100 Subject: [PATCH] Spectators share the same HPs of the player they're spectating --- init.lua | 2 +- src/api/in_game.lua | 6 +++--- src/player_manager.lua | 34 ++++++++++++++++++++++++++++++---- src/spectate/spectate_main.lua | 1 + 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/init.lua b/init.lua index 0824816..95b6af9 100755 --- a/init.lua +++ b/init.lua @@ -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" diff --git a/src/api/in_game.lua b/src/api/in_game.lua index 1c5e915..9e4747d 100755 --- a/src/api/in_game.lua +++ b/src/api/in_game.lua @@ -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 diff --git a/src/player_manager.lua b/src/player_manager.lua index ffcc12d..f78a624 100755 --- a/src/player_manager.lua +++ b/src/player_manager.lua @@ -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) diff --git a/src/spectate/spectate_main.lua b/src/spectate/spectate_main.lua index 1579ad5..e1e9be1 100755 --- a/src/spectate/spectate_main.lua +++ b/src/spectate/spectate_main.lua @@ -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))