RBXLegacy-src/libraries2013.rbxm

28399 lines
1.1 MiB

<roblox xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.roblox.com/roblox.xsd" version="4">
<External>null</External>
<External>nil</External>
<Item class="Script" referent="RBX0">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">Sorter</string>
<ProtectedString name="Source">print(&quot;Special thanks to Bitl, Carrot, iago, winsupermario1234, Khangaroo, drslicendice, coke, TheLivingBee, Raymonf, and a bunch of play - testers for help making 2013 fully stable and work. 8)&quot;)
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.Chat:clone().Parent = game.StarterGui
script.Notifications.Parent = game.StarterGui
script:remove()</ProtectedString>
</Properties>
<Item class="ScreenGui" referent="RBX1">
<Properties>
<string name="Name">Backpack</string>
</Properties>
<Item class="Frame" referent="RBX2">
<Properties>
<bool name="Active">false</bool>
<Color3 name="BackgroundColor3">4288914085</Color3>
<float name="BackgroundTransparency">1</float>
<Color3 name="BorderColor3">4279970357</Color3>
<int name="BorderSizePixel">1</int>
<bool name="ClipsDescendants">false</bool>
<bool name="Draggable">false</bool>
<string name="Name">ControlFrame</string>
<UDim2 name="Position">
<XS>0</XS>
<XO>0</XO>
<YS>0</YS>
<YO>0</YO>
</UDim2>
<UDim2 name="Size">
<XS>1</XS>
<XO>0</XO>
<YS>1</YS>
<YO>0</YO>
</UDim2>
<token name="SizeConstraint">0</token>
<token name="Style">0</token>
<bool name="Visible">true</bool>
<int name="ZIndex">1</int>
</Properties>
<Item class="NotificationBox" referent="RBX3">
<Properties>
<bool name="Active">false</bool>
<Color3 name="BackgroundColor3">4288914085</Color3>
<float name="BackgroundTransparency">1</float>
<Color3 name="BorderColor3">4279970357</Color3>
<int name="BorderSizePixel">1</int>
<bool name="ClipsDescendants">false</bool>
<bool name="Draggable">false</bool>
<string name="Name">NotificationBox</string>
<UDim2 name="Position">
<XS>1</XS>
<XO>-200</XO>
<YS>0.5</YS>
<YO>0</YO>
</UDim2>
<UDim2 name="Size">
<XS>0</XS>
<XO>200</XO>
<YS>0.419999987</YS>
<YO>0</YO>
</UDim2>
<token name="SizeConstraint">0</token>
<bool name="Visible">true</bool>
<int name="ZIndex">1</int>
</Properties>
</Item>
</Item>
<Item class="LocalScript" referent="RBX4">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">BackpackBuilder</string>
<ProtectedString name="Source">-- fixed by iagoMAO#6808, any bugs report to me. --
--rbxsig%ajqqTypn8cXmAlrdqhDKhItl413ndYEkpVdn/u7NGTmEyfwlhOJeSdZIZE+QLG/vRLkbVlp75MyPeWt7MR7K443uOfLnmRnXvj0XdhY0HQxdqVu9uRh1FvpjhLVWE3p9GRv2Vh99QxI/FUC0rDcT64cNueM8fjBp7QpFypJ1R+8=%
--rbxassetid%53878047%
-- 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)
&#9;while not instance:FindFirstChild(name) do
&#9;&#9;instance.ChildAdded:wait()
&#9;end
end
local function waitForProperty(instance, property)
&#9;while not instance[property] do
&#9;&#9;instance.Changed:wait()
&#9;end
end
local function IsTouchDevice()&#9;
--&#9;local touchEnabled = false
--&#9;pcall(function() touchEnabled = Game:GetService(&apos;UserInputService&apos;).TouchEnabled end)
--&#9;return touchEnabled &#9;
end
local function IsPhone()
&#9;--if gui.AbsoluteSize.Y &lt;= 320 then
---&#9;&#9;return true
--&#9;end
--&#9;return false
end
waitForChild(game,&quot;Players&quot;)
waitForProperty(game.Players,&quot;LocalPlayer&quot;)
local player = game.Players.LocalPlayer
-- First up is the current loadout
local CurrentLoadout = Instance.new(&quot;Frame&quot;)
CurrentLoadout.Name = &quot;CurrentLoadout&quot;
CurrentLoadout.Position = UDim2.new(0.5, -300, 1, -85)
CurrentLoadout.Size = UDim2.new(0, 600, 0, 54)
CurrentLoadout.BackgroundTransparency = 1
--CurrentLoadout.RobloxLocked = true
CurrentLoadout.Parent = gui
local CLBackground = Instance.new(&apos;ImageLabel&apos;)&#9;&#9;&#9;&#9;&#9;&#9;
CLBackground.Name = &apos;Background&apos;;
CLBackground.Size = UDim2.new(1.2, 0, 1.2, 0);
CLBackground.Image = &quot;http://www.roblox.com/asset/?id=96536002&quot;
CLBackground.BackgroundTransparency = 1.0;
CLBackground.Position = UDim2.new(-0.1, 0, -0.1, 0);
CLBackground.ZIndex = 0.0;&#9;
CLBackground.Parent = CurrentLoadout
CLBackground.Visible = true
local BackgroundUp = Instance.new(&apos;ImageLabel&apos;)
BackgroundUp.Size = UDim2.new(1, 0, 0.025, 1)
BackgroundUp.Position = UDim2.new(0, 0, 0, 0)
BackgroundUp.Image = &apos;http://www.roblox.com/asset/?id=97662207&apos;
BackgroundUp.BackgroundTransparency = 1.0
BackgroundUp.Parent = CLBackground
local Debounce = Instance.new(&quot;BoolValue&quot;)
Debounce.Name = &quot;Debounce&quot;
--Debounce.RobloxLocked = true
Debounce.Parent = CurrentLoadout
local BackpackButton = Instance.new(&quot;ImageButton&quot;)
--BackpackButton.RobloxLocked = true
BackpackButton.Visible = true
BackpackButton.Name = &quot;BackpackButton&quot;
BackpackButton.BackgroundTransparency = 1
BackpackButton.Image = &quot;http://www.roblox.com/asset/?id=97617958&quot;
BackpackButton.Position = UDim2.new(0.5, -60, 1, -108)
BackpackButton.Size = UDim2.new(0, 120, 0, 18)
waitForChild(gui,&quot;ControlFrame&quot;)
BackpackButton.Parent = gui.ControlFrame
local NumSlots = 9
for i = 0, NumSlots do&#9;
&#9;local slotFrame = Instance.new(&quot;Frame&quot;)
--&#9;slotFrame.RobloxLocked = true
&#9;slotFrame.BackgroundColor3 = Color3.new(0,0,0)
&#9;slotFrame.BackgroundTransparency = 1
&#9;slotFrame.BorderColor3 = Color3.new(1, 1, 1)
&#9;slotFrame.Name = &quot;Slot&quot; .. tostring(i)
&#9;slotFrame.ZIndex = 4.0
&#9;if i == 0 then
&#9;&#9;slotFrame.Position = UDim2.new(0.9, 0, 0, 0)
&#9;else
&#9;&#9;slotFrame.Position = UDim2.new((i - 1) * 0.1, (i-1)* 6,0,0)
&#9;end&#9;
&#9;slotFrame.Size = UDim2.new(0, 54, 1, 0)
&#9;slotFrame.Parent = CurrentLoadout&#9;
end
local TempSlot = Instance.new(&quot;ImageButton&quot;)
TempSlot.Name = &quot;TempSlot&quot;
TempSlot.Active = true
TempSlot.Size = UDim2.new(1,0,1,0)
TempSlot.BackgroundTransparency = 1.0
TempSlot.Style = &apos;Custom&apos;
TempSlot.Visible = false
--TempSlot.RobloxLocked = true
TempSlot.Parent = CurrentLoadout
TempSlot.ZIndex = 4.0
&#9;local slotBackground = Instance.new(&apos;ImageLabel&apos;)
&#9;slotBackground.Name = &apos;Background&apos;
&#9;slotBackground.BackgroundTransparency = 1.0
&#9;slotBackground.Image = &apos;http://www.roblox.com/asset/?id=97613075&apos;
&#9;slotBackground.Size = UDim2.new(1, 0, 1, 0)&#9;
&#9;slotBackground.Parent = TempSlot
&#9;local HighLight = Instance.new(&apos;ImageLabel&apos;)
&#9;HighLight.Name = &apos;Highlight&apos;
&#9;HighLight.BackgroundTransparency = 1.0
&#9;HighLight.Image = &apos;http://www.roblox.com/asset/?id=97643886&apos;
&#9;HighLight.Size = UDim2.new(1, 0, 1, 0)&#9;
&#9;--HighLight.Parent = TempSlot
&#9;HighLight.Visible = false
&#9;-- TempSlot Children
&#9;local GearReference = Instance.new(&quot;ObjectValue&quot;)
&#9;GearReference.Name = &quot;GearReference&quot;
&#9;--GearReference.RobloxLocked = true
&#9;GearReference.Parent = TempSlot
&#9;
&#9;local ToolTipLabel = Instance.new(&quot;TextLabel&quot;)
&#9;ToolTipLabel.Name = &quot;ToolTipLabel&quot;
--&#9;ToolTipLabel.RobloxLocked = true
&#9;ToolTipLabel.Text = &quot;&quot;
&#9;ToolTipLabel.BackgroundTransparency = 0.5
&#9;ToolTipLabel.BorderSizePixel = 0
&#9;ToolTipLabel.Visible = false
&#9;ToolTipLabel.TextColor3 = Color3.new(1,1,1)
&#9;ToolTipLabel.BackgroundColor3 = Color3.new(0,0,0)
&#9;ToolTipLabel.TextStrokeTransparency = 0
&#9;ToolTipLabel.Font = Enum.Font.ArialBold
&#9;ToolTipLabel.FontSize = Enum.FontSize.Size14
&#9;--ToolTipLabel.TextWrap = true
&#9;ToolTipLabel.Size = UDim2.new(1,60,0,20)
&#9;ToolTipLabel.Position = UDim2.new(0,-30,0,-30)
&#9;ToolTipLabel.Parent = TempSlot
&#9;
&#9;local Kill = Instance.new(&quot;BoolValue&quot;)
&#9;Kill.Name = &quot;Kill&quot;
--&#9;Kill.RobloxLocked = true
&#9;Kill.Parent = TempSlot
&#9;local GearImage = Instance.new(&quot;ImageLabel&quot;)
&#9;GearImage.Name = &quot;GearImage&quot;
&#9;GearImage.BackgroundTransparency = 1
&#9;GearImage.Position = UDim2.new(0, 0, 0, 0)
&#9;GearImage.Size = UDim2.new(1, 0, 1, 0)
&#9;GearImage.ZIndex = 5.0
--&#9;GearImage.RobloxLocked = true
&#9;GearImage.Parent = TempSlot
&#9;local SlotNumber = Instance.new(&quot;TextLabel&quot;)
&#9;SlotNumber.Name = &quot;SlotNumber&quot;
&#9;SlotNumber.BackgroundTransparency = 1
&#9;SlotNumber.BorderSizePixel = 0
&#9;SlotNumber.Font = Enum.Font.ArialBold
&#9;SlotNumber.FontSize = Enum.FontSize.Size18
&#9;SlotNumber.Position = UDim2.new(0, 0, 0, 0)
&#9;SlotNumber.Size = UDim2.new(0,10,0,15)
&#9;SlotNumber.TextColor3 = Color3.new(1,1,1)
&#9;SlotNumber.TextTransparency = 0
&#9;SlotNumber.TextXAlignment = Enum.TextXAlignment.Left
&#9;SlotNumber.TextYAlignment = Enum.TextYAlignment.Bottom&#9;
--&#9;SlotNumber.RobloxLocked = true
&#9;SlotNumber.Parent = TempSlot
&#9;SlotNumber.ZIndex = 5
&#9;local SlotNumberDownShadow = SlotNumber:Clone()
&#9;SlotNumberDownShadow.Name = &quot;SlotNumberDownShadow&quot;
&#9;SlotNumberDownShadow.TextColor3 = Color3.new(0,0,0)&#9;
&#9;SlotNumberDownShadow.Position = UDim2.new(0, 1, 0, -1)
&#9;SlotNumberDownShadow.Parent = TempSlot
&#9;SlotNumberDownShadow.ZIndex = 2
&#9;
&#9;local SlotNumberUpShadow = SlotNumberDownShadow:Clone()
&#9;SlotNumberUpShadow.Name = &quot;SlotNumberUpShadow&quot;
&#9;SlotNumberUpShadow.Position = UDim2.new(0, -1, 0, -1)
&#9;SlotNumberUpShadow.Parent = TempSlot
&#9;local GearText = Instance.new(&quot;TextLabel&quot;)
--&#9;GearText.RobloxLocked = true
&#9;GearText.Name = &quot;GearText&quot;
&#9;GearText.BackgroundTransparency = 1
&#9;GearText.Font = Enum.Font.Arial
&#9;GearText.FontSize = Enum.FontSize.Size14
&#9;GearText.Position = UDim2.new(0,-8,0,-8)&#9;
&#9;GearText.Size = UDim2.new(1,16,1,16)
&#9;GearText.Text = &quot;&quot;
&#9;GearText.TextColor3 = Color3.new(1,1,1)
&#9;GearText.TextWrap = true
&#9;GearText.Parent = TempSlot
&#9;GearText.ZIndex = 5.0
--- Great, now lets make the inventory!
local Backpack = Instance.new(&quot;Frame&quot;)
--Backpack.RobloxLocked = true
Backpack.Visible = false
Backpack.Name = &quot;Backpack&quot;
Backpack.Position = UDim2.new(0.5, 0, 0.5, 0)
Backpack.BackgroundColor3 = Color3.new(32/255, 32/255, 32/255)
Backpack.BackgroundTransparency = 0.0
Backpack.BorderSizePixel = 0
Backpack.Parent = gui
Backpack.Active = true
&#9;-- Backpack Children
&#9;local SwapSlot = Instance.new(&quot;BoolValue&quot;)
--&#9;SwapSlot.RobloxLocked = true
&#9;SwapSlot.Name = &quot;SwapSlot&quot;
&#9;SwapSlot.Parent = Backpack
&#9;&#9;
&#9;&#9;-- SwapSlot Children
&#9;&#9;local Slot = Instance.new(&quot;IntValue&quot;)
--&#9;&#9;Slot.RobloxLocked = true
&#9;&#9;Slot.Name = &quot;Slot&quot;
&#9;&#9;Slot.Parent = SwapSlot
&#9;&#9;
&#9;&#9;local GearButton = Instance.new(&quot;ObjectValue&quot;)
--&#9;&#9;GearButton.RobloxLocked = true
&#9;&#9;GearButton.Name = &quot;GearButton&quot;
&#9;&#9;GearButton.Parent = SwapSlot
&#9;
&#9;--[[local Tabs = Instance.new(&quot;Frame&quot;)
&#9;Tabs.Name = &quot;Tabs&quot;
&#9;Tabs.Visible = false
&#9;Tabs.Active = false
--&#9;Tabs.RobloxLocked = true
&#9;Tabs.BackgroundColor3 = Color3.new(0,0,0)
&#9;Tabs.BackgroundTransparency = 0.08
&#9;Tabs.BorderSizePixel = 0
&#9;Tabs.Position = UDim2.new(0,0,-0.1,-4)
&#9;Tabs.Size = UDim2.new(1,0,0.1,4)
&#9;Tabs.Parent = Backpack
&#9;
&#9;&#9;-- Tabs Children
&#9;&#9;
&#9;&#9;local tabLine = Instance.new(&quot;Frame&quot;)
--&#9;&#9;tabLine.RobloxLocked = true
&#9;&#9;tabLine.Name = &quot;TabLine&quot;
&#9;&#9;tabLine.BackgroundColor3 = Color3.new(53/255, 53/255, 53/255)
&#9;&#9;tabLine.BorderSizePixel = 0
&#9;&#9;tabLine.Position = UDim2.new(0,5,1,-4)
&#9;&#9;tabLine.Size = UDim2.new(1,-10,0,4)
&#9;&#9;tabLine.ZIndex = 2
&#9;&#9;tabLine.Parent = Tabs
&#9;&#9;
&#9;&#9;local InventoryButton = Instance.new(&quot;TextButton&quot;)
--&#9;&#9;InventoryButton.RobloxLocked = true
&#9;&#9;InventoryButton.Name = &quot;InventoryButton&quot;
&#9;&#9;InventoryButton.Size = UDim2.new(0,60,0,30)
&#9;&#9;InventoryButton.Position = UDim2.new(0,7,1,-31)
&#9;&#9;InventoryButton.BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;InventoryButton.BorderColor3 = Color3.new(1,1,1)
&#9;&#9;InventoryButton.Font = Enum.Font.ArialBold
&#9;&#9;InventoryButton.FontSize = Enum.FontSize.Size18
&#9;&#9;InventoryButton.Text = &quot;Gear&quot;
&#9;&#9;InventoryButton.AutoButtonColor = false
&#9;&#9;InventoryButton.TextColor3 = Color3.new(0,0,0)
&#9;&#9;InventoryButton.Selected = true
&#9;&#9;InventoryButton.Active = true
&#9;&#9;InventoryButton.ZIndex = 3
&#9;&#9;InventoryButton.Parent = Tabs
&#9;&#9;
&#9;&#9;&#9;
&#9;&#9;local closeButton = Instance.new(&quot;TextButton&quot;)
--&#9;&#9;closeButton.RobloxLocked = true
&#9;&#9;closeButton.Name = &quot;CloseButton&quot;
&#9;&#9;closeButton.Font = Enum.Font.ArialBold
&#9;&#9;closeButton.FontSize = Enum.FontSize.Size24
&#9;&#9;closeButton.Position = UDim2.new(1,-33,0,4)
&#9;&#9;closeButton.Size = UDim2.new(0,30,0,30)
&#9;&#9;closeButton.Style = Enum.ButtonStyle.RobloxButton
&#9;&#9;closeButton.Text = &quot;&quot;
&#9;&#9;closeButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;closeButton.Parent = Tabs
&#9;&#9;closeButton.Modal = true
&#9;&#9;
&#9;&#9;&#9;--closeButton child
&#9;&#9;&#9;local XImage = Instance.new(&quot;ImageLabel&quot;)
--&#9;&#9;&#9;XImage.RobloxLocked = true
&#9;&#9;&#9;XImage.Name = &quot;XImage&quot;
&#9;&#9;&#9;game:GetService(&quot;ContentProvider&quot;):Preload(&quot;http://www.roblox.com/asset/?id=75547445&quot;)
&#9;&#9;&#9;XImage.Image = &quot;http://www.roblox.com/asset/?id=75547445&quot; --TODO: move to rbxasset
&#9;&#9;&#9;XImage.BackgroundTransparency = 1
&#9;&#9;&#9;XImage.Position = UDim2.new(-.25,-1,-.25,-1)
&#9;&#9;&#9;XImage.Size = UDim2.new(1.5,2,1.5,2)
&#9;&#9;&#9;XImage.ZIndex = 2
&#9;&#9;&#9;XImage.Parent = closeButton--]]
&#9;&#9;&#9;
&#9;&#9;-- Generic Search gui used across backpack&#9;
&#9;&#9;local SearchFrame = Instance.new(&quot;Frame&quot;)
--&#9;&#9;SearchFrame.RobloxLocked = true
&#9;&#9;SearchFrame.Name = &quot;SearchFrame&quot;
&#9;&#9;SearchFrame.BackgroundTransparency = 1
&#9;&#9;SearchFrame.Position = UDim2.new(1,-220,0,2)
&#9;&#9;SearchFrame.Size = UDim2.new(0,220,0,24)
&#9;&#9;SearchFrame.Parent = Backpack
&#9;&#9;
&#9;&#9;&#9;-- SearchFrame Children
&#9;&#9;&#9;local SearchButton = Instance.new(&quot;ImageButton&quot;)
--&#9;&#9;&#9;SearchButton.RobloxLocked = true
&#9;&#9;&#9;SearchButton.Name = &quot;SearchButton&quot;
&#9;&#9;&#9;SearchButton.Size = UDim2.new(0,25,0,25)
&#9;&#9;&#9;SearchButton.BackgroundTransparency = 1
&#9;&#9;&#9;SearchButton.Image = &quot;rbxasset://textures/ui/SearchIcon.png&quot;
&#9;&#9;&#9;SearchButton.Parent = SearchFrame
&#9;&#9;&#9;
&#9;&#9;&#9;local SearchBoxFrame = Instance.new(&quot;TextButton&quot;)
--&#9;&#9;&#9;SearchBoxFrame.RobloxLocked = true
&#9;&#9;&#9;SearchBoxFrame.Position = UDim2.new(0,25,0,0)
&#9;&#9;&#9;SearchBoxFrame.Size = UDim2.new(1,-28,0,26)
&#9;&#9;&#9;SearchBoxFrame.Name = &quot;SearchBoxFrame&quot;
&#9;&#9;&#9;SearchBoxFrame.Text = &quot;&quot;
&#9;&#9;&#9;SearchBoxFrame.Style = Enum.ButtonStyle.RobloxButton
&#9;&#9;&#9;SearchBoxFrame.Parent = SearchFrame
&#9;&#9;&#9;
&#9;&#9;&#9;&#9;-- SearchBoxFrame Children
&#9;&#9;&#9;&#9;local SearchBox = Instance.new(&quot;TextBox&quot;)
--&#9;&#9;&#9;&#9;SearchBox.RobloxLocked = true
&#9;&#9;&#9;&#9;SearchBox.Name = &quot;SearchBox&quot;
&#9;&#9;&#9;&#9;SearchBox.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;SearchBox.Font = Enum.Font.ArialBold
&#9;&#9;&#9;&#9;SearchBox.FontSize = Enum.FontSize.Size12
&#9;&#9;&#9;&#9;SearchBox.Position = UDim2.new(0,-5,0,-5)
&#9;&#9;&#9;&#9;SearchBox.Size = UDim2.new(1,10,1,10)
&#9;&#9;&#9;&#9;SearchBox.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;SearchBox.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;&#9;&#9;SearchBox.ZIndex = 2
&#9;&#9;&#9;&#9;SearchBox.TextWrap = true
&#9;&#9;&#9;&#9;SearchBox.Text = &quot;Search...&quot;
&#9;&#9;&#9;&#9;SearchBox.Parent = SearchBoxFrame
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;
&#9;&#9;&#9;local ResetButton = Instance.new(&quot;TextButton&quot;)
--&#9;&#9;&#9;ResetButton.RobloxLocked = true
&#9;&#9;&#9;ResetButton.Visible = false
&#9;&#9;&#9;ResetButton.Name = &quot;ResetButton&quot;
&#9;&#9;&#9;ResetButton.Position = UDim2.new(1,-26,0,3)
&#9;&#9;&#9;ResetButton.Size = UDim2.new(0,20,0,20)
&#9;&#9;&#9;ResetButton.Style = Enum.ButtonStyle.RobloxButtonDefault
&#9;&#9;&#9;ResetButton.Text = &quot;X&quot;
&#9;&#9;&#9;ResetButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;ResetButton.Font = Enum.Font.ArialBold
&#9;&#9;&#9;ResetButton.FontSize = Enum.FontSize.Size18
&#9;&#9;&#9;ResetButton.ZIndex = 3
&#9;&#9;&#9;ResetButton.Parent = SearchFrame
&#9;&#9;
------------------------------- GEAR -------------------------------------------------------
&#9;local Gear = Instance.new(&quot;Frame&quot;)
&#9;Gear.Name = &quot;Gear&quot;
--&#9;Gear.RobloxLocked = true
&#9;Gear.BackgroundTransparency = 1
&#9;Gear.Size = UDim2.new(1,0,1,0)
&#9;Gear.Parent = Backpack
&#9;&#9;-- Gear Children
&#9;&#9;local AssetsList = Instance.new(&quot;Frame&quot;)
&#9;--&#9;AssetsList.RobloxLocked = true
&#9;&#9;AssetsList.Name = &quot;AssetsList&quot;
&#9;&#9;AssetsList.BackgroundTransparency = 1
&#9;&#9;AssetsList.Size = UDim2.new(0.2,0,1,0)
&#9;&#9;AssetsList.Style = Enum.FrameStyle.RobloxSquare
&#9;&#9;AssetsList.Visible = false
&#9;&#9;AssetsList.Parent = Gear
&#9;&#9;&#9;
&#9;&#9;local GearGrid = Instance.new(&quot;Frame&quot;)
&#9;--&#9;GearGrid.RobloxLocked = true
&#9;&#9;GearGrid.Name = &quot;GearGrid&quot;
&#9;&#9;GearGrid.Size = UDim2.new(0.95, 0, 1, 0)
&#9;&#9;GearGrid.BackgroundTransparency = 1
&#9;&#9;GearGrid.Parent = Gear&#9;
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;
&#9;&#9;&#9;local GearButton = Instance.new(&quot;ImageButton&quot;)
&#9;&#9;--&#9;GearButton.RobloxLocked = true
&#9;&#9;&#9;GearButton.Visible = false
&#9;&#9;&#9;GearButton.Name = &quot;GearButton&quot;
&#9;&#9;&#9;GearButton.Size = UDim2.new(0, 54, 0, 54)
&#9;&#9;&#9;GearButton.Style = &apos;Custom&apos;
&#9;&#9;&#9;GearButton.Parent = GearGrid
&#9;&#9;&#9;GearButton.BackgroundTransparency = 1.0
&#9;&#9;&#9;&#9;&#9;local slotBackground = Instance.new(&apos;ImageLabel&apos;)
&#9;&#9;&#9;&#9;&#9;slotBackground.Name = &apos;Background&apos;
&#9;&#9;&#9;&#9;&#9;slotBackground.BackgroundTransparency = 1.0
&#9;&#9;&#9;&#9;&#9;slotBackground.Image = &apos;http://www.roblox.com/asset/?id=97613075&apos;
&#9;&#9;&#9;&#9;&#9;slotBackground.Size = UDim2.new(1, 0, 1, 0)
&#9;&#9;&#9;&#9;&#9;slotBackground.Parent = GearButton
&#9;&#9;&#9;&#9;-- GearButton Children
&#9;&#9;&#9;&#9;local GearReference = Instance.new(&quot;ObjectValue&quot;)
&#9;&#9;--&#9;&#9;GearReference.ed = true
&#9;&#9;&#9;&#9;GearReference.Name = &quot;GearReference&quot;
&#9;&#9;&#9;&#9;GearReference.Parent = GearButton
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local GreyOutButton = Instance.new(&quot;Frame&quot;)
&#9;&#9;--&#9;&#9;GreyOutButton.RobloxLocked = true
&#9;&#9;&#9;&#9;GreyOutButton.Name = &quot;GreyOutButton&quot;
&#9;&#9;&#9;&#9;GreyOutButton.BackgroundTransparency = 0.5
&#9;&#9;&#9;&#9;GreyOutButton.Size = UDim2.new(1,0,1,0)
&#9;&#9;&#9;&#9;GreyOutButton.Active = true
&#9;&#9;&#9;&#9;GreyOutButton.Visible = false
&#9;&#9;&#9;&#9;GreyOutButton.ZIndex = 3
&#9;&#9;&#9;&#9;GreyOutButton.Parent = GearButton
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local GearText = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;--&#9;&#9;GearText.RobloxLocked = true
&#9;&#9;&#9;&#9;GearText.Name = &quot;GearText&quot;
&#9;&#9;&#9;&#9;GearText.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;GearText.Font = Enum.Font.Arial
&#9;&#9;&#9;&#9;GearText.FontSize = Enum.FontSize.Size14
&#9;&#9;&#9;&#9;GearText.Position = UDim2.new(0,-8,0,-8)
&#9;&#9;&#9;&#9;GearText.Size = UDim2.new(1,16,1,16)
&#9;&#9;&#9;&#9;GearText.Text = &quot;&quot;
&#9;&#9;&#9;&#9;GearText.ZIndex = 2
&#9;&#9;&#9;&#9;GearText.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;GearText.TextWrap = true
&#9;&#9;&#9;&#9;GearText.Parent = GearButton
&#9;&#9;local GearGridScrollingArea = Instance.new(&quot;Frame&quot;)
&#9;&#9;--GearGridScrollingArea.RobloxLocked = true
&#9;&#9;GearGridScrollingArea.Name = &quot;GearGridScrollingArea&quot;
&#9;&#9;GearGridScrollingArea.Position = UDim2.new(1, -19, 0, 35)
&#9;&#9;GearGridScrollingArea.Size = UDim2.new(0, 17, 1, -45)
&#9;&#9;GearGridScrollingArea.BackgroundTransparency = 1
&#9;&#9;GearGridScrollingArea.Parent = Gear
&#9;&#9;local GearLoadouts = Instance.new(&quot;Frame&quot;)
&#9;&#9;--GearLoadouts.RobloxLocked = true
&#9;&#9;GearLoadouts.Name = &quot;GearLoadouts&quot;
&#9;&#9;GearLoadouts.BackgroundTransparency = 1
&#9;&#9;GearLoadouts.Position = UDim2.new(0.7,23,0.5,1)
&#9;&#9;GearLoadouts.Size = UDim2.new(0.3,-23,0.5,-1)
&#9;&#9;GearLoadouts.Parent = Gear
&#9;&#9;GearLoadouts.Visible = false
&#9;&#9;
&#9;&#9;&#9;-- GearLoadouts Children
&#9;&#9;&#9;local GearLoadoutsHeader = Instance.new(&quot;Frame&quot;)
&#9;&#9;&#9;--GearLoadoutsHeader.RobloxLocked = true
&#9;&#9;&#9;GearLoadoutsHeader.Name = &quot;GearLoadoutsHeader&quot;
&#9;&#9;&#9;GearLoadoutsHeader.BackgroundColor3 = Color3.new(0,0,0)
&#9;&#9;&#9;GearLoadoutsHeader.BackgroundTransparency = 0.2
&#9;&#9;&#9;GearLoadoutsHeader.BorderColor3 = Color3.new(1,0,0)
&#9;&#9;&#9;GearLoadoutsHeader.Size = UDim2.new(1,2,0.15,-1)
&#9;&#9;&#9;GearLoadoutsHeader.Parent = GearLoadouts
&#9;&#9;&#9;&#9;-- GearLoadoutsHeader Children
&#9;&#9;&#9;&#9;local LoadoutsHeaderText = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;&#9;&#9;--LoadoutsHeaderText.RobloxLocked = true
&#9;&#9;&#9;&#9;LoadoutsHeaderText.Name = &quot;LoadoutsHeaderText&quot;
&#9;&#9;&#9;&#9;LoadoutsHeaderText.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;LoadoutsHeaderText.Font = Enum.Font.ArialBold
&#9;&#9;&#9;&#9;LoadoutsHeaderText.FontSize = Enum.FontSize.Size18
&#9;&#9;&#9;&#9;LoadoutsHeaderText.Size = UDim2.new(1,0,1,0)
&#9;&#9;&#9;&#9;LoadoutsHeaderText.Text = &quot;Loadouts&quot;
&#9;&#9;&#9;&#9;LoadoutsHeaderText.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;LoadoutsHeaderText.Parent = GearLoadoutsHeader
&#9;
&#9;&#9;&#9;&#9;local GearLoadoutsScrollingArea = GearGridScrollingArea:clone()
&#9;&#9;&#9;
&#9;&#9;&#9;&#9;GearLoadoutsScrollingArea.Name = &quot;GearLoadoutsScrollingArea&quot;
&#9;&#9;&#9;&#9;GearLoadoutsScrollingArea.Position = UDim2.new(1,-15,0.15,2)
&#9;&#9;&#9;&#9;GearLoadoutsScrollingArea.Size = UDim2.new(0,17,0.85,-2)
&#9;&#9;&#9;&#9;GearLoadoutsScrollingArea.Parent = GearLoadouts
&#9;&#9;&#9;&#9;local LoadoutsList = Instance.new(&quot;Frame&quot;)
&#9;&#9;&#9;
&#9;&#9;&#9;&#9;LoadoutsList.Name = &quot;LoadoutsList&quot;
&#9;&#9;&#9;&#9;LoadoutsList.Position = UDim2.new(0,0,0.15,2)
&#9;&#9;&#9;&#9;LoadoutsList.Size = UDim2.new(1,-17,0.85,-2)
&#9;&#9;&#9;&#9;LoadoutsList.Style = Enum.FrameStyle.RobloxSquare
&#9;&#9;&#9;&#9;LoadoutsList.Parent = GearLoadouts
&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;local GearPreview = Instance.new(&quot;Frame&quot;)
&#9;&#9;
&#9;&#9;GearPreview.Name = &quot;GearPreview&quot;
&#9;&#9;GearPreview.Position = UDim2.new(0.7,23,0,0)
&#9;&#9;GearPreview.Size = UDim2.new(0.3,-28,0.5,-1)
&#9;&#9;GearPreview.BackgroundTransparency = 1
&#9;&#9;GearPreview.ZIndex = 7
&#9;&#9;GearPreview.Parent = Gear
&#9;&#9;
&#9;&#9;&#9;-- GearPreview Children
&#9;&#9;&#9;local GearStats = Instance.new(&quot;Frame&quot;)
&#9;&#9;
&#9;&#9;&#9;GearStats.Name = &quot;GearStats&quot;
&#9;&#9;&#9;GearStats.BackgroundTransparency = 1
&#9;&#9;&#9;GearStats.Position = UDim2.new(0,0,0.75,0)
&#9;&#9;&#9;GearStats.Size = UDim2.new(1,0,0.25,0)
&#9;&#9;&#9;GearStats.ZIndex = 8
&#9;&#9;&#9;GearStats.Parent = GearPreview
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;-- GearStats Children
&#9;&#9;&#9;&#9;local GearName = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;&#9;
&#9;&#9;&#9;&#9;GearName.Name = &quot;GearName&quot;
&#9;&#9;&#9;&#9;GearName.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;GearName.Font = Enum.Font.ArialBold
&#9;&#9;&#9;&#9;GearName.FontSize = Enum.FontSize.Size18
&#9;&#9;&#9;&#9;GearName.Position = UDim2.new(0,-3,0,0)
&#9;&#9;&#9;&#9;GearName.Size = UDim2.new(1,6,1,5)
&#9;&#9;&#9;&#9;GearName.Text = &quot;&quot;
&#9;&#9;&#9;&#9;GearName.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;GearName.TextWrap = true
&#9;&#9;&#9;&#9;GearName.ZIndex = 9
&#9;&#9;&#9;&#9;GearName.Parent = GearStats
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;local GearImage = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;
&#9;&#9;&#9;GearImage.Name = &quot;GearImage&quot;
&#9;&#9;&#9;GearImage.Image = &quot;&quot;
&#9;&#9;&#9;GearImage.BackgroundTransparency = 1
&#9;&#9;&#9;GearImage.Position = UDim2.new(0.125,0,0,0)
&#9;&#9;&#9;GearImage.Size = UDim2.new(0.75,0,0.75,0)
&#9;&#9;&#9;GearImage.ZIndex = 8
&#9;&#9;&#9;GearImage.Parent = GearPreview
&#9;&#9;&#9;
&#9;&#9;&#9;&#9;--GearImage Children
&#9;&#9;&#9;&#9;local GearIcons = Instance.new(&quot;Frame&quot;)
&#9;&#9;&#9;&#9;GearIcons.BackgroundColor3 = Color3.new(0,0,0)
&#9;&#9;&#9;&#9;GearIcons.BackgroundTransparency = 0.5
&#9;&#9;&#9;&#9;GearIcons.BorderSizePixel = 0
&#9;&#9;&#9;
&#9;&#9;&#9;&#9;GearIcons.Name = &quot;GearIcons&quot;
&#9;&#9;&#9;&#9;GearIcons.Position = UDim2.new(0.4,2,0.85,-2)
&#9;&#9;&#9;&#9;GearIcons.Size = UDim2.new(0.6,0,0.15,0)
&#9;&#9;&#9;&#9;GearIcons.Visible = false
&#9;&#9;&#9;&#9;GearIcons.ZIndex = 9
&#9;&#9;&#9;&#9;GearIcons.Parent = GearImage
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;-- GearIcons Children
&#9;&#9;&#9;&#9;&#9;local GenreImage = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;GenreImage.Name = &quot;GenreImage&quot;
&#9;&#9;&#9;&#9;&#9;GenreImage.BackgroundColor3 = Color3.new(102/255,153/255,1)
&#9;&#9;&#9;&#9;&#9;GenreImage.BackgroundTransparency = 0.5
&#9;&#9;&#9;&#9;&#9;GenreImage.BorderSizePixel = 0
&#9;&#9;&#9;&#9;&#9;GenreImage.Size = UDim2.new(0.25,0,1,0)
&#9;&#9;&#9;&#9;&#9;GenreImage.Parent = GearIcons
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;local AttributeOneImage = GenreImage:clone()
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;AttributeOneImage.Name = &quot;AttributeOneImage&quot;
&#9;&#9;&#9;&#9;&#9;AttributeOneImage.BackgroundColor3 = Color3.new(1,51/255,0)
&#9;&#9;&#9;&#9;&#9;AttributeOneImage.Position = UDim2.new(0.25,0,0,0)
&#9;&#9;&#9;&#9;&#9;AttributeOneImage.Parent = GearIcons
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;local AttributeTwoImage = GenreImage:clone()
&#9;&#9;&#9;&#9;&#9;AttributeTwoImage.Name = &quot;AttributeTwoImage&quot;
&#9;&#9;&#9;&#9;&#9;AttributeTwoImage.BackgroundColor3 = Color3.new(153/255,1,153/255)
&#9;&#9;&#9;&#9;&#9;AttributeTwoImage.Position = UDim2.new(0.5,0,0,0)
&#9;&#9;&#9;&#9;&#9;AttributeTwoImage.Parent = GearIcons
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;local AttributeThreeImage = GenreImage:clone()
&#9;&#9;&#9;&#9;&#9;AttributeThreeImage.Name = &quot;AttributeThreeImage&quot;
&#9;&#9;&#9;&#9;&#9;AttributeThreeImage.BackgroundColor3 = Color3.new(0,0.5,0.5)
&#9;&#9;&#9;&#9;&#9;AttributeThreeImage.Position = UDim2.new(0.75,0,0,0)
&#9;&#9;&#9;&#9;&#9;AttributeThreeImage.Parent = GearIcons
&#9;&#9;&#9;&#9;&#9;
</ProtectedString>
</Properties>
</Item>
<Item class="LocalScript" referent="RBX5">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">BackpackGear</string>
<ProtectedString name="Source">--rbxsig%IEUAo3Q1k4Rwb3ZcqPBum//j3+Jm/9Nv0JyCeCRWUrggWps7aG81/aPzlH9pPlMkkdsZwLsCRu6eTTrqzXn2DAJNPRs7y8akc3z91r1DP3jwomfpdT+2DBAmPk3Cdj8NXQzP6T+uEYm2kk2TW9pXonKvCgRVqXFx8J7mTr+aM1M=%
--rbxassetid%45284430%
local t = {}
local function ScopedConnect(parentInstance, instance, event, signalFunc, syncFunc, removeFunc)
&#9;local eventConnection = nil
&#9;--Connection on parentInstance is scoped by parentInstance (when destroyed, it goes away)
&#9;local tryConnect = function()
&#9;&#9;if game:IsAncestorOf(parentInstance) then
&#9;&#9;&#9;--Entering the world, make sure we are connected/synced
&#9;&#9;&#9;if not eventConnection then
&#9;&#9;&#9;&#9;eventConnection = instance[event]:connect(signalFunc)
&#9;&#9;&#9;&#9;if syncFunc then syncFunc() end
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;--Probably leaving the world, so disconnect for now
&#9;&#9;&#9;if eventConnection then
&#9;&#9;&#9;&#9;eventConnection:disconnect()
&#9;&#9;&#9;&#9;if removeFunc then removeFunc() end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;--Hook it up to ancestryChanged signal
&#9;local connection = parentInstance.AncestryChanged:connect(tryConnect)
&#9;
&#9;--Now connect us if we&apos;re already in the world
&#9;tryConnect()
&#9;
&#9;return connection
end
local function getScreenGuiAncestor(instance)
&#9;local localInstance = instance
&#9;while localInstance and not localInstance:IsA(&quot;ScreenGui&quot;) do
&#9;&#9;localInstance = localInstance.Parent
&#9;end
&#9;return localInstance
end
local function CreateButtons(frame, buttons, yPos, ySize)
&#9;local buttonNum = 1
&#9;local buttonObjs = {}
&#9;for i, obj in ipairs(buttons) do
&#9;&#9;local button = Instance.new(&quot;TextButton&quot;)
&#9;&#9;button.Name = &quot;Button&quot; .. buttonNum
&#9;&#9;button.Font = Enum.Font.Arial
&#9;&#9;button.FontSize = Enum.FontSize.Size18
&#9;&#9;button.AutoButtonColor = true
&#9;&#9;button.Modal = true
&#9;&#9;if obj[&quot;Style&quot;] then
&#9;&#9;&#9;button.Style = obj.Style
&#9;&#9;else
&#9;&#9;&#9;button.Style = Enum.ButtonStyle.RobloxButton
&#9;&#9;end
&#9;&#9;if obj[&quot;ZIndex&quot;] then
&#9;&#9;&#9;button.ZIndex = obj.ZIndex
&#9;&#9;end
&#9;&#9;button.Text = obj.Text
&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;button.MouseButton1Click:connect(obj.Function)
&#9;&#9;button.Parent = frame
&#9;&#9;buttonObjs[buttonNum] = button
&#9;&#9;buttonNum = buttonNum + 1
&#9;end
&#9;local numButtons = buttonNum-1
&#9;if numButtons == 1 then
&#9;&#9;frame.Button1.Position = UDim2.new(0.35, 0, yPos.Scale, yPos.Offset)
&#9;&#9;frame.Button1.Size = UDim2.new(.4,0,ySize.Scale, ySize.Offset)
&#9;elseif numButtons == 2 then
&#9;&#9;frame.Button1.Position = UDim2.new(0.1, 0, yPos.Scale, yPos.Offset)
&#9;&#9;frame.Button1.Size = UDim2.new(.8/3,0, ySize.Scale, ySize.Offset)
&#9;&#9;frame.Button2.Position = UDim2.new(0.55, 0, yPos.Scale, yPos.Offset)
&#9;&#9;frame.Button2.Size = UDim2.new(.35,0, ySize.Scale, ySize.Offset)
&#9;elseif numButtons &gt;= 3 then
&#9;&#9;local spacing = .1 / numButtons
&#9;&#9;local buttonSize = .9 / numButtons
&#9;&#9;buttonNum = 1
&#9;&#9;while buttonNum &lt;= numButtons do
&#9;&#9;&#9;buttonObjs[buttonNum].Position = UDim2.new(spacing*buttonNum + (buttonNum-1) * buttonSize, 0, yPos.Scale, yPos.Offset)
&#9;&#9;&#9;buttonObjs[buttonNum].Size = UDim2.new(buttonSize, 0, ySize.Scale, ySize.Offset)
&#9;&#9;&#9;buttonNum = buttonNum + 1
&#9;&#9;end
&#9;end
end
local function setSliderPos(newAbsPosX,slider,sliderPosition,bar,steps)
&#9;local newStep = steps - 1 --otherwise we really get one more step than we want
&#9;local relativePosX = math.min(1, math.max(0, (newAbsPosX - bar.AbsolutePosition.X) / bar.AbsoluteSize.X ))
&#9;local wholeNum, remainder = math.modf(relativePosX * newStep)
&#9;if remainder &gt; 0.5 then
&#9;&#9;wholeNum = wholeNum + 1
&#9;end
&#9;relativePosX = wholeNum/newStep
&#9;local result = math.ceil(relativePosX * newStep)
&#9;if sliderPosition.Value ~= (result + 1) then --only update if we moved a step
&#9;&#9;sliderPosition.Value = result + 1
&#9;&#9;slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
&#9;end
&#9;
end
local function cancelSlide(areaSoak)
&#9;areaSoak.Visible = false
&#9;if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
end
t.CreateStyledMessageDialog = function(title, message, style, buttons)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Size = UDim2.new(0.5, 0, 0, 165)
&#9;frame.Position = UDim2.new(0.25, 0, 0.5, -72.5)
&#9;frame.Name = &quot;MessageDialog&quot;
&#9;frame.Active = true
&#9;frame.Style = Enum.FrameStyle.RobloxRound&#9;
&#9;
&#9;local styleImage = Instance.new(&quot;ImageLabel&quot;)
&#9;styleImage.Name = &quot;StyleImage&quot;
&#9;styleImage.BackgroundTransparency = 1
&#9;styleImage.Position = UDim2.new(0,5,0,15)
&#9;if style == &quot;error&quot; or style == &quot;Error&quot; then
&#9;&#9;styleImage.Size = UDim2.new(0, 71, 0, 71)
&#9;&#9;styleImage.Image = &quot;http://www.roblox.com/asset/?id=42565285&quot;
&#9;elseif style == &quot;notify&quot; or style == &quot;Notify&quot; then
&#9;&#9;styleImage.Size = UDim2.new(0, 71, 0, 71)
&#9;&#9;styleImage.Image = &quot;http://www.roblox.com/asset/?id=42604978&quot;
&#9;elseif style == &quot;confirm&quot; or style == &quot;Confirm&quot; then
&#9;&#9;styleImage.Size = UDim2.new(0, 74, 0, 76)
&#9;&#9;styleImage.Image = &quot;http://www.roblox.com/asset/?id=42557901&quot;
&#9;else
&#9;&#9;return t.CreateMessageDialog(title,message,buttons)
&#9;end
&#9;styleImage.Parent = frame
&#9;
&#9;local titleLabel = Instance.new(&quot;TextLabel&quot;)
&#9;titleLabel.Name = &quot;Title&quot;
&#9;titleLabel.Text = title
&#9;titleLabel.TextStrokeTransparency = 0
&#9;titleLabel.BackgroundTransparency = 1
&#9;titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
&#9;titleLabel.Position = UDim2.new(0, 80, 0, 0)
&#9;titleLabel.Size = UDim2.new(1, -80, 0, 40)
&#9;titleLabel.Font = Enum.Font.ArialBold
&#9;titleLabel.FontSize = Enum.FontSize.Size36
&#9;titleLabel.TextXAlignment = Enum.TextXAlignment.Center
&#9;titleLabel.TextYAlignment = Enum.TextYAlignment.Center
&#9;titleLabel.Parent = frame
&#9;local messageLabel = Instance.new(&quot;TextLabel&quot;)
&#9;messageLabel.Name = &quot;Message&quot;
&#9;messageLabel.Text = message
&#9;messageLabel.TextStrokeTransparency = 0
&#9;messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
&#9;messageLabel.Position = UDim2.new(0.025, 80, 0, 45)
&#9;messageLabel.Size = UDim2.new(0.95, -80, 0, 55)
&#9;messageLabel.BackgroundTransparency = 1
&#9;messageLabel.Font = Enum.Font.Arial
&#9;messageLabel.FontSize = Enum.FontSize.Size18
&#9;messageLabel.TextWrap = true
&#9;messageLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;messageLabel.TextYAlignment = Enum.TextYAlignment.Top
&#9;messageLabel.Parent = frame
&#9;CreateButtons(frame, buttons, UDim.new(0, 105), UDim.new(0, 40) )
&#9;return frame
end
t.CreateMessageDialog = function(title, message, buttons)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Size = UDim2.new(0.5, 0, 0.5, 0)
&#9;frame.Position = UDim2.new(0.25, 0, 0.25, 0)
&#9;frame.Name = &quot;MessageDialog&quot;
&#9;frame.Active = true
&#9;frame.Style = Enum.FrameStyle.RobloxRound
&#9;local titleLabel = Instance.new(&quot;TextLabel&quot;)
&#9;titleLabel.Name = &quot;Title&quot;
&#9;titleLabel.Text = title
&#9;titleLabel.BackgroundTransparency = 1
&#9;titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
&#9;titleLabel.Position = UDim2.new(0, 0, 0, 0)
&#9;titleLabel.Size = UDim2.new(1, 0, 0.15, 0)
&#9;titleLabel.Font = Enum.Font.ArialBold
&#9;titleLabel.FontSize = Enum.FontSize.Size36
&#9;titleLabel.TextXAlignment = Enum.TextXAlignment.Center
&#9;titleLabel.TextYAlignment = Enum.TextYAlignment.Center
&#9;titleLabel.Parent = frame
&#9;local messageLabel = Instance.new(&quot;TextLabel&quot;)
&#9;messageLabel.Name = &quot;Message&quot;
&#9;messageLabel.Text = message
&#9;messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
&#9;messageLabel.Position = UDim2.new(0.025, 0, 0.175, 0)
&#9;messageLabel.Size = UDim2.new(0.95, 0, .55, 0)
&#9;messageLabel.BackgroundTransparency = 1
&#9;messageLabel.Font = Enum.Font.Arial
&#9;messageLabel.FontSize = Enum.FontSize.Size18
&#9;messageLabel.TextWrap = true
&#9;messageLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;messageLabel.TextYAlignment = Enum.TextYAlignment.Top
&#9;messageLabel.Parent = frame
&#9;CreateButtons(frame, buttons, UDim.new(0.8,0), UDim.new(0.15, 0))
&#9;return frame
end
t.CreateDropDownMenu = function(items, onSelect, forRoblox, whiteSkin, baseZ)
&#9;local baseZIndex = 0
&#9;if (type(baseZ) == &quot;number&quot;) then
&#9;&#9;baseZIndex = baseZ
&#9;end
&#9;local width = UDim.new(0, 100)
&#9;local height = UDim.new(0, 32)
&#9;local xPos = 0.055
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;local textColor = Color3.new(1,1,1)
&#9;if (whiteSkin) then
&#9;&#9;textColor = Color3.new(0.5, 0.5, 0.5)
&#9;end
&#9;frame.Name = &quot;DropDownMenu&quot;
&#9;frame.BackgroundTransparency = 1
&#9;frame.Size = UDim2.new(width, height)
&#9;local dropDownMenu = Instance.new(&quot;TextButton&quot;)
&#9;dropDownMenu.Name = &quot;DropDownMenuButton&quot;
&#9;dropDownMenu.TextWrap = true
&#9;dropDownMenu.TextColor3 = textColor
&#9;dropDownMenu.Text = &quot;Choose One&quot;
&#9;dropDownMenu.Font = Enum.Font.ArialBold
&#9;dropDownMenu.FontSize = Enum.FontSize.Size18
&#9;dropDownMenu.TextXAlignment = Enum.TextXAlignment.Left
&#9;dropDownMenu.TextYAlignment = Enum.TextYAlignment.Center
&#9;dropDownMenu.BackgroundTransparency = 1
&#9;dropDownMenu.AutoButtonColor = true
&#9;if (whiteSkin) then
&#9;&#9;dropDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton
&#9;else
&#9;&#9;dropDownMenu.Style = Enum.ButtonStyle.RobloxButton
&#9;end
&#9;dropDownMenu.Size = UDim2.new(1,0,1,0)
&#9;dropDownMenu.Parent = frame
&#9;dropDownMenu.ZIndex = 2 + baseZIndex
&#9;local dropDownIcon = Instance.new(&quot;ImageLabel&quot;)
&#9;dropDownIcon.Name = &quot;Icon&quot;
&#9;dropDownIcon.Active = false
&#9;if (whiteSkin) then
&#9;&#9;dropDownIcon.Image = &quot;rbxasset://textures/ui/dropdown_arrow.png&quot;
&#9;&#9;dropDownIcon.Size = UDim2.new(0,16,0,12)
&#9;&#9;dropDownIcon.Position = UDim2.new(1,-17,0.5, -6)
&#9;else
&#9;&#9;dropDownIcon.Image = &quot;http://www.roblox.com/asset/?id=45732894&quot;
&#9;&#9;dropDownIcon.Size = UDim2.new(0,11,0,6)
&#9;&#9;dropDownIcon.Position = UDim2.new(1,-11,0.5, -2)
&#9;end
&#9;dropDownIcon.BackgroundTransparency = 1
&#9;dropDownIcon.Parent = dropDownMenu
&#9;dropDownIcon.ZIndex = 2 + baseZIndex
&#9;
&#9;local itemCount = #items
&#9;local dropDownItemCount = #items
&#9;local useScrollButtons = false
&#9;if dropDownItemCount &gt; 6 then
&#9;&#9;useScrollButtons = true
&#9;&#9;dropDownItemCount = 6
&#9;end
&#9;
&#9;local droppedDownMenu = Instance.new(&quot;TextButton&quot;)
&#9;droppedDownMenu.Name = &quot;List&quot;
&#9;droppedDownMenu.Text = &quot;&quot;
&#9;droppedDownMenu.BackgroundTransparency = 1
&#9;--droppedDownMenu.AutoButtonColor = true
&#9;if (whiteSkin) then
&#9;&#9;droppedDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton
&#9;else
&#9;&#9;droppedDownMenu.Style = Enum.ButtonStyle.RobloxButton
&#9;end
&#9;droppedDownMenu.Visible = false
&#9;droppedDownMenu.Active = true&#9;--Blocks clicks
&#9;droppedDownMenu.Position = UDim2.new(0,0,0,0)
&#9;droppedDownMenu.Size = UDim2.new(1,0, (1 + dropDownItemCount)*.8, 0)
&#9;droppedDownMenu.Parent = frame
&#9;droppedDownMenu.ZIndex = 2 + baseZIndex
&#9;local choiceButton = Instance.new(&quot;TextButton&quot;)
&#9;choiceButton.Name = &quot;ChoiceButton&quot;
&#9;choiceButton.BackgroundTransparency = 1
&#9;choiceButton.BorderSizePixel = 0
&#9;choiceButton.Text = &quot;ReplaceMe&quot;
&#9;choiceButton.TextColor3 = textColor
&#9;choiceButton.TextXAlignment = Enum.TextXAlignment.Left
&#9;choiceButton.TextYAlignment = Enum.TextYAlignment.Center
&#9;choiceButton.BackgroundColor3 = Color3.new(1, 1, 1)
&#9;choiceButton.Font = Enum.Font.Arial
&#9;choiceButton.FontSize = Enum.FontSize.Size18
&#9;if useScrollButtons then
&#9;&#9;choiceButton.Size = UDim2.new(1,-13, .8/((dropDownItemCount + 1)*.8),0)
&#9;else
&#9;&#9;choiceButton.Size = UDim2.new(1, 0, .8/((dropDownItemCount + 1)*.8),0)
&#9;end
&#9;choiceButton.TextWrap = true
&#9;choiceButton.ZIndex = 2 + baseZIndex
&#9;local areaSoak = Instance.new(&quot;TextButton&quot;)
&#9;areaSoak.Name = &quot;AreaSoak&quot;
&#9;areaSoak.Text = &quot;&quot;
&#9;areaSoak.BackgroundTransparency = 1
&#9;areaSoak.Active = true
&#9;areaSoak.Size = UDim2.new(1,0,1,0)
&#9;areaSoak.Visible = false
&#9;areaSoak.ZIndex = 3 + baseZIndex
&#9;local dropDownSelected = false
&#9;local scrollUpButton
&#9;local scrollDownButton
&#9;local scrollMouseCount = 0
&#9;local setZIndex = function(baseZIndex)
&#9;&#9;droppedDownMenu.ZIndex = baseZIndex +1
&#9;&#9;if scrollUpButton then
&#9;&#9;&#9;scrollUpButton.ZIndex = baseZIndex + 3
&#9;&#9;end
&#9;&#9;if scrollDownButton then
&#9;&#9;&#9;scrollDownButton.ZIndex = baseZIndex + 3
&#9;&#9;end
&#9;&#9;
&#9;&#9;local children = droppedDownMenu:GetChildren()
&#9;&#9;if children then
&#9;&#9;&#9;for i, child in ipairs(children) do
&#9;&#9;&#9;&#9;if child.Name == &quot;ChoiceButton&quot; then
&#9;&#9;&#9;&#9;&#9;child.ZIndex = baseZIndex + 2
&#9;&#9;&#9;&#9;elseif child.Name == &quot;ClickCaptureButton&quot; then
&#9;&#9;&#9;&#9;&#9;child.ZIndex = baseZIndex
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local scrollBarPosition = 1
&#9;local updateScroll = function()
&#9;&#9;if scrollUpButton then
&#9;&#9;&#9;scrollUpButton.Active = scrollBarPosition &gt; 1
&#9;&#9;end
&#9;&#9;if scrollDownButton then
&#9;&#9;&#9;scrollDownButton.Active = scrollBarPosition + dropDownItemCount &lt;= itemCount
&#9;&#9;end
&#9;&#9;local children = droppedDownMenu:GetChildren()
&#9;&#9;if not children then return end
&#9;&#9;local childNum = 1&#9;&#9;&#9;
&#9;&#9;for i, obj in ipairs(children) do
&#9;&#9;&#9;if obj.Name == &quot;ChoiceButton&quot; then
&#9;&#9;&#9;&#9;if childNum &lt; scrollBarPosition or childNum &gt;= scrollBarPosition + dropDownItemCount then
&#9;&#9;&#9;&#9;&#9;obj.Visible = false
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;obj.Position = UDim2.new(0,0,((childNum-scrollBarPosition+1)*.8)/((dropDownItemCount+1)*.8),0)
&#9;&#9;&#9;&#9;&#9;obj.Visible = true
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;obj.TextColor3 = textColor
&#9;&#9;&#9;&#9;obj.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;childNum = childNum + 1
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local toggleVisibility = function()
&#9;&#9;dropDownSelected = not dropDownSelected
&#9;&#9;areaSoak.Visible = not areaSoak.Visible
&#9;&#9;dropDownMenu.Visible = not dropDownSelected
&#9;&#9;droppedDownMenu.Visible = dropDownSelected
&#9;&#9;if dropDownSelected then
&#9;&#9;&#9;setZIndex(4 + baseZIndex)
&#9;&#9;else
&#9;&#9;&#9;setZIndex(2 + baseZIndex)
&#9;&#9;end
&#9;&#9;if useScrollButtons then
&#9;&#9;&#9;updateScroll()
&#9;&#9;end
&#9;end
&#9;droppedDownMenu.MouseButton1Click:connect(toggleVisibility)
&#9;local updateSelection = function(text)
&#9;&#9;local foundItem = false
&#9;&#9;local children = droppedDownMenu:GetChildren()
&#9;&#9;local childNum = 1
&#9;&#9;if children then
&#9;&#9;&#9;for i, obj in ipairs(children) do
&#9;&#9;&#9;&#9;if obj.Name == &quot;ChoiceButton&quot; then
&#9;&#9;&#9;&#9;&#9;if obj.Text == text then
&#9;&#9;&#9;&#9;&#9;&#9;obj.Font = Enum.Font.ArialBold
&#9;&#9;&#9;&#9;&#9;&#9;foundItem = true&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;scrollBarPosition = childNum&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;if (whiteSkin) then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;obj.TextColor3 = Color3.new(90/255,142/255,233/255)
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;obj.Font = Enum.Font.Arial
&#9;&#9;&#9;&#9;&#9;&#9;if (whiteSkin) then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;obj.TextColor3 = textColor
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;childNum = childNum + 1
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;if not text then
&#9;&#9;&#9;dropDownMenu.Text = &quot;Choose One&quot;
&#9;&#9;&#9;scrollBarPosition = 1
&#9;&#9;else
&#9;&#9;&#9;if not foundItem then
&#9;&#9;&#9;&#9;error(&quot;Invalid Selection Update -- &quot; .. text)
&#9;&#9;&#9;end
&#9;&#9;&#9;if scrollBarPosition + dropDownItemCount &gt; itemCount + 1 then
&#9;&#9;&#9;&#9;scrollBarPosition = itemCount - dropDownItemCount + 1
&#9;&#9;&#9;end
&#9;&#9;&#9;dropDownMenu.Text = text
&#9;&#9;end
&#9;end
&#9;
&#9;local function scrollDown()
&#9;&#9;if scrollBarPosition + dropDownItemCount &lt;= itemCount then
&#9;&#9;&#9;scrollBarPosition = scrollBarPosition + 1
&#9;&#9;&#9;updateScroll()
&#9;&#9;&#9;return true
&#9;&#9;end
&#9;&#9;return false
&#9;end
&#9;local function scrollUp()
&#9;&#9;if scrollBarPosition &gt; 1 then
&#9;&#9;&#9;scrollBarPosition = scrollBarPosition - 1
&#9;&#9;&#9;updateScroll()
&#9;&#9;&#9;return true
&#9;&#9;end
&#9;&#9;return false
&#9;end
&#9;
&#9;if useScrollButtons then
&#9;&#9;--Make some scroll buttons
&#9;&#9;scrollUpButton = Instance.new(&quot;ImageButton&quot;)
&#9;&#9;scrollUpButton.Name = &quot;ScrollUpButton&quot;
&#9;&#9;scrollUpButton.BackgroundTransparency = 1
&#9;&#9;scrollUpButton.Image = &quot;rbxasset://textures/ui/scrollbuttonUp.png&quot;
&#9;&#9;scrollUpButton.Size = UDim2.new(0,17,0,17)
&#9;&#9;scrollUpButton.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),0)
&#9;&#9;scrollUpButton.MouseButton1Click:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;&#9;&#9;end)
&#9;&#9;scrollUpButton.MouseLeave:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;&#9;&#9;end)
&#9;&#9;scrollUpButton.MouseButton1Down:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;
&#9;&#9;&#9;&#9;scrollUp()
&#9;&#9;&#9;&#9;local val = scrollMouseCount
&#9;&#9;&#9;&#9;wait(0.5)
&#9;&#9;&#9;&#9;while val == scrollMouseCount do
&#9;&#9;&#9;&#9;&#9;if scrollUp() == false then
&#9;&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;wait(0.1)
&#9;&#9;&#9;&#9;end&#9;&#9;&#9;&#9;
&#9;&#9;&#9;end)
&#9;&#9;scrollUpButton.Parent = droppedDownMenu
&#9;&#9;scrollDownButton = Instance.new(&quot;ImageButton&quot;)
&#9;&#9;scrollDownButton.Name = &quot;ScrollDownButton&quot;
&#9;&#9;scrollDownButton.BackgroundTransparency = 1
&#9;&#9;scrollDownButton.Image = &quot;rbxasset://textures/ui/scrollbuttonDown.png&quot;
&#9;&#9;scrollDownButton.Size = UDim2.new(0,17,0,17)
&#9;&#9;scrollDownButton.Position = UDim2.new(1,-11,1,-11)
&#9;&#9;scrollDownButton.Parent = droppedDownMenu
&#9;&#9;scrollDownButton.MouseButton1Click:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;&#9;&#9;end)
&#9;&#9;scrollDownButton.MouseLeave:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;&#9;&#9;end)
&#9;&#9;scrollDownButton.MouseButton1Down:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;&#9;&#9;&#9;scrollDown()
&#9;&#9;&#9;&#9;local val = scrollMouseCount
&#9;&#9;&#9;&#9;wait(0.5)
&#9;&#9;&#9;&#9;while val == scrollMouseCount do
&#9;&#9;&#9;&#9;&#9;if scrollDown() == false then
&#9;&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;wait(0.1)
&#9;&#9;&#9;&#9;end&#9;&#9;&#9;&#9;
&#9;&#9;&#9;end)&#9;
&#9;&#9;local scrollbar = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;scrollbar.Name = &quot;ScrollBar&quot;
&#9;&#9;scrollbar.Image = &quot;rbxasset://textures/ui/scrollbar.png&quot;
&#9;&#9;scrollbar.BackgroundTransparency = 1
&#9;&#9;scrollbar.Size = UDim2.new(0, 18, (dropDownItemCount*.8)/((dropDownItemCount+1)*.8), -(17) - 11 - 4)
&#9;&#9;scrollbar.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),17+2)
&#9;&#9;scrollbar.Parent = droppedDownMenu
&#9;end
&#9;for i,item in ipairs(items) do
&#9;&#9;-- needed to maintain local scope for items in event listeners below
&#9;&#9;local button = choiceButton:clone()
&#9;&#9;if forRoblox then
&#9;&#9;&#9;button.RobloxLocked = true
&#9;&#9;end&#9;&#9;
&#9;&#9;button.Text = item
&#9;&#9;button.Parent = droppedDownMenu
&#9;&#9;if (whiteSkin) then
&#9;&#9;&#9;button.TextColor3 = textColor
&#9;&#9;end
&#9;&#9;button.MouseButton1Click:connect(function()
&#9;&#9;&#9;--Remove Highlight
&#9;&#9;&#9;if (not whiteSkin) then
&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;end
&#9;&#9;&#9;button.BackgroundTransparency = 1
&#9;&#9;&#9;updateSelection(item)
&#9;&#9;&#9;onSelect(item)
&#9;&#9;&#9;toggleVisibility()
&#9;&#9;end)
&#9;&#9;button.MouseEnter:connect(function()
&#9;&#9;&#9;--Add Highlight&#9;
&#9;&#9;&#9;if (not whiteSkin) then
&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(0,0,0)
&#9;&#9;&#9;end
&#9;&#9;&#9;button.BackgroundTransparency = 0
&#9;&#9;end)
&#9;&#9;button.MouseLeave:connect(function()
&#9;&#9;&#9;--Remove Highlight
&#9;&#9;&#9;if (not whiteSkin) then
&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;end
&#9;&#9;&#9;button.BackgroundTransparency = 1
&#9;&#9;end)
&#9;end
&#9;--This does the initial layout of the buttons&#9;
&#9;updateScroll()
&#9;
&#9;frame.AncestryChanged:connect(function(child,parent)
&#9;&#9;if parent == nil then
&#9;&#9;&#9;areaSoak.Parent = nil
&#9;&#9;else
&#9;&#9;&#9;areaSoak.Parent = getScreenGuiAncestor(frame)
&#9;&#9;end
&#9;end)
&#9;dropDownMenu.MouseButton1Click:connect(toggleVisibility)
&#9;areaSoak.MouseButton1Click:connect(toggleVisibility)
&#9;return frame, updateSelection
end
t.CreatePropertyDropDownMenu = function(instance, property, enum)
&#9;local items = enum:GetEnumItems()
&#9;local names = {}
&#9;local nameToItem = {}
&#9;for i,obj in ipairs(items) do
&#9;&#9;names[i] = obj.Name
&#9;&#9;nameToItem[obj.Name] = obj
&#9;end
&#9;local frame
&#9;local updateSelection
&#9;frame, updateSelection = t.CreateDropDownMenu(names, function(text) instance[property] = nameToItem[text] end)
&#9;ScopedConnect(frame, instance, &quot;Changed&quot;,
&#9;&#9;function(prop)
&#9;&#9;&#9;if prop == property then
&#9;&#9;&#9;&#9;updateSelection(instance[property].Name)
&#9;&#9;&#9;end
&#9;&#9;end,
&#9;&#9;function()
&#9;&#9;&#9;updateSelection(instance[property].Name)
&#9;&#9;end)
&#9;return frame
end
t.GetFontHeight = function(font, fontSize)
&#9;if font == nil or fontSize == nil then
&#9;&#9;error(&quot;Font and FontSize must be non-nil&quot;)
&#9;end
&#9;if font == Enum.Font.Legacy then
&#9;&#9;if fontSize == Enum.FontSize.Size8 then
&#9;&#9;&#9;return 12
&#9;&#9;elseif fontSize == Enum.FontSize.Size9 then
&#9;&#9;&#9;return 14
&#9;&#9;elseif fontSize == Enum.FontSize.Size10 then
&#9;&#9;&#9;return 15
&#9;&#9;elseif fontSize == Enum.FontSize.Size11 then
&#9;&#9;&#9;return 17
&#9;&#9;elseif fontSize == Enum.FontSize.Size12 then
&#9;&#9;&#9;return 18
&#9;&#9;elseif fontSize == Enum.FontSize.Size14 then
&#9;&#9;&#9;return 21
&#9;&#9;elseif fontSize == Enum.FontSize.Size18 then
&#9;&#9;&#9;return 27
&#9;&#9;elseif fontSize == Enum.FontSize.Size24 then
&#9;&#9;&#9;return 36
&#9;&#9;elseif fontSize == Enum.FontSize.Size36 then
&#9;&#9;&#9;return 54
&#9;&#9;elseif fontSize == Enum.FontSize.Size48 then
&#9;&#9;&#9;return 72
&#9;&#9;else
&#9;&#9;&#9;error(&quot;Unknown FontSize&quot;)
&#9;&#9;end
&#9;elseif font == Enum.Font.Arial or font == Enum.Font.ArialBold then
&#9;&#9;if fontSize == Enum.FontSize.Size8 then
&#9;&#9;&#9;return 8
&#9;&#9;elseif fontSize == Enum.FontSize.Size9 then
&#9;&#9;&#9;return 9
&#9;&#9;elseif fontSize == Enum.FontSize.Size10 then
&#9;&#9;&#9;return 10
&#9;&#9;elseif fontSize == Enum.FontSize.Size11 then
&#9;&#9;&#9;return 11
&#9;&#9;elseif fontSize == Enum.FontSize.Size12 then
&#9;&#9;&#9;return 12
&#9;&#9;elseif fontSize == Enum.FontSize.Size14 then
&#9;&#9;&#9;return 14
&#9;&#9;elseif fontSize == Enum.FontSize.Size18 then
&#9;&#9;&#9;return 18
&#9;&#9;elseif fontSize == Enum.FontSize.Size24 then
&#9;&#9;&#9;return 24
&#9;&#9;elseif fontSize == Enum.FontSize.Size36 then
&#9;&#9;&#9;return 36
&#9;&#9;elseif fontSize == Enum.FontSize.Size48 then
&#9;&#9;&#9;return 48
&#9;&#9;else
&#9;&#9;&#9;error(&quot;Unknown FontSize&quot;)
&#9;&#9;end
&#9;else
&#9;&#9;error(&quot;Unknown Font &quot; .. font)
&#9;end
end
local function layoutGuiObjectsHelper(frame, guiObjects, settingsTable)
&#9;local totalPixels = frame.AbsoluteSize.Y
&#9;local pixelsRemaining = frame.AbsoluteSize.Y
&#9;for i, child in ipairs(guiObjects) do
&#9;&#9;if child:IsA(&quot;TextLabel&quot;) or child:IsA(&quot;TextButton&quot;) then
&#9;&#9;&#9;local isLabel = child:IsA(&quot;TextLabel&quot;)
&#9;&#9;&#9;if isLabel then
&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - settingsTable[&quot;TextLabelPositionPadY&quot;]
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - settingsTable[&quot;TextButtonPositionPadY&quot;]
&#9;&#9;&#9;end
&#9;&#9;&#9;child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
&#9;&#9;&#9;child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, pixelsRemaining)
&#9;&#9;&#9;if child.TextFits and child.TextBounds.Y &lt; pixelsRemaining then
&#9;&#9;&#9;&#9;child.Visible = true
&#9;&#9;&#9;&#9;if isLabel then
&#9;&#9;&#9;&#9;&#9;child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable[&quot;TextLabelSizePadY&quot;])
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable[&quot;TextButtonSizePadY&quot;])
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;while not child.TextFits do
&#9;&#9;&#9;&#9;&#9;child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.AbsoluteSize.Y + 1)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y&#9;&#9;
&#9;&#9;&#9;&#9;if isLabel then
&#9;&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - settingsTable[&quot;TextLabelPositionPadY&quot;]
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - settingsTable[&quot;TextButtonPositionPadY&quot;]
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;&#9;pixelsRemaining = -1
&#9;&#9;&#9;end&#9;&#9;&#9;
&#9;&#9;else
&#9;&#9;&#9;--GuiObject
&#9;&#9;&#9;child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
&#9;&#9;&#9;child.Visible = (pixelsRemaining &gt;= 0)
&#9;&#9;end
&#9;end
end
t.LayoutGuiObjects = function(frame, guiObjects, settingsTable)
&#9;if not frame:IsA(&quot;GuiObject&quot;) then
&#9;&#9;error(&quot;Frame must be a GuiObject&quot;)
&#9;end
&#9;for i, child in ipairs(guiObjects) do
&#9;&#9;if not child:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;error(&quot;All elements that are layed out must be of type GuiObject&quot;)
&#9;&#9;end
&#9;end
&#9;if not settingsTable then
&#9;&#9;settingsTable = {}
&#9;end
&#9;if not settingsTable[&quot;TextLabelSizePadY&quot;] then
&#9;&#9;settingsTable[&quot;TextLabelSizePadY&quot;] = 0
&#9;end
&#9;if not settingsTable[&quot;TextLabelPositionPadY&quot;] then
&#9;&#9;settingsTable[&quot;TextLabelPositionPadY&quot;] = 0
&#9;end
&#9;if not settingsTable[&quot;TextButtonSizePadY&quot;] then
&#9;&#9;settingsTable[&quot;TextButtonSizePadY&quot;] = 12
&#9;end
&#9;if not settingsTable[&quot;TextButtonPositionPadY&quot;] then
&#9;&#9;settingsTable[&quot;TextButtonPositionPadY&quot;] = 2
&#9;end
&#9;--Wrapper frame takes care of styled objects
&#9;local wrapperFrame = Instance.new(&quot;Frame&quot;)
&#9;wrapperFrame.Name = &quot;WrapperFrame&quot;
&#9;wrapperFrame.BackgroundTransparency = 1
&#9;wrapperFrame.Size = UDim2.new(1,0,1,0)
&#9;wrapperFrame.Parent = frame
&#9;for i, child in ipairs(guiObjects) do
&#9;&#9;child.Parent = wrapperFrame
&#9;end
&#9;local recalculate = function()
&#9;&#9;wait()
&#9;&#9;layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable)
&#9;end
&#9;
&#9;frame.Changed:connect(
&#9;&#9;function(prop)
&#9;&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;&#9;--Wait a heartbeat for it to sync in
&#9;&#9;&#9;&#9;recalculate(nil)
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;frame.AncestryChanged:connect(recalculate)
&#9;layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable)
end
t.CreateSlider = function(steps,width,position)
&#9;local sliderGui = Instance.new(&quot;Frame&quot;)
&#9;sliderGui.Size = UDim2.new(1,0,1,0)
&#9;sliderGui.BackgroundTransparency = 1
&#9;sliderGui.Name = &quot;SliderGui&quot;
&#9;
&#9;local sliderSteps = Instance.new(&quot;IntValue&quot;)
&#9;sliderSteps.Name = &quot;SliderSteps&quot;
&#9;sliderSteps.Value = steps
&#9;sliderSteps.Parent = sliderGui
&#9;
&#9;local areaSoak = Instance.new(&quot;TextButton&quot;)
&#9;areaSoak.Name = &quot;AreaSoak&quot;
&#9;areaSoak.Text = &quot;&quot;
&#9;areaSoak.BackgroundTransparency = 1
&#9;areaSoak.Active = false
&#9;areaSoak.Size = UDim2.new(1,0,1,0)
&#9;areaSoak.Visible = false
&#9;areaSoak.ZIndex = 4
&#9;
&#9;sliderGui.AncestryChanged:connect(function(child,parent)
&#9;&#9;if parent == nil then
&#9;&#9;&#9;areaSoak.Parent = nil
&#9;&#9;else
&#9;&#9;&#9;areaSoak.Parent = getScreenGuiAncestor(sliderGui)
&#9;&#9;end
&#9;end)
&#9;
&#9;local sliderPosition = Instance.new(&quot;IntValue&quot;)
&#9;sliderPosition.Name = &quot;SliderPosition&quot;
&#9;sliderPosition.Value = 0
&#9;sliderPosition.Parent = sliderGui
&#9;
&#9;local id = math.random(1,100)
&#9;
&#9;local bar = Instance.new(&quot;TextButton&quot;)
&#9;bar.Text = &quot;&quot;
&#9;bar.AutoButtonColor = false
&#9;bar.Name = &quot;Bar&quot;
&#9;bar.BackgroundColor3 = Color3.new(0,0,0)
&#9;if type(width) == &quot;number&quot; then
&#9;&#9;bar.Size = UDim2.new(0,width,0,5)
&#9;else
&#9;&#9;bar.Size = UDim2.new(0,200,0,5)
&#9;end
&#9;bar.BorderColor3 = Color3.new(95/255,95/255,95/255)
&#9;bar.ZIndex = 2
&#9;bar.Parent = sliderGui
&#9;
&#9;if position[&quot;X&quot;] and position[&quot;X&quot;][&quot;Scale&quot;] and position[&quot;X&quot;][&quot;Offset&quot;] and position[&quot;Y&quot;] and position[&quot;Y&quot;][&quot;Scale&quot;] and position[&quot;Y&quot;][&quot;Offset&quot;] then
&#9;&#9;bar.Position = position
&#9;end
&#9;
&#9;local slider = Instance.new(&quot;ImageButton&quot;)
&#9;slider.Name = &quot;Slider&quot;
&#9;slider.BackgroundTransparency = 1
&#9;slider.Image = &quot;rbxasset://textures/ui/Slider.png&quot;
&#9;slider.Position = UDim2.new(0,0,0.5,-10)
&#9;slider.Size = UDim2.new(0,20,0,20)
&#9;slider.ZIndex = 3
&#9;slider.Parent = bar
&#9;
&#9;local areaSoakMouseMoveCon = nil
&#9;
&#9;areaSoak.MouseLeave:connect(function()
&#9;&#9;if areaSoak.Visible then
&#9;&#9;&#9;cancelSlide(areaSoak)
&#9;&#9;end
&#9;end)
&#9;areaSoak.MouseButton1Up:connect(function()
&#9;&#9;if areaSoak.Visible then
&#9;&#9;&#9;cancelSlide(areaSoak)
&#9;&#9;end
&#9;end)
&#9;
&#9;slider.MouseButton1Down:connect(function()
&#9;&#9;areaSoak.Visible = true
&#9;&#9;if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
&#9;&#9;areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y)
&#9;&#9;&#9;setSliderPos(x,slider,sliderPosition,bar,steps)
&#9;&#9;end)
&#9;end)
&#9;
&#9;slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end)
&#9;
&#9;sliderPosition.Changed:connect(function(prop)
&#9;&#9;sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value))
&#9;&#9;local relativePosX = (sliderPosition.Value - 1) / (steps - 1)
&#9;&#9;slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
&#9;end)
&#9;
&#9;bar.MouseButton1Down:connect(function(x,y)
&#9;&#9;setSliderPos(x,slider,sliderPosition,bar,steps)
&#9;end)
&#9;
&#9;return sliderGui, sliderPosition, sliderSteps
end
t.CreateSliderNew = function(steps,width,position)
&#9;local sliderGui = Instance.new(&quot;Frame&quot;)
&#9;sliderGui.Size = UDim2.new(1,0,1,0)
&#9;sliderGui.BackgroundTransparency = 1
&#9;sliderGui.Name = &quot;SliderGui&quot;
&#9;
&#9;local sliderSteps = Instance.new(&quot;IntValue&quot;)
&#9;sliderSteps.Name = &quot;SliderSteps&quot;
&#9;sliderSteps.Value = steps
&#9;sliderSteps.Parent = sliderGui
&#9;
&#9;local areaSoak = Instance.new(&quot;TextButton&quot;)
&#9;areaSoak.Name = &quot;AreaSoak&quot;
&#9;areaSoak.Text = &quot;&quot;
&#9;areaSoak.BackgroundTransparency = 1
&#9;areaSoak.Active = false
&#9;areaSoak.Size = UDim2.new(1,0,1,0)
&#9;areaSoak.Visible = false
&#9;areaSoak.ZIndex = 6
&#9;
&#9;sliderGui.AncestryChanged:connect(function(child,parent)
&#9;&#9;if parent == nil then
&#9;&#9;&#9;areaSoak.Parent = nil
&#9;&#9;else
&#9;&#9;&#9;areaSoak.Parent = getScreenGuiAncestor(sliderGui)
&#9;&#9;end
&#9;end)
&#9;
&#9;local sliderPosition = Instance.new(&quot;IntValue&quot;)
&#9;sliderPosition.Name = &quot;SliderPosition&quot;
&#9;sliderPosition.Value = 0
&#9;sliderPosition.Parent = sliderGui
&#9;
&#9;local id = math.random(1,100)
&#9;
&#9;local sliderBarImgHeight = 7
&#9;local sliderBarCapImgWidth = 4
&#9;local bar = Instance.new(&quot;ImageButton&quot;)
&#9;bar.BackgroundTransparency = 1
&#9;bar.Image = &quot;rbxasset://textures/ui/Slider-BKG-Center.png&quot;
&#9;bar.Name = &quot;Bar&quot;
&#9;local displayWidth = 200
&#9;if type(width) == &quot;number&quot; then
&#9;&#9;bar.Size = UDim2.new(0,width - (sliderBarCapImgWidth * 2),0,sliderBarImgHeight)
&#9;&#9;displayWidth = width - (sliderBarCapImgWidth * 2)
&#9;else
&#9;&#9;bar.Size = UDim2.new(0,200,0,sliderBarImgHeight)
&#9;end
&#9;bar.ZIndex = 3
&#9;bar.Parent = sliderGui&#9;
&#9;if position[&quot;X&quot;] and position[&quot;X&quot;][&quot;Scale&quot;] and position[&quot;X&quot;][&quot;Offset&quot;] and position[&quot;Y&quot;] and position[&quot;Y&quot;][&quot;Scale&quot;] and position[&quot;Y&quot;][&quot;Offset&quot;] then
&#9;&#9;bar.Position = position
&#9;end
&#9;local barLeft = bar:clone()
&#9;barLeft.Name = &quot;BarLeft&quot;
&#9;barLeft.Image = &quot;rbxasset://textures/ui/Slider-BKG-Left-Cap.png&quot;
&#9;barLeft.Size = UDim2.new(0, sliderBarCapImgWidth, 0, sliderBarImgHeight)
&#9;barLeft.Position = UDim2.new(position.X.Scale, position.X.Offset - sliderBarCapImgWidth, position.Y.Scale, position.Y.Offset)
&#9;barLeft.Parent = sliderGui&#9;
&#9;barLeft.ZIndex = 3
&#9;local barRight = barLeft:clone()
&#9;barRight.Name = &quot;BarRight&quot;
&#9;barRight.Image = &quot;rbxasset://textures/ui/Slider-BKG-Right-Cap.png&quot;
&#9;barRight.Position = UDim2.new(position.X.Scale, position.X.Offset + displayWidth, position.Y.Scale, position.Y.Offset)
&#9;barRight.Parent = sliderGui&#9;
&#9;local fillLeft = barLeft:clone()
&#9;fillLeft.Name = &quot;FillLeft&quot;
&#9;fillLeft.Image = &quot;rbxasset://textures/ui/Slider-Fill-Left-Cap.png&quot;
&#9;fillLeft.Parent = sliderGui&#9;
&#9;fillLeft.ZIndex = 4
&#9;local fill = fillLeft:clone()
&#9;fill.Name = &quot;Fill&quot;
&#9;fill.Image = &quot;rbxasset://textures/ui/Slider-Fill-Center.png&quot;
&#9;fill.Parent = bar&#9;
&#9;fill.ZIndex = 4
&#9;fill.Position = UDim2.new(0, 0, 0, 0)
&#9;fill.Size = UDim2.new(0.5, 0, 1, 0)
--&#9;bar.Visible = false
&#9;local slider = Instance.new(&quot;ImageButton&quot;)
&#9;slider.Name = &quot;Slider&quot;
&#9;slider.BackgroundTransparency = 1
&#9;slider.Image = &quot;rbxasset://textures/ui/slider_new_tab.png&quot;
&#9;slider.Position = UDim2.new(0,0,0.5,-14)
&#9;slider.Size = UDim2.new(0,28,0,28)
&#9;slider.ZIndex = 5
&#9;slider.Parent = bar
&#9;
&#9;local areaSoakMouseMoveCon = nil
&#9;
&#9;areaSoak.MouseLeave:connect(function()
&#9;&#9;if areaSoak.Visible then
&#9;&#9;&#9;cancelSlide(areaSoak)
&#9;&#9;end
&#9;end)
&#9;areaSoak.MouseButton1Up:connect(function()
&#9;&#9;if areaSoak.Visible then
&#9;&#9;&#9;cancelSlide(areaSoak)
&#9;&#9;end
&#9;end)
&#9;
&#9;slider.MouseButton1Down:connect(function()
&#9;&#9;areaSoak.Visible = true
&#9;&#9;if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
&#9;&#9;areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y)
&#9;&#9;&#9;setSliderPos(x,slider,sliderPosition,bar,steps)
&#9;&#9;end)
&#9;end)
&#9;
&#9;slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end)
&#9;
&#9;sliderPosition.Changed:connect(function(prop)
&#9;&#9;sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value))
&#9;&#9;local relativePosX = (sliderPosition.Value - 1) / (steps - 1)
&#9;&#9;slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
&#9;&#9;fill.Size = UDim2.new(relativePosX, 0, 1, 0)
&#9;end)
&#9;
&#9;bar.MouseButton1Down:connect(function(x,y)
&#9;&#9;setSliderPos(x,slider,sliderPosition,bar,steps)
&#9;end)
&#9;return sliderGui, sliderPosition, sliderSteps
end
t.CreateTrueScrollingFrame = function()
&#9;local lowY = nil
&#9;local highY = nil
&#9;
&#9;local dragCon = nil
&#9;local upCon = nil
&#9;local internalChange = false
&#9;local descendantsChangeConMap = {}
&#9;local scrollingFrame = Instance.new(&quot;Frame&quot;)
&#9;scrollingFrame.Name = &quot;ScrollingFrame&quot;
&#9;scrollingFrame.Active = true
&#9;scrollingFrame.Size = UDim2.new(1,0,1,0)
&#9;scrollingFrame.ClipsDescendants = true
&#9;local controlFrame = Instance.new(&quot;Frame&quot;)
&#9;controlFrame.Name = &quot;ControlFrame&quot;
&#9;controlFrame.BackgroundTransparency = 1
&#9;controlFrame.Size = UDim2.new(0,18,1,0)
&#9;controlFrame.Position = UDim2.new(1,-20,0,0)
&#9;controlFrame.Parent = scrollingFrame
&#9;
&#9;local scrollBottom = Instance.new(&quot;BoolValue&quot;)
&#9;scrollBottom.Value = false
&#9;scrollBottom.Name = &quot;ScrollBottom&quot;
&#9;scrollBottom.Parent = controlFrame
&#9;
&#9;local scrollUp = Instance.new(&quot;BoolValue&quot;)
&#9;scrollUp.Value = false
&#9;scrollUp.Name = &quot;scrollUp&quot;
&#9;scrollUp.Parent = controlFrame
&#9;local scrollUpButton = Instance.new(&quot;TextButton&quot;)
&#9;scrollUpButton.Name = &quot;ScrollUpButton&quot;
&#9;scrollUpButton.Text = &quot;&quot;
&#9;scrollUpButton.AutoButtonColor = false
&#9;scrollUpButton.BackgroundColor3 = Color3.new(0,0,0)
&#9;scrollUpButton.BorderColor3 = Color3.new(1,1,1)
&#9;scrollUpButton.BackgroundTransparency = 0.5
&#9;scrollUpButton.Size = UDim2.new(0,18,0,18)
&#9;scrollUpButton.ZIndex = 2
&#9;scrollUpButton.Parent = controlFrame
&#9;for i = 1, 6 do
&#9;&#9;local triFrame = Instance.new(&quot;Frame&quot;)
&#9;&#9;triFrame.BorderColor3 = Color3.new(1,1,1)
&#9;&#9;triFrame.Name = &quot;tri&quot; .. tostring(i)
&#9;&#9;triFrame.ZIndex = 3
&#9;&#9;triFrame.BackgroundTransparency = 0.5
&#9;&#9;triFrame.Size = UDim2.new(0,12 - ((i -1) * 2),0,0)
&#9;&#9;triFrame.Position = UDim2.new(0,3 + (i -1),0.5,2 - (i -1))
&#9;&#9;triFrame.Parent = scrollUpButton
&#9;end
&#9;scrollUpButton.MouseEnter:connect(function()
&#9;&#9;scrollUpButton.BackgroundTransparency = 0.1
&#9;&#9;local upChildren = scrollUpButton:GetChildren()
&#9;&#9;for i = 1, #upChildren do
&#9;&#9;&#9;upChildren[i].BackgroundTransparency = 0.1
&#9;&#9;end
&#9;end)
&#9;scrollUpButton.MouseLeave:connect(function()
&#9;&#9;scrollUpButton.BackgroundTransparency = 0.5
&#9;&#9;local upChildren = scrollUpButton:GetChildren()
&#9;&#9;for i = 1, #upChildren do
&#9;&#9;&#9;upChildren[i].BackgroundTransparency = 0.5
&#9;&#9;end
&#9;end)
&#9;local scrollDownButton = scrollUpButton:clone()
&#9;scrollDownButton.Name = &quot;ScrollDownButton&quot;
&#9;scrollDownButton.Position = UDim2.new(0,0,1,-18)
&#9;local downChildren = scrollDownButton:GetChildren()
&#9;for i = 1, #downChildren do
&#9;&#9;downChildren[i].Position = UDim2.new(0,3 + (i -1),0.5,-2 + (i - 1))
&#9;end
&#9;scrollDownButton.MouseEnter:connect(function()
&#9;&#9;scrollDownButton.BackgroundTransparency = 0.1
&#9;&#9;local downChildren = scrollDownButton:GetChildren()
&#9;&#9;for i = 1, #downChildren do
&#9;&#9;&#9;downChildren[i].BackgroundTransparency = 0.1
&#9;&#9;end
&#9;end)
&#9;scrollDownButton.MouseLeave:connect(function()
&#9;&#9;scrollDownButton.BackgroundTransparency = 0.5
&#9;&#9;local downChildren = scrollDownButton:GetChildren()
&#9;&#9;for i = 1, #downChildren do
&#9;&#9;&#9;downChildren[i].BackgroundTransparency = 0.5
&#9;&#9;end
&#9;end)
&#9;scrollDownButton.Parent = controlFrame
&#9;
&#9;local scrollTrack = Instance.new(&quot;Frame&quot;)
&#9;scrollTrack.Name = &quot;ScrollTrack&quot;
&#9;scrollTrack.BackgroundTransparency = 1
&#9;scrollTrack.Size = UDim2.new(0,18,1,-38)
&#9;scrollTrack.Position = UDim2.new(0,0,0,19)
&#9;scrollTrack.Parent = controlFrame
&#9;local scrollbar = Instance.new(&quot;TextButton&quot;)
&#9;scrollbar.BackgroundColor3 = Color3.new(0,0,0)
&#9;scrollbar.BorderColor3 = Color3.new(1,1,1)
&#9;scrollbar.BackgroundTransparency = 0.5
&#9;scrollbar.AutoButtonColor = false
&#9;scrollbar.Text = &quot;&quot;
&#9;scrollbar.Active = true
&#9;scrollbar.Name = &quot;ScrollBar&quot;
&#9;scrollbar.ZIndex = 2
&#9;scrollbar.BackgroundTransparency = 0.5
&#9;scrollbar.Size = UDim2.new(0, 18, 0.1, 0)
&#9;scrollbar.Position = UDim2.new(0,0,0,0)
&#9;scrollbar.Parent = scrollTrack
&#9;local scrollNub = Instance.new(&quot;Frame&quot;)
&#9;scrollNub.Name = &quot;ScrollNub&quot;
&#9;scrollNub.BorderColor3 = Color3.new(1,1,1)
&#9;scrollNub.Size = UDim2.new(0,10,0,0)
&#9;scrollNub.Position = UDim2.new(0.5,-5,0.5,0)
&#9;scrollNub.ZIndex = 2
&#9;scrollNub.BackgroundTransparency = 0.5
&#9;scrollNub.Parent = scrollbar
&#9;local newNub = scrollNub:clone()
&#9;newNub.Position = UDim2.new(0.5,-5,0.5,-2)
&#9;newNub.Parent = scrollbar
&#9;
&#9;local lastNub = scrollNub:clone()
&#9;lastNub.Position = UDim2.new(0.5,-5,0.5,2)
&#9;lastNub.Parent = scrollbar
&#9;scrollbar.MouseEnter:connect(function()
&#9;&#9;scrollbar.BackgroundTransparency = 0.1
&#9;&#9;scrollNub.BackgroundTransparency = 0.1
&#9;&#9;newNub.BackgroundTransparency = 0.1
&#9;&#9;lastNub.BackgroundTransparency = 0.1
&#9;end)
&#9;scrollbar.MouseLeave:connect(function()
&#9;&#9;scrollbar.BackgroundTransparency = 0.5
&#9;&#9;scrollNub.BackgroundTransparency = 0.5
&#9;&#9;newNub.BackgroundTransparency = 0.5
&#9;&#9;lastNub.BackgroundTransparency = 0.5
&#9;end)
&#9;local mouseDrag = Instance.new(&quot;ImageButton&quot;)
&#9;mouseDrag.Active = false
&#9;mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0)
&#9;mouseDrag.AutoButtonColor = false
&#9;mouseDrag.BackgroundTransparency = 1
&#9;mouseDrag.Name = &quot;mouseDrag&quot;
&#9;mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0)
&#9;mouseDrag.ZIndex = 10
&#9;
&#9;local function positionScrollBar(x,y,offset)
&#9;&#9;local oldPos = scrollbar.Position
&#9;&#9;if y &lt; scrollTrack.AbsolutePosition.y then
&#9;&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0)
&#9;&#9;&#9;return (oldPos ~= scrollbar.Position)
&#9;&#9;end
&#9;&#9;
&#9;&#9;local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y
&#9;&#9;if y &gt; (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then
&#9;&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0)
&#9;&#9;&#9;return (oldPos ~= scrollbar.Position)
&#9;&#9;end
&#9;&#9;local newScaleYPos = (y - scrollTrack.AbsolutePosition.y - offset)/scrollTrack.AbsoluteSize.y
&#9;&#9;if newScaleYPos + relativeSize &gt; 1 then
&#9;&#9;&#9;newScaleYPos = 1 - relativeSize
&#9;&#9;&#9;scrollBottom.Value = true
&#9;&#9;&#9;scrollUp.Value = false
&#9;&#9;elseif newScaleYPos &lt;= 0 then
&#9;&#9;&#9;newScaleYPos = 0
&#9;&#9;&#9;scrollUp.Value = true
&#9;&#9;&#9;scrollBottom.Value = false
&#9;&#9;else
&#9;&#9;&#9;scrollUp.Value = false
&#9;&#9;&#9;scrollBottom.Value = false
&#9;&#9;end
&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,newScaleYPos,0)
&#9;&#9;
&#9;&#9;return (oldPos ~= scrollbar.Position)
&#9;end
&#9;local function drillDownSetHighLow(instance)
&#9;&#9;if not instance or not instance:IsA(&quot;GuiObject&quot;) then return end
&#9;&#9;if instance == controlFrame then return end
&#9;&#9;if instance:IsDescendantOf(controlFrame) then return end
&#9;&#9;if not instance.Visible then return end
&#9;&#9;if lowY and lowY &gt; instance.AbsolutePosition.Y then
&#9;&#9;&#9;lowY = instance.AbsolutePosition.Y
&#9;&#9;elseif not lowY then
&#9;&#9;&#9;lowY = instance.AbsolutePosition.Y
&#9;&#9;end
&#9;&#9;if highY and highY &lt; (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) then
&#9;&#9;&#9;highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
&#9;&#9;elseif not highY then
&#9;&#9;&#9;highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
&#9;&#9;end
&#9;&#9;local children = instance:GetChildren()
&#9;&#9;for i = 1, #children do
&#9;&#9;&#9;drillDownSetHighLow(children[i])
&#9;&#9;end
&#9;end
&#9;local function resetHighLow()
&#9;&#9;local firstChildren = scrollingFrame:GetChildren()
&#9;&#9;for i = 1, #firstChildren do
&#9;&#9;&#9;drillDownSetHighLow(firstChildren[i])
&#9;&#9;end
&#9;end
&#9;local function recalculate()
&#9;&#9;internalChange = true
&#9;&#9;local percentFrame = 0
&#9;&#9;if scrollbar.Position.Y.Scale &gt; 0 then
&#9;&#9;&#9;if scrollbar.Visible then
&#9;&#9;&#9;&#9;percentFrame = scrollbar.Position.Y.Scale/((scrollTrack.AbsoluteSize.Y - scrollbar.AbsoluteSize.Y)/scrollTrack.AbsoluteSize.Y)
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;percentFrame = 0
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;if percentFrame &gt; 0.99 then percentFrame = 1 end
&#9;&#9;local hiddenYAmount = (scrollingFrame.AbsoluteSize.Y - (highY - lowY)) * percentFrame
&#9;&#9;
&#9;&#9;local guiChildren = scrollingFrame:GetChildren()
&#9;&#9;for i = 1, #guiChildren do
&#9;&#9;&#9;if guiChildren[i] ~= controlFrame then
&#9;&#9;&#9;&#9;guiChildren[i].Position = UDim2.new(guiChildren[i].Position.X.Scale,guiChildren[i].Position.X.Offset,
&#9;&#9;&#9;&#9;&#9;0, math.ceil(guiChildren[i].AbsolutePosition.Y) - math.ceil(lowY) + hiddenYAmount)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;lowY = nil
&#9;&#9;highY = nil
&#9;&#9;resetHighLow()
&#9;&#9;internalChange = false
&#9;end
&#9;local function setSliderSizeAndPosition()
&#9;&#9;if not highY or not lowY then return end
&#9;&#9;local totalYSpan = math.abs(highY - lowY)
&#9;&#9;if totalYSpan == 0 then
&#9;&#9;&#9;scrollbar.Visible = false
&#9;&#9;&#9;scrollDownButton.Visible = false
&#9;&#9;&#9;scrollUpButton.Visible = false
&#9;&#9;&#9;if dragCon then dragCon:disconnect() dragCon = nil end
&#9;&#9;&#9;if upCon then upCon:disconnect() upCon = nil end
&#9;&#9;&#9;return
&#9;&#9;end
&#9;&#9;local percentShown = scrollingFrame.AbsoluteSize.Y/totalYSpan
&#9;&#9;if percentShown &gt;= 1 then
&#9;&#9;&#9;scrollbar.Visible = false
&#9;&#9;&#9;scrollDownButton.Visible = false
&#9;&#9;&#9;scrollUpButton.Visible = false
&#9;&#9;&#9;recalculate()
&#9;&#9;else
&#9;&#9;&#9;scrollbar.Visible = true
&#9;&#9;&#9;scrollDownButton.Visible = true
&#9;&#9;&#9;scrollUpButton.Visible = true
&#9;&#9;&#9;scrollbar.Size = UDim2.new(scrollbar.Size.X.Scale,scrollbar.Size.X.Offset,percentShown,0)
&#9;&#9;end
&#9;&#9;local percentPosition = (scrollingFrame.AbsolutePosition.Y - lowY)/totalYSpan
&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,percentPosition,-scrollbar.AbsoluteSize.X/2)
&#9;&#9;if scrollbar.AbsolutePosition.y &lt; scrollTrack.AbsolutePosition.y then
&#9;&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0)
&#9;&#9;end
&#9;&#9;if (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.Y) &gt; (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then
&#9;&#9;&#9;local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y
&#9;&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0)
&#9;&#9;end
&#9;end
&#9;
&#9;local buttonScrollAmountPixels = 7
&#9;local reentrancyGuardScrollUp = false
&#9;local function doScrollUp()
&#9;&#9;if reentrancyGuardScrollUp then return end
&#9;&#9;
&#9;&#9;reentrancyGuardScrollUp = true
&#9;&#9;&#9;if positionScrollBar(0,scrollbar.AbsolutePosition.Y - buttonScrollAmountPixels,0) then
&#9;&#9;&#9;&#9;recalculate()
&#9;&#9;&#9;end
&#9;&#9;reentrancyGuardScrollUp = false
&#9;end
&#9;
&#9;local reentrancyGuardScrollDown = false
&#9;local function doScrollDown()
&#9;&#9;if reentrancyGuardScrollDown then return end
&#9;&#9;
&#9;&#9;reentrancyGuardScrollDown = true
&#9;&#9;&#9;if positionScrollBar(0,scrollbar.AbsolutePosition.Y + buttonScrollAmountPixels,0) then
&#9;&#9;&#9;&#9;recalculate()
&#9;&#9;&#9;end
&#9;&#9;reentrancyGuardScrollDown = false
&#9;end
&#9;local function scrollUp(mouseYPos)
&#9;&#9;if scrollUpButton.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local current = scrollStamp
&#9;&#9;&#9;local upCon
&#9;&#9;&#9;upCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;upCon:disconnect()
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;&#9;doScrollUp()
&#9;&#9;&#9;wait(0.2)
&#9;&#9;&#9;local t = tick()
&#9;&#9;&#9;local w = 0.1
&#9;&#9;&#9;while scrollStamp == current do
&#9;&#9;&#9;&#9;doScrollUp()
&#9;&#9;&#9;&#9;if mouseYPos and mouseYPos &gt; scrollbar.AbsolutePosition.y then
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if not scrollUpButton.Active then break end
&#9;&#9;&#9;&#9;if tick()-t &gt; 5 then
&#9;&#9;&#9;&#9;&#9;w = 0
&#9;&#9;&#9;&#9;elseif tick()-t &gt; 2 then
&#9;&#9;&#9;&#9;&#9;w = 0.06
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;wait(w)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local function scrollDown(mouseYPos)
&#9;&#9;if scrollDownButton.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local current = scrollStamp
&#9;&#9;&#9;local downCon
&#9;&#9;&#9;downCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;downCon:disconnect()
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;&#9;doScrollDown()
&#9;&#9;&#9;wait(0.2)
&#9;&#9;&#9;local t = tick()
&#9;&#9;&#9;local w = 0.1
&#9;&#9;&#9;while scrollStamp == current do
&#9;&#9;&#9;&#9;doScrollDown()
&#9;&#9;&#9;&#9;if mouseYPos and mouseYPos &lt; (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.x) then
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if not scrollDownButton.Active then break end
&#9;&#9;&#9;&#9;if tick()-t &gt; 5 then
&#9;&#9;&#9;&#9;&#9;w = 0
&#9;&#9;&#9;&#9;elseif tick()-t &gt; 2 then
&#9;&#9;&#9;&#9;&#9;w = 0.06
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;wait(w)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;
&#9;scrollbar.MouseButton1Down:connect(function(x,y)
&#9;&#9;if scrollbar.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local mouseOffset = y - scrollbar.AbsolutePosition.y
&#9;&#9;&#9;if dragCon then dragCon:disconnect() dragCon = nil end
&#9;&#9;&#9;if upCon then upCon:disconnect() upCon = nil end
&#9;&#9;&#9;local prevY = y
&#9;&#9;&#9;local reentrancyGuardMouseScroll = false
&#9;&#9;&#9;dragCon = mouseDrag.MouseMoved:connect(function(x,y)
&#9;&#9;&#9;&#9;if reentrancyGuardMouseScroll then return end
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;reentrancyGuardMouseScroll = true
&#9;&#9;&#9;&#9;&#9;if positionScrollBar(x,y,mouseOffset) then
&#9;&#9;&#9;&#9;&#9;&#9;recalculate()
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;reentrancyGuardMouseScroll = false
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;end)
&#9;&#9;&#9;upCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;dragCon:disconnect(); dragCon = nil
&#9;&#9;&#9;&#9;upCon:disconnect(); drag = nil
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;end
&#9;end)
&#9;local scrollMouseCount = 0
&#9;scrollUpButton.MouseButton1Down:connect(function()
&#9;&#9;scrollUp()
&#9;end)
&#9;scrollUpButton.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;scrollDownButton.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;scrollDownButton.MouseButton1Down:connect(function()
&#9;&#9; scrollDown()
&#9;end)
&#9;&#9;
&#9;scrollbar.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;
&#9;local function heightCheck(instance)
&#9;&#9;if highY and (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) &gt; highY then
&#9;&#9;&#9;highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
&#9;&#9;elseif not highY then
&#9;&#9;&#9;highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
&#9;&#9;end
&#9;&#9;setSliderSizeAndPosition()
&#9;end
&#9;
&#9;local function highLowRecheck()
&#9;&#9;local oldLowY = lowY
&#9;&#9;local oldHighY = highY
&#9;&#9;lowY = nil
&#9;&#9;highY = nil
&#9;&#9;resetHighLow()
&#9;&#9;if (lowY ~= oldLowY) or (highY ~= oldHighY) then
&#9;&#9;&#9;setSliderSizeAndPosition()
&#9;&#9;end
&#9;end
&#9;local function descendantChanged(this, prop)
&#9;&#9;if internalChange then return end
&#9;&#9;if not this.Visible then return end
&#9;&#9;if prop == &quot;Size&quot; or prop == &quot;Position&quot; then
&#9;&#9;&#9;wait()
&#9;&#9;&#9;highLowRecheck()
&#9;&#9;end
&#9;end
&#9;scrollingFrame.DescendantAdded:connect(function(instance)
&#9;&#9;if not instance:IsA(&quot;GuiObject&quot;) then return end
&#9;&#9;if instance.Visible then
&#9;&#9;&#9;wait() -- wait a heartbeat for sizes to reconfig
&#9;&#9;&#9;highLowRecheck()
&#9;&#9;end
&#9;&#9;descendantsChangeConMap[instance] = instance.Changed:connect(function(prop) descendantChanged(instance, prop) end)
&#9;end)
&#9;scrollingFrame.DescendantRemoving:connect(function(instance)
&#9;&#9;if not instance:IsA(&quot;GuiObject&quot;) then return end
&#9;&#9;if descendantsChangeConMap[instance] then
&#9;&#9;&#9;descendantsChangeConMap[instance]:disconnect()
&#9;&#9;&#9;descendantsChangeConMap[instance] = nil
&#9;&#9;end
&#9;&#9;wait() -- wait a heartbeat for sizes to reconfig
&#9;&#9;highLowRecheck()
&#9;end)
&#9;
&#9;scrollingFrame.Changed:connect(function(prop)
&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;if not highY or not lowY then return end
&#9;&#9;&#9;highLowRecheck()
&#9;&#9;&#9;setSliderSizeAndPosition()
&#9;&#9;end
&#9;end)
&#9;return scrollingFrame, controlFrame
end
t.CreateScrollingFrame = function(orderList,scrollStyle)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Name = &quot;ScrollingFrame&quot;
&#9;frame.BackgroundTransparency = 1
&#9;frame.Size = UDim2.new(1,0,1,0)
&#9;
&#9;local scrollUpButton = Instance.new(&quot;ImageButton&quot;)
&#9;scrollUpButton.Name = &quot;ScrollUpButton&quot;
&#9;scrollUpButton.BackgroundTransparency = 1
&#9;scrollUpButton.Image = &quot;rbxasset://textures/ui/scrollbuttonUp.png&quot;
&#9;scrollUpButton.Size = UDim2.new(0,17,0,17)
&#9;
&#9;local scrollDownButton = Instance.new(&quot;ImageButton&quot;)
&#9;scrollDownButton.Name = &quot;ScrollDownButton&quot;
&#9;scrollDownButton.BackgroundTransparency = 1
&#9;scrollDownButton.Image = &quot;rbxasset://textures/ui/scrollbuttonDown.png&quot;
&#9;scrollDownButton.Size = UDim2.new(0,17,0,17)
&#9;
&#9;local scrollbar = Instance.new(&quot;ImageButton&quot;)
&#9;scrollbar.Name = &quot;ScrollBar&quot;
&#9;scrollbar.Image = &quot;rbxasset://textures/ui/scrollbar.png&quot;
&#9;scrollbar.BackgroundTransparency = 1
&#9;scrollbar.Size = UDim2.new(0, 18, 0, 150)
&#9;local scrollStamp = 0
&#9;&#9;
&#9;local scrollDrag = Instance.new(&quot;ImageButton&quot;)
&#9;scrollDrag.Image = &quot;http://www.roblox.com/asset/?id=61367186&quot;
&#9;scrollDrag.Size = UDim2.new(1, 0, 0, 16)
&#9;scrollDrag.BackgroundTransparency = 1
&#9;scrollDrag.Name = &quot;ScrollDrag&quot;
&#9;scrollDrag.Active = true
&#9;scrollDrag.Parent = scrollbar
&#9;
&#9;local mouseDrag = Instance.new(&quot;ImageButton&quot;)
&#9;mouseDrag.Active = false
&#9;mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0)
&#9;mouseDrag.AutoButtonColor = false
&#9;mouseDrag.BackgroundTransparency = 1
&#9;mouseDrag.Name = &quot;mouseDrag&quot;
&#9;mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0)
&#9;mouseDrag.ZIndex = 10
&#9;local style = &quot;simple&quot;
&#9;if scrollStyle and tostring(scrollStyle) then
&#9;&#9;style = scrollStyle
&#9;end
&#9;
&#9;local scrollPosition = 1
&#9;local rowSize = 0
&#9;local howManyDisplayed = 0
&#9;&#9;
&#9;local layoutGridScrollBar = function()
&#9;&#9;howManyDisplayed = 0
&#9;&#9;local guiObjects = {}
&#9;&#9;if orderList then
&#9;&#9;&#9;for i, child in ipairs(orderList) do
&#9;&#9;&#9;&#9;if child.Parent == frame then
&#9;&#9;&#9;&#9;&#9;table.insert(guiObjects, child)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;local children = frame:GetChildren()
&#9;&#9;&#9;if children then
&#9;&#9;&#9;&#9;for i, child in ipairs(children) do
&#9;&#9;&#9;&#9;&#9;if child:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;&#9;&#9;table.insert(guiObjects, child)
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;if #guiObjects == 0 then
&#9;&#9;&#9;scrollUpButton.Active = false
&#9;&#9;&#9;scrollDownButton.Active = false
&#9;&#9;&#9;scrollDrag.Active = false
&#9;&#9;&#9;scrollPosition = 1
&#9;&#9;&#9;return
&#9;&#9;end
&#9;&#9;if scrollPosition &gt; #guiObjects then
&#9;&#9;&#9;scrollPosition = #guiObjects
&#9;&#9;end
&#9;&#9;
&#9;&#9;if scrollPosition &lt; 1 then scrollPosition = 1 end
&#9;&#9;
&#9;&#9;local totalPixelsY = frame.AbsoluteSize.Y
&#9;&#9;local pixelsRemainingY = frame.AbsoluteSize.Y
&#9;&#9;
&#9;&#9;local totalPixelsX = frame.AbsoluteSize.X
&#9;&#9;
&#9;&#9;local xCounter = 0
&#9;&#9;local rowSizeCounter = 0
&#9;&#9;local setRowSize = true
&#9;&#9;local pixelsBelowScrollbar = 0
&#9;&#9;local pos = #guiObjects
&#9;&#9;
&#9;&#9;local currentRowY = 0
&#9;&#9;pos = scrollPosition
&#9;&#9;--count up from current scroll position to fill out grid
&#9;&#9;while pos &lt;= #guiObjects and pixelsBelowScrollbar &lt; totalPixelsY do
&#9;&#9;&#9;xCounter = xCounter + guiObjects[pos].AbsoluteSize.X
&#9;&#9;&#9;--previous pos was the end of a row
&#9;&#9;&#9;if xCounter &gt;= totalPixelsX then
&#9;&#9;&#9;&#9;pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
&#9;&#9;&#9;&#9;currentRowY = 0
&#9;&#9;&#9;&#9;xCounter = guiObjects[pos].AbsoluteSize.X
&#9;&#9;&#9;end
&#9;&#9;&#9;if guiObjects[pos].AbsoluteSize.Y &gt; currentRowY then
&#9;&#9;&#9;&#9;currentRowY = guiObjects[pos].AbsoluteSize.Y
&#9;&#9;&#9;end
&#9;&#9;&#9;pos = pos + 1
&#9;&#9;end
&#9;&#9;--Count wherever current row left off
&#9;&#9;pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
&#9;&#9;currentRowY = 0
&#9;&#9;
&#9;&#9;pos = scrollPosition - 1
&#9;&#9;xCounter = 0
&#9;&#9;
&#9;&#9;--objects with varying X,Y dimensions can rarely cause minor errors
&#9;&#9;--rechecking every new scrollPosition is necessary to avoid 100% of errors
&#9;&#9;
&#9;&#9;--count backwards from current scrollPosition to see if we can add more rows
&#9;&#9;while pixelsBelowScrollbar + currentRowY &lt; totalPixelsY and pos &gt;= 1 do
&#9;&#9;&#9;xCounter = xCounter + guiObjects[pos].AbsoluteSize.X
&#9;&#9;&#9;rowSizeCounter = rowSizeCounter + 1
&#9;&#9;&#9;if xCounter &gt;= totalPixelsX then
&#9;&#9;&#9;&#9;rowSize = rowSizeCounter - 1
&#9;&#9;&#9;&#9;rowSizeCounter = 0
&#9;&#9;&#9;&#9;xCounter = guiObjects[pos].AbsoluteSize.X
&#9;&#9;&#9;&#9;if pixelsBelowScrollbar + currentRowY &lt;= totalPixelsY then
&#9;&#9;&#9;&#9;&#9;--It fits, so back up our scroll position
&#9;&#9;&#9;&#9;&#9;pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
&#9;&#9;&#9;&#9;&#9;if scrollPosition &lt;= rowSize then
&#9;&#9;&#9;&#9;&#9;&#9;scrollPosition = 1
&#9;&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;scrollPosition = scrollPosition - rowSize
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;currentRowY = 0
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;
&#9;&#9;&#9;if guiObjects[pos].AbsoluteSize.Y &gt; currentRowY then
&#9;&#9;&#9;&#9;currentRowY = guiObjects[pos].AbsoluteSize.Y
&#9;&#9;&#9;end
&#9;&#9;&#9;pos = pos - 1
&#9;&#9;end
&#9;&#9;
&#9;&#9;--Do check last time if pos = 0
&#9;&#9;if (pos == 0) and (pixelsBelowScrollbar + currentRowY &lt;= totalPixelsY) then
&#9;&#9;&#9;scrollPosition = 1
&#9;&#9;end
&#9;&#9;xCounter = 0
&#9;&#9;--pos = scrollPosition
&#9;&#9;rowSizeCounter = 0
&#9;&#9;setRowSize = true
&#9;&#9;local lastChildSize = 0
&#9;&#9;
&#9;&#9;local xOffset,yOffset = 0
&#9;&#9;if guiObjects[1] then
&#9;&#9;&#9;yOffset = math.ceil(math.floor(math.fmod(totalPixelsY,guiObjects[1].AbsoluteSize.X))/2)
&#9;&#9;&#9;xOffset = math.ceil(math.floor(math.fmod(totalPixelsX,guiObjects[1].AbsoluteSize.Y))/2)
&#9;&#9;end
&#9;&#9;
&#9;&#9;for i, child in ipairs(guiObjects) do
&#9;&#9;&#9;if i &lt; scrollPosition then
&#9;&#9;&#9;&#9;--print(&quot;Hiding &quot; .. child.Name)
&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;if pixelsRemainingY &lt; 0 then
&#9;&#9;&#9;&#9;&#9;--print(&quot;Out of Space &quot; .. child.Name)
&#9;&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;--print(&quot;Laying out &quot; .. child.Name)
&#9;&#9;&#9;&#9;&#9;--GuiObject
&#9;&#9;&#9;&#9;&#9;if setRowSize then rowSizeCounter = rowSizeCounter + 1 end
&#9;&#9;&#9;&#9;&#9;if xCounter + child.AbsoluteSize.X &gt;= totalPixelsX then
&#9;&#9;&#9;&#9;&#9;&#9;if setRowSize then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;rowSize = rowSizeCounter - 1
&#9;&#9;&#9;&#9;&#9;&#9;&#9;setRowSize = false
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;&#9;xCounter = 0
&#9;&#9;&#9;&#9;&#9;&#9;pixelsRemainingY = pixelsRemainingY - child.AbsoluteSize.Y
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;child.Position = UDim2.new(child.Position.X.Scale,xCounter + xOffset, 0, totalPixelsY - pixelsRemainingY + yOffset)
&#9;&#9;&#9;&#9;&#9;xCounter = xCounter + child.AbsoluteSize.X
&#9;&#9;&#9;&#9;&#9;child.Visible = ((pixelsRemainingY - child.AbsoluteSize.Y) &gt;= 0)
&#9;&#9;&#9;&#9;&#9;if child.Visible then
&#9;&#9;&#9;&#9;&#9;&#9;howManyDisplayed = howManyDisplayed + 1
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;lastChildSize = child.AbsoluteSize&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;scrollUpButton.Active = (scrollPosition &gt; 1)
&#9;&#9;if lastChildSize == 0 then
&#9;&#9;&#9;scrollDownButton.Active = false
&#9;&#9;else
&#9;&#9;&#9;scrollDownButton.Active = ((pixelsRemainingY - lastChildSize.Y) &lt; 0)
&#9;&#9;end
&#9;&#9;scrollDrag.Active = #guiObjects &gt; howManyDisplayed
&#9;&#9;scrollDrag.Visible = scrollDrag.Active
&#9;end
&#9;local layoutSimpleScrollBar = function()
&#9;&#9;local guiObjects = {}&#9;
&#9;&#9;howManyDisplayed = 0
&#9;&#9;
&#9;&#9;if orderList then
&#9;&#9;&#9;for i, child in ipairs(orderList) do
&#9;&#9;&#9;&#9;if child.Parent == frame then
&#9;&#9;&#9;&#9;&#9;table.insert(guiObjects, child)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;local children = frame:GetChildren()
&#9;&#9;&#9;if children then
&#9;&#9;&#9;&#9;for i, child in ipairs(children) do
&#9;&#9;&#9;&#9;&#9;if child:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;&#9;&#9;table.insert(guiObjects, child)
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;if #guiObjects == 0 then
&#9;&#9;&#9;scrollUpButton.Active = false
&#9;&#9;&#9;scrollDownButton.Active = false
&#9;&#9;&#9;scrollDrag.Active = false
&#9;&#9;&#9;scrollPosition = 1
&#9;&#9;&#9;return
&#9;&#9;end
&#9;&#9;if scrollPosition &gt; #guiObjects then
&#9;&#9;&#9;scrollPosition = #guiObjects
&#9;&#9;end
&#9;&#9;
&#9;&#9;local totalPixels = frame.AbsoluteSize.Y
&#9;&#9;local pixelsRemaining = frame.AbsoluteSize.Y
&#9;&#9;local pixelsBelowScrollbar = 0
&#9;&#9;local pos = #guiObjects
&#9;&#9;while pixelsBelowScrollbar &lt; totalPixels and pos &gt;= 1 do
&#9;&#9;&#9;if pos &gt;= scrollPosition then
&#9;&#9;&#9;&#9;pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;if pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y &lt;= totalPixels then
&#9;&#9;&#9;&#9;&#9;--It fits, so back up our scroll position
&#9;&#9;&#9;&#9;&#9;pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y
&#9;&#9;&#9;&#9;&#9;if scrollPosition &lt;= 1 then
&#9;&#9;&#9;&#9;&#9;&#9;scrollPosition = 1
&#9;&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;--local (&quot;Backing up ScrollPosition from -- &quot; ..scrollPosition)
&#9;&#9;&#9;&#9;&#9;&#9;scrollPosition = scrollPosition - 1
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;pos = pos - 1
&#9;&#9;end
&#9;&#9;pos = scrollPosition
&#9;&#9;for i, child in ipairs(guiObjects) do
&#9;&#9;&#9;if i &lt; scrollPosition then
&#9;&#9;&#9;&#9;--print(&quot;Hiding &quot; .. child.Name)
&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;if pixelsRemaining &lt; 0 then
&#9;&#9;&#9;&#9;&#9;--print(&quot;Out of Space &quot; .. child.Name)
&#9;&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;--print(&quot;Laying out &quot; .. child.Name)
&#9;&#9;&#9;&#9;&#9;--GuiObject
&#9;&#9;&#9;&#9;&#9;child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
&#9;&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
&#9;&#9;&#9;&#9;&#9;if (pixelsRemaining &gt;= 0) then
&#9;&#9;&#9;&#9;&#9;&#9;child.Visible = true
&#9;&#9;&#9;&#9;&#9;&#9;howManyDisplayed = howManyDisplayed + 1
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;&#9;&#9;end&#9;&#9;
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;scrollUpButton.Active = (scrollPosition &gt; 1)
&#9;&#9;scrollDownButton.Active = (pixelsRemaining &lt; 0)
&#9;&#9;scrollDrag.Active = #guiObjects &gt; howManyDisplayed
&#9;&#9;scrollDrag.Visible = scrollDrag.Active
&#9;end
&#9;
&#9;&#9;
&#9;local moveDragger = function()&#9;
&#9;&#9;local guiObjects = 0
&#9;&#9;local children = frame:GetChildren()
&#9;&#9;if children then
&#9;&#9;&#9;for i, child in ipairs(children) do
&#9;&#9;&#9;&#9;if child:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;&#9;guiObjects = guiObjects + 1
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;
&#9;&#9;if not scrollDrag.Parent then return end
&#9;&#9;
&#9;&#9;local dragSizeY = scrollDrag.Parent.AbsoluteSize.y * (1/(guiObjects - howManyDisplayed + 1))
&#9;&#9;if dragSizeY &lt; 16 then dragSizeY = 16 end
&#9;&#9;scrollDrag.Size = UDim2.new(scrollDrag.Size.X.Scale,scrollDrag.Size.X.Offset,scrollDrag.Size.Y.Scale,dragSizeY)
&#9;&#9;local relativeYPos = (scrollPosition - 1)/(guiObjects - (howManyDisplayed))
&#9;&#9;if relativeYPos &gt; 1 then relativeYPos = 1
&#9;&#9;elseif relativeYPos &lt; 0 then relativeYPos = 0 end
&#9;&#9;local absYPos = 0
&#9;&#9;
&#9;&#9;if relativeYPos ~= 0 then
&#9;&#9;&#9;absYPos = (relativeYPos * scrollbar.AbsoluteSize.y) - (relativeYPos * scrollDrag.AbsoluteSize.y)
&#9;&#9;end
&#9;&#9;
&#9;&#9;scrollDrag.Position = UDim2.new(scrollDrag.Position.X.Scale,scrollDrag.Position.X.Offset,scrollDrag.Position.Y.Scale,absYPos)
&#9;end
&#9;local reentrancyGuard = false
&#9;local recalculate = function()
&#9;&#9;if reentrancyGuard then
&#9;&#9;&#9;return
&#9;&#9;end
&#9;&#9;reentrancyGuard = true
&#9;&#9;wait()
&#9;&#9;local success, err = nil
&#9;&#9;if style == &quot;grid&quot; then
&#9;&#9;&#9;success, err = pcall(function() layoutGridScrollBar() end)
&#9;&#9;elseif style == &quot;simple&quot; then
&#9;&#9;&#9;success, err = pcall(function() layoutSimpleScrollBar() end)
&#9;&#9;end
&#9;&#9;if not success then print(err) end
&#9;&#9;moveDragger()
&#9;&#9;reentrancyGuard = false
&#9;end
&#9;
&#9;local doScrollUp = function()
&#9;&#9;scrollPosition = (scrollPosition) - rowSize
&#9;&#9;if scrollPosition &lt; 1 then scrollPosition = 1 end
&#9;&#9;recalculate(nil)
&#9;end
&#9;
&#9;local doScrollDown = function()
&#9;&#9;scrollPosition = (scrollPosition) + rowSize
&#9;&#9;recalculate(nil)
&#9;end
&#9;local scrollUp = function(mouseYPos)
&#9;&#9;if scrollUpButton.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local current = scrollStamp
&#9;&#9;&#9;local upCon
&#9;&#9;&#9;upCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;upCon:disconnect()
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;&#9;doScrollUp()
&#9;&#9;&#9;wait(0.2)
&#9;&#9;&#9;local t = tick()
&#9;&#9;&#9;local w = 0.1
&#9;&#9;&#9;while scrollStamp == current do
&#9;&#9;&#9;&#9;doScrollUp()
&#9;&#9;&#9;&#9;if mouseYPos and mouseYPos &gt; scrollDrag.AbsolutePosition.y then
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if not scrollUpButton.Active then break end
&#9;&#9;&#9;&#9;if tick()-t &gt; 5 then
&#9;&#9;&#9;&#9;&#9;w = 0
&#9;&#9;&#9;&#9;elseif tick()-t &gt; 2 then
&#9;&#9;&#9;&#9;&#9;w = 0.06
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;wait(w)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local scrollDown = function(mouseYPos)
&#9;&#9;if scrollDownButton.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local current = scrollStamp
&#9;&#9;&#9;local downCon
&#9;&#9;&#9;downCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;downCon:disconnect()
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;&#9;doScrollDown()
&#9;&#9;&#9;wait(0.2)
&#9;&#9;&#9;local t = tick()
&#9;&#9;&#9;local w = 0.1
&#9;&#9;&#9;while scrollStamp == current do
&#9;&#9;&#9;&#9;doScrollDown()
&#9;&#9;&#9;&#9;if mouseYPos and mouseYPos &lt; (scrollDrag.AbsolutePosition.y + scrollDrag.AbsoluteSize.x) then
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if not scrollDownButton.Active then break end
&#9;&#9;&#9;&#9;if tick()-t &gt; 5 then
&#9;&#9;&#9;&#9;&#9;w = 0
&#9;&#9;&#9;&#9;elseif tick()-t &gt; 2 then
&#9;&#9;&#9;&#9;&#9;w = 0.06
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;wait(w)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;
&#9;local y = 0
&#9;scrollDrag.MouseButton1Down:connect(function(x,y)
&#9;&#9;if scrollDrag.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local mouseOffset = y - scrollDrag.AbsolutePosition.y
&#9;&#9;&#9;local dragCon
&#9;&#9;&#9;local upCon
&#9;&#9;&#9;dragCon = mouseDrag.MouseMoved:connect(function(x,y)
&#9;&#9;&#9;&#9;local barAbsPos = scrollbar.AbsolutePosition.y
&#9;&#9;&#9;&#9;local barAbsSize = scrollbar.AbsoluteSize.y
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local dragAbsSize = scrollDrag.AbsoluteSize.y
&#9;&#9;&#9;&#9;local barAbsOne = barAbsPos + barAbsSize - dragAbsSize
&#9;&#9;&#9;&#9;y = y - mouseOffset
&#9;&#9;&#9;&#9;y = y &lt; barAbsPos and barAbsPos or y &gt; barAbsOne and barAbsOne or y
&#9;&#9;&#9;&#9;y = y - barAbsPos
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local guiObjects = 0
&#9;&#9;&#9;&#9;local children = frame:GetChildren()
&#9;&#9;&#9;&#9;if children then
&#9;&#9;&#9;&#9;&#9;for i, child in ipairs(children) do
&#9;&#9;&#9;&#9;&#9;&#9;if child:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;guiObjects = guiObjects + 1
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local doublePercent = y/(barAbsSize-dragAbsSize)
&#9;&#9;&#9;&#9;local rowDiff = rowSize
&#9;&#9;&#9;&#9;local totalScrollCount = guiObjects - (howManyDisplayed - 1)
&#9;&#9;&#9;&#9;local newScrollPosition = math.floor((doublePercent * totalScrollCount) + 0.5) + rowDiff
&#9;&#9;&#9;&#9;if newScrollPosition &lt; scrollPosition then
&#9;&#9;&#9;&#9;&#9;rowDiff = -rowDiff
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;if newScrollPosition &lt; 1 then
&#9;&#9;&#9;&#9;&#9;newScrollPosition = 1
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;scrollPosition = newScrollPosition
&#9;&#9;&#9;&#9;recalculate(nil)
&#9;&#9;&#9;end)
&#9;&#9;&#9;upCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;dragCon:disconnect(); dragCon = nil
&#9;&#9;&#9;&#9;upCon:disconnect(); drag = nil
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;end
&#9;end)
&#9;local scrollMouseCount = 0
&#9;scrollUpButton.MouseButton1Down:connect(
&#9;&#9;function()
&#9;&#9;&#9;scrollUp()
&#9;&#9;end)
&#9;scrollUpButton.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;scrollDownButton.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;scrollDownButton.MouseButton1Down:connect(
&#9;&#9;function()
&#9;&#9;&#9;scrollDown()&#9;
&#9;&#9;end)
&#9;&#9;
&#9;scrollbar.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;scrollbar.MouseButton1Down:connect(
&#9;&#9;function(x,y)
&#9;&#9;&#9;if y &gt; (scrollDrag.AbsoluteSize.y + scrollDrag.AbsolutePosition.y) then
&#9;&#9;&#9;&#9;scrollDown(y)
&#9;&#9;&#9;elseif y &lt; (scrollDrag.AbsolutePosition.y) then
&#9;&#9;&#9;&#9;scrollUp(y)
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;frame.ChildAdded:connect(function()
&#9;&#9;recalculate(nil)
&#9;end)
&#9;frame.ChildRemoved:connect(function()
&#9;&#9;recalculate(nil)
&#9;end)
&#9;
&#9;frame.Changed:connect(
&#9;&#9;function(prop)
&#9;&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;&#9;--Wait a heartbeat for it to sync in
&#9;&#9;&#9;&#9;recalculate(nil)
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;frame.AncestryChanged:connect(function() recalculate(nil) end)
&#9;return frame, scrollUpButton, scrollDownButton, recalculate, scrollbar
end
local function binaryGrow(min, max, fits)
&#9;if min &gt; max then
&#9;&#9;return min
&#9;end
&#9;local biggestLegal = min
&#9;while min &lt;= max do
&#9;&#9;local mid = min + math.floor((max - min) / 2)
&#9;&#9;if fits(mid) and (biggestLegal == nil or biggestLegal &lt; mid) then
&#9;&#9;&#9;biggestLegal = mid
&#9;&#9;&#9;
&#9;&#9;&#9;--Try growing
&#9;&#9;&#9;min = mid + 1
&#9;&#9;else
&#9;&#9;&#9;--Doesn&apos;t fit, shrink
&#9;&#9;&#9;max = mid - 1
&#9;&#9;end
&#9;end
&#9;return biggestLegal
end
local function binaryShrink(min, max, fits)
&#9;if min &gt; max then
&#9;&#9;return min
&#9;end
&#9;local smallestLegal = max
&#9;while min &lt;= max do
&#9;&#9;local mid = min + math.floor((max - min) / 2)
&#9;&#9;if fits(mid) and (smallestLegal == nil or smallestLegal &gt; mid) then
&#9;&#9;&#9;smallestLegal = mid
&#9;&#9;&#9;
&#9;&#9;&#9;--It fits, shrink
&#9;&#9;&#9;max = mid - 1&#9;&#9;&#9;
&#9;&#9;else
&#9;&#9;&#9;--Doesn&apos;t fit, grow
&#9;&#9;&#9;min = mid + 1
&#9;&#9;end
&#9;end
&#9;return smallestLegal
end
local function getGuiOwner(instance)
&#9;while instance ~= nil do
&#9;&#9;if instance:IsA(&quot;ScreenGui&quot;) or instance:IsA(&quot;BillboardGui&quot;) then
&#9;&#9;&#9;return instance
&#9;&#9;end
&#9;&#9;instance = instance.Parent
&#9;end
&#9;return nil
end
t.AutoTruncateTextObject = function(textLabel)
&#9;local text = textLabel.Text
&#9;local fullLabel = textLabel:Clone()
&#9;fullLabel.Name = &quot;Full&quot; .. textLabel.Name
&#9;fullLabel.BorderSizePixel = 0
&#9;fullLabel.BackgroundTransparency = 0
&#9;fullLabel.Text = text
&#9;fullLabel.TextXAlignment = Enum.TextXAlignment.Center
&#9;fullLabel.Position = UDim2.new(0,-3,0,0)
&#9;fullLabel.Size = UDim2.new(0,100,1,0)
&#9;fullLabel.Visible = false
&#9;fullLabel.Parent = textLabel
&#9;local shortText = nil
&#9;local mouseEnterConnection = nil
&#9;local mouseLeaveConnection= nil
&#9;local checkForResize = function()
&#9;&#9;if getGuiOwner(textLabel) == nil then
&#9;&#9;&#9;return
&#9;&#9;end
&#9;&#9;textLabel.Text = text
&#9;&#9;if textLabel.TextFits then
&#9;&#9;&#9;--Tear down the rollover if it is active
&#9;&#9;&#9;if mouseEnterConnection then
&#9;&#9;&#9;&#9;mouseEnterConnection:disconnect()
&#9;&#9;&#9;&#9;mouseEnterConnection = nil
&#9;&#9;&#9;end
&#9;&#9;&#9;if mouseLeaveConnection then
&#9;&#9;&#9;&#9;mouseLeaveConnection:disconnect()
&#9;&#9;&#9;&#9;mouseLeaveConnection = nil
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;local len = string.len(text)
&#9;&#9;&#9;textLabel.Text = text .. &quot;~&quot;
&#9;&#9;&#9;--Shrink the text
&#9;&#9;&#9;local textSize = binaryGrow(0, len,
&#9;&#9;&#9;&#9;function(pos)
&#9;&#9;&#9;&#9;&#9;if pos == 0 then
&#9;&#9;&#9;&#9;&#9;&#9;textLabel.Text = &quot;~&quot;
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;textLabel.Text = string.sub(text, 1, pos) .. &quot;~&quot;
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;return textLabel.TextFits
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;shortText = string.sub(text, 1, textSize) .. &quot;~&quot;
&#9;&#9;&#9;textLabel.Text = shortText
&#9;&#9;&#9;
&#9;&#9;&#9;--Make sure the fullLabel fits
&#9;&#9;&#9;if not fullLabel.TextFits then
&#9;&#9;&#9;&#9;--Already too small, grow it really bit to start
&#9;&#9;&#9;&#9;fullLabel.Size = UDim2.new(0, 10000, 1, 0)
&#9;&#9;&#9;end
&#9;&#9;&#9;
&#9;&#9;&#9;--Okay, now try to binary shrink it back down
&#9;&#9;&#9;local fullLabelSize = binaryShrink(textLabel.AbsoluteSize.X,fullLabel.AbsoluteSize.X,
&#9;&#9;&#9;&#9;function(size)
&#9;&#9;&#9;&#9;&#9;fullLabel.Size = UDim2.new(0, size, 1, 0)
&#9;&#9;&#9;&#9;&#9;return fullLabel.TextFits
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;fullLabel.Size = UDim2.new(0,fullLabelSize+6,1,0)
&#9;&#9;&#9;--Now setup the rollover effects, if they are currently off
&#9;&#9;&#9;if mouseEnterConnection == nil then
&#9;&#9;&#9;&#9;mouseEnterConnection = textLabel.MouseEnter:connect(
&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;&#9;fullLabel.ZIndex = textLabel.ZIndex + 1
&#9;&#9;&#9;&#9;&#9;&#9;fullLabel.Visible = true
&#9;&#9;&#9;&#9;&#9;&#9;--textLabel.Text = &quot;&quot;
&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;&#9;if mouseLeaveConnection == nil then
&#9;&#9;&#9;&#9;mouseLeaveConnection = textLabel.MouseLeave:connect(
&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;&#9;fullLabel.Visible = false
&#9;&#9;&#9;&#9;&#9;&#9;--textLabel.Text = shortText
&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;textLabel.AncestryChanged:connect(checkForResize)
&#9;textLabel.Changed:connect(
&#9;&#9;function(prop)
&#9;&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;&#9;checkForResize() &#9;
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;checkForResize()
&#9;local function changeText(newText)
&#9;&#9;text = newText
&#9;&#9;fullLabel.Text = text
&#9;&#9;checkForResize()
&#9;end
&#9;return textLabel, changeText
end
local function TransitionTutorialPages(fromPage, toPage, transitionFrame, currentPageValue)&#9;
&#9;if fromPage then
&#9;&#9;fromPage.Visible = false
&#9;&#9;if transitionFrame.Visible == false then
&#9;&#9;&#9;transitionFrame.Size = fromPage.Size
&#9;&#9;&#9;transitionFrame.Position = fromPage.Position
&#9;&#9;end
&#9;else
&#9;&#9;if transitionFrame.Visible == false then
&#9;&#9;&#9;transitionFrame.Size = UDim2.new(0.0,50,0.0,50)
&#9;&#9;&#9;transitionFrame.Position = UDim2.new(0.5,-25,0.5,-25)
&#9;&#9;end
&#9;end
&#9;transitionFrame.Visible = true
&#9;currentPageValue.Value = nil
&#9;local newsize, newPosition
&#9;if toPage then
&#9;&#9;--Make it visible so it resizes
&#9;&#9;toPage.Visible = true
&#9;&#9;newSize = toPage.Size
&#9;&#9;newPosition = toPage.Position
&#9;&#9;toPage.Visible = false
&#9;else
&#9;&#9;newSize = UDim2.new(0.0,50,0.0,50)
&#9;&#9;newPosition = UDim2.new(0.5,-25,0.5,-25)
&#9;end
&#9;transitionFrame:TweenSizeAndPosition(newSize, newPosition, Enum.EasingDirection.InOut, Enum.EasingStyle.Quad, 0.3, true,
&#9;&#9;function(state)
&#9;&#9;&#9;if state == Enum.TweenStatus.Completed then
&#9;&#9;&#9;&#9;transitionFrame.Visible = false
&#9;&#9;&#9;&#9;if toPage then
&#9;&#9;&#9;&#9;&#9;toPage.Visible = true
&#9;&#9;&#9;&#9;&#9;currentPageValue.Value = toPage
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end)
end
t.CreateTutorial = function(name, tutorialKey, createButtons)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Name = &quot;Tutorial-&quot; .. name
&#9;frame.BackgroundTransparency = 1
&#9;frame.Size = UDim2.new(0.6, 0, 0.6, 0)
&#9;frame.Position = UDim2.new(0.2, 0, 0.2, 0)
&#9;local transitionFrame = Instance.new(&quot;Frame&quot;)
&#9;transitionFrame.Name = &quot;TransitionFrame&quot;
&#9;transitionFrame.Style = Enum.FrameStyle.RobloxRound
&#9;transitionFrame.Size = UDim2.new(0.6, 0, 0.6, 0)
&#9;transitionFrame.Position = UDim2.new(0.2, 0, 0.2, 0)
&#9;transitionFrame.Visible = false
&#9;transitionFrame.Parent = frame
&#9;local currentPageValue = Instance.new(&quot;ObjectValue&quot;)
&#9;currentPageValue.Name = &quot;CurrentTutorialPage&quot;
&#9;currentPageValue.Value = nil
&#9;currentPageValue.Parent = frame
&#9;local boolValue = Instance.new(&quot;BoolValue&quot;)
&#9;boolValue.Name = &quot;Buttons&quot;
&#9;boolValue.Value = createButtons
&#9;boolValue.Parent = frame
&#9;local pages = Instance.new(&quot;Frame&quot;)
&#9;pages.Name = &quot;Pages&quot;
&#9;pages.BackgroundTransparency = 1
&#9;pages.Size = UDim2.new(1,0,1,0)
&#9;pages.Parent = frame
&#9;local function getVisiblePageAndHideOthers()
&#9;&#9;local visiblePage = nil
&#9;&#9;local children = pages:GetChildren()
&#9;&#9;if children then
&#9;&#9;&#9;for i,child in ipairs(children) do
&#9;&#9;&#9;&#9;if child.Visible then
&#9;&#9;&#9;&#9;&#9;if visiblePage then
&#9;&#9;&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;visiblePage = child
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;return visiblePage
&#9;end
&#9;local showTutorial = function(alwaysShow)
&#9;&#9;if alwaysShow or UserSettings().GameSettings:GetTutorialState(tutorialKey) == false then
&#9;&#9;&#9;print(&quot;Showing tutorial-&quot;,tutorialKey)
&#9;&#9;&#9;local currentTutorialPage = getVisiblePageAndHideOthers()
&#9;&#9;&#9;local firstPage = pages:FindFirstChild(&quot;TutorialPage1&quot;)
&#9;&#9;&#9;if firstPage then
&#9;&#9;&#9;&#9;TransitionTutorialPages(currentTutorialPage, firstPage, transitionFrame, currentPageValue)&#9;
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;error(&quot;Could not find TutorialPage1&quot;)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local dismissTutorial = function()
&#9;&#9;local currentTutorialPage = getVisiblePageAndHideOthers()
&#9;&#9;if currentTutorialPage then
&#9;&#9;&#9;TransitionTutorialPages(currentTutorialPage, nil, transitionFrame, currentPageValue)
&#9;&#9;end
&#9;&#9;UserSettings().GameSettings:SetTutorialState(tutorialKey, true)
&#9;end
&#9;local gotoPage = function(pageNum)
&#9;&#9;local page = pages:FindFirstChild(&quot;TutorialPage&quot; .. pageNum)
&#9;&#9;local currentTutorialPage = getVisiblePageAndHideOthers()
&#9;&#9;TransitionTutorialPages(currentTutorialPage, page, transitionFrame, currentPageValue)
&#9;end
&#9;return frame, showTutorial, dismissTutorial, gotoPage
end
local function CreateBasicTutorialPage(name, handleResize, skipTutorial, giveDoneButton)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Name = &quot;TutorialPage&quot;
&#9;frame.Style = Enum.FrameStyle.RobloxRound
&#9;frame.Size = UDim2.new(0.6, 0, 0.6, 0)
&#9;frame.Position = UDim2.new(0.2, 0, 0.2, 0)
&#9;frame.Visible = false
&#9;
&#9;local frameHeader = Instance.new(&quot;TextLabel&quot;)
&#9;frameHeader.Name = &quot;Header&quot;
&#9;frameHeader.Text = name
&#9;frameHeader.BackgroundTransparency = 1
&#9;frameHeader.FontSize = Enum.FontSize.Size24
&#9;frameHeader.Font = Enum.Font.ArialBold
&#9;frameHeader.TextColor3 = Color3.new(1,1,1)
&#9;frameHeader.TextXAlignment = Enum.TextXAlignment.Center
&#9;frameHeader.TextWrap = true
&#9;frameHeader.Size = UDim2.new(1,-55, 0, 22)
&#9;frameHeader.Position = UDim2.new(0,0,0,0)
&#9;frameHeader.Parent = frame
&#9;local skipButton = Instance.new(&quot;ImageButton&quot;)
&#9;skipButton.Name = &quot;SkipButton&quot;
&#9;skipButton.AutoButtonColor = false
&#9;skipButton.BackgroundTransparency = 1
&#9;skipButton.Image = &quot;rbxasset://textures/ui/closeButton.png&quot;
&#9;skipButton.MouseButton1Click:connect(function()
&#9;&#9;skipTutorial()
&#9;end)
&#9;skipButton.MouseEnter:connect(function()
&#9;&#9;skipButton.Image = &quot;rbxasset://textures/ui/closeButton_dn.png&quot;
&#9;end)
&#9;skipButton.MouseLeave:connect(function()
&#9;&#9;skipButton.Image = &quot;rbxasset://textures/ui/closeButton.png&quot;
&#9;end)
&#9;skipButton.Size = UDim2.new(0, 25, 0, 25)
&#9;skipButton.Position = UDim2.new(1, -25, 0, 0)
&#9;skipButton.Parent = frame
&#9;
&#9;
&#9;if giveDoneButton then
&#9;&#9;local doneButton = Instance.new(&quot;TextButton&quot;)
&#9;&#9;doneButton.Name = &quot;DoneButton&quot;
&#9;&#9;doneButton.Style = Enum.ButtonStyle.RobloxButtonDefault
&#9;&#9;doneButton.Text = &quot;Done&quot;
&#9;&#9;doneButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;doneButton.Font = Enum.Font.ArialBold
&#9;&#9;doneButton.FontSize = Enum.FontSize.Size18
&#9;&#9;doneButton.Size = UDim2.new(0,100,0,50)
&#9;&#9;doneButton.Position = UDim2.new(0.5,-50,1,-50)
&#9;&#9;
&#9;&#9;if skipTutorial then
&#9;&#9;&#9;doneButton.MouseButton1Click:connect(function() skipTutorial() end)
&#9;&#9;end
&#9;&#9;
&#9;&#9;doneButton.Parent = frame
&#9;end
&#9;local innerFrame = Instance.new(&quot;Frame&quot;)
&#9;innerFrame.Name = &quot;ContentFrame&quot;
&#9;innerFrame.BackgroundTransparency = 1
&#9;innerFrame.Position = UDim2.new(0,0,0,25)
&#9;innerFrame.Parent = frame
&#9;local nextButton = Instance.new(&quot;TextButton&quot;)
&#9;nextButton.Name = &quot;NextButton&quot;
&#9;nextButton.Text = &quot;Next&quot;
&#9;nextButton.TextColor3 = Color3.new(1,1,1)
&#9;nextButton.Font = Enum.Font.Arial
&#9;nextButton.FontSize = Enum.FontSize.Size18
&#9;nextButton.Style = Enum.ButtonStyle.RobloxButtonDefault
&#9;nextButton.Size = UDim2.new(0,80, 0, 32)
&#9;nextButton.Position = UDim2.new(0.5, 5, 1, -32)
&#9;nextButton.Active = false
&#9;nextButton.Visible = false
&#9;nextButton.Parent = frame
&#9;local prevButton = Instance.new(&quot;TextButton&quot;)
&#9;prevButton.Name = &quot;PrevButton&quot;
&#9;prevButton.Text = &quot;Previous&quot;
&#9;prevButton.TextColor3 = Color3.new(1,1,1)
&#9;prevButton.Font = Enum.Font.Arial
&#9;prevButton.FontSize = Enum.FontSize.Size18
&#9;prevButton.Style = Enum.ButtonStyle.RobloxButton
&#9;prevButton.Size = UDim2.new(0,80, 0, 32)
&#9;prevButton.Position = UDim2.new(0.5, -85, 1, -32)
&#9;prevButton.Active = false
&#9;prevButton.Visible = false
&#9;prevButton.Parent = frame
&#9;if giveDoneButton then
&#9;&#9;innerFrame.Size = UDim2.new(1,0,1,-75)
&#9;else
&#9;&#9;innerFrame.Size = UDim2.new(1,0,1,-22)
&#9;end
&#9;local parentConnection = nil
&#9;local function basicHandleResize()
&#9;&#9;if frame.Visible and frame.Parent then
&#9;&#9;&#9;local maxSize = math.min(frame.Parent.AbsoluteSize.X, frame.Parent.AbsoluteSize.Y)
&#9;&#9;&#9;handleResize(200,maxSize)
&#9;&#9;end
&#9;end
&#9;frame.Changed:connect(
&#9;&#9;function(prop)
&#9;&#9;&#9;if prop == &quot;Parent&quot; then
&#9;&#9;&#9;&#9;if parentConnection ~= nil then
&#9;&#9;&#9;&#9;&#9;parentConnection:disconnect()
&#9;&#9;&#9;&#9;&#9;parentConnection = nil
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if frame.Parent and frame.Parent:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;&#9;parentConnection = frame.Parent.Changed:connect(
&#9;&#9;&#9;&#9;&#9;&#9;function(parentProp)
&#9;&#9;&#9;&#9;&#9;&#9;&#9;if parentProp == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;wait()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;basicHandleResize()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;&#9;&#9;basicHandleResize()
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;if prop == &quot;Visible&quot; then
&#9;&#9;&#9;&#9;basicHandleResize()
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;return frame, innerFrame
end
t.CreateTextTutorialPage = function(name, text, skipTutorialFunc)
&#9;local frame = nil
&#9;local contentFrame = nil
&#9;local textLabel = Instance.new(&quot;TextLabel&quot;)
&#9;textLabel.BackgroundTransparency = 1
&#9;textLabel.TextColor3 = Color3.new(1,1,1)
&#9;textLabel.Text = text
&#9;textLabel.TextWrap = true
&#9;textLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;textLabel.TextYAlignment = Enum.TextYAlignment.Center
&#9;textLabel.Font = Enum.Font.Arial
&#9;textLabel.FontSize = Enum.FontSize.Size14
&#9;textLabel.Size = UDim2.new(1,0,1,0)
&#9;local function handleResize(minSize, maxSize)
&#9;&#9;size = binaryShrink(minSize, maxSize,
&#9;&#9;&#9;function(size)
&#9;&#9;&#9;&#9;frame.Size = UDim2.new(0, size, 0, size)
&#9;&#9;&#9;&#9;return textLabel.TextFits
&#9;&#9;&#9;end)
&#9;&#9;frame.Size = UDim2.new(0, size, 0, size)
&#9;&#9;frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2)
&#9;end
&#9;frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc)
&#9;textLabel.Parent = contentFrame
&#9;return frame
end
t.CreateImageTutorialPage = function(name, imageAsset, x, y, skipTutorialFunc, giveDoneButton)
&#9;local frame = nil
&#9;local contentFrame = nil
&#9;local imageLabel = Instance.new(&quot;ImageLabel&quot;)
&#9;imageLabel.BackgroundTransparency = 1
&#9;imageLabel.Image = imageAsset
&#9;imageLabel.Size = UDim2.new(0,x,0,y)
&#9;imageLabel.Position = UDim2.new(0.5,-x/2,0.5,-y/2)
&#9;local function handleResize(minSize, maxSize)
&#9;&#9;size = binaryShrink(minSize, maxSize,
&#9;&#9;&#9;function(size)
&#9;&#9;&#9;&#9;return size &gt;= x and size &gt;= y
&#9;&#9;&#9;end)
&#9;&#9;if size &gt;= x and size &gt;= y then
&#9;&#9;&#9;imageLabel.Size = UDim2.new(0,x, 0,y)
&#9;&#9;&#9;imageLabel.Position = UDim2.new(0.5,-x/2, 0.5, -y/2)
&#9;&#9;else
&#9;&#9;&#9;if x &gt; y then
&#9;&#9;&#9;&#9;--X is limiter, so
&#9;&#9;&#9;&#9;imageLabel.Size = UDim2.new(1,0,y/x,0)
&#9;&#9;&#9;&#9;imageLabel.Position = UDim2.new(0,0, 0.5 - (y/x)/2, 0)
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;--Y is limiter
&#9;&#9;&#9;&#9;imageLabel.Size = UDim2.new(x/y,0,1, 0)
&#9;&#9;&#9;&#9;imageLabel.Position = UDim2.new(0.5-(x/y)/2, 0, 0, 0)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;size = size + 50
&#9;&#9;frame.Size = UDim2.new(0, size, 0, size)
&#9;&#9;frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2)
&#9;end
&#9;frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc, giveDoneButton)
&#9;imageLabel.Parent = contentFrame
&#9;return frame
end
t.AddTutorialPage = function(tutorial, tutorialPage)
&#9;local transitionFrame = tutorial.TransitionFrame
&#9;local currentPageValue = tutorial.CurrentTutorialPage
&#9;if not tutorial.Buttons.Value then
&#9;&#9;tutorialPage.NextButton.Parent = nil
&#9;&#9;tutorialPage.PrevButton.Parent = nil
&#9;end
&#9;local children = tutorial.Pages:GetChildren()
&#9;if children and #children &gt; 0 then
&#9;&#9;tutorialPage.Name = &quot;TutorialPage&quot; .. (#children+1)
&#9;&#9;local previousPage = children[#children]
&#9;&#9;if not previousPage:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;error(&quot;All elements under Pages must be GuiObjects&quot;)
&#9;&#9;end
&#9;&#9;if tutorial.Buttons.Value then
&#9;&#9;&#9;if previousPage.NextButton.Active then
&#9;&#9;&#9;&#9;error(&quot;NextButton already Active on previousPage, please only add pages with RbxGui.AddTutorialPage function&quot;)
&#9;&#9;&#9;end
&#9;&#9;&#9;previousPage.NextButton.MouseButton1Click:connect(
&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;TransitionTutorialPages(previousPage, tutorialPage, transitionFrame, currentPageValue)
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;previousPage.NextButton.Active = true
&#9;&#9;&#9;previousPage.NextButton.Visible = true
&#9;&#9;&#9;if tutorialPage.PrevButton.Active then
&#9;&#9;&#9;&#9;error(&quot;PrevButton already Active on tutorialPage, please only add pages with RbxGui.AddTutorialPage function&quot;)
&#9;&#9;&#9;end
&#9;&#9;&#9;tutorialPage.PrevButton.MouseButton1Click:connect(
&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;TransitionTutorialPages(tutorialPage, previousPage, transitionFrame, currentPageValue)
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;tutorialPage.PrevButton.Active = true
&#9;&#9;&#9;tutorialPage.PrevButton.Visible = true
&#9;&#9;end
&#9;&#9;tutorialPage.Parent = tutorial.Pages
&#9;else
&#9;&#9;--First child
&#9;&#9;tutorialPage.Name = &quot;TutorialPage1&quot;
&#9;&#9;tutorialPage.Parent = tutorial.Pages
&#9;end
end
t.CreateSetPanel = function(userIdsForSets, objectSelected, dialogClosed, size, position, showAdminCategories, useAssetVersionId)
&#9;if not userIdsForSets then
&#9;&#9;error(&quot;CreateSetPanel: userIdsForSets (first arg) is nil, should be a table of number ids&quot;)
&#9;end
&#9;if type(userIdsForSets) ~= &quot;table&quot; and type(userIdsForSets) ~= &quot;userdata&quot; then
&#9;&#9;error(&quot;CreateSetPanel: userIdsForSets (first arg) is of type &quot; ..type(userIdsForSets) .. &quot;, should be of type table or userdata&quot;)
&#9;end
&#9;if not objectSelected then
&#9;&#9;error(&quot;CreateSetPanel: objectSelected (second arg) is nil, should be a callback function!&quot;)
&#9;end
&#9;if type(objectSelected) ~= &quot;function&quot; then
&#9;&#9;error(&quot;CreateSetPanel: objectSelected (second arg) is of type &quot; .. type(objectSelected) .. &quot;, should be of type function!&quot;)
&#9;end
&#9;if dialogClosed and type(dialogClosed) ~= &quot;function&quot; then
&#9;&#9;error(&quot;CreateSetPanel: dialogClosed (third arg) is of type &quot; .. type(dialogClosed) .. &quot;, should be of type function!&quot;)
&#9;end
&#9;
&#9;if showAdminCategories == nil then -- by default, don&apos;t show beta sets
&#9;&#9;showAdminCategories = false
&#9;end
&#9;local arrayPosition = 1
&#9;local insertButtons = {}
&#9;local insertButtonCons = {}
&#9;local contents = nil
&#9;local setGui = nil
&#9;-- used for water selections
&#9;local waterForceDirection = &quot;NegX&quot;
&#9;local waterForce = &quot;None&quot;
&#9;local waterGui, waterTypeChangedEvent = nil
&#9;
&#9;local Data = {}
&#9;Data.CurrentCategory = nil
&#9;Data.Category = {}
&#9;local SetCache = {}
&#9;
&#9;local userCategoryButtons = nil
&#9;
&#9;local buttonWidth = 64
&#9;local buttonHeight = buttonWidth
&#9;
&#9;local SmallThumbnailUrl = nil
&#9;local LargeThumbnailUrl = nil
&#9;local BaseUrl = game:GetService(&quot;ContentProvider&quot;).BaseUrl:lower()
&#9;
&#9;if useAssetVersionId then
&#9;&#9;LargeThumbnailUrl = BaseUrl .. &quot;Game/Tools/ThumbnailAsset.ashx?fmt=png&amp;wd=420&amp;ht=420&amp;assetversionid=&quot;
&#9;&#9;SmallThumbnailUrl = BaseUrl .. &quot;Game/Tools/ThumbnailAsset.ashx?fmt=png&amp;wd=75&amp;ht=75&amp;assetversionid=&quot;
&#9;else
&#9;&#9;LargeThumbnailUrl = BaseUrl .. &quot;Game/Tools/ThumbnailAsset.ashx?fmt=png&amp;wd=420&amp;ht=420&amp;aid=&quot;
&#9;&#9;SmallThumbnailUrl = BaseUrl .. &quot;Game/Tools/ThumbnailAsset.ashx?fmt=png&amp;wd=75&amp;ht=75&amp;aid=&quot;
&#9;end
&#9;&#9;
&#9;local function drillDownSetZIndex(parent, index)
&#9;&#9;local children = parent:GetChildren()
&#9;&#9;for i = 1, #children do
&#9;&#9;&#9;if children[i]:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;children[i].ZIndex = index
&#9;&#9;&#9;end
&#9;&#9;&#9;drillDownSetZIndex(children[i], index)
&#9;&#9;end
&#9;end
&#9;
&#9;-- for terrain stamping
&#9;local currTerrainDropDownFrame = nil
&#9;local terrainShapes = {&quot;Block&quot;,&quot;Vertical Ramp&quot;,&quot;Corner Wedge&quot;,&quot;Inverse Corner Wedge&quot;,&quot;Horizontal Ramp&quot;,&quot;Auto-Wedge&quot;}
&#9;local terrainShapeMap = {}
&#9;for i = 1, #terrainShapes do
&#9;&#9;terrainShapeMap[terrainShapes[i]] = i - 1
&#9;end&#9;
&#9;terrainShapeMap[terrainShapes[#terrainShapes]] = 6
&#9;local function createWaterGui()
&#9;&#9;local waterForceDirections = {&quot;NegX&quot;,&quot;X&quot;,&quot;NegY&quot;,&quot;Y&quot;,&quot;NegZ&quot;,&quot;Z&quot;}
&#9;&#9;local waterForces = {&quot;None&quot;, &quot;Small&quot;, &quot;Medium&quot;, &quot;Strong&quot;, &quot;Max&quot;}
&#9;&#9;local waterFrame = Instance.new(&quot;Frame&quot;)
&#9;&#9;waterFrame.Name = &quot;WaterFrame&quot;
&#9;&#9;waterFrame.Style = Enum.FrameStyle.RobloxSquare
&#9;&#9;waterFrame.Size = UDim2.new(0,150,0,110)
&#9;&#9;waterFrame.Visible = false
&#9;&#9;local waterForceLabel = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;waterForceLabel.Name = &quot;WaterForceLabel&quot;
&#9;&#9;waterForceLabel.BackgroundTransparency = 1
&#9;&#9;waterForceLabel.Size = UDim2.new(1,0,0,12)
&#9;&#9;waterForceLabel.Font = Enum.Font.ArialBold
&#9;&#9;waterForceLabel.FontSize = Enum.FontSize.Size12
&#9;&#9;waterForceLabel.TextColor3 = Color3.new(1,1,1)
&#9;&#9;waterForceLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;waterForceLabel.Text = &quot;Water Force&quot;
&#9;&#9;waterForceLabel.Parent = waterFrame
&#9;&#9;local waterForceDirLabel = waterForceLabel:Clone()
&#9;&#9;waterForceDirLabel.Name = &quot;WaterForceDirectionLabel&quot;
&#9;&#9;waterForceDirLabel.Text = &quot;Water Force Direction&quot;
&#9;&#9;waterForceDirLabel.Position = UDim2.new(0,0,0,50)
&#9;&#9;waterForceDirLabel.Parent = waterFrame
&#9;&#9;local waterTypeChangedEvent = Instance.new(&quot;BindableEvent&quot;,waterFrame)
&#9;&#9;waterTypeChangedEvent.Name = &quot;WaterTypeChangedEvent&quot;
&#9;&#9;local waterForceDirectionSelectedFunc = function(newForceDirection)
&#9;&#9;&#9;waterForceDirection = newForceDirection
&#9;&#9;&#9;waterTypeChangedEvent:Fire({waterForce, waterForceDirection})
&#9;&#9;end
&#9;&#9;local waterForceSelectedFunc = function(newForce)
&#9;&#9;&#9;waterForce = newForce
&#9;&#9;&#9;waterTypeChangedEvent:Fire({waterForce, waterForceDirection})
&#9;&#9;end
&#9;&#9;local waterForceDirectionDropDown, forceWaterDirectionSelection = t.CreateDropDownMenu(waterForceDirections, waterForceDirectionSelectedFunc)
&#9;&#9;waterForceDirectionDropDown.Size = UDim2.new(1,0,0,25)
&#9;&#9;waterForceDirectionDropDown.Position = UDim2.new(0,0,1,3)
&#9;&#9;forceWaterDirectionSelection(&quot;NegX&quot;)
&#9;&#9;waterForceDirectionDropDown.Parent = waterForceDirLabel
&#9;&#9;local waterForceDropDown, forceWaterForceSelection = t.CreateDropDownMenu(waterForces, waterForceSelectedFunc)
&#9;&#9;forceWaterForceSelection(&quot;None&quot;)
&#9;&#9;waterForceDropDown.Size = UDim2.new(1,0,0,25)
&#9;&#9;waterForceDropDown.Position = UDim2.new(0,0,1,3)
&#9;&#9;waterForceDropDown.Parent = waterForceLabel
&#9;&#9;return waterFrame, waterTypeChangedEvent
&#9;end
&#9;-- Helper Function that contructs gui elements
&#9;local function createSetGui()
&#9;
&#9;&#9;local setGui = Instance.new(&quot;ScreenGui&quot;)
&#9;&#9;setGui.Name = &quot;SetGui&quot;
&#9;&#9;
&#9;&#9;local setPanel = Instance.new(&quot;Frame&quot;)
&#9;&#9;setPanel.Name = &quot;SetPanel&quot;
&#9;&#9;setPanel.Active = true
&#9;&#9;setPanel.BackgroundTransparency = 1
&#9;&#9;if position then
&#9;&#9;&#9;setPanel.Position = position
&#9;&#9;else
&#9;&#9;&#9;setPanel.Position = UDim2.new(0.2, 29, 0.1, 24)
&#9;&#9;end
&#9;&#9;if size then
&#9;&#9;&#9;setPanel.Size = size
&#9;&#9;else
&#9;&#9;&#9;setPanel.Size = UDim2.new(0.6, -58, 0.64, 0)
&#9;&#9;end
&#9;&#9;setPanel.Style = Enum.FrameStyle.RobloxRound
&#9;&#9;setPanel.ZIndex = 6
&#9;&#9;setPanel.Parent = setGui
&#9;&#9;
&#9;&#9;&#9;-- Children of SetPanel
&#9;&#9;&#9;local itemPreview = Instance.new(&quot;Frame&quot;)
&#9;&#9;&#9;itemPreview.Name = &quot;ItemPreview&quot;
&#9;&#9;&#9;itemPreview.BackgroundTransparency = 1
&#9;&#9;&#9;itemPreview.Position = UDim2.new(0.8,5,0.085,0)
&#9;&#9;&#9;itemPreview.Size = UDim2.new(0.21,0,0.9,0)
&#9;&#9;&#9;itemPreview.ZIndex = 6
&#9;&#9;&#9;itemPreview.Parent = setPanel
&#9;&#9;&#9;
&#9;&#9;&#9;&#9;-- Children of ItemPreview
&#9;&#9;&#9;&#9;local textPanel = Instance.new(&quot;Frame&quot;)
&#9;&#9;&#9;&#9;textPanel.Name = &quot;TextPanel&quot;
&#9;&#9;&#9;&#9;textPanel.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;textPanel.Position = UDim2.new(0,0,0.45,0)
&#9;&#9;&#9;&#9;textPanel.Size = UDim2.new(1,0,0.55,0)
&#9;&#9;&#9;&#9;textPanel.ZIndex = 6
&#9;&#9;&#9;&#9;textPanel.Parent = itemPreview
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;-- Children of TextPanel
&#9;&#9;&#9;&#9;&#9;local rolloverText = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;&#9;&#9;&#9;rolloverText.Name = &quot;RolloverText&quot;
&#9;&#9;&#9;&#9;&#9;rolloverText.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;&#9;rolloverText.Size = UDim2.new(1,0,0,48)
&#9;&#9;&#9;&#9;&#9;rolloverText.ZIndex = 6
&#9;&#9;&#9;&#9;&#9;rolloverText.Font = Enum.Font.ArialBold
&#9;&#9;&#9;&#9;&#9;rolloverText.FontSize = Enum.FontSize.Size24
&#9;&#9;&#9;&#9;&#9;rolloverText.Text = &quot;&quot;
&#9;&#9;&#9;&#9;&#9;rolloverText.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;&#9;rolloverText.TextWrap = true
&#9;&#9;&#9;&#9;&#9;rolloverText.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;&#9;&#9;&#9;rolloverText.TextYAlignment = Enum.TextYAlignment.Top
&#9;&#9;&#9;&#9;&#9;rolloverText.Parent = textPanel
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local largePreview = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;&#9;&#9;largePreview.Name = &quot;LargePreview&quot;
&#9;&#9;&#9;&#9;largePreview.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;largePreview.Image = &quot;&quot;
&#9;&#9;&#9;&#9;largePreview.Size = UDim2.new(1,0,0,170)
&#9;&#9;&#9;&#9;largePreview.ZIndex = 6
&#9;&#9;&#9;&#9;largePreview.Parent = itemPreview
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;local sets = Instance.new(&quot;Frame&quot;)
&#9;&#9;&#9;sets.Name = &quot;Sets&quot;
&#9;&#9;&#9;sets.BackgroundTransparency = 1
&#9;&#9;&#9;sets.Position = UDim2.new(0,0,0,5)
&#9;&#9;&#9;sets.Size = UDim2.new(0.23,0,1,-5)
&#9;&#9;&#9;sets.ZIndex = 6
&#9;&#9;&#9;sets.Parent = setPanel
&#9;&#9;&#9;
&#9;&#9;&#9;&#9;-- Children of Sets
&#9;&#9;&#9;&#9;local line = Instance.new(&quot;Frame&quot;)
&#9;&#9;&#9;&#9;line.Name = &quot;Line&quot;
&#9;&#9;&#9;&#9;line.BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;line.BackgroundTransparency = 0.7
&#9;&#9;&#9;&#9;line.BorderSizePixel = 0
&#9;&#9;&#9;&#9;line.Position = UDim2.new(1,-3,0.06,0)
&#9;&#9;&#9;&#9;line.Size = UDim2.new(0,3,0.9,0)
&#9;&#9;&#9;&#9;line.ZIndex = 6
&#9;&#9;&#9;&#9;line.Parent = sets
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local setsLists, controlFrame = t.CreateTrueScrollingFrame()
&#9;&#9;&#9;&#9;setsLists.Size = UDim2.new(1,-6,0.94,0)
&#9;&#9;&#9;&#9;setsLists.Position = UDim2.new(0,0,0.06,0)
&#9;&#9;&#9;&#9;setsLists.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;setsLists.Name = &quot;SetsLists&quot;
&#9;&#9;&#9;&#9;setsLists.ZIndex = 6
&#9;&#9;&#9;&#9;setsLists.Parent = sets
&#9;&#9;&#9;&#9;drillDownSetZIndex(controlFrame, 7)
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local setsHeader = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;&#9;&#9;setsHeader.Name = &quot;SetsHeader&quot;
&#9;&#9;&#9;&#9;setsHeader.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;setsHeader.Size = UDim2.new(0,47,0,24)
&#9;&#9;&#9;&#9;setsHeader.ZIndex = 6
&#9;&#9;&#9;&#9;setsHeader.Font = Enum.Font.ArialBold
&#9;&#9;&#9;&#9;setsHeader.FontSize = Enum.FontSize.Size24
&#9;&#9;&#9;&#9;setsHeader.Text = &quot;Sets&quot;
&#9;&#9;&#9;&#9;setsHeader.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;setsHeader.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;&#9;&#9;setsHeader.TextYAlignment = Enum.TextYAlignment.Top
&#9;&#9;&#9;&#9;setsHeader.Parent = sets
&#9;&#9;&#9;
&#9;&#9;&#9;local cancelButton = Instance.new(&quot;TextButton&quot;)
&#9;&#9;&#9;cancelButton.Name = &quot;CancelButton&quot;
&#9;&#9;&#9;cancelButton.Position = UDim2.new(1,-32,0,-2)
&#9;&#9;&#9;cancelButton.Size = UDim2.new(0,34,0,34)
&#9;&#9;&#9;cancelButton.Style = Enum.ButtonStyle.RobloxButtonDefault
&#9;&#9;&#9;cancelButton.ZIndex = 6
&#9;&#9;&#9;cancelButton.Text = &quot;&quot;
&#9;&#9;&#9;cancelButton.Modal = true
&#9;&#9;&#9;cancelButton.Parent = setPanel
&#9;&#9;&#9;
&#9;&#9;&#9;&#9;-- Children of Cancel Button
&#9;&#9;&#9;&#9;local cancelImage = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;&#9;&#9;cancelImage.Name = &quot;CancelImage&quot;
&#9;&#9;&#9;&#9;cancelImage.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;cancelImage.Image = &quot;http://www.roblox.com/asset/?id=54135717&quot;
&#9;&#9;&#9;&#9;cancelImage.Position = UDim2.new(0,-2,0,-2)
&#9;&#9;&#9;&#9;cancelImage.Size = UDim2.new(0,16,0,16)
&#9;&#9;&#9;&#9;cancelImage.ZIndex = 6
&#9;&#9;&#9;&#9;cancelImage.Parent = cancelButton
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;return setGui
&#9;end
&#9;
&#9;local function createSetButton(text)
&#9;&#9;local setButton = Instance.new(&quot;TextButton&quot;)
&#9;&#9;
&#9;&#9;if text then setButton.Text = text
&#9;&#9;else setButton.Text = &quot;&quot; end
&#9;&#9;
&#9;&#9;setButton.AutoButtonColor = false
&#9;&#9;setButton.BackgroundTransparency = 1
&#9;&#9;setButton.BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;setButton.BorderSizePixel = 0
&#9;&#9;setButton.Size = UDim2.new(1,-5,0,18)
&#9;&#9;setButton.ZIndex = 6
&#9;&#9;setButton.Visible = false
&#9;&#9;setButton.Font = Enum.Font.Arial
&#9;&#9;setButton.FontSize = Enum.FontSize.Size18
&#9;&#9;setButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;setButton.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;
&#9;&#9;return setButton
&#9;end
&#9;
&#9;local function buildSetButton(name, setId, setImageId, i, count)
&#9;&#9;local button = createSetButton(name)
&#9;&#9;button.Text = name
&#9;&#9;button.Name = &quot;SetButton&quot;
&#9;&#9;button.Visible = true
&#9;&#9;
&#9;&#9;local setValue = Instance.new(&quot;IntValue&quot;)
&#9;&#9;setValue.Name = &quot;SetId&quot;
&#9;&#9;setValue.Value = setId
&#9;&#9;setValue.Parent = button
&#9;&#9;local setName = Instance.new(&quot;StringValue&quot;)
&#9;&#9;setName.Name = &quot;SetName&quot;
&#9;&#9;setName.Value = name
&#9;&#9;setName.Parent = button
&#9;&#9;return button
&#9;end
&#9;
&#9;local function processCategory(sets)
&#9;&#9;local setButtons = {}
&#9;&#9;local numSkipped = 0
&#9;&#9;for i = 1, #sets do
&#9;&#9;&#9;if not showAdminCategories and sets[i].Name == &quot;Beta&quot; then
&#9;&#9;&#9;&#9;numSkipped = numSkipped + 1
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;setButtons[i - numSkipped] = buildSetButton(sets[i].Name, sets[i].CategoryId, sets[i].ImageAssetId, i - numSkipped, #sets)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;return setButtons
&#9;end
&#9;
&#9;local function handleResize()
&#9;&#9;wait() -- neccessary to insure heartbeat happened
&#9;&#9;
&#9;&#9;local itemPreview = setGui.SetPanel.ItemPreview
&#9;&#9;
&#9;&#9;itemPreview.LargePreview.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.X)
&#9;&#9;itemPreview.LargePreview.Position = UDim2.new(0.5,-itemPreview.LargePreview.AbsoluteSize.X/2,0,0)
&#9;&#9;itemPreview.TextPanel.Position = UDim2.new(0,0,0,itemPreview.LargePreview.AbsoluteSize.Y)
&#9;&#9;itemPreview.TextPanel.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.Y - itemPreview.LargePreview.AbsoluteSize.Y)
&#9;end
&#9;
&#9;local function makeInsertAssetButton()
&#9;&#9;local insertAssetButtonExample = Instance.new(&quot;Frame&quot;)
&#9;&#9;insertAssetButtonExample.Name = &quot;InsertAssetButtonExample&quot;
&#9;&#9;insertAssetButtonExample.Position = UDim2.new(0,128,0,64)
&#9;&#9;insertAssetButtonExample.Size = UDim2.new(0,64,0,64)
&#9;&#9;insertAssetButtonExample.BackgroundTransparency = 1
&#9;&#9;insertAssetButtonExample.ZIndex = 6
&#9;&#9;insertAssetButtonExample.Visible = false
&#9;&#9;local assetId = Instance.new(&quot;IntValue&quot;)
&#9;&#9;assetId.Name = &quot;AssetId&quot;
&#9;&#9;assetId.Value = 0
&#9;&#9;assetId.Parent = insertAssetButtonExample
&#9;&#9;
&#9;&#9;local assetName = Instance.new(&quot;StringValue&quot;)
&#9;&#9;assetName.Name = &quot;AssetName&quot;
&#9;&#9;assetName.Value = &quot;&quot;
&#9;&#9;assetName.Parent = insertAssetButtonExample
&#9;&#9;local button = Instance.new(&quot;TextButton&quot;)
&#9;&#9;button.Name = &quot;Button&quot;
&#9;&#9;button.Text = &quot;&quot;
&#9;&#9;button.Style = Enum.ButtonStyle.RobloxButton
&#9;&#9;button.Position = UDim2.new(0.025,0,0.025,0)
&#9;&#9;button.Size = UDim2.new(0.95,0,0.95,0)
&#9;&#9;button.ZIndex = 6
&#9;&#9;button.Parent = insertAssetButtonExample
&#9;&#9;local buttonImage = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;buttonImage.Name = &quot;ButtonImage&quot;
&#9;&#9;buttonImage.Image = &quot;&quot;
&#9;&#9;buttonImage.Position = UDim2.new(0,-7,0,-7)
&#9;&#9;buttonImage.Size = UDim2.new(1,14,1,14)
&#9;&#9;buttonImage.BackgroundTransparency = 1
&#9;&#9;buttonImage.ZIndex = 7
&#9;&#9;buttonImage.Parent = button
&#9;&#9;local configIcon = buttonImage:clone()
&#9;&#9;configIcon.Name = &quot;ConfigIcon&quot;
&#9;&#9;configIcon.Visible = false
&#9;&#9;configIcon.Position = UDim2.new(1,-23,1,-24)
&#9;&#9;configIcon.Size = UDim2.new(0,16,0,16)
&#9;&#9;configIcon.Image = &quot;&quot;
&#9;&#9;configIcon.ZIndex = 6
&#9;&#9;configIcon.Parent = insertAssetButtonExample
&#9;&#9;
&#9;&#9;return insertAssetButtonExample
&#9;end
&#9;
&#9;local function showLargePreview(insertButton)
&#9;&#9;if insertButton:FindFirstChild(&quot;AssetId&quot;) then
&#9;&#9;&#9;delay(0,function()
&#9;&#9;&#9;&#9;game:GetService(&quot;ContentProvider&quot;):Preload(LargeThumbnailUrl .. tostring(insertButton.AssetId.Value))
&#9;&#9;&#9;&#9;setGui.SetPanel.ItemPreview.LargePreview.Image = LargeThumbnailUrl .. tostring(insertButton.AssetId.Value)
&#9;&#9;&#9;end)
&#9;&#9;end
&#9;&#9;if insertButton:FindFirstChild(&quot;AssetName&quot;) then
&#9;&#9;&#9;setGui.SetPanel.ItemPreview.TextPanel.RolloverText.Text = insertButton.AssetName.Value
&#9;&#9;end
&#9;end
&#9;
&#9;local function selectTerrainShape(shape)
&#9;&#9;if currTerrainDropDownFrame then
&#9;&#9;&#9;objectSelected(tostring(currTerrainDropDownFrame.AssetName.Value), tonumber(currTerrainDropDownFrame.AssetId.Value), shape)
&#9;&#9;end
&#9;end
&#9;
&#9;local function createTerrainTypeButton(name, parent)
&#9;&#9;local dropDownTextButton = Instance.new(&quot;TextButton&quot;)
&#9;&#9;dropDownTextButton.Name = name .. &quot;Button&quot;
&#9;&#9;dropDownTextButton.Font = Enum.Font.ArialBold
&#9;&#9;dropDownTextButton.FontSize = Enum.FontSize.Size14
&#9;&#9;dropDownTextButton.BorderSizePixel = 0
&#9;&#9;dropDownTextButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;dropDownTextButton.Text = name
&#9;&#9;dropDownTextButton.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;dropDownTextButton.BackgroundTransparency = 1
&#9;&#9;dropDownTextButton.ZIndex = parent.ZIndex + 1
&#9;&#9;dropDownTextButton.Size = UDim2.new(0,parent.Size.X.Offset - 2,0,16)
&#9;&#9;dropDownTextButton.Position = UDim2.new(0,1,0,0)
&#9;&#9;dropDownTextButton.MouseEnter:connect(function()
&#9;&#9;&#9;dropDownTextButton.BackgroundTransparency = 0
&#9;&#9;&#9;dropDownTextButton.TextColor3 = Color3.new(0,0,0)
&#9;&#9;end)
&#9;&#9;dropDownTextButton.MouseLeave:connect(function()
&#9;&#9;&#9;dropDownTextButton.BackgroundTransparency = 1
&#9;&#9;&#9;dropDownTextButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;end)
&#9;&#9;dropDownTextButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;dropDownTextButton.BackgroundTransparency = 1
&#9;&#9;&#9;dropDownTextButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;if dropDownTextButton.Parent and dropDownTextButton.Parent:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;dropDownTextButton.Parent.Visible = false
&#9;&#9;&#9;end
&#9;&#9;&#9;selectTerrainShape(terrainShapeMap[dropDownTextButton.Text])
&#9;&#9;end)
&#9;&#9;return dropDownTextButton
&#9;end
&#9;
&#9;local function createTerrainDropDownMenu(zIndex)
&#9;&#9;local dropDown = Instance.new(&quot;Frame&quot;)
&#9;&#9;dropDown.Name = &quot;TerrainDropDown&quot;
&#9;&#9;dropDown.BackgroundColor3 = Color3.new(0,0,0)
&#9;&#9;dropDown.BorderColor3 = Color3.new(1,0,0)
&#9;&#9;dropDown.Size = UDim2.new(0,200,0,0)
&#9;&#9;dropDown.Visible = false
&#9;&#9;dropDown.ZIndex = zIndex
&#9;&#9;dropDown.Parent = setGui
&#9;&#9;for i = 1, #terrainShapes do
&#9;&#9;&#9;local shapeButton = createTerrainTypeButton(terrainShapes[i],dropDown)
&#9;&#9;&#9;shapeButton.Position = UDim2.new(0,1,0,(i - 1) * (shapeButton.Size.Y.Offset))
&#9;&#9;&#9;shapeButton.Parent = dropDown
&#9;&#9;&#9;dropDown.Size = UDim2.new(0,200,0,dropDown.Size.Y.Offset + (shapeButton.Size.Y.Offset))
&#9;&#9;end
&#9;&#9;dropDown.MouseLeave:connect(function()
&#9;&#9;&#9;dropDown.Visible = false
&#9;&#9;end)
&#9;end
&#9;
&#9;local function createDropDownMenuButton(parent)
&#9;&#9;local dropDownButton = Instance.new(&quot;ImageButton&quot;)
&#9;&#9;dropDownButton.Name = &quot;DropDownButton&quot;
&#9;&#9;dropDownButton.Image = &quot;http://www.roblox.com/asset/?id=67581509&quot;
&#9;&#9;dropDownButton.BackgroundTransparency = 1
&#9;&#9;dropDownButton.Size = UDim2.new(0,16,0,16)
&#9;&#9;dropDownButton.Position = UDim2.new(1,-24,0,6)
&#9;&#9;dropDownButton.ZIndex = parent.ZIndex + 2
&#9;&#9;dropDownButton.Parent = parent
&#9;&#9;
&#9;&#9;if not setGui:FindFirstChild(&quot;TerrainDropDown&quot;) then
&#9;&#9;&#9;createTerrainDropDownMenu(8)
&#9;&#9;end
&#9;&#9;
&#9;&#9;dropDownButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;setGui.TerrainDropDown.Visible = true
&#9;&#9;&#9;setGui.TerrainDropDown.Position = UDim2.new(0,parent.AbsolutePosition.X,0,parent.AbsolutePosition.Y)
&#9;&#9;&#9;currTerrainDropDownFrame = parent
&#9;&#9;end)
&#9;end
&#9;
&#9;local function buildInsertButton()
&#9;&#9;local insertButton = makeInsertAssetButton()
&#9;&#9;insertButton.Name = &quot;InsertAssetButton&quot;
&#9;&#9;insertButton.Visible = true
&#9;&#9;if Data.Category[Data.CurrentCategory].SetName == &quot;High Scalability&quot; then
&#9;&#9;&#9;createDropDownMenuButton(insertButton)
&#9;&#9;end
&#9;&#9;local lastEnter = nil
&#9;&#9;local mouseEnterCon = insertButton.MouseEnter:connect(function()
&#9;&#9;&#9;lastEnter = insertButton
&#9;&#9;&#9;delay(0.1,function()
&#9;&#9;&#9;&#9;if lastEnter == insertButton then
&#9;&#9;&#9;&#9;&#9;showLargePreview(insertButton)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;end)
&#9;&#9;return insertButton, mouseEnterCon
&#9;end
&#9;
&#9;local function realignButtonGrid(columns)
&#9;&#9;local x = 0
&#9;&#9;local y = 0
&#9;&#9;for i = 1, #insertButtons do
&#9;&#9;&#9;insertButtons[i].Position = UDim2.new(0, buttonWidth * x, 0, buttonHeight * y)
&#9;&#9;&#9;x = x + 1
&#9;&#9;&#9;if x &gt;= columns then
&#9;&#9;&#9;&#9;x = 0
&#9;&#9;&#9;&#9;y = y + 1
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local function setInsertButtonImageBehavior(insertFrame, visible, name, assetId)
&#9;&#9;if visible then
&#9;&#9;&#9;insertFrame.AssetName.Value = name
&#9;&#9;&#9;insertFrame.AssetId.Value = assetId
&#9;&#9;&#9;local newImageUrl = SmallThumbnailUrl .. assetId
&#9;&#9;&#9;if newImageUrl ~= insertFrame.Button.ButtonImage.Image then
&#9;&#9;&#9;&#9;delay(0,function()
&#9;&#9;&#9;&#9;&#9;game:GetService(&quot;ContentProvider&quot;):Preload(SmallThumbnailUrl .. assetId)
&#9;&#9;&#9;&#9;&#9;if insertFrame:findFirstChild(&quot;Button&quot;) then
&#9;&#9;&#9;&#9;&#9;&#9;insertFrame.Button.ButtonImage.Image = SmallThumbnailUrl .. assetId
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;&#9;table.insert(insertButtonCons,
&#9;&#9;&#9;&#9;insertFrame.Button.MouseButton1Click:connect(function()
&#9;&#9;&#9;&#9;&#9;-- special case for water, show water selection gui
&#9;&#9;&#9;&#9;&#9;local isWaterSelected = (name == &quot;Water&quot;) and (Data.Category[Data.CurrentCategory].SetName == &quot;High Scalability&quot;)
&#9;&#9;&#9;&#9;&#9;waterGui.Visible = isWaterSelected
&#9;&#9;&#9;&#9;&#9;if isWaterSelected then
&#9;&#9;&#9;&#9;&#9;&#9;objectSelected(name, tonumber(assetId), nil)
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;objectSelected(name, tonumber(assetId))
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;)
&#9;&#9;&#9;insertFrame.Visible = true
&#9;&#9;else
&#9;&#9;&#9;insertFrame.Visible = false
&#9;&#9;end
&#9;end
&#9;
&#9;local function loadSectionOfItems(setGui, rows, columns)
&#9;&#9;local pageSize = rows * columns
&#9;&#9;if arrayPosition &gt; #contents then return end
&#9;&#9;local origArrayPos = arrayPosition
&#9;&#9;local yCopy = 0
&#9;&#9;for i = 1, pageSize + 1 do
&#9;&#9;&#9;if arrayPosition &gt;= #contents + 1 then
&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;end
&#9;&#9;&#9;local buttonCon
&#9;&#9;&#9;insertButtons[arrayPosition], buttonCon = buildInsertButton()
&#9;&#9;&#9;table.insert(insertButtonCons,buttonCon)
&#9;&#9;&#9;insertButtons[arrayPosition].Parent = setGui.SetPanel.ItemsFrame
&#9;&#9;&#9;arrayPosition = arrayPosition + 1
&#9;&#9;end
&#9;&#9;realignButtonGrid(columns)
&#9;&#9;local indexCopy = origArrayPos
&#9;&#9;for index = origArrayPos, arrayPosition do
&#9;&#9;&#9;if insertButtons[index] then
&#9;&#9;&#9;&#9;if contents[index] then
&#9;&#9;&#9;&#9;&#9;-- we don&apos;t want water to have a drop down button
&#9;&#9;&#9;&#9;&#9;if contents[index].Name == &quot;Water&quot; then
&#9;&#9;&#9;&#9;&#9;&#9;if Data.Category[Data.CurrentCategory].SetName == &quot;High Scalability&quot; then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;insertButtons[index]:FindFirstChild(&quot;DropDownButton&quot;,true):Destroy()
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;local assetId
&#9;&#9;&#9;&#9;&#9;if useAssetVersionId then
&#9;&#9;&#9;&#9;&#9;&#9;assetId = contents[index].AssetVersionId
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;assetId = contents[index].AssetId
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;setInsertButtonImageBehavior(insertButtons[index], true, contents[index].Name, assetId)
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;end
&#9;&#9;&#9;indexCopy = index
&#9;&#9;end
&#9;end
&#9;
&#9;local function setSetIndex()
&#9;&#9;Data.Category[Data.CurrentCategory].Index = 0
&#9;&#9;rows = 7
&#9;&#9;columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth)
&#9;&#9;contents = Data.Category[Data.CurrentCategory].Contents
&#9;&#9;if contents then
&#9;&#9;&#9;-- remove our buttons and their connections
&#9;&#9;&#9;for i = 1, #insertButtons do
&#9;&#9;&#9;&#9;insertButtons[i]:remove()
&#9;&#9;&#9;end
&#9;&#9;&#9;for i = 1, #insertButtonCons do
&#9;&#9;&#9;&#9;if insertButtonCons[i] then insertButtonCons[i]:disconnect() end
&#9;&#9;&#9;end
&#9;&#9;&#9;insertButtonCons = {}
&#9;&#9;&#9;insertButtons = {}
&#9;&#9;&#9;arrayPosition = 1
&#9;&#9;&#9;loadSectionOfItems(setGui, rows, columns)
&#9;&#9;end
&#9;end
&#9;
&#9;local function selectSet(button, setName, setId, setIndex)
&#9;&#9;if button and Data.Category[Data.CurrentCategory] ~= nil then
&#9;&#9;&#9;if button ~= Data.Category[Data.CurrentCategory].Button then
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory].Button = button
&#9;&#9;&#9;&#9;if SetCache[setId] == nil then
&#9;&#9;&#9;&#9;&#9;SetCache[setId] = game:GetService(&quot;InsertService&quot;):GetCollection(setId)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory].Contents = SetCache[setId]
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory].SetName = setName
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory].SetId = setId
&#9;&#9;&#9;end
&#9;&#9;&#9;setSetIndex()
&#9;&#9;end
&#9;end
&#9;
&#9;local function selectCategoryPage(buttons, page)
&#9;&#9;if buttons ~= Data.CurrentCategory then
&#9;&#9;&#9;if Data.CurrentCategory then
&#9;&#9;&#9;&#9;for key, button in pairs(Data.CurrentCategory) do
&#9;&#9;&#9;&#9;&#9;button.Visible = false
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;Data.CurrentCategory = buttons
&#9;&#9;&#9;if Data.Category[Data.CurrentCategory] == nil then
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory] = {}
&#9;&#9;&#9;&#9;if #buttons &gt; 0 then
&#9;&#9;&#9;&#9;&#9;selectSet(buttons[1], buttons[1].SetName.Value, buttons[1].SetId.Value, 0)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory].Button = nil
&#9;&#9;&#9;&#9;selectSet(Data.Category[Data.CurrentCategory].ButtonFrame, Data.Category[Data.CurrentCategory].SetName, Data.Category[Data.CurrentCategory].SetId, Data.Category[Data.CurrentCategory].Index)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;
&#9;local function selectCategory(category)
&#9;&#9;selectCategoryPage(category, 0)
&#9;end
&#9;
&#9;local function resetAllSetButtonSelection()
&#9;&#9;local setButtons = setGui.SetPanel.Sets.SetsLists:GetChildren()
&#9;&#9;for i = 1, #setButtons do
&#9;&#9;&#9;if setButtons[i]:IsA(&quot;TextButton&quot;) then
&#9;&#9;&#9;&#9;setButtons[i].Selected = false
&#9;&#9;&#9;&#9;setButtons[i].BackgroundTransparency = 1
&#9;&#9;&#9;&#9;setButtons[i].TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;setButtons[i].BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;
&#9;local function populateSetsFrame()
&#9;&#9;local currRow = 0
&#9;&#9;for i = 1, #userCategoryButtons do
&#9;&#9;&#9;local button = userCategoryButtons[i]
&#9;&#9;&#9;button.Visible = true
&#9;&#9;&#9;button.Position = UDim2.new(0,5,0,currRow * button.Size.Y.Offset)
&#9;&#9;&#9;button.Parent = setGui.SetPanel.Sets.SetsLists
&#9;&#9;&#9;
&#9;&#9;&#9;if i == 1 then -- we will have this selected by default, so show it
&#9;&#9;&#9;&#9;button.Selected = true
&#9;&#9;&#9;&#9;button.BackgroundColor3 = Color3.new(0,204/255,0)
&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(0,0,0)
&#9;&#9;&#9;&#9;button.BackgroundTransparency = 0
&#9;&#9;&#9;end
&#9;&#9;&#9;button.MouseEnter:connect(function()
&#9;&#9;&#9;&#9;if not button.Selected then
&#9;&#9;&#9;&#9;&#9;button.BackgroundTransparency = 0
&#9;&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(0,0,0)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;&#9;button.MouseLeave:connect(function()
&#9;&#9;&#9;&#9;if not button.Selected then
&#9;&#9;&#9;&#9;&#9;button.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;&#9;button.MouseButton1Click:connect(function()
&#9;&#9;&#9;&#9;resetAllSetButtonSelection()
&#9;&#9;&#9;&#9;button.Selected = not button.Selected
&#9;&#9;&#9;&#9;button.BackgroundColor3 = Color3.new(0,204/255,0)
&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(0,0,0)
&#9;&#9;&#9;&#9;button.BackgroundTransparency = 0
&#9;&#9;&#9;&#9;selectSet(button, button.Text, userCategoryButtons[i].SetId.Value, 0)
&#9;&#9;&#9;end)
&#9;&#9;&#9;currRow = currRow + 1
&#9;&#9;end
&#9;&#9;local buttons = setGui.SetPanel.Sets.SetsLists:GetChildren()
&#9;&#9;-- set first category as loaded for default
&#9;&#9;if buttons then
&#9;&#9;&#9;for i = 1, #buttons do
&#9;&#9;&#9;&#9;if buttons[i]:IsA(&quot;TextButton&quot;) then
&#9;&#9;&#9;&#9;&#9;selectSet(buttons[i], buttons[i].Text, userCategoryButtons[i].SetId.Value, 0)
&#9;&#9;&#9;&#9;&#9;selectCategory(userCategoryButtons)
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;setGui = createSetGui()
&#9;waterGui, waterTypeChangedEvent = createWaterGui()
&#9;waterGui.Position = UDim2.new(0,55,0,0)
&#9;waterGui.Parent = setGui
&#9;setGui.Changed:connect(function(prop) -- this resizes the preview image to always be the right size
&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;handleResize()
&#9;&#9;&#9;setSetIndex()
&#9;&#9;end
&#9;end)
&#9;
&#9;local scrollFrame, controlFrame = t.CreateTrueScrollingFrame()
&#9;scrollFrame.Size = UDim2.new(0.54,0,0.85,0)
&#9;scrollFrame.Position = UDim2.new(0.24,0,0.085,0)
&#9;scrollFrame.Name = &quot;ItemsFrame&quot;
&#9;scrollFrame.ZIndex = 6
&#9;scrollFrame.Parent = setGui.SetPanel
&#9;scrollFrame.BackgroundTransparency = 1
&#9;drillDownSetZIndex(controlFrame,7)
&#9;controlFrame.Parent = setGui.SetPanel
&#9;controlFrame.Position = UDim2.new(0.76, 5, 0, 0)
&#9;local debounce = false
&#9;controlFrame.ScrollBottom.Changed:connect(function(prop)
&#9;&#9;if controlFrame.ScrollBottom.Value == true then
&#9;&#9;&#9;if debounce then return end
&#9;&#9;&#9;debounce = true
&#9;&#9;&#9;&#9;loadSectionOfItems(setGui, rows, columns)
&#9;&#9;&#9;debounce = false
&#9;&#9;end
&#9;end)
&#9;local userData = {}
&#9;for id = 1, #userIdsForSets do
&#9;&#9;local newUserData = game:GetService(&quot;InsertService&quot;):GetUserSets(userIdsForSets[id])
&#9;&#9;if newUserData and #newUserData &gt; 2 then
&#9;&#9;&#9;-- start at #3 to skip over My Decals and My Models for each account
&#9;&#9;&#9;for category = 3, #newUserData do
&#9;&#9;&#9;&#9;if newUserData[category].Name == &quot;High Scalability&quot; then -- we want high scalability parts to show first
&#9;&#9;&#9;&#9;&#9;table.insert(userData,1,newUserData[category])
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;table.insert(userData, newUserData[category])
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;
&#9;end
&#9;if userData then
&#9;&#9;userCategoryButtons = processCategory(userData)
&#9;end
&#9;rows = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.Y/buttonHeight)
&#9;columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth)
&#9;populateSetsFrame()
&#9;insertPanelCloseCon = setGui.SetPanel.CancelButton.MouseButton1Click:connect(function()
&#9;&#9;setGui.SetPanel.Visible = false
&#9;&#9;if dialogClosed then dialogClosed() end
&#9;end)
&#9;
&#9;local setVisibilityFunction = function(visible)
&#9;&#9;if visible then
&#9;&#9;&#9;setGui.SetPanel.Visible = true
&#9;&#9;else
&#9;&#9;&#9;setGui.SetPanel.Visible = false
&#9;&#9;end
&#9;end
&#9;
&#9;local getVisibilityFunction = function()
&#9;&#9;if setGui then
&#9;&#9;&#9;if setGui:FindFirstChild(&quot;SetPanel&quot;) then
&#9;&#9;&#9;&#9;return setGui.SetPanel.Visible
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;
&#9;&#9;return false
&#9;end
&#9;
&#9;return setGui, setVisibilityFunction, getVisibilityFunction, waterTypeChangedEvent
end
t.CreateTerrainMaterialSelector = function(size,position)
&#9;local terrainMaterialSelectionChanged = Instance.new(&quot;BindableEvent&quot;)
&#9;terrainMaterialSelectionChanged.Name = &quot;TerrainMaterialSelectionChanged&quot;
&#9;local selectedButton = nil
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Name = &quot;TerrainMaterialSelector&quot;
&#9;if size then
&#9;&#9;frame.Size = size
&#9;else
&#9;&#9;frame.Size = UDim2.new(0, 245, 0, 230)
&#9;end
&#9;if position then
&#9;&#9;frame.Position = position
&#9;end
&#9;frame.BorderSizePixel = 0
&#9;frame.BackgroundColor3 = Color3.new(0,0,0)
&#9;frame.Active = true
&#9;terrainMaterialSelectionChanged.Parent = frame
&#9;local waterEnabled = true -- todo: turn this on when water is ready
&#9;local materialToImageMap = {}
&#9;local materialNames = {&quot;Grass&quot;, &quot;Sand&quot;, &quot;Brick&quot;, &quot;Granite&quot;, &quot;Asphalt&quot;, &quot;Iron&quot;, &quot;Aluminum&quot;, &quot;Gold&quot;, &quot;Plank&quot;, &quot;Log&quot;, &quot;Gravel&quot;, &quot;Cinder Block&quot;, &quot;Stone Wall&quot;, &quot;Concrete&quot;, &quot;Plastic (red)&quot;, &quot;Plastic (blue)&quot;}
&#9;if waterEnabled then
&#9;&#9;table.insert(materialNames,&quot;Water&quot;)
&#9;end
&#9;local currentMaterial = 1
&#9;function getEnumFromName(choice)
&#9;&#9;if choice == &quot;Grass&quot; then return 1 end
&#9;&#9;if choice == &quot;Sand&quot; then return 2 end
&#9;&#9;if choice == &quot;Erase&quot; then return 0 end
&#9;&#9;if choice == &quot;Brick&quot; then return 3 end
&#9;&#9;if choice == &quot;Granite&quot; then return 4 end
&#9;&#9;if choice == &quot;Asphalt&quot; then return 5 end
&#9;&#9;if choice == &quot;Iron&quot; then return 6 end
&#9;&#9;if choice == &quot;Aluminum&quot; then return 7 end
&#9;&#9;if choice == &quot;Gold&quot; then return 8 end
&#9;&#9;if choice == &quot;Plank&quot; then return 9 end
&#9;&#9;if choice == &quot;Log&quot; then return 10 end
&#9;&#9;if choice == &quot;Gravel&quot; then return 11 end
&#9;&#9;if choice == &quot;Cinder Block&quot; then return 12 end
&#9;&#9;if choice == &quot;Stone Wall&quot; then return 13 end
&#9;&#9;if choice == &quot;Concrete&quot; then return 14 end
&#9;&#9;if choice == &quot;Plastic (red)&quot; then return 15 end
&#9;&#9;if choice == &quot;Plastic (blue)&quot; then return 16 end
&#9;&#9;if choice == &quot;Water&quot; then return 17 end
&#9;end
&#9;function getNameFromEnum(choice)
&#9;&#9;if choice == Enum.CellMaterial.Grass or choice == 1 then return &quot;Grass&quot;end
&#9;&#9;if choice == Enum.CellMaterial.Sand or choice == 2 then return &quot;Sand&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Empty or choice == 0 then return &quot;Erase&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Brick or choice == 3 then return &quot;Brick&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Granite or choice == 4 then return &quot;Granite&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Asphalt or choice == 5 then return &quot;Asphalt&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Iron or choice == 6 then return &quot;Iron&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Aluminum or choice == 7 then return &quot;Aluminum&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Gold or choice == 8 then return &quot;Gold&quot; end
&#9;&#9;if choice == Enum.CellMaterial.WoodPlank or choice == 9 then return &quot;Plank&quot; end
&#9;&#9;if choice == Enum.CellMaterial.WoodLog or choice == 10 then return &quot;Log&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Gravel or choice == 11 then return &quot;Gravel&quot; end
&#9;&#9;if choice == Enum.CellMaterial.CinderBlock or choice == 12 then return &quot;Cinder Block&quot; end
&#9;&#9;if choice == Enum.CellMaterial.MossyStone or choice == 13 then return &quot;Stone Wall&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Cement or choice == 14 then return &quot;Concrete&quot; end
&#9;&#9;if choice == Enum.CellMaterial.RedPlastic or choice == 15 then return &quot;Plastic (red)&quot; end
&#9;&#9;if choice == Enum.CellMaterial.BluePlastic or choice == 16 then return &quot;Plastic (blue)&quot; end
&#9;&#9;if waterEnabled then
&#9;&#9;&#9;if choice == Enum.CellMaterial.Water or choice == 17 then return &quot;Water&quot; end
&#9;&#9;end
&#9;end
&#9;local function updateMaterialChoice(choice)
&#9;&#9;currentMaterial = getEnumFromName(choice)
&#9;&#9;terrainMaterialSelectionChanged:Fire(currentMaterial)
&#9;end
&#9;-- we so need a better way to do this
&#9;for i,v in pairs(materialNames) do
&#9;&#9;materialToImageMap[v] = {}
&#9;&#9;if v == &quot;Grass&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=56563112&quot;
&#9;&#9;elseif v == &quot;Sand&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=62356652&quot;
&#9;&#9;elseif v == &quot;Brick&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=65961537&quot;
&#9;&#9;elseif v == &quot;Granite&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532153&quot;
&#9;&#9;elseif v == &quot;Asphalt&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532038&quot;
&#9;&#9;elseif v == &quot;Iron&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532093&quot;
&#9;&#9;elseif v == &quot;Aluminum&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67531995&quot;
&#9;&#9;elseif v == &quot;Gold&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532118&quot;
&#9;&#9;elseif v == &quot;Plastic (red)&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67531848&quot;
&#9;&#9;elseif v == &quot;Plastic (blue)&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67531924&quot;
&#9;&#9;elseif v == &quot;Plank&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532015&quot;
&#9;&#9;elseif v == &quot;Log&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532051&quot;
&#9;&#9;elseif v == &quot;Gravel&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532206&quot;
&#9;&#9;elseif v == &quot;Cinder Block&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532103&quot;
&#9;&#9;elseif v == &quot;Stone Wall&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67531804&quot;
&#9;&#9;elseif v == &quot;Concrete&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532059&quot;
&#9;&#9;elseif v == &quot;Water&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=81407474&quot;
&#9;&#9;else materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=66887593&quot; -- fill in the rest here!!
&#9;&#9;end
&#9;end
&#9;local scrollFrame, scrollUp, scrollDown, recalculateScroll = t.CreateScrollingFrame(nil,&quot;grid&quot;)
&#9;scrollFrame.Size = UDim2.new(0.85,0,1,0)
&#9;scrollFrame.Position = UDim2.new(0,0,0,0)
&#9;scrollFrame.Parent = frame
&#9;scrollUp.Parent = frame
&#9;scrollUp.Visible = true
&#9;scrollUp.Position = UDim2.new(1,-19,0,0)
&#9;scrollDown.Parent = frame
&#9;scrollDown.Visible = true
&#9;scrollDown.Position = UDim2.new(1,-19,1,-17)
&#9;local function goToNewMaterial(buttonWrap, materialName)
&#9;&#9;updateMaterialChoice(materialName)
&#9;&#9;buttonWrap.BackgroundTransparency = 0
&#9;&#9;selectedButton.BackgroundTransparency = 1
&#9;&#9;selectedButton = buttonWrap
&#9;end
&#9;local function createMaterialButton(name)&#9;
&#9;&#9;local buttonWrap = Instance.new(&quot;TextButton&quot;)
&#9;&#9;buttonWrap.Text = &quot;&quot;
&#9;&#9;buttonWrap.Size = UDim2.new(0,32,0,32)
&#9;&#9;buttonWrap.BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;buttonWrap.BorderSizePixel = 0
&#9;&#9;buttonWrap.BackgroundTransparency = 1
&#9;&#9;buttonWrap.AutoButtonColor = false
&#9;&#9;buttonWrap.Name = tostring(name)
&#9;&#9;
&#9;&#9;local imageButton = Instance.new(&quot;ImageButton&quot;)
&#9;&#9;imageButton.AutoButtonColor = false
&#9;&#9;imageButton.BackgroundTransparency = 1
&#9;&#9;imageButton.Size = UDim2.new(0,30,0,30)
&#9;&#9;imageButton.Position = UDim2.new(0,1,0,1)
&#9;&#9;imageButton.Name = tostring(name)
&#9;&#9;imageButton.Parent = buttonWrap
&#9;&#9;imageButton.Image = materialToImageMap[name].Regular
&#9;&#9;local enumType = Instance.new(&quot;NumberValue&quot;)
&#9;&#9;enumType.Name = &quot;EnumType&quot;
&#9;&#9;enumType.Parent = buttonWrap
&#9;&#9;enumType.Value = 0
&#9;&#9;
&#9;&#9;imageButton.MouseEnter:connect(function()
&#9;&#9;&#9;buttonWrap.BackgroundTransparency = 0
&#9;&#9;end)
&#9;&#9;imageButton.MouseLeave:connect(function()
&#9;&#9;&#9;if selectedButton ~= buttonWrap then
&#9;&#9;&#9;&#9;buttonWrap.BackgroundTransparency = 1
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;&#9;imageButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;if selectedButton ~= buttonWrap then
&#9;&#9;&#9;&#9;goToNewMaterial(buttonWrap, tostring(name))
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;&#9;
&#9;&#9;return buttonWrap
&#9;end
&#9;for i = 1, #materialNames do
&#9;&#9;local imageButton = createMaterialButton(materialNames[i])
&#9;&#9;
&#9;&#9;if materialNames[i] == &quot;Grass&quot; then -- always start with grass as the default
&#9;&#9;&#9;selectedButton = imageButton
&#9;&#9;&#9;imageButton.BackgroundTransparency = 0
&#9;&#9;end
&#9;&#9;
&#9;&#9;imageButton.Parent = scrollFrame
&#9;end
&#9;local forceTerrainMaterialSelection = function(newMaterialType)
&#9;&#9;if not newMaterialType then return end
&#9;&#9;if currentMaterial == newMaterialType then return end
&#9;&#9;local matName = getNameFromEnum(newMaterialType)
&#9;&#9;local buttons = scrollFrame:GetChildren()
&#9;&#9;for i = 1, #buttons do
&#9;&#9;&#9;if buttons[i].Name == &quot;Plastic (blue)&quot; and matName == &quot;Plastic (blue)&quot; then goToNewMaterial(buttons[i],matName) return end
&#9;&#9;&#9;if buttons[i].Name == &quot;Plastic (red)&quot; and matName == &quot;Plastic (red)&quot; then goToNewMaterial(buttons[i],matName) return end
&#9;&#9;&#9;if string.find(buttons[i].Name, matName) then
&#9;&#9;&#9;&#9;goToNewMaterial(buttons[i],matName)
&#9;&#9;&#9;&#9;return
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;frame.Changed:connect(function ( prop )
&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;recalculateScroll()
&#9;&#9;end
&#9;end)
&#9;recalculateScroll()
&#9;return frame, terrainMaterialSelectionChanged, forceTerrainMaterialSelection
end
t.CreateLoadingFrame = function(name,size,position)
&#9;game:GetService(&quot;ContentProvider&quot;):Preload(&quot;http://www.roblox.com/asset/?id=35238053&quot;)
&#9;local loadingFrame = Instance.new(&quot;Frame&quot;)
&#9;loadingFrame.Name = &quot;LoadingFrame&quot;
&#9;loadingFrame.Style = Enum.FrameStyle.RobloxRound
&#9;if size then loadingFrame.Size = size
&#9;else loadingFrame.Size = UDim2.new(0,300,0,160) end
&#9;if position then loadingFrame.Position = position
&#9;else loadingFrame.Position = UDim2.new(0.5, -150, 0.5,-80) end
&#9;local loadingBar = Instance.new(&quot;Frame&quot;)
&#9;loadingBar.Name = &quot;LoadingBar&quot;
&#9;loadingBar.BackgroundColor3 = Color3.new(0,0,0)
&#9;loadingBar.BorderColor3 = Color3.new(79/255,79/255,79/255)
&#9;loadingBar.Position = UDim2.new(0,0,0,41)
&#9;loadingBar.Size = UDim2.new(1,0,0,30)
&#9;loadingBar.Parent = loadingFrame
&#9;&#9;local loadingGreenBar = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;loadingGreenBar.Name = &quot;LoadingGreenBar&quot;
&#9;&#9;loadingGreenBar.Image = &quot;http://www.roblox.com/asset/?id=35238053&quot;
&#9;&#9;loadingGreenBar.Position = UDim2.new(0,0,0,0)
&#9;&#9;loadingGreenBar.Size = UDim2.new(0,0,1,0)
&#9;&#9;loadingGreenBar.Visible = false
&#9;&#9;loadingGreenBar.Parent = loadingBar
&#9;&#9;local loadingPercent = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;loadingPercent.Name = &quot;LoadingPercent&quot;
&#9;&#9;loadingPercent.BackgroundTransparency = 1
&#9;&#9;loadingPercent.Position = UDim2.new(0,0,1,0)
&#9;&#9;loadingPercent.Size = UDim2.new(1,0,0,14)
&#9;&#9;loadingPercent.Font = Enum.Font.Arial
&#9;&#9;loadingPercent.Text = &quot;0%&quot;
&#9;&#9;loadingPercent.FontSize = Enum.FontSize.Size14
&#9;&#9;loadingPercent.TextColor3 = Color3.new(1,1,1)
&#9;&#9;loadingPercent.Parent = loadingBar
&#9;local cancelButton = Instance.new(&quot;TextButton&quot;)
&#9;cancelButton.Name = &quot;CancelButton&quot;
&#9;cancelButton.Position = UDim2.new(0.5,-60,1,-40)
&#9;cancelButton.Size = UDim2.new(0,120,0,40)
&#9;cancelButton.Font = Enum.Font.Arial
&#9;cancelButton.FontSize = Enum.FontSize.Size18
&#9;cancelButton.TextColor3 = Color3.new(1,1,1)
&#9;cancelButton.Text = &quot;Cancel&quot;
&#9;cancelButton.Style = Enum.ButtonStyle.RobloxButton
&#9;cancelButton.Parent = loadingFrame
&#9;local loadingName = Instance.new(&quot;TextLabel&quot;)
&#9;loadingName.Name = &quot;loadingName&quot;
&#9;loadingName.BackgroundTransparency = 1
&#9;loadingName.Size = UDim2.new(1,0,0,18)
&#9;loadingName.Position = UDim2.new(0,0,0,2)
&#9;loadingName.Font = Enum.Font.Arial
&#9;loadingName.Text = name
&#9;loadingName.TextColor3 = Color3.new(1,1,1)
&#9;loadingName.TextStrokeTransparency = 1
&#9;loadingName.FontSize = Enum.FontSize.Size18
&#9;loadingName.Parent = loadingFrame
&#9;local cancelButtonClicked = Instance.new(&quot;BindableEvent&quot;)
&#9;cancelButtonClicked.Name = &quot;CancelButtonClicked&quot;
&#9;cancelButtonClicked.Parent = cancelButton
&#9;cancelButton.MouseButton1Click:connect(function()
&#9;&#9;cancelButtonClicked:Fire()
&#9;end)
&#9;local updateLoadingGuiPercent = function(percent, tweenAction, tweenLength)
&#9;&#9;if percent and type(percent) ~= &quot;number&quot; then
&#9;&#9;&#9;error(&quot;updateLoadingGuiPercent expects number as argument, got&quot;,type(percent),&quot;instead&quot;)
&#9;&#9;end
&#9;&#9;local newSize = nil
&#9;&#9;if percent &lt; 0 then
&#9;&#9;&#9;newSize = UDim2.new(0,0,1,0)
&#9;&#9;elseif percent &gt; 1 then
&#9;&#9;&#9;newSize = UDim2.new(1,0,1,0)
&#9;&#9;else
&#9;&#9;&#9;newSize = UDim2.new(percent,0,1,0)
&#9;&#9;end
&#9;&#9;if tweenAction then
&#9;&#9;&#9;if not tweenLength then
&#9;&#9;&#9;&#9;error(&quot;updateLoadingGuiPercent is set to tween new percentage, but got no tween time length! Please pass this in as third argument&quot;)
&#9;&#9;&#9;end
&#9;&#9;&#9;if (newSize.X.Scale &gt; 0) then
&#9;&#9;&#9;&#9;loadingGreenBar.Visible = true
&#9;&#9;&#9;&#9;loadingGreenBar:TweenSize(&#9;newSize,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Enum.EasingDirection.Out,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Enum.EasingStyle.Quad,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;tweenLength,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;true)
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;loadingGreenBar:TweenSize(&#9;newSize,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Enum.EasingDirection.Out,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Enum.EasingStyle.Quad,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;tweenLength,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;if (newSize.X.Scale &lt; 0) then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;loadingGreenBar.Visible = false
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;loadingGreenBar.Size = newSize
&#9;&#9;&#9;loadingGreenBar.Visible = (newSize.X.Scale &gt; 0)
&#9;&#9;end
&#9;end
&#9;loadingGreenBar.Changed:connect(function(prop)
&#9;&#9;if prop == &quot;Size&quot; then
&#9;&#9;&#9;loadingPercent.Text = tostring( math.ceil(loadingGreenBar.Size.X.Scale * 100) ) .. &quot;%&quot;
&#9;&#9;end
&#9;end)
&#9;return loadingFrame, updateLoadingGuiPercent, cancelButtonClicked
end
t.CreatePluginFrame = function (name,size,position,scrollable,parent)
&#9;function createMenuButton(size,position,text,fontsize,name,parent)
&#9;&#9;local button = Instance.new(&quot;TextButton&quot;,parent)
&#9;&#9;button.AutoButtonColor = false
&#9;&#9;button.Name = name
&#9;&#9;button.BackgroundTransparency = 1
&#9;&#9;button.Position = position
&#9;&#9;button.Size = size
&#9;&#9;button.Font = Enum.Font.ArialBold
&#9;&#9;button.FontSize = fontsize
&#9;&#9;button.Text = text
&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;button.BorderSizePixel = 0
&#9;&#9;button.BackgroundColor3 = Color3.new(20/255,20/255,20/255)
&#9;&#9;button.MouseEnter:connect(function ( )
&#9;&#9;&#9;if button.Selected then return end
&#9;&#9;&#9;button.BackgroundTransparency = 0
&#9;&#9;end)
&#9;&#9;button.MouseLeave:connect(function ( )
&#9;&#9;&#9;if button.Selected then return end
&#9;&#9;&#9;button.BackgroundTransparency = 1
&#9;&#9;end)
&#9;&#9;return button
&#9;end
&#9;local dragBar = Instance.new(&quot;Frame&quot;,parent)
&#9;dragBar.Name = tostring(name) .. &quot;DragBar&quot;
&#9;dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255)
&#9;dragBar.BorderColor3 = Color3.new(0,0,0)
&#9;if size then
&#9;&#9;dragBar.Size = UDim2.new(size.X.Scale,size.X.Offset,0,20) + UDim2.new(0,20,0,0)
&#9;else
&#9;&#9;dragBar.Size = UDim2.new(0,183,0,20)
&#9;end
&#9;if position then
&#9;&#9;dragBar.Position = position
&#9;end
&#9;dragBar.Active = true
&#9;dragBar.Draggable = true
&#9;--dragBar.Visible = false
&#9;dragBar.MouseEnter:connect(function ( )
&#9;&#9;dragBar.BackgroundColor3 = Color3.new(49/255,49/255,49/255)
&#9;end)
&#9;dragBar.MouseLeave:connect(function ( )
&#9;&#9;dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255)
&#9;end)
&#9;-- plugin name label
&#9;local pluginNameLabel = Instance.new(&quot;TextLabel&quot;,dragBar)
&#9;pluginNameLabel.Name = &quot;BarNameLabel&quot;
&#9;pluginNameLabel.Text = &quot; &quot; .. tostring(name)
&#9;pluginNameLabel.TextColor3 = Color3.new(1,1,1)
&#9;pluginNameLabel.TextStrokeTransparency = 0
&#9;pluginNameLabel.Size = UDim2.new(1,0,1,0)
&#9;pluginNameLabel.Font = Enum.Font.ArialBold
&#9;pluginNameLabel.FontSize = Enum.FontSize.Size18
&#9;pluginNameLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;pluginNameLabel.BackgroundTransparency = 1
&#9;-- close button
&#9;local closeButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-16,0.5,-8),&quot;X&quot;,Enum.FontSize.Size14,&quot;CloseButton&quot;,dragBar)
&#9;local closeEvent = Instance.new(&quot;BindableEvent&quot;)
&#9;closeEvent.Name = &quot;CloseEvent&quot;
&#9;closeEvent.Parent = closeButton
&#9;closeButton.MouseButton1Click:connect(function ()
&#9;&#9;closeEvent:Fire()
&#9;&#9;closeButton.BackgroundTransparency = 1
&#9;end)
&#9;-- help button
&#9;local helpButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-51,0.5,-8),&quot;?&quot;,Enum.FontSize.Size14,&quot;HelpButton&quot;,dragBar)
&#9;local helpFrame = Instance.new(&quot;Frame&quot;,dragBar)
&#9;helpFrame.Name = &quot;HelpFrame&quot;
&#9;helpFrame.BackgroundColor3 = Color3.new(0,0,0)
&#9;helpFrame.Size = UDim2.new(0,300,0,552)
&#9;helpFrame.Position = UDim2.new(1,5,0,0)
&#9;helpFrame.Active = true
&#9;helpFrame.BorderSizePixel = 0
&#9;helpFrame.Visible = false
&#9;helpButton.MouseButton1Click:connect(function( )
&#9;&#9;helpFrame.Visible = not helpFrame.Visible
&#9;&#9;if helpFrame.Visible then
&#9;&#9;&#9;helpButton.Selected = true
&#9;&#9;&#9;helpButton.BackgroundTransparency = 0
&#9;&#9;&#9;local screenGui = getScreenGuiAncestor(helpFrame)
&#9;&#9;&#9;if screenGui then
&#9;&#9;&#9;&#9;if helpFrame.AbsolutePosition.X + helpFrame.AbsoluteSize.X &gt; screenGui.AbsoluteSize.X then --position on left hand side
&#9;&#9;&#9;&#9;&#9;helpFrame.Position = UDim2.new(0,-5 - helpFrame.AbsoluteSize.X,0,0)
&#9;&#9;&#9;&#9;else -- position on right hand side
&#9;&#9;&#9;&#9;&#9;helpFrame.Position = UDim2.new(1,5,0,0)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;helpFrame.Position = UDim2.new(1,5,0,0)
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;helpButton.Selected = false
&#9;&#9;&#9;helpButton.BackgroundTransparency = 1
&#9;&#9;end
&#9;end)
&#9;local minimizeButton = createMenuButton(UDim2.new(0,16,0,17),UDim2.new(1,-34,0.5,-8),&quot;-&quot;,Enum.FontSize.Size14,&quot;MinimizeButton&quot;,dragBar)
&#9;minimizeButton.TextYAlignment = Enum.TextYAlignment.Top
&#9;local minimizeFrame = Instance.new(&quot;Frame&quot;,dragBar)
&#9;minimizeFrame.Name = &quot;MinimizeFrame&quot;
&#9;minimizeFrame.BackgroundColor3 = Color3.new(73/255,73/255,73/255)
&#9;minimizeFrame.BorderColor3 = Color3.new(0,0,0)
&#9;minimizeFrame.Position = UDim2.new(0,0,1,0)
&#9;if size then
&#9;&#9;minimizeFrame.Size = UDim2.new(size.X.Scale,size.X.Offset,0,50) + UDim2.new(0,20,0,0)
&#9;else
&#9;&#9;minimizeFrame.Size = UDim2.new(0,183,0,50)
&#9;end
&#9;minimizeFrame.Visible = false
&#9;local minimizeBigButton = Instance.new(&quot;TextButton&quot;,minimizeFrame)
&#9;minimizeBigButton.Position = UDim2.new(0.5,-50,0.5,-20)
&#9;minimizeBigButton.Name = &quot;MinimizeButton&quot;
&#9;minimizeBigButton.Size = UDim2.new(0,100,0,40)
&#9;minimizeBigButton.Style = Enum.ButtonStyle.RobloxButton
&#9;minimizeBigButton.Font = Enum.Font.ArialBold
&#9;minimizeBigButton.FontSize = Enum.FontSize.Size18
&#9;minimizeBigButton.TextColor3 = Color3.new(1,1,1)
&#9;minimizeBigButton.Text = &quot;Show&quot;
&#9;local separatingLine = Instance.new(&quot;Frame&quot;,dragBar)
&#9;separatingLine.Name = &quot;SeparatingLine&quot;
&#9;separatingLine.BackgroundColor3 = Color3.new(115/255,115/255,115/255)
&#9;separatingLine.BorderSizePixel = 0
&#9;separatingLine.Position = UDim2.new(1,-18,0.5,-7)
&#9;separatingLine.Size = UDim2.new(0,1,0,14)
&#9;local otherSeparatingLine = separatingLine:clone()
&#9;otherSeparatingLine.Position = UDim2.new(1,-35,0.5,-7)
&#9;otherSeparatingLine.Parent = dragBar
&#9;local widgetContainer = Instance.new(&quot;Frame&quot;,dragBar)
&#9;widgetContainer.Name = &quot;WidgetContainer&quot;
&#9;widgetContainer.BackgroundTransparency = 1
&#9;widgetContainer.Position = UDim2.new(0,0,1,0)
&#9;widgetContainer.BorderColor3 = Color3.new(0,0,0)
&#9;if not scrollable then
&#9;&#9;widgetContainer.BackgroundTransparency = 0
&#9;&#9;widgetContainer.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
&#9;end
&#9;if size then
&#9;&#9;if scrollable then
&#9;&#9;&#9;widgetContainer.Size = size
&#9;&#9;else
&#9;&#9;&#9;widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,size.Y.Scale,size.Y.Offset)
&#9;&#9;end
&#9;else
&#9;&#9;if scrollable then
&#9;&#9;&#9;widgetContainer.Size = UDim2.new(0,163,0,400)
&#9;&#9;else
&#9;&#9;&#9;widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,0,400)
&#9;&#9;end
&#9;end
&#9;if position then
&#9;&#9;widgetContainer.Position = position + UDim2.new(0,0,0,20)
&#9;end
&#9;local frame,control,verticalDragger = nil
&#9;if scrollable then
&#9;&#9;--frame for widgets
&#9;&#9;frame,control = t.CreateTrueScrollingFrame()
&#9;&#9;frame.Size = UDim2.new(1, 0, 1, 0)
&#9;&#9;frame.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
&#9;&#9;frame.BorderColor3 = Color3.new(0,0,0)
&#9;&#9;frame.Active = true
&#9;&#9;frame.Parent = widgetContainer
&#9;&#9;control.Parent = dragBar
&#9;&#9;control.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
&#9;&#9;control.BorderSizePixel = 0
&#9;&#9;control.BackgroundTransparency = 0
&#9;&#9;control.Position = UDim2.new(1,-21,1,1)
&#9;&#9;if size then
&#9;&#9;&#9;control.Size = UDim2.new(0,21,size.Y.Scale,size.Y.Offset)
&#9;&#9;else
&#9;&#9;&#9;control.Size = UDim2.new(0,21,0,400)
&#9;&#9;end
&#9;&#9;control:FindFirstChild(&quot;ScrollDownButton&quot;).Position = UDim2.new(0,0,1,-20)
&#9;&#9;local fakeLine = Instance.new(&quot;Frame&quot;,control)
&#9;&#9;fakeLine.Name = &quot;FakeLine&quot;
&#9;&#9;fakeLine.BorderSizePixel = 0
&#9;&#9;fakeLine.BackgroundColor3 = Color3.new(0,0,0)
&#9;&#9;fakeLine.Size = UDim2.new(0,1,1,1)
&#9;&#9;fakeLine.Position = UDim2.new(1,0,0,0)
&#9;&#9;verticalDragger = Instance.new(&quot;TextButton&quot;,widgetContainer)
&#9;&#9;verticalDragger.ZIndex = 2
&#9;&#9;verticalDragger.AutoButtonColor = false
&#9;&#9;verticalDragger.Name = &quot;VerticalDragger&quot;
&#9;&#9;verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255)
&#9;&#9;verticalDragger.BorderColor3 = Color3.new(0,0,0)
&#9;&#9;verticalDragger.Size = UDim2.new(1,20,0,20)
&#9;&#9;verticalDragger.Position = UDim2.new(0,0,1,0)
&#9;&#9;verticalDragger.Active = true
&#9;&#9;verticalDragger.Text = &quot;&quot;
&#9;&#9;local scrubFrame = Instance.new(&quot;Frame&quot;,verticalDragger)
&#9;&#9;scrubFrame.Name = &quot;ScrubFrame&quot;
&#9;&#9;scrubFrame.BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;scrubFrame.BorderSizePixel = 0
&#9;&#9;scrubFrame.Position = UDim2.new(0.5,-5,0.5,0)
&#9;&#9;scrubFrame.Size = UDim2.new(0,10,0,1)
&#9;&#9;scrubFrame.ZIndex = 5
&#9;&#9;local scrubTwo = scrubFrame:clone()
&#9;&#9;scrubTwo.Position = UDim2.new(0.5,-5,0.5,-2)
&#9;&#9;scrubTwo.Parent = verticalDragger
&#9;&#9;local scrubThree = scrubFrame:clone()
&#9;&#9;scrubThree.Position = UDim2.new(0.5,-5,0.5,2)
&#9;&#9;scrubThree.Parent = verticalDragger
&#9;&#9;local areaSoak = Instance.new(&quot;TextButton&quot;,getScreenGuiAncestor(parent))
&#9;&#9;areaSoak.Name = &quot;AreaSoak&quot;
&#9;&#9;areaSoak.Size = UDim2.new(1,0,1,0)
&#9;&#9;areaSoak.BackgroundTransparency = 1
&#9;&#9;areaSoak.BorderSizePixel = 0
&#9;&#9;areaSoak.Text = &quot;&quot;
&#9;&#9;areaSoak.ZIndex = 10
&#9;&#9;areaSoak.Visible = false
&#9;&#9;areaSoak.Active = true
&#9;&#9;local draggingVertical = false
&#9;&#9;local startYPos = nil
&#9;&#9;verticalDragger.MouseEnter:connect(function ()
&#9;&#9;&#9;verticalDragger.BackgroundColor3 = Color3.new(60/255,60/255,60/255)
&#9;&#9;end)
&#9;&#9;verticalDragger.MouseLeave:connect(function ()
&#9;&#9;&#9;verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255)
&#9;&#9;end)
&#9;&#9;verticalDragger.MouseButton1Down:connect(function(x,y)
&#9;&#9;&#9;draggingVertical = true
&#9;&#9;&#9;areaSoak.Visible = true
&#9;&#9;&#9;startYPos = y
&#9;&#9;end)
&#9;&#9;areaSoak.MouseButton1Up:connect(function ( )
&#9;&#9;&#9;draggingVertical = false
&#9;&#9;&#9;areaSoak.Visible = false
&#9;&#9;end)
&#9;&#9;areaSoak.MouseMoved:connect(function(x,y)
&#9;&#9;&#9;if not draggingVertical then return end
&#9;&#9;&#9;local yDelta = y - startYPos
&#9;&#9;&#9;if not control.ScrollDownButton.Visible and yDelta &gt; 0 then
&#9;&#9;&#9;&#9;return
&#9;&#9;&#9;end
&#9;&#9;&#9;if (widgetContainer.Size.Y.Offset + yDelta) &lt; 150 then
&#9;&#9;&#9;&#9;widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,150)
&#9;&#9;&#9;&#9;control.Size = UDim2.new (0,21,0,150)
&#9;&#9;&#9;&#9;return
&#9;&#9;&#9;end
&#9;&#9;&#9;startYPos = y
&#9;&#9;&#9;if widgetContainer.Size.Y.Offset + yDelta &gt;= 0 then
&#9;&#9;&#9;&#9;widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,widgetContainer.Size.Y.Offset + yDelta)
&#9;&#9;&#9;&#9;control.Size = UDim2.new(0,21,0,control.Size.Y.Offset + yDelta )
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;end
&#9;local function switchMinimize()
&#9;&#9;minimizeFrame.Visible = not minimizeFrame.Visible
&#9;&#9;if scrollable then
&#9;&#9;&#9;frame.Visible = not frame.Visible
&#9;&#9;&#9;verticalDragger.Visible = not verticalDragger.Visible
&#9;&#9;&#9;control.Visible = not control.Visible
&#9;&#9;else
&#9;&#9;&#9;widgetContainer.Visible = not widgetContainer.Visible
&#9;&#9;end
&#9;&#9;if minimizeFrame.Visible then
&#9;&#9;&#9;minimizeButton.Text = &quot;+&quot;
&#9;&#9;else
&#9;&#9;&#9;minimizeButton.Text = &quot;-&quot;
&#9;&#9;end
&#9;end
&#9;minimizeBigButton.MouseButton1Click:connect(function ( )
&#9;&#9;switchMinimize()
&#9;end)
&#9;minimizeButton.MouseButton1Click:connect(function( )
&#9;&#9;switchMinimize()
&#9;end)
&#9;if scrollable then
&#9;&#9;return dragBar, frame, helpFrame, closeEvent
&#9;else
&#9;&#9;return dragBar, widgetContainer, helpFrame, closeEvent
&#9;end
end
t.Help =
&#9;function(funcNameOrFunc)
&#9;&#9;--input argument can be a string or a function. Should return a description (of arguments and expected side effects)
&#9;&#9;if funcNameOrFunc == &quot;CreatePropertyDropDownMenu&quot; or funcNameOrFunc == t.CreatePropertyDropDownMenu then
&#9;&#9;&#9;return &quot;Function CreatePropertyDropDownMenu. &quot; ..
&#9;&#9;&#9;&#9; &quot;Arguments: (instance, propertyName, enumType). &quot; ..
&#9;&#9;&#9;&#9; &quot;Side effect: returns a container with a drop-down-box that is linked to the &apos;property&apos; field of &apos;instance&apos; which is of type &apos;enumType&apos;&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateDropDownMenu&quot; or funcNameOrFunc == t.CreateDropDownMenu then
&#9;&#9;&#9;return &quot;Function CreateDropDownMenu. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (items, onItemSelected). &quot; ..
&#9;&#9;&#9;&#9; &quot;Side effect: Returns 2 results, a container to the gui object and a &apos;updateSelection&apos; function for external updating. The container is a drop-down-box created around a list of items&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateMessageDialog&quot; or funcNameOrFunc == t.CreateMessageDialog then
&#9;&#9;&#9;return &quot;Function CreateMessageDialog. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (title, message, buttons). &quot; ..
&#9;&#9;&#9; &quot;Side effect: Returns a gui object of a message box with &apos;title&apos; and &apos;message&apos; as passed in. &apos;buttons&apos; input is an array of Tables contains a &apos;Text&apos; and &apos;Function&apos; field for the text/callback of each button&quot;
&#9;&#9;end&#9;&#9;
&#9;&#9;if funcNameOrFunc == &quot;CreateStyledMessageDialog&quot; or funcNameOrFunc == t.CreateStyledMessageDialog then
&#9;&#9;&#9;return &quot;Function CreateStyledMessageDialog. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (title, message, style, buttons). &quot; ..
&#9;&#9;&#9; &quot;Side effect: Returns a gui object of a message box with &apos;title&apos; and &apos;message&apos; as passed in. &apos;buttons&apos; input is an array of Tables contains a &apos;Text&apos; and &apos;Function&apos; field for the text/callback of each button, &apos;style&apos; is a string, either Error, Notify or Confirm&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;GetFontHeight&quot; or funcNameOrFunc == t.GetFontHeight then
&#9;&#9;&#9;return &quot;Function GetFontHeight. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (font, fontSize). &quot; ..
&#9;&#9;&#9; &quot;Side effect: returns the size in pixels of the given font + fontSize&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;LayoutGuiObjects&quot; or funcNameOrFunc == t.LayoutGuiObjects then
&#9;&#9;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateScrollingFrame&quot; or funcNameOrFunc == t.CreateScrollingFrame then
&#9;&#9;&#9;return &quot;Function CreateScrollingFrame. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (orderList, style) &quot; ..
&#9;&#9;&#9; &quot;Side effect: returns 4 objects, (scrollFrame, scrollUpButton, scrollDownButton, recalculateFunction). &apos;scrollFrame&apos; 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 &apos;grid&apos; styling if style is passed &apos;grid&apos; as a string. recalculateFunction can be called when a relayout is needed (when orderList changes)&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateTrueScrollingFrame&quot; or funcNameOrFunc == t.CreateTrueScrollingFrame then
&#9;&#9;&#9;return &quot;Function CreateTrueScrollingFrame. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (nil) &quot; ..
&#9;&#9;&#9; &quot;Side effect: returns 2 objects, (scrollFrame, controlFrame). &apos;scrollFrame&apos; can be filled with GuiObjects, and they will be clipped if not inside the frame&apos;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.&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;AutoTruncateTextObject&quot; or funcNameOrFunc == t.AutoTruncateTextObject then
&#9;&#9;&#9;return &quot;Function AutoTruncateTextObject. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (textLabel) &quot; ..
&#9;&#9;&#9; &quot;Side effect: returns 2 objects, (textLabel, changeText). The &apos;textLabel&apos; input is modified to automatically truncate text (with ellipsis), if it gets too small to fit. &apos;changeText&apos; is a function that can be used to change the text, it takes 1 string as an argument&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateSlider&quot; or funcNameOrFunc == t.CreateSlider then
&#9;&#9;&#9;return &quot;Function CreateSlider. &quot; ..
&#9;&#9;&#9;&#9;&quot;Arguments: (steps, width, position) &quot; ..
&#9;&#9;&#9;&#9;&quot;Side effect: returns 2 objects, (sliderGui, sliderPosition). The &apos;steps&apos; argument specifies how many different positions the slider can hold along the bar. &apos;width&apos; specifies in pixels how wide the bar should be (modifiable afterwards if desired). &apos;position&apos; argument should be a UDim2 for slider positioning. &apos;sliderPosition&apos; is an IntValue whose current .Value specifies the specific step the slider is currently on.&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateSliderNew&quot; or funcNameOrFunc == t.CreateSliderNew then
&#9;&#9;&#9;return &quot;Function CreateSliderNew. &quot; ..
&#9;&#9;&#9;&#9;&quot;Arguments: (steps, width, position) &quot; ..
&#9;&#9;&#9;&#9;&quot;Side effect: returns 2 objects, (sliderGui, sliderPosition). The &apos;steps&apos; argument specifies how many different positions the slider can hold along the bar. &apos;width&apos; specifies in pixels how wide the bar should be (modifiable afterwards if desired). &apos;position&apos; argument should be a UDim2 for slider positioning. &apos;sliderPosition&apos; is an IntValue whose current .Value specifies the specific step the slider is currently on.&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateLoadingFrame&quot; or funcNameOrFunc == t.CreateLoadingFrame then
&#9;&#9;&#9;return &quot;Function CreateLoadingFrame. &quot; ..
&#9;&#9;&#9;&#9;&quot;Arguments: (name, size, position) &quot; ..
&#9;&#9;&#9;&#9;&quot;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.&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateTerrainMaterialSelector&quot; or funcNameOrFunc == t.CreateTerrainMaterialSelector then
&#9;&#9;&#9;return &quot;Function CreateTerrainMaterialSelector. &quot; ..
&#9;&#9;&#9;&#9;&quot;Arguments: (size, position) &quot; ..
&#9;&#9;&#9;&#9;&quot;Side effect: Size and position are UDim2 values that specifies the selector&apos;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.&quot;
&#9;&#9;end
&#9;end
&#9;
-- A couple of necessary functions
local function waitForChild(instance, name)
&#9;assert(instance)
&#9;assert(name)
&#9;while not instance:FindFirstChild(name) do
&#9;&#9;instance.ChildAdded:wait()
&#9;end
&#9;return instance:FindFirstChild(name)
end
local function waitForProperty(instance, property)
&#9;assert(instance)
&#9;assert(property)
&#9;while not instance[property] do
&#9;&#9;instance.Changed:wait()
&#9;end
end
local function IsTouchDevice()
&#9;--return Game:GetService(&apos;UserInputService&apos;).TouchEnabled
end
waitForChild(game,&quot;Players&quot;)
waitForProperty(game.Players,&quot;LocalPlayer&quot;)
local player = game.Players.LocalPlayer
local RbxGui, msg = t
if not RbxGui then print(&quot;could not find RbxGui!&quot;) return end
--- Begin Locals
local StaticTabName = &quot;gear&quot;
local backpack = script.Parent.Backpack
local screen = script.Parent
local backpackItems = {}
local buttons = {}
local debounce = false
local browsingMenu = false
local mouseEnterCons = {}
local mouseClickCons = {}
local characterChildAddedCon = nil
local characterChildRemovedCon = nil
local backpackAddCon = nil
local playerBackpack = waitForChild(player,&quot;Backpack&quot;)
waitForChild(backpack,&quot;Gear&quot;)
local gearPreview = waitForChild(backpack.Gear,&quot;GearPreview&quot;)
local scroller = waitForChild(backpack.Gear,&quot;GearGridScrollingArea&quot;)
local currentLoadout = waitForChild(backpack.Parent,&quot;CurrentLoadout&quot;)
local grid = waitForChild(backpack.Gear,&quot;GearGrid&quot;)
local gearButton = waitForChild(grid,&quot;GearButton&quot;)
local swapSlot = waitForChild(script.Parent,&quot;SwapSlot&quot;)
local backpackManager = waitForChild(script.Parent,&quot;CoreScripts/BackpackScripts/BackpackManager&quot;)
local backpackOpenEvent = waitForChild(backpackManager,&quot;BackpackOpenEvent&quot;)
local backpackCloseEvent = waitForChild(backpackManager,&quot;BackpackCloseEvent&quot;)
local tabClickedEvent = waitForChild(backpackManager,&quot;TabClickedEvent&quot;)
local resizeEvent = waitForChild(backpackManager,&quot;ResizeEvent&quot;)
local searchRequestedEvent = waitForChild(backpackManager,&quot;SearchRequestedEvent&quot;)
local tellBackpackReadyFunc = waitForChild(backpackManager,&quot;BackpackReady&quot;)
-- creating scroll bar early as to make sure items get placed correctly
local scrollFrame, scrollUp, scrollDown, recalculateScroll = RbxGui.CreateScrollingFrame(nil, &quot;grid&quot;, Vector2.new(6, 6))
scrollFrame.Position = UDim2.new(0,0,0,30)
scrollFrame.Size = UDim2.new(1,0,1,-30)
scrollFrame.Parent = backpack.Gear.GearGrid
local scrollBar = Instance.new(&quot;Frame&quot;)
scrollBar.Name = &quot;ScrollBar&quot;
scrollBar.BackgroundTransparency = 0.9
scrollBar.BackgroundColor3 = Color3.new(1,1,1)
scrollBar.BorderSizePixel = 0
scrollBar.Size = UDim2.new(0, 17, 1, -36)
scrollBar.Position = UDim2.new(0,0,0,18)
scrollBar.Parent = scroller
scrollDown.Position = UDim2.new(0,0,1,-17)
scrollUp.Parent = scroller
scrollDown.Parent = scroller
local scrollFrameLoadout, scrollUpLoadout, scrollDownLoadout, recalculateScrollLoadout = RbxGui.CreateScrollingFrame()
scrollFrameLoadout.Position = UDim2.new(0,0,0,0)
scrollFrameLoadout.Size = UDim2.new(1,0,1,0)
scrollFrameLoadout.Parent = backpack.Gear.GearLoadouts.LoadoutsList
local LoadoutButton = Instance.new(&quot;TextButton&quot;)
LoadoutButton.Name = &quot;LoadoutButton&quot;
LoadoutButton.Font = Enum.Font.ArialBold
LoadoutButton.FontSize = Enum.FontSize.Size14
LoadoutButton.Position = UDim2.new(0,0,0,0)
LoadoutButton.Size = UDim2.new(1,0,0,32)
LoadoutButton.Style = Enum.ButtonStyle.RobloxButton
LoadoutButton.Text = &quot;Loadout #1&quot;
LoadoutButton.TextColor3 = Color3.new(1,1,1)
LoadoutButton.Parent = scrollFrameLoadout
local LoadoutButtonTwo = LoadoutButton:clone()
LoadoutButtonTwo.Text = &quot;Loadout #2&quot;
LoadoutButtonTwo.Parent = scrollFrameLoadout
local LoadoutButtonThree = LoadoutButton:clone()
LoadoutButtonThree.Text = &quot;Loadout #3&quot;
LoadoutButtonThree.Parent = scrollFrameLoadout
local LoadoutButtonFour = LoadoutButton:clone()
LoadoutButtonFour.Text = &quot;Loadout #4&quot;
LoadoutButtonFour.Parent = scrollFrameLoadout
local scrollBarLoadout = Instance.new(&quot;Frame&quot;)
scrollBarLoadout.Name = &quot;ScrollBarLoadout&quot;
scrollBarLoadout.BackgroundTransparency = 0.9
scrollBarLoadout.BackgroundColor3 = Color3.new(1,1,1)
scrollBarLoadout.BorderSizePixel = 0
scrollBarLoadout.Size = UDim2.new(0, 17, 1, -36)
scrollBarLoadout.Position = UDim2.new(0,0,0,18)
scrollBarLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea
scrollDownLoadout.Position = UDim2.new(0,0,1,-17)
scrollUpLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea
scrollDownLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea
-- Begin Functions
function removeFromMap(map,object)
&#9;for i = 1, #map do
&#9;&#9;if map[i] == object then
&#9;&#9;&#9;table.remove(map,i)
&#9;&#9;&#9;break
&#9;&#9;end
&#9;end
end
function robloxLock(instance)
end
function resize()
&#9;local size = 0
&#9;if gearPreview.AbsoluteSize.Y &gt; gearPreview.AbsoluteSize.X then
&#9;&#9;size = gearPreview.AbsoluteSize.X * 0.75
&#9;else
&#9;&#9;size = gearPreview.AbsoluteSize.Y * 0.75
&#9;end
&#9;waitForChild(gearPreview,&quot;GearImage&quot;)
&#9;gearPreview.GearImage.Size = UDim2.new(0,size,0,size)
&#9;gearPreview.GearImage.Position = UDim2.new(0,gearPreview.AbsoluteSize.X/2 - size/2,0.75,-size)
&#9;
&#9;resizeGrid()
end
function addToGrid(child)
&#9;if not child:IsA(&quot;Tool&quot;) then
&#9;&#9;if not child:IsA(&quot;HopperBin&quot;) then
&#9;&#9;&#9;return
&#9;&#9;end
&#9;end
&#9;if child:FindFirstChild(&quot;RobloxBuildTool&quot;) then return end
&#9;
&#9;for i,v in pairs(backpackItems) do -- check to see if we already have this gear registered
&#9;&#9;if v == child then return end
&#9;end
&#9;table.insert(backpackItems,child)
&#9;
&#9;local changeCon = child.Changed:connect(function(prop)
&#9;&#9;if prop == &quot;Name&quot; then
&#9;&#9;&#9;if buttons[child] then
&#9;&#9;&#9;&#9;if buttons[child].Image == &quot;&quot; then
&#9;&#9;&#9;&#9;&#9;buttons[child].GearText.Text = child.Name
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end)
&#9;local ancestryCon = nil
&#9;ancestryCon = child.AncestryChanged:connect(function(theChild,theParent)
&#9;&#9;local thisObject = nil
&#9;&#9;for k,v in pairs(backpackItems) do
&#9;&#9;&#9;if v == child then
&#9;&#9;&#9;&#9;thisObject = v
&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;
&#9;&#9;waitForProperty(player,&quot;Character&quot;)
&#9;&#9;waitForChild(player,&quot;Backpack&quot;)
&#9;&#9;if (child.Parent ~= player.Backpack and child.Parent ~= player.Character) then
&#9;&#9;&#9;if ancestryCon then ancestryCon:disconnect() end
&#9;&#9;&#9;if changeCon then changeCon:disconnect() end
&#9;&#9;&#9;
&#9;&#9;&#9;for k,v in pairs(backpackItems) do
&#9;&#9;&#9;&#9;if v == thisObject then
&#9;&#9;&#9;&#9;&#9;if mouseEnterCons[buttons[v]] then mouseEnterCons[buttons[v]]:disconnect() end
&#9;&#9;&#9;&#9;&#9;if mouseClickCons[buttons[v]] then mouseClickCons[buttons[v]]:disconnect() end
&#9;&#9;&#9;&#9;&#9;buttons[v].Parent = nil
&#9;&#9;&#9;&#9;&#9;buttons[v] = nil
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;removeFromMap(backpackItems,thisObject)
&#9;&#9;&#9;
&#9;&#9;&#9;resizeGrid()
&#9;&#9;else
&#9;&#9;&#9;resizeGrid()
&#9;&#9;end
&#9;&#9;updateGridActive()
&#9;end)
&#9;resizeGrid()
end
function buttonClick(button)
&#9;if button:FindFirstChild(&quot;UnequipContextMenu&quot;) and not button.Active then
&#9;&#9;button.UnequipContextMenu.Visible = true
&#9;&#9;browsingMenu = true
&#9;end
end
function previewGear(button)
&#9;if not browsingMenu then
&#9;&#9;gearPreview.Visible = false
&#9;&#9;gearPreview.GearImage.Image = button.Image
&#9;&#9;gearPreview.GearStats.GearName.Text = button.GearReference.Value.Name
&#9;end
end
function findEmptySlot()
&#9;local smallestNum = nil
&#9;local loadout = currentLoadout:GetChildren()
&#9;for i = 1, #loadout do
&#9;&#9;if loadout[i]:IsA(&quot;Frame&quot;) and #loadout[i]:GetChildren() &lt;= 0 then
&#9;&#9;&#9;local frameNum = tonumber(string.sub(loadout[i].Name,5))
&#9;&#9;&#9;if frameNum == 0 then frameNum = 10 end
&#9;&#9;&#9;if not smallestNum or (smallestNum &gt; frameNum) then
&#9;&#9;&#9;&#9;smallestNum = frameNum
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;if smallestNum == 10 then smallestNum = 0 end
&#9;return smallestNum
end
function checkForSwap(button,x,y)
&#9;local loadoutChildren = currentLoadout:GetChildren()
&#9;for i = 1, #loadoutChildren do
&#9;&#9;if loadoutChildren[i]:IsA(&quot;Frame&quot;) and string.find(loadoutChildren[i].Name,&quot;Slot&quot;) then
&#9;&#9;&#9;if x &gt;= loadoutChildren[i].AbsolutePosition.x and x &lt;= (loadoutChildren[i].AbsolutePosition.x + loadoutChildren[i].AbsoluteSize.x) then
&#9;&#9;&#9;&#9;if y &gt;= loadoutChildren[i].AbsolutePosition.y and y &lt;= (loadoutChildren[i].AbsolutePosition.y + loadoutChildren[i].AbsoluteSize.y) then
&#9;&#9;&#9;&#9;&#9;local slot = tonumber(string.sub(loadoutChildren[i].Name,5))
&#9;&#9;&#9;&#9;&#9;swapGearSlot(slot,button)
&#9;&#9;&#9;&#9;&#9;return true
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;return false
end
function resizeGrid()
&#9;for k,v in pairs(backpackItems) do
&#9;&#9;if not v:FindFirstChild(&quot;RobloxBuildTool&quot;) then
&#9;&#9;&#9;if not buttons[v] then
&#9;&#9;&#9;&#9;local buttonClone = gearButton:clone()
&#9;&#9;&#9;&#9;buttonClone.Parent = grid.ScrollingFrame
&#9;&#9;&#9;&#9;buttonClone.Visible = true
&#9;&#9;&#9;&#9;buttonClone.Image = v.TextureId
&#9;&#9;&#9;&#9;if buttonClone.Image == &quot;&quot; then
&#9;&#9;&#9;&#9;&#9;buttonClone.GearText.Text = v.Name
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;buttonClone.GearReference.Value = v
&#9;&#9;&#9;&#9;buttonClone.Draggable = true
&#9;&#9;&#9;&#9;buttons[v] = buttonClone
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;if not IsTouchDevice() then
&#9;&#9;&#9;&#9;&#9;local unequipMenu = getGearContextMenu()
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;unequipMenu.Visible = false
&#9;&#9;&#9;&#9;&#9;unequipMenu.Parent = buttonClone
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local beginPos = nil
&#9;&#9;&#9;&#9;buttonClone.DragBegin:connect(function(value)
&#9;&#9;&#9;&#9;&#9;waitForChild(buttonClone, &apos;Background&apos;)&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;buttonClone[&apos;Background&apos;].ZIndex = 10
&#9;&#9;&#9;&#9;&#9;buttonClone.ZIndex = 10&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;beginPos = value
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;&#9;buttonClone.DragStopped:connect(function(x,y)
&#9;&#9;&#9;&#9;&#9;waitForChild(buttonClone, &apos;Background&apos;)
&#9;&#9;&#9;&#9;&#9;buttonClone[&apos;Background&apos;].ZIndex = 1.0
&#9;&#9;&#9;&#9;&#9;buttonClone.ZIndex = 2&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;if beginPos ~= buttonClone.Position then
&#9;&#9;&#9;&#9;&#9;&#9;if not checkForSwap(buttonClone,x,y) then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;buttonClone:TweenPosition(beginPos,Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.5, true)
&#9;&#9;&#9;&#9;&#9;&#9;&#9;buttonClone.Draggable = false
&#9;&#9;&#9;&#9;&#9;&#9;&#9;delay(0.5,function()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;buttonClone.Draggable = true
&#9;&#9;&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;&#9;buttonClone.Position = beginPos
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;end&#9;
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;&#9;local clickTime = tick()
&#9;&#9;&#9;&#9;mouseEnterCons[buttonClone] = buttonClone.MouseEnter:connect(function() previewGear(buttonClone) end)
&#9;&#9;&#9;&#9;mouseClickCons[buttonClone] = buttonClone.MouseButton1Click:connect(function()
&#9;&#9;&#9;&#9;&#9;local newClickTime = tick()
&#9;&#9;&#9;&#9;&#9;if buttonClone.Active and (newClickTime - clickTime) &lt; 0.5 then
&#9;&#9;&#9;&#9;&#9;&#9;local slot = findEmptySlot()
&#9;&#9;&#9;&#9;&#9;&#9;if slot then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;buttonClone.ZIndex = 1
&#9;&#9;&#9;&#9;&#9;&#9;&#9;swapGearSlot(slot,buttonClone)
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;buttonClick(buttonClone)
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;clickTime = newClickTime
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;recalculateScroll()
end
function showPartialGrid(subset)
&#9;for k,v in pairs(buttons) do
&#9;&#9;v.Parent = nil
&#9;end
&#9;if subset then
&#9;&#9;for k,v in pairs(subset) do
&#9;&#9;&#9;v.Parent = grid.ScrollingFrame
&#9;&#9;end
&#9;end
&#9;recalculateScroll()
end
function showEntireGrid()
&#9;for k,v in pairs(buttons) do
&#9;&#9;v.Parent = grid.ScrollingFrame
&#9;end
&#9;recalculateScroll()
end
function inLoadout(gear)
&#9;local children = currentLoadout:GetChildren()
&#9;for i = 1, #children do
&#9;&#9;if children[i]:IsA(&quot;Frame&quot;) then
&#9;&#9;&#9;local button = children[i]:GetChildren()
&#9;&#9;&#9;if #button &gt; 0 then
&#9;&#9;&#9;&#9;if button[1].GearReference.Value and button[1].GearReference.Value == gear then
&#9;&#9;&#9;&#9;&#9;return true
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;return false
end&#9;
function updateGridActive()
&#9;for k,v in pairs(backpackItems) do
&#9;&#9;if buttons[v] then
&#9;&#9;&#9;local gear = nil
&#9;&#9;&#9;local gearRef = buttons[v]:FindFirstChild(&quot;GearReference&quot;)
&#9;&#9;&#9;
&#9;&#9;&#9;if gearRef then gear = gearRef.Value end
&#9;&#9;&#9;
&#9;&#9;&#9;if not gear then
&#9;&#9;&#9;&#9;buttons[v].Active = false
&#9;&#9;&#9;elseif inLoadout(gear) then
&#9;&#9;&#9;&#9;buttons[v].Active = false
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;buttons[v].Active = true
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
end
function centerGear(loadoutChildren)
&#9;local gearButtons = {}
&#9;local lastSlotAdd = nil
&#9;for i = 1, #loadoutChildren do
&#9;&#9;if loadoutChildren[i]:IsA(&quot;Frame&quot;) and #loadoutChildren[i]:GetChildren() &gt; 0 then
&#9;&#9;&#9;if loadoutChildren[i].Name == &quot;Slot0&quot; then
&#9;&#9;&#9;&#9;lastSlotAdd = loadoutChildren[i]
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;table.insert(gearButtons, loadoutChildren[i])
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;if lastSlotAdd then table.insert(gearButtons,lastSlotAdd) end
&#9;
&#9;local startPos = ( 1 - (#gearButtons * 0.1) ) / 2
&#9;for i = 1, #gearButtons do&#9;
&#9;&#9;gearButtons[i]:TweenPosition(UDim2.new(startPos + ((i - 1) * 0.1),0,0,0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.25, true)
&#9;end
end
function tabClickHandler(tabName)
&#9;if tabName == StaticTabName then
&#9;&#9;backpackOpenHandler(tabName)
&#9;else
&#9;&#9;backpackCloseHandler(tabName)
&#9;end
end
function backpackOpenHandler(currentTab)
&#9;if currentTab and currentTab ~= StaticTabName then
&#9;&#9;backpack.Gear.Visible = false
&#9;&#9;return
&#9;end
&#9;
&#9;backpack.Gear.Visible = true
&#9;updateGridActive()
&#9;resizeGrid()
&#9;resize()
&#9;tellBackpackReadyFunc:Invoke()
end
function backpackCloseHandler(currentTab)
&#9;if currentTab and currentTab ~= StaticTabName then
&#9;&#9;backpack.Gear.Visible = false
&#9;&#9;return
&#9;end
&#9;
&#9;backpack.Gear.Visible = false
&#9;resizeGrid()
&#9;resize()
&#9;tellBackpackReadyFunc:Invoke()
end
function loadoutCheck(child, selectState)
&#9;if not child:IsA(&quot;ImageButton&quot;) then return end
&#9;for k,v in pairs(backpackItems) do
&#9;&#9;if buttons[v] then
&#9;&#9;&#9;if child:FindFirstChild(&quot;GearReference&quot;) and buttons[v]:FindFirstChild(&quot;GearReference&quot;) then
&#9;&#9;&#9;&#9;if buttons[v].GearReference.Value == child.GearReference.Value then
&#9;&#9;&#9;&#9;&#9;buttons[v].Active = selectState
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
end
function clearPreview()
&#9;gearPreview.GearImage.Image = &quot;&quot;
&#9;gearPreview.GearStats.GearName.Text = &quot;&quot;
end
function removeAllEquippedGear(physGear)
&#9;local stuff = player.Character:GetChildren()
&#9;for i = 1, #stuff do
&#9;&#9;if ( stuff[i]:IsA(&quot;Tool&quot;) or stuff[i]:IsA(&quot;HopperBin&quot;) ) and stuff[i] ~= physGear then
&#9;&#9;&#9;stuff[i].Parent = playerBackpack
&#9;&#9;end
&#9;end
end
function equipGear(physGear)
&#9;removeAllEquippedGear(physGear)
&#9;physGear.Parent = player.Character
&#9;updateGridActive()
end
function unequipGear(physGear)
&#9;physGear.Parent = playerBackpack
&#9;updateGridActive()
end
function highlight(button)
&#9;button.TextColor3 = Color3.new(0,0,0)
&#9;button.BackgroundColor3 = Color3.new(0.8,0.8,0.8)
end
function clearHighlight(button)
&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;button.BackgroundColor3 = Color3.new(0,0,0)
end
function swapGearSlot(slot,gearButton)
&#9;if not swapSlot.Value then -- signal loadout to swap a gear out
&#9;&#9;swapSlot.Slot.Value = slot
&#9;&#9;swapSlot.GearButton.Value = gearButton
&#9;&#9;swapSlot.Value = true
&#9;&#9;updateGridActive()
&#9;end
end
local UnequipGearMenuClick = function(element, menu)
&#9;if type(element.Action) ~= &quot;number&quot; then return end
&#9;local num = element.Action
&#9;if num == 1 then -- remove from loadout
&#9;&#9;unequipGear(menu.Parent.GearReference.Value)
&#9;&#9;local inventoryButton = menu.Parent
&#9;&#9;local gearToUnequip = inventoryButton.GearReference.Value
&#9;&#9;local loadoutChildren = currentLoadout:GetChildren()
&#9;&#9;local slot = -1
&#9;&#9;for i = 1, #loadoutChildren do
&#9;&#9;&#9;if loadoutChildren[i]:IsA(&quot;Frame&quot;) then
&#9;&#9;&#9;&#9;local button = loadoutChildren[i]:GetChildren()
&#9;&#9;&#9;&#9;if button[1] and button[1].GearReference.Value == gearToUnequip then
&#9;&#9;&#9;&#9;&#9;slot = button[1].SlotNumber.Text
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;swapGearSlot(slot,nil)
&#9;end
end
function setupCharacterConnections()
&#9;if backpackAddCon then backpackAddCon:disconnect() end
&#9;backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded:connect(function(child) addToGrid(child) end)
&#9;
&#9;-- make sure we get all the children
&#9;local backpackChildren = game.Players.LocalPlayer.Backpack:GetChildren()
&#9;for i = 1, #backpackChildren do
&#9;&#9;addToGrid(backpackChildren[i])
&#9;end
&#9;if characterChildAddedCon then characterChildAddedCon:disconnect() end
&#9;characterChildAddedCon =
&#9;&#9;game.Players.LocalPlayer.Character.ChildAdded:connect(function(child)
&#9;&#9;&#9;addToGrid(child)
&#9;&#9;&#9;updateGridActive()
&#9;&#9;end)
&#9;&#9;
&#9;if characterChildRemovedCon then characterChildRemovedCon:disconnect() end
&#9;characterChildRemovedCon =
&#9;&#9;game.Players.LocalPlayer.Character.ChildRemoved:connect(function(child)
&#9;&#9;&#9;updateGridActive()
&#9;&#9;end)
&#9;wait()
&#9;centerGear(currentLoadout:GetChildren())
end
function removeCharacterConnections()
&#9;if characterChildAddedCon then characterChildAddedCon:disconnect() end
&#9;if characterChildRemovedCon then characterChildRemovedCon:disconnect() end
&#9;if backpackAddCon then backpackAddCon:disconnect() end
end
function trim(s)
return (s:gsub(&quot;^%s*(.-)%s*$&quot;, &quot;%1&quot;))
end
function filterGear(terms)
&#9;local filteredGear = {}
&#9;for k,v in pairs(backpackItems) do
&#9;&#9;if buttons[v] then
&#9;&#9;&#9;local gearString = string.lower(buttons[v].GearReference.Value.Name)
&#9;&#9;&#9;gearString = trim(gearString)
&#9;&#9;&#9;for i = 1, #terms do
&#9;&#9;&#9;&#9;if string.match(gearString,terms[i]) then
&#9;&#9;&#9;&#9;&#9;table.insert(filteredGear,buttons[v])
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;
&#9;return filteredGear
end
function splitByWhitespace(text)
&#9;if type(text) ~= &quot;string&quot; then return nil end
&#9;
&#9;local terms = {}
&#9;for token in string.gmatch(text, &quot;[^%s]+&quot;) do
&#9; if string.len(token) &gt; 0 then
&#9;&#9;&#9;table.insert(terms,token)
&#9; end
&#9;end
&#9;return terms
end
function showSearchGear(searchTerms)
&#9;if not backpack.Gear.Visible then return end -- currently not active tab
&#9;local searchTermTable = splitByWhitespace(searchTerms)
&#9;if searchTermTable and (#searchTermTable &gt; 0) then
&#9;&#9;currSearchTerms = searchTermTable
&#9;else
&#9;&#9;currSearchTerms = nil
&#9;end
&#9;if searchTermTable == nil then
&#9;&#9;showEntireGrid()
&#9;&#9;return
&#9;end
&#9;local filteredButtons = filterGear(currSearchTerms)
&#9;showPartialGrid(filteredButtons)
end
function nukeBackpack()
&#9;while #buttons &gt; 0 do
&#9;&#9;table.remove(buttons)
&#9;end
&#9;buttons = {}
&#9;while #backpackItems &gt; 0 do
&#9;&#9;table.remove(backpackItems)
&#9;end
&#9;backpackItems = {}
&#9;local scrollingFrameChildren = grid.ScrollingFrame:GetChildren()
&#9;for i = 1, #scrollingFrameChildren do
&#9;&#9;scrollingFrameChildren[i]:remove()
&#9;end
end
function getGearContextMenu()&#9;
&#9;local gearContextMenu = Instance.new(&quot;Frame&quot;)
&#9;gearContextMenu.Active = true
&#9;gearContextMenu.Name = &quot;UnequipContextMenu&quot;
&#9;gearContextMenu.Size = UDim2.new(0,115,0,70)
&#9;gearContextMenu.Position = UDim2.new(0,-16,0,-16)
&#9;gearContextMenu.BackgroundTransparency = 1
&#9;gearContextMenu.Visible = false
&#9;local gearContextMenuButton = Instance.new(&quot;TextButton&quot;)
&#9;gearContextMenuButton.Name = &quot;UnequipContextMenuButton&quot;
&#9;gearContextMenuButton.Text = &quot;&quot;
&#9;gearContextMenuButton.Style = Enum.ButtonStyle.RobloxButtonDefault
&#9;gearContextMenuButton.ZIndex = 8
&#9;gearContextMenuButton.Size = UDim2.new(1, 0, 1, -20)
&#9;gearContextMenuButton.Visible = true
&#9;gearContextMenuButton.Parent = gearContextMenu
&#9;
&#9;local elementHeight = 12
&#9;
&#9;local contextMenuElements = {}&#9;&#9;
&#9;local contextMenuElementsName = {&quot;Remove Hotkey&quot;}
&#9;for i = 1, #contextMenuElementsName do
&#9;&#9;local element = {}
&#9;&#9;element.Type = &quot;Button&quot;
&#9;&#9;element.Text = contextMenuElementsName[i]
&#9;&#9;element.Action = i
&#9;&#9;element.DoIt = UnequipGearMenuClick
&#9;&#9;table.insert(contextMenuElements,element)
&#9;end
&#9;for i, contextElement in ipairs(contextMenuElements) do
&#9;&#9;local element = contextElement
&#9;&#9;if element.Type == &quot;Button&quot; then
&#9;&#9;&#9;local button = Instance.new(&quot;TextButton&quot;)
&#9;&#9;&#9;button.Name = &quot;UnequipContextButton&quot; .. i
&#9;&#9;&#9;button.BackgroundColor3 = Color3.new(0,0,0)
&#9;&#9;&#9;button.BorderSizePixel = 0
&#9;&#9;&#9;button.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;&#9;button.Text = &quot; &quot; .. contextElement.Text
&#9;&#9;&#9;button.Font = Enum.Font.Arial
&#9;&#9;&#9;button.FontSize = Enum.FontSize.Size14
&#9;&#9;&#9;button.Size = UDim2.new(1, 8, 0, elementHeight)
&#9;&#9;&#9;button.Position = UDim2.new(0,0,0,elementHeight * i)
&#9;&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;button.ZIndex = 9
&#9;&#9;&#9;button.Parent = gearContextMenuButton
&#9;&#9;&#9;if not IsTouchDevice() then
&#9;&#9;&#9;&#9;button.MouseButton1Click:connect(function()
&#9;&#9;&#9;&#9;&#9;if button.Active and not gearContextMenu.Parent.Active then
&#9;&#9;&#9;&#9;&#9;&#9;local success, result = pcall(function() element.DoIt(element, gearContextMenu) end)
&#9;&#9;&#9;&#9;&#9;&#9;browsingMenu = false
&#9;&#9;&#9;&#9;&#9;&#9;gearContextMenu.Visible = false
&#9;&#9;&#9;&#9;&#9;&#9;clearHighlight(button)
&#9;&#9;&#9;&#9;&#9;&#9;clearPreview()
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;button.MouseEnter:connect(function()
&#9;&#9;&#9;&#9;&#9;if button.Active and gearContextMenu.Parent.Active then
&#9;&#9;&#9;&#9;&#9;&#9;highlight(button)
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;&#9;button.MouseLeave:connect(function()
&#9;&#9;&#9;&#9;&#9;if button.Active and gearContextMenu.Parent.Active then
&#9;&#9;&#9;&#9;&#9;&#9;clearHighlight(button)
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;&#9;contextElement.Button = button
&#9;&#9;&#9;contextElement.Element = button
&#9;&#9;elseif element.Type == &quot;Label&quot; then
&#9;&#9;&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;&#9;&#9;frame.Name = &quot;ContextLabel&quot; .. i
&#9;&#9;&#9;frame.BackgroundTransparency = 1
&#9;&#9;&#9;frame.Size = UDim2.new(1, 8, 0, elementHeight)
&#9;&#9;&#9;local label = Instance.new(&quot;TextLabel&quot;)&#9;
&#9;&#9;&#9;label.Name = &quot;Text1&quot;
&#9;&#9;&#9;label.BackgroundTransparency = 1
&#9;&#9;&#9;label.BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;label.BorderSizePixel = 0
&#9;&#9;&#9;label.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;&#9;label.Font = Enum.Font.ArialBold
&#9;&#9;&#9;label.FontSize = Enum.FontSize.Size14
&#9;&#9;&#9;label.Position = UDim2.new(0.0, 0, 0, 0)
&#9;&#9;&#9;label.Size = UDim2.new(0.5, 0, 1, 0)
&#9;&#9;&#9;label.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;label.ZIndex = 9
&#9;&#9;&#9;label.Parent = frame
&#9;&#9;&#9;element.Label1 = label
&#9;&#9;
&#9;&#9;&#9;if element.GetText2 then
&#9;&#9;&#9;&#9;label = Instance.new(&quot;TextLabel&quot;)&#9;
&#9;&#9;&#9;&#9;label.Name = &quot;Text2&quot;
&#9;&#9;&#9;&#9;label.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;label.BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;label.BorderSizePixel = 0
&#9;&#9;&#9;&#9;label.TextXAlignment = Enum.TextXAlignment.Right
&#9;&#9;&#9;&#9;label.Font = Enum.Font.Arial
&#9;&#9;&#9;&#9;label.FontSize = Enum.FontSize.Size14
&#9;&#9;&#9;&#9;label.Position = UDim2.new(0.5, 0, 0, 0)
&#9;&#9;&#9;&#9;label.Size = UDim2.new(0.5, 0, 1, 0)
&#9;&#9;&#9;&#9;label.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;label.ZIndex = 9
&#9;&#9;&#9;&#9;label.Parent = frame
&#9;&#9;&#9;&#9;element.Label2 = label
&#9;&#9;&#9;end
&#9;&#9;&#9;frame.Parent = gearContextMenuButton
&#9;&#9;&#9;element.Label = frame
&#9;&#9;&#9;element.Element = frame
&#9;&#9;end
&#9;end
&#9;gearContextMenu.ZIndex = 4
&#9;gearContextMenu.MouseLeave:connect(function()
&#9;&#9;browsingMenu = false
&#9;&#9;gearContextMenu.Visible = false
&#9;&#9;clearPreview()
&#9;end)
&#9;
&#9;return gearContextMenu
end
function coreGuiChanged(coreGuiType,enabled)
&#9;if coreGuiType == Enum.CoreGuiType.Backpack or coreGuiType == Enum.CoreGuiType.All then
&#9;&#9;if not enabled then
&#9;&#9;&#9;backpack.Gear.Visible = false
&#9;&#9;end
&#9;end
end
local backpackChildren = player.Backpack:GetChildren()
for i = 1, #backpackChildren do
&#9;addToGrid(backpackChildren[i])
end
------------------------- Start Lifelong Connections -----------------------
resizeEvent.Event:connect(function(absSize)
&#9;if debounce then return end
&#9;
&#9;debounce = true
&#9;wait()
&#9;resize()
&#9;resizeGrid()
&#9;debounce = false
end)
currentLoadout.ChildAdded:connect(function(child) loadoutCheck(child, false) end)
currentLoadout.ChildRemoved:connect(function(child) loadoutCheck(child, true) end)
currentLoadout.DescendantAdded:connect(function(descendant)
&#9;if not backpack.Visible and ( descendant:IsA(&quot;ImageButton&quot;) or descendant:IsA(&quot;TextButton&quot;) ) then
&#9;&#9;centerGear(currentLoadout:GetChildren())
&#9;end
end)
currentLoadout.DescendantRemoving:connect(function(descendant)
&#9;if not backpack.Visible and ( descendant:IsA(&quot;ImageButton&quot;) or descendant:IsA(&quot;TextButton&quot;) ) then
&#9;&#9;wait()
&#9;&#9;centerGear(currentLoadout:GetChildren())
&#9;end
end)
&#9;
grid.MouseEnter:connect(function() clearPreview() end)
grid.MouseLeave:connect(function() clearPreview() end)
player.CharacterRemoving:connect(function()
&#9;removeCharacterConnections()
&#9;nukeBackpack()
end)
player.CharacterAdded:connect(function() setupCharacterConnections() end)
player.ChildAdded:connect(function(child)
&#9;if child:IsA(&quot;Backpack&quot;) then
&#9;&#9;playerBackpack = child
&#9;&#9;if backpackAddCon then backpackAddCon:disconnect() end
&#9;&#9;backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded:connect(function(child) addToGrid(child) end)
&#9;end
end)
swapSlot.Changed:connect(function()
&#9;if not swapSlot.Value then
&#9;&#9;updateGridActive()
&#9;end
end)
local loadoutChildren = currentLoadout:GetChildren()
for i = 1, #loadoutChildren do
&#9;if loadoutChildren[i]:IsA(&quot;Frame&quot;) and string.find(loadoutChildren[i].Name,&quot;Slot&quot;) then
&#9;&#9;loadoutChildren[i].ChildRemoved:connect(function()
&#9;&#9;&#9;updateGridActive()
&#9;&#9;end)
&#9;&#9;loadoutChildren[i].ChildAdded:connect(function()
&#9;&#9;&#9;updateGridActive()
&#9;&#9;end)
&#9;end
end
------------------------- End Lifelong Connections -----------------------
resize()
resizeGrid()
-- make sure any items in the loadout are accounted for in inventory
local loadoutChildren = currentLoadout:GetChildren()
for i = 1, #loadoutChildren do
&#9;loadoutCheck(loadoutChildren[i], false)
end
if not backpack.Visible then centerGear(currentLoadout:GetChildren()) end
-- make sure that inventory is listening to gear reparenting
if characterChildAddedCon == nil and game.Players.LocalPlayer[&quot;Character&quot;] then
&#9;setupCharacterConnections()
end
if not backpackAddCon then
&#9;backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded:connect(function(child) addToGrid(child) end)
end
backpackOpenEvent.Event:connect(backpackOpenHandler)
backpackCloseEvent.Event:connect(backpackCloseHandler)
tabClickedEvent.Event:connect(tabClickHandler)
searchRequestedEvent.Event:connect(showSearchGear)
recalculateScrollLoadout()</ProtectedString>
</Properties>
</Item>
<Item class="LocalScript" referent="RBX6">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">BackpackManager</string>
<ProtectedString name="Source">-- basic functions
local function waitForChild(instance, name)
&#9;while not instance:FindFirstChild(name) do
&#9;&#9;instance.ChildAdded:wait()
&#9;end
&#9;return instance:FindFirstChild(name)
end
local function waitForProperty(instance, property)
&#9;while not instance[property] do
&#9;&#9;instance.Changed:wait()
&#9;end
end
-- don&apos;t do anything if we are in an empty game
waitForChild(game,&quot;Players&quot;)
if #game.Players:GetChildren() &lt; 1 then
&#9;game.Players.ChildAdded:wait()
end
-- make sure everything is loaded in before we do anything
-- get our local player
waitForProperty(game.Players,&quot;LocalPlayer&quot;)
local player = game.Players.LocalPlayer
------------------------ Locals ------------------------------
local backpack = script.Parent.Backpack
waitForChild(backpack,&quot;Gear&quot;)
local screen = script.Parent
assert(screen:IsA(&quot;ScreenGui&quot;))
waitForChild(backpack.Parent,&quot;ControlFrame&quot;)
local backpackButton = waitForChild(backpack.Parent.ControlFrame,&quot;BackpackButton&quot;)
local currentTab = &quot;gear&quot;
local searchFrame = waitForChild(backpack,&quot;SearchFrame&quot;)
waitForChild(backpack.SearchFrame,&quot;SearchBoxFrame&quot;)
local searchBox = waitForChild(backpack.SearchFrame.SearchBoxFrame,&quot;SearchBox&quot;)
local searchButton = waitForChild(backpack.SearchFrame,&quot;SearchButton&quot;)
local resetButton = waitForChild(backpack.SearchFrame,&quot;ResetButton&quot;)
local robloxGui = script.Parent
local currentLoadout = waitForChild(robloxGui, &apos;CurrentLoadout&apos;)
local loadoutBackground = waitForChild(currentLoadout, &apos;Background&apos;)
local canToggle = true
local readyForNextEvent = true
local backpackIsOpen = false
local active = true
local humanoidDiedCon = nil
local backpackButtonPos
local guiTweenSpeed = 0.25 -- how quickly we open/close the backpack
local searchDefaultText = &quot;Search...&quot;
local tilde = &quot;~&quot;
local backquote = &quot;`&quot;
local backpackSize = UDim2.new(0, 600, 0, 400)
------------------------ End Locals ---------------------------
---------------------------------------- Public Event Setup ----------------------------------------
function createPublicEvent(eventName)
&#9;assert(eventName, &quot;eventName is nil&quot;)
&#9;assert(tostring(eventName),&quot;eventName is not a string&quot;)
&#9;
&#9;local newEvent = Instance.new(&quot;BindableEvent&quot;)
&#9;newEvent.Name = tostring(eventName)
&#9;newEvent.Parent = script
&#9;return newEvent
end
function createPublicFunction(funcName, invokeFunc)
&#9;assert(funcName, &quot;funcName is nil&quot;)
&#9;assert(tostring(funcName), &quot;funcName is not a string&quot;)
&#9;assert(invokeFunc, &quot;invokeFunc is nil&quot;)
&#9;assert(type(invokeFunc) == &quot;function&quot;, &quot;invokeFunc should be of type &apos;function&apos;&quot;)
&#9;
&#9;local newFunction = Instance.new(&quot;BindableFunction&quot;)
&#9;newFunction.Name = tostring(funcName)
&#9;newFunction.OnInvoke = invokeFunc
&#9;newFunction.Parent = script
&#9;return newFunction
end
-- Events
local resizeEvent = createPublicEvent(&quot;ResizeEvent&quot;)
local backpackOpenEvent = createPublicEvent(&quot;BackpackOpenEvent&quot;)
local backpackCloseEvent = createPublicEvent(&quot;BackpackCloseEvent&quot;)
local tabClickedEvent = createPublicEvent(&quot;TabClickedEvent&quot;)
local searchRequestedEvent = createPublicEvent(&quot;SearchRequestedEvent&quot;)
---------------------------------------- End Public Event Setup ----------------------------------------
--------------------------- Internal Functions ----------------------------------------
function deactivateBackpack()
&#9;backpack.Visible = false
&#9;active = false
end
function activateBackpack()
&#9;initHumanoidDiedConnections()&#9;&#9;
&#9;active = true
&#9;backpack.Visible = backpackIsOpen
&#9;if backpackIsOpen then
&#9;&#9;toggleBackpack()
&#9;end
end
function initHumanoidDiedConnections()&#9;&#9;&#9;
&#9;if humanoidDiedCon then
&#9;&#9;humanoidDiedCon:disconnect()
&#9;end
&#9;waitForProperty(game.Players.LocalPlayer,&quot;Character&quot;)
&#9;waitForChild(game.Players.LocalPlayer.Character,&quot;Humanoid&quot;)
&#9;humanoidDiedCon = game.Players.LocalPlayer.Character.Humanoid.Died:connect(deactivateBackpack)
end
local hideBackpack = function()
&#9;backpackIsOpen = false
&#9;readyForNextEvent = false
&#9;backpackButton.Selected = false
&#9;resetSearch()
&#9;backpackCloseEvent:Fire(currentTab)
&#9;searchFrame.Visible = false
&#9;backpack:TweenSizeAndPosition(UDim2.new(0, backpackSize.X.Offset,0, 0), UDim2.new(0.5, -backpackSize.X.Offset/2, 1, -85), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, guiTweenSpeed, true,
&#9;&#9;function()
&#9;&#9;&#9;game.GuiService:RemoveCenterDialog(backpack)
&#9;&#9;&#9;backpack.Visible = false
&#9;&#9;&#9;backpackButton.Selected = false
&#9;&#9;end)
&#9;delay(guiTweenSpeed,function()
&#9;&#9;--game.GuiService:RemoveCenterDialog(backpack)
&#9;&#9;backpack.Visible = false
&#9;&#9;backpackButton.Selected = false
&#9;&#9;readyForNextEvent = true&#9;&#9;
&#9;&#9;canToggle = true
&#9;end)
end
function spreadOutGear(loadoutChildren)
&#9;for i = 1, #loadoutChildren do
&#9;&#9;if loadoutChildren[i]:IsA(&quot;Frame&quot;) then
&#9;&#9;&#9;local slot = tonumber(string.sub(loadoutChildren[i].Name,5))
&#9;&#9;&#9;if slot == 0 then slot = 10 end
&#9;&#9;&#9;loadoutChildren[i]:TweenPosition(UDim2.new((slot - 1)/10,0,0,0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.25, true)
&#9;&#9;end
&#9;end
end
function showBackpack()
&#9;game.GuiService:AddCenterDialog(backpack, Enum.CenterDialogType.PlayerInitiatedDialog,
&#9;&#9;function()
&#9;&#9;&#9;backpack.Visible = true
&#9;&#9;&#9;backpackButton.Selected = true
&#9;&#9;end,
&#9;&#9;function()
&#9;&#9;&#9;backpack.Visible = false
&#9;&#9;&#9;backpackButton.Selected = false
&#9;end)
&#9;backpack.Visible = true
backpack.Gear.Visible = true
&#9;backpackButton.Selected = true&#9;
&#9;backpack:TweenSizeAndPosition(backpackSize, UDim2.new(0.5, -backpackSize.X.Offset/2, 1, -backpackSize.Y.Offset - 88), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, guiTweenSpeed, true)
&#9;delay(guiTweenSpeed,function()
&#9;&#9;searchFrame.Visible = true
&#9;&#9;--backpackOpenEvent:Fire(currentTab)
&#9;&#9;canToggle = true
&#9;&#9;readyForNextEvent = true
&#9;&#9;backpackButton.Image = &apos;http://www.roblox.com/asset/?id=97644093&apos;
&#9;&#9;backpackButton.Position = UDim2.new(0.5, -60, 1, -backpackSize.Y.Offset - 103)
&#9;&#9;&#9;&#9;loadoutChildren = currentLoadout:GetChildren()
&#9;&#9;&#9;&#9;for i = 1, #loadoutChildren do
&#9;&#9;&#9;&#9;&#9;if loadoutChildren[i]:IsA(&quot;Frame&quot;) then
&#9;&#9;&#9;&#9;&#9;&#9;loadoutChildren[i].BackgroundTransparency = 0.5
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;spreadOutGear(loadoutChildren)
&#9;end)
end
function toggleBackpack()&#9;
&#9;if not game.Players.LocalPlayer then return end
&#9;if not game.Players.LocalPlayer[&quot;Character&quot;] then return end
&#9;if not canToggle then return end
&#9;if not readyForNextEvent then return end
&#9;readyForNextEvent = false
&#9;canToggle = false
&#9;
&#9;backpackIsOpen = not backpackIsOpen
&#9;if backpackIsOpen then&#9;&#9;&#9;&#9;
&#9;&#9;loadoutBackground.Image = &apos;http://www.roblox.com/asset/?id=97623721&apos;
&#9;&#9;loadoutBackground.Position = UDim2.new(-0.03, 0, -0.17, 0)
&#9;&#9;loadoutBackground.Size = UDim2.new(1.05, 0, 1.25, 0)
&#9;&#9;loadoutBackground.ZIndex = 2.0
&#9;&#9;loadoutBackground.Visible = true
&#9;&#9;backpackButton.Position = UDim2.new(0.5, -60, 1, -503)
&#9;&#9;showBackpack()
&#9;else&#9;&#9;
&#9;&#9;backpackButton.Position = UDim2.new(0.5, -60, 1, -44)
&#9;&#9;loadoutBackground.Visible = false
&#9;&#9;backpackButton.Selected = false&#9;&#9;
&#9;&#9;backpackButton.Image = &quot;http://www.roblox.com/asset/?id=97617958&quot;
&#9;&#9;loadoutBackground.Image = &apos;http://www.roblox.com/asset/?id=96536002&apos;
&#9;&#9;loadoutBackground.Position = UDim2.new(-0.1, 0, -0.1, 0)
&#9;&#9;loadoutBackground.Size = UDim2.new(1.2, 0, 1.2, 0)&#9;&#9;
&#9;&#9;hideBackpack()
&#9;&#9;
&#9;&#9;local clChildren = currentLoadout:GetChildren()
&#9;&#9;for i = 1, #clChildren do
&#9;&#9;&#9;if clChildren[i] and clChildren[i]:IsA(&apos;Frame&apos;) then
&#9;&#9;&#9;&#9;local frame = clChildren[i]
&#9;&#9;&#9;&#9;if #frame:GetChildren() &gt; 0 then
&#9;&#9;&#9;&#9;&#9;backpackButton.Position = UDim2.new(0.5, -60, 1, -108)
&#9;&#9;&#9;&#9;&#9;backpackButton.Visible = true
&#9;&#9;&#9;&#9;&#9;loadoutBackground.Visible = true
&#9;&#9;&#9;&#9;&#9;if frame:GetChildren()[1]:IsA(&apos;ImageButton&apos;) then
&#9;&#9;&#9;&#9;&#9;&#9;local imgButton = frame:GetChildren()[1]
&#9;&#9;&#9;&#9;&#9;&#9;imgButton.Active = true
&#9;&#9;&#9;&#9;&#9;&#9;imgButton.Draggable = false
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;
&#9;end
end
function closeBackpack()
&#9;if backpackIsOpen then
&#9;&#9;toggleBackpack()
&#9;end
end
function setSelected(tab)
&#9;assert(tab)
&#9;assert(tab:IsA(&quot;TextButton&quot;))
&#9;
&#9;tab.BackgroundColor3 = Color3.new(1,1,1)
&#9;tab.TextColor3 = Color3.new(0,0,0)
&#9;tab.Selected = true
&#9;tab.ZIndex = 3
end
function setUnselected(tab)
&#9;assert(tab)
&#9;assert(tab:IsA(&quot;TextButton&quot;))
&#9;
&#9;tab.BackgroundColor3 = Color3.new(0,0,0)
&#9;tab.TextColor3 = Color3.new(1,1,1)
&#9;tab.Selected = false
&#9;tab.ZIndex = 1
end
function updateTabGui(selectedTab)
&#9;assert(selectedTab)
&#9;
&#9;if selectedTab == &quot;gear&quot; then
&#9;elseif selectedTab == &quot;wardrobe&quot; then
&#9;&#9;
&#9;end
end
function mouseLeaveTab(button)
&#9;assert(button)
&#9;assert(button:IsA(&quot;TextButton&quot;))
&#9;
&#9;if button.Selected then return end
&#9;
&#9;button.BackgroundColor3 = Color3.new(0,0,0)
end
function mouseOverTab(button)
&#9;assert(button)
&#9;assert(button:IsA(&quot;TextButton&quot;))
&#9;
&#9;if button.Selected then return end
&#9;
&#9;button.BackgroundColor3 = Color3.new(39/255,39/255,39/255)
end
function newTabClicked(tabName)
&#9;assert(tabName)
&#9;tabName = string.lower(tabName)
&#9;currentTab = tabName
&#9;
&#9;updateTabGui(tabName)
&#9;tabClickedEvent:Fire(tabName)
&#9;resetSearch()
end
function trim(s)
return (s:gsub(&quot;^%s*(.-)%s*$&quot;, &quot;%1&quot;))
end
function splitByWhitespace(text)
&#9;if type(text) ~= &quot;string&quot; then return nil end
&#9;
&#9;local terms = {}
&#9;for token in string.gmatch(text, &quot;[^%s]+&quot;) do
&#9; if string.len(token) &gt; 0 then
&#9;&#9;&#9;table.insert(terms,token)
&#9; end
&#9;end
&#9;return terms
end
function resetSearchBoxGui()
&#9;resetButton.Visible = false
&#9;searchBox.Text = searchDefaultText
end
function doSearch()
&#9;local searchText = searchBox.Text
&#9;if searchText == &quot;&quot; then
&#9;&#9;resetSearch()
&#9;&#9;return
&#9;end
&#9;searchText = trim(searchText)
&#9;resetButton.Visible = true
&#9;termTable = splitByWhitespace(searchText)
&#9;searchRequestedEvent:Fire(searchText) -- todo: replace this with termtable when table passing is possible
end
function resetSearch()
&#9;resetSearchBoxGui()
&#9;searchRequestedEvent:Fire()
end
local backpackReady = function()
&#9;readyForNextEvent = true
end
--------------------------- End Internal Functions -------------------------------------
------------------------------ Public Functions Setup -------------------------------------
createPublicFunction(&quot;CloseBackpack&quot;, hideBackpack)
createPublicFunction(&quot;BackpackReady&quot;, backpackReady)
------------------------------ End Public Functions Setup ---------------------------------
------------------------ Connections/Script Main -------------------------------------------
screen.Changed:connect(function(prop)
&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;resizeEvent:Fire(screen.AbsoluteSize)
&#9;end
end)
-- GuiService key setup
game:GetService(&quot;GuiService&quot;):AddKey(tilde)
game:GetService(&quot;GuiService&quot;):AddKey(backquote)
game:GetService(&quot;GuiService&quot;).KeyPressed:connect(function(key)
&#9;if not active then return end
&#9;if key == tilde or key == backquote then
&#9;&#9;toggleBackpack()
showBackpack()
&#9;end
end)
backpackButton.MouseButton1Click:connect(function()
&#9;if not active then return end
&#9;toggleBackpack()
end)
if game.Players.LocalPlayer[&quot;Character&quot;] then
&#9;activateBackpack()
end
game.Players.LocalPlayer.CharacterAdded:connect(activateBackpack)
-- search functions
searchBox.FocusLost:connect(function(enterPressed)
&#9;if enterPressed or searchBox.Text ~= &quot;&quot; then
&#9;&#9;doSearch()
&#9;elseif searchBox.Text == &quot;&quot; then
&#9;&#9;resetSearch()
&#9;end
end)
searchButton.MouseButton1Click:connect(doSearch)
resetButton.MouseButton1Click:connect(resetSearch)
--backpackButton.Visible = true</ProtectedString>
</Properties>
</Item>
<Item class="LocalScript" referent="RBX7">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">BackpackResizer</string>
<ProtectedString name="Source">print(&quot;carrot is gay&quot;)
local t = {}
local function ScopedConnect(parentInstance, instance, event, signalFunc, syncFunc, removeFunc)
&#9;local eventConnection = nil
&#9;--Connection on parentInstance is scoped by parentInstance (when destroyed, it goes away)
&#9;local tryConnect = function()
&#9;&#9;if game:IsAncestorOf(parentInstance) then
&#9;&#9;&#9;--Entering the world, make sure we are connected/synced
&#9;&#9;&#9;if not eventConnection then
&#9;&#9;&#9;&#9;eventConnection = instance[event]:connect(signalFunc)
&#9;&#9;&#9;&#9;if syncFunc then syncFunc() end
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;--Probably leaving the world, so disconnect for now
&#9;&#9;&#9;if eventConnection then
&#9;&#9;&#9;&#9;eventConnection:disconnect()
&#9;&#9;&#9;&#9;if removeFunc then removeFunc() end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;--Hook it up to ancestryChanged signal
&#9;local connection = parentInstance.AncestryChanged:connect(tryConnect)
&#9;
&#9;--Now connect us if we&apos;re already in the world
&#9;tryConnect()
&#9;
&#9;return connection
end
local function getScreenGuiAncestor(instance)
&#9;local localInstance = instance
&#9;while localInstance and not localInstance:IsA(&quot;ScreenGui&quot;) do
&#9;&#9;localInstance = localInstance.Parent
&#9;end
&#9;return localInstance
end
local function CreateButtons(frame, buttons, yPos, ySize)
&#9;local buttonNum = 1
&#9;local buttonObjs = {}
&#9;for i, obj in ipairs(buttons) do
&#9;&#9;local button = Instance.new(&quot;TextButton&quot;)
&#9;&#9;button.Name = &quot;Button&quot; .. buttonNum
&#9;&#9;button.Font = Enum.Font.Arial
&#9;&#9;button.FontSize = Enum.FontSize.Size18
&#9;&#9;button.AutoButtonColor = true
&#9;&#9;button.Modal = true
&#9;&#9;if obj[&quot;Style&quot;] then
&#9;&#9;&#9;button.Style = obj.Style
&#9;&#9;else
&#9;&#9;&#9;button.Style = Enum.ButtonStyle.RobloxButton
&#9;&#9;end
&#9;&#9;if obj[&quot;ZIndex&quot;] then
&#9;&#9;&#9;button.ZIndex = obj.ZIndex
&#9;&#9;end
&#9;&#9;button.Text = obj.Text
&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;button.MouseButton1Click:connect(obj.Function)
&#9;&#9;button.Parent = frame
&#9;&#9;buttonObjs[buttonNum] = button
&#9;&#9;buttonNum = buttonNum + 1
&#9;end
&#9;local numButtons = buttonNum-1
&#9;if numButtons == 1 then
&#9;&#9;frame.Button1.Position = UDim2.new(0.35, 0, yPos.Scale, yPos.Offset)
&#9;&#9;frame.Button1.Size = UDim2.new(.4,0,ySize.Scale, ySize.Offset)
&#9;elseif numButtons == 2 then
&#9;&#9;frame.Button1.Position = UDim2.new(0.1, 0, yPos.Scale, yPos.Offset)
&#9;&#9;frame.Button1.Size = UDim2.new(.8/3,0, ySize.Scale, ySize.Offset)
&#9;&#9;frame.Button2.Position = UDim2.new(0.55, 0, yPos.Scale, yPos.Offset)
&#9;&#9;frame.Button2.Size = UDim2.new(.35,0, ySize.Scale, ySize.Offset)
&#9;elseif numButtons &gt;= 3 then
&#9;&#9;local spacing = .1 / numButtons
&#9;&#9;local buttonSize = .9 / numButtons
&#9;&#9;buttonNum = 1
&#9;&#9;while buttonNum &lt;= numButtons do
&#9;&#9;&#9;buttonObjs[buttonNum].Position = UDim2.new(spacing*buttonNum + (buttonNum-1) * buttonSize, 0, yPos.Scale, yPos.Offset)
&#9;&#9;&#9;buttonObjs[buttonNum].Size = UDim2.new(buttonSize, 0, ySize.Scale, ySize.Offset)
&#9;&#9;&#9;buttonNum = buttonNum + 1
&#9;&#9;end
&#9;end
end
local function setSliderPos(newAbsPosX,slider,sliderPosition,bar,steps)
&#9;local newStep = steps - 1 --otherwise we really get one more step than we want
&#9;local relativePosX = math.min(1, math.max(0, (newAbsPosX - bar.AbsolutePosition.X) / bar.AbsoluteSize.X ))
&#9;local wholeNum, remainder = math.modf(relativePosX * newStep)
&#9;if remainder &gt; 0.5 then
&#9;&#9;wholeNum = wholeNum + 1
&#9;end
&#9;relativePosX = wholeNum/newStep
&#9;local result = math.ceil(relativePosX * newStep)
&#9;if sliderPosition.Value ~= (result + 1) then --only update if we moved a step
&#9;&#9;sliderPosition.Value = result + 1
&#9;&#9;slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
&#9;end
&#9;
end
local function cancelSlide(areaSoak)
&#9;areaSoak.Visible = false
&#9;if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
end
t.CreateStyledMessageDialog = function(title, message, style, buttons)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Size = UDim2.new(0.5, 0, 0, 165)
&#9;frame.Position = UDim2.new(0.25, 0, 0.5, -72.5)
&#9;frame.Name = &quot;MessageDialog&quot;
&#9;frame.Active = true
&#9;frame.Style = Enum.FrameStyle.RobloxRound&#9;
&#9;
&#9;local styleImage = Instance.new(&quot;ImageLabel&quot;)
&#9;styleImage.Name = &quot;StyleImage&quot;
&#9;styleImage.BackgroundTransparency = 1
&#9;styleImage.Position = UDim2.new(0,5,0,15)
&#9;if style == &quot;error&quot; or style == &quot;Error&quot; then
&#9;&#9;styleImage.Size = UDim2.new(0, 71, 0, 71)
&#9;&#9;styleImage.Image = &quot;http://www.roblox.com/asset/?id=42565285&quot;
&#9;elseif style == &quot;notify&quot; or style == &quot;Notify&quot; then
&#9;&#9;styleImage.Size = UDim2.new(0, 71, 0, 71)
&#9;&#9;styleImage.Image = &quot;http://www.roblox.com/asset/?id=42604978&quot;
&#9;elseif style == &quot;confirm&quot; or style == &quot;Confirm&quot; then
&#9;&#9;styleImage.Size = UDim2.new(0, 74, 0, 76)
&#9;&#9;styleImage.Image = &quot;http://www.roblox.com/asset/?id=42557901&quot;
&#9;else
&#9;&#9;return t.CreateMessageDialog(title,message,buttons)
&#9;end
&#9;styleImage.Parent = frame
&#9;
&#9;local titleLabel = Instance.new(&quot;TextLabel&quot;)
&#9;titleLabel.Name = &quot;Title&quot;
&#9;titleLabel.Text = title
&#9;titleLabel.TextStrokeTransparency = 0
&#9;titleLabel.BackgroundTransparency = 1
&#9;titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
&#9;titleLabel.Position = UDim2.new(0, 80, 0, 0)
&#9;titleLabel.Size = UDim2.new(1, -80, 0, 40)
&#9;titleLabel.Font = Enum.Font.ArialBold
&#9;titleLabel.FontSize = Enum.FontSize.Size36
&#9;titleLabel.TextXAlignment = Enum.TextXAlignment.Center
&#9;titleLabel.TextYAlignment = Enum.TextYAlignment.Center
&#9;titleLabel.Parent = frame
&#9;local messageLabel = Instance.new(&quot;TextLabel&quot;)
&#9;messageLabel.Name = &quot;Message&quot;
&#9;messageLabel.Text = message
&#9;messageLabel.TextStrokeTransparency = 0
&#9;messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
&#9;messageLabel.Position = UDim2.new(0.025, 80, 0, 45)
&#9;messageLabel.Size = UDim2.new(0.95, -80, 0, 55)
&#9;messageLabel.BackgroundTransparency = 1
&#9;messageLabel.Font = Enum.Font.Arial
&#9;messageLabel.FontSize = Enum.FontSize.Size18
&#9;messageLabel.TextWrap = true
&#9;messageLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;messageLabel.TextYAlignment = Enum.TextYAlignment.Top
&#9;messageLabel.Parent = frame
&#9;CreateButtons(frame, buttons, UDim.new(0, 105), UDim.new(0, 40) )
&#9;return frame
end
t.CreateMessageDialog = function(title, message, buttons)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Size = UDim2.new(0.5, 0, 0.5, 0)
&#9;frame.Position = UDim2.new(0.25, 0, 0.25, 0)
&#9;frame.Name = &quot;MessageDialog&quot;
&#9;frame.Active = true
&#9;frame.Style = Enum.FrameStyle.RobloxRound
&#9;local titleLabel = Instance.new(&quot;TextLabel&quot;)
&#9;titleLabel.Name = &quot;Title&quot;
&#9;titleLabel.Text = title
&#9;titleLabel.BackgroundTransparency = 1
&#9;titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
&#9;titleLabel.Position = UDim2.new(0, 0, 0, 0)
&#9;titleLabel.Size = UDim2.new(1, 0, 0.15, 0)
&#9;titleLabel.Font = Enum.Font.ArialBold
&#9;titleLabel.FontSize = Enum.FontSize.Size36
&#9;titleLabel.TextXAlignment = Enum.TextXAlignment.Center
&#9;titleLabel.TextYAlignment = Enum.TextYAlignment.Center
&#9;titleLabel.Parent = frame
&#9;local messageLabel = Instance.new(&quot;TextLabel&quot;)
&#9;messageLabel.Name = &quot;Message&quot;
&#9;messageLabel.Text = message
&#9;messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
&#9;messageLabel.Position = UDim2.new(0.025, 0, 0.175, 0)
&#9;messageLabel.Size = UDim2.new(0.95, 0, .55, 0)
&#9;messageLabel.BackgroundTransparency = 1
&#9;messageLabel.Font = Enum.Font.Arial
&#9;messageLabel.FontSize = Enum.FontSize.Size18
&#9;messageLabel.TextWrap = true
&#9;messageLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;messageLabel.TextYAlignment = Enum.TextYAlignment.Top
&#9;messageLabel.Parent = frame
&#9;CreateButtons(frame, buttons, UDim.new(0.8,0), UDim.new(0.15, 0))
&#9;return frame
end
t.CreateDropDownMenu = function(items, onSelect, forRoblox, whiteSkin, baseZ)
&#9;local baseZIndex = 0
&#9;if (type(baseZ) == &quot;number&quot;) then
&#9;&#9;baseZIndex = baseZ
&#9;end
&#9;local width = UDim.new(0, 100)
&#9;local height = UDim.new(0, 32)
&#9;local xPos = 0.055
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;local textColor = Color3.new(1,1,1)
&#9;if (whiteSkin) then
&#9;&#9;textColor = Color3.new(0.5, 0.5, 0.5)
&#9;end
&#9;frame.Name = &quot;DropDownMenu&quot;
&#9;frame.BackgroundTransparency = 1
&#9;frame.Size = UDim2.new(width, height)
&#9;local dropDownMenu = Instance.new(&quot;TextButton&quot;)
&#9;dropDownMenu.Name = &quot;DropDownMenuButton&quot;
&#9;dropDownMenu.TextWrap = true
&#9;dropDownMenu.TextColor3 = textColor
&#9;dropDownMenu.Text = &quot;Choose One&quot;
&#9;dropDownMenu.Font = Enum.Font.ArialBold
&#9;dropDownMenu.FontSize = Enum.FontSize.Size18
&#9;dropDownMenu.TextXAlignment = Enum.TextXAlignment.Left
&#9;dropDownMenu.TextYAlignment = Enum.TextYAlignment.Center
&#9;dropDownMenu.BackgroundTransparency = 1
&#9;dropDownMenu.AutoButtonColor = true
&#9;if (whiteSkin) then
&#9;&#9;dropDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton
&#9;else
&#9;&#9;dropDownMenu.Style = Enum.ButtonStyle.RobloxButton
&#9;end
&#9;dropDownMenu.Size = UDim2.new(1,0,1,0)
&#9;dropDownMenu.Parent = frame
&#9;dropDownMenu.ZIndex = 2 + baseZIndex
&#9;local dropDownIcon = Instance.new(&quot;ImageLabel&quot;)
&#9;dropDownIcon.Name = &quot;Icon&quot;
&#9;dropDownIcon.Active = false
&#9;if (whiteSkin) then
&#9;&#9;dropDownIcon.Image = &quot;rbxasset://textures/ui/dropdown_arrow.png&quot;
&#9;&#9;dropDownIcon.Size = UDim2.new(0,16,0,12)
&#9;&#9;dropDownIcon.Position = UDim2.new(1,-17,0.5, -6)
&#9;else
&#9;&#9;dropDownIcon.Image = &quot;http://www.roblox.com/asset/?id=45732894&quot;
&#9;&#9;dropDownIcon.Size = UDim2.new(0,11,0,6)
&#9;&#9;dropDownIcon.Position = UDim2.new(1,-11,0.5, -2)
&#9;end
&#9;dropDownIcon.BackgroundTransparency = 1
&#9;dropDownIcon.Parent = dropDownMenu
&#9;dropDownIcon.ZIndex = 2 + baseZIndex
&#9;
&#9;local itemCount = #items
&#9;local dropDownItemCount = #items
&#9;local useScrollButtons = false
&#9;if dropDownItemCount &gt; 6 then
&#9;&#9;useScrollButtons = true
&#9;&#9;dropDownItemCount = 6
&#9;end
&#9;
&#9;local droppedDownMenu = Instance.new(&quot;TextButton&quot;)
&#9;droppedDownMenu.Name = &quot;List&quot;
&#9;droppedDownMenu.Text = &quot;&quot;
&#9;droppedDownMenu.BackgroundTransparency = 1
&#9;--droppedDownMenu.AutoButtonColor = true
&#9;if (whiteSkin) then
&#9;&#9;droppedDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton
&#9;else
&#9;&#9;droppedDownMenu.Style = Enum.ButtonStyle.RobloxButton
&#9;end
&#9;droppedDownMenu.Visible = false
&#9;droppedDownMenu.Active = true&#9;--Blocks clicks
&#9;droppedDownMenu.Position = UDim2.new(0,0,0,0)
&#9;droppedDownMenu.Size = UDim2.new(1,0, (1 + dropDownItemCount)*.8, 0)
&#9;droppedDownMenu.Parent = frame
&#9;droppedDownMenu.ZIndex = 2 + baseZIndex
&#9;local choiceButton = Instance.new(&quot;TextButton&quot;)
&#9;choiceButton.Name = &quot;ChoiceButton&quot;
&#9;choiceButton.BackgroundTransparency = 1
&#9;choiceButton.BorderSizePixel = 0
&#9;choiceButton.Text = &quot;ReplaceMe&quot;
&#9;choiceButton.TextColor3 = textColor
&#9;choiceButton.TextXAlignment = Enum.TextXAlignment.Left
&#9;choiceButton.TextYAlignment = Enum.TextYAlignment.Center
&#9;choiceButton.BackgroundColor3 = Color3.new(1, 1, 1)
&#9;choiceButton.Font = Enum.Font.Arial
&#9;choiceButton.FontSize = Enum.FontSize.Size18
&#9;if useScrollButtons then
&#9;&#9;choiceButton.Size = UDim2.new(1,-13, .8/((dropDownItemCount + 1)*.8),0)
&#9;else
&#9;&#9;choiceButton.Size = UDim2.new(1, 0, .8/((dropDownItemCount + 1)*.8),0)
&#9;end
&#9;choiceButton.TextWrap = true
&#9;choiceButton.ZIndex = 2 + baseZIndex
&#9;local areaSoak = Instance.new(&quot;TextButton&quot;)
&#9;areaSoak.Name = &quot;AreaSoak&quot;
&#9;areaSoak.Text = &quot;&quot;
&#9;areaSoak.BackgroundTransparency = 1
&#9;areaSoak.Active = true
&#9;areaSoak.Size = UDim2.new(1,0,1,0)
&#9;areaSoak.Visible = false
&#9;areaSoak.ZIndex = 3 + baseZIndex
&#9;local dropDownSelected = false
&#9;local scrollUpButton
&#9;local scrollDownButton
&#9;local scrollMouseCount = 0
&#9;local setZIndex = function(baseZIndex)
&#9;&#9;droppedDownMenu.ZIndex = baseZIndex +1
&#9;&#9;if scrollUpButton then
&#9;&#9;&#9;scrollUpButton.ZIndex = baseZIndex + 3
&#9;&#9;end
&#9;&#9;if scrollDownButton then
&#9;&#9;&#9;scrollDownButton.ZIndex = baseZIndex + 3
&#9;&#9;end
&#9;&#9;
&#9;&#9;local children = droppedDownMenu:GetChildren()
&#9;&#9;if children then
&#9;&#9;&#9;for i, child in ipairs(children) do
&#9;&#9;&#9;&#9;if child.Name == &quot;ChoiceButton&quot; then
&#9;&#9;&#9;&#9;&#9;child.ZIndex = baseZIndex + 2
&#9;&#9;&#9;&#9;elseif child.Name == &quot;ClickCaptureButton&quot; then
&#9;&#9;&#9;&#9;&#9;child.ZIndex = baseZIndex
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local scrollBarPosition = 1
&#9;local updateScroll = function()
&#9;&#9;if scrollUpButton then
&#9;&#9;&#9;scrollUpButton.Active = scrollBarPosition &gt; 1
&#9;&#9;end
&#9;&#9;if scrollDownButton then
&#9;&#9;&#9;scrollDownButton.Active = scrollBarPosition + dropDownItemCount &lt;= itemCount
&#9;&#9;end
&#9;&#9;local children = droppedDownMenu:GetChildren()
&#9;&#9;if not children then return end
&#9;&#9;local childNum = 1&#9;&#9;&#9;
&#9;&#9;for i, obj in ipairs(children) do
&#9;&#9;&#9;if obj.Name == &quot;ChoiceButton&quot; then
&#9;&#9;&#9;&#9;if childNum &lt; scrollBarPosition or childNum &gt;= scrollBarPosition + dropDownItemCount then
&#9;&#9;&#9;&#9;&#9;obj.Visible = false
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;obj.Position = UDim2.new(0,0,((childNum-scrollBarPosition+1)*.8)/((dropDownItemCount+1)*.8),0)
&#9;&#9;&#9;&#9;&#9;obj.Visible = true
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;obj.TextColor3 = textColor
&#9;&#9;&#9;&#9;obj.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;childNum = childNum + 1
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local toggleVisibility = function()
&#9;&#9;dropDownSelected = not dropDownSelected
&#9;&#9;areaSoak.Visible = not areaSoak.Visible
&#9;&#9;dropDownMenu.Visible = not dropDownSelected
&#9;&#9;droppedDownMenu.Visible = dropDownSelected
&#9;&#9;if dropDownSelected then
&#9;&#9;&#9;setZIndex(4 + baseZIndex)
&#9;&#9;else
&#9;&#9;&#9;setZIndex(2 + baseZIndex)
&#9;&#9;end
&#9;&#9;if useScrollButtons then
&#9;&#9;&#9;updateScroll()
&#9;&#9;end
&#9;end
&#9;droppedDownMenu.MouseButton1Click:connect(toggleVisibility)
&#9;local updateSelection = function(text)
&#9;&#9;local foundItem = false
&#9;&#9;local children = droppedDownMenu:GetChildren()
&#9;&#9;local childNum = 1
&#9;&#9;if children then
&#9;&#9;&#9;for i, obj in ipairs(children) do
&#9;&#9;&#9;&#9;if obj.Name == &quot;ChoiceButton&quot; then
&#9;&#9;&#9;&#9;&#9;if obj.Text == text then
&#9;&#9;&#9;&#9;&#9;&#9;obj.Font = Enum.Font.ArialBold
&#9;&#9;&#9;&#9;&#9;&#9;foundItem = true&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;scrollBarPosition = childNum&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;if (whiteSkin) then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;obj.TextColor3 = Color3.new(90/255,142/255,233/255)
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;obj.Font = Enum.Font.Arial
&#9;&#9;&#9;&#9;&#9;&#9;if (whiteSkin) then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;obj.TextColor3 = textColor
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;childNum = childNum + 1
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;if not text then
&#9;&#9;&#9;dropDownMenu.Text = &quot;Choose One&quot;
&#9;&#9;&#9;scrollBarPosition = 1
&#9;&#9;else
&#9;&#9;&#9;if not foundItem then
&#9;&#9;&#9;&#9;error(&quot;Invalid Selection Update -- &quot; .. text)
&#9;&#9;&#9;end
&#9;&#9;&#9;if scrollBarPosition + dropDownItemCount &gt; itemCount + 1 then
&#9;&#9;&#9;&#9;scrollBarPosition = itemCount - dropDownItemCount + 1
&#9;&#9;&#9;end
&#9;&#9;&#9;dropDownMenu.Text = text
&#9;&#9;end
&#9;end
&#9;
&#9;local function scrollDown()
&#9;&#9;if scrollBarPosition + dropDownItemCount &lt;= itemCount then
&#9;&#9;&#9;scrollBarPosition = scrollBarPosition + 1
&#9;&#9;&#9;updateScroll()
&#9;&#9;&#9;return true
&#9;&#9;end
&#9;&#9;return false
&#9;end
&#9;local function scrollUp()
&#9;&#9;if scrollBarPosition &gt; 1 then
&#9;&#9;&#9;scrollBarPosition = scrollBarPosition - 1
&#9;&#9;&#9;updateScroll()
&#9;&#9;&#9;return true
&#9;&#9;end
&#9;&#9;return false
&#9;end
&#9;
&#9;if useScrollButtons then
&#9;&#9;--Make some scroll buttons
&#9;&#9;scrollUpButton = Instance.new(&quot;ImageButton&quot;)
&#9;&#9;scrollUpButton.Name = &quot;ScrollUpButton&quot;
&#9;&#9;scrollUpButton.BackgroundTransparency = 1
&#9;&#9;scrollUpButton.Image = &quot;rbxasset://textures/ui/scrollbuttonUp.png&quot;
&#9;&#9;scrollUpButton.Size = UDim2.new(0,17,0,17)
&#9;&#9;scrollUpButton.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),0)
&#9;&#9;scrollUpButton.MouseButton1Click:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;&#9;&#9;end)
&#9;&#9;scrollUpButton.MouseLeave:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;&#9;&#9;end)
&#9;&#9;scrollUpButton.MouseButton1Down:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;
&#9;&#9;&#9;&#9;scrollUp()
&#9;&#9;&#9;&#9;local val = scrollMouseCount
&#9;&#9;&#9;&#9;wait(0.5)
&#9;&#9;&#9;&#9;while val == scrollMouseCount do
&#9;&#9;&#9;&#9;&#9;if scrollUp() == false then
&#9;&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;wait(0.1)
&#9;&#9;&#9;&#9;end&#9;&#9;&#9;&#9;
&#9;&#9;&#9;end)
&#9;&#9;scrollUpButton.Parent = droppedDownMenu
&#9;&#9;scrollDownButton = Instance.new(&quot;ImageButton&quot;)
&#9;&#9;scrollDownButton.Name = &quot;ScrollDownButton&quot;
&#9;&#9;scrollDownButton.BackgroundTransparency = 1
&#9;&#9;scrollDownButton.Image = &quot;rbxasset://textures/ui/scrollbuttonDown.png&quot;
&#9;&#9;scrollDownButton.Size = UDim2.new(0,17,0,17)
&#9;&#9;scrollDownButton.Position = UDim2.new(1,-11,1,-11)
&#9;&#9;scrollDownButton.Parent = droppedDownMenu
&#9;&#9;scrollDownButton.MouseButton1Click:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;&#9;&#9;end)
&#9;&#9;scrollDownButton.MouseLeave:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;&#9;&#9;end)
&#9;&#9;scrollDownButton.MouseButton1Down:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;&#9;&#9;&#9;scrollDown()
&#9;&#9;&#9;&#9;local val = scrollMouseCount
&#9;&#9;&#9;&#9;wait(0.5)
&#9;&#9;&#9;&#9;while val == scrollMouseCount do
&#9;&#9;&#9;&#9;&#9;if scrollDown() == false then
&#9;&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;wait(0.1)
&#9;&#9;&#9;&#9;end&#9;&#9;&#9;&#9;
&#9;&#9;&#9;end)&#9;
&#9;&#9;local scrollbar = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;scrollbar.Name = &quot;ScrollBar&quot;
&#9;&#9;scrollbar.Image = &quot;rbxasset://textures/ui/scrollbar.png&quot;
&#9;&#9;scrollbar.BackgroundTransparency = 1
&#9;&#9;scrollbar.Size = UDim2.new(0, 18, (dropDownItemCount*.8)/((dropDownItemCount+1)*.8), -(17) - 11 - 4)
&#9;&#9;scrollbar.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),17+2)
&#9;&#9;scrollbar.Parent = droppedDownMenu
&#9;end
&#9;for i,item in ipairs(items) do
&#9;&#9;-- needed to maintain local scope for items in event listeners below
&#9;&#9;local button = choiceButton:clone()
&#9;&#9;if forRoblox then
&#9;&#9;&#9;button.RobloxLocked = true
&#9;&#9;end&#9;&#9;
&#9;&#9;button.Text = item
&#9;&#9;button.Parent = droppedDownMenu
&#9;&#9;if (whiteSkin) then
&#9;&#9;&#9;button.TextColor3 = textColor
&#9;&#9;end
&#9;&#9;button.MouseButton1Click:connect(function()
&#9;&#9;&#9;--Remove Highlight
&#9;&#9;&#9;if (not whiteSkin) then
&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;end
&#9;&#9;&#9;button.BackgroundTransparency = 1
&#9;&#9;&#9;updateSelection(item)
&#9;&#9;&#9;onSelect(item)
&#9;&#9;&#9;toggleVisibility()
&#9;&#9;end)
&#9;&#9;button.MouseEnter:connect(function()
&#9;&#9;&#9;--Add Highlight&#9;
&#9;&#9;&#9;if (not whiteSkin) then
&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(0,0,0)
&#9;&#9;&#9;end
&#9;&#9;&#9;button.BackgroundTransparency = 0
&#9;&#9;end)
&#9;&#9;button.MouseLeave:connect(function()
&#9;&#9;&#9;--Remove Highlight
&#9;&#9;&#9;if (not whiteSkin) then
&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;end
&#9;&#9;&#9;button.BackgroundTransparency = 1
&#9;&#9;end)
&#9;end
&#9;--This does the initial layout of the buttons&#9;
&#9;updateScroll()
&#9;
&#9;frame.AncestryChanged:connect(function(child,parent)
&#9;&#9;if parent == nil then
&#9;&#9;&#9;areaSoak.Parent = nil
&#9;&#9;else
&#9;&#9;&#9;areaSoak.Parent = getScreenGuiAncestor(frame)
&#9;&#9;end
&#9;end)
&#9;dropDownMenu.MouseButton1Click:connect(toggleVisibility)
&#9;areaSoak.MouseButton1Click:connect(toggleVisibility)
&#9;return frame, updateSelection
end
t.CreatePropertyDropDownMenu = function(instance, property, enum)
&#9;local items = enum:GetEnumItems()
&#9;local names = {}
&#9;local nameToItem = {}
&#9;for i,obj in ipairs(items) do
&#9;&#9;names[i] = obj.Name
&#9;&#9;nameToItem[obj.Name] = obj
&#9;end
&#9;local frame
&#9;local updateSelection
&#9;frame, updateSelection = t.CreateDropDownMenu(names, function(text) instance[property] = nameToItem[text] end)
&#9;ScopedConnect(frame, instance, &quot;Changed&quot;,
&#9;&#9;function(prop)
&#9;&#9;&#9;if prop == property then
&#9;&#9;&#9;&#9;updateSelection(instance[property].Name)
&#9;&#9;&#9;end
&#9;&#9;end,
&#9;&#9;function()
&#9;&#9;&#9;updateSelection(instance[property].Name)
&#9;&#9;end)
&#9;return frame
end
t.GetFontHeight = function(font, fontSize)
&#9;if font == nil or fontSize == nil then
&#9;&#9;error(&quot;Font and FontSize must be non-nil&quot;)
&#9;end
&#9;if font == Enum.Font.Legacy then
&#9;&#9;if fontSize == Enum.FontSize.Size8 then
&#9;&#9;&#9;return 12
&#9;&#9;elseif fontSize == Enum.FontSize.Size9 then
&#9;&#9;&#9;return 14
&#9;&#9;elseif fontSize == Enum.FontSize.Size10 then
&#9;&#9;&#9;return 15
&#9;&#9;elseif fontSize == Enum.FontSize.Size11 then
&#9;&#9;&#9;return 17
&#9;&#9;elseif fontSize == Enum.FontSize.Size12 then
&#9;&#9;&#9;return 18
&#9;&#9;elseif fontSize == Enum.FontSize.Size14 then
&#9;&#9;&#9;return 21
&#9;&#9;elseif fontSize == Enum.FontSize.Size18 then
&#9;&#9;&#9;return 27
&#9;&#9;elseif fontSize == Enum.FontSize.Size24 then
&#9;&#9;&#9;return 36
&#9;&#9;elseif fontSize == Enum.FontSize.Size36 then
&#9;&#9;&#9;return 54
&#9;&#9;elseif fontSize == Enum.FontSize.Size48 then
&#9;&#9;&#9;return 72
&#9;&#9;else
&#9;&#9;&#9;error(&quot;Unknown FontSize&quot;)
&#9;&#9;end
&#9;elseif font == Enum.Font.Arial or font == Enum.Font.ArialBold then
&#9;&#9;if fontSize == Enum.FontSize.Size8 then
&#9;&#9;&#9;return 8
&#9;&#9;elseif fontSize == Enum.FontSize.Size9 then
&#9;&#9;&#9;return 9
&#9;&#9;elseif fontSize == Enum.FontSize.Size10 then
&#9;&#9;&#9;return 10
&#9;&#9;elseif fontSize == Enum.FontSize.Size11 then
&#9;&#9;&#9;return 11
&#9;&#9;elseif fontSize == Enum.FontSize.Size12 then
&#9;&#9;&#9;return 12
&#9;&#9;elseif fontSize == Enum.FontSize.Size14 then
&#9;&#9;&#9;return 14
&#9;&#9;elseif fontSize == Enum.FontSize.Size18 then
&#9;&#9;&#9;return 18
&#9;&#9;elseif fontSize == Enum.FontSize.Size24 then
&#9;&#9;&#9;return 24
&#9;&#9;elseif fontSize == Enum.FontSize.Size36 then
&#9;&#9;&#9;return 36
&#9;&#9;elseif fontSize == Enum.FontSize.Size48 then
&#9;&#9;&#9;return 48
&#9;&#9;else
&#9;&#9;&#9;error(&quot;Unknown FontSize&quot;)
&#9;&#9;end
&#9;else
&#9;&#9;error(&quot;Unknown Font &quot; .. font)
&#9;end
end
local function layoutGuiObjectsHelper(frame, guiObjects, settingsTable)
&#9;local totalPixels = frame.AbsoluteSize.Y
&#9;local pixelsRemaining = frame.AbsoluteSize.Y
&#9;for i, child in ipairs(guiObjects) do
&#9;&#9;if child:IsA(&quot;TextLabel&quot;) or child:IsA(&quot;TextButton&quot;) then
&#9;&#9;&#9;local isLabel = child:IsA(&quot;TextLabel&quot;)
&#9;&#9;&#9;if isLabel then
&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - settingsTable[&quot;TextLabelPositionPadY&quot;]
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - settingsTable[&quot;TextButtonPositionPadY&quot;]
&#9;&#9;&#9;end
&#9;&#9;&#9;child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
&#9;&#9;&#9;child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, pixelsRemaining)
&#9;&#9;&#9;if child.TextFits and child.TextBounds.Y &lt; pixelsRemaining then
&#9;&#9;&#9;&#9;child.Visible = true
&#9;&#9;&#9;&#9;if isLabel then
&#9;&#9;&#9;&#9;&#9;child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable[&quot;TextLabelSizePadY&quot;])
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable[&quot;TextButtonSizePadY&quot;])
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;while not child.TextFits do
&#9;&#9;&#9;&#9;&#9;child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.AbsoluteSize.Y + 1)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y&#9;&#9;
&#9;&#9;&#9;&#9;if isLabel then
&#9;&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - settingsTable[&quot;TextLabelPositionPadY&quot;]
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - settingsTable[&quot;TextButtonPositionPadY&quot;]
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;&#9;pixelsRemaining = -1
&#9;&#9;&#9;end&#9;&#9;&#9;
&#9;&#9;else
&#9;&#9;&#9;--GuiObject
&#9;&#9;&#9;child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
&#9;&#9;&#9;child.Visible = (pixelsRemaining &gt;= 0)
&#9;&#9;end
&#9;end
end
t.LayoutGuiObjects = function(frame, guiObjects, settingsTable)
&#9;if not frame:IsA(&quot;GuiObject&quot;) then
&#9;&#9;error(&quot;Frame must be a GuiObject&quot;)
&#9;end
&#9;for i, child in ipairs(guiObjects) do
&#9;&#9;if not child:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;error(&quot;All elements that are layed out must be of type GuiObject&quot;)
&#9;&#9;end
&#9;end
&#9;if not settingsTable then
&#9;&#9;settingsTable = {}
&#9;end
&#9;if not settingsTable[&quot;TextLabelSizePadY&quot;] then
&#9;&#9;settingsTable[&quot;TextLabelSizePadY&quot;] = 0
&#9;end
&#9;if not settingsTable[&quot;TextLabelPositionPadY&quot;] then
&#9;&#9;settingsTable[&quot;TextLabelPositionPadY&quot;] = 0
&#9;end
&#9;if not settingsTable[&quot;TextButtonSizePadY&quot;] then
&#9;&#9;settingsTable[&quot;TextButtonSizePadY&quot;] = 12
&#9;end
&#9;if not settingsTable[&quot;TextButtonPositionPadY&quot;] then
&#9;&#9;settingsTable[&quot;TextButtonPositionPadY&quot;] = 2
&#9;end
&#9;--Wrapper frame takes care of styled objects
&#9;local wrapperFrame = Instance.new(&quot;Frame&quot;)
&#9;wrapperFrame.Name = &quot;WrapperFrame&quot;
&#9;wrapperFrame.BackgroundTransparency = 1
&#9;wrapperFrame.Size = UDim2.new(1,0,1,0)
&#9;wrapperFrame.Parent = frame
&#9;for i, child in ipairs(guiObjects) do
&#9;&#9;child.Parent = wrapperFrame
&#9;end
&#9;local recalculate = function()
&#9;&#9;wait()
&#9;&#9;layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable)
&#9;end
&#9;
&#9;frame.Changed:connect(
&#9;&#9;function(prop)
&#9;&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;&#9;--Wait a heartbeat for it to sync in
&#9;&#9;&#9;&#9;recalculate(nil)
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;frame.AncestryChanged:connect(recalculate)
&#9;layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable)
end
t.CreateSlider = function(steps,width,position)
&#9;local sliderGui = Instance.new(&quot;Frame&quot;)
&#9;sliderGui.Size = UDim2.new(1,0,1,0)
&#9;sliderGui.BackgroundTransparency = 1
&#9;sliderGui.Name = &quot;SliderGui&quot;
&#9;
&#9;local sliderSteps = Instance.new(&quot;IntValue&quot;)
&#9;sliderSteps.Name = &quot;SliderSteps&quot;
&#9;sliderSteps.Value = steps
&#9;sliderSteps.Parent = sliderGui
&#9;
&#9;local areaSoak = Instance.new(&quot;TextButton&quot;)
&#9;areaSoak.Name = &quot;AreaSoak&quot;
&#9;areaSoak.Text = &quot;&quot;
&#9;areaSoak.BackgroundTransparency = 1
&#9;areaSoak.Active = false
&#9;areaSoak.Size = UDim2.new(1,0,1,0)
&#9;areaSoak.Visible = false
&#9;areaSoak.ZIndex = 4
&#9;
&#9;sliderGui.AncestryChanged:connect(function(child,parent)
&#9;&#9;if parent == nil then
&#9;&#9;&#9;areaSoak.Parent = nil
&#9;&#9;else
&#9;&#9;&#9;areaSoak.Parent = getScreenGuiAncestor(sliderGui)
&#9;&#9;end
&#9;end)
&#9;
&#9;local sliderPosition = Instance.new(&quot;IntValue&quot;)
&#9;sliderPosition.Name = &quot;SliderPosition&quot;
&#9;sliderPosition.Value = 0
&#9;sliderPosition.Parent = sliderGui
&#9;
&#9;local id = math.random(1,100)
&#9;
&#9;local bar = Instance.new(&quot;TextButton&quot;)
&#9;bar.Text = &quot;&quot;
&#9;bar.AutoButtonColor = false
&#9;bar.Name = &quot;Bar&quot;
&#9;bar.BackgroundColor3 = Color3.new(0,0,0)
&#9;if type(width) == &quot;number&quot; then
&#9;&#9;bar.Size = UDim2.new(0,width,0,5)
&#9;else
&#9;&#9;bar.Size = UDim2.new(0,200,0,5)
&#9;end
&#9;bar.BorderColor3 = Color3.new(95/255,95/255,95/255)
&#9;bar.ZIndex = 2
&#9;bar.Parent = sliderGui
&#9;
&#9;if position[&quot;X&quot;] and position[&quot;X&quot;][&quot;Scale&quot;] and position[&quot;X&quot;][&quot;Offset&quot;] and position[&quot;Y&quot;] and position[&quot;Y&quot;][&quot;Scale&quot;] and position[&quot;Y&quot;][&quot;Offset&quot;] then
&#9;&#9;bar.Position = position
&#9;end
&#9;
&#9;local slider = Instance.new(&quot;ImageButton&quot;)
&#9;slider.Name = &quot;Slider&quot;
&#9;slider.BackgroundTransparency = 1
&#9;slider.Image = &quot;rbxasset://textures/ui/Slider.png&quot;
&#9;slider.Position = UDim2.new(0,0,0.5,-10)
&#9;slider.Size = UDim2.new(0,20,0,20)
&#9;slider.ZIndex = 3
&#9;slider.Parent = bar
&#9;
&#9;local areaSoakMouseMoveCon = nil
&#9;
&#9;areaSoak.MouseLeave:connect(function()
&#9;&#9;if areaSoak.Visible then
&#9;&#9;&#9;cancelSlide(areaSoak)
&#9;&#9;end
&#9;end)
&#9;areaSoak.MouseButton1Up:connect(function()
&#9;&#9;if areaSoak.Visible then
&#9;&#9;&#9;cancelSlide(areaSoak)
&#9;&#9;end
&#9;end)
&#9;
&#9;slider.MouseButton1Down:connect(function()
&#9;&#9;areaSoak.Visible = true
&#9;&#9;if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
&#9;&#9;areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y)
&#9;&#9;&#9;setSliderPos(x,slider,sliderPosition,bar,steps)
&#9;&#9;end)
&#9;end)
&#9;
&#9;slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end)
&#9;
&#9;sliderPosition.Changed:connect(function(prop)
&#9;&#9;sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value))
&#9;&#9;local relativePosX = (sliderPosition.Value - 1) / (steps - 1)
&#9;&#9;slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
&#9;end)
&#9;
&#9;bar.MouseButton1Down:connect(function(x,y)
&#9;&#9;setSliderPos(x,slider,sliderPosition,bar,steps)
&#9;end)
&#9;
&#9;return sliderGui, sliderPosition, sliderSteps
end
t.CreateSliderNew = function(steps,width,position)
&#9;local sliderGui = Instance.new(&quot;Frame&quot;)
&#9;sliderGui.Size = UDim2.new(1,0,1,0)
&#9;sliderGui.BackgroundTransparency = 1
&#9;sliderGui.Name = &quot;SliderGui&quot;
&#9;
&#9;local sliderSteps = Instance.new(&quot;IntValue&quot;)
&#9;sliderSteps.Name = &quot;SliderSteps&quot;
&#9;sliderSteps.Value = steps
&#9;sliderSteps.Parent = sliderGui
&#9;
&#9;local areaSoak = Instance.new(&quot;TextButton&quot;)
&#9;areaSoak.Name = &quot;AreaSoak&quot;
&#9;areaSoak.Text = &quot;&quot;
&#9;areaSoak.BackgroundTransparency = 1
&#9;areaSoak.Active = false
&#9;areaSoak.Size = UDim2.new(1,0,1,0)
&#9;areaSoak.Visible = false
&#9;areaSoak.ZIndex = 6
&#9;
&#9;sliderGui.AncestryChanged:connect(function(child,parent)
&#9;&#9;if parent == nil then
&#9;&#9;&#9;areaSoak.Parent = nil
&#9;&#9;else
&#9;&#9;&#9;areaSoak.Parent = getScreenGuiAncestor(sliderGui)
&#9;&#9;end
&#9;end)
&#9;
&#9;local sliderPosition = Instance.new(&quot;IntValue&quot;)
&#9;sliderPosition.Name = &quot;SliderPosition&quot;
&#9;sliderPosition.Value = 0
&#9;sliderPosition.Parent = sliderGui
&#9;
&#9;local id = math.random(1,100)
&#9;
&#9;local sliderBarImgHeight = 7
&#9;local sliderBarCapImgWidth = 4
&#9;local bar = Instance.new(&quot;ImageButton&quot;)
&#9;bar.BackgroundTransparency = 1
&#9;bar.Image = &quot;rbxasset://textures/ui/Slider-BKG-Center.png&quot;
&#9;bar.Name = &quot;Bar&quot;
&#9;local displayWidth = 200
&#9;if type(width) == &quot;number&quot; then
&#9;&#9;bar.Size = UDim2.new(0,width - (sliderBarCapImgWidth * 2),0,sliderBarImgHeight)
&#9;&#9;displayWidth = width - (sliderBarCapImgWidth * 2)
&#9;else
&#9;&#9;bar.Size = UDim2.new(0,200,0,sliderBarImgHeight)
&#9;end
&#9;bar.ZIndex = 3
&#9;bar.Parent = sliderGui&#9;
&#9;if position[&quot;X&quot;] and position[&quot;X&quot;][&quot;Scale&quot;] and position[&quot;X&quot;][&quot;Offset&quot;] and position[&quot;Y&quot;] and position[&quot;Y&quot;][&quot;Scale&quot;] and position[&quot;Y&quot;][&quot;Offset&quot;] then
&#9;&#9;bar.Position = position
&#9;end
&#9;local barLeft = bar:clone()
&#9;barLeft.Name = &quot;BarLeft&quot;
&#9;barLeft.Image = &quot;rbxasset://textures/ui/Slider-BKG-Left-Cap.png&quot;
&#9;barLeft.Size = UDim2.new(0, sliderBarCapImgWidth, 0, sliderBarImgHeight)
&#9;barLeft.Position = UDim2.new(position.X.Scale, position.X.Offset - sliderBarCapImgWidth, position.Y.Scale, position.Y.Offset)
&#9;barLeft.Parent = sliderGui&#9;
&#9;barLeft.ZIndex = 3
&#9;local barRight = barLeft:clone()
&#9;barRight.Name = &quot;BarRight&quot;
&#9;barRight.Image = &quot;rbxasset://textures/ui/Slider-BKG-Right-Cap.png&quot;
&#9;barRight.Position = UDim2.new(position.X.Scale, position.X.Offset + displayWidth, position.Y.Scale, position.Y.Offset)
&#9;barRight.Parent = sliderGui&#9;
&#9;local fillLeft = barLeft:clone()
&#9;fillLeft.Name = &quot;FillLeft&quot;
&#9;fillLeft.Image = &quot;rbxasset://textures/ui/Slider-Fill-Left-Cap.png&quot;
&#9;fillLeft.Parent = sliderGui&#9;
&#9;fillLeft.ZIndex = 4
&#9;local fill = fillLeft:clone()
&#9;fill.Name = &quot;Fill&quot;
&#9;fill.Image = &quot;rbxasset://textures/ui/Slider-Fill-Center.png&quot;
&#9;fill.Parent = bar&#9;
&#9;fill.ZIndex = 4
&#9;fill.Position = UDim2.new(0, 0, 0, 0)
&#9;fill.Size = UDim2.new(0.5, 0, 1, 0)
--&#9;bar.Visible = false
&#9;local slider = Instance.new(&quot;ImageButton&quot;)
&#9;slider.Name = &quot;Slider&quot;
&#9;slider.BackgroundTransparency = 1
&#9;slider.Image = &quot;rbxasset://textures/ui/slider_new_tab.png&quot;
&#9;slider.Position = UDim2.new(0,0,0.5,-14)
&#9;slider.Size = UDim2.new(0,28,0,28)
&#9;slider.ZIndex = 5
&#9;slider.Parent = bar
&#9;
&#9;local areaSoakMouseMoveCon = nil
&#9;
&#9;areaSoak.MouseLeave:connect(function()
&#9;&#9;if areaSoak.Visible then
&#9;&#9;&#9;cancelSlide(areaSoak)
&#9;&#9;end
&#9;end)
&#9;areaSoak.MouseButton1Up:connect(function()
&#9;&#9;if areaSoak.Visible then
&#9;&#9;&#9;cancelSlide(areaSoak)
&#9;&#9;end
&#9;end)
&#9;
&#9;slider.MouseButton1Down:connect(function()
&#9;&#9;areaSoak.Visible = true
&#9;&#9;if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
&#9;&#9;areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y)
&#9;&#9;&#9;setSliderPos(x,slider,sliderPosition,bar,steps)
&#9;&#9;end)
&#9;end)
&#9;
&#9;slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end)
&#9;
&#9;sliderPosition.Changed:connect(function(prop)
&#9;&#9;sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value))
&#9;&#9;local relativePosX = (sliderPosition.Value - 1) / (steps - 1)
&#9;&#9;slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
&#9;&#9;fill.Size = UDim2.new(relativePosX, 0, 1, 0)
&#9;end)
&#9;
&#9;bar.MouseButton1Down:connect(function(x,y)
&#9;&#9;setSliderPos(x,slider,sliderPosition,bar,steps)
&#9;end)
&#9;return sliderGui, sliderPosition, sliderSteps
end
t.CreateTrueScrollingFrame = function()
&#9;local lowY = nil
&#9;local highY = nil
&#9;
&#9;local dragCon = nil
&#9;local upCon = nil
&#9;local internalChange = false
&#9;local descendantsChangeConMap = {}
&#9;local scrollingFrame = Instance.new(&quot;Frame&quot;)
&#9;scrollingFrame.Name = &quot;ScrollingFrame&quot;
&#9;scrollingFrame.Active = true
&#9;scrollingFrame.Size = UDim2.new(1,0,1,0)
&#9;scrollingFrame.ClipsDescendants = true
&#9;local controlFrame = Instance.new(&quot;Frame&quot;)
&#9;controlFrame.Name = &quot;ControlFrame&quot;
&#9;controlFrame.BackgroundTransparency = 1
&#9;controlFrame.Size = UDim2.new(0,18,1,0)
&#9;controlFrame.Position = UDim2.new(1,-20,0,0)
&#9;controlFrame.Parent = scrollingFrame
&#9;
&#9;local scrollBottom = Instance.new(&quot;BoolValue&quot;)
&#9;scrollBottom.Value = false
&#9;scrollBottom.Name = &quot;ScrollBottom&quot;
&#9;scrollBottom.Parent = controlFrame
&#9;
&#9;local scrollUp = Instance.new(&quot;BoolValue&quot;)
&#9;scrollUp.Value = false
&#9;scrollUp.Name = &quot;scrollUp&quot;
&#9;scrollUp.Parent = controlFrame
&#9;local scrollUpButton = Instance.new(&quot;TextButton&quot;)
&#9;scrollUpButton.Name = &quot;ScrollUpButton&quot;
&#9;scrollUpButton.Text = &quot;&quot;
&#9;scrollUpButton.AutoButtonColor = false
&#9;scrollUpButton.BackgroundColor3 = Color3.new(0,0,0)
&#9;scrollUpButton.BorderColor3 = Color3.new(1,1,1)
&#9;scrollUpButton.BackgroundTransparency = 0.5
&#9;scrollUpButton.Size = UDim2.new(0,18,0,18)
&#9;scrollUpButton.ZIndex = 2
&#9;scrollUpButton.Parent = controlFrame
&#9;for i = 1, 6 do
&#9;&#9;local triFrame = Instance.new(&quot;Frame&quot;)
&#9;&#9;triFrame.BorderColor3 = Color3.new(1,1,1)
&#9;&#9;triFrame.Name = &quot;tri&quot; .. tostring(i)
&#9;&#9;triFrame.ZIndex = 3
&#9;&#9;triFrame.BackgroundTransparency = 0.5
&#9;&#9;triFrame.Size = UDim2.new(0,12 - ((i -1) * 2),0,0)
&#9;&#9;triFrame.Position = UDim2.new(0,3 + (i -1),0.5,2 - (i -1))
&#9;&#9;triFrame.Parent = scrollUpButton
&#9;end
&#9;scrollUpButton.MouseEnter:connect(function()
&#9;&#9;scrollUpButton.BackgroundTransparency = 0.1
&#9;&#9;local upChildren = scrollUpButton:GetChildren()
&#9;&#9;for i = 1, #upChildren do
&#9;&#9;&#9;upChildren[i].BackgroundTransparency = 0.1
&#9;&#9;end
&#9;end)
&#9;scrollUpButton.MouseLeave:connect(function()
&#9;&#9;scrollUpButton.BackgroundTransparency = 0.5
&#9;&#9;local upChildren = scrollUpButton:GetChildren()
&#9;&#9;for i = 1, #upChildren do
&#9;&#9;&#9;upChildren[i].BackgroundTransparency = 0.5
&#9;&#9;end
&#9;end)
&#9;local scrollDownButton = scrollUpButton:clone()
&#9;scrollDownButton.Name = &quot;ScrollDownButton&quot;
&#9;scrollDownButton.Position = UDim2.new(0,0,1,-18)
&#9;local downChildren = scrollDownButton:GetChildren()
&#9;for i = 1, #downChildren do
&#9;&#9;downChildren[i].Position = UDim2.new(0,3 + (i -1),0.5,-2 + (i - 1))
&#9;end
&#9;scrollDownButton.MouseEnter:connect(function()
&#9;&#9;scrollDownButton.BackgroundTransparency = 0.1
&#9;&#9;local downChildren = scrollDownButton:GetChildren()
&#9;&#9;for i = 1, #downChildren do
&#9;&#9;&#9;downChildren[i].BackgroundTransparency = 0.1
&#9;&#9;end
&#9;end)
&#9;scrollDownButton.MouseLeave:connect(function()
&#9;&#9;scrollDownButton.BackgroundTransparency = 0.5
&#9;&#9;local downChildren = scrollDownButton:GetChildren()
&#9;&#9;for i = 1, #downChildren do
&#9;&#9;&#9;downChildren[i].BackgroundTransparency = 0.5
&#9;&#9;end
&#9;end)
&#9;scrollDownButton.Parent = controlFrame
&#9;
&#9;local scrollTrack = Instance.new(&quot;Frame&quot;)
&#9;scrollTrack.Name = &quot;ScrollTrack&quot;
&#9;scrollTrack.BackgroundTransparency = 1
&#9;scrollTrack.Size = UDim2.new(0,18,1,-38)
&#9;scrollTrack.Position = UDim2.new(0,0,0,19)
&#9;scrollTrack.Parent = controlFrame
&#9;local scrollbar = Instance.new(&quot;TextButton&quot;)
&#9;scrollbar.BackgroundColor3 = Color3.new(0,0,0)
&#9;scrollbar.BorderColor3 = Color3.new(1,1,1)
&#9;scrollbar.BackgroundTransparency = 0.5
&#9;scrollbar.AutoButtonColor = false
&#9;scrollbar.Text = &quot;&quot;
&#9;scrollbar.Active = true
&#9;scrollbar.Name = &quot;ScrollBar&quot;
&#9;scrollbar.ZIndex = 2
&#9;scrollbar.BackgroundTransparency = 0.5
&#9;scrollbar.Size = UDim2.new(0, 18, 0.1, 0)
&#9;scrollbar.Position = UDim2.new(0,0,0,0)
&#9;scrollbar.Parent = scrollTrack
&#9;local scrollNub = Instance.new(&quot;Frame&quot;)
&#9;scrollNub.Name = &quot;ScrollNub&quot;
&#9;scrollNub.BorderColor3 = Color3.new(1,1,1)
&#9;scrollNub.Size = UDim2.new(0,10,0,0)
&#9;scrollNub.Position = UDim2.new(0.5,-5,0.5,0)
&#9;scrollNub.ZIndex = 2
&#9;scrollNub.BackgroundTransparency = 0.5
&#9;scrollNub.Parent = scrollbar
&#9;local newNub = scrollNub:clone()
&#9;newNub.Position = UDim2.new(0.5,-5,0.5,-2)
&#9;newNub.Parent = scrollbar
&#9;
&#9;local lastNub = scrollNub:clone()
&#9;lastNub.Position = UDim2.new(0.5,-5,0.5,2)
&#9;lastNub.Parent = scrollbar
&#9;scrollbar.MouseEnter:connect(function()
&#9;&#9;scrollbar.BackgroundTransparency = 0.1
&#9;&#9;scrollNub.BackgroundTransparency = 0.1
&#9;&#9;newNub.BackgroundTransparency = 0.1
&#9;&#9;lastNub.BackgroundTransparency = 0.1
&#9;end)
&#9;scrollbar.MouseLeave:connect(function()
&#9;&#9;scrollbar.BackgroundTransparency = 0.5
&#9;&#9;scrollNub.BackgroundTransparency = 0.5
&#9;&#9;newNub.BackgroundTransparency = 0.5
&#9;&#9;lastNub.BackgroundTransparency = 0.5
&#9;end)
&#9;local mouseDrag = Instance.new(&quot;ImageButton&quot;)
&#9;mouseDrag.Active = false
&#9;mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0)
&#9;mouseDrag.AutoButtonColor = false
&#9;mouseDrag.BackgroundTransparency = 1
&#9;mouseDrag.Name = &quot;mouseDrag&quot;
&#9;mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0)
&#9;mouseDrag.ZIndex = 10
&#9;
&#9;local function positionScrollBar(x,y,offset)
&#9;&#9;local oldPos = scrollbar.Position
&#9;&#9;if y &lt; scrollTrack.AbsolutePosition.y then
&#9;&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0)
&#9;&#9;&#9;return (oldPos ~= scrollbar.Position)
&#9;&#9;end
&#9;&#9;
&#9;&#9;local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y
&#9;&#9;if y &gt; (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then
&#9;&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0)
&#9;&#9;&#9;return (oldPos ~= scrollbar.Position)
&#9;&#9;end
&#9;&#9;local newScaleYPos = (y - scrollTrack.AbsolutePosition.y - offset)/scrollTrack.AbsoluteSize.y
&#9;&#9;if newScaleYPos + relativeSize &gt; 1 then
&#9;&#9;&#9;newScaleYPos = 1 - relativeSize
&#9;&#9;&#9;scrollBottom.Value = true
&#9;&#9;&#9;scrollUp.Value = false
&#9;&#9;elseif newScaleYPos &lt;= 0 then
&#9;&#9;&#9;newScaleYPos = 0
&#9;&#9;&#9;scrollUp.Value = true
&#9;&#9;&#9;scrollBottom.Value = false
&#9;&#9;else
&#9;&#9;&#9;scrollUp.Value = false
&#9;&#9;&#9;scrollBottom.Value = false
&#9;&#9;end
&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,newScaleYPos,0)
&#9;&#9;
&#9;&#9;return (oldPos ~= scrollbar.Position)
&#9;end
&#9;local function drillDownSetHighLow(instance)
&#9;&#9;if not instance or not instance:IsA(&quot;GuiObject&quot;) then return end
&#9;&#9;if instance == controlFrame then return end
&#9;&#9;if instance:IsDescendantOf(controlFrame) then return end
&#9;&#9;if not instance.Visible then return end
&#9;&#9;if lowY and lowY &gt; instance.AbsolutePosition.Y then
&#9;&#9;&#9;lowY = instance.AbsolutePosition.Y
&#9;&#9;elseif not lowY then
&#9;&#9;&#9;lowY = instance.AbsolutePosition.Y
&#9;&#9;end
&#9;&#9;if highY and highY &lt; (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) then
&#9;&#9;&#9;highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
&#9;&#9;elseif not highY then
&#9;&#9;&#9;highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
&#9;&#9;end
&#9;&#9;local children = instance:GetChildren()
&#9;&#9;for i = 1, #children do
&#9;&#9;&#9;drillDownSetHighLow(children[i])
&#9;&#9;end
&#9;end
&#9;local function resetHighLow()
&#9;&#9;local firstChildren = scrollingFrame:GetChildren()
&#9;&#9;for i = 1, #firstChildren do
&#9;&#9;&#9;drillDownSetHighLow(firstChildren[i])
&#9;&#9;end
&#9;end
&#9;local function recalculate()
&#9;&#9;internalChange = true
&#9;&#9;local percentFrame = 0
&#9;&#9;if scrollbar.Position.Y.Scale &gt; 0 then
&#9;&#9;&#9;if scrollbar.Visible then
&#9;&#9;&#9;&#9;percentFrame = scrollbar.Position.Y.Scale/((scrollTrack.AbsoluteSize.Y - scrollbar.AbsoluteSize.Y)/scrollTrack.AbsoluteSize.Y)
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;percentFrame = 0
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;if percentFrame &gt; 0.99 then percentFrame = 1 end
&#9;&#9;local hiddenYAmount = (scrollingFrame.AbsoluteSize.Y - (highY - lowY)) * percentFrame
&#9;&#9;
&#9;&#9;local guiChildren = scrollingFrame:GetChildren()
&#9;&#9;for i = 1, #guiChildren do
&#9;&#9;&#9;if guiChildren[i] ~= controlFrame then
&#9;&#9;&#9;&#9;guiChildren[i].Position = UDim2.new(guiChildren[i].Position.X.Scale,guiChildren[i].Position.X.Offset,
&#9;&#9;&#9;&#9;&#9;0, math.ceil(guiChildren[i].AbsolutePosition.Y) - math.ceil(lowY) + hiddenYAmount)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;lowY = nil
&#9;&#9;highY = nil
&#9;&#9;resetHighLow()
&#9;&#9;internalChange = false
&#9;end
&#9;local function setSliderSizeAndPosition()
&#9;&#9;if not highY or not lowY then return end
&#9;&#9;local totalYSpan = math.abs(highY - lowY)
&#9;&#9;if totalYSpan == 0 then
&#9;&#9;&#9;scrollbar.Visible = false
&#9;&#9;&#9;scrollDownButton.Visible = false
&#9;&#9;&#9;scrollUpButton.Visible = false
&#9;&#9;&#9;if dragCon then dragCon:disconnect() dragCon = nil end
&#9;&#9;&#9;if upCon then upCon:disconnect() upCon = nil end
&#9;&#9;&#9;return
&#9;&#9;end
&#9;&#9;local percentShown = scrollingFrame.AbsoluteSize.Y/totalYSpan
&#9;&#9;if percentShown &gt;= 1 then
&#9;&#9;&#9;scrollbar.Visible = false
&#9;&#9;&#9;scrollDownButton.Visible = false
&#9;&#9;&#9;scrollUpButton.Visible = false
&#9;&#9;&#9;recalculate()
&#9;&#9;else
&#9;&#9;&#9;scrollbar.Visible = true
&#9;&#9;&#9;scrollDownButton.Visible = true
&#9;&#9;&#9;scrollUpButton.Visible = true
&#9;&#9;&#9;scrollbar.Size = UDim2.new(scrollbar.Size.X.Scale,scrollbar.Size.X.Offset,percentShown,0)
&#9;&#9;end
&#9;&#9;local percentPosition = (scrollingFrame.AbsolutePosition.Y - lowY)/totalYSpan
&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,percentPosition,-scrollbar.AbsoluteSize.X/2)
&#9;&#9;if scrollbar.AbsolutePosition.y &lt; scrollTrack.AbsolutePosition.y then
&#9;&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0)
&#9;&#9;end
&#9;&#9;if (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.Y) &gt; (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then
&#9;&#9;&#9;local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y
&#9;&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0)
&#9;&#9;end
&#9;end
&#9;
&#9;local buttonScrollAmountPixels = 7
&#9;local reentrancyGuardScrollUp = false
&#9;local function doScrollUp()
&#9;&#9;if reentrancyGuardScrollUp then return end
&#9;&#9;
&#9;&#9;reentrancyGuardScrollUp = true
&#9;&#9;&#9;if positionScrollBar(0,scrollbar.AbsolutePosition.Y - buttonScrollAmountPixels,0) then
&#9;&#9;&#9;&#9;recalculate()
&#9;&#9;&#9;end
&#9;&#9;reentrancyGuardScrollUp = false
&#9;end
&#9;
&#9;local reentrancyGuardScrollDown = false
&#9;local function doScrollDown()
&#9;&#9;if reentrancyGuardScrollDown then return end
&#9;&#9;
&#9;&#9;reentrancyGuardScrollDown = true
&#9;&#9;&#9;if positionScrollBar(0,scrollbar.AbsolutePosition.Y + buttonScrollAmountPixels,0) then
&#9;&#9;&#9;&#9;recalculate()
&#9;&#9;&#9;end
&#9;&#9;reentrancyGuardScrollDown = false
&#9;end
&#9;local function scrollUp(mouseYPos)
&#9;&#9;if scrollUpButton.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local current = scrollStamp
&#9;&#9;&#9;local upCon
&#9;&#9;&#9;upCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;upCon:disconnect()
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;&#9;doScrollUp()
&#9;&#9;&#9;wait(0.2)
&#9;&#9;&#9;local t = tick()
&#9;&#9;&#9;local w = 0.1
&#9;&#9;&#9;while scrollStamp == current do
&#9;&#9;&#9;&#9;doScrollUp()
&#9;&#9;&#9;&#9;if mouseYPos and mouseYPos &gt; scrollbar.AbsolutePosition.y then
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if not scrollUpButton.Active then break end
&#9;&#9;&#9;&#9;if tick()-t &gt; 5 then
&#9;&#9;&#9;&#9;&#9;w = 0
&#9;&#9;&#9;&#9;elseif tick()-t &gt; 2 then
&#9;&#9;&#9;&#9;&#9;w = 0.06
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;wait(w)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local function scrollDown(mouseYPos)
&#9;&#9;if scrollDownButton.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local current = scrollStamp
&#9;&#9;&#9;local downCon
&#9;&#9;&#9;downCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;downCon:disconnect()
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;&#9;doScrollDown()
&#9;&#9;&#9;wait(0.2)
&#9;&#9;&#9;local t = tick()
&#9;&#9;&#9;local w = 0.1
&#9;&#9;&#9;while scrollStamp == current do
&#9;&#9;&#9;&#9;doScrollDown()
&#9;&#9;&#9;&#9;if mouseYPos and mouseYPos &lt; (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.x) then
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if not scrollDownButton.Active then break end
&#9;&#9;&#9;&#9;if tick()-t &gt; 5 then
&#9;&#9;&#9;&#9;&#9;w = 0
&#9;&#9;&#9;&#9;elseif tick()-t &gt; 2 then
&#9;&#9;&#9;&#9;&#9;w = 0.06
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;wait(w)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;
&#9;scrollbar.MouseButton1Down:connect(function(x,y)
&#9;&#9;if scrollbar.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local mouseOffset = y - scrollbar.AbsolutePosition.y
&#9;&#9;&#9;if dragCon then dragCon:disconnect() dragCon = nil end
&#9;&#9;&#9;if upCon then upCon:disconnect() upCon = nil end
&#9;&#9;&#9;local prevY = y
&#9;&#9;&#9;local reentrancyGuardMouseScroll = false
&#9;&#9;&#9;dragCon = mouseDrag.MouseMoved:connect(function(x,y)
&#9;&#9;&#9;&#9;if reentrancyGuardMouseScroll then return end
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;reentrancyGuardMouseScroll = true
&#9;&#9;&#9;&#9;&#9;if positionScrollBar(x,y,mouseOffset) then
&#9;&#9;&#9;&#9;&#9;&#9;recalculate()
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;reentrancyGuardMouseScroll = false
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;end)
&#9;&#9;&#9;upCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;dragCon:disconnect(); dragCon = nil
&#9;&#9;&#9;&#9;upCon:disconnect(); drag = nil
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;end
&#9;end)
&#9;local scrollMouseCount = 0
&#9;scrollUpButton.MouseButton1Down:connect(function()
&#9;&#9;scrollUp()
&#9;end)
&#9;scrollUpButton.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;scrollDownButton.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;scrollDownButton.MouseButton1Down:connect(function()
&#9;&#9; scrollDown()
&#9;end)
&#9;&#9;
&#9;scrollbar.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;
&#9;local function heightCheck(instance)
&#9;&#9;if highY and (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) &gt; highY then
&#9;&#9;&#9;highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
&#9;&#9;elseif not highY then
&#9;&#9;&#9;highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
&#9;&#9;end
&#9;&#9;setSliderSizeAndPosition()
&#9;end
&#9;
&#9;local function highLowRecheck()
&#9;&#9;local oldLowY = lowY
&#9;&#9;local oldHighY = highY
&#9;&#9;lowY = nil
&#9;&#9;highY = nil
&#9;&#9;resetHighLow()
&#9;&#9;if (lowY ~= oldLowY) or (highY ~= oldHighY) then
&#9;&#9;&#9;setSliderSizeAndPosition()
&#9;&#9;end
&#9;end
&#9;local function descendantChanged(this, prop)
&#9;&#9;if internalChange then return end
&#9;&#9;if not this.Visible then return end
&#9;&#9;if prop == &quot;Size&quot; or prop == &quot;Position&quot; then
&#9;&#9;&#9;wait()
&#9;&#9;&#9;highLowRecheck()
&#9;&#9;end
&#9;end
&#9;scrollingFrame.DescendantAdded:connect(function(instance)
&#9;&#9;if not instance:IsA(&quot;GuiObject&quot;) then return end
&#9;&#9;if instance.Visible then
&#9;&#9;&#9;wait() -- wait a heartbeat for sizes to reconfig
&#9;&#9;&#9;highLowRecheck()
&#9;&#9;end
&#9;&#9;descendantsChangeConMap[instance] = instance.Changed:connect(function(prop) descendantChanged(instance, prop) end)
&#9;end)
&#9;scrollingFrame.DescendantRemoving:connect(function(instance)
&#9;&#9;if not instance:IsA(&quot;GuiObject&quot;) then return end
&#9;&#9;if descendantsChangeConMap[instance] then
&#9;&#9;&#9;descendantsChangeConMap[instance]:disconnect()
&#9;&#9;&#9;descendantsChangeConMap[instance] = nil
&#9;&#9;end
&#9;&#9;wait() -- wait a heartbeat for sizes to reconfig
&#9;&#9;highLowRecheck()
&#9;end)
&#9;
&#9;scrollingFrame.Changed:connect(function(prop)
&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;if not highY or not lowY then return end
&#9;&#9;&#9;highLowRecheck()
&#9;&#9;&#9;setSliderSizeAndPosition()
&#9;&#9;end
&#9;end)
&#9;return scrollingFrame, controlFrame
end
t.CreateScrollingFrame = function(orderList,scrollStyle)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Name = &quot;ScrollingFrame&quot;
&#9;frame.BackgroundTransparency = 1
&#9;frame.Size = UDim2.new(1,0,1,0)
&#9;
&#9;local scrollUpButton = Instance.new(&quot;ImageButton&quot;)
&#9;scrollUpButton.Name = &quot;ScrollUpButton&quot;
&#9;scrollUpButton.BackgroundTransparency = 1
&#9;scrollUpButton.Image = &quot;rbxasset://textures/ui/scrollbuttonUp.png&quot;
&#9;scrollUpButton.Size = UDim2.new(0,17,0,17)
&#9;
&#9;local scrollDownButton = Instance.new(&quot;ImageButton&quot;)
&#9;scrollDownButton.Name = &quot;ScrollDownButton&quot;
&#9;scrollDownButton.BackgroundTransparency = 1
&#9;scrollDownButton.Image = &quot;rbxasset://textures/ui/scrollbuttonDown.png&quot;
&#9;scrollDownButton.Size = UDim2.new(0,17,0,17)
&#9;
&#9;local scrollbar = Instance.new(&quot;ImageButton&quot;)
&#9;scrollbar.Name = &quot;ScrollBar&quot;
&#9;scrollbar.Image = &quot;rbxasset://textures/ui/scrollbar.png&quot;
&#9;scrollbar.BackgroundTransparency = 1
&#9;scrollbar.Size = UDim2.new(0, 18, 0, 150)
&#9;local scrollStamp = 0
&#9;&#9;
&#9;local scrollDrag = Instance.new(&quot;ImageButton&quot;)
&#9;scrollDrag.Image = &quot;http://www.roblox.com/asset/?id=61367186&quot;
&#9;scrollDrag.Size = UDim2.new(1, 0, 0, 16)
&#9;scrollDrag.BackgroundTransparency = 1
&#9;scrollDrag.Name = &quot;ScrollDrag&quot;
&#9;scrollDrag.Active = true
&#9;scrollDrag.Parent = scrollbar
&#9;
&#9;local mouseDrag = Instance.new(&quot;ImageButton&quot;)
&#9;mouseDrag.Active = false
&#9;mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0)
&#9;mouseDrag.AutoButtonColor = false
&#9;mouseDrag.BackgroundTransparency = 1
&#9;mouseDrag.Name = &quot;mouseDrag&quot;
&#9;mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0)
&#9;mouseDrag.ZIndex = 10
&#9;local style = &quot;simple&quot;
&#9;if scrollStyle and tostring(scrollStyle) then
&#9;&#9;style = scrollStyle
&#9;end
&#9;
&#9;local scrollPosition = 1
&#9;local rowSize = 0
&#9;local howManyDisplayed = 0
&#9;&#9;
&#9;local layoutGridScrollBar = function()
&#9;&#9;howManyDisplayed = 0
&#9;&#9;local guiObjects = {}
&#9;&#9;if orderList then
&#9;&#9;&#9;for i, child in ipairs(orderList) do
&#9;&#9;&#9;&#9;if child.Parent == frame then
&#9;&#9;&#9;&#9;&#9;table.insert(guiObjects, child)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;local children = frame:GetChildren()
&#9;&#9;&#9;if children then
&#9;&#9;&#9;&#9;for i, child in ipairs(children) do
&#9;&#9;&#9;&#9;&#9;if child:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;&#9;&#9;table.insert(guiObjects, child)
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;if #guiObjects == 0 then
&#9;&#9;&#9;scrollUpButton.Active = false
&#9;&#9;&#9;scrollDownButton.Active = false
&#9;&#9;&#9;scrollDrag.Active = false
&#9;&#9;&#9;scrollPosition = 1
&#9;&#9;&#9;return
&#9;&#9;end
&#9;&#9;if scrollPosition &gt; #guiObjects then
&#9;&#9;&#9;scrollPosition = #guiObjects
&#9;&#9;end
&#9;&#9;
&#9;&#9;if scrollPosition &lt; 1 then scrollPosition = 1 end
&#9;&#9;
&#9;&#9;local totalPixelsY = frame.AbsoluteSize.Y
&#9;&#9;local pixelsRemainingY = frame.AbsoluteSize.Y
&#9;&#9;
&#9;&#9;local totalPixelsX = frame.AbsoluteSize.X
&#9;&#9;
&#9;&#9;local xCounter = 0
&#9;&#9;local rowSizeCounter = 0
&#9;&#9;local setRowSize = true
&#9;&#9;local pixelsBelowScrollbar = 0
&#9;&#9;local pos = #guiObjects
&#9;&#9;
&#9;&#9;local currentRowY = 0
&#9;&#9;pos = scrollPosition
&#9;&#9;--count up from current scroll position to fill out grid
&#9;&#9;while pos &lt;= #guiObjects and pixelsBelowScrollbar &lt; totalPixelsY do
&#9;&#9;&#9;xCounter = xCounter + guiObjects[pos].AbsoluteSize.X
&#9;&#9;&#9;--previous pos was the end of a row
&#9;&#9;&#9;if xCounter &gt;= totalPixelsX then
&#9;&#9;&#9;&#9;pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
&#9;&#9;&#9;&#9;currentRowY = 0
&#9;&#9;&#9;&#9;xCounter = guiObjects[pos].AbsoluteSize.X
&#9;&#9;&#9;end
&#9;&#9;&#9;if guiObjects[pos].AbsoluteSize.Y &gt; currentRowY then
&#9;&#9;&#9;&#9;currentRowY = guiObjects[pos].AbsoluteSize.Y
&#9;&#9;&#9;end
&#9;&#9;&#9;pos = pos + 1
&#9;&#9;end
&#9;&#9;--Count wherever current row left off
&#9;&#9;pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
&#9;&#9;currentRowY = 0
&#9;&#9;
&#9;&#9;pos = scrollPosition - 1
&#9;&#9;xCounter = 0
&#9;&#9;
&#9;&#9;--objects with varying X,Y dimensions can rarely cause minor errors
&#9;&#9;--rechecking every new scrollPosition is necessary to avoid 100% of errors
&#9;&#9;
&#9;&#9;--count backwards from current scrollPosition to see if we can add more rows
&#9;&#9;while pixelsBelowScrollbar + currentRowY &lt; totalPixelsY and pos &gt;= 1 do
&#9;&#9;&#9;xCounter = xCounter + guiObjects[pos].AbsoluteSize.X
&#9;&#9;&#9;rowSizeCounter = rowSizeCounter + 1
&#9;&#9;&#9;if xCounter &gt;= totalPixelsX then
&#9;&#9;&#9;&#9;rowSize = rowSizeCounter - 1
&#9;&#9;&#9;&#9;rowSizeCounter = 0
&#9;&#9;&#9;&#9;xCounter = guiObjects[pos].AbsoluteSize.X
&#9;&#9;&#9;&#9;if pixelsBelowScrollbar + currentRowY &lt;= totalPixelsY then
&#9;&#9;&#9;&#9;&#9;--It fits, so back up our scroll position
&#9;&#9;&#9;&#9;&#9;pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
&#9;&#9;&#9;&#9;&#9;if scrollPosition &lt;= rowSize then
&#9;&#9;&#9;&#9;&#9;&#9;scrollPosition = 1
&#9;&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;scrollPosition = scrollPosition - rowSize
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;currentRowY = 0
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;
&#9;&#9;&#9;if guiObjects[pos].AbsoluteSize.Y &gt; currentRowY then
&#9;&#9;&#9;&#9;currentRowY = guiObjects[pos].AbsoluteSize.Y
&#9;&#9;&#9;end
&#9;&#9;&#9;pos = pos - 1
&#9;&#9;end
&#9;&#9;
&#9;&#9;--Do check last time if pos = 0
&#9;&#9;if (pos == 0) and (pixelsBelowScrollbar + currentRowY &lt;= totalPixelsY) then
&#9;&#9;&#9;scrollPosition = 1
&#9;&#9;end
&#9;&#9;xCounter = 0
&#9;&#9;--pos = scrollPosition
&#9;&#9;rowSizeCounter = 0
&#9;&#9;setRowSize = true
&#9;&#9;local lastChildSize = 0
&#9;&#9;
&#9;&#9;local xOffset,yOffset = 0
&#9;&#9;if guiObjects[1] then
&#9;&#9;&#9;yOffset = math.ceil(math.floor(math.fmod(totalPixelsY,guiObjects[1].AbsoluteSize.X))/2)
&#9;&#9;&#9;xOffset = math.ceil(math.floor(math.fmod(totalPixelsX,guiObjects[1].AbsoluteSize.Y))/2)
&#9;&#9;end
&#9;&#9;
&#9;&#9;for i, child in ipairs(guiObjects) do
&#9;&#9;&#9;if i &lt; scrollPosition then
&#9;&#9;&#9;&#9;--print(&quot;Hiding &quot; .. child.Name)
&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;if pixelsRemainingY &lt; 0 then
&#9;&#9;&#9;&#9;&#9;--print(&quot;Out of Space &quot; .. child.Name)
&#9;&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;--print(&quot;Laying out &quot; .. child.Name)
&#9;&#9;&#9;&#9;&#9;--GuiObject
&#9;&#9;&#9;&#9;&#9;if setRowSize then rowSizeCounter = rowSizeCounter + 1 end
&#9;&#9;&#9;&#9;&#9;if xCounter + child.AbsoluteSize.X &gt;= totalPixelsX then
&#9;&#9;&#9;&#9;&#9;&#9;if setRowSize then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;rowSize = rowSizeCounter - 1
&#9;&#9;&#9;&#9;&#9;&#9;&#9;setRowSize = false
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;&#9;xCounter = 0
&#9;&#9;&#9;&#9;&#9;&#9;pixelsRemainingY = pixelsRemainingY - child.AbsoluteSize.Y
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;child.Position = UDim2.new(child.Position.X.Scale,xCounter + xOffset, 0, totalPixelsY - pixelsRemainingY + yOffset)
&#9;&#9;&#9;&#9;&#9;xCounter = xCounter + child.AbsoluteSize.X
&#9;&#9;&#9;&#9;&#9;child.Visible = ((pixelsRemainingY - child.AbsoluteSize.Y) &gt;= 0)
&#9;&#9;&#9;&#9;&#9;if child.Visible then
&#9;&#9;&#9;&#9;&#9;&#9;howManyDisplayed = howManyDisplayed + 1
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;lastChildSize = child.AbsoluteSize&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;scrollUpButton.Active = (scrollPosition &gt; 1)
&#9;&#9;if lastChildSize == 0 then
&#9;&#9;&#9;scrollDownButton.Active = false
&#9;&#9;else
&#9;&#9;&#9;scrollDownButton.Active = ((pixelsRemainingY - lastChildSize.Y) &lt; 0)
&#9;&#9;end
&#9;&#9;scrollDrag.Active = #guiObjects &gt; howManyDisplayed
&#9;&#9;scrollDrag.Visible = scrollDrag.Active
&#9;end
&#9;local layoutSimpleScrollBar = function()
&#9;&#9;local guiObjects = {}&#9;
&#9;&#9;howManyDisplayed = 0
&#9;&#9;
&#9;&#9;if orderList then
&#9;&#9;&#9;for i, child in ipairs(orderList) do
&#9;&#9;&#9;&#9;if child.Parent == frame then
&#9;&#9;&#9;&#9;&#9;table.insert(guiObjects, child)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;local children = frame:GetChildren()
&#9;&#9;&#9;if children then
&#9;&#9;&#9;&#9;for i, child in ipairs(children) do
&#9;&#9;&#9;&#9;&#9;if child:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;&#9;&#9;table.insert(guiObjects, child)
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;if #guiObjects == 0 then
&#9;&#9;&#9;scrollUpButton.Active = false
&#9;&#9;&#9;scrollDownButton.Active = false
&#9;&#9;&#9;scrollDrag.Active = false
&#9;&#9;&#9;scrollPosition = 1
&#9;&#9;&#9;return
&#9;&#9;end
&#9;&#9;if scrollPosition &gt; #guiObjects then
&#9;&#9;&#9;scrollPosition = #guiObjects
&#9;&#9;end
&#9;&#9;
&#9;&#9;local totalPixels = frame.AbsoluteSize.Y
&#9;&#9;local pixelsRemaining = frame.AbsoluteSize.Y
&#9;&#9;local pixelsBelowScrollbar = 0
&#9;&#9;local pos = #guiObjects
&#9;&#9;while pixelsBelowScrollbar &lt; totalPixels and pos &gt;= 1 do
&#9;&#9;&#9;if pos &gt;= scrollPosition then
&#9;&#9;&#9;&#9;pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;if pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y &lt;= totalPixels then
&#9;&#9;&#9;&#9;&#9;--It fits, so back up our scroll position
&#9;&#9;&#9;&#9;&#9;pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y
&#9;&#9;&#9;&#9;&#9;if scrollPosition &lt;= 1 then
&#9;&#9;&#9;&#9;&#9;&#9;scrollPosition = 1
&#9;&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;--local (&quot;Backing up ScrollPosition from -- &quot; ..scrollPosition)
&#9;&#9;&#9;&#9;&#9;&#9;scrollPosition = scrollPosition - 1
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;pos = pos - 1
&#9;&#9;end
&#9;&#9;pos = scrollPosition
&#9;&#9;for i, child in ipairs(guiObjects) do
&#9;&#9;&#9;if i &lt; scrollPosition then
&#9;&#9;&#9;&#9;--print(&quot;Hiding &quot; .. child.Name)
&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;if pixelsRemaining &lt; 0 then
&#9;&#9;&#9;&#9;&#9;--print(&quot;Out of Space &quot; .. child.Name)
&#9;&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;--print(&quot;Laying out &quot; .. child.Name)
&#9;&#9;&#9;&#9;&#9;--GuiObject
&#9;&#9;&#9;&#9;&#9;child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
&#9;&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
&#9;&#9;&#9;&#9;&#9;if (pixelsRemaining &gt;= 0) then
&#9;&#9;&#9;&#9;&#9;&#9;child.Visible = true
&#9;&#9;&#9;&#9;&#9;&#9;howManyDisplayed = howManyDisplayed + 1
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;&#9;&#9;end&#9;&#9;
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;scrollUpButton.Active = (scrollPosition &gt; 1)
&#9;&#9;scrollDownButton.Active = (pixelsRemaining &lt; 0)
&#9;&#9;scrollDrag.Active = #guiObjects &gt; howManyDisplayed
&#9;&#9;scrollDrag.Visible = scrollDrag.Active
&#9;end
&#9;
&#9;&#9;
&#9;local moveDragger = function()&#9;
&#9;&#9;local guiObjects = 0
&#9;&#9;local children = frame:GetChildren()
&#9;&#9;if children then
&#9;&#9;&#9;for i, child in ipairs(children) do
&#9;&#9;&#9;&#9;if child:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;&#9;guiObjects = guiObjects + 1
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;
&#9;&#9;if not scrollDrag.Parent then return end
&#9;&#9;
&#9;&#9;local dragSizeY = scrollDrag.Parent.AbsoluteSize.y * (1/(guiObjects - howManyDisplayed + 1))
&#9;&#9;if dragSizeY &lt; 16 then dragSizeY = 16 end
&#9;&#9;scrollDrag.Size = UDim2.new(scrollDrag.Size.X.Scale,scrollDrag.Size.X.Offset,scrollDrag.Size.Y.Scale,dragSizeY)
&#9;&#9;local relativeYPos = (scrollPosition - 1)/(guiObjects - (howManyDisplayed))
&#9;&#9;if relativeYPos &gt; 1 then relativeYPos = 1
&#9;&#9;elseif relativeYPos &lt; 0 then relativeYPos = 0 end
&#9;&#9;local absYPos = 0
&#9;&#9;
&#9;&#9;if relativeYPos ~= 0 then
&#9;&#9;&#9;absYPos = (relativeYPos * scrollbar.AbsoluteSize.y) - (relativeYPos * scrollDrag.AbsoluteSize.y)
&#9;&#9;end
&#9;&#9;
&#9;&#9;scrollDrag.Position = UDim2.new(scrollDrag.Position.X.Scale,scrollDrag.Position.X.Offset,scrollDrag.Position.Y.Scale,absYPos)
&#9;end
&#9;local reentrancyGuard = false
&#9;local recalculate = function()
&#9;&#9;if reentrancyGuard then
&#9;&#9;&#9;return
&#9;&#9;end
&#9;&#9;reentrancyGuard = true
&#9;&#9;wait()
&#9;&#9;local success, err = nil
&#9;&#9;if style == &quot;grid&quot; then
&#9;&#9;&#9;success, err = pcall(function() layoutGridScrollBar() end)
&#9;&#9;elseif style == &quot;simple&quot; then
&#9;&#9;&#9;success, err = pcall(function() layoutSimpleScrollBar() end)
&#9;&#9;end
&#9;&#9;if not success then print(err) end
&#9;&#9;moveDragger()
&#9;&#9;reentrancyGuard = false
&#9;end
&#9;
&#9;local doScrollUp = function()
&#9;&#9;scrollPosition = (scrollPosition) - rowSize
&#9;&#9;if scrollPosition &lt; 1 then scrollPosition = 1 end
&#9;&#9;recalculate(nil)
&#9;end
&#9;
&#9;local doScrollDown = function()
&#9;&#9;scrollPosition = (scrollPosition) + rowSize
&#9;&#9;recalculate(nil)
&#9;end
&#9;local scrollUp = function(mouseYPos)
&#9;&#9;if scrollUpButton.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local current = scrollStamp
&#9;&#9;&#9;local upCon
&#9;&#9;&#9;upCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;upCon:disconnect()
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;&#9;doScrollUp()
&#9;&#9;&#9;wait(0.2)
&#9;&#9;&#9;local t = tick()
&#9;&#9;&#9;local w = 0.1
&#9;&#9;&#9;while scrollStamp == current do
&#9;&#9;&#9;&#9;doScrollUp()
&#9;&#9;&#9;&#9;if mouseYPos and mouseYPos &gt; scrollDrag.AbsolutePosition.y then
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if not scrollUpButton.Active then break end
&#9;&#9;&#9;&#9;if tick()-t &gt; 5 then
&#9;&#9;&#9;&#9;&#9;w = 0
&#9;&#9;&#9;&#9;elseif tick()-t &gt; 2 then
&#9;&#9;&#9;&#9;&#9;w = 0.06
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;wait(w)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local scrollDown = function(mouseYPos)
&#9;&#9;if scrollDownButton.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local current = scrollStamp
&#9;&#9;&#9;local downCon
&#9;&#9;&#9;downCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;downCon:disconnect()
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;&#9;doScrollDown()
&#9;&#9;&#9;wait(0.2)
&#9;&#9;&#9;local t = tick()
&#9;&#9;&#9;local w = 0.1
&#9;&#9;&#9;while scrollStamp == current do
&#9;&#9;&#9;&#9;doScrollDown()
&#9;&#9;&#9;&#9;if mouseYPos and mouseYPos &lt; (scrollDrag.AbsolutePosition.y + scrollDrag.AbsoluteSize.x) then
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if not scrollDownButton.Active then break end
&#9;&#9;&#9;&#9;if tick()-t &gt; 5 then
&#9;&#9;&#9;&#9;&#9;w = 0
&#9;&#9;&#9;&#9;elseif tick()-t &gt; 2 then
&#9;&#9;&#9;&#9;&#9;w = 0.06
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;wait(w)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;
&#9;local y = 0
&#9;scrollDrag.MouseButton1Down:connect(function(x,y)
&#9;&#9;if scrollDrag.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local mouseOffset = y - scrollDrag.AbsolutePosition.y
&#9;&#9;&#9;local dragCon
&#9;&#9;&#9;local upCon
&#9;&#9;&#9;dragCon = mouseDrag.MouseMoved:connect(function(x,y)
&#9;&#9;&#9;&#9;local barAbsPos = scrollbar.AbsolutePosition.y
&#9;&#9;&#9;&#9;local barAbsSize = scrollbar.AbsoluteSize.y
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local dragAbsSize = scrollDrag.AbsoluteSize.y
&#9;&#9;&#9;&#9;local barAbsOne = barAbsPos + barAbsSize - dragAbsSize
&#9;&#9;&#9;&#9;y = y - mouseOffset
&#9;&#9;&#9;&#9;y = y &lt; barAbsPos and barAbsPos or y &gt; barAbsOne and barAbsOne or y
&#9;&#9;&#9;&#9;y = y - barAbsPos
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local guiObjects = 0
&#9;&#9;&#9;&#9;local children = frame:GetChildren()
&#9;&#9;&#9;&#9;if children then
&#9;&#9;&#9;&#9;&#9;for i, child in ipairs(children) do
&#9;&#9;&#9;&#9;&#9;&#9;if child:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;guiObjects = guiObjects + 1
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local doublePercent = y/(barAbsSize-dragAbsSize)
&#9;&#9;&#9;&#9;local rowDiff = rowSize
&#9;&#9;&#9;&#9;local totalScrollCount = guiObjects - (howManyDisplayed - 1)
&#9;&#9;&#9;&#9;local newScrollPosition = math.floor((doublePercent * totalScrollCount) + 0.5) + rowDiff
&#9;&#9;&#9;&#9;if newScrollPosition &lt; scrollPosition then
&#9;&#9;&#9;&#9;&#9;rowDiff = -rowDiff
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;if newScrollPosition &lt; 1 then
&#9;&#9;&#9;&#9;&#9;newScrollPosition = 1
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;scrollPosition = newScrollPosition
&#9;&#9;&#9;&#9;recalculate(nil)
&#9;&#9;&#9;end)
&#9;&#9;&#9;upCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;dragCon:disconnect(); dragCon = nil
&#9;&#9;&#9;&#9;upCon:disconnect(); drag = nil
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;end
&#9;end)
&#9;local scrollMouseCount = 0
&#9;scrollUpButton.MouseButton1Down:connect(
&#9;&#9;function()
&#9;&#9;&#9;scrollUp()
&#9;&#9;end)
&#9;scrollUpButton.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;scrollDownButton.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;scrollDownButton.MouseButton1Down:connect(
&#9;&#9;function()
&#9;&#9;&#9;scrollDown()&#9;
&#9;&#9;end)
&#9;&#9;
&#9;scrollbar.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;scrollbar.MouseButton1Down:connect(
&#9;&#9;function(x,y)
&#9;&#9;&#9;if y &gt; (scrollDrag.AbsoluteSize.y + scrollDrag.AbsolutePosition.y) then
&#9;&#9;&#9;&#9;scrollDown(y)
&#9;&#9;&#9;elseif y &lt; (scrollDrag.AbsolutePosition.y) then
&#9;&#9;&#9;&#9;scrollUp(y)
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;frame.ChildAdded:connect(function()
&#9;&#9;recalculate(nil)
&#9;end)
&#9;frame.ChildRemoved:connect(function()
&#9;&#9;recalculate(nil)
&#9;end)
&#9;
&#9;frame.Changed:connect(
&#9;&#9;function(prop)
&#9;&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;&#9;--Wait a heartbeat for it to sync in
&#9;&#9;&#9;&#9;recalculate(nil)
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;frame.AncestryChanged:connect(function() recalculate(nil) end)
&#9;return frame, scrollUpButton, scrollDownButton, recalculate, scrollbar
end
local function binaryGrow(min, max, fits)
&#9;if min &gt; max then
&#9;&#9;return min
&#9;end
&#9;local biggestLegal = min
&#9;while min &lt;= max do
&#9;&#9;local mid = min + math.floor((max - min) / 2)
&#9;&#9;if fits(mid) and (biggestLegal == nil or biggestLegal &lt; mid) then
&#9;&#9;&#9;biggestLegal = mid
&#9;&#9;&#9;
&#9;&#9;&#9;--Try growing
&#9;&#9;&#9;min = mid + 1
&#9;&#9;else
&#9;&#9;&#9;--Doesn&apos;t fit, shrink
&#9;&#9;&#9;max = mid - 1
&#9;&#9;end
&#9;end
&#9;return biggestLegal
end
local function binaryShrink(min, max, fits)
&#9;if min &gt; max then
&#9;&#9;return min
&#9;end
&#9;local smallestLegal = max
&#9;while min &lt;= max do
&#9;&#9;local mid = min + math.floor((max - min) / 2)
&#9;&#9;if fits(mid) and (smallestLegal == nil or smallestLegal &gt; mid) then
&#9;&#9;&#9;smallestLegal = mid
&#9;&#9;&#9;
&#9;&#9;&#9;--It fits, shrink
&#9;&#9;&#9;max = mid - 1&#9;&#9;&#9;
&#9;&#9;else
&#9;&#9;&#9;--Doesn&apos;t fit, grow
&#9;&#9;&#9;min = mid + 1
&#9;&#9;end
&#9;end
&#9;return smallestLegal
end
local function getGuiOwner(instance)
&#9;while instance ~= nil do
&#9;&#9;if instance:IsA(&quot;ScreenGui&quot;) or instance:IsA(&quot;BillboardGui&quot;) then
&#9;&#9;&#9;return instance
&#9;&#9;end
&#9;&#9;instance = instance.Parent
&#9;end
&#9;return nil
end
t.AutoTruncateTextObject = function(textLabel)
&#9;local text = textLabel.Text
&#9;local fullLabel = textLabel:Clone()
&#9;fullLabel.Name = &quot;Full&quot; .. textLabel.Name
&#9;fullLabel.BorderSizePixel = 0
&#9;fullLabel.BackgroundTransparency = 0
&#9;fullLabel.Text = text
&#9;fullLabel.TextXAlignment = Enum.TextXAlignment.Center
&#9;fullLabel.Position = UDim2.new(0,-3,0,0)
&#9;fullLabel.Size = UDim2.new(0,100,1,0)
&#9;fullLabel.Visible = false
&#9;fullLabel.Parent = textLabel
&#9;local shortText = nil
&#9;local mouseEnterConnection = nil
&#9;local mouseLeaveConnection= nil
&#9;local checkForResize = function()
&#9;&#9;if getGuiOwner(textLabel) == nil then
&#9;&#9;&#9;return
&#9;&#9;end
&#9;&#9;textLabel.Text = text
&#9;&#9;if textLabel.TextFits then
&#9;&#9;&#9;--Tear down the rollover if it is active
&#9;&#9;&#9;if mouseEnterConnection then
&#9;&#9;&#9;&#9;mouseEnterConnection:disconnect()
&#9;&#9;&#9;&#9;mouseEnterConnection = nil
&#9;&#9;&#9;end
&#9;&#9;&#9;if mouseLeaveConnection then
&#9;&#9;&#9;&#9;mouseLeaveConnection:disconnect()
&#9;&#9;&#9;&#9;mouseLeaveConnection = nil
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;local len = string.len(text)
&#9;&#9;&#9;textLabel.Text = text .. &quot;~&quot;
&#9;&#9;&#9;--Shrink the text
&#9;&#9;&#9;local textSize = binaryGrow(0, len,
&#9;&#9;&#9;&#9;function(pos)
&#9;&#9;&#9;&#9;&#9;if pos == 0 then
&#9;&#9;&#9;&#9;&#9;&#9;textLabel.Text = &quot;~&quot;
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;textLabel.Text = string.sub(text, 1, pos) .. &quot;~&quot;
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;return textLabel.TextFits
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;shortText = string.sub(text, 1, textSize) .. &quot;~&quot;
&#9;&#9;&#9;textLabel.Text = shortText
&#9;&#9;&#9;
&#9;&#9;&#9;--Make sure the fullLabel fits
&#9;&#9;&#9;if not fullLabel.TextFits then
&#9;&#9;&#9;&#9;--Already too small, grow it really bit to start
&#9;&#9;&#9;&#9;fullLabel.Size = UDim2.new(0, 10000, 1, 0)
&#9;&#9;&#9;end
&#9;&#9;&#9;
&#9;&#9;&#9;--Okay, now try to binary shrink it back down
&#9;&#9;&#9;local fullLabelSize = binaryShrink(textLabel.AbsoluteSize.X,fullLabel.AbsoluteSize.X,
&#9;&#9;&#9;&#9;function(size)
&#9;&#9;&#9;&#9;&#9;fullLabel.Size = UDim2.new(0, size, 1, 0)
&#9;&#9;&#9;&#9;&#9;return fullLabel.TextFits
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;fullLabel.Size = UDim2.new(0,fullLabelSize+6,1,0)
&#9;&#9;&#9;--Now setup the rollover effects, if they are currently off
&#9;&#9;&#9;if mouseEnterConnection == nil then
&#9;&#9;&#9;&#9;mouseEnterConnection = textLabel.MouseEnter:connect(
&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;&#9;fullLabel.ZIndex = textLabel.ZIndex + 1
&#9;&#9;&#9;&#9;&#9;&#9;fullLabel.Visible = true
&#9;&#9;&#9;&#9;&#9;&#9;--textLabel.Text = &quot;&quot;
&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;&#9;if mouseLeaveConnection == nil then
&#9;&#9;&#9;&#9;mouseLeaveConnection = textLabel.MouseLeave:connect(
&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;&#9;fullLabel.Visible = false
&#9;&#9;&#9;&#9;&#9;&#9;--textLabel.Text = shortText
&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;textLabel.AncestryChanged:connect(checkForResize)
&#9;textLabel.Changed:connect(
&#9;&#9;function(prop)
&#9;&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;&#9;checkForResize() &#9;
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;checkForResize()
&#9;local function changeText(newText)
&#9;&#9;text = newText
&#9;&#9;fullLabel.Text = text
&#9;&#9;checkForResize()
&#9;end
&#9;return textLabel, changeText
end
local function TransitionTutorialPages(fromPage, toPage, transitionFrame, currentPageValue)&#9;
&#9;if fromPage then
&#9;&#9;fromPage.Visible = false
&#9;&#9;if transitionFrame.Visible == false then
&#9;&#9;&#9;transitionFrame.Size = fromPage.Size
&#9;&#9;&#9;transitionFrame.Position = fromPage.Position
&#9;&#9;end
&#9;else
&#9;&#9;if transitionFrame.Visible == false then
&#9;&#9;&#9;transitionFrame.Size = UDim2.new(0.0,50,0.0,50)
&#9;&#9;&#9;transitionFrame.Position = UDim2.new(0.5,-25,0.5,-25)
&#9;&#9;end
&#9;end
&#9;transitionFrame.Visible = true
&#9;currentPageValue.Value = nil
&#9;local newsize, newPosition
&#9;if toPage then
&#9;&#9;--Make it visible so it resizes
&#9;&#9;toPage.Visible = true
&#9;&#9;newSize = toPage.Size
&#9;&#9;newPosition = toPage.Position
&#9;&#9;toPage.Visible = false
&#9;else
&#9;&#9;newSize = UDim2.new(0.0,50,0.0,50)
&#9;&#9;newPosition = UDim2.new(0.5,-25,0.5,-25)
&#9;end
&#9;transitionFrame:TweenSizeAndPosition(newSize, newPosition, Enum.EasingDirection.InOut, Enum.EasingStyle.Quad, 0.3, true,
&#9;&#9;function(state)
&#9;&#9;&#9;if state == Enum.TweenStatus.Completed then
&#9;&#9;&#9;&#9;transitionFrame.Visible = false
&#9;&#9;&#9;&#9;if toPage then
&#9;&#9;&#9;&#9;&#9;toPage.Visible = true
&#9;&#9;&#9;&#9;&#9;currentPageValue.Value = toPage
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end)
end
t.CreateTutorial = function(name, tutorialKey, createButtons)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Name = &quot;Tutorial-&quot; .. name
&#9;frame.BackgroundTransparency = 1
&#9;frame.Size = UDim2.new(0.6, 0, 0.6, 0)
&#9;frame.Position = UDim2.new(0.2, 0, 0.2, 0)
&#9;local transitionFrame = Instance.new(&quot;Frame&quot;)
&#9;transitionFrame.Name = &quot;TransitionFrame&quot;
&#9;transitionFrame.Style = Enum.FrameStyle.RobloxRound
&#9;transitionFrame.Size = UDim2.new(0.6, 0, 0.6, 0)
&#9;transitionFrame.Position = UDim2.new(0.2, 0, 0.2, 0)
&#9;transitionFrame.Visible = false
&#9;transitionFrame.Parent = frame
&#9;local currentPageValue = Instance.new(&quot;ObjectValue&quot;)
&#9;currentPageValue.Name = &quot;CurrentTutorialPage&quot;
&#9;currentPageValue.Value = nil
&#9;currentPageValue.Parent = frame
&#9;local boolValue = Instance.new(&quot;BoolValue&quot;)
&#9;boolValue.Name = &quot;Buttons&quot;
&#9;boolValue.Value = createButtons
&#9;boolValue.Parent = frame
&#9;local pages = Instance.new(&quot;Frame&quot;)
&#9;pages.Name = &quot;Pages&quot;
&#9;pages.BackgroundTransparency = 1
&#9;pages.Size = UDim2.new(1,0,1,0)
&#9;pages.Parent = frame
&#9;local function getVisiblePageAndHideOthers()
&#9;&#9;local visiblePage = nil
&#9;&#9;local children = pages:GetChildren()
&#9;&#9;if children then
&#9;&#9;&#9;for i,child in ipairs(children) do
&#9;&#9;&#9;&#9;if child.Visible then
&#9;&#9;&#9;&#9;&#9;if visiblePage then
&#9;&#9;&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;visiblePage = child
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;return visiblePage
&#9;end
&#9;local showTutorial = function(alwaysShow)
&#9;&#9;if alwaysShow or UserSettings().GameSettings:GetTutorialState(tutorialKey) == false then
&#9;&#9;&#9;print(&quot;Showing tutorial-&quot;,tutorialKey)
&#9;&#9;&#9;local currentTutorialPage = getVisiblePageAndHideOthers()
&#9;&#9;&#9;local firstPage = pages:FindFirstChild(&quot;TutorialPage1&quot;)
&#9;&#9;&#9;if firstPage then
&#9;&#9;&#9;&#9;TransitionTutorialPages(currentTutorialPage, firstPage, transitionFrame, currentPageValue)&#9;
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;error(&quot;Could not find TutorialPage1&quot;)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local dismissTutorial = function()
&#9;&#9;local currentTutorialPage = getVisiblePageAndHideOthers()
&#9;&#9;if currentTutorialPage then
&#9;&#9;&#9;TransitionTutorialPages(currentTutorialPage, nil, transitionFrame, currentPageValue)
&#9;&#9;end
&#9;&#9;UserSettings().GameSettings:SetTutorialState(tutorialKey, true)
&#9;end
&#9;local gotoPage = function(pageNum)
&#9;&#9;local page = pages:FindFirstChild(&quot;TutorialPage&quot; .. pageNum)
&#9;&#9;local currentTutorialPage = getVisiblePageAndHideOthers()
&#9;&#9;TransitionTutorialPages(currentTutorialPage, page, transitionFrame, currentPageValue)
&#9;end
&#9;return frame, showTutorial, dismissTutorial, gotoPage
end
local function CreateBasicTutorialPage(name, handleResize, skipTutorial, giveDoneButton)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Name = &quot;TutorialPage&quot;
&#9;frame.Style = Enum.FrameStyle.RobloxRound
&#9;frame.Size = UDim2.new(0.6, 0, 0.6, 0)
&#9;frame.Position = UDim2.new(0.2, 0, 0.2, 0)
&#9;frame.Visible = false
&#9;
&#9;local frameHeader = Instance.new(&quot;TextLabel&quot;)
&#9;frameHeader.Name = &quot;Header&quot;
&#9;frameHeader.Text = name
&#9;frameHeader.BackgroundTransparency = 1
&#9;frameHeader.FontSize = Enum.FontSize.Size24
&#9;frameHeader.Font = Enum.Font.ArialBold
&#9;frameHeader.TextColor3 = Color3.new(1,1,1)
&#9;frameHeader.TextXAlignment = Enum.TextXAlignment.Center
&#9;frameHeader.TextWrap = true
&#9;frameHeader.Size = UDim2.new(1,-55, 0, 22)
&#9;frameHeader.Position = UDim2.new(0,0,0,0)
&#9;frameHeader.Parent = frame
&#9;local skipButton = Instance.new(&quot;ImageButton&quot;)
&#9;skipButton.Name = &quot;SkipButton&quot;
&#9;skipButton.AutoButtonColor = false
&#9;skipButton.BackgroundTransparency = 1
&#9;skipButton.Image = &quot;rbxasset://textures/ui/closeButton.png&quot;
&#9;skipButton.MouseButton1Click:connect(function()
&#9;&#9;skipTutorial()
&#9;end)
&#9;skipButton.MouseEnter:connect(function()
&#9;&#9;skipButton.Image = &quot;rbxasset://textures/ui/closeButton_dn.png&quot;
&#9;end)
&#9;skipButton.MouseLeave:connect(function()
&#9;&#9;skipButton.Image = &quot;rbxasset://textures/ui/closeButton.png&quot;
&#9;end)
&#9;skipButton.Size = UDim2.new(0, 25, 0, 25)
&#9;skipButton.Position = UDim2.new(1, -25, 0, 0)
&#9;skipButton.Parent = frame
&#9;
&#9;
&#9;if giveDoneButton then
&#9;&#9;local doneButton = Instance.new(&quot;TextButton&quot;)
&#9;&#9;doneButton.Name = &quot;DoneButton&quot;
&#9;&#9;doneButton.Style = Enum.ButtonStyle.RobloxButtonDefault
&#9;&#9;doneButton.Text = &quot;Done&quot;
&#9;&#9;doneButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;doneButton.Font = Enum.Font.ArialBold
&#9;&#9;doneButton.FontSize = Enum.FontSize.Size18
&#9;&#9;doneButton.Size = UDim2.new(0,100,0,50)
&#9;&#9;doneButton.Position = UDim2.new(0.5,-50,1,-50)
&#9;&#9;
&#9;&#9;if skipTutorial then
&#9;&#9;&#9;doneButton.MouseButton1Click:connect(function() skipTutorial() end)
&#9;&#9;end
&#9;&#9;
&#9;&#9;doneButton.Parent = frame
&#9;end
&#9;local innerFrame = Instance.new(&quot;Frame&quot;)
&#9;innerFrame.Name = &quot;ContentFrame&quot;
&#9;innerFrame.BackgroundTransparency = 1
&#9;innerFrame.Position = UDim2.new(0,0,0,25)
&#9;innerFrame.Parent = frame
&#9;local nextButton = Instance.new(&quot;TextButton&quot;)
&#9;nextButton.Name = &quot;NextButton&quot;
&#9;nextButton.Text = &quot;Next&quot;
&#9;nextButton.TextColor3 = Color3.new(1,1,1)
&#9;nextButton.Font = Enum.Font.Arial
&#9;nextButton.FontSize = Enum.FontSize.Size18
&#9;nextButton.Style = Enum.ButtonStyle.RobloxButtonDefault
&#9;nextButton.Size = UDim2.new(0,80, 0, 32)
&#9;nextButton.Position = UDim2.new(0.5, 5, 1, -32)
&#9;nextButton.Active = false
&#9;nextButton.Visible = false
&#9;nextButton.Parent = frame
&#9;local prevButton = Instance.new(&quot;TextButton&quot;)
&#9;prevButton.Name = &quot;PrevButton&quot;
&#9;prevButton.Text = &quot;Previous&quot;
&#9;prevButton.TextColor3 = Color3.new(1,1,1)
&#9;prevButton.Font = Enum.Font.Arial
&#9;prevButton.FontSize = Enum.FontSize.Size18
&#9;prevButton.Style = Enum.ButtonStyle.RobloxButton
&#9;prevButton.Size = UDim2.new(0,80, 0, 32)
&#9;prevButton.Position = UDim2.new(0.5, -85, 1, -32)
&#9;prevButton.Active = false
&#9;prevButton.Visible = false
&#9;prevButton.Parent = frame
&#9;if giveDoneButton then
&#9;&#9;innerFrame.Size = UDim2.new(1,0,1,-75)
&#9;else
&#9;&#9;innerFrame.Size = UDim2.new(1,0,1,-22)
&#9;end
&#9;local parentConnection = nil
&#9;local function basicHandleResize()
&#9;&#9;if frame.Visible and frame.Parent then
&#9;&#9;&#9;local maxSize = math.min(frame.Parent.AbsoluteSize.X, frame.Parent.AbsoluteSize.Y)
&#9;&#9;&#9;handleResize(200,maxSize)
&#9;&#9;end
&#9;end
&#9;frame.Changed:connect(
&#9;&#9;function(prop)
&#9;&#9;&#9;if prop == &quot;Parent&quot; then
&#9;&#9;&#9;&#9;if parentConnection ~= nil then
&#9;&#9;&#9;&#9;&#9;parentConnection:disconnect()
&#9;&#9;&#9;&#9;&#9;parentConnection = nil
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if frame.Parent and frame.Parent:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;&#9;parentConnection = frame.Parent.Changed:connect(
&#9;&#9;&#9;&#9;&#9;&#9;function(parentProp)
&#9;&#9;&#9;&#9;&#9;&#9;&#9;if parentProp == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;wait()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;basicHandleResize()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;&#9;&#9;basicHandleResize()
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;if prop == &quot;Visible&quot; then
&#9;&#9;&#9;&#9;basicHandleResize()
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;return frame, innerFrame
end
t.CreateTextTutorialPage = function(name, text, skipTutorialFunc)
&#9;local frame = nil
&#9;local contentFrame = nil
&#9;local textLabel = Instance.new(&quot;TextLabel&quot;)
&#9;textLabel.BackgroundTransparency = 1
&#9;textLabel.TextColor3 = Color3.new(1,1,1)
&#9;textLabel.Text = text
&#9;textLabel.TextWrap = true
&#9;textLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;textLabel.TextYAlignment = Enum.TextYAlignment.Center
&#9;textLabel.Font = Enum.Font.Arial
&#9;textLabel.FontSize = Enum.FontSize.Size14
&#9;textLabel.Size = UDim2.new(1,0,1,0)
&#9;local function handleResize(minSize, maxSize)
&#9;&#9;size = binaryShrink(minSize, maxSize,
&#9;&#9;&#9;function(size)
&#9;&#9;&#9;&#9;frame.Size = UDim2.new(0, size, 0, size)
&#9;&#9;&#9;&#9;return textLabel.TextFits
&#9;&#9;&#9;end)
&#9;&#9;frame.Size = UDim2.new(0, size, 0, size)
&#9;&#9;frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2)
&#9;end
&#9;frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc)
&#9;textLabel.Parent = contentFrame
&#9;return frame
end
t.CreateImageTutorialPage = function(name, imageAsset, x, y, skipTutorialFunc, giveDoneButton)
&#9;local frame = nil
&#9;local contentFrame = nil
&#9;local imageLabel = Instance.new(&quot;ImageLabel&quot;)
&#9;imageLabel.BackgroundTransparency = 1
&#9;imageLabel.Image = imageAsset
&#9;imageLabel.Size = UDim2.new(0,x,0,y)
&#9;imageLabel.Position = UDim2.new(0.5,-x/2,0.5,-y/2)
&#9;local function handleResize(minSize, maxSize)
&#9;&#9;size = binaryShrink(minSize, maxSize,
&#9;&#9;&#9;function(size)
&#9;&#9;&#9;&#9;return size &gt;= x and size &gt;= y
&#9;&#9;&#9;end)
&#9;&#9;if size &gt;= x and size &gt;= y then
&#9;&#9;&#9;imageLabel.Size = UDim2.new(0,x, 0,y)
&#9;&#9;&#9;imageLabel.Position = UDim2.new(0.5,-x/2, 0.5, -y/2)
&#9;&#9;else
&#9;&#9;&#9;if x &gt; y then
&#9;&#9;&#9;&#9;--X is limiter, so
&#9;&#9;&#9;&#9;imageLabel.Size = UDim2.new(1,0,y/x,0)
&#9;&#9;&#9;&#9;imageLabel.Position = UDim2.new(0,0, 0.5 - (y/x)/2, 0)
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;--Y is limiter
&#9;&#9;&#9;&#9;imageLabel.Size = UDim2.new(x/y,0,1, 0)
&#9;&#9;&#9;&#9;imageLabel.Position = UDim2.new(0.5-(x/y)/2, 0, 0, 0)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;size = size + 50
&#9;&#9;frame.Size = UDim2.new(0, size, 0, size)
&#9;&#9;frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2)
&#9;end
&#9;frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc, giveDoneButton)
&#9;imageLabel.Parent = contentFrame
&#9;return frame
end
t.AddTutorialPage = function(tutorial, tutorialPage)
&#9;local transitionFrame = tutorial.TransitionFrame
&#9;local currentPageValue = tutorial.CurrentTutorialPage
&#9;if not tutorial.Buttons.Value then
&#9;&#9;tutorialPage.NextButton.Parent = nil
&#9;&#9;tutorialPage.PrevButton.Parent = nil
&#9;end
&#9;local children = tutorial.Pages:GetChildren()
&#9;if children and #children &gt; 0 then
&#9;&#9;tutorialPage.Name = &quot;TutorialPage&quot; .. (#children+1)
&#9;&#9;local previousPage = children[#children]
&#9;&#9;if not previousPage:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;error(&quot;All elements under Pages must be GuiObjects&quot;)
&#9;&#9;end
&#9;&#9;if tutorial.Buttons.Value then
&#9;&#9;&#9;if previousPage.NextButton.Active then
&#9;&#9;&#9;&#9;error(&quot;NextButton already Active on previousPage, please only add pages with RbxGui.AddTutorialPage function&quot;)
&#9;&#9;&#9;end
&#9;&#9;&#9;previousPage.NextButton.MouseButton1Click:connect(
&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;TransitionTutorialPages(previousPage, tutorialPage, transitionFrame, currentPageValue)
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;previousPage.NextButton.Active = true
&#9;&#9;&#9;previousPage.NextButton.Visible = true
&#9;&#9;&#9;if tutorialPage.PrevButton.Active then
&#9;&#9;&#9;&#9;error(&quot;PrevButton already Active on tutorialPage, please only add pages with RbxGui.AddTutorialPage function&quot;)
&#9;&#9;&#9;end
&#9;&#9;&#9;tutorialPage.PrevButton.MouseButton1Click:connect(
&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;TransitionTutorialPages(tutorialPage, previousPage, transitionFrame, currentPageValue)
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;tutorialPage.PrevButton.Active = true
&#9;&#9;&#9;tutorialPage.PrevButton.Visible = true
&#9;&#9;end
&#9;&#9;tutorialPage.Parent = tutorial.Pages
&#9;else
&#9;&#9;--First child
&#9;&#9;tutorialPage.Name = &quot;TutorialPage1&quot;
&#9;&#9;tutorialPage.Parent = tutorial.Pages
&#9;end
end
t.CreateSetPanel = function(userIdsForSets, objectSelected, dialogClosed, size, position, showAdminCategories, useAssetVersionId)
&#9;if not userIdsForSets then
&#9;&#9;error(&quot;CreateSetPanel: userIdsForSets (first arg) is nil, should be a table of number ids&quot;)
&#9;end
&#9;if type(userIdsForSets) ~= &quot;table&quot; and type(userIdsForSets) ~= &quot;userdata&quot; then
&#9;&#9;error(&quot;CreateSetPanel: userIdsForSets (first arg) is of type &quot; ..type(userIdsForSets) .. &quot;, should be of type table or userdata&quot;)
&#9;end
&#9;if not objectSelected then
&#9;&#9;error(&quot;CreateSetPanel: objectSelected (second arg) is nil, should be a callback function!&quot;)
&#9;end
&#9;if type(objectSelected) ~= &quot;function&quot; then
&#9;&#9;error(&quot;CreateSetPanel: objectSelected (second arg) is of type &quot; .. type(objectSelected) .. &quot;, should be of type function!&quot;)
&#9;end
&#9;if dialogClosed and type(dialogClosed) ~= &quot;function&quot; then
&#9;&#9;error(&quot;CreateSetPanel: dialogClosed (third arg) is of type &quot; .. type(dialogClosed) .. &quot;, should be of type function!&quot;)
&#9;end
&#9;
&#9;if showAdminCategories == nil then -- by default, don&apos;t show beta sets
&#9;&#9;showAdminCategories = false
&#9;end
&#9;local arrayPosition = 1
&#9;local insertButtons = {}
&#9;local insertButtonCons = {}
&#9;local contents = nil
&#9;local setGui = nil
&#9;-- used for water selections
&#9;local waterForceDirection = &quot;NegX&quot;
&#9;local waterForce = &quot;None&quot;
&#9;local waterGui, waterTypeChangedEvent = nil
&#9;
&#9;local Data = {}
&#9;Data.CurrentCategory = nil
&#9;Data.Category = {}
&#9;local SetCache = {}
&#9;
&#9;local userCategoryButtons = nil
&#9;
&#9;local buttonWidth = 64
&#9;local buttonHeight = buttonWidth
&#9;
&#9;local SmallThumbnailUrl = nil
&#9;local LargeThumbnailUrl = nil
&#9;local BaseUrl = game:GetService(&quot;ContentProvider&quot;).BaseUrl:lower()
&#9;
&#9;if useAssetVersionId then
&#9;&#9;LargeThumbnailUrl = BaseUrl .. &quot;Game/Tools/ThumbnailAsset.ashx?fmt=png&amp;wd=420&amp;ht=420&amp;assetversionid=&quot;
&#9;&#9;SmallThumbnailUrl = BaseUrl .. &quot;Game/Tools/ThumbnailAsset.ashx?fmt=png&amp;wd=75&amp;ht=75&amp;assetversionid=&quot;
&#9;else
&#9;&#9;LargeThumbnailUrl = BaseUrl .. &quot;Game/Tools/ThumbnailAsset.ashx?fmt=png&amp;wd=420&amp;ht=420&amp;aid=&quot;
&#9;&#9;SmallThumbnailUrl = BaseUrl .. &quot;Game/Tools/ThumbnailAsset.ashx?fmt=png&amp;wd=75&amp;ht=75&amp;aid=&quot;
&#9;end
&#9;&#9;
&#9;local function drillDownSetZIndex(parent, index)
&#9;&#9;local children = parent:GetChildren()
&#9;&#9;for i = 1, #children do
&#9;&#9;&#9;if children[i]:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;children[i].ZIndex = index
&#9;&#9;&#9;end
&#9;&#9;&#9;drillDownSetZIndex(children[i], index)
&#9;&#9;end
&#9;end
&#9;
&#9;-- for terrain stamping
&#9;local currTerrainDropDownFrame = nil
&#9;local terrainShapes = {&quot;Block&quot;,&quot;Vertical Ramp&quot;,&quot;Corner Wedge&quot;,&quot;Inverse Corner Wedge&quot;,&quot;Horizontal Ramp&quot;,&quot;Auto-Wedge&quot;}
&#9;local terrainShapeMap = {}
&#9;for i = 1, #terrainShapes do
&#9;&#9;terrainShapeMap[terrainShapes[i]] = i - 1
&#9;end&#9;
&#9;terrainShapeMap[terrainShapes[#terrainShapes]] = 6
&#9;local function createWaterGui()
&#9;&#9;local waterForceDirections = {&quot;NegX&quot;,&quot;X&quot;,&quot;NegY&quot;,&quot;Y&quot;,&quot;NegZ&quot;,&quot;Z&quot;}
&#9;&#9;local waterForces = {&quot;None&quot;, &quot;Small&quot;, &quot;Medium&quot;, &quot;Strong&quot;, &quot;Max&quot;}
&#9;&#9;local waterFrame = Instance.new(&quot;Frame&quot;)
&#9;&#9;waterFrame.Name = &quot;WaterFrame&quot;
&#9;&#9;waterFrame.Style = Enum.FrameStyle.RobloxSquare
&#9;&#9;waterFrame.Size = UDim2.new(0,150,0,110)
&#9;&#9;waterFrame.Visible = false
&#9;&#9;local waterForceLabel = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;waterForceLabel.Name = &quot;WaterForceLabel&quot;
&#9;&#9;waterForceLabel.BackgroundTransparency = 1
&#9;&#9;waterForceLabel.Size = UDim2.new(1,0,0,12)
&#9;&#9;waterForceLabel.Font = Enum.Font.ArialBold
&#9;&#9;waterForceLabel.FontSize = Enum.FontSize.Size12
&#9;&#9;waterForceLabel.TextColor3 = Color3.new(1,1,1)
&#9;&#9;waterForceLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;waterForceLabel.Text = &quot;Water Force&quot;
&#9;&#9;waterForceLabel.Parent = waterFrame
&#9;&#9;local waterForceDirLabel = waterForceLabel:Clone()
&#9;&#9;waterForceDirLabel.Name = &quot;WaterForceDirectionLabel&quot;
&#9;&#9;waterForceDirLabel.Text = &quot;Water Force Direction&quot;
&#9;&#9;waterForceDirLabel.Position = UDim2.new(0,0,0,50)
&#9;&#9;waterForceDirLabel.Parent = waterFrame
&#9;&#9;local waterTypeChangedEvent = Instance.new(&quot;BindableEvent&quot;,waterFrame)
&#9;&#9;waterTypeChangedEvent.Name = &quot;WaterTypeChangedEvent&quot;
&#9;&#9;local waterForceDirectionSelectedFunc = function(newForceDirection)
&#9;&#9;&#9;waterForceDirection = newForceDirection
&#9;&#9;&#9;waterTypeChangedEvent:Fire({waterForce, waterForceDirection})
&#9;&#9;end
&#9;&#9;local waterForceSelectedFunc = function(newForce)
&#9;&#9;&#9;waterForce = newForce
&#9;&#9;&#9;waterTypeChangedEvent:Fire({waterForce, waterForceDirection})
&#9;&#9;end
&#9;&#9;local waterForceDirectionDropDown, forceWaterDirectionSelection = t.CreateDropDownMenu(waterForceDirections, waterForceDirectionSelectedFunc)
&#9;&#9;waterForceDirectionDropDown.Size = UDim2.new(1,0,0,25)
&#9;&#9;waterForceDirectionDropDown.Position = UDim2.new(0,0,1,3)
&#9;&#9;forceWaterDirectionSelection(&quot;NegX&quot;)
&#9;&#9;waterForceDirectionDropDown.Parent = waterForceDirLabel
&#9;&#9;local waterForceDropDown, forceWaterForceSelection = t.CreateDropDownMenu(waterForces, waterForceSelectedFunc)
&#9;&#9;forceWaterForceSelection(&quot;None&quot;)
&#9;&#9;waterForceDropDown.Size = UDim2.new(1,0,0,25)
&#9;&#9;waterForceDropDown.Position = UDim2.new(0,0,1,3)
&#9;&#9;waterForceDropDown.Parent = waterForceLabel
&#9;&#9;return waterFrame, waterTypeChangedEvent
&#9;end
&#9;-- Helper Function that contructs gui elements
&#9;local function createSetGui()
&#9;
&#9;&#9;local setGui = Instance.new(&quot;ScreenGui&quot;)
&#9;&#9;setGui.Name = &quot;SetGui&quot;
&#9;&#9;
&#9;&#9;local setPanel = Instance.new(&quot;Frame&quot;)
&#9;&#9;setPanel.Name = &quot;SetPanel&quot;
&#9;&#9;setPanel.Active = true
&#9;&#9;setPanel.BackgroundTransparency = 1
&#9;&#9;if position then
&#9;&#9;&#9;setPanel.Position = position
&#9;&#9;else
&#9;&#9;&#9;setPanel.Position = UDim2.new(0.2, 29, 0.1, 24)
&#9;&#9;end
&#9;&#9;if size then
&#9;&#9;&#9;setPanel.Size = size
&#9;&#9;else
&#9;&#9;&#9;setPanel.Size = UDim2.new(0.6, -58, 0.64, 0)
&#9;&#9;end
&#9;&#9;setPanel.Style = Enum.FrameStyle.RobloxRound
&#9;&#9;setPanel.ZIndex = 6
&#9;&#9;setPanel.Parent = setGui
&#9;&#9;
&#9;&#9;&#9;-- Children of SetPanel
&#9;&#9;&#9;local itemPreview = Instance.new(&quot;Frame&quot;)
&#9;&#9;&#9;itemPreview.Name = &quot;ItemPreview&quot;
&#9;&#9;&#9;itemPreview.BackgroundTransparency = 1
&#9;&#9;&#9;itemPreview.Position = UDim2.new(0.8,5,0.085,0)
&#9;&#9;&#9;itemPreview.Size = UDim2.new(0.21,0,0.9,0)
&#9;&#9;&#9;itemPreview.ZIndex = 6
&#9;&#9;&#9;itemPreview.Parent = setPanel
&#9;&#9;&#9;
&#9;&#9;&#9;&#9;-- Children of ItemPreview
&#9;&#9;&#9;&#9;local textPanel = Instance.new(&quot;Frame&quot;)
&#9;&#9;&#9;&#9;textPanel.Name = &quot;TextPanel&quot;
&#9;&#9;&#9;&#9;textPanel.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;textPanel.Position = UDim2.new(0,0,0.45,0)
&#9;&#9;&#9;&#9;textPanel.Size = UDim2.new(1,0,0.55,0)
&#9;&#9;&#9;&#9;textPanel.ZIndex = 6
&#9;&#9;&#9;&#9;textPanel.Parent = itemPreview
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;-- Children of TextPanel
&#9;&#9;&#9;&#9;&#9;local rolloverText = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;&#9;&#9;&#9;rolloverText.Name = &quot;RolloverText&quot;
&#9;&#9;&#9;&#9;&#9;rolloverText.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;&#9;rolloverText.Size = UDim2.new(1,0,0,48)
&#9;&#9;&#9;&#9;&#9;rolloverText.ZIndex = 6
&#9;&#9;&#9;&#9;&#9;rolloverText.Font = Enum.Font.ArialBold
&#9;&#9;&#9;&#9;&#9;rolloverText.FontSize = Enum.FontSize.Size24
&#9;&#9;&#9;&#9;&#9;rolloverText.Text = &quot;&quot;
&#9;&#9;&#9;&#9;&#9;rolloverText.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;&#9;rolloverText.TextWrap = true
&#9;&#9;&#9;&#9;&#9;rolloverText.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;&#9;&#9;&#9;rolloverText.TextYAlignment = Enum.TextYAlignment.Top
&#9;&#9;&#9;&#9;&#9;rolloverText.Parent = textPanel
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local largePreview = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;&#9;&#9;largePreview.Name = &quot;LargePreview&quot;
&#9;&#9;&#9;&#9;largePreview.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;largePreview.Image = &quot;&quot;
&#9;&#9;&#9;&#9;largePreview.Size = UDim2.new(1,0,0,170)
&#9;&#9;&#9;&#9;largePreview.ZIndex = 6
&#9;&#9;&#9;&#9;largePreview.Parent = itemPreview
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;local sets = Instance.new(&quot;Frame&quot;)
&#9;&#9;&#9;sets.Name = &quot;Sets&quot;
&#9;&#9;&#9;sets.BackgroundTransparency = 1
&#9;&#9;&#9;sets.Position = UDim2.new(0,0,0,5)
&#9;&#9;&#9;sets.Size = UDim2.new(0.23,0,1,-5)
&#9;&#9;&#9;sets.ZIndex = 6
&#9;&#9;&#9;sets.Parent = setPanel
&#9;&#9;&#9;
&#9;&#9;&#9;&#9;-- Children of Sets
&#9;&#9;&#9;&#9;local line = Instance.new(&quot;Frame&quot;)
&#9;&#9;&#9;&#9;line.Name = &quot;Line&quot;
&#9;&#9;&#9;&#9;line.BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;line.BackgroundTransparency = 0.7
&#9;&#9;&#9;&#9;line.BorderSizePixel = 0
&#9;&#9;&#9;&#9;line.Position = UDim2.new(1,-3,0.06,0)
&#9;&#9;&#9;&#9;line.Size = UDim2.new(0,3,0.9,0)
&#9;&#9;&#9;&#9;line.ZIndex = 6
&#9;&#9;&#9;&#9;line.Parent = sets
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local setsLists, controlFrame = t.CreateTrueScrollingFrame()
&#9;&#9;&#9;&#9;setsLists.Size = UDim2.new(1,-6,0.94,0)
&#9;&#9;&#9;&#9;setsLists.Position = UDim2.new(0,0,0.06,0)
&#9;&#9;&#9;&#9;setsLists.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;setsLists.Name = &quot;SetsLists&quot;
&#9;&#9;&#9;&#9;setsLists.ZIndex = 6
&#9;&#9;&#9;&#9;setsLists.Parent = sets
&#9;&#9;&#9;&#9;drillDownSetZIndex(controlFrame, 7)
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local setsHeader = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;&#9;&#9;setsHeader.Name = &quot;SetsHeader&quot;
&#9;&#9;&#9;&#9;setsHeader.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;setsHeader.Size = UDim2.new(0,47,0,24)
&#9;&#9;&#9;&#9;setsHeader.ZIndex = 6
&#9;&#9;&#9;&#9;setsHeader.Font = Enum.Font.ArialBold
&#9;&#9;&#9;&#9;setsHeader.FontSize = Enum.FontSize.Size24
&#9;&#9;&#9;&#9;setsHeader.Text = &quot;Sets&quot;
&#9;&#9;&#9;&#9;setsHeader.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;setsHeader.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;&#9;&#9;setsHeader.TextYAlignment = Enum.TextYAlignment.Top
&#9;&#9;&#9;&#9;setsHeader.Parent = sets
&#9;&#9;&#9;
&#9;&#9;&#9;local cancelButton = Instance.new(&quot;TextButton&quot;)
&#9;&#9;&#9;cancelButton.Name = &quot;CancelButton&quot;
&#9;&#9;&#9;cancelButton.Position = UDim2.new(1,-32,0,-2)
&#9;&#9;&#9;cancelButton.Size = UDim2.new(0,34,0,34)
&#9;&#9;&#9;cancelButton.Style = Enum.ButtonStyle.RobloxButtonDefault
&#9;&#9;&#9;cancelButton.ZIndex = 6
&#9;&#9;&#9;cancelButton.Text = &quot;&quot;
&#9;&#9;&#9;cancelButton.Modal = true
&#9;&#9;&#9;cancelButton.Parent = setPanel
&#9;&#9;&#9;
&#9;&#9;&#9;&#9;-- Children of Cancel Button
&#9;&#9;&#9;&#9;local cancelImage = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;&#9;&#9;cancelImage.Name = &quot;CancelImage&quot;
&#9;&#9;&#9;&#9;cancelImage.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;cancelImage.Image = &quot;http://www.roblox.com/asset/?id=54135717&quot;
&#9;&#9;&#9;&#9;cancelImage.Position = UDim2.new(0,-2,0,-2)
&#9;&#9;&#9;&#9;cancelImage.Size = UDim2.new(0,16,0,16)
&#9;&#9;&#9;&#9;cancelImage.ZIndex = 6
&#9;&#9;&#9;&#9;cancelImage.Parent = cancelButton
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;return setGui
&#9;end
&#9;
&#9;local function createSetButton(text)
&#9;&#9;local setButton = Instance.new(&quot;TextButton&quot;)
&#9;&#9;
&#9;&#9;if text then setButton.Text = text
&#9;&#9;else setButton.Text = &quot;&quot; end
&#9;&#9;
&#9;&#9;setButton.AutoButtonColor = false
&#9;&#9;setButton.BackgroundTransparency = 1
&#9;&#9;setButton.BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;setButton.BorderSizePixel = 0
&#9;&#9;setButton.Size = UDim2.new(1,-5,0,18)
&#9;&#9;setButton.ZIndex = 6
&#9;&#9;setButton.Visible = false
&#9;&#9;setButton.Font = Enum.Font.Arial
&#9;&#9;setButton.FontSize = Enum.FontSize.Size18
&#9;&#9;setButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;setButton.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;
&#9;&#9;return setButton
&#9;end
&#9;
&#9;local function buildSetButton(name, setId, setImageId, i, count)
&#9;&#9;local button = createSetButton(name)
&#9;&#9;button.Text = name
&#9;&#9;button.Name = &quot;SetButton&quot;
&#9;&#9;button.Visible = true
&#9;&#9;
&#9;&#9;local setValue = Instance.new(&quot;IntValue&quot;)
&#9;&#9;setValue.Name = &quot;SetId&quot;
&#9;&#9;setValue.Value = setId
&#9;&#9;setValue.Parent = button
&#9;&#9;local setName = Instance.new(&quot;StringValue&quot;)
&#9;&#9;setName.Name = &quot;SetName&quot;
&#9;&#9;setName.Value = name
&#9;&#9;setName.Parent = button
&#9;&#9;return button
&#9;end
&#9;
&#9;local function processCategory(sets)
&#9;&#9;local setButtons = {}
&#9;&#9;local numSkipped = 0
&#9;&#9;for i = 1, #sets do
&#9;&#9;&#9;if not showAdminCategories and sets[i].Name == &quot;Beta&quot; then
&#9;&#9;&#9;&#9;numSkipped = numSkipped + 1
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;setButtons[i - numSkipped] = buildSetButton(sets[i].Name, sets[i].CategoryId, sets[i].ImageAssetId, i - numSkipped, #sets)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;return setButtons
&#9;end
&#9;
&#9;local function handleResize()
&#9;&#9;wait() -- neccessary to insure heartbeat happened
&#9;&#9;
&#9;&#9;local itemPreview = setGui.SetPanel.ItemPreview
&#9;&#9;
&#9;&#9;itemPreview.LargePreview.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.X)
&#9;&#9;itemPreview.LargePreview.Position = UDim2.new(0.5,-itemPreview.LargePreview.AbsoluteSize.X/2,0,0)
&#9;&#9;itemPreview.TextPanel.Position = UDim2.new(0,0,0,itemPreview.LargePreview.AbsoluteSize.Y)
&#9;&#9;itemPreview.TextPanel.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.Y - itemPreview.LargePreview.AbsoluteSize.Y)
&#9;end
&#9;
&#9;local function makeInsertAssetButton()
&#9;&#9;local insertAssetButtonExample = Instance.new(&quot;Frame&quot;)
&#9;&#9;insertAssetButtonExample.Name = &quot;InsertAssetButtonExample&quot;
&#9;&#9;insertAssetButtonExample.Position = UDim2.new(0,128,0,64)
&#9;&#9;insertAssetButtonExample.Size = UDim2.new(0,64,0,64)
&#9;&#9;insertAssetButtonExample.BackgroundTransparency = 1
&#9;&#9;insertAssetButtonExample.ZIndex = 6
&#9;&#9;insertAssetButtonExample.Visible = false
&#9;&#9;local assetId = Instance.new(&quot;IntValue&quot;)
&#9;&#9;assetId.Name = &quot;AssetId&quot;
&#9;&#9;assetId.Value = 0
&#9;&#9;assetId.Parent = insertAssetButtonExample
&#9;&#9;
&#9;&#9;local assetName = Instance.new(&quot;StringValue&quot;)
&#9;&#9;assetName.Name = &quot;AssetName&quot;
&#9;&#9;assetName.Value = &quot;&quot;
&#9;&#9;assetName.Parent = insertAssetButtonExample
&#9;&#9;local button = Instance.new(&quot;TextButton&quot;)
&#9;&#9;button.Name = &quot;Button&quot;
&#9;&#9;button.Text = &quot;&quot;
&#9;&#9;button.Style = Enum.ButtonStyle.RobloxButton
&#9;&#9;button.Position = UDim2.new(0.025,0,0.025,0)
&#9;&#9;button.Size = UDim2.new(0.95,0,0.95,0)
&#9;&#9;button.ZIndex = 6
&#9;&#9;button.Parent = insertAssetButtonExample
&#9;&#9;local buttonImage = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;buttonImage.Name = &quot;ButtonImage&quot;
&#9;&#9;buttonImage.Image = &quot;&quot;
&#9;&#9;buttonImage.Position = UDim2.new(0,-7,0,-7)
&#9;&#9;buttonImage.Size = UDim2.new(1,14,1,14)
&#9;&#9;buttonImage.BackgroundTransparency = 1
&#9;&#9;buttonImage.ZIndex = 7
&#9;&#9;buttonImage.Parent = button
&#9;&#9;local configIcon = buttonImage:clone()
&#9;&#9;configIcon.Name = &quot;ConfigIcon&quot;
&#9;&#9;configIcon.Visible = false
&#9;&#9;configIcon.Position = UDim2.new(1,-23,1,-24)
&#9;&#9;configIcon.Size = UDim2.new(0,16,0,16)
&#9;&#9;configIcon.Image = &quot;&quot;
&#9;&#9;configIcon.ZIndex = 6
&#9;&#9;configIcon.Parent = insertAssetButtonExample
&#9;&#9;
&#9;&#9;return insertAssetButtonExample
&#9;end
&#9;
&#9;local function showLargePreview(insertButton)
&#9;&#9;if insertButton:FindFirstChild(&quot;AssetId&quot;) then
&#9;&#9;&#9;delay(0,function()
&#9;&#9;&#9;&#9;game:GetService(&quot;ContentProvider&quot;):Preload(LargeThumbnailUrl .. tostring(insertButton.AssetId.Value))
&#9;&#9;&#9;&#9;setGui.SetPanel.ItemPreview.LargePreview.Image = LargeThumbnailUrl .. tostring(insertButton.AssetId.Value)
&#9;&#9;&#9;end)
&#9;&#9;end
&#9;&#9;if insertButton:FindFirstChild(&quot;AssetName&quot;) then
&#9;&#9;&#9;setGui.SetPanel.ItemPreview.TextPanel.RolloverText.Text = insertButton.AssetName.Value
&#9;&#9;end
&#9;end
&#9;
&#9;local function selectTerrainShape(shape)
&#9;&#9;if currTerrainDropDownFrame then
&#9;&#9;&#9;objectSelected(tostring(currTerrainDropDownFrame.AssetName.Value), tonumber(currTerrainDropDownFrame.AssetId.Value), shape)
&#9;&#9;end
&#9;end
&#9;
&#9;local function createTerrainTypeButton(name, parent)
&#9;&#9;local dropDownTextButton = Instance.new(&quot;TextButton&quot;)
&#9;&#9;dropDownTextButton.Name = name .. &quot;Button&quot;
&#9;&#9;dropDownTextButton.Font = Enum.Font.ArialBold
&#9;&#9;dropDownTextButton.FontSize = Enum.FontSize.Size14
&#9;&#9;dropDownTextButton.BorderSizePixel = 0
&#9;&#9;dropDownTextButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;dropDownTextButton.Text = name
&#9;&#9;dropDownTextButton.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;dropDownTextButton.BackgroundTransparency = 1
&#9;&#9;dropDownTextButton.ZIndex = parent.ZIndex + 1
&#9;&#9;dropDownTextButton.Size = UDim2.new(0,parent.Size.X.Offset - 2,0,16)
&#9;&#9;dropDownTextButton.Position = UDim2.new(0,1,0,0)
&#9;&#9;dropDownTextButton.MouseEnter:connect(function()
&#9;&#9;&#9;dropDownTextButton.BackgroundTransparency = 0
&#9;&#9;&#9;dropDownTextButton.TextColor3 = Color3.new(0,0,0)
&#9;&#9;end)
&#9;&#9;dropDownTextButton.MouseLeave:connect(function()
&#9;&#9;&#9;dropDownTextButton.BackgroundTransparency = 1
&#9;&#9;&#9;dropDownTextButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;end)
&#9;&#9;dropDownTextButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;dropDownTextButton.BackgroundTransparency = 1
&#9;&#9;&#9;dropDownTextButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;if dropDownTextButton.Parent and dropDownTextButton.Parent:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;dropDownTextButton.Parent.Visible = false
&#9;&#9;&#9;end
&#9;&#9;&#9;selectTerrainShape(terrainShapeMap[dropDownTextButton.Text])
&#9;&#9;end)
&#9;&#9;return dropDownTextButton
&#9;end
&#9;
&#9;local function createTerrainDropDownMenu(zIndex)
&#9;&#9;local dropDown = Instance.new(&quot;Frame&quot;)
&#9;&#9;dropDown.Name = &quot;TerrainDropDown&quot;
&#9;&#9;dropDown.BackgroundColor3 = Color3.new(0,0,0)
&#9;&#9;dropDown.BorderColor3 = Color3.new(1,0,0)
&#9;&#9;dropDown.Size = UDim2.new(0,200,0,0)
&#9;&#9;dropDown.Visible = false
&#9;&#9;dropDown.ZIndex = zIndex
&#9;&#9;dropDown.Parent = setGui
&#9;&#9;for i = 1, #terrainShapes do
&#9;&#9;&#9;local shapeButton = createTerrainTypeButton(terrainShapes[i],dropDown)
&#9;&#9;&#9;shapeButton.Position = UDim2.new(0,1,0,(i - 1) * (shapeButton.Size.Y.Offset))
&#9;&#9;&#9;shapeButton.Parent = dropDown
&#9;&#9;&#9;dropDown.Size = UDim2.new(0,200,0,dropDown.Size.Y.Offset + (shapeButton.Size.Y.Offset))
&#9;&#9;end
&#9;&#9;dropDown.MouseLeave:connect(function()
&#9;&#9;&#9;dropDown.Visible = false
&#9;&#9;end)
&#9;end
&#9;
&#9;local function createDropDownMenuButton(parent)
&#9;&#9;local dropDownButton = Instance.new(&quot;ImageButton&quot;)
&#9;&#9;dropDownButton.Name = &quot;DropDownButton&quot;
&#9;&#9;dropDownButton.Image = &quot;http://www.roblox.com/asset/?id=67581509&quot;
&#9;&#9;dropDownButton.BackgroundTransparency = 1
&#9;&#9;dropDownButton.Size = UDim2.new(0,16,0,16)
&#9;&#9;dropDownButton.Position = UDim2.new(1,-24,0,6)
&#9;&#9;dropDownButton.ZIndex = parent.ZIndex + 2
&#9;&#9;dropDownButton.Parent = parent
&#9;&#9;
&#9;&#9;if not setGui:FindFirstChild(&quot;TerrainDropDown&quot;) then
&#9;&#9;&#9;createTerrainDropDownMenu(8)
&#9;&#9;end
&#9;&#9;
&#9;&#9;dropDownButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;setGui.TerrainDropDown.Visible = true
&#9;&#9;&#9;setGui.TerrainDropDown.Position = UDim2.new(0,parent.AbsolutePosition.X,0,parent.AbsolutePosition.Y)
&#9;&#9;&#9;currTerrainDropDownFrame = parent
&#9;&#9;end)
&#9;end
&#9;
&#9;local function buildInsertButton()
&#9;&#9;local insertButton = makeInsertAssetButton()
&#9;&#9;insertButton.Name = &quot;InsertAssetButton&quot;
&#9;&#9;insertButton.Visible = true
&#9;&#9;if Data.Category[Data.CurrentCategory].SetName == &quot;High Scalability&quot; then
&#9;&#9;&#9;createDropDownMenuButton(insertButton)
&#9;&#9;end
&#9;&#9;local lastEnter = nil
&#9;&#9;local mouseEnterCon = insertButton.MouseEnter:connect(function()
&#9;&#9;&#9;lastEnter = insertButton
&#9;&#9;&#9;delay(0.1,function()
&#9;&#9;&#9;&#9;if lastEnter == insertButton then
&#9;&#9;&#9;&#9;&#9;showLargePreview(insertButton)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;end)
&#9;&#9;return insertButton, mouseEnterCon
&#9;end
&#9;
&#9;local function realignButtonGrid(columns)
&#9;&#9;local x = 0
&#9;&#9;local y = 0
&#9;&#9;for i = 1, #insertButtons do
&#9;&#9;&#9;insertButtons[i].Position = UDim2.new(0, buttonWidth * x, 0, buttonHeight * y)
&#9;&#9;&#9;x = x + 1
&#9;&#9;&#9;if x &gt;= columns then
&#9;&#9;&#9;&#9;x = 0
&#9;&#9;&#9;&#9;y = y + 1
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local function setInsertButtonImageBehavior(insertFrame, visible, name, assetId)
&#9;&#9;if visible then
&#9;&#9;&#9;insertFrame.AssetName.Value = name
&#9;&#9;&#9;insertFrame.AssetId.Value = assetId
&#9;&#9;&#9;local newImageUrl = SmallThumbnailUrl .. assetId
&#9;&#9;&#9;if newImageUrl ~= insertFrame.Button.ButtonImage.Image then
&#9;&#9;&#9;&#9;delay(0,function()
&#9;&#9;&#9;&#9;&#9;game:GetService(&quot;ContentProvider&quot;):Preload(SmallThumbnailUrl .. assetId)
&#9;&#9;&#9;&#9;&#9;if insertFrame:findFirstChild(&quot;Button&quot;) then
&#9;&#9;&#9;&#9;&#9;&#9;insertFrame.Button.ButtonImage.Image = SmallThumbnailUrl .. assetId
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;&#9;table.insert(insertButtonCons,
&#9;&#9;&#9;&#9;insertFrame.Button.MouseButton1Click:connect(function()
&#9;&#9;&#9;&#9;&#9;-- special case for water, show water selection gui
&#9;&#9;&#9;&#9;&#9;local isWaterSelected = (name == &quot;Water&quot;) and (Data.Category[Data.CurrentCategory].SetName == &quot;High Scalability&quot;)
&#9;&#9;&#9;&#9;&#9;waterGui.Visible = isWaterSelected
&#9;&#9;&#9;&#9;&#9;if isWaterSelected then
&#9;&#9;&#9;&#9;&#9;&#9;objectSelected(name, tonumber(assetId), nil)
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;objectSelected(name, tonumber(assetId))
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;)
&#9;&#9;&#9;insertFrame.Visible = true
&#9;&#9;else
&#9;&#9;&#9;insertFrame.Visible = false
&#9;&#9;end
&#9;end
&#9;
&#9;local function loadSectionOfItems(setGui, rows, columns)
&#9;&#9;local pageSize = rows * columns
&#9;&#9;if arrayPosition &gt; #contents then return end
&#9;&#9;local origArrayPos = arrayPosition
&#9;&#9;local yCopy = 0
&#9;&#9;for i = 1, pageSize + 1 do
&#9;&#9;&#9;if arrayPosition &gt;= #contents + 1 then
&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;end
&#9;&#9;&#9;local buttonCon
&#9;&#9;&#9;insertButtons[arrayPosition], buttonCon = buildInsertButton()
&#9;&#9;&#9;table.insert(insertButtonCons,buttonCon)
&#9;&#9;&#9;insertButtons[arrayPosition].Parent = setGui.SetPanel.ItemsFrame
&#9;&#9;&#9;arrayPosition = arrayPosition + 1
&#9;&#9;end
&#9;&#9;realignButtonGrid(columns)
&#9;&#9;local indexCopy = origArrayPos
&#9;&#9;for index = origArrayPos, arrayPosition do
&#9;&#9;&#9;if insertButtons[index] then
&#9;&#9;&#9;&#9;if contents[index] then
&#9;&#9;&#9;&#9;&#9;-- we don&apos;t want water to have a drop down button
&#9;&#9;&#9;&#9;&#9;if contents[index].Name == &quot;Water&quot; then
&#9;&#9;&#9;&#9;&#9;&#9;if Data.Category[Data.CurrentCategory].SetName == &quot;High Scalability&quot; then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;insertButtons[index]:FindFirstChild(&quot;DropDownButton&quot;,true):Destroy()
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;local assetId
&#9;&#9;&#9;&#9;&#9;if useAssetVersionId then
&#9;&#9;&#9;&#9;&#9;&#9;assetId = contents[index].AssetVersionId
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;assetId = contents[index].AssetId
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;setInsertButtonImageBehavior(insertButtons[index], true, contents[index].Name, assetId)
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;end
&#9;&#9;&#9;indexCopy = index
&#9;&#9;end
&#9;end
&#9;
&#9;local function setSetIndex()
&#9;&#9;Data.Category[Data.CurrentCategory].Index = 0
&#9;&#9;rows = 7
&#9;&#9;columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth)
&#9;&#9;contents = Data.Category[Data.CurrentCategory].Contents
&#9;&#9;if contents then
&#9;&#9;&#9;-- remove our buttons and their connections
&#9;&#9;&#9;for i = 1, #insertButtons do
&#9;&#9;&#9;&#9;insertButtons[i]:remove()
&#9;&#9;&#9;end
&#9;&#9;&#9;for i = 1, #insertButtonCons do
&#9;&#9;&#9;&#9;if insertButtonCons[i] then insertButtonCons[i]:disconnect() end
&#9;&#9;&#9;end
&#9;&#9;&#9;insertButtonCons = {}
&#9;&#9;&#9;insertButtons = {}
&#9;&#9;&#9;arrayPosition = 1
&#9;&#9;&#9;loadSectionOfItems(setGui, rows, columns)
&#9;&#9;end
&#9;end
&#9;
&#9;local function selectSet(button, setName, setId, setIndex)
&#9;&#9;if button and Data.Category[Data.CurrentCategory] ~= nil then
&#9;&#9;&#9;if button ~= Data.Category[Data.CurrentCategory].Button then
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory].Button = button
&#9;&#9;&#9;&#9;if SetCache[setId] == nil then
&#9;&#9;&#9;&#9;&#9;SetCache[setId] = game:GetService(&quot;InsertService&quot;):GetCollection(setId)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory].Contents = SetCache[setId]
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory].SetName = setName
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory].SetId = setId
&#9;&#9;&#9;end
&#9;&#9;&#9;setSetIndex()
&#9;&#9;end
&#9;end
&#9;
&#9;local function selectCategoryPage(buttons, page)
&#9;&#9;if buttons ~= Data.CurrentCategory then
&#9;&#9;&#9;if Data.CurrentCategory then
&#9;&#9;&#9;&#9;for key, button in pairs(Data.CurrentCategory) do
&#9;&#9;&#9;&#9;&#9;button.Visible = false
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;Data.CurrentCategory = buttons
&#9;&#9;&#9;if Data.Category[Data.CurrentCategory] == nil then
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory] = {}
&#9;&#9;&#9;&#9;if #buttons &gt; 0 then
&#9;&#9;&#9;&#9;&#9;selectSet(buttons[1], buttons[1].SetName.Value, buttons[1].SetId.Value, 0)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory].Button = nil
&#9;&#9;&#9;&#9;selectSet(Data.Category[Data.CurrentCategory].ButtonFrame, Data.Category[Data.CurrentCategory].SetName, Data.Category[Data.CurrentCategory].SetId, Data.Category[Data.CurrentCategory].Index)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;
&#9;local function selectCategory(category)
&#9;&#9;selectCategoryPage(category, 0)
&#9;end
&#9;
&#9;local function resetAllSetButtonSelection()
&#9;&#9;local setButtons = setGui.SetPanel.Sets.SetsLists:GetChildren()
&#9;&#9;for i = 1, #setButtons do
&#9;&#9;&#9;if setButtons[i]:IsA(&quot;TextButton&quot;) then
&#9;&#9;&#9;&#9;setButtons[i].Selected = false
&#9;&#9;&#9;&#9;setButtons[i].BackgroundTransparency = 1
&#9;&#9;&#9;&#9;setButtons[i].TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;setButtons[i].BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;
&#9;local function populateSetsFrame()
&#9;&#9;local currRow = 0
&#9;&#9;for i = 1, #userCategoryButtons do
&#9;&#9;&#9;local button = userCategoryButtons[i]
&#9;&#9;&#9;button.Visible = true
&#9;&#9;&#9;button.Position = UDim2.new(0,5,0,currRow * button.Size.Y.Offset)
&#9;&#9;&#9;button.Parent = setGui.SetPanel.Sets.SetsLists
&#9;&#9;&#9;
&#9;&#9;&#9;if i == 1 then -- we will have this selected by default, so show it
&#9;&#9;&#9;&#9;button.Selected = true
&#9;&#9;&#9;&#9;button.BackgroundColor3 = Color3.new(0,204/255,0)
&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(0,0,0)
&#9;&#9;&#9;&#9;button.BackgroundTransparency = 0
&#9;&#9;&#9;end
&#9;&#9;&#9;button.MouseEnter:connect(function()
&#9;&#9;&#9;&#9;if not button.Selected then
&#9;&#9;&#9;&#9;&#9;button.BackgroundTransparency = 0
&#9;&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(0,0,0)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;&#9;button.MouseLeave:connect(function()
&#9;&#9;&#9;&#9;if not button.Selected then
&#9;&#9;&#9;&#9;&#9;button.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;&#9;button.MouseButton1Click:connect(function()
&#9;&#9;&#9;&#9;resetAllSetButtonSelection()
&#9;&#9;&#9;&#9;button.Selected = not button.Selected
&#9;&#9;&#9;&#9;button.BackgroundColor3 = Color3.new(0,204/255,0)
&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(0,0,0)
&#9;&#9;&#9;&#9;button.BackgroundTransparency = 0
&#9;&#9;&#9;&#9;selectSet(button, button.Text, userCategoryButtons[i].SetId.Value, 0)
&#9;&#9;&#9;end)
&#9;&#9;&#9;currRow = currRow + 1
&#9;&#9;end
&#9;&#9;local buttons = setGui.SetPanel.Sets.SetsLists:GetChildren()
&#9;&#9;-- set first category as loaded for default
&#9;&#9;if buttons then
&#9;&#9;&#9;for i = 1, #buttons do
&#9;&#9;&#9;&#9;if buttons[i]:IsA(&quot;TextButton&quot;) then
&#9;&#9;&#9;&#9;&#9;selectSet(buttons[i], buttons[i].Text, userCategoryButtons[i].SetId.Value, 0)
&#9;&#9;&#9;&#9;&#9;selectCategory(userCategoryButtons)
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;setGui = createSetGui()
&#9;waterGui, waterTypeChangedEvent = createWaterGui()
&#9;waterGui.Position = UDim2.new(0,55,0,0)
&#9;waterGui.Parent = setGui
&#9;setGui.Changed:connect(function(prop) -- this resizes the preview image to always be the right size
&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;handleResize()
&#9;&#9;&#9;setSetIndex()
&#9;&#9;end
&#9;end)
&#9;
&#9;local scrollFrame, controlFrame = t.CreateTrueScrollingFrame()
&#9;scrollFrame.Size = UDim2.new(0.54,0,0.85,0)
&#9;scrollFrame.Position = UDim2.new(0.24,0,0.085,0)
&#9;scrollFrame.Name = &quot;ItemsFrame&quot;
&#9;scrollFrame.ZIndex = 6
&#9;scrollFrame.Parent = setGui.SetPanel
&#9;scrollFrame.BackgroundTransparency = 1
&#9;drillDownSetZIndex(controlFrame,7)
&#9;controlFrame.Parent = setGui.SetPanel
&#9;controlFrame.Position = UDim2.new(0.76, 5, 0, 0)
&#9;local debounce = false
&#9;controlFrame.ScrollBottom.Changed:connect(function(prop)
&#9;&#9;if controlFrame.ScrollBottom.Value == true then
&#9;&#9;&#9;if debounce then return end
&#9;&#9;&#9;debounce = true
&#9;&#9;&#9;&#9;loadSectionOfItems(setGui, rows, columns)
&#9;&#9;&#9;debounce = false
&#9;&#9;end
&#9;end)
&#9;local userData = {}
&#9;for id = 1, #userIdsForSets do
&#9;&#9;local newUserData = game:GetService(&quot;InsertService&quot;):GetUserSets(userIdsForSets[id])
&#9;&#9;if newUserData and #newUserData &gt; 2 then
&#9;&#9;&#9;-- start at #3 to skip over My Decals and My Models for each account
&#9;&#9;&#9;for category = 3, #newUserData do
&#9;&#9;&#9;&#9;if newUserData[category].Name == &quot;High Scalability&quot; then -- we want high scalability parts to show first
&#9;&#9;&#9;&#9;&#9;table.insert(userData,1,newUserData[category])
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;table.insert(userData, newUserData[category])
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;
&#9;end
&#9;if userData then
&#9;&#9;userCategoryButtons = processCategory(userData)
&#9;end
&#9;rows = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.Y/buttonHeight)
&#9;columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth)
&#9;populateSetsFrame()
&#9;insertPanelCloseCon = setGui.SetPanel.CancelButton.MouseButton1Click:connect(function()
&#9;&#9;setGui.SetPanel.Visible = false
&#9;&#9;if dialogClosed then dialogClosed() end
&#9;end)
&#9;
&#9;local setVisibilityFunction = function(visible)
&#9;&#9;if visible then
&#9;&#9;&#9;setGui.SetPanel.Visible = true
&#9;&#9;else
&#9;&#9;&#9;setGui.SetPanel.Visible = false
&#9;&#9;end
&#9;end
&#9;
&#9;local getVisibilityFunction = function()
&#9;&#9;if setGui then
&#9;&#9;&#9;if setGui:FindFirstChild(&quot;SetPanel&quot;) then
&#9;&#9;&#9;&#9;return setGui.SetPanel.Visible
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;
&#9;&#9;return false
&#9;end
&#9;
&#9;return setGui, setVisibilityFunction, getVisibilityFunction, waterTypeChangedEvent
end
t.CreateTerrainMaterialSelector = function(size,position)
&#9;local terrainMaterialSelectionChanged = Instance.new(&quot;BindableEvent&quot;)
&#9;terrainMaterialSelectionChanged.Name = &quot;TerrainMaterialSelectionChanged&quot;
&#9;local selectedButton = nil
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Name = &quot;TerrainMaterialSelector&quot;
&#9;if size then
&#9;&#9;frame.Size = size
&#9;else
&#9;&#9;frame.Size = UDim2.new(0, 245, 0, 230)
&#9;end
&#9;if position then
&#9;&#9;frame.Position = position
&#9;end
&#9;frame.BorderSizePixel = 0
&#9;frame.BackgroundColor3 = Color3.new(0,0,0)
&#9;frame.Active = true
&#9;terrainMaterialSelectionChanged.Parent = frame
&#9;local waterEnabled = true -- todo: turn this on when water is ready
&#9;local materialToImageMap = {}
&#9;local materialNames = {&quot;Grass&quot;, &quot;Sand&quot;, &quot;Brick&quot;, &quot;Granite&quot;, &quot;Asphalt&quot;, &quot;Iron&quot;, &quot;Aluminum&quot;, &quot;Gold&quot;, &quot;Plank&quot;, &quot;Log&quot;, &quot;Gravel&quot;, &quot;Cinder Block&quot;, &quot;Stone Wall&quot;, &quot;Concrete&quot;, &quot;Plastic (red)&quot;, &quot;Plastic (blue)&quot;}
&#9;if waterEnabled then
&#9;&#9;table.insert(materialNames,&quot;Water&quot;)
&#9;end
&#9;local currentMaterial = 1
&#9;function getEnumFromName(choice)
&#9;&#9;if choice == &quot;Grass&quot; then return 1 end
&#9;&#9;if choice == &quot;Sand&quot; then return 2 end
&#9;&#9;if choice == &quot;Erase&quot; then return 0 end
&#9;&#9;if choice == &quot;Brick&quot; then return 3 end
&#9;&#9;if choice == &quot;Granite&quot; then return 4 end
&#9;&#9;if choice == &quot;Asphalt&quot; then return 5 end
&#9;&#9;if choice == &quot;Iron&quot; then return 6 end
&#9;&#9;if choice == &quot;Aluminum&quot; then return 7 end
&#9;&#9;if choice == &quot;Gold&quot; then return 8 end
&#9;&#9;if choice == &quot;Plank&quot; then return 9 end
&#9;&#9;if choice == &quot;Log&quot; then return 10 end
&#9;&#9;if choice == &quot;Gravel&quot; then return 11 end
&#9;&#9;if choice == &quot;Cinder Block&quot; then return 12 end
&#9;&#9;if choice == &quot;Stone Wall&quot; then return 13 end
&#9;&#9;if choice == &quot;Concrete&quot; then return 14 end
&#9;&#9;if choice == &quot;Plastic (red)&quot; then return 15 end
&#9;&#9;if choice == &quot;Plastic (blue)&quot; then return 16 end
&#9;&#9;if choice == &quot;Water&quot; then return 17 end
&#9;end
&#9;function getNameFromEnum(choice)
&#9;&#9;if choice == Enum.CellMaterial.Grass or choice == 1 then return &quot;Grass&quot;end
&#9;&#9;if choice == Enum.CellMaterial.Sand or choice == 2 then return &quot;Sand&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Empty or choice == 0 then return &quot;Erase&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Brick or choice == 3 then return &quot;Brick&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Granite or choice == 4 then return &quot;Granite&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Asphalt or choice == 5 then return &quot;Asphalt&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Iron or choice == 6 then return &quot;Iron&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Aluminum or choice == 7 then return &quot;Aluminum&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Gold or choice == 8 then return &quot;Gold&quot; end
&#9;&#9;if choice == Enum.CellMaterial.WoodPlank or choice == 9 then return &quot;Plank&quot; end
&#9;&#9;if choice == Enum.CellMaterial.WoodLog or choice == 10 then return &quot;Log&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Gravel or choice == 11 then return &quot;Gravel&quot; end
&#9;&#9;if choice == Enum.CellMaterial.CinderBlock or choice == 12 then return &quot;Cinder Block&quot; end
&#9;&#9;if choice == Enum.CellMaterial.MossyStone or choice == 13 then return &quot;Stone Wall&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Cement or choice == 14 then return &quot;Concrete&quot; end
&#9;&#9;if choice == Enum.CellMaterial.RedPlastic or choice == 15 then return &quot;Plastic (red)&quot; end
&#9;&#9;if choice == Enum.CellMaterial.BluePlastic or choice == 16 then return &quot;Plastic (blue)&quot; end
&#9;&#9;if waterEnabled then
&#9;&#9;&#9;if choice == Enum.CellMaterial.Water or choice == 17 then return &quot;Water&quot; end
&#9;&#9;end
&#9;end
&#9;local function updateMaterialChoice(choice)
&#9;&#9;currentMaterial = getEnumFromName(choice)
&#9;&#9;terrainMaterialSelectionChanged:Fire(currentMaterial)
&#9;end
&#9;-- we so need a better way to do this
&#9;for i,v in pairs(materialNames) do
&#9;&#9;materialToImageMap[v] = {}
&#9;&#9;if v == &quot;Grass&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=56563112&quot;
&#9;&#9;elseif v == &quot;Sand&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=62356652&quot;
&#9;&#9;elseif v == &quot;Brick&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=65961537&quot;
&#9;&#9;elseif v == &quot;Granite&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532153&quot;
&#9;&#9;elseif v == &quot;Asphalt&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532038&quot;
&#9;&#9;elseif v == &quot;Iron&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532093&quot;
&#9;&#9;elseif v == &quot;Aluminum&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67531995&quot;
&#9;&#9;elseif v == &quot;Gold&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532118&quot;
&#9;&#9;elseif v == &quot;Plastic (red)&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67531848&quot;
&#9;&#9;elseif v == &quot;Plastic (blue)&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67531924&quot;
&#9;&#9;elseif v == &quot;Plank&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532015&quot;
&#9;&#9;elseif v == &quot;Log&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532051&quot;
&#9;&#9;elseif v == &quot;Gravel&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532206&quot;
&#9;&#9;elseif v == &quot;Cinder Block&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532103&quot;
&#9;&#9;elseif v == &quot;Stone Wall&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67531804&quot;
&#9;&#9;elseif v == &quot;Concrete&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532059&quot;
&#9;&#9;elseif v == &quot;Water&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=81407474&quot;
&#9;&#9;else materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=66887593&quot; -- fill in the rest here!!
&#9;&#9;end
&#9;end
&#9;local scrollFrame, scrollUp, scrollDown, recalculateScroll = t.CreateScrollingFrame(nil,&quot;grid&quot;)
&#9;scrollFrame.Size = UDim2.new(0.85,0,1,0)
&#9;scrollFrame.Position = UDim2.new(0,0,0,0)
&#9;scrollFrame.Parent = frame
&#9;scrollUp.Parent = frame
&#9;scrollUp.Visible = true
&#9;scrollUp.Position = UDim2.new(1,-19,0,0)
&#9;scrollDown.Parent = frame
&#9;scrollDown.Visible = true
&#9;scrollDown.Position = UDim2.new(1,-19,1,-17)
&#9;local function goToNewMaterial(buttonWrap, materialName)
&#9;&#9;updateMaterialChoice(materialName)
&#9;&#9;buttonWrap.BackgroundTransparency = 0
&#9;&#9;selectedButton.BackgroundTransparency = 1
&#9;&#9;selectedButton = buttonWrap
&#9;end
&#9;local function createMaterialButton(name)&#9;
&#9;&#9;local buttonWrap = Instance.new(&quot;TextButton&quot;)
&#9;&#9;buttonWrap.Text = &quot;&quot;
&#9;&#9;buttonWrap.Size = UDim2.new(0,32,0,32)
&#9;&#9;buttonWrap.BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;buttonWrap.BorderSizePixel = 0
&#9;&#9;buttonWrap.BackgroundTransparency = 1
&#9;&#9;buttonWrap.AutoButtonColor = false
&#9;&#9;buttonWrap.Name = tostring(name)
&#9;&#9;
&#9;&#9;local imageButton = Instance.new(&quot;ImageButton&quot;)
&#9;&#9;imageButton.AutoButtonColor = false
&#9;&#9;imageButton.BackgroundTransparency = 1
&#9;&#9;imageButton.Size = UDim2.new(0,30,0,30)
&#9;&#9;imageButton.Position = UDim2.new(0,1,0,1)
&#9;&#9;imageButton.Name = tostring(name)
&#9;&#9;imageButton.Parent = buttonWrap
&#9;&#9;imageButton.Image = materialToImageMap[name].Regular
&#9;&#9;local enumType = Instance.new(&quot;NumberValue&quot;)
&#9;&#9;enumType.Name = &quot;EnumType&quot;
&#9;&#9;enumType.Parent = buttonWrap
&#9;&#9;enumType.Value = 0
&#9;&#9;
&#9;&#9;imageButton.MouseEnter:connect(function()
&#9;&#9;&#9;buttonWrap.BackgroundTransparency = 0
&#9;&#9;end)
&#9;&#9;imageButton.MouseLeave:connect(function()
&#9;&#9;&#9;if selectedButton ~= buttonWrap then
&#9;&#9;&#9;&#9;buttonWrap.BackgroundTransparency = 1
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;&#9;imageButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;if selectedButton ~= buttonWrap then
&#9;&#9;&#9;&#9;goToNewMaterial(buttonWrap, tostring(name))
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;&#9;
&#9;&#9;return buttonWrap
&#9;end
&#9;for i = 1, #materialNames do
&#9;&#9;local imageButton = createMaterialButton(materialNames[i])
&#9;&#9;
&#9;&#9;if materialNames[i] == &quot;Grass&quot; then -- always start with grass as the default
&#9;&#9;&#9;selectedButton = imageButton
&#9;&#9;&#9;imageButton.BackgroundTransparency = 0
&#9;&#9;end
&#9;&#9;
&#9;&#9;imageButton.Parent = scrollFrame
&#9;end
&#9;local forceTerrainMaterialSelection = function(newMaterialType)
&#9;&#9;if not newMaterialType then return end
&#9;&#9;if currentMaterial == newMaterialType then return end
&#9;&#9;local matName = getNameFromEnum(newMaterialType)
&#9;&#9;local buttons = scrollFrame:GetChildren()
&#9;&#9;for i = 1, #buttons do
&#9;&#9;&#9;if buttons[i].Name == &quot;Plastic (blue)&quot; and matName == &quot;Plastic (blue)&quot; then goToNewMaterial(buttons[i],matName) return end
&#9;&#9;&#9;if buttons[i].Name == &quot;Plastic (red)&quot; and matName == &quot;Plastic (red)&quot; then goToNewMaterial(buttons[i],matName) return end
&#9;&#9;&#9;if string.find(buttons[i].Name, matName) then
&#9;&#9;&#9;&#9;goToNewMaterial(buttons[i],matName)
&#9;&#9;&#9;&#9;return
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;frame.Changed:connect(function ( prop )
&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;recalculateScroll()
&#9;&#9;end
&#9;end)
&#9;recalculateScroll()
&#9;return frame, terrainMaterialSelectionChanged, forceTerrainMaterialSelection
end
t.CreateLoadingFrame = function(name,size,position)
&#9;game:GetService(&quot;ContentProvider&quot;):Preload(&quot;http://www.roblox.com/asset/?id=35238053&quot;)
&#9;local loadingFrame = Instance.new(&quot;Frame&quot;)
&#9;loadingFrame.Name = &quot;LoadingFrame&quot;
&#9;loadingFrame.Style = Enum.FrameStyle.RobloxRound
&#9;if size then loadingFrame.Size = size
&#9;else loadingFrame.Size = UDim2.new(0,300,0,160) end
&#9;if position then loadingFrame.Position = position
&#9;else loadingFrame.Position = UDim2.new(0.5, -150, 0.5,-80) end
&#9;local loadingBar = Instance.new(&quot;Frame&quot;)
&#9;loadingBar.Name = &quot;LoadingBar&quot;
&#9;loadingBar.BackgroundColor3 = Color3.new(0,0,0)
&#9;loadingBar.BorderColor3 = Color3.new(79/255,79/255,79/255)
&#9;loadingBar.Position = UDim2.new(0,0,0,41)
&#9;loadingBar.Size = UDim2.new(1,0,0,30)
&#9;loadingBar.Parent = loadingFrame
&#9;&#9;local loadingGreenBar = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;loadingGreenBar.Name = &quot;LoadingGreenBar&quot;
&#9;&#9;loadingGreenBar.Image = &quot;http://www.roblox.com/asset/?id=35238053&quot;
&#9;&#9;loadingGreenBar.Position = UDim2.new(0,0,0,0)
&#9;&#9;loadingGreenBar.Size = UDim2.new(0,0,1,0)
&#9;&#9;loadingGreenBar.Visible = false
&#9;&#9;loadingGreenBar.Parent = loadingBar
&#9;&#9;local loadingPercent = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;loadingPercent.Name = &quot;LoadingPercent&quot;
&#9;&#9;loadingPercent.BackgroundTransparency = 1
&#9;&#9;loadingPercent.Position = UDim2.new(0,0,1,0)
&#9;&#9;loadingPercent.Size = UDim2.new(1,0,0,14)
&#9;&#9;loadingPercent.Font = Enum.Font.Arial
&#9;&#9;loadingPercent.Text = &quot;0%&quot;
&#9;&#9;loadingPercent.FontSize = Enum.FontSize.Size14
&#9;&#9;loadingPercent.TextColor3 = Color3.new(1,1,1)
&#9;&#9;loadingPercent.Parent = loadingBar
&#9;local cancelButton = Instance.new(&quot;TextButton&quot;)
&#9;cancelButton.Name = &quot;CancelButton&quot;
&#9;cancelButton.Position = UDim2.new(0.5,-60,1,-40)
&#9;cancelButton.Size = UDim2.new(0,120,0,40)
&#9;cancelButton.Font = Enum.Font.Arial
&#9;cancelButton.FontSize = Enum.FontSize.Size18
&#9;cancelButton.TextColor3 = Color3.new(1,1,1)
&#9;cancelButton.Text = &quot;Cancel&quot;
&#9;cancelButton.Style = Enum.ButtonStyle.RobloxButton
&#9;cancelButton.Parent = loadingFrame
&#9;local loadingName = Instance.new(&quot;TextLabel&quot;)
&#9;loadingName.Name = &quot;loadingName&quot;
&#9;loadingName.BackgroundTransparency = 1
&#9;loadingName.Size = UDim2.new(1,0,0,18)
&#9;loadingName.Position = UDim2.new(0,0,0,2)
&#9;loadingName.Font = Enum.Font.Arial
&#9;loadingName.Text = name
&#9;loadingName.TextColor3 = Color3.new(1,1,1)
&#9;loadingName.TextStrokeTransparency = 1
&#9;loadingName.FontSize = Enum.FontSize.Size18
&#9;loadingName.Parent = loadingFrame
&#9;local cancelButtonClicked = Instance.new(&quot;BindableEvent&quot;)
&#9;cancelButtonClicked.Name = &quot;CancelButtonClicked&quot;
&#9;cancelButtonClicked.Parent = cancelButton
&#9;cancelButton.MouseButton1Click:connect(function()
&#9;&#9;cancelButtonClicked:Fire()
&#9;end)
&#9;local updateLoadingGuiPercent = function(percent, tweenAction, tweenLength)
&#9;&#9;if percent and type(percent) ~= &quot;number&quot; then
&#9;&#9;&#9;error(&quot;updateLoadingGuiPercent expects number as argument, got&quot;,type(percent),&quot;instead&quot;)
&#9;&#9;end
&#9;&#9;local newSize = nil
&#9;&#9;if percent &lt; 0 then
&#9;&#9;&#9;newSize = UDim2.new(0,0,1,0)
&#9;&#9;elseif percent &gt; 1 then
&#9;&#9;&#9;newSize = UDim2.new(1,0,1,0)
&#9;&#9;else
&#9;&#9;&#9;newSize = UDim2.new(percent,0,1,0)
&#9;&#9;end
&#9;&#9;if tweenAction then
&#9;&#9;&#9;if not tweenLength then
&#9;&#9;&#9;&#9;error(&quot;updateLoadingGuiPercent is set to tween new percentage, but got no tween time length! Please pass this in as third argument&quot;)
&#9;&#9;&#9;end
&#9;&#9;&#9;if (newSize.X.Scale &gt; 0) then
&#9;&#9;&#9;&#9;loadingGreenBar.Visible = true
&#9;&#9;&#9;&#9;loadingGreenBar:TweenSize(&#9;newSize,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Enum.EasingDirection.Out,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Enum.EasingStyle.Quad,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;tweenLength,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;true)
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;loadingGreenBar:TweenSize(&#9;newSize,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Enum.EasingDirection.Out,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Enum.EasingStyle.Quad,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;tweenLength,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;if (newSize.X.Scale &lt; 0) then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;loadingGreenBar.Visible = false
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;loadingGreenBar.Size = newSize
&#9;&#9;&#9;loadingGreenBar.Visible = (newSize.X.Scale &gt; 0)
&#9;&#9;end
&#9;end
&#9;loadingGreenBar.Changed:connect(function(prop)
&#9;&#9;if prop == &quot;Size&quot; then
&#9;&#9;&#9;loadingPercent.Text = tostring( math.ceil(loadingGreenBar.Size.X.Scale * 100) ) .. &quot;%&quot;
&#9;&#9;end
&#9;end)
&#9;return loadingFrame, updateLoadingGuiPercent, cancelButtonClicked
end
t.CreatePluginFrame = function (name,size,position,scrollable,parent)
&#9;function createMenuButton(size,position,text,fontsize,name,parent)
&#9;&#9;local button = Instance.new(&quot;TextButton&quot;,parent)
&#9;&#9;button.AutoButtonColor = false
&#9;&#9;button.Name = name
&#9;&#9;button.BackgroundTransparency = 1
&#9;&#9;button.Position = position
&#9;&#9;button.Size = size
&#9;&#9;button.Font = Enum.Font.ArialBold
&#9;&#9;button.FontSize = fontsize
&#9;&#9;button.Text = text
&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;button.BorderSizePixel = 0
&#9;&#9;button.BackgroundColor3 = Color3.new(20/255,20/255,20/255)
&#9;&#9;button.MouseEnter:connect(function ( )
&#9;&#9;&#9;if button.Selected then return end
&#9;&#9;&#9;button.BackgroundTransparency = 0
&#9;&#9;end)
&#9;&#9;button.MouseLeave:connect(function ( )
&#9;&#9;&#9;if button.Selected then return end
&#9;&#9;&#9;button.BackgroundTransparency = 1
&#9;&#9;end)
&#9;&#9;return button
&#9;end
&#9;local dragBar = Instance.new(&quot;Frame&quot;,parent)
&#9;dragBar.Name = tostring(name) .. &quot;DragBar&quot;
&#9;dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255)
&#9;dragBar.BorderColor3 = Color3.new(0,0,0)
&#9;if size then
&#9;&#9;dragBar.Size = UDim2.new(size.X.Scale,size.X.Offset,0,20) + UDim2.new(0,20,0,0)
&#9;else
&#9;&#9;dragBar.Size = UDim2.new(0,183,0,20)
&#9;end
&#9;if position then
&#9;&#9;dragBar.Position = position
&#9;end
&#9;dragBar.Active = true
&#9;dragBar.Draggable = true
&#9;--dragBar.Visible = false
&#9;dragBar.MouseEnter:connect(function ( )
&#9;&#9;dragBar.BackgroundColor3 = Color3.new(49/255,49/255,49/255)
&#9;end)
&#9;dragBar.MouseLeave:connect(function ( )
&#9;&#9;dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255)
&#9;end)
&#9;-- plugin name label
&#9;local pluginNameLabel = Instance.new(&quot;TextLabel&quot;,dragBar)
&#9;pluginNameLabel.Name = &quot;BarNameLabel&quot;
&#9;pluginNameLabel.Text = &quot; &quot; .. tostring(name)
&#9;pluginNameLabel.TextColor3 = Color3.new(1,1,1)
&#9;pluginNameLabel.TextStrokeTransparency = 0
&#9;pluginNameLabel.Size = UDim2.new(1,0,1,0)
&#9;pluginNameLabel.Font = Enum.Font.ArialBold
&#9;pluginNameLabel.FontSize = Enum.FontSize.Size18
&#9;pluginNameLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;pluginNameLabel.BackgroundTransparency = 1
&#9;-- close button
&#9;local closeButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-16,0.5,-8),&quot;X&quot;,Enum.FontSize.Size14,&quot;CloseButton&quot;,dragBar)
&#9;local closeEvent = Instance.new(&quot;BindableEvent&quot;)
&#9;closeEvent.Name = &quot;CloseEvent&quot;
&#9;closeEvent.Parent = closeButton
&#9;closeButton.MouseButton1Click:connect(function ()
&#9;&#9;closeEvent:Fire()
&#9;&#9;closeButton.BackgroundTransparency = 1
&#9;end)
&#9;-- help button
&#9;local helpButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-51,0.5,-8),&quot;?&quot;,Enum.FontSize.Size14,&quot;HelpButton&quot;,dragBar)
&#9;local helpFrame = Instance.new(&quot;Frame&quot;,dragBar)
&#9;helpFrame.Name = &quot;HelpFrame&quot;
&#9;helpFrame.BackgroundColor3 = Color3.new(0,0,0)
&#9;helpFrame.Size = UDim2.new(0,300,0,552)
&#9;helpFrame.Position = UDim2.new(1,5,0,0)
&#9;helpFrame.Active = true
&#9;helpFrame.BorderSizePixel = 0
&#9;helpFrame.Visible = false
&#9;helpButton.MouseButton1Click:connect(function( )
&#9;&#9;helpFrame.Visible = not helpFrame.Visible
&#9;&#9;if helpFrame.Visible then
&#9;&#9;&#9;helpButton.Selected = true
&#9;&#9;&#9;helpButton.BackgroundTransparency = 0
&#9;&#9;&#9;local screenGui = getScreenGuiAncestor(helpFrame)
&#9;&#9;&#9;if screenGui then
&#9;&#9;&#9;&#9;if helpFrame.AbsolutePosition.X + helpFrame.AbsoluteSize.X &gt; screenGui.AbsoluteSize.X then --position on left hand side
&#9;&#9;&#9;&#9;&#9;helpFrame.Position = UDim2.new(0,-5 - helpFrame.AbsoluteSize.X,0,0)
&#9;&#9;&#9;&#9;else -- position on right hand side
&#9;&#9;&#9;&#9;&#9;helpFrame.Position = UDim2.new(1,5,0,0)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;helpFrame.Position = UDim2.new(1,5,0,0)
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;helpButton.Selected = false
&#9;&#9;&#9;helpButton.BackgroundTransparency = 1
&#9;&#9;end
&#9;end)
&#9;local minimizeButton = createMenuButton(UDim2.new(0,16,0,17),UDim2.new(1,-34,0.5,-8),&quot;-&quot;,Enum.FontSize.Size14,&quot;MinimizeButton&quot;,dragBar)
&#9;minimizeButton.TextYAlignment = Enum.TextYAlignment.Top
&#9;local minimizeFrame = Instance.new(&quot;Frame&quot;,dragBar)
&#9;minimizeFrame.Name = &quot;MinimizeFrame&quot;
&#9;minimizeFrame.BackgroundColor3 = Color3.new(73/255,73/255,73/255)
&#9;minimizeFrame.BorderColor3 = Color3.new(0,0,0)
&#9;minimizeFrame.Position = UDim2.new(0,0,1,0)
&#9;if size then
&#9;&#9;minimizeFrame.Size = UDim2.new(size.X.Scale,size.X.Offset,0,50) + UDim2.new(0,20,0,0)
&#9;else
&#9;&#9;minimizeFrame.Size = UDim2.new(0,183,0,50)
&#9;end
&#9;minimizeFrame.Visible = false
&#9;local minimizeBigButton = Instance.new(&quot;TextButton&quot;,minimizeFrame)
&#9;minimizeBigButton.Position = UDim2.new(0.5,-50,0.5,-20)
&#9;minimizeBigButton.Name = &quot;MinimizeButton&quot;
&#9;minimizeBigButton.Size = UDim2.new(0,100,0,40)
&#9;minimizeBigButton.Style = Enum.ButtonStyle.RobloxButton
&#9;minimizeBigButton.Font = Enum.Font.ArialBold
&#9;minimizeBigButton.FontSize = Enum.FontSize.Size18
&#9;minimizeBigButton.TextColor3 = Color3.new(1,1,1)
&#9;minimizeBigButton.Text = &quot;Show&quot;
&#9;local separatingLine = Instance.new(&quot;Frame&quot;,dragBar)
&#9;separatingLine.Name = &quot;SeparatingLine&quot;
&#9;separatingLine.BackgroundColor3 = Color3.new(115/255,115/255,115/255)
&#9;separatingLine.BorderSizePixel = 0
&#9;separatingLine.Position = UDim2.new(1,-18,0.5,-7)
&#9;separatingLine.Size = UDim2.new(0,1,0,14)
&#9;local otherSeparatingLine = separatingLine:clone()
&#9;otherSeparatingLine.Position = UDim2.new(1,-35,0.5,-7)
&#9;otherSeparatingLine.Parent = dragBar
&#9;local widgetContainer = Instance.new(&quot;Frame&quot;,dragBar)
&#9;widgetContainer.Name = &quot;WidgetContainer&quot;
&#9;widgetContainer.BackgroundTransparency = 1
&#9;widgetContainer.Position = UDim2.new(0,0,1,0)
&#9;widgetContainer.BorderColor3 = Color3.new(0,0,0)
&#9;if not scrollable then
&#9;&#9;widgetContainer.BackgroundTransparency = 0
&#9;&#9;widgetContainer.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
&#9;end
&#9;if size then
&#9;&#9;if scrollable then
&#9;&#9;&#9;widgetContainer.Size = size
&#9;&#9;else
&#9;&#9;&#9;widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,size.Y.Scale,size.Y.Offset)
&#9;&#9;end
&#9;else
&#9;&#9;if scrollable then
&#9;&#9;&#9;widgetContainer.Size = UDim2.new(0,163,0,400)
&#9;&#9;else
&#9;&#9;&#9;widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,0,400)
&#9;&#9;end
&#9;end
&#9;if position then
&#9;&#9;widgetContainer.Position = position + UDim2.new(0,0,0,20)
&#9;end
&#9;local frame,control,verticalDragger = nil
&#9;if scrollable then
&#9;&#9;--frame for widgets
&#9;&#9;frame,control = t.CreateTrueScrollingFrame()
&#9;&#9;frame.Size = UDim2.new(1, 0, 1, 0)
&#9;&#9;frame.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
&#9;&#9;frame.BorderColor3 = Color3.new(0,0,0)
&#9;&#9;frame.Active = true
&#9;&#9;frame.Parent = widgetContainer
&#9;&#9;control.Parent = dragBar
&#9;&#9;control.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
&#9;&#9;control.BorderSizePixel = 0
&#9;&#9;control.BackgroundTransparency = 0
&#9;&#9;control.Position = UDim2.new(1,-21,1,1)
&#9;&#9;if size then
&#9;&#9;&#9;control.Size = UDim2.new(0,21,size.Y.Scale,size.Y.Offset)
&#9;&#9;else
&#9;&#9;&#9;control.Size = UDim2.new(0,21,0,400)
&#9;&#9;end
&#9;&#9;control:FindFirstChild(&quot;ScrollDownButton&quot;).Position = UDim2.new(0,0,1,-20)
&#9;&#9;local fakeLine = Instance.new(&quot;Frame&quot;,control)
&#9;&#9;fakeLine.Name = &quot;FakeLine&quot;
&#9;&#9;fakeLine.BorderSizePixel = 0
&#9;&#9;fakeLine.BackgroundColor3 = Color3.new(0,0,0)
&#9;&#9;fakeLine.Size = UDim2.new(0,1,1,1)
&#9;&#9;fakeLine.Position = UDim2.new(1,0,0,0)
&#9;&#9;verticalDragger = Instance.new(&quot;TextButton&quot;,widgetContainer)
&#9;&#9;verticalDragger.ZIndex = 2
&#9;&#9;verticalDragger.AutoButtonColor = false
&#9;&#9;verticalDragger.Name = &quot;VerticalDragger&quot;
&#9;&#9;verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255)
&#9;&#9;verticalDragger.BorderColor3 = Color3.new(0,0,0)
&#9;&#9;verticalDragger.Size = UDim2.new(1,20,0,20)
&#9;&#9;verticalDragger.Position = UDim2.new(0,0,1,0)
&#9;&#9;verticalDragger.Active = true
&#9;&#9;verticalDragger.Text = &quot;&quot;
&#9;&#9;local scrubFrame = Instance.new(&quot;Frame&quot;,verticalDragger)
&#9;&#9;scrubFrame.Name = &quot;ScrubFrame&quot;
&#9;&#9;scrubFrame.BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;scrubFrame.BorderSizePixel = 0
&#9;&#9;scrubFrame.Position = UDim2.new(0.5,-5,0.5,0)
&#9;&#9;scrubFrame.Size = UDim2.new(0,10,0,1)
&#9;&#9;scrubFrame.ZIndex = 5
&#9;&#9;local scrubTwo = scrubFrame:clone()
&#9;&#9;scrubTwo.Position = UDim2.new(0.5,-5,0.5,-2)
&#9;&#9;scrubTwo.Parent = verticalDragger
&#9;&#9;local scrubThree = scrubFrame:clone()
&#9;&#9;scrubThree.Position = UDim2.new(0.5,-5,0.5,2)
&#9;&#9;scrubThree.Parent = verticalDragger
&#9;&#9;local areaSoak = Instance.new(&quot;TextButton&quot;,getScreenGuiAncestor(parent))
&#9;&#9;areaSoak.Name = &quot;AreaSoak&quot;
&#9;&#9;areaSoak.Size = UDim2.new(1,0,1,0)
&#9;&#9;areaSoak.BackgroundTransparency = 1
&#9;&#9;areaSoak.BorderSizePixel = 0
&#9;&#9;areaSoak.Text = &quot;&quot;
&#9;&#9;areaSoak.ZIndex = 10
&#9;&#9;areaSoak.Visible = false
&#9;&#9;areaSoak.Active = true
&#9;&#9;local draggingVertical = false
&#9;&#9;local startYPos = nil
&#9;&#9;verticalDragger.MouseEnter:connect(function ()
&#9;&#9;&#9;verticalDragger.BackgroundColor3 = Color3.new(60/255,60/255,60/255)
&#9;&#9;end)
&#9;&#9;verticalDragger.MouseLeave:connect(function ()
&#9;&#9;&#9;verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255)
&#9;&#9;end)
&#9;&#9;verticalDragger.MouseButton1Down:connect(function(x,y)
&#9;&#9;&#9;draggingVertical = true
&#9;&#9;&#9;areaSoak.Visible = true
&#9;&#9;&#9;startYPos = y
&#9;&#9;end)
&#9;&#9;areaSoak.MouseButton1Up:connect(function ( )
&#9;&#9;&#9;draggingVertical = false
&#9;&#9;&#9;areaSoak.Visible = false
&#9;&#9;end)
&#9;&#9;areaSoak.MouseMoved:connect(function(x,y)
&#9;&#9;&#9;if not draggingVertical then return end
&#9;&#9;&#9;local yDelta = y - startYPos
&#9;&#9;&#9;if not control.ScrollDownButton.Visible and yDelta &gt; 0 then
&#9;&#9;&#9;&#9;return
&#9;&#9;&#9;end
&#9;&#9;&#9;if (widgetContainer.Size.Y.Offset + yDelta) &lt; 150 then
&#9;&#9;&#9;&#9;widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,150)
&#9;&#9;&#9;&#9;control.Size = UDim2.new (0,21,0,150)
&#9;&#9;&#9;&#9;return
&#9;&#9;&#9;end
&#9;&#9;&#9;startYPos = y
&#9;&#9;&#9;if widgetContainer.Size.Y.Offset + yDelta &gt;= 0 then
&#9;&#9;&#9;&#9;widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,widgetContainer.Size.Y.Offset + yDelta)
&#9;&#9;&#9;&#9;control.Size = UDim2.new(0,21,0,control.Size.Y.Offset + yDelta )
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;end
&#9;local function switchMinimize()
&#9;&#9;minimizeFrame.Visible = not minimizeFrame.Visible
&#9;&#9;if scrollable then
&#9;&#9;&#9;frame.Visible = not frame.Visible
&#9;&#9;&#9;verticalDragger.Visible = not verticalDragger.Visible
&#9;&#9;&#9;control.Visible = not control.Visible
&#9;&#9;else
&#9;&#9;&#9;widgetContainer.Visible = not widgetContainer.Visible
&#9;&#9;end
&#9;&#9;if minimizeFrame.Visible then
&#9;&#9;&#9;minimizeButton.Text = &quot;+&quot;
&#9;&#9;else
&#9;&#9;&#9;minimizeButton.Text = &quot;-&quot;
&#9;&#9;end
&#9;end
&#9;minimizeBigButton.MouseButton1Click:connect(function ( )
&#9;&#9;switchMinimize()
&#9;end)
&#9;minimizeButton.MouseButton1Click:connect(function( )
&#9;&#9;switchMinimize()
&#9;end)
&#9;if scrollable then
&#9;&#9;return dragBar, frame, helpFrame, closeEvent
&#9;else
&#9;&#9;return dragBar, widgetContainer, helpFrame, closeEvent
&#9;end
end
t.Help =
&#9;function(funcNameOrFunc)
&#9;&#9;--input argument can be a string or a function. Should return a description (of arguments and expected side effects)
&#9;&#9;if funcNameOrFunc == &quot;CreatePropertyDropDownMenu&quot; or funcNameOrFunc == t.CreatePropertyDropDownMenu then
&#9;&#9;&#9;return &quot;Function CreatePropertyDropDownMenu. &quot; ..
&#9;&#9;&#9;&#9; &quot;Arguments: (instance, propertyName, enumType). &quot; ..
&#9;&#9;&#9;&#9; &quot;Side effect: returns a container with a drop-down-box that is linked to the &apos;property&apos; field of &apos;instance&apos; which is of type &apos;enumType&apos;&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateDropDownMenu&quot; or funcNameOrFunc == t.CreateDropDownMenu then
&#9;&#9;&#9;return &quot;Function CreateDropDownMenu. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (items, onItemSelected). &quot; ..
&#9;&#9;&#9;&#9; &quot;Side effect: Returns 2 results, a container to the gui object and a &apos;updateSelection&apos; function for external updating. The container is a drop-down-box created around a list of items&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateMessageDialog&quot; or funcNameOrFunc == t.CreateMessageDialog then
&#9;&#9;&#9;return &quot;Function CreateMessageDialog. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (title, message, buttons). &quot; ..
&#9;&#9;&#9; &quot;Side effect: Returns a gui object of a message box with &apos;title&apos; and &apos;message&apos; as passed in. &apos;buttons&apos; input is an array of Tables contains a &apos;Text&apos; and &apos;Function&apos; field for the text/callback of each button&quot;
&#9;&#9;end&#9;&#9;
&#9;&#9;if funcNameOrFunc == &quot;CreateStyledMessageDialog&quot; or funcNameOrFunc == t.CreateStyledMessageDialog then
&#9;&#9;&#9;return &quot;Function CreateStyledMessageDialog. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (title, message, style, buttons). &quot; ..
&#9;&#9;&#9; &quot;Side effect: Returns a gui object of a message box with &apos;title&apos; and &apos;message&apos; as passed in. &apos;buttons&apos; input is an array of Tables contains a &apos;Text&apos; and &apos;Function&apos; field for the text/callback of each button, &apos;style&apos; is a string, either Error, Notify or Confirm&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;GetFontHeight&quot; or funcNameOrFunc == t.GetFontHeight then
&#9;&#9;&#9;return &quot;Function GetFontHeight. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (font, fontSize). &quot; ..
&#9;&#9;&#9; &quot;Side effect: returns the size in pixels of the given font + fontSize&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;LayoutGuiObjects&quot; or funcNameOrFunc == t.LayoutGuiObjects then
&#9;&#9;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateScrollingFrame&quot; or funcNameOrFunc == t.CreateScrollingFrame then
&#9;&#9;&#9;return &quot;Function CreateScrollingFrame. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (orderList, style) &quot; ..
&#9;&#9;&#9; &quot;Side effect: returns 4 objects, (scrollFrame, scrollUpButton, scrollDownButton, recalculateFunction). &apos;scrollFrame&apos; 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 &apos;grid&apos; styling if style is passed &apos;grid&apos; as a string. recalculateFunction can be called when a relayout is needed (when orderList changes)&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateTrueScrollingFrame&quot; or funcNameOrFunc == t.CreateTrueScrollingFrame then
&#9;&#9;&#9;return &quot;Function CreateTrueScrollingFrame. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (nil) &quot; ..
&#9;&#9;&#9; &quot;Side effect: returns 2 objects, (scrollFrame, controlFrame). &apos;scrollFrame&apos; can be filled with GuiObjects, and they will be clipped if not inside the frame&apos;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.&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;AutoTruncateTextObject&quot; or funcNameOrFunc == t.AutoTruncateTextObject then
&#9;&#9;&#9;return &quot;Function AutoTruncateTextObject. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (textLabel) &quot; ..
&#9;&#9;&#9; &quot;Side effect: returns 2 objects, (textLabel, changeText). The &apos;textLabel&apos; input is modified to automatically truncate text (with ellipsis), if it gets too small to fit. &apos;changeText&apos; is a function that can be used to change the text, it takes 1 string as an argument&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateSlider&quot; or funcNameOrFunc == t.CreateSlider then
&#9;&#9;&#9;return &quot;Function CreateSlider. &quot; ..
&#9;&#9;&#9;&#9;&quot;Arguments: (steps, width, position) &quot; ..
&#9;&#9;&#9;&#9;&quot;Side effect: returns 2 objects, (sliderGui, sliderPosition). The &apos;steps&apos; argument specifies how many different positions the slider can hold along the bar. &apos;width&apos; specifies in pixels how wide the bar should be (modifiable afterwards if desired). &apos;position&apos; argument should be a UDim2 for slider positioning. &apos;sliderPosition&apos; is an IntValue whose current .Value specifies the specific step the slider is currently on.&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateSliderNew&quot; or funcNameOrFunc == t.CreateSliderNew then
&#9;&#9;&#9;return &quot;Function CreateSliderNew. &quot; ..
&#9;&#9;&#9;&#9;&quot;Arguments: (steps, width, position) &quot; ..
&#9;&#9;&#9;&#9;&quot;Side effect: returns 2 objects, (sliderGui, sliderPosition). The &apos;steps&apos; argument specifies how many different positions the slider can hold along the bar. &apos;width&apos; specifies in pixels how wide the bar should be (modifiable afterwards if desired). &apos;position&apos; argument should be a UDim2 for slider positioning. &apos;sliderPosition&apos; is an IntValue whose current .Value specifies the specific step the slider is currently on.&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateLoadingFrame&quot; or funcNameOrFunc == t.CreateLoadingFrame then
&#9;&#9;&#9;return &quot;Function CreateLoadingFrame. &quot; ..
&#9;&#9;&#9;&#9;&quot;Arguments: (name, size, position) &quot; ..
&#9;&#9;&#9;&#9;&quot;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.&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateTerrainMaterialSelector&quot; or funcNameOrFunc == t.CreateTerrainMaterialSelector then
&#9;&#9;&#9;return &quot;Function CreateTerrainMaterialSelector. &quot; ..
&#9;&#9;&#9;&#9;&quot;Arguments: (size, position) &quot; ..
&#9;&#9;&#9;&#9;&quot;Side effect: Size and position are UDim2 values that specifies the selector&apos;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.&quot;
&#9;&#9;end
&#9;end
&#9;
-- A couple of necessary functions
local function waitForChild(instance, name)
&#9;while not instance:FindFirstChild(name) do
&#9;&#9;instance.ChildAdded:wait()
&#9;end
end
local function waitForProperty(instance, property)
&#9;while not instance[property] do
&#9;&#9;instance.Changed:wait()
&#9;end
end
waitForChild(game,&quot;Players&quot;)
waitForProperty(game.Players,&quot;LocalPlayer&quot;)
local player = game.Players.LocalPlayer
local RbxGui,msg = t
if not RbxGui then print(&quot;could not find RbxGui!&quot;) return end
--- Begin Locals
waitForChild(game,&quot;Players&quot;)
-- don&apos;t do anything if we are in an empty game
if #game.Players:GetChildren() &lt; 1 then
&#9;game.Players.ChildAdded:wait()
end
local tilde = &quot;~&quot;
local backquote = &quot;`&quot;
game:GetService(&quot;GuiService&quot;):AddKey(tilde) -- register our keys
game:GetService(&quot;GuiService&quot;):AddKey(backquote)
local player = game.Players.LocalPlayer
local backpack = script.Parent.Backpack
local screen = script.Parent
local openCloseDebounce = false
local backpackItems = {}
local buttons = {}
local debounce = false
local guiTweenSpeed = 1
local browsingMenu = false
local mouseEnterCons = {}
local mouseClickCons = {}
local characterChildAddedCon = nil
local characterChildRemovedCon = nil
local backpackAddCon = nil
local humanoidDiedCon = nil
local backpackButtonClickCon = nil
local guiServiceKeyPressCon = nil
local playerBackpack = player.Backpack
local gearPreview = backpack.Gear.GearPreview
local scroller = backpack.Gear.GearGridScrollingArea
local currentLoadout = backpack.Parent.CurrentLoadout
local backpackButton = backpack.Parent.ControlFrame.BackpackButton
local gearButton = backpack.Gear.GearGrid.GearButton
local grid = backpack.Gear.GearGrid
local searchBox = backpack.SearchFrame.SearchBoxFrame.SearchBox
local searchButton = backpack.SearchFrame.SearchButton
local resetFrame = backpack.SearchFrame
local resetButton = backpack.SearchFrame.ResetButton
local swapSlot = backpack.SwapSlot
-- creating scroll bar early as to make sure items get placed correctly
local scrollFrame, scrollUp, scrollDown, recalculateScroll = RbxGui.CreateScrollingFrame(nil,&quot;grid&quot;)
scrollFrame.Position = UDim2.new(0,0,0,30)
scrollFrame.Size = UDim2.new(1,0,1,-30)
scrollFrame.Parent = backpack.Gear.GearGrid
local scrollBar = Instance.new(&quot;Frame&quot;)
scrollBar.Name = &quot;ScrollBar&quot;
scrollBar.BackgroundTransparency = 0.9
scrollBar.BackgroundColor3 = Color3.new(1,1,1)
scrollBar.BorderSizePixel = 0
scrollBar.Size = UDim2.new(0, 17, 1, -36)
scrollBar.Position = UDim2.new(0,0,0,18)
scrollBar.Parent = scroller
scrollDown.Position = UDim2.new(0,0,1,-17)
scrollUp.Parent = scroller
scrollDown.Parent = scroller
local scrollFrameLoadout, scrollUpLoadout, scrollDownLoadout, recalculateScrollLoadout = RbxGui.CreateScrollingFrame()
scrollFrameLoadout.Position = UDim2.new(0,0,0,0)
scrollFrameLoadout.Size = UDim2.new(1,0,1,0)
scrollFrameLoadout.Parent = backpack.Gear.GearLoadouts.LoadoutsList
local LoadoutButton = Instance.new(&quot;TextButton&quot;)
LoadoutButton.RobloxLocked = true
LoadoutButton.Name = &quot;LoadoutButton&quot;
LoadoutButton.Font = Enum.Font.ArialBold
LoadoutButton.FontSize = Enum.FontSize.Size14
LoadoutButton.Position = UDim2.new(0,0,0,0)
LoadoutButton.Size = UDim2.new(1,0,0,32)
LoadoutButton.Style = Enum.ButtonStyle.RobloxButton
LoadoutButton.Text = &quot;Loadout #1&quot;
LoadoutButton.TextColor3 = Color3.new(1,1,1)
LoadoutButton.Parent = scrollFrameLoadout
local LoadoutButtonTwo = LoadoutButton:clone()
LoadoutButtonTwo.Text = &quot;Loadout #2&quot;
LoadoutButtonTwo.Parent = scrollFrameLoadout
local LoadoutButtonThree = LoadoutButton:clone()
LoadoutButtonThree.Text = &quot;Loadout #3&quot;
LoadoutButtonThree.Parent = scrollFrameLoadout
local LoadoutButtonFour = LoadoutButton:clone()
LoadoutButtonFour.Text = &quot;Loadout #4&quot;
LoadoutButtonFour.Parent = scrollFrameLoadout
local scrollBarLoadout = Instance.new(&quot;Frame&quot;)
scrollBarLoadout.Name = &quot;ScrollBarLoadout&quot;
scrollBarLoadout.BackgroundTransparency = 0.9
scrollBarLoadout.BackgroundColor3 = Color3.new(1,1,1)
scrollBarLoadout.BorderSizePixel = 0
scrollBarLoadout.Size = UDim2.new(0, 17, 1, -36)
scrollBarLoadout.Position = UDim2.new(0,0,0,18)
scrollBarLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea
scrollDownLoadout.Position = UDim2.new(0,0,1,-17)
scrollUpLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea
scrollDownLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea
-- Begin Functions
function removeFromMap(map,object)
&#9;for i = 1, #map do
&#9;&#9;if map[i] == object then
&#9;&#9;&#9;table.remove(map,i)
&#9;&#9;&#9;break
&#9;&#9;end
&#9;end
end
function robloxLock(instance)
instance.RobloxLocked = true
children = instance:GetChildren()
if children then
&#9; for i, child in ipairs(children) do
&#9;&#9;robloxLock(child)
&#9; end
end
end
function resize()
&#9;local size = 0
&#9;if gearPreview.AbsoluteSize.Y &gt; gearPreview.AbsoluteSize.X then
&#9;&#9;size = gearPreview.AbsoluteSize.X * 0.75
&#9;else
&#9;&#9;size = gearPreview.AbsoluteSize.Y * 0.75
&#9;end
&#9;gearPreview.GearImage.Size = UDim2.new(0,size,0,size)
&#9;gearPreview.GearImage.Position = UDim2.new(0,gearPreview.AbsoluteSize.X/2 - size/2,0.75,-size)
&#9;
&#9;resizeGrid()
end
function addToGrid(child)
&#9;if not child:IsA(&quot;Tool&quot;) then
&#9;&#9;if not child:IsA(&quot;HopperBin&quot;) then
&#9;&#9;&#9;return
&#9;&#9;end
&#9;end
&#9;if child:FindFirstChild(&quot;RobloxBuildTool&quot;) then return end
&#9;
&#9;for i,v in pairs(backpackItems) do -- check to see if we already have this gear registered
&#9;&#9;if v == child then return end
&#9;end
&#9;table.insert(backpackItems,child)
&#9;
&#9;local changeCon = child.Changed:connect(function(prop)
&#9;&#9;if prop == &quot;Name&quot; then
&#9;&#9;&#9;if buttons[child] then
&#9;&#9;&#9;&#9;if buttons[child].Image == &quot;&quot; then
&#9;&#9;&#9;&#9;&#9;buttons[child].GearText.Text = child.Name
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end)
&#9;local ancestryCon = nil
&#9;ancestryCon = child.AncestryChanged:connect(function(theChild,theParent)
&#9;&#9;local thisObject = nil
&#9;&#9;for k,v in pairs(backpackItems) do
&#9;&#9;&#9;if v == child then
&#9;&#9;&#9;&#9;thisObject = v
&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;
&#9;&#9;waitForProperty(player,&quot;Character&quot;)
&#9;&#9;waitForChild(player,&quot;Backpack&quot;)
&#9;&#9;if (child.Parent ~= player.Backpack and child.Parent ~= player.Character) then
&#9;&#9;&#9;if ancestryCon then ancestryCon:disconnect() end
&#9;&#9;&#9;if changeCon then changeCon:disconnect() end
&#9;&#9;&#9;
&#9;&#9;&#9;for k,v in pairs(backpackItems) do
&#9;&#9;&#9;&#9;if v == thisObject then
&#9;&#9;&#9;&#9;&#9;if mouseEnterCons[buttons[v]] then mouseEnterCons[buttons[v]]:disconnect() end
&#9;&#9;&#9;&#9;&#9;if mouseClickCons[buttons[v]] then mouseClickCons[buttons[v]]:disconnect() end
&#9;&#9;&#9;&#9;&#9;buttons[v].Parent = nil
&#9;&#9;&#9;&#9;&#9;buttons[v] = nil
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;removeFromMap(backpackItems,thisObject)
&#9;&#9;&#9;
&#9;&#9;&#9;resizeGrid()
&#9;&#9;else
&#9;&#9;&#9;resizeGrid()
&#9;&#9;end
&#9;&#9;updateGridActive()
&#9;end)
&#9;resizeGrid()
end
function buttonClick(button)
&#9;if button:FindFirstChild(&quot;UnequipContextMenu&quot;) and not button.Active then
&#9;&#9;button.UnequipContextMenu.Visible = true
&#9;&#9;browsingMenu = true
&#9;end
end
function previewGear(button)
&#9;if not browsingMenu then
&#9;&#9;gearPreview.GearImage.Image = button.Image
&#9;&#9;gearPreview.GearStats.GearName.Text = button.GearReference.Value.Name
&#9;end
end
function findEmptySlot()
&#9;local smallestNum = nil
&#9;local loadout = currentLoadout:GetChildren()
&#9;for i = 1, #loadout do
&#9;&#9;if loadout[i]:IsA(&quot;Frame&quot;) and #loadout[i]:GetChildren() &lt;= 0 then
&#9;&#9;&#9;local frameNum = tonumber(string.sub(loadout[i].Name,5))
&#9;&#9;&#9;if frameNum == 0 then frameNum = 10 end
&#9;&#9;&#9;if not smallestNum or (smallestNum &gt; frameNum) then
&#9;&#9;&#9;&#9;smallestNum = frameNum
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;if smallestNum == 10 then smallestNum = 0 end
&#9;return smallestNum
end
function checkForSwap(button,x,y)
&#9;local loadoutChildren = currentLoadout:GetChildren()
&#9;for i = 1, #loadoutChildren do
&#9;&#9;if loadoutChildren[i]:IsA(&quot;Frame&quot;) and string.find(loadoutChildren[i].Name,&quot;Slot&quot;) then
&#9;&#9;&#9;if x &gt;= loadoutChildren[i].AbsolutePosition.x and x &lt;= (loadoutChildren[i].AbsolutePosition.x + loadoutChildren[i].AbsoluteSize.x) then
&#9;&#9;&#9;&#9;if y &gt;= loadoutChildren[i].AbsolutePosition.y and y &lt;= (loadoutChildren[i].AbsolutePosition.y + loadoutChildren[i].AbsoluteSize.y) then
&#9;&#9;&#9;&#9;&#9;local slot = tonumber(string.sub(loadoutChildren[i].Name,5))
&#9;&#9;&#9;&#9;&#9;swapGearSlot(slot,button)
&#9;&#9;&#9;&#9;&#9;return true
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;return false
end
function resizeGrid()
&#9;for k,v in pairs(backpackItems) do
&#9;&#9;if not v:FindFirstChild(&quot;RobloxBuildTool&quot;) then
&#9;&#9;&#9;if not buttons[v] then
&#9;&#9;&#9;&#9;local buttonClone = gearButton:clone()
&#9;&#9;&#9;&#9;buttonClone.Parent = grid.ScrollingFrame
&#9;&#9;&#9;&#9;buttonClone.Visible = true
&#9;&#9;&#9;&#9;buttonClone.Image = v.TextureId
&#9;&#9;&#9;&#9;if buttonClone.Image == &quot;&quot; then
&#9;&#9;&#9;&#9;&#9;buttonClone.GearText.Text = v.Name
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;buttonClone.GearReference.Value = v
&#9;&#9;&#9;&#9;buttonClone.Draggable = true
&#9;&#9;&#9;&#9;buttons[v] = buttonClone
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local unequipMenu = getGearContextMenu()
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;unequipMenu.Visible = false
&#9;&#9;&#9;&#9;unequipMenu.Parent = buttonClone
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local beginPos = nil
&#9;&#9;&#9;&#9;buttonClone.DragBegin:connect(function(value)
&#9;&#9;&#9;&#9;&#9;buttonClone.ZIndex = 9
&#9;&#9;&#9;&#9;&#9;beginPos = value
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;&#9;buttonClone.DragStopped:connect(function(x,y)
&#9;&#9;&#9;&#9;&#9;if beginPos ~= buttonClone.Position then
&#9;&#9;&#9;&#9;&#9;&#9;buttonClone.ZIndex = 1
&#9;&#9;&#9;&#9;&#9;&#9;if not checkForSwap(buttonClone,x,y) then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;buttonClone:TweenPosition(beginPos,Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.5, true)
&#9;&#9;&#9;&#9;&#9;&#9;&#9;buttonClone.Draggable = false
&#9;&#9;&#9;&#9;&#9;&#9;&#9;delay(0.5,function()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;buttonClone.Draggable = true
&#9;&#9;&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;&#9;buttonClone.Position = beginPos
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;end&#9;
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;&#9;local clickTime = tick()
&#9;&#9;&#9;&#9;mouseEnterCons[buttonClone] = buttonClone.MouseEnter:connect(function() previewGear(buttonClone) end)
&#9;&#9;&#9;&#9;mouseClickCons[buttonClone] = buttonClone.MouseButton1Click:connect(function()
&#9;&#9;&#9;&#9;&#9;local newClickTime = tick()
&#9;&#9;&#9;&#9;&#9;if buttonClone.Active and (newClickTime - clickTime) &lt; 0.5 then
&#9;&#9;&#9;&#9;&#9;&#9;local slot = findEmptySlot()
&#9;&#9;&#9;&#9;&#9;&#9;if slot then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;buttonClone.ZIndex = 1
&#9;&#9;&#9;&#9;&#9;&#9;&#9;swapGearSlot(slot,buttonClone)
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;buttonClick(buttonClone)
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;clickTime = newClickTime
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;recalculateScroll()
end
function showPartialGrid(subset)
&#9;resetFrame.Visible = true
&#9;for k,v in pairs(buttons) do
&#9;&#9;v.Parent = nil
&#9;end
&#9;for k,v in pairs(subset) do
&#9;&#9;v.Parent = grid.ScrollingFrame
&#9;end
&#9;recalculateScroll()
end
function showEntireGrid()
&#9;resetFrame.Visible = false
&#9;
&#9;for k,v in pairs(buttons) do
&#9;&#9;v.Parent = grid.ScrollingFrame
&#9;end
&#9;recalculateScroll()
end
function inLoadout(gear)
&#9;local children = currentLoadout:GetChildren()
&#9;for i = 1, #children do
&#9;&#9;if children[i]:IsA(&quot;Frame&quot;) then
&#9;&#9;&#9;local button = children[i]:GetChildren()
&#9;&#9;&#9;if #button &gt; 0 then
&#9;&#9;&#9;&#9;if button[1].GearReference.Value and button[1].GearReference.Value == gear then
&#9;&#9;&#9;&#9;&#9;return true
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;return false
end&#9;
function updateGridActive()
&#9;for k,v in pairs(backpackItems) do
&#9;&#9;if buttons[v] then
&#9;&#9;&#9;local gear = nil
&#9;&#9;&#9;local gearRef = buttons[v]:FindFirstChild(&quot;GearReference&quot;)
&#9;&#9;&#9;
&#9;&#9;&#9;if gearRef then gear = gearRef.Value end
&#9;&#9;&#9;
&#9;&#9;&#9;if not gear then
&#9;&#9;&#9;&#9;buttons[v].Active = false
&#9;&#9;&#9;elseif inLoadout(gear) then
&#9;&#9;&#9;&#9;buttons[v].Active = false
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;buttons[v].Active = true
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
end
function centerGear(loadoutChildren)
&#9;local gearButtons = {}
&#9;local lastSlotAdd = nil
&#9;for i = 1, #loadoutChildren do
&#9;&#9;if loadoutChildren[i]:IsA(&quot;Frame&quot;) and #loadoutChildren[i]:GetChildren() &gt; 0 then
&#9;&#9;&#9;if loadoutChildren[i].Name == &quot;Slot0&quot; then
&#9;&#9;&#9;&#9;lastSlotAdd = loadoutChildren[i]
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;table.insert(gearButtons, loadoutChildren[i])
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;if lastSlotAdd then table.insert(gearButtons,lastSlotAdd) end
&#9;
&#9;local startPos = ( 1 - (#gearButtons * 0.1) ) / 2
&#9;for i = 1, #gearButtons do&#9;
&#9;&#9;gearButtons[i]:TweenPosition(UDim2.new(startPos + ((i - 1) * 0.1),0,0,0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.25, true)
&#9;end
end
function spreadOutGear(loadoutChildren)
&#9;for i = 1, #loadoutChildren do
&#9;&#9;if loadoutChildren[i]:IsA(&quot;Frame&quot;) then
&#9;&#9;&#9;local slot = tonumber(string.sub(loadoutChildren[i].Name,5))
&#9;&#9;&#9;if slot == 0 then slot = 10 end
&#9;&#9;&#9;loadoutChildren[i]:TweenPosition(UDim2.new((slot - 1)/10,0,0,0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.25, true)
&#9;&#9;end
&#9;end
end
function openCloseBackpack(close)
&#9;if openCloseDebounce then return end
&#9;openCloseDebounce = true
&#9;local visible = not backpack.Visible
&#9;if visible and not close then
&#9;&#9;updateGridActive()
&#9;&#9;local centerDialogSupported, msg = pcall(function() game.GuiService:AddCenterDialog(backpack, Enum.CenterDialogType.PlayerInitiatedDialog,
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;backpack.Visible = true
&#9;&#9;&#9;&#9;loadoutChildren = currentLoadout:GetChildren()
&#9;&#9;&#9;&#9;for i = 1, #loadoutChildren do
&#9;&#9;&#9;&#9;&#9;if loadoutChildren[i]:IsA(&quot;Frame&quot;) then
&#9;&#9;&#9;&#9;&#9;&#9;loadoutChildren[i].BackgroundTransparency = 0.5
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;spreadOutGear(loadoutChildren)
&#9;&#9;&#9;end,
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;backpack.Visible = false
&#9;&#9;&#9;end)
&#9;&#9;end)
&#9;&#9;backpackButton.Selected = true
&#9;&#9;backpack:TweenSizeAndPosition(UDim2.new(0.55, 0, 0.6, 0),UDim2.new(0.225, 0, 0.2, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, guiTweenSpeed/2, true)
&#9;&#9;delay(guiTweenSpeed/2 + 0.01,
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;local children = backpack:GetChildren()
&#9;&#9;&#9;&#9;for i = 1, #children do
&#9;&#9;&#9;&#9;&#9;if children[i]:IsA(&quot;Frame&quot;) then
&#9;&#9;&#9;&#9;&#9;&#9;children[i].Visible = true
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;resizeGrid()
&#9;&#9;&#9;&#9;resize()
&#9;&#9;&#9;&#9;openCloseDebounce = false
&#9;&#9;&#9;end)
&#9;else
&#9;&#9;backpackButton.Selected = false
&#9;&#9;local children = backpack:GetChildren()
&#9;&#9;for i = 1, #children do
&#9;&#9;&#9;if children[i]:IsA(&quot;Frame&quot;) then
&#9;&#9;&#9;&#9;children[i].Visible = false
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;loadoutChildren = currentLoadout:GetChildren()
&#9;&#9;for i = 1, #loadoutChildren do
&#9;&#9;&#9;if loadoutChildren[i]:IsA(&quot;Frame&quot;) then
&#9;&#9;&#9;&#9;loadoutChildren[i].BackgroundTransparency = 1
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;centerGear(loadoutChildren)
&#9;
&#9;&#9;backpack:TweenSizeAndPosition(UDim2.new(0,0,0,0),UDim2.new(0.5,0,0.5,0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, guiTweenSpeed/2, true)
&#9;&#9;delay(guiTweenSpeed/2 + 0.01,
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;backpack.Visible = true
&#9;&#9;&#9;&#9;resizeGrid()
&#9;&#9;&#9;&#9;resize()
&#9;&#9;&#9;&#9;pcall(function() game.GuiService:RemoveCenterDialog(backpack) end)
&#9;&#9;&#9;&#9;openCloseDebounce = false
&#9;&#9;&#9;end)
&#9;end
end
function loadoutCheck(child, selectState)
&#9;if not child:IsA(&quot;ImageButton&quot;) then return end
&#9;for k,v in pairs(backpackItems) do
&#9;&#9;if buttons[v] then
&#9;&#9;&#9;if child:FindFirstChild(&quot;GearReference&quot;) and buttons[v]:FindFirstChild(&quot;GearReference&quot;) then
&#9;&#9;&#9;&#9;if buttons[v].GearReference.Value == child.GearReference.Value then
&#9;&#9;&#9;&#9;&#9;buttons[v].Active = selectState
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
end
function clearPreview()
&#9;gearPreview.GearImage.Image = &quot;&quot;
&#9;gearPreview.GearStats.GearName.Text = &quot;&quot;
end
function removeAllEquippedGear(physGear)
&#9;local stuff = player.Character:GetChildren()
&#9;for i = 1, #stuff do
&#9;&#9;if ( stuff[i]:IsA(&quot;Tool&quot;) or stuff[i]:IsA(&quot;HopperBin&quot;) ) and stuff[i] ~= physGear then
&#9;&#9;&#9;stuff[i].Parent = playerBackpack
&#9;&#9;end
&#9;end
end
function equipGear(physGear)
&#9;removeAllEquippedGear(physGear)
&#9;physGear.Parent = player.Character
&#9;updateGridActive()
end
function unequipGear(physGear)
&#9;physGear.Parent = playerBackpack
&#9;updateGridActive()
end
function highlight(button)
&#9;button.TextColor3 = Color3.new(0,0,0)
&#9;button.BackgroundColor3 = Color3.new(0.8,0.8,0.8)
end
function clearHighlight(button)
&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;button.BackgroundColor3 = Color3.new(0,0,0)
end
function swapGearSlot(slot,gearButton)
&#9;if not swapSlot.Value then -- signal loadout to swap a gear out
&#9;&#9;swapSlot.Slot.Value = slot
&#9;&#9;swapSlot.GearButton.Value = gearButton
&#9;&#9;swapSlot.Value = true
&#9;&#9;updateGridActive()
&#9;end
end
local UnequipGearMenuClick = function(element, menu)
&#9;if type(element.Action) ~= &quot;number&quot; then return end
&#9;local num = element.Action
&#9;if num == 1 then -- remove from loadout
&#9;&#9;unequipGear(menu.Parent.GearReference.Value)
&#9;&#9;local inventoryButton = menu.Parent
&#9;&#9;local gearToUnequip = inventoryButton.GearReference.Value
&#9;&#9;local loadoutChildren = currentLoadout:GetChildren()
&#9;&#9;local slot = -1
&#9;&#9;for i = 1, #loadoutChildren do
&#9;&#9;&#9;if loadoutChildren[i]:IsA(&quot;Frame&quot;) then
&#9;&#9;&#9;&#9;local button = loadoutChildren[i]:GetChildren()
&#9;&#9;&#9;&#9;if button[1] and button[1].GearReference.Value == gearToUnequip then
&#9;&#9;&#9;&#9;&#9;slot = button[1].SlotNumber.Text
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;swapGearSlot(slot,nil)
&#9;end
end
-- these next two functions are used to stop any use of backpack while the player is dead (can cause issues)
function activateBackpack()
&#9;loadoutChildren = currentLoadout:GetChildren()
&#9;for i = 1, #loadoutChildren do
&#9;&#9;if loadoutChildren[i]:IsA(&quot;Frame&quot;) then
&#9;&#9;&#9;loadoutChildren[i].BackgroundTransparency = 1
&#9;&#9;end
&#9;end
&#9;backpackButtonClickCon = backpackButton.MouseButton1Click:connect(function() openCloseBackpack() end)
&#9;guiServiceKeyPressCon = game:GetService(&quot;GuiService&quot;).KeyPressed:connect(function(key)
&#9;&#9;if key == tilde or key == backquote then
&#9;&#9;&#9;openCloseBackpack()
&#9;&#9;end
&#9;end)
end
function deactivateBackpack()
&#9;if backpackButtonClickCon then backpackButtonClickCon:disconnect() end
&#9;if guiServiceKeyPressCon then guiServiceKeyPressCon:disconnect() end
&#9;openCloseBackpack(true)
end
function setupCharacterConnections()
&#9;if backpackAddCon then backpackAddCon:disconnect() end
&#9;backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded:connect(function(child) addToGrid(child) end)
&#9;
&#9;-- make sure we get all the children
&#9;local backpackChildren = game.Players.LocalPlayer.Backpack:GetChildren()
&#9;for i = 1, #backpackChildren do
&#9;&#9;addToGrid(backpackChildren[i])
&#9;end
&#9;if characterChildAddedCon then characterChildAddedCon:disconnect() end
&#9;characterChildAddedCon =
&#9;&#9;game.Players.LocalPlayer.Character.ChildAdded:connect(function(child)
&#9;&#9;&#9;addToGrid(child)
&#9;&#9;&#9;updateGridActive()
&#9;&#9;end)
&#9;&#9;
&#9;if characterChildRemovedCon then characterChildRemovedCon:disconnect() end
&#9;characterChildRemovedCon =
&#9;&#9;game.Players.LocalPlayer.Character.ChildRemoved:connect(function(child)
&#9;&#9;&#9;updateGridActive()
&#9;&#9;end)
&#9;&#9;
&#9;&#9;&#9;
&#9;if humanoidDiedCon then humanoidDiedCon:disconnect() end
&#9;local localPlayer = game.Players.LocalPlayer
&#9;waitForProperty(localPlayer,&quot;Character&quot;)
&#9;waitForChild(localPlayer.Character,&quot;Humanoid&quot;)
&#9;humanoidDiedCon = game.Players.LocalPlayer.Character.Humanoid.Died:connect(function() deactivateBackpack() end)
&#9;
&#9;activateBackpack()
&#9;wait()
&#9;centerGear(currentLoadout:GetChildren())
end
function removeCharacterConnections()
&#9;if characterChildAddedCon then characterChildAddedCon:disconnect() end
&#9;if characterChildRemovedCon then characterChildRemovedCon:disconnect() end
&#9;if backpackAddCon then backpackAddCon:disconnect() end
end
function trim(s)
return (s:gsub(&quot;^%s*(.-)%s*$&quot;, &quot;%1&quot;))
end
function splitByWhiteSpace(text)
&#9;if type(text) ~= &quot;string&quot; then return nil end
&#9;
&#9;local terms = {}
&#9;for token in string.gmatch(text, &quot;[^%s]+&quot;) do
&#9; if string.len(token) &gt; 2 then
&#9;&#9;&#9;table.insert(terms,token)
&#9; end
&#9;end
&#9;return terms
end
function filterGear(searchTerm)
&#9;string.lower(searchTerm)
&#9;searchTerm = trim(searchTerm)
&#9;if string.len(searchTerm) &lt; 2 then return nil end
&#9;local terms = splitByWhiteSpace(searchTerm)
&#9;
&#9;local filteredGear = {}
&#9;for k,v in pairs(backpackItems) do
&#9;&#9;if buttons[v] then
&#9;&#9;&#9;local gearString = string.lower(buttons[v].GearReference.Value.Name)
&#9;&#9;&#9;gearString = trim(gearString)
&#9;&#9;&#9;for i = 1, #terms do
&#9;&#9;&#9;&#9;if string.match(gearString,terms[i]) then
&#9;&#9;&#9;&#9;&#9;table.insert(filteredGear,buttons[v])
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;
&#9;return filteredGear
end
function showSearchGear()
&#9;local searchText = searchBox.Text
&#9;searchBox.Text = &quot;Search...&quot;
&#9;local filteredButtons = filterGear(searchText)
&#9;if filteredButtons and #filteredButtons &gt; 0 then
&#9;&#9;showPartialGrid(filteredButtons)
&#9;else
&#9;&#9;showEntireGrid()
&#9;end
end
function nukeBackpack()
&#9;while #buttons &gt; 0 do
&#9;&#9;table.remove(buttons)
&#9;end
&#9;buttons = {}
&#9;while #backpackItems &gt; 0 do
&#9;&#9;table.remove(backpackItems)
&#9;end
&#9;backpackItems = {}
&#9;local scrollingFrameChildren = grid.ScrollingFrame:GetChildren()
&#9;for i = 1, #scrollingFrameChildren do
&#9;&#9;scrollingFrameChildren[i]:remove()
&#9;end
end
function getGearContextMenu()
&#9;local gearContextMenu = Instance.new(&quot;Frame&quot;)
&#9;gearContextMenu.Active = true
&#9;gearContextMenu.Name = &quot;UnequipContextMenu&quot;
&#9;gearContextMenu.Size = UDim2.new(0,115,0,70)
&#9;gearContextMenu.Position = UDim2.new(0,-16,0,-16)
&#9;gearContextMenu.BackgroundTransparency = 1
&#9;gearContextMenu.Visible = false
&#9;local gearContextMenuButton = Instance.new(&quot;TextButton&quot;)
&#9;gearContextMenuButton.Name = &quot;UnequipContextMenuButton&quot;
&#9;gearContextMenuButton.Text = &quot;&quot;
&#9;gearContextMenuButton.Style = Enum.ButtonStyle.RobloxButtonDefault
&#9;gearContextMenuButton.ZIndex = 4
&#9;gearContextMenuButton.Size = UDim2.new(1, 0, 1, -20)
&#9;gearContextMenuButton.Visible = true
&#9;gearContextMenuButton.Parent = gearContextMenu
&#9;
&#9;local elementHeight = 12
&#9;
&#9;local contextMenuElements = {}&#9;&#9;
&#9;local contextMenuElementsName = {&quot;Remove Hotkey&quot;}
&#9;for i = 1, #contextMenuElementsName do
&#9;&#9;local element = {}
&#9;&#9;element.Type = &quot;Button&quot;
&#9;&#9;element.Text = contextMenuElementsName[i]
&#9;&#9;element.Action = i
&#9;&#9;element.DoIt = UnequipGearMenuClick
&#9;&#9;table.insert(contextMenuElements,element)
&#9;end
&#9;for i, contextElement in ipairs(contextMenuElements) do
&#9;&#9;local element = contextElement
&#9;&#9;if element.Type == &quot;Button&quot; then
&#9;&#9;&#9;local button = Instance.new(&quot;TextButton&quot;)
&#9;&#9;&#9;button.Name = &quot;UnequipContextButton&quot; .. i
&#9;&#9;&#9;button.BackgroundColor3 = Color3.new(0,0,0)
&#9;&#9;&#9;button.BorderSizePixel = 0
&#9;&#9;&#9;button.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;&#9;button.Text = &quot; &quot; .. contextElement.Text
&#9;&#9;&#9;button.Font = Enum.Font.Arial
&#9;&#9;&#9;button.FontSize = Enum.FontSize.Size14
&#9;&#9;&#9;button.Size = UDim2.new(1, 8, 0, elementHeight)
&#9;&#9;&#9;button.Position = UDim2.new(0,0,0,elementHeight * i)
&#9;&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;button.ZIndex = 4
&#9;&#9;&#9;button.Parent = gearContextMenuButton
&#9;&#9;&#9;button.MouseButton1Click:connect(function()
&#9;&#9;&#9;&#9;if button.Active and not gearContextMenu.Parent.Active then
&#9;&#9;&#9;&#9;&#9;local success, result = pcall(function() element.DoIt(element, gearContextMenu) end)
&#9;&#9;&#9;&#9;&#9;browsingMenu = false
&#9;&#9;&#9;&#9;&#9;gearContextMenu.Visible = false
&#9;&#9;&#9;&#9;&#9;clearHighlight(button)
&#9;&#9;&#9;&#9;&#9;clearPreview()
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;&#9;
&#9;&#9;&#9;button.MouseEnter:connect(function()
&#9;&#9;&#9;&#9;if button.Active and gearContextMenu.Parent.Active then
&#9;&#9;&#9;&#9;&#9;highlight(button)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;&#9;button.MouseLeave:connect(function()
&#9;&#9;&#9;&#9;if button.Active and gearContextMenu.Parent.Active then
&#9;&#9;&#9;&#9;&#9;clearHighlight(button)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;&#9;
&#9;&#9;&#9;contextElement.Button = button
&#9;&#9;&#9;contextElement.Element = button
&#9;&#9;elseif element.Type == &quot;Label&quot; then
&#9;&#9;&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;&#9;&#9;frame.Name = &quot;ContextLabel&quot; .. i
&#9;&#9;&#9;frame.BackgroundTransparency = 1
&#9;&#9;&#9;frame.Size = UDim2.new(1, 8, 0, elementHeight)
&#9;&#9;&#9;local label = Instance.new(&quot;TextLabel&quot;)&#9;
&#9;&#9;&#9;label.Name = &quot;Text1&quot;
&#9;&#9;&#9;label.BackgroundTransparency = 1
&#9;&#9;&#9;label.BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;label.BorderSizePixel = 0
&#9;&#9;&#9;label.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;&#9;label.Font = Enum.Font.ArialBold
&#9;&#9;&#9;label.FontSize = Enum.FontSize.Size14
&#9;&#9;&#9;label.Position = UDim2.new(0.0, 0, 0, 0)
&#9;&#9;&#9;label.Size = UDim2.new(0.5, 0, 1, 0)
&#9;&#9;&#9;label.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;label.ZIndex = 4
&#9;&#9;&#9;label.Parent = frame
&#9;&#9;&#9;element.Label1 = label
&#9;&#9;
&#9;&#9;&#9;if element.GetText2 then
&#9;&#9;&#9;&#9;label = Instance.new(&quot;TextLabel&quot;)&#9;
&#9;&#9;&#9;&#9;label.Name = &quot;Text2&quot;
&#9;&#9;&#9;&#9;label.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;label.BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;label.BorderSizePixel = 0
&#9;&#9;&#9;&#9;label.TextXAlignment = Enum.TextXAlignment.Right
&#9;&#9;&#9;&#9;label.Font = Enum.Font.Arial
&#9;&#9;&#9;&#9;label.FontSize = Enum.FontSize.Size14
&#9;&#9;&#9;&#9;label.Position = UDim2.new(0.5, 0, 0, 0)
&#9;&#9;&#9;&#9;label.Size = UDim2.new(0.5, 0, 1, 0)
&#9;&#9;&#9;&#9;label.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;label.ZIndex = 4
&#9;&#9;&#9;&#9;label.Parent = frame
&#9;&#9;&#9;&#9;element.Label2 = label
&#9;&#9;&#9;end
&#9;&#9;&#9;frame.Parent = gearContextMenuButton
&#9;&#9;&#9;element.Label = frame
&#9;&#9;&#9;element.Element = frame
&#9;&#9;end
&#9;end
&#9;gearContextMenu.ZIndex = 4
&#9;gearContextMenu.MouseLeave:connect(function()
&#9;&#9;browsingMenu = false
&#9;&#9;gearContextMenu.Visible = false
&#9;&#9;clearPreview()
&#9;end)
&#9;robloxLock(gearContextMenu)
&#9;
&#9;return gearContextMenu
end
local backpackChildren = player.Backpack:GetChildren()
for i = 1, #backpackChildren do
&#9;addToGrid(backpackChildren[i])
end
------------------------- Start Lifelong Connections -----------------------
screen.Changed:connect(function(prop)
&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;if debounce then return end
&#9;&#9;debounce = true
&#9;&#9;wait()
&#9;&#9;resize()
&#9;&#9;resizeGrid()
&#9;&#9;debounce = false
&#9;end
end)
currentLoadout.ChildAdded:connect(function(child) loadoutCheck(child, false) end)
currentLoadout.ChildRemoved:connect(function(child) loadoutCheck(child, true) end)
currentLoadout.DescendantAdded:connect(function(descendant)
&#9;if not backpack.Visible and ( descendant:IsA(&quot;ImageButton&quot;) or descendant:IsA(&quot;TextButton&quot;) ) then
&#9;&#9;centerGear(currentLoadout:GetChildren())
&#9;end
end)
currentLoadout.DescendantRemoving:connect(function(descendant)
&#9;if not backpack.Visible and ( descendant:IsA(&quot;ImageButton&quot;) or descendant:IsA(&quot;TextButton&quot;) ) then
&#9;&#9;wait()
&#9;&#9;centerGear(currentLoadout:GetChildren())
&#9;end
end)
&#9;
grid.MouseEnter:connect(function() clearPreview() end)
grid.MouseLeave:connect(function() clearPreview() end)
player.CharacterRemoving:connect(function()
&#9;removeCharacterConnections()
&#9;nukeBackpack()
end)
player.CharacterAdded:connect(function() setupCharacterConnections() end)
player.ChildAdded:connect(function(child)
&#9;if child:IsA(&quot;Backpack&quot;) then
&#9;&#9;playerBackpack = child
&#9;&#9;if backpackAddCon then backpackAddCon:disconnect() end
&#9;&#9;backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded:connect(function(child) addToGrid(child) end)
&#9;end
end)
swapSlot.Changed:connect(function()
&#9;if not swapSlot.Value then
&#9;&#9;updateGridActive()
&#9;end
end)
searchBox.FocusLost:connect(function(enterPressed)
&#9;if enterPressed then
&#9;&#9;showSearchGear()
&#9;end
end)
local loadoutChildren = currentLoadout:GetChildren()
for i = 1, #loadoutChildren do
&#9;if loadoutChildren[i]:IsA(&quot;Frame&quot;) and string.find(loadoutChildren[i].Name,&quot;Slot&quot;) then
&#9;&#9;loadoutChildren[i].ChildRemoved:connect(function()
&#9;&#9;&#9;updateGridActive()
&#9;&#9;end)
&#9;&#9;loadoutChildren[i].ChildAdded:connect(function()
&#9;&#9;&#9;updateGridActive()
&#9;&#9;end)
&#9;end
end
searchButton.MouseButton1Click:connect(function() showSearchGear() end)
resetButton.MouseButton1Click:connect(function() showEntireGrid() end)
------------------------- End Lifelong Connections -----------------------
resize()
resizeGrid()
-- make sure any items in the loadout are accounted for in inventory
local loadoutChildren = currentLoadout:GetChildren()
for i = 1, #loadoutChildren do
&#9;loadoutCheck(loadoutChildren[i], false)
end
if not backpack.Visible then centerGear(currentLoadout:GetChildren()) end
-- make sure that inventory is listening to gear reparenting
if characterChildAddedCon == nil and game.Players.LocalPlayer[&quot;Character&quot;] then
&#9;setupCharacterConnections()
end
if not backpackAddCon then
&#9;backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded:connect(function(child) addToGrid(child) end)
end
-- flip it on if we are good
&#9;backpackButton.Visible = true
recalculateScrollLoadout()</ProtectedString>
</Properties>
</Item>
<Item class="LocalScript" referent="RBX8">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">BackpackScript</string>
<ProtectedString name="Source">-- fixed by iagoMAO#6808, any bugs report to me. --
-- A couple of necessary functions
local function waitForChild(instance, name)
&#9;while not instance:FindFirstChild(name) do
&#9;&#9;instance.ChildAdded:wait()
&#9;end
end
local function waitForProperty(instance, property)
&#9;while not instance[property] do
&#9;&#9;instance.Changed:wait()
&#9;end
end
--- Begin Locals
waitForChild(game,&quot;Players&quot;)
waitForProperty(game.Players,&quot;LocalPlayer&quot;)
local player = game.Players.LocalPlayer
--[[waitForChild(game, &quot;LocalBackpack&quot;)
game.LocalBackpack:SetOldSchoolBackpack(false)--]]
waitForChild(script.Parent, &quot;CurrentLoadout&quot;)
local currentLoadout = script.Parent.CurrentLoadout
local maxNumLoadoutItems = 10
waitForChild(currentLoadout.Parent,&quot;Backpack&quot;)
local guiBackpack = currentLoadout.Parent.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
for i = 0, 9 do
&#9;game:GetService(&quot;GuiService&quot;):AddKey(tostring(i)) -- register our keys
end
local gearSlots = {}
for i = 1, maxNumLoadoutItems do
&#9;gearSlots[i] = &quot;empty&quot;
end
local inventory = {}
local lastLoadout = {}
--- End Locals
-- Begin Functions
local function kill(prop,con,gear)
&#9;if con then con:disconnect() end
&#9;if prop == true and gear then
&#9;&#9;reorganizeLoadout(gear,false)
&#9;end
end
function removeGear(gear)
&#9;local emptySlot = nil
&#9;for i = 1, #gearSlots do
&#9;&#9;if gearSlots[i] == gear and gear.Parent ~= nil then
&#9;&#9;&#9;emptySlot = i
&#9;&#9;&#9;break
&#9;&#9;end
&#9;end
&#9;if emptySlot then
&#9;&#9;if gearSlots[emptySlot].GearReference.Value then
&#9;&#9;&#9;if gearSlots[emptySlot].GearReference.Value.Parent == game.Players.LocalPlayer.Character then -- if we currently have this equipped, unequip it
&#9;&#9;&#9;&#9;gearSlots[emptySlot].GearReference.Value.Parent = game.Players.LocalPlayer.Backpack
&#9;&#9;&#9;end
&#9;&#9;&#9;if gearSlots[emptySlot].GearReference.Value:IsA(&quot;HopperBin&quot;) and gearSlots[emptySlot].GearReference.Value.Active then -- this is an active hopperbin
&#9;&#9;&#9;&#9;gearSlots[emptySlot].GearReference.Value:Disable()
&#9;&#9;&#9;&#9;gearSlots[emptySlot].GearReference.Value.Active = false
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;gearSlots[emptySlot] = &quot;empty&quot;
&#9;&#9;local centerizeX = gear.Size.X.Scale/2
&#9;&#9;local centerizeY = gear.Size.Y.Scale/2
&#9;&#9;gear:TweenSizeAndPosition(UDim2.new(0,0,0,0),
&#9;&#9;&#9;UDim2.new(gear.Position.X.Scale + centerizeX,gear.Position.X.Offset,gear.Position.Y.Scale + centerizeY,gear.Position.Y.Offset),
&#9;&#9;&#9;Enum.EasingDirection.Out, Enum.EasingStyle.Quad,guiTweenSpeed/4,true)
&#9;&#9;delay(guiTweenSpeed/2,
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;gear:remove()
&#9;&#9;&#9;end)
&#9;end
end
function insertGear(gear, addToSlot)
&#9;local pos = nil
&#9;if not addToSlot then
&#9;&#9;for i = 1, #gearSlots do
&#9;&#9;&#9;if gearSlots[i] == &quot;empty&quot; then
&#9;&#9;&#9;&#9;pos = i
&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;if pos == 1 and gearSlots[1] ~= &quot;empty&quot; then gear:remove() return end -- we are currently full, can&apos;t add in
&#9;else
&#9;&#9;pos = addToSlot
&#9;&#9;-- push all gear down one slot
&#9;&#9;local start = 1
&#9;&#9;for i = 1, #gearSlots do
&#9;&#9;&#9;if gearSlots[i] == &quot;empty&quot; then
&#9;&#9;&#9;&#9;start = i
&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;for i = start, pos + 1, -1 do
&#9;&#9;&#9;gearSlots[i] = gearSlots[i - 1]
&#9;&#9;&#9;if i == 10 then
&#9;&#9;&#9;&#9;gearSlots[i].SlotNumber.Text = &quot;0&quot;
&#9;&#9;&#9;&#9;gearSlots[i].SlotNumberDownShadow.Text = &quot;0&quot;
&#9;&#9;&#9;&#9;gearSlots[i].SlotNumberUpShadow.Text = &quot;0&quot;
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;gearSlots[i].SlotNumber.Text = i
&#9;&#9;&#9;&#9;gearSlots[i].SlotNumberDownShadow.Text = i
&#9;&#9;&#9;&#9;gearSlots[i].SlotNumberUpShadow.Text = i
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;gearSlots[pos] = gear
&#9;if pos ~= maxNumLoadoutItems then
&#9;&#9;if(type(tostring(pos)) == &quot;string&quot;) then
&#9;&#9;&#9;local posString = tostring(pos)
&#9;&#9;&#9;gear.SlotNumber.Text = posString
&#9;&#9;&#9;gear.SlotNumberDownShadow.Text = posString
&#9;&#9;&#9;gear.SlotNumberUpShadow.Text = posString
&#9;&#9;end
&#9;else -- tenth gear doesn&apos;t follow mathematical pattern :(
&#9;&#9;gear.SlotNumber.Text = &quot;0&quot;
&#9;&#9;gear.SlotNumberDownShadow.Text = &quot;0&quot;
&#9;&#9;gear.SlotNumberUpShadow.Text = &quot;0&quot;
&#9;end
&#9;gear.Visible = true
&#9;local con = nil
&#9;con = gear.Kill.Changed:connect(function(prop) kill(prop,con,gear) end)
end
function reorganizeLoadout(gear, inserting, equipped, addToSlot)
&#9;if inserting then -- add in gear
&#9;&#9;insertGear(gear, addToSlot)
&#9;else
&#9;&#9;removeGear(gear)
&#9;end
&#9;if gear ~= &quot;empty&quot; then&#9;gear.ZIndex = 1 end
end
function checkToolAncestry(child,parent)
&#9;if child:FindFirstChild(&quot;RobloxBuildTool&quot;) then return end -- don&apos;t show roblox build tools
&#9;if child:IsA(&quot;Tool&quot;) or child:IsA(&quot;HopperBin&quot;) then
&#9;&#9;for i = 1, #gearSlots do
&#9;&#9;&#9;if gearSlots[i] ~= &quot;empty&quot; and gearSlots[i].GearReference.Value == child then
&#9;&#9;&#9;&#9;if parent == nil then
&#9;&#9;&#9;&#9;&#9;gearSlots[i].Kill.Value = true
&#9;&#9;&#9;&#9;&#9;return false
&#9;&#9;&#9;&#9;elseif child.Parent == player.Character then
&#9;&#9;&#9;&#9;&#9;gearSlots[i].Selected = true
&#9;&#9;&#9;&#9;&#9;return true
&#9;&#9;&#9;&#9;elseif child.Parent == player.Backpack then
&#9;&#9;&#9;&#9;&#9;if child:IsA(&quot;Tool&quot;) then gearSlots[i].Selected = false end
&#9;&#9;&#9;&#9;&#9;return true
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;gearSlots[i].Kill.Value = true
&#9;&#9;&#9;&#9;&#9;return false
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;return true
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
end
function removeAllEquippedGear(physGear)
&#9;local stuff = player.Character:GetChildren()
&#9;for i = 1, #stuff do
&#9;&#9;if ( stuff[i]:IsA(&quot;Tool&quot;) or stuff[i]:IsA(&quot;HopperBin&quot;) ) and stuff[i] ~= physGear then
&#9;&#9;&#9;if stuff[i]:IsA(&quot;Tool&quot;) then stuff[i].Parent = player.Backpack end
&#9;&#9;&#9;if stuff[i]:IsA(&quot;HopperBin&quot;) then
&#9;&#9;&#9;&#9;stuff[i]:Disable()
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
end
function hopperBinSwitcher(numKey, physGear)
&#9;if not physGear then return end
&#9;physGear:ToggleSelect()
&#9;if gearSlots[numKey] == &quot;empty&quot; then return end
&#9;if not physGear.Active then
&#9;&#9;gearSlots[numKey].Selected = false
&#9;&#9;normalizeButton(gearSlots[numKey])
&#9;else
&#9;&#9;gearSlots[numKey].Selected = true
&#9;&#9;enlargeButton(gearSlots[numKey])
&#9;end
end
function toolSwitcher(numKey)
&#9;if not gearSlots[numKey] then return end
&#9;local physGear = gearSlots[numKey].GearReference.Value
&#9;if physGear == nil then return end
&#9;removeAllEquippedGear(physGear) -- we don&apos;t remove this gear, as then we get a double switcheroo
&#9;local key = numKey
&#9;if numKey == 0 then key = 10 end
&#9;for i = 1, #gearSlots do
&#9;&#9;if gearSlots[i] and gearSlots[i] ~= &quot;empty&quot; and i ~= key then
&#9;&#9;&#9;normalizeButton(gearSlots[i])
&#9;&#9;&#9;gearSlots[i].Selected = false
&#9;&#9;&#9;if gearSlots[i].GearReference and gearSlots[i].GearReference.Value and gearSlots[i].GearReference.Value:IsA(&quot;HopperBin&quot;) and gearSlots[i].GearReference.Value.Active then
&#9;&#9;&#9;&#9;gearSlots[i].GearReference.Value:ToggleSelect()
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;if physGear:IsA(&quot;HopperBin&quot;) then
&#9;&#9;hopperBinSwitcher(numKey,physGear)
&#9;else
&#9;&#9;if physGear.Parent == player.Character then
&#9;&#9;&#9;physGear.Parent = player.Backpack
&#9;&#9;&#9;gearSlots[numKey].Selected = false
&#9;&#9;&#9;normalizeButton(gearSlots[numKey])
&#9;&#9;else
&#9;&#9;&#9;physGear.Parent = player.Character
&#9;&#9;&#9;gearSlots[numKey].Selected = true
&#9;&#9;&#9;enlargeButton(gearSlots[numKey])
&#9;&#9;end
&#9;end
end
function activateGear(num)
&#9;local numKey = nil
&#9;if num == &quot;0&quot; then
&#9;&#9;numKey = 10 -- why do lua indexes have to start at 1? :(
&#9;else
&#9;&#9;numKey = tonumber(num)
&#9;end
&#9;if(numKey == nil) then return end
&#9;if gearSlots[numKey] ~= &quot;empty&quot; then
&#9;&#9;toolSwitcher(numKey)
&#9;end
end
enlargeButton = function(button)
&#9;if button.Size.Y.Scale &gt; 1 then return end
&#9;if not button.Parent then return end
&#9;if not button.Selected then return end
&#9;for i = 1, #gearSlots do
&#9;&#9;if gearSlots[i] == &quot;empty&quot; then break end
&#9;&#9;if gearSlots[i] ~= button then
&#9;&#9;&#9;normalizeButton(gearSlots[i])
&#9;&#9;end
&#9;end
&#9;if not enlargeOverride then
&#9;&#9;waitingOnEnlarge = button
&#9;&#9;return
&#9;end
&#9;if button:IsA(&quot;ImageButton&quot;) or button:IsA(&quot;TextButton&quot;) then
&#9;&#9;button.ZIndex = 2
&#9;&#9;local centerizeX = -(buttonSizeEnlarge.X.Scale - button.Size.X.Scale)/2
&#9;&#9;local centerizeY = -(buttonSizeEnlarge.Y.Scale - button.Size.Y.Scale)/2
&#9;&#9;button:TweenSizeAndPosition(buttonSizeEnlarge,
&#9;&#9;&#9;UDim2.new(button.Position.X.Scale + centerizeX,button.Position.X.Offset,button.Position.Y.Scale + centerizeY,button.Position.Y.Offset),
&#9;&#9;&#9;Enum.EasingDirection.Out, Enum.EasingStyle.Quad,guiTweenSpeed/5,enlargeOverride)
&#9;end
end
normalizeAllButtons = function()
&#9;for i = 1, #gearSlots do
&#9;&#9;if gearSlots[i] == &quot;empty&quot; then break end
&#9;&#9;if gearSlots[i] ~= button then
&#9;&#9;&#9;normalizeButton(gearSlots[i],0.1)
&#9;&#9;end
&#9;end
end
normalizeButton = function(button, speed)
&#9;if not button then return end
&#9;if button.Size.Y.Scale &lt;= 1 then return end
&#9;if button.Selected then return end
&#9;if not button.Parent then return end
&#9;local moveSpeed = speed
&#9;if moveSpeed == nil or type(moveSpeed) ~= &quot;number&quot; then moveSpeed = guiTweenSpeed/5 end
&#9;if button:IsA(&quot;ImageButton&quot;) or button:IsA(&quot;TextButton&quot;) then
&#9;&#9;button.ZIndex = 1
&#9;&#9;local inverseEnlarge = 1/enlargeFactor
&#9;&#9;local centerizeX = -(buttonSizeNormal.X.Scale - button.Size.X.Scale)/2
&#9;&#9;local centerizeY = -(buttonSizeNormal.Y.Scale - button.Size.Y.Scale)/2
&#9;&#9;button:TweenSizeAndPosition(buttonSizeNormal,
&#9;&#9;&#9;UDim2.new(button.Position.X.Scale + centerizeX,button.Position.X.Offset,button.Position.Y.Scale + centerizeY,button.Position.Y.Offset),
&#9;&#9;&#9;Enum.EasingDirection.Out, Enum.EasingStyle.Quad,moveSpeed,enlargeOverride)
&#9;end
end
waitForDebounce = function()
&#9;if debounce.Value then
&#9;&#9;debounce.Changed:wait()
&#9;end
end
function pointInRectangle(point,rectTopLeft,rectSize)
&#9;if point.x &gt; rectTopLeft.x and point.x &lt; (rectTopLeft.x + rectSize.x) then
&#9;&#9;if point.y &gt; rectTopLeft.y and point.y &lt; (rectTopLeft.y + rectSize.y) then
&#9;&#9;&#9;return true
&#9;&#9;end
&#9;end
&#9;return false
end
function swapGear(gearClone,toFrame)
&#9;local toFrameChildren = toFrame:GetChildren()
&#9;if #toFrameChildren == 1 then
&#9;&#9;if toFrameChildren[1]:FindFirstChild(&quot;SlotNumber&quot;) then
&#9;&#9;&#9;local toSlot = tonumber(toFrameChildren[1].SlotNumber.Text)
&#9;&#9;&#9;local gearCloneSlot = tonumber(gearClone.SlotNumber.Text)
&#9;&#9;&#9;if toSlot == 0 then toSlot = 10 end
&#9;&#9;&#9;if gearCloneSlot == 0 then gearCloneSlot = 10 end
&#9;&#9;&#9;gearSlots[toSlot] = gearClone
&#9;&#9;&#9;gearSlots[gearCloneSlot] = toFrameChildren[1]
&#9;&#9;&#9;toFrameChildren[1].SlotNumber.Text = gearClone.SlotNumber.Text
&#9;&#9;&#9;toFrameChildren[1].SlotNumberDownShadow.Text = gearClone.SlotNumber.Text
&#9;&#9;&#9;toFrameChildren[1].SlotNumberUpShadow.Text = gearClone.SlotNumber.Text
&#9;&#9;&#9;local subString = string.sub(toFrame.Name,5)
&#9;&#9;&#9;gearClone.SlotNumber.Text = subString
&#9;&#9;&#9;gearClone.SlotNumberDownShadow.Text = subString
&#9;&#9;&#9;gearClone.SlotNumberUpShadow.Text = subString
&#9;&#9;&#9;gearClone.Position = UDim2.new(gearClone.Position.X.Scale,0,gearClone.Position.Y.Scale,0)
&#9;&#9;&#9;toFrameChildren[1].Position = UDim2.new(toFrameChildren[1].Position.X.Scale,0,toFrameChildren[1].Position.Y.Scale,0)
&#9;&#9;&#9;toFrameChildren[1].Parent = gearClone.Parent
&#9;&#9;&#9;gearClone.Parent = toFrame
&#9;&#9;end
&#9;else
&#9;&#9;local slotNum = tonumber(gearClone.SlotNumber.Text)
&#9;&#9;if slotNum == 0 then slotNum = 10 end
&#9;&#9;gearSlots[slotNum] = &quot;empty&quot; -- reset this gear slot
&#9;&#9;local subString = string.sub(toFrame.Name,5)
&#9;&#9;gearClone.SlotNumber.Text = subString
&#9;&#9;gearClone.SlotNumberDownShadow.Text = subString
&#9;&#9;gearClone.SlotNumberUpShadow.Text = subString
&#9;&#9;local toSlotNum = tonumber(gearClone.SlotNumber.Text)
&#9;&#9;if toSlotNum == 0 then toSlotNum = 10 end
&#9;&#9;gearSlots[toSlotNum] = gearClone
&#9;&#9;gearClone.Position = UDim2.new(gearClone.Position.X.Scale,0,gearClone.Position.Y.Scale,0)
&#9;&#9;gearClone.Parent = toFrame
&#9;end
end
function resolveDrag(gearClone,x,y)
&#9;local mousePoint = Vector2.new(x,y)
&#9;local frame = gearClone.Parent
&#9;local frames = frame.Parent:GetChildren()
&#9;for i = 1, #frames do
&#9;&#9;if frames[i]:IsA(&quot;Frame&quot;) then
&#9;&#9;&#9;if pointInRectangle(mousePoint, frames[i].AbsolutePosition,frames[i].AbsoluteSize) then
&#9;&#9;&#9;&#9;swapGear(gearClone,frames[i])
&#9;&#9;&#9;&#9;saveGearPositions()
&#9;&#9;&#9;&#9;return true
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;if x &lt; frame.AbsolutePosition.x or x &gt; ( frame.AbsolutePosition.x + frame.AbsoluteSize.x ) then
&#9;&#9;reorganizeLoadout(gearClone,false)
&#9;&#9;saveGearPositions()
&#9;&#9;return false
&#9;elseif y &lt; frame.AbsolutePosition.y or y &gt; ( frame.AbsolutePosition.y + frame.AbsoluteSize.y ) then
&#9;&#9;reorganizeLoadout(gearClone,false)
&#9;&#9;saveGearPositions()
&#9;&#9;return false
&#9;else
&#9;&#9;if dragBeginPos then gearClone.Position = dragBeginPos end
&#9;&#9;return -1
&#9;end
end
function saveGearPositions()
&#9;lastLoadout = {}
&#9;for i = 1, #gearSlots do
&#9;&#9;if gearSlots[i] and gearSlots[i] ~= &quot;empty&quot; then
&#9;&#9;&#9;lastLoadout[i] = gearSlots[i]
&#9;&#9;end
&#9;end
end
function unequipAllItems(dontEquipThis)
&#9;for i = 1, #gearSlots do
&#9;&#9;if gearSlots[i] == &quot;empty&quot; then break end
&#9;&#9;if gearSlots[i].GearReference.Value and gearSlots[i].GearReference.Value ~= dontEquipThis then
&#9;&#9;&#9;if gearSlots[i].GearReference.Value:IsA(&quot;HopperBin&quot;) then
&#9;&#9;&#9;&#9;gearSlots[i].GearReference.Value:Disable()
&#9;&#9;&#9;elseif gearSlots[i].GearReference.Value:IsA(&quot;Tool&quot;) then
&#9;&#9;&#9;&#9;gearSlots[i].GearReference.Value.Parent = game.Players.LocalPlayer.Backpack
&#9;&#9;&#9;end
&#9;&#9;&#9;gearSlots[i].Selected = false
&#9;&#9;end
&#9;end
end
function showToolTip(button, tip)
&#9;if button and button:FindFirstChild(&quot;ToolTipLabel&quot;) and button.ToolTipLabel:IsA(&quot;TextLabel&quot;) then
&#9;&#9;button.ToolTipLabel.Text = tostring(tip)
&#9;&#9;local xSize = button.ToolTipLabel.TextBounds.X + 6
&#9;&#9;button.ToolTipLabel.Size = UDim2.new(0,xSize,0,20)
&#9;&#9;button.ToolTipLabel.Position = UDim2.new(0.5,-xSize/2,0,-30)
&#9;&#9;button.ToolTipLabel.Visible = true
&#9;end
end
function hideToolTip(button, tip)
&#9;if button and button:FindFirstChild(&quot;ToolTipLabel&quot;) and button.ToolTipLabel:IsA(&quot;TextLabel&quot;) then
&#9;&#9;button.ToolTipLabel.Visible = false
&#9;end
end
local addingPlayerChild = function(child, equipped, addToSlot, inventoryGearButton)
&#9;waitForDebounce()
&#9;debounce.Value = true
&#9;if child:FindFirstChild(&quot;RobloxBuildTool&quot;) then debounce.Value = false return end -- don&apos;t show roblox build tools
&#9;if not child:IsA(&quot;Tool&quot;) then
&#9;&#9;if not child:IsA(&quot;HopperBin&quot;) then
&#9;&#9;&#9;debounce.Value = false
&#9;&#9;&#9;return -- we don&apos;t care about anything besides tools (sigh...)
&#9;&#9;end
&#9;end
&#9;if not addToSlot then
&#9;&#9;for i = 1, #gearSlots do
&#9;&#9;&#9;if gearSlots[i] ~= &quot;empty&quot; and gearSlots[i].GearReference.Value == child then -- we already have gear, do nothing
&#9;&#9;&#9;&#9;debounce.Value = false
&#9;&#9;&#9;&#9;return
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local gearClone = currentLoadout.TempSlot:clone()
&#9;gearClone.Name = child.Name
&#9;gearClone.GearImage.Image = child.TextureId
&#9;if gearClone.GearImage.Image == &quot;&quot; then
&#9;&#9;gearClone.GearText.Text = child.Name
&#9;end
&#9;gearClone.GearReference.Value = child
&#9;
&#9;gearClone.MouseEnter:connect(function()
&#9;&#9;if gearClone.GearReference and gearClone.GearReference.Value[&quot;ToolTip&quot;] and gearClone.GearReference.Value.ToolTip ~= &quot;&quot; then
&#9;&#9;&#9;showToolTip(gearClone, gearClone.GearReference.Value.ToolTip)
&#9;&#9;end
&#9;end)
&#9;
&#9;gearClone.MouseLeave:connect(function()
&#9;&#9;if gearClone.GearReference and gearClone.GearReference.Value[&quot;ToolTip&quot;] and gearClone.GearReference.Value.ToolTip ~= &quot;&quot; then
&#9;&#9;&#9;hideToolTip(gearClone, gearClone.GearReference.Value.ToolTip)
&#9;&#9;end
&#9;end)
&#9;local slotToMod = -1
&#9;if not addToSlot then
&#9;&#9;for i = 1, #gearSlots do
&#9;&#9;&#9;if gearSlots[i] == &quot;empty&quot; then
&#9;&#9;&#9;&#9;slotToMod = i
&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;end
&#9;&#9;end
&#9;else
&#9;&#9;slotToMod = addToSlot
&#9;end
&#9;if slotToMod == - 1 then debounce.Value = false return end -- No available slot to add in!
&#9;local slotNum = slotToMod % 10
&#9;local parent = currentLoadout:FindFirstChild(&quot;Slot&quot;..tostring(slotNum))
&#9;gearClone.Parent = parent
&#9;if inventoryGearButton then
&#9;&#9;local absolutePositionFinal = inventoryGearButton.AbsolutePosition
&#9;&#9;local currentAbsolutePosition = gearClone.AbsolutePosition
&#9;&#9;local diff = absolutePositionFinal - currentAbsolutePosition
&#9;&#9;gearClone.Position = UDim2.new(gearClone.Position.X.Scale,diff.x,gearClone.Position.Y.Scale,diff.y)
&#9;&#9;gearClone.ZIndex = 4
&#9;end
&#9;if addToSlot then
&#9;&#9;reorganizeLoadout(gearClone, true, equipped, addToSlot)
&#9;else
&#9;&#9;reorganizeLoadout(gearClone, true)
&#9;end
&#9;if gearClone.Parent == nil then debounce.Value = false return end -- couldn&apos;t fit in (hopper is full!)
&#9;if equipped then
&#9;&#9;gearClone.Selected = true
&#9;&#9;unequipAllItems(child)
&#9;&#9;delay(guiTweenSpeed + 0.01,function() -- if our gear is equipped, we will want to enlarge it when done moving
&#9;&#9;&#9;if gearClone:FindFirstChild(&quot;GearReference&quot;) and ( (gearClone.GearReference.Value:IsA(&quot;Tool&quot;) and gearClone.GearReference.Value.Parent == player.Character) or
&#9;&#9;&#9;&#9;(gearClone.GearReference.Value:IsA(&quot;HopperBin&quot;) and gearClone.GearReference.Value.Active == true) ) then
&#9;&#9;&#9;&#9;&#9;enlargeButton(gearClone)
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;end
&#9;local dragBeginPos = nil
&#9;local clickCon, buttonDeleteCon, mouseEnterCon, mouseLeaveCon, dragStop, dragBegin = nil
&#9;clickCon = gearClone.MouseButton1Click:connect(function() if not gearClone.Draggable then activateGear(gearClone.SlotNumber.Text) end end)
&#9;mouseEnterCon = gearClone.MouseEnter:connect(function()
&#9;&#9;if guiBackpack.Visible then
&#9;&#9;&#9;gearClone.Draggable = true
&#9;&#9;end
&#9;end)
&#9;dragBegin = gearClone.DragBegin:connect(function(pos)
&#9;&#9;dragBeginPos = pos
&#9;&#9;gearClone.ZIndex = 7
&#9;&#9;local children = gearClone:GetChildren()
&#9;&#9;for i = 1, #children do
&#9;&#9;&#9;if children[i]:IsA(&quot;TextLabel&quot;) then
&#9;&#9;&#9;&#9;if string.find(children[i].Name,&quot;Shadow&quot;) then
&#9;&#9;&#9;&#9;&#9;children[i].ZIndex = 8
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;children[i].ZIndex = 9
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;elseif children[i]:IsA(&quot;Frame&quot;) or children[i]:IsA(&quot;ImageLabel&quot;) then
&#9;&#9;&#9;&#9; children[i].ZIndex = 7
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end)
&#9;dragStop = gearClone.DragStopped:connect(function(x,y)
&#9;&#9;if gearClone.Selected then
&#9;&#9;&#9;gearClone.ZIndex = 2
&#9;&#9;else
&#9;&#9;&#9;gearClone.ZIndex = 1
&#9;&#9;end
&#9;&#9;local children = gearClone:GetChildren()
&#9;&#9;for i = 1, #children do
&#9;&#9;&#9;if children[i]:IsA(&quot;TextLabel&quot;) then
&#9;&#9;&#9;&#9;if string.find(children[i].Name,&quot;Shadow&quot;) then
&#9;&#9;&#9;&#9;&#9;children[i].ZIndex = 3
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;children[i].ZIndex = 4
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;elseif children[i]:IsA(&quot;Frame&quot;) or children[i]:IsA(&quot;ImageLabel&quot;) then
&#9;&#9;&#9;&#9; children[i].ZIndex = 2
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;resolveDrag(gearClone,x,y)
&#9;end)
&#9;mouseLeaveCon = gearClone.MouseLeave:connect(function()
&#9;&#9;gearClone.Draggable = false
&#9;end)
&#9;buttonDeleteCon = gearClone.AncestryChanged:connect(function()
&#9;&#9;&#9;if gearClone.Parent and gearClone.Parent.Parent == currentLoadout then return end
&#9;&#9;&#9;if clickCon then clickCon:disconnect() end
&#9;&#9;&#9;if buttonDeleteCon then buttonDeleteCon:disconnect() end
&#9;&#9;&#9;if mouseEnterCon then mouseEnterCon:disconnect() end
&#9;&#9;&#9;if mouseLeaveCon then mouseLeaveCon:disconnect() end
&#9;&#9;&#9;if dragStop then dragStop:disconnect() end
&#9;&#9;&#9;if dragBegin then dragBegin:disconnect() end
&#9;end) -- this probably isn&apos;t necessary since objects are being deleted (probably), but this might still leak just in case
&#9;local childCon = nil
&#9;local childChangeCon = nil
&#9;childCon = child.AncestryChanged:connect(function(newChild,parent)
&#9;&#9;if not checkToolAncestry(newChild,parent) then
&#9;&#9;&#9;if childCon then childCon:disconnect() end
&#9;&#9;&#9;if childChangeCon then childChangeCon:disconnect() end
&#9;&#9;&#9;removeFromInventory(child)
&#9;&#9;elseif parent == game.Players.LocalPlayer.Backpack then
&#9;&#9;&#9;normalizeButton(gearClone)
&#9;&#9;end
&#9;end)
&#9;childChangeCon = child.Changed:connect(function(prop)
&#9;&#9;if prop == &quot;Name&quot; then
&#9;&#9;&#9;if gearClone and gearClone.GearImage.Image == &quot;&quot; then
&#9;&#9;&#9;&#9;gearClone.GearText.Text = child.Name
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end)
&#9;debounce.Value = false
end
function addToInventory(child)
&#9;if not child:IsA(&quot;Tool&quot;) or not child:IsA(&quot;HopperBin&quot;) then return end
&#9;local slot = nil
&#9;for i = 1, #inventory do
&#9;&#9;if inventory[i] and inventory[i] == child then return end
&#9;&#9;if not inventory[i] then slot = i end
&#9;end
&#9;if slot then
&#9;&#9;inventory[slot] = child
&#9;elseif #inventory &lt; 1 then
&#9;&#9;inventory[1] = child
&#9;else
&#9;&#9;inventory[#inventory + 1] = child
&#9;end
end
function removeFromInventory(child)
&#9;for i = 1, #inventory do
&#9;&#9;if inventory[i] == child then
&#9;&#9;&#9;table.remove(inventory,i)
&#9;&#9;&#9;inventory[i] = nil
&#9;&#9;end
&#9;end
end
-- these next two functions are used for safe guarding
-- when we are waiting for character to come back after dying
function activateLoadout()
&#9;keyPressCon = game:GetService(&quot;GuiService&quot;).KeyPressed:connect(function(key) activateGear(key) end)
&#9;currentLoadout.Visible = true
end
function deactivateLoadout()
&#9;if keyPressCon then keyPressCon:disconnect() end
&#9;currentLoadout.Visible = false
end
function setupBackpackListener()
&#9;if backpackChildCon then backpackChildCon:disconnect() backpackChildCon = nil end
&#9;backpackChildCon = player.Backpack.ChildAdded:connect(function(child)
&#9;&#9;addingPlayerChild(child)
&#9;&#9;addToInventory(child)
&#9;&#9;&#9;
&#9;&#9;-- now store info in case of death
&#9;&#9;saveGearPositions()
&#9;end)
end
function playerCharacterChildAdded(child)
&#9;addingPlayerChild(child,true)
&#9;addToInventory(child)
&#9;
&#9;-- now store info in case of death
&#9;saveGearPositions()
end
-- End Functions
-- Begin Script
wait() -- let stuff initialize incase this is first heartbeat...
waitForChild(player,&quot;Backpack&quot;)
local backpackChildren = player.Backpack:GetChildren()
local size = math.min(10,#backpackChildren)
for i = 1, size do
&#9;addingPlayerChild(backpackChildren[i],false)
&#9;
&#9;-- now store info in case of death
&#9;saveGearPositions()
end
setupBackpackListener()
waitForProperty(player,&quot;Character&quot;)
for i,v in ipairs(player.Character:GetChildren()) do
&#9;playerCharacterChildAdded(v)
end
characterChildAddedCon = player.Character.ChildAdded:connect(function(child) playerCharacterChildAdded(child) end)
waitForChild(player.Character,&quot;Humanoid&quot;)
humanoidDiedCon = player.Character.Humanoid.Died:connect(function()
&#9;if humanoidDiedCon then humanoidDiedCon:disconnect() humanoidDiedCon = nil end
&#9;deactivateLoadout()
&#9;if backpackChildCon then backpackChildCon:disconnect() backpackChildCon = nil end
end)
player.CharacterRemoving:connect(function()
&#9;for i = 1, #gearSlots do
&#9;&#9;if gearSlots[i] ~= &quot;empty&quot; then
&#9;&#9;&#9;gearSlots[i].Parent = nil
&#9;&#9;&#9;gearSlots[i] = &quot;empty&quot;
&#9;&#9;end
&#9;end
end)
player.CharacterAdded:connect(function()
&#9;player = game.Players.LocalPlayer -- make sure we are still looking at the correct character
&#9;
&#9;waitForChild(player,&quot;Backpack&quot;)
&#9;local backpackChildren = player.Backpack:GetChildren()
&#9;-- Make sure we put gear back in where we last had them
&#9;for i = 1, #backpackChildren do
&#9;&#9;for pos,v in pairs(lastLoadout) do
&#9;&#9;&#9;if v[&quot;Name&quot;] and v.Name == backpackChildren[i].Name then
&#9;&#9;&#9;&#9;&#9;addingPlayerChild(backpackChildren[i],false,pos)
&#9;&#9;&#9;&#9;&#9;lastLoadout[pos] = nil
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;end&#9;
&#9;&#9;end
&#9;end
&#9;setupBackpackListener()
&#9;
&#9;if characterChildAddedCon then
&#9;&#9;characterChildAddedCon:disconnect()
&#9;&#9;characterChildAddedCon = nil
&#9;end
&#9;characterChildAddedCon =
&#9;&#9;player.Character.ChildAdded:connect(function(child)
&#9;&#9;&#9;addingPlayerChild(child,true)
&#9;&#9;&#9;
&#9;&#9;&#9;-- now store info in case of death
&#9;&#9;&#9;saveGearPositions()
&#9;&#9;end)
&#9;waitForChild(player.Character,&quot;Humanoid&quot;)
&#9;humanoidDiedCon =
&#9;&#9;player.Character.Humanoid.Died:connect(function()
&#9;&#9;&#9;deactivateLoadout()
&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;if humanoidDiedCon then humanoidDiedCon:disconnect() humanoidDiedCon = nil end
&#9;&#9;&#9;if backpackChildCon then backpackChildCon:disconnect() backpackChildCon = nil end
&#9;&#9;end)
&#9;activateLoadout()
end)
waitForChild(guiBackpack,&quot;SwapSlot&quot;)
guiBackpack.SwapSlot.Changed:connect(function()
&#9;if guiBackpack.SwapSlot.Value then
&#9;&#9;local swapSlot = guiBackpack.SwapSlot
&#9;&#9;local pos = swapSlot.Slot.Value
&#9;&#9;if pos == 0 then pos = 10 end
&#9;&#9;if gearSlots[pos] then
&#9;&#9;&#9;reorganizeLoadout(gearSlots[pos],false)
&#9;&#9;end
&#9;&#9;if swapSlot.GearButton.Value then
&#9;&#9;&#9;addingPlayerChild(swapSlot.GearButton.Value.GearReference.Value,false,pos)
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;-- now store info in case of death
&#9;&#9;&#9;saveGearPositions()
&#9;&#9;end
&#9;&#9;guiBackpack.SwapSlot.Value = false
&#9;end
end)
keyPressCon = game:GetService(&quot;GuiService&quot;).KeyPressed:connect(function(key) activateGear(key) end)</ProtectedString>
</Properties>
</Item>
</Item>
<Item class="ScreenGui" referent="RBX9">
<Properties>
<string name="Name">Dialogs</string>
</Properties>
<Item class="Frame" referent="RBX10">
<Properties>
<bool name="Active">false</bool>
<Color3 name="BackgroundColor3">4288914085</Color3>
<float name="BackgroundTransparency">1</float>
<Color3 name="BorderColor3">4279970357</Color3>
<int name="BorderSizePixel">1</int>
<bool name="ClipsDescendants">false</bool>
<bool name="Draggable">false</bool>
<string name="Name">ControlFrame</string>
<UDim2 name="Position">
<XS>0</XS>
<XO>0</XO>
<YS>0</YS>
<YO>0</YO>
</UDim2>
<UDim2 name="Size">
<XS>1</XS>
<XO>0</XO>
<YS>1</YS>
<YO>0</YO>
</UDim2>
<token name="SizeConstraint">0</token>
<token name="Style">0</token>
<bool name="Visible">true</bool>
<int name="ZIndex">1</int>
</Properties>
<Item class="Frame" referent="RBX11">
<Properties>
<bool name="Active">false</bool>
<Color3 name="BackgroundColor3">4288914085</Color3>
<float name="BackgroundTransparency">1</float>
<Color3 name="BorderColor3">4279970357</Color3>
<int name="BorderSizePixel">1</int>
<bool name="ClipsDescendants">false</bool>
<bool name="Draggable">false</bool>
<string name="Name">BottomLeftControl</string>
<UDim2 name="Position">
<XS>0</XS>
<XO>0</XO>
<YS>1</YS>
<YO>-46</YO>
</UDim2>
<UDim2 name="Size">
<XS>0</XS>
<XO>130</XO>
<YS>0</YS>
<YO>46</YO>
</UDim2>
<token name="SizeConstraint">0</token>
<token name="Style">0</token>
<bool name="Visible">true</bool>
<int name="ZIndex">1</int>
</Properties>
</Item>
<Item class="NotificationBox" referent="RBX12">
<Properties>
<bool name="Active">false</bool>
<Color3 name="BackgroundColor3">4288914085</Color3>
<float name="BackgroundTransparency">1</float>
<Color3 name="BorderColor3">4279970357</Color3>
<int name="BorderSizePixel">1</int>
<bool name="ClipsDescendants">false</bool>
<bool name="Draggable">false</bool>
<string name="Name">NotificationBox</string>
<UDim2 name="Position">
<XS>1</XS>
<XO>-200</XO>
<YS>0.5</YS>
<YO>0</YO>
</UDim2>
<UDim2 name="Size">
<XS>0</XS>
<XO>200</XO>
<YS>0.419999987</YS>
<YO>0</YO>
</UDim2>
<token name="SizeConstraint">0</token>
<bool name="Visible">true</bool>
<int name="ZIndex">1</int>
</Properties>
</Item>
</Item>
<Item class="LocalScript" referent="RBX13">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">Init</string>
<ProtectedString name="Source">--rbxsig%XeVmMtUuu+dXh8pEbcaTkr2m9RJZXY42LaACJ12YYcuPtOUxy4Azi8uMDGU8ZTh7cvZC9BlOWgqmZHKjESSdfOZl0/cgd2JKHPZ2UqiqA1slJa7R5GtCcGXlNPHW8KDYgJGRuwe8h5CSiMDOl6QLTSEegTOG7fzHk/n1AFcRN8I=%
--rbxassetid%39250920%
--fixed by Carrot#0559
function waitForProperty(instance, name)
&#9;while not instance[name] do
&#9;&#9;instance.Changed:wait()
&#9;end
end
local beter = game.Lighting
function waitForDialogChildrenMyLord(beter, name)
&#9;&#9;while not beter:FindFirstChild(name) do
&#9;&#9;&#9;beter.ChildAdded:wait()
&#9;&#9;end
end
local bois = game.Players.LocalPlayer.PlayerGui
function waitForFaker(bois, name)
&#9;&#9;while not bois:FindFirstChild(name) do
&#9;&#9;&#9;bois.ChildAdded:wait()
&#9;&#9;end
end
local mainFrame
local choices = {}
local lastChoice
local choiceMap = {}
local currentConversationDialog
local currentConversationPartner
local currentAbortDialogScript
local tooFarAwayMessage = &quot;You are too far away to chat!&quot;
local tooFarAwaySize = 300
local characterWanderedOffMessage = &quot;Chat ended because you walked away&quot;
local characterWanderedOffSize = 350
local conversationTimedOut = &quot;Chat ended because you didn&apos;t reply&quot;
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,&quot;CoreGui&quot;)
--waitForDialogChildrenMyLord(game.CoreGui,&quot;RobloxGui&quot;)
--if game.CoreGui.RobloxGui:FindFirstChild(&quot;ControlFrame&quot;) then
--&#9;gui = game.CoreGui.RobloxGui.ControlFrame
--else
--&#9;gui = game.CoreGui.RobloxGui
--end
function currentTone()
&#9;if currentConversationDialog then
&#9;&#9;return currentConversationDialog.Tone
&#9;else
&#9;&#9;return Enum.DialogTone.Neutral
&#9;end
end
&#9;
function createChatNotificationGui()
&#9;chatNotificationGui = Instance.new(&quot;BillboardGui&quot;)
&#9;chatNotificationGui.Name = &quot;ChatNotificationGui&quot;
&#9;chatNotificationGui.ExtentsOffset = Vector3.new(0,1,0)
&#9;chatNotificationGui.Size = UDim2.new(4, 0, 5.42857122, 0)
&#9;chatNotificationGui.SizeOffset = Vector2.new(0,0)
&#9;chatNotificationGui.StudsOffset = Vector3.new(0.4, 4.3, 0)
&#9;chatNotificationGui.Enabled = true
&#9;chatNotificationGui.Active = true
&#9;local image = Instance.new(&quot;ImageLabel&quot;)
&#9;image.Name = &quot;Image&quot;
&#9;image.Active = false
&#9;image.BackgroundTransparency = 1
&#9;image.Position = UDim2.new(0,0,0,0)
&#9;image.Size = UDim2.new(1.0,0,1.0,0)
&#9;image.Image = &quot;&quot;
&#9;image.Parent = chatNotificationGui
&#9;local button = Instance.new(&quot;ImageButton&quot;)
&#9;button.Name = &quot;Button&quot;
&#9;button.AutoButtonColor = false
&#9;button.Position = UDim2.new(0.0879999995, 0, 0.0529999994, 0)
&#9;button.Size = UDim2.new(0.829999983, 0, 0.460000008, 0)
&#9;button.Image = &quot;&quot;
&#9;button.BackgroundTransparency = 1
&#9;button.Parent = image
end
function getChatColor(tone)
&#9;if tone == Enum.DialogTone.Neutral then
&#9;&#9;return Enum.ChatColor.Blue
&#9;elseif tone == Enum.DialogTone.Friendly then
&#9;&#9;return Enum.ChatColor.Green
&#9;elseif tone == Enum.DialogTone.Enemy then
&#9;&#9;return Enum.ChatColor.Red
&#9;end
end
function styleChoices(tone)
&#9;for i, obj in pairs(choices) do
&#9;&#9;resetColor(obj, tone)
&#9;end
&#9;resetColor(lastChoice, tone)
end
function styleMainFrame(tone)
&#9;if tone == Enum.DialogTone.Neutral then
&#9;&#9;mainFrame.Style = Enum.FrameStyle.ChatBlue
&#9;&#9;mainFrame.Tail.Image = &quot;rbxasset://textures/chatBubble_botBlue_tailRight.png&quot;
&#9;elseif tone == Enum.DialogTone.Friendly then
&#9;&#9;mainFrame.Style = Enum.FrameStyle.ChatGreen
&#9;&#9;mainFrame.Tail.Image = &quot;rbxasset://textures/chatBubble_botGreen_tailRight.png&quot;
&#9;elseif tone == Enum.DialogTone.Enemy then
&#9;&#9;mainFrame.Style = Enum.FrameStyle.ChatRed
&#9;&#9;mainFrame.Tail.Image = &quot;rbxasset://textures/chatBubble_botRed_tailRight.png&quot;
&#9;end
&#9;
&#9;styleChoices(tone)
end
function setChatNotificationTone(gui, purpose, tone)
&#9;if tone == Enum.DialogTone.Neutral then
&#9;&#9;gui.Image.Image = &quot;rbxasset://textures/chatBubble_botBlue_notify_bkg.png&quot;
&#9;elseif tone == Enum.DialogTone.Friendly then
&#9;&#9;gui.Image.Image = &quot;rbxasset://textures/chatBubble_botGreen_notify_bkg.png&quot;
&#9;elseif tone == Enum.DialogTone.Enemy then
&#9;&#9;gui.Image.Image = &quot;rbxasset://textures/chatBubble_botRed_notify_bkg.png&quot;
&#9;end
&#9;if purpose == Enum.DialogPurpose.Quest then
&#9;&#9;gui.Image.Button.Image = &quot;rbxasset://textures/chatBubble_bot_notify_bang.png&quot;
&#9;elseif purpose == Enum.DialogPurpose.Help then
&#9;&#9;gui.Image.Button.Image = &quot;rbxasset://textures/chatBubble_bot_notify_question.png&quot;
&#9;elseif purpose == Enum.DialogPurpose.Shop then
&#9;&#9;gui.Image.Button.Image = &quot;rbxasset://textures/chatBubble_bot_notify_money.png&quot;
&#9;end
end
function createMessageDialog()
&#9;messageDialog = Instance.new(&quot;Frame&quot;);
&#9;messageDialog.Name = &quot;DialogScriptMessage&quot;
&#9;messageDialog.Style = Enum.FrameStyle.RobloxRound
&#9;messageDialog.Visible = false
&#9;local text = Instance.new(&quot;TextLabel&quot;)
&#9;text.Name = &quot;Text&quot;
&#9;text.Position = UDim2.new(0,0,0,-1)
&#9;text.Size = UDim2.new(1,0,1,0)
&#9;text.FontSize = Enum.FontSize.Size14
&#9;text.BackgroundTransparency = 1
&#9;text.TextColor3 = Color3.new(1,1,1)
&#9;text.Parent = messageDialog
end
function showMessage(msg, size)
&#9;messageDialog.Text.Text = msg
&#9;messageDialog.Size = UDim2.new(0,size,0,40)
&#9;messageDialog.Position = UDim2.new(0.5, -size/2, 0.5, -40)
&#9;messageDialog.Visible = true
&#9;wait(2)
&#9;messageDialog.Visible = false
end
function variableDelay(str)
&#9;local length = math.min(string.len(str), 100)
&#9;wait(0.75 + ((length/75) * 1.5))
end
function resetColor(frame, tone)
&#9;if tone == Enum.DialogTone.Neutral then
&#9;&#9;frame.BackgroundColor3 = Color3.new(0/255, 0/255, 179/255)
&#9;&#9;frame.Number.TextColor3 = Color3.new(45/255, 142/255, 245/255)
&#9;elseif tone == Enum.DialogTone.Friendly then
&#9;&#9;frame.BackgroundColor3 = Color3.new(0/255, 77/255, 0/255)
&#9;&#9;frame.Number.TextColor3 = Color3.new(0/255, 190/255, 0/255)
&#9;elseif tone == Enum.DialogTone.Enemy then
&#9;&#9;frame.BackgroundColor3 = Color3.new(140/255, 0/255, 0/255)
&#9;&#9;frame.Number.TextColor3 = Color3.new(255/255,88/255, 79/255)
&#9;end
end
function highlightColor(frame, tone)
&#9;if tone == Enum.DialogTone.Neutral then
&#9;&#9;frame.BackgroundColor3 = Color3.new(2/255, 108/255, 255/255)
&#9;&#9;frame.Number.TextColor3 = Color3.new(1, 1, 1)
&#9;elseif tone == Enum.DialogTone.Friendly then
&#9;&#9;frame.BackgroundColor3 = Color3.new(0/255, 128/255, 0/255)
&#9;&#9;frame.Number.TextColor3 = Color3.new(1, 1, 1)
&#9;elseif tone == Enum.DialogTone.Enemy then
&#9;&#9;frame.BackgroundColor3 = Color3.new(204/255, 0/255, 0/255)
&#9;&#9;frame.Number.TextColor3 = Color3.new(1, 1, 1)
&#9;end
end
function wanderDialog()
&#9;print(&quot;Wander&quot;)
&#9;mainFrame.Visible = false
&#9;endDialog()
&#9;showMessage(characterWanderedOffMessage, characterWanderedOffSize)
end
function timeoutDialog()
&#9;print(&quot;Timeout&quot;)
&#9;mainFrame.Visible = false
&#9;endDialog()
&#9;showMessage(conversationTimedOut, conversationTimedOutSize)
end
function normalEndDialog()
&#9;print(&quot;Done&quot;)
&#9;endDialog()
end
function endDialog()
if currentAbortDialogScript then
&#9;&#9;currentAbortDialogScript:Remove()
&#9;&#9;currentAbortDialogScript = nil
&#9;end
&#9;local dialog = currentConversationDialog
&#9;currentConversationDialog = nil
&#9;if dialog and dialog.InUse then
&#9;&#9;local reenableScript = reenableDialogScript:Clone()
&#9;&#9;reenableScript.archivable = false
&#9;&#9;reenableScript.Disabled = false
&#9;&#9;reenableScript.Parent = dialog
&#9;end
&#9;for dialog, gui in pairs(dialogMap) do
&#9;&#9;if dialog and gui then
&#9;&#9;&#9;gui.Enabled = not dialog.InUse
&#9;&#9;end
&#9;end
&#9;currentConversationPartner = nil
end
function sanitizeMessage(msg)
if string.len(msg) == 0 then
return &quot;...&quot;
else
return msg
end
end
function selectChoice(choice)
&#9;renewKillswitch(currentConversationDialog)
&#9;--First hide the Gui
&#9;mainFrame.Visible = false
&#9;if choice == lastChoice then
&#9;&#9;game.Chat:Chat(game.Players.LocalPlayer.Character, &quot;Goodbye!&quot;, getChatColor(currentTone()))
&#9;&#9;
&#9;&#9;normalEndDialog()
&#9;else
&#9;&#9;local dialogChoice = choiceMap[choice]
&#9;&#9;game.Chat:Chat(game.Players.LocalPlayer.Character, sanitizeMessage(dialogChoice.UserDialog), getChatColor(currentTone()))
&#9;&#9;wait(1)
&#9;&#9;--currentConversationDialog:SignalDialogChoiceSelected(player, dialogChoice)
&#9;&#9;game.Chat:Chat(currentConversationPartner, sanitizeMessage(dialogChoice.ResponseDialog), getChatColor(currentTone()))
&#9;
&#9;&#9;variableDelay(dialogChoice.ResponseDialog)
&#9;&#9;presentDialogChoices(currentConversationPartner, dialogChoice:GetChildren())
&#9;end
end
function newChoice(numberText)
&#9;local frame = Instance.new(&quot;TextButton&quot;)
&#9;frame.BackgroundColor3 = Color3.new(0/255, 0/255, 179/255)
&#9;frame.AutoButtonColor = false
&#9;frame.BorderSizePixel = 0
&#9;frame.Text = &quot;&quot;
&#9;frame.MouseEnter:connect(function() highlightColor(frame, currentTone()) end)
&#9;frame.MouseLeave:connect(function() resetColor(frame, currentTone()) end)
&#9;frame.MouseButton1Click:connect(function() selectChoice(frame) end)
&#9;local number = Instance.new(&quot;TextLabel&quot;)
&#9;number.Name = &quot;Number&quot;
&#9;number.TextColor3 = Color3.new(127/255, 212/255, 255/255)
&#9;number.Text = numberText
&#9;number.FontSize = Enum.FontSize.Size14
&#9;number.BackgroundTransparency = 1
&#9;number.Position = UDim2.new(0,4,0,2)
&#9;number.Size = UDim2.new(0,20,0,24)
&#9;number.TextXAlignment = Enum.TextXAlignment.Left
&#9;number.TextYAlignment = Enum.TextYAlignment.Top
&#9;number.Parent = frame
&#9;local prompt = Instance.new(&quot;TextLabel&quot;)
&#9;prompt.Name = &quot;UserPrompt&quot;
&#9;prompt.BackgroundTransparency = 1
&#9;prompt.TextColor3 = Color3.new(1,1,1)
&#9;prompt.FontSize = Enum.FontSize.Size14
&#9;prompt.Position = UDim2.new(0,28, 0, 2)
&#9;prompt.Size = UDim2.new(1,-32, 1, -4)
&#9;prompt.TextXAlignment = Enum.TextXAlignment.Left
&#9;prompt.TextYAlignment = Enum.TextYAlignment.Top
&#9;prompt.TextWrap = true
&#9;prompt.Parent = frame
&#9;return frame
end
function initialize(parent)
&#9;choices[1] = newChoice(&quot;1)&quot;)
&#9;choices[2] = newChoice(&quot;2)&quot;)
&#9;choices[3] = newChoice(&quot;3)&quot;)
&#9;choices[4] = newChoice(&quot;4)&quot;)
&#9;lastChoice = newChoice(&quot;5)&quot;)
&#9;lastChoice.UserPrompt.Text = &quot;Goodbye!&quot;
&#9;lastChoice.Size = UDim2.new(1,0,0,28)
&#9;mainFrame = Instance.new(&quot;Frame&quot;)
&#9;mainFrame.Name = &quot;UserDialogArea&quot;
&#9;mainFrame.Size = UDim2.new(0, 350, 0, 200)
&#9;mainFrame.Style = Enum.FrameStyle.ChatBlue
&#9;mainFrame.Visible = false
&#9;
&#9;local imageLabel = Instance.new(&quot;ImageLabel&quot;)
&#9;imageLabel.Name = &quot;Tail&quot;
&#9;imageLabel.Size = UDim2.new(0,62,0,53)
&#9;imageLabel.Position = UDim2.new(1,8,0.25)
&#9;imageLabel.Image = &quot;rbxasset://textures/chatBubble_botBlue_tailRight.png&quot;
&#9;imageLabel.BackgroundTransparency = 1
&#9;imageLabel.Parent = mainFrame
&#9;&#9;
&#9;for n, obj in pairs(choices) do
&#9;&#9;obj.Parent = mainFrame
&#9;end
&#9;lastChoice.Parent = mainFrame
&#9;mainFrame.Parent = parent
end
function presentDialogChoices(talkingPart, dialogChoices)
&#9;if not currentConversationDialog then
&#9;&#9;return
&#9;end
&#9;currentConversationPartner = talkingPart
&#9;local sortedDialogChoices = {}
&#9;for n, obj in pairs(dialogChoices) do
&#9;&#9;if obj:IsA(&quot;DialogChoice&quot;) then
&#9;&#9;&#9;table.insert(sortedDialogChoices, obj)
&#9;&#9;end
&#9;end
&#9;table.sort(sortedDialogChoices, function(a,b) return a.Name &lt; b.Name end)
&#9;if #sortedDialogChoices == 0 then
&#9;&#9;normalEndDialog()
&#9;&#9;return
&#9;end
&#9;local pos = 1
local yPosition = 0
&#9;choiceMap = {}
&#9;for n, obj in pairs(choices) do
&#9;&#9;obj.Visible = false
&#9;end
&#9;for n, obj in pairs(sortedDialogChoices) do
&#9;&#9;if pos &lt;= #choices then
&#9;&#9;&#9;--3 lines is the maximum, set it to that temporarily
&#9;&#9;&#9;choices[pos].Size = UDim2.new(1, 0, 0, 24*3)
&#9;&#9;&#9;choices[pos].UserPrompt.Text = obj.UserDialog
&#9;&#9;&#9;local height = math.ceil(choices[pos].UserPrompt.TextBounds.Y/24)*24
&#9;&#9;&#9;choices[pos].Position = UDim2.new(0, 0, 0, yPosition)
&#9;&#9;&#9;choices[pos].Size = UDim2.new(1, 0, 0, height)
&#9;&#9;&#9;choices[pos].Visible = true
&#9;&#9;
&#9;&#9;&#9;choiceMap[choices[pos]] = obj
&#9;&#9;&#9;yPosition = yPosition + height
&#9;&#9;&#9;pos = pos + 1
&#9;&#9;end
&#9;end
&#9;lastChoice.Position = UDim2.new(0,0,0,yPosition)&#9;
&#9;lastChoice.Number.Text = pos .. &quot;)&quot;
&#9;mainFrame.Size = UDim2.new(0, 350, 0, yPosition+24+32)
&#9;mainFrame.Position = UDim2.new(0,20,0.0, -mainFrame.Size.Y.Offset-20)
&#9;styleMainFrame(currentTone())
&#9;mainFrame.Visible = true
end
function doDialog(dialog)
&#9;while not Instance.Lock(dialog, player) do
&#9;&#9;wait()
&#9;end
&#9;if dialog.InUse then
&#9;&#9;Instance.Unlock(dialog)
&#9;&#9;return &#9;&#9;&#9;
&#9;else
&#9;&#9;dialog.InUse = true
&#9;&#9;Instance.Unlock(dialog)
&#9;end
&#9;currentConversationDialog = dialog
&#9;game.Chat:Chat(dialog.Parent, dialog.InitialPrompt, getChatColor(dialog.Tone))
&#9;variableDelay(dialog.InitialPrompt)
&#9;presentDialogChoices(dialog.Parent, dialog:GetChildren())
end
function renewKillswitch(dialog)
&#9;if currentAbortDialogScript then
&#9;&#9;currentAbortDialogScript:Remove()
&#9;&#9;currentAbortDialogScript = nil
&#9;end
&#9;currentAbortDialogScript = timeoutScript:Clone()
&#9;currentAbortDialogScript.archivable = false
&#9;currentAbortDialogScript.Disabled = false
&#9;currentAbortDialogScript.Parent = dialog
end
function checkForLeaveArea()
&#9;while currentConversationDialog do
&#9;&#9;if currentConversationDialog.Parent and (player:DistanceFromCharacter(currentConversationDialog.Parent.Position) &gt;= currentConversationDialog.ConversationDistance) then
&#9;&#9;&#9;wanderDialog()
&#9;&#9;end
&#9;&#9;wait(1)&#9;&#9;
&#9;end
end
function startDialog(dialog)
&#9;if dialog.Parent and dialog.Parent:IsA(&quot;BasePart&quot;) then
&#9;&#9;if player:DistanceFromCharacter(dialog.Parent.Position) &gt;= dialog.ConversationDistance then
&#9;&#9;&#9;showMessage(tooFarAwayMessage, tooFarAwaySize)
&#9;&#9;&#9;return
&#9;&#9;end&#9;
&#9;&#9;
&#9;&#9;for dialog, gui in pairs(dialogMap) do
&#9;&#9;&#9;if dialog and gui then
&#9;&#9;&#9;&#9;gui.Enabled = false
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;renewKillswitch(dialog)
&#9;&#9;delay(1, checkForLeaveArea)
&#9;&#9;doDialog(dialog)
&#9;end
end
function removeDialog(dialog)
if dialogMap[dialog] then
dialogMap[dialog]:Remove()
dialogMap[dialog] = nil
end
&#9;if dialogConnections[dialog] then
&#9;&#9;dialogConnections[dialog]:disconnect()
&#9;&#9;dialogConnections[dialog] = nil
&#9;end
end&#9;
function addDialog(dialog)
&#9;if dialog.Parent then
&#9;&#9;if dialog.Parent:IsA(&quot;BasePart&quot;) then
&#9;&#9;&#9;local chatGui = chatNotificationGui:clone()
&#9;&#9;&#9;chatGui.Enabled = not dialog.InUse&#9;&#9;
&#9;&#9;&#9;chatGui.Adornee = dialog.Parent
&#9;&#9;&#9;chatGui.Parent = game.Players.LocalPlayer.PlayerGui
&#9;&#9;&#9;chatGui.Image.Button.MouseButton1Click:connect(function() startDialog(dialog) end)
&#9;&#9;&#9;setChatNotificationTone(chatGui, dialog.Purpose, dialog.Tone)
&#9;&#9;&#9;
&#9;&#9;&#9;dialogMap[dialog] = chatGui
&#9;&#9;&#9;dialogConnections[dialog] = dialog.Changed:connect(function(prop)
&#9;&#9;&#9;&#9;if prop == &quot;Parent&quot; and dialog.Parent then
&#9;&#9;&#9;&#9;&#9;--This handles the reparenting case, seperate from removal case
&#9;&#9;&#9;&#9;&#9;removeDialog(dialog)
&#9;&#9;&#9;&#9;&#9;addDialog(dialog)
&#9;&#9;&#9;&#9;elseif prop == &quot;InUse&quot; then
&#9;&#9;&#9;&#9;&#9;chatGui.Enabled = not currentConversationDialog and not dialog.InUse
&#9;&#9;&#9;&#9;&#9;if dialog == currentConversationDialog then
&#9;&#9;&#9;&#9;&#9;&#9;timeoutDialog()
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;elseif prop == &quot;Tone&quot; or prop == &quot;Purpose&quot; then
&#9;&#9;&#9;&#9;&#9;setChatNotificationTone(chatGui, dialog.Purpose, dialog.Tone)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;else -- still need to listen to parent changes even if current parent is not a BasePart
&#9;&#9;&#9;dialogConnections[dialog] = dialog.Changed:connect(function(prop)
&#9;&#9;&#9;&#9;if prop == &quot;Parent&quot; and dialog.Parent then
&#9;&#9;&#9;&#9;&#9;--This handles the reparenting case, seperate from removal case
&#9;&#9;&#9;&#9;&#9;removeDialog(dialog)
&#9;&#9;&#9;&#9;&#9;addDialog(dialog)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;end
&#9;end
end
--[[function fetchScripts()
&#9;local model = game:GetService(&quot;InsertService&quot;):LoadAsset(39226062)
if type(model) == &quot;string&quot; then -- load failed, lets try again
&#9;&#9;wait(0.1)
&#9;&#9;model = game:GetService(&quot;InsertService&quot;):LoadAsset(39226062)
&#9;end
&#9;if type(model) == &quot;string&quot; then -- not going to work, lets bail
&#9;&#9;return
&#9;end
&#9;
&#9;waitForDialogChildrenMyLord(model,&quot;TimeoutScript&quot;)
&#9;timeoutScript = model.TimeoutScript
&#9;waitForDialogChildrenMyLord(model,&quot;ReenableDialogScript&quot;)
&#9;reenableDialogScript = model.ReenableDialogScript
end
]]--
function onLoad()
waitForProperty(game.Players, &quot;LocalPlayer&quot;)
player = game.Players.LocalPlayer
waitForProperty(player, &quot;Character&quot;)
--print(&quot;Fetching Scripts&quot;)
--fetchScripts()
--print(&quot;Creating Guis&quot;)
createChatNotificationGui()
waitForFaker(bois,&quot;Dialogs&quot;)
--print(&quot;Creating MessageDialog&quot;)
createMessageDialog()
messageDialog.Parent = game.Players.LocalPlayer.PlayerGui.Dialogs
--print(&quot;Initializing Frame&quot;)
local frame = Instance.new(&quot;Frame&quot;)
frame.Name = &quot;DialogFrame&quot;
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(&quot;Adding Dialogs&quot;)
game.CollectionService.ItemAdded:connect(function(obj) if obj:IsA(&quot;Dialog&quot;) then addDialog(obj) end end)
game.CollectionService.ItemRemoved:connect(function(obj) if obj:IsA(&quot;Dialog&quot;) then removeDialog(obj) end end)
for i, obj in pairs(game.CollectionService:GetCollection(&quot;Dialog&quot;)) do
if obj:IsA(&quot;Dialog&quot;) then
addDialog(obj)
end
end
end
onLoad()</ProtectedString>
</Properties>
</Item>
</Item>
<Item class="GuiMain" referent="RBX14">
<Properties>
<string name="Name">Health</string>
</Properties>
<Item class="Frame" referent="RBX15">
<Properties>
<bool name="Active">false</bool>
<Color3 name="BackgroundColor3">4285215356</Color3>
<float name="BackgroundTransparency">1</float>
<Color3 name="BorderColor3">4279970357</Color3>
<int name="BorderSizePixel">1</int>
<bool name="ClipsDescendants">false</bool>
<bool name="Draggable">false</bool>
<string name="Name">tray</string>
<UDim2 name="Position">
<XS>0.5</XS>
<XO>-44</XO>
<YS>1</YS>
<YO>-26</YO>
</UDim2>
<UDim2 name="Size">
<XS>0</XS>
<XO>170</XO>
<YS>0</YS>
<YO>18</YO>
</UDim2>
<token name="SizeConstraint">2</token>
<token name="Style">0</token>
<bool name="Visible">true</bool>
<int name="ZIndex">1</int>
</Properties>
<Item class="ImageLabel" referent="RBX16">
<Properties>
<bool name="Active">false</bool>
<Color3 name="BackgroundColor3">4294967295</Color3>
<float name="BackgroundTransparency">1</float>
<Color3 name="BorderColor3">4279970357</Color3>
<int name="BorderSizePixel">1</int>
<bool name="ClipsDescendants">false</bool>
<bool name="Draggable">false</bool>
<Content name="Image"><url>rbxasset://textures/healthgui/bkg.png</url></Content>
<string name="Name">bkg</string>
<UDim2 name="Position">
<XS>0</XS>
<XO>0</XO>
<YS>0</YS>
<YO>0</YO>
</UDim2>
<UDim2 name="Size">
<XS>1</XS>
<XO>0</XO>
<YS>1</YS>
<YO>0</YO>
</UDim2>
<token name="SizeConstraint">0</token>
<bool name="Visible">true</bool>
<int name="ZIndex">1</int>
</Properties>
</Item>
<Item class="ImageLabel" referent="RBX17">
<Properties>
<bool name="Active">false</bool>
<Color3 name="BackgroundColor3">4294967295</Color3>
<float name="BackgroundTransparency">1</float>
<Color3 name="BorderColor3">4279970357</Color3>
<int name="BorderSizePixel">1</int>
<bool name="ClipsDescendants">false</bool>
<bool name="Draggable">false</bool>
<Content name="Image"><url>rbxasset://textures/healthgui/BarRed.png</url></Content>
<string name="Name">barRed</string>
<UDim2 name="Position">
<XS>0.0189999994</XS>
<XO>0</XO>
<YS>0.100000001</YS>
<YO>0</YO>
</UDim2>
<UDim2 name="Size">
<XS>0</XS>
<XO>0</XO>
<YS>0</YS>
<YO>0</YO>
</UDim2>
<token name="SizeConstraint">0</token>
<bool name="Visible">true</bool>
<int name="ZIndex">1</int>
</Properties>
</Item>
<Item class="Frame" referent="RBX18">
<Properties>
<bool name="Active">false</bool>
<Color3 name="BackgroundColor3">4294967295</Color3>
<float name="BackgroundTransparency">1.00000012</float>
<Color3 name="BorderColor3">4279970357</Color3>
<int name="BorderSizePixel">0</int>
<bool name="ClipsDescendants">false</bool>
<bool name="Draggable">false</bool>
<string name="Name">bar2</string>
<UDim2 name="Position">
<XS>0.0189999994</XS>
<XO>0</XO>
<YS>0.100000001</YS>
<YO>0</YO>
</UDim2>
<UDim2 name="Size">
<XS>0.192000002</XS>
<XO>0</XO>
<YS>0.829999983</YS>
<YO>0</YO>
</UDim2>
<token name="SizeConstraint">0</token>
<token name="Style">0</token>
<bool name="Visible">true</bool>
<int name="ZIndex">1</int>
</Properties>
<Item class="LocalScript" referent="RBX19">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">Init</string>
<ProtectedString name="Source">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)
&#9;local width = (health / h.MaxHealth) * maxWidth
&#9;local height = 0.83
&#9;local lastX = tray.bar.Position.X.Scale
&#9;local x = 0.019 + (maxWidth - width)
&#9;local y = 0.1
&#9;
&#9;tray.bar.Position = UDim2.new(x,0,y, 0)
&#9;tray.bar.Size = UDim2.new(width, 0, height, 0)
&#9;-- If more than 1/4 health, bar = green. Else, bar = red.
&#9;if( (health / h.MaxHealth) &gt; 0.25 ) then
&#9;&#9;tray.barRed.Size = UDim2.new(0, 0, 0, 0)
&#9;else
&#9;&#9;tray.barRed.Position = tray.bar.Position
&#9;&#9;tray.barRed.Size = tray.bar.Size
&#9;&#9;tray.bar.Size = UDim2.new(0, 0, 0, 0)
&#9;end
&#9;
&#9;if ( (lastHealth - health) &gt; (h.MaxHealth / 10) ) then
&#9;&#9;lastHealth = health
&#9;&#9;if h.Health ~= h.MaxHealth then
&#9;&#9;&#9;delay(0,function()
&#9;&#9;&#9;&#9;AnimateHurtOverlay()
&#9;&#9;&#9;end)
&#9;&#9;&#9;delay(0,function()
&#9;&#9;&#9;&#9;AnimateBars(x, y, lastX, height)
&#9;&#9;&#9;end)
&#9;&#9;end
&#9;else
&#9;&#9;lastHealth = health
&#9;end
end
function AnimateBars(x, y, lastX, height)
&#9;local width = math.abs(x - lastX)
&#9;if( x &gt; lastX ) then
&#9;&#9;x = lastX
&#9;end
&#9;tray.bar2.Position = UDim2.new(x,0, y, 0)
&#9;tray.bar2.Size = UDim2.new(width, 0, height, 0)
&#9;tray.bar2.BackgroundTransparency = 0
&#9;local GBchannels = 1
&#9;local j = 0.2
&#9;local i_total = 30
&#9;for i=1,i_total do
&#9;&#9;-- Increment Values
&#9;&#9;if (GBchannels &lt; 0.2) then
&#9;&#9;&#9;j = -j
&#9;&#9;end
&#9;&#9;GBchannels = GBchannels + j
&#9;&#9;if (i &gt; (i_total - 10)) then
&#9;&#9;&#9;tray.bar2.BackgroundTransparency = tray.bar2.BackgroundTransparency + 0.1
&#9;&#9;end
&#9;&#9;tray.bar2.BackgroundColor3 = Color3.new(1, GBchannels, GBchannels)
&#9;&#9;
&#9;&#9;wait(0.02)
&#9;end
end
function AnimateHurtOverlay()
&#9;-- Start:
&#9;-- overlay.Position = UDim2.new(0, 0, 0, -22)
&#9;-- overlay.Size = UDim2.new(1, 0, 1.15, 30)
&#9;
&#9;-- Finish:
&#9;-- overlay.Position = UDim2.new(-2, 0, -2, -22)
&#9;-- overlay.Size = UDim2.new(4.5, 0, 4.65, 30)
&#9;
&#9;overlay = base.hurtOverlay
&#9;overlay.Visible = true
&#9;overlay.Position = UDim2.new(-2, 0, -2, -22)
&#9;overlay.Size = UDim2.new(4.5, 0, 4.65, 30)
&#9;-- Animate In, fast
&#9;local i_total = 2
&#9;local wiggle_total = 0
&#9;local wiggle_i = 0.02
&#9;for i=1,i_total do
&#9;&#9;overlay.Position = UDim2.new( (-2 + (2 * (i/i_total)) + wiggle_total/2), 0, (-2 + (2 * (i/i_total)) + wiggle_total/2), -22 )
&#9;&#9;overlay.Size = UDim2.new( (4.5 - (3.5 * (i/i_total)) + wiggle_total), 0, (4.65 - (3.5 * (i/i_total)) + wiggle_total), 30 )
&#9;&#9;wait(0.01)
&#9;end
&#9;
&#9;i_total = 30
&#9;
&#9;wait(0.03)
&#9;
&#9;-- Animate Out, slow
&#9;for i=1,i_total do
&#9;&#9;if( math.abs(wiggle_total) &gt; (wiggle_i * 3) ) then
&#9;&#9;&#9;wiggle_i = -wiggle_i
&#9;&#9;end
&#9;&#9;wiggle_total = wiggle_total + wiggle_i
&#9;&#9;overlay.Position = UDim2.new( (0 - (2 * (i/i_total)) + wiggle_total/2), 0, (0 - (2 * (i/i_total)) + wiggle_total/2), -22 )
&#9;&#9;overlay.Size = UDim2.new( (1 + (3.5 * (i/i_total)) + wiggle_total), 0, (1.15 + (3.5 * (i/i_total)) + wiggle_total), 30 )
&#9;&#9;wait(0.01)
&#9;end
&#9;
&#9;-- Hide after we&apos;re done
&#9;overlay.Position = UDim2.new(10, 0, 0, 0)
&#9;overlay.Visible = false
end
h.Changed:connect(function()
&#9;UpdateGUI(h.Health)
&#9;if ( (lastHealth2 - h.Health) &gt; (h.MaxHealth / 10) ) then
&#9;&#9;lastHealth2 = h.Health
&#9;else
&#9;&#9;lastHealth2 = h.Health
&#9;end end)</ProtectedString>
</Properties>
</Item>
</Item>
<Item class="ImageLabel" referent="RBX20">
<Properties>
<bool name="Active">false</bool>
<Color3 name="BackgroundColor3">4294967295</Color3>
<float name="BackgroundTransparency">1</float>
<Color3 name="BorderColor3">4279970357</Color3>
<int name="BorderSizePixel">1</int>
<bool name="ClipsDescendants">false</bool>
<bool name="Draggable">false</bool>
<Content name="Image"><url>rbxasset://textures/healthgui/Bar.png</url></Content>
<string name="Name">bar</string>
<UDim2 name="Position">
<XS>0.0189999994</XS>
<XO>0</XO>
<YS>0.100000001</YS>
<YO>0</YO>
</UDim2>
<UDim2 name="Size">
<XS>0.959999979</XS>
<XO>0</XO>
<YS>0.829999983</YS>
<YO>0</YO>
</UDim2>
<token name="SizeConstraint">0</token>
<bool name="Visible">true</bool>
<int name="ZIndex">1</int>
</Properties>
</Item>
<Item class="ImageLabel" referent="RBX21">
<Properties>
<bool name="Active">false</bool>
<Color3 name="BackgroundColor3">4294967295</Color3>
<float name="BackgroundTransparency">1</float>
<Color3 name="BorderColor3">4279970357</Color3>
<int name="BorderSizePixel">0</int>
<bool name="ClipsDescendants">false</bool>
<bool name="Draggable">false</bool>
<Content name="Image"><url>rbxasset://textures/healthgui/label.png</url></Content>
<string name="Name">label</string>
<UDim2 name="Position">
<XS>0.680000007</XS>
<XO>0</XO>
<YS>0.300000012</YS>
<YO>0</YO>
</UDim2>
<UDim2 name="Size">
<XS>0.25</XS>
<XO>0</XO>
<YS>0.349999994</YS>
<YO>0</YO>
</UDim2>
<token name="SizeConstraint">0</token>
<bool name="Visible">true</bool>
<int name="ZIndex">1</int>
</Properties>
</Item>
</Item>
<Item class="ImageLabel" referent="RBX22">
<Properties>
<bool name="Active">false</bool>
<Color3 name="BackgroundColor3">4290164919</Color3>
<float name="BackgroundTransparency">1</float>
<Color3 name="BorderColor3">4279970357</Color3>
<int name="BorderSizePixel">1</int>
<bool name="ClipsDescendants">false</bool>
<bool name="Draggable">false</bool>
<Content name="Image"><url>rbxasset://textures/healthgui/HurtOverlay.png</url></Content>
<string name="Name">hurtOverlay</string>
<UDim2 name="Position">
<XS>2</XS>
<XO>0</XO>
<YS>0</YS>
<YO>-22</YO>
</UDim2>
<UDim2 name="Size">
<XS>1</XS>
<XO>0</XO>
<YS>1.1500001</YS>
<YO>30</YO>
</UDim2>
<token name="SizeConstraint">0</token>
<bool name="Visible">false</bool>
<int name="ZIndex">1</int>
</Properties>
</Item>
<Item class="LocalScript" referent="RBX23">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">Hide</string>
<ProtectedString name="Source">while true do
&#9;game.Players.LocalPlayer.PlayerGui.HealthGUI.tray.Visible = false
&#9;game.Players.LocalPlayer.PlayerGui.HealthGUI.hurtOverlay.Visible = false
end</ProtectedString>
</Properties>
</Item>
</Item>
<Item class="ScreenGui" referent="RBX24">
<Properties>
<string name="Name">Menu</string>
</Properties>
<Item class="Frame" referent="RBX25">
<Properties>
<bool name="Active">false</bool>
<Color3 name="BackgroundColor3">4288914085</Color3>
<float name="BackgroundTransparency">1</float>
<Color3 name="BorderColor3">4279970357</Color3>
<int name="BorderSizePixel">1</int>
<bool name="ClipsDescendants">false</bool>
<bool name="Draggable">false</bool>
<string name="Name">ControlFrame</string>
<UDim2 name="Position">
<XS>0</XS>
<XO>0</XO>
<YS>0</YS>
<YO>0</YO>
</UDim2>
<UDim2 name="Size">
<XS>1</XS>
<XO>0</XO>
<YS>1</YS>
<YO>0</YO>
</UDim2>
<token name="SizeConstraint">0</token>
<token name="Style">0</token>
<bool name="Visible">true</bool>
<int name="ZIndex">1</int>
</Properties>
<Item class="Frame" referent="RBX26">
<Properties>
<bool name="Active">false</bool>
<Color3 name="BackgroundColor3">4288914085</Color3>
<float name="BackgroundTransparency">1</float>
<Color3 name="BorderColor3">4279970357</Color3>
<int name="BorderSizePixel">1</int>
<bool name="ClipsDescendants">false</bool>
<bool name="Draggable">false</bool>
<string name="Name">BottomLeftControl</string>
<UDim2 name="Position">
<XS>0</XS>
<XO>0</XO>
<YS>1</YS>
<YO>-46</YO>
</UDim2>
<UDim2 name="Size">
<XS>0</XS>
<XO>130</XO>
<YS>0</YS>
<YO>46</YO>
</UDim2>
<token name="SizeConstraint">0</token>
<token name="Style">0</token>
<bool name="Visible">true</bool>
<int name="ZIndex">1</int>
</Properties>
<Item class="ImageButton" referent="RBX27">
<Properties>
<bool name="Active">true</bool>
<bool name="AutoButtonColor">true</bool>
<Color3 name="BackgroundColor3">4288914085</Color3>
<float name="BackgroundTransparency">1</float>
<Color3 name="BorderColor3">4279970357</Color3>
<int name="BorderSizePixel">1</int>
<bool name="ClipsDescendants">false</bool>
<bool name="Draggable">false</bool>
<Content name="Image"><url>rbxasset://textures/Exit.png</url></Content>
<bool name="Modal">false</bool>
<string name="Name">Exit</string>
<UDim2 name="Position">
<XS>0</XS>
<XO>2</XO>
<YS>0</YS>
<YO>-2</YO>
</UDim2>
<bool name="Selected">false</bool>
<UDim2 name="Size">
<XS>0</XS>
<XO>56</XO>
<YS>0</YS>
<YO>41</YO>
</UDim2>
<token name="SizeConstraint">0</token>
<token name="Style">0</token>
<bool name="Visible">false</bool>
<int name="ZIndex">1</int>
</Properties>
</Item>
</Item>
<Item class="Frame" referent="RBX28">
<Properties>
<bool name="Active">false</bool>
<Color3 name="BackgroundColor3">4288914085</Color3>
<float name="BackgroundTransparency">1</float>
<Color3 name="BorderColor3">4279970357</Color3>
<int name="BorderSizePixel">1</int>
<bool name="ClipsDescendants">false</bool>
<bool name="Draggable">false</bool>
<string name="Name">BottomRightControl</string>
<UDim2 name="Position">
<XS>1</XS>
<XO>-180</XO>
<YS>1</YS>
<YO>-41</YO>
</UDim2>
<UDim2 name="Size">
<XS>0</XS>
<XO>180</XO>
<YS>0</YS>
<YO>41</YO>
</UDim2>
<token name="SizeConstraint">0</token>
<token name="Style">0</token>
<bool name="Visible">true</bool>
<int name="ZIndex">1</int>
</Properties>
</Item>
<Item class="Frame" referent="RBX29">
<Properties>
<bool name="Active">false</bool>
<Color3 name="BackgroundColor3">4288914085</Color3>
<float name="BackgroundTransparency">1</float>
<Color3 name="BorderColor3">4279970357</Color3>
<int name="BorderSizePixel">1</int>
<bool name="ClipsDescendants">false</bool>
<bool name="Draggable">false</bool>
<string name="Name">TopLeftControl</string>
<UDim2 name="Position">
<XS>0</XS>
<XO>0</XO>
<YS>0</YS>
<YO>0</YO>
</UDim2>
<UDim2 name="Size">
<XS>0.0500000007</XS>
<XO>0</XO>
<YS>0.0500000007</YS>
<YO>0</YO>
</UDim2>
<token name="SizeConstraint">0</token>
<token name="Style">0</token>
<bool name="Visible">true</bool>
<int name="ZIndex">1</int>
</Properties>
</Item>
<Item class="NotificationBox" referent="RBX30">
<Properties>
<bool name="Active">false</bool>
<Color3 name="BackgroundColor3">4288914085</Color3>
<float name="BackgroundTransparency">1</float>
<Color3 name="BorderColor3">4279970357</Color3>
<int name="BorderSizePixel">1</int>
<bool name="ClipsDescendants">false</bool>
<bool name="Draggable">false</bool>
<string name="Name">NotificationBox</string>
<UDim2 name="Position">
<XS>1</XS>
<XO>-200</XO>
<YS>0.5</YS>
<YO>0</YO>
</UDim2>
<UDim2 name="Size">
<XS>0</XS>
<XO>200</XO>
<YS>0.419999987</YS>
<YO>0</YO>
</UDim2>
<token name="SizeConstraint">0</token>
<bool name="Visible">true</bool>
<int name="ZIndex">1</int>
</Properties>
</Item>
</Item>
<Item class="LocalScript" referent="RBX31">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">Workaround</string>
<ProtectedString name="Source">game.Players.LocalPlayer.PlayerGui.Menu.MenuScript.Disabled = true
game.Players.LocalPlayer.PlayerGui.Menu.MenuScript.Disabled = false</ProtectedString>
</Properties>
</Item>
<Item class="LocalScript" referent="RBX32">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">MenuScript</string>
<ProtectedString name="Source">-- 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)
&#9;local eventConnection = nil
&#9;--Connection on parentInstance is scoped by parentInstance (when destroyed, it goes away)
&#9;local tryConnect = function()
&#9;&#9;if game:IsAncestorOf(parentInstance) then
&#9;&#9;&#9;--Entering the world, make sure we are connected/synced
&#9;&#9;&#9;if not eventConnection then
&#9;&#9;&#9;&#9;eventConnection = instance[event]:connect(signalFunc)
&#9;&#9;&#9;&#9;if syncFunc then syncFunc() end
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;--Probably leaving the world, so disconnect for now
&#9;&#9;&#9;if eventConnection then
&#9;&#9;&#9;&#9;eventConnection:disconnect()
&#9;&#9;&#9;&#9;if removeFunc then removeFunc() end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;--Hook it up to ancestryChanged signal
&#9;local connection = parentInstance.AncestryChanged:connect(tryConnect)
&#9;
&#9;--Now connect us if we&apos;re already in the world
&#9;tryConnect()
&#9;
&#9;return connection
end
local function getScreenGuiAncestor(instance)
&#9;local localInstance = instance
&#9;while localInstance and not localInstance:IsA(&quot;ScreenGui&quot;) do
&#9;&#9;localInstance = localInstance.Parent
&#9;end
&#9;return localInstance
end
local function CreateButtons(frame, buttons, yPos, ySize)
&#9;local buttonNum = 1
&#9;local buttonObjs = {}
&#9;for i, obj in ipairs(buttons) do
&#9;&#9;local button = Instance.new(&quot;TextButton&quot;)
&#9;&#9;button.Name = &quot;Button&quot; .. buttonNum
&#9;&#9;button.Font = Enum.Font.Arial
&#9;&#9;button.FontSize = Enum.FontSize.Size18
&#9;&#9;button.AutoButtonColor = true
&#9;&#9;button.Modal = true
&#9;&#9;if obj[&quot;Style&quot;] then
&#9;&#9;&#9;button.Style = obj.Style
&#9;&#9;else
&#9;&#9;&#9;button.Style = Enum.ButtonStyle.RobloxButton
&#9;&#9;end
&#9;&#9;if obj[&quot;ZIndex&quot;] then
&#9;&#9;&#9;button.ZIndex = obj.ZIndex
&#9;&#9;end
&#9;&#9;button.Text = obj.Text
&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;button.MouseButton1Click:connect(obj.Function)
&#9;&#9;button.Parent = frame
&#9;&#9;buttonObjs[buttonNum] = button
&#9;&#9;buttonNum = buttonNum + 1
&#9;end
&#9;local numButtons = buttonNum-1
&#9;if numButtons == 1 then
&#9;&#9;frame.Button1.Position = UDim2.new(0.35, 0, yPos.Scale, yPos.Offset)
&#9;&#9;frame.Button1.Size = UDim2.new(.4,0,ySize.Scale, ySize.Offset)
&#9;elseif numButtons == 2 then
&#9;&#9;frame.Button1.Position = UDim2.new(0.1, 0, yPos.Scale, yPos.Offset)
&#9;&#9;frame.Button1.Size = UDim2.new(.8/3,0, ySize.Scale, ySize.Offset)
&#9;&#9;frame.Button2.Position = UDim2.new(0.55, 0, yPos.Scale, yPos.Offset)
&#9;&#9;frame.Button2.Size = UDim2.new(.35,0, ySize.Scale, ySize.Offset)
&#9;elseif numButtons &gt;= 3 then
&#9;&#9;local spacing = .1 / numButtons
&#9;&#9;local buttonSize = .9 / numButtons
&#9;&#9;buttonNum = 1
&#9;&#9;while buttonNum &lt;= numButtons do
&#9;&#9;&#9;buttonObjs[buttonNum].Position = UDim2.new(spacing*buttonNum + (buttonNum-1) * buttonSize, 0, yPos.Scale, yPos.Offset)
&#9;&#9;&#9;buttonObjs[buttonNum].Size = UDim2.new(buttonSize, 0, ySize.Scale, ySize.Offset)
&#9;&#9;&#9;buttonNum = buttonNum + 1
&#9;&#9;end
&#9;end
end
local function setSliderPos(newAbsPosX,slider,sliderPosition,bar,steps)
&#9;local steps = 10
&#9;local newStep = steps - 1 --otherwise we really get one more step than we want
&#9;local relativePosX = math.min(1, math.max(0, (newAbsPosX - bar.AbsolutePosition.X) / bar.AbsoluteSize.X ))
&#9;local wholeNum, remainder = math.modf(relativePosX * newStep)
&#9;if remainder &gt; 0.5 then
&#9;&#9;wholeNum = wholeNum + 1
&#9;end
&#9;relativePosX = wholeNum/newStep
&#9;local result = math.ceil(relativePosX * newStep)
&#9;if sliderPosition.Value ~= (result + 1) then --only update if we moved a step
&#9;&#9;sliderPosition.Value = result + 1
&#9;&#9;slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
&#9;end
&#9;
end
local function cancelSlide(areaSoak)
&#9;areaSoak.Visible = false
&#9;if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
end
t.CreateStyledMessageDialog = function(title, message, style, buttons)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Size = UDim2.new(0.5, 0, 0, 165)
&#9;frame.Position = UDim2.new(0.25, 0, 0.5, -72.5)
&#9;frame.Name = &quot;MessageDialog&quot;
&#9;frame.Active = true
&#9;frame.Style = Enum.FrameStyle.RobloxRound&#9;
&#9;
&#9;local styleImage = Instance.new(&quot;ImageLabel&quot;)
&#9;styleImage.Name = &quot;StyleImage&quot;
&#9;styleImage.BackgroundTransparency = 1
&#9;styleImage.Position = UDim2.new(0,5,0,15)
&#9;if style == &quot;error&quot; or style == &quot;Error&quot; then
&#9;&#9;styleImage.Size = UDim2.new(0, 71, 0, 71)
&#9;&#9;styleImage.Image = &quot;http://www.roblox.com/asset/?id=42565285&quot;
&#9;elseif style == &quot;notify&quot; or style == &quot;Notify&quot; then
&#9;&#9;styleImage.Size = UDim2.new(0, 71, 0, 71)
&#9;&#9;styleImage.Image = &quot;http://www.roblox.com/asset/?id=42604978&quot;
&#9;elseif style == &quot;confirm&quot; or style == &quot;Confirm&quot; then
&#9;&#9;styleImage.Size = UDim2.new(0, 74, 0, 76)
&#9;&#9;styleImage.Image = &quot;http://www.roblox.com/asset/?id=42557901&quot;
&#9;else
&#9;&#9;return t.CreateMessageDialog(title,message,buttons)
&#9;end
&#9;styleImage.Parent = frame
&#9;
&#9;local titleLabel = Instance.new(&quot;TextLabel&quot;)
&#9;titleLabel.Name = &quot;Title&quot;
&#9;titleLabel.Text = title
&#9;titleLabel.TextStrokeTransparency = 0
&#9;titleLabel.BackgroundTransparency = 1
&#9;titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
&#9;titleLabel.Position = UDim2.new(0, 80, 0, 0)
&#9;titleLabel.Size = UDim2.new(1, -80, 0, 40)
&#9;titleLabel.Font = Enum.Font.ArialBold
&#9;titleLabel.FontSize = Enum.FontSize.Size36
&#9;titleLabel.TextXAlignment = Enum.TextXAlignment.Center
&#9;titleLabel.TextYAlignment = Enum.TextYAlignment.Center
&#9;titleLabel.Parent = frame
&#9;local messageLabel = Instance.new(&quot;TextLabel&quot;)
&#9;messageLabel.Name = &quot;Message&quot;
&#9;messageLabel.Text = message
&#9;messageLabel.TextStrokeTransparency = 0
&#9;messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
&#9;messageLabel.Position = UDim2.new(0.025, 80, 0, 45)
&#9;messageLabel.Size = UDim2.new(0.95, -80, 0, 55)
&#9;messageLabel.BackgroundTransparency = 1
&#9;messageLabel.Font = Enum.Font.Arial
&#9;messageLabel.FontSize = Enum.FontSize.Size18
&#9;messageLabel.TextWrap = true
&#9;messageLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;messageLabel.TextYAlignment = Enum.TextYAlignment.Top
&#9;messageLabel.Parent = frame
&#9;CreateButtons(frame, buttons, UDim.new(0, 105), UDim.new(0, 40) )
&#9;return frame
end
t.CreateMessageDialog = function(title, message, buttons)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Size = UDim2.new(0.5, 0, 0.5, 0)
&#9;frame.Position = UDim2.new(0.25, 0, 0.25, 0)
&#9;frame.Name = &quot;MessageDialog&quot;
&#9;frame.Active = true
&#9;frame.Style = Enum.FrameStyle.RobloxRound
&#9;local titleLabel = Instance.new(&quot;TextLabel&quot;)
&#9;titleLabel.Name = &quot;Title&quot;
&#9;titleLabel.Text = title
&#9;titleLabel.BackgroundTransparency = 1
&#9;titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
&#9;titleLabel.Position = UDim2.new(0, 0, 0, 0)
&#9;titleLabel.Size = UDim2.new(1, 0, 0.15, 0)
&#9;titleLabel.Font = Enum.Font.ArialBold
&#9;titleLabel.FontSize = Enum.FontSize.Size36
&#9;titleLabel.TextXAlignment = Enum.TextXAlignment.Center
&#9;titleLabel.TextYAlignment = Enum.TextYAlignment.Center
&#9;titleLabel.Parent = frame
&#9;local messageLabel = Instance.new(&quot;TextLabel&quot;)
&#9;messageLabel.Name = &quot;Message&quot;
&#9;messageLabel.Text = message
&#9;messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
&#9;messageLabel.Position = UDim2.new(0.025, 0, 0.175, 0)
&#9;messageLabel.Size = UDim2.new(0.95, 0, .55, 0)
&#9;messageLabel.BackgroundTransparency = 1
&#9;messageLabel.Font = Enum.Font.Arial
&#9;messageLabel.FontSize = Enum.FontSize.Size18
&#9;messageLabel.TextWrap = true
&#9;messageLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;messageLabel.TextYAlignment = Enum.TextYAlignment.Top
&#9;messageLabel.Parent = frame
&#9;CreateButtons(frame, buttons, UDim.new(0.8,0), UDim.new(0.15, 0))
&#9;return frame
end
t.CreateDropDownMenu = function(items, onSelect, forRoblox, whiteSkin, baseZ)
&#9;local baseZIndex = 0
&#9;if (type(baseZ) == &quot;number&quot;) then
&#9;&#9;baseZIndex = baseZ
&#9;end
&#9;local width = UDim.new(0, 100)
&#9;local height = UDim.new(0, 32)
&#9;local xPos = 0.055
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;local textColor = Color3.new(1,1,1)
&#9;if (whiteSkin) then
&#9;&#9;textColor = Color3.new(0.5, 0.5, 0.5)
&#9;end
&#9;frame.Name = &quot;DropDownMenu&quot;
&#9;frame.BackgroundTransparency = 1
&#9;frame.Size = UDim2.new(width, height)
&#9;local dropDownMenu = Instance.new(&quot;TextButton&quot;)
&#9;dropDownMenu.Name = &quot;DropDownMenuButton&quot;
&#9;dropDownMenu.TextWrap = true
&#9;dropDownMenu.TextColor3 = textColor
&#9;dropDownMenu.Text = &quot;Choose One&quot;
&#9;dropDownMenu.Font = Enum.Font.ArialBold
&#9;dropDownMenu.FontSize = Enum.FontSize.Size18
&#9;dropDownMenu.TextXAlignment = Enum.TextXAlignment.Left
&#9;dropDownMenu.TextYAlignment = Enum.TextYAlignment.Center
&#9;dropDownMenu.BackgroundTransparency = 1
&#9;dropDownMenu.AutoButtonColor = true
&#9;if (whiteSkin) then
&#9;&#9;dropDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton
&#9;else
&#9;&#9;dropDownMenu.Style = Enum.ButtonStyle.RobloxButton
&#9;end
&#9;dropDownMenu.Size = UDim2.new(1,0,1,0)
&#9;dropDownMenu.Parent = frame
&#9;dropDownMenu.ZIndex = 2 + baseZIndex
&#9;local dropDownIcon = Instance.new(&quot;ImageLabel&quot;)
&#9;dropDownIcon.Name = &quot;Icon&quot;
&#9;dropDownIcon.Active = false
&#9;if (whiteSkin) then
&#9;&#9;dropDownIcon.Image = &quot;rbxasset://textures/ui/dropdown_arrow.png&quot;
&#9;&#9;dropDownIcon.Size = UDim2.new(0,16,0,12)
&#9;&#9;dropDownIcon.Position = UDim2.new(1,-17,0.5, -6)
&#9;else
&#9;&#9;dropDownIcon.Image = &quot;http://www.roblox.com/asset/?id=45732894&quot;
&#9;&#9;dropDownIcon.Size = UDim2.new(0,11,0,6)
&#9;&#9;dropDownIcon.Position = UDim2.new(1,-11,0.5, -2)
&#9;end
&#9;dropDownIcon.BackgroundTransparency = 1
&#9;dropDownIcon.Parent = dropDownMenu
&#9;dropDownIcon.ZIndex = 2 + baseZIndex
&#9;
&#9;local itemCount = #items
&#9;local dropDownItemCount = #items
&#9;local useScrollButtons = false
&#9;if dropDownItemCount &gt; 6 then
&#9;&#9;useScrollButtons = true
&#9;&#9;dropDownItemCount = 6
&#9;end
&#9;
&#9;local droppedDownMenu = Instance.new(&quot;TextButton&quot;)
&#9;droppedDownMenu.Name = &quot;List&quot;
&#9;droppedDownMenu.Text = &quot;&quot;
&#9;droppedDownMenu.BackgroundTransparency = 1
&#9;--droppedDownMenu.AutoButtonColor = true
&#9;if (whiteSkin) then
&#9;&#9;droppedDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton
&#9;else
&#9;&#9;droppedDownMenu.Style = Enum.ButtonStyle.RobloxButton
&#9;end
&#9;droppedDownMenu.Visible = false
&#9;droppedDownMenu.Active = true&#9;--Blocks clicks
&#9;droppedDownMenu.Position = UDim2.new(0,0,0,0)
&#9;droppedDownMenu.Size = UDim2.new(1,0, (1 + dropDownItemCount)*.8, 0)
&#9;droppedDownMenu.Parent = frame
&#9;droppedDownMenu.ZIndex = 2 + baseZIndex
&#9;local choiceButton = Instance.new(&quot;TextButton&quot;)
&#9;choiceButton.Name = &quot;ChoiceButton&quot;
&#9;choiceButton.BackgroundTransparency = 1
&#9;choiceButton.BorderSizePixel = 0
&#9;choiceButton.Text = &quot;ReplaceMe&quot;
&#9;choiceButton.TextColor3 = textColor
&#9;choiceButton.TextXAlignment = Enum.TextXAlignment.Left
&#9;choiceButton.TextYAlignment = Enum.TextYAlignment.Center
&#9;choiceButton.BackgroundColor3 = Color3.new(1, 1, 1)
&#9;choiceButton.Font = Enum.Font.Arial
&#9;choiceButton.FontSize = Enum.FontSize.Size18
&#9;if useScrollButtons then
&#9;&#9;choiceButton.Size = UDim2.new(1,-13, .8/((dropDownItemCount + 1)*.8),0)
&#9;else
&#9;&#9;choiceButton.Size = UDim2.new(1, 0, .8/((dropDownItemCount + 1)*.8),0)
&#9;end
&#9;choiceButton.TextWrap = true
&#9;choiceButton.ZIndex = 2 + baseZIndex
&#9;local areaSoak = Instance.new(&quot;TextButton&quot;)
&#9;areaSoak.Name = &quot;AreaSoak&quot;
&#9;areaSoak.Text = &quot;&quot;
&#9;areaSoak.BackgroundTransparency = 1
&#9;areaSoak.Active = true
&#9;areaSoak.Size = UDim2.new(1,0,1,0)
&#9;areaSoak.Visible = false
&#9;areaSoak.ZIndex = 3 + baseZIndex
&#9;local dropDownSelected = false
&#9;local scrollUpButton
&#9;local scrollDownButton
&#9;local scrollMouseCount = 0
&#9;local setZIndex = function(baseZIndex)
&#9;&#9;droppedDownMenu.ZIndex = baseZIndex +1
&#9;&#9;if scrollUpButton then
&#9;&#9;&#9;scrollUpButton.ZIndex = baseZIndex + 3
&#9;&#9;end
&#9;&#9;if scrollDownButton then
&#9;&#9;&#9;scrollDownButton.ZIndex = baseZIndex + 3
&#9;&#9;end
&#9;&#9;
&#9;&#9;local children = droppedDownMenu:GetChildren()
&#9;&#9;if children then
&#9;&#9;&#9;for i, child in ipairs(children) do
&#9;&#9;&#9;&#9;if child.Name == &quot;ChoiceButton&quot; then
&#9;&#9;&#9;&#9;&#9;child.ZIndex = baseZIndex + 2
&#9;&#9;&#9;&#9;elseif child.Name == &quot;ClickCaptureButton&quot; then
&#9;&#9;&#9;&#9;&#9;child.ZIndex = baseZIndex
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local scrollBarPosition = 1
&#9;local updateScroll = function()
&#9;&#9;if scrollUpButton then
&#9;&#9;&#9;scrollUpButton.Active = scrollBarPosition &gt; 1
&#9;&#9;end
&#9;&#9;if scrollDownButton then
&#9;&#9;&#9;scrollDownButton.Active = scrollBarPosition + dropDownItemCount &lt;= itemCount
&#9;&#9;end
&#9;&#9;local children = droppedDownMenu:GetChildren()
&#9;&#9;if not children then return end
&#9;&#9;local childNum = 1&#9;&#9;&#9;
&#9;&#9;for i, obj in ipairs(children) do
&#9;&#9;&#9;if obj.Name == &quot;ChoiceButton&quot; then
&#9;&#9;&#9;&#9;if childNum &lt; scrollBarPosition or childNum &gt;= scrollBarPosition + dropDownItemCount then
&#9;&#9;&#9;&#9;&#9;obj.Visible = false
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;obj.Position = UDim2.new(0,0,((childNum-scrollBarPosition+1)*.8)/((dropDownItemCount+1)*.8),0)
&#9;&#9;&#9;&#9;&#9;obj.Visible = true
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;obj.TextColor3 = textColor
&#9;&#9;&#9;&#9;obj.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;childNum = childNum + 1
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local toggleVisibility = function()
&#9;&#9;dropDownSelected = not dropDownSelected
&#9;&#9;areaSoak.Visible = not areaSoak.Visible
&#9;&#9;dropDownMenu.Visible = not dropDownSelected
&#9;&#9;droppedDownMenu.Visible = dropDownSelected
&#9;&#9;if dropDownSelected then
&#9;&#9;&#9;setZIndex(4 + baseZIndex)
&#9;&#9;else
&#9;&#9;&#9;setZIndex(2 + baseZIndex)
&#9;&#9;end
&#9;&#9;if useScrollButtons then
&#9;&#9;&#9;updateScroll()
&#9;&#9;end
&#9;end
&#9;droppedDownMenu.MouseButton1Click:connect(toggleVisibility)
&#9;local updateSelection = function(text)
&#9;&#9;local foundItem = false
&#9;&#9;local children = droppedDownMenu:GetChildren()
&#9;&#9;local childNum = 1
&#9;&#9;if children then
&#9;&#9;&#9;for i, obj in ipairs(children) do
&#9;&#9;&#9;&#9;if obj.Name == &quot;ChoiceButton&quot; then
&#9;&#9;&#9;&#9;&#9;if obj.Text == text then
&#9;&#9;&#9;&#9;&#9;&#9;obj.Font = Enum.Font.ArialBold
&#9;&#9;&#9;&#9;&#9;&#9;foundItem = true&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;scrollBarPosition = childNum&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;if (whiteSkin) then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;obj.TextColor3 = Color3.new(90/255,142/255,233/255)
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;obj.Font = Enum.Font.Arial
&#9;&#9;&#9;&#9;&#9;&#9;if (whiteSkin) then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;obj.TextColor3 = textColor
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;childNum = childNum + 1
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;if not text then
&#9;&#9;&#9;dropDownMenu.Text = &quot;Choose One&quot;
&#9;&#9;&#9;scrollBarPosition = 1
&#9;&#9;else
&#9;&#9;&#9;if not foundItem then
&#9;&#9;&#9;&#9;error(&quot;Invalid Selection Update -- &quot; .. text)
&#9;&#9;&#9;end
&#9;&#9;&#9;if scrollBarPosition + dropDownItemCount &gt; itemCount + 1 then
&#9;&#9;&#9;&#9;scrollBarPosition = itemCount - dropDownItemCount + 1
&#9;&#9;&#9;end
&#9;&#9;&#9;dropDownMenu.Text = text
&#9;&#9;end
&#9;end
&#9;
&#9;local function scrollDown()
&#9;&#9;if scrollBarPosition + dropDownItemCount &lt;= itemCount then
&#9;&#9;&#9;scrollBarPosition = scrollBarPosition + 1
&#9;&#9;&#9;updateScroll()
&#9;&#9;&#9;return true
&#9;&#9;end
&#9;&#9;return false
&#9;end
&#9;local function scrollUp()
&#9;&#9;if scrollBarPosition &gt; 1 then
&#9;&#9;&#9;scrollBarPosition = scrollBarPosition - 1
&#9;&#9;&#9;updateScroll()
&#9;&#9;&#9;return true
&#9;&#9;end
&#9;&#9;return false
&#9;end
&#9;
&#9;if useScrollButtons then
&#9;&#9;--Make some scroll buttons
&#9;&#9;scrollUpButton = Instance.new(&quot;ImageButton&quot;)
&#9;&#9;scrollUpButton.Name = &quot;ScrollUpButton&quot;
&#9;&#9;scrollUpButton.BackgroundTransparency = 1
&#9;&#9;scrollUpButton.Image = &quot;rbxasset://textures/ui/scrollbuttonUp.png&quot;
&#9;&#9;scrollUpButton.Size = UDim2.new(0,17,0,17)
&#9;&#9;scrollUpButton.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),0)
&#9;&#9;scrollUpButton.MouseButton1Click:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;&#9;&#9;end)
&#9;&#9;scrollUpButton.MouseLeave:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;&#9;&#9;end)
&#9;&#9;scrollUpButton.MouseButton1Down:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;
&#9;&#9;&#9;&#9;scrollUp()
&#9;&#9;&#9;&#9;local val = scrollMouseCount
&#9;&#9;&#9;&#9;wait(0.5)
&#9;&#9;&#9;&#9;while val == scrollMouseCount do
&#9;&#9;&#9;&#9;&#9;if scrollUp() == false then
&#9;&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;wait(0.1)
&#9;&#9;&#9;&#9;end&#9;&#9;&#9;&#9;
&#9;&#9;&#9;end)
&#9;&#9;scrollUpButton.Parent = droppedDownMenu
&#9;&#9;scrollDownButton = Instance.new(&quot;ImageButton&quot;)
&#9;&#9;scrollDownButton.Name = &quot;ScrollDownButton&quot;
&#9;&#9;scrollDownButton.BackgroundTransparency = 1
&#9;&#9;scrollDownButton.Image = &quot;rbxasset://textures/ui/scrollbuttonDown.png&quot;
&#9;&#9;scrollDownButton.Size = UDim2.new(0,17,0,17)
&#9;&#9;scrollDownButton.Position = UDim2.new(1,-11,1,-11)
&#9;&#9;scrollDownButton.Parent = droppedDownMenu
&#9;&#9;scrollDownButton.MouseButton1Click:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;&#9;&#9;end)
&#9;&#9;scrollDownButton.MouseLeave:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;&#9;&#9;end)
&#9;&#9;scrollDownButton.MouseButton1Down:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;&#9;&#9;&#9;scrollDown()
&#9;&#9;&#9;&#9;local val = scrollMouseCount
&#9;&#9;&#9;&#9;wait(0.5)
&#9;&#9;&#9;&#9;while val == scrollMouseCount do
&#9;&#9;&#9;&#9;&#9;if scrollDown() == false then
&#9;&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;wait(0.1)
&#9;&#9;&#9;&#9;end&#9;&#9;&#9;&#9;
&#9;&#9;&#9;end)&#9;
&#9;&#9;local scrollbar = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;scrollbar.Name = &quot;ScrollBar&quot;
&#9;&#9;scrollbar.Image = &quot;rbxasset://textures/ui/scrollbar.png&quot;
&#9;&#9;scrollbar.BackgroundTransparency = 1
&#9;&#9;scrollbar.Size = UDim2.new(0, 18, (dropDownItemCount*.8)/((dropDownItemCount+1)*.8), -(17) - 11 - 4)
&#9;&#9;scrollbar.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),17+2)
&#9;&#9;scrollbar.Parent = droppedDownMenu
&#9;end
&#9;for i,item in ipairs(items) do
&#9;&#9;-- needed to maintain local scope for items in event listeners below
&#9;&#9;local button = choiceButton:clone()
&#9;&#9;if forRoblox then
&#9;&#9;end&#9;&#9;
&#9;&#9;button.Text = item
&#9;&#9;button.Parent = droppedDownMenu
&#9;&#9;if (whiteSkin) then
&#9;&#9;&#9;button.TextColor3 = textColor
&#9;&#9;end
&#9;&#9;button.MouseButton1Click:connect(function()
&#9;&#9;&#9;--Remove Highlight
&#9;&#9;&#9;if (not whiteSkin) then
&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;end
&#9;&#9;&#9;button.BackgroundTransparency = 1
&#9;&#9;&#9;updateSelection(item)
&#9;&#9;&#9;onSelect(item)
&#9;&#9;&#9;toggleVisibility()
&#9;&#9;end)
&#9;&#9;button.MouseEnter:connect(function()
&#9;&#9;&#9;--Add Highlight&#9;
&#9;&#9;&#9;if (not whiteSkin) then
&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(0,0,0)
&#9;&#9;&#9;end
&#9;&#9;&#9;button.BackgroundTransparency = 0
&#9;&#9;end)
&#9;&#9;button.MouseLeave:connect(function()
&#9;&#9;&#9;--Remove Highlight
&#9;&#9;&#9;if (not whiteSkin) then
&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;end
&#9;&#9;&#9;button.BackgroundTransparency = 1
&#9;&#9;end)
&#9;end
&#9;--This does the initial layout of the buttons&#9;
&#9;updateScroll()
&#9;
&#9;frame.AncestryChanged:connect(function(child,parent)
&#9;&#9;if parent == nil then
&#9;&#9;&#9;areaSoak.Parent = nil
&#9;&#9;else
&#9;&#9;&#9;areaSoak.Parent = getScreenGuiAncestor(frame)
&#9;&#9;end
&#9;end)
&#9;dropDownMenu.MouseButton1Click:connect(toggleVisibility)
&#9;areaSoak.MouseButton1Click:connect(toggleVisibility)
&#9;return frame, updateSelection
end
t.CreatePropertyDropDownMenu = function(instance, property, enum)
&#9;local items = enum:GetEnumItems()
&#9;local names = {}
&#9;local nameToItem = {}
&#9;for i,obj in ipairs(items) do
&#9;&#9;names[i] = obj.Name
&#9;&#9;nameToItem[obj.Name] = obj
&#9;end
&#9;local frame
&#9;local updateSelection
&#9;frame, updateSelection = t.CreateDropDownMenu(names, function(text) instance[property] = nameToItem[text] end)
&#9;ScopedConnect(frame, instance, &quot;Changed&quot;,
&#9;&#9;function(prop)
&#9;&#9;&#9;if prop == property then
&#9;&#9;&#9;&#9;updateSelection(instance[property].Name)
&#9;&#9;&#9;end
&#9;&#9;end,
&#9;&#9;function()
&#9;&#9;&#9;updateSelection(instance[property].Name)
&#9;&#9;end)
&#9;return frame
end
t.GetFontHeight = function(font, fontSize)
&#9;if font == nil or fontSize == nil then
&#9;&#9;error(&quot;Font and FontSize must be non-nil&quot;)
&#9;end
&#9;if font == Enum.Font.Legacy then
&#9;&#9;if fontSize == Enum.FontSize.Size8 then
&#9;&#9;&#9;return 12
&#9;&#9;elseif fontSize == Enum.FontSize.Size9 then
&#9;&#9;&#9;return 14
&#9;&#9;elseif fontSize == Enum.FontSize.Size10 then
&#9;&#9;&#9;return 15
&#9;&#9;elseif fontSize == Enum.FontSize.Size11 then
&#9;&#9;&#9;return 17
&#9;&#9;elseif fontSize == Enum.FontSize.Size12 then
&#9;&#9;&#9;return 18
&#9;&#9;elseif fontSize == Enum.FontSize.Size14 then
&#9;&#9;&#9;return 21
&#9;&#9;elseif fontSize == Enum.FontSize.Size18 then
&#9;&#9;&#9;return 27
&#9;&#9;elseif fontSize == Enum.FontSize.Size24 then
&#9;&#9;&#9;return 36
&#9;&#9;elseif fontSize == Enum.FontSize.Size36 then
&#9;&#9;&#9;return 54
&#9;&#9;elseif fontSize == Enum.FontSize.Size48 then
&#9;&#9;&#9;return 72
&#9;&#9;else
&#9;&#9;&#9;error(&quot;Unknown FontSize&quot;)
&#9;&#9;end
&#9;elseif font == Enum.Font.Arial or font == Enum.Font.ArialBold then
&#9;&#9;if fontSize == Enum.FontSize.Size8 then
&#9;&#9;&#9;return 8
&#9;&#9;elseif fontSize == Enum.FontSize.Size9 then
&#9;&#9;&#9;return 9
&#9;&#9;elseif fontSize == Enum.FontSize.Size10 then
&#9;&#9;&#9;return 10
&#9;&#9;elseif fontSize == Enum.FontSize.Size11 then
&#9;&#9;&#9;return 11
&#9;&#9;elseif fontSize == Enum.FontSize.Size12 then
&#9;&#9;&#9;return 12
&#9;&#9;elseif fontSize == Enum.FontSize.Size14 then
&#9;&#9;&#9;return 14
&#9;&#9;elseif fontSize == Enum.FontSize.Size18 then
&#9;&#9;&#9;return 18
&#9;&#9;elseif fontSize == Enum.FontSize.Size24 then
&#9;&#9;&#9;return 24
&#9;&#9;elseif fontSize == Enum.FontSize.Size36 then
&#9;&#9;&#9;return 36
&#9;&#9;elseif fontSize == Enum.FontSize.Size48 then
&#9;&#9;&#9;return 48
&#9;&#9;else
&#9;&#9;&#9;error(&quot;Unknown FontSize&quot;)
&#9;&#9;end
&#9;else
&#9;&#9;error(&quot;Unknown Font &quot; .. font)
&#9;end
end
local function layoutGuiObjectsHelper(frame, guiObjects, settingsTable)
&#9;local totalPixels = frame.AbsoluteSize.Y
&#9;local pixelsRemaining = frame.AbsoluteSize.Y
&#9;for i, child in ipairs(guiObjects) do
&#9;&#9;if child:IsA(&quot;TextLabel&quot;) or child:IsA(&quot;TextButton&quot;) then
&#9;&#9;&#9;local isLabel = child:IsA(&quot;TextLabel&quot;)
&#9;&#9;&#9;if isLabel then
&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - settingsTable[&quot;TextLabelPositionPadY&quot;]
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - settingsTable[&quot;TextButtonPositionPadY&quot;]
&#9;&#9;&#9;end
&#9;&#9;&#9;child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
&#9;&#9;&#9;child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, pixelsRemaining)
&#9;&#9;&#9;if child.TextFits and child.TextBounds.Y &lt; pixelsRemaining then
&#9;&#9;&#9;&#9;child.Visible = true
&#9;&#9;&#9;&#9;if isLabel then
&#9;&#9;&#9;&#9;&#9;child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable[&quot;TextLabelSizePadY&quot;])
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable[&quot;TextButtonSizePadY&quot;])
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;while not child.TextFits do
&#9;&#9;&#9;&#9;&#9;child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.AbsoluteSize.Y + 1)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y&#9;&#9;
&#9;&#9;&#9;&#9;if isLabel then
&#9;&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - settingsTable[&quot;TextLabelPositionPadY&quot;]
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - settingsTable[&quot;TextButtonPositionPadY&quot;]
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;&#9;pixelsRemaining = -1
&#9;&#9;&#9;end&#9;&#9;&#9;
&#9;&#9;else
&#9;&#9;&#9;--GuiObject
&#9;&#9;&#9;child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
&#9;&#9;&#9;child.Visible = (pixelsRemaining &gt;= 0)
&#9;&#9;end
&#9;end
end
t.LayoutGuiObjects = function(frame, guiObjects, settingsTable)
&#9;if not frame:IsA(&quot;GuiObject&quot;) then
&#9;&#9;error(&quot;Frame must be a GuiObject&quot;)
&#9;end
&#9;for i, child in ipairs(guiObjects) do
&#9;&#9;if not child:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;error(&quot;All elements that are layed out must be of type GuiObject&quot;)
&#9;&#9;end
&#9;end
&#9;if not settingsTable then
&#9;&#9;settingsTable = {}
&#9;end
&#9;if not settingsTable[&quot;TextLabelSizePadY&quot;] then
&#9;&#9;settingsTable[&quot;TextLabelSizePadY&quot;] = 0
&#9;end
&#9;if not settingsTable[&quot;TextLabelPositionPadY&quot;] then
&#9;&#9;settingsTable[&quot;TextLabelPositionPadY&quot;] = 0
&#9;end
&#9;if not settingsTable[&quot;TextButtonSizePadY&quot;] then
&#9;&#9;settingsTable[&quot;TextButtonSizePadY&quot;] = 12
&#9;end
&#9;if not settingsTable[&quot;TextButtonPositionPadY&quot;] then
&#9;&#9;settingsTable[&quot;TextButtonPositionPadY&quot;] = 2
&#9;end
&#9;--Wrapper frame takes care of styled objects
&#9;local wrapperFrame = Instance.new(&quot;Frame&quot;)
&#9;wrapperFrame.Name = &quot;WrapperFrame&quot;
&#9;wrapperFrame.BackgroundTransparency = 1
&#9;wrapperFrame.Size = UDim2.new(1,0,1,0)
&#9;wrapperFrame.Parent = frame
&#9;for i, child in ipairs(guiObjects) do
&#9;&#9;child.Parent = wrapperFrame
&#9;end
&#9;local recalculate = function()
&#9;&#9;wait()
&#9;&#9;layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable)
&#9;end
&#9;
&#9;frame.Changed:connect(
&#9;&#9;function(prop)
&#9;&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;&#9;--Wait a heartbeat for it to sync in
&#9;&#9;&#9;&#9;recalculate(nil)
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;frame.AncestryChanged:connect(recalculate)
&#9;layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable)
end
t.CreateSlider = function(steps,width,position)
&#9;local sliderGui = Instance.new(&quot;Frame&quot;)
&#9;sliderGui.Size = UDim2.new(1,0,1,0)
&#9;sliderGui.BackgroundTransparency = 1
&#9;sliderGui.Name = &quot;SliderGui&quot;
&#9;
&#9;local sliderSteps = Instance.new(&quot;IntValue&quot;)
&#9;sliderSteps.Name = &quot;SliderSteps&quot;
&#9;sliderSteps.Value = steps
&#9;sliderSteps.Parent = sliderGui
&#9;
&#9;local areaSoak = Instance.new(&quot;TextButton&quot;)
&#9;areaSoak.Name = &quot;AreaSoak&quot;
&#9;areaSoak.Text = &quot;&quot;
&#9;areaSoak.BackgroundTransparency = 1
&#9;areaSoak.Active = false
&#9;areaSoak.Size = UDim2.new(1,0,1,0)
&#9;areaSoak.Visible = false
&#9;areaSoak.ZIndex = 4
&#9;
&#9;sliderGui.AncestryChanged:connect(function(child,parent)
&#9;&#9;if parent == nil then
&#9;&#9;&#9;areaSoak.Parent = nil
&#9;&#9;else
&#9;&#9;&#9;areaSoak.Parent = getScreenGuiAncestor(sliderGui)
&#9;&#9;end
&#9;end)
&#9;
&#9;local sliderPosition = Instance.new(&quot;IntValue&quot;)
&#9;sliderPosition.Name = &quot;SliderPosition&quot;
&#9;sliderPosition.Value = 0
&#9;sliderPosition.Parent = sliderGui
&#9;
&#9;local id = math.random(1,100)
&#9;
&#9;local bar = Instance.new(&quot;TextButton&quot;)
&#9;bar.Text = &quot;&quot;
&#9;bar.AutoButtonColor = false
&#9;bar.Name = &quot;Bar&quot;
&#9;bar.BackgroundColor3 = Color3.new(0,0,0)
&#9;if type(width) == &quot;number&quot; then
&#9;&#9;bar.Size = UDim2.new(0,width,0,5)
&#9;else
&#9;&#9;bar.Size = UDim2.new(0,200,0,5)
&#9;end
&#9;bar.BorderColor3 = Color3.new(95/255,95/255,95/255)
&#9;bar.ZIndex = 2
&#9;bar.Parent = sliderGui
&#9;
&#9;if position[&quot;X&quot;] and position[&quot;X&quot;][&quot;Scale&quot;] and position[&quot;X&quot;][&quot;Offset&quot;] and position[&quot;Y&quot;] and position[&quot;Y&quot;][&quot;Scale&quot;] and position[&quot;Y&quot;][&quot;Offset&quot;] then
&#9;&#9;bar.Position = position
&#9;end
&#9;
&#9;local slider = Instance.new(&quot;ImageButton&quot;)
&#9;slider.Name = &quot;Slider&quot;
&#9;slider.BackgroundTransparency = 1
&#9;slider.Image = &quot;rbxasset://textures/ui/Slider.png&quot;
&#9;slider.Position = UDim2.new(0,0,0.5,-10)
&#9;slider.Size = UDim2.new(0,20,0,20)
&#9;slider.ZIndex = 3
&#9;slider.Parent = bar
&#9;
&#9;local areaSoakMouseMoveCon = nil
&#9;
&#9;areaSoak.MouseLeave:connect(function()
&#9;&#9;if areaSoak.Visible then
&#9;&#9;&#9;cancelSlide(areaSoak)
&#9;&#9;end
&#9;end)
&#9;areaSoak.MouseButton1Up:connect(function()
&#9;&#9;if areaSoak.Visible then
&#9;&#9;&#9;cancelSlide(areaSoak)
&#9;&#9;end
&#9;end)
&#9;
&#9;slider.MouseButton1Down:connect(function()
&#9;&#9;areaSoak.Visible = true
&#9;&#9;if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
&#9;&#9;areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y)
&#9;&#9;&#9;setSliderPos(x,slider,sliderPosition,bar,10)
&#9;&#9;end)
&#9;end)
&#9;
&#9;slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end)
&#9;
&#9;sliderPosition.Changed:connect(function(prop)
&#9;&#9;sliderPosition.Value = math.min(10, math.max(1,sliderPosition.Value))
&#9;&#9;local relativePosX = (sliderPosition.Value - 1) / (10 - 1)
&#9;&#9;slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
&#9;end)
&#9;
&#9;bar.MouseButton1Down:connect(function(x,y)
&#9;&#9;setSliderPos(x,slider,sliderPosition,bar,steps)
&#9;end)
&#9;
&#9;return sliderGui, sliderPosition, sliderSteps
end
t.CreateSliderNew = function(steps,width,position)
&#9;local sliderGui = Instance.new(&quot;Frame&quot;)
&#9;sliderGui.Size = UDim2.new(1,0,1,0)
&#9;sliderGui.BackgroundTransparency = 1
&#9;sliderGui.Name = &quot;SliderGui&quot;
&#9;
&#9;local sliderSteps = Instance.new(&quot;IntValue&quot;)
&#9;sliderSteps.Name = &quot;SliderSteps&quot;
&#9;sliderSteps.Value = steps
&#9;sliderSteps.Parent = sliderGui
&#9;
&#9;local areaSoak = Instance.new(&quot;TextButton&quot;)
&#9;areaSoak.Name = &quot;AreaSoak&quot;
&#9;areaSoak.Text = &quot;&quot;
&#9;areaSoak.BackgroundTransparency = 1
&#9;areaSoak.Active = false
&#9;areaSoak.Size = UDim2.new(1,0,1,0)
&#9;areaSoak.Visible = false
&#9;areaSoak.ZIndex = 6
&#9;
&#9;sliderGui.AncestryChanged:connect(function(child,parent)
&#9;&#9;if parent == nil then
&#9;&#9;&#9;areaSoak.Parent = nil
&#9;&#9;else
&#9;&#9;&#9;areaSoak.Parent = getScreenGuiAncestor(sliderGui)
&#9;&#9;end
&#9;end)
&#9;
&#9;local sliderPosition = Instance.new(&quot;IntValue&quot;)
&#9;sliderPosition.Name = &quot;SliderPosition&quot;
&#9;sliderPosition.Value = 0
&#9;sliderPosition.Parent = sliderGui
&#9;
&#9;local id = math.random(1,100)
&#9;
&#9;local sliderBarImgHeight = 7
&#9;local sliderBarCapImgWidth = 4
&#9;local bar = Instance.new(&quot;ImageButton&quot;)
&#9;bar.BackgroundTransparency = 1
&#9;bar.Image = &quot;rbxasset://textures/ui/Slider-BKG-Center.png&quot;
&#9;bar.Name = &quot;Bar&quot;
&#9;local displayWidth = 200
&#9;if type(width) == &quot;number&quot; then
&#9;&#9;bar.Size = UDim2.new(0,width - (sliderBarCapImgWidth * 2),0,sliderBarImgHeight)
&#9;&#9;displayWidth = width - (sliderBarCapImgWidth * 2)
&#9;else
&#9;&#9;bar.Size = UDim2.new(0,200,0,sliderBarImgHeight)
&#9;end
&#9;bar.ZIndex = 3
&#9;bar.Parent = sliderGui&#9;
&#9;if position[&quot;X&quot;] and position[&quot;X&quot;][&quot;Scale&quot;] and position[&quot;X&quot;][&quot;Offset&quot;] and position[&quot;Y&quot;] and position[&quot;Y&quot;][&quot;Scale&quot;] and position[&quot;Y&quot;][&quot;Offset&quot;] then
&#9;&#9;bar.Position = position
&#9;end
&#9;local barLeft = bar:clone()
&#9;barLeft.Name = &quot;BarLeft&quot;
&#9;barLeft.Image = &quot;rbxasset://textures/ui/Slider-BKG-Left-Cap.png&quot;
&#9;barLeft.Size = UDim2.new(0, sliderBarCapImgWidth, 0, sliderBarImgHeight)
&#9;barLeft.Position = UDim2.new(position.X.Scale, position.X.Offset - sliderBarCapImgWidth, position.Y.Scale, position.Y.Offset)
&#9;barLeft.Parent = sliderGui&#9;
&#9;barLeft.ZIndex = 3
&#9;local barRight = barLeft:clone()
&#9;barRight.Name = &quot;BarRight&quot;
&#9;barRight.Image = &quot;rbxasset://textures/ui/Slider-BKG-Right-Cap.png&quot;
&#9;barRight.Position = UDim2.new(position.X.Scale, position.X.Offset + displayWidth, position.Y.Scale, position.Y.Offset)
&#9;barRight.Parent = sliderGui&#9;
&#9;local fillLeft = barLeft:clone()
&#9;fillLeft.Name = &quot;FillLeft&quot;
&#9;fillLeft.Image = &quot;rbxasset://textures/ui/Slider-Fill-Left-Cap.png&quot;
&#9;fillLeft.Parent = sliderGui&#9;
&#9;fillLeft.ZIndex = 4
&#9;local fill = fillLeft:clone()
&#9;fill.Name = &quot;Fill&quot;
&#9;fill.Image = &quot;rbxasset://textures/ui/Slider-Fill-Center.png&quot;
&#9;fill.Parent = bar&#9;
&#9;fill.ZIndex = 4
&#9;fill.Position = UDim2.new(0, 0, 0, 0)
&#9;fill.Size = UDim2.new(0.5, 0, 1, 0)
--&#9;bar.Visible = false
&#9;local slider = Instance.new(&quot;ImageButton&quot;)
&#9;slider.Name = &quot;Slider&quot;
&#9;slider.BackgroundTransparency = 1
&#9;slider.Image = &quot;rbxasset://textures/ui/slider_new_tab.png&quot;
&#9;slider.Position = UDim2.new(0,0,0.5,-14)
&#9;slider.Size = UDim2.new(0,28,0,28)
&#9;slider.ZIndex = 5
&#9;slider.Parent = bar
&#9;
&#9;local areaSoakMouseMoveCon = nil
&#9;
&#9;areaSoak.MouseLeave:connect(function()
&#9;&#9;if areaSoak.Visible then
&#9;&#9;&#9;cancelSlide(areaSoak)
&#9;&#9;end
&#9;end)
&#9;areaSoak.MouseButton1Up:connect(function()
&#9;&#9;if areaSoak.Visible then
&#9;&#9;&#9;cancelSlide(areaSoak)
&#9;&#9;end
&#9;end)
&#9;
&#9;slider.MouseButton1Down:connect(function()
&#9;&#9;areaSoak.Visible = true
&#9;&#9;if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
&#9;&#9;areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y)
&#9;&#9;&#9;setSliderPos(x,slider,sliderPosition,bar,steps)
&#9;&#9;end)
&#9;end)
&#9;
&#9;slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end)
&#9;
&#9;sliderPosition.Changed:connect(function(prop)
&#9;&#9;sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value))
&#9;&#9;local relativePosX = (sliderPosition.Value - 1) / (steps - 1)
&#9;&#9;slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
&#9;&#9;fill.Size = UDim2.new(relativePosX, 0, 1, 0)
&#9;end)
&#9;
&#9;bar.MouseButton1Down:connect(function(x,y)
&#9;&#9;setSliderPos(x,slider,sliderPosition,bar,steps)
&#9;end)
&#9;return sliderGui, sliderPosition, sliderSteps
end
t.CreateTrueScrollingFrame = function()
&#9;local lowY = nil
&#9;local highY = nil
&#9;
&#9;local dragCon = nil
&#9;local upCon = nil
&#9;local internalChange = false
&#9;local descendantsChangeConMap = {}
&#9;local scrollingFrame = Instance.new(&quot;Frame&quot;)
&#9;scrollingFrame.Name = &quot;ScrollingFrame&quot;
&#9;scrollingFrame.Active = true
&#9;scrollingFrame.Size = UDim2.new(1,0,1,0)
&#9;scrollingFrame.ClipsDescendants = true
&#9;local controlFrame = Instance.new(&quot;Frame&quot;)
&#9;controlFrame.Name = &quot;ControlFrame&quot;
&#9;controlFrame.BackgroundTransparency = 1
&#9;controlFrame.Size = UDim2.new(0,18,1,0)
&#9;controlFrame.Position = UDim2.new(1,-20,0,0)
&#9;controlFrame.Parent = scrollingFrame
&#9;
&#9;local scrollBottom = Instance.new(&quot;BoolValue&quot;)
&#9;scrollBottom.Value = false
&#9;scrollBottom.Name = &quot;ScrollBottom&quot;
&#9;scrollBottom.Parent = controlFrame
&#9;
&#9;local scrollUp = Instance.new(&quot;BoolValue&quot;)
&#9;scrollUp.Value = false
&#9;scrollUp.Name = &quot;scrollUp&quot;
&#9;scrollUp.Parent = controlFrame
&#9;local scrollUpButton = Instance.new(&quot;TextButton&quot;)
&#9;scrollUpButton.Name = &quot;ScrollUpButton&quot;
&#9;scrollUpButton.Text = &quot;&quot;
&#9;scrollUpButton.AutoButtonColor = false
&#9;scrollUpButton.BackgroundColor3 = Color3.new(0,0,0)
&#9;scrollUpButton.BorderColor3 = Color3.new(1,1,1)
&#9;scrollUpButton.BackgroundTransparency = 0.5
&#9;scrollUpButton.Size = UDim2.new(0,18,0,18)
&#9;scrollUpButton.ZIndex = 2
&#9;scrollUpButton.Parent = controlFrame
&#9;for i = 1, 6 do
&#9;&#9;local triFrame = Instance.new(&quot;Frame&quot;)
&#9;&#9;triFrame.BorderColor3 = Color3.new(1,1,1)
&#9;&#9;triFrame.Name = &quot;tri&quot; .. tostring(i)
&#9;&#9;triFrame.ZIndex = 3
&#9;&#9;triFrame.BackgroundTransparency = 0.5
&#9;&#9;triFrame.Size = UDim2.new(0,12 - ((i -1) * 2),0,0)
&#9;&#9;triFrame.Position = UDim2.new(0,3 + (i -1),0.5,2 - (i -1))
&#9;&#9;triFrame.Parent = scrollUpButton
&#9;end
&#9;scrollUpButton.MouseEnter:connect(function()
&#9;&#9;scrollUpButton.BackgroundTransparency = 0.1
&#9;&#9;local upChildren = scrollUpButton:GetChildren()
&#9;&#9;for i = 1, #upChildren do
&#9;&#9;&#9;upChildren[i].BackgroundTransparency = 0.1
&#9;&#9;end
&#9;end)
&#9;scrollUpButton.MouseLeave:connect(function()
&#9;&#9;scrollUpButton.BackgroundTransparency = 0.5
&#9;&#9;local upChildren = scrollUpButton:GetChildren()
&#9;&#9;for i = 1, #upChildren do
&#9;&#9;&#9;upChildren[i].BackgroundTransparency = 0.5
&#9;&#9;end
&#9;end)
&#9;local scrollDownButton = scrollUpButton:clone()
&#9;scrollDownButton.Name = &quot;ScrollDownButton&quot;
&#9;scrollDownButton.Position = UDim2.new(0,0,1,-18)
&#9;local downChildren = scrollDownButton:GetChildren()
&#9;for i = 1, #downChildren do
&#9;&#9;downChildren[i].Position = UDim2.new(0,3 + (i -1),0.5,-2 + (i - 1))
&#9;end
&#9;scrollDownButton.MouseEnter:connect(function()
&#9;&#9;scrollDownButton.BackgroundTransparency = 0.1
&#9;&#9;local downChildren = scrollDownButton:GetChildren()
&#9;&#9;for i = 1, #downChildren do
&#9;&#9;&#9;downChildren[i].BackgroundTransparency = 0.1
&#9;&#9;end
&#9;end)
&#9;scrollDownButton.MouseLeave:connect(function()
&#9;&#9;scrollDownButton.BackgroundTransparency = 0.5
&#9;&#9;local downChildren = scrollDownButton:GetChildren()
&#9;&#9;for i = 1, #downChildren do
&#9;&#9;&#9;downChildren[i].BackgroundTransparency = 0.5
&#9;&#9;end
&#9;end)
&#9;scrollDownButton.Parent = controlFrame
&#9;
&#9;local scrollTrack = Instance.new(&quot;Frame&quot;)
&#9;scrollTrack.Name = &quot;ScrollTrack&quot;
&#9;scrollTrack.BackgroundTransparency = 1
&#9;scrollTrack.Size = UDim2.new(0,18,1,-38)
&#9;scrollTrack.Position = UDim2.new(0,0,0,19)
&#9;scrollTrack.Parent = controlFrame
&#9;local scrollbar = Instance.new(&quot;TextButton&quot;)
&#9;scrollbar.BackgroundColor3 = Color3.new(0,0,0)
&#9;scrollbar.BorderColor3 = Color3.new(1,1,1)
&#9;scrollbar.BackgroundTransparency = 0.5
&#9;scrollbar.AutoButtonColor = false
&#9;scrollbar.Text = &quot;&quot;
&#9;scrollbar.Active = true
&#9;scrollbar.Name = &quot;ScrollBar&quot;
&#9;scrollbar.ZIndex = 2
&#9;scrollbar.BackgroundTransparency = 0.5
&#9;scrollbar.Size = UDim2.new(0, 18, 0.1, 0)
&#9;scrollbar.Position = UDim2.new(0,0,0,0)
&#9;scrollbar.Parent = scrollTrack
&#9;local scrollNub = Instance.new(&quot;Frame&quot;)
&#9;scrollNub.Name = &quot;ScrollNub&quot;
&#9;scrollNub.BorderColor3 = Color3.new(1,1,1)
&#9;scrollNub.Size = UDim2.new(0,10,0,0)
&#9;scrollNub.Position = UDim2.new(0.5,-5,0.5,0)
&#9;scrollNub.ZIndex = 2
&#9;scrollNub.BackgroundTransparency = 0.5
&#9;scrollNub.Parent = scrollbar
&#9;local newNub = scrollNub:clone()
&#9;newNub.Position = UDim2.new(0.5,-5,0.5,-2)
&#9;newNub.Parent = scrollbar
&#9;
&#9;local lastNub = scrollNub:clone()
&#9;lastNub.Position = UDim2.new(0.5,-5,0.5,2)
&#9;lastNub.Parent = scrollbar
&#9;scrollbar.MouseEnter:connect(function()
&#9;&#9;scrollbar.BackgroundTransparency = 0.1
&#9;&#9;scrollNub.BackgroundTransparency = 0.1
&#9;&#9;newNub.BackgroundTransparency = 0.1
&#9;&#9;lastNub.BackgroundTransparency = 0.1
&#9;end)
&#9;scrollbar.MouseLeave:connect(function()
&#9;&#9;scrollbar.BackgroundTransparency = 0.5
&#9;&#9;scrollNub.BackgroundTransparency = 0.5
&#9;&#9;newNub.BackgroundTransparency = 0.5
&#9;&#9;lastNub.BackgroundTransparency = 0.5
&#9;end)
&#9;local mouseDrag = Instance.new(&quot;ImageButton&quot;)
&#9;mouseDrag.Active = false
&#9;mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0)
&#9;mouseDrag.AutoButtonColor = false
&#9;mouseDrag.BackgroundTransparency = 1
&#9;mouseDrag.Name = &quot;mouseDrag&quot;
&#9;mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0)
&#9;mouseDrag.ZIndex = 10
&#9;
&#9;local function positionScrollBar(x,y,offset)
&#9;&#9;local oldPos = scrollbar.Position
&#9;&#9;if y &lt; scrollTrack.AbsolutePosition.y then
&#9;&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0)
&#9;&#9;&#9;return (oldPos ~= scrollbar.Position)
&#9;&#9;end
&#9;&#9;
&#9;&#9;local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y
&#9;&#9;if y &gt; (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then
&#9;&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0)
&#9;&#9;&#9;return (oldPos ~= scrollbar.Position)
&#9;&#9;end
&#9;&#9;local newScaleYPos = (y - scrollTrack.AbsolutePosition.y - offset)/scrollTrack.AbsoluteSize.y
&#9;&#9;if newScaleYPos + relativeSize &gt; 1 then
&#9;&#9;&#9;newScaleYPos = 1 - relativeSize
&#9;&#9;&#9;scrollBottom.Value = true
&#9;&#9;&#9;scrollUp.Value = false
&#9;&#9;elseif newScaleYPos &lt;= 0 then
&#9;&#9;&#9;newScaleYPos = 0
&#9;&#9;&#9;scrollUp.Value = true
&#9;&#9;&#9;scrollBottom.Value = false
&#9;&#9;else
&#9;&#9;&#9;scrollUp.Value = false
&#9;&#9;&#9;scrollBottom.Value = false
&#9;&#9;end
&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,newScaleYPos,0)
&#9;&#9;
&#9;&#9;return (oldPos ~= scrollbar.Position)
&#9;end
&#9;local function drillDownSetHighLow(instance)
&#9;&#9;if not instance or not instance:IsA(&quot;GuiObject&quot;) then return end
&#9;&#9;if instance == controlFrame then return end
&#9;&#9;if instance:IsDescendantOf(controlFrame) then return end
&#9;&#9;if not instance.Visible then return end
&#9;&#9;if lowY and lowY &gt; instance.AbsolutePosition.Y then
&#9;&#9;&#9;lowY = instance.AbsolutePosition.Y
&#9;&#9;elseif not lowY then
&#9;&#9;&#9;lowY = instance.AbsolutePosition.Y
&#9;&#9;end
&#9;&#9;if highY and highY &lt; (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) then
&#9;&#9;&#9;highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
&#9;&#9;elseif not highY then
&#9;&#9;&#9;highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
&#9;&#9;end
&#9;&#9;local children = instance:GetChildren()
&#9;&#9;for i = 1, #children do
&#9;&#9;&#9;drillDownSetHighLow(children[i])
&#9;&#9;end
&#9;end
&#9;local function resetHighLow()
&#9;&#9;local firstChildren = scrollingFrame:GetChildren()
&#9;&#9;for i = 1, #firstChildren do
&#9;&#9;&#9;drillDownSetHighLow(firstChildren[i])
&#9;&#9;end
&#9;end
&#9;local function recalculate()
&#9;&#9;internalChange = true
&#9;&#9;local percentFrame = 0
&#9;&#9;if scrollbar.Position.Y.Scale &gt; 0 then
&#9;&#9;&#9;if scrollbar.Visible then
&#9;&#9;&#9;&#9;percentFrame = scrollbar.Position.Y.Scale/((scrollTrack.AbsoluteSize.Y - scrollbar.AbsoluteSize.Y)/scrollTrack.AbsoluteSize.Y)
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;percentFrame = 0
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;if percentFrame &gt; 0.99 then percentFrame = 1 end
&#9;&#9;local hiddenYAmount = (scrollingFrame.AbsoluteSize.Y - (highY - lowY)) * percentFrame
&#9;&#9;
&#9;&#9;local guiChildren = scrollingFrame:GetChildren()
&#9;&#9;for i = 1, #guiChildren do
&#9;&#9;&#9;if guiChildren[i] ~= controlFrame then
&#9;&#9;&#9;&#9;guiChildren[i].Position = UDim2.new(guiChildren[i].Position.X.Scale,guiChildren[i].Position.X.Offset,
&#9;&#9;&#9;&#9;&#9;0, math.ceil(guiChildren[i].AbsolutePosition.Y) - math.ceil(lowY) + hiddenYAmount)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;lowY = nil
&#9;&#9;highY = nil
&#9;&#9;resetHighLow()
&#9;&#9;internalChange = false
&#9;end
&#9;local function setSliderSizeAndPosition()
&#9;&#9;if not highY or not lowY then return end
&#9;&#9;local totalYSpan = math.abs(highY - lowY)
&#9;&#9;if totalYSpan == 0 then
&#9;&#9;&#9;scrollbar.Visible = false
&#9;&#9;&#9;scrollDownButton.Visible = false
&#9;&#9;&#9;scrollUpButton.Visible = false
&#9;&#9;&#9;if dragCon then dragCon:disconnect() dragCon = nil end
&#9;&#9;&#9;if upCon then upCon:disconnect() upCon = nil end
&#9;&#9;&#9;return
&#9;&#9;end
&#9;&#9;local percentShown = scrollingFrame.AbsoluteSize.Y/totalYSpan
&#9;&#9;if percentShown &gt;= 1 then
&#9;&#9;&#9;scrollbar.Visible = false
&#9;&#9;&#9;scrollDownButton.Visible = false
&#9;&#9;&#9;scrollUpButton.Visible = false
&#9;&#9;&#9;recalculate()
&#9;&#9;else
&#9;&#9;&#9;scrollbar.Visible = true
&#9;&#9;&#9;scrollDownButton.Visible = true
&#9;&#9;&#9;scrollUpButton.Visible = true
&#9;&#9;&#9;scrollbar.Size = UDim2.new(scrollbar.Size.X.Scale,scrollbar.Size.X.Offset,percentShown,0)
&#9;&#9;end
&#9;&#9;local percentPosition = (scrollingFrame.AbsolutePosition.Y - lowY)/totalYSpan
&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,percentPosition,-scrollbar.AbsoluteSize.X/2)
&#9;&#9;if scrollbar.AbsolutePosition.y &lt; scrollTrack.AbsolutePosition.y then
&#9;&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0)
&#9;&#9;end
&#9;&#9;if (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.Y) &gt; (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then
&#9;&#9;&#9;local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y
&#9;&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0)
&#9;&#9;end
&#9;end
&#9;
&#9;local buttonScrollAmountPixels = 7
&#9;local reentrancyGuardScrollUp = false
&#9;local function doScrollUp()
&#9;&#9;if reentrancyGuardScrollUp then return end
&#9;&#9;
&#9;&#9;reentrancyGuardScrollUp = true
&#9;&#9;&#9;if positionScrollBar(0,scrollbar.AbsolutePosition.Y - buttonScrollAmountPixels,0) then
&#9;&#9;&#9;&#9;recalculate()
&#9;&#9;&#9;end
&#9;&#9;reentrancyGuardScrollUp = false
&#9;end
&#9;
&#9;local reentrancyGuardScrollDown = false
&#9;local function doScrollDown()
&#9;&#9;if reentrancyGuardScrollDown then return end
&#9;&#9;
&#9;&#9;reentrancyGuardScrollDown = true
&#9;&#9;&#9;if positionScrollBar(0,scrollbar.AbsolutePosition.Y + buttonScrollAmountPixels,0) then
&#9;&#9;&#9;&#9;recalculate()
&#9;&#9;&#9;end
&#9;&#9;reentrancyGuardScrollDown = false
&#9;end
&#9;local function scrollUp(mouseYPos)
&#9;&#9;if scrollUpButton.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local current = scrollStamp
&#9;&#9;&#9;local upCon
&#9;&#9;&#9;upCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;upCon:disconnect()
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;&#9;doScrollUp()
&#9;&#9;&#9;wait(0.2)
&#9;&#9;&#9;local t = tick()
&#9;&#9;&#9;local w = 0.1
&#9;&#9;&#9;while scrollStamp == current do
&#9;&#9;&#9;&#9;doScrollUp()
&#9;&#9;&#9;&#9;if mouseYPos and mouseYPos &gt; scrollbar.AbsolutePosition.y then
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if not scrollUpButton.Active then break end
&#9;&#9;&#9;&#9;if tick()-t &gt; 5 then
&#9;&#9;&#9;&#9;&#9;w = 0
&#9;&#9;&#9;&#9;elseif tick()-t &gt; 2 then
&#9;&#9;&#9;&#9;&#9;w = 0.06
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;wait(w)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local function scrollDown(mouseYPos)
&#9;&#9;if scrollDownButton.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local current = scrollStamp
&#9;&#9;&#9;local downCon
&#9;&#9;&#9;downCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;downCon:disconnect()
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;&#9;doScrollDown()
&#9;&#9;&#9;wait(0.2)
&#9;&#9;&#9;local t = tick()
&#9;&#9;&#9;local w = 0.1
&#9;&#9;&#9;while scrollStamp == current do
&#9;&#9;&#9;&#9;doScrollDown()
&#9;&#9;&#9;&#9;if mouseYPos and mouseYPos &lt; (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.x) then
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if not scrollDownButton.Active then break end
&#9;&#9;&#9;&#9;if tick()-t &gt; 5 then
&#9;&#9;&#9;&#9;&#9;w = 0
&#9;&#9;&#9;&#9;elseif tick()-t &gt; 2 then
&#9;&#9;&#9;&#9;&#9;w = 0.06
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;wait(w)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;
&#9;scrollbar.MouseButton1Down:connect(function(x,y)
&#9;&#9;if scrollbar.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local mouseOffset = y - scrollbar.AbsolutePosition.y
&#9;&#9;&#9;if dragCon then dragCon:disconnect() dragCon = nil end
&#9;&#9;&#9;if upCon then upCon:disconnect() upCon = nil end
&#9;&#9;&#9;local prevY = y
&#9;&#9;&#9;local reentrancyGuardMouseScroll = false
&#9;&#9;&#9;dragCon = mouseDrag.MouseMoved:connect(function(x,y)
&#9;&#9;&#9;&#9;if reentrancyGuardMouseScroll then return end
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;reentrancyGuardMouseScroll = true
&#9;&#9;&#9;&#9;&#9;if positionScrollBar(x,y,mouseOffset) then
&#9;&#9;&#9;&#9;&#9;&#9;recalculate()
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;reentrancyGuardMouseScroll = false
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;end)
&#9;&#9;&#9;upCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;dragCon:disconnect(); dragCon = nil
&#9;&#9;&#9;&#9;upCon:disconnect(); drag = nil
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;end
&#9;end)
&#9;local scrollMouseCount = 0
&#9;scrollUpButton.MouseButton1Down:connect(function()
&#9;&#9;scrollUp()
&#9;end)
&#9;scrollUpButton.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;scrollDownButton.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;scrollDownButton.MouseButton1Down:connect(function()
&#9;&#9; scrollDown()
&#9;end)
&#9;&#9;
&#9;scrollbar.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;
&#9;local function heightCheck(instance)
&#9;&#9;if highY and (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) &gt; highY then
&#9;&#9;&#9;highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
&#9;&#9;elseif not highY then
&#9;&#9;&#9;highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
&#9;&#9;end
&#9;&#9;setSliderSizeAndPosition()
&#9;end
&#9;
&#9;local function highLowRecheck()
&#9;&#9;local oldLowY = lowY
&#9;&#9;local oldHighY = highY
&#9;&#9;lowY = nil
&#9;&#9;highY = nil
&#9;&#9;resetHighLow()
&#9;&#9;if (lowY ~= oldLowY) or (highY ~= oldHighY) then
&#9;&#9;&#9;setSliderSizeAndPosition()
&#9;&#9;end
&#9;end
&#9;local function descendantChanged(this, prop)
&#9;&#9;if internalChange then return end
&#9;&#9;if not this.Visible then return end
&#9;&#9;if prop == &quot;Size&quot; or prop == &quot;Position&quot; then
&#9;&#9;&#9;wait()
&#9;&#9;&#9;highLowRecheck()
&#9;&#9;end
&#9;end
&#9;scrollingFrame.DescendantAdded:connect(function(instance)
&#9;&#9;if not instance:IsA(&quot;GuiObject&quot;) then return end
&#9;&#9;if instance.Visible then
&#9;&#9;&#9;wait() -- wait a heartbeat for sizes to reconfig
&#9;&#9;&#9;highLowRecheck()
&#9;&#9;end
&#9;&#9;descendantsChangeConMap[instance] = instance.Changed:connect(function(prop) descendantChanged(instance, prop) end)
&#9;end)
&#9;scrollingFrame.DescendantRemoving:connect(function(instance)
&#9;&#9;if not instance:IsA(&quot;GuiObject&quot;) then return end
&#9;&#9;if descendantsChangeConMap[instance] then
&#9;&#9;&#9;descendantsChangeConMap[instance]:disconnect()
&#9;&#9;&#9;descendantsChangeConMap[instance] = nil
&#9;&#9;end
&#9;&#9;wait() -- wait a heartbeat for sizes to reconfig
&#9;&#9;highLowRecheck()
&#9;end)
&#9;
&#9;scrollingFrame.Changed:connect(function(prop)
&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;if not highY or not lowY then return end
&#9;&#9;&#9;highLowRecheck()
&#9;&#9;&#9;setSliderSizeAndPosition()
&#9;&#9;end
&#9;end)
&#9;return scrollingFrame, controlFrame
end
t.CreateScrollingFrame = function(orderList,scrollStyle)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Name = &quot;ScrollingFrame&quot;
&#9;frame.BackgroundTransparency = 1
&#9;frame.Size = UDim2.new(1,0,1,0)
&#9;
&#9;local scrollUpButton = Instance.new(&quot;ImageButton&quot;)
&#9;scrollUpButton.Name = &quot;ScrollUpButton&quot;
&#9;scrollUpButton.BackgroundTransparency = 1
&#9;scrollUpButton.Image = &quot;rbxasset://textures/ui/scrollbuttonUp.png&quot;
&#9;scrollUpButton.Size = UDim2.new(0,17,0,17)
&#9;
&#9;local scrollDownButton = Instance.new(&quot;ImageButton&quot;)
&#9;scrollDownButton.Name = &quot;ScrollDownButton&quot;
&#9;scrollDownButton.BackgroundTransparency = 1
&#9;scrollDownButton.Image = &quot;rbxasset://textures/ui/scrollbuttonDown.png&quot;
&#9;scrollDownButton.Size = UDim2.new(0,17,0,17)
&#9;
&#9;local scrollbar = Instance.new(&quot;ImageButton&quot;)
&#9;scrollbar.Name = &quot;ScrollBar&quot;
&#9;scrollbar.Image = &quot;rbxasset://textures/ui/scrollbar.png&quot;
&#9;scrollbar.BackgroundTransparency = 1
&#9;scrollbar.Size = UDim2.new(0, 18, 0, 150)
&#9;local scrollStamp = 0
&#9;&#9;
&#9;local scrollDrag = Instance.new(&quot;ImageButton&quot;)
&#9;scrollDrag.Image = &quot;http://www.roblox.com/asset/?id=61367186&quot;
&#9;scrollDrag.Size = UDim2.new(1, 0, 0, 16)
&#9;scrollDrag.BackgroundTransparency = 1
&#9;scrollDrag.Name = &quot;ScrollDrag&quot;
&#9;scrollDrag.Active = true
&#9;scrollDrag.Parent = scrollbar
&#9;
&#9;local mouseDrag = Instance.new(&quot;ImageButton&quot;)
&#9;mouseDrag.Active = false
&#9;mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0)
&#9;mouseDrag.AutoButtonColor = false
&#9;mouseDrag.BackgroundTransparency = 1
&#9;mouseDrag.Name = &quot;mouseDrag&quot;
&#9;mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0)
&#9;mouseDrag.ZIndex = 10
&#9;local style = &quot;simple&quot;
&#9;if scrollStyle and tostring(scrollStyle) then
&#9;&#9;style = scrollStyle
&#9;end
&#9;
&#9;local scrollPosition = 1
&#9;local rowSize = 0
&#9;local howManyDisplayed = 0
&#9;&#9;
&#9;local layoutGridScrollBar = function()
&#9;&#9;howManyDisplayed = 0
&#9;&#9;local guiObjects = {}
&#9;&#9;if orderList then
&#9;&#9;&#9;for i, child in ipairs(orderList) do
&#9;&#9;&#9;&#9;if child.Parent == frame then
&#9;&#9;&#9;&#9;&#9;table.insert(guiObjects, child)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;local children = frame:GetChildren()
&#9;&#9;&#9;if children then
&#9;&#9;&#9;&#9;for i, child in ipairs(children) do
&#9;&#9;&#9;&#9;&#9;if child:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;&#9;&#9;table.insert(guiObjects, child)
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;if #guiObjects == 0 then
&#9;&#9;&#9;scrollUpButton.Active = false
&#9;&#9;&#9;scrollDownButton.Active = false
&#9;&#9;&#9;scrollDrag.Active = false
&#9;&#9;&#9;scrollPosition = 1
&#9;&#9;&#9;return
&#9;&#9;end
&#9;&#9;if scrollPosition &gt; #guiObjects then
&#9;&#9;&#9;scrollPosition = #guiObjects
&#9;&#9;end
&#9;&#9;
&#9;&#9;if scrollPosition &lt; 1 then scrollPosition = 1 end
&#9;&#9;
&#9;&#9;local totalPixelsY = frame.AbsoluteSize.Y
&#9;&#9;local pixelsRemainingY = frame.AbsoluteSize.Y
&#9;&#9;
&#9;&#9;local totalPixelsX = frame.AbsoluteSize.X
&#9;&#9;
&#9;&#9;local xCounter = 0
&#9;&#9;local rowSizeCounter = 0
&#9;&#9;local setRowSize = true
&#9;&#9;local pixelsBelowScrollbar = 0
&#9;&#9;local pos = #guiObjects
&#9;&#9;
&#9;&#9;local currentRowY = 0
&#9;&#9;pos = scrollPosition
&#9;&#9;--count up from current scroll position to fill out grid
&#9;&#9;while pos &lt;= #guiObjects and pixelsBelowScrollbar &lt; totalPixelsY do
&#9;&#9;&#9;xCounter = xCounter + guiObjects[pos].AbsoluteSize.X
&#9;&#9;&#9;--previous pos was the end of a row
&#9;&#9;&#9;if xCounter &gt;= totalPixelsX then
&#9;&#9;&#9;&#9;pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
&#9;&#9;&#9;&#9;currentRowY = 0
&#9;&#9;&#9;&#9;xCounter = guiObjects[pos].AbsoluteSize.X
&#9;&#9;&#9;end
&#9;&#9;&#9;if guiObjects[pos].AbsoluteSize.Y &gt; currentRowY then
&#9;&#9;&#9;&#9;currentRowY = guiObjects[pos].AbsoluteSize.Y
&#9;&#9;&#9;end
&#9;&#9;&#9;pos = pos + 1
&#9;&#9;end
&#9;&#9;--Count wherever current row left off
&#9;&#9;pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
&#9;&#9;currentRowY = 0
&#9;&#9;
&#9;&#9;pos = scrollPosition - 1
&#9;&#9;xCounter = 0
&#9;&#9;
&#9;&#9;--objects with varying X,Y dimensions can rarely cause minor errors
&#9;&#9;--rechecking every new scrollPosition is necessary to avoid 100% of errors
&#9;&#9;
&#9;&#9;--count backwards from current scrollPosition to see if we can add more rows
&#9;&#9;while pixelsBelowScrollbar + currentRowY &lt; totalPixelsY and pos &gt;= 1 do
&#9;&#9;&#9;xCounter = xCounter + guiObjects[pos].AbsoluteSize.X
&#9;&#9;&#9;rowSizeCounter = rowSizeCounter + 1
&#9;&#9;&#9;if xCounter &gt;= totalPixelsX then
&#9;&#9;&#9;&#9;rowSize = rowSizeCounter - 1
&#9;&#9;&#9;&#9;rowSizeCounter = 0
&#9;&#9;&#9;&#9;xCounter = guiObjects[pos].AbsoluteSize.X
&#9;&#9;&#9;&#9;if pixelsBelowScrollbar + currentRowY &lt;= totalPixelsY then
&#9;&#9;&#9;&#9;&#9;--It fits, so back up our scroll position
&#9;&#9;&#9;&#9;&#9;pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
&#9;&#9;&#9;&#9;&#9;if scrollPosition &lt;= rowSize then
&#9;&#9;&#9;&#9;&#9;&#9;scrollPosition = 1
&#9;&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;scrollPosition = scrollPosition - rowSize
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;currentRowY = 0
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;
&#9;&#9;&#9;if guiObjects[pos].AbsoluteSize.Y &gt; currentRowY then
&#9;&#9;&#9;&#9;currentRowY = guiObjects[pos].AbsoluteSize.Y
&#9;&#9;&#9;end
&#9;&#9;&#9;pos = pos - 1
&#9;&#9;end
&#9;&#9;
&#9;&#9;--Do check last time if pos = 0
&#9;&#9;if (pos == 0) and (pixelsBelowScrollbar + currentRowY &lt;= totalPixelsY) then
&#9;&#9;&#9;scrollPosition = 1
&#9;&#9;end
&#9;&#9;xCounter = 0
&#9;&#9;--pos = scrollPosition
&#9;&#9;rowSizeCounter = 0
&#9;&#9;setRowSize = true
&#9;&#9;local lastChildSize = 0
&#9;&#9;
&#9;&#9;local xOffset,yOffset = 0
&#9;&#9;if guiObjects[1] then
&#9;&#9;&#9;yOffset = math.ceil(math.floor(math.fmod(totalPixelsY,guiObjects[1].AbsoluteSize.X))/2)
&#9;&#9;&#9;xOffset = math.ceil(math.floor(math.fmod(totalPixelsX,guiObjects[1].AbsoluteSize.Y))/2)
&#9;&#9;end
&#9;&#9;
&#9;&#9;for i, child in ipairs(guiObjects) do
&#9;&#9;&#9;if i &lt; scrollPosition then
&#9;&#9;&#9;&#9;--print(&quot;Hiding &quot; .. child.Name)
&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;if pixelsRemainingY &lt; 0 then
&#9;&#9;&#9;&#9;&#9;--print(&quot;Out of Space &quot; .. child.Name)
&#9;&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;--print(&quot;Laying out &quot; .. child.Name)
&#9;&#9;&#9;&#9;&#9;--GuiObject
&#9;&#9;&#9;&#9;&#9;if setRowSize then rowSizeCounter = rowSizeCounter + 1 end
&#9;&#9;&#9;&#9;&#9;if xCounter + child.AbsoluteSize.X &gt;= totalPixelsX then
&#9;&#9;&#9;&#9;&#9;&#9;if setRowSize then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;rowSize = rowSizeCounter - 1
&#9;&#9;&#9;&#9;&#9;&#9;&#9;setRowSize = false
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;&#9;xCounter = 0
&#9;&#9;&#9;&#9;&#9;&#9;pixelsRemainingY = pixelsRemainingY - child.AbsoluteSize.Y
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;child.Position = UDim2.new(child.Position.X.Scale,xCounter + xOffset, 0, totalPixelsY - pixelsRemainingY + yOffset)
&#9;&#9;&#9;&#9;&#9;xCounter = xCounter + child.AbsoluteSize.X
&#9;&#9;&#9;&#9;&#9;child.Visible = ((pixelsRemainingY - child.AbsoluteSize.Y) &gt;= 0)
&#9;&#9;&#9;&#9;&#9;if child.Visible then
&#9;&#9;&#9;&#9;&#9;&#9;howManyDisplayed = howManyDisplayed + 1
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;lastChildSize = child.AbsoluteSize&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;scrollUpButton.Active = (scrollPosition &gt; 1)
&#9;&#9;if lastChildSize == 0 then
&#9;&#9;&#9;scrollDownButton.Active = false
&#9;&#9;else
&#9;&#9;&#9;scrollDownButton.Active = ((pixelsRemainingY - lastChildSize.Y) &lt; 0)
&#9;&#9;end
&#9;&#9;scrollDrag.Active = #guiObjects &gt; howManyDisplayed
&#9;&#9;scrollDrag.Visible = scrollDrag.Active
&#9;end
&#9;local layoutSimpleScrollBar = function()
&#9;&#9;local guiObjects = {}&#9;
&#9;&#9;howManyDisplayed = 0
&#9;&#9;
&#9;&#9;if orderList then
&#9;&#9;&#9;for i, child in ipairs(orderList) do
&#9;&#9;&#9;&#9;if child.Parent == frame then
&#9;&#9;&#9;&#9;&#9;table.insert(guiObjects, child)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;local children = frame:GetChildren()
&#9;&#9;&#9;if children then
&#9;&#9;&#9;&#9;for i, child in ipairs(children) do
&#9;&#9;&#9;&#9;&#9;if child:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;&#9;&#9;table.insert(guiObjects, child)
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;if #guiObjects == 0 then
&#9;&#9;&#9;scrollUpButton.Active = false
&#9;&#9;&#9;scrollDownButton.Active = false
&#9;&#9;&#9;scrollDrag.Active = false
&#9;&#9;&#9;scrollPosition = 1
&#9;&#9;&#9;return
&#9;&#9;end
&#9;&#9;if scrollPosition &gt; #guiObjects then
&#9;&#9;&#9;scrollPosition = #guiObjects
&#9;&#9;end
&#9;&#9;
&#9;&#9;local totalPixels = frame.AbsoluteSize.Y
&#9;&#9;local pixelsRemaining = frame.AbsoluteSize.Y
&#9;&#9;local pixelsBelowScrollbar = 0
&#9;&#9;local pos = #guiObjects
&#9;&#9;while pixelsBelowScrollbar &lt; totalPixels and pos &gt;= 1 do
&#9;&#9;&#9;if pos &gt;= scrollPosition then
&#9;&#9;&#9;&#9;pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;if pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y &lt;= totalPixels then
&#9;&#9;&#9;&#9;&#9;--It fits, so back up our scroll position
&#9;&#9;&#9;&#9;&#9;pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y
&#9;&#9;&#9;&#9;&#9;if scrollPosition &lt;= 1 then
&#9;&#9;&#9;&#9;&#9;&#9;scrollPosition = 1
&#9;&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;--local (&quot;Backing up ScrollPosition from -- &quot; ..scrollPosition)
&#9;&#9;&#9;&#9;&#9;&#9;scrollPosition = scrollPosition - 1
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;pos = pos - 1
&#9;&#9;end
&#9;&#9;pos = scrollPosition
&#9;&#9;for i, child in ipairs(guiObjects) do
&#9;&#9;&#9;if i &lt; scrollPosition then
&#9;&#9;&#9;&#9;--print(&quot;Hiding &quot; .. child.Name)
&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;if pixelsRemaining &lt; 0 then
&#9;&#9;&#9;&#9;&#9;--print(&quot;Out of Space &quot; .. child.Name)
&#9;&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;--print(&quot;Laying out &quot; .. child.Name)
&#9;&#9;&#9;&#9;&#9;--GuiObject
&#9;&#9;&#9;&#9;&#9;child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
&#9;&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
&#9;&#9;&#9;&#9;&#9;if (pixelsRemaining &gt;= 0) then
&#9;&#9;&#9;&#9;&#9;&#9;child.Visible = true
&#9;&#9;&#9;&#9;&#9;&#9;howManyDisplayed = howManyDisplayed + 1
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;&#9;&#9;end&#9;&#9;
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;scrollUpButton.Active = (scrollPosition &gt; 1)
&#9;&#9;scrollDownButton.Active = (pixelsRemaining &lt; 0)
&#9;&#9;scrollDrag.Active = #guiObjects &gt; howManyDisplayed
&#9;&#9;scrollDrag.Visible = scrollDrag.Active
&#9;end
&#9;
&#9;&#9;
&#9;local moveDragger = function()&#9;
&#9;&#9;local guiObjects = 0
&#9;&#9;local children = frame:GetChildren()
&#9;&#9;if children then
&#9;&#9;&#9;for i, child in ipairs(children) do
&#9;&#9;&#9;&#9;if child:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;&#9;guiObjects = guiObjects + 1
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;
&#9;&#9;if not scrollDrag.Parent then return end
&#9;&#9;
&#9;&#9;local dragSizeY = scrollDrag.Parent.AbsoluteSize.y * (1/(guiObjects - howManyDisplayed + 1))
&#9;&#9;if dragSizeY &lt; 16 then dragSizeY = 16 end
&#9;&#9;scrollDrag.Size = UDim2.new(scrollDrag.Size.X.Scale,scrollDrag.Size.X.Offset,scrollDrag.Size.Y.Scale,dragSizeY)
&#9;&#9;local relativeYPos = (scrollPosition - 1)/(guiObjects - (howManyDisplayed))
&#9;&#9;if relativeYPos &gt; 1 then relativeYPos = 1
&#9;&#9;elseif relativeYPos &lt; 0 then relativeYPos = 0 end
&#9;&#9;local absYPos = 0
&#9;&#9;
&#9;&#9;if relativeYPos ~= 0 then
&#9;&#9;&#9;absYPos = (relativeYPos * scrollbar.AbsoluteSize.y) - (relativeYPos * scrollDrag.AbsoluteSize.y)
&#9;&#9;end
&#9;&#9;
&#9;&#9;scrollDrag.Position = UDim2.new(scrollDrag.Position.X.Scale,scrollDrag.Position.X.Offset,scrollDrag.Position.Y.Scale,absYPos)
&#9;end
&#9;local reentrancyGuard = false
&#9;local recalculate = function()
&#9;&#9;if reentrancyGuard then
&#9;&#9;&#9;return
&#9;&#9;end
&#9;&#9;reentrancyGuard = true
&#9;&#9;wait()
&#9;&#9;local success, err = nil
&#9;&#9;if style == &quot;grid&quot; then
&#9;&#9;&#9;success, err = pcall(function() layoutGridScrollBar() end)
&#9;&#9;elseif style == &quot;simple&quot; then
&#9;&#9;&#9;success, err = pcall(function() layoutSimpleScrollBar() end)
&#9;&#9;end
&#9;&#9;if not success then print(err) end
&#9;&#9;moveDragger()
&#9;&#9;reentrancyGuard = false
&#9;end
&#9;
&#9;local doScrollUp = function()
&#9;&#9;scrollPosition = (scrollPosition) - rowSize
&#9;&#9;if scrollPosition &lt; 1 then scrollPosition = 1 end
&#9;&#9;recalculate(nil)
&#9;end
&#9;
&#9;local doScrollDown = function()
&#9;&#9;scrollPosition = (scrollPosition) + rowSize
&#9;&#9;recalculate(nil)
&#9;end
&#9;local scrollUp = function(mouseYPos)
&#9;&#9;if scrollUpButton.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local current = scrollStamp
&#9;&#9;&#9;local upCon
&#9;&#9;&#9;upCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;upCon:disconnect()
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;&#9;doScrollUp()
&#9;&#9;&#9;wait(0.2)
&#9;&#9;&#9;local t = tick()
&#9;&#9;&#9;local w = 0.1
&#9;&#9;&#9;while scrollStamp == current do
&#9;&#9;&#9;&#9;doScrollUp()
&#9;&#9;&#9;&#9;if mouseYPos and mouseYPos &gt; scrollDrag.AbsolutePosition.y then
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if not scrollUpButton.Active then break end
&#9;&#9;&#9;&#9;if tick()-t &gt; 5 then
&#9;&#9;&#9;&#9;&#9;w = 0
&#9;&#9;&#9;&#9;elseif tick()-t &gt; 2 then
&#9;&#9;&#9;&#9;&#9;w = 0.06
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;wait(w)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local scrollDown = function(mouseYPos)
&#9;&#9;if scrollDownButton.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local current = scrollStamp
&#9;&#9;&#9;local downCon
&#9;&#9;&#9;downCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;downCon:disconnect()
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;&#9;doScrollDown()
&#9;&#9;&#9;wait(0.2)
&#9;&#9;&#9;local t = tick()
&#9;&#9;&#9;local w = 0.1
&#9;&#9;&#9;while scrollStamp == current do
&#9;&#9;&#9;&#9;doScrollDown()
&#9;&#9;&#9;&#9;if mouseYPos and mouseYPos &lt; (scrollDrag.AbsolutePosition.y + scrollDrag.AbsoluteSize.x) then
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if not scrollDownButton.Active then break end
&#9;&#9;&#9;&#9;if tick()-t &gt; 5 then
&#9;&#9;&#9;&#9;&#9;w = 0
&#9;&#9;&#9;&#9;elseif tick()-t &gt; 2 then
&#9;&#9;&#9;&#9;&#9;w = 0.06
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;wait(w)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;
&#9;local y = 0
&#9;scrollDrag.MouseButton1Down:connect(function(x,y)
&#9;&#9;if scrollDrag.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local mouseOffset = y - scrollDrag.AbsolutePosition.y
&#9;&#9;&#9;local dragCon
&#9;&#9;&#9;local upCon
&#9;&#9;&#9;dragCon = mouseDrag.MouseMoved:connect(function(x,y)
&#9;&#9;&#9;&#9;local barAbsPos = scrollbar.AbsolutePosition.y
&#9;&#9;&#9;&#9;local barAbsSize = scrollbar.AbsoluteSize.y
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local dragAbsSize = scrollDrag.AbsoluteSize.y
&#9;&#9;&#9;&#9;local barAbsOne = barAbsPos + barAbsSize - dragAbsSize
&#9;&#9;&#9;&#9;y = y - mouseOffset
&#9;&#9;&#9;&#9;y = y &lt; barAbsPos and barAbsPos or y &gt; barAbsOne and barAbsOne or y
&#9;&#9;&#9;&#9;y = y - barAbsPos
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local guiObjects = 0
&#9;&#9;&#9;&#9;local children = frame:GetChildren()
&#9;&#9;&#9;&#9;if children then
&#9;&#9;&#9;&#9;&#9;for i, child in ipairs(children) do
&#9;&#9;&#9;&#9;&#9;&#9;if child:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;guiObjects = guiObjects + 1
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local doublePercent = y/(barAbsSize-dragAbsSize)
&#9;&#9;&#9;&#9;local rowDiff = rowSize
&#9;&#9;&#9;&#9;local totalScrollCount = guiObjects - (howManyDisplayed - 1)
&#9;&#9;&#9;&#9;local newScrollPosition = math.floor((doublePercent * totalScrollCount) + 0.5) + rowDiff
&#9;&#9;&#9;&#9;if newScrollPosition &lt; scrollPosition then
&#9;&#9;&#9;&#9;&#9;rowDiff = -rowDiff
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;if newScrollPosition &lt; 1 then
&#9;&#9;&#9;&#9;&#9;newScrollPosition = 1
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;scrollPosition = newScrollPosition
&#9;&#9;&#9;&#9;recalculate(nil)
&#9;&#9;&#9;end)
&#9;&#9;&#9;upCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;dragCon:disconnect(); dragCon = nil
&#9;&#9;&#9;&#9;upCon:disconnect(); drag = nil
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;end
&#9;end)
&#9;local scrollMouseCount = 0
&#9;scrollUpButton.MouseButton1Down:connect(
&#9;&#9;function()
&#9;&#9;&#9;scrollUp()
&#9;&#9;end)
&#9;scrollUpButton.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;scrollDownButton.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;scrollDownButton.MouseButton1Down:connect(
&#9;&#9;function()
&#9;&#9;&#9;scrollDown()&#9;
&#9;&#9;end)
&#9;&#9;
&#9;scrollbar.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;scrollbar.MouseButton1Down:connect(
&#9;&#9;function(x,y)
&#9;&#9;&#9;if y &gt; (scrollDrag.AbsoluteSize.y + scrollDrag.AbsolutePosition.y) then
&#9;&#9;&#9;&#9;scrollDown(y)
&#9;&#9;&#9;elseif y &lt; (scrollDrag.AbsolutePosition.y) then
&#9;&#9;&#9;&#9;scrollUp(y)
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;frame.ChildAdded:connect(function()
&#9;&#9;recalculate(nil)
&#9;end)
&#9;frame.ChildRemoved:connect(function()
&#9;&#9;recalculate(nil)
&#9;end)
&#9;
&#9;frame.Changed:connect(
&#9;&#9;function(prop)
&#9;&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;&#9;--Wait a heartbeat for it to sync in
&#9;&#9;&#9;&#9;recalculate(nil)
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;frame.AncestryChanged:connect(function() recalculate(nil) end)
&#9;return frame, scrollUpButton, scrollDownButton, recalculate, scrollbar
end
local function binaryGrow(min, max, fits)
&#9;if min &gt; max then
&#9;&#9;return min
&#9;end
&#9;local biggestLegal = min
&#9;while min &lt;= max do
&#9;&#9;local mid = min + math.floor((max - min) / 2)
&#9;&#9;if fits(mid) and (biggestLegal == nil or biggestLegal &lt; mid) then
&#9;&#9;&#9;biggestLegal = mid
&#9;&#9;&#9;
&#9;&#9;&#9;--Try growing
&#9;&#9;&#9;min = mid + 1
&#9;&#9;else
&#9;&#9;&#9;--Doesn&apos;t fit, shrink
&#9;&#9;&#9;max = mid - 1
&#9;&#9;end
&#9;end
&#9;return biggestLegal
end
local function binaryShrink(min, max, fits)
&#9;if min &gt; max then
&#9;&#9;return min
&#9;end
&#9;local smallestLegal = max
&#9;while min &lt;= max do
&#9;&#9;local mid = min + math.floor((max - min) / 2)
&#9;&#9;if fits(mid) and (smallestLegal == nil or smallestLegal &gt; mid) then
&#9;&#9;&#9;smallestLegal = mid
&#9;&#9;&#9;
&#9;&#9;&#9;--It fits, shrink
&#9;&#9;&#9;max = mid - 1&#9;&#9;&#9;
&#9;&#9;else
&#9;&#9;&#9;--Doesn&apos;t fit, grow
&#9;&#9;&#9;min = mid + 1
&#9;&#9;end
&#9;end
&#9;return smallestLegal
end
local function getGuiOwner(instance)
&#9;while instance ~= nil do
&#9;&#9;if instance:IsA(&quot;ScreenGui&quot;) or instance:IsA(&quot;BillboardGui&quot;) then
&#9;&#9;&#9;return instance
&#9;&#9;end
&#9;&#9;instance = instance.Parent
&#9;end
&#9;return nil
end
t.AutoTruncateTextObject = function(textLabel)
&#9;local text = textLabel.Text
&#9;local fullLabel = textLabel:Clone()
&#9;fullLabel.Name = &quot;Full&quot; .. textLabel.Name
&#9;fullLabel.BorderSizePixel = 0
&#9;fullLabel.BackgroundTransparency = 0
&#9;fullLabel.Text = text
&#9;fullLabel.TextXAlignment = Enum.TextXAlignment.Center
&#9;fullLabel.Position = UDim2.new(0,-3,0,0)
&#9;fullLabel.Size = UDim2.new(0,100,1,0)
&#9;fullLabel.Visible = false
&#9;fullLabel.Parent = textLabel
&#9;local shortText = nil
&#9;local mouseEnterConnection = nil
&#9;local mouseLeaveConnection= nil
&#9;local checkForResize = function()
&#9;&#9;if getGuiOwner(textLabel) == nil then
&#9;&#9;&#9;return
&#9;&#9;end
&#9;&#9;textLabel.Text = text
&#9;&#9;if textLabel.TextFits then
&#9;&#9;&#9;--Tear down the rollover if it is active
&#9;&#9;&#9;if mouseEnterConnection then
&#9;&#9;&#9;&#9;mouseEnterConnection:disconnect()
&#9;&#9;&#9;&#9;mouseEnterConnection = nil
&#9;&#9;&#9;end
&#9;&#9;&#9;if mouseLeaveConnection then
&#9;&#9;&#9;&#9;mouseLeaveConnection:disconnect()
&#9;&#9;&#9;&#9;mouseLeaveConnection = nil
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;local len = string.len(text)
&#9;&#9;&#9;textLabel.Text = text .. &quot;~&quot;
&#9;&#9;&#9;--Shrink the text
&#9;&#9;&#9;local textSize = binaryGrow(0, len,
&#9;&#9;&#9;&#9;function(pos)
&#9;&#9;&#9;&#9;&#9;if pos == 0 then
&#9;&#9;&#9;&#9;&#9;&#9;textLabel.Text = &quot;~&quot;
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;textLabel.Text = string.sub(text, 1, pos) .. &quot;~&quot;
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;return textLabel.TextFits
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;shortText = string.sub(text, 1, textSize) .. &quot;~&quot;
&#9;&#9;&#9;textLabel.Text = shortText
&#9;&#9;&#9;
&#9;&#9;&#9;--Make sure the fullLabel fits
&#9;&#9;&#9;if not fullLabel.TextFits then
&#9;&#9;&#9;&#9;--Already too small, grow it really bit to start
&#9;&#9;&#9;&#9;fullLabel.Size = UDim2.new(0, 10000, 1, 0)
&#9;&#9;&#9;end
&#9;&#9;&#9;
&#9;&#9;&#9;--Okay, now try to binary shrink it back down
&#9;&#9;&#9;local fullLabelSize = binaryShrink(textLabel.AbsoluteSize.X,fullLabel.AbsoluteSize.X,
&#9;&#9;&#9;&#9;function(size)
&#9;&#9;&#9;&#9;&#9;fullLabel.Size = UDim2.new(0, size, 1, 0)
&#9;&#9;&#9;&#9;&#9;return fullLabel.TextFits
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;fullLabel.Size = UDim2.new(0,fullLabelSize+6,1,0)
&#9;&#9;&#9;--Now setup the rollover effects, if they are currently off
&#9;&#9;&#9;if mouseEnterConnection == nil then
&#9;&#9;&#9;&#9;mouseEnterConnection = textLabel.MouseEnter:connect(
&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;&#9;fullLabel.ZIndex = textLabel.ZIndex + 1
&#9;&#9;&#9;&#9;&#9;&#9;fullLabel.Visible = true
&#9;&#9;&#9;&#9;&#9;&#9;--textLabel.Text = &quot;&quot;
&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;&#9;if mouseLeaveConnection == nil then
&#9;&#9;&#9;&#9;mouseLeaveConnection = textLabel.MouseLeave:connect(
&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;&#9;fullLabel.Visible = false
&#9;&#9;&#9;&#9;&#9;&#9;--textLabel.Text = shortText
&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;textLabel.AncestryChanged:connect(checkForResize)
&#9;textLabel.Changed:connect(
&#9;&#9;function(prop)
&#9;&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;&#9;checkForResize() &#9;
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;checkForResize()
&#9;local function changeText(newText)
&#9;&#9;text = newText
&#9;&#9;fullLabel.Text = text
&#9;&#9;checkForResize()
&#9;end
&#9;return textLabel, changeText
end
local function TransitionTutorialPages(fromPage, toPage, transitionFrame, currentPageValue)&#9;
&#9;if fromPage then
&#9;&#9;fromPage.Visible = false
&#9;&#9;if transitionFrame.Visible == false then
&#9;&#9;&#9;transitionFrame.Size = fromPage.Size
&#9;&#9;&#9;transitionFrame.Position = fromPage.Position
&#9;&#9;end
&#9;else
&#9;&#9;if transitionFrame.Visible == false then
&#9;&#9;&#9;transitionFrame.Size = UDim2.new(0.0,50,0.0,50)
&#9;&#9;&#9;transitionFrame.Position = UDim2.new(0.5,-25,0.5,-25)
&#9;&#9;end
&#9;end
&#9;transitionFrame.Visible = true
&#9;currentPageValue.Value = nil
&#9;local newsize, newPosition
&#9;if toPage then
&#9;&#9;--Make it visible so it resizes
&#9;&#9;toPage.Visible = true
&#9;&#9;newSize = toPage.Size
&#9;&#9;newPosition = toPage.Position
&#9;&#9;toPage.Visible = false
&#9;else
&#9;&#9;newSize = UDim2.new(0.0,50,0.0,50)
&#9;&#9;newPosition = UDim2.new(0.5,-25,0.5,-25)
&#9;end
&#9;transitionFrame:TweenSizeAndPosition(newSize, newPosition, Enum.EasingDirection.InOut, Enum.EasingStyle.Quad, 0.3, true,
&#9;&#9;function(state)
&#9;&#9;&#9;if state == Enum.TweenStatus.Completed then
&#9;&#9;&#9;&#9;transitionFrame.Visible = false
&#9;&#9;&#9;&#9;if toPage then
&#9;&#9;&#9;&#9;&#9;toPage.Visible = true
&#9;&#9;&#9;&#9;&#9;currentPageValue.Value = toPage
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end)
end
t.CreateTutorial = function(name, tutorialKey, createButtons)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Name = &quot;Tutorial-&quot; .. name
&#9;frame.BackgroundTransparency = 1
&#9;frame.Size = UDim2.new(0.6, 0, 0.6, 0)
&#9;frame.Position = UDim2.new(0.2, 0, 0.2, 0)
&#9;local transitionFrame = Instance.new(&quot;Frame&quot;)
&#9;transitionFrame.Name = &quot;TransitionFrame&quot;
&#9;transitionFrame.Style = Enum.FrameStyle.RobloxRound
&#9;transitionFrame.Size = UDim2.new(0.6, 0, 0.6, 0)
&#9;transitionFrame.Position = UDim2.new(0.2, 0, 0.2, 0)
&#9;transitionFrame.Visible = false
&#9;transitionFrame.Parent = frame
&#9;local currentPageValue = Instance.new(&quot;ObjectValue&quot;)
&#9;currentPageValue.Name = &quot;CurrentTutorialPage&quot;
&#9;currentPageValue.Value = nil
&#9;currentPageValue.Parent = frame
&#9;local boolValue = Instance.new(&quot;BoolValue&quot;)
&#9;boolValue.Name = &quot;Buttons&quot;
&#9;boolValue.Value = createButtons
&#9;boolValue.Parent = frame
&#9;local pages = Instance.new(&quot;Frame&quot;)
&#9;pages.Name = &quot;Pages&quot;
&#9;pages.BackgroundTransparency = 1
&#9;pages.Size = UDim2.new(1,0,1,0)
&#9;pages.Parent = frame
&#9;local function getVisiblePageAndHideOthers()
&#9;&#9;local visiblePage = nil
&#9;&#9;local children = pages:GetChildren()
&#9;&#9;if children then
&#9;&#9;&#9;for i,child in ipairs(children) do
&#9;&#9;&#9;&#9;if child.Visible then
&#9;&#9;&#9;&#9;&#9;if visiblePage then
&#9;&#9;&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;visiblePage = child
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;return visiblePage
&#9;end
&#9;local showTutorial = function(alwaysShow)
&#9;&#9;if alwaysShow or UserSettings().GameSettings:GetTutorialState(tutorialKey) == false then
&#9;&#9;&#9;print(&quot;Showing tutorial-&quot;,tutorialKey)
&#9;&#9;&#9;local currentTutorialPage = getVisiblePageAndHideOthers()
&#9;&#9;&#9;local firstPage = pages:FindFirstChild(&quot;TutorialPage1&quot;)
&#9;&#9;&#9;if firstPage then
&#9;&#9;&#9;&#9;TransitionTutorialPages(currentTutorialPage, firstPage, transitionFrame, currentPageValue)&#9;
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;error(&quot;Could not find TutorialPage1&quot;)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local dismissTutorial = function()
&#9;&#9;local currentTutorialPage = getVisiblePageAndHideOthers()
&#9;&#9;if currentTutorialPage then
&#9;&#9;&#9;TransitionTutorialPages(currentTutorialPage, nil, transitionFrame, currentPageValue)
&#9;&#9;end
&#9;&#9;UserSettings().GameSettings:SetTutorialState(tutorialKey, true)
&#9;end
&#9;local gotoPage = function(pageNum)
&#9;&#9;local page = pages:FindFirstChild(&quot;TutorialPage&quot; .. pageNum)
&#9;&#9;local currentTutorialPage = getVisiblePageAndHideOthers()
&#9;&#9;TransitionTutorialPages(currentTutorialPage, page, transitionFrame, currentPageValue)
&#9;end
&#9;return frame, showTutorial, dismissTutorial, gotoPage
end
local function CreateBasicTutorialPage(name, handleResize, skipTutorial, giveDoneButton)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Name = &quot;TutorialPage&quot;
&#9;frame.Style = Enum.FrameStyle.RobloxRound
&#9;frame.Size = UDim2.new(0.6, 0, 0.6, 0)
&#9;frame.Position = UDim2.new(0.2, 0, 0.2, 0)
&#9;frame.Visible = false
&#9;
&#9;local frameHeader = Instance.new(&quot;TextLabel&quot;)
&#9;frameHeader.Name = &quot;Header&quot;
&#9;frameHeader.Text = name
&#9;frameHeader.BackgroundTransparency = 1
&#9;frameHeader.FontSize = Enum.FontSize.Size24
&#9;frameHeader.Font = Enum.Font.ArialBold
&#9;frameHeader.TextColor3 = Color3.new(1,1,1)
&#9;frameHeader.TextXAlignment = Enum.TextXAlignment.Center
&#9;frameHeader.TextWrap = true
&#9;frameHeader.Size = UDim2.new(1,-55, 0, 22)
&#9;frameHeader.Position = UDim2.new(0,0,0,0)
&#9;frameHeader.Parent = frame
&#9;local skipButton = Instance.new(&quot;ImageButton&quot;)
&#9;skipButton.Name = &quot;SkipButton&quot;
&#9;skipButton.AutoButtonColor = false
&#9;skipButton.BackgroundTransparency = 1
&#9;skipButton.Image = &quot;rbxasset://textures/ui/closeButton.png&quot;
&#9;skipButton.MouseButton1Click:connect(function()
&#9;&#9;skipTutorial()
&#9;end)
&#9;skipButton.MouseEnter:connect(function()
&#9;&#9;skipButton.Image = &quot;rbxasset://textures/ui/closeButton_dn.png&quot;
&#9;end)
&#9;skipButton.MouseLeave:connect(function()
&#9;&#9;skipButton.Image = &quot;rbxasset://textures/ui/closeButton.png&quot;
&#9;end)
&#9;skipButton.Size = UDim2.new(0, 25, 0, 25)
&#9;skipButton.Position = UDim2.new(1, -25, 0, 0)
&#9;skipButton.Parent = frame
&#9;
&#9;
&#9;if giveDoneButton then
&#9;&#9;local doneButton = Instance.new(&quot;TextButton&quot;)
&#9;&#9;doneButton.Name = &quot;DoneButton&quot;
&#9;&#9;doneButton.Style = Enum.ButtonStyle.RobloxButtonDefault
&#9;&#9;doneButton.Text = &quot;Done&quot;
&#9;&#9;doneButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;doneButton.Font = Enum.Font.ArialBold
&#9;&#9;doneButton.FontSize = Enum.FontSize.Size18
&#9;&#9;doneButton.Size = UDim2.new(0,100,0,50)
&#9;&#9;doneButton.Position = UDim2.new(0.5,-50,1,-50)
&#9;&#9;
&#9;&#9;if skipTutorial then
&#9;&#9;&#9;doneButton.MouseButton1Click:connect(function() skipTutorial() end)
&#9;&#9;end
&#9;&#9;
&#9;&#9;doneButton.Parent = frame
&#9;end
&#9;local innerFrame = Instance.new(&quot;Frame&quot;)
&#9;innerFrame.Name = &quot;ContentFrame&quot;
&#9;innerFrame.BackgroundTransparency = 1
&#9;innerFrame.Position = UDim2.new(0,0,0,25)
&#9;innerFrame.Parent = frame
&#9;local nextButton = Instance.new(&quot;TextButton&quot;)
&#9;nextButton.Name = &quot;NextButton&quot;
&#9;nextButton.Text = &quot;Next&quot;
&#9;nextButton.TextColor3 = Color3.new(1,1,1)
&#9;nextButton.Font = Enum.Font.Arial
&#9;nextButton.FontSize = Enum.FontSize.Size18
&#9;nextButton.Style = Enum.ButtonStyle.RobloxButtonDefault
&#9;nextButton.Size = UDim2.new(0,80, 0, 32)
&#9;nextButton.Position = UDim2.new(0.5, 5, 1, -32)
&#9;nextButton.Active = false
&#9;nextButton.Visible = false
&#9;nextButton.Parent = frame
&#9;local prevButton = Instance.new(&quot;TextButton&quot;)
&#9;prevButton.Name = &quot;PrevButton&quot;
&#9;prevButton.Text = &quot;Previous&quot;
&#9;prevButton.TextColor3 = Color3.new(1,1,1)
&#9;prevButton.Font = Enum.Font.Arial
&#9;prevButton.FontSize = Enum.FontSize.Size18
&#9;prevButton.Style = Enum.ButtonStyle.RobloxButton
&#9;prevButton.Size = UDim2.new(0,80, 0, 32)
&#9;prevButton.Position = UDim2.new(0.5, -85, 1, -32)
&#9;prevButton.Active = false
&#9;prevButton.Visible = false
&#9;prevButton.Parent = frame
&#9;if giveDoneButton then
&#9;&#9;innerFrame.Size = UDim2.new(1,0,1,-75)
&#9;else
&#9;&#9;innerFrame.Size = UDim2.new(1,0,1,-22)
&#9;end
&#9;local parentConnection = nil
&#9;local function basicHandleResize()
&#9;&#9;if frame.Visible and frame.Parent then
&#9;&#9;&#9;local maxSize = math.min(frame.Parent.AbsoluteSize.X, frame.Parent.AbsoluteSize.Y)
&#9;&#9;&#9;handleResize(200,maxSize)
&#9;&#9;end
&#9;end
&#9;frame.Changed:connect(
&#9;&#9;function(prop)
&#9;&#9;&#9;if prop == &quot;Parent&quot; then
&#9;&#9;&#9;&#9;if parentConnection ~= nil then
&#9;&#9;&#9;&#9;&#9;parentConnection:disconnect()
&#9;&#9;&#9;&#9;&#9;parentConnection = nil
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if frame.Parent and frame.Parent:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;&#9;parentConnection = frame.Parent.Changed:connect(
&#9;&#9;&#9;&#9;&#9;&#9;function(parentProp)
&#9;&#9;&#9;&#9;&#9;&#9;&#9;if parentProp == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;wait()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;basicHandleResize()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;&#9;&#9;basicHandleResize()
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;if prop == &quot;Visible&quot; then
&#9;&#9;&#9;&#9;basicHandleResize()
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;return frame, innerFrame
end
t.CreateTextTutorialPage = function(name, text, skipTutorialFunc)
&#9;local frame = nil
&#9;local contentFrame = nil
&#9;local textLabel = Instance.new(&quot;TextLabel&quot;)
&#9;textLabel.BackgroundTransparency = 1
&#9;textLabel.TextColor3 = Color3.new(1,1,1)
&#9;textLabel.Text = text
&#9;textLabel.TextWrap = true
&#9;textLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;textLabel.TextYAlignment = Enum.TextYAlignment.Center
&#9;textLabel.Font = Enum.Font.Arial
&#9;textLabel.FontSize = Enum.FontSize.Size14
&#9;textLabel.Size = UDim2.new(1,0,1,0)
&#9;local function handleResize(minSize, maxSize)
&#9;&#9;size = binaryShrink(minSize, maxSize,
&#9;&#9;&#9;function(size)
&#9;&#9;&#9;&#9;frame.Size = UDim2.new(0, size, 0, size)
&#9;&#9;&#9;&#9;return textLabel.TextFits
&#9;&#9;&#9;end)
&#9;&#9;frame.Size = UDim2.new(0, size, 0, size)
&#9;&#9;frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2)
&#9;end
&#9;frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc)
&#9;textLabel.Parent = contentFrame
&#9;return frame
end
t.CreateImageTutorialPage = function(name, imageAsset, x, y, skipTutorialFunc, giveDoneButton)
&#9;local frame = nil
&#9;local contentFrame = nil
&#9;local imageLabel = Instance.new(&quot;ImageLabel&quot;)
&#9;imageLabel.BackgroundTransparency = 1
&#9;imageLabel.Image = imageAsset
&#9;imageLabel.Size = UDim2.new(0,x,0,y)
&#9;imageLabel.Position = UDim2.new(0.5,-x/2,0.5,-y/2)
&#9;local function handleResize(minSize, maxSize)
&#9;&#9;size = binaryShrink(minSize, maxSize,
&#9;&#9;&#9;function(size)
&#9;&#9;&#9;&#9;return size &gt;= x and size &gt;= y
&#9;&#9;&#9;end)
&#9;&#9;if size &gt;= x and size &gt;= y then
&#9;&#9;&#9;imageLabel.Size = UDim2.new(0,x, 0,y)
&#9;&#9;&#9;imageLabel.Position = UDim2.new(0.5,-x/2, 0.5, -y/2)
&#9;&#9;else
&#9;&#9;&#9;if x &gt; y then
&#9;&#9;&#9;&#9;--X is limiter, so
&#9;&#9;&#9;&#9;imageLabel.Size = UDim2.new(1,0,y/x,0)
&#9;&#9;&#9;&#9;imageLabel.Position = UDim2.new(0,0, 0.5 - (y/x)/2, 0)
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;--Y is limiter
&#9;&#9;&#9;&#9;imageLabel.Size = UDim2.new(x/y,0,1, 0)
&#9;&#9;&#9;&#9;imageLabel.Position = UDim2.new(0.5-(x/y)/2, 0, 0, 0)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;size = size + 50
&#9;&#9;frame.Size = UDim2.new(0, size, 0, size)
&#9;&#9;frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2)
&#9;end
&#9;frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc, giveDoneButton)
&#9;imageLabel.Parent = contentFrame
&#9;return frame
end
t.AddTutorialPage = function(tutorial, tutorialPage)
&#9;local transitionFrame = tutorial.TransitionFrame
&#9;local currentPageValue = tutorial.CurrentTutorialPage
&#9;if not tutorial.Buttons.Value then
&#9;&#9;tutorialPage.NextButton.Parent = nil
&#9;&#9;tutorialPage.PrevButton.Parent = nil
&#9;end
&#9;local children = tutorial.Pages:GetChildren()
&#9;if children and #children &gt; 0 then
&#9;&#9;tutorialPage.Name = &quot;TutorialPage&quot; .. (#children+1)
&#9;&#9;local previousPage = children[#children]
&#9;&#9;if not previousPage:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;error(&quot;All elements under Pages must be GuiObjects&quot;)
&#9;&#9;end
&#9;&#9;if tutorial.Buttons.Value then
&#9;&#9;&#9;if previousPage.NextButton.Active then
&#9;&#9;&#9;&#9;error(&quot;NextButton already Active on previousPage, please only add pages with RbxGui.AddTutorialPage function&quot;)
&#9;&#9;&#9;end
&#9;&#9;&#9;previousPage.NextButton.MouseButton1Click:connect(
&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;TransitionTutorialPages(previousPage, tutorialPage, transitionFrame, currentPageValue)
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;previousPage.NextButton.Active = true
&#9;&#9;&#9;previousPage.NextButton.Visible = true
&#9;&#9;&#9;if tutorialPage.PrevButton.Active then
&#9;&#9;&#9;&#9;error(&quot;PrevButton already Active on tutorialPage, please only add pages with RbxGui.AddTutorialPage function&quot;)
&#9;&#9;&#9;end
&#9;&#9;&#9;tutorialPage.PrevButton.MouseButton1Click:connect(
&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;TransitionTutorialPages(tutorialPage, previousPage, transitionFrame, currentPageValue)
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;tutorialPage.PrevButton.Active = true
&#9;&#9;&#9;tutorialPage.PrevButton.Visible = true
&#9;&#9;end
&#9;&#9;tutorialPage.Parent = tutorial.Pages
&#9;else
&#9;&#9;--First child
&#9;&#9;tutorialPage.Name = &quot;TutorialPage1&quot;
&#9;&#9;tutorialPage.Parent = tutorial.Pages
&#9;end
end
t.CreateSetPanel = function(userIdsForSets, objectSelected, dialogClosed, size, position, showAdminCategories, useAssetVersionId)
&#9;if not userIdsForSets then
&#9;&#9;error(&quot;CreateSetPanel: userIdsForSets (first arg) is nil, should be a table of number ids&quot;)
&#9;end
&#9;if type(userIdsForSets) ~= &quot;table&quot; and type(userIdsForSets) ~= &quot;userdata&quot; then
&#9;&#9;error(&quot;CreateSetPanel: userIdsForSets (first arg) is of type &quot; ..type(userIdsForSets) .. &quot;, should be of type table or userdata&quot;)
&#9;end
&#9;if not objectSelected then
&#9;&#9;error(&quot;CreateSetPanel: objectSelected (second arg) is nil, should be a callback function!&quot;)
&#9;end
&#9;if type(objectSelected) ~= &quot;function&quot; then
&#9;&#9;error(&quot;CreateSetPanel: objectSelected (second arg) is of type &quot; .. type(objectSelected) .. &quot;, should be of type function!&quot;)
&#9;end
&#9;if dialogClosed and type(dialogClosed) ~= &quot;function&quot; then
&#9;&#9;error(&quot;CreateSetPanel: dialogClosed (third arg) is of type &quot; .. type(dialogClosed) .. &quot;, should be of type function!&quot;)
&#9;end
&#9;
&#9;if showAdminCategories == nil then -- by default, don&apos;t show beta sets
&#9;&#9;showAdminCategories = false
&#9;end
&#9;local arrayPosition = 1
&#9;local insertButtons = {}
&#9;local insertButtonCons = {}
&#9;local contents = nil
&#9;local setGui = nil
&#9;-- used for water selections
&#9;local waterForceDirection = &quot;NegX&quot;
&#9;local waterForce = &quot;None&quot;
&#9;local waterGui, waterTypeChangedEvent = nil
&#9;
&#9;local Data = {}
&#9;Data.CurrentCategory = nil
&#9;Data.Category = {}
&#9;local SetCache = {}
&#9;
&#9;local userCategoryButtons = nil
&#9;
&#9;local buttonWidth = 64
&#9;local buttonHeight = buttonWidth
&#9;
&#9;local SmallThumbnailUrl = nil
&#9;local LargeThumbnailUrl = nil
&#9;local BaseUrl = game:GetService(&quot;ContentProvider&quot;).BaseUrl:lower()
&#9;
&#9;if useAssetVersionId then
&#9;&#9;LargeThumbnailUrl = BaseUrl .. &quot;Game/Tools/ThumbnailAsset.ashx?fmt=png&amp;wd=420&amp;ht=420&amp;assetversionid=&quot;
&#9;&#9;SmallThumbnailUrl = BaseUrl .. &quot;Game/Tools/ThumbnailAsset.ashx?fmt=png&amp;wd=75&amp;ht=75&amp;assetversionid=&quot;
&#9;else
&#9;&#9;LargeThumbnailUrl = BaseUrl .. &quot;Game/Tools/ThumbnailAsset.ashx?fmt=png&amp;wd=420&amp;ht=420&amp;aid=&quot;
&#9;&#9;SmallThumbnailUrl = BaseUrl .. &quot;Game/Tools/ThumbnailAsset.ashx?fmt=png&amp;wd=75&amp;ht=75&amp;aid=&quot;
&#9;end
&#9;&#9;
&#9;local function drillDownSetZIndex(parent, index)
&#9;&#9;local children = parent:GetChildren()
&#9;&#9;for i = 1, #children do
&#9;&#9;&#9;if children[i]:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;children[i].ZIndex = index
&#9;&#9;&#9;end
&#9;&#9;&#9;drillDownSetZIndex(children[i], index)
&#9;&#9;end
&#9;end
&#9;
&#9;-- for terrain stamping
&#9;local currTerrainDropDownFrame = nil
&#9;local terrainShapes = {&quot;Block&quot;,&quot;Vertical Ramp&quot;,&quot;Corner Wedge&quot;,&quot;Inverse Corner Wedge&quot;,&quot;Horizontal Ramp&quot;,&quot;Auto-Wedge&quot;}
&#9;local terrainShapeMap = {}
&#9;for i = 1, #terrainShapes do
&#9;&#9;terrainShapeMap[terrainShapes[i]] = i - 1
&#9;end&#9;
&#9;terrainShapeMap[terrainShapes[#terrainShapes]] = 6
&#9;local function createWaterGui()
&#9;&#9;local waterForceDirections = {&quot;NegX&quot;,&quot;X&quot;,&quot;NegY&quot;,&quot;Y&quot;,&quot;NegZ&quot;,&quot;Z&quot;}
&#9;&#9;local waterForces = {&quot;None&quot;, &quot;Small&quot;, &quot;Medium&quot;, &quot;Strong&quot;, &quot;Max&quot;}
&#9;&#9;local waterFrame = Instance.new(&quot;Frame&quot;)
&#9;&#9;waterFrame.Name = &quot;WaterFrame&quot;
&#9;&#9;waterFrame.Style = Enum.FrameStyle.RobloxSquare
&#9;&#9;waterFrame.Size = UDim2.new(0,150,0,110)
&#9;&#9;waterFrame.Visible = false
&#9;&#9;local waterForceLabel = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;waterForceLabel.Name = &quot;WaterForceLabel&quot;
&#9;&#9;waterForceLabel.BackgroundTransparency = 1
&#9;&#9;waterForceLabel.Size = UDim2.new(1,0,0,12)
&#9;&#9;waterForceLabel.Font = Enum.Font.ArialBold
&#9;&#9;waterForceLabel.FontSize = Enum.FontSize.Size12
&#9;&#9;waterForceLabel.TextColor3 = Color3.new(1,1,1)
&#9;&#9;waterForceLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;waterForceLabel.Text = &quot;Water Force&quot;
&#9;&#9;waterForceLabel.Parent = waterFrame
&#9;&#9;local waterForceDirLabel = waterForceLabel:Clone()
&#9;&#9;waterForceDirLabel.Name = &quot;WaterForceDirectionLabel&quot;
&#9;&#9;waterForceDirLabel.Text = &quot;Water Force Direction&quot;
&#9;&#9;waterForceDirLabel.Position = UDim2.new(0,0,0,50)
&#9;&#9;waterForceDirLabel.Parent = waterFrame
&#9;&#9;local waterTypeChangedEvent = Instance.new(&quot;BindableEvent&quot;,waterFrame)
&#9;&#9;waterTypeChangedEvent.Name = &quot;WaterTypeChangedEvent&quot;
&#9;&#9;local waterForceDirectionSelectedFunc = function(newForceDirection)
&#9;&#9;&#9;waterForceDirection = newForceDirection
&#9;&#9;&#9;waterTypeChangedEvent:Fire({waterForce, waterForceDirection})
&#9;&#9;end
&#9;&#9;local waterForceSelectedFunc = function(newForce)
&#9;&#9;&#9;waterForce = newForce
&#9;&#9;&#9;waterTypeChangedEvent:Fire({waterForce, waterForceDirection})
&#9;&#9;end
&#9;&#9;local waterForceDirectionDropDown, forceWaterDirectionSelection = t.CreateDropDownMenu(waterForceDirections, waterForceDirectionSelectedFunc)
&#9;&#9;waterForceDirectionDropDown.Size = UDim2.new(1,0,0,25)
&#9;&#9;waterForceDirectionDropDown.Position = UDim2.new(0,0,1,3)
&#9;&#9;forceWaterDirectionSelection(&quot;NegX&quot;)
&#9;&#9;waterForceDirectionDropDown.Parent = waterForceDirLabel
&#9;&#9;local waterForceDropDown, forceWaterForceSelection = t.CreateDropDownMenu(waterForces, waterForceSelectedFunc)
&#9;&#9;forceWaterForceSelection(&quot;None&quot;)
&#9;&#9;waterForceDropDown.Size = UDim2.new(1,0,0,25)
&#9;&#9;waterForceDropDown.Position = UDim2.new(0,0,1,3)
&#9;&#9;waterForceDropDown.Parent = waterForceLabel
&#9;&#9;return waterFrame, waterTypeChangedEvent
&#9;end
&#9;-- Helper Function that contructs gui elements
&#9;local function createSetGui()
&#9;
&#9;&#9;local setGui = Instance.new(&quot;ScreenGui&quot;)
&#9;&#9;setGui.Name = &quot;SetGui&quot;
&#9;&#9;
&#9;&#9;local setPanel = Instance.new(&quot;Frame&quot;)
&#9;&#9;setPanel.Name = &quot;SetPanel&quot;
&#9;&#9;setPanel.Active = true
&#9;&#9;setPanel.BackgroundTransparency = 1
&#9;&#9;if position then
&#9;&#9;&#9;setPanel.Position = position
&#9;&#9;else
&#9;&#9;&#9;setPanel.Position = UDim2.new(0.2, 29, 0.1, 24)
&#9;&#9;end
&#9;&#9;if size then
&#9;&#9;&#9;setPanel.Size = size
&#9;&#9;else
&#9;&#9;&#9;setPanel.Size = UDim2.new(0.6, -58, 0.64, 0)
&#9;&#9;end
&#9;&#9;setPanel.Style = Enum.FrameStyle.RobloxRound
&#9;&#9;setPanel.ZIndex = 6
&#9;&#9;setPanel.Parent = setGui
&#9;&#9;
&#9;&#9;&#9;-- Children of SetPanel
&#9;&#9;&#9;local itemPreview = Instance.new(&quot;Frame&quot;)
&#9;&#9;&#9;itemPreview.Name = &quot;ItemPreview&quot;
&#9;&#9;&#9;itemPreview.BackgroundTransparency = 1
&#9;&#9;&#9;itemPreview.Position = UDim2.new(0.8,5,0.085,0)
&#9;&#9;&#9;itemPreview.Size = UDim2.new(0.21,0,0.9,0)
&#9;&#9;&#9;itemPreview.ZIndex = 6
&#9;&#9;&#9;itemPreview.Parent = setPanel
&#9;&#9;&#9;
&#9;&#9;&#9;&#9;-- Children of ItemPreview
&#9;&#9;&#9;&#9;local textPanel = Instance.new(&quot;Frame&quot;)
&#9;&#9;&#9;&#9;textPanel.Name = &quot;TextPanel&quot;
&#9;&#9;&#9;&#9;textPanel.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;textPanel.Position = UDim2.new(0,0,0.45,0)
&#9;&#9;&#9;&#9;textPanel.Size = UDim2.new(1,0,0.55,0)
&#9;&#9;&#9;&#9;textPanel.ZIndex = 6
&#9;&#9;&#9;&#9;textPanel.Parent = itemPreview
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;-- Children of TextPanel
&#9;&#9;&#9;&#9;&#9;local rolloverText = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;&#9;&#9;&#9;rolloverText.Name = &quot;RolloverText&quot;
&#9;&#9;&#9;&#9;&#9;rolloverText.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;&#9;rolloverText.Size = UDim2.new(1,0,0,48)
&#9;&#9;&#9;&#9;&#9;rolloverText.ZIndex = 6
&#9;&#9;&#9;&#9;&#9;rolloverText.Font = Enum.Font.ArialBold
&#9;&#9;&#9;&#9;&#9;rolloverText.FontSize = Enum.FontSize.Size24
&#9;&#9;&#9;&#9;&#9;rolloverText.Text = &quot;&quot;
&#9;&#9;&#9;&#9;&#9;rolloverText.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;&#9;rolloverText.TextWrap = true
&#9;&#9;&#9;&#9;&#9;rolloverText.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;&#9;&#9;&#9;rolloverText.TextYAlignment = Enum.TextYAlignment.Top
&#9;&#9;&#9;&#9;&#9;rolloverText.Parent = textPanel
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local largePreview = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;&#9;&#9;largePreview.Name = &quot;LargePreview&quot;
&#9;&#9;&#9;&#9;largePreview.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;largePreview.Image = &quot;&quot;
&#9;&#9;&#9;&#9;largePreview.Size = UDim2.new(1,0,0,170)
&#9;&#9;&#9;&#9;largePreview.ZIndex = 6
&#9;&#9;&#9;&#9;largePreview.Parent = itemPreview
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;local sets = Instance.new(&quot;Frame&quot;)
&#9;&#9;&#9;sets.Name = &quot;Sets&quot;
&#9;&#9;&#9;sets.BackgroundTransparency = 1
&#9;&#9;&#9;sets.Position = UDim2.new(0,0,0,5)
&#9;&#9;&#9;sets.Size = UDim2.new(0.23,0,1,-5)
&#9;&#9;&#9;sets.ZIndex = 6
&#9;&#9;&#9;sets.Parent = setPanel
&#9;&#9;&#9;
&#9;&#9;&#9;&#9;-- Children of Sets
&#9;&#9;&#9;&#9;local line = Instance.new(&quot;Frame&quot;)
&#9;&#9;&#9;&#9;line.Name = &quot;Line&quot;
&#9;&#9;&#9;&#9;line.BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;line.BackgroundTransparency = 0.7
&#9;&#9;&#9;&#9;line.BorderSizePixel = 0
&#9;&#9;&#9;&#9;line.Position = UDim2.new(1,-3,0.06,0)
&#9;&#9;&#9;&#9;line.Size = UDim2.new(0,3,0.9,0)
&#9;&#9;&#9;&#9;line.ZIndex = 6
&#9;&#9;&#9;&#9;line.Parent = sets
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local setsLists, controlFrame = t.CreateTrueScrollingFrame()
&#9;&#9;&#9;&#9;setsLists.Size = UDim2.new(1,-6,0.94,0)
&#9;&#9;&#9;&#9;setsLists.Position = UDim2.new(0,0,0.06,0)
&#9;&#9;&#9;&#9;setsLists.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;setsLists.Name = &quot;SetsLists&quot;
&#9;&#9;&#9;&#9;setsLists.ZIndex = 6
&#9;&#9;&#9;&#9;setsLists.Parent = sets
&#9;&#9;&#9;&#9;drillDownSetZIndex(controlFrame, 7)
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local setsHeader = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;&#9;&#9;setsHeader.Name = &quot;SetsHeader&quot;
&#9;&#9;&#9;&#9;setsHeader.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;setsHeader.Size = UDim2.new(0,47,0,24)
&#9;&#9;&#9;&#9;setsHeader.ZIndex = 6
&#9;&#9;&#9;&#9;setsHeader.Font = Enum.Font.ArialBold
&#9;&#9;&#9;&#9;setsHeader.FontSize = Enum.FontSize.Size24
&#9;&#9;&#9;&#9;setsHeader.Text = &quot;Sets&quot;
&#9;&#9;&#9;&#9;setsHeader.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;setsHeader.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;&#9;&#9;setsHeader.TextYAlignment = Enum.TextYAlignment.Top
&#9;&#9;&#9;&#9;setsHeader.Parent = sets
&#9;&#9;&#9;
&#9;&#9;&#9;local cancelButton = Instance.new(&quot;TextButton&quot;)
&#9;&#9;&#9;cancelButton.Name = &quot;CancelButton&quot;
&#9;&#9;&#9;cancelButton.Position = UDim2.new(1,-32,0,-2)
&#9;&#9;&#9;cancelButton.Size = UDim2.new(0,34,0,34)
&#9;&#9;&#9;cancelButton.Style = Enum.ButtonStyle.RobloxButtonDefault
&#9;&#9;&#9;cancelButton.ZIndex = 6
&#9;&#9;&#9;cancelButton.Text = &quot;&quot;
&#9;&#9;&#9;cancelButton.Modal = true
&#9;&#9;&#9;cancelButton.Parent = setPanel
&#9;&#9;&#9;
&#9;&#9;&#9;&#9;-- Children of Cancel Button
&#9;&#9;&#9;&#9;local cancelImage = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;&#9;&#9;cancelImage.Name = &quot;CancelImage&quot;
&#9;&#9;&#9;&#9;cancelImage.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;cancelImage.Image = &quot;http://www.roblox.com/asset/?id=54135717&quot;
&#9;&#9;&#9;&#9;cancelImage.Position = UDim2.new(0,-2,0,-2)
&#9;&#9;&#9;&#9;cancelImage.Size = UDim2.new(0,16,0,16)
&#9;&#9;&#9;&#9;cancelImage.ZIndex = 6
&#9;&#9;&#9;&#9;cancelImage.Parent = cancelButton
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;return setGui
&#9;end
&#9;
&#9;local function createSetButton(text)
&#9;&#9;local setButton = Instance.new(&quot;TextButton&quot;)
&#9;&#9;
&#9;&#9;if text then setButton.Text = text
&#9;&#9;else setButton.Text = &quot;&quot; end
&#9;&#9;
&#9;&#9;setButton.AutoButtonColor = false
&#9;&#9;setButton.BackgroundTransparency = 1
&#9;&#9;setButton.BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;setButton.BorderSizePixel = 0
&#9;&#9;setButton.Size = UDim2.new(1,-5,0,18)
&#9;&#9;setButton.ZIndex = 6
&#9;&#9;setButton.Visible = false
&#9;&#9;setButton.Font = Enum.Font.Arial
&#9;&#9;setButton.FontSize = Enum.FontSize.Size18
&#9;&#9;setButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;setButton.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;
&#9;&#9;return setButton
&#9;end
&#9;
&#9;local function buildSetButton(name, setId, setImageId, i, count)
&#9;&#9;local button = createSetButton(name)
&#9;&#9;button.Text = name
&#9;&#9;button.Name = &quot;SetButton&quot;
&#9;&#9;button.Visible = true
&#9;&#9;
&#9;&#9;local setValue = Instance.new(&quot;IntValue&quot;)
&#9;&#9;setValue.Name = &quot;SetId&quot;
&#9;&#9;setValue.Value = setId
&#9;&#9;setValue.Parent = button
&#9;&#9;local setName = Instance.new(&quot;StringValue&quot;)
&#9;&#9;setName.Name = &quot;SetName&quot;
&#9;&#9;setName.Value = name
&#9;&#9;setName.Parent = button
&#9;&#9;return button
&#9;end
&#9;
&#9;local function processCategory(sets)
&#9;&#9;local setButtons = {}
&#9;&#9;local numSkipped = 0
&#9;&#9;for i = 1, #sets do
&#9;&#9;&#9;if not showAdminCategories and sets[i].Name == &quot;Beta&quot; then
&#9;&#9;&#9;&#9;numSkipped = numSkipped + 1
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;setButtons[i - numSkipped] = buildSetButton(sets[i].Name, sets[i].CategoryId, sets[i].ImageAssetId, i - numSkipped, #sets)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;return setButtons
&#9;end
&#9;
&#9;local function handleResize()
&#9;&#9;wait() -- neccessary to insure heartbeat happened
&#9;&#9;
&#9;&#9;local itemPreview = setGui.SetPanel.ItemPreview
&#9;&#9;
&#9;&#9;itemPreview.LargePreview.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.X)
&#9;&#9;itemPreview.LargePreview.Position = UDim2.new(0.5,-itemPreview.LargePreview.AbsoluteSize.X/2,0,0)
&#9;&#9;itemPreview.TextPanel.Position = UDim2.new(0,0,0,itemPreview.LargePreview.AbsoluteSize.Y)
&#9;&#9;itemPreview.TextPanel.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.Y - itemPreview.LargePreview.AbsoluteSize.Y)
&#9;end
&#9;
&#9;local function makeInsertAssetButton()
&#9;&#9;local insertAssetButtonExample = Instance.new(&quot;Frame&quot;)
&#9;&#9;insertAssetButtonExample.Name = &quot;InsertAssetButtonExample&quot;
&#9;&#9;insertAssetButtonExample.Position = UDim2.new(0,128,0,64)
&#9;&#9;insertAssetButtonExample.Size = UDim2.new(0,64,0,64)
&#9;&#9;insertAssetButtonExample.BackgroundTransparency = 1
&#9;&#9;insertAssetButtonExample.ZIndex = 6
&#9;&#9;insertAssetButtonExample.Visible = false
&#9;&#9;local assetId = Instance.new(&quot;IntValue&quot;)
&#9;&#9;assetId.Name = &quot;AssetId&quot;
&#9;&#9;assetId.Value = 0
&#9;&#9;assetId.Parent = insertAssetButtonExample
&#9;&#9;
&#9;&#9;local assetName = Instance.new(&quot;StringValue&quot;)
&#9;&#9;assetName.Name = &quot;AssetName&quot;
&#9;&#9;assetName.Value = &quot;&quot;
&#9;&#9;assetName.Parent = insertAssetButtonExample
&#9;&#9;local button = Instance.new(&quot;TextButton&quot;)
&#9;&#9;button.Name = &quot;Button&quot;
&#9;&#9;button.Text = &quot;&quot;
&#9;&#9;button.Style = Enum.ButtonStyle.RobloxButton
&#9;&#9;button.Position = UDim2.new(0.025,0,0.025,0)
&#9;&#9;button.Size = UDim2.new(0.95,0,0.95,0)
&#9;&#9;button.ZIndex = 6
&#9;&#9;button.Parent = insertAssetButtonExample
&#9;&#9;local buttonImage = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;buttonImage.Name = &quot;ButtonImage&quot;
&#9;&#9;buttonImage.Image = &quot;&quot;
&#9;&#9;buttonImage.Position = UDim2.new(0,-7,0,-7)
&#9;&#9;buttonImage.Size = UDim2.new(1,14,1,14)
&#9;&#9;buttonImage.BackgroundTransparency = 1
&#9;&#9;buttonImage.ZIndex = 7
&#9;&#9;buttonImage.Parent = button
&#9;&#9;local configIcon = buttonImage:clone()
&#9;&#9;configIcon.Name = &quot;ConfigIcon&quot;
&#9;&#9;configIcon.Visible = false
&#9;&#9;configIcon.Position = UDim2.new(1,-23,1,-24)
&#9;&#9;configIcon.Size = UDim2.new(0,16,0,16)
&#9;&#9;configIcon.Image = &quot;&quot;
&#9;&#9;configIcon.ZIndex = 6
&#9;&#9;configIcon.Parent = insertAssetButtonExample
&#9;&#9;
&#9;&#9;return insertAssetButtonExample
&#9;end
&#9;
&#9;local function showLargePreview(insertButton)
&#9;&#9;if insertButton:FindFirstChild(&quot;AssetId&quot;) then
&#9;&#9;&#9;delay(0,function()
&#9;&#9;&#9;&#9;game:GetService(&quot;ContentProvider&quot;):Preload(LargeThumbnailUrl .. tostring(insertButton.AssetId.Value))
&#9;&#9;&#9;&#9;setGui.SetPanel.ItemPreview.LargePreview.Image = LargeThumbnailUrl .. tostring(insertButton.AssetId.Value)
&#9;&#9;&#9;end)
&#9;&#9;end
&#9;&#9;if insertButton:FindFirstChild(&quot;AssetName&quot;) then
&#9;&#9;&#9;setGui.SetPanel.ItemPreview.TextPanel.RolloverText.Text = insertButton.AssetName.Value
&#9;&#9;end
&#9;end
&#9;
&#9;local function selectTerrainShape(shape)
&#9;&#9;if currTerrainDropDownFrame then
&#9;&#9;&#9;objectSelected(tostring(currTerrainDropDownFrame.AssetName.Value), tonumber(currTerrainDropDownFrame.AssetId.Value), shape)
&#9;&#9;end
&#9;end
&#9;
&#9;local function createTerrainTypeButton(name, parent)
&#9;&#9;local dropDownTextButton = Instance.new(&quot;TextButton&quot;)
&#9;&#9;dropDownTextButton.Name = name .. &quot;Button&quot;
&#9;&#9;dropDownTextButton.Font = Enum.Font.ArialBold
&#9;&#9;dropDownTextButton.FontSize = Enum.FontSize.Size14
&#9;&#9;dropDownTextButton.BorderSizePixel = 0
&#9;&#9;dropDownTextButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;dropDownTextButton.Text = name
&#9;&#9;dropDownTextButton.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;dropDownTextButton.BackgroundTransparency = 1
&#9;&#9;dropDownTextButton.ZIndex = parent.ZIndex + 1
&#9;&#9;dropDownTextButton.Size = UDim2.new(0,parent.Size.X.Offset - 2,0,16)
&#9;&#9;dropDownTextButton.Position = UDim2.new(0,1,0,0)
&#9;&#9;dropDownTextButton.MouseEnter:connect(function()
&#9;&#9;&#9;dropDownTextButton.BackgroundTransparency = 0
&#9;&#9;&#9;dropDownTextButton.TextColor3 = Color3.new(0,0,0)
&#9;&#9;end)
&#9;&#9;dropDownTextButton.MouseLeave:connect(function()
&#9;&#9;&#9;dropDownTextButton.BackgroundTransparency = 1
&#9;&#9;&#9;dropDownTextButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;end)
&#9;&#9;dropDownTextButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;dropDownTextButton.BackgroundTransparency = 1
&#9;&#9;&#9;dropDownTextButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;if dropDownTextButton.Parent and dropDownTextButton.Parent:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;dropDownTextButton.Parent.Visible = false
&#9;&#9;&#9;end
&#9;&#9;&#9;selectTerrainShape(terrainShapeMap[dropDownTextButton.Text])
&#9;&#9;end)
&#9;&#9;return dropDownTextButton
&#9;end
&#9;
&#9;local function createTerrainDropDownMenu(zIndex)
&#9;&#9;local dropDown = Instance.new(&quot;Frame&quot;)
&#9;&#9;dropDown.Name = &quot;TerrainDropDown&quot;
&#9;&#9;dropDown.BackgroundColor3 = Color3.new(0,0,0)
&#9;&#9;dropDown.BorderColor3 = Color3.new(1,0,0)
&#9;&#9;dropDown.Size = UDim2.new(0,200,0,0)
&#9;&#9;dropDown.Visible = false
&#9;&#9;dropDown.ZIndex = zIndex
&#9;&#9;dropDown.Parent = setGui
&#9;&#9;for i = 1, #terrainShapes do
&#9;&#9;&#9;local shapeButton = createTerrainTypeButton(terrainShapes[i],dropDown)
&#9;&#9;&#9;shapeButton.Position = UDim2.new(0,1,0,(i - 1) * (shapeButton.Size.Y.Offset))
&#9;&#9;&#9;shapeButton.Parent = dropDown
&#9;&#9;&#9;dropDown.Size = UDim2.new(0,200,0,dropDown.Size.Y.Offset + (shapeButton.Size.Y.Offset))
&#9;&#9;end
&#9;&#9;dropDown.MouseLeave:connect(function()
&#9;&#9;&#9;dropDown.Visible = false
&#9;&#9;end)
&#9;end
&#9;
&#9;local function createDropDownMenuButton(parent)
&#9;&#9;local dropDownButton = Instance.new(&quot;ImageButton&quot;)
&#9;&#9;dropDownButton.Name = &quot;DropDownButton&quot;
&#9;&#9;dropDownButton.Image = &quot;http://www.roblox.com/asset/?id=67581509&quot;
&#9;&#9;dropDownButton.BackgroundTransparency = 1
&#9;&#9;dropDownButton.Size = UDim2.new(0,16,0,16)
&#9;&#9;dropDownButton.Position = UDim2.new(1,-24,0,6)
&#9;&#9;dropDownButton.ZIndex = parent.ZIndex + 2
&#9;&#9;dropDownButton.Parent = parent
&#9;&#9;
&#9;&#9;if not setGui:FindFirstChild(&quot;TerrainDropDown&quot;) then
&#9;&#9;&#9;createTerrainDropDownMenu(8)
&#9;&#9;end
&#9;&#9;
&#9;&#9;dropDownButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;setGui.TerrainDropDown.Visible = true
&#9;&#9;&#9;setGui.TerrainDropDown.Position = UDim2.new(0,parent.AbsolutePosition.X,0,parent.AbsolutePosition.Y)
&#9;&#9;&#9;currTerrainDropDownFrame = parent
&#9;&#9;end)
&#9;end
&#9;
&#9;local function buildInsertButton()
&#9;&#9;local insertButton = makeInsertAssetButton()
&#9;&#9;insertButton.Name = &quot;InsertAssetButton&quot;
&#9;&#9;insertButton.Visible = true
&#9;&#9;if Data.Category[Data.CurrentCategory].SetName == &quot;High Scalability&quot; then
&#9;&#9;&#9;createDropDownMenuButton(insertButton)
&#9;&#9;end
&#9;&#9;local lastEnter = nil
&#9;&#9;local mouseEnterCon = insertButton.MouseEnter:connect(function()
&#9;&#9;&#9;lastEnter = insertButton
&#9;&#9;&#9;delay(0.1,function()
&#9;&#9;&#9;&#9;if lastEnter == insertButton then
&#9;&#9;&#9;&#9;&#9;showLargePreview(insertButton)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;end)
&#9;&#9;return insertButton, mouseEnterCon
&#9;end
&#9;
&#9;local function realignButtonGrid(columns)
&#9;&#9;local x = 0
&#9;&#9;local y = 0
&#9;&#9;for i = 1, #insertButtons do
&#9;&#9;&#9;insertButtons[i].Position = UDim2.new(0, buttonWidth * x, 0, buttonHeight * y)
&#9;&#9;&#9;x = x + 1
&#9;&#9;&#9;if x &gt;= columns then
&#9;&#9;&#9;&#9;x = 0
&#9;&#9;&#9;&#9;y = y + 1
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local function setInsertButtonImageBehavior(insertFrame, visible, name, assetId)
&#9;&#9;if visible then
&#9;&#9;&#9;insertFrame.AssetName.Value = name
&#9;&#9;&#9;insertFrame.AssetId.Value = assetId
&#9;&#9;&#9;local newImageUrl = SmallThumbnailUrl .. assetId
&#9;&#9;&#9;if newImageUrl ~= insertFrame.Button.ButtonImage.Image then
&#9;&#9;&#9;&#9;delay(0,function()
&#9;&#9;&#9;&#9;&#9;game:GetService(&quot;ContentProvider&quot;):Preload(SmallThumbnailUrl .. assetId)
&#9;&#9;&#9;&#9;&#9;if insertFrame:findFirstChild(&quot;Button&quot;) then
&#9;&#9;&#9;&#9;&#9;&#9;insertFrame.Button.ButtonImage.Image = SmallThumbnailUrl .. assetId
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;&#9;table.insert(insertButtonCons,
&#9;&#9;&#9;&#9;insertFrame.Button.MouseButton1Click:connect(function()
&#9;&#9;&#9;&#9;&#9;-- special case for water, show water selection gui
&#9;&#9;&#9;&#9;&#9;local isWaterSelected = (name == &quot;Water&quot;) and (Data.Category[Data.CurrentCategory].SetName == &quot;High Scalability&quot;)
&#9;&#9;&#9;&#9;&#9;waterGui.Visible = isWaterSelected
&#9;&#9;&#9;&#9;&#9;if isWaterSelected then
&#9;&#9;&#9;&#9;&#9;&#9;objectSelected(name, tonumber(assetId), nil)
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;objectSelected(name, tonumber(assetId))
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;)
&#9;&#9;&#9;insertFrame.Visible = true
&#9;&#9;else
&#9;&#9;&#9;insertFrame.Visible = false
&#9;&#9;end
&#9;end
&#9;
&#9;local function loadSectionOfItems(setGui, rows, columns)
&#9;&#9;local pageSize = rows * columns
&#9;&#9;if arrayPosition &gt; #contents then return end
&#9;&#9;local origArrayPos = arrayPosition
&#9;&#9;local yCopy = 0
&#9;&#9;for i = 1, pageSize + 1 do
&#9;&#9;&#9;if arrayPosition &gt;= #contents + 1 then
&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;end
&#9;&#9;&#9;local buttonCon
&#9;&#9;&#9;insertButtons[arrayPosition], buttonCon = buildInsertButton()
&#9;&#9;&#9;table.insert(insertButtonCons,buttonCon)
&#9;&#9;&#9;insertButtons[arrayPosition].Parent = setGui.SetPanel.ItemsFrame
&#9;&#9;&#9;arrayPosition = arrayPosition + 1
&#9;&#9;end
&#9;&#9;realignButtonGrid(columns)
&#9;&#9;local indexCopy = origArrayPos
&#9;&#9;for index = origArrayPos, arrayPosition do
&#9;&#9;&#9;if insertButtons[index] then
&#9;&#9;&#9;&#9;if contents[index] then
&#9;&#9;&#9;&#9;&#9;-- we don&apos;t want water to have a drop down button
&#9;&#9;&#9;&#9;&#9;if contents[index].Name == &quot;Water&quot; then
&#9;&#9;&#9;&#9;&#9;&#9;if Data.Category[Data.CurrentCategory].SetName == &quot;High Scalability&quot; then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;insertButtons[index]:FindFirstChild(&quot;DropDownButton&quot;,true):Destroy()
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;local assetId
&#9;&#9;&#9;&#9;&#9;if useAssetVersionId then
&#9;&#9;&#9;&#9;&#9;&#9;assetId = contents[index].AssetVersionId
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;assetId = contents[index].AssetId
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;setInsertButtonImageBehavior(insertButtons[index], true, contents[index].Name, assetId)
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;end
&#9;&#9;&#9;indexCopy = index
&#9;&#9;end
&#9;end
&#9;
&#9;local function setSetIndex()
&#9;&#9;Data.Category[Data.CurrentCategory].Index = 0
&#9;&#9;rows = 7
&#9;&#9;columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth)
&#9;&#9;contents = Data.Category[Data.CurrentCategory].Contents
&#9;&#9;if contents then
&#9;&#9;&#9;-- remove our buttons and their connections
&#9;&#9;&#9;for i = 1, #insertButtons do
&#9;&#9;&#9;&#9;insertButtons[i]:remove()
&#9;&#9;&#9;end
&#9;&#9;&#9;for i = 1, #insertButtonCons do
&#9;&#9;&#9;&#9;if insertButtonCons[i] then insertButtonCons[i]:disconnect() end
&#9;&#9;&#9;end
&#9;&#9;&#9;insertButtonCons = {}
&#9;&#9;&#9;insertButtons = {}
&#9;&#9;&#9;arrayPosition = 1
&#9;&#9;&#9;loadSectionOfItems(setGui, rows, columns)
&#9;&#9;end
&#9;end
&#9;
&#9;local function selectSet(button, setName, setId, setIndex)
&#9;&#9;if button and Data.Category[Data.CurrentCategory] ~= nil then
&#9;&#9;&#9;if button ~= Data.Category[Data.CurrentCategory].Button then
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory].Button = button
&#9;&#9;&#9;&#9;if SetCache[setId] == nil then
&#9;&#9;&#9;&#9;&#9;SetCache[setId] = game:GetService(&quot;InsertService&quot;):GetCollection(setId)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory].Contents = SetCache[setId]
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory].SetName = setName
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory].SetId = setId
&#9;&#9;&#9;end
&#9;&#9;&#9;setSetIndex()
&#9;&#9;end
&#9;end
&#9;
&#9;local function selectCategoryPage(buttons, page)
&#9;&#9;if buttons ~= Data.CurrentCategory then
&#9;&#9;&#9;if Data.CurrentCategory then
&#9;&#9;&#9;&#9;for key, button in pairs(Data.CurrentCategory) do
&#9;&#9;&#9;&#9;&#9;button.Visible = false
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;Data.CurrentCategory = buttons
&#9;&#9;&#9;if Data.Category[Data.CurrentCategory] == nil then
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory] = {}
&#9;&#9;&#9;&#9;if #buttons &gt; 0 then
&#9;&#9;&#9;&#9;&#9;selectSet(buttons[1], buttons[1].SetName.Value, buttons[1].SetId.Value, 0)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory].Button = nil
&#9;&#9;&#9;&#9;selectSet(Data.Category[Data.CurrentCategory].ButtonFrame, Data.Category[Data.CurrentCategory].SetName, Data.Category[Data.CurrentCategory].SetId, Data.Category[Data.CurrentCategory].Index)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;
&#9;local function selectCategory(category)
&#9;&#9;selectCategoryPage(category, 0)
&#9;end
&#9;
&#9;local function resetAllSetButtonSelection()
&#9;&#9;local setButtons = setGui.SetPanel.Sets.SetsLists:GetChildren()
&#9;&#9;for i = 1, #setButtons do
&#9;&#9;&#9;if setButtons[i]:IsA(&quot;TextButton&quot;) then
&#9;&#9;&#9;&#9;setButtons[i].Selected = false
&#9;&#9;&#9;&#9;setButtons[i].BackgroundTransparency = 1
&#9;&#9;&#9;&#9;setButtons[i].TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;setButtons[i].BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;
&#9;local function populateSetsFrame()
&#9;&#9;local currRow = 0
&#9;&#9;for i = 1, #userCategoryButtons do
&#9;&#9;&#9;local button = userCategoryButtons[i]
&#9;&#9;&#9;button.Visible = true
&#9;&#9;&#9;button.Position = UDim2.new(0,5,0,currRow * button.Size.Y.Offset)
&#9;&#9;&#9;button.Parent = setGui.SetPanel.Sets.SetsLists
&#9;&#9;&#9;
&#9;&#9;&#9;if i == 1 then -- we will have this selected by default, so show it
&#9;&#9;&#9;&#9;button.Selected = true
&#9;&#9;&#9;&#9;button.BackgroundColor3 = Color3.new(0,204/255,0)
&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(0,0,0)
&#9;&#9;&#9;&#9;button.BackgroundTransparency = 0
&#9;&#9;&#9;end
&#9;&#9;&#9;button.MouseEnter:connect(function()
&#9;&#9;&#9;&#9;if not button.Selected then
&#9;&#9;&#9;&#9;&#9;button.BackgroundTransparency = 0
&#9;&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(0,0,0)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;&#9;button.MouseLeave:connect(function()
&#9;&#9;&#9;&#9;if not button.Selected then
&#9;&#9;&#9;&#9;&#9;button.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;&#9;button.MouseButton1Click:connect(function()
&#9;&#9;&#9;&#9;resetAllSetButtonSelection()
&#9;&#9;&#9;&#9;button.Selected = not button.Selected
&#9;&#9;&#9;&#9;button.BackgroundColor3 = Color3.new(0,204/255,0)
&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(0,0,0)
&#9;&#9;&#9;&#9;button.BackgroundTransparency = 0
&#9;&#9;&#9;&#9;selectSet(button, button.Text, userCategoryButtons[i].SetId.Value, 0)
&#9;&#9;&#9;end)
&#9;&#9;&#9;currRow = currRow + 1
&#9;&#9;end
&#9;&#9;local buttons = setGui.SetPanel.Sets.SetsLists:GetChildren()
&#9;&#9;-- set first category as loaded for default
&#9;&#9;if buttons then
&#9;&#9;&#9;for i = 1, #buttons do
&#9;&#9;&#9;&#9;if buttons[i]:IsA(&quot;TextButton&quot;) then
&#9;&#9;&#9;&#9;&#9;selectSet(buttons[i], buttons[i].Text, userCategoryButtons[i].SetId.Value, 0)
&#9;&#9;&#9;&#9;&#9;selectCategory(userCategoryButtons)
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;setGui = createSetGui()
&#9;waterGui, waterTypeChangedEvent = createWaterGui()
&#9;waterGui.Position = UDim2.new(0,55,0,0)
&#9;waterGui.Parent = setGui
&#9;setGui.Changed:connect(function(prop) -- this resizes the preview image to always be the right size
&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;handleResize()
&#9;&#9;&#9;setSetIndex()
&#9;&#9;end
&#9;end)
&#9;
&#9;local scrollFrame, controlFrame = t.CreateTrueScrollingFrame()
&#9;scrollFrame.Size = UDim2.new(0.54,0,0.85,0)
&#9;scrollFrame.Position = UDim2.new(0.24,0,0.085,0)
&#9;scrollFrame.Name = &quot;ItemsFrame&quot;
&#9;scrollFrame.ZIndex = 6
&#9;scrollFrame.Parent = setGui.SetPanel
&#9;scrollFrame.BackgroundTransparency = 1
&#9;drillDownSetZIndex(controlFrame,7)
&#9;controlFrame.Parent = setGui.SetPanel
&#9;controlFrame.Position = UDim2.new(0.76, 5, 0, 0)
&#9;local debounce = false
&#9;controlFrame.ScrollBottom.Changed:connect(function(prop)
&#9;&#9;if controlFrame.ScrollBottom.Value == true then
&#9;&#9;&#9;if debounce then return end
&#9;&#9;&#9;debounce = true
&#9;&#9;&#9;&#9;loadSectionOfItems(setGui, rows, columns)
&#9;&#9;&#9;debounce = false
&#9;&#9;end
&#9;end)
&#9;local userData = {}
&#9;for id = 1, #userIdsForSets do
&#9;&#9;local newUserData = game:GetService(&quot;InsertService&quot;):GetUserSets(userIdsForSets[id])
&#9;&#9;if newUserData and #newUserData &gt; 2 then
&#9;&#9;&#9;-- start at #3 to skip over My Decals and My Models for each account
&#9;&#9;&#9;for category = 3, #newUserData do
&#9;&#9;&#9;&#9;if newUserData[category].Name == &quot;High Scalability&quot; then -- we want high scalability parts to show first
&#9;&#9;&#9;&#9;&#9;table.insert(userData,1,newUserData[category])
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;table.insert(userData, newUserData[category])
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;
&#9;end
&#9;if userData then
&#9;&#9;userCategoryButtons = processCategory(userData)
&#9;end
&#9;rows = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.Y/buttonHeight)
&#9;columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth)
&#9;populateSetsFrame()
&#9;insertPanelCloseCon = setGui.SetPanel.CancelButton.MouseButton1Click:connect(function()
&#9;&#9;setGui.SetPanel.Visible = false
&#9;&#9;if dialogClosed then dialogClosed() end
&#9;end)
&#9;
&#9;local setVisibilityFunction = function(visible)
&#9;&#9;if visible then
&#9;&#9;&#9;setGui.SetPanel.Visible = true
&#9;&#9;else
&#9;&#9;&#9;setGui.SetPanel.Visible = false
&#9;&#9;end
&#9;end
&#9;
&#9;local getVisibilityFunction = function()
&#9;&#9;if setGui then
&#9;&#9;&#9;if setGui:FindFirstChild(&quot;SetPanel&quot;) then
&#9;&#9;&#9;&#9;return setGui.SetPanel.Visible
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;
&#9;&#9;return false
&#9;end
&#9;
&#9;return setGui, setVisibilityFunction, getVisibilityFunction, waterTypeChangedEvent
end
t.CreateTerrainMaterialSelector = function(size,position)
&#9;local terrainMaterialSelectionChanged = Instance.new(&quot;BindableEvent&quot;)
&#9;terrainMaterialSelectionChanged.Name = &quot;TerrainMaterialSelectionChanged&quot;
&#9;local selectedButton = nil
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Name = &quot;TerrainMaterialSelector&quot;
&#9;if size then
&#9;&#9;frame.Size = size
&#9;else
&#9;&#9;frame.Size = UDim2.new(0, 245, 0, 230)
&#9;end
&#9;if position then
&#9;&#9;frame.Position = position
&#9;end
&#9;frame.BorderSizePixel = 0
&#9;frame.BackgroundColor3 = Color3.new(0,0,0)
&#9;frame.Active = true
&#9;terrainMaterialSelectionChanged.Parent = frame
&#9;local waterEnabled = true -- todo: turn this on when water is ready
&#9;local materialToImageMap = {}
&#9;local materialNames = {&quot;Grass&quot;, &quot;Sand&quot;, &quot;Brick&quot;, &quot;Granite&quot;, &quot;Asphalt&quot;, &quot;Iron&quot;, &quot;Aluminum&quot;, &quot;Gold&quot;, &quot;Plank&quot;, &quot;Log&quot;, &quot;Gravel&quot;, &quot;Cinder Block&quot;, &quot;Stone Wall&quot;, &quot;Concrete&quot;, &quot;Plastic (red)&quot;, &quot;Plastic (blue)&quot;}
&#9;if waterEnabled then
&#9;&#9;table.insert(materialNames,&quot;Water&quot;)
&#9;end
&#9;local currentMaterial = 1
&#9;function getEnumFromName(choice)
&#9;&#9;if choice == &quot;Grass&quot; then return 1 end
&#9;&#9;if choice == &quot;Sand&quot; then return 2 end
&#9;&#9;if choice == &quot;Erase&quot; then return 0 end
&#9;&#9;if choice == &quot;Brick&quot; then return 3 end
&#9;&#9;if choice == &quot;Granite&quot; then return 4 end
&#9;&#9;if choice == &quot;Asphalt&quot; then return 5 end
&#9;&#9;if choice == &quot;Iron&quot; then return 6 end
&#9;&#9;if choice == &quot;Aluminum&quot; then return 7 end
&#9;&#9;if choice == &quot;Gold&quot; then return 8 end
&#9;&#9;if choice == &quot;Plank&quot; then return 9 end
&#9;&#9;if choice == &quot;Log&quot; then return 10 end
&#9;&#9;if choice == &quot;Gravel&quot; then return 11 end
&#9;&#9;if choice == &quot;Cinder Block&quot; then return 12 end
&#9;&#9;if choice == &quot;Stone Wall&quot; then return 13 end
&#9;&#9;if choice == &quot;Concrete&quot; then return 14 end
&#9;&#9;if choice == &quot;Plastic (red)&quot; then return 15 end
&#9;&#9;if choice == &quot;Plastic (blue)&quot; then return 16 end
&#9;&#9;if choice == &quot;Water&quot; then return 17 end
&#9;end
&#9;function getNameFromEnum(choice)
&#9;&#9;if choice == Enum.CellMaterial.Grass or choice == 1 then return &quot;Grass&quot;end
&#9;&#9;if choice == Enum.CellMaterial.Sand or choice == 2 then return &quot;Sand&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Empty or choice == 0 then return &quot;Erase&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Brick or choice == 3 then return &quot;Brick&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Granite or choice == 4 then return &quot;Granite&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Asphalt or choice == 5 then return &quot;Asphalt&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Iron or choice == 6 then return &quot;Iron&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Aluminum or choice == 7 then return &quot;Aluminum&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Gold or choice == 8 then return &quot;Gold&quot; end
&#9;&#9;if choice == Enum.CellMaterial.WoodPlank or choice == 9 then return &quot;Plank&quot; end
&#9;&#9;if choice == Enum.CellMaterial.WoodLog or choice == 10 then return &quot;Log&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Gravel or choice == 11 then return &quot;Gravel&quot; end
&#9;&#9;if choice == Enum.CellMaterial.CinderBlock or choice == 12 then return &quot;Cinder Block&quot; end
&#9;&#9;if choice == Enum.CellMaterial.MossyStone or choice == 13 then return &quot;Stone Wall&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Cement or choice == 14 then return &quot;Concrete&quot; end
&#9;&#9;if choice == Enum.CellMaterial.RedPlastic or choice == 15 then return &quot;Plastic (red)&quot; end
&#9;&#9;if choice == Enum.CellMaterial.BluePlastic or choice == 16 then return &quot;Plastic (blue)&quot; end
&#9;&#9;if waterEnabled then
&#9;&#9;&#9;if choice == Enum.CellMaterial.Water or choice == 17 then return &quot;Water&quot; end
&#9;&#9;end
&#9;end
&#9;local function updateMaterialChoice(choice)
&#9;&#9;currentMaterial = getEnumFromName(choice)
&#9;&#9;terrainMaterialSelectionChanged:Fire(currentMaterial)
&#9;end
&#9;-- we so need a better way to do this
&#9;for i,v in pairs(materialNames) do
&#9;&#9;materialToImageMap[v] = {}
&#9;&#9;if v == &quot;Grass&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=56563112&quot;
&#9;&#9;elseif v == &quot;Sand&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=62356652&quot;
&#9;&#9;elseif v == &quot;Brick&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=65961537&quot;
&#9;&#9;elseif v == &quot;Granite&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532153&quot;
&#9;&#9;elseif v == &quot;Asphalt&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532038&quot;
&#9;&#9;elseif v == &quot;Iron&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532093&quot;
&#9;&#9;elseif v == &quot;Aluminum&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67531995&quot;
&#9;&#9;elseif v == &quot;Gold&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532118&quot;
&#9;&#9;elseif v == &quot;Plastic (red)&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67531848&quot;
&#9;&#9;elseif v == &quot;Plastic (blue)&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67531924&quot;
&#9;&#9;elseif v == &quot;Plank&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532015&quot;
&#9;&#9;elseif v == &quot;Log&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532051&quot;
&#9;&#9;elseif v == &quot;Gravel&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532206&quot;
&#9;&#9;elseif v == &quot;Cinder Block&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532103&quot;
&#9;&#9;elseif v == &quot;Stone Wall&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67531804&quot;
&#9;&#9;elseif v == &quot;Concrete&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532059&quot;
&#9;&#9;elseif v == &quot;Water&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=81407474&quot;
&#9;&#9;else materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=66887593&quot; -- fill in the rest here!!
&#9;&#9;end
&#9;end
&#9;local scrollFrame, scrollUp, scrollDown, recalculateScroll = t.CreateScrollingFrame(nil,&quot;grid&quot;)
&#9;scrollFrame.Size = UDim2.new(0.85,0,1,0)
&#9;scrollFrame.Position = UDim2.new(0,0,0,0)
&#9;scrollFrame.Parent = frame
&#9;scrollUp.Parent = frame
&#9;scrollUp.Visible = true
&#9;scrollUp.Position = UDim2.new(1,-19,0,0)
&#9;scrollDown.Parent = frame
&#9;scrollDown.Visible = true
&#9;scrollDown.Position = UDim2.new(1,-19,1,-17)
&#9;local function goToNewMaterial(buttonWrap, materialName)
&#9;&#9;updateMaterialChoice(materialName)
&#9;&#9;buttonWrap.BackgroundTransparency = 0
&#9;&#9;selectedButton.BackgroundTransparency = 1
&#9;&#9;selectedButton = buttonWrap
&#9;end
&#9;local function createMaterialButton(name)&#9;
&#9;&#9;local buttonWrap = Instance.new(&quot;TextButton&quot;)
&#9;&#9;buttonWrap.Text = &quot;&quot;
&#9;&#9;buttonWrap.Size = UDim2.new(0,32,0,32)
&#9;&#9;buttonWrap.BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;buttonWrap.BorderSizePixel = 0
&#9;&#9;buttonWrap.BackgroundTransparency = 1
&#9;&#9;buttonWrap.AutoButtonColor = false
&#9;&#9;buttonWrap.Name = tostring(name)
&#9;&#9;
&#9;&#9;local imageButton = Instance.new(&quot;ImageButton&quot;)
&#9;&#9;imageButton.AutoButtonColor = false
&#9;&#9;imageButton.BackgroundTransparency = 1
&#9;&#9;imageButton.Size = UDim2.new(0,30,0,30)
&#9;&#9;imageButton.Position = UDim2.new(0,1,0,1)
&#9;&#9;imageButton.Name = tostring(name)
&#9;&#9;imageButton.Parent = buttonWrap
&#9;&#9;imageButton.Image = materialToImageMap[name].Regular
&#9;&#9;local enumType = Instance.new(&quot;NumberValue&quot;)
&#9;&#9;enumType.Name = &quot;EnumType&quot;
&#9;&#9;enumType.Parent = buttonWrap
&#9;&#9;enumType.Value = 0
&#9;&#9;
&#9;&#9;imageButton.MouseEnter:connect(function()
&#9;&#9;&#9;buttonWrap.BackgroundTransparency = 0
&#9;&#9;end)
&#9;&#9;imageButton.MouseLeave:connect(function()
&#9;&#9;&#9;if selectedButton ~= buttonWrap then
&#9;&#9;&#9;&#9;buttonWrap.BackgroundTransparency = 1
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;&#9;imageButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;if selectedButton ~= buttonWrap then
&#9;&#9;&#9;&#9;goToNewMaterial(buttonWrap, tostring(name))
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;&#9;
&#9;&#9;return buttonWrap
&#9;end
&#9;for i = 1, #materialNames do
&#9;&#9;local imageButton = createMaterialButton(materialNames[i])
&#9;&#9;
&#9;&#9;if materialNames[i] == &quot;Grass&quot; then -- always start with grass as the default
&#9;&#9;&#9;selectedButton = imageButton
&#9;&#9;&#9;imageButton.BackgroundTransparency = 0
&#9;&#9;end
&#9;&#9;
&#9;&#9;imageButton.Parent = scrollFrame
&#9;end
&#9;local forceTerrainMaterialSelection = function(newMaterialType)
&#9;&#9;if not newMaterialType then return end
&#9;&#9;if currentMaterial == newMaterialType then return end
&#9;&#9;local matName = getNameFromEnum(newMaterialType)
&#9;&#9;local buttons = scrollFrame:GetChildren()
&#9;&#9;for i = 1, #buttons do
&#9;&#9;&#9;if buttons[i].Name == &quot;Plastic (blue)&quot; and matName == &quot;Plastic (blue)&quot; then goToNewMaterial(buttons[i],matName) return end
&#9;&#9;&#9;if buttons[i].Name == &quot;Plastic (red)&quot; and matName == &quot;Plastic (red)&quot; then goToNewMaterial(buttons[i],matName) return end
&#9;&#9;&#9;if string.find(buttons[i].Name, matName) then
&#9;&#9;&#9;&#9;goToNewMaterial(buttons[i],matName)
&#9;&#9;&#9;&#9;return
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;frame.Changed:connect(function ( prop )
&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;recalculateScroll()
&#9;&#9;end
&#9;end)
&#9;recalculateScroll()
&#9;return frame, terrainMaterialSelectionChanged, forceTerrainMaterialSelection
end
t.CreateLoadingFrame = function(name,size,position)
&#9;game:GetService(&quot;ContentProvider&quot;):Preload(&quot;http://www.roblox.com/asset/?id=35238053&quot;)
&#9;local loadingFrame = Instance.new(&quot;Frame&quot;)
&#9;loadingFrame.Name = &quot;LoadingFrame&quot;
&#9;loadingFrame.Style = Enum.FrameStyle.RobloxRound
&#9;if size then loadingFrame.Size = size
&#9;else loadingFrame.Size = UDim2.new(0,300,0,160) end
&#9;if position then loadingFrame.Position = position
&#9;else loadingFrame.Position = UDim2.new(0.5, -150, 0.5,-80) end
&#9;local loadingBar = Instance.new(&quot;Frame&quot;)
&#9;loadingBar.Name = &quot;LoadingBar&quot;
&#9;loadingBar.BackgroundColor3 = Color3.new(0,0,0)
&#9;loadingBar.BorderColor3 = Color3.new(79/255,79/255,79/255)
&#9;loadingBar.Position = UDim2.new(0,0,0,41)
&#9;loadingBar.Size = UDim2.new(1,0,0,30)
&#9;loadingBar.Parent = loadingFrame
&#9;&#9;local loadingGreenBar = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;loadingGreenBar.Name = &quot;LoadingGreenBar&quot;
&#9;&#9;loadingGreenBar.Image = &quot;http://www.roblox.com/asset/?id=35238053&quot;
&#9;&#9;loadingGreenBar.Position = UDim2.new(0,0,0,0)
&#9;&#9;loadingGreenBar.Size = UDim2.new(0,0,1,0)
&#9;&#9;loadingGreenBar.Visible = false
&#9;&#9;loadingGreenBar.Parent = loadingBar
&#9;&#9;local loadingPercent = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;loadingPercent.Name = &quot;LoadingPercent&quot;
&#9;&#9;loadingPercent.BackgroundTransparency = 1
&#9;&#9;loadingPercent.Position = UDim2.new(0,0,1,0)
&#9;&#9;loadingPercent.Size = UDim2.new(1,0,0,14)
&#9;&#9;loadingPercent.Font = Enum.Font.Arial
&#9;&#9;loadingPercent.Text = &quot;0%&quot;
&#9;&#9;loadingPercent.FontSize = Enum.FontSize.Size14
&#9;&#9;loadingPercent.TextColor3 = Color3.new(1,1,1)
&#9;&#9;loadingPercent.Parent = loadingBar
&#9;local cancelButton = Instance.new(&quot;TextButton&quot;)
&#9;cancelButton.Name = &quot;CancelButton&quot;
&#9;cancelButton.Position = UDim2.new(0.5,-60,1,-40)
&#9;cancelButton.Size = UDim2.new(0,120,0,40)
&#9;cancelButton.Font = Enum.Font.Arial
&#9;cancelButton.FontSize = Enum.FontSize.Size18
&#9;cancelButton.TextColor3 = Color3.new(1,1,1)
&#9;cancelButton.Text = &quot;Cancel&quot;
&#9;cancelButton.Style = Enum.ButtonStyle.RobloxButton
&#9;cancelButton.Parent = loadingFrame
&#9;local loadingName = Instance.new(&quot;TextLabel&quot;)
&#9;loadingName.Name = &quot;loadingName&quot;
&#9;loadingName.BackgroundTransparency = 1
&#9;loadingName.Size = UDim2.new(1,0,0,18)
&#9;loadingName.Position = UDim2.new(0,0,0,2)
&#9;loadingName.Font = Enum.Font.Arial
&#9;loadingName.Text = name
&#9;loadingName.TextColor3 = Color3.new(1,1,1)
&#9;loadingName.TextStrokeTransparency = 1
&#9;loadingName.FontSize = Enum.FontSize.Size18
&#9;loadingName.Parent = loadingFrame
&#9;local cancelButtonClicked = Instance.new(&quot;BindableEvent&quot;)
&#9;cancelButtonClicked.Name = &quot;CancelButtonClicked&quot;
&#9;cancelButtonClicked.Parent = cancelButton
&#9;cancelButton.MouseButton1Click:connect(function()
&#9;&#9;cancelButtonClicked:Fire()
&#9;end)
&#9;local updateLoadingGuiPercent = function(percent, tweenAction, tweenLength)
&#9;&#9;if percent and type(percent) ~= &quot;number&quot; then
&#9;&#9;&#9;error(&quot;updateLoadingGuiPercent expects number as argument, got&quot;,type(percent),&quot;instead&quot;)
&#9;&#9;end
&#9;&#9;local newSize = nil
&#9;&#9;if percent &lt; 0 then
&#9;&#9;&#9;newSize = UDim2.new(0,0,1,0)
&#9;&#9;elseif percent &gt; 1 then
&#9;&#9;&#9;newSize = UDim2.new(1,0,1,0)
&#9;&#9;else
&#9;&#9;&#9;newSize = UDim2.new(percent,0,1,0)
&#9;&#9;end
&#9;&#9;if tweenAction then
&#9;&#9;&#9;if not tweenLength then
&#9;&#9;&#9;&#9;error(&quot;updateLoadingGuiPercent is set to tween new percentage, but got no tween time length! Please pass this in as third argument&quot;)
&#9;&#9;&#9;end
&#9;&#9;&#9;if (newSize.X.Scale &gt; 0) then
&#9;&#9;&#9;&#9;loadingGreenBar.Visible = true
&#9;&#9;&#9;&#9;loadingGreenBar:TweenSize(&#9;newSize,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Enum.EasingDirection.Out,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Enum.EasingStyle.Quad,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;tweenLength,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;true)
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;loadingGreenBar:TweenSize(&#9;newSize,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Enum.EasingDirection.Out,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Enum.EasingStyle.Quad,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;tweenLength,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;if (newSize.X.Scale &lt; 0) then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;loadingGreenBar.Visible = false
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;loadingGreenBar.Size = newSize
&#9;&#9;&#9;loadingGreenBar.Visible = (newSize.X.Scale &gt; 0)
&#9;&#9;end
&#9;end
&#9;loadingGreenBar.Changed:connect(function(prop)
&#9;&#9;if prop == &quot;Size&quot; then
&#9;&#9;&#9;loadingPercent.Text = tostring( math.ceil(loadingGreenBar.Size.X.Scale * 100) ) .. &quot;%&quot;
&#9;&#9;end
&#9;end)
&#9;return loadingFrame, updateLoadingGuiPercent, cancelButtonClicked
end
t.CreatePluginFrame = function (name,size,position,scrollable,parent)
&#9;function createMenuButton(size,position,text,fontsize,name,parent)
&#9;&#9;local button = Instance.new(&quot;TextButton&quot;,parent)
&#9;&#9;button.AutoButtonColor = false
&#9;&#9;button.Name = name
&#9;&#9;button.BackgroundTransparency = 1
&#9;&#9;button.Position = position
&#9;&#9;button.Size = size
&#9;&#9;button.Font = Enum.Font.ArialBold
&#9;&#9;button.FontSize = fontsize
&#9;&#9;button.Text = text
&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;button.BorderSizePixel = 0
&#9;&#9;button.BackgroundColor3 = Color3.new(20/255,20/255,20/255)
&#9;&#9;button.MouseEnter:connect(function ( )
&#9;&#9;&#9;if button.Selected then return end
&#9;&#9;&#9;button.BackgroundTransparency = 0
&#9;&#9;end)
&#9;&#9;button.MouseLeave:connect(function ( )
&#9;&#9;&#9;if button.Selected then return end
&#9;&#9;&#9;button.BackgroundTransparency = 1
&#9;&#9;end)
&#9;&#9;return button
&#9;end
&#9;local dragBar = Instance.new(&quot;Frame&quot;,parent)
&#9;dragBar.Name = tostring(name) .. &quot;DragBar&quot;
&#9;dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255)
&#9;dragBar.BorderColor3 = Color3.new(0,0,0)
&#9;if size then
&#9;&#9;dragBar.Size = UDim2.new(size.X.Scale,size.X.Offset,0,20) + UDim2.new(0,20,0,0)
&#9;else
&#9;&#9;dragBar.Size = UDim2.new(0,183,0,20)
&#9;end
&#9;if position then
&#9;&#9;dragBar.Position = position
&#9;end
&#9;dragBar.Active = true
&#9;dragBar.Draggable = true
&#9;--dragBar.Visible = false
&#9;dragBar.MouseEnter:connect(function ( )
&#9;&#9;dragBar.BackgroundColor3 = Color3.new(49/255,49/255,49/255)
&#9;end)
&#9;dragBar.MouseLeave:connect(function ( )
&#9;&#9;dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255)
&#9;end)
&#9;-- plugin name label
&#9;local pluginNameLabel = Instance.new(&quot;TextLabel&quot;,dragBar)
&#9;pluginNameLabel.Name = &quot;BarNameLabel&quot;
&#9;pluginNameLabel.Text = &quot; &quot; .. tostring(name)
&#9;pluginNameLabel.TextColor3 = Color3.new(1,1,1)
&#9;pluginNameLabel.TextStrokeTransparency = 0
&#9;pluginNameLabel.Size = UDim2.new(1,0,1,0)
&#9;pluginNameLabel.Font = Enum.Font.ArialBold
&#9;pluginNameLabel.FontSize = Enum.FontSize.Size18
&#9;pluginNameLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;pluginNameLabel.BackgroundTransparency = 1
&#9;-- close button
&#9;local closeButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-16,0.5,-8),&quot;X&quot;,Enum.FontSize.Size14,&quot;CloseButton&quot;,dragBar)
&#9;local closeEvent = Instance.new(&quot;BindableEvent&quot;)
&#9;closeEvent.Name = &quot;CloseEvent&quot;
&#9;closeEvent.Parent = closeButton
&#9;closeButton.MouseButton1Click:connect(function ()
&#9;&#9;closeEvent:Fire()
&#9;&#9;closeButton.BackgroundTransparency = 1
&#9;end)
&#9;-- help button
&#9;local helpButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-51,0.5,-8),&quot;?&quot;,Enum.FontSize.Size14,&quot;HelpButton&quot;,dragBar)
&#9;local helpFrame = Instance.new(&quot;Frame&quot;,dragBar)
&#9;helpFrame.Name = &quot;HelpFrame&quot;
&#9;helpFrame.BackgroundColor3 = Color3.new(0,0,0)
&#9;helpFrame.Size = UDim2.new(0,300,0,552)
&#9;helpFrame.Position = UDim2.new(1,5,0,0)
&#9;helpFrame.Active = true
&#9;helpFrame.BorderSizePixel = 0
&#9;helpFrame.Visible = false
&#9;helpButton.MouseButton1Click:connect(function( )
&#9;&#9;helpFrame.Visible = not helpFrame.Visible
&#9;&#9;if helpFrame.Visible then
&#9;&#9;&#9;helpButton.Selected = true
&#9;&#9;&#9;helpButton.BackgroundTransparency = 0
&#9;&#9;&#9;local screenGui = getScreenGuiAncestor(helpFrame)
&#9;&#9;&#9;if screenGui then
&#9;&#9;&#9;&#9;if helpFrame.AbsolutePosition.X + helpFrame.AbsoluteSize.X &gt; screenGui.AbsoluteSize.X then --position on left hand side
&#9;&#9;&#9;&#9;&#9;helpFrame.Position = UDim2.new(0,-5 - helpFrame.AbsoluteSize.X,0,0)
&#9;&#9;&#9;&#9;else -- position on right hand side
&#9;&#9;&#9;&#9;&#9;helpFrame.Position = UDim2.new(1,5,0,0)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;helpFrame.Position = UDim2.new(1,5,0,0)
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;helpButton.Selected = false
&#9;&#9;&#9;helpButton.BackgroundTransparency = 1
&#9;&#9;end
&#9;end)
&#9;local minimizeButton = createMenuButton(UDim2.new(0,16,0,17),UDim2.new(1,-34,0.5,-8),&quot;-&quot;,Enum.FontSize.Size14,&quot;MinimizeButton&quot;,dragBar)
&#9;minimizeButton.TextYAlignment = Enum.TextYAlignment.Top
&#9;local minimizeFrame = Instance.new(&quot;Frame&quot;,dragBar)
&#9;minimizeFrame.Name = &quot;MinimizeFrame&quot;
&#9;minimizeFrame.BackgroundColor3 = Color3.new(73/255,73/255,73/255)
&#9;minimizeFrame.BorderColor3 = Color3.new(0,0,0)
&#9;minimizeFrame.Position = UDim2.new(0,0,1,0)
&#9;if size then
&#9;&#9;minimizeFrame.Size = UDim2.new(size.X.Scale,size.X.Offset,0,50) + UDim2.new(0,20,0,0)
&#9;else
&#9;&#9;minimizeFrame.Size = UDim2.new(0,183,0,50)
&#9;end
&#9;minimizeFrame.Visible = false
&#9;local minimizeBigButton = Instance.new(&quot;TextButton&quot;,minimizeFrame)
&#9;minimizeBigButton.Position = UDim2.new(0.5,-50,0.5,-20)
&#9;minimizeBigButton.Name = &quot;MinimizeButton&quot;
&#9;minimizeBigButton.Size = UDim2.new(0,100,0,40)
&#9;minimizeBigButton.Style = Enum.ButtonStyle.RobloxButton
&#9;minimizeBigButton.Font = Enum.Font.ArialBold
&#9;minimizeBigButton.FontSize = Enum.FontSize.Size18
&#9;minimizeBigButton.TextColor3 = Color3.new(1,1,1)
&#9;minimizeBigButton.Text = &quot;Show&quot;
&#9;local separatingLine = Instance.new(&quot;Frame&quot;,dragBar)
&#9;separatingLine.Name = &quot;SeparatingLine&quot;
&#9;separatingLine.BackgroundColor3 = Color3.new(115/255,115/255,115/255)
&#9;separatingLine.BorderSizePixel = 0
&#9;separatingLine.Position = UDim2.new(1,-18,0.5,-7)
&#9;separatingLine.Size = UDim2.new(0,1,0,14)
&#9;local otherSeparatingLine = separatingLine:clone()
&#9;otherSeparatingLine.Position = UDim2.new(1,-35,0.5,-7)
&#9;otherSeparatingLine.Parent = dragBar
&#9;local widgetContainer = Instance.new(&quot;Frame&quot;,dragBar)
&#9;widgetContainer.Name = &quot;WidgetContainer&quot;
&#9;widgetContainer.BackgroundTransparency = 1
&#9;widgetContainer.Position = UDim2.new(0,0,1,0)
&#9;widgetContainer.BorderColor3 = Color3.new(0,0,0)
&#9;if not scrollable then
&#9;&#9;widgetContainer.BackgroundTransparency = 0
&#9;&#9;widgetContainer.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
&#9;end
&#9;if size then
&#9;&#9;if scrollable then
&#9;&#9;&#9;widgetContainer.Size = size
&#9;&#9;else
&#9;&#9;&#9;widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,size.Y.Scale,size.Y.Offset)
&#9;&#9;end
&#9;else
&#9;&#9;if scrollable then
&#9;&#9;&#9;widgetContainer.Size = UDim2.new(0,163,0,400)
&#9;&#9;else
&#9;&#9;&#9;widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,0,400)
&#9;&#9;end
&#9;end
&#9;if position then
&#9;&#9;widgetContainer.Position = position + UDim2.new(0,0,0,20)
&#9;end
&#9;local frame,control,verticalDragger = nil
&#9;if scrollable then
&#9;&#9;--frame for widgets
&#9;&#9;frame,control = t.CreateTrueScrollingFrame()
&#9;&#9;frame.Size = UDim2.new(1, 0, 1, 0)
&#9;&#9;frame.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
&#9;&#9;frame.BorderColor3 = Color3.new(0,0,0)
&#9;&#9;frame.Active = true
&#9;&#9;frame.Parent = widgetContainer
&#9;&#9;control.Parent = dragBar
&#9;&#9;control.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
&#9;&#9;control.BorderSizePixel = 0
&#9;&#9;control.BackgroundTransparency = 0
&#9;&#9;control.Position = UDim2.new(1,-21,1,1)
&#9;&#9;if size then
&#9;&#9;&#9;control.Size = UDim2.new(0,21,size.Y.Scale,size.Y.Offset)
&#9;&#9;else
&#9;&#9;&#9;control.Size = UDim2.new(0,21,0,400)
&#9;&#9;end
&#9;&#9;control:FindFirstChild(&quot;ScrollDownButton&quot;).Position = UDim2.new(0,0,1,-20)
&#9;&#9;local fakeLine = Instance.new(&quot;Frame&quot;,control)
&#9;&#9;fakeLine.Name = &quot;FakeLine&quot;
&#9;&#9;fakeLine.BorderSizePixel = 0
&#9;&#9;fakeLine.BackgroundColor3 = Color3.new(0,0,0)
&#9;&#9;fakeLine.Size = UDim2.new(0,1,1,1)
&#9;&#9;fakeLine.Position = UDim2.new(1,0,0,0)
&#9;&#9;verticalDragger = Instance.new(&quot;TextButton&quot;,widgetContainer)
&#9;&#9;verticalDragger.ZIndex = 2
&#9;&#9;verticalDragger.AutoButtonColor = false
&#9;&#9;verticalDragger.Name = &quot;VerticalDragger&quot;
&#9;&#9;verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255)
&#9;&#9;verticalDragger.BorderColor3 = Color3.new(0,0,0)
&#9;&#9;verticalDragger.Size = UDim2.new(1,20,0,20)
&#9;&#9;verticalDragger.Position = UDim2.new(0,0,1,0)
&#9;&#9;verticalDragger.Active = true
&#9;&#9;verticalDragger.Text = &quot;&quot;
&#9;&#9;local scrubFrame = Instance.new(&quot;Frame&quot;,verticalDragger)
&#9;&#9;scrubFrame.Name = &quot;ScrubFrame&quot;
&#9;&#9;scrubFrame.BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;scrubFrame.BorderSizePixel = 0
&#9;&#9;scrubFrame.Position = UDim2.new(0.5,-5,0.5,0)
&#9;&#9;scrubFrame.Size = UDim2.new(0,10,0,1)
&#9;&#9;scrubFrame.ZIndex = 5
&#9;&#9;local scrubTwo = scrubFrame:clone()
&#9;&#9;scrubTwo.Position = UDim2.new(0.5,-5,0.5,-2)
&#9;&#9;scrubTwo.Parent = verticalDragger
&#9;&#9;local scrubThree = scrubFrame:clone()
&#9;&#9;scrubThree.Position = UDim2.new(0.5,-5,0.5,2)
&#9;&#9;scrubThree.Parent = verticalDragger
&#9;&#9;local areaSoak = Instance.new(&quot;TextButton&quot;,getScreenGuiAncestor(parent))
&#9;&#9;areaSoak.Name = &quot;AreaSoak&quot;
&#9;&#9;areaSoak.Size = UDim2.new(1,0,1,0)
&#9;&#9;areaSoak.BackgroundTransparency = 1
&#9;&#9;areaSoak.BorderSizePixel = 0
&#9;&#9;areaSoak.Text = &quot;&quot;
&#9;&#9;areaSoak.ZIndex = 10
&#9;&#9;areaSoak.Visible = false
&#9;&#9;areaSoak.Active = true
&#9;&#9;local draggingVertical = false
&#9;&#9;local startYPos = nil
&#9;&#9;verticalDragger.MouseEnter:connect(function ()
&#9;&#9;&#9;verticalDragger.BackgroundColor3 = Color3.new(60/255,60/255,60/255)
&#9;&#9;end)
&#9;&#9;verticalDragger.MouseLeave:connect(function ()
&#9;&#9;&#9;verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255)
&#9;&#9;end)
&#9;&#9;verticalDragger.MouseButton1Down:connect(function(x,y)
&#9;&#9;&#9;draggingVertical = true
&#9;&#9;&#9;areaSoak.Visible = true
&#9;&#9;&#9;startYPos = y
&#9;&#9;end)
&#9;&#9;areaSoak.MouseButton1Up:connect(function ( )
&#9;&#9;&#9;draggingVertical = false
&#9;&#9;&#9;areaSoak.Visible = false
&#9;&#9;end)
&#9;&#9;areaSoak.MouseMoved:connect(function(x,y)
&#9;&#9;&#9;if not draggingVertical then return end
&#9;&#9;&#9;local yDelta = y - startYPos
&#9;&#9;&#9;if not control.ScrollDownButton.Visible and yDelta &gt; 0 then
&#9;&#9;&#9;&#9;return
&#9;&#9;&#9;end
&#9;&#9;&#9;if (widgetContainer.Size.Y.Offset + yDelta) &lt; 150 then
&#9;&#9;&#9;&#9;widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,150)
&#9;&#9;&#9;&#9;control.Size = UDim2.new (0,21,0,150)
&#9;&#9;&#9;&#9;return
&#9;&#9;&#9;end
&#9;&#9;&#9;startYPos = y
&#9;&#9;&#9;if widgetContainer.Size.Y.Offset + yDelta &gt;= 0 then
&#9;&#9;&#9;&#9;widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,widgetContainer.Size.Y.Offset + yDelta)
&#9;&#9;&#9;&#9;control.Size = UDim2.new(0,21,0,control.Size.Y.Offset + yDelta )
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;end
&#9;local function switchMinimize()
&#9;&#9;minimizeFrame.Visible = not minimizeFrame.Visible
&#9;&#9;if scrollable then
&#9;&#9;&#9;frame.Visible = not frame.Visible
&#9;&#9;&#9;verticalDragger.Visible = not verticalDragger.Visible
&#9;&#9;&#9;control.Visible = not control.Visible
&#9;&#9;else
&#9;&#9;&#9;widgetContainer.Visible = not widgetContainer.Visible
&#9;&#9;end
&#9;&#9;if minimizeFrame.Visible then
&#9;&#9;&#9;minimizeButton.Text = &quot;+&quot;
&#9;&#9;else
&#9;&#9;&#9;minimizeButton.Text = &quot;-&quot;
&#9;&#9;end
&#9;end
&#9;minimizeBigButton.MouseButton1Click:connect(function ( )
&#9;&#9;switchMinimize()
&#9;end)
&#9;minimizeButton.MouseButton1Click:connect(function( )
&#9;&#9;switchMinimize()
&#9;end)
&#9;if scrollable then
&#9;&#9;return dragBar, frame, helpFrame, closeEvent
&#9;else
&#9;&#9;return dragBar, widgetContainer, helpFrame, closeEvent
&#9;end
end
t.Help =
&#9;function(funcNameOrFunc)
&#9;&#9;--input argument can be a string or a function. Should return a description (of arguments and expected side effects)
&#9;&#9;if funcNameOrFunc == &quot;CreatePropertyDropDownMenu&quot; or funcNameOrFunc == t.CreatePropertyDropDownMenu then
&#9;&#9;&#9;return &quot;Function CreatePropertyDropDownMenu. &quot; ..
&#9;&#9;&#9;&#9; &quot;Arguments: (instance, propertyName, enumType). &quot; ..
&#9;&#9;&#9;&#9; &quot;Side effect: returns a container with a drop-down-box that is linked to the &apos;property&apos; field of &apos;instance&apos; which is of type &apos;enumType&apos;&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateDropDownMenu&quot; or funcNameOrFunc == t.CreateDropDownMenu then
&#9;&#9;&#9;return &quot;Function CreateDropDownMenu. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (items, onItemSelected). &quot; ..
&#9;&#9;&#9;&#9; &quot;Side effect: Returns 2 results, a container to the gui object and a &apos;updateSelection&apos; function for external updating. The container is a drop-down-box created around a list of items&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateMessageDialog&quot; or funcNameOrFunc == t.CreateMessageDialog then
&#9;&#9;&#9;return &quot;Function CreateMessageDialog. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (title, message, buttons). &quot; ..
&#9;&#9;&#9; &quot;Side effect: Returns a gui object of a message box with &apos;title&apos; and &apos;message&apos; as passed in. &apos;buttons&apos; input is an array of Tables contains a &apos;Text&apos; and &apos;Function&apos; field for the text/callback of each button&quot;
&#9;&#9;end&#9;&#9;
&#9;&#9;if funcNameOrFunc == &quot;CreateStyledMessageDialog&quot; or funcNameOrFunc == t.CreateStyledMessageDialog then
&#9;&#9;&#9;return &quot;Function CreateStyledMessageDialog. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (title, message, style, buttons). &quot; ..
&#9;&#9;&#9; &quot;Side effect: Returns a gui object of a message box with &apos;title&apos; and &apos;message&apos; as passed in. &apos;buttons&apos; input is an array of Tables contains a &apos;Text&apos; and &apos;Function&apos; field for the text/callback of each button, &apos;style&apos; is a string, either Error, Notify or Confirm&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;GetFontHeight&quot; or funcNameOrFunc == t.GetFontHeight then
&#9;&#9;&#9;return &quot;Function GetFontHeight. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (font, fontSize). &quot; ..
&#9;&#9;&#9; &quot;Side effect: returns the size in pixels of the given font + fontSize&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;LayoutGuiObjects&quot; or funcNameOrFunc == t.LayoutGuiObjects then
&#9;&#9;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateScrollingFrame&quot; or funcNameOrFunc == t.CreateScrollingFrame then
&#9;&#9;&#9;return &quot;Function CreateScrollingFrame. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (orderList, style) &quot; ..
&#9;&#9;&#9; &quot;Side effect: returns 4 objects, (scrollFrame, scrollUpButton, scrollDownButton, recalculateFunction). &apos;scrollFrame&apos; 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 &apos;grid&apos; styling if style is passed &apos;grid&apos; as a string. recalculateFunction can be called when a relayout is needed (when orderList changes)&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateTrueScrollingFrame&quot; or funcNameOrFunc == t.CreateTrueScrollingFrame then
&#9;&#9;&#9;return &quot;Function CreateTrueScrollingFrame. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (nil) &quot; ..
&#9;&#9;&#9; &quot;Side effect: returns 2 objects, (scrollFrame, controlFrame). &apos;scrollFrame&apos; can be filled with GuiObjects, and they will be clipped if not inside the frame&apos;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.&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;AutoTruncateTextObject&quot; or funcNameOrFunc == t.AutoTruncateTextObject then
&#9;&#9;&#9;return &quot;Function AutoTruncateTextObject. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (textLabel) &quot; ..
&#9;&#9;&#9; &quot;Side effect: returns 2 objects, (textLabel, changeText). The &apos;textLabel&apos; input is modified to automatically truncate text (with ellipsis), if it gets too small to fit. &apos;changeText&apos; is a function that can be used to change the text, it takes 1 string as an argument&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateSlider&quot; or funcNameOrFunc == t.CreateSlider then
&#9;&#9;&#9;return &quot;Function CreateSlider. &quot; ..
&#9;&#9;&#9;&#9;&quot;Arguments: (steps, width, position) &quot; ..
&#9;&#9;&#9;&#9;&quot;Side effect: returns 2 objects, (sliderGui, sliderPosition). The &apos;steps&apos; argument specifies how many different positions the slider can hold along the bar. &apos;width&apos; specifies in pixels how wide the bar should be (modifiable afterwards if desired). &apos;position&apos; argument should be a UDim2 for slider positioning. &apos;sliderPosition&apos; is an IntValue whose current .Value specifies the specific step the slider is currently on.&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateSliderNew&quot; or funcNameOrFunc == t.CreateSliderNew then
&#9;&#9;&#9;return &quot;Function CreateSliderNew. &quot; ..
&#9;&#9;&#9;&#9;&quot;Arguments: (steps, width, position) &quot; ..
&#9;&#9;&#9;&#9;&quot;Side effect: returns 2 objects, (sliderGui, sliderPosition). The &apos;steps&apos; argument specifies how many different positions the slider can hold along the bar. &apos;width&apos; specifies in pixels how wide the bar should be (modifiable afterwards if desired). &apos;position&apos; argument should be a UDim2 for slider positioning. &apos;sliderPosition&apos; is an IntValue whose current .Value specifies the specific step the slider is currently on.&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateLoadingFrame&quot; or funcNameOrFunc == t.CreateLoadingFrame then
&#9;&#9;&#9;return &quot;Function CreateLoadingFrame. &quot; ..
&#9;&#9;&#9;&#9;&quot;Arguments: (name, size, position) &quot; ..
&#9;&#9;&#9;&#9;&quot;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.&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateTerrainMaterialSelector&quot; or funcNameOrFunc == t.CreateTerrainMaterialSelector then
&#9;&#9;&#9;return &quot;Function CreateTerrainMaterialSelector. &quot; ..
&#9;&#9;&#9;&#9;&quot;Arguments: (size, position) &quot; ..
&#9;&#9;&#9;&#9;&quot;Side effect: Size and position are UDim2 values that specifies the selector&apos;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.&quot;
&#9;&#9;end
&#9;end
&#9;
local function waitForChild(instance, name)
&#9;while not instance:FindFirstChild(name) do
&#9;&#9;instance.ChildAdded:wait()
&#9;end
end
local function waitForProperty(instance, property)
&#9;while not instance[property] do
&#9;&#9;instance.Changed:wait()
&#9;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 = &quot;http://www.roblox.com/asset?id=54071825&quot;
local classicLookScreenUrl = &quot;http://www.roblox.com/Asset?id=45915798&quot;
local hasGraphicsSlider = true
local GraphicsQualityLevels = 10
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)
&#9;shield.Settings:TweenPosition(UDim2.new(0.5, -262,-0.5, -200),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
&#9;delay(tweenTime,function()
&#9;&#9;shield.Visible = false
&#9;&#9;for i = 1, #centerDialogs do
&#9;&#9;&#9;centerDialogs[i].Visible = false
&#9;&#9;&#9;game.GuiService:RemoveCenterDialog(centerDialogs[i])
&#9;&#9;end
&#9;&#9;settingsButton.Active = true
&#9;&#9;currentMenuSelection = nil
&#9;&#9;lastMenuSelection = {}&#9;&#9;
&#9;end)
end
function goToMenu(container,menuName, moveDirection,size,position)
&#9;if type(menuName) ~= &quot;string&quot; then return end
&#9;
&#9;table.insert(lastMenuSelection,currentMenuSelection)
&#9;if menuName == &quot;GameMainMenu&quot; then
&#9;&#9;lastMenuSelection = {}
&#9;end
&#9;local containerChildren = container:GetChildren()
&#9;local selectedMenu = false
&#9;for i = 1, #containerChildren do
&#9;&#9;if containerChildren[i].Name == menuName then
&#9;&#9;&#9;containerChildren[i].Visible = true
&#9;&#9;&#9;currentMenuSelection = {container = container,name = menuName, direction = moveDirection, lastSize = size}
&#9;&#9;&#9;selectedMenu = true
&#9;&#9;&#9;if size and position then
&#9;&#9;&#9;&#9;containerChildren[i]:TweenSizeAndPosition(size,position,Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
&#9;&#9;&#9;elseif size then
&#9;&#9;&#9;&#9;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)
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;containerChildren[i]:TweenPosition(UDim2.new(0,0,0,0),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;if moveDirection == &quot;left&quot; then
&#9;&#9;&#9;&#9;containerChildren[i]:TweenPosition(UDim2.new(-1,-525,0,0),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
&#9;&#9;&#9;elseif moveDirection == &quot;right&quot; then
&#9;&#9;&#9;&#9;containerChildren[i]:TweenPosition(UDim2.new(1,525,0,0),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
&#9;&#9;&#9;elseif moveDirection == &quot;up&quot; then
&#9;&#9;&#9;&#9;containerChildren[i]:TweenPosition(UDim2.new(0,0,-1,-400),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
&#9;&#9;&#9;elseif moveDirection == &quot;down&quot; then
&#9;&#9;&#9;&#9;containerChildren[i]:TweenPosition(UDim2.new(0,0,1,400),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
&#9;&#9;&#9;end
&#9;&#9;&#9;delay(tweenTime,function()
&#9;&#9;&#9;&#9;containerChildren[i].Visible = false
&#9;&#9;&#9;end)
&#9;&#9;end
&#9;end&#9;
end
function resetLocalCharacter()
&#9;local player = game.Players.LocalPlayer
&#9;if player then
&#9;&#9;if player.Character and player.Character:FindFirstChild(&quot;Humanoid&quot;) then
&#9;&#9;&#9;player.Character.Humanoid.Health = 0
&#9;&#9;end
&#9;end
end
local function createTextButton(text,style,fontSize,buttonSize,buttonPosition)
&#9;local newTextButton = Instance.new(&quot;TextButton&quot;)
&#9;newTextButton.Font = Enum.Font.Arial
&#9;newTextButton.FontSize = fontSize
&#9;newTextButton.Size = buttonSize
&#9;newTextButton.Position = buttonPosition
&#9;newTextButton.Style = style
&#9;newTextButton.TextColor3 = Color3.new(1,1,1)
&#9;newTextButton.Text = text
&#9;return newTextButton
end
local function CreateTextButtons(frame, buttons, yPos, ySize)
&#9;if #buttons &lt; 1 then
&#9;&#9;error(&quot;Must have more than one button&quot;)
&#9;end
&#9;local buttonNum = 1
&#9;local buttonObjs = {}
&#9;local function toggleSelection(button)
&#9;&#9;for i, obj in ipairs(buttonObjs) do
&#9;&#9;&#9;if obj == button then
&#9;&#9;&#9;&#9;obj.Style = Enum.ButtonStyle.RobloxButtonDefault
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;obj.Style = Enum.ButtonStyle.RobloxButton
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;for i, obj in ipairs(buttons) do
&#9;&#9;local button = Instance.new(&quot;TextButton&quot;)
&#9;&#9;button.Name = &quot;Button&quot; .. buttonNum
&#9;&#9;button.Font = Enum.Font.Arial
&#9;&#9;button.FontSize = Enum.FontSize.Size18
&#9;&#9;button.AutoButtonColor = true
&#9;&#9;button.Style = Enum.ButtonStyle.RobloxButton
&#9;&#9;button.Text = obj.Text
&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;button.MouseButton1Click:connect(function() toggleSelection(button) obj.Function() end)
&#9;&#9;button.Parent = frame
&#9;&#9;buttonObjs[buttonNum] = button
&#9;&#9;buttonNum = buttonNum + 1
&#9;end
&#9;
&#9;toggleSelection(buttonObjs[1])
&#9;local numButtons = buttonNum-1
&#9;if numButtons == 1 then
&#9;&#9;frame.Button1.Position = UDim2.new(0.35, 0, yPos.Scale, yPos.Offset)
&#9;&#9;frame.Button1.Size = UDim2.new(.4,0,ySize.Scale, ySize.Offset)
&#9;elseif numButtons == 2 then
&#9;&#9;frame.Button1.Position = UDim2.new(0.1, 0, yPos.Scale, yPos.Offset)
&#9;&#9;frame.Button1.Size = UDim2.new(.35,0, ySize.Scale, ySize.Offset)
&#9;&#9;frame.Button2.Position = UDim2.new(0.55, 0, yPos.Scale, yPos.Offset)
&#9;&#9;frame.Button2.Size = UDim2.new(.35,0, ySize.Scale, ySize.Offset)
&#9;elseif numButtons &gt;= 3 then
&#9;&#9;local spacing = .1 / numButtons
&#9;&#9;local buttonSize = .9 / numButtons
&#9;&#9;buttonNum = 1
&#9;&#9;while buttonNum &lt;= numButtons do
&#9;&#9;&#9;buttonObjs[buttonNum].Position = UDim2.new(spacing*buttonNum + (buttonNum-1) * buttonSize, 0, yPos.Scale, yPos.Offset)
&#9;&#9;&#9;buttonObjs[buttonNum].Size = UDim2.new(buttonSize, 0, ySize.Scale, ySize.Offset)
&#9;&#9;&#9;buttonNum = buttonNum + 1
&#9;&#9;end
&#9;end
end
function setRecordGui(recording, stopRecordButton, recordVideoButton)
&#9;if recording then
&#9;&#9;stopRecordButton.Visible = true
&#9;&#9;recordVideoButton.Text = &quot;Stop Recording&quot;
&#9;else
&#9;&#9;stopRecordButton.Visible = false
&#9;&#9;recordVideoButton.Text = &quot;Record Video&quot;
&#9;end
end
function recordVideoClick(recordVideoButton, stopRecordButton)
&#9;recordingVideo = not recordingVideo
&#9;setRecordGui(recordingVideo, stopRecordButton, recordVideoButton)
end
function backToGame(buttonClicked, shield, settingsButton)
&#9;buttonClicked.Parent.Parent.Parent.Parent.Visible = false
&#9;shield.Visible = false
&#9;for i = 1, #centerDialogs do
&#9;&#9;game.GuiService:RemoveCenterDialog(centerDialogs[i])
&#9;&#9;centerDialogs[i].Visible = false
&#9;end
&#9;centerDialogs = {}
&#9;game.GuiService:RemoveCenterDialog(shield)
&#9;settingsButton.Active = true
end
function setDisabledState(guiObject)
&#9;if not guiObject then return end
&#9;
&#9;if guiObject:IsA(&quot;TextLabel&quot;) then
&#9;&#9;guiObject.TextTransparency = 0.9
&#9;elseif guiObject:IsA(&quot;TextButton&quot;) then
&#9;&#9;guiObject.TextTransparency = 0.9
&#9;&#9;guiObject.Active = false
&#9;else
&#9;&#9;if guiObject[&quot;ClassName&quot;] then
&#9;&#9;&#9;print(&quot;setDisabledState() got object of unsupported type. object type is &quot;,guiObject.ClassName)
&#9;&#9;end
&#9;end
end
local function createHelpDialog(baseZIndex)
&#9;if helpButton == nil then
&#9;&#9;if gui:FindFirstChild(&quot;TopLeftControl&quot;) and gui.TopLeftControl:FindFirstChild(&quot;Help&quot;) then
&#9;&#9;&#9;helpButton = gui.TopLeftControl.Help
&#9;&#9;elseif gui:FindFirstChild(&quot;BottomRightControl&quot;) and gui.BottomRightControl:FindFirstChild(&quot;Help&quot;) then
&#9;&#9;&#9;helpButton = gui.BottomRightControl.Help
&#9;&#9;end
&#9;end
&#9;local shield = Instance.new(&quot;Frame&quot;)
&#9;shield.Name = &quot;HelpDialogShield&quot;
&#9;shield.Active = true
&#9;shield.Visible = false
&#9;shield.Size = UDim2.new(1,0,1,0)
&#9;shield.BackgroundColor3 = Color3I(51,51,51)
&#9;shield.BorderColor3 = Color3I(27,42,53)
&#9;shield.BackgroundTransparency = 0.4
&#9;shield.ZIndex = baseZIndex + 1
shield.Parent = gui
&#9;local helpDialog = Instance.new(&quot;Frame&quot;)
&#9;helpDialog.Name = &quot;HelpDialog&quot;
&#9;helpDialog.Style = Enum.FrameStyle.RobloxRound
&#9;helpDialog.Position = UDim2.new(.2, 0, .2, 0)
&#9;helpDialog.Size = UDim2.new(0.6, 0, 0.6, 0)
&#9;helpDialog.Active = true
&#9;helpDialog.Parent = shield
&#9;local titleLabel = Instance.new(&quot;TextLabel&quot;)
&#9;titleLabel.Name = &quot;Title&quot;
&#9;titleLabel.Text = &quot;Keyboard &amp; Mouse Controls&quot;
&#9;titleLabel.Font = Enum.Font.ArialBold
&#9;titleLabel.FontSize = Enum.FontSize.Size36
&#9;titleLabel.Position = UDim2.new(0, 0, 0.025, 0)
&#9;titleLabel.Size = UDim2.new(1, 0, 0, 40)
&#9;titleLabel.TextColor3 = Color3.new(1,1,1)
&#9;titleLabel.BackgroundTransparency = 1
&#9;titleLabel.Parent = helpDialog
&#9;local buttonRow = Instance.new(&quot;Frame&quot;)
&#9;buttonRow.Name = &quot;Buttons&quot;
&#9;buttonRow.Position = UDim2.new(0.1, 0, .07, 40)
&#9;buttonRow.Size = UDim2.new(0.8, 0, 0, 45)
&#9;buttonRow.BackgroundTransparency = 1
&#9;buttonRow.Parent = helpDialog
&#9;local imageFrame = Instance.new(&quot;Frame&quot;)
&#9;imageFrame.Name = &quot;ImageFrame&quot;
&#9;imageFrame.Position = UDim2.new(0.05, 0, 0.075, 80)
&#9;imageFrame.Size = UDim2.new(0.9, 0, .9, -120)
&#9;imageFrame.BackgroundTransparency = 1
&#9;imageFrame.Parent = helpDialog
&#9;local layoutFrame = Instance.new(&quot;Frame&quot;)
&#9;layoutFrame.Name = &quot;LayoutFrame&quot;
&#9;layoutFrame.Position = UDim2.new(0.5, 0, 0, 0)
&#9;layoutFrame.Size = UDim2.new(1.5, 0, 1, 0)
&#9;layoutFrame.BackgroundTransparency = 1
&#9;layoutFrame.SizeConstraint = Enum.SizeConstraint.RelativeYY
&#9;layoutFrame.Parent = imageFrame
&#9;local image = Instance.new(&quot;ImageLabel&quot;)
&#9;image.Name = &quot;Image&quot;
&#9;if UserSettings().GameSettings.ControlMode == Enum.ControlMode[&quot;Mouse Lock Switch&quot;] then
&#9;&#9;image.Image = mouseLockLookScreenUrl
&#9;else
&#9;&#9;image.Image = classicLookScreenUrl
&#9;end
&#9;image.Position = UDim2.new(-0.5, 0, 0, 0)
&#9;image.Size = UDim2.new(1, 0, 1, 0)
&#9;image.BackgroundTransparency = 1
&#9;image.Parent = layoutFrame
&#9;
&#9;local buttons = {}
&#9;buttons[1] = {}
&#9;buttons[1].Text = &quot;Look&quot;
&#9;buttons[1].Function = function()
&#9;&#9;if UserSettings().GameSettings.ControlMode == Enum.ControlMode[&quot;Mouse Lock Switch&quot;] then
&#9;&#9;&#9;image.Image = mouseLockLookScreenUrl
&#9;&#9;else
&#9;&#9;&#9;image.Image = classicLookScreenUrl
&#9;&#9;end
&#9;end
&#9;buttons[2] = {}
&#9;buttons[2].Text = &quot;Move&quot;
&#9;buttons[2].Function = function()
&#9;&#9;image.Image = &quot;http://www.roblox.com/Asset?id=45915811&quot;
&#9;end
&#9;buttons[3] = {}
&#9;buttons[3].Text = &quot;Gear&quot;
&#9;buttons[3].Function = function()
&#9;&#9;image.Image = &quot;http://www.roblox.com/Asset?id=45917596&quot;
&#9;end
&#9;buttons[4] = {}
&#9;buttons[4].Text = &quot;Zoom&quot;
&#9;buttons[4].Function = function() &#9;
&#9;&#9;image.Image = &quot;http://www.roblox.com/Asset?id=45915825&quot;
&#9;end
&#9;CreateTextButtons(buttonRow, buttons, UDim.new(0, 0), UDim.new(1,0))
&#9;
&#9;&#9;
&#9;-- set up listeners for type of mouse mode, but keep constructing gui at same time
&#9;delay(0, function()
&#9;&#9;waitForChild(gui,&quot;UserSettingsShield&quot;)
&#9;&#9;waitForChild(gui.UserSettingsShield,&quot;Settings&quot;)
&#9;&#9;waitForChild(gui.UserSettingsShield.Settings,&quot;SettingsStyle&quot;)
&#9;&#9;waitForChild(gui.UserSettingsShield.Settings.SettingsStyle, &quot;GameSettingsMenu&quot;)
&#9;&#9;waitForChild(gui.UserSettingsShield.Settings.SettingsStyle.GameSettingsMenu, &quot;CameraField&quot;)
&#9;&#9;waitForChild(gui.UserSettingsShield.Settings.SettingsStyle.GameSettingsMenu.CameraField, &quot;DropDownMenuButton&quot;)
&#9;&#9;gui.UserSettingsShield.Settings.SettingsStyle.GameSettingsMenu.CameraField.DropDownMenuButton.Changed:connect(function(prop)
&#9;&#9;&#9;if prop ~= &quot;Text&quot; then return end
&#9;&#9;&#9;if buttonRow.Button1.Style == Enum.ButtonStyle.RobloxButtonDefault then -- only change if this is the currently selected panel
&#9;&#9;&#9;&#9;if gui.UserSettingsShield.Settings.SettingsStyle.GameSettingsMenu.CameraField.DropDownMenuButton.Text == &quot;Classic&quot; then
&#9;&#9;&#9;&#9;&#9;image.Image = classicLookScreenUrl
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;image.Image = mouseLockLookScreenUrl
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;end)
&#9;local okBtn = Instance.new(&quot;TextButton&quot;)
&#9;okBtn.Name = &quot;OkBtn&quot;
&#9;okBtn.Text = &quot;OK&quot;
&#9;okBtn.Modal = true
&#9;okBtn.Size = UDim2.new(0.3, 0, 0, 45)
&#9;okBtn.Position = UDim2.new(0.35, 0, .975, -50)
&#9;okBtn.Font = Enum.Font.Arial
&#9;okBtn.FontSize = Enum.FontSize.Size18
&#9;okBtn.BackgroundTransparency = 1
&#9;okBtn.TextColor3 = Color3.new(1,1,1)
&#9;okBtn.Style = Enum.ButtonStyle.RobloxButtonDefault
&#9;okBtn.MouseButton1Click:connect(
&#9;&#9;function()
&#9;&#9;&#9;gui.HelpDialogShield.Visible = false
&#9;&#9;end)
&#9;okBtn.Parent = helpDialog
&#9;return shield
end
local function createLeaveConfirmationMenu(baseZIndex,shield)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Name = &quot;LeaveConfirmationMenu&quot;
&#9;frame.BackgroundTransparency = 1
&#9;frame.Size = UDim2.new(1,0,1,0)
&#9;frame.Position = UDim2.new(0,0,2,400)
&#9;frame.ZIndex = baseZIndex + 4
&#9;
&#9;local yesButton = createTextButton(&quot;Leave&quot;,Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size24,UDim2.new(0,128,0,50),UDim2.new(0,313,0.8,0))
&#9;yesButton.Name = &quot;YesButton&quot;
&#9;yesButton.ZIndex = baseZIndex + 4
&#9;yesButton.Parent = frame
&#9;yesButton.Modal = true
&#9;yesButton:SetVerb(&quot;Exit&quot;)
&#9;
&#9;local noButton = createTextButton(&quot;Stay&quot;,Enum.ButtonStyle.RobloxButtonDefault,Enum.FontSize.Size24,UDim2.new(0,128,0,50),UDim2.new(0,90,0.8,0))
&#9;noButton.Name = &quot;NoButton&quot;
&#9;noButton.Parent = frame
&#9;noButton.ZIndex = baseZIndex + 4
&#9;noButton.MouseButton1Click:connect(function()
&#9;&#9;goToMenu(shield.Settings.SettingsStyle,&quot;GameMainMenu&quot;,&quot;down&quot;,UDim2.new(0,525,0,430))
&#9;&#9;shield.Settings:TweenSize(UDim2.new(0,525,0,430),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
&#9;end)
&#9;
&#9;local leaveText = Instance.new(&quot;TextLabel&quot;)
&#9;leaveText.Name = &quot;LeaveText&quot;
&#9;leaveText.Text = &quot;Leave this game?&quot;
&#9;leaveText.Size = UDim2.new(1,0,0.8,0)
&#9;leaveText.TextWrap = true
&#9;leaveText.TextColor3 = Color3.new(1,1,1)
&#9;leaveText.Font = Enum.Font.ArialBold
&#9;leaveText.FontSize = Enum.FontSize.Size36
&#9;leaveText.BackgroundTransparency = 1
&#9;leaveText.ZIndex = baseZIndex + 4
&#9;leaveText.Parent = frame
&#9;
&#9;return frame
end
local function createResetConfirmationMenu(baseZIndex,shield)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Name = &quot;ResetConfirmationMenu&quot;
&#9;frame.BackgroundTransparency = 1
&#9;frame.Size = UDim2.new(1,0,1,0)
&#9;frame.Position = UDim2.new(0,0,2,400)
&#9;frame.ZIndex = baseZIndex + 4
frame.Parent = gui
&#9;
&#9;local yesButton = createTextButton(&quot;Reset&quot;,Enum.ButtonStyle.RobloxButtonDefault,Enum.FontSize.Size24,UDim2.new(0,128,0,50),UDim2.new(0,313,0,299))
&#9;yesButton.Name = &quot;YesButton&quot;
&#9;yesButton.ZIndex = baseZIndex + 4
&#9;yesButton.Parent = frame
&#9;yesButton.Modal = true
&#9;yesButton.MouseButton1Click:connect(function()
&#9;&#9;resumeGameFunction(shield)
&#9;&#9;resetLocalCharacter()
&#9;end)
&#9;
&#9;local noButton = createTextButton(&quot;Cancel&quot;,Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size24,UDim2.new(0,128,0,50),UDim2.new(0,90,0,299))
&#9;noButton.Name = &quot;NoButton&quot;
&#9;noButton.Parent = frame
&#9;noButton.ZIndex = baseZIndex + 4
&#9;noButton.MouseButton1Click:connect(function()
&#9;&#9;goToMenu(shield.Settings.SettingsStyle,&quot;GameMainMenu&quot;,&quot;down&quot;,UDim2.new(0,525,0,430))
&#9;&#9;shield.Settings:TweenSize(UDim2.new(0,525,0,430),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
&#9;end)
&#9;
&#9;local resetCharacterText = Instance.new(&quot;TextLabel&quot;)
&#9;resetCharacterText.Name = &quot;ResetCharacterText&quot;
&#9;resetCharacterText.Text = &quot;Are you sure you want to reset your character?&quot;
&#9;resetCharacterText.Size = UDim2.new(1,0,0.8,0)
&#9;resetCharacterText.TextWrap = true
&#9;resetCharacterText.TextColor3 = Color3.new(1,1,1)
&#9;resetCharacterText.Font = Enum.Font.ArialBold
&#9;resetCharacterText.FontSize = Enum.FontSize.Size36
&#9;resetCharacterText.BackgroundTransparency = 1
&#9;resetCharacterText.ZIndex = baseZIndex + 4
&#9;resetCharacterText.Parent = frame
&#9;
&#9;local fineResetCharacterText = resetCharacterText:Clone()
&#9;fineResetCharacterText.Name = &quot;FineResetCharacterText&quot;
&#9;fineResetCharacterText.Text = &quot;You will be put back on a spawn point&quot;
&#9;fineResetCharacterText.Size = UDim2.new(0,303,0,18)
&#9;fineResetCharacterText.Position = UDim2.new(0, 109, 0, 215)
&#9;fineResetCharacterText.FontSize = Enum.FontSize.Size18
&#9;fineResetCharacterText.Parent = frame
&#9;
&#9;return frame
end
local function createGameMainMenu(baseZIndex, shield)
&#9;local gameMainMenuFrame = Instance.new(&quot;Frame&quot;)
&#9;gameMainMenuFrame.Name = &quot;GameMainMenu&quot;
&#9;gameMainMenuFrame.BackgroundTransparency = 1
&#9;gameMainMenuFrame.Size = UDim2.new(1,0,1,0)
&#9;gameMainMenuFrame.ZIndex = baseZIndex + 4
&#9;gameMainMenuFrame.Parent = script.Parent.UserSettingsShield.Settings.SettingsStyle
&#9;-- GameMainMenu Children
&#9;
&#9;local gameMainMenuTitle = Instance.new(&quot;TextLabel&quot;)
&#9;gameMainMenuTitle.Name = &quot;Title&quot;
&#9;gameMainMenuTitle.Text = &quot;Game Menu&quot;
&#9;gameMainMenuTitle.BackgroundTransparency = 1
&#9;gameMainMenuTitle.TextStrokeTransparency = 0
&#9;gameMainMenuTitle.Font = Enum.Font.ArialBold
&#9;gameMainMenuTitle.FontSize = Enum.FontSize.Size36
&#9;gameMainMenuTitle.Size = UDim2.new(1,0,0,36)
&#9;gameMainMenuTitle.Position = UDim2.new(0,0,0,4)
&#9;gameMainMenuTitle.TextColor3 = Color3.new(1,1,1)
&#9;gameMainMenuTitle.ZIndex = baseZIndex + 4
&#9;gameMainMenuTitle.Parent = gameMainMenuFrame
&#9;
&#9;local robloxHelpButton = createTextButton(&quot;Help&quot;,Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size18,UDim2.new(0,164,0,50),UDim2.new(0,82,0,256))
&#9;robloxHelpButton.Name = &quot;HelpButton&quot;
&#9;robloxHelpButton.ZIndex = baseZIndex + 4
&#9;robloxHelpButton.Parent = gameMainMenuFrame
&#9;helpButton = robloxHelpButton
&#9;&#9;&#9;
&#9;local helpDialog = createHelpDialog(baseZIndex)
&#9;helpDialog.Parent = gui
&#9;&#9;
&#9;helpButton.MouseButton1Click:connect(
&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;helpDialog.Visible = true
&#9;&#9;&#9;&#9;&#9;mainShield.Visible = false
&#9;&#9;end)
&#9;helpButton.Active = true
&#9;
&#9;local helpShortcut = Instance.new(&quot;TextLabel&quot;)
&#9;helpShortcut.Name = &quot;HelpShortcutText&quot;
&#9;helpShortcut.Text = &quot;F1&quot;
&#9;helpShortcut.Visible = false
&#9;helpShortcut.BackgroundTransparency = 1
&#9;helpShortcut.Font = Enum.Font.Arial
&#9;helpShortcut.FontSize = Enum.FontSize.Size12
&#9;helpShortcut.Position = UDim2.new(0,85,0,0)
&#9;helpShortcut.Size = UDim2.new(0,30,0,30)
&#9;helpShortcut.TextColor3 = Color3.new(0,1,0)
&#9;helpShortcut.ZIndex = baseZIndex + 4
&#9;helpShortcut.Parent = robloxHelpButton
&#9;
&#9;local screenshotButton = createTextButton(&quot;Screenshot&quot;,Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size18,UDim2.new(0,168,0,50),UDim2.new(0,254,0,256))
&#9;screenshotButton.Name = &quot;ScreenshotButton&quot;
&#9;screenshotButton.ZIndex = baseZIndex + 4
&#9;screenshotButton.Parent = shield.Settings.SettingsStyle.GameMainMenu
&#9;screenshotButton.Visible = not macClient
&#9;screenshotButton:SetVerb(&quot;Screenshot&quot;)
&#9;
&#9;local screenshotShortcut = helpShortcut:clone()
&#9;screenshotShortcut.Name = &quot;ScreenshotShortcutText&quot;
&#9;screenshotShortcut.Text = &quot;PrintSc&quot;
&#9;screenshotShortcut.Position = UDim2.new(0,118,0,0)
&#9;screenshotShortcut.Visible = true
&#9;screenshotShortcut.Parent = screenshotButton
&#9;local recordVideoButton = createTextButton(&quot;Record Video&quot;,Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size18,UDim2.new(0,168,0,50),UDim2.new(0,254,0,306))
&#9;recordVideoButton.Name = &quot;RecordVideoButton&quot;
&#9;recordVideoButton.ZIndex = baseZIndex + 4
&#9;recordVideoButton.Parent = gameMainMenuFrame
&#9;recordVideoButton.Visible = not macClient
&#9;recordVideoButton:SetVerb(&quot;RecordToggle&quot;)
&#9;
&#9;local recordVideoShortcut = helpShortcut:clone()
&#9;recordVideoShortcut.Visible = hasGraphicsSlider
&#9;recordVideoShortcut.Name = &quot;RecordVideoShortcutText&quot;
&#9;recordVideoShortcut.Text = &quot;F12&quot;
&#9;recordVideoShortcut.Position = UDim2.new(0,120,0,0)
&#9;recordVideoShortcut.Parent = recordVideoButton
&#9;
&#9;local stopRecordButton = Instance.new(&quot;ImageButton&quot;)
&#9;stopRecordButton.Name = &quot;StopRecordButton&quot;
&#9;stopRecordButton.BackgroundTransparency = 1
&#9;stopRecordButton.Image = &quot;rbxasset://textures/ui/RecordStop.png&quot;
&#9;stopRecordButton.Size = UDim2.new(0,59,0,27)
&#9;stopRecordButton:SetVerb(&quot;RecordToggle&quot;)
&#9;stopRecordButton.MouseButton1Click:connect(function() stopRecordButton.Visible = false end)
&#9;recordVideoButton.MouseButton1Click:connect(function() stopRecordButton.Visible = true game.Players.LocalPlayer.PlayerGui.Menu.UserSettingsShield.Visible = false end)
&#9;stopRecordButton.Visible = false
&#9;stopRecordButton.Parent = gui
&#9;
&#9;local reportAbuseButton = createTextButton(&quot;Report Abuse&quot;,Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size18,UDim2.new(0,164,0,50),UDim2.new(0,82,0,306))
&#9;reportAbuseButton.Name = &quot;ReportAbuseButton&quot;
&#9;reportAbuseButton.ZIndex = baseZIndex + 4
&#9;reportAbuseButton.Parent = gameMainMenuFrame
reportAbuseButton.Active = true
&#9;
&#9;local leaveGameButton = createTextButton(&quot;Leave Game&quot;,Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size24,UDim2.new(0,340,0,50),UDim2.new(0,82,0,358))
&#9;leaveGameButton.Name = &quot;LeaveGameButton&quot;
&#9;leaveGameButton.ZIndex = baseZIndex + 4
&#9;leaveGameButton.Parent = gameMainMenuFrame
&#9;
&#9;local resumeGameButton = createTextButton(&quot;Resume Game&quot;,Enum.ButtonStyle.RobloxButtonDefault,Enum.FontSize.Size24,UDim2.new(0,340,0,50),UDim2.new(0,82,0,54))
&#9;resumeGameButton.Name = &quot;resumeGameButton&quot;
&#9;resumeGameButton.ZIndex = baseZIndex + 4
&#9;resumeGameButton.Parent = gameMainMenuFrame
&#9;resumeGameButton.Modal = true
&#9;resumeGameButton.MouseButton1Click:connect(function() resumeGameFunction(shield) end)
&#9;
&#9;local gameSettingsButton = createTextButton(&quot;Game Settings&quot;,Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size24,UDim2.new(0,340,0,50),UDim2.new(0,82,0,156))
&#9;gameSettingsButton.Name = &quot;SettingsButton&quot;
&#9;gameSettingsButton.ZIndex = baseZIndex + 4
&#9;gameSettingsButton.Parent = gameMainMenuFrame
&#9;
&#9;if game:FindFirstChild(&quot;LoadingGuiService&quot;) and #game.LoadingGuiService:GetChildren() &gt; 0 then
&#9;&#9;local gameSettingsButton = createTextButton(&quot;Game Instructions&quot;,Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size24,UDim2.new(0,340,0,50),UDim2.new(0,82,0,207))
&#9;&#9;gameSettingsButton.Name = &quot;GameInstructions&quot;
&#9;&#9;gameSettingsButton.ZIndex = baseZIndex + 4
&#9;&#9;gameSettingsButton.Parent = gameMainMenuFrame
&#9;&#9;gameSettingsButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;if game:FindFirstChild(&quot;Players&quot;) and game.Players[&quot;LocalPlayer&quot;] then
&#9;&#9;&#9;&#9;local loadingGui = game.Players.LocalPlayer:FindFirstChild(&quot;PlayerLoadingGui&quot;)
&#9;&#9;&#9;&#9;if loadingGui then
&#9;&#9;&#9;&#9;&#9;loadingGui.Visible = true
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;end
&#9;
&#9;local resetButton = createTextButton(&quot;Reset Character&quot;,Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size24,UDim2.new(0,340,0,50),UDim2.new(0,82,0,105))
&#9;resetButton.Name = &quot;ResetButton&quot;
&#9;resetButton.ZIndex = baseZIndex + 4
&#9;resetButton.Parent = gameMainMenuFrame
&#9;
&#9;return gameMainMenuFrame
end
local function createGameSettingsMenu(baseZIndex, shield)
&#9;local gameSettingsMenuFrame = Instance.new(&quot;Frame&quot;)
&#9;gameSettingsMenuFrame.Name = &quot;GameSettingsMenu&quot;
&#9;gameSettingsMenuFrame.BackgroundTransparency = 1
&#9;gameSettingsMenuFrame.Size = UDim2.new(1,0,1,0)
&#9;gameSettingsMenuFrame.ZIndex = baseZIndex + 4
&#9;
&#9;local title = Instance.new(&quot;TextLabel&quot;)
&#9;title.Name = &quot;Title&quot;
&#9;title.Text = &quot;Settings&quot;
&#9;title.Size = UDim2.new(1,0,0,48)
&#9;title.Position = UDim2.new(0,9,0,-9)
&#9;title.Font = Enum.Font.ArialBold
&#9;title.FontSize = Enum.FontSize.Size36
&#9;title.TextColor3 = Color3.new(1,1,1)
&#9;title.ZIndex = baseZIndex + 4
&#9;title.BackgroundTransparency = 1
&#9;title.Parent = gameSettingsMenuFrame
&#9;
&#9;
&#9;--[[
&#9;local studioText = Instance.new(&quot;TextLabel&quot;)
&#9;studioText.Visible = false
&#9;studioText.Name = &quot;StudioText&quot;
&#9;studioText.Text = &quot;Studio Mode&quot;
&#9;studioText.Size = UDim2.new(0,95,0,18)
&#9;studioText.Position = UDim2.new(0,62,0,179)
&#9;studioText.Font = Enum.Font.Arial
&#9;studioText.FontSize = Enum.FontSize.Size18
&#9;studioText.TextColor3 = Color3.new(1,1,1)
&#9;studioText.ZIndex = baseZIndex + 4
&#9;studioText.BackgroundTransparency = 1
&#9;studioText.Parent = gameSettingsMenuFrame
&#9;
&#9;local studioShortcut = fullscreenShortcut:clone()
&#9;studioShortcut.Name = &quot;StudioShortcutText&quot;
&#9;studioShortcut.Visible = false -- TODO: turn back on when f2 hack is fixed
&#9;studioShortcut.Text = &quot;F2&quot;
&#9;studioShortcut.Position = UDim2.new(0,154,0,175)
&#9;studioShortcut.Parent = gameSettingsMenuFrame
&#9;
&#9;local studioCheckbox = nil
&#9;--]]
&#9;local itemTop = 35
&#9;----------------------------------------------------------------------------------------------------
&#9;-- C A M E R A C O N T R O L S
&#9;----------------------------------------------------------------------------------------------------
&#9;if not touchClient then
&#9;&#9;local cameraLabel = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;cameraLabel.Name = &quot;CameraLabel&quot;
&#9;&#9;cameraLabel.Text = &quot;Character &amp; Camera Controls&quot;
&#9;&#9;cameraLabel.Font = Enum.Font.Arial
&#9;&#9;cameraLabel.FontSize = Enum.FontSize.Size18
&#9;&#9;cameraLabel.Position = UDim2.new(0,31,0,itemTop + 6)
&#9;&#9;cameraLabel.Size = UDim2.new(0,224,0,18)
&#9;&#9;cameraLabel.TextColor3 = Color3I(255,255,255)
&#9;&#9;cameraLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;cameraLabel.BackgroundTransparency = 1
&#9;&#9;cameraLabel.ZIndex = baseZIndex + 4
&#9;&#9;cameraLabel.Parent = gameSettingsMenuFrame
local mouseLockLabel = nil
&#9;&#9;local enumItems = Enum.ControlMode:GetEnumItems()
&#9;&#9;local enumNames = {}
&#9;&#9;local enumNameToItem = {}
&#9;&#9;for i,obj in ipairs(enumItems) do
&#9;&#9;&#9;enumNames[i] = obj.Name
&#9;&#9;&#9;enumNameToItem[obj.Name] = obj
&#9;&#9;end
&#9;&#9;local cameraDropDown
&#9;&#9;cameraDropDown, updateCameraDropDownSelection = RbxGui.CreateDropDownMenu(enumNames,
&#9;&#9;&#9;function(text)
&#9;&#9;&#9;&#9;UserSettings().GameSettings.ControlMode = enumNameToItem[text]
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;pcall(function()
&#9;&#9;&#9;&#9;&#9;if mouseLockLabel and UserSettings().GameSettings.ControlMode == Enum.ControlMode[&quot;Mouse Lock Switch&quot;] then
&#9;&#9;&#9;&#9;&#9;&#9;mouseLockLabel.Visible = true
&#9;&#9;&#9;&#9;&#9;elseif mouseLockLabel then
&#9;&#9;&#9;&#9;&#9;&#9;mouseLockLabel.Visible = false
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end)
&#9;&#9;cameraDropDown.Name = &quot;CameraField&quot;
&#9;&#9;cameraDropDown.ZIndex = baseZIndex + 4
&#9;&#9;cameraDropDown.DropDownMenuButton.ZIndex = baseZIndex + 4
&#9;&#9;cameraDropDown.DropDownMenuButton.Icon.ZIndex = baseZIndex + 4
&#9;&#9;cameraDropDown.Position = UDim2.new(0, 270, 0, itemTop)
&#9;&#9;cameraDropDown.Size = UDim2.new(0,200,0,32)
&#9;&#9;cameraDropDown.Parent = gameSettingsMenuFrame
&#9;&#9;itemTop = itemTop + 35
&#9;end
&#9;----------------------------------------------------------------------------------------------------
&#9;-- V I D E O C A P T U R E S E T T I N G S
&#9;----------------------------------------------------------------------------------------------------
&#9;local syncVideoCaptureSetting = nil
&#9;if not macClient and not touchClient then
&#9;&#9;local videoCaptureLabel = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;videoCaptureLabel.Name = &quot;VideoCaptureLabel&quot;
&#9;&#9;videoCaptureLabel.Text = &quot;After Capturing Video&quot;
&#9;&#9;videoCaptureLabel.Font = Enum.Font.Arial
&#9;&#9;videoCaptureLabel.FontSize = Enum.FontSize.Size18
&#9;&#9;videoCaptureLabel.Position = UDim2.new(0,32,0,itemTop + 6)
&#9;&#9;videoCaptureLabel.Size = UDim2.new(0,164,0,18)
&#9;&#9;videoCaptureLabel.BackgroundTransparency = 1
&#9;&#9;videoCaptureLabel.TextColor3 = Color3I(255,255,255)
&#9;&#9;videoCaptureLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;videoCaptureLabel.ZIndex = baseZIndex + 4
&#9;&#9;videoCaptureLabel.Parent = gameSettingsMenuFrame
&#9;&#9;local videoNames = {}
&#9;&#9;local videoNameToItem = {}
&#9;&#9;videoNames[1] = &quot;Just Save to Disk&quot;
&#9;&#9;videoNameToItem[videoNames[1]] = Enum.UploadSetting[&quot;Never&quot;]
&#9;&#9;videoNames[2] = &quot;Upload to YouTube&quot;
&#9;&#9;videoNameToItem[videoNames[2]] = Enum.UploadSetting[&quot;Ask me first&quot;]
&#9;&#9;local videoCaptureDropDown = nil
&#9;&#9;videoCaptureDropDown, updateVideoCaptureDropDownSelection = RbxGui.CreateDropDownMenu(videoNames,
&#9;&#9;&#9;function(text)
&#9;&#9;&#9;&#9;UserSettings().GameSettings.VideoUploadPromptBehavior = videoNameToItem[text]
&#9;&#9;&#9;end)
&#9;&#9;videoCaptureDropDown.Name = &quot;VideoCaptureField&quot;
&#9;&#9;videoCaptureDropDown.ZIndex = baseZIndex + 4
&#9;&#9;videoCaptureDropDown.DropDownMenuButton.ZIndex = baseZIndex + 4
&#9;&#9;videoCaptureDropDown.DropDownMenuButton.Icon.ZIndex = baseZIndex + 4
&#9;&#9;videoCaptureDropDown.Position = UDim2.new(0, 270, 0, itemTop)
&#9;&#9;videoCaptureDropDown.Size = UDim2.new(0,200,0,32)
&#9;&#9;videoCaptureDropDown.Parent = gameSettingsMenuFrame
&#9;&#9;syncVideoCaptureSetting = function()
&#9;&#9;&#9;if UserSettings().GameSettings.VideoUploadPromptBehavior == Enum.UploadSetting[&quot;Never&quot;] then
&#9;&#9;&#9;&#9;updateVideoCaptureDropDownSelection(videoNames[1])
&#9;&#9;&#9;elseif UserSettings().GameSettings.VideoUploadPromptBehavior == Enum.UploadSetting[&quot;Ask me first&quot;] then
&#9;&#9;&#9;&#9;updateVideoCaptureDropDownSelection(videoNames[2])
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;UserSettings().GameSettings.VideoUploadPromptBehavior = Enum.UploadSetting[&quot;Ask me first&quot;]
&#9;&#9;&#9;&#9;updateVideoCaptureDropDownSelection(videoNames[2])
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;itemTop = itemTop + 35
&#9;end
&#9;
&#9;----------------------------------------------------------------------------------------------------
&#9;-- C U S T O M C A M E R A C O N T R O L S
&#9;----------------------------------------------------------------------------------------------------
&#9;----------------------------------------------------------------------------------------------------
&#9;-- F U L L S C R E E N M O D E
&#9;----------------------------------------------------------------------------------------------------
&#9;local fullscreenText = nil
&#9;local fullscreenShortcut = nil
&#9;local fullscreenCheckbox = nil
&#9;if not touchClient then
&#9;&#9;fullscreenText = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;fullscreenText.Name = &quot;FullscreenText&quot;
&#9;&#9;fullscreenText.Text = &quot;Fullscreen Mode&quot;
&#9;&#9;fullscreenText.Size = UDim2.new(0,124,0,18)
&#9;&#9;fullscreenText.Position = UDim2.new(0,62,0,itemTop + 2)
&#9;&#9;fullscreenText.Font = Enum.Font.Arial
&#9;&#9;fullscreenText.FontSize = Enum.FontSize.Size18
&#9;&#9;fullscreenText.TextColor3 = Color3.new(1,1,1)
&#9;&#9;fullscreenText.ZIndex = baseZIndex + 4
&#9;&#9;fullscreenText.BackgroundTransparency = 1
&#9;&#9;fullscreenText.Parent = gameSettingsMenuFrame
&#9;&#9;
&#9;&#9;fullscreenShortcut = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;fullscreenShortcut.Visible = hasGraphicsSlider
&#9;&#9;fullscreenShortcut.Name = &quot;FullscreenShortcutText&quot;
&#9;&#9;fullscreenShortcut.Text = &quot;F11&quot;
&#9;&#9;fullscreenShortcut.BackgroundTransparency = 1
&#9;&#9;fullscreenShortcut.Font = Enum.Font.Arial
&#9;&#9;fullscreenShortcut.FontSize = Enum.FontSize.Size12
&#9;&#9;fullscreenShortcut.Position = UDim2.new(0,186,0,itemTop - 4)
&#9;&#9;fullscreenShortcut.Size = UDim2.new(0,30,0,30)
&#9;&#9;fullscreenShortcut.TextColor3 = Color3.new(0,1,0)
&#9;&#9;fullscreenShortcut.ZIndex = baseZIndex + 4
&#9;&#9;fullscreenShortcut.Parent = gameSettingsMenuFrame
&#9;&#9;
&#9;&#9;fullscreenCheckbox = createTextButton(&quot;&quot;,Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size18,UDim2.new(0,25,0,25),UDim2.new(0,30,0,itemTop))
&#9;&#9;fullscreenCheckbox.Name = &quot;FullscreenCheckbox&quot;
&#9;&#9;fullscreenCheckbox.ZIndex = baseZIndex + 4
&#9;&#9;fullscreenCheckbox.Parent = gameSettingsMenuFrame
&#9;&#9;fullscreenCheckbox:SetVerb(&quot;ToggleFullScreen&quot;)
&#9;&#9;if UserSettings().GameSettings:InFullScreen() then fullscreenCheckbox.Text = &quot;X&quot; end
&#9;&#9;if hasGraphicsSlider then
&#9;&#9;&#9;UserSettings().GameSettings.FullscreenChanged:connect(function(isFullscreen)
&#9;&#9;&#9;&#9;if isFullscreen then
&#9;&#9;&#9;&#9;&#9;fullscreenCheckbox.Text = &quot;X&quot;
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;fullscreenCheckbox.Text = &quot;&quot;
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;else
&#9;&#9;&#9;fullscreenCheckbox.MouseButton1Click:connect(function()
&#9;&#9;&#9;&#9;if fullscreenCheckbox.Text == &quot;&quot; then
&#9;&#9;&#9;&#9;&#9;fullscreenCheckbox.Text = &quot;X&quot;
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;fullscreenCheckbox.Text = &quot;&quot;
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)&#9;
&#9;&#9;end
&#9;end
&#9;----------------------------------------------------------------------------------------------------
&#9;-- G R A P H I C S S L I D E R
&#9;----------------------------------------------------------------------------------------------------
&#9;if hasGraphicsSlider then
&#9;&#9;local qualityText = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;qualityText.Name = &quot;QualityText&quot;
&#9;&#9;qualityText.Text = &quot;Graphics Quality&quot;
&#9;&#9;qualityText.Size = UDim2.new(0,128,0,18)
&#9;&#9;qualityText.Position = UDim2.new(0,30,0,239)
&#9;&#9;qualityText.Font = Enum.Font.Arial
&#9;&#9;qualityText.FontSize = Enum.FontSize.Size18
&#9;&#9;qualityText.TextColor3 = Color3.new(1,1,1)
&#9;&#9;qualityText.ZIndex = baseZIndex + 4
&#9;&#9;qualityText.BackgroundTransparency = 1
&#9;&#9;qualityText.Parent = gameSettingsMenuFrame
&#9;&#9;qualityText.Visible = not inStudioMode
&#9;&#9;
&#9;&#9;local autoText = qualityText:clone()
&#9;&#9;autoText.Name = &quot;AutoText&quot;
&#9;&#9;autoText.Text = &quot;Auto&quot;
&#9;&#9;autoText.Position = UDim2.new(0,183,0,214)
&#9;&#9;autoText.TextColor3 = Color3.new(128/255,128/255,128/255)
&#9;&#9;autoText.Size = UDim2.new(0,34,0,18)
&#9;&#9;autoText.Parent = gameSettingsMenuFrame
&#9;&#9;autoText.Visible = not inStudioMode
&#9;&#9;
&#9;&#9;local fasterText = autoText:clone()
&#9;&#9;fasterText.Name = &quot;FasterText&quot;
&#9;&#9;fasterText.Text = &quot;Faster&quot;
&#9;&#9;fasterText.Position = UDim2.new(0,185,0,274)
&#9;&#9;fasterText.TextColor3 = Color3.new(95,95,95)
&#9;&#9;fasterText.FontSize = Enum.FontSize.Size14
&#9;&#9;fasterText.Parent = gameSettingsMenuFrame
&#9;&#9;fasterText.Visible = not inStudioMode
&#9;&#9;
&#9;&#9;local fasterShortcut = fullscreenShortcut:clone()
&#9;&#9;fasterShortcut.Name = &quot;FasterShortcutText&quot;
&#9;&#9;fasterShortcut.Text = &quot;F10 + Shift&quot;
&#9;&#9;fasterShortcut.Position = UDim2.new(0,185,0,283)
&#9;&#9;fasterShortcut.Parent = gameSettingsMenuFrame
&#9;&#9;fasterShortcut.Visible = not inStudioMode
&#9;&#9;
&#9;&#9;local betterQualityText = autoText:clone()
&#9;&#9;betterQualityText.Name = &quot;BetterQualityText&quot;
&#9;&#9;betterQualityText.Text = &quot;Better Quality&quot;
&#9;&#9;betterQualityText.TextWrap = true
&#9;&#9;betterQualityText.Size = UDim2.new(0,41,0,28)
&#9;&#9;betterQualityText.Position = UDim2.new(0,390,0,269)
&#9;&#9;betterQualityText.TextColor3 = Color3.new(95,95,95)
&#9;&#9;betterQualityText.FontSize = Enum.FontSize.Size14
&#9;&#9;betterQualityText.Parent = gameSettingsMenuFrame
&#9;&#9;betterQualityText.Visible = not inStudioMode
&#9;&#9;
&#9;&#9;local betterQualityShortcut = fullscreenShortcut:clone()
&#9;&#9;betterQualityShortcut.Name = &quot;BetterQualityShortcut&quot;
&#9;&#9;betterQualityShortcut.Text = &quot;F10&quot;
&#9;&#9;betterQualityShortcut.Position = UDim2.new(0,394,0,288)
&#9;&#9;betterQualityShortcut.Parent = gameSettingsMenuFrame
&#9;&#9;betterQualityShortcut.Visible = not inStudioMode
&#9;&#9;
&#9;&#9;local autoGraphicsButton = createTextButton(&quot;X&quot;,Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size18,UDim2.new(0,25,0,25),UDim2.new(0,187,0,239))
&#9;&#9;autoGraphicsButton.Name = &quot;AutoGraphicsButton&quot;
&#9;&#9;autoGraphicsButton.ZIndex = baseZIndex + 4
&#9;&#9;autoGraphicsButton.Parent = gameSettingsMenuFrame
&#9;&#9;autoGraphicsButton.Visible = not inStudioMode
&#9;&#9;
&#9;&#9;local graphicsSlider, graphicsLevel = RbxGui.CreateSlider(GraphicsQualityLevels,150,UDim2.new(0, 230, 0, 280)) -- graphics - 1 because slider starts at 1 instead of 0
&#9;&#9;graphicsSlider.Parent = gameSettingsMenuFrame
&#9;&#9;graphicsSlider.Bar.ZIndex = baseZIndex + 4
&#9;&#9;graphicsSlider.Bar.Slider.ZIndex = baseZIndex + 5
&#9;&#9;graphicsSlider.Visible = not inStudioMode
&#9;&#9;graphicsLevel.Value = math.floor((settings().Rendering:GetMaxQualityLevel() - 1)/2)
&#9;&#9;
&#9;&#9;local graphicsSetter = Instance.new(&quot;TextBox&quot;)
&#9;&#9;graphicsSetter.Name = &quot;GraphicsSetter&quot;
&#9;&#9;graphicsSetter.BackgroundColor3 = Color3.new(0,0,0)
&#9;&#9;graphicsSetter.BorderColor3 = Color3.new(128/255,128/255,128/255)
&#9;&#9;graphicsSetter.Size = UDim2.new(0,50,0,25)
&#9;&#9;graphicsSetter.Position = UDim2.new(0,450,0,269)
&#9;&#9;graphicsSetter.TextColor3 = Color3.new(1,1,1)
&#9;&#9;graphicsSetter.Font = Enum.Font.Arial
&#9;&#9;graphicsSetter.FontSize = Enum.FontSize.Size18
&#9;&#9;graphicsSetter.Text = &quot;Auto&quot;
&#9;&#9;graphicsSetter.ZIndex = 1
&#9;&#9;graphicsSetter.TextWrap = true
&#9;&#9;graphicsSetter.Parent = gameSettingsMenuFrame
&#9;&#9;graphicsSetter.Visible = not inStudioMode
&#9;&#9;local isAutoGraphics = true
&#9;&#9;if not inStudioMode then
&#9;&#9;&#9;isAutoGraphics = (UserSettings().GameSettings.SavedQualityLevel == Enum.SavedQualitySetting.Automatic)
&#9;&#9;else
&#9;&#9;&#9;settings().Rendering.EnableFRM = false
&#9;&#9;end
&#9;&#9;
&#9;&#9;local listenToGraphicsLevelChange = true
&#9;&#9;
&#9;&#9;local function setAutoGraphicsGui(active)
&#9;&#9;&#9;isAutoGraphics = active
&#9;&#9;&#9;if active then
&#9;&#9;&#9;&#9;autoGraphicsButton.Text = &quot;X&quot;
&#9;&#9;&#9;&#9;betterQualityText.ZIndex = 1
&#9;&#9;&#9;&#9;betterQualityShortcut.ZIndex = 1
&#9;&#9;&#9;&#9;fasterShortcut.ZIndex = 1
&#9;&#9;&#9;&#9;fasterText.ZIndex = 1
&#9;&#9;&#9;&#9;graphicsSlider.Bar.ZIndex = 1
&#9;&#9;&#9;&#9;graphicsSlider.Bar.Slider.ZIndex = 1
&#9;&#9;&#9;&#9;graphicsSetter.ZIndex = 1
&#9;&#9;&#9;&#9;graphicsSetter.Text = &quot;Auto&quot;
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;autoGraphicsButton.Text = &quot;&quot;
&#9;&#9;&#9;&#9;graphicsSlider.Bar.ZIndex = baseZIndex + 4
&#9;&#9;&#9;&#9;graphicsSlider.Bar.Slider.ZIndex = baseZIndex + 5
&#9;&#9;&#9;&#9;betterQualityShortcut.ZIndex = baseZIndex + 4
&#9;&#9;&#9;&#9;fasterShortcut.ZIndex = baseZIndex + 4
&#9;&#9;&#9;&#9;betterQualityText.ZIndex = baseZIndex + 4
&#9;&#9;&#9;&#9;fasterText.ZIndex = baseZIndex + 4
&#9;&#9;&#9;&#9;graphicsSetter.ZIndex = baseZIndex + 4
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;
&#9;&#9;local function goToAutoGraphics()
&#9;&#9;&#9;setAutoGraphicsGui(true)
&#9;&#9;&#9;
&#9;&#9;&#9;UserSettings().GameSettings.SavedQualityLevel = Enum.SavedQualitySetting.Automatic
&#9;&#9;&#9;
&#9;&#9;&#9;settings().Rendering.QualityLevel = Enum.QualityLevel.Automatic
&#9;&#9;end
&#9;&#9;&#9;&#9;
&#9;&#9;local function setGraphicsQualityLevel(newLevel)
&#9;&#9;&#9;local percentage = newLevel/GraphicsQualityLevels
&#9;&#9;&#9;local newSetting = math.floor((settings().Rendering:GetMaxQualityLevel() - 1) * percentage)
&#9;&#9;&#9;if newSetting == 20 then -- Level 20 is the same as level 21, except it doesn&apos;t render ambient occlusion
&#9;&#9;&#9;&#9;newSetting = 21
&#9;&#9;&#9;elseif newLevel == 1 then -- make sure we can go to lowest settings (for terrible computers)
&#9;&#9;&#9;&#9;newSetting = 1
&#9;&#9;&#9;elseif newSetting &gt; settings().Rendering:GetMaxQualityLevel() then
&#9;&#9;&#9;&#9;newSetting = settings().Rendering:GetMaxQualityLevel() - 1
&#9;&#9;&#9;end
&#9;&#9;&#9;
&#9;&#9;&#9;UserSettings().GameSettings.SavedQualityLevel = newLevel
&#9;&#9;&#9;settings().Rendering.QualityLevel = newSetting
&#9;&#9;end
&#9;&#9;
&#9;&#9;local function goToManualGraphics(explicitLevel)
&#9;&#9;&#9; setAutoGraphicsGui(false)
&#9;&#9;&#9;
&#9;&#9;&#9;if explicitLevel then
&#9;&#9;&#9;&#9;graphicsLevel.Value = explicitLevel
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;graphicsLevel.Value = math.floor((settings().Rendering.AutoFRMLevel/(settings().Rendering:GetMaxQualityLevel() - 1)) * GraphicsQualityLevels)
&#9;&#9;&#9;end
&#9;&#9;&#9;
&#9;&#9;&#9;if explicitLevel == graphicsLevel.Value then -- make sure we are actually in right graphics mode
&#9;&#9;&#9;&#9;setGraphicsQualityLevel(graphicsLevel.Value)
&#9;&#9;&#9;end
&#9;&#9;&#9;
&#9;&#9;&#9;if not explicitLevel then
&#9;&#9;&#9;&#9;UserSettings().GameSettings.SavedQualityLevel = graphicsLevel.Value
&#9;&#9;&#9;end
&#9;&#9;&#9;graphicsSetter.Text = tostring(graphicsLevel.Value)
&#9;&#9;end
&#9;&#9;
&#9;&#9;local function showAutoGraphics()
&#9;&#9;&#9;autoText.ZIndex = baseZIndex + 4
&#9;&#9;&#9;autoGraphicsButton.ZIndex = baseZIndex + 4
&#9;&#9;end
&#9;&#9;
&#9;&#9;local function hideAutoGraphics()
&#9;&#9;&#9;autoText.ZIndex = 1
&#9;&#9;&#9;autoGraphicsButton.ZIndex = 1
&#9;&#9;end
&#9;&#9;
&#9;&#9;local function showManualGraphics()
&#9;&#9;&#9;graphicsSlider.Bar.ZIndex = baseZIndex + 4
&#9;&#9;&#9;graphicsSlider.Bar.Slider.ZIndex = baseZIndex + 5
&#9;&#9;&#9;betterQualityShortcut.ZIndex = baseZIndex + 4
&#9;&#9;&#9;fasterShortcut.ZIndex = baseZIndex + 4
&#9;&#9;&#9;betterQualityText.ZIndex = baseZIndex + 4
&#9;&#9;&#9;fasterText.ZIndex = baseZIndex + 4
&#9;&#9;&#9;graphicsSetter.ZIndex = baseZIndex + 4
&#9;&#9;end
&#9;&#9;
&#9;&#9;local function hideManualGraphics()
&#9;&#9;&#9;betterQualityText.ZIndex = 1
&#9;&#9;&#9;betterQualityShortcut.ZIndex = 1
&#9;&#9;&#9;fasterShortcut.ZIndex = 1
&#9;&#9;&#9;fasterText.ZIndex = 1
&#9;&#9;&#9;graphicsSlider.Bar.ZIndex = 1
&#9;&#9;&#9;graphicsSlider.Bar.Slider.ZIndex = 1
&#9;&#9;&#9;graphicsSetter.ZIndex = 1
&#9;&#9;end
&#9;&#9;
&#9;&#9;local function translateSavedQualityLevelToInt(savedQualityLevel)
&#9;&#9;&#9;if savedQualityLevel == Enum.SavedQualitySetting.Automatic then
&#9;&#9;&#9;&#9;return 0
&#9;&#9;&#9;elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel1 then
&#9;&#9;&#9;&#9;return 1
&#9;&#9;&#9;elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel2 then
&#9;&#9;&#9;&#9;return 2
&#9;&#9;&#9;elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel3 then
&#9;&#9;&#9;&#9;return 3
&#9;&#9;&#9;elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel4 then
&#9;&#9;&#9;&#9;return 4
&#9;&#9;&#9;elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel5 then
&#9;&#9;&#9;&#9;return 5
&#9;&#9;&#9;elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel6 then
&#9;&#9;&#9;&#9;return 6
&#9;&#9;&#9;elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel7 then
&#9;&#9;&#9;&#9;return 7
&#9;&#9;&#9;elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel8 then
&#9;&#9;&#9;&#9;return 8
&#9;&#9;&#9;elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel9 then
&#9;&#9;&#9;&#9;return 9
&#9;&#9;&#9;elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel10 then
&#9;&#9;&#9;&#9;return 10
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;
&#9;&#9;local function enableGraphicsWidget()
&#9;&#9;&#9;settings().Rendering.EnableFRM = true
&#9;&#9;&#9;
&#9;&#9;&#9;isAutoGraphics = (UserSettings().GameSettings.SavedQualityLevel == Enum.SavedQualitySetting.Automatic)
&#9;&#9;&#9;if isAutoGraphics then
&#9;&#9;&#9;&#9;showAutoGraphics()
&#9;&#9;&#9;&#9;goToAutoGraphics()
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;showAutoGraphics()
&#9;&#9;&#9;&#9;showManualGraphics()
&#9;&#9;&#9;&#9;goToManualGraphics(translateSavedQualityLevelToInt(UserSettings().GameSettings.SavedQualityLevel))
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;
&#9;&#9;local function disableGraphicsWidget()
&#9;&#9;&#9;hideManualGraphics()
&#9;&#9;&#9;hideAutoGraphics()
&#9;&#9;&#9;settings().Rendering.EnableFRM = false
&#9;&#9;end
&#9;&#9;
&#9;&#9;graphicsSetter.FocusLost:connect(function()
&#9;&#9;&#9;if isAutoGraphics then
&#9;&#9;&#9;&#9;graphicsSetter.Text = tostring(graphicsLevel.Value)
&#9;&#9;&#9;&#9;return
&#9;&#9;&#9;end
&#9;&#9;&#9;
&#9;&#9;&#9;local newGraphicsValue = tonumber(graphicsSetter.Text)
&#9;&#9;&#9;if newGraphicsValue == nil then
&#9;&#9;&#9;&#9;graphicsSetter.Text = tostring(graphicsLevel.Value)
&#9;&#9;&#9;&#9;return
&#9;&#9;&#9;end
&#9;&#9;&#9;
&#9;&#9;&#9;if newGraphicsValue &lt; 1 then newGraphicsValue = 1
&#9;&#9;&#9;elseif newGraphicsValue &gt;= settings().Rendering:GetMaxQualityLevel() then
&#9;&#9;&#9;&#9;newGraphicsValue = settings().Rendering:GetMaxQualityLevel() - 1
&#9;&#9;&#9;end
&#9;&#9;&#9;
&#9;&#9;&#9;graphicsLevel.Value = newGraphicsValue
&#9;&#9;&#9;setGraphicsQualityLevel(graphicsLevel.Value)
&#9;&#9;&#9;graphicsSetter.Text = tostring(graphicsLevel.Value)
&#9;&#9;end)
&#9;&#9;
&#9;&#9;graphicsLevel.Changed:connect(function(prop)
&#9;&#9;&#9;if isAutoGraphics then return end
&#9;&#9;&#9;if not listenToGraphicsLevelChange then return end
&#9;&#9;&#9;
&#9;&#9;&#9;graphicsSetter.Text = tostring(graphicsLevel.Value)
&#9;&#9;&#9;setGraphicsQualityLevel(graphicsLevel.Value)
&#9;&#9;end)
&#9;&#9;
&#9;&#9;-- setup our graphic mode on load
&#9;&#9;if inStudioMode or UserSettings().GameSettings.SavedQualityLevel == Enum.SavedQualitySetting.Automatic then
&#9;&#9;&#9;if inStudioMode then
&#9;&#9;&#9;&#9;settings().Rendering.EnableFRM = false
&#9;&#9;&#9;&#9;disableGraphicsWidget()
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;settings().Rendering.EnableFRM = true
&#9;&#9;&#9;&#9;goToAutoGraphics()
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;settings().Rendering.EnableFRM = true
&#9;&#9;&#9;goToManualGraphics(translateSavedQualityLevelToInt(UserSettings().GameSettings.SavedQualityLevel))
&#9;&#9;end
&#9;&#9;
&#9;&#9;autoGraphicsButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;if inStudioMode and not game.Players.LocalPlayer then return end
&#9;&#9;&#9;
&#9;&#9;&#9;if not isAutoGraphics then
&#9;&#9;&#9;&#9;goToAutoGraphics()
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;goToManualGraphics(graphicsLevel.Value)
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;&#9;
&#9;&#9;local lastUpdate = nil
&#9;&#9;game.GraphicsQualityChangeRequest:connect(function(graphicsIncrease)
&#9;&#9;&#9;if isAutoGraphics then return end -- only can set graphics in manual mode
&#9;&#9;&#9;
&#9;&#9;&#9;if graphicsIncrease then
&#9;&#9;&#9;&#9;if (graphicsLevel.Value + 1) &gt; GraphicsQualityLevels then return end
&#9;&#9;&#9;&#9;graphicsLevel.Value = graphicsLevel.Value + 1
&#9;&#9;&#9;&#9;graphicsSetter.Text = tostring(graphicsLevel.Value)
&#9;&#9;&#9;&#9;setGraphicsQualityLevel(graphicsLevel.Value)
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;game:GetService(&quot;GuiService&quot;):SendNotification(&quot;Graphics Quality&quot;,
&#9;&#9;&#9;&#9;&#9;&quot;Increased to (&quot; .. graphicsSetter.Text .. &quot;)&quot;,
&#9;&#9;&#9;&#9;&#9;&quot;&quot;,
&#9;&#9;&#9;&#9;&#9;2,
&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;if (graphicsLevel.Value - 1) &lt;= 0 then return end
&#9;&#9;&#9;&#9;graphicsLevel.Value = graphicsLevel.Value - 1
&#9;&#9;&#9;&#9;graphicsSetter.Text = tostring(graphicsLevel.Value)
&#9;&#9;&#9;&#9;setGraphicsQualityLevel(graphicsLevel.Value)
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;game:GetService(&quot;GuiService&quot;):SendNotification(&quot;Graphics Quality&quot;,
&#9;&#9;&#9;&#9;&#9;&quot;Decreased to (&quot; .. graphicsSetter.Text .. &quot;)&quot;,
&#9;&#9;&#9;&#9;&#9;&quot;&quot;,
&#9;&#9;&#9;&#9;&#9;2,
&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;&#9;
&#9;&#9;game.Players.PlayerAdded:connect(function(player)
&#9;&#9;&#9;if player == game.Players.LocalPlayer and inStudioMode then
&#9;&#9;&#9;&#9;enableGraphicsWidget()
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;&#9;game.Players.PlayerRemoving:connect(function(player)
&#9;&#9;&#9;if player == game.Players.LocalPlayer and inStudioMode then
&#9;&#9;&#9;&#9;disableGraphicsWidget()
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;&#9;studioCheckbox = createTextButton(&quot;&quot;,Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size18,UDim2.new(0,25,0,25),UDim2.new(0,30,0,176))
&#9;&#9;studioCheckbox.Name = &quot;StudioCheckbox&quot;
&#9;&#9;studioCheckbox.ZIndex = baseZIndex + 4
&#9;&#9;--studioCheckbox.Parent = gameSettingsMenuFrame -- todo: enable when studio h4x aren&apos;t an issue anymore
&#9;&#9;studioCheckbox:SetVerb(&quot;TogglePlayMode&quot;)
&#9;&#9;studioCheckbox.Visible = false -- todo: enabled when studio h4x aren&apos;t an issue anymore
&#9;&#9;
&#9;&#9;local wasManualGraphics = (settings().Rendering.QualityLevel ~= Enum.QualityLevel.Automatic)
&#9;&#9;if inStudioMode and not game.Players.LocalPlayer then
&#9;&#9;&#9;studioCheckbox.Text = &quot;X&quot;
&#9;&#9;&#9;disableGraphicsWidget()
&#9;&#9;elseif inStudioMode then
&#9;&#9;&#9;studioCheckbox.Text = &quot;X&quot;
&#9;&#9;&#9;enableGraphicsWidget()
&#9;&#9;end
&#9;&#9;if hasGraphicsSlider then
&#9;&#9;&#9; UserSettings().GameSettings.StudioModeChanged:connect(function(isStudioMode)
&#9;&#9;&#9;&#9;inStudioMode = isStudioMode
&#9;&#9;&#9;&#9;if isStudioMode then
&#9;&#9;&#9;&#9;&#9;wasManualGraphics = (settings().Rendering.QualityLevel ~= Enum.QualityLevel.Automatic)
&#9;&#9;&#9;&#9;&#9;goToAutoGraphics()
&#9;&#9;&#9;&#9;&#9;studioCheckbox.Text = &quot;X&quot;
&#9;&#9;&#9;&#9;&#9;autoGraphicsButton.ZIndex = 1
&#9;&#9;&#9;&#9;&#9;autoText.ZIndex = 1
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;if wasManualGraphics then
&#9;&#9;&#9;&#9;&#9;&#9;goToManualGraphics()
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;studioCheckbox.Text = &quot;&quot;
&#9;&#9;&#9;&#9;&#9;autoGraphicsButton.ZIndex = baseZIndex + 4
&#9;&#9;&#9;&#9;&#9;autoText.ZIndex = baseZIndex + 4
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;else
&#9;&#9;&#9;studioCheckbox.MouseButton1Click:connect(function()
&#9;&#9;&#9;&#9;if not studioCheckbox.Active then return end
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;if studioCheckbox.Text == &quot;&quot; then
&#9;&#9;&#9;&#9;&#9;studioCheckbox.Text = &quot;X&quot;
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;studioCheckbox.Text = &quot;&quot;
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;end
&#9;end
&#9;
&#9;if game:FindFirstChild(&quot;NetworkClient&quot;) then -- we are playing online
&#9;&#9;setDisabledState(studioText)
&#9;&#9;setDisabledState(studioShortcut)
&#9;&#9;setDisabledState(studioCheckbox)
&#9;end
&#9;
&#9;----------------------------------------------------------------------------------------------------
&#9;-- O K B U T T O N
&#9;----------------------------------------------------------------------------------------------------
&#9;local backButton
&#9;if hasGraphicsSlider then
&#9;&#9;backButton = createTextButton(&quot;OK&quot;,Enum.ButtonStyle.RobloxButtonDefault,Enum.FontSize.Size24,UDim2.new(0,180,0,50),UDim2.new(0,170,0,330))
&#9;&#9;backButton.Modal = true
&#9;else
&#9;&#9;backButton = createTextButton(&quot;OK&quot;,Enum.ButtonStyle.RobloxButtonDefault,Enum.FontSize.Size24,UDim2.new(0,180,0,50),UDim2.new(0,170,0,270))
&#9;&#9;backButton.Modal = true
&#9;end
&#9;
&#9;backButton.Name = &quot;BackButton&quot;
&#9;backButton.ZIndex = baseZIndex + 4
&#9;backButton.Parent = gameSettingsMenuFrame
&#9;
&#9;return gameSettingsMenuFrame
end
if LoadLibrary then
RbxGui = t
local baseZIndex = 0
if UserSettings then
local createReportAbuseDialog = function()
&#9;waitForChild(game,&quot;Players&quot;)
&#9;waitForProperty(game.Players, &quot;LocalPlayer&quot;)
&#9;local localPlayer = game.Players.LocalPlayer
&#9;
&#9;local reportAbuseButton
&#9;waitForChild(script.Parent,&quot;UserSettingsShield&quot;)
&#9;waitForChild(script.Parent.UserSettingsShield, &quot;Settings&quot;)
&#9;waitForChild(script.Parent.UserSettingsShield.Settings,&quot;SettingsStyle&quot;)
&#9;waitForChild(script.Parent.UserSettingsShield.Settings.SettingsStyle,&quot;GameMainMenu&quot;)
&#9;waitForChild(script.Parent.UserSettingsShield.Settings.SettingsStyle.GameMainMenu, &quot;ReportAbuseButton&quot;)
&#9;reportAbuseButton = script.Parent.UserSettingsShield.Settings.SettingsStyle.GameMainMenu.ReportAbuseButton
&#9;local shield = Instance.new(&quot;TextButton&quot;)
&#9;shield.Name = &quot;ReportAbuseShield&quot;
&#9;shield.Text = &quot;&quot;
&#9;shield.AutoButtonColor = false
&#9;shield.Active = true
&#9;shield.Visible = false
&#9;shield.Size = UDim2.new(1,0,1,0)
&#9;shield.BackgroundColor3 = Color3I(51,51,51)
&#9;shield.BorderColor3 = Color3I(27,42,53)
&#9;shield.BackgroundTransparency = 0.4
&#9;shield.ZIndex = baseZIndex + 1
&#9;local closeAndResetDialgo
&#9;local messageBoxButtons = {}
&#9;messageBoxButtons[1] = {}
&#9;messageBoxButtons[1].Text = &quot;Ok&quot;
&#9;messageBoxButtons[1].Modal = true
&#9;messageBoxButtons[1].Function = function() closeAndResetDialog() end
&#9;local calmingMessageBox = RbxGui.CreateMessageDialog(&quot;Thanks for your report!&quot;, &quot;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&quot;, messageBoxButtons)
&#9;calmingMessageBox.Visible = false
&#9;calmingMessageBox.Parent = shield
&#9;local recordedMessageBox = RbxGui.CreateMessageDialog(&quot;Thanks for your report!&quot;,&quot;We&apos;ve recorded your report for evaluation.&quot;, messageBoxButtons)
&#9;recordedMessageBox.Visible = false
&#9;recordedMessageBox.Parent = shield
&#9;local normalMessageBox = RbxGui.CreateMessageDialog(&quot;Thanks for your report!&quot;, &quot;Our moderators will review the chat logs and determine what happened.&quot;, messageBoxButtons)
&#9;normalMessageBox.Visible = false
&#9;normalMessageBox.Parent = shield
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Name = &quot;Settings&quot;
&#9;frame.Position = UDim2.new(0.5, -250, 0.5, -200)
&#9;frame.Size = UDim2.new(0.0, 500, 0.0, 400)
&#9;frame.BackgroundTransparency = 1
&#9;frame.Active = true
&#9;frame.Parent = shield
&#9;local settingsFrame = Instance.new(&quot;Frame&quot;)
&#9;settingsFrame.Name = &quot;ReportAbuseStyle&quot;
&#9;settingsFrame.Size = UDim2.new(1, 0, 1, 0)
&#9;settingsFrame.Style = Enum.FrameStyle.RobloxRound
&#9;settingsFrame.Active = true
&#9;settingsFrame.ZIndex = baseZIndex + 1
&#9;settingsFrame.Parent = frame
&#9;local title = Instance.new(&quot;TextLabel&quot;)
&#9;title.Name = &quot;Title&quot;
&#9;title.Text = &quot;Report Abuse&quot;
&#9;title.TextColor3 = Color3I(221,221,221)
&#9;title.Position = UDim2.new(0.5, 0, 0, 30)
&#9;title.Font = Enum.Font.ArialBold
&#9;title.FontSize = Enum.FontSize.Size36
&#9;title.ZIndex = baseZIndex + 2
&#9;title.Parent = settingsFrame
&#9;local description = Instance.new(&quot;TextLabel&quot;)
&#9;description.Name = &quot;Description&quot;
&#9;description.Text = &quot;This will send a complete report to a moderator. The moderator will review the chat log and take appropriate action.&quot;
&#9;description.TextColor3 = Color3I(221,221,221)
&#9;description.Position = UDim2.new(0, 0, 0, 55)
&#9;description.Size = UDim2.new(1, 0, 0, 40)
&#9;description.BackgroundTransparency = 1
&#9;description.Font = Enum.Font.Arial
&#9;description.FontSize = Enum.FontSize.Size18
&#9;description.TextWrap = true
&#9;description.ZIndex = baseZIndex + 2
&#9;description.TextXAlignment = Enum.TextXAlignment.Left
&#9;description.TextYAlignment = Enum.TextYAlignment.Top
&#9;description.Parent = settingsFrame
&#9;local playerLabel = Instance.new(&quot;TextLabel&quot;)
&#9;playerLabel.Name = &quot;PlayerLabel&quot;
&#9;playerLabel.Text = &quot;Which player?&quot;
&#9;playerLabel.BackgroundTransparency = 1
&#9;playerLabel.Font = Enum.Font.Arial
&#9;playerLabel.FontSize = Enum.FontSize.Size18
&#9;playerLabel.Position = UDim2.new(0.025,0,0,100)
&#9;playerLabel.Size &#9; = UDim2.new(0.4,0,0,36)
&#9;playerLabel.TextColor3 = Color3I(255,255,255)
&#9;playerLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;playerLabel.ZIndex = baseZIndex + 2
&#9;playerLabel.Parent = settingsFrame
&#9;local abusingPlayer = nil
&#9;local abuse = nil
&#9;local submitReportButton = nil
&#9;local updatePlayerSelection = nil
&#9;local createPlayersDropDown = function()
&#9;&#9;local players = game:GetService(&quot;Players&quot;)
&#9;&#9;local playerNames = {}
&#9;&#9;local nameToPlayer = {}
&#9;&#9;local children = players:GetChildren()
&#9;&#9;local pos = 1
&#9;&#9;if children then
&#9;&#9; for i, player in ipairs(children) do
&#9;&#9;&#9;&#9;if player:IsA(&quot;Player&quot;) and player ~= localPlayer then
&#9;&#9;&#9;&#9;&#9;playerNames[pos] = player.Name
&#9;&#9;&#9;&#9;&#9;nameToPlayer[player.Name] = player
&#9;&#9;&#9;&#9;&#9;pos = pos + 1
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;local playerDropDown = nil
&#9;&#9;playerDropDown, updatePlayerSelection = RbxGui.CreateDropDownMenu(playerNames,
&#9;&#9;&#9;function(playerName)
&#9;&#9;&#9;&#9;abusingPlayer = nameToPlayer[playerName]
&#9;&#9;&#9;&#9;if abuse and abusingPlayer then
&#9;&#9;&#9;&#9;&#9;submitReportButton.Active = true
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;playerDropDown.Name = &quot;PlayersComboBox&quot;
&#9;&#9;playerDropDown.ZIndex = baseZIndex + 2
&#9;&#9;playerDropDown.Position = UDim2.new(.425, 0, 0, 102)
&#9;&#9;playerDropDown.Size = UDim2.new(.55,0,0,32)
&#9;&#9;
&#9;&#9;return playerDropDown
&#9;end
&#9;
&#9;local abuseLabel = Instance.new(&quot;TextLabel&quot;)
&#9;abuseLabel.Name = &quot;AbuseLabel&quot;
&#9;abuseLabel.Text = &quot;Type of Abuse:&quot;
&#9;abuseLabel.Font = Enum.Font.Arial
&#9;abuseLabel.BackgroundTransparency = 1
&#9;abuseLabel.FontSize = Enum.FontSize.Size18
&#9;abuseLabel.Position = UDim2.new(0.025,0,0,140)
&#9;abuseLabel.Size = UDim2.new(0.4,0,0,36)
&#9;abuseLabel.TextColor3 = Color3I(255,255,255)
&#9;abuseLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;abuseLabel.ZIndex = baseZIndex + 2
&#9;abuseLabel.Parent = settingsFrame
&#9;local abuses = {&quot;Swearing&quot;,&quot;Bullying&quot;,&quot;Scamming&quot;,&quot;Dating&quot;,&quot;Cheating/Exploiting&quot;,&quot;Personal Questions&quot;,&quot;Offsite Links&quot;,&quot;Bad Model or Script&quot;,&quot;Bad Username&quot;}
&#9;local abuseDropDown, updateAbuseSelection = RbxGui.CreateDropDownMenu(abuses,
&#9;&#9;function(abuseText)
&#9;&#9;&#9;abuse = abuseText
&#9;&#9;&#9;if abuse and abusingPlayer then
&#9;&#9;&#9;&#9;submitReportButton.Active = true
&#9;&#9;&#9;end
&#9;&#9;end, true)
&#9;abuseDropDown.Name = &quot;AbuseComboBox&quot;
&#9;abuseDropDown.ZIndex = baseZIndex + 2
&#9;abuseDropDown.Position = UDim2.new(0.425, 0, 0, 142)
&#9;abuseDropDown.Size = UDim2.new(0.55,0,0,32)
&#9;abuseDropDown.Parent = settingsFrame
&#9;local shortDescriptionLabel = Instance.new(&quot;TextLabel&quot;)
&#9;shortDescriptionLabel.Name = &quot;ShortDescriptionLabel&quot;
&#9;shortDescriptionLabel.Text = &quot;Short Description: (optional)&quot;
&#9;shortDescriptionLabel.Font = Enum.Font.Arial
&#9;shortDescriptionLabel.FontSize = Enum.FontSize.Size18
&#9;shortDescriptionLabel.Position = UDim2.new(0.025,0,0,180)
&#9;shortDescriptionLabel.Size = UDim2.new(0.95,0,0,36)
&#9;shortDescriptionLabel.TextColor3 = Color3I(255,255,255)
&#9;shortDescriptionLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;shortDescriptionLabel.BackgroundTransparency = 1
&#9;shortDescriptionLabel.ZIndex = baseZIndex + 2
&#9;shortDescriptionLabel.Parent = settingsFrame
&#9;local shortDescriptionWrapper = Instance.new(&quot;Frame&quot;)
&#9;shortDescriptionWrapper.Name = &quot;ShortDescriptionWrapper&quot;
&#9;shortDescriptionWrapper.Position = UDim2.new(0.025,0,0,220)
&#9;shortDescriptionWrapper.Size = UDim2.new(0.95,0,1,-310)
&#9;shortDescriptionWrapper.BackgroundColor3 = Color3I(0,0,0)
&#9;shortDescriptionWrapper.BorderSizePixel = 0
&#9;shortDescriptionWrapper.ZIndex = baseZIndex + 2
&#9;shortDescriptionWrapper.Parent = settingsFrame
&#9;local shortDescriptionBox = Instance.new(&quot;TextBox&quot;)
&#9;shortDescriptionBox.Name = &quot;TextBox&quot;
&#9;shortDescriptionBox.Text = &quot;&quot;
&#9;shortDescriptionBox.ClearTextOnFocus = false
&#9;shortDescriptionBox.Font = Enum.Font.Arial
&#9;shortDescriptionBox.FontSize = Enum.FontSize.Size18
&#9;shortDescriptionBox.Position = UDim2.new(0,3,0,3)
&#9;shortDescriptionBox.Size = UDim2.new(1,-6,1,-6)
&#9;shortDescriptionBox.TextColor3 = Color3I(255,255,255)
&#9;shortDescriptionBox.TextXAlignment = Enum.TextXAlignment.Left
&#9;shortDescriptionBox.TextYAlignment = Enum.TextYAlignment.Top
&#9;shortDescriptionBox.TextWrap = true
&#9;shortDescriptionBox.BackgroundColor3 = Color3I(0,0,0)
&#9;shortDescriptionBox.BorderSizePixel = 0
&#9;shortDescriptionBox.ZIndex = baseZIndex + 2
&#9;shortDescriptionBox.Parent = shortDescriptionWrapper
&#9;submitReportButton = Instance.new(&quot;TextButton&quot;)
&#9;submitReportButton.Name = &quot;SubmitReportBtn&quot;
&#9;submitReportButton.Active = false
&#9;submitReportButton.Modal = true
&#9;submitReportButton.Font = Enum.Font.Arial
&#9;submitReportButton.FontSize = Enum.FontSize.Size18
&#9;submitReportButton.Position = UDim2.new(0.1, 0, 1, -80)
&#9;submitReportButton.Size = UDim2.new(0.35,0,0,50)
&#9;submitReportButton.AutoButtonColor = true
&#9;submitReportButton.Style = Enum.ButtonStyle.RobloxButtonDefault
&#9;submitReportButton.Text = &quot;Submit Report&quot;
&#9;submitReportButton.TextColor3 = Color3I(255,255,255)
&#9;submitReportButton.ZIndex = baseZIndex + 2
&#9;submitReportButton.Parent = settingsFrame
&#9;submitReportButton.MouseButton1Click:connect(function()
&#9;&#9;if submitReportButton.Active then
&#9;&#9;&#9;if abuse and abusingPlayer then
&#9;&#9;&#9;&#9;frame.Visible = false
&#9;&#9;&#9;&#9;game.Players:ReportAbuse(abusingPlayer, abuse, shortDescriptionBox.Text)
&#9;&#9;&#9;&#9;if abuse == &quot;Cheating/Exploiting&quot; then
&#9;&#9;&#9;&#9;&#9;recordedMessageBox.Visible = true
&#9;&#9;&#9;&#9;elseif abuse == &quot;Bullying&quot; or abuse == &quot;Swearing&quot; then
&#9;&#9;&#9;&#9;&#9;calmingMessageBox.Visible = true
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;normalMessageBox.Visible = true
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;closeAndResetDialog()
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end)
&#9;local cancelButton = Instance.new(&quot;TextButton&quot;)
&#9;cancelButton.Name = &quot;CancelBtn&quot;
&#9;cancelButton.Font = Enum.Font.Arial
&#9;cancelButton.FontSize = Enum.FontSize.Size18
&#9;cancelButton.Position = UDim2.new(0.55, 0, 1, -80)
&#9;cancelButton.Size = UDim2.new(0.35,0,0,50)
&#9;cancelButton.AutoButtonColor = true
&#9;cancelButton.Style = Enum.ButtonStyle.RobloxButtonDefault
&#9;cancelButton.Text = &quot;Cancel&quot;
&#9;cancelButton.TextColor3 = Color3I(255,255,255)
&#9;cancelButton.ZIndex = baseZIndex + 2
&#9;cancelButton.Parent = settingsFrame
&#9;closeAndResetDialog = function()
&#9;&#9;settingsButton.Active = true
&#9;&#9;currentMenuSelection = nil
&#9;&#9;lastMenuSelection = {}
&#9;&#9;--Delete old player combo box
&#9;&#9;local oldComboBox = settingsFrame:FindFirstChild(&quot;PlayersComboBox&quot;)
&#9;&#9;if oldComboBox then
&#9;&#9;&#9;oldComboBox.Parent = nil
&#9;&#9;end
&#9;&#9;
&#9;&#9;abusingPlayer = nil updatePlayerSelection(nil)
&#9;&#9;abuse = nil updateAbuseSelection(nil)
&#9;&#9;submitReportButton.Active = false
&#9;&#9;shortDescriptionBox.Text = &quot;&quot;
&#9;&#9;frame.Visible = true
&#9;&#9;calmingMessageBox.Visible = false
&#9;&#9;recordedMessageBox.Visible = false
&#9;&#9;normalMessageBox.Visible = false
&#9;&#9;shield.Visible = false&#9;&#9;
&#9;&#9;reportAbuseButton.Active = true
&#9;&#9;game.GuiService:RemoveCenterDialog(shield)
&#9;end
&#9;cancelButton.MouseButton1Click:connect(closeAndResetDialog)
&#9;
&#9;reportAbuseButton.MouseButton1Click:connect(
&#9;&#9;function()
&#9;&#9;&#9;createPlayersDropDown().Parent = settingsFrame
&#9;&#9;&#9;table.insert(centerDialogs,shield)
&#9;&#9;&#9;game.GuiService:AddCenterDialog(shield, Enum.CenterDialogType.ModalDialog,
&#9;&#9;&#9;&#9;--ShowFunction
&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;reportAbuseButton.Active = true
&#9;&#9;&#9;&#9;&#9;shield.Visible = true
&#9;&#9;&#9;&#9;&#9;mainShield.Visible = false
&#9;&#9;&#9;&#9;end,
&#9;&#9;&#9;&#9;--HideFunction
&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;reportAbuseButton.Active = true
&#9;&#9;&#9;&#9;&#9;shield.Visible = false
&#9;&#9;&#9;&#9;end)
&#9;&#9;end)
&#9;return shield
end
&#9;local createSettingsDialog = function()
&#9;&#9;waitForChild(gui,&quot;BottomLeftControl&quot;)
&#9;&#9;settingsButton = gui.BottomLeftControl:FindFirstChild(&quot;SettingsButton&quot;)
&#9;&#9;
&#9;&#9;if settingsButton == nil then
&#9;&#9;&#9;settingsButton = Instance.new(&quot;ImageButton&quot;)
&#9;&#9;&#9;settingsButton.Name = &quot;SettingsButton&quot;
&#9;&#9;&#9;settingsButton.Image = &quot;rbxasset://textures/ui/SettingsButton.png&quot;
&#9;&#9;&#9;settingsButton.BackgroundTransparency = 1
&#9;&#9;&#9;settingsButton.Active = false
&#9;&#9;&#9;settingsButton.Size = UDim2.new(0,54,0,46)
&#9;&#9;&#9;settingsButton.Position = UDim2.new(0,2,0,50)
&#9;&#9;&#9;settingsButton.Parent = gui
settingsButton.MouseButton1Click:connect(function()
&#9;&#9; goToMenu(shield.Settings.SettingsStyle,&quot;GameMainMenu&quot;,&quot;down&quot;,UDim2.new(0,525,0,430))
&#9;&#9; shield.Settings:TweenSize(UDim2.new(0,525,0,430),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
&#9; end)
&#9;&#9;end
&#9;&#9;local shield = Instance.new(&quot;TextButton&quot;)
&#9;&#9;shield.Text = &quot;&quot;
&#9;&#9;shield.Name = &quot;UserSettingsShield&quot;
&#9;&#9;shield.Active = true
&#9;&#9;shield.AutoButtonColor = false
&#9;&#9;shield.Visible = false
&#9;&#9;shield.Size = UDim2.new(1,0,1,0)
&#9;&#9;shield.BackgroundColor3 = Color3I(51,51,51)
&#9;&#9;shield.BorderColor3 = Color3I(27,42,53)
&#9;&#9;shield.BackgroundTransparency = 0.4
&#9;&#9;shield.ZIndex = baseZIndex + 2
shield.Parent = script.Parent
&#9;&#9;mainShield = shield
&#9;&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;&#9;frame.Name = &quot;Settings&quot;
&#9;&#9;frame.Position = UDim2.new(0.5, -262, -0.5, -200)
&#9;&#9;frame.Size = UDim2.new(0, 525, 0, 430)
&#9;&#9;frame.BackgroundTransparency = 1
&#9;&#9;frame.Active = true
&#9;&#9;frame.Parent = shield
&#9;&#9;local settingsFrame = Instance.new(&quot;Frame&quot;)
&#9;&#9;settingsFrame.Name = &quot;SettingsStyle&quot;
&#9;&#9;settingsFrame.Size = UDim2.new(1, 0, 1, 0)
&#9;&#9;settingsFrame.Style = Enum.FrameStyle.RobloxRound
&#9;&#9;settingsFrame.Active = true
&#9;&#9;settingsFrame.ZIndex = baseZIndex + 3
&#9;&#9;settingsFrame.Parent = frame
&#9;&#9;
&#9; local gameSettingsMenu = createGameSettingsMenu(baseZIndex, shield)
&#9;&#9;gameSettingsMenu.Parent = settingsFrame
local gameReportAbuse = createReportAbuseDialog()
gameReportAbuse.Parent = script.Parent
&#9;&#9;local gameMainMenu = createGameMainMenu(baseZIndex, shield)
&#9;&#9;gameMainMenu.Parent = settingsFrame
&#9;&#9;
&#9;&#9;gameMainMenu.ScreenshotButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;
&#9;&#9;end)
&#9;&#9;
&#9;&#9;
&#9;&#9;
&#9;&#9;function localPlayerChange()
&#9;&#9;&#9;gameMainMenu.ResetButton.Visible = game.Players.LocalPlayer
&#9;&#9;&#9;if game.Players.LocalPlayer then
&#9;&#9;&#9;&#9;settings().Rendering.EnableFRM = true
&#9;&#9;&#9;elseif inStudioMode then
&#9;&#9;&#9;&#9;settings().Rendering.EnableFRM = false
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;
&#9;&#9;gameMainMenu.ResetButton.Visible = game.Players.LocalPlayer
&#9;&#9;if game.Players.LocalPlayer ~= nil then
&#9;&#9;&#9;game.Players.LocalPlayer.Changed:connect(function()
&#9;&#9;&#9;&#9;localPlayerChange()
&#9;&#9;&#9;end)
&#9;&#9;else
&#9;&#9;&#9;delay(0,function()
&#9;&#9;&#9;&#9;waitForProperty(game.Players,&quot;LocalPlayer&quot;)
&#9;&#9;&#9;&#9;gameMainMenu.ResetButton.Visible = game.Players.LocalPlayer
&#9;&#9;&#9;&#9;game.Players.LocalPlayer.Changed:connect(function()
&#9;&#9;&#9;&#9;&#9;localPlayerChange()
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end)
&#9;&#9;end
&#9;&#9;
&#9;&#9;gameMainMenu.ReportAbuseButton.Visible = game:FindFirstChild(&quot;NetworkClient&quot;)
&#9;&#9;if not gameMainMenu.ReportAbuseButton.Visible then
&#9;&#9;&#9;game.ChildAdded:connect(function(child)
&#9;&#9;&#9;&#9;if child:IsA(&quot;NetworkClient&quot;) then
&#9;&#9;&#9;&#9;&#9;gameMainMenu.ReportAbuseButton.Visible = game:FindFirstChild(&quot;NetworkClient&quot;)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;end
&#9;&#9;
&#9;&#9;gameMainMenu.ResetButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;goToMenu(settingsFrame,&quot;ResetConfirmationMenu&quot;,&quot;up&quot;,UDim2.new(0,525,0,370))
&#9;&#9;end)
&#9;&#9;
&#9;&#9;gameMainMenu.LeaveGameButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;goToMenu(settingsFrame,&quot;LeaveConfirmationMenu&quot;,&quot;down&quot;,UDim2.new(0,525,0,300))
&#9;&#9;end)
&#9;&#9;
&#9;
&#9;&#9;&#9;
&#9;&#9;local gameSettingsMenu = createGameSettingsMenu(baseZIndex, shield)
&#9;&#9;gameSettingsMenu.Visible = false
&#9;&#9;gameSettingsMenu.Parent = settingsFrame
&#9;&#9;gameMainMenu.LeaveGameButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;goToMenu(settingsFrame,&quot;LeaveConfirmationMenu&quot;,&quot;down&quot;,UDim2.new(0,525,0,300))
&#9;&#9;end)
&#9;&#9;gameMainMenu.SettingsButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;goToMenu(settingsFrame,&quot;GameSettingsMenu&quot;,&quot;left&quot;,UDim2.new(0,525,0,350))
&#9;&#9;end)
&#9;&#9;gameSettingsMenu.BackButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;goToMenu(settingsFrame,&quot;GameMainMenu&quot;,&quot;right&quot;,UDim2.new(0,525,0,430))
&#9;&#9;end)
&#9;&#9;
&#9;&#9;local resetConfirmationWindow = createResetConfirmationMenu(baseZIndex, shield)
&#9;&#9;resetConfirmationWindow.Visible = false
&#9;&#9;resetConfirmationWindow.Parent = settingsFrame
&#9;&#9;
&#9;&#9;local leaveConfirmationWindow = createLeaveConfirmationMenu(baseZIndex,shield)
&#9;&#9;leaveConfirmationWindow.Visible = false
&#9;&#9;leaveConfirmationWindow.Parent = settingsFrame
&#9;
&#9;&#9;
&#9;&#9;settingsButton.MouseButton1Click:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;game.GuiService:AddCenterDialog(shield, Enum.CenterDialogType.ModalDialog,
&#9;&#9;&#9;&#9;&#9;--showFunction
&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;&#9;settingsButton.Active = false
&#9;&#9;&#9;&#9;&#9;&#9;updateCameraDropDownSelection(UserSettings().GameSettings.ControlMode.Name)
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;if syncVideoCaptureSetting then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;syncVideoCaptureSetting()
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;&#9;goToMenu(settingsFrame,&quot;GameMainMenu&quot;,&quot;right&quot;,UDim2.new(0,525,0,430))
&#9;&#9;&#9;&#9;&#9;&#9;shield.Visible = true
&#9;&#9;&#9;&#9;&#9;&#9;settingsFrame.Parent:TweenPosition(UDim2.new(0.5, -262,0.5, -200),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
&#9;&#9;&#9;&#9;&#9;&#9;settingsFrame.Parent:TweenSize(UDim2.new(0,525,0,430),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
&#9;&#9;&#9;&#9;&#9;end,
&#9;&#9;&#9;&#9;&#9;--hideFunction
&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;&#9;settingsFrame.Parent:TweenPosition(UDim2.new(0.5, -262,-0.5, -200),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
&#9;&#9;&#9;&#9;&#9;&#9;settingsFrame.Parent:TweenSize(UDim2.new(0,525,0,430),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
&#9;&#9;&#9;&#9;&#9;&#9;shield.Visible = false
&#9;&#9;&#9;&#9;&#9;&#9;settingsButton.Active = true
&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end)
&#9;&#9;&#9;
&#9;&#9;return shield
&#9;end
&#9;
delay(0, function()
&#9;&#9;if settingsButton == nil then
&#9;&#9;&#9;settingsButton = Instance.new(&quot;ImageButton&quot;)
&#9;&#9;&#9;settingsButton.Name = &quot;SettingsButton&quot;
&#9;&#9;&#9;settingsButton.Image = &quot;rbxasset://textures/ui/SettingsButton.png&quot;
&#9;&#9;&#9;settingsButton.BackgroundTransparency = 1
&#9;&#9;&#9;settingsButton.Active = false
&#9;&#9;&#9;settingsButton.Size = UDim2.new(0,54,0,46)
&#9;&#9;&#9;settingsButton.Position = UDim2.new(0,2,0,50)
&#9;&#9;&#9;settingsButton.Parent = gui.BottomLeftControl
&#9;&#9;end
&#9;&#9;local shield = Instance.new(&quot;TextButton&quot;)
&#9;&#9;shield.Text = &quot;&quot;
&#9;&#9;shield.Name = &quot;UserSettingsShield&quot;
&#9;&#9;shield.Active = true
&#9;&#9;shield.AutoButtonColor = false
&#9;&#9;shield.Visible = false
&#9;&#9;shield.Size = UDim2.new(1,0,1,0)
&#9;&#9;shield.BackgroundColor3 = Color3I(51,51,51)
&#9;&#9;shield.BorderColor3 = Color3I(27,42,53)
&#9;&#9;shield.BackgroundTransparency = 0.4
&#9;&#9;shield.ZIndex = baseZIndex + 2
shield.Parent = script.Parent
&#9;&#9;mainShield = shield
&#9;&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;&#9;frame.Name = &quot;Settings&quot;
&#9;&#9;frame.Position = UDim2.new(0.5, -262, -0.5, -200)
&#9;&#9;frame.Size = UDim2.new(0, 525, 0, 430)
&#9;&#9;frame.BackgroundTransparency = 1
&#9;&#9;frame.Active = true
&#9;&#9;frame.Parent = shield
&#9;&#9;local settingsFrame = Instance.new(&quot;Frame&quot;)
&#9;&#9;settingsFrame.Name = &quot;SettingsStyle&quot;
&#9;&#9;settingsFrame.Size = UDim2.new(1, 0, 1, 0)
&#9;&#9;settingsFrame.Style = Enum.FrameStyle.RobloxRound
&#9;&#9;settingsFrame.Active = true
&#9;&#9;settingsFrame.ZIndex = baseZIndex + 3
&#9;&#9;settingsFrame.Parent = frame
&#9;&#9;local resetConfirmationWindow = createResetConfirmationMenu(baseZIndex, shield)
&#9;&#9;resetConfirmationWindow.Visible = false
&#9;&#9;resetConfirmationWindow.Parent = settingsFrame
local leaveConfirmationWindow = createLeaveConfirmationMenu(baseZIndex,shield)
&#9;&#9;leaveConfirmationWindow.Visible = false
&#9;&#9;leaveConfirmationWindow.Parent = settingsFrame
&#9;&#9;local gameMainMenu = createGameMainMenu(baseZIndex, shield)
&#9;&#9;gameMainMenu.Parent = settingsFrame
&#9;&#9;local gameSettingsMenu = createGameSettingsMenu(baseZIndex, shield)
&#9;&#9;gameSettingsMenu.Visible = false
&#9;&#9;gameSettingsMenu.Parent = settingsFrame
&#9;&#9;
&#9;&#9;gameMainMenu.SettingsButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;goToMenu(settingsFrame,&quot;GameSettingsMenu&quot;,&quot;left&quot;,UDim2.new(0,525,0,350))
&#9;&#9;end)
&#9;&#9;gameSettingsMenu.BackButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;goToMenu(settingsFrame,&quot;GameMainMenu&quot;,&quot;right&quot;,UDim2.new(0,525,0,430))
&#9;&#9;end)
&#9;gameMainMenu.ResetButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;goToMenu(settingsFrame,&quot;ResetConfirmationMenu&quot;,&quot;up&quot;,UDim2.new(0,525,0,370))
&#9;&#9;end)
gameMainMenu.LeaveGameButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;goToMenu(settingsFrame,&quot;LeaveConfirmationMenu&quot;,&quot;up&quot;,UDim2.new(0,525,0,300))
&#9;&#9;end)
&#9;&#9;gameMainMenu.ScreenshotButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;
&#9;&#9;end)
&#9;&#9; settingsButton.MouseButton1Click:connect(function()
goToMenu(settingsFrame,&quot;GameMainMenu&quot;,&quot;right&quot;,UDim2.new(0,525,0,430))
&#9;&#9;&#9;&#9;&#9;&#9;&#9;shield.Visible = true
&#9;&#9;&#9;&#9;&#9;&#9;&#9;shield.Active = true
&#9;&#9;&#9;&#9;&#9;&#9;&#9;settingsFrame.Parent:TweenPosition(UDim2.new(0.5, -262,0.5, -200),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
&#9;&#9;&#9;&#9;&#9;&#9;&#9;settingsFrame.Parent:TweenSize(UDim2.new(0,525,0,430),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
&#9; end)
game:GetService(&quot;GuiService&quot;).EscapeKeyPressed:connect(function()
&#9;&#9;&#9;&#9;if shield.Visible == false then
goToMenu(settingsFrame,&quot;GameMainMenu&quot;,&quot;right&quot;,UDim2.new(0,525,0,430))
&#9;&#9;&#9;&#9;&#9;&#9;&#9;shield.Visible = true
&#9;&#9;&#9;&#9;&#9;&#9;&#9;shield.Active = true
&#9;&#9;&#9;&#9;&#9;&#9;&#9;settingsFrame.Parent:TweenPosition(UDim2.new(0.5, -262,0.5, -200),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
&#9;&#9;&#9;&#9;&#9;&#9;&#9;settingsFrame.Parent:TweenSize(UDim2.new(0,525,0,430),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true)
elseif shield.Visible == true then
resumeGameFunction(shield)
end
end)
&#9;&#9;gui.BottomLeftControl.SettingsButton.Active = true
&#9;&#9;gui.BottomLeftControl.SettingsButton.Position = UDim2.new(0,2,0,-2)
&#9;&#9;
&#9;&#9;if mouseLockLabel and UserSettings().GameSettings.ControlMode == Enum.ControlMode[&quot;Mouse Lock Switch&quot;] then
&#9;&#9;&#9;mouseLockLabel.Visible = true
&#9;&#9;elseif mouseLockLabel then
&#9;&#9;&#9;mouseLockLabel.Visible = false
&#9;&#9;end
&#9;&#9;
local createSaveDialogs = function()
&#9;local shield = Instance.new(&quot;TextButton&quot;)
&#9;shield.Text = &quot;&quot;
&#9;shield.AutoButtonColor = false
&#9;shield.Name = &quot;SaveDialogShield&quot;
&#9;shield.Active = true
&#9;shield.Visible = false
&#9;shield.Size = UDim2.new(1,0,1,0)
&#9;shield.BackgroundColor3 = Color3I(51,51,51)
&#9;shield.BorderColor3 = Color3I(27,42,53)
&#9;shield.BackgroundTransparency = 0.4
&#9;shield.ZIndex = baseZIndex+1
&#9;local clearAndResetDialog
&#9;local save
&#9;local saveLocal
&#9;local dontSave
&#9;local cancel
&#9;local messageBoxButtons = {}
&#9;messageBoxButtons[1] = {}
&#9;messageBoxButtons[1].Text = &quot;Save&quot;
&#9;messageBoxButtons[1].Style = Enum.ButtonStyle.RobloxButtonDefault
&#9;messageBoxButtons[1].Function = function() save() end
&#9;messageBoxButtons[2] = {}
&#9;messageBoxButtons[2].Text = &quot;Cancel&quot;
&#9;messageBoxButtons[2].Function = function() cancel() end
&#9;messageBoxButtons[3] = {}
&#9;messageBoxButtons[3].Text = &quot;Don&apos;t Save&quot;
&#9;messageBoxButtons[3].Function = function() dontSave() end
&#9;local saveDialogMessageBox = RbxGui.CreateStyledMessageDialog(&quot;Unsaved Changes&quot;, &quot;Save your changes to ROBLOX before leaving?&quot;, &quot;Confirm&quot;, messageBoxButtons)
&#9;saveDialogMessageBox.Visible = true
&#9;saveDialogMessageBox.Parent = shield
&#9;local errorBoxButtons = {}
&#9;local buttonOffset = 1
&#9;if game.LocalSaveEnabled then
&#9;&#9;errorBoxButtons[buttonOffset] = {}
&#9;&#9;errorBoxButtons[buttonOffset].Text = &quot;Save to Disk&quot;
&#9;&#9;errorBoxButtons[buttonOffset].Function = function() saveLocal() end
&#9;&#9;buttonOffset = buttonOffset + 1
&#9;end
&#9;errorBoxButtons[buttonOffset] = {}
&#9;errorBoxButtons[buttonOffset].Text = &quot;Keep Playing&quot;
&#9;errorBoxButtons[buttonOffset].Function = function() cancel() end
&#9;errorBoxButtons[buttonOffset+1] = {}
&#9;errorBoxButtons[buttonOffset+1].Text = &quot;Don&apos;t Save&quot;
&#9;errorBoxButtons[buttonOffset+1].Function = function() dontSave() end
&#9;local errorDialogMessageBox = RbxGui.CreateStyledMessageDialog(&quot;Upload Failed&quot;, &quot;Sorry, we could not save your changes to ROBLOX.&quot;, &quot;Error&quot;, errorBoxButtons)
&#9;errorDialogMessageBox.Visible = false
&#9;errorDialogMessageBox.Parent = shield
&#9;local spinnerDialog = Instance.new(&quot;Frame&quot;)
&#9;spinnerDialog.Name = &quot;SpinnerDialog&quot;
&#9;spinnerDialog.Style = Enum.FrameStyle.RobloxRound
&#9;spinnerDialog.Size = UDim2.new(0, 350, 0, 150)
&#9;spinnerDialog.Position = UDim2.new(.5, -175, .5, -75)
&#9;spinnerDialog.Visible = false
&#9;spinnerDialog.Active = true
&#9;spinnerDialog.Parent = shield
&#9;local waitingLabel = Instance.new(&quot;TextLabel&quot;)
&#9;waitingLabel.Name = &quot;WaitingLabel&quot;
&#9;waitingLabel.Text = &quot;Saving to ROBLOX...&quot;
&#9;waitingLabel.Font = Enum.Font.ArialBold
&#9;waitingLabel.FontSize = Enum.FontSize.Size18
&#9;waitingLabel.Position = UDim2.new(0.5, 25, 0.5, 0)
&#9;waitingLabel.TextColor3 = Color3.new(1,1,1)
&#9;waitingLabel.Parent = spinnerDialog
&#9;local spinnerFrame = Instance.new(&quot;Frame&quot;)
&#9;spinnerFrame.Name = &quot;Spinner&quot;
&#9;spinnerFrame.Size = UDim2.new(0, 80, 0, 80)
&#9;spinnerFrame.Position = UDim2.new(0.5, -150, 0.5, -40)
&#9;spinnerFrame.BackgroundTransparency = 1
&#9;spinnerFrame.Parent = spinnerDialog
&#9;local spinnerIcons = {}
&#9;local spinnerNum = 1
&#9;while spinnerNum &lt;= 8 do
&#9;&#9;local spinnerImage = Instance.new(&quot;ImageLabel&quot;)
&#9; spinnerImage.Name = &quot;Spinner&quot;..spinnerNum
&#9;&#9;spinnerImage.Size = UDim2.new(0, 16, 0, 16)
&#9;&#9;spinnerImage.Position = UDim2.new(.5+.3*math.cos(math.rad(45*spinnerNum)), -8, .5+.3*math.sin(math.rad(45*spinnerNum)), -8)
&#9;&#9;spinnerImage.BackgroundTransparency = 1
&#9; spinnerImage.Image = &quot;http://www.roblox.com/Asset?id=45880710&quot;
&#9;&#9;spinnerImage.Parent = spinnerFrame
&#9; spinnerIcons[spinnerNum] = spinnerImage
&#9; spinnerNum = spinnerNum + 1
&#9;end
&#9;save = function()
&#9;&#9;saveDialogMessageBox.Visible = false
&#9;&#9;
&#9;&#9;--Show the spinner dialog
&#9;&#9;spinnerDialog.Visible = true
&#9;&#9;local spin = true
&#9;&#9;--Make it spin
&#9;&#9;delay(0, function()
&#9;&#9; local spinPos = 0
&#9;&#9;&#9;while spin do
&#9;&#9;&#9;&#9;local pos = 0
&#9;&#9;&#9;&#9;while pos &lt; 8 do
&#9;&#9;&#9;&#9;&#9;if pos == spinPos or pos == ((spinPos+1)%8) then
&#9;&#9;&#9;&#9;&#9;&#9;spinnerIcons[pos+1].Image = &quot;http://www.roblox.com/Asset?id=45880668&quot;
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;spinnerIcons[pos+1].Image = &quot;http://www.roblox.com/Asset?id=45880710&quot;
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;pos = pos + 1
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;spinPos = (spinPos + 1) % 8
&#9;&#9;&#9;&#9;wait(0.2)
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;&#9;--Do the save while the spinner is going, function will wait
&#9;&#9;local result = game:SaveToRoblox()
&#9;&#9;if not result then
&#9;&#9;&#9;--Try once more
&#9;&#9;&#9;result = game:SaveToRoblox()
&#9;&#9;end
&#9;&#9;--Hide the spinner dialog
&#9;&#9;spinnerDialog.Visible = false
&#9;&#9;--And cause the delay thread to stop
&#9;&#9;spin = false&#9;
&#9;&#9;--Now process the result
&#9;&#9;if result then
&#9;&#9;&#9;--Success, close
&#9;&#9;&#9;game:FinishShutdown(false)
&#9;&#9;&#9;clearAndResetDialog()
&#9;&#9;else
&#9;&#9;&#9;--Failure, show the second dialog prompt
&#9;&#9;&#9;errorDialogMessageBox.Visible = true
&#9;&#9;end
&#9;end
&#9;saveLocal = function()
&#9;&#9;errorDialogMessageBox.Visible = false
&#9;&#9;game:FinishShutdown(true)
&#9;&#9;clearAndResetDialog()
&#9;end
&#9;dontSave = function()
&#9;&#9;saveDialogMessageBox.Visible = false
&#9;&#9;errorDialogMessageBox.Visible = false
&#9;&#9;game:FinishShutdown(false)
&#9;&#9;clearAndResetDialog()
&#9;end
&#9;cancel = function()
&#9;&#9;saveDialogMessageBox.Visible = false
&#9;&#9;errorDialogMessageBox.Visible = false
&#9;&#9;clearAndResetDialog()
&#9;end
&#9;clearAndResetDialog = function()
&#9;&#9;saveDialogMessageBox.Visible = true
&#9;&#9;errorDialogMessageBox.Visible = false
&#9;&#9;spinnerDialog.Visible = false
&#9;&#9;shield.Visible = false
&#9;&#9;game.GuiService:RemoveCenterDialog(shield)
&#9;end
&#9;shield.Visible = false
&#9;return shield
end
local createChatBar = function()
&#9;--Only show a chat bar if we are a NetworkClient
&#9;waitForChild(game, &quot;NetworkClient&quot;)
&#9;waitForChild(game, &quot;Players&quot;)
&#9;waitForProperty(game.Players, &quot;LocalPlayer&quot;)
&#9;
&#9;local chatBar = Instance.new(&quot;Frame&quot;)
&#9;chatBar.Name = &quot;ChatBar&quot;
&#9;chatBar.Size = UDim2.new(1, 0, 0, 22)
&#9;chatBar.Position = UDim2.new(0, 0, 1, 0)
&#9;chatBar.BackgroundColor3 = Color3.new(0,0,0)
&#9;chatBar.BorderSizePixel = 0
&#9;local chatBox = Instance.new(&quot;TextBox&quot;)
&#9;chatBox.Text = &quot;&quot;
&#9;chatBox.Visible = false
&#9;chatBox.Size = UDim2.new(1,-4,1,0)
&#9;chatBox.Position = UDim2.new(0,2,0,0)
&#9;chatBox.TextXAlignment = Enum.TextXAlignment.Left
&#9;chatBox.Font = Enum.Font.Arial
&#9;chatBox.ClearTextOnFocus = false
&#9;chatBox.FontSize = Enum.FontSize.Size14
&#9;chatBox.TextColor3 = Color3.new(1,1,1)
&#9;chatBox.BackgroundTransparency = 1
&#9;--chatBox.Parent = chatBar
&#9;local chatButton = Instance.new(&quot;TextButton&quot;)
&#9;chatButton.Size = UDim2.new(1,-4,1,0)
&#9;chatButton.Position = UDim2.new(0,2,0,0)
&#9;chatButton.AutoButtonColor = false
&#9;chatButton.Text = &quot;To chat click here or press \&quot;/\&quot; key&quot;
&#9;chatButton.TextXAlignment = Enum.TextXAlignment.Left
&#9;chatButton.Font = Enum.Font.Arial
&#9;chatButton.FontSize = Enum.FontSize.Size14
&#9;chatButton.TextColor3 = Color3.new(1,1,1)
&#9;chatButton.BackgroundTransparency = 1
&#9;--chatButton.Parent = chatBar
&#9;local activateChat = function()
&#9;&#9;if chatBox.Visible then
&#9;&#9;&#9;return
&#9;&#9;end
&#9;&#9;chatButton.Visible = false
&#9;&#9;chatBox.Text = &quot;&quot;
&#9;&#9;chatBox.Visible = true
&#9;&#9;chatBox:CaptureFocus()
&#9;end
&#9;chatButton.MouseButton1Click:connect(activateChat)
&#9;local hotKeyEnabled = true
&#9;local toggleHotKey = function(value)
&#9;&#9;hotKeyEnabled = value
&#9;end
&#9;
&#9;local guiService = game:GetService(&quot;GuiService&quot;)
&#9;local newChatMode = pcall(function()
&#9;&#9;--guiService:AddSpecialKey(Enum.SpecialKey.ChatHotkey)
&#9;&#9;--guiService.SpecialKeyPressed:connect(function(key) if key == Enum.SpecialKey.ChatHotkey and hotKeyEnabled then activateChat() end end)
&#9;end)
&#9;if not newChatMode then
&#9;&#9;--guiService:AddKey(&quot;/&quot;)
&#9;&#9;--guiService.KeyPressed:connect(function(key) if key == &quot;/&quot; and hotKeyEnabled then activateChat() end end)
&#9;end
&#9;chatBox.FocusLost:connect(
&#9;&#9;function(enterPressed)
&#9;&#9;&#9;if enterPressed then
&#9;&#9;&#9;&#9;if chatBox.Text ~= &quot;&quot; then
&#9;&#9;&#9;&#9;&#9;local str = chatBox.Text
&#9;&#9;&#9;&#9;&#9;if string.sub(str, 1, 1) == &apos;%&apos; then
&#9;&#9;&#9;&#9;&#9;&#9;game.Players:TeamChat(string.sub(str, 2))
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;game.Players:Chat(str)
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;chatBox.Text = &quot;&quot;
&#9;&#9;&#9;chatBox.Visible = false
&#9;&#9;&#9;chatButton.Visible = true
&#9;&#9;end)
&#9;return chatBar, toggleHotKey
end
--Spawn a thread for the Save dialogs
local isSaveDialogSupported = pcall(function() local var = game.LocalSaveEnabled end)
if isSaveDialogSupported then
&#9;delay(0,
&#9;&#9;function()
&#9;&#9;&#9;local saveDialogs = createSaveDialogs()
&#9;&#9;&#9;saveDialogs.Parent = gui
&#9;&#9;
&#9;&#9;&#9;game.RequestShutdown = function()
&#9;&#9;&#9;&#9;table.insert(centerDialogs,saveDialogs)
&#9;&#9;&#9;&#9;game.GuiService:AddCenterDialog(saveDialogs, Enum.CenterDialogType.QuitDialog,
&#9;&#9;&#9;&#9;&#9;--ShowFunction
&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;&#9;saveDialogs.Visible = true
&#9;&#9;&#9;&#9;&#9;end,
&#9;&#9;&#9;&#9;&#9;--HideFunction
&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;&#9;saveDialogs.Visible = false
&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;&#9;return true
&#9;&#9;&#9;end
&#9;&#9;end)
end
end)
--Spawn a thread for the Report Abuse dialogs
delay(0,
&#9;function()
&#9;&#9;createReportAbuseDialog().Parent = script.Parent
&#9;&#9;waitForChild(gui,&quot;UserSettingsShield&quot;)
&#9;&#9;waitForChild(gui.UserSettingsShield, &quot;Settings&quot;)
&#9;&#9;waitForChild(gui.UserSettingsShield.Settings,&quot;SettingsStyle&quot;)
&#9;&#9;waitForChild(gui.UserSettingsShield.Settings.SettingsStyle,&quot;GameMainMenu&quot;)
&#9;&#9;waitForChild(gui.UserSettingsShield.Settings.SettingsStyle.GameMainMenu, &quot;ReportAbuseButton&quot;)
&#9;&#9;gui.UserSettingsShield.Settings.SettingsStyle.GameMainMenu.ReportAbuseButton.Active = true
&#9;end)
end --LoadLibrary if
end
</ProtectedString>
</Properties>
</Item>
</Item>
<Item class="ScreenGui" referent="RBX33">
<Properties>
<string name="Name">Notifications</string>
</Properties>
<Item class="LocalScript" referent="RBX34">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">Init</string>
<ProtectedString name="Source">--rbxsig%DIuke4NUwBAugRhVX8zUGw0lNHksGNmUbxnUjItyfN6YfmsPF6w9OML1jkc9uaOFfrayWCJEroukxRmuvY9E5jVqOM8TBXgRXfyVoJsVQ+YRTUdE1U1Jn/X7+oh/W1LN8Ayn42HhTEVjEbpVV+BHAeQZpjZltXo5qyozomUTeQE=%
--rbxassetid%48488398%
function waitForProperty(instance, property)
&#9;while not instance[property] do
&#9;&#9;instance.Changed:wait()
&#9;end
end
function waitForChild(instance, name)
&#9;while not instance:FindFirstChild(name) do
&#9;&#9;instance.ChildAdded:wait()
&#9;end
end
waitForProperty(game.Players,&quot;LocalPlayer&quot;)
waitForChild(script.Parent,&quot;Popup&quot;)
waitForChild(script.Parent.Popup,&quot;AcceptButton&quot;)
script.Parent.Popup.AcceptButton.Modal = true
local localPlayer = game.Players.LocalPlayer
local acceptedTeleport = Instance.new(&quot;IntValue&quot;)
local friendRequestBlacklist = {}
local teleportEnabled = true
local makePopupInvisible = function()
&#9;if script.Parent.Popup then script.Parent.Popup.Visible = false end
end
function makeFriend(fromPlayer,toPlayer)
&#9;
&#9;local popup = script.Parent:FindFirstChild(&quot;Popup&quot;)
&#9;if popup == nil then return end -- there is no popup!
&#9;if popup.Visible then return end -- currently popping something, abort!
&#9;if friendRequestBlacklist[fromPlayer] then return end -- previously cancelled friend request, we don&apos;t want it!
&#9;popup.PopupText.Text = &quot;Accept Friend Request from &quot; .. tostring(fromPlayer.Name) .. &quot;?&quot;
&#9;popup.PopupImage.Image = &quot;http://www.roblox.com/thumbs/avatar.ashx?userId=&quot;..tostring(fromPlayer.userId)..&quot;&amp;x=352&amp;y=352&quot;
&#9;
&#9;showTwoButtons()
&#9;popup.Visible = true
&#9;popup.AcceptButton.Text = &quot;Accept&quot;
&#9;popup.DeclineButton.Text = &quot;Decline&quot;
&#9;popup:TweenSize(UDim2.new(0,330,0,350),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true)
&#9;
&#9;local yesCon, noCon
&#9;yesCon = popup.AcceptButton.MouseButton1Click:connect(function()
&#9;&#9;popup.Visible = false
&#9;&#9;toPlayer:RequestFriendship(fromPlayer)
&#9;&#9;if yesCon then yesCon:disconnect() end
&#9;&#9;if noCon then noCon:disconnect() end
&#9;&#9;popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
&#9;end)
&#9;noCon = popup.DeclineButton.MouseButton1Click:connect(function()
&#9;&#9;popup.Visible = false
&#9;&#9;toPlayer:RevokeFriendship(fromPlayer)
&#9;&#9;friendRequestBlacklist[fromPlayer] = true
&#9;&#9;print(&quot;pop up blacklist&quot;)
&#9;&#9;if yesCon then yesCon:disconnect() end
&#9;&#9;if noCon then noCon:disconnect() end
&#9;&#9;popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
&#9;end)
end
game.Players.FriendRequestEvent:connect(function(fromPlayer,toPlayer,event)
&#9;-- if this doesn&apos;t involve me, then do nothing
&#9;if fromPlayer ~= localPlayer and toPlayer ~= localPlayer then return end
&#9;if fromPlayer == localPlayer then
&#9;&#9;if event == Enum.FriendRequestEvent.Accept then
&#9;&#9;&#9;game:GetService(&quot;GuiService&quot;):SendNotification(&quot;You are Friends&quot;,
&#9;&#9;&#9;&quot;With &quot; .. toPlayer.Name .. &quot;!&quot;,
&#9;&#9;&#9;&quot;http://www.roblox.com/thumbs/avatar.ashx?userId=&quot;..tostring(toPlayer.userId)..&quot;&amp;x=48&amp;y=48&quot;,
&#9;&#9;&#9;5,
&#9;&#9;&#9;function()
&#9;&#9;&#9;
&#9;&#9;&#9;end)
&#9;&#9;end
&#9;elseif toPlayer == localPlayer then
&#9;&#9;if event == Enum.FriendRequestEvent.Issue then
&#9;&#9;&#9;if friendRequestBlacklist[fromPlayer] then return end -- previously cancelled friend request, we don&apos;t want it!
&#9;&#9;&#9;game:GetService(&quot;GuiService&quot;):SendNotification(&quot;Friend Request&quot;,
&#9;&#9;&#9;&#9;&quot;From &quot; .. fromPlayer.Name,
&#9;&#9;&#9;&#9;&quot;http://www.roblox.com/thumbs/avatar.ashx?userId=&quot;..tostring(fromPlayer.userId)..&quot;&amp;x=48&amp;y=48&quot;,
&#9;&#9;&#9;&#9;8,
&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;makeFriend(fromPlayer,toPlayer)
&#9;&#9;&#9;&#9;end)
&#9;&#9;elseif event == Enum.FriendRequestEvent.Accept then
&#9;&#9;&#9;game:GetService(&quot;GuiService&quot;):SendNotification(&quot;You are Friends&quot;,
&#9;&#9;&#9;&quot;With &quot; .. fromPlayer.Name .. &quot;!&quot;,
&#9;&#9;&#9;&quot;http://www.roblox.com/thumbs/avatar.ashx?userId=&quot;..tostring(fromPlayer.userId)..&quot;&amp;x=48&amp;y=48&quot;,
&#9;&#9;&#9;5,
&#9;&#9;&#9;function()
&#9;&#9;&#9;
&#9;&#9;&#9;end)
&#9;&#9;end
&#9;end
end)
function showOneButton()
&#9;local popup = script.Parent:FindFirstChild(&quot;Popup&quot;)
&#9;if popup then
&#9;&#9;popup.OKButton.Visible = true
&#9;&#9;popup.DeclineButton.Visible = false
&#9;&#9;popup.AcceptButton.Visible = false
&#9;end
end
function showTwoButtons()
&#9;local popup = script.Parent:FindFirstChild(&quot;Popup&quot;)
&#9;if popup then
&#9;&#9;popup.DeclineButton.Visible = true
&#9;&#9;popup.AcceptButton.Visible = true
&#9;end&#9;
end
if teleportEnabled then
&#9;game:GetService(&quot;TeleportService&quot;).ErrorCallback = function(message)
&#9;&#9;local popup = script.Parent:FindFirstChild(&quot;Popup&quot;)
&#9;&#9;showOneButton()
&#9;&#9;popup.PopupText.Text = message
&#9;&#9;local clickCon
&#9;&#9;clickCon = popup.OKButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;if clickCon then clickCon:disconnect() end
&#9;&#9;&#9;game.GuiService:RemoveCenterDialog(script.Parent:FindFirstChild(&quot;Popup&quot;))
&#9;&#9;&#9;popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
&#9;&#9;end)
&#9;&#9;game.GuiService:AddCenterDialog(script.Parent:FindFirstChild(&quot;Popup&quot;), Enum.CenterDialogType.QuitDialog,
&#9;&#9;&#9;--ShowFunction
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;showOneButton()
&#9;&#9;&#9;&#9;script.Parent:FindFirstChild(&quot;Popup&quot;).Visible = true
&#9;&#9;&#9;&#9;popup:TweenSize(UDim2.new(0,330,0,350),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true)
&#9;&#9;&#9;end,
&#9;&#9;&#9;--HideFunction
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
&#9;&#9;&#9;end)
&#9;end
&#9;game:GetService(&quot;TeleportService&quot;).ConfirmationCallback = function(message, placeId, spawnName)
&#9;&#9;local popup = script.Parent:FindFirstChild(&quot;Popup&quot;)
&#9;&#9;popup.PopupText.Text = message
&#9;&#9;popup.PopupImage.Image = &quot;&quot;
&#9;&#9;
&#9;&#9;local yesCon, noCon
&#9;&#9;
&#9;&#9;local function killCons()
&#9;&#9;&#9;if yesCon then yesCon:disconnect() end
&#9;&#9;&#9;if noCon then noCon:disconnect() end
&#9;&#9;&#9;game.GuiService:RemoveCenterDialog(script.Parent:FindFirstChild(&quot;Popup&quot;))
&#9;&#9;&#9;popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
&#9;&#9;end
&#9;&#9;yesCon = popup.AcceptButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;killCons()
&#9;&#9;&#9;local success, err = pcall(function() game:GetService(&quot;TeleportService&quot;):TeleportImpl(placeId,spawnName) end)
&#9;&#9;&#9;if not success then
&#9;&#9;&#9;&#9;showOneButton()
&#9;&#9;&#9;&#9;popup.PopupText.Text = err
&#9;&#9;&#9;&#9;local clickCon
&#9;&#9;&#9;&#9;clickCon = popup.OKButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;&#9;&#9;if clickCon then clickCon:disconnect() end
&#9;&#9;&#9;&#9;&#9;game.GuiService:RemoveCenterDialog(script.Parent:FindFirstChild(&quot;Popup&quot;))
&#9;&#9;&#9;&#9;&#9;popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;&#9;game.GuiService:AddCenterDialog(script.Parent:FindFirstChild(&quot;Popup&quot;), Enum.CenterDialogType.QuitDialog,
&#9;&#9;&#9;&#9;&#9;&#9;--ShowFunction
&#9;&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;showOneButton()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;script.Parent:FindFirstChild(&quot;Popup&quot;).Visible = true
&#9;&#9;&#9;&#9;&#9;&#9;&#9;popup:TweenSize(UDim2.new(0,330,0,350),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true)
&#9;&#9;&#9;&#9;&#9;&#9;end,
&#9;&#9;&#9;&#9;&#9;&#9;--HideFunction
&#9;&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
&#9;&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;&#9;noCon = popup.DeclineButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;killCons()
&#9;&#9;&#9;local success = pcall(function() game:GetService(&quot;TeleportService&quot;):TeleportCancel() end)
&#9;&#9;end)
&#9;&#9;local centerDialogSuccess = pcall(function() game.GuiService:AddCenterDialog(script.Parent:FindFirstChild(&quot;Popup&quot;), Enum.CenterDialogType.QuitDialog,
&#9;&#9;&#9;&#9;&#9;&#9;--ShowFunction
&#9;&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;showTwoButtons()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;popup.AcceptButton.Text = &quot;Leave&quot;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;popup.DeclineButton.Text = &quot;Stay&quot;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;script.Parent:FindFirstChild(&quot;Popup&quot;).Visible = true
&#9;&#9;&#9;&#9;&#9;&#9;&#9;popup:TweenSize(UDim2.new(0,330,0,350),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true)
&#9;&#9;&#9;&#9;&#9;&#9;end,
&#9;&#9;&#9;&#9;&#9;&#9;--HideFunction
&#9;&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
&#9;&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;if centerDialogSuccess == false then
&#9;&#9;&#9;script.Parent:FindFirstChild(&quot;Popup&quot;).Visible = true
&#9;&#9;&#9;popup.AcceptButton.Text = &quot;Leave&quot;
&#9;&#9;&#9;popup.DeclineButton.Text = &quot;Stay&quot;
&#9;&#9;&#9;popup:TweenSize(UDim2.new(0,330,0,350),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true)
&#9;&#9;end
&#9;&#9;return true
&#9;&#9;&#9;&#9;&#9;
&#9;end
end</ProtectedString>
</Properties>
</Item>
<Item class="LocalScript" referent="RBX35">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">PopupScript</string>
<ProtectedString name="Source">--rbxsig%kFJjpVHvWkJX02PNT/54It5wEJZscSSdzAhjsXr0WtGNy+idQIKiWTiMUqEANPv/ST8P3B5jNDPtM9SNqR53nY9P6B1PAS08ik0AquNdrWORpnFHwksP3xC2ysi2Y1LsByVO2Uj0FikBhLe1CAVmlmX22AqbO/qNaL26sftSHT0=%
--rbxassetid%48488451%
--build our gui
local popupFrame = Instance.new(&quot;Frame&quot;)
popupFrame.Position = UDim2.new(0.5,-165,0.5,-175)
popupFrame.Size = UDim2.new(0,330,0,350)
popupFrame.Style = Enum.FrameStyle.RobloxRound
popupFrame.ZIndex = 4
popupFrame.Name = &quot;Popup&quot;
popupFrame.Visible = false
popupFrame.Parent = script.Parent
local darken = popupFrame:clone()
darken.Size = UDim2.new(1,16,1,16)
darken.Position = UDim2.new(0,-8,0,-8)
darken.Name = &quot;Darken&quot;
darken.ZIndex = 1
darken.Parent = popupFrame
local acceptButton = Instance.new(&quot;TextButton&quot;)
acceptButton.Position = UDim2.new(0,20,0,270)
acceptButton.Size = UDim2.new(0,100,0,50)
acceptButton.Font = Enum.Font.ArialBold
acceptButton.FontSize = Enum.FontSize.Size24
acceptButton.Style = Enum.ButtonStyle.RobloxButton
acceptButton.TextColor3 = Color3.new(248/255,248/255,248/255)
acceptButton.Text = &quot;Yes&quot;
acceptButton.ZIndex = 5
acceptButton.Name = &quot;AcceptButton&quot;
acceptButton.Parent = popupFrame
local declineButton = acceptButton:clone()
declineButton.Position = UDim2.new(1,-120,0,270)
declineButton.Text = &quot;No&quot;
declineButton.Name = &quot;DeclineButton&quot;
declineButton.Parent = popupFrame
local popupImage = Instance.new(&quot;ImageLabel&quot;)
popupImage.BackgroundTransparency = 1
popupImage.Position = UDim2.new(0.5,-140,0,0)
popupImage.Size = UDim2.new(0,280,0,280)
popupImage.ZIndex = 3
popupImage.Name = &quot;PopupImage&quot;
popupImage.Parent = popupFrame
local backing = Instance.new(&quot;ImageLabel&quot;)
backing.BackgroundTransparency = 1
backing.Size = UDim2.new(1,0,1,0)
backing.Image = &quot;http://www.roblox.com/asset/?id=47574181&quot;
backing.Name = &quot;Backing&quot;
backing.ZIndex = 2
backing.Parent = popupImage
local popupText = Instance.new(&quot;TextLabel&quot;)
popupText.Name = &quot;PopupText&quot;
popupText.Size = UDim2.new(1,0,0.8,0)
popupText.Font = Enum.Font.ArialBold
popupText.FontSize = Enum.FontSize.Size36
popupText.BackgroundTransparency = 1
popupText.Text = &quot;Hello I&apos;m a popup&quot;
popupText.TextColor3 = Color3.new(248/255,248/255,248/255)
popupText.TextWrap = true
popupText.ZIndex = 5
popupText.Parent = popupFrame
script:remove()</ProtectedString>
</Properties>
</Item>
</Item>
<Item class="ScreenGui" referent="RBX36">
<Properties>
<string name="Name">Playerlist</string>
</Properties>
<Item class="LocalScript" referent="RBX37">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">Init</string>
<ProtectedString name="Source">-- welcome to second version of playerlist!!! --
-- change log:
-- 1 using a later version of playerlist which means more stability!!!!1 --
-- 2 stat names now work!!! --
-- made by iago#6808 --
local t = {}
local function ScopedConnect(parentInstance, instance, event, signalFunc, syncFunc, removeFunc)
&#9;local eventConnection = nil
&#9;--Connection on parentInstance is scoped by parentInstance (when destroyed, it goes away)
&#9;local tryConnect = function()
&#9;&#9;if game:IsAncestorOf(parentInstance) then
&#9;&#9;&#9;--Entering the world, make sure we are connected/synced
&#9;&#9;&#9;if not eventConnection then
&#9;&#9;&#9;&#9;eventConnection = instance[event]:connect(signalFunc)
&#9;&#9;&#9;&#9;if syncFunc then syncFunc() end
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;--Probably leaving the world, so disconnect for now
&#9;&#9;&#9;if eventConnection then
&#9;&#9;&#9;&#9;eventConnection:disconnect()
&#9;&#9;&#9;&#9;if removeFunc then removeFunc() end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;--Hook it up to ancestryChanged signal
&#9;local connection = parentInstance.AncestryChanged:connect(tryConnect)
&#9;
&#9;--Now connect us if we&apos;re already in the world
&#9;tryConnect()
&#9;
&#9;return connection
end
local function getScreenGuiAncestor(instance)
&#9;local localInstance = instance
&#9;while localInstance and not localInstance:IsA(&quot;ScreenGui&quot;) do
&#9;&#9;localInstance = localInstance.Parent
&#9;end
&#9;return localInstance
end
local function CreateButtons(frame, buttons, yPos, ySize)
&#9;local buttonNum = 1
&#9;local buttonObjs = {}
&#9;for i, obj in ipairs(buttons) do
&#9;&#9;local button = Instance.new(&quot;TextButton&quot;)
&#9;&#9;button.Name = &quot;Button&quot; .. buttonNum
&#9;&#9;button.Font = Enum.Font.Arial
&#9;&#9;button.FontSize = Enum.FontSize.Size18
&#9;&#9;button.AutoButtonColor = true
&#9;&#9;button.Modal = true
&#9;&#9;if obj[&quot;Style&quot;] then
&#9;&#9;&#9;button.Style = obj.Style
&#9;&#9;else
&#9;&#9;&#9;button.Style = Enum.ButtonStyle.RobloxButton
&#9;&#9;end
&#9;&#9;if obj[&quot;ZIndex&quot;] then
&#9;&#9;&#9;button.ZIndex = obj.ZIndex
&#9;&#9;end
&#9;&#9;button.Text = obj.Text
&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;button.MouseButton1Click:connect(obj.Function)
&#9;&#9;button.Parent = frame
&#9;&#9;buttonObjs[buttonNum] = button
&#9;&#9;buttonNum = buttonNum + 1
&#9;end
&#9;local numButtons = buttonNum-1
&#9;if numButtons == 1 then
&#9;&#9;frame.Button1.Position = UDim2.new(0.35, 0, yPos.Scale, yPos.Offset)
&#9;&#9;frame.Button1.Size = UDim2.new(.4,0,ySize.Scale, ySize.Offset)
&#9;elseif numButtons == 2 then
&#9;&#9;frame.Button1.Position = UDim2.new(0.1, 0, yPos.Scale, yPos.Offset)
&#9;&#9;frame.Button1.Size = UDim2.new(.8/3,0, ySize.Scale, ySize.Offset)
&#9;&#9;frame.Button2.Position = UDim2.new(0.55, 0, yPos.Scale, yPos.Offset)
&#9;&#9;frame.Button2.Size = UDim2.new(.35,0, ySize.Scale, ySize.Offset)
&#9;elseif numButtons &gt;= 3 then
&#9;&#9;local spacing = .1 / numButtons
&#9;&#9;local buttonSize = .9 / numButtons
&#9;&#9;buttonNum = 1
&#9;&#9;while buttonNum &lt;= numButtons do
&#9;&#9;&#9;buttonObjs[buttonNum].Position = UDim2.new(spacing*buttonNum + (buttonNum-1) * buttonSize, 0, yPos.Scale, yPos.Offset)
&#9;&#9;&#9;buttonObjs[buttonNum].Size = UDim2.new(buttonSize, 0, ySize.Scale, ySize.Offset)
&#9;&#9;&#9;buttonNum = buttonNum + 1
&#9;&#9;end
&#9;end
end
local function setSliderPos(newAbsPosX,slider,sliderPosition,bar,steps)
&#9;local newStep = steps - 1 --otherwise we really get one more step than we want
&#9;local relativePosX = math.min(1, math.max(0, (newAbsPosX - bar.AbsolutePosition.X) / bar.AbsoluteSize.X ))
&#9;local wholeNum, remainder = math.modf(relativePosX * newStep)
&#9;if remainder &gt; 0.5 then
&#9;&#9;wholeNum = wholeNum + 1
&#9;end
&#9;relativePosX = wholeNum/newStep
&#9;local result = math.ceil(relativePosX * newStep)
&#9;if sliderPosition.Value ~= (result + 1) then --only update if we moved a step
&#9;&#9;sliderPosition.Value = result + 1
&#9;&#9;slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
&#9;end
&#9;
end
local function cancelSlide(areaSoak)
&#9;areaSoak.Visible = false
&#9;if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
end
t.CreateStyledMessageDialog = function(title, message, style, buttons)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Size = UDim2.new(0.5, 0, 0, 165)
&#9;frame.Position = UDim2.new(0.25, 0, 0.5, -72.5)
&#9;frame.Name = &quot;MessageDialog&quot;
&#9;frame.Active = true
&#9;frame.Style = Enum.FrameStyle.RobloxRound&#9;
&#9;
&#9;local styleImage = Instance.new(&quot;ImageLabel&quot;)
&#9;styleImage.Name = &quot;StyleImage&quot;
&#9;styleImage.BackgroundTransparency = 1
&#9;styleImage.Position = UDim2.new(0,5,0,15)
&#9;if style == &quot;error&quot; or style == &quot;Error&quot; then
&#9;&#9;styleImage.Size = UDim2.new(0, 71, 0, 71)
&#9;&#9;styleImage.Image = &quot;http://www.roblox.com/asset/?id=42565285&quot;
&#9;elseif style == &quot;notify&quot; or style == &quot;Notify&quot; then
&#9;&#9;styleImage.Size = UDim2.new(0, 71, 0, 71)
&#9;&#9;styleImage.Image = &quot;http://www.roblox.com/asset/?id=42604978&quot;
&#9;elseif style == &quot;confirm&quot; or style == &quot;Confirm&quot; then
&#9;&#9;styleImage.Size = UDim2.new(0, 74, 0, 76)
&#9;&#9;styleImage.Image = &quot;http://www.roblox.com/asset/?id=42557901&quot;
&#9;else
&#9;&#9;return t.CreateMessageDialog(title,message,buttons)
&#9;end
&#9;styleImage.Parent = frame
&#9;
&#9;local titleLabel = Instance.new(&quot;TextLabel&quot;)
&#9;titleLabel.Name = &quot;Title&quot;
&#9;titleLabel.Text = title
&#9;titleLabel.TextStrokeTransparency = 0
&#9;titleLabel.BackgroundTransparency = 1
&#9;titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
&#9;titleLabel.Position = UDim2.new(0, 80, 0, 0)
&#9;titleLabel.Size = UDim2.new(1, -80, 0, 40)
&#9;titleLabel.Font = Enum.Font.ArialBold
&#9;titleLabel.FontSize = Enum.FontSize.Size36
&#9;titleLabel.TextXAlignment = Enum.TextXAlignment.Center
&#9;titleLabel.TextYAlignment = Enum.TextYAlignment.Center
&#9;titleLabel.Parent = frame
&#9;local messageLabel = Instance.new(&quot;TextLabel&quot;)
&#9;messageLabel.Name = &quot;Message&quot;
&#9;messageLabel.Text = message
&#9;messageLabel.TextStrokeTransparency = 0
&#9;messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
&#9;messageLabel.Position = UDim2.new(0.025, 80, 0, 45)
&#9;messageLabel.Size = UDim2.new(0.95, -80, 0, 55)
&#9;messageLabel.BackgroundTransparency = 1
&#9;messageLabel.Font = Enum.Font.Arial
&#9;messageLabel.FontSize = Enum.FontSize.Size18
&#9;messageLabel.TextWrap = true
&#9;messageLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;messageLabel.TextYAlignment = Enum.TextYAlignment.Top
&#9;messageLabel.Parent = frame
&#9;CreateButtons(frame, buttons, UDim.new(0, 105), UDim.new(0, 40) )
&#9;return frame
end
t.CreateMessageDialog = function(title, message, buttons)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Size = UDim2.new(0.5, 0, 0.5, 0)
&#9;frame.Position = UDim2.new(0.25, 0, 0.25, 0)
&#9;frame.Name = &quot;MessageDialog&quot;
&#9;frame.Active = true
&#9;frame.Style = Enum.FrameStyle.RobloxRound
&#9;local titleLabel = Instance.new(&quot;TextLabel&quot;)
&#9;titleLabel.Name = &quot;Title&quot;
&#9;titleLabel.Text = title
&#9;titleLabel.BackgroundTransparency = 1
&#9;titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
&#9;titleLabel.Position = UDim2.new(0, 0, 0, 0)
&#9;titleLabel.Size = UDim2.new(1, 0, 0.15, 0)
&#9;titleLabel.Font = Enum.Font.ArialBold
&#9;titleLabel.FontSize = Enum.FontSize.Size36
&#9;titleLabel.TextXAlignment = Enum.TextXAlignment.Center
&#9;titleLabel.TextYAlignment = Enum.TextYAlignment.Center
&#9;titleLabel.Parent = frame
&#9;local messageLabel = Instance.new(&quot;TextLabel&quot;)
&#9;messageLabel.Name = &quot;Message&quot;
&#9;messageLabel.Text = message
&#9;messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
&#9;messageLabel.Position = UDim2.new(0.025, 0, 0.175, 0)
&#9;messageLabel.Size = UDim2.new(0.95, 0, .55, 0)
&#9;messageLabel.BackgroundTransparency = 1
&#9;messageLabel.Font = Enum.Font.Arial
&#9;messageLabel.FontSize = Enum.FontSize.Size18
&#9;messageLabel.TextWrap = true
&#9;messageLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;messageLabel.TextYAlignment = Enum.TextYAlignment.Top
&#9;messageLabel.Parent = frame
&#9;CreateButtons(frame, buttons, UDim.new(0.8,0), UDim.new(0.15, 0))
&#9;return frame
end
t.CreateDropDownMenu = function(items, onSelect, forRoblox, whiteSkin, baseZ)
&#9;local baseZIndex = 0
&#9;if (type(baseZ) == &quot;number&quot;) then
&#9;&#9;baseZIndex = baseZ
&#9;end
&#9;local width = UDim.new(0, 100)
&#9;local height = UDim.new(0, 32)
&#9;local xPos = 0.055
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;local textColor = Color3.new(1,1,1)
&#9;if (whiteSkin) then
&#9;&#9;textColor = Color3.new(0.5, 0.5, 0.5)
&#9;end
&#9;frame.Name = &quot;DropDownMenu&quot;
&#9;frame.BackgroundTransparency = 1
&#9;frame.Size = UDim2.new(width, height)
&#9;local dropDownMenu = Instance.new(&quot;TextButton&quot;)
&#9;dropDownMenu.Name = &quot;DropDownMenuButton&quot;
&#9;dropDownMenu.TextWrap = true
&#9;dropDownMenu.TextColor3 = textColor
&#9;dropDownMenu.Text = &quot;Choose One&quot;
&#9;dropDownMenu.Font = Enum.Font.ArialBold
&#9;dropDownMenu.FontSize = Enum.FontSize.Size18
&#9;dropDownMenu.TextXAlignment = Enum.TextXAlignment.Left
&#9;dropDownMenu.TextYAlignment = Enum.TextYAlignment.Center
&#9;dropDownMenu.BackgroundTransparency = 1
&#9;dropDownMenu.AutoButtonColor = true
&#9;if (whiteSkin) then
&#9;&#9;dropDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton
&#9;else
&#9;&#9;dropDownMenu.Style = Enum.ButtonStyle.RobloxButton
&#9;end
&#9;dropDownMenu.Size = UDim2.new(1,0,1,0)
&#9;dropDownMenu.Parent = frame
&#9;dropDownMenu.ZIndex = 2 + baseZIndex
&#9;local dropDownIcon = Instance.new(&quot;ImageLabel&quot;)
&#9;dropDownIcon.Name = &quot;Icon&quot;
&#9;dropDownIcon.Active = false
&#9;if (whiteSkin) then
&#9;&#9;dropDownIcon.Image = &quot;rbxasset://textures/ui/dropdown_arrow.png&quot;
&#9;&#9;dropDownIcon.Size = UDim2.new(0,16,0,12)
&#9;&#9;dropDownIcon.Position = UDim2.new(1,-17,0.5, -6)
&#9;else
&#9;&#9;dropDownIcon.Image = &quot;http://www.roblox.com/asset/?id=45732894&quot;
&#9;&#9;dropDownIcon.Size = UDim2.new(0,11,0,6)
&#9;&#9;dropDownIcon.Position = UDim2.new(1,-11,0.5, -2)
&#9;end
&#9;dropDownIcon.BackgroundTransparency = 1
&#9;dropDownIcon.Parent = dropDownMenu
&#9;dropDownIcon.ZIndex = 2 + baseZIndex
&#9;
&#9;local itemCount = #items
&#9;local dropDownItemCount = #items
&#9;local useScrollButtons = false
&#9;if dropDownItemCount &gt; 6 then
&#9;&#9;useScrollButtons = true
&#9;&#9;dropDownItemCount = 6
&#9;end
&#9;
&#9;local droppedDownMenu = Instance.new(&quot;TextButton&quot;)
&#9;droppedDownMenu.Name = &quot;List&quot;
&#9;droppedDownMenu.Text = &quot;&quot;
&#9;droppedDownMenu.BackgroundTransparency = 1
&#9;--droppedDownMenu.AutoButtonColor = true
&#9;if (whiteSkin) then
&#9;&#9;droppedDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton
&#9;else
&#9;&#9;droppedDownMenu.Style = Enum.ButtonStyle.RobloxButton
&#9;end
&#9;droppedDownMenu.Visible = false
&#9;droppedDownMenu.Active = true&#9;--Blocks clicks
&#9;droppedDownMenu.Position = UDim2.new(0,0,0,0)
&#9;droppedDownMenu.Size = UDim2.new(1,0, (1 + dropDownItemCount)*.8, 0)
&#9;droppedDownMenu.Parent = frame
&#9;droppedDownMenu.ZIndex = 2 + baseZIndex
&#9;local choiceButton = Instance.new(&quot;TextButton&quot;)
&#9;choiceButton.Name = &quot;ChoiceButton&quot;
&#9;choiceButton.BackgroundTransparency = 1
&#9;choiceButton.BorderSizePixel = 0
&#9;choiceButton.Text = &quot;ReplaceMe&quot;
&#9;choiceButton.TextColor3 = textColor
&#9;choiceButton.TextXAlignment = Enum.TextXAlignment.Left
&#9;choiceButton.TextYAlignment = Enum.TextYAlignment.Center
&#9;choiceButton.BackgroundColor3 = Color3.new(1, 1, 1)
&#9;choiceButton.Font = Enum.Font.Arial
&#9;choiceButton.FontSize = Enum.FontSize.Size18
&#9;if useScrollButtons then
&#9;&#9;choiceButton.Size = UDim2.new(1,-13, .8/((dropDownItemCount + 1)*.8),0)
&#9;else
&#9;&#9;choiceButton.Size = UDim2.new(1, 0, .8/((dropDownItemCount + 1)*.8),0)
&#9;end
&#9;choiceButton.TextWrap = true
&#9;choiceButton.ZIndex = 2 + baseZIndex
&#9;local areaSoak = Instance.new(&quot;TextButton&quot;)
&#9;areaSoak.Name = &quot;AreaSoak&quot;
&#9;areaSoak.Text = &quot;&quot;
&#9;areaSoak.BackgroundTransparency = 1
&#9;areaSoak.Active = true
&#9;areaSoak.Size = UDim2.new(1,0,1,0)
&#9;areaSoak.Visible = false
&#9;areaSoak.ZIndex = 3 + baseZIndex
&#9;local dropDownSelected = false
&#9;local scrollUpButton
&#9;local scrollDownButton
&#9;local scrollMouseCount = 0
&#9;local setZIndex = function(baseZIndex)
&#9;&#9;droppedDownMenu.ZIndex = baseZIndex +1
&#9;&#9;if scrollUpButton then
&#9;&#9;&#9;scrollUpButton.ZIndex = baseZIndex + 3
&#9;&#9;end
&#9;&#9;if scrollDownButton then
&#9;&#9;&#9;scrollDownButton.ZIndex = baseZIndex + 3
&#9;&#9;end
&#9;&#9;
&#9;&#9;local children = droppedDownMenu:GetChildren()
&#9;&#9;if children then
&#9;&#9;&#9;for i, child in ipairs(children) do
&#9;&#9;&#9;&#9;if child.Name == &quot;ChoiceButton&quot; then
&#9;&#9;&#9;&#9;&#9;child.ZIndex = baseZIndex + 2
&#9;&#9;&#9;&#9;elseif child.Name == &quot;ClickCaptureButton&quot; then
&#9;&#9;&#9;&#9;&#9;child.ZIndex = baseZIndex
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local scrollBarPosition = 1
&#9;local updateScroll = function()
&#9;&#9;if scrollUpButton then
&#9;&#9;&#9;scrollUpButton.Active = scrollBarPosition &gt; 1
&#9;&#9;end
&#9;&#9;if scrollDownButton then
&#9;&#9;&#9;scrollDownButton.Active = scrollBarPosition + dropDownItemCount &lt;= itemCount
&#9;&#9;end
&#9;&#9;local children = droppedDownMenu:GetChildren()
&#9;&#9;if not children then return end
&#9;&#9;local childNum = 1&#9;&#9;&#9;
&#9;&#9;for i, obj in ipairs(children) do
&#9;&#9;&#9;if obj.Name == &quot;ChoiceButton&quot; then
&#9;&#9;&#9;&#9;if childNum &lt; scrollBarPosition or childNum &gt;= scrollBarPosition + dropDownItemCount then
&#9;&#9;&#9;&#9;&#9;obj.Visible = false
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;obj.Position = UDim2.new(0,0,((childNum-scrollBarPosition+1)*.8)/((dropDownItemCount+1)*.8),0)
&#9;&#9;&#9;&#9;&#9;obj.Visible = true
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;obj.TextColor3 = textColor
&#9;&#9;&#9;&#9;obj.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;childNum = childNum + 1
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local toggleVisibility = function()
&#9;&#9;dropDownSelected = not dropDownSelected
&#9;&#9;areaSoak.Visible = not areaSoak.Visible
&#9;&#9;dropDownMenu.Visible = not dropDownSelected
&#9;&#9;droppedDownMenu.Visible = dropDownSelected
&#9;&#9;if dropDownSelected then
&#9;&#9;&#9;setZIndex(4 + baseZIndex)
&#9;&#9;else
&#9;&#9;&#9;setZIndex(2 + baseZIndex)
&#9;&#9;end
&#9;&#9;if useScrollButtons then
&#9;&#9;&#9;updateScroll()
&#9;&#9;end
&#9;end
&#9;droppedDownMenu.MouseButton1Click:connect(toggleVisibility)
&#9;local updateSelection = function(text)
&#9;&#9;local foundItem = false
&#9;&#9;local children = droppedDownMenu:GetChildren()
&#9;&#9;local childNum = 1
&#9;&#9;if children then
&#9;&#9;&#9;for i, obj in ipairs(children) do
&#9;&#9;&#9;&#9;if obj.Name == &quot;ChoiceButton&quot; then
&#9;&#9;&#9;&#9;&#9;if obj.Text == text then
&#9;&#9;&#9;&#9;&#9;&#9;obj.Font = Enum.Font.ArialBold
&#9;&#9;&#9;&#9;&#9;&#9;foundItem = true&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;scrollBarPosition = childNum&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;if (whiteSkin) then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;obj.TextColor3 = Color3.new(90/255,142/255,233/255)
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;obj.Font = Enum.Font.Arial
&#9;&#9;&#9;&#9;&#9;&#9;if (whiteSkin) then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;obj.TextColor3 = textColor
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;childNum = childNum + 1
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;if not text then
&#9;&#9;&#9;dropDownMenu.Text = &quot;Choose One&quot;
&#9;&#9;&#9;scrollBarPosition = 1
&#9;&#9;else
&#9;&#9;&#9;if not foundItem then
&#9;&#9;&#9;&#9;error(&quot;Invalid Selection Update -- &quot; .. text)
&#9;&#9;&#9;end
&#9;&#9;&#9;if scrollBarPosition + dropDownItemCount &gt; itemCount + 1 then
&#9;&#9;&#9;&#9;scrollBarPosition = itemCount - dropDownItemCount + 1
&#9;&#9;&#9;end
&#9;&#9;&#9;dropDownMenu.Text = text
&#9;&#9;end
&#9;end
&#9;
&#9;local function scrollDown()
&#9;&#9;if scrollBarPosition + dropDownItemCount &lt;= itemCount then
&#9;&#9;&#9;scrollBarPosition = scrollBarPosition + 1
&#9;&#9;&#9;updateScroll()
&#9;&#9;&#9;return true
&#9;&#9;end
&#9;&#9;return false
&#9;end
&#9;local function scrollUp()
&#9;&#9;if scrollBarPosition &gt; 1 then
&#9;&#9;&#9;scrollBarPosition = scrollBarPosition - 1
&#9;&#9;&#9;updateScroll()
&#9;&#9;&#9;return true
&#9;&#9;end
&#9;&#9;return false
&#9;end
&#9;
&#9;if useScrollButtons then
&#9;&#9;--Make some scroll buttons
&#9;&#9;scrollUpButton = Instance.new(&quot;ImageButton&quot;)
&#9;&#9;scrollUpButton.Name = &quot;ScrollUpButton&quot;
&#9;&#9;scrollUpButton.BackgroundTransparency = 1
&#9;&#9;scrollUpButton.Image = &quot;rbxasset://textures/ui/scrollbuttonUp.png&quot;
&#9;&#9;scrollUpButton.Size = UDim2.new(0,17,0,17)
&#9;&#9;scrollUpButton.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),0)
&#9;&#9;scrollUpButton.MouseButton1Click:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;&#9;&#9;end)
&#9;&#9;scrollUpButton.MouseLeave:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;&#9;&#9;end)
&#9;&#9;scrollUpButton.MouseButton1Down:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;
&#9;&#9;&#9;&#9;scrollUp()
&#9;&#9;&#9;&#9;local val = scrollMouseCount
&#9;&#9;&#9;&#9;wait(0.5)
&#9;&#9;&#9;&#9;while val == scrollMouseCount do
&#9;&#9;&#9;&#9;&#9;if scrollUp() == false then
&#9;&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;wait(0.1)
&#9;&#9;&#9;&#9;end&#9;&#9;&#9;&#9;
&#9;&#9;&#9;end)
&#9;&#9;scrollUpButton.Parent = droppedDownMenu
&#9;&#9;scrollDownButton = Instance.new(&quot;ImageButton&quot;)
&#9;&#9;scrollDownButton.Name = &quot;ScrollDownButton&quot;
&#9;&#9;scrollDownButton.BackgroundTransparency = 1
&#9;&#9;scrollDownButton.Image = &quot;rbxasset://textures/ui/scrollbuttonDown.png&quot;
&#9;&#9;scrollDownButton.Size = UDim2.new(0,17,0,17)
&#9;&#9;scrollDownButton.Position = UDim2.new(1,-11,1,-11)
&#9;&#9;scrollDownButton.Parent = droppedDownMenu
&#9;&#9;scrollDownButton.MouseButton1Click:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;&#9;&#9;end)
&#9;&#9;scrollDownButton.MouseLeave:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;&#9;&#9;end)
&#9;&#9;scrollDownButton.MouseButton1Down:connect(
&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;scrollMouseCount = scrollMouseCount + 1
&#9;&#9;&#9;&#9;scrollDown()
&#9;&#9;&#9;&#9;local val = scrollMouseCount
&#9;&#9;&#9;&#9;wait(0.5)
&#9;&#9;&#9;&#9;while val == scrollMouseCount do
&#9;&#9;&#9;&#9;&#9;if scrollDown() == false then
&#9;&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;wait(0.1)
&#9;&#9;&#9;&#9;end&#9;&#9;&#9;&#9;
&#9;&#9;&#9;end)&#9;
&#9;&#9;local scrollbar = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;scrollbar.Name = &quot;ScrollBar&quot;
&#9;&#9;scrollbar.Image = &quot;rbxasset://textures/ui/scrollbar.png&quot;
&#9;&#9;scrollbar.BackgroundTransparency = 1
&#9;&#9;scrollbar.Size = UDim2.new(0, 18, (dropDownItemCount*.8)/((dropDownItemCount+1)*.8), -(17) - 11 - 4)
&#9;&#9;scrollbar.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),17+2)
&#9;&#9;scrollbar.Parent = droppedDownMenu
&#9;end
&#9;for i,item in ipairs(items) do
&#9;&#9;-- needed to maintain local scope for items in event listeners below
&#9;&#9;local button = choiceButton:clone()&#9;
&#9;&#9;button.Text = item
&#9;&#9;button.Parent = droppedDownMenu
&#9;&#9;if (whiteSkin) then
&#9;&#9;&#9;button.TextColor3 = textColor
&#9;&#9;end
&#9;&#9;button.MouseButton1Click:connect(function()
&#9;&#9;&#9;--Remove Highlight
&#9;&#9;&#9;if (not whiteSkin) then
&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;end
&#9;&#9;&#9;button.BackgroundTransparency = 1
&#9;&#9;&#9;updateSelection(item)
&#9;&#9;&#9;onSelect(item)
&#9;&#9;&#9;toggleVisibility()
&#9;&#9;end)
&#9;&#9;button.MouseEnter:connect(function()
&#9;&#9;&#9;--Add Highlight&#9;
&#9;&#9;&#9;if (not whiteSkin) then
&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(0,0,0)
&#9;&#9;&#9;end
&#9;&#9;&#9;button.BackgroundTransparency = 0
&#9;&#9;end)
&#9;&#9;button.MouseLeave:connect(function()
&#9;&#9;&#9;--Remove Highlight
&#9;&#9;&#9;if (not whiteSkin) then
&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;end
&#9;&#9;&#9;button.BackgroundTransparency = 1
&#9;&#9;end)
&#9;end
&#9;--This does the initial layout of the buttons&#9;
&#9;updateScroll()
&#9;
&#9;frame.AncestryChanged:connect(function(child,parent)
&#9;&#9;if parent == nil then
&#9;&#9;&#9;areaSoak.Parent = nil
&#9;&#9;else
&#9;&#9;&#9;areaSoak.Parent = getScreenGuiAncestor(frame)
&#9;&#9;end
&#9;end)
&#9;dropDownMenu.MouseButton1Click:connect(toggleVisibility)
&#9;areaSoak.MouseButton1Click:connect(toggleVisibility)
&#9;return frame, updateSelection
end
t.CreatePropertyDropDownMenu = function(instance, property, enum)
&#9;local items = enum:GetEnumItems()
&#9;local names = {}
&#9;local nameToItem = {}
&#9;for i,obj in ipairs(items) do
&#9;&#9;names[i] = obj.Name
&#9;&#9;nameToItem[obj.Name] = obj
&#9;end
&#9;local frame
&#9;local updateSelection
&#9;frame, updateSelection = t.CreateDropDownMenu(names, function(text) instance[property] = nameToItem[text] end)
&#9;ScopedConnect(frame, instance, &quot;Changed&quot;,
&#9;&#9;function(prop)
&#9;&#9;&#9;if prop == property then
&#9;&#9;&#9;&#9;updateSelection(instance[property].Name)
&#9;&#9;&#9;end
&#9;&#9;end,
&#9;&#9;function()
&#9;&#9;&#9;updateSelection(instance[property].Name)
&#9;&#9;end)
&#9;return frame
end
t.GetFontHeight = function(font, fontSize)
&#9;if font == nil or fontSize == nil then
&#9;&#9;error(&quot;Font and FontSize must be non-nil&quot;)
&#9;end
&#9;if font == Enum.Font.Legacy then
&#9;&#9;if fontSize == Enum.FontSize.Size8 then
&#9;&#9;&#9;return 12
&#9;&#9;elseif fontSize == Enum.FontSize.Size9 then
&#9;&#9;&#9;return 14
&#9;&#9;elseif fontSize == Enum.FontSize.Size10 then
&#9;&#9;&#9;return 15
&#9;&#9;elseif fontSize == Enum.FontSize.Size11 then
&#9;&#9;&#9;return 17
&#9;&#9;elseif fontSize == Enum.FontSize.Size12 then
&#9;&#9;&#9;return 18
&#9;&#9;elseif fontSize == Enum.FontSize.Size14 then
&#9;&#9;&#9;return 21
&#9;&#9;elseif fontSize == Enum.FontSize.Size18 then
&#9;&#9;&#9;return 27
&#9;&#9;elseif fontSize == Enum.FontSize.Size24 then
&#9;&#9;&#9;return 36
&#9;&#9;elseif fontSize == Enum.FontSize.Size36 then
&#9;&#9;&#9;return 54
&#9;&#9;elseif fontSize == Enum.FontSize.Size48 then
&#9;&#9;&#9;return 72
&#9;&#9;else
&#9;&#9;&#9;error(&quot;Unknown FontSize&quot;)
&#9;&#9;end
&#9;elseif font == Enum.Font.Arial or font == Enum.Font.ArialBold then
&#9;&#9;if fontSize == Enum.FontSize.Size8 then
&#9;&#9;&#9;return 8
&#9;&#9;elseif fontSize == Enum.FontSize.Size9 then
&#9;&#9;&#9;return 9
&#9;&#9;elseif fontSize == Enum.FontSize.Size10 then
&#9;&#9;&#9;return 10
&#9;&#9;elseif fontSize == Enum.FontSize.Size11 then
&#9;&#9;&#9;return 11
&#9;&#9;elseif fontSize == Enum.FontSize.Size12 then
&#9;&#9;&#9;return 12
&#9;&#9;elseif fontSize == Enum.FontSize.Size14 then
&#9;&#9;&#9;return 14
&#9;&#9;elseif fontSize == Enum.FontSize.Size18 then
&#9;&#9;&#9;return 18
&#9;&#9;elseif fontSize == Enum.FontSize.Size24 then
&#9;&#9;&#9;return 24
&#9;&#9;elseif fontSize == Enum.FontSize.Size36 then
&#9;&#9;&#9;return 36
&#9;&#9;elseif fontSize == Enum.FontSize.Size48 then
&#9;&#9;&#9;return 48
&#9;&#9;else
&#9;&#9;&#9;error(&quot;Unknown FontSize&quot;)
&#9;&#9;end
&#9;else
&#9;&#9;error(&quot;Unknown Font &quot; .. font)
&#9;end
end
local function layoutGuiObjectsHelper(frame, guiObjects, settingsTable)
&#9;local totalPixels = frame.AbsoluteSize.Y
&#9;local pixelsRemaining = frame.AbsoluteSize.Y
&#9;for i, child in ipairs(guiObjects) do
&#9;&#9;if child:IsA(&quot;TextLabel&quot;) or child:IsA(&quot;TextButton&quot;) then
&#9;&#9;&#9;local isLabel = child:IsA(&quot;TextLabel&quot;)
&#9;&#9;&#9;if isLabel then
&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - settingsTable[&quot;TextLabelPositionPadY&quot;]
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - settingsTable[&quot;TextButtonPositionPadY&quot;]
&#9;&#9;&#9;end
&#9;&#9;&#9;child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
&#9;&#9;&#9;child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, pixelsRemaining)
&#9;&#9;&#9;if child.TextFits and child.TextBounds.Y &lt; pixelsRemaining then
&#9;&#9;&#9;&#9;child.Visible = true
&#9;&#9;&#9;&#9;if isLabel then
&#9;&#9;&#9;&#9;&#9;child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable[&quot;TextLabelSizePadY&quot;])
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable[&quot;TextButtonSizePadY&quot;])
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;while not child.TextFits do
&#9;&#9;&#9;&#9;&#9;child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.AbsoluteSize.Y + 1)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y&#9;&#9;
&#9;&#9;&#9;&#9;if isLabel then
&#9;&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - settingsTable[&quot;TextLabelPositionPadY&quot;]
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - settingsTable[&quot;TextButtonPositionPadY&quot;]
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;&#9;pixelsRemaining = -1
&#9;&#9;&#9;end&#9;&#9;&#9;
&#9;&#9;else
&#9;&#9;&#9;--GuiObject
&#9;&#9;&#9;child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
&#9;&#9;&#9;child.Visible = (pixelsRemaining &gt;= 0)
&#9;&#9;end
&#9;end
end
t.LayoutGuiObjects = function(frame, guiObjects, settingsTable)
&#9;if not frame:IsA(&quot;GuiObject&quot;) then
&#9;&#9;error(&quot;Frame must be a GuiObject&quot;)
&#9;end
&#9;for i, child in ipairs(guiObjects) do
&#9;&#9;if not child:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;error(&quot;All elements that are layed out must be of type GuiObject&quot;)
&#9;&#9;end
&#9;end
&#9;if not settingsTable then
&#9;&#9;settingsTable = {}
&#9;end
&#9;if not settingsTable[&quot;TextLabelSizePadY&quot;] then
&#9;&#9;settingsTable[&quot;TextLabelSizePadY&quot;] = 0
&#9;end
&#9;if not settingsTable[&quot;TextLabelPositionPadY&quot;] then
&#9;&#9;settingsTable[&quot;TextLabelPositionPadY&quot;] = 0
&#9;end
&#9;if not settingsTable[&quot;TextButtonSizePadY&quot;] then
&#9;&#9;settingsTable[&quot;TextButtonSizePadY&quot;] = 12
&#9;end
&#9;if not settingsTable[&quot;TextButtonPositionPadY&quot;] then
&#9;&#9;settingsTable[&quot;TextButtonPositionPadY&quot;] = 2
&#9;end
&#9;--Wrapper frame takes care of styled objects
&#9;local wrapperFrame = Instance.new(&quot;Frame&quot;)
&#9;wrapperFrame.Name = &quot;WrapperFrame&quot;
&#9;wrapperFrame.BackgroundTransparency = 1
&#9;wrapperFrame.Size = UDim2.new(1,0,1,0)
&#9;wrapperFrame.Parent = frame
&#9;for i, child in ipairs(guiObjects) do
&#9;&#9;child.Parent = wrapperFrame
&#9;end
&#9;local recalculate = function()
&#9;&#9;wait()
&#9;&#9;layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable)
&#9;end
&#9;
&#9;frame.Changed:connect(
&#9;&#9;function(prop)
&#9;&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;&#9;--Wait a heartbeat for it to sync in
&#9;&#9;&#9;&#9;recalculate(nil)
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;frame.AncestryChanged:connect(recalculate)
&#9;layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable)
end
t.CreateSlider = function(steps,width,position)
&#9;local sliderGui = Instance.new(&quot;Frame&quot;)
&#9;sliderGui.Size = UDim2.new(1,0,1,0)
&#9;sliderGui.BackgroundTransparency = 1
&#9;sliderGui.Name = &quot;SliderGui&quot;
&#9;
&#9;local sliderSteps = Instance.new(&quot;IntValue&quot;)
&#9;sliderSteps.Name = &quot;SliderSteps&quot;
&#9;sliderSteps.Value = steps
&#9;sliderSteps.Parent = sliderGui
&#9;
&#9;local areaSoak = Instance.new(&quot;TextButton&quot;)
&#9;areaSoak.Name = &quot;AreaSoak&quot;
&#9;areaSoak.Text = &quot;&quot;
&#9;areaSoak.BackgroundTransparency = 1
&#9;areaSoak.Active = false
&#9;areaSoak.Size = UDim2.new(1,0,1,0)
&#9;areaSoak.Visible = false
&#9;areaSoak.ZIndex = 4
&#9;
&#9;sliderGui.AncestryChanged:connect(function(child,parent)
&#9;&#9;if parent == nil then
&#9;&#9;&#9;areaSoak.Parent = nil
&#9;&#9;else
&#9;&#9;&#9;areaSoak.Parent = getScreenGuiAncestor(sliderGui)
&#9;&#9;end
&#9;end)
&#9;
&#9;local sliderPosition = Instance.new(&quot;IntValue&quot;)
&#9;sliderPosition.Name = &quot;SliderPosition&quot;
&#9;sliderPosition.Value = 0
&#9;sliderPosition.Parent = sliderGui
&#9;
&#9;local id = math.random(1,100)
&#9;
&#9;local bar = Instance.new(&quot;TextButton&quot;)
&#9;bar.Text = &quot;&quot;
&#9;bar.AutoButtonColor = false
&#9;bar.Name = &quot;Bar&quot;
&#9;bar.BackgroundColor3 = Color3.new(0,0,0)
&#9;if type(width) == &quot;number&quot; then
&#9;&#9;bar.Size = UDim2.new(0,width,0,5)
&#9;else
&#9;&#9;bar.Size = UDim2.new(0,200,0,5)
&#9;end
&#9;bar.BorderColor3 = Color3.new(95/255,95/255,95/255)
&#9;bar.ZIndex = 2
&#9;bar.Parent = sliderGui
&#9;
&#9;if position[&quot;X&quot;] and position[&quot;X&quot;][&quot;Scale&quot;] and position[&quot;X&quot;][&quot;Offset&quot;] and position[&quot;Y&quot;] and position[&quot;Y&quot;][&quot;Scale&quot;] and position[&quot;Y&quot;][&quot;Offset&quot;] then
&#9;&#9;bar.Position = position
&#9;end
&#9;
&#9;local slider = Instance.new(&quot;ImageButton&quot;)
&#9;slider.Name = &quot;Slider&quot;
&#9;slider.BackgroundTransparency = 1
&#9;slider.Image = &quot;rbxasset://textures/ui/Slider.png&quot;
&#9;slider.Position = UDim2.new(0,0,0.5,-10)
&#9;slider.Size = UDim2.new(0,20,0,20)
&#9;slider.ZIndex = 3
&#9;slider.Parent = bar
&#9;
&#9;local areaSoakMouseMoveCon = nil
&#9;
&#9;areaSoak.MouseLeave:connect(function()
&#9;&#9;if areaSoak.Visible then
&#9;&#9;&#9;cancelSlide(areaSoak)
&#9;&#9;end
&#9;end)
&#9;areaSoak.MouseButton1Up:connect(function()
&#9;&#9;if areaSoak.Visible then
&#9;&#9;&#9;cancelSlide(areaSoak)
&#9;&#9;end
&#9;end)
&#9;
&#9;slider.MouseButton1Down:connect(function()
&#9;&#9;areaSoak.Visible = true
&#9;&#9;if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
&#9;&#9;areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y)
&#9;&#9;&#9;setSliderPos(x,slider,sliderPosition,bar,steps)
&#9;&#9;end)
&#9;end)
&#9;
&#9;slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end)
&#9;
&#9;sliderPosition.Changed:connect(function(prop)
&#9;&#9;sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value))
&#9;&#9;local relativePosX = (sliderPosition.Value - 1) / (steps - 1)
&#9;&#9;slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
&#9;end)
&#9;
&#9;bar.MouseButton1Down:connect(function(x,y)
&#9;&#9;setSliderPos(x,slider,sliderPosition,bar,steps)
&#9;end)
&#9;
&#9;return sliderGui, sliderPosition, sliderSteps
end
t.CreateSliderNew = function(steps,width,position)
&#9;local sliderGui = Instance.new(&quot;Frame&quot;)
&#9;sliderGui.Size = UDim2.new(1,0,1,0)
&#9;sliderGui.BackgroundTransparency = 1
&#9;sliderGui.Name = &quot;SliderGui&quot;
&#9;
&#9;local sliderSteps = Instance.new(&quot;IntValue&quot;)
&#9;sliderSteps.Name = &quot;SliderSteps&quot;
&#9;sliderSteps.Value = steps
&#9;sliderSteps.Parent = sliderGui
&#9;
&#9;local areaSoak = Instance.new(&quot;TextButton&quot;)
&#9;areaSoak.Name = &quot;AreaSoak&quot;
&#9;areaSoak.Text = &quot;&quot;
&#9;areaSoak.BackgroundTransparency = 1
&#9;areaSoak.Active = false
&#9;areaSoak.Size = UDim2.new(1,0,1,0)
&#9;areaSoak.Visible = false
&#9;areaSoak.ZIndex = 6
&#9;
&#9;sliderGui.AncestryChanged:connect(function(child,parent)
&#9;&#9;if parent == nil then
&#9;&#9;&#9;areaSoak.Parent = nil
&#9;&#9;else
&#9;&#9;&#9;areaSoak.Parent = getScreenGuiAncestor(sliderGui)
&#9;&#9;end
&#9;end)
&#9;
&#9;local sliderPosition = Instance.new(&quot;IntValue&quot;)
&#9;sliderPosition.Name = &quot;SliderPosition&quot;
&#9;sliderPosition.Value = 0
&#9;sliderPosition.Parent = sliderGui
&#9;
&#9;local id = math.random(1,100)
&#9;
&#9;local sliderBarImgHeight = 7
&#9;local sliderBarCapImgWidth = 4
&#9;local bar = Instance.new(&quot;ImageButton&quot;)
&#9;bar.BackgroundTransparency = 1
&#9;bar.Image = &quot;rbxasset://textures/ui/Slider-BKG-Center.png&quot;
&#9;bar.Name = &quot;Bar&quot;
&#9;local displayWidth = 200
&#9;if type(width) == &quot;number&quot; then
&#9;&#9;bar.Size = UDim2.new(0,width - (sliderBarCapImgWidth * 2),0,sliderBarImgHeight)
&#9;&#9;displayWidth = width - (sliderBarCapImgWidth * 2)
&#9;else
&#9;&#9;bar.Size = UDim2.new(0,200,0,sliderBarImgHeight)
&#9;end
&#9;bar.ZIndex = 3
&#9;bar.Parent = sliderGui&#9;
&#9;if position[&quot;X&quot;] and position[&quot;X&quot;][&quot;Scale&quot;] and position[&quot;X&quot;][&quot;Offset&quot;] and position[&quot;Y&quot;] and position[&quot;Y&quot;][&quot;Scale&quot;] and position[&quot;Y&quot;][&quot;Offset&quot;] then
&#9;&#9;bar.Position = position
&#9;end
&#9;local barLeft = bar:clone()
&#9;barLeft.Name = &quot;BarLeft&quot;
&#9;barLeft.Image = &quot;rbxasset://textures/ui/Slider-BKG-Left-Cap.png&quot;
&#9;barLeft.Size = UDim2.new(0, sliderBarCapImgWidth, 0, sliderBarImgHeight)
&#9;barLeft.Position = UDim2.new(position.X.Scale, position.X.Offset - sliderBarCapImgWidth, position.Y.Scale, position.Y.Offset)
&#9;barLeft.Parent = sliderGui&#9;
&#9;barLeft.ZIndex = 3
&#9;local barRight = barLeft:clone()
&#9;barRight.Name = &quot;BarRight&quot;
&#9;barRight.Image = &quot;rbxasset://textures/ui/Slider-BKG-Right-Cap.png&quot;
&#9;barRight.Position = UDim2.new(position.X.Scale, position.X.Offset + displayWidth, position.Y.Scale, position.Y.Offset)
&#9;barRight.Parent = sliderGui&#9;
&#9;local fillLeft = barLeft:clone()
&#9;fillLeft.Name = &quot;FillLeft&quot;
&#9;fillLeft.Image = &quot;rbxasset://textures/ui/Slider-Fill-Left-Cap.png&quot;
&#9;fillLeft.Parent = sliderGui&#9;
&#9;fillLeft.ZIndex = 4
&#9;local fill = fillLeft:clone()
&#9;fill.Name = &quot;Fill&quot;
&#9;fill.Image = &quot;rbxasset://textures/ui/Slider-Fill-Center.png&quot;
&#9;fill.Parent = bar&#9;
&#9;fill.ZIndex = 4
&#9;fill.Position = UDim2.new(0, 0, 0, 0)
&#9;fill.Size = UDim2.new(0.5, 0, 1, 0)
--&#9;bar.Visible = false
&#9;local slider = Instance.new(&quot;ImageButton&quot;)
&#9;slider.Name = &quot;Slider&quot;
&#9;slider.BackgroundTransparency = 1
&#9;slider.Image = &quot;rbxasset://textures/ui/slider_new_tab.png&quot;
&#9;slider.Position = UDim2.new(0,0,0.5,-14)
&#9;slider.Size = UDim2.new(0,28,0,28)
&#9;slider.ZIndex = 5
&#9;slider.Parent = bar
&#9;
&#9;local areaSoakMouseMoveCon = nil
&#9;
&#9;areaSoak.MouseLeave:connect(function()
&#9;&#9;if areaSoak.Visible then
&#9;&#9;&#9;cancelSlide(areaSoak)
&#9;&#9;end
&#9;end)
&#9;areaSoak.MouseButton1Up:connect(function()
&#9;&#9;if areaSoak.Visible then
&#9;&#9;&#9;cancelSlide(areaSoak)
&#9;&#9;end
&#9;end)
&#9;
&#9;slider.MouseButton1Down:connect(function()
&#9;&#9;areaSoak.Visible = true
&#9;&#9;if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
&#9;&#9;areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y)
&#9;&#9;&#9;setSliderPos(x,slider,sliderPosition,bar,steps)
&#9;&#9;end)
&#9;end)
&#9;
&#9;slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end)
&#9;
&#9;sliderPosition.Changed:connect(function(prop)
&#9;&#9;sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value))
&#9;&#9;local relativePosX = (sliderPosition.Value - 1) / (steps - 1)
&#9;&#9;slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
&#9;&#9;fill.Size = UDim2.new(relativePosX, 0, 1, 0)
&#9;end)
&#9;
&#9;bar.MouseButton1Down:connect(function(x,y)
&#9;&#9;setSliderPos(x,slider,sliderPosition,bar,steps)
&#9;end)
&#9;return sliderGui, sliderPosition, sliderSteps
end
t.CreateTrueScrollingFrame = function()
&#9;local lowY = nil
&#9;local highY = nil
&#9;
&#9;local dragCon = nil
&#9;local upCon = nil
&#9;local internalChange = false
&#9;local descendantsChangeConMap = {}
&#9;local scrollingFrame = Instance.new(&quot;Frame&quot;)
&#9;scrollingFrame.Name = &quot;ScrollingFrame&quot;
&#9;scrollingFrame.Active = true
&#9;scrollingFrame.Size = UDim2.new(1,0,1,0)
&#9;scrollingFrame.ClipsDescendants = true
&#9;local controlFrame = Instance.new(&quot;Frame&quot;)
&#9;controlFrame.Name = &quot;ControlFrame&quot;
&#9;controlFrame.BackgroundTransparency = 1
&#9;controlFrame.Size = UDim2.new(0,18,1,0)
&#9;controlFrame.Position = UDim2.new(1,-20,0,0)
&#9;controlFrame.Parent = scrollingFrame
&#9;
&#9;local scrollBottom = Instance.new(&quot;BoolValue&quot;)
&#9;scrollBottom.Value = false
&#9;scrollBottom.Name = &quot;ScrollBottom&quot;
&#9;scrollBottom.Parent = controlFrame
&#9;
&#9;local scrollUp = Instance.new(&quot;BoolValue&quot;)
&#9;scrollUp.Value = false
&#9;scrollUp.Name = &quot;scrollUp&quot;
&#9;scrollUp.Parent = controlFrame
&#9;local scrollUpButton = Instance.new(&quot;TextButton&quot;)
&#9;scrollUpButton.Name = &quot;ScrollUpButton&quot;
&#9;scrollUpButton.Text = &quot;&quot;
&#9;scrollUpButton.AutoButtonColor = false
&#9;scrollUpButton.BackgroundColor3 = Color3.new(0,0,0)
&#9;scrollUpButton.BorderColor3 = Color3.new(1,1,1)
&#9;scrollUpButton.BackgroundTransparency = 0.5
&#9;scrollUpButton.Size = UDim2.new(0,18,0,18)
&#9;scrollUpButton.ZIndex = 2
&#9;scrollUpButton.Parent = controlFrame
&#9;for i = 1, 6 do
&#9;&#9;local triFrame = Instance.new(&quot;Frame&quot;)
&#9;&#9;triFrame.BorderColor3 = Color3.new(1,1,1)
&#9;&#9;triFrame.Name = &quot;tri&quot; .. tostring(i)
&#9;&#9;triFrame.ZIndex = 3
&#9;&#9;triFrame.BackgroundTransparency = 0.5
&#9;&#9;triFrame.Size = UDim2.new(0,12 - ((i -1) * 2),0,0)
&#9;&#9;triFrame.Position = UDim2.new(0,3 + (i -1),0.5,2 - (i -1))
&#9;&#9;triFrame.Parent = scrollUpButton
&#9;end
&#9;scrollUpButton.MouseEnter:connect(function()
&#9;&#9;scrollUpButton.BackgroundTransparency = 0.1
&#9;&#9;local upChildren = scrollUpButton:GetChildren()
&#9;&#9;for i = 1, #upChildren do
&#9;&#9;&#9;upChildren[i].BackgroundTransparency = 0.1
&#9;&#9;end
&#9;end)
&#9;scrollUpButton.MouseLeave:connect(function()
&#9;&#9;scrollUpButton.BackgroundTransparency = 0.5
&#9;&#9;local upChildren = scrollUpButton:GetChildren()
&#9;&#9;for i = 1, #upChildren do
&#9;&#9;&#9;upChildren[i].BackgroundTransparency = 0.5
&#9;&#9;end
&#9;end)
&#9;local scrollDownButton = scrollUpButton:clone()
&#9;scrollDownButton.Name = &quot;ScrollDownButton&quot;
&#9;scrollDownButton.Position = UDim2.new(0,0,1,-18)
&#9;local downChildren = scrollDownButton:GetChildren()
&#9;for i = 1, #downChildren do
&#9;&#9;downChildren[i].Position = UDim2.new(0,3 + (i -1),0.5,-2 + (i - 1))
&#9;end
&#9;scrollDownButton.MouseEnter:connect(function()
&#9;&#9;scrollDownButton.BackgroundTransparency = 0.1
&#9;&#9;local downChildren = scrollDownButton:GetChildren()
&#9;&#9;for i = 1, #downChildren do
&#9;&#9;&#9;downChildren[i].BackgroundTransparency = 0.1
&#9;&#9;end
&#9;end)
&#9;scrollDownButton.MouseLeave:connect(function()
&#9;&#9;scrollDownButton.BackgroundTransparency = 0.5
&#9;&#9;local downChildren = scrollDownButton:GetChildren()
&#9;&#9;for i = 1, #downChildren do
&#9;&#9;&#9;downChildren[i].BackgroundTransparency = 0.5
&#9;&#9;end
&#9;end)
&#9;scrollDownButton.Parent = controlFrame
&#9;
&#9;local scrollTrack = Instance.new(&quot;Frame&quot;)
&#9;scrollTrack.Name = &quot;ScrollTrack&quot;
&#9;scrollTrack.BackgroundTransparency = 1
&#9;scrollTrack.Size = UDim2.new(0,18,1,-38)
&#9;scrollTrack.Position = UDim2.new(0,0,0,19)
&#9;scrollTrack.Parent = controlFrame
&#9;local scrollbar = Instance.new(&quot;TextButton&quot;)
&#9;scrollbar.BackgroundColor3 = Color3.new(0,0,0)
&#9;scrollbar.BorderColor3 = Color3.new(1,1,1)
&#9;scrollbar.BackgroundTransparency = 0.5
&#9;scrollbar.AutoButtonColor = false
&#9;scrollbar.Text = &quot;&quot;
&#9;scrollbar.Active = true
&#9;scrollbar.Name = &quot;ScrollBar&quot;
&#9;scrollbar.ZIndex = 2
&#9;scrollbar.BackgroundTransparency = 0.5
&#9;scrollbar.Size = UDim2.new(0, 18, 0.1, 0)
&#9;scrollbar.Position = UDim2.new(0,0,0,0)
&#9;scrollbar.Parent = scrollTrack
&#9;local scrollNub = Instance.new(&quot;Frame&quot;)
&#9;scrollNub.Name = &quot;ScrollNub&quot;
&#9;scrollNub.BorderColor3 = Color3.new(1,1,1)
&#9;scrollNub.Size = UDim2.new(0,10,0,0)
&#9;scrollNub.Position = UDim2.new(0.5,-5,0.5,0)
&#9;scrollNub.ZIndex = 2
&#9;scrollNub.BackgroundTransparency = 0.5
&#9;scrollNub.Parent = scrollbar
&#9;local newNub = scrollNub:clone()
&#9;newNub.Position = UDim2.new(0.5,-5,0.5,-2)
&#9;newNub.Parent = scrollbar
&#9;
&#9;local lastNub = scrollNub:clone()
&#9;lastNub.Position = UDim2.new(0.5,-5,0.5,2)
&#9;lastNub.Parent = scrollbar
&#9;scrollbar.MouseEnter:connect(function()
&#9;&#9;scrollbar.BackgroundTransparency = 0.1
&#9;&#9;scrollNub.BackgroundTransparency = 0.1
&#9;&#9;newNub.BackgroundTransparency = 0.1
&#9;&#9;lastNub.BackgroundTransparency = 0.1
&#9;end)
&#9;scrollbar.MouseLeave:connect(function()
&#9;&#9;scrollbar.BackgroundTransparency = 0.5
&#9;&#9;scrollNub.BackgroundTransparency = 0.5
&#9;&#9;newNub.BackgroundTransparency = 0.5
&#9;&#9;lastNub.BackgroundTransparency = 0.5
&#9;end)
&#9;local mouseDrag = Instance.new(&quot;ImageButton&quot;)
&#9;mouseDrag.Active = false
&#9;mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0)
&#9;mouseDrag.AutoButtonColor = false
&#9;mouseDrag.BackgroundTransparency = 1
&#9;mouseDrag.Name = &quot;mouseDrag&quot;
&#9;mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0)
&#9;mouseDrag.ZIndex = 10
&#9;
&#9;local function positionScrollBar(x,y,offset)
&#9;&#9;local oldPos = scrollbar.Position
&#9;&#9;if y &lt; scrollTrack.AbsolutePosition.y then
&#9;&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0)
&#9;&#9;&#9;return (oldPos ~= scrollbar.Position)
&#9;&#9;end
&#9;&#9;
&#9;&#9;local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y
&#9;&#9;if y &gt; (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then
&#9;&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0)
&#9;&#9;&#9;return (oldPos ~= scrollbar.Position)
&#9;&#9;end
&#9;&#9;local newScaleYPos = (y - scrollTrack.AbsolutePosition.y - offset)/scrollTrack.AbsoluteSize.y
&#9;&#9;if newScaleYPos + relativeSize &gt; 1 then
&#9;&#9;&#9;newScaleYPos = 1 - relativeSize
&#9;&#9;&#9;scrollBottom.Value = true
&#9;&#9;&#9;scrollUp.Value = false
&#9;&#9;elseif newScaleYPos &lt;= 0 then
&#9;&#9;&#9;newScaleYPos = 0
&#9;&#9;&#9;scrollUp.Value = true
&#9;&#9;&#9;scrollBottom.Value = false
&#9;&#9;else
&#9;&#9;&#9;scrollUp.Value = false
&#9;&#9;&#9;scrollBottom.Value = false
&#9;&#9;end
&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,newScaleYPos,0)
&#9;&#9;
&#9;&#9;return (oldPos ~= scrollbar.Position)
&#9;end
&#9;local function drillDownSetHighLow(instance)
&#9;&#9;if not instance or not instance:IsA(&quot;GuiObject&quot;) then return end
&#9;&#9;if instance == controlFrame then return end
&#9;&#9;if instance:IsDescendantOf(controlFrame) then return end
&#9;&#9;if not instance.Visible then return end
&#9;&#9;if lowY and lowY &gt; instance.AbsolutePosition.Y then
&#9;&#9;&#9;lowY = instance.AbsolutePosition.Y
&#9;&#9;elseif not lowY then
&#9;&#9;&#9;lowY = instance.AbsolutePosition.Y
&#9;&#9;end
&#9;&#9;if highY and highY &lt; (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) then
&#9;&#9;&#9;highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
&#9;&#9;elseif not highY then
&#9;&#9;&#9;highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
&#9;&#9;end
&#9;&#9;local children = instance:GetChildren()
&#9;&#9;for i = 1, #children do
&#9;&#9;&#9;drillDownSetHighLow(children[i])
&#9;&#9;end
&#9;end
&#9;local function resetHighLow()
&#9;&#9;local firstChildren = scrollingFrame:GetChildren()
&#9;&#9;for i = 1, #firstChildren do
&#9;&#9;&#9;drillDownSetHighLow(firstChildren[i])
&#9;&#9;end
&#9;end
&#9;local function recalculate()
&#9;&#9;internalChange = true
&#9;&#9;local percentFrame = 0
&#9;&#9;if scrollbar.Position.Y.Scale &gt; 0 then
&#9;&#9;&#9;if scrollbar.Visible then
&#9;&#9;&#9;&#9;percentFrame = scrollbar.Position.Y.Scale/((scrollTrack.AbsoluteSize.Y - scrollbar.AbsoluteSize.Y)/scrollTrack.AbsoluteSize.Y)
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;percentFrame = 0
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;if percentFrame &gt; 0.99 then percentFrame = 1 end
&#9;&#9;local hiddenYAmount = (scrollingFrame.AbsoluteSize.Y - (highY - lowY)) * percentFrame
&#9;&#9;
&#9;&#9;local guiChildren = scrollingFrame:GetChildren()
&#9;&#9;for i = 1, #guiChildren do
&#9;&#9;&#9;if guiChildren[i] ~= controlFrame then
&#9;&#9;&#9;&#9;guiChildren[i].Position = UDim2.new(guiChildren[i].Position.X.Scale,guiChildren[i].Position.X.Offset,
&#9;&#9;&#9;&#9;&#9;0, math.ceil(guiChildren[i].AbsolutePosition.Y) - math.ceil(lowY) + hiddenYAmount)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;lowY = nil
&#9;&#9;highY = nil
&#9;&#9;resetHighLow()
&#9;&#9;internalChange = false
&#9;end
&#9;local function setSliderSizeAndPosition()
&#9;&#9;if not highY or not lowY then return end
&#9;&#9;local totalYSpan = math.abs(highY - lowY)
&#9;&#9;if totalYSpan == 0 then
&#9;&#9;&#9;scrollbar.Visible = false
&#9;&#9;&#9;scrollDownButton.Visible = false
&#9;&#9;&#9;scrollUpButton.Visible = false
&#9;&#9;&#9;if dragCon then dragCon:disconnect() dragCon = nil end
&#9;&#9;&#9;if upCon then upCon:disconnect() upCon = nil end
&#9;&#9;&#9;return
&#9;&#9;end
&#9;&#9;local percentShown = scrollingFrame.AbsoluteSize.Y/totalYSpan
&#9;&#9;if percentShown &gt;= 1 then
&#9;&#9;&#9;scrollbar.Visible = false
&#9;&#9;&#9;scrollDownButton.Visible = false
&#9;&#9;&#9;scrollUpButton.Visible = false
&#9;&#9;&#9;recalculate()
&#9;&#9;else
&#9;&#9;&#9;scrollbar.Visible = true
&#9;&#9;&#9;scrollDownButton.Visible = true
&#9;&#9;&#9;scrollUpButton.Visible = true
&#9;&#9;&#9;scrollbar.Size = UDim2.new(scrollbar.Size.X.Scale,scrollbar.Size.X.Offset,percentShown,0)
&#9;&#9;end
&#9;&#9;local percentPosition = (scrollingFrame.AbsolutePosition.Y - lowY)/totalYSpan
&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,percentPosition,-scrollbar.AbsoluteSize.X/2)
&#9;&#9;if scrollbar.AbsolutePosition.y &lt; scrollTrack.AbsolutePosition.y then
&#9;&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0)
&#9;&#9;end
&#9;&#9;if (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.Y) &gt; (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then
&#9;&#9;&#9;local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y
&#9;&#9;&#9;scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0)
&#9;&#9;end
&#9;end
&#9;
&#9;local buttonScrollAmountPixels = 7
&#9;local reentrancyGuardScrollUp = false
&#9;local function doScrollUp()
&#9;&#9;if reentrancyGuardScrollUp then return end
&#9;&#9;
&#9;&#9;reentrancyGuardScrollUp = true
&#9;&#9;&#9;if positionScrollBar(0,scrollbar.AbsolutePosition.Y - buttonScrollAmountPixels,0) then
&#9;&#9;&#9;&#9;recalculate()
&#9;&#9;&#9;end
&#9;&#9;reentrancyGuardScrollUp = false
&#9;end
&#9;
&#9;local reentrancyGuardScrollDown = false
&#9;local function doScrollDown()
&#9;&#9;if reentrancyGuardScrollDown then return end
&#9;&#9;
&#9;&#9;reentrancyGuardScrollDown = true
&#9;&#9;&#9;if positionScrollBar(0,scrollbar.AbsolutePosition.Y + buttonScrollAmountPixels,0) then
&#9;&#9;&#9;&#9;recalculate()
&#9;&#9;&#9;end
&#9;&#9;reentrancyGuardScrollDown = false
&#9;end
&#9;local function scrollUp(mouseYPos)
&#9;&#9;if scrollUpButton.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local current = scrollStamp
&#9;&#9;&#9;local upCon
&#9;&#9;&#9;upCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;upCon:disconnect()
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;&#9;doScrollUp()
&#9;&#9;&#9;wait(0.2)
&#9;&#9;&#9;local t = tick()
&#9;&#9;&#9;local w = 0.1
&#9;&#9;&#9;while scrollStamp == current do
&#9;&#9;&#9;&#9;doScrollUp()
&#9;&#9;&#9;&#9;if mouseYPos and mouseYPos &gt; scrollbar.AbsolutePosition.y then
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if not scrollUpButton.Active then break end
&#9;&#9;&#9;&#9;if tick()-t &gt; 5 then
&#9;&#9;&#9;&#9;&#9;w = 0
&#9;&#9;&#9;&#9;elseif tick()-t &gt; 2 then
&#9;&#9;&#9;&#9;&#9;w = 0.06
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;wait(w)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local function scrollDown(mouseYPos)
&#9;&#9;if scrollDownButton.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local current = scrollStamp
&#9;&#9;&#9;local downCon
&#9;&#9;&#9;downCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;downCon:disconnect()
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;&#9;doScrollDown()
&#9;&#9;&#9;wait(0.2)
&#9;&#9;&#9;local t = tick()
&#9;&#9;&#9;local w = 0.1
&#9;&#9;&#9;while scrollStamp == current do
&#9;&#9;&#9;&#9;doScrollDown()
&#9;&#9;&#9;&#9;if mouseYPos and mouseYPos &lt; (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.x) then
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if not scrollDownButton.Active then break end
&#9;&#9;&#9;&#9;if tick()-t &gt; 5 then
&#9;&#9;&#9;&#9;&#9;w = 0
&#9;&#9;&#9;&#9;elseif tick()-t &gt; 2 then
&#9;&#9;&#9;&#9;&#9;w = 0.06
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;wait(w)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;
&#9;scrollbar.MouseButton1Down:connect(function(x,y)
&#9;&#9;if scrollbar.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local mouseOffset = y - scrollbar.AbsolutePosition.y
&#9;&#9;&#9;if dragCon then dragCon:disconnect() dragCon = nil end
&#9;&#9;&#9;if upCon then upCon:disconnect() upCon = nil end
&#9;&#9;&#9;local prevY = y
&#9;&#9;&#9;local reentrancyGuardMouseScroll = false
&#9;&#9;&#9;dragCon = mouseDrag.MouseMoved:connect(function(x,y)
&#9;&#9;&#9;&#9;if reentrancyGuardMouseScroll then return end
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;reentrancyGuardMouseScroll = true
&#9;&#9;&#9;&#9;&#9;if positionScrollBar(x,y,mouseOffset) then
&#9;&#9;&#9;&#9;&#9;&#9;recalculate()
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;reentrancyGuardMouseScroll = false
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;end)
&#9;&#9;&#9;upCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;dragCon:disconnect(); dragCon = nil
&#9;&#9;&#9;&#9;upCon:disconnect(); drag = nil
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;end
&#9;end)
&#9;local scrollMouseCount = 0
&#9;scrollUpButton.MouseButton1Down:connect(function()
&#9;&#9;scrollUp()
&#9;end)
&#9;scrollUpButton.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;scrollDownButton.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;scrollDownButton.MouseButton1Down:connect(function()
&#9;&#9; scrollDown()
&#9;end)
&#9;&#9;
&#9;scrollbar.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;
&#9;local function heightCheck(instance)
&#9;&#9;if highY and (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) &gt; highY then
&#9;&#9;&#9;highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
&#9;&#9;elseif not highY then
&#9;&#9;&#9;highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
&#9;&#9;end
&#9;&#9;setSliderSizeAndPosition()
&#9;end
&#9;
&#9;local function highLowRecheck()
&#9;&#9;local oldLowY = lowY
&#9;&#9;local oldHighY = highY
&#9;&#9;lowY = nil
&#9;&#9;highY = nil
&#9;&#9;resetHighLow()
&#9;&#9;if (lowY ~= oldLowY) or (highY ~= oldHighY) then
&#9;&#9;&#9;setSliderSizeAndPosition()
&#9;&#9;end
&#9;end
&#9;local function descendantChanged(this, prop)
&#9;&#9;if internalChange then return end
&#9;&#9;if not this.Visible then return end
&#9;&#9;if prop == &quot;Size&quot; or prop == &quot;Position&quot; then
&#9;&#9;&#9;wait()
&#9;&#9;&#9;highLowRecheck()
&#9;&#9;end
&#9;end
&#9;scrollingFrame.DescendantAdded:connect(function(instance)
&#9;&#9;if not instance:IsA(&quot;GuiObject&quot;) then return end
&#9;&#9;if instance.Visible then
&#9;&#9;&#9;wait() -- wait a heartbeat for sizes to reconfig
&#9;&#9;&#9;highLowRecheck()
&#9;&#9;end
&#9;&#9;descendantsChangeConMap[instance] = instance.Changed:connect(function(prop) descendantChanged(instance, prop) end)
&#9;end)
&#9;scrollingFrame.DescendantRemoving:connect(function(instance)
&#9;&#9;if not instance:IsA(&quot;GuiObject&quot;) then return end
&#9;&#9;if descendantsChangeConMap[instance] then
&#9;&#9;&#9;descendantsChangeConMap[instance]:disconnect()
&#9;&#9;&#9;descendantsChangeConMap[instance] = nil
&#9;&#9;end
&#9;&#9;wait() -- wait a heartbeat for sizes to reconfig
&#9;&#9;highLowRecheck()
&#9;end)
&#9;
&#9;scrollingFrame.Changed:connect(function(prop)
&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;if not highY or not lowY then return end
&#9;&#9;&#9;highLowRecheck()
&#9;&#9;&#9;setSliderSizeAndPosition()
&#9;&#9;end
&#9;end)
&#9;return scrollingFrame, controlFrame
end
t.CreateScrollingFrame = function(orderList,scrollStyle)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Name = &quot;ScrollingFrame&quot;
&#9;frame.BackgroundTransparency = 1
&#9;frame.Size = UDim2.new(1,0,1,0)
&#9;
&#9;local scrollUpButton = Instance.new(&quot;ImageButton&quot;)
&#9;scrollUpButton.Name = &quot;ScrollUpButton&quot;
&#9;scrollUpButton.BackgroundTransparency = 1
&#9;scrollUpButton.Image = &quot;rbxasset://textures/ui/scrollbuttonUp.png&quot;
&#9;scrollUpButton.Size = UDim2.new(0,17,0,17)
&#9;
&#9;local scrollDownButton = Instance.new(&quot;ImageButton&quot;)
&#9;scrollDownButton.Name = &quot;ScrollDownButton&quot;
&#9;scrollDownButton.BackgroundTransparency = 1
&#9;scrollDownButton.Image = &quot;rbxasset://textures/ui/scrollbuttonDown.png&quot;
&#9;scrollDownButton.Size = UDim2.new(0,17,0,17)
&#9;
&#9;local scrollbar = Instance.new(&quot;ImageButton&quot;)
&#9;scrollbar.Name = &quot;ScrollBar&quot;
&#9;scrollbar.Image = &quot;rbxasset://textures/ui/scrollbar.png&quot;
&#9;scrollbar.BackgroundTransparency = 1
&#9;scrollbar.Size = UDim2.new(0, 18, 0, 150)
&#9;local scrollStamp = 0
&#9;&#9;
&#9;local scrollDrag = Instance.new(&quot;ImageButton&quot;)
&#9;scrollDrag.Image = &quot;http://www.roblox.com/asset/?id=61367186&quot;
&#9;scrollDrag.Size = UDim2.new(1, 0, 0, 16)
&#9;scrollDrag.BackgroundTransparency = 1
&#9;scrollDrag.Name = &quot;ScrollDrag&quot;
&#9;scrollDrag.Active = true
&#9;scrollDrag.Parent = scrollbar
&#9;
&#9;local mouseDrag = Instance.new(&quot;ImageButton&quot;)
&#9;mouseDrag.Active = false
&#9;mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0)
&#9;mouseDrag.AutoButtonColor = false
&#9;mouseDrag.BackgroundTransparency = 1
&#9;mouseDrag.Name = &quot;mouseDrag&quot;
&#9;mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0)
&#9;mouseDrag.ZIndex = 10
&#9;local style = &quot;simple&quot;
&#9;if scrollStyle and tostring(scrollStyle) then
&#9;&#9;style = scrollStyle
&#9;end
&#9;
&#9;local scrollPosition = 1
&#9;local rowSize = 0
&#9;local howManyDisplayed = 0
&#9;&#9;
&#9;local layoutGridScrollBar = function()
&#9;&#9;howManyDisplayed = 0
&#9;&#9;local guiObjects = {}
&#9;&#9;if orderList then
&#9;&#9;&#9;for i, child in ipairs(orderList) do
&#9;&#9;&#9;&#9;if child.Parent == frame then
&#9;&#9;&#9;&#9;&#9;table.insert(guiObjects, child)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;local children = frame:GetChildren()
&#9;&#9;&#9;if children then
&#9;&#9;&#9;&#9;for i, child in ipairs(children) do
&#9;&#9;&#9;&#9;&#9;if child:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;&#9;&#9;table.insert(guiObjects, child)
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;if #guiObjects == 0 then
&#9;&#9;&#9;scrollUpButton.Active = false
&#9;&#9;&#9;scrollDownButton.Active = false
&#9;&#9;&#9;scrollDrag.Active = false
&#9;&#9;&#9;scrollPosition = 1
&#9;&#9;&#9;return
&#9;&#9;end
&#9;&#9;if scrollPosition &gt; #guiObjects then
&#9;&#9;&#9;scrollPosition = #guiObjects
&#9;&#9;end
&#9;&#9;
&#9;&#9;if scrollPosition &lt; 1 then scrollPosition = 1 end
&#9;&#9;
&#9;&#9;local totalPixelsY = frame.AbsoluteSize.Y
&#9;&#9;local pixelsRemainingY = frame.AbsoluteSize.Y
&#9;&#9;
&#9;&#9;local totalPixelsX = frame.AbsoluteSize.X
&#9;&#9;
&#9;&#9;local xCounter = 0
&#9;&#9;local rowSizeCounter = 0
&#9;&#9;local setRowSize = true
&#9;&#9;local pixelsBelowScrollbar = 0
&#9;&#9;local pos = #guiObjects
&#9;&#9;
&#9;&#9;local currentRowY = 0
&#9;&#9;pos = scrollPosition
&#9;&#9;--count up from current scroll position to fill out grid
&#9;&#9;while pos &lt;= #guiObjects and pixelsBelowScrollbar &lt; totalPixelsY do
&#9;&#9;&#9;xCounter = xCounter + guiObjects[pos].AbsoluteSize.X
&#9;&#9;&#9;--previous pos was the end of a row
&#9;&#9;&#9;if xCounter &gt;= totalPixelsX then
&#9;&#9;&#9;&#9;pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
&#9;&#9;&#9;&#9;currentRowY = 0
&#9;&#9;&#9;&#9;xCounter = guiObjects[pos].AbsoluteSize.X
&#9;&#9;&#9;end
&#9;&#9;&#9;if guiObjects[pos].AbsoluteSize.Y &gt; currentRowY then
&#9;&#9;&#9;&#9;currentRowY = guiObjects[pos].AbsoluteSize.Y
&#9;&#9;&#9;end
&#9;&#9;&#9;pos = pos + 1
&#9;&#9;end
&#9;&#9;--Count wherever current row left off
&#9;&#9;pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
&#9;&#9;currentRowY = 0
&#9;&#9;
&#9;&#9;pos = scrollPosition - 1
&#9;&#9;xCounter = 0
&#9;&#9;
&#9;&#9;--objects with varying X,Y dimensions can rarely cause minor errors
&#9;&#9;--rechecking every new scrollPosition is necessary to avoid 100% of errors
&#9;&#9;
&#9;&#9;--count backwards from current scrollPosition to see if we can add more rows
&#9;&#9;while pixelsBelowScrollbar + currentRowY &lt; totalPixelsY and pos &gt;= 1 do
&#9;&#9;&#9;xCounter = xCounter + guiObjects[pos].AbsoluteSize.X
&#9;&#9;&#9;rowSizeCounter = rowSizeCounter + 1
&#9;&#9;&#9;if xCounter &gt;= totalPixelsX then
&#9;&#9;&#9;&#9;rowSize = rowSizeCounter - 1
&#9;&#9;&#9;&#9;rowSizeCounter = 0
&#9;&#9;&#9;&#9;xCounter = guiObjects[pos].AbsoluteSize.X
&#9;&#9;&#9;&#9;if pixelsBelowScrollbar + currentRowY &lt;= totalPixelsY then
&#9;&#9;&#9;&#9;&#9;--It fits, so back up our scroll position
&#9;&#9;&#9;&#9;&#9;pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
&#9;&#9;&#9;&#9;&#9;if scrollPosition &lt;= rowSize then
&#9;&#9;&#9;&#9;&#9;&#9;scrollPosition = 1
&#9;&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;scrollPosition = scrollPosition - rowSize
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;currentRowY = 0
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;
&#9;&#9;&#9;if guiObjects[pos].AbsoluteSize.Y &gt; currentRowY then
&#9;&#9;&#9;&#9;currentRowY = guiObjects[pos].AbsoluteSize.Y
&#9;&#9;&#9;end
&#9;&#9;&#9;pos = pos - 1
&#9;&#9;end
&#9;&#9;
&#9;&#9;--Do check last time if pos = 0
&#9;&#9;if (pos == 0) and (pixelsBelowScrollbar + currentRowY &lt;= totalPixelsY) then
&#9;&#9;&#9;scrollPosition = 1
&#9;&#9;end
&#9;&#9;xCounter = 0
&#9;&#9;--pos = scrollPosition
&#9;&#9;rowSizeCounter = 0
&#9;&#9;setRowSize = true
&#9;&#9;local lastChildSize = 0
&#9;&#9;
&#9;&#9;local xOffset,yOffset = 0
&#9;&#9;if guiObjects[1] then
&#9;&#9;&#9;yOffset = math.ceil(math.floor(math.fmod(totalPixelsY,guiObjects[1].AbsoluteSize.X))/2)
&#9;&#9;&#9;xOffset = math.ceil(math.floor(math.fmod(totalPixelsX,guiObjects[1].AbsoluteSize.Y))/2)
&#9;&#9;end
&#9;&#9;
&#9;&#9;for i, child in ipairs(guiObjects) do
&#9;&#9;&#9;if i &lt; scrollPosition then
&#9;&#9;&#9;&#9;--print(&quot;Hiding &quot; .. child.Name)
&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;if pixelsRemainingY &lt; 0 then
&#9;&#9;&#9;&#9;&#9;--print(&quot;Out of Space &quot; .. child.Name)
&#9;&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;--print(&quot;Laying out &quot; .. child.Name)
&#9;&#9;&#9;&#9;&#9;--GuiObject
&#9;&#9;&#9;&#9;&#9;if setRowSize then rowSizeCounter = rowSizeCounter + 1 end
&#9;&#9;&#9;&#9;&#9;if xCounter + child.AbsoluteSize.X &gt;= totalPixelsX then
&#9;&#9;&#9;&#9;&#9;&#9;if setRowSize then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;rowSize = rowSizeCounter - 1
&#9;&#9;&#9;&#9;&#9;&#9;&#9;setRowSize = false
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;&#9;xCounter = 0
&#9;&#9;&#9;&#9;&#9;&#9;pixelsRemainingY = pixelsRemainingY - child.AbsoluteSize.Y
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;child.Position = UDim2.new(child.Position.X.Scale,xCounter + xOffset, 0, totalPixelsY - pixelsRemainingY + yOffset)
&#9;&#9;&#9;&#9;&#9;xCounter = xCounter + child.AbsoluteSize.X
&#9;&#9;&#9;&#9;&#9;child.Visible = ((pixelsRemainingY - child.AbsoluteSize.Y) &gt;= 0)
&#9;&#9;&#9;&#9;&#9;if child.Visible then
&#9;&#9;&#9;&#9;&#9;&#9;howManyDisplayed = howManyDisplayed + 1
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;lastChildSize = child.AbsoluteSize&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;scrollUpButton.Active = (scrollPosition &gt; 1)
&#9;&#9;if lastChildSize == 0 then
&#9;&#9;&#9;scrollDownButton.Active = false
&#9;&#9;else
&#9;&#9;&#9;scrollDownButton.Active = ((pixelsRemainingY - lastChildSize.Y) &lt; 0)
&#9;&#9;end
&#9;&#9;scrollDrag.Active = #guiObjects &gt; howManyDisplayed
&#9;&#9;scrollDrag.Visible = scrollDrag.Active
&#9;end
&#9;local layoutSimpleScrollBar = function()
&#9;&#9;local guiObjects = {}&#9;
&#9;&#9;howManyDisplayed = 0
&#9;&#9;
&#9;&#9;if orderList then
&#9;&#9;&#9;for i, child in ipairs(orderList) do
&#9;&#9;&#9;&#9;if child.Parent == frame then
&#9;&#9;&#9;&#9;&#9;table.insert(guiObjects, child)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;local children = frame:GetChildren()
&#9;&#9;&#9;if children then
&#9;&#9;&#9;&#9;for i, child in ipairs(children) do
&#9;&#9;&#9;&#9;&#9;if child:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;&#9;&#9;table.insert(guiObjects, child)
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;if #guiObjects == 0 then
&#9;&#9;&#9;scrollUpButton.Active = false
&#9;&#9;&#9;scrollDownButton.Active = false
&#9;&#9;&#9;scrollDrag.Active = false
&#9;&#9;&#9;scrollPosition = 1
&#9;&#9;&#9;return
&#9;&#9;end
&#9;&#9;if scrollPosition &gt; #guiObjects then
&#9;&#9;&#9;scrollPosition = #guiObjects
&#9;&#9;end
&#9;&#9;
&#9;&#9;local totalPixels = frame.AbsoluteSize.Y
&#9;&#9;local pixelsRemaining = frame.AbsoluteSize.Y
&#9;&#9;local pixelsBelowScrollbar = 0
&#9;&#9;local pos = #guiObjects
&#9;&#9;while pixelsBelowScrollbar &lt; totalPixels and pos &gt;= 1 do
&#9;&#9;&#9;if pos &gt;= scrollPosition then
&#9;&#9;&#9;&#9;pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;if pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y &lt;= totalPixels then
&#9;&#9;&#9;&#9;&#9;--It fits, so back up our scroll position
&#9;&#9;&#9;&#9;&#9;pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y
&#9;&#9;&#9;&#9;&#9;if scrollPosition &lt;= 1 then
&#9;&#9;&#9;&#9;&#9;&#9;scrollPosition = 1
&#9;&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;--local (&quot;Backing up ScrollPosition from -- &quot; ..scrollPosition)
&#9;&#9;&#9;&#9;&#9;&#9;scrollPosition = scrollPosition - 1
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;pos = pos - 1
&#9;&#9;end
&#9;&#9;pos = scrollPosition
&#9;&#9;for i, child in ipairs(guiObjects) do
&#9;&#9;&#9;if i &lt; scrollPosition then
&#9;&#9;&#9;&#9;--print(&quot;Hiding &quot; .. child.Name)
&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;if pixelsRemaining &lt; 0 then
&#9;&#9;&#9;&#9;&#9;--print(&quot;Out of Space &quot; .. child.Name)
&#9;&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;--print(&quot;Laying out &quot; .. child.Name)
&#9;&#9;&#9;&#9;&#9;--GuiObject
&#9;&#9;&#9;&#9;&#9;child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
&#9;&#9;&#9;&#9;&#9;pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
&#9;&#9;&#9;&#9;&#9;if (pixelsRemaining &gt;= 0) then
&#9;&#9;&#9;&#9;&#9;&#9;child.Visible = true
&#9;&#9;&#9;&#9;&#9;&#9;howManyDisplayed = howManyDisplayed + 1
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;&#9;&#9;end&#9;&#9;
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;scrollUpButton.Active = (scrollPosition &gt; 1)
&#9;&#9;scrollDownButton.Active = (pixelsRemaining &lt; 0)
&#9;&#9;scrollDrag.Active = #guiObjects &gt; howManyDisplayed
&#9;&#9;scrollDrag.Visible = scrollDrag.Active
&#9;end
&#9;
&#9;&#9;
&#9;local moveDragger = function()&#9;
&#9;&#9;local guiObjects = 0
&#9;&#9;local children = frame:GetChildren()
&#9;&#9;if children then
&#9;&#9;&#9;for i, child in ipairs(children) do
&#9;&#9;&#9;&#9;if child:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;&#9;guiObjects = guiObjects + 1
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;
&#9;&#9;if not scrollDrag.Parent then return end
&#9;&#9;
&#9;&#9;local dragSizeY = scrollDrag.Parent.AbsoluteSize.y * (1/(guiObjects - howManyDisplayed + 1))
&#9;&#9;if dragSizeY &lt; 16 then dragSizeY = 16 end
&#9;&#9;scrollDrag.Size = UDim2.new(scrollDrag.Size.X.Scale,scrollDrag.Size.X.Offset,scrollDrag.Size.Y.Scale,dragSizeY)
&#9;&#9;local relativeYPos = (scrollPosition - 1)/(guiObjects - (howManyDisplayed))
&#9;&#9;if relativeYPos &gt; 1 then relativeYPos = 1
&#9;&#9;elseif relativeYPos &lt; 0 then relativeYPos = 0 end
&#9;&#9;local absYPos = 0
&#9;&#9;
&#9;&#9;if relativeYPos ~= 0 then
&#9;&#9;&#9;absYPos = (relativeYPos * scrollbar.AbsoluteSize.y) - (relativeYPos * scrollDrag.AbsoluteSize.y)
&#9;&#9;end
&#9;&#9;
&#9;&#9;scrollDrag.Position = UDim2.new(scrollDrag.Position.X.Scale,scrollDrag.Position.X.Offset,scrollDrag.Position.Y.Scale,absYPos)
&#9;end
&#9;local reentrancyGuard = false
&#9;local recalculate = function()
&#9;&#9;if reentrancyGuard then
&#9;&#9;&#9;return
&#9;&#9;end
&#9;&#9;reentrancyGuard = true
&#9;&#9;wait()
&#9;&#9;local success, err = nil
&#9;&#9;if style == &quot;grid&quot; then
&#9;&#9;&#9;success, err = pcall(function() layoutGridScrollBar() end)
&#9;&#9;elseif style == &quot;simple&quot; then
&#9;&#9;&#9;success, err = pcall(function() layoutSimpleScrollBar() end)
&#9;&#9;end
&#9;&#9;if not success then print(err) end
&#9;&#9;moveDragger()
&#9;&#9;reentrancyGuard = false
&#9;end
&#9;
&#9;local doScrollUp = function()
&#9;&#9;scrollPosition = (scrollPosition) - rowSize
&#9;&#9;if scrollPosition &lt; 1 then scrollPosition = 1 end
&#9;&#9;recalculate(nil)
&#9;end
&#9;
&#9;local doScrollDown = function()
&#9;&#9;scrollPosition = (scrollPosition) + rowSize
&#9;&#9;recalculate(nil)
&#9;end
&#9;local scrollUp = function(mouseYPos)
&#9;&#9;if scrollUpButton.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local current = scrollStamp
&#9;&#9;&#9;local upCon
&#9;&#9;&#9;upCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;upCon:disconnect()
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;&#9;doScrollUp()
&#9;&#9;&#9;wait(0.2)
&#9;&#9;&#9;local t = tick()
&#9;&#9;&#9;local w = 0.1
&#9;&#9;&#9;while scrollStamp == current do
&#9;&#9;&#9;&#9;doScrollUp()
&#9;&#9;&#9;&#9;if mouseYPos and mouseYPos &gt; scrollDrag.AbsolutePosition.y then
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if not scrollUpButton.Active then break end
&#9;&#9;&#9;&#9;if tick()-t &gt; 5 then
&#9;&#9;&#9;&#9;&#9;w = 0
&#9;&#9;&#9;&#9;elseif tick()-t &gt; 2 then
&#9;&#9;&#9;&#9;&#9;w = 0.06
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;wait(w)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local scrollDown = function(mouseYPos)
&#9;&#9;if scrollDownButton.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local current = scrollStamp
&#9;&#9;&#9;local downCon
&#9;&#9;&#9;downCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;downCon:disconnect()
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;&#9;doScrollDown()
&#9;&#9;&#9;wait(0.2)
&#9;&#9;&#9;local t = tick()
&#9;&#9;&#9;local w = 0.1
&#9;&#9;&#9;while scrollStamp == current do
&#9;&#9;&#9;&#9;doScrollDown()
&#9;&#9;&#9;&#9;if mouseYPos and mouseYPos &lt; (scrollDrag.AbsolutePosition.y + scrollDrag.AbsoluteSize.x) then
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if not scrollDownButton.Active then break end
&#9;&#9;&#9;&#9;if tick()-t &gt; 5 then
&#9;&#9;&#9;&#9;&#9;w = 0
&#9;&#9;&#9;&#9;elseif tick()-t &gt; 2 then
&#9;&#9;&#9;&#9;&#9;w = 0.06
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;wait(w)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;
&#9;local y = 0
&#9;scrollDrag.MouseButton1Down:connect(function(x,y)
&#9;&#9;if scrollDrag.Active then
&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;local mouseOffset = y - scrollDrag.AbsolutePosition.y
&#9;&#9;&#9;local dragCon
&#9;&#9;&#9;local upCon
&#9;&#9;&#9;dragCon = mouseDrag.MouseMoved:connect(function(x,y)
&#9;&#9;&#9;&#9;local barAbsPos = scrollbar.AbsolutePosition.y
&#9;&#9;&#9;&#9;local barAbsSize = scrollbar.AbsoluteSize.y
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local dragAbsSize = scrollDrag.AbsoluteSize.y
&#9;&#9;&#9;&#9;local barAbsOne = barAbsPos + barAbsSize - dragAbsSize
&#9;&#9;&#9;&#9;y = y - mouseOffset
&#9;&#9;&#9;&#9;y = y &lt; barAbsPos and barAbsPos or y &gt; barAbsOne and barAbsOne or y
&#9;&#9;&#9;&#9;y = y - barAbsPos
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local guiObjects = 0
&#9;&#9;&#9;&#9;local children = frame:GetChildren()
&#9;&#9;&#9;&#9;if children then
&#9;&#9;&#9;&#9;&#9;for i, child in ipairs(children) do
&#9;&#9;&#9;&#9;&#9;&#9;if child:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;guiObjects = guiObjects + 1
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local doublePercent = y/(barAbsSize-dragAbsSize)
&#9;&#9;&#9;&#9;local rowDiff = rowSize
&#9;&#9;&#9;&#9;local totalScrollCount = guiObjects - (howManyDisplayed - 1)
&#9;&#9;&#9;&#9;local newScrollPosition = math.floor((doublePercent * totalScrollCount) + 0.5) + rowDiff
&#9;&#9;&#9;&#9;if newScrollPosition &lt; scrollPosition then
&#9;&#9;&#9;&#9;&#9;rowDiff = -rowDiff
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;if newScrollPosition &lt; 1 then
&#9;&#9;&#9;&#9;&#9;newScrollPosition = 1
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;scrollPosition = newScrollPosition
&#9;&#9;&#9;&#9;recalculate(nil)
&#9;&#9;&#9;end)
&#9;&#9;&#9;upCon = mouseDrag.MouseButton1Up:connect(function()
&#9;&#9;&#9;&#9;scrollStamp = tick()
&#9;&#9;&#9;&#9;mouseDrag.Parent = nil
&#9;&#9;&#9;&#9;dragCon:disconnect(); dragCon = nil
&#9;&#9;&#9;&#9;upCon:disconnect(); drag = nil
&#9;&#9;&#9;end)
&#9;&#9;&#9;mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
&#9;&#9;end
&#9;end)
&#9;local scrollMouseCount = 0
&#9;scrollUpButton.MouseButton1Down:connect(
&#9;&#9;function()
&#9;&#9;&#9;scrollUp()
&#9;&#9;end)
&#9;scrollUpButton.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;scrollDownButton.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;scrollDownButton.MouseButton1Down:connect(
&#9;&#9;function()
&#9;&#9;&#9;scrollDown()&#9;
&#9;&#9;end)
&#9;&#9;
&#9;scrollbar.MouseButton1Up:connect(function()
&#9;&#9;scrollStamp = tick()
&#9;end)
&#9;scrollbar.MouseButton1Down:connect(
&#9;&#9;function(x,y)
&#9;&#9;&#9;if y &gt; (scrollDrag.AbsoluteSize.y + scrollDrag.AbsolutePosition.y) then
&#9;&#9;&#9;&#9;scrollDown(y)
&#9;&#9;&#9;elseif y &lt; (scrollDrag.AbsolutePosition.y) then
&#9;&#9;&#9;&#9;scrollUp(y)
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;frame.ChildAdded:connect(function()
&#9;&#9;recalculate(nil)
&#9;end)
&#9;frame.ChildRemoved:connect(function()
&#9;&#9;recalculate(nil)
&#9;end)
&#9;
&#9;frame.Changed:connect(
&#9;&#9;function(prop)
&#9;&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;&#9;--Wait a heartbeat for it to sync in
&#9;&#9;&#9;&#9;recalculate(nil)
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;frame.AncestryChanged:connect(function() recalculate(nil) end)
&#9;return frame, scrollUpButton, scrollDownButton, recalculate, scrollbar
end
local function binaryGrow(min, max, fits)
&#9;if min &gt; max then
&#9;&#9;return min
&#9;end
&#9;local biggestLegal = min
&#9;while min &lt;= max do
&#9;&#9;local mid = min + math.floor((max - min) / 2)
&#9;&#9;if fits(mid) and (biggestLegal == nil or biggestLegal &lt; mid) then
&#9;&#9;&#9;biggestLegal = mid
&#9;&#9;&#9;
&#9;&#9;&#9;--Try growing
&#9;&#9;&#9;min = mid + 1
&#9;&#9;else
&#9;&#9;&#9;--Doesn&apos;t fit, shrink
&#9;&#9;&#9;max = mid - 1
&#9;&#9;end
&#9;end
&#9;return biggestLegal
end
local function binaryShrink(min, max, fits)
&#9;if min &gt; max then
&#9;&#9;return min
&#9;end
&#9;local smallestLegal = max
&#9;while min &lt;= max do
&#9;&#9;local mid = min + math.floor((max - min) / 2)
&#9;&#9;if fits(mid) and (smallestLegal == nil or smallestLegal &gt; mid) then
&#9;&#9;&#9;smallestLegal = mid
&#9;&#9;&#9;
&#9;&#9;&#9;--It fits, shrink
&#9;&#9;&#9;max = mid - 1&#9;&#9;&#9;
&#9;&#9;else
&#9;&#9;&#9;--Doesn&apos;t fit, grow
&#9;&#9;&#9;min = mid + 1
&#9;&#9;end
&#9;end
&#9;return smallestLegal
end
local function getGuiOwner(instance)
&#9;while instance ~= nil do
&#9;&#9;if instance:IsA(&quot;ScreenGui&quot;) or instance:IsA(&quot;BillboardGui&quot;) then
&#9;&#9;&#9;return instance
&#9;&#9;end
&#9;&#9;instance = instance.Parent
&#9;end
&#9;return nil
end
t.AutoTruncateTextObject = function(textLabel)
&#9;local text = textLabel.Text
&#9;local fullLabel = textLabel:Clone()
&#9;fullLabel.Name = &quot;Full&quot; .. textLabel.Name
&#9;fullLabel.BorderSizePixel = 0
&#9;fullLabel.BackgroundTransparency = 0
&#9;fullLabel.Text = text
&#9;fullLabel.TextXAlignment = Enum.TextXAlignment.Center
&#9;fullLabel.Position = UDim2.new(0,-3,0,0)
&#9;fullLabel.Size = UDim2.new(0,100,1,0)
&#9;fullLabel.Visible = false
&#9;fullLabel.Parent = textLabel
&#9;local shortText = nil
&#9;local mouseEnterConnection = nil
&#9;local mouseLeaveConnection= nil
&#9;local checkForResize = function()
&#9;&#9;if getGuiOwner(textLabel) == nil then
&#9;&#9;&#9;return
&#9;&#9;end
&#9;&#9;textLabel.Text = text
&#9;&#9;if textLabel.TextFits then
&#9;&#9;&#9;--Tear down the rollover if it is active
&#9;&#9;&#9;if mouseEnterConnection then
&#9;&#9;&#9;&#9;mouseEnterConnection:disconnect()
&#9;&#9;&#9;&#9;mouseEnterConnection = nil
&#9;&#9;&#9;end
&#9;&#9;&#9;if mouseLeaveConnection then
&#9;&#9;&#9;&#9;mouseLeaveConnection:disconnect()
&#9;&#9;&#9;&#9;mouseLeaveConnection = nil
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;local len = string.len(text)
&#9;&#9;&#9;textLabel.Text = text .. &quot;~&quot;
&#9;&#9;&#9;--Shrink the text
&#9;&#9;&#9;local textSize = binaryGrow(0, len,
&#9;&#9;&#9;&#9;function(pos)
&#9;&#9;&#9;&#9;&#9;if pos == 0 then
&#9;&#9;&#9;&#9;&#9;&#9;textLabel.Text = &quot;~&quot;
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;textLabel.Text = string.sub(text, 1, pos) .. &quot;~&quot;
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;return textLabel.TextFits
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;shortText = string.sub(text, 1, textSize) .. &quot;~&quot;
&#9;&#9;&#9;textLabel.Text = shortText
&#9;&#9;&#9;
&#9;&#9;&#9;--Make sure the fullLabel fits
&#9;&#9;&#9;if not fullLabel.TextFits then
&#9;&#9;&#9;&#9;--Already too small, grow it really bit to start
&#9;&#9;&#9;&#9;fullLabel.Size = UDim2.new(0, 10000, 1, 0)
&#9;&#9;&#9;end
&#9;&#9;&#9;
&#9;&#9;&#9;--Okay, now try to binary shrink it back down
&#9;&#9;&#9;local fullLabelSize = binaryShrink(textLabel.AbsoluteSize.X,fullLabel.AbsoluteSize.X,
&#9;&#9;&#9;&#9;function(size)
&#9;&#9;&#9;&#9;&#9;fullLabel.Size = UDim2.new(0, size, 1, 0)
&#9;&#9;&#9;&#9;&#9;return fullLabel.TextFits
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;fullLabel.Size = UDim2.new(0,fullLabelSize+6,1,0)
&#9;&#9;&#9;--Now setup the rollover effects, if they are currently off
&#9;&#9;&#9;if mouseEnterConnection == nil then
&#9;&#9;&#9;&#9;mouseEnterConnection = textLabel.MouseEnter:connect(
&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;&#9;fullLabel.ZIndex = textLabel.ZIndex + 1
&#9;&#9;&#9;&#9;&#9;&#9;fullLabel.Visible = true
&#9;&#9;&#9;&#9;&#9;&#9;--textLabel.Text = &quot;&quot;
&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;&#9;if mouseLeaveConnection == nil then
&#9;&#9;&#9;&#9;mouseLeaveConnection = textLabel.MouseLeave:connect(
&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;&#9;fullLabel.Visible = false
&#9;&#9;&#9;&#9;&#9;&#9;--textLabel.Text = shortText
&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;textLabel.AncestryChanged:connect(checkForResize)
&#9;textLabel.Changed:connect(
&#9;&#9;function(prop)
&#9;&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;&#9;checkForResize() &#9;
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;checkForResize()
&#9;local function changeText(newText)
&#9;&#9;text = newText
&#9;&#9;fullLabel.Text = text
&#9;&#9;checkForResize()
&#9;end
&#9;return textLabel, changeText
end
local function TransitionTutorialPages(fromPage, toPage, transitionFrame, currentPageValue)&#9;
&#9;if fromPage then
&#9;&#9;fromPage.Visible = false
&#9;&#9;if transitionFrame.Visible == false then
&#9;&#9;&#9;transitionFrame.Size = fromPage.Size
&#9;&#9;&#9;transitionFrame.Position = fromPage.Position
&#9;&#9;end
&#9;else
&#9;&#9;if transitionFrame.Visible == false then
&#9;&#9;&#9;transitionFrame.Size = UDim2.new(0.0,50,0.0,50)
&#9;&#9;&#9;transitionFrame.Position = UDim2.new(0.5,-25,0.5,-25)
&#9;&#9;end
&#9;end
&#9;transitionFrame.Visible = true
&#9;currentPageValue.Value = nil
&#9;local newsize, newPosition
&#9;if toPage then
&#9;&#9;--Make it visible so it resizes
&#9;&#9;toPage.Visible = true
&#9;&#9;newSize = toPage.Size
&#9;&#9;newPosition = toPage.Position
&#9;&#9;toPage.Visible = false
&#9;else
&#9;&#9;newSize = UDim2.new(0.0,50,0.0,50)
&#9;&#9;newPosition = UDim2.new(0.5,-25,0.5,-25)
&#9;end
&#9;transitionFrame:TweenSizeAndPosition(newSize, newPosition, Enum.EasingDirection.InOut, Enum.EasingStyle.Quad, 0.3, true,
&#9;&#9;function(state)
&#9;&#9;&#9;if state == Enum.TweenStatus.Completed then
&#9;&#9;&#9;&#9;transitionFrame.Visible = false
&#9;&#9;&#9;&#9;if toPage then
&#9;&#9;&#9;&#9;&#9;toPage.Visible = true
&#9;&#9;&#9;&#9;&#9;currentPageValue.Value = toPage
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end)
end
t.CreateTutorial = function(name, tutorialKey, createButtons)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Name = &quot;Tutorial-&quot; .. name
&#9;frame.BackgroundTransparency = 1
&#9;frame.Size = UDim2.new(0.6, 0, 0.6, 0)
&#9;frame.Position = UDim2.new(0.2, 0, 0.2, 0)
&#9;local transitionFrame = Instance.new(&quot;Frame&quot;)
&#9;transitionFrame.Name = &quot;TransitionFrame&quot;
&#9;transitionFrame.Style = Enum.FrameStyle.RobloxRound
&#9;transitionFrame.Size = UDim2.new(0.6, 0, 0.6, 0)
&#9;transitionFrame.Position = UDim2.new(0.2, 0, 0.2, 0)
&#9;transitionFrame.Visible = false
&#9;transitionFrame.Parent = frame
&#9;local currentPageValue = Instance.new(&quot;ObjectValue&quot;)
&#9;currentPageValue.Name = &quot;CurrentTutorialPage&quot;
&#9;currentPageValue.Value = nil
&#9;currentPageValue.Parent = frame
&#9;local boolValue = Instance.new(&quot;BoolValue&quot;)
&#9;boolValue.Name = &quot;Buttons&quot;
&#9;boolValue.Value = createButtons
&#9;boolValue.Parent = frame
&#9;local pages = Instance.new(&quot;Frame&quot;)
&#9;pages.Name = &quot;Pages&quot;
&#9;pages.BackgroundTransparency = 1
&#9;pages.Size = UDim2.new(1,0,1,0)
&#9;pages.Parent = frame
&#9;local function getVisiblePageAndHideOthers()
&#9;&#9;local visiblePage = nil
&#9;&#9;local children = pages:GetChildren()
&#9;&#9;if children then
&#9;&#9;&#9;for i,child in ipairs(children) do
&#9;&#9;&#9;&#9;if child.Visible then
&#9;&#9;&#9;&#9;&#9;if visiblePage then
&#9;&#9;&#9;&#9;&#9;&#9;child.Visible = false
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;visiblePage = child
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;return visiblePage
&#9;end
&#9;local showTutorial = function(alwaysShow)
&#9;&#9;if alwaysShow or UserSettings().GameSettings:GetTutorialState(tutorialKey) == false then
&#9;&#9;&#9;print(&quot;Showing tutorial-&quot;,tutorialKey)
&#9;&#9;&#9;local currentTutorialPage = getVisiblePageAndHideOthers()
&#9;&#9;&#9;local firstPage = pages:FindFirstChild(&quot;TutorialPage1&quot;)
&#9;&#9;&#9;if firstPage then
&#9;&#9;&#9;&#9;TransitionTutorialPages(currentTutorialPage, firstPage, transitionFrame, currentPageValue)&#9;
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;error(&quot;Could not find TutorialPage1&quot;)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local dismissTutorial = function()
&#9;&#9;local currentTutorialPage = getVisiblePageAndHideOthers()
&#9;&#9;if currentTutorialPage then
&#9;&#9;&#9;TransitionTutorialPages(currentTutorialPage, nil, transitionFrame, currentPageValue)
&#9;&#9;end
&#9;&#9;UserSettings().GameSettings:SetTutorialState(tutorialKey, true)
&#9;end
&#9;local gotoPage = function(pageNum)
&#9;&#9;local page = pages:FindFirstChild(&quot;TutorialPage&quot; .. pageNum)
&#9;&#9;local currentTutorialPage = getVisiblePageAndHideOthers()
&#9;&#9;TransitionTutorialPages(currentTutorialPage, page, transitionFrame, currentPageValue)
&#9;end
&#9;return frame, showTutorial, dismissTutorial, gotoPage
end
local function CreateBasicTutorialPage(name, handleResize, skipTutorial, giveDoneButton)
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Name = &quot;TutorialPage&quot;
&#9;frame.Style = Enum.FrameStyle.RobloxRound
&#9;frame.Size = UDim2.new(0.6, 0, 0.6, 0)
&#9;frame.Position = UDim2.new(0.2, 0, 0.2, 0)
&#9;frame.Visible = false
&#9;
&#9;local frameHeader = Instance.new(&quot;TextLabel&quot;)
&#9;frameHeader.Name = &quot;Header&quot;
&#9;frameHeader.Text = name
&#9;frameHeader.BackgroundTransparency = 1
&#9;frameHeader.FontSize = Enum.FontSize.Size24
&#9;frameHeader.Font = Enum.Font.ArialBold
&#9;frameHeader.TextColor3 = Color3.new(1,1,1)
&#9;frameHeader.TextXAlignment = Enum.TextXAlignment.Center
&#9;frameHeader.TextWrap = true
&#9;frameHeader.Size = UDim2.new(1,-55, 0, 22)
&#9;frameHeader.Position = UDim2.new(0,0,0,0)
&#9;frameHeader.Parent = frame
&#9;local skipButton = Instance.new(&quot;ImageButton&quot;)
&#9;skipButton.Name = &quot;SkipButton&quot;
&#9;skipButton.AutoButtonColor = false
&#9;skipButton.BackgroundTransparency = 1
&#9;skipButton.Image = &quot;rbxasset://textures/ui/closeButton.png&quot;
&#9;skipButton.MouseButton1Click:connect(function()
&#9;&#9;skipTutorial()
&#9;end)
&#9;skipButton.MouseEnter:connect(function()
&#9;&#9;skipButton.Image = &quot;rbxasset://textures/ui/closeButton_dn.png&quot;
&#9;end)
&#9;skipButton.MouseLeave:connect(function()
&#9;&#9;skipButton.Image = &quot;rbxasset://textures/ui/closeButton.png&quot;
&#9;end)
&#9;skipButton.Size = UDim2.new(0, 25, 0, 25)
&#9;skipButton.Position = UDim2.new(1, -25, 0, 0)
&#9;skipButton.Parent = frame
&#9;
&#9;
&#9;if giveDoneButton then
&#9;&#9;local doneButton = Instance.new(&quot;TextButton&quot;)
&#9;&#9;doneButton.Name = &quot;DoneButton&quot;
&#9;&#9;doneButton.Style = Enum.ButtonStyle.RobloxButtonDefault
&#9;&#9;doneButton.Text = &quot;Done&quot;
&#9;&#9;doneButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;doneButton.Font = Enum.Font.ArialBold
&#9;&#9;doneButton.FontSize = Enum.FontSize.Size18
&#9;&#9;doneButton.Size = UDim2.new(0,100,0,50)
&#9;&#9;doneButton.Position = UDim2.new(0.5,-50,1,-50)
&#9;&#9;
&#9;&#9;if skipTutorial then
&#9;&#9;&#9;doneButton.MouseButton1Click:connect(function() skipTutorial() end)
&#9;&#9;end
&#9;&#9;
&#9;&#9;doneButton.Parent = frame
&#9;end
&#9;local innerFrame = Instance.new(&quot;Frame&quot;)
&#9;innerFrame.Name = &quot;ContentFrame&quot;
&#9;innerFrame.BackgroundTransparency = 1
&#9;innerFrame.Position = UDim2.new(0,0,0,25)
&#9;innerFrame.Parent = frame
&#9;local nextButton = Instance.new(&quot;TextButton&quot;)
&#9;nextButton.Name = &quot;NextButton&quot;
&#9;nextButton.Text = &quot;Next&quot;
&#9;nextButton.TextColor3 = Color3.new(1,1,1)
&#9;nextButton.Font = Enum.Font.Arial
&#9;nextButton.FontSize = Enum.FontSize.Size18
&#9;nextButton.Style = Enum.ButtonStyle.RobloxButtonDefault
&#9;nextButton.Size = UDim2.new(0,80, 0, 32)
&#9;nextButton.Position = UDim2.new(0.5, 5, 1, -32)
&#9;nextButton.Active = false
&#9;nextButton.Visible = false
&#9;nextButton.Parent = frame
&#9;local prevButton = Instance.new(&quot;TextButton&quot;)
&#9;prevButton.Name = &quot;PrevButton&quot;
&#9;prevButton.Text = &quot;Previous&quot;
&#9;prevButton.TextColor3 = Color3.new(1,1,1)
&#9;prevButton.Font = Enum.Font.Arial
&#9;prevButton.FontSize = Enum.FontSize.Size18
&#9;prevButton.Style = Enum.ButtonStyle.RobloxButton
&#9;prevButton.Size = UDim2.new(0,80, 0, 32)
&#9;prevButton.Position = UDim2.new(0.5, -85, 1, -32)
&#9;prevButton.Active = false
&#9;prevButton.Visible = false
&#9;prevButton.Parent = frame
&#9;if giveDoneButton then
&#9;&#9;innerFrame.Size = UDim2.new(1,0,1,-75)
&#9;else
&#9;&#9;innerFrame.Size = UDim2.new(1,0,1,-22)
&#9;end
&#9;local parentConnection = nil
&#9;local function basicHandleResize()
&#9;&#9;if frame.Visible and frame.Parent then
&#9;&#9;&#9;local maxSize = math.min(frame.Parent.AbsoluteSize.X, frame.Parent.AbsoluteSize.Y)
&#9;&#9;&#9;handleResize(200,maxSize)
&#9;&#9;end
&#9;end
&#9;frame.Changed:connect(
&#9;&#9;function(prop)
&#9;&#9;&#9;if prop == &quot;Parent&quot; then
&#9;&#9;&#9;&#9;if parentConnection ~= nil then
&#9;&#9;&#9;&#9;&#9;parentConnection:disconnect()
&#9;&#9;&#9;&#9;&#9;parentConnection = nil
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if frame.Parent and frame.Parent:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;&#9;parentConnection = frame.Parent.Changed:connect(
&#9;&#9;&#9;&#9;&#9;&#9;function(parentProp)
&#9;&#9;&#9;&#9;&#9;&#9;&#9;if parentProp == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;wait()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;basicHandleResize()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;&#9;&#9;basicHandleResize()
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;if prop == &quot;Visible&quot; then
&#9;&#9;&#9;&#9;basicHandleResize()
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;return frame, innerFrame
end
t.CreateTextTutorialPage = function(name, text, skipTutorialFunc)
&#9;local frame = nil
&#9;local contentFrame = nil
&#9;local textLabel = Instance.new(&quot;TextLabel&quot;)
&#9;textLabel.BackgroundTransparency = 1
&#9;textLabel.TextColor3 = Color3.new(1,1,1)
&#9;textLabel.Text = text
&#9;textLabel.TextWrap = true
&#9;textLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;textLabel.TextYAlignment = Enum.TextYAlignment.Center
&#9;textLabel.Font = Enum.Font.Arial
&#9;textLabel.FontSize = Enum.FontSize.Size14
&#9;textLabel.Size = UDim2.new(1,0,1,0)
&#9;local function handleResize(minSize, maxSize)
&#9;&#9;size = binaryShrink(minSize, maxSize,
&#9;&#9;&#9;function(size)
&#9;&#9;&#9;&#9;frame.Size = UDim2.new(0, size, 0, size)
&#9;&#9;&#9;&#9;return textLabel.TextFits
&#9;&#9;&#9;end)
&#9;&#9;frame.Size = UDim2.new(0, size, 0, size)
&#9;&#9;frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2)
&#9;end
&#9;frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc)
&#9;textLabel.Parent = contentFrame
&#9;return frame
end
t.CreateImageTutorialPage = function(name, imageAsset, x, y, skipTutorialFunc, giveDoneButton)
&#9;local frame = nil
&#9;local contentFrame = nil
&#9;local imageLabel = Instance.new(&quot;ImageLabel&quot;)
&#9;imageLabel.BackgroundTransparency = 1
&#9;imageLabel.Image = imageAsset
&#9;imageLabel.Size = UDim2.new(0,x,0,y)
&#9;imageLabel.Position = UDim2.new(0.5,-x/2,0.5,-y/2)
&#9;local function handleResize(minSize, maxSize)
&#9;&#9;size = binaryShrink(minSize, maxSize,
&#9;&#9;&#9;function(size)
&#9;&#9;&#9;&#9;return size &gt;= x and size &gt;= y
&#9;&#9;&#9;end)
&#9;&#9;if size &gt;= x and size &gt;= y then
&#9;&#9;&#9;imageLabel.Size = UDim2.new(0,x, 0,y)
&#9;&#9;&#9;imageLabel.Position = UDim2.new(0.5,-x/2, 0.5, -y/2)
&#9;&#9;else
&#9;&#9;&#9;if x &gt; y then
&#9;&#9;&#9;&#9;--X is limiter, so
&#9;&#9;&#9;&#9;imageLabel.Size = UDim2.new(1,0,y/x,0)
&#9;&#9;&#9;&#9;imageLabel.Position = UDim2.new(0,0, 0.5 - (y/x)/2, 0)
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;--Y is limiter
&#9;&#9;&#9;&#9;imageLabel.Size = UDim2.new(x/y,0,1, 0)
&#9;&#9;&#9;&#9;imageLabel.Position = UDim2.new(0.5-(x/y)/2, 0, 0, 0)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;size = size + 50
&#9;&#9;frame.Size = UDim2.new(0, size, 0, size)
&#9;&#9;frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2)
&#9;end
&#9;frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc, giveDoneButton)
&#9;imageLabel.Parent = contentFrame
&#9;return frame
end
t.AddTutorialPage = function(tutorial, tutorialPage)
&#9;local transitionFrame = tutorial.TransitionFrame
&#9;local currentPageValue = tutorial.CurrentTutorialPage
&#9;if not tutorial.Buttons.Value then
&#9;&#9;tutorialPage.NextButton.Parent = nil
&#9;&#9;tutorialPage.PrevButton.Parent = nil
&#9;end
&#9;local children = tutorial.Pages:GetChildren()
&#9;if children and #children &gt; 0 then
&#9;&#9;tutorialPage.Name = &quot;TutorialPage&quot; .. (#children+1)
&#9;&#9;local previousPage = children[#children]
&#9;&#9;if not previousPage:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;error(&quot;All elements under Pages must be GuiObjects&quot;)
&#9;&#9;end
&#9;&#9;if tutorial.Buttons.Value then
&#9;&#9;&#9;if previousPage.NextButton.Active then
&#9;&#9;&#9;&#9;error(&quot;NextButton already Active on previousPage, please only add pages with RbxGui.AddTutorialPage function&quot;)
&#9;&#9;&#9;end
&#9;&#9;&#9;previousPage.NextButton.MouseButton1Click:connect(
&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;TransitionTutorialPages(previousPage, tutorialPage, transitionFrame, currentPageValue)
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;previousPage.NextButton.Active = true
&#9;&#9;&#9;previousPage.NextButton.Visible = true
&#9;&#9;&#9;if tutorialPage.PrevButton.Active then
&#9;&#9;&#9;&#9;error(&quot;PrevButton already Active on tutorialPage, please only add pages with RbxGui.AddTutorialPage function&quot;)
&#9;&#9;&#9;end
&#9;&#9;&#9;tutorialPage.PrevButton.MouseButton1Click:connect(
&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;TransitionTutorialPages(tutorialPage, previousPage, transitionFrame, currentPageValue)
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;tutorialPage.PrevButton.Active = true
&#9;&#9;&#9;tutorialPage.PrevButton.Visible = true
&#9;&#9;end
&#9;&#9;tutorialPage.Parent = tutorial.Pages
&#9;else
&#9;&#9;--First child
&#9;&#9;tutorialPage.Name = &quot;TutorialPage1&quot;
&#9;&#9;tutorialPage.Parent = tutorial.Pages
&#9;end
end
t.CreateSetPanel = function(userIdsForSets, objectSelected, dialogClosed, size, position, showAdminCategories, useAssetVersionId)
&#9;if not userIdsForSets then
&#9;&#9;error(&quot;CreateSetPanel: userIdsForSets (first arg) is nil, should be a table of number ids&quot;)
&#9;end
&#9;if type(userIdsForSets) ~= &quot;table&quot; and type(userIdsForSets) ~= &quot;userdata&quot; then
&#9;&#9;error(&quot;CreateSetPanel: userIdsForSets (first arg) is of type &quot; ..type(userIdsForSets) .. &quot;, should be of type table or userdata&quot;)
&#9;end
&#9;if not objectSelected then
&#9;&#9;error(&quot;CreateSetPanel: objectSelected (second arg) is nil, should be a callback function!&quot;)
&#9;end
&#9;if type(objectSelected) ~= &quot;function&quot; then
&#9;&#9;error(&quot;CreateSetPanel: objectSelected (second arg) is of type &quot; .. type(objectSelected) .. &quot;, should be of type function!&quot;)
&#9;end
&#9;if dialogClosed and type(dialogClosed) ~= &quot;function&quot; then
&#9;&#9;error(&quot;CreateSetPanel: dialogClosed (third arg) is of type &quot; .. type(dialogClosed) .. &quot;, should be of type function!&quot;)
&#9;end
&#9;
&#9;if showAdminCategories == nil then -- by default, don&apos;t show beta sets
&#9;&#9;showAdminCategories = false
&#9;end
&#9;local arrayPosition = 1
&#9;local insertButtons = {}
&#9;local insertButtonCons = {}
&#9;local contents = nil
&#9;local setGui = nil
&#9;-- used for water selections
&#9;local waterForceDirection = &quot;NegX&quot;
&#9;local waterForce = &quot;None&quot;
&#9;local waterGui, waterTypeChangedEvent = nil
&#9;
&#9;local Data = {}
&#9;Data.CurrentCategory = nil
&#9;Data.Category = {}
&#9;local SetCache = {}
&#9;
&#9;local userCategoryButtons = nil
&#9;
&#9;local buttonWidth = 64
&#9;local buttonHeight = buttonWidth
&#9;
&#9;local SmallThumbnailUrl = nil
&#9;local LargeThumbnailUrl = nil
&#9;local BaseUrl = game:GetService(&quot;ContentProvider&quot;).BaseUrl:lower()
&#9;
&#9;if useAssetVersionId then
&#9;&#9;LargeThumbnailUrl = BaseUrl .. &quot;Game/Tools/ThumbnailAsset.ashx?fmt=png&amp;wd=420&amp;ht=420&amp;assetversionid=&quot;
&#9;&#9;SmallThumbnailUrl = BaseUrl .. &quot;Game/Tools/ThumbnailAsset.ashx?fmt=png&amp;wd=75&amp;ht=75&amp;assetversionid=&quot;
&#9;else
&#9;&#9;LargeThumbnailUrl = BaseUrl .. &quot;Game/Tools/ThumbnailAsset.ashx?fmt=png&amp;wd=420&amp;ht=420&amp;aid=&quot;
&#9;&#9;SmallThumbnailUrl = BaseUrl .. &quot;Game/Tools/ThumbnailAsset.ashx?fmt=png&amp;wd=75&amp;ht=75&amp;aid=&quot;
&#9;end
&#9;&#9;
&#9;local function drillDownSetZIndex(parent, index)
&#9;&#9;local children = parent:GetChildren()
&#9;&#9;for i = 1, #children do
&#9;&#9;&#9;if children[i]:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;children[i].ZIndex = index
&#9;&#9;&#9;end
&#9;&#9;&#9;drillDownSetZIndex(children[i], index)
&#9;&#9;end
&#9;end
&#9;
&#9;-- for terrain stamping
&#9;local currTerrainDropDownFrame = nil
&#9;local terrainShapes = {&quot;Block&quot;,&quot;Vertical Ramp&quot;,&quot;Corner Wedge&quot;,&quot;Inverse Corner Wedge&quot;,&quot;Horizontal Ramp&quot;,&quot;Auto-Wedge&quot;}
&#9;local terrainShapeMap = {}
&#9;for i = 1, #terrainShapes do
&#9;&#9;terrainShapeMap[terrainShapes[i]] = i - 1
&#9;end&#9;
&#9;terrainShapeMap[terrainShapes[#terrainShapes]] = 6
&#9;local function createWaterGui()
&#9;&#9;local waterForceDirections = {&quot;NegX&quot;,&quot;X&quot;,&quot;NegY&quot;,&quot;Y&quot;,&quot;NegZ&quot;,&quot;Z&quot;}
&#9;&#9;local waterForces = {&quot;None&quot;, &quot;Small&quot;, &quot;Medium&quot;, &quot;Strong&quot;, &quot;Max&quot;}
&#9;&#9;local waterFrame = Instance.new(&quot;Frame&quot;)
&#9;&#9;waterFrame.Name = &quot;WaterFrame&quot;
&#9;&#9;waterFrame.Style = Enum.FrameStyle.RobloxSquare
&#9;&#9;waterFrame.Size = UDim2.new(0,150,0,110)
&#9;&#9;waterFrame.Visible = false
&#9;&#9;local waterForceLabel = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;waterForceLabel.Name = &quot;WaterForceLabel&quot;
&#9;&#9;waterForceLabel.BackgroundTransparency = 1
&#9;&#9;waterForceLabel.Size = UDim2.new(1,0,0,12)
&#9;&#9;waterForceLabel.Font = Enum.Font.ArialBold
&#9;&#9;waterForceLabel.FontSize = Enum.FontSize.Size12
&#9;&#9;waterForceLabel.TextColor3 = Color3.new(1,1,1)
&#9;&#9;waterForceLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;waterForceLabel.Text = &quot;Water Force&quot;
&#9;&#9;waterForceLabel.Parent = waterFrame
&#9;&#9;local waterForceDirLabel = waterForceLabel:Clone()
&#9;&#9;waterForceDirLabel.Name = &quot;WaterForceDirectionLabel&quot;
&#9;&#9;waterForceDirLabel.Text = &quot;Water Force Direction&quot;
&#9;&#9;waterForceDirLabel.Position = UDim2.new(0,0,0,50)
&#9;&#9;waterForceDirLabel.Parent = waterFrame
&#9;&#9;local waterTypeChangedEvent = Instance.new(&quot;BindableEvent&quot;,waterFrame)
&#9;&#9;waterTypeChangedEvent.Name = &quot;WaterTypeChangedEvent&quot;
&#9;&#9;local waterForceDirectionSelectedFunc = function(newForceDirection)
&#9;&#9;&#9;waterForceDirection = newForceDirection
&#9;&#9;&#9;waterTypeChangedEvent:Fire({waterForce, waterForceDirection})
&#9;&#9;end
&#9;&#9;local waterForceSelectedFunc = function(newForce)
&#9;&#9;&#9;waterForce = newForce
&#9;&#9;&#9;waterTypeChangedEvent:Fire({waterForce, waterForceDirection})
&#9;&#9;end
&#9;&#9;local waterForceDirectionDropDown, forceWaterDirectionSelection = t.CreateDropDownMenu(waterForceDirections, waterForceDirectionSelectedFunc)
&#9;&#9;waterForceDirectionDropDown.Size = UDim2.new(1,0,0,25)
&#9;&#9;waterForceDirectionDropDown.Position = UDim2.new(0,0,1,3)
&#9;&#9;forceWaterDirectionSelection(&quot;NegX&quot;)
&#9;&#9;waterForceDirectionDropDown.Parent = waterForceDirLabel
&#9;&#9;local waterForceDropDown, forceWaterForceSelection = t.CreateDropDownMenu(waterForces, waterForceSelectedFunc)
&#9;&#9;forceWaterForceSelection(&quot;None&quot;)
&#9;&#9;waterForceDropDown.Size = UDim2.new(1,0,0,25)
&#9;&#9;waterForceDropDown.Position = UDim2.new(0,0,1,3)
&#9;&#9;waterForceDropDown.Parent = waterForceLabel
&#9;&#9;return waterFrame, waterTypeChangedEvent
&#9;end
&#9;-- Helper Function that contructs gui elements
&#9;local function createSetGui()
&#9;
&#9;&#9;local setGui = Instance.new(&quot;ScreenGui&quot;)
&#9;&#9;setGui.Name = &quot;SetGui&quot;
&#9;&#9;
&#9;&#9;local setPanel = Instance.new(&quot;Frame&quot;)
&#9;&#9;setPanel.Name = &quot;SetPanel&quot;
&#9;&#9;setPanel.Active = true
&#9;&#9;setPanel.BackgroundTransparency = 1
&#9;&#9;if position then
&#9;&#9;&#9;setPanel.Position = position
&#9;&#9;else
&#9;&#9;&#9;setPanel.Position = UDim2.new(0.2, 29, 0.1, 24)
&#9;&#9;end
&#9;&#9;if size then
&#9;&#9;&#9;setPanel.Size = size
&#9;&#9;else
&#9;&#9;&#9;setPanel.Size = UDim2.new(0.6, -58, 0.64, 0)
&#9;&#9;end
&#9;&#9;setPanel.Style = Enum.FrameStyle.RobloxRound
&#9;&#9;setPanel.ZIndex = 6
&#9;&#9;setPanel.Parent = setGui
&#9;&#9;
&#9;&#9;&#9;-- Children of SetPanel
&#9;&#9;&#9;local itemPreview = Instance.new(&quot;Frame&quot;)
&#9;&#9;&#9;itemPreview.Name = &quot;ItemPreview&quot;
&#9;&#9;&#9;itemPreview.BackgroundTransparency = 1
&#9;&#9;&#9;itemPreview.Position = UDim2.new(0.8,5,0.085,0)
&#9;&#9;&#9;itemPreview.Size = UDim2.new(0.21,0,0.9,0)
&#9;&#9;&#9;itemPreview.ZIndex = 6
&#9;&#9;&#9;itemPreview.Parent = setPanel
&#9;&#9;&#9;
&#9;&#9;&#9;&#9;-- Children of ItemPreview
&#9;&#9;&#9;&#9;local textPanel = Instance.new(&quot;Frame&quot;)
&#9;&#9;&#9;&#9;textPanel.Name = &quot;TextPanel&quot;
&#9;&#9;&#9;&#9;textPanel.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;textPanel.Position = UDim2.new(0,0,0.45,0)
&#9;&#9;&#9;&#9;textPanel.Size = UDim2.new(1,0,0.55,0)
&#9;&#9;&#9;&#9;textPanel.ZIndex = 6
&#9;&#9;&#9;&#9;textPanel.Parent = itemPreview
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;-- Children of TextPanel
&#9;&#9;&#9;&#9;&#9;local rolloverText = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;&#9;&#9;&#9;rolloverText.Name = &quot;RolloverText&quot;
&#9;&#9;&#9;&#9;&#9;rolloverText.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;&#9;rolloverText.Size = UDim2.new(1,0,0,48)
&#9;&#9;&#9;&#9;&#9;rolloverText.ZIndex = 6
&#9;&#9;&#9;&#9;&#9;rolloverText.Font = Enum.Font.ArialBold
&#9;&#9;&#9;&#9;&#9;rolloverText.FontSize = Enum.FontSize.Size24
&#9;&#9;&#9;&#9;&#9;rolloverText.Text = &quot;&quot;
&#9;&#9;&#9;&#9;&#9;rolloverText.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;&#9;rolloverText.TextWrap = true
&#9;&#9;&#9;&#9;&#9;rolloverText.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;&#9;&#9;&#9;rolloverText.TextYAlignment = Enum.TextYAlignment.Top
&#9;&#9;&#9;&#9;&#9;rolloverText.Parent = textPanel
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local largePreview = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;&#9;&#9;largePreview.Name = &quot;LargePreview&quot;
&#9;&#9;&#9;&#9;largePreview.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;largePreview.Image = &quot;&quot;
&#9;&#9;&#9;&#9;largePreview.Size = UDim2.new(1,0,0,170)
&#9;&#9;&#9;&#9;largePreview.ZIndex = 6
&#9;&#9;&#9;&#9;largePreview.Parent = itemPreview
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;local sets = Instance.new(&quot;Frame&quot;)
&#9;&#9;&#9;sets.Name = &quot;Sets&quot;
&#9;&#9;&#9;sets.BackgroundTransparency = 1
&#9;&#9;&#9;sets.Position = UDim2.new(0,0,0,5)
&#9;&#9;&#9;sets.Size = UDim2.new(0.23,0,1,-5)
&#9;&#9;&#9;sets.ZIndex = 6
&#9;&#9;&#9;sets.Parent = setPanel
&#9;&#9;&#9;
&#9;&#9;&#9;&#9;-- Children of Sets
&#9;&#9;&#9;&#9;local line = Instance.new(&quot;Frame&quot;)
&#9;&#9;&#9;&#9;line.Name = &quot;Line&quot;
&#9;&#9;&#9;&#9;line.BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;line.BackgroundTransparency = 0.7
&#9;&#9;&#9;&#9;line.BorderSizePixel = 0
&#9;&#9;&#9;&#9;line.Position = UDim2.new(1,-3,0.06,0)
&#9;&#9;&#9;&#9;line.Size = UDim2.new(0,3,0.9,0)
&#9;&#9;&#9;&#9;line.ZIndex = 6
&#9;&#9;&#9;&#9;line.Parent = sets
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local setsLists, controlFrame = t.CreateTrueScrollingFrame()
&#9;&#9;&#9;&#9;setsLists.Size = UDim2.new(1,-6,0.94,0)
&#9;&#9;&#9;&#9;setsLists.Position = UDim2.new(0,0,0.06,0)
&#9;&#9;&#9;&#9;setsLists.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;setsLists.Name = &quot;SetsLists&quot;
&#9;&#9;&#9;&#9;setsLists.ZIndex = 6
&#9;&#9;&#9;&#9;setsLists.Parent = sets
&#9;&#9;&#9;&#9;drillDownSetZIndex(controlFrame, 7)
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local setsHeader = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;&#9;&#9;setsHeader.Name = &quot;SetsHeader&quot;
&#9;&#9;&#9;&#9;setsHeader.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;setsHeader.Size = UDim2.new(0,47,0,24)
&#9;&#9;&#9;&#9;setsHeader.ZIndex = 6
&#9;&#9;&#9;&#9;setsHeader.Font = Enum.Font.ArialBold
&#9;&#9;&#9;&#9;setsHeader.FontSize = Enum.FontSize.Size24
&#9;&#9;&#9;&#9;setsHeader.Text = &quot;Sets&quot;
&#9;&#9;&#9;&#9;setsHeader.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;setsHeader.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;&#9;&#9;setsHeader.TextYAlignment = Enum.TextYAlignment.Top
&#9;&#9;&#9;&#9;setsHeader.Parent = sets
&#9;&#9;&#9;
&#9;&#9;&#9;local cancelButton = Instance.new(&quot;TextButton&quot;)
&#9;&#9;&#9;cancelButton.Name = &quot;CancelButton&quot;
&#9;&#9;&#9;cancelButton.Position = UDim2.new(1,-32,0,-2)
&#9;&#9;&#9;cancelButton.Size = UDim2.new(0,34,0,34)
&#9;&#9;&#9;cancelButton.Style = Enum.ButtonStyle.RobloxButtonDefault
&#9;&#9;&#9;cancelButton.ZIndex = 6
&#9;&#9;&#9;cancelButton.Text = &quot;&quot;
&#9;&#9;&#9;cancelButton.Modal = true
&#9;&#9;&#9;cancelButton.Parent = setPanel
&#9;&#9;&#9;
&#9;&#9;&#9;&#9;-- Children of Cancel Button
&#9;&#9;&#9;&#9;local cancelImage = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;&#9;&#9;cancelImage.Name = &quot;CancelImage&quot;
&#9;&#9;&#9;&#9;cancelImage.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;cancelImage.Image = &quot;http://www.roblox.com/asset/?id=54135717&quot;
&#9;&#9;&#9;&#9;cancelImage.Position = UDim2.new(0,-2,0,-2)
&#9;&#9;&#9;&#9;cancelImage.Size = UDim2.new(0,16,0,16)
&#9;&#9;&#9;&#9;cancelImage.ZIndex = 6
&#9;&#9;&#9;&#9;cancelImage.Parent = cancelButton
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;return setGui
&#9;end
&#9;
&#9;local function createSetButton(text)
&#9;&#9;local setButton = Instance.new(&quot;TextButton&quot;)
&#9;&#9;
&#9;&#9;if text then setButton.Text = text
&#9;&#9;else setButton.Text = &quot;&quot; end
&#9;&#9;
&#9;&#9;setButton.AutoButtonColor = false
&#9;&#9;setButton.BackgroundTransparency = 1
&#9;&#9;setButton.BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;setButton.BorderSizePixel = 0
&#9;&#9;setButton.Size = UDim2.new(1,-5,0,18)
&#9;&#9;setButton.ZIndex = 6
&#9;&#9;setButton.Visible = false
&#9;&#9;setButton.Font = Enum.Font.Arial
&#9;&#9;setButton.FontSize = Enum.FontSize.Size18
&#9;&#9;setButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;setButton.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;
&#9;&#9;return setButton
&#9;end
&#9;
&#9;local function buildSetButton(name, setId, setImageId, i, count)
&#9;&#9;local button = createSetButton(name)
&#9;&#9;button.Text = name
&#9;&#9;button.Name = &quot;SetButton&quot;
&#9;&#9;button.Visible = true
&#9;&#9;
&#9;&#9;local setValue = Instance.new(&quot;IntValue&quot;)
&#9;&#9;setValue.Name = &quot;SetId&quot;
&#9;&#9;setValue.Value = setId
&#9;&#9;setValue.Parent = button
&#9;&#9;local setName = Instance.new(&quot;StringValue&quot;)
&#9;&#9;setName.Name = &quot;SetName&quot;
&#9;&#9;setName.Value = name
&#9;&#9;setName.Parent = button
&#9;&#9;return button
&#9;end
&#9;
&#9;local function processCategory(sets)
&#9;&#9;local setButtons = {}
&#9;&#9;local numSkipped = 0
&#9;&#9;for i = 1, #sets do
&#9;&#9;&#9;if not showAdminCategories and sets[i].Name == &quot;Beta&quot; then
&#9;&#9;&#9;&#9;numSkipped = numSkipped + 1
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;setButtons[i - numSkipped] = buildSetButton(sets[i].Name, sets[i].CategoryId, sets[i].ImageAssetId, i - numSkipped, #sets)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;return setButtons
&#9;end
&#9;
&#9;local function handleResize()
&#9;&#9;wait() -- neccessary to insure heartbeat happened
&#9;&#9;
&#9;&#9;local itemPreview = setGui.SetPanel.ItemPreview
&#9;&#9;
&#9;&#9;itemPreview.LargePreview.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.X)
&#9;&#9;itemPreview.LargePreview.Position = UDim2.new(0.5,-itemPreview.LargePreview.AbsoluteSize.X/2,0,0)
&#9;&#9;itemPreview.TextPanel.Position = UDim2.new(0,0,0,itemPreview.LargePreview.AbsoluteSize.Y)
&#9;&#9;itemPreview.TextPanel.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.Y - itemPreview.LargePreview.AbsoluteSize.Y)
&#9;end
&#9;
&#9;local function makeInsertAssetButton()
&#9;&#9;local insertAssetButtonExample = Instance.new(&quot;Frame&quot;)
&#9;&#9;insertAssetButtonExample.Name = &quot;InsertAssetButtonExample&quot;
&#9;&#9;insertAssetButtonExample.Position = UDim2.new(0,128,0,64)
&#9;&#9;insertAssetButtonExample.Size = UDim2.new(0,64,0,64)
&#9;&#9;insertAssetButtonExample.BackgroundTransparency = 1
&#9;&#9;insertAssetButtonExample.ZIndex = 6
&#9;&#9;insertAssetButtonExample.Visible = false
&#9;&#9;local assetId = Instance.new(&quot;IntValue&quot;)
&#9;&#9;assetId.Name = &quot;AssetId&quot;
&#9;&#9;assetId.Value = 0
&#9;&#9;assetId.Parent = insertAssetButtonExample
&#9;&#9;
&#9;&#9;local assetName = Instance.new(&quot;StringValue&quot;)
&#9;&#9;assetName.Name = &quot;AssetName&quot;
&#9;&#9;assetName.Value = &quot;&quot;
&#9;&#9;assetName.Parent = insertAssetButtonExample
&#9;&#9;local button = Instance.new(&quot;TextButton&quot;)
&#9;&#9;button.Name = &quot;Button&quot;
&#9;&#9;button.Text = &quot;&quot;
&#9;&#9;button.Style = Enum.ButtonStyle.RobloxButton
&#9;&#9;button.Position = UDim2.new(0.025,0,0.025,0)
&#9;&#9;button.Size = UDim2.new(0.95,0,0.95,0)
&#9;&#9;button.ZIndex = 6
&#9;&#9;button.Parent = insertAssetButtonExample
&#9;&#9;local buttonImage = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;buttonImage.Name = &quot;ButtonImage&quot;
&#9;&#9;buttonImage.Image = &quot;&quot;
&#9;&#9;buttonImage.Position = UDim2.new(0,-7,0,-7)
&#9;&#9;buttonImage.Size = UDim2.new(1,14,1,14)
&#9;&#9;buttonImage.BackgroundTransparency = 1
&#9;&#9;buttonImage.ZIndex = 7
&#9;&#9;buttonImage.Parent = button
&#9;&#9;local configIcon = buttonImage:clone()
&#9;&#9;configIcon.Name = &quot;ConfigIcon&quot;
&#9;&#9;configIcon.Visible = false
&#9;&#9;configIcon.Position = UDim2.new(1,-23,1,-24)
&#9;&#9;configIcon.Size = UDim2.new(0,16,0,16)
&#9;&#9;configIcon.Image = &quot;&quot;
&#9;&#9;configIcon.ZIndex = 6
&#9;&#9;configIcon.Parent = insertAssetButtonExample
&#9;&#9;
&#9;&#9;return insertAssetButtonExample
&#9;end
&#9;
&#9;local function showLargePreview(insertButton)
&#9;&#9;if insertButton:FindFirstChild(&quot;AssetId&quot;) then
&#9;&#9;&#9;delay(0,function()
&#9;&#9;&#9;&#9;game:GetService(&quot;ContentProvider&quot;):Preload(LargeThumbnailUrl .. tostring(insertButton.AssetId.Value))
&#9;&#9;&#9;&#9;setGui.SetPanel.ItemPreview.LargePreview.Image = LargeThumbnailUrl .. tostring(insertButton.AssetId.Value)
&#9;&#9;&#9;end)
&#9;&#9;end
&#9;&#9;if insertButton:FindFirstChild(&quot;AssetName&quot;) then
&#9;&#9;&#9;setGui.SetPanel.ItemPreview.TextPanel.RolloverText.Text = insertButton.AssetName.Value
&#9;&#9;end
&#9;end
&#9;
&#9;local function selectTerrainShape(shape)
&#9;&#9;if currTerrainDropDownFrame then
&#9;&#9;&#9;objectSelected(tostring(currTerrainDropDownFrame.AssetName.Value), tonumber(currTerrainDropDownFrame.AssetId.Value), shape)
&#9;&#9;end
&#9;end
&#9;
&#9;local function createTerrainTypeButton(name, parent)
&#9;&#9;local dropDownTextButton = Instance.new(&quot;TextButton&quot;)
&#9;&#9;dropDownTextButton.Name = name .. &quot;Button&quot;
&#9;&#9;dropDownTextButton.Font = Enum.Font.ArialBold
&#9;&#9;dropDownTextButton.FontSize = Enum.FontSize.Size14
&#9;&#9;dropDownTextButton.BorderSizePixel = 0
&#9;&#9;dropDownTextButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;dropDownTextButton.Text = name
&#9;&#9;dropDownTextButton.TextXAlignment = Enum.TextXAlignment.Left
&#9;&#9;dropDownTextButton.BackgroundTransparency = 1
&#9;&#9;dropDownTextButton.ZIndex = parent.ZIndex + 1
&#9;&#9;dropDownTextButton.Size = UDim2.new(0,parent.Size.X.Offset - 2,0,16)
&#9;&#9;dropDownTextButton.Position = UDim2.new(0,1,0,0)
&#9;&#9;dropDownTextButton.MouseEnter:connect(function()
&#9;&#9;&#9;dropDownTextButton.BackgroundTransparency = 0
&#9;&#9;&#9;dropDownTextButton.TextColor3 = Color3.new(0,0,0)
&#9;&#9;end)
&#9;&#9;dropDownTextButton.MouseLeave:connect(function()
&#9;&#9;&#9;dropDownTextButton.BackgroundTransparency = 1
&#9;&#9;&#9;dropDownTextButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;end)
&#9;&#9;dropDownTextButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;dropDownTextButton.BackgroundTransparency = 1
&#9;&#9;&#9;dropDownTextButton.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;if dropDownTextButton.Parent and dropDownTextButton.Parent:IsA(&quot;GuiObject&quot;) then
&#9;&#9;&#9;&#9;dropDownTextButton.Parent.Visible = false
&#9;&#9;&#9;end
&#9;&#9;&#9;selectTerrainShape(terrainShapeMap[dropDownTextButton.Text])
&#9;&#9;end)
&#9;&#9;return dropDownTextButton
&#9;end
&#9;
&#9;local function createTerrainDropDownMenu(zIndex)
&#9;&#9;local dropDown = Instance.new(&quot;Frame&quot;)
&#9;&#9;dropDown.Name = &quot;TerrainDropDown&quot;
&#9;&#9;dropDown.BackgroundColor3 = Color3.new(0,0,0)
&#9;&#9;dropDown.BorderColor3 = Color3.new(1,0,0)
&#9;&#9;dropDown.Size = UDim2.new(0,200,0,0)
&#9;&#9;dropDown.Visible = false
&#9;&#9;dropDown.ZIndex = zIndex
&#9;&#9;dropDown.Parent = setGui
&#9;&#9;for i = 1, #terrainShapes do
&#9;&#9;&#9;local shapeButton = createTerrainTypeButton(terrainShapes[i],dropDown)
&#9;&#9;&#9;shapeButton.Position = UDim2.new(0,1,0,(i - 1) * (shapeButton.Size.Y.Offset))
&#9;&#9;&#9;shapeButton.Parent = dropDown
&#9;&#9;&#9;dropDown.Size = UDim2.new(0,200,0,dropDown.Size.Y.Offset + (shapeButton.Size.Y.Offset))
&#9;&#9;end
&#9;&#9;dropDown.MouseLeave:connect(function()
&#9;&#9;&#9;dropDown.Visible = false
&#9;&#9;end)
&#9;end
&#9;
&#9;local function createDropDownMenuButton(parent)
&#9;&#9;local dropDownButton = Instance.new(&quot;ImageButton&quot;)
&#9;&#9;dropDownButton.Name = &quot;DropDownButton&quot;
&#9;&#9;dropDownButton.Image = &quot;http://www.roblox.com/asset/?id=67581509&quot;
&#9;&#9;dropDownButton.BackgroundTransparency = 1
&#9;&#9;dropDownButton.Size = UDim2.new(0,16,0,16)
&#9;&#9;dropDownButton.Position = UDim2.new(1,-24,0,6)
&#9;&#9;dropDownButton.ZIndex = parent.ZIndex + 2
&#9;&#9;dropDownButton.Parent = parent
&#9;&#9;
&#9;&#9;if not setGui:FindFirstChild(&quot;TerrainDropDown&quot;) then
&#9;&#9;&#9;createTerrainDropDownMenu(8)
&#9;&#9;end
&#9;&#9;
&#9;&#9;dropDownButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;setGui.TerrainDropDown.Visible = true
&#9;&#9;&#9;setGui.TerrainDropDown.Position = UDim2.new(0,parent.AbsolutePosition.X,0,parent.AbsolutePosition.Y)
&#9;&#9;&#9;currTerrainDropDownFrame = parent
&#9;&#9;end)
&#9;end
&#9;
&#9;local function buildInsertButton()
&#9;&#9;local insertButton = makeInsertAssetButton()
&#9;&#9;insertButton.Name = &quot;InsertAssetButton&quot;
&#9;&#9;insertButton.Visible = true
&#9;&#9;if Data.Category[Data.CurrentCategory].SetName == &quot;High Scalability&quot; then
&#9;&#9;&#9;createDropDownMenuButton(insertButton)
&#9;&#9;end
&#9;&#9;local lastEnter = nil
&#9;&#9;local mouseEnterCon = insertButton.MouseEnter:connect(function()
&#9;&#9;&#9;lastEnter = insertButton
&#9;&#9;&#9;delay(0.1,function()
&#9;&#9;&#9;&#9;if lastEnter == insertButton then
&#9;&#9;&#9;&#9;&#9;showLargePreview(insertButton)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;end)
&#9;&#9;return insertButton, mouseEnterCon
&#9;end
&#9;
&#9;local function realignButtonGrid(columns)
&#9;&#9;local x = 0
&#9;&#9;local y = 0
&#9;&#9;for i = 1, #insertButtons do
&#9;&#9;&#9;insertButtons[i].Position = UDim2.new(0, buttonWidth * x, 0, buttonHeight * y)
&#9;&#9;&#9;x = x + 1
&#9;&#9;&#9;if x &gt;= columns then
&#9;&#9;&#9;&#9;x = 0
&#9;&#9;&#9;&#9;y = y + 1
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;local function setInsertButtonImageBehavior(insertFrame, visible, name, assetId)
&#9;&#9;if visible then
&#9;&#9;&#9;insertFrame.AssetName.Value = name
&#9;&#9;&#9;insertFrame.AssetId.Value = assetId
&#9;&#9;&#9;local newImageUrl = SmallThumbnailUrl .. assetId
&#9;&#9;&#9;if newImageUrl ~= insertFrame.Button.ButtonImage.Image then
&#9;&#9;&#9;&#9;delay(0,function()
&#9;&#9;&#9;&#9;&#9;game:GetService(&quot;ContentProvider&quot;):Preload(SmallThumbnailUrl .. assetId)
&#9;&#9;&#9;&#9;&#9;if insertFrame:findFirstChild(&quot;Button&quot;) then
&#9;&#9;&#9;&#9;&#9;&#9;insertFrame.Button.ButtonImage.Image = SmallThumbnailUrl .. assetId
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;&#9;table.insert(insertButtonCons,
&#9;&#9;&#9;&#9;insertFrame.Button.MouseButton1Click:connect(function()
&#9;&#9;&#9;&#9;&#9;-- special case for water, show water selection gui
&#9;&#9;&#9;&#9;&#9;local isWaterSelected = (name == &quot;Water&quot;) and (Data.Category[Data.CurrentCategory].SetName == &quot;High Scalability&quot;)
&#9;&#9;&#9;&#9;&#9;waterGui.Visible = isWaterSelected
&#9;&#9;&#9;&#9;&#9;if isWaterSelected then
&#9;&#9;&#9;&#9;&#9;&#9;objectSelected(name, tonumber(assetId), nil)
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;objectSelected(name, tonumber(assetId))
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;)
&#9;&#9;&#9;insertFrame.Visible = true
&#9;&#9;else
&#9;&#9;&#9;insertFrame.Visible = false
&#9;&#9;end
&#9;end
&#9;
&#9;local function loadSectionOfItems(setGui, rows, columns)
&#9;&#9;local pageSize = rows * columns
&#9;&#9;if arrayPosition &gt; #contents then return end
&#9;&#9;local origArrayPos = arrayPosition
&#9;&#9;local yCopy = 0
&#9;&#9;for i = 1, pageSize + 1 do
&#9;&#9;&#9;if arrayPosition &gt;= #contents + 1 then
&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;end
&#9;&#9;&#9;local buttonCon
&#9;&#9;&#9;insertButtons[arrayPosition], buttonCon = buildInsertButton()
&#9;&#9;&#9;table.insert(insertButtonCons,buttonCon)
&#9;&#9;&#9;insertButtons[arrayPosition].Parent = setGui.SetPanel.ItemsFrame
&#9;&#9;&#9;arrayPosition = arrayPosition + 1
&#9;&#9;end
&#9;&#9;realignButtonGrid(columns)
&#9;&#9;local indexCopy = origArrayPos
&#9;&#9;for index = origArrayPos, arrayPosition do
&#9;&#9;&#9;if insertButtons[index] then
&#9;&#9;&#9;&#9;if contents[index] then
&#9;&#9;&#9;&#9;&#9;-- we don&apos;t want water to have a drop down button
&#9;&#9;&#9;&#9;&#9;if contents[index].Name == &quot;Water&quot; then
&#9;&#9;&#9;&#9;&#9;&#9;if Data.Category[Data.CurrentCategory].SetName == &quot;High Scalability&quot; then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;insertButtons[index]:FindFirstChild(&quot;DropDownButton&quot;,true):Destroy()
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;local assetId
&#9;&#9;&#9;&#9;&#9;if useAssetVersionId then
&#9;&#9;&#9;&#9;&#9;&#9;assetId = contents[index].AssetVersionId
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;assetId = contents[index].AssetId
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;setInsertButtonImageBehavior(insertButtons[index], true, contents[index].Name, assetId)
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;end
&#9;&#9;&#9;indexCopy = index
&#9;&#9;end
&#9;end
&#9;
&#9;local function setSetIndex()
&#9;&#9;Data.Category[Data.CurrentCategory].Index = 0
&#9;&#9;rows = 7
&#9;&#9;columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth)
&#9;&#9;contents = Data.Category[Data.CurrentCategory].Contents
&#9;&#9;if contents then
&#9;&#9;&#9;-- remove our buttons and their connections
&#9;&#9;&#9;for i = 1, #insertButtons do
&#9;&#9;&#9;&#9;insertButtons[i]:remove()
&#9;&#9;&#9;end
&#9;&#9;&#9;for i = 1, #insertButtonCons do
&#9;&#9;&#9;&#9;if insertButtonCons[i] then insertButtonCons[i]:disconnect() end
&#9;&#9;&#9;end
&#9;&#9;&#9;insertButtonCons = {}
&#9;&#9;&#9;insertButtons = {}
&#9;&#9;&#9;arrayPosition = 1
&#9;&#9;&#9;loadSectionOfItems(setGui, rows, columns)
&#9;&#9;end
&#9;end
&#9;
&#9;local function selectSet(button, setName, setId, setIndex)
&#9;&#9;if button and Data.Category[Data.CurrentCategory] ~= nil then
&#9;&#9;&#9;if button ~= Data.Category[Data.CurrentCategory].Button then
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory].Button = button
&#9;&#9;&#9;&#9;if SetCache[setId] == nil then
&#9;&#9;&#9;&#9;&#9;SetCache[setId] = game:GetService(&quot;InsertService&quot;):GetCollection(setId)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory].Contents = SetCache[setId]
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory].SetName = setName
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory].SetId = setId
&#9;&#9;&#9;end
&#9;&#9;&#9;setSetIndex()
&#9;&#9;end
&#9;end
&#9;
&#9;local function selectCategoryPage(buttons, page)
&#9;&#9;if buttons ~= Data.CurrentCategory then
&#9;&#9;&#9;if Data.CurrentCategory then
&#9;&#9;&#9;&#9;for key, button in pairs(Data.CurrentCategory) do
&#9;&#9;&#9;&#9;&#9;button.Visible = false
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;Data.CurrentCategory = buttons
&#9;&#9;&#9;if Data.Category[Data.CurrentCategory] == nil then
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory] = {}
&#9;&#9;&#9;&#9;if #buttons &gt; 0 then
&#9;&#9;&#9;&#9;&#9;selectSet(buttons[1], buttons[1].SetName.Value, buttons[1].SetId.Value, 0)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;Data.Category[Data.CurrentCategory].Button = nil
&#9;&#9;&#9;&#9;selectSet(Data.Category[Data.CurrentCategory].ButtonFrame, Data.Category[Data.CurrentCategory].SetName, Data.Category[Data.CurrentCategory].SetId, Data.Category[Data.CurrentCategory].Index)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;
&#9;local function selectCategory(category)
&#9;&#9;selectCategoryPage(category, 0)
&#9;end
&#9;
&#9;local function resetAllSetButtonSelection()
&#9;&#9;local setButtons = setGui.SetPanel.Sets.SetsLists:GetChildren()
&#9;&#9;for i = 1, #setButtons do
&#9;&#9;&#9;if setButtons[i]:IsA(&quot;TextButton&quot;) then
&#9;&#9;&#9;&#9;setButtons[i].Selected = false
&#9;&#9;&#9;&#9;setButtons[i].BackgroundTransparency = 1
&#9;&#9;&#9;&#9;setButtons[i].TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;setButtons[i].BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;
&#9;local function populateSetsFrame()
&#9;&#9;local currRow = 0
&#9;&#9;for i = 1, #userCategoryButtons do
&#9;&#9;&#9;local button = userCategoryButtons[i]
&#9;&#9;&#9;button.Visible = true
&#9;&#9;&#9;button.Position = UDim2.new(0,5,0,currRow * button.Size.Y.Offset)
&#9;&#9;&#9;button.Parent = setGui.SetPanel.Sets.SetsLists
&#9;&#9;&#9;
&#9;&#9;&#9;if i == 1 then -- we will have this selected by default, so show it
&#9;&#9;&#9;&#9;button.Selected = true
&#9;&#9;&#9;&#9;button.BackgroundColor3 = Color3.new(0,204/255,0)
&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(0,0,0)
&#9;&#9;&#9;&#9;button.BackgroundTransparency = 0
&#9;&#9;&#9;end
&#9;&#9;&#9;button.MouseEnter:connect(function()
&#9;&#9;&#9;&#9;if not button.Selected then
&#9;&#9;&#9;&#9;&#9;button.BackgroundTransparency = 0
&#9;&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(0,0,0)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;&#9;button.MouseLeave:connect(function()
&#9;&#9;&#9;&#9;if not button.Selected then
&#9;&#9;&#9;&#9;&#9;button.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end)
&#9;&#9;&#9;button.MouseButton1Click:connect(function()
&#9;&#9;&#9;&#9;resetAllSetButtonSelection()
&#9;&#9;&#9;&#9;button.Selected = not button.Selected
&#9;&#9;&#9;&#9;button.BackgroundColor3 = Color3.new(0,204/255,0)
&#9;&#9;&#9;&#9;button.TextColor3 = Color3.new(0,0,0)
&#9;&#9;&#9;&#9;button.BackgroundTransparency = 0
&#9;&#9;&#9;&#9;selectSet(button, button.Text, userCategoryButtons[i].SetId.Value, 0)
&#9;&#9;&#9;end)
&#9;&#9;&#9;currRow = currRow + 1
&#9;&#9;end
&#9;&#9;local buttons = setGui.SetPanel.Sets.SetsLists:GetChildren()
&#9;&#9;-- set first category as loaded for default
&#9;&#9;if buttons then
&#9;&#9;&#9;for i = 1, #buttons do
&#9;&#9;&#9;&#9;if buttons[i]:IsA(&quot;TextButton&quot;) then
&#9;&#9;&#9;&#9;&#9;selectSet(buttons[i], buttons[i].Text, userCategoryButtons[i].SetId.Value, 0)
&#9;&#9;&#9;&#9;&#9;selectCategory(userCategoryButtons)
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;setGui = createSetGui()
&#9;waterGui, waterTypeChangedEvent = createWaterGui()
&#9;waterGui.Position = UDim2.new(0,55,0,0)
&#9;waterGui.Parent = setGui
&#9;setGui.Changed:connect(function(prop) -- this resizes the preview image to always be the right size
&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;handleResize()
&#9;&#9;&#9;setSetIndex()
&#9;&#9;end
&#9;end)
&#9;
&#9;local scrollFrame, controlFrame = t.CreateTrueScrollingFrame()
&#9;scrollFrame.Size = UDim2.new(0.54,0,0.85,0)
&#9;scrollFrame.Position = UDim2.new(0.24,0,0.085,0)
&#9;scrollFrame.Name = &quot;ItemsFrame&quot;
&#9;scrollFrame.ZIndex = 6
&#9;scrollFrame.Parent = setGui.SetPanel
&#9;scrollFrame.BackgroundTransparency = 1
&#9;drillDownSetZIndex(controlFrame,7)
&#9;controlFrame.Parent = setGui.SetPanel
&#9;controlFrame.Position = UDim2.new(0.76, 5, 0, 0)
&#9;local debounce = false
&#9;controlFrame.ScrollBottom.Changed:connect(function(prop)
&#9;&#9;if controlFrame.ScrollBottom.Value == true then
&#9;&#9;&#9;if debounce then return end
&#9;&#9;&#9;debounce = true
&#9;&#9;&#9;&#9;loadSectionOfItems(setGui, rows, columns)
&#9;&#9;&#9;debounce = false
&#9;&#9;end
&#9;end)
&#9;local userData = {}
&#9;for id = 1, #userIdsForSets do
&#9;&#9;local newUserData = game:GetService(&quot;InsertService&quot;):GetUserSets(userIdsForSets[id])
&#9;&#9;if newUserData and #newUserData &gt; 2 then
&#9;&#9;&#9;-- start at #3 to skip over My Decals and My Models for each account
&#9;&#9;&#9;for category = 3, #newUserData do
&#9;&#9;&#9;&#9;if newUserData[category].Name == &quot;High Scalability&quot; then -- we want high scalability parts to show first
&#9;&#9;&#9;&#9;&#9;table.insert(userData,1,newUserData[category])
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;table.insert(userData, newUserData[category])
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;
&#9;end
&#9;if userData then
&#9;&#9;userCategoryButtons = processCategory(userData)
&#9;end
&#9;rows = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.Y/buttonHeight)
&#9;columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth)
&#9;populateSetsFrame()
&#9;insertPanelCloseCon = setGui.SetPanel.CancelButton.MouseButton1Click:connect(function()
&#9;&#9;setGui.SetPanel.Visible = false
&#9;&#9;if dialogClosed then dialogClosed() end
&#9;end)
&#9;
&#9;local setVisibilityFunction = function(visible)
&#9;&#9;if visible then
&#9;&#9;&#9;setGui.SetPanel.Visible = true
&#9;&#9;else
&#9;&#9;&#9;setGui.SetPanel.Visible = false
&#9;&#9;end
&#9;end
&#9;
&#9;local getVisibilityFunction = function()
&#9;&#9;if setGui then
&#9;&#9;&#9;if setGui:FindFirstChild(&quot;SetPanel&quot;) then
&#9;&#9;&#9;&#9;return setGui.SetPanel.Visible
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;
&#9;&#9;return false
&#9;end
&#9;
&#9;return setGui, setVisibilityFunction, getVisibilityFunction, waterTypeChangedEvent
end
t.CreateTerrainMaterialSelector = function(size,position)
&#9;local terrainMaterialSelectionChanged = Instance.new(&quot;BindableEvent&quot;)
&#9;terrainMaterialSelectionChanged.Name = &quot;TerrainMaterialSelectionChanged&quot;
&#9;local selectedButton = nil
&#9;local frame = Instance.new(&quot;Frame&quot;)
&#9;frame.Name = &quot;TerrainMaterialSelector&quot;
&#9;if size then
&#9;&#9;frame.Size = size
&#9;else
&#9;&#9;frame.Size = UDim2.new(0, 245, 0, 230)
&#9;end
&#9;if position then
&#9;&#9;frame.Position = position
&#9;end
&#9;frame.BorderSizePixel = 0
&#9;frame.BackgroundColor3 = Color3.new(0,0,0)
&#9;frame.Active = true
&#9;terrainMaterialSelectionChanged.Parent = frame
&#9;local waterEnabled = true -- todo: turn this on when water is ready
&#9;local materialToImageMap = {}
&#9;local materialNames = {&quot;Grass&quot;, &quot;Sand&quot;, &quot;Brick&quot;, &quot;Granite&quot;, &quot;Asphalt&quot;, &quot;Iron&quot;, &quot;Aluminum&quot;, &quot;Gold&quot;, &quot;Plank&quot;, &quot;Log&quot;, &quot;Gravel&quot;, &quot;Cinder Block&quot;, &quot;Stone Wall&quot;, &quot;Concrete&quot;, &quot;Plastic (red)&quot;, &quot;Plastic (blue)&quot;}
&#9;if waterEnabled then
&#9;&#9;table.insert(materialNames,&quot;Water&quot;)
&#9;end
&#9;local currentMaterial = 1
&#9;function getEnumFromName(choice)
&#9;&#9;if choice == &quot;Grass&quot; then return 1 end
&#9;&#9;if choice == &quot;Sand&quot; then return 2 end
&#9;&#9;if choice == &quot;Erase&quot; then return 0 end
&#9;&#9;if choice == &quot;Brick&quot; then return 3 end
&#9;&#9;if choice == &quot;Granite&quot; then return 4 end
&#9;&#9;if choice == &quot;Asphalt&quot; then return 5 end
&#9;&#9;if choice == &quot;Iron&quot; then return 6 end
&#9;&#9;if choice == &quot;Aluminum&quot; then return 7 end
&#9;&#9;if choice == &quot;Gold&quot; then return 8 end
&#9;&#9;if choice == &quot;Plank&quot; then return 9 end
&#9;&#9;if choice == &quot;Log&quot; then return 10 end
&#9;&#9;if choice == &quot;Gravel&quot; then return 11 end
&#9;&#9;if choice == &quot;Cinder Block&quot; then return 12 end
&#9;&#9;if choice == &quot;Stone Wall&quot; then return 13 end
&#9;&#9;if choice == &quot;Concrete&quot; then return 14 end
&#9;&#9;if choice == &quot;Plastic (red)&quot; then return 15 end
&#9;&#9;if choice == &quot;Plastic (blue)&quot; then return 16 end
&#9;&#9;if choice == &quot;Water&quot; then return 17 end
&#9;end
&#9;function getNameFromEnum(choice)
&#9;&#9;if choice == Enum.CellMaterial.Grass or choice == 1 then return &quot;Grass&quot;end
&#9;&#9;if choice == Enum.CellMaterial.Sand or choice == 2 then return &quot;Sand&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Empty or choice == 0 then return &quot;Erase&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Brick or choice == 3 then return &quot;Brick&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Granite or choice == 4 then return &quot;Granite&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Asphalt or choice == 5 then return &quot;Asphalt&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Iron or choice == 6 then return &quot;Iron&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Aluminum or choice == 7 then return &quot;Aluminum&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Gold or choice == 8 then return &quot;Gold&quot; end
&#9;&#9;if choice == Enum.CellMaterial.WoodPlank or choice == 9 then return &quot;Plank&quot; end
&#9;&#9;if choice == Enum.CellMaterial.WoodLog or choice == 10 then return &quot;Log&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Gravel or choice == 11 then return &quot;Gravel&quot; end
&#9;&#9;if choice == Enum.CellMaterial.CinderBlock or choice == 12 then return &quot;Cinder Block&quot; end
&#9;&#9;if choice == Enum.CellMaterial.MossyStone or choice == 13 then return &quot;Stone Wall&quot; end
&#9;&#9;if choice == Enum.CellMaterial.Cement or choice == 14 then return &quot;Concrete&quot; end
&#9;&#9;if choice == Enum.CellMaterial.RedPlastic or choice == 15 then return &quot;Plastic (red)&quot; end
&#9;&#9;if choice == Enum.CellMaterial.BluePlastic or choice == 16 then return &quot;Plastic (blue)&quot; end
&#9;&#9;if waterEnabled then
&#9;&#9;&#9;if choice == Enum.CellMaterial.Water or choice == 17 then return &quot;Water&quot; end
&#9;&#9;end
&#9;end
&#9;local function updateMaterialChoice(choice)
&#9;&#9;currentMaterial = getEnumFromName(choice)
&#9;&#9;terrainMaterialSelectionChanged:Fire(currentMaterial)
&#9;end
&#9;-- we so need a better way to do this
&#9;for i,v in pairs(materialNames) do
&#9;&#9;materialToImageMap[v] = {}
&#9;&#9;if v == &quot;Grass&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=56563112&quot;
&#9;&#9;elseif v == &quot;Sand&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=62356652&quot;
&#9;&#9;elseif v == &quot;Brick&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=65961537&quot;
&#9;&#9;elseif v == &quot;Granite&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532153&quot;
&#9;&#9;elseif v == &quot;Asphalt&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532038&quot;
&#9;&#9;elseif v == &quot;Iron&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532093&quot;
&#9;&#9;elseif v == &quot;Aluminum&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67531995&quot;
&#9;&#9;elseif v == &quot;Gold&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532118&quot;
&#9;&#9;elseif v == &quot;Plastic (red)&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67531848&quot;
&#9;&#9;elseif v == &quot;Plastic (blue)&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67531924&quot;
&#9;&#9;elseif v == &quot;Plank&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532015&quot;
&#9;&#9;elseif v == &quot;Log&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532051&quot;
&#9;&#9;elseif v == &quot;Gravel&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532206&quot;
&#9;&#9;elseif v == &quot;Cinder Block&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532103&quot;
&#9;&#9;elseif v == &quot;Stone Wall&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67531804&quot;
&#9;&#9;elseif v == &quot;Concrete&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=67532059&quot;
&#9;&#9;elseif v == &quot;Water&quot; then materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=81407474&quot;
&#9;&#9;else materialToImageMap[v].Regular = &quot;http://www.roblox.com/asset/?id=66887593&quot; -- fill in the rest here!!
&#9;&#9;end
&#9;end
&#9;local scrollFrame, scrollUp, scrollDown, recalculateScroll = t.CreateScrollingFrame(nil,&quot;grid&quot;)
&#9;scrollFrame.Size = UDim2.new(0.85,0,1,0)
&#9;scrollFrame.Position = UDim2.new(0,0,0,0)
&#9;scrollFrame.Parent = frame
&#9;scrollUp.Parent = frame
&#9;scrollUp.Visible = true
&#9;scrollUp.Position = UDim2.new(1,-19,0,0)
&#9;scrollDown.Parent = frame
&#9;scrollDown.Visible = true
&#9;scrollDown.Position = UDim2.new(1,-19,1,-17)
&#9;local function goToNewMaterial(buttonWrap, materialName)
&#9;&#9;updateMaterialChoice(materialName)
&#9;&#9;buttonWrap.BackgroundTransparency = 0
&#9;&#9;selectedButton.BackgroundTransparency = 1
&#9;&#9;selectedButton = buttonWrap
&#9;end
&#9;local function createMaterialButton(name)&#9;
&#9;&#9;local buttonWrap = Instance.new(&quot;TextButton&quot;)
&#9;&#9;buttonWrap.Text = &quot;&quot;
&#9;&#9;buttonWrap.Size = UDim2.new(0,32,0,32)
&#9;&#9;buttonWrap.BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;buttonWrap.BorderSizePixel = 0
&#9;&#9;buttonWrap.BackgroundTransparency = 1
&#9;&#9;buttonWrap.AutoButtonColor = false
&#9;&#9;buttonWrap.Name = tostring(name)
&#9;&#9;
&#9;&#9;local imageButton = Instance.new(&quot;ImageButton&quot;)
&#9;&#9;imageButton.AutoButtonColor = false
&#9;&#9;imageButton.BackgroundTransparency = 1
&#9;&#9;imageButton.Size = UDim2.new(0,30,0,30)
&#9;&#9;imageButton.Position = UDim2.new(0,1,0,1)
&#9;&#9;imageButton.Name = tostring(name)
&#9;&#9;imageButton.Parent = buttonWrap
&#9;&#9;imageButton.Image = materialToImageMap[name].Regular
&#9;&#9;local enumType = Instance.new(&quot;NumberValue&quot;)
&#9;&#9;enumType.Name = &quot;EnumType&quot;
&#9;&#9;enumType.Parent = buttonWrap
&#9;&#9;enumType.Value = 0
&#9;&#9;
&#9;&#9;imageButton.MouseEnter:connect(function()
&#9;&#9;&#9;buttonWrap.BackgroundTransparency = 0
&#9;&#9;end)
&#9;&#9;imageButton.MouseLeave:connect(function()
&#9;&#9;&#9;if selectedButton ~= buttonWrap then
&#9;&#9;&#9;&#9;buttonWrap.BackgroundTransparency = 1
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;&#9;imageButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;if selectedButton ~= buttonWrap then
&#9;&#9;&#9;&#9;goToNewMaterial(buttonWrap, tostring(name))
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;&#9;
&#9;&#9;return buttonWrap
&#9;end
&#9;for i = 1, #materialNames do
&#9;&#9;local imageButton = createMaterialButton(materialNames[i])
&#9;&#9;
&#9;&#9;if materialNames[i] == &quot;Grass&quot; then -- always start with grass as the default
&#9;&#9;&#9;selectedButton = imageButton
&#9;&#9;&#9;imageButton.BackgroundTransparency = 0
&#9;&#9;end
&#9;&#9;
&#9;&#9;imageButton.Parent = scrollFrame
&#9;end
&#9;local forceTerrainMaterialSelection = function(newMaterialType)
&#9;&#9;if not newMaterialType then return end
&#9;&#9;if currentMaterial == newMaterialType then return end
&#9;&#9;local matName = getNameFromEnum(newMaterialType)
&#9;&#9;local buttons = scrollFrame:GetChildren()
&#9;&#9;for i = 1, #buttons do
&#9;&#9;&#9;if buttons[i].Name == &quot;Plastic (blue)&quot; and matName == &quot;Plastic (blue)&quot; then goToNewMaterial(buttons[i],matName) return end
&#9;&#9;&#9;if buttons[i].Name == &quot;Plastic (red)&quot; and matName == &quot;Plastic (red)&quot; then goToNewMaterial(buttons[i],matName) return end
&#9;&#9;&#9;if string.find(buttons[i].Name, matName) then
&#9;&#9;&#9;&#9;goToNewMaterial(buttons[i],matName)
&#9;&#9;&#9;&#9;return
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;frame.Changed:connect(function ( prop )
&#9;&#9;if prop == &quot;AbsoluteSize&quot; then
&#9;&#9;&#9;recalculateScroll()
&#9;&#9;end
&#9;end)
&#9;recalculateScroll()
&#9;return frame, terrainMaterialSelectionChanged, forceTerrainMaterialSelection
end
t.CreateLoadingFrame = function(name,size,position)
&#9;game:GetService(&quot;ContentProvider&quot;):Preload(&quot;http://www.roblox.com/asset/?id=35238053&quot;)
&#9;local loadingFrame = Instance.new(&quot;Frame&quot;)
&#9;loadingFrame.Name = &quot;LoadingFrame&quot;
&#9;loadingFrame.Style = Enum.FrameStyle.RobloxRound
&#9;if size then loadingFrame.Size = size
&#9;else loadingFrame.Size = UDim2.new(0,300,0,160) end
&#9;if position then loadingFrame.Position = position
&#9;else loadingFrame.Position = UDim2.new(0.5, -150, 0.5,-80) end
&#9;local loadingBar = Instance.new(&quot;Frame&quot;)
&#9;loadingBar.Name = &quot;LoadingBar&quot;
&#9;loadingBar.BackgroundColor3 = Color3.new(0,0,0)
&#9;loadingBar.BorderColor3 = Color3.new(79/255,79/255,79/255)
&#9;loadingBar.Position = UDim2.new(0,0,0,41)
&#9;loadingBar.Size = UDim2.new(1,0,0,30)
&#9;loadingBar.Parent = loadingFrame
&#9;&#9;local loadingGreenBar = Instance.new(&quot;ImageLabel&quot;)
&#9;&#9;loadingGreenBar.Name = &quot;LoadingGreenBar&quot;
&#9;&#9;loadingGreenBar.Image = &quot;http://www.roblox.com/asset/?id=35238053&quot;
&#9;&#9;loadingGreenBar.Position = UDim2.new(0,0,0,0)
&#9;&#9;loadingGreenBar.Size = UDim2.new(0,0,1,0)
&#9;&#9;loadingGreenBar.Visible = false
&#9;&#9;loadingGreenBar.Parent = loadingBar
&#9;&#9;local loadingPercent = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;loadingPercent.Name = &quot;LoadingPercent&quot;
&#9;&#9;loadingPercent.BackgroundTransparency = 1
&#9;&#9;loadingPercent.Position = UDim2.new(0,0,1,0)
&#9;&#9;loadingPercent.Size = UDim2.new(1,0,0,14)
&#9;&#9;loadingPercent.Font = Enum.Font.Arial
&#9;&#9;loadingPercent.Text = &quot;0%&quot;
&#9;&#9;loadingPercent.FontSize = Enum.FontSize.Size14
&#9;&#9;loadingPercent.TextColor3 = Color3.new(1,1,1)
&#9;&#9;loadingPercent.Parent = loadingBar
&#9;local cancelButton = Instance.new(&quot;TextButton&quot;)
&#9;cancelButton.Name = &quot;CancelButton&quot;
&#9;cancelButton.Position = UDim2.new(0.5,-60,1,-40)
&#9;cancelButton.Size = UDim2.new(0,120,0,40)
&#9;cancelButton.Font = Enum.Font.Arial
&#9;cancelButton.FontSize = Enum.FontSize.Size18
&#9;cancelButton.TextColor3 = Color3.new(1,1,1)
&#9;cancelButton.Text = &quot;Cancel&quot;
&#9;cancelButton.Style = Enum.ButtonStyle.RobloxButton
&#9;cancelButton.Parent = loadingFrame
&#9;local loadingName = Instance.new(&quot;TextLabel&quot;)
&#9;loadingName.Name = &quot;loadingName&quot;
&#9;loadingName.BackgroundTransparency = 1
&#9;loadingName.Size = UDim2.new(1,0,0,18)
&#9;loadingName.Position = UDim2.new(0,0,0,2)
&#9;loadingName.Font = Enum.Font.Arial
&#9;loadingName.Text = name
&#9;loadingName.TextColor3 = Color3.new(1,1,1)
&#9;loadingName.TextStrokeTransparency = 1
&#9;loadingName.FontSize = Enum.FontSize.Size18
&#9;loadingName.Parent = loadingFrame
&#9;local cancelButtonClicked = Instance.new(&quot;BindableEvent&quot;)
&#9;cancelButtonClicked.Name = &quot;CancelButtonClicked&quot;
&#9;cancelButtonClicked.Parent = cancelButton
&#9;cancelButton.MouseButton1Click:connect(function()
&#9;&#9;cancelButtonClicked:Fire()
&#9;end)
&#9;local updateLoadingGuiPercent = function(percent, tweenAction, tweenLength)
&#9;&#9;if percent and type(percent) ~= &quot;number&quot; then
&#9;&#9;&#9;error(&quot;updateLoadingGuiPercent expects number as argument, got&quot;,type(percent),&quot;instead&quot;)
&#9;&#9;end
&#9;&#9;local newSize = nil
&#9;&#9;if percent &lt; 0 then
&#9;&#9;&#9;newSize = UDim2.new(0,0,1,0)
&#9;&#9;elseif percent &gt; 1 then
&#9;&#9;&#9;newSize = UDim2.new(1,0,1,0)
&#9;&#9;else
&#9;&#9;&#9;newSize = UDim2.new(percent,0,1,0)
&#9;&#9;end
&#9;&#9;if tweenAction then
&#9;&#9;&#9;if not tweenLength then
&#9;&#9;&#9;&#9;error(&quot;updateLoadingGuiPercent is set to tween new percentage, but got no tween time length! Please pass this in as third argument&quot;)
&#9;&#9;&#9;end
&#9;&#9;&#9;if (newSize.X.Scale &gt; 0) then
&#9;&#9;&#9;&#9;loadingGreenBar.Visible = true
&#9;&#9;&#9;&#9;loadingGreenBar:TweenSize(&#9;newSize,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Enum.EasingDirection.Out,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Enum.EasingStyle.Quad,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;tweenLength,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;true)
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;loadingGreenBar:TweenSize(&#9;newSize,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Enum.EasingDirection.Out,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Enum.EasingStyle.Quad,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;tweenLength,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;function()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;if (newSize.X.Scale &lt; 0) then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;loadingGreenBar.Visible = false
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;loadingGreenBar.Size = newSize
&#9;&#9;&#9;loadingGreenBar.Visible = (newSize.X.Scale &gt; 0)
&#9;&#9;end
&#9;end
&#9;loadingGreenBar.Changed:connect(function(prop)
&#9;&#9;if prop == &quot;Size&quot; then
&#9;&#9;&#9;loadingPercent.Text = tostring( math.ceil(loadingGreenBar.Size.X.Scale * 100) ) .. &quot;%&quot;
&#9;&#9;end
&#9;end)
&#9;return loadingFrame, updateLoadingGuiPercent, cancelButtonClicked
end
t.CreatePluginFrame = function (name,size,position,scrollable,parent)
&#9;function createMenuButton(size,position,text,fontsize,name,parent)
&#9;&#9;local button = Instance.new(&quot;TextButton&quot;,parent)
&#9;&#9;button.AutoButtonColor = false
&#9;&#9;button.Name = name
&#9;&#9;button.BackgroundTransparency = 1
&#9;&#9;button.Position = position
&#9;&#9;button.Size = size
&#9;&#9;button.Font = Enum.Font.ArialBold
&#9;&#9;button.FontSize = fontsize
&#9;&#9;button.Text = text
&#9;&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;&#9;button.BorderSizePixel = 0
&#9;&#9;button.BackgroundColor3 = Color3.new(20/255,20/255,20/255)
&#9;&#9;button.MouseEnter:connect(function ( )
&#9;&#9;&#9;if button.Selected then return end
&#9;&#9;&#9;button.BackgroundTransparency = 0
&#9;&#9;end)
&#9;&#9;button.MouseLeave:connect(function ( )
&#9;&#9;&#9;if button.Selected then return end
&#9;&#9;&#9;button.BackgroundTransparency = 1
&#9;&#9;end)
&#9;&#9;return button
&#9;end
&#9;local dragBar = Instance.new(&quot;Frame&quot;,parent)
&#9;dragBar.Name = tostring(name) .. &quot;DragBar&quot;
&#9;dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255)
&#9;dragBar.BorderColor3 = Color3.new(0,0,0)
&#9;if size then
&#9;&#9;dragBar.Size = UDim2.new(size.X.Scale,size.X.Offset,0,20) + UDim2.new(0,20,0,0)
&#9;else
&#9;&#9;dragBar.Size = UDim2.new(0,183,0,20)
&#9;end
&#9;if position then
&#9;&#9;dragBar.Position = position
&#9;end
&#9;dragBar.Active = true
&#9;dragBar.Draggable = true
&#9;--dragBar.Visible = false
&#9;dragBar.MouseEnter:connect(function ( )
&#9;&#9;dragBar.BackgroundColor3 = Color3.new(49/255,49/255,49/255)
&#9;end)
&#9;dragBar.MouseLeave:connect(function ( )
&#9;&#9;dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255)
&#9;end)
&#9;-- plugin name label
&#9;local pluginNameLabel = Instance.new(&quot;TextLabel&quot;,dragBar)
&#9;pluginNameLabel.Name = &quot;BarNameLabel&quot;
&#9;pluginNameLabel.Text = &quot; &quot; .. tostring(name)
&#9;pluginNameLabel.TextColor3 = Color3.new(1,1,1)
&#9;pluginNameLabel.TextStrokeTransparency = 0
&#9;pluginNameLabel.Size = UDim2.new(1,0,1,0)
&#9;pluginNameLabel.Font = Enum.Font.ArialBold
&#9;pluginNameLabel.FontSize = Enum.FontSize.Size18
&#9;pluginNameLabel.TextXAlignment = Enum.TextXAlignment.Left
&#9;pluginNameLabel.BackgroundTransparency = 1
&#9;-- close button
&#9;local closeButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-16,0.5,-8),&quot;X&quot;,Enum.FontSize.Size14,&quot;CloseButton&quot;,dragBar)
&#9;local closeEvent = Instance.new(&quot;BindableEvent&quot;)
&#9;closeEvent.Name = &quot;CloseEvent&quot;
&#9;closeEvent.Parent = closeButton
&#9;closeButton.MouseButton1Click:connect(function ()
&#9;&#9;closeEvent:Fire()
&#9;&#9;closeButton.BackgroundTransparency = 1
&#9;end)
&#9;-- help button
&#9;local helpButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-51,0.5,-8),&quot;?&quot;,Enum.FontSize.Size14,&quot;HelpButton&quot;,dragBar)
&#9;local helpFrame = Instance.new(&quot;Frame&quot;,dragBar)
&#9;helpFrame.Name = &quot;HelpFrame&quot;
&#9;helpFrame.BackgroundColor3 = Color3.new(0,0,0)
&#9;helpFrame.Size = UDim2.new(0,300,0,552)
&#9;helpFrame.Position = UDim2.new(1,5,0,0)
&#9;helpFrame.Active = true
&#9;helpFrame.BorderSizePixel = 0
&#9;helpFrame.Visible = false
&#9;helpButton.MouseButton1Click:connect(function( )
&#9;&#9;helpFrame.Visible = not helpFrame.Visible
&#9;&#9;if helpFrame.Visible then
&#9;&#9;&#9;helpButton.Selected = true
&#9;&#9;&#9;helpButton.BackgroundTransparency = 0
&#9;&#9;&#9;local screenGui = getScreenGuiAncestor(helpFrame)
&#9;&#9;&#9;if screenGui then
&#9;&#9;&#9;&#9;if helpFrame.AbsolutePosition.X + helpFrame.AbsoluteSize.X &gt; screenGui.AbsoluteSize.X then --position on left hand side
&#9;&#9;&#9;&#9;&#9;helpFrame.Position = UDim2.new(0,-5 - helpFrame.AbsoluteSize.X,0,0)
&#9;&#9;&#9;&#9;else -- position on right hand side
&#9;&#9;&#9;&#9;&#9;helpFrame.Position = UDim2.new(1,5,0,0)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;helpFrame.Position = UDim2.new(1,5,0,0)
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;helpButton.Selected = false
&#9;&#9;&#9;helpButton.BackgroundTransparency = 1
&#9;&#9;end
&#9;end)
&#9;local minimizeButton = createMenuButton(UDim2.new(0,16,0,17),UDim2.new(1,-34,0.5,-8),&quot;-&quot;,Enum.FontSize.Size14,&quot;MinimizeButton&quot;,dragBar)
&#9;minimizeButton.TextYAlignment = Enum.TextYAlignment.Top
&#9;local minimizeFrame = Instance.new(&quot;Frame&quot;,dragBar)
&#9;minimizeFrame.Name = &quot;MinimizeFrame&quot;
&#9;minimizeFrame.BackgroundColor3 = Color3.new(73/255,73/255,73/255)
&#9;minimizeFrame.BorderColor3 = Color3.new(0,0,0)
&#9;minimizeFrame.Position = UDim2.new(0,0,1,0)
&#9;if size then
&#9;&#9;minimizeFrame.Size = UDim2.new(size.X.Scale,size.X.Offset,0,50) + UDim2.new(0,20,0,0)
&#9;else
&#9;&#9;minimizeFrame.Size = UDim2.new(0,183,0,50)
&#9;end
&#9;minimizeFrame.Visible = false
&#9;local minimizeBigButton = Instance.new(&quot;TextButton&quot;,minimizeFrame)
&#9;minimizeBigButton.Position = UDim2.new(0.5,-50,0.5,-20)
&#9;minimizeBigButton.Name = &quot;MinimizeButton&quot;
&#9;minimizeBigButton.Size = UDim2.new(0,100,0,40)
&#9;minimizeBigButton.Style = Enum.ButtonStyle.RobloxButton
&#9;minimizeBigButton.Font = Enum.Font.ArialBold
&#9;minimizeBigButton.FontSize = Enum.FontSize.Size18
&#9;minimizeBigButton.TextColor3 = Color3.new(1,1,1)
&#9;minimizeBigButton.Text = &quot;Show&quot;
&#9;local separatingLine = Instance.new(&quot;Frame&quot;,dragBar)
&#9;separatingLine.Name = &quot;SeparatingLine&quot;
&#9;separatingLine.BackgroundColor3 = Color3.new(115/255,115/255,115/255)
&#9;separatingLine.BorderSizePixel = 0
&#9;separatingLine.Position = UDim2.new(1,-18,0.5,-7)
&#9;separatingLine.Size = UDim2.new(0,1,0,14)
&#9;local otherSeparatingLine = separatingLine:clone()
&#9;otherSeparatingLine.Position = UDim2.new(1,-35,0.5,-7)
&#9;otherSeparatingLine.Parent = dragBar
&#9;local widgetContainer = Instance.new(&quot;Frame&quot;,dragBar)
&#9;widgetContainer.Name = &quot;WidgetContainer&quot;
&#9;widgetContainer.BackgroundTransparency = 1
&#9;widgetContainer.Position = UDim2.new(0,0,1,0)
&#9;widgetContainer.BorderColor3 = Color3.new(0,0,0)
&#9;if not scrollable then
&#9;&#9;widgetContainer.BackgroundTransparency = 0
&#9;&#9;widgetContainer.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
&#9;end
&#9;if size then
&#9;&#9;if scrollable then
&#9;&#9;&#9;widgetContainer.Size = size
&#9;&#9;else
&#9;&#9;&#9;widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,size.Y.Scale,size.Y.Offset)
&#9;&#9;end
&#9;else
&#9;&#9;if scrollable then
&#9;&#9;&#9;widgetContainer.Size = UDim2.new(0,163,0,400)
&#9;&#9;else
&#9;&#9;&#9;widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,0,400)
&#9;&#9;end
&#9;end
&#9;if position then
&#9;&#9;widgetContainer.Position = position + UDim2.new(0,0,0,20)
&#9;end
&#9;local frame,control,verticalDragger = nil
&#9;if scrollable then
&#9;&#9;--frame for widgets
&#9;&#9;frame,control = t.CreateTrueScrollingFrame()
&#9;&#9;frame.Size = UDim2.new(1, 0, 1, 0)
&#9;&#9;frame.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
&#9;&#9;frame.BorderColor3 = Color3.new(0,0,0)
&#9;&#9;frame.Active = true
&#9;&#9;frame.Parent = widgetContainer
&#9;&#9;control.Parent = dragBar
&#9;&#9;control.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
&#9;&#9;control.BorderSizePixel = 0
&#9;&#9;control.BackgroundTransparency = 0
&#9;&#9;control.Position = UDim2.new(1,-21,1,1)
&#9;&#9;if size then
&#9;&#9;&#9;control.Size = UDim2.new(0,21,size.Y.Scale,size.Y.Offset)
&#9;&#9;else
&#9;&#9;&#9;control.Size = UDim2.new(0,21,0,400)
&#9;&#9;end
&#9;&#9;control:FindFirstChild(&quot;ScrollDownButton&quot;).Position = UDim2.new(0,0,1,-20)
&#9;&#9;local fakeLine = Instance.new(&quot;Frame&quot;,control)
&#9;&#9;fakeLine.Name = &quot;FakeLine&quot;
&#9;&#9;fakeLine.BorderSizePixel = 0
&#9;&#9;fakeLine.BackgroundColor3 = Color3.new(0,0,0)
&#9;&#9;fakeLine.Size = UDim2.new(0,1,1,1)
&#9;&#9;fakeLine.Position = UDim2.new(1,0,0,0)
&#9;&#9;verticalDragger = Instance.new(&quot;TextButton&quot;,widgetContainer)
&#9;&#9;verticalDragger.ZIndex = 2
&#9;&#9;verticalDragger.AutoButtonColor = false
&#9;&#9;verticalDragger.Name = &quot;VerticalDragger&quot;
&#9;&#9;verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255)
&#9;&#9;verticalDragger.BorderColor3 = Color3.new(0,0,0)
&#9;&#9;verticalDragger.Size = UDim2.new(1,20,0,20)
&#9;&#9;verticalDragger.Position = UDim2.new(0,0,1,0)
&#9;&#9;verticalDragger.Active = true
&#9;&#9;verticalDragger.Text = &quot;&quot;
&#9;&#9;local scrubFrame = Instance.new(&quot;Frame&quot;,verticalDragger)
&#9;&#9;scrubFrame.Name = &quot;ScrubFrame&quot;
&#9;&#9;scrubFrame.BackgroundColor3 = Color3.new(1,1,1)
&#9;&#9;scrubFrame.BorderSizePixel = 0
&#9;&#9;scrubFrame.Position = UDim2.new(0.5,-5,0.5,0)
&#9;&#9;scrubFrame.Size = UDim2.new(0,10,0,1)
&#9;&#9;scrubFrame.ZIndex = 5
&#9;&#9;local scrubTwo = scrubFrame:clone()
&#9;&#9;scrubTwo.Position = UDim2.new(0.5,-5,0.5,-2)
&#9;&#9;scrubTwo.Parent = verticalDragger
&#9;&#9;local scrubThree = scrubFrame:clone()
&#9;&#9;scrubThree.Position = UDim2.new(0.5,-5,0.5,2)
&#9;&#9;scrubThree.Parent = verticalDragger
&#9;&#9;local areaSoak = Instance.new(&quot;TextButton&quot;,getScreenGuiAncestor(parent))
&#9;&#9;areaSoak.Name = &quot;AreaSoak&quot;
&#9;&#9;areaSoak.Size = UDim2.new(1,0,1,0)
&#9;&#9;areaSoak.BackgroundTransparency = 1
&#9;&#9;areaSoak.BorderSizePixel = 0
&#9;&#9;areaSoak.Text = &quot;&quot;
&#9;&#9;areaSoak.ZIndex = 10
&#9;&#9;areaSoak.Visible = false
&#9;&#9;areaSoak.Active = true
&#9;&#9;local draggingVertical = false
&#9;&#9;local startYPos = nil
&#9;&#9;verticalDragger.MouseEnter:connect(function ()
&#9;&#9;&#9;verticalDragger.BackgroundColor3 = Color3.new(60/255,60/255,60/255)
&#9;&#9;end)
&#9;&#9;verticalDragger.MouseLeave:connect(function ()
&#9;&#9;&#9;verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255)
&#9;&#9;end)
&#9;&#9;verticalDragger.MouseButton1Down:connect(function(x,y)
&#9;&#9;&#9;draggingVertical = true
&#9;&#9;&#9;areaSoak.Visible = true
&#9;&#9;&#9;startYPos = y
&#9;&#9;end)
&#9;&#9;areaSoak.MouseButton1Up:connect(function ( )
&#9;&#9;&#9;draggingVertical = false
&#9;&#9;&#9;areaSoak.Visible = false
&#9;&#9;end)
&#9;&#9;areaSoak.MouseMoved:connect(function(x,y)
&#9;&#9;&#9;if not draggingVertical then return end
&#9;&#9;&#9;local yDelta = y - startYPos
&#9;&#9;&#9;if not control.ScrollDownButton.Visible and yDelta &gt; 0 then
&#9;&#9;&#9;&#9;return
&#9;&#9;&#9;end
&#9;&#9;&#9;if (widgetContainer.Size.Y.Offset + yDelta) &lt; 150 then
&#9;&#9;&#9;&#9;widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,150)
&#9;&#9;&#9;&#9;control.Size = UDim2.new (0,21,0,150)
&#9;&#9;&#9;&#9;return
&#9;&#9;&#9;end
&#9;&#9;&#9;startYPos = y
&#9;&#9;&#9;if widgetContainer.Size.Y.Offset + yDelta &gt;= 0 then
&#9;&#9;&#9;&#9;widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,widgetContainer.Size.Y.Offset + yDelta)
&#9;&#9;&#9;&#9;control.Size = UDim2.new(0,21,0,control.Size.Y.Offset + yDelta )
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;end
&#9;local function switchMinimize()
&#9;&#9;minimizeFrame.Visible = not minimizeFrame.Visible
&#9;&#9;if scrollable then
&#9;&#9;&#9;frame.Visible = not frame.Visible
&#9;&#9;&#9;verticalDragger.Visible = not verticalDragger.Visible
&#9;&#9;&#9;control.Visible = not control.Visible
&#9;&#9;else
&#9;&#9;&#9;widgetContainer.Visible = not widgetContainer.Visible
&#9;&#9;end
&#9;&#9;if minimizeFrame.Visible then
&#9;&#9;&#9;minimizeButton.Text = &quot;+&quot;
&#9;&#9;else
&#9;&#9;&#9;minimizeButton.Text = &quot;-&quot;
&#9;&#9;end
&#9;end
&#9;minimizeBigButton.MouseButton1Click:connect(function ( )
&#9;&#9;switchMinimize()
&#9;end)
&#9;minimizeButton.MouseButton1Click:connect(function( )
&#9;&#9;switchMinimize()
&#9;end)
&#9;if scrollable then
&#9;&#9;return dragBar, frame, helpFrame, closeEvent
&#9;else
&#9;&#9;return dragBar, widgetContainer, helpFrame, closeEvent
&#9;end
end
t.Help =
&#9;function(funcNameOrFunc)
&#9;&#9;--input argument can be a string or a function. Should return a description (of arguments and expected side effects)
&#9;&#9;if funcNameOrFunc == &quot;CreatePropertyDropDownMenu&quot; or funcNameOrFunc == t.CreatePropertyDropDownMenu then
&#9;&#9;&#9;return &quot;Function CreatePropertyDropDownMenu. &quot; ..
&#9;&#9;&#9;&#9; &quot;Arguments: (instance, propertyName, enumType). &quot; ..
&#9;&#9;&#9;&#9; &quot;Side effect: returns a container with a drop-down-box that is linked to the &apos;property&apos; field of &apos;instance&apos; which is of type &apos;enumType&apos;&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateDropDownMenu&quot; or funcNameOrFunc == t.CreateDropDownMenu then
&#9;&#9;&#9;return &quot;Function CreateDropDownMenu. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (items, onItemSelected). &quot; ..
&#9;&#9;&#9;&#9; &quot;Side effect: Returns 2 results, a container to the gui object and a &apos;updateSelection&apos; function for external updating. The container is a drop-down-box created around a list of items&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateMessageDialog&quot; or funcNameOrFunc == t.CreateMessageDialog then
&#9;&#9;&#9;return &quot;Function CreateMessageDialog. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (title, message, buttons). &quot; ..
&#9;&#9;&#9; &quot;Side effect: Returns a gui object of a message box with &apos;title&apos; and &apos;message&apos; as passed in. &apos;buttons&apos; input is an array of Tables contains a &apos;Text&apos; and &apos;Function&apos; field for the text/callback of each button&quot;
&#9;&#9;end&#9;&#9;
&#9;&#9;if funcNameOrFunc == &quot;CreateStyledMessageDialog&quot; or funcNameOrFunc == t.CreateStyledMessageDialog then
&#9;&#9;&#9;return &quot;Function CreateStyledMessageDialog. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (title, message, style, buttons). &quot; ..
&#9;&#9;&#9; &quot;Side effect: Returns a gui object of a message box with &apos;title&apos; and &apos;message&apos; as passed in. &apos;buttons&apos; input is an array of Tables contains a &apos;Text&apos; and &apos;Function&apos; field for the text/callback of each button, &apos;style&apos; is a string, either Error, Notify or Confirm&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;GetFontHeight&quot; or funcNameOrFunc == t.GetFontHeight then
&#9;&#9;&#9;return &quot;Function GetFontHeight. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (font, fontSize). &quot; ..
&#9;&#9;&#9; &quot;Side effect: returns the size in pixels of the given font + fontSize&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;LayoutGuiObjects&quot; or funcNameOrFunc == t.LayoutGuiObjects then
&#9;&#9;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateScrollingFrame&quot; or funcNameOrFunc == t.CreateScrollingFrame then
&#9;&#9;&#9;return &quot;Function CreateScrollingFrame. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (orderList, style) &quot; ..
&#9;&#9;&#9; &quot;Side effect: returns 4 objects, (scrollFrame, scrollUpButton, scrollDownButton, recalculateFunction). &apos;scrollFrame&apos; 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 &apos;grid&apos; styling if style is passed &apos;grid&apos; as a string. recalculateFunction can be called when a relayout is needed (when orderList changes)&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateTrueScrollingFrame&quot; or funcNameOrFunc == t.CreateTrueScrollingFrame then
&#9;&#9;&#9;return &quot;Function CreateTrueScrollingFrame. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (nil) &quot; ..
&#9;&#9;&#9; &quot;Side effect: returns 2 objects, (scrollFrame, controlFrame). &apos;scrollFrame&apos; can be filled with GuiObjects, and they will be clipped if not inside the frame&apos;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.&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;AutoTruncateTextObject&quot; or funcNameOrFunc == t.AutoTruncateTextObject then
&#9;&#9;&#9;return &quot;Function AutoTruncateTextObject. &quot; ..
&#9;&#9;&#9; &quot;Arguments: (textLabel) &quot; ..
&#9;&#9;&#9; &quot;Side effect: returns 2 objects, (textLabel, changeText). The &apos;textLabel&apos; input is modified to automatically truncate text (with ellipsis), if it gets too small to fit. &apos;changeText&apos; is a function that can be used to change the text, it takes 1 string as an argument&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateSlider&quot; or funcNameOrFunc == t.CreateSlider then
&#9;&#9;&#9;return &quot;Function CreateSlider. &quot; ..
&#9;&#9;&#9;&#9;&quot;Arguments: (steps, width, position) &quot; ..
&#9;&#9;&#9;&#9;&quot;Side effect: returns 2 objects, (sliderGui, sliderPosition). The &apos;steps&apos; argument specifies how many different positions the slider can hold along the bar. &apos;width&apos; specifies in pixels how wide the bar should be (modifiable afterwards if desired). &apos;position&apos; argument should be a UDim2 for slider positioning. &apos;sliderPosition&apos; is an IntValue whose current .Value specifies the specific step the slider is currently on.&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateSliderNew&quot; or funcNameOrFunc == t.CreateSliderNew then
&#9;&#9;&#9;return &quot;Function CreateSliderNew. &quot; ..
&#9;&#9;&#9;&#9;&quot;Arguments: (steps, width, position) &quot; ..
&#9;&#9;&#9;&#9;&quot;Side effect: returns 2 objects, (sliderGui, sliderPosition). The &apos;steps&apos; argument specifies how many different positions the slider can hold along the bar. &apos;width&apos; specifies in pixels how wide the bar should be (modifiable afterwards if desired). &apos;position&apos; argument should be a UDim2 for slider positioning. &apos;sliderPosition&apos; is an IntValue whose current .Value specifies the specific step the slider is currently on.&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateLoadingFrame&quot; or funcNameOrFunc == t.CreateLoadingFrame then
&#9;&#9;&#9;return &quot;Function CreateLoadingFrame. &quot; ..
&#9;&#9;&#9;&#9;&quot;Arguments: (name, size, position) &quot; ..
&#9;&#9;&#9;&#9;&quot;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.&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;CreateTerrainMaterialSelector&quot; or funcNameOrFunc == t.CreateTerrainMaterialSelector then
&#9;&#9;&#9;return &quot;Function CreateTerrainMaterialSelector. &quot; ..
&#9;&#9;&#9;&#9;&quot;Arguments: (size, position) &quot; ..
&#9;&#9;&#9;&#9;&quot;Side effect: Size and position are UDim2 values that specifies the selector&apos;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.&quot;
&#9;&#9;end
&#9;end
&#9;
--rbxsig%CqCG5zfc/XIjIEri/nYJ9ncJ3CVrBvc+dEV0dQ0iMjszaG45Oo0mMObtk/wOX16pMnwFbOo5OEnl4hHRNHan3AfjuqIGQGvXAnkfpO9PC3aX9Ekw8Y86aje2lzBqi4eikB6dWdf/Zfh/RORnavUxn3htyTMVZmaAd/Qc6eNOAc4=%
--rbxassetid%48488235%
--new playerlist by Zach Lindblad (fusroblox)
--contact him for any revisions/issues
--------------------
-- Super Util
--------------------
local ADMINS =
{
iagoMAO = &quot;rbxasset://textures/ui/admins/iagoMAO.png&quot;,
winsupermario1234 = &quot;rbxasset://textures/ui/admins/winsupermario1234.png&quot;,
Carrot = &quot;rbxasset://textures/ui/admins/carrot.png&quot;,
coke = &quot;rbxasset://textures/ui/admins/coke.png&quot;,
khanglegos = &quot;rbxasset://textures/ui/admins/khanglegos.png&quot;,
QuackIAttack = &quot;rbxasset://textures/ui/admins/QuackIAttack.png&quot;,
romulo27 = &quot;rbxasset://textures/ui/admins/romulo27.png&quot;,
TheLivingBee = &quot;rbxasset://textures/ui/admins/TheLivingBee.png&quot;,
OliverA = 1,
kinery = 1,
Peridorky =1,
Bitl = 1,
Raymonf = &quot;rbxasset://textures/ui/admins/Raymonf.png&quot;,
}
--[[
&#9;Generic object Create function, which I am using to create Gui&apos;s
&#9;Thanks to Stravant!
--]]
local Obj = {}
function Obj.Create(guiType)
&#9;return function(data)
&#9;&#9;local obj = Instance.new(guiType)
&#9;&#9;for k, v in pairs(data) do
&#9;&#9;&#9;if type(k) == &apos;number&apos; then
&#9;&#9;&#9;&#9;v.Parent = obj
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;obj[k] = v
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;return obj
&#9;end
end
--[[
&#9;makes a full sized background for a guiobject
&#9;@Args:
&#9;imgName&#9;&#9;asset name of image to fill background
&#9;@Return:&#9;background gui object
--]]
function MakeBackgroundGuiObj(imgName)
&#9;return Obj.Create&apos;ImageLabel&apos;
&#9;{
&#9;&#9;Name = &apos;Background&apos;,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;Image = imgName,
&#9;&#9;Position = UDim2.new(0, 0, 0, 0),
&#9;&#9;Size = UDim2.new(1,0,1,0),
&#9;}
end
--[[ turns 255 integer color value to a color3 --]]
function Color3I(r,g,b)
&#9;return Color3.new(r/255,g/255,b/255)
end
--[[
&#9;Gets correct icon for builder&apos;s club status to display by name
&#9;@Args:
&#9;membershipType&#9;&#9;Enum of membership status
&#9;@Return: &#9;&#9;&#9;string of image asset
--]]
function getMembershipTypeIcon(membershipType,playerName)
&#9;if ADMINS[playerName]~=nil then
&#9;&#9;if ADMINS[playerName] == 1 then
&#9;&#9;&#9;return &quot;rbxasset://textures/ui/admins/default.png&quot;
&#9;&#9;else
&#9;&#9;&#9;return ADMINS[playerName]
&#9;&#9;end
&#9;elseif membershipType == Enum.MembershipType.None then
&#9;&#9;return &quot;&quot;
&#9;elseif membershipType == Enum.MembershipType.BuildersClub then
&#9;&#9;return &quot;rbxasset://textures/ui/TinyBcIcon.png&quot;
&#9;elseif membershipType == Enum.MembershipType.TurboBuildersClub then
&#9;&#9;return &quot;rbxasset://textures/ui/TinyTbcIcon.png&quot;
&#9;elseif membershipType == Enum.MembershipType.OutrageousBuildersClub then
&#9;&#9;return &quot;rbxasset://textures/ui/TinyObcIcon.png&quot;
&#9;else
&#9;&#9;error(&quot;Unknown membershipType&quot; .. membershipType)
&#9;end&#9;
end
local function getFriendStatusIcon(friendStatus)
&#9;if friendStatus == Enum.FriendStatus.Unknown or friendStatus == Enum.FriendStatus.NotFriend then
&#9;&#9;return &quot;&quot;
&#9;elseif friendStatus == Enum.FriendStatus.Friend then
&#9;&#9;return &quot;rbxasset://textures/ui/friend.png&quot;
&#9;elseif friendStatus == Enum.FriendStatus.FriendRequestSent then
&#9;&#9;return &quot;rbxasset://textures/ui/friendrequestsent.png&quot;
&#9;elseif friendStatus == Enum.FriendStatus.FriendRequestReceived then
&#9;&#9;return &quot;rbxasset://textures/ui/friendrequestreceived.png&quot;
&#9;else
&#9;&#9;error(&quot;Unknown FriendStatus: &quot; .. friendStatus)
&#9;end
end
--[[
&#9;Utility function to create buttons for the popup menus
&#9;@Args:
&#9;nparent&#9;&#9;what to parent this button to
&#9;ntext&#9;&#9;text to put on this button
&#9;index&#9;&#9;number index of this entry in menu
&#9;last&#9;&#9;is this the last element of the popup menu
&#9;@Return:&#9;a popup menu button
--]]
function MakePopupButton(nparent,ntext,index,last)
&#9;local tobj = Obj.Create&quot;ImageButton&quot;
&#9;{
&#9;&#9;Name = &apos;ReportButton&apos;,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;Position = UDim2.new(0,0,1*index,0),
&#9;&#9;Size = UDim2.new(1, 0, 1, 0),
&#9;&#9;ZIndex=9,
&#9;&#9;Obj.Create&apos;TextLabel&apos;
&#9;&#9;{
&#9;&#9;&#9;Name = &apos;ButtonText&apos;,
&#9;&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;&#9;Position = UDim2.new(.07, 0, .07, 0),
&#9;&#9;&#9;Size = UDim2.new(.86,0,.86,0),
&#9;&#9;&#9;Parent = HeaderFrame,
&#9;&#9;&#9;Font = &apos;ArialBold&apos;,
&#9;&#9;&#9;Text = ntext,
&#9;&#9;&#9;FontSize = &apos;Size14&apos;,
&#9;&#9;&#9;TextScaled = true,
&#9;&#9;&#9;TextColor3 = Color3.new(1,1,1),
&#9;&#9;&#9;TextStrokeTransparency = 1,
&#9;&#9;&#9;ZIndex=9,
&#9;&#9;},
&#9;&#9;Parent = nparent,
&#9;}
&#9;if index==0 then
&#9;&#9;tobj.Image = &apos;http://www.roblox.com/asset/?id=97108784&apos;
&#9;elseif last then
&#9;&#9;tobj.Image = &apos;http://www.roblox.com/asset/?id=97109175&apos;
&#9;else
&#9;&#9;if index%2==1 then
&#9;&#9;&#9;tobj.Image = &apos;http://www.roblox.com/asset/?id=97112126&apos;
&#9;&#9;else
&#9;&#9;&#9;tobj.Image = &apos;http://www.roblox.com/asset/?id=97109338&apos;
&#9;&#9;end
&#9;end
&#9;return tobj
end
--[[
&#9;obligatory wait for child function
&#9;@Args:
&#9;parent&#9;&#9;Parent object to look for child in
&#9;child&#9;&#9;name of child object to look for
&#9;@Return: object waited for
--]]
function WaitForChild(parent,child)
&#9;while not parent:FindFirstChild(child) do
&#9;&#9;wait() debugprint(&quot; child &quot;..parent.Name..&quot; waiting for &quot;..child)
&#9;end
&#9;return parent[child]
end
---------------------------
-- Workspace Objects
---------------------------
-- might want to move all this to an init function, wait for localplayer elsewhere
local Players = game:GetService(&apos;Players&apos;)
-- make sure this doesn&apos;t run on the server(it will if you dont do this)
while not Players.LocalPlayer do
&#9;Players.Changed:wait()
end
local LocalPlayer = Players.LocalPlayer
local Mouse = LocalPlayer:GetMouse()
local ScreenGui = Obj.Create&quot;Frame&quot;
{
&#9;Name = &apos;PlayerListScreen&apos;,
&#9;Size = UDim2.new(1, 0, 1, 0),
&#9;BackgroundTransparency = 1,
&#9;Parent = script.Parent -- LocalPlayer.PlayerGui -- use for switching into playergui mode
}
local MainFrame = Obj.Create&quot;Frame&quot;
{
&#9;Name = &apos;LeaderBoardFrame&apos;,
&#9;Position = UDim2.new(1, -150, 0.005, 0),
&#9;Size = UDim2.new(0, 150, 0, 800),
&#9;BackgroundTransparency = 1,
&#9;Parent = ScreenGui,
}
--frame used for expanding leaderstats when frame is &apos;focused&apos;
local FocusFrame = Obj.Create&quot;Frame&quot;
{
&#9;Name = &apos;FocusFrame&apos;,
&#9;Position = UDim2.new(0, 0, 0, 0),
&#9;Size = UDim2.new(1, 0, 0, 100),
&#9;BackgroundTransparency = 1,
&#9;Active = true,
&#9;Parent = MainFrame,
}
local TemplateFrameYSize = 0.670000017
-- HEADER
local HeaderFrame = Obj.Create&quot;Frame&quot;
{
&#9;Name = &apos;Header&apos;,
&#9;BackgroundTransparency = 1,
&#9;Position = UDim2.new(0,0,0,0),
&#9;Size = UDim2.new(1, 0, .07, 0),
&#9;Parent = MainFrame,
&#9;MakeBackgroundGuiObj(&apos;http://www.roblox.com/asset/?id=94692054&apos;),
}
&#9;local HeaderFrameHeight = HeaderFrame.Size.Y.Scale
&#9;local MaximizeButton = Obj.Create&quot;ImageButton&quot;
&#9;{
&#9;&#9;Name = &apos;MaximizeButton&apos;,
&#9;&#9;Active = true,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;Position = UDim2.new(0, 0, 0, 0),
&#9;&#9;Size = UDim2.new(1,0,1,0),
&#9;&#9;Parent = HeaderFrame,
&#9;}
&#9;local HeaderName = Obj.Create&quot;TextLabel&quot;
&#9;{
&#9;&#9;Name = &apos;PlayerName&apos;,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;Position = UDim2.new(0, 0, .01, 0),
&#9;&#9;Size = UDim2.new(.98,0,.38,0),
&#9;&#9;Parent = HeaderFrame,
&#9;&#9;Font = &apos;ArialBold&apos;,
&#9;&#9;Text = LocalPlayer.Name,
&#9;&#9;FontSize=&apos;Size24&apos;,
&#9;&#9;--TextScaled = true,
&#9;&#9;TextColor3 = Color3.new(1,1,1),
&#9;&#9;TextStrokeColor3 = Color3.new(0,0,0),
&#9;&#9;TextStrokeTransparency = 0,
&#9;&#9;TextXAlignment = &apos;Right&apos;,
&#9;&#9;TextYAlignment = &apos;Center&apos;,
&#9;}
&#9;local HeaderScore = Obj.Create&quot;TextLabel&quot;
&#9;{
&#9;&#9;Name = &apos;PlayerScore&apos;,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;Position = UDim2.new(0, 0, .4, 0),
&#9;&#9;Size = UDim2.new(.98,0,0,30),
&#9;&#9;Parent = HeaderFrame,
&#9;&#9;Font = &apos;ArialBold&apos;,
&#9;&#9;Text = &apos;&apos;,
&#9;&#9;FontSize=&apos;Size24&apos;,
&#9;&#9;TextYAlignment = &apos;Top&apos;,
&#9;&#9;--TextScaled = true,
&#9;&#9;TextColor3 = Color3.new(1,1,1),
&#9;&#9;TextStrokeTransparency = 1,
&#9;&#9;TextXAlignment = &apos;Right&apos;,
&#9;&#9;TextYAlignment = &apos;Top&apos;,
&#9;}
-- BOTTOM
--used for shifting bottom frame for mouse over effects
local BottomShiftFrame = Obj.Create&quot;Frame&quot;
{
&#9;Name= &apos;BottomShiftFrame&apos;,
&#9;BackgroundTransparency = 1,
&#9;Position = UDim2.new(0,0,HeaderFrameHeight,0),
&#9;Size = UDim2.new(1,0,1,0),
&#9;Parent=MainFrame,
}
&#9;local BottomFrame = Obj.Create&quot;Frame&quot;
&#9;{
&#9;&#9;Name = &apos;Bottom&apos;,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;Position = UDim2.new(0,0,.07,0),
&#9;&#9;Size = UDim2.new(1, 0, .03, 0),
&#9;&#9;Parent = BottomShiftFrame,
&#9;&#9;MakeBackgroundGuiObj(&apos;http://www.roblox.com/asset/?id=94754966&apos;),
&#9;}
&#9;&#9;local ExtendButton = Obj.Create&quot;ImageButton&quot;
&#9;&#9;{
&#9;&#9;&#9;Name = &apos;bigbutton&apos;,
&#9;&#9;&#9;Active = true,
&#9;&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;&#9;Position = UDim2.new(0, 0, 0, 0),
&#9;&#9;&#9;Size = UDim2.new(1,0,1.5,0),
&#9;&#9;&#9;ZIndex = 3,
&#9;&#9;&#9;Parent = BottomFrame,
&#9;&#9;}
&#9;&#9;local ExtendTab = Obj.Create&quot;ImageButton&quot;
&#9;&#9;{
&#9;&#9;&#9;Name = &apos;extendTab&apos;,
&#9;&#9;&#9;Active = true,
&#9;&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;&#9;Image = &apos;http://www.roblox.com/asset/?id=94692731&apos;,
&#9;&#9;&#9;Position = UDim2.new(.608, 0, .3, 0),
&#9;&#9;&#9;Size = UDim2.new(.3,0,.7,0),
&#9;&#9;&#9;Parent = BottomFrame,
&#9;&#9;}
local TopClipFrame = Obj.Create&quot;Frame&quot;
{
&#9;Name = &apos;ListFrame&apos;,
&#9;BackgroundTransparency = 1,
&#9;Position = UDim2.new(-1,0,.07,0),
&#9;Size = UDim2.new(2, 0, 1, 0),
&#9;Parent = MainFrame,
&#9;ClipsDescendants = true,
}
&#9;local BottomClipFrame = Obj.Create&quot;Frame&quot;
&#9;{
&#9;&#9;Name = &apos;BottomFrame&apos;,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;Position = UDim2.new(0,0, - .8,0),
&#9;&#9;Size = UDim2.new(1, 0, 1, 0),
&#9;&#9;Parent = TopClipFrame,
&#9;&#9;ClipsDescendants = true,
&#9;}
&#9;&#9;local ScrollBarFrame = Obj.Create&quot;Frame&quot;
&#9;&#9;{
&#9;&#9;&#9;Name = &apos;ScrollBarFrame&apos;,
&#9;&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;&#9;Position = UDim2.new(.987,0,.8,0),
&#9;&#9;&#9;Size = UDim2.new(.01, 0, .2, 0),
&#9;&#9;&#9;Parent = BottomClipFrame,
&#9;&#9;}
&#9;&#9;&#9;local ScrollBar = Obj.Create&quot;Frame&quot;
&#9;&#9;&#9;{
&#9;&#9;&#9;&#9;Name = &apos;ScrollBar&apos;,
&#9;&#9;&#9;&#9;BackgroundTransparency = 0,
&#9;&#9;&#9;&#9;BackgroundColor3 = Color3.new(.2,.2,.2),
&#9;&#9;&#9;&#9;Position = UDim2.new(0,0,0,0),
&#9;&#9;&#9;&#9;Size = UDim2.new(1, 0, .5, 0),
&#9;&#9;&#9;&#9;ZIndex = 5,
&#9;&#9;&#9;&#9;Parent = ScrollBarFrame,
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;}
&#9;&#9;local ListFrame = Obj.Create&quot;Frame&quot;
&#9;&#9;{
&#9;&#9;&#9;Name = &apos;SubFrame&apos;,
&#9;&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;&#9;Position = UDim2.new(0,0,.8,0),
&#9;&#9;&#9;Size = UDim2.new(1, 0, 1, 0),
&#9;&#9;&#9;Parent = BottomClipFrame,
&#9;&#9;}
local PopUpClipFrame = Obj.Create&quot;Frame&quot;
{
&#9;Name = &apos;PopUpFrame&apos;,
&#9;BackgroundTransparency = 1,
&#9;SizeConstraint=&apos;RelativeXX&apos;,
&#9;Position = MainFrame.Position + UDim2.new( 0,-150,0,0),
&#9;Size = UDim2.new(0,150,0,800),
&#9;Parent = MainFrame,
&#9;ClipsDescendants = true,
&#9;ZIndex=9,
}
&#9;local PopUpPanel = Obj.Create&quot;Frame&quot;
&#9;{
&#9;&#9;Name = &apos;Panel&apos;,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;Position = UDim2.new(1,0,0,0),
&#9;&#9;Size = UDim2.new(1,0,.032,0),
&#9;&#9;Parent = PopUpClipFrame,
&#9;}
&#9;&#9;local ReportPlayerButton = MakePopupButton(PopUpPanel,&apos;Report Player&apos;,0)
&#9;&#9;local FriendPlayerButton = MakePopupButton(PopUpPanel,&apos;Friend&apos;,1,true)
&#9;local PersonalServerPanel = Obj.Create&quot;Frame&quot;
&#9;{
&#9;&#9;Name = &apos;Panel&apos;,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;Position = UDim2.new(1,0,0,0),
&#9;&#9;Size = UDim2.new(1,0,.032,0),
&#9;&#9;Parent = PopUpClipFrame,
&#9;}
&#9;&#9;local PSReportPlayerButton = MakePopupButton(PersonalServerPanel,&apos;Report Player&apos;,0)
&#9;&#9;local PSFriendPlayerButton = MakePopupButton(PersonalServerPanel,&apos;Friend&apos;,1)
&#9;&#9;local BanPlayerButton = MakePopupButton(PersonalServerPanel,&apos;Ban&apos;,2)
&#9;&#9;local VisitorButton = MakePopupButton(PersonalServerPanel,&apos;Visitor&apos;,3)
&#9;&#9;local MemberButton = MakePopupButton(PersonalServerPanel,&apos;Member&apos;,4)
&#9;&#9;local AdminButton = MakePopupButton(PersonalServerPanel,&apos;Admin&apos;,5,true)
local StatTitles = Obj.Create&quot;Frame&quot;
{
&#9;Name = &apos;StatTitles&apos;,
&#9;BackgroundTransparency = 1,
&#9;Position = UDim2.new(0,0,1,-10),
&#9;Size = UDim2.new(1, 0, 0, 0),
&#9;Parent = HeaderFrame,
}
local IsMinimized = Instance.new(&apos;BoolValue&apos;)
local IsMaximized = Instance.new(&apos;BoolValue&apos;)
local IsTabified = Instance.new(&apos;BoolValue&apos;)
local AreNamesExpanded = Instance.new(&apos;BoolValue&apos;)
local MiddleTemplate = Obj.Create&quot;Frame&quot;
{
&#9;Name = &apos;MidTemplate&apos;,
&#9;BackgroundTransparency = 1,
&#9;Position = UDim2.new(100,0,.07,0),
&#9;Size = UDim2.new(.5, 0, .025, 0),--UDim2.new(1, 0, .03, 0),
&#9;Obj.Create&apos;ImageLabel&apos;
&#9;{
&#9;&#9;Name = &apos;BCLabel&apos;,
&#9;&#9;Active = true,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;Position = UDim2.new(.005, 5, .20, 0),
&#9;&#9;Size = UDim2.new(0,16,0,16),
&#9;&#9;SizeConstraint = &apos;RelativeYY&apos;,
&#9;&#9;Image = &quot;&quot;,
&#9;&#9;ZIndex = 3,
&#9;},
&#9;Obj.Create&apos;ImageLabel&apos;
&#9;{
&#9;&#9;Name = &apos;FriendLabel&apos;,
&#9;&#9;Active = true,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;Position = UDim2.new(.005, 5, .15, 0),
&#9;&#9;Size = UDim2.new(0,16,0,16),
&#9;&#9;SizeConstraint = &apos;RelativeYY&apos;,
&#9;&#9;Image = &quot;&quot;,
&#9;&#9;ZIndex = 3,
&#9;},
&#9;Obj.Create&quot;ImageButton&quot;
&#9;{
&#9;&#9;Name = &apos;ClickListener&apos;,
&#9;&#9;Active = true,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;Position = UDim2.new(.005, 1, 0, 0),
&#9;&#9;Size = UDim2.new(.96,0,1,0),
&#9;&#9;ZIndex = 3,
&#9;},
&#9;Obj.Create&quot;Frame&quot;
&#9;{
&#9;&#9;Name = &apos;TitleFrame&apos;,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;Position = UDim2.new(.01, 0, 0, 0),
&#9;&#9;Size = UDim2.new(0,140,1,0),
&#9;&#9;ClipsDescendants=true,
&#9;&#9;Obj.Create&quot;TextLabel&quot;
&#9;&#9;{
&#9;&#9;&#9;Name = &apos;Title&apos;,
&#9;&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;&#9;Position = UDim2.new(0, 5, 0, 0),
&#9;&#9;&#9;Size = UDim2.new(100,0,1,0),
&#9;&#9;&#9;Font = &apos;Arial&apos;,
&#9;&#9;&#9;FontSize=&apos;Size14&apos;,
&#9;&#9;&#9;TextColor3 = Color3.new(1,1,1),
&#9;&#9;&#9;TextXAlignment = &apos;Left&apos;,
&#9;&#9;&#9;TextYAlignment = &apos;Center&apos;,
&#9;&#9;&#9;ZIndex = 3,
&#9;&#9;},
&#9;},
&#9;
&#9;Obj.Create&quot;TextLabel&quot;
&#9;{
&#9;&#9;Name = &apos;PlayerScore&apos;,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;Position = UDim2.new(0, 0, 0, 0),
&#9;&#9;Size = UDim2.new(1,0,1,0),
&#9;&#9;Font = &apos;Arial&apos;,
&#9;&#9;Text = &apos;&apos;,
&#9;&#9;FontSize=&apos;Size14&apos;,
&#9;&#9;TextColor3 = Color3.new(1,1,1),
&#9;&#9;TextXAlignment = &apos;Left&apos;,
&#9;&#9;TextYAlignment = &apos;Center&apos;,
&#9;&#9;ZIndex = 3,
&#9;},
&#9;--Obj.Create&apos;IntValue&apos;{Name = &apos;ID&apos;},
&#9;--Obj.Create&apos;ObjectValue&apos;{Name = &apos;Player&apos;},
&#9;--Obj.Create&apos;IntValue&apos;{Name = &apos;Score&apos;},&#9;
&#9;ZIndex = 3,
}
local MiddleBGTemplate = Obj.Create&quot;Frame&quot;
{
&#9;Name = &apos;MidBGTemplate&apos;,
&#9;BackgroundTransparency = 1,
&#9;Position = UDim2.new(100,0,.07,0),
&#9;Size = UDim2.new(.5, 0, .025, 0),--UDim2.new(1, 0, .03, 0),
&#9;MakeBackgroundGuiObj(&apos;http://www.roblox.com/asset/?id=94692025&apos;),
&#9;
}
-- REPORT ABUSE OBJECTS
local ReportAbuseShield = Obj.Create&quot;TextButton&quot;
{
&#9;Name = &quot;ReportAbuseShield&quot;,
&#9;Text = &quot;&quot;,
&#9;AutoButtonColor = false,
&#9;Active = true,
&#9;Visible = true,
&#9;Size = UDim2.new(1,0,1,0),
&#9;BackgroundColor3 = Color3I(51,51,51),
&#9;BorderColor3 = Color3I(27,42,53),
&#9;BackgroundTransparency = 1,
}
local ReportAbuseFrame = Obj.Create &quot;Frame&quot;
{
&#9;Name = &quot;Settings&quot;,
&#9;Position = UDim2.new(0.5, - 250, 0.5, - 200),
&#9;Size = UDim2.new(0.0, 500, 0.0, 400),
&#9;BackgroundTransparency = 1,
&#9;Active = true,
&#9;Parent = ReportAbuseShield,
}
local AbuseSettingsFrame = Obj.Create&quot;Frame&quot;
{
&#9;Name = &quot;ReportAbuseStyle&quot;,
&#9;Size = UDim2.new(1, 0, 1, 0),
&#9;Active = true,
&#9;BackgroundTransparency = 1,
&#9;MakeBackgroundGuiObj(&apos;http://www.roblox.com/asset/?id=96488767&apos;), -- 96480351&apos;),
&#9;Obj.Create&quot;TextLabel&quot;
&#9;{
&#9;&#9;Name = &quot;Title&quot;,
&#9;&#9;Text = &quot;Report Abuse&quot;,
&#9;&#9;TextColor3 = Color3I(221,221,221),
&#9;&#9;Position = UDim2.new(0.5, 0, 0, 30),
&#9;&#9;Font = Enum.Font.ArialBold,
&#9;&#9;FontSize = Enum.FontSize.Size36,
&#9;},
&#9;Obj.Create&quot;TextLabel&quot;
&#9;{
&#9;&#9;Name = &quot;Description&quot;,
&#9;&#9;Text = &quot;This will send a complete report to a moderator. The moderator will review the chat log and take appropriate action.&quot;,
&#9;&#9;TextColor3 = Color3I(221,221,221),
&#9;&#9;Position = UDim2.new(.01, 0, 0, 55),
&#9;&#9;Size = UDim2.new(.99, 0, 0, 40),
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;Font = Enum.Font.Arial,
&#9;&#9;FontSize = Enum.FontSize.Size18,
&#9;&#9;TextWrap = true,
&#9;&#9;TextXAlignment = Enum.TextXAlignment.Left,
&#9;&#9;TextYAlignment = Enum.TextYAlignment.Top,
&#9;},
&#9;Obj.Create&quot;TextLabel&quot;
&#9;{
&#9;&#9;Name = &quot;AbuseLabel&quot;,
&#9;&#9;Text = &quot;What did they do?&quot;,
&#9;&#9;Font = Enum.Font.Arial,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;FontSize = Enum.FontSize.Size18,
&#9;&#9;Position = UDim2.new(0.025,0,0,140),
&#9;&#9;Size = UDim2.new(0.4,0,0,36),
&#9;&#9;TextColor3 = Color3I(255,255,255),
&#9;&#9;TextXAlignment = Enum.TextXAlignment.Left,
&#9;},
&#9;Obj.Create&quot;TextLabel&quot;
&#9;{
&#9;&#9;Name = &quot;ShortDescriptionLabel&quot;,
&#9;&#9;Text = &quot;Short Description: (optional)&quot;,
&#9;&#9;Font = Enum.Font.Arial,
&#9;&#9;FontSize = Enum.FontSize.Size18,
&#9;&#9;Position = UDim2.new(0.025,0,0,180),
&#9;&#9;Size = UDim2.new(0.95,0,0,36),
&#9;&#9;TextColor3 = Color3I(255,255,255),
&#9;&#9;TextXAlignment = Enum.TextXAlignment.Left,
&#9;&#9;BackgroundTransparency = 1,
&#9;},
&#9;Obj.Create&quot;TextLabel&quot;
&#9;{
&#9;&#9;Name = &quot;ReportingPlayerLabel&quot;,
&#9;&#9;Text = &quot;Reporting Player&quot;,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;Font = Enum.Font.Arial,
&#9;&#9;FontSize = Enum.FontSize.Size18,
&#9;&#9;Position = UDim2.new(0.025,0,0,100),
&#9;&#9;Size = UDim2.new(0.95,0,0,36),
&#9;&#9;TextColor3 = Color3I(255,255,255),
&#9;&#9;TextXAlignment = Enum.TextXAlignment.Left,
&#9;&#9;Parent = AbuseSettingsFrame
&#9;},
&#9;Parent = ReportAbuseFrame,
}
local AbusePlayerLabel = Obj.Create&quot;TextLabel&quot;
{
&#9;Name = &quot;PlayerLabel&quot;,
&#9;Text = &quot;&quot;,
&#9;BackgroundTransparency = 1,
&#9;Font = Enum.Font.ArialBold,
&#9;FontSize = Enum.FontSize.Size18,
&#9;Position = UDim2.new(0.025,0,0,100),
&#9;Size = UDim2.new(0.95,0,0,36),
&#9;TextColor3 = Color3I(255,255,255),
&#9;TextXAlignment = Enum.TextXAlignment.Right,
&#9;Parent = AbuseSettingsFrame
}
local SubmitReportButton = Obj.Create&quot;ImageButton&quot;
{
&#9;Name = &quot;SubmitReportBtn&quot;,
&#9;Active = false,
&#9;BackgroundTransparency = 1,
&#9;Position = UDim2.new(.5, - 200, 1, - 80),
&#9;Size = UDim2.new(0,150,0,50),
&#9;AutoButtonColor = false,
&#9;Image = &apos;http://www.roblox.com/asset/?id=96502438&apos;, -- 96501119&apos;,
&#9;Parent = AbuseSettingsFrame,
}
local CancelReportButton = Obj.Create&quot;ImageButton&quot;
{
&#9;Name = &quot;CancelBtn&quot;,
&#9;BackgroundTransparency = 1,
&#9;Position = UDim2.new(0.5, 50, 1, - 80),
&#9;Size = UDim2.new(0,150,0,50),
&#9;AutoButtonColor = true,
&#9;Image = &apos;http://www.roblox.com/asset/?id=96500683&apos;,
&#9;Parent = AbuseSettingsFrame,
}
local AbuseDescriptionWrapper = Obj.Create&quot;Frame&quot;
{
&#9;Name = &quot;AbuseDescriptionWrapper&quot;,
&#9;Position = UDim2.new(0.025,0,0,220),
&#9;Size = UDim2.new(0.95,0,1, - 310),
&#9;BackgroundColor3 = Color3I(0,0,0),
&#9;BorderSizePixel = 0,
&#9;Parent = AbuseSettingsFrame,
}
local AbuseDescriptionBox
local OriginalAbuseDescriptionBox = Obj.Create&quot;TextBox&quot;
{
&#9;Name = &quot;TextBox&quot;,
&#9;Text = &quot;&quot;,
&#9;ClearTextOnFocus = false,
&#9;Font = Enum.Font.Arial,
&#9;FontSize = Enum.FontSize.Size18,
&#9;Position = UDim2.new(0,3,0,3),
&#9;Size = UDim2.new(1, - 6,1, - 6),
&#9;TextColor3 = Color3I(255,255,255),
&#9;TextXAlignment = Enum.TextXAlignment.Left,
&#9;TextYAlignment = Enum.TextYAlignment.Top,
&#9;TextWrap = true,
&#9;BackgroundColor3 = Color3I(0,0,0),
&#9;BorderSizePixel = 0,
}
local CalmingAbuseBox = Obj.Create&apos;Frame&apos;
{
&#9;Name = &apos;AbuseFeedbackBox&apos;,
&#9;BackgroundTransparency = 1,
&#9;Position=UDim2.new(0.25, 0, 0.300000012, 0),
&#9;Size=UDim2.new(0.5, 0, 0.370000005, 0),
&#9;MakeBackgroundGuiObj(&apos;http://www.roblox.com/asset/?id=96506233&apos;),
&#9;Obj.Create&apos;TextLabel&apos;
&#9;{
&#9;&#9;Name = &apos;Header&apos;,
&#9;&#9;Position=UDim2.new(0,10,.05,0),
&#9;&#9;Size=UDim2.new(1, -30, .15, 0),
&#9;&#9;TextScaled = true,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;TextXAlignment = Enum.TextXAlignment.Center,
&#9;&#9;TextYAlignment = Enum.TextYAlignment.Top,
&#9;&#9;Text = &apos;Thanks for your report!&apos;,
&#9;&#9;TextColor3 = Color3.new(1,1,1),
&#9;&#9;FontSize = Enum.FontSize.Size48,
&#9;&#9;Font = &apos;ArialBold&apos;,
&#9;},
&#9;Obj.Create&apos;TextLabel&apos;
&#9;{
&#9;&#9;Name = &apos;content&apos;,
&#9;&#9;Position = UDim2.new(0,10,.20,0),
&#9;&#9;Size = UDim2.new(1, -30, .40, 0),
&#9;&#9;TextScaled = true,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;TextColor3 = Color3.new(1,1,1),
&#9;&#9;Text = &apos;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&apos;,
&#9;&#9;TextWrapped = true,
&#9;&#9;TextYAlignment = Enum.TextYAlignment.Top,
&#9;&#9;FontSize = Enum.FontSize.Size24,
&#9;&#9;Font = &apos;Arial&apos;,
&#9;},
&#9;Obj.Create&apos;ImageButton&apos;
&#9;{
&#9;&#9;Name = &quot;OkButton&quot;,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;Position = UDim2.new(0.5, -75, 1, -80),
&#9;&#9;Size = UDim2.new(0,150,0,50),
&#9;&#9;AutoButtonColor = true,
&#9;&#9;Image = &apos;http://www.roblox.com/asset/?id=96507959&apos;,
&#9;}
}
local NormalAbuseBox = Obj.Create&apos;Frame&apos;
{
&#9;Name = &apos;AbuseFeedbackBox&apos;,
&#9;BackgroundTransparency = 1,
&#9;Position = UDim2.new(0.25, 0, 0.300000012, 0),
&#9;Size = UDim2.new(0.5, 0, 0.370000005, 0),
&#9;MakeBackgroundGuiObj(&apos;http://www.roblox.com/asset/?id=96506233&apos;),
&#9;Obj.Create&apos;TextLabel&apos;
&#9;{
&#9;&#9;Name = &apos;Header&apos;,
&#9;&#9;Position = UDim2.new(0,10,.05,0),
&#9;&#9;Size = UDim2.new(1, -30, .15, 0),
&#9;&#9;TextScaled = true,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;TextColor3 = Color3.new(1,1,1),
&#9;&#9;TextXAlignment = Enum.TextXAlignment.Center,
&#9;&#9;TextYAlignment = Enum.TextYAlignment.Top,
&#9;&#9;Text = &apos;Thanks for your report!&apos;,
&#9;&#9;FontSize = Enum.FontSize.Size48,
&#9;&#9;Font =&apos;ArialBold&apos;
&#9;},
&#9;Obj.Create&apos;TextLabel&apos;
&#9;{
&#9;&#9;Name = &apos;content&apos;,
&#9;&#9;Position = UDim2.new(0,10,.20,0),
&#9;&#9;Size = UDim2.new(1, -30, .15, 0),
&#9;&#9;TextScaled = true,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;TextColor3 = Color3.new(1,1,1),
&#9;&#9;Text = &quot;Our moderators will review the chat logs and determine what happened.&quot;,
&#9;&#9;TextWrapped = true,
&#9;&#9;TextYAlignment = Enum.TextYAlignment.Top,
&#9;&#9;FontSize = Enum.FontSize.Size24,
&#9;&#9;Font = &apos;Arial&apos;,
&#9;},
&#9;Obj.Create&apos;ImageButton&apos;
&#9;{
&#9;&#9;Name = &quot;OkButton&quot;,
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;Position = UDim2.new(0.5, -75, 1, -80),
&#9;&#9;Size = UDim2.new(0,150,0,50),
&#9;&#9;AutoButtonColor = true,
&#9;&#9;Image = &apos;http://www.roblox.com/asset/?id=96507959&apos;,
&#9;},
}
local BigButton=Instance.new(&apos;ImageButton&apos;)
&#9;BigButton.Size=UDim2.new(1,0,1,0)
&#9;BigButton.BackgroundTransparency=1
&#9;BigButton.ZIndex=8
&#9;BigButton.Visible=false
&#9;--BigButton.Active=false
&#9;BigButton.Parent=ScreenGui
&#9;
&#9;
local debugFrame = Obj.Create&quot;Frame&quot;
&#9;{
&#9;&#9;Name = &apos;debugframe&apos;,
&#9;&#9;Position = UDim2.new(0, 0, 0, 0),
&#9;&#9;Size = UDim2.new(0, 150, 0, 800),--0.99000001
&#9;&#9;BackgroundTransparency = 1,
&#9;&#9;
&#9;}
&#9;local debugplayers = Obj.Create&quot;TextLabel&quot;
&#9;{
&#9;&#9;BackgroundTransparency = .8,
&#9;&#9;Position = UDim2.new(0, 0, .01, 0),
&#9;&#9;Size = UDim2.new(1,0,.5,0),
&#9;&#9;Parent = debugFrame,
&#9;&#9;Font = &apos;ArialBold&apos;,
&#9;&#9;Text = &apos;--&apos;,
&#9;&#9;FontSize=&apos;Size14&apos;,
&#9;&#9;TextWrapped=true,
&#9;&#9;TextColor3 = Color3.new(1,1,1),
&#9;&#9;TextStrokeColor3 = Color3.new(0,0,0),
&#9;&#9;TextStrokeTransparency = 0,
&#9;&#9;TextXAlignment = &apos;Right&apos;,
&#9;&#9;TextYAlignment = &apos;Center&apos;,
&#9;}
&#9;local debugOutput = Obj.Create&quot;TextLabel&quot;
&#9;{
&#9;&#9;BackgroundTransparency = .8,
&#9;&#9;Position = UDim2.new(0, 0, .5, 0),
&#9;&#9;Size = UDim2.new(1,0,.5,0),
&#9;&#9;Parent = debugFrame,
&#9;&#9;Font = &apos;ArialBold&apos;,
&#9;&#9;Text = &apos;--&apos;,
&#9;&#9;FontSize=&apos;Size14&apos;,
&#9;&#9;TextWrapped=true,
&#9;&#9;TextColor3 = Color3.new(1,1,1),
&#9;&#9;TextStrokeColor3 = Color3.new(0,0,0),
&#9;&#9;TextStrokeTransparency = 0,
&#9;&#9;TextXAlignment = &apos;Right&apos;,
&#9;&#9;TextYAlignment = &apos;Center&apos;,
&#9;}&#9;
--[[
&#9;simple function to toggle the display of debug output
--]]
local DebugPrintEnabled=true
function debugprint(str)
&#9;if DebugPrintEnabled then
&#9;&#9;debugOutput.Text=str
&#9;end
end
-------------------------
-- Script objects
-------------------------
local RbxGui = t
-- number of entries to show if you click minimize
local DefaultEntriesOnScreen = 8
&#9;
local Images = {
&#9;bottomDark = &apos;94691904&apos;,
&#9;bottomLight = &apos;94691940&apos;,
&#9;midDark = &apos;94691980&apos;,
&#9;midLight = &apos;94692025&apos;,
&#9;LargeDark = &apos;96098866&apos;,
&#9;LargeLight = &apos;96098920&apos;,
&#9;LargeHeader = &apos;96097470&apos;,
&#9;NormalHeader = &apos;94692054&apos;,
&#9;LargeBottom = &apos;96397271&apos;, -- &apos;96098152&apos;,
&#9;NormalBottom = &apos;94754966&apos;,
&#9;DarkBluePopupMid = &apos;97114905&apos;,
&#9;LightBluePopupMid = &apos;97114905&apos;,
&#9;DarkPopupMid = &apos;97112126&apos;,
&#9;LightPopupMid = &apos;97109338&apos;,
&#9;DarkBluePopupTop = &apos;97114838&apos;,
&#9;LightBluePopupTop = &apos;&apos;,
&#9;DarkPopupTop = &apos;&apos;,
&#9;LightPopupTop = &apos;&apos;,
&#9;DarkBluePopupBottom = &apos;97114758&apos;,
&#9;LightBluePopupBottom = &apos;&apos;,
&#9;DarkPopupBottom = &apos;97109175&apos;,
&#9;LightPopupBottom = &apos;&apos;,
}
for _,i in pairs(Images) do
&#9;Game:GetService(&quot;ContentProvider&quot;):Preload(&quot;http://www.roblox.com/asset/?id=&quot;..i)
end
-- ordered array of &apos;score data&apos;, each entry has:
-- Name(String)
-- Priority(number)
-- IsPrimary (bool, should it be shown in upper right)
-- MaxLength (integer, of the length of the longest element for this column)
local ScoreNames = {}
-- prevents flipping in playerlist panels
local AddId = 0
-- intermediate table form of all player entries in format of:
-- Frame
-- Player
-- Score
-- ID
-- MyTeam (team ENRTY(not actual team) I am currently on)
local PlayerFrames = {}
-- intermediate ordered frame array, composed of Entrys of
-- Frame
-- MyTeam (my team object)
-- MyPlayers ( an ordered array of all player frames in team )
-- AutoHide (bool saying whether it should be hidden)
-- IsHidden (bool)
-- ID (int to prevent flipping out of leaderboard, fun times)
local TeamFrames = {}
-- one special entry from teamFrames, for unaffiliated players, only shown if players non - empty
local NeutralTeam = nil
-- final &apos;to be displayed&apos; list of frames
local MiddleFrames = {}
local MiddleFrameBackgrounds = {}
local MiddleFrameHeight = .03
-- time of last click
local LastClick = 0
local ButtonCooldown = .25
local OnIos = false
pcall(function() OnIos = Game:GetService(&apos;UserInputService&apos;).TouchEnabled end)
-- you get 200 of x screen space per stat added, start width 16%
local BaseScreenXSize = 150
local SpacingPerStat = 10 --spacing between stats
local MaximizedBounds = UDim2.new(.5,0,1,0)
local MaximizedPosition = UDim2.new(.25,0,.1,0)
local NormalBounds = UDim2.new(0,BaseScreenXSize, 0, 800)
local NormalPosition = UDim2.new(1 , - BaseScreenXSize, 0.005, 0)
local MinimizedBounds = UDim2.new(0, BaseScreenXSize, 0.99000001, 0)
-- number of stats to show from leaderstats
local NumPrimaryStats = 0
-- where the scroll par currently is positioned
local ScrollPosition = 0.75999999
local IsDragging = false -- am I dragging the player list
local DefaultBottomClipPos = BottomClipFrame.Position.Y.Scale
local LastSelectedPlayerEntry = nil
local SelectedPlayerEntry = nil
local SelectedPlayer = nil
-- locks(semaphores) for stopping race conditions
local AddingFrameLock = false
local ChangingOrderLock = false
local AddingStatLock = false
local BaseUpdateLock = false
local WaitForClickLock = false
local InPopupWaitForClick=false
local PlayerChangedLock = false
local NeutralTeamLock = false
local ScrollWheelConnections = {}
-- report abuse objects
local AbuseName
local Abuses = {
&#9;&quot;Bad Words or Threats&quot;,
&#9;&quot;Bad Username&quot;,
&#9;&quot;Talking about Dating&quot;,
&#9;&quot;Account Trading or Sharing&quot;,
&#9;&quot;Asking Personal Questions&quot;,
&#9;&quot;Rude or Mean Behavior&quot;,
&#9;&quot;False Reporting Me&quot;
}
local UpdateAbuseFunction
local AbuseDropDown, UpdateAbuseSelection
local PrivilegeLevel =
{
&#9;Owner = 255,
&#9;Admin = 240,
&#9;Member = 128,
&#9;Visitor = 10,
&#9;Banned = 0,
}
local IsPersonalServer = not not game.Workspace:FindFirstChild(&quot;PSVariable&quot;)
if IsPersonalServer then
&#9;--THIS SHOULD NOT BE HERE GUYS, only keeping to perserve old functionality
&#9;game:GetService(&quot;ScriptContext&quot;):AddCoreScript(64164692,game.Players.LocalPlayer,&quot;BuildToolManager&quot;)
end
game.Workspace.ChildAdded:connect(function(nchild)
&#9;if nchild.Name==&apos;PSVariable&apos; and nchild:IsA(&apos;BoolValue&apos;) then
&#9;&#9;IsPersonalServer=true
&#9;&#9;--THIS SHOULD NOT BE HERE GUYS, only keeping to perserve old functionality
&#9;&#9;game:GetService(&quot;ScriptContext&quot;):AddCoreScript(64164692,game.Players.LocalPlayer,&quot;BuildToolManager&quot;)
&#9;end
end)
-------------------------------
-- Static Functions
-------------------------------
function GetTotalEntries()
&#9;return math.min(#MiddleFrameBackgrounds,DefaultEntriesOnScreen)
end
function GetEntryListLength()
&#9;local numEnts=#PlayerFrames+#TeamFrames
&#9;if NeutralTeam then
&#9;&#9;numEnts=numEnts+1
&#9;end
&#9;return numEnts
end
function AreAllEntriesOnScreen()
&#9;return #MiddleFrameBackgrounds * MiddleTemplate.Size.Y.Scale &lt;= 1 + BottomClipFrame.Position.Y.Scale
end
function GetLengthOfVisbleScroll()
&#9;return 1 + BottomClipFrame.Position.Y.Scale
end
function GetMaxScroll()
&#9;return BottomClipFrame.Position.Y.Scale * - 1
end
-- can be optimized by caching when this varible changes
function GetMinScroll()
&#9;if AreAllEntriesOnScreen() then
&#9;&#9;return GetMaxScroll()
&#9;else
&#9;&#9;return (GetMaxScroll() - (#MiddleFrameBackgrounds * MiddleTemplate.Size.Y.Scale)) + (1 + BottomClipFrame.Position.Y.Scale)
&#9;end
end
function AbsoluteToPercent(x,y)
&#9;return Vector2.new(x,y)/ScreenGui.AbsoluteSize
end
--[[
&#9;tweens text transparency of element from starta to enda over length of time
&#9;Warning: should be put in a Spawn call
&#9;@Args:
&#9;element&#9;&#9;textobject to tween transparency on
&#9;starta&#9;&#9;alpha to start tweening
&#9;enda&#9;&#9;alpha to end tweening on
&#9;length&#9;&#9;how many seconds to spend tweening
--]]
function TweenTextTransparency(element,starta,enda,length)
&#9;local startTime = time()
&#9;while time() - startTime &lt; length do
&#9;&#9;element.TextTransparency = ((enda - starta) * ((time() - startTime)/length)) + starta
&#9;&#9;wait(.01)
&#9;end
&#9;element.TextTransparency = enda
end
--[[
&#9;tweens background transparency of element from starta to enda over length of time
&#9;Warning: should be put in a Spawn call
&#9;@Args:
&#9;element&#9;&#9;guiobject to tween transparency on
&#9;starta&#9;&#9;alpha to start tweening
&#9;enda&#9;&#9;alpha to end tweening on
&#9;length&#9;&#9;how many seconds to spend tweening
--]]
function TweenBackgroundTransparency(element,starta,enda,length)
&#9;local startTime = time()
&#9;while time() - startTime &lt; length do
&#9;&#9;element.BackgroundTransparency = ((enda - starta) * ((time() - startTime)/length)) + starta
&#9;&#9;wait(.01)
&#9;end
&#9;element.BackgroundTransparency = enda
end
--[[
&#9;UGLY UGLY HACK FUNCTION
&#9;replace with some sort of global input catching A.S.A. FREAKING P.
&#9;creates a fullsize gui element to catch next mouse up event(completeing a click)
&#9;@Args:
&#9;frameParent&#9;&#9;Object to parent fullscreen gui to
&#9;polledFunction&#9;function to call on mouse moved events in this gui
&#9;exitFunction&#9;function to call when click event is fired
--]]
function WaitForClick(frameParent,polledFunction,exitFunction)
&#9;if WaitForClickLock then return end
&#9;debugprint(&apos;waiting for click!&apos;)
&#9;WaitForClickLock=true
&#9;BigButton.Visible=true
&#9;--BigButton.Active=true
&#9;--BigButton.Parent=frameParent
&#9;local upHappened=false
&#9;local connection, connection2
&#9;connection2=BigButton.MouseMoved:connect( function(nx,ny)
&#9;&#9;polledFunction(nx,ny)
&#9;end)
&#9;connection=BigButton.MouseButton1Up:connect(function(nx,ny)
&#9;&#9;exitFunction(nx,ny)
&#9;&#9;BigButton.Visible=false
&#9;&#9;connection:disconnect()
&#9;&#9;connection2:disconnect()
&#9;&#9;debugprint(&apos;mouse up!&apos;)
&#9;end)
&#9;frameParent.AncestryChanged:connect(function(child,nparent)
&#9;&#9;if child == frameParent and nparent ==nil then
&#9;&#9;&#9;exitFunction(nx,ny)
&#9;&#9;&#9;BigButton.Visible=false
&#9;&#9;&#9;connection:disconnect()
&#9;&#9;&#9;connection2:disconnect()
&#9;&#9;&#9;debugprint(&quot;forced out of wait for click&quot;)
&#9;&#9;end
&#9;end)
&#9;WaitForClickLock=false
end
---------------------------
--Personal Server Handling
---------------------------
--[[
&#9;returns privlage level based on integer rank
&#9;Note: these privilege levels seem completely arbitrary, but no documentation exists
&#9;this is all from the old player list, really weird
&#9;@Args:
&#9;rank&#9;Integer rank value for player
&#9;@Return&#9;&#9;Normalized integer value for rank?
--]]
function GetPrivilegeType(rank)
&#9;if rank &lt;= PrivilegeLevel[&apos;Banned&apos;] then
&#9;&#9;return PrivilegeLevel[&apos;Banned&apos;]
&#9;elseif rank &lt;= PrivilegeLevel[&apos;Visitor&apos;] then
&#9;&#9;return PrivilegeLevel[&apos;Visitor&apos;]
&#9;elseif rank &lt;= PrivilegeLevel[&apos;Member&apos;] then
&#9;&#9;return PrivilegeLevel[&apos;Member&apos;]
&#9;elseif rank &lt;= PrivilegeLevel[&apos;Admin&apos;] then
&#9;&#9;return PrivilegeLevel[&apos;Admin&apos;]
&#9;else
&#9;&#9;return PrivilegeLevel[&apos;Owner&apos;]
&#9;end
end
--[[
&#9;gives a player a new privilage rank
&#9;Note: Very odd that I have to use loops with this instead of directly setting the rank
&#9;but no documentation for personal server service exists
&#9;@Args:
&#9;player&#9;&#9;player to change rank of
&#9;nrank&#9;&#9;new integer rank to give player
--]]
function SetPrivilegeRank(player,nrank)
&#9;while player.PersonalServerRank&lt;nrank do
&#9;&#9;game:GetService(&quot;PersonalServerService&quot;):Promote(player)
&#9;end
&#9;while player.PersonalServerRank&gt;nrank do
&#9;&#9;game:GetService(&quot;PersonalServerService&quot;):Demote(player)
&#9;end
end
--[[
&#9;called when player selects new privilege level from popup menu
&#9;@Args:
&#9;player&#9;&#9;player to set privileges on
&#9;nlevel&#9;&#9;new privilege level for this player
--]]
function OnPrivilegeLevelSelect(player,nlevel)
&#9;debugprint(&apos;setting privilege level&apos;)
&#9;SetPrivilegeRank(player,nlevel)
&#9;HighlightMyRank(player)
&#9;PersonalServerPanel:TweenPosition(UDim2.new(1,0,0,0), &quot;Out&quot;, &quot;Quad&quot;, .5,true)
end
--[[
&#9;Highlights current rank of this player in the popup menu
&#9;@Args:
&#9;player&#9;&#9;Player to check for rank on
--]]
function HighlightMyRank(player)
&#9;BanPlayerButton.Image= &apos;http://www.roblox.com/asset/?id=&apos;..Images[&apos;LightPopupMid&apos;]
&#9;VisitorButton.Image= &apos;http://www.roblox.com/asset/?id=&apos;..Images[&apos;DarkPopupMid&apos;]
&#9;MemberButton.Image= &apos;http://www.roblox.com/asset/?id=&apos;..Images[&apos;LightPopupMid&apos;]
&#9;AdminButton.Image= &apos;http://www.roblox.com/asset/?id=&apos;..Images[&apos;DarkPopupBottom&apos;]
&#9;
&#9;local rank=player.PersonalServerRank
&#9;if rank &lt;= PrivilegeLevel[&apos;Banned&apos;] then
&#9;&#9;BanPlayerButton.Image=&apos;http://www.roblox.com/asset/?id=&apos;..Images[&apos;LightBluePopupMid&apos;]
&#9;elseif rank &lt;= PrivilegeLevel[&apos;Visitor&apos;] then
&#9;&#9;VisitorButton.Image=&apos;http://www.roblox.com/asset/?id=&apos;..Images[&apos;DarkBluePopupMid&apos;]
&#9;elseif rank &lt;= PrivilegeLevel[&apos;Member&apos;] then
&#9;&#9;MemberButton.Image=&apos;http://www.roblox.com/asset/?id=&apos;..Images[&apos;LightBluePopupMid&apos;]
&#9;elseif rank &lt;= PrivilegeLevel[&apos;Admin&apos;] then
&#9;&#9;AdminButton.Image= &apos;http://www.roblox.com/asset/?id=&apos;..Images[&apos;DarkBluePopupBottom&apos;]
&#9;end
end
BanPlayerButton.MouseButton1Click:connect(function() BigButton.Visible=false OnPrivilegeLevelSelect(SelectedPlayer,PrivilegeLevel[&apos;Banned&apos;]) end)
VisitorButton.MouseButton1Click:connect(function() BigButton.Visible=false OnPrivilegeLevelSelect(SelectedPlayer,PrivilegeLevel[&apos;Visitor&apos;]) end)
MemberButton.MouseButton1Click:connect(function() BigButton.Visible=false OnPrivilegeLevelSelect(SelectedPlayer,PrivilegeLevel[&apos;Member&apos;]) end)
AdminButton.MouseButton1Click:connect(function() BigButton.Visible=false OnPrivilegeLevelSelect(SelectedPlayer,PrivilegeLevel[&apos;Admin&apos;]) end)
--------------------------
-- Report abuse handling
--------------------------
--[[
&#9;does final reporting of abuse on selected player, calls closeAbuseDialog
--]]
function OnSubmitAbuse()
&#9;if SubmitReportButton.Active then
&#9;&#9;if AbuseName and SelectedPlayer then
&#9;&#9;&#9;AbuseSettingsFrame.Visible = false
&#9;&#9;&#9;game.Players:ReportAbuse(SelectedPlayer, AbuseName, AbuseDescriptionBox.Text)
&#9;&#9;&#9;if AbuseName == &quot;Rude or Mean Behavior&quot; or AbuseName == &quot;False Reporting Me&quot; then
&#9;&#9;&#9;&#9;CalmingAbuseBox.Parent = ReportAbuseShield
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;debugprint(&apos;opening abuse box&apos;)
&#9;&#9;&#9;&#9;NormalAbuseBox.Parent = ReportAbuseShield
&#9;&#9;&#9;end
&#9;&#9;else
&#9;&#9;&#9;CloseAbuseDialog()
&#9;&#9;end
&#9;end
end
--[[
&#9;opens the abuse dialog, initialises text to display selectedplayer
--]]
function OpenAbuseDialog()
&#9;debugprint(&apos;adding report dialog&apos;)
&#9;AbusePlayerLabel.Text = SelectedPlayer.Name
&#9;--AbuseDescriptionBox.Text = &quot;&quot;
&#9;PopUpPanel:TweenPosition(UDim2.new(1,0,0,0), &quot;Out&quot;, &quot;Quad&quot;, .5,true)
&#9;AbuseDescriptionBox=OriginalAbuseDescriptionBox:Clone()
&#9;AbuseDescriptionBox.Parent = AbuseDescriptionWrapper
&#9;ReportAbuseShield.Parent = ScreenGui
end
--[[
&#9;resets and closes abuse dialog
--]]
function CloseAbuseDialog()
&#9;AbuseName = nil
&#9;SubmitReportButton.Active = false
&#9;SubmitReportButton.Image = &apos;http://www.roblox.com/asset/?id=96502438&apos; -- 96501119&apos;,
&#9;AbuseDescriptionBox:Destroy()
&#9;CalmingAbuseBox.Parent = nil
&#9;NormalAbuseBox.Parent = nil
&#9;ReportAbuseShield.Parent = nil
&#9;AbuseSettingsFrame.Visible = true
end
--[[
&#9;creates dropdownbox, registers all listeners for abuse dialog
--]]
function InitReportAbuse()
&#9;UpdateAbuseFunction = function(abuseText)
&#9;&#9;AbuseName = abuseText
&#9;&#9;if AbuseName and SelectedPlayer then
&#9;&#9;&#9;SubmitReportButton.Active = true
&#9;&#9;&#9;SubmitReportButton.Image = &apos;http://www.roblox.com/asset/?id=96501119&apos;
&#9;&#9;end
&#9;end
&#9;
&#9;AbuseDropDown, UpdateAbuseSelection = RbxGui.CreateDropDownMenu(Abuses, UpdateAbuseFunction, true)
&#9;AbuseDropDown.Name = &quot;AbuseComboBox&quot;
&#9;AbuseDropDown.Position = UDim2.new(0.425, 0, 0, 142)
&#9;AbuseDropDown.Size = UDim2.new(0.55,0,0,32)
&#9;AbuseDropDown.Parent = AbuseSettingsFrame
&#9;
&#9;
&#9;CancelReportButton.MouseButton1Click:connect(CloseAbuseDialog)
&#9;SubmitReportButton.MouseButton1Click:connect(OnSubmitAbuse)
&#9;ReportPlayerButton.MouseButton1Click:connect(function() BigButton.Visible=false OpenAbuseDialog() end)
&#9;PSReportPlayerButton.MouseButton1Click:connect(function() BigButton.Visible=false OpenAbuseDialog() end)
&#9;CalmingAbuseBox:FindFirstChild(&apos;OkButton&apos;).MouseButton1Down:connect(CloseAbuseDialog)
&#9;NormalAbuseBox:FindFirstChild(&apos;OkButton&apos;).MouseButton1Down:connect(CloseAbuseDialog)
end
-------------------------------------
-- Friend/unfriending
-------------------------------------
--[[
&#9;gets enum val of friend status, uses pcall for some reason?(from old playerlist)
&#9;@Args:
&#9;player&#9;player object to check if friends with
&#9;@Return: enum of friend status
--]]
local function GetFriendStatus(player)
&#9;if player == game.Players.LocalPlayer then
&#9;&#9;return Enum.FriendStatus.NotFriend
&#9;else
&#9;&#9;local success, result = pcall(function() return game.Players.LocalPlayer:GetFriendStatus(player) end)
&#9;&#9;if success then
&#9;&#9;&#9;return result
&#9;&#9;else
&#9;&#9;&#9;return Enum.FriendStatus.NotFriend
&#9;&#9;end
&#9;end
end
--[[
&#9;Updates text on popup friend button of SelectedPlayer
&#9;called when popup opens
--]]
function OnFriendPopUpOpen()
&#9;local friendButton
&#9;if IsPersonalServer and LocalPlayer.PersonalServerRank &gt;= PrivilegeLevel[&apos;Admin&apos;] then
&#9;&#9;friendButton=PSFriendPlayerButton
&#9;else
&#9;&#9;friendButton=FriendPlayerButton
&#9;end
&#9;local friendStatus=GetFriendStatus(SelectedPlayer)
&#9;debugprint(&apos;status: &apos; .. tostring(friendStatus))
&#9;if friendStatus==Enum.FriendStatus.Friend then
&#9;&#9;friendButton:FindFirstChild(&apos;ButtonText&apos;).Text=&apos;UnFriend Player&apos;
&#9;elseif friendStatus==Enum.FriendStatus.Unknown or friendStatus==Enum.FriendStatus.NotFriend then
&#9;&#9;friendButton:FindFirstChild(&apos;ButtonText&apos;).Text=&apos;Send Friend Request&apos;
&#9;elseif friendStatus==Enum.FriendStatus.FriendRequestSent then
&#9;&#9;friendButton:FindFirstChild(&apos;ButtonText&apos;).Text=&apos;Revoke Friend Request&apos;
&#9;elseif friendStatus==Enum.FriendStatus.FriendRequestReceived then
&#9;&#9;friendButton:FindFirstChild(&apos;ButtonText&apos;).Text=&apos;Accept Friend Request&apos;
&#9;end
end
--[[
&#9;when friend button is clicked, tries to take appropriate action,
&#9;based on current friend status with SelectedPlayer
--]]
function OnFriendButtonSelect()
&#9;BigButton.Visible=false
&#9;local friendStatus=GetFriendStatus(SelectedPlayer)
&#9;if friendStatus==Enum.FriendStatus.Friend then
&#9;&#9;LocalPlayer:RevokeFriendship(SelectedPlayer)
&#9;elseif friendStatus==Enum.FriendStatus.Unknown or friendStatus==Enum.FriendStatus.NotFriend then
&#9;&#9;LocalPlayer:RequestFriendship(SelectedPlayer)
&#9;elseif friendStatus==Enum.FriendStatus.FriendRequestSent then
&#9;&#9;LocalPlayer:RevokeFriendship(SelectedPlayer)
&#9;elseif friendStatus==Enum.FriendStatus.FriendRequestReceived then
&#9;&#9;LocalPlayer:RequestFriendship(SelectedPlayer)
&#9;end
&#9;PersonalServerPanel:TweenPosition(UDim2.new(1,0,0,0), &quot;Out&quot;, &quot;Quad&quot;, .5,true)
&#9;PopUpPanel:TweenPosition(UDim2.new(1,0,0,0), &quot;Out&quot;, &quot;Quad&quot;, .5,true)
end
PSFriendPlayerButton.MouseButton1Click:connect(OnFriendButtonSelect)
FriendPlayerButton.MouseButton1Click:connect(OnFriendButtonSelect)
------------------------------------
-- Player Entry Handling
------------------------------------
--[[
&#9;used by lua&apos;s table.sort to sort player entries
--]]
function PlayerSortFunction(a,b)
-- prevents flipping out leaderboard
&#9;if a[&apos;Score&apos;] == b[&apos;Score&apos;] then
&#9;&#9;return a[&apos;ID&apos;] &lt; b[&apos;ID&apos;]
&#9;end
&#9;if not a[&apos;Score&apos;] then return false end
&#9;if not b[&apos;Score&apos;] then return true end
&#9;return a[&apos;Score&apos;] &lt; b[&apos;Score&apos;]
end
---------------------------------
-- Stat Handling
---------------------------------
-- removes and closes all leaderboard stuffs
function BlowThisPopsicleStand()
&#9;--ScreenGui:Destroy()
&#9;--script:Destroy()
&#9;--time to make the fanboys rage...
&#9;Tabify()
end
--[[
&#9;used by lua&apos;s table.sort to prioritize score entries
--]]
function StatSort(a,b)
-- primary stats should be shown before all others
&#9;if a.IsPrimary ~= b.IsPrimary then
&#9;&#9;return a.IsPrimary
&#9;end
-- if priorities are equal, then return the first added one
&#9;if a.Priority == b.Priority then
&#9;&#9;return a.AddId &lt; b.AddId
&#9;end
&#9;return a.Priority &lt; b.Priority
end
--[[
&#9;doing WAAY too much here, for optimization update only your team
&#9;@Args:
&#9;playerEntry&#9;&#9;Entry of player who had a stat change
&#9;property&#9;&#9;Name of stat changed
--]]
function StatChanged(playerEntry,property)
-- if(playerEntry[&apos;MyTeam&apos;]) then
-- UpdateSingleTeam(playerEntry[&apos;MyTeam&apos;])
-- else
&#9;&#9;BaseUpdate()
-- end
end
--[[
&#9;Called when stat is added
&#9;if playerEntry is localplayer, will add to score names and re-sort the stats, and resize the width of the leaderboard
&#9;for all players, will add a listener for if this stat changes
&#9;if stat is a string value, crashes the leaderboard
&#9;Note:change crash to a &apos;tabify&apos; leaderboard later
&#9;@Args:
&#9;nchild&#9;&#9;&#9;new child value to leaderstats
&#9;playerEntry&#9;&#9;entry this stat was added to
--]]
function StatAdded(nchild,playerEntry)
-- dont re - add a leaderstat I alreday have
&#9;while AddingStatLock do debugprint(&apos;in stat added function lock&apos;) wait(1/30) end
&#9;AddingStatLock = true
&#9;if not (nchild:IsA(&apos;StringValue&apos;) or nchild:IsA(&apos;IntValue&apos;) or nchild:IsA(&apos;BoolValue&apos;) or nchild:IsA(&apos;NumberValue&apos;) or nchild:IsA(&apos;DoubleConstrainedValue&apos;) or nchild:IsA(&apos;IntConstrainedValue&apos;)) then
&#9;&#9;BlowThisPopsicleStand()
&#9;else
&#9;&#9;local haveScore = false
&#9;&#9;for _,i in pairs(ScoreNames) do
&#9;&#9;&#9;if i[&apos;Name&apos;]==nchild.Name then haveScore=true end
&#9;&#9;end
&#9;&#9;if not haveScore then
&#9;&#9;&#9;local nstat = {}
&#9;&#9;&#9;nstat[&apos;Name&apos;] = nchild.Name
&#9;&#9;&#9;nstat[&apos;Priority&apos;] = 0
&#9;&#9;&#9;if(nchild:FindFirstChild(&apos;Priority&apos;)) then
&#9;&#9;&#9;&#9;nstat[&apos;Priority&apos;] = nchild.Priority
&#9;&#9;&#9;end
&#9;&#9;&#9;nstat[&apos;IsPrimary&apos;] = false
&#9;&#9;&#9;if(nchild:FindFirstChild(&apos;IsPrimary&apos;)) then
&#9;&#9;&#9;&#9;nstat[&apos;IsPrimary&apos;] = true
&#9;&#9;&#9;end
&#9;&#9;&#9;if(nstat[&apos;IsPrimary&apos;]) then
&#9;&#9;&#9;&#9;NumPrimaryStats = NumPrimaryStats + 1
&#9;&#9;&#9;end
&#9;&#9;&#9;nstat.AddId = AddId
&#9;&#9;&#9;AddId = AddId + 1
&#9;&#9;&#9;table.insert(ScoreNames,nstat)
&#9;&#9;&#9;table.sort(ScoreNames,StatSort)
&#9;&#9;&#9;UpdateMaximize()
&#9;&#9;end
&#9;end
&#9;&#9;AddingStatLock = false
&#9;&#9;StatChanged(playerEntry)
&#9;&#9;nchild.Changed:connect(function(property) StatChanged(playerEntry,property) end)
&#9;
&#9;
end
--[[
&#9;Called when stat is removed from player
&#9;for all players, destroys the stat frame associated with this value,
&#9;then calls statchanged(to resize frame)
&#9;if playerEntry==localplayer, will remove from scorenames
&#9;@Args:
&#9;nchild&#9;&#9;&#9;___value to be removed
&#9;playerEntry&#9;&#9;entry of player value is being removed from
--]]
function StatRemoved(nchild,playerEntry)
&#9;while AddingStatLock do debugprint(&apos;In Adding Stat Lock1&apos;) wait(1/30) end
&#9;AddingStatLock = true
&#9;if playerEntry[&apos;Frame&apos;]:FindFirstChild(nchild.Name) then
&#9;&#9;debugprint(&apos;Destroyed frame!&apos;)
&#9;&#9;playerEntry[&apos;Frame&apos;][nchild.Name].Parent = nil
&#9;end
&#9;if playerEntry[&apos;Player&apos;].Name == LocalPlayer.Name then
&#9;&#9;for i,val in ipairs(ScoreNames) do
&#9;&#9;&#9;if val[&apos;IsPrimary&apos;] then
&#9;&#9;&#9;&#9;NumPrimaryStats = NumPrimaryStats - 1
&#9;&#9;&#9;end
&#9;&#9;&#9;if val[&apos;Name&apos;] == nchild.Name then
&#9;&#9;&#9;&#9;table.remove(ScoreNames,i)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;AddingStatLock = false
&#9;StatChanged(playerEntry)
end
--[[
&#9;clears all stats from a given playerEntry
&#9;used when leaderstats are removed, or when new leaderstats are added(for weird edge case)+
--]]
function RemoveAllStats(playerEntry)
&#9;while AddingStatLock do debugprint(&apos;In Adding Stat Lock1&apos;) wait(1/30) end
&#9;AddingStatLock = true
&#9;for i,val in ipairs(ScoreNames) do
&#9;&#9;if playerEntry[&apos;Frame&apos;]:FindFirstChild(val[&apos;Name&apos;]) then
&#9;&#9;&#9;debugprint(&apos;Destroyed frame!&apos;)
&#9;&#9;&#9;playerEntry[&apos;Frame&apos;][val[&apos;Name&apos;]].Parent = nil
&#9;&#9;end
&#9;&#9;if playerEntry[&apos;Player&apos;].Name == LocalPlayer.Name then
&#9;&#9;&#9;NumPrimaryStats = NumPrimaryStats - 1
&#9;&#9;end
&#9;end
&#9;if playerEntry[&apos;Player&apos;].Name == LocalPlayer.Name then
&#9;&#9;NumPrimaryStats = NumPrimaryStats - 1
&#9;end
&#9;
&#9;AddingStatLock = false
&#9;StatChanged(playerEntry)
end
function GetScoreValue(score)
&#9;if score:IsA(&apos;DoubleConstrainedValue&apos;) or score:IsA(&apos;IntConstrainedValue&apos;) then
&#9;&#9;return score.ConstrainedValue
&#9;elseif score:IsA(&apos;BoolValue&apos;) then
&#9;&#9;if score.Value then return 1 else return 0 end
&#9;else
&#9;&#9;return score.Value
&#9;end
end
--[[
&#9;
--]]
function MakeScoreEntry(entry,scoreval,panel)
&#9;if not panel:FindFirstChild(&apos;PlayerScore&apos;) then return end
&#9;local nscoretxt = panel:FindFirstChild(&apos;PlayerScore&apos;):Clone()
&#9;local thisScore = nil
&#9;--here lies the resting place of a once great and terrible bug
&#9;--may its treachery never be forgoten, lest its survivors fall for it again
&#9;--RIP the leaderstat bug, oct 2012-nov 2012
&#9;wait()
&#9;if entry[&apos;Player&apos;]:FindFirstChild(&apos;leaderstats&apos;) then
&#9;&#9;thisScore = entry[&apos;Player&apos;]:FindFirstChild(&apos;leaderstats&apos;):FindFirstChild(scoreval[&apos;Name&apos;])
&#9;else
&#9;&#9;return
&#9;end
&#9;
&#9;if not entry[&apos;Player&apos;].Parent then return end
&#9;
&#9;nscoretxt.Name = scoreval[&apos;Name&apos;]
&#9;nscoretxt.Text = tostring(GetScoreValue(thisScore))
&#9;if scoreval[&apos;Name&apos;] == ScoreNames[1][&apos;Name&apos;] then
&#9;&#9;debugprint(&apos;changing score&apos;)
&#9;&#9;entry[&apos;Score&apos;] = GetScoreValue(thisScore)
&#9;&#9;if entry[&apos;Player&apos;] == LocalPlayer then HeaderScore.Text = tostring(GetScoreValue(thisScore)) end
&#9;end
&#9;thisScore.Changed:connect(function()
&#9;&#9;if not thisScore.Parent then return end
&#9;&#9;if scoreval[&apos;Name&apos;] == ScoreNames[1][&apos;Name&apos;] then
&#9;&#9;&#9;
&#9;&#9;&#9;entry[&apos;Score&apos;] = GetScoreValue(thisScore)
&#9;&#9;&#9;if entry[&apos;Player&apos;] == LocalPlayer then HeaderScore.Text = tostring(GetScoreValue(thisScore)) end
&#9;&#9;end
&#9;&#9;nscoretxt.Text = tostring(GetScoreValue(thisScore))
&#9;&#9;BaseUpdate()
&#9;end)
&#9;return nscoretxt
end
function CreateStatTitle(statName)
&#9;
&#9;local ntitle = MiddleTemplate:FindFirstChild(&apos;PlayerScore&apos;):Clone()
&#9;ntitle.Name = statName
&#9;ntitle.Text = statName
&#9;-- ntitle
&#9;if IsMaximized.Value then
&#9;&#9;ntitle.TextTransparency = 0
&#9;else
&#9;&#9;ntitle.TextTransparency = 1
&#9;end
&#9;ntitle.Parent = StatTitles
end
function RecreateScoreColumns(ptable)
&#9;while AddingStatLock do debugprint (&apos;In Adding Stat Lock2&apos;) wait(1/30) end
&#9;AddingStatLock = true
&#9;local Xoffset=BaseScreenXSize --current offset from left
&#9;local maxXOffset=Xoffset
&#9;local MaxSizeColumn=0 --max size for this column
&#9;
&#9;-- foreach known leaderstat
&#9;for j = 1, #ScoreNames,1 do
&#9;&#9;local scoreval = ScoreNames[j]
&#9;&#9;--if scoreval[&apos;ColumnSize&apos;] then
&#9;&#9;--&#9;MaxSizeColumn=0--scoreval[&apos;ColumnSize&apos;]
&#9;&#9;--else
&#9;&#9;MaxSizeColumn=0
&#9;&#9;--end
&#9;&#9;-- for each entry in this player table
&#9;&#9;for i,entry in ipairs(ptable) do
&#9;&#9;&#9;local panel = entry[&apos;Frame&apos;]
&#9;&#9;&#9;local tplayer = entry[&apos;Player&apos;]
&#9;&#9;&#9;-- if this panel does not have an element named after this stat
&#9;&#9;&#9;if not panel:FindFirstChild(scoreval[&apos;Name&apos;]) then
&#9;&#9;&#9;&#9;-- make an entry for this object
&#9;&#9;&#9;&#9;local nentry = MakeScoreEntry(entry,scoreval,panel)
&#9;&#9;&#9;&#9;if nentry then
&#9;&#9;&#9;&#9;&#9;debugprint(&apos;adding &apos;..nentry.Name..&apos; to &apos;..entry[&apos;Player&apos;].Name )
&#9;&#9;&#9;&#9;&#9;nentry.Parent = panel
&#9;&#9;&#9;&#9;&#9;-- add score to team
&#9;&#9;&#9;&#9;&#9;if entry[&apos;MyTeam&apos;] and entry[&apos;MyTeam&apos;] ~= NeutralTeam and not entry[&apos;MyTeam&apos;][&apos;Frame&apos;]:FindFirstChild(scoreval[&apos;Name&apos;]) then
&#9;&#9;&#9;&#9;&#9;&#9;local ntitle = nentry:Clone()
&#9;&#9;&#9;&#9;&#9;&#9;ntitle.Parent = entry[&apos;MyTeam&apos;][&apos;Frame&apos;]
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;scoreval[&apos;XOffset&apos;]=Xoffset
&#9;&#9;&#9;if panel:FindFirstChild(scoreval[&apos;Name&apos;]) then
&#9;&#9;&#9;&#9;MaxSizeColumn=math.max(MaxSizeColumn,panel[scoreval[&apos;Name&apos;]].TextBounds.X)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;-- add stat title to top bar
&#9;&#9;if not StatTitles:FindFirstChild(scoreval[&apos;Name&apos;]) then
&#9;&#9;&#9;CreateStatTitle(scoreval[&apos;Name&apos;])
&#9;&#9;end
&#9;&#9;
&#9;&#9;if AreNamesExpanded.Value then
&#9;&#9;&#9;MaxSizeColumn=math.max(MaxSizeColumn,StatTitles[scoreval[&apos;Name&apos;] ].TextBounds.X)
&#9;&#9;&#9;StatTitles[scoreval[&apos;Name&apos;] ]:TweenPosition(UDim2.new(0,Xoffset,0,0),&apos;Out&apos;,&apos;Quad&apos;,.25,true)
&#9;&#9;else
&#9;&#9;&#9;StatTitles[scoreval[&apos;Name&apos;] ]:TweenPosition(UDim2.new(.4+((.6/#ScoreNames)*(j-1)),0,0,0),&apos;Out&apos;,&apos;Quad&apos;,.25,true)
&#9;&#9;end
&#9;&#9;scoreval[&apos;ColumnSize&apos;]=MaxSizeColumn
&#9;&#9;Xoffset= Xoffset+SpacingPerStat+MaxSizeColumn
&#9;&#9;maxXOffset=math.max(Xoffset,maxXOffset)
&#9;end
&#9;--print(maxXOffset)
&#9;NormalBounds = UDim2.new(0, maxXOffset,0,800)
&#9;NormalPosition = UDim2.new(1 , -NormalBounds.X.Offset, NormalPosition.Y.Scale, 0)
&#9;UpdateHeaderNameSize()
&#9;UpdateMaximize()
&#9;
&#9;AddingStatLock = false
end
---------------------------
-- Minimizing and maximizing
---------------------------
function ToggleMinimize()
&#9;IsMinimized.Value = not IsMinimized.Value
end
function ToggleMaximize()
&#9;IsMaximized.Value = not IsMaximized.Value
&#9;
end
function Tabify()
&#9;IsTabified.Value= true
&#9;IsMaximized.Value=false
&#9;IsMinimized.Value=true
&#9;UpdateMinimize()
&#9;IsTabified.Value= true
&#9;ScreenGui:TweenPosition(UDim2.new(NormalBounds.X.Scale, NormalBounds.X.Offset-10, 0,0),&apos;Out&apos;,&apos;Quad&apos;,1,true)
end
function UnTabify()
&#9;if IsTabified.Value then
&#9;&#9;IsTabified.Value= false
&#9;&#9;ScreenGui:TweenPosition(UDim2.new(0, 0, 0,0),&apos;Out&apos;,&apos;Quad&apos;,1,true)
&#9;end
end
--[[
&#9;Does more than it looks like
&#9;monitors positions of the clipping frames and bottom frames
&#9;called from EVERYWHERE
--]]
function UpdateMinimize()
&#9;if IsMinimized.Value then
&#9;&#9;if IsMaximized.Value then
&#9;&#9;&#9;ToggleMaximize()
&#9;&#9;end
&#9;&#9;if not IsTabified.Value then
&#9;&#9;&#9;MainFrame:TweenSizeAndPosition(UDim2.new(0.010, HeaderName.TextBounds.X, NormalBounds.Y.Scale,NormalBounds.Y.Offset),
&#9;&#9;&#9;&#9;UDim2.new(.990, -HeaderName.TextBounds.X, NormalPosition.Y.Scale,0),&apos;Out&apos;,&apos;Quad&apos;,1,true)
&#9;&#9;else
&#9;&#9;&#9;MainFrame:TweenSizeAndPosition(NormalBounds,NormalPosition,&apos;Out&apos;,&apos;Quad&apos;,1,true)
&#9;&#9;end
&#9;&#9;BottomClipFrame:TweenPosition(UDim2.new(0,0,DefaultBottomClipPos - (((GetTotalEntries()) * MiddleTemplate.Size.Y.Scale)),0), &quot;Out&quot;, &quot;Linear&quot;, .25,true)
&#9;&#9;BottomFrame:TweenPosition(UDim2.new(0,0,0,0), &quot;Out&quot;, &quot;Linear&quot;, .25,true)
&#9;&#9;FocusFrame.Size=UDim2.new(1,0,HeaderFrameHeight,0)
&#9;&#9;ExtendTab.Image = &apos;http://www.roblox.com/asset/?id=94692731&apos;
&#9;else
&#9;&#9;if not IsMaximized.Value then
&#9;&#9;&#9;MainFrame:TweenSizeAndPosition(NormalBounds,NormalPosition,&apos;Out&apos;,&apos;Quad&apos;,1,true)
&#9;&#9;end
&#9;&#9;BottomClipFrame:TweenPosition(UDim2.new(0,0,DefaultBottomClipPos,0), &quot;Out&quot;, &quot;Linear&quot;, .25,true)
&#9;&#9;BottomFrame:TweenPosition(UDim2.new(0,0,((GetTotalEntries()) * MiddleTemplate.Size.Y.Scale),0), &quot;Out&quot;, &quot;Linear&quot;, .25,true)
&#9;&#9;FocusFrame.Size=UDim2.new(1,0,((GetTotalEntries()) * MiddleTemplate.Size.Y.Scale) + HeaderFrameHeight,0)
&#9;&#9;ExtendTab.Image = &apos;http://www.roblox.com/asset/?id=94825585&apos;
&#9;end
end
--[[
&#9;Manages the position/size of the mainFrame, swaps out different resolution images for the frame
&#9;fades in and out the stat names, moves position of headername and header score
--]]
function UpdateMaximize()
&#9;if IsMaximized.Value then
&#9;&#9;--undo any &apos;name showing&apos;, without invoking base update
&#9;&#9;if AreNamesExpanded.Value then
&#9;&#9;&#9;CloseNames()
&#9;&#9;&#9;for j = 1, #ScoreNames,1 do
&#9;&#9;&#9;&#9;local scoreval = ScoreNames[j]
&#9;&#9;&#9;&#9;StatTitles[scoreval[&apos;Name&apos;] ]:TweenPosition(UDim2.new(.4+((.6/#ScoreNames)*(j-1)),0,0,0),&apos;Out&apos;,&apos;Quad&apos;,.25,true)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;if IsMinimized.Value then
&#9;&#9;&#9;ToggleMinimize()
&#9;&#9;else
&#9;&#9;&#9;UpdateMinimize()
&#9;&#9;end
&#9;&#9;
&#9;&#9;MainFrame:TweenSizeAndPosition(MaximizedBounds,MaximizedPosition,&apos;Out&apos;,&apos;Quad&apos;,1,true)
&#9;&#9;HeaderScore:TweenPosition(UDim2.new(0,0,HeaderName.Position.Y.Scale,0), &quot;Out&quot;, &quot;Linear&quot;, .25,true)
&#9;&#9;HeaderName:TweenPosition(UDim2.new( - .1, - HeaderScore.TextBounds.x,HeaderName.Position.Y.Scale,0), &quot;Out&quot;, &quot;Linear&quot;, .25,true)
&#9;&#9;HeaderFrame.Background.Image = &apos;http://www.roblox.com/asset/?id=&apos;..Images[&apos;LargeHeader&apos;]
&#9;&#9;BottomFrame.Background.Image = &apos;http://www.roblox.com/asset/?id=&apos;..Images[&apos;LargeBottom&apos;]
&#9;&#9;for index, i in ipairs(MiddleFrameBackgrounds) do
&#9;&#9;&#9;if (index%2) ~= 1 then
&#9;&#9;&#9;&#9;i.Background.Image = &apos;http://www.roblox.com/asset/?id=&apos;..Images[&apos;LargeDark&apos;]
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;i.Background.Image = &apos;http://www.roblox.com/asset/?id=&apos;..Images[&apos;LargeLight&apos;]
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;for index, i in ipairs(MiddleFrames) do
&#9;&#9;&#9;if i:FindFirstChild(&apos;ClickListener&apos;) then
&#9;&#9;&#9;&#9;i.ClickListener.Size = UDim2.new(.974,0,i.ClickListener.Size.Y.Scale,0)
&#9;&#9;&#9;end
&#9;&#9;&#9;for j=1, #ScoreNames,1 do
&#9;&#9;&#9;&#9;local scoreval = ScoreNames[j]
&#9;&#9;&#9;&#9;if i:FindFirstChild(scoreval[&apos;Name&apos;]) then
&#9;&#9;&#9;&#9;&#9;i[scoreval[&apos;Name&apos;]]:TweenPosition(UDim2.new(.4+((.6/#ScoreNames)*(j-1)),0,0,0), &quot;Out&quot;, &quot;Linear&quot;, .25,true)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;for i,entry in ipairs(PlayerFrames) do
&#9;&#9;&#9;WaitForChild(entry[&apos;Frame&apos;],&apos;TitleFrame&apos;).Size=UDim2.new(.38,0,entry[&apos;Frame&apos;].TitleFrame.Size.Y.Scale,0)
&#9;&#9;end
&#9;&#9;
&#9;&#9;for i,entry in ipairs(TeamFrames) do
&#9;&#9;&#9;WaitForChild(entry[&apos;Frame&apos;],&apos;TitleFrame&apos;).Size=UDim2.new(.38,0,entry[&apos;Frame&apos;].TitleFrame.Size.Y.Scale,0)
&#9;&#9;end
&#9;&#9;
&#9;else
&#9;&#9;if not IsMinimized.Value then
&#9;&#9;&#9;MainFrame:TweenSizeAndPosition(NormalBounds,NormalPosition,&apos;Out&apos;,&apos;Quad&apos;,1,true)
&#9;&#9;end
&#9;&#9;HeaderScore:TweenPosition(UDim2.new(0,0,.4,0), &quot;Out&quot;, &quot;Linear&quot;, .25,true)
&#9;&#9;HeaderName:TweenPosition(UDim2.new(0,0,HeaderName.Position.Y.Scale,0), &quot;Out&quot;, &quot;Linear&quot;, .25,true)
&#9;&#9;HeaderFrame.Background.Image = &apos;http://www.roblox.com/asset/?id=&apos;..Images[&apos;NormalHeader&apos;]
&#9;&#9;BottomFrame.Background.Image = &apos;http://www.roblox.com/asset/?id=&apos;..Images[&apos;NormalBottom&apos;]
&#9;&#9;for index, i in ipairs(MiddleFrameBackgrounds) do
&#9;&#9;&#9;if index%2 ~= 1 then
&#9;&#9;&#9;&#9;i.Background.Image = &apos;http://www.roblox.com/asset/?id=&apos;..Images[&apos;midDark&apos;]
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;i.Background.Image = &apos;http://www.roblox.com/asset/?id=&apos;..Images[&apos;midLight&apos;]
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;for index, i in ipairs(MiddleFrames) do
&#9;&#9;&#9;if i:FindFirstChild(&apos;ClickListener&apos;) then
&#9;&#9;&#9;&#9;i.ClickListener.Size = UDim2.new(.96,0,i.ClickListener.Size.Y.Scale,0)
&#9;&#9;&#9;&#9;for j=1, #ScoreNames,1 do
&#9;&#9;&#9;&#9;&#9;local scoreval = ScoreNames[j]
&#9;&#9;&#9;&#9;&#9;--print(scoreval[&apos;XOffset&apos;])
&#9;&#9;&#9;&#9;&#9;if i:FindFirstChild(scoreval[&apos;Name&apos;]) and scoreval[&apos;XOffset&apos;] then
&#9;&#9;&#9;&#9;&#9;&#9;--print(&apos;updateing stat position: &apos; .. scoreval[&apos;Name&apos;])
&#9;&#9;&#9;&#9;&#9;&#9;i[scoreval[&apos;Name&apos;]]:TweenPosition(UDim2.new(0,scoreval[&apos;XOffset&apos;],0,0), &quot;Out&quot;, &quot;Linear&quot;, .25,true)
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;
&#9;&#9;if not AreNamesExpanded.Value then
&#9;&#9;&#9;for _,i in pairs(StatTitles:GetChildren()) do
&#9;&#9;&#9;&#9;Spawn(function()TweenTextTransparency(i,i.TextTransparency,1,.25) end)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;for i,entry in ipairs(TeamFrames) do
&#9;&#9;&#9;WaitForChild(entry[&apos;Frame&apos;],&apos;TitleFrame&apos;).Size=UDim2.new(0,BaseScreenXSize*.9,entry[&apos;Frame&apos;].TitleFrame.Size.Y.Scale,0)
&#9;&#9;&#9;
&#9;&#9;end
&#9;&#9;for i,entry in ipairs(PlayerFrames) do
&#9;&#9;&#9;WaitForChild(entry[&apos;Frame&apos;],&apos;TitleFrame&apos;).Size=UDim2.new(0,BaseScreenXSize*.9,entry[&apos;Frame&apos;].TitleFrame.Size.Y.Scale,0)
&#9;&#9;end
&#9;end
end
function ExpandNames()
&#9;if #ScoreNames ~= 0 then
&#9;&#9;for _,i in pairs(StatTitles:GetChildren()) do
&#9;&#9;&#9;Spawn(function()TweenTextTransparency(i,i.TextTransparency,0,.25) end)
&#9;&#9;end
&#9;&#9;HeaderFrameHeight=.09
&#9;&#9;--as of writing, this and &apos;CloseNames&apos; are the only places headerframe is resized
&#9;&#9;HeaderFrame:TweenSizeAndPosition(UDim2.new(HeaderFrame.Size.X.Scale, HeaderFrame.Size.X.Offset, HeaderFrameHeight,0),
&#9;&#9;HeaderFrame.Position,&apos;Out&apos;,&apos;Quad&apos;,.25,true)
&#9;&#9;TopClipFrame:TweenPosition(UDim2.new(TopClipFrame.Position.X.Scale,0,HeaderFrameHeight,0),&apos;Out&apos;,&apos;Quad&apos;,.25,true)
&#9;&#9;BottomShiftFrame:TweenPosition(UDim2.new(0,0,HeaderFrameHeight,0), &quot;Out&quot;, &apos;Quad&apos;, .25,true)
&#9;&#9;AreNamesExpanded.Value=true
&#9;end
&#9;
end
function CloseNames()
&#9;if #ScoreNames ~= 0 then
&#9;&#9;HeaderFrameHeight=.07
&#9;&#9;if not (IsMaximized.Value) then
&#9;&#9;&#9;for _,i in pairs(StatTitles:GetChildren()) do
&#9;&#9;&#9;&#9;Spawn(function()TweenTextTransparency(i,i.TextTransparency,1,.25) end)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;BottomShiftFrame:TweenPosition(UDim2.new(0,0,HeaderFrameHeight,0), &quot;Out&quot;, &apos;Quad&apos;, .25,true)
&#9;&#9;HeaderFrame:TweenSizeAndPosition(UDim2.new(HeaderFrame.Size.X.Scale, HeaderFrame.Size.X.Offset, HeaderFrameHeight,0),
&#9;&#9;HeaderFrame.Position,&apos;Out&apos;,&apos;Quad&apos;,.25,true)
&#9;&#9;TopClipFrame:TweenPosition(UDim2.new(TopClipFrame.Position.X.Scale,0,HeaderFrameHeight,0),&apos;Out&apos;,&apos;Quad&apos;,.25,true)
&#9;&#9;AreNamesExpanded.Value=false
&#9;end
end
function OnScrollWheelMove(direction)
&#9;if not (IsTabified.Value or IsMinimized.Value) then
&#9;&#9;local StartFrame = ListFrame.Position
&#9;&#9;local newFrameY = math.max(math.min(StartFrame.Y.Scale + (direction),GetMaxScroll()),GetMinScroll())
&#9;&#9;ListFrame.Position = UDim2.new(StartFrame.X.Scale,StartFrame.X.Offset,newFrameY,StartFrame.Y.Offset)
&#9;&#9;UpdateScrollPosition()
&#9;end
end
function AttachScrollWheel()
&#9;if ScrollWheelConnections then return end
&#9;local pmouse = LocalPlayer:GetMouse()
&#9;ScrollWheelConnections = {}
&#9;table.insert(ScrollWheelConnections,pmouse.WheelForward:connect(function()
&#9;&#9;OnScrollWheelMove(.05)
&#9;end))
&#9;table.insert(ScrollWheelConnections,pmouse.WheelBackward:connect(function()
&#9;&#9;OnScrollWheelMove(-.05)
&#9;end))
end
function DetachScrollWheel()
&#9;if ScrollWheelConnections then
&#9;&#9;for _,i in pairs(ScrollWheelConnections) do
&#9;&#9;&#9;i:disconnect()
&#9;&#9;end
&#9;end
&#9;ScrollWheelConnections=nil
end
FocusFrame.MouseEnter:connect(function()
&#9;if not (IsMaximized.Value or IsMinimized.Value or IsTabified.Value) then
&#9;&#9;ExpandNames()
&#9;&#9;AttachScrollWheel()
&#9;&#9;BaseUpdate()
&#9;&#9;if IsTabified.Value then
&#9;&#9;&#9;Tabify()
&#9;&#9;end
&#9;end
end)
FocusFrame.MouseLeave:connect(function()
&#9;--if not (IsMaximized.Value or IsMinimized.Value) then
&#9;&#9;CloseNames()
&#9;&#9;DetachScrollWheel()
&#9;&#9;BaseUpdate()
&#9;&#9;if IsTabified.Value then
&#9;&#9;&#9;Tabify()
&#9;&#9;end
&#9;--end
end)
------------------------
-- Scroll Bar functions
------------------------
--[[
&#9;updates whether the scroll bar should be showing, if it is showing, updates
&#9;the size of it
--]]
function UpdateScrollBarVisibility()
&#9;if AreAllEntriesOnScreen() then
&#9;&#9;ScrollBar.BackgroundTransparency = 1
&#9;else
&#9;&#9;ScrollBar.BackgroundTransparency = 0
&#9;&#9;UpdateScrollBarSize()
&#9;end
end
--[[
&#9;updates size of scrollbar depending on how many entries exist
--]]
function UpdateScrollBarSize()
&#9;local entryListSize = #MiddleFrameBackgrounds * MiddleTemplate.Size.Y.Scale
&#9;local shownAreaSize = ((BottomClipFrame.Position.Y.Scale) + 1)
&#9;ScrollBar.Size = UDim2.new(1,0,shownAreaSize/entryListSize,0)
&#9;
end
--[[
&#9;updates position of listframe so that no gaps at the bottom or top of the list are visible
&#9;updates position of scrollbar to match what parts of the list are visible
--]]
function UpdateScrollPosition()
&#9;local minPos = GetMinScroll()
&#9;local maxPos = GetMaxScroll()
&#9;local scrollLength = maxPos - minPos
&#9;
&#9;local yscrollpos=math.max(math.min(ListFrame.Position.Y.Scale,maxPos),minPos)
&#9;ListFrame.Position=UDim2.new(ListFrame.Position.X.Scale,ListFrame.Position.X.Offset,yscrollpos,ListFrame.Position.Y.Offset)
&#9;
&#9;local adjustedLength = 1 - ScrollBar.Size.Y.Scale
&#9;ScrollBar.Position = UDim2.new(0,0,adjustedLength - (adjustedLength * ((ListFrame.Position.Y.Scale - minPos)/scrollLength)),0)
end
--[[
&#9;WARNING:this is in a working state, but uses massive hacks
&#9;revize when global input is available
&#9;Manages scrolling of the playerlist on mouse drag
--]]
function StartDrag()
&#9;Delay(0,function()
&#9;&#9;debugprint(&apos;Got Click&apos;)
&#9;&#9;local stopDrag = false
&#9;&#9;local function dragExit()
&#9;&#9;&#9;debugprint(&apos;undone click&apos;)
&#9;&#9;&#9;stopDrag = true
&#9;&#9;end
&#9;&#9;local startY = nil --AbsoluteToPercent(Mouse.X,Mouse.Y).Y
&#9;&#9;local StartFrame = ListFrame.Position
&#9;&#9;local function dragpoll(nx,ny)
&#9;&#9;&#9;if not startY then
&#9;&#9;&#9;&#9;startY = AbsoluteToPercent(nx,ny).Y
&#9;&#9;&#9;end
&#9;&#9;&#9;local nowY = AbsoluteToPercent(nx,ny).Y
&#9;&#9;&#9;local newFrameY
&#9;&#9;&#9;if OnIos then
&#9;&#9;&#9;&#9;newFrameY = math.max(math.min(StartFrame.Y.Scale + (nowY - startY),GetMaxScroll()),GetMinScroll())
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;newFrameY = math.max(math.min(StartFrame.Y.Scale - (nowY - startY),GetMaxScroll()),GetMinScroll())
&#9;&#9;&#9;end
&#9;&#9;&#9;ListFrame.Position = UDim2.new(StartFrame.X.Scale,StartFrame.X.Offset,newFrameY,StartFrame.Y.Offset)
&#9;&#9;&#9;UpdateScrollPosition()
&#9;&#9;end
&#9;&#9;Spawn(function() WaitForClick(ScreenGui,dragpoll,dragExit) end)
&#9;end)
end
-------------------------------
-- Input Callback functions
-------------------------------
IsMaximized.Value=false
IsMinimized.Value=false
IsMaximized.Changed:connect(UpdateMaximize)
IsMinimized.Changed:connect(UpdateMinimize)
ExtendButton.MouseButton1Click:connect(function()
&#9;if(time() - LastClick &lt; ButtonCooldown) then return end
&#9;LastClick = time()
&#9;UnTabify()
&#9;ToggleMinimize()
end)
MaximizeButton.MouseButton1Click:connect(function()
&#9;if(time() - LastClick &lt; ButtonCooldown) then return end
&#9;LastClick = time()
&#9;if IsTabified.Value then
&#9;&#9;UnTabify()
&#9;else
&#9;&#9;ToggleMaximize()
&#9;end
end)
MaximizeButton.MouseButton2Click:connect(function()
&#9;if(time() - LastClick &lt; ButtonCooldown) then return end
&#9;LastClick = time()
&#9;if IsTabified.Value then
&#9;&#9;UnTabify()
&#9;else
&#9;&#9;Tabify()
&#9;end
end)
-------------------------------
-- MiddleFrames management
-------------------------------
--[[
&#9;adds a background frame to the listframe
--]]
function AddMiddleBGFrame()
&#9;local nBGFrame = MiddleBGTemplate:Clone()
&#9;nBGFrame.Position = UDim2.new(.5,0,((#MiddleFrameBackgrounds) * nBGFrame.Size.Y.Scale),0)
&#9;if (#MiddleFrameBackgrounds+1)%2 ~= 1 then
&#9;&#9;if IsMaximized.Value then
&#9;&#9;&#9;nBGFrame.Background.Image = &apos;http://www.roblox.com/asset/?id=&apos;..Images[&apos;LargeDark&apos;]
&#9;&#9;else
&#9;&#9;&#9;nBGFrame.Background.Image = &apos;http://www.roblox.com/asset/?id=&apos;..Images[&apos;midDark&apos;]
&#9;&#9;end
&#9;else
&#9;&#9;if IsMaximized.Value then
&#9;&#9;&#9;nBGFrame.Background.Image = &apos;http://www.roblox.com/asset/?id=&apos;..Images[&apos;LargeLight&apos;]
&#9;&#9;else
&#9;&#9;&#9;nBGFrame.Background.Image = &apos;http://www.roblox.com/asset/?id=&apos;..Images[&apos;midLight&apos;]
&#9;&#9;end
&#9;end
&#9;nBGFrame.Parent = ListFrame
&#9;table.insert(MiddleFrameBackgrounds,nBGFrame)
&#9;if not IsMinimized.Value then
-- BottomFrame:TweenPosition(UDim2.new(0,0,((#MiddleFrameBackgrounds) * nBGFrame.Size.Y.Scale) + HeaderFrameHeight,0), &quot;Out&quot;, &quot;Quad&quot;, .5,true)
&#9;&#9;UpdateMinimize()
&#9;end
end
--[[
&#9;removes a background from from the listframe
--]]
function RemoveMiddleBGFrame()
&#9;MiddleFrameBackgrounds[#MiddleFrameBackgrounds]:Destroy()
&#9;table.remove(MiddleFrameBackgrounds,#MiddleFrameBackgrounds)
&#9;if not IsMinimized.Value then
-- BottomFrame:TweenPosition(UDim2.new(0,0,((#MiddleFrameBackgrounds) * MiddleTemplate.Size.Y.Scale) + HeaderFrameHeight,0), &quot;Out&quot;, &quot;Quad&quot;, .5)
&#9;&#9;UpdateMinimize()
&#9;end
end
-------------------------------
-- Player Callback functions
-------------------------------
local FONT_SIZES =
{&apos;Size8&apos;,&apos;Size9&apos;,&apos;Size10&apos;,&apos;Size11&apos;,&apos;Size12&apos;,&apos;Size14&apos;,&apos;Size24&apos;,&apos;Size36&apos;,&apos;Size48&apos;}
--[[
&#9;note:should probably set to something other than mainFrame.AbsoluteSize, should work for now
&#9;if textbounds ever works on textscaled, switch to that :(
--]]
function ChangeHeaderName(nname)
&#9;HeaderName.Text = nname
&#9;UpdateHeaderNameSize()
end
--[[
&#9;Will fit the player&apos;s name to the bounds of the header
&#9;called on resize of the window and playedr name change events
&#9;HACK: cannot use &apos;Textscaled&apos; due to unable to find text bounds when scaled
--]]
function UpdateHeaderNameSize()
&#9;local tHeader= HeaderName:Clone()
&#9;tHeader.Position=UDim2.new(2,0,2,0)
&#9;tHeader.Parent=ScreenGui
&#9;local fSize=7 --Size24 in table
&#9;tHeader.FontSize=FONT_SIZES[fSize]
&#9;Delay(.2,function()
&#9;&#9;while tHeader.TextBounds.x==0 do wait(1/30) end
&#9;&#9;while tHeader.TextBounds.x-(NormalBounds.X.Offset) &gt; 1 do
&#9;&#9;&#9;fSize=fSize-1
&#9;&#9;&#9;tHeader.FontSize=FONT_SIZES[fSize]
&#9;&#9;&#9;wait(.2)
&#9;&#9;end
&#9;&#9;HeaderName.FontSize=tHeader.FontSize
&#9;&#9;tHeader:Destroy()
&#9;end)
end
ScreenGui.Changed:connect(UpdateHeaderNameSize)
--[[
&#9;called only when the leaderstats object is added to a given player entry
&#9;removes old stats, adds any existing stats, and sets up listeners for new stats
&#9;@Args:
&#9;playerEntry&#9;&#9;A reference to the ENTRY(table) of the player who had leaderstats added
--]]
function LeaderstatsAdded(playerEntry)
&#9;--RemoveAllStats(playerEntry)
&#9;local nplayer = playerEntry[&apos;Player&apos;]
&#9;for _,i in pairs(nplayer.leaderstats:GetChildren()) do
&#9;&#9;StatAdded(i,playerEntry)
&#9;end
&#9;nplayer.leaderstats.ChildAdded:connect(function(nchild) StatAdded(nchild,playerEntry) end)
&#9;nplayer.leaderstats.ChildRemoved:connect(function(nchild) StatRemoved(nchild,playerEntry) end)
end
--[[
&#9;called when leaderstats object is removed from play in player entry
&#9;Note: may not be needed, might be able to just rely on leaderstats added
&#9;@Args:
&#9;oldLeaderstats&#9;leaderstats object to be removed
&#9;playerEntry&#9;&#9;A reference to the ENTRY(table) of the player
--]]
function LeaderstatsRemoved(oldLeaderstats,playerEntry)
&#9;while AddingFrameLock do debugprint(&apos;waiting to insert &apos;..playerEntry[&apos;Player&apos;].Name) wait(1/30) end
&#9;AddingFrameLock = true
&#9;RemoveAllStats(playerEntry)
&#9;AddingFrameLock = false
end
--[[
&#9;prepares the needed movingpanel to be tweened on screen, and updates the position of the popup clip
&#9;frame to match the selected player frame&apos;s position
&#9;@Args:
&#9;movingPanel&#9;&#9;The popup panel to tween on screen
--]]
function InitMovingPanel(movingPanel)
&#9;PopUpClipFrame.Parent= SelectedPlayerEntry[&apos;Frame&apos;]
&#9;PopUpClipFrame.Position = UDim2.new( 0,-PopUpClipFrame.Size.X.Offset,0,0)
&#9;movingPanel:TweenPosition(UDim2.new(0,0,0,0), &quot;Out&quot;, &quot;Quad&quot;, .5,true)
&#9;OnFriendPopUpOpen()
&#9;if IsPersonalServer then
&#9;&#9;HighlightMyRank(SelectedPlayer)
&#9;end
&#9;WaitForClick(ScreenGui,function() end,function(nx,ny)
&#9;&#9;movingPanel:TweenPosition(UDim2.new(1,0,0,0), &quot;Out&quot;, &quot;Quad&quot;, .5,true)
&#9;&#9;--connection:disconnect()
&#9;end)
&#9;
end
--[[
&#9;Called when a player entry in the leaderboard is clicked
&#9;either will highlight entry and start the drag event, or open a popup menu
&#9;@Args:
&#9;entry&#9;the player entry clicked
--]]
function OnPlayerEntrySelect(entry)
&#9;local movingPanel
&#9;--if this is a personal server, and you are an admin and the selected person is a lower rank than you, then...
&#9;if IsPersonalServer and LocalPlayer.PersonalServerRank &gt;= PrivilegeLevel[&apos;Admin&apos;] and LocalPlayer.PersonalServerRank &gt; SelectedPlayer.PersonalServerRank then
&#9;&#9;&#9;--and LocalPlayer.PersonalServerRank&gt;entry[&apos;Player&apos;].PersonalServerRank then
&#9;&#9;movingPanel=PersonalServerPanel
&#9;else
&#9;&#9;movingPanel=PopUpPanel
&#9;end
&#9;if entry == SelectedPlayerEntry and SelectedPlayer~=LocalPlayer and SelectedPlayer.userId&gt;1 and LocalPlayer.userId&gt;1 then
&#9;&#9;InPopupWaitForClick=true
&#9;&#9;WaitForClick(ScreenGui,function() end, function()
&#9;&#9;&#9;InitMovingPanel(movingPanel)
&#9;&#9;&#9;SelectedPlayerEntry = nil
&#9;&#9;&#9;inWaitForClick=false
&#9;&#9;end)
&#9;else
&#9;&#9;
&#9;&#9;--movingPanel:TweenPosition(UDim2.new(1,0,0,0), &quot;Out&quot;, &quot;Quad&quot;, .5,true)
&#9;&#9;SelectedPlayerEntry = entry
&#9;&#9;SelectedPlayer = entry[&apos;Player&apos;]
&#9;&#9;entry[&apos;Frame&apos;].BackgroundColor3 = Color3.new(0,1,1)
&#9;&#9;entry[&apos;Frame&apos;].BackgroundTransparency = .5
&#9;&#9;Spawn(function() TweenBackgroundTransparency(entry[&apos;Frame&apos;],.5,1,1) end)
&#9;&#9;Delay(1, function()
&#9;&#9;&#9;if not InPopupWaitForClick then
&#9;&#9;&#9;&#9;SelectedPlayerEntry = nil
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;&#9;StartDrag()
&#9;end
&#9;
end
--[[
&#9;the basic update for the playerlist mode&apos;s state,
&#9;assures the order and length of the player frames
--]]
function PlayerListModeUpdate()
&#9;RecreateScoreColumns(PlayerFrames)
&#9;table.sort(PlayerFrames,PlayerSortFunction)
&#9;for i,val in ipairs(PlayerFrames) do
&#9;&#9;MiddleFrames[i] = val[&apos;Frame&apos;]
&#9;end
&#9;for i = #PlayerFrames + 1,#MiddleFrames,1 do
&#9;&#9;MiddleFrames[i] = nil
&#9;end
&#9;UpdateMinimize()
end
--[[
&#9;this one&apos;s a doozie, happens when a player is added to the game
&#9;inits their player frame and player entry, assigns them to a team if possible,
&#9;and hooks up their leaderstats
&#9;@Args:
&#9;nplayer&#9;&#9;new player object to insert
--]]
function InsertPlayerFrame(nplayer)
&#9;while AddingFrameLock do debugprint(&apos;waiting to insert &apos;..nplayer.Name) wait(1/30) end
&#9;AddingFrameLock = true
&#9;
&#9;local nFrame = MiddleTemplate:Clone()
&#9;WaitForChild(WaitForChild(nFrame,&apos;TitleFrame&apos;),&apos;Title&apos;).Text = nplayer.Name
&#9;
&#9;nFrame.Position = UDim2.new(1,0,((#MiddleFrames) * nFrame.Size.Y.Scale),0)
&#9;
&#9;local nfriendstatus = GetFriendStatus(nplayer)
&#9;
&#9;nFrame:FindFirstChild(&apos;BCLabel&apos;).Image = getMembershipTypeIcon(nplayer.MembershipType,nplayer.Name)
&#9;nFrame:FindFirstChild(&apos;FriendLabel&apos;).Image = getFriendStatusIcon(nfriendstatus)
&#9;nFrame.Name = nplayer.Name
&#9;WaitForChild(WaitForChild(nFrame,&apos;TitleFrame&apos;),&apos;Title&apos;).Text = nplayer.Name
&#9;
&#9;--move for bc label
&#9;nFrame.FriendLabel.Position=nFrame.FriendLabel.Position+UDim2.new(0,17,0,0)
&#9;nFrame.TitleFrame.Title.Position=nFrame.TitleFrame.Title.Position+UDim2.new(0,17,0,0)
&#9;
&#9;if(nFrame:FindFirstChild(&apos;FriendLabel&apos;).Image ~= &apos;&apos;) then
&#9;&#9;nFrame.TitleFrame.Title.Position=nFrame.TitleFrame.Title.Position+UDim2.new(0,17,0,0)
&#9;&#9;--nFrame.FriendLabel.Position=nFrame.TitleFrame.Position+UDim2.new(nFrame.TitleFrame.Size.X.Scale,-20+nFrame.TitleFrame.Size.X.Offset,0,0)
&#9;end
&#9;
&#9;if nplayer.Name == LocalPlayer.Name then
&#9;&#9;nFrame.TitleFrame.Title.Font = &apos;ArialBold&apos;
&#9;&#9;nFrame.PlayerScore.Font = &apos;ArialBold&apos;
&#9;&#9;ChangeHeaderName(nplayer.Name)
&#9;&#9;local dropShadow = nFrame.TitleFrame.Title:Clone()
&#9;&#9;dropShadow.TextColor3 = Color3.new(0,0,0)
&#9;&#9;dropShadow.TextTransparency=0
&#9;&#9;dropShadow.ZIndex=2
&#9;&#9;dropShadow.Position=nFrame.TitleFrame.Title.Position+UDim2.new(0,1,0,1)
&#9;&#9;dropShadow.Name=&apos;DropShadow&apos;
&#9;&#9;dropShadow.Parent= nFrame.TitleFrame
&#9;elseif LocalPlayer:IsFriendsWith(nplayer.userId) then
&#9;&#9;
&#9;end
&#9;nFrame.TitleFrame.Title.Font = &apos;ArialBold&apos;
&#9;
&#9;nFrame.Parent = ListFrame
&#9;nFrame:TweenPosition(UDim2.new(.5,0,((#MiddleFrames) * nFrame.Size.Y.Scale),0), &quot;Out&quot;, &quot;Quad&quot;, .5,true)
&#9;UpdateMinimize()
&#9;local nentry = {}
&#9;nentry[&apos;Frame&apos;] = nFrame
&#9;nentry[&apos;Player&apos;] = nplayer
&#9;nentry[&apos;ID&apos;] = AddId
&#9;AddId = AddId + 1
&#9;table.insert(PlayerFrames,nentry)
&#9;if #TeamFrames~=0 then
&#9;&#9;
&#9;&#9;if nplayer.Neutral then
&#9;&#9;&#9;nentry[&apos;MyTeam&apos;] = nil
&#9;&#9;&#9;if not NeutralTeam then
&#9;&#9;&#9;&#9;AddNeutralTeam()
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;AddPlayerToTeam(NeutralTeam,nentry)
&#9;&#9;&#9;end
&#9;&#9;&#9;
&#9;&#9;else
&#9;&#9;&#9;local addedToTeam=false
&#9;&#9;&#9;for i,tval in ipairs(TeamFrames) do
&#9;&#9;&#9;&#9;if tval[&apos;MyTeam&apos;].TeamColor == nplayer.TeamColor then
&#9;&#9;&#9;&#9;&#9;AddPlayerToTeam(tval,nentry)
&#9;&#9;&#9;&#9;&#9;nentry[&apos;MyTeam&apos;] = tval
&#9;&#9;&#9;&#9;&#9;addedToTeam=true
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;if not addedToTeam then
&#9;&#9;&#9;&#9;nentry[&apos;MyTeam&apos;]=nil
&#9;&#9;&#9;&#9;if not NeutralTeam then
&#9;&#9;&#9;&#9;&#9;AddNeutralTeam()
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;AddPlayerToTeam(NeutralTeam,nentry)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;nentry[&apos;MyTeam&apos;] = NeutralTeam
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;
&#9;end
&#9;
&#9;if nplayer==LocalPlayer and nplayer:FindFirstChild(&apos;leaderstats&apos;) then
&#9;&#9;LeaderstatsAdded(nentry)
&#9;end
&#9;
&#9;nplayer.ChildAdded:connect(function(nchild)
&#9;&#9;if nplayer==LocalPlayer and nchild.Name == &apos;leaderstats&apos; then
&#9;&#9;&#9;while AddingFrameLock do debugprint(&apos;in adding leaderstats lock&apos;) wait(1/30) end
&#9;&#9;&#9;AddingFrameLock = true
&#9;&#9;&#9;LeaderstatsAdded(nentry)
&#9;&#9;&#9;AddingFrameLock = false
&#9;&#9;end
&#9;end)
&#9;nplayer.ChildRemoved:connect(function (nchild)
&#9;&#9;if nplayer==LocalPlayer and nchild.Name == &apos;leaderstats&apos; then
&#9;&#9;&#9;LeaderstatsRemoved(nchild,nentry)
&#9;&#9;end
&#9;end)
&#9;nplayer.Changed:connect(function(prop)PlayerChanged(nentry,prop) end)
&#9;
&#9;local listener = WaitForChild(nFrame,&apos;ClickListener&apos;)
&#9;listener.Active = true
&#9;listener.MouseButton1Down:connect(function() OnPlayerEntrySelect(nentry) end)
&#9;
&#9;AddMiddleBGFrame()
&#9;BaseUpdate()
&#9;AddingFrameLock = false
end
--[[
&#9;Note:major optimization can be done here
&#9;removes this player&apos;s frame if it exists, calls base update
--]]
function RemovePlayerFrame(tplayer)
&#9;while AddingFrameLock do debugprint(&apos;in removing player frame lock&apos;) wait(1/30) end
&#9;AddingFrameLock = true
&#9;
&#9;local tteam
&#9;for i,key in ipairs(PlayerFrames) do
&#9;&#9;if tplayer == key[&apos;Player&apos;] then
&#9;&#9;&#9;if PopUpClipFrame.Parent == key[&apos;Frame&apos;] then
&#9;&#9;&#9;&#9;PopUpClipFrame.Parent = nil
&#9;&#9;&#9;end
&#9;&#9;&#9;key[&apos;Frame&apos;]:Destroy()
&#9;&#9;&#9;tteam=key[&apos;MyTeam&apos;]
&#9;&#9;&#9;table.remove(PlayerFrames,i)
&#9;&#9;end
&#9;end
&#9;if tteam then
&#9;&#9;for j,tentry in ipairs(tteam[&apos;MyPlayers&apos;]) do
&#9;&#9;&#9;if tentry[&apos;Player&apos;] == tplayer then
&#9;&#9;&#9;&#9;RemovePlayerFromTeam(tteam,j)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;RemoveMiddleBGFrame()
&#9;UpdateMinimize()
&#9;BaseUpdate()
&#9;AddingFrameLock = false
end
Players.ChildRemoved:connect(RemovePlayerFrame)
----------------------------
-- Team Callback Functions
----------------------------
--[[
&#9;turns a list of team entries with sub lists of players into a single ordered
&#9;list, in the correct order,and of the correct length
&#9;@Args:
&#9;tframes&#9;&#9;the team entries to unroll
&#9;outframes&#9;the list to unroll these entries into
--]]
function UnrollTeams(tframes,outframes)
&#9;local numEntries = 0
&#9;if NeutralTeam and not NeutralTeam[&apos;IsHidden&apos;] then
&#9;&#9;for i,val in ipairs(NeutralTeam[&apos;MyPlayers&apos;]) do
&#9;&#9;&#9;numEntries = numEntries + 1
&#9;&#9;&#9;outframes[numEntries] = val[&apos;Frame&apos;]
&#9;&#9;end
&#9;&#9;numEntries = numEntries + 1
&#9;&#9;outframes[numEntries] = NeutralTeam[&apos;Frame&apos;]
&#9;end
&#9;for i,val in ipairs(tframes) do
&#9;&#9;if not val[&apos;IsHidden&apos;] then
&#9;&#9;&#9;for j,pval in ipairs(val.MyPlayers) do
&#9;&#9;&#9;&#9;numEntries = numEntries + 1
&#9;&#9;&#9;&#9;outframes[numEntries] = pval[&apos;Frame&apos;]
&#9;&#9;&#9;end
&#9;&#9;&#9;numEntries = numEntries + 1
&#9;&#9;&#9;outframes[numEntries] = val[&apos;Frame&apos;]
&#9;&#9;end
&#9;end
-- clear any additional entries from outframes
&#9;for i = numEntries + 1,#outframes,1 do
&#9;&#9;outframes[i] = nil
&#9;end
end
--[[
&#9;uses lua&apos;s table.sort to sort the teams
--]]
function TeamSortFunc(a,b)
&#9;if a[&apos;TeamScore&apos;] == b[&apos;TeamScore&apos;] then
&#9;&#9;return a[&apos;ID&apos;] &lt; b[&apos;ID&apos;]
&#9;end
&#9;if not a[&apos;TeamScore&apos;] then return false end
&#9;if not b[&apos;TeamScore&apos;] then return true end
&#9;return a[&apos;TeamScore&apos;] &lt; b[&apos;TeamScore&apos;]
end
--[[
&#9;consider adding lock with wait for performance
&#9;sorts each of the team&apos;s player lists induvidually, adds up the team scores.
&#9;@Args:
&#9;tentries&#9;&#9;table of team entries&#9;
--]]
function SortTeams(tentries)
&#9;
&#9;for i,val in ipairs(tentries) do
&#9;&#9;table.sort(val[&apos;MyPlayers&apos;],PlayerSortFunction)
&#9;&#9;AddTeamScores(val)
&#9;end
&#9;table.sort(tentries,TeamSortFunc)
end
--[[
&#9;base update for team mode, adds up the scores of all teams, sorts them,
&#9;then unrolls them into middleframes
--]]
function TeamListModeUpdate()
&#9;RecreateScoreColumns(PlayerFrames)
&#9;SortTeams(TeamFrames)
&#9;if NeutralTeam then
&#9;&#9;AddTeamScores(NeutralTeam)
&#9;&#9;--RecreateScoreColumns(NeutralTeam[&apos;MyPlayers&apos;])
&#9;end
&#9;UnrollTeams(TeamFrames,MiddleFrames)
end
--[[
&#9;adds up all the score of this team&apos;s players to form the team score
&#9;@Args:
&#9;team&#9;&#9;team entry to sum the scores of
--]]
function AddTeamScores(team)
&#9;
&#9;for j = 1, #ScoreNames,1 do
&#9;&#9;local i = ScoreNames[j]
&#9;&#9;local tscore = 0
&#9;&#9;for _,j in ipairs(team[&apos;MyPlayers&apos;]) do
&#9;&#9;&#9;if j[&apos;Player&apos;]:FindFirstChild(&apos;leaderstats&apos;) and j[&apos;Player&apos;].leaderstats:FindFirstChild(i[&apos;Name&apos;]) then
&#9;&#9;&#9;&#9;tscore = tscore + GetScoreValue(j[&apos;Player&apos;].leaderstats[i[&apos;Name&apos;]])
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;if team[&apos;Frame&apos;]:FindFirstChild(i[&apos;Name&apos;]) then
&#9;&#9;&#9;team[&apos;Frame&apos;][i[&apos;Name&apos;]].Size = UDim2.new(1 - (ScrollBarFrame.Size.X.Scale * 2),- ((j-1) * SpacingPerStat),TemplateFrameYSize,0)
&#9;&#9;&#9;team[&apos;Frame&apos;][i[&apos;Name&apos;]].Text = tostring(tscore)
&#9;&#9;end
&#9;end
&#9;UpdateMinimize()
end
--[[
&#9;finds previous team this player was on, and if it exists calls removeplayerfromteam
&#9;@Args
&#9;entry&#9;Player entry
--]]
function FindRemovePlayerFromTeam(entry)
&#9;if entry[&apos;MyTeam&apos;] then
&#9;&#9;for j,oldEntry in ipairs(entry[&apos;MyTeam&apos;][&apos;MyPlayers&apos;]) do
&#9;&#9;&#9;if oldEntry[&apos;Player&apos;] == entry[&apos;Player&apos;] then
&#9;&#9;&#9;&#9;RemovePlayerFromTeam(entry[&apos;MyTeam&apos;],j)
&#9;&#9;&#9;&#9;return
&#9;&#9;&#9;end
&#9;&#9;end
&#9;elseif NeutralTeam then
&#9;&#9;for j,oldEntry in ipairs(NeutralTeam[&apos;MyPlayers&apos;]) do
&#9;&#9;&#9;if oldEntry[&apos;Player&apos;] == entry[&apos;Player&apos;] then
&#9;&#9;&#9;&#9;RemovePlayerFromTeam(NeutralTeam,j)
&#9;&#9;&#9;&#9;return
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
end
--[[
&#9;removes a single player from a given team (not usually called directly)
&#9;@Args:
&#9;teamEntry&#9;&#9;team entry to remove player from
&#9;index&#9;&#9;&#9;index of player in &apos;MyPlayers&apos; list to remove
--]]
function RemovePlayerFromTeam(teamEntry,index)
&#9;table.remove(teamEntry[&apos;MyPlayers&apos;],index)
&#9;--if teamEntry[&apos;AutoHide&apos;] and #teamEntry[&apos;MyPlayers&apos;] == 0 then
&#9;if teamEntry==NeutralTeam and #teamEntry[&apos;MyPlayers&apos;]==0 then
&#9;&#9;RemoveNeutralTeam()
&#9;end
end
--[[
&#9;adds player entry entry to teamentry
&#9;removes them from any previous team
&#9;@Args:
&#9;teamEntry&#9;&#9;entry of team to add player to
&#9;entry&#9;&#9;&#9;player entry to add to this team
--]]
function AddPlayerToTeam(teamEntry,entry)
&#9;FindRemovePlayerFromTeam(entry)
&#9;table.insert(teamEntry[&apos;MyPlayers&apos;],entry)
&#9;entry[&apos;MyTeam&apos;] = teamEntry
&#9;if teamEntry[&apos;IsHidden&apos;] then
&#9;&#9;teamEntry[&apos;Frame&apos;].Parent = ListFrame
&#9;&#9;AddMiddleBGFrame()
&#9;end
&#9;teamEntry[&apos;IsHidden&apos;] = false
end
function SetPlayerToTeam(entry)
&#9;FindRemovePlayerFromTeam(entry)
&#9;-- check to see if team exists, if it does add to that team
&#9;local setToTeam = false
&#9;for i,tframe in ipairs(TeamFrames) do
&#9;-- add my entry on the new team
&#9;if tframe[&apos;MyTeam&apos;].TeamColor == entry[&apos;Player&apos;].TeamColor then
&#9;&#9;&#9;AddPlayerToTeam(tframe,entry)
&#9;&#9;&#9;setToTeam = true
&#9;&#9;end
&#9;end
&#9;-- if player was set to an invalid team, then set it back to neutral
&#9;if not setToTeam then
&#9;&#9;entry[&apos;MyTeam&apos;]=nil
&#9;&#9;if not NeutralTeam then
&#9;&#9;&#9;AddNeutralTeam()
&#9;&#9;else AddPlayerToTeam(NeutralTeam,entry) end
&#9;end
end
--[[
&#9;Note:another big one, consiter breaking up
&#9;called when any children of player changes
&#9;handles &apos;Neutral&apos;, teamColor, Name and MembershipType changes
&#9;@Args
&#9;entry&#9;&#9;Player entry changed
&#9;property&#9;name of property changed
--]]
function PlayerChanged(entry, property)
&#9;while PlayerChangedLock do
&#9;&#9;debugprint(&apos;in playerchanged lock&apos;)
&#9;&#9;wait(1/30)
&#9;end
&#9;PlayerChangedLock=true
&#9;if property == &apos;Neutral&apos; then
&#9;&#9;-- if player changing to neutral
&#9;&#9;if entry[&apos;Player&apos;].Neutral then
&#9;&#9;&#9;debugprint(entry[&apos;Player&apos;].Name..&apos;setting to neutral&apos;)
&#9;&#9;&#9;FindRemovePlayerFromTeam(entry)
&#9;&#9;&#9;entry[&apos;MyTeam&apos;]=nil
&#9;&#9;&#9;if not NeutralTeam then
&#9;&#9;&#9;&#9;debugprint(entry[&apos;Player&apos;].Name..&apos;creating neutral team&apos;)
&#9;&#9;&#9;&#9;AddNeutralTeam()
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;debugprint(entry[&apos;Player&apos;].Name..&apos;adding to neutral team&apos;)
&#9;&#9;&#9;&#9;AddPlayerToTeam(NeutralTeam,entry)
&#9;&#9;&#9;end
&#9;&#9;else&#9;-- else player switching to a team, or a weird edgecase
&#9;&#9;&#9;SetPlayerToTeam(entry)
&#9;&#9;end
&#9;elseif property == &apos;TeamColor&apos; and not entry[&apos;Player&apos;].Neutral and entry[&apos;Player&apos;] ~= entry[&apos;MyTeam&apos;] then
&#9;&#9;debugprint(entry[&apos;Player&apos;].Name..&apos;setting to new team&apos;)
&#9;&#9;SetPlayerToTeam(entry)
&#9;&#9;
&#9;elseif property == &apos;Name&apos; or property == &apos;MembershipType&apos; then
&#9;&#9;entry[&apos;Frame&apos;]:FindFirstChild(&apos;BCLabel&apos;).Image = getMembershipTypeIcon(entry[&apos;Player&apos;].MembershipType,entry[&apos;Player&apos;].Name)
&#9;&#9;entry[&apos;Frame&apos;].Name = entry[&apos;Player&apos;].Name
&#9;&#9;entry[&apos;Frame&apos;].TitleFrame.Title.Text = entry[&apos;Player&apos;].Name
&#9;&#9;if(entry[&apos;Frame&apos;].BCLabel.Image ~= &apos;&apos;) then
&#9;&#9;&#9;entry[&apos;Frame&apos;].TitleFrame.Title.Position=UDim2.new(.01, 30, .1, 0)
&#9;&#9;end
&#9;&#9;if entry[&apos;Player&apos;] == LocalPlayer then
&#9;&#9;&#9;entry[&apos;Frame&apos;].TitleFrame.DropShadow.Text= entry[&apos;Player&apos;].Name
&#9;&#9;&#9;ChangeHeaderName(entry[&apos;Player&apos;].Name)
&#9;&#9;end
&#9;end
&#9;BaseUpdate()
&#9;PlayerChangedLock=false
end
function OnFriendshipChanged(player,friendStatus)
&#9;for _, entry in ipairs(PlayerFrames) do
&#9;&#9;if entry[&apos;Player&apos;]==player then
&#9;&#9;&#9;local nicon = getFriendStatusIcon(friendStatus)
&#9;&#9;&#9;if nicon == &apos;&apos; and entry[&apos;Frame&apos;].FriendLabel.Image ~= &apos;&apos; then
&#9;&#9;&#9;&#9;entry[&apos;Frame&apos;].TitleFrame.Title.Position=entry[&apos;Frame&apos;].TitleFrame.Title.Position-UDim2.new(0,17,0,0)
&#9;&#9;&#9;elseif nicon ~= &apos;&apos; and entry[&apos;Frame&apos;].FriendLabel.Image == &apos;&apos; then
&#9;&#9;&#9;&#9;entry[&apos;Frame&apos;].TitleFrame.Title.Position=entry[&apos;Frame&apos;].TitleFrame.Title.Position+UDim2.new(0,17,0,0)
&#9;&#9;&#9;end
&#9;&#9;&#9;entry[&apos;Frame&apos;].FriendLabel.Image = nicon
&#9;&#9;&#9;return
&#9;&#9;end
&#9;end
end
LocalPlayer.FriendStatusChanged:connect(OnFriendshipChanged)
--[[
&#9;adds a neutral team if nessisary
&#9;Note: a lot of redundant code here, might want to refactor to share a function with insertteamframe
--]]
function AddNeutralTeam()
&#9;while NeutralTeamLock do debugprint(&apos;in neutral team 2 lock&apos;) wait() end
&#9;NeutralTeamLock = true
&#9;
&#9;local defaultTeam = Instance.new(&apos;Team&apos;)
&#9;defaultTeam.TeamColor = BrickColor.new(&apos;White&apos;)
&#9;defaultTeam.Name = &apos;Neutral&apos;
&#9;local nentry = {}
&#9;nentry[&apos;MyTeam&apos;] = defaultTeam
&#9;nentry[&apos;MyPlayers&apos;] = {}
&#9;nentry[&apos;Frame&apos;] = MiddleTemplate:Clone()
&#9;WaitForChild(WaitForChild(nentry[&apos;Frame&apos;],&apos;TitleFrame&apos;),&apos;Title&apos;).Text = defaultTeam.Name
&#9;nentry[&apos;Frame&apos;].TitleFrame.Position=UDim2.new(nentry[&apos;Frame&apos;].TitleFrame.Position.X.Scale,nentry[&apos;Frame&apos;].TitleFrame.Position.X.Offset,.1,0)
&#9;nentry[&apos;Frame&apos;].TitleFrame.Size=UDim2.new(nentry[&apos;Frame&apos;].TitleFrame.Size.X.Scale,nentry[&apos;Frame&apos;].TitleFrame.Size.X.Offset,.8,0)
&#9;--nentry[&apos;Frame&apos;].TitleFrame.Title.TextScaled=true
&#9;nentry[&apos;Frame&apos;].TitleFrame.Title.Font = &apos;ArialBold&apos;
&#9;nentry[&apos;Frame&apos;].Position = UDim2.new(1,0,((#MiddleFrames) * nentry[&apos;Frame&apos;].Size.Y.Scale),0)
&#9;WaitForChild(nentry[&apos;Frame&apos;],&apos;ClickListener&apos;).MouseButton1Down:connect(StartDrag)
&#9;nentry[&apos;Frame&apos;].ClickListener.BackgroundColor3 = Color3.new(1,1,1)
&#9;nentry[&apos;Frame&apos;].ClickListener.BackgroundTransparency = .7
&#9;nentry[&apos;Frame&apos;].ClickListener.AutoButtonColor=false
&#9;nentry[&apos;AutoHide&apos;] = true
&#9;nentry[&apos;IsHidden&apos;] = true
&#9;for _,i in pairs(PlayerFrames) do
&#9;&#9;if i[&apos;Player&apos;].Neutral or not i[&apos;MyTeam&apos;] then
&#9;&#9;&#9;AddPlayerToTeam(nentry,i)
&#9;&#9;end
&#9;end
&#9;if #nentry[&apos;MyPlayers&apos;] &gt; 0 then
&#9;&#9;NeutralTeam = nentry
&#9;&#9;UpdateMinimize()
&#9;&#9;BaseUpdate()
&#9;end
NeutralTeamLock = false
end
function RemoveNeutralTeam()
&#9;while NeutralTeamLock do debugprint(&apos;in neutral team lock&apos;) wait() end
&#9;NeutralTeamLock = true
&#9;NeutralTeam[&apos;Frame&apos;]:Destroy()
&#9;NeutralTeam=nil
&#9;RemoveMiddleBGFrame()
&#9;NeutralTeamLock = false
end
--[[
&#9;
--]]
function TeamScoreChanged(entry,nscore)
&#9;WaitForChild(entry[&apos;Frame&apos;],&apos;PlayerScore&apos;).Text = tostring(nscore)
&#9;entry[&apos;TeamScore&apos;] = nscore
end
--[[
&#9;called when child added to a team, used for autohide functionality
&#9;Note: still has teamscore, consiter removing
--]]
function TeamChildAdded(entry,nchild)
&#9;if nchild.Name == &apos;AutoHide&apos; then
&#9;&#9;entry[&apos;AutoHide&apos;] = true
&#9;elseif nchild.Name == &apos;TeamScore&apos; then
&#9;&#9;WaitForChild(entry[&apos;Frame&apos;],&apos;PlayerScore&apos;).Text = tostring(nchild.Value)
&#9;&#9;entry[&apos;TeamScore&apos;] = nchild.Value
&#9;&#9;nchild.Changed:connect(function() TeamScoreChanged(entry,nchild.Value) end)
&#9;end
end
--[[
&#9;called when child added to a team, used for autohide functionality
&#9;Note: still has teamscore, consiter removing
--]]
function TeamChildRemoved(entry,nchild)
&#9;if nchild.Name == &apos;AutoHide&apos; then
&#9;&#9;entry[&apos;AutoHide&apos;] = false
&#9;elseif nchild.Name == &apos;TeamScore&apos; then
&#9;&#9;WaitForChild(entry[&apos;Frame&apos;],&apos;PlayerScore&apos;).Text = &quot;&quot;
&#9;&#9;entry[&apos;TeamScore&apos;] = nil
&#9;end
end
--[[
&#9;creates team entry and frame for this team, sets up listeners for this team
&#9;adds any players intended for this team,Creates neutral team if this is the first team added
&#9;Note:might be best to break this into multiple functions to simplify
&#9;@Args:
&#9;nteam&#9;new team object added
--]]
function InsertTeamFrame(nteam)
&#9;while AddingFrameLock do debugprint(&apos;in adding team frame lock&apos;) wait(1/30) end
&#9;AddingFrameLock = true
&#9;local nentry = {}
&#9;nentry[&apos;MyTeam&apos;] = nteam
&#9;nentry[&apos;MyPlayers&apos;] = {}
&#9;nentry[&apos;Frame&apos;] = MiddleTemplate:Clone()
&#9;WaitForChild(WaitForChild(nentry[&apos;Frame&apos;],&apos;TitleFrame&apos;),&apos;Title&apos;).Text = nteam.Name
&#9;nentry[&apos;Frame&apos;].TitleFrame.Title.Font = &apos;ArialBold&apos;
&#9;nentry[&apos;Frame&apos;].TitleFrame.Position=UDim2.new(nentry[&apos;Frame&apos;].TitleFrame.Position.X.Scale,nentry[&apos;Frame&apos;].TitleFrame.Position.X.Offset,.1,0)
&#9;nentry[&apos;Frame&apos;].TitleFrame.Size=UDim2.new(nentry[&apos;Frame&apos;].TitleFrame.Size.X.Scale,nentry[&apos;Frame&apos;].TitleFrame.Size.X.Offset,.8,0)
&#9;--nentry[&apos;Frame&apos;].TitleFrame.Title.TextScaled=true
&#9;nentry[&apos;Frame&apos;].Position = UDim2.new(1,0,((#MiddleFrames) * nentry[&apos;Frame&apos;].Size.Y.Scale),0)
&#9;WaitForChild(nentry[&apos;Frame&apos;],&apos;ClickListener&apos;).MouseButton1Down:connect(StartDrag)
&#9;nentry[&apos;Frame&apos;].ClickListener.BackgroundColor3 = nteam.TeamColor.Color
&#9;nentry[&apos;Frame&apos;].ClickListener.BackgroundTransparency = .7
&#9;nentry[&apos;Frame&apos;].ClickListener.AutoButtonColor=false
&#9;AddId = AddId + 1
&#9;nentry[&apos;ID&apos;] = AddId
&#9;nentry[&apos;AutoHide&apos;] = false
&#9;if nteam:FindFirstChild(&apos;AutoHide&apos;) then
&#9;&#9;nentry[&apos;AutoHide&apos;] = true
&#9;end
&#9;if nteam:FindFirstChild(&apos;TeamScore&apos;) then
&#9;&#9;TeamChildAdded(nentry,nteam.TeamScore)
&#9;&#9;
&#9;end
&#9;nteam.ChildAdded:connect(function(nchild) TeamChildAdded(nentry,nchild) end)
&#9;nteam.ChildRemoved:connect(function(nchild) TeamChildRemoved(nentry,nchild) end)
&#9;for _,i in pairs(PlayerFrames) do
&#9;&#9;if not i[&apos;Player&apos;].Neutral and i[&apos;Player&apos;].TeamColor == nteam.TeamColor then
&#9;&#9;&#9;AddPlayerToTeam(nentry,i)
&#9;&#9;end
&#9;end
&#9;nentry[&apos;IsHidden&apos;] = false
&#9;if not nentry[&apos;AutoHide&apos;] or #nentry[&apos;MyPlayers&apos;] &gt; 0 then
&#9;&#9;
&#9;&#9;nentry[&apos;Frame&apos;].Parent = ListFrame
&#9;&#9;nentry[&apos;Frame&apos;]:TweenPosition(UDim2.new(.5,0,((#MiddleFrames) * nentry[&apos;Frame&apos;].Size.Y.Scale),0), &quot;Out&quot;, &quot;Quad&quot;, .5,true)
&#9;&#9;AddMiddleBGFrame()
&#9;else
&#9;&#9;nentry[&apos;IsHidden&apos;] = true
&#9;&#9;nentry[&apos;Frame&apos;].Parent = nil
&#9;end
&#9;table.insert(TeamFrames,nentry)
&#9;UpdateMinimize()
&#9;BaseUpdate()
&#9;if #TeamFrames == 1 and not NeutralTeam then
&#9;&#9;AddNeutralTeam()
&#9;end
&#9;AddingFrameLock = false
end
--[[
&#9;removes team from team list
&#9;@Args:
&#9;nteam&#9;&#9;Teamobject to remove
--]]
function RemoveTeamFrame(nteam)
&#9;while AddingFrameLock do debugprint(&apos;in removing team frame lock&apos;) wait(1/30) end
&#9;AddingFrameLock = true
&#9;if IsMinimized.Value then
-- ListFrame.Position = ListFrame.Position + UDim2.new(0,0,MiddleTemplate.Size.Y.Scale,0)
&#9;end
&#9;local myEntry
&#9;for i,key in ipairs(TeamFrames) do
&#9;&#9;if nteam == key[&apos;MyTeam&apos;] then
&#9;&#9;&#9;myEntry = key
&#9;&#9;&#9;key[&apos;Frame&apos;]:Destroy()
&#9;&#9;&#9;table.remove(TeamFrames,i)
&#9;&#9;end
&#9;end
&#9;if #TeamFrames==0 then
&#9;&#9;if NeutralTeam then
&#9;&#9;&#9;RemoveNeutralTeam()
&#9;&#9;end
&#9;end
&#9;for i,key in ipairs(myEntry[&apos;MyPlayers&apos;]) do
&#9;&#9;RemovePlayerFromTeam(myEntry,i)
&#9;&#9;PlayerChanged(key, &apos;TeamColor&apos;)
&#9;end
&#9;RemoveMiddleBGFrame()
&#9;BaseUpdate()
&#9;AddingFrameLock = false
end
function TeamAdded(nteam)
&#9;InsertTeamFrame(nteam)
end
function TeamRemoved(nteam)
&#9;RemoveTeamFrame(nteam)
end
---------------------------------
--[[
&#9;called when ANYTHING changes the state of the playerlist
&#9;re-sorts everything,assures correct positions of all elements
--]]
function BaseUpdate()
&#9;while BaseUpdateLock do debugprint(&apos;in baseupdate lock&apos;) wait(1/30) end
&#9;BaseUpdateLock = true
&#9;if #TeamFrames == 0 then
&#9;&#9;PlayerListModeUpdate()
&#9;else
&#9;&#9;TeamListModeUpdate()
&#9;end
&#9;for i,key in ipairs(MiddleFrames) do
&#9;&#9;if key.Parent ~= nil then
&#9;&#9;&#9;key:TweenPosition(UDim2.new(.5,0,((#MiddleFrames - (i)) * key.Size.Y.Scale),0), &quot;Out&quot;, &quot;Quad&quot;, .9,true)
&#9;&#9;end
&#9;end
&#9;if not IsMinimized.Value and #MiddleFrames&gt;DefaultEntriesOnScreen then
&#9;&#9;UpdateScrollPosition()
&#9;end
&#9;UpdateScrollBarVisibility()
&#9;debugprint(&apos;EndBaseUpdate&apos;)
&#9;BaseUpdateLock = false
end
--[[
&#9;code for attaching tab key to maximizing player list
--]]
game.GuiService:AddKey(&quot;\t&quot;)
local LastTabTime = time()
game.GuiService.KeyPressed:connect(
function(key)
&#9;if key == &quot;\t&quot; then
&#9;&#9;debugprint(&apos;caught tab key&apos;)
&#9;&#9;local modalCheck, isModal = pcall(function() return game.GuiService.IsModalDialog end)
&#9;&#9;if modalCheck == false or (modalCheck and isModal == false) then
&#9;&#9;&#9;if time() - LastTabTime &gt; 0.4 then
&#9;&#9;&#9;&#9;LastTabTime = time()
&#9;&#9;&#9;&#9;if IsTabified.Value then
&#9;&#9;&#9;&#9;&#9;if not IsMaximized.Value then
&#9;&#9;&#9;&#9;&#9;&#9;ScreenGui:TweenPosition(UDim2.new(0, 0, 0,0),&apos;Out&apos;,&apos;Quad&apos;,1,true)
&#9;&#9;&#9;&#9;&#9;&#9;IsMaximized.Value = true
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;ScreenGui:TweenPosition(UDim2.new(NormalBounds.X.Scale, NormalBounds.X.Offset-10, 0,0),&apos;Out&apos;,&apos;Quad&apos;,1,true)
&#9;&#9;&#9;&#9;&#9;&#9;IsMaximized.Value = false
&#9;&#9;&#9;&#9;&#9;&#9;IsMinimized.Value=true
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;ToggleMaximize()
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
end)
----------------------------
-- Hookups and initialization
----------------------------
function debugPlayerAdd(p)
&#9;InsertPlayerFrame(p)
end
while not game:GetService(&apos;Teams&apos;) do wait(1/30) debugprint(&apos;Waiting For Teams&apos;) end
for _,i in pairs(game.Teams:GetTeams()) do TeamAdded(i) end
for _,i in pairs(Players:GetPlayers()) do Spawn(function() debugPlayerAdd(i) end) end--InsertPlayerFrame(i) end
game.Teams.ChildAdded:connect(TeamAdded)
game.Teams.ChildRemoved:connect(TeamRemoved)
Players.ChildAdded:connect(function(tplayer) Spawn(function() debugPlayerAdd(tplayer) end) end)--InsertPlayerFrame)
InitReportAbuse()
BaseUpdate()
--UGGGLY,find a better way later
wait(2)
IsPersonalServer= not not game.Workspace:FindFirstChild(&quot;PSVariable&quot;)
----------------------------
-- Running Logic
----------------------------
--debug stuffs, will only run for &apos;newplayerlistisbad&apos;
--REMOVEME
if LocalPlayer.Name == &apos;newplayerlistisbad&apos; then
&#9;debugFrame.Parent = ScreenGui
&#9;Spawn(function()
&#9;&#9;while true do
&#9;&#9;&#9;local str_players=&apos;&apos;
&#9;&#9;&#9;for _,i in pairs(game.Players:GetPlayers()) do
&#9;&#9;&#9;&#9;str_players= str_players ..&quot; &quot; .. i.Name
&#9;&#9;&#9;end
&#9;&#9;&#9;debugplayers.Text=str_players
&#9;&#9;&#9;wait(.5)
&#9;&#9;end
&#9;end)
end
function EnsureValidity()
&#9;while true do
&#9;&#9;--make sure all players are in the player list
&#9;&#9;--and make sure there are no entries that corespond to non-existant players
&#9;&#9;local unfoundEntries={}
&#9;&#9;for k,v in pairs(PlayerFrames) do
&#9;&#9;&#9;unfoundEntries[k] = v
&#9;&#9;end
&#9;&#9;--for all players
&#9;&#9;for _,i in pairs(Players:GetPlayers()) do
&#9;&#9;&#9;local foundPlayer=false
&#9;&#9;&#9;--for all known players
&#9;&#9;&#9;for entryIndex,j in pairs(PlayerFrames) do
&#9;&#9;&#9;&#9;-- if I know about this player, tag it
&#9;&#9;&#9;&#9;if i==j[&apos;Player&apos;] then
&#9;&#9;&#9;&#9;&#9;foundPlayer=true
&#9;&#9;&#9;&#9;&#9;unfoundEntries[entryIndex]=nil
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;--if this player is not known
&#9;&#9;&#9;if not foundPlayer then
&#9;&#9;&#9;&#9;wait(.5)
&#9;&#9;&#9;&#9;--do a double check
&#9;&#9;&#9;&#9;for _,j in pairs(PlayerFrames) do
&#9;&#9;&#9;&#9;&#9;if i==j[&apos;Player&apos;] then
&#9;&#9;&#9;&#9;&#9;&#9;foundPlayer=true
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if not foundPlayer then
&#9;&#9;&#9;&#9;&#9;InsertPlayerFrame(i)
&#9;&#9;&#9;&#9;&#9;debugOutput.Text= &quot;Manual Insertion! &quot; .. i.Name
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;
&#9;&#9;end
&#9;&#9;--for any additional entries, never found, remove them
&#9;&#9;for _,j in pairs(unfoundEntries) do
&#9;&#9;&#9;RemovePlayerFrame(j[&apos;Player&apos;])
&#9;&#9;&#9;debugOutput.Text= &quot;Player Manual Removal! &quot; ..j[&apos;Player&apos;].Name
&#9;&#9;end
&#9;&#9;wait(1/30)
&#9;&#9;--make sure there are no gaps or overlaps in the playerlist
&#9;&#9;while GetEntryListLength()&gt;#MiddleFrameBackgrounds do
&#9;&#9;&#9;AddMiddleBGFrame()
&#9;&#9;end
&#9;&#9;while GetEntryListLength()&lt;#MiddleFrameBackgrounds do
&#9;&#9;&#9;RemoveMiddleBGFrame()
&#9;&#9;end
&#9;&#9;wait(1/30)
&#9;&#9;--remove neutral team if it shouldn&apos;t exist
&#9;&#9;if NeutralTeam and (#NeutralTeam[&apos;MyPlayers&apos;]==0 or #TeamFrames==0) then
&#9;&#9;&#9;wait(.5)
&#9;&#9;&#9;if NeutralTeam and (#NeutralTeam[&apos;MyPlayers&apos;]==0 or #TeamFrames==0) then
&#9;&#9;&#9;&#9;RemoveNeutralTeam()
&#9;&#9;&#9;&#9;debugOutput.Text= &quot;Manual removal of neutral team! &quot;
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;wait(1/30)
&#9;&#9;--do a base update, just ot be sure
&#9;&#9;BaseUpdate()
&#9;&#9;wait(1/30)
&#9;&#9;
&#9;end
end
--quick fix running logic, PLEASE LET ME REPLACE LATER
--Spawn(EnsureValidity)
</ProtectedString>
</Properties>
</Item>
</Item>
<Item class="Script" referent="RBX38">
<Properties>
<bool name="Disabled">true</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">TimeoutScript</string>
<ProtectedString name="Source">wait(5)
local dialog = script.Parent
if dialog:IsA(&quot;Dialog&quot;) then
&#9;dialog.InUse = false
end&#9;
script:Remove()
</ProtectedString>
</Properties>
</Item>
<Item class="Script" referent="RBX39">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">ResetCommand</string>
<ProtectedString name="Source">function onChatted(msg, speaker)
source = string.lower(speaker.Name)
msg = string.lower(msg)
-- Note: This one is NOT caps sensitive
if msg == &quot;!!!reset&quot; 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)</ProtectedString>
</Properties>
</Item>
<Item class="Script" referent="RBX40">
<Properties>
<bool name="Disabled">true</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">ReenableDialogScript</string>
<ProtectedString name="Source">wait(5)
local dialog = script.Parent
if dialog:IsA(&quot;Dialog&quot;) then
&#9;dialog.InUse = false
end&#9;
script:Remove()
</ProtectedString>
</Properties>
</Item>
<Item class="ScreenGui" referent="RBX41">
<Properties>
<string name="Name">Chat</string>
</Properties>
<Item class="LocalScript" referent="RBX42">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">ChatScript</string>
<ProtectedString name="Source">--rbxsig%JEfYnuC18EOdJ5gffQHlphGalfinD7ZNa+lFyYhYGQmQKlc/17N4PkAlQOjn7p5BdnyvBX3SUw7sweW90l/eUVzzt3dV/Vm63x6KIHjG8HLPwkxKCrtLbV4Mnw5q6mIS1A3GYXDkd3HG5iKgRfQHlCaCut4VQXquAtSITfkUJhc=%
--rbxassetid%60595411%
local t = {}
--JSON Encoder and Parser for Lua 5.1
--
--Copyright 2007 Shaun Brown (http://www.chipmunkav.com)
--All Rights Reserved.
--Permission is hereby granted, free of charge, to any person
--obtaining a copy of this software to deal in the Software without
--restriction, including without limitation the rights to use,
--copy, modify, merge, publish, distribute, sublicense, and/or
--sell copies of the Software, and to permit persons to whom the
--Software is furnished to do so, subject to the following conditions:
--The above copyright notice and this permission notice shall be
--included in all copies or substantial portions of the Software.
--If you find this software useful please give www.chipmunkav.com a mention.
--THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,
--EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
--OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
--IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
--ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
--CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
--CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
local string = string
local math = math
local table = table
local error = error
local tonumber = tonumber
local tostring = tostring
local type = type
local setmetatable = setmetatable
local pairs = pairs
local ipairs = ipairs
local assert = assert
local Chipmunk = Chipmunk
local StringBuilder = {
&#9;buffer = {}
}
function StringBuilder:New()
&#9;local o = {}
&#9;setmetatable(o, self)
&#9;self.__index = self
&#9;o.buffer = {}
&#9;return o
end
function StringBuilder:Append(s)
&#9;self.buffer[#self.buffer+1] = s
end
function StringBuilder:ToString()
&#9;return table.concat(self.buffer)
end
local JsonWriter = {
&#9;backslashes = {
&#9;&#9;[&apos;\b&apos;] = &quot;\\b&quot;,
&#9;&#9;[&apos;\t&apos;] = &quot;\\t&quot;,&#9;
&#9;&#9;[&apos;\n&apos;] = &quot;\\n&quot;,
&#9;&#9;[&apos;\f&apos;] = &quot;\\f&quot;,
&#9;&#9;[&apos;\r&apos;] = &quot;\\r&quot;,
&#9;&#9;[&apos;&quot;&apos;] = &quot;\\\&quot;&quot;,
&#9;&#9;[&apos;\\&apos;] = &quot;\\\\&quot;,
&#9;&#9;[&apos;/&apos;] = &quot;\\/&quot;
&#9;}
}
function JsonWriter:New()
&#9;local o = {}
&#9;o.writer = StringBuilder:New()
&#9;setmetatable(o, self)
&#9;self.__index = self
&#9;return o
end
function JsonWriter:Append(s)
&#9;self.writer:Append(s)
end
function JsonWriter:ToString()
&#9;return self.writer:ToString()
end
function JsonWriter:Write(o)
&#9;local t = type(o)
&#9;if t == &quot;nil&quot; then
&#9;&#9;self:WriteNil()
&#9;elseif t == &quot;boolean&quot; then
&#9;&#9;self:WriteString(o)
&#9;elseif t == &quot;number&quot; then
&#9;&#9;self:WriteString(o)
&#9;elseif t == &quot;string&quot; then
&#9;&#9;self:ParseString(o)
&#9;elseif t == &quot;table&quot; then
&#9;&#9;self:WriteTable(o)
&#9;elseif t == &quot;function&quot; then
&#9;&#9;self:WriteFunction(o)
&#9;elseif t == &quot;thread&quot; then
&#9;&#9;self:WriteError(o)
&#9;elseif t == &quot;userdata&quot; then
&#9;&#9;self:WriteError(o)
&#9;end
end
function JsonWriter:WriteNil()
&#9;self:Append(&quot;null&quot;)
end
function JsonWriter:WriteString(o)
&#9;self:Append(tostring(o))
end
function JsonWriter:ParseString(s)
&#9;self:Append(&apos;&quot;&apos;)
&#9;self:Append(string.gsub(s, &quot;[%z%c\\\&quot;/]&quot;, function(n)
&#9;&#9;local c = self.backslashes[n]
&#9;&#9;if c then return c end
&#9;&#9;return string.format(&quot;\\u%.4X&quot;, string.byte(n))
&#9;end))
&#9;self:Append(&apos;&quot;&apos;)
end
function JsonWriter:IsArray(t)
&#9;local count = 0
&#9;local isindex = function(k)
&#9;&#9;if type(k) == &quot;number&quot; and k &gt; 0 then
&#9;&#9;&#9;if math.floor(k) == k then
&#9;&#9;&#9;&#9;return true
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;return false
&#9;end
&#9;for k,v in pairs(t) do
&#9;&#9;if not isindex(k) then
&#9;&#9;&#9;return false, &apos;{&apos;, &apos;}&apos;
&#9;&#9;else
&#9;&#9;&#9;count = math.max(count, k)
&#9;&#9;end
&#9;end
&#9;return true, &apos;[&apos;, &apos;]&apos;, count
end
function JsonWriter:WriteTable(t)
&#9;local ba, st, et, n = self:IsArray(t)
&#9;self:Append(st)&#9;
&#9;if ba then&#9;&#9;
&#9;&#9;for i = 1, n do
&#9;&#9;&#9;self:Write(t[i])
&#9;&#9;&#9;if i &lt; n then
&#9;&#9;&#9;&#9;self:Append(&apos;,&apos;)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;else
&#9;&#9;local first = true;
&#9;&#9;for k, v in pairs(t) do
&#9;&#9;&#9;if not first then
&#9;&#9;&#9;&#9;self:Append(&apos;,&apos;)
&#9;&#9;&#9;end
&#9;&#9;&#9;first = false;&#9;&#9;&#9;
&#9;&#9;&#9;self:ParseString(k)
&#9;&#9;&#9;self:Append(&apos;:&apos;)
&#9;&#9;&#9;self:Write(v)&#9;&#9;&#9;
&#9;&#9;end
&#9;end
&#9;self:Append(et)
end
function JsonWriter:WriteError(o)
&#9;error(string.format(
&#9;&#9;&quot;Encoding of %s unsupported&quot;,
&#9;&#9;tostring(o)))
end
function JsonWriter:WriteFunction(o)
&#9;if o == Null then
&#9;&#9;self:WriteNil()
&#9;else
&#9;&#9;self:WriteError(o)
&#9;end
end
local StringReader = {
&#9;s = &quot;&quot;,
&#9;i = 0
}
function StringReader:New(s)
&#9;local o = {}
&#9;setmetatable(o, self)
&#9;self.__index = self
&#9;o.s = s or o.s
&#9;return o&#9;
end
function StringReader:Peek()
&#9;local i = self.i + 1
&#9;if i &lt;= #self.s then
&#9;&#9;return string.sub(self.s, i, i)
&#9;end
&#9;return nil
end
function StringReader:Next()
&#9;self.i = self.i+1
&#9;if self.i &lt;= #self.s then
&#9;&#9;return string.sub(self.s, self.i, self.i)
&#9;end
&#9;return nil
end
function StringReader:All()
&#9;return self.s
end
local JsonReader = {
&#9;escapes = {
&#9;&#9;[&apos;t&apos;] = &apos;\t&apos;,
&#9;&#9;[&apos;n&apos;] = &apos;\n&apos;,
&#9;&#9;[&apos;f&apos;] = &apos;\f&apos;,
&#9;&#9;[&apos;r&apos;] = &apos;\r&apos;,
&#9;&#9;[&apos;b&apos;] = &apos;\b&apos;,
&#9;}
}
function JsonReader:New(s)
&#9;local o = {}
&#9;o.reader = StringReader:New(s)
&#9;setmetatable(o, self)
&#9;self.__index = self
&#9;return o;
end
function JsonReader:Read()
&#9;self:SkipWhiteSpace()
&#9;local peek = self:Peek()
&#9;if peek == nil then
&#9;&#9;error(string.format(
&#9;&#9;&#9;&quot;Nil string: &apos;%s&apos;&quot;,
&#9;&#9;&#9;self:All()))
&#9;elseif peek == &apos;{&apos; then
&#9;&#9;return self:ReadObject()
&#9;elseif peek == &apos;[&apos; then
&#9;&#9;return self:ReadArray()
&#9;elseif peek == &apos;&quot;&apos; then
&#9;&#9;return self:ReadString()
&#9;elseif string.find(peek, &quot;[%+%-%d]&quot;) then
&#9;&#9;return self:ReadNumber()
&#9;elseif peek == &apos;t&apos; then
&#9;&#9;return self:ReadTrue()
&#9;elseif peek == &apos;f&apos; then
&#9;&#9;return self:ReadFalse()
&#9;elseif peek == &apos;n&apos; then
&#9;&#9;return self:ReadNull()
&#9;elseif peek == &apos;/&apos; then
&#9;&#9;self:ReadComment()
&#9;&#9;return self:Read()
&#9;else
&#9;&#9;return nil
&#9;end
end
&#9;&#9;
function JsonReader:ReadTrue()
&#9;self:TestReservedWord{&apos;t&apos;,&apos;r&apos;,&apos;u&apos;,&apos;e&apos;}
&#9;return true
end
function JsonReader:ReadFalse()
&#9;self:TestReservedWord{&apos;f&apos;,&apos;a&apos;,&apos;l&apos;,&apos;s&apos;,&apos;e&apos;}
&#9;return false
end
function JsonReader:ReadNull()
&#9;self:TestReservedWord{&apos;n&apos;,&apos;u&apos;,&apos;l&apos;,&apos;l&apos;}
&#9;return nil
end
function JsonReader:TestReservedWord(t)
&#9;for i, v in ipairs(t) do
&#9;&#9;if self:Next() ~= v then
&#9;&#9;&#9; error(string.format(
&#9;&#9;&#9;&#9;&quot;Error reading &apos;%s&apos;: %s&quot;,
&#9;&#9;&#9;&#9;table.concat(t),
&#9;&#9;&#9;&#9;self:All()))
&#9;&#9;end
&#9;end
end
function JsonReader:ReadNumber()
local result = self:Next()
local peek = self:Peek()
while peek ~= nil and string.find(
&#9;&#9;peek,
&#9;&#9;&quot;[%+%-%d%.eE]&quot;) do
result = result .. self:Next()
peek = self:Peek()
&#9;end
&#9;result = tonumber(result)
&#9;if result == nil then
&#9; error(string.format(
&#9;&#9;&#9;&quot;Invalid number: &apos;%s&apos;&quot;,
&#9;&#9;&#9;result))
&#9;else
&#9;&#9;return result
&#9;end
end
function JsonReader:ReadString()
&#9;local result = &quot;&quot;
&#9;assert(self:Next() == &apos;&quot;&apos;)
while self:Peek() ~= &apos;&quot;&apos; do
&#9;&#9;local ch = self:Next()
&#9;&#9;if ch == &apos;\\&apos; then
&#9;&#9;&#9;ch = self:Next()
&#9;&#9;&#9;if self.escapes[ch] then
&#9;&#9;&#9;&#9;ch = self.escapes[ch]
&#9;&#9;&#9;end
&#9;&#9;end
result = result .. ch
&#9;end
assert(self:Next() == &apos;&quot;&apos;)
&#9;local fromunicode = function(m)
&#9;&#9;return string.char(tonumber(m, 16))
&#9;end
&#9;return string.gsub(
&#9;&#9;result,
&#9;&#9;&quot;u%x%x(%x%x)&quot;,
&#9;&#9;fromunicode)
end
function JsonReader:ReadComment()
assert(self:Next() == &apos;/&apos;)
local second = self:Next()
if second == &apos;/&apos; then
self:ReadSingleLineComment()
elseif second == &apos;*&apos; then
self:ReadBlockComment()
else
error(string.format(
&#9;&#9;&quot;Invalid comment: %s&quot;,
&#9;&#9;self:All()))
&#9;end
end
function JsonReader:ReadBlockComment()
&#9;local done = false
&#9;while not done do
&#9;&#9;local ch = self:Next()&#9;&#9;
&#9;&#9;if ch == &apos;*&apos; and self:Peek() == &apos;/&apos; then
&#9;&#9;&#9;done = true
end
&#9;&#9;if not done and
&#9;&#9;&#9;ch == &apos;/&apos; and
&#9;&#9;&#9;self:Peek() == &quot;*&quot; then
error(string.format(
&#9;&#9;&#9;&quot;Invalid comment: %s, &apos;/*&apos; illegal.&quot;,
&#9;&#9;&#9;self:All()))
&#9;&#9;end
&#9;end
&#9;self:Next()
end
function JsonReader:ReadSingleLineComment()
&#9;local ch = self:Next()
&#9;while ch ~= &apos;\r&apos; and ch ~= &apos;\n&apos; do
&#9;&#9;ch = self:Next()
&#9;end
end
function JsonReader:ReadArray()
&#9;local result = {}
&#9;assert(self:Next() == &apos;[&apos;)
&#9;local done = false
&#9;if self:Peek() == &apos;]&apos; then
&#9;&#9;done = true;
&#9;end
&#9;while not done do
&#9;&#9;local item = self:Read()
&#9;&#9;result[#result+1] = item
&#9;&#9;self:SkipWhiteSpace()
&#9;&#9;if self:Peek() == &apos;]&apos; then
&#9;&#9;&#9;done = true
&#9;&#9;end
&#9;&#9;if not done then
&#9;&#9;&#9;local ch = self:Next()
&#9;&#9;&#9;if ch ~= &apos;,&apos; then
&#9;&#9;&#9;&#9;error(string.format(
&#9;&#9;&#9;&#9;&#9;&quot;Invalid array: &apos;%s&apos; due to: &apos;%s&apos;&quot;,
&#9;&#9;&#9;&#9;&#9;self:All(), ch))
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;assert(&apos;]&apos; == self:Next())
&#9;return result
end
function JsonReader:ReadObject()
&#9;local result = {}
&#9;assert(self:Next() == &apos;{&apos;)
&#9;local done = false
&#9;if self:Peek() == &apos;}&apos; then
&#9;&#9;done = true
&#9;end
&#9;while not done do
&#9;&#9;local key = self:Read()
&#9;&#9;if type(key) ~= &quot;string&quot; then
&#9;&#9;&#9;error(string.format(
&#9;&#9;&#9;&#9;&quot;Invalid non-string object key: %s&quot;,
&#9;&#9;&#9;&#9;key))
&#9;&#9;end
&#9;&#9;self:SkipWhiteSpace()
&#9;&#9;local ch = self:Next()
&#9;&#9;if ch ~= &apos;:&apos; then
&#9;&#9;&#9;error(string.format(
&#9;&#9;&#9;&#9;&quot;Invalid object: &apos;%s&apos; due to: &apos;%s&apos;&quot;,
&#9;&#9;&#9;&#9;self:All(),
&#9;&#9;&#9;&#9;ch))
&#9;&#9;end
&#9;&#9;self:SkipWhiteSpace()
&#9;&#9;local val = self:Read()
&#9;&#9;result[key] = val
&#9;&#9;self:SkipWhiteSpace()
&#9;&#9;if self:Peek() == &apos;}&apos; then
&#9;&#9;&#9;done = true
&#9;&#9;end
&#9;&#9;if not done then
&#9;&#9;&#9;ch = self:Next()
&#9;if ch ~= &apos;,&apos; then
&#9;&#9;&#9;&#9;error(string.format(
&#9;&#9;&#9;&#9;&#9;&quot;Invalid array: &apos;%s&apos; near: &apos;%s&apos;&quot;,
&#9;&#9;&#9;&#9;&#9;self:All(),
&#9;&#9;&#9;&#9;&#9;ch))
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;assert(self:Next() == &quot;}&quot;)
&#9;return result
end
function JsonReader:SkipWhiteSpace()
&#9;local p = self:Peek()
&#9;while p ~= nil and string.find(p, &quot;[%s/]&quot;) do
&#9;&#9;if p == &apos;/&apos; then
&#9;&#9;&#9;self:ReadComment()
&#9;&#9;else
&#9;&#9;&#9;self:Next()
&#9;&#9;end
&#9;&#9;p = self:Peek()
&#9;end
end
function JsonReader:Peek()
&#9;return self.reader:Peek()
end
function JsonReader:Next()
&#9;return self.reader:Next()
end
function JsonReader:All()
&#9;return self.reader:All()
end
function Encode(o)
&#9;local writer = JsonWriter:New()
&#9;writer:Write(o)
&#9;return writer:ToString()
end
function Decode(s)
&#9;local reader = JsonReader:New(s)
&#9;return reader:Read()
end
function Null()
&#9;return Null
end
-------------------- End JSON Parser ------------------------
t.DecodeJSON = function(jsonString)
&#9;if type(jsonString) == &quot;string&quot; then
&#9;&#9;return Decode(jsonString)
&#9;end
&#9;print(&quot;RbxUtil.DecodeJSON expects string argument!&quot;)
&#9;return nil
end
t.EncodeJSON = function(jsonTable)
&#9;return Encode(jsonTable)
end
------------------------------Terrain Utilities Begin--------------------------------
--makes a wedge at location x, y, z
--sets cell x, y, z to default material if parameter is provided, if not sets cell x, y, z to be whatever material it previously was
--returns true if made a wedge, false if the cell remains a block
t.MakeWedge = function(x, y, z, defaultmaterial)
&#9;local c = game:GetService(&quot;TerrainService&quot;)
&#9;--gather info about all the cells around x, y, z
&#9;surroundings = {} --surroundings is a 3 x 3 x 3 array of the material of the cells adjacent to x, y, z
&#9;for i = x - 1, x + 1 do
&#9;&#9;surroundings[i] = {}
&#9;&#9;for j = y - 1, y + 1 do
&#9;&#9;&#9;surroundings[i][j] = {}
&#9;&#9;&#9;for k = z - 1, z + 1 do
&#9;&#9;&#9;&#9;print(&quot;seeing the latest&quot;)
&#9;&#9;&#9;&#9;local material = nil
&#9;&#9;&#9;&#9;local wedge = nil
&#9;&#9;&#9;&#9;local rotation = nil
&#9;&#9;&#9;&#9;material, wedge, rotation = c:GetCellFull(i, j, k)
&#9;&#9;&#9;&#9;surroundings[i][j][k] = material
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;--make some useful arrays and counters
&#9;local sides = {} --sides is an array of the material of the 4 adjacent sides
&#9;sides[0] = surroundings[x - 1][y][z]
&#9;sides[1] = surroundings[x][y][z + 1]
&#9;sides[2] = surroundings[x + 1][y][z]
&#9;sides[3] = surroundings[x][y][z - 1]
&#9;local adjacentSides = 0
&#9;for n = 0, 3 do
&#9;&#9;if sides[n] &gt; 0 then
&#9;&#9;&#9;adjacentSides = adjacentSides + 1
&#9;&#9;end
&#9;end
&#9;local sidesAbove = {} --sides is an array of the material of the 4 adjacent sides 1 height above
&#9;sidesAbove[0] = surroundings[x - 1][y + 1][z]
&#9;sidesAbove[1] = surroundings[x][y + 1][z + 1]
&#9;sidesAbove[2] = surroundings[x + 1][y + 1][z]
&#9;sidesAbove[3] = surroundings[x][y + 1][z - 1]
&#9;local adjacentSidesAbove = 0
&#9;for n = 0, 3 do
&#9;&#9;if sidesAbove[n] &gt; 0 then
&#9;&#9;&#9;adjacentSidesAbove = adjacentSidesAbove + 1
&#9;&#9;end
&#9;end
&#9;local corners = {} --corners is an array of the material of the 4 adjacent corners
&#9;corners[0] = surroundings[x - 1][y][z - 1]
&#9;corners[1] = surroundings[x - 1][y][z + 1]
&#9;corners[2] = surroundings[x + 1][y][z + 1]
&#9;corners[3] = surroundings[x + 1][y][z - 1]
&#9;local adjacentCorners = 0
&#9;for n = 0, 3 do
&#9;&#9;if corners[n] &gt; 0 then
&#9;&#9;&#9;adjacentCorners = adjacentCorners + 1
&#9;&#9;end
&#9;end
&#9;local cornersAbove = {} --corners is an array of the material of the 4 adjacent corners 1 height above
&#9;cornersAbove[0] = surroundings[x - 1][y + 1][z - 1]
&#9;cornersAbove[1] = surroundings[x - 1][y + 1][z + 1]
&#9;cornersAbove[2] = surroundings[x + 1][y + 1][z + 1]
&#9;cornersAbove[3] = surroundings[x + 1][y + 1][z - 1]
&#9;local adjacentCornersAbove = 0
&#9;for n = 0, 3 do
&#9;&#9;if cornersAbove[n] &gt; 0 then
&#9;&#9;&#9;adjacentCornersAbove = adjacentCornersAbove + 1
&#9;&#9;end
&#9;end
&#9;--determine what type of wedge to make
&#9;local material = nil
&#9;local wedge = nil
&#9;local rotation = nil
&#9;if defaultmaterial then
&#9;&#9;material = defaultmaterial
&#9;else
&#9;&#9;material, wedge, rotation = c:GetCellFull(x, y, z) --start with the existing material, wedge, and rotation
&#9;end
&#9;wedge = 0 --default wedge is a block
&#9;rotation = 0 --default rotation is 0
&#9;--type 1: 45 degree ramp //must not have a block on top and must have a block under, and be surrounded by 1 side; or 3 sides and the 2 corners between them
&#9;if surroundings[x][y + 1][z] == 0 and surroundings[x][y - 1][z] &gt; 0 then
&#9;&#9;if adjacentSides == 1 then
&#9;&#9;&#9;for n = 0, 3 do
&#9;&#9;&#9;&#9;if sides[n] &gt; 0 then
&#9;&#9;&#9;&#9;&#9;wedge = 1
&#9;&#9;&#9;&#9;&#9;rotation = (n + 1) % 4
&#9;&#9;&#9;&#9;&#9;c:SetCellFull(x, y, z, material, wedge, rotation)
&#9;&#9;&#9;&#9;&#9;return true
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;elseif adjacentSides == 3 then
&#9;&#9;&#9;for n = 0, 3 do
&#9;&#9;&#9;&#9;if sides[n] &gt; 0 and corners[(n + 1) % 4] &gt; 0 and sides[(n + 1) % 4] &gt; 0 and corners[(n + 2) % 4] &gt; 0 and sides[(n + 2) % 4] &gt; 0 then
&#9;&#9;&#9;&#9;&#9;wedge = 1
&#9;&#9;&#9;&#9;&#9;rotation = (n + 2) % 4
&#9;&#9;&#9;&#9;&#9;c:SetCellFull(x, y, z, material, wedge, rotation)
&#9;&#9;&#9;&#9;&#9;return true
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;--type 2: 45 degree corner //must not have a block on top and must have a block under, and be surrounded by 2 sides and the 1 corner between them; or 3 sides and 1 corner between 2 of them (facing towards that corner)
&#9;if surroundings[x][y + 1][z] == 0 and surroundings[x][y - 1][z] &gt; 0 then
&#9;&#9;for n = 0, 3 do
&#9;&#9;&#9;if sides[n] &gt; 0 and corners[(n + 1) % 4] &gt; 0 and sides[(n + 1) % 4] &gt; 0 and (adjacentSides == 2 or (adjacentSides == 3 and (corners[(n + 3) % 4] &gt; 0 or (sides[(n + 2) % 4] &gt; 0 and corners[(n + 2) % 4] &gt; 0) or (sides[(n + 3) % 4] &gt; 0 and corners[n] &gt; 0)))) then
&#9;&#9;&#9;&#9;wedge = 2
&#9;&#9;&#9;&#9;rotation = (n + 2) % 4
&#9;&#9;&#9;&#9;c:SetCellFull(x, y, z, material, wedge, rotation)
&#9;&#9;&#9;&#9;return true
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;--type 3: 45 degree inverse corner //surrounded by three sides or 4 sides and 3 corners, with nothing above or else a block on top surrounded on 2 sides and the corner between them
&#9;if adjacentSides == 3 and surroundings[x][y + 1][z] &gt; 0 then
&#9;&#9;if adjacentCorners &gt; 1 then
&#9;&#9;&#9;for n = 0, 3 do
&#9;&#9;&#9;&#9;if (corners[n] == 0 or cornersAbove[n] == 0) and (sides[(n - 1) % 4] == 0 or sides[n] == 0) and (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] &gt; 0 and sidesAbove[(n + 2) % 4] &gt; 0 and sidesAbove[(n + 3) % 4] == 0) then
&#9;&#9;&#9;&#9;&#9;wedge = 3
&#9;&#9;&#9;&#9;&#9;rotation = (n + 3) % 4
&#9;&#9;&#9;&#9;&#9;c:SetCellFull(x, y, z, material, wedge, rotation)
&#9;&#9;&#9;&#9;&#9;return true
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;elseif adjacentSides == 4 and adjacentCorners == 3 then
&#9;&#9;for n = 0, 3 do
&#9;&#9;&#9;if corners[n] == 0 and (surroundings[x][y + 1][z] == 0 or (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] &gt; 0 and cornersAbove[(n + 2) % 4] &gt; 0 and sidesAbove[(n + 2) % 4] &gt; 0 and sidesAbove[(n + 3) % 4] == 0)) then
&#9;&#9;&#9;&#9;wedge = 3
&#9;&#9;&#9;&#9;rotation = (n + 3) % 4
&#9;&#9;&#9;&#9;c:SetCellFull(x, y, z, material, wedge, rotation)
&#9;&#9;&#9;&#9;return true
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;--type 4: half a cube, as if it were cut diagonally from front to back //surrounded by 2 sides
&#9;if adjacentSides == 2 and adjacentCorners &lt; 4 then
&#9;&#9;for n = 0, 3 do
&#9;&#9;&#9;if sides[n] == 0 and sides[(n + 1) % 4] == 0 and (surroundings[x][y + 1][z] == 0 or (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] == 0 and sidesAbove[(n + 2) % 4] &gt; 0 and sidesAbove[(n + 3) % 4] &gt; 0)) then
&#9;&#9;&#9;&#9;wedge = 4
&#9;&#9;&#9;&#9;rotation = n
&#9;&#9;&#9;&#9;c:SetCellFull(x, y, z, material, wedge, rotation)
&#9;&#9;&#9;&#9;return true
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;c:SetCellFull(x, y, z, material, wedge, rotation)
&#9;return false
end
-----------------------------Terrain Utilities End-----------------------------
t.Help =
&#9;function(funcNameOrFunc)
&#9;&#9;--input argument can be a string or a function. Should return a description (of arguments and expected side effects)
&#9;&#9;if funcNameOrFunc == &quot;DecodeJSON&quot; or funcNameOrFunc == t.DecodeJSON then
&#9;&#9;&#9;return &quot;Function DecodeJSON. &quot; ..
&#9;&#9;&#9;&#9; &quot;Arguments: (string). &quot; ..
&#9;&#9;&#9;&#9; &quot;Side effect: returns a table with all parsed JSON values&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;EncodeJSON&quot; or funcNameOrFunc == t.EncodeJSON then
&#9;&#9;&#9;return &quot;Function EncodeJSON. &quot; ..
&#9;&#9;&#9;&#9; &quot;Arguments: (table). &quot; ..
&#9;&#9;&#9;&#9; &quot;Side effect: returns a string composed of argument table in JSON data format&quot;
&#9;&#9;end
&#9;&#9;if funcNameOrFunc == &quot;MakeWedge&quot; or funcNameOrFunc == t.MakeWedge then
&#9;&#9;&#9;return &quot;Function MakeWedge. &quot; ..
&#9;&#9;&#9;&#9;&#9;&quot;Arguments: (x, y, z, [default material]). &quot; ..
&#9;&#9;&#9;&#9;&#9;&quot;Description: Makes a wedge at location x, y, z. Sets cell x, y, z to default material if parameter is provided, if not sets cell x, y, z to be whatever material it previously was. Returns true if made a wedge, false if the cell remains a block &quot;
&#9;&#9;end
&#9;end
--rbxsig%REvu/wlKsFpV+wGhx4ZIeoKQ3ajJIMa8dt7TmxHPEQ3UyELsZVYT0DQiFiH7ICCEoiF9Yj9pNuB6DvyP739SU78jRrPa3Ln1aJHwdBur+X9TWjVvHDiHrezRhmWvXOIBhmw+/xoj+88xIoZABu36+kLyoHQDBbg8qrTf0CUZv5c=%
--rbxassetid%97188756%
--[[
&#9;//FileName: ChatScript.LUA
&#9;//Written by: Sorcus
&#9;//Description: Code for lua side chat on ROBLOX. Supports Scrolling.
&#9;//NOTE: If you find any bugs or inaccuracies PM Sorcus on ROBLOX or @Canavus on Twitter
]]
-- Utility functions + Globals
local function WaitForChild(parent, childName)&#9;
&#9;while parent:FindFirstChild(childName) == nil do
&#9;&#9;parent.ChildAdded:wait(0.03)
&#9;end &#9;
&#9;return parent[childName]
end
function Create(guiType)
&#9;return function(data)
&#9;&#9;local obj = Instance.new(guiType)
&#9;&#9;for k, v in pairs(data) do
&#9;&#9;&#9;if type(k) == &apos;number&apos; then
&#9;&#9;&#9;&#9;v.Parent = obj
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;obj[k] = v
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;return obj
&#9;end
end
local function typedef(obj)
&#9;return obj
end
local function IsPhone()
end
-- Users can use enough white spaces to spoof chatting as other players
-- This function removes trailing and leading white spaces
-- AFAIK, there is no reason for spam white spaces
local function StringTrim(str)
&#9;-- %S is whitespaces
&#9;-- When we find the first non space character defined by ^%s
&#9;-- we yank out anything in between that and the end of the string
&#9;-- Everything else is replaced with %1 which is essentially nothing &#9;
&#9;return (str:gsub(&quot;^%s*(.-)%s*$&quot;, &quot;%1&quot;))
end
while Game.Players.LocalPlayer == nil do wait(0.03) end
local Player = Game.Players.LocalPlayer
while Player.Character == nil do wait(0.03) end
local RbxUtility = t
local Gui = typedef(RbxUtility)
local Camera = Game.Workspace.CurrentCamera
-- Services
local CoreGuiService = Game:GetService(&apos;CoreGui&apos;)
local PlayersService = Game:GetService(&apos;Players&apos;)
local DebrisService= Game:GetService(&apos;Debris&apos;)
local GuiService = Game:GetService(&apos;GuiService&apos;)
-- Lua Enums
local Enums do
&#9;Enums = {}
&#9;local EnumName = {} -- used as unique key for enum name
&#9;local enum_mt = {
&#9;&#9;__call = function(self,value)
&#9;&#9;&#9;return self[value] or self[tonumber(value)]
&#9;&#9;end;
&#9;&#9;__index = {
&#9;&#9;&#9;GetEnumItems = function(self)
&#9;&#9;&#9;&#9;local t = {}
&#9;&#9;&#9;&#9;for i,item in pairs(self) do
&#9;&#9;&#9;&#9;&#9;if type(i) == &apos;number&apos; then
&#9;&#9;&#9;&#9;&#9;&#9;t[#t+1] = item
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;table.sort(t,function(a,b) return a.Value &lt; b.Value end)
&#9;&#9;&#9;&#9;return t
&#9;&#9;&#9;end;
&#9;&#9;};
&#9;&#9;__tostring = function(self)
&#9;&#9;&#9;return &quot;Enum.&quot; .. self[EnumName]
&#9;&#9;end;
&#9;}
&#9;local item_mt = {
&#9;&#9;__call = function(self,value)
&#9;&#9;&#9;return value == self or value == self.Name or value == self.Value
&#9;&#9;end;
&#9;&#9;__tostring = function(self)
&#9;&#9;&#9;return &quot;Enum.&quot; .. self[EnumName] .. &quot;.&quot; .. self.Name
&#9;&#9;end;
&#9;}
&#9;function CreateEnum(enumName)
&#9;&#9;return function(t)
&#9;&#9;&#9;local e = {[EnumName] = enumName}
&#9;&#9;&#9;for i,name in pairs(t) do
&#9;&#9;&#9;&#9;local item = setmetatable({Name=name,Value=i,Enum=e,[EnumName]=enumName},item_mt)
&#9;&#9;&#9;&#9;e[i] = item
&#9;&#9;&#9;&#9;e[name] = item
&#9;&#9;&#9;&#9;e[item] = item
&#9;&#9;&#9;end
&#9;&#9;&#9;Enums[enumName] = e
&#9;&#9;&#9;return setmetatable(e, enum_mt)
&#9;&#9;end
&#9;end
end
---------------------------------------------------
------------------ Input class --------------------
local Input = {
&#9;&#9;&#9;&#9;&#9;&#9;Mouse = Player:GetMouse(),
&#9;&#9;&#9;&#9;&#9;&#9;Speed = 0,
&#9;&#9;&#9;&#9;&#9;&#9;Simulating = false,
&#9;&#9;&#9;&#9;&#9;&#9;Configuration = {
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;DefaultSpeed = 1
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;&#9;&#9;&#9;UserIsScrolling = false
&#9;&#9;&#9;&#9;&#9;}
---------------------------------------------------
------------------ Chat class --------------------
local Chat = {
&#9;&#9;&#9;ChatColors = {
&#9;&#9;&#9;&#9;&#9;&#9;&#9;BrickColor.new(&quot;Bright red&quot;),
&#9;&#9;&#9;&#9;&#9;&#9;&#9;BrickColor.new(&quot;Bright blue&quot;),
&#9;&#9;&#9;&#9;&#9;&#9;&#9;BrickColor.new(&quot;Earth green&quot;),
&#9;&#9;&#9;&#9;&#9;&#9;&#9;BrickColor.new(&quot;Bright violet&quot;),
&#9;&#9;&#9;&#9;&#9;&#9;&#9;BrickColor.new(&quot;Bright orange&quot;),
&#9;&#9;&#9;&#9;&#9;&#9;&#9;BrickColor.new(&quot;Bright yellow&quot;),
&#9;&#9;&#9;&#9;&#9;&#9;&#9;BrickColor.new(&quot;Light reddish violet&quot;),
&#9;&#9;&#9;&#9;&#9;&#9;&#9;BrickColor.new(&quot;Brick yellow&quot;),
&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;Gui = nil,
&#9;&#9;&#9;Frame = nil,
&#9;&#9;&#9;RenderFrame = nil,
&#9;&#9;&#9;TapToChatLabel = nil,
&#9;&#9;&#9;ClickToChatButton = nil,
&#9;&#9;&#9;ScrollingLock = false,
&#9;&#9;&#9;EventListener = nil,
&#9;&#9;&#9;-- This is actually a ring buffer
&#9;&#9;&#9;-- Meaning at hitting the historyLength it wraps around
&#9;&#9;&#9;-- Reuses the text objects, so chat atmost uses 100 text objects
&#9;&#9;&#9;MessageQueue = {},
&#9;&#9;&#9;-- Stores all the values for configuring chat
&#9;&#9;&#9;Configuration = {&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;FontSize = Enum.FontSize.Size12, -- 10 is good &#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;-- Also change this when you are changing the above, this is suboptimal but so is our interface to find FontSize&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;NumFontSize = 12,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;HistoryLength = 20, -- stores up to 50 of the last chat messages for you to scroll through,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Size = UDim2.new(0.38, 0, 0.20, 0),
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;MessageColor = Color3.new(1, 1, 1),
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;AdminMessageColor = Color3.new(1, 215/255, 0),&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;XScale = 0.025,&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;LifeTime = 45,&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Position = UDim2.new(0, 2, 0.05, 0),
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;DefaultTweenSpeed = 0.15,&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;-- This could be redone by just using the previous and next fields of the Queue
&#9;&#9;&#9;-- But the iterators cause issues, will be optimized later
&#9;&#9;&#9;SlotPositions_List = {},&#9;
&#9;&#9;&#9;-- To precompute and store all player null strings since its an expensive process
&#9;&#9;&#9;CachedSpaceStrings_List = {},&#9;
&#9;&#9;&#9;MouseOnFrame = false,
&#9;&#9;&#9;GotFocus = false,
&#9;&#9;&#9;Messages_List = {},
&#9;&#9;&#9;MessageThread = nil,
-- changing anything here might and WILL get you banned. - iagoMAO --
&#9;&#9;&#9;Admins_List = {&apos;iagoMAO&apos;, &apos;Carrot&apos;, &apos;winsupermario1234&apos;, &apos;Bitl&apos;, &apos;QuackIAttack&apos;, &apos;khanglegos&apos;, &apos;Nukley&apos;, &apos;OliverA&apos;,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&apos;Raymonf&apos;, &apos;coke&apos;, &apos;TheLivingBee&apos;, &apos;Peridorky&apos;, &apos;romulo27&apos;, &apos;robloxtester&apos;, &apos;CPunch&apos;, &apos;connor&apos;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;SafeChat_List = {
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Use the Chat menu to talk to me.&apos;] = {&apos;/sc 0&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I can only see menu chats.&apos;] = {&apos;/sc 1&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Hello&apos;] = {&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Hi&apos;] = {&apos;/sc 2_0&apos;, true, [&apos;Hi there!&apos;] = true, [&apos;Hi everyone&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Howdy&apos;] = {&apos;/sc 2_1&apos;, true, [&apos;Howdy partner!&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Greetings&apos;] = {&apos;/sc 2_2&apos;, true, [&apos;Greetings everyone&apos;] = true, [&apos;Greetings Robloxians!&apos;] = true, [&apos;Seasons greetings!&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Welcome&apos;] = {&apos;/sc 2_3&apos;, true, [&apos;Welcome to my place&apos;] = true, [&apos;Welcome to my barbeque&apos;] = true, [&apos;Welcome to our base&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Hey there!&apos;] = {&apos;/sc 2_4&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;What\&apos;s up?&apos;] = {&apos;/sc 2_5&apos;, true, [&apos;How are you doing?&apos;] = true, [&apos;How\&apos;s it going?&apos;] = true, [&apos;What\&apos;s new?&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Good day&apos;] = {&apos;/sc 2_6&apos;, true, [&apos;Good morning&apos;] = true, [&apos;Good evening&apos;] = true, [&apos;Good afternoon&apos;] = true, [&apos;Good night&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Silly&apos;] = {&apos;/sc 2_7&apos;, true, [&apos;Waaaaaaaz up?!&apos;] = true, [&apos;Hullo!&apos;] = true, [&apos;Behold greatness, mortals!&apos;] = true, [&apos;Pardon me, is this Sparta?&apos;] = true, [&apos;THIS IS SPARTAAAA!&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Happy Holidays!&apos;] = {&apos;/sc 2_8&apos;, true, [&apos;Happy New Year!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Happy Valentine\&apos;s Day!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Beware the Ides of March!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Happy St. Patrick\&apos;s Day!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Happy Easter!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Happy Earth Day!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Happy 4th of July!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Happy Thanksgiving!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Happy Halloween!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Happy Hanukkah!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Merry Christmas!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Happy Halloween!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Happy Earth Day!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Happy May Day!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Happy Towel Day!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Happy ROBLOX Day!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Happy LOL Day!&apos;] = true },
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[1] = &apos;/sc 2&apos;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Goodbye&apos;] = {
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Good Night&apos;]= {&apos;/sc 3_0&apos;, true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Sweet dreams&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Go to sleep!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Lights out!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Bedtime&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Going to bed now&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Later&apos;]= {&apos;/sc 3_1&apos;, true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; &#9;&#9;&#9; [&apos;See ya later&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Later gator!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;See you tomorrow&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Bye&apos;] = {&apos;/sc 3_2&apos;, true, [&apos;Hasta la bye bye!&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I\&apos;ll be right back&apos;] = {&apos;/sc 3_3&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I have to go&apos;] = {&apos;/sc 3_4&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Farewell&apos;] = {&apos;/sc 3_5&apos;, true, [&apos;Take care&apos;] = true, [&apos;Have a nice day&apos;] = true, [&apos;Goodluck!&apos;] = true, [&apos;Ta-ta for now!&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Peace&apos;] = {&apos;/sc 3_6&apos;, true, [&apos;Peace out!&apos;] = true, [&apos;Peace dudes!&apos;] = true, [&apos;Rest in pieces!&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Silly&apos;] = {&apos;/sc 3_7&apos;, true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;To the batcave!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Over and out!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Happy trails!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;I\&apos;ve got to book it!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Tootles!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Smell you later!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;GG!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;My house is on fire! gtg.&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[1] = &apos;/sc 3&apos;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Friend&apos;] ={
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Wanna be friends?&apos;] = {&apos;/sc 4_0&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Follow me&apos;] = {&apos;/sc 4_1&apos;, true, [&apos;Come to my place!&apos;] = true, [&apos;Come to my base!&apos;] = true, [&apos;Follow me, team!&apos;] = true, [&apos;Follow me&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Your place is cool&apos;] = {&apos;/sc 4_2&apos;, true, [&apos;Your place is fun&apos;] = true, [&apos;Your place is awesome&apos;] = true, [&apos;Your place looks good&apos;] = true, [&apos;This place is awesome!&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Thank you&apos;] = {&apos;/sc 4_3&apos;, true, [&apos;Thanks for playing&apos;] = true, [&apos;Thanks for visiting&apos;] = true, [&apos;Thanks for everything&apos;] = true, [&apos;No, thank you&apos;] = true, [&apos;Thanx&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;No problem&apos;] = {&apos;/sc 4_4&apos;, true, [&apos;Don\&apos;t worry&apos;] = true, [&apos;That\&apos;s ok&apos;] = true, [&apos;np&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;You are ...&apos;] = {&apos;/sc 4_5&apos;, true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;You are great!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;You are good!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;You are cool!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;You are funny!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;You are silly!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;You are awesome!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;You are doing something I don\&apos;t like, please stop&apos;] = true
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; },
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I like ...&apos;] = {&apos;/sc 4_6&apos;, true, [&apos;I like your name&apos;] = true, [&apos;I like your shirt&apos;] = true, [&apos;I like your place&apos;] = true, [&apos;I like your style&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I like you&apos;] = true, [&apos;I like items&apos;] = true, [&apos;I like money&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Sorry&apos;] = {&apos;/sc 4_7&apos;, true, [&apos;My bad!&apos;] = true, [&apos;I\&apos;m sorry&apos;] = true, [&apos;Whoops!&apos;] = true, [&apos;Please forgive me.&apos;] = true, [&apos;I forgive you.&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I didn\&apos;t mean to do that.&apos;] = true, [&apos;Sorry, I\&apos;ll stop now.&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[1] = &apos;/sc 4&apos;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Questions&apos;] = {
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Who?&apos;] = {&apos;/sc 5_0&apos;, true, [&apos;Who wants to be my friend?&apos;] = true, [&apos;Who wants to be on my team?&apos;] = true, [&apos;Who made this brilliant game?&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;What?&apos;] = {&apos;/sc 5_1&apos;, true, [&apos;What is your favorite animal?&apos;] = true, [&apos;What is your favorite game?&apos;] = true, [&apos;What is your favorite movie?&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;What is your favorite TV show?&apos;] = true, [&apos;What is your favorite music?&apos;] = true, [&apos;What are your hobbies?&apos;] = true, [&apos;LOLWUT?&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;When?&apos;] = {&apos;/sc 5_2&apos;, true, [&apos;When are you online?&apos;] = true, [&apos;When is the new version coming out?&apos;] = true, [&apos;When can we play again?&apos;] = true, [&apos;When will your place be done?&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Where?&apos;] = {&apos;/sc 5_3&apos;, true, [&apos;Where do you want to go?&apos;] = true, [&apos;Where are you going?&apos;] = true, [&apos;Where am I?!&apos;] = true, [&apos;Where did you go?&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;How?&apos;] = {&apos;/sc 5_4&apos;, true, [&apos;How are you today?&apos;] = true, [&apos;How did you make this cool place?&apos;] = true, [&apos;LOLHOW?&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Can I...&apos;] = {&apos;/sc 5_5&apos;, true, [&apos;Can I have a tour?&apos;] = true, [&apos;Can I be on your team?&apos;] = true, [&apos;Can I be your friend?&apos;] = true, [&apos;Can I try something?&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Can I have that please?&apos;] = true, [&apos;Can I have that back please?&apos;] = true, [&apos;Can I have borrow your hat?&apos;] = true, [&apos;Can I have borrow your gear?&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[1] = &apos;/sc 5&apos;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Answers&apos;] = {
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;You need help?&apos;] = {&apos;/sc 6_0&apos;, true, [&apos;Check out the news section&apos;] = true, [&apos;Check out the help section&apos;] = true, [&apos;Read the wiki!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;All the answers are in the wiki!&apos;] = true, [&apos;I will help you with this.&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Some people ...&apos;] = {&apos;/sc 6_1&apos;, true, [&apos;Me&apos;] = true, [&apos;Not me&apos;] = true, [&apos;You&apos;] = true, [&apos;All of us&apos;] = true, [&apos;Everyone but you&apos;] = true, [&apos;Builderman!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Telamon!&apos;] = true, [&apos;My team&apos;] = true, [&apos;My group&apos;] = true, [&apos;Mom&apos;] = true, [&apos;Dad&apos;] = true, [&apos;Sister&apos;] = true, [&apos;Brother&apos;] = true, [&apos;Cousin&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Grandparent&apos;] = true, [&apos;Friend&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Time ...&apos;] = {&apos;/sc 6_2&apos;, true, [&apos;In the morning&apos;] = true, [&apos;In the afternoon&apos;] = true, [&apos;At night&apos;] = true, [&apos;Tomorrow&apos;] = true, [&apos;This week&apos;] = true, [&apos;This month&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Sometime&apos;] = true, [&apos;Sometimes&apos;] = true, [&apos;Whenever you want&apos;] = true, [&apos;Never&apos;] = true, [&apos;After this&apos;] = true, [&apos;In 10 minutes&apos;] = true, [&apos;In a couple hours&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;In a couple days&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Animals&apos;] = {&apos;/sc 6_3&apos;, true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Cats&apos;] = {[&apos;Lion&apos;] = true, [&apos;Tiger&apos;] = true, [&apos;Leopard&apos;] = true, [&apos;Cheetah&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Dogs&apos;] = {[&apos;Wolves&apos;] = true, [&apos;Beagle&apos;] = true, [&apos;Collie&apos;] = true, [&apos;Dalmatian&apos;] = true, [&apos;Poodle&apos;] = true, [&apos;Spaniel&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Shepherd&apos;] = true, [&apos;Terrier&apos;] = true, [&apos;Retriever&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Horses&apos;] = {[&apos;Ponies&apos;] = true, [&apos;Stallions&apos;] = true, [&apos;Pwnyz&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Reptiles&apos;] = {[&apos;Dinosaurs&apos;] = true, [&apos;Lizards&apos;] = true, [&apos;Snakes&apos;] = true, [&apos;Turtles!&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Hamster&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Monkey&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Bears&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Fish&apos;] = {[&apos;Goldfish&apos;] = true, [&apos;Sharks&apos;] = true, [&apos;Sea Bass&apos;] = true, [&apos;Halibut&apos;] = true, [&apos;Tropical Fish&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Birds&apos;] = {[&apos;Eagles&apos;] = true, [&apos;Penguins&apos;] = true, [&apos;Parakeets&apos;] = true, [&apos;Owls&apos;] = true, [&apos;Hawks&apos;] = true, [&apos;Pidgeons&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Elephants&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Mythical Beasts&apos;] = {[&apos;Dragons&apos;] = true, [&apos;Unicorns&apos;] = true, [&apos;Sea Serpents&apos;] = true, [&apos;Sphinx&apos;] = true, [&apos;Cyclops&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Minotaurs&apos;] = true, [&apos;Goblins&apos;] = true, [&apos;Honest Politicians&apos;] = true, [&apos;Ghosts&apos;] = true, [&apos;Scylla and Charybdis&apos;] = true}
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Games&apos;] = {&apos;/sc 6_4&apos;, true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Action&apos;] = true, [&apos;Puzzle&apos;] = true, [&apos;Strategy&apos;] = true, [&apos;Racing&apos;] = true, [&apos;RPG&apos;] = true, [&apos;Obstacle Course&apos;] = true, [&apos;Tycoon&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Roblox&apos;] = { [&apos;BrickBattle&apos;] = true, [&apos;Community Building&apos;] = true, [&apos;Roblox Minigames&apos;] = true, [&apos;Contest Place&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Board games&apos;] = { [&apos;Chess&apos;] = true, [&apos;Checkers&apos;] = true, [&apos;Settlers of Catan&apos;] = true, [&apos;Tigris and Euphrates&apos;] = true, [&apos;El Grande&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Stratego&apos;] = true, [&apos;Carcassonne&apos;] = true}
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Sports&apos;] = {&apos;/sc 6_5&apos;, true, [&apos;Hockey&apos;] = true, [&apos;Soccer&apos;] = true, [&apos;Football&apos;] = true, [&apos;Baseball&apos;] = true, [&apos;Basketball&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Volleyball&apos;] = true, [&apos;Tennis&apos;] = true, [&apos;Sports team practice&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Watersports&apos;] = { [&apos;Surfing&apos;] = true,[&apos;Swimming&apos;] = true, [&apos;Water Polo&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Winter sports&apos;] = { [&apos;Skiing&apos;] = true, [&apos;Snowboarding&apos;] = true, [&apos;Sledding&apos;] = true, [&apos;Skating&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Adventure&apos;] = {[&apos;Rock climbing&apos;] = true, [&apos;Hiking&apos;] = true, [&apos;Fishing&apos;] = true, [&apos;Horseback riding&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Wacky&apos;] = {[&apos;Foosball&apos;] = true, [&apos;Calvinball&apos;] = true, [&apos;Croquet&apos;] = true, [&apos;Cricket&apos;] = true, [&apos;Dodgeball&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Squash&apos;] = true, &#9;[&apos;Trampoline&apos;] = true}
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; },
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Movies/TV&apos;] = {&apos;/sc 6_6&apos;, true, [&apos;Science Fiction&apos;] = true, [&apos;Animated&apos;] = {[&apos;Anime&apos;] = true}, [&apos;Comedy&apos;] = true, [&apos;Romantic&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Action&apos;] = true, [&apos;Fantasy&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Music&apos;] = {&apos;/sc 6_7&apos;, true, [&apos;Country&apos;] = true, [&apos;Jazz&apos;] = true, [&apos;Rap&apos;] = true, [&apos;Hip-hop&apos;] = true, [&apos;Techno&apos;] = true, [&apos;Classical&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Pop&apos;] = true, [&apos;Rock&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Hobbies&apos;] = {&apos;/sc 6_8&apos;, true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Computers&apos;] = { [&apos;Building computers&apos;] = true, [&apos;Videogames&apos;] = true, [&apos;Coding&apos;] = true, [&apos;Hacking&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;The Internet&apos;] = { [&apos;lol. teh internets!&apos;] = true, [&apos;Watching vids&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Dance&apos;] = true, [&apos;Gymnastics&apos;] = true, [&apos;Listening to music&apos;] = true, [&apos;Arts and crafts&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Martial Arts&apos;] = {[&apos;Karate&apos;] = true, [&apos;Judo&apos;] = true, [&apos;Taikwon Do&apos;] = true, [&apos;Wushu&apos;] = true, [&apos;Street fighting&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;Music lessons&apos;] = {[&apos;Playing in my band&apos;] = true, [&apos;Playing piano&apos;] = true, [&apos;Playing guitar&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Playing violin&apos;] = true, [&apos;Playing drums&apos;] = true, [&apos;Playing a weird instrument&apos;] = true}
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Location&apos;] = {&apos;/sc 6_9&apos;, true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;USA&apos;] = {
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;West&apos;] = { [&apos;Alaska&apos;] = true, [&apos;Arizona&apos;] = true, [&apos;California&apos;] = true, [&apos;Colorado&apos;] = true, [&apos;Hawaii&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Idaho&apos;] = true, [&apos;Montana&apos;] = true, [&apos;Nevada&apos;] = true, [&apos;New Mexico&apos;] = true, [&apos;Oregon&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Utah&apos;] = true, [&apos;Washington&apos;] = true, [&apos;Wyoming&apos;] = true
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;South&apos;] = { [&apos;Alabama&apos;] = true, [&apos;Arkansas&apos;] = true, [&apos;Florida&apos;] = true, [&apos;Georgia&apos;] = true, [&apos;Kentucky&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Louisiana&apos;] = true, [&apos;Mississippi&apos;] = true, [&apos;North Carolina&apos;] = true, [&apos;Oklahoma&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;South Carolina&apos;] = true, [&apos;Tennessee&apos;] = true, [&apos;Texas&apos;] = true, [&apos;Virginia&apos;] = true, [&apos;West Virginia&apos;] = true
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Northeast&apos;] = {[&apos;Connecticut&apos;] = true, [&apos;Delaware&apos;] = true, [&apos;Maine&apos;] = true, [&apos;Maryland&apos;] = true, [&apos;Massachusetts&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;New Hampshire&apos;] = true, [&apos;New Jersey&apos;] = true, [&apos;New York&apos;] = true, [&apos;Pennsylvania&apos;] = true, [&apos;Rhode Island&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Vermont&apos;] = true
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Midwest&apos;] = {[&apos;Illinois&apos;] = true, [&apos;Indiana&apos;] = true, [&apos;Iowa&apos;] = true, [&apos;Kansas&apos;] = true, [&apos;Michigan&apos;] = true, [&apos;Minnesota&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Missouri&apos;] = true, [&apos;Nebraska&apos;] = true, [&apos;North Dakota&apos;] = true, [&apos;Ohio&apos;] = true, [&apos;South Dakota&apos;] = true, [&apos;Wisconsin&apos;] = true}
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Canada&apos;] = {[&apos;Alberta&apos;] = true, [&apos;British Columbia&apos;] = true, [&apos;Manitoba&apos;] = true, [&apos;New Brunswick&apos;] = true, [&apos;Newfoundland&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Northwest Territories&apos;] = true, [&apos;Nova Scotia&apos;] = true, [&apos;Nunavut&apos;] = true, [&apos;Ontario&apos;] = true, [&apos;Prince Edward Island&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Quebec&apos;] = true, [&apos;Saskatchewan&apos;] = true, [&apos;Yukon&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Mexico&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Central America&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Europe&apos;] = {[&apos;France&apos;] = true, [&apos;Germany&apos;] = true, [&apos;Spain&apos;] = true, [&apos;Italy&apos;] = true, [&apos;Poland&apos;] = true, [&apos;Switzerland&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Greece&apos;] = true, [&apos;Romania&apos;] = true, [&apos;Netherlands&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Great Britain&apos;] = {[&apos;England&apos;] = true, [&apos;Scotland&apos;] = true, [&apos;Wales&apos;] = true, [&apos;Northern Ireland&apos;] = true}
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Asia&apos;] = { [&apos;China&apos;] = true, [&apos;India&apos;] = true, [&apos;Japan&apos;] = true, [&apos;Korea&apos;] = true, [&apos;Russia&apos;] = true, [&apos;Vietnam&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;South America&apos;] = { [&apos;Argentina&apos;] = true, [&apos;Brazil&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Africa&apos;] = { [&apos;Eygpt&apos;] = true, [&apos;Swaziland&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Australia&apos;] = true, [&apos;Middle East&apos;] = true, [&apos;Antarctica&apos;] = true, [&apos;New Zealand&apos;] = true
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Age&apos;] = {&apos;/sc 6_10&apos;, true, [&apos;Rugrat&apos;] = true, [&apos;Kid&apos;] = true, [&apos;Tween&apos;] = true, [&apos;Teen&apos;] = true, [&apos;Twenties&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Old&apos;] = true, [&apos;Ancient&apos;] = true, [&apos;Mesozoic&apos;] = true, [&apos;I don\&apos;t want to say my age. Don\&apos;t ask.&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Mood&apos;] = {&apos;/sc 6_11&apos;, true, [&apos;Good&apos;] = true, [&apos;Great!&apos;] = true, [&apos;Not bad&apos;] = true, [&apos;Sad&apos;] = true, [&apos;Hyper&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Chill&apos;] = true, [&apos;Happy&apos;] = true, [&apos;Kind of mad&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Boy&apos;] = {&apos;/sc 6_12&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Girl&apos;] = {&apos;/sc 6_13&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I don\&apos;t want to say boy or girl. Don\&apos;t ask.&apos;] = {&apos;/sc 6_14&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[1] = &apos;/sc 6&apos;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Game&apos;] = {
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Let\&apos;s build&apos;] = {&apos;/sc 7_0&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Let\&apos;s battle&apos;] = {&apos;/sc 7_1&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Nice one!&apos;] = {&apos;/sc 7_2&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;So far so good&apos;] = {&apos;/sc 7_3&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Lucky shot!&apos;] = {&apos;/sc 7_4&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Oh man!&apos;] = {&apos;/sc 7_5&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I challenge you to a fight!&apos;] = {&apos;/sc 7_6&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Help me with this&apos;] = {&apos;/sc 7_7&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Let\&apos;s go to your game&apos;] = {&apos;/sc 7_8&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Can you show me how do to that?&apos;] = {&apos;/sc 7_9&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Backflip!&apos;] = {&apos;/sc 7_10&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Frontflip!&apos;] = {&apos;/sc 7_11&apos;, true},&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Dance!&apos;] = {&apos;/sc 7_12&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I\&apos;m on your side!&apos;] = {&apos;/sc 7_13&apos;, true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Game Commands&apos;] = {&apos;/sc 7_14&apos;, true, [&apos;regen&apos;] = true, [&apos;reset&apos;] = true, [&apos;go&apos;] = true, [&apos;fix&apos;] = true, [&apos;respawn&apos;] = true},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[1] = &apos;/sc 7&apos;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;};
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Silly&apos;] = {
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Muahahahaha!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;all your base are belong to me!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;GET OFF MAH LAWN&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;TEH EPIK DUCK IS COMING!!!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;ROFL&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;1337&apos;] = {true, [&apos;i r teh pwnz0r!&apos;] = true, [&apos;w00t!&apos;] = true, [&apos;z0mg h4x!&apos;] = true, [&apos;ub3rR0xXorzage!&apos;] = true}
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Yes&apos;] = {
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Absolutely!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Rock on!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Totally!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Juice!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Yay!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Yesh&apos;] = true
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;No&apos;] = {
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Ummm. No.&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;...&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Stop!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Go away!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Don\&apos;t do that&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Stop breaking the rules&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I don\&apos;t want to&apos;] = true
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Ok&apos;] = {
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Well... ok&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Sure&apos;] = true
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Uncertain&apos;] = {
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Maybe&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I don\&apos;t know&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;idk&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I can\&apos;t decide&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Hmm...&apos;] = true
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;:-)&apos;] = {
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;:-(&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;:D&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;:-O&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;lol&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;=D&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;D=&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;XD&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;;D&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;;)&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;O_O&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;=)&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;@_@&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;&amp;gt;_&amp;lt;&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;T_T&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9; [&apos;^_^&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;&lt;(0_0&lt;) &lt;(0_0)&gt; (&gt;0_0)&gt; KIRBY DANCE&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;)\&apos;;&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;:3&apos;] = true
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;},
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Ratings&apos;] = {
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Rate it!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I give it a 1 out of 10&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I give it a 2 out of 10&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I give it a 3 out of 10&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I give it a 4 out of 10&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I give it a 5 out of 10&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I give it a 6 out of 10&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I give it a 7 out of 10&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I give it a 8 out of 10&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I give it a 9 out of 10&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;I give it a 10 out of 10!&apos;] = true,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;}
&#9;&#9;&#9;&#9;&#9;&#9;&#9;},&#9;&#9;&#9;
&#9;&#9;&#9;CreateEnum(&apos;SafeChat&apos;){&apos;Level1&apos;, &apos;Level2&apos;, &apos;Level3&apos;},
&#9;&#9;&#9;SafeChatTree = {},
&#9;&#9;&#9;TempSpaceLabel = nil
&#9;&#9;}
---------------------------------------------------
local function GetNameValue(pName)
&#9;local value = 0
&#9;for index = 1, #pName do
&#9;&#9;local cValue = string.byte(string.sub(pName, index, index))
&#9;&#9;local reverseIndex = #pName - index + 1
&#9;&#9;if #pName%2 == 1 then
&#9;&#9;&#9;reverseIndex = reverseIndex - 1&#9;&#9;&#9;
&#9;&#9;end
&#9;&#9;if reverseIndex%4 &gt;= 2 then
&#9;&#9;&#9;cValue = -cValue &#9;&#9;&#9;
&#9;&#9;end
&#9;&#9;value = value + cValue
&#9;end
&#9;return value%8
end
function Chat:ComputeChatColor(pName)
&#9;return self.ChatColors[GetNameValue(pName) + 1].Color
end
-- This is context based scrolling
function Chat:EnableScrolling(toggle)
&#9;-- Genius idea gone to fail, if we switch the camera type we can effectively lock the
&#9;-- camera and do no click scrolling
&#9;self.MouseOnFrame = false
&#9;if self.RenderFrame then
&#9;&#9;self.RenderFrame.MouseEnter:connect(function()&#9;&#9;&#9;
&#9;&#9;&#9;local character = Player.Character
&#9;&#9;&#9;local torso = WaitForChild(character, &apos;Torso&apos;)
&#9;&#9;&#9;local humanoid = WaitForChild(character, &apos;Humanoid&apos;)
&#9;&#9;&#9;local head = WaitForChild(character, &apos;Head&apos;)
&#9;&#9;&#9;if toggle then
&#9;&#9;&#9;&#9;self.MouseOnFrame = true
&#9;&#9;&#9;&#9;Camera.CameraType = &apos;Scriptable&apos;
&#9;&#9;&#9;&#9;-- Get relative position of camera and keep to it
&#9;&#9;&#9;&#9;Spawn(function()&#9;
&#9;&#9;&#9;&#9;&#9;local currentRelativePos = Camera.CoordinateFrame.p - torso.Position
&#9;&#9;&#9;&#9;&#9;while Chat.MouseOnFrame do
&#9;&#9;&#9;&#9;&#9;&#9;Camera.CoordinateFrame = CFrame.new(torso.Position + currentRelativePos, head.Position)
&#9;&#9;&#9;&#9;&#9;&#9;wait(0.015)
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;&#9;self.RenderFrame.MouseLeave:connect(function()
&#9;&#9;&#9;Camera.CameraType = &apos;Custom&apos;
&#9;&#9;&#9;self.MouseOnFrame = false
&#9;&#9;end)
&#9;end &#9;
end
-- TODO: Scrolling using Mouse wheel
function Chat:OnScroll(speed)
&#9;if self.MouseOnFrame then
&#9;&#9;--
&#9;end
end
-- Check if we are running on a touch device
function Chat:IsTouchDevice()
&#9;local touchEnabled = false
&#9;pcall(function() touchEnabled = Game:GetService(&apos;UserInputService&apos;).TouchEnabled end)&#9;
&#9;return touchEnabled
end
-- Scrolling
function Chat:ScrollQueue(value)&#9;
&#9;--[[for i = 1, #self.MessageQueue do
&#9;&#9;if self.MessageQueue[i] then
&#9;&#9;&#9;for _, label in pairs(self.MessageQueue[i]) do
&#9;&#9;&#9;&#9;local next = self.MessageQueue[i].Next
&#9;&#9;&#9;&#9;local previous = self.MessageQueue[i].Previous
&#9;&#9;&#9;&#9;if label and label:IsA(&apos;TextLabel&apos;) or label:IsA(&apos;TextButton&apos;) then &#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;if value &gt; 0 and previous and previous[&apos;Message&apos;] then &#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;label.Position = previous[&apos;Message&apos;].Position
&#9;&#9;&#9;&#9;&#9;elseif value &lt; 1 and next[&apos;Message&apos;] then
&#9;&#9;&#9;&#9;&#9;&#9;label.Position = previous[&apos;Message&apos;].Position
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end ]]
end
-- Handles the rendering of the text objects in their appropriate places
function Chat:UpdateQueue(field, diff)&#9;
&#9;-- Have to do some sort of correction here &#9;&#9;&#9;&#9;
&#9;for i = #self.MessageQueue, 1, -1 do &#9;&#9;&#9;
&#9;&#9;if self.MessageQueue[i] then &#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;for _, label in pairs(self.MessageQueue[i]) do &#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;if label and type(label) ~= &apos;table&apos; and type(label) ~= &apos;number&apos; then&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;if label:IsA(&apos;TextLabel&apos;) or label:IsA(&apos;TextButton&apos;) then &#9;
&#9;&#9;&#9;&#9;&#9;&#9;if diff then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;label.Position = label.Position - UDim2.new(0, 0, diff, 0)
&#9;&#9;&#9;&#9;&#9;&#9;else&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;if field == self.MessageQueue[i] then &#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;label.Position = UDim2.new(self.Configuration.XScale, 0, label.Position.Y.Scale - field[&apos;Message&apos;].Size.Y.Scale , 0)
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;-- Just to show up popping effect for the latest message in chat
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Spawn(function()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;wait(0.05)&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;while label.TextTransparency &gt;= 0 do
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;label.TextTransparency = label.TextTransparency - 0.2
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;wait(0.03)
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;end &#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;if label == field[&apos;Message&apos;] then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;label.TextStrokeTransparency = 0.8
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;label.TextStrokeTransparency = 1.0
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;end &#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;&#9;&#9;&#9;&#9;&#9;else &#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;label.Position = UDim2.new(self.Configuration.XScale, 0, label.Position.Y.Scale - field[&apos;Message&apos;].Size.Y.Scale, 0)&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;&#9;&#9;if label.Position.Y.Scale &lt; -0.01 then &#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;-- NOTE: Remove this fix when Textbounds is fixed
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;label.Visible = false &#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;label:Destroy()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end &#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end&#9;
end
function Chat:CreateScrollBar()
&#9;-- Code for scrolling is in here, partially, but scroll bar drawing isn&apos;t drawn
&#9;-- TODO: Implement
end
-- For scrolling, to see if we hit the bounds so that we can stop it from scrolling anymore
function Chat:CheckIfInBounds(value)
&#9;if #Chat.MessageQueue &lt; 3 then
&#9;&#9;return true
&#9;end
&#9;if value &gt; 0 and Chat.MessageQueue[1] and Chat.MessageQueue[1][&apos;Player&apos;] and Chat.MessageQueue[1][&apos;Player&apos;].Position.Y.Scale == 0 then
&#9;&#9;return true
&#9;elseif value &lt; 0 and Chat.MessageQueue[1] and Chat.MessageQueue[1][&apos;Player&apos;] and Chat.MessageQueue[1][&apos;Player&apos;].Position.Y.Scale &lt; 0 then
&#9;&#9;return true
&#9;else
&#9;&#9;return false
&#9;end
&#9;return false
end
-- This is to precompute all playerName space strings
-- This is used to offset the message by exactly this + 2 spacestrings
function Chat:ComputeSpaceString(pLabel)
&#9;local nString = &quot; &quot;
&#9;if not self.TempSpaceLabel then
&#9;&#9;self.TempSpaceLabel = Create&apos;TextButton&apos;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;{
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Size = UDim2.new(0, pLabel.AbsoluteSize.X, 0, pLabel.AbsoluteSize.Y);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;FontSize = self.Configuration.FontSize;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Parent = self.RenderFrame;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;BackgroundTransparency = 1.0;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Text = nString;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Name = &apos;SpaceButton&apos;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;};
&#9;else
&#9;&#9;self.TempSpaceLabel.Text = nString
&#9;end
&#9;
&#9;while self.TempSpaceLabel.TextBounds.X &lt; pLabel.TextBounds.X do
&#9;&#9;nString = nString .. &quot; &quot;
&#9;&#9;self.TempSpaceLabel.Text = nString &#9;&#9;&#9;&#9;
&#9;end
&#9;nString = nString .. &quot; &quot;
&#9;self.CachedSpaceStrings_List[pLabel.Text] = nString
&#9;self.TempSpaceLabel.Text = &quot;&quot;
&#9;return nString&#9;
end
-- When the playerChatted event fires
-- The message is what the player chatted
function Chat:UpdateChat(cPlayer, message)
&#9;local messageField = {
&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Player&apos;] = cPlayer,
&#9;&#9;&#9;&#9;&#9;&#9;&#9;[&apos;Message&apos;] = message
&#9;&#9;&#9;&#9;&#9;&#9;}&#9;
&#9;if coroutine.status(Chat.MessageThread) == &apos;dead&apos; then &#9;&#9;
&#9;&#9;--Chat.Messages_List = {}&#9;&#9;
&#9;&#9;table.insert(Chat.Messages_List, messageField)&#9;&#9;&#9;&#9;
&#9;&#9;Chat.MessageThread = coroutine.create(function()
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;for i = 1, #Chat.Messages_List do &#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;local field = Chat.Messages_List[i]&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Chat:CreateMessage(field[&apos;Player&apos;], field[&apos;Message&apos;]) &#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Chat.Messages_List = {}&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;end)
&#9;&#9;coroutine.resume(Chat.MessageThread)
&#9;else
&#9;&#9;table.insert(Chat.Messages_List, messageField)
&#9;end
end
function Chat:RecalculateSpacing()
&#9;--[[for i = 1, #self.MessageQueue do
&#9;&#9;local pLabel = self.MessageQueue[i][&apos;Player&apos;]
&#9;&#9;local mLabel = self.MessageQueue[i][&apos;Message&apos;]&#9;&#9;
&#9;&#9;local prevYScale = mLabel.Size.Y.Scale
&#9;&#9;local prevText = mLabel.Text
&#9;&#9;mLabel.Text = prevText
&#9;&#9;local heightField = mLabel.TextBounds.Y&#9;
&#9;&#9;mLabel.Size = UDim2.new(1, 0, heightField/self.RenderFrame.AbsoluteSize.Y, 0)&#9;
&#9;&#9;pLabel.Size = mLabel.Size
&#9;&#9;local diff = mLabel.Size.Y.Scale - prevYScale
&#9;&#9;Chat:UpdateQueue(self.MessageQueue[i], diff)
&#9;end ]]
end
function Chat:ApplyFilter(str)
&#9;--[[for _, word in pair(self.Filter_List) do
&#9;&#9;if string.find(str, word) then
&#9;&#9;&#9;str:gsub(word, &apos;@#$^&apos;)
&#9;&#9;end
&#9;end ]]&#9;
end
-- NOTE: Temporarily disabled ring buffer to allow for chat to always wrap around
function Chat:CreateMessage(cPlayer, message)&#9;&#9;
&#9;local pName
&#9;if not cPlayer then
&#9;&#9;pName = &apos;&apos;
&#9;else
&#9;&#9;pName = cPlayer.Name&#9;&#9;&#9;
&#9;end &#9;
&#9;message = StringTrim(message)&#9;&#9;
&#9;local pLabel
&#9;local mLabel
&#9;-- Our history stores upto 50 messages that is 100 textlabels
&#9;-- If we ever hit the mark, which would be in every popular game btw
&#9;-- we wrap around and reuse the labels
&#9;if #self.MessageQueue &gt; self.Configuration.HistoryLength then
&#9;&#9;--[[pLabel = self.MessageQueue[#self.MessageQueue][&apos;Player&apos;]
&#9;&#9;mLabel = self.MessageQueue[#self.MessageQueue][&apos;Message&apos;]
&#9;&#9;pLabel.Text = pName .. &apos;:&apos;
&#9;&#9;pLabel.Name = pName
&#9;&#9;local pColor
&#9;&#9;if cPlayer.Neutral then
&#9;&#9;&#9;pLabel.TextColor3 = Chat:ComputeChatColor(pName)
&#9;&#9;else
&#9;&#9;&#9;pLabel.TextColor3 = cPlayer.TeamColor.Color
&#9;&#9;end
&#9;&#9;local nString
&#9;&#9;if not self.CachedSpaceStrings_List[pName] then
&#9;&#9;&#9;nString = Chat:ComputeSpaceString(pLabel)
&#9;&#9;else
&#9;&#9;&#9;nString = self.CachedSpaceStrings_List[pName]
&#9;&#9;end &#9;
&#9;&#9;mLabel.Text = &quot;&quot;
&#9;&#9;mLabel.Name = pName .. &quot; - message&quot;
&#9;&#9;mLabel.Text = nString .. message;
&#9;&#9;mLabel.Parent = nil
&#9;&#9;mLabel.Parent = self.RenderFrame&#9;&#9;
&#9;&#9;mLabel.Position = UDim2.new(0, 0, 1, 0);
&#9;&#9;pLabel.Position = UDim2.new(0, 0, 1, 0);]]
&#9;&#9;-- Reinserted at the beginning, ring buffer
&#9;&#9;self.MessageQueue[#self.MessageQueue] = nil
&#9;end
&#9;--else
&#9;&#9;-- Haven&apos;t hit the mark yet, so keep creating
&#9;&#9;pLabel = Create&apos;TextLabel&apos;
&#9;&#9;&#9;&#9;&#9;{
&#9;&#9;&#9;&#9;&#9;&#9;Name = pName;
&#9;&#9;&#9;&#9;&#9;&#9;Text = pName .. &quot;:&quot;;
&#9;&#9;&#9;&#9;&#9;&#9;TextColor3 = pColor;
&#9;&#9;&#9;&#9;&#9;&#9;FontSize = Chat.Configuration.FontSize;
&#9;&#9;&#9;&#9;&#9;&#9;TextXAlignment = Enum.TextXAlignment.Left;
&#9;&#9;&#9;&#9;&#9;&#9;TextYAlignment = Enum.TextYAlignment.Top;
&#9;&#9;&#9;&#9;&#9;&#9;Parent = self.RenderFrame;
&#9;&#9;&#9;&#9;&#9;&#9;TextWrapped = false;
&#9;&#9;&#9;&#9;&#9;&#9;Size = UDim2.new(1, 0, 0.1, 0);
&#9;&#9;&#9;&#9;&#9;&#9;BackgroundTransparency = 1.0;
&#9;&#9;&#9;&#9;&#9;&#9;TextTransparency = 1.0;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;Position = UDim2.new(0, 0, 1, 0);
&#9;&#9;&#9;&#9;&#9;&#9;BorderSizePixel = 0.0;
&#9;&#9;&#9;&#9;&#9;&#9;TextStrokeColor3 = Color3.new(0.5, 0.5, 0.5);
&#9;&#9;&#9;&#9;&#9;&#9;TextStrokeTransparency = 0.75;
&#9;&#9;&#9;&#9;&#9;&#9;--Active = false;
&#9;&#9;&#9;&#9;&#9;};&#9;&#9;&#9;&#9;&#9;
&#9;&#9;local pColor
&#9;&#9;if cPlayer.Neutral then
&#9;&#9;&#9;pLabel.TextColor3 = Chat:ComputeChatColor(pName)
&#9;&#9;else
&#9;&#9;&#9;pLabel.TextColor3 = cPlayer.TeamColor.Color
&#9;&#9;end
&#9;&#9;local nString
&#9;&#9;if not self.CachedSpaceStrings_List[pName] then
&#9;&#9;&#9;nString = Chat:ComputeSpaceString(pLabel)
&#9;&#9;else
&#9;&#9;&#9;nString = self.CachedSpaceStrings_List[pName]
&#9;&#9;end &#9;&#9;
&#9;&#9;mLabel = Create&apos;TextLabel&apos;
&#9;&#9;&#9;&#9;&#9;&#9;{
&#9;&#9;&#9;&#9;&#9;&#9;&#9;Name = pName .. &apos; - message&apos;;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;-- Max is 3 lines
&#9;&#9;&#9;&#9;&#9;&#9;&#9;Size = UDim2.new(1, 0, 0.5, 0);&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;TextColor3 = Chat.Configuration.MessageColor;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;FontSize = Chat.Configuration.FontSize;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;TextXAlignment = Enum.TextXAlignment.Left;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;TextYAlignment = Enum.TextYAlignment.Top;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;Text = &quot;&quot;; -- this is to stop when the engine reverts the swear words to default, which is button, ugh
&#9;&#9;&#9;&#9;&#9;&#9;&#9;Parent = self.RenderFrame;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;TextWrapped = true;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;BackgroundTransparency = 1.0;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;TextTransparency = 1.0;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;Position = UDim2.new(0, 0, 1, 0);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;BorderSizePixel = 0.0;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;TextStrokeColor3 = Color3.new(0, 0, 0);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;--TextStrokeTransparency = 0.8;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;--Active = false;
&#9;&#9;&#9;&#9;&#9;&#9;};
&#9;&#9;mLabel.Text = nString .. message;
&#9;&#9;if not pName then
&#9;&#9;&#9;pLabel.Text = &apos;&apos;
&#9;&#9;&#9;mLabel.TextColor3 = Color3.new(0, 0.4, 1.0)
&#9;&#9;end
&#9;--end
&#9;for _, adminName in pairs(self.Admins_List) do
&#9;&#9;if string.lower(adminName) == string.lower(pName) then
&#9;&#9;&#9;mLabel.TextColor3 = self.Configuration.AdminMessageColor
&#9;&#9;end
&#9;end
&#9;pLabel.Visible = true
&#9;mLabel.Visible = true
&#9;
&#9;-- This will give beautiful multilines as well
&#9;local heightField = mLabel.TextBounds.Y&#9;
&#9;mLabel.Size = UDim2.new(1, 0, heightField/self.RenderFrame.AbsoluteSize.Y, 0)&#9;
&#9;pLabel.Size = mLabel.Size
&#9;local yPixels = self.RenderFrame.AbsoluteSize.Y
&#9;local yFieldSize = mLabel.TextBounds.Y
&#9;local queueField = {}&#9;
&#9;queueField[&apos;Player&apos;] = pLabel
&#9;queueField[&apos;Message&apos;] = mLabel
&#9;queueField[&apos;SpawnTime&apos;] = tick() -- Used for identifying when to make the message invisible
&#9;table.insert(self.MessageQueue, 1, queueField)&#9;&#9;
&#9;Chat:UpdateQueue(queueField)
end
function Chat:ScreenSizeChanged() &#9;
&#9;wait()
&#9;while self.Frame.AbsoluteSize.Y &gt; 120 do
&#9;&#9;self.Frame.Size = self.Frame.Size - UDim2.new(0, 0, 0.005, 0)
&#9;end
&#9;Chat:RecalculateSpacing()
end
function Chat:FindButtonTree(scButton, rootList)&#9;
&#9;local list = {}
&#9;rootList = rootList or self.SafeChatTree &#9;
&#9;for button, _ in pairs(rootList) do &#9;&#9;
&#9;&#9;if button == scButton then &#9;&#9;&#9;
&#9;&#9;&#9;list = rootList[button]
&#9;&#9;elseif type(rootList[button]) == &apos;table&apos; then
&#9;&#9;&#9;list = Chat:FindButtonTree(scButton, rootList[button])
&#9;&#9;end
&#9;end &#9;&#9;
&#9;return list
end
function Chat:ToggleSafeChatMenu(scButton)
&#9;local list = Chat:FindButtonTree(scButton, self.SafeChatTree)&#9;&#9;
&#9;if list then
&#9;&#9;for button, _ in pairs(list) do
&#9;&#9;&#9;if button:IsA(&apos;TextButton&apos;) or button:IsA(&apos;ImageButton&apos;) then
&#9;&#9;&#9;&#9;button.Visible = not button.Visible
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;return true
&#9;end
&#9;return false
end
function Chat:CreateSafeChatOptions(list, rootButton)
&#9;local text_List = {}
&#9;level = level or 0
&#9;local count = 0
&#9;text_List[rootButton] = {}
&#9;text_List[rootButton][1] = list[1]
&#9;rootButton = rootButton or self.SafeChatButton
&#9;for msg, _ in pairs(list) do
&#9;&#9;if type(msg) == &apos;string&apos; then
&#9;&#9;&#9;local chatText = Create&apos;TextButton&apos;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;{
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Name = msg;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Text = msg;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Size = UDim2.new(0, 100, 0, 20);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;TextXAlignment = Enum.TextXAlignment.Center;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;TextColor3 = Color3.new(0.2, 0.1, 0.1);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;BackgroundTransparency = 0.5;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;BackgroundColor3 = Color3.new(1, 1, 1);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Parent = self.SafeChatFrame;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Visible = false;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Position = UDim2.new(0, rootButton.Position.X.Scale + 105, 0, rootButton.Position.Y.Scale - ((count - 3) * 100));
&#9;&#9;&#9;&#9;&#9;&#9;&#9;};
&#9;&#9;&#9;count = count + 1
&#9;&#9;&#9;if type(list[msg]) == &apos;table&apos; then &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;text_List[rootButton][chatText] = Chat:CreateSafeChatOptions(list[msg], chatText)&#9;&#9;&#9;&#9;
&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;--table.insert(text_List[chatText], true)
&#9;&#9;&#9;end
&#9;&#9;&#9;chatText.MouseEnter:connect(function()
&#9;&#9;&#9;&#9;Chat:ToggleSafeChatMenu(chatText)
&#9;&#9;&#9;end)
&#9;&#9;&#9;chatText.MouseLeave:connect(function()
&#9;&#9;&#9;&#9;Chat:ToggleSafeChatMenu(chatText)
&#9;&#9;&#9;end)
&#9;&#9;&#9;chatText.MouseButton1Click:connect(function()&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;local lList = Chat:FindButtonTree(chatText)
&#9;&#9;&#9;&#9;if lList then &#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;for i, v in pairs(lList) do &#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;else &#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;pcall(function() PlayersService:Chat(lList[1])&#9;end)
&#9;&#9;&#9;end)
&#9;&#9;end
&#9;end
&#9;return text_List
end
function Chat:CreateSafeChatGui()
&#9;self.SafeChatFrame = Create&apos;Frame&apos;
&#9;&#9;&#9;&#9;&#9;&#9;{
&#9;&#9;&#9;&#9;&#9;&#9;&#9;Name = &apos;SafeChatFrame&apos;;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;Size = UDim2.new(1, 0, 1, 0);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;Parent = self.Gui;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;BackgroundTransparency = 1.0;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;Create&apos;ImageButton&apos;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;{
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Name = &apos;SafeChatButton&apos;;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Size = UDim2.new(0, 44, 0, 31);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Position = UDim2.new(0, 1, 0.35, 0);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;BackgroundTransparency = 1.0;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Image = &apos;http://www.roblox.com/asset/?id=97080365&apos;;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;};
&#9;&#9;&#9;&#9;&#9;&#9;}
&#9;self.SafeChatButton = self.SafeChatFrame.SafeChatButton
&#9;-- safe chat button is the root of this tree
&#9;self.SafeChatTree[self.SafeChatButton] = Chat:CreateSafeChatOptions(self.SafeChat_List, self.SafeChatButton)
&#9;self.SafeChatButton.MouseButton1Click:connect(function()&#9;&#9;
&#9;&#9;Chat:ToggleSafeChatMenu(self.SafeChatButton)
&#9;end)
end
function Chat:FocusOnChatBar()
&#9;if self.ClickToChatButton then
&#9;&#9;self.ClickToChatButton.Visible = false &#9;
&#9;end
&#9;self.GotFocus = true
&#9;if self.Frame[&apos;Background&apos;] then
&#9;&#9;self.Frame.Background.Visible = false
&#9;end &#9;
&#9;self.ChatBar:CaptureFocus()
end
-- For touch devices we create a button instead
function Chat:CreateTouchButton()&#9;
&#9;self.ChatTouchFrame = Create&apos;Frame&apos;
&#9;&#9;&#9;&#9;&#9;&#9;{
&#9;&#9;&#9;&#9;&#9;&#9;&#9;Name = &apos;ChatTouchFrame&apos;;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;Size = UDim2.new(0, 128, 0, 32);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;Position = UDim2.new(0, 88, 0, 0);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;BackgroundTransparency = 1.0;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;Parent = self.Gui;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;Create&apos;ImageButton&apos;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;{
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Name = &apos;ChatLabel&apos;;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Size = UDim2.new(0, 74, 0, 28);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Position = UDim2.new(0, 0, 0, 0);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;BackgroundTransparency = 1.0;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;ZIndex = 2.0;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;};&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;Create&apos;ImageLabel&apos;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;{
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Name = &apos;Background&apos;;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Size = UDim2.new(1, 0, 1, 0);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Position = UDim2.new(0, 0, 0, 0);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;BackgroundTransparency = 1.0;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Image = &apos;http://www.roblox.com/asset/?id=97078724&apos;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;};
&#9;&#9;&#9;&#9;&#9;&#9;}
&#9;self.TapToChatLabel = self.ChatTouchFrame.ChatLabel&#9;
&#9;self.TouchLabelBackground = self.ChatTouchFrame.Background
&#9;self.ChatBar = Create&apos;TextBox&apos;
&#9;&#9;&#9;&#9;&#9;{
&#9;&#9;&#9;&#9;&#9;&#9;Name = &apos;ChatBar&apos;;
&#9;&#9;&#9;&#9;&#9;&#9;Size = UDim2.new(1, 0, 0.2, 0);
&#9;&#9;&#9;&#9;&#9;&#9;Position = UDim2.new(0, 0, 0.8, 800);
&#9;&#9;&#9;&#9;&#9;&#9;Text = &quot;&quot;;
&#9;&#9;&#9;&#9;&#9;&#9;ZIndex = 1.0;
&#9;&#9;&#9;&#9;&#9;&#9;BackgroundTransparency = 1.0;
&#9;&#9;&#9;&#9;&#9;&#9;Parent = self.Frame;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;TextXAlignment = Enum.TextXAlignment.Left;
&#9;&#9;&#9;&#9;&#9;&#9;TextColor3 = Color3.new(1, 1, 1);&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;ClearTextOnFocus = false;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;};&#9;
&#9;self.TapToChatLabel.MouseButton1Click:connect(function()
&#9;&#9;self.TapToChatLabel.Visible = false
&#9;&#9;--self.ChatBar.Visible = true
&#9;&#9;--self.Frame.Background.Visible = true&#9;&#9;&#9;
&#9;&#9;self.ChatBar:CaptureFocus()
&#9;&#9;self.GotFocus = true
&#9;&#9;if self.TouchLabelBackground then
&#9;&#9;&#9;self.TouchLabelBackground.Visible = false
&#9;&#9;end
&#9;end)
end
-- Non touch devices, create the bottom chat bar
function Chat:CreateChatBar()
&#9;-- okay now we do
&#9;local status, result = pcall(function() return GuiService.UseLuaChat end)&#9;&#9;
&#9;if status and result then &#9;
&#9;&#9;self.ClickToChatButton = Create&apos;TextButton&apos;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;{
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Name = &apos;ClickToChat&apos;;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Size = UDim2.new(1, 0, 0, 20);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;BackgroundTransparency = 1.0;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;ZIndex = 2.0;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Parent = self.Gui;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Text = &quot;To chat click here or press \&quot;/\&quot; key&quot;;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;TextColor3 = Color3.new(1, 1, 0.9);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Position = UDim2.new(0, 0, 1, 0);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;TextXAlignment = Enum.TextXAlignment.Left;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;FontSize = Enum.FontSize.Size12;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;}
&#9;&#9;self.ChatBar = Create&apos;TextBox&apos;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;{
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Name = &apos;ChatBar&apos;;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Size = UDim2.new(1, 0, 0, 20);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Position = UDim2.new(0, 0, 1, 0);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Text = &quot;&quot;;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;ZIndex = 1.0;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;BackgroundColor3 = Color3.new(0, 0, 0);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;BackgroundTransparency = 0.25;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Parent = self.Gui;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;TextXAlignment = Enum.TextXAlignment.Left;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;TextColor3 = Color3.new(1, 1, 1);&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;FontSize = Enum.FontSize.Size12;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;ClearTextOnFocus = false;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Text = &apos;&apos;;&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;};&#9;
&#9;&#9;-- Engine has code to offset the entire world, so if we do it by -20 pixels nothing gets in our chat&apos;s way
&#9;&#9;GuiService:SetGlobalSizeOffsetPixel(0, -20)
&#9;&#9;-- CHatHotKey is &apos;/&apos;
&#9;&#9;GuiService:AddSpecialKey(Enum.SpecialKey.ChatHotkey)
&#9;&#9;GuiService.SpecialKeyPressed:connect(function(key)
&#9;&#9;&#9;if key == Enum.SpecialKey.ChatHotkey then
&#9;&#9;&#9;&#9;Chat:FocusOnChatBar()
&#9;&#9;&#9;end
&#9;&#9;end)&#9;
&#9;&#9;self.ClickToChatButton.MouseButton1Click:connect(function()
&#9;&#9;&#9;Chat:FocusOnChatBar()
&#9;&#9;end)&#9;
&#9;end
end
-- Create the initial Chat stuff
-- Done only once
function Chat:CreateGui()
&#9;self.Gui = script.Parent
&#9;self.Frame = Create&apos;Frame&apos;
&#9;&#9;&#9;&#9;{&#9;
&#9;&#9;&#9;&#9;&#9;Name = &apos;ChatFrame&apos;;
&#9;&#9;&#9;&#9;&#9;--Size = self.Configuration.Size;
&#9;&#9;&#9;&#9;&#9;Size = UDim2.new(0, 500, 0, 120);
&#9;&#9;&#9;&#9;&#9;Position = UDim2.new(0, 0, 0, 5);
&#9;&#9;&#9;&#9;&#9;BackgroundTransparency = 1.0;
&#9;&#9;&#9;&#9;&#9;--ClipsDescendants = true;
&#9;&#9;&#9;&#9;&#9;ZIndex = 0.0;
&#9;&#9;&#9;&#9;&#9;Parent = self.Gui;
&#9;&#9;&#9;&#9;&#9;Active = false;
&#9;&#9;&#9;&#9;&#9;Create&apos;ImageLabel&apos;
&#9;&#9;&#9;&#9;&#9;{
&#9;&#9;&#9;&#9;&#9;&#9;Name = &apos;Background&apos;;
&#9;&#9;&#9;&#9;&#9;&#9;Image = &apos;http://www.roblox.com/asset/?id=97120937&apos;; --96551212&apos;;
&#9;&#9;&#9;&#9;&#9;&#9;Size = UDim2.new(1.3, 0, 1.64, 0);
&#9;&#9;&#9;&#9;&#9;&#9;Position = UDim2.new(0, 0, 0, 0);
&#9;&#9;&#9;&#9;&#9;&#9;BackgroundTransparency = 1.0;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;ZIndex = 0.0;
&#9;&#9;&#9;&#9;&#9;&#9;Visible = false
&#9;&#9;&#9;&#9;&#9;};
&#9;&#9;&#9;&#9;&#9;Create&apos;Frame&apos;
&#9;&#9;&#9;&#9;&#9;{
&#9;&#9;&#9;&#9;&#9;&#9;Name = &apos;Border&apos;;
&#9;&#9;&#9;&#9;&#9;&#9;Size = UDim2.new(1, 0, 0, 1);
&#9;&#9;&#9;&#9;&#9;&#9;Position = UDim2.new(0, 0, 0.8, 0);
&#9;&#9;&#9;&#9;&#9;&#9;BackgroundTransparency = 0.0;
&#9;&#9;&#9;&#9;&#9;&#9;BackgroundColor3 = Color3.new(236/255, 236/255, 236/255);
&#9;&#9;&#9;&#9;&#9;&#9;BorderSizePixel = 0.0;
&#9;&#9;&#9;&#9;&#9;&#9;Visible = false;
&#9;&#9;&#9;&#9;&#9;};
&#9;&#9;&#9;&#9;&#9;Create&apos;Frame&apos;
&#9;&#9;&#9;&#9;&#9;{
&#9;&#9;&#9;&#9;&#9;&#9;Name = &apos;ChatRenderFrame&apos;;
&#9;&#9;&#9;&#9;&#9;&#9;Size = UDim2.new(1.02, 0, 1.01, 0);
&#9;&#9;&#9;&#9;&#9;&#9;Position = UDim2.new(0, 0, 0, 0);&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;BackgroundTransparency = 1.0;
&#9;&#9;&#9;&#9;&#9;&#9;--ClipsDescendants = true;
&#9;&#9;&#9;&#9;&#9;&#9;ZIndex = 0.0;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;Active = false;&#9;
&#9;&#9;&#9;&#9;&#9;};&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;};&#9;&#9;
&#9;Spawn(function()
&#9;&#9;wait(0.5)
&#9;&#9;if IsPhone() then
&#9;&#9;&#9;self.Frame.Size = UDim2.new(0, 280, 0, 120)
&#9;&#9;end
&#9;end)&#9;&#9;&#9;&#9;&#9;
&#9;
&#9;self.RenderFrame = self.Frame.ChatRenderFrame &#9;&#9;
&#9;if Chat:IsTouchDevice() then
&#9;&#9;self.Frame.Position = self.Configuration.Position;
&#9;&#9;self.RenderFrame.Size = UDim2.new(1, 0, 1, 0)
&#9;elseif self.Frame.AbsoluteSize.Y &gt; 120 then
&#9;&#9;Chat:ScreenSizeChanged()
&#9;&#9;self.Gui.Changed:connect(function(property)
&#9;&#9;&#9;if property == &apos;AbsoluteSize&apos; then
&#9;&#9;&#9;&#9;Chat:ScreenSizeChanged()
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;end &#9;&#9;
&#9;if Player.ChatMode == Enum.ChatMode.TextAndMenu then &#9;&#9;&#9;
&#9;&#9;if Chat:IsTouchDevice() then
&#9;&#9;&#9;Chat:CreateTouchButton() &#9;
&#9;&#9;else
&#9;&#9;&#9;Chat:CreateChatBar()
&#9;&#9;&#9;--Chat:CreateSafeChatGui()
&#9;&#9;end
&#9;&#9;if self.ChatBar then
&#9;&#9;&#9;self.ChatBar.FocusLost:connect(function(enterPressed)
&#9;&#9;&#9;&#9;Chat.GotFocus = false
&#9;&#9;&#9;&#9;if Chat:IsTouchDevice() then
&#9;&#9;&#9;&#9;&#9;self.ChatBar.Visible = false
&#9;&#9;&#9;&#9;&#9;self.TapToChatLabel.Visible = true
&#9;&#9;&#9;&#9;&#9;if self.TouchLabelBackground then
&#9;&#9;&#9;&#9;&#9;&#9;self.TouchLabelBackground.Visible = true
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if enterPressed and self.ChatBar.Text ~= &quot;&quot; then
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;local cText = self.ChatBar.Text
&#9;&#9;&#9;&#9;&#9;if string.sub(self.ChatBar.Text, 1, 1) == &apos;%&apos; then
&#9;&#9;&#9;&#9;&#9;&#9;cText = &apos;(TEAM) &apos; .. string.sub(cText, 2, #cText)
&#9;&#9;&#9;&#9;&#9;&#9;pcall(function() PlayersService:TeamChat(cText) end)&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;pcall(function() PlayersService:Chat(cText) end)&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;end &#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;if self.ClickToChatButton then
&#9;&#9;&#9;&#9;&#9;&#9;self.ClickToChatButton.Visible = true
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;self.ChatBar.Text = &quot;&quot;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;Spawn(function()
&#9;&#9;&#9;&#9;&#9;wait(5.0)
&#9;&#9;&#9;&#9;&#9;if not Chat.GotFocus then &#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;Chat.Frame.Background.Visible = false
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end)&#9;&#9;
&#9;&#9;&#9;end)&#9;
&#9;&#9;end
&#9;end
end
-- Scrolling function
-- Applies a speed(velocity) to have nice scrolling effect
function Input:OnMouseScroll()
&#9;Spawn(function()
&#9;&#9;-- How long should the speed last?
&#9;&#9;while Input.Speed ~=0 do
&#9;&#9;&#9;if Input.Speed &gt; 1 then
&#9;&#9;&#9;&#9;while Input.Speed &gt; 0 do &#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;Input.Speed = Input.Speed - 1
&#9;&#9;&#9;&#9;&#9;wait(0.25)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;elseif Input.Speed &lt; 0 then &#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;while Input.Speed &lt; 0 do &#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;Input.Speed = Input.Speed + 1
&#9;&#9;&#9;&#9;&#9;wait(0.25)
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;wait(0.03)
&#9;&#9;end
&#9;end)
&#9;if Chat:CheckIfInBounds(Input.Speed) then
&#9;&#9;return
&#9;end
&#9;Chat:ScrollQueue()
end
function Input:ApplySpeed(value)
&#9;Input.Speed = Input.Speed + value
&#9;if not self.Simulating then
&#9;&#9;Input:OnMouseScroll()
&#9;end
end
function Input:Initialize()
&#9;self.Mouse.WheelBackward:connect(function()
&#9;&#9;Input:ApplySpeed(self.Configuration.DefaultSpeed)
&#9;end)
&#9;self.Mouse.WheelForward:connect(function()
&#9;&#9;Input:ApplySpeed(self.Configuration.DefaultSpeed)
&#9;end)
end
function Chat:FindMessageInSafeChat(message, list)
&#9;local foundMessage = false
&#9;for msg, _ in pairs(list) do &#9;&#9;
&#9;&#9;if msg == message then &#9;&#9;&#9;
&#9;&#9;&#9;return true
&#9;&#9;end
&#9;&#9;if type(list[msg]) == &apos;table&apos; then
&#9;&#9;&#9;foundMessage = Chat:FindMessageInSafeChat(message, list[msg])
&#9;&#9;&#9;if foundMessage then
&#9;&#9;&#9;&#9;return true
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;return foundMessage
end
-- Just a wrapper around our PlayerChatted event
function Chat:PlayerChatted(...)&#9;
&#9;local args = {...}
&#9;local argCount = select(&apos;#&apos;, ...)
&#9;local player
&#9;local message
&#9;-- This doesn&apos;t look very good, but what else to do?
&#9;if args[2] then
&#9;&#9;player = args[2]
&#9;end
&#9;if args[3] then
&#9;&#9;message = args[3]
&#9;&#9;if string.sub(message, 1, 1) == &apos;%&apos; then
&#9;&#9;&#9;message = &apos;(TEAM) &apos; .. string.sub(message, 2, #message)
&#9;&#9;end
&#9;end
&#9;if PlayersService.ClassicChat then &#9;&#9;&#9;&#9;
&#9;&#9;if Player.ChatMode == Enum.ChatMode.TextAndMenu then
&#9;&#9;&#9;Chat:UpdateChat(player, message)
&#9;&#9;elseif Player.ChatMode == Enum.ChatMode.Menu and string.sub(message, 3) == &apos;/sc&apos; then &#9;&#9;&#9;
&#9;&#9;&#9;Chat:UpdateChat(player, message)&#9;&#9;&#9;
&#9;&#9;else
&#9;&#9;&#9;if Chat:FindMessageInSafeChat(message, self.SafeChat_List) then
&#9;&#9;&#9;&#9;Chat:UpdateChat(player, message)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
end
-- After Chat.Configuration.Lifetime seconds of existence, the labels become invisible
-- Runs only every 5 seconds and has to loop through 50 values
-- Shouldn&apos;t be too expensive
function Chat:CullThread()
&#9;while true do
&#9;&#9;if #self.MessageQueue &gt; 0 then
&#9;&#9;&#9;for _, field in pairs(self.MessageQueue) do &#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;if field[&apos;SpawnTime&apos;] and field[&apos;Player&apos;] and field[&apos;Message&apos;] and tick() - field[&apos;SpawnTime&apos;] &gt; self.Configuration.LifeTime then
&#9;&#9;&#9;&#9;&#9;field[&apos;Player&apos;].Visible = false
&#9;&#9;&#9;&#9;&#9;field[&apos;Message&apos;].Visible = false
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;&#9;wait(5.0)
&#9;end
end
-- RobloxLock everything so users can&apos;t delete them(?)
function Chat:LockAllFields(gui)
end
-- Constructor
-- This function initializes everything
function Chat:Initialize()&#9;&#9;&#9;
&#9;Chat:CreateGui() &#9;&#9;
&#9;self.EventListener = PlayersService.PlayerChatted:connect(function(...) &#9;
&#9;&#9;-- This event has 4 callback arguments
&#9;&#9;-- Enum.PlayerChatType.All, chatPlayer, message, targetPlayer
&#9;&#9;Chat:PlayerChatted(...)
&#9;&#9;
&#9;end)
&#9;self.MessageThread = coroutine.create(function() end)
&#9;coroutine.resume(self.MessageThread)
&#9;-- Initialize input for us
&#9;Input:Initialize() &#9;
&#9;-- Eww, everytime a player is added, you have to redo the connection
&#9;-- Seems this is not automatic
&#9;-- NOTE: PlayerAdded only fires on the server, hence ChildAdded is used here
&#9;PlayersService.ChildAdded:connect(function()
&#9;&#9;Chat.EventListener:disconnect()
&#9;&#9;self.EventListener = PlayersService.PlayerChatted:connect(function(...) &#9;
&#9;&#9;&#9;-- This event has 4 callback arguments
&#9;&#9;&#9;-- Enum.PlayerChatType.All, chatPlayer, message, targetPlayer
&#9;&#9;&#9;Chat:PlayerChatted(...)
&#9;&#9;end)
&#9;end)
&#9;Spawn(function()
&#9;&#9;Chat:CullThread()
&#9;end)
&#9;self.Frame.DescendantAdded:connect(function(descendant)
&#9;end)&#9;
end
Chat:Initialize()
</ProtectedString>
</Properties>
</Item>
</Item>
</Item>
</roblox>