376 lines
12 KiB
Lua
Executable File
376 lines
12 KiB
Lua
Executable File
local S = minetest.get_translator("arena_lib")
|
|
|
|
local function assign_team() end
|
|
local function in_game_txt(arena) end
|
|
local function HUD_countdown(arena, seconds) end
|
|
|
|
|
|
|
|
signs_lib.register_sign("arena_lib:sign", {
|
|
description = S("Arena sign"),
|
|
tiles = {
|
|
{ name = "arenalib_sign.png", backface_culling = true},
|
|
"arenalib_sign_edge.png"
|
|
},
|
|
inventory_image = "arenalib_sign_icon.png",
|
|
default_color = "8",
|
|
entity_info = "standard",
|
|
sounds = default.node_sound_wood_defaults(),
|
|
groups = {cracky = 3, oddly_breakable_by_hand = 3},
|
|
allow_widefont = true,
|
|
chars_per_line = 40,
|
|
horiz_scaling = 0.95,
|
|
vert_scaling = 1.38,
|
|
number_of_lines = 5,
|
|
|
|
on_dig = function(pos, node, digger)
|
|
if minetest.get_meta(pos):get_int("arenaID") ~= 0 then
|
|
return end
|
|
|
|
minetest.node_dig(pos,node,digger)
|
|
end,
|
|
|
|
|
|
on_punch = function(pos, node, puncher, pointed_thing)
|
|
|
|
local arenaID = minetest.get_meta(pos):get_int("arenaID")
|
|
if arenaID == 0 then return end
|
|
|
|
local mod = minetest.get_meta(pos):get_string("mod")
|
|
local mod_ref = arena_lib.mods[mod]
|
|
local sign_arena = mod_ref.arenas[arenaID]
|
|
local p_name = puncher:get_player_name()
|
|
|
|
if not sign_arena then return end -- nel caso qualche cartello dovesse buggarsi, si può rompere senza far crashare
|
|
|
|
-- se si è nell'editor
|
|
if arena_lib.is_player_in_edit_mode(p_name) then
|
|
minetest.chat_send_player(p_name, minetest.colorize("#e6482e", S("[!] You must leave the editor first!")))
|
|
return end
|
|
|
|
-- se c'è parties e si è in gruppo...
|
|
if minetest.get_modpath("parties") and parties.is_player_in_party(p_name) and arena_lib.get_queueID_by_player(p_name) ~= arenaID then
|
|
|
|
-- se non si è il capo gruppo
|
|
if not parties.is_player_party_leader(p_name) then
|
|
minetest.chat_send_player(p_name, minetest.colorize("#e6482e", S("[!] Only the party leader can enter the queue!")))
|
|
return end
|
|
|
|
local party_members = parties.get_party_members(p_name)
|
|
|
|
for _, pl_name in pairs(party_members) do
|
|
if arena_lib.is_player_in_arena(pl_name) then
|
|
minetest.chat_send_player(p_name, minetest.colorize("#e6482e", S("[!] You must wait for all your party members to finish their ongoing games before entering a new one!")))
|
|
return
|
|
end
|
|
end
|
|
|
|
--se non c'è spazio (no team)
|
|
if not sign_arena.teams_enabled then
|
|
if #party_members > sign_arena.max_players - sign_arena.players_amount then
|
|
minetest.chat_send_player(p_name, minetest.colorize("#e6482e", S("[!] There is not enough space for the whole party!")))
|
|
return end
|
|
-- se non c'è spazio (team)
|
|
else
|
|
|
|
local free_space = false
|
|
for _, amount in pairs(sign_arena.players_amount_per_team) do
|
|
if #party_members <= sign_arena.max_players - amount then
|
|
free_space = true
|
|
break
|
|
end
|
|
end
|
|
|
|
if not free_space then
|
|
minetest.chat_send_player(p_name, minetest.colorize("#e6482e", S("[!] There is no team with enough space for the whole party!")))
|
|
return end
|
|
end
|
|
end
|
|
|
|
-- se non è abilitata
|
|
if not sign_arena.enabled then
|
|
minetest.chat_send_player(p_name, minetest.colorize("#e6482e", S("[!] The arena is not enabled!")))
|
|
return end
|
|
|
|
-- se l'arena è piena
|
|
if sign_arena.players_amount == sign_arena.max_players * #sign_arena.teams and arena_lib.get_queueID_by_player(p_name) ~= arenaID then
|
|
minetest.chat_send_player(p_name, minetest.colorize("#e6482e", S("[!] The arena is already full!")))
|
|
return end
|
|
|
|
-- se sta caricando o sta finendo
|
|
if sign_arena.in_loading or sign_arena.in_celebration then
|
|
minetest.chat_send_player(p_name, minetest.colorize("#e6482e", S("[!] The arena is loading, try again in a few seconds!")))
|
|
return end
|
|
|
|
-- se è in corso e non permette l'entrata
|
|
if sign_arena.in_game and mod_ref.join_while_in_progress == false then
|
|
minetest.chat_send_player(p_name, minetest.colorize("#e6482e", S("[!] This minigame doesn't allow to join while in progress!")))
|
|
return end
|
|
|
|
-- se è già in coda
|
|
if arena_lib.is_player_in_queue(p_name) then
|
|
|
|
local queued_mod = arena_lib.get_mod_by_player(p_name)
|
|
local queued_ID = arena_lib.get_queueID_by_player(p_name)
|
|
|
|
-- se è un party, rimuovo tutto il gruppo
|
|
if minetest.get_modpath("parties") and parties.is_player_in_party(p_name) then
|
|
|
|
-- (se non è il capogruppo, annullo)
|
|
if not parties.is_player_party_leader(p_name) then
|
|
minetest.chat_send_player(p_name, minetest.colorize("#e6482e", S("[!] Only the party leader can leave the queue!")))
|
|
return end
|
|
|
|
local party_members = parties.get_party_members(p_name)
|
|
|
|
for _, pl_name in pairs(party_members) do
|
|
arena_lib.HUD_hide("all", pl_name)
|
|
arena_lib.remove_from_queue(pl_name)
|
|
end
|
|
|
|
-- sennò rimuovo il singolo utente
|
|
else
|
|
arena_lib.HUD_hide("all", p_name)
|
|
arena_lib.remove_from_queue(p_name)
|
|
end
|
|
|
|
-- se era in coda per la stessa arena, interrompo qua, sennò procedo per
|
|
-- aggiungerlo nella nuova
|
|
if queued_mod == mod and queued_ID == arenaID then return end
|
|
end
|
|
|
|
local p_team_ID
|
|
|
|
-- determino eventuale team giocatore
|
|
if sign_arena.teams_enabled then
|
|
p_team_ID = assign_team(mod_ref, sign_arena, p_name)
|
|
end
|
|
|
|
local players_to_add = {}
|
|
|
|
-- potrei avere o un giocatore o un intero gruppo da aggiungere. Quindi per evitare mille if, metto a prescindere il/i giocatore/i in una tabella per iterare in alcune operazioni successive
|
|
if minetest.get_modpath("parties") and parties.is_player_in_party(p_name) then
|
|
for k, v in pairs(parties.get_party_members(p_name)) do
|
|
players_to_add[k] = v
|
|
end
|
|
else
|
|
table.insert(players_to_add, p_name)
|
|
end
|
|
|
|
-- aggiungo il giocatore
|
|
for _, pl_name in pairs(players_to_add) do
|
|
sign_arena.players[pl_name] = {kills = 0, deaths = 0, teamID = p_team_ID}
|
|
end
|
|
|
|
-- aumento il conteggio di giocatori in partita
|
|
sign_arena.players_amount = sign_arena.players_amount + #players_to_add
|
|
if sign_arena.teams_enabled then
|
|
sign_arena.players_amount_per_team[p_team_ID] = sign_arena.players_amount_per_team[p_team_ID] + #players_to_add
|
|
end
|
|
|
|
-- notifico i vari giocatori del nuovo player
|
|
for _, pl_name in pairs(players_to_add) do
|
|
if sign_arena.in_game then
|
|
arena_lib.join_arena(mod, pl_name, arenaID)
|
|
arena_lib.send_message_players_in_arena(sign_arena, minetest.colorize("#c6f154", " >>> " .. pl_name))
|
|
arena_lib.update_sign(sign_arena)
|
|
return
|
|
else
|
|
arena_lib.add_to_queue(pl_name, mod, arenaID)
|
|
arena_lib.send_message_players_in_arena(sign_arena, minetest.colorize("#c8d692", sign_arena.name .. " > " .. pl_name))
|
|
end
|
|
end
|
|
|
|
local timer = minetest.get_node_timer(pos)
|
|
local arena_max_players = sign_arena.max_players * #sign_arena.teams
|
|
|
|
-- se la coda non è partita...
|
|
if not sign_arena.in_queue and not sign_arena.in_game then
|
|
|
|
local players_required = arena_lib.get_players_to_start_queue(sign_arena)
|
|
|
|
-- ...e ci sono abbastanza giocatori, parte il timer d'attesa
|
|
if players_required <= 0 then
|
|
sign_arena.in_queue = true
|
|
timer:start(mod_ref.settings.queue_waiting_time)
|
|
HUD_countdown(sign_arena, timer)
|
|
|
|
-- sennò aggiorno semplicemente la HUD
|
|
else
|
|
arena_lib.HUD_send_msg_all("hotbar", sign_arena, arena_lib.queue_format(sign_arena, S("Waiting for more players...")) ..
|
|
" (" .. players_required .. ")")
|
|
end
|
|
end
|
|
|
|
arena_lib.update_sign(sign_arena)
|
|
|
|
-- se raggiungo i giocatori massimi e la partita non è iniziata, accorcio eventualmente la durata
|
|
if sign_arena.players_amount == arena_max_players and sign_arena.in_queue then
|
|
if timer:get_timeout() - timer:get_elapsed() > 5 then
|
|
timer:stop()
|
|
timer:start(5)
|
|
end
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
-- quello che succede una volta che il timer raggiunge lo 0
|
|
on_timer = function(pos)
|
|
|
|
local mod = minetest.get_meta(pos):get_string("mod")
|
|
local arena_ID = minetest.get_meta(pos):get_int("arenaID")
|
|
local sign_arena = arena_lib.mods[mod].arenas[arena_ID]
|
|
|
|
sign_arena.in_queue = false
|
|
sign_arena.in_game = true
|
|
arena_lib.update_sign(sign_arena)
|
|
|
|
arena_lib.HUD_hide("all", sign_arena)
|
|
arena_lib.load_arena(mod, arena_ID)
|
|
|
|
return false
|
|
end,
|
|
})
|
|
|
|
|
|
|
|
--v------------------ LEGACY UPDATE, to remove in 5.0 -------------------v
|
|
minetest.override_item("default:sign_wall", {
|
|
|
|
on_punch = function(pos, node, puncher, pointed_thing)
|
|
|
|
local arenaID = minetest.get_meta(pos):get_int("arenaID")
|
|
if arenaID == 0 then return end
|
|
|
|
local lookdir = minetest.yaw_to_dir(puncher:get_look_horizontal())
|
|
minetest.swap_node(pos,{name = "arena_lib:sign", param2 = minetest.dir_to_wallmounted(lookdir)})
|
|
minetest.chat_send_player(puncher:get_player_name(), "Alakazam! We got a new sign here")
|
|
|
|
end,
|
|
|
|
})
|
|
--^------------------ LEGACY UPDATE, to remove in 5.0 -------------------^
|
|
|
|
|
|
|
|
function arena_lib.update_sign(arena)
|
|
|
|
local p_count = 0
|
|
local t_count = #arena.teams
|
|
|
|
-- non uso il getter perché dovrei richiamare 2 funzioni (ID e count)
|
|
for pl, stats in pairs(arena.players) do
|
|
p_count = p_count +1
|
|
end
|
|
|
|
signs_lib.update_sign(arena.sign, {text = [[
|
|
]] .. "\n\n" .. [[
|
|
]] .. arena.name .. "\n" .. [[
|
|
]] .. p_count .. "/".. arena.max_players * t_count .. "\n" .. [[
|
|
]] .. in_game_txt(arena) .. "\n" .. [[
|
|
|
|
]]})
|
|
end
|
|
|
|
|
|
|
|
-- es. Foresta | 3/4 | Il match inizierà a breve
|
|
function arena_lib.queue_format(arena, msg)
|
|
local arena_max_players = arena.max_players * #arena.teams
|
|
return arena.name .. " | " .. arena.players_amount .. "/" .. arena_max_players .. " | " .. msg
|
|
end
|
|
|
|
|
|
|
|
function arena_lib.get_players_to_start_queue(arena)
|
|
|
|
local arena_min_players = arena.min_players * #arena.teams
|
|
local players_required
|
|
|
|
if arena.teams_enabled then
|
|
|
|
players_required = 0
|
|
|
|
for _, amount in pairs(arena.players_amount_per_team) do
|
|
if arena.min_players - amount > 0 then
|
|
players_required = players_required + (arena.min_players - amount)
|
|
end
|
|
end
|
|
else
|
|
players_required = arena_min_players - arena.players_amount
|
|
end
|
|
|
|
return players_required
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
----------------------------------------------
|
|
---------------FUNZIONI LOCALI----------------
|
|
----------------------------------------------
|
|
|
|
function assign_team(mod_ref, arena, p_name)
|
|
|
|
local assigned_team_ID = 1
|
|
|
|
for i = 1, #arena.teams do
|
|
if arena.players_amount_per_team[i] < arena.players_amount_per_team[assigned_team_ID] then
|
|
assigned_team_ID = i
|
|
end
|
|
end
|
|
|
|
local p_team = arena.teams[assigned_team_ID].name
|
|
|
|
if minetest.get_modpath("parties") and parties.is_player_in_party(p_name) then
|
|
for _, pl_name in pairs(parties.get_party_members(p_name)) do
|
|
minetest.chat_send_player(pl_name, mod_ref.prefix .. S("You've joined team @1", minetest.colorize("#eea160", p_team)))
|
|
end
|
|
else
|
|
minetest.chat_send_player(p_name, mod_ref.prefix .. S("You've joined team @1", minetest.colorize("#eea160", p_team)))
|
|
end
|
|
|
|
return assigned_team_ID
|
|
end
|
|
|
|
|
|
|
|
function HUD_countdown(arena, timer)
|
|
|
|
if not arena.in_queue or not timer:is_started() then return end
|
|
|
|
local seconds = math.floor(timer:get_timeout() - timer:get_elapsed() + 0.51)
|
|
|
|
-- dai 5 secondi in giù il messaggio è stampato su broadcast e genero i team
|
|
if seconds <= 5 then
|
|
arena_lib.HUD_send_msg_all("broadcast", arena, S("The game begins in @1 seconds!", seconds), nil, "arenalib_countdown")
|
|
arena_lib.HUD_send_msg_all("hotbar", arena, arena_lib.queue_format(arena, S("Get ready!")))
|
|
else
|
|
arena_lib.HUD_send_msg_all("hotbar", arena, arena_lib.queue_format(arena, S("@1 seconds for the match to start", seconds)))
|
|
end
|
|
|
|
minetest.after(1, function()
|
|
HUD_countdown(arena, timer)
|
|
end)
|
|
end
|
|
|
|
|
|
|
|
function in_game_txt(arena)
|
|
local txt
|
|
|
|
-- it's not possible to translate them => https://gitlab.com/VanessaE/signs_lib/-/issues/9
|
|
if not arena.enabled then txt = "#dWIP"
|
|
elseif arena.in_queue then txt = "#2Queueing"
|
|
elseif arena.in_celebration then txt = "#4Terminating"
|
|
elseif arena.in_loading then txt = "#4Loading"
|
|
elseif arena.in_game then txt = "#4In progress"
|
|
|
|
else txt = "#3Waiting" end
|
|
|
|
return txt
|
|
end
|