Jump to content

How to sort table by value


maffius

Recommended Posts

How can I sort this scoreboard by Alive Time?

B4G8sNw.png

 

local sw, sh = guiGetScreenSize()
			
ColumnName = {{ name = "", width = 120, data = function (element) return (string.gsub(getPlayerName(element), '#%x%x%x%x%x%x', '' )) end },}
ColumnStats = {
{ name = "Murders", width = 80, data = function (element) return ( getElementData ( element, "murders" ) or 0 ) end },
{ name = "Killed Zombies", width = 80, data = function (element) return ( getElementData ( element, "zombieskilled" ) or 0 ) end },
{ name = "Alive Time", width = 80, data = function (element) return formatTimeFromMinutes(getElementData ( element, "alivetime" ) or 1 ) end },
{ name = "TKZ", width = 50, data = function (element) return ( getElementData ( element, "totalzombieskilled1" ) or 0 ) end },
{ name = "TM", width = 50, data = function (element) return ( getElementData ( element, "totalmurders1" ) or 0 ) end },
{ name = "TD", width = 50, data = function (element) return ( getElementData ( element, "totaldeaths3" ) or 0 ) end },
{ name = "KD Ratio", width = 50, data = function (element) 
if not (getElementData ( element, "totaldeaths3" ) and getElementData ( element, "totalmurders1" ) ) then
return 0
elseif not (getElementData ( element, "totaldeaths3" ) > 0 ) then
return ( ('%.2f'):format( (getElementData ( element, "totalmurders1" ) or 0) / 1) )
else 
return ( ('%.2f'):format( (getElementData ( element, "totalmurders1" ) or 0) / getElementData ( element, "totaldeaths3" ) ) ) end end },
{ name = "TOT", width = 50, data = function (element) return formatTimeFromMinutes(getElementData ( element, "totalonlinetime1" ) or 1 ) end },
{ name = "Ping", width = 40, data = function (element) return (getPlayerPing(element)) end },
}

local serverName = "FRAGUJEMY"
local serverName1 = ". com"
local topsize = 60
local playersize = topsize-40
local panelsize = playersize*1.2

function calculateWidth()
	local width = 0
	for key, value in ipairs( ColumnName ) do
		width = width + value.width
	end
	for key, value in ipairs( ColumnStats ) do
		width = width + value.width
	end	
	return width + 60
end 

local max_players = 70
local ploff = 0
local width = calculateWidth()
local baseX = sw/2-width/2
local baseY = sh/2-(panelsize+topsize)/0.5

