2013/yue/48488235.yue

3007 lines
81 KiB
Plaintext

import "macros" as { $ }
$load $FILE
--new playerlist by Zach Lindblad (fusroblox)
--contact him for any revisions/issues
--------------------
-- Super Util
--------------------
--[[ ADMINS =
aceswayuphigh: 1
adamintygum: 1
afackler11: 1
aleverns: 1
aquabot8: 1
arbolito: 1
argforpirates: 1
argonpirate: 1
asmohdian: 1
bellavour: 1
blockhaak: 1
brighteyes: 1
briguy9876: 1
builderman: 1
cdakkar: 1
chiefjustus: 1
chro: 1
cmed: 1
coatp0cketninja: 1
codewriter: 1
commandercrow: 1
corgiparade: 1
dapperbuffalo: 1
dbapostle: 1
deeana00: 1
doughtless: 1
dunbar1138: 1
echodown: 1
ffjosh: 1
foyle: 1
gemlocker: 1
goddessnoob: 1
gongfutiger: 1
gordonrox24: 1
gorroth: 1
grossinger: 1
groundcontroll2: 1
hawkeyebandit: 1
hawkington: 1
ibanez2189: 1
iltalumi: 1
inventx: 1
jackssmirkingrevenge: 1
jeditkacheff: 'http://www.roblox.com/asset/?id=134032333'
kbux: 1
keith: 1
limon: 1
loopylens: 1
lordrugdumph: 1
majortom4321: 1
malcomso: 1
maxvee: 1
midwinterfires: 1
mistersquirrel: 1
morganic: 1
motornerve: 1
mrdoombringer: 1
mse6: 1
newtrat: 1
niquemonster: 1
nobledragon: 1
noob007: 1
nrawat1: 1
olive71: 1
onlytwentycharacters: 1
orcasparkles: 1
ostrichsized: 1
phaedre: 1
phil: 1
pulmoesflor: 1
raeglyn: 1
rbadam: 1
reesemcblox: 1
robliu: 1
roblowilson: 1
robloxsai: 1
roboyz: 1
saurauss: 1
screenme: 1
scubasomething: 1
seanthornton: 1
shedletsky: 'http://www.roblox.com/asset/?id=105897927'
sickenedmonkey: 1
slingshotjunkie: 1
smeaferblox: 1
soggoth: 1
solarcrane: 1
sooraya: 1
sorcus: 'http://www.roblox.com/asset/?id=113059239'
squidcod: 1
stickmasterluke: 1
stuball: 1
tabemono: 1
tarabyte: 1
thelorekt: 1
thorasaur: 1
timobius: 1
tobotrobot: 1
tone: 1
totallynothere: 1
totbl: 1
twberg: 1
vaiobot: 1
varia: 1
vladthefirst: 1
wonderboy76: 1
xerolayne: 1
yesth: 1
yumyumcheerios: 1
zeuxcg: 1
zodiaczak: 1
['erik.cassel']: 1
['david.baszucki']: 1
['matt dusek']: 1
} --]]
ADMINS =
taskmanager: 1
Heliodex: 1
multako: "http://www.roblox.com/asset/?id=6923328292"
mercury: 1
pizzaboxer: "http://www.roblox.com/asset/?id=6917566633"
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"
BASE_TWEEN = 0.25
MOUSE_DRAG_DISTANCE = 15
-- Heliodex's basic New function (basically a simplified version of melt)
New = (className, name, props) ->
if not props? -- no name was provided
props = name
name = nil
obj = Instance.new className
obj.Name = name if name
local parent
for k, v in pairs props
if type(k) == "string"
if k == "Parent"
parent = v
else
obj[k] = v
elseif type(k) == "number" and type(v) == "userdata"
v.Parent = obj
obj.Parent = parent
obj
--
--[[
makes a full sized background for a guiobject
@Args:
imgName asset name of image to fill background
@Return: background gui object
--]]
MakeBackgroundGuiObj = (imgName) ->
New "ImageLabel", "Background"
BackgroundTransparency: 1
Image: imgName
Position: UDim2.new 0, 0, 0, 0
Size: UDim2.new 1, 0, 1, 0
--[[ turns 255 integer color value to a color3 --]]
Color3I = (r, g, b) -> Color3.new r / 255, g / 255, b / 255
--[[
Gets correct icon for builder's club status to display by name
@Args:
membershipType Enum of membership status
@Return: string of image asset
--]]
getMembershipTypeIcon = (membershipType, playerName) ->
if ADMINS[string.lower playerName]?
if ADMINS[string.lower playerName] == 1
"http://www.roblox.com/asset/?id=6923330951"
else
ADMINS[string.lower playerName]
elseif membershipType == Enum.MembershipType.None
""
elseif membershipType == Enum.MembershipType.BuildersClub
"rbxasset://textures/ui/TinyBcIcon.png"
elseif membershipType == Enum.MembershipType.TurboBuildersClub
"rbxasset://textures/ui/TinyTbcIcon.png"
elseif membershipType == Enum.MembershipType.OutrageousBuildersClub
"rbxasset://textures/ui/TinyObcIcon.png"
else
error "Unknown membershipType #{membershipType}"
getFriendStatusIcon = (friendStatus) ->
if friendStatus == Enum.FriendStatus.Unknown or friendStatus == Enum.FriendStatus.NotFriend
""
elseif friendStatus == Enum.FriendStatus.Friend
"http://www.roblox.com/asset/?id=99749771"
elseif friendStatus == Enum.FriendStatus.FriendRequestSent
"http://www.roblox.com/asset/?id=99776888"
elseif friendStatus == Enum.FriendStatus.FriendRequestReceived
"http://www.roblox.com/asset/?id=99776838"
else
error "Unknown FriendStatus: #{friendStatus}"
--[[
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
--]]
MakePopupButton = (nparent, ntext, index, last) ->
tobj = New "ImageButton", "ReportButton",
BackgroundTransparency: 1
Position: UDim2.new 0, 0, 1 * index, 0
Size: UDim2.new 1, 0, 1, 0
ZIndex: 7
Parent: nparent
* New "TextLabel", "ButtonText",
BackgroundTransparency: 1
Position: UDim2.new 0.07, 0, 0.07, 0
Size: UDim2.new 0.86, 0, 0.86, 0
Font: "ArialBold"
Text: ntext
FontSize: "Size14"
TextScaled: true
TextColor3: Color3.new 1, 1, 1
TextStrokeTransparency: 1
ZIndex: 7
tobj.Image = "http://www.roblox.com/asset/?id=" .. if index == 0
"97108784"
elseif last
if index % 2 == 1
Images["LightPopupBottom"]
else
Images["DarkPopupBottom"]
else
if index % 2 == 1
"97112126"
else
"97109338"
tobj
--[[
simple function to toggle the display of debug output
--]]
local debugOutput
DebugPrintEnabled = true
debugprint = (str) ->
--print(str)
if DebugPrintEnabled
debugOutput.Text = str
--[[
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
--]]
WaitForChild = (parent, child) ->
while not parent\FindFirstChild child
wait!
debugprint " child #{parent.Name} waiting for #{child}"
parent[child]
---------------------------
-- Workspace Objects
---------------------------
-- might want to move all this to an init function, wait for localplayer elsewhere
Players = game\GetService "Players"
-- make sure this doesn't run on the server(it will if you dont do this)
while not Players.LocalPlayer
Players.Changed\wait!
LocalPlayer = Players.LocalPlayer
Mouse = LocalPlayer\GetMouse!
ScreenGui = New "Frame", "PlayerListScreen"
Size: UDim2.new 1, 0, 1, 0
BackgroundTransparency: 1
Parent: script.Parent
MainFrame = New "Frame", "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'
FocusFrame = New "Frame", "FocusFrame"
Position: UDim2.new 0, 0, 0, 0
Size: UDim2.new 1, 0, 0, 100
BackgroundTransparency: 1
Active: true
Parent: MainFrame
-- HEADER
HeaderFrame = New "Frame", "Header"
BackgroundTransparency: 1
Position: UDim2.new 0, 0, 0, 0
Size: UDim2.new 1, 0, 0.07, 0
Parent: MainFrame
* MakeBackgroundGuiObj "http://www.roblox.com/asset/?id=94692054"
HeaderFrameHeight = HeaderFrame.Size.Y.Scale
MaximizeButton = New "ImageButton", "MaximizeButton"
Active: true
BackgroundTransparency: 1
Position: UDim2.new 0, 0, 0, 0
Size: UDim2.new 1, 0, 1, 0
Parent: HeaderFrame
HeaderName = New "TextLabel", "PlayerName"
BackgroundTransparency: 1
Position: UDim2.new 0, 0, 0.01, 0
Size: UDim2.new 0.98, 0, 0.38, 0
Parent: HeaderFrame
Font: "ArialBold"
Text: LocalPlayer.Name
FontSize: "Size24"
--TextScaled: true
TextColor3: Color3.new 1, 1, 1
TextStrokeColor3: Color3.new 0, 0, 0
TextStrokeTransparency: 0
TextXAlignment: "Right"
TextYAlignment: "Center"
HeaderScore = New "TextLabel", "PlayerScore"
BackgroundTransparency: 1
Position: UDim2.new 0, 0, 0.4, 0
Size: UDim2.new 0.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"
-- BOTTOM
--used for shifting bottom frame for mouse over effects
BottomShiftFrame = New "Frame", "BottomShiftFrame"
BackgroundTransparency: 1
Position: UDim2.new 0, 0, HeaderFrameHeight, 0
Size: UDim2.new 1, 0, 1, 0
Parent: MainFrame
BottomFrame = New "Frame", "Bottom"
BackgroundTransparency: 1
Position: UDim2.new 0, 0, 0.07, 0
Size: UDim2.new 1, 0, 0.03, 0
Parent: BottomShiftFrame
* MakeBackgroundGuiObj "http://www.roblox.com/asset/?id=94754966"
ExtendButton = New "ImageButton", "bigbutton"
Active: true
BackgroundTransparency: 1
Position: UDim2.new 0, 0, 0, 0
Size: UDim2.new 1, 0, 1.5, 0
ZIndex: 3
Parent: BottomFrame
ExtendTab = New "ImageButton", "extendTab"
Active: true
BackgroundTransparency: 1
Image: "http://www.roblox.com/asset/?id=94692731"
Position: UDim2.new 0.608, 0, 0.3, 0
Size: UDim2.new 0.3, 0, 0.7, 0
Parent: BottomFrame
TopClipFrame = New "Frame", "ListFrame"
BackgroundTransparency: 1
Position: UDim2.new -1, 0, 0.07, 0
Size: UDim2.new 2, 0, 1, 0
Parent: MainFrame
ClipsDescendants: true
BottomClipFrame = New "Frame", "BottomFrame"
BackgroundTransparency: 1
Position: UDim2.new 0, 0, -0.8, 0
Size: UDim2.new 1, 0, 1, 0
Parent: TopClipFrame
ClipsDescendants: true
ScrollBarFrame = New "Frame", "ScrollBarFrame"
BackgroundTransparency: 1
Position: UDim2.new 0.987, 0, 0.8, 0
Size: UDim2.new 0.01, 0, 0.2, 0
Parent: BottomClipFrame
ScrollBar = New "Frame", "ScrollBar"
BackgroundTransparency: 0
BackgroundColor3: Color3.new 0.2, 0.2, 0.2
Position: UDim2.new 0, 0, 0, 0
Size: UDim2.new 1, 0, 0.5, 0
ZIndex: 5
Parent: ScrollBarFrame
ListFrame = New "Frame", "SubFrame"
BackgroundTransparency: 1
Position: UDim2.new 0, 0, 0.8, 0
Size: UDim2.new 1, 0, 1, 0
Parent: BottomClipFrame
PopUpClipFrame = New "Frame", "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
PopUpPanel = nil
PopUpPanelTemplate = New "Frame", "Panel"
BackgroundTransparency: 1
Position: UDim2.new 1, 0, 0, 0
Size: UDim2.new 1, 0, 0.032, 0
Parent: PopUpClipFrame
StatTitles = New "Frame", "StatTitles",
BackgroundTransparency: 1,
Position: UDim2.new 0, 0, 1, -10,
Size: UDim2.new 1, 0, 0, 0,
Parent: HeaderFrame,
IsMinimized = Instance.new "BoolValue"
IsMaximized = Instance.new "BoolValue"
IsTabified = Instance.new "BoolValue"
AreNamesExpanded = Instance.new "BoolValue"
MiddleTemplate = New "Frame"
Name: "MidTemplate"
BackgroundTransparency: 1
Position: UDim2.new 100, 0, 0.07, 0
Size: UDim2.new 0.5, 0, 0.025, 0 --UDim2.new 1, 0, .03, 0
* New "ImageLabel"
Name: "BCLabel"
Active: true
BackgroundTransparency: 1
Position: UDim2.new 0.005, 5, 0.20, 0
Size: UDim2.new 0, 16, 0, 16
SizeConstraint: "RelativeYY"
Image: ""
ZIndex: 3
* New "ImageLabel"
Name: "FriendLabel"
Active: true
BackgroundTransparency: 1
Position: UDim2.new 0.005, 5, 0.15, 0
Size: UDim2.new 0, 16, 0, 16
SizeConstraint: "RelativeYY"
Image: ""
ZIndex: 3
* New "ImageButton", "ClickListener"
Active: true
BackgroundTransparency: 1
Position: UDim2.new 0.005, 1, 0, 0
Size: UDim2.new 0.96, 0, 1, 0
ZIndex: 3
* New "Frame", "TitleFrame"
BackgroundTransparency: 1
Position: UDim2.new 0.01, 0, 0, 0
Size: UDim2.new 0, 140, 1, 0
ClipsDescendants: true
* New "TextLabel", "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
* New "TextLabel", "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
--New'IntValue'{Name = 'ID'},
--New'ObjectValue'{Name = 'Player'},
--New'IntValue'{Name = 'Score'},
ZIndex: 3,
MiddleBGTemplate = New "Frame", "MidBGTemplate"
BackgroundTransparency: 1
Position: UDim2.new 100, 0, 0.07, 0
Size: UDim2.new 0.5, 0, 0.025, 0 --UDim2.new 1, 0, .03, 0
* MakeBackgroundGuiObj "http://www.roblox.com/asset/?id=94692025"
-- REPORT ABUSE OBJECTS
ReportAbuseShield = New "TextButton", "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
ReportAbuseFrame = New "Frame", "Settings"
Position: UDim2.new 0.5, -250, 0.5, -200
Size: UDim2.new 0, 500, 0, 400
BackgroundTransparency: 1
Active: true
Parent: ReportAbuseShield
local AbuseSettingsFrame
AbuseSettingsFrame = New "Frame", "ReportAbuseStyle"
Size: UDim2.new 1, 0, 1, 0
Active: true
BackgroundTransparency: 1
Parent: ReportAbuseFrame
* MakeBackgroundGuiObj "http://www.roblox.com/asset/?id=96488767" -- 96480351"
* New "TextLabel", "Title"
Text: "Report Abuse"
TextColor3: Color3I 221, 221, 221
Position: UDim2.new 0.5, 0, 0, 30
Font: Enum.Font.ArialBold
FontSize: Enum.FontSize.Size36
* New "TextLabel", "Description"
Text: "This will send a complete report to a moderator. The moderator will review the chat log and take appropriate action."
TextColor3: Color3I 221, 221, 221
Position: UDim2.new 0.01, 0, 0, 55
Size: UDim2.new 0.99, 0, 0, 40
BackgroundTransparency: 1
Font: Enum.Font.Arial
FontSize: Enum.FontSize.Size18
TextWrap: true
TextXAlignment: Enum.TextXAlignment.Left
TextYAlignment: Enum.TextYAlignment.Top
* New "TextLabel", "AbuseLabel"
Text: "What did they do?"
Font: Enum.Font.Arial
BackgroundTransparency: 1
FontSize: Enum.FontSize.Size18
Position: UDim2.new 0.025, 0, 0, 140
Size: UDim2.new 0.4, 0, 0, 36
TextColor3: Color3I 255, 255, 255
TextXAlignment: Enum.TextXAlignment.Left
* New "TextLabel", "ShortDescriptionLabel"
Text: "Short Description: (optional)"
Font: Enum.Font.Arial
FontSize: Enum.FontSize.Size18
Position: UDim2.new 0.025, 0, 0, 180
Size: UDim2.new 0.95, 0, 0, 36
TextColor3: Color3I 255, 255, 255
TextXAlignment: Enum.TextXAlignment.Left
BackgroundTransparency: 1
* New "TextLabel", "ReportingPlayerLabel"
Text: "Reporting Player"
BackgroundTransparency: 1
Font: Enum.Font.Arial
FontSize: Enum.FontSize.Size18
Position: UDim2.new 0.025, 0, 0, 100
Size: UDim2.new 0.95, 0, 0, 36
TextColor3: Color3I 255, 255, 255
TextXAlignment: Enum.TextXAlignment.Left
Parent: AbuseSettingsFrame
AbusePlayerLabel = New "TextLabel", "PlayerLabel"
Text: ""
BackgroundTransparency: 1
Font: Enum.Font.ArialBold
FontSize: Enum.FontSize.Size18
Position: UDim2.new 0.025, 0, 0, 100
Size: UDim2.new 0.95, 0, 0, 36
TextColor3: Color3I 255, 255, 255
TextXAlignment: Enum.TextXAlignment.Right
Parent: AbuseSettingsFrame
SubmitReportButton = New "ImageButton", "SubmitReportBtn"
Active: false
BackgroundTransparency: 1
Position: UDim2.new 0.5, -200, 1, -80
Size: UDim2.new 0, 150, 0, 50
AutoButtonColor: false
Image: "http://www.roblox.com/asset/?id=96502438" -- 96501119'
Parent: AbuseSettingsFrame
CancelReportButton = New "ImageButton", "CancelBtn"
BackgroundTransparency: 1
Position: UDim2.new 0.5, 50, 1, -80
Size: UDim2.new 0, 150, 0, 50
AutoButtonColor: true
Image: "http://www.roblox.com/asset/?id=96500683"
Parent: AbuseSettingsFrame
AbuseDescriptionWrapper = New "Frame", "AbuseDescriptionWrapper"
Position: UDim2.new 0.025, 0, 0, 220
Size: UDim2.new 0.95, 0, 1, -310
BackgroundColor3: Color3I 0, 0, 0
BorderSizePixel: 0
Parent: AbuseSettingsFrame
local AbuseDescriptionBox
OriginalAbuseDescriptionBox = New "TextBox"
Text: ""
ClearTextOnFocus: false
Font: Enum.Font.Arial
FontSize: Enum.FontSize.Size18
Position: UDim2.new 0, 3, 0, 3
Size: UDim2.new 1, -6, 1, -6
TextColor3: Color3I 255, 255, 255
TextXAlignment: Enum.TextXAlignment.Left
TextYAlignment: Enum.TextYAlignment.Top
TextWrap: true
BackgroundColor3: Color3I 0, 0, 0
BorderSizePixel: 0
CalmingAbuseBox = New "Frame", "AbuseFeedbackBox"
BackgroundTransparency: 1
Position: UDim2.new 0.25, 0, 0.3, 0
Size: UDim2.new 0.5, 0, 0.37, 0
* MakeBackgroundGuiObj "http://www.roblox.com/asset/?id=96506233"
* New "TextLabel", "Header",
Position: UDim2.new 0, 10, 0.05, 0
Size: UDim2.new 1, -30, 0.15, 0
TextScaled: true
BackgroundTransparency: 1
TextXAlignment: Enum.TextXAlignment.Center
TextYAlignment: Enum.TextYAlignment.Top
Text: "Thanks for your report!"
TextColor3: Color3.new 1, 1, 1
FontSize: Enum.FontSize.Size48
Font: "ArialBold"
* New "TextLabel", "content"
Position: UDim2.new 0, 10, 0.20, 0
Size: UDim2.new 1, -30, 0.40, 0
TextScaled: true
BackgroundTransparency: 1
TextColor3: Color3.new 1, 1, 1
Text: "Our moderators will review the chat logs and determine what happened. The other user is probably just trying to make you mad.\n\nIf anyone used swear words, inappropriate language, or threatened you in real life, please report them for Bad Words or Threats"
TextWrapped: true
TextYAlignment: Enum.TextYAlignment.Top
FontSize: Enum.FontSize.Size24
Font: "Arial"
* New "ImageButton", "OkButton"
BackgroundTransparency: 1,
Position: UDim2.new 0.5, -75, 1, -80,
Size: UDim2.new 0, 150, 0, 50,
AutoButtonColor: true,
Image: "http://www.roblox.com/asset/?id=96507959",
NormalAbuseBox = New "Frame", "AbuseFeedbackBox"
BackgroundTransparency: 1
Position: UDim2.new 0.25, 0, 0.300000012, 0
Size: UDim2.new 0.5, 0, 0.370000005, 0
* MakeBackgroundGuiObj "http://www.roblox.com/asset/?id=96506233"
* New "TextLabel", "Header"
Position: UDim2.new 0, 10, 0.05, 0
Size: UDim2.new 1, -30, 0.15, 0
TextScaled: true
BackgroundTransparency: 1
TextColor3: Color3.new 1, 1, 1
TextXAlignment: Enum.TextXAlignment.Center
TextYAlignment: Enum.TextYAlignment.Top
Text: "Thanks for your report!"
FontSize: Enum.FontSize.Size48
Font: "ArialBold"
* New "TextLabel", "content",
Position: UDim2.new 0, 10, 0.20, 0
Size: UDim2.new 1, -30, 0.15, 0
TextScaled: true
BackgroundTransparency: 1
TextColor3: Color3.new 1, 1, 1
Text: "Our moderators will review the chat logs and determine what happened."
TextWrapped: true
TextYAlignment: Enum.TextYAlignment.Top
FontSize: Enum.FontSize.Size24
Font: "Arial"
* New "ImageButton", "OkButton",
BackgroundTransparency: 1
Position: UDim2.new 0.5, -75, 1, -80
Size: UDim2.new 0, 150, 0, 50
AutoButtonColor: true
Image: "http://www.roblox.com/asset/?id=96507959"
BigButton = New "ImageButton"
Size: UDim2.new 1, 0, 1, 0
BackgroundTransparency: 1
ZIndex: 8
Visible: false
--Active: false
Parent: ScreenGui
debugFrame = New "Frame", "debugframe"
-- Position: UDim2.new 0, 0, 0, 0
-- Size: UDim2.new 0, 150, 0, 800 --0.99000001
-- BackgroundTransparency: 1
BackgroundTransparency: 1
Position: UDim2.new 0.25, 0, 0.3, 0
Size: UDim2.new 0.5, 0, 0.37, 0
* MakeBackgroundGuiObj "http://www.roblox.com/asset/?id=96506233"
debugplayers = New "TextLabel"
BackgroundTransparency: 0.8
Position: UDim2.new 0, 0, 0.01, 0
Size: UDim2.new 1, 0, 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"
debugOutput = New "TextLabel"
BackgroundTransparency: 0.8
Position: UDim2.new 0, 0, 0.5, 0
Size: UDim2.new 1, 0, 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"
-------------------------
-- Script objects
-------------------------
RbxGui = assert LoadLibrary "RbxGui"
-- number of entries to show if you click minimize
DefaultEntriesOnScreen = 8
for _, i in pairs Images
Game\GetService"ContentProvider"\Preload "http://www.roblox.com/asset/?id=#{i}"
-- 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)
ScoreNames = {}
-- prevents flipping in playerlist panels
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)
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)
TeamFrames = {}
-- one special entry from teamFrames, for unaffiliated players, only shown if players non - empty
local NeutralTeam
-- final 'to be displayed' list of frames
MiddleFrames = {}
MiddleFrameBackgrounds = {}
-- time of last click
LastClick = 0
ButtonCooldown = 0.25
OnIos = false
try
OnIos = Game\GetService"UserInputService".TouchEnabled
-- you get 200 of x screen space per stat added, start width 16%
BaseScreenXSize = 150
SpacingPerStat = 10 --spacing between stats
MaximizedBounds = UDim2.new 0.5, 0, 1, 0
MaximizedPosition = UDim2.new 0.25, 0, 0.1, 0
NormalBounds = UDim2.new 0, BaseScreenXSize, 0, 800
NormalPosition = UDim2.new 1, -BaseScreenXSize, 0.005, 0
--free space to give last stat on the right
RightEdgeSpace = -0.04
-- where the scroll par currently is positioned
DefaultBottomClipPos = BottomClipFrame.Position.Y.Scale
local SelectedPlayerEntry
local SelectedPlayer
-- locks(semaphores) for stopping race conditions
AddingFrameLock = false
AddingStatLock = false
BaseUpdateLock = false
WaitForClickLock = false
InPopupWaitForClick = false
PlayerChangedLock = false
NeutralTeamLock = false
ScrollWheelConnections = {}
DefaultListSize = 8
if not OnIos
DefaultListSize = 12
DidMinimizeDrag = false
--local PlaceCreatorId=game.CreatorId
-- report abuse objects
local AbuseName
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
PrivilegeLevel =
Owner: 255
Admin: 240
Member: 128
Visitor: 10
Banned: 0
IsPersonalServer = not not game.Workspace\FindFirstChild "PSVariable"
game.Workspace.ChildAdded\connect (nchild) ->
if nchild.Name == "PSVariable" and nchild\IsA "BoolValue"
IsPersonalServer = true
-------------------------------
-- Static Functions
-------------------------------
-- GetTotalEntries = ->
-- return math.min(#MiddleFrameBackgrounds, DefaultEntriesOnScreen)
-- GetEntryListLength = ->
-- numEnts = #PlayerFrames + #TeamFrames
-- if NeutralTeam
-- numEnts += 1
-- numEnts
AreAllEntriesOnScreen = ->
#MiddleFrameBackgrounds * MiddleTemplate.Size.Y.Scale <= 1 + DefaultBottomClipPos
-- GetLengthOfVisbleScroll = ->
-- 1 + DefaultBottomClipPos
GetMaxScroll = ->
DefaultBottomClipPos * -1
-- can be optimized by caching when this varible changes
GetMinScroll = ->
if AreAllEntriesOnScreen!
GetMaxScroll!
else
(GetMaxScroll! - (#MiddleFrameBackgrounds * MiddleTemplate.Size.Y.Scale)) + (1 + DefaultBottomClipPos)
AbsoluteToPercent = (x, y) ->
Vector2.new(x, y) / ScreenGui.AbsoluteSize
--[[
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
--]]
TweenProperty = (obj, propName, inita, enda, length) ->
startTime = tick!
while tick! - startTime < length
obj[propName] = ((enda - inita) * ((tick! - startTime) / length)) + inita
wait 1 / 30
obj[propName] = enda
--[[
UGLY UGLY HACK FUNCTION
replace with some sort of global input catching A.S.A. FREAKING P.
creates a fullsize gui element to catch next mouse up event(completeing a click)
@Args:
frameParent Object to parent fullscreen gui to
polledFunction function to call on mouse moved events in this gui
exitFunction function to call when click event is fired
--]]
WaitForClick = (frameParent, polledFunction, exitFunction) ->
return if WaitForClickLock
WaitForClickLock = true
local connection, connection2
connection = BigButton.MouseButton1Up\connect (nx, ny) ->
exitFunction nx, ny
BigButton.Visible = false
connection\disconnect!
connection2?\disconnect!
--debugprint 'mouse up!'
connection2 = BigButton.MouseMoved\connect (nx, ny) ->
polledFunction nx, ny
--debugprint "waiting for click!"
BigButton.Visible = true
BigButton.Active = true
BigButton.Parent = frameParent
frameParent.AncestryChanged\connect (child, nparent) ->
if child == frameParent and not nparent?
exitFunction nx, ny
BigButton.Visible = false
connection\disconnect!
connection2\disconnect!
debugprint "forced out of wait for click"
WaitForClickLock = false
---------------------------
--Personal Server Handling
---------------------------
--[[
returns privlage level based on integer rank
Note: these privilege levels seem completely arbitrary, but no documentation exists
this is all from the old player list, really weird
@Args:
rank Integer rank value for player
@Return Normalized integer value for rank?
--]]
-- GetPrivilegeType = (rank) ->
-- if rank <= PrivilegeLevel["Banned"]
-- PrivilegeLevel["Banned"]
-- elseif rank <= PrivilegeLevel["Visitor"]
-- PrivilegeLevel["Visitor"]
-- elseif rank <= PrivilegeLevel["Member"]
-- PrivilegeLevel["Member"]
-- elseif rank <= PrivilegeLevel["Admin"]
-- PrivilegeLevel["Admin"]
-- else
-- PrivilegeLevel["Owner"]
--[[
gives a player a new privilage rank
Note: Very odd that I have to use loops with this instead of directly setting the rank
but no documentation for personal server service exists
@Args:
player player to change rank of
nrank new integer rank to give player
--]]
SetPrivilegeRank = (player, nrank) ->
while player.PersonalServerRank < nrank
game\GetService"PersonalServerService"\Promote player
while player.PersonalServerRank > nrank
game\GetService"PersonalServerService"\Demote player
assetid = "http://www.roblox.com/asset/?id="
--[[
Highlights current rank of this player in the popup menu
@Args:
player Player to check for rank on
--]]
HighlightMyRank = (player, BanPlayerButton, VisitorButton, MemberButton, AdminButton) ->
BanPlayerButton.Image = assetid .. Images["LightPopupMid"]
VisitorButton.Image = assetid .. Images["DarkPopupMid"]
MemberButton.Image = assetid .. Images["LightPopupMid"]
AdminButton.Image = assetid .. Images["DarkPopupBottom"]
rank = player.PersonalServerRank
if rank <= PrivilegeLevel["Banned"]
BanPlayerButton.Image = assetid .. Images["LightBluePopupMid"]
elseif rank <= PrivilegeLevel["Visitor"]
VisitorButton.Image = assetid .. Images["DarkBluePopupMid"]
elseif rank <= PrivilegeLevel["Member"]
MemberButton.Image = assetid .. Images["LightBluePopupMid"]
elseif rank <= PrivilegeLevel["Admin"]
AdminButton.Image = assetid .. Images["DarkBluePopupBottom"]
--[[
called when player selects new privilege level from popup menu
@Args:
player player to set privileges on
nlevel new privilege level for this player
--]]
OnPrivilegeLevelSelect = (player, nlevel, BanPlayerButton, VisitorButton, MemberButton, AdminButton) ->
debugprint "setting privilege level"
SetPrivilegeRank player, nlevel
HighlightMyRank player, BanPlayerButton, VisitorButton, MemberButton, AdminButton
--------------------------
-- Report abuse handling
--------------------------
--[[
resets and closes abuse dialog
--]]
CloseAbuseDialog = ->
AbuseName = nil
SubmitReportButton.Active = false
SubmitReportButton.Image = "http://www.roblox.com/asset/?id=96502438" -- 96501119'
AbuseDescriptionBox\Destroy!
CalmingAbuseBox.Parent = nil
NormalAbuseBox.Parent = nil
ReportAbuseShield.Parent = nil
AbuseSettingsFrame.Visible = true
--[[
does final reporting of abuse on selected player, calls closeAbuseDialog
--]]
OnSubmitAbuse = ->
if SubmitReportButton.Active
if AbuseName and SelectedPlayer
AbuseSettingsFrame.Visible = false
game.Players\ReportAbuse SelectedPlayer, AbuseName, AbuseDescriptionBox.Text
if AbuseName == "Rude or Mean Behavior" or AbuseName == "False Reporting Me"
CalmingAbuseBox.Parent = ReportAbuseShield
else
debugprint "opening abuse box"
NormalAbuseBox.Parent = ReportAbuseShield
else
CloseAbuseDialog!
ClosePopUpPanel = ->
if SelectedPlayerEntry
tframe = SelectedPlayerEntry["Frame"]
Spawn ->
TweenProperty tframe, "BackgroundTransparency", 0.5, 1, BASE_TWEEN
PopUpPanel\TweenPosition UDim2.new(1, 0, 0, 0), "Out", "Linear", BASE_TWEEN, true
wait 0.1
InPopupWaitForClick = false
SelectedPlayerEntry = nil
--[[
opens the abuse dialog, initialises text to display selectedplayer
--]]
OpenAbuseDialog = ->
debugprint "adding report dialog"
AbusePlayerLabel.Text = SelectedPlayer.Name
--AbuseDescriptionBox.Text = ""
PopUpPanel\TweenPosition UDim2.new(1, 0, 0, 0), "Out", "Linear", BASE_TWEEN, true
AbuseDescriptionBox = OriginalAbuseDescriptionBox\Clone!
AbuseDescriptionBox.Parent = AbuseDescriptionWrapper
ReportAbuseShield.Parent = ScreenGui
ClosePopUpPanel!
--[[
creates dropdownbox, registers all listeners for abuse dialog
--]]
InitReportAbuse = ->
UpdateAbuseFunction = (abuseText) ->
AbuseName = abuseText
if AbuseName and SelectedPlayer
SubmitReportButton.Active = true
SubmitReportButton.Image = "http://www.roblox.com/asset/?id=96501119"
AbuseDropDown, _ = RbxGui.CreateDropDownMenu Abuses, UpdateAbuseFunction, true
AbuseDropDown.Name = "AbuseComboBox"
AbuseDropDown.Position = UDim2.new 0.425, 0, 0, 142
AbuseDropDown.Size = UDim2.new 0.55, 0, 0, 32
AbuseDropDown.Parent = AbuseSettingsFrame
CancelReportButton.MouseButton1Click\connect CloseAbuseDialog
SubmitReportButton.MouseButton1Click\connect OnSubmitAbuse
CalmingAbuseBox\FindFirstChild"OkButton".MouseButton1Down\connect CloseAbuseDialog
NormalAbuseBox\FindFirstChild"OkButton".MouseButton1Down\connect CloseAbuseDialog
-------------------------------------
-- 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
--]]
GetFriendStatus = (player) ->
if player == game.Players.LocalPlayer
return Enum.FriendStatus.NotFriend
else
success, result = try
game.Players.LocalPlayer\GetFriendStatus player
return if success
result
else
Enum.FriendStatus.NotFriend
--[[
when friend button is clicked, tries to take appropriate action,
based on current friend status with SelectedPlayer
--]]
OnFriendButtonSelect = ->
friendStatus = GetFriendStatus SelectedPlayer
if friendStatus == Enum.FriendStatus.Friend
LocalPlayer\RevokeFriendship SelectedPlayer
elseif friendStatus == Enum.FriendStatus.Unknown or
friendStatus == Enum.FriendStatus.NotFriend or
friendStatus == Enum.FriendStatus.FriendRequestSent or
friendStatus == Enum.FriendStatus.FriendRequestReceived
LocalPlayer\RequestFriendship SelectedPlayer
--PersonalServerPanel\TweenPosition UDim2.new(1,0,0,0), "Out", "Quad", .5,true
ClosePopUpPanel!
--PopUpPanel\TweenPosition UDim2.new(1,0,0,0), "Out", "Linear", BASE_TWEEN,true
OnFriendRefuseButtonSelect = ->
LocalPlayer\RevokeFriendship SelectedPlayer
ClosePopUpPanel!
PopUpPanel\TweenPosition UDim2.new(1, 0, 0, 0), "Out", "Linear", BASE_TWEEN, true
------------------------------------
-- Player Entry Handling
------------------------------------
--[[
used by lua's table.sort to sort player entries
--]]
PlayerSortFunction = (a, b) ->
-- prevents flipping out leaderboard
if a["Score"] == b["Score"]
return a["Player"].Name\upper! < b["Player"].Name\upper!
if not a["Score"]
return false
if not b["Score"]
return true
a["Score"] < b["Score"]
---------------------------------
-- Stat Handling
---------------------------------
local UpdateMinimize
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
)
UnTabify = ->
if IsTabified.Value
IsTabified.Value = false
ScreenGui\TweenPosition UDim2.new(0, 0, 0, 0), "Out", "Linear", BASE_TWEEN * 1.2, true
-- removes and closes all leaderboard stuffs
BlowThisPopsicleStand = ->
--ScreenGui\Destroy!
--script\Destroy!
--time to make the fanboys rage...
Tabify!
--[[
used by lua's table.sort to prioritize score entries
--]]
StatSort = (a, b) ->
-- primary stats should be shown before all others
if a.IsPrimary ~= b.IsPrimary
return a.IsPrimary
-- if priorities are equal, then return the first added one
if a.Priority == b.Priority
return a.AddId < b.AddId
a.Priority < b.Priority
local BaseUpdate
--[[
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
--]]
StatChanged = (_, _) -> --playerEntry, property)
-- if(playerEntry['MyTeam'])
-- UpdateSingleTeam(playerEntry['MyTeam'])
-- else
BaseUpdate!
-- end
CreateStatTitle = (statName) ->
with MiddleTemplate\FindFirstChild"PlayerScore"\Clone!
.Name = statName
.Text = statName
-- ntitle
.TextTransparency = if IsMaximized.Value
0
else
1
.Parent = StatTitles
local UpdateMaximize
--[[
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
--]]
StatAdded = (nchild, playerEntry) ->
-- dont re - add a leaderstat I alreday have
while AddingStatLock
debugprint "in stat added function lock"
wait 1 / 30
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"
)
BlowThisPopsicleStand!
else
haveScore = false
for _, i in pairs ScoreNames
if i["Name"] == nchild.Name
haveScore = true
if not haveScore
nstat = {}
nstat["Name"] = nchild.Name
nstat["Priority"] = 0
if nchild\FindFirstChild "Priority"
nstat["Priority"] = nchild.Priority
nstat["IsPrimary"] = false
if nchild\FindFirstChild "IsPrimary"
nstat["IsPrimary"] = true
nstat.AddId = AddId
AddId += 1
table.insert ScoreNames, nstat
table.sort ScoreNames, StatSort
if not StatTitles\FindFirstChild nstat["Name"]
CreateStatTitle nstat["Name"]
UpdateMaximize!
AddingStatLock = false
StatChanged playerEntry
nchild.Changed\connect (property) ->
StatChanged playerEntry, property
--returns whether any of the existing players has this stat
DoesStatExist = (statName, exception) ->
for _, playerf in pairs PlayerFrames
if playerf["Player"] ~= exception and
playerf["Player"]\FindFirstChild "leaderstats" and
playerf["Player"].leaderstats\FindFirstChild statName
--print 'player:' .. playerf['Player'].Name ..' has stat'
return true
false
--[[
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
--]]
StatRemoved = (nchild, playerEntry) ->
while AddingStatLock
debugprint "In Adding Stat Lock1"
wait 1 / 30
AddingStatLock = true
if playerEntry["Frame"]\FindFirstChild nchild.Name
debugprint "Destroyed frame!"
playerEntry["Frame"][nchild.Name].Parent = nil
if not DoesStatExist nchild.Name, playerEntry["Player"]
for i, val in ipairs ScoreNames
if val["Name"] == nchild.Name
table.remove ScoreNames, i
if StatTitles\FindFirstChild nchild.Name
StatTitles[nchild.Name]\Destroy!
for _, teamf in pairs TeamFrames
if teamf["Frame"]\FindFirstChild nchild.Name
teamf["Frame"][nchild.Name]\Destroy!
AddingStatLock = false
StatChanged playerEntry
--[[
clears all stats from a given playerEntry
used when leaderstats are removed, or when new leaderstats are added(for weird edge case)+
--]]
RemoveAllStats = (playerEntry) ->
for _, val in ipairs ScoreNames
StatRemoved val, playerEntry
GetScoreValue = (score) ->
if score\IsA"DoubleConstrainedValue" or score\IsA "IntConstrainedValue"
score.ConstrainedValue
elseif score\IsA "BoolValue"
if score.Value
1
else
0
else
score.Value
--[[
--]]
MakeScoreEntry = (entry, scoreval, panel) ->
return if not panel\FindFirstChild "PlayerScore"
nscoretxt = panel\FindFirstChild"PlayerScore"\Clone!
local thisScore
--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"]
thisScore = entry["Player"]\FindFirstChild"leaderstats"\FindFirstChild scoreval["Name"]
else
return
return if not entry["Player"].Parent
nscoretxt.Name = scoreval["Name"]
nscoretxt.Text = "#{GetScoreValue thisScore}"
if scoreval["Name"] == ScoreNames[1]["Name"]
debugprint "changing score"
entry["Score"] = GetScoreValue thisScore
if entry["Player"] == LocalPlayer
HeaderScore.Text = "#{GetScoreValue thisScore}"
thisScore.Changed\connect ->
return if not thisScore.Parent
if scoreval["Name"] == ScoreNames[1]["Name"]
entry["Score"] = GetScoreValue thisScore
if entry["Player"] == LocalPlayer
HeaderScore.Text = "#{GetScoreValue thisScore}"
nscoretxt.Text = "#{GetScoreValue thisScore}"
BaseUpdate!
nscoretxt
FONT_SIZES = { "Size8", "Size9", "Size10", "Size11", "Size12", "Size14", "Size24", "Size36", "Size48" }
--[[
Will fit the player's name to the bounds of the header
called on resize of the window and playedr name change events
HACK: cannot use 'Textscaled' due to unable to find text bounds when scaled
--]]
UpdateHeaderNameSize = ->
tHeader = HeaderName\Clone!
tHeader.Position = UDim2.new 2, 0, 2, 0
tHeader.Parent = ScreenGui
fSize = 7 --Size24 in table
tHeader.FontSize = FONT_SIZES[fSize]
Delay 0.2, ->
while tHeader.TextBounds.x == 0
wait 1 / 30
while tHeader.TextBounds.x - NormalBounds.X.Offset > 1
fSize -= 1
tHeader.FontSize = FONT_SIZES[fSize]
wait 0.2
HeaderName.FontSize = tHeader.FontSize
tHeader\Destroy!
RecreateScoreColumns = (ptable) ->
while AddingStatLock
debugprint "In Adding Stat Lock2"
wait 1 / 30
AddingStatLock = true
Xoffset = 5 --15 --current offset from Right
maxXOffset = Xoffset
MaxSizeColumn = 0 --max size for this column
-- foreach known leaderstat
for j = #ScoreNames, 1, -1
scoreval = ScoreNames[j]
MaxSizeColumn = 0
-- for each entry in this player table
for _, entry in ipairs ptable
panel = entry["Frame"]
-- tplayer = entry["Player"]
-- if this panel does not have an element named after this stat
if not panel\FindFirstChild scoreval["Name"]
-- make an entry for this object
nentry = MakeScoreEntry entry, scoreval, panel
if nentry
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"]
ntitle = nentry\Clone!
--ntitle.TextXAlignment = 'Right'
ntitle.Parent = entry["MyTeam"]["Frame"]
scoreval["XOffset"] = Xoffset
if panel\FindFirstChild scoreval["Name"]
MaxSizeColumn = math.max MaxSizeColumn, panel[scoreval["Name"]].TextBounds.X
if AreNamesExpanded.Value
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((0.4 + ((0.6 / #ScoreNames) * (j - 1))) - 1, 0, 0, 0),
"Out",
"Linear",
BASE_TWEEN,
true
)
scoreval["ColumnSize"] = MaxSizeColumn
Xoffset += SpacingPerStat + MaxSizeColumn
maxXOffset = math.max Xoffset, maxXOffset
NormalBounds = UDim2.new 0, BaseScreenXSize + maxXOffset - SpacingPerStat, 0, 800
NormalPosition = UDim2.new 1, -NormalBounds.X.Offset, NormalPosition.Y.Scale, 0
UpdateHeaderNameSize!
UpdateMaximize!
AddingStatLock = false
---------------------------
-- Minimizing and maximizing
---------------------------
ExpandNames = ->
if #ScoreNames ~= 0
for _, i in pairs StatTitles\GetChildren!
Spawn ->
TweenProperty i, "TextTransparency", i.TextTransparency, 0, BASE_TWEEN
HeaderFrameHeight = 0.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
CloseNames = ->
if #ScoreNames ~= 0
HeaderFrameHeight = 0.07
if not IsMaximized.Value
for _, i in pairs StatTitles\GetChildren!
Spawn ->
TweenProperty i, "TextTransparency", i.TextTransparency, 1, BASE_TWEEN
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
)
UpdateStatNames = ->
if not AreNamesExpanded.Value or IsMinimized.Value
CloseNames!
else
ExpandNames!
ToggleMinimize = ->
IsMinimized.Value = not IsMinimized.Value
UpdateStatNames!
ToggleMaximize = ->
IsMaximized.Value = not IsMaximized.Value
RecreateScoreColumns PlayerFrames --done to re-position stat names NOTE: optimize-able
--[[
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
--]]
UpdateScrollPosition = ->
minPos = GetMinScroll!
maxPos = GetMaxScroll!
scrollLength = maxPos - minPos
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
adjustedLength = 1 - ScrollBar.Size.Y.Scale
ScrollBar.Position = UDim2.new 0, 0, adjustedLength - (adjustedLength * ((ListFrame.Position.Y.Scale - minPos) / scrollLength)), 0
--[[
Does more than it looks like
monitors positions of the clipping frames and bottom frames
called from EVERYWHERE, too much probably
--]]
UpdateMinimize = ->
if IsMinimized.Value
if IsMaximized.Value
ToggleMaximize!
if not IsTabified.Value
MainFrame\TweenSizeAndPosition(
UDim2.new(0.010, HeaderName.TextBounds.X, NormalBounds.Y.Scale, NormalBounds.Y.Offset),
UDim2.new(0.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
--(#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
MainFrame\TweenSizeAndPosition NormalBounds, NormalPosition, "Out", "Linear", BASE_TWEEN * 1.2, true
--do limiting
DefaultBottomClipPos = math.min math.max(DefaultBottomClipPos, -1), -1 + #MiddleFrameBackgrounds * MiddleBGTemplate.Size.Y.Scale
UpdateScrollPosition!
BottomClipFrame.Position = UDim2.new 0, 0, DefaultBottomClipPos, 0
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"
--[[
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
--]]
UpdateMaximize = ->
if IsMaximized.Value
for j = 1, #ScoreNames, 1
scoreval = ScoreNames[j]
StatTitles[scoreval["Name"]]\TweenPosition(
UDim2.new(0.4 + ((0.6 / #ScoreNames) * (j - 1)) - 1, 0, 0, 0),
"Out",
"Linear",
BASE_TWEEN,
true
)
if IsMinimized.Value
ToggleMinimize!
else
UpdateMinimize!
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(-0.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
i.Background.Image = "http://www.roblox.com/asset/?id=" .. if index % 2 ~= 1
Images["LargeDark"]
else
Images["LargeLight"]
for _, i in ipairs MiddleFrames
if i\FindFirstChild "ClickListener"
i.ClickListener.Size = UDim2.new 0.974, 0, i.ClickListener.Size.Y.Scale, 0
for j = 1, #ScoreNames, 1
scoreval = ScoreNames[j]
if i\FindFirstChild scoreval["Name"]
i[scoreval["Name"]]\TweenPosition(
UDim2.new(0.4 + ((0.6 / #ScoreNames) * (j - 1)) - 1, 0, 0, 0),
"Out",
"Linear",
BASE_TWEEN,
true
)
for _, entry in ipairs PlayerFrames
WaitForChild(entry["Frame"], "TitleFrame").Size = UDim2.new(
0.38,
0,
entry["Frame"].TitleFrame.Size.Y.Scale,
0
)
for _, entry in ipairs TeamFrames
WaitForChild(entry["Frame"], "TitleFrame").Size = UDim2.new(
0.38,
0,
entry["Frame"].TitleFrame.Size.Y.Scale,
0
)
else
if not IsMinimized.Value
MainFrame\TweenSizeAndPosition NormalBounds, NormalPosition, "Out", "Linear", BASE_TWEEN * 1.2, true
HeaderScore\TweenPosition UDim2.new(0, 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
i.Background.Image = "http://www.roblox.com/asset/?id=" .. if index % 2 ~= 1
Images["midDark"]
else
Images["midLight"]
for _, i in ipairs MiddleFrames
if i\FindFirstChild "ClickListener"
i.ClickListener.Size = UDim2.new 0.96, 0, i.ClickListener.Size.Y.Scale, 0
for j = 1, #ScoreNames, 1
scoreval = ScoreNames[j]
if i\FindFirstChild(scoreval["Name"]) and scoreval["XOffset"]
--print('updateing stat position: ' .. scoreval['Name'])
i[scoreval["Name"]]\TweenPosition(
UDim2.new(RightEdgeSpace, -scoreval["XOffset"], 0, 0),
"Out",
"Linear",
BASE_TWEEN,
true
)
for _, entry in ipairs TeamFrames
WaitForChild(entry["Frame"], "TitleFrame").Size = UDim2.new(
0,
BaseScreenXSize * 0.9,
entry["Frame"].TitleFrame.Size.Y.Scale,
0
)
for _, entry in ipairs PlayerFrames
WaitForChild(entry["Frame"], "TitleFrame").Size = UDim2.new(
0,
BaseScreenXSize * 0.9,
entry["Frame"].TitleFrame.Size.Y.Scale,
0
)
OnScrollWheelMove = (direction) ->
if not (IsTabified.Value or IsMinimized.Value or InPopupWaitForClick)
StartFrame = ListFrame.Position
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!
AttachScrollWheel = ->
return if ScrollWheelConnections
ScrollWheelConnections = {}
table.insert(
ScrollWheelConnections,
Mouse.WheelForward\connect ->
OnScrollWheelMove 0.05
)
table.insert(
ScrollWheelConnections,
Mouse.WheelBackward\connect ->
OnScrollWheelMove -0.05
)
DetachScrollWheel = ->
if ScrollWheelConnections
for _, i in pairs ScrollWheelConnections
i\disconnect!
ScrollWheelConnections = nil
FocusFrame.MouseEnter\connect ->
if not (IsMinimized.Value or IsTabified.Value)
AttachScrollWheel!
FocusFrame.MouseLeave\connect ->
--if not (IsMaximized.Value or IsMinimized.Value)
DetachScrollWheel!
------------------------
-- Scroll Bar functions
------------------------
--[[
updates size of scrollbar depending on how many entries exist
--]]
UpdateScrollBarSize = ->
entryListSize = #MiddleFrameBackgrounds * MiddleTemplate.Size.Y.Scale
shownAreaSize = BottomClipFrame.Position.Y.Scale + 1
ScrollBar.Size = UDim2.new 1, 0, shownAreaSize / entryListSize, 0
--[[
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
--]]
InitMovingPanel = (entry, player) ->
PopUpClipFrame.Parent = ScreenGui
PopUpPanel?\Destroy!
PopUpPanel = PopUpPanelTemplate\Clone!
PopUpPanel.Parent = PopUpClipFrame
nextIndex = 2
friendStatus = GetFriendStatus player
debugprint "#{friendStatus}"
showRankMenu = IsPersonalServer and
LocalPlayer.PersonalServerRank >= PrivilegeLevel["Admin"] and
LocalPlayer.PersonalServerRank > SelectedPlayer.PersonalServerRank
ReportPlayerButton = MakePopupButton PopUpPanel, "Report Player", 0
ReportPlayerButton.MouseButton1Click\connect ->
OpenAbuseDialog!
FriendPlayerButton = MakePopupButton(
PopUpPanel,
"Friend",
1,
not showRankMenu and friendStatus ~= Enum.FriendStatus.FriendRequestReceived
)
FriendPlayerButton.MouseButton1Click\connect OnFriendButtonSelect
if friendStatus == Enum.FriendStatus.Friend
FriendPlayerButton\FindFirstChild"ButtonText".Text = "UnFriend Player"
elseif friendStatus == Enum.FriendStatus.Unknown or friendStatus == Enum.FriendStatus.NotFriend
FriendPlayerButton\FindFirstChild"ButtonText".Text = "Send Request"
elseif friendStatus == Enum.FriendStatus.FriendRequestSent
FriendPlayerButton\FindFirstChild"ButtonText".Text = "Revoke Request"
elseif friendStatus == Enum.FriendStatus.FriendRequestReceived
FriendPlayerButton\FindFirstChild"ButtonText".Text = "Accept Friend"
FriendRefuseButton = MakePopupButton PopUpPanel, "Decline Friend", 2, not showRankMenu
FriendRefuseButton.MouseButton1Click\connect OnFriendRefuseButtonSelect
nextIndex += 1
if showRankMenu
BanPlayerButton = MakePopupButton PopUpPanel, "Ban", nextIndex
VisitorButton = MakePopupButton PopUpPanel, "Visitor", nextIndex + 1
MemberButton = MakePopupButton PopUpPanel, "Member", nextIndex + 2
AdminButton = MakePopupButton PopUpPanel, "Admin", nextIndex + 3, true
BanPlayerButton.MouseButton1Click\connect ->
OnPrivilegeLevelSelect(
player,
PrivilegeLevel["Banned"],
BanPlayerButton,
VisitorButton,
MemberButton,
AdminButton
)
VisitorButton.MouseButton1Click\connect ->
OnPrivilegeLevelSelect(
player,
PrivilegeLevel["Visitor"],
BanPlayerButton,
VisitorButton,
MemberButton,
AdminButton
)
MemberButton.MouseButton1Click\connect ->
OnPrivilegeLevelSelect(
player,
PrivilegeLevel["Member"],
BanPlayerButton,
VisitorButton,
MemberButton,
AdminButton
)
AdminButton.MouseButton1Click\connect ->
OnPrivilegeLevelSelect(
player,
PrivilegeLevel["Admin"],
BanPlayerButton,
VisitorButton,
MemberButton,
AdminButton
)
HighlightMyRank SelectedPlayer, BanPlayerButton, VisitorButton, MemberButton, AdminButton
PopUpPanel\TweenPosition UDim2.new(0, 0, 0, 0), "Out", "Linear", BASE_TWEEN, true
Delay 0, ->
tconnection = Mouse.Button1Down\connect ->
tconnection\disconnect!
ClosePopUpPanel!
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 ->
while InPopupWaitForClick
PopUpClipFrame.Position = UDim2.new(
0, myFrame.AbsolutePosition.X - PopUpClipFrame.Size.X.Offset,
0, myFrame.AbsolutePosition.Y
)
wait!
--[[
updates whether the scroll bar should be showing, if it is showing, updates
the size of it
--]]
UpdateScrollBarVisibility = ->
if AreAllEntriesOnScreen!
ScrollBar.BackgroundTransparency = 1
else
ScrollBar.BackgroundTransparency = 0
UpdateScrollBarSize!
ActivatePlayerEntryPanel = (entry) ->
entry["Frame"].BackgroundColor3 = Color3.new 0, 1, 1
Spawn ->
TweenProperty entry["Frame"], "BackgroundTransparency", 1, 0.5, 0.5
InPopupWaitForClick = true
InitMovingPanel entry, entry["Player"]
--[[
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
--]]
StartDrag = (entry, startx, starty) ->
openPanel = true
--[[draggedFrame = ]]
WaitForChild entry["Frame"], "ClickListener"
dragExit = ->
-- stopDrag = true
if entry["Player"] and
SelectedPlayer and
openPanel and
entry["Player"] ~= LocalPlayer and
SelectedPlayer.userId > 1 and
LocalPlayer.userId > 1
ActivatePlayerEntryPanel entry
local startY
StartFrame = ListFrame.Position
dragpoll = (nx, ny) ->
if not startY
startY = AbsoluteToPercent(nx, ny).Y
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
openPanel = false
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!
WaitForClick ScreenGui, dragpoll, dragExit
StartMinimizeDrag = ->
Delay 0, ->
startTime = tick!
debugprint "Got Click2"
dragExit = ->
--debugprint 'undone click2'
if tick! - startTime < 0.25 --was click
ToggleMinimize!
else --was drag
DidMinimizeDrag = true
if IsMinimized.Value
ToggleMinimize!
-- stopDrag = true
local startY
StartFrame = DefaultBottomClipPos
dragpoll = (nx, ny) ->
if not IsMinimized.Value
if not startY
startY = AbsoluteToPercent(nx, ny).Y
nowY = AbsoluteToPercent(nx, ny).Y
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!
Spawn ->
WaitForClick ScreenGui, dragpoll, dragExit
-------------------------------
-- Input Callback functions
-------------------------------
IsMaximized.Value = false
IsMinimized.Value = false
IsMaximized.Changed\connect UpdateMaximize
IsMinimized.Changed\connect UpdateMinimize
ExtendButton.MouseButton1Down\connect ->
return if (time! - LastClick < ButtonCooldown) or InPopupWaitForClick
LastClick = time!
if IsTabified.Value
UnTabify!
else
StartMinimizeDrag!
MaximizeButton.MouseButton1Click\connect ->
return if (time! - LastClick < ButtonCooldown) or InPopupWaitForClick
LastClick = time!
if IsTabified.Value
UnTabify!
elseif not AreNamesExpanded.Value
AreNamesExpanded.Value = true
BaseUpdate!
else
ToggleMaximize!
MaximizeButton.MouseButton2Click\connect ->
return if (time! - LastClick < ButtonCooldown) or InPopupWaitForClick
LastClick = time!
if IsTabified.Value
UnTabify!
elseif IsMaximized.Value
ToggleMaximize!
elseif AreNamesExpanded.Value
AreNamesExpanded.Value = false
BaseUpdate!
else
Tabify!
-------------------------------
-- MiddleFrames management
-------------------------------
--[[
adds a background frame to the listframe
--]]
AddMiddleBGFrame = ->
nBGFrame = MiddleBGTemplate\Clone!
nBGFrame.Position = UDim2.new 0.5, 0, (#MiddleFrameBackgrounds * nBGFrame.Size.Y.Scale), 0
nBGFrame.Background.Image = "http://www.roblox.com/asset/?id=" .. if (#MiddleFrameBackgrounds + 1) % 2 ~= 1
if IsMaximized.Value
Images["LargeDark"]
else
Images["midDark"]
else
if IsMaximized.Value
Images["LargeLight"]
else
Images["midLight"]
nBGFrame.Parent = ListFrame
table.insert MiddleFrameBackgrounds, nBGFrame
if #MiddleFrameBackgrounds < DefaultListSize and not DidMinimizeDrag
--print('readjusting bottom clip')
DefaultBottomClipPos = -1 + #MiddleFrameBackgrounds * MiddleBGTemplate.Size.Y.Scale
if not IsMinimized.Value
UpdateMinimize!
--[[
removes a background from from the listframe
--]]
RemoveMiddleBGFrame = ->
MiddleFrameBackgrounds[#MiddleFrameBackgrounds]\Destroy!
table.remove MiddleFrameBackgrounds, #MiddleFrameBackgrounds
if not IsMinimized.Value
UpdateMinimize!
-------------------------------
-- Player Callback functions
-------------------------------
--[[
note: should probably set to something other than mainFrame.AbsoluteSize, should work for now
if textbounds ever works on textscaled, switch to that :(
--]]
ChangeHeaderName = (nname) ->
HeaderName.Text = nname
UpdateHeaderNameSize!
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
--]]
LeaderstatsAdded = (playerEntry) ->
--RemoveAllStats(playerEntry)
nplayer = playerEntry["Player"]
for _, i in pairs nplayer.leaderstats\GetChildren!
StatAdded i, playerEntry
nplayer.leaderstats.ChildAdded\connect (nchild) ->
StatAdded nchild, playerEntry
nplayer.leaderstats.ChildRemoved\connect (nchild) ->
StatRemoved nchild, playerEntry
--[[
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
--]]
LeaderstatsRemoved = (_, playerEntry) ->
while AddingFrameLock
debugprint "waiting to insert #{playerEntry["Player"].Name}"
wait 1 / 30
AddingFrameLock = true
RemoveAllStats playerEntry
AddingFrameLock = false
--[[
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
--]]
OnPlayerEntrySelect = (entry, startx, starty) ->
if not InPopupWaitForClick
SelectedPlayerEntry = entry
SelectedPlayer = entry["Player"]
StartDrag entry, startx, starty
--[[
the basic update for the playerlist mode's state,
assures the order and length of the player frames
--]]
PlayerListModeUpdate = ->
RecreateScoreColumns(PlayerFrames)
table.sort(PlayerFrames, PlayerSortFunction)
for i, val in ipairs PlayerFrames
MiddleFrames[i] = val["Frame"]
for i = #PlayerFrames + 1, #MiddleFrames, 1
MiddleFrames[i] = nil
UpdateMinimize!
RemoveNeutralTeam = ->
while NeutralTeamLock
debugprint "in neutral team lock"
wait!
NeutralTeamLock = true
NeutralTeam["Frame"]\Destroy!
NeutralTeam = nil
RemoveMiddleBGFrame!
NeutralTeamLock = false
--[[
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
--]]
RemovePlayerFromTeam = (teamEntry, index) ->
table.remove(teamEntry["MyPlayers"], index)
--if teamEntry['AutoHide'] and #teamEntry['MyPlayers'] == 0
if teamEntry == NeutralTeam and #teamEntry["MyPlayers"] == 0
RemoveNeutralTeam!
--[[
finds previous team this player was on, and if it exists calls removeplayerfromteam
@Args
entry Player entry
--]]
FindRemovePlayerFromTeam = (entry) ->
if entry["MyTeam"]
for j, oldEntry in ipairs entry["MyTeam"]["MyPlayers"]
if oldEntry["Player"] == entry["Player"]
RemovePlayerFromTeam entry["MyTeam"], j
return
elseif NeutralTeam
for j, oldEntry in ipairs NeutralTeam["MyPlayers"]
if oldEntry["Player"] == entry["Player"]
RemovePlayerFromTeam NeutralTeam, j
return
--[[
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
--]]
AddPlayerToTeam = (teamEntry, entry) ->
FindRemovePlayerFromTeam entry
table.insert teamEntry["MyPlayers"], entry
entry["MyTeam"] = teamEntry
if teamEntry["IsHidden"]
teamEntry["Frame"].Parent = ListFrame
AddMiddleBGFrame!
teamEntry["IsHidden"] = false
--[[
adds a neutral team if nessisary
Note: a lot of redundant code here, might want to refactor to share a function with insertteamframe
--]]
AddNeutralTeam = ->
while NeutralTeamLock
debugprint "in neutral team 2 lock"
wait!
NeutralTeamLock = true
defaultTeam = Instance.new "Team"
defaultTeam.TeamColor = BrickColor.new "White"
defaultTeam.Name = "Neutral"
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,
0.1,
0
)
nentry["Frame"].TitleFrame.Size = UDim2.new(
nentry["Frame"].TitleFrame.Size.X.Scale,
nentry["Frame"].TitleFrame.Size.X.Offset,
0.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 (nx, ny) ->
StartDrag nentry, nx, ny
nentry["Frame"].ClickListener.BackgroundColor3 = Color3.new 1, 1, 1
nentry["Frame"].ClickListener.BackgroundTransparency = 0.7
nentry["Frame"].ClickListener.AutoButtonColor = false
nentry["AutoHide"] = true
nentry["IsHidden"] = true
for _, i in pairs PlayerFrames
if i["Player"].Neutral or not i["MyTeam"]
AddPlayerToTeam nentry, i
if #nentry["MyPlayers"] > 0
NeutralTeam = nentry
UpdateMinimize!
BaseUpdate!
NeutralTeamLock = false
SetPlayerToTeam = (entry) ->
FindRemovePlayerFromTeam entry
-- check to see if team exists, if it does add to that team
setToTeam = false
for _, tframe in ipairs TeamFrames
-- add my entry on the new team
if tframe["MyTeam"].TeamColor == entry["Player"].TeamColor
AddPlayerToTeam tframe, entry
setToTeam = true
-- if player was set to an invalid team, then set it back to neutral
if not setToTeam and #(game.Teams\GetTeams!) > 0
debugprint "#{entry["Player"].Name} could not find team"
entry["MyTeam"] = nil
if not NeutralTeam
AddNeutralTeam!
else
AddPlayerToTeam NeutralTeam, entry
--[[
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
--]]
PlayerChanged = (entry, property) ->
while PlayerChangedLock
debugprint "in playerchanged lock"
wait 1 / 30
PlayerChangedLock = true
if property == "Neutral"
-- if player changing to neutral
if entry["Player"].Neutral and #game.Teams\GetTeams! > 0
debugprint "#{entry["Player"].Name} setting to neutral"
FindRemovePlayerFromTeam(entry)
entry["MyTeam"] = nil
if not NeutralTeam
debugprint "#{entry["Player"].Name} creating neutral team"
AddNeutralTeam!
else
debugprint "#{entry["Player"].Name} adding to neutral team"
AddPlayerToTeam NeutralTeam, entry
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
BaseUpdate!
elseif property == "TeamColor" and not entry["Player"].Neutral and entry["Player"] ~= entry["MyTeam"]
debugprint "#{entry["Player"].Name} setting to new team"
SetPlayerToTeam entry
BaseUpdate!
elseif property == "Name" or property == "MembershipType"
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 ~= ""
entry["Frame"].TitleFrame.Title.Position = UDim2.new 0.01, 30, 0.1, 0
if entry["Player"] == LocalPlayer
entry["Frame"].TitleFrame.DropShadow.Text = entry["Player"].Name
ChangeHeaderName entry["Player"].Name
BaseUpdate!
PlayerChangedLock = false
--[[
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
--]]
InsertPlayerFrame = (nplayer) ->
while AddingFrameLock
debugprint "waiting to insert #{nplayer.Name}"
wait 1 / 30
AddingFrameLock = true
nFrame = MiddleTemplate\Clone!
WaitForChild(WaitForChild(nFrame, "TitleFrame"), "Title").Text = nplayer.Name
nFrame.Position = UDim2.new 1, 0, (#MiddleFrames * nFrame.Size.Y.Scale), 0
nfriendstatus = GetFriendStatus nplayer
nFrame\FindFirstChild"BCLabel".Image = getMembershipTypeIcon(nplayer.MembershipType, nplayer.Name)
nFrame\FindFirstChild"FriendLabel".Image = getFriendStatusIcon(nfriendstatus)
nFrame.Name = nplayer.Name
WaitForChild(WaitForChild(nFrame, "TitleFrame"), "Title").Text = nplayer.Name
--move for bc label
nFrame.FriendLabel.Position = nFrame.FriendLabel.Position + UDim2.new 0, 17, 0, 0
nFrame.TitleFrame.Title.Position = nFrame.TitleFrame.Title.Position + UDim2.new 0, 17, 0, 0
if nFrame\FindFirstChild"FriendLabel".Image ~= ""
nFrame.TitleFrame.Title.Position = nFrame.TitleFrame.Title.Position + UDim2.new 0, 17, 0, 0
if nplayer.Name == LocalPlayer.Name
nFrame.TitleFrame.Title.Font = "ArialBold"
nFrame.PlayerScore.Font = "ArialBold"
ChangeHeaderName nplayer.Name
with nFrame.TitleFrame.Title\Clone!
.TextColor3 = Color3.new 0, 0, 0
.TextTransparency = 0
.ZIndex = 2
.Position = nFrame.TitleFrame.Title.Position + UDim2.new 0, 1, 0, 1
.Name = "DropShadow"
.Parent = nFrame.TitleFrame
-- else
-- --Delay 2, -> OnFriendshipChanged(nplayer,LocalPlayer\GetFriendStatus(nplayer)) end)
nFrame.TitleFrame.Title.Font = "ArialBold"
nFrame.Parent = ListFrame
nFrame\TweenPosition UDim2.new(0.5, 0, (#MiddleFrames * nFrame.Size.Y.Scale), 0), "Out", "Linear", BASE_TWEEN, true
UpdateMinimize!
nentry = {}
nentry["Frame"] = nFrame
nentry["Player"] = nplayer
nentry["ID"] = AddId
AddId += 1
table.insert PlayerFrames, nentry
if #TeamFrames ~= 0
if nplayer.Neutral
nentry["MyTeam"] = nil
if not NeutralTeam
AddNeutralTeam!
else
AddPlayerToTeam NeutralTeam, nentry
else
addedToTeam = false
for _, tval in ipairs TeamFrames
if tval["MyTeam"].TeamColor == nplayer.TeamColor
AddPlayerToTeam tval, nentry
nentry["MyTeam"] = tval
addedToTeam = true
if not addedToTeam
nentry["MyTeam"] = nil
if not NeutralTeam
AddNeutralTeam!
else
AddPlayerToTeam NeutralTeam, nentry
nentry["MyTeam"] = NeutralTeam
if nplayer\FindFirstChild "leaderstats"
LeaderstatsAdded nentry
nplayer.ChildAdded\connect (nchild) ->
if nchild.Name == "leaderstats"
while AddingFrameLock
debugprint "in adding leaderstats lock"
wait 1 / 30
AddingFrameLock = true
LeaderstatsAdded nentry
AddingFrameLock = false
nplayer.ChildRemoved\connect (nchild) ->
if nplayer == LocalPlayer and nchild.Name == "leaderstats"
LeaderstatsRemoved nchild, nentry
nplayer.Changed\connect (prop) ->
PlayerChanged nentry, prop
listener = WaitForChild nFrame, "ClickListener"
listener.Active = true
listener.MouseButton1Down\connect (nx, ny) ->
OnPlayerEntrySelect nentry, nx, ny
AddMiddleBGFrame!
BaseUpdate!
AddingFrameLock = false
--[[
Note: major optimization can be done here
removes this player's frame if it exists, calls base update
--]]
RemovePlayerFrame = (tplayer) ->
while AddingFrameLock
debugprint "in removing player frame lock"
wait 1 / 30
AddingFrameLock = true
local tteam
for i, key in ipairs PlayerFrames
if tplayer == key["Player"]
if PopUpClipFrame.Parent == key["Frame"]
PopUpClipFrame.Parent = nil
key["Frame"]\Destroy!
tteam = key["MyTeam"]
table.remove PlayerFrames, i
if tteam
for j, tentry in ipairs tteam["MyPlayers"]
if tentry["Player"] == tplayer
RemovePlayerFromTeam tteam, j
RemoveMiddleBGFrame!
UpdateMinimize!
BaseUpdate!
AddingFrameLock = false
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
--]]
UnrollTeams = (tframes, outframes) ->
numEntries = 0
if NeutralTeam and not NeutralTeam["IsHidden"]
for _, val in ipairs(NeutralTeam["MyPlayers"])
numEntries += 1
outframes[numEntries] = val["Frame"]
numEntries += 1
outframes[numEntries] = NeutralTeam["Frame"]
for _, val in ipairs tframes
if not val["IsHidden"]
for _, pval in ipairs(val.MyPlayers)
numEntries += 1
outframes[numEntries] = pval["Frame"]
numEntries += 1
outframes[numEntries] = val["Frame"]
-- clear any additional entries from outframes
for i = numEntries + 1, #outframes, 1
outframes[i] = nil
--[[
uses lua's table.sort to sort the teams
--]]
TeamSortFunc = (a, b) ->
if a["TeamScore"] == b["TeamScore"]
return a["ID"] < b["ID"]
if not a["TeamScore"]
return false
if not b["TeamScore"]
return true
a["TeamScore"] < b["TeamScore"]
--[[
adds up all the score of this team's players to form the team score
@Args:
team team entry to sum the scores of
--]]
AddTeamScores = (team) ->
for j = 1, #ScoreNames, 1
i = ScoreNames[j]
tscore = 0
for _, j in ipairs(team["MyPlayers"])
tval = j["Player"]\FindFirstChild "leaderstats" and j["Player"].leaderstats\FindFirstChild i["Name"]
if tval and not tval\IsA "StringValue"
tscore += GetScoreValue (j["Player"].leaderstats)[i["Name"]]
if team["Frame"]\FindFirstChild i["Name"]
--team['Frame'][i['Name'] ].Size = UDim2.new(1 - (ScrollBarFrame.Size.X.Scale * 2),- ((j-1) * SpacingPerStat),1,0)
team["Frame"][i["Name"]].Text = "#{tscore}"
UpdateMinimize!
--[[
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
--]]
SortTeams = (tentries) ->
for _, val in ipairs tentries
table.sort val["MyPlayers"], PlayerSortFunction
AddTeamScores val
table.sort tentries, TeamSortFunc
--[[
base update for team mode, adds up the scores of all teams, sorts them,
then unrolls them into middleframes
--]]
TeamListModeUpdate = ->
RecreateScoreColumns PlayerFrames
SortTeams TeamFrames
if NeutralTeam
AddTeamScores NeutralTeam
--RecreateScoreColumns(NeutralTeam['MyPlayers'])
UnrollTeams TeamFrames, MiddleFrames
OnFriendshipChanged = (player, friendStatus) ->
Delay 0.5, ->
debugprint "friend status changed for: #{player.Name} #{friendStatus} vs #{GetFriendStatus player}"
for _, entry in ipairs PlayerFrames
if entry["Player"] == player
nicon = getFriendStatusIcon friendStatus
if nicon == "" and entry["Frame"].FriendLabel.Image ~= ""
entry["Frame"].TitleFrame.Title.Position = entry["Frame"].TitleFrame.Title.Position -
UDim2.new 0, 17, 0, 0
elseif nicon ~= "" and entry["Frame"].FriendLabel.Image == ""
entry["Frame"].TitleFrame.Title.Position = entry["Frame"].TitleFrame.Title.Position +
UDim2.new 0, 17, 0, 0
debugprint "confirmed status: #{player.Name}"
entry["Frame"].FriendLabel.Image = nicon
return
LocalPlayer.FriendStatusChanged\connect OnFriendshipChanged
--[[
--]]
TeamScoreChanged = (entry, nscore) ->
WaitForChild(entry["Frame"], "PlayerScore").Text = "#{nscore}"
entry["TeamScore"] = nscore
--[[
called when child added to a team, used for autohide functionality
Note: still has teamscore, consiter removing
--]]
TeamChildAdded = (entry, nchild) ->
if nchild.Name == "AutoHide"
entry["AutoHide"] = true
elseif nchild.Name == "TeamScore"
WaitForChild(entry["Frame"], "PlayerScore").Text = "#{nchild.Value}"
entry["TeamScore"] = nchild.Value
nchild.Changed\connect ->
TeamScoreChanged entry, nchild.Value
--[[
called when child added to a team, used for autohide functionality
Note: still has teamscore, consiter removing
--]]
TeamChildRemoved = (entry, nchild) ->
if nchild.Name == "AutoHide"
entry["AutoHide"] = false
elseif nchild.Name == "TeamScore"
WaitForChild(entry["Frame"], "PlayerScore").Text = ""
entry["TeamScore"] = nil
--[[
removes team from team list
@Args:
nteam Teamobject to remove
--]]
RemoveTeamFrame = (nteam) ->
while AddingFrameLock
debugprint "in removing team frame lock"
wait 1 / 30
AddingFrameLock = true
-- if IsMinimized.Value
-- end
local myEntry
for i, key in ipairs TeamFrames
if nteam == key["MyTeam"]
myEntry = key
key["Frame"]\Destroy!
table.remove TeamFrames, i
if #TeamFrames == 0
debugprint "removeteamframe, remove neutral"
if NeutralTeam
RemoveNeutralTeam!
for i, key in ipairs myEntry["MyPlayers"]
RemovePlayerFromTeam myEntry, i
PlayerChanged key, "TeamColor"
RemoveMiddleBGFrame!
BaseUpdate!
AddingFrameLock = false
TeamChanged = (entry, property) ->
if property == "Name"
WaitForChild(WaitForChild(entry["Frame"], "TitleFrame"), "Title").Text = entry["MyTeam"].Name
elseif property == "TeamColor"
entry["Frame"].ClickListener.BackgroundColor3 = entry["MyTeam"].TeamColor.Color
for _, i in pairs TeamFrames
if i["MyTeam"].TeamColor == entry["MyTeam"]
RemoveTeamFrame entry["MyTeam"] --NO DUPLICATE TEAMS!
entry["MyPlayers"] = {}
for _, i in pairs PlayerFrames
SetPlayerToTeam i
BaseUpdate!
--[[
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
--]]
InsertTeamFrame = (nteam) ->
while AddingFrameLock
debugprint "in adding team frame lock"
wait 1 / 30
AddingFrameLock = true
--for _,i in pairs TeamFrames
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,
0.1,
0
)
nentry["Frame"].TitleFrame.Size = UDim2.new(
nentry["Frame"].TitleFrame.Size.X.Scale,
nentry["Frame"].TitleFrame.Size.X.Offset,
0.8,
0
)
nentry["Frame"].Position = UDim2.new(1, 0, (#MiddleFrames * nentry["Frame"].Size.Y.Scale), 0)
WaitForChild(nentry["Frame"], "ClickListener").MouseButton1Down\connect (nx, ny) ->
StartDrag nentry, nx, ny
nentry["Frame"].ClickListener.BackgroundColor3 = nteam.TeamColor.Color
nentry["Frame"].ClickListener.BackgroundTransparency = 0.7
nentry["Frame"].ClickListener.AutoButtonColor = false
AddId += 1
nentry["ID"] = AddId
nentry["AutoHide"] = false
if nteam\FindFirstChild "AutoHide"
nentry["AutoHide"] = true
if nteam\FindFirstChild "TeamScore"
TeamChildAdded nentry, nteam.TeamScore
nteam.ChildAdded\connect (nchild) -> TeamChildAdded nentry, nchild
nteam.ChildRemoved\connect (nchild) -> TeamChildRemoved nentry, nchild
nteam.Changed\connect (prop) -> TeamChanged nentry, prop
for _, i in pairs PlayerFrames
if not i["Player"].Neutral and i["Player"].TeamColor == nteam.TeamColor
AddPlayerToTeam nentry, i
nentry["IsHidden"] = false
if not nentry["AutoHide"] or #nentry["MyPlayers"] > 0
nentry["Frame"].Parent = ListFrame
nentry["Frame"]\TweenPosition(
UDim2.new(0.5, 0, (#MiddleFrames * nentry["Frame"].Size.Y.Scale), 0),
"Out",
"Linear",
BASE_TWEEN,
true
)
AddMiddleBGFrame!
else
nentry["IsHidden"] = true
nentry["Frame"].Parent = nil
table.insert TeamFrames, nentry
UpdateMinimize!
BaseUpdate!
if #TeamFrames == 1 and not NeutralTeam
AddNeutralTeam!
AddingFrameLock = false
TeamAdded = (nteam) -> InsertTeamFrame nteam
TeamRemoved = (nteam) -> RemoveTeamFrame nteam
---------------------------------
--[[
called when ANYTHING changes the state of the playerlist
re-sorts everything,assures correct positions of all elements
--]]
BaseUpdate = ->
while BaseUpdateLock
debugprint "in baseupdate lock"
wait 1 / 30
BaseUpdateLock = true
--print ('baseupdate')
UpdateStatNames!
if #TeamFrames == 0 and not NeutralTeam
PlayerListModeUpdate!
else
TeamListModeUpdate!
for i, key in ipairs MiddleFrames
if not key.Parent?
key\TweenPosition(
UDim2.new(0.5, 0, ((#MiddleFrames - i) * key.Size.Y.Scale), 0),
"Out",
"Linear",
BASE_TWEEN,
true
)
if not IsMinimized.Value and #MiddleFrames > DefaultEntriesOnScreen
UpdateScrollPosition!
UpdateMinimize!
UpdateScrollBarSize!
UpdateScrollPosition!
UpdateScrollBarVisibility!
--debugprint('EndBaseUpdate')
BaseUpdateLock = false
--[[
code for attaching tab key to maximizing player list
--]]
game.GuiService\AddKey "\t"
LastTabTime = time!
game.GuiService.KeyPressed\connect (key) ->
if key == "\t"
debugprint "caught tab key"
local modalCheck, isModal = try
return game.GuiService.IsModalDialog
if modalCheck == false or (modalCheck and isModal == false)
if time! - LastTabTime > 0.4
LastTabTime = time!
if IsTabified.Value
if not IsMaximized.Value
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
else
ToggleMaximize!
debugPlayerAdd = (p) ->
InsertPlayerFrame p
PlayersChildAdded = (tplayer) ->
if tplayer\IsA "Player"
Spawn ->
debugPlayerAdd tplayer
else
BlowThisPopsicleStand!
coreGuiChanged = (coreGuiType, enabled) ->
if coreGuiType == Enum.CoreGuiType.All or coreGuiType == Enum.CoreGuiType.PlayerList
MainFrame.Visible = enabled
TeamsChildAdded = (nteam) ->
if nteam\IsA "Team"
TeamAdded nteam
else
BlowThisPopsicleStand!
TeamsChildRemoved = (nteam) ->
if nteam\IsA "Team"
TeamRemoved nteam
else
BlowThisPopsicleStand!
----------------------------
-- Hookups and initialization
----------------------------
try
coreGuiChanged Enum.CoreGuiType.PlayerList, Game.StarterGui\GetCoreGuiEnabled Enum.CoreGuiType.PlayerList
Game.StarterGui.CoreGuiChangedSignal\connect coreGuiChanged
while not game\GetService "Teams"
wait 1 / 30
debugprint "Waiting For Teams"
for _, i in pairs game.Teams\GetTeams!
TeamAdded i
for _, i in pairs Players\GetPlayers!
Spawn ->
debugPlayerAdd i
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"
debugFrame.Parent = ScreenGui
Spawn ->
while true
local str_players = ""
for _, i in pairs game.Players\GetPlayers!
str_players ..= " #{i.Name}"
debugplayers.Text = str_players
wait 0.5