capturetheflag/mods/ctf/ctf_respawn_delay/init.lua
2021-05-26 07:19:29 -07:00

116 lines
3.2 KiB
Lua

ctf_respawn_delay = {
players = {},
}
local respawnfunc
local RESPAWN_DELAY = 5
local RESPAWN_INTERVAL = 1.1
local RESPAWN_MESSAGE = "Respawning in "
minetest.register_on_dieplayer(function(player, reason)
local pname = player:get_player_name()
if ctf_match.is_in_build_time() or ctf_respawn_delay.players[pname] then -- what is dead may never die
return
end
ctf_respawn_delay.players[pname] = {
old_max = player:get_properties().hp_max,
timeleft = "waiting",
hudid = player:hud_add({
hud_elem_type = "text",
position = {x=0.5, y=0.5},
name = "respawn_delay",
scale = {x=100, y=100},
text = RESPAWN_MESSAGE..RESPAWN_DELAY,
number = 0xD600AF,
alignment = {x = 0, y = -1},
offset = {x = 0, y = 0},
size = {x = 2},
})
}
player:set_properties({hp_max = 0})
end)
minetest.register_on_mods_loaded(function()
ctf_respawn_delay.registered_on_respawnplayers = minetest.registered_on_respawnplayers
minetest.registered_on_respawnplayers = {}
table.insert(minetest.registered_on_respawnplayers, 1, function(player)
local pname = player:get_player_name()
if ctf_respawn_delay.players[pname] then
-- Since the player is still dead the client can send respawn actions
-- https://github.com/minetest/minetest/blob/4152227f17315a9cf9038266d9f9bb06e21e3424/src/network/serverpackethandler.cpp#L895
-- We should ignore those
if ctf_respawn_delay.players[pname].timeleft == "waiting" then
ctf_respawn_delay.players[pname].timeleft = RESPAWN_DELAY
local pos = player:get_pos()
pos.y = ctf_map.map.h/2 + 10
player:set_pos(pos) -- Player will be stuck there because CTF 'air' is walkable
minetest.after(RESPAWN_INTERVAL, respawnfunc, pname)
end
return true
end
for k, func in ipairs(ctf_respawn_delay.registered_on_respawnplayers) do
func(player)
end
return true
end)
end)
function respawnplayer(player, pname)
player:hud_remove(ctf_respawn_delay.players[pname].hudid)
player:set_properties({hp_max = ctf_respawn_delay.players[pname].old_max})
player:set_hp(ctf_respawn_delay.players[pname].old_max)
for k, func in ipairs(ctf_respawn_delay.registered_on_respawnplayers) do
func(player)
end
end
function respawnfunc(pname)
if not ctf_respawn_delay.players[pname] then
return
end
local player = minetest.get_player_by_name(pname)
if not player then
ctf_respawn_delay.players[pname] = nil
return
end
ctf_respawn_delay.players[pname].timeleft = ctf_respawn_delay.players[pname].timeleft - 1
local timeleft = ctf_respawn_delay.players[pname].timeleft
if timeleft > 0 then
player:hud_change(ctf_respawn_delay.players[pname].hudid, "text", RESPAWN_MESSAGE..timeleft)
minetest.after(RESPAWN_INTERVAL, respawnfunc, pname)
else
respawnplayer(player, pname)
ctf_respawn_delay.players[pname] = nil
end
end
ctf_match.register_on_new_match(function()
for pname in pairs(ctf_respawn_delay.players) do
local player = minetest.get_player_by_name(pname)
if player then
respawnplayer(player, pname)
end
end
ctf_respawn_delay.players = {}
end)
minetest.register_on_leaveplayer(function(player)
local pname = player:get_player_name()
if ctf_respawn_delay.players[pname] then
player:set_properties({hp_max = ctf_respawn_delay.players[pname].old_max})
ctf_respawn_delay.players[pname] = nil
end
end)