function scoreBoard ()
    if getKeyState( "tab" ) == false then ploff = 0; return end
	if getElementData(getLocalPlayer(),"logedin") then
		dxDrawRectangle ( baseX, baseY-40, width, topsize+40, tocolor(25,25,25) )
		dxDrawText ( serverName, baseX+170, baseY-38, baseX+width, baseY+topsize, tocolor(255,255,255), 2.15, "bankgothic" )
		dxDrawText ( serverName1, baseX+600, baseY, baseX+width, baseY+topsize, tocolor(255,255,255), 0.5, "bankgothic" )
		dxDrawRectangle ( baseX, baseY+topsize, width, panelsize, tocolor(112,112,112,0) )			
		dxDrawLine ( baseX, baseY+30, baseX+width, baseY+30, tocolor(75,75,75),0.8 )	
		local xoff = 60
		for i, v in ipairs ( ColumnName ) do
			dxDrawText ( v.name, baseX+xoff, baseY+70, baseX+xoff+v.width+10, baseY+topsize-30, tocolor(255,255,255), 1, "default-bold", "center", "center" )
			xoff = xoff+v.width
		end			
		for i, v in ipairs ( ColumnStats ) do
			dxDrawText ( v.name, baseX+xoff-5, baseY+60, baseX+xoff+v.width, baseY+topsize-30, tocolor(255,255,255), 1, "default-bold", "center", "center" )
			xoff = xoff+v.width
		end
		local playersTable = getElementsByType ( "player" )
		dxDrawText ( "Online:  "..tostring(#playersTable).." | "..tostring(max_players), baseX-625, baseY+60, baseX+width, baseY+30, tocolor(255,255,255), 1, "default-bold", "center", "center" )	
		local maxNum = #playersTable
		if maxNum > 20 then
			maxNum = 20
		end
		for i = 1, maxNum do
		local rank = getElementDataPosition("alivetime",getElementData(getLocalPlayer(),"alivetime"))
			dxDrawText (i+ploff, baseX, baseY+topsize+playersize*(i-1), baseX+25, baseY+topsize+playersize*i, tocolor(255,255,255), 1, "default-bold", "center", "center" )
			if playersTable[i+ploff] == localPlayer then
				dxDrawRectangle ( baseX, baseY+topsize+playersize*(i-1), width, playersize, tocolor(50,50,50,160) )
				else
				dxDrawRectangle ( baseX, baseY+topsize+playersize*(i-1), width, playersize, tocolor(50,50,50,120) )					
			end
			local xoff = 60		
			for c, d in ipairs ( ColumnName ) do
				local data = d.data(playersTable[i+ploff])
				local r,g,b = 255,255,255
				dxDrawText ( data, baseX+xoff-40, baseY+topsize+playersize*(i-1), baseX+xoff+d.width-10, baseY+topsize+playersize*i, tocolor(r,g,b), 0.9, "default-bold", "center", "center" )
				xoff = xoff+d.width
			end
				for c, d in ipairs ( ColumnStats ) do
				local data = d.data(playersTable[i+ploff])
				local r,g,b = 255,255,255
				if d.name == "gang" and data == "None" then
					r,g,b = 0,255,0
					data = "None"
				end
				dxDrawText ( data, baseX+xoff, baseY+topsize+playersize*(i-1), baseX+xoff+d.width-5, baseY+topsize+playersize*i, tocolor(r,g,b), 0.9, "default-bold", "center", "center" )
				xoff = xoff+d.width
			end
		end
	end
end
addEventHandler ( "onClientRender", getRootElement(), scoreBoard )

function PlayerScrollMenu (key,keyState,arg)
	if getElementData(localPlayer,"logedin") and getKeyState( "tab" ) then
		if ( keyState == "down" ) then
			if arg == "up" then
				if ploff > 0 then
					ploff=ploff-1
				end
			elseif arg == "down" then
				local playersTable = getElementsByType ( "player" )
				if ploff < #playersTable-20 then
					ploff = ploff+1
				end
			end
		end
	end
end
bindKey ( "mouse_wheel_up", "down", PlayerScrollMenu, "up" )
bindKey ( "mouse_wheel_down", "down", PlayerScrollMenu, "down" )

function formatTimeFromMinutes(value)
	if value then
		local hours = math.floor(value/60)
		local minutes = math.round(((value/60) - math.floor(value/60))*100/(100/60))
		if minutes < 10 then minutes = "0"..minutes end
		value = hours..":"..minutes
		return value
	end
	return false
end

function math.round(number, decimals, method)
    decimals = decimals or 0
    local factor = 10 ^ decimals
    if (method == "ceil" or method == "floor") then return math[method](number * factor) / factor
    else return tonumber(("%."..decimals.."f"):format(number)) end
end

function sendMaxPlayersOnServer (players)
	max_players = players
end
addEvent("sendMaxPlayersOnServer",true)
addEventHandler("sendMaxPlayersOnServer",getLocalPlayer(),sendMaxPlayersOnServer)

 

Link to comment

You could use three loops for getting this done. I think it should work but I cannot guarantee. :P

local players = getElementsByType("player")
local players_a = { }
local players_b = { }

for z = 1, #players do
  local p = players[ z ]
  if ( #players_a ~= #players ) then
    local s
    local p1_a = getElementData( p, "alivetime" )
    for i = 1, #players_a do
      local p2 = players_a[ i ]
      local p2_a = getElementData( p2, "alivetime" )
      if ( p1_a > p2_a ) then
        players_a[ i ] = p
        for x = 1, #players_b do
          local v = players_b[ x ]
          players_a[ x + 1 ] = v
        end
        players_b = players_a
  	  elseif ( i == #players_a ) then
        players_a[#players_a + 1] = p
        players_b = players_a
      end
    end
  end
end

 

Edited by Simple01
Link to comment

You could use table.sort after line 62 in your script.

-- Descending
table.sort(playersTable,
	function(a,b)
		return tonumber(getElementData(a,"alivetime") or 0) > tonumber(getElementData(b,"alivetime") or 0)
	end
)

-- Or ascending
table.sort(playersTable,
	function(a,b)
		return tonumber(getElementData(a,"alivetime") or 0) < tonumber(getElementData(b,"alivetime") or 0)
	end
)

Assuming that your alivetime element data is integer.

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...