Guest User

Dxscoreboard

a guest
Nov 30th, 2012
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 51.89 KB | None | 0 0
  1. -- THESE CAN BE CHANGED
  2. triggerKey = "tab" -- default button to open/close scoreboard
  3. settingsKey = "F7" -- default button to open the settings window
  4. drawOverGUI = true -- draw scoreboard over gui?
  5. seperationSpace = 80 -- the space between top/bottom screen and scoreboard top/bottom in pixels
  6.  
  7. -- BUT DON'T TOUCH THESE
  8. scoreboardToggled = false
  9. scoreboardForced = false
  10. scoreboardDrawn = false
  11. forceScoreboardUpdate = false
  12. useAnimation = true
  13. scoreboardIsToggleable = false
  14. showServerInfo = false
  15. showGamemodeInfo = false
  16. showTeams = true
  17. useColors = true
  18. drawSpeed = 1
  19. scoreboardScale = 1
  20. teamHeaderFont = "clear"
  21. contentFont = "default-bold"
  22. columnFont = "default-bold"
  23. serverInfoFont = "default"
  24. rmbFont = "clear"
  25. cBlack = tocolor( 0, 0, 0 )
  26. cWhite = tocolor( 255, 255, 255 )
  27. cSettingsBox = tocolor( 255, 255, 255, 150 )
  28. MAX_PRIRORITY_SLOT = 500
  29.  
  30. scoreboardColumns = {}
  31. resourceColumns = {}
  32. scoreboardDimensions = { ["width"] = 0, ["height"] = 0, ["phase"] = 1, ["lastSeconds"] = 0 }
  33. scoreboardTicks = { ["lastUpdate"] = 0, ["updateInterval"] = 500 }
  34. scoreboardContent = {}
  35. firstVisibleIndex = 1
  36. sortBy = { ["what"] = "__NONE__", ["dir"] = -1 } -- -1 = dec, 1 = asc
  37. sbOutOffset, sbInOffset = 1, 1
  38. sbFont = "clear"
  39. sbFontScale = 0.68
  40. serverInfo = {}
  41. fontScale = { -- To make all fonts be equal in height
  42. ["default"] = 1.0,
  43. ["default-bold"] = 1.0,
  44. ["clear"] = 1.0,
  45. ["arial"] = 1.0,
  46. ["sans"] = 1.0,
  47. ["pricedown"] = 0.5,
  48. ["bankgothic"] = 0.5,
  49. ["diploma"] = 0.5,
  50. ["beckett"] = 0.5
  51. }
  52. selectedRows = {}
  53.  
  54. addEvent( "onClientPlayerScoreboardClick" )
  55.  
  56. addEventHandler( "onClientResourceStart", getResourceRootElement( getThisResource() ),
  57. function ( resource )
  58. cScoreboardBackground = tocolor( defaultSettings.bg_color.r, defaultSettings.bg_color.g, defaultSettings.bg_color.b, defaultSettings.bg_color.a )
  59. cSelection = tocolor( defaultSettings.selection_color.r, defaultSettings.selection_color.g, defaultSettings.selection_color.b, defaultSettings.selection_color.a )
  60. cHighlight = tocolor( defaultSettings.highlight_color.r, defaultSettings.highlight_color.g, defaultSettings.highlight_color.b, defaultSettings.highlight_color.a )
  61. cHeader = tocolor( defaultSettings.header_color.r, defaultSettings.header_color.g, defaultSettings.header_color.b, defaultSettings.header_color.a )
  62. cTeam = tocolor( defaultSettings.team_color.r, defaultSettings.team_color.g, defaultSettings.team_color.b, defaultSettings.team_color.a )
  63. cBorder = tocolor( defaultSettings.border_color.r, defaultSettings.border_color.g, defaultSettings.border_color.b, defaultSettings.border_color.a )
  64. cServerInfo = tocolor( defaultSettings.serverinfo_color.r, defaultSettings.serverinfo_color.g, defaultSettings.serverinfo_color.b, defaultSettings.serverinfo_color.a )
  65. cContent = tocolor( defaultSettings.content_color.r, defaultSettings.content_color.g, defaultSettings.content_color.b, defaultSettings.content_color.a )
  66.  
  67. bindKey( triggerKey, "down", "Toggle scoreboard", "1" )
  68. bindKey( triggerKey, "up", "Toggle scoreboard", "0" )
  69. bindKey( settingsKey, "down", "Open scoreboard settings", "1" )
  70.  
  71. addEventHandler( "onClientRender", getRootElement(), drawScoreboard )
  72. triggerServerEvent( "onClientDXScoreboardResourceStart", getRootElement() )
  73. readScoreboardSettings()
  74. triggerServerEvent( "requestServerInfo", getRootElement() )
  75.  
  76. colorPicker.constructor()
  77. end
  78. )
  79.  
  80. addEventHandler( "onClientPlayerQuit", getRootElement(),
  81. function()
  82. selectedRows[source] = nil
  83. end
  84. )
  85.  
  86. function sendServerInfo( output )
  87. serverInfo = output
  88. end
  89. addEvent( "sendServerInfo", true )
  90. addEventHandler( "sendServerInfo", getResourceRootElement( getThisResource() ), sendServerInfo )
  91.  
  92. function toggleScoreboard( _, state )
  93. state = iif( state == "1", true, false )
  94. if scoreboardIsToggleable and state then
  95. scoreboardToggled = not scoreboardToggled
  96. elseif not scoreboardIsToggleable then
  97. scoreboardToggled = state
  98. end
  99. end
  100. addCommandHandler( "Toggle scoreboard", toggleScoreboard )
  101.  
  102. function openSettingsWindow()
  103. if scoreboardDrawn then
  104. local sX, sY = guiGetScreenSize()
  105. if not (windowSettings and isElement( windowSettings ) and guiGetVisible( windowSettings )) then
  106. createScoreboardSettingsWindow( sX-323, sY-350 )
  107. showCursor( true )
  108. elseif isElement( windowSettings ) then
  109. destroyScoreboardSettingsWindow()
  110. end
  111. end
  112. end
  113. addCommandHandler( "Open scoreboard settings", openSettingsWindow )
  114.  
  115. addCommandHandler( "scoreboard",
  116. function ()
  117. scoreboardToggled = not scoreboardToggled
  118. end
  119. )
  120.  
  121. function iif( cond, arg1, arg2 )
  122. if cond then
  123. return arg1
  124. end
  125. return arg2
  126. end
  127.  
  128. function doDrawScoreboard( rtPass, onlyAnim, sX, sY )
  129. if #scoreboardColumns ~= 0 then
  130.  
  131. --
  132. -- In/out animation
  133. --
  134. local currentSeconds = getTickCount() / 1000
  135. local deltaSeconds = currentSeconds - scoreboardDimensions.lastSeconds
  136. scoreboardDimensions.lastSeconds = currentSeconds
  137. deltaSeconds = math.clamp( 0, deltaSeconds, 1/25 )
  138.  
  139. if scoreboardToggled or scoreboardForced then
  140. local phases = {
  141. [1] = {
  142. ["width"] = s(10),
  143. ["height"] = s(5),
  144.  
  145. ["incToWidth"] = s(10),
  146. ["incToHeight"] = s(5),
  147.  
  148. ["decToWidth"] = 0,
  149. ["decToHeight"] = 0
  150. },
  151. [2] = {
  152. ["width"] = s(40),
  153. ["height"] = s(5),
  154.  
  155. ["incToWidth"] = calculateWidth(),
  156. ["incToHeight"] = s(5),
  157.  
  158. ["decToWidth"] = s(10),
  159. ["decToHeight"] = s(5)
  160.  
  161. },
  162. [3] = {
  163. ["width"] = calculateWidth(),
  164. ["height"] = s(30),
  165.  
  166. ["incToWidth"] = calculateWidth(),
  167. ["incToHeight"] = calculateHeight(),
  168.  
  169. ["decToWidth"] = calculateWidth(),
  170. ["decToHeight"] = s(5)
  171. }
  172. }
  173.  
  174. if not useAnimation then
  175. scoreboardDimensions.width = calculateWidth()
  176. scoreboardDimensions.height = calculateHeight()
  177. scoreboardDimensions.phase = #phases
  178. end
  179.  
  180. local maxChange = deltaSeconds * 30*drawSpeed
  181. local maxWidthDiff = math.clamp( -maxChange, phases[scoreboardDimensions.phase].incToWidth - scoreboardDimensions.width, maxChange )
  182. local maxHeightDiff = math.clamp( -maxChange, phases[scoreboardDimensions.phase].incToHeight - scoreboardDimensions.height, maxChange )
  183.  
  184. if scoreboardDimensions.width < phases[scoreboardDimensions.phase].incToWidth then
  185. scoreboardDimensions.width = scoreboardDimensions.width + maxWidthDiff * phases[scoreboardDimensions.phase].width
  186. if scoreboardDimensions.width > phases[scoreboardDimensions.phase].incToWidth then
  187. scoreboardDimensions.width = phases[scoreboardDimensions.phase].incToWidth
  188. end
  189. elseif scoreboardDimensions.width > phases[scoreboardDimensions.phase].incToWidth and not scoreboardDrawn then
  190. scoreboardDimensions.width = scoreboardDimensions.width - maxWidthDiff * phases[scoreboardDimensions.phase].width
  191. if scoreboardDimensions.width < phases[scoreboardDimensions.phase].incToWidth then
  192. scoreboardDimensions.width = phases[scoreboardDimensions.phase].incToWidth
  193. end
  194. end
  195.  
  196. if scoreboardDimensions.height < phases[scoreboardDimensions.phase].incToHeight then
  197. scoreboardDimensions.height = scoreboardDimensions.height + maxHeightDiff * phases[scoreboardDimensions.phase].height
  198. if scoreboardDimensions.height > phases[scoreboardDimensions.phase].incToHeight then
  199. scoreboardDimensions.height = phases[scoreboardDimensions.phase].incToHeight
  200. end
  201. elseif scoreboardDimensions.height > phases[scoreboardDimensions.phase].incToHeight and not scoreboardDrawn then
  202. scoreboardDimensions.height = scoreboardDimensions.height - maxHeightDiff * phases[scoreboardDimensions.phase].height
  203. if scoreboardDimensions.height < phases[scoreboardDimensions.phase].incToHeight then
  204. scoreboardDimensions.height = phases[scoreboardDimensions.phase].incToHeight
  205. end
  206. end
  207.  
  208. if scoreboardDimensions.width == phases[scoreboardDimensions.phase].incToWidth and
  209. scoreboardDimensions.height == phases[scoreboardDimensions.phase].incToHeight then
  210. if phases[scoreboardDimensions.phase + 1] then
  211. scoreboardDimensions.phase = scoreboardDimensions.phase + 1
  212. else
  213. if not scoreboardDrawn then
  214. bindKey( "mouse2", "both", showTheCursor )
  215. bindKey( "mouse_wheel_up", "down", scrollScoreboard, -1 )
  216. bindKey( "mouse_wheel_down", "down", scrollScoreboard, 1 )
  217. addEventHandler( "onClientClick", getRootElement(), scoreboardClickHandler )
  218. if not (windowSettings and isElement( windowSettings )) then
  219. showCursor( false )
  220. end
  221. triggerServerEvent( "requestServerInfo", getRootElement() )
  222. end
  223. scoreboardDrawn = true
  224. end
  225. end
  226. elseif scoreboardDimensions.width ~= 0 and scoreboardDimensions.height ~= 0 then
  227. local phases = {
  228. [1] = {
  229. ["width"] = s(10),
  230. ["height"] = s(5),
  231.  
  232. ["incToWidth"] = s(10),
  233. ["incToHeight"] = s(5),
  234.  
  235. ["decToWidth"] = 0,
  236. ["decToHeight"] = 0
  237. },
  238. [2] = {
  239. ["width"] = s(40),
  240. ["height"] = s(5),
  241.  
  242. ["incToWidth"] = calculateWidth(),
  243. ["incToHeight"] = s(5),
  244.  
  245. ["decToWidth"] = s(10),
  246. ["decToHeight"] = s(5)
  247.  
  248. },
  249. [3] = {
  250. ["width"] = calculateWidth(),
  251. ["height"] = s(30),
  252.  
  253. ["incToWidth"] = calculateWidth(),
  254. ["incToHeight"] = calculateHeight(),
  255.  
  256. ["decToWidth"] = calculateWidth(),
  257. ["decToHeight"] = s(5)
  258. }
  259. }
  260.  
  261. if scoreboardDrawn then
  262. unbindKey( "mouse2", "both", showTheCursor )
  263. unbindKey( "mouse_wheel_up", "down", scrollScoreboard, -1 )
  264. unbindKey( "mouse_wheel_down", "down", scrollScoreboard, 1 )
  265. removeEventHandler( "onClientClick", getRootElement(), scoreboardClickHandler )
  266. if not (windowSettings and isElement( windowSettings )) then
  267. showCursor( false )
  268. end
  269. end
  270. scoreboardDrawn = false
  271.  
  272. if not useAnimation then
  273. scoreboardDimensions.width = 0
  274. scoreboardDimensions.height = 0
  275. scoreboardDimensions.phase = 1
  276. end
  277.  
  278. local maxChange = deltaSeconds * 30*drawSpeed
  279. local maxWidthDiff = math.clamp( -maxChange, scoreboardDimensions.width - phases[scoreboardDimensions.phase].decToWidth, maxChange )
  280. local maxHeightDiff = math.clamp( -maxChange, scoreboardDimensions.height - phases[scoreboardDimensions.phase].decToHeight, maxChange )
  281.  
  282. if scoreboardDimensions.width > phases[scoreboardDimensions.phase].decToWidth then
  283. scoreboardDimensions.width = scoreboardDimensions.width - maxWidthDiff * phases[scoreboardDimensions.phase].width
  284. if scoreboardDimensions.width < phases[scoreboardDimensions.phase].decToWidth then
  285. scoreboardDimensions.width = phases[scoreboardDimensions.phase].decToWidth
  286. end
  287. elseif scoreboardDimensions.width < phases[scoreboardDimensions.phase].decToWidth then
  288. scoreboardDimensions.width = scoreboardDimensions.width - maxWidthDiff * phases[scoreboardDimensions.phase].width
  289. if scoreboardDimensions.width > phases[scoreboardDimensions.phase].decToWidth then
  290. scoreboardDimensions.width = phases[scoreboardDimensions.phase].decToWidth
  291. end
  292. end
  293.  
  294. if scoreboardDimensions.height > phases[scoreboardDimensions.phase].decToHeight then
  295. scoreboardDimensions.height = scoreboardDimensions.height - maxHeightDiff * phases[scoreboardDimensions.phase].height
  296. if scoreboardDimensions.height < phases[scoreboardDimensions.phase].decToHeight then
  297. scoreboardDimensions.height = phases[scoreboardDimensions.phase].decToHeight
  298. end
  299. elseif scoreboardDimensions.height < phases[scoreboardDimensions.phase].decToHeight then
  300. scoreboardDimensions.height = scoreboardDimensions.height - maxHeightDiff * phases[scoreboardDimensions.phase].height
  301. if scoreboardDimensions.height > phases[scoreboardDimensions.phase].decToHeight then
  302. scoreboardDimensions.height = phases[scoreboardDimensions.phase].decToHeight
  303. end
  304. end
  305.  
  306. if scoreboardDimensions.width == phases[scoreboardDimensions.phase].decToWidth and
  307. scoreboardDimensions.height == phases[scoreboardDimensions.phase].decToHeight and
  308. scoreboardDimensions.width ~= 0 and scoreboardDimensions.height ~= 0 then
  309.  
  310. scoreboardDimensions.phase = scoreboardDimensions.phase - 1
  311. if scoreboardDimensions.phase < 1 then scoreboardDimensions.phase = 1 end
  312. end
  313. end
  314.  
  315. --
  316. -- Draw scoreboard background
  317. --
  318. if (not rtPass or onlyAnim) and scoreboardDimensions.width ~= 0 and scoreboardDimensions.height ~= 0 then
  319. dxDrawRectangle( (sX/2)-(scoreboardDimensions.width/2), (sY/2)-(scoreboardDimensions.height/2), scoreboardDimensions.width, scoreboardDimensions.height, cScoreboardBackground, drawOverGUI )
  320. end
  321.  
  322. -- Check if anything else to do
  323. if not scoreboardDrawn or onlyAnim then
  324. return
  325. end
  326.  
  327. --
  328. -- Update the scoreboard content
  329. --
  330. local currentTick = getTickCount()
  331. if (currentTick - scoreboardTicks.lastUpdate > scoreboardTicks.updateInterval and (scoreboardToggled or scoreboardForced)) or forceScoreboardUpdate then
  332. forceScoreboardUpdate = false
  333. scoreboardContent = {}
  334. local index = 1
  335.  
  336. local sortTableIndex = 1
  337. local sortTable = {}
  338.  
  339. local players = getElementsByType( "player" )
  340. for key, player in ipairs( players ) do
  341. if not getPlayerTeam( player ) or not (showTeams or (serverInfo.forceshowteams and not serverInfo.forcehideteams)) or serverInfo.forcehideteams then
  342. sortTable[sortTableIndex] = {}
  343. for key, column in ipairs( scoreboardColumns ) do
  344. local content
  345. if column.name == "name" then
  346. local playerName = getPlayerName( player )
  347. if serverInfo.allowcolorcodes then
  348. if string.find( playerName, "#%x%x%x%x%x%x" ) then
  349. local colorCodes = {}
  350. while( string.find( playerName, "#%x%x%x%x%x%x" ) ) do
  351. local startPos, endPos = string.find( playerName, "#%x%x%x%x%x%x" )
  352. if startPos then
  353. colorCode = string.sub( playerName, startPos, endPos )
  354. table.insert( colorCodes, { { getColorFromString( colorCode ) }, startPos } )
  355. playerName = string.gsub( playerName, "#%x%x%x%x%x%x", "", 1 )
  356. end
  357. end
  358. content = { playerName, colorCodes }
  359. else
  360. content = playerName
  361. end
  362. else
  363. content = playerName
  364. end
  365. elseif column.name == "ping" then
  366. content = getPlayerPing( player )
  367. else
  368. content = getElementData( player, column.name )
  369. end
  370. content = iif( content and column.name ~= "name" and type( content ) ~= "table", tostring( content ), content )
  371. if column.textfunction then
  372. if content and column.name == "name" and type( content ) == "table" then
  373. content[1] = column.textfunction( content[1], player )
  374. else
  375. content = column.textfunction( content, player )
  376. end
  377. end
  378. sortTable[sortTableIndex][column.name] = content
  379. sortTable[sortTableIndex]["__SCOREBOARDELEMENT__"] = player
  380. end
  381. sortTableIndex = sortTableIndex + 1
  382. end
  383. end
  384. if sortBy.what ~= "__NONE__" then table.sort( sortTable, scoreboardSortfunction ) end
  385. for key, value in ipairs( sortTable ) do
  386. scoreboardContent[index] = value
  387. index = index + 1
  388. end
  389.  
  390. if (showTeams or (serverInfo.forceshowteams and not serverInfo.forcehideteams)) and not serverInfo.forcehideteams then
  391. -- And then the teams
  392. local teamSortTableIndex = 1
  393. local teamSortTable = {}
  394. sortTableIndex = 1
  395. sortTable = {}
  396. local teams = getElementsByType( "team" )
  397. for key, team in ipairs( teams ) do
  398.  
  399. -- Add teams to sorting table first
  400. teamSortTable[teamSortTableIndex] = {}
  401. for key, column in ipairs( scoreboardColumns ) do
  402. local content
  403. if column.name == "name" then
  404. local teamName = getTeamName( team )
  405. local teamMemberCount = #getPlayersInTeam( team )
  406. teamName = iif( teamName, tostring( teamName ), "-" )
  407. teamMemberCount = iif( teamMemberCount, tostring( teamMemberCount ), "0" )
  408. teamName = teamName .. " (" .. teamMemberCount .. " player" .. iif( teamMemberCount == "1", "", "s" ) .. ")"
  409. if serverInfo.allowcolorcodes then
  410. if string.find( teamName, "#%x%x%x%x%x%x" ) then
  411. local colorCodes = {}
  412. while( string.find( teamName, "#%x%x%x%x%x%x" ) ) do
  413. local startPos, endPos = string.find( teamName, "#%x%x%x%x%x%x" )
  414. if startPos then
  415. colorCode = string.sub( teamName, startPos, endPos )
  416. table.insert( colorCodes, { { getColorFromString( colorCode ) }, startPos } )
  417. teamName = string.gsub( teamName, "#%x%x%x%x%x%x", "", 1 )
  418. end
  419. end
  420. content = { teamName, colorCodes }
  421. else
  422. content = teamName
  423. end
  424. else
  425. content = teamName
  426. end
  427. else
  428. content = getElementData( team, column.name )
  429. end
  430. content = iif( content and column.name ~= "name" and type( content ) ~= "table", tostring( content ), content )
  431. if column.textfunction then
  432. if content and column.name == "name" and type( content ) == "table" then
  433. content[1] = column.textfunction( content[1], team )
  434. else
  435. content = column.textfunction( content, team )
  436. end
  437. end
  438. teamSortTable[teamSortTableIndex][column.name] = content
  439. teamSortTable[teamSortTableIndex]["__SCOREBOARDELEMENT__"] = team
  440. end
  441. teamSortTableIndex = teamSortTableIndex + 1
  442.  
  443. -- and then the players
  444. sortTableIndex = 1
  445. sortTable[team] = {}
  446. local players = getPlayersInTeam( team )
  447. for key, player in ipairs( players ) do
  448. sortTable[team][sortTableIndex] = {}
  449. for key, column in ipairs( scoreboardColumns ) do
  450. local content
  451. if column.name == "name" then
  452. local playerName = getPlayerName( player )
  453. if serverInfo.allowcolorcodes then
  454. if string.find( playerName, "#%x%x%x%x%x%x" ) then
  455. local colorCodes = {}
  456. while( string.find( playerName, "#%x%x%x%x%x%x" ) ) do
  457. local startPos, endPos = string.find( playerName, "#%x%x%x%x%x%x" )
  458. if startPos then
  459. colorCode = string.sub( playerName, startPos, endPos )
  460. table.insert( colorCodes, { { getColorFromString( colorCode ) }, startPos } )
  461. playerName = string.gsub( playerName, "#%x%x%x%x%x%x", "", 1 )
  462. end
  463. end
  464. content = { playerName, colorCodes }
  465. else
  466. content = playerName
  467. end
  468. else
  469. content = playerName
  470. end
  471. elseif column.name == "ping" then
  472. content = getPlayerPing( player )
  473. else
  474. content = getElementData( player, column.name )
  475. end
  476. content = iif( content and column.name ~= "name" and type( content ) ~= "table", tostring( content ), content )
  477. if column.textfunction then
  478. if content and column.name == "name" and type( content ) == "table" then
  479. content[1] = column.textfunction( content[1], player )
  480. else
  481. content = column.textfunction( content, player )
  482. end
  483. end
  484. sortTable[team][sortTableIndex][column.name] = content
  485. sortTable[team][sortTableIndex]["__SCOREBOARDELEMENT__"] = player
  486. end
  487. sortTableIndex = sortTableIndex + 1
  488. end
  489. if sortBy.what ~= "__NONE__" then table.sort( sortTable[team], scoreboardSortfunction ) end
  490. end
  491. if sortBy.what ~= "__NONE__" then table.sort( teamSortTable, scoreboardSortfunction ) end
  492. for key, content in ipairs( teamSortTable ) do
  493. local team = content["__SCOREBOARDELEMENT__"]
  494. scoreboardContent[index] = content
  495. index = index + 1
  496.  
  497. for key, value in ipairs( sortTable[team] ) do
  498. scoreboardContent[index] = value
  499. index = index + 1
  500. end
  501. end
  502. end
  503. scoreboardTicks.lastUpdate = currentTick
  504. end
  505.  
  506. --
  507. -- Draw scoreboard content
  508. --
  509. if scoreboardDrawn then
  510. scoreboardDimensions.height = calculateHeight()
  511. scoreboardDimensions.width = calculateWidth()
  512.  
  513. local topX, topY = (sX/2)-(calculateWidth()/2), (sY/2)-(calculateHeight()/2)
  514. local index = firstVisibleIndex
  515. local maxPerWindow = getMaxPerWindow()
  516.  
  517. if firstVisibleIndex > #scoreboardContent-maxPerWindow+1 then
  518. firstVisibleIndex = 1
  519. end
  520.  
  521. if firstVisibleIndex > 1 then
  522. dxDrawImage( sX/2-8, topY-15, 17, 11, "arrow.png", 0, 0, 0, cWhite, drawOverGUI )
  523. end
  524. if firstVisibleIndex+maxPerWindow <= #scoreboardContent and #scoreboardContent > maxPerWindow then
  525. dxDrawImage( sX/2-8, topY+scoreboardDimensions.height+4, 17, 11, "arrow.png", 180, 0, 0, cWhite, drawOverGUI )
  526. end
  527.  
  528. local y = topY+s(5)
  529. if serverInfo.server and showServerInfo then
  530. dxDrawText( "Server: " .. serverInfo.server, topX+s(5), y, topX+scoreboardDimensions.width-s(10), y+dxGetFontHeight( fontscale(serverInfoFont, scoreboardScale), serverInfoFont ), cServerInfo, fontscale(serverInfoFont, s(0.75)), serverInfoFont, "left", "top", false, false, drawOverGUI )
  531. end
  532. if serverInfo.players and showServerInfo then
  533. local players = getElementsByType( "player" )
  534. local text = "Players: " .. tostring( #players ) .. "/" .. serverInfo.players
  535. local textWidth = dxGetTextWidth( text, fontscale(serverInfoFont, s(0.75)), serverInfoFont )
  536. dxDrawText( text, topX+scoreboardDimensions.width-s(5)-textWidth, y, topX+scoreboardDimensions.width-s(5), y+dxGetFontHeight( fontscale(serverInfoFont, scoreboardScale), serverInfoFont ), cServerInfo, fontscale(serverInfoFont, s(0.75)), serverInfoFont, "left", "top", false, false, drawOverGUI )
  537. end
  538. if (serverInfo.server or serverInfo.players) and showServerInfo then y = y+dxGetFontHeight( fontscale(serverInfoFont, scoreboardScale), serverInfoFont ) end
  539. if serverInfo.gamemode and showGamemodeInfo then
  540. dxDrawText( "Gamemode: " .. serverInfo.gamemode, topX+s(5), y, topX+scoreboardDimensions.width-s(10), y+dxGetFontHeight( fontscale(serverInfoFont, scoreboardScale), serverInfoFont ), cServerInfo, fontscale(serverInfoFont, s(0.75)), serverInfoFont, "left", "top", false, false, drawOverGUI )
  541. end
  542. if serverInfo.map and showGamemodeInfo then
  543. local text = "Map: " .. serverInfo.map
  544. local textWidth = dxGetTextWidth( text, fontscale(serverInfoFont, s(0.75)), serverInfoFont )
  545. dxDrawText( text, topX+scoreboardDimensions.width-s(5)-textWidth, y, topX+scoreboardDimensions.width-s(5), y+dxGetFontHeight( fontscale(serverInfoFont, scoreboardScale), serverInfoFont ), cServerInfo, fontscale(serverInfoFont, s(0.75)), serverInfoFont, "left", "top", false, false, drawOverGUI )
  546. end
  547. if (serverInfo.gamemode or serverInfo.map) and showGamemodeInfo then y = y+dxGetFontHeight( fontscale(serverInfoFont, scoreboardScale), serverInfoFont ) end
  548. y = y+s(3)
  549.  
  550. local textLength = dxGetTextWidth( "Hold RMB to enable scrolling/sorting", fontscale(rmbFont, s(0.75)), rmbFont )
  551. local textHeight = dxGetFontHeight( fontscale(rmbFont, s(0.75)), rmbFont )
  552. dxDrawText( "Hold RMB to enable scrolling/sorting", sX/2-(textLength/2), topY+scoreboardDimensions.height-textHeight-s(2), sX/2+(textLength/2), topY+scoreboardDimensions.height-s(2), cWhite, fontscale(serverInfoFont, s(0.75)), rmbFont, "left", "top", false, false, drawOverGUI )
  553.  
  554. local bottomX, bottomY = topX+scoreboardDimensions.width, topY+scoreboardDimensions.height
  555. textLength = dxGetTextWidth( "settings...", fontscale(sbFont, s(sbFontScale)), sbFont )
  556. textHeight = dxGetFontHeight( fontscale(sbFont, s(sbFontScale)), sbFont )
  557. dxDrawText( "settings...", bottomX-s(sbOutOffset+1+sbInOffset)-textLength, bottomY-s(sbOutOffset+1+sbInOffset)-textHeight, bottomX-s(sbOutOffset+1+sbInOffset), bottomY-s(sbOutOffset+1+sbInOffset), cSettingsBox, fontscale(sbFont, s(sbFontScale)), sbFont, "left", "top", false, false, drawOverGUI )
  558. dxDrawLine( bottomX-s(sbOutOffset+2*sbInOffset+2)-textLength, bottomY-s(sbOutOffset+2*sbInOffset+1)-textHeight, bottomX-s(sbOutOffset+2*sbInOffset+2)-textLength, bottomY-s(sbOutOffset+1), cSettingsBox, 1, drawOverGUI )
  559. dxDrawLine( bottomX-s(sbOutOffset+1), bottomY-s(sbOutOffset+2*sbInOffset+1)-textHeight, bottomX-s(sbOutOffset+1), bottomY-s(sbOutOffset+1), cSettingsBox, 1, drawOverGUI )
  560. dxDrawLine( bottomX-s(sbOutOffset+2*sbInOffset+2)-textLength, bottomY-s(sbOutOffset+2*sbInOffset+1)-textHeight, bottomX-s(sbOutOffset+1), bottomY-s(sbOutOffset+2*sbInOffset+1)-textHeight, cSettingsBox, 1, drawOverGUI )
  561. dxDrawLine( bottomX-s(sbOutOffset+2*sbInOffset+2)-textLength, bottomY-s(sbOutOffset+1), bottomX-s(sbOutOffset+1), bottomY-s(sbOutOffset+1), cSettingsBox, 1, drawOverGUI )
  562.  
  563. local x = s(10)
  564. for key, column in ipairs( scoreboardColumns ) do
  565. if x ~= s(10) then
  566. local height = s(5)
  567. if (serverInfo.server or serverInfo.players) and showServerInfo then height = height+dxGetFontHeight( fontscale(serverInfoFont, scoreboardScale), serverInfoFont ) end
  568. if (serverInfo.gamemode or serverInfo.map) and showGamemodeInfo then height = height+dxGetFontHeight( fontscale(serverInfoFont, scoreboardScale), serverInfoFont ) end
  569. height = height+s(3)
  570. dxDrawLine( topX+x-s(5), y+s(1), topX+x-s(5), y+scoreboardDimensions.height-height-s(2)-textHeight-s(5), cBorder, s(1), drawOverGUI )
  571. end
  572. if sortBy.what == column.name then
  573. local _, _, _, a = fromcolor( cHeader )
  574. dxDrawText( column.friendlyName or "-", topX+x+s(1+9), y+s(1), topX+x+s(1+column.width), y+s(1)+dxGetFontHeight( fontscale(columnFont, scoreboardScale), columnFont ), tocolor( 0, 0, 0, a ), fontscale(columnFont, s(1)), columnFont, "left", "top", true, false, drawOverGUI )
  575. dxDrawText( column.friendlyName or "-", topX+x+s(9), y, topX+x+s(column.width), y+dxGetFontHeight( fontscale(columnFont, scoreboardScale), columnFont ), cHeader, fontscale(columnFont, s(1)), columnFont, "left", "top", true, false, drawOverGUI )
  576. dxDrawRectangle( topX+x, iif( sortBy.dir == 1, y+s(8), y+s(6) ), s(5), s(1), cWhite, drawOverGUI )
  577. dxDrawRectangle( topX+x+s(1), y+s(7), s(3), s(1), cWhite, drawOverGUI )
  578. dxDrawRectangle( topX+x+s(2), iif( sortBy.dir == 1, y+s(6), y+s(8) ), s(1), s(1), cWhite, drawOverGUI )
  579. else
  580. local _, _, _, a = fromcolor( cHeader )
  581. dxDrawText( column.friendlyName or "-", topX+x+s(1), y+s(1), topX+x+s(1+column.width), y+s(1)+dxGetFontHeight( fontscale(columnFont, scoreboardScale), columnFont ), tocolor( 0, 0, 0, a ), fontscale(columnFont, s(1)), columnFont, "left", "top", true, false, drawOverGUI )
  582. dxDrawText( column.friendlyName or "-", topX+x, y, topX+x+s(column.width), y+dxGetFontHeight( fontscale(columnFont, scoreboardScale), columnFont ), cHeader, fontscale(columnFont, s(1)), columnFont, "left", "top", true, false, drawOverGUI )
  583. end
  584. x = x + s(column.width + 10)
  585. end
  586. dxDrawLine( topX+s(5), y+s(1)+dxGetFontHeight( fontscale(columnFont, scoreboardScale), columnFont ), topX+scoreboardDimensions.width-s(5), y+s(1)+dxGetFontHeight( fontscale(columnFont, scoreboardScale), columnFont ), cBorder, s(1), drawOverGUI )
  587.  
  588. y = y+s(5)+dxGetFontHeight( fontscale(columnFont, scoreboardScale), columnFont )
  589. while ( index < firstVisibleIndex+maxPerWindow and scoreboardContent[index] ) do
  590. local x = s(10)
  591. local element = scoreboardContent[index]["__SCOREBOARDELEMENT__"]
  592. local team, player
  593.  
  594. if element and isElement( element ) and getElementType( element ) == "team" then
  595. dxDrawRectangle( topX+s(5), y, scoreboardDimensions.width-s(10), dxGetFontHeight( fontscale(teamHeaderFont, scoreboardScale), teamHeaderFont ), cTeam, drawOverGUI )
  596. -- Highlight the the row on which the cursor lies on
  597. if checkCursorOverRow( rtPass, topX+s(5), topX+scoreboardDimensions.width-s(5), y, y+dxGetFontHeight( fontscale(teamHeaderFont, scoreboardScale), teamHeaderFont ) ) then
  598. dxDrawRectangle( topX+s(5), y, scoreboardDimensions.width-s(10), dxGetFontHeight( fontscale(teamHeaderFont, scoreboardScale), teamHeaderFont ), cHighlight, drawOverGUI )
  599. end
  600. -- Highlight selected row
  601. if selectedRows[element] then
  602. dxDrawRectangle( topX+s(5), y, scoreboardDimensions.width-s(10), dxGetFontHeight( fontscale(teamHeaderFont, scoreboardScale), teamHeaderFont ), cHighlight, drawOverGUI )
  603. end
  604.  
  605. for key, column in ipairs( scoreboardColumns ) do
  606. local r, g, b, a = fromcolor( cContent )
  607. if not useColors then
  608. r, g, b = 255, 255, 255
  609. end
  610. local theX = x
  611. local content = scoreboardContent[index][column.name]
  612. if content and column.name == "name" then
  613. if useColors then
  614. r, g, b = getTeamColor( element )
  615. end
  616. theX = x - s(3)
  617. end
  618. if content then
  619. if serverInfo.allowcolorcodes and type( content ) == "table" and column.name == "name" then
  620. local playerName = content[1]
  621. local colorCodes = content[2]
  622. local xPos = topX+theX
  623. for k, v in ipairs( colorCodes ) do
  624. local firstCodePos = v[2]
  625. local secondCodePos = colorCodes[k+1] and colorCodes[k+1][2]-1 or #playerName
  626. if firstCodePos ~= 1 and k == 1 then
  627. local secondPos = firstCodePos-1
  628. local firstPos = 1
  629. local partOfName = string.sub( playerName, firstPos, secondPos )
  630. local textLength = dxGetTextWidth( partOfName, fontscale(contentFont, s(1)), contentFont )
  631. dxDrawText( partOfName, xPos+s(1), y+s(1), topX+x+s(1+column.width), y+s(11)+dxGetFontHeight( fontscale(teamHeaderFont, scoreboardScale), teamHeaderFont ), tocolor( 0, 0, 0, a or 255 ), fontscale(teamHeaderFont, s(1)), teamHeaderFont, "left", "top", true, false, drawOverGUI )
  632. dxDrawText( partOfName, xPos, y, topX+x+s(column.width), y+dxGetFontHeight( fontscale(teamHeaderFont, scoreboardScale), teamHeaderFont ), tocolor( r or 255, g or 255, b or 255, a or 255 ), fontscale(teamHeaderFont, s(1)), teamHeaderFont, "left", "top", true, false, drawOverGUI )
  633. xPos = xPos + textLength
  634. end
  635. if useColors then
  636. r, g, b = v[1][1], v[1][2], v[1][3]
  637. end
  638. local partOfName = string.sub( playerName, firstCodePos, secondCodePos )
  639. local textLength = dxGetTextWidth( partOfName, fontscale(contentFont, s(1)), contentFont )
  640. dxDrawText( partOfName, xPos+s(1), y+s(1), topX+x+s(1+column.width), y+s(11)+dxGetFontHeight( fontscale(teamHeaderFont, scoreboardScale), teamHeaderFont ), tocolor( 0, 0, 0, a or 255 ), fontscale(teamHeaderFont, s(1)), teamHeaderFont, "left", "top", true, false, drawOverGUI )
  641. dxDrawText( partOfName, xPos, y, topX+x+s(column.width), y+dxGetFontHeight( fontscale(teamHeaderFont, scoreboardScale), teamHeaderFont ), tocolor( r or 255, g or 255, b or 255, a or 255 ), fontscale(teamHeaderFont, s(1)), teamHeaderFont, "left", "top", true, false, drawOverGUI )
  642. xPos = xPos + textLength
  643. end
  644. else
  645. dxDrawText( content, topX+theX+s(1), y+s(1), topX+x+s(1+column.width), y+s(11)+dxGetFontHeight( fontscale(teamHeaderFont, scoreboardScale), teamHeaderFont ), tocolor( 0, 0, 0, a or 255 ), fontscale(teamHeaderFont, s(1)), teamHeaderFont, "left", "top", true, false, drawOverGUI )
  646. dxDrawText( content, topX+theX, y, topX+x+s(column.width), y+dxGetFontHeight( fontscale(teamHeaderFont, scoreboardScale), teamHeaderFont ), tocolor( r or 255, g or 255, b or 255, a or 255 ), fontscale(teamHeaderFont, s(1)), teamHeaderFont, "left", "top", true, false, drawOverGUI )
  647. end
  648. end
  649. x = x + s(column.width + 10)
  650. end
  651. elseif element and isElement( element ) and getElementType( element ) == "player" then
  652. -- Highlight local player's name
  653. if element == getLocalPlayer() then
  654. dxDrawRectangle( topX+s(5), y, scoreboardDimensions.width-s(10), dxGetFontHeight( fontscale(contentFont, scoreboardScale), contentFont ), cSelection, drawOverGUI )
  655. end
  656. -- Highlight the the row on which the cursor lies on
  657. if checkCursorOverRow( rtPass, topX+s(5), topX+scoreboardDimensions.width-s(5), y, y+dxGetFontHeight( fontscale(contentFont, scoreboardScale), contentFont ) ) then
  658. dxDrawRectangle( topX+s(5), y, scoreboardDimensions.width-s(10), dxGetFontHeight( fontscale(contentFont, scoreboardScale), contentFont ), cHighlight, drawOverGUI )
  659. end
  660. -- Highlight selected row
  661. if selectedRows[element] then
  662. dxDrawRectangle( topX+s(5), y, scoreboardDimensions.width-s(10), dxGetFontHeight( fontscale(contentFont, scoreboardScale), contentFont ), cHighlight, drawOverGUI )
  663. end
  664.  
  665. for key, column in ipairs( scoreboardColumns ) do
  666. local r, g, b, a = fromcolor( cContent )
  667. if not useColors then
  668. r, g, b = 255, 255, 255
  669. end
  670. local theX = x
  671. local content = scoreboardContent[index][column.name]
  672. if content and column.name == "name" then
  673. if useColors then
  674. r, g, b = getPlayerNametagColor( element )
  675. end
  676. if getPlayerTeam( element ) and (showTeams or (serverInfo.forceshowteams and not serverInfo.forcehideteams)) and not serverInfo.forcehideteams then theX = x + s(12) end
  677. end
  678. if content then
  679. if serverInfo.allowcolorcodes and type( content ) == "table" and column.name == "name" then
  680. local playerName = content[1]
  681. local colorCodes = content[2]
  682. local xPos = topX+theX
  683. for k, v in ipairs( colorCodes ) do
  684. local firstCodePos = v[2]
  685. local secondCodePos = colorCodes[k+1] and colorCodes[k+1][2]-1 or #playerName
  686. if firstCodePos ~= 1 and k == 1 then
  687. local secondPos = firstCodePos-1
  688. local firstPos = 1
  689. local partOfName = string.sub( playerName, firstPos, secondPos )
  690. local textLength = dxGetTextWidth( partOfName, fontscale(contentFont, s(1)), contentFont )
  691. dxDrawText( partOfName, xPos+s(1), y+s(1), topX+x+s(1+column.width), y+s(11)+dxGetFontHeight( fontscale(contentFont, scoreboardScale), contentFont ), tocolor( 0, 0, 0, a or 255 ), fontscale(contentFont, s(1)), contentFont, "left", "top", true, false, drawOverGUI )
  692. dxDrawText( partOfName, xPos, y, topX+x+s(column.width), y+dxGetFontHeight( fontscale(contentFont, scoreboardScale), contentFont ), tocolor( r or 255, g or 255, b or 255, a or 255 ), fontscale(contentFont, s(1)), contentFont, "left", "top", true, false, drawOverGUI )
  693. xPos = xPos + textLength
  694. end
  695. if useColors then
  696. r, g, b = v[1][1], v[1][2], v[1][3]
  697. end
  698. local partOfName = string.sub( playerName, firstCodePos, secondCodePos )
  699. local textLength = dxGetTextWidth( partOfName, fontscale(contentFont, s(1)), contentFont )
  700. dxDrawText( partOfName, xPos+s(1), y+s(1), topX+x+s(1+column.width), y+s(11)+dxGetFontHeight( fontscale(contentFont, scoreboardScale), contentFont ), tocolor( 0, 0, 0, a or 255 ), fontscale(contentFont, s(1)), contentFont, "left", "top", true, false, drawOverGUI )
  701. dxDrawText( partOfName, xPos, y, topX+x+s(column.width), y+dxGetFontHeight( fontscale(contentFont, scoreboardScale), contentFont ), tocolor( r or 255, g or 255, b or 255, a or 255 ), fontscale(contentFont, s(1)), contentFont, "left", "top", true, false, drawOverGUI )
  702. xPos = xPos + textLength
  703. end
  704. elseif column.name == "Home" then
  705. dxDrawImage( topX+theX, y+s(1), 16, 11, content, 0, 0, 0, cWhite, drawOverGUI )
  706. else
  707. dxDrawText( content, topX+theX+s(1), y+s(1), topX+x+s(1+column.width), y+s(11)+dxGetFontHeight( fontscale(contentFont, scoreboardScale), contentFont ), tocolor( 0, 0, 0, a or 255 ), fontscale(contentFont, s(1)), contentFont, "left", "top", true, false, drawOverGUI )
  708. dxDrawText( content, topX+theX, y, topX+x+s(column.width), y+dxGetFontHeight( fontscale(contentFont, scoreboardScale), contentFont ), tocolor( r or 255, g or 255, b or 255, a or 255 ), fontscale(contentFont, s(1)), contentFont, "left", "top", true, false, drawOverGUI )
  709. end
  710. end
  711. x = x + s(column.width + 10)
  712. end
  713. end
  714. local font = iif( element and isElement( element ) and getElementType( element ) == "team", teamHeaderFont, contentFont )
  715. y = y + dxGetFontHeight( fontscale(font, scoreboardScale), font )
  716. index = index + 1
  717. end
  718. index = 1
  719. end
  720. end
  721. end
  722.  
  723. -- FUNCTIONS
  724. -- addColumn
  725. function scoreboardAddColumn( name, width, friendlyName, priority, textfunction, fromResource )
  726. if type( name ) == "string" then
  727. width = width or 70
  728. friendlyName = friendlyName or name
  729. priority = tonumber( priority ) or getNextFreePrioritySlot( scoreboardGetColumnPriority( "name" ) )
  730. fixPrioritySlot( priority )
  731. textfunction = textfunction or nil
  732. fromResource = sourceResource or fromResource or nil
  733.  
  734. if not (priority > MAX_PRIRORITY_SLOT or priority < 1) then
  735. for key, value in ipairs( scoreboardColumns ) do
  736. if name == value.name then
  737. return false
  738. end
  739. end
  740. table.insert( scoreboardColumns, { ["name"] = name, ["width"] = width, ["friendlyName"] = friendlyName, ["priority"] = priority, ["textFunction"] = textfunction } )
  741. table.sort( scoreboardColumns, function ( a, b ) return a.priority < b.priority end )
  742. if fromResource then
  743. if not resourceColumns[fromResource] then resourceColumns[fromResource] = {} end
  744. table.insert ( resourceColumns[fromResource], name )
  745. end
  746. return true
  747. end
  748. end
  749. return false
  750. end
  751.  
  752. addEvent( "doScoreboardAddColumn", true )
  753. addEventHandler( "doScoreboardAddColumn", getResourceRootElement(),
  754. function ( name, width, friendlyName, priority, fromResource )
  755. scoreboardAddColumn( name, width, friendlyName, priority, nil, fromResource )
  756. end
  757. )
  758.  
  759. -- removeColumn
  760. function scoreboardRemoveColumn( name )
  761. if type( name ) == "string" then
  762. for key, value in ipairs( scoreboardColumns ) do
  763. if name == value.name then
  764. table.remove( scoreboardColumns, key )
  765. for resource, content in pairs( resourceColumns ) do
  766. table.removevalue( content, name )
  767. end
  768. return true
  769. end
  770. end
  771. end
  772. return false
  773. end
  774.  
  775. addEvent( "doScoreboardRemoveColumn", true )
  776. addEventHandler( "doScoreboardRemoveColumn", getResourceRootElement(),
  777. function ( name )
  778. scoreboardRemoveColumn( name )
  779. end
  780. )
  781.  
  782. -- clearColumns
  783. function scoreboardClearColumns()
  784. while ( scoreboardColumns[1] ) do
  785. table.remove( scoreboardColumns, 1 )
  786. resourceColumns = {}
  787. end
  788. return true
  789. end
  790.  
  791. addEvent( "doScoreboardClearColumns", true )
  792. addEventHandler( "doScoreboardClearColumns", getResourceRootElement(),
  793. function ()
  794. scoreboardClearColumns()
  795. end
  796. )
  797.  
  798. -- resetColumns
  799. function scoreboardResetColumns( fromServer )
  800. while ( scoreboardColumns[1] ) do
  801. table.remove( scoreboardColumns, 1 )
  802. resourceColumns = {}
  803. end
  804. if not fromServer then
  805. scoreboardAddColumn( "name", 200, "Name" )
  806. scoreboardAddColumn( "ping", 40, "Ping" )
  807. end
  808. return true
  809. end
  810.  
  811. addEvent( "doScoreboardResetColumns", true )
  812. addEventHandler( "doScoreboardResetColumns", getResourceRootElement(),
  813. function ( fromServer )
  814. scoreboardResetColumns( iif( fromServer == nil, true, fromServer ) )
  815. end
  816. )
  817.  
  818. -- setForced
  819. function scoreboardSetForced( forced )
  820. scoreboardForced = forced
  821. end
  822.  
  823. addEvent( "doScoreboardSetForced", true )
  824. addEventHandler( "doScoreboardSetForced", getResourceRootElement(),
  825. function ( forced )
  826. scoreboardSetForced( forced )
  827. end
  828. )
  829.  
  830. --Compability
  831. setScoreboardForced = scoreboardSetForced
  832.  
  833. --setSortBy
  834. function scoreboardSetSortBy( name, desc )
  835. if name then
  836. if type( name ) == "string" then
  837. local exists = false
  838. for key, value in ipairs( scoreboardColumns ) do
  839. if name == value.name then
  840. exists = true
  841. end
  842. end
  843. if exists then
  844. desc = iif( type( desc ) == "boolean" and not desc, 1, -1 )
  845. sortBy.what = name
  846. sortBy.dir = desc
  847. end
  848. end
  849. return false
  850. else
  851. sortBy.what = "__NONE__"
  852. sortBy.dir = -1
  853. return true
  854. end
  855. end
  856.  
  857. addEvent( "doScoreboardSetSortBy", true )
  858. addEventHandler( "doScoreboardSetSortBy", getResourceRootElement(),
  859. function ( name, desc )
  860. scoreboardSetSortBy( name, desc )
  861. end
  862. )
  863.  
  864. --getColumnPriority
  865. function scoreboardGetColumnPriority( name )
  866. if type( name ) == "string" then
  867. for key, value in ipairs( scoreboardColumns ) do
  868. if name == value.name then
  869. return value.priority
  870. end
  871. end
  872. end
  873. return false
  874. end
  875.  
  876. --setColumnPriority
  877. function scoreboardSetColumnPriority( name, priority )
  878. if type( name ) == "string" and type( priority ) == "number" then
  879. if not (priority > MAX_PRIRORITY_SLOT or priority < 1) then
  880. local columnIndex = false
  881. for key, value in ipairs( scoreboardColumns ) do
  882. if name == value.name then
  883. columnIndex = key
  884. end
  885. end
  886. if columnIndex then
  887. scoreboardColumns[columnIndex].priority = -1 -- To empty out the current priority
  888. fixPrioritySlot( priority )
  889. scoreboardColumns[columnIndex].priority = priority
  890. table.sort( scoreboardColumns, function ( a, b ) return a.priority < b.priority end )
  891. return true
  892. end
  893. end
  894. end
  895. return false
  896. end
  897.  
  898. addEvent( "doScoreboardSetColumnPriority", true )
  899. addEventHandler( "doScoreboardSetColumnPriority", getResourceRootElement(),
  900. function ( name, priority )
  901. scoreboardSetColumnPriority( name, priority )
  902. end
  903. )
  904.  
  905. --getColumnCount
  906. function scoreboardGetColumnCount()
  907. return #scoreboardColumns
  908. end
  909.  
  910. --setColumnTextFunction
  911. function scoreboardSetColumnTextfunction( name, func )
  912. if type( name ) == "string" then
  913. for key, value in ipairs( scoreboardColumns ) do
  914. if name == value.name then
  915. scoreboardColumns[key].textfunction = func
  916. return true
  917. end
  918. end
  919. end
  920. return false
  921. end
  922.  
  923. function scoreboardGetTopCornerPosition()
  924. if scoreboardDrawn then
  925. local sX, sY = guiGetScreenSize()
  926. local topX, topY = (sX/2)-(calculateWidth()/2), (sY/2)-(calculateHeight()/2)
  927. topY = topY - 15 -- Extra 15 pixels for the scroll up button
  928. return math.floor(topX), math.floor(topY+1)
  929. end
  930. return false
  931. end
  932.  
  933. function scoreboardGetSize()
  934. if scoreboardDrawn then
  935. local width, height = calculateWidth(), calculateHeight()
  936. return width, height
  937. end
  938. return false
  939. end
  940.  
  941. function scoreboardGetSelectedRows()
  942. local rows = {}
  943. for k, v in pairs( selectedRows ) do
  944. table.insert( rows, k )
  945. end
  946. return rows
  947. end
  948.  
  949. -- Other
  950. function calculateWidth()
  951. local width = 0
  952. for key, value in ipairs( scoreboardColumns ) do
  953. width = width + s(value.width + 10)
  954. end
  955. return width + s(10)
  956. end
  957.  
  958. function calculateHeight()
  959. local sX, sY = guiGetScreenSize()
  960. local maxPerWindow = getMaxPerWindow()
  961. local index = firstVisibleIndex
  962. local height = s(5)
  963. if (serverInfo.server or serverInfo.players) and showServerInfo then height = height+dxGetFontHeight( fontscale(serverInfoFont, scoreboardScale), serverInfoFont ) end
  964. if (serverInfo.gamemode or serverInfo.map) and showGamemodeInfo then height = height+dxGetFontHeight( fontscale(serverInfoFont, scoreboardScale), serverInfoFont ) end
  965. height = height+s(3)
  966. height = height+s(5)+dxGetFontHeight( fontscale(columnFont, scoreboardScale), columnFont )
  967. height = height+s(5)+dxGetFontHeight( fontscale(rmbFont, s(0.75)), rmbFont )
  968. height = height+s(2)
  969. while ( index < firstVisibleIndex+maxPerWindow and scoreboardContent[index] ) do
  970. local element = scoreboardContent[index]["__SCOREBOARDELEMENT__"]
  971. if element and isElement( element ) and getElementType( element ) == "team" then
  972. height = height + dxGetFontHeight( fontscale(teamHeaderFont, scoreboardScale), teamHeaderFont )
  973. else
  974. height = height + dxGetFontHeight( fontscale(contentFont, scoreboardScale), contentFont )
  975. end
  976. index = index + 1
  977. end
  978. return height
  979. end
  980.  
  981. function showTheCursor( _, state )
  982. if state == "down" then
  983. showCursor( true )
  984. else
  985. if not (windowSettings and isElement( windowSettings )) then
  986. showCursor( false )
  987. end
  988. end
  989. end
  990.  
  991. function scrollScoreboard( _, _, upOrDown )
  992. if isCursorShowing() then
  993. local index = firstVisibleIndex
  994. local maxPerWindow = getMaxPerWindow()
  995. local highestIndex = #scoreboardContent - maxPerWindow + 1
  996. if index >= 1 and index <= highestIndex then
  997. local newIndex = math.max(1,math.min(index + upOrDown * serverInfo.scrollStep,highestIndex))
  998. if index ~= newIndex then
  999. firstVisibleIndex = newIndex
  1000. bForceUpdate = true
  1001. end
  1002. end
  1003. end
  1004. end
  1005.  
  1006. function math.clamp( low, value, high )
  1007. return math.max( low, math.min( value, high ) )
  1008. end
  1009.  
  1010. function fromcolor( color )
  1011. -- Propably not the most efficient way, but only way it works
  1012. local colorCode = string.format( "%x", color )
  1013. local a = string.sub( colorCode, 1, 2 ) or "FF"
  1014. local r = string.sub( colorCode, 3, 4 ) or "FF"
  1015. local g = string.sub( colorCode, 5, 6 ) or "FF"
  1016. local b = string.sub( colorCode, 7, 8 ) or "FF"
  1017. a = tonumber( "0x" .. a )
  1018. r = tonumber( "0x" .. r )
  1019. g = tonumber( "0x" .. g )
  1020. b = tonumber( "0x" .. b )
  1021. return r, g, b, a
  1022. end
  1023.  
  1024. function scale( value )
  1025. return value*scoreboardScale
  1026. end
  1027. s = scale
  1028.  
  1029. function fontscale( font, value )
  1030. return value*fontScale[font]
  1031. end
  1032.  
  1033. function scoreboardSortfunction( a, b )
  1034. local firstContent, secondContent
  1035. local sortByA
  1036. if a[sortBy.what] and type( a[sortBy.what] ) == "table" and sortBy.what == "name" then
  1037. sortByA = a[sortBy.what][1]
  1038. else
  1039. sortByA = a[sortBy.what]
  1040. end
  1041. local sortByB
  1042. if b[sortBy.what] and type( b[sortBy.what] ) == "table" and sortBy.what == "name" then
  1043. sortByB = b[sortBy.what][1]
  1044. else
  1045. sortByB = b[sortBy.what]
  1046. end
  1047. if tonumber( sortByA ) then
  1048. firstContent = tonumber( sortByA )
  1049. else
  1050. if sortByA then
  1051. firstContent = string.lower( tostring( sortByA ) )
  1052. else
  1053. firstContent = ""
  1054. end
  1055. end
  1056. if tonumber( sortByB ) then
  1057. secondContent = tonumber( sortByB )
  1058. else
  1059. if sortByB then
  1060. secondContent = string.lower( tostring( sortByB ) )
  1061. else
  1062. secondContent = ""
  1063. end
  1064. end
  1065. if type( sortBy.dir ) == "number" then
  1066. if type( firstContent ) == type( secondContent ) then
  1067. else
  1068. firstContent = string.lower( tostring( firstContent ) )
  1069. secondContent = string.lower( tostring( secondContent ) )
  1070. end
  1071. return iif( sortBy.dir == 1, firstContent > secondContent, firstContent < secondContent )
  1072. end
  1073. return false
  1074. end
  1075.  
  1076. function getMaxPerWindow()
  1077. local sX, sY = guiGetScreenSize()
  1078. local availableHeight = sY-(seperationSpace*2)-s(5)
  1079. if (serverInfo.server or serverInfo.players) and showServerInfo then availableHeight = availableHeight-dxGetFontHeight( fontscale(serverInfoFont, scoreboardScale), serverInfoFont ) end
  1080. if (serverInfo.gamemode or serverInfo.map) and showGamemodeInfo then availableHeight = availableHeight-dxGetFontHeight( fontscale(serverInfoFont, scoreboardScale), serverInfoFont ) end
  1081. availableHeight = availableHeight-s(3)
  1082. availableHeight = availableHeight-s(5)-dxGetFontHeight( fontscale(columnFont, scoreboardScale), columnFont )
  1083. availableHeight = availableHeight-s(5)-dxGetFontHeight( fontscale(rmbFont, s(0.75)), rmbFont )
  1084. availableHeight = availableHeight-s(2)
  1085.  
  1086. local index = firstVisibleIndex
  1087. local count = 0
  1088. local height = 0
  1089. while ( scoreboardContent[index] ) do
  1090. local element = scoreboardContent[index]["__SCOREBOARDELEMENT__"]
  1091. if element and isElement( element ) and getElementType( element ) == "team" then
  1092. height = height + dxGetFontHeight( fontscale(teamHeaderFont, scoreboardScale), teamHeaderFont )
  1093. else
  1094. height = height + dxGetFontHeight( fontscale(contentFont, scoreboardScale), contentFont )
  1095. end
  1096. if height >= availableHeight then
  1097. return count
  1098. end
  1099. index = index + 1
  1100. count = count + 1
  1101. end
  1102. return count
  1103. end
  1104.  
  1105. function scoreboardClickHandler( button, state, cX, cY )
  1106. if scoreboardDrawn and button == "left" and state == "down" then
  1107. local sX, sY = guiGetScreenSize()
  1108. local topX, topY = (sX/2)-(calculateWidth()/2), (sY/2)-(calculateHeight()/2)
  1109. local xMin, xMax, yMin, yMax = topX, topX+calculateWidth(), topY, topY+calculateHeight()
  1110. local maxPerWindow = getMaxPerWindow()
  1111. if cX >= xMin and cX <= xMax and cY >= yMin and cY <= yMax then
  1112. local clickedOnColumn = false
  1113. local x = s(10)
  1114. local y = s(5)+s(3)
  1115. if (serverInfo.server or serverInfo.players) and showServerInfo then y = y + dxGetFontHeight( fontscale(serverInfoFont, scoreboardScale), serverInfoFont ) end
  1116. if (serverInfo.gamemode or serverInfo.map) and showGamemodeInfo then y = y + dxGetFontHeight( fontscale(serverInfoFont, scoreboardScale), serverInfoFont ) end
  1117. for key, column in ipairs( scoreboardColumns ) do
  1118. if cX >= topX+x and cX <= topX+x+s(column.width) and cY >= topY+y and cY <= topY+y+dxGetFontHeight( fontscale(contentFont, scoreboardScale), contentFont ) then
  1119. clickedOnColumn = column.name
  1120. end
  1121. x = x + s(column.width + 10)
  1122. end
  1123. if clickedOnColumn then
  1124. if sortBy.what == clickedOnColumn then -- last click was this column
  1125. sortBy.dir = sortBy.dir + 2
  1126. if sortBy.dir > 1 then
  1127. sortBy.what = "__NONE__"
  1128. sortBy.dir = -1
  1129. end
  1130. else
  1131. sortBy.what = clickedOnColumn
  1132. sortBy.dir = -1
  1133. end
  1134. forceScoreboardUpdate = true
  1135. end
  1136.  
  1137. -- Settings button
  1138. local bottomX, bottomY = topX+calculateWidth(), topY+calculateHeight()
  1139. textLength = dxGetTextWidth( "settings...", fontscale(sbFont, s(sbFontScale)), sbFont )
  1140. textHeight = dxGetFontHeight( fontscale(sbFont, s(sbFontScale)), sbFont )
  1141. if cX >= bottomX-s(sbOutOffset+2*sbInOffset+2)-textLength and cX <= bottomX-s(sbOutOffset+1) and cY >= bottomY-s(sbOutOffset+2*sbInOffset+1)-textHeight and cY <= bottomY-s(sbOutOffset+1) then
  1142. if not (windowSettings and isElement( windowSettings ) and guiGetVisible( windowSettings )) then
  1143. createScoreboardSettingsWindow( sX-323, sY-350 )
  1144. elseif isElement( windowSettings ) then
  1145. destroyScoreboardSettingsWindow()
  1146. end
  1147. end
  1148. end
  1149.  
  1150. -- Scroll buttons
  1151. if firstVisibleIndex > 1 then
  1152. if cX >= sX/2-8 and cX <= sX/2-8+17 and cY >= topY-15 and cY <= topY-15+11 then
  1153. scrollScoreboard( nil, nil, -1 )
  1154. end
  1155. end
  1156. if firstVisibleIndex+maxPerWindow <= #scoreboardContent and #scoreboardContent > maxPerWindow then
  1157. if cX >= sX/2-8 and cX <= sX/2-8+17 and cY >= topY+calculateHeight()+4 and cY <= topY+calculateHeight()+4+11 then
  1158. scrollScoreboard( nil, nil, 1 )
  1159. end
  1160. end
  1161.  
  1162. -- Player/team click
  1163. local y = topY+s(5)
  1164. if (serverInfo.server or serverInfo.players) and showServerInfo then y = y+dxGetFontHeight( fontscale(serverInfoFont, scoreboardScale), serverInfoFont ) end
  1165. if (serverInfo.gamemode or serverInfo.map) and showGamemodeInfo then y = y+dxGetFontHeight( fontscale(serverInfoFont, scoreboardScale), serverInfoFont ) end
  1166. y = y+s(3)
  1167. y = y+s(5)+dxGetFontHeight( fontscale(columnFont, scoreboardScale), columnFont )
  1168. if cY >= y and cX then
  1169. local index = firstVisibleIndex
  1170. local maxPerWindow = getMaxPerWindow()
  1171. local topX, topY = (sX/2)-(calculateWidth()/2), (sY/2)-(calculateHeight()/2)
  1172. local width = calculateWidth()
  1173. while ( index < firstVisibleIndex+maxPerWindow and scoreboardContent[index] ) do
  1174. local element = scoreboardContent[index]["__SCOREBOARDELEMENT__"]
  1175. local font = iif( element and isElement( element ) and getElementType( element ) == "team", teamHeaderFont, contentFont )
  1176. if cX >= topX+s(5) and cX <= topX+width-s(5) and cY >= y and cY <= y+dxGetFontHeight( fontscale(font, scoreboardScale), font ) then
  1177. local selected = (not selectedRows[element]) == true
  1178. local triggered = triggerEvent( "onClientPlayerScoreboardClick", element, selected, cX, cY )
  1179. if triggered then
  1180. selectedRows[element] = not selectedRows[element]
  1181. end
  1182. end
  1183. y = y + dxGetFontHeight( fontscale(font, scoreboardScale), font )
  1184. index = index + 1
  1185. end
  1186. end
  1187. end
  1188. end
  1189.  
  1190. function removeResourceScoreboardColumns( resource )
  1191. if resourceColumns[resource] then
  1192. while resourceColumns[resource][1] do
  1193. local success = scoreboardRemoveColumn( resourceColumns[resource][1] )
  1194. if not success then break end
  1195. end
  1196. resourceColumns[resource] = nil
  1197. end
  1198. end
  1199. addEventHandler( "onClientResourceStop", getRootElement(), removeResourceScoreboardColumns )
Advertisement
Add Comment
Please, Sign In to add comment