diff --git a/CSMPFunctions.lua b/CSMPFunctions.lua
index 1d03e6a..653faeb 100644
--- a/CSMPFunctions.lua
+++ b/CSMPFunctions.lua
@@ -1,6 +1,5 @@
--coded by Bitl and Carrot
--stuff was borrowed from RBXBanland, EnergyCell, John, and the RBXPri team
-
rbxlegacyversion = ""
function SetRBXLegacyVersion(Version)
@@ -80,8 +79,10 @@ function SetRBXLegacyVersion(Version)
BottomRightControl.Position = UDim2.new(1,-BottomRightControl.AbsoluteSize.X,1,-BottomRightControl.AbsoluteSize.Y)
end
function makeXRelative()
- BottomLeftControl.SizeConstraint = 1
+ loadstring("\66\111\116\116\111\109\76\101\102\116\67\111\110\116\114\111\108\46\83\105\122\101\67\111\110\115\116\114\97\105\110\116\32\61\32\49\10\9\9\9\9\66\111\116\116\111\109\82\105\103\104\116\67\111\110\116\114\111\108\46\83\105\122\101\67\111\110\115\116\114\97\105\110\116\32\61\32\49")()
+ --[[BottomLeftControl.SizeConstraint = 1
BottomRightControl.SizeConstraint = 1
+ ]]--
if TopLeftControl then TopLeftControl.SizeConstraint = 1
end
if BuildTools then BuildTools.Frame.SizeConstraint = 1
@@ -127,13 +128,27 @@ function SetRBXLegacyVersion(Version)
elseif (rbxlegacyversion == "omega") then
settings().Rendering.FrameRateManager = 2
pcall(function() game:GetService("ScriptContext").ScriptsDisabled = false end)
- pcall(function() settings().Diagnostics:LegacyScriptMode() end)
- elseif (rbxlegacyversion == "ultra") then
+ pcall(function() settings().Diagnostics:LegacyScriptMode()
+ --stamper
+ game:GetService("InsertService"):SetBaseSetsUrl("http://www.roblox.com/Game/Tools/InsertAsset.ashx?nsets=10&type=base")
+ game:GetService("InsertService"):SetUserSetsUrl("http://www.roblox.com/Game/Tools/InsertAsset.ashx?nsets=20&type=user&userid=%d")
+ game:GetService("InsertService"):SetCollectionUrl("http://www.roblox.com/Game/Tools/InsertAsset.ashx?sid=%d")
+ game:GetService("InsertService"):SetAssetUrl("http://www.roblox.com/Asset/?id=%d")
+ game:GetService("InsertService"):SetAssetVersionUrl("http://www.roblox.com/Asset/?assetversionid=%d")
+ --[[corescripts
+ local RobloxGui = game:GetService("CoreGui"):WaitForChild("RobloxGui")
+ local scriptContext = game:GetService("ScriptContext")
+ scriptContext:AddCoreScript("CoreScripts/Playerlist", RobloxGui)
+ scriptContext:AddCoreScript("CoreScripts/GameMenu", RobloxGui)
+ scriptContext:AddCoreScript("CoreScripts/BackpackFull", RobloxGui)
+ ]]--todo: file:// (rbxasset://) and the corescript adder thing
+ end)
+ --[[elseif (rbxlegacyversion == "ultra") then
settings().Rendering.FrameRateManager = 2
pcall(function() game:GetService("ScriptContext").ScriptsDisabled = false end)
- pcall(function() settings().Diagnostics:LegacyScriptMode() end)
+ pcall(function() settings().Diagnostics:LegacyScriptMode() end)]]--we aren't ready for this yet
end
- print("RBXLegacy client opration set to '" .. rbxlegacyversion .. "'.")
+ print("RBXLegacy client operation set to '" .. rbxlegacyversion .. "'.")
end
rbxversion = version()
@@ -150,6 +165,8 @@ function newWaitForChild(newParent,name)
end
function LoadCharacterNew(playerApp,newChar)
+ --authentic roblox style loading
+ wait(0.5)
local charparts = {[1] = newWaitForChild(newChar,"Head"),[2] = newWaitForChild(newChar,"Torso"),[3] = newWaitForChild(newChar,"Left Arm"),[4] = newWaitForChild(newChar,"Right Arm"),[5] = newWaitForChild(newChar,"Left Leg"),[6] = newWaitForChild(newChar,"Right Leg")}
for _,newVal in pairs(playerApp:GetChildren()) do
if (newVal.CustomizationType.Value == 1) then
@@ -366,6 +383,7 @@ function InitalizeClientAppearance(Player,Hat1ID,Hat2ID,Hat3ID,HeadColorID,Torso
typeValue.Name = "CustomizationType"
typeValue.Parent = newFace
typeValue.Value = 6
+ --BODY PARTS
end
function CSServer(Port,PlayerLimit)
@@ -414,7 +432,7 @@ function CSServer(Port,PlayerLimit)
RunService = game:GetService("RunService")
Server:start(Port, 20)
RunService:run()
- game.Workspace:InsertContent("rbxasset://fonts/libraries.rbxm")
+ game.Workspace:InsertContent("rbxasset://fonts/libraries.rbxm")
game:GetService("Players").MaxPlayers = PlayerLimit
game:GetService("Players").PlayerAdded:connect(function(Player)
if (game:GetService("Players").NumPlayers > game:GetService("Players").MaxPlayers) then
@@ -559,11 +577,14 @@ function CSConnect(UserID,ServerIP,ServerPort,PlayerName,Hat1ID,Hat2ID,Hat3ID,He
elseif (rbxlegacyversion == "omega" or rbxlegacyversion == "delta-omega") then
game.CoreGui.RobloxGui.ControlFrame.BottomRightControl.Help:Remove()
game.CoreGui.RobloxGui.ControlFrame.BottomRightControl.ReportAbuse:Remove()
- game.CoreGui.RobloxGui.ControlFrame.BottomRightControl.RecordToggle.Position = UDim2.new(1, -150, 1, -40)
- game.CoreGui.RobloxGui.ControlFrame.BottomRightControl.Screenshot.Position = UDim2.new(1, -118, 1, -40)
- game.CoreGui.RobloxGui.ControlFrame.BottomRightControl.ToggleFullScreen.Position = UDim2.new(1, -85, 1, -48)
+ game.CoreGui.RobloxGui.ControlFrame.BottomRightControl.RecordToggle:Remove()
+ game.CoreGui.RobloxGui.ControlFrame.BottomRightControl.Screenshot:Remove()
+ game.CoreGui.RobloxGui.ControlFrame.BottomRightControl.ToggleFullScreen:Remove()
game.CoreGui.RobloxGui.ControlFrame.BottomLeftControl.TogglePlayMode:Remove()
game.CoreGui.RobloxGui.ControlFrame.BottomLeftControl.Exit:Remove()
+ wait(5) -- we have to wait until the menu gets built, don't we?
+ Player.PlayerGui.Menu.UserSettingsShield.Settings.SettingsStyle.GameSettingsMenu.FullscreenCheckbox:SetVerb("ToggleFullScreen")
+ Player.PlayerGui.Menu.UserSettingsShield.Settings.SettingsStyle.GameMainMenu.ScreenshotButton:SetVerb("Screenshot")
end
InitalizeClientAppearance(Player,Hat1ID,Hat2ID,Hat3ID,HeadColorID,TorsoColorID,LeftArmColorID,RightArmColorID,LeftLegColorID,RightLegColorID,TShirtID,ShirtID,PantsID,FaceID)
else
@@ -629,7 +650,7 @@ function CSConnect(UserID,ServerIP,ServerPort,PlayerName,Hat1ID,Hat2ID,Hat3ID,He
client.ConnectionRejected:connect(rejected)
client.ConnectionFailed:connect(failed)
client:Connect(ServerIP,ServerPort, 0, 20)
- end)
+ end)
end)
if not suc then
@@ -642,7 +663,7 @@ function CSConnect(UserID,ServerIP,ServerPort,PlayerName,Hat1ID,Hat2ID,Hat3ID,He
end
function CSSolo(UserID,PlayerName,Hat1ID,Hat2ID,Hat3ID,HeadColorID,TorsoColorID,LeftArmColorID,RightArmColorID,LeftLegColorID,RightLegColorID,TShirtID,ShirtID,PantsID,FaceID,IconType)
- if (rbxlegacyversion == "ultra" or rbxlegacyversion == "omega" or rbxlegacyversion == "delta-omega") then
+ if (rbxlegacyversion == "omega" or rbxlegacyversion == "delta-omega") then
game:GetService("RunService"):Run()
else
game:GetService("RunService"):run()
@@ -652,20 +673,26 @@ function CSSolo(UserID,PlayerName,Hat1ID,Hat2ID,Hat3ID,HeadColorID,TorsoColorID,
game.CoreGui.RobloxGui.TopLeftControl.Help:Remove()
elseif (rbxlegacyversion == "omega" or rbxlegacyversion == "delta-omega") then
game.CoreGui.RobloxGui.ControlFrame.BottomRightControl.Help:Remove()
- game.CoreGui.RobloxGui.ControlFrame.BottomRightControl.ReportAbuse:Remove()
- game.CoreGui.RobloxGui.ControlFrame.BottomRightControl.RecordToggle.Position = UDim2.new(1, -150, 1, -40)
- game.CoreGui.RobloxGui.ControlFrame.BottomRightControl.Screenshot.Position = UDim2.new(1, -118, 1, -40)
- game.CoreGui.RobloxGui.ControlFrame.BottomRightControl.ToggleFullScreen.Position = UDim2.new(1, -85, 1, -48)
- game.CoreGui.RobloxGui.ControlFrame.BottomLeftControl.TogglePlayMode:Remove()
+ game.CoreGui.RobloxGui.ControlFrame.BottomRightControl.ReportAbuse:Remove()
+ game.CoreGui.RobloxGui.ControlFrame.BottomRightControl.RecordToggle:Remove()
+ game.CoreGui.RobloxGui.ControlFrame.BottomRightControl.Screenshot:Remove()
+ game.CoreGui.RobloxGui.ControlFrame.BottomRightControl.ToggleFullScreen:Remove()
+ game.CoreGui.RobloxGui.ControlFrame.BottomLeftControl.TogglePlayMode:Remove()
game.CoreGui.RobloxGui.ControlFrame.BottomLeftControl.Exit:Remove()
- elseif (rbxlegacyversion == "ultra") then
- game.CoreGui.RobloxGui.ControlFrame.BottomRightControl:Remove()
end
+ --[[elseif (rbxlegacyversion == "ultra") then
+ game.CoreGui.RobloxGui.ControlFrame.BottomRightControl:Remove()
+ end]]
local plr = game.Players:CreateLocalPlayer(UserID)
plr.Name = PlayerName
plr:LoadCharacter()
+ if (rbxlegacyversion == "omega") then
+ wait(5) -- we have to wait until the menu gets built, don't we?
+ plr.PlayerGui.Menu.UserSettingsShield.Settings.SettingsStyle.GameSettingsMenu.FullscreenCheckbox:SetVerb("ToggleFullScreen")
+ plr.PlayerGui.Menu.UserSettingsShield.Settings.SettingsStyle.GameMainMenu.ScreenshotButton:SetVerb("Screenshot")
+ end
pcall(function() plr:SetUnder13(false) end)
- if (rbxlegacyversion == "delta" or rbxlegacyversion == "omega" or rbxlegacyversion == "delta-omega" or rbxlegacyversion == "ultra") then
+ if (rbxlegacyversion == "delta" or rbxlegacyversion == "omega" or rbxlegacyversion == "delta-omega") then
if (IconType == "BC") then
plr:SetMembershipType(Enum.MembershipType.BuildersClub)
elseif (IconType == "TBC") then
diff --git a/CoreGui2011.rbxm b/CoreGui2011.rbxm
deleted file mode 100644
index 6cb363e..0000000
--- a/CoreGui2011.rbxm
+++ /dev/null
@@ -1,6463 +0,0 @@
-
- null
- nil
- -
-
- false
-
- GUI_Copy
- script.Playerlist:clone().Parent = game.StarterGui
-script:remove()
- true
-
-
-
-
- Playerlist
- true
-
-
-
-
- false
-
- Init
- --rbxsig%bMgJMPt2chG7JIOhV0y5so/4dL1lRGiT3ELG0LsKh4QrqkG8sRdndraomuViGbDkVOWLXwIilzkhlSJSCjgZ9zXp6fS+SekW/n/RVWjNLA/gPThKLVxP6HmHRK9WTzIQ4ZTXjBmaExcdxBb1remqDPHWHlO2QoxZBqHs5sDGlQI=%
---rbxassetid%48488235%
---rbxsig%NGgzAS16V87kRv1YSTnTXts2fZjkDnnBr6KQq6h00V6iAQ8ZzNuc8zVRUQM/7krGgX+IJGvOqwZDpx1SiZICdYGcC6hhL0znChB4Stf54czFbYfp8ZY9k46+XGAFZtXYXuTLmIushHX/mDwEknP1qY16rTWjm/8J9o3nGx14W78=%
---rbxassetid%45284430%
---fixed by Carrot#0559
---for non corescript use
---rbxsig%IEUAo3Q1k4Rwb3ZcqPBum//j3+Jm/9Nv0JyCeCRWUrggWps7aG81/aPzlH9pPlMkkdsZwLsCRu6eTTrqzXn2DAJNPRs7y8akc3z91r1DP3jwomfpdT+2DBAmPk3Cdj8NXQzP6T+uEYm2kk2TW9pXonKvCgRVqXFx8J7mTr+aM1M=%
---rbxassetid%45284430%
-local t = {}
-
-local function ScopedConnect(parentInstance, instance, event, signalFunc, syncFunc, removeFunc)
- local eventConnection = nil
-
- --Connection on parentInstance is scoped by parentInstance (when destroyed, it goes away)
- local tryConnect = function()
- if game:IsAncestorOf(parentInstance) then
- --Entering the world, make sure we are connected/synced
- if not eventConnection then
- eventConnection = instance[event]:connect(signalFunc)
- if syncFunc then syncFunc() end
- end
- else
- --Probably leaving the world, so disconnect for now
- if eventConnection then
- eventConnection:disconnect()
- if removeFunc then removeFunc() end
- end
- end
- end
-
- --Hook it up to ancestryChanged signal
- local connection = parentInstance.AncestryChanged:connect(tryConnect)
-
- --Now connect us if we're already in the world
- tryConnect()
-
- return connection
-end
-
-local function getScreenGuiAncestor(instance)
- local localInstance = instance
- while localInstance and not localInstance:IsA("ScreenGui") do
- localInstance = localInstance.Parent
- end
- return localInstance
-end
-
-local function CreateButtons(frame, buttons, yPos, ySize)
- local buttonNum = 1
- local buttonObjs = {}
- for i, obj in ipairs(buttons) do
- local button = Instance.new("TextButton")
- button.Name = "Button" .. buttonNum
- button.Font = Enum.Font.Arial
- button.FontSize = Enum.FontSize.Size18
- button.AutoButtonColor = true
- button.Modal = true
- if obj["Style"] then
- button.Style = obj.Style
- else
- button.Style = Enum.ButtonStyle.RobloxButton
- end
- if obj["ZIndex"] then
- button.ZIndex = obj.ZIndex
- end
- button.Text = obj.Text
- button.TextColor3 = Color3.new(1,1,1)
- button.MouseButton1Click:connect(obj.Function)
- button.Parent = frame
- buttonObjs[buttonNum] = button
-
- buttonNum = buttonNum + 1
- end
- local numButtons = buttonNum-1
-
- if numButtons == 1 then
- frame.Button1.Position = UDim2.new(0.35, 0, yPos.Scale, yPos.Offset)
- frame.Button1.Size = UDim2.new(.4,0,ySize.Scale, ySize.Offset)
- elseif numButtons == 2 then
- frame.Button1.Position = UDim2.new(0.1, 0, yPos.Scale, yPos.Offset)
- frame.Button1.Size = UDim2.new(.8/3,0, ySize.Scale, ySize.Offset)
-
- frame.Button2.Position = UDim2.new(0.55, 0, yPos.Scale, yPos.Offset)
- frame.Button2.Size = UDim2.new(.35,0, ySize.Scale, ySize.Offset)
- elseif numButtons >= 3 then
- local spacing = .1 / numButtons
- local buttonSize = .9 / numButtons
-
- buttonNum = 1
- while buttonNum <= numButtons do
- buttonObjs[buttonNum].Position = UDim2.new(spacing*buttonNum + (buttonNum-1) * buttonSize, 0, yPos.Scale, yPos.Offset)
- buttonObjs[buttonNum].Size = UDim2.new(buttonSize, 0, ySize.Scale, ySize.Offset)
- buttonNum = buttonNum + 1
- end
- end
-end
-
-local function setSliderPos(newAbsPosX,slider,sliderPosition,bar,steps)
-
- local newStep = steps - 1 --otherwise we really get one more step than we want
- local relativePosX = math.min(1, math.max(0, (newAbsPosX - bar.AbsolutePosition.X) / bar.AbsoluteSize.X ))
- local wholeNum, remainder = math.modf(relativePosX * newStep)
- if remainder > 0.5 then
- wholeNum = wholeNum + 1
- end
- relativePosX = wholeNum/newStep
-
- local result = math.ceil(relativePosX * newStep)
- if sliderPosition.Value ~= (result + 1) then --only update if we moved a step
- sliderPosition.Value = result + 1
- slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
- end
-
-end
-
-local function cancelSlide(areaSoak)
- areaSoak.Visible = false
- if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
-end
-
-t.CreateStyledMessageDialog = function(title, message, style, buttons)
- local frame = Instance.new("Frame")
- frame.Size = UDim2.new(0.5, 0, 0, 165)
- frame.Position = UDim2.new(0.25, 0, 0.5, -72.5)
- frame.Name = "MessageDialog"
- frame.Active = true
- frame.Style = Enum.FrameStyle.RobloxRound
-
- local styleImage = Instance.new("ImageLabel")
- styleImage.Name = "StyleImage"
- styleImage.BackgroundTransparency = 1
- styleImage.Position = UDim2.new(0,5,0,15)
- if style == "error" or style == "Error" then
- styleImage.Size = UDim2.new(0, 71, 0, 71)
- styleImage.Image = "http://www.roblox.com/asset/?id=42565285"
- elseif style == "notify" or style == "Notify" then
- styleImage.Size = UDim2.new(0, 71, 0, 71)
- styleImage.Image = "http://www.roblox.com/asset/?id=42604978"
- elseif style == "confirm" or style == "Confirm" then
- styleImage.Size = UDim2.new(0, 74, 0, 76)
- styleImage.Image = "http://www.roblox.com/asset/?id=42557901"
- else
- return t.CreateMessageDialog(title,message,buttons)
- end
- styleImage.Parent = frame
-
- local titleLabel = Instance.new("TextLabel")
- titleLabel.Name = "Title"
- titleLabel.Text = title
- titleLabel.TextStrokeTransparency = 0
- titleLabel.BackgroundTransparency = 1
- titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
- titleLabel.Position = UDim2.new(0, 80, 0, 0)
- titleLabel.Size = UDim2.new(1, -80, 0, 40)
- titleLabel.Font = Enum.Font.ArialBold
- titleLabel.FontSize = Enum.FontSize.Size36
- titleLabel.TextXAlignment = Enum.TextXAlignment.Center
- titleLabel.TextYAlignment = Enum.TextYAlignment.Center
- titleLabel.Parent = frame
-
- local messageLabel = Instance.new("TextLabel")
- messageLabel.Name = "Message"
- messageLabel.Text = message
- messageLabel.TextStrokeTransparency = 0
- messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
- messageLabel.Position = UDim2.new(0.025, 80, 0, 45)
- messageLabel.Size = UDim2.new(0.95, -80, 0, 55)
- messageLabel.BackgroundTransparency = 1
- messageLabel.Font = Enum.Font.Arial
- messageLabel.FontSize = Enum.FontSize.Size18
- messageLabel.TextWrap = true
- messageLabel.TextXAlignment = Enum.TextXAlignment.Left
- messageLabel.TextYAlignment = Enum.TextYAlignment.Top
- messageLabel.Parent = frame
-
- CreateButtons(frame, buttons, UDim.new(0, 105), UDim.new(0, 40) )
-
- return frame
-end
-
-t.CreateMessageDialog = function(title, message, buttons)
- local frame = Instance.new("Frame")
- frame.Size = UDim2.new(0.5, 0, 0.5, 0)
- frame.Position = UDim2.new(0.25, 0, 0.25, 0)
- frame.Name = "MessageDialog"
- frame.Active = true
- frame.Style = Enum.FrameStyle.RobloxRound
-
- local titleLabel = Instance.new("TextLabel")
- titleLabel.Name = "Title"
- titleLabel.Text = title
- titleLabel.BackgroundTransparency = 1
- titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
- titleLabel.Position = UDim2.new(0, 0, 0, 0)
- titleLabel.Size = UDim2.new(1, 0, 0.15, 0)
- titleLabel.Font = Enum.Font.ArialBold
- titleLabel.FontSize = Enum.FontSize.Size36
- titleLabel.TextXAlignment = Enum.TextXAlignment.Center
- titleLabel.TextYAlignment = Enum.TextYAlignment.Center
- titleLabel.Parent = frame
-
- local messageLabel = Instance.new("TextLabel")
- messageLabel.Name = "Message"
- messageLabel.Text = message
- messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
- messageLabel.Position = UDim2.new(0.025, 0, 0.175, 0)
- messageLabel.Size = UDim2.new(0.95, 0, .55, 0)
- messageLabel.BackgroundTransparency = 1
- messageLabel.Font = Enum.Font.Arial
- messageLabel.FontSize = Enum.FontSize.Size18
- messageLabel.TextWrap = true
- messageLabel.TextXAlignment = Enum.TextXAlignment.Left
- messageLabel.TextYAlignment = Enum.TextYAlignment.Top
- messageLabel.Parent = frame
-
- CreateButtons(frame, buttons, UDim.new(0.8,0), UDim.new(0.15, 0))
-
- return frame
-end
-
-t.CreateDropDownMenu = function(items, onSelect, forRoblox, whiteSkin, baseZ)
- local baseZIndex = 0
- if (type(baseZ) == "number") then
- baseZIndex = baseZ
- end
- local width = UDim.new(0, 100)
- local height = UDim.new(0, 32)
-
- local xPos = 0.055
- local frame = Instance.new("Frame")
- local textColor = Color3.new(1,1,1)
- if (whiteSkin) then
- textColor = Color3.new(0.5, 0.5, 0.5)
- end
- frame.Name = "DropDownMenu"
- frame.BackgroundTransparency = 1
- frame.Size = UDim2.new(width, height)
-
- local dropDownMenu = Instance.new("TextButton")
- dropDownMenu.Name = "DropDownMenuButton"
- dropDownMenu.TextWrap = true
- dropDownMenu.TextColor3 = textColor
- dropDownMenu.Text = "Choose One"
- dropDownMenu.Font = Enum.Font.ArialBold
- dropDownMenu.FontSize = Enum.FontSize.Size18
- dropDownMenu.TextXAlignment = Enum.TextXAlignment.Left
- dropDownMenu.TextYAlignment = Enum.TextYAlignment.Center
- dropDownMenu.BackgroundTransparency = 1
- dropDownMenu.AutoButtonColor = true
- if (whiteSkin) then
- dropDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton
- else
- dropDownMenu.Style = Enum.ButtonStyle.RobloxButton
- end
- dropDownMenu.Size = UDim2.new(1,0,1,0)
- dropDownMenu.Parent = frame
- dropDownMenu.ZIndex = 2 + baseZIndex
-
- local dropDownIcon = Instance.new("ImageLabel")
- dropDownIcon.Name = "Icon"
- dropDownIcon.Active = false
- if (whiteSkin) then
- dropDownIcon.Image = "rbxasset://textures/ui/dropdown_arrow.png"
- dropDownIcon.Size = UDim2.new(0,16,0,12)
- dropDownIcon.Position = UDim2.new(1,-17,0.5, -6)
- else
- dropDownIcon.Image = "http://www.roblox.com/asset/?id=45732894"
- dropDownIcon.Size = UDim2.new(0,11,0,6)
- dropDownIcon.Position = UDim2.new(1,-11,0.5, -2)
- end
- dropDownIcon.BackgroundTransparency = 1
- dropDownIcon.Parent = dropDownMenu
- dropDownIcon.ZIndex = 2 + baseZIndex
-
- local itemCount = #items
- local dropDownItemCount = #items
- local useScrollButtons = false
- if dropDownItemCount > 6 then
- useScrollButtons = true
- dropDownItemCount = 6
- end
-
- local droppedDownMenu = Instance.new("TextButton")
- droppedDownMenu.Name = "List"
- droppedDownMenu.Text = ""
- droppedDownMenu.BackgroundTransparency = 1
- --droppedDownMenu.AutoButtonColor = true
- if (whiteSkin) then
- droppedDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton
- else
- droppedDownMenu.Style = Enum.ButtonStyle.RobloxButton
- end
- droppedDownMenu.Visible = false
- droppedDownMenu.Active = true --Blocks clicks
- droppedDownMenu.Position = UDim2.new(0,0,0,0)
- droppedDownMenu.Size = UDim2.new(1,0, (1 + dropDownItemCount)*.8, 0)
- droppedDownMenu.Parent = frame
- droppedDownMenu.ZIndex = 2 + baseZIndex
-
- local choiceButton = Instance.new("TextButton")
- choiceButton.Name = "ChoiceButton"
- choiceButton.BackgroundTransparency = 1
- choiceButton.BorderSizePixel = 0
- choiceButton.Text = "ReplaceMe"
- choiceButton.TextColor3 = textColor
- choiceButton.TextXAlignment = Enum.TextXAlignment.Left
- choiceButton.TextYAlignment = Enum.TextYAlignment.Center
- choiceButton.BackgroundColor3 = Color3.new(1, 1, 1)
- choiceButton.Font = Enum.Font.Arial
- choiceButton.FontSize = Enum.FontSize.Size18
- if useScrollButtons then
- choiceButton.Size = UDim2.new(1,-13, .8/((dropDownItemCount + 1)*.8),0)
- else
- choiceButton.Size = UDim2.new(1, 0, .8/((dropDownItemCount + 1)*.8),0)
- end
- choiceButton.TextWrap = true
- choiceButton.ZIndex = 2 + baseZIndex
-
- local areaSoak = Instance.new("TextButton")
- areaSoak.Name = "AreaSoak"
- areaSoak.Text = ""
- areaSoak.BackgroundTransparency = 1
- areaSoak.Active = true
- areaSoak.Size = UDim2.new(1,0,1,0)
- areaSoak.Visible = false
- areaSoak.ZIndex = 3 + baseZIndex
-
- local dropDownSelected = false
-
- local scrollUpButton
- local scrollDownButton
- local scrollMouseCount = 0
-
- local setZIndex = function(baseZIndex)
- droppedDownMenu.ZIndex = baseZIndex +1
- if scrollUpButton then
- scrollUpButton.ZIndex = baseZIndex + 3
- end
- if scrollDownButton then
- scrollDownButton.ZIndex = baseZIndex + 3
- end
-
- local children = droppedDownMenu:GetChildren()
- if children then
- for i, child in ipairs(children) do
- if child.Name == "ChoiceButton" then
- child.ZIndex = baseZIndex + 2
- elseif child.Name == "ClickCaptureButton" then
- child.ZIndex = baseZIndex
- end
- end
- end
- end
-
- local scrollBarPosition = 1
- local updateScroll = function()
- if scrollUpButton then
- scrollUpButton.Active = scrollBarPosition > 1
- end
- if scrollDownButton then
- scrollDownButton.Active = scrollBarPosition + dropDownItemCount <= itemCount
- end
-
- local children = droppedDownMenu:GetChildren()
- if not children then return end
-
- local childNum = 1
- for i, obj in ipairs(children) do
- if obj.Name == "ChoiceButton" then
- if childNum < scrollBarPosition or childNum >= scrollBarPosition + dropDownItemCount then
- obj.Visible = false
- else
- obj.Position = UDim2.new(0,0,((childNum-scrollBarPosition+1)*.8)/((dropDownItemCount+1)*.8),0)
- obj.Visible = true
- end
- obj.TextColor3 = textColor
- obj.BackgroundTransparency = 1
-
- childNum = childNum + 1
- end
- end
- end
- local toggleVisibility = function()
- dropDownSelected = not dropDownSelected
-
- areaSoak.Visible = not areaSoak.Visible
- dropDownMenu.Visible = not dropDownSelected
- droppedDownMenu.Visible = dropDownSelected
- if dropDownSelected then
- setZIndex(4 + baseZIndex)
- else
- setZIndex(2 + baseZIndex)
- end
- if useScrollButtons then
- updateScroll()
- end
- end
- droppedDownMenu.MouseButton1Click:connect(toggleVisibility)
-
- local updateSelection = function(text)
- local foundItem = false
- local children = droppedDownMenu:GetChildren()
- local childNum = 1
- if children then
- for i, obj in ipairs(children) do
- if obj.Name == "ChoiceButton" then
- if obj.Text == text then
- obj.Font = Enum.Font.ArialBold
- foundItem = true
- scrollBarPosition = childNum
- if (whiteSkin) then
- obj.TextColor3 = Color3.new(90/255,142/255,233/255)
- end
- else
- obj.Font = Enum.Font.Arial
- if (whiteSkin) then
- obj.TextColor3 = textColor
- end
- end
- childNum = childNum + 1
- end
- end
- end
- if not text then
- dropDownMenu.Text = "Choose One"
- scrollBarPosition = 1
- else
- if not foundItem then
- error("Invalid Selection Update -- " .. text)
- end
-
- if scrollBarPosition + dropDownItemCount > itemCount + 1 then
- scrollBarPosition = itemCount - dropDownItemCount + 1
- end
-
- dropDownMenu.Text = text
- end
- end
-
- local function scrollDown()
- if scrollBarPosition + dropDownItemCount <= itemCount then
- scrollBarPosition = scrollBarPosition + 1
- updateScroll()
- return true
- end
- return false
- end
- local function scrollUp()
- if scrollBarPosition > 1 then
- scrollBarPosition = scrollBarPosition - 1
- updateScroll()
- return true
- end
- return false
- end
-
- if useScrollButtons then
- --Make some scroll buttons
- scrollUpButton = Instance.new("ImageButton")
- scrollUpButton.Name = "ScrollUpButton"
- scrollUpButton.BackgroundTransparency = 1
- scrollUpButton.Image = "rbxasset://textures/ui/scrollbuttonUp.png"
- scrollUpButton.Size = UDim2.new(0,17,0,17)
- scrollUpButton.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),0)
- scrollUpButton.MouseButton1Click:connect(
- function()
- scrollMouseCount = scrollMouseCount + 1
- end)
- scrollUpButton.MouseLeave:connect(
- function()
- scrollMouseCount = scrollMouseCount + 1
- end)
- scrollUpButton.MouseButton1Down:connect(
- function()
- scrollMouseCount = scrollMouseCount + 1
-
- scrollUp()
- local val = scrollMouseCount
- wait(0.5)
- while val == scrollMouseCount do
- if scrollUp() == false then
- break
- end
- wait(0.1)
- end
- end)
-
- scrollUpButton.Parent = droppedDownMenu
-
- scrollDownButton = Instance.new("ImageButton")
- scrollDownButton.Name = "ScrollDownButton"
- scrollDownButton.BackgroundTransparency = 1
- scrollDownButton.Image = "rbxasset://textures/ui/scrollbuttonDown.png"
- scrollDownButton.Size = UDim2.new(0,17,0,17)
- scrollDownButton.Position = UDim2.new(1,-11,1,-11)
- scrollDownButton.Parent = droppedDownMenu
- scrollDownButton.MouseButton1Click:connect(
- function()
- scrollMouseCount = scrollMouseCount + 1
- end)
- scrollDownButton.MouseLeave:connect(
- function()
- scrollMouseCount = scrollMouseCount + 1
- end)
- scrollDownButton.MouseButton1Down:connect(
- function()
- scrollMouseCount = scrollMouseCount + 1
-
- scrollDown()
- local val = scrollMouseCount
- wait(0.5)
- while val == scrollMouseCount do
- if scrollDown() == false then
- break
- end
- wait(0.1)
- end
- end)
-
- local scrollbar = Instance.new("ImageLabel")
- scrollbar.Name = "ScrollBar"
- scrollbar.Image = "rbxasset://textures/ui/scrollbar.png"
- scrollbar.BackgroundTransparency = 1
- scrollbar.Size = UDim2.new(0, 18, (dropDownItemCount*.8)/((dropDownItemCount+1)*.8), -(17) - 11 - 4)
- scrollbar.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),17+2)
- scrollbar.Parent = droppedDownMenu
- end
-
- for i,item in ipairs(items) do
- -- needed to maintain local scope for items in event listeners below
- local button = choiceButton:clone()
- if forRoblox then
- button.RobloxLocked = true
- end
- button.Text = item
- button.Parent = droppedDownMenu
- if (whiteSkin) then
- button.TextColor3 = textColor
- end
-
- button.MouseButton1Click:connect(function()
- --Remove Highlight
- if (not whiteSkin) then
- button.TextColor3 = Color3.new(1,1,1)
- end
- button.BackgroundTransparency = 1
-
- updateSelection(item)
- onSelect(item)
-
- toggleVisibility()
- end)
- button.MouseEnter:connect(function()
- --Add Highlight
- if (not whiteSkin) then
- button.TextColor3 = Color3.new(0,0,0)
- end
- button.BackgroundTransparency = 0
- end)
-
- button.MouseLeave:connect(function()
- --Remove Highlight
- if (not whiteSkin) then
- button.TextColor3 = Color3.new(1,1,1)
- end
- button.BackgroundTransparency = 1
- end)
- end
-
- --This does the initial layout of the buttons
- updateScroll()
-
- frame.AncestryChanged:connect(function(child,parent)
- if parent == nil then
- areaSoak.Parent = nil
- else
- areaSoak.Parent = getScreenGuiAncestor(frame)
- end
- end)
-
- dropDownMenu.MouseButton1Click:connect(toggleVisibility)
- areaSoak.MouseButton1Click:connect(toggleVisibility)
- return frame, updateSelection
-end
-
-t.CreatePropertyDropDownMenu = function(instance, property, enum)
-
- local items = enum:GetEnumItems()
- local names = {}
- local nameToItem = {}
- for i,obj in ipairs(items) do
- names[i] = obj.Name
- nameToItem[obj.Name] = obj
- end
-
- local frame
- local updateSelection
- frame, updateSelection = t.CreateDropDownMenu(names, function(text) instance[property] = nameToItem[text] end)
-
- ScopedConnect(frame, instance, "Changed",
- function(prop)
- if prop == property then
- updateSelection(instance[property].Name)
- end
- end,
- function()
- updateSelection(instance[property].Name)
- end)
-
- return frame
-end
-
-t.GetFontHeight = function(font, fontSize)
- if font == nil or fontSize == nil then
- error("Font and FontSize must be non-nil")
- end
-
- if font == Enum.Font.Legacy then
- if fontSize == Enum.FontSize.Size8 then
- return 12
- elseif fontSize == Enum.FontSize.Size9 then
- return 14
- elseif fontSize == Enum.FontSize.Size10 then
- return 15
- elseif fontSize == Enum.FontSize.Size11 then
- return 17
- elseif fontSize == Enum.FontSize.Size12 then
- return 18
- elseif fontSize == Enum.FontSize.Size14 then
- return 21
- elseif fontSize == Enum.FontSize.Size18 then
- return 27
- elseif fontSize == Enum.FontSize.Size24 then
- return 36
- elseif fontSize == Enum.FontSize.Size36 then
- return 54
- elseif fontSize == Enum.FontSize.Size48 then
- return 72
- else
- error("Unknown FontSize")
- end
- elseif font == Enum.Font.Arial or font == Enum.Font.ArialBold then
- if fontSize == Enum.FontSize.Size8 then
- return 8
- elseif fontSize == Enum.FontSize.Size9 then
- return 9
- elseif fontSize == Enum.FontSize.Size10 then
- return 10
- elseif fontSize == Enum.FontSize.Size11 then
- return 11
- elseif fontSize == Enum.FontSize.Size12 then
- return 12
- elseif fontSize == Enum.FontSize.Size14 then
- return 14
- elseif fontSize == Enum.FontSize.Size18 then
- return 18
- elseif fontSize == Enum.FontSize.Size24 then
- return 24
- elseif fontSize == Enum.FontSize.Size36 then
- return 36
- elseif fontSize == Enum.FontSize.Size48 then
- return 48
- else
- error("Unknown FontSize")
- end
- else
- error("Unknown Font " .. font)
- end
-end
-
-local function layoutGuiObjectsHelper(frame, guiObjects, settingsTable)
- local totalPixels = frame.AbsoluteSize.Y
- local pixelsRemaining = frame.AbsoluteSize.Y
- for i, child in ipairs(guiObjects) do
- if child:IsA("TextLabel") or child:IsA("TextButton") then
- local isLabel = child:IsA("TextLabel")
- if isLabel then
- pixelsRemaining = pixelsRemaining - settingsTable["TextLabelPositionPadY"]
- else
- pixelsRemaining = pixelsRemaining - settingsTable["TextButtonPositionPadY"]
- end
- child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
- child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, pixelsRemaining)
-
- if child.TextFits and child.TextBounds.Y < pixelsRemaining then
- child.Visible = true
- if isLabel then
- child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable["TextLabelSizePadY"])
- else
- child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable["TextButtonSizePadY"])
- end
-
- while not child.TextFits do
- child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.AbsoluteSize.Y + 1)
- end
- pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
-
- if isLabel then
- pixelsRemaining = pixelsRemaining - settingsTable["TextLabelPositionPadY"]
- else
- pixelsRemaining = pixelsRemaining - settingsTable["TextButtonPositionPadY"]
- end
- else
- child.Visible = false
- pixelsRemaining = -1
- end
-
- else
- --GuiObject
- child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
- pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
- child.Visible = (pixelsRemaining >= 0)
- end
- end
-end
-
-t.LayoutGuiObjects = function(frame, guiObjects, settingsTable)
- if not frame:IsA("GuiObject") then
- error("Frame must be a GuiObject")
- end
- for i, child in ipairs(guiObjects) do
- if not child:IsA("GuiObject") then
- error("All elements that are layed out must be of type GuiObject")
- end
- end
-
- if not settingsTable then
- settingsTable = {}
- end
-
- if not settingsTable["TextLabelSizePadY"] then
- settingsTable["TextLabelSizePadY"] = 0
- end
- if not settingsTable["TextLabelPositionPadY"] then
- settingsTable["TextLabelPositionPadY"] = 0
- end
- if not settingsTable["TextButtonSizePadY"] then
- settingsTable["TextButtonSizePadY"] = 12
- end
- if not settingsTable["TextButtonPositionPadY"] then
- settingsTable["TextButtonPositionPadY"] = 2
- end
-
- --Wrapper frame takes care of styled objects
- local wrapperFrame = Instance.new("Frame")
- wrapperFrame.Name = "WrapperFrame"
- wrapperFrame.BackgroundTransparency = 1
- wrapperFrame.Size = UDim2.new(1,0,1,0)
- wrapperFrame.Parent = frame
-
- for i, child in ipairs(guiObjects) do
- child.Parent = wrapperFrame
- end
-
- local recalculate = function()
- wait()
- layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable)
- end
-
- frame.Changed:connect(
- function(prop)
- if prop == "AbsoluteSize" then
- --Wait a heartbeat for it to sync in
- recalculate(nil)
- end
- end)
- frame.AncestryChanged:connect(recalculate)
-
- layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable)
-end
-
-
-t.CreateSlider = function(steps,width,position)
- local sliderGui = Instance.new("Frame")
- sliderGui.Size = UDim2.new(1,0,1,0)
- sliderGui.BackgroundTransparency = 1
- sliderGui.Name = "SliderGui"
-
- local sliderSteps = Instance.new("IntValue")
- sliderSteps.Name = "SliderSteps"
- sliderSteps.Value = steps
- sliderSteps.Parent = sliderGui
-
- local areaSoak = Instance.new("TextButton")
- areaSoak.Name = "AreaSoak"
- areaSoak.Text = ""
- areaSoak.BackgroundTransparency = 1
- areaSoak.Active = false
- areaSoak.Size = UDim2.new(1,0,1,0)
- areaSoak.Visible = false
- areaSoak.ZIndex = 4
-
- sliderGui.AncestryChanged:connect(function(child,parent)
- if parent == nil then
- areaSoak.Parent = nil
- else
- areaSoak.Parent = getScreenGuiAncestor(sliderGui)
- end
- end)
-
- local sliderPosition = Instance.new("IntValue")
- sliderPosition.Name = "SliderPosition"
- sliderPosition.Value = 0
- sliderPosition.Parent = sliderGui
-
- local id = math.random(1,100)
-
- local bar = Instance.new("TextButton")
- bar.Text = ""
- bar.AutoButtonColor = false
- bar.Name = "Bar"
- bar.BackgroundColor3 = Color3.new(0,0,0)
- if type(width) == "number" then
- bar.Size = UDim2.new(0,width,0,5)
- else
- bar.Size = UDim2.new(0,200,0,5)
- end
- bar.BorderColor3 = Color3.new(95/255,95/255,95/255)
- bar.ZIndex = 2
- bar.Parent = sliderGui
-
- if position["X"] and position["X"]["Scale"] and position["X"]["Offset"] and position["Y"] and position["Y"]["Scale"] and position["Y"]["Offset"] then
- bar.Position = position
- end
-
- local slider = Instance.new("ImageButton")
- slider.Name = "Slider"
- slider.BackgroundTransparency = 1
- slider.Image = "rbxasset://textures/ui/Slider.png"
- slider.Position = UDim2.new(0,0,0.5,-10)
- slider.Size = UDim2.new(0,20,0,20)
- slider.ZIndex = 3
- slider.Parent = bar
-
- local areaSoakMouseMoveCon = nil
-
- areaSoak.MouseLeave:connect(function()
- if areaSoak.Visible then
- cancelSlide(areaSoak)
- end
- end)
- areaSoak.MouseButton1Up:connect(function()
- if areaSoak.Visible then
- cancelSlide(areaSoak)
- end
- end)
-
- slider.MouseButton1Down:connect(function()
- areaSoak.Visible = true
- if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
- areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y)
- setSliderPos(x,slider,sliderPosition,bar,steps)
- end)
- end)
-
- slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end)
-
- sliderPosition.Changed:connect(function(prop)
- sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value))
- local relativePosX = (sliderPosition.Value - 1) / (steps - 1)
- slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
- end)
-
- bar.MouseButton1Down:connect(function(x,y)
- setSliderPos(x,slider,sliderPosition,bar,steps)
- end)
-
- return sliderGui, sliderPosition, sliderSteps
-
-end
-
-
-
-t.CreateSliderNew = function(steps,width,position)
- local sliderGui = Instance.new("Frame")
- sliderGui.Size = UDim2.new(1,0,1,0)
- sliderGui.BackgroundTransparency = 1
- sliderGui.Name = "SliderGui"
-
- local sliderSteps = Instance.new("IntValue")
- sliderSteps.Name = "SliderSteps"
- sliderSteps.Value = steps
- sliderSteps.Parent = sliderGui
-
- local areaSoak = Instance.new("TextButton")
- areaSoak.Name = "AreaSoak"
- areaSoak.Text = ""
- areaSoak.BackgroundTransparency = 1
- areaSoak.Active = false
- areaSoak.Size = UDim2.new(1,0,1,0)
- areaSoak.Visible = false
- areaSoak.ZIndex = 6
-
- sliderGui.AncestryChanged:connect(function(child,parent)
- if parent == nil then
- areaSoak.Parent = nil
- else
- areaSoak.Parent = getScreenGuiAncestor(sliderGui)
- end
- end)
-
- local sliderPosition = Instance.new("IntValue")
- sliderPosition.Name = "SliderPosition"
- sliderPosition.Value = 0
- sliderPosition.Parent = sliderGui
-
- local id = math.random(1,100)
-
- local sliderBarImgHeight = 7
- local sliderBarCapImgWidth = 4
-
- local bar = Instance.new("ImageButton")
- bar.BackgroundTransparency = 1
- bar.Image = "rbxasset://textures/ui/Slider-BKG-Center.png"
- bar.Name = "Bar"
- local displayWidth = 200
- if type(width) == "number" then
- bar.Size = UDim2.new(0,width - (sliderBarCapImgWidth * 2),0,sliderBarImgHeight)
- displayWidth = width - (sliderBarCapImgWidth * 2)
- else
- bar.Size = UDim2.new(0,200,0,sliderBarImgHeight)
- end
- bar.ZIndex = 3
- bar.Parent = sliderGui
- if position["X"] and position["X"]["Scale"] and position["X"]["Offset"] and position["Y"] and position["Y"]["Scale"] and position["Y"]["Offset"] then
- bar.Position = position
- end
-
- local barLeft = bar:clone()
- barLeft.Name = "BarLeft"
- barLeft.Image = "rbxasset://textures/ui/Slider-BKG-Left-Cap.png"
- barLeft.Size = UDim2.new(0, sliderBarCapImgWidth, 0, sliderBarImgHeight)
- barLeft.Position = UDim2.new(position.X.Scale, position.X.Offset - sliderBarCapImgWidth, position.Y.Scale, position.Y.Offset)
- barLeft.Parent = sliderGui
- barLeft.ZIndex = 3
-
- local barRight = barLeft:clone()
- barRight.Name = "BarRight"
- barRight.Image = "rbxasset://textures/ui/Slider-BKG-Right-Cap.png"
- barRight.Position = UDim2.new(position.X.Scale, position.X.Offset + displayWidth, position.Y.Scale, position.Y.Offset)
- barRight.Parent = sliderGui
-
- local fillLeft = barLeft:clone()
- fillLeft.Name = "FillLeft"
- fillLeft.Image = "rbxasset://textures/ui/Slider-Fill-Left-Cap.png"
- fillLeft.Parent = sliderGui
- fillLeft.ZIndex = 4
-
- local fill = fillLeft:clone()
- fill.Name = "Fill"
- fill.Image = "rbxasset://textures/ui/Slider-Fill-Center.png"
- fill.Parent = bar
- fill.ZIndex = 4
- fill.Position = UDim2.new(0, 0, 0, 0)
- fill.Size = UDim2.new(0.5, 0, 1, 0)
-
-
--- bar.Visible = false
-
- local slider = Instance.new("ImageButton")
- slider.Name = "Slider"
- slider.BackgroundTransparency = 1
- slider.Image = "rbxasset://textures/ui/slider_new_tab.png"
- slider.Position = UDim2.new(0,0,0.5,-14)
- slider.Size = UDim2.new(0,28,0,28)
- slider.ZIndex = 5
- slider.Parent = bar
-
- local areaSoakMouseMoveCon = nil
-
- areaSoak.MouseLeave:connect(function()
- if areaSoak.Visible then
- cancelSlide(areaSoak)
- end
- end)
- areaSoak.MouseButton1Up:connect(function()
- if areaSoak.Visible then
- cancelSlide(areaSoak)
- end
- end)
-
- slider.MouseButton1Down:connect(function()
- areaSoak.Visible = true
- if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
- areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y)
- setSliderPos(x,slider,sliderPosition,bar,steps)
- end)
- end)
-
- slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end)
-
- sliderPosition.Changed:connect(function(prop)
- sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value))
- local relativePosX = (sliderPosition.Value - 1) / (steps - 1)
- slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
- fill.Size = UDim2.new(relativePosX, 0, 1, 0)
- end)
-
- bar.MouseButton1Down:connect(function(x,y)
- setSliderPos(x,slider,sliderPosition,bar,steps)
- end)
-
- return sliderGui, sliderPosition, sliderSteps
-
-end
-
-
-
-
-
-t.CreateTrueScrollingFrame = function()
- local lowY = nil
- local highY = nil
-
- local dragCon = nil
- local upCon = nil
-
- local internalChange = false
-
- local descendantsChangeConMap = {}
-
- local scrollingFrame = Instance.new("Frame")
- scrollingFrame.Name = "ScrollingFrame"
- scrollingFrame.Active = true
- scrollingFrame.Size = UDim2.new(1,0,1,0)
- scrollingFrame.ClipsDescendants = true
-
- local controlFrame = Instance.new("Frame")
- controlFrame.Name = "ControlFrame"
- controlFrame.BackgroundTransparency = 1
- controlFrame.Size = UDim2.new(0,18,1,0)
- controlFrame.Position = UDim2.new(1,-20,0,0)
- controlFrame.Parent = scrollingFrame
-
- local scrollBottom = Instance.new("BoolValue")
- scrollBottom.Value = false
- scrollBottom.Name = "ScrollBottom"
- scrollBottom.Parent = controlFrame
-
- local scrollUp = Instance.new("BoolValue")
- scrollUp.Value = false
- scrollUp.Name = "scrollUp"
- scrollUp.Parent = controlFrame
-
- local scrollUpButton = Instance.new("TextButton")
- scrollUpButton.Name = "ScrollUpButton"
- scrollUpButton.Text = ""
- scrollUpButton.AutoButtonColor = false
- scrollUpButton.BackgroundColor3 = Color3.new(0,0,0)
- scrollUpButton.BorderColor3 = Color3.new(1,1,1)
- scrollUpButton.BackgroundTransparency = 0.5
- scrollUpButton.Size = UDim2.new(0,18,0,18)
- scrollUpButton.ZIndex = 2
- scrollUpButton.Parent = controlFrame
- for i = 1, 6 do
- local triFrame = Instance.new("Frame")
- triFrame.BorderColor3 = Color3.new(1,1,1)
- triFrame.Name = "tri" .. tostring(i)
- triFrame.ZIndex = 3
- triFrame.BackgroundTransparency = 0.5
- triFrame.Size = UDim2.new(0,12 - ((i -1) * 2),0,0)
- triFrame.Position = UDim2.new(0,3 + (i -1),0.5,2 - (i -1))
- triFrame.Parent = scrollUpButton
- end
- scrollUpButton.MouseEnter:connect(function()
- scrollUpButton.BackgroundTransparency = 0.1
- local upChildren = scrollUpButton:GetChildren()
- for i = 1, #upChildren do
- upChildren[i].BackgroundTransparency = 0.1
- end
- end)
- scrollUpButton.MouseLeave:connect(function()
- scrollUpButton.BackgroundTransparency = 0.5
- local upChildren = scrollUpButton:GetChildren()
- for i = 1, #upChildren do
- upChildren[i].BackgroundTransparency = 0.5
- end
- end)
-
- local scrollDownButton = scrollUpButton:clone()
- scrollDownButton.Name = "ScrollDownButton"
- scrollDownButton.Position = UDim2.new(0,0,1,-18)
- local downChildren = scrollDownButton:GetChildren()
- for i = 1, #downChildren do
- downChildren[i].Position = UDim2.new(0,3 + (i -1),0.5,-2 + (i - 1))
- end
- scrollDownButton.MouseEnter:connect(function()
- scrollDownButton.BackgroundTransparency = 0.1
- local downChildren = scrollDownButton:GetChildren()
- for i = 1, #downChildren do
- downChildren[i].BackgroundTransparency = 0.1
- end
- end)
- scrollDownButton.MouseLeave:connect(function()
- scrollDownButton.BackgroundTransparency = 0.5
- local downChildren = scrollDownButton:GetChildren()
- for i = 1, #downChildren do
- downChildren[i].BackgroundTransparency = 0.5
- end
- end)
- scrollDownButton.Parent = controlFrame
-
- local scrollTrack = Instance.new("Frame")
- scrollTrack.Name = "ScrollTrack"
- scrollTrack.BackgroundTransparency = 1
- scrollTrack.Size = UDim2.new(0,18,1,-38)
- scrollTrack.Position = UDim2.new(0,0,0,19)
- scrollTrack.Parent = controlFrame
-
- local scrollbar = Instance.new("TextButton")
- scrollbar.BackgroundColor3 = Color3.new(0,0,0)
- scrollbar.BorderColor3 = Color3.new(1,1,1)
- scrollbar.BackgroundTransparency = 0.5
- scrollbar.AutoButtonColor = false
- scrollbar.Text = ""
- scrollbar.Active = true
- scrollbar.Name = "ScrollBar"
- scrollbar.ZIndex = 2
- scrollbar.BackgroundTransparency = 0.5
- scrollbar.Size = UDim2.new(0, 18, 0.1, 0)
- scrollbar.Position = UDim2.new(0,0,0,0)
- scrollbar.Parent = scrollTrack
-
- local scrollNub = Instance.new("Frame")
- scrollNub.Name = "ScrollNub"
- scrollNub.BorderColor3 = Color3.new(1,1,1)
- scrollNub.Size = UDim2.new(0,10,0,0)
- scrollNub.Position = UDim2.new(0.5,-5,0.5,0)
- scrollNub.ZIndex = 2
- scrollNub.BackgroundTransparency = 0.5
- scrollNub.Parent = scrollbar
-
- local newNub = scrollNub:clone()
- newNub.Position = UDim2.new(0.5,-5,0.5,-2)
- newNub.Parent = scrollbar
-
- local lastNub = scrollNub:clone()
- lastNub.Position = UDim2.new(0.5,-5,0.5,2)
- lastNub.Parent = scrollbar
-
- scrollbar.MouseEnter:connect(function()
- scrollbar.BackgroundTransparency = 0.1
- scrollNub.BackgroundTransparency = 0.1
- newNub.BackgroundTransparency = 0.1
- lastNub.BackgroundTransparency = 0.1
- end)
- scrollbar.MouseLeave:connect(function()
- scrollbar.BackgroundTransparency = 0.5
- scrollNub.BackgroundTransparency = 0.5
- newNub.BackgroundTransparency = 0.5
- lastNub.BackgroundTransparency = 0.5
- end)
-
- local mouseDrag = Instance.new("ImageButton")
- mouseDrag.Active = false
- mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0)
- mouseDrag.AutoButtonColor = false
- mouseDrag.BackgroundTransparency = 1
- mouseDrag.Name = "mouseDrag"
- mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0)
- mouseDrag.ZIndex = 10
-
- local function positionScrollBar(x,y,offset)
- local oldPos = scrollbar.Position
-
- if y < scrollTrack.AbsolutePosition.y then
- scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0)
- return (oldPos ~= scrollbar.Position)
- end
-
- local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y
-
- if y > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then
- scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0)
- return (oldPos ~= scrollbar.Position)
- end
- local newScaleYPos = (y - scrollTrack.AbsolutePosition.y - offset)/scrollTrack.AbsoluteSize.y
- if newScaleYPos + relativeSize > 1 then
- newScaleYPos = 1 - relativeSize
- scrollBottom.Value = true
- scrollUp.Value = false
- elseif newScaleYPos <= 0 then
- newScaleYPos = 0
- scrollUp.Value = true
- scrollBottom.Value = false
- else
- scrollUp.Value = false
- scrollBottom.Value = false
- end
- scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,newScaleYPos,0)
-
- return (oldPos ~= scrollbar.Position)
- end
-
- local function drillDownSetHighLow(instance)
- if not instance or not instance:IsA("GuiObject") then return end
- if instance == controlFrame then return end
- if instance:IsDescendantOf(controlFrame) then return end
- if not instance.Visible then return end
-
- if lowY and lowY > instance.AbsolutePosition.Y then
- lowY = instance.AbsolutePosition.Y
- elseif not lowY then
- lowY = instance.AbsolutePosition.Y
- end
- if highY and highY < (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) then
- highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
- elseif not highY then
- highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
- end
- local children = instance:GetChildren()
- for i = 1, #children do
- drillDownSetHighLow(children[i])
- end
- end
-
- local function resetHighLow()
- local firstChildren = scrollingFrame:GetChildren()
-
- for i = 1, #firstChildren do
- drillDownSetHighLow(firstChildren[i])
- end
- end
-
- local function recalculate()
- internalChange = true
-
- local percentFrame = 0
- if scrollbar.Position.Y.Scale > 0 then
- if scrollbar.Visible then
- percentFrame = scrollbar.Position.Y.Scale/((scrollTrack.AbsoluteSize.Y - scrollbar.AbsoluteSize.Y)/scrollTrack.AbsoluteSize.Y)
- else
- percentFrame = 0
- end
- end
- if percentFrame > 0.99 then percentFrame = 1 end
-
- local hiddenYAmount = (scrollingFrame.AbsoluteSize.Y - (highY - lowY)) * percentFrame
-
- local guiChildren = scrollingFrame:GetChildren()
- for i = 1, #guiChildren do
- if guiChildren[i] ~= controlFrame then
- guiChildren[i].Position = UDim2.new(guiChildren[i].Position.X.Scale,guiChildren[i].Position.X.Offset,
- 0, math.ceil(guiChildren[i].AbsolutePosition.Y) - math.ceil(lowY) + hiddenYAmount)
- end
- end
-
- lowY = nil
- highY = nil
- resetHighLow()
- internalChange = false
- end
-
- local function setSliderSizeAndPosition()
- if not highY or not lowY then return end
-
- local totalYSpan = math.abs(highY - lowY)
- if totalYSpan == 0 then
- scrollbar.Visible = false
- scrollDownButton.Visible = false
- scrollUpButton.Visible = false
-
- if dragCon then dragCon:disconnect() dragCon = nil end
- if upCon then upCon:disconnect() upCon = nil end
- return
- end
-
- local percentShown = scrollingFrame.AbsoluteSize.Y/totalYSpan
- if percentShown >= 1 then
- scrollbar.Visible = false
- scrollDownButton.Visible = false
- scrollUpButton.Visible = false
- recalculate()
- else
- scrollbar.Visible = true
- scrollDownButton.Visible = true
- scrollUpButton.Visible = true
-
- scrollbar.Size = UDim2.new(scrollbar.Size.X.Scale,scrollbar.Size.X.Offset,percentShown,0)
- end
-
- local percentPosition = (scrollingFrame.AbsolutePosition.Y - lowY)/totalYSpan
- scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,percentPosition,-scrollbar.AbsoluteSize.X/2)
-
- if scrollbar.AbsolutePosition.y < scrollTrack.AbsolutePosition.y then
- scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0)
- end
-
- if (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.Y) > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then
- local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y
- scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0)
- end
- end
-
- local buttonScrollAmountPixels = 7
- local reentrancyGuardScrollUp = false
- local function doScrollUp()
- if reentrancyGuardScrollUp then return end
-
- reentrancyGuardScrollUp = true
- if positionScrollBar(0,scrollbar.AbsolutePosition.Y - buttonScrollAmountPixels,0) then
- recalculate()
- end
- reentrancyGuardScrollUp = false
- end
-
- local reentrancyGuardScrollDown = false
- local function doScrollDown()
- if reentrancyGuardScrollDown then return end
-
- reentrancyGuardScrollDown = true
- if positionScrollBar(0,scrollbar.AbsolutePosition.Y + buttonScrollAmountPixels,0) then
- recalculate()
- end
- reentrancyGuardScrollDown = false
- end
-
- local function scrollUp(mouseYPos)
- if scrollUpButton.Active then
- scrollStamp = tick()
- local current = scrollStamp
- local upCon
- upCon = mouseDrag.MouseButton1Up:connect(function()
- scrollStamp = tick()
- mouseDrag.Parent = nil
- upCon:disconnect()
- end)
- mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
- doScrollUp()
- wait(0.2)
- local t = tick()
- local w = 0.1
- while scrollStamp == current do
- doScrollUp()
- if mouseYPos and mouseYPos > scrollbar.AbsolutePosition.y then
- break
- end
- if not scrollUpButton.Active then break end
- if tick()-t > 5 then
- w = 0
- elseif tick()-t > 2 then
- w = 0.06
- end
- wait(w)
- end
- end
- end
-
- local function scrollDown(mouseYPos)
- if scrollDownButton.Active then
- scrollStamp = tick()
- local current = scrollStamp
- local downCon
- downCon = mouseDrag.MouseButton1Up:connect(function()
- scrollStamp = tick()
- mouseDrag.Parent = nil
- downCon:disconnect()
- end)
- mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
- doScrollDown()
- wait(0.2)
- local t = tick()
- local w = 0.1
- while scrollStamp == current do
- doScrollDown()
- if mouseYPos and mouseYPos < (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.x) then
- break
- end
- if not scrollDownButton.Active then break end
- if tick()-t > 5 then
- w = 0
- elseif tick()-t > 2 then
- w = 0.06
- end
- wait(w)
- end
- end
- end
-
- scrollbar.MouseButton1Down:connect(function(x,y)
- if scrollbar.Active then
- scrollStamp = tick()
- local mouseOffset = y - scrollbar.AbsolutePosition.y
- if dragCon then dragCon:disconnect() dragCon = nil end
- if upCon then upCon:disconnect() upCon = nil end
- local prevY = y
- local reentrancyGuardMouseScroll = false
- dragCon = mouseDrag.MouseMoved:connect(function(x,y)
- if reentrancyGuardMouseScroll then return end
-
- reentrancyGuardMouseScroll = true
- if positionScrollBar(x,y,mouseOffset) then
- recalculate()
- end
- reentrancyGuardMouseScroll = false
-
- end)
- upCon = mouseDrag.MouseButton1Up:connect(function()
- scrollStamp = tick()
- mouseDrag.Parent = nil
- dragCon:disconnect(); dragCon = nil
- upCon:disconnect(); drag = nil
- end)
- mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
- end
- end)
-
- local scrollMouseCount = 0
-
- scrollUpButton.MouseButton1Down:connect(function()
- scrollUp()
- end)
- scrollUpButton.MouseButton1Up:connect(function()
- scrollStamp = tick()
- end)
-
- scrollDownButton.MouseButton1Up:connect(function()
- scrollStamp = tick()
- end)
- scrollDownButton.MouseButton1Down:connect(function()
- scrollDown()
- end)
-
- scrollbar.MouseButton1Up:connect(function()
- scrollStamp = tick()
- end)
-
- local function heightCheck(instance)
- if highY and (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) > highY then
- highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
- elseif not highY then
- highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
- end
- setSliderSizeAndPosition()
- end
-
- local function highLowRecheck()
- local oldLowY = lowY
- local oldHighY = highY
- lowY = nil
- highY = nil
- resetHighLow()
-
- if (lowY ~= oldLowY) or (highY ~= oldHighY) then
- setSliderSizeAndPosition()
- end
- end
-
- local function descendantChanged(this, prop)
- if internalChange then return end
- if not this.Visible then return end
-
- if prop == "Size" or prop == "Position" then
- wait()
- highLowRecheck()
- end
- end
-
- scrollingFrame.DescendantAdded:connect(function(instance)
- if not instance:IsA("GuiObject") then return end
-
- if instance.Visible then
- wait() -- wait a heartbeat for sizes to reconfig
- highLowRecheck()
- end
-
- descendantsChangeConMap[instance] = instance.Changed:connect(function(prop) descendantChanged(instance, prop) end)
- end)
-
- scrollingFrame.DescendantRemoving:connect(function(instance)
- if not instance:IsA("GuiObject") then return end
- if descendantsChangeConMap[instance] then
- descendantsChangeConMap[instance]:disconnect()
- descendantsChangeConMap[instance] = nil
- end
- wait() -- wait a heartbeat for sizes to reconfig
- highLowRecheck()
- end)
-
- scrollingFrame.Changed:connect(function(prop)
- if prop == "AbsoluteSize" then
- if not highY or not lowY then return end
-
- highLowRecheck()
- setSliderSizeAndPosition()
- end
- end)
-
- return scrollingFrame, controlFrame
-end
-
-t.CreateScrollingFrame = function(orderList,scrollStyle)
- local frame = Instance.new("Frame")
- frame.Name = "ScrollingFrame"
- frame.BackgroundTransparency = 1
- frame.Size = UDim2.new(1,0,1,0)
-
- local scrollUpButton = Instance.new("ImageButton")
- scrollUpButton.Name = "ScrollUpButton"
- scrollUpButton.BackgroundTransparency = 1
- scrollUpButton.Image = "rbxasset://textures/ui/scrollbuttonUp.png"
- scrollUpButton.Size = UDim2.new(0,17,0,17)
-
-
- local scrollDownButton = Instance.new("ImageButton")
- scrollDownButton.Name = "ScrollDownButton"
- scrollDownButton.BackgroundTransparency = 1
- scrollDownButton.Image = "rbxasset://textures/ui/scrollbuttonDown.png"
- scrollDownButton.Size = UDim2.new(0,17,0,17)
-
- local scrollbar = Instance.new("ImageButton")
- scrollbar.Name = "ScrollBar"
- scrollbar.Image = "rbxasset://textures/ui/scrollbar.png"
- scrollbar.BackgroundTransparency = 1
- scrollbar.Size = UDim2.new(0, 18, 0, 150)
-
- local scrollStamp = 0
-
- local scrollDrag = Instance.new("ImageButton")
- scrollDrag.Image = "http://www.roblox.com/asset/?id=61367186"
- scrollDrag.Size = UDim2.new(1, 0, 0, 16)
- scrollDrag.BackgroundTransparency = 1
- scrollDrag.Name = "ScrollDrag"
- scrollDrag.Active = true
- scrollDrag.Parent = scrollbar
-
- local mouseDrag = Instance.new("ImageButton")
- mouseDrag.Active = false
- mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0)
- mouseDrag.AutoButtonColor = false
- mouseDrag.BackgroundTransparency = 1
- mouseDrag.Name = "mouseDrag"
- mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0)
- mouseDrag.ZIndex = 10
-
- local style = "simple"
- if scrollStyle and tostring(scrollStyle) then
- style = scrollStyle
- end
-
- local scrollPosition = 1
- local rowSize = 0
- local howManyDisplayed = 0
-
- local layoutGridScrollBar = function()
- howManyDisplayed = 0
- local guiObjects = {}
- if orderList then
- for i, child in ipairs(orderList) do
- if child.Parent == frame then
- table.insert(guiObjects, child)
- end
- end
- else
- local children = frame:GetChildren()
- if children then
- for i, child in ipairs(children) do
- if child:IsA("GuiObject") then
- table.insert(guiObjects, child)
- end
- end
- end
- end
- if #guiObjects == 0 then
- scrollUpButton.Active = false
- scrollDownButton.Active = false
- scrollDrag.Active = false
- scrollPosition = 1
- return
- end
-
- if scrollPosition > #guiObjects then
- scrollPosition = #guiObjects
- end
-
- if scrollPosition < 1 then scrollPosition = 1 end
-
- local totalPixelsY = frame.AbsoluteSize.Y
- local pixelsRemainingY = frame.AbsoluteSize.Y
-
- local totalPixelsX = frame.AbsoluteSize.X
-
- local xCounter = 0
- local rowSizeCounter = 0
- local setRowSize = true
-
- local pixelsBelowScrollbar = 0
- local pos = #guiObjects
-
- local currentRowY = 0
-
- pos = scrollPosition
- --count up from current scroll position to fill out grid
- while pos <= #guiObjects and pixelsBelowScrollbar < totalPixelsY do
- xCounter = xCounter + guiObjects[pos].AbsoluteSize.X
- --previous pos was the end of a row
- if xCounter >= totalPixelsX then
- pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
- currentRowY = 0
- xCounter = guiObjects[pos].AbsoluteSize.X
- end
- if guiObjects[pos].AbsoluteSize.Y > currentRowY then
- currentRowY = guiObjects[pos].AbsoluteSize.Y
- end
- pos = pos + 1
- end
- --Count wherever current row left off
- pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
- currentRowY = 0
-
- pos = scrollPosition - 1
- xCounter = 0
-
- --objects with varying X,Y dimensions can rarely cause minor errors
- --rechecking every new scrollPosition is necessary to avoid 100% of errors
-
- --count backwards from current scrollPosition to see if we can add more rows
- while pixelsBelowScrollbar + currentRowY < totalPixelsY and pos >= 1 do
- xCounter = xCounter + guiObjects[pos].AbsoluteSize.X
- rowSizeCounter = rowSizeCounter + 1
- if xCounter >= totalPixelsX then
- rowSize = rowSizeCounter - 1
- rowSizeCounter = 0
- xCounter = guiObjects[pos].AbsoluteSize.X
- if pixelsBelowScrollbar + currentRowY <= totalPixelsY then
- --It fits, so back up our scroll position
- pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
- if scrollPosition <= rowSize then
- scrollPosition = 1
- break
- else
- scrollPosition = scrollPosition - rowSize
- end
- currentRowY = 0
- else
- break
- end
- end
-
- if guiObjects[pos].AbsoluteSize.Y > currentRowY then
- currentRowY = guiObjects[pos].AbsoluteSize.Y
- end
-
- pos = pos - 1
- end
-
- --Do check last time if pos = 0
- if (pos == 0) and (pixelsBelowScrollbar + currentRowY <= totalPixelsY) then
- scrollPosition = 1
- end
-
- xCounter = 0
- --pos = scrollPosition
- rowSizeCounter = 0
- setRowSize = true
- local lastChildSize = 0
-
- local xOffset,yOffset = 0
- if guiObjects[1] then
- yOffset = math.ceil(math.floor(math.fmod(totalPixelsY,guiObjects[1].AbsoluteSize.X))/2)
- xOffset = math.ceil(math.floor(math.fmod(totalPixelsX,guiObjects[1].AbsoluteSize.Y))/2)
- end
-
- for i, child in ipairs(guiObjects) do
- if i < scrollPosition then
- --print("Hiding " .. child.Name)
- child.Visible = false
- else
- if pixelsRemainingY < 0 then
- --print("Out of Space " .. child.Name)
- child.Visible = false
- else
- --print("Laying out " .. child.Name)
- --GuiObject
- if setRowSize then rowSizeCounter = rowSizeCounter + 1 end
- if xCounter + child.AbsoluteSize.X >= totalPixelsX then
- if setRowSize then
- rowSize = rowSizeCounter - 1
- setRowSize = false
- end
- xCounter = 0
- pixelsRemainingY = pixelsRemainingY - child.AbsoluteSize.Y
- end
- child.Position = UDim2.new(child.Position.X.Scale,xCounter + xOffset, 0, totalPixelsY - pixelsRemainingY + yOffset)
- xCounter = xCounter + child.AbsoluteSize.X
- child.Visible = ((pixelsRemainingY - child.AbsoluteSize.Y) >= 0)
- if child.Visible then
- howManyDisplayed = howManyDisplayed + 1
- end
- lastChildSize = child.AbsoluteSize
- end
- end
- end
-
- scrollUpButton.Active = (scrollPosition > 1)
- if lastChildSize == 0 then
- scrollDownButton.Active = false
- else
- scrollDownButton.Active = ((pixelsRemainingY - lastChildSize.Y) < 0)
- end
- scrollDrag.Active = #guiObjects > howManyDisplayed
- scrollDrag.Visible = scrollDrag.Active
- end
-
-
-
- local layoutSimpleScrollBar = function()
- local guiObjects = {}
- howManyDisplayed = 0
-
- if orderList then
- for i, child in ipairs(orderList) do
- if child.Parent == frame then
- table.insert(guiObjects, child)
- end
- end
- else
- local children = frame:GetChildren()
- if children then
- for i, child in ipairs(children) do
- if child:IsA("GuiObject") then
- table.insert(guiObjects, child)
- end
- end
- end
- end
- if #guiObjects == 0 then
- scrollUpButton.Active = false
- scrollDownButton.Active = false
- scrollDrag.Active = false
- scrollPosition = 1
- return
- end
-
- if scrollPosition > #guiObjects then
- scrollPosition = #guiObjects
- end
-
- local totalPixels = frame.AbsoluteSize.Y
- local pixelsRemaining = frame.AbsoluteSize.Y
-
- local pixelsBelowScrollbar = 0
- local pos = #guiObjects
- while pixelsBelowScrollbar < totalPixels and pos >= 1 do
- if pos >= scrollPosition then
- pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y
- else
- if pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y <= totalPixels then
- --It fits, so back up our scroll position
- pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y
- if scrollPosition <= 1 then
- scrollPosition = 1
- break
- else
- --local ("Backing up ScrollPosition from -- " ..scrollPosition)
- scrollPosition = scrollPosition - 1
- end
- else
- break
- end
- end
- pos = pos - 1
- end
-
- pos = scrollPosition
- for i, child in ipairs(guiObjects) do
- if i < scrollPosition then
- --print("Hiding " .. child.Name)
- child.Visible = false
- else
- if pixelsRemaining < 0 then
- --print("Out of Space " .. child.Name)
- child.Visible = false
- else
- --print("Laying out " .. child.Name)
- --GuiObject
- child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
- pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
- if (pixelsRemaining >= 0) then
- child.Visible = true
- howManyDisplayed = howManyDisplayed + 1
- else
- child.Visible = false
- end
- end
- end
- end
- scrollUpButton.Active = (scrollPosition > 1)
- scrollDownButton.Active = (pixelsRemaining < 0)
- scrollDrag.Active = #guiObjects > howManyDisplayed
- scrollDrag.Visible = scrollDrag.Active
- end
-
-
- local moveDragger = function()
- local guiObjects = 0
- local children = frame:GetChildren()
- if children then
- for i, child in ipairs(children) do
- if child:IsA("GuiObject") then
- guiObjects = guiObjects + 1
- end
- end
- end
-
- if not scrollDrag.Parent then return end
-
- local dragSizeY = scrollDrag.Parent.AbsoluteSize.y * (1/(guiObjects - howManyDisplayed + 1))
- if dragSizeY < 16 then dragSizeY = 16 end
- scrollDrag.Size = UDim2.new(scrollDrag.Size.X.Scale,scrollDrag.Size.X.Offset,scrollDrag.Size.Y.Scale,dragSizeY)
-
- local relativeYPos = (scrollPosition - 1)/(guiObjects - (howManyDisplayed))
- if relativeYPos > 1 then relativeYPos = 1
- elseif relativeYPos < 0 then relativeYPos = 0 end
- local absYPos = 0
-
- if relativeYPos ~= 0 then
- absYPos = (relativeYPos * scrollbar.AbsoluteSize.y) - (relativeYPos * scrollDrag.AbsoluteSize.y)
- end
-
- scrollDrag.Position = UDim2.new(scrollDrag.Position.X.Scale,scrollDrag.Position.X.Offset,scrollDrag.Position.Y.Scale,absYPos)
- end
-
- local reentrancyGuard = false
- local recalculate = function()
- if reentrancyGuard then
- return
- end
- reentrancyGuard = true
- wait()
- local success, err = nil
- if style == "grid" then
- success, err = pcall(function() layoutGridScrollBar() end)
- elseif style == "simple" then
- success, err = pcall(function() layoutSimpleScrollBar() end)
- end
- if not success then print(err) end
- moveDragger()
- reentrancyGuard = false
- end
-
- local doScrollUp = function()
- scrollPosition = (scrollPosition) - rowSize
- if scrollPosition < 1 then scrollPosition = 1 end
- recalculate(nil)
- end
-
- local doScrollDown = function()
- scrollPosition = (scrollPosition) + rowSize
- recalculate(nil)
- end
-
- local scrollUp = function(mouseYPos)
- if scrollUpButton.Active then
- scrollStamp = tick()
- local current = scrollStamp
- local upCon
- upCon = mouseDrag.MouseButton1Up:connect(function()
- scrollStamp = tick()
- mouseDrag.Parent = nil
- upCon:disconnect()
- end)
- mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
- doScrollUp()
- wait(0.2)
- local t = tick()
- local w = 0.1
- while scrollStamp == current do
- doScrollUp()
- if mouseYPos and mouseYPos > scrollDrag.AbsolutePosition.y then
- break
- end
- if not scrollUpButton.Active then break end
- if tick()-t > 5 then
- w = 0
- elseif tick()-t > 2 then
- w = 0.06
- end
- wait(w)
- end
- end
- end
-
- local scrollDown = function(mouseYPos)
- if scrollDownButton.Active then
- scrollStamp = tick()
- local current = scrollStamp
- local downCon
- downCon = mouseDrag.MouseButton1Up:connect(function()
- scrollStamp = tick()
- mouseDrag.Parent = nil
- downCon:disconnect()
- end)
- mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
- doScrollDown()
- wait(0.2)
- local t = tick()
- local w = 0.1
- while scrollStamp == current do
- doScrollDown()
- if mouseYPos and mouseYPos < (scrollDrag.AbsolutePosition.y + scrollDrag.AbsoluteSize.x) then
- break
- end
- if not scrollDownButton.Active then break end
- if tick()-t > 5 then
- w = 0
- elseif tick()-t > 2 then
- w = 0.06
- end
- wait(w)
- end
- end
- end
-
- local y = 0
- scrollDrag.MouseButton1Down:connect(function(x,y)
- if scrollDrag.Active then
- scrollStamp = tick()
- local mouseOffset = y - scrollDrag.AbsolutePosition.y
- local dragCon
- local upCon
- dragCon = mouseDrag.MouseMoved:connect(function(x,y)
- local barAbsPos = scrollbar.AbsolutePosition.y
- local barAbsSize = scrollbar.AbsoluteSize.y
-
- local dragAbsSize = scrollDrag.AbsoluteSize.y
- local barAbsOne = barAbsPos + barAbsSize - dragAbsSize
- y = y - mouseOffset
- y = y < barAbsPos and barAbsPos or y > barAbsOne and barAbsOne or y
- y = y - barAbsPos
-
- local guiObjects = 0
- local children = frame:GetChildren()
- if children then
- for i, child in ipairs(children) do
- if child:IsA("GuiObject") then
- guiObjects = guiObjects + 1
- end
- end
- end
-
- local doublePercent = y/(barAbsSize-dragAbsSize)
- local rowDiff = rowSize
- local totalScrollCount = guiObjects - (howManyDisplayed - 1)
- local newScrollPosition = math.floor((doublePercent * totalScrollCount) + 0.5) + rowDiff
- if newScrollPosition < scrollPosition then
- rowDiff = -rowDiff
- end
-
- if newScrollPosition < 1 then
- newScrollPosition = 1
- end
-
- scrollPosition = newScrollPosition
- recalculate(nil)
- end)
- upCon = mouseDrag.MouseButton1Up:connect(function()
- scrollStamp = tick()
- mouseDrag.Parent = nil
- dragCon:disconnect(); dragCon = nil
- upCon:disconnect(); drag = nil
- end)
- mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
- end
- end)
-
- local scrollMouseCount = 0
-
- scrollUpButton.MouseButton1Down:connect(
- function()
- scrollUp()
- end)
- scrollUpButton.MouseButton1Up:connect(function()
- scrollStamp = tick()
- end)
-
-
- scrollDownButton.MouseButton1Up:connect(function()
- scrollStamp = tick()
- end)
- scrollDownButton.MouseButton1Down:connect(
- function()
- scrollDown()
- end)
-
- scrollbar.MouseButton1Up:connect(function()
- scrollStamp = tick()
- end)
- scrollbar.MouseButton1Down:connect(
- function(x,y)
- if y > (scrollDrag.AbsoluteSize.y + scrollDrag.AbsolutePosition.y) then
- scrollDown(y)
- elseif y < (scrollDrag.AbsolutePosition.y) then
- scrollUp(y)
- end
- end)
-
-
- frame.ChildAdded:connect(function()
- recalculate(nil)
- end)
-
- frame.ChildRemoved:connect(function()
- recalculate(nil)
- end)
-
- frame.Changed:connect(
- function(prop)
- if prop == "AbsoluteSize" then
- --Wait a heartbeat for it to sync in
- recalculate(nil)
- end
- end)
- frame.AncestryChanged:connect(function() recalculate(nil) end)
-
- return frame, scrollUpButton, scrollDownButton, recalculate, scrollbar
-end
-local function binaryGrow(min, max, fits)
- if min > max then
- return min
- end
- local biggestLegal = min
-
- while min <= max do
- local mid = min + math.floor((max - min) / 2)
- if fits(mid) and (biggestLegal == nil or biggestLegal < mid) then
- biggestLegal = mid
-
- --Try growing
- min = mid + 1
- else
- --Doesn't fit, shrink
- max = mid - 1
- end
- end
- return biggestLegal
-end
-
-
-local function binaryShrink(min, max, fits)
- if min > max then
- return min
- end
- local smallestLegal = max
-
- while min <= max do
- local mid = min + math.floor((max - min) / 2)
- if fits(mid) and (smallestLegal == nil or smallestLegal > mid) then
- smallestLegal = mid
-
- --It fits, shrink
- max = mid - 1
- else
- --Doesn't fit, grow
- min = mid + 1
- end
- end
- return smallestLegal
-end
-
-
-local function getGuiOwner(instance)
- while instance ~= nil do
- if instance:IsA("ScreenGui") or instance:IsA("BillboardGui") then
- return instance
- end
- instance = instance.Parent
- end
- return nil
-end
-
-t.AutoTruncateTextObject = function(textLabel)
- local text = textLabel.Text
-
- local fullLabel = textLabel:Clone()
- fullLabel.Name = "Full" .. textLabel.Name
- fullLabel.BorderSizePixel = 0
- fullLabel.BackgroundTransparency = 0
- fullLabel.Text = text
- fullLabel.TextXAlignment = Enum.TextXAlignment.Center
- fullLabel.Position = UDim2.new(0,-3,0,0)
- fullLabel.Size = UDim2.new(0,100,1,0)
- fullLabel.Visible = false
- fullLabel.Parent = textLabel
-
- local shortText = nil
- local mouseEnterConnection = nil
- local mouseLeaveConnection= nil
-
- local checkForResize = function()
- if getGuiOwner(textLabel) == nil then
- return
- end
- textLabel.Text = text
- if textLabel.TextFits then
- --Tear down the rollover if it is active
- if mouseEnterConnection then
- mouseEnterConnection:disconnect()
- mouseEnterConnection = nil
- end
- if mouseLeaveConnection then
- mouseLeaveConnection:disconnect()
- mouseLeaveConnection = nil
- end
- else
- local len = string.len(text)
- textLabel.Text = text .. "~"
-
- --Shrink the text
- local textSize = binaryGrow(0, len,
- function(pos)
- if pos == 0 then
- textLabel.Text = "~"
- else
- textLabel.Text = string.sub(text, 1, pos) .. "~"
- end
- return textLabel.TextFits
- end)
- shortText = string.sub(text, 1, textSize) .. "~"
- textLabel.Text = shortText
-
- --Make sure the fullLabel fits
- if not fullLabel.TextFits then
- --Already too small, grow it really bit to start
- fullLabel.Size = UDim2.new(0, 10000, 1, 0)
- end
-
- --Okay, now try to binary shrink it back down
- local fullLabelSize = binaryShrink(textLabel.AbsoluteSize.X,fullLabel.AbsoluteSize.X,
- function(size)
- fullLabel.Size = UDim2.new(0, size, 1, 0)
- return fullLabel.TextFits
- end)
- fullLabel.Size = UDim2.new(0,fullLabelSize+6,1,0)
-
- --Now setup the rollover effects, if they are currently off
- if mouseEnterConnection == nil then
- mouseEnterConnection = textLabel.MouseEnter:connect(
- function()
- fullLabel.ZIndex = textLabel.ZIndex + 1
- fullLabel.Visible = true
- --textLabel.Text = ""
- end)
- end
- if mouseLeaveConnection == nil then
- mouseLeaveConnection = textLabel.MouseLeave:connect(
- function()
- fullLabel.Visible = false
- --textLabel.Text = shortText
- end)
- end
- end
- end
- textLabel.AncestryChanged:connect(checkForResize)
- textLabel.Changed:connect(
- function(prop)
- if prop == "AbsoluteSize" then
- checkForResize()
- end
- end)
-
- checkForResize()
-
- local function changeText(newText)
- text = newText
- fullLabel.Text = text
- checkForResize()
- end
-
- return textLabel, changeText
-end
-
-local function TransitionTutorialPages(fromPage, toPage, transitionFrame, currentPageValue)
- if fromPage then
- fromPage.Visible = false
- if transitionFrame.Visible == false then
- transitionFrame.Size = fromPage.Size
- transitionFrame.Position = fromPage.Position
- end
- else
- if transitionFrame.Visible == false then
- transitionFrame.Size = UDim2.new(0.0,50,0.0,50)
- transitionFrame.Position = UDim2.new(0.5,-25,0.5,-25)
- end
- end
- transitionFrame.Visible = true
- currentPageValue.Value = nil
-
- local newsize, newPosition
- if toPage then
- --Make it visible so it resizes
- toPage.Visible = true
-
- newSize = toPage.Size
- newPosition = toPage.Position
-
- toPage.Visible = false
- else
- newSize = UDim2.new(0.0,50,0.0,50)
- newPosition = UDim2.new(0.5,-25,0.5,-25)
- end
- transitionFrame:TweenSizeAndPosition(newSize, newPosition, Enum.EasingDirection.InOut, Enum.EasingStyle.Quad, 0.3, true,
- function(state)
- if state == Enum.TweenStatus.Completed then
- transitionFrame.Visible = false
- if toPage then
- toPage.Visible = true
- currentPageValue.Value = toPage
- end
- end
- end)
-end
-
-t.CreateTutorial = function(name, tutorialKey, createButtons)
- local frame = Instance.new("Frame")
- frame.Name = "Tutorial-" .. name
- frame.BackgroundTransparency = 1
- frame.Size = UDim2.new(0.6, 0, 0.6, 0)
- frame.Position = UDim2.new(0.2, 0, 0.2, 0)
-
- local transitionFrame = Instance.new("Frame")
- transitionFrame.Name = "TransitionFrame"
- transitionFrame.Style = Enum.FrameStyle.RobloxRound
- transitionFrame.Size = UDim2.new(0.6, 0, 0.6, 0)
- transitionFrame.Position = UDim2.new(0.2, 0, 0.2, 0)
- transitionFrame.Visible = false
- transitionFrame.Parent = frame
-
- local currentPageValue = Instance.new("ObjectValue")
- currentPageValue.Name = "CurrentTutorialPage"
- currentPageValue.Value = nil
- currentPageValue.Parent = frame
-
- local boolValue = Instance.new("BoolValue")
- boolValue.Name = "Buttons"
- boolValue.Value = createButtons
- boolValue.Parent = frame
-
- local pages = Instance.new("Frame")
- pages.Name = "Pages"
- pages.BackgroundTransparency = 1
- pages.Size = UDim2.new(1,0,1,0)
- pages.Parent = frame
-
- local function getVisiblePageAndHideOthers()
- local visiblePage = nil
- local children = pages:GetChildren()
- if children then
- for i,child in ipairs(children) do
- if child.Visible then
- if visiblePage then
- child.Visible = false
- else
- visiblePage = child
- end
- end
- end
- end
- return visiblePage
- end
-
- local showTutorial = function(alwaysShow)
- if alwaysShow or UserSettings().GameSettings:GetTutorialState(tutorialKey) == false then
- print("Showing tutorial-",tutorialKey)
- local currentTutorialPage = getVisiblePageAndHideOthers()
-
- local firstPage = pages:FindFirstChild("TutorialPage1")
- if firstPage then
- TransitionTutorialPages(currentTutorialPage, firstPage, transitionFrame, currentPageValue)
- else
- error("Could not find TutorialPage1")
- end
- end
- end
-
- local dismissTutorial = function()
- local currentTutorialPage = getVisiblePageAndHideOthers()
-
- if currentTutorialPage then
- TransitionTutorialPages(currentTutorialPage, nil, transitionFrame, currentPageValue)
- end
-
- UserSettings().GameSettings:SetTutorialState(tutorialKey, true)
- end
-
- local gotoPage = function(pageNum)
- local page = pages:FindFirstChild("TutorialPage" .. pageNum)
- local currentTutorialPage = getVisiblePageAndHideOthers()
- TransitionTutorialPages(currentTutorialPage, page, transitionFrame, currentPageValue)
- end
-
- return frame, showTutorial, dismissTutorial, gotoPage
-end
-
-local function CreateBasicTutorialPage(name, handleResize, skipTutorial, giveDoneButton)
- local frame = Instance.new("Frame")
- frame.Name = "TutorialPage"
- frame.Style = Enum.FrameStyle.RobloxRound
- frame.Size = UDim2.new(0.6, 0, 0.6, 0)
- frame.Position = UDim2.new(0.2, 0, 0.2, 0)
- frame.Visible = false
-
- local frameHeader = Instance.new("TextLabel")
- frameHeader.Name = "Header"
- frameHeader.Text = name
- frameHeader.BackgroundTransparency = 1
- frameHeader.FontSize = Enum.FontSize.Size24
- frameHeader.Font = Enum.Font.ArialBold
- frameHeader.TextColor3 = Color3.new(1,1,1)
- frameHeader.TextXAlignment = Enum.TextXAlignment.Center
- frameHeader.TextWrap = true
- frameHeader.Size = UDim2.new(1,-55, 0, 22)
- frameHeader.Position = UDim2.new(0,0,0,0)
- frameHeader.Parent = frame
-
- local skipButton = Instance.new("ImageButton")
- skipButton.Name = "SkipButton"
- skipButton.AutoButtonColor = false
- skipButton.BackgroundTransparency = 1
- skipButton.Image = "rbxasset://textures/ui/closeButton.png"
- skipButton.MouseButton1Click:connect(function()
- skipTutorial()
- end)
- skipButton.MouseEnter:connect(function()
- skipButton.Image = "rbxasset://textures/ui/closeButton_dn.png"
- end)
- skipButton.MouseLeave:connect(function()
- skipButton.Image = "rbxasset://textures/ui/closeButton.png"
- end)
- skipButton.Size = UDim2.new(0, 25, 0, 25)
- skipButton.Position = UDim2.new(1, -25, 0, 0)
- skipButton.Parent = frame
-
-
- if giveDoneButton then
- local doneButton = Instance.new("TextButton")
- doneButton.Name = "DoneButton"
- doneButton.Style = Enum.ButtonStyle.RobloxButtonDefault
- doneButton.Text = "Done"
- doneButton.TextColor3 = Color3.new(1,1,1)
- doneButton.Font = Enum.Font.ArialBold
- doneButton.FontSize = Enum.FontSize.Size18
- doneButton.Size = UDim2.new(0,100,0,50)
- doneButton.Position = UDim2.new(0.5,-50,1,-50)
-
- if skipTutorial then
- doneButton.MouseButton1Click:connect(function() skipTutorial() end)
- end
-
- doneButton.Parent = frame
- end
-
- local innerFrame = Instance.new("Frame")
- innerFrame.Name = "ContentFrame"
- innerFrame.BackgroundTransparency = 1
- innerFrame.Position = UDim2.new(0,0,0,25)
- innerFrame.Parent = frame
-
- local nextButton = Instance.new("TextButton")
- nextButton.Name = "NextButton"
- nextButton.Text = "Next"
- nextButton.TextColor3 = Color3.new(1,1,1)
- nextButton.Font = Enum.Font.Arial
- nextButton.FontSize = Enum.FontSize.Size18
- nextButton.Style = Enum.ButtonStyle.RobloxButtonDefault
- nextButton.Size = UDim2.new(0,80, 0, 32)
- nextButton.Position = UDim2.new(0.5, 5, 1, -32)
- nextButton.Active = false
- nextButton.Visible = false
- nextButton.Parent = frame
-
- local prevButton = Instance.new("TextButton")
- prevButton.Name = "PrevButton"
- prevButton.Text = "Previous"
- prevButton.TextColor3 = Color3.new(1,1,1)
- prevButton.Font = Enum.Font.Arial
- prevButton.FontSize = Enum.FontSize.Size18
- prevButton.Style = Enum.ButtonStyle.RobloxButton
- prevButton.Size = UDim2.new(0,80, 0, 32)
- prevButton.Position = UDim2.new(0.5, -85, 1, -32)
- prevButton.Active = false
- prevButton.Visible = false
- prevButton.Parent = frame
-
- if giveDoneButton then
- innerFrame.Size = UDim2.new(1,0,1,-75)
- else
- innerFrame.Size = UDim2.new(1,0,1,-22)
- end
-
- local parentConnection = nil
-
- local function basicHandleResize()
- if frame.Visible and frame.Parent then
- local maxSize = math.min(frame.Parent.AbsoluteSize.X, frame.Parent.AbsoluteSize.Y)
- handleResize(200,maxSize)
- end
- end
-
- frame.Changed:connect(
- function(prop)
- if prop == "Parent" then
- if parentConnection ~= nil then
- parentConnection:disconnect()
- parentConnection = nil
- end
- if frame.Parent and frame.Parent:IsA("GuiObject") then
- parentConnection = frame.Parent.Changed:connect(
- function(parentProp)
- if parentProp == "AbsoluteSize" then
- wait()
- basicHandleResize()
- end
- end)
- basicHandleResize()
- end
- end
-
- if prop == "Visible" then
- basicHandleResize()
- end
- end)
-
- return frame, innerFrame
-end
-
-t.CreateTextTutorialPage = function(name, text, skipTutorialFunc)
- local frame = nil
- local contentFrame = nil
-
- local textLabel = Instance.new("TextLabel")
- textLabel.BackgroundTransparency = 1
- textLabel.TextColor3 = Color3.new(1,1,1)
- textLabel.Text = text
- textLabel.TextWrap = true
- textLabel.TextXAlignment = Enum.TextXAlignment.Left
- textLabel.TextYAlignment = Enum.TextYAlignment.Center
- textLabel.Font = Enum.Font.Arial
- textLabel.FontSize = Enum.FontSize.Size14
- textLabel.Size = UDim2.new(1,0,1,0)
-
- local function handleResize(minSize, maxSize)
- size = binaryShrink(minSize, maxSize,
- function(size)
- frame.Size = UDim2.new(0, size, 0, size)
- return textLabel.TextFits
- end)
- frame.Size = UDim2.new(0, size, 0, size)
- frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2)
- end
-
- frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc)
- textLabel.Parent = contentFrame
-
- return frame
-end
-
-t.CreateImageTutorialPage = function(name, imageAsset, x, y, skipTutorialFunc, giveDoneButton)
- local frame = nil
- local contentFrame = nil
-
- local imageLabel = Instance.new("ImageLabel")
- imageLabel.BackgroundTransparency = 1
- imageLabel.Image = imageAsset
- imageLabel.Size = UDim2.new(0,x,0,y)
- imageLabel.Position = UDim2.new(0.5,-x/2,0.5,-y/2)
-
- local function handleResize(minSize, maxSize)
- size = binaryShrink(minSize, maxSize,
- function(size)
- return size >= x and size >= y
- end)
- if size >= x and size >= y then
- imageLabel.Size = UDim2.new(0,x, 0,y)
- imageLabel.Position = UDim2.new(0.5,-x/2, 0.5, -y/2)
- else
- if x > y then
- --X is limiter, so
- imageLabel.Size = UDim2.new(1,0,y/x,0)
- imageLabel.Position = UDim2.new(0,0, 0.5 - (y/x)/2, 0)
- else
- --Y is limiter
- imageLabel.Size = UDim2.new(x/y,0,1, 0)
- imageLabel.Position = UDim2.new(0.5-(x/y)/2, 0, 0, 0)
- end
- end
- size = size + 50
- frame.Size = UDim2.new(0, size, 0, size)
- frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2)
- end
-
- frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc, giveDoneButton)
- imageLabel.Parent = contentFrame
-
- return frame
-end
-
-t.AddTutorialPage = function(tutorial, tutorialPage)
- local transitionFrame = tutorial.TransitionFrame
- local currentPageValue = tutorial.CurrentTutorialPage
-
- if not tutorial.Buttons.Value then
- tutorialPage.NextButton.Parent = nil
- tutorialPage.PrevButton.Parent = nil
- end
-
- local children = tutorial.Pages:GetChildren()
- if children and #children > 0 then
- tutorialPage.Name = "TutorialPage" .. (#children+1)
- local previousPage = children[#children]
- if not previousPage:IsA("GuiObject") then
- error("All elements under Pages must be GuiObjects")
- end
-
- if tutorial.Buttons.Value then
- if previousPage.NextButton.Active then
- error("NextButton already Active on previousPage, please only add pages with RbxGui.AddTutorialPage function")
- end
- previousPage.NextButton.MouseButton1Click:connect(
- function()
- TransitionTutorialPages(previousPage, tutorialPage, transitionFrame, currentPageValue)
- end)
- previousPage.NextButton.Active = true
- previousPage.NextButton.Visible = true
-
- if tutorialPage.PrevButton.Active then
- error("PrevButton already Active on tutorialPage, please only add pages with RbxGui.AddTutorialPage function")
- end
- tutorialPage.PrevButton.MouseButton1Click:connect(
- function()
- TransitionTutorialPages(tutorialPage, previousPage, transitionFrame, currentPageValue)
- end)
- tutorialPage.PrevButton.Active = true
- tutorialPage.PrevButton.Visible = true
- end
-
- tutorialPage.Parent = tutorial.Pages
- else
- --First child
- tutorialPage.Name = "TutorialPage1"
- tutorialPage.Parent = tutorial.Pages
- end
-end
-
-t.CreateSetPanel = function(userIdsForSets, objectSelected, dialogClosed, size, position, showAdminCategories, useAssetVersionId)
-
- if not userIdsForSets then
- error("CreateSetPanel: userIdsForSets (first arg) is nil, should be a table of number ids")
- end
- if type(userIdsForSets) ~= "table" and type(userIdsForSets) ~= "userdata" then
- error("CreateSetPanel: userIdsForSets (first arg) is of type " ..type(userIdsForSets) .. ", should be of type table or userdata")
- end
- if not objectSelected then
- error("CreateSetPanel: objectSelected (second arg) is nil, should be a callback function!")
- end
- if type(objectSelected) ~= "function" then
- error("CreateSetPanel: objectSelected (second arg) is of type " .. type(objectSelected) .. ", should be of type function!")
- end
- if dialogClosed and type(dialogClosed) ~= "function" then
- error("CreateSetPanel: dialogClosed (third arg) is of type " .. type(dialogClosed) .. ", should be of type function!")
- end
-
- if showAdminCategories == nil then -- by default, don't show beta sets
- showAdminCategories = false
- end
-
- local arrayPosition = 1
- local insertButtons = {}
- local insertButtonCons = {}
- local contents = nil
- local setGui = nil
-
- -- used for water selections
- local waterForceDirection = "NegX"
- local waterForce = "None"
- local waterGui, waterTypeChangedEvent = nil
-
- local Data = {}
- Data.CurrentCategory = nil
- Data.Category = {}
- local SetCache = {}
-
- local userCategoryButtons = nil
-
- local buttonWidth = 64
- local buttonHeight = buttonWidth
-
- local SmallThumbnailUrl = nil
- local LargeThumbnailUrl = nil
- local BaseUrl = game:GetService("ContentProvider").BaseUrl:lower()
-
- if useAssetVersionId then
- LargeThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&assetversionid="
- SmallThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&assetversionid="
- else
- LargeThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&aid="
- SmallThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&aid="
- end
-
- local function drillDownSetZIndex(parent, index)
- local children = parent:GetChildren()
- for i = 1, #children do
- if children[i]:IsA("GuiObject") then
- children[i].ZIndex = index
- end
- drillDownSetZIndex(children[i], index)
- end
- end
-
- -- for terrain stamping
- local currTerrainDropDownFrame = nil
- local terrainShapes = {"Block","Vertical Ramp","Corner Wedge","Inverse Corner Wedge","Horizontal Ramp","Auto-Wedge"}
- local terrainShapeMap = {}
- for i = 1, #terrainShapes do
- terrainShapeMap[terrainShapes[i]] = i - 1
- end
- terrainShapeMap[terrainShapes[#terrainShapes]] = 6
-
- local function createWaterGui()
- local waterForceDirections = {"NegX","X","NegY","Y","NegZ","Z"}
- local waterForces = {"None", "Small", "Medium", "Strong", "Max"}
-
- local waterFrame = Instance.new("Frame")
- waterFrame.Name = "WaterFrame"
- waterFrame.Style = Enum.FrameStyle.RobloxSquare
- waterFrame.Size = UDim2.new(0,150,0,110)
- waterFrame.Visible = false
-
- local waterForceLabel = Instance.new("TextLabel")
- waterForceLabel.Name = "WaterForceLabel"
- waterForceLabel.BackgroundTransparency = 1
- waterForceLabel.Size = UDim2.new(1,0,0,12)
- waterForceLabel.Font = Enum.Font.ArialBold
- waterForceLabel.FontSize = Enum.FontSize.Size12
- waterForceLabel.TextColor3 = Color3.new(1,1,1)
- waterForceLabel.TextXAlignment = Enum.TextXAlignment.Left
- waterForceLabel.Text = "Water Force"
- waterForceLabel.Parent = waterFrame
-
- local waterForceDirLabel = waterForceLabel:Clone()
- waterForceDirLabel.Name = "WaterForceDirectionLabel"
- waterForceDirLabel.Text = "Water Force Direction"
- waterForceDirLabel.Position = UDim2.new(0,0,0,50)
- waterForceDirLabel.Parent = waterFrame
-
- local waterTypeChangedEvent = Instance.new("BindableEvent",waterFrame)
- waterTypeChangedEvent.Name = "WaterTypeChangedEvent"
-
- local waterForceDirectionSelectedFunc = function(newForceDirection)
- waterForceDirection = newForceDirection
- waterTypeChangedEvent:Fire({waterForce, waterForceDirection})
- end
- local waterForceSelectedFunc = function(newForce)
- waterForce = newForce
- waterTypeChangedEvent:Fire({waterForce, waterForceDirection})
- end
-
- local waterForceDirectionDropDown, forceWaterDirectionSelection = t.CreateDropDownMenu(waterForceDirections, waterForceDirectionSelectedFunc)
- waterForceDirectionDropDown.Size = UDim2.new(1,0,0,25)
- waterForceDirectionDropDown.Position = UDim2.new(0,0,1,3)
- forceWaterDirectionSelection("NegX")
- waterForceDirectionDropDown.Parent = waterForceDirLabel
-
- local waterForceDropDown, forceWaterForceSelection = t.CreateDropDownMenu(waterForces, waterForceSelectedFunc)
- forceWaterForceSelection("None")
- waterForceDropDown.Size = UDim2.new(1,0,0,25)
- waterForceDropDown.Position = UDim2.new(0,0,1,3)
- waterForceDropDown.Parent = waterForceLabel
-
- return waterFrame, waterTypeChangedEvent
- end
-
- -- Helper Function that contructs gui elements
- local function createSetGui()
-
- local setGui = Instance.new("ScreenGui")
- setGui.Name = "SetGui"
-
- local setPanel = Instance.new("Frame")
- setPanel.Name = "SetPanel"
- setPanel.Active = true
- setPanel.BackgroundTransparency = 1
- if position then
- setPanel.Position = position
- else
- setPanel.Position = UDim2.new(0.2, 29, 0.1, 24)
- end
- if size then
- setPanel.Size = size
- else
- setPanel.Size = UDim2.new(0.6, -58, 0.64, 0)
- end
- setPanel.Style = Enum.FrameStyle.RobloxRound
- setPanel.ZIndex = 6
- setPanel.Parent = setGui
-
- -- Children of SetPanel
- local itemPreview = Instance.new("Frame")
- itemPreview.Name = "ItemPreview"
- itemPreview.BackgroundTransparency = 1
- itemPreview.Position = UDim2.new(0.8,5,0.085,0)
- itemPreview.Size = UDim2.new(0.21,0,0.9,0)
- itemPreview.ZIndex = 6
- itemPreview.Parent = setPanel
-
- -- Children of ItemPreview
- local textPanel = Instance.new("Frame")
- textPanel.Name = "TextPanel"
- textPanel.BackgroundTransparency = 1
- textPanel.Position = UDim2.new(0,0,0.45,0)
- textPanel.Size = UDim2.new(1,0,0.55,0)
- textPanel.ZIndex = 6
- textPanel.Parent = itemPreview
-
- -- Children of TextPanel
- local rolloverText = Instance.new("TextLabel")
- rolloverText.Name = "RolloverText"
- rolloverText.BackgroundTransparency = 1
- rolloverText.Size = UDim2.new(1,0,0,48)
- rolloverText.ZIndex = 6
- rolloverText.Font = Enum.Font.ArialBold
- rolloverText.FontSize = Enum.FontSize.Size24
- rolloverText.Text = ""
- rolloverText.TextColor3 = Color3.new(1,1,1)
- rolloverText.TextWrap = true
- rolloverText.TextXAlignment = Enum.TextXAlignment.Left
- rolloverText.TextYAlignment = Enum.TextYAlignment.Top
- rolloverText.Parent = textPanel
-
- local largePreview = Instance.new("ImageLabel")
- largePreview.Name = "LargePreview"
- largePreview.BackgroundTransparency = 1
- largePreview.Image = ""
- largePreview.Size = UDim2.new(1,0,0,170)
- largePreview.ZIndex = 6
- largePreview.Parent = itemPreview
-
- local sets = Instance.new("Frame")
- sets.Name = "Sets"
- sets.BackgroundTransparency = 1
- sets.Position = UDim2.new(0,0,0,5)
- sets.Size = UDim2.new(0.23,0,1,-5)
- sets.ZIndex = 6
- sets.Parent = setPanel
-
- -- Children of Sets
- local line = Instance.new("Frame")
- line.Name = "Line"
- line.BackgroundColor3 = Color3.new(1,1,1)
- line.BackgroundTransparency = 0.7
- line.BorderSizePixel = 0
- line.Position = UDim2.new(1,-3,0.06,0)
- line.Size = UDim2.new(0,3,0.9,0)
- line.ZIndex = 6
- line.Parent = sets
-
- local setsLists, controlFrame = t.CreateTrueScrollingFrame()
- setsLists.Size = UDim2.new(1,-6,0.94,0)
- setsLists.Position = UDim2.new(0,0,0.06,0)
- setsLists.BackgroundTransparency = 1
- setsLists.Name = "SetsLists"
- setsLists.ZIndex = 6
- setsLists.Parent = sets
- drillDownSetZIndex(controlFrame, 7)
-
- local setsHeader = Instance.new("TextLabel")
- setsHeader.Name = "SetsHeader"
- setsHeader.BackgroundTransparency = 1
- setsHeader.Size = UDim2.new(0,47,0,24)
- setsHeader.ZIndex = 6
- setsHeader.Font = Enum.Font.ArialBold
- setsHeader.FontSize = Enum.FontSize.Size24
- setsHeader.Text = "Sets"
- setsHeader.TextColor3 = Color3.new(1,1,1)
- setsHeader.TextXAlignment = Enum.TextXAlignment.Left
- setsHeader.TextYAlignment = Enum.TextYAlignment.Top
- setsHeader.Parent = sets
-
- local cancelButton = Instance.new("TextButton")
- cancelButton.Name = "CancelButton"
- cancelButton.Position = UDim2.new(1,-32,0,-2)
- cancelButton.Size = UDim2.new(0,34,0,34)
- cancelButton.Style = Enum.ButtonStyle.RobloxButtonDefault
- cancelButton.ZIndex = 6
- cancelButton.Text = ""
- cancelButton.Modal = true
- cancelButton.Parent = setPanel
-
- -- Children of Cancel Button
- local cancelImage = Instance.new("ImageLabel")
- cancelImage.Name = "CancelImage"
- cancelImage.BackgroundTransparency = 1
- cancelImage.Image = "http://www.roblox.com/asset/?id=54135717"
- cancelImage.Position = UDim2.new(0,-2,0,-2)
- cancelImage.Size = UDim2.new(0,16,0,16)
- cancelImage.ZIndex = 6
- cancelImage.Parent = cancelButton
-
- return setGui
- end
-
- local function createSetButton(text)
- local setButton = Instance.new("TextButton")
-
- if text then setButton.Text = text
- else setButton.Text = "" end
-
- setButton.AutoButtonColor = false
- setButton.BackgroundTransparency = 1
- setButton.BackgroundColor3 = Color3.new(1,1,1)
- setButton.BorderSizePixel = 0
- setButton.Size = UDim2.new(1,-5,0,18)
- setButton.ZIndex = 6
- setButton.Visible = false
- setButton.Font = Enum.Font.Arial
- setButton.FontSize = Enum.FontSize.Size18
- setButton.TextColor3 = Color3.new(1,1,1)
- setButton.TextXAlignment = Enum.TextXAlignment.Left
-
- return setButton
- end
-
- local function buildSetButton(name, setId, setImageId, i, count)
- local button = createSetButton(name)
- button.Text = name
- button.Name = "SetButton"
- button.Visible = true
-
- local setValue = Instance.new("IntValue")
- setValue.Name = "SetId"
- setValue.Value = setId
- setValue.Parent = button
-
- local setName = Instance.new("StringValue")
- setName.Name = "SetName"
- setName.Value = name
- setName.Parent = button
-
- return button
- end
-
- local function processCategory(sets)
- local setButtons = {}
- local numSkipped = 0
- for i = 1, #sets do
- if not showAdminCategories and sets[i].Name == "Beta" then
- numSkipped = numSkipped + 1
- else
- setButtons[i - numSkipped] = buildSetButton(sets[i].Name, sets[i].CategoryId, sets[i].ImageAssetId, i - numSkipped, #sets)
- end
- end
- return setButtons
- end
-
- local function handleResize()
- wait() -- neccessary to insure heartbeat happened
-
- local itemPreview = setGui.SetPanel.ItemPreview
-
- itemPreview.LargePreview.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.X)
- itemPreview.LargePreview.Position = UDim2.new(0.5,-itemPreview.LargePreview.AbsoluteSize.X/2,0,0)
- itemPreview.TextPanel.Position = UDim2.new(0,0,0,itemPreview.LargePreview.AbsoluteSize.Y)
- itemPreview.TextPanel.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.Y - itemPreview.LargePreview.AbsoluteSize.Y)
- end
-
- local function makeInsertAssetButton()
- local insertAssetButtonExample = Instance.new("Frame")
- insertAssetButtonExample.Name = "InsertAssetButtonExample"
- insertAssetButtonExample.Position = UDim2.new(0,128,0,64)
- insertAssetButtonExample.Size = UDim2.new(0,64,0,64)
- insertAssetButtonExample.BackgroundTransparency = 1
- insertAssetButtonExample.ZIndex = 6
- insertAssetButtonExample.Visible = false
-
- local assetId = Instance.new("IntValue")
- assetId.Name = "AssetId"
- assetId.Value = 0
- assetId.Parent = insertAssetButtonExample
-
- local assetName = Instance.new("StringValue")
- assetName.Name = "AssetName"
- assetName.Value = ""
- assetName.Parent = insertAssetButtonExample
-
- local button = Instance.new("TextButton")
- button.Name = "Button"
- button.Text = ""
- button.Style = Enum.ButtonStyle.RobloxButton
- button.Position = UDim2.new(0.025,0,0.025,0)
- button.Size = UDim2.new(0.95,0,0.95,0)
- button.ZIndex = 6
- button.Parent = insertAssetButtonExample
-
- local buttonImage = Instance.new("ImageLabel")
- buttonImage.Name = "ButtonImage"
- buttonImage.Image = ""
- buttonImage.Position = UDim2.new(0,-7,0,-7)
- buttonImage.Size = UDim2.new(1,14,1,14)
- buttonImage.BackgroundTransparency = 1
- buttonImage.ZIndex = 7
- buttonImage.Parent = button
-
- local configIcon = buttonImage:clone()
- configIcon.Name = "ConfigIcon"
- configIcon.Visible = false
- configIcon.Position = UDim2.new(1,-23,1,-24)
- configIcon.Size = UDim2.new(0,16,0,16)
- configIcon.Image = ""
- configIcon.ZIndex = 6
- configIcon.Parent = insertAssetButtonExample
-
- return insertAssetButtonExample
- end
-
- local function showLargePreview(insertButton)
- if insertButton:FindFirstChild("AssetId") then
- delay(0,function()
- game:GetService("ContentProvider"):Preload(LargeThumbnailUrl .. tostring(insertButton.AssetId.Value))
- setGui.SetPanel.ItemPreview.LargePreview.Image = LargeThumbnailUrl .. tostring(insertButton.AssetId.Value)
- end)
- end
- if insertButton:FindFirstChild("AssetName") then
- setGui.SetPanel.ItemPreview.TextPanel.RolloverText.Text = insertButton.AssetName.Value
- end
- end
-
- local function selectTerrainShape(shape)
- if currTerrainDropDownFrame then
- objectSelected(tostring(currTerrainDropDownFrame.AssetName.Value), tonumber(currTerrainDropDownFrame.AssetId.Value), shape)
- end
- end
-
- local function createTerrainTypeButton(name, parent)
- local dropDownTextButton = Instance.new("TextButton")
- dropDownTextButton.Name = name .. "Button"
- dropDownTextButton.Font = Enum.Font.ArialBold
- dropDownTextButton.FontSize = Enum.FontSize.Size14
- dropDownTextButton.BorderSizePixel = 0
- dropDownTextButton.TextColor3 = Color3.new(1,1,1)
- dropDownTextButton.Text = name
- dropDownTextButton.TextXAlignment = Enum.TextXAlignment.Left
- dropDownTextButton.BackgroundTransparency = 1
- dropDownTextButton.ZIndex = parent.ZIndex + 1
- dropDownTextButton.Size = UDim2.new(0,parent.Size.X.Offset - 2,0,16)
- dropDownTextButton.Position = UDim2.new(0,1,0,0)
-
- dropDownTextButton.MouseEnter:connect(function()
- dropDownTextButton.BackgroundTransparency = 0
- dropDownTextButton.TextColor3 = Color3.new(0,0,0)
- end)
-
- dropDownTextButton.MouseLeave:connect(function()
- dropDownTextButton.BackgroundTransparency = 1
- dropDownTextButton.TextColor3 = Color3.new(1,1,1)
- end)
-
- dropDownTextButton.MouseButton1Click:connect(function()
- dropDownTextButton.BackgroundTransparency = 1
- dropDownTextButton.TextColor3 = Color3.new(1,1,1)
- if dropDownTextButton.Parent and dropDownTextButton.Parent:IsA("GuiObject") then
- dropDownTextButton.Parent.Visible = false
- end
- selectTerrainShape(terrainShapeMap[dropDownTextButton.Text])
- end)
-
- return dropDownTextButton
- end
-
- local function createTerrainDropDownMenu(zIndex)
- local dropDown = Instance.new("Frame")
- dropDown.Name = "TerrainDropDown"
- dropDown.BackgroundColor3 = Color3.new(0,0,0)
- dropDown.BorderColor3 = Color3.new(1,0,0)
- dropDown.Size = UDim2.new(0,200,0,0)
- dropDown.Visible = false
- dropDown.ZIndex = zIndex
- dropDown.Parent = setGui
-
- for i = 1, #terrainShapes do
- local shapeButton = createTerrainTypeButton(terrainShapes[i],dropDown)
- shapeButton.Position = UDim2.new(0,1,0,(i - 1) * (shapeButton.Size.Y.Offset))
- shapeButton.Parent = dropDown
- dropDown.Size = UDim2.new(0,200,0,dropDown.Size.Y.Offset + (shapeButton.Size.Y.Offset))
- end
-
- dropDown.MouseLeave:connect(function()
- dropDown.Visible = false
- end)
- end
-
-
- local function createDropDownMenuButton(parent)
- local dropDownButton = Instance.new("ImageButton")
- dropDownButton.Name = "DropDownButton"
- dropDownButton.Image = "http://www.roblox.com/asset/?id=67581509"
- dropDownButton.BackgroundTransparency = 1
- dropDownButton.Size = UDim2.new(0,16,0,16)
- dropDownButton.Position = UDim2.new(1,-24,0,6)
- dropDownButton.ZIndex = parent.ZIndex + 2
- dropDownButton.Parent = parent
-
- if not setGui:FindFirstChild("TerrainDropDown") then
- createTerrainDropDownMenu(8)
- end
-
- dropDownButton.MouseButton1Click:connect(function()
- setGui.TerrainDropDown.Visible = true
- setGui.TerrainDropDown.Position = UDim2.new(0,parent.AbsolutePosition.X,0,parent.AbsolutePosition.Y)
- currTerrainDropDownFrame = parent
- end)
- end
-
- local function buildInsertButton()
- local insertButton = makeInsertAssetButton()
- insertButton.Name = "InsertAssetButton"
- insertButton.Visible = true
-
- if Data.Category[Data.CurrentCategory].SetName == "High Scalability" then
- createDropDownMenuButton(insertButton)
- end
-
- local lastEnter = nil
- local mouseEnterCon = insertButton.MouseEnter:connect(function()
- lastEnter = insertButton
- delay(0.1,function()
- if lastEnter == insertButton then
- showLargePreview(insertButton)
- end
- end)
- end)
- return insertButton, mouseEnterCon
- end
-
- local function realignButtonGrid(columns)
- local x = 0
- local y = 0
- for i = 1, #insertButtons do
- insertButtons[i].Position = UDim2.new(0, buttonWidth * x, 0, buttonHeight * y)
- x = x + 1
- if x >= columns then
- x = 0
- y = y + 1
- end
- end
- end
-
- local function setInsertButtonImageBehavior(insertFrame, visible, name, assetId)
- if visible then
- insertFrame.AssetName.Value = name
- insertFrame.AssetId.Value = assetId
- local newImageUrl = SmallThumbnailUrl .. assetId
- if newImageUrl ~= insertFrame.Button.ButtonImage.Image then
- delay(0,function()
- game:GetService("ContentProvider"):Preload(SmallThumbnailUrl .. assetId)
- if insertFrame:findFirstChild("Button") then
- insertFrame.Button.ButtonImage.Image = SmallThumbnailUrl .. assetId
- end
- end)
- end
- table.insert(insertButtonCons,
- insertFrame.Button.MouseButton1Click:connect(function()
- -- special case for water, show water selection gui
- local isWaterSelected = (name == "Water") and (Data.Category[Data.CurrentCategory].SetName == "High Scalability")
- waterGui.Visible = isWaterSelected
- if isWaterSelected then
- objectSelected(name, tonumber(assetId), nil)
- else
- objectSelected(name, tonumber(assetId))
- end
- end)
- )
- insertFrame.Visible = true
- else
- insertFrame.Visible = false
- end
- end
-
- local function loadSectionOfItems(setGui, rows, columns)
- local pageSize = rows * columns
-
- if arrayPosition > #contents then return end
-
- local origArrayPos = arrayPosition
-
- local yCopy = 0
- for i = 1, pageSize + 1 do
- if arrayPosition >= #contents + 1 then
- break
- end
-
- local buttonCon
- insertButtons[arrayPosition], buttonCon = buildInsertButton()
- table.insert(insertButtonCons,buttonCon)
- insertButtons[arrayPosition].Parent = setGui.SetPanel.ItemsFrame
- arrayPosition = arrayPosition + 1
- end
- realignButtonGrid(columns)
-
- local indexCopy = origArrayPos
- for index = origArrayPos, arrayPosition do
- if insertButtons[index] then
- if contents[index] then
-
- -- we don't want water to have a drop down button
- if contents[index].Name == "Water" then
- if Data.Category[Data.CurrentCategory].SetName == "High Scalability" then
- insertButtons[index]:FindFirstChild("DropDownButton",true):Destroy()
- end
- end
-
- local assetId
- if useAssetVersionId then
- assetId = contents[index].AssetVersionId
- else
- assetId = contents[index].AssetId
- end
- setInsertButtonImageBehavior(insertButtons[index], true, contents[index].Name, assetId)
- else
- break
- end
- else
- break
- end
- indexCopy = index
- end
- end
-
- local function setSetIndex()
- Data.Category[Data.CurrentCategory].Index = 0
-
- rows = 7
- columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth)
-
- contents = Data.Category[Data.CurrentCategory].Contents
- if contents then
- -- remove our buttons and their connections
- for i = 1, #insertButtons do
- insertButtons[i]:remove()
- end
- for i = 1, #insertButtonCons do
- if insertButtonCons[i] then insertButtonCons[i]:disconnect() end
- end
- insertButtonCons = {}
- insertButtons = {}
-
- arrayPosition = 1
- loadSectionOfItems(setGui, rows, columns)
- end
- end
-
- local function selectSet(button, setName, setId, setIndex)
- if button and Data.Category[Data.CurrentCategory] ~= nil then
- if button ~= Data.Category[Data.CurrentCategory].Button then
- Data.Category[Data.CurrentCategory].Button = button
-
- if SetCache[setId] == nil then
- SetCache[setId] = game:GetService("InsertService"):GetCollection(setId)
- end
- Data.Category[Data.CurrentCategory].Contents = SetCache[setId]
-
- Data.Category[Data.CurrentCategory].SetName = setName
- Data.Category[Data.CurrentCategory].SetId = setId
- end
- setSetIndex()
- end
- end
-
- local function selectCategoryPage(buttons, page)
- if buttons ~= Data.CurrentCategory then
- if Data.CurrentCategory then
- for key, button in pairs(Data.CurrentCategory) do
- button.Visible = false
- end
- end
-
- Data.CurrentCategory = buttons
- if Data.Category[Data.CurrentCategory] == nil then
- Data.Category[Data.CurrentCategory] = {}
- if #buttons > 0 then
- selectSet(buttons[1], buttons[1].SetName.Value, buttons[1].SetId.Value, 0)
- end
- else
- Data.Category[Data.CurrentCategory].Button = nil
- selectSet(Data.Category[Data.CurrentCategory].ButtonFrame, Data.Category[Data.CurrentCategory].SetName, Data.Category[Data.CurrentCategory].SetId, Data.Category[Data.CurrentCategory].Index)
- end
- end
- end
-
- local function selectCategory(category)
- selectCategoryPage(category, 0)
- end
-
- local function resetAllSetButtonSelection()
- local setButtons = setGui.SetPanel.Sets.SetsLists:GetChildren()
- for i = 1, #setButtons do
- if setButtons[i]:IsA("TextButton") then
- setButtons[i].Selected = false
- setButtons[i].BackgroundTransparency = 1
- setButtons[i].TextColor3 = Color3.new(1,1,1)
- setButtons[i].BackgroundColor3 = Color3.new(1,1,1)
- end
- end
- end
-
- local function populateSetsFrame()
- local currRow = 0
- for i = 1, #userCategoryButtons do
- local button = userCategoryButtons[i]
- button.Visible = true
- button.Position = UDim2.new(0,5,0,currRow * button.Size.Y.Offset)
- button.Parent = setGui.SetPanel.Sets.SetsLists
-
- if i == 1 then -- we will have this selected by default, so show it
- button.Selected = true
- button.BackgroundColor3 = Color3.new(0,204/255,0)
- button.TextColor3 = Color3.new(0,0,0)
- button.BackgroundTransparency = 0
- end
-
- button.MouseEnter:connect(function()
- if not button.Selected then
- button.BackgroundTransparency = 0
- button.TextColor3 = Color3.new(0,0,0)
- end
- end)
- button.MouseLeave:connect(function()
- if not button.Selected then
- button.BackgroundTransparency = 1
- button.TextColor3 = Color3.new(1,1,1)
- end
- end)
- button.MouseButton1Click:connect(function()
- resetAllSetButtonSelection()
- button.Selected = not button.Selected
- button.BackgroundColor3 = Color3.new(0,204/255,0)
- button.TextColor3 = Color3.new(0,0,0)
- button.BackgroundTransparency = 0
- selectSet(button, button.Text, userCategoryButtons[i].SetId.Value, 0)
- end)
-
- currRow = currRow + 1
- end
-
- local buttons = setGui.SetPanel.Sets.SetsLists:GetChildren()
-
- -- set first category as loaded for default
- if buttons then
- for i = 1, #buttons do
- if buttons[i]:IsA("TextButton") then
- selectSet(buttons[i], buttons[i].Text, userCategoryButtons[i].SetId.Value, 0)
- selectCategory(userCategoryButtons)
- break
- end
- end
- end
- end
-
- setGui = createSetGui()
- waterGui, waterTypeChangedEvent = createWaterGui()
- waterGui.Position = UDim2.new(0,55,0,0)
- waterGui.Parent = setGui
- setGui.Changed:connect(function(prop) -- this resizes the preview image to always be the right size
- if prop == "AbsoluteSize" then
- handleResize()
- setSetIndex()
- end
- end)
-
- local scrollFrame, controlFrame = t.CreateTrueScrollingFrame()
- scrollFrame.Size = UDim2.new(0.54,0,0.85,0)
- scrollFrame.Position = UDim2.new(0.24,0,0.085,0)
- scrollFrame.Name = "ItemsFrame"
- scrollFrame.ZIndex = 6
- scrollFrame.Parent = setGui.SetPanel
- scrollFrame.BackgroundTransparency = 1
-
- drillDownSetZIndex(controlFrame,7)
-
- controlFrame.Parent = setGui.SetPanel
- controlFrame.Position = UDim2.new(0.76, 5, 0, 0)
-
- local debounce = false
- controlFrame.ScrollBottom.Changed:connect(function(prop)
- if controlFrame.ScrollBottom.Value == true then
- if debounce then return end
- debounce = true
- loadSectionOfItems(setGui, rows, columns)
- debounce = false
- end
- end)
-
- local userData = {}
- for id = 1, #userIdsForSets do
- local newUserData = game:GetService("InsertService"):GetUserSets(userIdsForSets[id])
- if newUserData and #newUserData > 2 then
- -- start at #3 to skip over My Decals and My Models for each account
- for category = 3, #newUserData do
- if newUserData[category].Name == "High Scalability" then -- we want high scalability parts to show first
- table.insert(userData,1,newUserData[category])
- else
- table.insert(userData, newUserData[category])
- end
- end
- end
-
- end
- if userData then
- userCategoryButtons = processCategory(userData)
- end
-
- rows = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.Y/buttonHeight)
- columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth)
-
- populateSetsFrame()
-
- insertPanelCloseCon = setGui.SetPanel.CancelButton.MouseButton1Click:connect(function()
- setGui.SetPanel.Visible = false
- if dialogClosed then dialogClosed() end
- end)
-
- local setVisibilityFunction = function(visible)
- if visible then
- setGui.SetPanel.Visible = true
- else
- setGui.SetPanel.Visible = false
- end
- end
-
- local getVisibilityFunction = function()
- if setGui then
- if setGui:FindFirstChild("SetPanel") then
- return setGui.SetPanel.Visible
- end
- end
-
- return false
- end
-
- return setGui, setVisibilityFunction, getVisibilityFunction, waterTypeChangedEvent
-end
-
-t.CreateTerrainMaterialSelector = function(size,position)
- local terrainMaterialSelectionChanged = Instance.new("BindableEvent")
- terrainMaterialSelectionChanged.Name = "TerrainMaterialSelectionChanged"
-
- local selectedButton = nil
-
- local frame = Instance.new("Frame")
- frame.Name = "TerrainMaterialSelector"
- if size then
- frame.Size = size
- else
- frame.Size = UDim2.new(0, 245, 0, 230)
- end
- if position then
- frame.Position = position
- end
- frame.BorderSizePixel = 0
- frame.BackgroundColor3 = Color3.new(0,0,0)
- frame.Active = true
-
- terrainMaterialSelectionChanged.Parent = frame
-
- local waterEnabled = true -- todo: turn this on when water is ready
-
- local materialToImageMap = {}
- local materialNames = {"Grass", "Sand", "Brick", "Granite", "Asphalt", "Iron", "Aluminum", "Gold", "Plank", "Log", "Gravel", "Cinder Block", "Stone Wall", "Concrete", "Plastic (red)", "Plastic (blue)"}
- if waterEnabled then
- table.insert(materialNames,"Water")
- end
- local currentMaterial = 1
-
- function getEnumFromName(choice)
- if choice == "Grass" then return 1 end
- if choice == "Sand" then return 2 end
- if choice == "Erase" then return 0 end
- if choice == "Brick" then return 3 end
- if choice == "Granite" then return 4 end
- if choice == "Asphalt" then return 5 end
- if choice == "Iron" then return 6 end
- if choice == "Aluminum" then return 7 end
- if choice == "Gold" then return 8 end
- if choice == "Plank" then return 9 end
- if choice == "Log" then return 10 end
- if choice == "Gravel" then return 11 end
- if choice == "Cinder Block" then return 12 end
- if choice == "Stone Wall" then return 13 end
- if choice == "Concrete" then return 14 end
- if choice == "Plastic (red)" then return 15 end
- if choice == "Plastic (blue)" then return 16 end
- if choice == "Water" then return 17 end
- end
-
- function getNameFromEnum(choice)
- if choice == Enum.CellMaterial.Grass or choice == 1 then return "Grass"end
- if choice == Enum.CellMaterial.Sand or choice == 2 then return "Sand" end
- if choice == Enum.CellMaterial.Empty or choice == 0 then return "Erase" end
- if choice == Enum.CellMaterial.Brick or choice == 3 then return "Brick" end
- if choice == Enum.CellMaterial.Granite or choice == 4 then return "Granite" end
- if choice == Enum.CellMaterial.Asphalt or choice == 5 then return "Asphalt" end
- if choice == Enum.CellMaterial.Iron or choice == 6 then return "Iron" end
- if choice == Enum.CellMaterial.Aluminum or choice == 7 then return "Aluminum" end
- if choice == Enum.CellMaterial.Gold or choice == 8 then return "Gold" end
- if choice == Enum.CellMaterial.WoodPlank or choice == 9 then return "Plank" end
- if choice == Enum.CellMaterial.WoodLog or choice == 10 then return "Log" end
- if choice == Enum.CellMaterial.Gravel or choice == 11 then return "Gravel" end
- if choice == Enum.CellMaterial.CinderBlock or choice == 12 then return "Cinder Block" end
- if choice == Enum.CellMaterial.MossyStone or choice == 13 then return "Stone Wall" end
- if choice == Enum.CellMaterial.Cement or choice == 14 then return "Concrete" end
- if choice == Enum.CellMaterial.RedPlastic or choice == 15 then return "Plastic (red)" end
- if choice == Enum.CellMaterial.BluePlastic or choice == 16 then return "Plastic (blue)" end
-
- if waterEnabled then
- if choice == Enum.CellMaterial.Water or choice == 17 then return "Water" end
- end
- end
-
-
- local function updateMaterialChoice(choice)
- currentMaterial = getEnumFromName(choice)
- terrainMaterialSelectionChanged:Fire(currentMaterial)
- end
-
- -- we so need a better way to do this
- for i,v in pairs(materialNames) do
- materialToImageMap[v] = {}
- if v == "Grass" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=56563112"
- elseif v == "Sand" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=62356652"
- elseif v == "Brick" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=65961537"
- elseif v == "Granite" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532153"
- elseif v == "Asphalt" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532038"
- elseif v == "Iron" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532093"
- elseif v == "Aluminum" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531995"
- elseif v == "Gold" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532118"
- elseif v == "Plastic (red)" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531848"
- elseif v == "Plastic (blue)" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531924"
- elseif v == "Plank" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532015"
- elseif v == "Log" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532051"
- elseif v == "Gravel" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532206"
- elseif v == "Cinder Block" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532103"
- elseif v == "Stone Wall" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531804"
- elseif v == "Concrete" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532059"
- elseif v == "Water" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=81407474"
- else materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=66887593" -- fill in the rest here!!
- end
- end
-
- local scrollFrame, scrollUp, scrollDown, recalculateScroll = t.CreateScrollingFrame(nil,"grid")
- scrollFrame.Size = UDim2.new(0.85,0,1,0)
- scrollFrame.Position = UDim2.new(0,0,0,0)
- scrollFrame.Parent = frame
-
- scrollUp.Parent = frame
- scrollUp.Visible = true
- scrollUp.Position = UDim2.new(1,-19,0,0)
-
- scrollDown.Parent = frame
- scrollDown.Visible = true
- scrollDown.Position = UDim2.new(1,-19,1,-17)
-
- local function goToNewMaterial(buttonWrap, materialName)
- updateMaterialChoice(materialName)
- buttonWrap.BackgroundTransparency = 0
- selectedButton.BackgroundTransparency = 1
- selectedButton = buttonWrap
- end
-
- local function createMaterialButton(name)
- local buttonWrap = Instance.new("TextButton")
- buttonWrap.Text = ""
- buttonWrap.Size = UDim2.new(0,32,0,32)
- buttonWrap.BackgroundColor3 = Color3.new(1,1,1)
- buttonWrap.BorderSizePixel = 0
- buttonWrap.BackgroundTransparency = 1
- buttonWrap.AutoButtonColor = false
- buttonWrap.Name = tostring(name)
-
- local imageButton = Instance.new("ImageButton")
- imageButton.AutoButtonColor = false
- imageButton.BackgroundTransparency = 1
- imageButton.Size = UDim2.new(0,30,0,30)
- imageButton.Position = UDim2.new(0,1,0,1)
- imageButton.Name = tostring(name)
- imageButton.Parent = buttonWrap
- imageButton.Image = materialToImageMap[name].Regular
-
- local enumType = Instance.new("NumberValue")
- enumType.Name = "EnumType"
- enumType.Parent = buttonWrap
- enumType.Value = 0
-
- imageButton.MouseEnter:connect(function()
- buttonWrap.BackgroundTransparency = 0
- end)
- imageButton.MouseLeave:connect(function()
- if selectedButton ~= buttonWrap then
- buttonWrap.BackgroundTransparency = 1
- end
- end)
- imageButton.MouseButton1Click:connect(function()
- if selectedButton ~= buttonWrap then
- goToNewMaterial(buttonWrap, tostring(name))
- end
- end)
-
- return buttonWrap
- end
-
- for i = 1, #materialNames do
- local imageButton = createMaterialButton(materialNames[i])
-
- if materialNames[i] == "Grass" then -- always start with grass as the default
- selectedButton = imageButton
- imageButton.BackgroundTransparency = 0
- end
-
- imageButton.Parent = scrollFrame
- end
-
- local forceTerrainMaterialSelection = function(newMaterialType)
- if not newMaterialType then return end
- if currentMaterial == newMaterialType then return end
-
- local matName = getNameFromEnum(newMaterialType)
- local buttons = scrollFrame:GetChildren()
- for i = 1, #buttons do
- if buttons[i].Name == "Plastic (blue)" and matName == "Plastic (blue)" then goToNewMaterial(buttons[i],matName) return end
- if buttons[i].Name == "Plastic (red)" and matName == "Plastic (red)" then goToNewMaterial(buttons[i],matName) return end
- if string.find(buttons[i].Name, matName) then
- goToNewMaterial(buttons[i],matName)
- return
- end
- end
- end
-
- frame.Changed:connect(function ( prop )
- if prop == "AbsoluteSize" then
- recalculateScroll()
- end
- end)
-
- recalculateScroll()
- return frame, terrainMaterialSelectionChanged, forceTerrainMaterialSelection
-end
-
-t.CreateLoadingFrame = function(name,size,position)
- game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=35238053")
-
- local loadingFrame = Instance.new("Frame")
- loadingFrame.Name = "LoadingFrame"
- loadingFrame.Style = Enum.FrameStyle.RobloxRound
-
- if size then loadingFrame.Size = size
- else loadingFrame.Size = UDim2.new(0,300,0,160) end
- if position then loadingFrame.Position = position
- else loadingFrame.Position = UDim2.new(0.5, -150, 0.5,-80) end
-
- local loadingBar = Instance.new("Frame")
- loadingBar.Name = "LoadingBar"
- loadingBar.BackgroundColor3 = Color3.new(0,0,0)
- loadingBar.BorderColor3 = Color3.new(79/255,79/255,79/255)
- loadingBar.Position = UDim2.new(0,0,0,41)
- loadingBar.Size = UDim2.new(1,0,0,30)
- loadingBar.Parent = loadingFrame
-
- local loadingGreenBar = Instance.new("ImageLabel")
- loadingGreenBar.Name = "LoadingGreenBar"
- loadingGreenBar.Image = "http://www.roblox.com/asset/?id=35238053"
- loadingGreenBar.Position = UDim2.new(0,0,0,0)
- loadingGreenBar.Size = UDim2.new(0,0,1,0)
- loadingGreenBar.Visible = false
- loadingGreenBar.Parent = loadingBar
-
- local loadingPercent = Instance.new("TextLabel")
- loadingPercent.Name = "LoadingPercent"
- loadingPercent.BackgroundTransparency = 1
- loadingPercent.Position = UDim2.new(0,0,1,0)
- loadingPercent.Size = UDim2.new(1,0,0,14)
- loadingPercent.Font = Enum.Font.Arial
- loadingPercent.Text = "0%"
- loadingPercent.FontSize = Enum.FontSize.Size14
- loadingPercent.TextColor3 = Color3.new(1,1,1)
- loadingPercent.Parent = loadingBar
-
- local cancelButton = Instance.new("TextButton")
- cancelButton.Name = "CancelButton"
- cancelButton.Position = UDim2.new(0.5,-60,1,-40)
- cancelButton.Size = UDim2.new(0,120,0,40)
- cancelButton.Font = Enum.Font.Arial
- cancelButton.FontSize = Enum.FontSize.Size18
- cancelButton.TextColor3 = Color3.new(1,1,1)
- cancelButton.Text = "Cancel"
- cancelButton.Style = Enum.ButtonStyle.RobloxButton
- cancelButton.Parent = loadingFrame
-
- local loadingName = Instance.new("TextLabel")
- loadingName.Name = "loadingName"
- loadingName.BackgroundTransparency = 1
- loadingName.Size = UDim2.new(1,0,0,18)
- loadingName.Position = UDim2.new(0,0,0,2)
- loadingName.Font = Enum.Font.Arial
- loadingName.Text = name
- loadingName.TextColor3 = Color3.new(1,1,1)
- loadingName.TextStrokeTransparency = 1
- loadingName.FontSize = Enum.FontSize.Size18
- loadingName.Parent = loadingFrame
-
- local cancelButtonClicked = Instance.new("BindableEvent")
- cancelButtonClicked.Name = "CancelButtonClicked"
- cancelButtonClicked.Parent = cancelButton
- cancelButton.MouseButton1Click:connect(function()
- cancelButtonClicked:Fire()
- end)
-
- local updateLoadingGuiPercent = function(percent, tweenAction, tweenLength)
- if percent and type(percent) ~= "number" then
- error("updateLoadingGuiPercent expects number as argument, got",type(percent),"instead")
- end
-
- local newSize = nil
- if percent < 0 then
- newSize = UDim2.new(0,0,1,0)
- elseif percent > 1 then
- newSize = UDim2.new(1,0,1,0)
- else
- newSize = UDim2.new(percent,0,1,0)
- end
-
- if tweenAction then
- if not tweenLength then
- error("updateLoadingGuiPercent is set to tween new percentage, but got no tween time length! Please pass this in as third argument")
- end
-
- if (newSize.X.Scale > 0) then
- loadingGreenBar.Visible = true
- loadingGreenBar:TweenSize( newSize,
- Enum.EasingDirection.Out,
- Enum.EasingStyle.Quad,
- tweenLength,
- true)
- else
- loadingGreenBar:TweenSize( newSize,
- Enum.EasingDirection.Out,
- Enum.EasingStyle.Quad,
- tweenLength,
- true,
- function()
- if (newSize.X.Scale < 0) then
- loadingGreenBar.Visible = false
- end
- end)
- end
-
- else
- loadingGreenBar.Size = newSize
- loadingGreenBar.Visible = (newSize.X.Scale > 0)
- end
- end
-
- loadingGreenBar.Changed:connect(function(prop)
- if prop == "Size" then
- loadingPercent.Text = tostring( math.ceil(loadingGreenBar.Size.X.Scale * 100) ) .. "%"
- end
- end)
-
- return loadingFrame, updateLoadingGuiPercent, cancelButtonClicked
-end
-
-t.CreatePluginFrame = function (name,size,position,scrollable,parent)
- function createMenuButton(size,position,text,fontsize,name,parent)
- local button = Instance.new("TextButton",parent)
- button.AutoButtonColor = false
- button.Name = name
- button.BackgroundTransparency = 1
- button.Position = position
- button.Size = size
- button.Font = Enum.Font.ArialBold
- button.FontSize = fontsize
- button.Text = text
- button.TextColor3 = Color3.new(1,1,1)
- button.BorderSizePixel = 0
- button.BackgroundColor3 = Color3.new(20/255,20/255,20/255)
-
- button.MouseEnter:connect(function ( )
- if button.Selected then return end
- button.BackgroundTransparency = 0
- end)
- button.MouseLeave:connect(function ( )
- if button.Selected then return end
- button.BackgroundTransparency = 1
- end)
-
- return button
-
- end
-
- local dragBar = Instance.new("Frame",parent)
- dragBar.Name = tostring(name) .. "DragBar"
- dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255)
- dragBar.BorderColor3 = Color3.new(0,0,0)
- if size then
- dragBar.Size = UDim2.new(size.X.Scale,size.X.Offset,0,20) + UDim2.new(0,20,0,0)
- else
- dragBar.Size = UDim2.new(0,183,0,20)
- end
- if position then
- dragBar.Position = position
- end
- dragBar.Active = true
- dragBar.Draggable = true
- --dragBar.Visible = false
- dragBar.MouseEnter:connect(function ( )
- dragBar.BackgroundColor3 = Color3.new(49/255,49/255,49/255)
- end)
- dragBar.MouseLeave:connect(function ( )
- dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255)
- end)
-
- -- plugin name label
- local pluginNameLabel = Instance.new("TextLabel",dragBar)
- pluginNameLabel.Name = "BarNameLabel"
- pluginNameLabel.Text = " " .. tostring(name)
- pluginNameLabel.TextColor3 = Color3.new(1,1,1)
- pluginNameLabel.TextStrokeTransparency = 0
- pluginNameLabel.Size = UDim2.new(1,0,1,0)
- pluginNameLabel.Font = Enum.Font.ArialBold
- pluginNameLabel.FontSize = Enum.FontSize.Size18
- pluginNameLabel.TextXAlignment = Enum.TextXAlignment.Left
- pluginNameLabel.BackgroundTransparency = 1
-
- -- close button
- local closeButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-16,0.5,-8),"X",Enum.FontSize.Size14,"CloseButton",dragBar)
- local closeEvent = Instance.new("BindableEvent")
- closeEvent.Name = "CloseEvent"
- closeEvent.Parent = closeButton
- closeButton.MouseButton1Click:connect(function ()
- closeEvent:Fire()
- closeButton.BackgroundTransparency = 1
- end)
-
- -- help button
- local helpButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-51,0.5,-8),"?",Enum.FontSize.Size14,"HelpButton",dragBar)
- local helpFrame = Instance.new("Frame",dragBar)
- helpFrame.Name = "HelpFrame"
- helpFrame.BackgroundColor3 = Color3.new(0,0,0)
- helpFrame.Size = UDim2.new(0,300,0,552)
- helpFrame.Position = UDim2.new(1,5,0,0)
- helpFrame.Active = true
- helpFrame.BorderSizePixel = 0
- helpFrame.Visible = false
-
- helpButton.MouseButton1Click:connect(function( )
- helpFrame.Visible = not helpFrame.Visible
- if helpFrame.Visible then
- helpButton.Selected = true
- helpButton.BackgroundTransparency = 0
- local screenGui = getScreenGuiAncestor(helpFrame)
- if screenGui then
- if helpFrame.AbsolutePosition.X + helpFrame.AbsoluteSize.X > screenGui.AbsoluteSize.X then --position on left hand side
- helpFrame.Position = UDim2.new(0,-5 - helpFrame.AbsoluteSize.X,0,0)
- else -- position on right hand side
- helpFrame.Position = UDim2.new(1,5,0,0)
- end
- else
- helpFrame.Position = UDim2.new(1,5,0,0)
- end
- else
- helpButton.Selected = false
- helpButton.BackgroundTransparency = 1
- end
- end)
-
- local minimizeButton = createMenuButton(UDim2.new(0,16,0,17),UDim2.new(1,-34,0.5,-8),"-",Enum.FontSize.Size14,"MinimizeButton",dragBar)
- minimizeButton.TextYAlignment = Enum.TextYAlignment.Top
-
- local minimizeFrame = Instance.new("Frame",dragBar)
- minimizeFrame.Name = "MinimizeFrame"
- minimizeFrame.BackgroundColor3 = Color3.new(73/255,73/255,73/255)
- minimizeFrame.BorderColor3 = Color3.new(0,0,0)
- minimizeFrame.Position = UDim2.new(0,0,1,0)
- if size then
- minimizeFrame.Size = UDim2.new(size.X.Scale,size.X.Offset,0,50) + UDim2.new(0,20,0,0)
- else
- minimizeFrame.Size = UDim2.new(0,183,0,50)
- end
- minimizeFrame.Visible = false
-
- local minimizeBigButton = Instance.new("TextButton",minimizeFrame)
- minimizeBigButton.Position = UDim2.new(0.5,-50,0.5,-20)
- minimizeBigButton.Name = "MinimizeButton"
- minimizeBigButton.Size = UDim2.new(0,100,0,40)
- minimizeBigButton.Style = Enum.ButtonStyle.RobloxButton
- minimizeBigButton.Font = Enum.Font.ArialBold
- minimizeBigButton.FontSize = Enum.FontSize.Size18
- minimizeBigButton.TextColor3 = Color3.new(1,1,1)
- minimizeBigButton.Text = "Show"
-
- local separatingLine = Instance.new("Frame",dragBar)
- separatingLine.Name = "SeparatingLine"
- separatingLine.BackgroundColor3 = Color3.new(115/255,115/255,115/255)
- separatingLine.BorderSizePixel = 0
- separatingLine.Position = UDim2.new(1,-18,0.5,-7)
- separatingLine.Size = UDim2.new(0,1,0,14)
-
- local otherSeparatingLine = separatingLine:clone()
- otherSeparatingLine.Position = UDim2.new(1,-35,0.5,-7)
- otherSeparatingLine.Parent = dragBar
-
- local widgetContainer = Instance.new("Frame",dragBar)
- widgetContainer.Name = "WidgetContainer"
- widgetContainer.BackgroundTransparency = 1
- widgetContainer.Position = UDim2.new(0,0,1,0)
- widgetContainer.BorderColor3 = Color3.new(0,0,0)
- if not scrollable then
- widgetContainer.BackgroundTransparency = 0
- widgetContainer.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
- end
-
- if size then
- if scrollable then
- widgetContainer.Size = size
- else
- widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,size.Y.Scale,size.Y.Offset)
- end
- else
- if scrollable then
- widgetContainer.Size = UDim2.new(0,163,0,400)
- else
- widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,0,400)
- end
- end
- if position then
- widgetContainer.Position = position + UDim2.new(0,0,0,20)
- end
-
- local frame,control,verticalDragger = nil
- if scrollable then
- --frame for widgets
- frame,control = t.CreateTrueScrollingFrame()
- frame.Size = UDim2.new(1, 0, 1, 0)
- frame.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
- frame.BorderColor3 = Color3.new(0,0,0)
- frame.Active = true
- frame.Parent = widgetContainer
- control.Parent = dragBar
- control.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
- control.BorderSizePixel = 0
- control.BackgroundTransparency = 0
- control.Position = UDim2.new(1,-21,1,1)
- if size then
- control.Size = UDim2.new(0,21,size.Y.Scale,size.Y.Offset)
- else
- control.Size = UDim2.new(0,21,0,400)
- end
- control:FindFirstChild("ScrollDownButton").Position = UDim2.new(0,0,1,-20)
-
- local fakeLine = Instance.new("Frame",control)
- fakeLine.Name = "FakeLine"
- fakeLine.BorderSizePixel = 0
- fakeLine.BackgroundColor3 = Color3.new(0,0,0)
- fakeLine.Size = UDim2.new(0,1,1,1)
- fakeLine.Position = UDim2.new(1,0,0,0)
-
- verticalDragger = Instance.new("TextButton",widgetContainer)
- verticalDragger.ZIndex = 2
- verticalDragger.AutoButtonColor = false
- verticalDragger.Name = "VerticalDragger"
- verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255)
- verticalDragger.BorderColor3 = Color3.new(0,0,0)
- verticalDragger.Size = UDim2.new(1,20,0,20)
- verticalDragger.Position = UDim2.new(0,0,1,0)
- verticalDragger.Active = true
- verticalDragger.Text = ""
-
- local scrubFrame = Instance.new("Frame",verticalDragger)
- scrubFrame.Name = "ScrubFrame"
- scrubFrame.BackgroundColor3 = Color3.new(1,1,1)
- scrubFrame.BorderSizePixel = 0
- scrubFrame.Position = UDim2.new(0.5,-5,0.5,0)
- scrubFrame.Size = UDim2.new(0,10,0,1)
- scrubFrame.ZIndex = 5
- local scrubTwo = scrubFrame:clone()
- scrubTwo.Position = UDim2.new(0.5,-5,0.5,-2)
- scrubTwo.Parent = verticalDragger
- local scrubThree = scrubFrame:clone()
- scrubThree.Position = UDim2.new(0.5,-5,0.5,2)
- scrubThree.Parent = verticalDragger
-
- local areaSoak = Instance.new("TextButton",getScreenGuiAncestor(parent))
- areaSoak.Name = "AreaSoak"
- areaSoak.Size = UDim2.new(1,0,1,0)
- areaSoak.BackgroundTransparency = 1
- areaSoak.BorderSizePixel = 0
- areaSoak.Text = ""
- areaSoak.ZIndex = 10
- areaSoak.Visible = false
- areaSoak.Active = true
-
- local draggingVertical = false
- local startYPos = nil
- verticalDragger.MouseEnter:connect(function ()
- verticalDragger.BackgroundColor3 = Color3.new(60/255,60/255,60/255)
- end)
- verticalDragger.MouseLeave:connect(function ()
- verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255)
- end)
- verticalDragger.MouseButton1Down:connect(function(x,y)
- draggingVertical = true
- areaSoak.Visible = true
- startYPos = y
- end)
- areaSoak.MouseButton1Up:connect(function ( )
- draggingVertical = false
- areaSoak.Visible = false
- end)
- areaSoak.MouseMoved:connect(function(x,y)
- if not draggingVertical then return end
-
- local yDelta = y - startYPos
- if not control.ScrollDownButton.Visible and yDelta > 0 then
- return
- end
-
- if (widgetContainer.Size.Y.Offset + yDelta) < 150 then
- widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,150)
- control.Size = UDim2.new (0,21,0,150)
- return
- end
-
- startYPos = y
-
- if widgetContainer.Size.Y.Offset + yDelta >= 0 then
- widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,widgetContainer.Size.Y.Offset + yDelta)
- control.Size = UDim2.new(0,21,0,control.Size.Y.Offset + yDelta )
- end
- end)
- end
-
- local function switchMinimize()
- minimizeFrame.Visible = not minimizeFrame.Visible
- if scrollable then
- frame.Visible = not frame.Visible
- verticalDragger.Visible = not verticalDragger.Visible
- control.Visible = not control.Visible
- else
- widgetContainer.Visible = not widgetContainer.Visible
- end
-
- if minimizeFrame.Visible then
- minimizeButton.Text = "+"
- else
- minimizeButton.Text = "-"
- end
- end
-
- minimizeBigButton.MouseButton1Click:connect(function ( )
- switchMinimize()
- end)
-
- minimizeButton.MouseButton1Click:connect(function( )
- switchMinimize()
- end)
-
- if scrollable then
- return dragBar, frame, helpFrame, closeEvent
- else
- return dragBar, widgetContainer, helpFrame, closeEvent
- end
-end
-
-t.Help =
- function(funcNameOrFunc)
- --input argument can be a string or a function. Should return a description (of arguments and expected side effects)
- if funcNameOrFunc == "CreatePropertyDropDownMenu" or funcNameOrFunc == t.CreatePropertyDropDownMenu then
- return "Function CreatePropertyDropDownMenu. " ..
- "Arguments: (instance, propertyName, enumType). " ..
- "Side effect: returns a container with a drop-down-box that is linked to the 'property' field of 'instance' which is of type 'enumType'"
- end
- if funcNameOrFunc == "CreateDropDownMenu" or funcNameOrFunc == t.CreateDropDownMenu then
- return "Function CreateDropDownMenu. " ..
- "Arguments: (items, onItemSelected). " ..
- "Side effect: Returns 2 results, a container to the gui object and a 'updateSelection' function for external updating. The container is a drop-down-box created around a list of items"
- end
- if funcNameOrFunc == "CreateMessageDialog" or funcNameOrFunc == t.CreateMessageDialog then
- return "Function CreateMessageDialog. " ..
- "Arguments: (title, message, buttons). " ..
- "Side effect: Returns a gui object of a message box with 'title' and 'message' as passed in. 'buttons' input is an array of Tables contains a 'Text' and 'Function' field for the text/callback of each button"
- end
- if funcNameOrFunc == "CreateStyledMessageDialog" or funcNameOrFunc == t.CreateStyledMessageDialog then
- return "Function CreateStyledMessageDialog. " ..
- "Arguments: (title, message, style, buttons). " ..
- "Side effect: Returns a gui object of a message box with 'title' and 'message' as passed in. 'buttons' input is an array of Tables contains a 'Text' and 'Function' field for the text/callback of each button, 'style' is a string, either Error, Notify or Confirm"
- end
- if funcNameOrFunc == "GetFontHeight" or funcNameOrFunc == t.GetFontHeight then
- return "Function GetFontHeight. " ..
- "Arguments: (font, fontSize). " ..
- "Side effect: returns the size in pixels of the given font + fontSize"
- end
- if funcNameOrFunc == "LayoutGuiObjects" or funcNameOrFunc == t.LayoutGuiObjects then
-
- end
- if funcNameOrFunc == "CreateScrollingFrame" or funcNameOrFunc == t.CreateScrollingFrame then
- return "Function CreateScrollingFrame. " ..
- "Arguments: (orderList, style) " ..
- "Side effect: returns 4 objects, (scrollFrame, scrollUpButton, scrollDownButton, recalculateFunction). 'scrollFrame' can be filled with GuiObjects. It will lay them out and allow scrollUpButton/scrollDownButton to interact with them. Orderlist is optional (and specifies the order to layout the children. Without orderlist, it uses the children order. style is also optional, and allows for a 'grid' styling if style is passed 'grid' as a string. recalculateFunction can be called when a relayout is needed (when orderList changes)"
- end
- if funcNameOrFunc == "CreateTrueScrollingFrame" or funcNameOrFunc == t.CreateTrueScrollingFrame then
- return "Function CreateTrueScrollingFrame. " ..
- "Arguments: (nil) " ..
- "Side effect: returns 2 objects, (scrollFrame, controlFrame). 'scrollFrame' can be filled with GuiObjects, and they will be clipped if not inside the frame's bounds. controlFrame has children scrollup and scrolldown, as well as a slider. controlFrame can be parented to any guiobject and it will readjust itself to fit."
- end
- if funcNameOrFunc == "AutoTruncateTextObject" or funcNameOrFunc == t.AutoTruncateTextObject then
- return "Function AutoTruncateTextObject. " ..
- "Arguments: (textLabel) " ..
- "Side effect: returns 2 objects, (textLabel, changeText). The 'textLabel' input is modified to automatically truncate text (with ellipsis), if it gets too small to fit. 'changeText' is a function that can be used to change the text, it takes 1 string as an argument"
- end
- if funcNameOrFunc == "CreateSlider" or funcNameOrFunc == t.CreateSlider then
- return "Function CreateSlider. " ..
- "Arguments: (steps, width, position) " ..
- "Side effect: returns 2 objects, (sliderGui, sliderPosition). The 'steps' argument specifies how many different positions the slider can hold along the bar. 'width' specifies in pixels how wide the bar should be (modifiable afterwards if desired). 'position' argument should be a UDim2 for slider positioning. 'sliderPosition' is an IntValue whose current .Value specifies the specific step the slider is currently on."
- end
- if funcNameOrFunc == "CreateSliderNew" or funcNameOrFunc == t.CreateSliderNew then
- return "Function CreateSliderNew. " ..
- "Arguments: (steps, width, position) " ..
- "Side effect: returns 2 objects, (sliderGui, sliderPosition). The 'steps' argument specifies how many different positions the slider can hold along the bar. 'width' specifies in pixels how wide the bar should be (modifiable afterwards if desired). 'position' argument should be a UDim2 for slider positioning. 'sliderPosition' is an IntValue whose current .Value specifies the specific step the slider is currently on."
- end
- if funcNameOrFunc == "CreateLoadingFrame" or funcNameOrFunc == t.CreateLoadingFrame then
- return "Function CreateLoadingFrame. " ..
- "Arguments: (name, size, position) " ..
- "Side effect: Creates a gui that can be manipulated to show progress for a particular action. Name appears above the loading bar, and size and position are udim2 values (both size and position are optional arguments). Returns 3 arguments, the first being the gui created. The second being updateLoadingGuiPercent, which is a bindable function. This function takes one argument (two optionally), which should be a number between 0 and 1, representing the percentage the loading gui should be at. The second argument to this function is a boolean value that if set to true will tween the current percentage value to the new percentage value, therefore our third argument is how long this tween should take. Our third returned argument is a BindableEvent, that when fired means that someone clicked the cancel button on the dialog."
- end
- if funcNameOrFunc == "CreateTerrainMaterialSelector" or funcNameOrFunc == t.CreateTerrainMaterialSelector then
- return "Function CreateTerrainMaterialSelector. " ..
- "Arguments: (size, position) " ..
- "Side effect: Size and position are UDim2 values that specifies the selector's size and position. Both size and position are optional arguments. This method returns 3 objects (terrainSelectorGui, terrainSelected, forceTerrainSelection). terrainSelectorGui is just the gui object that we generate with this function, parent it as you like. TerrainSelected is a BindableEvent that is fired whenever a new terrain type is selected in the gui. ForceTerrainSelection is a function that takes an argument of Enum.CellMaterial and will force the gui to show that material as currently selected."
- end
- end
-
-
-
-local RbxGui
-
-local localTesting = true
-
-local screen = script.Parent
-local screenResizeCon = nil
-
-local friendWord = "Friend"
-local friendWordLowercase = "friend"
-
-local elementNames = {}
-local elementNameToElement = {}
-
-local privilegeOwner = 255
-local privilegeAdmin = 240
-local privilegeMember = 128
-local privilegeVisitor = 10
-local privilegeBanned = 0
-
-local inContextMenu = false
-local contextMenu3d = false
-
-local bigEasingStyle = Enum.EasingStyle.Back
-local smallEasingStyle = Enum.EasingStyle.Quart
-
-local personalServerContextAdded = false
-local personalServerPlace = false
-local success = pcall(function() personalServerPlace = game.IsPersonalServer end)
-if not success then
- personalServerPlace = false
-end
-
-local friendRequestBlacklist = {}
-local otherPlayerBlacklist = {}
-
-local currentSortName = ""
-
-local function waitForChild(instance, name)
- while not instance:FindFirstChild(name) do
- instance.ChildAdded:wait()
- end
-end
-
-local function waitForProperty(instance, prop)
- while not instance[prop] do
- instance.Changed:wait()
- end
-end
-
-local function Color3I(r,g,b)
- return Color3.new(r/255,g/255,b/255)
-end
-
-function robloxLock(instance)
-end
-
-function ArrayRemove(t, obj)
- for i, obj2 in ipairs(t) do
- if obj == obj2 then
- table.remove(t, i)
- return true
- end
- end
- return false
-end
-
-local function getPlayers()
- local result = {}
- local players = game:GetService("Players"):GetChildren()
- if players then
- for i, player in ipairs(players) do
- if player:IsA("Player") then
- table.insert(result, player)
- end
- end
- end
- return result
-end
-
-local brickColorTable = {}
-for i = 0, 63 do
- brickColorTable[BrickColor.palette(i).Name] = BrickColor.palette(i).Color
-end
-
-local function remapColor(i, j)
- brickColorTable[BrickColor.palette(i).Name] = BrickColor.palette(j).Color
-end
-
-remapColor(13, 12)
-remapColor(14, 12)
-remapColor(15, 12)
-remapColor(61, 29)
-remapColor(63, 62)
-remapColor(56, 50)
-remapColor(45, 53)
-remapColor(51, 20)
-remapColor(4, 20)
-remapColor(59, 35)
-remapColor(60, 29)
-
-local function getColor(brickColor)
- if brickColorTable[brickColor.Name] then
- return brickColorTable[brickColor.Name]
- else
- return brickColor.Color;
- end
-end
-
-
-
-local function getTeams()
- local result = {}
- local teams = game:GetService("Teams"):GetChildren()
- for i, team in ipairs(teams) do
- if team:IsA("Team") then
- table.insert(result, team)
- end
- end
- return result
-end
-
-local supportFriends = false
-local currentBoardType = "PlayerList"
-local currentStatCount = 0
-
-local createBoardsFunction = nil
-
-
-local playerTable = {}
-local teamTable = {}
-local teamColorTable = {}
-
-local removePlayerFunction = nil
-local recreatePlayerFunction = nil
-local addPlayerFunction = function(player)
- if recreatePlayerFunction then
- recreatePlayerFunction(player)
- end
-end
-local sortPlayerListsFunction = nil
-
-local minimizedState = nil
-local bigWindowImposter = nil
-local smallWindowPosition = UDim2.new(0, -20, 0,5)
-local smallWindowSize = UDim2.new(1,0,1,0)
-local bigWindowSize = UDim2.new(0.6,0,0.6,0)
-local bigWindowPosition = UDim2.new(.2, 0, .2,0)
-
-local smallWindowHeaderYSize = 32
-
-local debounceTeamsChanged = false
-
-local currentWindowState = "Small"
-local previousWindowState = nil
-local transitionWindowsFunction = nil
-
-local container = nil
-local topRightTrayContainer = nil
-
-local playerContextMenu = nil
-local contextMenuElements = {}
-local updateContextMenuItems = nil
-
-local function addContextMenuLabel(getText1, getText2, isVisible)
- local t = {}
- t.Type = "Label"
- t.GetText1 = getText1
- t.GetText2 = getText2
- t.IsVisible = isVisible
- table.insert(contextMenuElements, t)
-end
-local function addContextMenuButton(text, isVisible, isActive, doIt)
- local t = {}
- t.Text = text
- t.Type = "Button"
- t.IsVisible = isVisible
- t.IsActive = isActive
- t.DoIt = doIt
- table.insert(contextMenuElements, t)
-end
-
-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
-
-
-local function getPrivilegeType(player)
- local rank = player.PersonalServerRank
- if rank >= privilegeOwner then
- return privilegeOwner
- elseif rank < privilegeOwner and rank >= privilegeAdmin then
- return privilegeAdmin
- elseif rank < privilegeAdmin and rank >= privilegeMember then
- return privilegeMember
- elseif rank < privilegeMember and rank >= privilegeVisitor then
- return privilegeVisitor
- else
- return privilegeBanned
- end
-end
-
---Populate the ContextMenus
-addContextMenuLabel(
- --GetText1
- function(player)
- return "Loading..."
- end,
- --GetText2
- nil,
- --IsVisible
- function(player)
- return getFriendStatus(player) == Enum.FriendStatus.Unknown
- end)
-
-addContextMenuButton("Send " .. friendWord .. " Request",
- --IsVisible
- function(player)
- return (not otherPlayerBlacklist[player]) and (getFriendStatus(player) == Enum.FriendStatus.NotFriend)
- end,
- --IsActive
- function(player)
- return true
- end,
- --DoIt?
- function(player)
- otherPlayerBlacklist[player] = true
- return game.Players.LocalPlayer:RequestFriendship(player)
- end
-)
-addContextMenuButton("Un" .. friendWordLowercase,
- --IsVisible
- function(player)
- return getFriendStatus(player) == Enum.FriendStatus.Friend
- end,
- --IsActive
- function(player)
- return true
- end,
- --DoIt
- function(player)
- return game.Players.LocalPlayer:RevokeFriendship(player)
- end
-)
-addContextMenuButton("Accept " .. friendWord .. " Request",
- --IsVisible
- function(player)
- return (not friendRequestBlacklist[player]) and (getFriendStatus(player) == Enum.FriendStatus.FriendRequestReceived)
- end,
- --IsActive
- function(player)
- return true
- end,
- --DoIt
- function(player)
- return game.Players.LocalPlayer:RequestFriendship(player)
- end
-)
-
-addContextMenuButton("Deny " .. friendWord .. " Request",
- --IsVisible
- function(player)
- return getFriendStatus(player) == Enum.FriendStatus.FriendRequestReceived
- end,
- --IsActive
- function(player)
- return true
- end,
- --DoIt
- function(player)
- friendRequestBlacklist[player] = true
- return game.Players.LocalPlayer:RevokeFriendship(player)
- end
-)
-
-addContextMenuButton("Cancel " .. friendWord .. " Request",
- --IsVisible
- function(player)
- return false -- disable cancel request for now (can lead to griefing)
- --return getFriendStatus(player) == Enum.FriendStatus.FriendRequestSent
- end,
- --IsActive
- function(player)
- return true
- end,
- --DoIt
- function(player)
- otherPlayerBlacklist[player] = false
- return game.Players.LocalPlayer:RevokeFriendship(player)
- end
-)
-
-function addPersonalServerContext()
- if personalServerContextAdded then return end
- personalServerContextAdded = true
- addContextMenuButton("Ban",
- --IsVisible
- function(player)
- return ( getPrivilegeType(game.Players.LocalPlayer) >= privilegeAdmin and (getPrivilegeType(player) < privilegeAdmin) )
- end,
- --IsActive
- function(player)
- return true
- end,
- --DoIt
- function(player)
- player.PersonalServerRank = privilegeBanned
- return true
- end
- )
- addContextMenuButton("Promote to Visitor",
- --IsVisible
- function(player)
- return ( getPrivilegeType(game.Players.LocalPlayer) >= privilegeAdmin ) and ( getPrivilegeType(player) == privilegeBanned )
- end,
- --IsActive
- function(player)
- return true
- end,
- --DoIt
- function(player)
- game:GetService("PersonalServerService"):Promote(player)
- return true
- end
- )
- addContextMenuButton("Promote to Member",
- --IsVisible
- function(player)
- return ( getPrivilegeType(game.Players.LocalPlayer) >= privilegeAdmin ) and ( getPrivilegeType(player) == privilegeVisitor )
- end,
- --IsActive
- function(player)
- return true
- end,
- --DoIt
- function(player)
- game:GetService("PersonalServerService"):Promote(player)
- return true
- end
- )
- addContextMenuButton("Promote to Admin",
- --IsVisible
- function(player)
- return ( getPrivilegeType(game.Players.LocalPlayer) == privilegeOwner ) and ( getPrivilegeType(player) == privilegeMember )
- end,
- --IsActive
- function(player)
- return true
- end,
- --DoIt
- function(player)
- game:GetService("PersonalServerService"):Promote(player)
- return true
- end
- )
- addContextMenuButton("Demote to Member",
- --IsVisible
- function(player)
- return ( getPrivilegeType(game.Players.LocalPlayer) == privilegeOwner ) and ( getPrivilegeType(player) == privilegeAdmin )
- end,
- --IsActive
- function(player)
- return true
- end,
- --DoIt
- function(player)
- game:GetService("PersonalServerService"):Demote(player)
- return true
- end
- )
- addContextMenuButton("Demote to Visitor",
- --IsVisible
- function(player)
- return ( getPrivilegeType(game.Players.LocalPlayer) >= privilegeAdmin ) and ( getPrivilegeType(player) == privilegeMember )
- end,
- --IsActive
- function(player)
- return true
- end,
- --DoIt
- function(player)
- game:GetService("PersonalServerService"):Demote(player)
- return true
- end
- )
-end
-
-local function setupBuildToolManagement()
- local buildToolManagerAssetId = 64164692
- game:GetService("ScriptContext"):AddCoreScript(buildToolManagerAssetId,game.Players.LocalPlayer,"BuildToolManager")
-end
-
-
-local function getStatColumns(players)
- for i, player in ipairs(players) do
- local leaderstats = player:FindFirstChild("leaderstats")
- if leaderstats then
- local stats = {}
- local children = leaderstats:GetChildren()
- if children then
- for i, stat in ipairs(children) do
- if stat:IsA("IntValue") then
- table.insert(stats, stat)
- else
- --TODO: This should check for IntValue only but current ScoreHud does not
- table.insert(stats, stat)
- end
- end
- end
- return stats
- end
- end
- return nil
-end
-
-local function determineBoardType()
- local players = getPlayers()
-
- local foundLeaderstats = false
- local numStats = 0
- local foundTeam = false
-
- local stats = getStatColumns(players)
- if stats then
- foundLeaderstats = true
- numStats = #stats
- end
-
- for i, player in ipairs(players) do
- if not foundTeam then
- if not player.Neutral then
- foundTeam = true
- break
- end
- end
- end
-
- if foundLeaderstats and foundTeam then
- return "TeamScore", numStats
- elseif foundLeaderstats then
- return "PlayerScore", numStats
- elseif foundTeam then
- return "TeamList", numStats
- else
- return "PlayerList", numStats
- end
-end
-
-local function toggleBigWindow()
- if container == nil then
- return
- end
-
- if currentWindowState == "Big" then
- --Hide it
- if previousWindowState == nil or previousWindowState == "Big" or previousWindowState == "None" then
- transitionWindowsFunction("None")
- else
- transitionWindowsFunction("Small")
- end
- else
- previousWindowState = currentWindowState
- transitionWindowsFunction("Big")
- end
-end
-local previousBigPlayerList = nil
-local function rebuildBoard(owner, boardType, numStats)
- if topRightTrayContainer == nil then
- topRightTrayContainer = owner:FindFirstChild("PlayerListTopRightFrame")
- if topRightTrayContainer == nil then
- topRightTrayContainer = Instance.new("Frame")
- topRightTrayContainer.Name = "PlayerListTopRightFrame"
- topRightTrayContainer.BackgroundTransparency = 1
- topRightTrayContainer.Size = UDim2.new(0.2, 16, 0.42, 16)
- topRightTrayContainer.Position = UDim2.new(0.8, 0, 0, 0)
- topRightTrayContainer.Parent = container
- end
- end
- if minimizedState == nil then
- minimizedState = Instance.new("Frame")
- minimizedState.Name = "MinimizedPlayerlist"
- minimizedState.BackgroundTransparency = 1
- minimizedState.Position = UDim2.new(1, -166, 0,0)
- minimizedState.Size = UDim2.new(0, 151, 0, 30)
-
- playerListButton = Instance.new("ImageButton")
- playerListButton.Name = "GoSmallButton"
- playerListButton.Image = "rbxasset://textures/ui/playerlist_hidden_small.png"
- playerListButton.BackgroundTransparency = 1
- playerListButton.Size = UDim2.new(0.0, 35, 0, 30)
- playerListButton.Position = UDim2.new(1, -35, 0, 0)
- playerListButton.MouseButton1Click:connect(
- function()
- transitionWindowsFunction("Small")
- end)
- playerListButton.Parent = minimizedState
-
- minimizedState.Visible = false
- robloxLock(minimizedState)
- minimizedState.Parent = topRightTrayContainer
- end
- if bigWindowImposter == nil then
- bigWindowImposter = owner:FindFirstChild("BigPlayerListWindowImposter")
- if bigWindowImposter == nil then
- bigWindowImposter = Instance.new("Frame")
- bigWindowImposter.Name = "BigPlayerListWindowImposter"
- bigWindowImposter.Visible = false
- bigWindowImposter.BackgroundColor3 = Color3.new(0,0,0)
- bigWindowImposter.BackgroundTransparency = 0.7
- bigWindowImposter.BorderSizePixel = 0
- bigWindowImposter.Size = UDim2.new(0.4, 7, 0.4, 7)
- bigWindowImposter.Position = UDim2.new(0.3, 0, 0.3, 0)
- robloxLock(bigWindowImposter)
- bigWindowImposter.Parent = container
- end
- end
- if container == nil or container ~= owner then
- container = owner
-
- topRightTrayContainer.Parent = container
- bigWindowImposter.Parent = container
- end
-
- local smallVisible = true
- local bigVisible = false
- if container then
- if topRightTrayContainer then
- --Delete the old boards
- if topRightTrayContainer:FindFirstChild("SmallPlayerlist") then
- smallVisible = topRightTrayContainer.SmallPlayerlist.Visible
- topRightTrayContainer.SmallPlayerlist.Parent = nil
- end
- end
- if container:FindFirstChild("BigPlayerlist") then
- bigVisible = container.BigPlayerlist.Visible or (previousBigPlayerList ~= nil)
- container.BigPlayerlist.Parent = nil
- if previousBigPlayerList ~= nil then
- pcall(function() game.GuiService:RemoveCenterDialog(previousBigPlayerList) end)
- previousBigPlayerList = nil
- end
- end
- end
-
- local smallBoard, bigBoard = createBoardsFunction(boardType, numStats)
- if smallBoard then
- smallBoard.Visible = smallVisible
- smallBoard.Parent = topRightTrayContainer
- recalculateSmallPlayerListSize(smallBoard)
- end
- if bigBoard then
- if bigVisible then
- previousBigPlayerList = bigBoard
- local centerDialogSupported, msg = pcall(function() game.GuiService:AddCenterDialog(previousBigPlayerList, Enum.CenterDialogType.PlayerInitiatedDialog,
- function()
- previousBigPlayerList.Visible = true
- end,
- function()
- previousBigPlayerList.Visible = false
- end)
- end)
- bigBoard.Visible = bigVisible
- else
- bigBoard.Visible = false
- end
- bigBoard.Parent = container
- end
- return container
-end
-
-function recalculateSmallPlayerListSize(smallPlayerList)
- waitForChild(smallPlayerList,"ScrollingArea")
- waitForChild(smallPlayerList.ScrollingArea, "ScrollingFrame")
- local scrollingFrame = smallPlayerList.ScrollingArea.ScrollingFrame
- local playerLines = scrollingFrame:GetChildren()
-
- local totalPlayerListSize = 0
- for i = 1, #playerLines do
- totalPlayerListSize = totalPlayerListSize + playerLines[i].AbsoluteSize.Y
- end
-
- if not smallPlayerList.Parent then return end
-
- local yOffset = math.max(0,(smallPlayerList.Size.Y.Scale * smallPlayerList.Parent.AbsoluteSize.Y) - totalPlayerListSize - smallWindowHeaderYSize)
- smallPlayerList.Size = UDim2.new(smallPlayerList.Size.X.Scale,smallPlayerList.Size.X.Offset,smallPlayerList.Size.Y.Scale,-yOffset)
-end
-
-
-local function showBigPlayerWindow()
- if container:FindFirstChild("BigPlayerlist") then
- if container.BigPlayerlist.Visible then
- return
- end
- end
-
- bigWindowImposter.Visible = true
- bigWindowImposter:TweenSizeAndPosition(bigWindowSize, bigWindowPosition, Enum.EasingDirection.Out, bigEasingStyle, 0.3, true,
- function(state)
- if state == Enum.TweenStatus.Completed then
- bigWindowImposter.Visible = false
- if container:FindFirstChild("BigPlayerlist") then
- container.BigPlayerlist.Visible = true
- end
- end
- end)
-end
-
-local function hideBigPlayerWindow(completed)
- if playerContextMenu then
- playerContextMenu.Visible = false
- end
-
- if container:FindFirstChild("BigPlayerlist") then
- if container.BigPlayerlist.Visible == false and bigWindowImposter.Visible == false then
- if completed then
- completed()
- end
- --Already completely hidden
- return
- end
- container.BigPlayerlist.Visible = false
- end
-
- local completedFunction = completed
- bigWindowImposter.Visible = true
- bigWindowImposter:TweenSizeAndPosition(UDim2.new(0.4, 0, 0.4, 0), UDim2.new(0.3, 0, 0.3, 0), Enum.EasingDirection.In, Enum.EasingStyle.Quart, 0.15, true,
- function(state)
- if state == Enum.TweenStatus.Completed then
- bigWindowImposter.Visible = false
- if completedFunction then
- completedFunction()
- end
- end
- end)
-end
-local function hideSmallPlayerWindow(completed)
- if playerContextMenu then
- playerContextMenu.Visible = false
- end
- if topRightTrayContainer:FindFirstChild("SmallPlayerlist") then
- local completedFunction = completed
- if topRightTrayContainer.SmallPlayerlist.Visible then
- topRightTrayContainer.SmallPlayerlist:TweenPosition(UDim2.new(1,0,smallWindowPosition.Y.Scale, smallWindowPosition.Y.Offset), Enum.EasingDirection.Out, smallEasingStyle, 0.3, true,
- function(state)
- if state == Enum.TweenStatus.Completed then
- if topRightTrayContainer:FindFirstChild("SmallPlayerlist") then
- topRightTrayContainer.SmallPlayerlist.Visible = false
- end
- if completedFunction then
- completedFunction()
- end
- end
- end)
- return
- end
- end
- if completed then
- completed()
- end
-end
-
-
-transitionWindowsFunction = function(desiredState)
- if desiredState == "Big" then
- minimizedState.Visible = false
- hideSmallPlayerWindow()
-
- if previousBigPlayerList ~= nil then
- if previousBigPlayerList ~= container:FindFirstChild("BigPlayerlist") then
- pcall(function() game.GuiService:RemoveCenterDialog(previousBigPlayerList) end)
- previousBigPlayerList = nil
- previousBigPlayerList = container:FindFirstChild("BigPlayerlist")
- end
- else
- previousBigPlayerList = container:FindFirstChild("BigPlayerlist")
- end
-
- if previousBigPlayerList then
- local firstShow = false
- local centerDialogSupported, msg = pcall(function() game.GuiService:AddCenterDialog(previousBigPlayerList, Enum.CenterDialogType.PlayerInitiatedDialog,
- function()
- if not firstShow then
- showBigPlayerWindow()
- firstShow = true
- else
- previousBigPlayerList.Visible = true
- end
- end,
- function()
- if previousBigPlayerList then
- previousBigPlayerList.Visible = false
- end
- end)
- end)
- if centerDialogSupported == false then
- print("Exception", msg)
- showBigPlayerWindow()
- end
- else
- showBigPlayerWindow()
- end
- currentWindowState = "Big"
- elseif desiredState == "Small" then
- minimizedState.Visible = false
- if previousBigPlayerList ~= nil then
- pcall(function() game.GuiService:RemoveCenterDialog(previousBigPlayerList) end)
- previousBigPlayerList = nil
- end
-
- hideBigPlayerWindow()
- if topRightTrayContainer:FindFirstChild("SmallPlayerlist") then
- if not topRightTrayContainer.SmallPlayerlist.Visible or topRightTrayContainer.SmallPlayerlist.Position ~= smallWindowPosition then
- topRightTrayContainer.SmallPlayerlist.Visible = true
- topRightTrayContainer.SmallPlayerlist:TweenPosition(smallWindowPosition, Enum.EasingDirection.Out, smallEasingStyle, 0.3, true)
- end
- end
- currentWindowState = "Small"
- elseif desiredState == "None" then
- if previousBigPlayerList ~= nil then
- pcall(function() game.GuiService:RemoveCenterDialog(previousBigPlayerList) end)
- previousBigPlayerList = nil
- end
-
- local smallDone = false
- local bigDone = false
- hideSmallPlayerWindow(
- function()
- smallDone = true
- if bigDone and smallDone then
- minimizedState.Visible = true
- end
- end)
- hideBigPlayerWindow(
- function()
- bigDone = true
- if bigDone and smallDone then
- minimizedState.Visible = true
- end
- end)
- currentWindowState = "None"
- end
-end
-
-local function getStatValuesForPlayer(player)
- local leaderstats = player:FindFirstChild("leaderstats")
- if leaderstats then
- local children = leaderstats:GetChildren()
- if children then
- local result = {}
- --Just go based on position
- for i, stat in ipairs(children) do
- if stat:IsA("IntValue") then
- table.insert(result, stat)
- else
- table.insert(result, 0)
- end
- end
-
- return result, leaderstats
- end
- end
- return nil
-end
-
---ChildAdded on Player (if it's name is "leaderstats")
-
-if UserSettings and LoadLibrary then
-
- RbxGui,msg = t
-
- local function createTeamName(name, color)
- local fontHeight = 20
- local frame = Instance.new("Frame")
- frame.Name = "Team-" .. name
- frame.BorderSizePixel = 0
- frame.BackgroundTransparency = 0.5
- frame.BackgroundColor3 = Color3.new(1,1,1)
- frame.Size = UDim2.new(1, 0, 0, fontHeight)
- frame.Position = UDim2.new(0,0,0,0)
-
- local label = Instance.new("TextLabel")
- label.Name = "NameLabel"
- label.Text = " " .. name
- label.Font = Enum.Font.ArialBold
- label.FontSize = Enum.FontSize.Size18
- label.Position = UDim2.new(0,0,0,0)
- label.Size = UDim2.new(1,0,1,0)
- label.TextColor3 = Color3.new(1,1,1)
- label.BackgroundTransparency = 0.5
- label.BackgroundColor3 = getColor(color)
- label.BorderSizePixel = 0
- label.TextXAlignment = Enum.TextXAlignment.Left
-
- local changeFunc = nil
- label, changeFunc = RbxGui.AutoTruncateTextObject(label)
- label.Parent = frame
-
- return frame, changeFunc
- end
-
- local function getFriendStatusIcon(friendStatus)
- if friendStatus == Enum.FriendStatus.Unknown or friendStatus == Enum.FriendStatus.NotFriend then
- return nil
- elseif friendStatus == Enum.FriendStatus.Friend then
- return "rbxasset://textures/ui/PlayerlistFriendIcon.png"
- elseif friendStatus == Enum.FriendStatus.FriendRequestSent then
- return "rbxasset://textures/ui/PlayerlistFriendRequestSentIcon.png"
- elseif friendStatus == Enum.FriendStatus.FriendRequestReceived then
- return "rbxasset://textures/ui/PlayerlistFriendRequestReceivedIcon.png"
- else
- error("Unknown FriendStatus: " .. friendStatus)
- end
- end
-
- local function getMembershipTypeIcon(membershipType)
- if 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("Uknown membershipType" .. membershipType)
- end
- end
-
-
- local function updatePlayerFriendStatus(nameObject, friendStatus)
- local fontHeight = 20
-
- local friendIconImage = getFriendStatusIcon(friendStatus)
- nameObject.MembershipTypeLabel.FriendStatusLabel.Visible = (friendIconImage ~= nil)
-
- if friendIconImage ~= nil then
- --Show friend icon
- nameObject.MembershipTypeLabel.FriendStatusLabel.Image = friendIconImage
- nameObject.NameLabel.Position =UDim2.new(0,2*fontHeight,0,1)
- nameObject.NameLabel.Size = UDim2.new(1,-2*fontHeight,1,-2)
- else
- --Hide the friend icon
- nameObject.NameLabel.Position = UDim2.new(0,fontHeight+1,0,1)
- nameObject.NameLabel.Size = UDim2.new(1,-(fontHeight+1),1,-2)
- end
- end
- local function updatePlayerName(nameObject, membershipStatus, teamColor)
- local fontHeight = 20
-
- nameObject.Size = UDim2.new(1,0,0,fontHeight)
- nameObject.MembershipTypeLabel.Image = getMembershipTypeIcon(membershipStatus)
- end
-
-
- local function updatePlayerNameColor(player, teamColor)
- local function updatePlayerNameColorHelper(nameObject)
- if teamColor ~= nil then
- nameObject.NameLabel.TextColor3 = getColor(teamColor)
- nameObject.NameLabel.FullNameLabel.TextColor3 = getColor(teamColor)
- else
- nameObject.NameLabel.TextColor3 = Color3.new(1,1,1)
- nameObject.NameLabel.FullNameLabel.TextColor3 = Color3.new(1,1,1)
- end
- end
-
- updatePlayerNameColorHelper(playerTable[player].NameObjectSmall)
- updatePlayerNameColorHelper(playerTable[player].NameObjectBig)
- end
-
-
- local function createPlayerName(name, membershipStatus, teamColor, friendStatus)
- local frame = Instance.new("Frame")
- frame.Name = "Player_" .. name
- frame.BackgroundColor3 = Color3.new(1,1,1)
- frame.BackgroundTransparency = 0.5
- frame.BorderSizePixel = 0
-
- local membershipStatusLabel = Instance.new("ImageLabel")
- membershipStatusLabel.Name = "MembershipTypeLabel"
- membershipStatusLabel.BackgroundTransparency = 1
- membershipStatusLabel.Size = UDim2.new(1,0,1,0)
- membershipStatusLabel.Position = UDim2.new(0,0,0,0)
- membershipStatusLabel.SizeConstraint = Enum.SizeConstraint.RelativeYY
- membershipStatusLabel.Parent = frame
-
- local friendStatusLabel = Instance.new("ImageLabel")
- friendStatusLabel.Name = "FriendStatusLabel"
- friendStatusLabel.Visible = false
- friendStatusLabel.BackgroundTransparency = 1
- friendStatusLabel.Size = UDim2.new(1,0,1,0)
- friendStatusLabel.Position = UDim2.new(1,0,0,0)
- friendStatusLabel.Parent = membershipStatusLabel
-
- local changeNameFunction
- local nameLabel = Instance.new("TextLabel")
- nameLabel.Name = "NameLabel"
- nameLabel.Text = name
- nameLabel.Font = Enum.Font.ArialBold
- nameLabel.FontSize = Enum.FontSize.Size14
- nameLabel.TextColor3 = Color3.new(1,1,1)
- nameLabel.BackgroundTransparency = 1
- nameLabel.BackgroundColor3 = Color3.new(0,0,0)
- nameLabel.TextXAlignment = Enum.TextXAlignment.Left
- nameLabel, changeNameFunction = RbxGui.AutoTruncateTextObject(nameLabel)
- nameLabel.Parent = frame
-
- updatePlayerName(frame, membershipStatus, teamColor)
- if supportFriends and not friendRequestBlacklist[game.Players:FindFirstChild(name)] then
- updatePlayerFriendStatus(frame, friendStatus)
- else
- updatePlayerFriendStatus(frame, Enum.FriendStatus.NotFriend)
- end
- return frame, changeNameFunction
- end
-
- local function createStatColumn(i, numColumns, isTeam, color3, isHeader, stat)
- local textLabel = Instance.new("TextButton")
- textLabel.Name = "Stat" .. i
- textLabel.AutoButtonColor = false
- textLabel.TextColor3 = Color3.new(1,1,1)
- textLabel.TextXAlignment = Enum.TextXAlignment.Right
- textLabel.TextYAlignment = Enum.TextYAlignment.Center
- textLabel.FontSize = Enum.FontSize.Size14
-
- if isHeader then
- textLabel.FontSize = Enum.FontSize.Size18
- else
- textLabel.FontSize = Enum.FontSize.Size14
- end
- if isHeader or isTeam then
- textLabel.Font = Enum.Font.ArialBold
- else
- textLabel.Font = Enum.Font.Arial
- end
-
- if isTeam then
- textLabel.BackgroundColor3 = color3
- textLabel.Text = 0
- else
- textLabel.BackgroundColor3 = Color3.new(0,0,0)
- textLabel.Text = ""
- end
- textLabel.BackgroundTransparency = 1
- if i == numColumns then
- textLabel.Size = UDim2.new(1/numColumns, -6, 1, 0)
- else
- textLabel.Size = UDim2.new(1/numColumns, -4, 1, 0)
- end
-
- textLabel.Position = UDim2.new((i-1) * (1/numColumns), 0, 0, 0)
-
- local truncLabel, changer = RbxGui.AutoTruncateTextObject(textLabel)
-
- if isHeader then
- local mouseCon = {}
-
- mouseCon[1] = truncLabel.MouseEnter:connect(function()
- truncLabel.BackgroundTransparency = 0.2
- end)
- mouseCon[2] = truncLabel.MouseLeave:connect(function()
- truncLabel.BackgroundTransparency = 1
- end)
-
- mouseCon[3] = truncLabel.MouseButton1Click:connect(function()
- sortPlayerListsFunction(truncLabel:GetChildren()[1].Name, (currentSortName == truncLabel:GetChildren()[1].Name) )
- truncLabel.BackgroundTransparency = 1
- end)
-
- mouseCon[4] = truncLabel:GetChildren()[1].MouseButton1Click:connect(function()
- sortPlayerListsFunction(textLabel.Name, (currentSortName == truncLabel.Name) )
- truncLabel.BackgroundTransparency = 1
- end)
-
- mouseCon[5] = nil
- mouseCon[5] = truncLabel.AncestryChanged:connect(function(child,parent)
- if parent == nil then
- for i,connection in pairs(mouseCon) do
- connection:disconnect()
- end
- end
- end)
- end
-
- return truncLabel, changer
- end
-
- local function createStatHeaders(stats, numColumns, isBig)
- local frame = Instance.new("Frame")
- frame.Name = "Headers"
- frame.BorderSizePixel = 0
- frame.BackgroundColor3 = Color3.new(0,0,0)
- frame.BackgroundTransparency = 1
-
- local nameSize
- if isBig then
- nameSize = 0.5
- elseif numColumns == 1 then
- nameSize = 0.7
- elseif numColumns == 2 then
- nameSize = 0.6
- else
- nameSize = 0.45
- end
- frame.Size = UDim2.new(1-nameSize, 0, 1,0)
- if isBig then
- frame.Position = UDim2.new(nameSize,-25, 0,0)
- else
- frame.Position = UDim2.new(nameSize,0, 0,0)
- end
-
- local i = 1
- while i <= numColumns do
- local headerColumn, changeText = createStatColumn(i, numColumns, false, nil, true,stats[i])
- changeText(stats[i].Name)
- headerColumn.Parent = frame
- i = i + 1
- end
- return frame, textChangers
- end
-
- local function createStatColumns(nameObject, numColumns, isTeam, isBig)
- local frame = Instance.new("Frame")
- frame.Name = nameObject.Name .. "_WithStats"
- frame.BorderSizePixel = 0
- frame.BackgroundColor3 = nameObject.BackgroundColor3
- frame.BackgroundTransparency = nameObject.BackgroundTransparency
- frame.Size = nameObject.Size
- frame.Position = nameObject.Position
-
- nameObject.BackgroundTransparency = 1
-
- if numColumns == 0 then
- nameObject.Size = UDim2.new(1,0,1,0)
- nameObject.Position = UDim2.new(0,0,0,0)
- nameObject.Parent = frame
- return frame
- end
-
- local statFrame = Instance.new("Frame")
- statFrame.Name = "Stats"
- if isTeam then
- statFrame.BorderSizePixel = 0
- statFrame.BackgroundColor3 = nameObject.NameLabel.BackgroundColor3
- statFrame.BackgroundTransparency = nameObject.NameLabel.BackgroundTransparency
- else
- statFrame.BackgroundTransparency = 1
- end
-
- local nameSize
- if isBig then
- nameSize = 0.5
- elseif numColumns == 1 then
- nameSize = 0.7
- elseif numColumns == 2 then
- nameSize = 0.6
- else
- nameSize = 0.45
- end
- nameObject.Size = UDim2.new(nameSize, 0, 1, 0)
- nameObject.Position = UDim2.new(0, 0, 0, 0)
- statFrame.Size = UDim2.new(1-nameSize,0, 1,0)
- statFrame.Position = UDim2.new(nameSize,0, 0,0)
-
- nameObject.Parent = frame
- statFrame.Parent = frame
-
- local textChangers = {}
- local i = 1
- while i <= numColumns do
- local statColumn, changeText = createStatColumn(i, numColumns, isTeam, statFrame.BackgroundColor3)
- statColumn.Parent = statFrame
- table.insert(textChangers, changeText)
-
- i = i + 1
- end
-
- return frame, statFrame, textChangers
- end
-
- local function createAlternatingRows(objects)
- for i, line in ipairs(objects) do
- if i % 2 == 0 then
- line.BackgroundTransparency = 1
- else
- line.BackgroundTransparency = 0.95
- end
- end
- end
- local removeFromTeam = nil
-
- local function clearTableEntry(obj, tableInfo)
- if tableInfo.MainObjectSmall then
- tableInfo.MainObjectSmall.Parent = nil
- tableInfo.MainObjectSmall = nil
- end
- if tableInfo.MainObjectBig then
- tableInfo.MainObjectBig.Parent = nil
- tableInfo.MainObjectBig = nil
- end
- if tableInfo.Connections then
- for i, connection in ipairs(tableInfo.Connections) do
- connection:disconnect()
- end
- tableInfo.Connections = nil
- end
- if tableInfo.LeaderStatConnections then
- for i, connection in ipairs(tableInfo.LeaderStatConnections) do
- connection:disconnect()
- end
- tableInfo.LeaderStatConnections = nil
- end
- if tableInfo.CurrentTeam then
- removeFromTeam(obj)
- tableInfo.CurrentTeam = nil
- end
- if tableInfo.Players then
- for i, player in ipairs(tableInfo.Players) do
- playerTable[player].CurrentTeam = nil
- end
- tableInfo.Players = {}
- end
- if tableInfo.StatValues then
- tableInfo.StatValues = nil
- end
- end
-
- local function resetPlayerTable()
- for player, info in pairs(playerTable) do
- clearTableEntry(player, info)
- playerTable[player] = nil
- end
- playerTable = {}
- end
-
- local function resetTeamTable()
- for team, info in pairs(teamTable) do
- clearTableEntry(team, info)
- teamTable[team] = nil
- end
- teamTable = {}
- teamColorTable = {}
- end
-
- local function getBoardTypeInfo()
- local isTeam = (currentBoardType == "TeamScore" or currentBoardType == "TeamList")
- local isScore = (currentBoardType == "TeamScore" or currentBoardType == "PlayerScore")
- return isTeam, isScore
- end
-
-
- local function recomputeTeamScore(team, column)
- if not team or team == "Neutral" then
- return
- end
-
- local function recomputeScoreHelper(statChangers)
- if statChangers and column <= #statChangers then
- local sum = 0
- for i, p in ipairs(teamTable[team].Players) do
- if playerTable[p].StatValues and column <= #playerTable[p].StatValues then
- sum = sum + playerTable[p].StatValues[column].Value
- end
- end
- statChangers[column](sum)
- end
- end
-
- recomputeScoreHelper(teamTable[team].StatChangersSmall)
- recomputeScoreHelper(teamTable[team].StatChangersBig)
- end
- local function recomputeCompleteTeamScore(team)
- local col = 1
- while col <= currentStatCount do
- recomputeTeamScore(team, col)
- col = col + 1
- end
- end
- removeFromTeam = function(player)
- if playerTable[player].CurrentTeam ~= nil and teamTable[playerTable[player].CurrentTeam] ~= nil then
- ArrayRemove(teamTable[playerTable[player].CurrentTeam].Players, player)
- recomputeCompleteTeamScore(playerTable[player].CurrentTeam)
- playerTable[player].CurrentTeam = nil
- end
- end
-
- local function assignToTeam(player)
- local isTeam, isScore = getBoardTypeInfo()
-
- if isTeam then
- local newTeam = nil
-
- if player.Neutral or teamColorTable[player.TeamColor.Name] == nil then
- newTeam = "Neutral"
- else
- newTeam = teamColorTable[player.TeamColor.Name]
- end
-
- if playerTable[player].CurrentTeam == newTeam then
- return
- end
-
- local oldTeam = playerTable[player].LastTeam
- removeFromTeam(player)
-
- playerTable[player].CurrentTeam = newTeam
-
- if teamTable[oldTeam] and teamTable[oldTeam]["NameChangeFuncBig"] then
- if #teamTable[oldTeam].Players < 1 then
- teamTable[oldTeam]["NameChangeFuncBig"](" " .. oldTeam.Name)
- else
- teamTable[oldTeam]["NameChangeFuncBig"](" " .. oldTeam.Name .. " (" .. tostring(#teamTable[oldTeam].Players) ..")")
- end
- end
-
- if teamTable[newTeam] then
- table.insert(teamTable[newTeam].Players, player)
- if newTeam["Name"] then
- if teamTable[newTeam]["NameChangeFuncBig"] then
- if #teamTable[newTeam].Players < 1 then
- teamTable[newTeam]["NameChangeFuncBig"](" " .. newTeam.Name)
- else
- teamTable[newTeam]["NameChangeFuncBig"](" " .. newTeam.Name .. " (" .. tostring(#teamTable[newTeam].Players) ..")")
- end
- end
- end
- end
-
- if newTeam == "Neutral" then
- updatePlayerNameColor(player, nil)
- else
- updatePlayerNameColor(player, player.TeamColor)
- end
-
- playerTable[player].LastTeam = newTeam
-
- recomputeCompleteTeamScore(newTeam)
-
- --Relayout
- if sortPlayerListsFunction then
- sortPlayerListsFunction()
- end
- end
- end
-
- local function buildTeamObject(team, numStatColumns, suffix)
- local isTeam, isScore = getBoardTypeInfo()
- local teamObject, changeFunc = createTeamName(team.Name, team.TeamColor)
- teamObject.NameLabel.Text = " " .. team.Name .. " (0)"
- if not teamTable[team] then
- teamTable[team] = {}
- end
- teamTable[team]["NameObject" .. suffix] = teamObject
- teamTable[team]["NameChangeFunc" .. suffix] = changeFunc
- if isScore then
- local statObject
- local textChangers
- teamObject, statObject, textChangers = createStatColumns(teamObject, numStatColumns, true, suffix == "Big")
- teamTable[team]["StatObject" .. suffix] = statObject
- teamTable[team]["StatChangers" .. suffix] = textChangers
- end
- teamTable[team]["MainObject" .. suffix] = teamObject
- changeFunc(" " .. team.Name)
- if not teamTable[team].Players then
- teamTable[team].Players = {}
- else
- if suffix ~= "Small" and #teamTable[team].Players > 0 then
- changeFunc(" " .. team.Name .. " (" .. tostring(#teamTable[team].Players) ..")")
- end
- end
-
- return teamObject
- end
-
- local currentContextMenuPlayer = nil
- local function updatePlayerContextMenu(player,x,y)
- currentContextMenuPlayer = player
- local elementHeight = 18
- local function highlight(button)
- button.TextColor3 = Color3.new(0,0,0)
- button.BackgroundColor3 = Color3.new(0.8,0.8,0.8)
- end
- local function clearHighlight(button)
- button.TextColor3 = Color3.new(1,1,1)
- button.BackgroundColor3 = Color3.new(0,0,0)
- end
- if playerContextMenu == nil then
- elementNames = {}
- elementNameToElement = {}
-
- for i, contextElement in ipairs(contextMenuElements) do
- table.insert(elementNames, contextElement.Text)
- elementNameToElement[tostring(contextElement.Text)] = contextElement
- end
-
- playerContextMenu = Instance.new("TextButton")
- playerContextMenu.Name = "PlayerListContextMenu"
- playerContextMenu.Style = Enum.ButtonStyle.RobloxButton
- playerContextMenu.Text = ""
- playerContextMenu.Visible = false
- playerContextMenu.ZIndex = 4
-
- playerContextMenu.MouseLeave:connect(function()
- local menuChildren = playerContextMenu:GetChildren()
- for i = 1, #menuChildren do
- if menuChildren[i].Name == "ChoiceButton" then
- menuChildren[i].TextColor3 = Color3.new(1,1,1)
- menuChildren[i].BackgroundTransparency = 1
- end
- end
- playerContextMenu.Visible = false
- inContextMenu = false
- end)
-
- playerContextMenu.MouseEnter:connect(function()
- inContextMenu = true
- end)
-
- for i = 1, #elementNames do
- local newElementButton = Instance.new("TextButton")
- newElementButton.Name = "ChoiceButton"
- newElementButton.Text = elementNames[i]
- newElementButton.TextColor3 = Color3.new(1,1,1)
- newElementButton.Font = Enum.Font.Arial
- newElementButton.FontSize = Enum.FontSize.Size14
- newElementButton.BackgroundTransparency = 1
- newElementButton.TextWrap = true
- newElementButton.Size = UDim2.new(1,0,0,elementHeight)
- newElementButton.Position = UDim2.new(0,0,0,elementHeight * (i - 1))
- newElementButton.ZIndex = playerContextMenu.ZIndex + 1
-
- newElementButton.MouseEnter:connect(function()
- newElementButton.TextColor3 = Color3.new(0,0,0)
- newElementButton.BackgroundTransparency = 0
- end)
-
- newElementButton.MouseLeave:connect(function()
- newElementButton.TextColor3 = Color3.new(1,1,1)
- newElementButton.BackgroundTransparency = 1
- end)
-
- newElementButton.MouseButton1Click:connect(function()
- local element = elementNameToElement[newElementButton.Text]
- pcall(function() element.DoIt(currentContextMenuPlayer) end)
- playerContextMenu.Visible = false
- newElementButton.TextColor3 = Color3.new(1,1,1)
- newElementButton.BackgroundTransparency = 1
- end)
-
- newElementButton.Parent = playerContextMenu
- end
-
- robloxLock(playerContextMenu)
- playerContextMenu.Parent = script.Parent
-
- end
-
- local visibleElements = 0
- for i, contextElement in ipairs(contextMenuElements) do
- local isVisible = false
-
- if contextElement.IsVisible then
- local success, visible = pcall(function() return contextElement.IsVisible(currentContextMenuPlayer) end)
- if success then
- isVisible = visible
- else
- print("Error in IsVisible call: " .. visible)
- end
- end
-
- if isVisible then
- local foundElement = false
- for i = 1, #elementNames do
- if elementNames[i] == contextElement.Text then
- foundElement = true
- break
- end
- end
- if not foundElement then
- table.insert(elementNames,contextElement.Text)
- end
- visibleElements = visibleElements + 1
- else
- for i = 1, #elementNames do
- if elementNames[i] == contextElement.Text then
- table.remove(elementNames,i)
- break
- end
- end
- end
- end
- playerContextMenu.Size = UDim2.new(0, 150, 0, elementHeight + (elementHeight * visibleElements) )
-
- if x and y then
- x = x - (playerContextMenu.AbsoluteSize.X/2)
- if x + playerContextMenu.AbsoluteSize.X >= script.Parent.AbsoluteSize.X then
- x = script.Parent.AbsoluteSize.X - playerContextMenu.AbsoluteSize.X
- end
- playerContextMenu.Position = UDim2.new(0, x, 0, y - 3)
- end
-
- local elementPos = 0
- local contextChildren = playerContextMenu:GetChildren()
- for i = 1, #contextChildren do
- if contextChildren[i]:IsA("GuiObject") and contextChildren[i].Name == "ChoiceButton" then
- contextChildren[i].Visible = false
- for j = 1, #elementNames do
- if elementNames[j] == contextChildren[i].Text then
- contextChildren[i].Visible = true
- contextChildren[i].Position = UDim2.new(0,0,0,elementPos * elementHeight)
- elementPos = elementPos + 1
- break
- end
- end
- end
- end
- end
-
- local function playerContextMenuHasItems()
- if playerContextMenu then
- local children = playerContextMenu:GetChildren()
- for i = 1, #children do
- if children[i]:IsA("GuiObject") and children[i].Name == "ChoiceButton" and children[i].Visible then
- return true
- end
- end
- end
- return false
- end
-
- local function showPlayerMenu(player, x, y)
- updatePlayerContextMenu(player,x,y)
- if not playerContextMenuHasItems() then return end -- don't show if we have nothing to show
- playerContextMenu.Visible = true
- end
-
- local function buildPlayerObject(player, numStatColumns, suffix)
- if not player then return nil end
-
- local isTeam, isScore = getBoardTypeInfo()
-
- local playerObject = nil
- local changePlayerNameFunction = nil
- local currentColor = nil
- if isTeam and not player.Neutral then
- currentColor = player.TeamColor.Color
- else
- currentColor = Color3.new(1,1,1)
- end
- playerObject, changePlayerNameFunction = createPlayerName(player.Name, player.MembershipType, currentColor, getFriendStatus(player))
-
- if not playerTable[player] then
- playerTable[player] = {}
- end
- if not playerTable[player].Connections then
- playerTable[player].Connections = {}
- end
- if not playerTable[player].CurrentTeam then
- playerTable[player].CurrentTeam = nil
- end
- if not playerTable[player].LastTeam then
- playerTable[player].LastTeam = nil
- end
- playerTable[player]["NameObject" .. suffix] = playerObject
- playerTable[player]["ChangeName" .. suffix] = changePlayerNameFunction
-
- if isScore then
- local statObject = nil
- local textChangers = nil
- playerObject, statObject, textChangers = createStatColumns(playerObject, numStatColumns, false, suffix == "Big")
- playerTable[player]["StatObject" .. suffix]= statObject
- playerTable[player]["StatChangers" .. suffix] = textChangers
-
- local statValues, leaderstats = getStatValuesForPlayer(player)
- if not statValues or #statValues < numStatColumns then
- if not playerTable[player].LeaderStatConnections then
- playerTable[player].LeaderStatConnections = {}
- end
- --Setup a listener to see when this data gets filled in
- if not leaderstats then
- --We don't even have a leaderstats child, wait for one
- table.insert(playerTable[player].LeaderStatConnections,
- player.ChildAdded:connect(
- function(child)
- if child.Name == "leaderstats" then
- --Connections will be torn down
- recreatePlayerFunction(player)
- else
- table.insert(playerTable[player].LeaderStatConnections,
- child.Changed:connect(
- function(prop)
- if prop == "Name" and child.Name == "leaderstats" then
- --Connections will be torn down
- recreatePlayerFunction(player)
- end
- end))
- end
- end))
- else
- --We have a leaderstats, but not enough children, recreate if we get them
- table.insert(playerTable[player].LeaderStatConnections,
- leaderstats.ChildAdded:connect(
- function(child)
- --TODO only look for IntValue
- recreatePlayerFunction(player)
- end)
- )
- table.insert(playerTable[player].LeaderStatConnections,
- leaderstats.AncestryChanged:connect(
- function(child)
- --We got deleted, try again
- recreatePlayerFunction(player)
- end)
- )
- end
- end
- if statValues then
- if not playerTable[player].StatValues then
- playerTable[player].StatValues = {}
- end
- local pos = 1
- while pos <= numStatColumns and pos <= #statValues do
- local currentColumn = pos
- local statValue = statValues[pos]
- local statChanger = textChangers[pos]
-
- local updateStat = function(val)
- statChanger(val)
- if playerTable[player] ~= nil then recomputeTeamScore(playerTable[player].CurrentTeam, currentColumn) end
- end
- if pos > #playerTable[player].StatValues then
- table.insert(playerTable[player].StatValues, statValue)
- end
-
- if type(statValue) ~= "number" and statValue["Changed"] then
- table.insert(playerTable[player].Connections,
- statValue.Changed:connect(updateStat)
- )
- end
-
- table.insert(playerTable[player].Connections,
- statValue.AncestryChanged:connect(
- function()
- recreatePlayerFunction(player)
- end)
- )
- updateStat(statValue.Value)
- pos = pos + 1
- end
- end
- end
-
- if supportFriends and player ~= game.Players.LocalPlayer and player.userId > 0 and game.Players.LocalPlayer.userId > 0 then
- local button = Instance.new("TextButton")
- button.Name = playerObject.Name .. "Button"
- button.Text = ""
- button.Active = false
- button.Size = playerObject.Size
- button.Position = playerObject.Position
- button.BackgroundColor3 = playerObject.BackgroundColor3
-
- local secondButton = Instance.new("TextButton")
- secondButton.Name = playerObject.Name .. "RealButton"
- secondButton.Text = ""
- secondButton.BackgroundTransparency = 1
- secondButton.BackgroundColor3 = playerObject.BackgroundColor3
- local theNameLabel = playerObject:findFirstChild("NameLabel",true)
- secondButton.Parent.BackgroundTransparency = 1
- secondButton.Parent.Visible = true
- secondButton.ZIndex = 2
- secondButton.Size = UDim2.new(1,0,1,0)
-
- local previousTransparency = nil
- table.insert(playerTable[player].Connections,
- secondButton.MouseEnter:connect(
- function(x,y)
- if playerContextMenu and playerContextMenu.Visible then
- return
- end -- don't update if we currently see it
-
- updatePlayerContextMenu(player,x,y)
- if not playerContextMenuHasItems() then return end -- don't show if we have nothing to show
-
- if previousTransparency == nil then
- previousTransparency = secondButton.BackgroundTransparency
- end
- secondButton.Parent.BackgroundTransparency = 0
- end))
- table.insert(playerTable[player].Connections,
- secondButton.MouseLeave:connect(
- function()
- if previousTransparency ~= nil then
- previousTransparency = nil
- end
- delay(0.01,function()
- if playerContextMenu and not inContextMenu then
- playerContextMenu.Visible = false
- end
- end)
- secondButton.Parent.BackgroundTransparency = 1
- end))
-
- local mouseDownX, mouseDownY
- table.insert(playerTable[player].Connections,
- secondButton.MouseButton1Down:connect(function(x,y)
- mouseDownX = x
- mouseDownY = y
- end))
- table.insert(playerTable[player].Connections,
- secondButton.MouseButton1Click:connect(function()
- showPlayerMenu(player, mouseDownX, secondButton.AbsolutePosition.Y + secondButton.AbsoluteSize.Y )
- end))
- playerObject.BackgroundTransparency = 1
- playerObject.Size = UDim2.new(1,0,1,0)
- playerObject.Position = UDim2.new(0,0,0,0)
- playerObject.Parent = button
-
- playerTable[player]["MainObject" .. suffix] = button
-
- playerObject = button
- else
- playerTable[player]["MainObject" .. suffix] = playerObject
-
- if player == game.Players.LocalPlayer and supportFriends then
- table.insert(playerTable[player].Connections,
- player.FriendStatusChanged:connect(
- function(otherPlayer, friendStatus)
- if friendRequestBlacklist[otherPlayer] then
- updatePlayerFriendStatus(playerTable[otherPlayer]["NameObject" .. suffix], Enum.FriendStatus.NotFriend)
- elseif playerTable[otherPlayer] then
- updatePlayerFriendStatus(playerTable[otherPlayer]["NameObject" .. suffix], friendStatus)
- end
- end)
- )
- end
- end
- table.insert(playerTable[player].Connections,
- player.Changed:connect(
- function(prop)
- if prop == "MembershipType" then
- updatePlayerName(playerTable[player]["NameObject" .. suffix], player.MembershipType, currentColor)
- elseif prop == "Name" then
- playerTable[player]["ChangeName" .. suffix](player.Name)
- elseif prop == "Neutral" or prop == "TeamColor" then
- assignToTeam(player)
- end
- end)
- )
- return playerObject
- end
-
- local function doSort(tableToSort, objectName, order, startPos, sortType, ascending)
- local orderedPlayerTable = {}
- getLocalPlayer = false
- for i, player in ipairs(tableToSort) do
- if playerTable[player] then
- if playerTable[player][objectName] ~= nil then
- if player ~= game.Players.LocalPlayer then
- table.insert(orderedPlayerTable,playerTable[player][objectName])
- else
- getLocalPlayer = true
- end
- end
- end
- end
-
- if sortType == nil then -- default back to alphabetical sort
- table.sort(orderedPlayerTable,function(a,b)
- return string.lower(a:FindFirstChild("FullNameLabel",true).Text) < string.lower(b:FindFirstChild("FullNameLabel",true).Text)
- end)
- else -- we are sorting by a value
- table.sort(orderedPlayerTable,function(a,b)
- if ascending then
- currentSortName = ""
- return tonumber(a:FindFirstChild(sortType,true).Text) > tonumber(b:FindFirstChild(sortType,true).Text)
- else
- currentSortName = sortType
- return tonumber(a:FindFirstChild(sortType,true).Text) < tonumber(b:FindFirstChild(sortType,true).Text)
- end
- end)
- end
- if getLocalPlayer and playerTable[game.Players.LocalPlayer] and playerTable[game.Players.LocalPlayer][objectName] then
- table.insert(orderedPlayerTable,1,playerTable[game.Players.LocalPlayer][objectName])
- end
- for i = 1, #orderedPlayerTable do
- order[orderedPlayerTable[i]] = startPos
- startPos = startPos + 1
- end
-
- return startPos
- end
-
- local function orderScrollList(scrollOrder, objectName, scrollFrame, sortType, ascending)
- local pos = 0
- local order = {}
- local isTeam, isScore = getBoardTypeInfo()
- for i, obj in ipairs(scrollOrder) do
- order[obj] = 0
- end
-
- if isTeam then
- local teams = getTeams()
- for i, team in ipairs(teams) do
- if teamTable[team][objectName] then
- order[teamTable[team][objectName]] = pos
- pos = pos + 1
- end
- pos = doSort(teamTable[team].Players, objectName, order, pos, sortType, ascending)
- end
-
- if #teamTable["Neutral"].Players > 0 then
- teamTable["Neutral"][objectName].Parent = scrollFrame
- order[teamTable["Neutral"][objectName]] = pos
- pos = pos + 1
- doSort(teamTable["Neutral"].Players, objectName, order, pos, sortType, ascending)
- else
- teamTable["Neutral"][objectName].Parent = nil
- end
- else
- local players = getPlayers()
- doSort(players, objectName, order, pos, sortType, ascending)
- end
-
- table.sort(scrollOrder,
- function(a,b)
- return order[a] < order[b]
- end)
- end
-
- local function createPlayerListBasics(frame, isBig)
- local headerFrame = Instance.new("Frame")
- headerFrame.Name = "Header"
- headerFrame.BackgroundTransparency = 1
- headerFrame.Size = UDim2.new(1,-13,0,26)
- headerFrame.Position = UDim2.new(0,0,0,0)
- headerFrame.Parent = frame
-
- local lowerPaneFrame = Instance.new("Frame")
- lowerPaneFrame.Name = "ScrollingArea"
- lowerPaneFrame.BackgroundTransparency = 1
- lowerPaneFrame.Size = UDim2.new(1,-3,1,-26)
- if not isBig then lowerPaneFrame.Size = UDim2.new(1,-3,1,-30) end
- lowerPaneFrame.Position = UDim2.new(0,0,0,26)
- lowerPaneFrame.Parent = frame
-
- local scrollOrder = {}
- local scrollFrame, scrollUp, scrollDown, recalculateScroll, scrollBar = RbxGui.CreateScrollingFrame(scrollOrder)
-
- scrollBar.Size = UDim2.new(0, 17, 1, -36)
- if isBig then scrollBar.Size = UDim2.new(0, 17, 1, -61) end
- scrollBar.Parent = lowerPaneFrame
-
- scrollFrame.Parent = lowerPaneFrame
- scrollUp.Parent = lowerPaneFrame
- scrollDown.Parent = lowerPaneFrame
-
- if isBig then
- scrollFrame.Position = UDim2.new(0,0,0,0)
- scrollUp.Position = UDim2.new(1,-41,0,5)
- scrollDown.Position = UDim2.new(1,-41,1,-35)
- scrollBar.Position = UDim2.new(1, -41, 0, 24)
-
- scrollFrame.Size = UDim2.new(1,-48,1,-16)
- headerFrame.Size = UDim2.new(1,-20,0,26)
-
- else
- scrollBar.Position = UDim2.new(1, -15, 0, 14)
- scrollBar.Size = UDim2.new(0,17,1,-36)
- scrollFrame.Position = UDim2.new(0,1,0,0)
- scrollUp.Position = UDim2.new(1,-15,0,-5)
- scrollDown.Position = UDim2.new(1,-15,1,-20)
-
- lowerPaneFrame.Position = UDim2.new(0,0,0,30)
-
- local toggleScrollBar = function(visible)
- if visible then
- scrollFrame.Size = UDim2.new(1,-16,1,0)
- headerFrame.Size = UDim2.new(1,-16,0,smallWindowHeaderYSize)
- else
- scrollFrame.Size = UDim2.new(1,0,1,0)
- headerFrame.Size = UDim2.new(1,0,0,smallWindowHeaderYSize)
- end
- scrollUp.Visible = visible
- scrollDown.Visible = visible
- scrollBar.Visible = visible
- end
- scrollUp.Changed:connect(function(prop)
- if prop == "Active" then
- toggleScrollBar(scrollUp.Active or scrollDown.Active)
- end
- end)
-
- scrollDown.Changed:connect(function(prop)
- if prop == "Active" then
- toggleScrollBar(scrollUp.Active or scrollDown.Active)
- end
- end)
-
- toggleScrollBar(scrollUp.Active or scrollDown.Active)
- end
- return headerFrame, scrollFrame, recalculateScroll, scrollOrder
- end
-
- createBoardsFunction = function (boardType, numStatColumns)
- local updatePlayerCount = function()
- return #getPlayers()
- end
-
- local smallFrame = Instance.new("Frame")
- smallFrame.Name = "SmallPlayerlist"
- smallFrame.Position = smallWindowPosition
- smallFrame.Active = false
- smallFrame.Size = smallWindowSize
- smallFrame.BackgroundColor3 = Color3.new(0,0,0)
- smallFrame.BackgroundTransparency = 0.7
- smallFrame.BorderSizePixel = 0
-
- local bigFrame = Instance.new("Frame")
- bigFrame.Name = "BigPlayerlist"
- bigFrame.Size = bigWindowSize
- bigFrame.Position = bigWindowPosition
- bigFrame.BackgroundColor3 = Color3.new(0,0,0)
- bigFrame.BackgroundTransparency = 0.7
- bigFrame.BorderSizePixel = 0
- bigFrame.Visible = false
-
- local bigFrameWrapper = Instance.new("Frame")
- bigFrameWrapper.Name = "Expander"
- bigFrameWrapper.Size = UDim2.new(1,21,1,16)
- bigFrameWrapper.Position = UDim2.new(0, 0, 0,0)
- bigFrameWrapper.BackgroundTransparency = 1
- bigFrameWrapper.Parent = bigFrame
-
- local smallHeaderFrame, scrollFrameSmall, recalculateScrollSmall, scrollOrderSmall = createPlayerListBasics(smallFrame, false)
- local bigHeaderFrame, scrollFrameBig, recalculateScrollBig, scrollOrderBig = createPlayerListBasics(bigFrameWrapper, true)
-
- local playerListButton = Instance.new("ImageButton")
- playerListButton.Name = "GoBigButton"
- playerListButton.BackgroundTransparency = 1
- playerListButton.Image = "rbxasset://textures/ui/playerlist_small_maximize.png"
- playerListButton.Size = UDim2.new(0.0, 35, 0, 29)
- playerListButton.Position = UDim2.new(0, 0, 0, 0)
- playerListButton.MouseButton1Click:connect(
- function()
- toggleBigWindow()
- end)
- playerListButton.Parent = smallHeaderFrame
-
- playerListButton = Instance.new("ImageButton")
- playerListButton.Name = "CloseButton"
- playerListButton.BackgroundTransparency = 1
- playerListButton.Image = "rbxasset://textures/ui/playerlist_small_hide.png"
- playerListButton.Size = UDim2.new(0.0, 38, 0, 29)
- playerListButton.Position = UDim2.new(0, 35, 0, 0)
- playerListButton.MouseButton1Click:connect(
- function()
- transitionWindowsFunction("None")
- end)
- playerListButton.Parent = smallHeaderFrame
-
- playerListButton = Instance.new("ImageButton")
- playerListButton.Name = "CloseButton"
- playerListButton.Image = "rbxasset://textures/ui/playerlist_big_hide.png"
- playerListButton.BackgroundTransparency = 1
- playerListButton.Size = UDim2.new(0.0, 29, 0, 29)
- playerListButton.Position = UDim2.new(1, -30, 0.5, -13)
- playerListButton.MouseButton1Click:connect(
- function()
- toggleBigWindow()
- end)
- playerListButton.Parent = bigHeaderFrame
-
- local placeName = Instance.new("TextButton")
- placeName.Name = "PlaceName"
- placeName.Text = " Players (" .. tostring(updatePlayerCount()) .. ")"
- placeName.AutoButtonColor = false
- placeName.FontSize = Enum.FontSize.Size24
- placeName.TextXAlignment = Enum.TextXAlignment.Left
- placeName.Font = Enum.Font.ArialBold
- placeName.BorderSizePixel = 0
- placeName.BackgroundColor3 = Color3.new(0,0,0)
- placeName.BackgroundTransparency = 1
- placeName.TextColor3 = Color3.new(1,1,1)
- placeName.Size = UDim2.new(0.4, 0, 1, 0)
- placeName.Position = UDim2.new(0, 0, 0.0, 0)
- placeName = RbxGui.AutoTruncateTextObject(placeName)
- placeName.Parent = bigHeaderFrame
-
- placeName.MouseEnter:connect(function()
- placeName.BackgroundTransparency = 0.2
- end)
-
- placeName.MouseLeave:connect(function()
- placeName.BackgroundTransparency = 1
- end)
-
- placeName.MouseButton1Click:connect(function()
- sortPlayerListsFunction()
- end)
-
- currentBoardType = boardType
- currentStatCount = numStatColumns
- local isTeam, isScore = getBoardTypeInfo()
- local players = getPlayers()
-
- if isScore then
- local statColumns = getStatColumns(players)
- numStatColumns = #statColumns
- if numStatColumns > 3 then
- numStatColumns = 3
- end
- createStatHeaders(statColumns, numStatColumns, false).Parent = smallHeaderFrame
- createStatHeaders(statColumns, currentStatCount, true).Parent = bigHeaderFrame
- end
-
- --Clean up all old stuff
- resetPlayerTable()
- updatePlayerCount()
-
- for i, player in ipairs(players) do
- local playerObject = buildPlayerObject(player, numStatColumns, "Small")
- table.insert(scrollOrderSmall, playerObject)
- playerObject.Parent = scrollFrameSmall
-
- playerObject = buildPlayerObject(player, currentStatCount, "Big")
- table.insert(scrollOrderBig, playerObject)
- playerObject.Parent = scrollFrameBig
- end
-
- --Clean up old stuff
- resetTeamTable()
-
- local teamStatObjects = {}
- if isTeam then
- local teams = getTeams()
- local i = #teams
- while i >= 1 do
- --We go backwards so the "first" team color gets the team
- local team = teams[i]
- teamColorTable[team.TeamColor.Name] = team
- i = i - 1
- end
-
- --Adding/Removing a Team causes a full invalidation of the board
- for i, team in ipairs(teams) do
- local teamObject = buildTeamObject(team, numStatColumns, "Small")
- table.insert(scrollOrderSmall, teamObject)
- teamObject.Parent = scrollFrameSmall
-
- teamObject = buildTeamObject(team, currentStatCount, "Big")
- table.insert(scrollOrderBig, teamObject)
- teamObject.Parent = scrollFrameBig
- end
-
- teamTable["Neutral"] = {}
- teamTable["Neutral"].Players = {}
-
- local neutralTeamObject = createTeamName("Neutral", BrickColor.palette(8))
- teamTable["Neutral"].NameObjectSmall = neutralTeamObject
- teamTable["Neutral"].StatObjectSmall = nil
- teamTable["Neutral"].MainObjectSmall = neutralTeamObject
- table.insert(scrollOrderSmall, neutralTeamObject)
-
- neutralTeamObject = createTeamName("Neutral", BrickColor.palette(8))
- teamTable["Neutral"].NameObjectBig = neutralTeamObject
- teamTable["Neutral"].StatObjectBig = nil
- teamTable["Neutral"].MainObjectBig = neutralTeamObject
- table.insert(scrollOrderBig, neutralTeamObject)
-
- local neutralPlayers = {}
- for i, player in ipairs(players) do
- assignToTeam(player)
- end
- end
-
- removePlayerFunction = function(player)
- if playerTable[player] then
- clearTableEntry(player, playerTable[player])
-
- placeName.Text = " Players (" .. tostring(updatePlayerCount()) .. ")"
-
- ArrayRemove(scrollOrderSmall, playerTable[player].MainObjectSmall)
- ArrayRemove(scrollOrderBig, playerTable[player].MainObjectBig)
-
- playerTable[player] = nil
- recalculateSmallPlayerListSize(smallFrame)
- end
- end
- recreatePlayerFunction = function(player)
- placeName.Text = " Players (" .. tostring(updatePlayerCount()) .. ")"
-
- removePlayerFunction(player)
-
- local playerObject = buildPlayerObject(player, numStatColumns, "Small")
- table.insert(scrollOrderSmall, playerObject)
- robloxLock(playerObject)
- playerObject.Parent = scrollFrameSmall
-
- playerObject = buildPlayerObject(player, currentStatCount, "Big")
- table.insert(scrollOrderBig, playerObject)
- robloxLock(playerObject)
- playerObject.Parent = scrollFrameBig
-
- local isTeam, isScore = getBoardTypeInfo()
- if isTeam then
- assignToTeam(player)
- end
-
- sortPlayerListsFunction()
- recalculateSmallPlayerListSize(smallFrame)
- end
-
- if screenResizeCon then screenResizeCon:disconnect() end
- screenResizeCon = screen.Changed:connect(
- function(prop)
- if prop == "AbsoluteSize" then
- wait()
- recalculateSmallPlayerListSize(smallFrame)
- end
- end)
-
- sortPlayerListsFunction = function(sortType, ascending)
- orderScrollList(scrollOrderSmall, "MainObjectSmall", scrollFrameSmall, sortType, ascending)
- recalculateScrollSmall()
- createAlternatingRows(scrollOrderSmall)
-
- orderScrollList(scrollOrderBig, "MainObjectBig", scrollFrameBig, sortType, ascending)
- recalculateScrollBig()
- createAlternatingRows(scrollOrderBig)
- end
-
- sortPlayerListsFunction()
-
- robloxLock(smallFrame)
- robloxLock(bigFrame)
- return smallFrame, bigFrame
- end
-
- --Teams changing invalidates the whole board
- local function teamsChanged()
- if debounceTeamsChanged then
- return
- end
-
- debounceTeamsChanged = true
- wait()
- rebuildBoard(script.Parent, determineBoardType())
- debounceTeamsChanged = false
- end
-
-
- local checkIfBoardChanged = function()
- local newBoardType, numStats = determineBoardType()
- if newBoardType ~= currentBoardType or numStats ~= currentStatCount then
- rebuildBoard(script.Parent, newBoardType, numStats)
- end
- end
-
- local function buildPlayerList()
- waitForChild(game, "Players")
- waitForProperty(game.Players, "LocalPlayer")
-
- local teams = game:GetService("Teams")
- if teams then
- local teamConnections = {}
-
- teams.ChildAdded:connect(
- function(child)
- if child:IsA("Team") then
- teamsChanged()
- teamConnections[child] = child.Changed:connect(
- function(prop)
- if prop == "TeamColor" or prop == "Name" then
- --Rebuild when things change
- teamsChanged()
- end
- end)
- end
- end)
- teams.ChildRemoved:connect(
- function(child)
- if child:IsA("Team") then
- if teamConnections[child] then
- teamConnections[child]:disconnect()
- teamConnections[child] = nil
- end
- teamsChanged()
- end
- end)
- end
-
- game.Players.ChildAdded:connect(
- function(player)
- if player:IsA("Player") then
- addPlayerFunction(player)
- end
- end)
-
- game.Players.ChildRemoved:connect(
- function(player)
- if player:IsA("Player") then
- if removePlayerFunction then
- removePlayerFunction(player)
- end
- end
- end)
-
- rebuildBoard(script.Parent, determineBoardType())
-
- delay(0,
- function()
- while true do
- wait(5)
- checkIfBoardChanged()
- end
- end)
- end
-
- buildPlayerList()
-end
-
-if not personalServerPlace then -- one more backup check
- local theBool = game.Workspace:FindFirstChild("PSVariable")
- if theBool and theBool:IsA("BoolValue") then
- personalServerPlace = true
- end
-end
-
-if personalServerPlace then
- addPersonalServerContext()
- setupBuildToolManagement()
-else
- local psVarCon = nil
- psVarCon = game.Workspace.ChildAdded:connect(function(child)
- if child:IsA("BoolValue") and child.Name == "PSVariable" then
- psVarCon:disconnect()
- personalServerPlace = true
- addPersonalServerContext()
- setupBuildToolManagement()
- end
- end)
-end
-
-
----------------------------------- Start Player Hover Code ----------------------------------------
-if contextMenu3d then
- local inMenu = false
-
- function waitForProperty(instance, name)
- while not instance[name] do
- instance.Changed:wait()
- end
- end
-
- function makeNewActionButton()
- local button = Instance.new("TextButton")
- button.Name = "ActionButton"
- button.Style = Enum.ButtonStyle.RobloxButtonDefault
- button.BackgroundColor3 = Color3.new(0,0,0)
- button.BorderColor3 = Color3.new(1,0,0)
- button.BackgroundTransparency = 0.5
- button.Size = UDim2.new(1,0,0,50)
- button.Text = ""
- button.Font = Enum.Font.ArialBold
- button.FontSize = Enum.FontSize.Size18
- button.TextColor3 = Color3.new(1,1,1)
- button.ZIndex = 4
- return button
- end
-
- function getContextElements(currentContextMenuPlayer)
- local elements = {}
- for i, contextElement in ipairs(contextMenuElements) do
- local element = contextElement
-
- local isVisible = false
-
- if contextElement.IsVisible then
- local success, visible = pcall(function() return contextElement.IsVisible(currentContextMenuPlayer) end)
- if success then
- isVisible = visible
- else
- print("Error in IsVisible call: " .. visible)
- end
- end
-
- if element.Type == "Button" then
- local button = makeNewActionButton()
- button.Name = "ContextButton" .. i
- button.Visible = isVisible
- button.Text = contextElement.Text
- button.MouseButton1Click:connect(function()
- if button.Active then
- local success, result = pcall(function() element.DoIt(currentContextMenuPlayer) end)
- end
- end)
-
- contextElement.Button = button
- contextElement.Element = button
-
- table.insert(elements,contextElement)
- end
- end
-
- return elements
- end
-
- function findContextElement(contextElements, button)
- for i = 1, #contextElements do
- if contextElements[i].Button == button then
- return contextElements[i]
- end
- end
- end
-
- function populateActions(scrollFrame, nullFrame, recalcFunction, otherPlayer)
- local elements = getContextElements(otherPlayer)
- for i = 1, #elements do
- if elements[i].Button.Visible then
- elements[i].Button.Parent = scrollFrame
- else
- elements[i].Button.Parent = nullFrame
- end
-
- local actionButtonCon
- actionButtonCon = elements[i].Button.MouseButton1Click:connect(function()
- actionButtonCon:disconnect()
-
- local nullFrameChildren = nullFrame:GetChildren()
- for j = 1, #nullFrameChildren do
- local contextElement = findContextElement(elements, nullFrameChildren[j])
- pcall(function() nullFrameChildren[j].Visible = contextElement.IsVisible(otherPlayer) end)
- if nullFrameChildren[j].Visible then
- nullFrameChildren[j].Parent = scrollFrame
- end
- end
-
- local scrollFrameChildren = scrollFrame:GetChildren()
- for j = 1, #scrollFrameChildren do
- local contextElement = findContextElement(elements, scrollFrameChildren[j])
- pcall(function() scrollFrameChildren[j].Visible = contextElement.IsVisible(otherPlayer) end)
- if not scrollFrameChildren[j].Visible then
- scrollFrameChildren[j].Parent = nullFrame
- end
- end
-
- elements[i].Button.Parent = nullFrame
- recalcFunction()
- end)
- end
- end
-
-
- function createContextMenu(otherPlayer)
-
- local frame = Instance.new("Frame")
- frame.Name = "ContextMenuFrame"
- frame.Style = Enum.FrameStyle.RobloxRound
- frame.Size = UDim2.new(0,300,0,400)
- frame.Position = UDim2.new(0.5,-150,0.5,-200)
- frame.ZIndex = 2
-
- local scrollFrame, scrollUpButton, scrollDownButton, recalc, scrollBar = RbxGui.CreateScrollingFrame()
-
- scrollFrame.Name = "Actions"
- scrollFrame.BackgroundTransparency = 1
- scrollFrame.Position = UDim2.new(0,0,0,25)
- scrollFrame.Size = UDim2.new(1,-20,1,-80)
- scrollFrame.ZIndex = 3
- scrollFrame.Parent = frame
-
- local nullFrame = Instance.new("Frame")
- nullFrame.Name = "NullFrame"
- nullFrame.BackgroundTransparency = 1
- nullFrame.Visible = false
- nullFrame.Parent = frame
-
- local scrollButtons = Instance.new("Frame")
- scrollButtons.Name = "ScrollButtons"
- scrollButtons.BackgroundTransparency = 1
- scrollButtons.Position = UDim2.new(1,-17,0,25)
- scrollButtons.Size = UDim2.new(0,17,1,-80)
- scrollButtons.ZIndex = 3
- scrollButtons.Parent = frame
-
- scrollUpButton.ZIndex = 3
- scrollUpButton.Parent = scrollButtons
- scrollDownButton.Position = UDim2.new(0,0,1,-17)
- scrollDownButton.ZIndex = 3
- scrollDownButton.Parent = scrollButtons
-
- scrollBar.Size = UDim2.new(1,0,1,-34)
- scrollBar.Position = UDim2.new(0,0,0,17)
- scrollBar.Parent = scrollButtons
-
- local playerImage = Instance.new("ImageLabel")
- playerImage.Name = "PlayerImage"
- playerImage.BackgroundTransparency = 1
- playerImage.Image = "http://www.roblox.com/thumbs/avatar.ashx?userId=" .. tostring(otherPlayer.userId) .. "&x=352&y=352"
- playerImage.Position = UDim2.new(0.5,-150,0.5,-150)
- playerImage.Size = UDim2.new(0,300,0,300)
- playerImage.Parent = frame
-
- local playerName = Instance.new("TextLabel")
- playerName.Name = "PlayerName"
- playerName.BackgroundTransparency = 1
- playerName.Font = Enum.Font.ArialBold
- playerName.FontSize = Enum.FontSize.Size24
- playerName.Position = UDim2.new(0,-8,0,-6)
- playerName.Size = UDim2.new(1,16,0,24)
- playerName.Text = otherPlayer["Name"]
- playerName.TextColor3 = Color3.new(1,1,1)
- playerName.TextWrap = true
- playerName.ZIndex = 3
- playerName.Parent = frame
-
- local doneButtonCon
-
- local doneButton = Instance.new("TextButton")
- doneButton.Name = "DoneButton"
- doneButton.Style = Enum.ButtonStyle.RobloxButton
- doneButton.Font = Enum.Font.ArialBold
- doneButton.FontSize = Enum.FontSize.Size36
- doneButton.Position = UDim2.new(0.25,0,1,-50)
- doneButton.Size = UDim2.new(0.5,0,0,50)
- doneButton.Text = "Done"
- doneButton.TextColor3 = Color3.new(1,1,1)
- doneButton.ZIndex = 3
- doneButton.Parent = frame
- doneButton.Modal = true
- doneButtonCon = doneButton.MouseButton1Click:connect(function()
- doneButtonCon:disconnect()
- inMenu = false
- game.GuiService:RemoveCenterDialog(frame)
- frame:remove()
- end)
-
- populateActions(scrollFrame, nullFrame, recalc, otherPlayer)
- recalc()
-
- return frame
- end
-
- function makeContextInvisible(menu)
- menu.Visible = false
- end
-
- function goToContextMenu(otherPlayer)
-
- local menu = createContextMenu(otherPlayer)
-
- game.GuiService:AddCenterDialog(menu, Enum.CenterDialogType.PlayerInitiatedDialog,
- --ShowFunction
- function()
- menu.Visible = true
- menu:TweenSize(UDim2.new(0,300,0,400),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.5,true)
- end,
- --HideFunction
- function()
- menu:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.5,true,function() makeContextInvisible(menu) end)
- end)
- menu.Parent = game.CoreGui.RobloxGui
-
- inMenu = true
- end
-
- waitForProperty(game.Players, "LocalPlayer")
-
- local currSelectedPlayer = nil
- if game.Players.LocalPlayer["HoverOnPlayerChanged"] then
- game.Players.LocalPlayer.HoverOnPlayerChanged:connect(function(otherPlayer)
- if not inMenu then
- if otherPlayer and otherPlayer.userId < 0 then return end -- we don't want this for guests
- end
- wait(0.5)
- currSelectedPlayer = otherPlayer
- end)
- end
-
- if game.Players.LocalPlayer["MouseDownOnPlayer"] then
- game.Players.LocalPlayer.MouseDownOnPlayer:connect(function(otherPlayer)
- if currSelectedPlayer ~= otherPlayer then return end
- if not inMenu and otherPlayer.userId > 0 then
- goToContextMenu(otherPlayer)
- end
- end)
- end
-end
----------------------------------- End Player Hover Code ----------------------------------------
- true
-
-
-
-
-
\ No newline at end of file
diff --git a/Health2011.rbxm b/Health2011.rbxm
deleted file mode 100644
index 4fadee2..0000000
--- a/Health2011.rbxm
+++ /dev/null
@@ -1,336 +0,0 @@
-
- null
- nil
- -
-
- false
-
- GUI_Copy
- script.HealthGUI:clone().Parent = game.StarterGui;
-script:remove();
- true
-
-
-
-
- HealthGUI
- true
-
-
-
-
- false
- 4285215356
- 1
- 4279970357
- 1
- tray
-
- 0.5
- -44
- 1
- -26
-
-
- 0
- 170
- 0
- 18
-
- 2
- 0
- true
- 1
- true
-
-
-
-
- false
- 4294967295
- 1
- 4279970357
- 1
- rbxasset://textures/healthgui/bkg.png
- bkg
-
- 0
- 0
- 0
- 0
-
-
- 1
- 0
- 1
- 0
-
- 0
- true
- 1
- true
-
-
- -
-
- false
- 4294967295
- 1
- 4279970357
- 1
- rbxasset://textures/healthgui/BarRed.png
- barRed
-
- 0.0189999994
- 0
- 0.100000001
- 0
-
-
- 0
- 0
- 0
- 0
-
- 0
- true
- 1
- true
-
-
- -
-
- false
- 4294967295
- 1.00000012
- 4279970357
- 0
- bar2
-
- 0.0189999994
- 0
- 0.100000001
- 0
-
-
- 0.192000002
- 0
- 0.829999983
- 0
-
- 0
- 0
- true
- 1
- true
-
-
-
-
- false
-
- Script
- h = script.Parent.Parent.Parent.Parent.Parent.Character.Humanoid
-tray = script.Parent.Parent
-base = tray.Parent
-local lastHealth = 100
-local lastHealth2 = 100
-local maxWidth = 0.96
-
-function UpdateGUI(health)
- local width = (health / h.MaxHealth) * maxWidth
- local height = 0.83
- local lastX = tray.bar.Position.X.Scale
- local x = 0.019 + (maxWidth - width)
- local y = 0.1
-
- tray.bar.Position = UDim2.new(x,0,y, 0)
- tray.bar.Size = UDim2.new(width, 0, height, 0)
- -- If more than 1/4 health, bar = green. Else, bar = red.
- if( (health / h.MaxHealth) > 0.25 ) then
- tray.barRed.Size = UDim2.new(0, 0, 0, 0)
- else
- tray.barRed.Position = tray.bar.Position
- tray.barRed.Size = tray.bar.Size
- tray.bar.Size = UDim2.new(0, 0, 0, 0)
- end
-
- if ( (lastHealth - health) > (h.MaxHealth / 10) ) then
- lastHealth = health
-
- if h.Health ~= h.MaxHealth then
- delay(0,function()
- AnimateHurtOverlay()
- end)
- delay(0,function()
- AnimateBars(x, y, lastX, height)
- end)
- end
- else
- lastHealth = health
- end
-end
-
-function AnimateBars(x, y, lastX, height)
- local width = math.abs(x - lastX)
- if( x > lastX ) then
- x = lastX
- end
- tray.bar2.Position = UDim2.new(x,0, y, 0)
- tray.bar2.Size = UDim2.new(width, 0, height, 0)
- tray.bar2.BackgroundTransparency = 0
- local GBchannels = 1
- local j = 0.2
-
- local i_total = 30
- for i=1,i_total do
- -- Increment Values
- if (GBchannels < 0.2) then
- j = -j
- end
- GBchannels = GBchannels + j
- if (i > (i_total - 10)) then
- tray.bar2.BackgroundTransparency = tray.bar2.BackgroundTransparency + 0.1
- end
- tray.bar2.BackgroundColor3 = Color3.new(1, GBchannels, GBchannels)
-
- wait(0.02)
- end
-end
-
-function AnimateHurtOverlay()
- -- Start:
- -- overlay.Position = UDim2.new(0, 0, 0, -22)
- -- overlay.Size = UDim2.new(1, 0, 1.15, 30)
-
- -- Finish:
- -- overlay.Position = UDim2.new(-2, 0, -2, -22)
- -- overlay.Size = UDim2.new(4.5, 0, 4.65, 30)
-
- overlay = base.hurtOverlay
- overlay.Visible = true
- overlay.Position = UDim2.new(-2, 0, -2, -22)
- overlay.Size = UDim2.new(4.5, 0, 4.65, 30)
- -- Animate In, fast
- local i_total = 2
- local wiggle_total = 0
- local wiggle_i = 0.02
- for i=1,i_total do
- overlay.Position = UDim2.new( (-2 + (2 * (i/i_total)) + wiggle_total/2), 0, (-2 + (2 * (i/i_total)) + wiggle_total/2), -22 )
- overlay.Size = UDim2.new( (4.5 - (3.5 * (i/i_total)) + wiggle_total), 0, (4.65 - (3.5 * (i/i_total)) + wiggle_total), 30 )
- wait(0.01)
- end
-
- i_total = 30
-
- wait(0.03)
-
- -- Animate Out, slow
- for i=1,i_total do
- if( math.abs(wiggle_total) > (wiggle_i * 3) ) then
- wiggle_i = -wiggle_i
- end
- wiggle_total = wiggle_total + wiggle_i
- overlay.Position = UDim2.new( (0 - (2 * (i/i_total)) + wiggle_total/2), 0, (0 - (2 * (i/i_total)) + wiggle_total/2), -22 )
- overlay.Size = UDim2.new( (1 + (3.5 * (i/i_total)) + wiggle_total), 0, (1.15 + (3.5 * (i/i_total)) + wiggle_total), 30 )
- wait(0.01)
- end
-
- -- Hide after we're done
- overlay.Position = UDim2.new(10, 0, 0, 0)
- overlay.Visible = false
-end
-
-h.Changed:connect(function()
- UpdateGUI(h.Health)
- if ( (lastHealth2 - h.Health) > (h.MaxHealth / 10) ) then
- lastHealth2 = h.Health
- else
- lastHealth2 = h.Health
- end end)
-
- true
-
-
-
- -
-
- false
- 4294967295
- 1
- 4279970357
- 1
- rbxasset://textures/healthgui/Bar.png
- bar
-
- 0.0189999994
- 0
- 0.100000001
- 0
-
-
- 0.959999979
- 0
- 0.829999983
- 0
-
- 0
- true
- 1
- true
-
-
- -
-
- false
- 4294967295
- 1
- 4279970357
- 0
- rbxasset://textures/healthgui/label.png
- label
-
- 0.680000007
- 0
- 0.300000012
- 0
-
-
- 0.25
- 0
- 0.349999994
- 0
-
- 0
- true
- 1
- true
-
-
-
- -
-
- false
- 4290164919
- 1
- 4279970357
- 1
- rbxasset://textures/healthgui/HurtOverlay.png
- hurtOverlay
-
- 2
- 0
- 0
- -22
-
-
- 1
- 0
- 1.1500001
- 30
-
- 0
- false
- 1
- true
-
-
-
-
-
\ No newline at end of file
diff --git a/Health2012.rbxm b/Health2012.rbxm
deleted file mode 100644
index 4fadee2..0000000
--- a/Health2012.rbxm
+++ /dev/null
@@ -1,336 +0,0 @@
-
- null
- nil
- -
-
- false
-
- GUI_Copy
- script.HealthGUI:clone().Parent = game.StarterGui;
-script:remove();
- true
-
-
-
-
- HealthGUI
- true
-
-
-
-
- false
- 4285215356
- 1
- 4279970357
- 1
- tray
-
- 0.5
- -44
- 1
- -26
-
-
- 0
- 170
- 0
- 18
-
- 2
- 0
- true
- 1
- true
-
-
-
-
- false
- 4294967295
- 1
- 4279970357
- 1
- rbxasset://textures/healthgui/bkg.png
- bkg
-
- 0
- 0
- 0
- 0
-
-
- 1
- 0
- 1
- 0
-
- 0
- true
- 1
- true
-
-
- -
-
- false
- 4294967295
- 1
- 4279970357
- 1
- rbxasset://textures/healthgui/BarRed.png
- barRed
-
- 0.0189999994
- 0
- 0.100000001
- 0
-
-
- 0
- 0
- 0
- 0
-
- 0
- true
- 1
- true
-
-
- -
-
- false
- 4294967295
- 1.00000012
- 4279970357
- 0
- bar2
-
- 0.0189999994
- 0
- 0.100000001
- 0
-
-
- 0.192000002
- 0
- 0.829999983
- 0
-
- 0
- 0
- true
- 1
- true
-
-
-
-
- false
-
- Script
- h = script.Parent.Parent.Parent.Parent.Parent.Character.Humanoid
-tray = script.Parent.Parent
-base = tray.Parent
-local lastHealth = 100
-local lastHealth2 = 100
-local maxWidth = 0.96
-
-function UpdateGUI(health)
- local width = (health / h.MaxHealth) * maxWidth
- local height = 0.83
- local lastX = tray.bar.Position.X.Scale
- local x = 0.019 + (maxWidth - width)
- local y = 0.1
-
- tray.bar.Position = UDim2.new(x,0,y, 0)
- tray.bar.Size = UDim2.new(width, 0, height, 0)
- -- If more than 1/4 health, bar = green. Else, bar = red.
- if( (health / h.MaxHealth) > 0.25 ) then
- tray.barRed.Size = UDim2.new(0, 0, 0, 0)
- else
- tray.barRed.Position = tray.bar.Position
- tray.barRed.Size = tray.bar.Size
- tray.bar.Size = UDim2.new(0, 0, 0, 0)
- end
-
- if ( (lastHealth - health) > (h.MaxHealth / 10) ) then
- lastHealth = health
-
- if h.Health ~= h.MaxHealth then
- delay(0,function()
- AnimateHurtOverlay()
- end)
- delay(0,function()
- AnimateBars(x, y, lastX, height)
- end)
- end
- else
- lastHealth = health
- end
-end
-
-function AnimateBars(x, y, lastX, height)
- local width = math.abs(x - lastX)
- if( x > lastX ) then
- x = lastX
- end
- tray.bar2.Position = UDim2.new(x,0, y, 0)
- tray.bar2.Size = UDim2.new(width, 0, height, 0)
- tray.bar2.BackgroundTransparency = 0
- local GBchannels = 1
- local j = 0.2
-
- local i_total = 30
- for i=1,i_total do
- -- Increment Values
- if (GBchannels < 0.2) then
- j = -j
- end
- GBchannels = GBchannels + j
- if (i > (i_total - 10)) then
- tray.bar2.BackgroundTransparency = tray.bar2.BackgroundTransparency + 0.1
- end
- tray.bar2.BackgroundColor3 = Color3.new(1, GBchannels, GBchannels)
-
- wait(0.02)
- end
-end
-
-function AnimateHurtOverlay()
- -- Start:
- -- overlay.Position = UDim2.new(0, 0, 0, -22)
- -- overlay.Size = UDim2.new(1, 0, 1.15, 30)
-
- -- Finish:
- -- overlay.Position = UDim2.new(-2, 0, -2, -22)
- -- overlay.Size = UDim2.new(4.5, 0, 4.65, 30)
-
- overlay = base.hurtOverlay
- overlay.Visible = true
- overlay.Position = UDim2.new(-2, 0, -2, -22)
- overlay.Size = UDim2.new(4.5, 0, 4.65, 30)
- -- Animate In, fast
- local i_total = 2
- local wiggle_total = 0
- local wiggle_i = 0.02
- for i=1,i_total do
- overlay.Position = UDim2.new( (-2 + (2 * (i/i_total)) + wiggle_total/2), 0, (-2 + (2 * (i/i_total)) + wiggle_total/2), -22 )
- overlay.Size = UDim2.new( (4.5 - (3.5 * (i/i_total)) + wiggle_total), 0, (4.65 - (3.5 * (i/i_total)) + wiggle_total), 30 )
- wait(0.01)
- end
-
- i_total = 30
-
- wait(0.03)
-
- -- Animate Out, slow
- for i=1,i_total do
- if( math.abs(wiggle_total) > (wiggle_i * 3) ) then
- wiggle_i = -wiggle_i
- end
- wiggle_total = wiggle_total + wiggle_i
- overlay.Position = UDim2.new( (0 - (2 * (i/i_total)) + wiggle_total/2), 0, (0 - (2 * (i/i_total)) + wiggle_total/2), -22 )
- overlay.Size = UDim2.new( (1 + (3.5 * (i/i_total)) + wiggle_total), 0, (1.15 + (3.5 * (i/i_total)) + wiggle_total), 30 )
- wait(0.01)
- end
-
- -- Hide after we're done
- overlay.Position = UDim2.new(10, 0, 0, 0)
- overlay.Visible = false
-end
-
-h.Changed:connect(function()
- UpdateGUI(h.Health)
- if ( (lastHealth2 - h.Health) > (h.MaxHealth / 10) ) then
- lastHealth2 = h.Health
- else
- lastHealth2 = h.Health
- end end)
-
- true
-
-
-
- -
-
- false
- 4294967295
- 1
- 4279970357
- 1
- rbxasset://textures/healthgui/Bar.png
- bar
-
- 0.0189999994
- 0
- 0.100000001
- 0
-
-
- 0.959999979
- 0
- 0.829999983
- 0
-
- 0
- true
- 1
- true
-
-
- -
-
- false
- 4294967295
- 1
- 4279970357
- 0
- rbxasset://textures/healthgui/label.png
- label
-
- 0.680000007
- 0
- 0.300000012
- 0
-
-
- 0.25
- 0
- 0.349999994
- 0
-
- 0
- true
- 1
- true
-
-
-
- -
-
- false
- 4290164919
- 1
- 4279970357
- 1
- rbxasset://textures/healthgui/HurtOverlay.png
- hurtOverlay
-
- 2
- 0
- 0
- -22
-
-
- 1
- 0
- 1.1500001
- 30
-
- 0
- false
- 1
- true
-
-
-
-
-
\ No newline at end of file
diff --git a/LICENCE.MD b/LICENSE.MD
similarity index 100%
rename from LICENCE.MD
rename to LICENSE.MD
diff --git a/RBXLegacyLauncher/RBXLegacyLauncher/MainForm.resx b/RBXLegacyLauncher/RBXLegacyLauncher/MainForm.resx
index 4312cb0..ac14fe9 100644
--- a/RBXLegacyLauncher/RBXLegacyLauncher/MainForm.resx
+++ b/RBXLegacyLauncher/RBXLegacyLauncher/MainForm.resx
@@ -120,64 +120,86 @@
- iVBORw0KGgoAAAANSUhEUgAAAQsAAABGCAYAAADb5LFUAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
- wQAADsEBuJFr7QAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTFH80I3AAAM90lEQVR4Xu2d
- P44lNRDG5w7cAGljLoDEKZC4AdIegJSIgJQAcYCVOMFK5GgiEoINIZh4VkQTTfCW+p7teX52VbnK7W6Y
- mfpJn2amn9v9Z1xf29XufjdBEARBEARBEARBEARBUPPp5uYN6Y70Ni8KgucJNeL3pE+k+0pYVvS20pu8
- WmCAztfXpEcSzi9+xvkLni/UgItZePVAKuZySyrm8j3p1ZsLHfs7UnvObvPHS6D6foLyn0GwL9TYZs3C
- IxgLguervNkXCx1jGXZw5wH6OhfdBNUDoyh1fp8XB8F+UEM7wixqvVjjoGOqhx2SHnLxaaiO2iigE2mJ
- CQWBCDWyo82iVjGOZz9coWPwnMf3eTU3tG5rFEVhGMG+UAPjGjmujnXCkxMCvV1vi9B1RyDsahxUP3Ip
- yKvguD+QcCzn481FXNB6GHagDu6YIAQxt9wd2LSOZBRFYRjBflDj6s3ixx8/LePPP1EnEqCj7nmtaeOg
- db4iwRCwPo4NdWnBXOtDrsYElcd2JDNI5/HjR/zOlXGZE5UfGUURtvXic0PBfwA1rH3NouZiHHKA9Tob
- R97dM/Q3cgMIVAxhsP8rezomw6By/Xm76PTp99/zQRPv33NloHe5OhUqZzWKIpyLuE0brIUa1XFmUZMC
- CMMAq3GgnKd3skViENNno2HH/bk30cKvM+wF0OeyUfz6K37iHPafhWEEq6EGNW8Wf/+dgp4LDg9+4zhC
- 3fwFWjYedkjgXPHrisMR+kw3ikIYRnAE1JjmzQJd7ct6aJi3m80jGYc2T8Er7Beu6nfn44KwDew7hkXp
- 6izpyTDod/uwQ+KXX7h1Ic6YbEZRSMfZl6Xlucog2AY1pr5RzplFqwdzPRwwnBTI0tBDNwEPsmGgJ4A7
- J1IgQg8uc5SHI089APpdMoqTeGzYB3k/XYnbIGChhoSu9XXjWmMWRfwY3gofXPnDheg9DEm3eW078nDk
- Lv8//EZRCMMI9oQa0d5mAT24r/aFo8wC2A3jdO7FzCIPR6Tcw9goCmEYwV5QAzrCLKC5ADvSLMDYMB7O
- vYOtSMfVy24UBZTHenx9Sx9mC14R1HhWmwWCQE4G4qrqYU+zkIZHumF8yKW2IQ9HavmNoqAbRjypGvih
- hrPcLHK9GHtLjfWDOY+xyizKbd40KSzVqR2n3JX3G56EPByBfIlTjjCMYCXUaHqzQDBZUMwC0O/aU5gP
- uRYd6TbqCOwbzCCtL+3DSQzIZCpt+YvQ+1gBb4bbjQKk3gtnejAQ0+zRIHiCGs28WaQrdbdurvoM/Y0Z
- j/xVGgE9IgV8Lwk5SSiJH1akq7Ku2SFCTT8cWWMUcq8Cy+Jhs8APNZx5s+ADmc240/LeMLaYhRSoUk9E
- k5Sw5IOt1nxOoeYyHFljFHLOBf+DmNEZzEGNZ7VZsO9qwPKmXFp/hGQWktFI5XXxx2vrpTwuCXAMe1bV
- w+8njiWMIpiHGtBrMItyhwbHyr0bk6/PPu9iTY9gC9i+3KuaftlOEDxBDWl3s6Bl2AaXZBxvx2sWfICf
- Z0cW6G8uqfiYa7iQApATl4O5y2sdT9pPKZEZdz2CNVBj2s0s6HckN7Wu/PiOiNcssLwvj6BBz+Kc2Mu/
- 9+W4Oxx8EOJ5Ec781szB8BCJzOAoqEHtYhb0EwGlJQjvxcRiDR/8XrOwqr+Vyh8j8gK4Ldwf36o5GBZS
- L4o7xzC4eFtWsBZqVKvNAj0J7Y6Eb9q31yzSrcgZPbI9i3TlbnV+7Jt+cueO76GsRupxpXMficxgPdSw
- VpuFJl/GPxkFP4NTMgvAlZd1PwxufshxvnLTT/4p0RW3VCXkoV089xHsBzWwI8ziUQ3ultQ70OdLbDeL
- e/M+8cE5ejHOmjkYNXIiE4pEZrAv1MjmzUK66teCoVhJJqElRC/SAh15A2wXwx2UK7LkSFrSLFUuL9De
- YeH2e80cDJCGQ1wPJxKZwTFQQ9vLLGwJTICASr0ULSF6LWuvYJZkXNrxXb2ujv7GnR8+2bjVMGTDikRm
- cBzU2ObNAle7+spdy0qa6qyZBK6mfdB6tuFF3ycsx7Cjfg2e/PwLls/0aAo4Tr5enJdIZAbHQQ1u3izA
- 7FUz3fbjutVF+Ow8DqeffU5gL7NIPYrR8yUYcpQEp24UK4Yhcg8nvhA5OA5qcNvMAoHlTeTJ8wOK2nzA
- WrOwBHC6oo9yMjCNfY0CoB7+fGFZ5CuCY6DGttUsEFD+V+alANCu4Ki3XL17s/BsD72FZFAIbvRY7Hcq
- xj0gTuufFUkJTk4wqxiOBPtDDQ3fDdo2QI9ZXK54o/kKHHLyriwvX1F4/Zl2lwWBmurFTEvpyu/bX3sC
- dr+Hyi6PsreKF/EGx8A0Po9ZXGvGMFIvQ38zVSvNLDw9Ac/+JgPStJ9RFPhbtFC8+SrYH6bhzZsFpAWy
- RsoT2AJdNwufrIYhByq0v1GAZKxSb8mbv/iS9J2gLXxD4ur06HOSBD7j1pGk1VWjnQ9OVjznA2U1pLq0
- 9drjsp6PHqbRbTOLpPknMFOXX9dKs4BGhpGCVDKyOaNAT8WbHAbpjg03JMIyT/4CDYdWYbWF30hcnR6h
- gUvgM24dSVpdNdr54GTFcz5QVkOqS1uvPS7r+eihtdtGZzOLFECa5g0jJfS0uxH8N53x8xIQ5HgKFvkZ
- bbjD769+NZ87RphTWn9uWrg8JBK/aJkhzOKaMIsRtHbb4E65Serwgdlq29cXjiZItT0Cfp/alwhLj8/3
- L7DRjcLeA6vphzNz08LlHthtPtQRR5vFHyQ0VIs+I7WgXgj11PX+TOLqgFAWKuu2fEEqn/1FGtVVb7es
- 9wOpBcOC8vk/pHo9rm7oWxLKlvW4oQWW13UVYbnErmaRW+MA+SreBuK28fx4WHKZWn65Ytfq7hZgWVMm
- GVONbhR9+RGpPqm3NHeO5PosE7aONgutQVvg6oRwHBLtvrQgcOrPPXUVccc1c24t+zJzbtt9+d+YBRov
- 92KYecOw5DCwPZTjy8IYMJ+kCD2Lvlw9HBgZBeQZPqRh1Sh5a/sulZq0n1y9OP+j50ZmGrSFmQZtgasT
- 8gR4y0sxi7rXhl4ZVP5Gb6kui2Vz0NptQ8stcQBvFuXbwGEY7Wdz43ObWWzV9dBrvE3bUA3oc0la+XMg
- yYi4+mF2WsLzNZjFCASOta69zcILVzdUTKJetuUcXaCa2kaWW+EAfpJQ/Q5O7sUwfsPwmYU1KFv1+Qpu
- qHKR7QW98kQq9Ab4F+fMGAY//IK0CVthFmEWPqimvpFZ4IP46u3e9Pd2w7CZxSn3dLQ7KLKkW6dysI/N
- Qjabpys+/eQNQ9ofDXl70otxjjYLJBCxzVZWuDqhtg4ESruNopbnbBblmNr9wrCjDD1KGRzndqjGvoFZ
- MJgFoGXbAmI8c/LafJDshHGkQMetUhiI3uMoCVIOeV0+D6PnO7hkK/9dJnOGIW2Xm7C1V4OWgkqSFW5d
- CMdR4zmu52wWheO2RTX2jcuC0SwALZ83DD43UmRPnKIc6sI2077DRDAc6L8zpJDyAZqu31ch5w8gcUo2
- fcb3CrC/HuT9xXG2+Yu9GlmYxZEBfOS2qMa+cVngJzhpAcEbhnYLUr9Kb5vDYUEehtRKPRuYEG8UWDa8
- lUlluKdw7UO2ZIByL6jvXezVyKSgqjP2taxwdUJtgGM6c6m7nRvRgjL15zMKsxjC5wfe5mpZ6HPeMHBl
- bUlXSel2o/824wz2HIgUpFhuemaDykkv0jmpw6Q0TJPOE7YvGfjRZsEFlQeuTqg1i5p2X1rCLDxQjVwj
- m5VqFoDKjA0jDT2kAITmZk964beN/df2rQiB73rXBMqTuMDvh1vJTDUzG32HSJhFbxZIwmIdTu1MzCJ8
- 1jJzbuu5EZD1ga+XaxaAykmGcWfs+u9vFnyu5JT3n/9GsouQg3AZRYHWk+pOhpGGZtptXZiN5f8QZtGb
- haeuolVm4dmXmr3+jz1UI9fgZmUyC0BlJcOwCkFxdx6royvOddURWAh6TSXh2Yq/aj+98o9+l4YNbJLX
- A9XBTWqDsD3NpK5eJjxgr0YWZjF3bsMsNKj8VsM4WldzFujv1jCWfdkP6qrqHQnG5v1aAK2RIQAs8jzs
- VD8kNRIe8GrB/kLt9GXP0KFlL7NAvWV/sX9teU5IxtZzUVCHBZSt66/1sqAj0oICgYjnObgr+H+hLiBp
- GQwDwbr85blU58gw0MuYNSitkVmFOlrQ8LmyHmmB0ga4Ry17mUWN53yM6uJ4PWYB6Ki4iUkwiKcuNf1e
- 3kchZf731mPelUOh7Ur5CZyLqbxIJswizOJ5QkdWB4X6Elr6HL0NlLfclbAIPYMiBCHG/hCu7OVp1eU9
- Byu07frcnHtb+aMgeJ3koLjNf5qg8njkvJ7Q9L8O/Blof8tQZ3PyNAiCIAiCIAiCIAiCIAiCIAiCIAiC
- IAiCIAiCLdzc/AuZ7B/G7fOUiQAAAABJRU5ErkJggg==
+ iVBORw0KGgoAAAANSUhEUgAAAh0AAABxCAMAAABGF+HdAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAMAUExURQAAAEdHR/8AAP8REf8jI/80NP9HR/9XV/9paf96eomJif+Jif+YmP+np/+1tcPDw//D
+ w//Q0P/d3f/s7P///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMw1
+ ONYAAAAJcEhZcwAADrwAAA68AZW8ckkAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjExR/NC
+ NwAADxlJREFUeF7tne2C4ioShs+2th8n6kad+7/WJeSFKqCqIDHtzI48f6a7xKQHHqGAJP7zq9PR6HZ0
+ dLodHZ1uR0en29HR6XZ0dLodHZ3/DztuB/zQeSvMjtuXY3eIDJHbGHig7Ft5nr++BvzceSfMjnGyo43j
+ 9Yk3vYH7fjrlb/Hy01lnh+N4w9t+mmE+X9PY8kZnP4LVdrhB6PQGQR4HnO3rgojBdXfHT51NeMEOx+70
+ w81x3eFM7lzVseXqCnU9tuQ1Oxz78881yPOIk3hqY4uTo8WhTjsv2+HYX36mSUafjhL22OLl+Pr67rnH
+ dgh27KdJ7AnTWuIbL4t8/4AgSEcJs1+Ipbse2yHYUZ0d3M/Zh9pz2HaWeycbz2f8YPxlJxRxdD02QxpZ
+ 8LvF/UzpItG4DPIcx8swHA77rysiJZd4/N3t1zPYqI4tTI6ux3astMNxO0mC6LPcxzgOw/lwSN6l6MHS
+ 0e9pOAl/2k5p90SOrsdmrLfDcUvmFCBdBrmPN5/E4MUCUY8bGXSeI2FsOc6/ZmRydD224iU73If8Kgpy
+ Hq/DcLQTWVDqMW2rgF14NY4tUtcU5Thh3tL12IgX7XA8Ly0S6OR6sHT0m5ZSjLGF5IjT2q7HNrxuh+Px
+ kiCpHmwee+ItrI4tXI6ux7ZsYodDnuW2wfSgbRUaVWa0sSXKgeLx967H67TZcT0Ol7G2Yn4XJzElh8Np
+ GMaRpZ7RAxZjo8qMPLbkcnQ9tqTNDnT3u8NkiVHp8izXAyfYcuc9n5nwbZVkVJmRxpZSjq7HhiyyY8av
+ QKigECidYDA9ppyBbatko8pMObY84ziUlO96bMUKO+xtcpRxDV6/zDDRg51jL58g/IF7NPoz5sKZTF2P
+ jVhjR9EaHJRouxKU6cGGpKPWpmFswUAU5ChsJW26Hi+xzo6whCkQW7npOmGmR0TfqI9jyzj9osrR9dgK
+ ZscdFSrYQauXgYNW6zEVaLuKvNBDGVVm2NhiydH12AhmRxwU8CtD2CYpZpxgoR25HuqoMhPHFluOrsc2
+ LLPjGOvcNYu8GxvtaL1BKdHjG0GNOLaEf9UMueuxAcvsGGg64BAThMV2pHoY+a4nJkczxuz6EQ/b9VjL
+ Ujt+XfDjhLBktcIOSngmanpwPe12J+u6HitZbAdf7ZaqvW7HY7wO6UVC8T0OdagAT/v0nK7Hqyy3g2+x
+ C20ZP9uFHc/xNpwPSBiS3RLeH1X18Lf7emptPt9i6el6rGKFHWwBW9hQj0sj3A5nBVPK4/fbwQOxmVpL
+ ht2YWrmR9TINN9J1StbYwQf/oocQ7UAoYVrRCtCHfKLS7BhbpKSHE6/0cN0RP1enHcmOstrDpzDYwaoe
+ gYhoR95xTITdkolstY33KwJ+bKmU4dmrtjTTqSHZUX7S8AJ7JY7++D0i2sHTzkhUrZin1prejS2VEnzw
+ U5d1OzXW2vFEpCjcbscX+0izFMFjz2ufu4ocD9ZZ1TqZjs5aO2IoXzEV7Sj3aSbYwmiyijFh61EZKvj6
+ Wm39pGOw2o48UQ3EQYLbEZTZHYfrGCcd7L0shZypzWstej66FWvtiGsJ+V6+accci5sldNt0HKgi6/Vg
+ HVXPR19jpR1x/EgkmBDtCDksxpK4dE5lQldEF6auXMB6skEqzUf/SUCwY7HKDv5gjf0cikQ7+AsxiN/j
+ 4mjMCkJk/+LyN23NFvkotAAIdiya7EgnKPzT6fAliCgCfyG1Y6QDxAX1uFz6oAOsmG1Y+Si0AAh2LJrs
+ SBqX78K5zjvfQhftiHplt+CzlfjQHV1YUrlYD/6YsSLlgBYAwY7FUjvYzWqOXbl/QXsmCHgQEggnC7mk
+ 04WSmoXTUXqjdOEHtAAIdiwW2kEPXZkQL/PDa212HOK54jncMWnkWaQHG/GkvwxaAAQ7FsvsSPZL9kW5
+ CbqUBwGPtNHC3XAE76bltdhBLZjX8nxUvGQeWgAEOxbL7OAMUsfBM1aEPNJS+int/MMa2ZRsUEs368Eu
+ 5lB6HGgBEOxY8FoK9dtih7jO9Bz4wIOgp7Qjc4NWOP1MmK4Aa5zXslxZEwpaAAQ7FryWQhPW7RCyUceV
+ fXwdiHqyjZbdUCaNcV7jG3fhsgdbPFcvRIYWAMGOxSo7jlIDjHn/gLjncvD3Ww+XcdSe9BB9mM2jczbM
+ ayv56Ay0AAh2LJrsSK77lG9kebAGAnilDfawMCyvty978Is59Fs4ux3LabKDrSNMt6EhyngmJQBeayJ5
+ 6DVO0Lrswa6CFp/sEIAWAEETFK2AwsR/8ULJf1Ai52ff8S9emfkX0UB4NY9PLLXju3jRwZYoGXixAdZx
+ OPZh3CJj5NvuZtjiuT3BQS0ABE1QtAIKEx9mh82YLmbEIQYv10k6Dkp4aayyElOWE1XyV9QCQNAERSug
+ MNHtiDzY45wcLmHFT612pJt6dKV5mxy0TlL98g3UAkDQBEUroDDR7QDpmDAvfuLn1sM80kOEdZBWOdjK
+ WSV7RS0ABE1QtAIKE3+3He23BqXbLlgYx2/tkqU7e94PNg2prndQ4mFnr6gFgKAJilZAYeLvtiO/VNSh
+ tHTSriGbxK9LuqBbuo524s87rsnB576/OyvV24zD2+8d7/hxOw5CzJP0HnMh/LIsfUnW4Bm1O948cWzS
+ voPBg1oACJqgKEDQIm25/FMcXpXaWis7o9vRco4ft0Mf1JPvbvPzXfws2nEfh+HwLT39SVhOczSsk07E
+ Liy/ypWDWgAImqAoQNBiectJsQn9SMvP8QY79IZKLhY7P2U7xttwCvffK6tW2cx4olEOtmm36VopigIE
+ LZa3nBSb0I+0/BzvsEPv5JOJyz7eQ8ntoMcqALEV0yS3XQ7XJ+EdVmaKWgAImqAoQNBiectJsQn9SMvP
+ 8RY7jAQx//ZHD7ejXGkXD5be1tIuB8tM9fVS1AJA0ARFAYIWy1tOik3oR1p+jp+2AxeL6npIGy22HWIz
+ Js+IWiIHWx9R/0jUAkDQBEUBghbLW06KTehHWn6O1I6ZyQXbmok2O8JytTG95E8EmuF2pAuqoFxXSR5K
+ hlgjtChWPHAGoBYAgiYoChC0sFtOYms7dEoXrF5jZpkd5j5XPinldoRDpxSZDJNooRyuf4unF0bGCdQF
+ QNAERQGCFh9uh6lHtubJ7aCOZX9kEmXXcbHtVn29Vu2+6I/kZyZQFwBBExQFCFp8ph1symHukieTDt4z
+ IOQbPXkqHd+bZ3LoM4+TPrrF5Ebej0NdAARNUBQgaPGZdvCk0rzCJlkbY02PyPyp5oXY3bYtckz7L/qK
+ VzyuaBDqAiBogqIAQYtuR2WzK9kyCRegxk4frUbZJ617MDnUnGO+LUF92d6uRV0ABE1QVAAFcrSWq7f1
+ u+3gtNkRFrVqdth68LuOwrU80Q7/myMOVbF7YXKoxw+rsuqCKB1EOATqAiBogqICKJDzJ9sxU/YgFvz/
+ GRzQ7QgZZVmCkeam/saXsFYVnwUV7QhDAJfjS0wbeI+j6mlt16JGAIImKCqAAjmfaUcY0IfQiNZ8M7XD
+ vekZjxztCGtXIZDIkT8SBPBtOlUPY7sWNQIQNEFRARTI+Uw7KCNp0CO342s/hiNPE9ph+r64kJxgjKCP
+ /IR47GTAMmZO8ezsmXUzqBGAoAmKCqBAzqfbQXqoE8vCDteY+BfsYpF5ZYJWKjxSx8Bvk51Q9dC3a1Ej
+ AEETFBVAgZzPtmPKIYMe6rpDKJwpIYK3pNd2CGlH+kiZCf6o5AR1uxY1AhA0QVEBFMhZb4fNn21H+OD6
+ j3pNj7Lv+NZEiUsXXA8h7aCR6Rj7GdVObbsWNQIQNEFRgKCF3XLh1b/NDryAgaCiR2HHqXzeJKAzsf23
+ Iu1g9zS40SI2vroqFoun/QtqBCBogqIAQYtuhyPoIQ/+6TDhW7vsTmbY+ykxzaWjfHRepo0ltcxY2a5F
+ jQAETVAUIGjxCXaUH0q8EOyw9aBhwDOP/o/xcs6fKPe18y8BeluqRzgXnS3qp62Kydu1qBGAoAmKAgQt
+ PtuO2GyWHokd2a7MeB3Y91ImH23W5XA96B5disai0uxmgiZBbJcPNQIQNEFRgKDFR9pRLIQzPcoG4nbI
+ Y899HE7TYJNs0/MpK4lAB2NTaBo6ND3ifhzbrkWNAARNUBQgaPH77ZDOwXmPHdThFw3E7DCfU/4cWRch
+ f/sXy0eTZIj0EE/ALzQh0VAjAEETFAUIWqy3Qys7I71jpuUcnDfZoetB+/N8hKiRLpfOb6WvWcm7qJhZ
+ VIc2etwIagQgaIKiAEGL5S2ntaZ+pOXn4LzLDtIjnePQx11fThVgaYfH6RFPIDgQXyv2U5ILXA/sjagR
+ gKAJigIELZa3nNaa+pGWn4PzA3aEz3W2ThWlYVNLfns0Qm1kK+Xu7bQEIvVB8eTZi7zjSB9+hxoBCJqg
+ KEDQYnnLaa2pH2n5OTiv26GSa1OuPPC9skIyi5h2XPlHf0bug+LJuYXJ/XTZ+1AjAEETFAUIWixvOa01
+ 9SMtPwfnjXZQC+FJf/z72JbZETuKJxfMUy7OzcS3kJv8prziGVaokQoo7EGoAgpPpC2nsaUdGn+CHewD
+ POlBicLEIjtCKjt1BEkKYlzGGstBD35H3q50CjVSAYU9CFVAYaLWfq/ZMaOfQ/Ni5q12JHqkcuiPlZUI
+ b/XLn0wPecEExHKTQUnHIT1RFTVSAYU9CFVAYeJD7ZA2NkiP/B5pF7qKGQPjOY7jMAyHmMvOa5ux2aV8
+ lOCrYnyPX36+P2qkAgp7EKqAwsSH2iFmAFEPkWM5MNzH8ToMp0Px1fgTsAF/Sm1OTHrQIov7M+V3oUYq
+ oLAHoQooTHQ7GLkeWReyO43URRQbcRlx/uEPquWjBO23RYpvmwqgRiqgsAehCihM/J12rCXV41o8q2MB
+ tOt6tfJRIst15Md0z6BGKqCwB6EKKEx0OxKYHq5Jn0OxstUMa9urlY8SqYvSY7o7q9nEDtIDU4z7uTKC
+ aKxoXKYmXzfvbMA2doQmYnuyN/re4WYO0qSoSkiX5C+N6bzARnbMeqTzz+eVTyRkdi5RdenqbZxuclnL
+ PP9dtOfXaWIrOyY9yvZ5XspZ6yZCpDgLxe9+6LzIZnb8usrDwsPlqPvD4eiEcNPan/l8P9WH7XZeYjs7
+ On8f3Y6OTrejo9Pt6Oh0Ozo63Y6OTrejo/Hr1/8Ak7ap1Jj4mP8AAAAASUVORK5CYII=
diff --git a/RBXLegacyLauncher/RBXLegacyLauncher/Resources/Logo.png b/RBXLegacyLauncher/RBXLegacyLauncher/Resources/Logo.png
deleted file mode 100644
index b715a48..0000000
Binary files a/RBXLegacyLauncher/RBXLegacyLauncher/Resources/Logo.png and /dev/null differ
diff --git a/README.md b/README.md
index fb90d59..60b7148 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,22 @@
-Source code for RBXLegacy's launcher, installer, and server. All of these source files are under the license specified in LICENSE.MD.
+
+
+
+## Overview
+
+RBXLegacy is a launcher and website for ROBLOX's clients from 2006 - 2012, designed so you can play offline, online and through LAN.
+
+This is the source code for RBXLegacy's launcher, installer and server. All of these source files are under the license specified in [LICENSE.MD](https://github.com/Bitl/RBXLegacy-src/blob/master/LICENSE.MD).
+
+## Installing
+
+The latest stable version will always be found on the official Discord in `#downloads`. You can ask a friend to get an invite for the Discord.
+
+You can also download it from this repository to receive changes as soon as they are committed.
+
+## Contributing
+
+If you find any problem(s) in RBXLegacy, [feel free to submit an issue here.](https://github.com/Bitl/RBXLegacy-src/issues)
+
+If you know how to solve an (existing) issue in RBXLegacy, [you can submit a pull request for it.](https://github.com/Bitl/RBXLegacy-src/pulls)
+
+And of course, we welcome everyone with new ideas. [You can post your idea in issues as well.](https://github.com/Bitl/RBXLegacy-src/issues)
diff --git a/character_fakeclients.rbxm b/character_fakeclients.rbxm
new file mode 100644
index 0000000..ee3c1a3
--- /dev/null
+++ b/character_fakeclients.rbxm
@@ -0,0 +1,712 @@
+
+ null
+ nil
+ -
+
+ 7
+ true
+
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 1
+
+ erik.cassel
+
[RBX1]
+ true
+
+ -
+
+ false
+ -0.5
+ 0.5
+ 0
+ 0
+ -0.5
+ 0.5
+ 4
+ 0
+ 24
+
+ 0
+ 4.5
+ -0.5
+ -1
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ -1
+
+ true
+ 0
+ true
+ false
+ 0.5
+ 0
+ 0.300000012
+ -0.5
+ 0.5
+ 0
+ 0
+ -0.5
+ 0.5
+ 0
+ 0
+ true
+ Head
+ 0
+ -0.5
+ 0.5
+ 0
+ 0
+
+ 0
+ 0
+ 0
+
+ -0.5
+ 0.5
+ 0
+ 0
+ 0
+
+ 0
+ 0
+ 0
+
+ true
+ 1
+
+ 2
+ 1
+ 1
+
+
+
-
+
+
+ 0
+ Mesh
+
+ 1.25
+ 1.25
+ 1.25
+
+
+
+ 1
+ 1
+ 1
+
+ true
+
+
+ -
+
+ 5
+ face
+ 20
+ 0
+ rbxasset://textures\face.png
+ true
+
+
+ -
+
+
+ 0
+ 0.5
+ 0
+ 1
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 1
+
+
+ 0
+ -0.200000003
+ 0.150000006
+ 1
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 1
+
+ HeadWeld
+
[RBX1]
+ [null]
+ true
+
+
+ -
+
+
+ 0
+ 0.5
+ 0
+ 1
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 1
+
+
+ 0
+ -0.200000003
+ 0.150000006
+ 1
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 1
+
+ HeadWeld
+
[RBX1]
+ [null]
+ true
+
+
+
+ -
+
+ false
+ -0.5
+ 0.5
+ 0
+ 0
+ -0.5
+ 0.5
+ 4
+ 0
+ 23
+
+ 0
+ 3
+ -0.5
+ -1
+ 0
+ -0
+ -0
+ 1
+ -0
+ -0
+ 0
+ -1
+
+ true
+ 0
+ true
+ false
+ 0.5
+ 0
+ 0.300000012
+ -0.5
+ 0.5
+ 0
+ 0
+ 0
+ 0
+ 2
+ 0
+ true
+ Torso
+ 0
+ 0
+ 0
+ 2
+ 0
+
+ 0
+ 0
+ 0
+
+ -0.5
+ 0.5
+ 3
+ 0
+ 0
+
+ 0
+ 0
+ 0
+
+ true
+ 1
+
+ 2
+ 2
+ 1
+
+
+
-
+
+ 5
+ roblox
+ 20
+ 0
+
+ true
+
+
+
+ -
+
+ false
+ -0.5
+ 0.5
+ 0
+ 0
+ -0.5
+ 0.5
+ 4
+ 0
+ 24
+
+ 1.5
+ 3
+ -0.5
+ -1
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ -1
+
+ true
+ 0
+ true
+ false
+ 0.5
+ 0
+ 0.300000012
+ -0.5
+ 0.5
+ 0
+ 0
+ -0.5
+ 0.5
+ 0
+ 0
+ true
+ Left Arm
+ 0
+ -0.5
+ 0.5
+ 0
+ 0
+
+ 0
+ 0
+ 0
+
+ -0.5
+ 0.5
+ 3
+ 0
+ 0
+
+ 0
+ 0
+ 0
+
+ true
+ 1
+
+ 1
+ 2
+ 1
+
+
+
-
+
+ false
+
+ Script
+ while true do--while its told its true it will happen
+script.Parent.CanCollide=true--script.Parent.(whatever) meens that its talking about the script effecting the
+--parent, which is the brick, changing whatever setting in the brick its told too change. and the true/false is
+--setting the setting to something else useing whatever unit it uses.
+wait(0)--this is how long it will wait until going to the next piece of the script below it or will restart it.
+script.Parent.CanCollide = false
+end
+ true
+
+
+
+ -
+
+ false
+ -0.5
+ 0.5
+ 0
+ 0
+ -0.5
+ 0.5
+ 4
+ 0
+ 24
+
+ -1.5
+ 3
+ -0.5
+ -1
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ -1
+
+ true
+ 0
+ true
+ false
+ 0.5
+ 0
+ 0.300000012
+ -0.5
+ 0.5
+ 0
+ 0
+ -0.5
+ 0.5
+ 0
+ 0
+ true
+ Right Arm
+ 0
+ -0.5
+ 0.5
+ 0
+ 0
+
+ 0
+ 0
+ 0
+
+ -0.5
+ 0.5
+ 3
+ 0
+ 0
+
+ 0
+ 0
+ 0
+
+ true
+ 1
+
+ 1
+ 2
+ 1
+
+
+
-
+
+ false
+
+ Script
+ while true do--while its told its true it will happen
+script.Parent.CanCollide=true--script.Parent.(whatever) meens that its talking about the script effecting the
+--parent, which is the brick, changing whatever setting in the brick its told too change. and the true/false is
+--setting the setting to something else useing whatever unit it uses.
+wait(0)--this is how long it will wait until going to the next piece of the script below it or will restart it.
+script.Parent.CanCollide = false
+end
+ true
+
+
+
+ -
+
+ false
+ -0.5
+ 0.5
+ 0
+ 0
+ -0.5
+ 0.5
+ 0
+ 0
+ 119
+
+ 0.5
+ 1
+ -0.5
+ -1
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ -1
+
+ false
+ 0
+ true
+ false
+ 0.5
+ 0
+ 0.300000012
+ -0.5
+ 0.5
+ 0
+ 0
+ -0.5
+ 0.5
+ 0
+ 0
+ true
+ Left Leg
+ 0
+ -0.5
+ 0.5
+ 0
+ 0
+
+ 0
+ 0
+ 0
+
+ -0.5
+ 0.5
+ 3
+ 0
+ 0
+
+ 0
+ 0
+ 0
+
+ true
+ 1
+
+ 1
+ 2
+ 1
+
+
+
-
+
+ false
+
+ Script
+ while true do--while its told its true it will happen
+script.Parent.CanCollide=true--script.Parent.(whatever) meens that its talking about the script effecting the
+--parent, which is the brick, changing whatever setting in the brick its told too change. and the true/false is
+--setting the setting to something else useing whatever unit it uses .
+wait(0)--this is how long it will wait until going to the next piece of the script below it or will restart it.
+script.Parent.CanCollide=false--script.Parent.(whatever) meens that its talking about the script effecting the
+--parent, which is the brick, changing whatever setting in the brick its told too change. and the true/false is
+--setting the setting to something else useing whatever unit it uses.
+wait(0)--this is how long it will wait until going to the next piece of the script below it or will restart it.
+end
+while true do--while its told its true it will happen
+script.Parent.CanCollide=true--script.Parent.(whatever) meens that its talking about the script effecting the
+--parent, which is the brick, changing whatever setting in the brick its told too change. and the true/false is
+--setting the setting to something else useing whatever unit it uses .
+wait(0)--this is how long it will wait until going to the next piece of the script below it or will restart it.
+script.Parent.CanCollide=false--script.Parent.(whatever) meens that its talking about the script effecting the
+--parent, which is the brick, changing whatever setting in the brick its told too change. and the true/false is
+--setting the setting to something else useing whatever unit it uses.
+wait(0)--this is how long it will wait until going to the next piece of the script below it or will restart it.
+end
+
+
+ true
+
+
+
+ -
+
+ false
+ -0.5
+ 0.5
+ 0
+ 0
+ -0.5
+ 0.5
+ 0
+ 0
+ 119
+
+ -0.5
+ 1
+ -0.5
+ -1
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ -1
+
+ false
+ 0
+ true
+ false
+ 0.5
+ 0
+ 0.300000012
+ -0.5
+ 0.5
+ 0
+ 0
+ -0.5
+ 0.5
+ 0
+ 0
+ true
+ Right Leg
+ 0
+ -0.5
+ 0.5
+ 0
+ 0
+
+ 0
+ 0
+ 0
+
+ -0.5
+ 0.5
+ 3
+ 0
+ 0
+
+ 0
+ 0
+ 0
+
+ true
+ 1
+
+ 1
+ 2
+ 1
+
+
+
-
+
+ false
+
+ Script
+ while true do--while its told its true it will happen
+script.Parent.CanCollide=true--script.Parent.(whatever) meens that its talking about the script effecting the
+--parent, which is the brick, changing whatever setting in the brick its told too change. and the true/false is
+--setting the setting to something else useing whatever unit it uses .
+wait(0)--this is how long it will wait until going to the next piece of the script below it or will restart it.
+script.Parent.CanCollide=false--script.Parent.(whatever) meens that its talking about the script effecting the
+--parent, which is the brick, changing whatever setting in the brick its told too change. and the true/false is
+--setting the setting to something else useing whatever unit it uses.
+wait(0)--this is how long it will wait until going to the next piece of the script below it or will restart it.
+end
+while true do--while its told its true it will happen
+script.Parent.CanCollide=true--script.Parent.(whatever) meens that its talking about the script effecting the
+--parent, which is the brick, changing whatever setting in the brick its told too change. and the true/false is
+--setting the setting to something else useing whatever unit it uses .
+wait(0)--this is how long it will wait until going to the next piece of the script below it or will restart it.
+script.Parent.CanCollide=false--script.Parent.(whatever) meens that its talking about the script effecting the
+--parent, which is the brick, changing whatever setting in the brick its told too change. and the true/false is
+--setting the setting to something else useing whatever unit it uses.
+wait(0)--this is how long it will wait until going to the next piece of the script below it or will restart it.
+end
+
+
+ true
+
+
+
+ -
+
+ 100
+ false
+ 100
+ Humanoid
+ false
+ false
+
+ 0
+ 0
+ 0
+
+
+ 0
+ 0
+ 0
+
+ 0
+
[null]
+
+ 0
+ 0
+ 0
+
+ true
+
+
+ -
+
+ false
+
+ Hats
+ while true do
+ wait()
+ if script.Parent.Humanoid.Health == 0 then
+ local Hat = nil
+ for a,b in ipairs(script.Parent:GetChildren())do
+ if(b.className == "Hat")then
+ Hat = b
+ local Handles = Hat:findFirstChild("Handle")
+ if Handles then
+ Handles.CanCollide = true
+ end
+ end
+ end
+ end
+ end
+
+ true
+
+
+
+
diff --git a/humanoidAnimate2007.rbxm b/humanoidAnimate2007.rbxm
new file mode 100644
index 0000000..2fe6ce3
--- /dev/null
+++ b/humanoidAnimate2007.rbxm
@@ -0,0 +1,301 @@
+
+ null
+ nil
+ -
+
+ false
+
+ Animate
+ -- Now with exciting TeamColors HACK!
+
+function waitForChild(parent, childName)
+ local child = parent:findFirstChild(childName)
+ if child then return child end
+ while true do
+ child = parent.ChildAdded:wait()
+ if child.Name==childName then return child end
+ end
+end
+
+----------------------------- TEAM COLORS
+
+
+function onTeamChanged(player)
+
+ wait(1)
+
+ local char = player.Character
+ if char == nil then return end
+
+ if player.Neutral then
+ -- Replacing the current BodyColor object will force a reset
+ local old = char:findFirstChild("Body Colors")
+ if not old then return end
+ old:clone().Parent = char
+ old.Parent = nil
+ else
+ local head = char:findFirstChild("Head")
+ local torso = char:findFirstChild("Torso")
+ local left_arm = char:findFirstChild("Left Arm")
+ local right_arm = char:findFirstChild("Right Arm")
+ local left_leg = char:findFirstChild("Left Leg")
+ local right_leg = char:findFirstChild("Right Leg")
+
+ if head then head.BrickColor = BrickColor.new(24) end
+ if torso then torso.BrickColor = player.TeamColor end
+ if left_arm then left_arm.BrickColor = BrickColor.new(26) end
+ if right_arm then right_arm.BrickColor = BrickColor.new(26) end
+ if left_leg then left_leg.BrickColor = BrickColor.new(26) end
+ if right_leg then right_leg.BrickColor = BrickColor.new(26) end
+ end
+end
+
+function onPlayerPropChanged(property, player)
+ if property == "Character" then
+ onTeamChanged(player)
+ end
+ if property== "TeamColor" or property == "Neutral" then
+ onTeamChanged(player)
+ end
+end
+
+
+local cPlayer = game.Players:GetPlayerFromCharacter(script.Parent)
+cPlayer.Changed:connect(function(property) onPlayerPropChanged(property, cPlayer) end )
+onTeamChanged(cPlayer)
+
+
+----------------------------- ANIMATION
+
+-- declarations
+
+local Figure = script.Parent
+local Torso = waitForChild(Figure, "Torso")
+local RightShoulder = waitForChild(Torso, "Right Shoulder")
+local LeftShoulder = waitForChild(Torso, "Left Shoulder")
+local RightHip = waitForChild(Torso, "Right Hip")
+local LeftHip = waitForChild(Torso, "Left Hip")
+local Neck = waitForChild(Torso, "Neck")
+local Humanoid = waitForChild(Figure, "Humanoid")
+local pose = "Standing"
+
+local toolAnim = "None"
+local toolAnimTime = 0
+
+local isSeated = false
+
+-- functions
+
+function onRunning(speed)
+ if isSeated then return end
+
+ if speed>0 then
+ pose = "Running"
+ else
+ pose = "Standing"
+ end
+end
+
+function onDied()
+ pose = "Dead"
+end
+
+function onJumping()
+ isSeated = false
+ pose = "Jumping"
+end
+
+function onClimbing()
+ pose = "Climbing"
+end
+
+function onGettingUp()
+ pose = "GettingUp"
+end
+
+function onFreeFall()
+ pose = "FreeFall"
+end
+
+function onFallingDown()
+ pose = "FallingDown"
+end
+
+function onSeated()
+ isSeated = true
+ pose = "Seated"
+end
+
+function moveJump()
+ RightShoulder.MaxVelocity = 0.5
+ LeftShoulder.MaxVelocity = 0.5
+ RightShoulder.DesiredAngle = 3.14
+ LeftShoulder.DesiredAngle = -3.14
+ RightHip.DesiredAngle = 0
+ LeftHip.DesiredAngle = 0
+end
+
+
+-- same as jump for now
+
+function moveFreeFall()
+ RightShoulder.MaxVelocity = 0.5
+ LeftShoulder.MaxVelocity = 0.5
+ RightShoulder.DesiredAngle = 3.14
+ LeftShoulder.DesiredAngle = -3.14
+ RightHip.DesiredAngle = 0
+ LeftHip.DesiredAngle = 0
+ wait(0.5)
+ RightShoulder.MaxVelocity = 0.1
+ LeftShoulder.MaxVelocity = 0.1
+end
+
+function moveSit()
+ RightShoulder.MaxVelocity = 0.15
+ LeftShoulder.MaxVelocity = 0.15
+ RightShoulder.DesiredAngle = 3.14 /2
+ LeftShoulder.DesiredAngle = -3.14 /2
+ RightHip.DesiredAngle = 3.14 /2
+ LeftHip.DesiredAngle = -3.14 /2
+end
+
+function getTool()
+ for _, kid in ipairs(Figure:GetChildren()) do
+ if kid.className == "Tool" then return kid end
+ end
+ return nil
+end
+
+function getToolAnim(tool)
+ for _, c in ipairs(tool:GetChildren()) do
+ if c.Name == "toolanim" and c.className == "StringValue" then
+ return c
+ end
+ end
+ return nil
+end
+
+function animateTool()
+
+ if (toolAnim == "None") then
+ RightShoulder.DesiredAngle = 1.57
+ return
+ end
+ if (toolAnim == "Slash") then
+ RightShoulder.MaxVelocity = 0.5
+ RightShoulder.DesiredAngle = 0
+ return
+ end
+
+ if (toolAnim == "Lunge") then
+ RightShoulder.MaxVelocity = 0.5
+ LeftShoulder.MaxVelocity = 0.5
+ RightHip.MaxVelocity = 0.5
+ LeftHip.MaxVelocity = 0.5
+ RightShoulder.DesiredAngle = 1.57
+ LeftShoulder.DesiredAngle = 1.0
+ RightHip.DesiredAngle = 1.57
+ LeftHip.DesiredAngle = 1.0
+ return
+ end
+end
+
+function move(time)
+ local amplitude
+ local frequency
+
+ if (pose == "Jumping") then
+ moveJump()
+ return
+ end
+
+ if (pose == "FreeFall") then
+ moveFreeFall()
+ return
+ end
+
+ if (pose == "Seated") then
+ moveSit()
+ return
+ end
+
+ local climbFudge = 0
+
+ if (pose == "Running") then
+ RightShoulder.MaxVelocity = 0.15
+ LeftShoulder.MaxVelocity = 0.15
+ amplitude = 1
+ frequency = 9
+ elseif (pose == "Climbing") and (toolAnim == "None") then
+ RightShoulder.MaxVelocity = 0.5
+ LeftShoulder.MaxVelocity = 0.5
+ RightShoulder.DesiredAngle = 0
+ amplitude = 0
+ frequency = 0
+ climbFudge = -3.14
+ RightShoulder.DesiredAngle = 0
+ else
+ amplitude = 0.1
+ frequency = 1
+ end
+
+ desiredAngle = amplitude * math.sin(time*frequency)
+
+ RightShoulder.DesiredAngle = desiredAngle + climbFudge
+ LeftShoulder.DesiredAngle = desiredAngle - climbFudge
+ RightHip.DesiredAngle = -desiredAngle
+ LeftHip.DesiredAngle = -desiredAngle
+
+
+ local tool = getTool()
+
+ if tool then
+
+ animStringValueObject = getToolAnim(tool)
+
+ if animStringValueObject then
+ toolAnim = animStringValueObject.Value
+ -- message recieved, delete StringValue
+ animStringValueObject.Parent = nil
+ toolAnimTime = time + .3
+ end
+
+ if time > toolAnimTime then
+ toolAnimTime = 0
+ toolAnim = "None"
+ end
+
+ animateTool()
+
+
+ else
+ toolAnim = "None"
+ toolAnimTime = 0
+ end
+end
+
+
+-- connect events
+
+Humanoid.Died:connect(onDied)
+Humanoid.Running:connect(onRunning)
+Humanoid.Jumping:connect(onJumping)
+Humanoid.Climbing:connect(onClimbing)
+Humanoid.GettingUp:connect(onGettingUp)
+Humanoid.FreeFalling:connect(onFreeFall)
+Humanoid.FallingDown:connect(onFallingDown)
+Humanoid.Seated:connect(onSeated)
+
+-- main program
+
+local runService = game:service("RunService");
+
+while Figure.Parent~=nil do
+ local _, time = wait(0.1)
+ move(time)
+end
+
+ true
+
+
+
diff --git a/Health2010.rbxm b/libraries2010.rbxm
similarity index 81%
rename from Health2010.rbxm
rename to libraries2010.rbxm
index cb430cc..2ac2f93 100644
--- a/Health2010.rbxm
+++ b/libraries2010.rbxm
@@ -5,14 +5,15 @@
false
- GUI_Copy
- script.HealthGUI:clone().Parent = game.StarterGui;
-script:remove();
+ Sorter
+ script.Health:clone().Parent = game.StarterGui
+script.ResetCommand:clone().Parent = game.Workspace
+script:remove()
true
-
- HealthGUI
+ Health
true
-
@@ -136,5 +137,29 @@ end)
+ -
+
+ false
+
+ ResetCommand
+ function onChatted(msg, speaker)
+
+ source = string.lower(speaker.Name)
+ msg = string.lower(msg)
+ -- Note: This one is NOT caps sensitive
+
+ if msg == "!!!reset" then
+ speaker.Character.Humanoid.Health = 0
+ end
+end
+
+function onPlayerEntered(newPlayer)
+ newPlayer.Chatted:connect(function(msg) onChatted(msg, newPlayer) end)
+end
+
+game.Players.ChildAdded:connect(onPlayerEntered)
+ true
+
+
-
\ No newline at end of file
+
diff --git a/CoreGui2012.rbxm b/libraries2011.rbxm
similarity index 92%
rename from CoreGui2012.rbxm
rename to libraries2011.rbxm
index 4692055..35fd428 100644
--- a/CoreGui2012.rbxm
+++ b/libraries2011.rbxm
@@ -5,31 +5,1071 @@
false
- GUI_Copy
- script.Playerlist:clone().Parent = game.StarterGui
+ Sorter
+ print("Special thanks to Bitl, Carrot, iago, winsupermario1234, Khangaroo, drslicendice, coke, TheLivingBee, Raymonf, and a bunch of play - testers for help making 2011 fully stable and work. 8)")
+script.Playerlist:clone().Parent = game.StarterGui
script.Dialogs:clone().Parent = game.StarterGui
-script.GameMenu:clone().Parent = game.StarterGui
+script.Health:clone().Parent = game.StarterGui
+script.ReenableDialogScript:clone().Parent = game.Lighting
+script.TimeoutScript:clone().Parent = game.Lighting
+script.ResetCommand:clone().Parent = game.Workspace
script:remove()
true
- -
+
-
- Playerlist
+ true
+
+ ReenableDialogScript
+ wait(5)
+local dialog = script.Parent
+if dialog:IsA("Dialog") then
+ dialog.InUse = false
+end
+script:Remove()
+
true
-
-
+
+ -
+
+ true
+
+ TimeoutScript
+ wait(5)
+local dialog = script.Parent
+if dialog:IsA("Dialog") then
+ dialog.InUse = false
+end
+script:Remove()
+
+ true
+
+
+ -
+
+ false
+
+ ResetCommand
+ function onChatted(msg, speaker)
+
+ source = string.lower(speaker.Name)
+ msg = string.lower(msg)
+ -- Note: This one is NOT caps sensitive
+
+ if msg == "!!!reset" then
+ speaker.Character.Humanoid.Health = 0
+ end
+end
+
+function onPlayerEntered(newPlayer)
+ newPlayer.Chatted:connect(function(msg) onChatted(msg, newPlayer) end)
+end
+
+game.Players.ChildAdded:connect(onPlayerEntered)
+ true
+
+
+ -
+
+ Health
+ true
+
+
-
+
+ false
+ 4285215356
+ 1
+ 4279970357
+ 1
+ tray
+
+ 0.5
+ -44
+ 1
+ -26
+
+
+ 0
+ 170
+ 0
+ 18
+
+ 2
+ 0
+ true
+ 1
+ true
+
+
-
+
+ false
+ 4294967295
+ 1
+ 4279970357
+ 1
+ rbxasset://textures/healthgui/bkg.png
+ bkg
+
+ 0
+ 0
+ 0
+ 0
+
+
+ 1
+ 0
+ 1
+ 0
+
+ 0
+ true
+ 1
+ true
+
+
+ -
+
+ false
+ 4294967295
+ 1
+ 4279970357
+ 1
+ rbxasset://textures/healthgui/BarRed.png
+ barRed
+
+ 0.0189999994
+ 0
+ 0.100000001
+ 0
+
+
+ 0
+ 0
+ 0
+ 0
+
+ 0
+ true
+ 1
+ true
+
+
+ -
+
+ false
+ 4294967295
+ 1.00000012
+ 4279970357
+ 0
+ bar2
+
+ 0.0189999994
+ 0
+ 0.100000001
+ 0
+
+
+ 0.192000002
+ 0
+ 0.829999983
+ 0
+
+ 0
+ 0
+ true
+ 1
+ true
+
+
-
+
+ false
+
+ Init
+ h = game.Players.LocalPlayer.Character.Humanoid
+tray = script.Parent.Parent
+base = tray.Parent
+local lastHealth = 100
+local lastHealth2 = 100
+local maxWidth = 0.96
+
+function UpdateGUI(health)
+ local width = (health / h.MaxHealth) * maxWidth
+ local height = 0.83
+ local lastX = tray.bar.Position.X.Scale
+ local x = 0.019 + (maxWidth - width)
+ local y = 0.1
+
+ tray.bar.Position = UDim2.new(x,0,y, 0)
+ tray.bar.Size = UDim2.new(width, 0, height, 0)
+ -- If more than 1/4 health, bar = green. Else, bar = red.
+ if( (health / h.MaxHealth) > 0.25 ) then
+ tray.barRed.Size = UDim2.new(0, 0, 0, 0)
+ else
+ tray.barRed.Position = tray.bar.Position
+ tray.barRed.Size = tray.bar.Size
+ tray.bar.Size = UDim2.new(0, 0, 0, 0)
+ end
+
+ if ( (lastHealth - health) > (h.MaxHealth / 10) ) then
+ lastHealth = health
+
+ if h.Health ~= h.MaxHealth then
+ delay(0,function()
+ AnimateHurtOverlay()
+ end)
+ delay(0,function()
+ AnimateBars(x, y, lastX, height)
+ end)
+ end
+ else
+ lastHealth = health
+ end
+end
+
+function AnimateBars(x, y, lastX, height)
+ local width = math.abs(x - lastX)
+ if( x > lastX ) then
+ x = lastX
+ end
+ tray.bar2.Position = UDim2.new(x,0, y, 0)
+ tray.bar2.Size = UDim2.new(width, 0, height, 0)
+ tray.bar2.BackgroundTransparency = 0
+ local GBchannels = 1
+ local j = 0.2
+
+ local i_total = 30
+ for i=1,i_total do
+ -- Increment Values
+ if (GBchannels < 0.2) then
+ j = -j
+ end
+ GBchannels = GBchannels + j
+ if (i > (i_total - 10)) then
+ tray.bar2.BackgroundTransparency = tray.bar2.BackgroundTransparency + 0.1
+ end
+ tray.bar2.BackgroundColor3 = Color3.new(1, GBchannels, GBchannels)
+
+ wait(0.02)
+ end
+end
+
+function AnimateHurtOverlay()
+ -- Start:
+ -- overlay.Position = UDim2.new(0, 0, 0, -22)
+ -- overlay.Size = UDim2.new(1, 0, 1.15, 30)
+
+ -- Finish:
+ -- overlay.Position = UDim2.new(-2, 0, -2, -22)
+ -- overlay.Size = UDim2.new(4.5, 0, 4.65, 30)
+
+ overlay = base.hurtOverlay
+ overlay.Visible = true
+ overlay.Position = UDim2.new(-2, 0, -2, -22)
+ overlay.Size = UDim2.new(4.5, 0, 4.65, 30)
+ -- Animate In, fast
+ local i_total = 2
+ local wiggle_total = 0
+ local wiggle_i = 0.02
+ for i=1,i_total do
+ overlay.Position = UDim2.new( (-2 + (2 * (i/i_total)) + wiggle_total/2), 0, (-2 + (2 * (i/i_total)) + wiggle_total/2), -22 )
+ overlay.Size = UDim2.new( (4.5 - (3.5 * (i/i_total)) + wiggle_total), 0, (4.65 - (3.5 * (i/i_total)) + wiggle_total), 30 )
+ wait(0.01)
+ end
+
+ i_total = 30
+
+ wait(0.03)
+
+ -- Animate Out, slow
+ for i=1,i_total do
+ if( math.abs(wiggle_total) > (wiggle_i * 3) ) then
+ wiggle_i = -wiggle_i
+ end
+ wiggle_total = wiggle_total + wiggle_i
+ overlay.Position = UDim2.new( (0 - (2 * (i/i_total)) + wiggle_total/2), 0, (0 - (2 * (i/i_total)) + wiggle_total/2), -22 )
+ overlay.Size = UDim2.new( (1 + (3.5 * (i/i_total)) + wiggle_total), 0, (1.15 + (3.5 * (i/i_total)) + wiggle_total), 30 )
+ wait(0.01)
+ end
+
+ -- Hide after we're done
+ overlay.Position = UDim2.new(10, 0, 0, 0)
+ overlay.Visible = false
+end
+
+h.Changed:connect(function()
+ UpdateGUI(h.Health)
+ if ( (lastHealth2 - h.Health) > (h.MaxHealth / 10) ) then
+ lastHealth2 = h.Health
+ else
+ lastHealth2 = h.Health
+ end end)
+ true
+
+
+
+ -
+
+ false
+ 4294967295
+ 1
+ 4279970357
+ 1
+ rbxasset://textures/healthgui/Bar.png
+ bar
+
+ 0.0189999994
+ 0
+ 0.100000001
+ 0
+
+
+ 0.959999979
+ 0
+ 0.829999983
+ 0
+
+ 0
+ true
+ 1
+ true
+
+
+ -
+
+ false
+ 4294967295
+ 1
+ 4279970357
+ 0
+ rbxasset://textures/healthgui/label.png
+ label
+
+ 0.680000007
+ 0
+ 0.300000012
+ 0
+
+
+ 0.25
+ 0
+ 0.349999994
+ 0
+
+ 0
+ true
+ 1
+ true
+
+
+
+ -
+
+ false
+ 4290164919
+ 1
+ 4279970357
+ 1
+ rbxasset://textures/healthgui/HurtOverlay.png
+ hurtOverlay
+
+ 2
+ 0
+ 0
+ -22
+
+
+ 1
+ 0
+ 1.1500001
+ 30
+
+ 0
+ false
+ 1
+ true
+
+
+ -
+
+ false
+
+ Hide
+ while true do
+ game.Players.LocalPlayer.PlayerGui.HealthGUI.tray.Visible = false
+ game.Players.LocalPlayer.PlayerGui.HealthGUI.hurtOverlay.Visible = false
+end
+ true
+
+
+
+ -
+
+ Dialogs
+ true
+
+
-
+
+ false
+ 4288914085
+ 1
+ 4279970357
+ 1
+ ControlFrame
+
+ 0
+ 0
+ 0
+ 0
+
+
+ 1
+ 0
+ 1
+ 0
+
+ 0
+ 0
+ true
+ 1
+ true
+
+
-
+
+ false
+ 4288914085
+ 1
+ 4279970357
+ 1
+ BottomLeftControl
+
+ 0
+ 0
+ 1
+ -46
+
+
+ 0
+ 130
+ 0
+ 46
+
+ 0
+ 0
+ true
+ 1
+ true
+
+
+ -
+
+ false
+ 4288914085
+ 1
+ 4279970357
+ 1
+ NotificationBox
+
+ 1
+ -200
+ 0.5
+ 0
+
+
+ 0
+ 200
+ 0.419999987
+ 0
+
+ 0
+ true
+ 1
+ true
+
+
+
+ -
false
Init
- --rbxsig%bMgJMPt2chG7JIOhV0y5so/4dL1lRGiT3ELG0LsKh4QrqkG8sRdndraomuViGbDkVOWLXwIilzkhlSJSCjgZ9zXp6fS+SekW/n/RVWjNLA/gPThKLVxP6HmHRK9WTzIQ4ZTXjBmaExcdxBb1remqDPHWHlO2QoxZBqHs5sDGlQI=%
---rbxassetid%48488235%
---rbxsig%NGgzAS16V87kRv1YSTnTXts2fZjkDnnBr6KQq6h00V6iAQ8ZzNuc8zVRUQM/7krGgX+IJGvOqwZDpx1SiZICdYGcC6hhL0znChB4Stf54czFbYfp8ZY9k46+XGAFZtXYXuTLmIushHX/mDwEknP1qY16rTWjm/8J9o3nGx14W78=%
---rbxassetid%45284430%
+ --rbxsig%XeVmMtUuu+dXh8pEbcaTkr2m9RJZXY42LaACJ12YYcuPtOUxy4Azi8uMDGU8ZTh7cvZC9BlOWgqmZHKjESSdfOZl0/cgd2JKHPZ2UqiqA1slJa7R5GtCcGXlNPHW8KDYgJGRuwe8h5CSiMDOl6QLTSEegTOG7fzHk/n1AFcRN8I=%
+--rbxassetid%39250920%
--fixed by Carrot#0559
+
+function waitForProperty(instance, name)
+ while not instance[name] do
+ instance.Changed:wait()
+ end
+end
+
+local beter = game.Lighting
+
+function waitForDialogChildrenMyLord(beter, name)
+ while not beter:FindFirstChild(name) do
+ beter.ChildAdded:wait()
+ end
+end
+
+local bois = game.Players.LocalPlayer.PlayerGui
+
+function waitForFaker(bois, name)
+ while not bois:FindFirstChild(name) do
+ bois.ChildAdded:wait()
+ end
+end
+
+
+local mainFrame
+local choices = {}
+local lastChoice
+local choiceMap = {}
+local currentConversationDialog
+local currentConversationPartner
+local currentAbortDialogScript
+
+local tooFarAwayMessage = "You are too far away to chat!"
+local tooFarAwaySize = 300
+local characterWanderedOffMessage = "Chat ended because you walked away"
+local characterWanderedOffSize = 350
+local conversationTimedOut = "Chat ended because you didn't reply"
+local conversationTimedOutSize = 350
+
+local player
+local screenGui
+local chatNotificationGui
+local messageDialog
+local timeoutScript = game.Lighting.ReenableDialogScript
+local reenableDialogScript = game.Lighting.TimeoutScript
+local dialogMap = {}
+local dialogConnections = {}
+
+local gui = nil
+--waitForDialogChildrenMyLord(game,"CoreGui")
+--waitForDialogChildrenMyLord(game.CoreGui,"RobloxGui")
+--if game.CoreGui.RobloxGui:FindFirstChild("ControlFrame") then
+-- gui = game.CoreGui.RobloxGui.ControlFrame
+--else
+-- gui = game.CoreGui.RobloxGui
+--end
+
+function currentTone()
+ if currentConversationDialog then
+ return currentConversationDialog.Tone
+ else
+ return Enum.DialogTone.Neutral
+ end
+end
+
+
+function createChatNotificationGui()
+ chatNotificationGui = Instance.new("BillboardGui")
+ chatNotificationGui.Name = "ChatNotificationGui"
+ chatNotificationGui.ExtentsOffset = Vector3.new(0,1,0)
+ chatNotificationGui.Size = UDim2.new(4, 0, 5.42857122, 0)
+ chatNotificationGui.SizeOffset = Vector2.new(0,0)
+ chatNotificationGui.StudsOffset = Vector3.new(0.4, 4.3, 0)
+ chatNotificationGui.Enabled = true
+ chatNotificationGui.Active = true
+
+ local image = Instance.new("ImageLabel")
+ image.Name = "Image"
+ image.Active = false
+ image.BackgroundTransparency = 1
+ image.Position = UDim2.new(0,0,0,0)
+ image.Size = UDim2.new(1.0,0,1.0,0)
+ image.Image = ""
+ image.Parent = chatNotificationGui
+
+
+ local button = Instance.new("ImageButton")
+ button.Name = "Button"
+ button.AutoButtonColor = false
+ button.Position = UDim2.new(0.0879999995, 0, 0.0529999994, 0)
+ button.Size = UDim2.new(0.829999983, 0, 0.460000008, 0)
+ button.Image = ""
+ button.BackgroundTransparency = 1
+ button.Parent = image
+end
+
+function getChatColor(tone)
+ if tone == Enum.DialogTone.Neutral then
+ return Enum.ChatColor.Blue
+ elseif tone == Enum.DialogTone.Friendly then
+ return Enum.ChatColor.Green
+ elseif tone == Enum.DialogTone.Enemy then
+ return Enum.ChatColor.Red
+ end
+end
+
+function styleChoices(tone)
+ for i, obj in pairs(choices) do
+ resetColor(obj, tone)
+ end
+ resetColor(lastChoice, tone)
+end
+
+function styleMainFrame(tone)
+ if tone == Enum.DialogTone.Neutral then
+ mainFrame.Style = Enum.FrameStyle.ChatBlue
+ mainFrame.Tail.Image = "rbxasset://textures/chatBubble_botBlue_tailRight.png"
+ elseif tone == Enum.DialogTone.Friendly then
+ mainFrame.Style = Enum.FrameStyle.ChatGreen
+ mainFrame.Tail.Image = "rbxasset://textures/chatBubble_botGreen_tailRight.png"
+ elseif tone == Enum.DialogTone.Enemy then
+ mainFrame.Style = Enum.FrameStyle.ChatRed
+ mainFrame.Tail.Image = "rbxasset://textures/chatBubble_botRed_tailRight.png"
+ end
+
+ styleChoices(tone)
+end
+function setChatNotificationTone(gui, purpose, tone)
+ if tone == Enum.DialogTone.Neutral then
+ gui.Image.Image = "rbxasset://textures/chatBubble_botBlue_notify_bkg.png"
+ elseif tone == Enum.DialogTone.Friendly then
+ gui.Image.Image = "rbxasset://textures/chatBubble_botGreen_notify_bkg.png"
+ elseif tone == Enum.DialogTone.Enemy then
+ gui.Image.Image = "rbxasset://textures/chatBubble_botRed_notify_bkg.png"
+ end
+ if purpose == Enum.DialogPurpose.Quest then
+ gui.Image.Button.Image = "rbxasset://textures/chatBubble_bot_notify_bang.png"
+ elseif purpose == Enum.DialogPurpose.Help then
+ gui.Image.Button.Image = "rbxasset://textures/chatBubble_bot_notify_question.png"
+ elseif purpose == Enum.DialogPurpose.Shop then
+ gui.Image.Button.Image = "rbxasset://textures/chatBubble_bot_notify_money.png"
+ end
+end
+
+function createMessageDialog()
+ messageDialog = Instance.new("Frame");
+ messageDialog.Name = "DialogScriptMessage"
+ messageDialog.Style = Enum.FrameStyle.RobloxRound
+ messageDialog.Visible = false
+
+ local text = Instance.new("TextLabel")
+ text.Name = "Text"
+ text.Position = UDim2.new(0,0,0,-1)
+ text.Size = UDim2.new(1,0,1,0)
+ text.FontSize = Enum.FontSize.Size14
+ text.BackgroundTransparency = 1
+ text.TextColor3 = Color3.new(1,1,1)
+ text.Parent = messageDialog
+end
+
+function showMessage(msg, size)
+ messageDialog.Text.Text = msg
+ messageDialog.Size = UDim2.new(0,size,0,40)
+ messageDialog.Position = UDim2.new(0.5, -size/2, 0.5, -40)
+ messageDialog.Visible = true
+ wait(2)
+ messageDialog.Visible = false
+end
+
+function variableDelay(str)
+ local length = math.min(string.len(str), 100)
+ wait(0.75 + ((length/75) * 1.5))
+end
+
+function resetColor(frame, tone)
+ if tone == Enum.DialogTone.Neutral then
+ frame.BackgroundColor3 = Color3.new(0/255, 0/255, 179/255)
+ frame.Number.TextColor3 = Color3.new(45/255, 142/255, 245/255)
+ elseif tone == Enum.DialogTone.Friendly then
+ frame.BackgroundColor3 = Color3.new(0/255, 77/255, 0/255)
+ frame.Number.TextColor3 = Color3.new(0/255, 190/255, 0/255)
+ elseif tone == Enum.DialogTone.Enemy then
+ frame.BackgroundColor3 = Color3.new(140/255, 0/255, 0/255)
+ frame.Number.TextColor3 = Color3.new(255/255,88/255, 79/255)
+ end
+end
+
+function highlightColor(frame, tone)
+ if tone == Enum.DialogTone.Neutral then
+ frame.BackgroundColor3 = Color3.new(2/255, 108/255, 255/255)
+ frame.Number.TextColor3 = Color3.new(1, 1, 1)
+ elseif tone == Enum.DialogTone.Friendly then
+ frame.BackgroundColor3 = Color3.new(0/255, 128/255, 0/255)
+ frame.Number.TextColor3 = Color3.new(1, 1, 1)
+ elseif tone == Enum.DialogTone.Enemy then
+ frame.BackgroundColor3 = Color3.new(204/255, 0/255, 0/255)
+ frame.Number.TextColor3 = Color3.new(1, 1, 1)
+ end
+end
+
+function wanderDialog()
+ print("Wander")
+ mainFrame.Visible = false
+ endDialog()
+ showMessage(characterWanderedOffMessage, characterWanderedOffSize)
+end
+
+function timeoutDialog()
+ print("Timeout")
+ mainFrame.Visible = false
+ endDialog()
+ showMessage(conversationTimedOut, conversationTimedOutSize)
+end
+function normalEndDialog()
+ print("Done")
+ endDialog()
+end
+
+function endDialog()
+ if currentAbortDialogScript then
+ currentAbortDialogScript:Remove()
+ currentAbortDialogScript = nil
+ end
+
+ local dialog = currentConversationDialog
+ currentConversationDialog = nil
+ if dialog and dialog.InUse then
+ local reenableScript = reenableDialogScript:Clone()
+ reenableScript.archivable = false
+ reenableScript.Disabled = false
+ reenableScript.Parent = dialog
+ end
+
+ for dialog, gui in pairs(dialogMap) do
+ if dialog and gui then
+ gui.Enabled = not dialog.InUse
+ end
+ end
+
+ currentConversationPartner = nil
+end
+
+function sanitizeMessage(msg)
+ if string.len(msg) == 0 then
+ return "..."
+ else
+ return msg
+ end
+end
+
+function selectChoice(choice)
+ renewKillswitch(currentConversationDialog)
+
+ --First hide the Gui
+ mainFrame.Visible = false
+ if choice == lastChoice then
+ game.Chat:Chat(game.Players.LocalPlayer.Character, "Goodbye!", getChatColor(currentTone()))
+
+ normalEndDialog()
+ else
+ local dialogChoice = choiceMap[choice]
+
+ game.Chat:Chat(game.Players.LocalPlayer.Character, sanitizeMessage(dialogChoice.UserDialog), getChatColor(currentTone()))
+ wait(1)
+ --currentConversationDialog:SignalDialogChoiceSelected(player, dialogChoice)
+ game.Chat:Chat(currentConversationPartner, sanitizeMessage(dialogChoice.ResponseDialog), getChatColor(currentTone()))
+
+ variableDelay(dialogChoice.ResponseDialog)
+ presentDialogChoices(currentConversationPartner, dialogChoice:GetChildren())
+ end
+end
+
+function newChoice(numberText)
+ local frame = Instance.new("TextButton")
+ frame.BackgroundColor3 = Color3.new(0/255, 0/255, 179/255)
+ frame.AutoButtonColor = false
+ frame.BorderSizePixel = 0
+ frame.Text = ""
+ frame.MouseEnter:connect(function() highlightColor(frame, currentTone()) end)
+ frame.MouseLeave:connect(function() resetColor(frame, currentTone()) end)
+ frame.MouseButton1Click:connect(function() selectChoice(frame) end)
+
+ local number = Instance.new("TextLabel")
+ number.Name = "Number"
+ number.TextColor3 = Color3.new(127/255, 212/255, 255/255)
+ number.Text = numberText
+ number.FontSize = Enum.FontSize.Size14
+ number.BackgroundTransparency = 1
+ number.Position = UDim2.new(0,4,0,2)
+ number.Size = UDim2.new(0,20,0,24)
+ number.TextXAlignment = Enum.TextXAlignment.Left
+ number.TextYAlignment = Enum.TextYAlignment.Top
+ number.Parent = frame
+
+ local prompt = Instance.new("TextLabel")
+ prompt.Name = "UserPrompt"
+ prompt.BackgroundTransparency = 1
+ prompt.TextColor3 = Color3.new(1,1,1)
+ prompt.FontSize = Enum.FontSize.Size14
+ prompt.Position = UDim2.new(0,28, 0, 2)
+ prompt.Size = UDim2.new(1,-32, 1, -4)
+ prompt.TextXAlignment = Enum.TextXAlignment.Left
+ prompt.TextYAlignment = Enum.TextYAlignment.Top
+ prompt.TextWrap = true
+ prompt.Parent = frame
+
+ return frame
+end
+function initialize(parent)
+ choices[1] = newChoice("1)")
+ choices[2] = newChoice("2)")
+ choices[3] = newChoice("3)")
+ choices[4] = newChoice("4)")
+
+ lastChoice = newChoice("5)")
+ lastChoice.UserPrompt.Text = "Goodbye!"
+ lastChoice.Size = UDim2.new(1,0,0,28)
+
+ mainFrame = Instance.new("Frame")
+ mainFrame.Name = "UserDialogArea"
+ mainFrame.Size = UDim2.new(0, 350, 0, 200)
+ mainFrame.Style = Enum.FrameStyle.ChatBlue
+ mainFrame.Visible = false
+
+ local imageLabel = Instance.new("ImageLabel")
+ imageLabel.Name = "Tail"
+ imageLabel.Size = UDim2.new(0,62,0,53)
+ imageLabel.Position = UDim2.new(1,8,0.25)
+ imageLabel.Image = "rbxasset://textures/chatBubble_botBlue_tailRight.png"
+ imageLabel.BackgroundTransparency = 1
+ imageLabel.Parent = mainFrame
+
+ for n, obj in pairs(choices) do
+ obj.Parent = mainFrame
+ end
+ lastChoice.Parent = mainFrame
+
+ mainFrame.Parent = parent
+end
+
+function presentDialogChoices(talkingPart, dialogChoices)
+ if not currentConversationDialog then
+ return
+ end
+
+ currentConversationPartner = talkingPart
+ local sortedDialogChoices = {}
+ for n, obj in pairs(dialogChoices) do
+ if obj:IsA("DialogChoice") then
+ table.insert(sortedDialogChoices, obj)
+ end
+ end
+ table.sort(sortedDialogChoices, function(a,b) return a.Name < b.Name end)
+
+ if #sortedDialogChoices == 0 then
+ normalEndDialog()
+ return
+ end
+
+ local pos = 1
+ local yPosition = 0
+ choiceMap = {}
+ for n, obj in pairs(choices) do
+ obj.Visible = false
+ end
+
+ for n, obj in pairs(sortedDialogChoices) do
+ if pos <= #choices then
+ --3 lines is the maximum, set it to that temporarily
+ choices[pos].Size = UDim2.new(1, 0, 0, 24*3)
+ choices[pos].UserPrompt.Text = obj.UserDialog
+ local height = math.ceil(choices[pos].UserPrompt.TextBounds.Y/24)*24
+
+ choices[pos].Position = UDim2.new(0, 0, 0, yPosition)
+ choices[pos].Size = UDim2.new(1, 0, 0, height)
+ choices[pos].Visible = true
+
+ choiceMap[choices[pos]] = obj
+
+ yPosition = yPosition + height
+ pos = pos + 1
+ end
+ end
+
+ lastChoice.Position = UDim2.new(0,0,0,yPosition)
+ lastChoice.Number.Text = pos .. ")"
+
+ mainFrame.Size = UDim2.new(0, 350, 0, yPosition+24+32)
+ mainFrame.Position = UDim2.new(0,20,0.0, -mainFrame.Size.Y.Offset-20)
+ styleMainFrame(currentTone())
+ mainFrame.Visible = true
+end
+
+function doDialog(dialog)
+ while not Instance.Lock(dialog, player) do
+ wait()
+ end
+
+ if dialog.InUse then
+ Instance.Unlock(dialog)
+ return
+ else
+ dialog.InUse = true
+ Instance.Unlock(dialog)
+ end
+
+ currentConversationDialog = dialog
+ game.Chat:Chat(dialog.Parent, dialog.InitialPrompt, getChatColor(dialog.Tone))
+ variableDelay(dialog.InitialPrompt)
+
+ presentDialogChoices(dialog.Parent, dialog:GetChildren())
+end
+
+function renewKillswitch(dialog)
+ if currentAbortDialogScript then
+ currentAbortDialogScript:Remove()
+ currentAbortDialogScript = nil
+ end
+
+ currentAbortDialogScript = timeoutScript:Clone()
+ currentAbortDialogScript.archivable = false
+ currentAbortDialogScript.Disabled = false
+ currentAbortDialogScript.Parent = dialog
+end
+
+function checkForLeaveArea()
+ while currentConversationDialog do
+ if currentConversationDialog.Parent and (player:DistanceFromCharacter(currentConversationDialog.Parent.Position) >= currentConversationDialog.ConversationDistance) then
+ wanderDialog()
+ end
+ wait(1)
+ end
+end
+
+function startDialog(dialog)
+ if dialog.Parent and dialog.Parent:IsA("BasePart") then
+ if player:DistanceFromCharacter(dialog.Parent.Position) >= dialog.ConversationDistance then
+ showMessage(tooFarAwayMessage, tooFarAwaySize)
+ return
+ end
+
+ for dialog, gui in pairs(dialogMap) do
+ if dialog and gui then
+ gui.Enabled = false
+ end
+ end
+
+ renewKillswitch(dialog)
+
+ delay(1, checkForLeaveArea)
+ doDialog(dialog)
+ end
+end
+
+function removeDialog(dialog)
+ if dialogMap[dialog] then
+ dialogMap[dialog]:Remove()
+ dialogMap[dialog] = nil
+ end
+ if dialogConnections[dialog] then
+ dialogConnections[dialog]:disconnect()
+ dialogConnections[dialog] = nil
+ end
+end
+
+function addDialog(dialog)
+ if dialog.Parent then
+ if dialog.Parent:IsA("BasePart") then
+ local chatGui = chatNotificationGui:clone()
+ chatGui.Enabled = not dialog.InUse
+ chatGui.Adornee = dialog.Parent
+ chatGui.Parent = game.Players.LocalPlayer.PlayerGui
+ chatGui.Image.Button.MouseButton1Click:connect(function() startDialog(dialog) end)
+ setChatNotificationTone(chatGui, dialog.Purpose, dialog.Tone)
+
+ dialogMap[dialog] = chatGui
+
+ dialogConnections[dialog] = dialog.Changed:connect(function(prop)
+ if prop == "Parent" and dialog.Parent then
+ --This handles the reparenting case, seperate from removal case
+ removeDialog(dialog)
+ addDialog(dialog)
+ elseif prop == "InUse" then
+ chatGui.Enabled = not currentConversationDialog and not dialog.InUse
+ if dialog == currentConversationDialog then
+ timeoutDialog()
+ end
+ elseif prop == "Tone" or prop == "Purpose" then
+ setChatNotificationTone(chatGui, dialog.Purpose, dialog.Tone)
+ end
+ end)
+ else -- still need to listen to parent changes even if current parent is not a BasePart
+ dialogConnections[dialog] = dialog.Changed:connect(function(prop)
+ if prop == "Parent" and dialog.Parent then
+ --This handles the reparenting case, seperate from removal case
+ removeDialog(dialog)
+ addDialog(dialog)
+ end
+ end)
+ end
+ end
+end
+
+
+--[[function fetchScripts()
+ local model = game:GetService("InsertService"):LoadAsset(39226062)
+ if type(model) == "string" then -- load failed, lets try again
+ wait(0.1)
+ model = game:GetService("InsertService"):LoadAsset(39226062)
+ end
+ if type(model) == "string" then -- not going to work, lets bail
+ return
+ end
+
+ waitForDialogChildrenMyLord(model,"TimeoutScript")
+ timeoutScript = model.TimeoutScript
+ waitForDialogChildrenMyLord(model,"ReenableDialogScript")
+ reenableDialogScript = model.ReenableDialogScript
+end
+]]--
+
+function onLoad()
+ waitForProperty(game.Players, "LocalPlayer")
+ player = game.Players.LocalPlayer
+ waitForProperty(player, "Character")
+
+ --print("Fetching Scripts")
+ --fetchScripts()
+
+ --print("Creating Guis")
+ createChatNotificationGui()
+
+ waitForFaker(bois,"Dialogs")
+ --print("Creating MessageDialog")
+ createMessageDialog()
+ messageDialog.Parent = game.Players.LocalPlayer.PlayerGui.Dialogs
+
+
+ --print("Initializing Frame")
+ local frame = Instance.new("Frame")
+ frame.Name = "DialogFrame"
+ frame.Position = UDim2.new(0,0,0,0)
+ frame.Size = UDim2.new(0,0,0,0)
+ frame.BackgroundTransparency = 1
+ frame.Parent = game.Players.LocalPlayer.PlayerGui.Dialogs.ControlFrame.BottomLeftControl
+ initialize(frame)
+
+ --print("Adding Dialogs")
+ game.CollectionService.ItemAdded:connect(function(obj) if obj:IsA("Dialog") then addDialog(obj) end end)
+ game.CollectionService.ItemRemoved:connect(function(obj) if obj:IsA("Dialog") then removeDialog(obj) end end)
+ for i, obj in pairs(game.CollectionService:GetCollection("Dialog")) do
+ if obj:IsA("Dialog") then
+ addDialog(obj)
+ end
+ end
+end
+
+onLoad()
+ true
+
+
+
+ -
+
+ Playerlist
+ true
+
+
-
+
+ false
+
+ Init
+ --fixed by Carrot#0559
--for non corescript use
---rbxsig%IEUAo3Q1k4Rwb3ZcqPBum//j3+Jm/9Nv0JyCeCRWUrggWps7aG81/aPzlH9pPlMkkdsZwLsCRu6eTTrqzXn2DAJNPRs7y8akc3z91r1DP3jwomfpdT+2DBAmPk3Cdj8NXQzP6T+uEYm2kk2TW9pXonKvCgRVqXFx8J7mTr+aM1M=%
---rbxassetid%45284430%
local t = {}
local function ScopedConnect(parentInstance, instance, event, signalFunc, syncFunc, removeFunc)
@@ -4640,20 +5680,6 @@ local function rebuildBoard(owner, boardType, numStats)
end
function recalculateSmallPlayerListSize(smallPlayerList)
- waitForChild(smallPlayerList,"ScrollingArea")
- waitForChild(smallPlayerList.ScrollingArea, "ScrollingFrame")
- local scrollingFrame = smallPlayerList.ScrollingArea.ScrollingFrame
- local playerLines = scrollingFrame:GetChildren()
-
- local totalPlayerListSize = 0
- for i = 1, #playerLines do
- totalPlayerListSize = totalPlayerListSize + playerLines[i].AbsoluteSize.Y
- end
-
- if not smallPlayerList.Parent then return end
-
- local yOffset = math.max(0,(smallPlayerList.Size.Y.Scale * smallPlayerList.Parent.AbsoluteSize.Y) - totalPlayerListSize - smallWindowHeaderYSize)
- smallPlayerList.Size = UDim2.new(smallPlayerList.Size.X.Scale,smallPlayerList.Size.X.Offset,smallPlayerList.Size.Y.Scale,-yOffset)
end
@@ -6209,1200 +7235,10 @@ else
setupBuildToolManagement()
end
end)
-end
-
-
----------------------------------- Start Player Hover Code ----------------------------------------
-if contextMenu3d then
- local inMenu = false
-
- function waitForProperty(instance, name)
- while not instance[name] do
- instance.Changed:wait()
- end
- end
-
- function makeNewActionButton()
- local button = Instance.new("TextButton")
- button.Name = "ActionButton"
- button.Style = Enum.ButtonStyle.RobloxButtonDefault
- button.BackgroundColor3 = Color3.new(0,0,0)
- button.BorderColor3 = Color3.new(1,0,0)
- button.BackgroundTransparency = 0.5
- button.Size = UDim2.new(1,0,0,50)
- button.Text = ""
- button.Font = Enum.Font.ArialBold
- button.FontSize = Enum.FontSize.Size18
- button.TextColor3 = Color3.new(1,1,1)
- button.ZIndex = 4
- return button
- end
-
- function getContextElements(currentContextMenuPlayer)
- local elements = {}
- for i, contextElement in ipairs(contextMenuElements) do
- local element = contextElement
-
- local isVisible = false
-
- if contextElement.IsVisible then
- local success, visible = pcall(function() return contextElement.IsVisible(currentContextMenuPlayer) end)
- if success then
- isVisible = visible
- else
- print("Error in IsVisible call: " .. visible)
- end
- end
-
- if element.Type == "Button" then
- local button = makeNewActionButton()
- button.Name = "ContextButton" .. i
- button.Visible = isVisible
- button.Text = contextElement.Text
- button.MouseButton1Click:connect(function()
- if button.Active then
- local success, result = pcall(function() element.DoIt(currentContextMenuPlayer) end)
- end
- end)
-
- contextElement.Button = button
- contextElement.Element = button
-
- table.insert(elements,contextElement)
- end
- end
-
- return elements
- end
-
- function findContextElement(contextElements, button)
- for i = 1, #contextElements do
- if contextElements[i].Button == button then
- return contextElements[i]
- end
- end
- end
-
- function populateActions(scrollFrame, nullFrame, recalcFunction, otherPlayer)
- local elements = getContextElements(otherPlayer)
- for i = 1, #elements do
- if elements[i].Button.Visible then
- elements[i].Button.Parent = scrollFrame
- else
- elements[i].Button.Parent = nullFrame
- end
-
- local actionButtonCon
- actionButtonCon = elements[i].Button.MouseButton1Click:connect(function()
- actionButtonCon:disconnect()
-
- local nullFrameChildren = nullFrame:GetChildren()
- for j = 1, #nullFrameChildren do
- local contextElement = findContextElement(elements, nullFrameChildren[j])
- pcall(function() nullFrameChildren[j].Visible = contextElement.IsVisible(otherPlayer) end)
- if nullFrameChildren[j].Visible then
- nullFrameChildren[j].Parent = scrollFrame
- end
- end
-
- local scrollFrameChildren = scrollFrame:GetChildren()
- for j = 1, #scrollFrameChildren do
- local contextElement = findContextElement(elements, scrollFrameChildren[j])
- pcall(function() scrollFrameChildren[j].Visible = contextElement.IsVisible(otherPlayer) end)
- if not scrollFrameChildren[j].Visible then
- scrollFrameChildren[j].Parent = nullFrame
- end
- end
-
- elements[i].Button.Parent = nullFrame
- recalcFunction()
- end)
- end
- end
-
-
- function createContextMenu(otherPlayer)
-
- local frame = Instance.new("Frame")
- frame.Name = "ContextMenuFrame"
- frame.Style = Enum.FrameStyle.RobloxRound
- frame.Size = UDim2.new(0,300,0,400)
- frame.Position = UDim2.new(0.5,-150,0.5,-200)
- frame.ZIndex = 2
-
- local scrollFrame, scrollUpButton, scrollDownButton, recalc, scrollBar = RbxGui.CreateScrollingFrame()
-
- scrollFrame.Name = "Actions"
- scrollFrame.BackgroundTransparency = 1
- scrollFrame.Position = UDim2.new(0,0,0,25)
- scrollFrame.Size = UDim2.new(1,-20,1,-80)
- scrollFrame.ZIndex = 3
- scrollFrame.Parent = frame
-
- local nullFrame = Instance.new("Frame")
- nullFrame.Name = "NullFrame"
- nullFrame.BackgroundTransparency = 1
- nullFrame.Visible = false
- nullFrame.Parent = frame
-
- local scrollButtons = Instance.new("Frame")
- scrollButtons.Name = "ScrollButtons"
- scrollButtons.BackgroundTransparency = 1
- scrollButtons.Position = UDim2.new(1,-17,0,25)
- scrollButtons.Size = UDim2.new(0,17,1,-80)
- scrollButtons.ZIndex = 3
- scrollButtons.Parent = frame
-
- scrollUpButton.ZIndex = 3
- scrollUpButton.Parent = scrollButtons
- scrollDownButton.Position = UDim2.new(0,0,1,-17)
- scrollDownButton.ZIndex = 3
- scrollDownButton.Parent = scrollButtons
-
- scrollBar.Size = UDim2.new(1,0,1,-34)
- scrollBar.Position = UDim2.new(0,0,0,17)
- scrollBar.Parent = scrollButtons
-
- local playerImage = Instance.new("ImageLabel")
- playerImage.Name = "PlayerImage"
- playerImage.BackgroundTransparency = 1
- playerImage.Image = "http://www.roblox.com/thumbs/avatar.ashx?userId=" .. tostring(otherPlayer.userId) .. "&x=352&y=352"
- playerImage.Position = UDim2.new(0.5,-150,0.5,-150)
- playerImage.Size = UDim2.new(0,300,0,300)
- playerImage.Parent = frame
-
- local playerName = Instance.new("TextLabel")
- playerName.Name = "PlayerName"
- playerName.BackgroundTransparency = 1
- playerName.Font = Enum.Font.ArialBold
- playerName.FontSize = Enum.FontSize.Size24
- playerName.Position = UDim2.new(0,-8,0,-6)
- playerName.Size = UDim2.new(1,16,0,24)
- playerName.Text = otherPlayer["Name"]
- playerName.TextColor3 = Color3.new(1,1,1)
- playerName.TextWrap = true
- playerName.ZIndex = 3
- playerName.Parent = frame
-
- local doneButtonCon
-
- local doneButton = Instance.new("TextButton")
- doneButton.Name = "DoneButton"
- doneButton.Style = Enum.ButtonStyle.RobloxButton
- doneButton.Font = Enum.Font.ArialBold
- doneButton.FontSize = Enum.FontSize.Size36
- doneButton.Position = UDim2.new(0.25,0,1,-50)
- doneButton.Size = UDim2.new(0.5,0,0,50)
- doneButton.Text = "Done"
- doneButton.TextColor3 = Color3.new(1,1,1)
- doneButton.ZIndex = 3
- doneButton.Parent = frame
- doneButton.Modal = true
- doneButtonCon = doneButton.MouseButton1Click:connect(function()
- doneButtonCon:disconnect()
- inMenu = false
- game.GuiService:RemoveCenterDialog(frame)
- frame:remove()
- end)
-
- populateActions(scrollFrame, nullFrame, recalc, otherPlayer)
- recalc()
-
- return frame
- end
-
- function makeContextInvisible(menu)
- menu.Visible = false
- end
-
- function goToContextMenu(otherPlayer)
-
- local menu = createContextMenu(otherPlayer)
-
- game.GuiService:AddCenterDialog(menu, Enum.CenterDialogType.PlayerInitiatedDialog,
- --ShowFunction
- function()
- menu.Visible = true
- menu:TweenSize(UDim2.new(0,300,0,400),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.5,true)
- end,
- --HideFunction
- function()
- menu:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.5,true,function() makeContextInvisible(menu) end)
- end)
- menu.Parent = game.CoreGui.RobloxGui
-
- inMenu = true
- end
-
- waitForProperty(game.Players, "LocalPlayer")
-
- local currSelectedPlayer = nil
- if game.Players.LocalPlayer["HoverOnPlayerChanged"] then
- game.Players.LocalPlayer.HoverOnPlayerChanged:connect(function(otherPlayer)
- if not inMenu then
- if otherPlayer and otherPlayer.userId < 0 then return end -- we don't want this for guests
- end
- wait(0.5)
- currSelectedPlayer = otherPlayer
- end)
- end
-
- if game.Players.LocalPlayer["MouseDownOnPlayer"] then
- game.Players.LocalPlayer.MouseDownOnPlayer:connect(function(otherPlayer)
- if currSelectedPlayer ~= otherPlayer then return end
- if not inMenu and otherPlayer.userId > 0 then
- goToContextMenu(otherPlayer)
- end
- end)
- end
-end
----------------------------------- End Player Hover Code ----------------------------------------
+end
true
- -
-
- false
-
- Dialogs
- --rbxsig%XeVmMtUuu+dXh8pEbcaTkr2m9RJZXY42LaACJ12YYcuPtOUxy4Azi8uMDGU8ZTh7cvZC9BlOWgqmZHKjESSdfOZl0/cgd2JKHPZ2UqiqA1slJa7R5GtCcGXlNPHW8KDYgJGRuwe8h5CSiMDOl6QLTSEegTOG7fzHk/n1AFcRN8I=%
---rbxassetid%39250920%
---fixed by Carrot#0559
-
-function waitForProperty(instance, name)
- while not instance[name] do
- instance.Changed:wait()
- end
-end
-
-local beter = game.Workspace
-
-function waitForDialogChildrenMyLord(beter, name)
- while not beter:FindFirstChild(name) do
- beter.ChildAdded:wait()
- end
-end
-
-
-local mainFrame
-local choices = {}
-local lastChoice
-local choiceMap = {}
-local currentConversationDialog
-local currentConversationPartner
-local currentAbortDialogScript
-
-local tooFarAwayMessage = "You are too far away to chat!"
-local tooFarAwaySize = 300
-local characterWanderedOffMessage = "Chat ended because you walked away"
-local characterWanderedOffSize = 350
-local conversationTimedOut = "Chat ended because you didn't reply"
-local conversationTimedOutSize = 350
-
-local player
-local screenGui
-local chatNotificationGui
-local messageDialog
-local timeoutScript = game.Workspace.ReenableDialogScript
-local reenableDialogScript = game.Workspace.TimeoutScript
-local dialogMap = {}
-local dialogConnections = {}
-
-local gui = nil
---waitForDialogChildrenMyLord(game,"CoreGui")
---waitForDialogChildrenMyLord(game.CoreGui,"RobloxGui")
---if game.CoreGui.RobloxGui:FindFirstChild("ControlFrame") then
--- gui = game.CoreGui.RobloxGui.ControlFrame
---else
--- gui = game.CoreGui.RobloxGui
---end
-
-function currentTone()
- if currentConversationDialog then
- return currentConversationDialog.Tone
- else
- return Enum.DialogTone.Neutral
- end
-end
-
-
-function createChatNotificationGui()
- chatNotificationGui = Instance.new("BillboardGui")
- chatNotificationGui.Name = "ChatNotificationGui"
- chatNotificationGui.ExtentsOffset = Vector3.new(0,1,0)
- chatNotificationGui.Size = UDim2.new(4, 0, 5.42857122, 0)
- chatNotificationGui.SizeOffset = Vector2.new(0,0)
- chatNotificationGui.StudsOffset = Vector3.new(0.4, 4.3, 0)
- chatNotificationGui.Enabled = true
- chatNotificationGui.Active = true
-
- local image = Instance.new("ImageLabel")
- image.Name = "Image"
- image.Active = false
- image.BackgroundTransparency = 1
- image.Position = UDim2.new(0,0,0,0)
- image.Size = UDim2.new(1.0,0,1.0,0)
- image.Image = ""
- image.Parent = chatNotificationGui
-
-
- local button = Instance.new("ImageButton")
- button.Name = "Button"
- button.AutoButtonColor = false
- button.Position = UDim2.new(0.0879999995, 0, 0.0529999994, 0)
- button.Size = UDim2.new(0.829999983, 0, 0.460000008, 0)
- button.Image = ""
- button.BackgroundTransparency = 1
- button.Parent = image
-end
-
-function getChatColor(tone)
- if tone == Enum.DialogTone.Neutral then
- return Enum.ChatColor.Blue
- elseif tone == Enum.DialogTone.Friendly then
- return Enum.ChatColor.Green
- elseif tone == Enum.DialogTone.Enemy then
- return Enum.ChatColor.Red
- end
-end
-
-function styleChoices(tone)
- for i, obj in pairs(choices) do
- resetColor(obj, tone)
- end
- resetColor(lastChoice, tone)
-end
-
-function styleMainFrame(tone)
- if tone == Enum.DialogTone.Neutral then
- mainFrame.Style = Enum.FrameStyle.ChatBlue
- mainFrame.Tail.Image = "rbxasset://textures/chatBubble_botBlue_tailRight.png"
- elseif tone == Enum.DialogTone.Friendly then
- mainFrame.Style = Enum.FrameStyle.ChatGreen
- mainFrame.Tail.Image = "rbxasset://textures/chatBubble_botGreen_tailRight.png"
- elseif tone == Enum.DialogTone.Enemy then
- mainFrame.Style = Enum.FrameStyle.ChatRed
- mainFrame.Tail.Image = "rbxasset://textures/chatBubble_botRed_tailRight.png"
- end
-
- styleChoices(tone)
-end
-function setChatNotificationTone(gui, purpose, tone)
- if tone == Enum.DialogTone.Neutral then
- gui.Image.Image = "rbxasset://textures/chatBubble_botBlue_notify_bkg.png"
- elseif tone == Enum.DialogTone.Friendly then
- gui.Image.Image = "rbxasset://textures/chatBubble_botGreen_notify_bkg.png"
- elseif tone == Enum.DialogTone.Enemy then
- gui.Image.Image = "rbxasset://textures/chatBubble_botRed_notify_bkg.png"
- end
- if purpose == Enum.DialogPurpose.Quest then
- gui.Image.Button.Image = "rbxasset://textures/chatBubble_bot_notify_bang.png"
- elseif purpose == Enum.DialogPurpose.Help then
- gui.Image.Button.Image = "rbxasset://textures/chatBubble_bot_notify_question.png"
- elseif purpose == Enum.DialogPurpose.Shop then
- gui.Image.Button.Image = "rbxasset://textures/chatBubble_bot_notify_money.png"
- end
-end
-
-function createMessageDialog()
- messageDialog = Instance.new("Frame");
- messageDialog.Name = "DialogScriptMessage"
- messageDialog.Style = Enum.FrameStyle.RobloxRound
- messageDialog.Visible = false
-
- local text = Instance.new("TextLabel")
- text.Name = "Text"
- text.Position = UDim2.new(0,0,0,-1)
- text.Size = UDim2.new(1,0,1,0)
- text.FontSize = Enum.FontSize.Size14
- text.BackgroundTransparency = 1
- text.TextColor3 = Color3.new(1,1,1)
- text.Parent = messageDialog
-end
-
-function showMessage(msg, size)
- messageDialog.Text.Text = msg
- messageDialog.Size = UDim2.new(0,size,0,40)
- messageDialog.Position = UDim2.new(0.5, -size/2, 0.5, -40)
- messageDialog.Visible = true
- wait(2)
- messageDialog.Visible = false
-end
-
-function variableDelay(str)
- local length = math.min(string.len(str), 100)
- wait(0.75 + ((length/75) * 1.5))
-end
-
-function resetColor(frame, tone)
- if tone == Enum.DialogTone.Neutral then
- frame.BackgroundColor3 = Color3.new(0/255, 0/255, 179/255)
- frame.Number.TextColor3 = Color3.new(45/255, 142/255, 245/255)
- elseif tone == Enum.DialogTone.Friendly then
- frame.BackgroundColor3 = Color3.new(0/255, 77/255, 0/255)
- frame.Number.TextColor3 = Color3.new(0/255, 190/255, 0/255)
- elseif tone == Enum.DialogTone.Enemy then
- frame.BackgroundColor3 = Color3.new(140/255, 0/255, 0/255)
- frame.Number.TextColor3 = Color3.new(255/255,88/255, 79/255)
- end
-end
-
-function highlightColor(frame, tone)
- if tone == Enum.DialogTone.Neutral then
- frame.BackgroundColor3 = Color3.new(2/255, 108/255, 255/255)
- frame.Number.TextColor3 = Color3.new(1, 1, 1)
- elseif tone == Enum.DialogTone.Friendly then
- frame.BackgroundColor3 = Color3.new(0/255, 128/255, 0/255)
- frame.Number.TextColor3 = Color3.new(1, 1, 1)
- elseif tone == Enum.DialogTone.Enemy then
- frame.BackgroundColor3 = Color3.new(204/255, 0/255, 0/255)
- frame.Number.TextColor3 = Color3.new(1, 1, 1)
- end
-end
-
-function wanderDialog()
- print("Wander")
- mainFrame.Visible = false
- endDialog()
- showMessage(characterWanderedOffMessage, characterWanderedOffSize)
-end
-
-function timeoutDialog()
- print("Timeout")
- mainFrame.Visible = false
- endDialog()
- showMessage(conversationTimedOut, conversationTimedOutSize)
-end
-function normalEndDialog()
- print("Done")
- endDialog()
-end
-
-function endDialog()
- if currentAbortDialogScript then
- currentAbortDialogScript:Remove()
- currentAbortDialogScript = nil
- end
-
- local dialog = currentConversationDialog
- currentConversationDialog = nil
- if dialog and dialog.InUse then
- local reenableScript = reenableDialogScript:Clone()
- reenableScript.archivable = false
- reenableScript.Disabled = false
- reenableScript.Parent = dialog
- end
-
- for dialog, gui in pairs(dialogMap) do
- if dialog and gui then
- gui.Enabled = not dialog.InUse
- end
- end
-
- currentConversationPartner = nil
-end
-
-function sanitizeMessage(msg)
- if string.len(msg) == 0 then
- return "..."
- else
- return msg
- end
-end
-
-function selectChoice(choice)
- renewKillswitch(currentConversationDialog)
-
- --First hide the Gui
- mainFrame.Visible = false
- if choice == lastChoice then
- game.Chat:Chat(game.Players.LocalPlayer.Character, "Goodbye!", getChatColor(currentTone()))
-
- normalEndDialog()
- else
- local dialogChoice = choiceMap[choice]
-
- game.Chat:Chat(game.Players.LocalPlayer.Character, sanitizeMessage(dialogChoice.UserDialog), getChatColor(currentTone()))
- wait(1)
- currentConversationDialog:SignalDialogChoiceSelected(player, dialogChoice)
- game.Chat:Chat(currentConversationPartner, sanitizeMessage(dialogChoice.ResponseDialog), getChatColor(currentTone()))
-
- variableDelay(dialogChoice.ResponseDialog)
- presentDialogChoices(currentConversationPartner, dialogChoice:GetChildren())
- end
-end
-
-function newChoice(numberText)
- local frame = Instance.new("TextButton")
- frame.BackgroundColor3 = Color3.new(0/255, 0/255, 179/255)
- frame.AutoButtonColor = false
- frame.BorderSizePixel = 0
- frame.Text = ""
- frame.MouseEnter:connect(function() highlightColor(frame, currentTone()) end)
- frame.MouseLeave:connect(function() resetColor(frame, currentTone()) end)
- frame.MouseButton1Click:connect(function() selectChoice(frame) end)
-
- local number = Instance.new("TextLabel")
- number.Name = "Number"
- number.TextColor3 = Color3.new(127/255, 212/255, 255/255)
- number.Text = numberText
- number.FontSize = Enum.FontSize.Size14
- number.BackgroundTransparency = 1
- number.Position = UDim2.new(0,4,0,2)
- number.Size = UDim2.new(0,20,0,24)
- number.TextXAlignment = Enum.TextXAlignment.Left
- number.TextYAlignment = Enum.TextYAlignment.Top
- number.Parent = frame
-
- local prompt = Instance.new("TextLabel")
- prompt.Name = "UserPrompt"
- prompt.BackgroundTransparency = 1
- prompt.TextColor3 = Color3.new(1,1,1)
- prompt.FontSize = Enum.FontSize.Size14
- prompt.Position = UDim2.new(0,28, 0, 2)
- prompt.Size = UDim2.new(1,-32, 1, -4)
- prompt.TextXAlignment = Enum.TextXAlignment.Left
- prompt.TextYAlignment = Enum.TextYAlignment.Top
- prompt.TextWrap = true
- prompt.Parent = frame
-
- return frame
-end
-function initialize(parent)
- choices[1] = newChoice("1)")
- choices[2] = newChoice("2)")
- choices[3] = newChoice("3)")
- choices[4] = newChoice("4)")
-
- lastChoice = newChoice("5)")
- lastChoice.UserPrompt.Text = "Goodbye!"
- lastChoice.Size = UDim2.new(1,0,0,28)
-
- mainFrame = Instance.new("Frame")
- mainFrame.Name = "UserDialogArea"
- mainFrame.Size = UDim2.new(0, 350, 0, 200)
- mainFrame.Style = Enum.FrameStyle.ChatBlue
- mainFrame.Visible = false
-
- local imageLabel = Instance.new("ImageLabel")
- imageLabel.Name = "Tail"
- imageLabel.Size = UDim2.new(0,62,0,53)
- imageLabel.Position = UDim2.new(1,8,0.25)
- imageLabel.Image = "rbxasset://textures/chatBubble_botBlue_tailRight.png"
- imageLabel.BackgroundTransparency = 1
- imageLabel.Parent = mainFrame
-
- for n, obj in pairs(choices) do
- obj.Parent = mainFrame
- end
- lastChoice.Parent = mainFrame
-
- mainFrame.Parent = parent
-end
-
-function presentDialogChoices(talkingPart, dialogChoices)
- if not currentConversationDialog then
- return
- end
-
- currentConversationPartner = talkingPart
- local sortedDialogChoices = {}
- for n, obj in pairs(dialogChoices) do
- if obj:IsA("DialogChoice") then
- table.insert(sortedDialogChoices, obj)
- end
- end
- table.sort(sortedDialogChoices, function(a,b) return a.Name < b.Name end)
-
- if #sortedDialogChoices == 0 then
- normalEndDialog()
- return
- end
-
- local pos = 1
- local yPosition = 0
- choiceMap = {}
- for n, obj in pairs(choices) do
- obj.Visible = false
- end
-
- for n, obj in pairs(sortedDialogChoices) do
- if pos <= #choices then
- --3 lines is the maximum, set it to that temporarily
- choices[pos].Size = UDim2.new(1, 0, 0, 24*3)
- choices[pos].UserPrompt.Text = obj.UserDialog
- local height = math.ceil(choices[pos].UserPrompt.TextBounds.Y/24)*24
-
- choices[pos].Position = UDim2.new(0, 0, 0, yPosition)
- choices[pos].Size = UDim2.new(1, 0, 0, height)
- choices[pos].Visible = true
-
- choiceMap[choices[pos]] = obj
-
- yPosition = yPosition + height
- pos = pos + 1
- end
- end
-
- lastChoice.Position = UDim2.new(0,0,0,yPosition)
- lastChoice.Number.Text = pos .. ")"
-
- mainFrame.Size = UDim2.new(0, 350, 0, yPosition+24+32)
- mainFrame.Position = UDim2.new(0,20,0.0, -mainFrame.Size.Y.Offset-20)
- styleMainFrame(currentTone())
- mainFrame.Visible = true
-end
-
-function doDialog(dialog)
- while not Instance.Lock(dialog, player) do
- wait()
- end
-
- if dialog.InUse then
- Instance.Unlock(dialog)
- return
- else
- dialog.InUse = true
- Instance.Unlock(dialog)
- end
-
- currentConversationDialog = dialog
- game.Chat:Chat(dialog.Parent, dialog.InitialPrompt, getChatColor(dialog.Tone))
- variableDelay(dialog.InitialPrompt)
-
- presentDialogChoices(dialog.Parent, dialog:GetChildren())
-end
-
-function renewKillswitch(dialog)
- if currentAbortDialogScript then
- currentAbortDialogScript:Remove()
- currentAbortDialogScript = nil
- end
-
- currentAbortDialogScript = timeoutScript:Clone()
- currentAbortDialogScript.archivable = false
- currentAbortDialogScript.Disabled = false
- currentAbortDialogScript.Parent = dialog
-end
-
-function checkForLeaveArea()
- while currentConversationDialog do
- if currentConversationDialog.Parent and (player:DistanceFromCharacter(currentConversationDialog.Parent.Position) >= currentConversationDialog.ConversationDistance) then
- wanderDialog()
- end
- wait(1)
- end
-end
-
-function startDialog(dialog)
- if dialog.Parent and dialog.Parent:IsA("BasePart") then
- if player:DistanceFromCharacter(dialog.Parent.Position) >= dialog.ConversationDistance then
- showMessage(tooFarAwayMessage, tooFarAwaySize)
- return
- end
-
- for dialog, gui in pairs(dialogMap) do
- if dialog and gui then
- gui.Enabled = false
- end
- end
-
- renewKillswitch(dialog)
-
- delay(1, checkForLeaveArea)
- doDialog(dialog)
- end
-end
-
-function removeDialog(dialog)
- if dialogMap[dialog] then
- dialogMap[dialog]:Remove()
- dialogMap[dialog] = nil
- end
- if dialogConnections[dialog] then
- dialogConnections[dialog]:disconnect()
- dialogConnections[dialog] = nil
- end
-end
-
-function addDialog(dialog)
- if dialog.Parent then
- if dialog.Parent:IsA("BasePart") then
- local chatGui = chatNotificationGui:clone()
- chatGui.Enabled = not dialog.InUse
- chatGui.Adornee = dialog.Parent
- chatGui.Parent = game.Players.LocalPlayer.PlayerGui
- chatGui.Image.Button.MouseButton1Click:connect(function() startDialog(dialog) end)
- setChatNotificationTone(chatGui, dialog.Purpose, dialog.Tone)
-
- dialogMap[dialog] = chatGui
-
- dialogConnections[dialog] = dialog.Changed:connect(function(prop)
- if prop == "Parent" and dialog.Parent then
- --This handles the reparenting case, seperate from removal case
- removeDialog(dialog)
- addDialog(dialog)
- elseif prop == "InUse" then
- chatGui.Enabled = not currentConversationDialog and not dialog.InUse
- if dialog == currentConversationDialog then
- timeoutDialog()
- end
- elseif prop == "Tone" or prop == "Purpose" then
- setChatNotificationTone(chatGui, dialog.Purpose, dialog.Tone)
- end
- end)
- else -- still need to listen to parent changes even if current parent is not a BasePart
- dialogConnections[dialog] = dialog.Changed:connect(function(prop)
- if prop == "Parent" and dialog.Parent then
- --This handles the reparenting case, seperate from removal case
- removeDialog(dialog)
- addDialog(dialog)
- end
- end)
- end
- end
-end
-
-
---[[function fetchScripts()
- local model = game:GetService("InsertService"):LoadAsset(39226062)
- if type(model) == "string" then -- load failed, lets try again
- wait(0.1)
- model = game:GetService("InsertService"):LoadAsset(39226062)
- end
- if type(model) == "string" then -- not going to work, lets bail
- return
- end
-
- waitForDialogChildrenMyLord(model,"TimeoutScript")
- timeoutScript = model.TimeoutScript
- waitForDialogChildrenMyLord(model,"ReenableDialogScript")
- reenableDialogScript = model.ReenableDialogScript
-end
-]]--
-
-function onLoad()
- waitForProperty(game.Players, "LocalPlayer")
- player = game.Players.LocalPlayer
- waitForProperty(player, "Character")
-
- --print("Fetching Scripts")
- --fetchScripts()
-
- --print("Creating Guis")
- createChatNotificationGui()
-
- --print("Creating MessageDialog")
- createMessageDialog()
- messageDialog.Parent = gui
-
-
- --print("Initializing Frame")
- local frame = Instance.new("Frame")
- frame.Name = "DialogFrame"
- frame.Position = UDim2.new(0,0,0,0)
- frame.Size = UDim2.new(0,0,0,0)
- frame.BackgroundTransparency = 1
- frame.Parent = game.Players.LocalPlayer.PlayerGui
- initialize(frame)
-
- --print("Adding Dialogs")
- game.CollectionService.ItemAdded:connect(function(obj) if obj:IsA("Dialog") then addDialog(obj) end end)
- game.CollectionService.ItemRemoved:connect(function(obj) if obj:IsA("Dialog") then removeDialog(obj) end end)
- for i, obj in pairs(game.CollectionService:GetCollection("Dialog")) do
- if obj:IsA("Dialog") then
- addDialog(obj)
- end
- end
-end
-
-onLoad()
- true
-
-
- -
-
- GameMenu
- true
-
-
-
-
- false
- 4294967295
- 1
- 4279970357
- 1
- HoldOn
-
- 0.300000012
- 0
- 0.400000006
- 0
-
-
- 0.400000006
- 0
- 0.600000024
- 1
-
- 0
- 0
- false
- 10
- true
-
-
-
-
- true
- true
- 4288914085
- 0
- 4279970357
- 1
- 1
- 7
- ResetCharacter
-
- 0.100000009
- 0
- 0.220000088
- 0
-
- false
-
- 0.800000012
- 0
- 0.120000012
- 0
-
- 0
- 2
- Reset Character
- 4294967295
- 0
- false
- 2
- 1
- true
- 10
- true
-
-
-
-
- false
-
- Function
- function onClicked()
- game.Players.LocalPlayer.Character.Humanoid.Health = 0
- script.Parent.Parent.Visible = false
- --script.Parent.Parent.Parent.Menu.Visible = false
- game.Players.LocalPlayer.PlayerGui.GameMenu.Menu.Visible = false
- game.Players.LocalPlayer.PlayerGui.GameMenu.Tint.Visible = false
-end
-script.Parent.MouseButton1Click:connect(onClicked)
- true
-
-
-
- -
-
- true
- true
- 4288914085
- 0
- 4279970357
- 1
- 1
- 7
- ResumeGame
-
- 0.100000009
- 0
- 0.100000098
- 0
-
- false
-
- 0.800000012
- 0
- 0.120000012
- 0
-
- 0
- 1
- Resume Game
- 4294967295
- 0
- false
- 2
- 1
- true
- 10
- true
-
-
-
-
- false
-
- Function
- function onClicked()
- script.Parent.Parent.Visible = false
- --script.Parent.Parent.Parent.Menu.Visible = false
- game.Players.LocalPlayer.PlayerGui.GameMenu.Menu.Visible = false
- game.Players.LocalPlayer.PlayerGui.GameMenu.Tint.Visible = false
-end
-script.Parent.MouseButton1Click:connect(onClicked)
- true
-
-
-
- -
-
- false
- 4294901760
- 0
- 4278190080
- 0
- 2
- 8
- GameMenu
-
- 0.5
- 0
- 0.0399999991
- 3
-
-
- 0
- 0
- 0
- 0
-
- 0
- Game Menu
- 4294967295
- 0
- false
- 2
- 1
- true
- 10
- true
-
-
-
- -
-
- false
- 4278190080
- 0
- 4279970357
- 1
- Menu
-
- 0.300000012
- 0
- 0.400000006
- 0
-
-
- 0.400000006
- 0
- 0.209999993
- 0
-
- 0
- 3
- false
- 1
- true
-
-
- -
-
- false
- 4278190080
- 0
- 4279970357
- 1
- Tint
-
- 0
- 0
- 0
- 0
-
-
- 100
- 100
- 100
- 100
-
- 0
- 2
- false
- 1
- true
-
-
- -
-
- false
- 4288914085
- 1
- 4279970357
- 1
- ControlFrameGM
-
- 0
- 0
- 0
- 0
-
-
- 1
- 0
- 1
- 0
-
- 0
- 0
- true
- 1
- true
-
-
-
-
- false
- 4288914085
- 1
- 4279970357
- 1
- BottomLeftControlGM
-
- 0
- 0
- 1
- -46
-
-
- 0
- 130
- 0
- 46
-
- 0
- 0
- true
- 1
- true
-
-
-
-
- true
- true
- 4288914085
- 1
- 4279970357
- 1
- rbxasset://textures/ui/SettingsButton.png
- Home
-
- 0.5
- 2
- 0
- -2
-
- false
-
- 0
- 45
- 0
- 41
-
- 0
- 0
- true
- 1
- true
-
-
-
-
- false
-
- Function
- function onClicked()
- --script.Parent.Parent.Parent.Menu.Visible = false
- script.Parent.Parent.Parent.Parent.HoldOn.Visible = true
- script.Parent.Parent.Parent.Parent.Tint.Visible = true
- script.Parent.Parent.Parent.Parent.Menu.Visible = true
- --game.CoreGui.RobloxGui.Visible = false
- --game.Players.LocalPlayer.PlayerGui.Playerlist.Visible = false
-end
-script.Parent.MouseButton1Click:connect(onClicked)
- true
-
-
-
-
- -
-
- false
- 4288914085
- 1
- 4279970357
- 1
- NotificationBox
-
- 1
- -200
- 0.5
- 0
-
-
- 0
- 200
- 0.419999987
- 0
-
- 0
- true
- 1
- true
-
-
-
-
- -
-
- true
-
- ReenableDialogScript
- wait(5)
-local dialog = script.Parent
-if dialog:IsA("Dialog") then
- dialog.InUse = false
-end
-script:Remove()
-
- true
-
-
- -
-
- true
-
- TimeoutScript
- wait(15)
-local dialog = script.Parent
-if dialog:IsA("Dialog") then
- dialog.InUse = false
-end
-script:Remove()
-
- true
-
-
-
\ No newline at end of file
+
diff --git a/libraries2012.rbxm b/libraries2012.rbxm
new file mode 100644
index 0000000..4962683
--- /dev/null
+++ b/libraries2012.rbxm
@@ -0,0 +1,15319 @@
+
+ null
+ nil
+ -
+
+ false
+
+ Sorter
+ print("Special thanks to Bitl, Carrot, iago, winsupermario1234, Khangaroo, drslicendice, coke, TheLivingBee, Raymonf, and a bunch of play - testers for help making 2012 fully stable and work. 8)")
+script.Playerlist:clone().Parent = game.StarterGui
+script.Dialogs:clone().Parent = game.StarterGui
+script.Backpack:clone().Parent = game.StarterGui
+script.Health:clone().Parent = game.StarterGui
+script.Menu:clone().Parent = game.StarterGui
+script.ReenableDialogScript:clone().Parent = game.Lighting
+script.TimeoutScript:clone().Parent = game.Lighting
+script.ResetCommand:clone().Parent = game.Workspace
+script:remove()
+
+
-
+
+ Playerlist
+
+
-
+
+ false
+
+ Init
+ --fixed by Carrot#0559
+--for non corescript use
+local t = {}
+
+local function ScopedConnect(parentInstance, instance, event, signalFunc, syncFunc, removeFunc)
+ local eventConnection = nil
+
+ --Connection on parentInstance is scoped by parentInstance (when destroyed, it goes away)
+ local tryConnect = function()
+ if game:IsAncestorOf(parentInstance) then
+ --Entering the world, make sure we are connected/synced
+ if not eventConnection then
+ eventConnection = instance[event]:connect(signalFunc)
+ if syncFunc then syncFunc() end
+ end
+ else
+ --Probably leaving the world, so disconnect for now
+ if eventConnection then
+ eventConnection:disconnect()
+ if removeFunc then removeFunc() end
+ end
+ end
+ end
+
+ --Hook it up to ancestryChanged signal
+ local connection = parentInstance.AncestryChanged:connect(tryConnect)
+
+ --Now connect us if we're already in the world
+ tryConnect()
+
+ return connection
+end
+
+local function getScreenGuiAncestor(instance)
+ local localInstance = instance
+ while localInstance and not localInstance:IsA("ScreenGui") do
+ localInstance = localInstance.Parent
+ end
+ return localInstance
+end
+
+local function CreateButtons(frame, buttons, yPos, ySize)
+ local buttonNum = 1
+ local buttonObjs = {}
+ for i, obj in ipairs(buttons) do
+ local button = Instance.new("TextButton")
+ button.Name = "Button" .. buttonNum
+ button.Font = Enum.Font.Arial
+ button.FontSize = Enum.FontSize.Size18
+ button.AutoButtonColor = true
+ button.Modal = true
+ if obj["Style"] then
+ button.Style = obj.Style
+ else
+ button.Style = Enum.ButtonStyle.RobloxButton
+ end
+ if obj["ZIndex"] then
+ button.ZIndex = obj.ZIndex
+ end
+ button.Text = obj.Text
+ button.TextColor3 = Color3.new(1,1,1)
+ button.MouseButton1Click:connect(obj.Function)
+ button.Parent = frame
+ buttonObjs[buttonNum] = button
+
+ buttonNum = buttonNum + 1
+ end
+ local numButtons = buttonNum-1
+
+ if numButtons == 1 then
+ frame.Button1.Position = UDim2.new(0.35, 0, yPos.Scale, yPos.Offset)
+ frame.Button1.Size = UDim2.new(.4,0,ySize.Scale, ySize.Offset)
+ elseif numButtons == 2 then
+ frame.Button1.Position = UDim2.new(0.1, 0, yPos.Scale, yPos.Offset)
+ frame.Button1.Size = UDim2.new(.8/3,0, ySize.Scale, ySize.Offset)
+
+ frame.Button2.Position = UDim2.new(0.55, 0, yPos.Scale, yPos.Offset)
+ frame.Button2.Size = UDim2.new(.35,0, ySize.Scale, ySize.Offset)
+ elseif numButtons >= 3 then
+ local spacing = .1 / numButtons
+ local buttonSize = .9 / numButtons
+
+ buttonNum = 1
+ while buttonNum <= numButtons do
+ buttonObjs[buttonNum].Position = UDim2.new(spacing*buttonNum + (buttonNum-1) * buttonSize, 0, yPos.Scale, yPos.Offset)
+ buttonObjs[buttonNum].Size = UDim2.new(buttonSize, 0, ySize.Scale, ySize.Offset)
+ buttonNum = buttonNum + 1
+ end
+ end
+end
+
+local function setSliderPos(newAbsPosX,slider,sliderPosition,bar,steps)
+
+ local newStep = steps - 1 --otherwise we really get one more step than we want
+ local relativePosX = math.min(1, math.max(0, (newAbsPosX - bar.AbsolutePosition.X) / bar.AbsoluteSize.X ))
+ local wholeNum, remainder = math.modf(relativePosX * newStep)
+ if remainder > 0.5 then
+ wholeNum = wholeNum + 1
+ end
+ relativePosX = wholeNum/newStep
+
+ local result = math.ceil(relativePosX * newStep)
+ if sliderPosition.Value ~= (result + 1) then --only update if we moved a step
+ sliderPosition.Value = result + 1
+ slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
+ end
+
+end
+
+local function cancelSlide(areaSoak)
+ areaSoak.Visible = false
+ if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
+end
+
+t.CreateStyledMessageDialog = function(title, message, style, buttons)
+ local frame = Instance.new("Frame")
+ frame.Size = UDim2.new(0.5, 0, 0, 165)
+ frame.Position = UDim2.new(0.25, 0, 0.5, -72.5)
+ frame.Name = "MessageDialog"
+ frame.Active = true
+ frame.Style = Enum.FrameStyle.RobloxRound
+
+ local styleImage = Instance.new("ImageLabel")
+ styleImage.Name = "StyleImage"
+ styleImage.BackgroundTransparency = 1
+ styleImage.Position = UDim2.new(0,5,0,15)
+ if style == "error" or style == "Error" then
+ styleImage.Size = UDim2.new(0, 71, 0, 71)
+ styleImage.Image = "http://www.roblox.com/asset/?id=42565285"
+ elseif style == "notify" or style == "Notify" then
+ styleImage.Size = UDim2.new(0, 71, 0, 71)
+ styleImage.Image = "http://www.roblox.com/asset/?id=42604978"
+ elseif style == "confirm" or style == "Confirm" then
+ styleImage.Size = UDim2.new(0, 74, 0, 76)
+ styleImage.Image = "http://www.roblox.com/asset/?id=42557901"
+ else
+ return t.CreateMessageDialog(title,message,buttons)
+ end
+ styleImage.Parent = frame
+
+ local titleLabel = Instance.new("TextLabel")
+ titleLabel.Name = "Title"
+ titleLabel.Text = title
+ titleLabel.TextStrokeTransparency = 0
+ titleLabel.BackgroundTransparency = 1
+ titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
+ titleLabel.Position = UDim2.new(0, 80, 0, 0)
+ titleLabel.Size = UDim2.new(1, -80, 0, 40)
+ titleLabel.Font = Enum.Font.ArialBold
+ titleLabel.FontSize = Enum.FontSize.Size36
+ titleLabel.TextXAlignment = Enum.TextXAlignment.Center
+ titleLabel.TextYAlignment = Enum.TextYAlignment.Center
+ titleLabel.Parent = frame
+
+ local messageLabel = Instance.new("TextLabel")
+ messageLabel.Name = "Message"
+ messageLabel.Text = message
+ messageLabel.TextStrokeTransparency = 0
+ messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
+ messageLabel.Position = UDim2.new(0.025, 80, 0, 45)
+ messageLabel.Size = UDim2.new(0.95, -80, 0, 55)
+ messageLabel.BackgroundTransparency = 1
+ messageLabel.Font = Enum.Font.Arial
+ messageLabel.FontSize = Enum.FontSize.Size18
+ messageLabel.TextWrap = true
+ messageLabel.TextXAlignment = Enum.TextXAlignment.Left
+ messageLabel.TextYAlignment = Enum.TextYAlignment.Top
+ messageLabel.Parent = frame
+
+ CreateButtons(frame, buttons, UDim.new(0, 105), UDim.new(0, 40) )
+
+ return frame
+end
+
+t.CreateMessageDialog = function(title, message, buttons)
+ local frame = Instance.new("Frame")
+ frame.Size = UDim2.new(0.5, 0, 0.5, 0)
+ frame.Position = UDim2.new(0.25, 0, 0.25, 0)
+ frame.Name = "MessageDialog"
+ frame.Active = true
+ frame.Style = Enum.FrameStyle.RobloxRound
+
+ local titleLabel = Instance.new("TextLabel")
+ titleLabel.Name = "Title"
+ titleLabel.Text = title
+ titleLabel.BackgroundTransparency = 1
+ titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
+ titleLabel.Position = UDim2.new(0, 0, 0, 0)
+ titleLabel.Size = UDim2.new(1, 0, 0.15, 0)
+ titleLabel.Font = Enum.Font.ArialBold
+ titleLabel.FontSize = Enum.FontSize.Size36
+ titleLabel.TextXAlignment = Enum.TextXAlignment.Center
+ titleLabel.TextYAlignment = Enum.TextYAlignment.Center
+ titleLabel.Parent = frame
+
+ local messageLabel = Instance.new("TextLabel")
+ messageLabel.Name = "Message"
+ messageLabel.Text = message
+ messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
+ messageLabel.Position = UDim2.new(0.025, 0, 0.175, 0)
+ messageLabel.Size = UDim2.new(0.95, 0, .55, 0)
+ messageLabel.BackgroundTransparency = 1
+ messageLabel.Font = Enum.Font.Arial
+ messageLabel.FontSize = Enum.FontSize.Size18
+ messageLabel.TextWrap = true
+ messageLabel.TextXAlignment = Enum.TextXAlignment.Left
+ messageLabel.TextYAlignment = Enum.TextYAlignment.Top
+ messageLabel.Parent = frame
+
+ CreateButtons(frame, buttons, UDim.new(0.8,0), UDim.new(0.15, 0))
+
+ return frame
+end
+
+t.CreateDropDownMenu = function(items, onSelect, forRoblox, whiteSkin, baseZ)
+ local baseZIndex = 0
+ if (type(baseZ) == "number") then
+ baseZIndex = baseZ
+ end
+ local width = UDim.new(0, 100)
+ local height = UDim.new(0, 32)
+
+ local xPos = 0.055
+ local frame = Instance.new("Frame")
+ local textColor = Color3.new(1,1,1)
+ if (whiteSkin) then
+ textColor = Color3.new(0.5, 0.5, 0.5)
+ end
+ frame.Name = "DropDownMenu"
+ frame.BackgroundTransparency = 1
+ frame.Size = UDim2.new(width, height)
+
+ local dropDownMenu = Instance.new("TextButton")
+ dropDownMenu.Name = "DropDownMenuButton"
+ dropDownMenu.TextWrap = true
+ dropDownMenu.TextColor3 = textColor
+ dropDownMenu.Text = "Choose One"
+ dropDownMenu.Font = Enum.Font.ArialBold
+ dropDownMenu.FontSize = Enum.FontSize.Size18
+ dropDownMenu.TextXAlignment = Enum.TextXAlignment.Left
+ dropDownMenu.TextYAlignment = Enum.TextYAlignment.Center
+ dropDownMenu.BackgroundTransparency = 1
+ dropDownMenu.AutoButtonColor = true
+ if (whiteSkin) then
+ dropDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton
+ else
+ dropDownMenu.Style = Enum.ButtonStyle.RobloxButton
+ end
+ dropDownMenu.Size = UDim2.new(1,0,1,0)
+ dropDownMenu.Parent = frame
+ dropDownMenu.ZIndex = 2 + baseZIndex
+
+ local dropDownIcon = Instance.new("ImageLabel")
+ dropDownIcon.Name = "Icon"
+ dropDownIcon.Active = false
+ if (whiteSkin) then
+ dropDownIcon.Image = "rbxasset://textures/ui/dropdown_arrow.png"
+ dropDownIcon.Size = UDim2.new(0,16,0,12)
+ dropDownIcon.Position = UDim2.new(1,-17,0.5, -6)
+ else
+ dropDownIcon.Image = "http://www.roblox.com/asset/?id=45732894"
+ dropDownIcon.Size = UDim2.new(0,11,0,6)
+ dropDownIcon.Position = UDim2.new(1,-11,0.5, -2)
+ end
+ dropDownIcon.BackgroundTransparency = 1
+ dropDownIcon.Parent = dropDownMenu
+ dropDownIcon.ZIndex = 2 + baseZIndex
+
+ local itemCount = #items
+ local dropDownItemCount = #items
+ local useScrollButtons = false
+ if dropDownItemCount > 6 then
+ useScrollButtons = true
+ dropDownItemCount = 6
+ end
+
+ local droppedDownMenu = Instance.new("TextButton")
+ droppedDownMenu.Name = "List"
+ droppedDownMenu.Text = ""
+ droppedDownMenu.BackgroundTransparency = 1
+ --droppedDownMenu.AutoButtonColor = true
+ if (whiteSkin) then
+ droppedDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton
+ else
+ droppedDownMenu.Style = Enum.ButtonStyle.RobloxButton
+ end
+ droppedDownMenu.Visible = false
+ droppedDownMenu.Active = true --Blocks clicks
+ droppedDownMenu.Position = UDim2.new(0,0,0,0)
+ droppedDownMenu.Size = UDim2.new(1,0, (1 + dropDownItemCount)*.8, 0)
+ droppedDownMenu.Parent = frame
+ droppedDownMenu.ZIndex = 2 + baseZIndex
+
+ local choiceButton = Instance.new("TextButton")
+ choiceButton.Name = "ChoiceButton"
+ choiceButton.BackgroundTransparency = 1
+ choiceButton.BorderSizePixel = 0
+ choiceButton.Text = "ReplaceMe"
+ choiceButton.TextColor3 = textColor
+ choiceButton.TextXAlignment = Enum.TextXAlignment.Left
+ choiceButton.TextYAlignment = Enum.TextYAlignment.Center
+ choiceButton.BackgroundColor3 = Color3.new(1, 1, 1)
+ choiceButton.Font = Enum.Font.Arial
+ choiceButton.FontSize = Enum.FontSize.Size18
+ if useScrollButtons then
+ choiceButton.Size = UDim2.new(1,-13, .8/((dropDownItemCount + 1)*.8),0)
+ else
+ choiceButton.Size = UDim2.new(1, 0, .8/((dropDownItemCount + 1)*.8),0)
+ end
+ choiceButton.TextWrap = true
+ choiceButton.ZIndex = 2 + baseZIndex
+
+ local areaSoak = Instance.new("TextButton")
+ areaSoak.Name = "AreaSoak"
+ areaSoak.Text = ""
+ areaSoak.BackgroundTransparency = 1
+ areaSoak.Active = true
+ areaSoak.Size = UDim2.new(1,0,1,0)
+ areaSoak.Visible = false
+ areaSoak.ZIndex = 3 + baseZIndex
+
+ local dropDownSelected = false
+
+ local scrollUpButton
+ local scrollDownButton
+ local scrollMouseCount = 0
+
+ local setZIndex = function(baseZIndex)
+ droppedDownMenu.ZIndex = baseZIndex +1
+ if scrollUpButton then
+ scrollUpButton.ZIndex = baseZIndex + 3
+ end
+ if scrollDownButton then
+ scrollDownButton.ZIndex = baseZIndex + 3
+ end
+
+ local children = droppedDownMenu:GetChildren()
+ if children then
+ for i, child in ipairs(children) do
+ if child.Name == "ChoiceButton" then
+ child.ZIndex = baseZIndex + 2
+ elseif child.Name == "ClickCaptureButton" then
+ child.ZIndex = baseZIndex
+ end
+ end
+ end
+ end
+
+ local scrollBarPosition = 1
+ local updateScroll = function()
+ if scrollUpButton then
+ scrollUpButton.Active = scrollBarPosition > 1
+ end
+ if scrollDownButton then
+ scrollDownButton.Active = scrollBarPosition + dropDownItemCount <= itemCount
+ end
+
+ local children = droppedDownMenu:GetChildren()
+ if not children then return end
+
+ local childNum = 1
+ for i, obj in ipairs(children) do
+ if obj.Name == "ChoiceButton" then
+ if childNum < scrollBarPosition or childNum >= scrollBarPosition + dropDownItemCount then
+ obj.Visible = false
+ else
+ obj.Position = UDim2.new(0,0,((childNum-scrollBarPosition+1)*.8)/((dropDownItemCount+1)*.8),0)
+ obj.Visible = true
+ end
+ obj.TextColor3 = textColor
+ obj.BackgroundTransparency = 1
+
+ childNum = childNum + 1
+ end
+ end
+ end
+ local toggleVisibility = function()
+ dropDownSelected = not dropDownSelected
+
+ areaSoak.Visible = not areaSoak.Visible
+ dropDownMenu.Visible = not dropDownSelected
+ droppedDownMenu.Visible = dropDownSelected
+ if dropDownSelected then
+ setZIndex(4 + baseZIndex)
+ else
+ setZIndex(2 + baseZIndex)
+ end
+ if useScrollButtons then
+ updateScroll()
+ end
+ end
+ droppedDownMenu.MouseButton1Click:connect(toggleVisibility)
+
+ local updateSelection = function(text)
+ local foundItem = false
+ local children = droppedDownMenu:GetChildren()
+ local childNum = 1
+ if children then
+ for i, obj in ipairs(children) do
+ if obj.Name == "ChoiceButton" then
+ if obj.Text == text then
+ obj.Font = Enum.Font.ArialBold
+ foundItem = true
+ scrollBarPosition = childNum
+ if (whiteSkin) then
+ obj.TextColor3 = Color3.new(90/255,142/255,233/255)
+ end
+ else
+ obj.Font = Enum.Font.Arial
+ if (whiteSkin) then
+ obj.TextColor3 = textColor
+ end
+ end
+ childNum = childNum + 1
+ end
+ end
+ end
+ if not text then
+ dropDownMenu.Text = "Choose One"
+ scrollBarPosition = 1
+ else
+ if not foundItem then
+ error("Invalid Selection Update -- " .. text)
+ end
+
+ if scrollBarPosition + dropDownItemCount > itemCount + 1 then
+ scrollBarPosition = itemCount - dropDownItemCount + 1
+ end
+
+ dropDownMenu.Text = text
+ end
+ end
+
+ local function scrollDown()
+ if scrollBarPosition + dropDownItemCount <= itemCount then
+ scrollBarPosition = scrollBarPosition + 1
+ updateScroll()
+ return true
+ end
+ return false
+ end
+ local function scrollUp()
+ if scrollBarPosition > 1 then
+ scrollBarPosition = scrollBarPosition - 1
+ updateScroll()
+ return true
+ end
+ return false
+ end
+
+ if useScrollButtons then
+ --Make some scroll buttons
+ scrollUpButton = Instance.new("ImageButton")
+ scrollUpButton.Name = "ScrollUpButton"
+ scrollUpButton.BackgroundTransparency = 1
+ scrollUpButton.Image = "rbxasset://textures/ui/scrollbuttonUp.png"
+ scrollUpButton.Size = UDim2.new(0,17,0,17)
+ scrollUpButton.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),0)
+ scrollUpButton.MouseButton1Click:connect(
+ function()
+ scrollMouseCount = scrollMouseCount + 1
+ end)
+ scrollUpButton.MouseLeave:connect(
+ function()
+ scrollMouseCount = scrollMouseCount + 1
+ end)
+ scrollUpButton.MouseButton1Down:connect(
+ function()
+ scrollMouseCount = scrollMouseCount + 1
+
+ scrollUp()
+ local val = scrollMouseCount
+ wait(0.5)
+ while val == scrollMouseCount do
+ if scrollUp() == false then
+ break
+ end
+ wait(0.1)
+ end
+ end)
+
+ scrollUpButton.Parent = droppedDownMenu
+
+ scrollDownButton = Instance.new("ImageButton")
+ scrollDownButton.Name = "ScrollDownButton"
+ scrollDownButton.BackgroundTransparency = 1
+ scrollDownButton.Image = "rbxasset://textures/ui/scrollbuttonDown.png"
+ scrollDownButton.Size = UDim2.new(0,17,0,17)
+ scrollDownButton.Position = UDim2.new(1,-11,1,-11)
+ scrollDownButton.Parent = droppedDownMenu
+ scrollDownButton.MouseButton1Click:connect(
+ function()
+ scrollMouseCount = scrollMouseCount + 1
+ end)
+ scrollDownButton.MouseLeave:connect(
+ function()
+ scrollMouseCount = scrollMouseCount + 1
+ end)
+ scrollDownButton.MouseButton1Down:connect(
+ function()
+ scrollMouseCount = scrollMouseCount + 1
+
+ scrollDown()
+ local val = scrollMouseCount
+ wait(0.5)
+ while val == scrollMouseCount do
+ if scrollDown() == false then
+ break
+ end
+ wait(0.1)
+ end
+ end)
+
+ local scrollbar = Instance.new("ImageLabel")
+ scrollbar.Name = "ScrollBar"
+ scrollbar.Image = "rbxasset://textures/ui/scrollbar.png"
+ scrollbar.BackgroundTransparency = 1
+ scrollbar.Size = UDim2.new(0, 18, (dropDownItemCount*.8)/((dropDownItemCount+1)*.8), -(17) - 11 - 4)
+ scrollbar.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),17+2)
+ scrollbar.Parent = droppedDownMenu
+ end
+
+ for i,item in ipairs(items) do
+ -- needed to maintain local scope for items in event listeners below
+ local button = choiceButton:clone()
+ if forRoblox then
+ button.RobloxLocked = true
+ end
+ button.Text = item
+ button.Parent = droppedDownMenu
+ if (whiteSkin) then
+ button.TextColor3 = textColor
+ end
+
+ button.MouseButton1Click:connect(function()
+ --Remove Highlight
+ if (not whiteSkin) then
+ button.TextColor3 = Color3.new(1,1,1)
+ end
+ button.BackgroundTransparency = 1
+
+ updateSelection(item)
+ onSelect(item)
+
+ toggleVisibility()
+ end)
+ button.MouseEnter:connect(function()
+ --Add Highlight
+ if (not whiteSkin) then
+ button.TextColor3 = Color3.new(0,0,0)
+ end
+ button.BackgroundTransparency = 0
+ end)
+
+ button.MouseLeave:connect(function()
+ --Remove Highlight
+ if (not whiteSkin) then
+ button.TextColor3 = Color3.new(1,1,1)
+ end
+ button.BackgroundTransparency = 1
+ end)
+ end
+
+ --This does the initial layout of the buttons
+ updateScroll()
+
+ frame.AncestryChanged:connect(function(child,parent)
+ if parent == nil then
+ areaSoak.Parent = nil
+ else
+ areaSoak.Parent = getScreenGuiAncestor(frame)
+ end
+ end)
+
+ dropDownMenu.MouseButton1Click:connect(toggleVisibility)
+ areaSoak.MouseButton1Click:connect(toggleVisibility)
+ return frame, updateSelection
+end
+
+t.CreatePropertyDropDownMenu = function(instance, property, enum)
+
+ local items = enum:GetEnumItems()
+ local names = {}
+ local nameToItem = {}
+ for i,obj in ipairs(items) do
+ names[i] = obj.Name
+ nameToItem[obj.Name] = obj
+ end
+
+ local frame
+ local updateSelection
+ frame, updateSelection = t.CreateDropDownMenu(names, function(text) instance[property] = nameToItem[text] end)
+
+ ScopedConnect(frame, instance, "Changed",
+ function(prop)
+ if prop == property then
+ updateSelection(instance[property].Name)
+ end
+ end,
+ function()
+ updateSelection(instance[property].Name)
+ end)
+
+ return frame
+end
+
+t.GetFontHeight = function(font, fontSize)
+ if font == nil or fontSize == nil then
+ error("Font and FontSize must be non-nil")
+ end
+
+ if font == Enum.Font.Legacy then
+ if fontSize == Enum.FontSize.Size8 then
+ return 12
+ elseif fontSize == Enum.FontSize.Size9 then
+ return 14
+ elseif fontSize == Enum.FontSize.Size10 then
+ return 15
+ elseif fontSize == Enum.FontSize.Size11 then
+ return 17
+ elseif fontSize == Enum.FontSize.Size12 then
+ return 18
+ elseif fontSize == Enum.FontSize.Size14 then
+ return 21
+ elseif fontSize == Enum.FontSize.Size18 then
+ return 27
+ elseif fontSize == Enum.FontSize.Size24 then
+ return 36
+ elseif fontSize == Enum.FontSize.Size36 then
+ return 54
+ elseif fontSize == Enum.FontSize.Size48 then
+ return 72
+ else
+ error("Unknown FontSize")
+ end
+ elseif font == Enum.Font.Arial or font == Enum.Font.ArialBold then
+ if fontSize == Enum.FontSize.Size8 then
+ return 8
+ elseif fontSize == Enum.FontSize.Size9 then
+ return 9
+ elseif fontSize == Enum.FontSize.Size10 then
+ return 10
+ elseif fontSize == Enum.FontSize.Size11 then
+ return 11
+ elseif fontSize == Enum.FontSize.Size12 then
+ return 12
+ elseif fontSize == Enum.FontSize.Size14 then
+ return 14
+ elseif fontSize == Enum.FontSize.Size18 then
+ return 18
+ elseif fontSize == Enum.FontSize.Size24 then
+ return 24
+ elseif fontSize == Enum.FontSize.Size36 then
+ return 36
+ elseif fontSize == Enum.FontSize.Size48 then
+ return 48
+ else
+ error("Unknown FontSize")
+ end
+ else
+ error("Unknown Font " .. font)
+ end
+end
+
+local function layoutGuiObjectsHelper(frame, guiObjects, settingsTable)
+ local totalPixels = frame.AbsoluteSize.Y
+ local pixelsRemaining = frame.AbsoluteSize.Y
+ for i, child in ipairs(guiObjects) do
+ if child:IsA("TextLabel") or child:IsA("TextButton") then
+ local isLabel = child:IsA("TextLabel")
+ if isLabel then
+ pixelsRemaining = pixelsRemaining - settingsTable["TextLabelPositionPadY"]
+ else
+ pixelsRemaining = pixelsRemaining - settingsTable["TextButtonPositionPadY"]
+ end
+ child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
+ child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, pixelsRemaining)
+
+ if child.TextFits and child.TextBounds.Y < pixelsRemaining then
+ child.Visible = true
+ if isLabel then
+ child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable["TextLabelSizePadY"])
+ else
+ child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable["TextButtonSizePadY"])
+ end
+
+ while not child.TextFits do
+ child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.AbsoluteSize.Y + 1)
+ end
+ pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
+
+ if isLabel then
+ pixelsRemaining = pixelsRemaining - settingsTable["TextLabelPositionPadY"]
+ else
+ pixelsRemaining = pixelsRemaining - settingsTable["TextButtonPositionPadY"]
+ end
+ else
+ child.Visible = false
+ pixelsRemaining = -1
+ end
+
+ else
+ --GuiObject
+ child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
+ pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
+ child.Visible = (pixelsRemaining >= 0)
+ end
+ end
+end
+
+t.LayoutGuiObjects = function(frame, guiObjects, settingsTable)
+ if not frame:IsA("GuiObject") then
+ error("Frame must be a GuiObject")
+ end
+ for i, child in ipairs(guiObjects) do
+ if not child:IsA("GuiObject") then
+ error("All elements that are layed out must be of type GuiObject")
+ end
+ end
+
+ if not settingsTable then
+ settingsTable = {}
+ end
+
+ if not settingsTable["TextLabelSizePadY"] then
+ settingsTable["TextLabelSizePadY"] = 0
+ end
+ if not settingsTable["TextLabelPositionPadY"] then
+ settingsTable["TextLabelPositionPadY"] = 0
+ end
+ if not settingsTable["TextButtonSizePadY"] then
+ settingsTable["TextButtonSizePadY"] = 12
+ end
+ if not settingsTable["TextButtonPositionPadY"] then
+ settingsTable["TextButtonPositionPadY"] = 2
+ end
+
+ --Wrapper frame takes care of styled objects
+ local wrapperFrame = Instance.new("Frame")
+ wrapperFrame.Name = "WrapperFrame"
+ wrapperFrame.BackgroundTransparency = 1
+ wrapperFrame.Size = UDim2.new(1,0,1,0)
+ wrapperFrame.Parent = frame
+
+ for i, child in ipairs(guiObjects) do
+ child.Parent = wrapperFrame
+ end
+
+ local recalculate = function()
+ wait()
+ layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable)
+ end
+
+ frame.Changed:connect(
+ function(prop)
+ if prop == "AbsoluteSize" then
+ --Wait a heartbeat for it to sync in
+ recalculate(nil)
+ end
+ end)
+ frame.AncestryChanged:connect(recalculate)
+
+ layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable)
+end
+
+
+t.CreateSlider = function(steps,width,position)
+ local sliderGui = Instance.new("Frame")
+ sliderGui.Size = UDim2.new(1,0,1,0)
+ sliderGui.BackgroundTransparency = 1
+ sliderGui.Name = "SliderGui"
+
+ local sliderSteps = Instance.new("IntValue")
+ sliderSteps.Name = "SliderSteps"
+ sliderSteps.Value = steps
+ sliderSteps.Parent = sliderGui
+
+ local areaSoak = Instance.new("TextButton")
+ areaSoak.Name = "AreaSoak"
+ areaSoak.Text = ""
+ areaSoak.BackgroundTransparency = 1
+ areaSoak.Active = false
+ areaSoak.Size = UDim2.new(1,0,1,0)
+ areaSoak.Visible = false
+ areaSoak.ZIndex = 4
+
+ sliderGui.AncestryChanged:connect(function(child,parent)
+ if parent == nil then
+ areaSoak.Parent = nil
+ else
+ areaSoak.Parent = getScreenGuiAncestor(sliderGui)
+ end
+ end)
+
+ local sliderPosition = Instance.new("IntValue")
+ sliderPosition.Name = "SliderPosition"
+ sliderPosition.Value = 0
+ sliderPosition.Parent = sliderGui
+
+ local id = math.random(1,100)
+
+ local bar = Instance.new("TextButton")
+ bar.Text = ""
+ bar.AutoButtonColor = false
+ bar.Name = "Bar"
+ bar.BackgroundColor3 = Color3.new(0,0,0)
+ if type(width) == "number" then
+ bar.Size = UDim2.new(0,width,0,5)
+ else
+ bar.Size = UDim2.new(0,200,0,5)
+ end
+ bar.BorderColor3 = Color3.new(95/255,95/255,95/255)
+ bar.ZIndex = 2
+ bar.Parent = sliderGui
+
+ if position["X"] and position["X"]["Scale"] and position["X"]["Offset"] and position["Y"] and position["Y"]["Scale"] and position["Y"]["Offset"] then
+ bar.Position = position
+ end
+
+ local slider = Instance.new("ImageButton")
+ slider.Name = "Slider"
+ slider.BackgroundTransparency = 1
+ slider.Image = "rbxasset://textures/ui/Slider.png"
+ slider.Position = UDim2.new(0,0,0.5,-10)
+ slider.Size = UDim2.new(0,20,0,20)
+ slider.ZIndex = 3
+ slider.Parent = bar
+
+ local areaSoakMouseMoveCon = nil
+
+ areaSoak.MouseLeave:connect(function()
+ if areaSoak.Visible then
+ cancelSlide(areaSoak)
+ end
+ end)
+ areaSoak.MouseButton1Up:connect(function()
+ if areaSoak.Visible then
+ cancelSlide(areaSoak)
+ end
+ end)
+
+ slider.MouseButton1Down:connect(function()
+ areaSoak.Visible = true
+ if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
+ areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y)
+ setSliderPos(x,slider,sliderPosition,bar,steps)
+ end)
+ end)
+
+ slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end)
+
+ sliderPosition.Changed:connect(function(prop)
+ sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value))
+ local relativePosX = (sliderPosition.Value - 1) / (steps - 1)
+ slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
+ end)
+
+ bar.MouseButton1Down:connect(function(x,y)
+ setSliderPos(x,slider,sliderPosition,bar,steps)
+ end)
+
+ return sliderGui, sliderPosition, sliderSteps
+
+end
+
+
+
+t.CreateSliderNew = function(steps,width,position)
+ local sliderGui = Instance.new("Frame")
+ sliderGui.Size = UDim2.new(1,0,1,0)
+ sliderGui.BackgroundTransparency = 1
+ sliderGui.Name = "SliderGui"
+
+ local sliderSteps = Instance.new("IntValue")
+ sliderSteps.Name = "SliderSteps"
+ sliderSteps.Value = steps
+ sliderSteps.Parent = sliderGui
+
+ local areaSoak = Instance.new("TextButton")
+ areaSoak.Name = "AreaSoak"
+ areaSoak.Text = ""
+ areaSoak.BackgroundTransparency = 1
+ areaSoak.Active = false
+ areaSoak.Size = UDim2.new(1,0,1,0)
+ areaSoak.Visible = false
+ areaSoak.ZIndex = 6
+
+ sliderGui.AncestryChanged:connect(function(child,parent)
+ if parent == nil then
+ areaSoak.Parent = nil
+ else
+ areaSoak.Parent = getScreenGuiAncestor(sliderGui)
+ end
+ end)
+
+ local sliderPosition = Instance.new("IntValue")
+ sliderPosition.Name = "SliderPosition"
+ sliderPosition.Value = 0
+ sliderPosition.Parent = sliderGui
+
+ local id = math.random(1,100)
+
+ local sliderBarImgHeight = 7
+ local sliderBarCapImgWidth = 4
+
+ local bar = Instance.new("ImageButton")
+ bar.BackgroundTransparency = 1
+ bar.Image = "rbxasset://textures/ui/Slider-BKG-Center.png"
+ bar.Name = "Bar"
+ local displayWidth = 200
+ if type(width) == "number" then
+ bar.Size = UDim2.new(0,width - (sliderBarCapImgWidth * 2),0,sliderBarImgHeight)
+ displayWidth = width - (sliderBarCapImgWidth * 2)
+ else
+ bar.Size = UDim2.new(0,200,0,sliderBarImgHeight)
+ end
+ bar.ZIndex = 3
+ bar.Parent = sliderGui
+ if position["X"] and position["X"]["Scale"] and position["X"]["Offset"] and position["Y"] and position["Y"]["Scale"] and position["Y"]["Offset"] then
+ bar.Position = position
+ end
+
+ local barLeft = bar:clone()
+ barLeft.Name = "BarLeft"
+ barLeft.Image = "rbxasset://textures/ui/Slider-BKG-Left-Cap.png"
+ barLeft.Size = UDim2.new(0, sliderBarCapImgWidth, 0, sliderBarImgHeight)
+ barLeft.Position = UDim2.new(position.X.Scale, position.X.Offset - sliderBarCapImgWidth, position.Y.Scale, position.Y.Offset)
+ barLeft.Parent = sliderGui
+ barLeft.ZIndex = 3
+
+ local barRight = barLeft:clone()
+ barRight.Name = "BarRight"
+ barRight.Image = "rbxasset://textures/ui/Slider-BKG-Right-Cap.png"
+ barRight.Position = UDim2.new(position.X.Scale, position.X.Offset + displayWidth, position.Y.Scale, position.Y.Offset)
+ barRight.Parent = sliderGui
+
+ local fillLeft = barLeft:clone()
+ fillLeft.Name = "FillLeft"
+ fillLeft.Image = "rbxasset://textures/ui/Slider-Fill-Left-Cap.png"
+ fillLeft.Parent = sliderGui
+ fillLeft.ZIndex = 4
+
+ local fill = fillLeft:clone()
+ fill.Name = "Fill"
+ fill.Image = "rbxasset://textures/ui/Slider-Fill-Center.png"
+ fill.Parent = bar
+ fill.ZIndex = 4
+ fill.Position = UDim2.new(0, 0, 0, 0)
+ fill.Size = UDim2.new(0.5, 0, 1, 0)
+
+
+-- bar.Visible = false
+
+ local slider = Instance.new("ImageButton")
+ slider.Name = "Slider"
+ slider.BackgroundTransparency = 1
+ slider.Image = "rbxasset://textures/ui/slider_new_tab.png"
+ slider.Position = UDim2.new(0,0,0.5,-14)
+ slider.Size = UDim2.new(0,28,0,28)
+ slider.ZIndex = 5
+ slider.Parent = bar
+
+ local areaSoakMouseMoveCon = nil
+
+ areaSoak.MouseLeave:connect(function()
+ if areaSoak.Visible then
+ cancelSlide(areaSoak)
+ end
+ end)
+ areaSoak.MouseButton1Up:connect(function()
+ if areaSoak.Visible then
+ cancelSlide(areaSoak)
+ end
+ end)
+
+ slider.MouseButton1Down:connect(function()
+ areaSoak.Visible = true
+ if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
+ areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y)
+ setSliderPos(x,slider,sliderPosition,bar,steps)
+ end)
+ end)
+
+ slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end)
+
+ sliderPosition.Changed:connect(function(prop)
+ sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value))
+ local relativePosX = (sliderPosition.Value - 1) / (steps - 1)
+ slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
+ fill.Size = UDim2.new(relativePosX, 0, 1, 0)
+ end)
+
+ bar.MouseButton1Down:connect(function(x,y)
+ setSliderPos(x,slider,sliderPosition,bar,steps)
+ end)
+
+ return sliderGui, sliderPosition, sliderSteps
+
+end
+
+
+
+
+
+t.CreateTrueScrollingFrame = function()
+ local lowY = nil
+ local highY = nil
+
+ local dragCon = nil
+ local upCon = nil
+
+ local internalChange = false
+
+ local descendantsChangeConMap = {}
+
+ local scrollingFrame = Instance.new("Frame")
+ scrollingFrame.Name = "ScrollingFrame"
+ scrollingFrame.Active = true
+ scrollingFrame.Size = UDim2.new(1,0,1,0)
+ scrollingFrame.ClipsDescendants = true
+
+ local controlFrame = Instance.new("Frame")
+ controlFrame.Name = "ControlFrame"
+ controlFrame.BackgroundTransparency = 1
+ controlFrame.Size = UDim2.new(0,18,1,0)
+ controlFrame.Position = UDim2.new(1,-20,0,0)
+ controlFrame.Parent = scrollingFrame
+
+ local scrollBottom = Instance.new("BoolValue")
+ scrollBottom.Value = false
+ scrollBottom.Name = "ScrollBottom"
+ scrollBottom.Parent = controlFrame
+
+ local scrollUp = Instance.new("BoolValue")
+ scrollUp.Value = false
+ scrollUp.Name = "scrollUp"
+ scrollUp.Parent = controlFrame
+
+ local scrollUpButton = Instance.new("TextButton")
+ scrollUpButton.Name = "ScrollUpButton"
+ scrollUpButton.Text = ""
+ scrollUpButton.AutoButtonColor = false
+ scrollUpButton.BackgroundColor3 = Color3.new(0,0,0)
+ scrollUpButton.BorderColor3 = Color3.new(1,1,1)
+ scrollUpButton.BackgroundTransparency = 0.5
+ scrollUpButton.Size = UDim2.new(0,18,0,18)
+ scrollUpButton.ZIndex = 2
+ scrollUpButton.Parent = controlFrame
+ for i = 1, 6 do
+ local triFrame = Instance.new("Frame")
+ triFrame.BorderColor3 = Color3.new(1,1,1)
+ triFrame.Name = "tri" .. tostring(i)
+ triFrame.ZIndex = 3
+ triFrame.BackgroundTransparency = 0.5
+ triFrame.Size = UDim2.new(0,12 - ((i -1) * 2),0,0)
+ triFrame.Position = UDim2.new(0,3 + (i -1),0.5,2 - (i -1))
+ triFrame.Parent = scrollUpButton
+ end
+ scrollUpButton.MouseEnter:connect(function()
+ scrollUpButton.BackgroundTransparency = 0.1
+ local upChildren = scrollUpButton:GetChildren()
+ for i = 1, #upChildren do
+ upChildren[i].BackgroundTransparency = 0.1
+ end
+ end)
+ scrollUpButton.MouseLeave:connect(function()
+ scrollUpButton.BackgroundTransparency = 0.5
+ local upChildren = scrollUpButton:GetChildren()
+ for i = 1, #upChildren do
+ upChildren[i].BackgroundTransparency = 0.5
+ end
+ end)
+
+ local scrollDownButton = scrollUpButton:clone()
+ scrollDownButton.Name = "ScrollDownButton"
+ scrollDownButton.Position = UDim2.new(0,0,1,-18)
+ local downChildren = scrollDownButton:GetChildren()
+ for i = 1, #downChildren do
+ downChildren[i].Position = UDim2.new(0,3 + (i -1),0.5,-2 + (i - 1))
+ end
+ scrollDownButton.MouseEnter:connect(function()
+ scrollDownButton.BackgroundTransparency = 0.1
+ local downChildren = scrollDownButton:GetChildren()
+ for i = 1, #downChildren do
+ downChildren[i].BackgroundTransparency = 0.1
+ end
+ end)
+ scrollDownButton.MouseLeave:connect(function()
+ scrollDownButton.BackgroundTransparency = 0.5
+ local downChildren = scrollDownButton:GetChildren()
+ for i = 1, #downChildren do
+ downChildren[i].BackgroundTransparency = 0.5
+ end
+ end)
+ scrollDownButton.Parent = controlFrame
+
+ local scrollTrack = Instance.new("Frame")
+ scrollTrack.Name = "ScrollTrack"
+ scrollTrack.BackgroundTransparency = 1
+ scrollTrack.Size = UDim2.new(0,18,1,-38)
+ scrollTrack.Position = UDim2.new(0,0,0,19)
+ scrollTrack.Parent = controlFrame
+
+ local scrollbar = Instance.new("TextButton")
+ scrollbar.BackgroundColor3 = Color3.new(0,0,0)
+ scrollbar.BorderColor3 = Color3.new(1,1,1)
+ scrollbar.BackgroundTransparency = 0.5
+ scrollbar.AutoButtonColor = false
+ scrollbar.Text = ""
+ scrollbar.Active = true
+ scrollbar.Name = "ScrollBar"
+ scrollbar.ZIndex = 2
+ scrollbar.BackgroundTransparency = 0.5
+ scrollbar.Size = UDim2.new(0, 18, 0.1, 0)
+ scrollbar.Position = UDim2.new(0,0,0,0)
+ scrollbar.Parent = scrollTrack
+
+ local scrollNub = Instance.new("Frame")
+ scrollNub.Name = "ScrollNub"
+ scrollNub.BorderColor3 = Color3.new(1,1,1)
+ scrollNub.Size = UDim2.new(0,10,0,0)
+ scrollNub.Position = UDim2.new(0.5,-5,0.5,0)
+ scrollNub.ZIndex = 2
+ scrollNub.BackgroundTransparency = 0.5
+ scrollNub.Parent = scrollbar
+
+ local newNub = scrollNub:clone()
+ newNub.Position = UDim2.new(0.5,-5,0.5,-2)
+ newNub.Parent = scrollbar
+
+ local lastNub = scrollNub:clone()
+ lastNub.Position = UDim2.new(0.5,-5,0.5,2)
+ lastNub.Parent = scrollbar
+
+ scrollbar.MouseEnter:connect(function()
+ scrollbar.BackgroundTransparency = 0.1
+ scrollNub.BackgroundTransparency = 0.1
+ newNub.BackgroundTransparency = 0.1
+ lastNub.BackgroundTransparency = 0.1
+ end)
+ scrollbar.MouseLeave:connect(function()
+ scrollbar.BackgroundTransparency = 0.5
+ scrollNub.BackgroundTransparency = 0.5
+ newNub.BackgroundTransparency = 0.5
+ lastNub.BackgroundTransparency = 0.5
+ end)
+
+ local mouseDrag = Instance.new("ImageButton")
+ mouseDrag.Active = false
+ mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0)
+ mouseDrag.AutoButtonColor = false
+ mouseDrag.BackgroundTransparency = 1
+ mouseDrag.Name = "mouseDrag"
+ mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0)
+ mouseDrag.ZIndex = 10
+
+ local function positionScrollBar(x,y,offset)
+ local oldPos = scrollbar.Position
+
+ if y < scrollTrack.AbsolutePosition.y then
+ scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0)
+ return (oldPos ~= scrollbar.Position)
+ end
+
+ local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y
+
+ if y > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then
+ scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0)
+ return (oldPos ~= scrollbar.Position)
+ end
+ local newScaleYPos = (y - scrollTrack.AbsolutePosition.y - offset)/scrollTrack.AbsoluteSize.y
+ if newScaleYPos + relativeSize > 1 then
+ newScaleYPos = 1 - relativeSize
+ scrollBottom.Value = true
+ scrollUp.Value = false
+ elseif newScaleYPos <= 0 then
+ newScaleYPos = 0
+ scrollUp.Value = true
+ scrollBottom.Value = false
+ else
+ scrollUp.Value = false
+ scrollBottom.Value = false
+ end
+ scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,newScaleYPos,0)
+
+ return (oldPos ~= scrollbar.Position)
+ end
+
+ local function drillDownSetHighLow(instance)
+ if not instance or not instance:IsA("GuiObject") then return end
+ if instance == controlFrame then return end
+ if instance:IsDescendantOf(controlFrame) then return end
+ if not instance.Visible then return end
+
+ if lowY and lowY > instance.AbsolutePosition.Y then
+ lowY = instance.AbsolutePosition.Y
+ elseif not lowY then
+ lowY = instance.AbsolutePosition.Y
+ end
+ if highY and highY < (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) then
+ highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
+ elseif not highY then
+ highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
+ end
+ local children = instance:GetChildren()
+ for i = 1, #children do
+ drillDownSetHighLow(children[i])
+ end
+ end
+
+ local function resetHighLow()
+ local firstChildren = scrollingFrame:GetChildren()
+
+ for i = 1, #firstChildren do
+ drillDownSetHighLow(firstChildren[i])
+ end
+ end
+
+ local function recalculate()
+ internalChange = true
+
+ local percentFrame = 0
+ if scrollbar.Position.Y.Scale > 0 then
+ if scrollbar.Visible then
+ percentFrame = scrollbar.Position.Y.Scale/((scrollTrack.AbsoluteSize.Y - scrollbar.AbsoluteSize.Y)/scrollTrack.AbsoluteSize.Y)
+ else
+ percentFrame = 0
+ end
+ end
+ if percentFrame > 0.99 then percentFrame = 1 end
+
+ local hiddenYAmount = (scrollingFrame.AbsoluteSize.Y - (highY - lowY)) * percentFrame
+
+ local guiChildren = scrollingFrame:GetChildren()
+ for i = 1, #guiChildren do
+ if guiChildren[i] ~= controlFrame then
+ guiChildren[i].Position = UDim2.new(guiChildren[i].Position.X.Scale,guiChildren[i].Position.X.Offset,
+ 0, math.ceil(guiChildren[i].AbsolutePosition.Y) - math.ceil(lowY) + hiddenYAmount)
+ end
+ end
+
+ lowY = nil
+ highY = nil
+ resetHighLow()
+ internalChange = false
+ end
+
+ local function setSliderSizeAndPosition()
+ if not highY or not lowY then return end
+
+ local totalYSpan = math.abs(highY - lowY)
+ if totalYSpan == 0 then
+ scrollbar.Visible = false
+ scrollDownButton.Visible = false
+ scrollUpButton.Visible = false
+
+ if dragCon then dragCon:disconnect() dragCon = nil end
+ if upCon then upCon:disconnect() upCon = nil end
+ return
+ end
+
+ local percentShown = scrollingFrame.AbsoluteSize.Y/totalYSpan
+ if percentShown >= 1 then
+ scrollbar.Visible = false
+ scrollDownButton.Visible = false
+ scrollUpButton.Visible = false
+ recalculate()
+ else
+ scrollbar.Visible = true
+ scrollDownButton.Visible = true
+ scrollUpButton.Visible = true
+
+ scrollbar.Size = UDim2.new(scrollbar.Size.X.Scale,scrollbar.Size.X.Offset,percentShown,0)
+ end
+
+ local percentPosition = (scrollingFrame.AbsolutePosition.Y - lowY)/totalYSpan
+ scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,percentPosition,-scrollbar.AbsoluteSize.X/2)
+
+ if scrollbar.AbsolutePosition.y < scrollTrack.AbsolutePosition.y then
+ scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0)
+ end
+
+ if (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.Y) > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then
+ local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y
+ scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0)
+ end
+ end
+
+ local buttonScrollAmountPixels = 7
+ local reentrancyGuardScrollUp = false
+ local function doScrollUp()
+ if reentrancyGuardScrollUp then return end
+
+ reentrancyGuardScrollUp = true
+ if positionScrollBar(0,scrollbar.AbsolutePosition.Y - buttonScrollAmountPixels,0) then
+ recalculate()
+ end
+ reentrancyGuardScrollUp = false
+ end
+
+ local reentrancyGuardScrollDown = false
+ local function doScrollDown()
+ if reentrancyGuardScrollDown then return end
+
+ reentrancyGuardScrollDown = true
+ if positionScrollBar(0,scrollbar.AbsolutePosition.Y + buttonScrollAmountPixels,0) then
+ recalculate()
+ end
+ reentrancyGuardScrollDown = false
+ end
+
+ local function scrollUp(mouseYPos)
+ if scrollUpButton.Active then
+ scrollStamp = tick()
+ local current = scrollStamp
+ local upCon
+ upCon = mouseDrag.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ mouseDrag.Parent = nil
+ upCon:disconnect()
+ end)
+ mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
+ doScrollUp()
+ wait(0.2)
+ local t = tick()
+ local w = 0.1
+ while scrollStamp == current do
+ doScrollUp()
+ if mouseYPos and mouseYPos > scrollbar.AbsolutePosition.y then
+ break
+ end
+ if not scrollUpButton.Active then break end
+ if tick()-t > 5 then
+ w = 0
+ elseif tick()-t > 2 then
+ w = 0.06
+ end
+ wait(w)
+ end
+ end
+ end
+
+ local function scrollDown(mouseYPos)
+ if scrollDownButton.Active then
+ scrollStamp = tick()
+ local current = scrollStamp
+ local downCon
+ downCon = mouseDrag.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ mouseDrag.Parent = nil
+ downCon:disconnect()
+ end)
+ mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
+ doScrollDown()
+ wait(0.2)
+ local t = tick()
+ local w = 0.1
+ while scrollStamp == current do
+ doScrollDown()
+ if mouseYPos and mouseYPos < (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.x) then
+ break
+ end
+ if not scrollDownButton.Active then break end
+ if tick()-t > 5 then
+ w = 0
+ elseif tick()-t > 2 then
+ w = 0.06
+ end
+ wait(w)
+ end
+ end
+ end
+
+ scrollbar.MouseButton1Down:connect(function(x,y)
+ if scrollbar.Active then
+ scrollStamp = tick()
+ local mouseOffset = y - scrollbar.AbsolutePosition.y
+ if dragCon then dragCon:disconnect() dragCon = nil end
+ if upCon then upCon:disconnect() upCon = nil end
+ local prevY = y
+ local reentrancyGuardMouseScroll = false
+ dragCon = mouseDrag.MouseMoved:connect(function(x,y)
+ if reentrancyGuardMouseScroll then return end
+
+ reentrancyGuardMouseScroll = true
+ if positionScrollBar(x,y,mouseOffset) then
+ recalculate()
+ end
+ reentrancyGuardMouseScroll = false
+
+ end)
+ upCon = mouseDrag.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ mouseDrag.Parent = nil
+ dragCon:disconnect(); dragCon = nil
+ upCon:disconnect(); drag = nil
+ end)
+ mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
+ end
+ end)
+
+ local scrollMouseCount = 0
+
+ scrollUpButton.MouseButton1Down:connect(function()
+ scrollUp()
+ end)
+ scrollUpButton.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ end)
+
+ scrollDownButton.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ end)
+ scrollDownButton.MouseButton1Down:connect(function()
+ scrollDown()
+ end)
+
+ scrollbar.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ end)
+
+ local function heightCheck(instance)
+ if highY and (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) > highY then
+ highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
+ elseif not highY then
+ highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
+ end
+ setSliderSizeAndPosition()
+ end
+
+ local function highLowRecheck()
+ local oldLowY = lowY
+ local oldHighY = highY
+ lowY = nil
+ highY = nil
+ resetHighLow()
+
+ if (lowY ~= oldLowY) or (highY ~= oldHighY) then
+ setSliderSizeAndPosition()
+ end
+ end
+
+ local function descendantChanged(this, prop)
+ if internalChange then return end
+ if not this.Visible then return end
+
+ if prop == "Size" or prop == "Position" then
+ wait()
+ highLowRecheck()
+ end
+ end
+
+ scrollingFrame.DescendantAdded:connect(function(instance)
+ if not instance:IsA("GuiObject") then return end
+
+ if instance.Visible then
+ wait() -- wait a heartbeat for sizes to reconfig
+ highLowRecheck()
+ end
+
+ descendantsChangeConMap[instance] = instance.Changed:connect(function(prop) descendantChanged(instance, prop) end)
+ end)
+
+ scrollingFrame.DescendantRemoving:connect(function(instance)
+ if not instance:IsA("GuiObject") then return end
+ if descendantsChangeConMap[instance] then
+ descendantsChangeConMap[instance]:disconnect()
+ descendantsChangeConMap[instance] = nil
+ end
+ wait() -- wait a heartbeat for sizes to reconfig
+ highLowRecheck()
+ end)
+
+ scrollingFrame.Changed:connect(function(prop)
+ if prop == "AbsoluteSize" then
+ if not highY or not lowY then return end
+
+ highLowRecheck()
+ setSliderSizeAndPosition()
+ end
+ end)
+
+ return scrollingFrame, controlFrame
+end
+
+t.CreateScrollingFrame = function(orderList,scrollStyle)
+ local frame = Instance.new("Frame")
+ frame.Name = "ScrollingFrame"
+ frame.BackgroundTransparency = 1
+ frame.Size = UDim2.new(1,0,1,0)
+
+ local scrollUpButton = Instance.new("ImageButton")
+ scrollUpButton.Name = "ScrollUpButton"
+ scrollUpButton.BackgroundTransparency = 1
+ scrollUpButton.Image = "rbxasset://textures/ui/scrollbuttonUp.png"
+ scrollUpButton.Size = UDim2.new(0,17,0,17)
+
+
+ local scrollDownButton = Instance.new("ImageButton")
+ scrollDownButton.Name = "ScrollDownButton"
+ scrollDownButton.BackgroundTransparency = 1
+ scrollDownButton.Image = "rbxasset://textures/ui/scrollbuttonDown.png"
+ scrollDownButton.Size = UDim2.new(0,17,0,17)
+
+ local scrollbar = Instance.new("ImageButton")
+ scrollbar.Name = "ScrollBar"
+ scrollbar.Image = "rbxasset://textures/ui/scrollbar.png"
+ scrollbar.BackgroundTransparency = 1
+ scrollbar.Size = UDim2.new(0, 18, 0, 150)
+
+ local scrollStamp = 0
+
+ local scrollDrag = Instance.new("ImageButton")
+ scrollDrag.Image = "http://www.roblox.com/asset/?id=61367186"
+ scrollDrag.Size = UDim2.new(1, 0, 0, 16)
+ scrollDrag.BackgroundTransparency = 1
+ scrollDrag.Name = "ScrollDrag"
+ scrollDrag.Active = true
+ scrollDrag.Parent = scrollbar
+
+ local mouseDrag = Instance.new("ImageButton")
+ mouseDrag.Active = false
+ mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0)
+ mouseDrag.AutoButtonColor = false
+ mouseDrag.BackgroundTransparency = 1
+ mouseDrag.Name = "mouseDrag"
+ mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0)
+ mouseDrag.ZIndex = 10
+
+ local style = "simple"
+ if scrollStyle and tostring(scrollStyle) then
+ style = scrollStyle
+ end
+
+ local scrollPosition = 1
+ local rowSize = 0
+ local howManyDisplayed = 0
+
+ local layoutGridScrollBar = function()
+ howManyDisplayed = 0
+ local guiObjects = {}
+ if orderList then
+ for i, child in ipairs(orderList) do
+ if child.Parent == frame then
+ table.insert(guiObjects, child)
+ end
+ end
+ else
+ local children = frame:GetChildren()
+ if children then
+ for i, child in ipairs(children) do
+ if child:IsA("GuiObject") then
+ table.insert(guiObjects, child)
+ end
+ end
+ end
+ end
+ if #guiObjects == 0 then
+ scrollUpButton.Active = false
+ scrollDownButton.Active = false
+ scrollDrag.Active = false
+ scrollPosition = 1
+ return
+ end
+
+ if scrollPosition > #guiObjects then
+ scrollPosition = #guiObjects
+ end
+
+ if scrollPosition < 1 then scrollPosition = 1 end
+
+ local totalPixelsY = frame.AbsoluteSize.Y
+ local pixelsRemainingY = frame.AbsoluteSize.Y
+
+ local totalPixelsX = frame.AbsoluteSize.X
+
+ local xCounter = 0
+ local rowSizeCounter = 0
+ local setRowSize = true
+
+ local pixelsBelowScrollbar = 0
+ local pos = #guiObjects
+
+ local currentRowY = 0
+
+ pos = scrollPosition
+ --count up from current scroll position to fill out grid
+ while pos <= #guiObjects and pixelsBelowScrollbar < totalPixelsY do
+ xCounter = xCounter + guiObjects[pos].AbsoluteSize.X
+ --previous pos was the end of a row
+ if xCounter >= totalPixelsX then
+ pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
+ currentRowY = 0
+ xCounter = guiObjects[pos].AbsoluteSize.X
+ end
+ if guiObjects[pos].AbsoluteSize.Y > currentRowY then
+ currentRowY = guiObjects[pos].AbsoluteSize.Y
+ end
+ pos = pos + 1
+ end
+ --Count wherever current row left off
+ pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
+ currentRowY = 0
+
+ pos = scrollPosition - 1
+ xCounter = 0
+
+ --objects with varying X,Y dimensions can rarely cause minor errors
+ --rechecking every new scrollPosition is necessary to avoid 100% of errors
+
+ --count backwards from current scrollPosition to see if we can add more rows
+ while pixelsBelowScrollbar + currentRowY < totalPixelsY and pos >= 1 do
+ xCounter = xCounter + guiObjects[pos].AbsoluteSize.X
+ rowSizeCounter = rowSizeCounter + 1
+ if xCounter >= totalPixelsX then
+ rowSize = rowSizeCounter - 1
+ rowSizeCounter = 0
+ xCounter = guiObjects[pos].AbsoluteSize.X
+ if pixelsBelowScrollbar + currentRowY <= totalPixelsY then
+ --It fits, so back up our scroll position
+ pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
+ if scrollPosition <= rowSize then
+ scrollPosition = 1
+ break
+ else
+ scrollPosition = scrollPosition - rowSize
+ end
+ currentRowY = 0
+ else
+ break
+ end
+ end
+
+ if guiObjects[pos].AbsoluteSize.Y > currentRowY then
+ currentRowY = guiObjects[pos].AbsoluteSize.Y
+ end
+
+ pos = pos - 1
+ end
+
+ --Do check last time if pos = 0
+ if (pos == 0) and (pixelsBelowScrollbar + currentRowY <= totalPixelsY) then
+ scrollPosition = 1
+ end
+
+ xCounter = 0
+ --pos = scrollPosition
+ rowSizeCounter = 0
+ setRowSize = true
+ local lastChildSize = 0
+
+ local xOffset,yOffset = 0
+ if guiObjects[1] then
+ yOffset = math.ceil(math.floor(math.fmod(totalPixelsY,guiObjects[1].AbsoluteSize.X))/2)
+ xOffset = math.ceil(math.floor(math.fmod(totalPixelsX,guiObjects[1].AbsoluteSize.Y))/2)
+ end
+
+ for i, child in ipairs(guiObjects) do
+ if i < scrollPosition then
+ --print("Hiding " .. child.Name)
+ child.Visible = false
+ else
+ if pixelsRemainingY < 0 then
+ --print("Out of Space " .. child.Name)
+ child.Visible = false
+ else
+ --print("Laying out " .. child.Name)
+ --GuiObject
+ if setRowSize then rowSizeCounter = rowSizeCounter + 1 end
+ if xCounter + child.AbsoluteSize.X >= totalPixelsX then
+ if setRowSize then
+ rowSize = rowSizeCounter - 1
+ setRowSize = false
+ end
+ xCounter = 0
+ pixelsRemainingY = pixelsRemainingY - child.AbsoluteSize.Y
+ end
+ child.Position = UDim2.new(child.Position.X.Scale,xCounter + xOffset, 0, totalPixelsY - pixelsRemainingY + yOffset)
+ xCounter = xCounter + child.AbsoluteSize.X
+ child.Visible = ((pixelsRemainingY - child.AbsoluteSize.Y) >= 0)
+ if child.Visible then
+ howManyDisplayed = howManyDisplayed + 1
+ end
+ lastChildSize = child.AbsoluteSize
+ end
+ end
+ end
+
+ scrollUpButton.Active = (scrollPosition > 1)
+ if lastChildSize == 0 then
+ scrollDownButton.Active = false
+ else
+ scrollDownButton.Active = ((pixelsRemainingY - lastChildSize.Y) < 0)
+ end
+ scrollDrag.Active = #guiObjects > howManyDisplayed
+ scrollDrag.Visible = scrollDrag.Active
+ end
+
+
+
+ local layoutSimpleScrollBar = function()
+ local guiObjects = {}
+ howManyDisplayed = 0
+
+ if orderList then
+ for i, child in ipairs(orderList) do
+ if child.Parent == frame then
+ table.insert(guiObjects, child)
+ end
+ end
+ else
+ local children = frame:GetChildren()
+ if children then
+ for i, child in ipairs(children) do
+ if child:IsA("GuiObject") then
+ table.insert(guiObjects, child)
+ end
+ end
+ end
+ end
+ if #guiObjects == 0 then
+ scrollUpButton.Active = false
+ scrollDownButton.Active = false
+ scrollDrag.Active = false
+ scrollPosition = 1
+ return
+ end
+
+ if scrollPosition > #guiObjects then
+ scrollPosition = #guiObjects
+ end
+
+ local totalPixels = frame.AbsoluteSize.Y
+ local pixelsRemaining = frame.AbsoluteSize.Y
+
+ local pixelsBelowScrollbar = 0
+ local pos = #guiObjects
+ while pixelsBelowScrollbar < totalPixels and pos >= 1 do
+ if pos >= scrollPosition then
+ pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y
+ else
+ if pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y <= totalPixels then
+ --It fits, so back up our scroll position
+ pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y
+ if scrollPosition <= 1 then
+ scrollPosition = 1
+ break
+ else
+ --local ("Backing up ScrollPosition from -- " ..scrollPosition)
+ scrollPosition = scrollPosition - 1
+ end
+ else
+ break
+ end
+ end
+ pos = pos - 1
+ end
+
+ pos = scrollPosition
+ for i, child in ipairs(guiObjects) do
+ if i < scrollPosition then
+ --print("Hiding " .. child.Name)
+ child.Visible = false
+ else
+ if pixelsRemaining < 0 then
+ --print("Out of Space " .. child.Name)
+ child.Visible = false
+ else
+ --print("Laying out " .. child.Name)
+ --GuiObject
+ child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
+ pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
+ if (pixelsRemaining >= 0) then
+ child.Visible = true
+ howManyDisplayed = howManyDisplayed + 1
+ else
+ child.Visible = false
+ end
+ end
+ end
+ end
+ scrollUpButton.Active = (scrollPosition > 1)
+ scrollDownButton.Active = (pixelsRemaining < 0)
+ scrollDrag.Active = #guiObjects > howManyDisplayed
+ scrollDrag.Visible = scrollDrag.Active
+ end
+
+
+ local moveDragger = function()
+ local guiObjects = 0
+ local children = frame:GetChildren()
+ if children then
+ for i, child in ipairs(children) do
+ if child:IsA("GuiObject") then
+ guiObjects = guiObjects + 1
+ end
+ end
+ end
+
+ if not scrollDrag.Parent then return end
+
+ local dragSizeY = scrollDrag.Parent.AbsoluteSize.y * (1/(guiObjects - howManyDisplayed + 1))
+ if dragSizeY < 16 then dragSizeY = 16 end
+ scrollDrag.Size = UDim2.new(scrollDrag.Size.X.Scale,scrollDrag.Size.X.Offset,scrollDrag.Size.Y.Scale,dragSizeY)
+
+ local relativeYPos = (scrollPosition - 1)/(guiObjects - (howManyDisplayed))
+ if relativeYPos > 1 then relativeYPos = 1
+ elseif relativeYPos < 0 then relativeYPos = 0 end
+ local absYPos = 0
+
+ if relativeYPos ~= 0 then
+ absYPos = (relativeYPos * scrollbar.AbsoluteSize.y) - (relativeYPos * scrollDrag.AbsoluteSize.y)
+ end
+
+ scrollDrag.Position = UDim2.new(scrollDrag.Position.X.Scale,scrollDrag.Position.X.Offset,scrollDrag.Position.Y.Scale,absYPos)
+ end
+
+ local reentrancyGuard = false
+ local recalculate = function()
+ if reentrancyGuard then
+ return
+ end
+ reentrancyGuard = true
+ wait()
+ local success, err = nil
+ if style == "grid" then
+ success, err = pcall(function() layoutGridScrollBar() end)
+ elseif style == "simple" then
+ success, err = pcall(function() layoutSimpleScrollBar() end)
+ end
+ if not success then print(err) end
+ moveDragger()
+ reentrancyGuard = false
+ end
+
+ local doScrollUp = function()
+ scrollPosition = (scrollPosition) - rowSize
+ if scrollPosition < 1 then scrollPosition = 1 end
+ recalculate(nil)
+ end
+
+ local doScrollDown = function()
+ scrollPosition = (scrollPosition) + rowSize
+ recalculate(nil)
+ end
+
+ local scrollUp = function(mouseYPos)
+ if scrollUpButton.Active then
+ scrollStamp = tick()
+ local current = scrollStamp
+ local upCon
+ upCon = mouseDrag.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ mouseDrag.Parent = nil
+ upCon:disconnect()
+ end)
+ mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
+ doScrollUp()
+ wait(0.2)
+ local t = tick()
+ local w = 0.1
+ while scrollStamp == current do
+ doScrollUp()
+ if mouseYPos and mouseYPos > scrollDrag.AbsolutePosition.y then
+ break
+ end
+ if not scrollUpButton.Active then break end
+ if tick()-t > 5 then
+ w = 0
+ elseif tick()-t > 2 then
+ w = 0.06
+ end
+ wait(w)
+ end
+ end
+ end
+
+ local scrollDown = function(mouseYPos)
+ if scrollDownButton.Active then
+ scrollStamp = tick()
+ local current = scrollStamp
+ local downCon
+ downCon = mouseDrag.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ mouseDrag.Parent = nil
+ downCon:disconnect()
+ end)
+ mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
+ doScrollDown()
+ wait(0.2)
+ local t = tick()
+ local w = 0.1
+ while scrollStamp == current do
+ doScrollDown()
+ if mouseYPos and mouseYPos < (scrollDrag.AbsolutePosition.y + scrollDrag.AbsoluteSize.x) then
+ break
+ end
+ if not scrollDownButton.Active then break end
+ if tick()-t > 5 then
+ w = 0
+ elseif tick()-t > 2 then
+ w = 0.06
+ end
+ wait(w)
+ end
+ end
+ end
+
+ local y = 0
+ scrollDrag.MouseButton1Down:connect(function(x,y)
+ if scrollDrag.Active then
+ scrollStamp = tick()
+ local mouseOffset = y - scrollDrag.AbsolutePosition.y
+ local dragCon
+ local upCon
+ dragCon = mouseDrag.MouseMoved:connect(function(x,y)
+ local barAbsPos = scrollbar.AbsolutePosition.y
+ local barAbsSize = scrollbar.AbsoluteSize.y
+
+ local dragAbsSize = scrollDrag.AbsoluteSize.y
+ local barAbsOne = barAbsPos + barAbsSize - dragAbsSize
+ y = y - mouseOffset
+ y = y < barAbsPos and barAbsPos or y > barAbsOne and barAbsOne or y
+ y = y - barAbsPos
+
+ local guiObjects = 0
+ local children = frame:GetChildren()
+ if children then
+ for i, child in ipairs(children) do
+ if child:IsA("GuiObject") then
+ guiObjects = guiObjects + 1
+ end
+ end
+ end
+
+ local doublePercent = y/(barAbsSize-dragAbsSize)
+ local rowDiff = rowSize
+ local totalScrollCount = guiObjects - (howManyDisplayed - 1)
+ local newScrollPosition = math.floor((doublePercent * totalScrollCount) + 0.5) + rowDiff
+ if newScrollPosition < scrollPosition then
+ rowDiff = -rowDiff
+ end
+
+ if newScrollPosition < 1 then
+ newScrollPosition = 1
+ end
+
+ scrollPosition = newScrollPosition
+ recalculate(nil)
+ end)
+ upCon = mouseDrag.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ mouseDrag.Parent = nil
+ dragCon:disconnect(); dragCon = nil
+ upCon:disconnect(); drag = nil
+ end)
+ mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
+ end
+ end)
+
+ local scrollMouseCount = 0
+
+ scrollUpButton.MouseButton1Down:connect(
+ function()
+ scrollUp()
+ end)
+ scrollUpButton.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ end)
+
+
+ scrollDownButton.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ end)
+ scrollDownButton.MouseButton1Down:connect(
+ function()
+ scrollDown()
+ end)
+
+ scrollbar.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ end)
+ scrollbar.MouseButton1Down:connect(
+ function(x,y)
+ if y > (scrollDrag.AbsoluteSize.y + scrollDrag.AbsolutePosition.y) then
+ scrollDown(y)
+ elseif y < (scrollDrag.AbsolutePosition.y) then
+ scrollUp(y)
+ end
+ end)
+
+
+ frame.ChildAdded:connect(function()
+ recalculate(nil)
+ end)
+
+ frame.ChildRemoved:connect(function()
+ recalculate(nil)
+ end)
+
+ frame.Changed:connect(
+ function(prop)
+ if prop == "AbsoluteSize" then
+ --Wait a heartbeat for it to sync in
+ recalculate(nil)
+ end
+ end)
+ frame.AncestryChanged:connect(function() recalculate(nil) end)
+
+ return frame, scrollUpButton, scrollDownButton, recalculate, scrollbar
+end
+local function binaryGrow(min, max, fits)
+ if min > max then
+ return min
+ end
+ local biggestLegal = min
+
+ while min <= max do
+ local mid = min + math.floor((max - min) / 2)
+ if fits(mid) and (biggestLegal == nil or biggestLegal < mid) then
+ biggestLegal = mid
+
+ --Try growing
+ min = mid + 1
+ else
+ --Doesn't fit, shrink
+ max = mid - 1
+ end
+ end
+ return biggestLegal
+end
+
+
+local function binaryShrink(min, max, fits)
+ if min > max then
+ return min
+ end
+ local smallestLegal = max
+
+ while min <= max do
+ local mid = min + math.floor((max - min) / 2)
+ if fits(mid) and (smallestLegal == nil or smallestLegal > mid) then
+ smallestLegal = mid
+
+ --It fits, shrink
+ max = mid - 1
+ else
+ --Doesn't fit, grow
+ min = mid + 1
+ end
+ end
+ return smallestLegal
+end
+
+
+local function getGuiOwner(instance)
+ while instance ~= nil do
+ if instance:IsA("ScreenGui") or instance:IsA("BillboardGui") then
+ return instance
+ end
+ instance = instance.Parent
+ end
+ return nil
+end
+
+t.AutoTruncateTextObject = function(textLabel)
+ local text = textLabel.Text
+
+ local fullLabel = textLabel:Clone()
+ fullLabel.Name = "Full" .. textLabel.Name
+ fullLabel.BorderSizePixel = 0
+ fullLabel.BackgroundTransparency = 0
+ fullLabel.Text = text
+ fullLabel.TextXAlignment = Enum.TextXAlignment.Center
+ fullLabel.Position = UDim2.new(0,-3,0,0)
+ fullLabel.Size = UDim2.new(0,100,1,0)
+ fullLabel.Visible = false
+ fullLabel.Parent = textLabel
+
+ local shortText = nil
+ local mouseEnterConnection = nil
+ local mouseLeaveConnection= nil
+
+ local checkForResize = function()
+ if getGuiOwner(textLabel) == nil then
+ return
+ end
+ textLabel.Text = text
+ if textLabel.TextFits then
+ --Tear down the rollover if it is active
+ if mouseEnterConnection then
+ mouseEnterConnection:disconnect()
+ mouseEnterConnection = nil
+ end
+ if mouseLeaveConnection then
+ mouseLeaveConnection:disconnect()
+ mouseLeaveConnection = nil
+ end
+ else
+ local len = string.len(text)
+ textLabel.Text = text .. "~"
+
+ --Shrink the text
+ local textSize = binaryGrow(0, len,
+ function(pos)
+ if pos == 0 then
+ textLabel.Text = "~"
+ else
+ textLabel.Text = string.sub(text, 1, pos) .. "~"
+ end
+ return textLabel.TextFits
+ end)
+ shortText = string.sub(text, 1, textSize) .. "~"
+ textLabel.Text = shortText
+
+ --Make sure the fullLabel fits
+ if not fullLabel.TextFits then
+ --Already too small, grow it really bit to start
+ fullLabel.Size = UDim2.new(0, 10000, 1, 0)
+ end
+
+ --Okay, now try to binary shrink it back down
+ local fullLabelSize = binaryShrink(textLabel.AbsoluteSize.X,fullLabel.AbsoluteSize.X,
+ function(size)
+ fullLabel.Size = UDim2.new(0, size, 1, 0)
+ return fullLabel.TextFits
+ end)
+ fullLabel.Size = UDim2.new(0,fullLabelSize+6,1,0)
+
+ --Now setup the rollover effects, if they are currently off
+ if mouseEnterConnection == nil then
+ mouseEnterConnection = textLabel.MouseEnter:connect(
+ function()
+ fullLabel.ZIndex = textLabel.ZIndex + 1
+ fullLabel.Visible = true
+ --textLabel.Text = ""
+ end)
+ end
+ if mouseLeaveConnection == nil then
+ mouseLeaveConnection = textLabel.MouseLeave:connect(
+ function()
+ fullLabel.Visible = false
+ --textLabel.Text = shortText
+ end)
+ end
+ end
+ end
+ textLabel.AncestryChanged:connect(checkForResize)
+ textLabel.Changed:connect(
+ function(prop)
+ if prop == "AbsoluteSize" then
+ checkForResize()
+ end
+ end)
+
+ checkForResize()
+
+ local function changeText(newText)
+ text = newText
+ fullLabel.Text = text
+ checkForResize()
+ end
+
+ return textLabel, changeText
+end
+
+local function TransitionTutorialPages(fromPage, toPage, transitionFrame, currentPageValue)
+ if fromPage then
+ fromPage.Visible = false
+ if transitionFrame.Visible == false then
+ transitionFrame.Size = fromPage.Size
+ transitionFrame.Position = fromPage.Position
+ end
+ else
+ if transitionFrame.Visible == false then
+ transitionFrame.Size = UDim2.new(0.0,50,0.0,50)
+ transitionFrame.Position = UDim2.new(0.5,-25,0.5,-25)
+ end
+ end
+ transitionFrame.Visible = true
+ currentPageValue.Value = nil
+
+ local newsize, newPosition
+ if toPage then
+ --Make it visible so it resizes
+ toPage.Visible = true
+
+ newSize = toPage.Size
+ newPosition = toPage.Position
+
+ toPage.Visible = false
+ else
+ newSize = UDim2.new(0.0,50,0.0,50)
+ newPosition = UDim2.new(0.5,-25,0.5,-25)
+ end
+ transitionFrame:TweenSizeAndPosition(newSize, newPosition, Enum.EasingDirection.InOut, Enum.EasingStyle.Quad, 0.3, true,
+ function(state)
+ if state == Enum.TweenStatus.Completed then
+ transitionFrame.Visible = false
+ if toPage then
+ toPage.Visible = true
+ currentPageValue.Value = toPage
+ end
+ end
+ end)
+end
+
+t.CreateTutorial = function(name, tutorialKey, createButtons)
+ local frame = Instance.new("Frame")
+ frame.Name = "Tutorial-" .. name
+ frame.BackgroundTransparency = 1
+ frame.Size = UDim2.new(0.6, 0, 0.6, 0)
+ frame.Position = UDim2.new(0.2, 0, 0.2, 0)
+
+ local transitionFrame = Instance.new("Frame")
+ transitionFrame.Name = "TransitionFrame"
+ transitionFrame.Style = Enum.FrameStyle.RobloxRound
+ transitionFrame.Size = UDim2.new(0.6, 0, 0.6, 0)
+ transitionFrame.Position = UDim2.new(0.2, 0, 0.2, 0)
+ transitionFrame.Visible = false
+ transitionFrame.Parent = frame
+
+ local currentPageValue = Instance.new("ObjectValue")
+ currentPageValue.Name = "CurrentTutorialPage"
+ currentPageValue.Value = nil
+ currentPageValue.Parent = frame
+
+ local boolValue = Instance.new("BoolValue")
+ boolValue.Name = "Buttons"
+ boolValue.Value = createButtons
+ boolValue.Parent = frame
+
+ local pages = Instance.new("Frame")
+ pages.Name = "Pages"
+ pages.BackgroundTransparency = 1
+ pages.Size = UDim2.new(1,0,1,0)
+ pages.Parent = frame
+
+ local function getVisiblePageAndHideOthers()
+ local visiblePage = nil
+ local children = pages:GetChildren()
+ if children then
+ for i,child in ipairs(children) do
+ if child.Visible then
+ if visiblePage then
+ child.Visible = false
+ else
+ visiblePage = child
+ end
+ end
+ end
+ end
+ return visiblePage
+ end
+
+ local showTutorial = function(alwaysShow)
+ if alwaysShow or UserSettings().GameSettings:GetTutorialState(tutorialKey) == false then
+ print("Showing tutorial-",tutorialKey)
+ local currentTutorialPage = getVisiblePageAndHideOthers()
+
+ local firstPage = pages:FindFirstChild("TutorialPage1")
+ if firstPage then
+ TransitionTutorialPages(currentTutorialPage, firstPage, transitionFrame, currentPageValue)
+ else
+ error("Could not find TutorialPage1")
+ end
+ end
+ end
+
+ local dismissTutorial = function()
+ local currentTutorialPage = getVisiblePageAndHideOthers()
+
+ if currentTutorialPage then
+ TransitionTutorialPages(currentTutorialPage, nil, transitionFrame, currentPageValue)
+ end
+
+ UserSettings().GameSettings:SetTutorialState(tutorialKey, true)
+ end
+
+ local gotoPage = function(pageNum)
+ local page = pages:FindFirstChild("TutorialPage" .. pageNum)
+ local currentTutorialPage = getVisiblePageAndHideOthers()
+ TransitionTutorialPages(currentTutorialPage, page, transitionFrame, currentPageValue)
+ end
+
+ return frame, showTutorial, dismissTutorial, gotoPage
+end
+
+local function CreateBasicTutorialPage(name, handleResize, skipTutorial, giveDoneButton)
+ local frame = Instance.new("Frame")
+ frame.Name = "TutorialPage"
+ frame.Style = Enum.FrameStyle.RobloxRound
+ frame.Size = UDim2.new(0.6, 0, 0.6, 0)
+ frame.Position = UDim2.new(0.2, 0, 0.2, 0)
+ frame.Visible = false
+
+ local frameHeader = Instance.new("TextLabel")
+ frameHeader.Name = "Header"
+ frameHeader.Text = name
+ frameHeader.BackgroundTransparency = 1
+ frameHeader.FontSize = Enum.FontSize.Size24
+ frameHeader.Font = Enum.Font.ArialBold
+ frameHeader.TextColor3 = Color3.new(1,1,1)
+ frameHeader.TextXAlignment = Enum.TextXAlignment.Center
+ frameHeader.TextWrap = true
+ frameHeader.Size = UDim2.new(1,-55, 0, 22)
+ frameHeader.Position = UDim2.new(0,0,0,0)
+ frameHeader.Parent = frame
+
+ local skipButton = Instance.new("ImageButton")
+ skipButton.Name = "SkipButton"
+ skipButton.AutoButtonColor = false
+ skipButton.BackgroundTransparency = 1
+ skipButton.Image = "rbxasset://textures/ui/closeButton.png"
+ skipButton.MouseButton1Click:connect(function()
+ skipTutorial()
+ end)
+ skipButton.MouseEnter:connect(function()
+ skipButton.Image = "rbxasset://textures/ui/closeButton_dn.png"
+ end)
+ skipButton.MouseLeave:connect(function()
+ skipButton.Image = "rbxasset://textures/ui/closeButton.png"
+ end)
+ skipButton.Size = UDim2.new(0, 25, 0, 25)
+ skipButton.Position = UDim2.new(1, -25, 0, 0)
+ skipButton.Parent = frame
+
+
+ if giveDoneButton then
+ local doneButton = Instance.new("TextButton")
+ doneButton.Name = "DoneButton"
+ doneButton.Style = Enum.ButtonStyle.RobloxButtonDefault
+ doneButton.Text = "Done"
+ doneButton.TextColor3 = Color3.new(1,1,1)
+ doneButton.Font = Enum.Font.ArialBold
+ doneButton.FontSize = Enum.FontSize.Size18
+ doneButton.Size = UDim2.new(0,100,0,50)
+ doneButton.Position = UDim2.new(0.5,-50,1,-50)
+
+ if skipTutorial then
+ doneButton.MouseButton1Click:connect(function() skipTutorial() end)
+ end
+
+ doneButton.Parent = frame
+ end
+
+ local innerFrame = Instance.new("Frame")
+ innerFrame.Name = "ContentFrame"
+ innerFrame.BackgroundTransparency = 1
+ innerFrame.Position = UDim2.new(0,0,0,25)
+ innerFrame.Parent = frame
+
+ local nextButton = Instance.new("TextButton")
+ nextButton.Name = "NextButton"
+ nextButton.Text = "Next"
+ nextButton.TextColor3 = Color3.new(1,1,1)
+ nextButton.Font = Enum.Font.Arial
+ nextButton.FontSize = Enum.FontSize.Size18
+ nextButton.Style = Enum.ButtonStyle.RobloxButtonDefault
+ nextButton.Size = UDim2.new(0,80, 0, 32)
+ nextButton.Position = UDim2.new(0.5, 5, 1, -32)
+ nextButton.Active = false
+ nextButton.Visible = false
+ nextButton.Parent = frame
+
+ local prevButton = Instance.new("TextButton")
+ prevButton.Name = "PrevButton"
+ prevButton.Text = "Previous"
+ prevButton.TextColor3 = Color3.new(1,1,1)
+ prevButton.Font = Enum.Font.Arial
+ prevButton.FontSize = Enum.FontSize.Size18
+ prevButton.Style = Enum.ButtonStyle.RobloxButton
+ prevButton.Size = UDim2.new(0,80, 0, 32)
+ prevButton.Position = UDim2.new(0.5, -85, 1, -32)
+ prevButton.Active = false
+ prevButton.Visible = false
+ prevButton.Parent = frame
+
+ if giveDoneButton then
+ innerFrame.Size = UDim2.new(1,0,1,-75)
+ else
+ innerFrame.Size = UDim2.new(1,0,1,-22)
+ end
+
+ local parentConnection = nil
+
+ local function basicHandleResize()
+ if frame.Visible and frame.Parent then
+ local maxSize = math.min(frame.Parent.AbsoluteSize.X, frame.Parent.AbsoluteSize.Y)
+ handleResize(200,maxSize)
+ end
+ end
+
+ frame.Changed:connect(
+ function(prop)
+ if prop == "Parent" then
+ if parentConnection ~= nil then
+ parentConnection:disconnect()
+ parentConnection = nil
+ end
+ if frame.Parent and frame.Parent:IsA("GuiObject") then
+ parentConnection = frame.Parent.Changed:connect(
+ function(parentProp)
+ if parentProp == "AbsoluteSize" then
+ wait()
+ basicHandleResize()
+ end
+ end)
+ basicHandleResize()
+ end
+ end
+
+ if prop == "Visible" then
+ basicHandleResize()
+ end
+ end)
+
+ return frame, innerFrame
+end
+
+t.CreateTextTutorialPage = function(name, text, skipTutorialFunc)
+ local frame = nil
+ local contentFrame = nil
+
+ local textLabel = Instance.new("TextLabel")
+ textLabel.BackgroundTransparency = 1
+ textLabel.TextColor3 = Color3.new(1,1,1)
+ textLabel.Text = text
+ textLabel.TextWrap = true
+ textLabel.TextXAlignment = Enum.TextXAlignment.Left
+ textLabel.TextYAlignment = Enum.TextYAlignment.Center
+ textLabel.Font = Enum.Font.Arial
+ textLabel.FontSize = Enum.FontSize.Size14
+ textLabel.Size = UDim2.new(1,0,1,0)
+
+ local function handleResize(minSize, maxSize)
+ size = binaryShrink(minSize, maxSize,
+ function(size)
+ frame.Size = UDim2.new(0, size, 0, size)
+ return textLabel.TextFits
+ end)
+ frame.Size = UDim2.new(0, size, 0, size)
+ frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2)
+ end
+
+ frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc)
+ textLabel.Parent = contentFrame
+
+ return frame
+end
+
+t.CreateImageTutorialPage = function(name, imageAsset, x, y, skipTutorialFunc, giveDoneButton)
+ local frame = nil
+ local contentFrame = nil
+
+ local imageLabel = Instance.new("ImageLabel")
+ imageLabel.BackgroundTransparency = 1
+ imageLabel.Image = imageAsset
+ imageLabel.Size = UDim2.new(0,x,0,y)
+ imageLabel.Position = UDim2.new(0.5,-x/2,0.5,-y/2)
+
+ local function handleResize(minSize, maxSize)
+ size = binaryShrink(minSize, maxSize,
+ function(size)
+ return size >= x and size >= y
+ end)
+ if size >= x and size >= y then
+ imageLabel.Size = UDim2.new(0,x, 0,y)
+ imageLabel.Position = UDim2.new(0.5,-x/2, 0.5, -y/2)
+ else
+ if x > y then
+ --X is limiter, so
+ imageLabel.Size = UDim2.new(1,0,y/x,0)
+ imageLabel.Position = UDim2.new(0,0, 0.5 - (y/x)/2, 0)
+ else
+ --Y is limiter
+ imageLabel.Size = UDim2.new(x/y,0,1, 0)
+ imageLabel.Position = UDim2.new(0.5-(x/y)/2, 0, 0, 0)
+ end
+ end
+ size = size + 50
+ frame.Size = UDim2.new(0, size, 0, size)
+ frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2)
+ end
+
+ frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc, giveDoneButton)
+ imageLabel.Parent = contentFrame
+
+ return frame
+end
+
+t.AddTutorialPage = function(tutorial, tutorialPage)
+ local transitionFrame = tutorial.TransitionFrame
+ local currentPageValue = tutorial.CurrentTutorialPage
+
+ if not tutorial.Buttons.Value then
+ tutorialPage.NextButton.Parent = nil
+ tutorialPage.PrevButton.Parent = nil
+ end
+
+ local children = tutorial.Pages:GetChildren()
+ if children and #children > 0 then
+ tutorialPage.Name = "TutorialPage" .. (#children+1)
+ local previousPage = children[#children]
+ if not previousPage:IsA("GuiObject") then
+ error("All elements under Pages must be GuiObjects")
+ end
+
+ if tutorial.Buttons.Value then
+ if previousPage.NextButton.Active then
+ error("NextButton already Active on previousPage, please only add pages with RbxGui.AddTutorialPage function")
+ end
+ previousPage.NextButton.MouseButton1Click:connect(
+ function()
+ TransitionTutorialPages(previousPage, tutorialPage, transitionFrame, currentPageValue)
+ end)
+ previousPage.NextButton.Active = true
+ previousPage.NextButton.Visible = true
+
+ if tutorialPage.PrevButton.Active then
+ error("PrevButton already Active on tutorialPage, please only add pages with RbxGui.AddTutorialPage function")
+ end
+ tutorialPage.PrevButton.MouseButton1Click:connect(
+ function()
+ TransitionTutorialPages(tutorialPage, previousPage, transitionFrame, currentPageValue)
+ end)
+ tutorialPage.PrevButton.Active = true
+ tutorialPage.PrevButton.Visible = true
+ end
+
+ tutorialPage.Parent = tutorial.Pages
+ else
+ --First child
+ tutorialPage.Name = "TutorialPage1"
+ tutorialPage.Parent = tutorial.Pages
+ end
+end
+
+t.CreateSetPanel = function(userIdsForSets, objectSelected, dialogClosed, size, position, showAdminCategories, useAssetVersionId)
+
+ if not userIdsForSets then
+ error("CreateSetPanel: userIdsForSets (first arg) is nil, should be a table of number ids")
+ end
+ if type(userIdsForSets) ~= "table" and type(userIdsForSets) ~= "userdata" then
+ error("CreateSetPanel: userIdsForSets (first arg) is of type " ..type(userIdsForSets) .. ", should be of type table or userdata")
+ end
+ if not objectSelected then
+ error("CreateSetPanel: objectSelected (second arg) is nil, should be a callback function!")
+ end
+ if type(objectSelected) ~= "function" then
+ error("CreateSetPanel: objectSelected (second arg) is of type " .. type(objectSelected) .. ", should be of type function!")
+ end
+ if dialogClosed and type(dialogClosed) ~= "function" then
+ error("CreateSetPanel: dialogClosed (third arg) is of type " .. type(dialogClosed) .. ", should be of type function!")
+ end
+
+ if showAdminCategories == nil then -- by default, don't show beta sets
+ showAdminCategories = false
+ end
+
+ local arrayPosition = 1
+ local insertButtons = {}
+ local insertButtonCons = {}
+ local contents = nil
+ local setGui = nil
+
+ -- used for water selections
+ local waterForceDirection = "NegX"
+ local waterForce = "None"
+ local waterGui, waterTypeChangedEvent = nil
+
+ local Data = {}
+ Data.CurrentCategory = nil
+ Data.Category = {}
+ local SetCache = {}
+
+ local userCategoryButtons = nil
+
+ local buttonWidth = 64
+ local buttonHeight = buttonWidth
+
+ local SmallThumbnailUrl = nil
+ local LargeThumbnailUrl = nil
+ local BaseUrl = game:GetService("ContentProvider").BaseUrl:lower()
+
+ if useAssetVersionId then
+ LargeThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&assetversionid="
+ SmallThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&assetversionid="
+ else
+ LargeThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&aid="
+ SmallThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&aid="
+ end
+
+ local function drillDownSetZIndex(parent, index)
+ local children = parent:GetChildren()
+ for i = 1, #children do
+ if children[i]:IsA("GuiObject") then
+ children[i].ZIndex = index
+ end
+ drillDownSetZIndex(children[i], index)
+ end
+ end
+
+ -- for terrain stamping
+ local currTerrainDropDownFrame = nil
+ local terrainShapes = {"Block","Vertical Ramp","Corner Wedge","Inverse Corner Wedge","Horizontal Ramp","Auto-Wedge"}
+ local terrainShapeMap = {}
+ for i = 1, #terrainShapes do
+ terrainShapeMap[terrainShapes[i]] = i - 1
+ end
+ terrainShapeMap[terrainShapes[#terrainShapes]] = 6
+
+ local function createWaterGui()
+ local waterForceDirections = {"NegX","X","NegY","Y","NegZ","Z"}
+ local waterForces = {"None", "Small", "Medium", "Strong", "Max"}
+
+ local waterFrame = Instance.new("Frame")
+ waterFrame.Name = "WaterFrame"
+ waterFrame.Style = Enum.FrameStyle.RobloxSquare
+ waterFrame.Size = UDim2.new(0,150,0,110)
+ waterFrame.Visible = false
+
+ local waterForceLabel = Instance.new("TextLabel")
+ waterForceLabel.Name = "WaterForceLabel"
+ waterForceLabel.BackgroundTransparency = 1
+ waterForceLabel.Size = UDim2.new(1,0,0,12)
+ waterForceLabel.Font = Enum.Font.ArialBold
+ waterForceLabel.FontSize = Enum.FontSize.Size12
+ waterForceLabel.TextColor3 = Color3.new(1,1,1)
+ waterForceLabel.TextXAlignment = Enum.TextXAlignment.Left
+ waterForceLabel.Text = "Water Force"
+ waterForceLabel.Parent = waterFrame
+
+ local waterForceDirLabel = waterForceLabel:Clone()
+ waterForceDirLabel.Name = "WaterForceDirectionLabel"
+ waterForceDirLabel.Text = "Water Force Direction"
+ waterForceDirLabel.Position = UDim2.new(0,0,0,50)
+ waterForceDirLabel.Parent = waterFrame
+
+ local waterTypeChangedEvent = Instance.new("BindableEvent",waterFrame)
+ waterTypeChangedEvent.Name = "WaterTypeChangedEvent"
+
+ local waterForceDirectionSelectedFunc = function(newForceDirection)
+ waterForceDirection = newForceDirection
+ waterTypeChangedEvent:Fire({waterForce, waterForceDirection})
+ end
+ local waterForceSelectedFunc = function(newForce)
+ waterForce = newForce
+ waterTypeChangedEvent:Fire({waterForce, waterForceDirection})
+ end
+
+ local waterForceDirectionDropDown, forceWaterDirectionSelection = t.CreateDropDownMenu(waterForceDirections, waterForceDirectionSelectedFunc)
+ waterForceDirectionDropDown.Size = UDim2.new(1,0,0,25)
+ waterForceDirectionDropDown.Position = UDim2.new(0,0,1,3)
+ forceWaterDirectionSelection("NegX")
+ waterForceDirectionDropDown.Parent = waterForceDirLabel
+
+ local waterForceDropDown, forceWaterForceSelection = t.CreateDropDownMenu(waterForces, waterForceSelectedFunc)
+ forceWaterForceSelection("None")
+ waterForceDropDown.Size = UDim2.new(1,0,0,25)
+ waterForceDropDown.Position = UDim2.new(0,0,1,3)
+ waterForceDropDown.Parent = waterForceLabel
+
+ return waterFrame, waterTypeChangedEvent
+ end
+
+ -- Helper Function that contructs gui elements
+ local function createSetGui()
+
+ local setGui = Instance.new("ScreenGui")
+ setGui.Name = "SetGui"
+
+ local setPanel = Instance.new("Frame")
+ setPanel.Name = "SetPanel"
+ setPanel.Active = true
+ setPanel.BackgroundTransparency = 1
+ if position then
+ setPanel.Position = position
+ else
+ setPanel.Position = UDim2.new(0.2, 29, 0.1, 24)
+ end
+ if size then
+ setPanel.Size = size
+ else
+ setPanel.Size = UDim2.new(0.6, -58, 0.64, 0)
+ end
+ setPanel.Style = Enum.FrameStyle.RobloxRound
+ setPanel.ZIndex = 6
+ setPanel.Parent = setGui
+
+ -- Children of SetPanel
+ local itemPreview = Instance.new("Frame")
+ itemPreview.Name = "ItemPreview"
+ itemPreview.BackgroundTransparency = 1
+ itemPreview.Position = UDim2.new(0.8,5,0.085,0)
+ itemPreview.Size = UDim2.new(0.21,0,0.9,0)
+ itemPreview.ZIndex = 6
+ itemPreview.Parent = setPanel
+
+ -- Children of ItemPreview
+ local textPanel = Instance.new("Frame")
+ textPanel.Name = "TextPanel"
+ textPanel.BackgroundTransparency = 1
+ textPanel.Position = UDim2.new(0,0,0.45,0)
+ textPanel.Size = UDim2.new(1,0,0.55,0)
+ textPanel.ZIndex = 6
+ textPanel.Parent = itemPreview
+
+ -- Children of TextPanel
+ local rolloverText = Instance.new("TextLabel")
+ rolloverText.Name = "RolloverText"
+ rolloverText.BackgroundTransparency = 1
+ rolloverText.Size = UDim2.new(1,0,0,48)
+ rolloverText.ZIndex = 6
+ rolloverText.Font = Enum.Font.ArialBold
+ rolloverText.FontSize = Enum.FontSize.Size24
+ rolloverText.Text = ""
+ rolloverText.TextColor3 = Color3.new(1,1,1)
+ rolloverText.TextWrap = true
+ rolloverText.TextXAlignment = Enum.TextXAlignment.Left
+ rolloverText.TextYAlignment = Enum.TextYAlignment.Top
+ rolloverText.Parent = textPanel
+
+ local largePreview = Instance.new("ImageLabel")
+ largePreview.Name = "LargePreview"
+ largePreview.BackgroundTransparency = 1
+ largePreview.Image = ""
+ largePreview.Size = UDim2.new(1,0,0,170)
+ largePreview.ZIndex = 6
+ largePreview.Parent = itemPreview
+
+ local sets = Instance.new("Frame")
+ sets.Name = "Sets"
+ sets.BackgroundTransparency = 1
+ sets.Position = UDim2.new(0,0,0,5)
+ sets.Size = UDim2.new(0.23,0,1,-5)
+ sets.ZIndex = 6
+ sets.Parent = setPanel
+
+ -- Children of Sets
+ local line = Instance.new("Frame")
+ line.Name = "Line"
+ line.BackgroundColor3 = Color3.new(1,1,1)
+ line.BackgroundTransparency = 0.7
+ line.BorderSizePixel = 0
+ line.Position = UDim2.new(1,-3,0.06,0)
+ line.Size = UDim2.new(0,3,0.9,0)
+ line.ZIndex = 6
+ line.Parent = sets
+
+ local setsLists, controlFrame = t.CreateTrueScrollingFrame()
+ setsLists.Size = UDim2.new(1,-6,0.94,0)
+ setsLists.Position = UDim2.new(0,0,0.06,0)
+ setsLists.BackgroundTransparency = 1
+ setsLists.Name = "SetsLists"
+ setsLists.ZIndex = 6
+ setsLists.Parent = sets
+ drillDownSetZIndex(controlFrame, 7)
+
+ local setsHeader = Instance.new("TextLabel")
+ setsHeader.Name = "SetsHeader"
+ setsHeader.BackgroundTransparency = 1
+ setsHeader.Size = UDim2.new(0,47,0,24)
+ setsHeader.ZIndex = 6
+ setsHeader.Font = Enum.Font.ArialBold
+ setsHeader.FontSize = Enum.FontSize.Size24
+ setsHeader.Text = "Sets"
+ setsHeader.TextColor3 = Color3.new(1,1,1)
+ setsHeader.TextXAlignment = Enum.TextXAlignment.Left
+ setsHeader.TextYAlignment = Enum.TextYAlignment.Top
+ setsHeader.Parent = sets
+
+ local cancelButton = Instance.new("TextButton")
+ cancelButton.Name = "CancelButton"
+ cancelButton.Position = UDim2.new(1,-32,0,-2)
+ cancelButton.Size = UDim2.new(0,34,0,34)
+ cancelButton.Style = Enum.ButtonStyle.RobloxButtonDefault
+ cancelButton.ZIndex = 6
+ cancelButton.Text = ""
+ cancelButton.Modal = true
+ cancelButton.Parent = setPanel
+
+ -- Children of Cancel Button
+ local cancelImage = Instance.new("ImageLabel")
+ cancelImage.Name = "CancelImage"
+ cancelImage.BackgroundTransparency = 1
+ cancelImage.Image = "http://www.roblox.com/asset/?id=54135717"
+ cancelImage.Position = UDim2.new(0,-2,0,-2)
+ cancelImage.Size = UDim2.new(0,16,0,16)
+ cancelImage.ZIndex = 6
+ cancelImage.Parent = cancelButton
+
+ return setGui
+ end
+
+ local function createSetButton(text)
+ local setButton = Instance.new("TextButton")
+
+ if text then setButton.Text = text
+ else setButton.Text = "" end
+
+ setButton.AutoButtonColor = false
+ setButton.BackgroundTransparency = 1
+ setButton.BackgroundColor3 = Color3.new(1,1,1)
+ setButton.BorderSizePixel = 0
+ setButton.Size = UDim2.new(1,-5,0,18)
+ setButton.ZIndex = 6
+ setButton.Visible = false
+ setButton.Font = Enum.Font.Arial
+ setButton.FontSize = Enum.FontSize.Size18
+ setButton.TextColor3 = Color3.new(1,1,1)
+ setButton.TextXAlignment = Enum.TextXAlignment.Left
+
+ return setButton
+ end
+
+ local function buildSetButton(name, setId, setImageId, i, count)
+ local button = createSetButton(name)
+ button.Text = name
+ button.Name = "SetButton"
+ button.Visible = true
+
+ local setValue = Instance.new("IntValue")
+ setValue.Name = "SetId"
+ setValue.Value = setId
+ setValue.Parent = button
+
+ local setName = Instance.new("StringValue")
+ setName.Name = "SetName"
+ setName.Value = name
+ setName.Parent = button
+
+ return button
+ end
+
+ local function processCategory(sets)
+ local setButtons = {}
+ local numSkipped = 0
+ for i = 1, #sets do
+ if not showAdminCategories and sets[i].Name == "Beta" then
+ numSkipped = numSkipped + 1
+ else
+ setButtons[i - numSkipped] = buildSetButton(sets[i].Name, sets[i].CategoryId, sets[i].ImageAssetId, i - numSkipped, #sets)
+ end
+ end
+ return setButtons
+ end
+
+ local function handleResize()
+ wait() -- neccessary to insure heartbeat happened
+
+ local itemPreview = setGui.SetPanel.ItemPreview
+
+ itemPreview.LargePreview.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.X)
+ itemPreview.LargePreview.Position = UDim2.new(0.5,-itemPreview.LargePreview.AbsoluteSize.X/2,0,0)
+ itemPreview.TextPanel.Position = UDim2.new(0,0,0,itemPreview.LargePreview.AbsoluteSize.Y)
+ itemPreview.TextPanel.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.Y - itemPreview.LargePreview.AbsoluteSize.Y)
+ end
+
+ local function makeInsertAssetButton()
+ local insertAssetButtonExample = Instance.new("Frame")
+ insertAssetButtonExample.Name = "InsertAssetButtonExample"
+ insertAssetButtonExample.Position = UDim2.new(0,128,0,64)
+ insertAssetButtonExample.Size = UDim2.new(0,64,0,64)
+ insertAssetButtonExample.BackgroundTransparency = 1
+ insertAssetButtonExample.ZIndex = 6
+ insertAssetButtonExample.Visible = false
+
+ local assetId = Instance.new("IntValue")
+ assetId.Name = "AssetId"
+ assetId.Value = 0
+ assetId.Parent = insertAssetButtonExample
+
+ local assetName = Instance.new("StringValue")
+ assetName.Name = "AssetName"
+ assetName.Value = ""
+ assetName.Parent = insertAssetButtonExample
+
+ local button = Instance.new("TextButton")
+ button.Name = "Button"
+ button.Text = ""
+ button.Style = Enum.ButtonStyle.RobloxButton
+ button.Position = UDim2.new(0.025,0,0.025,0)
+ button.Size = UDim2.new(0.95,0,0.95,0)
+ button.ZIndex = 6
+ button.Parent = insertAssetButtonExample
+
+ local buttonImage = Instance.new("ImageLabel")
+ buttonImage.Name = "ButtonImage"
+ buttonImage.Image = ""
+ buttonImage.Position = UDim2.new(0,-7,0,-7)
+ buttonImage.Size = UDim2.new(1,14,1,14)
+ buttonImage.BackgroundTransparency = 1
+ buttonImage.ZIndex = 7
+ buttonImage.Parent = button
+
+ local configIcon = buttonImage:clone()
+ configIcon.Name = "ConfigIcon"
+ configIcon.Visible = false
+ configIcon.Position = UDim2.new(1,-23,1,-24)
+ configIcon.Size = UDim2.new(0,16,0,16)
+ configIcon.Image = ""
+ configIcon.ZIndex = 6
+ configIcon.Parent = insertAssetButtonExample
+
+ return insertAssetButtonExample
+ end
+
+ local function showLargePreview(insertButton)
+ if insertButton:FindFirstChild("AssetId") then
+ delay(0,function()
+ game:GetService("ContentProvider"):Preload(LargeThumbnailUrl .. tostring(insertButton.AssetId.Value))
+ setGui.SetPanel.ItemPreview.LargePreview.Image = LargeThumbnailUrl .. tostring(insertButton.AssetId.Value)
+ end)
+ end
+ if insertButton:FindFirstChild("AssetName") then
+ setGui.SetPanel.ItemPreview.TextPanel.RolloverText.Text = insertButton.AssetName.Value
+ end
+ end
+
+ local function selectTerrainShape(shape)
+ if currTerrainDropDownFrame then
+ objectSelected(tostring(currTerrainDropDownFrame.AssetName.Value), tonumber(currTerrainDropDownFrame.AssetId.Value), shape)
+ end
+ end
+
+ local function createTerrainTypeButton(name, parent)
+ local dropDownTextButton = Instance.new("TextButton")
+ dropDownTextButton.Name = name .. "Button"
+ dropDownTextButton.Font = Enum.Font.ArialBold
+ dropDownTextButton.FontSize = Enum.FontSize.Size14
+ dropDownTextButton.BorderSizePixel = 0
+ dropDownTextButton.TextColor3 = Color3.new(1,1,1)
+ dropDownTextButton.Text = name
+ dropDownTextButton.TextXAlignment = Enum.TextXAlignment.Left
+ dropDownTextButton.BackgroundTransparency = 1
+ dropDownTextButton.ZIndex = parent.ZIndex + 1
+ dropDownTextButton.Size = UDim2.new(0,parent.Size.X.Offset - 2,0,16)
+ dropDownTextButton.Position = UDim2.new(0,1,0,0)
+
+ dropDownTextButton.MouseEnter:connect(function()
+ dropDownTextButton.BackgroundTransparency = 0
+ dropDownTextButton.TextColor3 = Color3.new(0,0,0)
+ end)
+
+ dropDownTextButton.MouseLeave:connect(function()
+ dropDownTextButton.BackgroundTransparency = 1
+ dropDownTextButton.TextColor3 = Color3.new(1,1,1)
+ end)
+
+ dropDownTextButton.MouseButton1Click:connect(function()
+ dropDownTextButton.BackgroundTransparency = 1
+ dropDownTextButton.TextColor3 = Color3.new(1,1,1)
+ if dropDownTextButton.Parent and dropDownTextButton.Parent:IsA("GuiObject") then
+ dropDownTextButton.Parent.Visible = false
+ end
+ selectTerrainShape(terrainShapeMap[dropDownTextButton.Text])
+ end)
+
+ return dropDownTextButton
+ end
+
+ local function createTerrainDropDownMenu(zIndex)
+ local dropDown = Instance.new("Frame")
+ dropDown.Name = "TerrainDropDown"
+ dropDown.BackgroundColor3 = Color3.new(0,0,0)
+ dropDown.BorderColor3 = Color3.new(1,0,0)
+ dropDown.Size = UDim2.new(0,200,0,0)
+ dropDown.Visible = false
+ dropDown.ZIndex = zIndex
+ dropDown.Parent = setGui
+
+ for i = 1, #terrainShapes do
+ local shapeButton = createTerrainTypeButton(terrainShapes[i],dropDown)
+ shapeButton.Position = UDim2.new(0,1,0,(i - 1) * (shapeButton.Size.Y.Offset))
+ shapeButton.Parent = dropDown
+ dropDown.Size = UDim2.new(0,200,0,dropDown.Size.Y.Offset + (shapeButton.Size.Y.Offset))
+ end
+
+ dropDown.MouseLeave:connect(function()
+ dropDown.Visible = false
+ end)
+ end
+
+
+ local function createDropDownMenuButton(parent)
+ local dropDownButton = Instance.new("ImageButton")
+ dropDownButton.Name = "DropDownButton"
+ dropDownButton.Image = "http://www.roblox.com/asset/?id=67581509"
+ dropDownButton.BackgroundTransparency = 1
+ dropDownButton.Size = UDim2.new(0,16,0,16)
+ dropDownButton.Position = UDim2.new(1,-24,0,6)
+ dropDownButton.ZIndex = parent.ZIndex + 2
+ dropDownButton.Parent = parent
+
+ if not setGui:FindFirstChild("TerrainDropDown") then
+ createTerrainDropDownMenu(8)
+ end
+
+ dropDownButton.MouseButton1Click:connect(function()
+ setGui.TerrainDropDown.Visible = true
+ setGui.TerrainDropDown.Position = UDim2.new(0,parent.AbsolutePosition.X,0,parent.AbsolutePosition.Y)
+ currTerrainDropDownFrame = parent
+ end)
+ end
+
+ local function buildInsertButton()
+ local insertButton = makeInsertAssetButton()
+ insertButton.Name = "InsertAssetButton"
+ insertButton.Visible = true
+
+ if Data.Category[Data.CurrentCategory].SetName == "High Scalability" then
+ createDropDownMenuButton(insertButton)
+ end
+
+ local lastEnter = nil
+ local mouseEnterCon = insertButton.MouseEnter:connect(function()
+ lastEnter = insertButton
+ delay(0.1,function()
+ if lastEnter == insertButton then
+ showLargePreview(insertButton)
+ end
+ end)
+ end)
+ return insertButton, mouseEnterCon
+ end
+
+ local function realignButtonGrid(columns)
+ local x = 0
+ local y = 0
+ for i = 1, #insertButtons do
+ insertButtons[i].Position = UDim2.new(0, buttonWidth * x, 0, buttonHeight * y)
+ x = x + 1
+ if x >= columns then
+ x = 0
+ y = y + 1
+ end
+ end
+ end
+
+ local function setInsertButtonImageBehavior(insertFrame, visible, name, assetId)
+ if visible then
+ insertFrame.AssetName.Value = name
+ insertFrame.AssetId.Value = assetId
+ local newImageUrl = SmallThumbnailUrl .. assetId
+ if newImageUrl ~= insertFrame.Button.ButtonImage.Image then
+ delay(0,function()
+ game:GetService("ContentProvider"):Preload(SmallThumbnailUrl .. assetId)
+ if insertFrame:findFirstChild("Button") then
+ insertFrame.Button.ButtonImage.Image = SmallThumbnailUrl .. assetId
+ end
+ end)
+ end
+ table.insert(insertButtonCons,
+ insertFrame.Button.MouseButton1Click:connect(function()
+ -- special case for water, show water selection gui
+ local isWaterSelected = (name == "Water") and (Data.Category[Data.CurrentCategory].SetName == "High Scalability")
+ waterGui.Visible = isWaterSelected
+ if isWaterSelected then
+ objectSelected(name, tonumber(assetId), nil)
+ else
+ objectSelected(name, tonumber(assetId))
+ end
+ end)
+ )
+ insertFrame.Visible = true
+ else
+ insertFrame.Visible = false
+ end
+ end
+
+ local function loadSectionOfItems(setGui, rows, columns)
+ local pageSize = rows * columns
+
+ if arrayPosition > #contents then return end
+
+ local origArrayPos = arrayPosition
+
+ local yCopy = 0
+ for i = 1, pageSize + 1 do
+ if arrayPosition >= #contents + 1 then
+ break
+ end
+
+ local buttonCon
+ insertButtons[arrayPosition], buttonCon = buildInsertButton()
+ table.insert(insertButtonCons,buttonCon)
+ insertButtons[arrayPosition].Parent = setGui.SetPanel.ItemsFrame
+ arrayPosition = arrayPosition + 1
+ end
+ realignButtonGrid(columns)
+
+ local indexCopy = origArrayPos
+ for index = origArrayPos, arrayPosition do
+ if insertButtons[index] then
+ if contents[index] then
+
+ -- we don't want water to have a drop down button
+ if contents[index].Name == "Water" then
+ if Data.Category[Data.CurrentCategory].SetName == "High Scalability" then
+ insertButtons[index]:FindFirstChild("DropDownButton",true):Destroy()
+ end
+ end
+
+ local assetId
+ if useAssetVersionId then
+ assetId = contents[index].AssetVersionId
+ else
+ assetId = contents[index].AssetId
+ end
+ setInsertButtonImageBehavior(insertButtons[index], true, contents[index].Name, assetId)
+ else
+ break
+ end
+ else
+ break
+ end
+ indexCopy = index
+ end
+ end
+
+ local function setSetIndex()
+ Data.Category[Data.CurrentCategory].Index = 0
+
+ rows = 7
+ columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth)
+
+ contents = Data.Category[Data.CurrentCategory].Contents
+ if contents then
+ -- remove our buttons and their connections
+ for i = 1, #insertButtons do
+ insertButtons[i]:remove()
+ end
+ for i = 1, #insertButtonCons do
+ if insertButtonCons[i] then insertButtonCons[i]:disconnect() end
+ end
+ insertButtonCons = {}
+ insertButtons = {}
+
+ arrayPosition = 1
+ loadSectionOfItems(setGui, rows, columns)
+ end
+ end
+
+ local function selectSet(button, setName, setId, setIndex)
+ if button and Data.Category[Data.CurrentCategory] ~= nil then
+ if button ~= Data.Category[Data.CurrentCategory].Button then
+ Data.Category[Data.CurrentCategory].Button = button
+
+ if SetCache[setId] == nil then
+ SetCache[setId] = game:GetService("InsertService"):GetCollection(setId)
+ end
+ Data.Category[Data.CurrentCategory].Contents = SetCache[setId]
+
+ Data.Category[Data.CurrentCategory].SetName = setName
+ Data.Category[Data.CurrentCategory].SetId = setId
+ end
+ setSetIndex()
+ end
+ end
+
+ local function selectCategoryPage(buttons, page)
+ if buttons ~= Data.CurrentCategory then
+ if Data.CurrentCategory then
+ for key, button in pairs(Data.CurrentCategory) do
+ button.Visible = false
+ end
+ end
+
+ Data.CurrentCategory = buttons
+ if Data.Category[Data.CurrentCategory] == nil then
+ Data.Category[Data.CurrentCategory] = {}
+ if #buttons > 0 then
+ selectSet(buttons[1], buttons[1].SetName.Value, buttons[1].SetId.Value, 0)
+ end
+ else
+ Data.Category[Data.CurrentCategory].Button = nil
+ selectSet(Data.Category[Data.CurrentCategory].ButtonFrame, Data.Category[Data.CurrentCategory].SetName, Data.Category[Data.CurrentCategory].SetId, Data.Category[Data.CurrentCategory].Index)
+ end
+ end
+ end
+
+ local function selectCategory(category)
+ selectCategoryPage(category, 0)
+ end
+
+ local function resetAllSetButtonSelection()
+ local setButtons = setGui.SetPanel.Sets.SetsLists:GetChildren()
+ for i = 1, #setButtons do
+ if setButtons[i]:IsA("TextButton") then
+ setButtons[i].Selected = false
+ setButtons[i].BackgroundTransparency = 1
+ setButtons[i].TextColor3 = Color3.new(1,1,1)
+ setButtons[i].BackgroundColor3 = Color3.new(1,1,1)
+ end
+ end
+ end
+
+ local function populateSetsFrame()
+ local currRow = 0
+ for i = 1, #userCategoryButtons do
+ local button = userCategoryButtons[i]
+ button.Visible = true
+ button.Position = UDim2.new(0,5,0,currRow * button.Size.Y.Offset)
+ button.Parent = setGui.SetPanel.Sets.SetsLists
+
+ if i == 1 then -- we will have this selected by default, so show it
+ button.Selected = true
+ button.BackgroundColor3 = Color3.new(0,204/255,0)
+ button.TextColor3 = Color3.new(0,0,0)
+ button.BackgroundTransparency = 0
+ end
+
+ button.MouseEnter:connect(function()
+ if not button.Selected then
+ button.BackgroundTransparency = 0
+ button.TextColor3 = Color3.new(0,0,0)
+ end
+ end)
+ button.MouseLeave:connect(function()
+ if not button.Selected then
+ button.BackgroundTransparency = 1
+ button.TextColor3 = Color3.new(1,1,1)
+ end
+ end)
+ button.MouseButton1Click:connect(function()
+ resetAllSetButtonSelection()
+ button.Selected = not button.Selected
+ button.BackgroundColor3 = Color3.new(0,204/255,0)
+ button.TextColor3 = Color3.new(0,0,0)
+ button.BackgroundTransparency = 0
+ selectSet(button, button.Text, userCategoryButtons[i].SetId.Value, 0)
+ end)
+
+ currRow = currRow + 1
+ end
+
+ local buttons = setGui.SetPanel.Sets.SetsLists:GetChildren()
+
+ -- set first category as loaded for default
+ if buttons then
+ for i = 1, #buttons do
+ if buttons[i]:IsA("TextButton") then
+ selectSet(buttons[i], buttons[i].Text, userCategoryButtons[i].SetId.Value, 0)
+ selectCategory(userCategoryButtons)
+ break
+ end
+ end
+ end
+ end
+
+ setGui = createSetGui()
+ waterGui, waterTypeChangedEvent = createWaterGui()
+ waterGui.Position = UDim2.new(0,55,0,0)
+ waterGui.Parent = setGui
+ setGui.Changed:connect(function(prop) -- this resizes the preview image to always be the right size
+ if prop == "AbsoluteSize" then
+ handleResize()
+ setSetIndex()
+ end
+ end)
+
+ local scrollFrame, controlFrame = t.CreateTrueScrollingFrame()
+ scrollFrame.Size = UDim2.new(0.54,0,0.85,0)
+ scrollFrame.Position = UDim2.new(0.24,0,0.085,0)
+ scrollFrame.Name = "ItemsFrame"
+ scrollFrame.ZIndex = 6
+ scrollFrame.Parent = setGui.SetPanel
+ scrollFrame.BackgroundTransparency = 1
+
+ drillDownSetZIndex(controlFrame,7)
+
+ controlFrame.Parent = setGui.SetPanel
+ controlFrame.Position = UDim2.new(0.76, 5, 0, 0)
+
+ local debounce = false
+ controlFrame.ScrollBottom.Changed:connect(function(prop)
+ if controlFrame.ScrollBottom.Value == true then
+ if debounce then return end
+ debounce = true
+ loadSectionOfItems(setGui, rows, columns)
+ debounce = false
+ end
+ end)
+
+ local userData = {}
+ for id = 1, #userIdsForSets do
+ local newUserData = game:GetService("InsertService"):GetUserSets(userIdsForSets[id])
+ if newUserData and #newUserData > 2 then
+ -- start at #3 to skip over My Decals and My Models for each account
+ for category = 3, #newUserData do
+ if newUserData[category].Name == "High Scalability" then -- we want high scalability parts to show first
+ table.insert(userData,1,newUserData[category])
+ else
+ table.insert(userData, newUserData[category])
+ end
+ end
+ end
+
+ end
+ if userData then
+ userCategoryButtons = processCategory(userData)
+ end
+
+ rows = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.Y/buttonHeight)
+ columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth)
+
+ populateSetsFrame()
+
+ insertPanelCloseCon = setGui.SetPanel.CancelButton.MouseButton1Click:connect(function()
+ setGui.SetPanel.Visible = false
+ if dialogClosed then dialogClosed() end
+ end)
+
+ local setVisibilityFunction = function(visible)
+ if visible then
+ setGui.SetPanel.Visible = true
+ else
+ setGui.SetPanel.Visible = false
+ end
+ end
+
+ local getVisibilityFunction = function()
+ if setGui then
+ if setGui:FindFirstChild("SetPanel") then
+ return setGui.SetPanel.Visible
+ end
+ end
+
+ return false
+ end
+
+ return setGui, setVisibilityFunction, getVisibilityFunction, waterTypeChangedEvent
+end
+
+t.CreateTerrainMaterialSelector = function(size,position)
+ local terrainMaterialSelectionChanged = Instance.new("BindableEvent")
+ terrainMaterialSelectionChanged.Name = "TerrainMaterialSelectionChanged"
+
+ local selectedButton = nil
+
+ local frame = Instance.new("Frame")
+ frame.Name = "TerrainMaterialSelector"
+ if size then
+ frame.Size = size
+ else
+ frame.Size = UDim2.new(0, 245, 0, 230)
+ end
+ if position then
+ frame.Position = position
+ end
+ frame.BorderSizePixel = 0
+ frame.BackgroundColor3 = Color3.new(0,0,0)
+ frame.Active = true
+
+ terrainMaterialSelectionChanged.Parent = frame
+
+ local waterEnabled = true -- todo: turn this on when water is ready
+
+ local materialToImageMap = {}
+ local materialNames = {"Grass", "Sand", "Brick", "Granite", "Asphalt", "Iron", "Aluminum", "Gold", "Plank", "Log", "Gravel", "Cinder Block", "Stone Wall", "Concrete", "Plastic (red)", "Plastic (blue)"}
+ if waterEnabled then
+ table.insert(materialNames,"Water")
+ end
+ local currentMaterial = 1
+
+ function getEnumFromName(choice)
+ if choice == "Grass" then return 1 end
+ if choice == "Sand" then return 2 end
+ if choice == "Erase" then return 0 end
+ if choice == "Brick" then return 3 end
+ if choice == "Granite" then return 4 end
+ if choice == "Asphalt" then return 5 end
+ if choice == "Iron" then return 6 end
+ if choice == "Aluminum" then return 7 end
+ if choice == "Gold" then return 8 end
+ if choice == "Plank" then return 9 end
+ if choice == "Log" then return 10 end
+ if choice == "Gravel" then return 11 end
+ if choice == "Cinder Block" then return 12 end
+ if choice == "Stone Wall" then return 13 end
+ if choice == "Concrete" then return 14 end
+ if choice == "Plastic (red)" then return 15 end
+ if choice == "Plastic (blue)" then return 16 end
+ if choice == "Water" then return 17 end
+ end
+
+ function getNameFromEnum(choice)
+ if choice == Enum.CellMaterial.Grass or choice == 1 then return "Grass"end
+ if choice == Enum.CellMaterial.Sand or choice == 2 then return "Sand" end
+ if choice == Enum.CellMaterial.Empty or choice == 0 then return "Erase" end
+ if choice == Enum.CellMaterial.Brick or choice == 3 then return "Brick" end
+ if choice == Enum.CellMaterial.Granite or choice == 4 then return "Granite" end
+ if choice == Enum.CellMaterial.Asphalt or choice == 5 then return "Asphalt" end
+ if choice == Enum.CellMaterial.Iron or choice == 6 then return "Iron" end
+ if choice == Enum.CellMaterial.Aluminum or choice == 7 then return "Aluminum" end
+ if choice == Enum.CellMaterial.Gold or choice == 8 then return "Gold" end
+ if choice == Enum.CellMaterial.WoodPlank or choice == 9 then return "Plank" end
+ if choice == Enum.CellMaterial.WoodLog or choice == 10 then return "Log" end
+ if choice == Enum.CellMaterial.Gravel or choice == 11 then return "Gravel" end
+ if choice == Enum.CellMaterial.CinderBlock or choice == 12 then return "Cinder Block" end
+ if choice == Enum.CellMaterial.MossyStone or choice == 13 then return "Stone Wall" end
+ if choice == Enum.CellMaterial.Cement or choice == 14 then return "Concrete" end
+ if choice == Enum.CellMaterial.RedPlastic or choice == 15 then return "Plastic (red)" end
+ if choice == Enum.CellMaterial.BluePlastic or choice == 16 then return "Plastic (blue)" end
+
+ if waterEnabled then
+ if choice == Enum.CellMaterial.Water or choice == 17 then return "Water" end
+ end
+ end
+
+
+ local function updateMaterialChoice(choice)
+ currentMaterial = getEnumFromName(choice)
+ terrainMaterialSelectionChanged:Fire(currentMaterial)
+ end
+
+ -- we so need a better way to do this
+ for i,v in pairs(materialNames) do
+ materialToImageMap[v] = {}
+ if v == "Grass" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=56563112"
+ elseif v == "Sand" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=62356652"
+ elseif v == "Brick" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=65961537"
+ elseif v == "Granite" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532153"
+ elseif v == "Asphalt" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532038"
+ elseif v == "Iron" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532093"
+ elseif v == "Aluminum" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531995"
+ elseif v == "Gold" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532118"
+ elseif v == "Plastic (red)" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531848"
+ elseif v == "Plastic (blue)" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531924"
+ elseif v == "Plank" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532015"
+ elseif v == "Log" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532051"
+ elseif v == "Gravel" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532206"
+ elseif v == "Cinder Block" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532103"
+ elseif v == "Stone Wall" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531804"
+ elseif v == "Concrete" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532059"
+ elseif v == "Water" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=81407474"
+ else materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=66887593" -- fill in the rest here!!
+ end
+ end
+
+ local scrollFrame, scrollUp, scrollDown, recalculateScroll = t.CreateScrollingFrame(nil,"grid")
+ scrollFrame.Size = UDim2.new(0.85,0,1,0)
+ scrollFrame.Position = UDim2.new(0,0,0,0)
+ scrollFrame.Parent = frame
+
+ scrollUp.Parent = frame
+ scrollUp.Visible = true
+ scrollUp.Position = UDim2.new(1,-19,0,0)
+
+ scrollDown.Parent = frame
+ scrollDown.Visible = true
+ scrollDown.Position = UDim2.new(1,-19,1,-17)
+
+ local function goToNewMaterial(buttonWrap, materialName)
+ updateMaterialChoice(materialName)
+ buttonWrap.BackgroundTransparency = 0
+ selectedButton.BackgroundTransparency = 1
+ selectedButton = buttonWrap
+ end
+
+ local function createMaterialButton(name)
+ local buttonWrap = Instance.new("TextButton")
+ buttonWrap.Text = ""
+ buttonWrap.Size = UDim2.new(0,32,0,32)
+ buttonWrap.BackgroundColor3 = Color3.new(1,1,1)
+ buttonWrap.BorderSizePixel = 0
+ buttonWrap.BackgroundTransparency = 1
+ buttonWrap.AutoButtonColor = false
+ buttonWrap.Name = tostring(name)
+
+ local imageButton = Instance.new("ImageButton")
+ imageButton.AutoButtonColor = false
+ imageButton.BackgroundTransparency = 1
+ imageButton.Size = UDim2.new(0,30,0,30)
+ imageButton.Position = UDim2.new(0,1,0,1)
+ imageButton.Name = tostring(name)
+ imageButton.Parent = buttonWrap
+ imageButton.Image = materialToImageMap[name].Regular
+
+ local enumType = Instance.new("NumberValue")
+ enumType.Name = "EnumType"
+ enumType.Parent = buttonWrap
+ enumType.Value = 0
+
+ imageButton.MouseEnter:connect(function()
+ buttonWrap.BackgroundTransparency = 0
+ end)
+ imageButton.MouseLeave:connect(function()
+ if selectedButton ~= buttonWrap then
+ buttonWrap.BackgroundTransparency = 1
+ end
+ end)
+ imageButton.MouseButton1Click:connect(function()
+ if selectedButton ~= buttonWrap then
+ goToNewMaterial(buttonWrap, tostring(name))
+ end
+ end)
+
+ return buttonWrap
+ end
+
+ for i = 1, #materialNames do
+ local imageButton = createMaterialButton(materialNames[i])
+
+ if materialNames[i] == "Grass" then -- always start with grass as the default
+ selectedButton = imageButton
+ imageButton.BackgroundTransparency = 0
+ end
+
+ imageButton.Parent = scrollFrame
+ end
+
+ local forceTerrainMaterialSelection = function(newMaterialType)
+ if not newMaterialType then return end
+ if currentMaterial == newMaterialType then return end
+
+ local matName = getNameFromEnum(newMaterialType)
+ local buttons = scrollFrame:GetChildren()
+ for i = 1, #buttons do
+ if buttons[i].Name == "Plastic (blue)" and matName == "Plastic (blue)" then goToNewMaterial(buttons[i],matName) return end
+ if buttons[i].Name == "Plastic (red)" and matName == "Plastic (red)" then goToNewMaterial(buttons[i],matName) return end
+ if string.find(buttons[i].Name, matName) then
+ goToNewMaterial(buttons[i],matName)
+ return
+ end
+ end
+ end
+
+ frame.Changed:connect(function ( prop )
+ if prop == "AbsoluteSize" then
+ recalculateScroll()
+ end
+ end)
+
+ recalculateScroll()
+ return frame, terrainMaterialSelectionChanged, forceTerrainMaterialSelection
+end
+
+t.CreateLoadingFrame = function(name,size,position)
+ game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=35238053")
+
+ local loadingFrame = Instance.new("Frame")
+ loadingFrame.Name = "LoadingFrame"
+ loadingFrame.Style = Enum.FrameStyle.RobloxRound
+
+ if size then loadingFrame.Size = size
+ else loadingFrame.Size = UDim2.new(0,300,0,160) end
+ if position then loadingFrame.Position = position
+ else loadingFrame.Position = UDim2.new(0.5, -150, 0.5,-80) end
+
+ local loadingBar = Instance.new("Frame")
+ loadingBar.Name = "LoadingBar"
+ loadingBar.BackgroundColor3 = Color3.new(0,0,0)
+ loadingBar.BorderColor3 = Color3.new(79/255,79/255,79/255)
+ loadingBar.Position = UDim2.new(0,0,0,41)
+ loadingBar.Size = UDim2.new(1,0,0,30)
+ loadingBar.Parent = loadingFrame
+
+ local loadingGreenBar = Instance.new("ImageLabel")
+ loadingGreenBar.Name = "LoadingGreenBar"
+ loadingGreenBar.Image = "http://www.roblox.com/asset/?id=35238053"
+ loadingGreenBar.Position = UDim2.new(0,0,0,0)
+ loadingGreenBar.Size = UDim2.new(0,0,1,0)
+ loadingGreenBar.Visible = false
+ loadingGreenBar.Parent = loadingBar
+
+ local loadingPercent = Instance.new("TextLabel")
+ loadingPercent.Name = "LoadingPercent"
+ loadingPercent.BackgroundTransparency = 1
+ loadingPercent.Position = UDim2.new(0,0,1,0)
+ loadingPercent.Size = UDim2.new(1,0,0,14)
+ loadingPercent.Font = Enum.Font.Arial
+ loadingPercent.Text = "0%"
+ loadingPercent.FontSize = Enum.FontSize.Size14
+ loadingPercent.TextColor3 = Color3.new(1,1,1)
+ loadingPercent.Parent = loadingBar
+
+ local cancelButton = Instance.new("TextButton")
+ cancelButton.Name = "CancelButton"
+ cancelButton.Position = UDim2.new(0.5,-60,1,-40)
+ cancelButton.Size = UDim2.new(0,120,0,40)
+ cancelButton.Font = Enum.Font.Arial
+ cancelButton.FontSize = Enum.FontSize.Size18
+ cancelButton.TextColor3 = Color3.new(1,1,1)
+ cancelButton.Text = "Cancel"
+ cancelButton.Style = Enum.ButtonStyle.RobloxButton
+ cancelButton.Parent = loadingFrame
+
+ local loadingName = Instance.new("TextLabel")
+ loadingName.Name = "loadingName"
+ loadingName.BackgroundTransparency = 1
+ loadingName.Size = UDim2.new(1,0,0,18)
+ loadingName.Position = UDim2.new(0,0,0,2)
+ loadingName.Font = Enum.Font.Arial
+ loadingName.Text = name
+ loadingName.TextColor3 = Color3.new(1,1,1)
+ loadingName.TextStrokeTransparency = 1
+ loadingName.FontSize = Enum.FontSize.Size18
+ loadingName.Parent = loadingFrame
+
+ local cancelButtonClicked = Instance.new("BindableEvent")
+ cancelButtonClicked.Name = "CancelButtonClicked"
+ cancelButtonClicked.Parent = cancelButton
+ cancelButton.MouseButton1Click:connect(function()
+ cancelButtonClicked:Fire()
+ end)
+
+ local updateLoadingGuiPercent = function(percent, tweenAction, tweenLength)
+ if percent and type(percent) ~= "number" then
+ error("updateLoadingGuiPercent expects number as argument, got",type(percent),"instead")
+ end
+
+ local newSize = nil
+ if percent < 0 then
+ newSize = UDim2.new(0,0,1,0)
+ elseif percent > 1 then
+ newSize = UDim2.new(1,0,1,0)
+ else
+ newSize = UDim2.new(percent,0,1,0)
+ end
+
+ if tweenAction then
+ if not tweenLength then
+ error("updateLoadingGuiPercent is set to tween new percentage, but got no tween time length! Please pass this in as third argument")
+ end
+
+ if (newSize.X.Scale > 0) then
+ loadingGreenBar.Visible = true
+ loadingGreenBar:TweenSize( newSize,
+ Enum.EasingDirection.Out,
+ Enum.EasingStyle.Quad,
+ tweenLength,
+ true)
+ else
+ loadingGreenBar:TweenSize( newSize,
+ Enum.EasingDirection.Out,
+ Enum.EasingStyle.Quad,
+ tweenLength,
+ true,
+ function()
+ if (newSize.X.Scale < 0) then
+ loadingGreenBar.Visible = false
+ end
+ end)
+ end
+
+ else
+ loadingGreenBar.Size = newSize
+ loadingGreenBar.Visible = (newSize.X.Scale > 0)
+ end
+ end
+
+ loadingGreenBar.Changed:connect(function(prop)
+ if prop == "Size" then
+ loadingPercent.Text = tostring( math.ceil(loadingGreenBar.Size.X.Scale * 100) ) .. "%"
+ end
+ end)
+
+ return loadingFrame, updateLoadingGuiPercent, cancelButtonClicked
+end
+
+t.CreatePluginFrame = function (name,size,position,scrollable,parent)
+ function createMenuButton(size,position,text,fontsize,name,parent)
+ local button = Instance.new("TextButton",parent)
+ button.AutoButtonColor = false
+ button.Name = name
+ button.BackgroundTransparency = 1
+ button.Position = position
+ button.Size = size
+ button.Font = Enum.Font.ArialBold
+ button.FontSize = fontsize
+ button.Text = text
+ button.TextColor3 = Color3.new(1,1,1)
+ button.BorderSizePixel = 0
+ button.BackgroundColor3 = Color3.new(20/255,20/255,20/255)
+
+ button.MouseEnter:connect(function ( )
+ if button.Selected then return end
+ button.BackgroundTransparency = 0
+ end)
+ button.MouseLeave:connect(function ( )
+ if button.Selected then return end
+ button.BackgroundTransparency = 1
+ end)
+
+ return button
+
+ end
+
+ local dragBar = Instance.new("Frame",parent)
+ dragBar.Name = tostring(name) .. "DragBar"
+ dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255)
+ dragBar.BorderColor3 = Color3.new(0,0,0)
+ if size then
+ dragBar.Size = UDim2.new(size.X.Scale,size.X.Offset,0,20) + UDim2.new(0,20,0,0)
+ else
+ dragBar.Size = UDim2.new(0,183,0,20)
+ end
+ if position then
+ dragBar.Position = position
+ end
+ dragBar.Active = true
+ dragBar.Draggable = true
+ --dragBar.Visible = false
+ dragBar.MouseEnter:connect(function ( )
+ dragBar.BackgroundColor3 = Color3.new(49/255,49/255,49/255)
+ end)
+ dragBar.MouseLeave:connect(function ( )
+ dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255)
+ end)
+
+ -- plugin name label
+ local pluginNameLabel = Instance.new("TextLabel",dragBar)
+ pluginNameLabel.Name = "BarNameLabel"
+ pluginNameLabel.Text = " " .. tostring(name)
+ pluginNameLabel.TextColor3 = Color3.new(1,1,1)
+ pluginNameLabel.TextStrokeTransparency = 0
+ pluginNameLabel.Size = UDim2.new(1,0,1,0)
+ pluginNameLabel.Font = Enum.Font.ArialBold
+ pluginNameLabel.FontSize = Enum.FontSize.Size18
+ pluginNameLabel.TextXAlignment = Enum.TextXAlignment.Left
+ pluginNameLabel.BackgroundTransparency = 1
+
+ -- close button
+ local closeButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-16,0.5,-8),"X",Enum.FontSize.Size14,"CloseButton",dragBar)
+ local closeEvent = Instance.new("BindableEvent")
+ closeEvent.Name = "CloseEvent"
+ closeEvent.Parent = closeButton
+ closeButton.MouseButton1Click:connect(function ()
+ closeEvent:Fire()
+ closeButton.BackgroundTransparency = 1
+ end)
+
+ -- help button
+ local helpButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-51,0.5,-8),"?",Enum.FontSize.Size14,"HelpButton",dragBar)
+ local helpFrame = Instance.new("Frame",dragBar)
+ helpFrame.Name = "HelpFrame"
+ helpFrame.BackgroundColor3 = Color3.new(0,0,0)
+ helpFrame.Size = UDim2.new(0,300,0,552)
+ helpFrame.Position = UDim2.new(1,5,0,0)
+ helpFrame.Active = true
+ helpFrame.BorderSizePixel = 0
+ helpFrame.Visible = false
+
+ helpButton.MouseButton1Click:connect(function( )
+ helpFrame.Visible = not helpFrame.Visible
+ if helpFrame.Visible then
+ helpButton.Selected = true
+ helpButton.BackgroundTransparency = 0
+ local screenGui = getScreenGuiAncestor(helpFrame)
+ if screenGui then
+ if helpFrame.AbsolutePosition.X + helpFrame.AbsoluteSize.X > screenGui.AbsoluteSize.X then --position on left hand side
+ helpFrame.Position = UDim2.new(0,-5 - helpFrame.AbsoluteSize.X,0,0)
+ else -- position on right hand side
+ helpFrame.Position = UDim2.new(1,5,0,0)
+ end
+ else
+ helpFrame.Position = UDim2.new(1,5,0,0)
+ end
+ else
+ helpButton.Selected = false
+ helpButton.BackgroundTransparency = 1
+ end
+ end)
+
+ local minimizeButton = createMenuButton(UDim2.new(0,16,0,17),UDim2.new(1,-34,0.5,-8),"-",Enum.FontSize.Size14,"MinimizeButton",dragBar)
+ minimizeButton.TextYAlignment = Enum.TextYAlignment.Top
+
+ local minimizeFrame = Instance.new("Frame",dragBar)
+ minimizeFrame.Name = "MinimizeFrame"
+ minimizeFrame.BackgroundColor3 = Color3.new(73/255,73/255,73/255)
+ minimizeFrame.BorderColor3 = Color3.new(0,0,0)
+ minimizeFrame.Position = UDim2.new(0,0,1,0)
+ if size then
+ minimizeFrame.Size = UDim2.new(size.X.Scale,size.X.Offset,0,50) + UDim2.new(0,20,0,0)
+ else
+ minimizeFrame.Size = UDim2.new(0,183,0,50)
+ end
+ minimizeFrame.Visible = false
+
+ local minimizeBigButton = Instance.new("TextButton",minimizeFrame)
+ minimizeBigButton.Position = UDim2.new(0.5,-50,0.5,-20)
+ minimizeBigButton.Name = "MinimizeButton"
+ minimizeBigButton.Size = UDim2.new(0,100,0,40)
+ minimizeBigButton.Style = Enum.ButtonStyle.RobloxButton
+ minimizeBigButton.Font = Enum.Font.ArialBold
+ minimizeBigButton.FontSize = Enum.FontSize.Size18
+ minimizeBigButton.TextColor3 = Color3.new(1,1,1)
+ minimizeBigButton.Text = "Show"
+
+ local separatingLine = Instance.new("Frame",dragBar)
+ separatingLine.Name = "SeparatingLine"
+ separatingLine.BackgroundColor3 = Color3.new(115/255,115/255,115/255)
+ separatingLine.BorderSizePixel = 0
+ separatingLine.Position = UDim2.new(1,-18,0.5,-7)
+ separatingLine.Size = UDim2.new(0,1,0,14)
+
+ local otherSeparatingLine = separatingLine:clone()
+ otherSeparatingLine.Position = UDim2.new(1,-35,0.5,-7)
+ otherSeparatingLine.Parent = dragBar
+
+ local widgetContainer = Instance.new("Frame",dragBar)
+ widgetContainer.Name = "WidgetContainer"
+ widgetContainer.BackgroundTransparency = 1
+ widgetContainer.Position = UDim2.new(0,0,1,0)
+ widgetContainer.BorderColor3 = Color3.new(0,0,0)
+ if not scrollable then
+ widgetContainer.BackgroundTransparency = 0
+ widgetContainer.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
+ end
+
+ if size then
+ if scrollable then
+ widgetContainer.Size = size
+ else
+ widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,size.Y.Scale,size.Y.Offset)
+ end
+ else
+ if scrollable then
+ widgetContainer.Size = UDim2.new(0,163,0,400)
+ else
+ widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,0,400)
+ end
+ end
+ if position then
+ widgetContainer.Position = position + UDim2.new(0,0,0,20)
+ end
+
+ local frame,control,verticalDragger = nil
+ if scrollable then
+ --frame for widgets
+ frame,control = t.CreateTrueScrollingFrame()
+ frame.Size = UDim2.new(1, 0, 1, 0)
+ frame.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
+ frame.BorderColor3 = Color3.new(0,0,0)
+ frame.Active = true
+ frame.Parent = widgetContainer
+ control.Parent = dragBar
+ control.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
+ control.BorderSizePixel = 0
+ control.BackgroundTransparency = 0
+ control.Position = UDim2.new(1,-21,1,1)
+ if size then
+ control.Size = UDim2.new(0,21,size.Y.Scale,size.Y.Offset)
+ else
+ control.Size = UDim2.new(0,21,0,400)
+ end
+ control:FindFirstChild("ScrollDownButton").Position = UDim2.new(0,0,1,-20)
+
+ local fakeLine = Instance.new("Frame",control)
+ fakeLine.Name = "FakeLine"
+ fakeLine.BorderSizePixel = 0
+ fakeLine.BackgroundColor3 = Color3.new(0,0,0)
+ fakeLine.Size = UDim2.new(0,1,1,1)
+ fakeLine.Position = UDim2.new(1,0,0,0)
+
+ verticalDragger = Instance.new("TextButton",widgetContainer)
+ verticalDragger.ZIndex = 2
+ verticalDragger.AutoButtonColor = false
+ verticalDragger.Name = "VerticalDragger"
+ verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255)
+ verticalDragger.BorderColor3 = Color3.new(0,0,0)
+ verticalDragger.Size = UDim2.new(1,20,0,20)
+ verticalDragger.Position = UDim2.new(0,0,1,0)
+ verticalDragger.Active = true
+ verticalDragger.Text = ""
+
+ local scrubFrame = Instance.new("Frame",verticalDragger)
+ scrubFrame.Name = "ScrubFrame"
+ scrubFrame.BackgroundColor3 = Color3.new(1,1,1)
+ scrubFrame.BorderSizePixel = 0
+ scrubFrame.Position = UDim2.new(0.5,-5,0.5,0)
+ scrubFrame.Size = UDim2.new(0,10,0,1)
+ scrubFrame.ZIndex = 5
+ local scrubTwo = scrubFrame:clone()
+ scrubTwo.Position = UDim2.new(0.5,-5,0.5,-2)
+ scrubTwo.Parent = verticalDragger
+ local scrubThree = scrubFrame:clone()
+ scrubThree.Position = UDim2.new(0.5,-5,0.5,2)
+ scrubThree.Parent = verticalDragger
+
+ local areaSoak = Instance.new("TextButton",getScreenGuiAncestor(parent))
+ areaSoak.Name = "AreaSoak"
+ areaSoak.Size = UDim2.new(1,0,1,0)
+ areaSoak.BackgroundTransparency = 1
+ areaSoak.BorderSizePixel = 0
+ areaSoak.Text = ""
+ areaSoak.ZIndex = 10
+ areaSoak.Visible = false
+ areaSoak.Active = true
+
+ local draggingVertical = false
+ local startYPos = nil
+ verticalDragger.MouseEnter:connect(function ()
+ verticalDragger.BackgroundColor3 = Color3.new(60/255,60/255,60/255)
+ end)
+ verticalDragger.MouseLeave:connect(function ()
+ verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255)
+ end)
+ verticalDragger.MouseButton1Down:connect(function(x,y)
+ draggingVertical = true
+ areaSoak.Visible = true
+ startYPos = y
+ end)
+ areaSoak.MouseButton1Up:connect(function ( )
+ draggingVertical = false
+ areaSoak.Visible = false
+ end)
+ areaSoak.MouseMoved:connect(function(x,y)
+ if not draggingVertical then return end
+
+ local yDelta = y - startYPos
+ if not control.ScrollDownButton.Visible and yDelta > 0 then
+ return
+ end
+
+ if (widgetContainer.Size.Y.Offset + yDelta) < 150 then
+ widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,150)
+ control.Size = UDim2.new (0,21,0,150)
+ return
+ end
+
+ startYPos = y
+
+ if widgetContainer.Size.Y.Offset + yDelta >= 0 then
+ widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,widgetContainer.Size.Y.Offset + yDelta)
+ control.Size = UDim2.new(0,21,0,control.Size.Y.Offset + yDelta )
+ end
+ end)
+ end
+
+ local function switchMinimize()
+ minimizeFrame.Visible = not minimizeFrame.Visible
+ if scrollable then
+ frame.Visible = not frame.Visible
+ verticalDragger.Visible = not verticalDragger.Visible
+ control.Visible = not control.Visible
+ else
+ widgetContainer.Visible = not widgetContainer.Visible
+ end
+
+ if minimizeFrame.Visible then
+ minimizeButton.Text = "+"
+ else
+ minimizeButton.Text = "-"
+ end
+ end
+
+ minimizeBigButton.MouseButton1Click:connect(function ( )
+ switchMinimize()
+ end)
+
+ minimizeButton.MouseButton1Click:connect(function( )
+ switchMinimize()
+ end)
+
+ if scrollable then
+ return dragBar, frame, helpFrame, closeEvent
+ else
+ return dragBar, widgetContainer, helpFrame, closeEvent
+ end
+end
+
+t.Help =
+ function(funcNameOrFunc)
+ --input argument can be a string or a function. Should return a description (of arguments and expected side effects)
+ if funcNameOrFunc == "CreatePropertyDropDownMenu" or funcNameOrFunc == t.CreatePropertyDropDownMenu then
+ return "Function CreatePropertyDropDownMenu. " ..
+ "Arguments: (instance, propertyName, enumType). " ..
+ "Side effect: returns a container with a drop-down-box that is linked to the 'property' field of 'instance' which is of type 'enumType'"
+ end
+ if funcNameOrFunc == "CreateDropDownMenu" or funcNameOrFunc == t.CreateDropDownMenu then
+ return "Function CreateDropDownMenu. " ..
+ "Arguments: (items, onItemSelected). " ..
+ "Side effect: Returns 2 results, a container to the gui object and a 'updateSelection' function for external updating. The container is a drop-down-box created around a list of items"
+ end
+ if funcNameOrFunc == "CreateMessageDialog" or funcNameOrFunc == t.CreateMessageDialog then
+ return "Function CreateMessageDialog. " ..
+ "Arguments: (title, message, buttons). " ..
+ "Side effect: Returns a gui object of a message box with 'title' and 'message' as passed in. 'buttons' input is an array of Tables contains a 'Text' and 'Function' field for the text/callback of each button"
+ end
+ if funcNameOrFunc == "CreateStyledMessageDialog" or funcNameOrFunc == t.CreateStyledMessageDialog then
+ return "Function CreateStyledMessageDialog. " ..
+ "Arguments: (title, message, style, buttons). " ..
+ "Side effect: Returns a gui object of a message box with 'title' and 'message' as passed in. 'buttons' input is an array of Tables contains a 'Text' and 'Function' field for the text/callback of each button, 'style' is a string, either Error, Notify or Confirm"
+ end
+ if funcNameOrFunc == "GetFontHeight" or funcNameOrFunc == t.GetFontHeight then
+ return "Function GetFontHeight. " ..
+ "Arguments: (font, fontSize). " ..
+ "Side effect: returns the size in pixels of the given font + fontSize"
+ end
+ if funcNameOrFunc == "LayoutGuiObjects" or funcNameOrFunc == t.LayoutGuiObjects then
+
+ end
+ if funcNameOrFunc == "CreateScrollingFrame" or funcNameOrFunc == t.CreateScrollingFrame then
+ return "Function CreateScrollingFrame. " ..
+ "Arguments: (orderList, style) " ..
+ "Side effect: returns 4 objects, (scrollFrame, scrollUpButton, scrollDownButton, recalculateFunction). 'scrollFrame' can be filled with GuiObjects. It will lay them out and allow scrollUpButton/scrollDownButton to interact with them. Orderlist is optional (and specifies the order to layout the children. Without orderlist, it uses the children order. style is also optional, and allows for a 'grid' styling if style is passed 'grid' as a string. recalculateFunction can be called when a relayout is needed (when orderList changes)"
+ end
+ if funcNameOrFunc == "CreateTrueScrollingFrame" or funcNameOrFunc == t.CreateTrueScrollingFrame then
+ return "Function CreateTrueScrollingFrame. " ..
+ "Arguments: (nil) " ..
+ "Side effect: returns 2 objects, (scrollFrame, controlFrame). 'scrollFrame' can be filled with GuiObjects, and they will be clipped if not inside the frame's bounds. controlFrame has children scrollup and scrolldown, as well as a slider. controlFrame can be parented to any guiobject and it will readjust itself to fit."
+ end
+ if funcNameOrFunc == "AutoTruncateTextObject" or funcNameOrFunc == t.AutoTruncateTextObject then
+ return "Function AutoTruncateTextObject. " ..
+ "Arguments: (textLabel) " ..
+ "Side effect: returns 2 objects, (textLabel, changeText). The 'textLabel' input is modified to automatically truncate text (with ellipsis), if it gets too small to fit. 'changeText' is a function that can be used to change the text, it takes 1 string as an argument"
+ end
+ if funcNameOrFunc == "CreateSlider" or funcNameOrFunc == t.CreateSlider then
+ return "Function CreateSlider. " ..
+ "Arguments: (steps, width, position) " ..
+ "Side effect: returns 2 objects, (sliderGui, sliderPosition). The 'steps' argument specifies how many different positions the slider can hold along the bar. 'width' specifies in pixels how wide the bar should be (modifiable afterwards if desired). 'position' argument should be a UDim2 for slider positioning. 'sliderPosition' is an IntValue whose current .Value specifies the specific step the slider is currently on."
+ end
+ if funcNameOrFunc == "CreateSliderNew" or funcNameOrFunc == t.CreateSliderNew then
+ return "Function CreateSliderNew. " ..
+ "Arguments: (steps, width, position) " ..
+ "Side effect: returns 2 objects, (sliderGui, sliderPosition). The 'steps' argument specifies how many different positions the slider can hold along the bar. 'width' specifies in pixels how wide the bar should be (modifiable afterwards if desired). 'position' argument should be a UDim2 for slider positioning. 'sliderPosition' is an IntValue whose current .Value specifies the specific step the slider is currently on."
+ end
+ if funcNameOrFunc == "CreateLoadingFrame" or funcNameOrFunc == t.CreateLoadingFrame then
+ return "Function CreateLoadingFrame. " ..
+ "Arguments: (name, size, position) " ..
+ "Side effect: Creates a gui that can be manipulated to show progress for a particular action. Name appears above the loading bar, and size and position are udim2 values (both size and position are optional arguments). Returns 3 arguments, the first being the gui created. The second being updateLoadingGuiPercent, which is a bindable function. This function takes one argument (two optionally), which should be a number between 0 and 1, representing the percentage the loading gui should be at. The second argument to this function is a boolean value that if set to true will tween the current percentage value to the new percentage value, therefore our third argument is how long this tween should take. Our third returned argument is a BindableEvent, that when fired means that someone clicked the cancel button on the dialog."
+ end
+ if funcNameOrFunc == "CreateTerrainMaterialSelector" or funcNameOrFunc == t.CreateTerrainMaterialSelector then
+ return "Function CreateTerrainMaterialSelector. " ..
+ "Arguments: (size, position) " ..
+ "Side effect: Size and position are UDim2 values that specifies the selector's size and position. Both size and position are optional arguments. This method returns 3 objects (terrainSelectorGui, terrainSelected, forceTerrainSelection). terrainSelectorGui is just the gui object that we generate with this function, parent it as you like. TerrainSelected is a BindableEvent that is fired whenever a new terrain type is selected in the gui. ForceTerrainSelection is a function that takes an argument of Enum.CellMaterial and will force the gui to show that material as currently selected."
+ end
+ end
+
+
+
+local RbxGui
+
+local localTesting = true
+
+local screen = script.Parent
+local screenResizeCon = nil
+
+local friendWord = "Friend"
+local friendWordLowercase = "friend"
+
+local elementNames = {}
+local elementNameToElement = {}
+
+local privilegeOwner = 255
+local privilegeAdmin = 240
+local privilegeMember = 128
+local privilegeVisitor = 10
+local privilegeBanned = 0
+
+local inContextMenu = false
+local contextMenu3d = false
+
+local bigEasingStyle = Enum.EasingStyle.Back
+local smallEasingStyle = Enum.EasingStyle.Quart
+
+local personalServerContextAdded = false
+local personalServerPlace = false
+local success = pcall(function() personalServerPlace = game.IsPersonalServer end)
+if not success then
+ personalServerPlace = false
+end
+
+local friendRequestBlacklist = {}
+local otherPlayerBlacklist = {}
+
+local currentSortName = ""
+
+local function waitForChild(instance, name)
+ while not instance:FindFirstChild(name) do
+ instance.ChildAdded:wait()
+ end
+end
+
+local function waitForProperty(instance, prop)
+ while not instance[prop] do
+ instance.Changed:wait()
+ end
+end
+
+local function Color3I(r,g,b)
+ return Color3.new(r/255,g/255,b/255)
+end
+
+function robloxLock(instance)
+end
+
+function ArrayRemove(t, obj)
+ for i, obj2 in ipairs(t) do
+ if obj == obj2 then
+ table.remove(t, i)
+ return true
+ end
+ end
+ return false
+end
+
+local function getPlayers()
+ local result = {}
+ local players = game:GetService("Players"):GetChildren()
+ if players then
+ for i, player in ipairs(players) do
+ if player:IsA("Player") then
+ table.insert(result, player)
+ end
+ end
+ end
+ return result
+end
+
+local brickColorTable = {}
+for i = 0, 63 do
+ brickColorTable[BrickColor.palette(i).Name] = BrickColor.palette(i).Color
+end
+
+local function remapColor(i, j)
+ brickColorTable[BrickColor.palette(i).Name] = BrickColor.palette(j).Color
+end
+
+remapColor(13, 12)
+remapColor(14, 12)
+remapColor(15, 12)
+remapColor(61, 29)
+remapColor(63, 62)
+remapColor(56, 50)
+remapColor(45, 53)
+remapColor(51, 20)
+remapColor(4, 20)
+remapColor(59, 35)
+remapColor(60, 29)
+
+local function getColor(brickColor)
+ if brickColorTable[brickColor.Name] then
+ return brickColorTable[brickColor.Name]
+ else
+ return brickColor.Color;
+ end
+end
+
+
+
+local function getTeams()
+ local result = {}
+ local teams = game:GetService("Teams"):GetChildren()
+ for i, team in ipairs(teams) do
+ if team:IsA("Team") then
+ table.insert(result, team)
+ end
+ end
+ return result
+end
+
+local supportFriends = false
+local currentBoardType = "PlayerList"
+local currentStatCount = 0
+
+local createBoardsFunction = nil
+
+
+local playerTable = {}
+local teamTable = {}
+local teamColorTable = {}
+
+local removePlayerFunction = nil
+local recreatePlayerFunction = nil
+local addPlayerFunction = function(player)
+ if recreatePlayerFunction then
+ recreatePlayerFunction(player)
+ end
+end
+local sortPlayerListsFunction = nil
+
+local minimizedState = nil
+local bigWindowImposter = nil
+local smallWindowPosition = UDim2.new(0, -20, 0,5)
+local smallWindowSize = UDim2.new(1,0,1,0)
+local bigWindowSize = UDim2.new(0.6,0,0.6,0)
+local bigWindowPosition = UDim2.new(.2, 0, .2,0)
+
+local smallWindowHeaderYSize = 32
+
+local debounceTeamsChanged = false
+
+local currentWindowState = "Small"
+local previousWindowState = nil
+local transitionWindowsFunction = nil
+
+local container = nil
+local topRightTrayContainer = nil
+
+local playerContextMenu = nil
+local contextMenuElements = {}
+local updateContextMenuItems = nil
+
+local function addContextMenuLabel(getText1, getText2, isVisible)
+ local t = {}
+ t.Type = "Label"
+ t.GetText1 = getText1
+ t.GetText2 = getText2
+ t.IsVisible = isVisible
+ table.insert(contextMenuElements, t)
+end
+local function addContextMenuButton(text, isVisible, isActive, doIt)
+ local t = {}
+ t.Text = text
+ t.Type = "Button"
+ t.IsVisible = isVisible
+ t.IsActive = isActive
+ t.DoIt = doIt
+ table.insert(contextMenuElements, t)
+end
+
+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
+
+
+local function getPrivilegeType(player)
+ local rank = player.PersonalServerRank
+ if rank >= privilegeOwner then
+ return privilegeOwner
+ elseif rank < privilegeOwner and rank >= privilegeAdmin then
+ return privilegeAdmin
+ elseif rank < privilegeAdmin and rank >= privilegeMember then
+ return privilegeMember
+ elseif rank < privilegeMember and rank >= privilegeVisitor then
+ return privilegeVisitor
+ else
+ return privilegeBanned
+ end
+end
+
+--Populate the ContextMenus
+addContextMenuLabel(
+ --GetText1
+ function(player)
+ return "Loading..."
+ end,
+ --GetText2
+ nil,
+ --IsVisible
+ function(player)
+ return getFriendStatus(player) == Enum.FriendStatus.Unknown
+ end)
+
+addContextMenuButton("Send " .. friendWord .. " Request",
+ --IsVisible
+ function(player)
+ return (not otherPlayerBlacklist[player]) and (getFriendStatus(player) == Enum.FriendStatus.NotFriend)
+ end,
+ --IsActive
+ function(player)
+ return true
+ end,
+ --DoIt?
+ function(player)
+ otherPlayerBlacklist[player] = true
+ return game.Players.LocalPlayer:RequestFriendship(player)
+ end
+)
+addContextMenuButton("Un" .. friendWordLowercase,
+ --IsVisible
+ function(player)
+ return getFriendStatus(player) == Enum.FriendStatus.Friend
+ end,
+ --IsActive
+ function(player)
+ return true
+ end,
+ --DoIt
+ function(player)
+ return game.Players.LocalPlayer:RevokeFriendship(player)
+ end
+)
+addContextMenuButton("Accept " .. friendWord .. " Request",
+ --IsVisible
+ function(player)
+ return (not friendRequestBlacklist[player]) and (getFriendStatus(player) == Enum.FriendStatus.FriendRequestReceived)
+ end,
+ --IsActive
+ function(player)
+ return true
+ end,
+ --DoIt
+ function(player)
+ return game.Players.LocalPlayer:RequestFriendship(player)
+ end
+)
+
+addContextMenuButton("Deny " .. friendWord .. " Request",
+ --IsVisible
+ function(player)
+ return getFriendStatus(player) == Enum.FriendStatus.FriendRequestReceived
+ end,
+ --IsActive
+ function(player)
+ return true
+ end,
+ --DoIt
+ function(player)
+ friendRequestBlacklist[player] = true
+ return game.Players.LocalPlayer:RevokeFriendship(player)
+ end
+)
+
+addContextMenuButton("Cancel " .. friendWord .. " Request",
+ --IsVisible
+ function(player)
+ return false -- disable cancel request for now (can lead to griefing)
+ --return getFriendStatus(player) == Enum.FriendStatus.FriendRequestSent
+ end,
+ --IsActive
+ function(player)
+ return true
+ end,
+ --DoIt
+ function(player)
+ otherPlayerBlacklist[player] = false
+ return game.Players.LocalPlayer:RevokeFriendship(player)
+ end
+)
+
+function addPersonalServerContext()
+ if personalServerContextAdded then return end
+ personalServerContextAdded = true
+ addContextMenuButton("Ban",
+ --IsVisible
+ function(player)
+ return ( getPrivilegeType(game.Players.LocalPlayer) >= privilegeAdmin and (getPrivilegeType(player) < privilegeAdmin) )
+ end,
+ --IsActive
+ function(player)
+ return true
+ end,
+ --DoIt
+ function(player)
+ player.PersonalServerRank = privilegeBanned
+ return true
+ end
+ )
+ addContextMenuButton("Promote to Visitor",
+ --IsVisible
+ function(player)
+ return ( getPrivilegeType(game.Players.LocalPlayer) >= privilegeAdmin ) and ( getPrivilegeType(player) == privilegeBanned )
+ end,
+ --IsActive
+ function(player)
+ return true
+ end,
+ --DoIt
+ function(player)
+ game:GetService("PersonalServerService"):Promote(player)
+ return true
+ end
+ )
+ addContextMenuButton("Promote to Member",
+ --IsVisible
+ function(player)
+ return ( getPrivilegeType(game.Players.LocalPlayer) >= privilegeAdmin ) and ( getPrivilegeType(player) == privilegeVisitor )
+ end,
+ --IsActive
+ function(player)
+ return true
+ end,
+ --DoIt
+ function(player)
+ game:GetService("PersonalServerService"):Promote(player)
+ return true
+ end
+ )
+ addContextMenuButton("Promote to Admin",
+ --IsVisible
+ function(player)
+ return ( getPrivilegeType(game.Players.LocalPlayer) == privilegeOwner ) and ( getPrivilegeType(player) == privilegeMember )
+ end,
+ --IsActive
+ function(player)
+ return true
+ end,
+ --DoIt
+ function(player)
+ game:GetService("PersonalServerService"):Promote(player)
+ return true
+ end
+ )
+ addContextMenuButton("Demote to Member",
+ --IsVisible
+ function(player)
+ return ( getPrivilegeType(game.Players.LocalPlayer) == privilegeOwner ) and ( getPrivilegeType(player) == privilegeAdmin )
+ end,
+ --IsActive
+ function(player)
+ return true
+ end,
+ --DoIt
+ function(player)
+ game:GetService("PersonalServerService"):Demote(player)
+ return true
+ end
+ )
+ addContextMenuButton("Demote to Visitor",
+ --IsVisible
+ function(player)
+ return ( getPrivilegeType(game.Players.LocalPlayer) >= privilegeAdmin ) and ( getPrivilegeType(player) == privilegeMember )
+ end,
+ --IsActive
+ function(player)
+ return true
+ end,
+ --DoIt
+ function(player)
+ game:GetService("PersonalServerService"):Demote(player)
+ return true
+ end
+ )
+end
+
+local function setupBuildToolManagement()
+ local buildToolManagerAssetId = 64164692
+ game:GetService("ScriptContext"):AddCoreScript(buildToolManagerAssetId,game.Players.LocalPlayer,"BuildToolManager")
+end
+
+
+local function getStatColumns(players)
+ for i, player in ipairs(players) do
+ local leaderstats = player:FindFirstChild("leaderstats")
+ if leaderstats then
+ local stats = {}
+ local children = leaderstats:GetChildren()
+ if children then
+ for i, stat in ipairs(children) do
+ if stat:IsA("IntValue") then
+ table.insert(stats, stat)
+ else
+ --TODO: This should check for IntValue only but current ScoreHud does not
+ table.insert(stats, stat)
+ end
+ end
+ end
+ return stats
+ end
+ end
+ return nil
+end
+
+local function determineBoardType()
+ local players = getPlayers()
+
+ local foundLeaderstats = false
+ local numStats = 0
+ local foundTeam = false
+
+ local stats = getStatColumns(players)
+ if stats then
+ foundLeaderstats = true
+ numStats = #stats
+ end
+
+ for i, player in ipairs(players) do
+ if not foundTeam then
+ if not player.Neutral then
+ foundTeam = true
+ break
+ end
+ end
+ end
+
+ if foundLeaderstats and foundTeam then
+ return "TeamScore", numStats
+ elseif foundLeaderstats then
+ return "PlayerScore", numStats
+ elseif foundTeam then
+ return "TeamList", numStats
+ else
+ return "PlayerList", numStats
+ end
+end
+
+local function toggleBigWindow()
+ if container == nil then
+ return
+ end
+
+ if currentWindowState == "Big" then
+ --Hide it
+ if previousWindowState == nil or previousWindowState == "Big" or previousWindowState == "None" then
+ transitionWindowsFunction("None")
+ else
+ transitionWindowsFunction("Small")
+ end
+ else
+ previousWindowState = currentWindowState
+ transitionWindowsFunction("Big")
+ end
+end
+local previousBigPlayerList = nil
+local function rebuildBoard(owner, boardType, numStats)
+ if topRightTrayContainer == nil then
+ topRightTrayContainer = owner:FindFirstChild("PlayerListTopRightFrame")
+ if topRightTrayContainer == nil then
+ topRightTrayContainer = Instance.new("Frame")
+ topRightTrayContainer.Name = "PlayerListTopRightFrame"
+ topRightTrayContainer.BackgroundTransparency = 1
+ topRightTrayContainer.Size = UDim2.new(0.2, 16, 0.42, 16)
+ topRightTrayContainer.Position = UDim2.new(0.8, 0, 0, 0)
+ topRightTrayContainer.Parent = container
+ end
+ end
+ if minimizedState == nil then
+ minimizedState = Instance.new("Frame")
+ minimizedState.Name = "MinimizedPlayerlist"
+ minimizedState.BackgroundTransparency = 1
+ minimizedState.Position = UDim2.new(1, -166, 0,0)
+ minimizedState.Size = UDim2.new(0, 151, 0, 30)
+
+ playerListButton = Instance.new("ImageButton")
+ playerListButton.Name = "GoSmallButton"
+ playerListButton.Image = "rbxasset://textures/ui/playerlist_hidden_small.png"
+ playerListButton.BackgroundTransparency = 1
+ playerListButton.Size = UDim2.new(0.0, 35, 0, 30)
+ playerListButton.Position = UDim2.new(1, -35, 0, 0)
+ playerListButton.MouseButton1Click:connect(
+ function()
+ transitionWindowsFunction("Small")
+ end)
+ playerListButton.Parent = minimizedState
+
+ minimizedState.Visible = false
+ robloxLock(minimizedState)
+ minimizedState.Parent = topRightTrayContainer
+ end
+ if bigWindowImposter == nil then
+ bigWindowImposter = owner:FindFirstChild("BigPlayerListWindowImposter")
+ if bigWindowImposter == nil then
+ bigWindowImposter = Instance.new("Frame")
+ bigWindowImposter.Name = "BigPlayerListWindowImposter"
+ bigWindowImposter.Visible = false
+ bigWindowImposter.BackgroundColor3 = Color3.new(0,0,0)
+ bigWindowImposter.BackgroundTransparency = 0.7
+ bigWindowImposter.BorderSizePixel = 0
+ bigWindowImposter.Size = UDim2.new(0.4, 7, 0.4, 7)
+ bigWindowImposter.Position = UDim2.new(0.3, 0, 0.3, 0)
+ robloxLock(bigWindowImposter)
+ bigWindowImposter.Parent = container
+ end
+ end
+ if container == nil or container ~= owner then
+ container = owner
+
+ topRightTrayContainer.Parent = container
+ bigWindowImposter.Parent = container
+ end
+
+ local smallVisible = true
+ local bigVisible = false
+ if container then
+ if topRightTrayContainer then
+ --Delete the old boards
+ if topRightTrayContainer:FindFirstChild("SmallPlayerlist") then
+ smallVisible = topRightTrayContainer.SmallPlayerlist.Visible
+ topRightTrayContainer.SmallPlayerlist.Parent = nil
+ end
+ end
+ if container:FindFirstChild("BigPlayerlist") then
+ bigVisible = container.BigPlayerlist.Visible or (previousBigPlayerList ~= nil)
+ container.BigPlayerlist.Parent = nil
+ if previousBigPlayerList ~= nil then
+ pcall(function() game.GuiService:RemoveCenterDialog(previousBigPlayerList) end)
+ previousBigPlayerList = nil
+ end
+ end
+ end
+
+ local smallBoard, bigBoard = createBoardsFunction(boardType, numStats)
+ if smallBoard then
+ smallBoard.Visible = smallVisible
+ smallBoard.Parent = topRightTrayContainer
+ recalculateSmallPlayerListSize(smallBoard)
+ end
+ if bigBoard then
+ if bigVisible then
+ previousBigPlayerList = bigBoard
+ local centerDialogSupported, msg = pcall(function() game.GuiService:AddCenterDialog(previousBigPlayerList, Enum.CenterDialogType.PlayerInitiatedDialog,
+ function()
+ previousBigPlayerList.Visible = true
+ end,
+ function()
+ previousBigPlayerList.Visible = false
+ end)
+ end)
+ bigBoard.Visible = bigVisible
+ else
+ bigBoard.Visible = false
+ end
+ bigBoard.Parent = container
+ end
+ return container
+end
+
+function recalculateSmallPlayerListSize(smallPlayerList)
+ waitForChild(smallPlayerList,"ScrollingArea")
+ waitForChild(smallPlayerList.ScrollingArea, "ScrollingFrame")
+ local scrollingFrame = smallPlayerList.ScrollingArea.ScrollingFrame
+ local playerLines = scrollingFrame:GetChildren()
+
+ local totalPlayerListSize = 0
+ for i = 1, #playerLines do
+ totalPlayerListSize = totalPlayerListSize + playerLines[i].AbsoluteSize.Y
+ end
+
+ if not smallPlayerList.Parent then return end
+
+ local yOffset = math.max(0,(smallPlayerList.Size.Y.Scale * smallPlayerList.Parent.AbsoluteSize.Y) - totalPlayerListSize - smallWindowHeaderYSize)
+ smallPlayerList.Size = UDim2.new(smallPlayerList.Size.X.Scale,smallPlayerList.Size.X.Offset,smallPlayerList.Size.Y.Scale,-yOffset)
+end
+
+
+local function showBigPlayerWindow()
+ if container:FindFirstChild("BigPlayerlist") then
+ if container.BigPlayerlist.Visible then
+ return
+ end
+ end
+
+ bigWindowImposter.Visible = true
+ bigWindowImposter:TweenSizeAndPosition(bigWindowSize, bigWindowPosition, Enum.EasingDirection.Out, bigEasingStyle, 0.3, true,
+ function(state)
+ if state == Enum.TweenStatus.Completed then
+ bigWindowImposter.Visible = false
+ if container:FindFirstChild("BigPlayerlist") then
+ container.BigPlayerlist.Visible = true
+ end
+ end
+ end)
+end
+
+local function hideBigPlayerWindow(completed)
+ if playerContextMenu then
+ playerContextMenu.Visible = false
+ end
+
+ if container:FindFirstChild("BigPlayerlist") then
+ if container.BigPlayerlist.Visible == false and bigWindowImposter.Visible == false then
+ if completed then
+ completed()
+ end
+ --Already completely hidden
+ return
+ end
+ container.BigPlayerlist.Visible = false
+ end
+
+ local completedFunction = completed
+ bigWindowImposter.Visible = true
+ bigWindowImposter:TweenSizeAndPosition(UDim2.new(0.4, 0, 0.4, 0), UDim2.new(0.3, 0, 0.3, 0), Enum.EasingDirection.In, Enum.EasingStyle.Quart, 0.15, true,
+ function(state)
+ if state == Enum.TweenStatus.Completed then
+ bigWindowImposter.Visible = false
+ if completedFunction then
+ completedFunction()
+ end
+ end
+ end)
+end
+local function hideSmallPlayerWindow(completed)
+ if playerContextMenu then
+ playerContextMenu.Visible = false
+ end
+ if topRightTrayContainer:FindFirstChild("SmallPlayerlist") then
+ local completedFunction = completed
+ if topRightTrayContainer.SmallPlayerlist.Visible then
+ topRightTrayContainer.SmallPlayerlist:TweenPosition(UDim2.new(1,0,smallWindowPosition.Y.Scale, smallWindowPosition.Y.Offset), Enum.EasingDirection.Out, smallEasingStyle, 0.3, true,
+ function(state)
+ if state == Enum.TweenStatus.Completed then
+ if topRightTrayContainer:FindFirstChild("SmallPlayerlist") then
+ topRightTrayContainer.SmallPlayerlist.Visible = false
+ end
+ if completedFunction then
+ completedFunction()
+ end
+ end
+ end)
+ return
+ end
+ end
+ if completed then
+ completed()
+ end
+end
+
+
+transitionWindowsFunction = function(desiredState)
+ if desiredState == "Big" then
+ minimizedState.Visible = false
+ hideSmallPlayerWindow()
+
+ if previousBigPlayerList ~= nil then
+ if previousBigPlayerList ~= container:FindFirstChild("BigPlayerlist") then
+ pcall(function() game.GuiService:RemoveCenterDialog(previousBigPlayerList) end)
+ previousBigPlayerList = nil
+ previousBigPlayerList = container:FindFirstChild("BigPlayerlist")
+ end
+ else
+ previousBigPlayerList = container:FindFirstChild("BigPlayerlist")
+ end
+
+ if previousBigPlayerList then
+ local firstShow = false
+ local centerDialogSupported, msg = pcall(function() game.GuiService:AddCenterDialog(previousBigPlayerList, Enum.CenterDialogType.PlayerInitiatedDialog,
+ function()
+ if not firstShow then
+ showBigPlayerWindow()
+ firstShow = true
+ else
+ previousBigPlayerList.Visible = true
+ end
+ end,
+ function()
+ if previousBigPlayerList then
+ previousBigPlayerList.Visible = false
+ end
+ end)
+ end)
+ if centerDialogSupported == false then
+ print("Exception", msg)
+ showBigPlayerWindow()
+ end
+ else
+ showBigPlayerWindow()
+ end
+ currentWindowState = "Big"
+ elseif desiredState == "Small" then
+ minimizedState.Visible = false
+ if previousBigPlayerList ~= nil then
+ pcall(function() game.GuiService:RemoveCenterDialog(previousBigPlayerList) end)
+ previousBigPlayerList = nil
+ end
+
+ hideBigPlayerWindow()
+ if topRightTrayContainer:FindFirstChild("SmallPlayerlist") then
+ if not topRightTrayContainer.SmallPlayerlist.Visible or topRightTrayContainer.SmallPlayerlist.Position ~= smallWindowPosition then
+ topRightTrayContainer.SmallPlayerlist.Visible = true
+ topRightTrayContainer.SmallPlayerlist:TweenPosition(smallWindowPosition, Enum.EasingDirection.Out, smallEasingStyle, 0.3, true)
+ end
+ end
+ currentWindowState = "Small"
+ elseif desiredState == "None" then
+ if previousBigPlayerList ~= nil then
+ pcall(function() game.GuiService:RemoveCenterDialog(previousBigPlayerList) end)
+ previousBigPlayerList = nil
+ end
+
+ local smallDone = false
+ local bigDone = false
+ hideSmallPlayerWindow(
+ function()
+ smallDone = true
+ if bigDone and smallDone then
+ minimizedState.Visible = true
+ end
+ end)
+ hideBigPlayerWindow(
+ function()
+ bigDone = true
+ if bigDone and smallDone then
+ minimizedState.Visible = true
+ end
+ end)
+ currentWindowState = "None"
+ end
+end
+
+local function getStatValuesForPlayer(player)
+ local leaderstats = player:FindFirstChild("leaderstats")
+ if leaderstats then
+ local children = leaderstats:GetChildren()
+ if children then
+ local result = {}
+ --Just go based on position
+ for i, stat in ipairs(children) do
+ if stat:IsA("IntValue") then
+ table.insert(result, stat)
+ else
+ table.insert(result, 0)
+ end
+ end
+
+ return result, leaderstats
+ end
+ end
+ return nil
+end
+
+--ChildAdded on Player (if it's name is "leaderstats")
+
+if UserSettings and LoadLibrary then
+
+ RbxGui,msg = t
+
+ local function createTeamName(name, color)
+ local fontHeight = 20
+ local frame = Instance.new("Frame")
+ frame.Name = "Team-" .. name
+ frame.BorderSizePixel = 0
+ frame.BackgroundTransparency = 0.5
+ frame.BackgroundColor3 = Color3.new(1,1,1)
+ frame.Size = UDim2.new(1, 0, 0, fontHeight)
+ frame.Position = UDim2.new(0,0,0,0)
+
+ local label = Instance.new("TextLabel")
+ label.Name = "NameLabel"
+ label.Text = " " .. name
+ label.Font = Enum.Font.ArialBold
+ label.FontSize = Enum.FontSize.Size18
+ label.Position = UDim2.new(0,0,0,0)
+ label.Size = UDim2.new(1,0,1,0)
+ label.TextColor3 = Color3.new(1,1,1)
+ label.BackgroundTransparency = 0.5
+ label.BackgroundColor3 = getColor(color)
+ label.BorderSizePixel = 0
+ label.TextXAlignment = Enum.TextXAlignment.Left
+
+ local changeFunc = nil
+ label, changeFunc = RbxGui.AutoTruncateTextObject(label)
+ label.Parent = frame
+
+ return frame, changeFunc
+ end
+
+ local function getFriendStatusIcon(friendStatus)
+ if friendStatus == Enum.FriendStatus.Unknown or friendStatus == Enum.FriendStatus.NotFriend then
+ return nil
+ elseif friendStatus == Enum.FriendStatus.Friend then
+ return "rbxasset://textures/ui/PlayerlistFriendIcon.png"
+ elseif friendStatus == Enum.FriendStatus.FriendRequestSent then
+ return "rbxasset://textures/ui/PlayerlistFriendRequestSentIcon.png"
+ elseif friendStatus == Enum.FriendStatus.FriendRequestReceived then
+ return "rbxasset://textures/ui/PlayerlistFriendRequestReceivedIcon.png"
+ else
+ error("Unknown FriendStatus: " .. friendStatus)
+ end
+ end
+
+ local function getMembershipTypeIcon(membershipType)
+ if 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("Uknown membershipType" .. membershipType)
+ end
+ end
+
+
+ local function updatePlayerFriendStatus(nameObject, friendStatus)
+ local fontHeight = 20
+
+ local friendIconImage = getFriendStatusIcon(friendStatus)
+ nameObject.MembershipTypeLabel.FriendStatusLabel.Visible = (friendIconImage ~= nil)
+
+ if friendIconImage ~= nil then
+ --Show friend icon
+ nameObject.MembershipTypeLabel.FriendStatusLabel.Image = friendIconImage
+ nameObject.NameLabel.Position =UDim2.new(0,2*fontHeight,0,1)
+ nameObject.NameLabel.Size = UDim2.new(1,-2*fontHeight,1,-2)
+ else
+ --Hide the friend icon
+ nameObject.NameLabel.Position = UDim2.new(0,fontHeight+1,0,1)
+ nameObject.NameLabel.Size = UDim2.new(1,-(fontHeight+1),1,-2)
+ end
+ end
+ local function updatePlayerName(nameObject, membershipStatus, teamColor)
+ local fontHeight = 20
+
+ nameObject.Size = UDim2.new(1,0,0,fontHeight)
+ nameObject.MembershipTypeLabel.Image = getMembershipTypeIcon(membershipStatus)
+ end
+
+
+ local function updatePlayerNameColor(player, teamColor)
+ local function updatePlayerNameColorHelper(nameObject)
+ if teamColor ~= nil then
+ nameObject.NameLabel.TextColor3 = getColor(teamColor)
+ nameObject.NameLabel.FullNameLabel.TextColor3 = getColor(teamColor)
+ else
+ nameObject.NameLabel.TextColor3 = Color3.new(1,1,1)
+ nameObject.NameLabel.FullNameLabel.TextColor3 = Color3.new(1,1,1)
+ end
+ end
+
+ updatePlayerNameColorHelper(playerTable[player].NameObjectSmall)
+ updatePlayerNameColorHelper(playerTable[player].NameObjectBig)
+ end
+
+
+ local function createPlayerName(name, membershipStatus, teamColor, friendStatus)
+ local frame = Instance.new("Frame")
+ frame.Name = "Player_" .. name
+ frame.BackgroundColor3 = Color3.new(1,1,1)
+ frame.BackgroundTransparency = 0.5
+ frame.BorderSizePixel = 0
+
+ local membershipStatusLabel = Instance.new("ImageLabel")
+ membershipStatusLabel.Name = "MembershipTypeLabel"
+ membershipStatusLabel.BackgroundTransparency = 1
+ membershipStatusLabel.Size = UDim2.new(1,0,1,0)
+ membershipStatusLabel.Position = UDim2.new(0,0,0,0)
+ membershipStatusLabel.SizeConstraint = Enum.SizeConstraint.RelativeYY
+ membershipStatusLabel.Parent = frame
+
+ local friendStatusLabel = Instance.new("ImageLabel")
+ friendStatusLabel.Name = "FriendStatusLabel"
+ friendStatusLabel.Visible = false
+ friendStatusLabel.BackgroundTransparency = 1
+ friendStatusLabel.Size = UDim2.new(1,0,1,0)
+ friendStatusLabel.Position = UDim2.new(1,0,0,0)
+ friendStatusLabel.Parent = membershipStatusLabel
+
+ local changeNameFunction
+ local nameLabel = Instance.new("TextLabel")
+ nameLabel.Name = "NameLabel"
+ nameLabel.Text = name
+ nameLabel.Font = Enum.Font.ArialBold
+ nameLabel.FontSize = Enum.FontSize.Size14
+ nameLabel.TextColor3 = Color3.new(1,1,1)
+ nameLabel.BackgroundTransparency = 1
+ nameLabel.BackgroundColor3 = Color3.new(0,0,0)
+ nameLabel.TextXAlignment = Enum.TextXAlignment.Left
+ nameLabel, changeNameFunction = RbxGui.AutoTruncateTextObject(nameLabel)
+ nameLabel.Parent = frame
+
+ updatePlayerName(frame, membershipStatus, teamColor)
+ if supportFriends and not friendRequestBlacklist[game.Players:FindFirstChild(name)] then
+ updatePlayerFriendStatus(frame, friendStatus)
+ else
+ updatePlayerFriendStatus(frame, Enum.FriendStatus.NotFriend)
+ end
+ return frame, changeNameFunction
+ end
+
+ local function createStatColumn(i, numColumns, isTeam, color3, isHeader, stat)
+ local textLabel = Instance.new("TextButton")
+ textLabel.Name = "Stat" .. i
+ textLabel.AutoButtonColor = false
+ textLabel.TextColor3 = Color3.new(1,1,1)
+ textLabel.TextXAlignment = Enum.TextXAlignment.Right
+ textLabel.TextYAlignment = Enum.TextYAlignment.Center
+ textLabel.FontSize = Enum.FontSize.Size14
+
+ if isHeader then
+ textLabel.FontSize = Enum.FontSize.Size18
+ else
+ textLabel.FontSize = Enum.FontSize.Size14
+ end
+ if isHeader or isTeam then
+ textLabel.Font = Enum.Font.ArialBold
+ else
+ textLabel.Font = Enum.Font.Arial
+ end
+
+ if isTeam then
+ textLabel.BackgroundColor3 = color3
+ textLabel.Text = 0
+ else
+ textLabel.BackgroundColor3 = Color3.new(0,0,0)
+ textLabel.Text = ""
+ end
+ textLabel.BackgroundTransparency = 1
+ if i == numColumns then
+ textLabel.Size = UDim2.new(1/numColumns, -6, 1, 0)
+ else
+ textLabel.Size = UDim2.new(1/numColumns, -4, 1, 0)
+ end
+
+ textLabel.Position = UDim2.new((i-1) * (1/numColumns), 0, 0, 0)
+
+ local truncLabel, changer = RbxGui.AutoTruncateTextObject(textLabel)
+
+ if isHeader then
+ local mouseCon = {}
+
+ mouseCon[1] = truncLabel.MouseEnter:connect(function()
+ truncLabel.BackgroundTransparency = 0.2
+ end)
+ mouseCon[2] = truncLabel.MouseLeave:connect(function()
+ truncLabel.BackgroundTransparency = 1
+ end)
+
+ mouseCon[3] = truncLabel.MouseButton1Click:connect(function()
+ sortPlayerListsFunction(truncLabel:GetChildren()[1].Name, (currentSortName == truncLabel:GetChildren()[1].Name) )
+ truncLabel.BackgroundTransparency = 1
+ end)
+
+ mouseCon[4] = truncLabel:GetChildren()[1].MouseButton1Click:connect(function()
+ sortPlayerListsFunction(textLabel.Name, (currentSortName == truncLabel.Name) )
+ truncLabel.BackgroundTransparency = 1
+ end)
+
+ mouseCon[5] = nil
+ mouseCon[5] = truncLabel.AncestryChanged:connect(function(child,parent)
+ if parent == nil then
+ for i,connection in pairs(mouseCon) do
+ connection:disconnect()
+ end
+ end
+ end)
+ end
+
+ return truncLabel, changer
+ end
+
+ local function createStatHeaders(stats, numColumns, isBig)
+ local frame = Instance.new("Frame")
+ frame.Name = "Headers"
+ frame.BorderSizePixel = 0
+ frame.BackgroundColor3 = Color3.new(0,0,0)
+ frame.BackgroundTransparency = 1
+
+ local nameSize
+ if isBig then
+ nameSize = 0.5
+ elseif numColumns == 1 then
+ nameSize = 0.7
+ elseif numColumns == 2 then
+ nameSize = 0.6
+ else
+ nameSize = 0.45
+ end
+ frame.Size = UDim2.new(1-nameSize, 0, 1,0)
+ if isBig then
+ frame.Position = UDim2.new(nameSize,-25, 0,0)
+ else
+ frame.Position = UDim2.new(nameSize,0, 0,0)
+ end
+
+ local i = 1
+ while i <= numColumns do
+ local headerColumn, changeText = createStatColumn(i, numColumns, false, nil, true,stats[i])
+ changeText(stats[i].Name)
+ headerColumn.Parent = frame
+ i = i + 1
+ end
+ return frame, textChangers
+ end
+
+ local function createStatColumns(nameObject, numColumns, isTeam, isBig)
+ local frame = Instance.new("Frame")
+ frame.Name = nameObject.Name .. "_WithStats"
+ frame.BorderSizePixel = 0
+ frame.BackgroundColor3 = nameObject.BackgroundColor3
+ frame.BackgroundTransparency = nameObject.BackgroundTransparency
+ frame.Size = nameObject.Size
+ frame.Position = nameObject.Position
+
+ nameObject.BackgroundTransparency = 1
+
+ if numColumns == 0 then
+ nameObject.Size = UDim2.new(1,0,1,0)
+ nameObject.Position = UDim2.new(0,0,0,0)
+ nameObject.Parent = frame
+ return frame
+ end
+
+ local statFrame = Instance.new("Frame")
+ statFrame.Name = "Stats"
+ if isTeam then
+ statFrame.BorderSizePixel = 0
+ statFrame.BackgroundColor3 = nameObject.NameLabel.BackgroundColor3
+ statFrame.BackgroundTransparency = nameObject.NameLabel.BackgroundTransparency
+ else
+ statFrame.BackgroundTransparency = 1
+ end
+
+ local nameSize
+ if isBig then
+ nameSize = 0.5
+ elseif numColumns == 1 then
+ nameSize = 0.7
+ elseif numColumns == 2 then
+ nameSize = 0.6
+ else
+ nameSize = 0.45
+ end
+ nameObject.Size = UDim2.new(nameSize, 0, 1, 0)
+ nameObject.Position = UDim2.new(0, 0, 0, 0)
+ statFrame.Size = UDim2.new(1-nameSize,0, 1,0)
+ statFrame.Position = UDim2.new(nameSize,0, 0,0)
+
+ nameObject.Parent = frame
+ statFrame.Parent = frame
+
+ local textChangers = {}
+ local i = 1
+ while i <= numColumns do
+ local statColumn, changeText = createStatColumn(i, numColumns, isTeam, statFrame.BackgroundColor3)
+ statColumn.Parent = statFrame
+ table.insert(textChangers, changeText)
+
+ i = i + 1
+ end
+
+ return frame, statFrame, textChangers
+ end
+
+ local function createAlternatingRows(objects)
+ for i, line in ipairs(objects) do
+ if i % 2 == 0 then
+ line.BackgroundTransparency = 1
+ else
+ line.BackgroundTransparency = 0.95
+ end
+ end
+ end
+ local removeFromTeam = nil
+
+ local function clearTableEntry(obj, tableInfo)
+ if tableInfo.MainObjectSmall then
+ tableInfo.MainObjectSmall.Parent = nil
+ tableInfo.MainObjectSmall = nil
+ end
+ if tableInfo.MainObjectBig then
+ tableInfo.MainObjectBig.Parent = nil
+ tableInfo.MainObjectBig = nil
+ end
+ if tableInfo.Connections then
+ for i, connection in ipairs(tableInfo.Connections) do
+ connection:disconnect()
+ end
+ tableInfo.Connections = nil
+ end
+ if tableInfo.LeaderStatConnections then
+ for i, connection in ipairs(tableInfo.LeaderStatConnections) do
+ connection:disconnect()
+ end
+ tableInfo.LeaderStatConnections = nil
+ end
+ if tableInfo.CurrentTeam then
+ removeFromTeam(obj)
+ tableInfo.CurrentTeam = nil
+ end
+ if tableInfo.Players then
+ for i, player in ipairs(tableInfo.Players) do
+ playerTable[player].CurrentTeam = nil
+ end
+ tableInfo.Players = {}
+ end
+ if tableInfo.StatValues then
+ tableInfo.StatValues = nil
+ end
+ end
+
+ local function resetPlayerTable()
+ for player, info in pairs(playerTable) do
+ clearTableEntry(player, info)
+ playerTable[player] = nil
+ end
+ playerTable = {}
+ end
+
+ local function resetTeamTable()
+ for team, info in pairs(teamTable) do
+ clearTableEntry(team, info)
+ teamTable[team] = nil
+ end
+ teamTable = {}
+ teamColorTable = {}
+ end
+
+ local function getBoardTypeInfo()
+ local isTeam = (currentBoardType == "TeamScore" or currentBoardType == "TeamList")
+ local isScore = (currentBoardType == "TeamScore" or currentBoardType == "PlayerScore")
+ return isTeam, isScore
+ end
+
+
+ local function recomputeTeamScore(team, column)
+ if not team or team == "Neutral" then
+ return
+ end
+
+ local function recomputeScoreHelper(statChangers)
+ if statChangers and column <= #statChangers then
+ local sum = 0
+ for i, p in ipairs(teamTable[team].Players) do
+ if playerTable[p].StatValues and column <= #playerTable[p].StatValues then
+ sum = sum + playerTable[p].StatValues[column].Value
+ end
+ end
+ statChangers[column](sum)
+ end
+ end
+
+ recomputeScoreHelper(teamTable[team].StatChangersSmall)
+ recomputeScoreHelper(teamTable[team].StatChangersBig)
+ end
+ local function recomputeCompleteTeamScore(team)
+ local col = 1
+ while col <= currentStatCount do
+ recomputeTeamScore(team, col)
+ col = col + 1
+ end
+ end
+ removeFromTeam = function(player)
+ if playerTable[player].CurrentTeam ~= nil and teamTable[playerTable[player].CurrentTeam] ~= nil then
+ ArrayRemove(teamTable[playerTable[player].CurrentTeam].Players, player)
+ recomputeCompleteTeamScore(playerTable[player].CurrentTeam)
+ playerTable[player].CurrentTeam = nil
+ end
+ end
+
+ local function assignToTeam(player)
+ local isTeam, isScore = getBoardTypeInfo()
+
+ if isTeam then
+ local newTeam = nil
+
+ if player.Neutral or teamColorTable[player.TeamColor.Name] == nil then
+ newTeam = "Neutral"
+ else
+ newTeam = teamColorTable[player.TeamColor.Name]
+ end
+
+ if playerTable[player].CurrentTeam == newTeam then
+ return
+ end
+
+ local oldTeam = playerTable[player].LastTeam
+ removeFromTeam(player)
+
+ playerTable[player].CurrentTeam = newTeam
+
+ if teamTable[oldTeam] and teamTable[oldTeam]["NameChangeFuncBig"] then
+ if #teamTable[oldTeam].Players < 1 then
+ teamTable[oldTeam]["NameChangeFuncBig"](" " .. oldTeam.Name)
+ else
+ teamTable[oldTeam]["NameChangeFuncBig"](" " .. oldTeam.Name .. " (" .. tostring(#teamTable[oldTeam].Players) ..")")
+ end
+ end
+
+ if teamTable[newTeam] then
+ table.insert(teamTable[newTeam].Players, player)
+ if newTeam["Name"] then
+ if teamTable[newTeam]["NameChangeFuncBig"] then
+ if #teamTable[newTeam].Players < 1 then
+ teamTable[newTeam]["NameChangeFuncBig"](" " .. newTeam.Name)
+ else
+ teamTable[newTeam]["NameChangeFuncBig"](" " .. newTeam.Name .. " (" .. tostring(#teamTable[newTeam].Players) ..")")
+ end
+ end
+ end
+ end
+
+ if newTeam == "Neutral" then
+ updatePlayerNameColor(player, nil)
+ else
+ updatePlayerNameColor(player, player.TeamColor)
+ end
+
+ playerTable[player].LastTeam = newTeam
+
+ recomputeCompleteTeamScore(newTeam)
+
+ --Relayout
+ if sortPlayerListsFunction then
+ sortPlayerListsFunction()
+ end
+ end
+ end
+
+ local function buildTeamObject(team, numStatColumns, suffix)
+ local isTeam, isScore = getBoardTypeInfo()
+ local teamObject, changeFunc = createTeamName(team.Name, team.TeamColor)
+ teamObject.NameLabel.Text = " " .. team.Name .. " (0)"
+ if not teamTable[team] then
+ teamTable[team] = {}
+ end
+ teamTable[team]["NameObject" .. suffix] = teamObject
+ teamTable[team]["NameChangeFunc" .. suffix] = changeFunc
+ if isScore then
+ local statObject
+ local textChangers
+ teamObject, statObject, textChangers = createStatColumns(teamObject, numStatColumns, true, suffix == "Big")
+ teamTable[team]["StatObject" .. suffix] = statObject
+ teamTable[team]["StatChangers" .. suffix] = textChangers
+ end
+ teamTable[team]["MainObject" .. suffix] = teamObject
+ changeFunc(" " .. team.Name)
+ if not teamTable[team].Players then
+ teamTable[team].Players = {}
+ else
+ if suffix ~= "Small" and #teamTable[team].Players > 0 then
+ changeFunc(" " .. team.Name .. " (" .. tostring(#teamTable[team].Players) ..")")
+ end
+ end
+
+ return teamObject
+ end
+
+ local currentContextMenuPlayer = nil
+ local function updatePlayerContextMenu(player,x,y)
+ currentContextMenuPlayer = player
+ local elementHeight = 18
+ local function highlight(button)
+ button.TextColor3 = Color3.new(0,0,0)
+ button.BackgroundColor3 = Color3.new(0.8,0.8,0.8)
+ end
+ local function clearHighlight(button)
+ button.TextColor3 = Color3.new(1,1,1)
+ button.BackgroundColor3 = Color3.new(0,0,0)
+ end
+ if playerContextMenu == nil then
+ elementNames = {}
+ elementNameToElement = {}
+
+ for i, contextElement in ipairs(contextMenuElements) do
+ table.insert(elementNames, contextElement.Text)
+ elementNameToElement[tostring(contextElement.Text)] = contextElement
+ end
+
+ playerContextMenu = Instance.new("TextButton")
+ playerContextMenu.Name = "PlayerListContextMenu"
+ playerContextMenu.Style = Enum.ButtonStyle.RobloxButton
+ playerContextMenu.Text = ""
+ playerContextMenu.Visible = false
+ playerContextMenu.ZIndex = 4
+
+ playerContextMenu.MouseLeave:connect(function()
+ local menuChildren = playerContextMenu:GetChildren()
+ for i = 1, #menuChildren do
+ if menuChildren[i].Name == "ChoiceButton" then
+ menuChildren[i].TextColor3 = Color3.new(1,1,1)
+ menuChildren[i].BackgroundTransparency = 1
+ end
+ end
+ playerContextMenu.Visible = false
+ inContextMenu = false
+ end)
+
+ playerContextMenu.MouseEnter:connect(function()
+ inContextMenu = true
+ end)
+
+ for i = 1, #elementNames do
+ local newElementButton = Instance.new("TextButton")
+ newElementButton.Name = "ChoiceButton"
+ newElementButton.Text = elementNames[i]
+ newElementButton.TextColor3 = Color3.new(1,1,1)
+ newElementButton.Font = Enum.Font.Arial
+ newElementButton.FontSize = Enum.FontSize.Size14
+ newElementButton.BackgroundTransparency = 1
+ newElementButton.TextWrap = true
+ newElementButton.Size = UDim2.new(1,0,0,elementHeight)
+ newElementButton.Position = UDim2.new(0,0,0,elementHeight * (i - 1))
+ newElementButton.ZIndex = playerContextMenu.ZIndex + 1
+
+ newElementButton.MouseEnter:connect(function()
+ newElementButton.TextColor3 = Color3.new(0,0,0)
+ newElementButton.BackgroundTransparency = 0
+ end)
+
+ newElementButton.MouseLeave:connect(function()
+ newElementButton.TextColor3 = Color3.new(1,1,1)
+ newElementButton.BackgroundTransparency = 1
+ end)
+
+ newElementButton.MouseButton1Click:connect(function()
+ local element = elementNameToElement[newElementButton.Text]
+ pcall(function() element.DoIt(currentContextMenuPlayer) end)
+ playerContextMenu.Visible = false
+ newElementButton.TextColor3 = Color3.new(1,1,1)
+ newElementButton.BackgroundTransparency = 1
+ end)
+
+ newElementButton.Parent = playerContextMenu
+ end
+
+ robloxLock(playerContextMenu)
+ playerContextMenu.Parent = script.Parent
+
+ end
+
+ local visibleElements = 0
+ for i, contextElement in ipairs(contextMenuElements) do
+ local isVisible = false
+
+ if contextElement.IsVisible then
+ local success, visible = pcall(function() return contextElement.IsVisible(currentContextMenuPlayer) end)
+ if success then
+ isVisible = visible
+ else
+ print("Error in IsVisible call: " .. visible)
+ end
+ end
+
+ if isVisible then
+ local foundElement = false
+ for i = 1, #elementNames do
+ if elementNames[i] == contextElement.Text then
+ foundElement = true
+ break
+ end
+ end
+ if not foundElement then
+ table.insert(elementNames,contextElement.Text)
+ end
+ visibleElements = visibleElements + 1
+ else
+ for i = 1, #elementNames do
+ if elementNames[i] == contextElement.Text then
+ table.remove(elementNames,i)
+ break
+ end
+ end
+ end
+ end
+ playerContextMenu.Size = UDim2.new(0, 150, 0, elementHeight + (elementHeight * visibleElements) )
+
+ if x and y then
+ x = x - (playerContextMenu.AbsoluteSize.X/2)
+ if x + playerContextMenu.AbsoluteSize.X >= script.Parent.AbsoluteSize.X then
+ x = script.Parent.AbsoluteSize.X - playerContextMenu.AbsoluteSize.X
+ end
+ playerContextMenu.Position = UDim2.new(0, x, 0, y - 3)
+ end
+
+ local elementPos = 0
+ local contextChildren = playerContextMenu:GetChildren()
+ for i = 1, #contextChildren do
+ if contextChildren[i]:IsA("GuiObject") and contextChildren[i].Name == "ChoiceButton" then
+ contextChildren[i].Visible = false
+ for j = 1, #elementNames do
+ if elementNames[j] == contextChildren[i].Text then
+ contextChildren[i].Visible = true
+ contextChildren[i].Position = UDim2.new(0,0,0,elementPos * elementHeight)
+ elementPos = elementPos + 1
+ break
+ end
+ end
+ end
+ end
+ end
+
+ local function playerContextMenuHasItems()
+ if playerContextMenu then
+ local children = playerContextMenu:GetChildren()
+ for i = 1, #children do
+ if children[i]:IsA("GuiObject") and children[i].Name == "ChoiceButton" and children[i].Visible then
+ return true
+ end
+ end
+ end
+ return false
+ end
+
+ local function showPlayerMenu(player, x, y)
+ updatePlayerContextMenu(player,x,y)
+ if not playerContextMenuHasItems() then return end -- don't show if we have nothing to show
+ playerContextMenu.Visible = true
+ end
+
+ local function buildPlayerObject(player, numStatColumns, suffix)
+ if not player then return nil end
+
+ local isTeam, isScore = getBoardTypeInfo()
+
+ local playerObject = nil
+ local changePlayerNameFunction = nil
+ local currentColor = nil
+ if isTeam and not player.Neutral then
+ currentColor = player.TeamColor.Color
+ else
+ currentColor = Color3.new(1,1,1)
+ end
+ playerObject, changePlayerNameFunction = createPlayerName(player.Name, player.MembershipType, currentColor, getFriendStatus(player))
+
+ if not playerTable[player] then
+ playerTable[player] = {}
+ end
+ if not playerTable[player].Connections then
+ playerTable[player].Connections = {}
+ end
+ if not playerTable[player].CurrentTeam then
+ playerTable[player].CurrentTeam = nil
+ end
+ if not playerTable[player].LastTeam then
+ playerTable[player].LastTeam = nil
+ end
+ playerTable[player]["NameObject" .. suffix] = playerObject
+ playerTable[player]["ChangeName" .. suffix] = changePlayerNameFunction
+
+ if isScore then
+ local statObject = nil
+ local textChangers = nil
+ playerObject, statObject, textChangers = createStatColumns(playerObject, numStatColumns, false, suffix == "Big")
+ playerTable[player]["StatObject" .. suffix]= statObject
+ playerTable[player]["StatChangers" .. suffix] = textChangers
+
+ local statValues, leaderstats = getStatValuesForPlayer(player)
+ if not statValues or #statValues < numStatColumns then
+ if not playerTable[player].LeaderStatConnections then
+ playerTable[player].LeaderStatConnections = {}
+ end
+ --Setup a listener to see when this data gets filled in
+ if not leaderstats then
+ --We don't even have a leaderstats child, wait for one
+ table.insert(playerTable[player].LeaderStatConnections,
+ player.ChildAdded:connect(
+ function(child)
+ if child.Name == "leaderstats" then
+ --Connections will be torn down
+ recreatePlayerFunction(player)
+ else
+ table.insert(playerTable[player].LeaderStatConnections,
+ child.Changed:connect(
+ function(prop)
+ if prop == "Name" and child.Name == "leaderstats" then
+ --Connections will be torn down
+ recreatePlayerFunction(player)
+ end
+ end))
+ end
+ end))
+ else
+ --We have a leaderstats, but not enough children, recreate if we get them
+ table.insert(playerTable[player].LeaderStatConnections,
+ leaderstats.ChildAdded:connect(
+ function(child)
+ --TODO only look for IntValue
+ recreatePlayerFunction(player)
+ end)
+ )
+ table.insert(playerTable[player].LeaderStatConnections,
+ leaderstats.AncestryChanged:connect(
+ function(child)
+ --We got deleted, try again
+ recreatePlayerFunction(player)
+ end)
+ )
+ end
+ end
+ if statValues then
+ if not playerTable[player].StatValues then
+ playerTable[player].StatValues = {}
+ end
+ local pos = 1
+ while pos <= numStatColumns and pos <= #statValues do
+ local currentColumn = pos
+ local statValue = statValues[pos]
+ local statChanger = textChangers[pos]
+
+ local updateStat = function(val)
+ statChanger(val)
+ if playerTable[player] ~= nil then recomputeTeamScore(playerTable[player].CurrentTeam, currentColumn) end
+ end
+ if pos > #playerTable[player].StatValues then
+ table.insert(playerTable[player].StatValues, statValue)
+ end
+
+ if type(statValue) ~= "number" and statValue["Changed"] then
+ table.insert(playerTable[player].Connections,
+ statValue.Changed:connect(updateStat)
+ )
+ end
+
+ table.insert(playerTable[player].Connections,
+ statValue.AncestryChanged:connect(
+ function()
+ recreatePlayerFunction(player)
+ end)
+ )
+ updateStat(statValue.Value)
+ pos = pos + 1
+ end
+ end
+ end
+
+ if supportFriends and player ~= game.Players.LocalPlayer and player.userId > 0 and game.Players.LocalPlayer.userId > 0 then
+ local button = Instance.new("TextButton")
+ button.Name = playerObject.Name .. "Button"
+ button.Text = ""
+ button.Active = false
+ button.Size = playerObject.Size
+ button.Position = playerObject.Position
+ button.BackgroundColor3 = playerObject.BackgroundColor3
+
+ local secondButton = Instance.new("TextButton")
+ secondButton.Name = playerObject.Name .. "RealButton"
+ secondButton.Text = ""
+ secondButton.BackgroundTransparency = 1
+ secondButton.BackgroundColor3 = playerObject.BackgroundColor3
+ local theNameLabel = playerObject:findFirstChild("NameLabel",true)
+ secondButton.Parent.BackgroundTransparency = 1
+ secondButton.Parent.Visible = true
+ secondButton.ZIndex = 2
+ secondButton.Size = UDim2.new(1,0,1,0)
+
+ local previousTransparency = nil
+ table.insert(playerTable[player].Connections,
+ secondButton.MouseEnter:connect(
+ function(x,y)
+ if playerContextMenu and playerContextMenu.Visible then
+ return
+ end -- don't update if we currently see it
+
+ updatePlayerContextMenu(player,x,y)
+ if not playerContextMenuHasItems() then return end -- don't show if we have nothing to show
+
+ if previousTransparency == nil then
+ previousTransparency = secondButton.BackgroundTransparency
+ end
+ secondButton.Parent.BackgroundTransparency = 0
+ end))
+ table.insert(playerTable[player].Connections,
+ secondButton.MouseLeave:connect(
+ function()
+ if previousTransparency ~= nil then
+ previousTransparency = nil
+ end
+ delay(0.01,function()
+ if playerContextMenu and not inContextMenu then
+ playerContextMenu.Visible = false
+ end
+ end)
+ secondButton.Parent.BackgroundTransparency = 1
+ end))
+
+ local mouseDownX, mouseDownY
+ table.insert(playerTable[player].Connections,
+ secondButton.MouseButton1Down:connect(function(x,y)
+ mouseDownX = x
+ mouseDownY = y
+ end))
+ table.insert(playerTable[player].Connections,
+ secondButton.MouseButton1Click:connect(function()
+ showPlayerMenu(player, mouseDownX, secondButton.AbsolutePosition.Y + secondButton.AbsoluteSize.Y )
+ end))
+ playerObject.BackgroundTransparency = 1
+ playerObject.Size = UDim2.new(1,0,1,0)
+ playerObject.Position = UDim2.new(0,0,0,0)
+ playerObject.Parent = button
+
+ playerTable[player]["MainObject" .. suffix] = button
+
+ playerObject = button
+ else
+ playerTable[player]["MainObject" .. suffix] = playerObject
+
+ if player == game.Players.LocalPlayer and supportFriends then
+ table.insert(playerTable[player].Connections,
+ player.FriendStatusChanged:connect(
+ function(otherPlayer, friendStatus)
+ if friendRequestBlacklist[otherPlayer] then
+ updatePlayerFriendStatus(playerTable[otherPlayer]["NameObject" .. suffix], Enum.FriendStatus.NotFriend)
+ elseif playerTable[otherPlayer] then
+ updatePlayerFriendStatus(playerTable[otherPlayer]["NameObject" .. suffix], friendStatus)
+ end
+ end)
+ )
+ end
+ end
+ table.insert(playerTable[player].Connections,
+ player.Changed:connect(
+ function(prop)
+ if prop == "MembershipType" then
+ updatePlayerName(playerTable[player]["NameObject" .. suffix], player.MembershipType, currentColor)
+ elseif prop == "Name" then
+ playerTable[player]["ChangeName" .. suffix](player.Name)
+ elseif prop == "Neutral" or prop == "TeamColor" then
+ assignToTeam(player)
+ end
+ end)
+ )
+ return playerObject
+ end
+
+ local function doSort(tableToSort, objectName, order, startPos, sortType, ascending)
+ local orderedPlayerTable = {}
+ getLocalPlayer = false
+ for i, player in ipairs(tableToSort) do
+ if playerTable[player] then
+ if playerTable[player][objectName] ~= nil then
+ if player ~= game.Players.LocalPlayer then
+ table.insert(orderedPlayerTable,playerTable[player][objectName])
+ else
+ getLocalPlayer = true
+ end
+ end
+ end
+ end
+
+ if sortType == nil then -- default back to alphabetical sort
+ table.sort(orderedPlayerTable,function(a,b)
+ return string.lower(a:FindFirstChild("FullNameLabel",true).Text) < string.lower(b:FindFirstChild("FullNameLabel",true).Text)
+ end)
+ else -- we are sorting by a value
+ table.sort(orderedPlayerTable,function(a,b)
+ if ascending then
+ currentSortName = ""
+ return tonumber(a:FindFirstChild(sortType,true).Text) > tonumber(b:FindFirstChild(sortType,true).Text)
+ else
+ currentSortName = sortType
+ return tonumber(a:FindFirstChild(sortType,true).Text) < tonumber(b:FindFirstChild(sortType,true).Text)
+ end
+ end)
+ end
+ if getLocalPlayer and playerTable[game.Players.LocalPlayer] and playerTable[game.Players.LocalPlayer][objectName] then
+ table.insert(orderedPlayerTable,1,playerTable[game.Players.LocalPlayer][objectName])
+ end
+ for i = 1, #orderedPlayerTable do
+ order[orderedPlayerTable[i]] = startPos
+ startPos = startPos + 1
+ end
+
+ return startPos
+ end
+
+ local function orderScrollList(scrollOrder, objectName, scrollFrame, sortType, ascending)
+ local pos = 0
+ local order = {}
+ local isTeam, isScore = getBoardTypeInfo()
+ for i, obj in ipairs(scrollOrder) do
+ order[obj] = 0
+ end
+
+ if isTeam then
+ local teams = getTeams()
+ for i, team in ipairs(teams) do
+ if teamTable[team][objectName] then
+ order[teamTable[team][objectName]] = pos
+ pos = pos + 1
+ end
+ pos = doSort(teamTable[team].Players, objectName, order, pos, sortType, ascending)
+ end
+
+ if #teamTable["Neutral"].Players > 0 then
+ teamTable["Neutral"][objectName].Parent = scrollFrame
+ order[teamTable["Neutral"][objectName]] = pos
+ pos = pos + 1
+ doSort(teamTable["Neutral"].Players, objectName, order, pos, sortType, ascending)
+ else
+ teamTable["Neutral"][objectName].Parent = nil
+ end
+ else
+ local players = getPlayers()
+ doSort(players, objectName, order, pos, sortType, ascending)
+ end
+
+ table.sort(scrollOrder,
+ function(a,b)
+ return order[a] < order[b]
+ end)
+ end
+
+ local function createPlayerListBasics(frame, isBig)
+ local headerFrame = Instance.new("Frame")
+ headerFrame.Name = "Header"
+ headerFrame.BackgroundTransparency = 1
+ headerFrame.Size = UDim2.new(1,-13,0,26)
+ headerFrame.Position = UDim2.new(0,0,0,0)
+ headerFrame.Parent = frame
+
+ local lowerPaneFrame = Instance.new("Frame")
+ lowerPaneFrame.Name = "ScrollingArea"
+ lowerPaneFrame.BackgroundTransparency = 1
+ lowerPaneFrame.Size = UDim2.new(1,-3,1,-26)
+ if not isBig then lowerPaneFrame.Size = UDim2.new(1,-3,1,-30) end
+ lowerPaneFrame.Position = UDim2.new(0,0,0,26)
+ lowerPaneFrame.Parent = frame
+
+ local scrollOrder = {}
+ local scrollFrame, scrollUp, scrollDown, recalculateScroll, scrollBar = RbxGui.CreateScrollingFrame(scrollOrder)
+
+ scrollBar.Size = UDim2.new(0, 17, 1, -36)
+ if isBig then scrollBar.Size = UDim2.new(0, 17, 1, -61) end
+ scrollBar.Parent = lowerPaneFrame
+
+ scrollFrame.Parent = lowerPaneFrame
+ scrollUp.Parent = lowerPaneFrame
+ scrollDown.Parent = lowerPaneFrame
+
+ if isBig then
+ scrollFrame.Position = UDim2.new(0,0,0,0)
+ scrollUp.Position = UDim2.new(1,-41,0,5)
+ scrollDown.Position = UDim2.new(1,-41,1,-35)
+ scrollBar.Position = UDim2.new(1, -41, 0, 24)
+
+ scrollFrame.Size = UDim2.new(1,-48,1,-16)
+ headerFrame.Size = UDim2.new(1,-20,0,26)
+
+ else
+ scrollBar.Position = UDim2.new(1, -15, 0, 14)
+ scrollBar.Size = UDim2.new(0,17,1,-36)
+ scrollFrame.Position = UDim2.new(0,1,0,0)
+ scrollUp.Position = UDim2.new(1,-15,0,-5)
+ scrollDown.Position = UDim2.new(1,-15,1,-20)
+
+ lowerPaneFrame.Position = UDim2.new(0,0,0,30)
+
+ local toggleScrollBar = function(visible)
+ if visible then
+ scrollFrame.Size = UDim2.new(1,-16,1,0)
+ headerFrame.Size = UDim2.new(1,-16,0,smallWindowHeaderYSize)
+ else
+ scrollFrame.Size = UDim2.new(1,0,1,0)
+ headerFrame.Size = UDim2.new(1,0,0,smallWindowHeaderYSize)
+ end
+ scrollUp.Visible = visible
+ scrollDown.Visible = visible
+ scrollBar.Visible = visible
+ end
+ scrollUp.Changed:connect(function(prop)
+ if prop == "Active" then
+ toggleScrollBar(scrollUp.Active or scrollDown.Active)
+ end
+ end)
+
+ scrollDown.Changed:connect(function(prop)
+ if prop == "Active" then
+ toggleScrollBar(scrollUp.Active or scrollDown.Active)
+ end
+ end)
+
+ toggleScrollBar(scrollUp.Active or scrollDown.Active)
+ end
+ return headerFrame, scrollFrame, recalculateScroll, scrollOrder
+ end
+
+ createBoardsFunction = function (boardType, numStatColumns)
+ local updatePlayerCount = function()
+ return #getPlayers()
+ end
+
+ local smallFrame = Instance.new("Frame")
+ smallFrame.Name = "SmallPlayerlist"
+ smallFrame.Position = smallWindowPosition
+ smallFrame.Active = false
+ smallFrame.Size = smallWindowSize
+ smallFrame.BackgroundColor3 = Color3.new(0,0,0)
+ smallFrame.BackgroundTransparency = 0.7
+ smallFrame.BorderSizePixel = 0
+
+ local bigFrame = Instance.new("Frame")
+ bigFrame.Name = "BigPlayerlist"
+ bigFrame.Size = bigWindowSize
+ bigFrame.Position = bigWindowPosition
+ bigFrame.BackgroundColor3 = Color3.new(0,0,0)
+ bigFrame.BackgroundTransparency = 0.7
+ bigFrame.BorderSizePixel = 0
+ bigFrame.Visible = false
+
+ local bigFrameWrapper = Instance.new("Frame")
+ bigFrameWrapper.Name = "Expander"
+ bigFrameWrapper.Size = UDim2.new(1,21,1,16)
+ bigFrameWrapper.Position = UDim2.new(0, 0, 0,0)
+ bigFrameWrapper.BackgroundTransparency = 1
+ bigFrameWrapper.Parent = bigFrame
+
+ local smallHeaderFrame, scrollFrameSmall, recalculateScrollSmall, scrollOrderSmall = createPlayerListBasics(smallFrame, false)
+ local bigHeaderFrame, scrollFrameBig, recalculateScrollBig, scrollOrderBig = createPlayerListBasics(bigFrameWrapper, true)
+
+ local playerListButton = Instance.new("ImageButton")
+ playerListButton.Name = "GoBigButton"
+ playerListButton.BackgroundTransparency = 1
+ playerListButton.Image = "rbxasset://textures/ui/playerlist_small_maximize.png"
+ playerListButton.Size = UDim2.new(0.0, 35, 0, 29)
+ playerListButton.Position = UDim2.new(0, 0, 0, 0)
+ playerListButton.MouseButton1Click:connect(
+ function()
+ toggleBigWindow()
+ end)
+ playerListButton.Parent = smallHeaderFrame
+
+ playerListButton = Instance.new("ImageButton")
+ playerListButton.Name = "CloseButton"
+ playerListButton.BackgroundTransparency = 1
+ playerListButton.Image = "rbxasset://textures/ui/playerlist_small_hide.png"
+ playerListButton.Size = UDim2.new(0.0, 38, 0, 29)
+ playerListButton.Position = UDim2.new(0, 35, 0, 0)
+ playerListButton.MouseButton1Click:connect(
+ function()
+ transitionWindowsFunction("None")
+ end)
+ playerListButton.Parent = smallHeaderFrame
+
+ playerListButton = Instance.new("ImageButton")
+ playerListButton.Name = "CloseButton"
+ playerListButton.Image = "rbxasset://textures/ui/playerlist_big_hide.png"
+ playerListButton.BackgroundTransparency = 1
+ playerListButton.Size = UDim2.new(0.0, 29, 0, 29)
+ playerListButton.Position = UDim2.new(1, -30, 0.5, -13)
+ playerListButton.MouseButton1Click:connect(
+ function()
+ toggleBigWindow()
+ end)
+ playerListButton.Parent = bigHeaderFrame
+
+ local placeName = Instance.new("TextButton")
+ placeName.Name = "PlaceName"
+ placeName.Text = " Players (" .. tostring(updatePlayerCount()) .. ")"
+ placeName.AutoButtonColor = false
+ placeName.FontSize = Enum.FontSize.Size24
+ placeName.TextXAlignment = Enum.TextXAlignment.Left
+ placeName.Font = Enum.Font.ArialBold
+ placeName.BorderSizePixel = 0
+ placeName.BackgroundColor3 = Color3.new(0,0,0)
+ placeName.BackgroundTransparency = 1
+ placeName.TextColor3 = Color3.new(1,1,1)
+ placeName.Size = UDim2.new(0.4, 0, 1, 0)
+ placeName.Position = UDim2.new(0, 0, 0.0, 0)
+ placeName = RbxGui.AutoTruncateTextObject(placeName)
+ placeName.Parent = bigHeaderFrame
+
+ placeName.MouseEnter:connect(function()
+ placeName.BackgroundTransparency = 0.2
+ end)
+
+ placeName.MouseLeave:connect(function()
+ placeName.BackgroundTransparency = 1
+ end)
+
+ placeName.MouseButton1Click:connect(function()
+ sortPlayerListsFunction()
+ end)
+
+ currentBoardType = boardType
+ currentStatCount = numStatColumns
+ local isTeam, isScore = getBoardTypeInfo()
+ local players = getPlayers()
+
+ if isScore then
+ local statColumns = getStatColumns(players)
+ numStatColumns = #statColumns
+ if numStatColumns > 3 then
+ numStatColumns = 3
+ end
+ createStatHeaders(statColumns, numStatColumns, false).Parent = smallHeaderFrame
+ createStatHeaders(statColumns, currentStatCount, true).Parent = bigHeaderFrame
+ end
+
+ --Clean up all old stuff
+ resetPlayerTable()
+ updatePlayerCount()
+
+ for i, player in ipairs(players) do
+ local playerObject = buildPlayerObject(player, numStatColumns, "Small")
+ table.insert(scrollOrderSmall, playerObject)
+ playerObject.Parent = scrollFrameSmall
+
+ playerObject = buildPlayerObject(player, currentStatCount, "Big")
+ table.insert(scrollOrderBig, playerObject)
+ playerObject.Parent = scrollFrameBig
+ end
+
+ --Clean up old stuff
+ resetTeamTable()
+
+ local teamStatObjects = {}
+ if isTeam then
+ local teams = getTeams()
+ local i = #teams
+ while i >= 1 do
+ --We go backwards so the "first" team color gets the team
+ local team = teams[i]
+ teamColorTable[team.TeamColor.Name] = team
+ i = i - 1
+ end
+
+ --Adding/Removing a Team causes a full invalidation of the board
+ for i, team in ipairs(teams) do
+ local teamObject = buildTeamObject(team, numStatColumns, "Small")
+ table.insert(scrollOrderSmall, teamObject)
+ teamObject.Parent = scrollFrameSmall
+
+ teamObject = buildTeamObject(team, currentStatCount, "Big")
+ table.insert(scrollOrderBig, teamObject)
+ teamObject.Parent = scrollFrameBig
+ end
+
+ teamTable["Neutral"] = {}
+ teamTable["Neutral"].Players = {}
+
+ local neutralTeamObject = createTeamName("Neutral", BrickColor.palette(8))
+ teamTable["Neutral"].NameObjectSmall = neutralTeamObject
+ teamTable["Neutral"].StatObjectSmall = nil
+ teamTable["Neutral"].MainObjectSmall = neutralTeamObject
+ table.insert(scrollOrderSmall, neutralTeamObject)
+
+ neutralTeamObject = createTeamName("Neutral", BrickColor.palette(8))
+ teamTable["Neutral"].NameObjectBig = neutralTeamObject
+ teamTable["Neutral"].StatObjectBig = nil
+ teamTable["Neutral"].MainObjectBig = neutralTeamObject
+ table.insert(scrollOrderBig, neutralTeamObject)
+
+ local neutralPlayers = {}
+ for i, player in ipairs(players) do
+ assignToTeam(player)
+ end
+ end
+
+ removePlayerFunction = function(player)
+ if playerTable[player] then
+ clearTableEntry(player, playerTable[player])
+
+ placeName.Text = " Players (" .. tostring(updatePlayerCount()) .. ")"
+
+ ArrayRemove(scrollOrderSmall, playerTable[player].MainObjectSmall)
+ ArrayRemove(scrollOrderBig, playerTable[player].MainObjectBig)
+
+ playerTable[player] = nil
+ recalculateSmallPlayerListSize(smallFrame)
+ end
+ end
+ recreatePlayerFunction = function(player)
+ placeName.Text = " Players (" .. tostring(updatePlayerCount()) .. ")"
+
+ removePlayerFunction(player)
+
+ local playerObject = buildPlayerObject(player, numStatColumns, "Small")
+ table.insert(scrollOrderSmall, playerObject)
+ robloxLock(playerObject)
+ playerObject.Parent = scrollFrameSmall
+
+ playerObject = buildPlayerObject(player, currentStatCount, "Big")
+ table.insert(scrollOrderBig, playerObject)
+ robloxLock(playerObject)
+ playerObject.Parent = scrollFrameBig
+
+ local isTeam, isScore = getBoardTypeInfo()
+ if isTeam then
+ assignToTeam(player)
+ end
+
+ sortPlayerListsFunction()
+ recalculateSmallPlayerListSize(smallFrame)
+ end
+
+ if screenResizeCon then screenResizeCon:disconnect() end
+ screenResizeCon = screen.Changed:connect(
+ function(prop)
+ if prop == "AbsoluteSize" then
+ wait()
+ recalculateSmallPlayerListSize(smallFrame)
+ end
+ end)
+
+ sortPlayerListsFunction = function(sortType, ascending)
+ orderScrollList(scrollOrderSmall, "MainObjectSmall", scrollFrameSmall, sortType, ascending)
+ recalculateScrollSmall()
+ createAlternatingRows(scrollOrderSmall)
+
+ orderScrollList(scrollOrderBig, "MainObjectBig", scrollFrameBig, sortType, ascending)
+ recalculateScrollBig()
+ createAlternatingRows(scrollOrderBig)
+ end
+
+ sortPlayerListsFunction()
+
+ robloxLock(smallFrame)
+ robloxLock(bigFrame)
+ return smallFrame, bigFrame
+ end
+
+ --Teams changing invalidates the whole board
+ local function teamsChanged()
+ if debounceTeamsChanged then
+ return
+ end
+
+ debounceTeamsChanged = true
+ wait()
+ rebuildBoard(script.Parent, determineBoardType())
+ debounceTeamsChanged = false
+ end
+
+
+ local checkIfBoardChanged = function()
+ local newBoardType, numStats = determineBoardType()
+ if newBoardType ~= currentBoardType or numStats ~= currentStatCount then
+ rebuildBoard(script.Parent, newBoardType, numStats)
+ end
+ end
+
+ local function buildPlayerList()
+ waitForChild(game, "Players")
+ waitForProperty(game.Players, "LocalPlayer")
+
+ local teams = game:GetService("Teams")
+ if teams then
+ local teamConnections = {}
+
+ teams.ChildAdded:connect(
+ function(child)
+ if child:IsA("Team") then
+ teamsChanged()
+ teamConnections[child] = child.Changed:connect(
+ function(prop)
+ if prop == "TeamColor" or prop == "Name" then
+ --Rebuild when things change
+ teamsChanged()
+ end
+ end)
+ end
+ end)
+ teams.ChildRemoved:connect(
+ function(child)
+ if child:IsA("Team") then
+ if teamConnections[child] then
+ teamConnections[child]:disconnect()
+ teamConnections[child] = nil
+ end
+ teamsChanged()
+ end
+ end)
+ end
+
+ game.Players.ChildAdded:connect(
+ function(player)
+ if player:IsA("Player") then
+ addPlayerFunction(player)
+ end
+ end)
+
+ game.Players.ChildRemoved:connect(
+ function(player)
+ if player:IsA("Player") then
+ if removePlayerFunction then
+ removePlayerFunction(player)
+ end
+ end
+ end)
+
+ rebuildBoard(script.Parent, determineBoardType())
+
+ delay(0,
+ function()
+ while true do
+ wait(5)
+ checkIfBoardChanged()
+ end
+ end)
+ end
+
+ buildPlayerList()
+end
+
+if not personalServerPlace then -- one more backup check
+ local theBool = game.Workspace:FindFirstChild("PSVariable")
+ if theBool and theBool:IsA("BoolValue") then
+ personalServerPlace = true
+ end
+end
+
+if personalServerPlace then
+ addPersonalServerContext()
+ setupBuildToolManagement()
+else
+ local psVarCon = nil
+ psVarCon = game.Workspace.ChildAdded:connect(function(child)
+ if child:IsA("BoolValue") and child.Name == "PSVariable" then
+ psVarCon:disconnect()
+ personalServerPlace = true
+ addPersonalServerContext()
+ setupBuildToolManagement()
+ end
+ end)
+end
+
+
+
+ -
+
+ Dialogs
+
+
-
+
+ false
+ 4288914085
+ 1
+ 4279970357
+ 1
+ false
+ false
+ ControlFrame
+
+ 0
+ 0
+ 0
+ 0
+
+
+ 1
+ 0
+ 1
+ 0
+
+ 0
+ 0
+ true
+ 1
+
+
-
+
+ false
+ 4288914085
+ 1
+ 4279970357
+ 1
+ false
+ false
+ BottomLeftControl
+
+ 0
+ 0
+ 1
+ -46
+
+
+ 0
+ 130
+ 0
+ 46
+
+ 0
+ 0
+ true
+ 1
+
+
+ -
+
+ false
+ 4288914085
+ 1
+ 4279970357
+ 1
+ false
+ false
+ NotificationBox
+
+ 1
+ -200
+ 0.5
+ 0
+
+
+ 0
+ 200
+ 0.419999987
+ 0
+
+ 0
+ true
+ 1
+
+
+
+ -
+
+ false
+
+ Init
+ --rbxsig%XeVmMtUuu+dXh8pEbcaTkr2m9RJZXY42LaACJ12YYcuPtOUxy4Azi8uMDGU8ZTh7cvZC9BlOWgqmZHKjESSdfOZl0/cgd2JKHPZ2UqiqA1slJa7R5GtCcGXlNPHW8KDYgJGRuwe8h5CSiMDOl6QLTSEegTOG7fzHk/n1AFcRN8I=%
+--rbxassetid%39250920%
+--fixed by Carrot#0559
+
+function waitForProperty(instance, name)
+ while not instance[name] do
+ instance.Changed:wait()
+ end
+end
+
+local beter = game.Lighting
+
+function waitForDialogChildrenMyLord(beter, name)
+ while not beter:FindFirstChild(name) do
+ beter.ChildAdded:wait()
+ end
+end
+
+local bois = game.Players.LocalPlayer.PlayerGui
+
+function waitForFaker(bois, name)
+ while not bois:FindFirstChild(name) do
+ bois.ChildAdded:wait()
+ end
+end
+
+
+local mainFrame
+local choices = {}
+local lastChoice
+local choiceMap = {}
+local currentConversationDialog
+local currentConversationPartner
+local currentAbortDialogScript
+
+local tooFarAwayMessage = "You are too far away to chat!"
+local tooFarAwaySize = 300
+local characterWanderedOffMessage = "Chat ended because you walked away"
+local characterWanderedOffSize = 350
+local conversationTimedOut = "Chat ended because you didn't reply"
+local conversationTimedOutSize = 350
+
+local player
+local screenGui
+local chatNotificationGui
+local messageDialog
+local timeoutScript = game.Lighting.ReenableDialogScript
+local reenableDialogScript = game.Lighting.TimeoutScript
+local dialogMap = {}
+local dialogConnections = {}
+
+local gui = nil
+--waitForDialogChildrenMyLord(game,"CoreGui")
+--waitForDialogChildrenMyLord(game.CoreGui,"RobloxGui")
+--if game.CoreGui.RobloxGui:FindFirstChild("ControlFrame") then
+-- gui = game.CoreGui.RobloxGui.ControlFrame
+--else
+-- gui = game.CoreGui.RobloxGui
+--end
+
+function currentTone()
+ if currentConversationDialog then
+ return currentConversationDialog.Tone
+ else
+ return Enum.DialogTone.Neutral
+ end
+end
+
+
+function createChatNotificationGui()
+ chatNotificationGui = Instance.new("BillboardGui")
+ chatNotificationGui.Name = "ChatNotificationGui"
+ chatNotificationGui.ExtentsOffset = Vector3.new(0,1,0)
+ chatNotificationGui.Size = UDim2.new(4, 0, 5.42857122, 0)
+ chatNotificationGui.SizeOffset = Vector2.new(0,0)
+ chatNotificationGui.StudsOffset = Vector3.new(0.4, 4.3, 0)
+ chatNotificationGui.Enabled = true
+ chatNotificationGui.Active = true
+
+ local image = Instance.new("ImageLabel")
+ image.Name = "Image"
+ image.Active = false
+ image.BackgroundTransparency = 1
+ image.Position = UDim2.new(0,0,0,0)
+ image.Size = UDim2.new(1.0,0,1.0,0)
+ image.Image = ""
+ image.Parent = chatNotificationGui
+
+
+ local button = Instance.new("ImageButton")
+ button.Name = "Button"
+ button.AutoButtonColor = false
+ button.Position = UDim2.new(0.0879999995, 0, 0.0529999994, 0)
+ button.Size = UDim2.new(0.829999983, 0, 0.460000008, 0)
+ button.Image = ""
+ button.BackgroundTransparency = 1
+ button.Parent = image
+end
+
+function getChatColor(tone)
+ if tone == Enum.DialogTone.Neutral then
+ return Enum.ChatColor.Blue
+ elseif tone == Enum.DialogTone.Friendly then
+ return Enum.ChatColor.Green
+ elseif tone == Enum.DialogTone.Enemy then
+ return Enum.ChatColor.Red
+ end
+end
+
+function styleChoices(tone)
+ for i, obj in pairs(choices) do
+ resetColor(obj, tone)
+ end
+ resetColor(lastChoice, tone)
+end
+
+function styleMainFrame(tone)
+ if tone == Enum.DialogTone.Neutral then
+ mainFrame.Style = Enum.FrameStyle.ChatBlue
+ mainFrame.Tail.Image = "rbxasset://textures/chatBubble_botBlue_tailRight.png"
+ elseif tone == Enum.DialogTone.Friendly then
+ mainFrame.Style = Enum.FrameStyle.ChatGreen
+ mainFrame.Tail.Image = "rbxasset://textures/chatBubble_botGreen_tailRight.png"
+ elseif tone == Enum.DialogTone.Enemy then
+ mainFrame.Style = Enum.FrameStyle.ChatRed
+ mainFrame.Tail.Image = "rbxasset://textures/chatBubble_botRed_tailRight.png"
+ end
+
+ styleChoices(tone)
+end
+function setChatNotificationTone(gui, purpose, tone)
+ if tone == Enum.DialogTone.Neutral then
+ gui.Image.Image = "rbxasset://textures/chatBubble_botBlue_notify_bkg.png"
+ elseif tone == Enum.DialogTone.Friendly then
+ gui.Image.Image = "rbxasset://textures/chatBubble_botGreen_notify_bkg.png"
+ elseif tone == Enum.DialogTone.Enemy then
+ gui.Image.Image = "rbxasset://textures/chatBubble_botRed_notify_bkg.png"
+ end
+ if purpose == Enum.DialogPurpose.Quest then
+ gui.Image.Button.Image = "rbxasset://textures/chatBubble_bot_notify_bang.png"
+ elseif purpose == Enum.DialogPurpose.Help then
+ gui.Image.Button.Image = "rbxasset://textures/chatBubble_bot_notify_question.png"
+ elseif purpose == Enum.DialogPurpose.Shop then
+ gui.Image.Button.Image = "rbxasset://textures/chatBubble_bot_notify_money.png"
+ end
+end
+
+function createMessageDialog()
+ messageDialog = Instance.new("Frame");
+ messageDialog.Name = "DialogScriptMessage"
+ messageDialog.Style = Enum.FrameStyle.RobloxRound
+ messageDialog.Visible = false
+
+ local text = Instance.new("TextLabel")
+ text.Name = "Text"
+ text.Position = UDim2.new(0,0,0,-1)
+ text.Size = UDim2.new(1,0,1,0)
+ text.FontSize = Enum.FontSize.Size14
+ text.BackgroundTransparency = 1
+ text.TextColor3 = Color3.new(1,1,1)
+ text.Parent = messageDialog
+end
+
+function showMessage(msg, size)
+ messageDialog.Text.Text = msg
+ messageDialog.Size = UDim2.new(0,size,0,40)
+ messageDialog.Position = UDim2.new(0.5, -size/2, 0.5, -40)
+ messageDialog.Visible = true
+ wait(2)
+ messageDialog.Visible = false
+end
+
+function variableDelay(str)
+ local length = math.min(string.len(str), 100)
+ wait(0.75 + ((length/75) * 1.5))
+end
+
+function resetColor(frame, tone)
+ if tone == Enum.DialogTone.Neutral then
+ frame.BackgroundColor3 = Color3.new(0/255, 0/255, 179/255)
+ frame.Number.TextColor3 = Color3.new(45/255, 142/255, 245/255)
+ elseif tone == Enum.DialogTone.Friendly then
+ frame.BackgroundColor3 = Color3.new(0/255, 77/255, 0/255)
+ frame.Number.TextColor3 = Color3.new(0/255, 190/255, 0/255)
+ elseif tone == Enum.DialogTone.Enemy then
+ frame.BackgroundColor3 = Color3.new(140/255, 0/255, 0/255)
+ frame.Number.TextColor3 = Color3.new(255/255,88/255, 79/255)
+ end
+end
+
+function highlightColor(frame, tone)
+ if tone == Enum.DialogTone.Neutral then
+ frame.BackgroundColor3 = Color3.new(2/255, 108/255, 255/255)
+ frame.Number.TextColor3 = Color3.new(1, 1, 1)
+ elseif tone == Enum.DialogTone.Friendly then
+ frame.BackgroundColor3 = Color3.new(0/255, 128/255, 0/255)
+ frame.Number.TextColor3 = Color3.new(1, 1, 1)
+ elseif tone == Enum.DialogTone.Enemy then
+ frame.BackgroundColor3 = Color3.new(204/255, 0/255, 0/255)
+ frame.Number.TextColor3 = Color3.new(1, 1, 1)
+ end
+end
+
+function wanderDialog()
+ print("Wander")
+ mainFrame.Visible = false
+ endDialog()
+ showMessage(characterWanderedOffMessage, characterWanderedOffSize)
+end
+
+function timeoutDialog()
+ print("Timeout")
+ mainFrame.Visible = false
+ endDialog()
+ showMessage(conversationTimedOut, conversationTimedOutSize)
+end
+function normalEndDialog()
+ print("Done")
+ endDialog()
+end
+
+function endDialog()
+ if currentAbortDialogScript then
+ currentAbortDialogScript:Remove()
+ currentAbortDialogScript = nil
+ end
+
+ local dialog = currentConversationDialog
+ currentConversationDialog = nil
+ if dialog and dialog.InUse then
+ local reenableScript = reenableDialogScript:Clone()
+ reenableScript.archivable = false
+ reenableScript.Disabled = false
+ reenableScript.Parent = dialog
+ end
+
+ for dialog, gui in pairs(dialogMap) do
+ if dialog and gui then
+ gui.Enabled = not dialog.InUse
+ end
+ end
+
+ currentConversationPartner = nil
+end
+
+function sanitizeMessage(msg)
+ if string.len(msg) == 0 then
+ return "..."
+ else
+ return msg
+ end
+end
+
+function selectChoice(choice)
+ renewKillswitch(currentConversationDialog)
+
+ --First hide the Gui
+ mainFrame.Visible = false
+ if choice == lastChoice then
+ game.Chat:Chat(game.Players.LocalPlayer.Character, "Goodbye!", getChatColor(currentTone()))
+
+ normalEndDialog()
+ else
+ local dialogChoice = choiceMap[choice]
+
+ game.Chat:Chat(game.Players.LocalPlayer.Character, sanitizeMessage(dialogChoice.UserDialog), getChatColor(currentTone()))
+ wait(1)
+ --currentConversationDialog:SignalDialogChoiceSelected(player, dialogChoice)
+ game.Chat:Chat(currentConversationPartner, sanitizeMessage(dialogChoice.ResponseDialog), getChatColor(currentTone()))
+
+ variableDelay(dialogChoice.ResponseDialog)
+ presentDialogChoices(currentConversationPartner, dialogChoice:GetChildren())
+ end
+end
+
+function newChoice(numberText)
+ local frame = Instance.new("TextButton")
+ frame.BackgroundColor3 = Color3.new(0/255, 0/255, 179/255)
+ frame.AutoButtonColor = false
+ frame.BorderSizePixel = 0
+ frame.Text = ""
+ frame.MouseEnter:connect(function() highlightColor(frame, currentTone()) end)
+ frame.MouseLeave:connect(function() resetColor(frame, currentTone()) end)
+ frame.MouseButton1Click:connect(function() selectChoice(frame) end)
+
+ local number = Instance.new("TextLabel")
+ number.Name = "Number"
+ number.TextColor3 = Color3.new(127/255, 212/255, 255/255)
+ number.Text = numberText
+ number.FontSize = Enum.FontSize.Size14
+ number.BackgroundTransparency = 1
+ number.Position = UDim2.new(0,4,0,2)
+ number.Size = UDim2.new(0,20,0,24)
+ number.TextXAlignment = Enum.TextXAlignment.Left
+ number.TextYAlignment = Enum.TextYAlignment.Top
+ number.Parent = frame
+
+ local prompt = Instance.new("TextLabel")
+ prompt.Name = "UserPrompt"
+ prompt.BackgroundTransparency = 1
+ prompt.TextColor3 = Color3.new(1,1,1)
+ prompt.FontSize = Enum.FontSize.Size14
+ prompt.Position = UDim2.new(0,28, 0, 2)
+ prompt.Size = UDim2.new(1,-32, 1, -4)
+ prompt.TextXAlignment = Enum.TextXAlignment.Left
+ prompt.TextYAlignment = Enum.TextYAlignment.Top
+ prompt.TextWrap = true
+ prompt.Parent = frame
+
+ return frame
+end
+function initialize(parent)
+ choices[1] = newChoice("1)")
+ choices[2] = newChoice("2)")
+ choices[3] = newChoice("3)")
+ choices[4] = newChoice("4)")
+
+ lastChoice = newChoice("5)")
+ lastChoice.UserPrompt.Text = "Goodbye!"
+ lastChoice.Size = UDim2.new(1,0,0,28)
+
+ mainFrame = Instance.new("Frame")
+ mainFrame.Name = "UserDialogArea"
+ mainFrame.Size = UDim2.new(0, 350, 0, 200)
+ mainFrame.Style = Enum.FrameStyle.ChatBlue
+ mainFrame.Visible = false
+
+ local imageLabel = Instance.new("ImageLabel")
+ imageLabel.Name = "Tail"
+ imageLabel.Size = UDim2.new(0,62,0,53)
+ imageLabel.Position = UDim2.new(1,8,0.25)
+ imageLabel.Image = "rbxasset://textures/chatBubble_botBlue_tailRight.png"
+ imageLabel.BackgroundTransparency = 1
+ imageLabel.Parent = mainFrame
+
+ for n, obj in pairs(choices) do
+ obj.Parent = mainFrame
+ end
+ lastChoice.Parent = mainFrame
+
+ mainFrame.Parent = parent
+end
+
+function presentDialogChoices(talkingPart, dialogChoices)
+ if not currentConversationDialog then
+ return
+ end
+
+ currentConversationPartner = talkingPart
+ local sortedDialogChoices = {}
+ for n, obj in pairs(dialogChoices) do
+ if obj:IsA("DialogChoice") then
+ table.insert(sortedDialogChoices, obj)
+ end
+ end
+ table.sort(sortedDialogChoices, function(a,b) return a.Name < b.Name end)
+
+ if #sortedDialogChoices == 0 then
+ normalEndDialog()
+ return
+ end
+
+ local pos = 1
+ local yPosition = 0
+ choiceMap = {}
+ for n, obj in pairs(choices) do
+ obj.Visible = false
+ end
+
+ for n, obj in pairs(sortedDialogChoices) do
+ if pos <= #choices then
+ --3 lines is the maximum, set it to that temporarily
+ choices[pos].Size = UDim2.new(1, 0, 0, 24*3)
+ choices[pos].UserPrompt.Text = obj.UserDialog
+ local height = math.ceil(choices[pos].UserPrompt.TextBounds.Y/24)*24
+
+ choices[pos].Position = UDim2.new(0, 0, 0, yPosition)
+ choices[pos].Size = UDim2.new(1, 0, 0, height)
+ choices[pos].Visible = true
+
+ choiceMap[choices[pos]] = obj
+
+ yPosition = yPosition + height
+ pos = pos + 1
+ end
+ end
+
+ lastChoice.Position = UDim2.new(0,0,0,yPosition)
+ lastChoice.Number.Text = pos .. ")"
+
+ mainFrame.Size = UDim2.new(0, 350, 0, yPosition+24+32)
+ mainFrame.Position = UDim2.new(0,20,0.0, -mainFrame.Size.Y.Offset-20)
+ styleMainFrame(currentTone())
+ mainFrame.Visible = true
+end
+
+function doDialog(dialog)
+ while not Instance.Lock(dialog, player) do
+ wait()
+ end
+
+ if dialog.InUse then
+ Instance.Unlock(dialog)
+ return
+ else
+ dialog.InUse = true
+ Instance.Unlock(dialog)
+ end
+
+ currentConversationDialog = dialog
+ game.Chat:Chat(dialog.Parent, dialog.InitialPrompt, getChatColor(dialog.Tone))
+ variableDelay(dialog.InitialPrompt)
+
+ presentDialogChoices(dialog.Parent, dialog:GetChildren())
+end
+
+function renewKillswitch(dialog)
+ if currentAbortDialogScript then
+ currentAbortDialogScript:Remove()
+ currentAbortDialogScript = nil
+ end
+
+ currentAbortDialogScript = timeoutScript:Clone()
+ currentAbortDialogScript.archivable = false
+ currentAbortDialogScript.Disabled = false
+ currentAbortDialogScript.Parent = dialog
+end
+
+function checkForLeaveArea()
+ while currentConversationDialog do
+ if currentConversationDialog.Parent and (player:DistanceFromCharacter(currentConversationDialog.Parent.Position) >= currentConversationDialog.ConversationDistance) then
+ wanderDialog()
+ end
+ wait(1)
+ end
+end
+
+function startDialog(dialog)
+ if dialog.Parent and dialog.Parent:IsA("BasePart") then
+ if player:DistanceFromCharacter(dialog.Parent.Position) >= dialog.ConversationDistance then
+ showMessage(tooFarAwayMessage, tooFarAwaySize)
+ return
+ end
+
+ for dialog, gui in pairs(dialogMap) do
+ if dialog and gui then
+ gui.Enabled = false
+ end
+ end
+
+ renewKillswitch(dialog)
+
+ delay(1, checkForLeaveArea)
+ doDialog(dialog)
+ end
+end
+
+function removeDialog(dialog)
+ if dialogMap[dialog] then
+ dialogMap[dialog]:Remove()
+ dialogMap[dialog] = nil
+ end
+ if dialogConnections[dialog] then
+ dialogConnections[dialog]:disconnect()
+ dialogConnections[dialog] = nil
+ end
+end
+
+function addDialog(dialog)
+ if dialog.Parent then
+ if dialog.Parent:IsA("BasePart") then
+ local chatGui = chatNotificationGui:clone()
+ chatGui.Enabled = not dialog.InUse
+ chatGui.Adornee = dialog.Parent
+ chatGui.Parent = game.Players.LocalPlayer.PlayerGui
+ chatGui.Image.Button.MouseButton1Click:connect(function() startDialog(dialog) end)
+ setChatNotificationTone(chatGui, dialog.Purpose, dialog.Tone)
+
+ dialogMap[dialog] = chatGui
+
+ dialogConnections[dialog] = dialog.Changed:connect(function(prop)
+ if prop == "Parent" and dialog.Parent then
+ --This handles the reparenting case, seperate from removal case
+ removeDialog(dialog)
+ addDialog(dialog)
+ elseif prop == "InUse" then
+ chatGui.Enabled = not currentConversationDialog and not dialog.InUse
+ if dialog == currentConversationDialog then
+ timeoutDialog()
+ end
+ elseif prop == "Tone" or prop == "Purpose" then
+ setChatNotificationTone(chatGui, dialog.Purpose, dialog.Tone)
+ end
+ end)
+ else -- still need to listen to parent changes even if current parent is not a BasePart
+ dialogConnections[dialog] = dialog.Changed:connect(function(prop)
+ if prop == "Parent" and dialog.Parent then
+ --This handles the reparenting case, seperate from removal case
+ removeDialog(dialog)
+ addDialog(dialog)
+ end
+ end)
+ end
+ end
+end
+
+
+--[[function fetchScripts()
+ local model = game:GetService("InsertService"):LoadAsset(39226062)
+ if type(model) == "string" then -- load failed, lets try again
+ wait(0.1)
+ model = game:GetService("InsertService"):LoadAsset(39226062)
+ end
+ if type(model) == "string" then -- not going to work, lets bail
+ return
+ end
+
+ waitForDialogChildrenMyLord(model,"TimeoutScript")
+ timeoutScript = model.TimeoutScript
+ waitForDialogChildrenMyLord(model,"ReenableDialogScript")
+ reenableDialogScript = model.ReenableDialogScript
+end
+]]--
+
+function onLoad()
+ waitForProperty(game.Players, "LocalPlayer")
+ player = game.Players.LocalPlayer
+ waitForProperty(player, "Character")
+
+ --print("Fetching Scripts")
+ --fetchScripts()
+
+ --print("Creating Guis")
+ createChatNotificationGui()
+
+ waitForFaker(bois,"Dialogs")
+ --print("Creating MessageDialog")
+ createMessageDialog()
+ messageDialog.Parent = game.Players.LocalPlayer.PlayerGui.Dialogs
+
+
+ --print("Initializing Frame")
+ local frame = Instance.new("Frame")
+ frame.Name = "DialogFrame"
+ frame.Position = UDim2.new(0,0,0,0)
+ frame.Size = UDim2.new(0,0,0,0)
+ frame.BackgroundTransparency = 1
+ frame.Parent = game.Players.LocalPlayer.PlayerGui.Dialogs.ControlFrame.BottomLeftControl
+ initialize(frame)
+
+ --print("Adding Dialogs")
+ game.CollectionService.ItemAdded:connect(function(obj) if obj:IsA("Dialog") then addDialog(obj) end end)
+ game.CollectionService.ItemRemoved:connect(function(obj) if obj:IsA("Dialog") then removeDialog(obj) end end)
+ for i, obj in pairs(game.CollectionService:GetCollection("Dialog")) do
+ if obj:IsA("Dialog") then
+ addDialog(obj)
+ end
+ end
+end
+
+onLoad()
+
+
+
+ -
+
+ true
+
+ ReenableDialogScript
+ wait(5)
+local dialog = script.Parent
+if dialog:IsA("Dialog") then
+ dialog.InUse = false
+end
+script:Remove()
+
+
+
+ -
+
+ true
+
+ TimeoutScript
+ wait(5)
+local dialog = script.Parent
+if dialog:IsA("Dialog") then
+ dialog.InUse = false
+end
+script:Remove()
+
+
+
+ -
+
+ Health
+
+
-
+
+ false
+ 4285215356
+ 1
+ 4279970357
+ 1
+ false
+ false
+ tray
+
+ 0.5
+ -44
+ 1
+ -26
+
+
+ 0
+ 170
+ 0
+ 18
+
+ 2
+ 0
+ true
+ 1
+
+
-
+
+ false
+ 4294967295
+ 1
+ 4279970357
+ 1
+ false
+ false
+ rbxasset://textures/healthgui/bkg.png
+ bkg
+
+ 0
+ 0
+ 0
+ 0
+
+
+ 1
+ 0
+ 1
+ 0
+
+ 0
+ true
+ 1
+
+
+ -
+
+ false
+ 4294967295
+ 1
+ 4279970357
+ 1
+ false
+ false
+ rbxasset://textures/healthgui/BarRed.png
+ barRed
+
+ 0.0189999994
+ 0
+ 0.100000001
+ 0
+
+
+ 0
+ 0
+ 0
+ 0
+
+ 0
+ true
+ 1
+
+
+ -
+
+ false
+ 4294967295
+ 1.00000012
+ 4279970357
+ 0
+ false
+ false
+ bar2
+
+ 0.0189999994
+ 0
+ 0.100000001
+ 0
+
+
+ 0.192000002
+ 0
+ 0.829999983
+ 0
+
+ 0
+ 0
+ true
+ 1
+
+
-
+
+ false
+
+ Init
+ h = game.Players.LocalPlayer.Character.Humanoid
+tray = script.Parent.Parent
+base = tray.Parent
+local lastHealth = 100
+local lastHealth2 = 100
+local maxWidth = 0.96
+
+function UpdateGUI(health)
+ local width = (health / h.MaxHealth) * maxWidth
+ local height = 0.83
+ local lastX = tray.bar.Position.X.Scale
+ local x = 0.019 + (maxWidth - width)
+ local y = 0.1
+
+ tray.bar.Position = UDim2.new(x,0,y, 0)
+ tray.bar.Size = UDim2.new(width, 0, height, 0)
+ -- If more than 1/4 health, bar = green. Else, bar = red.
+ if( (health / h.MaxHealth) > 0.25 ) then
+ tray.barRed.Size = UDim2.new(0, 0, 0, 0)
+ else
+ tray.barRed.Position = tray.bar.Position
+ tray.barRed.Size = tray.bar.Size
+ tray.bar.Size = UDim2.new(0, 0, 0, 0)
+ end
+
+ if ( (lastHealth - health) > (h.MaxHealth / 10) ) then
+ lastHealth = health
+
+ if h.Health ~= h.MaxHealth then
+ delay(0,function()
+ AnimateHurtOverlay()
+ end)
+ delay(0,function()
+ AnimateBars(x, y, lastX, height)
+ end)
+ end
+ else
+ lastHealth = health
+ end
+end
+
+function AnimateBars(x, y, lastX, height)
+ local width = math.abs(x - lastX)
+ if( x > lastX ) then
+ x = lastX
+ end
+ tray.bar2.Position = UDim2.new(x,0, y, 0)
+ tray.bar2.Size = UDim2.new(width, 0, height, 0)
+ tray.bar2.BackgroundTransparency = 0
+ local GBchannels = 1
+ local j = 0.2
+
+ local i_total = 30
+ for i=1,i_total do
+ -- Increment Values
+ if (GBchannels < 0.2) then
+ j = -j
+ end
+ GBchannels = GBchannels + j
+ if (i > (i_total - 10)) then
+ tray.bar2.BackgroundTransparency = tray.bar2.BackgroundTransparency + 0.1
+ end
+ tray.bar2.BackgroundColor3 = Color3.new(1, GBchannels, GBchannels)
+
+ wait(0.02)
+ end
+end
+
+function AnimateHurtOverlay()
+ -- Start:
+ -- overlay.Position = UDim2.new(0, 0, 0, -22)
+ -- overlay.Size = UDim2.new(1, 0, 1.15, 30)
+
+ -- Finish:
+ -- overlay.Position = UDim2.new(-2, 0, -2, -22)
+ -- overlay.Size = UDim2.new(4.5, 0, 4.65, 30)
+
+ overlay = base.hurtOverlay
+ overlay.Visible = true
+ overlay.Position = UDim2.new(-2, 0, -2, -22)
+ overlay.Size = UDim2.new(4.5, 0, 4.65, 30)
+ -- Animate In, fast
+ local i_total = 2
+ local wiggle_total = 0
+ local wiggle_i = 0.02
+ for i=1,i_total do
+ overlay.Position = UDim2.new( (-2 + (2 * (i/i_total)) + wiggle_total/2), 0, (-2 + (2 * (i/i_total)) + wiggle_total/2), -22 )
+ overlay.Size = UDim2.new( (4.5 - (3.5 * (i/i_total)) + wiggle_total), 0, (4.65 - (3.5 * (i/i_total)) + wiggle_total), 30 )
+ wait(0.01)
+ end
+
+ i_total = 30
+
+ wait(0.03)
+
+ -- Animate Out, slow
+ for i=1,i_total do
+ if( math.abs(wiggle_total) > (wiggle_i * 3) ) then
+ wiggle_i = -wiggle_i
+ end
+ wiggle_total = wiggle_total + wiggle_i
+ overlay.Position = UDim2.new( (0 - (2 * (i/i_total)) + wiggle_total/2), 0, (0 - (2 * (i/i_total)) + wiggle_total/2), -22 )
+ overlay.Size = UDim2.new( (1 + (3.5 * (i/i_total)) + wiggle_total), 0, (1.15 + (3.5 * (i/i_total)) + wiggle_total), 30 )
+ wait(0.01)
+ end
+
+ -- Hide after we're done
+ overlay.Position = UDim2.new(10, 0, 0, 0)
+ overlay.Visible = false
+end
+
+h.Changed:connect(function()
+ UpdateGUI(h.Health)
+ if ( (lastHealth2 - h.Health) > (h.MaxHealth / 10) ) then
+ lastHealth2 = h.Health
+ else
+ lastHealth2 = h.Health
+ end end)
+wait(0.1)
+script.Parent.Parent.Parent.Parent.HealthGUI:Remove()
+script.Parent.Parent.Parent.Name = "HealthGUI"
+
+
+
+ -
+
+ false
+ 4294967295
+ 1
+ 4279970357
+ 1
+ false
+ false
+ rbxasset://textures/healthgui/Bar.png
+ bar
+
+ 0.0189999994
+ 0
+ 0.100000001
+ 0
+
+
+ 0.959999979
+ 0
+ 0.829999983
+ 0
+
+ 0
+ true
+ 1
+
+
+ -
+
+ false
+ 4294967295
+ 1
+ 4279970357
+ 0
+ false
+ false
+ rbxasset://textures/healthgui/label.png
+ label
+
+ 0.680000007
+ 0
+ 0.300000012
+ 0
+
+
+ 0.25
+ 0
+ 0.349999994
+ 0
+
+ 0
+ true
+ 1
+
+
+
+ -
+
+ false
+ 4290164919
+ 1
+ 4279970357
+ 1
+ false
+ false
+ rbxasset://textures/healthgui/HurtOverlay.png
+ hurtOverlay
+
+ 2
+ 0
+ 0
+ -22
+
+
+ 1
+ 0
+ 1.1500001
+ 30
+
+ 0
+ false
+ 1
+
+
+ -
+
+ false
+
+ Hide
+ while true do
+ game.Players.LocalPlayer.PlayerGui.HealthGUI.tray.Visible = false
+ game.Players.LocalPlayer.PlayerGui.HealthGUI.hurtOverlay.Visible = false
+end
+
+
+
+ -
+
+ false
+
+ ResetCommand
+ function onChatted(msg, speaker)
+
+ source = string.lower(speaker.Name)
+ msg = string.lower(msg)
+ -- Note: This one is NOT caps sensitive
+
+ if msg == "!!!reset" then
+ speaker.Character.Humanoid.Health = 0
+ end
+end
+
+function onPlayerEntered(newPlayer)
+ newPlayer.Chatted:connect(function(msg) onChatted(msg, newPlayer) end)
+end
+
+game.Players.ChildAdded:connect(onPlayerEntered)
+
+
+ -
+
+ Backpack
+
+
-
+
+ false
+
+ BackpackBuilder
+ -- This script creates almost all gui elements found in the backpack (warning: there are a lot!)
+-- TODO: automate this process
+
+local gui = script.Parent
+
+-- A couple of necessary functions
+local function waitForChild(instance, name)
+ while not instance:FindFirstChild(name) do
+ instance.ChildAdded:wait()
+ end
+end
+local function waitForProperty(instance, property)
+ while not instance[property] do
+ instance.Changed:wait()
+ end
+end
+
+waitForChild(game,"Players")
+waitForProperty(game.Players,"LocalPlayer")
+local player = game.Players.LocalPlayer
+
+-- First up is the current loadout
+local CurrentLoadout = Instance.new("Frame")
+CurrentLoadout.Name = "CurrentLoadout"
+CurrentLoadout.Position = UDim2.new(0.5, -170, 1, -85)
+CurrentLoadout.Size = UDim2.new(0, 480, 0, 48)
+CurrentLoadout.BackgroundTransparency = 1
+
+CurrentLoadout.Parent = gui
+
+local Debounce = Instance.new("BoolValue")
+Debounce.Name = "Debounce"
+
+Debounce.Parent = CurrentLoadout
+
+for i = 0, 9 do
+ local slotFrame = Instance.new("Frame")
+
+ slotFrame.BackgroundColor3 = Color3.new(0,0,0)
+ slotFrame.BackgroundTransparency = 1
+ slotFrame.BorderColor3 = Color3.new(1,1,1)
+ slotFrame.Name = "Slot" .. tostring(i)
+ if i == 0 then
+ slotFrame.Position = UDim2.new(0.9,0,0,0)
+ else
+ slotFrame.Position = UDim2.new((i - 1) * 0.1,0,0,0)
+ end
+ slotFrame.Size = UDim2.new(0.1,0,1,0)
+ slotFrame.Parent = CurrentLoadout
+end
+
+local TempSlot = Instance.new("ImageButton")
+TempSlot.Name = "TempSlot"
+TempSlot.Active = true
+TempSlot.Size = UDim2.new(1,0,1,0)
+TempSlot.Style = Enum.ButtonStyle.RobloxButton
+TempSlot.Visible = false
+
+TempSlot.Parent = CurrentLoadout
+
+ -- TempSlot Children
+ local GearReference = Instance.new("ObjectValue")
+ GearReference.Name = "GearReference"
+
+ GearReference.Parent = TempSlot
+
+ local ToolTipLabel = Instance.new("TextLabel")
+ ToolTipLabel.Name = "ToolTipLabel"
+
+ ToolTipLabel.Text = ""
+ ToolTipLabel.BackgroundTransparency = 0.5
+ ToolTipLabel.BorderSizePixel = 0
+ ToolTipLabel.Visible = false
+ ToolTipLabel.TextColor3 = Color3.new(1,1,1)
+ ToolTipLabel.BackgroundColor3 = Color3.new(0,0,0)
+ ToolTipLabel.TextStrokeTransparency = 0
+ ToolTipLabel.Font = Enum.Font.ArialBold
+ ToolTipLabel.FontSize = Enum.FontSize.Size14
+ --ToolTipLabel.TextWrap = true
+ ToolTipLabel.Size = UDim2.new(1,60,0,20)
+ ToolTipLabel.Position = UDim2.new(0,-30,0,-30)
+ ToolTipLabel.Parent = TempSlot
+
+ local Kill = Instance.new("BoolValue")
+ Kill.Name = "Kill"
+
+ Kill.Parent = TempSlot
+
+ local GearImage = Instance.new("ImageLabel")
+ GearImage.Name = "GearImage"
+ GearImage.BackgroundTransparency = 1
+ GearImage.Position = UDim2.new(0,-7,0,-7)
+ GearImage.Size = UDim2.new(1,14,1,14)
+ GearImage.ZIndex = 2
+
+ GearImage.Parent = TempSlot
+
+ local SlotNumber = Instance.new("TextLabel")
+ SlotNumber.Name = "SlotNumber"
+ SlotNumber.BackgroundTransparency = 1
+ SlotNumber.BorderSizePixel = 0
+ SlotNumber.Font = Enum.Font.ArialBold
+ SlotNumber.FontSize = Enum.FontSize.Size18
+ SlotNumber.Position = UDim2.new(0,-7,0,-7)
+ SlotNumber.Size = UDim2.new(0,10,0,15)
+ SlotNumber.TextColor3 = Color3.new(1,1,1)
+ SlotNumber.TextTransparency = 0
+ SlotNumber.TextXAlignment = Enum.TextXAlignment.Left
+ SlotNumber.TextYAlignment = Enum.TextYAlignment.Bottom
+ SlotNumber.ZIndex = 4
+
+ SlotNumber.Parent = TempSlot
+
+ local SlotNumberDownShadow = SlotNumber:clone()
+ SlotNumberDownShadow.Name = "SlotNumberDownShadow"
+ SlotNumberDownShadow.TextColor3 = Color3.new(0,0,0)
+ SlotNumberDownShadow.ZIndex = 3
+ SlotNumberDownShadow.Position = UDim2.new(0,-6,0,-6)
+ SlotNumberDownShadow.Parent = TempSlot
+
+ local SlotNumberUpShadow = SlotNumberDownShadow:clone()
+ SlotNumberUpShadow.Name = "SlotNumberUpShadow"
+ SlotNumberUpShadow.Position = UDim2.new(0,-8,0,-8)
+ SlotNumberUpShadow.Parent = TempSlot
+
+ local GearText = Instance.new("TextLabel")
+
+ GearText.Name = "GearText"
+ GearText.BackgroundTransparency = 1
+ GearText.Font = Enum.Font.Arial
+ GearText.FontSize = Enum.FontSize.Size14
+ GearText.Position = UDim2.new(0,-8,0,-8)
+ GearText.ZIndex = 2
+ GearText.Size = UDim2.new(1,16,1,16)
+ GearText.Text = ""
+ GearText.TextColor3 = Color3.new(1,1,1)
+ GearText.TextWrap = true
+ GearText.Parent = TempSlot
+
+--- Great, now lets make the inventory!
+
+local Backpack = Instance.new("Frame")
+
+Backpack.Visible = false
+Backpack.Name = "Backpack"
+Backpack.Position = UDim2.new(0.5,0,0.5,0)
+Backpack.BackgroundColor3 = Color3.new(0,0,0)
+Backpack.BackgroundTransparency = 0.08
+Backpack.BorderSizePixel = 0
+Backpack.Parent = gui
+Backpack.Active = true
+
+ -- Backpack Children
+ local SwapSlot = Instance.new("BoolValue")
+
+ SwapSlot.Name = "SwapSlot"
+ SwapSlot.Parent = Backpack
+
+ -- SwapSlot Children
+ local Slot = Instance.new("IntValue")
+
+ Slot.Name = "Slot"
+ Slot.Parent = SwapSlot
+
+ local GearButton = Instance.new("ObjectValue")
+
+ GearButton.Name = "GearButton"
+ GearButton.Parent = SwapSlot
+
+ local Tabs = Instance.new("Frame")
+ Tabs.Name = "Tabs"
+ Tabs.Visible = true
+
+ Tabs.BackgroundColor3 = Color3.new(0,0,0)
+ Tabs.BackgroundTransparency = 0.08
+ Tabs.BorderSizePixel = 0
+ Tabs.Position = UDim2.new(0,0,-0.1,-4)
+ Tabs.Size = UDim2.new(1,0,0.1,4)
+ Tabs.Parent = Backpack
+
+ -- Tabs Children
+
+ local tabLine = Instance.new("Frame")
+
+ tabLine.Name = "TabLine"
+ tabLine.BackgroundColor3 = Color3.new(53/255, 53/255, 53/255)
+ tabLine.BorderSizePixel = 0
+ tabLine.Position = UDim2.new(0,5,1,-4)
+ tabLine.Size = UDim2.new(1,-10,0,4)
+ tabLine.ZIndex = 2
+ tabLine.Parent = Tabs
+
+ local InventoryButton = Instance.new("TextButton")
+
+ InventoryButton.Name = "InventoryButton"
+ InventoryButton.Size = UDim2.new(0,60,0,30)
+ InventoryButton.Position = UDim2.new(0,7,1,-31)
+ InventoryButton.BackgroundColor3 = Color3.new(1,1,1)
+ InventoryButton.BorderColor3 = Color3.new(1,1,1)
+ InventoryButton.Font = Enum.Font.ArialBold
+ InventoryButton.FontSize = Enum.FontSize.Size18
+ InventoryButton.Text = "Gear"
+ InventoryButton.AutoButtonColor = false
+ InventoryButton.TextColor3 = Color3.new(0,0,0)
+ InventoryButton.Selected = true
+ InventoryButton.Active = true
+ InventoryButton.ZIndex = 3
+ InventoryButton.Parent = Tabs
+
+
+ local WardrobeButton = Instance.new("TextButton")
+
+ WardrobeButton.Name = "WardrobeButton"
+ WardrobeButton.Size = UDim2.new(0,90,0,30)
+ WardrobeButton.Position = UDim2.new(0,77,1,-31)
+ WardrobeButton.BackgroundColor3 = Color3.new(0,0,0)
+ WardrobeButton.BorderColor3 = Color3.new(1,1,1)
+ WardrobeButton.Font = Enum.Font.ArialBold
+ WardrobeButton.FontSize = Enum.FontSize.Size18
+ WardrobeButton.Text = "Wardrobe"
+ WardrobeButton.AutoButtonColor = false
+ WardrobeButton.TextColor3 = Color3.new(1,1,1)
+ WardrobeButton.Selected = false
+ WardrobeButton.Active = true
+ WardrobeButton.Parent = Tabs
+
+
+ local closeButton = Instance.new("TextButton")
+
+ closeButton.Name = "CloseButton"
+ closeButton.Font = Enum.Font.ArialBold
+ closeButton.FontSize = Enum.FontSize.Size24
+ closeButton.Position = UDim2.new(1,-33,0,4)
+ closeButton.Size = UDim2.new(0,30,0,30)
+ closeButton.Style = Enum.ButtonStyle.RobloxButton
+ closeButton.Text = ""
+ closeButton.TextColor3 = Color3.new(1,1,1)
+ closeButton.Parent = Tabs
+ closeButton.Modal = true
+
+ --closeButton child
+ local XImage = Instance.new("ImageLabel")
+
+ XImage.Name = "XImage"
+ game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=75547445")
+ XImage.Image = "http://www.roblox.com/asset/?id=75547445" --TODO: move to rbxasset
+ XImage.BackgroundTransparency = 1
+ XImage.Position = UDim2.new(-.25,-1,-.25,-1)
+ XImage.Size = UDim2.new(1.5,2,1.5,2)
+ XImage.ZIndex = 2
+ XImage.Parent = closeButton
+
+ -- Generic Search gui used across backpack
+ local SearchFrame = Instance.new("Frame")
+
+ SearchFrame.Name = "SearchFrame"
+ SearchFrame.BackgroundTransparency = 1
+ SearchFrame.Position = UDim2.new(1,-220,0,2)
+ SearchFrame.Size = UDim2.new(0,220,0,24)
+ SearchFrame.Parent = Backpack
+
+ -- SearchFrame Children
+ local SearchButton = Instance.new("ImageButton")
+
+ SearchButton.Name = "SearchButton"
+ SearchButton.Size = UDim2.new(0,25,0,25)
+ SearchButton.BackgroundTransparency = 1
+ SearchButton.Image = "rbxasset://textures/ui/SearchIcon.png"
+ SearchButton.Parent = SearchFrame
+
+ local SearchBoxFrame = Instance.new("TextButton")
+
+ SearchBoxFrame.Position = UDim2.new(0,25,0,0)
+ SearchBoxFrame.Size = UDim2.new(1,-28,0,26)
+ SearchBoxFrame.Name = "SearchBoxFrame"
+ SearchBoxFrame.Text = ""
+ SearchBoxFrame.Style = Enum.ButtonStyle.RobloxButton
+ SearchBoxFrame.Parent = SearchFrame
+
+ -- SearchBoxFrame Children
+ local SearchBox = Instance.new("TextBox")
+
+ SearchBox.Name = "SearchBox"
+ SearchBox.BackgroundTransparency = 1
+ SearchBox.Font = Enum.Font.ArialBold
+ SearchBox.FontSize = Enum.FontSize.Size12
+ SearchBox.Position = UDim2.new(0,-5,0,-5)
+ SearchBox.Size = UDim2.new(1,10,1,10)
+ SearchBox.TextColor3 = Color3.new(1,1,1)
+ SearchBox.TextXAlignment = Enum.TextXAlignment.Left
+ SearchBox.ZIndex = 2
+ SearchBox.TextWrap = true
+ SearchBox.Text = "Search..."
+ SearchBox.Parent = SearchBoxFrame
+
+
+ local ResetButton = Instance.new("TextButton")
+
+ ResetButton.Visible = false
+ ResetButton.Name = "ResetButton"
+ ResetButton.Position = UDim2.new(1,-26,0,3)
+ ResetButton.Size = UDim2.new(0,20,0,20)
+ ResetButton.Style = Enum.ButtonStyle.RobloxButtonDefault
+ ResetButton.Text = "X"
+ ResetButton.TextColor3 = Color3.new(1,1,1)
+ ResetButton.Font = Enum.Font.ArialBold
+ ResetButton.FontSize = Enum.FontSize.Size18
+ ResetButton.ZIndex = 3
+ ResetButton.Parent = SearchFrame
+
+------------------------------- GEAR -------------------------------------------------------
+ local Gear = Instance.new("Frame")
+ Gear.Name = "Gear"
+
+ Gear.BackgroundTransparency = 1
+ Gear.Size = UDim2.new(1,0,1,0)
+ Gear.Parent = Backpack
+
+ -- Gear Children
+ local AssetsList = Instance.new("Frame")
+
+ AssetsList.Name = "AssetsList"
+ AssetsList.BackgroundTransparency = 1
+ AssetsList.Size = UDim2.new(0.2,0,1,0)
+ AssetsList.Style = Enum.FrameStyle.RobloxSquare
+ AssetsList.Visible = false
+ AssetsList.Parent = Gear
+
+ local GearGrid = Instance.new("Frame")
+
+ GearGrid.Name = "GearGrid"
+ GearGrid.Size = UDim2.new(0.69,0,1,0)
+ GearGrid.BackgroundTransparency = 1
+ GearGrid.Parent = Gear
+
+
+ local GearButton = Instance.new("ImageButton")
+
+ GearButton.Visible = false
+ GearButton.Name = "GearButton"
+ GearButton.Size = UDim2.new(0,64,0,64)
+ GearButton.Style = Enum.ButtonStyle.RobloxButton
+ GearButton.Parent = GearGrid
+
+ -- GearButton Children
+ local GearReference = Instance.new("ObjectValue")
+
+ GearReference.Name = "GearReference"
+ GearReference.Parent = GearButton
+
+ local GreyOutButton = Instance.new("Frame")
+
+ GreyOutButton.Name = "GreyOutButton"
+ GreyOutButton.BackgroundTransparency = 0.5
+ GreyOutButton.Size = UDim2.new(1,0,1,0)
+ GreyOutButton.Active = true
+ GreyOutButton.Visible = false
+ GreyOutButton.ZIndex = 3
+ GreyOutButton.Parent = GearButton
+
+ local GearText = Instance.new("TextLabel")
+
+ GearText.Name = "GearText"
+ GearText.BackgroundTransparency = 1
+ GearText.Font = Enum.Font.Arial
+ GearText.FontSize = Enum.FontSize.Size14
+ GearText.Position = UDim2.new(0,-8,0,-8)
+ GearText.Size = UDim2.new(1,16,1,16)
+ GearText.Text = ""
+ GearText.ZIndex = 2
+ GearText.TextColor3 = Color3.new(1,1,1)
+ GearText.TextWrap = true
+ GearText.Parent = GearButton
+
+ local GearGridScrollingArea = Instance.new("Frame")
+
+ GearGridScrollingArea.Name = "GearGridScrollingArea"
+ GearGridScrollingArea.Position = UDim2.new(0.7,0,0,35)
+ GearGridScrollingArea.Size = UDim2.new(0,17,1,-45)
+ GearGridScrollingArea.BackgroundTransparency = 1
+ GearGridScrollingArea.Parent = Gear
+
+ local GearLoadouts = Instance.new("Frame")
+
+ GearLoadouts.Name = "GearLoadouts"
+ GearLoadouts.BackgroundTransparency = 1
+ GearLoadouts.Position = UDim2.new(0.7,23,0.5,1)
+ GearLoadouts.Size = UDim2.new(0.3,-23,0.5,-1)
+ GearLoadouts.Parent = Gear
+ GearLoadouts.Visible = false
+
+ -- GearLoadouts Children
+ local GearLoadoutsHeader = Instance.new("Frame")
+
+ GearLoadoutsHeader.Name = "GearLoadoutsHeader"
+ GearLoadoutsHeader.BackgroundColor3 = Color3.new(0,0,0)
+ GearLoadoutsHeader.BackgroundTransparency = 0.2
+ GearLoadoutsHeader.BorderColor3 = Color3.new(1,0,0)
+ GearLoadoutsHeader.Size = UDim2.new(1,2,0.15,-1)
+ GearLoadoutsHeader.Parent = GearLoadouts
+
+ -- GearLoadoutsHeader Children
+ local LoadoutsHeaderText = Instance.new("TextLabel")
+
+ LoadoutsHeaderText.Name = "LoadoutsHeaderText"
+ LoadoutsHeaderText.BackgroundTransparency = 1
+ LoadoutsHeaderText.Font = Enum.Font.ArialBold
+ LoadoutsHeaderText.FontSize = Enum.FontSize.Size18
+ LoadoutsHeaderText.Size = UDim2.new(1,0,1,0)
+ LoadoutsHeaderText.Text = "Loadouts"
+ LoadoutsHeaderText.TextColor3 = Color3.new(1,1,1)
+ LoadoutsHeaderText.Parent = GearLoadoutsHeader
+
+ local GearLoadoutsScrollingArea = GearGridScrollingArea:clone()
+
+ GearLoadoutsScrollingArea.Name = "GearLoadoutsScrollingArea"
+ GearLoadoutsScrollingArea.Position = UDim2.new(1,-15,0.15,2)
+ GearLoadoutsScrollingArea.Size = UDim2.new(0,17,0.85,-2)
+ GearLoadoutsScrollingArea.Parent = GearLoadouts
+
+ local LoadoutsList = Instance.new("Frame")
+
+ LoadoutsList.Name = "LoadoutsList"
+ LoadoutsList.Position = UDim2.new(0,0,0.15,2)
+ LoadoutsList.Size = UDim2.new(1,-17,0.85,-2)
+ LoadoutsList.Style = Enum.FrameStyle.RobloxSquare
+ LoadoutsList.Parent = GearLoadouts
+
+ local GearPreview = Instance.new("Frame")
+
+ GearPreview.Name = "GearPreview"
+ GearPreview.Position = UDim2.new(0.7,23,0,0)
+ GearPreview.Size = UDim2.new(0.3,-28,0.5,-1)
+ GearPreview.BackgroundTransparency = 1
+ GearPreview.ZIndex = 7
+ GearPreview.Parent = Gear
+
+ -- GearPreview Children
+ local GearStats = Instance.new("Frame")
+
+ GearStats.Name = "GearStats"
+ GearStats.BackgroundTransparency = 1
+ GearStats.Position = UDim2.new(0,0,0.75,0)
+ GearStats.Size = UDim2.new(1,0,0.25,0)
+ GearStats.ZIndex = 8
+ GearStats.Parent = GearPreview
+
+ -- GearStats Children
+ local GearName = Instance.new("TextLabel")
+
+ GearName.Name = "GearName"
+ GearName.BackgroundTransparency = 1
+ GearName.Font = Enum.Font.ArialBold
+ GearName.FontSize = Enum.FontSize.Size18
+ GearName.Position = UDim2.new(0,-3,0,0)
+ GearName.Size = UDim2.new(1,6,1,5)
+ GearName.Text = ""
+ GearName.TextColor3 = Color3.new(1,1,1)
+ GearName.TextWrap = true
+ GearName.ZIndex = 9
+ GearName.Parent = GearStats
+
+ local GearImage = Instance.new("ImageLabel")
+ GearImage.Name = "GearImage"
+ GearImage.Image = ""
+ GearImage.BackgroundTransparency = 1
+ GearImage.Position = UDim2.new(0.125,0,0,0)
+ GearImage.Size = UDim2.new(0.75,0,0.75,0)
+ GearImage.ZIndex = 8
+ GearImage.Parent = GearPreview
+
+ --GearImage Children
+ local GearIcons = Instance.new("Frame")
+ GearIcons.BackgroundColor3 = Color3.new(0,0,0)
+ GearIcons.BackgroundTransparency = 0.5
+ GearIcons.BorderSizePixel = 0
+
+ GearIcons.Name = "GearIcons"
+ GearIcons.Position = UDim2.new(0.4,2,0.85,-2)
+ GearIcons.Size = UDim2.new(0.6,0,0.15,0)
+ GearIcons.Visible = false
+ GearIcons.ZIndex = 9
+ GearIcons.Parent = GearImage
+
+ -- GearIcons Children
+ local GenreImage = Instance.new("ImageLabel")
+
+ GenreImage.Name = "GenreImage"
+ GenreImage.BackgroundColor3 = Color3.new(102/255,153/255,1)
+ GenreImage.BackgroundTransparency = 0.5
+ GenreImage.BorderSizePixel = 0
+ GenreImage.Size = UDim2.new(0.25,0,1,0)
+ GenreImage.Parent = GearIcons
+
+ local AttributeOneImage = GenreImage:clone()
+
+ AttributeOneImage.Name = "AttributeOneImage"
+ AttributeOneImage.BackgroundColor3 = Color3.new(1,51/255,0)
+ AttributeOneImage.Position = UDim2.new(0.25,0,0,0)
+ AttributeOneImage.Parent = GearIcons
+
+ local AttributeTwoImage = GenreImage:clone()
+
+ AttributeTwoImage.Name = "AttributeTwoImage"
+ AttributeTwoImage.BackgroundColor3 = Color3.new(153/255,1,153/255)
+ AttributeTwoImage.Position = UDim2.new(0.5,0,0,0)
+ AttributeTwoImage.Parent = GearIcons
+
+ local AttributeThreeImage = GenreImage:clone()
+
+ AttributeThreeImage.Name = "AttributeThreeImage"
+ AttributeThreeImage.BackgroundColor3 = Color3.new(0,0.5,0.5)
+ AttributeThreeImage.Position = UDim2.new(0.75,0,0,0)
+ AttributeThreeImage.Parent = GearIcons
+
+------------------------------- WARDROBE -------------------------------------------------------
+
+
+ local function makeCharFrame(frameName, parent)
+ local frame = Instance.new("Frame")
+
+ frame.Size = UDim2.new(1,0,1,-70)
+ frame.Position = UDim2.new(0,0,0,20)
+ frame.Name = frameName
+ frame.BackgroundTransparency = 1
+ frame.Parent = parent
+ frame.Visible = false
+ return frame
+ end
+ local function makeZone( zoneName, image, size, position, parent )
+ local zone = Instance.new("ImageLabel")
+
+ zone.Name = zoneName
+ zone.Image = image
+ zone.Size = size
+ zone.BackgroundTransparency = 1
+ zone.Position = position
+ zone.Parent = parent
+ return zone
+ end
+ local function makeStyledButton( buttonName, size, position, parent, buttonStyle )
+ local button = Instance.new("ImageButton")
+
+ button.Name = buttonName
+ button.Size = size
+ button.Position = position
+ if buttonStyle then
+ button.Style = buttonStyle
+ else
+ button.BackgroundColor3 = Color3.new(0,0,0)
+ button.BorderColor3 = Color3.new(1,1,1)
+ end
+ button.Parent = parent
+ return button
+ end
+ local function makeTextLabel( TextLabelName,text,position,parent )
+ local label = Instance.new("TextLabel")
+
+ label.BackgroundTransparency = 1
+ label.Size = UDim2.new(0,32,0,14)
+ label.Name = TextLabelName
+ label.Font = Enum.Font.Arial
+ label.TextColor3 = Color3.new(1,1,1)
+ label.FontSize = Enum.FontSize.Size14
+ label.Text = text
+ label.Position = position
+ label.Parent = parent
+ end
+
+
+ local Wardrobe = Instance.new("Frame")
+ Wardrobe.Name = "Wardrobe"
+
+ Wardrobe.BackgroundTransparency = 1
+ Wardrobe.Visible = false
+ Wardrobe.Size = UDim2.new(1,0,1,0)
+ Wardrobe.Parent = Backpack
+
+ local AssetList = Instance.new("Frame")
+
+ AssetList.Name = "AssetList"
+ AssetList.Position = UDim2.new(0,4,0,5)
+ AssetList.Size = UDim2.new(0,85,1,-5)
+ AssetList.BackgroundTransparency = 1
+ AssetList.Visible = true
+ AssetList.Parent = Wardrobe
+
+ local PreviewAssetFrame = Instance.new("Frame")
+
+ PreviewAssetFrame.Name = "PreviewAssetFrame"
+ PreviewAssetFrame.BackgroundTransparency = 1
+ PreviewAssetFrame.Position = UDim2.new(1,-240,0,30)
+ PreviewAssetFrame.Size = UDim2.new(0,250,0,250)
+ PreviewAssetFrame.Parent = Wardrobe
+
+ local PreviewAssetBacking = Instance.new("TextButton")
+
+ PreviewAssetBacking.Name = "PreviewAssetBacking"
+ PreviewAssetBacking.Active = false
+ PreviewAssetBacking.Text = ""
+ PreviewAssetBacking.AutoButtonColor = false
+ PreviewAssetBacking.Size = UDim2.new(1,0,1,0)
+ PreviewAssetBacking.Style = Enum.ButtonStyle.RobloxButton
+ PreviewAssetBacking.Visible = false
+ PreviewAssetBacking.ZIndex = 9
+ PreviewAssetBacking.Parent = PreviewAssetFrame
+
+ local PreviewAssetImage = Instance.new("ImageLabel")
+
+ PreviewAssetImage.Name = "PreviewAssetImage"
+ PreviewAssetImage.BackgroundTransparency = 0.8
+ PreviewAssetImage.Position = UDim2.new(0.5,-100,0,0)
+ PreviewAssetImage.Size = UDim2.new(0,200,0,200)
+ PreviewAssetImage.BorderSizePixel = 0
+ PreviewAssetImage.ZIndex = 10
+ PreviewAssetImage.Parent = PreviewAssetBacking
+
+ local AssetNameLabel = Instance.new("TextLabel")
+ AssetNameLabel.Name = "AssetNameLabel"
+
+ AssetNameLabel.BackgroundTransparency = 1
+ AssetNameLabel.Position = UDim2.new(0,0,1,-20)
+ AssetNameLabel.Size = UDim2.new(0.5,0,0,24)
+ AssetNameLabel.ZIndex = 10
+ AssetNameLabel.Font = Enum.Font.Arial
+ AssetNameLabel.Text = ""
+ AssetNameLabel.TextColor3 = Color3.new(1,1,1)
+
+ AssetNameLabel.Parent = PreviewAssetBacking
+
+ local AssetTypeLabel = AssetNameLabel:clone()
+
+ AssetTypeLabel.Name = "AssetTypeLabel"
+
+ AssetTypeLabel.FontSize = Enum.FontSize.Size18
+ AssetTypeLabel.Position = UDim2.new(0.5,3,1,-20)
+ AssetTypeLabel.Parent = PreviewAssetBacking
+
+
+
+ local PreviewButton = Instance.new("TextButton")
+
+ PreviewButton.Name = "PreviewButton"
+ PreviewButton.Text = "Rotate"
+ PreviewButton.BackgroundColor3 = Color3.new(0,0,0)
+ PreviewButton.BackgroundTransparency = 0.5
+ PreviewButton.BorderColor3 = Color3.new(1,1,1)
+ PreviewButton.Position = UDim2.new(1.2,-62,1,-50)
+ PreviewButton.Size = UDim2.new(0,125,0,50)
+ PreviewButton.Font = Enum.Font.ArialBold
+ PreviewButton.FontSize = Enum.FontSize.Size24
+ PreviewButton.TextColor3 = Color3.new(1,1,1)
+ PreviewButton.TextWrap = true
+ PreviewButton.TextStrokeTransparency = 0
+ PreviewButton.Parent = Wardrobe
+
+ local CharacterPane = Instance.new("Frame")
+
+ CharacterPane.Name = "CharacterPane"
+ CharacterPane.Position = UDim2.new(1,-220,0,32)
+ CharacterPane.Size = UDim2.new(0,220,1,-40)
+ CharacterPane.BackgroundTransparency = 1
+ CharacterPane.Visible = true
+ CharacterPane.Parent = Wardrobe
+
+ --CharacterPane Children
+ local FaceFrame = makeCharFrame("FacesFrame", CharacterPane)
+ game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=75460621")
+ makeZone("FaceZone","http://www.roblox.com/asset/?id=75460621",UDim2.new(0,157,0,137),UDim2.new(0.5,-78,0.5,-68),FaceFrame)
+ makeStyledButton("Face",UDim2.new(0,64,0,64),UDim2.new(0.5,-32,0.5,-135),FaceFrame)
+
+ local HeadFrame = makeCharFrame("HeadsFrame", CharacterPane)
+ makeZone("FaceZone","http://www.roblox.com/asset/?id=75460621",UDim2.new(0,157,0,137),UDim2.new(0.5,-78,0.5,-68),HeadFrame)
+ makeStyledButton("Head",UDim2.new(0,64,0,64),UDim2.new(0.5,-32,0.5,-135),HeadFrame)
+
+ local HatsFrame = makeCharFrame("HatsFrame", CharacterPane)
+ game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=75457888")
+ local HatsZone = makeZone("HatsZone","http://www.roblox.com/asset/?id=75457888",UDim2.new(0,186,0,184),UDim2.new(0.5,-93,0.5,-100), HatsFrame)
+ makeStyledButton("Hat1Button",UDim2.new(0,64,0,64),UDim2.new(0,-1,0,-1),HatsZone,Enum.ButtonStyle.RobloxButton)
+ makeStyledButton("Hat2Button",UDim2.new(0,64,0,64),UDim2.new(0,63,0,-1),HatsZone,Enum.ButtonStyle.RobloxButton)
+ makeStyledButton("Hat3Button",UDim2.new(0,64,0,64),UDim2.new(0,127,0,-1),HatsZone,Enum.ButtonStyle.RobloxButton)
+
+ local PantsFrame = makeCharFrame("PantsFrame", CharacterPane)
+ game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=75457920")
+ makeZone("PantsZone","http://www.roblox.com/asset/?id=75457920",UDim2.new(0,121,0,99),UDim2.new(0.5,-60,0.5,-100),PantsFrame)
+
+ local pantFrame = Instance.new("Frame")
+
+ pantFrame.Size = UDim2.new(0,25,0,56)
+ pantFrame.Position = UDim2.new(0.5,-26,0.5,0)
+ pantFrame.BackgroundColor3 = Color3.new(0,0,0)
+ pantFrame.BorderColor3 = Color3.new(1,1,1)
+ pantFrame.Name = "PantFrame"
+ pantFrame.Parent = PantsFrame
+
+ local otherPantFrame = pantFrame:clone()
+ otherPantFrame.Position = UDim2.new(0.5,3,0.5,0)
+
+ otherPantFrame.Parent = PantsFrame
+
+ local CurrentPants = Instance.new("ImageButton")
+
+ CurrentPants.BackgroundTransparency = 1
+ CurrentPants.ZIndex = 2
+ CurrentPants.Name = "CurrentPants"
+ CurrentPants.Position = UDim2.new(0.5,-31,0.5,-4)
+ CurrentPants.Size = UDim2.new(0,54,0,59)
+ CurrentPants.Parent = PantsFrame
+
+ local MeshFrame = makeCharFrame("PackagesFrame", CharacterPane)
+ local torsoButton = makeStyledButton("TorsoMeshButton", UDim2.new(0,64,0,64),UDim2.new(0.5,-32,0.5,-110),MeshFrame,Enum.ButtonStyle.RobloxButton)
+ makeTextLabel("TorsoLabel","Torso",UDim2.new(0.5,-16,0,-25),torsoButton)
+ local leftLegButton = makeStyledButton("LeftLegMeshButton", UDim2.new(0,64,0,64),UDim2.new(0.5,0,0.5,-25),MeshFrame,Enum.ButtonStyle.RobloxButton)
+ makeTextLabel("LeftLegLabel","Left Leg",UDim2.new(0.5,-16,0,-25),leftLegButton)
+ local rightLegButton = makeStyledButton("RightLegMeshButton", UDim2.new(0,64,0,64),UDim2.new(0.5,-64,0.5,-25),MeshFrame,Enum.ButtonStyle.RobloxButton)
+ makeTextLabel("RightLegLabel","Right Leg",UDim2.new(0.5,-16,0,-25),rightLegButton)
+ local rightArmButton = makeStyledButton("RightArmMeshButton", UDim2.new(0,64,0,64),UDim2.new(0.5,-96,0.5,-110),MeshFrame,Enum.ButtonStyle.RobloxButton)
+ makeTextLabel("RightArmLabel","Right Arm",UDim2.new(0.5,-16,0,-25),rightArmButton)
+ local leftArmButton = makeStyledButton("LeftArmMeshButton", UDim2.new(0,64,0,64),UDim2.new(0.5,32,0.5,-110),MeshFrame,Enum.ButtonStyle.RobloxButton)
+ makeTextLabel("LeftArmLabel","Left Arm",UDim2.new(0.5,-16,0,-25),leftArmButton)
+
+ local TShirtFrame = makeCharFrame("T-ShirtsFrame",CharacterPane)
+ game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=75460642")
+ makeZone("TShirtZone","http://www.roblox.com/asset/?id=75460642",UDim2.new(0,121,0,154),UDim2.new(0.5,-60,0.5,-100),TShirtFrame)
+ makeStyledButton("TShirtButton", UDim2.new(0,64,0,64),UDim2.new(0.5,-32,0.5,-64),TShirtFrame)
+
+
+ local ShirtFrame = makeCharFrame("ShirtsFrame", CharacterPane)
+ makeZone("ShirtZone","http://www.roblox.com/asset/?id=75460642",UDim2.new(0,121,0,154),UDim2.new(0.5,-60,0.5,-100),ShirtFrame)
+ makeStyledButton("ShirtButton", UDim2.new(0,64,0,64),UDim2.new(0.5,-32,0.5,-64),ShirtFrame)
+
+
+ local ColorFrame = makeCharFrame("ColorFrame", CharacterPane)
+ game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=76049888")
+ local ColorZone = makeZone("ColorZone","http://www.roblox.com/asset/?id=76049888", UDim2.new(0,120,0,150),UDim2.new(0.5,-60,0.5,-100),ColorFrame)
+ makeStyledButton("Head",UDim2.new(0.26,0,0.19,0),UDim2.new(0.37,0,0.02,0),ColorZone).AutoButtonColor = false
+ makeStyledButton("LeftArm",UDim2.new(0.19,0,0.36,0),UDim2.new(0.78,0,0.26,0),ColorZone).AutoButtonColor = false
+ makeStyledButton("RightArm",UDim2.new(0.19,0,0.36,0),UDim2.new(0.025,0,0.26,0),ColorZone).AutoButtonColor = false
+ makeStyledButton("Torso",UDim2.new(0.43,0,0.36,0),UDim2.new(0.28,0,0.26,0),ColorZone).AutoButtonColor = false
+ makeStyledButton("RightLeg",UDim2.new(0.19,0,0.31,0),UDim2.new(0.275,0,0.67,0),ColorZone).AutoButtonColor = false
+ makeStyledButton("LeftLeg",UDim2.new(0.19,0,0.31,0),UDim2.new(0.525,0,0.67,0),ColorZone).AutoButtonColor = false
+
+ -- Character Panel label (shows what category we are currently browsing)
+ local CategoryLabel = Instance.new("TextLabel")
+
+ CategoryLabel.Name = "CategoryLabel"
+ CategoryLabel.BackgroundTransparency = 1
+ CategoryLabel.Font = Enum.Font.ArialBold
+ CategoryLabel.FontSize = Enum.FontSize.Size18
+ CategoryLabel.Position = UDim2.new(0,0,0,-7)
+ CategoryLabel.Size = UDim2.new(1,0,0,20)
+ CategoryLabel.TextXAlignment = Enum.TextXAlignment.Center
+ CategoryLabel.Text = "All"
+ CategoryLabel.TextColor3 = Color3.new(1,1,1)
+ CategoryLabel.Parent = CharacterPane
+
+ --Save Button
+ local SaveButton = Instance.new("TextButton")
+
+ SaveButton.Name = "SaveButton"
+ SaveButton.Size = UDim2.new(0.6,0,0,50)
+ SaveButton.Position = UDim2.new(0.2,0,1,-50)
+ SaveButton.Style = Enum.ButtonStyle.RobloxButton
+ SaveButton.Selected = false
+ SaveButton.Font = Enum.Font.ArialBold
+ SaveButton.FontSize = Enum.FontSize.Size18
+ SaveButton.Text = "Save"
+ SaveButton.TextColor3 = Color3.new(1,1,1)
+ SaveButton.Parent = CharacterPane
+
+
+
+
+ -
+
+ false
+
+ BackpackScript
+ -- A couple of necessary functions
+local function waitForChild(instance, name)
+ while not instance:FindFirstChild(name) do
+ instance.ChildAdded:wait()
+ end
+end
+local function waitForProperty(instance, property)
+ while not instance[property] do
+ instance.Changed:wait()
+ end
+end
+
+
+
+
+
+--- Begin Locals
+waitForChild(game,"Players")
+waitForProperty(game.Players,"LocalPlayer")
+local player = game.Players.LocalPlayer
+
+local currentLoadout = script.Parent
+local maxNumLoadoutItems = 10
+
+local guiBackpack = currentLoadout.Backpack
+
+local characterChildAddedCon = nil
+local keyPressCon = nil
+local backpackChildCon = nil
+
+local debounce = script.Parent.CurrentLoadout.Debounce
+
+local waitingOnEnlarge = nil
+
+local enlargeFactor = 1.18
+local buttonSizeEnlarge = UDim2.new(1 * enlargeFactor,0,1 * enlargeFactor,0)
+local buttonSizeNormal = UDim2.new(1,0,1,0)
+local enlargeOverride = true
+
+local guiTweenSpeed = 0.5
+
+
+local gearSlots = {}
+for i = 1, maxNumLoadoutItems do
+ gearSlots[i] = "empty"
+end
+
+local inventory = {}
+--- End Locals
+
+
+
+
+
+
+-- Begin Functions
+local function kill(prop,con,gear)
+ if con then con:disconnect() end
+ if prop == true and gear then
+ reorganizeLoadout(gear,false)
+ end
+end
+
+function removeGear(gear)
+ local emptySlot = nil
+ for i = 1, #gearSlots do
+ if gearSlots[i] == gear and gear.Parent ~= nil then
+ emptySlot = i
+ break
+ end
+ end
+ if emptySlot then
+ if gearSlots[emptySlot].GearReference.Value then
+ if gearSlots[emptySlot].GearReference.Value.Parent == game.Players.LocalPlayer.Character then -- if we currently have this equipped, unequip it
+ gearSlots[emptySlot].GearReference.Value.Parent = game.Players.LocalPlayer.Backpack
+ end
+
+ if gearSlots[emptySlot].GearReference.Value:IsA("HopperBin") and gearSlots[emptySlot].GearReference.Value.Active then -- this is an active hopperbin
+ gearSlots[emptySlot].GearReference.Value:Disable()
+ gearSlots[emptySlot].GearReference.Value.Active = false
+ end
+ end
+
+ gearSlots[emptySlot] = "empty"
+
+ local centerizeX = gear.Size.X.Scale/2
+ local centerizeY = gear.Size.Y.Scale/2
+ gear:TweenSizeAndPosition(UDim2.new(0,0,0,0),
+ UDim2.new(gear.Position.X.Scale + centerizeX,gear.Position.X.Offset,gear.Position.Y.Scale + centerizeY,gear.Position.Y.Offset),
+ Enum.EasingDirection.Out, Enum.EasingStyle.Quad,guiTweenSpeed/4,true)
+ delay(guiTweenSpeed/2,
+ function()
+ gear:remove()
+ end)
+ end
+end
+
+function insertGear(gear, addToSlot)
+ local pos = nil
+ if not addToSlot then
+ for i = 1, #gearSlots do
+ if gearSlots[i] == "empty" then
+ pos = i
+ break
+ end
+ end
+
+ if pos == 1 and gearSlots[1] ~= "empty" then gear:remove() return end -- we are currently full, can't add in
+ else
+ pos = addToSlot
+ -- push all gear down one slot
+ local start = 1
+ for i = 1, #gearSlots do
+ if gearSlots[i] == "empty" then
+ start = i
+ break
+ end
+ end
+ for i = start, pos + 1, -1 do
+ gearSlots[i] = gearSlots[i - 1]
+ if i == 10 then
+ gearSlots[i].SlotNumber.Text = "0"
+ gearSlots[i].SlotNumberDownShadow.Text = "0"
+ gearSlots[i].SlotNumberUpShadow.Text = "0"
+ else
+ gearSlots[i].SlotNumber.Text = i
+ gearSlots[i].SlotNumberDownShadow.Text = i
+ gearSlots[i].SlotNumberUpShadow.Text = i
+ end
+ end
+ end
+
+ gearSlots[pos] = gear
+ if pos ~= maxNumLoadoutItems then
+ if(type(tostring(pos)) == "string") then
+ local posString = tostring(pos)
+ gear.SlotNumber.Text = posString
+ gear.SlotNumberDownShadow.Text = posString
+ gear.SlotNumberUpShadow.Text = posString
+ end
+ else -- tenth gear doesn't follow mathematical pattern :(
+ gear.SlotNumber.Text = "0"
+ gear.SlotNumberDownShadow.Text = "0"
+ gear.SlotNumberUpShadow.Text = "0"
+ end
+ gear.Visible = true
+
+ local con = nil
+ con = gear.Kill.Changed:connect(function(prop) kill(prop,con,gear) end)
+end
+
+
+function reorganizeLoadout(gear, inserting, equipped, addToSlot)
+ if inserting then -- add in gear
+ insertGear(gear, addToSlot)
+ else
+ removeGear(gear)
+ end
+ if gear ~= "empty" then gear.ZIndex = 1 end
+end
+
+function checkToolAncestry(child,parent)
+ if child:FindFirstChild("RobloxBuildTool") then return end -- don't show roblox build tools
+ if child:IsA("Tool") or child:IsA("HopperBin") then
+ for i = 1, #gearSlots do
+ if gearSlots[i] ~= "empty" and gearSlots[i].GearReference.Value == child then
+ if parent == nil then
+ gearSlots[i].Kill.Value = true
+ return false
+ elseif child.Parent == player.Character then
+ gearSlots[i].Selected = true
+ return true
+ elseif child.Parent == player.Backpack then
+ if child:IsA("Tool") then gearSlots[i].Selected = false end
+ return true
+ else
+ gearSlots[i].Kill.Value = true
+ return false
+ end
+ return true
+ end
+ end
+ end
+end
+
+function removeAllEquippedGear(physGear)
+ local stuff = player.Character:GetChildren()
+ for i = 1, #stuff do
+ if ( stuff[i]:IsA("Tool") or stuff[i]:IsA("HopperBin") ) and stuff[i] ~= physGear then
+ if stuff[i]:IsA("Tool") then stuff[i].Parent = player.Backpack end
+ if stuff[i]:IsA("HopperBin") then
+ stuff[i]:Disable()
+ end
+ end
+ end
+end
+
+function hopperBinSwitcher(numKey, physGear)
+ if not physGear then return end
+
+ physGear:ToggleSelect()
+
+ if gearSlots[numKey] == "empty" then return end
+
+ if not physGear.Active then
+ gearSlots[numKey].Selected = false
+ normalizeButton(gearSlots[numKey])
+ else
+ gearSlots[numKey].Selected = true
+ enlargeButton(gearSlots[numKey])
+ end
+end
+
+function toolSwitcher(numKey)
+
+ if not gearSlots[numKey] then return end
+ local physGear = gearSlots[numKey].GearReference.Value
+ if physGear == nil then return end
+
+ removeAllEquippedGear(physGear) -- we don't remove this gear, as then we get a double switcheroo
+
+ local key = numKey
+ if numKey == 0 then key = 10 end
+
+ for i = 1, #gearSlots do
+ if gearSlots[i] and gearSlots[i] ~= "empty" and i ~= key then
+ normalizeButton(gearSlots[i])
+ gearSlots[i].Selected = false
+ if gearSlots[i].GearReference.Value:IsA("HopperBin") and gearSlots[i].GearReference.Value.Active then
+ gearSlots[i].GearReference.Value:ToggleSelect()
+ end
+ end
+ end
+
+ if physGear:IsA("HopperBin") then
+ hopperBinSwitcher(numKey,physGear)
+ else
+ if physGear.Parent == player.Character then
+ physGear.Parent = player.Backpack
+ gearSlots[numKey].Selected = false
+
+ normalizeButton(gearSlots[numKey])
+ else
+ physGear.Parent = player.Character
+ gearSlots[numKey].Selected = true
+
+ enlargeButton(gearSlots[numKey])
+ end
+ end
+end
+
+
+function activateGear(num)
+ local numKey = nil
+ if num == "0" then
+ numKey = 10 -- why do lua indexes have to start at 1? :(
+ else
+ numKey = tonumber(num)
+ end
+
+ if(numKey == nil) then return end
+
+ if gearSlots[numKey] ~= "empty" then
+ toolSwitcher(numKey)
+ end
+end
+
+
+enlargeButton = function(button)
+ if button.Size.Y.Scale > 1 then return end
+ if not button.Parent then return end
+ if not button.Selected then return end
+
+ for i = 1, #gearSlots do
+ if gearSlots[i] == "empty" then break end
+ if gearSlots[i] ~= button then
+ normalizeButton(gearSlots[i])
+ end
+ end
+
+ if not enlargeOverride then
+ waitingOnEnlarge = button
+ return
+ end
+
+ if button:IsA("ImageButton") or button:IsA("TextButton") then
+ button.ZIndex = 2
+ local centerizeX = -(buttonSizeEnlarge.X.Scale - button.Size.X.Scale)/2
+ local centerizeY = -(buttonSizeEnlarge.Y.Scale - button.Size.Y.Scale)/2
+ button:TweenSizeAndPosition(buttonSizeEnlarge,
+ UDim2.new(button.Position.X.Scale + centerizeX,button.Position.X.Offset,button.Position.Y.Scale + centerizeY,button.Position.Y.Offset),
+ Enum.EasingDirection.Out, Enum.EasingStyle.Quad,guiTweenSpeed/5,enlargeOverride)
+ end
+end
+
+normalizeAllButtons = function()
+ for i = 1, #gearSlots do
+ if gearSlots[i] == "empty" then break end
+ if gearSlots[i] ~= button then
+ normalizeButton(gearSlots[i],0.1)
+ end
+ end
+end
+
+
+normalizeButton = function(button, speed)
+ if not button then return end
+ if button.Size.Y.Scale <= 1 then return end
+ if button.Selected then return end
+ if not button.Parent then return end
+
+ local moveSpeed = speed
+ if moveSpeed == nil or type(moveSpeed) ~= "number" then moveSpeed = guiTweenSpeed/5 end
+
+ if button:IsA("ImageButton") or button:IsA("TextButton") then
+ button.ZIndex = 1
+ local inverseEnlarge = 1/enlargeFactor
+ local centerizeX = -(buttonSizeNormal.X.Scale - button.Size.X.Scale)/2
+ local centerizeY = -(buttonSizeNormal.Y.Scale - button.Size.Y.Scale)/2
+ button:TweenSizeAndPosition(buttonSizeNormal,
+ UDim2.new(button.Position.X.Scale + centerizeX,button.Position.X.Offset,button.Position.Y.Scale + centerizeY,button.Position.Y.Offset),
+ Enum.EasingDirection.Out, Enum.EasingStyle.Quad,moveSpeed,enlargeOverride)
+ end
+end
+
+waitForDebounce = function()
+ if debounce.Value then
+ debounce.Changed:wait()
+ end
+end
+
+function pointInRectangle(point,rectTopLeft,rectSize)
+ if point.x > rectTopLeft.x and point.x < (rectTopLeft.x + rectSize.x) then
+ if point.y > rectTopLeft.y and point.y < (rectTopLeft.y + rectSize.y) then
+ return true
+ end
+ end
+ return false
+end
+
+function swapGear(gearClone,toFrame)
+ local toFrameChildren = toFrame:GetChildren()
+ if #toFrameChildren == 1 then
+ if toFrameChildren[1]:FindFirstChild("SlotNumber") then
+
+ local toSlot = tonumber(toFrameChildren[1].SlotNumber.Text)
+ local gearCloneSlot = tonumber(gearClone.SlotNumber.Text)
+ if toSlot == 0 then toSlot = 10 end
+ if gearCloneSlot == 0 then gearCloneSlot = 10 end
+
+ gearSlots[toSlot] = gearClone
+ gearSlots[gearCloneSlot] = toFrameChildren[1]
+
+ toFrameChildren[1].SlotNumber.Text = gearClone.SlotNumber.Text
+ toFrameChildren[1].SlotNumberDownShadow.Text = gearClone.SlotNumber.Text
+ toFrameChildren[1].SlotNumberUpShadow.Text = gearClone.SlotNumber.Text
+
+ local subString = string.sub(toFrame.Name,5)
+ gearClone.SlotNumber.Text = subString
+ gearClone.SlotNumberDownShadow.Text = subString
+ gearClone.SlotNumberUpShadow.Text = subString
+
+ gearClone.Position = UDim2.new(gearClone.Position.X.Scale,0,gearClone.Position.Y.Scale,0)
+ toFrameChildren[1].Position = UDim2.new(toFrameChildren[1].Position.X.Scale,0,toFrameChildren[1].Position.Y.Scale,0)
+
+ toFrameChildren[1].Parent = gearClone.Parent
+ gearClone.Parent = toFrame
+ end
+ else
+ local slotNum = tonumber(gearClone.SlotNumber.Text)
+ if slotNum == 0 then slotNum = 10 end
+ gearSlots[slotNum] = "empty" -- reset this gear slot
+
+ local subString = string.sub(toFrame.Name,5)
+ gearClone.SlotNumber.Text = subString
+ gearClone.SlotNumberDownShadow.Text = subString
+ gearClone.SlotNumberUpShadow.Text = subString
+
+ local toSlotNum = tonumber(gearClone.SlotNumber.Text)
+ if toSlotNum == 0 then toSlotNum = 10 end
+ gearSlots[toSlotNum] = gearClone
+ gearClone.Position = UDim2.new(gearClone.Position.X.Scale,0,gearClone.Position.Y.Scale,0)
+ gearClone.Parent = toFrame
+ end
+end
+
+function resolveDrag(gearClone,x,y)
+ local mousePoint = Vector2.new(x,y)
+
+ local frame = gearClone.Parent
+ local frames = frame.Parent:GetChildren()
+
+ for i = 1, #frames do
+ if frames[i]:IsA("Frame") then
+ if pointInRectangle(mousePoint, frames[i].AbsolutePosition,frames[i].AbsoluteSize) then
+ swapGear(gearClone,frames[i])
+ return true
+ end
+ end
+ end
+
+ if x < frame.AbsolutePosition.x or x > ( frame.AbsolutePosition.x + frame.AbsoluteSize.x ) then
+ reorganizeLoadout(gearClone,false)
+ return false
+ elseif y < frame.AbsolutePosition.y or y > ( frame.AbsolutePosition.y + frame.AbsoluteSize.y ) then
+ reorganizeLoadout(gearClone,false)
+ return false
+ else
+ gearClone.Position = dragBeginPos
+ return -1
+ end
+end
+
+function unequipAllItems(dontEquipThis)
+ for i = 1, #gearSlots do
+ if gearSlots[i] == "empty" then break end
+ if gearSlots[i].GearReference.Value ~= dontEquipThis then
+ if gearSlots[i].GearReference.Value:IsA("HopperBin") then
+ gearSlots[i].GearReference.Value:Disable()
+ elseif gearSlots[i].GearReference.Value:IsA("Tool") then
+ gearSlots[i].GearReference.Value.Parent = game.Players.LocalPlayer.Backpack
+ end
+ gearSlots[i].Selected = false
+ end
+ end
+end
+
+local addingPlayerChild = function(child, equipped, addToSlot, inventoryGearButton)
+ waitForDebounce()
+ debounce.Value = true
+
+ if child:FindFirstChild("RobloxBuildTool") then debounce.Value = false return end -- don't show roblox build tools
+ if not child:IsA("Tool") then
+ if not child:IsA("HopperBin") then
+ debounce.Value = false
+ return -- we don't care about anything besides tools (sigh...)
+ end
+ end
+
+ if not addToSlot then
+ for i = 1, #gearSlots do
+ if gearSlots[i] ~= "empty" and gearSlots[i].GearReference.Value == child then -- we already have gear, do nothing
+ debounce.Value = false
+ return
+ end
+ end
+ end
+
+
+ local gearClone = currentLoadout.CurrentLoadout.TempSlot:clone()
+ gearClone.Name = child.Name
+ gearClone.GearImage.Image = child.TextureId
+ if gearClone.GearImage.Image == "" then
+ gearClone.GearText.Text = child.Name
+ end
+ gearClone.GearReference.Value = child
+
+
+
+ local slotToMod = -1
+
+ if not addToSlot then
+ for i = 1, #gearSlots do
+ if gearSlots[i] == "empty" then
+ slotToMod = i
+ break
+ end
+ end
+ else
+ slotToMod = addToSlot
+ end
+
+ if slotToMod == - 1 then debounce.Value = false print("no slots!") return end -- No available slot to add in!
+
+ local slotNum = slotToMod % 10
+ local parent = currentLoadout.CurrentLoadout:FindFirstChild("Slot"..tostring(slotNum))
+ gearClone.Parent = parent
+
+ if inventoryGearButton then
+ local absolutePositionFinal = inventoryGearButton.AbsolutePosition
+ local currentAbsolutePosition = gearClone.AbsolutePosition
+ local diff = absolutePositionFinal - currentAbsolutePosition
+ gearClone.Position = UDim2.new(gearClone.Position.X.Scale,diff.x,gearClone.Position.Y.Scale,diff.y)
+ gearClone.ZIndex = 4
+ end
+
+ if addToSlot then
+ reorganizeLoadout(gearClone, true, equipped, addToSlot)
+ else
+ reorganizeLoadout(gearClone, true)
+ end
+
+ if gearClone.Parent == nil then debounce.Value = false return end -- couldn't fit in (hopper is full!)
+
+ if equipped then
+ gearClone.Selected = true
+ unequipAllItems(child)
+ delay(guiTweenSpeed + 0.01,function() -- if our gear is equipped, we will want to enlarge it when done moving
+ if (gearClone.GearReference.Value:IsA("Tool") and gearClone.GearReference.Value.Parent == player.Character) or
+ (gearClone.GearReference.Value:IsA("HopperBin") and gearClone.GearReference.Value.Active == true) then
+ enlargeButton(gearClone)
+ end
+ end)
+ end
+
+ local dragBeginPos = nil
+ local clickCon, buttonDeleteCon, mouseEnterCon, mouseLeaveCon, dragStop, dragBegin = nil
+ clickCon = gearClone.MouseButton1Click:connect(function() if not gearClone.Draggable then activateGear(gearClone.SlotNumber.Text) end end)
+ mouseEnterCon = gearClone.MouseEnter:connect(function()
+ if guiBackpack.Visible then
+ gearClone.Draggable = true
+ end
+ end)
+ dragBegin = gearClone.DragBegin:connect(function(pos)
+ dragBeginPos = pos
+ gearClone.ZIndex = 7
+ local children = gearClone:GetChildren()
+ for i = 1, #children do
+ if children[i]:IsA("TextLabel") then
+ if string.find(children[i].Name,"Shadow") then
+ children[i].ZIndex = 8
+ else
+ children[i].ZIndex = 9
+ end
+ elseif children[i]:IsA("Frame") or children[i]:IsA("ImageLabel") then
+ children[i].ZIndex = 7
+ end
+ end
+ end)
+ dragStop = gearClone.DragStopped:connect(function(x,y)
+ if gearClone.Selected then
+ gearClone.ZIndex = 2
+ else
+ gearClone.ZIndex = 1
+ end
+ local children = gearClone:GetChildren()
+ for i = 1, #children do
+ if children[i]:IsA("TextLabel") then
+ if string.find(children[i].Name,"Shadow") then
+ children[i].ZIndex = 3
+ else
+ children[i].ZIndex = 4
+ end
+ elseif children[i]:IsA("Frame") or children[i]:IsA("ImageLabel") then
+ children[i].ZIndex = 2
+ end
+ end
+ resolveDrag(gearClone,x,y)
+ end)
+ mouseLeaveCon = gearClone.MouseLeave:connect(function()
+ gearClone.Draggable = false
+ end)
+ buttonDeleteCon = gearClone.AncestryChanged:connect(function()
+ if gearClone.Parent and gearClone.Parent.Parent == currentLoadout then return end
+ if clickCon then clickCon:disconnect() end
+ if buttonDeleteCon then buttonDeleteCon:disconnect() end
+ if mouseEnterCon then mouseEnterCon:disconnect() end
+ if mouseLeaveCon then mouseLeaveCon:disconnect() end
+ if dragStop then dragStop:disconnect() end
+ if dragBegin then dragBegin:disconnect() end
+ end) -- this probably isn't necessary since objects are being deleted (probably), but this might still leak just in case
+
+ local childCon = nil
+ local childChangeCon = nil
+ childCon = child.AncestryChanged:connect(function(newChild,parent)
+ if not checkToolAncestry(newChild,parent) then
+ if childCon then childCon:disconnect() end
+ if childChangeCon then childChangeCon:disconnect() end
+ removeFromInventory(child)
+ elseif parent == game.Players.LocalPlayer.Backpack then
+ normalizeButton(gearClone)
+ end
+ end)
+
+ childChangeCon = child.Changed:connect(function(prop)
+ if prop == "Name" then
+ if gearClone and gearClone.GearImage.Image == "" then
+ gearClone.GearText.Text = child.Name
+ end
+ end
+ end)
+
+ debounce.Value = false
+
+end
+
+function addToInventory(child)
+ if not child:IsA("Tool") or not child:IsA("HopperBin") then return end
+
+ local slot = nil
+ for i = 1, #inventory do
+ if inventory[i] and inventory[i] == child then return end
+ if not inventory[i] then slot = i end
+ end
+ if slot then
+ inventory[slot] = child
+ elseif #inventory < 1 then
+ inventory[1] = child
+ else
+ inventory[#inventory + 1] = child
+ end
+end
+
+function removeFromInventory(child)
+ for i = 1, #inventory do
+ if inventory[i] == child then
+ table.remove(inventory,i)
+ inventory[i] = nil
+ end
+ end
+end
+
+-- these next two functions are used for safe guarding
+-- when we are waiting for character to come back after dying
+function activateLoadout()
+ keyPressCon = game:GetService("GuiService").KeyPressed:connect(function(key) activateGear(key) end)
+ currentLoadout.Visible = true
+end
+
+function deactivateLoadout()
+ if keyPressCon then keyPressCon:disconnect() end
+ currentLoadout.CurrentLoadout.Visible = false
+end
+
+function setupBackpackListener()
+ if backpackChildCon then backpackChildCon:disconnect() end
+ backpackChildCon = player.Backpack.ChildAdded:connect(function(child)
+ addingPlayerChild(child)
+ addToInventory(child)
+ end)
+end
+
+function playerCharacterChildAdded(child)
+ addingPlayerChild(child,true)
+ addToInventory(child)
+end
+-- End Functions
+
+
+
+
+
+
+-- Begin Script
+wait() -- let stuff initialize incase this is first heartbeat...
+
+waitForChild(player,"Backpack")
+local backpackChildren = player.Backpack:GetChildren()
+local size = math.min(10,#backpackChildren)
+for i = 1, size do
+ addingPlayerChild(backpackChildren[i],false)
+end
+setupBackpackListener()
+
+waitForProperty(player,"Character")
+for i,v in ipairs(player.Character:GetChildren()) do
+ playerCharacterChildAdded(v)
+end
+characterChildAddedCon = player.Character.ChildAdded:connect(function(child) playerCharacterChildAdded(child) end)
+
+waitForChild(player.Character,"Humanoid")
+humanoidDiedCon = player.Character.Humanoid.Died:connect(function() deactivateLoadout() end)
+
+player.CharacterRemoving:connect(function()
+ if characterChildAddedCon then characterChildAddedCon:disconnect() end
+ if humanoidDiedCon then humanoidDiedCon:disconnect() end
+ if backpackChildCon then backpackChildCon:disconnect() end
+ deactivateLoadout()
+end)
+player.CharacterAdded:connect(function()
+ player = game.Players.LocalPlayer -- make sure we are still looking at the correct character
+
+ for i = 1, #gearSlots do
+ if gearSlots[i] ~= "empty" then
+ gearSlots[i].Parent = nil
+ gearSlots[i] = "empty"
+ end
+ end
+
+ local backpackChildren = player.Backpack:GetChildren()
+ local size = math.min(10,#backpackChildren)
+ for i = 1, size do
+ addingPlayerChild(backpackChildren[i])
+ end
+
+ setupBackpackListener()
+
+ characterChildAddedCon =
+ player.Character.ChildAdded:connect(function(child)
+ addingPlayerChild(child,true)
+ end)
+
+ waitForChild(player.Character,"Humanoid")
+ humanoidDiedCon =
+ player.Character.Humanoid.Died:connect(function()
+ deactivateLoadout()
+ end)
+ activateLoadout()
+end)
+
+waitForChild(guiBackpack,"SwapSlot")
+guiBackpack.SwapSlot.Changed:connect(function()
+ if guiBackpack.SwapSlot.Value then
+ local swapSlot = guiBackpack.SwapSlot
+ local pos = swapSlot.Slot.Value
+ if pos == 0 then pos = 10 end
+ if gearSlots[pos] then
+ reorganizeLoadout(gearSlots[pos],false)
+ end
+ if swapSlot.GearButton.Value then
+ addingPlayerChild(swapSlot.GearButton.Value.GearReference.Value,false,pos)
+ end
+ guiBackpack.SwapSlot.Value = false
+ end
+end)
+
+
+
+
+ -
+
+ false
+ 4288914085
+ 1
+ 4279970357
+ 1
+ false
+ false
+ ControlFrame
+
+ 0
+ 0
+ 0
+ 0
+
+
+ 1
+ 0
+ 1
+ 0
+
+ 0
+ 0
+ true
+ 1
+
+
-
+
+ false
+ 4288914085
+ 1
+ 4279970357
+ 1
+ false
+ false
+ NotificationBox
+
+ 1
+ -200
+ 0.5
+ 0
+
+
+ 0
+ 200
+ 0.419999987
+ 0
+
+ 0
+ true
+ 1
+
+
+
+
+ -
+
+ Menu
+
+
-
+
+ false
+
+ MenuScript
+ -- fixed by iago#6808 --
+-- version 0.25 --
+-- changelog: --
+-- 100% finished settings menu --
+-- report abuse is still in work --
+
+local t = {}
+
+local function ScopedConnect(parentInstance, instance, event, signalFunc, syncFunc, removeFunc)
+ local eventConnection = nil
+
+ --Connection on parentInstance is scoped by parentInstance (when destroyed, it goes away)
+ local tryConnect = function()
+ if game:IsAncestorOf(parentInstance) then
+ --Entering the world, make sure we are connected/synced
+ if not eventConnection then
+ eventConnection = instance[event]:connect(signalFunc)
+ if syncFunc then syncFunc() end
+ end
+ else
+ --Probably leaving the world, so disconnect for now
+ if eventConnection then
+ eventConnection:disconnect()
+ if removeFunc then removeFunc() end
+ end
+ end
+ end
+
+ --Hook it up to ancestryChanged signal
+ local connection = parentInstance.AncestryChanged:connect(tryConnect)
+
+ --Now connect us if we're already in the world
+ tryConnect()
+
+ return connection
+end
+
+local function getScreenGuiAncestor(instance)
+ local localInstance = instance
+ while localInstance and not localInstance:IsA("ScreenGui") do
+ localInstance = localInstance.Parent
+ end
+ return localInstance
+end
+
+local function CreateButtons(frame, buttons, yPos, ySize)
+ local buttonNum = 1
+ local buttonObjs = {}
+ for i, obj in ipairs(buttons) do
+ local button = Instance.new("TextButton")
+ button.Name = "Button" .. buttonNum
+ button.Font = Enum.Font.Arial
+ button.FontSize = Enum.FontSize.Size18
+ button.AutoButtonColor = true
+ button.Modal = true
+ if obj["Style"] then
+ button.Style = obj.Style
+ else
+ button.Style = Enum.ButtonStyle.RobloxButton
+ end
+ if obj["ZIndex"] then
+ button.ZIndex = obj.ZIndex
+ end
+ button.Text = obj.Text
+ button.TextColor3 = Color3.new(1,1,1)
+ button.MouseButton1Click:connect(obj.Function)
+ button.Parent = frame
+ buttonObjs[buttonNum] = button
+
+ buttonNum = buttonNum + 1
+ end
+ local numButtons = buttonNum-1
+
+ if numButtons == 1 then
+ frame.Button1.Position = UDim2.new(0.35, 0, yPos.Scale, yPos.Offset)
+ frame.Button1.Size = UDim2.new(.4,0,ySize.Scale, ySize.Offset)
+ elseif numButtons == 2 then
+ frame.Button1.Position = UDim2.new(0.1, 0, yPos.Scale, yPos.Offset)
+ frame.Button1.Size = UDim2.new(.8/3,0, ySize.Scale, ySize.Offset)
+
+ frame.Button2.Position = UDim2.new(0.55, 0, yPos.Scale, yPos.Offset)
+ frame.Button2.Size = UDim2.new(.35,0, ySize.Scale, ySize.Offset)
+ elseif numButtons >= 3 then
+ local spacing = .1 / numButtons
+ local buttonSize = .9 / numButtons
+
+ buttonNum = 1
+ while buttonNum <= numButtons do
+ buttonObjs[buttonNum].Position = UDim2.new(spacing*buttonNum + (buttonNum-1) * buttonSize, 0, yPos.Scale, yPos.Offset)
+ buttonObjs[buttonNum].Size = UDim2.new(buttonSize, 0, ySize.Scale, ySize.Offset)
+ buttonNum = buttonNum + 1
+ end
+ end
+end
+
+local function setSliderPos(newAbsPosX,slider,sliderPosition,bar,steps)
+
+ local steps = 10
+ local newStep = steps - 1 --otherwise we really get one more step than we want
+ local relativePosX = math.min(1, math.max(0, (newAbsPosX - bar.AbsolutePosition.X) / bar.AbsoluteSize.X ))
+ local wholeNum, remainder = math.modf(relativePosX * newStep)
+ if remainder > 0.5 then
+ wholeNum = wholeNum + 1
+ end
+ relativePosX = wholeNum/newStep
+
+ local result = math.ceil(relativePosX * newStep)
+ if sliderPosition.Value ~= (result + 1) then --only update if we moved a step
+ sliderPosition.Value = result + 1
+ slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
+ end
+
+end
+
+local function cancelSlide(areaSoak)
+ areaSoak.Visible = false
+ if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
+end
+
+t.CreateStyledMessageDialog = function(title, message, style, buttons)
+ local frame = Instance.new("Frame")
+ frame.Size = UDim2.new(0.5, 0, 0, 165)
+ frame.Position = UDim2.new(0.25, 0, 0.5, -72.5)
+ frame.Name = "MessageDialog"
+ frame.Active = true
+ frame.Style = Enum.FrameStyle.RobloxRound
+
+ local styleImage = Instance.new("ImageLabel")
+ styleImage.Name = "StyleImage"
+ styleImage.BackgroundTransparency = 1
+ styleImage.Position = UDim2.new(0,5,0,15)
+ if style == "error" or style == "Error" then
+ styleImage.Size = UDim2.new(0, 71, 0, 71)
+ styleImage.Image = "http://www.roblox.com/asset/?id=42565285"
+ elseif style == "notify" or style == "Notify" then
+ styleImage.Size = UDim2.new(0, 71, 0, 71)
+ styleImage.Image = "http://www.roblox.com/asset/?id=42604978"
+ elseif style == "confirm" or style == "Confirm" then
+ styleImage.Size = UDim2.new(0, 74, 0, 76)
+ styleImage.Image = "http://www.roblox.com/asset/?id=42557901"
+ else
+ return t.CreateMessageDialog(title,message,buttons)
+ end
+ styleImage.Parent = frame
+
+ local titleLabel = Instance.new("TextLabel")
+ titleLabel.Name = "Title"
+ titleLabel.Text = title
+ titleLabel.TextStrokeTransparency = 0
+ titleLabel.BackgroundTransparency = 1
+ titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
+ titleLabel.Position = UDim2.new(0, 80, 0, 0)
+ titleLabel.Size = UDim2.new(1, -80, 0, 40)
+ titleLabel.Font = Enum.Font.ArialBold
+ titleLabel.FontSize = Enum.FontSize.Size36
+ titleLabel.TextXAlignment = Enum.TextXAlignment.Center
+ titleLabel.TextYAlignment = Enum.TextYAlignment.Center
+ titleLabel.Parent = frame
+
+ local messageLabel = Instance.new("TextLabel")
+ messageLabel.Name = "Message"
+ messageLabel.Text = message
+ messageLabel.TextStrokeTransparency = 0
+ messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
+ messageLabel.Position = UDim2.new(0.025, 80, 0, 45)
+ messageLabel.Size = UDim2.new(0.95, -80, 0, 55)
+ messageLabel.BackgroundTransparency = 1
+ messageLabel.Font = Enum.Font.Arial
+ messageLabel.FontSize = Enum.FontSize.Size18
+ messageLabel.TextWrap = true
+ messageLabel.TextXAlignment = Enum.TextXAlignment.Left
+ messageLabel.TextYAlignment = Enum.TextYAlignment.Top
+ messageLabel.Parent = frame
+
+ CreateButtons(frame, buttons, UDim.new(0, 105), UDim.new(0, 40) )
+
+ return frame
+end
+
+t.CreateMessageDialog = function(title, message, buttons)
+ local frame = Instance.new("Frame")
+ frame.Size = UDim2.new(0.5, 0, 0.5, 0)
+ frame.Position = UDim2.new(0.25, 0, 0.25, 0)
+ frame.Name = "MessageDialog"
+ frame.Active = true
+ frame.Style = Enum.FrameStyle.RobloxRound
+
+ local titleLabel = Instance.new("TextLabel")
+ titleLabel.Name = "Title"
+ titleLabel.Text = title
+ titleLabel.BackgroundTransparency = 1
+ titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
+ titleLabel.Position = UDim2.new(0, 0, 0, 0)
+ titleLabel.Size = UDim2.new(1, 0, 0.15, 0)
+ titleLabel.Font = Enum.Font.ArialBold
+ titleLabel.FontSize = Enum.FontSize.Size36
+ titleLabel.TextXAlignment = Enum.TextXAlignment.Center
+ titleLabel.TextYAlignment = Enum.TextYAlignment.Center
+ titleLabel.Parent = frame
+
+ local messageLabel = Instance.new("TextLabel")
+ messageLabel.Name = "Message"
+ messageLabel.Text = message
+ messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
+ messageLabel.Position = UDim2.new(0.025, 0, 0.175, 0)
+ messageLabel.Size = UDim2.new(0.95, 0, .55, 0)
+ messageLabel.BackgroundTransparency = 1
+ messageLabel.Font = Enum.Font.Arial
+ messageLabel.FontSize = Enum.FontSize.Size18
+ messageLabel.TextWrap = true
+ messageLabel.TextXAlignment = Enum.TextXAlignment.Left
+ messageLabel.TextYAlignment = Enum.TextYAlignment.Top
+ messageLabel.Parent = frame
+
+ CreateButtons(frame, buttons, UDim.new(0.8,0), UDim.new(0.15, 0))
+
+ return frame
+end
+
+t.CreateDropDownMenu = function(items, onSelect, forRoblox, whiteSkin, baseZ)
+ local baseZIndex = 0
+ if (type(baseZ) == "number") then
+ baseZIndex = baseZ
+ end
+ local width = UDim.new(0, 100)
+ local height = UDim.new(0, 32)
+
+ local xPos = 0.055
+ local frame = Instance.new("Frame")
+ local textColor = Color3.new(1,1,1)
+ if (whiteSkin) then
+ textColor = Color3.new(0.5, 0.5, 0.5)
+ end
+ frame.Name = "DropDownMenu"
+ frame.BackgroundTransparency = 1
+ frame.Size = UDim2.new(width, height)
+
+ local dropDownMenu = Instance.new("TextButton")
+ dropDownMenu.Name = "DropDownMenuButton"
+ dropDownMenu.TextWrap = true
+ dropDownMenu.TextColor3 = textColor
+ dropDownMenu.Text = "Choose One"
+ dropDownMenu.Font = Enum.Font.ArialBold
+ dropDownMenu.FontSize = Enum.FontSize.Size18
+ dropDownMenu.TextXAlignment = Enum.TextXAlignment.Left
+ dropDownMenu.TextYAlignment = Enum.TextYAlignment.Center
+ dropDownMenu.BackgroundTransparency = 1
+ dropDownMenu.AutoButtonColor = true
+ if (whiteSkin) then
+ dropDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton
+ else
+ dropDownMenu.Style = Enum.ButtonStyle.RobloxButton
+ end
+ dropDownMenu.Size = UDim2.new(1,0,1,0)
+ dropDownMenu.Parent = frame
+ dropDownMenu.ZIndex = 2 + baseZIndex
+
+ local dropDownIcon = Instance.new("ImageLabel")
+ dropDownIcon.Name = "Icon"
+ dropDownIcon.Active = false
+ if (whiteSkin) then
+ dropDownIcon.Image = "rbxasset://textures/ui/dropdown_arrow.png"
+ dropDownIcon.Size = UDim2.new(0,16,0,12)
+ dropDownIcon.Position = UDim2.new(1,-17,0.5, -6)
+ else
+ dropDownIcon.Image = "http://www.roblox.com/asset/?id=45732894"
+ dropDownIcon.Size = UDim2.new(0,11,0,6)
+ dropDownIcon.Position = UDim2.new(1,-11,0.5, -2)
+ end
+ dropDownIcon.BackgroundTransparency = 1
+ dropDownIcon.Parent = dropDownMenu
+ dropDownIcon.ZIndex = 2 + baseZIndex
+
+ local itemCount = #items
+ local dropDownItemCount = #items
+ local useScrollButtons = false
+ if dropDownItemCount > 6 then
+ useScrollButtons = true
+ dropDownItemCount = 6
+ end
+
+ local droppedDownMenu = Instance.new("TextButton")
+ droppedDownMenu.Name = "List"
+ droppedDownMenu.Text = ""
+ droppedDownMenu.BackgroundTransparency = 1
+ --droppedDownMenu.AutoButtonColor = true
+ if (whiteSkin) then
+ droppedDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton
+ else
+ droppedDownMenu.Style = Enum.ButtonStyle.RobloxButton
+ end
+ droppedDownMenu.Visible = false
+ droppedDownMenu.Active = true --Blocks clicks
+ droppedDownMenu.Position = UDim2.new(0,0,0,0)
+ droppedDownMenu.Size = UDim2.new(1,0, (1 + dropDownItemCount)*.8, 0)
+ droppedDownMenu.Parent = frame
+ droppedDownMenu.ZIndex = 2 + baseZIndex
+
+ local choiceButton = Instance.new("TextButton")
+ choiceButton.Name = "ChoiceButton"
+ choiceButton.BackgroundTransparency = 1
+ choiceButton.BorderSizePixel = 0
+ choiceButton.Text = "ReplaceMe"
+ choiceButton.TextColor3 = textColor
+ choiceButton.TextXAlignment = Enum.TextXAlignment.Left
+ choiceButton.TextYAlignment = Enum.TextYAlignment.Center
+ choiceButton.BackgroundColor3 = Color3.new(1, 1, 1)
+ choiceButton.Font = Enum.Font.Arial
+ choiceButton.FontSize = Enum.FontSize.Size18
+ if useScrollButtons then
+ choiceButton.Size = UDim2.new(1,-13, .8/((dropDownItemCount + 1)*.8),0)
+ else
+ choiceButton.Size = UDim2.new(1, 0, .8/((dropDownItemCount + 1)*.8),0)
+ end
+ choiceButton.TextWrap = true
+ choiceButton.ZIndex = 2 + baseZIndex
+
+ local areaSoak = Instance.new("TextButton")
+ areaSoak.Name = "AreaSoak"
+ areaSoak.Text = ""
+ areaSoak.BackgroundTransparency = 1
+ areaSoak.Active = true
+ areaSoak.Size = UDim2.new(1,0,1,0)
+ areaSoak.Visible = false
+ areaSoak.ZIndex = 3 + baseZIndex
+
+ local dropDownSelected = false
+
+ local scrollUpButton
+ local scrollDownButton
+ local scrollMouseCount = 0
+
+ local setZIndex = function(baseZIndex)
+ droppedDownMenu.ZIndex = baseZIndex +1
+ if scrollUpButton then
+ scrollUpButton.ZIndex = baseZIndex + 3
+ end
+ if scrollDownButton then
+ scrollDownButton.ZIndex = baseZIndex + 3
+ end
+
+ local children = droppedDownMenu:GetChildren()
+ if children then
+ for i, child in ipairs(children) do
+ if child.Name == "ChoiceButton" then
+ child.ZIndex = baseZIndex + 2
+ elseif child.Name == "ClickCaptureButton" then
+ child.ZIndex = baseZIndex
+ end
+ end
+ end
+ end
+
+ local scrollBarPosition = 1
+ local updateScroll = function()
+ if scrollUpButton then
+ scrollUpButton.Active = scrollBarPosition > 1
+ end
+ if scrollDownButton then
+ scrollDownButton.Active = scrollBarPosition + dropDownItemCount <= itemCount
+ end
+
+ local children = droppedDownMenu:GetChildren()
+ if not children then return end
+
+ local childNum = 1
+ for i, obj in ipairs(children) do
+ if obj.Name == "ChoiceButton" then
+ if childNum < scrollBarPosition or childNum >= scrollBarPosition + dropDownItemCount then
+ obj.Visible = false
+ else
+ obj.Position = UDim2.new(0,0,((childNum-scrollBarPosition+1)*.8)/((dropDownItemCount+1)*.8),0)
+ obj.Visible = true
+ end
+ obj.TextColor3 = textColor
+ obj.BackgroundTransparency = 1
+
+ childNum = childNum + 1
+ end
+ end
+ end
+ local toggleVisibility = function()
+ dropDownSelected = not dropDownSelected
+
+ areaSoak.Visible = not areaSoak.Visible
+ dropDownMenu.Visible = not dropDownSelected
+ droppedDownMenu.Visible = dropDownSelected
+ if dropDownSelected then
+ setZIndex(4 + baseZIndex)
+ else
+ setZIndex(2 + baseZIndex)
+ end
+ if useScrollButtons then
+ updateScroll()
+ end
+ end
+ droppedDownMenu.MouseButton1Click:connect(toggleVisibility)
+
+ local updateSelection = function(text)
+ local foundItem = false
+ local children = droppedDownMenu:GetChildren()
+ local childNum = 1
+ if children then
+ for i, obj in ipairs(children) do
+ if obj.Name == "ChoiceButton" then
+ if obj.Text == text then
+ obj.Font = Enum.Font.ArialBold
+ foundItem = true
+ scrollBarPosition = childNum
+ if (whiteSkin) then
+ obj.TextColor3 = Color3.new(90/255,142/255,233/255)
+ end
+ else
+ obj.Font = Enum.Font.Arial
+ if (whiteSkin) then
+ obj.TextColor3 = textColor
+ end
+ end
+ childNum = childNum + 1
+ end
+ end
+ end
+ if not text then
+ dropDownMenu.Text = "Choose One"
+ scrollBarPosition = 1
+ else
+ if not foundItem then
+ error("Invalid Selection Update -- " .. text)
+ end
+
+ if scrollBarPosition + dropDownItemCount > itemCount + 1 then
+ scrollBarPosition = itemCount - dropDownItemCount + 1
+ end
+
+ dropDownMenu.Text = text
+ end
+ end
+
+ local function scrollDown()
+ if scrollBarPosition + dropDownItemCount <= itemCount then
+ scrollBarPosition = scrollBarPosition + 1
+ updateScroll()
+ return true
+ end
+ return false
+ end
+ local function scrollUp()
+ if scrollBarPosition > 1 then
+ scrollBarPosition = scrollBarPosition - 1
+ updateScroll()
+ return true
+ end
+ return false
+ end
+
+ if useScrollButtons then
+ --Make some scroll buttons
+ scrollUpButton = Instance.new("ImageButton")
+ scrollUpButton.Name = "ScrollUpButton"
+ scrollUpButton.BackgroundTransparency = 1
+ scrollUpButton.Image = "rbxasset://textures/ui/scrollbuttonUp.png"
+ scrollUpButton.Size = UDim2.new(0,17,0,17)
+ scrollUpButton.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),0)
+ scrollUpButton.MouseButton1Click:connect(
+ function()
+ scrollMouseCount = scrollMouseCount + 1
+ end)
+ scrollUpButton.MouseLeave:connect(
+ function()
+ scrollMouseCount = scrollMouseCount + 1
+ end)
+ scrollUpButton.MouseButton1Down:connect(
+ function()
+ scrollMouseCount = scrollMouseCount + 1
+
+ scrollUp()
+ local val = scrollMouseCount
+ wait(0.5)
+ while val == scrollMouseCount do
+ if scrollUp() == false then
+ break
+ end
+ wait(0.1)
+ end
+ end)
+
+ scrollUpButton.Parent = droppedDownMenu
+
+ scrollDownButton = Instance.new("ImageButton")
+ scrollDownButton.Name = "ScrollDownButton"
+ scrollDownButton.BackgroundTransparency = 1
+ scrollDownButton.Image = "rbxasset://textures/ui/scrollbuttonDown.png"
+ scrollDownButton.Size = UDim2.new(0,17,0,17)
+ scrollDownButton.Position = UDim2.new(1,-11,1,-11)
+ scrollDownButton.Parent = droppedDownMenu
+ scrollDownButton.MouseButton1Click:connect(
+ function()
+ scrollMouseCount = scrollMouseCount + 1
+ end)
+ scrollDownButton.MouseLeave:connect(
+ function()
+ scrollMouseCount = scrollMouseCount + 1
+ end)
+ scrollDownButton.MouseButton1Down:connect(
+ function()
+ scrollMouseCount = scrollMouseCount + 1
+
+ scrollDown()
+ local val = scrollMouseCount
+ wait(0.5)
+ while val == scrollMouseCount do
+ if scrollDown() == false then
+ break
+ end
+ wait(0.1)
+ end
+ end)
+
+ local scrollbar = Instance.new("ImageLabel")
+ scrollbar.Name = "ScrollBar"
+ scrollbar.Image = "rbxasset://textures/ui/scrollbar.png"
+ scrollbar.BackgroundTransparency = 1
+ scrollbar.Size = UDim2.new(0, 18, (dropDownItemCount*.8)/((dropDownItemCount+1)*.8), -(17) - 11 - 4)
+ scrollbar.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),17+2)
+ scrollbar.Parent = droppedDownMenu
+ end
+
+ for i,item in ipairs(items) do
+ -- needed to maintain local scope for items in event listeners below
+ local button = choiceButton:clone()
+ if forRoblox then
+
+ end
+ button.Text = item
+ button.Parent = droppedDownMenu
+ if (whiteSkin) then
+ button.TextColor3 = textColor
+ end
+
+ button.MouseButton1Click:connect(function()
+ --Remove Highlight
+ if (not whiteSkin) then
+ button.TextColor3 = Color3.new(1,1,1)
+ end
+ button.BackgroundTransparency = 1
+
+ updateSelection(item)
+ onSelect(item)
+
+ toggleVisibility()
+ end)
+ button.MouseEnter:connect(function()
+ --Add Highlight
+ if (not whiteSkin) then
+ button.TextColor3 = Color3.new(0,0,0)
+ end
+ button.BackgroundTransparency = 0
+ end)
+
+ button.MouseLeave:connect(function()
+ --Remove Highlight
+ if (not whiteSkin) then
+ button.TextColor3 = Color3.new(1,1,1)
+ end
+ button.BackgroundTransparency = 1
+ end)
+ end
+
+ --This does the initial layout of the buttons
+ updateScroll()
+
+ frame.AncestryChanged:connect(function(child,parent)
+ if parent == nil then
+ areaSoak.Parent = nil
+ else
+ areaSoak.Parent = getScreenGuiAncestor(frame)
+ end
+ end)
+
+ dropDownMenu.MouseButton1Click:connect(toggleVisibility)
+ areaSoak.MouseButton1Click:connect(toggleVisibility)
+ return frame, updateSelection
+end
+
+t.CreatePropertyDropDownMenu = function(instance, property, enum)
+
+ local items = enum:GetEnumItems()
+ local names = {}
+ local nameToItem = {}
+ for i,obj in ipairs(items) do
+ names[i] = obj.Name
+ nameToItem[obj.Name] = obj
+ end
+
+ local frame
+ local updateSelection
+ frame, updateSelection = t.CreateDropDownMenu(names, function(text) instance[property] = nameToItem[text] end)
+
+ ScopedConnect(frame, instance, "Changed",
+ function(prop)
+ if prop == property then
+ updateSelection(instance[property].Name)
+ end
+ end,
+ function()
+ updateSelection(instance[property].Name)
+ end)
+
+ return frame
+end
+
+t.GetFontHeight = function(font, fontSize)
+ if font == nil or fontSize == nil then
+ error("Font and FontSize must be non-nil")
+ end
+
+ if font == Enum.Font.Legacy then
+ if fontSize == Enum.FontSize.Size8 then
+ return 12
+ elseif fontSize == Enum.FontSize.Size9 then
+ return 14
+ elseif fontSize == Enum.FontSize.Size10 then
+ return 15
+ elseif fontSize == Enum.FontSize.Size11 then
+ return 17
+ elseif fontSize == Enum.FontSize.Size12 then
+ return 18
+ elseif fontSize == Enum.FontSize.Size14 then
+ return 21
+ elseif fontSize == Enum.FontSize.Size18 then
+ return 27
+ elseif fontSize == Enum.FontSize.Size24 then
+ return 36
+ elseif fontSize == Enum.FontSize.Size36 then
+ return 54
+ elseif fontSize == Enum.FontSize.Size48 then
+ return 72
+ else
+ error("Unknown FontSize")
+ end
+ elseif font == Enum.Font.Arial or font == Enum.Font.ArialBold then
+ if fontSize == Enum.FontSize.Size8 then
+ return 8
+ elseif fontSize == Enum.FontSize.Size9 then
+ return 9
+ elseif fontSize == Enum.FontSize.Size10 then
+ return 10
+ elseif fontSize == Enum.FontSize.Size11 then
+ return 11
+ elseif fontSize == Enum.FontSize.Size12 then
+ return 12
+ elseif fontSize == Enum.FontSize.Size14 then
+ return 14
+ elseif fontSize == Enum.FontSize.Size18 then
+ return 18
+ elseif fontSize == Enum.FontSize.Size24 then
+ return 24
+ elseif fontSize == Enum.FontSize.Size36 then
+ return 36
+ elseif fontSize == Enum.FontSize.Size48 then
+ return 48
+ else
+ error("Unknown FontSize")
+ end
+ else
+ error("Unknown Font " .. font)
+ end
+end
+
+local function layoutGuiObjectsHelper(frame, guiObjects, settingsTable)
+ local totalPixels = frame.AbsoluteSize.Y
+ local pixelsRemaining = frame.AbsoluteSize.Y
+ for i, child in ipairs(guiObjects) do
+ if child:IsA("TextLabel") or child:IsA("TextButton") then
+ local isLabel = child:IsA("TextLabel")
+ if isLabel then
+ pixelsRemaining = pixelsRemaining - settingsTable["TextLabelPositionPadY"]
+ else
+ pixelsRemaining = pixelsRemaining - settingsTable["TextButtonPositionPadY"]
+ end
+ child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
+ child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, pixelsRemaining)
+
+ if child.TextFits and child.TextBounds.Y < pixelsRemaining then
+ child.Visible = true
+ if isLabel then
+ child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable["TextLabelSizePadY"])
+ else
+ child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable["TextButtonSizePadY"])
+ end
+
+ while not child.TextFits do
+ child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.AbsoluteSize.Y + 1)
+ end
+ pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
+
+ if isLabel then
+ pixelsRemaining = pixelsRemaining - settingsTable["TextLabelPositionPadY"]
+ else
+ pixelsRemaining = pixelsRemaining - settingsTable["TextButtonPositionPadY"]
+ end
+ else
+ child.Visible = false
+ pixelsRemaining = -1
+ end
+
+ else
+ --GuiObject
+ child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
+ pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
+ child.Visible = (pixelsRemaining >= 0)
+ end
+ end
+end
+
+t.LayoutGuiObjects = function(frame, guiObjects, settingsTable)
+ if not frame:IsA("GuiObject") then
+ error("Frame must be a GuiObject")
+ end
+ for i, child in ipairs(guiObjects) do
+ if not child:IsA("GuiObject") then
+ error("All elements that are layed out must be of type GuiObject")
+ end
+ end
+
+ if not settingsTable then
+ settingsTable = {}
+ end
+
+ if not settingsTable["TextLabelSizePadY"] then
+ settingsTable["TextLabelSizePadY"] = 0
+ end
+ if not settingsTable["TextLabelPositionPadY"] then
+ settingsTable["TextLabelPositionPadY"] = 0
+ end
+ if not settingsTable["TextButtonSizePadY"] then
+ settingsTable["TextButtonSizePadY"] = 12
+ end
+ if not settingsTable["TextButtonPositionPadY"] then
+ settingsTable["TextButtonPositionPadY"] = 2
+ end
+
+ --Wrapper frame takes care of styled objects
+ local wrapperFrame = Instance.new("Frame")
+ wrapperFrame.Name = "WrapperFrame"
+ wrapperFrame.BackgroundTransparency = 1
+ wrapperFrame.Size = UDim2.new(1,0,1,0)
+ wrapperFrame.Parent = frame
+
+ for i, child in ipairs(guiObjects) do
+ child.Parent = wrapperFrame
+ end
+
+ local recalculate = function()
+ wait()
+ layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable)
+ end
+
+ frame.Changed:connect(
+ function(prop)
+ if prop == "AbsoluteSize" then
+ --Wait a heartbeat for it to sync in
+ recalculate(nil)
+ end
+ end)
+ frame.AncestryChanged:connect(recalculate)
+
+ layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable)
+end
+
+
+t.CreateSlider = function(steps,width,position)
+ local sliderGui = Instance.new("Frame")
+ sliderGui.Size = UDim2.new(1,0,1,0)
+ sliderGui.BackgroundTransparency = 1
+ sliderGui.Name = "SliderGui"
+
+ local sliderSteps = Instance.new("IntValue")
+ sliderSteps.Name = "SliderSteps"
+ sliderSteps.Value = steps
+ sliderSteps.Parent = sliderGui
+
+ local areaSoak = Instance.new("TextButton")
+ areaSoak.Name = "AreaSoak"
+ areaSoak.Text = ""
+ areaSoak.BackgroundTransparency = 1
+ areaSoak.Active = false
+ areaSoak.Size = UDim2.new(1,0,1,0)
+ areaSoak.Visible = false
+ areaSoak.ZIndex = 4
+
+ sliderGui.AncestryChanged:connect(function(child,parent)
+ if parent == nil then
+ areaSoak.Parent = nil
+ else
+ areaSoak.Parent = getScreenGuiAncestor(sliderGui)
+ end
+ end)
+
+ local sliderPosition = Instance.new("IntValue")
+ sliderPosition.Name = "SliderPosition"
+ sliderPosition.Value = 0
+ sliderPosition.Parent = sliderGui
+
+ local id = math.random(1,100)
+
+ local bar = Instance.new("TextButton")
+ bar.Text = ""
+ bar.AutoButtonColor = false
+ bar.Name = "Bar"
+ bar.BackgroundColor3 = Color3.new(0,0,0)
+ if type(width) == "number" then
+ bar.Size = UDim2.new(0,width,0,5)
+ else
+ bar.Size = UDim2.new(0,200,0,5)
+ end
+ bar.BorderColor3 = Color3.new(95/255,95/255,95/255)
+ bar.ZIndex = 2
+ bar.Parent = sliderGui
+
+ if position["X"] and position["X"]["Scale"] and position["X"]["Offset"] and position["Y"] and position["Y"]["Scale"] and position["Y"]["Offset"] then
+ bar.Position = position
+ end
+
+ local slider = Instance.new("ImageButton")
+ slider.Name = "Slider"
+ slider.BackgroundTransparency = 1
+ slider.Image = "rbxasset://textures/ui/Slider.png"
+ slider.Position = UDim2.new(0,0,0.5,-10)
+ slider.Size = UDim2.new(0,20,0,20)
+ slider.ZIndex = 3
+ slider.Parent = bar
+
+ local areaSoakMouseMoveCon = nil
+
+ areaSoak.MouseLeave:connect(function()
+ if areaSoak.Visible then
+ cancelSlide(areaSoak)
+ end
+ end)
+ areaSoak.MouseButton1Up:connect(function()
+ if areaSoak.Visible then
+ cancelSlide(areaSoak)
+ end
+ end)
+
+ slider.MouseButton1Down:connect(function()
+ areaSoak.Visible = true
+ if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
+ areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y)
+ setSliderPos(x,slider,sliderPosition,bar,10)
+ end)
+ end)
+
+ slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end)
+
+ sliderPosition.Changed:connect(function(prop)
+ sliderPosition.Value = math.min(10, math.max(1,sliderPosition.Value))
+ local relativePosX = (sliderPosition.Value - 1) / (10 - 1)
+ slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
+ end)
+
+ bar.MouseButton1Down:connect(function(x,y)
+ setSliderPos(x,slider,sliderPosition,bar,steps)
+ end)
+
+ return sliderGui, sliderPosition, sliderSteps
+
+end
+
+
+
+t.CreateSliderNew = function(steps,width,position)
+ local sliderGui = Instance.new("Frame")
+ sliderGui.Size = UDim2.new(1,0,1,0)
+ sliderGui.BackgroundTransparency = 1
+ sliderGui.Name = "SliderGui"
+
+ local sliderSteps = Instance.new("IntValue")
+ sliderSteps.Name = "SliderSteps"
+ sliderSteps.Value = steps
+ sliderSteps.Parent = sliderGui
+
+ local areaSoak = Instance.new("TextButton")
+ areaSoak.Name = "AreaSoak"
+ areaSoak.Text = ""
+ areaSoak.BackgroundTransparency = 1
+ areaSoak.Active = false
+ areaSoak.Size = UDim2.new(1,0,1,0)
+ areaSoak.Visible = false
+ areaSoak.ZIndex = 6
+
+ sliderGui.AncestryChanged:connect(function(child,parent)
+ if parent == nil then
+ areaSoak.Parent = nil
+ else
+ areaSoak.Parent = getScreenGuiAncestor(sliderGui)
+ end
+ end)
+
+ local sliderPosition = Instance.new("IntValue")
+ sliderPosition.Name = "SliderPosition"
+ sliderPosition.Value = 0
+ sliderPosition.Parent = sliderGui
+
+ local id = math.random(1,100)
+
+ local sliderBarImgHeight = 7
+ local sliderBarCapImgWidth = 4
+
+ local bar = Instance.new("ImageButton")
+ bar.BackgroundTransparency = 1
+ bar.Image = "rbxasset://textures/ui/Slider-BKG-Center.png"
+ bar.Name = "Bar"
+ local displayWidth = 200
+ if type(width) == "number" then
+ bar.Size = UDim2.new(0,width - (sliderBarCapImgWidth * 2),0,sliderBarImgHeight)
+ displayWidth = width - (sliderBarCapImgWidth * 2)
+ else
+ bar.Size = UDim2.new(0,200,0,sliderBarImgHeight)
+ end
+ bar.ZIndex = 3
+ bar.Parent = sliderGui
+ if position["X"] and position["X"]["Scale"] and position["X"]["Offset"] and position["Y"] and position["Y"]["Scale"] and position["Y"]["Offset"] then
+ bar.Position = position
+ end
+
+ local barLeft = bar:clone()
+ barLeft.Name = "BarLeft"
+ barLeft.Image = "rbxasset://textures/ui/Slider-BKG-Left-Cap.png"
+ barLeft.Size = UDim2.new(0, sliderBarCapImgWidth, 0, sliderBarImgHeight)
+ barLeft.Position = UDim2.new(position.X.Scale, position.X.Offset - sliderBarCapImgWidth, position.Y.Scale, position.Y.Offset)
+ barLeft.Parent = sliderGui
+ barLeft.ZIndex = 3
+
+ local barRight = barLeft:clone()
+ barRight.Name = "BarRight"
+ barRight.Image = "rbxasset://textures/ui/Slider-BKG-Right-Cap.png"
+ barRight.Position = UDim2.new(position.X.Scale, position.X.Offset + displayWidth, position.Y.Scale, position.Y.Offset)
+ barRight.Parent = sliderGui
+
+ local fillLeft = barLeft:clone()
+ fillLeft.Name = "FillLeft"
+ fillLeft.Image = "rbxasset://textures/ui/Slider-Fill-Left-Cap.png"
+ fillLeft.Parent = sliderGui
+ fillLeft.ZIndex = 4
+
+ local fill = fillLeft:clone()
+ fill.Name = "Fill"
+ fill.Image = "rbxasset://textures/ui/Slider-Fill-Center.png"
+ fill.Parent = bar
+ fill.ZIndex = 4
+ fill.Position = UDim2.new(0, 0, 0, 0)
+ fill.Size = UDim2.new(0.5, 0, 1, 0)
+
+
+-- bar.Visible = false
+
+ local slider = Instance.new("ImageButton")
+ slider.Name = "Slider"
+ slider.BackgroundTransparency = 1
+ slider.Image = "rbxasset://textures/ui/slider_new_tab.png"
+ slider.Position = UDim2.new(0,0,0.5,-14)
+ slider.Size = UDim2.new(0,28,0,28)
+ slider.ZIndex = 5
+ slider.Parent = bar
+
+ local areaSoakMouseMoveCon = nil
+
+ areaSoak.MouseLeave:connect(function()
+ if areaSoak.Visible then
+ cancelSlide(areaSoak)
+ end
+ end)
+ areaSoak.MouseButton1Up:connect(function()
+ if areaSoak.Visible then
+ cancelSlide(areaSoak)
+ end
+ end)
+
+ slider.MouseButton1Down:connect(function()
+ areaSoak.Visible = true
+ if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
+ areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y)
+ setSliderPos(x,slider,sliderPosition,bar,steps)
+ end)
+ end)
+
+ slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end)
+
+ sliderPosition.Changed:connect(function(prop)
+ sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value))
+ local relativePosX = (sliderPosition.Value - 1) / (steps - 1)
+ slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
+ fill.Size = UDim2.new(relativePosX, 0, 1, 0)
+ end)
+
+ bar.MouseButton1Down:connect(function(x,y)
+ setSliderPos(x,slider,sliderPosition,bar,steps)
+ end)
+
+ return sliderGui, sliderPosition, sliderSteps
+
+end
+
+
+
+
+
+t.CreateTrueScrollingFrame = function()
+ local lowY = nil
+ local highY = nil
+
+ local dragCon = nil
+ local upCon = nil
+
+ local internalChange = false
+
+ local descendantsChangeConMap = {}
+
+ local scrollingFrame = Instance.new("Frame")
+ scrollingFrame.Name = "ScrollingFrame"
+ scrollingFrame.Active = true
+ scrollingFrame.Size = UDim2.new(1,0,1,0)
+ scrollingFrame.ClipsDescendants = true
+
+ local controlFrame = Instance.new("Frame")
+ controlFrame.Name = "ControlFrame"
+ controlFrame.BackgroundTransparency = 1
+ controlFrame.Size = UDim2.new(0,18,1,0)
+ controlFrame.Position = UDim2.new(1,-20,0,0)
+ controlFrame.Parent = scrollingFrame
+
+ local scrollBottom = Instance.new("BoolValue")
+ scrollBottom.Value = false
+ scrollBottom.Name = "ScrollBottom"
+ scrollBottom.Parent = controlFrame
+
+ local scrollUp = Instance.new("BoolValue")
+ scrollUp.Value = false
+ scrollUp.Name = "scrollUp"
+ scrollUp.Parent = controlFrame
+
+ local scrollUpButton = Instance.new("TextButton")
+ scrollUpButton.Name = "ScrollUpButton"
+ scrollUpButton.Text = ""
+ scrollUpButton.AutoButtonColor = false
+ scrollUpButton.BackgroundColor3 = Color3.new(0,0,0)
+ scrollUpButton.BorderColor3 = Color3.new(1,1,1)
+ scrollUpButton.BackgroundTransparency = 0.5
+ scrollUpButton.Size = UDim2.new(0,18,0,18)
+ scrollUpButton.ZIndex = 2
+ scrollUpButton.Parent = controlFrame
+ for i = 1, 6 do
+ local triFrame = Instance.new("Frame")
+ triFrame.BorderColor3 = Color3.new(1,1,1)
+ triFrame.Name = "tri" .. tostring(i)
+ triFrame.ZIndex = 3
+ triFrame.BackgroundTransparency = 0.5
+ triFrame.Size = UDim2.new(0,12 - ((i -1) * 2),0,0)
+ triFrame.Position = UDim2.new(0,3 + (i -1),0.5,2 - (i -1))
+ triFrame.Parent = scrollUpButton
+ end
+ scrollUpButton.MouseEnter:connect(function()
+ scrollUpButton.BackgroundTransparency = 0.1
+ local upChildren = scrollUpButton:GetChildren()
+ for i = 1, #upChildren do
+ upChildren[i].BackgroundTransparency = 0.1
+ end
+ end)
+ scrollUpButton.MouseLeave:connect(function()
+ scrollUpButton.BackgroundTransparency = 0.5
+ local upChildren = scrollUpButton:GetChildren()
+ for i = 1, #upChildren do
+ upChildren[i].BackgroundTransparency = 0.5
+ end
+ end)
+
+ local scrollDownButton = scrollUpButton:clone()
+ scrollDownButton.Name = "ScrollDownButton"
+ scrollDownButton.Position = UDim2.new(0,0,1,-18)
+ local downChildren = scrollDownButton:GetChildren()
+ for i = 1, #downChildren do
+ downChildren[i].Position = UDim2.new(0,3 + (i -1),0.5,-2 + (i - 1))
+ end
+ scrollDownButton.MouseEnter:connect(function()
+ scrollDownButton.BackgroundTransparency = 0.1
+ local downChildren = scrollDownButton:GetChildren()
+ for i = 1, #downChildren do
+ downChildren[i].BackgroundTransparency = 0.1
+ end
+ end)
+ scrollDownButton.MouseLeave:connect(function()
+ scrollDownButton.BackgroundTransparency = 0.5
+ local downChildren = scrollDownButton:GetChildren()
+ for i = 1, #downChildren do
+ downChildren[i].BackgroundTransparency = 0.5
+ end
+ end)
+ scrollDownButton.Parent = controlFrame
+
+ local scrollTrack = Instance.new("Frame")
+ scrollTrack.Name = "ScrollTrack"
+ scrollTrack.BackgroundTransparency = 1
+ scrollTrack.Size = UDim2.new(0,18,1,-38)
+ scrollTrack.Position = UDim2.new(0,0,0,19)
+ scrollTrack.Parent = controlFrame
+
+ local scrollbar = Instance.new("TextButton")
+ scrollbar.BackgroundColor3 = Color3.new(0,0,0)
+ scrollbar.BorderColor3 = Color3.new(1,1,1)
+ scrollbar.BackgroundTransparency = 0.5
+ scrollbar.AutoButtonColor = false
+ scrollbar.Text = ""
+ scrollbar.Active = true
+ scrollbar.Name = "ScrollBar"
+ scrollbar.ZIndex = 2
+ scrollbar.BackgroundTransparency = 0.5
+ scrollbar.Size = UDim2.new(0, 18, 0.1, 0)
+ scrollbar.Position = UDim2.new(0,0,0,0)
+ scrollbar.Parent = scrollTrack
+
+ local scrollNub = Instance.new("Frame")
+ scrollNub.Name = "ScrollNub"
+ scrollNub.BorderColor3 = Color3.new(1,1,1)
+ scrollNub.Size = UDim2.new(0,10,0,0)
+ scrollNub.Position = UDim2.new(0.5,-5,0.5,0)
+ scrollNub.ZIndex = 2
+ scrollNub.BackgroundTransparency = 0.5
+ scrollNub.Parent = scrollbar
+
+ local newNub = scrollNub:clone()
+ newNub.Position = UDim2.new(0.5,-5,0.5,-2)
+ newNub.Parent = scrollbar
+
+ local lastNub = scrollNub:clone()
+ lastNub.Position = UDim2.new(0.5,-5,0.5,2)
+ lastNub.Parent = scrollbar
+
+ scrollbar.MouseEnter:connect(function()
+ scrollbar.BackgroundTransparency = 0.1
+ scrollNub.BackgroundTransparency = 0.1
+ newNub.BackgroundTransparency = 0.1
+ lastNub.BackgroundTransparency = 0.1
+ end)
+ scrollbar.MouseLeave:connect(function()
+ scrollbar.BackgroundTransparency = 0.5
+ scrollNub.BackgroundTransparency = 0.5
+ newNub.BackgroundTransparency = 0.5
+ lastNub.BackgroundTransparency = 0.5
+ end)
+
+ local mouseDrag = Instance.new("ImageButton")
+ mouseDrag.Active = false
+ mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0)
+ mouseDrag.AutoButtonColor = false
+ mouseDrag.BackgroundTransparency = 1
+ mouseDrag.Name = "mouseDrag"
+ mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0)
+ mouseDrag.ZIndex = 10
+
+ local function positionScrollBar(x,y,offset)
+ local oldPos = scrollbar.Position
+
+ if y < scrollTrack.AbsolutePosition.y then
+ scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0)
+ return (oldPos ~= scrollbar.Position)
+ end
+
+ local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y
+
+ if y > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then
+ scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0)
+ return (oldPos ~= scrollbar.Position)
+ end
+ local newScaleYPos = (y - scrollTrack.AbsolutePosition.y - offset)/scrollTrack.AbsoluteSize.y
+ if newScaleYPos + relativeSize > 1 then
+ newScaleYPos = 1 - relativeSize
+ scrollBottom.Value = true
+ scrollUp.Value = false
+ elseif newScaleYPos <= 0 then
+ newScaleYPos = 0
+ scrollUp.Value = true
+ scrollBottom.Value = false
+ else
+ scrollUp.Value = false
+ scrollBottom.Value = false
+ end
+ scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,newScaleYPos,0)
+
+ return (oldPos ~= scrollbar.Position)
+ end
+
+ local function drillDownSetHighLow(instance)
+ if not instance or not instance:IsA("GuiObject") then return end
+ if instance == controlFrame then return end
+ if instance:IsDescendantOf(controlFrame) then return end
+ if not instance.Visible then return end
+
+ if lowY and lowY > instance.AbsolutePosition.Y then
+ lowY = instance.AbsolutePosition.Y
+ elseif not lowY then
+ lowY = instance.AbsolutePosition.Y
+ end
+ if highY and highY < (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) then
+ highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
+ elseif not highY then
+ highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
+ end
+ local children = instance:GetChildren()
+ for i = 1, #children do
+ drillDownSetHighLow(children[i])
+ end
+ end
+
+ local function resetHighLow()
+ local firstChildren = scrollingFrame:GetChildren()
+
+ for i = 1, #firstChildren do
+ drillDownSetHighLow(firstChildren[i])
+ end
+ end
+
+ local function recalculate()
+ internalChange = true
+
+ local percentFrame = 0
+ if scrollbar.Position.Y.Scale > 0 then
+ if scrollbar.Visible then
+ percentFrame = scrollbar.Position.Y.Scale/((scrollTrack.AbsoluteSize.Y - scrollbar.AbsoluteSize.Y)/scrollTrack.AbsoluteSize.Y)
+ else
+ percentFrame = 0
+ end
+ end
+ if percentFrame > 0.99 then percentFrame = 1 end
+
+ local hiddenYAmount = (scrollingFrame.AbsoluteSize.Y - (highY - lowY)) * percentFrame
+
+ local guiChildren = scrollingFrame:GetChildren()
+ for i = 1, #guiChildren do
+ if guiChildren[i] ~= controlFrame then
+ guiChildren[i].Position = UDim2.new(guiChildren[i].Position.X.Scale,guiChildren[i].Position.X.Offset,
+ 0, math.ceil(guiChildren[i].AbsolutePosition.Y) - math.ceil(lowY) + hiddenYAmount)
+ end
+ end
+
+ lowY = nil
+ highY = nil
+ resetHighLow()
+ internalChange = false
+ end
+
+ local function setSliderSizeAndPosition()
+ if not highY or not lowY then return end
+
+ local totalYSpan = math.abs(highY - lowY)
+ if totalYSpan == 0 then
+ scrollbar.Visible = false
+ scrollDownButton.Visible = false
+ scrollUpButton.Visible = false
+
+ if dragCon then dragCon:disconnect() dragCon = nil end
+ if upCon then upCon:disconnect() upCon = nil end
+ return
+ end
+
+ local percentShown = scrollingFrame.AbsoluteSize.Y/totalYSpan
+ if percentShown >= 1 then
+ scrollbar.Visible = false
+ scrollDownButton.Visible = false
+ scrollUpButton.Visible = false
+ recalculate()
+ else
+ scrollbar.Visible = true
+ scrollDownButton.Visible = true
+ scrollUpButton.Visible = true
+
+ scrollbar.Size = UDim2.new(scrollbar.Size.X.Scale,scrollbar.Size.X.Offset,percentShown,0)
+ end
+
+ local percentPosition = (scrollingFrame.AbsolutePosition.Y - lowY)/totalYSpan
+ scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,percentPosition,-scrollbar.AbsoluteSize.X/2)
+
+ if scrollbar.AbsolutePosition.y < scrollTrack.AbsolutePosition.y then
+ scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0)
+ end
+
+ if (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.Y) > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then
+ local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y
+ scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0)
+ end
+ end
+
+ local buttonScrollAmountPixels = 7
+ local reentrancyGuardScrollUp = false
+ local function doScrollUp()
+ if reentrancyGuardScrollUp then return end
+
+ reentrancyGuardScrollUp = true
+ if positionScrollBar(0,scrollbar.AbsolutePosition.Y - buttonScrollAmountPixels,0) then
+ recalculate()
+ end
+ reentrancyGuardScrollUp = false
+ end
+
+ local reentrancyGuardScrollDown = false
+ local function doScrollDown()
+ if reentrancyGuardScrollDown then return end
+
+ reentrancyGuardScrollDown = true
+ if positionScrollBar(0,scrollbar.AbsolutePosition.Y + buttonScrollAmountPixels,0) then
+ recalculate()
+ end
+ reentrancyGuardScrollDown = false
+ end
+
+ local function scrollUp(mouseYPos)
+ if scrollUpButton.Active then
+ scrollStamp = tick()
+ local current = scrollStamp
+ local upCon
+ upCon = mouseDrag.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ mouseDrag.Parent = nil
+ upCon:disconnect()
+ end)
+ mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
+ doScrollUp()
+ wait(0.2)
+ local t = tick()
+ local w = 0.1
+ while scrollStamp == current do
+ doScrollUp()
+ if mouseYPos and mouseYPos > scrollbar.AbsolutePosition.y then
+ break
+ end
+ if not scrollUpButton.Active then break end
+ if tick()-t > 5 then
+ w = 0
+ elseif tick()-t > 2 then
+ w = 0.06
+ end
+ wait(w)
+ end
+ end
+ end
+
+ local function scrollDown(mouseYPos)
+ if scrollDownButton.Active then
+ scrollStamp = tick()
+ local current = scrollStamp
+ local downCon
+ downCon = mouseDrag.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ mouseDrag.Parent = nil
+ downCon:disconnect()
+ end)
+ mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
+ doScrollDown()
+ wait(0.2)
+ local t = tick()
+ local w = 0.1
+ while scrollStamp == current do
+ doScrollDown()
+ if mouseYPos and mouseYPos < (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.x) then
+ break
+ end
+ if not scrollDownButton.Active then break end
+ if tick()-t > 5 then
+ w = 0
+ elseif tick()-t > 2 then
+ w = 0.06
+ end
+ wait(w)
+ end
+ end
+ end
+
+ scrollbar.MouseButton1Down:connect(function(x,y)
+ if scrollbar.Active then
+ scrollStamp = tick()
+ local mouseOffset = y - scrollbar.AbsolutePosition.y
+ if dragCon then dragCon:disconnect() dragCon = nil end
+ if upCon then upCon:disconnect() upCon = nil end
+ local prevY = y
+ local reentrancyGuardMouseScroll = false
+ dragCon = mouseDrag.MouseMoved:connect(function(x,y)
+ if reentrancyGuardMouseScroll then return end
+
+ reentrancyGuardMouseScroll = true
+ if positionScrollBar(x,y,mouseOffset) then
+ recalculate()
+ end
+ reentrancyGuardMouseScroll = false
+
+ end)
+ upCon = mouseDrag.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ mouseDrag.Parent = nil
+ dragCon:disconnect(); dragCon = nil
+ upCon:disconnect(); drag = nil
+ end)
+ mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
+ end
+ end)
+
+ local scrollMouseCount = 0
+
+ scrollUpButton.MouseButton1Down:connect(function()
+ scrollUp()
+ end)
+ scrollUpButton.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ end)
+
+ scrollDownButton.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ end)
+ scrollDownButton.MouseButton1Down:connect(function()
+ scrollDown()
+ end)
+
+ scrollbar.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ end)
+
+ local function heightCheck(instance)
+ if highY and (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) > highY then
+ highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
+ elseif not highY then
+ highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
+ end
+ setSliderSizeAndPosition()
+ end
+
+ local function highLowRecheck()
+ local oldLowY = lowY
+ local oldHighY = highY
+ lowY = nil
+ highY = nil
+ resetHighLow()
+
+ if (lowY ~= oldLowY) or (highY ~= oldHighY) then
+ setSliderSizeAndPosition()
+ end
+ end
+
+ local function descendantChanged(this, prop)
+ if internalChange then return end
+ if not this.Visible then return end
+
+ if prop == "Size" or prop == "Position" then
+ wait()
+ highLowRecheck()
+ end
+ end
+
+ scrollingFrame.DescendantAdded:connect(function(instance)
+ if not instance:IsA("GuiObject") then return end
+
+ if instance.Visible then
+ wait() -- wait a heartbeat for sizes to reconfig
+ highLowRecheck()
+ end
+
+ descendantsChangeConMap[instance] = instance.Changed:connect(function(prop) descendantChanged(instance, prop) end)
+ end)
+
+ scrollingFrame.DescendantRemoving:connect(function(instance)
+ if not instance:IsA("GuiObject") then return end
+ if descendantsChangeConMap[instance] then
+ descendantsChangeConMap[instance]:disconnect()
+ descendantsChangeConMap[instance] = nil
+ end
+ wait() -- wait a heartbeat for sizes to reconfig
+ highLowRecheck()
+ end)
+
+ scrollingFrame.Changed:connect(function(prop)
+ if prop == "AbsoluteSize" then
+ if not highY or not lowY then return end
+
+ highLowRecheck()
+ setSliderSizeAndPosition()
+ end
+ end)
+
+ return scrollingFrame, controlFrame
+end
+
+t.CreateScrollingFrame = function(orderList,scrollStyle)
+ local frame = Instance.new("Frame")
+ frame.Name = "ScrollingFrame"
+ frame.BackgroundTransparency = 1
+ frame.Size = UDim2.new(1,0,1,0)
+
+ local scrollUpButton = Instance.new("ImageButton")
+ scrollUpButton.Name = "ScrollUpButton"
+ scrollUpButton.BackgroundTransparency = 1
+ scrollUpButton.Image = "rbxasset://textures/ui/scrollbuttonUp.png"
+ scrollUpButton.Size = UDim2.new(0,17,0,17)
+
+
+ local scrollDownButton = Instance.new("ImageButton")
+ scrollDownButton.Name = "ScrollDownButton"
+ scrollDownButton.BackgroundTransparency = 1
+ scrollDownButton.Image = "rbxasset://textures/ui/scrollbuttonDown.png"
+ scrollDownButton.Size = UDim2.new(0,17,0,17)
+
+ local scrollbar = Instance.new("ImageButton")
+ scrollbar.Name = "ScrollBar"
+ scrollbar.Image = "rbxasset://textures/ui/scrollbar.png"
+ scrollbar.BackgroundTransparency = 1
+ scrollbar.Size = UDim2.new(0, 18, 0, 150)
+
+ local scrollStamp = 0
+
+ local scrollDrag = Instance.new("ImageButton")
+ scrollDrag.Image = "http://www.roblox.com/asset/?id=61367186"
+ scrollDrag.Size = UDim2.new(1, 0, 0, 16)
+ scrollDrag.BackgroundTransparency = 1
+ scrollDrag.Name = "ScrollDrag"
+ scrollDrag.Active = true
+ scrollDrag.Parent = scrollbar
+
+ local mouseDrag = Instance.new("ImageButton")
+ mouseDrag.Active = false
+ mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0)
+ mouseDrag.AutoButtonColor = false
+ mouseDrag.BackgroundTransparency = 1
+ mouseDrag.Name = "mouseDrag"
+ mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0)
+ mouseDrag.ZIndex = 10
+
+ local style = "simple"
+ if scrollStyle and tostring(scrollStyle) then
+ style = scrollStyle
+ end
+
+ local scrollPosition = 1
+ local rowSize = 0
+ local howManyDisplayed = 0
+
+ local layoutGridScrollBar = function()
+ howManyDisplayed = 0
+ local guiObjects = {}
+ if orderList then
+ for i, child in ipairs(orderList) do
+ if child.Parent == frame then
+ table.insert(guiObjects, child)
+ end
+ end
+ else
+ local children = frame:GetChildren()
+ if children then
+ for i, child in ipairs(children) do
+ if child:IsA("GuiObject") then
+ table.insert(guiObjects, child)
+ end
+ end
+ end
+ end
+ if #guiObjects == 0 then
+ scrollUpButton.Active = false
+ scrollDownButton.Active = false
+ scrollDrag.Active = false
+ scrollPosition = 1
+ return
+ end
+
+ if scrollPosition > #guiObjects then
+ scrollPosition = #guiObjects
+ end
+
+ if scrollPosition < 1 then scrollPosition = 1 end
+
+ local totalPixelsY = frame.AbsoluteSize.Y
+ local pixelsRemainingY = frame.AbsoluteSize.Y
+
+ local totalPixelsX = frame.AbsoluteSize.X
+
+ local xCounter = 0
+ local rowSizeCounter = 0
+ local setRowSize = true
+
+ local pixelsBelowScrollbar = 0
+ local pos = #guiObjects
+
+ local currentRowY = 0
+
+ pos = scrollPosition
+ --count up from current scroll position to fill out grid
+ while pos <= #guiObjects and pixelsBelowScrollbar < totalPixelsY do
+ xCounter = xCounter + guiObjects[pos].AbsoluteSize.X
+ --previous pos was the end of a row
+ if xCounter >= totalPixelsX then
+ pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
+ currentRowY = 0
+ xCounter = guiObjects[pos].AbsoluteSize.X
+ end
+ if guiObjects[pos].AbsoluteSize.Y > currentRowY then
+ currentRowY = guiObjects[pos].AbsoluteSize.Y
+ end
+ pos = pos + 1
+ end
+ --Count wherever current row left off
+ pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
+ currentRowY = 0
+
+ pos = scrollPosition - 1
+ xCounter = 0
+
+ --objects with varying X,Y dimensions can rarely cause minor errors
+ --rechecking every new scrollPosition is necessary to avoid 100% of errors
+
+ --count backwards from current scrollPosition to see if we can add more rows
+ while pixelsBelowScrollbar + currentRowY < totalPixelsY and pos >= 1 do
+ xCounter = xCounter + guiObjects[pos].AbsoluteSize.X
+ rowSizeCounter = rowSizeCounter + 1
+ if xCounter >= totalPixelsX then
+ rowSize = rowSizeCounter - 1
+ rowSizeCounter = 0
+ xCounter = guiObjects[pos].AbsoluteSize.X
+ if pixelsBelowScrollbar + currentRowY <= totalPixelsY then
+ --It fits, so back up our scroll position
+ pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
+ if scrollPosition <= rowSize then
+ scrollPosition = 1
+ break
+ else
+ scrollPosition = scrollPosition - rowSize
+ end
+ currentRowY = 0
+ else
+ break
+ end
+ end
+
+ if guiObjects[pos].AbsoluteSize.Y > currentRowY then
+ currentRowY = guiObjects[pos].AbsoluteSize.Y
+ end
+
+ pos = pos - 1
+ end
+
+ --Do check last time if pos = 0
+ if (pos == 0) and (pixelsBelowScrollbar + currentRowY <= totalPixelsY) then
+ scrollPosition = 1
+ end
+
+ xCounter = 0
+ --pos = scrollPosition
+ rowSizeCounter = 0
+ setRowSize = true
+ local lastChildSize = 0
+
+ local xOffset,yOffset = 0
+ if guiObjects[1] then
+ yOffset = math.ceil(math.floor(math.fmod(totalPixelsY,guiObjects[1].AbsoluteSize.X))/2)
+ xOffset = math.ceil(math.floor(math.fmod(totalPixelsX,guiObjects[1].AbsoluteSize.Y))/2)
+ end
+
+ for i, child in ipairs(guiObjects) do
+ if i < scrollPosition then
+ --print("Hiding " .. child.Name)
+ child.Visible = false
+ else
+ if pixelsRemainingY < 0 then
+ --print("Out of Space " .. child.Name)
+ child.Visible = false
+ else
+ --print("Laying out " .. child.Name)
+ --GuiObject
+ if setRowSize then rowSizeCounter = rowSizeCounter + 1 end
+ if xCounter + child.AbsoluteSize.X >= totalPixelsX then
+ if setRowSize then
+ rowSize = rowSizeCounter - 1
+ setRowSize = false
+ end
+ xCounter = 0
+ pixelsRemainingY = pixelsRemainingY - child.AbsoluteSize.Y
+ end
+ child.Position = UDim2.new(child.Position.X.Scale,xCounter + xOffset, 0, totalPixelsY - pixelsRemainingY + yOffset)
+ xCounter = xCounter + child.AbsoluteSize.X
+ child.Visible = ((pixelsRemainingY - child.AbsoluteSize.Y) >= 0)
+ if child.Visible then
+ howManyDisplayed = howManyDisplayed + 1
+ end
+ lastChildSize = child.AbsoluteSize
+ end
+ end
+ end
+
+ scrollUpButton.Active = (scrollPosition > 1)
+ if lastChildSize == 0 then
+ scrollDownButton.Active = false
+ else
+ scrollDownButton.Active = ((pixelsRemainingY - lastChildSize.Y) < 0)
+ end
+ scrollDrag.Active = #guiObjects > howManyDisplayed
+ scrollDrag.Visible = scrollDrag.Active
+ end
+
+
+
+ local layoutSimpleScrollBar = function()
+ local guiObjects = {}
+ howManyDisplayed = 0
+
+ if orderList then
+ for i, child in ipairs(orderList) do
+ if child.Parent == frame then
+ table.insert(guiObjects, child)
+ end
+ end
+ else
+ local children = frame:GetChildren()
+ if children then
+ for i, child in ipairs(children) do
+ if child:IsA("GuiObject") then
+ table.insert(guiObjects, child)
+ end
+ end
+ end
+ end
+ if #guiObjects == 0 then
+ scrollUpButton.Active = false
+ scrollDownButton.Active = false
+ scrollDrag.Active = false
+ scrollPosition = 1
+ return
+ end
+
+ if scrollPosition > #guiObjects then
+ scrollPosition = #guiObjects
+ end
+
+ local totalPixels = frame.AbsoluteSize.Y
+ local pixelsRemaining = frame.AbsoluteSize.Y
+
+ local pixelsBelowScrollbar = 0
+ local pos = #guiObjects
+ while pixelsBelowScrollbar < totalPixels and pos >= 1 do
+ if pos >= scrollPosition then
+ pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y
+ else
+ if pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y <= totalPixels then
+ --It fits, so back up our scroll position
+ pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y
+ if scrollPosition <= 1 then
+ scrollPosition = 1
+ break
+ else
+ --local ("Backing up ScrollPosition from -- " ..scrollPosition)
+ scrollPosition = scrollPosition - 1
+ end
+ else
+ break
+ end
+ end
+ pos = pos - 1
+ end
+
+ pos = scrollPosition
+ for i, child in ipairs(guiObjects) do
+ if i < scrollPosition then
+ --print("Hiding " .. child.Name)
+ child.Visible = false
+ else
+ if pixelsRemaining < 0 then
+ --print("Out of Space " .. child.Name)
+ child.Visible = false
+ else
+ --print("Laying out " .. child.Name)
+ --GuiObject
+ child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
+ pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
+ if (pixelsRemaining >= 0) then
+ child.Visible = true
+ howManyDisplayed = howManyDisplayed + 1
+ else
+ child.Visible = false
+ end
+ end
+ end
+ end
+ scrollUpButton.Active = (scrollPosition > 1)
+ scrollDownButton.Active = (pixelsRemaining < 0)
+ scrollDrag.Active = #guiObjects > howManyDisplayed
+ scrollDrag.Visible = scrollDrag.Active
+ end
+
+
+ local moveDragger = function()
+ local guiObjects = 0
+ local children = frame:GetChildren()
+ if children then
+ for i, child in ipairs(children) do
+ if child:IsA("GuiObject") then
+ guiObjects = guiObjects + 1
+ end
+ end
+ end
+
+ if not scrollDrag.Parent then return end
+
+ local dragSizeY = scrollDrag.Parent.AbsoluteSize.y * (1/(guiObjects - howManyDisplayed + 1))
+ if dragSizeY < 16 then dragSizeY = 16 end
+ scrollDrag.Size = UDim2.new(scrollDrag.Size.X.Scale,scrollDrag.Size.X.Offset,scrollDrag.Size.Y.Scale,dragSizeY)
+
+ local relativeYPos = (scrollPosition - 1)/(guiObjects - (howManyDisplayed))
+ if relativeYPos > 1 then relativeYPos = 1
+ elseif relativeYPos < 0 then relativeYPos = 0 end
+ local absYPos = 0
+
+ if relativeYPos ~= 0 then
+ absYPos = (relativeYPos * scrollbar.AbsoluteSize.y) - (relativeYPos * scrollDrag.AbsoluteSize.y)
+ end
+
+ scrollDrag.Position = UDim2.new(scrollDrag.Position.X.Scale,scrollDrag.Position.X.Offset,scrollDrag.Position.Y.Scale,absYPos)
+ end
+
+ local reentrancyGuard = false
+ local recalculate = function()
+ if reentrancyGuard then
+ return
+ end
+ reentrancyGuard = true
+ wait()
+ local success, err = nil
+ if style == "grid" then
+ success, err = pcall(function() layoutGridScrollBar() end)
+ elseif style == "simple" then
+ success, err = pcall(function() layoutSimpleScrollBar() end)
+ end
+ if not success then print(err) end
+ moveDragger()
+ reentrancyGuard = false
+ end
+
+ local doScrollUp = function()
+ scrollPosition = (scrollPosition) - rowSize
+ if scrollPosition < 1 then scrollPosition = 1 end
+ recalculate(nil)
+ end
+
+ local doScrollDown = function()
+ scrollPosition = (scrollPosition) + rowSize
+ recalculate(nil)
+ end
+
+ local scrollUp = function(mouseYPos)
+ if scrollUpButton.Active then
+ scrollStamp = tick()
+ local current = scrollStamp
+ local upCon
+ upCon = mouseDrag.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ mouseDrag.Parent = nil
+ upCon:disconnect()
+ end)
+ mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
+ doScrollUp()
+ wait(0.2)
+ local t = tick()
+ local w = 0.1
+ while scrollStamp == current do
+ doScrollUp()
+ if mouseYPos and mouseYPos > scrollDrag.AbsolutePosition.y then
+ break
+ end
+ if not scrollUpButton.Active then break end
+ if tick()-t > 5 then
+ w = 0
+ elseif tick()-t > 2 then
+ w = 0.06
+ end
+ wait(w)
+ end
+ end
+ end
+
+ local scrollDown = function(mouseYPos)
+ if scrollDownButton.Active then
+ scrollStamp = tick()
+ local current = scrollStamp
+ local downCon
+ downCon = mouseDrag.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ mouseDrag.Parent = nil
+ downCon:disconnect()
+ end)
+ mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
+ doScrollDown()
+ wait(0.2)
+ local t = tick()
+ local w = 0.1
+ while scrollStamp == current do
+ doScrollDown()
+ if mouseYPos and mouseYPos < (scrollDrag.AbsolutePosition.y + scrollDrag.AbsoluteSize.x) then
+ break
+ end
+ if not scrollDownButton.Active then break end
+ if tick()-t > 5 then
+ w = 0
+ elseif tick()-t > 2 then
+ w = 0.06
+ end
+ wait(w)
+ end
+ end
+ end
+
+ local y = 0
+ scrollDrag.MouseButton1Down:connect(function(x,y)
+ if scrollDrag.Active then
+ scrollStamp = tick()
+ local mouseOffset = y - scrollDrag.AbsolutePosition.y
+ local dragCon
+ local upCon
+ dragCon = mouseDrag.MouseMoved:connect(function(x,y)
+ local barAbsPos = scrollbar.AbsolutePosition.y
+ local barAbsSize = scrollbar.AbsoluteSize.y
+
+ local dragAbsSize = scrollDrag.AbsoluteSize.y
+ local barAbsOne = barAbsPos + barAbsSize - dragAbsSize
+ y = y - mouseOffset
+ y = y < barAbsPos and barAbsPos or y > barAbsOne and barAbsOne or y
+ y = y - barAbsPos
+
+ local guiObjects = 0
+ local children = frame:GetChildren()
+ if children then
+ for i, child in ipairs(children) do
+ if child:IsA("GuiObject") then
+ guiObjects = guiObjects + 1
+ end
+ end
+ end
+
+ local doublePercent = y/(barAbsSize-dragAbsSize)
+ local rowDiff = rowSize
+ local totalScrollCount = guiObjects - (howManyDisplayed - 1)
+ local newScrollPosition = math.floor((doublePercent * totalScrollCount) + 0.5) + rowDiff
+ if newScrollPosition < scrollPosition then
+ rowDiff = -rowDiff
+ end
+
+ if newScrollPosition < 1 then
+ newScrollPosition = 1
+ end
+
+ scrollPosition = newScrollPosition
+ recalculate(nil)
+ end)
+ upCon = mouseDrag.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ mouseDrag.Parent = nil
+ dragCon:disconnect(); dragCon = nil
+ upCon:disconnect(); drag = nil
+ end)
+ mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
+ end
+ end)
+
+ local scrollMouseCount = 0
+
+ scrollUpButton.MouseButton1Down:connect(
+ function()
+ scrollUp()
+ end)
+ scrollUpButton.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ end)
+
+
+ scrollDownButton.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ end)
+ scrollDownButton.MouseButton1Down:connect(
+ function()
+ scrollDown()
+ end)
+
+ scrollbar.MouseButton1Up:connect(function()
+ scrollStamp = tick()
+ end)
+ scrollbar.MouseButton1Down:connect(
+ function(x,y)
+ if y > (scrollDrag.AbsoluteSize.y + scrollDrag.AbsolutePosition.y) then
+ scrollDown(y)
+ elseif y < (scrollDrag.AbsolutePosition.y) then
+ scrollUp(y)
+ end
+ end)
+
+
+ frame.ChildAdded:connect(function()
+ recalculate(nil)
+ end)
+
+ frame.ChildRemoved:connect(function()
+ recalculate(nil)
+ end)
+
+ frame.Changed:connect(
+ function(prop)
+ if prop == "AbsoluteSize" then
+ --Wait a heartbeat for it to sync in
+ recalculate(nil)
+ end
+ end)
+ frame.AncestryChanged:connect(function() recalculate(nil) end)
+
+ return frame, scrollUpButton, scrollDownButton, recalculate, scrollbar
+end
+local function binaryGrow(min, max, fits)
+ if min > max then
+ return min
+ end
+ local biggestLegal = min
+
+ while min <= max do
+ local mid = min + math.floor((max - min) / 2)
+ if fits(mid) and (biggestLegal == nil or biggestLegal < mid) then
+ biggestLegal = mid
+
+ --Try growing
+ min = mid + 1
+ else
+ --Doesn't fit, shrink
+ max = mid - 1
+ end
+ end
+ return biggestLegal
+end
+
+
+local function binaryShrink(min, max, fits)
+ if min > max then
+ return min
+ end
+ local smallestLegal = max
+
+ while min <= max do
+ local mid = min + math.floor((max - min) / 2)
+ if fits(mid) and (smallestLegal == nil or smallestLegal > mid) then
+ smallestLegal = mid
+
+ --It fits, shrink
+ max = mid - 1
+ else
+ --Doesn't fit, grow
+ min = mid + 1
+ end
+ end
+ return smallestLegal
+end
+
+
+local function getGuiOwner(instance)
+ while instance ~= nil do
+ if instance:IsA("ScreenGui") or instance:IsA("BillboardGui") then
+ return instance
+ end
+ instance = instance.Parent
+ end
+ return nil
+end
+
+t.AutoTruncateTextObject = function(textLabel)
+ local text = textLabel.Text
+
+ local fullLabel = textLabel:Clone()
+ fullLabel.Name = "Full" .. textLabel.Name
+ fullLabel.BorderSizePixel = 0
+ fullLabel.BackgroundTransparency = 0
+ fullLabel.Text = text
+ fullLabel.TextXAlignment = Enum.TextXAlignment.Center
+ fullLabel.Position = UDim2.new(0,-3,0,0)
+ fullLabel.Size = UDim2.new(0,100,1,0)
+ fullLabel.Visible = false
+ fullLabel.Parent = textLabel
+
+ local shortText = nil
+ local mouseEnterConnection = nil
+ local mouseLeaveConnection= nil
+
+ local checkForResize = function()
+ if getGuiOwner(textLabel) == nil then
+ return
+ end
+ textLabel.Text = text
+ if textLabel.TextFits then
+ --Tear down the rollover if it is active
+ if mouseEnterConnection then
+ mouseEnterConnection:disconnect()
+ mouseEnterConnection = nil
+ end
+ if mouseLeaveConnection then
+ mouseLeaveConnection:disconnect()
+ mouseLeaveConnection = nil
+ end
+ else
+ local len = string.len(text)
+ textLabel.Text = text .. "~"
+
+ --Shrink the text
+ local textSize = binaryGrow(0, len,
+ function(pos)
+ if pos == 0 then
+ textLabel.Text = "~"
+ else
+ textLabel.Text = string.sub(text, 1, pos) .. "~"
+ end
+ return textLabel.TextFits
+ end)
+ shortText = string.sub(text, 1, textSize) .. "~"
+ textLabel.Text = shortText
+
+ --Make sure the fullLabel fits
+ if not fullLabel.TextFits then
+ --Already too small, grow it really bit to start
+ fullLabel.Size = UDim2.new(0, 10000, 1, 0)
+ end
+
+ --Okay, now try to binary shrink it back down
+ local fullLabelSize = binaryShrink(textLabel.AbsoluteSize.X,fullLabel.AbsoluteSize.X,
+ function(size)
+ fullLabel.Size = UDim2.new(0, size, 1, 0)
+ return fullLabel.TextFits
+ end)
+ fullLabel.Size = UDim2.new(0,fullLabelSize+6,1,0)
+
+ --Now setup the rollover effects, if they are currently off
+ if mouseEnterConnection == nil then
+ mouseEnterConnection = textLabel.MouseEnter:connect(
+ function()
+ fullLabel.ZIndex = textLabel.ZIndex + 1
+ fullLabel.Visible = true
+ --textLabel.Text = ""
+ end)
+ end
+ if mouseLeaveConnection == nil then
+ mouseLeaveConnection = textLabel.MouseLeave:connect(
+ function()
+ fullLabel.Visible = false
+ --textLabel.Text = shortText
+ end)
+ end
+ end
+ end
+ textLabel.AncestryChanged:connect(checkForResize)
+ textLabel.Changed:connect(
+ function(prop)
+ if prop == "AbsoluteSize" then
+ checkForResize()
+ end
+ end)
+
+ checkForResize()
+
+ local function changeText(newText)
+ text = newText
+ fullLabel.Text = text
+ checkForResize()
+ end
+
+ return textLabel, changeText
+end
+
+local function TransitionTutorialPages(fromPage, toPage, transitionFrame, currentPageValue)
+ if fromPage then
+ fromPage.Visible = false
+ if transitionFrame.Visible == false then
+ transitionFrame.Size = fromPage.Size
+ transitionFrame.Position = fromPage.Position
+ end
+ else
+ if transitionFrame.Visible == false then
+ transitionFrame.Size = UDim2.new(0.0,50,0.0,50)
+ transitionFrame.Position = UDim2.new(0.5,-25,0.5,-25)
+ end
+ end
+ transitionFrame.Visible = true
+ currentPageValue.Value = nil
+
+ local newsize, newPosition
+ if toPage then
+ --Make it visible so it resizes
+ toPage.Visible = true
+
+ newSize = toPage.Size
+ newPosition = toPage.Position
+
+ toPage.Visible = false
+ else
+ newSize = UDim2.new(0.0,50,0.0,50)
+ newPosition = UDim2.new(0.5,-25,0.5,-25)
+ end
+ transitionFrame:TweenSizeAndPosition(newSize, newPosition, Enum.EasingDirection.InOut, Enum.EasingStyle.Quad, 0.3, true,
+ function(state)
+ if state == Enum.TweenStatus.Completed then
+ transitionFrame.Visible = false
+ if toPage then
+ toPage.Visible = true
+ currentPageValue.Value = toPage
+ end
+ end
+ end)
+end
+
+t.CreateTutorial = function(name, tutorialKey, createButtons)
+ local frame = Instance.new("Frame")
+ frame.Name = "Tutorial-" .. name
+ frame.BackgroundTransparency = 1
+ frame.Size = UDim2.new(0.6, 0, 0.6, 0)
+ frame.Position = UDim2.new(0.2, 0, 0.2, 0)
+
+ local transitionFrame = Instance.new("Frame")
+ transitionFrame.Name = "TransitionFrame"
+ transitionFrame.Style = Enum.FrameStyle.RobloxRound
+ transitionFrame.Size = UDim2.new(0.6, 0, 0.6, 0)
+ transitionFrame.Position = UDim2.new(0.2, 0, 0.2, 0)
+ transitionFrame.Visible = false
+ transitionFrame.Parent = frame
+
+ local currentPageValue = Instance.new("ObjectValue")
+ currentPageValue.Name = "CurrentTutorialPage"
+ currentPageValue.Value = nil
+ currentPageValue.Parent = frame
+
+ local boolValue = Instance.new("BoolValue")
+ boolValue.Name = "Buttons"
+ boolValue.Value = createButtons
+ boolValue.Parent = frame
+
+ local pages = Instance.new("Frame")
+ pages.Name = "Pages"
+ pages.BackgroundTransparency = 1
+ pages.Size = UDim2.new(1,0,1,0)
+ pages.Parent = frame
+
+ local function getVisiblePageAndHideOthers()
+ local visiblePage = nil
+ local children = pages:GetChildren()
+ if children then
+ for i,child in ipairs(children) do
+ if child.Visible then
+ if visiblePage then
+ child.Visible = false
+ else
+ visiblePage = child
+ end
+ end
+ end
+ end
+ return visiblePage
+ end
+
+ local showTutorial = function(alwaysShow)
+ if alwaysShow or UserSettings().GameSettings:GetTutorialState(tutorialKey) == false then
+ print("Showing tutorial-",tutorialKey)
+ local currentTutorialPage = getVisiblePageAndHideOthers()
+
+ local firstPage = pages:FindFirstChild("TutorialPage1")
+ if firstPage then
+ TransitionTutorialPages(currentTutorialPage, firstPage, transitionFrame, currentPageValue)
+ else
+ error("Could not find TutorialPage1")
+ end
+ end
+ end
+
+ local dismissTutorial = function()
+ local currentTutorialPage = getVisiblePageAndHideOthers()
+
+ if currentTutorialPage then
+ TransitionTutorialPages(currentTutorialPage, nil, transitionFrame, currentPageValue)
+ end
+
+ UserSettings().GameSettings:SetTutorialState(tutorialKey, true)
+ end
+
+ local gotoPage = function(pageNum)
+ local page = pages:FindFirstChild("TutorialPage" .. pageNum)
+ local currentTutorialPage = getVisiblePageAndHideOthers()
+ TransitionTutorialPages(currentTutorialPage, page, transitionFrame, currentPageValue)
+ end
+
+ return frame, showTutorial, dismissTutorial, gotoPage
+end
+
+local function CreateBasicTutorialPage(name, handleResize, skipTutorial, giveDoneButton)
+ local frame = Instance.new("Frame")
+ frame.Name = "TutorialPage"
+ frame.Style = Enum.FrameStyle.RobloxRound
+ frame.Size = UDim2.new(0.6, 0, 0.6, 0)
+ frame.Position = UDim2.new(0.2, 0, 0.2, 0)
+ frame.Visible = false
+
+ local frameHeader = Instance.new("TextLabel")
+ frameHeader.Name = "Header"
+ frameHeader.Text = name
+ frameHeader.BackgroundTransparency = 1
+ frameHeader.FontSize = Enum.FontSize.Size24
+ frameHeader.Font = Enum.Font.ArialBold
+ frameHeader.TextColor3 = Color3.new(1,1,1)
+ frameHeader.TextXAlignment = Enum.TextXAlignment.Center
+ frameHeader.TextWrap = true
+ frameHeader.Size = UDim2.new(1,-55, 0, 22)
+ frameHeader.Position = UDim2.new(0,0,0,0)
+ frameHeader.Parent = frame
+
+ local skipButton = Instance.new("ImageButton")
+ skipButton.Name = "SkipButton"
+ skipButton.AutoButtonColor = false
+ skipButton.BackgroundTransparency = 1
+ skipButton.Image = "rbxasset://textures/ui/closeButton.png"
+ skipButton.MouseButton1Click:connect(function()
+ skipTutorial()
+ end)
+ skipButton.MouseEnter:connect(function()
+ skipButton.Image = "rbxasset://textures/ui/closeButton_dn.png"
+ end)
+ skipButton.MouseLeave:connect(function()
+ skipButton.Image = "rbxasset://textures/ui/closeButton.png"
+ end)
+ skipButton.Size = UDim2.new(0, 25, 0, 25)
+ skipButton.Position = UDim2.new(1, -25, 0, 0)
+ skipButton.Parent = frame
+
+
+ if giveDoneButton then
+ local doneButton = Instance.new("TextButton")
+ doneButton.Name = "DoneButton"
+ doneButton.Style = Enum.ButtonStyle.RobloxButtonDefault
+ doneButton.Text = "Done"
+ doneButton.TextColor3 = Color3.new(1,1,1)
+ doneButton.Font = Enum.Font.ArialBold
+ doneButton.FontSize = Enum.FontSize.Size18
+ doneButton.Size = UDim2.new(0,100,0,50)
+ doneButton.Position = UDim2.new(0.5,-50,1,-50)
+
+ if skipTutorial then
+ doneButton.MouseButton1Click:connect(function() skipTutorial() end)
+ end
+
+ doneButton.Parent = frame
+ end
+
+ local innerFrame = Instance.new("Frame")
+ innerFrame.Name = "ContentFrame"
+ innerFrame.BackgroundTransparency = 1
+ innerFrame.Position = UDim2.new(0,0,0,25)
+ innerFrame.Parent = frame
+
+ local nextButton = Instance.new("TextButton")
+ nextButton.Name = "NextButton"
+ nextButton.Text = "Next"
+ nextButton.TextColor3 = Color3.new(1,1,1)
+ nextButton.Font = Enum.Font.Arial
+ nextButton.FontSize = Enum.FontSize.Size18
+ nextButton.Style = Enum.ButtonStyle.RobloxButtonDefault
+ nextButton.Size = UDim2.new(0,80, 0, 32)
+ nextButton.Position = UDim2.new(0.5, 5, 1, -32)
+ nextButton.Active = false
+ nextButton.Visible = false
+ nextButton.Parent = frame
+
+ local prevButton = Instance.new("TextButton")
+ prevButton.Name = "PrevButton"
+ prevButton.Text = "Previous"
+ prevButton.TextColor3 = Color3.new(1,1,1)
+ prevButton.Font = Enum.Font.Arial
+ prevButton.FontSize = Enum.FontSize.Size18
+ prevButton.Style = Enum.ButtonStyle.RobloxButton
+ prevButton.Size = UDim2.new(0,80, 0, 32)
+ prevButton.Position = UDim2.new(0.5, -85, 1, -32)
+ prevButton.Active = false
+ prevButton.Visible = false
+ prevButton.Parent = frame
+
+ if giveDoneButton then
+ innerFrame.Size = UDim2.new(1,0,1,-75)
+ else
+ innerFrame.Size = UDim2.new(1,0,1,-22)
+ end
+
+ local parentConnection = nil
+
+ local function basicHandleResize()
+ if frame.Visible and frame.Parent then
+ local maxSize = math.min(frame.Parent.AbsoluteSize.X, frame.Parent.AbsoluteSize.Y)
+ handleResize(200,maxSize)
+ end
+ end
+
+ frame.Changed:connect(
+ function(prop)
+ if prop == "Parent" then
+ if parentConnection ~= nil then
+ parentConnection:disconnect()
+ parentConnection = nil
+ end
+ if frame.Parent and frame.Parent:IsA("GuiObject") then
+ parentConnection = frame.Parent.Changed:connect(
+ function(parentProp)
+ if parentProp == "AbsoluteSize" then
+ wait()
+ basicHandleResize()
+ end
+ end)
+ basicHandleResize()
+ end
+ end
+
+ if prop == "Visible" then
+ basicHandleResize()
+ end
+ end)
+
+ return frame, innerFrame
+end
+
+t.CreateTextTutorialPage = function(name, text, skipTutorialFunc)
+ local frame = nil
+ local contentFrame = nil
+
+ local textLabel = Instance.new("TextLabel")
+ textLabel.BackgroundTransparency = 1
+ textLabel.TextColor3 = Color3.new(1,1,1)
+ textLabel.Text = text
+ textLabel.TextWrap = true
+ textLabel.TextXAlignment = Enum.TextXAlignment.Left
+ textLabel.TextYAlignment = Enum.TextYAlignment.Center
+ textLabel.Font = Enum.Font.Arial
+ textLabel.FontSize = Enum.FontSize.Size14
+ textLabel.Size = UDim2.new(1,0,1,0)
+
+ local function handleResize(minSize, maxSize)
+ size = binaryShrink(minSize, maxSize,
+ function(size)
+ frame.Size = UDim2.new(0, size, 0, size)
+ return textLabel.TextFits
+ end)
+ frame.Size = UDim2.new(0, size, 0, size)
+ frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2)
+ end
+
+ frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc)
+ textLabel.Parent = contentFrame
+
+ return frame
+end
+
+t.CreateImageTutorialPage = function(name, imageAsset, x, y, skipTutorialFunc, giveDoneButton)
+ local frame = nil
+ local contentFrame = nil
+
+ local imageLabel = Instance.new("ImageLabel")
+ imageLabel.BackgroundTransparency = 1
+ imageLabel.Image = imageAsset
+ imageLabel.Size = UDim2.new(0,x,0,y)
+ imageLabel.Position = UDim2.new(0.5,-x/2,0.5,-y/2)
+
+ local function handleResize(minSize, maxSize)
+ size = binaryShrink(minSize, maxSize,
+ function(size)
+ return size >= x and size >= y
+ end)
+ if size >= x and size >= y then
+ imageLabel.Size = UDim2.new(0,x, 0,y)
+ imageLabel.Position = UDim2.new(0.5,-x/2, 0.5, -y/2)
+ else
+ if x > y then
+ --X is limiter, so
+ imageLabel.Size = UDim2.new(1,0,y/x,0)
+ imageLabel.Position = UDim2.new(0,0, 0.5 - (y/x)/2, 0)
+ else
+ --Y is limiter
+ imageLabel.Size = UDim2.new(x/y,0,1, 0)
+ imageLabel.Position = UDim2.new(0.5-(x/y)/2, 0, 0, 0)
+ end
+ end
+ size = size + 50
+ frame.Size = UDim2.new(0, size, 0, size)
+ frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2)
+ end
+
+ frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc, giveDoneButton)
+ imageLabel.Parent = contentFrame
+
+ return frame
+end
+
+t.AddTutorialPage = function(tutorial, tutorialPage)
+ local transitionFrame = tutorial.TransitionFrame
+ local currentPageValue = tutorial.CurrentTutorialPage
+
+ if not tutorial.Buttons.Value then
+ tutorialPage.NextButton.Parent = nil
+ tutorialPage.PrevButton.Parent = nil
+ end
+
+ local children = tutorial.Pages:GetChildren()
+ if children and #children > 0 then
+ tutorialPage.Name = "TutorialPage" .. (#children+1)
+ local previousPage = children[#children]
+ if not previousPage:IsA("GuiObject") then
+ error("All elements under Pages must be GuiObjects")
+ end
+
+ if tutorial.Buttons.Value then
+ if previousPage.NextButton.Active then
+ error("NextButton already Active on previousPage, please only add pages with RbxGui.AddTutorialPage function")
+ end
+ previousPage.NextButton.MouseButton1Click:connect(
+ function()
+ TransitionTutorialPages(previousPage, tutorialPage, transitionFrame, currentPageValue)
+ end)
+ previousPage.NextButton.Active = true
+ previousPage.NextButton.Visible = true
+
+ if tutorialPage.PrevButton.Active then
+ error("PrevButton already Active on tutorialPage, please only add pages with RbxGui.AddTutorialPage function")
+ end
+ tutorialPage.PrevButton.MouseButton1Click:connect(
+ function()
+ TransitionTutorialPages(tutorialPage, previousPage, transitionFrame, currentPageValue)
+ end)
+ tutorialPage.PrevButton.Active = true
+ tutorialPage.PrevButton.Visible = true
+ end
+
+ tutorialPage.Parent = tutorial.Pages
+ else
+ --First child
+ tutorialPage.Name = "TutorialPage1"
+ tutorialPage.Parent = tutorial.Pages
+ end
+end
+
+t.CreateSetPanel = function(userIdsForSets, objectSelected, dialogClosed, size, position, showAdminCategories, useAssetVersionId)
+
+ if not userIdsForSets then
+ error("CreateSetPanel: userIdsForSets (first arg) is nil, should be a table of number ids")
+ end
+ if type(userIdsForSets) ~= "table" and type(userIdsForSets) ~= "userdata" then
+ error("CreateSetPanel: userIdsForSets (first arg) is of type " ..type(userIdsForSets) .. ", should be of type table or userdata")
+ end
+ if not objectSelected then
+ error("CreateSetPanel: objectSelected (second arg) is nil, should be a callback function!")
+ end
+ if type(objectSelected) ~= "function" then
+ error("CreateSetPanel: objectSelected (second arg) is of type " .. type(objectSelected) .. ", should be of type function!")
+ end
+ if dialogClosed and type(dialogClosed) ~= "function" then
+ error("CreateSetPanel: dialogClosed (third arg) is of type " .. type(dialogClosed) .. ", should be of type function!")
+ end
+
+ if showAdminCategories == nil then -- by default, don't show beta sets
+ showAdminCategories = false
+ end
+
+ local arrayPosition = 1
+ local insertButtons = {}
+ local insertButtonCons = {}
+ local contents = nil
+ local setGui = nil
+
+ -- used for water selections
+ local waterForceDirection = "NegX"
+ local waterForce = "None"
+ local waterGui, waterTypeChangedEvent = nil
+
+ local Data = {}
+ Data.CurrentCategory = nil
+ Data.Category = {}
+ local SetCache = {}
+
+ local userCategoryButtons = nil
+
+ local buttonWidth = 64
+ local buttonHeight = buttonWidth
+
+ local SmallThumbnailUrl = nil
+ local LargeThumbnailUrl = nil
+ local BaseUrl = game:GetService("ContentProvider").BaseUrl:lower()
+
+ if useAssetVersionId then
+ LargeThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&assetversionid="
+ SmallThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&assetversionid="
+ else
+ LargeThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&aid="
+ SmallThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&aid="
+ end
+
+ local function drillDownSetZIndex(parent, index)
+ local children = parent:GetChildren()
+ for i = 1, #children do
+ if children[i]:IsA("GuiObject") then
+ children[i].ZIndex = index
+ end
+ drillDownSetZIndex(children[i], index)
+ end
+ end
+
+ -- for terrain stamping
+ local currTerrainDropDownFrame = nil
+ local terrainShapes = {"Block","Vertical Ramp","Corner Wedge","Inverse Corner Wedge","Horizontal Ramp","Auto-Wedge"}
+ local terrainShapeMap = {}
+ for i = 1, #terrainShapes do
+ terrainShapeMap[terrainShapes[i]] = i - 1
+ end
+ terrainShapeMap[terrainShapes[#terrainShapes]] = 6
+
+ local function createWaterGui()
+ local waterForceDirections = {"NegX","X","NegY","Y","NegZ","Z"}
+ local waterForces = {"None", "Small", "Medium", "Strong", "Max"}
+
+ local waterFrame = Instance.new("Frame")
+ waterFrame.Name = "WaterFrame"
+ waterFrame.Style = Enum.FrameStyle.RobloxSquare
+ waterFrame.Size = UDim2.new(0,150,0,110)
+ waterFrame.Visible = false
+
+ local waterForceLabel = Instance.new("TextLabel")
+ waterForceLabel.Name = "WaterForceLabel"
+ waterForceLabel.BackgroundTransparency = 1
+ waterForceLabel.Size = UDim2.new(1,0,0,12)
+ waterForceLabel.Font = Enum.Font.ArialBold
+ waterForceLabel.FontSize = Enum.FontSize.Size12
+ waterForceLabel.TextColor3 = Color3.new(1,1,1)
+ waterForceLabel.TextXAlignment = Enum.TextXAlignment.Left
+ waterForceLabel.Text = "Water Force"
+ waterForceLabel.Parent = waterFrame
+
+ local waterForceDirLabel = waterForceLabel:Clone()
+ waterForceDirLabel.Name = "WaterForceDirectionLabel"
+ waterForceDirLabel.Text = "Water Force Direction"
+ waterForceDirLabel.Position = UDim2.new(0,0,0,50)
+ waterForceDirLabel.Parent = waterFrame
+
+ local waterTypeChangedEvent = Instance.new("BindableEvent",waterFrame)
+ waterTypeChangedEvent.Name = "WaterTypeChangedEvent"
+
+ local waterForceDirectionSelectedFunc = function(newForceDirection)
+ waterForceDirection = newForceDirection
+ waterTypeChangedEvent:Fire({waterForce, waterForceDirection})
+ end
+ local waterForceSelectedFunc = function(newForce)
+ waterForce = newForce
+ waterTypeChangedEvent:Fire({waterForce, waterForceDirection})
+ end
+
+ local waterForceDirectionDropDown, forceWaterDirectionSelection = t.CreateDropDownMenu(waterForceDirections, waterForceDirectionSelectedFunc)
+ waterForceDirectionDropDown.Size = UDim2.new(1,0,0,25)
+ waterForceDirectionDropDown.Position = UDim2.new(0,0,1,3)
+ forceWaterDirectionSelection("NegX")
+ waterForceDirectionDropDown.Parent = waterForceDirLabel
+
+ local waterForceDropDown, forceWaterForceSelection = t.CreateDropDownMenu(waterForces, waterForceSelectedFunc)
+ forceWaterForceSelection("None")
+ waterForceDropDown.Size = UDim2.new(1,0,0,25)
+ waterForceDropDown.Position = UDim2.new(0,0,1,3)
+ waterForceDropDown.Parent = waterForceLabel
+
+ return waterFrame, waterTypeChangedEvent
+ end
+
+ -- Helper Function that contructs gui elements
+ local function createSetGui()
+
+ local setGui = Instance.new("ScreenGui")
+ setGui.Name = "SetGui"
+
+ local setPanel = Instance.new("Frame")
+ setPanel.Name = "SetPanel"
+ setPanel.Active = true
+ setPanel.BackgroundTransparency = 1
+ if position then
+ setPanel.Position = position
+ else
+ setPanel.Position = UDim2.new(0.2, 29, 0.1, 24)
+ end
+ if size then
+ setPanel.Size = size
+ else
+ setPanel.Size = UDim2.new(0.6, -58, 0.64, 0)
+ end
+ setPanel.Style = Enum.FrameStyle.RobloxRound
+ setPanel.ZIndex = 6
+ setPanel.Parent = setGui
+
+ -- Children of SetPanel
+ local itemPreview = Instance.new("Frame")
+ itemPreview.Name = "ItemPreview"
+ itemPreview.BackgroundTransparency = 1
+ itemPreview.Position = UDim2.new(0.8,5,0.085,0)
+ itemPreview.Size = UDim2.new(0.21,0,0.9,0)
+ itemPreview.ZIndex = 6
+ itemPreview.Parent = setPanel
+
+ -- Children of ItemPreview
+ local textPanel = Instance.new("Frame")
+ textPanel.Name = "TextPanel"
+ textPanel.BackgroundTransparency = 1
+ textPanel.Position = UDim2.new(0,0,0.45,0)
+ textPanel.Size = UDim2.new(1,0,0.55,0)
+ textPanel.ZIndex = 6
+ textPanel.Parent = itemPreview
+
+ -- Children of TextPanel
+ local rolloverText = Instance.new("TextLabel")
+ rolloverText.Name = "RolloverText"
+ rolloverText.BackgroundTransparency = 1
+ rolloverText.Size = UDim2.new(1,0,0,48)
+ rolloverText.ZIndex = 6
+ rolloverText.Font = Enum.Font.ArialBold
+ rolloverText.FontSize = Enum.FontSize.Size24
+ rolloverText.Text = ""
+ rolloverText.TextColor3 = Color3.new(1,1,1)
+ rolloverText.TextWrap = true
+ rolloverText.TextXAlignment = Enum.TextXAlignment.Left
+ rolloverText.TextYAlignment = Enum.TextYAlignment.Top
+ rolloverText.Parent = textPanel
+
+ local largePreview = Instance.new("ImageLabel")
+ largePreview.Name = "LargePreview"
+ largePreview.BackgroundTransparency = 1
+ largePreview.Image = ""
+ largePreview.Size = UDim2.new(1,0,0,170)
+ largePreview.ZIndex = 6
+ largePreview.Parent = itemPreview
+
+ local sets = Instance.new("Frame")
+ sets.Name = "Sets"
+ sets.BackgroundTransparency = 1
+ sets.Position = UDim2.new(0,0,0,5)
+ sets.Size = UDim2.new(0.23,0,1,-5)
+ sets.ZIndex = 6
+ sets.Parent = setPanel
+
+ -- Children of Sets
+ local line = Instance.new("Frame")
+ line.Name = "Line"
+ line.BackgroundColor3 = Color3.new(1,1,1)
+ line.BackgroundTransparency = 0.7
+ line.BorderSizePixel = 0
+ line.Position = UDim2.new(1,-3,0.06,0)
+ line.Size = UDim2.new(0,3,0.9,0)
+ line.ZIndex = 6
+ line.Parent = sets
+
+ local setsLists, controlFrame = t.CreateTrueScrollingFrame()
+ setsLists.Size = UDim2.new(1,-6,0.94,0)
+ setsLists.Position = UDim2.new(0,0,0.06,0)
+ setsLists.BackgroundTransparency = 1
+ setsLists.Name = "SetsLists"
+ setsLists.ZIndex = 6
+ setsLists.Parent = sets
+ drillDownSetZIndex(controlFrame, 7)
+
+ local setsHeader = Instance.new("TextLabel")
+ setsHeader.Name = "SetsHeader"
+ setsHeader.BackgroundTransparency = 1
+ setsHeader.Size = UDim2.new(0,47,0,24)
+ setsHeader.ZIndex = 6
+ setsHeader.Font = Enum.Font.ArialBold
+ setsHeader.FontSize = Enum.FontSize.Size24
+ setsHeader.Text = "Sets"
+ setsHeader.TextColor3 = Color3.new(1,1,1)
+ setsHeader.TextXAlignment = Enum.TextXAlignment.Left
+ setsHeader.TextYAlignment = Enum.TextYAlignment.Top
+ setsHeader.Parent = sets
+
+ local cancelButton = Instance.new("TextButton")
+ cancelButton.Name = "CancelButton"
+ cancelButton.Position = UDim2.new(1,-32,0,-2)
+ cancelButton.Size = UDim2.new(0,34,0,34)
+ cancelButton.Style = Enum.ButtonStyle.RobloxButtonDefault
+ cancelButton.ZIndex = 6
+ cancelButton.Text = ""
+ cancelButton.Modal = true
+ cancelButton.Parent = setPanel
+
+ -- Children of Cancel Button
+ local cancelImage = Instance.new("ImageLabel")
+ cancelImage.Name = "CancelImage"
+ cancelImage.BackgroundTransparency = 1
+ cancelImage.Image = "http://www.roblox.com/asset/?id=54135717"
+ cancelImage.Position = UDim2.new(0,-2,0,-2)
+ cancelImage.Size = UDim2.new(0,16,0,16)
+ cancelImage.ZIndex = 6
+ cancelImage.Parent = cancelButton
+
+ return setGui
+ end
+
+ local function createSetButton(text)
+ local setButton = Instance.new("TextButton")
+
+ if text then setButton.Text = text
+ else setButton.Text = "" end
+
+ setButton.AutoButtonColor = false
+ setButton.BackgroundTransparency = 1
+ setButton.BackgroundColor3 = Color3.new(1,1,1)
+ setButton.BorderSizePixel = 0
+ setButton.Size = UDim2.new(1,-5,0,18)
+ setButton.ZIndex = 6
+ setButton.Visible = false
+ setButton.Font = Enum.Font.Arial
+ setButton.FontSize = Enum.FontSize.Size18
+ setButton.TextColor3 = Color3.new(1,1,1)
+ setButton.TextXAlignment = Enum.TextXAlignment.Left
+
+ return setButton
+ end
+
+ local function buildSetButton(name, setId, setImageId, i, count)
+ local button = createSetButton(name)
+ button.Text = name
+ button.Name = "SetButton"
+ button.Visible = true
+
+ local setValue = Instance.new("IntValue")
+ setValue.Name = "SetId"
+ setValue.Value = setId
+ setValue.Parent = button
+
+ local setName = Instance.new("StringValue")
+ setName.Name = "SetName"
+ setName.Value = name
+ setName.Parent = button
+
+ return button
+ end
+
+ local function processCategory(sets)
+ local setButtons = {}
+ local numSkipped = 0
+ for i = 1, #sets do
+ if not showAdminCategories and sets[i].Name == "Beta" then
+ numSkipped = numSkipped + 1
+ else
+ setButtons[i - numSkipped] = buildSetButton(sets[i].Name, sets[i].CategoryId, sets[i].ImageAssetId, i - numSkipped, #sets)
+ end
+ end
+ return setButtons
+ end
+
+ local function handleResize()
+ wait() -- neccessary to insure heartbeat happened
+
+ local itemPreview = setGui.SetPanel.ItemPreview
+
+ itemPreview.LargePreview.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.X)
+ itemPreview.LargePreview.Position = UDim2.new(0.5,-itemPreview.LargePreview.AbsoluteSize.X/2,0,0)
+ itemPreview.TextPanel.Position = UDim2.new(0,0,0,itemPreview.LargePreview.AbsoluteSize.Y)
+ itemPreview.TextPanel.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.Y - itemPreview.LargePreview.AbsoluteSize.Y)
+ end
+
+ local function makeInsertAssetButton()
+ local insertAssetButtonExample = Instance.new("Frame")
+ insertAssetButtonExample.Name = "InsertAssetButtonExample"
+ insertAssetButtonExample.Position = UDim2.new(0,128,0,64)
+ insertAssetButtonExample.Size = UDim2.new(0,64,0,64)
+ insertAssetButtonExample.BackgroundTransparency = 1
+ insertAssetButtonExample.ZIndex = 6
+ insertAssetButtonExample.Visible = false
+
+ local assetId = Instance.new("IntValue")
+ assetId.Name = "AssetId"
+ assetId.Value = 0
+ assetId.Parent = insertAssetButtonExample
+
+ local assetName = Instance.new("StringValue")
+ assetName.Name = "AssetName"
+ assetName.Value = ""
+ assetName.Parent = insertAssetButtonExample
+
+ local button = Instance.new("TextButton")
+ button.Name = "Button"
+ button.Text = ""
+ button.Style = Enum.ButtonStyle.RobloxButton
+ button.Position = UDim2.new(0.025,0,0.025,0)
+ button.Size = UDim2.new(0.95,0,0.95,0)
+ button.ZIndex = 6
+ button.Parent = insertAssetButtonExample
+
+ local buttonImage = Instance.new("ImageLabel")
+ buttonImage.Name = "ButtonImage"
+ buttonImage.Image = ""
+ buttonImage.Position = UDim2.new(0,-7,0,-7)
+ buttonImage.Size = UDim2.new(1,14,1,14)
+ buttonImage.BackgroundTransparency = 1
+ buttonImage.ZIndex = 7
+ buttonImage.Parent = button
+
+ local configIcon = buttonImage:clone()
+ configIcon.Name = "ConfigIcon"
+ configIcon.Visible = false
+ configIcon.Position = UDim2.new(1,-23,1,-24)
+ configIcon.Size = UDim2.new(0,16,0,16)
+ configIcon.Image = ""
+ configIcon.ZIndex = 6
+ configIcon.Parent = insertAssetButtonExample
+
+ return insertAssetButtonExample
+ end
+
+ local function showLargePreview(insertButton)
+ if insertButton:FindFirstChild("AssetId") then
+ delay(0,function()
+ game:GetService("ContentProvider"):Preload(LargeThumbnailUrl .. tostring(insertButton.AssetId.Value))
+ setGui.SetPanel.ItemPreview.LargePreview.Image = LargeThumbnailUrl .. tostring(insertButton.AssetId.Value)
+ end)
+ end
+ if insertButton:FindFirstChild("AssetName") then
+ setGui.SetPanel.ItemPreview.TextPanel.RolloverText.Text = insertButton.AssetName.Value
+ end
+ end
+
+ local function selectTerrainShape(shape)
+ if currTerrainDropDownFrame then
+ objectSelected(tostring(currTerrainDropDownFrame.AssetName.Value), tonumber(currTerrainDropDownFrame.AssetId.Value), shape)
+ end
+ end
+
+ local function createTerrainTypeButton(name, parent)
+ local dropDownTextButton = Instance.new("TextButton")
+ dropDownTextButton.Name = name .. "Button"
+ dropDownTextButton.Font = Enum.Font.ArialBold
+ dropDownTextButton.FontSize = Enum.FontSize.Size14
+ dropDownTextButton.BorderSizePixel = 0
+ dropDownTextButton.TextColor3 = Color3.new(1,1,1)
+ dropDownTextButton.Text = name
+ dropDownTextButton.TextXAlignment = Enum.TextXAlignment.Left
+ dropDownTextButton.BackgroundTransparency = 1
+ dropDownTextButton.ZIndex = parent.ZIndex + 1
+ dropDownTextButton.Size = UDim2.new(0,parent.Size.X.Offset - 2,0,16)
+ dropDownTextButton.Position = UDim2.new(0,1,0,0)
+
+ dropDownTextButton.MouseEnter:connect(function()
+ dropDownTextButton.BackgroundTransparency = 0
+ dropDownTextButton.TextColor3 = Color3.new(0,0,0)
+ end)
+
+ dropDownTextButton.MouseLeave:connect(function()
+ dropDownTextButton.BackgroundTransparency = 1
+ dropDownTextButton.TextColor3 = Color3.new(1,1,1)
+ end)
+
+ dropDownTextButton.MouseButton1Click:connect(function()
+ dropDownTextButton.BackgroundTransparency = 1
+ dropDownTextButton.TextColor3 = Color3.new(1,1,1)
+ if dropDownTextButton.Parent and dropDownTextButton.Parent:IsA("GuiObject") then
+ dropDownTextButton.Parent.Visible = false
+ end
+ selectTerrainShape(terrainShapeMap[dropDownTextButton.Text])
+ end)
+
+ return dropDownTextButton
+ end
+
+ local function createTerrainDropDownMenu(zIndex)
+ local dropDown = Instance.new("Frame")
+ dropDown.Name = "TerrainDropDown"
+ dropDown.BackgroundColor3 = Color3.new(0,0,0)
+ dropDown.BorderColor3 = Color3.new(1,0,0)
+ dropDown.Size = UDim2.new(0,200,0,0)
+ dropDown.Visible = false
+ dropDown.ZIndex = zIndex
+ dropDown.Parent = setGui
+
+ for i = 1, #terrainShapes do
+ local shapeButton = createTerrainTypeButton(terrainShapes[i],dropDown)
+ shapeButton.Position = UDim2.new(0,1,0,(i - 1) * (shapeButton.Size.Y.Offset))
+ shapeButton.Parent = dropDown
+ dropDown.Size = UDim2.new(0,200,0,dropDown.Size.Y.Offset + (shapeButton.Size.Y.Offset))
+ end
+
+ dropDown.MouseLeave:connect(function()
+ dropDown.Visible = false
+ end)
+ end
+
+
+ local function createDropDownMenuButton(parent)
+ local dropDownButton = Instance.new("ImageButton")
+ dropDownButton.Name = "DropDownButton"
+ dropDownButton.Image = "http://www.roblox.com/asset/?id=67581509"
+ dropDownButton.BackgroundTransparency = 1
+ dropDownButton.Size = UDim2.new(0,16,0,16)
+ dropDownButton.Position = UDim2.new(1,-24,0,6)
+ dropDownButton.ZIndex = parent.ZIndex + 2
+ dropDownButton.Parent = parent
+
+ if not setGui:FindFirstChild("TerrainDropDown") then
+ createTerrainDropDownMenu(8)
+ end
+
+ dropDownButton.MouseButton1Click:connect(function()
+ setGui.TerrainDropDown.Visible = true
+ setGui.TerrainDropDown.Position = UDim2.new(0,parent.AbsolutePosition.X,0,parent.AbsolutePosition.Y)
+ currTerrainDropDownFrame = parent
+ end)
+ end
+
+ local function buildInsertButton()
+ local insertButton = makeInsertAssetButton()
+ insertButton.Name = "InsertAssetButton"
+ insertButton.Visible = true
+
+ if Data.Category[Data.CurrentCategory].SetName == "High Scalability" then
+ createDropDownMenuButton(insertButton)
+ end
+
+ local lastEnter = nil
+ local mouseEnterCon = insertButton.MouseEnter:connect(function()
+ lastEnter = insertButton
+ delay(0.1,function()
+ if lastEnter == insertButton then
+ showLargePreview(insertButton)
+ end
+ end)
+ end)
+ return insertButton, mouseEnterCon
+ end
+
+ local function realignButtonGrid(columns)
+ local x = 0
+ local y = 0
+ for i = 1, #insertButtons do
+ insertButtons[i].Position = UDim2.new(0, buttonWidth * x, 0, buttonHeight * y)
+ x = x + 1
+ if x >= columns then
+ x = 0
+ y = y + 1
+ end
+ end
+ end
+
+ local function setInsertButtonImageBehavior(insertFrame, visible, name, assetId)
+ if visible then
+ insertFrame.AssetName.Value = name
+ insertFrame.AssetId.Value = assetId
+ local newImageUrl = SmallThumbnailUrl .. assetId
+ if newImageUrl ~= insertFrame.Button.ButtonImage.Image then
+ delay(0,function()
+ game:GetService("ContentProvider"):Preload(SmallThumbnailUrl .. assetId)
+ if insertFrame:findFirstChild("Button") then
+ insertFrame.Button.ButtonImage.Image = SmallThumbnailUrl .. assetId
+ end
+ end)
+ end
+ table.insert(insertButtonCons,
+ insertFrame.Button.MouseButton1Click:connect(function()
+ -- special case for water, show water selection gui
+ local isWaterSelected = (name == "Water") and (Data.Category[Data.CurrentCategory].SetName == "High Scalability")
+ waterGui.Visible = isWaterSelected
+ if isWaterSelected then
+ objectSelected(name, tonumber(assetId), nil)
+ else
+ objectSelected(name, tonumber(assetId))
+ end
+ end)
+ )
+ insertFrame.Visible = true
+ else
+ insertFrame.Visible = false
+ end
+ end
+
+ local function loadSectionOfItems(setGui, rows, columns)
+ local pageSize = rows * columns
+
+ if arrayPosition > #contents then return end
+
+ local origArrayPos = arrayPosition
+
+ local yCopy = 0
+ for i = 1, pageSize + 1 do
+ if arrayPosition >= #contents + 1 then
+ break
+ end
+
+ local buttonCon
+ insertButtons[arrayPosition], buttonCon = buildInsertButton()
+ table.insert(insertButtonCons,buttonCon)
+ insertButtons[arrayPosition].Parent = setGui.SetPanel.ItemsFrame
+ arrayPosition = arrayPosition + 1
+ end
+ realignButtonGrid(columns)
+
+ local indexCopy = origArrayPos
+ for index = origArrayPos, arrayPosition do
+ if insertButtons[index] then
+ if contents[index] then
+
+ -- we don't want water to have a drop down button
+ if contents[index].Name == "Water" then
+ if Data.Category[Data.CurrentCategory].SetName == "High Scalability" then
+ insertButtons[index]:FindFirstChild("DropDownButton",true):Destroy()
+ end
+ end
+
+ local assetId
+ if useAssetVersionId then
+ assetId = contents[index].AssetVersionId
+ else
+ assetId = contents[index].AssetId
+ end
+ setInsertButtonImageBehavior(insertButtons[index], true, contents[index].Name, assetId)
+ else
+ break
+ end
+ else
+ break
+ end
+ indexCopy = index
+ end
+ end
+
+ local function setSetIndex()
+ Data.Category[Data.CurrentCategory].Index = 0
+
+ rows = 7
+ columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth)
+
+ contents = Data.Category[Data.CurrentCategory].Contents
+ if contents then
+ -- remove our buttons and their connections
+ for i = 1, #insertButtons do
+ insertButtons[i]:remove()
+ end
+ for i = 1, #insertButtonCons do
+ if insertButtonCons[i] then insertButtonCons[i]:disconnect() end
+ end
+ insertButtonCons = {}
+ insertButtons = {}
+
+ arrayPosition = 1
+ loadSectionOfItems(setGui, rows, columns)
+ end
+ end
+
+ local function selectSet(button, setName, setId, setIndex)
+ if button and Data.Category[Data.CurrentCategory] ~= nil then
+ if button ~= Data.Category[Data.CurrentCategory].Button then
+ Data.Category[Data.CurrentCategory].Button = button
+
+ if SetCache[setId] == nil then
+ SetCache[setId] = game:GetService("InsertService"):GetCollection(setId)
+ end
+ Data.Category[Data.CurrentCategory].Contents = SetCache[setId]
+
+ Data.Category[Data.CurrentCategory].SetName = setName
+ Data.Category[Data.CurrentCategory].SetId = setId
+ end
+ setSetIndex()
+ end
+ end
+
+ local function selectCategoryPage(buttons, page)
+ if buttons ~= Data.CurrentCategory then
+ if Data.CurrentCategory then
+ for key, button in pairs(Data.CurrentCategory) do
+ button.Visible = false
+ end
+ end
+
+ Data.CurrentCategory = buttons
+ if Data.Category[Data.CurrentCategory] == nil then
+ Data.Category[Data.CurrentCategory] = {}
+ if #buttons > 0 then
+ selectSet(buttons[1], buttons[1].SetName.Value, buttons[1].SetId.Value, 0)
+ end
+ else
+ Data.Category[Data.CurrentCategory].Button = nil
+ selectSet(Data.Category[Data.CurrentCategory].ButtonFrame, Data.Category[Data.CurrentCategory].SetName, Data.Category[Data.CurrentCategory].SetId, Data.Category[Data.CurrentCategory].Index)
+ end
+ end
+ end
+
+ local function selectCategory(category)
+ selectCategoryPage(category, 0)
+ end
+
+ local function resetAllSetButtonSelection()
+ local setButtons = setGui.SetPanel.Sets.SetsLists:GetChildren()
+ for i = 1, #setButtons do
+ if setButtons[i]:IsA("TextButton") then
+ setButtons[i].Selected = false
+ setButtons[i].BackgroundTransparency = 1
+ setButtons[i].TextColor3 = Color3.new(1,1,1)
+ setButtons[i].BackgroundColor3 = Color3.new(1,1,1)
+ end
+ end
+ end
+
+ local function populateSetsFrame()
+ local currRow = 0
+ for i = 1, #userCategoryButtons do
+ local button = userCategoryButtons[i]
+ button.Visible = true
+ button.Position = UDim2.new(0,5,0,currRow * button.Size.Y.Offset)
+ button.Parent = setGui.SetPanel.Sets.SetsLists
+
+ if i == 1 then -- we will have this selected by default, so show it
+ button.Selected = true
+ button.BackgroundColor3 = Color3.new(0,204/255,0)
+ button.TextColor3 = Color3.new(0,0,0)
+ button.BackgroundTransparency = 0
+ end
+
+ button.MouseEnter:connect(function()
+ if not button.Selected then
+ button.BackgroundTransparency = 0
+ button.TextColor3 = Color3.new(0,0,0)
+ end
+ end)
+ button.MouseLeave:connect(function()
+ if not button.Selected then
+ button.BackgroundTransparency = 1
+ button.TextColor3 = Color3.new(1,1,1)
+ end
+ end)
+ button.MouseButton1Click:connect(function()
+ resetAllSetButtonSelection()
+ button.Selected = not button.Selected
+ button.BackgroundColor3 = Color3.new(0,204/255,0)
+ button.TextColor3 = Color3.new(0,0,0)
+ button.BackgroundTransparency = 0
+ selectSet(button, button.Text, userCategoryButtons[i].SetId.Value, 0)
+ end)
+
+ currRow = currRow + 1
+ end
+
+ local buttons = setGui.SetPanel.Sets.SetsLists:GetChildren()
+
+ -- set first category as loaded for default
+ if buttons then
+ for i = 1, #buttons do
+ if buttons[i]:IsA("TextButton") then
+ selectSet(buttons[i], buttons[i].Text, userCategoryButtons[i].SetId.Value, 0)
+ selectCategory(userCategoryButtons)
+ break
+ end
+ end
+ end
+ end
+
+ setGui = createSetGui()
+ waterGui, waterTypeChangedEvent = createWaterGui()
+ waterGui.Position = UDim2.new(0,55,0,0)
+ waterGui.Parent = setGui
+ setGui.Changed:connect(function(prop) -- this resizes the preview image to always be the right size
+ if prop == "AbsoluteSize" then
+ handleResize()
+ setSetIndex()
+ end
+ end)
+
+ local scrollFrame, controlFrame = t.CreateTrueScrollingFrame()
+ scrollFrame.Size = UDim2.new(0.54,0,0.85,0)
+ scrollFrame.Position = UDim2.new(0.24,0,0.085,0)
+ scrollFrame.Name = "ItemsFrame"
+ scrollFrame.ZIndex = 6
+ scrollFrame.Parent = setGui.SetPanel
+ scrollFrame.BackgroundTransparency = 1
+
+ drillDownSetZIndex(controlFrame,7)
+
+ controlFrame.Parent = setGui.SetPanel
+ controlFrame.Position = UDim2.new(0.76, 5, 0, 0)
+
+ local debounce = false
+ controlFrame.ScrollBottom.Changed:connect(function(prop)
+ if controlFrame.ScrollBottom.Value == true then
+ if debounce then return end
+ debounce = true
+ loadSectionOfItems(setGui, rows, columns)
+ debounce = false
+ end
+ end)
+
+ local userData = {}
+ for id = 1, #userIdsForSets do
+ local newUserData = game:GetService("InsertService"):GetUserSets(userIdsForSets[id])
+ if newUserData and #newUserData > 2 then
+ -- start at #3 to skip over My Decals and My Models for each account
+ for category = 3, #newUserData do
+ if newUserData[category].Name == "High Scalability" then -- we want high scalability parts to show first
+ table.insert(userData,1,newUserData[category])
+ else
+ table.insert(userData, newUserData[category])
+ end
+ end
+ end
+
+ end
+ if userData then
+ userCategoryButtons = processCategory(userData)
+ end
+
+ rows = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.Y/buttonHeight)
+ columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth)
+
+ populateSetsFrame()
+
+ insertPanelCloseCon = setGui.SetPanel.CancelButton.MouseButton1Click:connect(function()
+ setGui.SetPanel.Visible = false
+ if dialogClosed then dialogClosed() end
+ end)
+
+ local setVisibilityFunction = function(visible)
+ if visible then
+ setGui.SetPanel.Visible = true
+ else
+ setGui.SetPanel.Visible = false
+ end
+ end
+
+ local getVisibilityFunction = function()
+ if setGui then
+ if setGui:FindFirstChild("SetPanel") then
+ return setGui.SetPanel.Visible
+ end
+ end
+
+ return false
+ end
+
+ return setGui, setVisibilityFunction, getVisibilityFunction, waterTypeChangedEvent
+end
+
+t.CreateTerrainMaterialSelector = function(size,position)
+ local terrainMaterialSelectionChanged = Instance.new("BindableEvent")
+ terrainMaterialSelectionChanged.Name = "TerrainMaterialSelectionChanged"
+
+ local selectedButton = nil
+
+ local frame = Instance.new("Frame")
+ frame.Name = "TerrainMaterialSelector"
+ if size then
+ frame.Size = size
+ else
+ frame.Size = UDim2.new(0, 245, 0, 230)
+ end
+ if position then
+ frame.Position = position
+ end
+ frame.BorderSizePixel = 0
+ frame.BackgroundColor3 = Color3.new(0,0,0)
+ frame.Active = true
+
+ terrainMaterialSelectionChanged.Parent = frame
+
+ local waterEnabled = true -- todo: turn this on when water is ready
+
+ local materialToImageMap = {}
+ local materialNames = {"Grass", "Sand", "Brick", "Granite", "Asphalt", "Iron", "Aluminum", "Gold", "Plank", "Log", "Gravel", "Cinder Block", "Stone Wall", "Concrete", "Plastic (red)", "Plastic (blue)"}
+ if waterEnabled then
+ table.insert(materialNames,"Water")
+ end
+ local currentMaterial = 1
+
+ function getEnumFromName(choice)
+ if choice == "Grass" then return 1 end
+ if choice == "Sand" then return 2 end
+ if choice == "Erase" then return 0 end
+ if choice == "Brick" then return 3 end
+ if choice == "Granite" then return 4 end
+ if choice == "Asphalt" then return 5 end
+ if choice == "Iron" then return 6 end
+ if choice == "Aluminum" then return 7 end
+ if choice == "Gold" then return 8 end
+ if choice == "Plank" then return 9 end
+ if choice == "Log" then return 10 end
+ if choice == "Gravel" then return 11 end
+ if choice == "Cinder Block" then return 12 end
+ if choice == "Stone Wall" then return 13 end
+ if choice == "Concrete" then return 14 end
+ if choice == "Plastic (red)" then return 15 end
+ if choice == "Plastic (blue)" then return 16 end
+ if choice == "Water" then return 17 end
+ end
+
+ function getNameFromEnum(choice)
+ if choice == Enum.CellMaterial.Grass or choice == 1 then return "Grass"end
+ if choice == Enum.CellMaterial.Sand or choice == 2 then return "Sand" end
+ if choice == Enum.CellMaterial.Empty or choice == 0 then return "Erase" end
+ if choice == Enum.CellMaterial.Brick or choice == 3 then return "Brick" end
+ if choice == Enum.CellMaterial.Granite or choice == 4 then return "Granite" end
+ if choice == Enum.CellMaterial.Asphalt or choice == 5 then return "Asphalt" end
+ if choice == Enum.CellMaterial.Iron or choice == 6 then return "Iron" end
+ if choice == Enum.CellMaterial.Aluminum or choice == 7 then return "Aluminum" end
+ if choice == Enum.CellMaterial.Gold or choice == 8 then return "Gold" end
+ if choice == Enum.CellMaterial.WoodPlank or choice == 9 then return "Plank" end
+ if choice == Enum.CellMaterial.WoodLog or choice == 10 then return "Log" end
+ if choice == Enum.CellMaterial.Gravel or choice == 11 then return "Gravel" end
+ if choice == Enum.CellMaterial.CinderBlock or choice == 12 then return "Cinder Block" end
+ if choice == Enum.CellMaterial.MossyStone or choice == 13 then return "Stone Wall" end
+ if choice == Enum.CellMaterial.Cement or choice == 14 then return "Concrete" end
+ if choice == Enum.CellMaterial.RedPlastic or choice == 15 then return "Plastic (red)" end
+ if choice == Enum.CellMaterial.BluePlastic or choice == 16 then return "Plastic (blue)" end
+
+ if waterEnabled then
+ if choice == Enum.CellMaterial.Water or choice == 17 then return "Water" end
+ end
+ end
+
+
+ local function updateMaterialChoice(choice)
+ currentMaterial = getEnumFromName(choice)
+ terrainMaterialSelectionChanged:Fire(currentMaterial)
+ end
+
+ -- we so need a better way to do this
+ for i,v in pairs(materialNames) do
+ materialToImageMap[v] = {}
+ if v == "Grass" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=56563112"
+ elseif v == "Sand" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=62356652"
+ elseif v == "Brick" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=65961537"
+ elseif v == "Granite" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532153"
+ elseif v == "Asphalt" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532038"
+ elseif v == "Iron" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532093"
+ elseif v == "Aluminum" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531995"
+ elseif v == "Gold" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532118"
+ elseif v == "Plastic (red)" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531848"
+ elseif v == "Plastic (blue)" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531924"
+ elseif v == "Plank" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532015"
+ elseif v == "Log" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532051"
+ elseif v == "Gravel" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532206"
+ elseif v == "Cinder Block" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532103"
+ elseif v == "Stone Wall" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531804"
+ elseif v == "Concrete" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532059"
+ elseif v == "Water" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=81407474"
+ else materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=66887593" -- fill in the rest here!!
+ end
+ end
+
+ local scrollFrame, scrollUp, scrollDown, recalculateScroll = t.CreateScrollingFrame(nil,"grid")
+ scrollFrame.Size = UDim2.new(0.85,0,1,0)
+ scrollFrame.Position = UDim2.new(0,0,0,0)
+ scrollFrame.Parent = frame
+
+ scrollUp.Parent = frame
+ scrollUp.Visible = true
+ scrollUp.Position = UDim2.new(1,-19,0,0)
+
+ scrollDown.Parent = frame
+ scrollDown.Visible = true
+ scrollDown.Position = UDim2.new(1,-19,1,-17)
+
+ local function goToNewMaterial(buttonWrap, materialName)
+ updateMaterialChoice(materialName)
+ buttonWrap.BackgroundTransparency = 0
+ selectedButton.BackgroundTransparency = 1
+ selectedButton = buttonWrap
+ end
+
+ local function createMaterialButton(name)
+ local buttonWrap = Instance.new("TextButton")
+ buttonWrap.Text = ""
+ buttonWrap.Size = UDim2.new(0,32,0,32)
+ buttonWrap.BackgroundColor3 = Color3.new(1,1,1)
+ buttonWrap.BorderSizePixel = 0
+ buttonWrap.BackgroundTransparency = 1
+ buttonWrap.AutoButtonColor = false
+ buttonWrap.Name = tostring(name)
+
+ local imageButton = Instance.new("ImageButton")
+ imageButton.AutoButtonColor = false
+ imageButton.BackgroundTransparency = 1
+ imageButton.Size = UDim2.new(0,30,0,30)
+ imageButton.Position = UDim2.new(0,1,0,1)
+ imageButton.Name = tostring(name)
+ imageButton.Parent = buttonWrap
+ imageButton.Image = materialToImageMap[name].Regular
+
+ local enumType = Instance.new("NumberValue")
+ enumType.Name = "EnumType"
+ enumType.Parent = buttonWrap
+ enumType.Value = 0
+
+ imageButton.MouseEnter:connect(function()
+ buttonWrap.BackgroundTransparency = 0
+ end)
+ imageButton.MouseLeave:connect(function()
+ if selectedButton ~= buttonWrap then
+ buttonWrap.BackgroundTransparency = 1
+ end
+ end)
+ imageButton.MouseButton1Click:connect(function()
+ if selectedButton ~= buttonWrap then
+ goToNewMaterial(buttonWrap, tostring(name))
+ end
+ end)
+
+ return buttonWrap
+ end
+
+ for i = 1, #materialNames do
+ local imageButton = createMaterialButton(materialNames[i])
+
+ if materialNames[i] == "Grass" then -- always start with grass as the default
+ selectedButton = imageButton
+ imageButton.BackgroundTransparency = 0
+ end
+
+ imageButton.Parent = scrollFrame
+ end
+
+ local forceTerrainMaterialSelection = function(newMaterialType)
+ if not newMaterialType then return end
+ if currentMaterial == newMaterialType then return end
+
+ local matName = getNameFromEnum(newMaterialType)
+ local buttons = scrollFrame:GetChildren()
+ for i = 1, #buttons do
+ if buttons[i].Name == "Plastic (blue)" and matName == "Plastic (blue)" then goToNewMaterial(buttons[i],matName) return end
+ if buttons[i].Name == "Plastic (red)" and matName == "Plastic (red)" then goToNewMaterial(buttons[i],matName) return end
+ if string.find(buttons[i].Name, matName) then
+ goToNewMaterial(buttons[i],matName)
+ return
+ end
+ end
+ end
+
+ frame.Changed:connect(function ( prop )
+ if prop == "AbsoluteSize" then
+ recalculateScroll()
+ end
+ end)
+
+ recalculateScroll()
+ return frame, terrainMaterialSelectionChanged, forceTerrainMaterialSelection
+end
+
+t.CreateLoadingFrame = function(name,size,position)
+ game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=35238053")
+
+ local loadingFrame = Instance.new("Frame")
+ loadingFrame.Name = "LoadingFrame"
+ loadingFrame.Style = Enum.FrameStyle.RobloxRound
+
+ if size then loadingFrame.Size = size
+ else loadingFrame.Size = UDim2.new(0,300,0,160) end
+ if position then loadingFrame.Position = position
+ else loadingFrame.Position = UDim2.new(0.5, -150, 0.5,-80) end
+
+ local loadingBar = Instance.new("Frame")
+ loadingBar.Name = "LoadingBar"
+ loadingBar.BackgroundColor3 = Color3.new(0,0,0)
+ loadingBar.BorderColor3 = Color3.new(79/255,79/255,79/255)
+ loadingBar.Position = UDim2.new(0,0,0,41)
+ loadingBar.Size = UDim2.new(1,0,0,30)
+ loadingBar.Parent = loadingFrame
+
+ local loadingGreenBar = Instance.new("ImageLabel")
+ loadingGreenBar.Name = "LoadingGreenBar"
+ loadingGreenBar.Image = "http://www.roblox.com/asset/?id=35238053"
+ loadingGreenBar.Position = UDim2.new(0,0,0,0)
+ loadingGreenBar.Size = UDim2.new(0,0,1,0)
+ loadingGreenBar.Visible = false
+ loadingGreenBar.Parent = loadingBar
+
+ local loadingPercent = Instance.new("TextLabel")
+ loadingPercent.Name = "LoadingPercent"
+ loadingPercent.BackgroundTransparency = 1
+ loadingPercent.Position = UDim2.new(0,0,1,0)
+ loadingPercent.Size = UDim2.new(1,0,0,14)
+ loadingPercent.Font = Enum.Font.Arial
+ loadingPercent.Text = "0%"
+ loadingPercent.FontSize = Enum.FontSize.Size14
+ loadingPercent.TextColor3 = Color3.new(1,1,1)
+ loadingPercent.Parent = loadingBar
+
+ local cancelButton = Instance.new("TextButton")
+ cancelButton.Name = "CancelButton"
+ cancelButton.Position = UDim2.new(0.5,-60,1,-40)
+ cancelButton.Size = UDim2.new(0,120,0,40)
+ cancelButton.Font = Enum.Font.Arial
+ cancelButton.FontSize = Enum.FontSize.Size18
+ cancelButton.TextColor3 = Color3.new(1,1,1)
+ cancelButton.Text = "Cancel"
+ cancelButton.Style = Enum.ButtonStyle.RobloxButton
+ cancelButton.Parent = loadingFrame
+
+ local loadingName = Instance.new("TextLabel")
+ loadingName.Name = "loadingName"
+ loadingName.BackgroundTransparency = 1
+ loadingName.Size = UDim2.new(1,0,0,18)
+ loadingName.Position = UDim2.new(0,0,0,2)
+ loadingName.Font = Enum.Font.Arial
+ loadingName.Text = name
+ loadingName.TextColor3 = Color3.new(1,1,1)
+ loadingName.TextStrokeTransparency = 1
+ loadingName.FontSize = Enum.FontSize.Size18
+ loadingName.Parent = loadingFrame
+
+ local cancelButtonClicked = Instance.new("BindableEvent")
+ cancelButtonClicked.Name = "CancelButtonClicked"
+ cancelButtonClicked.Parent = cancelButton
+ cancelButton.MouseButton1Click:connect(function()
+ cancelButtonClicked:Fire()
+ end)
+
+ local updateLoadingGuiPercent = function(percent, tweenAction, tweenLength)
+ if percent and type(percent) ~= "number" then
+ error("updateLoadingGuiPercent expects number as argument, got",type(percent),"instead")
+ end
+
+ local newSize = nil
+ if percent < 0 then
+ newSize = UDim2.new(0,0,1,0)
+ elseif percent > 1 then
+ newSize = UDim2.new(1,0,1,0)
+ else
+ newSize = UDim2.new(percent,0,1,0)
+ end
+
+ if tweenAction then
+ if not tweenLength then
+ error("updateLoadingGuiPercent is set to tween new percentage, but got no tween time length! Please pass this in as third argument")
+ end
+
+ if (newSize.X.Scale > 0) then
+ loadingGreenBar.Visible = true
+ loadingGreenBar:TweenSize( newSize,
+ Enum.EasingDirection.Out,
+ Enum.EasingStyle.Quad,
+ tweenLength,
+ true)
+ else
+ loadingGreenBar:TweenSize( newSize,
+ Enum.EasingDirection.Out,
+ Enum.EasingStyle.Quad,
+ tweenLength,
+ true,
+ function()
+ if (newSize.X.Scale < 0) then
+ loadingGreenBar.Visible = false
+ end
+ end)
+ end
+
+ else
+ loadingGreenBar.Size = newSize
+ loadingGreenBar.Visible = (newSize.X.Scale > 0)
+ end
+ end
+
+ loadingGreenBar.Changed:connect(function(prop)
+ if prop == "Size" then
+ loadingPercent.Text = tostring( math.ceil(loadingGreenBar.Size.X.Scale * 100) ) .. "%"
+ end
+ end)
+
+ return loadingFrame, updateLoadingGuiPercent, cancelButtonClicked
+end
+
+t.CreatePluginFrame = function (name,size,position,scrollable,parent)
+ function createMenuButton(size,position,text,fontsize,name,parent)
+ local button = Instance.new("TextButton",parent)
+ button.AutoButtonColor = false
+ button.Name = name
+ button.BackgroundTransparency = 1
+ button.Position = position
+ button.Size = size
+ button.Font = Enum.Font.ArialBold
+ button.FontSize = fontsize
+ button.Text = text
+ button.TextColor3 = Color3.new(1,1,1)
+ button.BorderSizePixel = 0
+ button.BackgroundColor3 = Color3.new(20/255,20/255,20/255)
+
+ button.MouseEnter:connect(function ( )
+ if button.Selected then return end
+ button.BackgroundTransparency = 0
+ end)
+ button.MouseLeave:connect(function ( )
+ if button.Selected then return end
+ button.BackgroundTransparency = 1
+ end)
+
+ return button
+
+ end
+
+ local dragBar = Instance.new("Frame",parent)
+ dragBar.Name = tostring(name) .. "DragBar"
+ dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255)
+ dragBar.BorderColor3 = Color3.new(0,0,0)
+ if size then
+ dragBar.Size = UDim2.new(size.X.Scale,size.X.Offset,0,20) + UDim2.new(0,20,0,0)
+ else
+ dragBar.Size = UDim2.new(0,183,0,20)
+ end
+ if position then
+ dragBar.Position = position
+ end
+ dragBar.Active = true
+ dragBar.Draggable = true
+ --dragBar.Visible = false
+ dragBar.MouseEnter:connect(function ( )
+ dragBar.BackgroundColor3 = Color3.new(49/255,49/255,49/255)
+ end)
+ dragBar.MouseLeave:connect(function ( )
+ dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255)
+ end)
+
+ -- plugin name label
+ local pluginNameLabel = Instance.new("TextLabel",dragBar)
+ pluginNameLabel.Name = "BarNameLabel"
+ pluginNameLabel.Text = " " .. tostring(name)
+ pluginNameLabel.TextColor3 = Color3.new(1,1,1)
+ pluginNameLabel.TextStrokeTransparency = 0
+ pluginNameLabel.Size = UDim2.new(1,0,1,0)
+ pluginNameLabel.Font = Enum.Font.ArialBold
+ pluginNameLabel.FontSize = Enum.FontSize.Size18
+ pluginNameLabel.TextXAlignment = Enum.TextXAlignment.Left
+ pluginNameLabel.BackgroundTransparency = 1
+
+ -- close button
+ local closeButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-16,0.5,-8),"X",Enum.FontSize.Size14,"CloseButton",dragBar)
+ local closeEvent = Instance.new("BindableEvent")
+ closeEvent.Name = "CloseEvent"
+ closeEvent.Parent = closeButton
+ closeButton.MouseButton1Click:connect(function ()
+ closeEvent:Fire()
+ closeButton.BackgroundTransparency = 1
+ end)
+
+ -- help button
+ local helpButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-51,0.5,-8),"?",Enum.FontSize.Size14,"HelpButton",dragBar)
+ local helpFrame = Instance.new("Frame",dragBar)
+ helpFrame.Name = "HelpFrame"
+ helpFrame.BackgroundColor3 = Color3.new(0,0,0)
+ helpFrame.Size = UDim2.new(0,300,0,552)
+ helpFrame.Position = UDim2.new(1,5,0,0)
+ helpFrame.Active = true
+ helpFrame.BorderSizePixel = 0
+ helpFrame.Visible = false
+
+ helpButton.MouseButton1Click:connect(function( )
+ helpFrame.Visible = not helpFrame.Visible
+ if helpFrame.Visible then
+ helpButton.Selected = true
+ helpButton.BackgroundTransparency = 0
+ local screenGui = getScreenGuiAncestor(helpFrame)
+ if screenGui then
+ if helpFrame.AbsolutePosition.X + helpFrame.AbsoluteSize.X > screenGui.AbsoluteSize.X then --position on left hand side
+ helpFrame.Position = UDim2.new(0,-5 - helpFrame.AbsoluteSize.X,0,0)
+ else -- position on right hand side
+ helpFrame.Position = UDim2.new(1,5,0,0)
+ end
+ else
+ helpFrame.Position = UDim2.new(1,5,0,0)
+ end
+ else
+ helpButton.Selected = false
+ helpButton.BackgroundTransparency = 1
+ end
+ end)
+
+ local minimizeButton = createMenuButton(UDim2.new(0,16,0,17),UDim2.new(1,-34,0.5,-8),"-",Enum.FontSize.Size14,"MinimizeButton",dragBar)
+ minimizeButton.TextYAlignment = Enum.TextYAlignment.Top
+
+ local minimizeFrame = Instance.new("Frame",dragBar)
+ minimizeFrame.Name = "MinimizeFrame"
+ minimizeFrame.BackgroundColor3 = Color3.new(73/255,73/255,73/255)
+ minimizeFrame.BorderColor3 = Color3.new(0,0,0)
+ minimizeFrame.Position = UDim2.new(0,0,1,0)
+ if size then
+ minimizeFrame.Size = UDim2.new(size.X.Scale,size.X.Offset,0,50) + UDim2.new(0,20,0,0)
+ else
+ minimizeFrame.Size = UDim2.new(0,183,0,50)
+ end
+ minimizeFrame.Visible = false
+
+ local minimizeBigButton = Instance.new("TextButton",minimizeFrame)
+ minimizeBigButton.Position = UDim2.new(0.5,-50,0.5,-20)
+ minimizeBigButton.Name = "MinimizeButton"
+ minimizeBigButton.Size = UDim2.new(0,100,0,40)
+ minimizeBigButton.Style = Enum.ButtonStyle.RobloxButton
+ minimizeBigButton.Font = Enum.Font.ArialBold
+ minimizeBigButton.FontSize = Enum.FontSize.Size18
+ minimizeBigButton.TextColor3 = Color3.new(1,1,1)
+ minimizeBigButton.Text = "Show"
+
+ local separatingLine = Instance.new("Frame",dragBar)
+ separatingLine.Name = "SeparatingLine"
+ separatingLine.BackgroundColor3 = Color3.new(115/255,115/255,115/255)
+ separatingLine.BorderSizePixel = 0
+ separatingLine.Position = UDim2.new(1,-18,0.5,-7)
+ separatingLine.Size = UDim2.new(0,1,0,14)
+
+ local otherSeparatingLine = separatingLine:clone()
+ otherSeparatingLine.Position = UDim2.new(1,-35,0.5,-7)
+ otherSeparatingLine.Parent = dragBar
+
+ local widgetContainer = Instance.new("Frame",dragBar)
+ widgetContainer.Name = "WidgetContainer"
+ widgetContainer.BackgroundTransparency = 1
+ widgetContainer.Position = UDim2.new(0,0,1,0)
+ widgetContainer.BorderColor3 = Color3.new(0,0,0)
+ if not scrollable then
+ widgetContainer.BackgroundTransparency = 0
+ widgetContainer.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
+ end
+
+ if size then
+ if scrollable then
+ widgetContainer.Size = size
+ else
+ widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,size.Y.Scale,size.Y.Offset)
+ end
+ else
+ if scrollable then
+ widgetContainer.Size = UDim2.new(0,163,0,400)
+ else
+ widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,0,400)
+ end
+ end
+ if position then
+ widgetContainer.Position = position + UDim2.new(0,0,0,20)
+ end
+
+ local frame,control,verticalDragger = nil
+ if scrollable then
+ --frame for widgets
+ frame,control = t.CreateTrueScrollingFrame()
+ frame.Size = UDim2.new(1, 0, 1, 0)
+ frame.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
+ frame.BorderColor3 = Color3.new(0,0,0)
+ frame.Active = true
+ frame.Parent = widgetContainer
+ control.Parent = dragBar
+ control.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
+ control.BorderSizePixel = 0
+ control.BackgroundTransparency = 0
+ control.Position = UDim2.new(1,-21,1,1)
+ if size then
+ control.Size = UDim2.new(0,21,size.Y.Scale,size.Y.Offset)
+ else
+ control.Size = UDim2.new(0,21,0,400)
+ end
+ control:FindFirstChild("ScrollDownButton").Position = UDim2.new(0,0,1,-20)
+
+ local fakeLine = Instance.new("Frame",control)
+ fakeLine.Name = "FakeLine"
+ fakeLine.BorderSizePixel = 0
+ fakeLine.BackgroundColor3 = Color3.new(0,0,0)
+ fakeLine.Size = UDim2.new(0,1,1,1)
+ fakeLine.Position = UDim2.new(1,0,0,0)
+
+ verticalDragger = Instance.new("TextButton",widgetContainer)
+ verticalDragger.ZIndex = 2
+ verticalDragger.AutoButtonColor = false
+ verticalDragger.Name = "VerticalDragger"
+ verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255)
+ verticalDragger.BorderColor3 = Color3.new(0,0,0)
+ verticalDragger.Size = UDim2.new(1,20,0,20)
+ verticalDragger.Position = UDim2.new(0,0,1,0)
+ verticalDragger.Active = true
+ verticalDragger.Text = ""
+
+ local scrubFrame = Instance.new("Frame",verticalDragger)
+ scrubFrame.Name = "ScrubFrame"
+ scrubFrame.BackgroundColor3 = Color3.new(1,1,1)
+ scrubFrame.BorderSizePixel = 0
+ scrubFrame.Position = UDim2.new(0.5,-5,0.5,0)
+ scrubFrame.Size = UDim2.new(0,10,0,1)
+ scrubFrame.ZIndex = 5
+ local scrubTwo = scrubFrame:clone()
+ scrubTwo.Position = UDim2.new(0.5,-5,0.5,-2)
+ scrubTwo.Parent = verticalDragger
+ local scrubThree = scrubFrame:clone()
+ scrubThree.Position = UDim2.new(0.5,-5,0.5,2)
+ scrubThree.Parent = verticalDragger
+
+ local areaSoak = Instance.new("TextButton",getScreenGuiAncestor(parent))
+ areaSoak.Name = "AreaSoak"
+ areaSoak.Size = UDim2.new(1,0,1,0)
+ areaSoak.BackgroundTransparency = 1
+ areaSoak.BorderSizePixel = 0
+ areaSoak.Text = ""
+ areaSoak.ZIndex = 10
+ areaSoak.Visible = false
+ areaSoak.Active = true
+
+ local draggingVertical = false
+ local startYPos = nil
+ verticalDragger.MouseEnter:connect(function ()
+ verticalDragger.BackgroundColor3 = Color3.new(60/255,60/255,60/255)
+ end)
+ verticalDragger.MouseLeave:connect(function ()
+ verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255)
+ end)
+ verticalDragger.MouseButton1Down:connect(function(x,y)
+ draggingVertical = true
+ areaSoak.Visible = true
+ startYPos = y
+ end)
+ areaSoak.MouseButton1Up:connect(function ( )
+ draggingVertical = false
+ areaSoak.Visible = false
+ end)
+ areaSoak.MouseMoved:connect(function(x,y)
+ if not draggingVertical then return end
+
+ local yDelta = y - startYPos
+ if not control.ScrollDownButton.Visible and yDelta > 0 then
+ return
+ end
+
+ if (widgetContainer.Size.Y.Offset + yDelta) < 150 then
+ widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,150)
+ control.Size = UDim2.new (0,21,0,150)
+ return
+ end
+
+ startYPos = y
+
+ if widgetContainer.Size.Y.Offset + yDelta >= 0 then
+ widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,widgetContainer.Size.Y.Offset + yDelta)
+ control.Size = UDim2.new(0,21,0,control.Size.Y.Offset + yDelta )
+ end
+ end)
+ end
+
+ local function switchMinimize()
+ minimizeFrame.Visible = not minimizeFrame.Visible
+ if scrollable then
+ frame.Visible = not frame.Visible
+ verticalDragger.Visible = not verticalDragger.Visible
+ control.Visible = not control.Visible
+ else
+ widgetContainer.Visible = not widgetContainer.Visible
+ end
+
+ if minimizeFrame.Visible then
+ minimizeButton.Text = "+"
+ else
+ minimizeButton.Text = "-"
+ end
+ end
+
+ minimizeBigButton.MouseButton1Click:connect(function ( )
+ switchMinimize()
+ end)
+
+ minimizeButton.MouseButton1Click:connect(function( )
+ switchMinimize()
+ end)
+
+ if scrollable then
+ return dragBar, frame, helpFrame, closeEvent
+ else
+ return dragBar, widgetContainer, helpFrame, closeEvent
+ end
+end
+
+t.Help =
+ function(funcNameOrFunc)
+ --input argument can be a string or a function. Should return a description (of arguments and expected side effects)
+ if funcNameOrFunc == "CreatePropertyDropDownMenu" or funcNameOrFunc == t.CreatePropertyDropDownMenu then
+ return "Function CreatePropertyDropDownMenu. " ..
+ "Arguments: (instance, propertyName, enumType). " ..
+ "Side effect: returns a container with a drop-down-box that is linked to the 'property' field of 'instance' which is of type 'enumType'"
+ end
+ if funcNameOrFunc == "CreateDropDownMenu" or funcNameOrFunc == t.CreateDropDownMenu then
+ return "Function CreateDropDownMenu. " ..
+ "Arguments: (items, onItemSelected). " ..
+ "Side effect: Returns 2 results, a container to the gui object and a 'updateSelection' function for external updating. The container is a drop-down-box created around a list of items"
+ end
+ if funcNameOrFunc == "CreateMessageDialog" or funcNameOrFunc == t.CreateMessageDialog then
+ return "Function CreateMessageDialog. " ..
+ "Arguments: (title, message, buttons). " ..
+ "Side effect: Returns a gui object of a message box with 'title' and 'message' as passed in. 'buttons' input is an array of Tables contains a 'Text' and 'Function' field for the text/callback of each button"
+ end
+ if funcNameOrFunc == "CreateStyledMessageDialog" or funcNameOrFunc == t.CreateStyledMessageDialog then
+ return "Function CreateStyledMessageDialog. " ..
+ "Arguments: (title, message, style, buttons). " ..
+ "Side effect: Returns a gui object of a message box with 'title' and 'message' as passed in. 'buttons' input is an array of Tables contains a 'Text' and 'Function' field for the text/callback of each button, 'style' is a string, either Error, Notify or Confirm"
+ end
+ if funcNameOrFunc == "GetFontHeight" or funcNameOrFunc == t.GetFontHeight then
+ return "Function GetFontHeight. " ..
+ "Arguments: (font, fontSize). " ..
+ "Side effect: returns the size in pixels of the given font + fontSize"
+ end
+ if funcNameOrFunc == "LayoutGuiObjects" or funcNameOrFunc == t.LayoutGuiObjects then
+
+ end
+ if funcNameOrFunc == "CreateScrollingFrame" or funcNameOrFunc == t.CreateScrollingFrame then
+ return "Function CreateScrollingFrame. " ..
+ "Arguments: (orderList, style) " ..
+ "Side effect: returns 4 objects, (scrollFrame, scrollUpButton, scrollDownButton, recalculateFunction). 'scrollFrame' can be filled with GuiObjects. It will lay them out and allow scrollUpButton/scrollDownButton to interact with them. Orderlist is optional (and specifies the order to layout the children. Without orderlist, it uses the children order. style is also optional, and allows for a 'grid' styling if style is passed 'grid' as a string. recalculateFunction can be called when a relayout is needed (when orderList changes)"
+ end
+ if funcNameOrFunc == "CreateTrueScrollingFrame" or funcNameOrFunc == t.CreateTrueScrollingFrame then
+ return "Function CreateTrueScrollingFrame. " ..
+ "Arguments: (nil) " ..
+ "Side effect: returns 2 objects, (scrollFrame, controlFrame). 'scrollFrame' can be filled with GuiObjects, and they will be clipped if not inside the frame's bounds. controlFrame has children scrollup and scrolldown, as well as a slider. controlFrame can be parented to any guiobject and it will readjust itself to fit."
+ end
+ if funcNameOrFunc == "AutoTruncateTextObject" or funcNameOrFunc == t.AutoTruncateTextObject then
+ return "Function AutoTruncateTextObject. " ..
+ "Arguments: (textLabel) " ..
+ "Side effect: returns 2 objects, (textLabel, changeText). The 'textLabel' input is modified to automatically truncate text (with ellipsis), if it gets too small to fit. 'changeText' is a function that can be used to change the text, it takes 1 string as an argument"
+ end
+ if funcNameOrFunc == "CreateSlider" or funcNameOrFunc == t.CreateSlider then
+ return "Function CreateSlider. " ..
+ "Arguments: (steps, width, position) " ..
+ "Side effect: returns 2 objects, (sliderGui, sliderPosition). The 'steps' argument specifies how many different positions the slider can hold along the bar. 'width' specifies in pixels how wide the bar should be (modifiable afterwards if desired). 'position' argument should be a UDim2 for slider positioning. 'sliderPosition' is an IntValue whose current .Value specifies the specific step the slider is currently on."
+ end
+ if funcNameOrFunc == "CreateSliderNew" or funcNameOrFunc == t.CreateSliderNew then
+ return "Function CreateSliderNew. " ..
+ "Arguments: (steps, width, position) " ..
+ "Side effect: returns 2 objects, (sliderGui, sliderPosition). The 'steps' argument specifies how many different positions the slider can hold along the bar. 'width' specifies in pixels how wide the bar should be (modifiable afterwards if desired). 'position' argument should be a UDim2 for slider positioning. 'sliderPosition' is an IntValue whose current .Value specifies the specific step the slider is currently on."
+ end
+ if funcNameOrFunc == "CreateLoadingFrame" or funcNameOrFunc == t.CreateLoadingFrame then
+ return "Function CreateLoadingFrame. " ..
+ "Arguments: (name, size, position) " ..
+ "Side effect: Creates a gui that can be manipulated to show progress for a particular action. Name appears above the loading bar, and size and position are udim2 values (both size and position are optional arguments). Returns 3 arguments, the first being the gui created. The second being updateLoadingGuiPercent, which is a bindable function. This function takes one argument (two optionally), which should be a number between 0 and 1, representing the percentage the loading gui should be at. The second argument to this function is a boolean value that if set to true will tween the current percentage value to the new percentage value, therefore our third argument is how long this tween should take. Our third returned argument is a BindableEvent, that when fired means that someone clicked the cancel button on the dialog."
+ end
+ if funcNameOrFunc == "CreateTerrainMaterialSelector" or funcNameOrFunc == t.CreateTerrainMaterialSelector then
+ return "Function CreateTerrainMaterialSelector. " ..
+ "Arguments: (size, position) " ..
+ "Side effect: Size and position are UDim2 values that specifies the selector's size and position. Both size and position are optional arguments. This method returns 3 objects (terrainSelectorGui, terrainSelected, forceTerrainSelection). terrainSelectorGui is just the gui object that we generate with this function, parent it as you like. TerrainSelected is a BindableEvent that is fired whenever a new terrain type is selected in the gui. ForceTerrainSelection is a function that takes an argument of Enum.CellMaterial and will force the gui to show that material as currently selected."
+ end
+ end
+
+
+local function waitForChild(instance, name)
+ while not instance:FindFirstChild(name) do
+ instance.ChildAdded:wait()
+ end
+end
+
+local function waitForProperty(instance, property)
+ while not instance[property] do
+ instance.Changed:wait()
+ end
+end
+
+-- A Few Script Globals
+local gui = script.Parent.ControlFrame
+
+local helpButton = nil
+local updateCameraDropDownSelection = nil
+local updateVideoCaptureDropDownSelection = nil
+local tweenTime = 0.2
+
+local mouseLockLookScreenUrl = "http://www.roblox.com/asset?id=54071825"
+local classicLookScreenUrl = "http://www.roblox.com/Asset?id=45915798"
+
+local hasGraphicsSlider = yes
+local GraphicsQualityLevels = true
+local recordingVideo = false
+
+local currentMenuSelection = nil
+local lastMenuSelection = {}
+
+local defaultPosition = UDim2.new(0,0,0,0)
+local newGuiPlaces = {0,41324860}
+
+local centerDialogs = {}
+local mainShield = nil
+
+local inStudioMode = false
+
+local macClient = false
+local success, isMac = pcall(function() return not game.GuiService.IsWindows end)
+macClient = success and isMac
+
+local function Color3I(r,g,b)
+ return Color3.new(r/255,g/255,b/255)
+end
+
+local function robloxLock(instance)
+end
+
+function resumeGameFunction(shield)
+ shield.Settings:TweenPosition(UDim2.new(0.5, -262,-0.5, -200),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
+ delay(tweenTime,function()
+ shield.Visible = false
+ for i = 1, #centerDialogs do
+ centerDialogs[i].Visible = false
+ game.GuiService:RemoveCenterDialog(centerDialogs[i])
+ end
+
+ settingsButton.Active = true
+ currentMenuSelection = nil
+ lastMenuSelection = {}
+ end)
+end
+
+function goToMenu(container,menuName, moveDirection,size,position)
+ if type(menuName) ~= "string" then return end
+
+ table.insert(lastMenuSelection,currentMenuSelection)
+ if menuName == "GameMainMenu" then
+ lastMenuSelection = {}
+ end
+
+ local containerChildren = container:GetChildren()
+ local selectedMenu = false
+ for i = 1, #containerChildren do
+ if containerChildren[i].Name == menuName then
+ containerChildren[i].Visible = true
+ currentMenuSelection = {container = container,name = menuName, direction = moveDirection, lastSize = size}
+ selectedMenu = true
+ if size and position then
+ containerChildren[i]:TweenSizeAndPosition(size,position,Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
+ elseif size then
+ containerChildren[i]:TweenSizeAndPosition(size,UDim2.new(0.5,-size.X.Offset/2,0.5,-size.Y.Offset/2),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
+ else
+ containerChildren[i]:TweenPosition(UDim2.new(0,0,0,0),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
+ end
+ else
+ if moveDirection == "left" then
+ containerChildren[i]:TweenPosition(UDim2.new(-1,-525,0,0),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
+ elseif moveDirection == "right" then
+ containerChildren[i]:TweenPosition(UDim2.new(1,525,0,0),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
+ elseif moveDirection == "up" then
+ containerChildren[i]:TweenPosition(UDim2.new(0,0,-1,-400),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
+ elseif moveDirection == "down" then
+ containerChildren[i]:TweenPosition(UDim2.new(0,0,1,400),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
+ end
+ delay(tweenTime,function()
+ containerChildren[i].Visible = false
+ end)
+ end
+ end
+end
+
+function resetLocalCharacter()
+ local player = game.Players.LocalPlayer
+ if player then
+ if player.Character and player.Character:FindFirstChild("Humanoid") then
+ player.Character.Humanoid.Health = 0
+ end
+ end
+end
+
+local function createTextButton(text,style,fontSize,buttonSize,buttonPosition)
+ local newTextButton = Instance.new("TextButton")
+ newTextButton.Font = Enum.Font.Arial
+ newTextButton.FontSize = fontSize
+ newTextButton.Size = buttonSize
+ newTextButton.Position = buttonPosition
+ newTextButton.Style = style
+ newTextButton.TextColor3 = Color3.new(1,1,1)
+ newTextButton.Text = text
+ return newTextButton
+end
+
+local function CreateTextButtons(frame, buttons, yPos, ySize)
+ if #buttons < 1 then
+ error("Must have more than one button")
+ end
+
+ local buttonNum = 1
+ local buttonObjs = {}
+
+ local function toggleSelection(button)
+ for i, obj in ipairs(buttonObjs) do
+ if obj == button then
+ obj.Style = Enum.ButtonStyle.RobloxButtonDefault
+ else
+ obj.Style = Enum.ButtonStyle.RobloxButton
+ end
+ end
+ end
+
+ for i, obj in ipairs(buttons) do
+ local button = Instance.new("TextButton")
+ button.Name = "Button" .. buttonNum
+ button.Font = Enum.Font.Arial
+ button.FontSize = Enum.FontSize.Size18
+ button.AutoButtonColor = true
+ button.Style = Enum.ButtonStyle.RobloxButton
+ button.Text = obj.Text
+ button.TextColor3 = Color3.new(1,1,1)
+ button.MouseButton1Click:connect(function() toggleSelection(button) obj.Function() end)
+ button.Parent = frame
+ buttonObjs[buttonNum] = button
+
+ buttonNum = buttonNum + 1
+ end
+
+ toggleSelection(buttonObjs[1])
+
+ local numButtons = buttonNum-1
+
+ if numButtons == 1 then
+ frame.Button1.Position = UDim2.new(0.35, 0, yPos.Scale, yPos.Offset)
+ frame.Button1.Size = UDim2.new(.4,0,ySize.Scale, ySize.Offset)
+ elseif numButtons == 2 then
+ frame.Button1.Position = UDim2.new(0.1, 0, yPos.Scale, yPos.Offset)
+ frame.Button1.Size = UDim2.new(.35,0, ySize.Scale, ySize.Offset)
+
+ frame.Button2.Position = UDim2.new(0.55, 0, yPos.Scale, yPos.Offset)
+ frame.Button2.Size = UDim2.new(.35,0, ySize.Scale, ySize.Offset)
+ elseif numButtons >= 3 then
+ local spacing = .1 / numButtons
+ local buttonSize = .9 / numButtons
+
+ buttonNum = 1
+ while buttonNum <= numButtons do
+ buttonObjs[buttonNum].Position = UDim2.new(spacing*buttonNum + (buttonNum-1) * buttonSize, 0, yPos.Scale, yPos.Offset)
+ buttonObjs[buttonNum].Size = UDim2.new(buttonSize, 0, ySize.Scale, ySize.Offset)
+ buttonNum = buttonNum + 1
+ end
+ end
+end
+
+function setRecordGui(recording, stopRecordButton, recordVideoButton)
+ if recording then
+ stopRecordButton.Visible = true
+ recordVideoButton.Text = "Stop Recording"
+ else
+ stopRecordButton.Visible = false
+ recordVideoButton.Text = "Record Video"
+ end
+end
+
+function recordVideoClick(recordVideoButton, stopRecordButton)
+ recordingVideo = not recordingVideo
+ setRecordGui(recordingVideo, stopRecordButton, recordVideoButton)
+end
+
+function backToGame(buttonClicked, shield, settingsButton)
+ buttonClicked.Parent.Parent.Parent.Parent.Visible = false
+ shield.Visible = false
+ for i = 1, #centerDialogs do
+ game.GuiService:RemoveCenterDialog(centerDialogs[i])
+ centerDialogs[i].Visible = false
+ end
+ centerDialogs = {}
+ game.GuiService:RemoveCenterDialog(shield)
+ settingsButton.Active = true
+end
+
+function setDisabledState(guiObject)
+ if not guiObject then return end
+
+ if guiObject:IsA("TextLabel") then
+ guiObject.TextTransparency = 0.9
+ elseif guiObject:IsA("TextButton") then
+ guiObject.TextTransparency = 0.9
+ guiObject.Active = false
+ else
+ if guiObject["ClassName"] then
+ print("setDisabledState() got object of unsupported type. object type is ",guiObject.ClassName)
+ end
+ end
+end
+
+local function createHelpDialog(baseZIndex)
+
+ if helpButton == nil then
+ if gui:FindFirstChild("TopLeftControl") and gui.TopLeftControl:FindFirstChild("Help") then
+ helpButton = gui.TopLeftControl.Help
+ elseif gui:FindFirstChild("BottomRightControl") and gui.BottomRightControl:FindFirstChild("Help") then
+ helpButton = gui.BottomRightControl.Help
+ end
+ end
+
+ local shield = Instance.new("Frame")
+ shield.Name = "HelpDialogShield"
+ shield.Active = true
+ shield.Visible = false
+ shield.Size = UDim2.new(1,0,1,0)
+ shield.BackgroundColor3 = Color3I(51,51,51)
+ shield.BorderColor3 = Color3I(27,42,53)
+ shield.BackgroundTransparency = 0.4
+ shield.ZIndex = baseZIndex + 1
+ shield.Parent = gui
+
+ local helpDialog = Instance.new("Frame")
+ helpDialog.Name = "HelpDialog"
+ helpDialog.Style = Enum.FrameStyle.RobloxRound
+ helpDialog.Position = UDim2.new(.2, 0, .2, 0)
+ helpDialog.Size = UDim2.new(0.6, 0, 0.6, 0)
+ helpDialog.Active = true
+ helpDialog.Parent = shield
+
+ local titleLabel = Instance.new("TextLabel")
+ titleLabel.Name = "Title"
+ titleLabel.Text = "Keyboard & Mouse Controls"
+ titleLabel.Font = Enum.Font.ArialBold
+ titleLabel.FontSize = Enum.FontSize.Size36
+ titleLabel.Position = UDim2.new(0, 0, 0.025, 0)
+ titleLabel.Size = UDim2.new(1, 0, 0, 40)
+ titleLabel.TextColor3 = Color3.new(1,1,1)
+ titleLabel.BackgroundTransparency = 1
+ titleLabel.Parent = helpDialog
+
+ local buttonRow = Instance.new("Frame")
+ buttonRow.Name = "Buttons"
+ buttonRow.Position = UDim2.new(0.1, 0, .07, 40)
+ buttonRow.Size = UDim2.new(0.8, 0, 0, 45)
+ buttonRow.BackgroundTransparency = 1
+ buttonRow.Parent = helpDialog
+
+ local imageFrame = Instance.new("Frame")
+ imageFrame.Name = "ImageFrame"
+ imageFrame.Position = UDim2.new(0.05, 0, 0.075, 80)
+ imageFrame.Size = UDim2.new(0.9, 0, .9, -120)
+ imageFrame.BackgroundTransparency = 1
+ imageFrame.Parent = helpDialog
+
+ local layoutFrame = Instance.new("Frame")
+ layoutFrame.Name = "LayoutFrame"
+ layoutFrame.Position = UDim2.new(0.5, 0, 0, 0)
+ layoutFrame.Size = UDim2.new(1.5, 0, 1, 0)
+ layoutFrame.BackgroundTransparency = 1
+ layoutFrame.SizeConstraint = Enum.SizeConstraint.RelativeYY
+ layoutFrame.Parent = imageFrame
+
+ local image = Instance.new("ImageLabel")
+ image.Name = "Image"
+ image.Image = classicLookScreenUrl
+ image.Position = UDim2.new(-0.5, 0, 0, 0)
+ image.Size = UDim2.new(1, 0, 1, 0)
+ image.BackgroundTransparency = 1
+ image.Parent = layoutFrame
+
+ local buttons = {}
+ buttons[1] = {}
+ buttons[1].Text = "Look"
+ buttons[1].Function = function()
+ if UserSettings().GameSettings.ControlMode == Enum.ControlMode["Mouse Lock Switch"] then
+ image.Image = mouseLockLookScreenUrl
+ else
+ image.Image = classicLookScreenUrl
+ end
+ end
+ buttons[2] = {}
+ buttons[2].Text = "Move"
+ buttons[2].Function = function()
+ image.Image = "http://www.roblox.com/Asset?id=45915811"
+ end
+ buttons[3] = {}
+ buttons[3].Text = "Gear"
+ buttons[3].Function = function()
+ image.Image = "http://www.roblox.com/Asset?id=45917596"
+ end
+ buttons[4] = {}
+ buttons[4].Text = "Zoom"
+ buttons[4].Function = function()
+ image.Image = "http://www.roblox.com/Asset?id=45915825"
+ end
+
+ CreateTextButtons(buttonRow, buttons, UDim.new(0, 0), UDim.new(1,0))
+
+
+ -- set up listeners for type of mouse mode, but keep constructing gui at same time
+ delay(0, function()
+ waitForChild(gui,"UserSettingsShield")
+ waitForChild(gui.UserSettingsShield,"Settings")
+ waitForChild(gui.UserSettingsShield.Settings,"SettingsStyle")
+ waitForChild(gui.UserSettingsShield.Settings.SettingsStyle, "GameSettingsMenu")
+ waitForChild(gui.UserSettingsShield.Settings.SettingsStyle.GameSettingsMenu, "CameraField")
+ waitForChild(gui.UserSettingsShield.Settings.SettingsStyle.GameSettingsMenu.CameraField, "DropDownMenuButton")
+ gui.UserSettingsShield.Settings.SettingsStyle.GameSettingsMenu.CameraField.DropDownMenuButton.Changed:connect(function(prop)
+ if prop ~= "Text" then return end
+ if buttonRow.Button1.Style == Enum.ButtonStyle.RobloxButtonDefault then -- only change if this is the currently selected panel
+ if gui.UserSettingsShield.Settings.SettingsStyle.GameSettingsMenu.CameraField.DropDownMenuButton.Text == "Classic" then
+ image.Image = classicLookScreenUrl
+ else
+ image.Image = mouseLockLookScreenUrl
+ end
+ end
+ end)
+ end)
+
+
+ local okBtn = Instance.new("TextButton")
+ okBtn.Name = "OkBtn"
+ okBtn.Text = "OK"
+ okBtn.Modal = true
+ okBtn.Size = UDim2.new(0.3, 0, 0, 45)
+ okBtn.Position = UDim2.new(0.35, 0, .975, -50)
+ okBtn.Font = Enum.Font.Arial
+ okBtn.FontSize = Enum.FontSize.Size18
+ okBtn.BackgroundTransparency = 1
+ okBtn.TextColor3 = Color3.new(1,1,1)
+ okBtn.Style = Enum.ButtonStyle.RobloxButtonDefault
+ okBtn.MouseButton1Click:connect(
+ function()
+ gui.HelpDialogShield.Visible = false
+ end)
+ okBtn.Parent = helpDialog
+
+
+ return shield
+end
+
+local function createLeaveConfirmationMenu(baseZIndex,shield)
+ local frame = Instance.new("Frame")
+ frame.Name = "LeaveConfirmationMenu"
+ frame.BackgroundTransparency = 1
+ frame.Size = UDim2.new(1,0,1,0)
+ frame.Position = UDim2.new(0,0,2,400)
+ frame.ZIndex = baseZIndex + 4
+
+ --[[local yesButton = createTextButton("Leave",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size24,UDim2.new(0,128,0,50),UDim2.new(0,313,0.8,0))
+ yesButton.Name = "YesButton"
+ yesButton.ZIndex = baseZIndex + 4
+ yesButton.Parent = frame
+ yesButton.Modal = --]]
+
+ local noButton = createTextButton("OK",Enum.ButtonStyle.RobloxButtonDefault,Enum.FontSize.Size24,UDim2.new(0,128,0,50),UDim2.new(0,200,0.8,0))
+ noButton.Name = "NoButton"
+ noButton.Parent = frame
+ noButton.ZIndex = baseZIndex + 4
+ noButton.MouseButton1Click:connect(function()
+ goToMenu(shield.Settings.SettingsStyle,"GameMainMenu","down",UDim2.new(0,525,0,430))
+ shield.Settings:TweenSize(UDim2.new(0,525,0,430),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
+ end)
+
+ local leaveText = Instance.new("TextLabel")
+ leaveText.Name = "LeaveText"
+ leaveText.Text = "Click the red X in the top right corner."
+ leaveText.Size = UDim2.new(1,0,0.8,0)
+ leaveText.TextWrap = true
+ leaveText.TextColor3 = Color3.new(1,1,1)
+ leaveText.Font = Enum.Font.ArialBold
+ leaveText.FontSize = Enum.FontSize.Size36
+ leaveText.BackgroundTransparency = 1
+ leaveText.ZIndex = baseZIndex + 4
+ leaveText.Parent = frame
+
+ return frame
+end
+
+local function createResetConfirmationMenu(baseZIndex,shield)
+ local frame = Instance.new("Frame")
+ frame.Name = "ResetConfirmationMenu"
+ frame.BackgroundTransparency = 1
+ frame.Size = UDim2.new(1,0,1,0)
+ frame.Position = UDim2.new(0,0,2,400)
+ frame.ZIndex = baseZIndex + 4
+ frame.Parent = gui
+
+
+ local yesButton = createTextButton("Reset",Enum.ButtonStyle.RobloxButtonDefault,Enum.FontSize.Size24,UDim2.new(0,128,0,50),UDim2.new(0,313,0,299))
+ yesButton.Name = "YesButton"
+ yesButton.ZIndex = baseZIndex + 4
+ yesButton.Parent = frame
+ yesButton.Modal = true
+ yesButton.MouseButton1Click:connect(function()
+ resumeGameFunction(shield)
+ resetLocalCharacter()
+ end)
+
+ local noButton = createTextButton("Cancel",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size24,UDim2.new(0,128,0,50),UDim2.new(0,90,0,299))
+ noButton.Name = "NoButton"
+ noButton.Parent = frame
+ noButton.ZIndex = baseZIndex + 4
+ noButton.MouseButton1Click:connect(function()
+ goToMenu(shield.Settings.SettingsStyle,"GameMainMenu","down",UDim2.new(0,525,0,430))
+ shield.Settings:TweenSize(UDim2.new(0,525,0,430),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
+ end)
+
+ local resetCharacterText = Instance.new("TextLabel")
+ resetCharacterText.Name = "ResetCharacterText"
+ resetCharacterText.Text = "Are you sure you want to reset your character?"
+ resetCharacterText.Size = UDim2.new(1,0,0.8,0)
+ resetCharacterText.TextWrap = true
+ resetCharacterText.TextColor3 = Color3.new(1,1,1)
+ resetCharacterText.Font = Enum.Font.ArialBold
+ resetCharacterText.FontSize = Enum.FontSize.Size36
+ resetCharacterText.BackgroundTransparency = 1
+ resetCharacterText.ZIndex = baseZIndex + 4
+ resetCharacterText.Parent = frame
+
+ local fineResetCharacterText = resetCharacterText:Clone()
+ fineResetCharacterText.Name = "FineResetCharacterText"
+ fineResetCharacterText.Text = "You will be put back on a spawn point"
+ fineResetCharacterText.Size = UDim2.new(0,303,0,18)
+ fineResetCharacterText.Position = UDim2.new(0, 109, 0, 215)
+ fineResetCharacterText.FontSize = Enum.FontSize.Size18
+ fineResetCharacterText.Parent = frame
+
+ return frame
+end
+
+local function createGameMainMenu(baseZIndex, shield)
+ local gameMainMenuFrame = Instance.new("Frame")
+ gameMainMenuFrame.Name = "GameMainMenu"
+ gameMainMenuFrame.BackgroundTransparency = 1
+ gameMainMenuFrame.Size = UDim2.new(1,0,1,0)
+ gameMainMenuFrame.ZIndex = baseZIndex + 4
+ gameMainMenuFrame.Parent = script.Parent.UserSettingsShield.Settings.SettingsStyle
+
+ -- GameMainMenu Children
+
+ local gameMainMenuTitle = Instance.new("TextLabel")
+ gameMainMenuTitle.Name = "Title"
+ gameMainMenuTitle.Text = "Game Menu"
+ gameMainMenuTitle.BackgroundTransparency = 1
+ gameMainMenuTitle.TextStrokeTransparency = 0
+ gameMainMenuTitle.Font = Enum.Font.ArialBold
+ gameMainMenuTitle.FontSize = Enum.FontSize.Size36
+ gameMainMenuTitle.Size = UDim2.new(1,0,0,36)
+ gameMainMenuTitle.Position = UDim2.new(0,0,0,4)
+ gameMainMenuTitle.TextColor3 = Color3.new(1,1,1)
+ gameMainMenuTitle.ZIndex = baseZIndex + 4
+ gameMainMenuTitle.Parent = gameMainMenuFrame
+
+ local robloxHelpButton = createTextButton("Help",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size18,UDim2.new(0,164,0,50),UDim2.new(0,82,0,256))
+ robloxHelpButton.Name = "HelpButton"
+ robloxHelpButton.ZIndex = baseZIndex + 4
+ robloxHelpButton.Parent = gameMainMenuFrame
+ helpButton = robloxHelpButton
+
+ local helpDialog = createHelpDialog(baseZIndex)
+ helpDialog.Parent = gui
+
+ helpButton.MouseButton1Click:connect(
+ function()
+ helpDialog.Visible = true
+ mainShield.Visible = false
+ end)
+ helpButton.Active = true
+
+ local helpShortcut = Instance.new("TextLabel")
+ helpShortcut.Name = "HelpShortcutText"
+ helpShortcut.Text = "F1"
+ helpShortcut.Visible = false
+ helpShortcut.BackgroundTransparency = 1
+ helpShortcut.Font = Enum.Font.Arial
+ helpShortcut.FontSize = Enum.FontSize.Size12
+ helpShortcut.Position = UDim2.new(0,85,0,0)
+ helpShortcut.Size = UDim2.new(0,30,0,30)
+ helpShortcut.TextColor3 = Color3.new(0,1,0)
+ helpShortcut.ZIndex = baseZIndex + 4
+ helpShortcut.Parent = robloxHelpButton
+
+ local screenshotButton = createTextButton("Screenshot",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size18,UDim2.new(0,168,0,50),UDim2.new(0,254,0,256))
+ screenshotButton.Name = "ScreenshotButton"
+ screenshotButton.ZIndex = baseZIndex + 4
+ screenshotButton.Parent = shield.Settings.SettingsStyle.GameMainMenu
+ screenshotButton.Visible = not macClient
+
+ local screenshotShortcut = helpShortcut:clone()
+ screenshotShortcut.Name = "ScreenshotShortcutText"
+ screenshotShortcut.Text = "PrintSc"
+ screenshotShortcut.Position = UDim2.new(0,118,0,0)
+ screenshotShortcut.Visible = true
+ screenshotShortcut.Parent = screenshotButton
+
+
+ local recordVideoButton = createTextButton("Record Video",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size18,UDim2.new(0,168,0,50),UDim2.new(0,254,0,306))
+ recordVideoButton.Name = "RecordVideoButton"
+ recordVideoButton.ZIndex = baseZIndex + 4
+ recordVideoButton.Parent = gameMainMenuFrame
+ recordVideoButton.Visible = not macClient
+
+ local recordVideoShortcut = helpShortcut:clone()
+ recordVideoShortcut.Visible = hasGraphicsSlider
+ recordVideoShortcut.Name = "RecordVideoShortcutText"
+ recordVideoShortcut.Text = "F12"
+ recordVideoShortcut.Position = UDim2.new(0,120,0,0)
+ recordVideoShortcut.Parent = recordVideoButton
+
+ local stopRecordButton = Instance.new("ImageButton")
+ stopRecordButton.Name = "StopRecordButton"
+ stopRecordButton.BackgroundTransparency = 1
+ stopRecordButton.Image = "rbxasset://textures/ui/RecordStop.png"
+ stopRecordButton.Size = UDim2.new(0,59,0,27)
+
+
+ stopRecordButton.MouseButton1Click:connect(function() print("function removed cuz its a localscript noob") end)
+ stopRecordButton.Visible = false
+ stopRecordButton.Parent = gui
+
+ local reportAbuseButton = createTextButton("Report Abuse [W.I.P]",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size18,UDim2.new(0,164,0,50),UDim2.new(0,82,0,306))
+ reportAbuseButton.Name = "ReportAbuseButton"
+ reportAbuseButton.ZIndex = baseZIndex + 4
+ reportAbuseButton.Parent = gameMainMenuFrame
+ reportAbuseButton.Active = true
+
+ local leaveGameButton = createTextButton("Leave Game",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size24,UDim2.new(0,340,0,50),UDim2.new(0,82,0,358))
+ leaveGameButton.Name = "LeaveGameButton"
+ leaveGameButton.ZIndex = baseZIndex + 4
+ leaveGameButton.Parent = gameMainMenuFrame
+
+
+ local resumeGameButton = createTextButton("Resume Game",Enum.ButtonStyle.RobloxButtonDefault,Enum.FontSize.Size24,UDim2.new(0,340,0,50),UDim2.new(0,82,0,54))
+ resumeGameButton.Name = "resumeGameButton"
+ resumeGameButton.ZIndex = baseZIndex + 4
+ resumeGameButton.Parent = gameMainMenuFrame
+ resumeGameButton.Modal = true
+ resumeGameButton.MouseButton1Click:connect(function() resumeGameFunction(shield) end)
+
+ local gameSettingsButton = createTextButton("Game Settings",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size24,UDim2.new(0,340,0,50),UDim2.new(0,82,0,156))
+ gameSettingsButton.Name = "SettingsButton"
+ gameSettingsButton.ZIndex = baseZIndex + 4
+ gameSettingsButton.Parent = gameMainMenuFrame
+
+
+
+ if game:FindFirstChild("LoadingGuiService") and #game.LoadingGuiService:GetChildren() > 0 then
+ local gameSettingsButton = createTextButton("Game Instructions",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size24,UDim2.new(0,340,0,50),UDim2.new(0,82,0,207))
+ gameSettingsButton.Name = "GameInstructions"
+ gameSettingsButton.ZIndex = baseZIndex + 4
+ gameSettingsButton.Parent = gameMainMenuFrame
+ gameSettingsButton.MouseButton1Click:connect(function()
+ if game:FindFirstChild("Players") and game.Players["LocalPlayer"] then
+ local loadingGui = game.Players.LocalPlayer:FindFirstChild("PlayerLoadingGui")
+ if loadingGui then
+ loadingGui.Visible = true
+ end
+ end
+ end)
+ end
+
+ local resetButton = createTextButton("Reset Character",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size24,UDim2.new(0,340,0,50),UDim2.new(0,82,0,105))
+ resetButton.Name = "ResetButton"
+ resetButton.ZIndex = baseZIndex + 4
+ resetButton.Parent = gameMainMenuFrame
+
+ return gameMainMenuFrame
+end
+
+local function createGameSettingsMenu(baseZIndex, shield)
+ local gameSettingsMenuFrame = Instance.new("Frame")
+ gameSettingsMenuFrame.Name = "GameSettingsMenu"
+ gameSettingsMenuFrame.BackgroundTransparency = 1
+ gameSettingsMenuFrame.Size = UDim2.new(1,0,1,0)
+ gameSettingsMenuFrame.ZIndex = baseZIndex + 4
+
+ local title = Instance.new("TextLabel")
+ title.Name = "Title"
+ title.Text = "Settings"
+ title.Size = UDim2.new(1,0,0,48)
+ title.Position = UDim2.new(0,9,0,-9)
+ title.Font = Enum.Font.ArialBold
+ title.FontSize = Enum.FontSize.Size36
+ title.TextColor3 = Color3.new(1,1,1)
+ title.ZIndex = baseZIndex + 4
+ title.BackgroundTransparency = 1
+ title.Parent = gameSettingsMenuFrame
+
+ local fullscreenText = Instance.new("TextLabel")
+ fullscreenText.Name = "FullscreenText"
+ fullscreenText.Text = "Fullscreen Mode"
+ fullscreenText.Size = UDim2.new(0,124,0,18)
+ fullscreenText.Position = UDim2.new(0,62,0,145)
+ fullscreenText.Font = Enum.Font.Arial
+ fullscreenText.FontSize = Enum.FontSize.Size18
+ fullscreenText.TextColor3 = Color3.new(1,1,1)
+ fullscreenText.ZIndex = baseZIndex + 4
+ fullscreenText.BackgroundTransparency = 1
+ fullscreenText.Parent = gameSettingsMenuFrame
+
+ local fullscreenShortcut = Instance.new("TextLabel")
+ fullscreenShortcut.Visible = true
+ fullscreenShortcut.Name = "FullscreenShortcutText"
+ fullscreenShortcut.Text = "F11"
+ fullscreenShortcut.BackgroundTransparency = 1
+ fullscreenShortcut.Font = Enum.Font.Arial
+ fullscreenShortcut.FontSize = Enum.FontSize.Size12
+ fullscreenShortcut.Position = UDim2.new(0,186,0,141)
+ fullscreenShortcut.Size = UDim2.new(0,30,0,30)
+ fullscreenShortcut.TextColor3 = Color3.new(0,1,0)
+ fullscreenShortcut.ZIndex = baseZIndex + 4
+ fullscreenShortcut.Parent = gameSettingsMenuFrame
+
+ local fullscreenCheckbox = createTextButton("",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size18,UDim2.new(0,25,0,25),UDim2.new(0,30,0,144))
+ fullscreenCheckbox.Name = "FullscreenCheckbox"
+ fullscreenCheckbox.ZIndex = baseZIndex + 4
+ fullscreenCheckbox.Parent = gameSettingsMenuFrame
+
+ local studioText = Instance.new("TextLabel")
+ studioText.Visible = false
+ studioText.Name = "StudioText"
+ studioText.Text = "Studio Mode"
+ studioText.Size = UDim2.new(0,95,0,18)
+ studioText.Position = UDim2.new(0,62,0,179)
+ studioText.Font = Enum.Font.Arial
+ studioText.FontSize = Enum.FontSize.Size18
+ studioText.TextColor3 = Color3.new(1,1,1)
+ studioText.ZIndex = baseZIndex + 4
+ studioText.BackgroundTransparency = 1
+ studioText.Parent = gameSettingsMenuFrame
+
+ local studioShortcut = fullscreenShortcut:clone()
+ studioShortcut.Name = "StudioShortcutText"
+ studioShortcut.Visible = false -- TODO: turn back on when f2 hack is fixed
+ studioShortcut.Text = "F2"
+ studioShortcut.Position = UDim2.new(0,154,0,175)
+ studioShortcut.Parent = gameSettingsMenuFrame
+
+ local studioCheckbox = nil
+
+ if studioCheckbox == nil then
+ local qualityText = Instance.new("TextLabel")
+ qualityText.Name = "QualityText"
+ qualityText.Text = "Graphics Quality"
+ qualityText.Size = UDim2.new(0,128,0,18)
+ qualityText.Position = UDim2.new(0,30,0,239)
+ qualityText.Font = Enum.Font.Arial
+ qualityText.FontSize = Enum.FontSize.Size18
+ qualityText.TextColor3 = Color3.new(1,1,1)
+ qualityText.ZIndex = baseZIndex + 4
+ qualityText.BackgroundTransparency = 1
+ qualityText.Parent = gameSettingsMenuFrame
+ qualityText.Visible = true
+
+ local autoText = qualityText:clone()
+ autoText.Name = "AutoText"
+ autoText.Text = "Auto"
+ autoText.Position = UDim2.new(0,183,0,214)
+ autoText.TextColor3 = Color3.new(128/255,128/255,128/255)
+ autoText.Size = UDim2.new(0,34,0,18)
+ autoText.Parent = gameSettingsMenuFrame
+ autoText.Visible = not inStudioMode
+
+ local fasterText = autoText:clone()
+ fasterText.Name = "FasterText"
+ fasterText.Text = "Faster"
+ fasterText.Position = UDim2.new(0,185,0,274)
+ fasterText.TextColor3 = Color3.new(95,95,95)
+ fasterText.FontSize = Enum.FontSize.Size14
+ fasterText.Parent = gameSettingsMenuFrame
+ fasterText.Visible = not inStudioMode
+
+ local fasterShortcut = fullscreenShortcut:clone()
+ fasterShortcut.Name = "FasterShortcutText"
+ fasterShortcut.Text = "F10 + Shift"
+ fasterShortcut.Position = UDim2.new(0,185,0,283)
+ fasterShortcut.Parent = gameSettingsMenuFrame
+ fasterShortcut.Visible = not inStudioMode
+
+ local betterQualityText = autoText:clone()
+ betterQualityText.Name = "BetterQualityText"
+ betterQualityText.Text = "Better Quality"
+ betterQualityText.TextWrap = true
+ betterQualityText.Size = UDim2.new(0,41,0,28)
+ betterQualityText.Position = UDim2.new(0,390,0,269)
+ betterQualityText.TextColor3 = Color3.new(95,95,95)
+ betterQualityText.FontSize = Enum.FontSize.Size14
+ betterQualityText.Parent = gameSettingsMenuFrame
+ betterQualityText.Visible = not inStudioMode
+
+ local betterQualityShortcut = fullscreenShortcut:clone()
+ betterQualityShortcut.Name = "BetterQualityShortcut"
+ betterQualityShortcut.Text = "F10"
+ betterQualityShortcut.Position = UDim2.new(0,394,0,288)
+ betterQualityShortcut.Parent = gameSettingsMenuFrame
+ betterQualityShortcut.Visible = not inStudioMode
+
+ local autoGraphicsButton = createTextButton("X",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size18,UDim2.new(0,25,0,25),UDim2.new(0,187,0,239))
+ autoGraphicsButton.Name = "AutoGraphicsButton"
+ autoGraphicsButton.ZIndex = baseZIndex + 4
+ autoGraphicsButton.Parent = gameSettingsMenuFrame
+ autoGraphicsButton.Visible = not inStudioMode
+
+ local graphicsSlider, graphicsLevel = RbxGui.CreateSlider(GraphicsQualityLevels,150,UDim2.new(0, 230, 0, 280)) -- graphics - 1 because slider starts at 1 instead of 0
+ graphicsSlider.Parent = gameSettingsMenuFrame
+ graphicsSlider.Bar.ZIndex = baseZIndex + 4
+ graphicsSlider.Bar.Slider.ZIndex = baseZIndex + 5
+ graphicsSlider.Visible = not inStudioMode
+
+ local graphicsSetter = Instance.new("TextBox")
+ graphicsSetter.Name = "GraphicsSetter"
+ graphicsSetter.BackgroundColor3 = Color3.new(0,0,0)
+ graphicsSetter.BorderColor3 = Color3.new(128/255,128/255,128/255)
+ graphicsSetter.Size = UDim2.new(0,50,0,25)
+ graphicsSetter.Position = UDim2.new(0,450,0,269)
+ graphicsSetter.TextColor3 = Color3.new(1,1,1)
+ graphicsSetter.Font = Enum.Font.Arial
+ graphicsSetter.FontSize = Enum.FontSize.Size18
+ graphicsSetter.Text = "Auto"
+ graphicsSetter.ZIndex = 1
+ graphicsSetter.TextWrap = true
+ graphicsSetter.Parent = gameSettingsMenuFrame
+ graphicsSetter.Visible = false
+
+ local listenToGraphicsLevelChange = false
+
+ local function setAutoGraphicsGui(active)
+ isAutoGraphics = active
+ if active then
+ autoGraphicsButton.Text = "X"
+ betterQualityText.ZIndex = 1
+ betterQualityShortcut.ZIndex = 1
+ fasterShortcut.ZIndex = 1
+ fasterText.ZIndex = 1
+ graphicsSlider.Bar.ZIndex = 1
+ graphicsSlider.Bar.Slider.ZIndex = 1
+ graphicsSetter.ZIndex = 1
+ graphicsSetter.Text = "Auto"
+ else
+ autoGraphicsButton.Text = ""
+ graphicsSlider.Bar.ZIndex = baseZIndex + 4
+ graphicsSlider.Bar.Slider.ZIndex = baseZIndex + 5
+ betterQualityShortcut.ZIndex = baseZIndex + 4
+ fasterShortcut.ZIndex = baseZIndex + 4
+ betterQualityText.ZIndex = baseZIndex + 4
+ fasterText.ZIndex = baseZIndex + 4
+ graphicsSetter.ZIndex = baseZIndex + 4
+ end
+ end
+
+ local function goToAutoGraphics()
+ setAutoGraphicsGui(true)
+
+ UserSettings().GameSettings.SavedQualityLevel = Enum.SavedQualitySetting.Automatic
+
+ settings().Rendering.QualityLevel = Enum.QualityLevel.Automatic
+ end
+
+ local function setGraphicsQualityLevel(newLevel)
+ local percentage = newLevel/GraphicsQualityLevels
+ local newSetting = math.floor((settings().Rendering:GetMaxQualityLevel() - 1) * percentage)
+ if newSetting == 20 then -- Level 20 is the same as level 21, except it doesn't render ambient occlusion
+ newSetting = 21
+ elseif newLevel == 1 then -- make sure we can go to lowest settings (for terrible computers)
+ newSetting = 1
+ elseif newSetting > settings().Rendering:GetMaxQualityLevel() then
+ newSetting = settings().Rendering:GetMaxQualityLevel() - 1
+ end
+
+ UserSettings().GameSettings.SavedQualityLevel = newLevel
+ settings().Rendering.QualityLevel = newSetting
+ end
+
+ local function goToManualGraphics(explicitLevel)
+ setAutoGraphicsGui(false)
+
+ if explicitLevel then
+ graphicsLevel.Value = explicitLevel
+ else
+ graphicsLevel.Value = math.floor((settings().Rendering.AutoFRMLevel/(settings().Rendering:GetMaxQualityLevel() - 1)) * GraphicsQualityLevels)
+ end
+
+ if explicitLevel == graphicsLevel.Value then -- make sure we are actually in right graphics mode
+ setGraphicsQualityLevel(graphicsLevel.Value)
+ end
+
+ if not explicitLevel then
+ UserSettings().GameSettings.SavedQualityLevel = graphicsLevel.Value
+ end
+ graphicsSetter.Text = tostring(graphicsLevel.Value)
+ end
+
+ local function showAutoGraphics()
+ autoText.ZIndex = baseZIndex + 4
+ autoGraphicsButton.ZIndex = baseZIndex + 4
+ end
+
+ local function hideAutoGraphics()
+ autoText.ZIndex = 1
+ autoGraphicsButton.ZIndex = 1
+ end
+
+ local function showManualGraphics()
+ graphicsSlider.Bar.ZIndex = baseZIndex + 4
+ graphicsSlider.Bar.Slider.ZIndex = baseZIndex + 5
+ betterQualityShortcut.ZIndex = baseZIndex + 4
+ fasterShortcut.ZIndex = baseZIndex + 4
+ betterQualityText.ZIndex = baseZIndex + 4
+ fasterText.ZIndex = baseZIndex + 4
+ graphicsSetter.ZIndex = baseZIndex + 4
+ end
+
+ local function hideManualGraphics()
+ betterQualityText.ZIndex = 1
+ betterQualityShortcut.ZIndex = 1
+ fasterShortcut.ZIndex = 1
+ fasterText.ZIndex = 1
+ graphicsSlider.Visible = false
+ graphicsSlider.Bar.ZIndex = 1
+ graphicsSlider.Bar.Slider.ZIndex = 1
+ graphicsSetter.ZIndex = 1
+ end
+
+ local function translateSavedQualityLevelToInt(savedQualityLevel)
+ if savedQualityLevel == Enum.SavedQualitySetting.Automatic then
+ return 0
+ elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel1 then
+ return 1
+ elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel2 then
+ return 2
+ elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel3 then
+ return 3
+ elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel4 then
+ return 4
+ elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel5 then
+ return 5
+ elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel6 then
+ return 6
+ elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel7 then
+ return 7
+ elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel8 then
+ return 8
+ elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel9 then
+ return 9
+ elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel10 then
+ return 10
+ end
+ end
+
+ local function enableGraphicsWidget()
+ settings().Rendering.EnableFRM = true
+
+ isAutoGraphics = (UserSettings().GameSettings.SavedQualityLevel == Enum.SavedQualitySetting.Automatic)
+ if isAutoGraphics then
+ showAutoGraphics()
+ goToAutoGraphics()
+ else
+ showAutoGraphics()
+ showManualGraphics()
+ goToManualGraphics(translateSavedQualityLevelToInt(UserSettings().GameSettings.SavedQualityLevel))
+ end
+ end
+
+ local function disableGraphicsWidget()
+ hideManualGraphics()
+ hideAutoGraphics()
+ settings().Rendering.EnableFRM = false
+ end
+
+ graphicsSetter.FocusLost:connect(function()
+ if isAutoGraphics then
+ graphicsSetter.Text = tostring(graphicsLevel.Value)
+ return
+ end
+
+ local newGraphicsValue = tonumber(graphicsSetter.Text)
+ if newGraphicsValue == nil then
+ graphicsSetter.Text = tostring(graphicsLevel.Value)
+ return
+ end
+
+ if newGraphicsValue < 1 then newGraphicsValue = 1
+ elseif newGraphicsValue >= settings().Rendering:GetMaxQualityLevel() then
+ newGraphicsValue = settings().Rendering:GetMaxQualityLevel() - 1
+ end
+
+ graphicsLevel.Value = newGraphicsValue
+ setGraphicsQualityLevel(graphicsLevel.Value)
+ graphicsSetter.Text = tostring(graphicsLevel.Value)
+ end)
+
+ graphicsLevel.Changed:connect(function(prop)
+ if isAutoGraphics then return end
+ if not listenToGraphicsLevelChange then return end
+
+ graphicsSetter.Text = tostring(graphicsLevel.Value)
+ setGraphicsQualityLevel(graphicsLevel.Value)
+ end)
+
+ -- setup our graphic mode on load
+
+
+
+
+ game.Players.PlayerAdded:connect(function(player)
+ if player == game.Players.LocalPlayer and inStudioMode then
+ enableGraphicsWidget()
+ end
+ end)
+ game.Players.PlayerRemoving:connect(function(player)
+ if player == game.Players.LocalPlayer and inStudioMode then
+ disableGraphicsWidget()
+ end
+ end)
+
+
+ studioCheckbox = createTextButton("",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size18,UDim2.new(0,25,0,25),UDim2.new(0,30,0,176))
+ studioCheckbox.Name = "StudioCheckbox"
+ studioCheckbox.ZIndex = baseZIndex + 4
+ --studioCheckbox.Parent = gameSettingsMenuFrame -- todo: enable when studio h4x aren't an issue anymore
+ studioCheckbox.Visible = false -- todo: enabled when studio h4x aren't an issue anymore
+
+ if hasGraphicsSlider then
+ UserSettings().GameSettings.StudioModeChanged:connect(function(isStudioMode)
+ inStudioMode = isStudioMode
+ if isStudioMode then
+ wasManualGraphics = (settings().Rendering.QualityLevel ~= Enum.QualityLevel.Automatic)
+ goToAutoGraphics()
+ studioCheckbox.Text = "X"
+ autoGraphicsButton.ZIndex = 1
+ autoText.ZIndex = 1
+ else
+ if wasManualGraphics then
+ goToManualGraphics()
+ end
+ studioCheckbox.Text = ""
+ autoGraphicsButton.ZIndex = baseZIndex + 4
+ autoText.ZIndex = baseZIndex + 4
+ end
+ end)
+ else
+ studioCheckbox.MouseButton1Click:connect(function()
+ if not studioCheckbox.Active then return end
+
+ if studioCheckbox.Text == "" then
+ studioCheckbox.Text = "X"
+ else
+ studioCheckbox.Text = ""
+ end
+ end)
+ end
+ end
+
+ if game:FindFirstChild("NetworkClient") then -- we are playing online
+ setDisabledState(studioText)
+ setDisabledState(studioShortcut)
+ setDisabledState(studioCheckbox)
+ end
+
+ local backButton
+ if hasGraphicsSlider then
+ backButton = createTextButton("OK",Enum.ButtonStyle.RobloxButtonDefault,Enum.FontSize.Size24,UDim2.new(0,180,0,50),UDim2.new(0,170,0,330))
+ backButton.Modal = true
+ else
+ backButton = createTextButton("OK",Enum.ButtonStyle.RobloxButtonDefault,Enum.FontSize.Size24,UDim2.new(0,180,0,50),UDim2.new(0,170,0,330))
+ backButton.Modal = true
+ end
+
+ backButton.Name = "BackButton"
+ backButton.ZIndex = baseZIndex + 4
+ backButton.Parent = gameSettingsMenuFrame
+
+ local syncVideoCaptureSetting = nil
+
+ if not macClient then
+ local videoCaptureLabel = Instance.new("TextLabel")
+ videoCaptureLabel.Name = "VideoCaptureLabel"
+ videoCaptureLabel.Text = "After Capturing Video"
+ videoCaptureLabel.Font = Enum.Font.Arial
+ videoCaptureLabel.FontSize = Enum.FontSize.Size18
+ videoCaptureLabel.Position = UDim2.new(0,32,0,100)
+ videoCaptureLabel.Size = UDim2.new(0,164,0,18)
+ videoCaptureLabel.BackgroundTransparency = 1
+ videoCaptureLabel.TextColor3 = Color3I(255,255,255)
+ videoCaptureLabel.TextXAlignment = Enum.TextXAlignment.Left
+ videoCaptureLabel.ZIndex = baseZIndex + 4
+ videoCaptureLabel.Parent = gameSettingsMenuFrame
+
+ local videoNames = {}
+ local videoNameToItem = {}
+ videoNames[1] = "Just Save to Disk"
+ videoNameToItem[videoNames[1]] = Enum.UploadSetting["Never"]
+ videoNames[2] = "Upload to YouTube"
+ videoNameToItem[videoNames[2]] = Enum.UploadSetting["Ask me first"]
+
+ local videoCaptureDropDown = nil
+ videoCaptureDropDown, updateVideoCaptureDropDownSelection = RbxGui.CreateDropDownMenu(videoNames,
+ function(text)
+ UserSettings().GameSettings.VideoUploadPromptBehavior = videoNameToItem[text]
+ end)
+ videoCaptureDropDown.Name = "VideoCaptureField"
+ videoCaptureDropDown.ZIndex = baseZIndex + 4
+ videoCaptureDropDown.DropDownMenuButton.ZIndex = baseZIndex + 4
+ videoCaptureDropDown.DropDownMenuButton.Icon.ZIndex = baseZIndex + 4
+ videoCaptureDropDown.Position = UDim2.new(0, 270, 0, 94)
+ videoCaptureDropDown.Size = UDim2.new(0,200,0,32)
+ videoCaptureDropDown.Parent = gameSettingsMenuFrame
+
+ syncVideoCaptureSetting = function()
+ if UserSettings().GameSettings.VideoUploadPromptBehavior == Enum.UploadSetting["Never"] then
+ updateVideoCaptureDropDownSelection(videoNames[1])
+ elseif UserSettings().GameSettings.VideoUploadPromptBehavior == Enum.UploadSetting["Ask me first"] then
+ updateVideoCaptureDropDownSelection(videoNames[2])
+ else
+ UserSettings().GameSettings.VideoUploadPromptBehavior = Enum.UploadSetting["Ask me first"]
+ updateVideoCaptureDropDownSelection(videoNames[2])
+ end
+ end
+ end
+
+ local cameraLabel = Instance.new("TextLabel")
+ cameraLabel.Name = "CameraLabel"
+ cameraLabel.Text = "Character & Camera Controls"
+ cameraLabel.Font = Enum.Font.Arial
+ cameraLabel.FontSize = Enum.FontSize.Size18
+ cameraLabel.Position = UDim2.new(0,31,0,58)
+ cameraLabel.Size = UDim2.new(0,224,0,18)
+ cameraLabel.TextColor3 = Color3I(255,255,255)
+ cameraLabel.TextXAlignment = Enum.TextXAlignment.Left
+ cameraLabel.BackgroundTransparency = 1
+ cameraLabel.ZIndex = baseZIndex + 4
+ cameraLabel.Parent = gameSettingsMenuFrame
+
+ local mouseLockLabel = true
+
+ local enumItems = Enum.ControlMode:GetEnumItems()
+ local enumNames = {}
+ local enumNameToItem = {}
+ for i,obj in ipairs(enumItems) do
+ enumNames[i] = obj.Name
+ enumNameToItem[obj.Name] = obj
+ end
+
+ local cameraDropDown
+ cameraDropDown, updateCameraDropDownSelection = RbxGui.CreateDropDownMenu(enumNames,
+ function(text)
+ UserSettings().GameSettings.ControlMode = enumNameToItem[text]
+
+ pcall(function()
+ if mouseLockLabel and UserSettings().GameSettings.ControlMode == Enum.ControlMode["Mouse Lock Switch"] then
+ mouseLockLabel.Visible = true
+ elseif mouseLockLabel then
+ mouseLockLabel.Visible = false
+ end
+ end)
+ end)
+ cameraDropDown.Name = "CameraField"
+ cameraDropDown.ZIndex = baseZIndex + 4
+ cameraDropDown.DropDownMenuButton.ZIndex = baseZIndex + 4
+ cameraDropDown.DropDownMenuButton.Icon.ZIndex = baseZIndex + 4
+ cameraDropDown.Position = UDim2.new(0, 270, 0, 52)
+ cameraDropDown.Size = UDim2.new(0,200,0,32)
+ cameraDropDown.Parent = gameSettingsMenuFrame
+
+ return gameSettingsMenuFrame
+end
+
+
+if LoadLibrary then
+ RbxGui = t
+ local baseZIndex = 0
+if UserSettings then
+
+ local createSettingsDialog = function()
+ waitForChild(gui,"BottomLeftControl")
+ settingsButton = gui.BottomLeftControl:FindFirstChild("SettingsButton")
+
+ if settingsButton == nil then
+ settingsButton = Instance.new("ImageButton")
+ settingsButton.Name = "SettingsButton"
+ settingsButton.Image = "rbxasset://textures/ui/SettingsButton.png"
+ settingsButton.BackgroundTransparency = 1
+ settingsButton.Active = false
+ settingsButton.Size = UDim2.new(0,54,0,46)
+ settingsButton.Position = UDim2.new(0,2,0,50)
+ settingsButton.Parent = gui
+ settingsButton.MouseButton1Click:connect(function()
+ goToMenu(shield.Settings.SettingsStyle,"GameMainMenu","down",UDim2.new(0,525,0,430))
+ shield.Settings:TweenSize(UDim2.new(0,525,0,430),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
+ end)
+ end
+
+ local shield = Instance.new("TextButton")
+ shield.Text = ""
+ shield.Name = "UserSettingsShield"
+ shield.Active = true
+ shield.AutoButtonColor = false
+ shield.Visible = false
+ shield.Size = UDim2.new(1,0,1,0)
+ shield.BackgroundColor3 = Color3I(51,51,51)
+ shield.BorderColor3 = Color3I(27,42,53)
+ shield.BackgroundTransparency = 0.4
+ shield.ZIndex = baseZIndex + 2
+ shield.Parent = script.Parent
+ mainShield = shield
+
+ local frame = Instance.new("Frame")
+ frame.Name = "Settings"
+ frame.Position = UDim2.new(0.5, -262, -0.5, -200)
+ frame.Size = UDim2.new(0, 525, 0, 430)
+ frame.BackgroundTransparency = 1
+ frame.Active = true
+ frame.Parent = shield
+
+ local settingsFrame = Instance.new("Frame")
+ settingsFrame.Name = "SettingsStyle"
+ settingsFrame.Size = UDim2.new(1, 0, 1, 0)
+ settingsFrame.Style = Enum.FrameStyle.RobloxRound
+ settingsFrame.Active = true
+ settingsFrame.ZIndex = baseZIndex + 3
+ settingsFrame.Parent = frame
+
+ local gameSettingsMenu = createGameSettingsMenu(baseZIndex, shield)
+ gameSettingsMenu.Parent = settingsFrame
+
+ local gameMainMenu = createGameMainMenu(baseZIndex, shield)
+ gameMainMenu.Parent = settingsFrame
+
+
+
+ gameMainMenu.ScreenshotButton.MouseButton1Click:connect(function()
+
+ end)
+
+ gameMainMenu.RecordVideoButton.MouseButton1Click:connect(function()
+
+ end)
+
+
+
+
+
+ function localPlayerChange()
+ gameMainMenu.ResetButton.Visible = game.Players.LocalPlayer
+ if game.Players.LocalPlayer then
+ settings().Rendering.EnableFRM = true
+ elseif inStudioMode then
+ settings().Rendering.EnableFRM = false
+ end
+ end
+
+ gameMainMenu.ResetButton.Visible = game.Players.LocalPlayer
+ if game.Players.LocalPlayer ~= nil then
+ game.Players.LocalPlayer.Changed:connect(function()
+ localPlayerChange()
+ end)
+ else
+ delay(0,function()
+ waitForProperty(game.Players,"LocalPlayer")
+ gameMainMenu.ResetButton.Visible = game.Players.LocalPlayer
+ game.Players.LocalPlayer.Changed:connect(function()
+ localPlayerChange()
+ end)
+ end)
+ end
+
+ gameMainMenu.ReportAbuseButton.Visible = game:FindFirstChild("NetworkClient")
+ if not gameMainMenu.ReportAbuseButton.Visible then
+ game.ChildAdded:connect(function(child)
+ if child:IsA("NetworkClient") then
+ gameMainMenu.ReportAbuseButton.Visible = game:FindFirstChild("NetworkClient")
+ end
+ end)
+ end
+
+
+
+ gameMainMenu.ResetButton.MouseButton1Click:connect(function()
+ goToMenu(settingsFrame,"ResetConfirmationMenu","up",UDim2.new(0,525,0,370))
+ end)
+
+ gameMainMenu.LeaveGameButton.MouseButton1Click:connect(function()
+ goToMenu(settingsFrame,"LeaveConfirmationMenu","down",UDim2.new(0,525,0,300))
+ end)
+
+
+
+ local gameSettingsMenu = createGameSettingsMenu(baseZIndex, shield)
+ gameSettingsMenu.Visible = false
+ gameSettingsMenu.Parent = settingsFrame
+
+ gameMainMenu.LeaveGameButton.MouseButton1Click:connect(function()
+ goToMenu(settingsFrame,"LeaveConfirmationMenu","down",UDim2.new(0,525,0,300))
+ end)
+
+ gameMainMenu.SettingsButton.MouseButton1Click:connect(function()
+ goToMenu(settingsFrame,"GameSettingsMenu","left",UDim2.new(0,525,0,350))
+ end)
+
+ gameSettingsMenu.BackButton.MouseButton1Click:connect(function()
+ goToMenu(settingsFrame,"GameMainMenu","right",UDim2.new(0,525,0,430))
+ end)
+
+ local resetConfirmationWindow = createResetConfirmationMenu(baseZIndex, shield)
+ resetConfirmationWindow.Visible = false
+ resetConfirmationWindow.Parent = settingsFrame
+
+ local leaveConfirmationWindow = createLeaveConfirmationMenu(baseZIndex,shield)
+ leaveConfirmationWindow.Visible = false
+ leaveConfirmationWindow.Parent = settingsFrame
+
+
+
+
+
+ settingsButton.MouseButton1Click:connect(
+ function()
+ game.GuiService:AddCenterDialog(shield, Enum.CenterDialogType.ModalDialog,
+ --showFunction
+ function()
+ settingsButton.Active = false
+ updateCameraDropDownSelection(UserSettings().GameSettings.ControlMode.Name)
+
+ if syncVideoCaptureSetting then
+ syncVideoCaptureSetting()
+ end
+
+ goToMenu(settingsFrame,"GameMainMenu","right",UDim2.new(0,525,0,430))
+ shield.Visible = true
+ settingsFrame.Parent:TweenPosition(UDim2.new(0.5, -262,0.5, -200),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
+ settingsFrame.Parent:TweenSize(UDim2.new(0,525,0,430),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
+ end,
+ --hideFunction
+ function()
+ settingsFrame.Parent:TweenPosition(UDim2.new(0.5, -262,-0.5, -200),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
+ settingsFrame.Parent:TweenSize(UDim2.new(0,525,0,430),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
+ shield.Visible = false
+ settingsButton.Active = true
+ end)
+ end)
+
+ return shield
+ end
+
+
+delay(0, function()
+ if settingsButton == nil then
+ settingsButton = Instance.new("ImageButton")
+ settingsButton.Name = "SettingsButton"
+ settingsButton.Image = "rbxasset://textures/ui/SettingsButton.png"
+ settingsButton.BackgroundTransparency = 1
+ settingsButton.Active = false
+ settingsButton.Size = UDim2.new(0,54,0,46)
+ settingsButton.Position = UDim2.new(0,2,0,50)
+ settingsButton.Parent = gui.BottomLeftControl
+ end
+
+ local shield = Instance.new("TextButton")
+ shield.Text = ""
+ shield.Name = "UserSettingsShield"
+ shield.Active = true
+ shield.AutoButtonColor = false
+ shield.Visible = false
+ shield.Size = UDim2.new(1,0,1,0)
+ shield.BackgroundColor3 = Color3I(51,51,51)
+ shield.BorderColor3 = Color3I(27,42,53)
+ shield.BackgroundTransparency = 0.4
+ shield.ZIndex = baseZIndex + 2
+ shield.Parent = script.Parent
+ mainShield = shield
+
+
+
+ local frame = Instance.new("Frame")
+ frame.Name = "Settings"
+ frame.Position = UDim2.new(0.5, -262, -0.5, -200)
+ frame.Size = UDim2.new(0, 525, 0, 430)
+ frame.BackgroundTransparency = 1
+ frame.Active = true
+ frame.Parent = shield
+
+ local settingsFrame = Instance.new("Frame")
+ settingsFrame.Name = "SettingsStyle"
+ settingsFrame.Size = UDim2.new(1, 0, 1, 0)
+ settingsFrame.Style = Enum.FrameStyle.RobloxRound
+ settingsFrame.Active = true
+ settingsFrame.ZIndex = baseZIndex + 3
+ settingsFrame.Parent = frame
+
+
+
+ local resetConfirmationWindow = createResetConfirmationMenu(baseZIndex, shield)
+ resetConfirmationWindow.Visible = false
+ resetConfirmationWindow.Parent = settingsFrame
+
+ local leaveConfirmationWindow = createLeaveConfirmationMenu(baseZIndex,shield)
+ leaveConfirmationWindow.Visible = false
+ leaveConfirmationWindow.Parent = settingsFrame
+
+
+ local gameMainMenu = createGameMainMenu(baseZIndex, shield)
+ gameMainMenu.Parent = settingsFrame
+
+ local gameSettingsMenu = createGameSettingsMenu(baseZIndex, shield)
+ gameSettingsMenu.Visible = false
+ gameSettingsMenu.Parent = settingsFrame
+
+ gameMainMenu.SettingsButton.MouseButton1Click:connect(function()
+ goToMenu(settingsFrame,"GameSettingsMenu","left",UDim2.new(0,525,0,350))
+ end)
+
+ gameSettingsMenu.BackButton.MouseButton1Click:connect(function()
+ goToMenu(settingsFrame,"GameMainMenu","right",UDim2.new(0,525,0,430))
+ end)
+
+ gameMainMenu.ResetButton.MouseButton1Click:connect(function()
+ goToMenu(settingsFrame,"ResetConfirmationMenu","up",UDim2.new(0,525,0,370))
+ end)
+
+ gameMainMenu.LeaveGameButton.MouseButton1Click:connect(function()
+ goToMenu(settingsFrame,"LeaveConfirmationMenu","up",UDim2.new(0,525,0,300))
+ end)
+
+
+
+ gameMainMenu.ScreenshotButton.MouseButton1Click:connect(function()
+
+ end)
+
+ gameMainMenu.RecordVideoButton.MouseButton1Click:connect(function()
+
+ end)
+
+ settingsButton.MouseButton1Click:connect(function()
+ goToMenu(settingsFrame,"GameMainMenu","right",UDim2.new(0,525,0,430))
+ shield.Visible = true
+ shield.Active = true
+ settingsFrame.Parent:TweenPosition(UDim2.new(0.5, -262,0.5, -200),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
+ settingsFrame.Parent:TweenSize(UDim2.new(0,525,0,430),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
+ end)
+
+ gui.BottomLeftControl.SettingsButton.Active = true
+ gui.BottomLeftControl.SettingsButton.Position = UDim2.new(0,2,0,-2)
+
+ if mouseLockLabel and UserSettings().GameSettings.ControlMode == Enum.ControlMode["Mouse Lock Switch"] then
+ mouseLockLabel.Visible = true
+ elseif mouseLockLabel then
+ mouseLockLabel.Visible = false
+ end
+
+ --Only show things if we are a NetworkClient
+ waitForChild(game,"NetworkClient")
+
+ waitForChild(game,"Players")
+ waitForProperty(game.Players, "LocalPlayer")
+ local localPlayer = game.Players.LocalPlayer
+
+ local reportAbuseButton
+ waitForChild(gui,"UserSettingsShield")
+ waitForChild(gui.UserSettingsShield, "Settings")
+ waitForChild(gui.UserSettingsShield.Settings,"SettingsStyle")
+ waitForChild(gui.UserSettingsShield.Settings.SettingsStyle,"GameMainMenu")
+ waitForChild(gui.UserSettingsShield.Settings.SettingsStyle.GameMainMenu, "ReportAbuseButton")
+ reportAbuseButton = gui.UserSettingsShield.Settings.SettingsStyle.GameMainMenu.ReportAbuseButton
+
+ local shield = Instance.new("TextButton")
+ shield.Name = "ReportAbuseShield"
+ shield.Text = ""
+ shield.AutoButtonColor = false
+ shield.Active = true
+ shield.Visible = false
+ shield.Size = UDim2.new(1,0,1,0)
+ shield.BackgroundColor3 = Color3I(51,51,51)
+ shield.BorderColor3 = Color3I(27,42,53)
+ shield.BackgroundTransparency = 0.4
+ shield.ZIndex = baseZIndex + 1
+
+ local closeAndResetDialgo
+
+ local messageBoxButtons = {}
+ messageBoxButtons[1] = {}
+ messageBoxButtons[1].Text = "Ok"
+ messageBoxButtons[1].Modal = true
+ messageBoxButtons[1].Function = function() closeAndResetDialog() end
+ local calmingMessageBox = RbxGui.CreateMessageDialog("Thanks for your report!", "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", messageBoxButtons)
+ calmingMessageBox.Visible = false
+ calmingMessageBox.Parent = shield
+
+ local recordedMessageBox = RbxGui.CreateMessageDialog("Thanks for your report!","We've recorded your report for evaluation.", messageBoxButtons)
+ recordedMessageBox.Visible = false
+ recordedMessageBox.Parent = shield
+
+ local normalMessageBox = RbxGui.CreateMessageDialog("Thanks for your report!", "Our moderators will review the chat logs and determine what happened.", messageBoxButtons)
+ normalMessageBox.Visible = false
+ normalMessageBox.Parent = shield
+
+ local frame = Instance.new("Frame")
+ frame.Name = "Settings"
+ frame.Position = UDim2.new(0.5, -250, 0.5, -200)
+ frame.Size = UDim2.new(0.0, 500, 0.0, 400)
+ frame.BackgroundTransparency = 1
+ frame.Active = true
+ frame.Parent = shield
+
+ local settingsFrame = Instance.new("Frame")
+ settingsFrame.Name = "ReportAbuseStyle"
+ settingsFrame.Size = UDim2.new(1, 0, 1, 0)
+ settingsFrame.Style = Enum.FrameStyle.RobloxRound
+ settingsFrame.Active = true
+ settingsFrame.ZIndex = baseZIndex + 1
+ settingsFrame.Parent = frame
+
+ local title = Instance.new("TextLabel")
+ title.Name = "Title"
+ title.Text = "Report Abuse"
+ title.TextColor3 = Color3I(221,221,221)
+ title.Position = UDim2.new(0.5, 0, 0, 30)
+ title.Font = Enum.Font.ArialBold
+ title.FontSize = Enum.FontSize.Size36
+ title.ZIndex = baseZIndex + 2
+ title.Parent = settingsFrame
+
+ local description = Instance.new("TextLabel")
+ description.Name = "Description"
+ description.Text = "This will send a complete report to a moderator. The moderator will review the chat log and take appropriate action."
+ description.TextColor3 = Color3I(221,221,221)
+ description.Position = UDim2.new(0, 0, 0, 55)
+ description.Size = UDim2.new(1, 0, 0, 40)
+ description.BackgroundTransparency = 1
+ description.Font = Enum.Font.Arial
+ description.FontSize = Enum.FontSize.Size18
+ description.TextWrap = true
+ description.ZIndex = baseZIndex + 2
+ description.TextXAlignment = Enum.TextXAlignment.Left
+ description.TextYAlignment = Enum.TextYAlignment.Top
+ description.Parent = settingsFrame
+
+ local playerLabel = Instance.new("TextLabel")
+ playerLabel.Name = "PlayerLabel"
+ playerLabel.Text = "Which player?"
+ playerLabel.BackgroundTransparency = 1
+ playerLabel.Font = Enum.Font.Arial
+ playerLabel.FontSize = Enum.FontSize.Size18
+ playerLabel.Position = UDim2.new(0.025,0,0,100)
+ playerLabel.Size = UDim2.new(0.4,0,0,36)
+ playerLabel.TextColor3 = Color3I(255,255,255)
+ playerLabel.TextXAlignment = Enum.TextXAlignment.Left
+ playerLabel.ZIndex = baseZIndex + 2
+ playerLabel.Parent = settingsFrame
+
+ local abusingPlayer = nil
+ local abuse = nil
+ local submitReportButton = nil
+
+ local updatePlayerSelection = nil
+ local createPlayersDropDown = function()
+ local players = game:GetService("Players")
+ local playerNames = {}
+ local nameToPlayer = {}
+ local children = players:GetChildren()
+ local pos = 1
+ if children then
+ for i, player in ipairs(children) do
+ if player:IsA("Player") and player ~= localPlayer then
+ playerNames[pos] = player.Name
+ nameToPlayer[player.Name] = player
+ pos = pos + 1
+ end
+ end
+ end
+ local playerDropDown = nil
+ playerDropDown, updatePlayerSelection = RbxGui.CreateDropDownMenu(playerNames,
+ function(playerName)
+ abusingPlayer = nameToPlayer[playerName]
+ if abuse and abusingPlayer then
+ submitReportButton.Active = true
+ end
+ end)
+ playerDropDown.Name = "PlayersComboBox"
+ playerDropDown.ZIndex = baseZIndex + 2
+ playerDropDown.Position = UDim2.new(.425, 0, 0, 102)
+ playerDropDown.Size = UDim2.new(.55,0,0,32)
+
+ return playerDropDown
+ end
+
+ local abuseLabel = Instance.new("TextLabel")
+ abuseLabel.Name = "AbuseLabel"
+ abuseLabel.Text = "Type of Abuse:"
+ abuseLabel.Font = Enum.Font.Arial
+ abuseLabel.BackgroundTransparency = 1
+ abuseLabel.FontSize = Enum.FontSize.Size18
+ abuseLabel.Position = UDim2.new(0.025,0,0,140)
+ abuseLabel.Size = UDim2.new(0.4,0,0,36)
+ abuseLabel.TextColor3 = Color3I(255,255,255)
+ abuseLabel.TextXAlignment = Enum.TextXAlignment.Left
+ abuseLabel.ZIndex = baseZIndex + 2
+ abuseLabel.Parent = settingsFrame
+
+ local abuses = {"Swearing","Bullying","Scamming","Dating","Cheating/Exploiting","Personal Questions","Offsite Links","Bad Model or Script","Bad Username"}
+ local abuseDropDown, updateAbuseSelection = RbxGui.CreateDropDownMenu(abuses,
+ function(abuseText)
+ abuse = abuseText
+ if abuse and abusingPlayer then
+ submitReportButton.Active = true
+ end
+ end, true)
+ abuseDropDown.Name = "AbuseComboBox"
+ abuseDropDown.ZIndex = baseZIndex + 2
+ abuseDropDown.Position = UDim2.new(0.425, 0, 0, 142)
+ abuseDropDown.Size = UDim2.new(0.55,0,0,32)
+ abuseDropDown.Parent = settingsFrame
+
+ local shortDescriptionLabel = Instance.new("TextLabel")
+ shortDescriptionLabel.Name = "ShortDescriptionLabel"
+ shortDescriptionLabel.Text = "Short Description: (optional)"
+ shortDescriptionLabel.Font = Enum.Font.Arial
+ shortDescriptionLabel.FontSize = Enum.FontSize.Size18
+ shortDescriptionLabel.Position = UDim2.new(0.025,0,0,180)
+ shortDescriptionLabel.Size = UDim2.new(0.95,0,0,36)
+ shortDescriptionLabel.TextColor3 = Color3I(255,255,255)
+ shortDescriptionLabel.TextXAlignment = Enum.TextXAlignment.Left
+ shortDescriptionLabel.BackgroundTransparency = 1
+ shortDescriptionLabel.ZIndex = baseZIndex + 2
+ shortDescriptionLabel.Parent = settingsFrame
+
+ local shortDescriptionWrapper = Instance.new("Frame")
+ shortDescriptionWrapper.Name = "ShortDescriptionWrapper"
+ shortDescriptionWrapper.Position = UDim2.new(0.025,0,0,220)
+ shortDescriptionWrapper.Size = UDim2.new(0.95,0,1,-310)
+ shortDescriptionWrapper.BackgroundColor3 = Color3I(0,0,0)
+ shortDescriptionWrapper.BorderSizePixel = 0
+ shortDescriptionWrapper.ZIndex = baseZIndex + 2
+ shortDescriptionWrapper.Parent = settingsFrame
+
+ local shortDescriptionBox = Instance.new("TextBox")
+ shortDescriptionBox.Name = "TextBox"
+ shortDescriptionBox.Text = ""
+ shortDescriptionBox.ClearTextOnFocus = false
+ shortDescriptionBox.Font = Enum.Font.Arial
+ shortDescriptionBox.FontSize = Enum.FontSize.Size18
+ shortDescriptionBox.Position = UDim2.new(0,3,0,3)
+ shortDescriptionBox.Size = UDim2.new(1,-6,1,-6)
+ shortDescriptionBox.TextColor3 = Color3I(255,255,255)
+ shortDescriptionBox.TextXAlignment = Enum.TextXAlignment.Left
+ shortDescriptionBox.TextYAlignment = Enum.TextYAlignment.Top
+ shortDescriptionBox.TextWrap = true
+ shortDescriptionBox.BackgroundColor3 = Color3I(0,0,0)
+ shortDescriptionBox.BorderSizePixel = 0
+ shortDescriptionBox.ZIndex = baseZIndex + 2
+ shortDescriptionBox.Parent = shortDescriptionWrapper
+
+ submitReportButton = Instance.new("TextButton")
+ submitReportButton.Name = "SubmitReportBtn"
+ submitReportButton.Active = false
+ submitReportButton.Modal = true
+ submitReportButton.Font = Enum.Font.Arial
+ submitReportButton.FontSize = Enum.FontSize.Size18
+ submitReportButton.Position = UDim2.new(0.1, 0, 1, -80)
+ submitReportButton.Size = UDim2.new(0.35,0,0,50)
+ submitReportButton.AutoButtonColor = true
+ submitReportButton.Style = Enum.ButtonStyle.RobloxButtonDefault
+ submitReportButton.Text = "Submit Report"
+ submitReportButton.TextColor3 = Color3I(255,255,255)
+ submitReportButton.ZIndex = baseZIndex + 2
+ submitReportButton.Parent = settingsFrame
+
+ submitReportButton.MouseButton1Click:connect(function()
+ if submitReportButton.Active then
+ if abuse and abusingPlayer then
+ frame.Visible = false
+ game.Players:ReportAbuse(abusingPlayer, abuse, shortDescriptionBox.Text)
+ if abuse == "Cheating/Exploiting" then
+ recordedMessageBox.Visible = true
+ elseif abuse == "Bullying" or abuse == "Swearing" then
+ calmingMessageBox.Visible = true
+ else
+ normalMessageBox.Visible = true
+ end
+ else
+ closeAndResetDialog()
+ end
+ end
+ end)
+
+ local cancelButton = Instance.new("TextButton")
+ cancelButton.Name = "CancelBtn"
+ cancelButton.Font = Enum.Font.Arial
+ cancelButton.FontSize = Enum.FontSize.Size18
+ cancelButton.Position = UDim2.new(0.55, 0, 1, -80)
+ cancelButton.Size = UDim2.new(0.35,0,0,50)
+ cancelButton.AutoButtonColor = true
+ cancelButton.Style = Enum.ButtonStyle.RobloxButtonDefault
+ cancelButton.Text = "Cancel"
+ cancelButton.TextColor3 = Color3I(255,255,255)
+ cancelButton.ZIndex = baseZIndex + 2
+ cancelButton.Parent = settingsFrame
+
+ closeAndResetDialog = function()
+ --Delete old player combo box
+ local oldComboBox = settingsFrame:FindFirstChild("PlayersComboBox")
+ if oldComboBox then
+ oldComboBox.Parent = nil
+ end
+
+ abusingPlayer = nil updatePlayerSelection(nil)
+ abuse = nil updateAbuseSelection(nil)
+ submitReportButton.Active = false
+ shortDescriptionBox.Text = ""
+ frame.Visible = true
+ calmingMessageBox.Visible = false
+ recordedMessageBox.Visible = false
+ normalMessageBox.Visible = false
+ shield.Visible = false
+ reportAbuseButton.Active = true
+ game.GuiService:RemoveCenterDialog(shield)
+ end
+
+ cancelButton.MouseButton1Click:connect(closeAndResetDialog)
+
+ reportAbuseButton.MouseButton1Click:connect(
+ function()
+ createPlayersDropDown().Parent = settingsFrame
+ table.insert(centerDialogs,shield)
+ game.GuiService:AddCenterDialog(shield, Enum.CenterDialogType.ModalDialog,
+ --ShowFunction
+ function()
+ reportAbuseButton.Active = true
+ shield.Visible = true
+ mainShield.Visible = false
+ end,
+ --HideFunction
+ function()
+ reportAbuseButton.Active = true
+ shield.Visible = false
+ end)
+ end)
+
+
+end)
+
+local createSaveDialogs = function()
+ local shield = Instance.new("TextButton")
+ shield.Text = ""
+ shield.AutoButtonColor = false
+ shield.Name = "SaveDialogShield"
+ shield.Active = true
+ shield.Visible = false
+ shield.Size = UDim2.new(1,0,1,0)
+ shield.BackgroundColor3 = Color3I(51,51,51)
+ shield.BorderColor3 = Color3I(27,42,53)
+ shield.BackgroundTransparency = 0.4
+ shield.ZIndex = baseZIndex+1
+
+ local clearAndResetDialog
+ local save
+ local saveLocal
+ local dontSave
+ local cancel
+
+ local messageBoxButtons = {}
+ messageBoxButtons[1] = {}
+ messageBoxButtons[1].Text = "Save"
+ messageBoxButtons[1].Style = Enum.ButtonStyle.RobloxButtonDefault
+ messageBoxButtons[1].Function = function() save() end
+ messageBoxButtons[2] = {}
+ messageBoxButtons[2].Text = "Cancel"
+ messageBoxButtons[2].Function = function() cancel() end
+ messageBoxButtons[3] = {}
+ messageBoxButtons[3].Text = "Don't Save"
+ messageBoxButtons[3].Function = function() dontSave() end
+
+ local saveDialogMessageBox = RbxGui.CreateStyledMessageDialog("Unsaved Changes", "Save your changes to ROBLOX before leaving?", "Confirm", messageBoxButtons)
+ saveDialogMessageBox.Visible = true
+ saveDialogMessageBox.Parent = shield
+
+
+ local errorBoxButtons = {}
+
+ local buttonOffset = 1
+ if game.LocalSaveEnabled then
+ errorBoxButtons[buttonOffset] = {}
+ errorBoxButtons[buttonOffset].Text = "Save to Disk"
+ errorBoxButtons[buttonOffset].Function = function() saveLocal() end
+ buttonOffset = buttonOffset + 1
+ end
+ errorBoxButtons[buttonOffset] = {}
+ errorBoxButtons[buttonOffset].Text = "Keep Playing"
+ errorBoxButtons[buttonOffset].Function = function() cancel() end
+ errorBoxButtons[buttonOffset+1] = {}
+ errorBoxButtons[buttonOffset+1].Text = "Don't Save"
+ errorBoxButtons[buttonOffset+1].Function = function() dontSave() end
+
+ local errorDialogMessageBox = RbxGui.CreateStyledMessageDialog("Upload Failed", "Sorry, we could not save your changes to ROBLOX.", "Error", errorBoxButtons)
+ errorDialogMessageBox.Visible = false
+ errorDialogMessageBox.Parent = shield
+
+ local spinnerDialog = Instance.new("Frame")
+ spinnerDialog.Name = "SpinnerDialog"
+ spinnerDialog.Style = Enum.FrameStyle.RobloxRound
+ spinnerDialog.Size = UDim2.new(0, 350, 0, 150)
+ spinnerDialog.Position = UDim2.new(.5, -175, .5, -75)
+ spinnerDialog.Visible = false
+ spinnerDialog.Active = true
+ spinnerDialog.Parent = shield
+
+ local waitingLabel = Instance.new("TextLabel")
+ waitingLabel.Name = "WaitingLabel"
+ waitingLabel.Text = "Saving to ROBLOX..."
+ waitingLabel.Font = Enum.Font.ArialBold
+ waitingLabel.FontSize = Enum.FontSize.Size18
+ waitingLabel.Position = UDim2.new(0.5, 25, 0.5, 0)
+ waitingLabel.TextColor3 = Color3.new(1,1,1)
+ waitingLabel.Parent = spinnerDialog
+
+ local spinnerFrame = Instance.new("Frame")
+ spinnerFrame.Name = "Spinner"
+ spinnerFrame.Size = UDim2.new(0, 80, 0, 80)
+ spinnerFrame.Position = UDim2.new(0.5, -150, 0.5, -40)
+ spinnerFrame.BackgroundTransparency = 1
+ spinnerFrame.Parent = spinnerDialog
+
+ local spinnerIcons = {}
+ local spinnerNum = 1
+ while spinnerNum <= 8 do
+ local spinnerImage = Instance.new("ImageLabel")
+ spinnerImage.Name = "Spinner"..spinnerNum
+ spinnerImage.Size = UDim2.new(0, 16, 0, 16)
+ spinnerImage.Position = UDim2.new(.5+.3*math.cos(math.rad(45*spinnerNum)), -8, .5+.3*math.sin(math.rad(45*spinnerNum)), -8)
+ spinnerImage.BackgroundTransparency = 1
+ spinnerImage.Image = "http://www.roblox.com/Asset?id=45880710"
+ spinnerImage.Parent = spinnerFrame
+
+ spinnerIcons[spinnerNum] = spinnerImage
+ spinnerNum = spinnerNum + 1
+ end
+
+ save = function()
+ saveDialogMessageBox.Visible = false
+
+ --Show the spinner dialog
+ spinnerDialog.Visible = true
+ local spin = true
+ --Make it spin
+ delay(0, function()
+ local spinPos = 0
+ while spin do
+ local pos = 0
+
+ while pos < 8 do
+ if pos == spinPos or pos == ((spinPos+1)%8) then
+ spinnerIcons[pos+1].Image = "http://www.roblox.com/Asset?id=45880668"
+ else
+ spinnerIcons[pos+1].Image = "http://www.roblox.com/Asset?id=45880710"
+ end
+
+ pos = pos + 1
+ end
+ spinPos = (spinPos + 1) % 8
+ wait(0.2)
+ end
+ end)
+
+ --Do the save while the spinner is going, function will wait
+ local result = game:SaveToRoblox()
+ if not result then
+ --Try once more
+ result = game:SaveToRoblox()
+ end
+
+ --Hide the spinner dialog
+ spinnerDialog.Visible = false
+ --And cause the delay thread to stop
+ spin = false
+
+ --Now process the result
+ if result then
+ --Success, close
+ game:FinishShutdown(false)
+ clearAndResetDialog()
+ else
+ --Failure, show the second dialog prompt
+ errorDialogMessageBox.Visible = true
+ end
+ end
+
+ saveLocal = function()
+ errorDialogMessageBox.Visible = false
+ game:FinishShutdown(true)
+ clearAndResetDialog()
+ end
+
+ dontSave = function()
+ saveDialogMessageBox.Visible = false
+ errorDialogMessageBox.Visible = false
+ game:FinishShutdown(false)
+ clearAndResetDialog()
+ end
+ cancel = function()
+ saveDialogMessageBox.Visible = false
+ errorDialogMessageBox.Visible = false
+ clearAndResetDialog()
+ end
+
+ clearAndResetDialog = function()
+ saveDialogMessageBox.Visible = true
+ errorDialogMessageBox.Visible = false
+ spinnerDialog.Visible = false
+ shield.Visible = false
+ game.GuiService:RemoveCenterDialog(shield)
+ end
+
+
+ shield.Visible = false
+ return shield
+end
+
+local createReportAbuseDialog = function()
+ --Only show things if we are a NetworkClient
+ waitForChild(game,"NetworkClient")
+
+ waitForChild(game,"Players")
+ waitForProperty(game.Players, "LocalPlayer")
+ local localPlayer = game.Players.LocalPlayer
+
+ local reportAbuseButton
+ waitForChild(script.Parent,"UserSettingsShield")
+ waitForChild(script.Parent.UserSettingsShield, "Settings")
+ waitForChild(script.Parent.UserSettingsShield.Settings,"SettingsStyle")
+ waitForChild(script.Parent.UserSettingsShield.Settings.SettingsStyle,"GameMainMenu")
+ waitForChild(script.Parent.UserSettingsShield.Settings.SettingsStyle.GameMainMenu, "ReportAbuseButton")
+ reportAbuseButton = script.Parent.UserSettingsShield.Settings.SettingsStyle.GameMainMenu.ReportAbuseButton
+
+ local shield = Instance.new("TextButton")
+ shield.Name = "ReportAbuseShield"
+ shield.Text = ""
+ shield.AutoButtonColor = false
+ shield.Active = true
+ shield.Visible = false
+ shield.Size = UDim2.new(1,0,1,0)
+ shield.BackgroundColor3 = Color3I(51,51,51)
+ shield.BorderColor3 = Color3I(27,42,53)
+ shield.BackgroundTransparency = 0.4
+ shield.ZIndex = baseZIndex + 1
+ shield.Parent = script.Parent
+
+ local closeAndResetDialgo
+
+ local messageBoxButtons = {}
+ messageBoxButtons[1] = {}
+ messageBoxButtons[1].Text = "Ok"
+ messageBoxButtons[1].Modal = true
+ messageBoxButtons[1].Function = function() closeAndResetDialog() end
+ local calmingMessageBox = RbxGui.CreateMessageDialog("Thanks for your report!", "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", messageBoxButtons)
+ calmingMessageBox.Visible = false
+ calmingMessageBox.Parent = shield
+
+ local recordedMessageBox = RbxGui.CreateMessageDialog("Thanks for your report!","We've recorded your report for evaluation.", messageBoxButtons)
+ recordedMessageBox.Visible = false
+ recordedMessageBox.Parent = shield
+
+ local normalMessageBox = RbxGui.CreateMessageDialog("Thanks for your report!", "Our moderators will review the chat logs and determine what happened.", messageBoxButtons)
+ normalMessageBox.Visible = false
+ normalMessageBox.Parent = shield
+
+ local frame = Instance.new("Frame")
+ frame.Name = "Settings"
+ frame.Position = UDim2.new(0.5, -250, 0.5, -200)
+ frame.Size = UDim2.new(0.0, 500, 0.0, 400)
+ frame.BackgroundTransparency = 1
+ frame.Active = true
+ frame.Parent = shield
+
+ local settingsFrame = Instance.new("Frame")
+ settingsFrame.Name = "ReportAbuseStyle"
+ settingsFrame.Size = UDim2.new(1, 0, 1, 0)
+ settingsFrame.Style = Enum.FrameStyle.RobloxRound
+ settingsFrame.Active = true
+ settingsFrame.ZIndex = baseZIndex + 1
+ settingsFrame.Parent = frame
+
+ local title = Instance.new("TextLabel")
+ title.Name = "Title"
+ title.Text = "Report Abuse"
+ title.TextColor3 = Color3I(221,221,221)
+ title.Position = UDim2.new(0.5, 0, 0, 30)
+ title.Font = Enum.Font.ArialBold
+ title.FontSize = Enum.FontSize.Size36
+ title.ZIndex = baseZIndex + 2
+ title.Parent = settingsFrame
+
+ local description = Instance.new("TextLabel")
+ description.Name = "Description"
+ description.Text = "This will send a complete report to a moderator. The moderator will review the chat log and take appropriate action."
+ description.TextColor3 = Color3I(221,221,221)
+ description.Position = UDim2.new(0, 0, 0, 55)
+ description.Size = UDim2.new(1, 0, 0, 40)
+ description.BackgroundTransparency = 1
+ description.Font = Enum.Font.Arial
+ description.FontSize = Enum.FontSize.Size18
+ description.TextWrap = true
+ description.ZIndex = baseZIndex + 2
+ description.TextXAlignment = Enum.TextXAlignment.Left
+ description.TextYAlignment = Enum.TextYAlignment.Top
+ description.Parent = settingsFrame
+
+ local playerLabel = Instance.new("TextLabel")
+ playerLabel.Name = "PlayerLabel"
+ playerLabel.Text = "Which player?"
+ playerLabel.BackgroundTransparency = 1
+ playerLabel.Font = Enum.Font.Arial
+ playerLabel.FontSize = Enum.FontSize.Size18
+ playerLabel.Position = UDim2.new(0.025,0,0,100)
+ playerLabel.Size = UDim2.new(0.4,0,0,36)
+ playerLabel.TextColor3 = Color3I(255,255,255)
+ playerLabel.TextXAlignment = Enum.TextXAlignment.Left
+ playerLabel.ZIndex = baseZIndex + 2
+ playerLabel.Parent = settingsFrame
+
+ local abusingPlayer = nil
+ local abuse = nil
+ local submitReportButton = nil
+
+ local updatePlayerSelection = nil
+ local createPlayersDropDown = function()
+ local players = game:GetService("Players")
+ local playerNames = {}
+ local nameToPlayer = {}
+ local children = players:GetChildren()
+ local pos = 1
+ if children then
+ for i, player in ipairs(children) do
+ if player:IsA("Player") and player ~= localPlayer then
+ playerNames[pos] = player.Name
+ nameToPlayer[player.Name] = player
+ pos = pos + 1
+ end
+ end
+ end
+ local playerDropDown = nil
+ playerDropDown, updatePlayerSelection = RbxGui.CreateDropDownMenu(playerNames,
+ function(playerName)
+ abusingPlayer = nameToPlayer[playerName]
+ if abuse and abusingPlayer then
+ submitReportButton.Active = true
+ end
+ end)
+ playerDropDown.Name = "PlayersComboBox"
+ playerDropDown.ZIndex = baseZIndex + 2
+ playerDropDown.Position = UDim2.new(.425, 0, 0, 102)
+ playerDropDown.Size = UDim2.new(.55,0,0,32)
+
+ return playerDropDown
+ end
+
+ local abuseLabel = Instance.new("TextLabel")
+ abuseLabel.Name = "AbuseLabel"
+ abuseLabel.Text = "Type of Abuse:"
+ abuseLabel.Font = Enum.Font.Arial
+ abuseLabel.BackgroundTransparency = 1
+ abuseLabel.FontSize = Enum.FontSize.Size18
+ abuseLabel.Position = UDim2.new(0.025,0,0,140)
+ abuseLabel.Size = UDim2.new(0.4,0,0,36)
+ abuseLabel.TextColor3 = Color3I(255,255,255)
+ abuseLabel.TextXAlignment = Enum.TextXAlignment.Left
+ abuseLabel.ZIndex = baseZIndex + 2
+ abuseLabel.Parent = settingsFrame
+
+ local abuses = {"Swearing","Bullying","Scamming","Dating","Cheating/Exploiting","Personal Questions","Offsite Links","Bad Model or Script","Bad Username"}
+ local abuseDropDown, updateAbuseSelection = RbxGui.CreateDropDownMenu(abuses,
+ function(abuseText)
+ abuse = abuseText
+ if abuse and abusingPlayer then
+ submitReportButton.Active = true
+ end
+ end, true)
+ abuseDropDown.Name = "AbuseComboBox"
+ abuseDropDown.ZIndex = baseZIndex + 2
+ abuseDropDown.Position = UDim2.new(0.425, 0, 0, 142)
+ abuseDropDown.Size = UDim2.new(0.55,0,0,32)
+ abuseDropDown.Parent = settingsFrame
+
+ local shortDescriptionLabel = Instance.new("TextLabel")
+ shortDescriptionLabel.Name = "ShortDescriptionLabel"
+ shortDescriptionLabel.Text = "Short Description: (optional)"
+ shortDescriptionLabel.Font = Enum.Font.Arial
+ shortDescriptionLabel.FontSize = Enum.FontSize.Size18
+ shortDescriptionLabel.Position = UDim2.new(0.025,0,0,180)
+ shortDescriptionLabel.Size = UDim2.new(0.95,0,0,36)
+ shortDescriptionLabel.TextColor3 = Color3I(255,255,255)
+ shortDescriptionLabel.TextXAlignment = Enum.TextXAlignment.Left
+ shortDescriptionLabel.BackgroundTransparency = 1
+ shortDescriptionLabel.ZIndex = baseZIndex + 2
+ shortDescriptionLabel.Parent = settingsFrame
+
+ local shortDescriptionWrapper = Instance.new("Frame")
+ shortDescriptionWrapper.Name = "ShortDescriptionWrapper"
+ shortDescriptionWrapper.Position = UDim2.new(0.025,0,0,220)
+ shortDescriptionWrapper.Size = UDim2.new(0.95,0,1,-310)
+ shortDescriptionWrapper.BackgroundColor3 = Color3I(0,0,0)
+ shortDescriptionWrapper.BorderSizePixel = 0
+ shortDescriptionWrapper.ZIndex = baseZIndex + 2
+ shortDescriptionWrapper.Parent = settingsFrame
+
+ local shortDescriptionBox = Instance.new("TextBox")
+ shortDescriptionBox.Name = "TextBox"
+ shortDescriptionBox.Text = ""
+ shortDescriptionBox.ClearTextOnFocus = false
+ shortDescriptionBox.Font = Enum.Font.Arial
+ shortDescriptionBox.FontSize = Enum.FontSize.Size18
+ shortDescriptionBox.Position = UDim2.new(0,3,0,3)
+ shortDescriptionBox.Size = UDim2.new(1,-6,1,-6)
+ shortDescriptionBox.TextColor3 = Color3I(255,255,255)
+ shortDescriptionBox.TextXAlignment = Enum.TextXAlignment.Left
+ shortDescriptionBox.TextYAlignment = Enum.TextYAlignment.Top
+ shortDescriptionBox.TextWrap = true
+ shortDescriptionBox.BackgroundColor3 = Color3I(0,0,0)
+ shortDescriptionBox.BorderSizePixel = 0
+ shortDescriptionBox.ZIndex = baseZIndex + 2
+ shortDescriptionBox.Parent = shortDescriptionWrapper
+
+ submitReportButton = Instance.new("TextButton")
+ submitReportButton.Name = "SubmitReportBtn"
+ submitReportButton.Active = false
+ submitReportButton.Modal = true
+ submitReportButton.Font = Enum.Font.Arial
+ submitReportButton.FontSize = Enum.FontSize.Size18
+ submitReportButton.Position = UDim2.new(0.1, 0, 1, -80)
+ submitReportButton.Size = UDim2.new(0.35,0,0,50)
+ submitReportButton.AutoButtonColor = true
+ submitReportButton.Style = Enum.ButtonStyle.RobloxButtonDefault
+ submitReportButton.Text = "Submit Report"
+ submitReportButton.TextColor3 = Color3I(255,255,255)
+ submitReportButton.ZIndex = baseZIndex + 2
+ submitReportButton.Parent = settingsFrame
+
+ submitReportButton.MouseButton1Click:connect(function()
+ if submitReportButton.Active then
+ if abuse and abusingPlayer then
+ frame.Visible = false
+ game.Players:ReportAbuse(abusingPlayer, abuse, shortDescriptionBox.Text)
+ if abuse == "Cheating/Exploiting" then
+ recordedMessageBox.Visible = true
+ elseif abuse == "Bullying" or abuse == "Swearing" then
+ calmingMessageBox.Visible = true
+ else
+ normalMessageBox.Visible = true
+ end
+ else
+ closeAndResetDialog()
+ end
+ end
+ end)
+
+ local cancelButton = Instance.new("TextButton")
+ cancelButton.Name = "CancelBtn"
+ cancelButton.Font = Enum.Font.Arial
+ cancelButton.FontSize = Enum.FontSize.Size18
+ cancelButton.Position = UDim2.new(0.55, 0, 1, -80)
+ cancelButton.Size = UDim2.new(0.35,0,0,50)
+ cancelButton.AutoButtonColor = true
+ cancelButton.Style = Enum.ButtonStyle.RobloxButtonDefault
+ cancelButton.Text = "Cancel"
+ cancelButton.TextColor3 = Color3I(255,255,255)
+ cancelButton.ZIndex = baseZIndex + 2
+ cancelButton.Parent = settingsFrame
+
+ closeAndResetDialog = function()
+ --Delete old player combo box
+ local oldComboBox = settingsFrame:FindFirstChild("PlayersComboBox")
+ if oldComboBox then
+ oldComboBox.Parent = nil
+ end
+
+ abusingPlayer = nil updatePlayerSelection(nil)
+ abuse = nil updateAbuseSelection(nil)
+ submitReportButton.Active = false
+ shortDescriptionBox.Text = ""
+ frame.Visible = true
+ calmingMessageBox.Visible = false
+ recordedMessageBox.Visible = false
+ normalMessageBox.Visible = false
+ shield.Visible = false
+ reportAbuseButton.Active = true
+ game.GuiService:RemoveCenterDialog(shield)
+ end
+
+ cancelButton.MouseButton1Click:connect(closeAndResetDialog)
+
+ reportAbuseButton.MouseButton1Click:connect(
+ function()
+ createPlayersDropDown().Parent = settingsFrame
+ table.insert(centerDialogs,shield)
+ game.GuiService:AddCenterDialog(shield, Enum.CenterDialogType.ModalDialog,
+ --ShowFunction
+ function()
+ reportAbuseButton.Active = true
+ shield.Visible = true
+ mainShield.Visible = false
+ end,
+ --HideFunction
+ function()
+ reportAbuseButton.Active = true
+ shield.Visible = false
+ end)
+ end)
+
+
+ return shield
+end
+
+local createChatBar = function()
+ --Only show a chat bar if we are a NetworkClient
+ waitForChild(game, "NetworkClient")
+
+ waitForChild(game, "Players")
+ waitForProperty(game.Players, "LocalPlayer")
+
+ local chatBar = Instance.new("Frame")
+ chatBar.Name = "ChatBar"
+ chatBar.Size = UDim2.new(1, 0, 0, 22)
+ chatBar.Position = UDim2.new(0, 0, 1, 0)
+ chatBar.BackgroundColor3 = Color3.new(0,0,0)
+ chatBar.BorderSizePixel = 0
+
+ local chatBox = Instance.new("TextBox")
+ chatBox.Text = ""
+ chatBox.Visible = false
+ chatBox.Size = UDim2.new(1,-4,1,0)
+ chatBox.Position = UDim2.new(0,2,0,0)
+ chatBox.TextXAlignment = Enum.TextXAlignment.Left
+ chatBox.Font = Enum.Font.Arial
+ chatBox.ClearTextOnFocus = false
+ chatBox.FontSize = Enum.FontSize.Size14
+ chatBox.TextColor3 = Color3.new(1,1,1)
+ chatBox.BackgroundTransparency = 1
+ --chatBox.Parent = chatBar
+
+ local chatButton = Instance.new("TextButton")
+ chatButton.Size = UDim2.new(1,-4,1,0)
+ chatButton.Position = UDim2.new(0,2,0,0)
+ chatButton.AutoButtonColor = false
+ chatButton.Text = "To chat click here or press \"/\" key"
+ chatButton.TextXAlignment = Enum.TextXAlignment.Left
+ chatButton.Font = Enum.Font.Arial
+ chatButton.FontSize = Enum.FontSize.Size14
+ chatButton.TextColor3 = Color3.new(1,1,1)
+ chatButton.BackgroundTransparency = 1
+ --chatButton.Parent = chatBar
+
+ local activateChat = function()
+ if chatBox.Visible then
+ return
+ end
+ chatButton.Visible = false
+ chatBox.Text = ""
+ chatBox.Visible = true
+ chatBox:CaptureFocus()
+ end
+
+ chatButton.MouseButton1Click:connect(activateChat)
+
+ local hotKeyEnabled = true
+ local toggleHotKey = function(value)
+ hotKeyEnabled = value
+ end
+
+ local guiService = game:GetService("GuiService")
+ local newChatMode = pcall(function()
+ --guiService:AddSpecialKey(Enum.SpecialKey.ChatHotkey)
+ --guiService.SpecialKeyPressed:connect(function(key) if key == Enum.SpecialKey.ChatHotkey and hotKeyEnabled then activateChat() end end)
+ end)
+ if not newChatMode then
+ --guiService:AddKey("/")
+ --guiService.KeyPressed:connect(function(key) if key == "/" and hotKeyEnabled then activateChat() end end)
+ end
+
+ chatBox.FocusLost:connect(
+ function(enterPressed)
+ if enterPressed then
+ if chatBox.Text ~= "" then
+ local str = chatBox.Text
+ if string.sub(str, 1, 1) == '%' then
+ game.Players:TeamChat(string.sub(str, 2))
+ else
+ game.Players:Chat(str)
+ end
+ end
+ end
+ chatBox.Text = ""
+ chatBox.Visible = false
+ chatButton.Visible = true
+ end)
+
+ return chatBar, toggleHotKey
+end
+
+--Spawn a thread for the Save dialogs
+local isSaveDialogSupported = pcall(function() local var = game.LocalSaveEnabled end)
+if isSaveDialogSupported then
+ delay(0,
+ function()
+ local saveDialogs = createSaveDialogs()
+ saveDialogs.Parent = gui
+
+ game.RequestShutdown = function()
+ table.insert(centerDialogs,saveDialogs)
+ game.GuiService:AddCenterDialog(saveDialogs, Enum.CenterDialogType.QuitDialog,
+ --ShowFunction
+ function()
+ saveDialogs.Visible = true
+ end,
+ --HideFunction
+ function()
+ saveDialogs.Visible = false
+ end)
+
+ return true
+ end
+ end)
+end
+
+--Spawn a thread for the Report Abuse dialogs
+--Spawn a thread for the Report Abuse dialogs
+delay(0,
+ function()
+ createReportAbuseDialog().Parent = script.Parent
+ waitForChild(script.Parent,"UserSettingsShield")
+ waitForChild(script.Parent.UserSettingsShield, "Settings")
+ waitForChild(script.Parent.UserSettingsShield.Settings,"SettingsStyle")
+ waitForChild(script.Parent.UserSettingsShield.Settings.SettingsStyle,"GameMainMenu")
+ waitForChild(script.Parent.UserSettingsShield.Settings.SettingsStyle.GameMainMenu, "ReportAbuseButton")
+ script.Parent.UserSettingsShield.Settings.SettingsStyle.GameMainMenu.ReportAbuseButton.Active = true
+ end)
+end
+end
+
+
+
+ -
+
+ false
+ 4288914085
+ 1
+ 4279970357
+ 1
+ false
+ false
+ ControlFrame
+
+ 0
+ 0
+ 0
+ 0
+
+
+ 1
+ 0
+ 1
+ 0
+
+ 0
+ 0
+ true
+ 1
+
+
-
+
+ false
+ 4288914085
+ 1
+ 4279970357
+ 1
+ false
+ false
+ BottomLeftControl
+
+ 0
+ 0
+ 1
+ -46
+
+
+ 0
+ 130
+ 0
+ 46
+
+ 0
+ 0
+ true
+ 1
+
+
-
+
+ true
+ true
+ 4288914085
+ 1
+ 4279970357
+ 1
+ false
+ false
+ rbxasset://textures/Exit.png
+ false
+ Exit
+
+ 0
+ 2
+ 0
+ -2
+
+ false
+
+ 0
+ 56
+ 0
+ 41
+
+ 0
+ 0
+ false
+ 1
+
+
+
+ -
+
+ false
+ 4288914085
+ 1
+ 4279970357
+ 1
+ false
+ false
+ BottomRightControl
+
+ 1
+ -180
+ 1
+ -41
+
+
+ 0
+ 180
+ 0
+ 41
+
+ 0
+ 0
+ true
+ 1
+
+
+ -
+
+ false
+ 4288914085
+ 1
+ 4279970357
+ 1
+ false
+ false
+ TopLeftControl
+
+ 0
+ 0
+ 0
+ 0
+
+
+ 0.0500000007
+ 0
+ 0.0500000007
+ 0
+
+ 0
+ 0
+ true
+ 1
+
+
+ -
+
+ false
+ 4288914085
+ 1
+ 4279970357
+ 1
+ false
+ false
+ NotificationBox
+
+ 1
+ -200
+ 0.5
+ 0
+
+
+ 0
+ 200
+ 0.419999987
+ 0
+
+ 0
+ true
+ 1
+
+
+
+ -
+
+ false
+
+ Workaround
+ wait(0.1)
+game.Players.LocalPlayer.PlayerGui.Menu.MenuScript.Disabled = true
+game.Players.LocalPlayer.PlayerGui.Menu.MenuScript.Disabled = false
+
+
+
+
+
diff --git a/librariesGlobal.rbxm b/librariesGlobal.rbxm
new file mode 100644
index 0000000..56601b2
--- /dev/null
+++ b/librariesGlobal.rbxm
@@ -0,0 +1,28 @@
+
+ null
+ nil
+ -
+
+ false
+
+ ResetCommand
+ function onChatted(msg, speaker)
+
+ source = string.lower(speaker.Name)
+ msg = string.lower(msg)
+ -- Note: This one is NOT caps sensitive
+
+ if msg == "!!!reset" then
+ speaker.Character.Humanoid.Health = 0
+ end
+end
+
+function onPlayerEntered(newPlayer)
+ newPlayer.Chatted:connect(function(msg) onChatted(msg, newPlayer) end)
+end
+
+game.Players.ChildAdded:connect(onPlayerEntered)
+ true
+
+
+