Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local function WaitForChild(parent, instance)
- while parent:FindFirstChild(instance) == nil do
- wait()
- end
- return parent[instance]
- end
- -- Global vars -----
- --- CONSTANTS ----
- local FRAME_X_MARGIN_SIZE = 20
- local FRAME_Y_OFFSET = 160
- local PLAYER_LIST_START_Y_OFFSET = 43
- local PIXELS_Y_BETWEEN_PLAYER_ROWS = 20
- local PIXELS_X_BETWEEN_STAT_COLUMNS = 65
- local PLAYERS_X_PADDING_PIXELS = 10
- local DARK_FONT_COLOR = Color3.new(0, 0, 0)
- local LIGHT_FONT_COLOR = Color3.new(1, 1, 1)
- local TOGGLES = false
- local PlayersService = game.Players
- local MainGui = script.Parent
- local LeaderboardFrame = WaitForChild(MainGui, "LeaderboardFrame")
- local LeaderboardButton = WaitForChild(MainGui, 'LeaderboardButton')
- local TeamsService = game:GetService("Teams")
- local DebrisService = game:GetService("Debris")
- --local MyMouse = PlayersService.localPlayer:GetMouse()
- local PlayerFieldsList = {} -- This one stores all the fields to help in removal
- local Gui = {} -- Class, that contains functions to create various gui objects
- -- This variable tells us if atleast one team exists
- local TeamsExist = false
- -- In here we store a parallel representation of the leaderboard gui heirarchy in the data model
- local TeamFramesList = {}
- -- This table lets us index a TeamColor to the GUI for that team
- local TeamColorToTeamFrame = {}
- local StatTextLabel = Instance.new("TextLabel")
- StatTextLabel.Font = Enum.Font.Legacy
- StatTextLabel.FontSize = Enum.FontSize.Size10
- StatTextLabel.BackgroundTransparency = 1.0
- StatTextLabel.Size = UDim2.new(0, 0, 0, 0)
- StatTextLabel.TextXAlignment = Enum.TextXAlignment.Right
- StatTextLabel.ZIndex = 10
- StatTextLabel.TextColor3 = LIGHT_FONT_COLOR
- local PlayerTextLabel = Instance.new("TextLabel")
- PlayerTextLabel.BackgroundTransparency = 1.0
- PlayerTextLabel.Font = Enum.Font.Arial
- PlayerTextLabel.FontSize = Enum.FontSize.Size18
- PlayerTextLabel.Size = UDim2.new(0, 0, 0, 0)
- PlayerTextLabel.TextXAlignment = Enum.TextXAlignment.Left
- PlayerTextLabel.ZIndex = 10
- PlayerTextLabel.TextColor3 = LIGHT_FONT_COLOR
- -- For luminance calculation formula look at: http://en.wikipedia.org/wiki/Grayscale
- local function IsDark(color)
- local cieLuminance = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b
- return cieLuminance < 0.5
- end
- local function CreateTeamFrames()
- local numberOfTeams = #TeamsService:GetTeams()
- local sizeOfTeamFrame = math.min(1 / 3, 1 / numberOfTeams)
- local templateFrame = LeaderboardFrame:FindFirstChild('TemplateFrame')
- for teamNumber, team in pairs(TeamsService:GetTeams()) do
- if templateFrame then
- local newTeamFrame = templateFrame:Clone()
- newTeamFrame.Name = team.Name
- newTeamFrame.Visible = true
- newTeamFrame.BackgroundColor3 = team.TeamColor.Color
- newTeamFrame.Parent = LeaderboardFrame
- newTeamFrame.Position = UDim2.new(sizeOfTeamFrame * (teamNumber - 1), FRAME_X_MARGIN_SIZE, 0, FRAME_Y_OFFSET)
- -- This special case is needed because we math.min the size of the frame
- if numberOfTeams == 1 then
- newTeamFrame.Position = UDim2.new(0.25, 20, 0, 160)
- sizeOfTeamFrame = 0.5
- elseif numberOfTeams == 2 then
- newTeamFrame.Position = UDim2.new((1 - (2 / 3)) / 2 + 1 / 3 * (teamNumber - 1), FRAME_X_MARGIN_SIZE, 0, FRAME_Y_OFFSET)
- end
- newTeamFrame.Size = UDim2.new(sizeOfTeamFrame, -2 * FRAME_X_MARGIN_SIZE, 0.5, 0)
- if newTeamFrame:FindFirstChild('Team') then
- newTeamFrame:FindFirstChild('Team').Text = team.Name
- end
- TeamColorToTeamFrame[team.TeamColor.Name] = newTeamFrame
- end
- end
- end
- local function CreateNeutralTeamFrame()
- local templateFrame = LeaderboardFrame:FindFirstChild('TemplateFrame')
- if templateFrame then
- local newTeamFrame = templateFrame:Clone()
- newTeamFrame.Name = "TeamlessFrame"
- newTeamFrame.Visible = true
- newTeamFrame.BackgroundColor3 = BrickColor.new("Black").Color
- newTeamFrame.Parent = LeaderboardFrame
- newTeamFrame.Position = UDim2.new(0.25, 0, 0, FRAME_Y_OFFSET)
- newTeamFrame.Size = UDim2.new(1 / 2, 0, 0.7, 0)
- if newTeamFrame:FindFirstChild('Team') then
- newTeamFrame:FindFirstChild('Team').Text = "Scores"
- end
- end
- end
- --[[
- // Here is the thing - if the Leaderboard frame is split into multiple frames
- // we assume that each of those frames represent different teams and
- // that they are positioned correctly
- ]]
- local function MirrorTemplateFrame()
- -- The team color thing is annoying, ideally I want the frames
- -- to be named by the team names instead of ridiculous team color things
- -- But in this case, the frames are named after the brick color string
- local TeamFrames = LeaderboardFrame:GetChildren()
- for i = 1, #TeamFrames do
- if TeamFrames[i] then
- TeamsExist = true
- local t = {}
- local CurrentTeamFrame = TeamFrames[i]
- t[CurrentTeamFrame] = {}
- local CurrentTeamElements = TeamFrames[i]:GetChildren()
- for j = 1, #CurrentTeamElements do
- table.insert(t[CurrentTeamFrame], CurrentTeamElements[j])
- end
- table.insert(TeamFramesList, t)
- end
- end
- end
- local function ClearLeaderboardFrame()
- -- Clear the entire leaderboard so that we can repopulate it with new info
- LeaderboardFrame:ClearAllChildren()
- for _, t in pairs(TeamFramesList) do
- for frame, children in pairs(t) do
- frame.Parent = LeaderboardFrame
- for i = 1, #children do
- children[i].Parent = frame
- end
- frame.Parent = LeaderboardFrame
- end
- end
- end
- -- Currently we are clearing the leaderboard and recreating it so
- -- that it will stay up to date no matter what kinds of stat changes
- -- player joins/leaves occur
- local function PopulateLeaderboard()
- -- First clear the leaderboard
- if TeamsExist then
- ClearLeaderboardFrame()
- end
- -- Add the labels for the stat columns
- if PlayersService.LocalPlayer ~= nil then
- for _, t in pairs(TeamFramesList) do
- for frame, children in pairs(t) do
- -- Update each teams scores by finding the team that corresponds to this frame
- local frameTeamColor
- for _, team in pairs(TeamsService:GetTeams()) do
- if team.Name == frame.Name then
- frameTeamColor = team.TeamColor
- if frame:FindFirstChild('TeamScore') ~= nil then
- frame:FindFirstChild('TeamScore').Text = team.Score
- end
- end
- end
- -- Get the leaderstats object
- local leaderstats = WaitForChild(PlayersService.LocalPlayer, "leaderstats")
- local leaderstatsList = leaderstats:GetChildren()
- local counter = 0
- for _, stat in pairs(leaderstatsList) do
- -- For each stat we create a label for the column
- if stat:IsA("IntValue") or stat:IsA("NumberValue") or stat:IsA("StringValue") then
- local stat_TextLabel = StatTextLabel:Clone()
- stat_TextLabel.Name = stat.Name
- stat_TextLabel.Text = stat.Name
- stat_TextLabel.Position = UDim2.new(1, (-PIXELS_X_BETWEEN_STAT_COLUMNS * counter) - PLAYERS_X_PADDING_PIXELS, 0, 15)
- stat_TextLabel.Parent = frame
- counter = counter + 1
- -- For each stat create a sum label at the bottom
- local sum = 0
- for _, player in pairs(PlayersService:GetPlayers()) do
- if frameTeamColor and player.TeamColor == frameTeamColor and player:FindFirstChild('leaderstats') then
- local currStat = player:FindFirstChild('leaderstats'):FindFirstChild(stat.Name)
- if currStat:IsA('IntValue') or currStat:IsA('NumberValue') or currStat:IsA('IntConstrainedValue') then
- sum = sum + currStat.Value
- end
- end
- end
- local stat_SumLabel = stat_TextLabel:Clone()
- stat_SumLabel.Name = "Team" .. stat_TextLabel.Name
- stat_SumLabel.Text = sum
- stat_SumLabel.Position = UDim2.new(stat_TextLabel.Position.X.Scale, stat_TextLabel.Position.X.Offset, 1, -20)
- stat_SumLabel.Parent = frame
- end
- end
- end
- end
- end
- -- This variable will keep track of how many players are in each team's frame
- -- so we now how far down to put the next player in the score list
- local numberOfPlayersInTeamSoFar = {}
- local players = PlayersService:GetPlayers()
- for i = 1, #players do
- if players[i] then
- local xOffset = 0
- local yOffset = 0
- -- Get the leaderstats object
- local leaderstats = WaitForChild(players[i], "leaderstats")
- local leaderstatsList = leaderstats:GetChildren()
- -- Create the player name
- local playerName_TextLabel = PlayerTextLabel:Clone()
- playerName_TextLabel.Name = players[i].Name
- playerName_TextLabel.Text = players[i].Name
- -- If we have frames for each team, then encapsulate the score inside their team's frame
- if TeamsExist and TeamColorToTeamFrame[players[i].TeamColor.Name] ~= nil then
- local teamFrame = TeamColorToTeamFrame[players[i].TeamColor.Name]
- -- Create or increment the player count
- if not numberOfPlayersInTeamSoFar[players[i].TeamColor.Name] then
- numberOfPlayersInTeamSoFar[players[i].TeamColor.Name] = 1
- else
- numberOfPlayersInTeamSoFar[players[i].TeamColor.Name] = numberOfPlayersInTeamSoFar[players[i].TeamColor.Name] + 1
- end
- playerName_TextLabel.Parent = teamFrame
- yOffset = PLAYER_LIST_START_Y_OFFSET +
- (numberOfPlayersInTeamSoFar[players[i].TeamColor.Name] - 1) * PIXELS_Y_BETWEEN_PLAYER_ROWS
- playerName_TextLabel.Position = UDim2.new(0, PLAYERS_X_PADDING_PIXELS, 0, yOffset)
- elseif #TeamsService:GetTeams() == 0 then -- Otherwise we will fallback to putting the score inside the root of leaderboard
- if not LeaderboardFrame:FindFirstChild('TeamlessFrame') then CreateNeutralTeamFrame() end
- local teamlessFrame = LeaderboardFrame:FindFirstChild('TeamlessFrame')
- if not numberOfPlayersInTeamSoFar['Neutral'] then
- numberOfPlayersInTeamSoFar['Neutral'] = 1
- else
- numberOfPlayersInTeamSoFar['Neutral'] = numberOfPlayersInTeamSoFar['Neutral'] + 1
- end
- playerName_TextLabel.Parent = teamlessFrame
- yOffset = PLAYER_LIST_START_Y_OFFSET +
- (numberOfPlayersInTeamSoFar['Neutral'] - 1) * PIXELS_Y_BETWEEN_PLAYER_ROWS
- playerName_TextLabel.Position = UDim2.new(0, PLAYERS_X_PADDING_PIXELS, 0, yOffset)
- end
- -- For this player we will incrementally place their leaderstats to the right of their name
- local counter = 0
- for _, stat in pairs(leaderstatsList) do
- if stat:IsA("IntValue") or stat:IsA("NumberValue") or stat:IsA("StringValue") then
- local stat_TextLabel = playerName_TextLabel:Clone()
- stat_TextLabel.Text = stat.Value
- stat_TextLabel.Position = UDim2.new(1, -PIXELS_X_BETWEEN_STAT_COLUMNS * counter - PLAYERS_X_PADDING_PIXELS, 0, yOffset)
- stat_TextLabel.TextXAlignment = Enum.TextXAlignment.Right
- stat_TextLabel.Parent = playerName_TextLabel.Parent
- counter = counter + 1
- -- If this player isn't on a team then we can add up their points in the neutral team window
- if not TeamsExist or TeamColorToTeamFrame[players[i].TeamColor.Name] == nil then
- local teamlessFrame = LeaderboardFrame:FindFirstChild('TeamlessFrame')
- if teamlessFrame and teamlessFrame:FindFirstChild("Team" .. stat.Name) then
- local statLabel = teamlessFrame:FindFirstChild("Team" .. stat.Name)
- -- Make sure that statlabel's value can be turned into a number
- if tonumber(statLabel.Text) then statLabel.Text = tonumber(statLabel.Text) + stat.Value end
- else
- print("No teamlessframe")
- end
- end
- end
- end
- end
- end
- -- Change all the text and color within the frame to contrast with the background
- for _, frame in pairs(TeamColorToTeamFrame) do
- local textColor = DARK_FONT_COLOR
- if IsDark(frame.BackgroundColor3) then
- textColor = LIGHT_FONT_COLOR
- end
- for _, item in pairs(frame:GetChildren()) do
- if item.Name == 'Team' or item.Name == 'TeamScore' then
- --skip
- elseif item:IsA('TextLabel') then
- item.TextColor3 = textColor
- elseif item:IsA('Frame') then
- item.BorderColor3 = textColor
- end
- end
- end
- end
- --[[MyMouse.KeyDown:connect(function(key)
- if string.lower(key) == 'q' then
- if LeaderboardFrame then
- if TOGGLES then
- LeaderboardFrame.Visible = not LeaderboardFrame.Visible
- else
- LeaderboardFrame.Visible = true
- end
- end
- end
- end)]]
- --[[MyMouse.KeyUp:connect(function(key)
- if string.lower(key) == 'q' then
- if LeaderboardFrame then
- if not TOGGLES then
- LeaderboardFrame.Visible = false
- end
- end
- end
- end)]]
- LeaderboardButton.MouseButton1Click:connect(function()
- LeaderboardFrame.Visible = not LeaderboardFrame.Visible
- end)
- CreateTeamFrames()
- MirrorTemplateFrame()
- PopulateLeaderboard()
- Spawn(function() while true do
- PopulateLeaderboard()
- wait(3)
- end
- end)
Advertisement
Add Comment
Please, Sign In to add comment