2020-04-02 12:47:55 +02:00
----------------------------------------------
--------------GESTIONE STORAGE----------------
----------------------------------------------
2020-03-31 17:04:03 +02:00
2020-04-02 12:47:55 +02:00
local storage = minetest.get_mod_storage ( )
--storage:set_string("arenas", nil) -- PER RESETTARE LO STORAGE
2020-03-31 17:04:03 +02:00
if minetest.deserialize ( storage : get_string ( " arenas " ) ) ~= nil then
arena_lib.arenas = minetest.deserialize ( storage : get_string ( " arenas " ) )
end
2020-03-31 17:53:08 +02:00
2020-04-02 12:47:55 +02:00
----------------------------------------------
---------------DICHIARAZIONI------------------
----------------------------------------------
local function update_storage ( ) end
local function new_arena ( ) end
local function next_ID ( ) end
arena_lib = { arenas = { } }
2020-03-31 17:04:03 +02:00
local arenasID
2020-03-31 23:38:31 +02:00
local players_in_game = { } --KEY: player name, INDEX: arenaID
local players_in_queue = { } --KEY: player name, INDEX: arenaID
2020-03-31 17:04:03 +02:00
2020-04-01 01:36:07 +02:00
local arena_default_max_players = 2
local arena_default_min_players = 1
2020-03-31 17:04:03 +02:00
local arena_default_kill_cap = 10
2020-04-02 12:47:55 +02:00
local arena_default = {
2020-03-31 17:04:03 +02:00
name = " " ,
sign = { } ,
2020-03-31 23:38:31 +02:00
players = { } , --KEY: player name, INDEX: kills, deaths, killstreak
2020-03-31 17:04:03 +02:00
spawn_points = { } ,
max_players = arena_default_max_players ,
min_players = arena_default_min_players ,
kill_cap = arena_default_kill_cap ,
kill_leader = " " ,
in_queue = false ,
2020-04-02 12:47:55 +02:00
in_loading = false ,
2020-03-31 17:04:03 +02:00
in_game = false ,
in_celebration = false
}
2020-04-01 13:13:13 +02:00
local prefix = " [Arena_lib] "
local load_time = 3
local celebration_time = 3
2020-04-01 17:20:15 +02:00
local immunity_time = 3
2020-04-01 22:22:42 +02:00
local immunity_slot = 9 --people may have tweaked the slots, hence the custom parameter
2020-04-01 13:13:13 +02:00
2020-04-02 12:47:55 +02:00
-- call this in your mod to override the last block of values
2020-04-01 13:13:13 +02:00
function arena_lib . settings ( def )
if def.prefix then
prefix = def.prefix
end
if def.load_time then
load_time = def.load_time
end
if def.celebration_time then
celebration_time = def.celebration_time
end
2020-04-01 17:20:15 +02:00
if def.immunity_time then
immunity_time = def.immunity_time
end
2020-04-01 22:22:42 +02:00
if def.immunity_slot then
immunity_slot = def.immunity_slot
end
2020-04-01 13:13:13 +02:00
end
2020-04-01 12:35:15 +02:00
2020-04-02 12:47:55 +02:00
----------------------------------------------
---------------GESTIONE ARENA-----------------
----------------------------------------------
2020-03-31 17:04:03 +02:00
function arena_lib . create_arena ( sender , arena_name )
2020-04-02 12:47:55 +02:00
arenasID = next_ID ( )
2020-03-31 17:04:03 +02:00
-- controllo che non ci siano duplicati
if arenasID > 1 and arena_lib.get_arena_by_name ( arena_name ) ~= nil then
minetest.chat_send_player ( sender , minetest.colorize ( " #e6482e " , " [!] Esiste già un'arena con quel nome! " ) )
return end
-- creo l'arena e la rinomino, aggiornando anche lo storage
2020-04-02 12:47:55 +02:00
arena_lib.arenas [ arenasID ] = new_arena ( arena_default )
2020-03-31 17:04:03 +02:00
arena_lib.arenas [ arenasID ] . name = arena_name
2020-04-02 12:47:55 +02:00
update_storage ( )
2020-04-01 13:13:13 +02:00
minetest.chat_send_player ( sender , prefix .. " Arena " .. arena_name .. " creata con successo " )
2020-03-31 17:04:03 +02:00
end
function arena_lib . remove_arena ( sender , arena_name )
local id , arena = arena_lib.get_arena_by_name ( arena_name )
if not arena then minetest.chat_send_player ( sender , minetest.colorize ( " #e6482e " , " [!] Non c'è nessun'arena chiamata " .. arena_name .. " ! " ) )
return end
if arena.in_game then
minetest.chat_send_player ( sender , minetest.colorize ( " #e6482e " , " [!] Una partita è in corso nell'arena " .. arena_name .. " : impossibile rimuoverla " ) )
return end
--TODO: -chiedere conferma
-- rimozione cartello coi rispettivi metadati
2020-03-31 23:38:31 +02:00
if arena.sign ~= nil then
minetest.set_node ( arena.sign , { name = " air " } ) end
2020-03-31 17:04:03 +02:00
2020-04-01 13:13:13 +02:00
arena_lib.send_message_players_in_arena ( id , prefix .. " L'arena per la quale eri in coda è stata rimossa... :( " )
2020-03-31 17:04:03 +02:00
-- rimozione arena e aggiornamento storage
arena_lib.arenas [ id ] = nil
2020-04-02 12:47:55 +02:00
update_storage ( )
2020-04-01 13:13:13 +02:00
minetest.chat_send_player ( sender , prefix .. " Arena " .. arena_name .. " rimossa con successo " )
2020-03-31 23:38:31 +02:00
end
2020-04-02 12:47:55 +02:00
-- Gli spawn points si impostano prendendo la coordinata del giocatore che lancia il comando.
-- Non ci possono essere più spawn points del numero massimo di giocatori e non possono essere impostati in aria
function arena_lib . set_spawner ( name , arena_name )
local id , arena = arena_lib.get_arena_by_name ( arena_name )
if arena == nil then minetest.chat_send_player ( name , minetest.colorize ( " #e6482e " , " [!] Quest'arena non esiste! " ) )
return end
local spawn_points_count = arena_lib.get_arena_spawners_count ( id )
if spawn_points_count == arena.max_players then
minetest.chat_send_player ( name , minetest.colorize ( " #e6482e " , " [!] Gli spawn point non possono superare i giocatori massimi! Vuoi cancellarne alcuni con /quakeadmin delspawn <arena>? " ) )
return end
local pos = vector.floor ( minetest.get_player_by_name ( name ) : get_pos ( ) ) --tolgo i decimali per storare un int
local pos_Y_up = { x = pos.x , y = pos.y + 1 , z = pos.z } -- alzo Y di uno sennò tippa nel blocco
local pos_feet = { x = pos.x , y = pos.y - 1 , z = pos.z }
if minetest.get_node ( pos_feet ) . name == " air " then minetest.chat_send_player ( name , minetest.colorize ( " #e6482e " , " [!] Non puoi impostare spawn point nell'aria! " ) )
return end
for id , spawn in pairs ( arena.spawn_points ) do
if minetest.serialize ( pos_Y_up ) == minetest.serialize ( spawn ) then minetest.chat_send_player ( name , minetest.colorize ( " #e6482e " , " [!] C'è già uno spawn in questo punto! " ) )
return end
end
local new_spawn_ID = spawn_points_count + 1
arena.spawn_points [ new_spawn_ID ] = pos_Y_up
update_storage ( )
minetest.chat_send_player ( name , prefix .. " Spawn point " .. new_spawn_ID .. " impostato con successo " )
end
2020-03-31 17:04:03 +02:00
----------------------------------------------
2020-04-02 12:47:55 +02:00
--------------GESTIONE PARTITA-----------------
2020-03-31 17:04:03 +02:00
----------------------------------------------
-- per tutti i giocatori quando finisce la coda
function arena_lib . load_arena ( arena_ID )
local count = 1
local arena = arena_lib.arenas [ arena_ID ]
2020-04-02 12:47:55 +02:00
arena.in_loading = true
arena_lib.update_sign ( arena.sign , arena )
2020-03-31 17:04:03 +02:00
-- teletrasporto giocatori e sostituisco l'inventario
for pl_name , stats in pairs ( arena.players ) do
local player = minetest.get_player_by_name ( pl_name )
player : set_nametag_attributes ( { color = { a = 0 , r = 255 , g = 255 , b = 255 } } )
2020-04-01 12:35:15 +02:00
player : set_physics_override ( {
speed = 0 ,
} )
2020-03-31 17:04:03 +02:00
player : set_pos ( arena.spawn_points [ count ] )
player : get_inventory ( ) : set_list ( " main " , { } )
2020-03-31 23:38:31 +02:00
players_in_queue [ pl_name ] = nil
2020-03-31 17:04:03 +02:00
players_in_game [ pl_name ] = arena_ID -- registro giocatori nella tabella apposita
count = count + 1
end
2020-04-01 01:36:07 +02:00
arena_lib.on_load ( arena )
2020-04-01 13:13:13 +02:00
minetest.after ( load_time , function ( )
2020-04-01 12:35:15 +02:00
arena_lib.start_arena ( arena )
end )
2020-04-01 01:36:07 +02:00
2020-03-31 17:04:03 +02:00
end
2020-04-01 12:35:15 +02:00
2020-04-02 12:47:55 +02:00
-- per il player singolo a match iniziato
function arena_lib . join_arena ( p_name , arena_ID )
local player = minetest.get_player_by_name ( p_name )
player : set_pos ( arena_lib.get_random_spawner ( arena_ID ) )
player : get_inventory ( ) : set_list ( " main " , { } )
players_in_game [ pl_name ] = arena_ID
arena_lib.on_join ( p_name , arena_ID )
end
2020-04-01 12:35:15 +02:00
function arena_lib . start_arena ( arena )
2020-04-01 13:13:13 +02:00
2020-04-02 12:47:55 +02:00
arena.in_loading = false
arena.in_game = true
arena_lib.update_sign ( arena.sign , arena )
2020-04-01 13:13:13 +02:00
for pl_name , stats in pairs ( arena.players ) do
minetest.get_player_by_name ( pl_name ) : set_physics_override ( {
speed = 1 ,
jump = 1 ,
gravity = 1 ,
} )
end
2020-04-01 12:35:15 +02:00
arena_lib.on_start ( arena )
2020-03-31 17:04:03 +02:00
end
2020-04-02 12:47:55 +02:00
2020-03-31 17:04:03 +02:00
--a partita finita
function arena_lib . load_celebration ( arena_ID , winner_name )
local arena = arena_lib.arenas [ arena_ID ]
2020-04-02 12:47:55 +02:00
arena.in_celebration = true
2020-03-31 17:04:03 +02:00
arena_lib.update_sign ( arena.sign , arena )
for pl_name , stats in pairs ( arena.players ) do
local inv = minetest.get_player_by_name ( pl_name ) : get_inventory ( )
2020-04-02 12:47:55 +02:00
2020-04-01 17:20:15 +02:00
-- giocatori immortali
if not inv : contains_item ( " main " , " arena_lib.immunity " ) then
2020-04-01 22:22:42 +02:00
inv : set_stack ( " main " , immunity_slot , " arena_lib:immunity " )
2020-04-01 17:20:15 +02:00
end
2020-03-31 17:04:03 +02:00
minetest.get_player_by_name ( pl_name ) : set_nametag_attributes ( { color = { a = 255 , r = 255 , g = 255 , b = 255 } } )
2020-04-01 13:13:13 +02:00
minetest.chat_send_player ( pl_name , prefix .. winner_name .. " ha vinto la partita " )
2020-03-31 17:04:03 +02:00
end
2020-04-01 12:35:15 +02:00
arena_lib.on_celebration ( arena_ID , winner_name )
2020-03-31 17:04:03 +02:00
-- momento celebrazione
2020-04-01 13:13:13 +02:00
minetest.after ( celebration_time , function ( )
2020-04-01 01:01:01 +02:00
arena_lib.end_arena ( arena )
end )
2020-03-31 17:04:03 +02:00
end
function arena_lib . end_arena ( arena )
2020-04-02 00:09:35 +02:00
arena_lib.on_end ( arena )
2020-04-02 01:13:09 +02:00
arena.kill_leader = " "
2020-03-31 17:04:03 +02:00
for pl_name , stats in pairs ( arena.players ) do
arena.players [ pl_name ] = nil
players_in_game [ pl_name ] = nil
arena.in_celebration = false
arena.in_game = false
2020-04-01 17:20:15 +02:00
minetest.get_player_by_name ( pl_name ) : get_inventory ( ) : set_list ( " main " , { } )
2020-03-31 17:04:03 +02:00
--TODO: teleport lobby, metti variabile locale
end
2020-04-02 12:47:55 +02:00
arena_lib.update_sign ( arena.sign , arena )
2020-04-01 12:35:15 +02:00
end
2020-03-31 23:38:31 +02:00
function arena_lib . add_to_queue ( p_name , arena_ID )
players_in_queue [ p_name ] = arena_ID
end
2020-04-01 12:35:15 +02:00
2020-03-31 23:38:31 +02:00
function arena_lib . remove_from_queue ( p_name )
players_in_queue [ p_name ] = nil
end
2020-04-01 12:35:15 +02:00
2020-04-01 23:25:57 +02:00
function arena_lib . on_load ( arena )
2020-04-01 12:35:15 +02:00
--[[override this function on your mod if you wanna add more!
Just do : function arena_lib . on_load ( ) yourstuff end ] ]
end
2020-04-02 12:47:55 +02:00
function arena_lib . on_join ( p_name , arena_ID )
--[[override this function on your mod if you wanna add more!
Just do : function arena_lib . on_join ( ) yourstuff end ] ]
end
2020-04-01 23:25:57 +02:00
function arena_lib . on_start ( arena )
2020-04-01 12:35:15 +02:00
--[[override this function on your mod if you wanna add more!
Just do : function arena_lib . on_load ( ) yourstuff end ] ]
end
2020-04-01 23:25:57 +02:00
function arena_lib . on_celebration ( arena_ID , winner_name )
2020-04-01 12:35:15 +02:00
--[[override this function on your mod if you wanna add more!
Just do : function arena_lib . on_celebration ( ) yourstuff end ] ]
end
2020-04-01 23:25:57 +02:00
function arena_lib . on_end ( arena )
2020-04-01 12:35:15 +02:00
--[[override this function on your mod if you wanna add more!
Just do : function arena_lib . on_end ( ) yourstuff end ] ]
end
2020-04-01 13:13:13 +02:00
2020-03-31 17:04:03 +02:00
----------------------------------------------
--------------------UTILS---------------------
----------------------------------------------
2020-04-01 13:13:13 +02:00
function arena_lib . is_player_in_arena ( p_name )
if not players_in_game [ p_name ] then return false
else return true end
end
function arena_lib . is_player_in_queue ( p_name )
if not players_in_queue [ p_name ] then return false
else return true end
end
2020-03-31 17:04:03 +02:00
function arena_lib . remove_player_from_arena ( p_name )
local arena_ID = players_in_game [ p_name ]
2020-04-02 12:47:55 +02:00
local arena = arena_lib.arenas [ arena_ID ]
if arena == nil then return end
2020-03-31 17:04:03 +02:00
2020-04-02 12:47:55 +02:00
arena.players [ p_name ] = nil
2020-03-31 17:04:03 +02:00
players_in_game [ p_name ] = nil
2020-04-01 01:01:01 +02:00
players_in_queue [ p_name ] = nil
2020-04-01 13:13:13 +02:00
arena_lib.send_message_players_in_arena ( arena_ID , prefix .. p_name .. " ha abbandonato la partita " )
2020-03-31 17:04:03 +02:00
2020-04-02 12:47:55 +02:00
if arena.get_arena_players_count ( arena_ID ) == 1 then
arena.send_message_players_in_arena ( arena_ID , prefix .. " Hai vinto la partita per troppi pochi giocatori " )
end
2020-03-31 17:04:03 +02:00
end
2020-04-01 13:13:13 +02:00
2020-03-31 17:04:03 +02:00
function arena_lib . send_message_players_in_arena ( arena_ID , msg )
for pl_name , stats in pairs ( arena_lib.arenas [ arena_ID ] . players ) do
2020-03-31 23:38:31 +02:00
minetest.chat_send_player ( pl_name , msg ) end
2020-03-31 17:04:03 +02:00
end
2020-04-01 13:13:13 +02:00
2020-03-31 17:04:03 +02:00
function arena_lib . calc_kill_leader ( arena , killer )
2020-04-01 01:01:01 +02:00
if arena.kill_leader == " " then arena.kill_leader = killer return end
if arena.players [ killer ] . kills > arena.players [ arena.kill_leader ] . kills then
2020-03-31 23:38:31 +02:00
arena.kill_leader = killer end
2020-03-31 17:04:03 +02:00
end
2020-04-01 13:13:13 +02:00
2020-03-31 23:38:31 +02:00
function arena_lib . immunity ( player )
2020-04-01 17:20:15 +02:00
local immunity_item = ItemStack ( " arena_lib:immunity " )
local inv = player : get_inventory ( )
2020-03-31 23:38:31 +02:00
2020-04-01 22:22:42 +02:00
inv : set_stack ( " main " , immunity_slot , immunity_item )
2020-03-31 23:38:31 +02:00
minetest.after ( immunity_time , function ( )
2020-04-01 17:20:15 +02:00
if player == nil then return end -- they may disconnect
if inv : contains_item ( " main " , immunity_item ) then
inv : remove_item ( " main " , immunity_item )
2020-03-31 23:38:31 +02:00
end
end )
end
2020-04-01 13:13:13 +02:00
2020-03-31 17:04:03 +02:00
----------------------------------------------
-----------------GETTERS----------------------
----------------------------------------------
function arena_lib . get_arena_by_name ( arena_name )
for id , arena in pairs ( arena_lib.arenas ) do
if arena.name == arena_name then
return id , arena end
end
end
function arena_lib . get_arenaID_by_player ( p_name )
return players_in_game [ p_name ]
end
2020-03-31 23:38:31 +02:00
function arena_lib . get_queueID_by_player ( p_name )
return players_in_queue [ p_name ]
end
2020-03-31 17:04:03 +02:00
function arena_lib . get_arena_players_count ( arena_ID )
local count = 0
local arena = arena_lib.arenas [ arena_ID ]
2020-04-02 12:47:55 +02:00
for pl_name , stats in pairs ( arena.players ) do
2020-03-31 17:04:03 +02:00
count = count + 1
end
return count
end
function arena_lib . get_arena_spawners_count ( arena_ID )
return table.maxn ( arena_lib.arenas [ arena_ID ] . spawn_points )
end
function arena_lib . get_random_spawner ( arena_ID )
return arena_lib.arenas [ arena_ID ] . spawn_points [ math.random ( 1 , arena_lib.get_arena_spawners_count ( arena_ID ) ) ]
end
2020-03-31 23:38:31 +02:00
2020-04-01 22:22:42 +02:00
function arena_lib . get_immunity_slot ( )
return immunity_slot
end
2020-03-31 23:38:31 +02:00
----------------------------------------------
-----------------SETTERS----------------------
----------------------------------------------
2020-04-02 12:47:55 +02:00
-- nothing to see here ¯\_(ツ)_/¯
2020-04-01 17:20:15 +02:00
2020-03-31 23:38:31 +02:00
----------------------------------------------
---------------FUNZIONI LOCALI----------------
----------------------------------------------
2020-03-31 17:04:03 +02:00
2020-04-02 12:47:55 +02:00
function update_storage ( )
storage : set_string ( " arenas " , minetest.serialize ( arena_lib.arenas ) )
end
2020-03-31 17:04:03 +02:00
--[[ Dato che in Lua non è possibile istanziare le tabelle copiandole, bisogna istanziare ogni campo in una nuova tabella.
Ricorsivo per le sottotabelle . Codice da => http : // lua - users.org / wiki / CopyTable ] ]
2020-04-02 12:47:55 +02:00
function new_arena ( orig )
2020-03-31 17:04:03 +02:00
local orig_type = type ( orig )
local copy
if orig_type == ' table ' then
copy = { }
for orig_key , orig_value in next , orig , nil do
2020-04-02 12:47:55 +02:00
copy [ new_arena ( orig_key ) ] = new_arena ( orig_value )
2020-03-31 17:04:03 +02:00
end
2020-04-02 12:47:55 +02:00
setmetatable ( copy , new_arena ( getmetatable ( orig ) ) )
2020-03-31 17:04:03 +02:00
else -- number, string, boolean, etc
copy = orig
end
return copy
end
2020-04-02 12:47:55 +02:00
2020-03-31 17:04:03 +02:00
--[[ l'ID di base parte da 1 (n+1) per non generare errori, tipo "if arenaID == 0" al verificare se non esiste.
In una sequenza 0 , 1 , 2 , 3 se si rimuove " 2 " e si aggiunge un nuovo ID perciò si avrà 0 , 1 , 3 , 4 ] ]
2020-04-02 12:47:55 +02:00
function next_ID ( )
2020-03-31 17:04:03 +02:00
local n = 0
for id , arena in pairs ( arena_lib.arenas ) do
if id > n then n = id end
end
return n + 1
end