NNickey

Untitled

Dec 26th, 2017
173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.54 KB | None | 0 0
  1. local function WaitForChild(parent, instance)
  2. while parent:FindFirstChild(instance) == nil do
  3. wait()
  4. end
  5. return parent[instance]
  6. end
  7.  
  8. -- Global vars -----
  9. --- CONSTANTS ----
  10. local FRAME_X_MARGIN_SIZE = 20
  11. local FRAME_Y_OFFSET = 160
  12. local PLAYER_LIST_START_Y_OFFSET = 43
  13. local PIXELS_Y_BETWEEN_PLAYER_ROWS = 20
  14. local PIXELS_X_BETWEEN_STAT_COLUMNS = 65
  15. local PLAYERS_X_PADDING_PIXELS = 10
  16.  
  17.  
  18. local DARK_FONT_COLOR = Color3.new(0, 0, 0)
  19. local LIGHT_FONT_COLOR = Color3.new(1, 1, 1)
  20. local TOGGLES = false
  21.  
  22. local PlayersService = game.Players
  23. local MainGui = script.Parent
  24. local LeaderboardFrame = WaitForChild(MainGui, "LeaderboardFrame")
  25. local LeaderboardButton = WaitForChild(MainGui, 'LeaderboardButton')
  26. local TeamsService = game:GetService("Teams")
  27. local DebrisService = game:GetService("Debris")
  28. --local MyMouse = PlayersService.localPlayer:GetMouse()
  29. local PlayerFieldsList = {} -- This one stores all the fields to help in removal
  30. local Gui = {} -- Class, that contains functions to create various gui objects
  31.  
  32. -- This variable tells us if atleast one team exists
  33. local TeamsExist = false
  34. -- In here we store a parallel representation of the leaderboard gui heirarchy in the data model
  35. local TeamFramesList = {}
  36. -- This table lets us index a TeamColor to the GUI for that team
  37. local TeamColorToTeamFrame = {}
  38.  
  39. local StatTextLabel = Instance.new("TextLabel")
  40. StatTextLabel.Font = Enum.Font.Legacy
  41. StatTextLabel.FontSize = Enum.FontSize.Size10
  42. StatTextLabel.BackgroundTransparency = 1.0
  43. StatTextLabel.Size = UDim2.new(0, 0, 0, 0)
  44. StatTextLabel.TextXAlignment = Enum.TextXAlignment.Right
  45. StatTextLabel.ZIndex = 10
  46. StatTextLabel.TextColor3 = LIGHT_FONT_COLOR
  47.  
  48.  
  49. local PlayerTextLabel = Instance.new("TextLabel")
  50. PlayerTextLabel.BackgroundTransparency = 1.0
  51. PlayerTextLabel.Font = Enum.Font.Arial
  52. PlayerTextLabel.FontSize = Enum.FontSize.Size18
  53. PlayerTextLabel.Size = UDim2.new(0, 0, 0, 0)
  54. PlayerTextLabel.TextXAlignment = Enum.TextXAlignment.Left
  55. PlayerTextLabel.ZIndex = 10
  56. PlayerTextLabel.TextColor3 = LIGHT_FONT_COLOR
  57.  
  58.  
  59. -- For luminance calculation formula look at: http://en.wikipedia.org/wiki/Grayscale
  60. local function IsDark(color)
  61. local cieLuminance = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b
  62. return cieLuminance < 0.5
  63. end
  64.  
  65. local function CreateTeamFrames()
  66. local numberOfTeams = #TeamsService:GetTeams()
  67. local sizeOfTeamFrame = math.min(1 / 3, 1 / numberOfTeams)
  68. local templateFrame = LeaderboardFrame:FindFirstChild('TemplateFrame')
  69. for teamNumber, team in pairs(TeamsService:GetTeams()) do
  70. if templateFrame then
  71. local newTeamFrame = templateFrame:Clone()
  72. newTeamFrame.Name = team.Name
  73. newTeamFrame.Visible = true
  74. newTeamFrame.BackgroundColor3 = team.TeamColor.Color
  75. newTeamFrame.Parent = LeaderboardFrame
  76. newTeamFrame.Position = UDim2.new(sizeOfTeamFrame * (teamNumber - 1), FRAME_X_MARGIN_SIZE, 0, FRAME_Y_OFFSET)
  77. -- This special case is needed because we math.min the size of the frame
  78. if numberOfTeams == 1 then
  79. newTeamFrame.Position = UDim2.new(0.25, 20, 0, 160)
  80. sizeOfTeamFrame = 0.5
  81. elseif numberOfTeams == 2 then
  82. newTeamFrame.Position = UDim2.new((1 - (2 / 3)) / 2 + 1 / 3 * (teamNumber - 1), FRAME_X_MARGIN_SIZE, 0, FRAME_Y_OFFSET)
  83. end
  84. newTeamFrame.Size = UDim2.new(sizeOfTeamFrame, -2 * FRAME_X_MARGIN_SIZE, 0.5, 0)
  85. if newTeamFrame:FindFirstChild('Team') then
  86. newTeamFrame:FindFirstChild('Team').Text = team.Name
  87. end
  88. TeamColorToTeamFrame[team.TeamColor.Name] = newTeamFrame
  89. end
  90. end
  91. end
  92.  
  93. local function CreateNeutralTeamFrame()
  94. local templateFrame = LeaderboardFrame:FindFirstChild('TemplateFrame')
  95. if templateFrame then
  96. local newTeamFrame = templateFrame:Clone()
  97. newTeamFrame.Name = "TeamlessFrame"
  98. newTeamFrame.Visible = true
  99. newTeamFrame.BackgroundColor3 = BrickColor.new("Black").Color
  100. newTeamFrame.Parent = LeaderboardFrame
  101. newTeamFrame.Position = UDim2.new(0.25, 0, 0, FRAME_Y_OFFSET)
  102. newTeamFrame.Size = UDim2.new(1 / 2, 0, 0.7, 0)
  103. if newTeamFrame:FindFirstChild('Team') then
  104. newTeamFrame:FindFirstChild('Team').Text = "Scores"
  105. end
  106. end
  107. end
  108.  
  109. --[[
  110.  
  111. // Here is the thing - if the Leaderboard frame is split into multiple frames
  112. // we assume that each of those frames represent different teams and
  113. // that they are positioned correctly
  114. ]]
  115.  
  116. local function MirrorTemplateFrame()
  117. -- The team color thing is annoying, ideally I want the frames
  118. -- to be named by the team names instead of ridiculous team color things
  119. -- But in this case, the frames are named after the brick color string
  120. local TeamFrames = LeaderboardFrame:GetChildren()
  121. for i = 1, #TeamFrames do
  122. if TeamFrames[i] then
  123. TeamsExist = true
  124. local t = {}
  125. local CurrentTeamFrame = TeamFrames[i]
  126. t[CurrentTeamFrame] = {}
  127. local CurrentTeamElements = TeamFrames[i]:GetChildren()
  128. for j = 1, #CurrentTeamElements do
  129. table.insert(t[CurrentTeamFrame], CurrentTeamElements[j])
  130. end
  131. table.insert(TeamFramesList, t)
  132. end
  133. end
  134. end
  135.  
  136. local function ClearLeaderboardFrame()
  137. -- Clear the entire leaderboard so that we can repopulate it with new info
  138. LeaderboardFrame:ClearAllChildren()
  139. for _, t in pairs(TeamFramesList) do
  140. for frame, children in pairs(t) do
  141. frame.Parent = LeaderboardFrame
  142. for i = 1, #children do
  143. children[i].Parent = frame
  144. end
  145. frame.Parent = LeaderboardFrame
  146. end
  147. end
  148. end
  149.  
  150. -- Currently we are clearing the leaderboard and recreating it so
  151. -- that it will stay up to date no matter what kinds of stat changes
  152. -- player joins/leaves occur
  153. local function PopulateLeaderboard()
  154. -- First clear the leaderboard
  155. if TeamsExist then
  156. ClearLeaderboardFrame()
  157. end
  158.  
  159. -- Add the labels for the stat columns
  160. if PlayersService.LocalPlayer ~= nil then
  161. for _, t in pairs(TeamFramesList) do
  162. for frame, children in pairs(t) do
  163. -- Update each teams scores by finding the team that corresponds to this frame
  164. local frameTeamColor
  165. for _, team in pairs(TeamsService:GetTeams()) do
  166. if team.Name == frame.Name then
  167. frameTeamColor = team.TeamColor
  168. if frame:FindFirstChild('TeamScore') ~= nil then
  169. frame:FindFirstChild('TeamScore').Text = team.Score
  170. end
  171. end
  172. end
  173. -- Get the leaderstats object
  174. local leaderstats = WaitForChild(PlayersService.LocalPlayer, "leaderstats")
  175. local leaderstatsList = leaderstats:GetChildren()
  176. local counter = 0
  177. for _, stat in pairs(leaderstatsList) do
  178. -- For each stat we create a label for the column
  179. if stat:IsA("IntValue") or stat:IsA("NumberValue") or stat:IsA("StringValue") then
  180. local stat_TextLabel = StatTextLabel:Clone()
  181. stat_TextLabel.Name = stat.Name
  182. stat_TextLabel.Text = stat.Name
  183. stat_TextLabel.Position = UDim2.new(1, (-PIXELS_X_BETWEEN_STAT_COLUMNS * counter) - PLAYERS_X_PADDING_PIXELS, 0, 15)
  184. stat_TextLabel.Parent = frame
  185.  
  186. counter = counter + 1
  187. -- For each stat create a sum label at the bottom
  188. local sum = 0
  189. for _, player in pairs(PlayersService:GetPlayers()) do
  190. if frameTeamColor and player.TeamColor == frameTeamColor and player:FindFirstChild('leaderstats') then
  191. local currStat = player:FindFirstChild('leaderstats'):FindFirstChild(stat.Name)
  192. if currStat:IsA('IntValue') or currStat:IsA('NumberValue') or currStat:IsA('IntConstrainedValue') then
  193. sum = sum + currStat.Value
  194. end
  195. end
  196. end
  197. local stat_SumLabel = stat_TextLabel:Clone()
  198. stat_SumLabel.Name = "Team" .. stat_TextLabel.Name
  199. stat_SumLabel.Text = sum
  200. stat_SumLabel.Position = UDim2.new(stat_TextLabel.Position.X.Scale, stat_TextLabel.Position.X.Offset, 1, -20)
  201. stat_SumLabel.Parent = frame
  202. end
  203. end
  204. end
  205. end
  206. end
  207.  
  208. -- This variable will keep track of how many players are in each team's frame
  209. -- so we now how far down to put the next player in the score list
  210. local numberOfPlayersInTeamSoFar = {}
  211.  
  212. local players = PlayersService:GetPlayers()
  213. for i = 1, #players do
  214. if players[i] then
  215. local xOffset = 0
  216. local yOffset = 0
  217. -- Get the leaderstats object
  218. local leaderstats = WaitForChild(players[i], "leaderstats")
  219. local leaderstatsList = leaderstats:GetChildren()
  220. -- Create the player name
  221. local playerName_TextLabel = PlayerTextLabel:Clone()
  222. playerName_TextLabel.Name = players[i].Name
  223. playerName_TextLabel.Text = players[i].Name
  224.  
  225. -- If we have frames for each team, then encapsulate the score inside their team's frame
  226. if TeamsExist and TeamColorToTeamFrame[players[i].TeamColor.Name] ~= nil then
  227. local teamFrame = TeamColorToTeamFrame[players[i].TeamColor.Name]
  228. -- Create or increment the player count
  229. if not numberOfPlayersInTeamSoFar[players[i].TeamColor.Name] then
  230. numberOfPlayersInTeamSoFar[players[i].TeamColor.Name] = 1
  231. else
  232. numberOfPlayersInTeamSoFar[players[i].TeamColor.Name] = numberOfPlayersInTeamSoFar[players[i].TeamColor.Name] + 1
  233. end
  234. playerName_TextLabel.Parent = teamFrame
  235. yOffset = PLAYER_LIST_START_Y_OFFSET +
  236. (numberOfPlayersInTeamSoFar[players[i].TeamColor.Name] - 1) * PIXELS_Y_BETWEEN_PLAYER_ROWS
  237. playerName_TextLabel.Position = UDim2.new(0, PLAYERS_X_PADDING_PIXELS, 0, yOffset)
  238. elseif #TeamsService:GetTeams() == 0 then -- Otherwise we will fallback to putting the score inside the root of leaderboard
  239. if not LeaderboardFrame:FindFirstChild('TeamlessFrame') then CreateNeutralTeamFrame() end
  240. local teamlessFrame = LeaderboardFrame:FindFirstChild('TeamlessFrame')
  241. if not numberOfPlayersInTeamSoFar['Neutral'] then
  242. numberOfPlayersInTeamSoFar['Neutral'] = 1
  243. else
  244. numberOfPlayersInTeamSoFar['Neutral'] = numberOfPlayersInTeamSoFar['Neutral'] + 1
  245. end
  246. playerName_TextLabel.Parent = teamlessFrame
  247. yOffset = PLAYER_LIST_START_Y_OFFSET +
  248. (numberOfPlayersInTeamSoFar['Neutral'] - 1) * PIXELS_Y_BETWEEN_PLAYER_ROWS
  249. playerName_TextLabel.Position = UDim2.new(0, PLAYERS_X_PADDING_PIXELS, 0, yOffset)
  250. end
  251.  
  252. -- For this player we will incrementally place their leaderstats to the right of their name
  253. local counter = 0
  254. for _, stat in pairs(leaderstatsList) do
  255. if stat:IsA("IntValue") or stat:IsA("NumberValue") or stat:IsA("StringValue") then
  256. local stat_TextLabel = playerName_TextLabel:Clone()
  257. stat_TextLabel.Text = stat.Value
  258. stat_TextLabel.Position = UDim2.new(1, -PIXELS_X_BETWEEN_STAT_COLUMNS * counter - PLAYERS_X_PADDING_PIXELS, 0, yOffset)
  259. stat_TextLabel.TextXAlignment = Enum.TextXAlignment.Right
  260. stat_TextLabel.Parent = playerName_TextLabel.Parent
  261.  
  262. counter = counter + 1
  263. -- If this player isn't on a team then we can add up their points in the neutral team window
  264. if not TeamsExist or TeamColorToTeamFrame[players[i].TeamColor.Name] == nil then
  265. local teamlessFrame = LeaderboardFrame:FindFirstChild('TeamlessFrame')
  266. if teamlessFrame and teamlessFrame:FindFirstChild("Team" .. stat.Name) then
  267. local statLabel = teamlessFrame:FindFirstChild("Team" .. stat.Name)
  268. -- Make sure that statlabel's value can be turned into a number
  269. if tonumber(statLabel.Text) then statLabel.Text = tonumber(statLabel.Text) + stat.Value end
  270. else
  271. print("No teamlessframe")
  272. end
  273. end
  274.  
  275. end
  276. end
  277. end
  278. end
  279. -- Change all the text and color within the frame to contrast with the background
  280. for _, frame in pairs(TeamColorToTeamFrame) do
  281. local textColor = DARK_FONT_COLOR
  282. if IsDark(frame.BackgroundColor3) then
  283. textColor = LIGHT_FONT_COLOR
  284. end
  285. for _, item in pairs(frame:GetChildren()) do
  286. if item.Name == 'Team' or item.Name == 'TeamScore' then
  287. --skip
  288. elseif item:IsA('TextLabel') then
  289. item.TextColor3 = textColor
  290. elseif item:IsA('Frame') then
  291. item.BorderColor3 = textColor
  292. end
  293. end
  294. end
  295. end
  296.  
  297. --[[MyMouse.KeyDown:connect(function(key)
  298. if string.lower(key) == 'q' then
  299. if LeaderboardFrame then
  300. if TOGGLES then
  301. LeaderboardFrame.Visible = not LeaderboardFrame.Visible
  302. else
  303. LeaderboardFrame.Visible = true
  304. end
  305. end
  306. end
  307. end)]]
  308.  
  309. --[[MyMouse.KeyUp:connect(function(key)
  310. if string.lower(key) == 'q' then
  311. if LeaderboardFrame then
  312. if not TOGGLES then
  313. LeaderboardFrame.Visible = false
  314. end
  315. end
  316. end
  317. end)]]
  318.  
  319. LeaderboardButton.MouseButton1Click:connect(function()
  320. LeaderboardFrame.Visible = not LeaderboardFrame.Visible
  321. end)
  322.  
  323.  
  324. CreateTeamFrames()
  325. MirrorTemplateFrame()
  326. PopulateLeaderboard()
  327. Spawn(function() while true do
  328. PopulateLeaderboard()
  329. wait(3)
  330. end
  331. end)
Advertisement
Add Comment
Please, Sign In to add comment