LuckyEcho

Untitled

Jul 24th, 2024 (edited)
24
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.71 KB | None | 0 0
  1. -- This script relies on a modular framework I wrote. Since I use modules it's harder to get a 200 line+ script, so I wrote up this one in around 40 minutes without any tutorials. My post on my framework is below.
  2. -- https://devforum.roblox.com/t/code-framework-and-structure/3059321
  3.  
  4. -- [ SERVICES ]
  5. local Players = game:GetService("Players")
  6. local Teams = game:GetService("Teams")
  7. local ContextActionService = game:GetService("ContextActionService")
  8. local StarterGui = game:GetService("StarterGui")
  9. local TweenService = game:GetService("TweenService")
  10. local UserInputService = game:GetService("UserInputService")
  11.  
  12. -- [ FOLDER ]
  13. local Assets = script:WaitForChild("Assets")
  14.  
  15. -- [ MODULES ]
  16. local Settings = require(script:WaitForChild("Settings"))
  17.  
  18. -- [ VARIABLES ]
  19. local LocalPlayer : Player = game.Players.LocalPlayer
  20. local PlayerGui = LocalPlayer:WaitForChild("PlayerGui")
  21.  
  22. local LeaderboardHandler = {}
  23. local TeamConnections = {}
  24. local LatestTeamIndexList = {}
  25. local LeaderboardOpen = true
  26.  
  27. local PlayerFrame = Assets:WaitForChild("PlayerFrame")
  28. local TeamFrame = Assets:WaitForChild("Team")
  29. local LeaderboardUI
  30. local MainFrame
  31. local OpenCloseButton
  32.  
  33.  
  34.  
  35. -- [ FUNCTIONS ]
  36. local function ClearList()
  37.     for _, frame in pairs(MainFrame:GetChildren()) do
  38.         if frame:IsA("Frame") then
  39.             frame:Destroy()
  40.         end
  41.     end
  42. end
  43.  
  44. local function PlayerToFrame(player : Player, index : number) : Frame
  45.     local playerFrame = PlayerFrame:Clone()
  46.    
  47.     -- Setup the player's name and image.
  48.     playerFrame.Image.Image = Players:GetUserThumbnailAsync(player.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size420x420)
  49.     playerFrame.DisplayName.Text = player.DisplayName
  50.     playerFrame.Username.Text = "@"..player.Name
  51.     playerFrame.LayoutOrder = index
  52.     playerFrame.Name = player.UserId
  53.    
  54.     -- Check if the user is in settings.
  55.     if Settings.CustomIcons[player.UserId] then
  56.         playerFrame.Icon.Image = "http://www.roblox.com/asset/?id="..tostring(Settings.CustomIcons[player.UserId].ID)
  57.         playerFrame.Icon.ImageColor3 = Settings.CustomIcons[player.UserId].ImageColor
  58.         playerFrame.Icon.Visible = true
  59.     end
  60.    
  61.     -- Return
  62.     return playerFrame
  63. end
  64.  
  65. local function TeamToFrame(team : Team, index : number) : Frame
  66.     local teamFrame = TeamFrame:Clone()
  67.    
  68.     -- Setup the team text.
  69.     teamFrame.TeamName.Text = team.Name
  70.     teamFrame.TeamName.TextColor = team.TeamColor
  71.     teamFrame.LayoutOrder = index
  72.    
  73.     -- Return
  74.     return teamFrame
  75. end
  76.  
  77. local function FindPlayerFrameInList(player : Player)
  78.     for index, frame : Frame in pairs(MainFrame:GetChildren()) do
  79.         if frame.Name == tostring(player.UserId) then
  80.             return frame
  81.         end
  82.     end
  83.     return nil
  84. end
  85.  
  86. local function GetPlayerLocationInTeams(player : Player, teamIndexTable : {[string]: number}) : number
  87.     -- Find the team.
  88.     local team = player.Team
  89.  
  90.     -- Search through the index table to find their index.
  91.     for key, index in pairs(teamIndexTable) do
  92.         if key == team then
  93.             return index
  94.         end
  95.     end
  96.  
  97.     -- Return nil if they weren't in any of the found tables.
  98.     return -1
  99. end
  100.  
  101. local function UserChangedTeam(player : Player)
  102.     -- Find the users frame in the list.
  103.     local frame = FindPlayerFrameInList(player)
  104.  
  105.     -- Check if it exists.
  106.     if frame then
  107.         -- Grab the users index position in the teams.
  108.         local indexPosition = GetPlayerLocationInTeams(player, LatestTeamIndexList)
  109.  
  110.         -- Check if the index position exists and update the frame layout order.
  111.         if indexPosition > -1 then
  112.             frame.LayoutOrder = indexPosition
  113.         end
  114.     end
  115. end
  116.  
  117. local function RefreshUI()
  118.     -- Clear the previous list.
  119.     ClearList()
  120.    
  121.     -- Get the players.
  122.     local PlayerTable = Players:GetPlayers()
  123.     local TeamTable = Teams:GetTeams()
  124.     local TeamIndexTable = {}
  125.    
  126.     -- Create frames for the teams.
  127.     for index, team : Team in ipairs(TeamTable) do
  128.         -- Grab the correct index. Multiply by 1000 so that more than 1 user can be in that list.
  129.         local correctIndex = index * 1000
  130.        
  131.         -- Add the team to the index table so we can sort the UI later.
  132.         TeamIndexTable[team] = correctIndex
  133.        
  134.         -- Create the team frame.
  135.         local teamFrame = TeamToFrame(team, correctIndex)        
  136.         teamFrame.Visible = true
  137.         teamFrame.Parent = MainFrame
  138.     end
  139.    
  140.     -- Update the team index table.
  141.     LatestTeamIndexList = TeamIndexTable
  142.    
  143.     -- Create frames for each of the players.
  144.     for index, player : Player in ipairs(PlayerTable) do
  145.         -- Grab the users index in the team table.
  146.         local usersIndex = GetPlayerLocationInTeams(player, TeamIndexTable)
  147.        
  148.         -- Check if the index exists.
  149.         if usersIndex > -1 then
  150.             -- Create the frame and parent it.
  151.             local playerFrame = PlayerToFrame(player, usersIndex + index)
  152.             playerFrame.Parent = MainFrame
  153.             playerFrame.Visible = true
  154.         end
  155.     end
  156. end
  157.  
  158. local function OpenCloseLeaderboard(actionName, inputState : Enum.UserInputState)
  159.     -- Check if the user is beginning the press.
  160.     if inputState ~= Enum.UserInputState.Begin then return end
  161.  
  162.     -- Check if the leaderboard is already open.
  163.     LeaderboardOpen = not LeaderboardOpen
  164.  
  165.     -- We hold the tween's properties here.
  166.     local propertyTable = {}
  167.    
  168.     -- Check if the user is mobile to update the button.
  169.     if OpenCloseButton.Visible == true then
  170.         OpenCloseButton.Text = if LeaderboardOpen then "CLOSE" else "OPEN"
  171.     end
  172.    
  173.     -- Check if the leaderboard is open.
  174.     if LeaderboardOpen then
  175.         -- The leaderboard needs to be opened.
  176.         propertyTable.Position = Settings.TweeningStyle.OpenPosition
  177.     else
  178.         -- The leaderboard needs to be closed.
  179.         propertyTable.Position = Settings.TweeningStyle.ClosedPosition
  180.     end
  181.  
  182.     -- Create the tween and play it.
  183.     local lbInfo = Settings.TweeningStyle.LeaderboardTweenInfo
  184.     local tween = TweenService:Create(MainFrame.Parent, lbInfo, propertyTable)
  185.     tween:Play()
  186. end
  187.  
  188. local function SetupUI()
  189.     -- Place the leaderboard UI on the playergui.
  190.     LeaderboardUI = Assets:WaitForChild("Leaderboard"):Clone()
  191.     LeaderboardUI.Parent = PlayerGui
  192.  
  193.    
  194.     -- Set up the variables for the frames.
  195.     MainFrame = LeaderboardUI:WaitForChild("Frame"):WaitForChild("MainFrame")
  196.     OpenCloseButton = LeaderboardUI:WaitForChild("Frame"):WaitForChild("OpenClose")
  197.    
  198.     -- Check if the user is mobile.
  199.     if UserInputService.TouchEnabled then
  200.         -- Enable the close button and listen for touches.
  201.         OpenCloseButton.Visible = true
  202.         OpenCloseButton.Text = if LeaderboardOpen then "CLOSE" else "OPEN"
  203.         OpenCloseButton.MouseButton1Up:Connect(function()
  204.             OpenCloseLeaderboard(nil, Enum.UserInputState.Begin)
  205.         end)
  206.     else
  207.         -- Disable the close button.
  208.         OpenCloseButton.Visible = false
  209.     end
  210.    
  211.     -- Loop through all the current players and connect to them.
  212.     for index, player : Player in pairs(Players:GetPlayers()) do
  213.         -- Check if the user is already connected.
  214.         if not TeamConnections[player.UserId] then
  215.             -- Check if the user changed teams.
  216.             TeamConnections[player.UserId] = player:GetPropertyChangedSignal("Team"):Connect(function()
  217.                 UserChangedTeam(player)
  218.             end)
  219.         end    
  220.     end
  221. end
  222.  
  223. local function PlayerAdded(player : Player)
  224.     -- Connect to the player changing teams.
  225.     TeamConnections[player.UserId] = player:GetPropertyChangedSignal("Team"):Connect(function()
  226.         UserChangedTeam(player)
  227.     end)
  228. end
  229.  
  230. local function PlayerRemoving(player : Player)
  231.     -- Disconnect listening for the team change on leave.
  232.     if TeamConnections[player.UserId] then
  233.         TeamConnections[player.UserId]:Disconnect()
  234.         print("Disconnected from player "..player.DisplayName)
  235.     end
  236. end
  237.  
  238.  
  239.  
  240. -- [ INITIALIZATION ]
  241. function LeaderboardHandler.__init()
  242.     -- Disable the old ui.
  243.     StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.PlayerList, false)
  244.    
  245.     -- Bind the opening and closing keys.
  246.     ContextActionService:BindAction("Leaderboard", OpenCloseLeaderboard, false, Enum.KeyCode.Tab)
  247.     ContextActionService:SetPosition("Leaderboard", UDim2.new(0.3, 0,-1.2, 0))
  248.     ContextActionService:SetTitle("Leaderboard", "Leaderboard")
  249.    
  250.     -- Setup the UI and refresh it.
  251.     SetupUI()
  252.     RefreshUI()
  253. end
  254.  
  255. -- [ CONNECTIONS ]
  256. Players.PlayerAdded:Connect(PlayerAdded)
  257. Players.PlayerRemoving:Connect(PlayerRemoving)
  258.  
  259.  
  260. -- [ RETURNING ]
  261. return LeaderboardHandler
  262.  
Advertisement
Add Comment
Please, Sign In to add comment