2020-04-02 18:38:18 +02:00
arena_lib = { }
2020-04-15 02:18:56 +02:00
arena_lib.mods = { }
2020-04-02 18:38:18 +02:00
2020-04-16 00:56:51 +02:00
local hub_spawn_point = { x = 0 , y = 20 , z = 0 }
2020-04-02 18:38:18 +02:00
2020-04-17 15:27:36 +02:00
local S = minetest.get_translator ( " arena_lib " )
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 ( )
2020-04-16 13:17:05 +02:00
--storage:set_string("mods", nil) -- PER RESETTARE LO STORAGE
2020-04-15 02:18:56 +02:00
2020-04-18 16:25:58 +02:00
--------------LEGACY START----------------
-- [!!!] for arena_lib 2.1.0 and lesser: it automatically converts your old arenas
-- into the new storage ystem. Please start your server at least once if you wanna
-- keep them as this will be removed in the who-knows-exactly-when upcoming 3.0.0
local function legacy_storage_conversion ( )
local old_table = minetest.deserialize ( storage : get_string ( " mods " ) )
if old_table == nil then return end
for mod , properties in pairs ( old_table ) do
2020-04-16 13:17:05 +02:00
for id , arena in pairs ( properties.arenas ) do
2020-04-15 02:18:56 +02:00
2020-04-18 16:25:58 +02:00
--salvo ogni arena in una stringa a parte
local entry = mod .. " . " .. id
storage : set_string ( entry , minetest.serialize ( arena ) )
2020-04-15 02:18:56 +02:00
end
2020-04-18 16:25:58 +02:00
-- svuoto le arene per non salvarle insieme alla mod
arena_lib.mods [ mod ] = old_table [ mod ]
arena_lib.mods [ mod ] . arenas = { }
-- salvo la mod in una stringa a parte
storage : set_string ( mod , minetest.serialize ( arena_lib.mods [ mod ] ) )
2020-04-03 12:57:21 +02:00
end
2020-04-18 16:25:58 +02:00
--svuoto il vecchio storage
storage : set_string ( " mods " , " " )
end
if minetest.deserialize ( storage : get_string ( " mods " ) ) ~= nil then
legacy_storage_conversion ( )
2020-03-31 17:04:03 +02:00
end
2020-04-18 16:25:58 +02:00
--------------LEGACY END----------------
2020-03-31 17:53:08 +02:00
2020-04-02 12:47:55 +02:00
----------------------------------------------
---------------DICHIARAZIONI------------------
----------------------------------------------
2020-04-18 16:25:58 +02:00
local function init_storage ( ) end
2020-04-02 12:47:55 +02:00
local function update_storage ( ) end
local function new_arena ( ) end
local function next_ID ( ) end
2020-04-16 13:17:05 +02:00
local players_in_game = { } --KEY: player name, INDEX: {mod, arenaID}
local players_in_queue = { } --KEY: player name, INDEX: {mod, arenaID}
2020-03-31 17:04:03 +02:00
2020-04-02 13:31:11 +02:00
local arena_default_max_players = 4
local arena_default_min_players = 2
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 ,
2020-04-02 23:24:35 +02:00
in_celebration = false ,
enabled = false
2020-03-31 17:04:03 +02:00
}
2020-04-01 13:13:13 +02:00
2020-04-15 13:14:30 +02:00
-- per inizializzare. Da lanciare all'inizio di ogni mod
2020-04-16 00:56:51 +02:00
function arena_lib . initialize ( mod )
2020-04-15 13:14:30 +02:00
2020-04-18 16:25:58 +02:00
init_storage ( mod )
2020-04-15 13:14:30 +02:00
--Se esiste già in memoria, ignora il resto
2020-04-16 00:56:51 +02:00
if arena_lib.mods [ mod ] ~= nil then return end
2020-04-15 13:14:30 +02:00
2020-04-16 00:56:51 +02:00
arena_lib.mods [ mod ] = { }
arena_lib.mods [ mod ] . arenas = { } -- KEY: (int) arenaID , VALUE: (table) arena properties
arena_lib.mods [ mod ] . arenasID = 1 -- we start counting from 1, not 0
2020-04-15 13:14:30 +02:00
end
2020-04-15 02:18:56 +02:00
-- call this in your mod to override the default parameters
2020-04-18 16:25:58 +02:00
function arena_lib . settings ( mod , def )
2020-04-15 02:18:56 +02:00
2020-04-18 16:25:58 +02:00
local mod_ref = arena_lib.mods [ mod ]
2020-04-01 13:13:13 +02:00
2020-04-15 02:18:56 +02:00
--default parameters
2020-04-16 00:56:51 +02:00
mod_ref.prefix = " [Arena_lib] "
mod_ref.hub_spawn_point = { x = 0 , y = 20 , z = 0 }
mod_ref.load_time = 3 --time in the loading phase (the pre-match)
mod_ref.celebration_time = 3 --time in the celebration phase
mod_ref.immunity_time = 3
mod_ref.immunity_slot = 9 --people may have tweaked the slots, hence the custom parameter
2020-04-18 16:25:58 +02:00
--mod_ref.properties = {}
--mod_ref.temp_properties = {}
2020-04-01 13:13:13 +02:00
if def.prefix then
2020-04-16 00:56:51 +02:00
mod_ref.prefix = def.prefix
2020-04-01 13:13:13 +02:00
end
2020-04-03 14:49:16 +02:00
if def.hub_spawn_point then
2020-04-16 00:56:51 +02:00
mod_ref.hub_spawn_point = def.hub_spawn_point
2020-04-03 14:49:16 +02:00
end
2020-04-01 13:13:13 +02:00
if def.load_time then
2020-04-16 00:56:51 +02:00
mod_ref.load_time = def.load_time
2020-04-01 13:13:13 +02:00
end
if def.celebration_time then
2020-04-16 00:56:51 +02:00
mod_ref.celebration_time = def.celebration_time
2020-04-01 13:13:13 +02:00
end
2020-04-01 17:20:15 +02:00
if def.immunity_time then
2020-04-16 00:56:51 +02:00
mod_ref.immunity_time = def.immunity_time
2020-04-01 17:20:15 +02:00
end
2020-04-01 22:22:42 +02:00
if def.immunity_slot then
2020-04-16 00:56:51 +02:00
mod_ref.immunity_slot = def.immunity_slot
2020-04-01 22:22:42 +02:00
end
2020-04-18 16:25:58 +02:00
storage : set_string ( mod , minetest.serialize ( mod_ref ) )
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-04-15 15:17:12 +02:00
function arena_lib . create_arena ( sender , mod , arena_name , min_players , max_players )
2020-03-31 17:04:03 +02:00
2020-04-15 15:17:12 +02:00
local mod_ref = arena_lib.mods [ mod ]
mod_ref.arenasID = next_ID ( mod_ref )
2020-03-31 17:04:03 +02:00
-- controllo che non ci siano duplicati
2020-04-15 15:17:12 +02:00
if mod_ref.arenasID > 1 and arena_lib.get_arena_by_name ( mod , arena_name ) ~= nil then
2020-04-17 15:27:36 +02:00
minetest.chat_send_player ( sender , minetest.colorize ( " #e6482e " , S ( " [!] An arena with that name exists already! " ) ) )
2020-03-31 17:04:03 +02:00
return end
2020-04-15 13:14:30 +02:00
-- creo l'arena
2020-04-15 15:17:12 +02:00
mod_ref.arenas [ mod_ref.arenasID ] = new_arena ( arena_default )
2020-04-15 13:14:30 +02:00
2020-04-15 15:17:12 +02:00
local arena = mod_ref.arenas [ mod_ref.arenasID ]
2020-04-15 13:14:30 +02:00
-- sovrascrivo con i parametri della funzione
arena.name = arena_name
2020-04-07 23:16:31 +02:00
if min_players and max_players then
2020-04-15 13:14:30 +02:00
arena.min_players = min_players
arena.max_players = max_players
2020-04-07 23:16:31 +02:00
end
2020-04-15 13:14:30 +02:00
-- aggiungo allo storage
2020-04-18 16:25:58 +02:00
update_storage ( false , mod , mod_ref.arenasID , arena )
2020-04-18 17:20:26 +02:00
--aggiorno l'ID globale nello storage
storage : set_string ( mod , minetest.serialize ( mod_ref ) )
2020-04-15 13:14:30 +02:00
2020-04-17 15:27:36 +02:00
minetest.chat_send_player ( sender , mod_ref.prefix .. S ( " Arena @1 succesfully created " , arena_name ) )
2020-03-31 17:04:03 +02:00
end
2020-04-15 15:17:12 +02:00
function arena_lib . remove_arena ( sender , mod , arena_name )
2020-03-31 17:04:03 +02:00
2020-04-15 15:17:12 +02:00
local id , arena = arena_lib.get_arena_by_name ( mod , arena_name )
2020-03-31 17:04:03 +02:00
2020-04-17 15:27:36 +02:00
if not arena then
minetest.chat_send_player ( sender , minetest.colorize ( " #e6482e " , S ( " [!] There is no arena named @1! " , arena_name ) ) )
return end
2020-03-31 17:04:03 +02:00
if arena.in_game then
2020-04-17 15:27:36 +02:00
minetest.chat_send_player ( sender , minetest.colorize ( " #e6482e " , S ( " [!] There is an ongoing match inside the arena @1: impossible to remove! " , arena_name ) ) )
return end
2020-03-31 17:04:03 +02:00
--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-15 15:17:12 +02:00
local mod_ref = arena_lib.mods [ mod ]
2020-04-17 21:04:37 +02:00
arena_lib.send_message_players_in_arena ( arena , mod_ref.prefix .. S ( " The arena you were queueing for has been removed... :( " ) )
2020-03-31 17:04:03 +02:00
-- rimozione arena e aggiornamento storage
2020-04-15 15:17:12 +02:00
mod_ref.arenas [ id ] = nil
2020-04-18 16:25:58 +02:00
update_storage ( true , mod , id , arena )
2020-04-17 21:04:37 +02:00
minetest.chat_send_player ( sender , mod_ref.prefix .. S ( " Arena @1 successfully removed " , arena_name ) )
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
2020-04-03 15:25:39 +02:00
-- Indicando lo spawner_ID, si andrà a sovrascrivere lo spawner con quell'ID se esiste
2020-04-15 15:17:12 +02:00
function arena_lib . set_spawner ( sender , mod , arena_name , spawner_ID )
2020-04-02 12:47:55 +02:00
2020-04-15 15:17:12 +02:00
local id , arena = arena_lib.get_arena_by_name ( mod , arena_name )
2020-04-02 12:47:55 +02:00
2020-04-15 15:17:12 +02:00
-- controllo se esiste l'arena
if arena == nil then
2020-04-17 21:04:37 +02:00
minetest.chat_send_player ( sender , minetest.colorize ( " #e6482e " , S ( " [!] This arena doesn't exist! " ) ) )
2020-04-15 15:17:12 +02:00
return end
2020-04-02 12:47:55 +02:00
2020-04-16 13:17:05 +02:00
local spawn_points_count = arena_lib.get_arena_spawners_count ( arena )
2020-04-02 12:47:55 +02:00
2020-04-18 17:22:52 +02:00
-- se provo a settare uno spawn point di troppo, annullo
2020-04-03 15:25:39 +02:00
if spawn_points_count == arena.max_players and spawner_ID == nil then
2020-04-17 21:04:37 +02:00
minetest.chat_send_player ( sender , minetest.colorize ( " #e6482e " , S ( " [!] Spawn points can't exceed the maximum number of players! If requested, you can overwrite them specifying the ID of the spawn as a parameter " ) ) )
2020-04-03 15:25:39 +02:00
return end
2020-04-15 15:17:12 +02:00
-- se l'ID dello spawner da sovrascrivere non corrisponde a nessun altro ID, annullo
2020-04-03 15:25:39 +02:00
if spawner_ID ~= nil and spawner_ID > spawn_points_count then
2020-04-17 21:04:37 +02:00
minetest.chat_send_player ( sender , minetest.colorize ( " #e6482e " , S ( " [!] No spawner with that ID to overwrite! " ) ) )
2020-04-03 15:25:39 +02:00
return end
2020-04-02 12:47:55 +02:00
2020-04-03 16:05:20 +02:00
local pos = vector.floor ( minetest.get_player_by_name ( sender ) : get_pos ( ) ) --tolgo i decimali per storare un int
2020-04-02 12:47:55 +02:00
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 }
2020-04-15 15:17:12 +02:00
-- se il blocco sotto i piedi è aria, annullo
if minetest.get_node ( pos_feet ) . name == " air " then
2020-04-17 21:04:37 +02:00
minetest.chat_send_player ( sender , minetest.colorize ( " #e6482e " , S ( " [!] You can't set the spawn point in the air! " ) ) )
2020-04-15 15:17:12 +02:00
return end
2020-04-02 12:47:55 +02:00
2020-04-15 15:17:12 +02:00
-- se c'è già uno spawner in quel punto, annullo
2020-04-02 12:47:55 +02:00
for id , spawn in pairs ( arena.spawn_points ) do
2020-04-17 21:04:37 +02:00
if minetest.serialize ( pos_Y_up ) == minetest.serialize ( spawn ) then minetest.chat_send_player ( sender , minetest.colorize ( " #e6482e " , S ( " [!] There's already a spawn in this point! " ) ) )
2020-04-02 12:47:55 +02:00
return end
end
2020-04-15 15:17:12 +02:00
local mod_ref = arena_lib.mods [ mod ]
-- sovrascrivo/creo lo spawnpoint
2020-04-03 15:25:39 +02:00
if spawner_ID ~= nil then
arena.spawn_points [ spawner_ID ] = pos_Y_up
2020-04-17 21:04:37 +02:00
minetest.chat_send_player ( sender , mod_ref.prefix .. S ( " Spawn point #@1 successfully overwritten " , spawner_ID ) )
2020-04-03 15:25:39 +02:00
else
arena.spawn_points [ spawn_points_count + 1 ] = pos_Y_up
2020-04-17 21:04:37 +02:00
minetest.chat_send_player ( sender , mod_ref.prefix .. S ( " Spawn point #@1 successfully set " , spawn_points_count + 1 ) )
2020-04-03 15:25:39 +02:00
end
2020-04-02 12:47:55 +02:00
2020-04-18 16:25:58 +02:00
update_storage ( false , mod , id , arena )
2020-04-02 12:47:55 +02:00
end
2020-04-15 15:17:12 +02:00
function arena_lib . enable_arena ( sender , mod , arena_ID )
2020-04-02 23:24:35 +02:00
2020-04-15 15:17:12 +02:00
local mod_ref = arena_lib.mods [ mod ]
local arena = mod_ref.arenas [ arena_ID ]
-- controllo se esiste l'arena
if not arena then
2020-04-17 21:04:37 +02:00
minetest.chat_send_player ( sender , minetest.colorize ( " #e6482e " , S ( " [!] There is no arena associated with this ID! " ) ) )
2020-04-15 15:17:12 +02:00
return end
2020-04-02 23:24:35 +02:00
2020-04-16 13:17:05 +02:00
-- check requisiti: spawner e cartello
if arena_lib.get_arena_spawners_count ( arena ) < arena.max_players then
2020-04-17 21:04:37 +02:00
minetest.chat_send_player ( sender , minetest.colorize ( " #e6482e " , S ( " [!] Insufficient spawners, the arena has been disabled! " ) ) )
2020-04-03 13:00:35 +02:00
arena.enabled = false
return end
2020-04-15 15:26:43 +02:00
if not arena.sign . x then
2020-04-17 21:04:37 +02:00
minetest.chat_send_player ( sender , minetest.colorize ( " #e6482e " , S ( " [!] Sign not set, the arena has been disabled! " ) ) )
2020-04-15 15:26:43 +02:00
arena.enabled = false
return end
2020-04-16 13:17:05 +02:00
-- abilito
2020-04-03 13:00:35 +02:00
arena.enabled = true
arena_lib.update_sign ( arena.sign , arena )
2020-04-18 16:25:58 +02:00
update_storage ( false , mod , arena_ID , arena )
2020-04-17 21:04:37 +02:00
minetest.chat_send_player ( sender , mod_ref.prefix .. S ( " Arena successfully enabled " ) )
2020-04-02 23:28:36 +02:00
2020-04-02 23:24:35 +02:00
end
2020-04-03 18:57:39 +02:00
2020-04-15 15:17:12 +02:00
function arena_lib . disable_arena ( sender , mod , arena_ID )
2020-04-03 18:57:39 +02:00
2020-04-15 15:17:12 +02:00
local mod_ref = arena_lib.mods [ mod ]
local arena = mod_ref.arenas [ arena_ID ]
2020-04-03 18:57:39 +02:00
2020-04-15 15:17:12 +02:00
-- controllo se esiste l'arena
2020-04-03 18:57:39 +02:00
if not arena then
2020-04-17 21:04:37 +02:00
minetest.chat_send_player ( sender , minetest.colorize ( " #e6482e " , S ( " [!] There is no arena associated with this ID! " ) ) )
2020-04-03 18:57:39 +02:00
return end
2020-04-15 15:17:12 +02:00
-- se è già disabilitata, annullo
2020-04-03 18:57:39 +02:00
if not arena.enabled then
2020-04-17 21:04:37 +02:00
minetest.chat_send_player ( sender , minetest.colorize ( " #e6482e " , S ( " [!] The arena is already disabled " ) ) )
2020-04-03 18:57:39 +02:00
return end
2020-04-15 15:17:12 +02:00
-- se una partita è in corso, annullo
2020-04-03 18:57:39 +02:00
if arena.in_loading or arena.in_game or arena.in_celebration then
2020-04-17 21:04:37 +02:00
minetest.chat_send_player ( sender , minetest.colorize ( " #e6482e " , S ( " [!] You can't disable an arena during an ongoing game! " ) ) )
2020-04-03 18:57:39 +02:00
return end
2020-04-15 15:17:12 +02:00
-- se c'è gente rimasta è in coda: annullo la coda e li avviso della disabilitazione
2020-04-03 18:57:39 +02:00
for pl_name , stats in pairs ( arena.players ) do
players_in_queue [ pl_name ] = nil
arena.players [ pl_name ] = nil
2020-04-15 15:17:12 +02:00
arena.in_queue = false
2020-04-17 21:04:37 +02:00
minetest.chat_send_player ( pl_name , minetest.colorize ( " #e6482e " , S ( " [!] The arena you were queueing for has been disabled! " ) ) )
2020-04-03 18:57:39 +02:00
end
2020-04-16 13:17:05 +02:00
-- disabilito
2020-04-03 18:57:39 +02:00
arena.enabled = false
arena_lib.update_sign ( arena.sign , arena )
2020-04-18 16:25:58 +02:00
update_storage ( false , mod , arena_ID , arena )
2020-04-17 21:04:37 +02:00
minetest.chat_send_player ( sender , mod_ref.prefix .. S ( " Arena @1 successfully disabled " , arena.name ) )
2020-04-03 18:57:39 +02:00
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
2020-04-16 00:56:51 +02:00
function arena_lib . load_arena ( mod , arena_ID )
2020-03-31 17:04:03 +02:00
local count = 1
2020-04-16 00:56:51 +02:00
local mod_ref = arena_lib.mods [ mod ]
local arena = mod_ref.arenas [ arena_ID ]
2020-03-31 17:04:03 +02:00
2020-04-02 12:47:55 +02:00
arena.in_loading = true
arena_lib.update_sign ( arena.sign , arena )
2020-04-16 00:56:51 +02:00
-- teletrasporto giocatori, li blocco sul posto, nascondo i nomi e svuoto l'inventario
2020-03-31 17:04:03 +02:00
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-04-16 13:17:05 +02:00
players_in_game [ pl_name ] = { minigame = mod , arenaID = arena_ID } -- registro giocatori nella tabella apposita
2020-03-31 17:04:03 +02:00
count = count + 1
end
2020-04-01 01:36:07 +02:00
2020-04-16 00:56:51 +02:00
-- eventuale codice aggiuntivo
if mod_ref.on_load then
mod_ref.on_load ( arena )
end
2020-04-01 01:36:07 +02:00
2020-04-16 00:56:51 +02:00
-- inizio l'arena dopo tot secondi
minetest.after ( mod_ref.load_time , function ( )
arena_lib.start_arena ( mod_ref , arena )
2020-04-01 12:35:15 +02:00
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-16 00:56:51 +02:00
function arena_lib . start_arena ( mod_ref , 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-16 00:56:51 +02:00
-- eventuale codice aggiuntivo
if mod_ref.on_start then
mod_ref.on_start ( arena )
end
2020-03-31 17:04:03 +02:00
end
2020-04-02 12:47:55 +02:00
2020-04-16 00:56:51 +02:00
-- per il player singolo a match iniziato
function arena_lib . join_arena ( mod , p_name , arena_ID )
2020-04-16 13:17:05 +02:00
local mod_ref = arena_lib.mods [ mod ]
2020-04-16 00:56:51 +02:00
local player = minetest.get_player_by_name ( p_name )
local arena = mod_ref.arenas [ arena_ID ]
player : set_nametag_attributes ( { color = { a = 0 , r = 255 , g = 255 , b = 255 } } )
player : get_inventory ( ) : set_list ( " main " , { } )
2020-04-16 15:51:20 +02:00
player : set_pos ( arena_lib.get_random_spawner ( arena ) )
2020-04-16 13:17:05 +02:00
players_in_game [ p_name ] = { minigame = mod , arenaID = arena_ID }
2020-04-16 00:56:51 +02:00
-- eventuale codice aggiuntivo
if mod_ref.on_join then
mod_ref.on_join ( p_name , arena )
end
end
2020-03-31 17:04:03 +02:00
--a partita finita
2020-04-16 00:56:51 +02:00
function arena_lib . load_celebration ( mod , arena , winner_name )
2020-03-31 17:04:03 +02:00
2020-04-16 00:56:51 +02:00
local mod_ref = arena_lib.mods [ mod ]
2020-03-31 17:04:03 +02:00
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
2020-04-16 00:56:51 +02:00
if not inv : contains_item ( " main " , " arena_lib:immunity " ) then
2020-04-16 15:51:20 +02:00
inv : set_stack ( " main " , mod_ref.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-17 21:04:37 +02:00
minetest.chat_send_player ( pl_name , mod_ref.prefix .. S ( " @1 wins the game " , winner_name ) )
2020-03-31 17:04:03 +02:00
end
2020-04-16 00:56:51 +02:00
-- eventuale codice aggiuntivo
if mod_ref.on_celebration then
mod_ref.on_celebration ( arena , winner_name )
end
2020-03-31 17:04:03 +02:00
2020-04-16 00:56:51 +02:00
-- l'arena finisce dopo tot secondi
2020-04-16 15:51:20 +02:00
minetest.after ( mod_ref.celebration_time , function ( )
2020-04-16 00:56:51 +02:00
arena_lib.end_arena ( mod_ref , arena )
2020-04-01 01:01:01 +02:00
end )
2020-03-31 17:04:03 +02:00
end
2020-04-16 00:56:51 +02:00
function arena_lib . end_arena ( mod_ref , arena )
2020-03-31 17:04:03 +02:00
2020-04-02 01:13:09 +02:00
arena.kill_leader = " "
2020-04-03 12:16:04 +02:00
local players = { }
2020-04-15 02:24:23 +02:00
arena.in_celebration = false
arena.in_game = false
2020-03-31 17:04:03 +02:00
for pl_name , stats in pairs ( arena.players ) do
2020-04-03 12:16:04 +02:00
players [ pl_name ] = stats
2020-03-31 17:04:03 +02:00
arena.players [ pl_name ] = nil
2020-04-16 13:17:05 +02:00
players_in_game [ pl_name ] = nil
2020-03-31 17:04:03 +02:00
2020-04-15 02:24:23 +02:00
local player = minetest.get_player_by_name ( pl_name )
2020-04-01 17:20:15 +02:00
2020-04-03 14:49:16 +02:00
player : get_inventory ( ) : set_list ( " main " , { } )
2020-04-16 00:56:51 +02:00
player : set_pos ( mod_ref.hub_spawn_point )
2020-03-31 17:04:03 +02:00
end
2020-04-03 14:49:16 +02:00
2020-04-02 12:47:55 +02:00
arena_lib.update_sign ( arena.sign , arena )
2020-04-16 00:56:51 +02:00
-- eventuale codice aggiuntivo
if mod_ref.on_end then
mod_ref.on_end ( arena , players )
end
2020-04-01 12:35:15 +02:00
end
2020-04-16 13:17:05 +02:00
function arena_lib . add_to_queue ( p_name , mod , arena_ID )
players_in_queue [ p_name ] = { minigame = mod , arenaID = arena_ID }
2020-03-31 23:38:31 +02:00
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 13:13:13 +02:00
2020-03-31 17:04:03 +02:00
----------------------------------------------
--------------------UTILS---------------------
----------------------------------------------
2020-04-16 00:56:51 +02:00
--TODO: rename_arena
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 )
2020-04-16 13:17:05 +02:00
local mod , arena_ID
-- se non è in partita né in coda, annullo
2020-04-16 15:51:20 +02:00
if arena_lib.is_player_in_arena ( p_name ) then
mod = players_in_game [ p_name ] . minigame
arena_ID = players_in_game [ p_name ] . arenaID
elseif arena_lib.is_player_in_queue ( p_name ) then
mod = players_in_queue [ p_name ] . minigame
arena_ID = players_in_queue [ p_name ] . arenaID
2020-04-16 13:17:05 +02:00
else return end
2020-04-04 17:47:07 +02:00
2020-04-16 13:17:05 +02:00
local mod_ref = arena_lib.mods [ mod ]
local arena = mod_ref.arenas [ arena_ID ]
2020-04-02 12:47:55 +02:00
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-03 13:10:50 +02:00
arena_lib.update_sign ( arena.sign , arena )
2020-04-17 21:04:37 +02:00
arena_lib.send_message_players_in_arena ( arena , mod_ref.prefix .. S ( " @1 has left the game " , p_name ) )
2020-03-31 17:04:03 +02:00
2020-04-16 13:17:05 +02:00
-- se l'arena era in coda e ora ci son troppi pochi giocatori, annullo la coda
2020-04-04 17:47:07 +02:00
if arena.in_queue then
local timer = minetest.get_node_timer ( arena.sign )
2020-04-13 21:26:06 +00:00
if arena_lib.get_arena_players_count ( arena ) < arena.min_players then
2020-04-04 17:47:07 +02:00
timer : stop ( )
arena.in_queue = false
2020-04-17 21:04:37 +02:00
arena_lib.send_message_players_in_arena ( arena , mod_ref.prefix .. S ( " The queue has been cancelled due to not enough players " ) )
2020-04-04 17:47:07 +02:00
end
2020-04-16 13:17:05 +02:00
-- se invece erano rimasti solo 2 giocatori in partita, l'altro vince
2020-04-13 21:26:06 +00:00
elseif arena_lib.get_arena_players_count ( arena ) == 1 then
2020-04-04 17:47:07 +02:00
2020-04-17 21:04:37 +02:00
arena_lib.send_message_players_in_arena ( arena , mod_ref.prefix .. S ( " You win the game due to not enough players " ) )
2020-04-03 12:16:04 +02:00
for pl_name , stats in pairs ( arena.players ) do
2020-04-16 13:17:05 +02:00
arena_lib.load_celebration ( mod , arena , pl_name )
2020-04-03 12:16:04 +02:00
end
2020-04-02 12:47:55 +02:00
end
2020-04-04 17:47:07 +02:00
2020-03-31 17:04:03 +02:00
end
2020-04-01 13:13:13 +02:00
2020-04-13 21:26:06 +00:00
function arena_lib . send_message_players_in_arena ( arena , msg )
for pl_name , stats in pairs ( arena.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-16 13:17:05 +02:00
local immunity_item = ItemStack ( " arena_lib:immunity " )
2020-04-01 17:20:15 +02:00
local inv = player : get_inventory ( )
2020-04-16 15:51:20 +02:00
local p_name = player : get_player_name ( )
local mod_ref = arena_lib.mods [ arena_lib.get_mod_by_player ( p_name ) ]
2020-03-31 23:38:31 +02:00
2020-04-16 13:17:05 +02:00
inv : set_stack ( " main " , mod_ref.immunity_slot , immunity_item )
2020-03-31 23:38:31 +02:00
2020-04-16 15:51:20 +02:00
minetest.after ( mod_ref.immunity_time , function ( )
2020-04-16 13:17:05 +02:00
if player == nil then return end -- they might have disconnected
2020-04-01 17:20:15 +02:00
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----------------------
----------------------------------------------
2020-04-16 13:17:05 +02:00
function arena_lib . get_hub_spawn_point ( )
2020-04-16 00:56:51 +02:00
return hub_spawn_point
2020-04-03 14:49:16 +02:00
end
2020-04-15 02:18:56 +02:00
function arena_lib . get_arena_by_name ( mod , arena_name )
2020-03-31 17:04:03 +02:00
2020-04-15 13:14:30 +02:00
for id , arena in pairs ( arena_lib.mods [ mod ] . arenas ) do
2020-03-31 17:04:03 +02:00
if arena.name == arena_name then
return id , arena end
end
end
2020-04-03 14:49:16 +02:00
2020-04-14 12:13:10 +02:00
function arena_lib . get_players_in_game ( )
return players_in_game
end
2020-04-16 13:17:05 +02:00
function arena_lib . get_mod_by_player ( p_name )
if arena_lib.is_player_in_arena ( p_name ) then
return players_in_game [ p_name ] . minigame
else
return players_in_queue [ p_name ] . minigame
end
end
function arena_lib . get_arena_by_player ( p_name )
2020-04-16 13:21:37 +02:00
local mod , arenaID
2020-04-16 13:17:05 +02:00
2020-04-16 15:51:20 +02:00
if arena_lib.is_player_in_arena ( p_name ) then -- è in partita
mod = players_in_game [ p_name ] . minigame
arenaID = players_in_game [ p_name ] . arenaID
else -- è in coda
mod = players_in_queue [ p_name ] . minigame
arenaID = players_in_queue [ p_name ] . arenaID
2020-04-16 13:17:05 +02:00
end
2020-04-16 15:51:20 +02:00
if not mod then return end -- se non è né l'uno né l'altro, annullo
return arena_lib.mods [ mod ] . arenas [ arenaID ]
2020-04-16 13:17:05 +02:00
end
2020-03-31 17:04:03 +02:00
function arena_lib . get_arenaID_by_player ( p_name )
2020-04-16 13:17:05 +02:00
return players_in_game [ p_name ] . arenaID
2020-03-31 17:04:03 +02:00
end
2020-04-03 14:49:16 +02:00
2020-03-31 23:38:31 +02:00
function arena_lib . get_queueID_by_player ( p_name )
2020-04-16 13:17:05 +02:00
return players_in_queue [ p_name ] . arenaID
2020-03-31 23:38:31 +02:00
end
2020-04-03 14:49:16 +02:00
2020-04-13 21:26:06 +00:00
function arena_lib . get_arena_players_count ( arena )
2020-03-31 17:04:03 +02:00
local count = 0
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
2020-04-03 14:49:16 +02:00
2020-04-16 13:17:05 +02:00
function arena_lib . get_arena_spawners_count ( arena )
return table.maxn ( arena.spawn_points )
2020-03-31 17:04:03 +02:00
end
2020-04-03 14:49:16 +02:00
2020-04-16 13:17:05 +02:00
function arena_lib . get_random_spawner ( arena )
return arena.spawn_points [ math.random ( 1 , table.maxn ( arena.spawn_points ) ) ]
2020-03-31 17:04:03 +02:00
end
2020-03-31 23:38:31 +02:00
2020-04-16 13:17:05 +02:00
function arena_lib . get_immunity_slot ( mod )
return arena_lib.mods [ mod ] . immunity_slot
2020-04-01 22:22:42 +02:00
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-18 16:25:58 +02:00
function init_storage ( mod )
-- aggiungo la mod
local mod_ref = minetest.deserialize ( storage : get_string ( mod ) )
if mod_ref == nil then return end
arena_lib.mods [ mod ] = mod_ref
-- aggiungo le arene
local i = 1
2020-04-18 17:20:26 +02:00
for i = 1 , arena_lib.mods [ mod ] . arenasID do
2020-04-18 16:25:58 +02:00
local arena_str = storage : get_string ( mod .. " . " .. i )
-- se c'è una stringa con quell'ID, aggiungo l'arena e aggiorno il cartello con associato quell'ID
if arena_str ~= " " then
local arena = minetest.deserialize ( arena_str )
arena_lib.mods [ mod ] . arenas [ i ] = arena
--signs_lib ha bisogno di un attimo per caricare sennò tira errore
minetest.after ( 0.01 , function ( )
if arena.sign . x then --se non è ancora stato registrato nessun cartello per l'arena, evito il crash
arena_lib.update_sign ( arena.sign , arena )
end
end )
end
end
minetest.log ( " action " , " [ARENA_LIB] Mini-game " .. mod .. " loaded " )
2020-04-02 12:47:55 +02:00
end
2020-04-18 16:25:58 +02:00
function update_storage ( erase , mod , id , arena )
-- ogni mod e ogni arena vengono salvate seguendo il formato mod.ID
local entry = mod .. " . " .. id
if erase then
storage : set_string ( entry , " " )
else
2020-04-18 17:20:26 +02:00
storage : set_string ( entry , minetest.serialize ( arena ) )
2020-04-18 16:25:58 +02:00
end
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-15 15:17:12 +02:00
function next_ID ( mod_ref )
2020-03-31 17:04:03 +02:00
local n = 0
2020-04-15 15:17:12 +02:00
for id , arena in pairs ( mod_ref.arenas ) do
2020-03-31 17:04:03 +02:00
if id > n then n = id end
end
2020-04-15 13:14:30 +02:00
return n + 1
2020-03-31 17:04:03 +02:00
end