overhaul leaderboard

master
MisterE123 2021-12-30 22:17:55 -05:00
parent 1108639ef7
commit e437d25e30
5 changed files with 245 additions and 203 deletions

View File

@ -47,6 +47,17 @@ ChatCmdBuilder.new("wormball", function(cmd)
arena_lib.disable_arena(name, "wormball", arena)
end)
--clear highscores
cmd:sub("clrleaderboard :arena", function(name, arena)
local success, msg = wormball.leaderboard.clear_highscores(arena)
if success == true then
return "[!] Wormball arena " .. arena .. " Highscores Cleared!"
else
return "[!] Highscore Clear Attempt Failed! Error: ".. msg
end
end)
end, {
description = [[
@ -57,6 +68,7 @@ end, {
- edit <arena name>
- enable <arena name>
- list -- show created arenas
- clrleaderboard <arena_name>
Other commands:
- remove <arena name>
@ -101,3 +113,5 @@ minetest.register_chatcommand("wormball_multiscores", {
return "error"
end,
})

View File

@ -1,4 +1,4 @@
wormball.version = "03.11.2021.1"
wormball.version = "12.30.2021.1"
wormball.player_texture_save = {}

View File

@ -26,6 +26,8 @@ dofile(minetest.get_modpath("wormball") .. "/globals.lua")
show_nametags = false,
hotbar = {
slots = 1,
background_image = "blank.png",
selected_image = "blank.png",
},
celebration_time = 10,
@ -83,32 +85,17 @@ if not minetest.get_modpath("lib_chatcmdbuilder") then
dofile(minetest.get_modpath("wormball") .. "/chatcmdbuilder.lua")
end
dofile(minetest.get_modpath("wormball") .. "/editor.lua")
dofile(minetest.get_modpath("wormball") .. "/commands.lua")
--nodes includes the attachment entity, also there are creative decorative worm body parts for decorating minigame hubs
dofile(minetest.get_modpath("wormball") .. "/nodes.lua")
dofile(minetest.get_modpath("wormball") .. "/privs.lua")
dofile(minetest.get_modpath("wormball") .. "/leaderboard.lua")
dofile(minetest.get_modpath("wormball") .. "/commands.lua")
--minigame_manager simply runs all the files in the folder minigame_manager
dofile(minetest.get_modpath("wormball") .. "/minigame_manager.lua")
-- get highscores from storage if found
-- it doesnt seem to work for some reason
-- you will have to play one game before scores are available.
if arena_lib.mods and arena_lib.mods["wormball"] and arena_lib.mods["wormball"].arenas and # arena_lib.mods["wormball"].arenas > 0 then
for arena_name, arena_stats in pairs(arena_lib.mods["wormball"].arenas) do
if wormball.storage:get_string(arena_name .. "_highscores") then
local wormball_highscores = wormball.storage:get_string(arena_name .. "_highscores")
local leaderboard = {}
if wormball_highscores then leaderboard = minetest.deserialize( wormball_highscores ) end
arena_lib.mods["wormball"].arenas.singleplayer_leaderboard = leaderboard
end
end
end

216
leaderboard.lua Normal file
View File

@ -0,0 +1,216 @@
local storage = wormball.storage
wormball.leaderboard = {}
-- get highscores from storage if found. if not found, create an empty table for each existing arena.
if arena_lib.mods and arena_lib.mods["wormball"] and arena_lib.mods["wormball"].arenas then
for id, arena in pairs(arena_lib.mods["wormball"].arenas) do
local arena_name = arena.name
-- assume the leaderboard is empty
local leaderboard = {}
-- recall the leaderboard from storage
if storage:get_string(arena_name .. "_highscores") then
local ser_leaderboard = storage:get_string(arena_name .. "_highscores")
if ser_leaderboard then
leaderboard = minetest.deserialize( ser_leaderboard )
end
end
-- update storage
storage:set_string(arena_name .. "_highscores", minetest.serialize(leaderboard))
-- update the arena leaderboard
arena_lib.mods["wormball"].arenas[id].singleplayer_leaderboard = leaderboard
end
end
-- returns a , b
-- a can be true or false, indicates success
-- b is the error message
wormball.leaderboard.save_highscores = function(arena_name,highscores)
local arenas = arena_lib.mods["wormball"].arenas
if # arenas == 0 then return false, "there are no wormball arenas" end
if not arena_lib.get_arena_by_name("wormball",arena_name) then return false, "there is no such arena" end
local id , arena = arena_lib.get_arena_by_name("wormball",arena_name)
-- update storage
storage:set_string(arena_name .. "_highscores", minetest.serialize(highscores))
-- update the arena leaderboard
arena_lib.mods["wormball"].arenas[id].singleplayer_leaderboard = highscores
return true , "success"
end
-- returns: a , b , c
-- a can be nil or a table of highscores
-- b is either true or false, indicates if a is a table
-- c is the error message
wormball.leaderboard.get_highscores = function(arena_name)
local arenas = arena_lib.mods["wormball"].arenas
if # arenas == 0 then return nil, false, "there are no arenas" end
if not arena_lib.get_arena_by_name("wormball",arena_name) then return nil, false, "there is no such arena" end
local id , arena = arena_lib.get_arena_by_name("wormball",arena_name)
local highscores = {}
local msg = "there were no highscores to return"
local ser_leaderboard = storage:get_string(arena_name .. "_highscores")
if ser_leaderboard then
leaderboard = minetest.deserialize( ser_leaderboard )
if leaderboard then
highscores = leaderboard
msg = "success!"
end
end
return highscores, true, msg
end
-- returns a , b
-- a can be true or false, indicates success
-- b is the error message
wormball.leaderboard.clear_highscores = function(arena_name)
local arenas = arena_lib.mods["wormball"].arenas
if # arenas == 0 then return false, "there are no wormball arenas" end
if not arena_lib.get_arena_by_name("wormball",arena_name) then return false, "there is no such arena" end
local id , arena = arena_lib.get_arena_by_name("wormball",arena_name)
-- update storage
storage:set_string(arena_name .. "_highscores", minetest.serialize({}))
-- update the arena leaderboard
arena_lib.mods["wormball"].arenas[id].singleplayer_leaderboard = {}
return true , "success"
end
-- scoreboards
wormball.show_leaderboard_formspec = function(playername,arena_name,board_title,leaderboard, formname)
if not minetest.get_player_by_name(playername) then
return false, "no player by that name!"
end
local is_empty = false
local player_list = ""
if not leaderboard or not leaderboard[1] then
is_empty = true
leaderboard = {}
end
if is_empty == false then
for idx , winner_table in ipairs( leaderboard ) do
local max_len = 30
local p_name = winner_table [ 2 ]
local name_len = string.len( winner_table [ 2 ] )
if name_len > 20 then
p_name = string.sub(p_name, 1, 20)
name_len = 20
end
local pts = tostring( winner_table [ 1 ] )
local pts_len = string.len( pts )
local spaces = 5 - pts_len
player_list = player_list .. pts
for i = 1, spaces do
player_list = player_list .. " "
end
player_list = player_list .. p_name .. ","
end
end
local formspec = "formspec_version[4]"..
"size[8,9]"..
"box[0,0;8,1;#ff4800]"..
"label[3,0.5;" .. board_title .. "]"..
"box[0,1;8,1;#ff8000]"..
"label[3,1.5;" .. arena_name .. "]"..
"box[0,2;8,7;#191359]"..
"textlist[0.5,2.5;7,6;;".. player_list ..";1;true]"
minetest.show_formspec(playername, formname, formspec)
return true, ""
end
wormball.show_multi_scores = function( arena , player , scores )
local leaderboard = scores
--minetest.chat_send_all(dump(arena))
local player_list = ""
wormball.show_leaderboard_formspec(player,arena.name,"Multiplayer Scores",leaderboard,'multiscoreboard')
return true , ""
end
wormball.show_singleplayer_leaderboard = function( arena_name , playername )
if not arena_lib.get_arena_by_name('wormball', arena_name ) then return false, "no arena by that name!" end
local arena_id, arena = arena_lib.get_arena_by_name('wormball', arena_name )
local leaderboard = arena.singleplayer_leaderboard
--minetest.chat_send_all(dump(arena.singleplayer_leaderboard))
wormball.show_leaderboard_formspec(playername,arena_name,"LeaderBoard",leaderboard,'scoreboard')
return true , ""
end

View File

@ -1,129 +1,5 @@
-- scoreboards
local storage = wormball.storage
wormball.show_multi_scores = function( arena , player , scores )
local leaderboard = scores
--minetest.chat_send_all(dump(arena))
local player_list = ""
if not leaderboard or not leaderboard[1] then return end
for idx , winner_table in ipairs( leaderboard ) do
local max_len = 30
local p_name = winner_table [ 2 ]
local name_len = string.len( winner_table [ 2 ] )
if name_len > 20 then
p_name = string.sub(p_name, 1, 20)
name_len = 20
end
local pts = tostring( winner_table [ 1 ] )
local pts_len = string.len( pts )
local spaces = max_len - name_len - pts_len
player_list = player_list .. p_name
for i = 1, spaces do
player_list = player_list .. " "
end
player_list = player_list .. pts .. ","
end
local formspec = "formspec_version[4]"..
"size[8,9]"..
"box[0,0;8,1;#ff4800]"..
"label[2.5,0.5;Multiplayer Scores]"..
"box[0,1;8,1;#ff8000]"..
"label[3,1.5;" .. arena.name .. "]"..
"box[0,2;8,7;#191359]"..
"textlist[0.5,2.5;7,6;;".. player_list ..";1;true]"
minetest.show_formspec(player, 'multiscoreboard', formspec)
end
wormball.show_singleplayer_leaderboard = function( arena_name , playername )
if not arena_lib.get_arena_by_name('wormball', arena_name ) then return false end
local arena_id, arena = arena_lib.get_arena_by_name('wormball', arena_name )
local leaderboard = arena.singleplayer_leaderboard
--minetest.chat_send_all(dump(arena.singleplayer_leaderboard))
local player_list = ""
if not leaderboard or not leaderboard[1] then return end
for idx , winner_table in ipairs( leaderboard ) do
local max_len = 30
local p_name = winner_table [ 2 ]
local name_len = string.len( winner_table [ 2 ] )
if name_len > 20 then
p_name = string.sub(p_name, 1, 20)
name_len = 20
end
local pts = tostring( winner_table [ 1 ] )
local pts_len = string.len( pts )
local spaces = max_len - name_len - pts_len
player_list = player_list .. p_name
for i = 1, spaces do
player_list = player_list .. " "
end
player_list = player_list .. pts .. ","
end
local formspec = "formspec_version[4]"..
"size[8,9]"..
"box[0,0;8,1;#ff4800]"..
"label[3,0.5;Leaderboard]"..
"box[0,1;8,1;#ff8000]"..
"label[3,1.5;" .. arena_name .. "]"..
"box[0,2;8,7;#191359]"..
"textlist[0.5,2.5;7,6;;".. player_list ..";1;true]"
minetest.show_formspec(playername, 'scoreboard', formspec)
end
arena_lib.on_celebration('wormball', function(arena, winner_name)
@ -154,7 +30,7 @@ arena_lib.on_celebration('wormball', function(arena, winner_name)
local new_highscore = false
local leaderboard = arena.singleplayer_leaderboard
local leaderboard = wormball.leaderboard.get_highscores(arena.name) --arena.singleplayer_leaderboard
local score = arena.players [ winner_name ] .score
@ -202,10 +78,15 @@ arena_lib.on_celebration('wormball', function(arena, winner_name)
--save (update) the highscore data to disk
arena.singleplayer_leaderboard = leaderboard
local serial = minetest.serialize(arena.singleplayer_leaderboard)
storage:set_string(arena.name .. "_highscores", serial )
local success, msg = wormball.leaderboard.save_highscores(arena.name,leaderboard)
minetest.chat_send_all(tostring(success))
minetest.chat_send_all(msg)
--local serial = minetest.serialize(arena.singleplayer_leaderboard)
--storage:set_string(arena.name .. "_highscores", serial )
@ -261,62 +142,6 @@ arena_lib.on_celebration('wormball', function(arena, winner_name)
end
end
-- --Highscores are stored per number of players...
-- --in a crash report, highscore was nil... WHY!? #BUG
-- --crash (hopefully) prevented with nil check... place debug code here
-- --note: crash occured when arena edit mode was entered while arena had crashed due to another bug, and the arena was still active (in_celebration)
-- --note2: this will also prevent crashes due to arena editors messing with the highscores table.
-- local highscore = arena.highscores[arena.num_players]
-- if not highscore then --nil check
-- local highscore_tbl = arena.highscores
-- highscore_tbl[arena.num_players] = {'pl_name_placeholder',0}
-- arena_lib.change_arena_property(nil, 'wormball', arena.name, highscores, highscore_tbl)
-- if arena.mode == 'singleplayer' then
-- local splb = arena.singleplayer_leaderboard
-- table.insert(splb, {})
-- highscore = {'pl_name_placeholder',0}
-- end
-- --old highscore info if existing
-- local high_name = highscore[1] or ''
-- local high_num = highscore[2] or 0
-- --current winner pts
-- local winner_pts = arena.players[winner_name].score
-- --HUD info sent to players
-- arena_lib.HUD_send_msg_all("title", arena, winner_name..' won with '..winner_pts.. ' pts!', 9,'sumo_win',0xAEAE00)
-- arena_lib.HUD_send_msg_all("hotbar", arena, 'Highscore: '..high_name.. ' '..high_num, 9,nil,0x0000FF)
-- --if highscore was broken, 2 sec later, another HUD info abt that...
-- if high_num < winner_pts then
-- --set highscore info
-- arena.highscores[arena.num_players] = {winner_name,winner_pts} --could this have cause the bug?
-- minetest.after(2,function(arena,winner_name,winner_pts)
-- arena_lib.HUD_send_msg_all("title", arena, 'NEW HIGH SCORE '.. arena.num_players ..' PLAYER!', 7,'sumo_win',0xAEAE00)
-- arena_lib.HUD_send_msg_all("hotbar", arena, 'Highscore: '..winner_name.. ' '..winner_pts, 7,nil,0x0000FF)
-- end,arena,winner_name,winner_pts)
-- end
end
end)