• How to get a top score of all players Frags (kills)
    22 replies, posted
I am working on a kill counter with top score for all players as well. My kill counter works but not my top score. Currently it overlaps with 0 and I do not know why. https://files.facepunch.com/forum/upload/110291/26c785af-c9ef-4991-b8d4-401539439129/Screenshot_13.jpg Serverside: hook.Add("OnNPCKilled", "killingnpcorplayer", function(victim, killer, weapon)     if(IsValid(killer)) then         if(killer:IsNPC()) then             killer:AddFrags(1)         elseif(killer:IsPlayer()) then             killer:AddFrags(1)         end     end end) hook.Add("PlayerDeath", "resetcounter", function(victim, killer, weapon)     victim:SetFrags(0) end) Clientside: local plykills = 0 surface.CreateFont( "KillCounter", {     font = "DermaLarge", -- Use the font-name which is shown to you by your operating system Font Viewer, not the file name     extended = false,     size = 50,     weight = 500,     blursize = 0,     scanlines = 0,     antialias = true,     underline = false,     italic = false,     strikeout = false,     symbol = false,     rotary = false,     shadow = false,     additive = false,     outline = false, } ) hook.Add("HUDPaint", "countkills", function()     --draw.SimpleTextOutlined("X"..plykills, "KillCounter", ScrW() * 0.02, ScrH() * 0.35, Color(255,255,255,200), TEXT_ALIGN_LEFT, TEXT_ALIGN_LEFT, 1, Color(0,0,0,255))     for k,v in pairs(player.GetAll()) do         draw.SimpleTextOutlined("Top Score: "..math.max(v:Frags(0), v:Frags()), "KillCounter", ScrW() * 0.02, ScrH() * 0.35, Color(255,255,255,200), TEXT_ALIGN_LEFT, TEXT_ALIGN_LEFT, 1, Color(0,0,0,255))     end end)
v:Frags(0) What's that?
Frags is the kills for each player.
Passing the 0 argument does nothing as the function doesn't take arguments. You've basically made it always be v:Frags() If you want to get the highest score out of ALL the players in the server, you need to have a variable outside the player loop that updates if the value you get is larger. I think that's what you're trying to do Something like: local maxfrags = 0 for _, ply in ipairs( player.GetAll() ) do if ply:Frags() > maxfrags then maxfrags = ply:Frags() end end --DO YOUR HUD DRAW NOW WITH MAXFRAGS --( IT WILL ALWAYS BE AT LEAST 0 SO NO NEED TO DO A MATH.MAX )
How would I get the name of the highest frags player?
local playersSortedByFrags = player.GetAll() table.sort(playersSortedByFrags, function(a, b) return a:Frags() > b:Frags() end
I get this error. I may be missing something obvious.. [ERROR] addons/gmodevents/lua/autorun/client/cl_killcounter.lua:35: attempt to index global 'a' (a nil value)   1. fn - addons/gmodevents/lua/autorun/client/cl_killcounter.lua:35    2. unknown - addons/ulib/lua/ulib/shared/hook.lua:109 hook.Add("HUDPaint", "countkills", function()     for k,v in pairs(player.GetAll()) do         if(v:Frags() > maxfrags) then             maxfrags = v:Frags()         end     end     plykills = LocalPlayer():Frags()     table.sort(player.GetAll(), function(a, b)         return a:Frags() > b:Frags()     end)     draw.SimpleTextOutlined("Your Kills: X"..plykills, "KillCounter", ScrW() * 0.02, ScrH() * 0.55, Color(255,255,255,200), TEXT_ALIGN_LEFT, TEXT_ALIGN_LEFT, 1, Color(0,0,0,255))     draw.SimpleTextOutlined("Top Score: "..a:Frags(), "KillCounter", ScrW() * 0.02, ScrH() * 0.35, Color(255,255,255,200), TEXT_ALIGN_LEFT, TEXT_ALIGN_LEFT, 1, Color(0,0,0,255)) end)
variable a is defined only here: table.sort(player.GetAll(), function(a, b) return a:Frags() > b:Frags() end) You use it in drawing a:Frags() Also sort function that you have been given is incorrect because player.GetAll() can't be updated. Code is even unoptimised to use it in drawing function which renders EVERY FRAME. We copy player.GetAll() (just call function, because it returns copy everytime) local t = player.GetAll() 2. Now we have table of players for use. Now we need to capture winning frag and player. To do that optimisied we use one for loop for k,v in pairs(t) do     t[k] = {ply=v,frags=v:Frags()} -- We override original table value to table with same player and his frags end 3. Now we have table with player and his frags, it's time to sort table.SortByMember(t,"frags") 4. Now time to find winner "Top Score: "..t[1].frags.." ("..t[1].ply..")" All in all: local t = player.GetAll() for k,v in pairs(t) do t[k] = {ply=v,frags=v:Frags()} -- We override original table value to table with same player and his frags end table.SortByMember(t,"frags") -- "Top Score: "..t[1].frags.." ("..t[1].ply..")" I would recommend use that not in draw function. For example update values every second or five by timer.
local t = player.GetAll() timer.Create("Update", CurTime(), 0, function()     for k,v in pairs(t) do         t[k] = {ply=v,frags=v:Frags()} -- We override original table value to table with same player and his frags     end end) table.SortByMember(t,"frags") hook.Add("HUDPaint", "countkills", function()     for k,v in pairs(player.GetAll()) do         if(v:Frags() > maxfrags) then             maxfrags = v:Frags()         end     end     plykills = LocalPlayer():Frags()     --draw.SimpleTextOutlined("Your Kills: X"..plykills, "KillCounter", ScrW() * 0.02, ScrH() * 0.55, Color(255,255,255,200), TEXT_ALIGN_LEFT, TEXT_ALIGN_LEFT, 1, Color(0,0,0,255))     draw.SimpleTextOutlined("Top Score: "..t[1].frags.." ("..t[1]..ply..")", "KillCounter", ScrW() * 0.02, ScrH() * 0.35, Color(255,255,255,200), TEXT_ALIGN_LEFT, TEXT_ALIGN_LEFT, 1, Color(0,0,0,255)) end) It pops up with this error: [ERROR] addons/gmodevents/lua/autorun/client/cl_killcounter.lua:38: attempt to concatenate global 'ply' (a nil value)   1. fn - addons/gmodevents/lua/autorun/client/cl_killcounter.lua:38    2. unknown - addons/ulib/lua/ulib/shared/hook.lua:109
Just copy the line with "Top Score"
What do you mean "Copy the line"?
Copy this to your code, you made typo "Top Score: "..t[1].frags.." ("..t[1].ply..")"
I copied it. But still getting the same error. draw.SimpleTextOutlined("Top Score: "..t[1].frags.." ("..t[1].ply..")", "KillCounter", ScrW() * 0.02, ScrH() * 0.35, Color(255,255,255,200), TEXT_ALIGN_LEFT, TEXT_ALIGN_LEFT, 1, Color(0,0,0,255))
Use spaces or brackets for that draw.SimpleTextOutlined("Top Score: ".. t[1].frags .." (".. t[1].ply ..")", "KillCounter", ScrW() * 0.02, ScrH() * 0.35, Color(255,255,255,200), TEXT_ALIGN_LEFT, TEXT_ALIGN_LEFT, 1, Color(0,0,0,255))
local players = player.GetAll() table.sort(players, function(a, b)     return a:Frags() > b:Frags() end) local top = players[1] string.format("Top Kills: %i (%s)", top:Frags(), top:Nick())
Works like a charm. Does this show for all players? https://files.facepunch.com/forum/upload/110291/3e12b835-68a3-475f-b5d7-d7db8ff61c4b/Screenshot_14.jpg
Have you looked into using the entity_killed gamevent on the client to keep the top frags up to date? This would allow it to be event driven instead of using a timer or sorting a table on every HUDPaint call.
the %i represents a int and the %s is a string of characters. you can read more about how it works here string.format
%i (%s) is a format markers. They use C++ function. Learn more
Would that be better?
It would be more better than timers. Because it listens to kill updates. Used in gameevent.Listen
If you don't want it to go off screen you could just use TEXT_ALIGN_RIGHT instead of TEXT_ALIGN_LEFT or offset it using the width of the text.
Thank you, that is very handy.
Sorry, you need to Log In to post a reply to this thread.