Advertisement
Guest User

Untitled

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