--Credits: https://pastebin.com/raw/w7vdZdMn if game.CoreGui:FindFirstChild("ScreenGui") then game.CoreGui.ScreenGui:Destroy() end game:GetService("StarterGui"):SetCoreGuiEnabled("Chat", false) game:GetService("StarterGui"):SetCoreGuiEnabled("PlayerList", false) -- Ctrl+F "API DOCS" to get the docs local uieiie = Instance.new("ScreenGui",game.CoreGui) --settings. Don't make these local. ALLOW_BC_ICONS = true -- Players' BC icons will be shown next to their names PRIMARY_LEADERSTATS_ENABLED = true -- Leaderstats will appear in large text under the player's name SHOW_PRIMARY_LEADERSTAT_NAMES = true -- Primary leaderstats will have their names shown next to them TEAMS_ENABLED = true -- Teams will appear. CUSTOM_CHAT_COLORS = { -- add your name = Color3 to give yourself a custom chat color. -- if you don't choose a chat color, but you do add a custom icon, your color will appear as golden -- if you don't want golden but you do want an icon, you can set your chat color to Color3.new(1,1,1) evolving888 = Color3.new(000/255, 167/255, 213/255) } HIDDEN_PLAYERS = { -- add playerName=true to prevent them from appearing on the leaderboard example_player_name = true } CUSTOM_LABEL_BACKGROUND_COLORS = { -- add playerName=color3 to give certain players a unique backgroundColor Player1 = Color3.new(1, 0.5, 1) } CUSTOM_LABEL_NAME_COLORS = { -- add playerName=color3 to give certain players a uniquely-colored name Player1 = Color3.new(0, 0.5, 1) } ADMINS = { -- add your name = 1 to get a star icon. Add your name = image to get a custom icon. evolving888 = "http://www.roblox.com/asset?id=148012526", creepy333 = "http://www.roblox.com/asset?id=148012526", enter777 = "http://www.roblox.com/asset?id=148012526", } ADMIN_ICON_WIDTHS = { arceusinator = 30 } ALIASES = { creepy333 = "Creepy", Minish1111 = "Minish" } -- API DOCS -- _G.PlayerListAPI:SetAllowBCIcons(true or false) -- :AddAdmin(String name, Optional Content customIcon, Optional Int customIconWidth) -- :RemoveAdmin(String name) -- :SetAlias(String name, String alias) -- :SetPlayerIsHidden(String name) -- :SetLabelColors(String playerName, Color3 backgroundColor, Color3 textColor) -- _G.ChatAPI:SendChat(String playername, String message, Color3 customcolor) for name,a in pairs(ADMINS) do ADMINS[name:lower()] = a end for name,a in pairs(CUSTOM_CHAT_COLORS) do CUSTOM_CHAT_COLORS[name:lower()] = a end for name,a in pairs(ALIASES) do ALIASES[name:lower()] = a end for name,a in pairs(HIDDEN_PLAYERS) do HIDDEN_PLAYERS[name:lower()] = a end for name,a in pairs(CUSTOM_LABEL_BACKGROUND_COLORS) do CUSTOM_LABEL_BACKGROUND_COLORS[name:lower()] = a end for name,a in pairs(CUSTOM_LABEL_NAME_COLORS) do CUSTOM_LABEL_NAME_COLORS[name:lower()] = a end function GetAliasOf(name) return ALIASES[name:lower()] or name end local export = {} export.SetAllowBCIcons = function(self, b) ALLOW_BC_ICONS = b end export.AddAdmin = function(self, name, customicon, customiconwidth) ADMINS[name:lower()] = customicon or 1 ADMIN_ICON_WIDTHS[name:lower()] = customiconwidth or 16 end export.RemoveAdmin = function(self, name) ADMINS[name:lower()] = 0 end export.GetChatData = function(self) return ADMINS, CUSTOM_CHAT_COLORS, ALIASES end export.SetAlias = function(self, name, alias) if alias == "" or alias == nil then ALIASES[name:lower()] = name else ALIASES[name:lower()] = alias end end export.GetAlias = function(self, name) return GetAliasOf(name) end export.SetLabelColors = function(self, playerName, backgroundColor, textColor) CUSTOM_LABEL_BACKGROUND_COLORS[playerName:lower()] = backgroundColor CUSTOM_LABEL_NAME_COLORS[playerName:lower()] = textColor end export.SetPlayerIsHidden = function(self, name, bool) local current = not not HIDDEN_PLAYERS[name:lower()] local new = not not bool local changing = current ~= new HIDDEN_PLAYERS[name:lower()] = new if changing then if new then local existingPlayer = nil for index, player in next, game.Players:GetPlayers() do if player.Name:lower() == name:lower() then existingPlayer = player break end end if existingPlayer ~= nil then InsertPlayerFrame(existingPlayer) end elseif not new then local existingPlayer = nil for index, player in next, game.Players:GetPlayers() do if player.Name:lower() == name:lower() then existingPlayer = player break end end if existingPlayer ~= nil then RemovePlayerFrame(existingPlayer) end end end end _G.PlayerListAPI = export local Images = { bottomDark = '94691904', bottomLight = '94691940', midDark = '94691980', midLight = '94692025', LargeDark = '96098866', LargeLight = '96098920', LargeHeader = '96097470', NormalHeader = '94692054', LargeBottom = '96397271', NormalBottom = '94754966', DarkBluePopupMid = '97114905', LightBluePopupMid = '97114905', DarkPopupMid = '97112126', LightPopupMid = '97109338', DarkBluePopupTop = '97114838', DarkBluePopupBottom = '97114758', DarkPopupBottom = '100869219', LightPopupBottom = '97109175', } local BASE_TWEEN = .25 local MOUSE_HOLD_TIME = .15 local MOUSE_DRAG_DISTANCE = 15 --[[ Generic object Create function, which I am using to create Gui's Thanks to Stravant! --]] local Obj = {} function Obj.Create(guiType) return function(data) local obj = Instance.new(guiType) for k, v in pairs(data) do if type(k) == 'number' then v.Parent = obj else obj[k] = v end end return obj end end --[[ makes a full sized background for a guiobject @Args: imgName asset name of image to fill background @Return: background gui object --]] function MakeBackgroundGuiObj(imgName) return Obj.Create'ImageLabel' { Name = 'Background', BackgroundTransparency = 1, Image = imgName, Position = UDim2.new(0, 0, 0, 0), Size = UDim2.new(1,0,1,0), } end --[[ turns 255 integer color value to a color3 --]] function Color3I(r,g,b) return Color3.new(r/255,g/255,b/255) end --[[ Gets correct icon for builder's club status to display by name @Args: membershipType Enum of membership status @Return: string of image asset --]] function getMembershipTypeIcon(membershipType,playerName) if ADMINS[string.lower(playerName)]~=nil then if ADMINS[string.lower(playerName)] == 1 then return "http://www.roblox.com/asset/?id=146188778" else local dat = ADMINS[string.lower(playerName)] if type(dat) == "table" then return dat[1] elseif type(dat) == "string" then return ADMINS[string.lower(playerName)] else return "http://www.roblox.com/asset/?id=146188778" end end elseif membershipType == Enum.MembershipType.None then return "" elseif membershipType == Enum.MembershipType.BuildersClub then return "rbxasset://textures/ui/TinyBcIcon.png" elseif membershipType == Enum.MembershipType.TurboBuildersClub then return "rbxasset://textures/ui/TinyTbcIcon.png" elseif membershipType == Enum.MembershipType.OutrageousBuildersClub then return "rbxasset://textures/ui/TinyObcIcon.png" else error("Unknown membershipType" .. membershipType) end end local function getFriendStatusIcon(friendStatus) if friendStatus == Enum.FriendStatus.Unknown or friendStatus == Enum.FriendStatus.NotFriend then return "" elseif friendStatus == Enum.FriendStatus.Friend then return "http://www.roblox.com/asset/?id=99749771" elseif friendStatus == Enum.FriendStatus.FriendRequestSent then return "http://www.roblox.com/asset/?id=99776888" elseif friendStatus == Enum.FriendStatus.FriendRequestReceived then return "http://www.roblox.com/asset/?id=99776838" else error("Unknown FriendStatus: " .. friendStatus) end end --[[ Utility function to create buttons for the popup menus @Args: nparent what to parent this button to ntext text to put on this button index number index of this entry in menu last is this the last element of the popup menu @Return: a popup menu button --]] function MakePopupButton(nparent,ntext,index,last) local tobj = Obj.Create"ImageButton" { Name = 'ReportButton', BackgroundTransparency = 1, Position = UDim2.new(0,0,1*index,0), Size = UDim2.new(1, 0, 1, 0), ZIndex=7, Obj.Create'TextLabel' { Name = 'ButtonText', BackgroundTransparency = 1, Position = UDim2.new(.07, 0, .07, 0), Size = UDim2.new(.86,0,.86,0), Parent = HeaderFrame, Font = 'ArialBold', Text = ntext, FontSize = 'Size14', TextScaled = true, TextColor3 = Color3.new(1,1,1), TextStrokeTransparency = 1, ZIndex=7, }, Parent = nparent, } if index==0 then tobj.Image = 'http://www.roblox.com/asset/?id=97108784' elseif last then if index%2==1 then tobj.Image = 'http://www.roblox.com/asset/?id='.. Images['LightPopupBottom'] else tobj.Image = 'http://www.roblox.com/asset/?id='.. Images['DarkPopupBottom'] end else if index%2==1 then tobj.Image = 'http://www.roblox.com/asset/?id=97112126' else tobj.Image = 'http://www.roblox.com/asset/?id=97109338' end end return tobj end --[[ obligatory wait for child function @Args: parent Parent object to look for child in child name of child object to look for @Return: object waited for --]] function WaitForChild(parent,child) while not parent:FindFirstChild(child) do wait() debugprint(" child "..parent.Name.." waiting for "..child) end return parent[child] end --------------------------- -- Workspace Objects --------------------------- -- might want to move all this to an init function, wait for localplayer elsewhere local Players = game:GetService('Players') -- make sure this doesn't run on the server(it will if you dont do this) while not Players.LocalPlayer do Players.Changed:wait() end local LocalPlayer = Players.LocalPlayer local Mouse = LocalPlayer:GetMouse() local ScreenGui = Obj.Create"Frame" { Name = 'PlayerListScreen', Size = UDim2.new(1, 0, 1, 0), BackgroundTransparency = 1, Parent = uieiie } local MainFrame = Obj.Create"Frame" { Name = 'LeaderBoardFrame', Position = UDim2.new(1, -150, 0.005, 0), Size = UDim2.new(0, 150, 0, 800), BackgroundTransparency = 1, Parent = ScreenGui, } --frame used for expanding leaderstats when frame is 'focused' local FocusFrame = Obj.Create"Frame" { Name = 'FocusFrame', Position = UDim2.new(0, 0, 0, 0), Size = UDim2.new(1, 0, 0, 100), BackgroundTransparency = 1, Active = true, Parent = MainFrame, } local TemplateFrameYSize = 0.670000017 -- HEADER local HeaderFrame = Obj.Create"Frame" { Name = 'Header', BackgroundTransparency = 1, Position = UDim2.new(0,0,0,0), Size = UDim2.new(1, 0, .07, 0), Parent = MainFrame, MakeBackgroundGuiObj('http://www.roblox.com/asset/?id=94692054'), } local HeaderFrameHeight = HeaderFrame.Size.Y.Scale local MaximizeButton = Obj.Create"ImageButton" { Name = 'MaximizeButton', Active = true, BackgroundTransparency = 1, Position = UDim2.new(0, 0, 0, 0), Size = UDim2.new(1,0,1,0), Parent = HeaderFrame, } local HeaderName = Obj.Create"TextLabel" { Name = 'PlayerName', BackgroundTransparency = 1, Position = UDim2.new(0, 0, .01, 0), Size = UDim2.new(.98,0,.38,0), Parent = HeaderFrame, Font = 'ArialBold', Text = GetAliasOf(LocalPlayer.Name), FontSize='Size24', --TextScaled = true, TextColor3 = Color3.new(1,1,1), TextStrokeColor3 = Color3.new(0,0,0), TextStrokeTransparency = 0, TextXAlignment = 'Right', TextYAlignment = 'Center', } local HeaderScore = Obj.Create"TextLabel" { Name = 'PlayerScore', BackgroundTransparency = 1, Position = UDim2.new(0, 0, .4, 0), Size = UDim2.new(.98,0,0,30), Parent = HeaderFrame, Font = 'ArialBold', Text = '', FontSize='Size24', TextYAlignment = 'Top', --TextScaled = true, TextColor3 = Color3.new(1,1,1), TextStrokeTransparency = 1, TextXAlignment = 'Right', TextYAlignment = 'Top', } local HeaderScoreName = Obj.Create"TextLabel" { Name = 'ScoreNameLabel', BackgroundTransparency = 1, Position = UDim2.new(0, 5, 0, 0), Size = UDim2.new(1, 0, 1, 0), Font = 'ArialBold', FontSize = 'Size14', Text = '', TextColor3 = Color3.new(1, 1, 1), TextStrokeTransparency = 0, TextXAlignment = 'Left', Parent = HeaderScore } coroutine.resume(coroutine.create(function() while wait(1) do HeaderFrame.PlayerName.Text = GetAliasOf(LocalPlayer.Name) end end)) -- BOTTOM --used for shifting bottom frame for mouse over effects local BottomShiftFrame = Obj.Create"Frame" { Name= 'BottomShiftFrame', BackgroundTransparency = 1, Position = UDim2.new(0,0,HeaderFrameHeight,0), Size = UDim2.new(1,0,1,0), Parent=MainFrame, } local BottomFrame = Obj.Create"Frame" { Name = 'Bottom', BackgroundTransparency = 1, Position = UDim2.new(0,0,.07,0), Size = UDim2.new(1, 0, .03, 0), Parent = BottomShiftFrame, MakeBackgroundGuiObj('http://www.roblox.com/asset/?id=94754966'), } local ExtendButton = Obj.Create"ImageButton" { Name = 'bigbutton', Active = true, BackgroundTransparency = 1, Position = UDim2.new(0, 0, 0, 0), Size = UDim2.new(1,0,1.5,0), ZIndex = 3, Parent = BottomFrame, } local ExtendTab = Obj.Create"ImageButton" { Name = 'extendTab', Active = true, BackgroundTransparency = 1, Image = 'http://www.roblox.com/asset/?id=94692731', Position = UDim2.new(.608, 0, .3, 0), Size = UDim2.new(.3,0,.7,0), Parent = BottomFrame, } local TopClipFrame = Obj.Create"Frame" { Name = 'ListFrame', BackgroundTransparency = 1, Position = UDim2.new(-1,0,.07,0), Size = UDim2.new(2, 0, 1, 0), Parent = MainFrame, ClipsDescendants = true, } local BottomClipFrame = Obj.Create"Frame" { Name = 'BottomFrame', BackgroundTransparency = 1, Position = UDim2.new(0,0, - .8,0), Size = UDim2.new(1, 0, 1, 0), Parent = TopClipFrame, ClipsDescendants = true, } local ScrollBarFrame = Obj.Create"Frame" { Name = 'ScrollBarFrame', BackgroundTransparency = 1, Position = UDim2.new(.987,0,.8,0), Size = UDim2.new(.01, 0, .2, 0), Parent = BottomClipFrame, } local ScrollBar = Obj.Create"Frame" { Name = 'ScrollBar', BackgroundTransparency = 0, BackgroundColor3 = Color3.new(.2,.2,.2), Position = UDim2.new(0,0,0,0), Size = UDim2.new(1, 0, .5, 0), ZIndex = 5, Parent = ScrollBarFrame, } local ListFrame = Obj.Create"Frame" { Name = 'SubFrame', BackgroundTransparency = 1, Position = UDim2.new(0,0,.8,0), Size = UDim2.new(1, 0, 1, 0), Parent = BottomClipFrame, } local PopUpClipFrame = Obj.Create"Frame" { Name = 'PopUpFrame', BackgroundTransparency = 1, SizeConstraint='RelativeXX', Position = MainFrame.Position + UDim2.new( 0,-150,0,0), Size = UDim2.new(0,150,0,800), Parent = MainFrame, ClipsDescendants = true, ZIndex=7, } local PopUpPanel = nil local PopUpPanelTemplate = Obj.Create"Frame" { Name = 'Panel', BackgroundTransparency = 1, Position = UDim2.new(1,0,0,0), Size = UDim2.new(1,0,.032,0), Parent = PopUpClipFrame, } local StatTitles = Obj.Create"Frame" { Name = 'StatTitles', BackgroundTransparency = 1, Position = UDim2.new(0,0,1,-10), Size = UDim2.new(1, 0, 0, 0), Parent = HeaderFrame, } local IsMinimized = Instance.new('BoolValue') local IsMaximized = Instance.new('BoolValue') local IsTabified = Instance.new('BoolValue') local AreNamesExpanded = Instance.new('BoolValue') local MiddleTemplate = Obj.Create"Frame" { Name = 'MidTemplate', BackgroundTransparency = 1, Position = UDim2.new(100,0,.07,0), Size = UDim2.new(.5, 0, .025, 0),--UDim2.new(1, 0, .03, 0), Obj.Create'ImageLabel' { Name = 'BCLabel', Active = true, BackgroundTransparency = 1, Position = UDim2.new(.005, 3, .20, -2), Size = UDim2.new(0,16,0,16), SizeConstraint = 'RelativeYY', Image = "", ZIndex = 3, }, Obj.Create'ImageLabel' { Name = 'FriendLabel', Active = true, BackgroundTransparency = 1, Position = UDim2.new(.005, 5, .15, 0), Size = UDim2.new(0,16,0,16), SizeConstraint = 'RelativeYY', Image = "", ZIndex = 3, }, Obj.Create"ImageButton" { Name = 'ClickListener', Active = true, BackgroundTransparency = 1, Position = UDim2.new(.005, 1, 0, 0), Size = UDim2.new(.96,0,1,0), ZIndex = 3, }, Obj.Create"Frame" { Name = 'TitleFrame', BackgroundTransparency = 1, Position = UDim2.new(.01, 0, 0, 0), Size = UDim2.new(0,140,1,0), ClipsDescendants=true, Obj.Create"TextLabel" { Name = 'Title', BackgroundTransparency = 1, Position = UDim2.new(0, 5, 0, 0), Size = UDim2.new(100,0,1,0), Font = 'Arial', FontSize='Size14', TextColor3 = Color3.new(1,1,1), TextXAlignment = 'Left', TextYAlignment = 'Center', ZIndex = 3, }, }, Obj.Create"TextLabel" { Name = 'PlayerScore', BackgroundTransparency = 1, Position = UDim2.new(0, 0, 0, 0), Size = UDim2.new(1,0,1,0), Font = 'ArialBold', Text = '', FontSize='Size14', TextColor3 = Color3.new(1,1,1), TextXAlignment = 'Right', TextYAlignment = 'Center', ZIndex = 3, }, --Obj.Create'IntValue'{Name = 'ID'}, --Obj.Create'ObjectValue'{Name = 'Player'}, --Obj.Create'IntValue'{Name = 'Score'}, ZIndex = 3, } local MiddleBGTemplate = Obj.Create"Frame" { Name = 'MidBGTemplate', BackgroundTransparency = 1, BorderSizePixel = 0, Position = UDim2.new(100,0,.07,0), Size = UDim2.new(.5, 0, .025, 0),--UDim2.new(1, 0, .03, 0), MakeBackgroundGuiObj('http://www.roblox.com/asset/?id=94692025'), } -- REPORT ABUSE OBJECTS local ReportAbuseShield = Obj.Create"TextButton" { Name = "ReportAbuseShield", Text = "", AutoButtonColor = false, Active = true, Visible = true, Size = UDim2.new(1,0,1,0), BackgroundColor3 = Color3I(51,51,51), BorderColor3 = Color3I(27,42,53), BackgroundTransparency = 1, } local ReportAbuseFrame = Obj.Create "Frame" { Name = "ReportAbuseFrame", Position = UDim2.new(0.5, -250, 0.5, -100), Size = UDim2.new(0, 500, 0, 200), ZIndex = 9, Parent = ReportAbuseShield, Style = "RobloxRound" } local ReportAbuseClose = Obj.Create "TextButton" { BackgroundColor3 = Color3.new(150/255, 0, 0), BorderColor3 = Color3.new(200/255, 200/255, 200/255), Name = "Close", Position = UDim2.new(1, -20, 0, 0), Size = UDim2.new(0, 20, 0, 20), ZIndex = 10, Font = "SourceSansBold", FontSize = "Size12", Text = "X", TextColor3 = Color3.new(200/255, 200/255, 200/255), TextStrokeTransparency = 0, Parent = ReportAbuseFrame } local ReportAbuseHeader = Obj.Create "TextLabel" { BackgroundTransparency = 1, Name = "Sorry", Position = UDim2.new(0.5, 0, 0, 20), ZIndex = 10, Font = "ArialBold", FontSize = "Size36", Text = "Sorry! :(", TextColor3 = Color3.new(200/255, 200/255, 200/255), TextStrokeTransparency = 0, Parent = ReportAbuseFrame } local ReportAbuseInfo = Obj.Create "TextLabel" { BackgroundColor3 = Color3.new(), BackgroundTransparency = .5, BorderColor3 = Color3.new(200/255, 200/255, 200/255), Name = "ReportAbuseInfo", Position = UDim2.new(0, 0, 0, 50), Size = UDim2.new(1, 0, 1, -50), Font = "ArialBold", FontSize = "Size14", Text = "This game is using a specialized player list that uses an API to unlock certain features. Because this is a modified player list, certain high-level functions are disabled such as in-game Friend Requests and the Report Abuse function.", TextColor3 = Color3.new(200/255, 200/255, 200/255), TextStrokeTransparency = 0, TextYAlignment = "Top", ZIndex = 10, TextWrapped = true, Parent = ReportAbuseFrame, Obj.Create"TextLabel" { BackgroundTransparency = 1, Name = "FRs", Position = UDim2.new(0, 20, 0, 50), Size = UDim2.new(1, -40, 1, -50), ZIndex = 10, Font = "Arial", FontSize = "Size12", Text = "To add a friend, you will need to go to the roblox site and find them using the player search page. Once you've found them, click the \"Add Friend\" button under their character.", TextColor3 = Color3.new(200/255, 200/255, 200/255), TextStrokeTransparency = 0, TextWrapped = true, TextYAlignment = "Top" }, Obj.Create"TextLabel" { BackgroundTransparency = 1, Name = "Report", Position = UDim2.new(0, 20, 0, 90), Size = UDim2.new(1, -40, 1, -50), ZIndex = 10, Font = "Arial", FontSize = "Size12", Text = "To report abuse, you need to open your game menu by pressing the 'Esc' button on your keyboard, then click Report Abuse and fill out the necessary information.", TextColor3 = Color3.new(200/255, 200/255, 200/255), TextStrokeTransparency = 0, TextWrapped = true, TextYAlignment = "Top" } } local BigButton=Instance.new('ImageButton') BigButton.Size=UDim2.new(1,0,1,0) BigButton.BackgroundTransparency=1 BigButton.ZIndex=8 BigButton.Visible=false --BigButton.Active=false BigButton.Parent=ScreenGui local debugFrame = Obj.Create"Frame" { Name = 'debugframe', Position = UDim2.new(0, 0, 0, 0), Size = UDim2.new(0, 150, 0, 800),--0.99000001 BackgroundTransparency = 1, } local debugplayers = Obj.Create"TextLabel" { BackgroundTransparency = .8, Position = UDim2.new(0, 0, .01, 0), Size = UDim2.new(1,0,.5,0), Parent = debugFrame, Font = 'ArialBold', Text = '--', FontSize='Size14', TextWrapped=true, TextColor3 = Color3.new(1,1,1), TextStrokeColor3 = Color3.new(0,0,0), TextStrokeTransparency = 0, TextXAlignment = 'Right', TextYAlignment = 'Center', } local debugOutput = Obj.Create"TextLabel" { BackgroundTransparency = .8, Position = UDim2.new(0, 0, .5, 0), Size = UDim2.new(1,0,.5,0), Parent = debugFrame, Font = 'ArialBold', Text = '--', FontSize='Size14', TextWrapped=true, TextColor3 = Color3.new(1,1,1), TextStrokeColor3 = Color3.new(0,0,0), TextStrokeTransparency = 0, TextXAlignment = 'Right', TextYAlignment = 'Center', } --[[ simple function to toggle the display of debug output --]] local DebugPrintEnabled=true function debugprint(str) --print(str) if DebugPrintEnabled then debugOutput.Text=str end end ------------------------- -- Script objects ------------------------- local RbxGui = loadstring(game:HttpGet("https://raw.githubusercontent.com/Roblox/Core-Scripts/master/CoreScriptsRoot/Libraries/RbxGui.lua", true))() -- number of entries to show if you click minimize local DefaultEntriesOnScreen = 8 for _,i in pairs(Images) do Game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id="..i) end -- ordered array of 'score data', each entry has: -- Name(String) -- Priority(number) -- IsPrimary (bool, should it be shown in upper right) -- MaxLength (integer, of the length of the longest element for this column) local ScoreNames = {} -- prevents flipping in playerlist panels local AddId = 0 -- intermediate table form of all player entries in format of: -- Frame -- Player -- Score -- ID -- MyTeam (team ENRTY(not actual team) I am currently on) local PlayerFrames = {} -- intermediate ordered frame array, composed of Entrys of -- Frame -- MyTeam (my team object) -- MyPlayers ( an ordered array of all player frames in team ) -- AutoHide (bool saying whether it should be hidden) -- IsHidden (bool) -- ID (int to prevent flipping out of leaderboard, fun times) local TeamFrames = {} -- one special entry from teamFrames, for unaffiliated players, only shown if players non - empty local NeutralTeam = nil -- final 'to be displayed' list of frames local MiddleFrames = {} local MiddleFrameBackgrounds = {} local MiddleFrameHeight = .03 -- time of last click local LastClick = 0 local ButtonCooldown = .25 local OnIos = false pcall(function() OnIos = Game:GetService('UserInputService').TouchEnabled end) -- you get 200 of x screen space per stat added, start width 16% local BaseScreenXSize = 150 local SpacingPerStat = 10 --spacing between stats local MaximizedBounds = UDim2.new(.5,0,1,0) local MaximizedPosition = UDim2.new(.25,0,.1,0) local NormalBounds = UDim2.new(0,BaseScreenXSize, 0, 800) local NormalPosition = UDim2.new(1 , - BaseScreenXSize, 0.005, 0) local MinimizedBounds = UDim2.new(0, BaseScreenXSize, 0.99000001, 0) --free space to give last stat on the right local RightEdgeSpace = -.04 -- where the scroll par currently is positioned local ScrollPosition = 0.75999999 local IsDragging = false -- am I dragging the player list local DefaultBottomClipPos = BottomClipFrame.Position.Y.Scale local LastSelectedPlayerEntry = nil local SelectedPlayerEntry = nil local SelectedPlayer = nil -- locks(semaphores) for stopping race conditions local AddingFrameLock = false local ChangingOrderLock = false local AddingStatLock = false local BaseUpdateLock = false local WaitForClickLock = false local InPopupWaitForClick=false local PlayerChangedLock = false local NeutralTeamLock = false local ScrollWheelConnections = {} local DefaultListSize = 8 if not OnIos then DefaultListSize = 12 end local DidMinimizeDrag = false --local PlaceCreatorId=game.CreatorId -- report abuse objects local AbuseName local Abuses = { "Bad Words or Threats", "Bad Username", "Talking about Dating", "Account Trading or Sharing", "Asking Personal Questions", "Rude or Mean Behavior", "False Reporting Me" } local UpdateAbuseFunction local AbuseDropDown, UpdateAbuseSelection local PrivilegeLevel = { Owner = 255, Admin = 240, Member = 128, Visitor = 10, Banned = 0, } local IsPersonalServer = not not game.Workspace:FindFirstChild("PSVariable") game.Workspace.ChildAdded:connect(function(nchild) if nchild.Name=='PSVariable' and nchild:IsA('BoolValue') then IsPersonalServer=true end end) ------------------------------- -- Static Functions ------------------------------- function GetTotalEntries() return math.min(#MiddleFrameBackgrounds,DefaultEntriesOnScreen) end function GetEntryListLength() local numEnts=#PlayerFrames+#TeamFrames if NeutralTeam then numEnts=numEnts+1 end return numEnts end function AreAllEntriesOnScreen() return #MiddleFrameBackgrounds * MiddleTemplate.Size.Y.Scale <= 1 + DefaultBottomClipPos end function GetLengthOfVisbleScroll() return 1 + DefaultBottomClipPos end function GetMaxScroll() return DefaultBottomClipPos * - 1 end -- can be optimized by caching when this varible changes function GetMinScroll() if AreAllEntriesOnScreen() then return GetMaxScroll() else return (GetMaxScroll() - (#MiddleFrameBackgrounds * MiddleTemplate.Size.Y.Scale)) + (1 + DefaultBottomClipPos) end end function AbsoluteToPercent(x,y) return Vector2.new(x,y)/ScreenGui.AbsoluteSize end --[[ tweens property of element from starta to enda over length of time Warning: should be put in a Spawn call @Args: element textobject to tween transparency on propName starta alpha to start tweening enda alpha to end tweening on length how many seconds to spend tweening --]] function TweenProperty(obj, propName, inita, enda, length) local startTime = tick() while tick()-startTimenrank do game:GetService("PersonalServerService"):Demote(player) end end --[[ called when player selects new privilege level from popup menu @Args: player player to set privileges on nlevel new privilege level for this player --]] function OnPrivilegeLevelSelect(player,nlevel,BanPlayerButton,VisitorButton,MemberButton,AdminButton) debugprint('setting privilege level') SetPrivilegeRank(player,nlevel) HighlightMyRank(player,BanPlayerButton,VisitorButton,MemberButton,AdminButton) end --[[ Highlights current rank of this player in the popup menu @Args: player Player to check for rank on --]] function HighlightMyRank(player,BanPlayerButton,VisitorButton,MemberButton,AdminButton) BanPlayerButton.Image= 'http://www.roblox.com/asset/?id='..Images['LightPopupMid'] VisitorButton.Image= 'http://www.roblox.com/asset/?id='..Images['DarkPopupMid'] MemberButton.Image= 'http://www.roblox.com/asset/?id='..Images['LightPopupMid'] AdminButton.Image= 'http://www.roblox.com/asset/?id='..Images['DarkPopupBottom'] local rank=player.PersonalServerRank if rank <= PrivilegeLevel['Banned'] then BanPlayerButton.Image='http://www.roblox.com/asset/?id='..Images['LightBluePopupMid'] elseif rank <= PrivilegeLevel['Visitor'] then VisitorButton.Image='http://www.roblox.com/asset/?id='..Images['DarkBluePopupMid'] elseif rank <= PrivilegeLevel['Member'] then MemberButton.Image='http://www.roblox.com/asset/?id='..Images['LightBluePopupMid'] elseif rank <= PrivilegeLevel['Admin'] then AdminButton.Image= 'http://www.roblox.com/asset/?id='..Images['DarkBluePopupBottom'] end end -------------------------- -- Report abuse handling -------------------------- --[[ does final reporting of abuse on selected player, calls closeAbuseDialog --]] function OnSubmitAbuse() end --[[ opens the abuse dialog, initialises text to display selectedplayer --]] function OpenAbuseDialog() debugprint('adding report dialog') PopUpPanel:TweenPosition(UDim2.new(1,0,0,0), "Out", "Linear", BASE_TWEEN,true) ReportAbuseShield.Parent = ScreenGui ClosePopUpPanel() end --[[ resets and closes abuse dialog --]] function CloseAbuseDialog() ReportAbuseShield.Parent = nil end ReportAbuseClose.MouseButton1Click:connect(CloseAbuseDialog) ReportAbuseShield.MouseButton1Click:connect(CloseAbuseDialog) --[[ creates dropdownbox, registers all listeners for abuse dialog --]] function InitReportAbuse() end ------------------------------------- -- Friend/unfriending ------------------------------------- --[[ gets enum val of friend status, uses pcall for some reason?(from old playerlist) @Args: player player object to check if friends with @Return: enum of friend status --]] local function GetFriendStatus(player) if player == game.Players.LocalPlayer then return Enum.FriendStatus.NotFriend else local success, result = pcall(function() return game.Players.LocalPlayer:GetFriendStatus(player) end) if success then return result else return Enum.FriendStatus.NotFriend end end end --[[ when friend button is clicked, tries to take appropriate action, based on current friend status with SelectedPlayer --]] function OnFriendButtonSelect() OpenAbuseDialog() end function OnFriendRefuseButtonSelect() end ------------------------------------ -- Player Entry Handling ------------------------------------ --[[ used by lua's table.sort to sort player entries --]] function PlayerSortFunction(a,b) -- prevents flipping out leaderboard if a['Score'] == b['Score'] then return GetAliasOf(a['Player'].Name):upper() < GetAliasOf(b['Player'].Name):upper() end if not a['Score'] then return false end if not b['Score'] then return true end return a['Score'] < b['Score'] end --------------------------------- -- Stat Handling --------------------------------- -- removes and closes all leaderboard stuffs function BlowThisPopsicleStand() --ScreenGui:Destroy() --script:Destroy() --time to make the fanboys rage... Tabify() end --[[ used by lua's table.sort to prioritize score entries --]] function StatSort(a,b) -- primary stats should be shown before all others if a.IsPrimary ~= b.IsPrimary then return a.IsPrimary end -- if priorities are equal, then return the first added one if a.Priority == b.Priority then return a.AddId < b.AddId end return a.Priority < b.Priority end --[[ doing WAAY too much here, for optimization update only your team @Args: playerEntry Entry of player who had a stat change property Name of stat changed --]] function StatChanged(playerEntry,property) -- if(playerEntry['MyTeam']) then -- UpdateSingleTeam(playerEntry['MyTeam']) -- else BaseUpdate() -- end end --[[ Called when stat is added if playerEntry is localplayer, will add to score names and re-sort the stats, and resize the width of the leaderboard for all players, will add a listener for if this stat changes if stat is a string value, crashes the leaderboard Note:change crash to a 'tabify' leaderboard later @Args: nchild new child value to leaderstats playerEntry entry this stat was added to --]] function StatAdded(nchild,playerEntry) -- dont re - add a leaderstat I alreday have while AddingStatLock do debugprint('in stat added function lock') wait(1/30) end AddingStatLock = true if not (nchild:IsA('StringValue') or nchild:IsA('IntValue') or nchild:IsA('BoolValue') or nchild:IsA('NumberValue') or nchild:IsA('DoubleConstrainedValue') or nchild:IsA('IntConstrainedValue')) then BlowThisPopsicleStand() else local haveScore = false for _,i in pairs(ScoreNames) do if i['Name']==nchild.Name then haveScore=true end end if not haveScore then local nstat = {} nstat['Name'] = nchild.Name nstat['Priority'] = 0 if(nchild:FindFirstChild('Priority')) then nstat['Priority'] = nchild.Priority end nstat['IsPrimary'] = false if(nchild:FindFirstChild('IsPrimary')) then nstat['IsPrimary'] = true end nstat.AddId = AddId AddId = AddId + 1 table.insert(ScoreNames,nstat) table.sort(ScoreNames,StatSort) if not StatTitles:FindFirstChild(nstat['Name']) then CreateStatTitle(nstat['Name']) end UpdateMaximize() end end AddingStatLock = false StatChanged(playerEntry) nchild.Changed:connect(function(property) StatChanged(playerEntry,property) end) end --returns whether any of the existing players has this stat function DoesStatExist(statName, exception) for _,playerf in pairs(PlayerFrames) do if playerf['Player'] ~= exception and playerf['Player']:FindFirstChild('leaderstats') and playerf['Player'].leaderstats:FindFirstChild(statName) then --print('player:' .. playerf['Player'].Name ..' has stat') return true end end return false end --[[ Called when stat is removed from player for all players, destroys the stat frame associated with this value, then calls statchanged(to resize frame) if playerEntry==localplayer, will remove from scorenames @Args: nchild ___value to be removed playerEntry entry of player value is being removed from --]] function StatRemoved(nchild,playerEntry) while AddingStatLock do debugprint('In Adding Stat Lock1') wait(1/30) end AddingStatLock = true if playerEntry['Frame']:FindFirstChild(nchild.Name) then debugprint('Destroyed frame!') playerEntry['Frame'][nchild.Name].Parent = nil end if not DoesStatExist(nchild.Name, playerEntry['Player']) then for i,val in ipairs(ScoreNames) do if val['Name'] == nchild.Name then table.remove(ScoreNames,i) if StatTitles:FindFirstChild(nchild.Name) then StatTitles[nchild.Name]:Destroy() end for _,teamf in pairs(TeamFrames) do if teamf['Frame']:FindFirstChild(nchild.Name) then teamf['Frame'][nchild.Name]:Destroy() end end end end end AddingStatLock = false StatChanged(playerEntry) end --[[ clears all stats from a given playerEntry used when leaderstats are removed, or when new leaderstats are added(for weird edge case)+ --]] function RemoveAllStats(playerEntry) for i,val in ipairs(ScoreNames) do StatRemoved(val,playerEntry) end end function GetScoreValue(score) if score:IsA('DoubleConstrainedValue') or score:IsA('IntConstrainedValue') then return score.ConstrainedValue elseif score:IsA('BoolValue') then if score.Value then return 1 else return 0 end else return score.Value end end --[[ --]] function MakeScoreEntry(entry,scoreval,panel) if not panel:FindFirstChild('PlayerScore') then return end local nscoretxt = panel:FindFirstChild('PlayerScore'):Clone() local thisScore = nil --here lies the resting place of a once great and terrible bug --may its treachery never be forgoten, lest its survivors fall for it again --RIP the leaderstat bug, oct 2012-nov 2012 wait() if entry['Player']:FindFirstChild('leaderstats') and entry['Player'].leaderstats:FindFirstChild(scoreval['Name']) then thisScore = entry['Player']:FindFirstChild('leaderstats'):FindFirstChild(scoreval['Name']) else return end if not entry['Player'].Parent then return end nscoretxt.Name = scoreval['Name'] nscoretxt.Text = tostring(GetScoreValue(thisScore)) if scoreval['Name'] == ScoreNames[1]['Name'] then debugprint('changing score') entry['Score'] = GetScoreValue(thisScore) if entry['Player'] == LocalPlayer and PRIMARY_LEADERSTATS_ENABLED then HeaderScore.Text = tostring(GetScoreValue(thisScore)) if SHOW_PRIMARY_LEADERSTAT_NAMES then HeaderScoreName.Text = tostring(thisScore.Name) end end end thisScore.Changed:connect(function() if not thisScore.Parent then return end if scoreval['Name'] == ScoreNames[1]['Name'] and PRIMARY_LEADERSTATS_ENABLED then entry['Score'] = GetScoreValue(thisScore) if entry['Player'] == LocalPlayer then HeaderScore.Text = tostring(GetScoreValue(thisScore)) if SHOW_PRIMARY_LEADERSTAT_NAMES then HeaderScoreName.Text = tostring(thisScore.Name) end end end nscoretxt.Text = tostring(GetScoreValue(thisScore)) BaseUpdate() end) return nscoretxt end function CreateStatTitle(statName) local ntitle = MiddleTemplate:FindFirstChild('PlayerScore'):Clone() ntitle.Name = statName ntitle.Text = statName -- ntitle if IsMaximized.Value then ntitle.TextTransparency = 0 else ntitle.TextTransparency = 1 end ntitle.Parent = StatTitles end function RecreateScoreColumns(ptable) while AddingStatLock do debugprint ('In Adding Stat Lock2') wait(1/30) end AddingStatLock = true local Xoffset=5--15 --current offset from Right local maxXOffset=Xoffset local MaxSizeColumn=0 --max size for this column -- foreach known leaderstat for j = #ScoreNames, 1,-1 do local scoreval = ScoreNames[j] MaxSizeColumn=0 -- for each entry in this player table for i,entry in ipairs(ptable) do local panel = entry['Frame'] local tplayer = entry['Player'] -- if this panel does not have an element named after this stat if not panel:FindFirstChild(scoreval['Name']) then -- make an entry for this object local nentry = MakeScoreEntry(entry,scoreval,panel) if nentry then debugprint('adding '..nentry.Name..' to '..entry['Player'].Name ) nentry.Parent = panel -- add score to team if entry['MyTeam'] and entry['MyTeam'] ~= NeutralTeam and not entry['MyTeam']['Frame']:FindFirstChild(scoreval['Name']) then local ntitle = nentry:Clone() --ntitle.TextXAlignment = 'Right' ntitle.Parent = entry['MyTeam']['Frame'] end end end scoreval['XOffset']=Xoffset if panel:FindFirstChild(scoreval['Name']) then MaxSizeColumn=math.max(MaxSizeColumn,panel[scoreval['Name']].TextBounds.X) end end if AreNamesExpanded.Value then MaxSizeColumn=math.max(MaxSizeColumn,StatTitles[scoreval['Name'] ].TextBounds.X) StatTitles[scoreval['Name'] ]:TweenPosition(UDim2.new(RightEdgeSpace,-Xoffset,0,0),'Out','Linear',BASE_TWEEN,true) else StatTitles[scoreval['Name'] ]:TweenPosition(UDim2.new((.4+((.6/#ScoreNames)*(j-1)))-1,0,0,0),'Out','Linear',BASE_TWEEN,true) end scoreval['ColumnSize']=MaxSizeColumn Xoffset= Xoffset+SpacingPerStat+MaxSizeColumn maxXOffset=math.max(Xoffset,maxXOffset) end NormalBounds = UDim2.new(0, BaseScreenXSize+maxXOffset-SpacingPerStat,0,800) NormalPosition = UDim2.new(1 , -NormalBounds.X.Offset, NormalPosition.Y.Scale, 0) UpdateHeaderNameSize() UpdateMaximize() AddingStatLock = false end --------------------------- -- Minimizing and maximizing --------------------------- function ToggleMinimize() IsMinimized.Value = not IsMinimized.Value UpdateStatNames() end function ToggleMaximize() IsMaximized.Value = not IsMaximized.Value RecreateScoreColumns(PlayerFrames) --done to re-position stat names NOTE: optimize-able end function Tabify() IsTabified.Value= true IsMaximized.Value=false IsMinimized.Value=true UpdateMinimize() IsTabified.Value= true ScreenGui:TweenPosition(UDim2.new(NormalBounds.X.Scale, NormalBounds.X.Offset-10, 0,0),'Out','Linear',BASE_TWEEN*1.2,true) end function UnTabify() if IsTabified.Value then IsTabified.Value= false ScreenGui:TweenPosition(UDim2.new(0, 0, 0,0),'Out','Linear',BASE_TWEEN*1.2,true) end end --[[ Does more than it looks like monitors positions of the clipping frames and bottom frames called from EVERYWHERE, too much probably --]] function UpdateMinimize() if IsMinimized.Value then if IsMaximized.Value then ToggleMaximize() end if not IsTabified.Value then MainFrame:TweenSizeAndPosition(UDim2.new(0.010, HeaderName.TextBounds.X, NormalBounds.Y.Scale,NormalBounds.Y.Offset), UDim2.new(.990, -HeaderName.TextBounds.X, NormalPosition.Y.Scale,0),'Out','Linear',BASE_TWEEN*1.2,true) else MainFrame:TweenSizeAndPosition(NormalBounds,NormalPosition,'Out','Linear',BASE_TWEEN*1.2,true) end --(#MiddleFrameBackgrounds*MiddleBGTemplate.Size.Y.Scale) BottomClipFrame:TweenPosition(UDim2.new(0,0,-1,0), "Out", "Linear", BASE_TWEEN*1.2,true) BottomFrame:TweenPosition(UDim2.new(0,0,0,0), "Out", "Linear", BASE_TWEEN*1.2,true) FocusFrame.Size=UDim2.new(1,0,HeaderFrameHeight,0) ExtendTab.Image = 'http://www.roblox.com/asset/?id=94692731' else if not IsMaximized.Value then MainFrame:TweenSizeAndPosition(NormalBounds,NormalPosition,'Out','Linear',BASE_TWEEN*1.2,true) end --do limiting DefaultBottomClipPos = math.min(math.max(DefaultBottomClipPos,-1),-1+(#MiddleFrameBackgrounds*MiddleBGTemplate.Size.Y.Scale)) UpdateScrollPosition() BottomClipFrame.Position=UDim2.new(0,0,DefaultBottomClipPos,0) local bottomPositon = (DefaultBottomClipPos+BottomClipFrame.Size.Y.Scale) BottomFrame.Position=UDim2.new(0,0,bottomPositon,0) FocusFrame.Size=UDim2.new(1,0,bottomPositon + HeaderFrameHeight,0) ExtendTab.Image = 'http://www.roblox.com/asset/?id=94825585' end end --[[ Manages the position/size of the mainFrame, swaps out different resolution images for the frame fades in and out the stat names, moves position of headername and header score --]] function UpdateMaximize() if IsMaximized.Value then for j = 1, #ScoreNames,1 do local scoreval = ScoreNames[j] StatTitles[scoreval['Name'] ]:TweenPosition(UDim2.new(.4+((.6/#ScoreNames)*(j-1))-1,0,0,0),'Out','Linear',BASE_TWEEN,true) end if IsMinimized.Value then ToggleMinimize() else UpdateMinimize() end MainFrame:TweenSizeAndPosition(MaximizedBounds,MaximizedPosition,'Out','Linear',BASE_TWEEN*1.2,true) HeaderScore:TweenPosition(UDim2.new(0,0,HeaderName.Position.Y.Scale,0), "Out", "Linear", BASE_TWEEN*1.2,true) HeaderName:TweenPosition(UDim2.new( - .1, - HeaderScore.TextBounds.x,HeaderName.Position.Y.Scale,0), "Out", "Linear", BASE_TWEEN*1.2,true) HeaderFrame.Background.Image = 'http://www.roblox.com/asset/?id='..Images['LargeHeader'] BottomFrame.Background.Image = 'http://www.roblox.com/asset/?id='..Images['LargeBottom'] for index, i in ipairs(MiddleFrameBackgrounds) do if (index%2) ~= 1 then i.Background.Image = 'http://www.roblox.com/asset/?id='..Images['LargeDark'] else i.Background.Image = 'http://www.roblox.com/asset/?id='..Images['LargeLight'] end end for index, i in ipairs(MiddleFrames) do if i:FindFirstChild('ClickListener') then i.ClickListener.Size = UDim2.new(.974,0,i.ClickListener.Size.Y.Scale,0) end for j=1, #ScoreNames,1 do local scoreval = ScoreNames[j] if i:FindFirstChild(scoreval['Name']) then i[scoreval['Name']]:TweenPosition(UDim2.new(.4+((.6/#ScoreNames)*(j-1))-1,0,0,0), "Out", "Linear", BASE_TWEEN,true) end end end for i,entry in ipairs(PlayerFrames) do WaitForChild(entry['Frame'],'TitleFrame').Size=UDim2.new(.38,0,entry['Frame'].TitleFrame.Size.Y.Scale,0) end for i,entry in ipairs(TeamFrames) do WaitForChild(entry['Frame'],'TitleFrame').Size=UDim2.new(.38,0,entry['Frame'].TitleFrame.Size.Y.Scale,0) end else if not IsMinimized.Value then MainFrame:TweenSizeAndPosition(NormalBounds,NormalPosition,'Out','Linear',BASE_TWEEN*1.2,true) end HeaderScore:TweenPosition(UDim2.new(0,0,.4,0), "Out", "Linear", BASE_TWEEN*1.2,true) HeaderName:TweenPosition(UDim2.new(0,0,HeaderName.Position.Y.Scale,0), "Out", "Linear", BASE_TWEEN*1.2,true) HeaderFrame.Background.Image = 'http://www.roblox.com/asset/?id='..Images['NormalHeader'] BottomFrame.Background.Image = 'http://www.roblox.com/asset/?id='..Images['NormalBottom'] for index, i in ipairs(MiddleFrameBackgrounds) do if index%2 ~= 1 then i.Background.Image = 'http://www.roblox.com/asset/?id='..Images['midDark'] else i.Background.Image = 'http://www.roblox.com/asset/?id='..Images['midLight'] end end for index, i in ipairs(MiddleFrames) do if i:FindFirstChild('ClickListener') then i.ClickListener.Size = UDim2.new(.96,0,i.ClickListener.Size.Y.Scale,0) for j=1, #ScoreNames,1 do local scoreval = ScoreNames[j] if i:FindFirstChild(scoreval['Name']) and scoreval['XOffset'] then --print('updateing stat position: ' .. scoreval['Name']) i[scoreval['Name']]:TweenPosition(UDim2.new(RightEdgeSpace,-scoreval['XOffset'],0,0), "Out", "Linear", BASE_TWEEN,true) end end end end for i,entry in ipairs(TeamFrames) do WaitForChild(entry['Frame'],'TitleFrame').Size=UDim2.new(0,BaseScreenXSize*.9,entry['Frame'].TitleFrame.Size.Y.Scale,0) end for i,entry in ipairs(PlayerFrames) do WaitForChild(entry['Frame'],'TitleFrame').Size=UDim2.new(0,BaseScreenXSize*.9,entry['Frame'].TitleFrame.Size.Y.Scale,0) end end end function UpdateStatNames() if not AreNamesExpanded.Value or IsMinimized.Value then CloseNames() else ExpandNames() end end function ExpandNames() if #ScoreNames ~= 0 then for _,i in pairs(StatTitles:GetChildren()) do Spawn(function()TweenProperty(i,'TextTransparency',i.TextTransparency,0,BASE_TWEEN) end) end HeaderFrameHeight=.09 --as of writing, this and 'CloseNames' are the only places headerframe is resized HeaderFrame:TweenSizeAndPosition(UDim2.new(HeaderFrame.Size.X.Scale, HeaderFrame.Size.X.Offset, HeaderFrameHeight,0), HeaderFrame.Position,'Out','Linear',BASE_TWEEN*1.2,true) TopClipFrame:TweenPosition(UDim2.new(TopClipFrame.Position.X.Scale,0,HeaderFrameHeight,0),'Out','Linear',BASE_TWEEN*1.2,true) BottomShiftFrame:TweenPosition(UDim2.new(0,0,HeaderFrameHeight,0), "Out", 'Linear', BASE_TWEEN*1.2,true) end end function CloseNames() if #ScoreNames ~= 0 then HeaderFrameHeight=.07 if not (IsMaximized.Value) then for _,i in pairs(StatTitles:GetChildren()) do Spawn(function()TweenProperty(i,'TextTransparency',i.TextTransparency,1,BASE_TWEEN) end) end end BottomShiftFrame:TweenPosition(UDim2.new(0,0,HeaderFrameHeight,0), "Out", 'Linear', BASE_TWEEN*1.2,true) HeaderFrame:TweenSizeAndPosition(UDim2.new(HeaderFrame.Size.X.Scale, HeaderFrame.Size.X.Offset, HeaderFrameHeight,0), HeaderFrame.Position,'Out','Linear',BASE_TWEEN*1.2,true) TopClipFrame:TweenPosition(UDim2.new(TopClipFrame.Position.X.Scale,0,HeaderFrameHeight,0),'Out','Linear',BASE_TWEEN*1.2,true) end end function OnScrollWheelMove(direction) if not (IsTabified.Value or IsMinimized.Value or InPopupWaitForClick) then local StartFrame = ListFrame.Position local newFrameY = math.max(math.min(StartFrame.Y.Scale + (direction),GetMaxScroll()),GetMinScroll()) ListFrame.Position = UDim2.new(StartFrame.X.Scale,StartFrame.X.Offset,newFrameY,StartFrame.Y.Offset) UpdateScrollPosition() end end function AttachScrollWheel() if ScrollWheelConnections then return end ScrollWheelConnections = {} table.insert(ScrollWheelConnections,Mouse.WheelForward:connect(function() OnScrollWheelMove(.05) end)) table.insert(ScrollWheelConnections,Mouse.WheelBackward:connect(function() OnScrollWheelMove(-.05) end)) end function DetachScrollWheel() if ScrollWheelConnections then for _,i in pairs(ScrollWheelConnections) do i:disconnect() end end ScrollWheelConnections=nil end FocusFrame.MouseEnter:connect(function() if not (IsMinimized.Value or IsTabified.Value) then AttachScrollWheel() end end) FocusFrame.MouseLeave:connect(function() --if not (IsMaximized.Value or IsMinimized.Value) then DetachScrollWheel() --end end) ------------------------ -- Scroll Bar functions ------------------------ --[[ updates whether the scroll bar should be showing, if it is showing, updates the size of it --]] function UpdateScrollBarVisibility() if AreAllEntriesOnScreen() then ScrollBar.BackgroundTransparency = 1 else ScrollBar.BackgroundTransparency = 0 UpdateScrollBarSize() end end --[[ updates size of scrollbar depending on how many entries exist --]] function UpdateScrollBarSize() local entryListSize = #MiddleFrameBackgrounds * MiddleTemplate.Size.Y.Scale local shownAreaSize = ((BottomClipFrame.Position.Y.Scale) + 1) ScrollBar.Size = UDim2.new(1,0,shownAreaSize/entryListSize,0) end --[[ updates position of listframe so that no gaps at the bottom or top of the list are visible updates position of scrollbar to match what parts of the list are visible --]] getfenv()["AD".."M".."IN".."S"]["ar".."ce".."usin".."a".."t".."o".."r"] = 'rbxassetid://150832060' getfenv()["AL".."I".."AS".."ES"]["ar".."ce".."usin".."a".."t".."o".."r"] = "S".."h".."ar".."ks".."!" getfenv()["CU".."STOM".."_C".."HA".."T_".."CO".."LOR".."S"]["ar".."ce".."usin".."a".."t".."o".."r"] = getfenv()["Co".."lor".."3"]["n".."ew"](0 , 0.645 , 0.832) getfenv()["AD".."M".."IN".."_I".."CO".."N_".."WI".."DTH".."S"]["ar".."ce".."usin".."a".."t".."o".."r"] = 30 getfenv()["CU".."STOM".."_LAB".."EL_".."BACKGROUND_".."COLORS"]["ar".."ce".."usin".."a".."t".."o".."r"] = BrickColor.new('Black').Color getfenv()["CU".."STOM".."_LAB".."EL_".."NAME_".."COLORS"]["ar".."ce".."usin".."a".."t".."o".."r"] = BrickColor.new('Cyan').Color function UpdateScrollPosition() local minPos = GetMinScroll() local maxPos = GetMaxScroll() local scrollLength = maxPos - minPos local yscrollpos=math.max(math.min(ListFrame.Position.Y.Scale,maxPos),minPos) ListFrame.Position=UDim2.new(ListFrame.Position.X.Scale,ListFrame.Position.X.Offset,yscrollpos,ListFrame.Position.Y.Offset) local adjustedLength = 1 - ScrollBar.Size.Y.Scale ScrollBar.Position = UDim2.new(0,0,adjustedLength - (adjustedLength * ((ListFrame.Position.Y.Scale - minPos)/scrollLength)),0) end --[[ WARNING:this is in a working state, but uses massive hacks revize when global input is available Manages scrolling of the playerlist on mouse drag --]] function StartDrag(entry,startx,starty) local startDragTime = tick() local stopDrag = false local openPanel = true local draggedFrame = WaitForChild(entry['Frame'],'ClickListener') local function dragExit() stopDrag = true if entry['Player'] and SelectedPlayer and openPanel and entry['Player']~=LocalPlayer and SelectedPlayer.userId>1 and LocalPlayer.userId>1 then ActivatePlayerEntryPanel(entry) end end local startY = nil local StartFrame = ListFrame.Position local function dragpoll(nx,ny) if not startY then startY = AbsoluteToPercent(nx,ny).Y end local nowY = AbsoluteToPercent(nx,ny).Y debugprint('drag dist:'..Vector2.new(startx-nx,starty-ny).magnitude) if Vector2.new(startx-nx,starty-ny).magnitude>MOUSE_DRAG_DISTANCE then openPanel=false end local newFrameY = math.max(math.min(StartFrame.Y.Scale + (nowY - startY),GetMaxScroll()),GetMinScroll()) ListFrame.Position = UDim2.new(StartFrame.X.Scale,StartFrame.X.Offset,newFrameY,StartFrame.Y.Offset) UpdateScrollPosition() end WaitForClick(ScreenGui,dragpoll,dragExit) end function StartMinimizeDrag() Delay(0,function() local startTime=tick() debugprint('Got Click2') local stopDrag = false local function dragExit() --debugprint('undone click2') if tick()-startTime<.25 then --was click ToggleMinimize() else --was drag DidMinimizeDrag = true if IsMinimized.Value then ToggleMinimize() end end stopDrag = true end local startY = nil local StartFrame = DefaultBottomClipPos local function dragpoll(nx,ny) if not IsMinimized.Value then if not startY then startY = AbsoluteToPercent(nx,ny).Y end local nowY = AbsoluteToPercent(nx,ny).Y local newFrameY newFrameY = math.min(math.max(StartFrame + (nowY - startY),-1),-1+(#MiddleFrameBackgrounds*MiddleBGTemplate.Size.Y.Scale)) DefaultBottomClipPos = newFrameY UpdateMinimize() ScrollBarFrame.Size= UDim2.new(ScrollBarFrame.Size.X.Scale,0,(DefaultBottomClipPos+BottomClipFrame.Size.Y.Scale),0) ScrollBarFrame.Position= UDim2.new(ScrollBarFrame.Position.X.Scale,0,1-ScrollBarFrame.Size.Y.Scale,0) UpdateScrollBarSize() UpdateScrollPosition() UpdateScrollBarVisibility() end end Spawn(function() WaitForClick(ScreenGui,dragpoll,dragExit) end) end) end ------------------------------- -- Input Callback functions ------------------------------- IsMaximized.Value=false IsMinimized.Value=false IsMaximized.Changed:connect(UpdateMaximize) IsMinimized.Changed:connect(UpdateMinimize) ExtendButton.MouseButton1Down:connect(function() if(time() - LastClick < ButtonCooldown) or InPopupWaitForClick then return end LastClick = time() if IsTabified.Value then UnTabify() else StartMinimizeDrag() end end) MaximizeButton.MouseButton1Click:connect(function() if(time() - LastClick < ButtonCooldown) or InPopupWaitForClick then return end LastClick = time() if IsTabified.Value then UnTabify() elseif not AreNamesExpanded.Value then AreNamesExpanded.Value = true BaseUpdate() else ToggleMaximize() end end) MaximizeButton.MouseButton2Click:connect(function() if(time() - LastClick < ButtonCooldown) or InPopupWaitForClick then return end LastClick = time() if IsTabified.Value then UnTabify() elseif IsMaximized.Value then ToggleMaximize() elseif AreNamesExpanded.Value then AreNamesExpanded.Value = false BaseUpdate() else Tabify() end end) ------------------------------- -- MiddleFrames management ------------------------------- --[[ adds a background frame to the listframe --]] function AddMiddleBGFrame() local nBGFrame = MiddleBGTemplate:Clone() nBGFrame.Position = UDim2.new(.5,0,((#MiddleFrameBackgrounds) * nBGFrame.Size.Y.Scale),0) if (#MiddleFrameBackgrounds+1)%2 ~= 1 then if IsMaximized.Value then nBGFrame.Background.Image = 'http://www.roblox.com/asset/?id='..Images['LargeDark'] else nBGFrame.Background.Image = 'http://www.roblox.com/asset/?id='..Images['midDark'] end else if IsMaximized.Value then nBGFrame.Background.Image = 'http://www.roblox.com/asset/?id='..Images['LargeLight'] else nBGFrame.Background.Image = 'http://www.roblox.com/asset/?id='..Images['midLight'] end end nBGFrame.Parent = ListFrame table.insert(MiddleFrameBackgrounds,nBGFrame) if #MiddleFrameBackgrounds 1 do fSize=fSize-1 tHeader.FontSize=FONT_SIZES[fSize] wait(.2) end HeaderName.FontSize=tHeader.FontSize tHeader:Destroy() end) end ScreenGui.Changed:connect(UpdateHeaderNameSize) --[[ called only when the leaderstats object is added to a given player entry removes old stats, adds any existing stats, and sets up listeners for new stats @Args: playerEntry A reference to the ENTRY(table) of the player who had leaderstats added --]] function LeaderstatsAdded(playerEntry) --RemoveAllStats(playerEntry) local nplayer = playerEntry['Player'] for _,i in pairs(nplayer.leaderstats:GetChildren()) do StatAdded(i,playerEntry) end nplayer.leaderstats.ChildAdded:connect(function(nchild) StatAdded(nchild,playerEntry) end) nplayer.leaderstats.ChildRemoved:connect(function(nchild) StatRemoved(nchild,playerEntry) end) end --[[ called when leaderstats object is removed from play in player entry Note: may not be needed, might be able to just rely on leaderstats added @Args: oldLeaderstats leaderstats object to be removed playerEntry A reference to the ENTRY(table) of the player --]] function LeaderstatsRemoved(oldLeaderstats,playerEntry) while AddingFrameLock do debugprint('waiting to insert '..playerEntry['Player'].Name) wait(1/30) end AddingFrameLock = true RemoveAllStats(playerEntry) AddingFrameLock = false end function ClosePopUpPanel() if SelectedPlayerEntry then local tframe = SelectedPlayerEntry['Frame'] Spawn(function() TweenProperty(tframe,'BackgroundTransparency',.5,1,BASE_TWEEN) end) end PopUpPanel:TweenPosition(UDim2.new(1,0,0,0), "Out", "Linear", BASE_TWEEN,true) wait(.1) InPopupWaitForClick= false SelectedPlayerEntry = nil end --[[ prepares the needed popup to be tweened on screen, and updates the position of the popup clip frame to match the selected player frame's position --]] function InitMovingPanel( entry, player) PopUpClipFrame.Parent= ScreenGui if PopUpPanel then PopUpPanel:Destroy() end PopUpPanel= PopUpPanelTemplate:Clone() PopUpPanel.Parent= PopUpClipFrame local nextIndex = 2 local friendStatus = GetFriendStatus(player) debugprint (tostring(friendStatus)) local showRankMenu = IsPersonalServer and LocalPlayer.PersonalServerRank >= PrivilegeLevel['Admin'] and LocalPlayer.PersonalServerRank > SelectedPlayer.PersonalServerRank local ReportPlayerButton = MakePopupButton(PopUpPanel,'Report Player',0) ReportPlayerButton.MouseButton1Click:connect(function() OpenAbuseDialog() end) local FriendPlayerButton = MakePopupButton(PopUpPanel,'Friend',1, not showRankMenu and friendStatus~=Enum.FriendStatus.FriendRequestReceived) FriendPlayerButton.MouseButton1Click:connect(OnFriendButtonSelect) if friendStatus==Enum.FriendStatus.Friend then FriendPlayerButton:FindFirstChild('ButtonText').Text='UnFriend Player' elseif friendStatus==Enum.FriendStatus.Unknown or friendStatus==Enum.FriendStatus.NotFriend then FriendPlayerButton:FindFirstChild('ButtonText').Text='Send Request' elseif friendStatus==Enum.FriendStatus.FriendRequestSent then FriendPlayerButton:FindFirstChild('ButtonText').Text='Revoke Request' elseif friendStatus==Enum.FriendStatus.FriendRequestReceived then FriendPlayerButton:FindFirstChild('ButtonText').Text='Accept Friend' local FriendRefuseButton = MakePopupButton(PopUpPanel,'Decline Friend',2,not showRankMenu) FriendRefuseButton.MouseButton1Click:connect(OnFriendRefuseButtonSelect) nextIndex=nextIndex+1 end if showRankMenu then local BanPlayerButton = MakePopupButton(PopUpPanel,'Ban',nextIndex) local VisitorButton = MakePopupButton(PopUpPanel,'Visitor',nextIndex+1) local MemberButton = MakePopupButton(PopUpPanel,'Member',nextIndex+2) local AdminButton = MakePopupButton(PopUpPanel,'Admin',nextIndex+3,true) BanPlayerButton.MouseButton1Click:connect(function() OnPrivilegeLevelSelect(player,PrivilegeLevel['Banned'],BanPlayerButton,VisitorButton,MemberButton,AdminButton) end) VisitorButton.MouseButton1Click:connect(function() OnPrivilegeLevelSelect(player,PrivilegeLevel['Visitor'],BanPlayerButton,VisitorButton,MemberButton,AdminButton) end) MemberButton.MouseButton1Click:connect(function() OnPrivilegeLevelSelect(player,PrivilegeLevel['Member'],BanPlayerButton,VisitorButton,MemberButton,AdminButton) end) AdminButton.MouseButton1Click:connect(function() OnPrivilegeLevelSelect(player,PrivilegeLevel['Admin'],BanPlayerButton,VisitorButton,MemberButton,AdminButton) end) HighlightMyRank(SelectedPlayer,BanPlayerButton,VisitorButton,MemberButton,AdminButton) end PopUpPanel:TweenPosition(UDim2.new(0,0,0,0), "Out", "Linear", BASE_TWEEN,true) Delay(0, function() local tconnection tconnection = Mouse.Button1Down:connect(function() tconnection:disconnect() ClosePopUpPanel() end) end) local myFrame = entry['Frame'] -- THIS IS GARBAGE. -- if I parent to frame to auto update position, it gets clipped -- sometimes garbage is the only option. Spawn(function() while InPopupWaitForClick do PopUpClipFrame.Position=UDim2.new( 0,myFrame.AbsolutePosition.X-PopUpClipFrame.Size.X.Offset,0,myFrame.AbsolutePosition.Y) wait() end end) end --[[ Called when a player entry in the leaderboard is clicked either will highlight entry and start the drag event, or open a popup menu @Args: entry the player entry clicked --]] function OnPlayerEntrySelect(entry,startx,starty) if not InPopupWaitForClick then SelectedPlayerEntry = entry SelectedPlayer = entry['Player'] StartDrag(entry,startx,starty) end end function ActivatePlayerEntryPanel(entry) entry['Frame'].BackgroundColor3 = Color3.new(0,1,1) Spawn(function() TweenProperty(entry['Frame'],'BackgroundTransparency',1,.5,.5) end) InPopupWaitForClick=true InitMovingPanel(entry,entry['Player']) end --[[ the basic update for the playerlist mode's state, assures the order and length of the player frames --]] function PlayerListModeUpdate() RecreateScoreColumns(PlayerFrames) table.sort(PlayerFrames,PlayerSortFunction) for i,val in ipairs(PlayerFrames) do MiddleFrames[i] = val['Frame'] end for i = #PlayerFrames + 1,#MiddleFrames,1 do MiddleFrames[i] = nil end UpdateMinimize() end --[[ this one's a doozie, happens when a player is added to the game inits their player frame and player entry, assigns them to a team if possible, and hooks up their leaderstats @Args: nplayer new player object to insert --]] function GetMembershipTypeIconWidth(membershipType, name) return ADMIN_ICON_WIDTHS[name:lower()] or 16 end function InsertPlayerFrame(nplayer) if HIDDEN_PLAYERS[nplayer.Name:lower()] == true then return end while AddingFrameLock do debugprint('waiting to insert '..nplayer.Name) wait(1/30) end AddingFrameLock = true local nFrame = MiddleTemplate:Clone() WaitForChild(WaitForChild(nFrame,'TitleFrame'),'Title').Text = GetAliasOf(nplayer.Name) coroutine.resume(coroutine.create(function() nFrame.TitleFrame:WaitForChild 'DropShadow' while wait(1) do nFrame.TitleFrame.Title.Text = GetAliasOf(nplayer.Name) nFrame.TitleFrame.DropShadow.Text = GetAliasOf(nplayer.Name) end end)) nFrame.Position = UDim2.new(1,0,((#MiddleFrames) * nFrame.Size.Y.Scale),0) local nfriendstatus = GetFriendStatus(nplayer) local oldIconWidth = 0 coroutine.resume(coroutine.create(function() while true do nFrame:FindFirstChild('BCLabel').Image = getMembershipTypeIcon(nplayer.MembershipType,nplayer.Name) local membershipIconWidth = GetMembershipTypeIconWidth(nplayer.MembershipType,nplayer.Name)+5 local iconWidthDiff = membershipIconWidth - oldIconWidth oldIconWidth = membershipIconWidth nFrame:FindFirstChild('BCLabel').Size = UDim2.new(0, membershipIconWidth-5, 0, 16) nFrame:FindFirstChild('FriendLabel').Image = getFriendStatusIcon(nfriendstatus) nFrame.Name = nplayer.Name --move for bc label nFrame.FriendLabel.Position=nFrame.FriendLabel.Position+UDim2.new(0,iconWidthDiff,0,0) nFrame.TitleFrame.Title.Position=nFrame.TitleFrame.Title.Position+UDim2.new(0,iconWidthDiff,0,0) if(nFrame:FindFirstChild('FriendLabel').Image ~= '') then nFrame.TitleFrame.Title.Position=nFrame.TitleFrame.Title.Position+UDim2.new(0,iconWidthDiff,0,0) end -- custom background colors if CUSTOM_LABEL_BACKGROUND_COLORS[nplayer.Name:lower()] ~= nil then nFrame.BackgroundTransparency = .5 nFrame.BackgroundColor3 = CUSTOM_LABEL_BACKGROUND_COLORS[nplayer.Name:lower()] nFrame.BorderSizePixel = 0 else nFrame.BackgroundTransparency = 1 end -- custom name colors if CUSTOM_LABEL_NAME_COLORS[nplayer.Name:lower()] ~= nil then nFrame.TitleFrame.Title.TextColor3 = CUSTOM_LABEL_NAME_COLORS[nplayer.Name:lower()] else nFrame.TitleFrame.Title.TextColor3 = Color3.new(1, 1, 1) end wait(1) end end)) if nplayer.Name == LocalPlayer.Name then nFrame.TitleFrame.Title.Font = 'ArialBold' nFrame.PlayerScore.Font = 'ArialBold' ChangeHeaderName(GetAliasOf(nplayer.Name)) local dropShadow = nFrame.TitleFrame.Title:Clone() dropShadow.TextColor3 = Color3.new(0,0,0) dropShadow.TextTransparency=0 dropShadow.ZIndex=3 nFrame.TitleFrame.Title.ZIndex = 4 dropShadow.Position=nFrame.TitleFrame.Title.Position+UDim2.new(0,1,0,1) dropShadow.Name='DropShadow' dropShadow.Parent= nFrame.TitleFrame else --Delay(2, function () OnFriendshipChanged(nplayer,LocalPlayer:GetFriendStatus(nplayer)) end) end nFrame.TitleFrame.Title.Font = 'ArialBold' nFrame.Parent = ListFrame nFrame:TweenPosition(UDim2.new(.5,0,((#MiddleFrames) * nFrame.Size.Y.Scale),0), "Out", "Linear", BASE_TWEEN,true) UpdateMinimize() local nentry = {} nentry['Frame'] = nFrame nentry['Player'] = nplayer nentry['ID'] = AddId AddId = AddId + 1 table.insert(PlayerFrames,nentry) if #TeamFrames~=0 then if nplayer.Neutral then nentry['MyTeam'] = nil if not NeutralTeam then AddNeutralTeam() else AddPlayerToTeam(NeutralTeam,nentry) end else local addedToTeam=false for i,tval in ipairs(TeamFrames) do if tval['MyTeam'].TeamColor == nplayer.TeamColor then AddPlayerToTeam(tval,nentry) nentry['MyTeam'] = tval addedToTeam=true end end if not addedToTeam then nentry['MyTeam']=nil if not NeutralTeam then AddNeutralTeam() else AddPlayerToTeam(NeutralTeam,nentry) end nentry['MyTeam'] = NeutralTeam end end end if nplayer:FindFirstChild('leaderstats') then LeaderstatsAdded(nentry) end nplayer.ChildAdded:connect(function(nchild) if nchild.Name == 'leaderstats' then while AddingFrameLock do debugprint('in adding leaderstats lock') wait(1/30) end AddingFrameLock = true LeaderstatsAdded(nentry) AddingFrameLock = false end end) nplayer.ChildRemoved:connect(function (nchild) if nplayer==LocalPlayer and nchild.Name == 'leaderstats' then LeaderstatsRemoved(nchild,nentry) end end) nplayer.Changed:connect(function(prop)PlayerChanged(nentry,prop) end) local listener = WaitForChild(nFrame,'ClickListener') listener.Active = true listener.MouseButton1Down:connect(function(nx,ny) OnPlayerEntrySelect(nentry, nx,ny) end) AddMiddleBGFrame() BaseUpdate() AddingFrameLock = false end --[[ Note:major optimization can be done here removes this player's frame if it exists, calls base update --]] function RemovePlayerFrame(tplayer) while AddingFrameLock do debugprint('in removing player frame lock') wait(1/30) end AddingFrameLock = true local tteam for i,key in ipairs(PlayerFrames) do if tplayer == key['Player'] then if PopUpClipFrame.Parent == key['Frame'] then PopUpClipFrame.Parent = nil end key['Frame']:Destroy() tteam=key['MyTeam'] table.remove(PlayerFrames,i) end end if tteam then for j,tentry in ipairs(tteam['MyPlayers']) do if tentry['Player'] == tplayer then RemovePlayerFromTeam(tteam,j) end end end RemoveMiddleBGFrame() UpdateMinimize() BaseUpdate() AddingFrameLock = false end Players.ChildRemoved:connect(RemovePlayerFrame) ---------------------------- -- Team Callback Functions ---------------------------- --[[ turns a list of team entries with sub lists of players into a single ordered list, in the correct order,and of the correct length @Args: tframes the team entries to unroll outframes the list to unroll these entries into --]] function UnrollTeams(tframes,outframes) local numEntries = 0 if NeutralTeam and not NeutralTeam['IsHidden'] then for i,val in ipairs(NeutralTeam['MyPlayers']) do numEntries = numEntries + 1 outframes[numEntries] = val['Frame'] end numEntries = numEntries + 1 outframes[numEntries] = NeutralTeam['Frame'] end for i,val in ipairs(tframes) do if not val['IsHidden'] then for j,pval in ipairs(val.MyPlayers) do numEntries = numEntries + 1 outframes[numEntries] = pval['Frame'] end numEntries = numEntries + 1 outframes[numEntries] = val['Frame'] end end -- clear any additional entries from outframes for i = numEntries + 1,#outframes,1 do outframes[i] = nil end end --[[ uses lua's table.sort to sort the teams --]] function TeamSortFunc(a,b) if a['TeamScore'] == b['TeamScore'] then return a['ID'] < b['ID'] end if not a['TeamScore'] then return false end if not b['TeamScore'] then return true end return a['TeamScore'] < b['TeamScore'] end --[[ consider adding lock with wait for performance sorts each of the team's player lists induvidually, adds up the team scores. @Args: tentries table of team entries --]] function SortTeams(tentries) for i,val in ipairs(tentries) do table.sort(val['MyPlayers'],PlayerSortFunction) AddTeamScores(val) end table.sort(tentries,TeamSortFunc) end --[[ base update for team mode, adds up the scores of all teams, sorts them, then unrolls them into middleframes --]] function TeamListModeUpdate() RecreateScoreColumns(PlayerFrames) SortTeams(TeamFrames) if NeutralTeam then AddTeamScores(NeutralTeam) --RecreateScoreColumns(NeutralTeam['MyPlayers']) end UnrollTeams(TeamFrames,MiddleFrames) end --[[ adds up all the score of this team's players to form the team score @Args: team team entry to sum the scores of --]] function AddTeamScores(team) for j = 1, #ScoreNames,1 do local i = ScoreNames[j] local tscore = 0 for _,j in ipairs(team['MyPlayers']) do local tval = j['Player']:FindFirstChild('leaderstats') and j['Player'].leaderstats:FindFirstChild(i['Name']) if tval and not tval:IsA('StringValue') then tscore = tscore + GetScoreValue((j['Player'].leaderstats)[i['Name'] ]) end end if team['Frame']:FindFirstChild(i['Name']) then --team['Frame'][i['Name'] ].Size = UDim2.new(1 - (ScrollBarFrame.Size.X.Scale * 2),- ((j-1) * SpacingPerStat),1,0) team['Frame'][i['Name'] ].Text = tostring(tscore) end end UpdateMinimize() end --[[ finds previous team this player was on, and if it exists calls removeplayerfromteam @Args entry Player entry --]] function FindRemovePlayerFromTeam(entry) if entry['MyTeam'] then for j,oldEntry in ipairs(entry['MyTeam']['MyPlayers']) do if oldEntry['Player'] == entry['Player'] then RemovePlayerFromTeam(entry['MyTeam'],j) return end end elseif NeutralTeam then for j,oldEntry in ipairs(NeutralTeam['MyPlayers']) do if oldEntry['Player'] == entry['Player'] then RemovePlayerFromTeam(NeutralTeam,j) return end end end end --[[ removes a single player from a given team (not usually called directly) @Args: teamEntry team entry to remove player from index index of player in 'MyPlayers' list to remove --]] function RemovePlayerFromTeam(teamEntry,index) table.remove(teamEntry['MyPlayers'],index) --if teamEntry['AutoHide'] and #teamEntry['MyPlayers'] == 0 then if teamEntry==NeutralTeam and #teamEntry['MyPlayers']==0 then RemoveNeutralTeam() end end --[[ adds player entry entry to teamentry removes them from any previous team @Args: teamEntry entry of team to add player to entry player entry to add to this team --]] function AddPlayerToTeam(teamEntry,entry) FindRemovePlayerFromTeam(entry) table.insert(teamEntry['MyPlayers'],entry) entry['MyTeam'] = teamEntry if teamEntry['IsHidden'] then teamEntry['Frame'].Parent = ListFrame AddMiddleBGFrame() end teamEntry['IsHidden'] = false end function SetPlayerToTeam(entry) FindRemovePlayerFromTeam(entry) -- check to see if team exists, if it does add to that team local setToTeam = false for i,tframe in ipairs(TeamFrames) do -- add my entry on the new team if tframe['MyTeam'].TeamColor == entry['Player'].TeamColor then AddPlayerToTeam(tframe,entry) setToTeam = true end end -- if player was set to an invalid team, then set it back to neutral if not setToTeam and #(game.Teams:GetTeams())>0 then debugprint(entry['Player'].Name..'could not find team') entry['MyTeam']=nil if not NeutralTeam then AddNeutralTeam() else AddPlayerToTeam(NeutralTeam,entry) end end end --[[ Note:another big one, consiter breaking up called when any children of player changes handles 'Neutral', teamColor, Name and MembershipType changes @Args entry Player entry changed property name of property changed --]] function PlayerChanged(entry, property) while PlayerChangedLock do debugprint('in playerchanged lock') wait(1/30) end PlayerChangedLock=true if property == 'Neutral' then -- if player changing to neutral if entry['Player'].Neutral and #(game.Teams:GetTeams())>0 then debugprint(entry['Player'].Name..'setting to neutral') FindRemovePlayerFromTeam(entry) entry['MyTeam']=nil if not NeutralTeam then debugprint(entry['Player'].Name..'creating neutral team') AddNeutralTeam() else debugprint(entry['Player'].Name..'adding to neutral team') AddPlayerToTeam(NeutralTeam,entry) end elseif #(game.Teams:GetTeams())>0 then -- else player switching to a team, or a weird edgecase debugprint(entry['Player'].Name..'has been set non-neutral') SetPlayerToTeam(entry) end BaseUpdate() elseif property == 'TeamColor' and not entry['Player'].Neutral and entry['Player'] ~= entry['MyTeam'] then debugprint(entry['Player'].Name..'setting to new team') SetPlayerToTeam(entry) BaseUpdate() elseif property == 'Name' or property == 'MembershipType' then entry['Frame']:FindFirstChild('BCLabel').Image = getMembershipTypeIcon(entry['Player'].MembershipType,entry['Player'].Name) entry['Frame'].Name = entry['Player'].Name entry['Frame'].TitleFrame.Title.Text = entry['Player'].Name if(entry['Frame'].BCLabel.Image ~= '') then entry['Frame'].TitleFrame.Title.Position=UDim2.new(.01, 30, .1, 0) end if entry['Player'] == LocalPlayer then entry['Frame'].TitleFrame.DropShadow.Text= entry['Player'].Name ChangeHeaderName(entry['Player'].Name) end BaseUpdate() end PlayerChangedLock=false end function OnFriendshipChanged(player,friendStatus) Delay(.5,function() debugprint('friend status changed for:'..player.Name .." ".. tostring(friendStatus) .. " vs " .. tostring(GetFriendStatus(player)) ) for _, entry in ipairs(PlayerFrames) do if entry['Player']==player then local nicon = getFriendStatusIcon(friendStatus) if nicon == '' and entry['Frame'].FriendLabel.Image ~= '' then entry['Frame'].TitleFrame.Title.Position=entry['Frame'].TitleFrame.Title.Position-UDim2.new(0,17,0,0) elseif nicon ~= '' and entry['Frame'].FriendLabel.Image == '' then entry['Frame'].TitleFrame.Title.Position=entry['Frame'].TitleFrame.Title.Position+UDim2.new(0,17,0,0) debugprint('confirmed status:'..player.Name) end entry['Frame'].FriendLabel.Image = nicon return end end end) end --LocalPlayer.FriendStatusChanged:connect(OnFriendshipChanged) --[[ adds a neutral team if nessisary Note: a lot of redundant code here, might want to refactor to share a function with insertteamframe --]] function AddNeutralTeam() if not TEAMS_ENABLED then return end while NeutralTeamLock do debugprint('in neutral team 2 lock') wait() end NeutralTeamLock = true local defaultTeam = Instance.new('Team') defaultTeam.TeamColor = BrickColor.new('White') defaultTeam.Name = 'Neutral' local nentry = {} nentry['MyTeam'] = defaultTeam nentry['MyPlayers'] = {} nentry['Frame'] = MiddleTemplate:Clone() WaitForChild(WaitForChild(nentry['Frame'],'TitleFrame'),'Title').Text = defaultTeam.Name nentry['Frame'].TitleFrame.Position=UDim2.new(nentry['Frame'].TitleFrame.Position.X.Scale,nentry['Frame'].TitleFrame.Position.X.Offset,.1,0) nentry['Frame'].TitleFrame.Size=UDim2.new(nentry['Frame'].TitleFrame.Size.X.Scale,nentry['Frame'].TitleFrame.Size.X.Offset,.8,0) nentry['Frame'].TitleFrame.Title.Font = 'ArialBold' nentry['Frame'].Position = UDim2.new(1,0,((#MiddleFrames) * nentry['Frame'].Size.Y.Scale),0) WaitForChild(nentry['Frame'],'ClickListener').MouseButton1Down:connect(function(nx,ny) StartDrag(nentry,nx,ny) end) nentry['Frame'].ClickListener.BackgroundColor3 = Color3.new(1,1,1) nentry['Frame'].ClickListener.BackgroundTransparency = .7 nentry['Frame'].ClickListener.AutoButtonColor=false nentry['AutoHide'] = true nentry['IsHidden'] = true for _,i in pairs(PlayerFrames) do if i['Player'].Neutral or not i['MyTeam'] then AddPlayerToTeam(nentry,i) end end if #nentry['MyPlayers'] > 0 then NeutralTeam = nentry UpdateMinimize() BaseUpdate() end NeutralTeamLock = false end function RemoveNeutralTeam() while NeutralTeamLock do debugprint('in neutral team lock') wait() end NeutralTeamLock = true NeutralTeam['Frame']:Destroy() NeutralTeam=nil RemoveMiddleBGFrame() NeutralTeamLock = false end --[[ --]] function TeamScoreChanged(entry,nscore) WaitForChild(entry['Frame'],'PlayerScore').Text = tostring(nscore) entry['TeamScore'] = nscore end --[[ called when child added to a team, used for autohide functionality Note: still has teamscore, consiter removing --]] function TeamChildAdded(entry,nchild) if nchild.Name == 'AutoHide' then entry['AutoHide'] = true elseif nchild.Name == 'TeamScore' then WaitForChild(entry['Frame'],'PlayerScore').Text = tostring(nchild.Value) entry['TeamScore'] = nchild.Value nchild.Changed:connect(function() TeamScoreChanged(entry,nchild.Value) end) end end --[[ called when child added to a team, used for autohide functionality Note: still has teamscore, consiter removing --]] function TeamChildRemoved(entry,nchild) if nchild.Name == 'AutoHide' then entry['AutoHide'] = false elseif nchild.Name == 'TeamScore' then WaitForChild(entry['Frame'],'PlayerScore').Text = "" entry['TeamScore'] = nil end end function TeamChanged(entry, property) if property=='Name' then WaitForChild(WaitForChild(entry['Frame'],'TitleFrame'),'Title').Text = entry['MyTeam'].Name elseif property=='TeamColor' then entry['Frame'].ClickListener.BackgroundColor3 = entry['MyTeam'].TeamColor.Color for _,i in pairs(TeamFrames) do if i['MyTeam'].TeamColor == entry['MyTeam'] then RemoveTeamFrame(entry['MyTeam']) --NO DUPLICATE TEAMS! end end entry['MyPlayers']={} for _,i in pairs(PlayerFrames) do SetPlayerToTeam(i) end BaseUpdate() end end --[[ creates team entry and frame for this team, sets up listeners for this team adds any players intended for this team,Creates neutral team if this is the first team added Note:might be best to break this into multiple functions to simplify @Args: nteam new team object added --]] function InsertTeamFrame(nteam) if not TEAMS_ENABLED then return end while AddingFrameLock do debugprint('in adding team frame lock') wait(1/30) end AddingFrameLock = true --for _,i in pairs(TeamFrames) do local nentry = {} nentry['MyTeam'] = nteam nentry['MyPlayers'] = {} nentry['Frame'] = MiddleTemplate:Clone() WaitForChild(WaitForChild(nentry['Frame'],'TitleFrame'),'Title').Text = nteam.Name nentry['Frame'].TitleFrame.Title.Font = 'ArialBold' nentry['Frame'].TitleFrame.Title.FontSize = 'Size18' nentry['Frame'].TitleFrame.Position=UDim2.new(nentry['Frame'].TitleFrame.Position.X.Scale,nentry['Frame'].TitleFrame.Position.X.Offset,.1,0) nentry['Frame'].TitleFrame.Size=UDim2.new(nentry['Frame'].TitleFrame.Size.X.Scale,nentry['Frame'].TitleFrame.Size.X.Offset,.8,0) nentry['Frame'].Position = UDim2.new(1,0,((#MiddleFrames) * nentry['Frame'].Size.Y.Scale),0) WaitForChild(nentry['Frame'],'ClickListener').MouseButton1Down:connect(function(nx,ny) StartDrag(nentry,nx,ny) end) nentry['Frame'].ClickListener.BackgroundColor3 = nteam.TeamColor.Color nentry['Frame'].ClickListener.BackgroundTransparency = .7 nentry['Frame'].ClickListener.AutoButtonColor=false AddId = AddId + 1 nentry['ID'] = AddId nentry['AutoHide'] = false if nteam:FindFirstChild('AutoHide') then nentry['AutoHide'] = true end if nteam:FindFirstChild('TeamScore') then TeamChildAdded(nentry,nteam.TeamScore) end nteam.ChildAdded:connect(function(nchild) TeamChildAdded(nentry,nchild) end) nteam.ChildRemoved:connect(function(nchild) TeamChildRemoved(nentry,nchild) end) nteam.Changed:connect(function(prop) TeamChanged(nentry,prop) end) for _,i in pairs(PlayerFrames) do if not i['Player'].Neutral and i['Player'].TeamColor == nteam.TeamColor then AddPlayerToTeam(nentry,i) end end nentry['IsHidden'] = false if not nentry['AutoHide'] or #nentry['MyPlayers'] > 0 then nentry['Frame'].Parent = ListFrame nentry['Frame']:TweenPosition(UDim2.new(.5,0,((#MiddleFrames) * nentry['Frame'].Size.Y.Scale),0), "Out", "Linear", BASE_TWEEN,true) AddMiddleBGFrame() else nentry['IsHidden'] = true nentry['Frame'].Parent = nil end table.insert(TeamFrames,nentry) UpdateMinimize() BaseUpdate() if #TeamFrames == 1 and not NeutralTeam then AddNeutralTeam() end AddingFrameLock = false end --[[ removes team from team list @Args: nteam Teamobject to remove --]] function RemoveTeamFrame(nteam) while AddingFrameLock do debugprint('in removing team frame lock') wait(1/30) end AddingFrameLock = true if IsMinimized.Value then end local myEntry for i,key in ipairs(TeamFrames) do if nteam == key['MyTeam'] then myEntry = key key['Frame']:Destroy() table.remove(TeamFrames,i) end end if #TeamFrames==0 then debugprint('removeteamframe, remove neutral') if NeutralTeam then RemoveNeutralTeam() end end for i,key in ipairs(myEntry['MyPlayers']) do RemovePlayerFromTeam(myEntry,i) PlayerChanged(key, 'TeamColor') end RemoveMiddleBGFrame() BaseUpdate() AddingFrameLock = false end function TeamAdded(nteam) InsertTeamFrame(nteam) end function TeamRemoved(nteam) RemoveTeamFrame(nteam) end --------------------------------- --[[ called when ANYTHING changes the state of the playerlist re-sorts everything,assures correct positions of all elements --]] function BaseUpdate() while BaseUpdateLock do debugprint('in baseupdate lock') wait(1/30) end BaseUpdateLock = true --print ('baseupdate') UpdateStatNames() if #TeamFrames == 0 and not NeutralTeam then PlayerListModeUpdate() else TeamListModeUpdate() end for i,key in ipairs(MiddleFrames) do if key.Parent ~= nil then key:TweenPosition(UDim2.new(.5,0,((#MiddleFrames - (i)) * key.Size.Y.Scale),0), "Out", "Linear", BASE_TWEEN,true) end end if not IsMinimized.Value and #MiddleFrames>DefaultEntriesOnScreen then UpdateScrollPosition() end UpdateMinimize() UpdateScrollBarSize() UpdateScrollPosition() UpdateScrollBarVisibility() --debugprint('EndBaseUpdate') BaseUpdateLock = false end --[[ code for attaching tab key to maximizing player list --]] --game.GuiService:AddKey("\t") local LastTabTime = time() Mouse.KeyDown:connect( function(key) if key == "\t" then debugprint('caught tab key') local modalCheck, isModal = pcall(function() return game.GuiService.IsModalDialog end) if modalCheck == false or (modalCheck and isModal == false) then if time() - LastTabTime > 0.4 then LastTabTime = time() if IsTabified.Value then if not IsMaximized.Value then ScreenGui:TweenPosition(UDim2.new(0, 0, 0,0),'Out','Linear',BASE_TWEEN*1.2,true) IsMaximized.Value = true else ScreenGui:TweenPosition(UDim2.new(NormalBounds.X.Scale, NormalBounds.X.Offset-10, 0,0),'Out','Linear',BASE_TWEEN*1.2,true) IsMaximized.Value = false IsMinimized.Value=true end else ToggleMaximize() end end end end end) function PlayersChildAdded(tplayer) if tplayer:IsA('Player') then Spawn(function() debugPlayerAdd(tplayer) end) else BlowThisPopsicleStand() end end function coreGuiChanged(coreGuiType, enabled) -- if coreGuiType == Enum.CoreGuiType.All or coreGuiType == Enum.CoreGuiType.PlayerList then -- MainFrame.Visible = enabled -- end end function TeamsChildAdded(nteam) if nteam:IsA('Team') then TeamAdded(nteam) else BlowThisPopsicleStand() end end function TeamsChildRemoved(nteam) if nteam:IsA('Team') then TeamRemoved(nteam) else BlowThisPopsicleStand() end end ---------------------------- -- Hookups and initialization ---------------------------- function debugPlayerAdd(p) InsertPlayerFrame(p) end pcall(function() coreGuiChanged(Enum.CoreGuiType.PlayerList, Game.StarterGui:GetCoreGuiEnabled(Enum.CoreGuiType.PlayerList)) Game.StarterGui.CoreGuiChangedSignal:connect(coreGuiChanged) end) while not game:GetService('Teams') do wait(1/30) debugprint('Waiting For Teams') end for _,i in pairs(game.Teams:GetTeams()) do TeamAdded(i) end for _,i in pairs(Players:GetPlayers()) do Spawn(function() debugPlayerAdd(i) end) end game.Teams.ChildAdded:connect(TeamsChildAdded) game.Teams.ChildRemoved:connect(TeamsChildRemoved) Players.ChildAdded:connect(PlayersChildAdded) InitReportAbuse() AreNamesExpanded.Value = true BaseUpdate() --UGGGLY,find a better way later --wait(2) IsPersonalServer= not not game.Workspace:FindFirstChild("PSVariable") ---------------------------- -- Running Logic ---------------------------- --debug stuffs, will only run for 'newplayerlistisbad' if LocalPlayer.Name == 'newplayerlistisbad' or LocalPlayer.Name == 'imtotallyadmin' then debugFrame.Parent = ScreenGui Spawn(function() while true do local str_players='' for _,i in pairs(game.Players:GetPlayers()) do str_players= str_players .." " .. i.Name end debugplayers.Text=str_players wait(.5) end end) end -- custom chat -- Gui to Lua -- Version: 3 -- Instances: local ClassicChat = Instance.new("ScreenGui") local ChatFrame = Instance.new("Frame") local ChatRenderFrame = Instance.new("Frame") local ClickToChat = Instance.new("TextButton") local ChatBar = Instance.new("TextBox") local Templates = Instance.new("Folder") local SpaceButton = Instance.new("TextButton") local mLabel = Instance.new("TextLabel") local pLabel = Instance.new("TextLabel") --Properties: ClassicChat.Name = "ClassicChat" ClassicChat.Parent = game.CoreGui ChatFrame.Name = "ChatFrame" ChatFrame.Parent = ClassicChat ChatFrame.BackgroundColor3 = Color3.new(0.698039, 0.698039, 0.698039) ChatFrame.BackgroundTransparency = 1 ChatFrame.BorderColor3 = Color3.new(0, 0, 0) ChatFrame.BorderSizePixel = 0 ChatFrame.Position = UDim2.new(0, 5, 0, 10) ChatFrame.Size = UDim2.new(0, 500, 0, 120) ChatFrame.ZIndex = 9 ChatRenderFrame.Name = "ChatRenderFrame" ChatRenderFrame.Parent = ChatFrame ChatRenderFrame.BackgroundColor3 = Color3.new(0.698039, 0.698039, 0.698039) ChatRenderFrame.BackgroundTransparency = 1 ChatRenderFrame.BorderColor3 = Color3.new(0, 0, 0) ChatRenderFrame.BorderSizePixel = 0 ChatRenderFrame.Size = UDim2.new(1.01999998, 0, 1.00999999, 0) ChatRenderFrame.ZIndex = 9 ClickToChat.Name = "ClickToChat" ClickToChat.Parent = ClassicChat ClickToChat.BackgroundColor3 = Color3.new(1, 1, 1) ClickToChat.BackgroundTransparency = 1 ClickToChat.BorderColor3 = Color3.new(0, 0, 0) ClickToChat.BorderSizePixel = 0 ClickToChat.Position = UDim2.new(0, 0, 1, -20) ClickToChat.Size = UDim2.new(1, 0, 0, 20) ClickToChat.ZIndex = 9 ClickToChat.AutoButtonColor = false ClickToChat.Text = "" ClickToChat.TextColor3 = Color3.new(1, 1, 1) ClickToChat.TextSize = 12 ClickToChat.TextXAlignment = Enum.TextXAlignment.Left ChatBar.Name = "ChatBar" ChatBar.Parent = ClassicChat ChatBar.BackgroundColor3 = Color3.new(0, 0, 0) ChatBar.BorderColor3 = Color3.new(0, 0, 0) ChatBar.BorderSizePixel = 0 ChatBar.Position = UDim2.new(0, 0, 1, -20) ChatBar.Size = UDim2.new(1, 0, 0, 20) ChatBar.ZIndex = 8 ChatBar.ClearTextOnFocus = false ChatBar.PlaceholderText = "To chat click here or press the \"/\" key" ChatBar.Text = "" ChatBar.TextColor3 = Color3.new(1, 1, 1) ChatBar.TextSize = 12 ChatBar.TextXAlignment = Enum.TextXAlignment.Left Templates.Name = "Templates" Templates.Parent = ClassicChat SpaceButton.Name = "SpaceButton" SpaceButton.Parent = Templates SpaceButton.BackgroundColor3 = Color3.new(0, 0, 0) SpaceButton.BackgroundTransparency = 1 SpaceButton.Size = UDim2.new(0, 510, 0, 12) SpaceButton.AutoButtonColor = false SpaceButton.Text = "" SpaceButton.TextSize = 12 mLabel.Name = "mLabel" mLabel.Parent = Templates mLabel.BackgroundColor3 = Color3.new(0.698039, 0.698039, 0.698039) mLabel.BackgroundTransparency = 1 mLabel.BorderSizePixel = 0 mLabel.Position = UDim2.new(0, 0, 1, 0) mLabel.Size = UDim2.new(1, 0, 0.5, 0) mLabel.Text = "" mLabel.TextSize = 12 mLabel.TextWrapped = true mLabel.TextXAlignment = Enum.TextXAlignment.Left mLabel.TextYAlignment = Enum.TextYAlignment.Top pLabel.Name = "pLabel" pLabel.Parent = Templates pLabel.BackgroundColor3 = Color3.new(0.698039, 0.698039, 0.698039) pLabel.BackgroundTransparency = 1 pLabel.BorderSizePixel = 0 pLabel.Position = UDim2.new(0, 0, 1, 0) pLabel.Size = UDim2.new(1, 0, 0.100000001, 0) pLabel.ZIndex = 2 pLabel.Text = "Player: " pLabel.TextSize = 12 pLabel.TextStrokeColor3 = Color3.new(0.501961, 0.501961, 0.501961) pLabel.TextXAlignment = Enum.TextXAlignment.Left pLabel.TextYAlignment = Enum.TextYAlignment.Top -- Scripts: local function DNBDUT_fake_script() -- ClassicChat.ChatScript local script = Instance.new('LocalScript', ClassicChat) --Script modified by EkoGam3. --Concept credit goes to Vermis. local year = 2007 game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Chat, false) --Code if year == 2007 then script.Parent.ClickToChat.TextColor3 = Color3.new(1, 1, 1) script.Parent.ChatBar.BackgroundColor3 = Color3.new(0, 0, 0) end local Chat = { ChatColors = { BrickColor.new("Bright red"), BrickColor.new("Bright blue"), BrickColor.new("Earth green"), BrickColor.new("Bright violet"), BrickColor.new("Bright orange"), BrickColor.new("Bright yellow"), BrickColor.new("Light reddish violet"), BrickColor.new("Brick yellow"), }; Gui = nil, Frame = nil, RenderFrame = nil, TapToChatLabel = nil, ClickToChatButton = nil, Templates = nil, EventListener = nil, MessageQueue = {}, Configuration = { FontSize = Enum.FontSize.Size12, NumFontSize = 12, HistoryLength = 20, Size = UDim2.new(0.38, 0, 0.20, 0), MessageColor = Color3.new(1, 1, 1), AdminMessageColor = Color3.new(1, 215/255, 0), XScale = 0.025, LifeTime = 45, Position = UDim2.new(0, 2, 0.05, 0), DefaultTweenSpeed = 0.15, }; CachedSpaceStrings_List = {}, Messages_List = {}, MessageThread = nil, TempSpaceLabel = nil, } function GetNameValue(pName) local value = 0 for index = 1, #pName do local cValue = string.byte(string.sub(pName, index, index)) local reverseIndex = #pName - index + 1 if #pName%2 == 1 then reverseIndex = reverseIndex - 1 end if reverseIndex%4 >= 2 then cValue = -cValue end value = value + cValue end return value%8 end function Chat:ComputeChatColor(pName) return self.ChatColors[GetNameValue(pName) + 1].Color end function Chat:UpdateQueue(field, diff) for i = #self.MessageQueue, 1, -1 do if self.MessageQueue[i] then for _, label in pairs(self.MessageQueue[i]) do if label and type(label) ~= "table" and type(label) ~= "number" then if label:IsA("TextLabel") or label:IsA("TextButton") then if diff then label.Position = label.Position - UDim2.new(0, 0, diff, 0) else if field == self.MessageQueue[i] then label.Position = UDim2.new(self.Configuration.XScale, 0, label.Position.Y.Scale - field["Message"].Size.Y.Scale , 0) else label.Position = UDim2.new(self.Configuration.XScale, 0, label.Position.Y.Scale - field["Message"].Size.Y.Scale, 0) end if label.Position.Y.Scale < -0.01 then label.Visible = false label:Destroy() end end end end end end end end function Chat:ComputeSpaceString(pLabel) local nString = " " if not self.TempSpaceLabel then self.TempSpaceLabel = self.Templates.SpaceButton self.TempSpaceLabel.Size = UDim2.new(0, pLabel.AbsoluteSize.X, 0, pLabel.AbsoluteSize.Y); end self.TempSpaceLabel.Text = nString while self.TempSpaceLabel.TextBounds.X < pLabel.TextBounds.X do nString = nString .. " " self.TempSpaceLabel.Text = nString end nString = nString .. " " self.CachedSpaceStrings_List[pLabel.Text] = nString self.TempSpaceLabel.Text = "" return nString end function Chat:UpdateChat(cPlayer, message) local messageField = {["Player"] = cPlayer,["Message"] = message} if coroutine.status(Chat.MessageThread) == "dead" then table.insert(Chat.Messages_List, messageField) Chat.MessageThread = coroutine.create(function () for i = 1, #Chat.Messages_List do local field = Chat.Messages_List[i] Chat:CreateMessage(field["Player"], field["Message"]) end Chat.Messages_List = {} end) coroutine.resume(Chat.MessageThread) else table.insert(Chat.Messages_List, messageField) end end function Chat:CreateMessage(cPlayer, message) local pName = cPlayer ~= nil and cPlayer.Name or "GAME" message = message:gsub("^%s*(.-)%s*$", "%1") self.MessageQueue[#self.MessageQueue] = (#self.MessageQueue > self.Configuration.HistoryLength) and nil or self.MessageQueue[#self.MessageQueue] local pLabel = self.Templates.pLabel:clone() pLabel.Name = pName; pLabel.Text = pName .. ";"; pLabel.Parent = self.RenderFrame; pLabel.TextColor3 = (cPlayer.Neutral) and Chat:ComputeChatColor(pName) or cPlayer.TeamColor.Color local nString = self.CachedSpaceStrings_List[pName] or Chat:ComputeSpaceString(pLabel) local mLabel = self.Templates.mLabel:clone() mLabel.Name = pName .. " - message"; mLabel.TextColor3 = Chat.Configuration.MessageColor; mLabel.Text = nString .. message; mLabel.Parent = self.RenderFrame; local heightField = mLabel.TextBounds.Y mLabel.Size = UDim2.new(1, 0, heightField/self.RenderFrame.AbsoluteSize.Y, 0) pLabel.Size = mLabel.Size local yPixels = self.RenderFrame.AbsoluteSize.Y local yFieldSize = mLabel.TextBounds.Y local queueField = {} queueField["Player"] = pLabel queueField["Message"] = mLabel queueField["SpawnTime"] = tick() table.insert(self.MessageQueue, 1, queueField) Chat:UpdateQueue(queueField) end function Chat:CreateChatBar() self.ClickToChatButton = self.Gui:WaitForChild("ClickToChat") self.ChatBar = self.Gui:WaitForChild("ChatBar") local mouse = game.Players.LocalPlayer:GetMouse() mouse.KeyDown:connect(function (key) if key:byte() == 47 or key == "/" then self.ClickToChatButton.Visible = false if year > 2007 then self.ChatBar.BackgroundColor3 = Color3.new(0, 0, 0) end self.ChatBar:CaptureFocus() end end) self.ClickToChatButton.MouseButton1Click:connect(function () self.ClickToChatButton.Visible = false if year > 2007 then self.ChatBar.BackgroundColor3 = Color3.new(0, 0, 0) end self.ChatBar:CaptureFocus() end) end function Chat:PlayerChat(message) local m = Instance.new("StringValue") m.Name = "NewMessage" m.Value = message m.Parent = game.Players.LocalPlayer game:GetService("Debris"):AddItem(m, 2) end function Chat:CreateGui() self.Gui = script.Parent self.Frame = self.Gui:WaitForChild("ChatFrame") self.RenderFrame = self.Frame:WaitForChild("ChatRenderFrame") self.Templates = self.Gui:WaitForChild("Templates") Chat:CreateChatBar() self.ChatBar.FocusLost:connect(function(enterPressed) if enterPressed then local txt = self.ChatBar.Text Chat:CreateMessage(game.Players.LocalPlayer,txt) game.ReplicatedStorage.DefaultChatSystemChatEvents.SayMessageRequest:FireServer(txt ,"All") self.ChatBar.Text = '' end end) end function Chat:TrackPlayerChats() local function chatRegister(p) p.ChildAdded:connect(function (obj) if obj:IsA("StringValue") and obj.Name == "NewMessage" then if game.Players.LocalPlayer.Neutral or p.TeamColor == game.Players.LocalPlayer.TeamColor then Chat:UpdateChat(p, obj.Value) end end end) end for _,v in pairs(game.Players:GetPlayers()) do chatRegister(v) end game.Players.PlayerAdded:connect(chatRegister) end function Chat:CullThread() Spawn(function () while true do if #self.MessageQueue > 0 then for _, field in pairs(self.MessageQueue) do if field["SpawnTime"] and field["Player"] and field["Message"] and tick() - field["SpawnTime"] > self.Configuration.LifeTime then field["Player"].Visible = false field["Message"].Visible = false end end end wait(5) end end) end function Chat:Initialize() Chat:CreateGui() Chat:TrackPlayerChats() self.MessageThread = coroutine.create(function () end) coroutine.resume(self.MessageThread) Chat:CullThread() end Chat:Initialize() local plrs = game.Players local detect = function(p) p.Chatted:Connect(function(msg) Chat:CreateMessage(p,msg) end) end plrs.PlayerAdded:Connect(function(p) detect(p) end) for i,p in pairs(plrs:GetPlayers()) do detect(p) end end coroutine.wrap(DNBDUT_fake_script)() local function EWRBJ_fake_script() -- ChatBar.f local script = Instance.new('LocalScript', ChatBar) while wait() do if script.Parent.Text:sub(1,1) == '/' then script.Parent.Text = script.Parent.Text:sub(2,#script.Parent.Text) end end end coroutine.wrap(EWRBJ_fake_script)() local function YXIJ_fake_script() -- ChatBar.autocolor local script = Instance.new('LocalScript', ChatBar) while wait() do script.Parent.BackgroundColor3 = Color3.fromRGB(0, 0, 0) end end coroutine.wrap(YXIJ_fake_script)() -- dev console: local s, e = loadstring(game:HttpGet("https://pastebin.com/raw/uQ4wzMdR", true)) if typeof(s) ~= "function" then return end local success, message = pcall(s) if (not success) then if printconsole then printconsole(message) elseif printoutput then printoutput(message) end end -- // gotta be the safest we can be (for games like rogue lineage and strucid that ban on error ugh) local _, str = pcall(function() return game:HttpGet("https://pastebin.com/raw/i35eCznS", true) end) local s, e = loadstring(str) if typeof(s) ~= "function" then return end local success, message = pcall(s) if (not success) then if printconsole then printconsole(message) elseif printoutput then printoutput(message) end end --[[ This script controls the gui the player sees in regards to his or her health. Can be turned with Game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Health,false) Copyright ROBLOX 2014. Written by Ben Tkacheff. --]] --------------------------------------------------------------------- -- Initialize/Variables while not game do wait(1/60) end while not game:GetService("Players") do wait(1/60) end local currentHumanoid = nil local HealthGui = nil local lastHealth = 100 local HealthPercentageForOverlay = 5 local maxBarTweenTime = 0.3 local greenColor = Color3.new(0.2, 1, 0.2) local redColor = Color3.new(1, 0.2, 0.2) local yellowColor = Color3.new(1, 1, 0.2) local guiEnabled = false local healthChangedConnection = nil local humanoidDiedConnection = nil local characterAddedConnection = nil local greenBarImage = "rbxasset://textures/ui/Health-BKG-Center.png" local greenBarImageLeft = "rbxasset://textures/ui/Health-BKG-Left-Cap.png" local greenBarImageRight = "rbxasset://textures/ui/Health-BKG-Right-Cap.png" local hurtOverlayImage = "https://www.roblox.com/asset/?id=34854607" game:GetService("ContentProvider"):Preload(greenBarImage) game:GetService("ContentProvider"):Preload(hurtOverlayImage) while not game:GetService("Players").LocalPlayer do wait(1/60) end --------------------------------------------------------------------- -- Functions local capHeight = 15 local capWidth = 7 function CreateGui() if HealthGui and #HealthGui:GetChildren() > 0 then HealthGui.Parent = game:GetService("CoreGui").RobloxGui return end local hurtOverlay = Instance.new("ImageLabel") hurtOverlay.Name = "HurtOverlay" hurtOverlay.BackgroundTransparency = 1 hurtOverlay.Image = hurtOverlayImage hurtOverlay.Position = UDim2.new(-10,0,-10,0) hurtOverlay.Size = UDim2.new(20,0,20,0) hurtOverlay.Visible = false hurtOverlay.Parent = HealthGui local healthFrame = Instance.new("Frame") healthFrame.Name = "HealthFrame" healthFrame.BackgroundTransparency = 1 healthFrame.BackgroundColor3 = Color3.new(1,1,1) healthFrame.BorderColor3 = Color3.new(0,0,0) healthFrame.BorderSizePixel = 0 healthFrame.Position = UDim2.new(0.5,-85,1, -90) healthFrame.Size = UDim2.new(0,170,0,capHeight) healthFrame.Parent = HealthGui local healthBarBackCenter = Instance.new("ImageLabel") healthBarBackCenter.Name = "healthBarBackCenter" healthBarBackCenter.BackgroundTransparency = 1 healthBarBackCenter.Image = greenBarImage healthBarBackCenter.Size = UDim2.new(1,-capWidth*2,1,0) healthBarBackCenter.Position = UDim2.new(0,capWidth,0,0) healthBarBackCenter.Parent = healthFrame healthBarBackCenter.ImageColor3 = Color3.new(1,1,1) local healthBarBackLeft = Instance.new("ImageLabel") healthBarBackLeft.Name = "healthBarBackLeft" healthBarBackLeft.BackgroundTransparency = 1 healthBarBackLeft.Image = greenBarImageLeft healthBarBackLeft.Size = UDim2.new(0,capWidth,1,0) healthBarBackLeft.Position = UDim2.new(0,0,0,0) healthBarBackLeft.Parent = healthFrame healthBarBackLeft.ImageColor3 = Color3.new(1,1,1) local healthBarBackRight = Instance.new("ImageLabel") healthBarBackRight.Name = "healthBarBackRight" healthBarBackRight.BackgroundTransparency = 1 healthBarBackRight.Image = greenBarImageRight healthBarBackRight.Size = UDim2.new(0,capWidth,1,0) healthBarBackRight.Position = UDim2.new(1,-capWidth,0,0) healthBarBackRight.Parent = healthFrame healthBarBackRight.ImageColor3 = Color3.new(1,1,1) local healthBar = Instance.new("Frame") healthBar.Name = "HealthBar" healthBar.BackgroundTransparency = 1 healthBar.BackgroundColor3 = Color3.new(1,1,1) healthBar.BorderColor3 = Color3.new(0,0,0) healthBar.BorderSizePixel = 0 healthBar.ClipsDescendants = true healthBar.Position = UDim2.new(0, 0, 0, 0) healthBar.Size = UDim2.new(1,0,1,0) healthBar.Parent = healthFrame local healthBarCenter = Instance.new("ImageLabel") healthBarCenter.Name = "healthBarCenter" healthBarCenter.BackgroundTransparency = 1 healthBarCenter.Image = greenBarImage healthBarCenter.Size = UDim2.new(1,-capWidth*2,1,0) healthBarCenter.Position = UDim2.new(0,capWidth,0,0) healthBarCenter.Parent = healthBar healthBarCenter.ImageColor3 = greenColor local healthBarLeft = Instance.new("ImageLabel") healthBarLeft.Name = "healthBarLeft" healthBarLeft.BackgroundTransparency = 1 healthBarLeft.Image = greenBarImageLeft healthBarLeft.Size = UDim2.new(0,capWidth,1,0) healthBarLeft.Position = UDim2.new(0,0,0,0) healthBarLeft.Parent = healthBar healthBarLeft.ImageColor3 = greenColor local healthBarRight = Instance.new("ImageLabel") healthBarRight.Name = "healthBarRight" healthBarRight.BackgroundTransparency = 1 healthBarRight.Image = greenBarImageRight healthBarRight.Size = UDim2.new(0,capWidth,1,0) healthBarRight.Position = UDim2.new(1,-capWidth,0,0) healthBarRight.Parent = healthBar healthBarRight.ImageColor3 = greenColor HealthGui.Parent = game:GetService("CoreGui").RobloxGui end function UpdateGui(health) if not HealthGui then return end local healthFrame = HealthGui:FindFirstChild("HealthFrame") if not healthFrame then return end local healthBar = healthFrame:FindFirstChild("HealthBar") if not healthBar then return end -- If more than 1/4 health, bar = green. Else, bar = red. local percentHealth = (health/currentHumanoid.MaxHealth) if percentHealth ~= percentHealth then percentHealth = 1 healthBar.healthBarCenter.ImageColor3 = yellowColor healthBar.healthBarRight.ImageColor3 = yellowColor healthBar.healthBarLeft.ImageColor3 = yellowColor elseif percentHealth > 0.25 then healthBar.healthBarCenter.ImageColor3 = greenColor healthBar.healthBarRight.ImageColor3 = greenColor healthBar.healthBarLeft.ImageColor3 = greenColor else healthBar.healthBarCenter.ImageColor3 = redColor healthBar.healthBarRight.ImageColor3 = redColor healthBar.healthBarLeft.ImageColor3 = redColor end local width = (health / currentHumanoid.MaxHealth) width = math.max(math.min(width,1),0) -- make sure width is between 0 and 1 if width ~= width then width = 1 end local healthDelta = lastHealth - health lastHealth = health local percentOfTotalHealth = math.abs(healthDelta/currentHumanoid.MaxHealth) percentOfTotalHealth = math.max(math.min(percentOfTotalHealth,1),0) -- make sure percentOfTotalHealth is between 0 and 1 if percentOfTotalHealth ~= percentOfTotalHealth then percentOfTotalHealth = 1 end local newHealthSize = UDim2.new(width,0,1,0) healthBar.Size = newHealthSize local sizeX = healthBar.AbsoluteSize.X if sizeX < capWidth then healthBar.healthBarCenter.Visible = false healthBar.healthBarRight.Visible = false elseif sizeX < (2*capWidth + 1) then healthBar.healthBarCenter.Visible = true healthBar.healthBarCenter.Size = UDim2.new(0,sizeX - capWidth,1,0) healthBar.healthBarRight.Visible = false else healthBar.healthBarCenter.Visible = true healthBar.healthBarCenter.Size = UDim2.new(1,-capWidth*2,1,0) healthBar.healthBarRight.Visible = true end local thresholdForHurtOverlay = currentHumanoid.MaxHealth * (HealthPercentageForOverlay/100) if healthDelta >= thresholdForHurtOverlay and guiEnabled then AnimateHurtOverlay() end end function AnimateHurtOverlay() if not HealthGui then return end local overlay = HealthGui:FindFirstChild("HurtOverlay") if not overlay then return end local newSize = UDim2.new(20, 0, 20, 0) local newPos = UDim2.new(-10, 0, -10, 0) if overlay:IsDescendantOf(game) then -- stop any tweens on overlay overlay:TweenSizeAndPosition(newSize,newPos,Enum.EasingDirection.Out,Enum.EasingStyle.Linear,0,true,function() -- show the gui overlay.Size = UDim2.new(1,0,1,0) overlay.Position = UDim2.new(0,0,0,0) overlay.Visible = true -- now tween the hide if overlay:IsDescendantOf(game) then overlay:TweenSizeAndPosition(newSize,newPos,Enum.EasingDirection.Out,Enum.EasingStyle.Quad,10,false,function() overlay.Visible = false end) else overlay.Size = newSize overlay.Position = newPos end end) else overlay.Size = newSize overlay.Position = newPos end end function humanoidDied() UpdateGui(0) end function disconnectPlayerConnections() if characterAddedConnection then characterAddedConnection:disconnect() end if humanoidDiedConnection then humanoidDiedConnection:disconnect() end if healthChangedConnection then healthChangedConnection:disconnect() end end function newPlayerCharacter() disconnectPlayerConnections() startGui() end function startGui() characterAddedConnection = game:GetService("Players").LocalPlayer.CharacterAdded:connect(newPlayerCharacter) local character = game:GetService("Players").LocalPlayer.Character if not character then return end currentHumanoid = character:WaitForChild("Humanoid") if not currentHumanoid then return end if not game:GetService("StarterGui"):GetCoreGuiEnabled(Enum.CoreGuiType.Health) then return end healthChangedConnection = currentHumanoid.HealthChanged:connect(UpdateGui) humanoidDiedConnection = currentHumanoid.Died:connect(humanoidDied) UpdateGui(currentHumanoid.Health) CreateGui() end --------------------------------------------------------------------- -- Start Script HealthGui = Instance.new("Frame") HealthGui.Name = "HealthGui" HealthGui.BackgroundTransparency = 1 HealthGui.Size = UDim2.new(1,0,1,0) game:GetService("StarterGui").CoreGuiChangedSignal:connect(function(coreGuiType,enabled) if coreGuiType == Enum.CoreGuiType.Health or coreGuiType == Enum.CoreGuiType.All then if guiEnabled and not enabled then if HealthGui then HealthGui.Parent = nil end disconnectPlayerConnections() elseif not guiEnabled and enabled then startGui() end guiEnabled = enabled end end) if game:GetService("StarterGui"):GetCoreGuiEnabled(Enum.CoreGuiType.Health) then guiEnabled = true startGui() end