null nil false Sorter print("Special thanks to Bitl, Carrot, iago, winsupermario1234, Khangaroo, drslicendice, coke, TheLivingBee, Raymonf, and a bunch of play - testers for help making 2012 fully stable and work. 8)") script.Playerlist:clone().Parent = game.StarterGui script.Dialogs:clone().Parent = game.StarterGui script.Backpack:clone().Parent = game.StarterGui script.Health:clone().Parent = game.StarterGui script.Menu:clone().Parent = game.StarterGui script.ReenableDialogScript:clone().Parent = game.Lighting script.TimeoutScript:clone().Parent = game.Lighting script.ResetCommand:clone().Parent = game.Workspace script:remove() Playerlist false Init --fixed by Carrot#0559 --for non corescript use local t = {} local function ScopedConnect(parentInstance, instance, event, signalFunc, syncFunc, removeFunc) local eventConnection = nil --Connection on parentInstance is scoped by parentInstance (when destroyed, it goes away) local tryConnect = function() if game:IsAncestorOf(parentInstance) then --Entering the world, make sure we are connected/synced if not eventConnection then eventConnection = instance[event]:connect(signalFunc) if syncFunc then syncFunc() end end else --Probably leaving the world, so disconnect for now if eventConnection then eventConnection:disconnect() if removeFunc then removeFunc() end end end end --Hook it up to ancestryChanged signal local connection = parentInstance.AncestryChanged:connect(tryConnect) --Now connect us if we're already in the world tryConnect() return connection end local function getScreenGuiAncestor(instance) local localInstance = instance while localInstance and not localInstance:IsA("ScreenGui") do localInstance = localInstance.Parent end return localInstance end local function CreateButtons(frame, buttons, yPos, ySize) local buttonNum = 1 local buttonObjs = {} for i, obj in ipairs(buttons) do local button = Instance.new("TextButton") button.Name = "Button" .. buttonNum button.Font = Enum.Font.Arial button.FontSize = Enum.FontSize.Size18 button.AutoButtonColor = true button.Modal = true if obj["Style"] then button.Style = obj.Style else button.Style = Enum.ButtonStyle.RobloxButton end if obj["ZIndex"] then button.ZIndex = obj.ZIndex end button.Text = obj.Text button.TextColor3 = Color3.new(1,1,1) button.MouseButton1Click:connect(obj.Function) button.Parent = frame buttonObjs[buttonNum] = button buttonNum = buttonNum + 1 end local numButtons = buttonNum-1 if numButtons == 1 then frame.Button1.Position = UDim2.new(0.35, 0, yPos.Scale, yPos.Offset) frame.Button1.Size = UDim2.new(.4,0,ySize.Scale, ySize.Offset) elseif numButtons == 2 then frame.Button1.Position = UDim2.new(0.1, 0, yPos.Scale, yPos.Offset) frame.Button1.Size = UDim2.new(.8/3,0, ySize.Scale, ySize.Offset) frame.Button2.Position = UDim2.new(0.55, 0, yPos.Scale, yPos.Offset) frame.Button2.Size = UDim2.new(.35,0, ySize.Scale, ySize.Offset) elseif numButtons >= 3 then local spacing = .1 / numButtons local buttonSize = .9 / numButtons buttonNum = 1 while buttonNum <= numButtons do buttonObjs[buttonNum].Position = UDim2.new(spacing*buttonNum + (buttonNum-1) * buttonSize, 0, yPos.Scale, yPos.Offset) buttonObjs[buttonNum].Size = UDim2.new(buttonSize, 0, ySize.Scale, ySize.Offset) buttonNum = buttonNum + 1 end end end local function setSliderPos(newAbsPosX,slider,sliderPosition,bar,steps) local newStep = steps - 1 --otherwise we really get one more step than we want local relativePosX = math.min(1, math.max(0, (newAbsPosX - bar.AbsolutePosition.X) / bar.AbsoluteSize.X )) local wholeNum, remainder = math.modf(relativePosX * newStep) if remainder > 0.5 then wholeNum = wholeNum + 1 end relativePosX = wholeNum/newStep local result = math.ceil(relativePosX * newStep) if sliderPosition.Value ~= (result + 1) then --only update if we moved a step sliderPosition.Value = result + 1 slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset) end end local function cancelSlide(areaSoak) areaSoak.Visible = false if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end end t.CreateStyledMessageDialog = function(title, message, style, buttons) local frame = Instance.new("Frame") frame.Size = UDim2.new(0.5, 0, 0, 165) frame.Position = UDim2.new(0.25, 0, 0.5, -72.5) frame.Name = "MessageDialog" frame.Active = true frame.Style = Enum.FrameStyle.RobloxRound local styleImage = Instance.new("ImageLabel") styleImage.Name = "StyleImage" styleImage.BackgroundTransparency = 1 styleImage.Position = UDim2.new(0,5,0,15) if style == "error" or style == "Error" then styleImage.Size = UDim2.new(0, 71, 0, 71) styleImage.Image = "http://www.roblox.com/asset/?id=42565285" elseif style == "notify" or style == "Notify" then styleImage.Size = UDim2.new(0, 71, 0, 71) styleImage.Image = "http://www.roblox.com/asset/?id=42604978" elseif style == "confirm" or style == "Confirm" then styleImage.Size = UDim2.new(0, 74, 0, 76) styleImage.Image = "http://www.roblox.com/asset/?id=42557901" else return t.CreateMessageDialog(title,message,buttons) end styleImage.Parent = frame local titleLabel = Instance.new("TextLabel") titleLabel.Name = "Title" titleLabel.Text = title titleLabel.TextStrokeTransparency = 0 titleLabel.BackgroundTransparency = 1 titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255) titleLabel.Position = UDim2.new(0, 80, 0, 0) titleLabel.Size = UDim2.new(1, -80, 0, 40) titleLabel.Font = Enum.Font.ArialBold titleLabel.FontSize = Enum.FontSize.Size36 titleLabel.TextXAlignment = Enum.TextXAlignment.Center titleLabel.TextYAlignment = Enum.TextYAlignment.Center titleLabel.Parent = frame local messageLabel = Instance.new("TextLabel") messageLabel.Name = "Message" messageLabel.Text = message messageLabel.TextStrokeTransparency = 0 messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255) messageLabel.Position = UDim2.new(0.025, 80, 0, 45) messageLabel.Size = UDim2.new(0.95, -80, 0, 55) messageLabel.BackgroundTransparency = 1 messageLabel.Font = Enum.Font.Arial messageLabel.FontSize = Enum.FontSize.Size18 messageLabel.TextWrap = true messageLabel.TextXAlignment = Enum.TextXAlignment.Left messageLabel.TextYAlignment = Enum.TextYAlignment.Top messageLabel.Parent = frame CreateButtons(frame, buttons, UDim.new(0, 105), UDim.new(0, 40) ) return frame end t.CreateMessageDialog = function(title, message, buttons) local frame = Instance.new("Frame") frame.Size = UDim2.new(0.5, 0, 0.5, 0) frame.Position = UDim2.new(0.25, 0, 0.25, 0) frame.Name = "MessageDialog" frame.Active = true frame.Style = Enum.FrameStyle.RobloxRound local titleLabel = Instance.new("TextLabel") titleLabel.Name = "Title" titleLabel.Text = title titleLabel.BackgroundTransparency = 1 titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255) titleLabel.Position = UDim2.new(0, 0, 0, 0) titleLabel.Size = UDim2.new(1, 0, 0.15, 0) titleLabel.Font = Enum.Font.ArialBold titleLabel.FontSize = Enum.FontSize.Size36 titleLabel.TextXAlignment = Enum.TextXAlignment.Center titleLabel.TextYAlignment = Enum.TextYAlignment.Center titleLabel.Parent = frame local messageLabel = Instance.new("TextLabel") messageLabel.Name = "Message" messageLabel.Text = message messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255) messageLabel.Position = UDim2.new(0.025, 0, 0.175, 0) messageLabel.Size = UDim2.new(0.95, 0, .55, 0) messageLabel.BackgroundTransparency = 1 messageLabel.Font = Enum.Font.Arial messageLabel.FontSize = Enum.FontSize.Size18 messageLabel.TextWrap = true messageLabel.TextXAlignment = Enum.TextXAlignment.Left messageLabel.TextYAlignment = Enum.TextYAlignment.Top messageLabel.Parent = frame CreateButtons(frame, buttons, UDim.new(0.8,0), UDim.new(0.15, 0)) return frame end t.CreateDropDownMenu = function(items, onSelect, forRoblox, whiteSkin, baseZ) local baseZIndex = 0 if (type(baseZ) == "number") then baseZIndex = baseZ end local width = UDim.new(0, 100) local height = UDim.new(0, 32) local xPos = 0.055 local frame = Instance.new("Frame") local textColor = Color3.new(1,1,1) if (whiteSkin) then textColor = Color3.new(0.5, 0.5, 0.5) end frame.Name = "DropDownMenu" frame.BackgroundTransparency = 1 frame.Size = UDim2.new(width, height) local dropDownMenu = Instance.new("TextButton") dropDownMenu.Name = "DropDownMenuButton" dropDownMenu.TextWrap = true dropDownMenu.TextColor3 = textColor dropDownMenu.Text = "Choose One" dropDownMenu.Font = Enum.Font.ArialBold dropDownMenu.FontSize = Enum.FontSize.Size18 dropDownMenu.TextXAlignment = Enum.TextXAlignment.Left dropDownMenu.TextYAlignment = Enum.TextYAlignment.Center dropDownMenu.BackgroundTransparency = 1 dropDownMenu.AutoButtonColor = true if (whiteSkin) then dropDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton else dropDownMenu.Style = Enum.ButtonStyle.RobloxButton end dropDownMenu.Size = UDim2.new(1,0,1,0) dropDownMenu.Parent = frame dropDownMenu.ZIndex = 2 + baseZIndex local dropDownIcon = Instance.new("ImageLabel") dropDownIcon.Name = "Icon" dropDownIcon.Active = false if (whiteSkin) then dropDownIcon.Image = "rbxasset://textures/ui/dropdown_arrow.png" dropDownIcon.Size = UDim2.new(0,16,0,12) dropDownIcon.Position = UDim2.new(1,-17,0.5, -6) else dropDownIcon.Image = "http://www.roblox.com/asset/?id=45732894" dropDownIcon.Size = UDim2.new(0,11,0,6) dropDownIcon.Position = UDim2.new(1,-11,0.5, -2) end dropDownIcon.BackgroundTransparency = 1 dropDownIcon.Parent = dropDownMenu dropDownIcon.ZIndex = 2 + baseZIndex local itemCount = #items local dropDownItemCount = #items local useScrollButtons = false if dropDownItemCount > 6 then useScrollButtons = true dropDownItemCount = 6 end local droppedDownMenu = Instance.new("TextButton") droppedDownMenu.Name = "List" droppedDownMenu.Text = "" droppedDownMenu.BackgroundTransparency = 1 --droppedDownMenu.AutoButtonColor = true if (whiteSkin) then droppedDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton else droppedDownMenu.Style = Enum.ButtonStyle.RobloxButton end droppedDownMenu.Visible = false droppedDownMenu.Active = true --Blocks clicks droppedDownMenu.Position = UDim2.new(0,0,0,0) droppedDownMenu.Size = UDim2.new(1,0, (1 + dropDownItemCount)*.8, 0) droppedDownMenu.Parent = frame droppedDownMenu.ZIndex = 2 + baseZIndex local choiceButton = Instance.new("TextButton") choiceButton.Name = "ChoiceButton" choiceButton.BackgroundTransparency = 1 choiceButton.BorderSizePixel = 0 choiceButton.Text = "ReplaceMe" choiceButton.TextColor3 = textColor choiceButton.TextXAlignment = Enum.TextXAlignment.Left choiceButton.TextYAlignment = Enum.TextYAlignment.Center choiceButton.BackgroundColor3 = Color3.new(1, 1, 1) choiceButton.Font = Enum.Font.Arial choiceButton.FontSize = Enum.FontSize.Size18 if useScrollButtons then choiceButton.Size = UDim2.new(1,-13, .8/((dropDownItemCount + 1)*.8),0) else choiceButton.Size = UDim2.new(1, 0, .8/((dropDownItemCount + 1)*.8),0) end choiceButton.TextWrap = true choiceButton.ZIndex = 2 + baseZIndex local areaSoak = Instance.new("TextButton") areaSoak.Name = "AreaSoak" areaSoak.Text = "" areaSoak.BackgroundTransparency = 1 areaSoak.Active = true areaSoak.Size = UDim2.new(1,0,1,0) areaSoak.Visible = false areaSoak.ZIndex = 3 + baseZIndex local dropDownSelected = false local scrollUpButton local scrollDownButton local scrollMouseCount = 0 local setZIndex = function(baseZIndex) droppedDownMenu.ZIndex = baseZIndex +1 if scrollUpButton then scrollUpButton.ZIndex = baseZIndex + 3 end if scrollDownButton then scrollDownButton.ZIndex = baseZIndex + 3 end local children = droppedDownMenu:GetChildren() if children then for i, child in ipairs(children) do if child.Name == "ChoiceButton" then child.ZIndex = baseZIndex + 2 elseif child.Name == "ClickCaptureButton" then child.ZIndex = baseZIndex end end end end local scrollBarPosition = 1 local updateScroll = function() if scrollUpButton then scrollUpButton.Active = scrollBarPosition > 1 end if scrollDownButton then scrollDownButton.Active = scrollBarPosition + dropDownItemCount <= itemCount end local children = droppedDownMenu:GetChildren() if not children then return end local childNum = 1 for i, obj in ipairs(children) do if obj.Name == "ChoiceButton" then if childNum < scrollBarPosition or childNum >= scrollBarPosition + dropDownItemCount then obj.Visible = false else obj.Position = UDim2.new(0,0,((childNum-scrollBarPosition+1)*.8)/((dropDownItemCount+1)*.8),0) obj.Visible = true end obj.TextColor3 = textColor obj.BackgroundTransparency = 1 childNum = childNum + 1 end end end local toggleVisibility = function() dropDownSelected = not dropDownSelected areaSoak.Visible = not areaSoak.Visible dropDownMenu.Visible = not dropDownSelected droppedDownMenu.Visible = dropDownSelected if dropDownSelected then setZIndex(4 + baseZIndex) else setZIndex(2 + baseZIndex) end if useScrollButtons then updateScroll() end end droppedDownMenu.MouseButton1Click:connect(toggleVisibility) local updateSelection = function(text) local foundItem = false local children = droppedDownMenu:GetChildren() local childNum = 1 if children then for i, obj in ipairs(children) do if obj.Name == "ChoiceButton" then if obj.Text == text then obj.Font = Enum.Font.ArialBold foundItem = true scrollBarPosition = childNum if (whiteSkin) then obj.TextColor3 = Color3.new(90/255,142/255,233/255) end else obj.Font = Enum.Font.Arial if (whiteSkin) then obj.TextColor3 = textColor end end childNum = childNum + 1 end end end if not text then dropDownMenu.Text = "Choose One" scrollBarPosition = 1 else if not foundItem then error("Invalid Selection Update -- " .. text) end if scrollBarPosition + dropDownItemCount > itemCount + 1 then scrollBarPosition = itemCount - dropDownItemCount + 1 end dropDownMenu.Text = text end end local function scrollDown() if scrollBarPosition + dropDownItemCount <= itemCount then scrollBarPosition = scrollBarPosition + 1 updateScroll() return true end return false end local function scrollUp() if scrollBarPosition > 1 then scrollBarPosition = scrollBarPosition - 1 updateScroll() return true end return false end if useScrollButtons then --Make some scroll buttons scrollUpButton = Instance.new("ImageButton") scrollUpButton.Name = "ScrollUpButton" scrollUpButton.BackgroundTransparency = 1 scrollUpButton.Image = "rbxasset://textures/ui/scrollbuttonUp.png" scrollUpButton.Size = UDim2.new(0,17,0,17) scrollUpButton.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),0) scrollUpButton.MouseButton1Click:connect( function() scrollMouseCount = scrollMouseCount + 1 end) scrollUpButton.MouseLeave:connect( function() scrollMouseCount = scrollMouseCount + 1 end) scrollUpButton.MouseButton1Down:connect( function() scrollMouseCount = scrollMouseCount + 1 scrollUp() local val = scrollMouseCount wait(0.5) while val == scrollMouseCount do if scrollUp() == false then break end wait(0.1) end end) scrollUpButton.Parent = droppedDownMenu scrollDownButton = Instance.new("ImageButton") scrollDownButton.Name = "ScrollDownButton" scrollDownButton.BackgroundTransparency = 1 scrollDownButton.Image = "rbxasset://textures/ui/scrollbuttonDown.png" scrollDownButton.Size = UDim2.new(0,17,0,17) scrollDownButton.Position = UDim2.new(1,-11,1,-11) scrollDownButton.Parent = droppedDownMenu scrollDownButton.MouseButton1Click:connect( function() scrollMouseCount = scrollMouseCount + 1 end) scrollDownButton.MouseLeave:connect( function() scrollMouseCount = scrollMouseCount + 1 end) scrollDownButton.MouseButton1Down:connect( function() scrollMouseCount = scrollMouseCount + 1 scrollDown() local val = scrollMouseCount wait(0.5) while val == scrollMouseCount do if scrollDown() == false then break end wait(0.1) end end) local scrollbar = Instance.new("ImageLabel") scrollbar.Name = "ScrollBar" scrollbar.Image = "rbxasset://textures/ui/scrollbar.png" scrollbar.BackgroundTransparency = 1 scrollbar.Size = UDim2.new(0, 18, (dropDownItemCount*.8)/((dropDownItemCount+1)*.8), -(17) - 11 - 4) scrollbar.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),17+2) scrollbar.Parent = droppedDownMenu end for i,item in ipairs(items) do -- needed to maintain local scope for items in event listeners below local button = choiceButton:clone() if forRoblox then button.RobloxLocked = true end button.Text = item button.Parent = droppedDownMenu if (whiteSkin) then button.TextColor3 = textColor end button.MouseButton1Click:connect(function() --Remove Highlight if (not whiteSkin) then button.TextColor3 = Color3.new(1,1,1) end button.BackgroundTransparency = 1 updateSelection(item) onSelect(item) toggleVisibility() end) button.MouseEnter:connect(function() --Add Highlight if (not whiteSkin) then button.TextColor3 = Color3.new(0,0,0) end button.BackgroundTransparency = 0 end) button.MouseLeave:connect(function() --Remove Highlight if (not whiteSkin) then button.TextColor3 = Color3.new(1,1,1) end button.BackgroundTransparency = 1 end) end --This does the initial layout of the buttons updateScroll() frame.AncestryChanged:connect(function(child,parent) if parent == nil then areaSoak.Parent = nil else areaSoak.Parent = getScreenGuiAncestor(frame) end end) dropDownMenu.MouseButton1Click:connect(toggleVisibility) areaSoak.MouseButton1Click:connect(toggleVisibility) return frame, updateSelection end t.CreatePropertyDropDownMenu = function(instance, property, enum) local items = enum:GetEnumItems() local names = {} local nameToItem = {} for i,obj in ipairs(items) do names[i] = obj.Name nameToItem[obj.Name] = obj end local frame local updateSelection frame, updateSelection = t.CreateDropDownMenu(names, function(text) instance[property] = nameToItem[text] end) ScopedConnect(frame, instance, "Changed", function(prop) if prop == property then updateSelection(instance[property].Name) end end, function() updateSelection(instance[property].Name) end) return frame end t.GetFontHeight = function(font, fontSize) if font == nil or fontSize == nil then error("Font and FontSize must be non-nil") end if font == Enum.Font.Legacy then if fontSize == Enum.FontSize.Size8 then return 12 elseif fontSize == Enum.FontSize.Size9 then return 14 elseif fontSize == Enum.FontSize.Size10 then return 15 elseif fontSize == Enum.FontSize.Size11 then return 17 elseif fontSize == Enum.FontSize.Size12 then return 18 elseif fontSize == Enum.FontSize.Size14 then return 21 elseif fontSize == Enum.FontSize.Size18 then return 27 elseif fontSize == Enum.FontSize.Size24 then return 36 elseif fontSize == Enum.FontSize.Size36 then return 54 elseif fontSize == Enum.FontSize.Size48 then return 72 else error("Unknown FontSize") end elseif font == Enum.Font.Arial or font == Enum.Font.ArialBold then if fontSize == Enum.FontSize.Size8 then return 8 elseif fontSize == Enum.FontSize.Size9 then return 9 elseif fontSize == Enum.FontSize.Size10 then return 10 elseif fontSize == Enum.FontSize.Size11 then return 11 elseif fontSize == Enum.FontSize.Size12 then return 12 elseif fontSize == Enum.FontSize.Size14 then return 14 elseif fontSize == Enum.FontSize.Size18 then return 18 elseif fontSize == Enum.FontSize.Size24 then return 24 elseif fontSize == Enum.FontSize.Size36 then return 36 elseif fontSize == Enum.FontSize.Size48 then return 48 else error("Unknown FontSize") end else error("Unknown Font " .. font) end end local function layoutGuiObjectsHelper(frame, guiObjects, settingsTable) local totalPixels = frame.AbsoluteSize.Y local pixelsRemaining = frame.AbsoluteSize.Y for i, child in ipairs(guiObjects) do if child:IsA("TextLabel") or child:IsA("TextButton") then local isLabel = child:IsA("TextLabel") if isLabel then pixelsRemaining = pixelsRemaining - settingsTable["TextLabelPositionPadY"] else pixelsRemaining = pixelsRemaining - settingsTable["TextButtonPositionPadY"] end child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining) child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, pixelsRemaining) if child.TextFits and child.TextBounds.Y < pixelsRemaining then child.Visible = true if isLabel then child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable["TextLabelSizePadY"]) else child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable["TextButtonSizePadY"]) end while not child.TextFits do child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.AbsoluteSize.Y + 1) end pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y if isLabel then pixelsRemaining = pixelsRemaining - settingsTable["TextLabelPositionPadY"] else pixelsRemaining = pixelsRemaining - settingsTable["TextButtonPositionPadY"] end else child.Visible = false pixelsRemaining = -1 end else --GuiObject child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining) pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y child.Visible = (pixelsRemaining >= 0) end end end t.LayoutGuiObjects = function(frame, guiObjects, settingsTable) if not frame:IsA("GuiObject") then error("Frame must be a GuiObject") end for i, child in ipairs(guiObjects) do if not child:IsA("GuiObject") then error("All elements that are layed out must be of type GuiObject") end end if not settingsTable then settingsTable = {} end if not settingsTable["TextLabelSizePadY"] then settingsTable["TextLabelSizePadY"] = 0 end if not settingsTable["TextLabelPositionPadY"] then settingsTable["TextLabelPositionPadY"] = 0 end if not settingsTable["TextButtonSizePadY"] then settingsTable["TextButtonSizePadY"] = 12 end if not settingsTable["TextButtonPositionPadY"] then settingsTable["TextButtonPositionPadY"] = 2 end --Wrapper frame takes care of styled objects local wrapperFrame = Instance.new("Frame") wrapperFrame.Name = "WrapperFrame" wrapperFrame.BackgroundTransparency = 1 wrapperFrame.Size = UDim2.new(1,0,1,0) wrapperFrame.Parent = frame for i, child in ipairs(guiObjects) do child.Parent = wrapperFrame end local recalculate = function() wait() layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable) end frame.Changed:connect( function(prop) if prop == "AbsoluteSize" then --Wait a heartbeat for it to sync in recalculate(nil) end end) frame.AncestryChanged:connect(recalculate) layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable) end t.CreateSlider = function(steps,width,position) local sliderGui = Instance.new("Frame") sliderGui.Size = UDim2.new(1,0,1,0) sliderGui.BackgroundTransparency = 1 sliderGui.Name = "SliderGui" local sliderSteps = Instance.new("IntValue") sliderSteps.Name = "SliderSteps" sliderSteps.Value = steps sliderSteps.Parent = sliderGui local areaSoak = Instance.new("TextButton") areaSoak.Name = "AreaSoak" areaSoak.Text = "" areaSoak.BackgroundTransparency = 1 areaSoak.Active = false areaSoak.Size = UDim2.new(1,0,1,0) areaSoak.Visible = false areaSoak.ZIndex = 4 sliderGui.AncestryChanged:connect(function(child,parent) if parent == nil then areaSoak.Parent = nil else areaSoak.Parent = getScreenGuiAncestor(sliderGui) end end) local sliderPosition = Instance.new("IntValue") sliderPosition.Name = "SliderPosition" sliderPosition.Value = 0 sliderPosition.Parent = sliderGui local id = math.random(1,100) local bar = Instance.new("TextButton") bar.Text = "" bar.AutoButtonColor = false bar.Name = "Bar" bar.BackgroundColor3 = Color3.new(0,0,0) if type(width) == "number" then bar.Size = UDim2.new(0,width,0,5) else bar.Size = UDim2.new(0,200,0,5) end bar.BorderColor3 = Color3.new(95/255,95/255,95/255) bar.ZIndex = 2 bar.Parent = sliderGui if position["X"] and position["X"]["Scale"] and position["X"]["Offset"] and position["Y"] and position["Y"]["Scale"] and position["Y"]["Offset"] then bar.Position = position end local slider = Instance.new("ImageButton") slider.Name = "Slider" slider.BackgroundTransparency = 1 slider.Image = "rbxasset://textures/ui/Slider.png" slider.Position = UDim2.new(0,0,0.5,-10) slider.Size = UDim2.new(0,20,0,20) slider.ZIndex = 3 slider.Parent = bar local areaSoakMouseMoveCon = nil areaSoak.MouseLeave:connect(function() if areaSoak.Visible then cancelSlide(areaSoak) end end) areaSoak.MouseButton1Up:connect(function() if areaSoak.Visible then cancelSlide(areaSoak) end end) slider.MouseButton1Down:connect(function() areaSoak.Visible = true if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y) setSliderPos(x,slider,sliderPosition,bar,steps) end) end) slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end) sliderPosition.Changed:connect(function(prop) sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value)) local relativePosX = (sliderPosition.Value - 1) / (steps - 1) slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset) end) bar.MouseButton1Down:connect(function(x,y) setSliderPos(x,slider,sliderPosition,bar,steps) end) return sliderGui, sliderPosition, sliderSteps end t.CreateSliderNew = function(steps,width,position) local sliderGui = Instance.new("Frame") sliderGui.Size = UDim2.new(1,0,1,0) sliderGui.BackgroundTransparency = 1 sliderGui.Name = "SliderGui" local sliderSteps = Instance.new("IntValue") sliderSteps.Name = "SliderSteps" sliderSteps.Value = steps sliderSteps.Parent = sliderGui local areaSoak = Instance.new("TextButton") areaSoak.Name = "AreaSoak" areaSoak.Text = "" areaSoak.BackgroundTransparency = 1 areaSoak.Active = false areaSoak.Size = UDim2.new(1,0,1,0) areaSoak.Visible = false areaSoak.ZIndex = 6 sliderGui.AncestryChanged:connect(function(child,parent) if parent == nil then areaSoak.Parent = nil else areaSoak.Parent = getScreenGuiAncestor(sliderGui) end end) local sliderPosition = Instance.new("IntValue") sliderPosition.Name = "SliderPosition" sliderPosition.Value = 0 sliderPosition.Parent = sliderGui local id = math.random(1,100) local sliderBarImgHeight = 7 local sliderBarCapImgWidth = 4 local bar = Instance.new("ImageButton") bar.BackgroundTransparency = 1 bar.Image = "rbxasset://textures/ui/Slider-BKG-Center.png" bar.Name = "Bar" local displayWidth = 200 if type(width) == "number" then bar.Size = UDim2.new(0,width - (sliderBarCapImgWidth * 2),0,sliderBarImgHeight) displayWidth = width - (sliderBarCapImgWidth * 2) else bar.Size = UDim2.new(0,200,0,sliderBarImgHeight) end bar.ZIndex = 3 bar.Parent = sliderGui if position["X"] and position["X"]["Scale"] and position["X"]["Offset"] and position["Y"] and position["Y"]["Scale"] and position["Y"]["Offset"] then bar.Position = position end local barLeft = bar:clone() barLeft.Name = "BarLeft" barLeft.Image = "rbxasset://textures/ui/Slider-BKG-Left-Cap.png" barLeft.Size = UDim2.new(0, sliderBarCapImgWidth, 0, sliderBarImgHeight) barLeft.Position = UDim2.new(position.X.Scale, position.X.Offset - sliderBarCapImgWidth, position.Y.Scale, position.Y.Offset) barLeft.Parent = sliderGui barLeft.ZIndex = 3 local barRight = barLeft:clone() barRight.Name = "BarRight" barRight.Image = "rbxasset://textures/ui/Slider-BKG-Right-Cap.png" barRight.Position = UDim2.new(position.X.Scale, position.X.Offset + displayWidth, position.Y.Scale, position.Y.Offset) barRight.Parent = sliderGui local fillLeft = barLeft:clone() fillLeft.Name = "FillLeft" fillLeft.Image = "rbxasset://textures/ui/Slider-Fill-Left-Cap.png" fillLeft.Parent = sliderGui fillLeft.ZIndex = 4 local fill = fillLeft:clone() fill.Name = "Fill" fill.Image = "rbxasset://textures/ui/Slider-Fill-Center.png" fill.Parent = bar fill.ZIndex = 4 fill.Position = UDim2.new(0, 0, 0, 0) fill.Size = UDim2.new(0.5, 0, 1, 0) -- bar.Visible = false local slider = Instance.new("ImageButton") slider.Name = "Slider" slider.BackgroundTransparency = 1 slider.Image = "rbxasset://textures/ui/slider_new_tab.png" slider.Position = UDim2.new(0,0,0.5,-14) slider.Size = UDim2.new(0,28,0,28) slider.ZIndex = 5 slider.Parent = bar local areaSoakMouseMoveCon = nil areaSoak.MouseLeave:connect(function() if areaSoak.Visible then cancelSlide(areaSoak) end end) areaSoak.MouseButton1Up:connect(function() if areaSoak.Visible then cancelSlide(areaSoak) end end) slider.MouseButton1Down:connect(function() areaSoak.Visible = true if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y) setSliderPos(x,slider,sliderPosition,bar,steps) end) end) slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end) sliderPosition.Changed:connect(function(prop) sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value)) local relativePosX = (sliderPosition.Value - 1) / (steps - 1) slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset) fill.Size = UDim2.new(relativePosX, 0, 1, 0) end) bar.MouseButton1Down:connect(function(x,y) setSliderPos(x,slider,sliderPosition,bar,steps) end) return sliderGui, sliderPosition, sliderSteps end t.CreateTrueScrollingFrame = function() local lowY = nil local highY = nil local dragCon = nil local upCon = nil local internalChange = false local descendantsChangeConMap = {} local scrollingFrame = Instance.new("Frame") scrollingFrame.Name = "ScrollingFrame" scrollingFrame.Active = true scrollingFrame.Size = UDim2.new(1,0,1,0) scrollingFrame.ClipsDescendants = true local controlFrame = Instance.new("Frame") controlFrame.Name = "ControlFrame" controlFrame.BackgroundTransparency = 1 controlFrame.Size = UDim2.new(0,18,1,0) controlFrame.Position = UDim2.new(1,-20,0,0) controlFrame.Parent = scrollingFrame local scrollBottom = Instance.new("BoolValue") scrollBottom.Value = false scrollBottom.Name = "ScrollBottom" scrollBottom.Parent = controlFrame local scrollUp = Instance.new("BoolValue") scrollUp.Value = false scrollUp.Name = "scrollUp" scrollUp.Parent = controlFrame local scrollUpButton = Instance.new("TextButton") scrollUpButton.Name = "ScrollUpButton" scrollUpButton.Text = "" scrollUpButton.AutoButtonColor = false scrollUpButton.BackgroundColor3 = Color3.new(0,0,0) scrollUpButton.BorderColor3 = Color3.new(1,1,1) scrollUpButton.BackgroundTransparency = 0.5 scrollUpButton.Size = UDim2.new(0,18,0,18) scrollUpButton.ZIndex = 2 scrollUpButton.Parent = controlFrame for i = 1, 6 do local triFrame = Instance.new("Frame") triFrame.BorderColor3 = Color3.new(1,1,1) triFrame.Name = "tri" .. tostring(i) triFrame.ZIndex = 3 triFrame.BackgroundTransparency = 0.5 triFrame.Size = UDim2.new(0,12 - ((i -1) * 2),0,0) triFrame.Position = UDim2.new(0,3 + (i -1),0.5,2 - (i -1)) triFrame.Parent = scrollUpButton end scrollUpButton.MouseEnter:connect(function() scrollUpButton.BackgroundTransparency = 0.1 local upChildren = scrollUpButton:GetChildren() for i = 1, #upChildren do upChildren[i].BackgroundTransparency = 0.1 end end) scrollUpButton.MouseLeave:connect(function() scrollUpButton.BackgroundTransparency = 0.5 local upChildren = scrollUpButton:GetChildren() for i = 1, #upChildren do upChildren[i].BackgroundTransparency = 0.5 end end) local scrollDownButton = scrollUpButton:clone() scrollDownButton.Name = "ScrollDownButton" scrollDownButton.Position = UDim2.new(0,0,1,-18) local downChildren = scrollDownButton:GetChildren() for i = 1, #downChildren do downChildren[i].Position = UDim2.new(0,3 + (i -1),0.5,-2 + (i - 1)) end scrollDownButton.MouseEnter:connect(function() scrollDownButton.BackgroundTransparency = 0.1 local downChildren = scrollDownButton:GetChildren() for i = 1, #downChildren do downChildren[i].BackgroundTransparency = 0.1 end end) scrollDownButton.MouseLeave:connect(function() scrollDownButton.BackgroundTransparency = 0.5 local downChildren = scrollDownButton:GetChildren() for i = 1, #downChildren do downChildren[i].BackgroundTransparency = 0.5 end end) scrollDownButton.Parent = controlFrame local scrollTrack = Instance.new("Frame") scrollTrack.Name = "ScrollTrack" scrollTrack.BackgroundTransparency = 1 scrollTrack.Size = UDim2.new(0,18,1,-38) scrollTrack.Position = UDim2.new(0,0,0,19) scrollTrack.Parent = controlFrame local scrollbar = Instance.new("TextButton") scrollbar.BackgroundColor3 = Color3.new(0,0,0) scrollbar.BorderColor3 = Color3.new(1,1,1) scrollbar.BackgroundTransparency = 0.5 scrollbar.AutoButtonColor = false scrollbar.Text = "" scrollbar.Active = true scrollbar.Name = "ScrollBar" scrollbar.ZIndex = 2 scrollbar.BackgroundTransparency = 0.5 scrollbar.Size = UDim2.new(0, 18, 0.1, 0) scrollbar.Position = UDim2.new(0,0,0,0) scrollbar.Parent = scrollTrack local scrollNub = Instance.new("Frame") scrollNub.Name = "ScrollNub" scrollNub.BorderColor3 = Color3.new(1,1,1) scrollNub.Size = UDim2.new(0,10,0,0) scrollNub.Position = UDim2.new(0.5,-5,0.5,0) scrollNub.ZIndex = 2 scrollNub.BackgroundTransparency = 0.5 scrollNub.Parent = scrollbar local newNub = scrollNub:clone() newNub.Position = UDim2.new(0.5,-5,0.5,-2) newNub.Parent = scrollbar local lastNub = scrollNub:clone() lastNub.Position = UDim2.new(0.5,-5,0.5,2) lastNub.Parent = scrollbar scrollbar.MouseEnter:connect(function() scrollbar.BackgroundTransparency = 0.1 scrollNub.BackgroundTransparency = 0.1 newNub.BackgroundTransparency = 0.1 lastNub.BackgroundTransparency = 0.1 end) scrollbar.MouseLeave:connect(function() scrollbar.BackgroundTransparency = 0.5 scrollNub.BackgroundTransparency = 0.5 newNub.BackgroundTransparency = 0.5 lastNub.BackgroundTransparency = 0.5 end) local mouseDrag = Instance.new("ImageButton") mouseDrag.Active = false mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0) mouseDrag.AutoButtonColor = false mouseDrag.BackgroundTransparency = 1 mouseDrag.Name = "mouseDrag" mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0) mouseDrag.ZIndex = 10 local function positionScrollBar(x,y,offset) local oldPos = scrollbar.Position if y < scrollTrack.AbsolutePosition.y then scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0) return (oldPos ~= scrollbar.Position) end local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y if y > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0) return (oldPos ~= scrollbar.Position) end local newScaleYPos = (y - scrollTrack.AbsolutePosition.y - offset)/scrollTrack.AbsoluteSize.y if newScaleYPos + relativeSize > 1 then newScaleYPos = 1 - relativeSize scrollBottom.Value = true scrollUp.Value = false elseif newScaleYPos <= 0 then newScaleYPos = 0 scrollUp.Value = true scrollBottom.Value = false else scrollUp.Value = false scrollBottom.Value = false end scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,newScaleYPos,0) return (oldPos ~= scrollbar.Position) end local function drillDownSetHighLow(instance) if not instance or not instance:IsA("GuiObject") then return end if instance == controlFrame then return end if instance:IsDescendantOf(controlFrame) then return end if not instance.Visible then return end if lowY and lowY > instance.AbsolutePosition.Y then lowY = instance.AbsolutePosition.Y elseif not lowY then lowY = instance.AbsolutePosition.Y end if highY and highY < (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) then highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y elseif not highY then highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y end local children = instance:GetChildren() for i = 1, #children do drillDownSetHighLow(children[i]) end end local function resetHighLow() local firstChildren = scrollingFrame:GetChildren() for i = 1, #firstChildren do drillDownSetHighLow(firstChildren[i]) end end local function recalculate() internalChange = true local percentFrame = 0 if scrollbar.Position.Y.Scale > 0 then if scrollbar.Visible then percentFrame = scrollbar.Position.Y.Scale/((scrollTrack.AbsoluteSize.Y - scrollbar.AbsoluteSize.Y)/scrollTrack.AbsoluteSize.Y) else percentFrame = 0 end end if percentFrame > 0.99 then percentFrame = 1 end local hiddenYAmount = (scrollingFrame.AbsoluteSize.Y - (highY - lowY)) * percentFrame local guiChildren = scrollingFrame:GetChildren() for i = 1, #guiChildren do if guiChildren[i] ~= controlFrame then guiChildren[i].Position = UDim2.new(guiChildren[i].Position.X.Scale,guiChildren[i].Position.X.Offset, 0, math.ceil(guiChildren[i].AbsolutePosition.Y) - math.ceil(lowY) + hiddenYAmount) end end lowY = nil highY = nil resetHighLow() internalChange = false end local function setSliderSizeAndPosition() if not highY or not lowY then return end local totalYSpan = math.abs(highY - lowY) if totalYSpan == 0 then scrollbar.Visible = false scrollDownButton.Visible = false scrollUpButton.Visible = false if dragCon then dragCon:disconnect() dragCon = nil end if upCon then upCon:disconnect() upCon = nil end return end local percentShown = scrollingFrame.AbsoluteSize.Y/totalYSpan if percentShown >= 1 then scrollbar.Visible = false scrollDownButton.Visible = false scrollUpButton.Visible = false recalculate() else scrollbar.Visible = true scrollDownButton.Visible = true scrollUpButton.Visible = true scrollbar.Size = UDim2.new(scrollbar.Size.X.Scale,scrollbar.Size.X.Offset,percentShown,0) end local percentPosition = (scrollingFrame.AbsolutePosition.Y - lowY)/totalYSpan scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,percentPosition,-scrollbar.AbsoluteSize.X/2) if scrollbar.AbsolutePosition.y < scrollTrack.AbsolutePosition.y then scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0) end if (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.Y) > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0) end end local buttonScrollAmountPixels = 7 local reentrancyGuardScrollUp = false local function doScrollUp() if reentrancyGuardScrollUp then return end reentrancyGuardScrollUp = true if positionScrollBar(0,scrollbar.AbsolutePosition.Y - buttonScrollAmountPixels,0) then recalculate() end reentrancyGuardScrollUp = false end local reentrancyGuardScrollDown = false local function doScrollDown() if reentrancyGuardScrollDown then return end reentrancyGuardScrollDown = true if positionScrollBar(0,scrollbar.AbsolutePosition.Y + buttonScrollAmountPixels,0) then recalculate() end reentrancyGuardScrollDown = false end local function scrollUp(mouseYPos) if scrollUpButton.Active then scrollStamp = tick() local current = scrollStamp local upCon upCon = mouseDrag.MouseButton1Up:connect(function() scrollStamp = tick() mouseDrag.Parent = nil upCon:disconnect() end) mouseDrag.Parent = getScreenGuiAncestor(scrollbar) doScrollUp() wait(0.2) local t = tick() local w = 0.1 while scrollStamp == current do doScrollUp() if mouseYPos and mouseYPos > scrollbar.AbsolutePosition.y then break end if not scrollUpButton.Active then break end if tick()-t > 5 then w = 0 elseif tick()-t > 2 then w = 0.06 end wait(w) end end end local function scrollDown(mouseYPos) if scrollDownButton.Active then scrollStamp = tick() local current = scrollStamp local downCon downCon = mouseDrag.MouseButton1Up:connect(function() scrollStamp = tick() mouseDrag.Parent = nil downCon:disconnect() end) mouseDrag.Parent = getScreenGuiAncestor(scrollbar) doScrollDown() wait(0.2) local t = tick() local w = 0.1 while scrollStamp == current do doScrollDown() if mouseYPos and mouseYPos < (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.x) then break end if not scrollDownButton.Active then break end if tick()-t > 5 then w = 0 elseif tick()-t > 2 then w = 0.06 end wait(w) end end end scrollbar.MouseButton1Down:connect(function(x,y) if scrollbar.Active then scrollStamp = tick() local mouseOffset = y - scrollbar.AbsolutePosition.y if dragCon then dragCon:disconnect() dragCon = nil end if upCon then upCon:disconnect() upCon = nil end local prevY = y local reentrancyGuardMouseScroll = false dragCon = mouseDrag.MouseMoved:connect(function(x,y) if reentrancyGuardMouseScroll then return end reentrancyGuardMouseScroll = true if positionScrollBar(x,y,mouseOffset) then recalculate() end reentrancyGuardMouseScroll = false end) upCon = mouseDrag.MouseButton1Up:connect(function() scrollStamp = tick() mouseDrag.Parent = nil dragCon:disconnect(); dragCon = nil upCon:disconnect(); drag = nil end) mouseDrag.Parent = getScreenGuiAncestor(scrollbar) end end) local scrollMouseCount = 0 scrollUpButton.MouseButton1Down:connect(function() scrollUp() end) scrollUpButton.MouseButton1Up:connect(function() scrollStamp = tick() end) scrollDownButton.MouseButton1Up:connect(function() scrollStamp = tick() end) scrollDownButton.MouseButton1Down:connect(function() scrollDown() end) scrollbar.MouseButton1Up:connect(function() scrollStamp = tick() end) local function heightCheck(instance) if highY and (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) > highY then highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y elseif not highY then highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y end setSliderSizeAndPosition() end local function highLowRecheck() local oldLowY = lowY local oldHighY = highY lowY = nil highY = nil resetHighLow() if (lowY ~= oldLowY) or (highY ~= oldHighY) then setSliderSizeAndPosition() end end local function descendantChanged(this, prop) if internalChange then return end if not this.Visible then return end if prop == "Size" or prop == "Position" then wait() highLowRecheck() end end scrollingFrame.DescendantAdded:connect(function(instance) if not instance:IsA("GuiObject") then return end if instance.Visible then wait() -- wait a heartbeat for sizes to reconfig highLowRecheck() end descendantsChangeConMap[instance] = instance.Changed:connect(function(prop) descendantChanged(instance, prop) end) end) scrollingFrame.DescendantRemoving:connect(function(instance) if not instance:IsA("GuiObject") then return end if descendantsChangeConMap[instance] then descendantsChangeConMap[instance]:disconnect() descendantsChangeConMap[instance] = nil end wait() -- wait a heartbeat for sizes to reconfig highLowRecheck() end) scrollingFrame.Changed:connect(function(prop) if prop == "AbsoluteSize" then if not highY or not lowY then return end highLowRecheck() setSliderSizeAndPosition() end end) return scrollingFrame, controlFrame end t.CreateScrollingFrame = function(orderList,scrollStyle) local frame = Instance.new("Frame") frame.Name = "ScrollingFrame" frame.BackgroundTransparency = 1 frame.Size = UDim2.new(1,0,1,0) local scrollUpButton = Instance.new("ImageButton") scrollUpButton.Name = "ScrollUpButton" scrollUpButton.BackgroundTransparency = 1 scrollUpButton.Image = "rbxasset://textures/ui/scrollbuttonUp.png" scrollUpButton.Size = UDim2.new(0,17,0,17) local scrollDownButton = Instance.new("ImageButton") scrollDownButton.Name = "ScrollDownButton" scrollDownButton.BackgroundTransparency = 1 scrollDownButton.Image = "rbxasset://textures/ui/scrollbuttonDown.png" scrollDownButton.Size = UDim2.new(0,17,0,17) local scrollbar = Instance.new("ImageButton") scrollbar.Name = "ScrollBar" scrollbar.Image = "rbxasset://textures/ui/scrollbar.png" scrollbar.BackgroundTransparency = 1 scrollbar.Size = UDim2.new(0, 18, 0, 150) local scrollStamp = 0 local scrollDrag = Instance.new("ImageButton") scrollDrag.Image = "http://www.roblox.com/asset/?id=61367186" scrollDrag.Size = UDim2.new(1, 0, 0, 16) scrollDrag.BackgroundTransparency = 1 scrollDrag.Name = "ScrollDrag" scrollDrag.Active = true scrollDrag.Parent = scrollbar local mouseDrag = Instance.new("ImageButton") mouseDrag.Active = false mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0) mouseDrag.AutoButtonColor = false mouseDrag.BackgroundTransparency = 1 mouseDrag.Name = "mouseDrag" mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0) mouseDrag.ZIndex = 10 local style = "simple" if scrollStyle and tostring(scrollStyle) then style = scrollStyle end local scrollPosition = 1 local rowSize = 0 local howManyDisplayed = 0 local layoutGridScrollBar = function() howManyDisplayed = 0 local guiObjects = {} if orderList then for i, child in ipairs(orderList) do if child.Parent == frame then table.insert(guiObjects, child) end end else local children = frame:GetChildren() if children then for i, child in ipairs(children) do if child:IsA("GuiObject") then table.insert(guiObjects, child) end end end end if #guiObjects == 0 then scrollUpButton.Active = false scrollDownButton.Active = false scrollDrag.Active = false scrollPosition = 1 return end if scrollPosition > #guiObjects then scrollPosition = #guiObjects end if scrollPosition < 1 then scrollPosition = 1 end local totalPixelsY = frame.AbsoluteSize.Y local pixelsRemainingY = frame.AbsoluteSize.Y local totalPixelsX = frame.AbsoluteSize.X local xCounter = 0 local rowSizeCounter = 0 local setRowSize = true local pixelsBelowScrollbar = 0 local pos = #guiObjects local currentRowY = 0 pos = scrollPosition --count up from current scroll position to fill out grid while pos <= #guiObjects and pixelsBelowScrollbar < totalPixelsY do xCounter = xCounter + guiObjects[pos].AbsoluteSize.X --previous pos was the end of a row if xCounter >= totalPixelsX then pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY currentRowY = 0 xCounter = guiObjects[pos].AbsoluteSize.X end if guiObjects[pos].AbsoluteSize.Y > currentRowY then currentRowY = guiObjects[pos].AbsoluteSize.Y end pos = pos + 1 end --Count wherever current row left off pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY currentRowY = 0 pos = scrollPosition - 1 xCounter = 0 --objects with varying X,Y dimensions can rarely cause minor errors --rechecking every new scrollPosition is necessary to avoid 100% of errors --count backwards from current scrollPosition to see if we can add more rows while pixelsBelowScrollbar + currentRowY < totalPixelsY and pos >= 1 do xCounter = xCounter + guiObjects[pos].AbsoluteSize.X rowSizeCounter = rowSizeCounter + 1 if xCounter >= totalPixelsX then rowSize = rowSizeCounter - 1 rowSizeCounter = 0 xCounter = guiObjects[pos].AbsoluteSize.X if pixelsBelowScrollbar + currentRowY <= totalPixelsY then --It fits, so back up our scroll position pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY if scrollPosition <= rowSize then scrollPosition = 1 break else scrollPosition = scrollPosition - rowSize end currentRowY = 0 else break end end if guiObjects[pos].AbsoluteSize.Y > currentRowY then currentRowY = guiObjects[pos].AbsoluteSize.Y end pos = pos - 1 end --Do check last time if pos = 0 if (pos == 0) and (pixelsBelowScrollbar + currentRowY <= totalPixelsY) then scrollPosition = 1 end xCounter = 0 --pos = scrollPosition rowSizeCounter = 0 setRowSize = true local lastChildSize = 0 local xOffset,yOffset = 0 if guiObjects[1] then yOffset = math.ceil(math.floor(math.fmod(totalPixelsY,guiObjects[1].AbsoluteSize.X))/2) xOffset = math.ceil(math.floor(math.fmod(totalPixelsX,guiObjects[1].AbsoluteSize.Y))/2) end for i, child in ipairs(guiObjects) do if i < scrollPosition then --print("Hiding " .. child.Name) child.Visible = false else if pixelsRemainingY < 0 then --print("Out of Space " .. child.Name) child.Visible = false else --print("Laying out " .. child.Name) --GuiObject if setRowSize then rowSizeCounter = rowSizeCounter + 1 end if xCounter + child.AbsoluteSize.X >= totalPixelsX then if setRowSize then rowSize = rowSizeCounter - 1 setRowSize = false end xCounter = 0 pixelsRemainingY = pixelsRemainingY - child.AbsoluteSize.Y end child.Position = UDim2.new(child.Position.X.Scale,xCounter + xOffset, 0, totalPixelsY - pixelsRemainingY + yOffset) xCounter = xCounter + child.AbsoluteSize.X child.Visible = ((pixelsRemainingY - child.AbsoluteSize.Y) >= 0) if child.Visible then howManyDisplayed = howManyDisplayed + 1 end lastChildSize = child.AbsoluteSize end end end scrollUpButton.Active = (scrollPosition > 1) if lastChildSize == 0 then scrollDownButton.Active = false else scrollDownButton.Active = ((pixelsRemainingY - lastChildSize.Y) < 0) end scrollDrag.Active = #guiObjects > howManyDisplayed scrollDrag.Visible = scrollDrag.Active end local layoutSimpleScrollBar = function() local guiObjects = {} howManyDisplayed = 0 if orderList then for i, child in ipairs(orderList) do if child.Parent == frame then table.insert(guiObjects, child) end end else local children = frame:GetChildren() if children then for i, child in ipairs(children) do if child:IsA("GuiObject") then table.insert(guiObjects, child) end end end end if #guiObjects == 0 then scrollUpButton.Active = false scrollDownButton.Active = false scrollDrag.Active = false scrollPosition = 1 return end if scrollPosition > #guiObjects then scrollPosition = #guiObjects end local totalPixels = frame.AbsoluteSize.Y local pixelsRemaining = frame.AbsoluteSize.Y local pixelsBelowScrollbar = 0 local pos = #guiObjects while pixelsBelowScrollbar < totalPixels and pos >= 1 do if pos >= scrollPosition then pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y else if pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y <= totalPixels then --It fits, so back up our scroll position pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y if scrollPosition <= 1 then scrollPosition = 1 break else --local ("Backing up ScrollPosition from -- " ..scrollPosition) scrollPosition = scrollPosition - 1 end else break end end pos = pos - 1 end pos = scrollPosition for i, child in ipairs(guiObjects) do if i < scrollPosition then --print("Hiding " .. child.Name) child.Visible = false else if pixelsRemaining < 0 then --print("Out of Space " .. child.Name) child.Visible = false else --print("Laying out " .. child.Name) --GuiObject child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining) pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y if (pixelsRemaining >= 0) then child.Visible = true howManyDisplayed = howManyDisplayed + 1 else child.Visible = false end end end end scrollUpButton.Active = (scrollPosition > 1) scrollDownButton.Active = (pixelsRemaining < 0) scrollDrag.Active = #guiObjects > howManyDisplayed scrollDrag.Visible = scrollDrag.Active end local moveDragger = function() local guiObjects = 0 local children = frame:GetChildren() if children then for i, child in ipairs(children) do if child:IsA("GuiObject") then guiObjects = guiObjects + 1 end end end if not scrollDrag.Parent then return end local dragSizeY = scrollDrag.Parent.AbsoluteSize.y * (1/(guiObjects - howManyDisplayed + 1)) if dragSizeY < 16 then dragSizeY = 16 end scrollDrag.Size = UDim2.new(scrollDrag.Size.X.Scale,scrollDrag.Size.X.Offset,scrollDrag.Size.Y.Scale,dragSizeY) local relativeYPos = (scrollPosition - 1)/(guiObjects - (howManyDisplayed)) if relativeYPos > 1 then relativeYPos = 1 elseif relativeYPos < 0 then relativeYPos = 0 end local absYPos = 0 if relativeYPos ~= 0 then absYPos = (relativeYPos * scrollbar.AbsoluteSize.y) - (relativeYPos * scrollDrag.AbsoluteSize.y) end scrollDrag.Position = UDim2.new(scrollDrag.Position.X.Scale,scrollDrag.Position.X.Offset,scrollDrag.Position.Y.Scale,absYPos) end local reentrancyGuard = false local recalculate = function() if reentrancyGuard then return end reentrancyGuard = true wait() local success, err = nil if style == "grid" then success, err = pcall(function() layoutGridScrollBar() end) elseif style == "simple" then success, err = pcall(function() layoutSimpleScrollBar() end) end if not success then print(err) end moveDragger() reentrancyGuard = false end local doScrollUp = function() scrollPosition = (scrollPosition) - rowSize if scrollPosition < 1 then scrollPosition = 1 end recalculate(nil) end local doScrollDown = function() scrollPosition = (scrollPosition) + rowSize recalculate(nil) end local scrollUp = function(mouseYPos) if scrollUpButton.Active then scrollStamp = tick() local current = scrollStamp local upCon upCon = mouseDrag.MouseButton1Up:connect(function() scrollStamp = tick() mouseDrag.Parent = nil upCon:disconnect() end) mouseDrag.Parent = getScreenGuiAncestor(scrollbar) doScrollUp() wait(0.2) local t = tick() local w = 0.1 while scrollStamp == current do doScrollUp() if mouseYPos and mouseYPos > scrollDrag.AbsolutePosition.y then break end if not scrollUpButton.Active then break end if tick()-t > 5 then w = 0 elseif tick()-t > 2 then w = 0.06 end wait(w) end end end local scrollDown = function(mouseYPos) if scrollDownButton.Active then scrollStamp = tick() local current = scrollStamp local downCon downCon = mouseDrag.MouseButton1Up:connect(function() scrollStamp = tick() mouseDrag.Parent = nil downCon:disconnect() end) mouseDrag.Parent = getScreenGuiAncestor(scrollbar) doScrollDown() wait(0.2) local t = tick() local w = 0.1 while scrollStamp == current do doScrollDown() if mouseYPos and mouseYPos < (scrollDrag.AbsolutePosition.y + scrollDrag.AbsoluteSize.x) then break end if not scrollDownButton.Active then break end if tick()-t > 5 then w = 0 elseif tick()-t > 2 then w = 0.06 end wait(w) end end end local y = 0 scrollDrag.MouseButton1Down:connect(function(x,y) if scrollDrag.Active then scrollStamp = tick() local mouseOffset = y - scrollDrag.AbsolutePosition.y local dragCon local upCon dragCon = mouseDrag.MouseMoved:connect(function(x,y) local barAbsPos = scrollbar.AbsolutePosition.y local barAbsSize = scrollbar.AbsoluteSize.y local dragAbsSize = scrollDrag.AbsoluteSize.y local barAbsOne = barAbsPos + barAbsSize - dragAbsSize y = y - mouseOffset y = y < barAbsPos and barAbsPos or y > barAbsOne and barAbsOne or y y = y - barAbsPos local guiObjects = 0 local children = frame:GetChildren() if children then for i, child in ipairs(children) do if child:IsA("GuiObject") then guiObjects = guiObjects + 1 end end end local doublePercent = y/(barAbsSize-dragAbsSize) local rowDiff = rowSize local totalScrollCount = guiObjects - (howManyDisplayed - 1) local newScrollPosition = math.floor((doublePercent * totalScrollCount) + 0.5) + rowDiff if newScrollPosition < scrollPosition then rowDiff = -rowDiff end if newScrollPosition < 1 then newScrollPosition = 1 end scrollPosition = newScrollPosition recalculate(nil) end) upCon = mouseDrag.MouseButton1Up:connect(function() scrollStamp = tick() mouseDrag.Parent = nil dragCon:disconnect(); dragCon = nil upCon:disconnect(); drag = nil end) mouseDrag.Parent = getScreenGuiAncestor(scrollbar) end end) local scrollMouseCount = 0 scrollUpButton.MouseButton1Down:connect( function() scrollUp() end) scrollUpButton.MouseButton1Up:connect(function() scrollStamp = tick() end) scrollDownButton.MouseButton1Up:connect(function() scrollStamp = tick() end) scrollDownButton.MouseButton1Down:connect( function() scrollDown() end) scrollbar.MouseButton1Up:connect(function() scrollStamp = tick() end) scrollbar.MouseButton1Down:connect( function(x,y) if y > (scrollDrag.AbsoluteSize.y + scrollDrag.AbsolutePosition.y) then scrollDown(y) elseif y < (scrollDrag.AbsolutePosition.y) then scrollUp(y) end end) frame.ChildAdded:connect(function() recalculate(nil) end) frame.ChildRemoved:connect(function() recalculate(nil) end) frame.Changed:connect( function(prop) if prop == "AbsoluteSize" then --Wait a heartbeat for it to sync in recalculate(nil) end end) frame.AncestryChanged:connect(function() recalculate(nil) end) return frame, scrollUpButton, scrollDownButton, recalculate, scrollbar end local function binaryGrow(min, max, fits) if min > max then return min end local biggestLegal = min while min <= max do local mid = min + math.floor((max - min) / 2) if fits(mid) and (biggestLegal == nil or biggestLegal < mid) then biggestLegal = mid --Try growing min = mid + 1 else --Doesn't fit, shrink max = mid - 1 end end return biggestLegal end local function binaryShrink(min, max, fits) if min > max then return min end local smallestLegal = max while min <= max do local mid = min + math.floor((max - min) / 2) if fits(mid) and (smallestLegal == nil or smallestLegal > mid) then smallestLegal = mid --It fits, shrink max = mid - 1 else --Doesn't fit, grow min = mid + 1 end end return smallestLegal end local function getGuiOwner(instance) while instance ~= nil do if instance:IsA("ScreenGui") or instance:IsA("BillboardGui") then return instance end instance = instance.Parent end return nil end t.AutoTruncateTextObject = function(textLabel) local text = textLabel.Text local fullLabel = textLabel:Clone() fullLabel.Name = "Full" .. textLabel.Name fullLabel.BorderSizePixel = 0 fullLabel.BackgroundTransparency = 0 fullLabel.Text = text fullLabel.TextXAlignment = Enum.TextXAlignment.Center fullLabel.Position = UDim2.new(0,-3,0,0) fullLabel.Size = UDim2.new(0,100,1,0) fullLabel.Visible = false fullLabel.Parent = textLabel local shortText = nil local mouseEnterConnection = nil local mouseLeaveConnection= nil local checkForResize = function() if getGuiOwner(textLabel) == nil then return end textLabel.Text = text if textLabel.TextFits then --Tear down the rollover if it is active if mouseEnterConnection then mouseEnterConnection:disconnect() mouseEnterConnection = nil end if mouseLeaveConnection then mouseLeaveConnection:disconnect() mouseLeaveConnection = nil end else local len = string.len(text) textLabel.Text = text .. "~" --Shrink the text local textSize = binaryGrow(0, len, function(pos) if pos == 0 then textLabel.Text = "~" else textLabel.Text = string.sub(text, 1, pos) .. "~" end return textLabel.TextFits end) shortText = string.sub(text, 1, textSize) .. "~" textLabel.Text = shortText --Make sure the fullLabel fits if not fullLabel.TextFits then --Already too small, grow it really bit to start fullLabel.Size = UDim2.new(0, 10000, 1, 0) end --Okay, now try to binary shrink it back down local fullLabelSize = binaryShrink(textLabel.AbsoluteSize.X,fullLabel.AbsoluteSize.X, function(size) fullLabel.Size = UDim2.new(0, size, 1, 0) return fullLabel.TextFits end) fullLabel.Size = UDim2.new(0,fullLabelSize+6,1,0) --Now setup the rollover effects, if they are currently off if mouseEnterConnection == nil then mouseEnterConnection = textLabel.MouseEnter:connect( function() fullLabel.ZIndex = textLabel.ZIndex + 1 fullLabel.Visible = true --textLabel.Text = "" end) end if mouseLeaveConnection == nil then mouseLeaveConnection = textLabel.MouseLeave:connect( function() fullLabel.Visible = false --textLabel.Text = shortText end) end end end textLabel.AncestryChanged:connect(checkForResize) textLabel.Changed:connect( function(prop) if prop == "AbsoluteSize" then checkForResize() end end) checkForResize() local function changeText(newText) text = newText fullLabel.Text = text checkForResize() end return textLabel, changeText end local function TransitionTutorialPages(fromPage, toPage, transitionFrame, currentPageValue) if fromPage then fromPage.Visible = false if transitionFrame.Visible == false then transitionFrame.Size = fromPage.Size transitionFrame.Position = fromPage.Position end else if transitionFrame.Visible == false then transitionFrame.Size = UDim2.new(0.0,50,0.0,50) transitionFrame.Position = UDim2.new(0.5,-25,0.5,-25) end end transitionFrame.Visible = true currentPageValue.Value = nil local newsize, newPosition if toPage then --Make it visible so it resizes toPage.Visible = true newSize = toPage.Size newPosition = toPage.Position toPage.Visible = false else newSize = UDim2.new(0.0,50,0.0,50) newPosition = UDim2.new(0.5,-25,0.5,-25) end transitionFrame:TweenSizeAndPosition(newSize, newPosition, Enum.EasingDirection.InOut, Enum.EasingStyle.Quad, 0.3, true, function(state) if state == Enum.TweenStatus.Completed then transitionFrame.Visible = false if toPage then toPage.Visible = true currentPageValue.Value = toPage end end end) end t.CreateTutorial = function(name, tutorialKey, createButtons) local frame = Instance.new("Frame") frame.Name = "Tutorial-" .. name frame.BackgroundTransparency = 1 frame.Size = UDim2.new(0.6, 0, 0.6, 0) frame.Position = UDim2.new(0.2, 0, 0.2, 0) local transitionFrame = Instance.new("Frame") transitionFrame.Name = "TransitionFrame" transitionFrame.Style = Enum.FrameStyle.RobloxRound transitionFrame.Size = UDim2.new(0.6, 0, 0.6, 0) transitionFrame.Position = UDim2.new(0.2, 0, 0.2, 0) transitionFrame.Visible = false transitionFrame.Parent = frame local currentPageValue = Instance.new("ObjectValue") currentPageValue.Name = "CurrentTutorialPage" currentPageValue.Value = nil currentPageValue.Parent = frame local boolValue = Instance.new("BoolValue") boolValue.Name = "Buttons" boolValue.Value = createButtons boolValue.Parent = frame local pages = Instance.new("Frame") pages.Name = "Pages" pages.BackgroundTransparency = 1 pages.Size = UDim2.new(1,0,1,0) pages.Parent = frame local function getVisiblePageAndHideOthers() local visiblePage = nil local children = pages:GetChildren() if children then for i,child in ipairs(children) do if child.Visible then if visiblePage then child.Visible = false else visiblePage = child end end end end return visiblePage end local showTutorial = function(alwaysShow) if alwaysShow or UserSettings().GameSettings:GetTutorialState(tutorialKey) == false then print("Showing tutorial-",tutorialKey) local currentTutorialPage = getVisiblePageAndHideOthers() local firstPage = pages:FindFirstChild("TutorialPage1") if firstPage then TransitionTutorialPages(currentTutorialPage, firstPage, transitionFrame, currentPageValue) else error("Could not find TutorialPage1") end end end local dismissTutorial = function() local currentTutorialPage = getVisiblePageAndHideOthers() if currentTutorialPage then TransitionTutorialPages(currentTutorialPage, nil, transitionFrame, currentPageValue) end UserSettings().GameSettings:SetTutorialState(tutorialKey, true) end local gotoPage = function(pageNum) local page = pages:FindFirstChild("TutorialPage" .. pageNum) local currentTutorialPage = getVisiblePageAndHideOthers() TransitionTutorialPages(currentTutorialPage, page, transitionFrame, currentPageValue) end return frame, showTutorial, dismissTutorial, gotoPage end local function CreateBasicTutorialPage(name, handleResize, skipTutorial, giveDoneButton) local frame = Instance.new("Frame") frame.Name = "TutorialPage" frame.Style = Enum.FrameStyle.RobloxRound frame.Size = UDim2.new(0.6, 0, 0.6, 0) frame.Position = UDim2.new(0.2, 0, 0.2, 0) frame.Visible = false local frameHeader = Instance.new("TextLabel") frameHeader.Name = "Header" frameHeader.Text = name frameHeader.BackgroundTransparency = 1 frameHeader.FontSize = Enum.FontSize.Size24 frameHeader.Font = Enum.Font.ArialBold frameHeader.TextColor3 = Color3.new(1,1,1) frameHeader.TextXAlignment = Enum.TextXAlignment.Center frameHeader.TextWrap = true frameHeader.Size = UDim2.new(1,-55, 0, 22) frameHeader.Position = UDim2.new(0,0,0,0) frameHeader.Parent = frame local skipButton = Instance.new("ImageButton") skipButton.Name = "SkipButton" skipButton.AutoButtonColor = false skipButton.BackgroundTransparency = 1 skipButton.Image = "rbxasset://textures/ui/closeButton.png" skipButton.MouseButton1Click:connect(function() skipTutorial() end) skipButton.MouseEnter:connect(function() skipButton.Image = "rbxasset://textures/ui/closeButton_dn.png" end) skipButton.MouseLeave:connect(function() skipButton.Image = "rbxasset://textures/ui/closeButton.png" end) skipButton.Size = UDim2.new(0, 25, 0, 25) skipButton.Position = UDim2.new(1, -25, 0, 0) skipButton.Parent = frame if giveDoneButton then local doneButton = Instance.new("TextButton") doneButton.Name = "DoneButton" doneButton.Style = Enum.ButtonStyle.RobloxButtonDefault doneButton.Text = "Done" doneButton.TextColor3 = Color3.new(1,1,1) doneButton.Font = Enum.Font.ArialBold doneButton.FontSize = Enum.FontSize.Size18 doneButton.Size = UDim2.new(0,100,0,50) doneButton.Position = UDim2.new(0.5,-50,1,-50) if skipTutorial then doneButton.MouseButton1Click:connect(function() skipTutorial() end) end doneButton.Parent = frame end local innerFrame = Instance.new("Frame") innerFrame.Name = "ContentFrame" innerFrame.BackgroundTransparency = 1 innerFrame.Position = UDim2.new(0,0,0,25) innerFrame.Parent = frame local nextButton = Instance.new("TextButton") nextButton.Name = "NextButton" nextButton.Text = "Next" nextButton.TextColor3 = Color3.new(1,1,1) nextButton.Font = Enum.Font.Arial nextButton.FontSize = Enum.FontSize.Size18 nextButton.Style = Enum.ButtonStyle.RobloxButtonDefault nextButton.Size = UDim2.new(0,80, 0, 32) nextButton.Position = UDim2.new(0.5, 5, 1, -32) nextButton.Active = false nextButton.Visible = false nextButton.Parent = frame local prevButton = Instance.new("TextButton") prevButton.Name = "PrevButton" prevButton.Text = "Previous" prevButton.TextColor3 = Color3.new(1,1,1) prevButton.Font = Enum.Font.Arial prevButton.FontSize = Enum.FontSize.Size18 prevButton.Style = Enum.ButtonStyle.RobloxButton prevButton.Size = UDim2.new(0,80, 0, 32) prevButton.Position = UDim2.new(0.5, -85, 1, -32) prevButton.Active = false prevButton.Visible = false prevButton.Parent = frame if giveDoneButton then innerFrame.Size = UDim2.new(1,0,1,-75) else innerFrame.Size = UDim2.new(1,0,1,-22) end local parentConnection = nil local function basicHandleResize() if frame.Visible and frame.Parent then local maxSize = math.min(frame.Parent.AbsoluteSize.X, frame.Parent.AbsoluteSize.Y) handleResize(200,maxSize) end end frame.Changed:connect( function(prop) if prop == "Parent" then if parentConnection ~= nil then parentConnection:disconnect() parentConnection = nil end if frame.Parent and frame.Parent:IsA("GuiObject") then parentConnection = frame.Parent.Changed:connect( function(parentProp) if parentProp == "AbsoluteSize" then wait() basicHandleResize() end end) basicHandleResize() end end if prop == "Visible" then basicHandleResize() end end) return frame, innerFrame end t.CreateTextTutorialPage = function(name, text, skipTutorialFunc) local frame = nil local contentFrame = nil local textLabel = Instance.new("TextLabel") textLabel.BackgroundTransparency = 1 textLabel.TextColor3 = Color3.new(1,1,1) textLabel.Text = text textLabel.TextWrap = true textLabel.TextXAlignment = Enum.TextXAlignment.Left textLabel.TextYAlignment = Enum.TextYAlignment.Center textLabel.Font = Enum.Font.Arial textLabel.FontSize = Enum.FontSize.Size14 textLabel.Size = UDim2.new(1,0,1,0) local function handleResize(minSize, maxSize) size = binaryShrink(minSize, maxSize, function(size) frame.Size = UDim2.new(0, size, 0, size) return textLabel.TextFits end) frame.Size = UDim2.new(0, size, 0, size) frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2) end frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc) textLabel.Parent = contentFrame return frame end t.CreateImageTutorialPage = function(name, imageAsset, x, y, skipTutorialFunc, giveDoneButton) local frame = nil local contentFrame = nil local imageLabel = Instance.new("ImageLabel") imageLabel.BackgroundTransparency = 1 imageLabel.Image = imageAsset imageLabel.Size = UDim2.new(0,x,0,y) imageLabel.Position = UDim2.new(0.5,-x/2,0.5,-y/2) local function handleResize(minSize, maxSize) size = binaryShrink(minSize, maxSize, function(size) return size >= x and size >= y end) if size >= x and size >= y then imageLabel.Size = UDim2.new(0,x, 0,y) imageLabel.Position = UDim2.new(0.5,-x/2, 0.5, -y/2) else if x > y then --X is limiter, so imageLabel.Size = UDim2.new(1,0,y/x,0) imageLabel.Position = UDim2.new(0,0, 0.5 - (y/x)/2, 0) else --Y is limiter imageLabel.Size = UDim2.new(x/y,0,1, 0) imageLabel.Position = UDim2.new(0.5-(x/y)/2, 0, 0, 0) end end size = size + 50 frame.Size = UDim2.new(0, size, 0, size) frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2) end frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc, giveDoneButton) imageLabel.Parent = contentFrame return frame end t.AddTutorialPage = function(tutorial, tutorialPage) local transitionFrame = tutorial.TransitionFrame local currentPageValue = tutorial.CurrentTutorialPage if not tutorial.Buttons.Value then tutorialPage.NextButton.Parent = nil tutorialPage.PrevButton.Parent = nil end local children = tutorial.Pages:GetChildren() if children and #children > 0 then tutorialPage.Name = "TutorialPage" .. (#children+1) local previousPage = children[#children] if not previousPage:IsA("GuiObject") then error("All elements under Pages must be GuiObjects") end if tutorial.Buttons.Value then if previousPage.NextButton.Active then error("NextButton already Active on previousPage, please only add pages with RbxGui.AddTutorialPage function") end previousPage.NextButton.MouseButton1Click:connect( function() TransitionTutorialPages(previousPage, tutorialPage, transitionFrame, currentPageValue) end) previousPage.NextButton.Active = true previousPage.NextButton.Visible = true if tutorialPage.PrevButton.Active then error("PrevButton already Active on tutorialPage, please only add pages with RbxGui.AddTutorialPage function") end tutorialPage.PrevButton.MouseButton1Click:connect( function() TransitionTutorialPages(tutorialPage, previousPage, transitionFrame, currentPageValue) end) tutorialPage.PrevButton.Active = true tutorialPage.PrevButton.Visible = true end tutorialPage.Parent = tutorial.Pages else --First child tutorialPage.Name = "TutorialPage1" tutorialPage.Parent = tutorial.Pages end end t.CreateSetPanel = function(userIdsForSets, objectSelected, dialogClosed, size, position, showAdminCategories, useAssetVersionId) if not userIdsForSets then error("CreateSetPanel: userIdsForSets (first arg) is nil, should be a table of number ids") end if type(userIdsForSets) ~= "table" and type(userIdsForSets) ~= "userdata" then error("CreateSetPanel: userIdsForSets (first arg) is of type " ..type(userIdsForSets) .. ", should be of type table or userdata") end if not objectSelected then error("CreateSetPanel: objectSelected (second arg) is nil, should be a callback function!") end if type(objectSelected) ~= "function" then error("CreateSetPanel: objectSelected (second arg) is of type " .. type(objectSelected) .. ", should be of type function!") end if dialogClosed and type(dialogClosed) ~= "function" then error("CreateSetPanel: dialogClosed (third arg) is of type " .. type(dialogClosed) .. ", should be of type function!") end if showAdminCategories == nil then -- by default, don't show beta sets showAdminCategories = false end local arrayPosition = 1 local insertButtons = {} local insertButtonCons = {} local contents = nil local setGui = nil -- used for water selections local waterForceDirection = "NegX" local waterForce = "None" local waterGui, waterTypeChangedEvent = nil local Data = {} Data.CurrentCategory = nil Data.Category = {} local SetCache = {} local userCategoryButtons = nil local buttonWidth = 64 local buttonHeight = buttonWidth local SmallThumbnailUrl = nil local LargeThumbnailUrl = nil local BaseUrl = game:GetService("ContentProvider").BaseUrl:lower() if useAssetVersionId then LargeThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&assetversionid=" SmallThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&assetversionid=" else LargeThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&aid=" SmallThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&aid=" end local function drillDownSetZIndex(parent, index) local children = parent:GetChildren() for i = 1, #children do if children[i]:IsA("GuiObject") then children[i].ZIndex = index end drillDownSetZIndex(children[i], index) end end -- for terrain stamping local currTerrainDropDownFrame = nil local terrainShapes = {"Block","Vertical Ramp","Corner Wedge","Inverse Corner Wedge","Horizontal Ramp","Auto-Wedge"} local terrainShapeMap = {} for i = 1, #terrainShapes do terrainShapeMap[terrainShapes[i]] = i - 1 end terrainShapeMap[terrainShapes[#terrainShapes]] = 6 local function createWaterGui() local waterForceDirections = {"NegX","X","NegY","Y","NegZ","Z"} local waterForces = {"None", "Small", "Medium", "Strong", "Max"} local waterFrame = Instance.new("Frame") waterFrame.Name = "WaterFrame" waterFrame.Style = Enum.FrameStyle.RobloxSquare waterFrame.Size = UDim2.new(0,150,0,110) waterFrame.Visible = false local waterForceLabel = Instance.new("TextLabel") waterForceLabel.Name = "WaterForceLabel" waterForceLabel.BackgroundTransparency = 1 waterForceLabel.Size = UDim2.new(1,0,0,12) waterForceLabel.Font = Enum.Font.ArialBold waterForceLabel.FontSize = Enum.FontSize.Size12 waterForceLabel.TextColor3 = Color3.new(1,1,1) waterForceLabel.TextXAlignment = Enum.TextXAlignment.Left waterForceLabel.Text = "Water Force" waterForceLabel.Parent = waterFrame local waterForceDirLabel = waterForceLabel:Clone() waterForceDirLabel.Name = "WaterForceDirectionLabel" waterForceDirLabel.Text = "Water Force Direction" waterForceDirLabel.Position = UDim2.new(0,0,0,50) waterForceDirLabel.Parent = waterFrame local waterTypeChangedEvent = Instance.new("BindableEvent",waterFrame) waterTypeChangedEvent.Name = "WaterTypeChangedEvent" local waterForceDirectionSelectedFunc = function(newForceDirection) waterForceDirection = newForceDirection waterTypeChangedEvent:Fire({waterForce, waterForceDirection}) end local waterForceSelectedFunc = function(newForce) waterForce = newForce waterTypeChangedEvent:Fire({waterForce, waterForceDirection}) end local waterForceDirectionDropDown, forceWaterDirectionSelection = t.CreateDropDownMenu(waterForceDirections, waterForceDirectionSelectedFunc) waterForceDirectionDropDown.Size = UDim2.new(1,0,0,25) waterForceDirectionDropDown.Position = UDim2.new(0,0,1,3) forceWaterDirectionSelection("NegX") waterForceDirectionDropDown.Parent = waterForceDirLabel local waterForceDropDown, forceWaterForceSelection = t.CreateDropDownMenu(waterForces, waterForceSelectedFunc) forceWaterForceSelection("None") waterForceDropDown.Size = UDim2.new(1,0,0,25) waterForceDropDown.Position = UDim2.new(0,0,1,3) waterForceDropDown.Parent = waterForceLabel return waterFrame, waterTypeChangedEvent end -- Helper Function that contructs gui elements local function createSetGui() local setGui = Instance.new("ScreenGui") setGui.Name = "SetGui" local setPanel = Instance.new("Frame") setPanel.Name = "SetPanel" setPanel.Active = true setPanel.BackgroundTransparency = 1 if position then setPanel.Position = position else setPanel.Position = UDim2.new(0.2, 29, 0.1, 24) end if size then setPanel.Size = size else setPanel.Size = UDim2.new(0.6, -58, 0.64, 0) end setPanel.Style = Enum.FrameStyle.RobloxRound setPanel.ZIndex = 6 setPanel.Parent = setGui -- Children of SetPanel local itemPreview = Instance.new("Frame") itemPreview.Name = "ItemPreview" itemPreview.BackgroundTransparency = 1 itemPreview.Position = UDim2.new(0.8,5,0.085,0) itemPreview.Size = UDim2.new(0.21,0,0.9,0) itemPreview.ZIndex = 6 itemPreview.Parent = setPanel -- Children of ItemPreview local textPanel = Instance.new("Frame") textPanel.Name = "TextPanel" textPanel.BackgroundTransparency = 1 textPanel.Position = UDim2.new(0,0,0.45,0) textPanel.Size = UDim2.new(1,0,0.55,0) textPanel.ZIndex = 6 textPanel.Parent = itemPreview -- Children of TextPanel local rolloverText = Instance.new("TextLabel") rolloverText.Name = "RolloverText" rolloverText.BackgroundTransparency = 1 rolloverText.Size = UDim2.new(1,0,0,48) rolloverText.ZIndex = 6 rolloverText.Font = Enum.Font.ArialBold rolloverText.FontSize = Enum.FontSize.Size24 rolloverText.Text = "" rolloverText.TextColor3 = Color3.new(1,1,1) rolloverText.TextWrap = true rolloverText.TextXAlignment = Enum.TextXAlignment.Left rolloverText.TextYAlignment = Enum.TextYAlignment.Top rolloverText.Parent = textPanel local largePreview = Instance.new("ImageLabel") largePreview.Name = "LargePreview" largePreview.BackgroundTransparency = 1 largePreview.Image = "" largePreview.Size = UDim2.new(1,0,0,170) largePreview.ZIndex = 6 largePreview.Parent = itemPreview local sets = Instance.new("Frame") sets.Name = "Sets" sets.BackgroundTransparency = 1 sets.Position = UDim2.new(0,0,0,5) sets.Size = UDim2.new(0.23,0,1,-5) sets.ZIndex = 6 sets.Parent = setPanel -- Children of Sets local line = Instance.new("Frame") line.Name = "Line" line.BackgroundColor3 = Color3.new(1,1,1) line.BackgroundTransparency = 0.7 line.BorderSizePixel = 0 line.Position = UDim2.new(1,-3,0.06,0) line.Size = UDim2.new(0,3,0.9,0) line.ZIndex = 6 line.Parent = sets local setsLists, controlFrame = t.CreateTrueScrollingFrame() setsLists.Size = UDim2.new(1,-6,0.94,0) setsLists.Position = UDim2.new(0,0,0.06,0) setsLists.BackgroundTransparency = 1 setsLists.Name = "SetsLists" setsLists.ZIndex = 6 setsLists.Parent = sets drillDownSetZIndex(controlFrame, 7) local setsHeader = Instance.new("TextLabel") setsHeader.Name = "SetsHeader" setsHeader.BackgroundTransparency = 1 setsHeader.Size = UDim2.new(0,47,0,24) setsHeader.ZIndex = 6 setsHeader.Font = Enum.Font.ArialBold setsHeader.FontSize = Enum.FontSize.Size24 setsHeader.Text = "Sets" setsHeader.TextColor3 = Color3.new(1,1,1) setsHeader.TextXAlignment = Enum.TextXAlignment.Left setsHeader.TextYAlignment = Enum.TextYAlignment.Top setsHeader.Parent = sets local cancelButton = Instance.new("TextButton") cancelButton.Name = "CancelButton" cancelButton.Position = UDim2.new(1,-32,0,-2) cancelButton.Size = UDim2.new(0,34,0,34) cancelButton.Style = Enum.ButtonStyle.RobloxButtonDefault cancelButton.ZIndex = 6 cancelButton.Text = "" cancelButton.Modal = true cancelButton.Parent = setPanel -- Children of Cancel Button local cancelImage = Instance.new("ImageLabel") cancelImage.Name = "CancelImage" cancelImage.BackgroundTransparency = 1 cancelImage.Image = "http://www.roblox.com/asset/?id=54135717" cancelImage.Position = UDim2.new(0,-2,0,-2) cancelImage.Size = UDim2.new(0,16,0,16) cancelImage.ZIndex = 6 cancelImage.Parent = cancelButton return setGui end local function createSetButton(text) local setButton = Instance.new("TextButton") if text then setButton.Text = text else setButton.Text = "" end setButton.AutoButtonColor = false setButton.BackgroundTransparency = 1 setButton.BackgroundColor3 = Color3.new(1,1,1) setButton.BorderSizePixel = 0 setButton.Size = UDim2.new(1,-5,0,18) setButton.ZIndex = 6 setButton.Visible = false setButton.Font = Enum.Font.Arial setButton.FontSize = Enum.FontSize.Size18 setButton.TextColor3 = Color3.new(1,1,1) setButton.TextXAlignment = Enum.TextXAlignment.Left return setButton end local function buildSetButton(name, setId, setImageId, i, count) local button = createSetButton(name) button.Text = name button.Name = "SetButton" button.Visible = true local setValue = Instance.new("IntValue") setValue.Name = "SetId" setValue.Value = setId setValue.Parent = button local setName = Instance.new("StringValue") setName.Name = "SetName" setName.Value = name setName.Parent = button return button end local function processCategory(sets) local setButtons = {} local numSkipped = 0 for i = 1, #sets do if not showAdminCategories and sets[i].Name == "Beta" then numSkipped = numSkipped + 1 else setButtons[i - numSkipped] = buildSetButton(sets[i].Name, sets[i].CategoryId, sets[i].ImageAssetId, i - numSkipped, #sets) end end return setButtons end local function handleResize() wait() -- neccessary to insure heartbeat happened local itemPreview = setGui.SetPanel.ItemPreview itemPreview.LargePreview.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.X) itemPreview.LargePreview.Position = UDim2.new(0.5,-itemPreview.LargePreview.AbsoluteSize.X/2,0,0) itemPreview.TextPanel.Position = UDim2.new(0,0,0,itemPreview.LargePreview.AbsoluteSize.Y) itemPreview.TextPanel.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.Y - itemPreview.LargePreview.AbsoluteSize.Y) end local function makeInsertAssetButton() local insertAssetButtonExample = Instance.new("Frame") insertAssetButtonExample.Name = "InsertAssetButtonExample" insertAssetButtonExample.Position = UDim2.new(0,128,0,64) insertAssetButtonExample.Size = UDim2.new(0,64,0,64) insertAssetButtonExample.BackgroundTransparency = 1 insertAssetButtonExample.ZIndex = 6 insertAssetButtonExample.Visible = false local assetId = Instance.new("IntValue") assetId.Name = "AssetId" assetId.Value = 0 assetId.Parent = insertAssetButtonExample local assetName = Instance.new("StringValue") assetName.Name = "AssetName" assetName.Value = "" assetName.Parent = insertAssetButtonExample local button = Instance.new("TextButton") button.Name = "Button" button.Text = "" button.Style = Enum.ButtonStyle.RobloxButton button.Position = UDim2.new(0.025,0,0.025,0) button.Size = UDim2.new(0.95,0,0.95,0) button.ZIndex = 6 button.Parent = insertAssetButtonExample local buttonImage = Instance.new("ImageLabel") buttonImage.Name = "ButtonImage" buttonImage.Image = "" buttonImage.Position = UDim2.new(0,-7,0,-7) buttonImage.Size = UDim2.new(1,14,1,14) buttonImage.BackgroundTransparency = 1 buttonImage.ZIndex = 7 buttonImage.Parent = button local configIcon = buttonImage:clone() configIcon.Name = "ConfigIcon" configIcon.Visible = false configIcon.Position = UDim2.new(1,-23,1,-24) configIcon.Size = UDim2.new(0,16,0,16) configIcon.Image = "" configIcon.ZIndex = 6 configIcon.Parent = insertAssetButtonExample return insertAssetButtonExample end local function showLargePreview(insertButton) if insertButton:FindFirstChild("AssetId") then delay(0,function() game:GetService("ContentProvider"):Preload(LargeThumbnailUrl .. tostring(insertButton.AssetId.Value)) setGui.SetPanel.ItemPreview.LargePreview.Image = LargeThumbnailUrl .. tostring(insertButton.AssetId.Value) end) end if insertButton:FindFirstChild("AssetName") then setGui.SetPanel.ItemPreview.TextPanel.RolloverText.Text = insertButton.AssetName.Value end end local function selectTerrainShape(shape) if currTerrainDropDownFrame then objectSelected(tostring(currTerrainDropDownFrame.AssetName.Value), tonumber(currTerrainDropDownFrame.AssetId.Value), shape) end end local function createTerrainTypeButton(name, parent) local dropDownTextButton = Instance.new("TextButton") dropDownTextButton.Name = name .. "Button" dropDownTextButton.Font = Enum.Font.ArialBold dropDownTextButton.FontSize = Enum.FontSize.Size14 dropDownTextButton.BorderSizePixel = 0 dropDownTextButton.TextColor3 = Color3.new(1,1,1) dropDownTextButton.Text = name dropDownTextButton.TextXAlignment = Enum.TextXAlignment.Left dropDownTextButton.BackgroundTransparency = 1 dropDownTextButton.ZIndex = parent.ZIndex + 1 dropDownTextButton.Size = UDim2.new(0,parent.Size.X.Offset - 2,0,16) dropDownTextButton.Position = UDim2.new(0,1,0,0) dropDownTextButton.MouseEnter:connect(function() dropDownTextButton.BackgroundTransparency = 0 dropDownTextButton.TextColor3 = Color3.new(0,0,0) end) dropDownTextButton.MouseLeave:connect(function() dropDownTextButton.BackgroundTransparency = 1 dropDownTextButton.TextColor3 = Color3.new(1,1,1) end) dropDownTextButton.MouseButton1Click:connect(function() dropDownTextButton.BackgroundTransparency = 1 dropDownTextButton.TextColor3 = Color3.new(1,1,1) if dropDownTextButton.Parent and dropDownTextButton.Parent:IsA("GuiObject") then dropDownTextButton.Parent.Visible = false end selectTerrainShape(terrainShapeMap[dropDownTextButton.Text]) end) return dropDownTextButton end local function createTerrainDropDownMenu(zIndex) local dropDown = Instance.new("Frame") dropDown.Name = "TerrainDropDown" dropDown.BackgroundColor3 = Color3.new(0,0,0) dropDown.BorderColor3 = Color3.new(1,0,0) dropDown.Size = UDim2.new(0,200,0,0) dropDown.Visible = false dropDown.ZIndex = zIndex dropDown.Parent = setGui for i = 1, #terrainShapes do local shapeButton = createTerrainTypeButton(terrainShapes[i],dropDown) shapeButton.Position = UDim2.new(0,1,0,(i - 1) * (shapeButton.Size.Y.Offset)) shapeButton.Parent = dropDown dropDown.Size = UDim2.new(0,200,0,dropDown.Size.Y.Offset + (shapeButton.Size.Y.Offset)) end dropDown.MouseLeave:connect(function() dropDown.Visible = false end) end local function createDropDownMenuButton(parent) local dropDownButton = Instance.new("ImageButton") dropDownButton.Name = "DropDownButton" dropDownButton.Image = "http://www.roblox.com/asset/?id=67581509" dropDownButton.BackgroundTransparency = 1 dropDownButton.Size = UDim2.new(0,16,0,16) dropDownButton.Position = UDim2.new(1,-24,0,6) dropDownButton.ZIndex = parent.ZIndex + 2 dropDownButton.Parent = parent if not setGui:FindFirstChild("TerrainDropDown") then createTerrainDropDownMenu(8) end dropDownButton.MouseButton1Click:connect(function() setGui.TerrainDropDown.Visible = true setGui.TerrainDropDown.Position = UDim2.new(0,parent.AbsolutePosition.X,0,parent.AbsolutePosition.Y) currTerrainDropDownFrame = parent end) end local function buildInsertButton() local insertButton = makeInsertAssetButton() insertButton.Name = "InsertAssetButton" insertButton.Visible = true if Data.Category[Data.CurrentCategory].SetName == "High Scalability" then createDropDownMenuButton(insertButton) end local lastEnter = nil local mouseEnterCon = insertButton.MouseEnter:connect(function() lastEnter = insertButton delay(0.1,function() if lastEnter == insertButton then showLargePreview(insertButton) end end) end) return insertButton, mouseEnterCon end local function realignButtonGrid(columns) local x = 0 local y = 0 for i = 1, #insertButtons do insertButtons[i].Position = UDim2.new(0, buttonWidth * x, 0, buttonHeight * y) x = x + 1 if x >= columns then x = 0 y = y + 1 end end end local function setInsertButtonImageBehavior(insertFrame, visible, name, assetId) if visible then insertFrame.AssetName.Value = name insertFrame.AssetId.Value = assetId local newImageUrl = SmallThumbnailUrl .. assetId if newImageUrl ~= insertFrame.Button.ButtonImage.Image then delay(0,function() game:GetService("ContentProvider"):Preload(SmallThumbnailUrl .. assetId) if insertFrame:findFirstChild("Button") then insertFrame.Button.ButtonImage.Image = SmallThumbnailUrl .. assetId end end) end table.insert(insertButtonCons, insertFrame.Button.MouseButton1Click:connect(function() -- special case for water, show water selection gui local isWaterSelected = (name == "Water") and (Data.Category[Data.CurrentCategory].SetName == "High Scalability") waterGui.Visible = isWaterSelected if isWaterSelected then objectSelected(name, tonumber(assetId), nil) else objectSelected(name, tonumber(assetId)) end end) ) insertFrame.Visible = true else insertFrame.Visible = false end end local function loadSectionOfItems(setGui, rows, columns) local pageSize = rows * columns if arrayPosition > #contents then return end local origArrayPos = arrayPosition local yCopy = 0 for i = 1, pageSize + 1 do if arrayPosition >= #contents + 1 then break end local buttonCon insertButtons[arrayPosition], buttonCon = buildInsertButton() table.insert(insertButtonCons,buttonCon) insertButtons[arrayPosition].Parent = setGui.SetPanel.ItemsFrame arrayPosition = arrayPosition + 1 end realignButtonGrid(columns) local indexCopy = origArrayPos for index = origArrayPos, arrayPosition do if insertButtons[index] then if contents[index] then -- we don't want water to have a drop down button if contents[index].Name == "Water" then if Data.Category[Data.CurrentCategory].SetName == "High Scalability" then insertButtons[index]:FindFirstChild("DropDownButton",true):Destroy() end end local assetId if useAssetVersionId then assetId = contents[index].AssetVersionId else assetId = contents[index].AssetId end setInsertButtonImageBehavior(insertButtons[index], true, contents[index].Name, assetId) else break end else break end indexCopy = index end end local function setSetIndex() Data.Category[Data.CurrentCategory].Index = 0 rows = 7 columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth) contents = Data.Category[Data.CurrentCategory].Contents if contents then -- remove our buttons and their connections for i = 1, #insertButtons do insertButtons[i]:remove() end for i = 1, #insertButtonCons do if insertButtonCons[i] then insertButtonCons[i]:disconnect() end end insertButtonCons = {} insertButtons = {} arrayPosition = 1 loadSectionOfItems(setGui, rows, columns) end end local function selectSet(button, setName, setId, setIndex) if button and Data.Category[Data.CurrentCategory] ~= nil then if button ~= Data.Category[Data.CurrentCategory].Button then Data.Category[Data.CurrentCategory].Button = button if SetCache[setId] == nil then SetCache[setId] = game:GetService("InsertService"):GetCollection(setId) end Data.Category[Data.CurrentCategory].Contents = SetCache[setId] Data.Category[Data.CurrentCategory].SetName = setName Data.Category[Data.CurrentCategory].SetId = setId end setSetIndex() end end local function selectCategoryPage(buttons, page) if buttons ~= Data.CurrentCategory then if Data.CurrentCategory then for key, button in pairs(Data.CurrentCategory) do button.Visible = false end end Data.CurrentCategory = buttons if Data.Category[Data.CurrentCategory] == nil then Data.Category[Data.CurrentCategory] = {} if #buttons > 0 then selectSet(buttons[1], buttons[1].SetName.Value, buttons[1].SetId.Value, 0) end else Data.Category[Data.CurrentCategory].Button = nil selectSet(Data.Category[Data.CurrentCategory].ButtonFrame, Data.Category[Data.CurrentCategory].SetName, Data.Category[Data.CurrentCategory].SetId, Data.Category[Data.CurrentCategory].Index) end end end local function selectCategory(category) selectCategoryPage(category, 0) end local function resetAllSetButtonSelection() local setButtons = setGui.SetPanel.Sets.SetsLists:GetChildren() for i = 1, #setButtons do if setButtons[i]:IsA("TextButton") then setButtons[i].Selected = false setButtons[i].BackgroundTransparency = 1 setButtons[i].TextColor3 = Color3.new(1,1,1) setButtons[i].BackgroundColor3 = Color3.new(1,1,1) end end end local function populateSetsFrame() local currRow = 0 for i = 1, #userCategoryButtons do local button = userCategoryButtons[i] button.Visible = true button.Position = UDim2.new(0,5,0,currRow * button.Size.Y.Offset) button.Parent = setGui.SetPanel.Sets.SetsLists if i == 1 then -- we will have this selected by default, so show it button.Selected = true button.BackgroundColor3 = Color3.new(0,204/255,0) button.TextColor3 = Color3.new(0,0,0) button.BackgroundTransparency = 0 end button.MouseEnter:connect(function() if not button.Selected then button.BackgroundTransparency = 0 button.TextColor3 = Color3.new(0,0,0) end end) button.MouseLeave:connect(function() if not button.Selected then button.BackgroundTransparency = 1 button.TextColor3 = Color3.new(1,1,1) end end) button.MouseButton1Click:connect(function() resetAllSetButtonSelection() button.Selected = not button.Selected button.BackgroundColor3 = Color3.new(0,204/255,0) button.TextColor3 = Color3.new(0,0,0) button.BackgroundTransparency = 0 selectSet(button, button.Text, userCategoryButtons[i].SetId.Value, 0) end) currRow = currRow + 1 end local buttons = setGui.SetPanel.Sets.SetsLists:GetChildren() -- set first category as loaded for default if buttons then for i = 1, #buttons do if buttons[i]:IsA("TextButton") then selectSet(buttons[i], buttons[i].Text, userCategoryButtons[i].SetId.Value, 0) selectCategory(userCategoryButtons) break end end end end setGui = createSetGui() waterGui, waterTypeChangedEvent = createWaterGui() waterGui.Position = UDim2.new(0,55,0,0) waterGui.Parent = setGui setGui.Changed:connect(function(prop) -- this resizes the preview image to always be the right size if prop == "AbsoluteSize" then handleResize() setSetIndex() end end) local scrollFrame, controlFrame = t.CreateTrueScrollingFrame() scrollFrame.Size = UDim2.new(0.54,0,0.85,0) scrollFrame.Position = UDim2.new(0.24,0,0.085,0) scrollFrame.Name = "ItemsFrame" scrollFrame.ZIndex = 6 scrollFrame.Parent = setGui.SetPanel scrollFrame.BackgroundTransparency = 1 drillDownSetZIndex(controlFrame,7) controlFrame.Parent = setGui.SetPanel controlFrame.Position = UDim2.new(0.76, 5, 0, 0) local debounce = false controlFrame.ScrollBottom.Changed:connect(function(prop) if controlFrame.ScrollBottom.Value == true then if debounce then return end debounce = true loadSectionOfItems(setGui, rows, columns) debounce = false end end) local userData = {} for id = 1, #userIdsForSets do local newUserData = game:GetService("InsertService"):GetUserSets(userIdsForSets[id]) if newUserData and #newUserData > 2 then -- start at #3 to skip over My Decals and My Models for each account for category = 3, #newUserData do if newUserData[category].Name == "High Scalability" then -- we want high scalability parts to show first table.insert(userData,1,newUserData[category]) else table.insert(userData, newUserData[category]) end end end end if userData then userCategoryButtons = processCategory(userData) end rows = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.Y/buttonHeight) columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth) populateSetsFrame() insertPanelCloseCon = setGui.SetPanel.CancelButton.MouseButton1Click:connect(function() setGui.SetPanel.Visible = false if dialogClosed then dialogClosed() end end) local setVisibilityFunction = function(visible) if visible then setGui.SetPanel.Visible = true else setGui.SetPanel.Visible = false end end local getVisibilityFunction = function() if setGui then if setGui:FindFirstChild("SetPanel") then return setGui.SetPanel.Visible end end return false end return setGui, setVisibilityFunction, getVisibilityFunction, waterTypeChangedEvent end t.CreateTerrainMaterialSelector = function(size,position) local terrainMaterialSelectionChanged = Instance.new("BindableEvent") terrainMaterialSelectionChanged.Name = "TerrainMaterialSelectionChanged" local selectedButton = nil local frame = Instance.new("Frame") frame.Name = "TerrainMaterialSelector" if size then frame.Size = size else frame.Size = UDim2.new(0, 245, 0, 230) end if position then frame.Position = position end frame.BorderSizePixel = 0 frame.BackgroundColor3 = Color3.new(0,0,0) frame.Active = true terrainMaterialSelectionChanged.Parent = frame local waterEnabled = true -- todo: turn this on when water is ready local materialToImageMap = {} local materialNames = {"Grass", "Sand", "Brick", "Granite", "Asphalt", "Iron", "Aluminum", "Gold", "Plank", "Log", "Gravel", "Cinder Block", "Stone Wall", "Concrete", "Plastic (red)", "Plastic (blue)"} if waterEnabled then table.insert(materialNames,"Water") end local currentMaterial = 1 function getEnumFromName(choice) if choice == "Grass" then return 1 end if choice == "Sand" then return 2 end if choice == "Erase" then return 0 end if choice == "Brick" then return 3 end if choice == "Granite" then return 4 end if choice == "Asphalt" then return 5 end if choice == "Iron" then return 6 end if choice == "Aluminum" then return 7 end if choice == "Gold" then return 8 end if choice == "Plank" then return 9 end if choice == "Log" then return 10 end if choice == "Gravel" then return 11 end if choice == "Cinder Block" then return 12 end if choice == "Stone Wall" then return 13 end if choice == "Concrete" then return 14 end if choice == "Plastic (red)" then return 15 end if choice == "Plastic (blue)" then return 16 end if choice == "Water" then return 17 end end function getNameFromEnum(choice) if choice == Enum.CellMaterial.Grass or choice == 1 then return "Grass"end if choice == Enum.CellMaterial.Sand or choice == 2 then return "Sand" end if choice == Enum.CellMaterial.Empty or choice == 0 then return "Erase" end if choice == Enum.CellMaterial.Brick or choice == 3 then return "Brick" end if choice == Enum.CellMaterial.Granite or choice == 4 then return "Granite" end if choice == Enum.CellMaterial.Asphalt or choice == 5 then return "Asphalt" end if choice == Enum.CellMaterial.Iron or choice == 6 then return "Iron" end if choice == Enum.CellMaterial.Aluminum or choice == 7 then return "Aluminum" end if choice == Enum.CellMaterial.Gold or choice == 8 then return "Gold" end if choice == Enum.CellMaterial.WoodPlank or choice == 9 then return "Plank" end if choice == Enum.CellMaterial.WoodLog or choice == 10 then return "Log" end if choice == Enum.CellMaterial.Gravel or choice == 11 then return "Gravel" end if choice == Enum.CellMaterial.CinderBlock or choice == 12 then return "Cinder Block" end if choice == Enum.CellMaterial.MossyStone or choice == 13 then return "Stone Wall" end if choice == Enum.CellMaterial.Cement or choice == 14 then return "Concrete" end if choice == Enum.CellMaterial.RedPlastic or choice == 15 then return "Plastic (red)" end if choice == Enum.CellMaterial.BluePlastic or choice == 16 then return "Plastic (blue)" end if waterEnabled then if choice == Enum.CellMaterial.Water or choice == 17 then return "Water" end end end local function updateMaterialChoice(choice) currentMaterial = getEnumFromName(choice) terrainMaterialSelectionChanged:Fire(currentMaterial) end -- we so need a better way to do this for i,v in pairs(materialNames) do materialToImageMap[v] = {} if v == "Grass" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=56563112" elseif v == "Sand" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=62356652" elseif v == "Brick" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=65961537" elseif v == "Granite" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532153" elseif v == "Asphalt" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532038" elseif v == "Iron" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532093" elseif v == "Aluminum" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531995" elseif v == "Gold" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532118" elseif v == "Plastic (red)" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531848" elseif v == "Plastic (blue)" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531924" elseif v == "Plank" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532015" elseif v == "Log" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532051" elseif v == "Gravel" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532206" elseif v == "Cinder Block" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532103" elseif v == "Stone Wall" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531804" elseif v == "Concrete" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532059" elseif v == "Water" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=81407474" else materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=66887593" -- fill in the rest here!! end end local scrollFrame, scrollUp, scrollDown, recalculateScroll = t.CreateScrollingFrame(nil,"grid") scrollFrame.Size = UDim2.new(0.85,0,1,0) scrollFrame.Position = UDim2.new(0,0,0,0) scrollFrame.Parent = frame scrollUp.Parent = frame scrollUp.Visible = true scrollUp.Position = UDim2.new(1,-19,0,0) scrollDown.Parent = frame scrollDown.Visible = true scrollDown.Position = UDim2.new(1,-19,1,-17) local function goToNewMaterial(buttonWrap, materialName) updateMaterialChoice(materialName) buttonWrap.BackgroundTransparency = 0 selectedButton.BackgroundTransparency = 1 selectedButton = buttonWrap end local function createMaterialButton(name) local buttonWrap = Instance.new("TextButton") buttonWrap.Text = "" buttonWrap.Size = UDim2.new(0,32,0,32) buttonWrap.BackgroundColor3 = Color3.new(1,1,1) buttonWrap.BorderSizePixel = 0 buttonWrap.BackgroundTransparency = 1 buttonWrap.AutoButtonColor = false buttonWrap.Name = tostring(name) local imageButton = Instance.new("ImageButton") imageButton.AutoButtonColor = false imageButton.BackgroundTransparency = 1 imageButton.Size = UDim2.new(0,30,0,30) imageButton.Position = UDim2.new(0,1,0,1) imageButton.Name = tostring(name) imageButton.Parent = buttonWrap imageButton.Image = materialToImageMap[name].Regular local enumType = Instance.new("NumberValue") enumType.Name = "EnumType" enumType.Parent = buttonWrap enumType.Value = 0 imageButton.MouseEnter:connect(function() buttonWrap.BackgroundTransparency = 0 end) imageButton.MouseLeave:connect(function() if selectedButton ~= buttonWrap then buttonWrap.BackgroundTransparency = 1 end end) imageButton.MouseButton1Click:connect(function() if selectedButton ~= buttonWrap then goToNewMaterial(buttonWrap, tostring(name)) end end) return buttonWrap end for i = 1, #materialNames do local imageButton = createMaterialButton(materialNames[i]) if materialNames[i] == "Grass" then -- always start with grass as the default selectedButton = imageButton imageButton.BackgroundTransparency = 0 end imageButton.Parent = scrollFrame end local forceTerrainMaterialSelection = function(newMaterialType) if not newMaterialType then return end if currentMaterial == newMaterialType then return end local matName = getNameFromEnum(newMaterialType) local buttons = scrollFrame:GetChildren() for i = 1, #buttons do if buttons[i].Name == "Plastic (blue)" and matName == "Plastic (blue)" then goToNewMaterial(buttons[i],matName) return end if buttons[i].Name == "Plastic (red)" and matName == "Plastic (red)" then goToNewMaterial(buttons[i],matName) return end if string.find(buttons[i].Name, matName) then goToNewMaterial(buttons[i],matName) return end end end frame.Changed:connect(function ( prop ) if prop == "AbsoluteSize" then recalculateScroll() end end) recalculateScroll() return frame, terrainMaterialSelectionChanged, forceTerrainMaterialSelection end t.CreateLoadingFrame = function(name,size,position) game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=35238053") local loadingFrame = Instance.new("Frame") loadingFrame.Name = "LoadingFrame" loadingFrame.Style = Enum.FrameStyle.RobloxRound if size then loadingFrame.Size = size else loadingFrame.Size = UDim2.new(0,300,0,160) end if position then loadingFrame.Position = position else loadingFrame.Position = UDim2.new(0.5, -150, 0.5,-80) end local loadingBar = Instance.new("Frame") loadingBar.Name = "LoadingBar" loadingBar.BackgroundColor3 = Color3.new(0,0,0) loadingBar.BorderColor3 = Color3.new(79/255,79/255,79/255) loadingBar.Position = UDim2.new(0,0,0,41) loadingBar.Size = UDim2.new(1,0,0,30) loadingBar.Parent = loadingFrame local loadingGreenBar = Instance.new("ImageLabel") loadingGreenBar.Name = "LoadingGreenBar" loadingGreenBar.Image = "http://www.roblox.com/asset/?id=35238053" loadingGreenBar.Position = UDim2.new(0,0,0,0) loadingGreenBar.Size = UDim2.new(0,0,1,0) loadingGreenBar.Visible = false loadingGreenBar.Parent = loadingBar local loadingPercent = Instance.new("TextLabel") loadingPercent.Name = "LoadingPercent" loadingPercent.BackgroundTransparency = 1 loadingPercent.Position = UDim2.new(0,0,1,0) loadingPercent.Size = UDim2.new(1,0,0,14) loadingPercent.Font = Enum.Font.Arial loadingPercent.Text = "0%" loadingPercent.FontSize = Enum.FontSize.Size14 loadingPercent.TextColor3 = Color3.new(1,1,1) loadingPercent.Parent = loadingBar local cancelButton = Instance.new("TextButton") cancelButton.Name = "CancelButton" cancelButton.Position = UDim2.new(0.5,-60,1,-40) cancelButton.Size = UDim2.new(0,120,0,40) cancelButton.Font = Enum.Font.Arial cancelButton.FontSize = Enum.FontSize.Size18 cancelButton.TextColor3 = Color3.new(1,1,1) cancelButton.Text = "Cancel" cancelButton.Style = Enum.ButtonStyle.RobloxButton cancelButton.Parent = loadingFrame local loadingName = Instance.new("TextLabel") loadingName.Name = "loadingName" loadingName.BackgroundTransparency = 1 loadingName.Size = UDim2.new(1,0,0,18) loadingName.Position = UDim2.new(0,0,0,2) loadingName.Font = Enum.Font.Arial loadingName.Text = name loadingName.TextColor3 = Color3.new(1,1,1) loadingName.TextStrokeTransparency = 1 loadingName.FontSize = Enum.FontSize.Size18 loadingName.Parent = loadingFrame local cancelButtonClicked = Instance.new("BindableEvent") cancelButtonClicked.Name = "CancelButtonClicked" cancelButtonClicked.Parent = cancelButton cancelButton.MouseButton1Click:connect(function() cancelButtonClicked:Fire() end) local updateLoadingGuiPercent = function(percent, tweenAction, tweenLength) if percent and type(percent) ~= "number" then error("updateLoadingGuiPercent expects number as argument, got",type(percent),"instead") end local newSize = nil if percent < 0 then newSize = UDim2.new(0,0,1,0) elseif percent > 1 then newSize = UDim2.new(1,0,1,0) else newSize = UDim2.new(percent,0,1,0) end if tweenAction then if not tweenLength then error("updateLoadingGuiPercent is set to tween new percentage, but got no tween time length! Please pass this in as third argument") end if (newSize.X.Scale > 0) then loadingGreenBar.Visible = true loadingGreenBar:TweenSize( newSize, Enum.EasingDirection.Out, Enum.EasingStyle.Quad, tweenLength, true) else loadingGreenBar:TweenSize( newSize, Enum.EasingDirection.Out, Enum.EasingStyle.Quad, tweenLength, true, function() if (newSize.X.Scale < 0) then loadingGreenBar.Visible = false end end) end else loadingGreenBar.Size = newSize loadingGreenBar.Visible = (newSize.X.Scale > 0) end end loadingGreenBar.Changed:connect(function(prop) if prop == "Size" then loadingPercent.Text = tostring( math.ceil(loadingGreenBar.Size.X.Scale * 100) ) .. "%" end end) return loadingFrame, updateLoadingGuiPercent, cancelButtonClicked end t.CreatePluginFrame = function (name,size,position,scrollable,parent) function createMenuButton(size,position,text,fontsize,name,parent) local button = Instance.new("TextButton",parent) button.AutoButtonColor = false button.Name = name button.BackgroundTransparency = 1 button.Position = position button.Size = size button.Font = Enum.Font.ArialBold button.FontSize = fontsize button.Text = text button.TextColor3 = Color3.new(1,1,1) button.BorderSizePixel = 0 button.BackgroundColor3 = Color3.new(20/255,20/255,20/255) button.MouseEnter:connect(function ( ) if button.Selected then return end button.BackgroundTransparency = 0 end) button.MouseLeave:connect(function ( ) if button.Selected then return end button.BackgroundTransparency = 1 end) return button end local dragBar = Instance.new("Frame",parent) dragBar.Name = tostring(name) .. "DragBar" dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255) dragBar.BorderColor3 = Color3.new(0,0,0) if size then dragBar.Size = UDim2.new(size.X.Scale,size.X.Offset,0,20) + UDim2.new(0,20,0,0) else dragBar.Size = UDim2.new(0,183,0,20) end if position then dragBar.Position = position end dragBar.Active = true dragBar.Draggable = true --dragBar.Visible = false dragBar.MouseEnter:connect(function ( ) dragBar.BackgroundColor3 = Color3.new(49/255,49/255,49/255) end) dragBar.MouseLeave:connect(function ( ) dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255) end) -- plugin name label local pluginNameLabel = Instance.new("TextLabel",dragBar) pluginNameLabel.Name = "BarNameLabel" pluginNameLabel.Text = " " .. tostring(name) pluginNameLabel.TextColor3 = Color3.new(1,1,1) pluginNameLabel.TextStrokeTransparency = 0 pluginNameLabel.Size = UDim2.new(1,0,1,0) pluginNameLabel.Font = Enum.Font.ArialBold pluginNameLabel.FontSize = Enum.FontSize.Size18 pluginNameLabel.TextXAlignment = Enum.TextXAlignment.Left pluginNameLabel.BackgroundTransparency = 1 -- close button local closeButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-16,0.5,-8),"X",Enum.FontSize.Size14,"CloseButton",dragBar) local closeEvent = Instance.new("BindableEvent") closeEvent.Name = "CloseEvent" closeEvent.Parent = closeButton closeButton.MouseButton1Click:connect(function () closeEvent:Fire() closeButton.BackgroundTransparency = 1 end) -- help button local helpButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-51,0.5,-8),"?",Enum.FontSize.Size14,"HelpButton",dragBar) local helpFrame = Instance.new("Frame",dragBar) helpFrame.Name = "HelpFrame" helpFrame.BackgroundColor3 = Color3.new(0,0,0) helpFrame.Size = UDim2.new(0,300,0,552) helpFrame.Position = UDim2.new(1,5,0,0) helpFrame.Active = true helpFrame.BorderSizePixel = 0 helpFrame.Visible = false helpButton.MouseButton1Click:connect(function( ) helpFrame.Visible = not helpFrame.Visible if helpFrame.Visible then helpButton.Selected = true helpButton.BackgroundTransparency = 0 local screenGui = getScreenGuiAncestor(helpFrame) if screenGui then if helpFrame.AbsolutePosition.X + helpFrame.AbsoluteSize.X > screenGui.AbsoluteSize.X then --position on left hand side helpFrame.Position = UDim2.new(0,-5 - helpFrame.AbsoluteSize.X,0,0) else -- position on right hand side helpFrame.Position = UDim2.new(1,5,0,0) end else helpFrame.Position = UDim2.new(1,5,0,0) end else helpButton.Selected = false helpButton.BackgroundTransparency = 1 end end) local minimizeButton = createMenuButton(UDim2.new(0,16,0,17),UDim2.new(1,-34,0.5,-8),"-",Enum.FontSize.Size14,"MinimizeButton",dragBar) minimizeButton.TextYAlignment = Enum.TextYAlignment.Top local minimizeFrame = Instance.new("Frame",dragBar) minimizeFrame.Name = "MinimizeFrame" minimizeFrame.BackgroundColor3 = Color3.new(73/255,73/255,73/255) minimizeFrame.BorderColor3 = Color3.new(0,0,0) minimizeFrame.Position = UDim2.new(0,0,1,0) if size then minimizeFrame.Size = UDim2.new(size.X.Scale,size.X.Offset,0,50) + UDim2.new(0,20,0,0) else minimizeFrame.Size = UDim2.new(0,183,0,50) end minimizeFrame.Visible = false local minimizeBigButton = Instance.new("TextButton",minimizeFrame) minimizeBigButton.Position = UDim2.new(0.5,-50,0.5,-20) minimizeBigButton.Name = "MinimizeButton" minimizeBigButton.Size = UDim2.new(0,100,0,40) minimizeBigButton.Style = Enum.ButtonStyle.RobloxButton minimizeBigButton.Font = Enum.Font.ArialBold minimizeBigButton.FontSize = Enum.FontSize.Size18 minimizeBigButton.TextColor3 = Color3.new(1,1,1) minimizeBigButton.Text = "Show" local separatingLine = Instance.new("Frame",dragBar) separatingLine.Name = "SeparatingLine" separatingLine.BackgroundColor3 = Color3.new(115/255,115/255,115/255) separatingLine.BorderSizePixel = 0 separatingLine.Position = UDim2.new(1,-18,0.5,-7) separatingLine.Size = UDim2.new(0,1,0,14) local otherSeparatingLine = separatingLine:clone() otherSeparatingLine.Position = UDim2.new(1,-35,0.5,-7) otherSeparatingLine.Parent = dragBar local widgetContainer = Instance.new("Frame",dragBar) widgetContainer.Name = "WidgetContainer" widgetContainer.BackgroundTransparency = 1 widgetContainer.Position = UDim2.new(0,0,1,0) widgetContainer.BorderColor3 = Color3.new(0,0,0) if not scrollable then widgetContainer.BackgroundTransparency = 0 widgetContainer.BackgroundColor3 = Color3.new(72/255,72/255,72/255) end if size then if scrollable then widgetContainer.Size = size else widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,size.Y.Scale,size.Y.Offset) end else if scrollable then widgetContainer.Size = UDim2.new(0,163,0,400) else widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,0,400) end end if position then widgetContainer.Position = position + UDim2.new(0,0,0,20) end local frame,control,verticalDragger = nil if scrollable then --frame for widgets frame,control = t.CreateTrueScrollingFrame() frame.Size = UDim2.new(1, 0, 1, 0) frame.BackgroundColor3 = Color3.new(72/255,72/255,72/255) frame.BorderColor3 = Color3.new(0,0,0) frame.Active = true frame.Parent = widgetContainer control.Parent = dragBar control.BackgroundColor3 = Color3.new(72/255,72/255,72/255) control.BorderSizePixel = 0 control.BackgroundTransparency = 0 control.Position = UDim2.new(1,-21,1,1) if size then control.Size = UDim2.new(0,21,size.Y.Scale,size.Y.Offset) else control.Size = UDim2.new(0,21,0,400) end control:FindFirstChild("ScrollDownButton").Position = UDim2.new(0,0,1,-20) local fakeLine = Instance.new("Frame",control) fakeLine.Name = "FakeLine" fakeLine.BorderSizePixel = 0 fakeLine.BackgroundColor3 = Color3.new(0,0,0) fakeLine.Size = UDim2.new(0,1,1,1) fakeLine.Position = UDim2.new(1,0,0,0) verticalDragger = Instance.new("TextButton",widgetContainer) verticalDragger.ZIndex = 2 verticalDragger.AutoButtonColor = false verticalDragger.Name = "VerticalDragger" verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255) verticalDragger.BorderColor3 = Color3.new(0,0,0) verticalDragger.Size = UDim2.new(1,20,0,20) verticalDragger.Position = UDim2.new(0,0,1,0) verticalDragger.Active = true verticalDragger.Text = "" local scrubFrame = Instance.new("Frame",verticalDragger) scrubFrame.Name = "ScrubFrame" scrubFrame.BackgroundColor3 = Color3.new(1,1,1) scrubFrame.BorderSizePixel = 0 scrubFrame.Position = UDim2.new(0.5,-5,0.5,0) scrubFrame.Size = UDim2.new(0,10,0,1) scrubFrame.ZIndex = 5 local scrubTwo = scrubFrame:clone() scrubTwo.Position = UDim2.new(0.5,-5,0.5,-2) scrubTwo.Parent = verticalDragger local scrubThree = scrubFrame:clone() scrubThree.Position = UDim2.new(0.5,-5,0.5,2) scrubThree.Parent = verticalDragger local areaSoak = Instance.new("TextButton",getScreenGuiAncestor(parent)) areaSoak.Name = "AreaSoak" areaSoak.Size = UDim2.new(1,0,1,0) areaSoak.BackgroundTransparency = 1 areaSoak.BorderSizePixel = 0 areaSoak.Text = "" areaSoak.ZIndex = 10 areaSoak.Visible = false areaSoak.Active = true local draggingVertical = false local startYPos = nil verticalDragger.MouseEnter:connect(function () verticalDragger.BackgroundColor3 = Color3.new(60/255,60/255,60/255) end) verticalDragger.MouseLeave:connect(function () verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255) end) verticalDragger.MouseButton1Down:connect(function(x,y) draggingVertical = true areaSoak.Visible = true startYPos = y end) areaSoak.MouseButton1Up:connect(function ( ) draggingVertical = false areaSoak.Visible = false end) areaSoak.MouseMoved:connect(function(x,y) if not draggingVertical then return end local yDelta = y - startYPos if not control.ScrollDownButton.Visible and yDelta > 0 then return end if (widgetContainer.Size.Y.Offset + yDelta) < 150 then widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,150) control.Size = UDim2.new (0,21,0,150) return end startYPos = y if widgetContainer.Size.Y.Offset + yDelta >= 0 then widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,widgetContainer.Size.Y.Offset + yDelta) control.Size = UDim2.new(0,21,0,control.Size.Y.Offset + yDelta ) end end) end local function switchMinimize() minimizeFrame.Visible = not minimizeFrame.Visible if scrollable then frame.Visible = not frame.Visible verticalDragger.Visible = not verticalDragger.Visible control.Visible = not control.Visible else widgetContainer.Visible = not widgetContainer.Visible end if minimizeFrame.Visible then minimizeButton.Text = "+" else minimizeButton.Text = "-" end end minimizeBigButton.MouseButton1Click:connect(function ( ) switchMinimize() end) minimizeButton.MouseButton1Click:connect(function( ) switchMinimize() end) if scrollable then return dragBar, frame, helpFrame, closeEvent else return dragBar, widgetContainer, helpFrame, closeEvent end end t.Help = function(funcNameOrFunc) --input argument can be a string or a function. Should return a description (of arguments and expected side effects) if funcNameOrFunc == "CreatePropertyDropDownMenu" or funcNameOrFunc == t.CreatePropertyDropDownMenu then return "Function CreatePropertyDropDownMenu. " .. "Arguments: (instance, propertyName, enumType). " .. "Side effect: returns a container with a drop-down-box that is linked to the 'property' field of 'instance' which is of type 'enumType'" end if funcNameOrFunc == "CreateDropDownMenu" or funcNameOrFunc == t.CreateDropDownMenu then return "Function CreateDropDownMenu. " .. "Arguments: (items, onItemSelected). " .. "Side effect: Returns 2 results, a container to the gui object and a 'updateSelection' function for external updating. The container is a drop-down-box created around a list of items" end if funcNameOrFunc == "CreateMessageDialog" or funcNameOrFunc == t.CreateMessageDialog then return "Function CreateMessageDialog. " .. "Arguments: (title, message, buttons). " .. "Side effect: Returns a gui object of a message box with 'title' and 'message' as passed in. 'buttons' input is an array of Tables contains a 'Text' and 'Function' field for the text/callback of each button" end if funcNameOrFunc == "CreateStyledMessageDialog" or funcNameOrFunc == t.CreateStyledMessageDialog then return "Function CreateStyledMessageDialog. " .. "Arguments: (title, message, style, buttons). " .. "Side effect: Returns a gui object of a message box with 'title' and 'message' as passed in. 'buttons' input is an array of Tables contains a 'Text' and 'Function' field for the text/callback of each button, 'style' is a string, either Error, Notify or Confirm" end if funcNameOrFunc == "GetFontHeight" or funcNameOrFunc == t.GetFontHeight then return "Function GetFontHeight. " .. "Arguments: (font, fontSize). " .. "Side effect: returns the size in pixels of the given font + fontSize" end if funcNameOrFunc == "LayoutGuiObjects" or funcNameOrFunc == t.LayoutGuiObjects then end if funcNameOrFunc == "CreateScrollingFrame" or funcNameOrFunc == t.CreateScrollingFrame then return "Function CreateScrollingFrame. " .. "Arguments: (orderList, style) " .. "Side effect: returns 4 objects, (scrollFrame, scrollUpButton, scrollDownButton, recalculateFunction). 'scrollFrame' can be filled with GuiObjects. It will lay them out and allow scrollUpButton/scrollDownButton to interact with them. Orderlist is optional (and specifies the order to layout the children. Without orderlist, it uses the children order. style is also optional, and allows for a 'grid' styling if style is passed 'grid' as a string. recalculateFunction can be called when a relayout is needed (when orderList changes)" end if funcNameOrFunc == "CreateTrueScrollingFrame" or funcNameOrFunc == t.CreateTrueScrollingFrame then return "Function CreateTrueScrollingFrame. " .. "Arguments: (nil) " .. "Side effect: returns 2 objects, (scrollFrame, controlFrame). 'scrollFrame' can be filled with GuiObjects, and they will be clipped if not inside the frame's bounds. controlFrame has children scrollup and scrolldown, as well as a slider. controlFrame can be parented to any guiobject and it will readjust itself to fit." end if funcNameOrFunc == "AutoTruncateTextObject" or funcNameOrFunc == t.AutoTruncateTextObject then return "Function AutoTruncateTextObject. " .. "Arguments: (textLabel) " .. "Side effect: returns 2 objects, (textLabel, changeText). The 'textLabel' input is modified to automatically truncate text (with ellipsis), if it gets too small to fit. 'changeText' is a function that can be used to change the text, it takes 1 string as an argument" end if funcNameOrFunc == "CreateSlider" or funcNameOrFunc == t.CreateSlider then return "Function CreateSlider. " .. "Arguments: (steps, width, position) " .. "Side effect: returns 2 objects, (sliderGui, sliderPosition). The 'steps' argument specifies how many different positions the slider can hold along the bar. 'width' specifies in pixels how wide the bar should be (modifiable afterwards if desired). 'position' argument should be a UDim2 for slider positioning. 'sliderPosition' is an IntValue whose current .Value specifies the specific step the slider is currently on." end if funcNameOrFunc == "CreateSliderNew" or funcNameOrFunc == t.CreateSliderNew then return "Function CreateSliderNew. " .. "Arguments: (steps, width, position) " .. "Side effect: returns 2 objects, (sliderGui, sliderPosition). The 'steps' argument specifies how many different positions the slider can hold along the bar. 'width' specifies in pixels how wide the bar should be (modifiable afterwards if desired). 'position' argument should be a UDim2 for slider positioning. 'sliderPosition' is an IntValue whose current .Value specifies the specific step the slider is currently on." end if funcNameOrFunc == "CreateLoadingFrame" or funcNameOrFunc == t.CreateLoadingFrame then return "Function CreateLoadingFrame. " .. "Arguments: (name, size, position) " .. "Side effect: Creates a gui that can be manipulated to show progress for a particular action. Name appears above the loading bar, and size and position are udim2 values (both size and position are optional arguments). Returns 3 arguments, the first being the gui created. The second being updateLoadingGuiPercent, which is a bindable function. This function takes one argument (two optionally), which should be a number between 0 and 1, representing the percentage the loading gui should be at. The second argument to this function is a boolean value that if set to true will tween the current percentage value to the new percentage value, therefore our third argument is how long this tween should take. Our third returned argument is a BindableEvent, that when fired means that someone clicked the cancel button on the dialog." end if funcNameOrFunc == "CreateTerrainMaterialSelector" or funcNameOrFunc == t.CreateTerrainMaterialSelector then return "Function CreateTerrainMaterialSelector. " .. "Arguments: (size, position) " .. "Side effect: Size and position are UDim2 values that specifies the selector's size and position. Both size and position are optional arguments. This method returns 3 objects (terrainSelectorGui, terrainSelected, forceTerrainSelection). terrainSelectorGui is just the gui object that we generate with this function, parent it as you like. TerrainSelected is a BindableEvent that is fired whenever a new terrain type is selected in the gui. ForceTerrainSelection is a function that takes an argument of Enum.CellMaterial and will force the gui to show that material as currently selected." end end local RbxGui local localTesting = true local screen = script.Parent local screenResizeCon = nil local friendWord = "Friend" local friendWordLowercase = "friend" local elementNames = {} local elementNameToElement = {} local privilegeOwner = 255 local privilegeAdmin = 240 local privilegeMember = 128 local privilegeVisitor = 10 local privilegeBanned = 0 local inContextMenu = false local contextMenu3d = false local bigEasingStyle = Enum.EasingStyle.Back local smallEasingStyle = Enum.EasingStyle.Quart local personalServerContextAdded = false local personalServerPlace = false local success = pcall(function() personalServerPlace = game.IsPersonalServer end) if not success then personalServerPlace = false end local friendRequestBlacklist = {} local otherPlayerBlacklist = {} local currentSortName = "" local function waitForChild(instance, name) while not instance:FindFirstChild(name) do instance.ChildAdded:wait() end end local function waitForProperty(instance, prop) while not instance[prop] do instance.Changed:wait() end end local function Color3I(r,g,b) return Color3.new(r/255,g/255,b/255) end function robloxLock(instance) end function ArrayRemove(t, obj) for i, obj2 in ipairs(t) do if obj == obj2 then table.remove(t, i) return true end end return false end local function getPlayers() local result = {} local players = game:GetService("Players"):GetChildren() if players then for i, player in ipairs(players) do if player:IsA("Player") then table.insert(result, player) end end end return result end local brickColorTable = {} for i = 0, 63 do brickColorTable[BrickColor.palette(i).Name] = BrickColor.palette(i).Color end local function remapColor(i, j) brickColorTable[BrickColor.palette(i).Name] = BrickColor.palette(j).Color end remapColor(13, 12) remapColor(14, 12) remapColor(15, 12) remapColor(61, 29) remapColor(63, 62) remapColor(56, 50) remapColor(45, 53) remapColor(51, 20) remapColor(4, 20) remapColor(59, 35) remapColor(60, 29) local function getColor(brickColor) if brickColorTable[brickColor.Name] then return brickColorTable[brickColor.Name] else return brickColor.Color; end end local function getTeams() local result = {} local teams = game:GetService("Teams"):GetChildren() for i, team in ipairs(teams) do if team:IsA("Team") then table.insert(result, team) end end return result end local supportFriends = false local currentBoardType = "PlayerList" local currentStatCount = 0 local createBoardsFunction = nil local playerTable = {} local teamTable = {} local teamColorTable = {} local removePlayerFunction = nil local recreatePlayerFunction = nil local addPlayerFunction = function(player) if recreatePlayerFunction then recreatePlayerFunction(player) end end local sortPlayerListsFunction = nil local minimizedState = nil local bigWindowImposter = nil local smallWindowPosition = UDim2.new(0, -20, 0,5) local smallWindowSize = UDim2.new(1,0,1,0) local bigWindowSize = UDim2.new(0.6,0,0.6,0) local bigWindowPosition = UDim2.new(.2, 0, .2,0) local smallWindowHeaderYSize = 32 local debounceTeamsChanged = false local currentWindowState = "Small" local previousWindowState = nil local transitionWindowsFunction = nil local container = nil local topRightTrayContainer = nil local playerContextMenu = nil local contextMenuElements = {} local updateContextMenuItems = nil local function addContextMenuLabel(getText1, getText2, isVisible) local t = {} t.Type = "Label" t.GetText1 = getText1 t.GetText2 = getText2 t.IsVisible = isVisible table.insert(contextMenuElements, t) end local function addContextMenuButton(text, isVisible, isActive, doIt) local t = {} t.Text = text t.Type = "Button" t.IsVisible = isVisible t.IsActive = isActive t.DoIt = doIt table.insert(contextMenuElements, t) end local function getFriendStatus(player) if player == game.Players.LocalPlayer then return Enum.FriendStatus.NotFriend else local success, result = pcall(function() return game.Players.LocalPlayer:GetFriendStatus(player) end) if success then return result else return Enum.FriendStatus.NotFriend end end end local function getPrivilegeType(player) local rank = player.PersonalServerRank if rank >= privilegeOwner then return privilegeOwner elseif rank < privilegeOwner and rank >= privilegeAdmin then return privilegeAdmin elseif rank < privilegeAdmin and rank >= privilegeMember then return privilegeMember elseif rank < privilegeMember and rank >= privilegeVisitor then return privilegeVisitor else return privilegeBanned end end --Populate the ContextMenus addContextMenuLabel( --GetText1 function(player) return "Loading..." end, --GetText2 nil, --IsVisible function(player) return getFriendStatus(player) == Enum.FriendStatus.Unknown end) addContextMenuButton("Send " .. friendWord .. " Request", --IsVisible function(player) return (not otherPlayerBlacklist[player]) and (getFriendStatus(player) == Enum.FriendStatus.NotFriend) end, --IsActive function(player) return true end, --DoIt? function(player) otherPlayerBlacklist[player] = true return game.Players.LocalPlayer:RequestFriendship(player) end ) addContextMenuButton("Un" .. friendWordLowercase, --IsVisible function(player) return getFriendStatus(player) == Enum.FriendStatus.Friend end, --IsActive function(player) return true end, --DoIt function(player) return game.Players.LocalPlayer:RevokeFriendship(player) end ) addContextMenuButton("Accept " .. friendWord .. " Request", --IsVisible function(player) return (not friendRequestBlacklist[player]) and (getFriendStatus(player) == Enum.FriendStatus.FriendRequestReceived) end, --IsActive function(player) return true end, --DoIt function(player) return game.Players.LocalPlayer:RequestFriendship(player) end ) addContextMenuButton("Deny " .. friendWord .. " Request", --IsVisible function(player) return getFriendStatus(player) == Enum.FriendStatus.FriendRequestReceived end, --IsActive function(player) return true end, --DoIt function(player) friendRequestBlacklist[player] = true return game.Players.LocalPlayer:RevokeFriendship(player) end ) addContextMenuButton("Cancel " .. friendWord .. " Request", --IsVisible function(player) return false -- disable cancel request for now (can lead to griefing) --return getFriendStatus(player) == Enum.FriendStatus.FriendRequestSent end, --IsActive function(player) return true end, --DoIt function(player) otherPlayerBlacklist[player] = false return game.Players.LocalPlayer:RevokeFriendship(player) end ) function addPersonalServerContext() if personalServerContextAdded then return end personalServerContextAdded = true addContextMenuButton("Ban", --IsVisible function(player) return ( getPrivilegeType(game.Players.LocalPlayer) >= privilegeAdmin and (getPrivilegeType(player) < privilegeAdmin) ) end, --IsActive function(player) return true end, --DoIt function(player) player.PersonalServerRank = privilegeBanned return true end ) addContextMenuButton("Promote to Visitor", --IsVisible function(player) return ( getPrivilegeType(game.Players.LocalPlayer) >= privilegeAdmin ) and ( getPrivilegeType(player) == privilegeBanned ) end, --IsActive function(player) return true end, --DoIt function(player) game:GetService("PersonalServerService"):Promote(player) return true end ) addContextMenuButton("Promote to Member", --IsVisible function(player) return ( getPrivilegeType(game.Players.LocalPlayer) >= privilegeAdmin ) and ( getPrivilegeType(player) == privilegeVisitor ) end, --IsActive function(player) return true end, --DoIt function(player) game:GetService("PersonalServerService"):Promote(player) return true end ) addContextMenuButton("Promote to Admin", --IsVisible function(player) return ( getPrivilegeType(game.Players.LocalPlayer) == privilegeOwner ) and ( getPrivilegeType(player) == privilegeMember ) end, --IsActive function(player) return true end, --DoIt function(player) game:GetService("PersonalServerService"):Promote(player) return true end ) addContextMenuButton("Demote to Member", --IsVisible function(player) return ( getPrivilegeType(game.Players.LocalPlayer) == privilegeOwner ) and ( getPrivilegeType(player) == privilegeAdmin ) end, --IsActive function(player) return true end, --DoIt function(player) game:GetService("PersonalServerService"):Demote(player) return true end ) addContextMenuButton("Demote to Visitor", --IsVisible function(player) return ( getPrivilegeType(game.Players.LocalPlayer) >= privilegeAdmin ) and ( getPrivilegeType(player) == privilegeMember ) end, --IsActive function(player) return true end, --DoIt function(player) game:GetService("PersonalServerService"):Demote(player) return true end ) end local function setupBuildToolManagement() local buildToolManagerAssetId = 64164692 game:GetService("ScriptContext"):AddCoreScript(buildToolManagerAssetId,game.Players.LocalPlayer,"BuildToolManager") end local function getStatColumns(players) for i, player in ipairs(players) do local leaderstats = player:FindFirstChild("leaderstats") if leaderstats then local stats = {} local children = leaderstats:GetChildren() if children then for i, stat in ipairs(children) do if stat:IsA("IntValue") then table.insert(stats, stat) else --TODO: This should check for IntValue only but current ScoreHud does not table.insert(stats, stat) end end end return stats end end return nil end local function determineBoardType() local players = getPlayers() local foundLeaderstats = false local numStats = 0 local foundTeam = false local stats = getStatColumns(players) if stats then foundLeaderstats = true numStats = #stats end for i, player in ipairs(players) do if not foundTeam then if not player.Neutral then foundTeam = true break end end end if foundLeaderstats and foundTeam then return "TeamScore", numStats elseif foundLeaderstats then return "PlayerScore", numStats elseif foundTeam then return "TeamList", numStats else return "PlayerList", numStats end end local function toggleBigWindow() if container == nil then return end if currentWindowState == "Big" then --Hide it if previousWindowState == nil or previousWindowState == "Big" or previousWindowState == "None" then transitionWindowsFunction("None") else transitionWindowsFunction("Small") end else previousWindowState = currentWindowState transitionWindowsFunction("Big") end end local previousBigPlayerList = nil local function rebuildBoard(owner, boardType, numStats) if topRightTrayContainer == nil then topRightTrayContainer = owner:FindFirstChild("PlayerListTopRightFrame") if topRightTrayContainer == nil then topRightTrayContainer = Instance.new("Frame") topRightTrayContainer.Name = "PlayerListTopRightFrame" topRightTrayContainer.BackgroundTransparency = 1 topRightTrayContainer.Size = UDim2.new(0.2, 16, 0.42, 16) topRightTrayContainer.Position = UDim2.new(0.8, 0, 0, 0) topRightTrayContainer.Parent = container end end if minimizedState == nil then minimizedState = Instance.new("Frame") minimizedState.Name = "MinimizedPlayerlist" minimizedState.BackgroundTransparency = 1 minimizedState.Position = UDim2.new(1, -166, 0,0) minimizedState.Size = UDim2.new(0, 151, 0, 30) playerListButton = Instance.new("ImageButton") playerListButton.Name = "GoSmallButton" playerListButton.Image = "rbxasset://textures/ui/playerlist_hidden_small.png" playerListButton.BackgroundTransparency = 1 playerListButton.Size = UDim2.new(0.0, 35, 0, 30) playerListButton.Position = UDim2.new(1, -35, 0, 0) playerListButton.MouseButton1Click:connect( function() transitionWindowsFunction("Small") end) playerListButton.Parent = minimizedState minimizedState.Visible = false robloxLock(minimizedState) minimizedState.Parent = topRightTrayContainer end if bigWindowImposter == nil then bigWindowImposter = owner:FindFirstChild("BigPlayerListWindowImposter") if bigWindowImposter == nil then bigWindowImposter = Instance.new("Frame") bigWindowImposter.Name = "BigPlayerListWindowImposter" bigWindowImposter.Visible = false bigWindowImposter.BackgroundColor3 = Color3.new(0,0,0) bigWindowImposter.BackgroundTransparency = 0.7 bigWindowImposter.BorderSizePixel = 0 bigWindowImposter.Size = UDim2.new(0.4, 7, 0.4, 7) bigWindowImposter.Position = UDim2.new(0.3, 0, 0.3, 0) robloxLock(bigWindowImposter) bigWindowImposter.Parent = container end end if container == nil or container ~= owner then container = owner topRightTrayContainer.Parent = container bigWindowImposter.Parent = container end local smallVisible = true local bigVisible = false if container then if topRightTrayContainer then --Delete the old boards if topRightTrayContainer:FindFirstChild("SmallPlayerlist") then smallVisible = topRightTrayContainer.SmallPlayerlist.Visible topRightTrayContainer.SmallPlayerlist.Parent = nil end end if container:FindFirstChild("BigPlayerlist") then bigVisible = container.BigPlayerlist.Visible or (previousBigPlayerList ~= nil) container.BigPlayerlist.Parent = nil if previousBigPlayerList ~= nil then pcall(function() game.GuiService:RemoveCenterDialog(previousBigPlayerList) end) previousBigPlayerList = nil end end end local smallBoard, bigBoard = createBoardsFunction(boardType, numStats) if smallBoard then smallBoard.Visible = smallVisible smallBoard.Parent = topRightTrayContainer recalculateSmallPlayerListSize(smallBoard) end if bigBoard then if bigVisible then previousBigPlayerList = bigBoard local centerDialogSupported, msg = pcall(function() game.GuiService:AddCenterDialog(previousBigPlayerList, Enum.CenterDialogType.PlayerInitiatedDialog, function() previousBigPlayerList.Visible = true end, function() previousBigPlayerList.Visible = false end) end) bigBoard.Visible = bigVisible else bigBoard.Visible = false end bigBoard.Parent = container end return container end function recalculateSmallPlayerListSize(smallPlayerList) waitForChild(smallPlayerList,"ScrollingArea") waitForChild(smallPlayerList.ScrollingArea, "ScrollingFrame") local scrollingFrame = smallPlayerList.ScrollingArea.ScrollingFrame local playerLines = scrollingFrame:GetChildren() local totalPlayerListSize = 0 for i = 1, #playerLines do totalPlayerListSize = totalPlayerListSize + playerLines[i].AbsoluteSize.Y end if not smallPlayerList.Parent then return end local yOffset = math.max(0,(smallPlayerList.Size.Y.Scale * smallPlayerList.Parent.AbsoluteSize.Y) - totalPlayerListSize - smallWindowHeaderYSize) smallPlayerList.Size = UDim2.new(smallPlayerList.Size.X.Scale,smallPlayerList.Size.X.Offset,smallPlayerList.Size.Y.Scale,-yOffset) end local function showBigPlayerWindow() if container:FindFirstChild("BigPlayerlist") then if container.BigPlayerlist.Visible then return end end bigWindowImposter.Visible = true bigWindowImposter:TweenSizeAndPosition(bigWindowSize, bigWindowPosition, Enum.EasingDirection.Out, bigEasingStyle, 0.3, true, function(state) if state == Enum.TweenStatus.Completed then bigWindowImposter.Visible = false if container:FindFirstChild("BigPlayerlist") then container.BigPlayerlist.Visible = true end end end) end local function hideBigPlayerWindow(completed) if playerContextMenu then playerContextMenu.Visible = false end if container:FindFirstChild("BigPlayerlist") then if container.BigPlayerlist.Visible == false and bigWindowImposter.Visible == false then if completed then completed() end --Already completely hidden return end container.BigPlayerlist.Visible = false end local completedFunction = completed bigWindowImposter.Visible = true bigWindowImposter:TweenSizeAndPosition(UDim2.new(0.4, 0, 0.4, 0), UDim2.new(0.3, 0, 0.3, 0), Enum.EasingDirection.In, Enum.EasingStyle.Quart, 0.15, true, function(state) if state == Enum.TweenStatus.Completed then bigWindowImposter.Visible = false if completedFunction then completedFunction() end end end) end local function hideSmallPlayerWindow(completed) if playerContextMenu then playerContextMenu.Visible = false end if topRightTrayContainer:FindFirstChild("SmallPlayerlist") then local completedFunction = completed if topRightTrayContainer.SmallPlayerlist.Visible then topRightTrayContainer.SmallPlayerlist:TweenPosition(UDim2.new(1,0,smallWindowPosition.Y.Scale, smallWindowPosition.Y.Offset), Enum.EasingDirection.Out, smallEasingStyle, 0.3, true, function(state) if state == Enum.TweenStatus.Completed then if topRightTrayContainer:FindFirstChild("SmallPlayerlist") then topRightTrayContainer.SmallPlayerlist.Visible = false end if completedFunction then completedFunction() end end end) return end end if completed then completed() end end transitionWindowsFunction = function(desiredState) if desiredState == "Big" then minimizedState.Visible = false hideSmallPlayerWindow() if previousBigPlayerList ~= nil then if previousBigPlayerList ~= container:FindFirstChild("BigPlayerlist") then pcall(function() game.GuiService:RemoveCenterDialog(previousBigPlayerList) end) previousBigPlayerList = nil previousBigPlayerList = container:FindFirstChild("BigPlayerlist") end else previousBigPlayerList = container:FindFirstChild("BigPlayerlist") end if previousBigPlayerList then local firstShow = false local centerDialogSupported, msg = pcall(function() game.GuiService:AddCenterDialog(previousBigPlayerList, Enum.CenterDialogType.PlayerInitiatedDialog, function() if not firstShow then showBigPlayerWindow() firstShow = true else previousBigPlayerList.Visible = true end end, function() if previousBigPlayerList then previousBigPlayerList.Visible = false end end) end) if centerDialogSupported == false then print("Exception", msg) showBigPlayerWindow() end else showBigPlayerWindow() end currentWindowState = "Big" elseif desiredState == "Small" then minimizedState.Visible = false if previousBigPlayerList ~= nil then pcall(function() game.GuiService:RemoveCenterDialog(previousBigPlayerList) end) previousBigPlayerList = nil end hideBigPlayerWindow() if topRightTrayContainer:FindFirstChild("SmallPlayerlist") then if not topRightTrayContainer.SmallPlayerlist.Visible or topRightTrayContainer.SmallPlayerlist.Position ~= smallWindowPosition then topRightTrayContainer.SmallPlayerlist.Visible = true topRightTrayContainer.SmallPlayerlist:TweenPosition(smallWindowPosition, Enum.EasingDirection.Out, smallEasingStyle, 0.3, true) end end currentWindowState = "Small" elseif desiredState == "None" then if previousBigPlayerList ~= nil then pcall(function() game.GuiService:RemoveCenterDialog(previousBigPlayerList) end) previousBigPlayerList = nil end local smallDone = false local bigDone = false hideSmallPlayerWindow( function() smallDone = true if bigDone and smallDone then minimizedState.Visible = true end end) hideBigPlayerWindow( function() bigDone = true if bigDone and smallDone then minimizedState.Visible = true end end) currentWindowState = "None" end end local function getStatValuesForPlayer(player) local leaderstats = player:FindFirstChild("leaderstats") if leaderstats then local children = leaderstats:GetChildren() if children then local result = {} --Just go based on position for i, stat in ipairs(children) do if stat:IsA("IntValue") then table.insert(result, stat) else table.insert(result, 0) end end return result, leaderstats end end return nil end --ChildAdded on Player (if it's name is "leaderstats") if UserSettings and LoadLibrary then RbxGui,msg = t local function createTeamName(name, color) local fontHeight = 20 local frame = Instance.new("Frame") frame.Name = "Team-" .. name frame.BorderSizePixel = 0 frame.BackgroundTransparency = 0.5 frame.BackgroundColor3 = Color3.new(1,1,1) frame.Size = UDim2.new(1, 0, 0, fontHeight) frame.Position = UDim2.new(0,0,0,0) local label = Instance.new("TextLabel") label.Name = "NameLabel" label.Text = " " .. name label.Font = Enum.Font.ArialBold label.FontSize = Enum.FontSize.Size18 label.Position = UDim2.new(0,0,0,0) label.Size = UDim2.new(1,0,1,0) label.TextColor3 = Color3.new(1,1,1) label.BackgroundTransparency = 0.5 label.BackgroundColor3 = getColor(color) label.BorderSizePixel = 0 label.TextXAlignment = Enum.TextXAlignment.Left local changeFunc = nil label, changeFunc = RbxGui.AutoTruncateTextObject(label) label.Parent = frame return frame, changeFunc end local function getFriendStatusIcon(friendStatus) if friendStatus == Enum.FriendStatus.Unknown or friendStatus == Enum.FriendStatus.NotFriend then return nil elseif friendStatus == Enum.FriendStatus.Friend then return "rbxasset://textures/ui/PlayerlistFriendIcon.png" elseif friendStatus == Enum.FriendStatus.FriendRequestSent then return "rbxasset://textures/ui/PlayerlistFriendRequestSentIcon.png" elseif friendStatus == Enum.FriendStatus.FriendRequestReceived then return "rbxasset://textures/ui/PlayerlistFriendRequestReceivedIcon.png" else error("Unknown FriendStatus: " .. friendStatus) end end local function getMembershipTypeIcon(membershipType) if membershipType == Enum.MembershipType.None then return "" elseif membershipType == Enum.MembershipType.BuildersClub then return "rbxasset://textures/ui/TinyBcIcon.png" elseif membershipType == Enum.MembershipType.TurboBuildersClub then return "rbxasset://textures/ui/TinyTbcIcon.png" elseif membershipType == Enum.MembershipType.OutrageousBuildersClub then return "rbxasset://textures/ui/TinyObcIcon.png" else error("Uknown membershipType" .. membershipType) end end local function updatePlayerFriendStatus(nameObject, friendStatus) local fontHeight = 20 local friendIconImage = getFriendStatusIcon(friendStatus) nameObject.MembershipTypeLabel.FriendStatusLabel.Visible = (friendIconImage ~= nil) if friendIconImage ~= nil then --Show friend icon nameObject.MembershipTypeLabel.FriendStatusLabel.Image = friendIconImage nameObject.NameLabel.Position =UDim2.new(0,2*fontHeight,0,1) nameObject.NameLabel.Size = UDim2.new(1,-2*fontHeight,1,-2) else --Hide the friend icon nameObject.NameLabel.Position = UDim2.new(0,fontHeight+1,0,1) nameObject.NameLabel.Size = UDim2.new(1,-(fontHeight+1),1,-2) end end local function updatePlayerName(nameObject, membershipStatus, teamColor) local fontHeight = 20 nameObject.Size = UDim2.new(1,0,0,fontHeight) nameObject.MembershipTypeLabel.Image = getMembershipTypeIcon(membershipStatus) end local function updatePlayerNameColor(player, teamColor) local function updatePlayerNameColorHelper(nameObject) if teamColor ~= nil then nameObject.NameLabel.TextColor3 = getColor(teamColor) nameObject.NameLabel.FullNameLabel.TextColor3 = getColor(teamColor) else nameObject.NameLabel.TextColor3 = Color3.new(1,1,1) nameObject.NameLabel.FullNameLabel.TextColor3 = Color3.new(1,1,1) end end updatePlayerNameColorHelper(playerTable[player].NameObjectSmall) updatePlayerNameColorHelper(playerTable[player].NameObjectBig) end local function createPlayerName(name, membershipStatus, teamColor, friendStatus) local frame = Instance.new("Frame") frame.Name = "Player_" .. name frame.BackgroundColor3 = Color3.new(1,1,1) frame.BackgroundTransparency = 0.5 frame.BorderSizePixel = 0 local membershipStatusLabel = Instance.new("ImageLabel") membershipStatusLabel.Name = "MembershipTypeLabel" membershipStatusLabel.BackgroundTransparency = 1 membershipStatusLabel.Size = UDim2.new(1,0,1,0) membershipStatusLabel.Position = UDim2.new(0,0,0,0) membershipStatusLabel.SizeConstraint = Enum.SizeConstraint.RelativeYY membershipStatusLabel.Parent = frame local friendStatusLabel = Instance.new("ImageLabel") friendStatusLabel.Name = "FriendStatusLabel" friendStatusLabel.Visible = false friendStatusLabel.BackgroundTransparency = 1 friendStatusLabel.Size = UDim2.new(1,0,1,0) friendStatusLabel.Position = UDim2.new(1,0,0,0) friendStatusLabel.Parent = membershipStatusLabel local changeNameFunction local nameLabel = Instance.new("TextLabel") nameLabel.Name = "NameLabel" nameLabel.Text = name nameLabel.Font = Enum.Font.ArialBold nameLabel.FontSize = Enum.FontSize.Size14 nameLabel.TextColor3 = Color3.new(1,1,1) nameLabel.BackgroundTransparency = 1 nameLabel.BackgroundColor3 = Color3.new(0,0,0) nameLabel.TextXAlignment = Enum.TextXAlignment.Left nameLabel, changeNameFunction = RbxGui.AutoTruncateTextObject(nameLabel) nameLabel.Parent = frame updatePlayerName(frame, membershipStatus, teamColor) if supportFriends and not friendRequestBlacklist[game.Players:FindFirstChild(name)] then updatePlayerFriendStatus(frame, friendStatus) else updatePlayerFriendStatus(frame, Enum.FriendStatus.NotFriend) end return frame, changeNameFunction end local function createStatColumn(i, numColumns, isTeam, color3, isHeader, stat) local textLabel = Instance.new("TextButton") textLabel.Name = "Stat" .. i textLabel.AutoButtonColor = false textLabel.TextColor3 = Color3.new(1,1,1) textLabel.TextXAlignment = Enum.TextXAlignment.Right textLabel.TextYAlignment = Enum.TextYAlignment.Center textLabel.FontSize = Enum.FontSize.Size14 if isHeader then textLabel.FontSize = Enum.FontSize.Size18 else textLabel.FontSize = Enum.FontSize.Size14 end if isHeader or isTeam then textLabel.Font = Enum.Font.ArialBold else textLabel.Font = Enum.Font.Arial end if isTeam then textLabel.BackgroundColor3 = color3 textLabel.Text = 0 else textLabel.BackgroundColor3 = Color3.new(0,0,0) textLabel.Text = "" end textLabel.BackgroundTransparency = 1 if i == numColumns then textLabel.Size = UDim2.new(1/numColumns, -6, 1, 0) else textLabel.Size = UDim2.new(1/numColumns, -4, 1, 0) end textLabel.Position = UDim2.new((i-1) * (1/numColumns), 0, 0, 0) local truncLabel, changer = RbxGui.AutoTruncateTextObject(textLabel) if isHeader then local mouseCon = {} mouseCon[1] = truncLabel.MouseEnter:connect(function() truncLabel.BackgroundTransparency = 0.2 end) mouseCon[2] = truncLabel.MouseLeave:connect(function() truncLabel.BackgroundTransparency = 1 end) mouseCon[3] = truncLabel.MouseButton1Click:connect(function() sortPlayerListsFunction(truncLabel:GetChildren()[1].Name, (currentSortName == truncLabel:GetChildren()[1].Name) ) truncLabel.BackgroundTransparency = 1 end) mouseCon[4] = truncLabel:GetChildren()[1].MouseButton1Click:connect(function() sortPlayerListsFunction(textLabel.Name, (currentSortName == truncLabel.Name) ) truncLabel.BackgroundTransparency = 1 end) mouseCon[5] = nil mouseCon[5] = truncLabel.AncestryChanged:connect(function(child,parent) if parent == nil then for i,connection in pairs(mouseCon) do connection:disconnect() end end end) end return truncLabel, changer end local function createStatHeaders(stats, numColumns, isBig) local frame = Instance.new("Frame") frame.Name = "Headers" frame.BorderSizePixel = 0 frame.BackgroundColor3 = Color3.new(0,0,0) frame.BackgroundTransparency = 1 local nameSize if isBig then nameSize = 0.5 elseif numColumns == 1 then nameSize = 0.7 elseif numColumns == 2 then nameSize = 0.6 else nameSize = 0.45 end frame.Size = UDim2.new(1-nameSize, 0, 1,0) if isBig then frame.Position = UDim2.new(nameSize,-25, 0,0) else frame.Position = UDim2.new(nameSize,0, 0,0) end local i = 1 while i <= numColumns do local headerColumn, changeText = createStatColumn(i, numColumns, false, nil, true,stats[i]) changeText(stats[i].Name) headerColumn.Parent = frame i = i + 1 end return frame, textChangers end local function createStatColumns(nameObject, numColumns, isTeam, isBig) local frame = Instance.new("Frame") frame.Name = nameObject.Name .. "_WithStats" frame.BorderSizePixel = 0 frame.BackgroundColor3 = nameObject.BackgroundColor3 frame.BackgroundTransparency = nameObject.BackgroundTransparency frame.Size = nameObject.Size frame.Position = nameObject.Position nameObject.BackgroundTransparency = 1 if numColumns == 0 then nameObject.Size = UDim2.new(1,0,1,0) nameObject.Position = UDim2.new(0,0,0,0) nameObject.Parent = frame return frame end local statFrame = Instance.new("Frame") statFrame.Name = "Stats" if isTeam then statFrame.BorderSizePixel = 0 statFrame.BackgroundColor3 = nameObject.NameLabel.BackgroundColor3 statFrame.BackgroundTransparency = nameObject.NameLabel.BackgroundTransparency else statFrame.BackgroundTransparency = 1 end local nameSize if isBig then nameSize = 0.5 elseif numColumns == 1 then nameSize = 0.7 elseif numColumns == 2 then nameSize = 0.6 else nameSize = 0.45 end nameObject.Size = UDim2.new(nameSize, 0, 1, 0) nameObject.Position = UDim2.new(0, 0, 0, 0) statFrame.Size = UDim2.new(1-nameSize,0, 1,0) statFrame.Position = UDim2.new(nameSize,0, 0,0) nameObject.Parent = frame statFrame.Parent = frame local textChangers = {} local i = 1 while i <= numColumns do local statColumn, changeText = createStatColumn(i, numColumns, isTeam, statFrame.BackgroundColor3) statColumn.Parent = statFrame table.insert(textChangers, changeText) i = i + 1 end return frame, statFrame, textChangers end local function createAlternatingRows(objects) for i, line in ipairs(objects) do if i % 2 == 0 then line.BackgroundTransparency = 1 else line.BackgroundTransparency = 0.95 end end end local removeFromTeam = nil local function clearTableEntry(obj, tableInfo) if tableInfo.MainObjectSmall then tableInfo.MainObjectSmall.Parent = nil tableInfo.MainObjectSmall = nil end if tableInfo.MainObjectBig then tableInfo.MainObjectBig.Parent = nil tableInfo.MainObjectBig = nil end if tableInfo.Connections then for i, connection in ipairs(tableInfo.Connections) do connection:disconnect() end tableInfo.Connections = nil end if tableInfo.LeaderStatConnections then for i, connection in ipairs(tableInfo.LeaderStatConnections) do connection:disconnect() end tableInfo.LeaderStatConnections = nil end if tableInfo.CurrentTeam then removeFromTeam(obj) tableInfo.CurrentTeam = nil end if tableInfo.Players then for i, player in ipairs(tableInfo.Players) do playerTable[player].CurrentTeam = nil end tableInfo.Players = {} end if tableInfo.StatValues then tableInfo.StatValues = nil end end local function resetPlayerTable() for player, info in pairs(playerTable) do clearTableEntry(player, info) playerTable[player] = nil end playerTable = {} end local function resetTeamTable() for team, info in pairs(teamTable) do clearTableEntry(team, info) teamTable[team] = nil end teamTable = {} teamColorTable = {} end local function getBoardTypeInfo() local isTeam = (currentBoardType == "TeamScore" or currentBoardType == "TeamList") local isScore = (currentBoardType == "TeamScore" or currentBoardType == "PlayerScore") return isTeam, isScore end local function recomputeTeamScore(team, column) if not team or team == "Neutral" then return end local function recomputeScoreHelper(statChangers) if statChangers and column <= #statChangers then local sum = 0 for i, p in ipairs(teamTable[team].Players) do if playerTable[p].StatValues and column <= #playerTable[p].StatValues then sum = sum + playerTable[p].StatValues[column].Value end end statChangers[column](sum) end end recomputeScoreHelper(teamTable[team].StatChangersSmall) recomputeScoreHelper(teamTable[team].StatChangersBig) end local function recomputeCompleteTeamScore(team) local col = 1 while col <= currentStatCount do recomputeTeamScore(team, col) col = col + 1 end end removeFromTeam = function(player) if playerTable[player].CurrentTeam ~= nil and teamTable[playerTable[player].CurrentTeam] ~= nil then ArrayRemove(teamTable[playerTable[player].CurrentTeam].Players, player) recomputeCompleteTeamScore(playerTable[player].CurrentTeam) playerTable[player].CurrentTeam = nil end end local function assignToTeam(player) local isTeam, isScore = getBoardTypeInfo() if isTeam then local newTeam = nil if player.Neutral or teamColorTable[player.TeamColor.Name] == nil then newTeam = "Neutral" else newTeam = teamColorTable[player.TeamColor.Name] end if playerTable[player].CurrentTeam == newTeam then return end local oldTeam = playerTable[player].LastTeam removeFromTeam(player) playerTable[player].CurrentTeam = newTeam if teamTable[oldTeam] and teamTable[oldTeam]["NameChangeFuncBig"] then if #teamTable[oldTeam].Players < 1 then teamTable[oldTeam]["NameChangeFuncBig"](" " .. oldTeam.Name) else teamTable[oldTeam]["NameChangeFuncBig"](" " .. oldTeam.Name .. " (" .. tostring(#teamTable[oldTeam].Players) ..")") end end if teamTable[newTeam] then table.insert(teamTable[newTeam].Players, player) if newTeam["Name"] then if teamTable[newTeam]["NameChangeFuncBig"] then if #teamTable[newTeam].Players < 1 then teamTable[newTeam]["NameChangeFuncBig"](" " .. newTeam.Name) else teamTable[newTeam]["NameChangeFuncBig"](" " .. newTeam.Name .. " (" .. tostring(#teamTable[newTeam].Players) ..")") end end end end if newTeam == "Neutral" then updatePlayerNameColor(player, nil) else updatePlayerNameColor(player, player.TeamColor) end playerTable[player].LastTeam = newTeam recomputeCompleteTeamScore(newTeam) --Relayout if sortPlayerListsFunction then sortPlayerListsFunction() end end end local function buildTeamObject(team, numStatColumns, suffix) local isTeam, isScore = getBoardTypeInfo() local teamObject, changeFunc = createTeamName(team.Name, team.TeamColor) teamObject.NameLabel.Text = " " .. team.Name .. " (0)" if not teamTable[team] then teamTable[team] = {} end teamTable[team]["NameObject" .. suffix] = teamObject teamTable[team]["NameChangeFunc" .. suffix] = changeFunc if isScore then local statObject local textChangers teamObject, statObject, textChangers = createStatColumns(teamObject, numStatColumns, true, suffix == "Big") teamTable[team]["StatObject" .. suffix] = statObject teamTable[team]["StatChangers" .. suffix] = textChangers end teamTable[team]["MainObject" .. suffix] = teamObject changeFunc(" " .. team.Name) if not teamTable[team].Players then teamTable[team].Players = {} else if suffix ~= "Small" and #teamTable[team].Players > 0 then changeFunc(" " .. team.Name .. " (" .. tostring(#teamTable[team].Players) ..")") end end return teamObject end local currentContextMenuPlayer = nil local function updatePlayerContextMenu(player,x,y) currentContextMenuPlayer = player local elementHeight = 18 local function highlight(button) button.TextColor3 = Color3.new(0,0,0) button.BackgroundColor3 = Color3.new(0.8,0.8,0.8) end local function clearHighlight(button) button.TextColor3 = Color3.new(1,1,1) button.BackgroundColor3 = Color3.new(0,0,0) end if playerContextMenu == nil then elementNames = {} elementNameToElement = {} for i, contextElement in ipairs(contextMenuElements) do table.insert(elementNames, contextElement.Text) elementNameToElement[tostring(contextElement.Text)] = contextElement end playerContextMenu = Instance.new("TextButton") playerContextMenu.Name = "PlayerListContextMenu" playerContextMenu.Style = Enum.ButtonStyle.RobloxButton playerContextMenu.Text = "" playerContextMenu.Visible = false playerContextMenu.ZIndex = 4 playerContextMenu.MouseLeave:connect(function() local menuChildren = playerContextMenu:GetChildren() for i = 1, #menuChildren do if menuChildren[i].Name == "ChoiceButton" then menuChildren[i].TextColor3 = Color3.new(1,1,1) menuChildren[i].BackgroundTransparency = 1 end end playerContextMenu.Visible = false inContextMenu = false end) playerContextMenu.MouseEnter:connect(function() inContextMenu = true end) for i = 1, #elementNames do local newElementButton = Instance.new("TextButton") newElementButton.Name = "ChoiceButton" newElementButton.Text = elementNames[i] newElementButton.TextColor3 = Color3.new(1,1,1) newElementButton.Font = Enum.Font.Arial newElementButton.FontSize = Enum.FontSize.Size14 newElementButton.BackgroundTransparency = 1 newElementButton.TextWrap = true newElementButton.Size = UDim2.new(1,0,0,elementHeight) newElementButton.Position = UDim2.new(0,0,0,elementHeight * (i - 1)) newElementButton.ZIndex = playerContextMenu.ZIndex + 1 newElementButton.MouseEnter:connect(function() newElementButton.TextColor3 = Color3.new(0,0,0) newElementButton.BackgroundTransparency = 0 end) newElementButton.MouseLeave:connect(function() newElementButton.TextColor3 = Color3.new(1,1,1) newElementButton.BackgroundTransparency = 1 end) newElementButton.MouseButton1Click:connect(function() local element = elementNameToElement[newElementButton.Text] pcall(function() element.DoIt(currentContextMenuPlayer) end) playerContextMenu.Visible = false newElementButton.TextColor3 = Color3.new(1,1,1) newElementButton.BackgroundTransparency = 1 end) newElementButton.Parent = playerContextMenu end robloxLock(playerContextMenu) playerContextMenu.Parent = script.Parent end local visibleElements = 0 for i, contextElement in ipairs(contextMenuElements) do local isVisible = false if contextElement.IsVisible then local success, visible = pcall(function() return contextElement.IsVisible(currentContextMenuPlayer) end) if success then isVisible = visible else print("Error in IsVisible call: " .. visible) end end if isVisible then local foundElement = false for i = 1, #elementNames do if elementNames[i] == contextElement.Text then foundElement = true break end end if not foundElement then table.insert(elementNames,contextElement.Text) end visibleElements = visibleElements + 1 else for i = 1, #elementNames do if elementNames[i] == contextElement.Text then table.remove(elementNames,i) break end end end end playerContextMenu.Size = UDim2.new(0, 150, 0, elementHeight + (elementHeight * visibleElements) ) if x and y then x = x - (playerContextMenu.AbsoluteSize.X/2) if x + playerContextMenu.AbsoluteSize.X >= script.Parent.AbsoluteSize.X then x = script.Parent.AbsoluteSize.X - playerContextMenu.AbsoluteSize.X end playerContextMenu.Position = UDim2.new(0, x, 0, y - 3) end local elementPos = 0 local contextChildren = playerContextMenu:GetChildren() for i = 1, #contextChildren do if contextChildren[i]:IsA("GuiObject") and contextChildren[i].Name == "ChoiceButton" then contextChildren[i].Visible = false for j = 1, #elementNames do if elementNames[j] == contextChildren[i].Text then contextChildren[i].Visible = true contextChildren[i].Position = UDim2.new(0,0,0,elementPos * elementHeight) elementPos = elementPos + 1 break end end end end end local function playerContextMenuHasItems() if playerContextMenu then local children = playerContextMenu:GetChildren() for i = 1, #children do if children[i]:IsA("GuiObject") and children[i].Name == "ChoiceButton" and children[i].Visible then return true end end end return false end local function showPlayerMenu(player, x, y) updatePlayerContextMenu(player,x,y) if not playerContextMenuHasItems() then return end -- don't show if we have nothing to show playerContextMenu.Visible = true end local function buildPlayerObject(player, numStatColumns, suffix) if not player then return nil end local isTeam, isScore = getBoardTypeInfo() local playerObject = nil local changePlayerNameFunction = nil local currentColor = nil if isTeam and not player.Neutral then currentColor = player.TeamColor.Color else currentColor = Color3.new(1,1,1) end playerObject, changePlayerNameFunction = createPlayerName(player.Name, player.MembershipType, currentColor, getFriendStatus(player)) if not playerTable[player] then playerTable[player] = {} end if not playerTable[player].Connections then playerTable[player].Connections = {} end if not playerTable[player].CurrentTeam then playerTable[player].CurrentTeam = nil end if not playerTable[player].LastTeam then playerTable[player].LastTeam = nil end playerTable[player]["NameObject" .. suffix] = playerObject playerTable[player]["ChangeName" .. suffix] = changePlayerNameFunction if isScore then local statObject = nil local textChangers = nil playerObject, statObject, textChangers = createStatColumns(playerObject, numStatColumns, false, suffix == "Big") playerTable[player]["StatObject" .. suffix]= statObject playerTable[player]["StatChangers" .. suffix] = textChangers local statValues, leaderstats = getStatValuesForPlayer(player) if not statValues or #statValues < numStatColumns then if not playerTable[player].LeaderStatConnections then playerTable[player].LeaderStatConnections = {} end --Setup a listener to see when this data gets filled in if not leaderstats then --We don't even have a leaderstats child, wait for one table.insert(playerTable[player].LeaderStatConnections, player.ChildAdded:connect( function(child) if child.Name == "leaderstats" then --Connections will be torn down recreatePlayerFunction(player) else table.insert(playerTable[player].LeaderStatConnections, child.Changed:connect( function(prop) if prop == "Name" and child.Name == "leaderstats" then --Connections will be torn down recreatePlayerFunction(player) end end)) end end)) else --We have a leaderstats, but not enough children, recreate if we get them table.insert(playerTable[player].LeaderStatConnections, leaderstats.ChildAdded:connect( function(child) --TODO only look for IntValue recreatePlayerFunction(player) end) ) table.insert(playerTable[player].LeaderStatConnections, leaderstats.AncestryChanged:connect( function(child) --We got deleted, try again recreatePlayerFunction(player) end) ) end end if statValues then if not playerTable[player].StatValues then playerTable[player].StatValues = {} end local pos = 1 while pos <= numStatColumns and pos <= #statValues do local currentColumn = pos local statValue = statValues[pos] local statChanger = textChangers[pos] local updateStat = function(val) statChanger(val) if playerTable[player] ~= nil then recomputeTeamScore(playerTable[player].CurrentTeam, currentColumn) end end if pos > #playerTable[player].StatValues then table.insert(playerTable[player].StatValues, statValue) end if type(statValue) ~= "number" and statValue["Changed"] then table.insert(playerTable[player].Connections, statValue.Changed:connect(updateStat) ) end table.insert(playerTable[player].Connections, statValue.AncestryChanged:connect( function() recreatePlayerFunction(player) end) ) updateStat(statValue.Value) pos = pos + 1 end end end if supportFriends and player ~= game.Players.LocalPlayer and player.userId > 0 and game.Players.LocalPlayer.userId > 0 then local button = Instance.new("TextButton") button.Name = playerObject.Name .. "Button" button.Text = "" button.Active = false button.Size = playerObject.Size button.Position = playerObject.Position button.BackgroundColor3 = playerObject.BackgroundColor3 local secondButton = Instance.new("TextButton") secondButton.Name = playerObject.Name .. "RealButton" secondButton.Text = "" secondButton.BackgroundTransparency = 1 secondButton.BackgroundColor3 = playerObject.BackgroundColor3 local theNameLabel = playerObject:findFirstChild("NameLabel",true) secondButton.Parent.BackgroundTransparency = 1 secondButton.Parent.Visible = true secondButton.ZIndex = 2 secondButton.Size = UDim2.new(1,0,1,0) local previousTransparency = nil table.insert(playerTable[player].Connections, secondButton.MouseEnter:connect( function(x,y) if playerContextMenu and playerContextMenu.Visible then return end -- don't update if we currently see it updatePlayerContextMenu(player,x,y) if not playerContextMenuHasItems() then return end -- don't show if we have nothing to show if previousTransparency == nil then previousTransparency = secondButton.BackgroundTransparency end secondButton.Parent.BackgroundTransparency = 0 end)) table.insert(playerTable[player].Connections, secondButton.MouseLeave:connect( function() if previousTransparency ~= nil then previousTransparency = nil end delay(0.01,function() if playerContextMenu and not inContextMenu then playerContextMenu.Visible = false end end) secondButton.Parent.BackgroundTransparency = 1 end)) local mouseDownX, mouseDownY table.insert(playerTable[player].Connections, secondButton.MouseButton1Down:connect(function(x,y) mouseDownX = x mouseDownY = y end)) table.insert(playerTable[player].Connections, secondButton.MouseButton1Click:connect(function() showPlayerMenu(player, mouseDownX, secondButton.AbsolutePosition.Y + secondButton.AbsoluteSize.Y ) end)) playerObject.BackgroundTransparency = 1 playerObject.Size = UDim2.new(1,0,1,0) playerObject.Position = UDim2.new(0,0,0,0) playerObject.Parent = button playerTable[player]["MainObject" .. suffix] = button playerObject = button else playerTable[player]["MainObject" .. suffix] = playerObject if player == game.Players.LocalPlayer and supportFriends then table.insert(playerTable[player].Connections, player.FriendStatusChanged:connect( function(otherPlayer, friendStatus) if friendRequestBlacklist[otherPlayer] then updatePlayerFriendStatus(playerTable[otherPlayer]["NameObject" .. suffix], Enum.FriendStatus.NotFriend) elseif playerTable[otherPlayer] then updatePlayerFriendStatus(playerTable[otherPlayer]["NameObject" .. suffix], friendStatus) end end) ) end end table.insert(playerTable[player].Connections, player.Changed:connect( function(prop) if prop == "MembershipType" then updatePlayerName(playerTable[player]["NameObject" .. suffix], player.MembershipType, currentColor) elseif prop == "Name" then playerTable[player]["ChangeName" .. suffix](player.Name) elseif prop == "Neutral" or prop == "TeamColor" then assignToTeam(player) end end) ) return playerObject end local function doSort(tableToSort, objectName, order, startPos, sortType, ascending) local orderedPlayerTable = {} getLocalPlayer = false for i, player in ipairs(tableToSort) do if playerTable[player] then if playerTable[player][objectName] ~= nil then if player ~= game.Players.LocalPlayer then table.insert(orderedPlayerTable,playerTable[player][objectName]) else getLocalPlayer = true end end end end if sortType == nil then -- default back to alphabetical sort table.sort(orderedPlayerTable,function(a,b) return string.lower(a:FindFirstChild("FullNameLabel",true).Text) < string.lower(b:FindFirstChild("FullNameLabel",true).Text) end) else -- we are sorting by a value table.sort(orderedPlayerTable,function(a,b) if ascending then currentSortName = "" return tonumber(a:FindFirstChild(sortType,true).Text) > tonumber(b:FindFirstChild(sortType,true).Text) else currentSortName = sortType return tonumber(a:FindFirstChild(sortType,true).Text) < tonumber(b:FindFirstChild(sortType,true).Text) end end) end if getLocalPlayer and playerTable[game.Players.LocalPlayer] and playerTable[game.Players.LocalPlayer][objectName] then table.insert(orderedPlayerTable,1,playerTable[game.Players.LocalPlayer][objectName]) end for i = 1, #orderedPlayerTable do order[orderedPlayerTable[i]] = startPos startPos = startPos + 1 end return startPos end local function orderScrollList(scrollOrder, objectName, scrollFrame, sortType, ascending) local pos = 0 local order = {} local isTeam, isScore = getBoardTypeInfo() for i, obj in ipairs(scrollOrder) do order[obj] = 0 end if isTeam then local teams = getTeams() for i, team in ipairs(teams) do if teamTable[team][objectName] then order[teamTable[team][objectName]] = pos pos = pos + 1 end pos = doSort(teamTable[team].Players, objectName, order, pos, sortType, ascending) end if #teamTable["Neutral"].Players > 0 then teamTable["Neutral"][objectName].Parent = scrollFrame order[teamTable["Neutral"][objectName]] = pos pos = pos + 1 doSort(teamTable["Neutral"].Players, objectName, order, pos, sortType, ascending) else teamTable["Neutral"][objectName].Parent = nil end else local players = getPlayers() doSort(players, objectName, order, pos, sortType, ascending) end table.sort(scrollOrder, function(a,b) return order[a] < order[b] end) end local function createPlayerListBasics(frame, isBig) local headerFrame = Instance.new("Frame") headerFrame.Name = "Header" headerFrame.BackgroundTransparency = 1 headerFrame.Size = UDim2.new(1,-13,0,26) headerFrame.Position = UDim2.new(0,0,0,0) headerFrame.Parent = frame local lowerPaneFrame = Instance.new("Frame") lowerPaneFrame.Name = "ScrollingArea" lowerPaneFrame.BackgroundTransparency = 1 lowerPaneFrame.Size = UDim2.new(1,-3,1,-26) if not isBig then lowerPaneFrame.Size = UDim2.new(1,-3,1,-30) end lowerPaneFrame.Position = UDim2.new(0,0,0,26) lowerPaneFrame.Parent = frame local scrollOrder = {} local scrollFrame, scrollUp, scrollDown, recalculateScroll, scrollBar = RbxGui.CreateScrollingFrame(scrollOrder) scrollBar.Size = UDim2.new(0, 17, 1, -36) if isBig then scrollBar.Size = UDim2.new(0, 17, 1, -61) end scrollBar.Parent = lowerPaneFrame scrollFrame.Parent = lowerPaneFrame scrollUp.Parent = lowerPaneFrame scrollDown.Parent = lowerPaneFrame if isBig then scrollFrame.Position = UDim2.new(0,0,0,0) scrollUp.Position = UDim2.new(1,-41,0,5) scrollDown.Position = UDim2.new(1,-41,1,-35) scrollBar.Position = UDim2.new(1, -41, 0, 24) scrollFrame.Size = UDim2.new(1,-48,1,-16) headerFrame.Size = UDim2.new(1,-20,0,26) else scrollBar.Position = UDim2.new(1, -15, 0, 14) scrollBar.Size = UDim2.new(0,17,1,-36) scrollFrame.Position = UDim2.new(0,1,0,0) scrollUp.Position = UDim2.new(1,-15,0,-5) scrollDown.Position = UDim2.new(1,-15,1,-20) lowerPaneFrame.Position = UDim2.new(0,0,0,30) local toggleScrollBar = function(visible) if visible then scrollFrame.Size = UDim2.new(1,-16,1,0) headerFrame.Size = UDim2.new(1,-16,0,smallWindowHeaderYSize) else scrollFrame.Size = UDim2.new(1,0,1,0) headerFrame.Size = UDim2.new(1,0,0,smallWindowHeaderYSize) end scrollUp.Visible = visible scrollDown.Visible = visible scrollBar.Visible = visible end scrollUp.Changed:connect(function(prop) if prop == "Active" then toggleScrollBar(scrollUp.Active or scrollDown.Active) end end) scrollDown.Changed:connect(function(prop) if prop == "Active" then toggleScrollBar(scrollUp.Active or scrollDown.Active) end end) toggleScrollBar(scrollUp.Active or scrollDown.Active) end return headerFrame, scrollFrame, recalculateScroll, scrollOrder end createBoardsFunction = function (boardType, numStatColumns) local updatePlayerCount = function() return #getPlayers() end local smallFrame = Instance.new("Frame") smallFrame.Name = "SmallPlayerlist" smallFrame.Position = smallWindowPosition smallFrame.Active = false smallFrame.Size = smallWindowSize smallFrame.BackgroundColor3 = Color3.new(0,0,0) smallFrame.BackgroundTransparency = 0.7 smallFrame.BorderSizePixel = 0 local bigFrame = Instance.new("Frame") bigFrame.Name = "BigPlayerlist" bigFrame.Size = bigWindowSize bigFrame.Position = bigWindowPosition bigFrame.BackgroundColor3 = Color3.new(0,0,0) bigFrame.BackgroundTransparency = 0.7 bigFrame.BorderSizePixel = 0 bigFrame.Visible = false local bigFrameWrapper = Instance.new("Frame") bigFrameWrapper.Name = "Expander" bigFrameWrapper.Size = UDim2.new(1,21,1,16) bigFrameWrapper.Position = UDim2.new(0, 0, 0,0) bigFrameWrapper.BackgroundTransparency = 1 bigFrameWrapper.Parent = bigFrame local smallHeaderFrame, scrollFrameSmall, recalculateScrollSmall, scrollOrderSmall = createPlayerListBasics(smallFrame, false) local bigHeaderFrame, scrollFrameBig, recalculateScrollBig, scrollOrderBig = createPlayerListBasics(bigFrameWrapper, true) local playerListButton = Instance.new("ImageButton") playerListButton.Name = "GoBigButton" playerListButton.BackgroundTransparency = 1 playerListButton.Image = "rbxasset://textures/ui/playerlist_small_maximize.png" playerListButton.Size = UDim2.new(0.0, 35, 0, 29) playerListButton.Position = UDim2.new(0, 0, 0, 0) playerListButton.MouseButton1Click:connect( function() toggleBigWindow() end) playerListButton.Parent = smallHeaderFrame playerListButton = Instance.new("ImageButton") playerListButton.Name = "CloseButton" playerListButton.BackgroundTransparency = 1 playerListButton.Image = "rbxasset://textures/ui/playerlist_small_hide.png" playerListButton.Size = UDim2.new(0.0, 38, 0, 29) playerListButton.Position = UDim2.new(0, 35, 0, 0) playerListButton.MouseButton1Click:connect( function() transitionWindowsFunction("None") end) playerListButton.Parent = smallHeaderFrame playerListButton = Instance.new("ImageButton") playerListButton.Name = "CloseButton" playerListButton.Image = "rbxasset://textures/ui/playerlist_big_hide.png" playerListButton.BackgroundTransparency = 1 playerListButton.Size = UDim2.new(0.0, 29, 0, 29) playerListButton.Position = UDim2.new(1, -30, 0.5, -13) playerListButton.MouseButton1Click:connect( function() toggleBigWindow() end) playerListButton.Parent = bigHeaderFrame local placeName = Instance.new("TextButton") placeName.Name = "PlaceName" placeName.Text = " Players (" .. tostring(updatePlayerCount()) .. ")" placeName.AutoButtonColor = false placeName.FontSize = Enum.FontSize.Size24 placeName.TextXAlignment = Enum.TextXAlignment.Left placeName.Font = Enum.Font.ArialBold placeName.BorderSizePixel = 0 placeName.BackgroundColor3 = Color3.new(0,0,0) placeName.BackgroundTransparency = 1 placeName.TextColor3 = Color3.new(1,1,1) placeName.Size = UDim2.new(0.4, 0, 1, 0) placeName.Position = UDim2.new(0, 0, 0.0, 0) placeName = RbxGui.AutoTruncateTextObject(placeName) placeName.Parent = bigHeaderFrame placeName.MouseEnter:connect(function() placeName.BackgroundTransparency = 0.2 end) placeName.MouseLeave:connect(function() placeName.BackgroundTransparency = 1 end) placeName.MouseButton1Click:connect(function() sortPlayerListsFunction() end) currentBoardType = boardType currentStatCount = numStatColumns local isTeam, isScore = getBoardTypeInfo() local players = getPlayers() if isScore then local statColumns = getStatColumns(players) numStatColumns = #statColumns if numStatColumns > 3 then numStatColumns = 3 end createStatHeaders(statColumns, numStatColumns, false).Parent = smallHeaderFrame createStatHeaders(statColumns, currentStatCount, true).Parent = bigHeaderFrame end --Clean up all old stuff resetPlayerTable() updatePlayerCount() for i, player in ipairs(players) do local playerObject = buildPlayerObject(player, numStatColumns, "Small") table.insert(scrollOrderSmall, playerObject) playerObject.Parent = scrollFrameSmall playerObject = buildPlayerObject(player, currentStatCount, "Big") table.insert(scrollOrderBig, playerObject) playerObject.Parent = scrollFrameBig end --Clean up old stuff resetTeamTable() local teamStatObjects = {} if isTeam then local teams = getTeams() local i = #teams while i >= 1 do --We go backwards so the "first" team color gets the team local team = teams[i] teamColorTable[team.TeamColor.Name] = team i = i - 1 end --Adding/Removing a Team causes a full invalidation of the board for i, team in ipairs(teams) do local teamObject = buildTeamObject(team, numStatColumns, "Small") table.insert(scrollOrderSmall, teamObject) teamObject.Parent = scrollFrameSmall teamObject = buildTeamObject(team, currentStatCount, "Big") table.insert(scrollOrderBig, teamObject) teamObject.Parent = scrollFrameBig end teamTable["Neutral"] = {} teamTable["Neutral"].Players = {} local neutralTeamObject = createTeamName("Neutral", BrickColor.palette(8)) teamTable["Neutral"].NameObjectSmall = neutralTeamObject teamTable["Neutral"].StatObjectSmall = nil teamTable["Neutral"].MainObjectSmall = neutralTeamObject table.insert(scrollOrderSmall, neutralTeamObject) neutralTeamObject = createTeamName("Neutral", BrickColor.palette(8)) teamTable["Neutral"].NameObjectBig = neutralTeamObject teamTable["Neutral"].StatObjectBig = nil teamTable["Neutral"].MainObjectBig = neutralTeamObject table.insert(scrollOrderBig, neutralTeamObject) local neutralPlayers = {} for i, player in ipairs(players) do assignToTeam(player) end end removePlayerFunction = function(player) if playerTable[player] then clearTableEntry(player, playerTable[player]) placeName.Text = " Players (" .. tostring(updatePlayerCount()) .. ")" ArrayRemove(scrollOrderSmall, playerTable[player].MainObjectSmall) ArrayRemove(scrollOrderBig, playerTable[player].MainObjectBig) playerTable[player] = nil recalculateSmallPlayerListSize(smallFrame) end end recreatePlayerFunction = function(player) placeName.Text = " Players (" .. tostring(updatePlayerCount()) .. ")" removePlayerFunction(player) local playerObject = buildPlayerObject(player, numStatColumns, "Small") table.insert(scrollOrderSmall, playerObject) robloxLock(playerObject) playerObject.Parent = scrollFrameSmall playerObject = buildPlayerObject(player, currentStatCount, "Big") table.insert(scrollOrderBig, playerObject) robloxLock(playerObject) playerObject.Parent = scrollFrameBig local isTeam, isScore = getBoardTypeInfo() if isTeam then assignToTeam(player) end sortPlayerListsFunction() recalculateSmallPlayerListSize(smallFrame) end if screenResizeCon then screenResizeCon:disconnect() end screenResizeCon = screen.Changed:connect( function(prop) if prop == "AbsoluteSize" then wait() recalculateSmallPlayerListSize(smallFrame) end end) sortPlayerListsFunction = function(sortType, ascending) orderScrollList(scrollOrderSmall, "MainObjectSmall", scrollFrameSmall, sortType, ascending) recalculateScrollSmall() createAlternatingRows(scrollOrderSmall) orderScrollList(scrollOrderBig, "MainObjectBig", scrollFrameBig, sortType, ascending) recalculateScrollBig() createAlternatingRows(scrollOrderBig) end sortPlayerListsFunction() robloxLock(smallFrame) robloxLock(bigFrame) return smallFrame, bigFrame end --Teams changing invalidates the whole board local function teamsChanged() if debounceTeamsChanged then return end debounceTeamsChanged = true wait() rebuildBoard(script.Parent, determineBoardType()) debounceTeamsChanged = false end local checkIfBoardChanged = function() local newBoardType, numStats = determineBoardType() if newBoardType ~= currentBoardType or numStats ~= currentStatCount then rebuildBoard(script.Parent, newBoardType, numStats) end end local function buildPlayerList() waitForChild(game, "Players") waitForProperty(game.Players, "LocalPlayer") local teams = game:GetService("Teams") if teams then local teamConnections = {} teams.ChildAdded:connect( function(child) if child:IsA("Team") then teamsChanged() teamConnections[child] = child.Changed:connect( function(prop) if prop == "TeamColor" or prop == "Name" then --Rebuild when things change teamsChanged() end end) end end) teams.ChildRemoved:connect( function(child) if child:IsA("Team") then if teamConnections[child] then teamConnections[child]:disconnect() teamConnections[child] = nil end teamsChanged() end end) end game.Players.ChildAdded:connect( function(player) if player:IsA("Player") then addPlayerFunction(player) end end) game.Players.ChildRemoved:connect( function(player) if player:IsA("Player") then if removePlayerFunction then removePlayerFunction(player) end end end) rebuildBoard(script.Parent, determineBoardType()) delay(0, function() while true do wait(5) checkIfBoardChanged() end end) end buildPlayerList() end if not personalServerPlace then -- one more backup check local theBool = game.Workspace:FindFirstChild("PSVariable") if theBool and theBool:IsA("BoolValue") then personalServerPlace = true end end if personalServerPlace then addPersonalServerContext() setupBuildToolManagement() else local psVarCon = nil psVarCon = game.Workspace.ChildAdded:connect(function(child) if child:IsA("BoolValue") and child.Name == "PSVariable" then psVarCon:disconnect() personalServerPlace = true addPersonalServerContext() setupBuildToolManagement() end end) end Dialogs false 4288914085 1 4279970357 1 false false ControlFrame 0 0 0 0 1 0 1 0 0 0 true 1 false 4288914085 1 4279970357 1 false false BottomLeftControl 0 0 1 -46 0 130 0 46 0 0 true 1 false 4288914085 1 4279970357 1 false false NotificationBox 1 -200 0.5 0 0 200 0.419999987 0 0 true 1 false Init --rbxsig%XeVmMtUuu+dXh8pEbcaTkr2m9RJZXY42LaACJ12YYcuPtOUxy4Azi8uMDGU8ZTh7cvZC9BlOWgqmZHKjESSdfOZl0/cgd2JKHPZ2UqiqA1slJa7R5GtCcGXlNPHW8KDYgJGRuwe8h5CSiMDOl6QLTSEegTOG7fzHk/n1AFcRN8I=% --rbxassetid%39250920% --fixed by Carrot#0559 function waitForProperty(instance, name) while not instance[name] do instance.Changed:wait() end end local beter = game.Lighting function waitForDialogChildrenMyLord(beter, name) while not beter:FindFirstChild(name) do beter.ChildAdded:wait() end end local bois = game.Players.LocalPlayer.PlayerGui function waitForFaker(bois, name) while not bois:FindFirstChild(name) do bois.ChildAdded:wait() end end local mainFrame local choices = {} local lastChoice local choiceMap = {} local currentConversationDialog local currentConversationPartner local currentAbortDialogScript local tooFarAwayMessage = "You are too far away to chat!" local tooFarAwaySize = 300 local characterWanderedOffMessage = "Chat ended because you walked away" local characterWanderedOffSize = 350 local conversationTimedOut = "Chat ended because you didn't reply" local conversationTimedOutSize = 350 local player local screenGui local chatNotificationGui local messageDialog local timeoutScript = game.Lighting.ReenableDialogScript local reenableDialogScript = game.Lighting.TimeoutScript local dialogMap = {} local dialogConnections = {} local gui = nil --waitForDialogChildrenMyLord(game,"CoreGui") --waitForDialogChildrenMyLord(game.CoreGui,"RobloxGui") --if game.CoreGui.RobloxGui:FindFirstChild("ControlFrame") then -- gui = game.CoreGui.RobloxGui.ControlFrame --else -- gui = game.CoreGui.RobloxGui --end function currentTone() if currentConversationDialog then return currentConversationDialog.Tone else return Enum.DialogTone.Neutral end end function createChatNotificationGui() chatNotificationGui = Instance.new("BillboardGui") chatNotificationGui.Name = "ChatNotificationGui" chatNotificationGui.ExtentsOffset = Vector3.new(0,1,0) chatNotificationGui.Size = UDim2.new(4, 0, 5.42857122, 0) chatNotificationGui.SizeOffset = Vector2.new(0,0) chatNotificationGui.StudsOffset = Vector3.new(0.4, 4.3, 0) chatNotificationGui.Enabled = true chatNotificationGui.Active = true local image = Instance.new("ImageLabel") image.Name = "Image" image.Active = false image.BackgroundTransparency = 1 image.Position = UDim2.new(0,0,0,0) image.Size = UDim2.new(1.0,0,1.0,0) image.Image = "" image.Parent = chatNotificationGui local button = Instance.new("ImageButton") button.Name = "Button" button.AutoButtonColor = false button.Position = UDim2.new(0.0879999995, 0, 0.0529999994, 0) button.Size = UDim2.new(0.829999983, 0, 0.460000008, 0) button.Image = "" button.BackgroundTransparency = 1 button.Parent = image end function getChatColor(tone) if tone == Enum.DialogTone.Neutral then return Enum.ChatColor.Blue elseif tone == Enum.DialogTone.Friendly then return Enum.ChatColor.Green elseif tone == Enum.DialogTone.Enemy then return Enum.ChatColor.Red end end function styleChoices(tone) for i, obj in pairs(choices) do resetColor(obj, tone) end resetColor(lastChoice, tone) end function styleMainFrame(tone) if tone == Enum.DialogTone.Neutral then mainFrame.Style = Enum.FrameStyle.ChatBlue mainFrame.Tail.Image = "rbxasset://textures/chatBubble_botBlue_tailRight.png" elseif tone == Enum.DialogTone.Friendly then mainFrame.Style = Enum.FrameStyle.ChatGreen mainFrame.Tail.Image = "rbxasset://textures/chatBubble_botGreen_tailRight.png" elseif tone == Enum.DialogTone.Enemy then mainFrame.Style = Enum.FrameStyle.ChatRed mainFrame.Tail.Image = "rbxasset://textures/chatBubble_botRed_tailRight.png" end styleChoices(tone) end function setChatNotificationTone(gui, purpose, tone) if tone == Enum.DialogTone.Neutral then gui.Image.Image = "rbxasset://textures/chatBubble_botBlue_notify_bkg.png" elseif tone == Enum.DialogTone.Friendly then gui.Image.Image = "rbxasset://textures/chatBubble_botGreen_notify_bkg.png" elseif tone == Enum.DialogTone.Enemy then gui.Image.Image = "rbxasset://textures/chatBubble_botRed_notify_bkg.png" end if purpose == Enum.DialogPurpose.Quest then gui.Image.Button.Image = "rbxasset://textures/chatBubble_bot_notify_bang.png" elseif purpose == Enum.DialogPurpose.Help then gui.Image.Button.Image = "rbxasset://textures/chatBubble_bot_notify_question.png" elseif purpose == Enum.DialogPurpose.Shop then gui.Image.Button.Image = "rbxasset://textures/chatBubble_bot_notify_money.png" end end function createMessageDialog() messageDialog = Instance.new("Frame"); messageDialog.Name = "DialogScriptMessage" messageDialog.Style = Enum.FrameStyle.RobloxRound messageDialog.Visible = false local text = Instance.new("TextLabel") text.Name = "Text" text.Position = UDim2.new(0,0,0,-1) text.Size = UDim2.new(1,0,1,0) text.FontSize = Enum.FontSize.Size14 text.BackgroundTransparency = 1 text.TextColor3 = Color3.new(1,1,1) text.Parent = messageDialog end function showMessage(msg, size) messageDialog.Text.Text = msg messageDialog.Size = UDim2.new(0,size,0,40) messageDialog.Position = UDim2.new(0.5, -size/2, 0.5, -40) messageDialog.Visible = true wait(2) messageDialog.Visible = false end function variableDelay(str) local length = math.min(string.len(str), 100) wait(0.75 + ((length/75) * 1.5)) end function resetColor(frame, tone) if tone == Enum.DialogTone.Neutral then frame.BackgroundColor3 = Color3.new(0/255, 0/255, 179/255) frame.Number.TextColor3 = Color3.new(45/255, 142/255, 245/255) elseif tone == Enum.DialogTone.Friendly then frame.BackgroundColor3 = Color3.new(0/255, 77/255, 0/255) frame.Number.TextColor3 = Color3.new(0/255, 190/255, 0/255) elseif tone == Enum.DialogTone.Enemy then frame.BackgroundColor3 = Color3.new(140/255, 0/255, 0/255) frame.Number.TextColor3 = Color3.new(255/255,88/255, 79/255) end end function highlightColor(frame, tone) if tone == Enum.DialogTone.Neutral then frame.BackgroundColor3 = Color3.new(2/255, 108/255, 255/255) frame.Number.TextColor3 = Color3.new(1, 1, 1) elseif tone == Enum.DialogTone.Friendly then frame.BackgroundColor3 = Color3.new(0/255, 128/255, 0/255) frame.Number.TextColor3 = Color3.new(1, 1, 1) elseif tone == Enum.DialogTone.Enemy then frame.BackgroundColor3 = Color3.new(204/255, 0/255, 0/255) frame.Number.TextColor3 = Color3.new(1, 1, 1) end end function wanderDialog() print("Wander") mainFrame.Visible = false endDialog() showMessage(characterWanderedOffMessage, characterWanderedOffSize) end function timeoutDialog() print("Timeout") mainFrame.Visible = false endDialog() showMessage(conversationTimedOut, conversationTimedOutSize) end function normalEndDialog() print("Done") endDialog() end function endDialog() if currentAbortDialogScript then currentAbortDialogScript:Remove() currentAbortDialogScript = nil end local dialog = currentConversationDialog currentConversationDialog = nil if dialog and dialog.InUse then local reenableScript = reenableDialogScript:Clone() reenableScript.archivable = false reenableScript.Disabled = false reenableScript.Parent = dialog end for dialog, gui in pairs(dialogMap) do if dialog and gui then gui.Enabled = not dialog.InUse end end currentConversationPartner = nil end function sanitizeMessage(msg) if string.len(msg) == 0 then return "..." else return msg end end function selectChoice(choice) renewKillswitch(currentConversationDialog) --First hide the Gui mainFrame.Visible = false if choice == lastChoice then game.Chat:Chat(game.Players.LocalPlayer.Character, "Goodbye!", getChatColor(currentTone())) normalEndDialog() else local dialogChoice = choiceMap[choice] game.Chat:Chat(game.Players.LocalPlayer.Character, sanitizeMessage(dialogChoice.UserDialog), getChatColor(currentTone())) wait(1) --currentConversationDialog:SignalDialogChoiceSelected(player, dialogChoice) game.Chat:Chat(currentConversationPartner, sanitizeMessage(dialogChoice.ResponseDialog), getChatColor(currentTone())) variableDelay(dialogChoice.ResponseDialog) presentDialogChoices(currentConversationPartner, dialogChoice:GetChildren()) end end function newChoice(numberText) local frame = Instance.new("TextButton") frame.BackgroundColor3 = Color3.new(0/255, 0/255, 179/255) frame.AutoButtonColor = false frame.BorderSizePixel = 0 frame.Text = "" frame.MouseEnter:connect(function() highlightColor(frame, currentTone()) end) frame.MouseLeave:connect(function() resetColor(frame, currentTone()) end) frame.MouseButton1Click:connect(function() selectChoice(frame) end) local number = Instance.new("TextLabel") number.Name = "Number" number.TextColor3 = Color3.new(127/255, 212/255, 255/255) number.Text = numberText number.FontSize = Enum.FontSize.Size14 number.BackgroundTransparency = 1 number.Position = UDim2.new(0,4,0,2) number.Size = UDim2.new(0,20,0,24) number.TextXAlignment = Enum.TextXAlignment.Left number.TextYAlignment = Enum.TextYAlignment.Top number.Parent = frame local prompt = Instance.new("TextLabel") prompt.Name = "UserPrompt" prompt.BackgroundTransparency = 1 prompt.TextColor3 = Color3.new(1,1,1) prompt.FontSize = Enum.FontSize.Size14 prompt.Position = UDim2.new(0,28, 0, 2) prompt.Size = UDim2.new(1,-32, 1, -4) prompt.TextXAlignment = Enum.TextXAlignment.Left prompt.TextYAlignment = Enum.TextYAlignment.Top prompt.TextWrap = true prompt.Parent = frame return frame end function initialize(parent) choices[1] = newChoice("1)") choices[2] = newChoice("2)") choices[3] = newChoice("3)") choices[4] = newChoice("4)") lastChoice = newChoice("5)") lastChoice.UserPrompt.Text = "Goodbye!" lastChoice.Size = UDim2.new(1,0,0,28) mainFrame = Instance.new("Frame") mainFrame.Name = "UserDialogArea" mainFrame.Size = UDim2.new(0, 350, 0, 200) mainFrame.Style = Enum.FrameStyle.ChatBlue mainFrame.Visible = false local imageLabel = Instance.new("ImageLabel") imageLabel.Name = "Tail" imageLabel.Size = UDim2.new(0,62,0,53) imageLabel.Position = UDim2.new(1,8,0.25) imageLabel.Image = "rbxasset://textures/chatBubble_botBlue_tailRight.png" imageLabel.BackgroundTransparency = 1 imageLabel.Parent = mainFrame for n, obj in pairs(choices) do obj.Parent = mainFrame end lastChoice.Parent = mainFrame mainFrame.Parent = parent end function presentDialogChoices(talkingPart, dialogChoices) if not currentConversationDialog then return end currentConversationPartner = talkingPart local sortedDialogChoices = {} for n, obj in pairs(dialogChoices) do if obj:IsA("DialogChoice") then table.insert(sortedDialogChoices, obj) end end table.sort(sortedDialogChoices, function(a,b) return a.Name < b.Name end) if #sortedDialogChoices == 0 then normalEndDialog() return end local pos = 1 local yPosition = 0 choiceMap = {} for n, obj in pairs(choices) do obj.Visible = false end for n, obj in pairs(sortedDialogChoices) do if pos <= #choices then --3 lines is the maximum, set it to that temporarily choices[pos].Size = UDim2.new(1, 0, 0, 24*3) choices[pos].UserPrompt.Text = obj.UserDialog local height = math.ceil(choices[pos].UserPrompt.TextBounds.Y/24)*24 choices[pos].Position = UDim2.new(0, 0, 0, yPosition) choices[pos].Size = UDim2.new(1, 0, 0, height) choices[pos].Visible = true choiceMap[choices[pos]] = obj yPosition = yPosition + height pos = pos + 1 end end lastChoice.Position = UDim2.new(0,0,0,yPosition) lastChoice.Number.Text = pos .. ")" mainFrame.Size = UDim2.new(0, 350, 0, yPosition+24+32) mainFrame.Position = UDim2.new(0,20,0.0, -mainFrame.Size.Y.Offset-20) styleMainFrame(currentTone()) mainFrame.Visible = true end function doDialog(dialog) while not Instance.Lock(dialog, player) do wait() end if dialog.InUse then Instance.Unlock(dialog) return else dialog.InUse = true Instance.Unlock(dialog) end currentConversationDialog = dialog game.Chat:Chat(dialog.Parent, dialog.InitialPrompt, getChatColor(dialog.Tone)) variableDelay(dialog.InitialPrompt) presentDialogChoices(dialog.Parent, dialog:GetChildren()) end function renewKillswitch(dialog) if currentAbortDialogScript then currentAbortDialogScript:Remove() currentAbortDialogScript = nil end currentAbortDialogScript = timeoutScript:Clone() currentAbortDialogScript.archivable = false currentAbortDialogScript.Disabled = false currentAbortDialogScript.Parent = dialog end function checkForLeaveArea() while currentConversationDialog do if currentConversationDialog.Parent and (player:DistanceFromCharacter(currentConversationDialog.Parent.Position) >= currentConversationDialog.ConversationDistance) then wanderDialog() end wait(1) end end function startDialog(dialog) if dialog.Parent and dialog.Parent:IsA("BasePart") then if player:DistanceFromCharacter(dialog.Parent.Position) >= dialog.ConversationDistance then showMessage(tooFarAwayMessage, tooFarAwaySize) return end for dialog, gui in pairs(dialogMap) do if dialog and gui then gui.Enabled = false end end renewKillswitch(dialog) delay(1, checkForLeaveArea) doDialog(dialog) end end function removeDialog(dialog) if dialogMap[dialog] then dialogMap[dialog]:Remove() dialogMap[dialog] = nil end if dialogConnections[dialog] then dialogConnections[dialog]:disconnect() dialogConnections[dialog] = nil end end function addDialog(dialog) if dialog.Parent then if dialog.Parent:IsA("BasePart") then local chatGui = chatNotificationGui:clone() chatGui.Enabled = not dialog.InUse chatGui.Adornee = dialog.Parent chatGui.Parent = game.Players.LocalPlayer.PlayerGui chatGui.Image.Button.MouseButton1Click:connect(function() startDialog(dialog) end) setChatNotificationTone(chatGui, dialog.Purpose, dialog.Tone) dialogMap[dialog] = chatGui dialogConnections[dialog] = dialog.Changed:connect(function(prop) if prop == "Parent" and dialog.Parent then --This handles the reparenting case, seperate from removal case removeDialog(dialog) addDialog(dialog) elseif prop == "InUse" then chatGui.Enabled = not currentConversationDialog and not dialog.InUse if dialog == currentConversationDialog then timeoutDialog() end elseif prop == "Tone" or prop == "Purpose" then setChatNotificationTone(chatGui, dialog.Purpose, dialog.Tone) end end) else -- still need to listen to parent changes even if current parent is not a BasePart dialogConnections[dialog] = dialog.Changed:connect(function(prop) if prop == "Parent" and dialog.Parent then --This handles the reparenting case, seperate from removal case removeDialog(dialog) addDialog(dialog) end end) end end end --[[function fetchScripts() local model = game:GetService("InsertService"):LoadAsset(39226062) if type(model) == "string" then -- load failed, lets try again wait(0.1) model = game:GetService("InsertService"):LoadAsset(39226062) end if type(model) == "string" then -- not going to work, lets bail return end waitForDialogChildrenMyLord(model,"TimeoutScript") timeoutScript = model.TimeoutScript waitForDialogChildrenMyLord(model,"ReenableDialogScript") reenableDialogScript = model.ReenableDialogScript end ]]-- function onLoad() waitForProperty(game.Players, "LocalPlayer") player = game.Players.LocalPlayer waitForProperty(player, "Character") --print("Fetching Scripts") --fetchScripts() --print("Creating Guis") createChatNotificationGui() waitForFaker(bois,"Dialogs") --print("Creating MessageDialog") createMessageDialog() messageDialog.Parent = game.Players.LocalPlayer.PlayerGui.Dialogs --print("Initializing Frame") local frame = Instance.new("Frame") frame.Name = "DialogFrame" frame.Position = UDim2.new(0,0,0,0) frame.Size = UDim2.new(0,0,0,0) frame.BackgroundTransparency = 1 frame.Parent = game.Players.LocalPlayer.PlayerGui.Dialogs.ControlFrame.BottomLeftControl initialize(frame) --print("Adding Dialogs") game.CollectionService.ItemAdded:connect(function(obj) if obj:IsA("Dialog") then addDialog(obj) end end) game.CollectionService.ItemRemoved:connect(function(obj) if obj:IsA("Dialog") then removeDialog(obj) end end) for i, obj in pairs(game.CollectionService:GetCollection("Dialog")) do if obj:IsA("Dialog") then addDialog(obj) end end end onLoad() true ReenableDialogScript wait(5) local dialog = script.Parent if dialog:IsA("Dialog") then dialog.InUse = false end script:Remove() true TimeoutScript wait(5) local dialog = script.Parent if dialog:IsA("Dialog") then dialog.InUse = false end script:Remove() Health false 4285215356 1 4279970357 1 false false tray 0.5 -44 1 -26 0 170 0 18 2 0 true 1 false 4294967295 1 4279970357 1 false false rbxasset://textures/healthgui/bkg.png bkg 0 0 0 0 1 0 1 0 0 true 1 false 4294967295 1 4279970357 1 false false rbxasset://textures/healthgui/BarRed.png barRed 0.0189999994 0 0.100000001 0 0 0 0 0 0 true 1 false 4294967295 1.00000012 4279970357 0 false false bar2 0.0189999994 0 0.100000001 0 0.192000002 0 0.829999983 0 0 0 true 1 false Init h = game.Players.LocalPlayer.Character.Humanoid tray = script.Parent.Parent base = tray.Parent local lastHealth = 100 local lastHealth2 = 100 local maxWidth = 0.96 function UpdateGUI(health) local width = (health / h.MaxHealth) * maxWidth local height = 0.83 local lastX = tray.bar.Position.X.Scale local x = 0.019 + (maxWidth - width) local y = 0.1 tray.bar.Position = UDim2.new(x,0,y, 0) tray.bar.Size = UDim2.new(width, 0, height, 0) -- If more than 1/4 health, bar = green. Else, bar = red. if( (health / h.MaxHealth) > 0.25 ) then tray.barRed.Size = UDim2.new(0, 0, 0, 0) else tray.barRed.Position = tray.bar.Position tray.barRed.Size = tray.bar.Size tray.bar.Size = UDim2.new(0, 0, 0, 0) end if ( (lastHealth - health) > (h.MaxHealth / 10) ) then lastHealth = health if h.Health ~= h.MaxHealth then delay(0,function() AnimateHurtOverlay() end) delay(0,function() AnimateBars(x, y, lastX, height) end) end else lastHealth = health end end function AnimateBars(x, y, lastX, height) local width = math.abs(x - lastX) if( x > lastX ) then x = lastX end tray.bar2.Position = UDim2.new(x,0, y, 0) tray.bar2.Size = UDim2.new(width, 0, height, 0) tray.bar2.BackgroundTransparency = 0 local GBchannels = 1 local j = 0.2 local i_total = 30 for i=1,i_total do -- Increment Values if (GBchannels < 0.2) then j = -j end GBchannels = GBchannels + j if (i > (i_total - 10)) then tray.bar2.BackgroundTransparency = tray.bar2.BackgroundTransparency + 0.1 end tray.bar2.BackgroundColor3 = Color3.new(1, GBchannels, GBchannels) wait(0.02) end end function AnimateHurtOverlay() -- Start: -- overlay.Position = UDim2.new(0, 0, 0, -22) -- overlay.Size = UDim2.new(1, 0, 1.15, 30) -- Finish: -- overlay.Position = UDim2.new(-2, 0, -2, -22) -- overlay.Size = UDim2.new(4.5, 0, 4.65, 30) overlay = base.hurtOverlay overlay.Visible = true overlay.Position = UDim2.new(-2, 0, -2, -22) overlay.Size = UDim2.new(4.5, 0, 4.65, 30) -- Animate In, fast local i_total = 2 local wiggle_total = 0 local wiggle_i = 0.02 for i=1,i_total do overlay.Position = UDim2.new( (-2 + (2 * (i/i_total)) + wiggle_total/2), 0, (-2 + (2 * (i/i_total)) + wiggle_total/2), -22 ) overlay.Size = UDim2.new( (4.5 - (3.5 * (i/i_total)) + wiggle_total), 0, (4.65 - (3.5 * (i/i_total)) + wiggle_total), 30 ) wait(0.01) end i_total = 30 wait(0.03) -- Animate Out, slow for i=1,i_total do if( math.abs(wiggle_total) > (wiggle_i * 3) ) then wiggle_i = -wiggle_i end wiggle_total = wiggle_total + wiggle_i overlay.Position = UDim2.new( (0 - (2 * (i/i_total)) + wiggle_total/2), 0, (0 - (2 * (i/i_total)) + wiggle_total/2), -22 ) overlay.Size = UDim2.new( (1 + (3.5 * (i/i_total)) + wiggle_total), 0, (1.15 + (3.5 * (i/i_total)) + wiggle_total), 30 ) wait(0.01) end -- Hide after we're done overlay.Position = UDim2.new(10, 0, 0, 0) overlay.Visible = false end h.Changed:connect(function() UpdateGUI(h.Health) if ( (lastHealth2 - h.Health) > (h.MaxHealth / 10) ) then lastHealth2 = h.Health else lastHealth2 = h.Health end end) wait(0.1) script.Parent.Parent.Parent.Parent.HealthGUI:Remove() script.Parent.Parent.Parent.Name = "HealthGUI" false 4294967295 1 4279970357 1 false false rbxasset://textures/healthgui/Bar.png bar 0.0189999994 0 0.100000001 0 0.959999979 0 0.829999983 0 0 true 1 false 4294967295 1 4279970357 0 false false rbxasset://textures/healthgui/label.png label 0.680000007 0 0.300000012 0 0.25 0 0.349999994 0 0 true 1 false 4290164919 1 4279970357 1 false false rbxasset://textures/healthgui/HurtOverlay.png hurtOverlay 2 0 0 -22 1 0 1.1500001 30 0 false 1 false Hide while true do game.Players.LocalPlayer.PlayerGui.HealthGUI.tray.Visible = false game.Players.LocalPlayer.PlayerGui.HealthGUI.hurtOverlay.Visible = false end false ResetCommand function onChatted(msg, speaker) source = string.lower(speaker.Name) msg = string.lower(msg) -- Note: This one is NOT caps sensitive if msg == "!!!reset" then speaker.Character.Humanoid.Health = 0 end end function onPlayerEntered(newPlayer) newPlayer.Chatted:connect(function(msg) onChatted(msg, newPlayer) end) end game.Players.ChildAdded:connect(onPlayerEntered) Backpack false BackpackBuilder -- This script creates almost all gui elements found in the backpack (warning: there are a lot!) -- TODO: automate this process local gui = script.Parent -- A couple of necessary functions local function waitForChild(instance, name) while not instance:FindFirstChild(name) do instance.ChildAdded:wait() end end local function waitForProperty(instance, property) while not instance[property] do instance.Changed:wait() end end waitForChild(game,"Players") waitForProperty(game.Players,"LocalPlayer") local player = game.Players.LocalPlayer -- First up is the current loadout local CurrentLoadout = Instance.new("Frame") CurrentLoadout.Name = "CurrentLoadout" CurrentLoadout.Position = UDim2.new(0.5, -170, 1, -85) CurrentLoadout.Size = UDim2.new(0, 480, 0, 48) CurrentLoadout.BackgroundTransparency = 1 CurrentLoadout.Parent = gui local Debounce = Instance.new("BoolValue") Debounce.Name = "Debounce" Debounce.Parent = CurrentLoadout for i = 0, 9 do local slotFrame = Instance.new("Frame") slotFrame.BackgroundColor3 = Color3.new(0,0,0) slotFrame.BackgroundTransparency = 1 slotFrame.BorderColor3 = Color3.new(1,1,1) slotFrame.Name = "Slot" .. tostring(i) if i == 0 then slotFrame.Position = UDim2.new(0.9,0,0,0) else slotFrame.Position = UDim2.new((i - 1) * 0.1,0,0,0) end slotFrame.Size = UDim2.new(0.1,0,1,0) slotFrame.Parent = CurrentLoadout end local TempSlot = Instance.new("ImageButton") TempSlot.Name = "TempSlot" TempSlot.Active = true TempSlot.Size = UDim2.new(1,0,1,0) TempSlot.Style = Enum.ButtonStyle.RobloxButton TempSlot.Visible = false TempSlot.Parent = CurrentLoadout -- TempSlot Children local GearReference = Instance.new("ObjectValue") GearReference.Name = "GearReference" GearReference.Parent = TempSlot local ToolTipLabel = Instance.new("TextLabel") ToolTipLabel.Name = "ToolTipLabel" ToolTipLabel.Text = "" ToolTipLabel.BackgroundTransparency = 0.5 ToolTipLabel.BorderSizePixel = 0 ToolTipLabel.Visible = false ToolTipLabel.TextColor3 = Color3.new(1,1,1) ToolTipLabel.BackgroundColor3 = Color3.new(0,0,0) ToolTipLabel.TextStrokeTransparency = 0 ToolTipLabel.Font = Enum.Font.ArialBold ToolTipLabel.FontSize = Enum.FontSize.Size14 --ToolTipLabel.TextWrap = true ToolTipLabel.Size = UDim2.new(1,60,0,20) ToolTipLabel.Position = UDim2.new(0,-30,0,-30) ToolTipLabel.Parent = TempSlot local Kill = Instance.new("BoolValue") Kill.Name = "Kill" Kill.Parent = TempSlot local GearImage = Instance.new("ImageLabel") GearImage.Name = "GearImage" GearImage.BackgroundTransparency = 1 GearImage.Position = UDim2.new(0,-7,0,-7) GearImage.Size = UDim2.new(1,14,1,14) GearImage.ZIndex = 2 GearImage.Parent = TempSlot local SlotNumber = Instance.new("TextLabel") SlotNumber.Name = "SlotNumber" SlotNumber.BackgroundTransparency = 1 SlotNumber.BorderSizePixel = 0 SlotNumber.Font = Enum.Font.ArialBold SlotNumber.FontSize = Enum.FontSize.Size18 SlotNumber.Position = UDim2.new(0,-7,0,-7) SlotNumber.Size = UDim2.new(0,10,0,15) SlotNumber.TextColor3 = Color3.new(1,1,1) SlotNumber.TextTransparency = 0 SlotNumber.TextXAlignment = Enum.TextXAlignment.Left SlotNumber.TextYAlignment = Enum.TextYAlignment.Bottom SlotNumber.ZIndex = 4 SlotNumber.Parent = TempSlot local SlotNumberDownShadow = SlotNumber:clone() SlotNumberDownShadow.Name = "SlotNumberDownShadow" SlotNumberDownShadow.TextColor3 = Color3.new(0,0,0) SlotNumberDownShadow.ZIndex = 3 SlotNumberDownShadow.Position = UDim2.new(0,-6,0,-6) SlotNumberDownShadow.Parent = TempSlot local SlotNumberUpShadow = SlotNumberDownShadow:clone() SlotNumberUpShadow.Name = "SlotNumberUpShadow" SlotNumberUpShadow.Position = UDim2.new(0,-8,0,-8) SlotNumberUpShadow.Parent = TempSlot local GearText = Instance.new("TextLabel") GearText.Name = "GearText" GearText.BackgroundTransparency = 1 GearText.Font = Enum.Font.Arial GearText.FontSize = Enum.FontSize.Size14 GearText.Position = UDim2.new(0,-8,0,-8) GearText.ZIndex = 2 GearText.Size = UDim2.new(1,16,1,16) GearText.Text = "" GearText.TextColor3 = Color3.new(1,1,1) GearText.TextWrap = true GearText.Parent = TempSlot --- Great, now lets make the inventory! local Backpack = Instance.new("Frame") Backpack.Visible = false Backpack.Name = "Backpack" Backpack.Position = UDim2.new(0.5,0,0.5,0) Backpack.BackgroundColor3 = Color3.new(0,0,0) Backpack.BackgroundTransparency = 0.08 Backpack.BorderSizePixel = 0 Backpack.Parent = gui Backpack.Active = true -- Backpack Children local SwapSlot = Instance.new("BoolValue") SwapSlot.Name = "SwapSlot" SwapSlot.Parent = Backpack -- SwapSlot Children local Slot = Instance.new("IntValue") Slot.Name = "Slot" Slot.Parent = SwapSlot local GearButton = Instance.new("ObjectValue") GearButton.Name = "GearButton" GearButton.Parent = SwapSlot local Tabs = Instance.new("Frame") Tabs.Name = "Tabs" Tabs.Visible = true Tabs.BackgroundColor3 = Color3.new(0,0,0) Tabs.BackgroundTransparency = 0.08 Tabs.BorderSizePixel = 0 Tabs.Position = UDim2.new(0,0,-0.1,-4) Tabs.Size = UDim2.new(1,0,0.1,4) Tabs.Parent = Backpack -- Tabs Children local tabLine = Instance.new("Frame") tabLine.Name = "TabLine" tabLine.BackgroundColor3 = Color3.new(53/255, 53/255, 53/255) tabLine.BorderSizePixel = 0 tabLine.Position = UDim2.new(0,5,1,-4) tabLine.Size = UDim2.new(1,-10,0,4) tabLine.ZIndex = 2 tabLine.Parent = Tabs local InventoryButton = Instance.new("TextButton") InventoryButton.Name = "InventoryButton" InventoryButton.Size = UDim2.new(0,60,0,30) InventoryButton.Position = UDim2.new(0,7,1,-31) InventoryButton.BackgroundColor3 = Color3.new(1,1,1) InventoryButton.BorderColor3 = Color3.new(1,1,1) InventoryButton.Font = Enum.Font.ArialBold InventoryButton.FontSize = Enum.FontSize.Size18 InventoryButton.Text = "Gear" InventoryButton.AutoButtonColor = false InventoryButton.TextColor3 = Color3.new(0,0,0) InventoryButton.Selected = true InventoryButton.Active = true InventoryButton.ZIndex = 3 InventoryButton.Parent = Tabs local WardrobeButton = Instance.new("TextButton") WardrobeButton.Name = "WardrobeButton" WardrobeButton.Size = UDim2.new(0,90,0,30) WardrobeButton.Position = UDim2.new(0,77,1,-31) WardrobeButton.BackgroundColor3 = Color3.new(0,0,0) WardrobeButton.BorderColor3 = Color3.new(1,1,1) WardrobeButton.Font = Enum.Font.ArialBold WardrobeButton.FontSize = Enum.FontSize.Size18 WardrobeButton.Text = "Wardrobe" WardrobeButton.AutoButtonColor = false WardrobeButton.TextColor3 = Color3.new(1,1,1) WardrobeButton.Selected = false WardrobeButton.Active = true WardrobeButton.Parent = Tabs local closeButton = Instance.new("TextButton") closeButton.Name = "CloseButton" closeButton.Font = Enum.Font.ArialBold closeButton.FontSize = Enum.FontSize.Size24 closeButton.Position = UDim2.new(1,-33,0,4) closeButton.Size = UDim2.new(0,30,0,30) closeButton.Style = Enum.ButtonStyle.RobloxButton closeButton.Text = "" closeButton.TextColor3 = Color3.new(1,1,1) closeButton.Parent = Tabs closeButton.Modal = true --closeButton child local XImage = Instance.new("ImageLabel") XImage.Name = "XImage" game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=75547445") XImage.Image = "http://www.roblox.com/asset/?id=75547445" --TODO: move to rbxasset XImage.BackgroundTransparency = 1 XImage.Position = UDim2.new(-.25,-1,-.25,-1) XImage.Size = UDim2.new(1.5,2,1.5,2) XImage.ZIndex = 2 XImage.Parent = closeButton -- Generic Search gui used across backpack local SearchFrame = Instance.new("Frame") SearchFrame.Name = "SearchFrame" SearchFrame.BackgroundTransparency = 1 SearchFrame.Position = UDim2.new(1,-220,0,2) SearchFrame.Size = UDim2.new(0,220,0,24) SearchFrame.Parent = Backpack -- SearchFrame Children local SearchButton = Instance.new("ImageButton") SearchButton.Name = "SearchButton" SearchButton.Size = UDim2.new(0,25,0,25) SearchButton.BackgroundTransparency = 1 SearchButton.Image = "rbxasset://textures/ui/SearchIcon.png" SearchButton.Parent = SearchFrame local SearchBoxFrame = Instance.new("TextButton") SearchBoxFrame.Position = UDim2.new(0,25,0,0) SearchBoxFrame.Size = UDim2.new(1,-28,0,26) SearchBoxFrame.Name = "SearchBoxFrame" SearchBoxFrame.Text = "" SearchBoxFrame.Style = Enum.ButtonStyle.RobloxButton SearchBoxFrame.Parent = SearchFrame -- SearchBoxFrame Children local SearchBox = Instance.new("TextBox") SearchBox.Name = "SearchBox" SearchBox.BackgroundTransparency = 1 SearchBox.Font = Enum.Font.ArialBold SearchBox.FontSize = Enum.FontSize.Size12 SearchBox.Position = UDim2.new(0,-5,0,-5) SearchBox.Size = UDim2.new(1,10,1,10) SearchBox.TextColor3 = Color3.new(1,1,1) SearchBox.TextXAlignment = Enum.TextXAlignment.Left SearchBox.ZIndex = 2 SearchBox.TextWrap = true SearchBox.Text = "Search..." SearchBox.Parent = SearchBoxFrame local ResetButton = Instance.new("TextButton") ResetButton.Visible = false ResetButton.Name = "ResetButton" ResetButton.Position = UDim2.new(1,-26,0,3) ResetButton.Size = UDim2.new(0,20,0,20) ResetButton.Style = Enum.ButtonStyle.RobloxButtonDefault ResetButton.Text = "X" ResetButton.TextColor3 = Color3.new(1,1,1) ResetButton.Font = Enum.Font.ArialBold ResetButton.FontSize = Enum.FontSize.Size18 ResetButton.ZIndex = 3 ResetButton.Parent = SearchFrame ------------------------------- GEAR ------------------------------------------------------- local Gear = Instance.new("Frame") Gear.Name = "Gear" Gear.BackgroundTransparency = 1 Gear.Size = UDim2.new(1,0,1,0) Gear.Parent = Backpack -- Gear Children local AssetsList = Instance.new("Frame") AssetsList.Name = "AssetsList" AssetsList.BackgroundTransparency = 1 AssetsList.Size = UDim2.new(0.2,0,1,0) AssetsList.Style = Enum.FrameStyle.RobloxSquare AssetsList.Visible = false AssetsList.Parent = Gear local GearGrid = Instance.new("Frame") GearGrid.Name = "GearGrid" GearGrid.Size = UDim2.new(0.69,0,1,0) GearGrid.BackgroundTransparency = 1 GearGrid.Parent = Gear local GearButton = Instance.new("ImageButton") GearButton.Visible = false GearButton.Name = "GearButton" GearButton.Size = UDim2.new(0,64,0,64) GearButton.Style = Enum.ButtonStyle.RobloxButton GearButton.Parent = GearGrid -- GearButton Children local GearReference = Instance.new("ObjectValue") GearReference.Name = "GearReference" GearReference.Parent = GearButton local GreyOutButton = Instance.new("Frame") GreyOutButton.Name = "GreyOutButton" GreyOutButton.BackgroundTransparency = 0.5 GreyOutButton.Size = UDim2.new(1,0,1,0) GreyOutButton.Active = true GreyOutButton.Visible = false GreyOutButton.ZIndex = 3 GreyOutButton.Parent = GearButton local GearText = Instance.new("TextLabel") GearText.Name = "GearText" GearText.BackgroundTransparency = 1 GearText.Font = Enum.Font.Arial GearText.FontSize = Enum.FontSize.Size14 GearText.Position = UDim2.new(0,-8,0,-8) GearText.Size = UDim2.new(1,16,1,16) GearText.Text = "" GearText.ZIndex = 2 GearText.TextColor3 = Color3.new(1,1,1) GearText.TextWrap = true GearText.Parent = GearButton local GearGridScrollingArea = Instance.new("Frame") GearGridScrollingArea.Name = "GearGridScrollingArea" GearGridScrollingArea.Position = UDim2.new(0.7,0,0,35) GearGridScrollingArea.Size = UDim2.new(0,17,1,-45) GearGridScrollingArea.BackgroundTransparency = 1 GearGridScrollingArea.Parent = Gear local GearLoadouts = Instance.new("Frame") GearLoadouts.Name = "GearLoadouts" GearLoadouts.BackgroundTransparency = 1 GearLoadouts.Position = UDim2.new(0.7,23,0.5,1) GearLoadouts.Size = UDim2.new(0.3,-23,0.5,-1) GearLoadouts.Parent = Gear GearLoadouts.Visible = false -- GearLoadouts Children local GearLoadoutsHeader = Instance.new("Frame") GearLoadoutsHeader.Name = "GearLoadoutsHeader" GearLoadoutsHeader.BackgroundColor3 = Color3.new(0,0,0) GearLoadoutsHeader.BackgroundTransparency = 0.2 GearLoadoutsHeader.BorderColor3 = Color3.new(1,0,0) GearLoadoutsHeader.Size = UDim2.new(1,2,0.15,-1) GearLoadoutsHeader.Parent = GearLoadouts -- GearLoadoutsHeader Children local LoadoutsHeaderText = Instance.new("TextLabel") LoadoutsHeaderText.Name = "LoadoutsHeaderText" LoadoutsHeaderText.BackgroundTransparency = 1 LoadoutsHeaderText.Font = Enum.Font.ArialBold LoadoutsHeaderText.FontSize = Enum.FontSize.Size18 LoadoutsHeaderText.Size = UDim2.new(1,0,1,0) LoadoutsHeaderText.Text = "Loadouts" LoadoutsHeaderText.TextColor3 = Color3.new(1,1,1) LoadoutsHeaderText.Parent = GearLoadoutsHeader local GearLoadoutsScrollingArea = GearGridScrollingArea:clone() GearLoadoutsScrollingArea.Name = "GearLoadoutsScrollingArea" GearLoadoutsScrollingArea.Position = UDim2.new(1,-15,0.15,2) GearLoadoutsScrollingArea.Size = UDim2.new(0,17,0.85,-2) GearLoadoutsScrollingArea.Parent = GearLoadouts local LoadoutsList = Instance.new("Frame") LoadoutsList.Name = "LoadoutsList" LoadoutsList.Position = UDim2.new(0,0,0.15,2) LoadoutsList.Size = UDim2.new(1,-17,0.85,-2) LoadoutsList.Style = Enum.FrameStyle.RobloxSquare LoadoutsList.Parent = GearLoadouts local GearPreview = Instance.new("Frame") GearPreview.Name = "GearPreview" GearPreview.Position = UDim2.new(0.7,23,0,0) GearPreview.Size = UDim2.new(0.3,-28,0.5,-1) GearPreview.BackgroundTransparency = 1 GearPreview.ZIndex = 7 GearPreview.Parent = Gear -- GearPreview Children local GearStats = Instance.new("Frame") GearStats.Name = "GearStats" GearStats.BackgroundTransparency = 1 GearStats.Position = UDim2.new(0,0,0.75,0) GearStats.Size = UDim2.new(1,0,0.25,0) GearStats.ZIndex = 8 GearStats.Parent = GearPreview -- GearStats Children local GearName = Instance.new("TextLabel") GearName.Name = "GearName" GearName.BackgroundTransparency = 1 GearName.Font = Enum.Font.ArialBold GearName.FontSize = Enum.FontSize.Size18 GearName.Position = UDim2.new(0,-3,0,0) GearName.Size = UDim2.new(1,6,1,5) GearName.Text = "" GearName.TextColor3 = Color3.new(1,1,1) GearName.TextWrap = true GearName.ZIndex = 9 GearName.Parent = GearStats local GearImage = Instance.new("ImageLabel") GearImage.Name = "GearImage" GearImage.Image = "" GearImage.BackgroundTransparency = 1 GearImage.Position = UDim2.new(0.125,0,0,0) GearImage.Size = UDim2.new(0.75,0,0.75,0) GearImage.ZIndex = 8 GearImage.Parent = GearPreview --GearImage Children local GearIcons = Instance.new("Frame") GearIcons.BackgroundColor3 = Color3.new(0,0,0) GearIcons.BackgroundTransparency = 0.5 GearIcons.BorderSizePixel = 0 GearIcons.Name = "GearIcons" GearIcons.Position = UDim2.new(0.4,2,0.85,-2) GearIcons.Size = UDim2.new(0.6,0,0.15,0) GearIcons.Visible = false GearIcons.ZIndex = 9 GearIcons.Parent = GearImage -- GearIcons Children local GenreImage = Instance.new("ImageLabel") GenreImage.Name = "GenreImage" GenreImage.BackgroundColor3 = Color3.new(102/255,153/255,1) GenreImage.BackgroundTransparency = 0.5 GenreImage.BorderSizePixel = 0 GenreImage.Size = UDim2.new(0.25,0,1,0) GenreImage.Parent = GearIcons local AttributeOneImage = GenreImage:clone() AttributeOneImage.Name = "AttributeOneImage" AttributeOneImage.BackgroundColor3 = Color3.new(1,51/255,0) AttributeOneImage.Position = UDim2.new(0.25,0,0,0) AttributeOneImage.Parent = GearIcons local AttributeTwoImage = GenreImage:clone() AttributeTwoImage.Name = "AttributeTwoImage" AttributeTwoImage.BackgroundColor3 = Color3.new(153/255,1,153/255) AttributeTwoImage.Position = UDim2.new(0.5,0,0,0) AttributeTwoImage.Parent = GearIcons local AttributeThreeImage = GenreImage:clone() AttributeThreeImage.Name = "AttributeThreeImage" AttributeThreeImage.BackgroundColor3 = Color3.new(0,0.5,0.5) AttributeThreeImage.Position = UDim2.new(0.75,0,0,0) AttributeThreeImage.Parent = GearIcons ------------------------------- WARDROBE ------------------------------------------------------- local function makeCharFrame(frameName, parent) local frame = Instance.new("Frame") frame.Size = UDim2.new(1,0,1,-70) frame.Position = UDim2.new(0,0,0,20) frame.Name = frameName frame.BackgroundTransparency = 1 frame.Parent = parent frame.Visible = false return frame end local function makeZone( zoneName, image, size, position, parent ) local zone = Instance.new("ImageLabel") zone.Name = zoneName zone.Image = image zone.Size = size zone.BackgroundTransparency = 1 zone.Position = position zone.Parent = parent return zone end local function makeStyledButton( buttonName, size, position, parent, buttonStyle ) local button = Instance.new("ImageButton") button.Name = buttonName button.Size = size button.Position = position if buttonStyle then button.Style = buttonStyle else button.BackgroundColor3 = Color3.new(0,0,0) button.BorderColor3 = Color3.new(1,1,1) end button.Parent = parent return button end local function makeTextLabel( TextLabelName,text,position,parent ) local label = Instance.new("TextLabel") label.BackgroundTransparency = 1 label.Size = UDim2.new(0,32,0,14) label.Name = TextLabelName label.Font = Enum.Font.Arial label.TextColor3 = Color3.new(1,1,1) label.FontSize = Enum.FontSize.Size14 label.Text = text label.Position = position label.Parent = parent end local Wardrobe = Instance.new("Frame") Wardrobe.Name = "Wardrobe" Wardrobe.BackgroundTransparency = 1 Wardrobe.Visible = false Wardrobe.Size = UDim2.new(1,0,1,0) Wardrobe.Parent = Backpack local AssetList = Instance.new("Frame") AssetList.Name = "AssetList" AssetList.Position = UDim2.new(0,4,0,5) AssetList.Size = UDim2.new(0,85,1,-5) AssetList.BackgroundTransparency = 1 AssetList.Visible = true AssetList.Parent = Wardrobe local PreviewAssetFrame = Instance.new("Frame") PreviewAssetFrame.Name = "PreviewAssetFrame" PreviewAssetFrame.BackgroundTransparency = 1 PreviewAssetFrame.Position = UDim2.new(1,-240,0,30) PreviewAssetFrame.Size = UDim2.new(0,250,0,250) PreviewAssetFrame.Parent = Wardrobe local PreviewAssetBacking = Instance.new("TextButton") PreviewAssetBacking.Name = "PreviewAssetBacking" PreviewAssetBacking.Active = false PreviewAssetBacking.Text = "" PreviewAssetBacking.AutoButtonColor = false PreviewAssetBacking.Size = UDim2.new(1,0,1,0) PreviewAssetBacking.Style = Enum.ButtonStyle.RobloxButton PreviewAssetBacking.Visible = false PreviewAssetBacking.ZIndex = 9 PreviewAssetBacking.Parent = PreviewAssetFrame local PreviewAssetImage = Instance.new("ImageLabel") PreviewAssetImage.Name = "PreviewAssetImage" PreviewAssetImage.BackgroundTransparency = 0.8 PreviewAssetImage.Position = UDim2.new(0.5,-100,0,0) PreviewAssetImage.Size = UDim2.new(0,200,0,200) PreviewAssetImage.BorderSizePixel = 0 PreviewAssetImage.ZIndex = 10 PreviewAssetImage.Parent = PreviewAssetBacking local AssetNameLabel = Instance.new("TextLabel") AssetNameLabel.Name = "AssetNameLabel" AssetNameLabel.BackgroundTransparency = 1 AssetNameLabel.Position = UDim2.new(0,0,1,-20) AssetNameLabel.Size = UDim2.new(0.5,0,0,24) AssetNameLabel.ZIndex = 10 AssetNameLabel.Font = Enum.Font.Arial AssetNameLabel.Text = "" AssetNameLabel.TextColor3 = Color3.new(1,1,1) AssetNameLabel.Parent = PreviewAssetBacking local AssetTypeLabel = AssetNameLabel:clone() AssetTypeLabel.Name = "AssetTypeLabel" AssetTypeLabel.FontSize = Enum.FontSize.Size18 AssetTypeLabel.Position = UDim2.new(0.5,3,1,-20) AssetTypeLabel.Parent = PreviewAssetBacking local PreviewButton = Instance.new("TextButton") PreviewButton.Name = "PreviewButton" PreviewButton.Text = "Rotate" PreviewButton.BackgroundColor3 = Color3.new(0,0,0) PreviewButton.BackgroundTransparency = 0.5 PreviewButton.BorderColor3 = Color3.new(1,1,1) PreviewButton.Position = UDim2.new(1.2,-62,1,-50) PreviewButton.Size = UDim2.new(0,125,0,50) PreviewButton.Font = Enum.Font.ArialBold PreviewButton.FontSize = Enum.FontSize.Size24 PreviewButton.TextColor3 = Color3.new(1,1,1) PreviewButton.TextWrap = true PreviewButton.TextStrokeTransparency = 0 PreviewButton.Parent = Wardrobe local CharacterPane = Instance.new("Frame") CharacterPane.Name = "CharacterPane" CharacterPane.Position = UDim2.new(1,-220,0,32) CharacterPane.Size = UDim2.new(0,220,1,-40) CharacterPane.BackgroundTransparency = 1 CharacterPane.Visible = true CharacterPane.Parent = Wardrobe --CharacterPane Children local FaceFrame = makeCharFrame("FacesFrame", CharacterPane) game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=75460621") makeZone("FaceZone","http://www.roblox.com/asset/?id=75460621",UDim2.new(0,157,0,137),UDim2.new(0.5,-78,0.5,-68),FaceFrame) makeStyledButton("Face",UDim2.new(0,64,0,64),UDim2.new(0.5,-32,0.5,-135),FaceFrame) local HeadFrame = makeCharFrame("HeadsFrame", CharacterPane) makeZone("FaceZone","http://www.roblox.com/asset/?id=75460621",UDim2.new(0,157,0,137),UDim2.new(0.5,-78,0.5,-68),HeadFrame) makeStyledButton("Head",UDim2.new(0,64,0,64),UDim2.new(0.5,-32,0.5,-135),HeadFrame) local HatsFrame = makeCharFrame("HatsFrame", CharacterPane) game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=75457888") local HatsZone = makeZone("HatsZone","http://www.roblox.com/asset/?id=75457888",UDim2.new(0,186,0,184),UDim2.new(0.5,-93,0.5,-100), HatsFrame) makeStyledButton("Hat1Button",UDim2.new(0,64,0,64),UDim2.new(0,-1,0,-1),HatsZone,Enum.ButtonStyle.RobloxButton) makeStyledButton("Hat2Button",UDim2.new(0,64,0,64),UDim2.new(0,63,0,-1),HatsZone,Enum.ButtonStyle.RobloxButton) makeStyledButton("Hat3Button",UDim2.new(0,64,0,64),UDim2.new(0,127,0,-1),HatsZone,Enum.ButtonStyle.RobloxButton) local PantsFrame = makeCharFrame("PantsFrame", CharacterPane) game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=75457920") makeZone("PantsZone","http://www.roblox.com/asset/?id=75457920",UDim2.new(0,121,0,99),UDim2.new(0.5,-60,0.5,-100),PantsFrame) local pantFrame = Instance.new("Frame") pantFrame.Size = UDim2.new(0,25,0,56) pantFrame.Position = UDim2.new(0.5,-26,0.5,0) pantFrame.BackgroundColor3 = Color3.new(0,0,0) pantFrame.BorderColor3 = Color3.new(1,1,1) pantFrame.Name = "PantFrame" pantFrame.Parent = PantsFrame local otherPantFrame = pantFrame:clone() otherPantFrame.Position = UDim2.new(0.5,3,0.5,0) otherPantFrame.Parent = PantsFrame local CurrentPants = Instance.new("ImageButton") CurrentPants.BackgroundTransparency = 1 CurrentPants.ZIndex = 2 CurrentPants.Name = "CurrentPants" CurrentPants.Position = UDim2.new(0.5,-31,0.5,-4) CurrentPants.Size = UDim2.new(0,54,0,59) CurrentPants.Parent = PantsFrame local MeshFrame = makeCharFrame("PackagesFrame", CharacterPane) local torsoButton = makeStyledButton("TorsoMeshButton", UDim2.new(0,64,0,64),UDim2.new(0.5,-32,0.5,-110),MeshFrame,Enum.ButtonStyle.RobloxButton) makeTextLabel("TorsoLabel","Torso",UDim2.new(0.5,-16,0,-25),torsoButton) local leftLegButton = makeStyledButton("LeftLegMeshButton", UDim2.new(0,64,0,64),UDim2.new(0.5,0,0.5,-25),MeshFrame,Enum.ButtonStyle.RobloxButton) makeTextLabel("LeftLegLabel","Left Leg",UDim2.new(0.5,-16,0,-25),leftLegButton) local rightLegButton = makeStyledButton("RightLegMeshButton", UDim2.new(0,64,0,64),UDim2.new(0.5,-64,0.5,-25),MeshFrame,Enum.ButtonStyle.RobloxButton) makeTextLabel("RightLegLabel","Right Leg",UDim2.new(0.5,-16,0,-25),rightLegButton) local rightArmButton = makeStyledButton("RightArmMeshButton", UDim2.new(0,64,0,64),UDim2.new(0.5,-96,0.5,-110),MeshFrame,Enum.ButtonStyle.RobloxButton) makeTextLabel("RightArmLabel","Right Arm",UDim2.new(0.5,-16,0,-25),rightArmButton) local leftArmButton = makeStyledButton("LeftArmMeshButton", UDim2.new(0,64,0,64),UDim2.new(0.5,32,0.5,-110),MeshFrame,Enum.ButtonStyle.RobloxButton) makeTextLabel("LeftArmLabel","Left Arm",UDim2.new(0.5,-16,0,-25),leftArmButton) local TShirtFrame = makeCharFrame("T-ShirtsFrame",CharacterPane) game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=75460642") makeZone("TShirtZone","http://www.roblox.com/asset/?id=75460642",UDim2.new(0,121,0,154),UDim2.new(0.5,-60,0.5,-100),TShirtFrame) makeStyledButton("TShirtButton", UDim2.new(0,64,0,64),UDim2.new(0.5,-32,0.5,-64),TShirtFrame) local ShirtFrame = makeCharFrame("ShirtsFrame", CharacterPane) makeZone("ShirtZone","http://www.roblox.com/asset/?id=75460642",UDim2.new(0,121,0,154),UDim2.new(0.5,-60,0.5,-100),ShirtFrame) makeStyledButton("ShirtButton", UDim2.new(0,64,0,64),UDim2.new(0.5,-32,0.5,-64),ShirtFrame) local ColorFrame = makeCharFrame("ColorFrame", CharacterPane) game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=76049888") local ColorZone = makeZone("ColorZone","http://www.roblox.com/asset/?id=76049888", UDim2.new(0,120,0,150),UDim2.new(0.5,-60,0.5,-100),ColorFrame) makeStyledButton("Head",UDim2.new(0.26,0,0.19,0),UDim2.new(0.37,0,0.02,0),ColorZone).AutoButtonColor = false makeStyledButton("LeftArm",UDim2.new(0.19,0,0.36,0),UDim2.new(0.78,0,0.26,0),ColorZone).AutoButtonColor = false makeStyledButton("RightArm",UDim2.new(0.19,0,0.36,0),UDim2.new(0.025,0,0.26,0),ColorZone).AutoButtonColor = false makeStyledButton("Torso",UDim2.new(0.43,0,0.36,0),UDim2.new(0.28,0,0.26,0),ColorZone).AutoButtonColor = false makeStyledButton("RightLeg",UDim2.new(0.19,0,0.31,0),UDim2.new(0.275,0,0.67,0),ColorZone).AutoButtonColor = false makeStyledButton("LeftLeg",UDim2.new(0.19,0,0.31,0),UDim2.new(0.525,0,0.67,0),ColorZone).AutoButtonColor = false -- Character Panel label (shows what category we are currently browsing) local CategoryLabel = Instance.new("TextLabel") CategoryLabel.Name = "CategoryLabel" CategoryLabel.BackgroundTransparency = 1 CategoryLabel.Font = Enum.Font.ArialBold CategoryLabel.FontSize = Enum.FontSize.Size18 CategoryLabel.Position = UDim2.new(0,0,0,-7) CategoryLabel.Size = UDim2.new(1,0,0,20) CategoryLabel.TextXAlignment = Enum.TextXAlignment.Center CategoryLabel.Text = "All" CategoryLabel.TextColor3 = Color3.new(1,1,1) CategoryLabel.Parent = CharacterPane --Save Button local SaveButton = Instance.new("TextButton") SaveButton.Name = "SaveButton" SaveButton.Size = UDim2.new(0.6,0,0,50) SaveButton.Position = UDim2.new(0.2,0,1,-50) SaveButton.Style = Enum.ButtonStyle.RobloxButton SaveButton.Selected = false SaveButton.Font = Enum.Font.ArialBold SaveButton.FontSize = Enum.FontSize.Size18 SaveButton.Text = "Save" SaveButton.TextColor3 = Color3.new(1,1,1) SaveButton.Parent = CharacterPane false BackpackScript -- A couple of necessary functions local function waitForChild(instance, name) while not instance:FindFirstChild(name) do instance.ChildAdded:wait() end end local function waitForProperty(instance, property) while not instance[property] do instance.Changed:wait() end end --- Begin Locals waitForChild(game,"Players") waitForProperty(game.Players,"LocalPlayer") local player = game.Players.LocalPlayer local currentLoadout = script.Parent local maxNumLoadoutItems = 10 local guiBackpack = currentLoadout.Backpack local characterChildAddedCon = nil local keyPressCon = nil local backpackChildCon = nil local debounce = script.Parent.CurrentLoadout.Debounce local waitingOnEnlarge = nil local enlargeFactor = 1.18 local buttonSizeEnlarge = UDim2.new(1 * enlargeFactor,0,1 * enlargeFactor,0) local buttonSizeNormal = UDim2.new(1,0,1,0) local enlargeOverride = true local guiTweenSpeed = 0.5 local gearSlots = {} for i = 1, maxNumLoadoutItems do gearSlots[i] = "empty" end local inventory = {} --- End Locals -- Begin Functions local function kill(prop,con,gear) if con then con:disconnect() end if prop == true and gear then reorganizeLoadout(gear,false) end end function removeGear(gear) local emptySlot = nil for i = 1, #gearSlots do if gearSlots[i] == gear and gear.Parent ~= nil then emptySlot = i break end end if emptySlot then if gearSlots[emptySlot].GearReference.Value then if gearSlots[emptySlot].GearReference.Value.Parent == game.Players.LocalPlayer.Character then -- if we currently have this equipped, unequip it gearSlots[emptySlot].GearReference.Value.Parent = game.Players.LocalPlayer.Backpack end if gearSlots[emptySlot].GearReference.Value:IsA("HopperBin") and gearSlots[emptySlot].GearReference.Value.Active then -- this is an active hopperbin gearSlots[emptySlot].GearReference.Value:Disable() gearSlots[emptySlot].GearReference.Value.Active = false end end gearSlots[emptySlot] = "empty" local centerizeX = gear.Size.X.Scale/2 local centerizeY = gear.Size.Y.Scale/2 gear:TweenSizeAndPosition(UDim2.new(0,0,0,0), UDim2.new(gear.Position.X.Scale + centerizeX,gear.Position.X.Offset,gear.Position.Y.Scale + centerizeY,gear.Position.Y.Offset), Enum.EasingDirection.Out, Enum.EasingStyle.Quad,guiTweenSpeed/4,true) delay(guiTweenSpeed/2, function() gear:remove() end) end end function insertGear(gear, addToSlot) local pos = nil if not addToSlot then for i = 1, #gearSlots do if gearSlots[i] == "empty" then pos = i break end end if pos == 1 and gearSlots[1] ~= "empty" then gear:remove() return end -- we are currently full, can't add in else pos = addToSlot -- push all gear down one slot local start = 1 for i = 1, #gearSlots do if gearSlots[i] == "empty" then start = i break end end for i = start, pos + 1, -1 do gearSlots[i] = gearSlots[i - 1] if i == 10 then gearSlots[i].SlotNumber.Text = "0" gearSlots[i].SlotNumberDownShadow.Text = "0" gearSlots[i].SlotNumberUpShadow.Text = "0" else gearSlots[i].SlotNumber.Text = i gearSlots[i].SlotNumberDownShadow.Text = i gearSlots[i].SlotNumberUpShadow.Text = i end end end gearSlots[pos] = gear if pos ~= maxNumLoadoutItems then if(type(tostring(pos)) == "string") then local posString = tostring(pos) gear.SlotNumber.Text = posString gear.SlotNumberDownShadow.Text = posString gear.SlotNumberUpShadow.Text = posString end else -- tenth gear doesn't follow mathematical pattern :( gear.SlotNumber.Text = "0" gear.SlotNumberDownShadow.Text = "0" gear.SlotNumberUpShadow.Text = "0" end gear.Visible = true local con = nil con = gear.Kill.Changed:connect(function(prop) kill(prop,con,gear) end) end function reorganizeLoadout(gear, inserting, equipped, addToSlot) if inserting then -- add in gear insertGear(gear, addToSlot) else removeGear(gear) end if gear ~= "empty" then gear.ZIndex = 1 end end function checkToolAncestry(child,parent) if child:FindFirstChild("RobloxBuildTool") then return end -- don't show roblox build tools if child:IsA("Tool") or child:IsA("HopperBin") then for i = 1, #gearSlots do if gearSlots[i] ~= "empty" and gearSlots[i].GearReference.Value == child then if parent == nil then gearSlots[i].Kill.Value = true return false elseif child.Parent == player.Character then gearSlots[i].Selected = true return true elseif child.Parent == player.Backpack then if child:IsA("Tool") then gearSlots[i].Selected = false end return true else gearSlots[i].Kill.Value = true return false end return true end end end end function removeAllEquippedGear(physGear) local stuff = player.Character:GetChildren() for i = 1, #stuff do if ( stuff[i]:IsA("Tool") or stuff[i]:IsA("HopperBin") ) and stuff[i] ~= physGear then if stuff[i]:IsA("Tool") then stuff[i].Parent = player.Backpack end if stuff[i]:IsA("HopperBin") then stuff[i]:Disable() end end end end function hopperBinSwitcher(numKey, physGear) if not physGear then return end physGear:ToggleSelect() if gearSlots[numKey] == "empty" then return end if not physGear.Active then gearSlots[numKey].Selected = false normalizeButton(gearSlots[numKey]) else gearSlots[numKey].Selected = true enlargeButton(gearSlots[numKey]) end end function toolSwitcher(numKey) if not gearSlots[numKey] then return end local physGear = gearSlots[numKey].GearReference.Value if physGear == nil then return end removeAllEquippedGear(physGear) -- we don't remove this gear, as then we get a double switcheroo local key = numKey if numKey == 0 then key = 10 end for i = 1, #gearSlots do if gearSlots[i] and gearSlots[i] ~= "empty" and i ~= key then normalizeButton(gearSlots[i]) gearSlots[i].Selected = false if gearSlots[i].GearReference.Value:IsA("HopperBin") and gearSlots[i].GearReference.Value.Active then gearSlots[i].GearReference.Value:ToggleSelect() end end end if physGear:IsA("HopperBin") then hopperBinSwitcher(numKey,physGear) else if physGear.Parent == player.Character then physGear.Parent = player.Backpack gearSlots[numKey].Selected = false normalizeButton(gearSlots[numKey]) else physGear.Parent = player.Character gearSlots[numKey].Selected = true enlargeButton(gearSlots[numKey]) end end end function activateGear(num) local numKey = nil if num == "0" then numKey = 10 -- why do lua indexes have to start at 1? :( else numKey = tonumber(num) end if(numKey == nil) then return end if gearSlots[numKey] ~= "empty" then toolSwitcher(numKey) end end enlargeButton = function(button) if button.Size.Y.Scale > 1 then return end if not button.Parent then return end if not button.Selected then return end for i = 1, #gearSlots do if gearSlots[i] == "empty" then break end if gearSlots[i] ~= button then normalizeButton(gearSlots[i]) end end if not enlargeOverride then waitingOnEnlarge = button return end if button:IsA("ImageButton") or button:IsA("TextButton") then button.ZIndex = 2 local centerizeX = -(buttonSizeEnlarge.X.Scale - button.Size.X.Scale)/2 local centerizeY = -(buttonSizeEnlarge.Y.Scale - button.Size.Y.Scale)/2 button:TweenSizeAndPosition(buttonSizeEnlarge, UDim2.new(button.Position.X.Scale + centerizeX,button.Position.X.Offset,button.Position.Y.Scale + centerizeY,button.Position.Y.Offset), Enum.EasingDirection.Out, Enum.EasingStyle.Quad,guiTweenSpeed/5,enlargeOverride) end end normalizeAllButtons = function() for i = 1, #gearSlots do if gearSlots[i] == "empty" then break end if gearSlots[i] ~= button then normalizeButton(gearSlots[i],0.1) end end end normalizeButton = function(button, speed) if not button then return end if button.Size.Y.Scale <= 1 then return end if button.Selected then return end if not button.Parent then return end local moveSpeed = speed if moveSpeed == nil or type(moveSpeed) ~= "number" then moveSpeed = guiTweenSpeed/5 end if button:IsA("ImageButton") or button:IsA("TextButton") then button.ZIndex = 1 local inverseEnlarge = 1/enlargeFactor local centerizeX = -(buttonSizeNormal.X.Scale - button.Size.X.Scale)/2 local centerizeY = -(buttonSizeNormal.Y.Scale - button.Size.Y.Scale)/2 button:TweenSizeAndPosition(buttonSizeNormal, UDim2.new(button.Position.X.Scale + centerizeX,button.Position.X.Offset,button.Position.Y.Scale + centerizeY,button.Position.Y.Offset), Enum.EasingDirection.Out, Enum.EasingStyle.Quad,moveSpeed,enlargeOverride) end end waitForDebounce = function() if debounce.Value then debounce.Changed:wait() end end function pointInRectangle(point,rectTopLeft,rectSize) if point.x > rectTopLeft.x and point.x < (rectTopLeft.x + rectSize.x) then if point.y > rectTopLeft.y and point.y < (rectTopLeft.y + rectSize.y) then return true end end return false end function swapGear(gearClone,toFrame) local toFrameChildren = toFrame:GetChildren() if #toFrameChildren == 1 then if toFrameChildren[1]:FindFirstChild("SlotNumber") then local toSlot = tonumber(toFrameChildren[1].SlotNumber.Text) local gearCloneSlot = tonumber(gearClone.SlotNumber.Text) if toSlot == 0 then toSlot = 10 end if gearCloneSlot == 0 then gearCloneSlot = 10 end gearSlots[toSlot] = gearClone gearSlots[gearCloneSlot] = toFrameChildren[1] toFrameChildren[1].SlotNumber.Text = gearClone.SlotNumber.Text toFrameChildren[1].SlotNumberDownShadow.Text = gearClone.SlotNumber.Text toFrameChildren[1].SlotNumberUpShadow.Text = gearClone.SlotNumber.Text local subString = string.sub(toFrame.Name,5) gearClone.SlotNumber.Text = subString gearClone.SlotNumberDownShadow.Text = subString gearClone.SlotNumberUpShadow.Text = subString gearClone.Position = UDim2.new(gearClone.Position.X.Scale,0,gearClone.Position.Y.Scale,0) toFrameChildren[1].Position = UDim2.new(toFrameChildren[1].Position.X.Scale,0,toFrameChildren[1].Position.Y.Scale,0) toFrameChildren[1].Parent = gearClone.Parent gearClone.Parent = toFrame end else local slotNum = tonumber(gearClone.SlotNumber.Text) if slotNum == 0 then slotNum = 10 end gearSlots[slotNum] = "empty" -- reset this gear slot local subString = string.sub(toFrame.Name,5) gearClone.SlotNumber.Text = subString gearClone.SlotNumberDownShadow.Text = subString gearClone.SlotNumberUpShadow.Text = subString local toSlotNum = tonumber(gearClone.SlotNumber.Text) if toSlotNum == 0 then toSlotNum = 10 end gearSlots[toSlotNum] = gearClone gearClone.Position = UDim2.new(gearClone.Position.X.Scale,0,gearClone.Position.Y.Scale,0) gearClone.Parent = toFrame end end function resolveDrag(gearClone,x,y) local mousePoint = Vector2.new(x,y) local frame = gearClone.Parent local frames = frame.Parent:GetChildren() for i = 1, #frames do if frames[i]:IsA("Frame") then if pointInRectangle(mousePoint, frames[i].AbsolutePosition,frames[i].AbsoluteSize) then swapGear(gearClone,frames[i]) return true end end end if x < frame.AbsolutePosition.x or x > ( frame.AbsolutePosition.x + frame.AbsoluteSize.x ) then reorganizeLoadout(gearClone,false) return false elseif y < frame.AbsolutePosition.y or y > ( frame.AbsolutePosition.y + frame.AbsoluteSize.y ) then reorganizeLoadout(gearClone,false) return false else gearClone.Position = dragBeginPos return -1 end end function unequipAllItems(dontEquipThis) for i = 1, #gearSlots do if gearSlots[i] == "empty" then break end if gearSlots[i].GearReference.Value ~= dontEquipThis then if gearSlots[i].GearReference.Value:IsA("HopperBin") then gearSlots[i].GearReference.Value:Disable() elseif gearSlots[i].GearReference.Value:IsA("Tool") then gearSlots[i].GearReference.Value.Parent = game.Players.LocalPlayer.Backpack end gearSlots[i].Selected = false end end end local addingPlayerChild = function(child, equipped, addToSlot, inventoryGearButton) waitForDebounce() debounce.Value = true if child:FindFirstChild("RobloxBuildTool") then debounce.Value = false return end -- don't show roblox build tools if not child:IsA("Tool") then if not child:IsA("HopperBin") then debounce.Value = false return -- we don't care about anything besides tools (sigh...) end end if not addToSlot then for i = 1, #gearSlots do if gearSlots[i] ~= "empty" and gearSlots[i].GearReference.Value == child then -- we already have gear, do nothing debounce.Value = false return end end end local gearClone = currentLoadout.CurrentLoadout.TempSlot:clone() gearClone.Name = child.Name gearClone.GearImage.Image = child.TextureId if gearClone.GearImage.Image == "" then gearClone.GearText.Text = child.Name end gearClone.GearReference.Value = child local slotToMod = -1 if not addToSlot then for i = 1, #gearSlots do if gearSlots[i] == "empty" then slotToMod = i break end end else slotToMod = addToSlot end if slotToMod == - 1 then debounce.Value = false print("no slots!") return end -- No available slot to add in! local slotNum = slotToMod % 10 local parent = currentLoadout.CurrentLoadout:FindFirstChild("Slot"..tostring(slotNum)) gearClone.Parent = parent if inventoryGearButton then local absolutePositionFinal = inventoryGearButton.AbsolutePosition local currentAbsolutePosition = gearClone.AbsolutePosition local diff = absolutePositionFinal - currentAbsolutePosition gearClone.Position = UDim2.new(gearClone.Position.X.Scale,diff.x,gearClone.Position.Y.Scale,diff.y) gearClone.ZIndex = 4 end if addToSlot then reorganizeLoadout(gearClone, true, equipped, addToSlot) else reorganizeLoadout(gearClone, true) end if gearClone.Parent == nil then debounce.Value = false return end -- couldn't fit in (hopper is full!) if equipped then gearClone.Selected = true unequipAllItems(child) delay(guiTweenSpeed + 0.01,function() -- if our gear is equipped, we will want to enlarge it when done moving if (gearClone.GearReference.Value:IsA("Tool") and gearClone.GearReference.Value.Parent == player.Character) or (gearClone.GearReference.Value:IsA("HopperBin") and gearClone.GearReference.Value.Active == true) then enlargeButton(gearClone) end end) end local dragBeginPos = nil local clickCon, buttonDeleteCon, mouseEnterCon, mouseLeaveCon, dragStop, dragBegin = nil clickCon = gearClone.MouseButton1Click:connect(function() if not gearClone.Draggable then activateGear(gearClone.SlotNumber.Text) end end) mouseEnterCon = gearClone.MouseEnter:connect(function() if guiBackpack.Visible then gearClone.Draggable = true end end) dragBegin = gearClone.DragBegin:connect(function(pos) dragBeginPos = pos gearClone.ZIndex = 7 local children = gearClone:GetChildren() for i = 1, #children do if children[i]:IsA("TextLabel") then if string.find(children[i].Name,"Shadow") then children[i].ZIndex = 8 else children[i].ZIndex = 9 end elseif children[i]:IsA("Frame") or children[i]:IsA("ImageLabel") then children[i].ZIndex = 7 end end end) dragStop = gearClone.DragStopped:connect(function(x,y) if gearClone.Selected then gearClone.ZIndex = 2 else gearClone.ZIndex = 1 end local children = gearClone:GetChildren() for i = 1, #children do if children[i]:IsA("TextLabel") then if string.find(children[i].Name,"Shadow") then children[i].ZIndex = 3 else children[i].ZIndex = 4 end elseif children[i]:IsA("Frame") or children[i]:IsA("ImageLabel") then children[i].ZIndex = 2 end end resolveDrag(gearClone,x,y) end) mouseLeaveCon = gearClone.MouseLeave:connect(function() gearClone.Draggable = false end) buttonDeleteCon = gearClone.AncestryChanged:connect(function() if gearClone.Parent and gearClone.Parent.Parent == currentLoadout then return end if clickCon then clickCon:disconnect() end if buttonDeleteCon then buttonDeleteCon:disconnect() end if mouseEnterCon then mouseEnterCon:disconnect() end if mouseLeaveCon then mouseLeaveCon:disconnect() end if dragStop then dragStop:disconnect() end if dragBegin then dragBegin:disconnect() end end) -- this probably isn't necessary since objects are being deleted (probably), but this might still leak just in case local childCon = nil local childChangeCon = nil childCon = child.AncestryChanged:connect(function(newChild,parent) if not checkToolAncestry(newChild,parent) then if childCon then childCon:disconnect() end if childChangeCon then childChangeCon:disconnect() end removeFromInventory(child) elseif parent == game.Players.LocalPlayer.Backpack then normalizeButton(gearClone) end end) childChangeCon = child.Changed:connect(function(prop) if prop == "Name" then if gearClone and gearClone.GearImage.Image == "" then gearClone.GearText.Text = child.Name end end end) debounce.Value = false end function addToInventory(child) if not child:IsA("Tool") or not child:IsA("HopperBin") then return end local slot = nil for i = 1, #inventory do if inventory[i] and inventory[i] == child then return end if not inventory[i] then slot = i end end if slot then inventory[slot] = child elseif #inventory < 1 then inventory[1] = child else inventory[#inventory + 1] = child end end function removeFromInventory(child) for i = 1, #inventory do if inventory[i] == child then table.remove(inventory,i) inventory[i] = nil end end end -- these next two functions are used for safe guarding -- when we are waiting for character to come back after dying function activateLoadout() keyPressCon = game:GetService("GuiService").KeyPressed:connect(function(key) activateGear(key) end) currentLoadout.Visible = true end function deactivateLoadout() if keyPressCon then keyPressCon:disconnect() end currentLoadout.CurrentLoadout.Visible = false end function setupBackpackListener() if backpackChildCon then backpackChildCon:disconnect() end backpackChildCon = player.Backpack.ChildAdded:connect(function(child) addingPlayerChild(child) addToInventory(child) end) end function playerCharacterChildAdded(child) addingPlayerChild(child,true) addToInventory(child) end -- End Functions -- Begin Script wait() -- let stuff initialize incase this is first heartbeat... waitForChild(player,"Backpack") local backpackChildren = player.Backpack:GetChildren() local size = math.min(10,#backpackChildren) for i = 1, size do addingPlayerChild(backpackChildren[i],false) end setupBackpackListener() waitForProperty(player,"Character") for i,v in ipairs(player.Character:GetChildren()) do playerCharacterChildAdded(v) end characterChildAddedCon = player.Character.ChildAdded:connect(function(child) playerCharacterChildAdded(child) end) waitForChild(player.Character,"Humanoid") humanoidDiedCon = player.Character.Humanoid.Died:connect(function() deactivateLoadout() end) player.CharacterRemoving:connect(function() if characterChildAddedCon then characterChildAddedCon:disconnect() end if humanoidDiedCon then humanoidDiedCon:disconnect() end if backpackChildCon then backpackChildCon:disconnect() end deactivateLoadout() end) player.CharacterAdded:connect(function() player = game.Players.LocalPlayer -- make sure we are still looking at the correct character for i = 1, #gearSlots do if gearSlots[i] ~= "empty" then gearSlots[i].Parent = nil gearSlots[i] = "empty" end end local backpackChildren = player.Backpack:GetChildren() local size = math.min(10,#backpackChildren) for i = 1, size do addingPlayerChild(backpackChildren[i]) end setupBackpackListener() characterChildAddedCon = player.Character.ChildAdded:connect(function(child) addingPlayerChild(child,true) end) waitForChild(player.Character,"Humanoid") humanoidDiedCon = player.Character.Humanoid.Died:connect(function() deactivateLoadout() end) activateLoadout() end) waitForChild(guiBackpack,"SwapSlot") guiBackpack.SwapSlot.Changed:connect(function() if guiBackpack.SwapSlot.Value then local swapSlot = guiBackpack.SwapSlot local pos = swapSlot.Slot.Value if pos == 0 then pos = 10 end if gearSlots[pos] then reorganizeLoadout(gearSlots[pos],false) end if swapSlot.GearButton.Value then addingPlayerChild(swapSlot.GearButton.Value.GearReference.Value,false,pos) end guiBackpack.SwapSlot.Value = false end end) false 4288914085 1 4279970357 1 false false ControlFrame 0 0 0 0 1 0 1 0 0 0 true 1 false 4288914085 1 4279970357 1 false false NotificationBox 1 -200 0.5 0 0 200 0.419999987 0 0 true 1 Menu false MenuScript -- fixed by iago#6808 -- -- version 0.25 -- -- changelog: -- -- 100% finished settings menu -- -- report abuse is still in work -- local t = {} local function ScopedConnect(parentInstance, instance, event, signalFunc, syncFunc, removeFunc) local eventConnection = nil --Connection on parentInstance is scoped by parentInstance (when destroyed, it goes away) local tryConnect = function() if game:IsAncestorOf(parentInstance) then --Entering the world, make sure we are connected/synced if not eventConnection then eventConnection = instance[event]:connect(signalFunc) if syncFunc then syncFunc() end end else --Probably leaving the world, so disconnect for now if eventConnection then eventConnection:disconnect() if removeFunc then removeFunc() end end end end --Hook it up to ancestryChanged signal local connection = parentInstance.AncestryChanged:connect(tryConnect) --Now connect us if we're already in the world tryConnect() return connection end local function getScreenGuiAncestor(instance) local localInstance = instance while localInstance and not localInstance:IsA("ScreenGui") do localInstance = localInstance.Parent end return localInstance end local function CreateButtons(frame, buttons, yPos, ySize) local buttonNum = 1 local buttonObjs = {} for i, obj in ipairs(buttons) do local button = Instance.new("TextButton") button.Name = "Button" .. buttonNum button.Font = Enum.Font.Arial button.FontSize = Enum.FontSize.Size18 button.AutoButtonColor = true button.Modal = true if obj["Style"] then button.Style = obj.Style else button.Style = Enum.ButtonStyle.RobloxButton end if obj["ZIndex"] then button.ZIndex = obj.ZIndex end button.Text = obj.Text button.TextColor3 = Color3.new(1,1,1) button.MouseButton1Click:connect(obj.Function) button.Parent = frame buttonObjs[buttonNum] = button buttonNum = buttonNum + 1 end local numButtons = buttonNum-1 if numButtons == 1 then frame.Button1.Position = UDim2.new(0.35, 0, yPos.Scale, yPos.Offset) frame.Button1.Size = UDim2.new(.4,0,ySize.Scale, ySize.Offset) elseif numButtons == 2 then frame.Button1.Position = UDim2.new(0.1, 0, yPos.Scale, yPos.Offset) frame.Button1.Size = UDim2.new(.8/3,0, ySize.Scale, ySize.Offset) frame.Button2.Position = UDim2.new(0.55, 0, yPos.Scale, yPos.Offset) frame.Button2.Size = UDim2.new(.35,0, ySize.Scale, ySize.Offset) elseif numButtons >= 3 then local spacing = .1 / numButtons local buttonSize = .9 / numButtons buttonNum = 1 while buttonNum <= numButtons do buttonObjs[buttonNum].Position = UDim2.new(spacing*buttonNum + (buttonNum-1) * buttonSize, 0, yPos.Scale, yPos.Offset) buttonObjs[buttonNum].Size = UDim2.new(buttonSize, 0, ySize.Scale, ySize.Offset) buttonNum = buttonNum + 1 end end end local function setSliderPos(newAbsPosX,slider,sliderPosition,bar,steps) local steps = 10 local newStep = steps - 1 --otherwise we really get one more step than we want local relativePosX = math.min(1, math.max(0, (newAbsPosX - bar.AbsolutePosition.X) / bar.AbsoluteSize.X )) local wholeNum, remainder = math.modf(relativePosX * newStep) if remainder > 0.5 then wholeNum = wholeNum + 1 end relativePosX = wholeNum/newStep local result = math.ceil(relativePosX * newStep) if sliderPosition.Value ~= (result + 1) then --only update if we moved a step sliderPosition.Value = result + 1 slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset) end end local function cancelSlide(areaSoak) areaSoak.Visible = false if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end end t.CreateStyledMessageDialog = function(title, message, style, buttons) local frame = Instance.new("Frame") frame.Size = UDim2.new(0.5, 0, 0, 165) frame.Position = UDim2.new(0.25, 0, 0.5, -72.5) frame.Name = "MessageDialog" frame.Active = true frame.Style = Enum.FrameStyle.RobloxRound local styleImage = Instance.new("ImageLabel") styleImage.Name = "StyleImage" styleImage.BackgroundTransparency = 1 styleImage.Position = UDim2.new(0,5,0,15) if style == "error" or style == "Error" then styleImage.Size = UDim2.new(0, 71, 0, 71) styleImage.Image = "http://www.roblox.com/asset/?id=42565285" elseif style == "notify" or style == "Notify" then styleImage.Size = UDim2.new(0, 71, 0, 71) styleImage.Image = "http://www.roblox.com/asset/?id=42604978" elseif style == "confirm" or style == "Confirm" then styleImage.Size = UDim2.new(0, 74, 0, 76) styleImage.Image = "http://www.roblox.com/asset/?id=42557901" else return t.CreateMessageDialog(title,message,buttons) end styleImage.Parent = frame local titleLabel = Instance.new("TextLabel") titleLabel.Name = "Title" titleLabel.Text = title titleLabel.TextStrokeTransparency = 0 titleLabel.BackgroundTransparency = 1 titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255) titleLabel.Position = UDim2.new(0, 80, 0, 0) titleLabel.Size = UDim2.new(1, -80, 0, 40) titleLabel.Font = Enum.Font.ArialBold titleLabel.FontSize = Enum.FontSize.Size36 titleLabel.TextXAlignment = Enum.TextXAlignment.Center titleLabel.TextYAlignment = Enum.TextYAlignment.Center titleLabel.Parent = frame local messageLabel = Instance.new("TextLabel") messageLabel.Name = "Message" messageLabel.Text = message messageLabel.TextStrokeTransparency = 0 messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255) messageLabel.Position = UDim2.new(0.025, 80, 0, 45) messageLabel.Size = UDim2.new(0.95, -80, 0, 55) messageLabel.BackgroundTransparency = 1 messageLabel.Font = Enum.Font.Arial messageLabel.FontSize = Enum.FontSize.Size18 messageLabel.TextWrap = true messageLabel.TextXAlignment = Enum.TextXAlignment.Left messageLabel.TextYAlignment = Enum.TextYAlignment.Top messageLabel.Parent = frame CreateButtons(frame, buttons, UDim.new(0, 105), UDim.new(0, 40) ) return frame end t.CreateMessageDialog = function(title, message, buttons) local frame = Instance.new("Frame") frame.Size = UDim2.new(0.5, 0, 0.5, 0) frame.Position = UDim2.new(0.25, 0, 0.25, 0) frame.Name = "MessageDialog" frame.Active = true frame.Style = Enum.FrameStyle.RobloxRound local titleLabel = Instance.new("TextLabel") titleLabel.Name = "Title" titleLabel.Text = title titleLabel.BackgroundTransparency = 1 titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255) titleLabel.Position = UDim2.new(0, 0, 0, 0) titleLabel.Size = UDim2.new(1, 0, 0.15, 0) titleLabel.Font = Enum.Font.ArialBold titleLabel.FontSize = Enum.FontSize.Size36 titleLabel.TextXAlignment = Enum.TextXAlignment.Center titleLabel.TextYAlignment = Enum.TextYAlignment.Center titleLabel.Parent = frame local messageLabel = Instance.new("TextLabel") messageLabel.Name = "Message" messageLabel.Text = message messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255) messageLabel.Position = UDim2.new(0.025, 0, 0.175, 0) messageLabel.Size = UDim2.new(0.95, 0, .55, 0) messageLabel.BackgroundTransparency = 1 messageLabel.Font = Enum.Font.Arial messageLabel.FontSize = Enum.FontSize.Size18 messageLabel.TextWrap = true messageLabel.TextXAlignment = Enum.TextXAlignment.Left messageLabel.TextYAlignment = Enum.TextYAlignment.Top messageLabel.Parent = frame CreateButtons(frame, buttons, UDim.new(0.8,0), UDim.new(0.15, 0)) return frame end t.CreateDropDownMenu = function(items, onSelect, forRoblox, whiteSkin, baseZ) local baseZIndex = 0 if (type(baseZ) == "number") then baseZIndex = baseZ end local width = UDim.new(0, 100) local height = UDim.new(0, 32) local xPos = 0.055 local frame = Instance.new("Frame") local textColor = Color3.new(1,1,1) if (whiteSkin) then textColor = Color3.new(0.5, 0.5, 0.5) end frame.Name = "DropDownMenu" frame.BackgroundTransparency = 1 frame.Size = UDim2.new(width, height) local dropDownMenu = Instance.new("TextButton") dropDownMenu.Name = "DropDownMenuButton" dropDownMenu.TextWrap = true dropDownMenu.TextColor3 = textColor dropDownMenu.Text = "Choose One" dropDownMenu.Font = Enum.Font.ArialBold dropDownMenu.FontSize = Enum.FontSize.Size18 dropDownMenu.TextXAlignment = Enum.TextXAlignment.Left dropDownMenu.TextYAlignment = Enum.TextYAlignment.Center dropDownMenu.BackgroundTransparency = 1 dropDownMenu.AutoButtonColor = true if (whiteSkin) then dropDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton else dropDownMenu.Style = Enum.ButtonStyle.RobloxButton end dropDownMenu.Size = UDim2.new(1,0,1,0) dropDownMenu.Parent = frame dropDownMenu.ZIndex = 2 + baseZIndex local dropDownIcon = Instance.new("ImageLabel") dropDownIcon.Name = "Icon" dropDownIcon.Active = false if (whiteSkin) then dropDownIcon.Image = "rbxasset://textures/ui/dropdown_arrow.png" dropDownIcon.Size = UDim2.new(0,16,0,12) dropDownIcon.Position = UDim2.new(1,-17,0.5, -6) else dropDownIcon.Image = "http://www.roblox.com/asset/?id=45732894" dropDownIcon.Size = UDim2.new(0,11,0,6) dropDownIcon.Position = UDim2.new(1,-11,0.5, -2) end dropDownIcon.BackgroundTransparency = 1 dropDownIcon.Parent = dropDownMenu dropDownIcon.ZIndex = 2 + baseZIndex local itemCount = #items local dropDownItemCount = #items local useScrollButtons = false if dropDownItemCount > 6 then useScrollButtons = true dropDownItemCount = 6 end local droppedDownMenu = Instance.new("TextButton") droppedDownMenu.Name = "List" droppedDownMenu.Text = "" droppedDownMenu.BackgroundTransparency = 1 --droppedDownMenu.AutoButtonColor = true if (whiteSkin) then droppedDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton else droppedDownMenu.Style = Enum.ButtonStyle.RobloxButton end droppedDownMenu.Visible = false droppedDownMenu.Active = true --Blocks clicks droppedDownMenu.Position = UDim2.new(0,0,0,0) droppedDownMenu.Size = UDim2.new(1,0, (1 + dropDownItemCount)*.8, 0) droppedDownMenu.Parent = frame droppedDownMenu.ZIndex = 2 + baseZIndex local choiceButton = Instance.new("TextButton") choiceButton.Name = "ChoiceButton" choiceButton.BackgroundTransparency = 1 choiceButton.BorderSizePixel = 0 choiceButton.Text = "ReplaceMe" choiceButton.TextColor3 = textColor choiceButton.TextXAlignment = Enum.TextXAlignment.Left choiceButton.TextYAlignment = Enum.TextYAlignment.Center choiceButton.BackgroundColor3 = Color3.new(1, 1, 1) choiceButton.Font = Enum.Font.Arial choiceButton.FontSize = Enum.FontSize.Size18 if useScrollButtons then choiceButton.Size = UDim2.new(1,-13, .8/((dropDownItemCount + 1)*.8),0) else choiceButton.Size = UDim2.new(1, 0, .8/((dropDownItemCount + 1)*.8),0) end choiceButton.TextWrap = true choiceButton.ZIndex = 2 + baseZIndex local areaSoak = Instance.new("TextButton") areaSoak.Name = "AreaSoak" areaSoak.Text = "" areaSoak.BackgroundTransparency = 1 areaSoak.Active = true areaSoak.Size = UDim2.new(1,0,1,0) areaSoak.Visible = false areaSoak.ZIndex = 3 + baseZIndex local dropDownSelected = false local scrollUpButton local scrollDownButton local scrollMouseCount = 0 local setZIndex = function(baseZIndex) droppedDownMenu.ZIndex = baseZIndex +1 if scrollUpButton then scrollUpButton.ZIndex = baseZIndex + 3 end if scrollDownButton then scrollDownButton.ZIndex = baseZIndex + 3 end local children = droppedDownMenu:GetChildren() if children then for i, child in ipairs(children) do if child.Name == "ChoiceButton" then child.ZIndex = baseZIndex + 2 elseif child.Name == "ClickCaptureButton" then child.ZIndex = baseZIndex end end end end local scrollBarPosition = 1 local updateScroll = function() if scrollUpButton then scrollUpButton.Active = scrollBarPosition > 1 end if scrollDownButton then scrollDownButton.Active = scrollBarPosition + dropDownItemCount <= itemCount end local children = droppedDownMenu:GetChildren() if not children then return end local childNum = 1 for i, obj in ipairs(children) do if obj.Name == "ChoiceButton" then if childNum < scrollBarPosition or childNum >= scrollBarPosition + dropDownItemCount then obj.Visible = false else obj.Position = UDim2.new(0,0,((childNum-scrollBarPosition+1)*.8)/((dropDownItemCount+1)*.8),0) obj.Visible = true end obj.TextColor3 = textColor obj.BackgroundTransparency = 1 childNum = childNum + 1 end end end local toggleVisibility = function() dropDownSelected = not dropDownSelected areaSoak.Visible = not areaSoak.Visible dropDownMenu.Visible = not dropDownSelected droppedDownMenu.Visible = dropDownSelected if dropDownSelected then setZIndex(4 + baseZIndex) else setZIndex(2 + baseZIndex) end if useScrollButtons then updateScroll() end end droppedDownMenu.MouseButton1Click:connect(toggleVisibility) local updateSelection = function(text) local foundItem = false local children = droppedDownMenu:GetChildren() local childNum = 1 if children then for i, obj in ipairs(children) do if obj.Name == "ChoiceButton" then if obj.Text == text then obj.Font = Enum.Font.ArialBold foundItem = true scrollBarPosition = childNum if (whiteSkin) then obj.TextColor3 = Color3.new(90/255,142/255,233/255) end else obj.Font = Enum.Font.Arial if (whiteSkin) then obj.TextColor3 = textColor end end childNum = childNum + 1 end end end if not text then dropDownMenu.Text = "Choose One" scrollBarPosition = 1 else if not foundItem then error("Invalid Selection Update -- " .. text) end if scrollBarPosition + dropDownItemCount > itemCount + 1 then scrollBarPosition = itemCount - dropDownItemCount + 1 end dropDownMenu.Text = text end end local function scrollDown() if scrollBarPosition + dropDownItemCount <= itemCount then scrollBarPosition = scrollBarPosition + 1 updateScroll() return true end return false end local function scrollUp() if scrollBarPosition > 1 then scrollBarPosition = scrollBarPosition - 1 updateScroll() return true end return false end if useScrollButtons then --Make some scroll buttons scrollUpButton = Instance.new("ImageButton") scrollUpButton.Name = "ScrollUpButton" scrollUpButton.BackgroundTransparency = 1 scrollUpButton.Image = "rbxasset://textures/ui/scrollbuttonUp.png" scrollUpButton.Size = UDim2.new(0,17,0,17) scrollUpButton.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),0) scrollUpButton.MouseButton1Click:connect( function() scrollMouseCount = scrollMouseCount + 1 end) scrollUpButton.MouseLeave:connect( function() scrollMouseCount = scrollMouseCount + 1 end) scrollUpButton.MouseButton1Down:connect( function() scrollMouseCount = scrollMouseCount + 1 scrollUp() local val = scrollMouseCount wait(0.5) while val == scrollMouseCount do if scrollUp() == false then break end wait(0.1) end end) scrollUpButton.Parent = droppedDownMenu scrollDownButton = Instance.new("ImageButton") scrollDownButton.Name = "ScrollDownButton" scrollDownButton.BackgroundTransparency = 1 scrollDownButton.Image = "rbxasset://textures/ui/scrollbuttonDown.png" scrollDownButton.Size = UDim2.new(0,17,0,17) scrollDownButton.Position = UDim2.new(1,-11,1,-11) scrollDownButton.Parent = droppedDownMenu scrollDownButton.MouseButton1Click:connect( function() scrollMouseCount = scrollMouseCount + 1 end) scrollDownButton.MouseLeave:connect( function() scrollMouseCount = scrollMouseCount + 1 end) scrollDownButton.MouseButton1Down:connect( function() scrollMouseCount = scrollMouseCount + 1 scrollDown() local val = scrollMouseCount wait(0.5) while val == scrollMouseCount do if scrollDown() == false then break end wait(0.1) end end) local scrollbar = Instance.new("ImageLabel") scrollbar.Name = "ScrollBar" scrollbar.Image = "rbxasset://textures/ui/scrollbar.png" scrollbar.BackgroundTransparency = 1 scrollbar.Size = UDim2.new(0, 18, (dropDownItemCount*.8)/((dropDownItemCount+1)*.8), -(17) - 11 - 4) scrollbar.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),17+2) scrollbar.Parent = droppedDownMenu end for i,item in ipairs(items) do -- needed to maintain local scope for items in event listeners below local button = choiceButton:clone() if forRoblox then end button.Text = item button.Parent = droppedDownMenu if (whiteSkin) then button.TextColor3 = textColor end button.MouseButton1Click:connect(function() --Remove Highlight if (not whiteSkin) then button.TextColor3 = Color3.new(1,1,1) end button.BackgroundTransparency = 1 updateSelection(item) onSelect(item) toggleVisibility() end) button.MouseEnter:connect(function() --Add Highlight if (not whiteSkin) then button.TextColor3 = Color3.new(0,0,0) end button.BackgroundTransparency = 0 end) button.MouseLeave:connect(function() --Remove Highlight if (not whiteSkin) then button.TextColor3 = Color3.new(1,1,1) end button.BackgroundTransparency = 1 end) end --This does the initial layout of the buttons updateScroll() frame.AncestryChanged:connect(function(child,parent) if parent == nil then areaSoak.Parent = nil else areaSoak.Parent = getScreenGuiAncestor(frame) end end) dropDownMenu.MouseButton1Click:connect(toggleVisibility) areaSoak.MouseButton1Click:connect(toggleVisibility) return frame, updateSelection end t.CreatePropertyDropDownMenu = function(instance, property, enum) local items = enum:GetEnumItems() local names = {} local nameToItem = {} for i,obj in ipairs(items) do names[i] = obj.Name nameToItem[obj.Name] = obj end local frame local updateSelection frame, updateSelection = t.CreateDropDownMenu(names, function(text) instance[property] = nameToItem[text] end) ScopedConnect(frame, instance, "Changed", function(prop) if prop == property then updateSelection(instance[property].Name) end end, function() updateSelection(instance[property].Name) end) return frame end t.GetFontHeight = function(font, fontSize) if font == nil or fontSize == nil then error("Font and FontSize must be non-nil") end if font == Enum.Font.Legacy then if fontSize == Enum.FontSize.Size8 then return 12 elseif fontSize == Enum.FontSize.Size9 then return 14 elseif fontSize == Enum.FontSize.Size10 then return 15 elseif fontSize == Enum.FontSize.Size11 then return 17 elseif fontSize == Enum.FontSize.Size12 then return 18 elseif fontSize == Enum.FontSize.Size14 then return 21 elseif fontSize == Enum.FontSize.Size18 then return 27 elseif fontSize == Enum.FontSize.Size24 then return 36 elseif fontSize == Enum.FontSize.Size36 then return 54 elseif fontSize == Enum.FontSize.Size48 then return 72 else error("Unknown FontSize") end elseif font == Enum.Font.Arial or font == Enum.Font.ArialBold then if fontSize == Enum.FontSize.Size8 then return 8 elseif fontSize == Enum.FontSize.Size9 then return 9 elseif fontSize == Enum.FontSize.Size10 then return 10 elseif fontSize == Enum.FontSize.Size11 then return 11 elseif fontSize == Enum.FontSize.Size12 then return 12 elseif fontSize == Enum.FontSize.Size14 then return 14 elseif fontSize == Enum.FontSize.Size18 then return 18 elseif fontSize == Enum.FontSize.Size24 then return 24 elseif fontSize == Enum.FontSize.Size36 then return 36 elseif fontSize == Enum.FontSize.Size48 then return 48 else error("Unknown FontSize") end else error("Unknown Font " .. font) end end local function layoutGuiObjectsHelper(frame, guiObjects, settingsTable) local totalPixels = frame.AbsoluteSize.Y local pixelsRemaining = frame.AbsoluteSize.Y for i, child in ipairs(guiObjects) do if child:IsA("TextLabel") or child:IsA("TextButton") then local isLabel = child:IsA("TextLabel") if isLabel then pixelsRemaining = pixelsRemaining - settingsTable["TextLabelPositionPadY"] else pixelsRemaining = pixelsRemaining - settingsTable["TextButtonPositionPadY"] end child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining) child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, pixelsRemaining) if child.TextFits and child.TextBounds.Y < pixelsRemaining then child.Visible = true if isLabel then child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable["TextLabelSizePadY"]) else child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable["TextButtonSizePadY"]) end while not child.TextFits do child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.AbsoluteSize.Y + 1) end pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y if isLabel then pixelsRemaining = pixelsRemaining - settingsTable["TextLabelPositionPadY"] else pixelsRemaining = pixelsRemaining - settingsTable["TextButtonPositionPadY"] end else child.Visible = false pixelsRemaining = -1 end else --GuiObject child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining) pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y child.Visible = (pixelsRemaining >= 0) end end end t.LayoutGuiObjects = function(frame, guiObjects, settingsTable) if not frame:IsA("GuiObject") then error("Frame must be a GuiObject") end for i, child in ipairs(guiObjects) do if not child:IsA("GuiObject") then error("All elements that are layed out must be of type GuiObject") end end if not settingsTable then settingsTable = {} end if not settingsTable["TextLabelSizePadY"] then settingsTable["TextLabelSizePadY"] = 0 end if not settingsTable["TextLabelPositionPadY"] then settingsTable["TextLabelPositionPadY"] = 0 end if not settingsTable["TextButtonSizePadY"] then settingsTable["TextButtonSizePadY"] = 12 end if not settingsTable["TextButtonPositionPadY"] then settingsTable["TextButtonPositionPadY"] = 2 end --Wrapper frame takes care of styled objects local wrapperFrame = Instance.new("Frame") wrapperFrame.Name = "WrapperFrame" wrapperFrame.BackgroundTransparency = 1 wrapperFrame.Size = UDim2.new(1,0,1,0) wrapperFrame.Parent = frame for i, child in ipairs(guiObjects) do child.Parent = wrapperFrame end local recalculate = function() wait() layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable) end frame.Changed:connect( function(prop) if prop == "AbsoluteSize" then --Wait a heartbeat for it to sync in recalculate(nil) end end) frame.AncestryChanged:connect(recalculate) layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable) end t.CreateSlider = function(steps,width,position) local sliderGui = Instance.new("Frame") sliderGui.Size = UDim2.new(1,0,1,0) sliderGui.BackgroundTransparency = 1 sliderGui.Name = "SliderGui" local sliderSteps = Instance.new("IntValue") sliderSteps.Name = "SliderSteps" sliderSteps.Value = steps sliderSteps.Parent = sliderGui local areaSoak = Instance.new("TextButton") areaSoak.Name = "AreaSoak" areaSoak.Text = "" areaSoak.BackgroundTransparency = 1 areaSoak.Active = false areaSoak.Size = UDim2.new(1,0,1,0) areaSoak.Visible = false areaSoak.ZIndex = 4 sliderGui.AncestryChanged:connect(function(child,parent) if parent == nil then areaSoak.Parent = nil else areaSoak.Parent = getScreenGuiAncestor(sliderGui) end end) local sliderPosition = Instance.new("IntValue") sliderPosition.Name = "SliderPosition" sliderPosition.Value = 0 sliderPosition.Parent = sliderGui local id = math.random(1,100) local bar = Instance.new("TextButton") bar.Text = "" bar.AutoButtonColor = false bar.Name = "Bar" bar.BackgroundColor3 = Color3.new(0,0,0) if type(width) == "number" then bar.Size = UDim2.new(0,width,0,5) else bar.Size = UDim2.new(0,200,0,5) end bar.BorderColor3 = Color3.new(95/255,95/255,95/255) bar.ZIndex = 2 bar.Parent = sliderGui if position["X"] and position["X"]["Scale"] and position["X"]["Offset"] and position["Y"] and position["Y"]["Scale"] and position["Y"]["Offset"] then bar.Position = position end local slider = Instance.new("ImageButton") slider.Name = "Slider" slider.BackgroundTransparency = 1 slider.Image = "rbxasset://textures/ui/Slider.png" slider.Position = UDim2.new(0,0,0.5,-10) slider.Size = UDim2.new(0,20,0,20) slider.ZIndex = 3 slider.Parent = bar local areaSoakMouseMoveCon = nil areaSoak.MouseLeave:connect(function() if areaSoak.Visible then cancelSlide(areaSoak) end end) areaSoak.MouseButton1Up:connect(function() if areaSoak.Visible then cancelSlide(areaSoak) end end) slider.MouseButton1Down:connect(function() areaSoak.Visible = true if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y) setSliderPos(x,slider,sliderPosition,bar,10) end) end) slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end) sliderPosition.Changed:connect(function(prop) sliderPosition.Value = math.min(10, math.max(1,sliderPosition.Value)) local relativePosX = (sliderPosition.Value - 1) / (10 - 1) slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset) end) bar.MouseButton1Down:connect(function(x,y) setSliderPos(x,slider,sliderPosition,bar,steps) end) return sliderGui, sliderPosition, sliderSteps end t.CreateSliderNew = function(steps,width,position) local sliderGui = Instance.new("Frame") sliderGui.Size = UDim2.new(1,0,1,0) sliderGui.BackgroundTransparency = 1 sliderGui.Name = "SliderGui" local sliderSteps = Instance.new("IntValue") sliderSteps.Name = "SliderSteps" sliderSteps.Value = steps sliderSteps.Parent = sliderGui local areaSoak = Instance.new("TextButton") areaSoak.Name = "AreaSoak" areaSoak.Text = "" areaSoak.BackgroundTransparency = 1 areaSoak.Active = false areaSoak.Size = UDim2.new(1,0,1,0) areaSoak.Visible = false areaSoak.ZIndex = 6 sliderGui.AncestryChanged:connect(function(child,parent) if parent == nil then areaSoak.Parent = nil else areaSoak.Parent = getScreenGuiAncestor(sliderGui) end end) local sliderPosition = Instance.new("IntValue") sliderPosition.Name = "SliderPosition" sliderPosition.Value = 0 sliderPosition.Parent = sliderGui local id = math.random(1,100) local sliderBarImgHeight = 7 local sliderBarCapImgWidth = 4 local bar = Instance.new("ImageButton") bar.BackgroundTransparency = 1 bar.Image = "rbxasset://textures/ui/Slider-BKG-Center.png" bar.Name = "Bar" local displayWidth = 200 if type(width) == "number" then bar.Size = UDim2.new(0,width - (sliderBarCapImgWidth * 2),0,sliderBarImgHeight) displayWidth = width - (sliderBarCapImgWidth * 2) else bar.Size = UDim2.new(0,200,0,sliderBarImgHeight) end bar.ZIndex = 3 bar.Parent = sliderGui if position["X"] and position["X"]["Scale"] and position["X"]["Offset"] and position["Y"] and position["Y"]["Scale"] and position["Y"]["Offset"] then bar.Position = position end local barLeft = bar:clone() barLeft.Name = "BarLeft" barLeft.Image = "rbxasset://textures/ui/Slider-BKG-Left-Cap.png" barLeft.Size = UDim2.new(0, sliderBarCapImgWidth, 0, sliderBarImgHeight) barLeft.Position = UDim2.new(position.X.Scale, position.X.Offset - sliderBarCapImgWidth, position.Y.Scale, position.Y.Offset) barLeft.Parent = sliderGui barLeft.ZIndex = 3 local barRight = barLeft:clone() barRight.Name = "BarRight" barRight.Image = "rbxasset://textures/ui/Slider-BKG-Right-Cap.png" barRight.Position = UDim2.new(position.X.Scale, position.X.Offset + displayWidth, position.Y.Scale, position.Y.Offset) barRight.Parent = sliderGui local fillLeft = barLeft:clone() fillLeft.Name = "FillLeft" fillLeft.Image = "rbxasset://textures/ui/Slider-Fill-Left-Cap.png" fillLeft.Parent = sliderGui fillLeft.ZIndex = 4 local fill = fillLeft:clone() fill.Name = "Fill" fill.Image = "rbxasset://textures/ui/Slider-Fill-Center.png" fill.Parent = bar fill.ZIndex = 4 fill.Position = UDim2.new(0, 0, 0, 0) fill.Size = UDim2.new(0.5, 0, 1, 0) -- bar.Visible = false local slider = Instance.new("ImageButton") slider.Name = "Slider" slider.BackgroundTransparency = 1 slider.Image = "rbxasset://textures/ui/slider_new_tab.png" slider.Position = UDim2.new(0,0,0.5,-14) slider.Size = UDim2.new(0,28,0,28) slider.ZIndex = 5 slider.Parent = bar local areaSoakMouseMoveCon = nil areaSoak.MouseLeave:connect(function() if areaSoak.Visible then cancelSlide(areaSoak) end end) areaSoak.MouseButton1Up:connect(function() if areaSoak.Visible then cancelSlide(areaSoak) end end) slider.MouseButton1Down:connect(function() areaSoak.Visible = true if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y) setSliderPos(x,slider,sliderPosition,bar,steps) end) end) slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end) sliderPosition.Changed:connect(function(prop) sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value)) local relativePosX = (sliderPosition.Value - 1) / (steps - 1) slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset) fill.Size = UDim2.new(relativePosX, 0, 1, 0) end) bar.MouseButton1Down:connect(function(x,y) setSliderPos(x,slider,sliderPosition,bar,steps) end) return sliderGui, sliderPosition, sliderSteps end t.CreateTrueScrollingFrame = function() local lowY = nil local highY = nil local dragCon = nil local upCon = nil local internalChange = false local descendantsChangeConMap = {} local scrollingFrame = Instance.new("Frame") scrollingFrame.Name = "ScrollingFrame" scrollingFrame.Active = true scrollingFrame.Size = UDim2.new(1,0,1,0) scrollingFrame.ClipsDescendants = true local controlFrame = Instance.new("Frame") controlFrame.Name = "ControlFrame" controlFrame.BackgroundTransparency = 1 controlFrame.Size = UDim2.new(0,18,1,0) controlFrame.Position = UDim2.new(1,-20,0,0) controlFrame.Parent = scrollingFrame local scrollBottom = Instance.new("BoolValue") scrollBottom.Value = false scrollBottom.Name = "ScrollBottom" scrollBottom.Parent = controlFrame local scrollUp = Instance.new("BoolValue") scrollUp.Value = false scrollUp.Name = "scrollUp" scrollUp.Parent = controlFrame local scrollUpButton = Instance.new("TextButton") scrollUpButton.Name = "ScrollUpButton" scrollUpButton.Text = "" scrollUpButton.AutoButtonColor = false scrollUpButton.BackgroundColor3 = Color3.new(0,0,0) scrollUpButton.BorderColor3 = Color3.new(1,1,1) scrollUpButton.BackgroundTransparency = 0.5 scrollUpButton.Size = UDim2.new(0,18,0,18) scrollUpButton.ZIndex = 2 scrollUpButton.Parent = controlFrame for i = 1, 6 do local triFrame = Instance.new("Frame") triFrame.BorderColor3 = Color3.new(1,1,1) triFrame.Name = "tri" .. tostring(i) triFrame.ZIndex = 3 triFrame.BackgroundTransparency = 0.5 triFrame.Size = UDim2.new(0,12 - ((i -1) * 2),0,0) triFrame.Position = UDim2.new(0,3 + (i -1),0.5,2 - (i -1)) triFrame.Parent = scrollUpButton end scrollUpButton.MouseEnter:connect(function() scrollUpButton.BackgroundTransparency = 0.1 local upChildren = scrollUpButton:GetChildren() for i = 1, #upChildren do upChildren[i].BackgroundTransparency = 0.1 end end) scrollUpButton.MouseLeave:connect(function() scrollUpButton.BackgroundTransparency = 0.5 local upChildren = scrollUpButton:GetChildren() for i = 1, #upChildren do upChildren[i].BackgroundTransparency = 0.5 end end) local scrollDownButton = scrollUpButton:clone() scrollDownButton.Name = "ScrollDownButton" scrollDownButton.Position = UDim2.new(0,0,1,-18) local downChildren = scrollDownButton:GetChildren() for i = 1, #downChildren do downChildren[i].Position = UDim2.new(0,3 + (i -1),0.5,-2 + (i - 1)) end scrollDownButton.MouseEnter:connect(function() scrollDownButton.BackgroundTransparency = 0.1 local downChildren = scrollDownButton:GetChildren() for i = 1, #downChildren do downChildren[i].BackgroundTransparency = 0.1 end end) scrollDownButton.MouseLeave:connect(function() scrollDownButton.BackgroundTransparency = 0.5 local downChildren = scrollDownButton:GetChildren() for i = 1, #downChildren do downChildren[i].BackgroundTransparency = 0.5 end end) scrollDownButton.Parent = controlFrame local scrollTrack = Instance.new("Frame") scrollTrack.Name = "ScrollTrack" scrollTrack.BackgroundTransparency = 1 scrollTrack.Size = UDim2.new(0,18,1,-38) scrollTrack.Position = UDim2.new(0,0,0,19) scrollTrack.Parent = controlFrame local scrollbar = Instance.new("TextButton") scrollbar.BackgroundColor3 = Color3.new(0,0,0) scrollbar.BorderColor3 = Color3.new(1,1,1) scrollbar.BackgroundTransparency = 0.5 scrollbar.AutoButtonColor = false scrollbar.Text = "" scrollbar.Active = true scrollbar.Name = "ScrollBar" scrollbar.ZIndex = 2 scrollbar.BackgroundTransparency = 0.5 scrollbar.Size = UDim2.new(0, 18, 0.1, 0) scrollbar.Position = UDim2.new(0,0,0,0) scrollbar.Parent = scrollTrack local scrollNub = Instance.new("Frame") scrollNub.Name = "ScrollNub" scrollNub.BorderColor3 = Color3.new(1,1,1) scrollNub.Size = UDim2.new(0,10,0,0) scrollNub.Position = UDim2.new(0.5,-5,0.5,0) scrollNub.ZIndex = 2 scrollNub.BackgroundTransparency = 0.5 scrollNub.Parent = scrollbar local newNub = scrollNub:clone() newNub.Position = UDim2.new(0.5,-5,0.5,-2) newNub.Parent = scrollbar local lastNub = scrollNub:clone() lastNub.Position = UDim2.new(0.5,-5,0.5,2) lastNub.Parent = scrollbar scrollbar.MouseEnter:connect(function() scrollbar.BackgroundTransparency = 0.1 scrollNub.BackgroundTransparency = 0.1 newNub.BackgroundTransparency = 0.1 lastNub.BackgroundTransparency = 0.1 end) scrollbar.MouseLeave:connect(function() scrollbar.BackgroundTransparency = 0.5 scrollNub.BackgroundTransparency = 0.5 newNub.BackgroundTransparency = 0.5 lastNub.BackgroundTransparency = 0.5 end) local mouseDrag = Instance.new("ImageButton") mouseDrag.Active = false mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0) mouseDrag.AutoButtonColor = false mouseDrag.BackgroundTransparency = 1 mouseDrag.Name = "mouseDrag" mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0) mouseDrag.ZIndex = 10 local function positionScrollBar(x,y,offset) local oldPos = scrollbar.Position if y < scrollTrack.AbsolutePosition.y then scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0) return (oldPos ~= scrollbar.Position) end local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y if y > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0) return (oldPos ~= scrollbar.Position) end local newScaleYPos = (y - scrollTrack.AbsolutePosition.y - offset)/scrollTrack.AbsoluteSize.y if newScaleYPos + relativeSize > 1 then newScaleYPos = 1 - relativeSize scrollBottom.Value = true scrollUp.Value = false elseif newScaleYPos <= 0 then newScaleYPos = 0 scrollUp.Value = true scrollBottom.Value = false else scrollUp.Value = false scrollBottom.Value = false end scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,newScaleYPos,0) return (oldPos ~= scrollbar.Position) end local function drillDownSetHighLow(instance) if not instance or not instance:IsA("GuiObject") then return end if instance == controlFrame then return end if instance:IsDescendantOf(controlFrame) then return end if not instance.Visible then return end if lowY and lowY > instance.AbsolutePosition.Y then lowY = instance.AbsolutePosition.Y elseif not lowY then lowY = instance.AbsolutePosition.Y end if highY and highY < (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) then highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y elseif not highY then highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y end local children = instance:GetChildren() for i = 1, #children do drillDownSetHighLow(children[i]) end end local function resetHighLow() local firstChildren = scrollingFrame:GetChildren() for i = 1, #firstChildren do drillDownSetHighLow(firstChildren[i]) end end local function recalculate() internalChange = true local percentFrame = 0 if scrollbar.Position.Y.Scale > 0 then if scrollbar.Visible then percentFrame = scrollbar.Position.Y.Scale/((scrollTrack.AbsoluteSize.Y - scrollbar.AbsoluteSize.Y)/scrollTrack.AbsoluteSize.Y) else percentFrame = 0 end end if percentFrame > 0.99 then percentFrame = 1 end local hiddenYAmount = (scrollingFrame.AbsoluteSize.Y - (highY - lowY)) * percentFrame local guiChildren = scrollingFrame:GetChildren() for i = 1, #guiChildren do if guiChildren[i] ~= controlFrame then guiChildren[i].Position = UDim2.new(guiChildren[i].Position.X.Scale,guiChildren[i].Position.X.Offset, 0, math.ceil(guiChildren[i].AbsolutePosition.Y) - math.ceil(lowY) + hiddenYAmount) end end lowY = nil highY = nil resetHighLow() internalChange = false end local function setSliderSizeAndPosition() if not highY or not lowY then return end local totalYSpan = math.abs(highY - lowY) if totalYSpan == 0 then scrollbar.Visible = false scrollDownButton.Visible = false scrollUpButton.Visible = false if dragCon then dragCon:disconnect() dragCon = nil end if upCon then upCon:disconnect() upCon = nil end return end local percentShown = scrollingFrame.AbsoluteSize.Y/totalYSpan if percentShown >= 1 then scrollbar.Visible = false scrollDownButton.Visible = false scrollUpButton.Visible = false recalculate() else scrollbar.Visible = true scrollDownButton.Visible = true scrollUpButton.Visible = true scrollbar.Size = UDim2.new(scrollbar.Size.X.Scale,scrollbar.Size.X.Offset,percentShown,0) end local percentPosition = (scrollingFrame.AbsolutePosition.Y - lowY)/totalYSpan scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,percentPosition,-scrollbar.AbsoluteSize.X/2) if scrollbar.AbsolutePosition.y < scrollTrack.AbsolutePosition.y then scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0) end if (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.Y) > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0) end end local buttonScrollAmountPixels = 7 local reentrancyGuardScrollUp = false local function doScrollUp() if reentrancyGuardScrollUp then return end reentrancyGuardScrollUp = true if positionScrollBar(0,scrollbar.AbsolutePosition.Y - buttonScrollAmountPixels,0) then recalculate() end reentrancyGuardScrollUp = false end local reentrancyGuardScrollDown = false local function doScrollDown() if reentrancyGuardScrollDown then return end reentrancyGuardScrollDown = true if positionScrollBar(0,scrollbar.AbsolutePosition.Y + buttonScrollAmountPixels,0) then recalculate() end reentrancyGuardScrollDown = false end local function scrollUp(mouseYPos) if scrollUpButton.Active then scrollStamp = tick() local current = scrollStamp local upCon upCon = mouseDrag.MouseButton1Up:connect(function() scrollStamp = tick() mouseDrag.Parent = nil upCon:disconnect() end) mouseDrag.Parent = getScreenGuiAncestor(scrollbar) doScrollUp() wait(0.2) local t = tick() local w = 0.1 while scrollStamp == current do doScrollUp() if mouseYPos and mouseYPos > scrollbar.AbsolutePosition.y then break end if not scrollUpButton.Active then break end if tick()-t > 5 then w = 0 elseif tick()-t > 2 then w = 0.06 end wait(w) end end end local function scrollDown(mouseYPos) if scrollDownButton.Active then scrollStamp = tick() local current = scrollStamp local downCon downCon = mouseDrag.MouseButton1Up:connect(function() scrollStamp = tick() mouseDrag.Parent = nil downCon:disconnect() end) mouseDrag.Parent = getScreenGuiAncestor(scrollbar) doScrollDown() wait(0.2) local t = tick() local w = 0.1 while scrollStamp == current do doScrollDown() if mouseYPos and mouseYPos < (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.x) then break end if not scrollDownButton.Active then break end if tick()-t > 5 then w = 0 elseif tick()-t > 2 then w = 0.06 end wait(w) end end end scrollbar.MouseButton1Down:connect(function(x,y) if scrollbar.Active then scrollStamp = tick() local mouseOffset = y - scrollbar.AbsolutePosition.y if dragCon then dragCon:disconnect() dragCon = nil end if upCon then upCon:disconnect() upCon = nil end local prevY = y local reentrancyGuardMouseScroll = false dragCon = mouseDrag.MouseMoved:connect(function(x,y) if reentrancyGuardMouseScroll then return end reentrancyGuardMouseScroll = true if positionScrollBar(x,y,mouseOffset) then recalculate() end reentrancyGuardMouseScroll = false end) upCon = mouseDrag.MouseButton1Up:connect(function() scrollStamp = tick() mouseDrag.Parent = nil dragCon:disconnect(); dragCon = nil upCon:disconnect(); drag = nil end) mouseDrag.Parent = getScreenGuiAncestor(scrollbar) end end) local scrollMouseCount = 0 scrollUpButton.MouseButton1Down:connect(function() scrollUp() end) scrollUpButton.MouseButton1Up:connect(function() scrollStamp = tick() end) scrollDownButton.MouseButton1Up:connect(function() scrollStamp = tick() end) scrollDownButton.MouseButton1Down:connect(function() scrollDown() end) scrollbar.MouseButton1Up:connect(function() scrollStamp = tick() end) local function heightCheck(instance) if highY and (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) > highY then highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y elseif not highY then highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y end setSliderSizeAndPosition() end local function highLowRecheck() local oldLowY = lowY local oldHighY = highY lowY = nil highY = nil resetHighLow() if (lowY ~= oldLowY) or (highY ~= oldHighY) then setSliderSizeAndPosition() end end local function descendantChanged(this, prop) if internalChange then return end if not this.Visible then return end if prop == "Size" or prop == "Position" then wait() highLowRecheck() end end scrollingFrame.DescendantAdded:connect(function(instance) if not instance:IsA("GuiObject") then return end if instance.Visible then wait() -- wait a heartbeat for sizes to reconfig highLowRecheck() end descendantsChangeConMap[instance] = instance.Changed:connect(function(prop) descendantChanged(instance, prop) end) end) scrollingFrame.DescendantRemoving:connect(function(instance) if not instance:IsA("GuiObject") then return end if descendantsChangeConMap[instance] then descendantsChangeConMap[instance]:disconnect() descendantsChangeConMap[instance] = nil end wait() -- wait a heartbeat for sizes to reconfig highLowRecheck() end) scrollingFrame.Changed:connect(function(prop) if prop == "AbsoluteSize" then if not highY or not lowY then return end highLowRecheck() setSliderSizeAndPosition() end end) return scrollingFrame, controlFrame end t.CreateScrollingFrame = function(orderList,scrollStyle) local frame = Instance.new("Frame") frame.Name = "ScrollingFrame" frame.BackgroundTransparency = 1 frame.Size = UDim2.new(1,0,1,0) local scrollUpButton = Instance.new("ImageButton") scrollUpButton.Name = "ScrollUpButton" scrollUpButton.BackgroundTransparency = 1 scrollUpButton.Image = "rbxasset://textures/ui/scrollbuttonUp.png" scrollUpButton.Size = UDim2.new(0,17,0,17) local scrollDownButton = Instance.new("ImageButton") scrollDownButton.Name = "ScrollDownButton" scrollDownButton.BackgroundTransparency = 1 scrollDownButton.Image = "rbxasset://textures/ui/scrollbuttonDown.png" scrollDownButton.Size = UDim2.new(0,17,0,17) local scrollbar = Instance.new("ImageButton") scrollbar.Name = "ScrollBar" scrollbar.Image = "rbxasset://textures/ui/scrollbar.png" scrollbar.BackgroundTransparency = 1 scrollbar.Size = UDim2.new(0, 18, 0, 150) local scrollStamp = 0 local scrollDrag = Instance.new("ImageButton") scrollDrag.Image = "http://www.roblox.com/asset/?id=61367186" scrollDrag.Size = UDim2.new(1, 0, 0, 16) scrollDrag.BackgroundTransparency = 1 scrollDrag.Name = "ScrollDrag" scrollDrag.Active = true scrollDrag.Parent = scrollbar local mouseDrag = Instance.new("ImageButton") mouseDrag.Active = false mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0) mouseDrag.AutoButtonColor = false mouseDrag.BackgroundTransparency = 1 mouseDrag.Name = "mouseDrag" mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0) mouseDrag.ZIndex = 10 local style = "simple" if scrollStyle and tostring(scrollStyle) then style = scrollStyle end local scrollPosition = 1 local rowSize = 0 local howManyDisplayed = 0 local layoutGridScrollBar = function() howManyDisplayed = 0 local guiObjects = {} if orderList then for i, child in ipairs(orderList) do if child.Parent == frame then table.insert(guiObjects, child) end end else local children = frame:GetChildren() if children then for i, child in ipairs(children) do if child:IsA("GuiObject") then table.insert(guiObjects, child) end end end end if #guiObjects == 0 then scrollUpButton.Active = false scrollDownButton.Active = false scrollDrag.Active = false scrollPosition = 1 return end if scrollPosition > #guiObjects then scrollPosition = #guiObjects end if scrollPosition < 1 then scrollPosition = 1 end local totalPixelsY = frame.AbsoluteSize.Y local pixelsRemainingY = frame.AbsoluteSize.Y local totalPixelsX = frame.AbsoluteSize.X local xCounter = 0 local rowSizeCounter = 0 local setRowSize = true local pixelsBelowScrollbar = 0 local pos = #guiObjects local currentRowY = 0 pos = scrollPosition --count up from current scroll position to fill out grid while pos <= #guiObjects and pixelsBelowScrollbar < totalPixelsY do xCounter = xCounter + guiObjects[pos].AbsoluteSize.X --previous pos was the end of a row if xCounter >= totalPixelsX then pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY currentRowY = 0 xCounter = guiObjects[pos].AbsoluteSize.X end if guiObjects[pos].AbsoluteSize.Y > currentRowY then currentRowY = guiObjects[pos].AbsoluteSize.Y end pos = pos + 1 end --Count wherever current row left off pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY currentRowY = 0 pos = scrollPosition - 1 xCounter = 0 --objects with varying X,Y dimensions can rarely cause minor errors --rechecking every new scrollPosition is necessary to avoid 100% of errors --count backwards from current scrollPosition to see if we can add more rows while pixelsBelowScrollbar + currentRowY < totalPixelsY and pos >= 1 do xCounter = xCounter + guiObjects[pos].AbsoluteSize.X rowSizeCounter = rowSizeCounter + 1 if xCounter >= totalPixelsX then rowSize = rowSizeCounter - 1 rowSizeCounter = 0 xCounter = guiObjects[pos].AbsoluteSize.X if pixelsBelowScrollbar + currentRowY <= totalPixelsY then --It fits, so back up our scroll position pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY if scrollPosition <= rowSize then scrollPosition = 1 break else scrollPosition = scrollPosition - rowSize end currentRowY = 0 else break end end if guiObjects[pos].AbsoluteSize.Y > currentRowY then currentRowY = guiObjects[pos].AbsoluteSize.Y end pos = pos - 1 end --Do check last time if pos = 0 if (pos == 0) and (pixelsBelowScrollbar + currentRowY <= totalPixelsY) then scrollPosition = 1 end xCounter = 0 --pos = scrollPosition rowSizeCounter = 0 setRowSize = true local lastChildSize = 0 local xOffset,yOffset = 0 if guiObjects[1] then yOffset = math.ceil(math.floor(math.fmod(totalPixelsY,guiObjects[1].AbsoluteSize.X))/2) xOffset = math.ceil(math.floor(math.fmod(totalPixelsX,guiObjects[1].AbsoluteSize.Y))/2) end for i, child in ipairs(guiObjects) do if i < scrollPosition then --print("Hiding " .. child.Name) child.Visible = false else if pixelsRemainingY < 0 then --print("Out of Space " .. child.Name) child.Visible = false else --print("Laying out " .. child.Name) --GuiObject if setRowSize then rowSizeCounter = rowSizeCounter + 1 end if xCounter + child.AbsoluteSize.X >= totalPixelsX then if setRowSize then rowSize = rowSizeCounter - 1 setRowSize = false end xCounter = 0 pixelsRemainingY = pixelsRemainingY - child.AbsoluteSize.Y end child.Position = UDim2.new(child.Position.X.Scale,xCounter + xOffset, 0, totalPixelsY - pixelsRemainingY + yOffset) xCounter = xCounter + child.AbsoluteSize.X child.Visible = ((pixelsRemainingY - child.AbsoluteSize.Y) >= 0) if child.Visible then howManyDisplayed = howManyDisplayed + 1 end lastChildSize = child.AbsoluteSize end end end scrollUpButton.Active = (scrollPosition > 1) if lastChildSize == 0 then scrollDownButton.Active = false else scrollDownButton.Active = ((pixelsRemainingY - lastChildSize.Y) < 0) end scrollDrag.Active = #guiObjects > howManyDisplayed scrollDrag.Visible = scrollDrag.Active end local layoutSimpleScrollBar = function() local guiObjects = {} howManyDisplayed = 0 if orderList then for i, child in ipairs(orderList) do if child.Parent == frame then table.insert(guiObjects, child) end end else local children = frame:GetChildren() if children then for i, child in ipairs(children) do if child:IsA("GuiObject") then table.insert(guiObjects, child) end end end end if #guiObjects == 0 then scrollUpButton.Active = false scrollDownButton.Active = false scrollDrag.Active = false scrollPosition = 1 return end if scrollPosition > #guiObjects then scrollPosition = #guiObjects end local totalPixels = frame.AbsoluteSize.Y local pixelsRemaining = frame.AbsoluteSize.Y local pixelsBelowScrollbar = 0 local pos = #guiObjects while pixelsBelowScrollbar < totalPixels and pos >= 1 do if pos >= scrollPosition then pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y else if pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y <= totalPixels then --It fits, so back up our scroll position pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y if scrollPosition <= 1 then scrollPosition = 1 break else --local ("Backing up ScrollPosition from -- " ..scrollPosition) scrollPosition = scrollPosition - 1 end else break end end pos = pos - 1 end pos = scrollPosition for i, child in ipairs(guiObjects) do if i < scrollPosition then --print("Hiding " .. child.Name) child.Visible = false else if pixelsRemaining < 0 then --print("Out of Space " .. child.Name) child.Visible = false else --print("Laying out " .. child.Name) --GuiObject child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining) pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y if (pixelsRemaining >= 0) then child.Visible = true howManyDisplayed = howManyDisplayed + 1 else child.Visible = false end end end end scrollUpButton.Active = (scrollPosition > 1) scrollDownButton.Active = (pixelsRemaining < 0) scrollDrag.Active = #guiObjects > howManyDisplayed scrollDrag.Visible = scrollDrag.Active end local moveDragger = function() local guiObjects = 0 local children = frame:GetChildren() if children then for i, child in ipairs(children) do if child:IsA("GuiObject") then guiObjects = guiObjects + 1 end end end if not scrollDrag.Parent then return end local dragSizeY = scrollDrag.Parent.AbsoluteSize.y * (1/(guiObjects - howManyDisplayed + 1)) if dragSizeY < 16 then dragSizeY = 16 end scrollDrag.Size = UDim2.new(scrollDrag.Size.X.Scale,scrollDrag.Size.X.Offset,scrollDrag.Size.Y.Scale,dragSizeY) local relativeYPos = (scrollPosition - 1)/(guiObjects - (howManyDisplayed)) if relativeYPos > 1 then relativeYPos = 1 elseif relativeYPos < 0 then relativeYPos = 0 end local absYPos = 0 if relativeYPos ~= 0 then absYPos = (relativeYPos * scrollbar.AbsoluteSize.y) - (relativeYPos * scrollDrag.AbsoluteSize.y) end scrollDrag.Position = UDim2.new(scrollDrag.Position.X.Scale,scrollDrag.Position.X.Offset,scrollDrag.Position.Y.Scale,absYPos) end local reentrancyGuard = false local recalculate = function() if reentrancyGuard then return end reentrancyGuard = true wait() local success, err = nil if style == "grid" then success, err = pcall(function() layoutGridScrollBar() end) elseif style == "simple" then success, err = pcall(function() layoutSimpleScrollBar() end) end if not success then print(err) end moveDragger() reentrancyGuard = false end local doScrollUp = function() scrollPosition = (scrollPosition) - rowSize if scrollPosition < 1 then scrollPosition = 1 end recalculate(nil) end local doScrollDown = function() scrollPosition = (scrollPosition) + rowSize recalculate(nil) end local scrollUp = function(mouseYPos) if scrollUpButton.Active then scrollStamp = tick() local current = scrollStamp local upCon upCon = mouseDrag.MouseButton1Up:connect(function() scrollStamp = tick() mouseDrag.Parent = nil upCon:disconnect() end) mouseDrag.Parent = getScreenGuiAncestor(scrollbar) doScrollUp() wait(0.2) local t = tick() local w = 0.1 while scrollStamp == current do doScrollUp() if mouseYPos and mouseYPos > scrollDrag.AbsolutePosition.y then break end if not scrollUpButton.Active then break end if tick()-t > 5 then w = 0 elseif tick()-t > 2 then w = 0.06 end wait(w) end end end local scrollDown = function(mouseYPos) if scrollDownButton.Active then scrollStamp = tick() local current = scrollStamp local downCon downCon = mouseDrag.MouseButton1Up:connect(function() scrollStamp = tick() mouseDrag.Parent = nil downCon:disconnect() end) mouseDrag.Parent = getScreenGuiAncestor(scrollbar) doScrollDown() wait(0.2) local t = tick() local w = 0.1 while scrollStamp == current do doScrollDown() if mouseYPos and mouseYPos < (scrollDrag.AbsolutePosition.y + scrollDrag.AbsoluteSize.x) then break end if not scrollDownButton.Active then break end if tick()-t > 5 then w = 0 elseif tick()-t > 2 then w = 0.06 end wait(w) end end end local y = 0 scrollDrag.MouseButton1Down:connect(function(x,y) if scrollDrag.Active then scrollStamp = tick() local mouseOffset = y - scrollDrag.AbsolutePosition.y local dragCon local upCon dragCon = mouseDrag.MouseMoved:connect(function(x,y) local barAbsPos = scrollbar.AbsolutePosition.y local barAbsSize = scrollbar.AbsoluteSize.y local dragAbsSize = scrollDrag.AbsoluteSize.y local barAbsOne = barAbsPos + barAbsSize - dragAbsSize y = y - mouseOffset y = y < barAbsPos and barAbsPos or y > barAbsOne and barAbsOne or y y = y - barAbsPos local guiObjects = 0 local children = frame:GetChildren() if children then for i, child in ipairs(children) do if child:IsA("GuiObject") then guiObjects = guiObjects + 1 end end end local doublePercent = y/(barAbsSize-dragAbsSize) local rowDiff = rowSize local totalScrollCount = guiObjects - (howManyDisplayed - 1) local newScrollPosition = math.floor((doublePercent * totalScrollCount) + 0.5) + rowDiff if newScrollPosition < scrollPosition then rowDiff = -rowDiff end if newScrollPosition < 1 then newScrollPosition = 1 end scrollPosition = newScrollPosition recalculate(nil) end) upCon = mouseDrag.MouseButton1Up:connect(function() scrollStamp = tick() mouseDrag.Parent = nil dragCon:disconnect(); dragCon = nil upCon:disconnect(); drag = nil end) mouseDrag.Parent = getScreenGuiAncestor(scrollbar) end end) local scrollMouseCount = 0 scrollUpButton.MouseButton1Down:connect( function() scrollUp() end) scrollUpButton.MouseButton1Up:connect(function() scrollStamp = tick() end) scrollDownButton.MouseButton1Up:connect(function() scrollStamp = tick() end) scrollDownButton.MouseButton1Down:connect( function() scrollDown() end) scrollbar.MouseButton1Up:connect(function() scrollStamp = tick() end) scrollbar.MouseButton1Down:connect( function(x,y) if y > (scrollDrag.AbsoluteSize.y + scrollDrag.AbsolutePosition.y) then scrollDown(y) elseif y < (scrollDrag.AbsolutePosition.y) then scrollUp(y) end end) frame.ChildAdded:connect(function() recalculate(nil) end) frame.ChildRemoved:connect(function() recalculate(nil) end) frame.Changed:connect( function(prop) if prop == "AbsoluteSize" then --Wait a heartbeat for it to sync in recalculate(nil) end end) frame.AncestryChanged:connect(function() recalculate(nil) end) return frame, scrollUpButton, scrollDownButton, recalculate, scrollbar end local function binaryGrow(min, max, fits) if min > max then return min end local biggestLegal = min while min <= max do local mid = min + math.floor((max - min) / 2) if fits(mid) and (biggestLegal == nil or biggestLegal < mid) then biggestLegal = mid --Try growing min = mid + 1 else --Doesn't fit, shrink max = mid - 1 end end return biggestLegal end local function binaryShrink(min, max, fits) if min > max then return min end local smallestLegal = max while min <= max do local mid = min + math.floor((max - min) / 2) if fits(mid) and (smallestLegal == nil or smallestLegal > mid) then smallestLegal = mid --It fits, shrink max = mid - 1 else --Doesn't fit, grow min = mid + 1 end end return smallestLegal end local function getGuiOwner(instance) while instance ~= nil do if instance:IsA("ScreenGui") or instance:IsA("BillboardGui") then return instance end instance = instance.Parent end return nil end t.AutoTruncateTextObject = function(textLabel) local text = textLabel.Text local fullLabel = textLabel:Clone() fullLabel.Name = "Full" .. textLabel.Name fullLabel.BorderSizePixel = 0 fullLabel.BackgroundTransparency = 0 fullLabel.Text = text fullLabel.TextXAlignment = Enum.TextXAlignment.Center fullLabel.Position = UDim2.new(0,-3,0,0) fullLabel.Size = UDim2.new(0,100,1,0) fullLabel.Visible = false fullLabel.Parent = textLabel local shortText = nil local mouseEnterConnection = nil local mouseLeaveConnection= nil local checkForResize = function() if getGuiOwner(textLabel) == nil then return end textLabel.Text = text if textLabel.TextFits then --Tear down the rollover if it is active if mouseEnterConnection then mouseEnterConnection:disconnect() mouseEnterConnection = nil end if mouseLeaveConnection then mouseLeaveConnection:disconnect() mouseLeaveConnection = nil end else local len = string.len(text) textLabel.Text = text .. "~" --Shrink the text local textSize = binaryGrow(0, len, function(pos) if pos == 0 then textLabel.Text = "~" else textLabel.Text = string.sub(text, 1, pos) .. "~" end return textLabel.TextFits end) shortText = string.sub(text, 1, textSize) .. "~" textLabel.Text = shortText --Make sure the fullLabel fits if not fullLabel.TextFits then --Already too small, grow it really bit to start fullLabel.Size = UDim2.new(0, 10000, 1, 0) end --Okay, now try to binary shrink it back down local fullLabelSize = binaryShrink(textLabel.AbsoluteSize.X,fullLabel.AbsoluteSize.X, function(size) fullLabel.Size = UDim2.new(0, size, 1, 0) return fullLabel.TextFits end) fullLabel.Size = UDim2.new(0,fullLabelSize+6,1,0) --Now setup the rollover effects, if they are currently off if mouseEnterConnection == nil then mouseEnterConnection = textLabel.MouseEnter:connect( function() fullLabel.ZIndex = textLabel.ZIndex + 1 fullLabel.Visible = true --textLabel.Text = "" end) end if mouseLeaveConnection == nil then mouseLeaveConnection = textLabel.MouseLeave:connect( function() fullLabel.Visible = false --textLabel.Text = shortText end) end end end textLabel.AncestryChanged:connect(checkForResize) textLabel.Changed:connect( function(prop) if prop == "AbsoluteSize" then checkForResize() end end) checkForResize() local function changeText(newText) text = newText fullLabel.Text = text checkForResize() end return textLabel, changeText end local function TransitionTutorialPages(fromPage, toPage, transitionFrame, currentPageValue) if fromPage then fromPage.Visible = false if transitionFrame.Visible == false then transitionFrame.Size = fromPage.Size transitionFrame.Position = fromPage.Position end else if transitionFrame.Visible == false then transitionFrame.Size = UDim2.new(0.0,50,0.0,50) transitionFrame.Position = UDim2.new(0.5,-25,0.5,-25) end end transitionFrame.Visible = true currentPageValue.Value = nil local newsize, newPosition if toPage then --Make it visible so it resizes toPage.Visible = true newSize = toPage.Size newPosition = toPage.Position toPage.Visible = false else newSize = UDim2.new(0.0,50,0.0,50) newPosition = UDim2.new(0.5,-25,0.5,-25) end transitionFrame:TweenSizeAndPosition(newSize, newPosition, Enum.EasingDirection.InOut, Enum.EasingStyle.Quad, 0.3, true, function(state) if state == Enum.TweenStatus.Completed then transitionFrame.Visible = false if toPage then toPage.Visible = true currentPageValue.Value = toPage end end end) end t.CreateTutorial = function(name, tutorialKey, createButtons) local frame = Instance.new("Frame") frame.Name = "Tutorial-" .. name frame.BackgroundTransparency = 1 frame.Size = UDim2.new(0.6, 0, 0.6, 0) frame.Position = UDim2.new(0.2, 0, 0.2, 0) local transitionFrame = Instance.new("Frame") transitionFrame.Name = "TransitionFrame" transitionFrame.Style = Enum.FrameStyle.RobloxRound transitionFrame.Size = UDim2.new(0.6, 0, 0.6, 0) transitionFrame.Position = UDim2.new(0.2, 0, 0.2, 0) transitionFrame.Visible = false transitionFrame.Parent = frame local currentPageValue = Instance.new("ObjectValue") currentPageValue.Name = "CurrentTutorialPage" currentPageValue.Value = nil currentPageValue.Parent = frame local boolValue = Instance.new("BoolValue") boolValue.Name = "Buttons" boolValue.Value = createButtons boolValue.Parent = frame local pages = Instance.new("Frame") pages.Name = "Pages" pages.BackgroundTransparency = 1 pages.Size = UDim2.new(1,0,1,0) pages.Parent = frame local function getVisiblePageAndHideOthers() local visiblePage = nil local children = pages:GetChildren() if children then for i,child in ipairs(children) do if child.Visible then if visiblePage then child.Visible = false else visiblePage = child end end end end return visiblePage end local showTutorial = function(alwaysShow) if alwaysShow or UserSettings().GameSettings:GetTutorialState(tutorialKey) == false then print("Showing tutorial-",tutorialKey) local currentTutorialPage = getVisiblePageAndHideOthers() local firstPage = pages:FindFirstChild("TutorialPage1") if firstPage then TransitionTutorialPages(currentTutorialPage, firstPage, transitionFrame, currentPageValue) else error("Could not find TutorialPage1") end end end local dismissTutorial = function() local currentTutorialPage = getVisiblePageAndHideOthers() if currentTutorialPage then TransitionTutorialPages(currentTutorialPage, nil, transitionFrame, currentPageValue) end UserSettings().GameSettings:SetTutorialState(tutorialKey, true) end local gotoPage = function(pageNum) local page = pages:FindFirstChild("TutorialPage" .. pageNum) local currentTutorialPage = getVisiblePageAndHideOthers() TransitionTutorialPages(currentTutorialPage, page, transitionFrame, currentPageValue) end return frame, showTutorial, dismissTutorial, gotoPage end local function CreateBasicTutorialPage(name, handleResize, skipTutorial, giveDoneButton) local frame = Instance.new("Frame") frame.Name = "TutorialPage" frame.Style = Enum.FrameStyle.RobloxRound frame.Size = UDim2.new(0.6, 0, 0.6, 0) frame.Position = UDim2.new(0.2, 0, 0.2, 0) frame.Visible = false local frameHeader = Instance.new("TextLabel") frameHeader.Name = "Header" frameHeader.Text = name frameHeader.BackgroundTransparency = 1 frameHeader.FontSize = Enum.FontSize.Size24 frameHeader.Font = Enum.Font.ArialBold frameHeader.TextColor3 = Color3.new(1,1,1) frameHeader.TextXAlignment = Enum.TextXAlignment.Center frameHeader.TextWrap = true frameHeader.Size = UDim2.new(1,-55, 0, 22) frameHeader.Position = UDim2.new(0,0,0,0) frameHeader.Parent = frame local skipButton = Instance.new("ImageButton") skipButton.Name = "SkipButton" skipButton.AutoButtonColor = false skipButton.BackgroundTransparency = 1 skipButton.Image = "rbxasset://textures/ui/closeButton.png" skipButton.MouseButton1Click:connect(function() skipTutorial() end) skipButton.MouseEnter:connect(function() skipButton.Image = "rbxasset://textures/ui/closeButton_dn.png" end) skipButton.MouseLeave:connect(function() skipButton.Image = "rbxasset://textures/ui/closeButton.png" end) skipButton.Size = UDim2.new(0, 25, 0, 25) skipButton.Position = UDim2.new(1, -25, 0, 0) skipButton.Parent = frame if giveDoneButton then local doneButton = Instance.new("TextButton") doneButton.Name = "DoneButton" doneButton.Style = Enum.ButtonStyle.RobloxButtonDefault doneButton.Text = "Done" doneButton.TextColor3 = Color3.new(1,1,1) doneButton.Font = Enum.Font.ArialBold doneButton.FontSize = Enum.FontSize.Size18 doneButton.Size = UDim2.new(0,100,0,50) doneButton.Position = UDim2.new(0.5,-50,1,-50) if skipTutorial then doneButton.MouseButton1Click:connect(function() skipTutorial() end) end doneButton.Parent = frame end local innerFrame = Instance.new("Frame") innerFrame.Name = "ContentFrame" innerFrame.BackgroundTransparency = 1 innerFrame.Position = UDim2.new(0,0,0,25) innerFrame.Parent = frame local nextButton = Instance.new("TextButton") nextButton.Name = "NextButton" nextButton.Text = "Next" nextButton.TextColor3 = Color3.new(1,1,1) nextButton.Font = Enum.Font.Arial nextButton.FontSize = Enum.FontSize.Size18 nextButton.Style = Enum.ButtonStyle.RobloxButtonDefault nextButton.Size = UDim2.new(0,80, 0, 32) nextButton.Position = UDim2.new(0.5, 5, 1, -32) nextButton.Active = false nextButton.Visible = false nextButton.Parent = frame local prevButton = Instance.new("TextButton") prevButton.Name = "PrevButton" prevButton.Text = "Previous" prevButton.TextColor3 = Color3.new(1,1,1) prevButton.Font = Enum.Font.Arial prevButton.FontSize = Enum.FontSize.Size18 prevButton.Style = Enum.ButtonStyle.RobloxButton prevButton.Size = UDim2.new(0,80, 0, 32) prevButton.Position = UDim2.new(0.5, -85, 1, -32) prevButton.Active = false prevButton.Visible = false prevButton.Parent = frame if giveDoneButton then innerFrame.Size = UDim2.new(1,0,1,-75) else innerFrame.Size = UDim2.new(1,0,1,-22) end local parentConnection = nil local function basicHandleResize() if frame.Visible and frame.Parent then local maxSize = math.min(frame.Parent.AbsoluteSize.X, frame.Parent.AbsoluteSize.Y) handleResize(200,maxSize) end end frame.Changed:connect( function(prop) if prop == "Parent" then if parentConnection ~= nil then parentConnection:disconnect() parentConnection = nil end if frame.Parent and frame.Parent:IsA("GuiObject") then parentConnection = frame.Parent.Changed:connect( function(parentProp) if parentProp == "AbsoluteSize" then wait() basicHandleResize() end end) basicHandleResize() end end if prop == "Visible" then basicHandleResize() end end) return frame, innerFrame end t.CreateTextTutorialPage = function(name, text, skipTutorialFunc) local frame = nil local contentFrame = nil local textLabel = Instance.new("TextLabel") textLabel.BackgroundTransparency = 1 textLabel.TextColor3 = Color3.new(1,1,1) textLabel.Text = text textLabel.TextWrap = true textLabel.TextXAlignment = Enum.TextXAlignment.Left textLabel.TextYAlignment = Enum.TextYAlignment.Center textLabel.Font = Enum.Font.Arial textLabel.FontSize = Enum.FontSize.Size14 textLabel.Size = UDim2.new(1,0,1,0) local function handleResize(minSize, maxSize) size = binaryShrink(minSize, maxSize, function(size) frame.Size = UDim2.new(0, size, 0, size) return textLabel.TextFits end) frame.Size = UDim2.new(0, size, 0, size) frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2) end frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc) textLabel.Parent = contentFrame return frame end t.CreateImageTutorialPage = function(name, imageAsset, x, y, skipTutorialFunc, giveDoneButton) local frame = nil local contentFrame = nil local imageLabel = Instance.new("ImageLabel") imageLabel.BackgroundTransparency = 1 imageLabel.Image = imageAsset imageLabel.Size = UDim2.new(0,x,0,y) imageLabel.Position = UDim2.new(0.5,-x/2,0.5,-y/2) local function handleResize(minSize, maxSize) size = binaryShrink(minSize, maxSize, function(size) return size >= x and size >= y end) if size >= x and size >= y then imageLabel.Size = UDim2.new(0,x, 0,y) imageLabel.Position = UDim2.new(0.5,-x/2, 0.5, -y/2) else if x > y then --X is limiter, so imageLabel.Size = UDim2.new(1,0,y/x,0) imageLabel.Position = UDim2.new(0,0, 0.5 - (y/x)/2, 0) else --Y is limiter imageLabel.Size = UDim2.new(x/y,0,1, 0) imageLabel.Position = UDim2.new(0.5-(x/y)/2, 0, 0, 0) end end size = size + 50 frame.Size = UDim2.new(0, size, 0, size) frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2) end frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc, giveDoneButton) imageLabel.Parent = contentFrame return frame end t.AddTutorialPage = function(tutorial, tutorialPage) local transitionFrame = tutorial.TransitionFrame local currentPageValue = tutorial.CurrentTutorialPage if not tutorial.Buttons.Value then tutorialPage.NextButton.Parent = nil tutorialPage.PrevButton.Parent = nil end local children = tutorial.Pages:GetChildren() if children and #children > 0 then tutorialPage.Name = "TutorialPage" .. (#children+1) local previousPage = children[#children] if not previousPage:IsA("GuiObject") then error("All elements under Pages must be GuiObjects") end if tutorial.Buttons.Value then if previousPage.NextButton.Active then error("NextButton already Active on previousPage, please only add pages with RbxGui.AddTutorialPage function") end previousPage.NextButton.MouseButton1Click:connect( function() TransitionTutorialPages(previousPage, tutorialPage, transitionFrame, currentPageValue) end) previousPage.NextButton.Active = true previousPage.NextButton.Visible = true if tutorialPage.PrevButton.Active then error("PrevButton already Active on tutorialPage, please only add pages with RbxGui.AddTutorialPage function") end tutorialPage.PrevButton.MouseButton1Click:connect( function() TransitionTutorialPages(tutorialPage, previousPage, transitionFrame, currentPageValue) end) tutorialPage.PrevButton.Active = true tutorialPage.PrevButton.Visible = true end tutorialPage.Parent = tutorial.Pages else --First child tutorialPage.Name = "TutorialPage1" tutorialPage.Parent = tutorial.Pages end end t.CreateSetPanel = function(userIdsForSets, objectSelected, dialogClosed, size, position, showAdminCategories, useAssetVersionId) if not userIdsForSets then error("CreateSetPanel: userIdsForSets (first arg) is nil, should be a table of number ids") end if type(userIdsForSets) ~= "table" and type(userIdsForSets) ~= "userdata" then error("CreateSetPanel: userIdsForSets (first arg) is of type " ..type(userIdsForSets) .. ", should be of type table or userdata") end if not objectSelected then error("CreateSetPanel: objectSelected (second arg) is nil, should be a callback function!") end if type(objectSelected) ~= "function" then error("CreateSetPanel: objectSelected (second arg) is of type " .. type(objectSelected) .. ", should be of type function!") end if dialogClosed and type(dialogClosed) ~= "function" then error("CreateSetPanel: dialogClosed (third arg) is of type " .. type(dialogClosed) .. ", should be of type function!") end if showAdminCategories == nil then -- by default, don't show beta sets showAdminCategories = false end local arrayPosition = 1 local insertButtons = {} local insertButtonCons = {} local contents = nil local setGui = nil -- used for water selections local waterForceDirection = "NegX" local waterForce = "None" local waterGui, waterTypeChangedEvent = nil local Data = {} Data.CurrentCategory = nil Data.Category = {} local SetCache = {} local userCategoryButtons = nil local buttonWidth = 64 local buttonHeight = buttonWidth local SmallThumbnailUrl = nil local LargeThumbnailUrl = nil local BaseUrl = game:GetService("ContentProvider").BaseUrl:lower() if useAssetVersionId then LargeThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&assetversionid=" SmallThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&assetversionid=" else LargeThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&aid=" SmallThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&aid=" end local function drillDownSetZIndex(parent, index) local children = parent:GetChildren() for i = 1, #children do if children[i]:IsA("GuiObject") then children[i].ZIndex = index end drillDownSetZIndex(children[i], index) end end -- for terrain stamping local currTerrainDropDownFrame = nil local terrainShapes = {"Block","Vertical Ramp","Corner Wedge","Inverse Corner Wedge","Horizontal Ramp","Auto-Wedge"} local terrainShapeMap = {} for i = 1, #terrainShapes do terrainShapeMap[terrainShapes[i]] = i - 1 end terrainShapeMap[terrainShapes[#terrainShapes]] = 6 local function createWaterGui() local waterForceDirections = {"NegX","X","NegY","Y","NegZ","Z"} local waterForces = {"None", "Small", "Medium", "Strong", "Max"} local waterFrame = Instance.new("Frame") waterFrame.Name = "WaterFrame" waterFrame.Style = Enum.FrameStyle.RobloxSquare waterFrame.Size = UDim2.new(0,150,0,110) waterFrame.Visible = false local waterForceLabel = Instance.new("TextLabel") waterForceLabel.Name = "WaterForceLabel" waterForceLabel.BackgroundTransparency = 1 waterForceLabel.Size = UDim2.new(1,0,0,12) waterForceLabel.Font = Enum.Font.ArialBold waterForceLabel.FontSize = Enum.FontSize.Size12 waterForceLabel.TextColor3 = Color3.new(1,1,1) waterForceLabel.TextXAlignment = Enum.TextXAlignment.Left waterForceLabel.Text = "Water Force" waterForceLabel.Parent = waterFrame local waterForceDirLabel = waterForceLabel:Clone() waterForceDirLabel.Name = "WaterForceDirectionLabel" waterForceDirLabel.Text = "Water Force Direction" waterForceDirLabel.Position = UDim2.new(0,0,0,50) waterForceDirLabel.Parent = waterFrame local waterTypeChangedEvent = Instance.new("BindableEvent",waterFrame) waterTypeChangedEvent.Name = "WaterTypeChangedEvent" local waterForceDirectionSelectedFunc = function(newForceDirection) waterForceDirection = newForceDirection waterTypeChangedEvent:Fire({waterForce, waterForceDirection}) end local waterForceSelectedFunc = function(newForce) waterForce = newForce waterTypeChangedEvent:Fire({waterForce, waterForceDirection}) end local waterForceDirectionDropDown, forceWaterDirectionSelection = t.CreateDropDownMenu(waterForceDirections, waterForceDirectionSelectedFunc) waterForceDirectionDropDown.Size = UDim2.new(1,0,0,25) waterForceDirectionDropDown.Position = UDim2.new(0,0,1,3) forceWaterDirectionSelection("NegX") waterForceDirectionDropDown.Parent = waterForceDirLabel local waterForceDropDown, forceWaterForceSelection = t.CreateDropDownMenu(waterForces, waterForceSelectedFunc) forceWaterForceSelection("None") waterForceDropDown.Size = UDim2.new(1,0,0,25) waterForceDropDown.Position = UDim2.new(0,0,1,3) waterForceDropDown.Parent = waterForceLabel return waterFrame, waterTypeChangedEvent end -- Helper Function that contructs gui elements local function createSetGui() local setGui = Instance.new("ScreenGui") setGui.Name = "SetGui" local setPanel = Instance.new("Frame") setPanel.Name = "SetPanel" setPanel.Active = true setPanel.BackgroundTransparency = 1 if position then setPanel.Position = position else setPanel.Position = UDim2.new(0.2, 29, 0.1, 24) end if size then setPanel.Size = size else setPanel.Size = UDim2.new(0.6, -58, 0.64, 0) end setPanel.Style = Enum.FrameStyle.RobloxRound setPanel.ZIndex = 6 setPanel.Parent = setGui -- Children of SetPanel local itemPreview = Instance.new("Frame") itemPreview.Name = "ItemPreview" itemPreview.BackgroundTransparency = 1 itemPreview.Position = UDim2.new(0.8,5,0.085,0) itemPreview.Size = UDim2.new(0.21,0,0.9,0) itemPreview.ZIndex = 6 itemPreview.Parent = setPanel -- Children of ItemPreview local textPanel = Instance.new("Frame") textPanel.Name = "TextPanel" textPanel.BackgroundTransparency = 1 textPanel.Position = UDim2.new(0,0,0.45,0) textPanel.Size = UDim2.new(1,0,0.55,0) textPanel.ZIndex = 6 textPanel.Parent = itemPreview -- Children of TextPanel local rolloverText = Instance.new("TextLabel") rolloverText.Name = "RolloverText" rolloverText.BackgroundTransparency = 1 rolloverText.Size = UDim2.new(1,0,0,48) rolloverText.ZIndex = 6 rolloverText.Font = Enum.Font.ArialBold rolloverText.FontSize = Enum.FontSize.Size24 rolloverText.Text = "" rolloverText.TextColor3 = Color3.new(1,1,1) rolloverText.TextWrap = true rolloverText.TextXAlignment = Enum.TextXAlignment.Left rolloverText.TextYAlignment = Enum.TextYAlignment.Top rolloverText.Parent = textPanel local largePreview = Instance.new("ImageLabel") largePreview.Name = "LargePreview" largePreview.BackgroundTransparency = 1 largePreview.Image = "" largePreview.Size = UDim2.new(1,0,0,170) largePreview.ZIndex = 6 largePreview.Parent = itemPreview local sets = Instance.new("Frame") sets.Name = "Sets" sets.BackgroundTransparency = 1 sets.Position = UDim2.new(0,0,0,5) sets.Size = UDim2.new(0.23,0,1,-5) sets.ZIndex = 6 sets.Parent = setPanel -- Children of Sets local line = Instance.new("Frame") line.Name = "Line" line.BackgroundColor3 = Color3.new(1,1,1) line.BackgroundTransparency = 0.7 line.BorderSizePixel = 0 line.Position = UDim2.new(1,-3,0.06,0) line.Size = UDim2.new(0,3,0.9,0) line.ZIndex = 6 line.Parent = sets local setsLists, controlFrame = t.CreateTrueScrollingFrame() setsLists.Size = UDim2.new(1,-6,0.94,0) setsLists.Position = UDim2.new(0,0,0.06,0) setsLists.BackgroundTransparency = 1 setsLists.Name = "SetsLists" setsLists.ZIndex = 6 setsLists.Parent = sets drillDownSetZIndex(controlFrame, 7) local setsHeader = Instance.new("TextLabel") setsHeader.Name = "SetsHeader" setsHeader.BackgroundTransparency = 1 setsHeader.Size = UDim2.new(0,47,0,24) setsHeader.ZIndex = 6 setsHeader.Font = Enum.Font.ArialBold setsHeader.FontSize = Enum.FontSize.Size24 setsHeader.Text = "Sets" setsHeader.TextColor3 = Color3.new(1,1,1) setsHeader.TextXAlignment = Enum.TextXAlignment.Left setsHeader.TextYAlignment = Enum.TextYAlignment.Top setsHeader.Parent = sets local cancelButton = Instance.new("TextButton") cancelButton.Name = "CancelButton" cancelButton.Position = UDim2.new(1,-32,0,-2) cancelButton.Size = UDim2.new(0,34,0,34) cancelButton.Style = Enum.ButtonStyle.RobloxButtonDefault cancelButton.ZIndex = 6 cancelButton.Text = "" cancelButton.Modal = true cancelButton.Parent = setPanel -- Children of Cancel Button local cancelImage = Instance.new("ImageLabel") cancelImage.Name = "CancelImage" cancelImage.BackgroundTransparency = 1 cancelImage.Image = "http://www.roblox.com/asset/?id=54135717" cancelImage.Position = UDim2.new(0,-2,0,-2) cancelImage.Size = UDim2.new(0,16,0,16) cancelImage.ZIndex = 6 cancelImage.Parent = cancelButton return setGui end local function createSetButton(text) local setButton = Instance.new("TextButton") if text then setButton.Text = text else setButton.Text = "" end setButton.AutoButtonColor = false setButton.BackgroundTransparency = 1 setButton.BackgroundColor3 = Color3.new(1,1,1) setButton.BorderSizePixel = 0 setButton.Size = UDim2.new(1,-5,0,18) setButton.ZIndex = 6 setButton.Visible = false setButton.Font = Enum.Font.Arial setButton.FontSize = Enum.FontSize.Size18 setButton.TextColor3 = Color3.new(1,1,1) setButton.TextXAlignment = Enum.TextXAlignment.Left return setButton end local function buildSetButton(name, setId, setImageId, i, count) local button = createSetButton(name) button.Text = name button.Name = "SetButton" button.Visible = true local setValue = Instance.new("IntValue") setValue.Name = "SetId" setValue.Value = setId setValue.Parent = button local setName = Instance.new("StringValue") setName.Name = "SetName" setName.Value = name setName.Parent = button return button end local function processCategory(sets) local setButtons = {} local numSkipped = 0 for i = 1, #sets do if not showAdminCategories and sets[i].Name == "Beta" then numSkipped = numSkipped + 1 else setButtons[i - numSkipped] = buildSetButton(sets[i].Name, sets[i].CategoryId, sets[i].ImageAssetId, i - numSkipped, #sets) end end return setButtons end local function handleResize() wait() -- neccessary to insure heartbeat happened local itemPreview = setGui.SetPanel.ItemPreview itemPreview.LargePreview.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.X) itemPreview.LargePreview.Position = UDim2.new(0.5,-itemPreview.LargePreview.AbsoluteSize.X/2,0,0) itemPreview.TextPanel.Position = UDim2.new(0,0,0,itemPreview.LargePreview.AbsoluteSize.Y) itemPreview.TextPanel.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.Y - itemPreview.LargePreview.AbsoluteSize.Y) end local function makeInsertAssetButton() local insertAssetButtonExample = Instance.new("Frame") insertAssetButtonExample.Name = "InsertAssetButtonExample" insertAssetButtonExample.Position = UDim2.new(0,128,0,64) insertAssetButtonExample.Size = UDim2.new(0,64,0,64) insertAssetButtonExample.BackgroundTransparency = 1 insertAssetButtonExample.ZIndex = 6 insertAssetButtonExample.Visible = false local assetId = Instance.new("IntValue") assetId.Name = "AssetId" assetId.Value = 0 assetId.Parent = insertAssetButtonExample local assetName = Instance.new("StringValue") assetName.Name = "AssetName" assetName.Value = "" assetName.Parent = insertAssetButtonExample local button = Instance.new("TextButton") button.Name = "Button" button.Text = "" button.Style = Enum.ButtonStyle.RobloxButton button.Position = UDim2.new(0.025,0,0.025,0) button.Size = UDim2.new(0.95,0,0.95,0) button.ZIndex = 6 button.Parent = insertAssetButtonExample local buttonImage = Instance.new("ImageLabel") buttonImage.Name = "ButtonImage" buttonImage.Image = "" buttonImage.Position = UDim2.new(0,-7,0,-7) buttonImage.Size = UDim2.new(1,14,1,14) buttonImage.BackgroundTransparency = 1 buttonImage.ZIndex = 7 buttonImage.Parent = button local configIcon = buttonImage:clone() configIcon.Name = "ConfigIcon" configIcon.Visible = false configIcon.Position = UDim2.new(1,-23,1,-24) configIcon.Size = UDim2.new(0,16,0,16) configIcon.Image = "" configIcon.ZIndex = 6 configIcon.Parent = insertAssetButtonExample return insertAssetButtonExample end local function showLargePreview(insertButton) if insertButton:FindFirstChild("AssetId") then delay(0,function() game:GetService("ContentProvider"):Preload(LargeThumbnailUrl .. tostring(insertButton.AssetId.Value)) setGui.SetPanel.ItemPreview.LargePreview.Image = LargeThumbnailUrl .. tostring(insertButton.AssetId.Value) end) end if insertButton:FindFirstChild("AssetName") then setGui.SetPanel.ItemPreview.TextPanel.RolloverText.Text = insertButton.AssetName.Value end end local function selectTerrainShape(shape) if currTerrainDropDownFrame then objectSelected(tostring(currTerrainDropDownFrame.AssetName.Value), tonumber(currTerrainDropDownFrame.AssetId.Value), shape) end end local function createTerrainTypeButton(name, parent) local dropDownTextButton = Instance.new("TextButton") dropDownTextButton.Name = name .. "Button" dropDownTextButton.Font = Enum.Font.ArialBold dropDownTextButton.FontSize = Enum.FontSize.Size14 dropDownTextButton.BorderSizePixel = 0 dropDownTextButton.TextColor3 = Color3.new(1,1,1) dropDownTextButton.Text = name dropDownTextButton.TextXAlignment = Enum.TextXAlignment.Left dropDownTextButton.BackgroundTransparency = 1 dropDownTextButton.ZIndex = parent.ZIndex + 1 dropDownTextButton.Size = UDim2.new(0,parent.Size.X.Offset - 2,0,16) dropDownTextButton.Position = UDim2.new(0,1,0,0) dropDownTextButton.MouseEnter:connect(function() dropDownTextButton.BackgroundTransparency = 0 dropDownTextButton.TextColor3 = Color3.new(0,0,0) end) dropDownTextButton.MouseLeave:connect(function() dropDownTextButton.BackgroundTransparency = 1 dropDownTextButton.TextColor3 = Color3.new(1,1,1) end) dropDownTextButton.MouseButton1Click:connect(function() dropDownTextButton.BackgroundTransparency = 1 dropDownTextButton.TextColor3 = Color3.new(1,1,1) if dropDownTextButton.Parent and dropDownTextButton.Parent:IsA("GuiObject") then dropDownTextButton.Parent.Visible = false end selectTerrainShape(terrainShapeMap[dropDownTextButton.Text]) end) return dropDownTextButton end local function createTerrainDropDownMenu(zIndex) local dropDown = Instance.new("Frame") dropDown.Name = "TerrainDropDown" dropDown.BackgroundColor3 = Color3.new(0,0,0) dropDown.BorderColor3 = Color3.new(1,0,0) dropDown.Size = UDim2.new(0,200,0,0) dropDown.Visible = false dropDown.ZIndex = zIndex dropDown.Parent = setGui for i = 1, #terrainShapes do local shapeButton = createTerrainTypeButton(terrainShapes[i],dropDown) shapeButton.Position = UDim2.new(0,1,0,(i - 1) * (shapeButton.Size.Y.Offset)) shapeButton.Parent = dropDown dropDown.Size = UDim2.new(0,200,0,dropDown.Size.Y.Offset + (shapeButton.Size.Y.Offset)) end dropDown.MouseLeave:connect(function() dropDown.Visible = false end) end local function createDropDownMenuButton(parent) local dropDownButton = Instance.new("ImageButton") dropDownButton.Name = "DropDownButton" dropDownButton.Image = "http://www.roblox.com/asset/?id=67581509" dropDownButton.BackgroundTransparency = 1 dropDownButton.Size = UDim2.new(0,16,0,16) dropDownButton.Position = UDim2.new(1,-24,0,6) dropDownButton.ZIndex = parent.ZIndex + 2 dropDownButton.Parent = parent if not setGui:FindFirstChild("TerrainDropDown") then createTerrainDropDownMenu(8) end dropDownButton.MouseButton1Click:connect(function() setGui.TerrainDropDown.Visible = true setGui.TerrainDropDown.Position = UDim2.new(0,parent.AbsolutePosition.X,0,parent.AbsolutePosition.Y) currTerrainDropDownFrame = parent end) end local function buildInsertButton() local insertButton = makeInsertAssetButton() insertButton.Name = "InsertAssetButton" insertButton.Visible = true if Data.Category[Data.CurrentCategory].SetName == "High Scalability" then createDropDownMenuButton(insertButton) end local lastEnter = nil local mouseEnterCon = insertButton.MouseEnter:connect(function() lastEnter = insertButton delay(0.1,function() if lastEnter == insertButton then showLargePreview(insertButton) end end) end) return insertButton, mouseEnterCon end local function realignButtonGrid(columns) local x = 0 local y = 0 for i = 1, #insertButtons do insertButtons[i].Position = UDim2.new(0, buttonWidth * x, 0, buttonHeight * y) x = x + 1 if x >= columns then x = 0 y = y + 1 end end end local function setInsertButtonImageBehavior(insertFrame, visible, name, assetId) if visible then insertFrame.AssetName.Value = name insertFrame.AssetId.Value = assetId local newImageUrl = SmallThumbnailUrl .. assetId if newImageUrl ~= insertFrame.Button.ButtonImage.Image then delay(0,function() game:GetService("ContentProvider"):Preload(SmallThumbnailUrl .. assetId) if insertFrame:findFirstChild("Button") then insertFrame.Button.ButtonImage.Image = SmallThumbnailUrl .. assetId end end) end table.insert(insertButtonCons, insertFrame.Button.MouseButton1Click:connect(function() -- special case for water, show water selection gui local isWaterSelected = (name == "Water") and (Data.Category[Data.CurrentCategory].SetName == "High Scalability") waterGui.Visible = isWaterSelected if isWaterSelected then objectSelected(name, tonumber(assetId), nil) else objectSelected(name, tonumber(assetId)) end end) ) insertFrame.Visible = true else insertFrame.Visible = false end end local function loadSectionOfItems(setGui, rows, columns) local pageSize = rows * columns if arrayPosition > #contents then return end local origArrayPos = arrayPosition local yCopy = 0 for i = 1, pageSize + 1 do if arrayPosition >= #contents + 1 then break end local buttonCon insertButtons[arrayPosition], buttonCon = buildInsertButton() table.insert(insertButtonCons,buttonCon) insertButtons[arrayPosition].Parent = setGui.SetPanel.ItemsFrame arrayPosition = arrayPosition + 1 end realignButtonGrid(columns) local indexCopy = origArrayPos for index = origArrayPos, arrayPosition do if insertButtons[index] then if contents[index] then -- we don't want water to have a drop down button if contents[index].Name == "Water" then if Data.Category[Data.CurrentCategory].SetName == "High Scalability" then insertButtons[index]:FindFirstChild("DropDownButton",true):Destroy() end end local assetId if useAssetVersionId then assetId = contents[index].AssetVersionId else assetId = contents[index].AssetId end setInsertButtonImageBehavior(insertButtons[index], true, contents[index].Name, assetId) else break end else break end indexCopy = index end end local function setSetIndex() Data.Category[Data.CurrentCategory].Index = 0 rows = 7 columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth) contents = Data.Category[Data.CurrentCategory].Contents if contents then -- remove our buttons and their connections for i = 1, #insertButtons do insertButtons[i]:remove() end for i = 1, #insertButtonCons do if insertButtonCons[i] then insertButtonCons[i]:disconnect() end end insertButtonCons = {} insertButtons = {} arrayPosition = 1 loadSectionOfItems(setGui, rows, columns) end end local function selectSet(button, setName, setId, setIndex) if button and Data.Category[Data.CurrentCategory] ~= nil then if button ~= Data.Category[Data.CurrentCategory].Button then Data.Category[Data.CurrentCategory].Button = button if SetCache[setId] == nil then SetCache[setId] = game:GetService("InsertService"):GetCollection(setId) end Data.Category[Data.CurrentCategory].Contents = SetCache[setId] Data.Category[Data.CurrentCategory].SetName = setName Data.Category[Data.CurrentCategory].SetId = setId end setSetIndex() end end local function selectCategoryPage(buttons, page) if buttons ~= Data.CurrentCategory then if Data.CurrentCategory then for key, button in pairs(Data.CurrentCategory) do button.Visible = false end end Data.CurrentCategory = buttons if Data.Category[Data.CurrentCategory] == nil then Data.Category[Data.CurrentCategory] = {} if #buttons > 0 then selectSet(buttons[1], buttons[1].SetName.Value, buttons[1].SetId.Value, 0) end else Data.Category[Data.CurrentCategory].Button = nil selectSet(Data.Category[Data.CurrentCategory].ButtonFrame, Data.Category[Data.CurrentCategory].SetName, Data.Category[Data.CurrentCategory].SetId, Data.Category[Data.CurrentCategory].Index) end end end local function selectCategory(category) selectCategoryPage(category, 0) end local function resetAllSetButtonSelection() local setButtons = setGui.SetPanel.Sets.SetsLists:GetChildren() for i = 1, #setButtons do if setButtons[i]:IsA("TextButton") then setButtons[i].Selected = false setButtons[i].BackgroundTransparency = 1 setButtons[i].TextColor3 = Color3.new(1,1,1) setButtons[i].BackgroundColor3 = Color3.new(1,1,1) end end end local function populateSetsFrame() local currRow = 0 for i = 1, #userCategoryButtons do local button = userCategoryButtons[i] button.Visible = true button.Position = UDim2.new(0,5,0,currRow * button.Size.Y.Offset) button.Parent = setGui.SetPanel.Sets.SetsLists if i == 1 then -- we will have this selected by default, so show it button.Selected = true button.BackgroundColor3 = Color3.new(0,204/255,0) button.TextColor3 = Color3.new(0,0,0) button.BackgroundTransparency = 0 end button.MouseEnter:connect(function() if not button.Selected then button.BackgroundTransparency = 0 button.TextColor3 = Color3.new(0,0,0) end end) button.MouseLeave:connect(function() if not button.Selected then button.BackgroundTransparency = 1 button.TextColor3 = Color3.new(1,1,1) end end) button.MouseButton1Click:connect(function() resetAllSetButtonSelection() button.Selected = not button.Selected button.BackgroundColor3 = Color3.new(0,204/255,0) button.TextColor3 = Color3.new(0,0,0) button.BackgroundTransparency = 0 selectSet(button, button.Text, userCategoryButtons[i].SetId.Value, 0) end) currRow = currRow + 1 end local buttons = setGui.SetPanel.Sets.SetsLists:GetChildren() -- set first category as loaded for default if buttons then for i = 1, #buttons do if buttons[i]:IsA("TextButton") then selectSet(buttons[i], buttons[i].Text, userCategoryButtons[i].SetId.Value, 0) selectCategory(userCategoryButtons) break end end end end setGui = createSetGui() waterGui, waterTypeChangedEvent = createWaterGui() waterGui.Position = UDim2.new(0,55,0,0) waterGui.Parent = setGui setGui.Changed:connect(function(prop) -- this resizes the preview image to always be the right size if prop == "AbsoluteSize" then handleResize() setSetIndex() end end) local scrollFrame, controlFrame = t.CreateTrueScrollingFrame() scrollFrame.Size = UDim2.new(0.54,0,0.85,0) scrollFrame.Position = UDim2.new(0.24,0,0.085,0) scrollFrame.Name = "ItemsFrame" scrollFrame.ZIndex = 6 scrollFrame.Parent = setGui.SetPanel scrollFrame.BackgroundTransparency = 1 drillDownSetZIndex(controlFrame,7) controlFrame.Parent = setGui.SetPanel controlFrame.Position = UDim2.new(0.76, 5, 0, 0) local debounce = false controlFrame.ScrollBottom.Changed:connect(function(prop) if controlFrame.ScrollBottom.Value == true then if debounce then return end debounce = true loadSectionOfItems(setGui, rows, columns) debounce = false end end) local userData = {} for id = 1, #userIdsForSets do local newUserData = game:GetService("InsertService"):GetUserSets(userIdsForSets[id]) if newUserData and #newUserData > 2 then -- start at #3 to skip over My Decals and My Models for each account for category = 3, #newUserData do if newUserData[category].Name == "High Scalability" then -- we want high scalability parts to show first table.insert(userData,1,newUserData[category]) else table.insert(userData, newUserData[category]) end end end end if userData then userCategoryButtons = processCategory(userData) end rows = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.Y/buttonHeight) columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth) populateSetsFrame() insertPanelCloseCon = setGui.SetPanel.CancelButton.MouseButton1Click:connect(function() setGui.SetPanel.Visible = false if dialogClosed then dialogClosed() end end) local setVisibilityFunction = function(visible) if visible then setGui.SetPanel.Visible = true else setGui.SetPanel.Visible = false end end local getVisibilityFunction = function() if setGui then if setGui:FindFirstChild("SetPanel") then return setGui.SetPanel.Visible end end return false end return setGui, setVisibilityFunction, getVisibilityFunction, waterTypeChangedEvent end t.CreateTerrainMaterialSelector = function(size,position) local terrainMaterialSelectionChanged = Instance.new("BindableEvent") terrainMaterialSelectionChanged.Name = "TerrainMaterialSelectionChanged" local selectedButton = nil local frame = Instance.new("Frame") frame.Name = "TerrainMaterialSelector" if size then frame.Size = size else frame.Size = UDim2.new(0, 245, 0, 230) end if position then frame.Position = position end frame.BorderSizePixel = 0 frame.BackgroundColor3 = Color3.new(0,0,0) frame.Active = true terrainMaterialSelectionChanged.Parent = frame local waterEnabled = true -- todo: turn this on when water is ready local materialToImageMap = {} local materialNames = {"Grass", "Sand", "Brick", "Granite", "Asphalt", "Iron", "Aluminum", "Gold", "Plank", "Log", "Gravel", "Cinder Block", "Stone Wall", "Concrete", "Plastic (red)", "Plastic (blue)"} if waterEnabled then table.insert(materialNames,"Water") end local currentMaterial = 1 function getEnumFromName(choice) if choice == "Grass" then return 1 end if choice == "Sand" then return 2 end if choice == "Erase" then return 0 end if choice == "Brick" then return 3 end if choice == "Granite" then return 4 end if choice == "Asphalt" then return 5 end if choice == "Iron" then return 6 end if choice == "Aluminum" then return 7 end if choice == "Gold" then return 8 end if choice == "Plank" then return 9 end if choice == "Log" then return 10 end if choice == "Gravel" then return 11 end if choice == "Cinder Block" then return 12 end if choice == "Stone Wall" then return 13 end if choice == "Concrete" then return 14 end if choice == "Plastic (red)" then return 15 end if choice == "Plastic (blue)" then return 16 end if choice == "Water" then return 17 end end function getNameFromEnum(choice) if choice == Enum.CellMaterial.Grass or choice == 1 then return "Grass"end if choice == Enum.CellMaterial.Sand or choice == 2 then return "Sand" end if choice == Enum.CellMaterial.Empty or choice == 0 then return "Erase" end if choice == Enum.CellMaterial.Brick or choice == 3 then return "Brick" end if choice == Enum.CellMaterial.Granite or choice == 4 then return "Granite" end if choice == Enum.CellMaterial.Asphalt or choice == 5 then return "Asphalt" end if choice == Enum.CellMaterial.Iron or choice == 6 then return "Iron" end if choice == Enum.CellMaterial.Aluminum or choice == 7 then return "Aluminum" end if choice == Enum.CellMaterial.Gold or choice == 8 then return "Gold" end if choice == Enum.CellMaterial.WoodPlank or choice == 9 then return "Plank" end if choice == Enum.CellMaterial.WoodLog or choice == 10 then return "Log" end if choice == Enum.CellMaterial.Gravel or choice == 11 then return "Gravel" end if choice == Enum.CellMaterial.CinderBlock or choice == 12 then return "Cinder Block" end if choice == Enum.CellMaterial.MossyStone or choice == 13 then return "Stone Wall" end if choice == Enum.CellMaterial.Cement or choice == 14 then return "Concrete" end if choice == Enum.CellMaterial.RedPlastic or choice == 15 then return "Plastic (red)" end if choice == Enum.CellMaterial.BluePlastic or choice == 16 then return "Plastic (blue)" end if waterEnabled then if choice == Enum.CellMaterial.Water or choice == 17 then return "Water" end end end local function updateMaterialChoice(choice) currentMaterial = getEnumFromName(choice) terrainMaterialSelectionChanged:Fire(currentMaterial) end -- we so need a better way to do this for i,v in pairs(materialNames) do materialToImageMap[v] = {} if v == "Grass" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=56563112" elseif v == "Sand" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=62356652" elseif v == "Brick" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=65961537" elseif v == "Granite" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532153" elseif v == "Asphalt" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532038" elseif v == "Iron" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532093" elseif v == "Aluminum" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531995" elseif v == "Gold" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532118" elseif v == "Plastic (red)" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531848" elseif v == "Plastic (blue)" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531924" elseif v == "Plank" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532015" elseif v == "Log" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532051" elseif v == "Gravel" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532206" elseif v == "Cinder Block" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532103" elseif v == "Stone Wall" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531804" elseif v == "Concrete" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532059" elseif v == "Water" then materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=81407474" else materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=66887593" -- fill in the rest here!! end end local scrollFrame, scrollUp, scrollDown, recalculateScroll = t.CreateScrollingFrame(nil,"grid") scrollFrame.Size = UDim2.new(0.85,0,1,0) scrollFrame.Position = UDim2.new(0,0,0,0) scrollFrame.Parent = frame scrollUp.Parent = frame scrollUp.Visible = true scrollUp.Position = UDim2.new(1,-19,0,0) scrollDown.Parent = frame scrollDown.Visible = true scrollDown.Position = UDim2.new(1,-19,1,-17) local function goToNewMaterial(buttonWrap, materialName) updateMaterialChoice(materialName) buttonWrap.BackgroundTransparency = 0 selectedButton.BackgroundTransparency = 1 selectedButton = buttonWrap end local function createMaterialButton(name) local buttonWrap = Instance.new("TextButton") buttonWrap.Text = "" buttonWrap.Size = UDim2.new(0,32,0,32) buttonWrap.BackgroundColor3 = Color3.new(1,1,1) buttonWrap.BorderSizePixel = 0 buttonWrap.BackgroundTransparency = 1 buttonWrap.AutoButtonColor = false buttonWrap.Name = tostring(name) local imageButton = Instance.new("ImageButton") imageButton.AutoButtonColor = false imageButton.BackgroundTransparency = 1 imageButton.Size = UDim2.new(0,30,0,30) imageButton.Position = UDim2.new(0,1,0,1) imageButton.Name = tostring(name) imageButton.Parent = buttonWrap imageButton.Image = materialToImageMap[name].Regular local enumType = Instance.new("NumberValue") enumType.Name = "EnumType" enumType.Parent = buttonWrap enumType.Value = 0 imageButton.MouseEnter:connect(function() buttonWrap.BackgroundTransparency = 0 end) imageButton.MouseLeave:connect(function() if selectedButton ~= buttonWrap then buttonWrap.BackgroundTransparency = 1 end end) imageButton.MouseButton1Click:connect(function() if selectedButton ~= buttonWrap then goToNewMaterial(buttonWrap, tostring(name)) end end) return buttonWrap end for i = 1, #materialNames do local imageButton = createMaterialButton(materialNames[i]) if materialNames[i] == "Grass" then -- always start with grass as the default selectedButton = imageButton imageButton.BackgroundTransparency = 0 end imageButton.Parent = scrollFrame end local forceTerrainMaterialSelection = function(newMaterialType) if not newMaterialType then return end if currentMaterial == newMaterialType then return end local matName = getNameFromEnum(newMaterialType) local buttons = scrollFrame:GetChildren() for i = 1, #buttons do if buttons[i].Name == "Plastic (blue)" and matName == "Plastic (blue)" then goToNewMaterial(buttons[i],matName) return end if buttons[i].Name == "Plastic (red)" and matName == "Plastic (red)" then goToNewMaterial(buttons[i],matName) return end if string.find(buttons[i].Name, matName) then goToNewMaterial(buttons[i],matName) return end end end frame.Changed:connect(function ( prop ) if prop == "AbsoluteSize" then recalculateScroll() end end) recalculateScroll() return frame, terrainMaterialSelectionChanged, forceTerrainMaterialSelection end t.CreateLoadingFrame = function(name,size,position) game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=35238053") local loadingFrame = Instance.new("Frame") loadingFrame.Name = "LoadingFrame" loadingFrame.Style = Enum.FrameStyle.RobloxRound if size then loadingFrame.Size = size else loadingFrame.Size = UDim2.new(0,300,0,160) end if position then loadingFrame.Position = position else loadingFrame.Position = UDim2.new(0.5, -150, 0.5,-80) end local loadingBar = Instance.new("Frame") loadingBar.Name = "LoadingBar" loadingBar.BackgroundColor3 = Color3.new(0,0,0) loadingBar.BorderColor3 = Color3.new(79/255,79/255,79/255) loadingBar.Position = UDim2.new(0,0,0,41) loadingBar.Size = UDim2.new(1,0,0,30) loadingBar.Parent = loadingFrame local loadingGreenBar = Instance.new("ImageLabel") loadingGreenBar.Name = "LoadingGreenBar" loadingGreenBar.Image = "http://www.roblox.com/asset/?id=35238053" loadingGreenBar.Position = UDim2.new(0,0,0,0) loadingGreenBar.Size = UDim2.new(0,0,1,0) loadingGreenBar.Visible = false loadingGreenBar.Parent = loadingBar local loadingPercent = Instance.new("TextLabel") loadingPercent.Name = "LoadingPercent" loadingPercent.BackgroundTransparency = 1 loadingPercent.Position = UDim2.new(0,0,1,0) loadingPercent.Size = UDim2.new(1,0,0,14) loadingPercent.Font = Enum.Font.Arial loadingPercent.Text = "0%" loadingPercent.FontSize = Enum.FontSize.Size14 loadingPercent.TextColor3 = Color3.new(1,1,1) loadingPercent.Parent = loadingBar local cancelButton = Instance.new("TextButton") cancelButton.Name = "CancelButton" cancelButton.Position = UDim2.new(0.5,-60,1,-40) cancelButton.Size = UDim2.new(0,120,0,40) cancelButton.Font = Enum.Font.Arial cancelButton.FontSize = Enum.FontSize.Size18 cancelButton.TextColor3 = Color3.new(1,1,1) cancelButton.Text = "Cancel" cancelButton.Style = Enum.ButtonStyle.RobloxButton cancelButton.Parent = loadingFrame local loadingName = Instance.new("TextLabel") loadingName.Name = "loadingName" loadingName.BackgroundTransparency = 1 loadingName.Size = UDim2.new(1,0,0,18) loadingName.Position = UDim2.new(0,0,0,2) loadingName.Font = Enum.Font.Arial loadingName.Text = name loadingName.TextColor3 = Color3.new(1,1,1) loadingName.TextStrokeTransparency = 1 loadingName.FontSize = Enum.FontSize.Size18 loadingName.Parent = loadingFrame local cancelButtonClicked = Instance.new("BindableEvent") cancelButtonClicked.Name = "CancelButtonClicked" cancelButtonClicked.Parent = cancelButton cancelButton.MouseButton1Click:connect(function() cancelButtonClicked:Fire() end) local updateLoadingGuiPercent = function(percent, tweenAction, tweenLength) if percent and type(percent) ~= "number" then error("updateLoadingGuiPercent expects number as argument, got",type(percent),"instead") end local newSize = nil if percent < 0 then newSize = UDim2.new(0,0,1,0) elseif percent > 1 then newSize = UDim2.new(1,0,1,0) else newSize = UDim2.new(percent,0,1,0) end if tweenAction then if not tweenLength then error("updateLoadingGuiPercent is set to tween new percentage, but got no tween time length! Please pass this in as third argument") end if (newSize.X.Scale > 0) then loadingGreenBar.Visible = true loadingGreenBar:TweenSize( newSize, Enum.EasingDirection.Out, Enum.EasingStyle.Quad, tweenLength, true) else loadingGreenBar:TweenSize( newSize, Enum.EasingDirection.Out, Enum.EasingStyle.Quad, tweenLength, true, function() if (newSize.X.Scale < 0) then loadingGreenBar.Visible = false end end) end else loadingGreenBar.Size = newSize loadingGreenBar.Visible = (newSize.X.Scale > 0) end end loadingGreenBar.Changed:connect(function(prop) if prop == "Size" then loadingPercent.Text = tostring( math.ceil(loadingGreenBar.Size.X.Scale * 100) ) .. "%" end end) return loadingFrame, updateLoadingGuiPercent, cancelButtonClicked end t.CreatePluginFrame = function (name,size,position,scrollable,parent) function createMenuButton(size,position,text,fontsize,name,parent) local button = Instance.new("TextButton",parent) button.AutoButtonColor = false button.Name = name button.BackgroundTransparency = 1 button.Position = position button.Size = size button.Font = Enum.Font.ArialBold button.FontSize = fontsize button.Text = text button.TextColor3 = Color3.new(1,1,1) button.BorderSizePixel = 0 button.BackgroundColor3 = Color3.new(20/255,20/255,20/255) button.MouseEnter:connect(function ( ) if button.Selected then return end button.BackgroundTransparency = 0 end) button.MouseLeave:connect(function ( ) if button.Selected then return end button.BackgroundTransparency = 1 end) return button end local dragBar = Instance.new("Frame",parent) dragBar.Name = tostring(name) .. "DragBar" dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255) dragBar.BorderColor3 = Color3.new(0,0,0) if size then dragBar.Size = UDim2.new(size.X.Scale,size.X.Offset,0,20) + UDim2.new(0,20,0,0) else dragBar.Size = UDim2.new(0,183,0,20) end if position then dragBar.Position = position end dragBar.Active = true dragBar.Draggable = true --dragBar.Visible = false dragBar.MouseEnter:connect(function ( ) dragBar.BackgroundColor3 = Color3.new(49/255,49/255,49/255) end) dragBar.MouseLeave:connect(function ( ) dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255) end) -- plugin name label local pluginNameLabel = Instance.new("TextLabel",dragBar) pluginNameLabel.Name = "BarNameLabel" pluginNameLabel.Text = " " .. tostring(name) pluginNameLabel.TextColor3 = Color3.new(1,1,1) pluginNameLabel.TextStrokeTransparency = 0 pluginNameLabel.Size = UDim2.new(1,0,1,0) pluginNameLabel.Font = Enum.Font.ArialBold pluginNameLabel.FontSize = Enum.FontSize.Size18 pluginNameLabel.TextXAlignment = Enum.TextXAlignment.Left pluginNameLabel.BackgroundTransparency = 1 -- close button local closeButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-16,0.5,-8),"X",Enum.FontSize.Size14,"CloseButton",dragBar) local closeEvent = Instance.new("BindableEvent") closeEvent.Name = "CloseEvent" closeEvent.Parent = closeButton closeButton.MouseButton1Click:connect(function () closeEvent:Fire() closeButton.BackgroundTransparency = 1 end) -- help button local helpButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-51,0.5,-8),"?",Enum.FontSize.Size14,"HelpButton",dragBar) local helpFrame = Instance.new("Frame",dragBar) helpFrame.Name = "HelpFrame" helpFrame.BackgroundColor3 = Color3.new(0,0,0) helpFrame.Size = UDim2.new(0,300,0,552) helpFrame.Position = UDim2.new(1,5,0,0) helpFrame.Active = true helpFrame.BorderSizePixel = 0 helpFrame.Visible = false helpButton.MouseButton1Click:connect(function( ) helpFrame.Visible = not helpFrame.Visible if helpFrame.Visible then helpButton.Selected = true helpButton.BackgroundTransparency = 0 local screenGui = getScreenGuiAncestor(helpFrame) if screenGui then if helpFrame.AbsolutePosition.X + helpFrame.AbsoluteSize.X > screenGui.AbsoluteSize.X then --position on left hand side helpFrame.Position = UDim2.new(0,-5 - helpFrame.AbsoluteSize.X,0,0) else -- position on right hand side helpFrame.Position = UDim2.new(1,5,0,0) end else helpFrame.Position = UDim2.new(1,5,0,0) end else helpButton.Selected = false helpButton.BackgroundTransparency = 1 end end) local minimizeButton = createMenuButton(UDim2.new(0,16,0,17),UDim2.new(1,-34,0.5,-8),"-",Enum.FontSize.Size14,"MinimizeButton",dragBar) minimizeButton.TextYAlignment = Enum.TextYAlignment.Top local minimizeFrame = Instance.new("Frame",dragBar) minimizeFrame.Name = "MinimizeFrame" minimizeFrame.BackgroundColor3 = Color3.new(73/255,73/255,73/255) minimizeFrame.BorderColor3 = Color3.new(0,0,0) minimizeFrame.Position = UDim2.new(0,0,1,0) if size then minimizeFrame.Size = UDim2.new(size.X.Scale,size.X.Offset,0,50) + UDim2.new(0,20,0,0) else minimizeFrame.Size = UDim2.new(0,183,0,50) end minimizeFrame.Visible = false local minimizeBigButton = Instance.new("TextButton",minimizeFrame) minimizeBigButton.Position = UDim2.new(0.5,-50,0.5,-20) minimizeBigButton.Name = "MinimizeButton" minimizeBigButton.Size = UDim2.new(0,100,0,40) minimizeBigButton.Style = Enum.ButtonStyle.RobloxButton minimizeBigButton.Font = Enum.Font.ArialBold minimizeBigButton.FontSize = Enum.FontSize.Size18 minimizeBigButton.TextColor3 = Color3.new(1,1,1) minimizeBigButton.Text = "Show" local separatingLine = Instance.new("Frame",dragBar) separatingLine.Name = "SeparatingLine" separatingLine.BackgroundColor3 = Color3.new(115/255,115/255,115/255) separatingLine.BorderSizePixel = 0 separatingLine.Position = UDim2.new(1,-18,0.5,-7) separatingLine.Size = UDim2.new(0,1,0,14) local otherSeparatingLine = separatingLine:clone() otherSeparatingLine.Position = UDim2.new(1,-35,0.5,-7) otherSeparatingLine.Parent = dragBar local widgetContainer = Instance.new("Frame",dragBar) widgetContainer.Name = "WidgetContainer" widgetContainer.BackgroundTransparency = 1 widgetContainer.Position = UDim2.new(0,0,1,0) widgetContainer.BorderColor3 = Color3.new(0,0,0) if not scrollable then widgetContainer.BackgroundTransparency = 0 widgetContainer.BackgroundColor3 = Color3.new(72/255,72/255,72/255) end if size then if scrollable then widgetContainer.Size = size else widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,size.Y.Scale,size.Y.Offset) end else if scrollable then widgetContainer.Size = UDim2.new(0,163,0,400) else widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,0,400) end end if position then widgetContainer.Position = position + UDim2.new(0,0,0,20) end local frame,control,verticalDragger = nil if scrollable then --frame for widgets frame,control = t.CreateTrueScrollingFrame() frame.Size = UDim2.new(1, 0, 1, 0) frame.BackgroundColor3 = Color3.new(72/255,72/255,72/255) frame.BorderColor3 = Color3.new(0,0,0) frame.Active = true frame.Parent = widgetContainer control.Parent = dragBar control.BackgroundColor3 = Color3.new(72/255,72/255,72/255) control.BorderSizePixel = 0 control.BackgroundTransparency = 0 control.Position = UDim2.new(1,-21,1,1) if size then control.Size = UDim2.new(0,21,size.Y.Scale,size.Y.Offset) else control.Size = UDim2.new(0,21,0,400) end control:FindFirstChild("ScrollDownButton").Position = UDim2.new(0,0,1,-20) local fakeLine = Instance.new("Frame",control) fakeLine.Name = "FakeLine" fakeLine.BorderSizePixel = 0 fakeLine.BackgroundColor3 = Color3.new(0,0,0) fakeLine.Size = UDim2.new(0,1,1,1) fakeLine.Position = UDim2.new(1,0,0,0) verticalDragger = Instance.new("TextButton",widgetContainer) verticalDragger.ZIndex = 2 verticalDragger.AutoButtonColor = false verticalDragger.Name = "VerticalDragger" verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255) verticalDragger.BorderColor3 = Color3.new(0,0,0) verticalDragger.Size = UDim2.new(1,20,0,20) verticalDragger.Position = UDim2.new(0,0,1,0) verticalDragger.Active = true verticalDragger.Text = "" local scrubFrame = Instance.new("Frame",verticalDragger) scrubFrame.Name = "ScrubFrame" scrubFrame.BackgroundColor3 = Color3.new(1,1,1) scrubFrame.BorderSizePixel = 0 scrubFrame.Position = UDim2.new(0.5,-5,0.5,0) scrubFrame.Size = UDim2.new(0,10,0,1) scrubFrame.ZIndex = 5 local scrubTwo = scrubFrame:clone() scrubTwo.Position = UDim2.new(0.5,-5,0.5,-2) scrubTwo.Parent = verticalDragger local scrubThree = scrubFrame:clone() scrubThree.Position = UDim2.new(0.5,-5,0.5,2) scrubThree.Parent = verticalDragger local areaSoak = Instance.new("TextButton",getScreenGuiAncestor(parent)) areaSoak.Name = "AreaSoak" areaSoak.Size = UDim2.new(1,0,1,0) areaSoak.BackgroundTransparency = 1 areaSoak.BorderSizePixel = 0 areaSoak.Text = "" areaSoak.ZIndex = 10 areaSoak.Visible = false areaSoak.Active = true local draggingVertical = false local startYPos = nil verticalDragger.MouseEnter:connect(function () verticalDragger.BackgroundColor3 = Color3.new(60/255,60/255,60/255) end) verticalDragger.MouseLeave:connect(function () verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255) end) verticalDragger.MouseButton1Down:connect(function(x,y) draggingVertical = true areaSoak.Visible = true startYPos = y end) areaSoak.MouseButton1Up:connect(function ( ) draggingVertical = false areaSoak.Visible = false end) areaSoak.MouseMoved:connect(function(x,y) if not draggingVertical then return end local yDelta = y - startYPos if not control.ScrollDownButton.Visible and yDelta > 0 then return end if (widgetContainer.Size.Y.Offset + yDelta) < 150 then widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,150) control.Size = UDim2.new (0,21,0,150) return end startYPos = y if widgetContainer.Size.Y.Offset + yDelta >= 0 then widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,widgetContainer.Size.Y.Offset + yDelta) control.Size = UDim2.new(0,21,0,control.Size.Y.Offset + yDelta ) end end) end local function switchMinimize() minimizeFrame.Visible = not minimizeFrame.Visible if scrollable then frame.Visible = not frame.Visible verticalDragger.Visible = not verticalDragger.Visible control.Visible = not control.Visible else widgetContainer.Visible = not widgetContainer.Visible end if minimizeFrame.Visible then minimizeButton.Text = "+" else minimizeButton.Text = "-" end end minimizeBigButton.MouseButton1Click:connect(function ( ) switchMinimize() end) minimizeButton.MouseButton1Click:connect(function( ) switchMinimize() end) if scrollable then return dragBar, frame, helpFrame, closeEvent else return dragBar, widgetContainer, helpFrame, closeEvent end end t.Help = function(funcNameOrFunc) --input argument can be a string or a function. Should return a description (of arguments and expected side effects) if funcNameOrFunc == "CreatePropertyDropDownMenu" or funcNameOrFunc == t.CreatePropertyDropDownMenu then return "Function CreatePropertyDropDownMenu. " .. "Arguments: (instance, propertyName, enumType). " .. "Side effect: returns a container with a drop-down-box that is linked to the 'property' field of 'instance' which is of type 'enumType'" end if funcNameOrFunc == "CreateDropDownMenu" or funcNameOrFunc == t.CreateDropDownMenu then return "Function CreateDropDownMenu. " .. "Arguments: (items, onItemSelected). " .. "Side effect: Returns 2 results, a container to the gui object and a 'updateSelection' function for external updating. The container is a drop-down-box created around a list of items" end if funcNameOrFunc == "CreateMessageDialog" or funcNameOrFunc == t.CreateMessageDialog then return "Function CreateMessageDialog. " .. "Arguments: (title, message, buttons). " .. "Side effect: Returns a gui object of a message box with 'title' and 'message' as passed in. 'buttons' input is an array of Tables contains a 'Text' and 'Function' field for the text/callback of each button" end if funcNameOrFunc == "CreateStyledMessageDialog" or funcNameOrFunc == t.CreateStyledMessageDialog then return "Function CreateStyledMessageDialog. " .. "Arguments: (title, message, style, buttons). " .. "Side effect: Returns a gui object of a message box with 'title' and 'message' as passed in. 'buttons' input is an array of Tables contains a 'Text' and 'Function' field for the text/callback of each button, 'style' is a string, either Error, Notify or Confirm" end if funcNameOrFunc == "GetFontHeight" or funcNameOrFunc == t.GetFontHeight then return "Function GetFontHeight. " .. "Arguments: (font, fontSize). " .. "Side effect: returns the size in pixels of the given font + fontSize" end if funcNameOrFunc == "LayoutGuiObjects" or funcNameOrFunc == t.LayoutGuiObjects then end if funcNameOrFunc == "CreateScrollingFrame" or funcNameOrFunc == t.CreateScrollingFrame then return "Function CreateScrollingFrame. " .. "Arguments: (orderList, style) " .. "Side effect: returns 4 objects, (scrollFrame, scrollUpButton, scrollDownButton, recalculateFunction). 'scrollFrame' can be filled with GuiObjects. It will lay them out and allow scrollUpButton/scrollDownButton to interact with them. Orderlist is optional (and specifies the order to layout the children. Without orderlist, it uses the children order. style is also optional, and allows for a 'grid' styling if style is passed 'grid' as a string. recalculateFunction can be called when a relayout is needed (when orderList changes)" end if funcNameOrFunc == "CreateTrueScrollingFrame" or funcNameOrFunc == t.CreateTrueScrollingFrame then return "Function CreateTrueScrollingFrame. " .. "Arguments: (nil) " .. "Side effect: returns 2 objects, (scrollFrame, controlFrame). 'scrollFrame' can be filled with GuiObjects, and they will be clipped if not inside the frame's bounds. controlFrame has children scrollup and scrolldown, as well as a slider. controlFrame can be parented to any guiobject and it will readjust itself to fit." end if funcNameOrFunc == "AutoTruncateTextObject" or funcNameOrFunc == t.AutoTruncateTextObject then return "Function AutoTruncateTextObject. " .. "Arguments: (textLabel) " .. "Side effect: returns 2 objects, (textLabel, changeText). The 'textLabel' input is modified to automatically truncate text (with ellipsis), if it gets too small to fit. 'changeText' is a function that can be used to change the text, it takes 1 string as an argument" end if funcNameOrFunc == "CreateSlider" or funcNameOrFunc == t.CreateSlider then return "Function CreateSlider. " .. "Arguments: (steps, width, position) " .. "Side effect: returns 2 objects, (sliderGui, sliderPosition). The 'steps' argument specifies how many different positions the slider can hold along the bar. 'width' specifies in pixels how wide the bar should be (modifiable afterwards if desired). 'position' argument should be a UDim2 for slider positioning. 'sliderPosition' is an IntValue whose current .Value specifies the specific step the slider is currently on." end if funcNameOrFunc == "CreateSliderNew" or funcNameOrFunc == t.CreateSliderNew then return "Function CreateSliderNew. " .. "Arguments: (steps, width, position) " .. "Side effect: returns 2 objects, (sliderGui, sliderPosition). The 'steps' argument specifies how many different positions the slider can hold along the bar. 'width' specifies in pixels how wide the bar should be (modifiable afterwards if desired). 'position' argument should be a UDim2 for slider positioning. 'sliderPosition' is an IntValue whose current .Value specifies the specific step the slider is currently on." end if funcNameOrFunc == "CreateLoadingFrame" or funcNameOrFunc == t.CreateLoadingFrame then return "Function CreateLoadingFrame. " .. "Arguments: (name, size, position) " .. "Side effect: Creates a gui that can be manipulated to show progress for a particular action. Name appears above the loading bar, and size and position are udim2 values (both size and position are optional arguments). Returns 3 arguments, the first being the gui created. The second being updateLoadingGuiPercent, which is a bindable function. This function takes one argument (two optionally), which should be a number between 0 and 1, representing the percentage the loading gui should be at. The second argument to this function is a boolean value that if set to true will tween the current percentage value to the new percentage value, therefore our third argument is how long this tween should take. Our third returned argument is a BindableEvent, that when fired means that someone clicked the cancel button on the dialog." end if funcNameOrFunc == "CreateTerrainMaterialSelector" or funcNameOrFunc == t.CreateTerrainMaterialSelector then return "Function CreateTerrainMaterialSelector. " .. "Arguments: (size, position) " .. "Side effect: Size and position are UDim2 values that specifies the selector's size and position. Both size and position are optional arguments. This method returns 3 objects (terrainSelectorGui, terrainSelected, forceTerrainSelection). terrainSelectorGui is just the gui object that we generate with this function, parent it as you like. TerrainSelected is a BindableEvent that is fired whenever a new terrain type is selected in the gui. ForceTerrainSelection is a function that takes an argument of Enum.CellMaterial and will force the gui to show that material as currently selected." end end local function waitForChild(instance, name) while not instance:FindFirstChild(name) do instance.ChildAdded:wait() end end local function waitForProperty(instance, property) while not instance[property] do instance.Changed:wait() end end -- A Few Script Globals local gui = script.Parent.ControlFrame local helpButton = nil local updateCameraDropDownSelection = nil local updateVideoCaptureDropDownSelection = nil local tweenTime = 0.2 local mouseLockLookScreenUrl = "http://www.roblox.com/asset?id=54071825" local classicLookScreenUrl = "http://www.roblox.com/Asset?id=45915798" local hasGraphicsSlider = yes local GraphicsQualityLevels = true local recordingVideo = false local currentMenuSelection = nil local lastMenuSelection = {} local defaultPosition = UDim2.new(0,0,0,0) local newGuiPlaces = {0,41324860} local centerDialogs = {} local mainShield = nil local inStudioMode = false local macClient = false local success, isMac = pcall(function() return not game.GuiService.IsWindows end) macClient = success and isMac local function Color3I(r,g,b) return Color3.new(r/255,g/255,b/255) end local function robloxLock(instance) end function resumeGameFunction(shield) shield.Settings:TweenPosition(UDim2.new(0.5, -262,-0.5, -200),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true) delay(tweenTime,function() shield.Visible = false for i = 1, #centerDialogs do centerDialogs[i].Visible = false game.GuiService:RemoveCenterDialog(centerDialogs[i]) end settingsButton.Active = true currentMenuSelection = nil lastMenuSelection = {} end) end function goToMenu(container,menuName, moveDirection,size,position) if type(menuName) ~= "string" then return end table.insert(lastMenuSelection,currentMenuSelection) if menuName == "GameMainMenu" then lastMenuSelection = {} end local containerChildren = container:GetChildren() local selectedMenu = false for i = 1, #containerChildren do if containerChildren[i].Name == menuName then containerChildren[i].Visible = true currentMenuSelection = {container = container,name = menuName, direction = moveDirection, lastSize = size} selectedMenu = true if size and position then containerChildren[i]:TweenSizeAndPosition(size,position,Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true) elseif size then containerChildren[i]:TweenSizeAndPosition(size,UDim2.new(0.5,-size.X.Offset/2,0.5,-size.Y.Offset/2),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true) else containerChildren[i]:TweenPosition(UDim2.new(0,0,0,0),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true) end else if moveDirection == "left" then containerChildren[i]:TweenPosition(UDim2.new(-1,-525,0,0),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true) elseif moveDirection == "right" then containerChildren[i]:TweenPosition(UDim2.new(1,525,0,0),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true) elseif moveDirection == "up" then containerChildren[i]:TweenPosition(UDim2.new(0,0,-1,-400),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true) elseif moveDirection == "down" then containerChildren[i]:TweenPosition(UDim2.new(0,0,1,400),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true) end delay(tweenTime,function() containerChildren[i].Visible = false end) end end end function resetLocalCharacter() local player = game.Players.LocalPlayer if player then if player.Character and player.Character:FindFirstChild("Humanoid") then player.Character.Humanoid.Health = 0 end end end local function createTextButton(text,style,fontSize,buttonSize,buttonPosition) local newTextButton = Instance.new("TextButton") newTextButton.Font = Enum.Font.Arial newTextButton.FontSize = fontSize newTextButton.Size = buttonSize newTextButton.Position = buttonPosition newTextButton.Style = style newTextButton.TextColor3 = Color3.new(1,1,1) newTextButton.Text = text return newTextButton end local function CreateTextButtons(frame, buttons, yPos, ySize) if #buttons < 1 then error("Must have more than one button") end local buttonNum = 1 local buttonObjs = {} local function toggleSelection(button) for i, obj in ipairs(buttonObjs) do if obj == button then obj.Style = Enum.ButtonStyle.RobloxButtonDefault else obj.Style = Enum.ButtonStyle.RobloxButton end end end for i, obj in ipairs(buttons) do local button = Instance.new("TextButton") button.Name = "Button" .. buttonNum button.Font = Enum.Font.Arial button.FontSize = Enum.FontSize.Size18 button.AutoButtonColor = true button.Style = Enum.ButtonStyle.RobloxButton button.Text = obj.Text button.TextColor3 = Color3.new(1,1,1) button.MouseButton1Click:connect(function() toggleSelection(button) obj.Function() end) button.Parent = frame buttonObjs[buttonNum] = button buttonNum = buttonNum + 1 end toggleSelection(buttonObjs[1]) local numButtons = buttonNum-1 if numButtons == 1 then frame.Button1.Position = UDim2.new(0.35, 0, yPos.Scale, yPos.Offset) frame.Button1.Size = UDim2.new(.4,0,ySize.Scale, ySize.Offset) elseif numButtons == 2 then frame.Button1.Position = UDim2.new(0.1, 0, yPos.Scale, yPos.Offset) frame.Button1.Size = UDim2.new(.35,0, ySize.Scale, ySize.Offset) frame.Button2.Position = UDim2.new(0.55, 0, yPos.Scale, yPos.Offset) frame.Button2.Size = UDim2.new(.35,0, ySize.Scale, ySize.Offset) elseif numButtons >= 3 then local spacing = .1 / numButtons local buttonSize = .9 / numButtons buttonNum = 1 while buttonNum <= numButtons do buttonObjs[buttonNum].Position = UDim2.new(spacing*buttonNum + (buttonNum-1) * buttonSize, 0, yPos.Scale, yPos.Offset) buttonObjs[buttonNum].Size = UDim2.new(buttonSize, 0, ySize.Scale, ySize.Offset) buttonNum = buttonNum + 1 end end end function setRecordGui(recording, stopRecordButton, recordVideoButton) if recording then stopRecordButton.Visible = true recordVideoButton.Text = "Stop Recording" else stopRecordButton.Visible = false recordVideoButton.Text = "Record Video" end end function recordVideoClick(recordVideoButton, stopRecordButton) recordingVideo = not recordingVideo setRecordGui(recordingVideo, stopRecordButton, recordVideoButton) end function backToGame(buttonClicked, shield, settingsButton) buttonClicked.Parent.Parent.Parent.Parent.Visible = false shield.Visible = false for i = 1, #centerDialogs do game.GuiService:RemoveCenterDialog(centerDialogs[i]) centerDialogs[i].Visible = false end centerDialogs = {} game.GuiService:RemoveCenterDialog(shield) settingsButton.Active = true end function setDisabledState(guiObject) if not guiObject then return end if guiObject:IsA("TextLabel") then guiObject.TextTransparency = 0.9 elseif guiObject:IsA("TextButton") then guiObject.TextTransparency = 0.9 guiObject.Active = false else if guiObject["ClassName"] then print("setDisabledState() got object of unsupported type. object type is ",guiObject.ClassName) end end end local function createHelpDialog(baseZIndex) if helpButton == nil then if gui:FindFirstChild("TopLeftControl") and gui.TopLeftControl:FindFirstChild("Help") then helpButton = gui.TopLeftControl.Help elseif gui:FindFirstChild("BottomRightControl") and gui.BottomRightControl:FindFirstChild("Help") then helpButton = gui.BottomRightControl.Help end end local shield = Instance.new("Frame") shield.Name = "HelpDialogShield" shield.Active = true shield.Visible = false shield.Size = UDim2.new(1,0,1,0) shield.BackgroundColor3 = Color3I(51,51,51) shield.BorderColor3 = Color3I(27,42,53) shield.BackgroundTransparency = 0.4 shield.ZIndex = baseZIndex + 1 shield.Parent = gui local helpDialog = Instance.new("Frame") helpDialog.Name = "HelpDialog" helpDialog.Style = Enum.FrameStyle.RobloxRound helpDialog.Position = UDim2.new(.2, 0, .2, 0) helpDialog.Size = UDim2.new(0.6, 0, 0.6, 0) helpDialog.Active = true helpDialog.Parent = shield local titleLabel = Instance.new("TextLabel") titleLabel.Name = "Title" titleLabel.Text = "Keyboard & Mouse Controls" titleLabel.Font = Enum.Font.ArialBold titleLabel.FontSize = Enum.FontSize.Size36 titleLabel.Position = UDim2.new(0, 0, 0.025, 0) titleLabel.Size = UDim2.new(1, 0, 0, 40) titleLabel.TextColor3 = Color3.new(1,1,1) titleLabel.BackgroundTransparency = 1 titleLabel.Parent = helpDialog local buttonRow = Instance.new("Frame") buttonRow.Name = "Buttons" buttonRow.Position = UDim2.new(0.1, 0, .07, 40) buttonRow.Size = UDim2.new(0.8, 0, 0, 45) buttonRow.BackgroundTransparency = 1 buttonRow.Parent = helpDialog local imageFrame = Instance.new("Frame") imageFrame.Name = "ImageFrame" imageFrame.Position = UDim2.new(0.05, 0, 0.075, 80) imageFrame.Size = UDim2.new(0.9, 0, .9, -120) imageFrame.BackgroundTransparency = 1 imageFrame.Parent = helpDialog local layoutFrame = Instance.new("Frame") layoutFrame.Name = "LayoutFrame" layoutFrame.Position = UDim2.new(0.5, 0, 0, 0) layoutFrame.Size = UDim2.new(1.5, 0, 1, 0) layoutFrame.BackgroundTransparency = 1 layoutFrame.SizeConstraint = Enum.SizeConstraint.RelativeYY layoutFrame.Parent = imageFrame local image = Instance.new("ImageLabel") image.Name = "Image" image.Image = classicLookScreenUrl image.Position = UDim2.new(-0.5, 0, 0, 0) image.Size = UDim2.new(1, 0, 1, 0) image.BackgroundTransparency = 1 image.Parent = layoutFrame local buttons = {} buttons[1] = {} buttons[1].Text = "Look" buttons[1].Function = function() if UserSettings().GameSettings.ControlMode == Enum.ControlMode["Mouse Lock Switch"] then image.Image = mouseLockLookScreenUrl else image.Image = classicLookScreenUrl end end buttons[2] = {} buttons[2].Text = "Move" buttons[2].Function = function() image.Image = "http://www.roblox.com/Asset?id=45915811" end buttons[3] = {} buttons[3].Text = "Gear" buttons[3].Function = function() image.Image = "http://www.roblox.com/Asset?id=45917596" end buttons[4] = {} buttons[4].Text = "Zoom" buttons[4].Function = function() image.Image = "http://www.roblox.com/Asset?id=45915825" end CreateTextButtons(buttonRow, buttons, UDim.new(0, 0), UDim.new(1,0)) -- set up listeners for type of mouse mode, but keep constructing gui at same time delay(0, function() waitForChild(gui,"UserSettingsShield") waitForChild(gui.UserSettingsShield,"Settings") waitForChild(gui.UserSettingsShield.Settings,"SettingsStyle") waitForChild(gui.UserSettingsShield.Settings.SettingsStyle, "GameSettingsMenu") waitForChild(gui.UserSettingsShield.Settings.SettingsStyle.GameSettingsMenu, "CameraField") waitForChild(gui.UserSettingsShield.Settings.SettingsStyle.GameSettingsMenu.CameraField, "DropDownMenuButton") gui.UserSettingsShield.Settings.SettingsStyle.GameSettingsMenu.CameraField.DropDownMenuButton.Changed:connect(function(prop) if prop ~= "Text" then return end if buttonRow.Button1.Style == Enum.ButtonStyle.RobloxButtonDefault then -- only change if this is the currently selected panel if gui.UserSettingsShield.Settings.SettingsStyle.GameSettingsMenu.CameraField.DropDownMenuButton.Text == "Classic" then image.Image = classicLookScreenUrl else image.Image = mouseLockLookScreenUrl end end end) end) local okBtn = Instance.new("TextButton") okBtn.Name = "OkBtn" okBtn.Text = "OK" okBtn.Modal = true okBtn.Size = UDim2.new(0.3, 0, 0, 45) okBtn.Position = UDim2.new(0.35, 0, .975, -50) okBtn.Font = Enum.Font.Arial okBtn.FontSize = Enum.FontSize.Size18 okBtn.BackgroundTransparency = 1 okBtn.TextColor3 = Color3.new(1,1,1) okBtn.Style = Enum.ButtonStyle.RobloxButtonDefault okBtn.MouseButton1Click:connect( function() gui.HelpDialogShield.Visible = false end) okBtn.Parent = helpDialog return shield end local function createLeaveConfirmationMenu(baseZIndex,shield) local frame = Instance.new("Frame") frame.Name = "LeaveConfirmationMenu" frame.BackgroundTransparency = 1 frame.Size = UDim2.new(1,0,1,0) frame.Position = UDim2.new(0,0,2,400) frame.ZIndex = baseZIndex + 4 --[[local yesButton = createTextButton("Leave",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size24,UDim2.new(0,128,0,50),UDim2.new(0,313,0.8,0)) yesButton.Name = "YesButton" yesButton.ZIndex = baseZIndex + 4 yesButton.Parent = frame yesButton.Modal = --]] local noButton = createTextButton("OK",Enum.ButtonStyle.RobloxButtonDefault,Enum.FontSize.Size24,UDim2.new(0,128,0,50),UDim2.new(0,200,0.8,0)) noButton.Name = "NoButton" noButton.Parent = frame noButton.ZIndex = baseZIndex + 4 noButton.MouseButton1Click:connect(function() goToMenu(shield.Settings.SettingsStyle,"GameMainMenu","down",UDim2.new(0,525,0,430)) shield.Settings:TweenSize(UDim2.new(0,525,0,430),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true) end) local leaveText = Instance.new("TextLabel") leaveText.Name = "LeaveText" leaveText.Text = "Click the red X in the top right corner." leaveText.Size = UDim2.new(1,0,0.8,0) leaveText.TextWrap = true leaveText.TextColor3 = Color3.new(1,1,1) leaveText.Font = Enum.Font.ArialBold leaveText.FontSize = Enum.FontSize.Size36 leaveText.BackgroundTransparency = 1 leaveText.ZIndex = baseZIndex + 4 leaveText.Parent = frame return frame end local function createResetConfirmationMenu(baseZIndex,shield) local frame = Instance.new("Frame") frame.Name = "ResetConfirmationMenu" frame.BackgroundTransparency = 1 frame.Size = UDim2.new(1,0,1,0) frame.Position = UDim2.new(0,0,2,400) frame.ZIndex = baseZIndex + 4 frame.Parent = gui local yesButton = createTextButton("Reset",Enum.ButtonStyle.RobloxButtonDefault,Enum.FontSize.Size24,UDim2.new(0,128,0,50),UDim2.new(0,313,0,299)) yesButton.Name = "YesButton" yesButton.ZIndex = baseZIndex + 4 yesButton.Parent = frame yesButton.Modal = true yesButton.MouseButton1Click:connect(function() resumeGameFunction(shield) resetLocalCharacter() end) local noButton = createTextButton("Cancel",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size24,UDim2.new(0,128,0,50),UDim2.new(0,90,0,299)) noButton.Name = "NoButton" noButton.Parent = frame noButton.ZIndex = baseZIndex + 4 noButton.MouseButton1Click:connect(function() goToMenu(shield.Settings.SettingsStyle,"GameMainMenu","down",UDim2.new(0,525,0,430)) shield.Settings:TweenSize(UDim2.new(0,525,0,430),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true) end) local resetCharacterText = Instance.new("TextLabel") resetCharacterText.Name = "ResetCharacterText" resetCharacterText.Text = "Are you sure you want to reset your character?" resetCharacterText.Size = UDim2.new(1,0,0.8,0) resetCharacterText.TextWrap = true resetCharacterText.TextColor3 = Color3.new(1,1,1) resetCharacterText.Font = Enum.Font.ArialBold resetCharacterText.FontSize = Enum.FontSize.Size36 resetCharacterText.BackgroundTransparency = 1 resetCharacterText.ZIndex = baseZIndex + 4 resetCharacterText.Parent = frame local fineResetCharacterText = resetCharacterText:Clone() fineResetCharacterText.Name = "FineResetCharacterText" fineResetCharacterText.Text = "You will be put back on a spawn point" fineResetCharacterText.Size = UDim2.new(0,303,0,18) fineResetCharacterText.Position = UDim2.new(0, 109, 0, 215) fineResetCharacterText.FontSize = Enum.FontSize.Size18 fineResetCharacterText.Parent = frame return frame end local function createGameMainMenu(baseZIndex, shield) local gameMainMenuFrame = Instance.new("Frame") gameMainMenuFrame.Name = "GameMainMenu" gameMainMenuFrame.BackgroundTransparency = 1 gameMainMenuFrame.Size = UDim2.new(1,0,1,0) gameMainMenuFrame.ZIndex = baseZIndex + 4 gameMainMenuFrame.Parent = script.Parent.UserSettingsShield.Settings.SettingsStyle -- GameMainMenu Children local gameMainMenuTitle = Instance.new("TextLabel") gameMainMenuTitle.Name = "Title" gameMainMenuTitle.Text = "Game Menu" gameMainMenuTitle.BackgroundTransparency = 1 gameMainMenuTitle.TextStrokeTransparency = 0 gameMainMenuTitle.Font = Enum.Font.ArialBold gameMainMenuTitle.FontSize = Enum.FontSize.Size36 gameMainMenuTitle.Size = UDim2.new(1,0,0,36) gameMainMenuTitle.Position = UDim2.new(0,0,0,4) gameMainMenuTitle.TextColor3 = Color3.new(1,1,1) gameMainMenuTitle.ZIndex = baseZIndex + 4 gameMainMenuTitle.Parent = gameMainMenuFrame local robloxHelpButton = createTextButton("Help",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size18,UDim2.new(0,164,0,50),UDim2.new(0,82,0,256)) robloxHelpButton.Name = "HelpButton" robloxHelpButton.ZIndex = baseZIndex + 4 robloxHelpButton.Parent = gameMainMenuFrame helpButton = robloxHelpButton local helpDialog = createHelpDialog(baseZIndex) helpDialog.Parent = gui helpButton.MouseButton1Click:connect( function() helpDialog.Visible = true mainShield.Visible = false end) helpButton.Active = true local helpShortcut = Instance.new("TextLabel") helpShortcut.Name = "HelpShortcutText" helpShortcut.Text = "F1" helpShortcut.Visible = false helpShortcut.BackgroundTransparency = 1 helpShortcut.Font = Enum.Font.Arial helpShortcut.FontSize = Enum.FontSize.Size12 helpShortcut.Position = UDim2.new(0,85,0,0) helpShortcut.Size = UDim2.new(0,30,0,30) helpShortcut.TextColor3 = Color3.new(0,1,0) helpShortcut.ZIndex = baseZIndex + 4 helpShortcut.Parent = robloxHelpButton local screenshotButton = createTextButton("Screenshot",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size18,UDim2.new(0,168,0,50),UDim2.new(0,254,0,256)) screenshotButton.Name = "ScreenshotButton" screenshotButton.ZIndex = baseZIndex + 4 screenshotButton.Parent = shield.Settings.SettingsStyle.GameMainMenu screenshotButton.Visible = not macClient local screenshotShortcut = helpShortcut:clone() screenshotShortcut.Name = "ScreenshotShortcutText" screenshotShortcut.Text = "PrintSc" screenshotShortcut.Position = UDim2.new(0,118,0,0) screenshotShortcut.Visible = true screenshotShortcut.Parent = screenshotButton local recordVideoButton = createTextButton("Record Video",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size18,UDim2.new(0,168,0,50),UDim2.new(0,254,0,306)) recordVideoButton.Name = "RecordVideoButton" recordVideoButton.ZIndex = baseZIndex + 4 recordVideoButton.Parent = gameMainMenuFrame recordVideoButton.Visible = not macClient local recordVideoShortcut = helpShortcut:clone() recordVideoShortcut.Visible = hasGraphicsSlider recordVideoShortcut.Name = "RecordVideoShortcutText" recordVideoShortcut.Text = "F12" recordVideoShortcut.Position = UDim2.new(0,120,0,0) recordVideoShortcut.Parent = recordVideoButton local stopRecordButton = Instance.new("ImageButton") stopRecordButton.Name = "StopRecordButton" stopRecordButton.BackgroundTransparency = 1 stopRecordButton.Image = "rbxasset://textures/ui/RecordStop.png" stopRecordButton.Size = UDim2.new(0,59,0,27) stopRecordButton.MouseButton1Click:connect(function() print("function removed cuz its a localscript noob") end) stopRecordButton.Visible = false stopRecordButton.Parent = gui local reportAbuseButton = createTextButton("Report Abuse [W.I.P]",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size18,UDim2.new(0,164,0,50),UDim2.new(0,82,0,306)) reportAbuseButton.Name = "ReportAbuseButton" reportAbuseButton.ZIndex = baseZIndex + 4 reportAbuseButton.Parent = gameMainMenuFrame reportAbuseButton.Active = true local leaveGameButton = createTextButton("Leave Game",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size24,UDim2.new(0,340,0,50),UDim2.new(0,82,0,358)) leaveGameButton.Name = "LeaveGameButton" leaveGameButton.ZIndex = baseZIndex + 4 leaveGameButton.Parent = gameMainMenuFrame local resumeGameButton = createTextButton("Resume Game",Enum.ButtonStyle.RobloxButtonDefault,Enum.FontSize.Size24,UDim2.new(0,340,0,50),UDim2.new(0,82,0,54)) resumeGameButton.Name = "resumeGameButton" resumeGameButton.ZIndex = baseZIndex + 4 resumeGameButton.Parent = gameMainMenuFrame resumeGameButton.Modal = true resumeGameButton.MouseButton1Click:connect(function() resumeGameFunction(shield) end) local gameSettingsButton = createTextButton("Game Settings",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size24,UDim2.new(0,340,0,50),UDim2.new(0,82,0,156)) gameSettingsButton.Name = "SettingsButton" gameSettingsButton.ZIndex = baseZIndex + 4 gameSettingsButton.Parent = gameMainMenuFrame if game:FindFirstChild("LoadingGuiService") and #game.LoadingGuiService:GetChildren() > 0 then local gameSettingsButton = createTextButton("Game Instructions",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size24,UDim2.new(0,340,0,50),UDim2.new(0,82,0,207)) gameSettingsButton.Name = "GameInstructions" gameSettingsButton.ZIndex = baseZIndex + 4 gameSettingsButton.Parent = gameMainMenuFrame gameSettingsButton.MouseButton1Click:connect(function() if game:FindFirstChild("Players") and game.Players["LocalPlayer"] then local loadingGui = game.Players.LocalPlayer:FindFirstChild("PlayerLoadingGui") if loadingGui then loadingGui.Visible = true end end end) end local resetButton = createTextButton("Reset Character",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size24,UDim2.new(0,340,0,50),UDim2.new(0,82,0,105)) resetButton.Name = "ResetButton" resetButton.ZIndex = baseZIndex + 4 resetButton.Parent = gameMainMenuFrame return gameMainMenuFrame end local function createGameSettingsMenu(baseZIndex, shield) local gameSettingsMenuFrame = Instance.new("Frame") gameSettingsMenuFrame.Name = "GameSettingsMenu" gameSettingsMenuFrame.BackgroundTransparency = 1 gameSettingsMenuFrame.Size = UDim2.new(1,0,1,0) gameSettingsMenuFrame.ZIndex = baseZIndex + 4 local title = Instance.new("TextLabel") title.Name = "Title" title.Text = "Settings" title.Size = UDim2.new(1,0,0,48) title.Position = UDim2.new(0,9,0,-9) title.Font = Enum.Font.ArialBold title.FontSize = Enum.FontSize.Size36 title.TextColor3 = Color3.new(1,1,1) title.ZIndex = baseZIndex + 4 title.BackgroundTransparency = 1 title.Parent = gameSettingsMenuFrame local fullscreenText = Instance.new("TextLabel") fullscreenText.Name = "FullscreenText" fullscreenText.Text = "Fullscreen Mode" fullscreenText.Size = UDim2.new(0,124,0,18) fullscreenText.Position = UDim2.new(0,62,0,145) fullscreenText.Font = Enum.Font.Arial fullscreenText.FontSize = Enum.FontSize.Size18 fullscreenText.TextColor3 = Color3.new(1,1,1) fullscreenText.ZIndex = baseZIndex + 4 fullscreenText.BackgroundTransparency = 1 fullscreenText.Parent = gameSettingsMenuFrame local fullscreenShortcut = Instance.new("TextLabel") fullscreenShortcut.Visible = true fullscreenShortcut.Name = "FullscreenShortcutText" fullscreenShortcut.Text = "F11" fullscreenShortcut.BackgroundTransparency = 1 fullscreenShortcut.Font = Enum.Font.Arial fullscreenShortcut.FontSize = Enum.FontSize.Size12 fullscreenShortcut.Position = UDim2.new(0,186,0,141) fullscreenShortcut.Size = UDim2.new(0,30,0,30) fullscreenShortcut.TextColor3 = Color3.new(0,1,0) fullscreenShortcut.ZIndex = baseZIndex + 4 fullscreenShortcut.Parent = gameSettingsMenuFrame local fullscreenCheckbox = createTextButton("",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size18,UDim2.new(0,25,0,25),UDim2.new(0,30,0,144)) fullscreenCheckbox.Name = "FullscreenCheckbox" fullscreenCheckbox.ZIndex = baseZIndex + 4 fullscreenCheckbox.Parent = gameSettingsMenuFrame local studioText = Instance.new("TextLabel") studioText.Visible = false studioText.Name = "StudioText" studioText.Text = "Studio Mode" studioText.Size = UDim2.new(0,95,0,18) studioText.Position = UDim2.new(0,62,0,179) studioText.Font = Enum.Font.Arial studioText.FontSize = Enum.FontSize.Size18 studioText.TextColor3 = Color3.new(1,1,1) studioText.ZIndex = baseZIndex + 4 studioText.BackgroundTransparency = 1 studioText.Parent = gameSettingsMenuFrame local studioShortcut = fullscreenShortcut:clone() studioShortcut.Name = "StudioShortcutText" studioShortcut.Visible = false -- TODO: turn back on when f2 hack is fixed studioShortcut.Text = "F2" studioShortcut.Position = UDim2.new(0,154,0,175) studioShortcut.Parent = gameSettingsMenuFrame local studioCheckbox = nil if studioCheckbox == nil then local qualityText = Instance.new("TextLabel") qualityText.Name = "QualityText" qualityText.Text = "Graphics Quality" qualityText.Size = UDim2.new(0,128,0,18) qualityText.Position = UDim2.new(0,30,0,239) qualityText.Font = Enum.Font.Arial qualityText.FontSize = Enum.FontSize.Size18 qualityText.TextColor3 = Color3.new(1,1,1) qualityText.ZIndex = baseZIndex + 4 qualityText.BackgroundTransparency = 1 qualityText.Parent = gameSettingsMenuFrame qualityText.Visible = true local autoText = qualityText:clone() autoText.Name = "AutoText" autoText.Text = "Auto" autoText.Position = UDim2.new(0,183,0,214) autoText.TextColor3 = Color3.new(128/255,128/255,128/255) autoText.Size = UDim2.new(0,34,0,18) autoText.Parent = gameSettingsMenuFrame autoText.Visible = not inStudioMode local fasterText = autoText:clone() fasterText.Name = "FasterText" fasterText.Text = "Faster" fasterText.Position = UDim2.new(0,185,0,274) fasterText.TextColor3 = Color3.new(95,95,95) fasterText.FontSize = Enum.FontSize.Size14 fasterText.Parent = gameSettingsMenuFrame fasterText.Visible = not inStudioMode local fasterShortcut = fullscreenShortcut:clone() fasterShortcut.Name = "FasterShortcutText" fasterShortcut.Text = "F10 + Shift" fasterShortcut.Position = UDim2.new(0,185,0,283) fasterShortcut.Parent = gameSettingsMenuFrame fasterShortcut.Visible = not inStudioMode local betterQualityText = autoText:clone() betterQualityText.Name = "BetterQualityText" betterQualityText.Text = "Better Quality" betterQualityText.TextWrap = true betterQualityText.Size = UDim2.new(0,41,0,28) betterQualityText.Position = UDim2.new(0,390,0,269) betterQualityText.TextColor3 = Color3.new(95,95,95) betterQualityText.FontSize = Enum.FontSize.Size14 betterQualityText.Parent = gameSettingsMenuFrame betterQualityText.Visible = not inStudioMode local betterQualityShortcut = fullscreenShortcut:clone() betterQualityShortcut.Name = "BetterQualityShortcut" betterQualityShortcut.Text = "F10" betterQualityShortcut.Position = UDim2.new(0,394,0,288) betterQualityShortcut.Parent = gameSettingsMenuFrame betterQualityShortcut.Visible = not inStudioMode local autoGraphicsButton = createTextButton("X",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size18,UDim2.new(0,25,0,25),UDim2.new(0,187,0,239)) autoGraphicsButton.Name = "AutoGraphicsButton" autoGraphicsButton.ZIndex = baseZIndex + 4 autoGraphicsButton.Parent = gameSettingsMenuFrame autoGraphicsButton.Visible = not inStudioMode local graphicsSlider, graphicsLevel = RbxGui.CreateSlider(GraphicsQualityLevels,150,UDim2.new(0, 230, 0, 280)) -- graphics - 1 because slider starts at 1 instead of 0 graphicsSlider.Parent = gameSettingsMenuFrame graphicsSlider.Bar.ZIndex = baseZIndex + 4 graphicsSlider.Bar.Slider.ZIndex = baseZIndex + 5 graphicsSlider.Visible = not inStudioMode local graphicsSetter = Instance.new("TextBox") graphicsSetter.Name = "GraphicsSetter" graphicsSetter.BackgroundColor3 = Color3.new(0,0,0) graphicsSetter.BorderColor3 = Color3.new(128/255,128/255,128/255) graphicsSetter.Size = UDim2.new(0,50,0,25) graphicsSetter.Position = UDim2.new(0,450,0,269) graphicsSetter.TextColor3 = Color3.new(1,1,1) graphicsSetter.Font = Enum.Font.Arial graphicsSetter.FontSize = Enum.FontSize.Size18 graphicsSetter.Text = "Auto" graphicsSetter.ZIndex = 1 graphicsSetter.TextWrap = true graphicsSetter.Parent = gameSettingsMenuFrame graphicsSetter.Visible = false local listenToGraphicsLevelChange = false local function setAutoGraphicsGui(active) isAutoGraphics = active if active then autoGraphicsButton.Text = "X" betterQualityText.ZIndex = 1 betterQualityShortcut.ZIndex = 1 fasterShortcut.ZIndex = 1 fasterText.ZIndex = 1 graphicsSlider.Bar.ZIndex = 1 graphicsSlider.Bar.Slider.ZIndex = 1 graphicsSetter.ZIndex = 1 graphicsSetter.Text = "Auto" else autoGraphicsButton.Text = "" graphicsSlider.Bar.ZIndex = baseZIndex + 4 graphicsSlider.Bar.Slider.ZIndex = baseZIndex + 5 betterQualityShortcut.ZIndex = baseZIndex + 4 fasterShortcut.ZIndex = baseZIndex + 4 betterQualityText.ZIndex = baseZIndex + 4 fasterText.ZIndex = baseZIndex + 4 graphicsSetter.ZIndex = baseZIndex + 4 end end local function goToAutoGraphics() setAutoGraphicsGui(true) UserSettings().GameSettings.SavedQualityLevel = Enum.SavedQualitySetting.Automatic settings().Rendering.QualityLevel = Enum.QualityLevel.Automatic end local function setGraphicsQualityLevel(newLevel) local percentage = newLevel/GraphicsQualityLevels local newSetting = math.floor((settings().Rendering:GetMaxQualityLevel() - 1) * percentage) if newSetting == 20 then -- Level 20 is the same as level 21, except it doesn't render ambient occlusion newSetting = 21 elseif newLevel == 1 then -- make sure we can go to lowest settings (for terrible computers) newSetting = 1 elseif newSetting > settings().Rendering:GetMaxQualityLevel() then newSetting = settings().Rendering:GetMaxQualityLevel() - 1 end UserSettings().GameSettings.SavedQualityLevel = newLevel settings().Rendering.QualityLevel = newSetting end local function goToManualGraphics(explicitLevel) setAutoGraphicsGui(false) if explicitLevel then graphicsLevel.Value = explicitLevel else graphicsLevel.Value = math.floor((settings().Rendering.AutoFRMLevel/(settings().Rendering:GetMaxQualityLevel() - 1)) * GraphicsQualityLevels) end if explicitLevel == graphicsLevel.Value then -- make sure we are actually in right graphics mode setGraphicsQualityLevel(graphicsLevel.Value) end if not explicitLevel then UserSettings().GameSettings.SavedQualityLevel = graphicsLevel.Value end graphicsSetter.Text = tostring(graphicsLevel.Value) end local function showAutoGraphics() autoText.ZIndex = baseZIndex + 4 autoGraphicsButton.ZIndex = baseZIndex + 4 end local function hideAutoGraphics() autoText.ZIndex = 1 autoGraphicsButton.ZIndex = 1 end local function showManualGraphics() graphicsSlider.Bar.ZIndex = baseZIndex + 4 graphicsSlider.Bar.Slider.ZIndex = baseZIndex + 5 betterQualityShortcut.ZIndex = baseZIndex + 4 fasterShortcut.ZIndex = baseZIndex + 4 betterQualityText.ZIndex = baseZIndex + 4 fasterText.ZIndex = baseZIndex + 4 graphicsSetter.ZIndex = baseZIndex + 4 end local function hideManualGraphics() betterQualityText.ZIndex = 1 betterQualityShortcut.ZIndex = 1 fasterShortcut.ZIndex = 1 fasterText.ZIndex = 1 graphicsSlider.Visible = false graphicsSlider.Bar.ZIndex = 1 graphicsSlider.Bar.Slider.ZIndex = 1 graphicsSetter.ZIndex = 1 end local function translateSavedQualityLevelToInt(savedQualityLevel) if savedQualityLevel == Enum.SavedQualitySetting.Automatic then return 0 elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel1 then return 1 elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel2 then return 2 elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel3 then return 3 elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel4 then return 4 elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel5 then return 5 elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel6 then return 6 elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel7 then return 7 elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel8 then return 8 elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel9 then return 9 elseif savedQualityLevel == Enum.SavedQualitySetting.QualityLevel10 then return 10 end end local function enableGraphicsWidget() settings().Rendering.EnableFRM = true isAutoGraphics = (UserSettings().GameSettings.SavedQualityLevel == Enum.SavedQualitySetting.Automatic) if isAutoGraphics then showAutoGraphics() goToAutoGraphics() else showAutoGraphics() showManualGraphics() goToManualGraphics(translateSavedQualityLevelToInt(UserSettings().GameSettings.SavedQualityLevel)) end end local function disableGraphicsWidget() hideManualGraphics() hideAutoGraphics() settings().Rendering.EnableFRM = false end graphicsSetter.FocusLost:connect(function() if isAutoGraphics then graphicsSetter.Text = tostring(graphicsLevel.Value) return end local newGraphicsValue = tonumber(graphicsSetter.Text) if newGraphicsValue == nil then graphicsSetter.Text = tostring(graphicsLevel.Value) return end if newGraphicsValue < 1 then newGraphicsValue = 1 elseif newGraphicsValue >= settings().Rendering:GetMaxQualityLevel() then newGraphicsValue = settings().Rendering:GetMaxQualityLevel() - 1 end graphicsLevel.Value = newGraphicsValue setGraphicsQualityLevel(graphicsLevel.Value) graphicsSetter.Text = tostring(graphicsLevel.Value) end) graphicsLevel.Changed:connect(function(prop) if isAutoGraphics then return end if not listenToGraphicsLevelChange then return end graphicsSetter.Text = tostring(graphicsLevel.Value) setGraphicsQualityLevel(graphicsLevel.Value) end) -- setup our graphic mode on load game.Players.PlayerAdded:connect(function(player) if player == game.Players.LocalPlayer and inStudioMode then enableGraphicsWidget() end end) game.Players.PlayerRemoving:connect(function(player) if player == game.Players.LocalPlayer and inStudioMode then disableGraphicsWidget() end end) studioCheckbox = createTextButton("",Enum.ButtonStyle.RobloxButton,Enum.FontSize.Size18,UDim2.new(0,25,0,25),UDim2.new(0,30,0,176)) studioCheckbox.Name = "StudioCheckbox" studioCheckbox.ZIndex = baseZIndex + 4 --studioCheckbox.Parent = gameSettingsMenuFrame -- todo: enable when studio h4x aren't an issue anymore studioCheckbox.Visible = false -- todo: enabled when studio h4x aren't an issue anymore if hasGraphicsSlider then UserSettings().GameSettings.StudioModeChanged:connect(function(isStudioMode) inStudioMode = isStudioMode if isStudioMode then wasManualGraphics = (settings().Rendering.QualityLevel ~= Enum.QualityLevel.Automatic) goToAutoGraphics() studioCheckbox.Text = "X" autoGraphicsButton.ZIndex = 1 autoText.ZIndex = 1 else if wasManualGraphics then goToManualGraphics() end studioCheckbox.Text = "" autoGraphicsButton.ZIndex = baseZIndex + 4 autoText.ZIndex = baseZIndex + 4 end end) else studioCheckbox.MouseButton1Click:connect(function() if not studioCheckbox.Active then return end if studioCheckbox.Text == "" then studioCheckbox.Text = "X" else studioCheckbox.Text = "" end end) end end if game:FindFirstChild("NetworkClient") then -- we are playing online setDisabledState(studioText) setDisabledState(studioShortcut) setDisabledState(studioCheckbox) end local backButton if hasGraphicsSlider then backButton = createTextButton("OK",Enum.ButtonStyle.RobloxButtonDefault,Enum.FontSize.Size24,UDim2.new(0,180,0,50),UDim2.new(0,170,0,330)) backButton.Modal = true else backButton = createTextButton("OK",Enum.ButtonStyle.RobloxButtonDefault,Enum.FontSize.Size24,UDim2.new(0,180,0,50),UDim2.new(0,170,0,330)) backButton.Modal = true end backButton.Name = "BackButton" backButton.ZIndex = baseZIndex + 4 backButton.Parent = gameSettingsMenuFrame local syncVideoCaptureSetting = nil if not macClient then local videoCaptureLabel = Instance.new("TextLabel") videoCaptureLabel.Name = "VideoCaptureLabel" videoCaptureLabel.Text = "After Capturing Video" videoCaptureLabel.Font = Enum.Font.Arial videoCaptureLabel.FontSize = Enum.FontSize.Size18 videoCaptureLabel.Position = UDim2.new(0,32,0,100) videoCaptureLabel.Size = UDim2.new(0,164,0,18) videoCaptureLabel.BackgroundTransparency = 1 videoCaptureLabel.TextColor3 = Color3I(255,255,255) videoCaptureLabel.TextXAlignment = Enum.TextXAlignment.Left videoCaptureLabel.ZIndex = baseZIndex + 4 videoCaptureLabel.Parent = gameSettingsMenuFrame local videoNames = {} local videoNameToItem = {} videoNames[1] = "Just Save to Disk" videoNameToItem[videoNames[1]] = Enum.UploadSetting["Never"] videoNames[2] = "Upload to YouTube" videoNameToItem[videoNames[2]] = Enum.UploadSetting["Ask me first"] local videoCaptureDropDown = nil videoCaptureDropDown, updateVideoCaptureDropDownSelection = RbxGui.CreateDropDownMenu(videoNames, function(text) UserSettings().GameSettings.VideoUploadPromptBehavior = videoNameToItem[text] end) videoCaptureDropDown.Name = "VideoCaptureField" videoCaptureDropDown.ZIndex = baseZIndex + 4 videoCaptureDropDown.DropDownMenuButton.ZIndex = baseZIndex + 4 videoCaptureDropDown.DropDownMenuButton.Icon.ZIndex = baseZIndex + 4 videoCaptureDropDown.Position = UDim2.new(0, 270, 0, 94) videoCaptureDropDown.Size = UDim2.new(0,200,0,32) videoCaptureDropDown.Parent = gameSettingsMenuFrame syncVideoCaptureSetting = function() if UserSettings().GameSettings.VideoUploadPromptBehavior == Enum.UploadSetting["Never"] then updateVideoCaptureDropDownSelection(videoNames[1]) elseif UserSettings().GameSettings.VideoUploadPromptBehavior == Enum.UploadSetting["Ask me first"] then updateVideoCaptureDropDownSelection(videoNames[2]) else UserSettings().GameSettings.VideoUploadPromptBehavior = Enum.UploadSetting["Ask me first"] updateVideoCaptureDropDownSelection(videoNames[2]) end end end local cameraLabel = Instance.new("TextLabel") cameraLabel.Name = "CameraLabel" cameraLabel.Text = "Character & Camera Controls" cameraLabel.Font = Enum.Font.Arial cameraLabel.FontSize = Enum.FontSize.Size18 cameraLabel.Position = UDim2.new(0,31,0,58) cameraLabel.Size = UDim2.new(0,224,0,18) cameraLabel.TextColor3 = Color3I(255,255,255) cameraLabel.TextXAlignment = Enum.TextXAlignment.Left cameraLabel.BackgroundTransparency = 1 cameraLabel.ZIndex = baseZIndex + 4 cameraLabel.Parent = gameSettingsMenuFrame local mouseLockLabel = true local enumItems = Enum.ControlMode:GetEnumItems() local enumNames = {} local enumNameToItem = {} for i,obj in ipairs(enumItems) do enumNames[i] = obj.Name enumNameToItem[obj.Name] = obj end local cameraDropDown cameraDropDown, updateCameraDropDownSelection = RbxGui.CreateDropDownMenu(enumNames, function(text) UserSettings().GameSettings.ControlMode = enumNameToItem[text] pcall(function() if mouseLockLabel and UserSettings().GameSettings.ControlMode == Enum.ControlMode["Mouse Lock Switch"] then mouseLockLabel.Visible = true elseif mouseLockLabel then mouseLockLabel.Visible = false end end) end) cameraDropDown.Name = "CameraField" cameraDropDown.ZIndex = baseZIndex + 4 cameraDropDown.DropDownMenuButton.ZIndex = baseZIndex + 4 cameraDropDown.DropDownMenuButton.Icon.ZIndex = baseZIndex + 4 cameraDropDown.Position = UDim2.new(0, 270, 0, 52) cameraDropDown.Size = UDim2.new(0,200,0,32) cameraDropDown.Parent = gameSettingsMenuFrame return gameSettingsMenuFrame end if LoadLibrary then RbxGui = t local baseZIndex = 0 if UserSettings then local createSettingsDialog = function() waitForChild(gui,"BottomLeftControl") settingsButton = gui.BottomLeftControl:FindFirstChild("SettingsButton") if settingsButton == nil then settingsButton = Instance.new("ImageButton") settingsButton.Name = "SettingsButton" settingsButton.Image = "rbxasset://textures/ui/SettingsButton.png" settingsButton.BackgroundTransparency = 1 settingsButton.Active = false settingsButton.Size = UDim2.new(0,54,0,46) settingsButton.Position = UDim2.new(0,2,0,50) settingsButton.Parent = gui settingsButton.MouseButton1Click:connect(function() goToMenu(shield.Settings.SettingsStyle,"GameMainMenu","down",UDim2.new(0,525,0,430)) shield.Settings:TweenSize(UDim2.new(0,525,0,430),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true) end) end local shield = Instance.new("TextButton") shield.Text = "" shield.Name = "UserSettingsShield" shield.Active = true shield.AutoButtonColor = false shield.Visible = false shield.Size = UDim2.new(1,0,1,0) shield.BackgroundColor3 = Color3I(51,51,51) shield.BorderColor3 = Color3I(27,42,53) shield.BackgroundTransparency = 0.4 shield.ZIndex = baseZIndex + 2 shield.Parent = script.Parent mainShield = shield local frame = Instance.new("Frame") frame.Name = "Settings" frame.Position = UDim2.new(0.5, -262, -0.5, -200) frame.Size = UDim2.new(0, 525, 0, 430) frame.BackgroundTransparency = 1 frame.Active = true frame.Parent = shield local settingsFrame = Instance.new("Frame") settingsFrame.Name = "SettingsStyle" settingsFrame.Size = UDim2.new(1, 0, 1, 0) settingsFrame.Style = Enum.FrameStyle.RobloxRound settingsFrame.Active = true settingsFrame.ZIndex = baseZIndex + 3 settingsFrame.Parent = frame local gameSettingsMenu = createGameSettingsMenu(baseZIndex, shield) gameSettingsMenu.Parent = settingsFrame local gameMainMenu = createGameMainMenu(baseZIndex, shield) gameMainMenu.Parent = settingsFrame gameMainMenu.ScreenshotButton.MouseButton1Click:connect(function() end) gameMainMenu.RecordVideoButton.MouseButton1Click:connect(function() end) function localPlayerChange() gameMainMenu.ResetButton.Visible = game.Players.LocalPlayer if game.Players.LocalPlayer then settings().Rendering.EnableFRM = true elseif inStudioMode then settings().Rendering.EnableFRM = false end end gameMainMenu.ResetButton.Visible = game.Players.LocalPlayer if game.Players.LocalPlayer ~= nil then game.Players.LocalPlayer.Changed:connect(function() localPlayerChange() end) else delay(0,function() waitForProperty(game.Players,"LocalPlayer") gameMainMenu.ResetButton.Visible = game.Players.LocalPlayer game.Players.LocalPlayer.Changed:connect(function() localPlayerChange() end) end) end gameMainMenu.ReportAbuseButton.Visible = game:FindFirstChild("NetworkClient") if not gameMainMenu.ReportAbuseButton.Visible then game.ChildAdded:connect(function(child) if child:IsA("NetworkClient") then gameMainMenu.ReportAbuseButton.Visible = game:FindFirstChild("NetworkClient") end end) end gameMainMenu.ResetButton.MouseButton1Click:connect(function() goToMenu(settingsFrame,"ResetConfirmationMenu","up",UDim2.new(0,525,0,370)) end) gameMainMenu.LeaveGameButton.MouseButton1Click:connect(function() goToMenu(settingsFrame,"LeaveConfirmationMenu","down",UDim2.new(0,525,0,300)) end) local gameSettingsMenu = createGameSettingsMenu(baseZIndex, shield) gameSettingsMenu.Visible = false gameSettingsMenu.Parent = settingsFrame gameMainMenu.LeaveGameButton.MouseButton1Click:connect(function() goToMenu(settingsFrame,"LeaveConfirmationMenu","down",UDim2.new(0,525,0,300)) end) gameMainMenu.SettingsButton.MouseButton1Click:connect(function() goToMenu(settingsFrame,"GameSettingsMenu","left",UDim2.new(0,525,0,350)) end) gameSettingsMenu.BackButton.MouseButton1Click:connect(function() goToMenu(settingsFrame,"GameMainMenu","right",UDim2.new(0,525,0,430)) end) local resetConfirmationWindow = createResetConfirmationMenu(baseZIndex, shield) resetConfirmationWindow.Visible = false resetConfirmationWindow.Parent = settingsFrame local leaveConfirmationWindow = createLeaveConfirmationMenu(baseZIndex,shield) leaveConfirmationWindow.Visible = false leaveConfirmationWindow.Parent = settingsFrame settingsButton.MouseButton1Click:connect( function() game.GuiService:AddCenterDialog(shield, Enum.CenterDialogType.ModalDialog, --showFunction function() settingsButton.Active = false updateCameraDropDownSelection(UserSettings().GameSettings.ControlMode.Name) if syncVideoCaptureSetting then syncVideoCaptureSetting() end goToMenu(settingsFrame,"GameMainMenu","right",UDim2.new(0,525,0,430)) shield.Visible = true settingsFrame.Parent:TweenPosition(UDim2.new(0.5, -262,0.5, -200),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true) settingsFrame.Parent:TweenSize(UDim2.new(0,525,0,430),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true) end, --hideFunction function() settingsFrame.Parent:TweenPosition(UDim2.new(0.5, -262,-0.5, -200),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true) settingsFrame.Parent:TweenSize(UDim2.new(0,525,0,430),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true) shield.Visible = false settingsButton.Active = true end) end) return shield end delay(0, function() if settingsButton == nil then settingsButton = Instance.new("ImageButton") settingsButton.Name = "SettingsButton" settingsButton.Image = "rbxasset://textures/ui/SettingsButton.png" settingsButton.BackgroundTransparency = 1 settingsButton.Active = false settingsButton.Size = UDim2.new(0,54,0,46) settingsButton.Position = UDim2.new(0,2,0,50) settingsButton.Parent = gui.BottomLeftControl end local shield = Instance.new("TextButton") shield.Text = "" shield.Name = "UserSettingsShield" shield.Active = true shield.AutoButtonColor = false shield.Visible = false shield.Size = UDim2.new(1,0,1,0) shield.BackgroundColor3 = Color3I(51,51,51) shield.BorderColor3 = Color3I(27,42,53) shield.BackgroundTransparency = 0.4 shield.ZIndex = baseZIndex + 2 shield.Parent = script.Parent mainShield = shield local frame = Instance.new("Frame") frame.Name = "Settings" frame.Position = UDim2.new(0.5, -262, -0.5, -200) frame.Size = UDim2.new(0, 525, 0, 430) frame.BackgroundTransparency = 1 frame.Active = true frame.Parent = shield local settingsFrame = Instance.new("Frame") settingsFrame.Name = "SettingsStyle" settingsFrame.Size = UDim2.new(1, 0, 1, 0) settingsFrame.Style = Enum.FrameStyle.RobloxRound settingsFrame.Active = true settingsFrame.ZIndex = baseZIndex + 3 settingsFrame.Parent = frame local resetConfirmationWindow = createResetConfirmationMenu(baseZIndex, shield) resetConfirmationWindow.Visible = false resetConfirmationWindow.Parent = settingsFrame local leaveConfirmationWindow = createLeaveConfirmationMenu(baseZIndex,shield) leaveConfirmationWindow.Visible = false leaveConfirmationWindow.Parent = settingsFrame local gameMainMenu = createGameMainMenu(baseZIndex, shield) gameMainMenu.Parent = settingsFrame local gameSettingsMenu = createGameSettingsMenu(baseZIndex, shield) gameSettingsMenu.Visible = false gameSettingsMenu.Parent = settingsFrame gameMainMenu.SettingsButton.MouseButton1Click:connect(function() goToMenu(settingsFrame,"GameSettingsMenu","left",UDim2.new(0,525,0,350)) end) gameSettingsMenu.BackButton.MouseButton1Click:connect(function() goToMenu(settingsFrame,"GameMainMenu","right",UDim2.new(0,525,0,430)) end) gameMainMenu.ResetButton.MouseButton1Click:connect(function() goToMenu(settingsFrame,"ResetConfirmationMenu","up",UDim2.new(0,525,0,370)) end) gameMainMenu.LeaveGameButton.MouseButton1Click:connect(function() goToMenu(settingsFrame,"LeaveConfirmationMenu","up",UDim2.new(0,525,0,300)) end) gameMainMenu.ScreenshotButton.MouseButton1Click:connect(function() end) gameMainMenu.RecordVideoButton.MouseButton1Click:connect(function() end) settingsButton.MouseButton1Click:connect(function() goToMenu(settingsFrame,"GameMainMenu","right",UDim2.new(0,525,0,430)) shield.Visible = true shield.Active = true settingsFrame.Parent:TweenPosition(UDim2.new(0.5, -262,0.5, -200),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true) settingsFrame.Parent:TweenSize(UDim2.new(0,525,0,430),Enum.EasingDirection.InOut,Enum.EasingStyle.Sine,tweenTime,true) end) gui.BottomLeftControl.SettingsButton.Active = true gui.BottomLeftControl.SettingsButton.Position = UDim2.new(0,2,0,-2) if mouseLockLabel and UserSettings().GameSettings.ControlMode == Enum.ControlMode["Mouse Lock Switch"] then mouseLockLabel.Visible = true elseif mouseLockLabel then mouseLockLabel.Visible = false end --Only show things if we are a NetworkClient waitForChild(game,"NetworkClient") waitForChild(game,"Players") waitForProperty(game.Players, "LocalPlayer") local localPlayer = game.Players.LocalPlayer local reportAbuseButton waitForChild(gui,"UserSettingsShield") waitForChild(gui.UserSettingsShield, "Settings") waitForChild(gui.UserSettingsShield.Settings,"SettingsStyle") waitForChild(gui.UserSettingsShield.Settings.SettingsStyle,"GameMainMenu") waitForChild(gui.UserSettingsShield.Settings.SettingsStyle.GameMainMenu, "ReportAbuseButton") reportAbuseButton = gui.UserSettingsShield.Settings.SettingsStyle.GameMainMenu.ReportAbuseButton local shield = Instance.new("TextButton") shield.Name = "ReportAbuseShield" shield.Text = "" shield.AutoButtonColor = false shield.Active = true shield.Visible = false shield.Size = UDim2.new(1,0,1,0) shield.BackgroundColor3 = Color3I(51,51,51) shield.BorderColor3 = Color3I(27,42,53) shield.BackgroundTransparency = 0.4 shield.ZIndex = baseZIndex + 1 local closeAndResetDialgo local messageBoxButtons = {} messageBoxButtons[1] = {} messageBoxButtons[1].Text = "Ok" messageBoxButtons[1].Modal = true messageBoxButtons[1].Function = function() closeAndResetDialog() end local calmingMessageBox = RbxGui.CreateMessageDialog("Thanks for your report!", "Our moderators will review the chat logs and determine what happened. The other user is probably just trying to make you mad.\n\nIf anyone used swear words, inappropriate language, or threatened you in real life, please report them for Bad Words or Threats", messageBoxButtons) calmingMessageBox.Visible = false calmingMessageBox.Parent = shield local recordedMessageBox = RbxGui.CreateMessageDialog("Thanks for your report!","We've recorded your report for evaluation.", messageBoxButtons) recordedMessageBox.Visible = false recordedMessageBox.Parent = shield local normalMessageBox = RbxGui.CreateMessageDialog("Thanks for your report!", "Our moderators will review the chat logs and determine what happened.", messageBoxButtons) normalMessageBox.Visible = false normalMessageBox.Parent = shield local frame = Instance.new("Frame") frame.Name = "Settings" frame.Position = UDim2.new(0.5, -250, 0.5, -200) frame.Size = UDim2.new(0.0, 500, 0.0, 400) frame.BackgroundTransparency = 1 frame.Active = true frame.Parent = shield local settingsFrame = Instance.new("Frame") settingsFrame.Name = "ReportAbuseStyle" settingsFrame.Size = UDim2.new(1, 0, 1, 0) settingsFrame.Style = Enum.FrameStyle.RobloxRound settingsFrame.Active = true settingsFrame.ZIndex = baseZIndex + 1 settingsFrame.Parent = frame local title = Instance.new("TextLabel") title.Name = "Title" title.Text = "Report Abuse" title.TextColor3 = Color3I(221,221,221) title.Position = UDim2.new(0.5, 0, 0, 30) title.Font = Enum.Font.ArialBold title.FontSize = Enum.FontSize.Size36 title.ZIndex = baseZIndex + 2 title.Parent = settingsFrame local description = Instance.new("TextLabel") description.Name = "Description" description.Text = "This will send a complete report to a moderator. The moderator will review the chat log and take appropriate action." description.TextColor3 = Color3I(221,221,221) description.Position = UDim2.new(0, 0, 0, 55) description.Size = UDim2.new(1, 0, 0, 40) description.BackgroundTransparency = 1 description.Font = Enum.Font.Arial description.FontSize = Enum.FontSize.Size18 description.TextWrap = true description.ZIndex = baseZIndex + 2 description.TextXAlignment = Enum.TextXAlignment.Left description.TextYAlignment = Enum.TextYAlignment.Top description.Parent = settingsFrame local playerLabel = Instance.new("TextLabel") playerLabel.Name = "PlayerLabel" playerLabel.Text = "Which player?" playerLabel.BackgroundTransparency = 1 playerLabel.Font = Enum.Font.Arial playerLabel.FontSize = Enum.FontSize.Size18 playerLabel.Position = UDim2.new(0.025,0,0,100) playerLabel.Size = UDim2.new(0.4,0,0,36) playerLabel.TextColor3 = Color3I(255,255,255) playerLabel.TextXAlignment = Enum.TextXAlignment.Left playerLabel.ZIndex = baseZIndex + 2 playerLabel.Parent = settingsFrame local abusingPlayer = nil local abuse = nil local submitReportButton = nil local updatePlayerSelection = nil local createPlayersDropDown = function() local players = game:GetService("Players") local playerNames = {} local nameToPlayer = {} local children = players:GetChildren() local pos = 1 if children then for i, player in ipairs(children) do if player:IsA("Player") and player ~= localPlayer then playerNames[pos] = player.Name nameToPlayer[player.Name] = player pos = pos + 1 end end end local playerDropDown = nil playerDropDown, updatePlayerSelection = RbxGui.CreateDropDownMenu(playerNames, function(playerName) abusingPlayer = nameToPlayer[playerName] if abuse and abusingPlayer then submitReportButton.Active = true end end) playerDropDown.Name = "PlayersComboBox" playerDropDown.ZIndex = baseZIndex + 2 playerDropDown.Position = UDim2.new(.425, 0, 0, 102) playerDropDown.Size = UDim2.new(.55,0,0,32) return playerDropDown end local abuseLabel = Instance.new("TextLabel") abuseLabel.Name = "AbuseLabel" abuseLabel.Text = "Type of Abuse:" abuseLabel.Font = Enum.Font.Arial abuseLabel.BackgroundTransparency = 1 abuseLabel.FontSize = Enum.FontSize.Size18 abuseLabel.Position = UDim2.new(0.025,0,0,140) abuseLabel.Size = UDim2.new(0.4,0,0,36) abuseLabel.TextColor3 = Color3I(255,255,255) abuseLabel.TextXAlignment = Enum.TextXAlignment.Left abuseLabel.ZIndex = baseZIndex + 2 abuseLabel.Parent = settingsFrame local abuses = {"Swearing","Bullying","Scamming","Dating","Cheating/Exploiting","Personal Questions","Offsite Links","Bad Model or Script","Bad Username"} local abuseDropDown, updateAbuseSelection = RbxGui.CreateDropDownMenu(abuses, function(abuseText) abuse = abuseText if abuse and abusingPlayer then submitReportButton.Active = true end end, true) abuseDropDown.Name = "AbuseComboBox" abuseDropDown.ZIndex = baseZIndex + 2 abuseDropDown.Position = UDim2.new(0.425, 0, 0, 142) abuseDropDown.Size = UDim2.new(0.55,0,0,32) abuseDropDown.Parent = settingsFrame local shortDescriptionLabel = Instance.new("TextLabel") shortDescriptionLabel.Name = "ShortDescriptionLabel" shortDescriptionLabel.Text = "Short Description: (optional)" shortDescriptionLabel.Font = Enum.Font.Arial shortDescriptionLabel.FontSize = Enum.FontSize.Size18 shortDescriptionLabel.Position = UDim2.new(0.025,0,0,180) shortDescriptionLabel.Size = UDim2.new(0.95,0,0,36) shortDescriptionLabel.TextColor3 = Color3I(255,255,255) shortDescriptionLabel.TextXAlignment = Enum.TextXAlignment.Left shortDescriptionLabel.BackgroundTransparency = 1 shortDescriptionLabel.ZIndex = baseZIndex + 2 shortDescriptionLabel.Parent = settingsFrame local shortDescriptionWrapper = Instance.new("Frame") shortDescriptionWrapper.Name = "ShortDescriptionWrapper" shortDescriptionWrapper.Position = UDim2.new(0.025,0,0,220) shortDescriptionWrapper.Size = UDim2.new(0.95,0,1,-310) shortDescriptionWrapper.BackgroundColor3 = Color3I(0,0,0) shortDescriptionWrapper.BorderSizePixel = 0 shortDescriptionWrapper.ZIndex = baseZIndex + 2 shortDescriptionWrapper.Parent = settingsFrame local shortDescriptionBox = Instance.new("TextBox") shortDescriptionBox.Name = "TextBox" shortDescriptionBox.Text = "" shortDescriptionBox.ClearTextOnFocus = false shortDescriptionBox.Font = Enum.Font.Arial shortDescriptionBox.FontSize = Enum.FontSize.Size18 shortDescriptionBox.Position = UDim2.new(0,3,0,3) shortDescriptionBox.Size = UDim2.new(1,-6,1,-6) shortDescriptionBox.TextColor3 = Color3I(255,255,255) shortDescriptionBox.TextXAlignment = Enum.TextXAlignment.Left shortDescriptionBox.TextYAlignment = Enum.TextYAlignment.Top shortDescriptionBox.TextWrap = true shortDescriptionBox.BackgroundColor3 = Color3I(0,0,0) shortDescriptionBox.BorderSizePixel = 0 shortDescriptionBox.ZIndex = baseZIndex + 2 shortDescriptionBox.Parent = shortDescriptionWrapper submitReportButton = Instance.new("TextButton") submitReportButton.Name = "SubmitReportBtn" submitReportButton.Active = false submitReportButton.Modal = true submitReportButton.Font = Enum.Font.Arial submitReportButton.FontSize = Enum.FontSize.Size18 submitReportButton.Position = UDim2.new(0.1, 0, 1, -80) submitReportButton.Size = UDim2.new(0.35,0,0,50) submitReportButton.AutoButtonColor = true submitReportButton.Style = Enum.ButtonStyle.RobloxButtonDefault submitReportButton.Text = "Submit Report" submitReportButton.TextColor3 = Color3I(255,255,255) submitReportButton.ZIndex = baseZIndex + 2 submitReportButton.Parent = settingsFrame submitReportButton.MouseButton1Click:connect(function() if submitReportButton.Active then if abuse and abusingPlayer then frame.Visible = false game.Players:ReportAbuse(abusingPlayer, abuse, shortDescriptionBox.Text) if abuse == "Cheating/Exploiting" then recordedMessageBox.Visible = true elseif abuse == "Bullying" or abuse == "Swearing" then calmingMessageBox.Visible = true else normalMessageBox.Visible = true end else closeAndResetDialog() end end end) local cancelButton = Instance.new("TextButton") cancelButton.Name = "CancelBtn" cancelButton.Font = Enum.Font.Arial cancelButton.FontSize = Enum.FontSize.Size18 cancelButton.Position = UDim2.new(0.55, 0, 1, -80) cancelButton.Size = UDim2.new(0.35,0,0,50) cancelButton.AutoButtonColor = true cancelButton.Style = Enum.ButtonStyle.RobloxButtonDefault cancelButton.Text = "Cancel" cancelButton.TextColor3 = Color3I(255,255,255) cancelButton.ZIndex = baseZIndex + 2 cancelButton.Parent = settingsFrame closeAndResetDialog = function() --Delete old player combo box local oldComboBox = settingsFrame:FindFirstChild("PlayersComboBox") if oldComboBox then oldComboBox.Parent = nil end abusingPlayer = nil updatePlayerSelection(nil) abuse = nil updateAbuseSelection(nil) submitReportButton.Active = false shortDescriptionBox.Text = "" frame.Visible = true calmingMessageBox.Visible = false recordedMessageBox.Visible = false normalMessageBox.Visible = false shield.Visible = false reportAbuseButton.Active = true game.GuiService:RemoveCenterDialog(shield) end cancelButton.MouseButton1Click:connect(closeAndResetDialog) reportAbuseButton.MouseButton1Click:connect( function() createPlayersDropDown().Parent = settingsFrame table.insert(centerDialogs,shield) game.GuiService:AddCenterDialog(shield, Enum.CenterDialogType.ModalDialog, --ShowFunction function() reportAbuseButton.Active = true shield.Visible = true mainShield.Visible = false end, --HideFunction function() reportAbuseButton.Active = true shield.Visible = false end) end) end) local createSaveDialogs = function() local shield = Instance.new("TextButton") shield.Text = "" shield.AutoButtonColor = false shield.Name = "SaveDialogShield" shield.Active = true shield.Visible = false shield.Size = UDim2.new(1,0,1,0) shield.BackgroundColor3 = Color3I(51,51,51) shield.BorderColor3 = Color3I(27,42,53) shield.BackgroundTransparency = 0.4 shield.ZIndex = baseZIndex+1 local clearAndResetDialog local save local saveLocal local dontSave local cancel local messageBoxButtons = {} messageBoxButtons[1] = {} messageBoxButtons[1].Text = "Save" messageBoxButtons[1].Style = Enum.ButtonStyle.RobloxButtonDefault messageBoxButtons[1].Function = function() save() end messageBoxButtons[2] = {} messageBoxButtons[2].Text = "Cancel" messageBoxButtons[2].Function = function() cancel() end messageBoxButtons[3] = {} messageBoxButtons[3].Text = "Don't Save" messageBoxButtons[3].Function = function() dontSave() end local saveDialogMessageBox = RbxGui.CreateStyledMessageDialog("Unsaved Changes", "Save your changes to ROBLOX before leaving?", "Confirm", messageBoxButtons) saveDialogMessageBox.Visible = true saveDialogMessageBox.Parent = shield local errorBoxButtons = {} local buttonOffset = 1 if game.LocalSaveEnabled then errorBoxButtons[buttonOffset] = {} errorBoxButtons[buttonOffset].Text = "Save to Disk" errorBoxButtons[buttonOffset].Function = function() saveLocal() end buttonOffset = buttonOffset + 1 end errorBoxButtons[buttonOffset] = {} errorBoxButtons[buttonOffset].Text = "Keep Playing" errorBoxButtons[buttonOffset].Function = function() cancel() end errorBoxButtons[buttonOffset+1] = {} errorBoxButtons[buttonOffset+1].Text = "Don't Save" errorBoxButtons[buttonOffset+1].Function = function() dontSave() end local errorDialogMessageBox = RbxGui.CreateStyledMessageDialog("Upload Failed", "Sorry, we could not save your changes to ROBLOX.", "Error", errorBoxButtons) errorDialogMessageBox.Visible = false errorDialogMessageBox.Parent = shield local spinnerDialog = Instance.new("Frame") spinnerDialog.Name = "SpinnerDialog" spinnerDialog.Style = Enum.FrameStyle.RobloxRound spinnerDialog.Size = UDim2.new(0, 350, 0, 150) spinnerDialog.Position = UDim2.new(.5, -175, .5, -75) spinnerDialog.Visible = false spinnerDialog.Active = true spinnerDialog.Parent = shield local waitingLabel = Instance.new("TextLabel") waitingLabel.Name = "WaitingLabel" waitingLabel.Text = "Saving to ROBLOX..." waitingLabel.Font = Enum.Font.ArialBold waitingLabel.FontSize = Enum.FontSize.Size18 waitingLabel.Position = UDim2.new(0.5, 25, 0.5, 0) waitingLabel.TextColor3 = Color3.new(1,1,1) waitingLabel.Parent = spinnerDialog local spinnerFrame = Instance.new("Frame") spinnerFrame.Name = "Spinner" spinnerFrame.Size = UDim2.new(0, 80, 0, 80) spinnerFrame.Position = UDim2.new(0.5, -150, 0.5, -40) spinnerFrame.BackgroundTransparency = 1 spinnerFrame.Parent = spinnerDialog local spinnerIcons = {} local spinnerNum = 1 while spinnerNum <= 8 do local spinnerImage = Instance.new("ImageLabel") spinnerImage.Name = "Spinner"..spinnerNum spinnerImage.Size = UDim2.new(0, 16, 0, 16) spinnerImage.Position = UDim2.new(.5+.3*math.cos(math.rad(45*spinnerNum)), -8, .5+.3*math.sin(math.rad(45*spinnerNum)), -8) spinnerImage.BackgroundTransparency = 1 spinnerImage.Image = "http://www.roblox.com/Asset?id=45880710" spinnerImage.Parent = spinnerFrame spinnerIcons[spinnerNum] = spinnerImage spinnerNum = spinnerNum + 1 end save = function() saveDialogMessageBox.Visible = false --Show the spinner dialog spinnerDialog.Visible = true local spin = true --Make it spin delay(0, function() local spinPos = 0 while spin do local pos = 0 while pos < 8 do if pos == spinPos or pos == ((spinPos+1)%8) then spinnerIcons[pos+1].Image = "http://www.roblox.com/Asset?id=45880668" else spinnerIcons[pos+1].Image = "http://www.roblox.com/Asset?id=45880710" end pos = pos + 1 end spinPos = (spinPos + 1) % 8 wait(0.2) end end) --Do the save while the spinner is going, function will wait local result = game:SaveToRoblox() if not result then --Try once more result = game:SaveToRoblox() end --Hide the spinner dialog spinnerDialog.Visible = false --And cause the delay thread to stop spin = false --Now process the result if result then --Success, close game:FinishShutdown(false) clearAndResetDialog() else --Failure, show the second dialog prompt errorDialogMessageBox.Visible = true end end saveLocal = function() errorDialogMessageBox.Visible = false game:FinishShutdown(true) clearAndResetDialog() end dontSave = function() saveDialogMessageBox.Visible = false errorDialogMessageBox.Visible = false game:FinishShutdown(false) clearAndResetDialog() end cancel = function() saveDialogMessageBox.Visible = false errorDialogMessageBox.Visible = false clearAndResetDialog() end clearAndResetDialog = function() saveDialogMessageBox.Visible = true errorDialogMessageBox.Visible = false spinnerDialog.Visible = false shield.Visible = false game.GuiService:RemoveCenterDialog(shield) end shield.Visible = false return shield end local createReportAbuseDialog = function() --Only show things if we are a NetworkClient waitForChild(game,"NetworkClient") waitForChild(game,"Players") waitForProperty(game.Players, "LocalPlayer") local localPlayer = game.Players.LocalPlayer local reportAbuseButton waitForChild(script.Parent,"UserSettingsShield") waitForChild(script.Parent.UserSettingsShield, "Settings") waitForChild(script.Parent.UserSettingsShield.Settings,"SettingsStyle") waitForChild(script.Parent.UserSettingsShield.Settings.SettingsStyle,"GameMainMenu") waitForChild(script.Parent.UserSettingsShield.Settings.SettingsStyle.GameMainMenu, "ReportAbuseButton") reportAbuseButton = script.Parent.UserSettingsShield.Settings.SettingsStyle.GameMainMenu.ReportAbuseButton local shield = Instance.new("TextButton") shield.Name = "ReportAbuseShield" shield.Text = "" shield.AutoButtonColor = false shield.Active = true shield.Visible = false shield.Size = UDim2.new(1,0,1,0) shield.BackgroundColor3 = Color3I(51,51,51) shield.BorderColor3 = Color3I(27,42,53) shield.BackgroundTransparency = 0.4 shield.ZIndex = baseZIndex + 1 shield.Parent = script.Parent local closeAndResetDialgo local messageBoxButtons = {} messageBoxButtons[1] = {} messageBoxButtons[1].Text = "Ok" messageBoxButtons[1].Modal = true messageBoxButtons[1].Function = function() closeAndResetDialog() end local calmingMessageBox = RbxGui.CreateMessageDialog("Thanks for your report!", "Our moderators will review the chat logs and determine what happened. The other user is probably just trying to make you mad.\n\nIf anyone used swear words, inappropriate language, or threatened you in real life, please report them for Bad Words or Threats", messageBoxButtons) calmingMessageBox.Visible = false calmingMessageBox.Parent = shield local recordedMessageBox = RbxGui.CreateMessageDialog("Thanks for your report!","We've recorded your report for evaluation.", messageBoxButtons) recordedMessageBox.Visible = false recordedMessageBox.Parent = shield local normalMessageBox = RbxGui.CreateMessageDialog("Thanks for your report!", "Our moderators will review the chat logs and determine what happened.", messageBoxButtons) normalMessageBox.Visible = false normalMessageBox.Parent = shield local frame = Instance.new("Frame") frame.Name = "Settings" frame.Position = UDim2.new(0.5, -250, 0.5, -200) frame.Size = UDim2.new(0.0, 500, 0.0, 400) frame.BackgroundTransparency = 1 frame.Active = true frame.Parent = shield local settingsFrame = Instance.new("Frame") settingsFrame.Name = "ReportAbuseStyle" settingsFrame.Size = UDim2.new(1, 0, 1, 0) settingsFrame.Style = Enum.FrameStyle.RobloxRound settingsFrame.Active = true settingsFrame.ZIndex = baseZIndex + 1 settingsFrame.Parent = frame local title = Instance.new("TextLabel") title.Name = "Title" title.Text = "Report Abuse" title.TextColor3 = Color3I(221,221,221) title.Position = UDim2.new(0.5, 0, 0, 30) title.Font = Enum.Font.ArialBold title.FontSize = Enum.FontSize.Size36 title.ZIndex = baseZIndex + 2 title.Parent = settingsFrame local description = Instance.new("TextLabel") description.Name = "Description" description.Text = "This will send a complete report to a moderator. The moderator will review the chat log and take appropriate action." description.TextColor3 = Color3I(221,221,221) description.Position = UDim2.new(0, 0, 0, 55) description.Size = UDim2.new(1, 0, 0, 40) description.BackgroundTransparency = 1 description.Font = Enum.Font.Arial description.FontSize = Enum.FontSize.Size18 description.TextWrap = true description.ZIndex = baseZIndex + 2 description.TextXAlignment = Enum.TextXAlignment.Left description.TextYAlignment = Enum.TextYAlignment.Top description.Parent = settingsFrame local playerLabel = Instance.new("TextLabel") playerLabel.Name = "PlayerLabel" playerLabel.Text = "Which player?" playerLabel.BackgroundTransparency = 1 playerLabel.Font = Enum.Font.Arial playerLabel.FontSize = Enum.FontSize.Size18 playerLabel.Position = UDim2.new(0.025,0,0,100) playerLabel.Size = UDim2.new(0.4,0,0,36) playerLabel.TextColor3 = Color3I(255,255,255) playerLabel.TextXAlignment = Enum.TextXAlignment.Left playerLabel.ZIndex = baseZIndex + 2 playerLabel.Parent = settingsFrame local abusingPlayer = nil local abuse = nil local submitReportButton = nil local updatePlayerSelection = nil local createPlayersDropDown = function() local players = game:GetService("Players") local playerNames = {} local nameToPlayer = {} local children = players:GetChildren() local pos = 1 if children then for i, player in ipairs(children) do if player:IsA("Player") and player ~= localPlayer then playerNames[pos] = player.Name nameToPlayer[player.Name] = player pos = pos + 1 end end end local playerDropDown = nil playerDropDown, updatePlayerSelection = RbxGui.CreateDropDownMenu(playerNames, function(playerName) abusingPlayer = nameToPlayer[playerName] if abuse and abusingPlayer then submitReportButton.Active = true end end) playerDropDown.Name = "PlayersComboBox" playerDropDown.ZIndex = baseZIndex + 2 playerDropDown.Position = UDim2.new(.425, 0, 0, 102) playerDropDown.Size = UDim2.new(.55,0,0,32) return playerDropDown end local abuseLabel = Instance.new("TextLabel") abuseLabel.Name = "AbuseLabel" abuseLabel.Text = "Type of Abuse:" abuseLabel.Font = Enum.Font.Arial abuseLabel.BackgroundTransparency = 1 abuseLabel.FontSize = Enum.FontSize.Size18 abuseLabel.Position = UDim2.new(0.025,0,0,140) abuseLabel.Size = UDim2.new(0.4,0,0,36) abuseLabel.TextColor3 = Color3I(255,255,255) abuseLabel.TextXAlignment = Enum.TextXAlignment.Left abuseLabel.ZIndex = baseZIndex + 2 abuseLabel.Parent = settingsFrame local abuses = {"Swearing","Bullying","Scamming","Dating","Cheating/Exploiting","Personal Questions","Offsite Links","Bad Model or Script","Bad Username"} local abuseDropDown, updateAbuseSelection = RbxGui.CreateDropDownMenu(abuses, function(abuseText) abuse = abuseText if abuse and abusingPlayer then submitReportButton.Active = true end end, true) abuseDropDown.Name = "AbuseComboBox" abuseDropDown.ZIndex = baseZIndex + 2 abuseDropDown.Position = UDim2.new(0.425, 0, 0, 142) abuseDropDown.Size = UDim2.new(0.55,0,0,32) abuseDropDown.Parent = settingsFrame local shortDescriptionLabel = Instance.new("TextLabel") shortDescriptionLabel.Name = "ShortDescriptionLabel" shortDescriptionLabel.Text = "Short Description: (optional)" shortDescriptionLabel.Font = Enum.Font.Arial shortDescriptionLabel.FontSize = Enum.FontSize.Size18 shortDescriptionLabel.Position = UDim2.new(0.025,0,0,180) shortDescriptionLabel.Size = UDim2.new(0.95,0,0,36) shortDescriptionLabel.TextColor3 = Color3I(255,255,255) shortDescriptionLabel.TextXAlignment = Enum.TextXAlignment.Left shortDescriptionLabel.BackgroundTransparency = 1 shortDescriptionLabel.ZIndex = baseZIndex + 2 shortDescriptionLabel.Parent = settingsFrame local shortDescriptionWrapper = Instance.new("Frame") shortDescriptionWrapper.Name = "ShortDescriptionWrapper" shortDescriptionWrapper.Position = UDim2.new(0.025,0,0,220) shortDescriptionWrapper.Size = UDim2.new(0.95,0,1,-310) shortDescriptionWrapper.BackgroundColor3 = Color3I(0,0,0) shortDescriptionWrapper.BorderSizePixel = 0 shortDescriptionWrapper.ZIndex = baseZIndex + 2 shortDescriptionWrapper.Parent = settingsFrame local shortDescriptionBox = Instance.new("TextBox") shortDescriptionBox.Name = "TextBox" shortDescriptionBox.Text = "" shortDescriptionBox.ClearTextOnFocus = false shortDescriptionBox.Font = Enum.Font.Arial shortDescriptionBox.FontSize = Enum.FontSize.Size18 shortDescriptionBox.Position = UDim2.new(0,3,0,3) shortDescriptionBox.Size = UDim2.new(1,-6,1,-6) shortDescriptionBox.TextColor3 = Color3I(255,255,255) shortDescriptionBox.TextXAlignment = Enum.TextXAlignment.Left shortDescriptionBox.TextYAlignment = Enum.TextYAlignment.Top shortDescriptionBox.TextWrap = true shortDescriptionBox.BackgroundColor3 = Color3I(0,0,0) shortDescriptionBox.BorderSizePixel = 0 shortDescriptionBox.ZIndex = baseZIndex + 2 shortDescriptionBox.Parent = shortDescriptionWrapper submitReportButton = Instance.new("TextButton") submitReportButton.Name = "SubmitReportBtn" submitReportButton.Active = false submitReportButton.Modal = true submitReportButton.Font = Enum.Font.Arial submitReportButton.FontSize = Enum.FontSize.Size18 submitReportButton.Position = UDim2.new(0.1, 0, 1, -80) submitReportButton.Size = UDim2.new(0.35,0,0,50) submitReportButton.AutoButtonColor = true submitReportButton.Style = Enum.ButtonStyle.RobloxButtonDefault submitReportButton.Text = "Submit Report" submitReportButton.TextColor3 = Color3I(255,255,255) submitReportButton.ZIndex = baseZIndex + 2 submitReportButton.Parent = settingsFrame submitReportButton.MouseButton1Click:connect(function() if submitReportButton.Active then if abuse and abusingPlayer then frame.Visible = false game.Players:ReportAbuse(abusingPlayer, abuse, shortDescriptionBox.Text) if abuse == "Cheating/Exploiting" then recordedMessageBox.Visible = true elseif abuse == "Bullying" or abuse == "Swearing" then calmingMessageBox.Visible = true else normalMessageBox.Visible = true end else closeAndResetDialog() end end end) local cancelButton = Instance.new("TextButton") cancelButton.Name = "CancelBtn" cancelButton.Font = Enum.Font.Arial cancelButton.FontSize = Enum.FontSize.Size18 cancelButton.Position = UDim2.new(0.55, 0, 1, -80) cancelButton.Size = UDim2.new(0.35,0,0,50) cancelButton.AutoButtonColor = true cancelButton.Style = Enum.ButtonStyle.RobloxButtonDefault cancelButton.Text = "Cancel" cancelButton.TextColor3 = Color3I(255,255,255) cancelButton.ZIndex = baseZIndex + 2 cancelButton.Parent = settingsFrame closeAndResetDialog = function() --Delete old player combo box local oldComboBox = settingsFrame:FindFirstChild("PlayersComboBox") if oldComboBox then oldComboBox.Parent = nil end abusingPlayer = nil updatePlayerSelection(nil) abuse = nil updateAbuseSelection(nil) submitReportButton.Active = false shortDescriptionBox.Text = "" frame.Visible = true calmingMessageBox.Visible = false recordedMessageBox.Visible = false normalMessageBox.Visible = false shield.Visible = false reportAbuseButton.Active = true game.GuiService:RemoveCenterDialog(shield) end cancelButton.MouseButton1Click:connect(closeAndResetDialog) reportAbuseButton.MouseButton1Click:connect( function() createPlayersDropDown().Parent = settingsFrame table.insert(centerDialogs,shield) game.GuiService:AddCenterDialog(shield, Enum.CenterDialogType.ModalDialog, --ShowFunction function() reportAbuseButton.Active = true shield.Visible = true mainShield.Visible = false end, --HideFunction function() reportAbuseButton.Active = true shield.Visible = false end) end) return shield end local createChatBar = function() --Only show a chat bar if we are a NetworkClient waitForChild(game, "NetworkClient") waitForChild(game, "Players") waitForProperty(game.Players, "LocalPlayer") local chatBar = Instance.new("Frame") chatBar.Name = "ChatBar" chatBar.Size = UDim2.new(1, 0, 0, 22) chatBar.Position = UDim2.new(0, 0, 1, 0) chatBar.BackgroundColor3 = Color3.new(0,0,0) chatBar.BorderSizePixel = 0 local chatBox = Instance.new("TextBox") chatBox.Text = "" chatBox.Visible = false chatBox.Size = UDim2.new(1,-4,1,0) chatBox.Position = UDim2.new(0,2,0,0) chatBox.TextXAlignment = Enum.TextXAlignment.Left chatBox.Font = Enum.Font.Arial chatBox.ClearTextOnFocus = false chatBox.FontSize = Enum.FontSize.Size14 chatBox.TextColor3 = Color3.new(1,1,1) chatBox.BackgroundTransparency = 1 --chatBox.Parent = chatBar local chatButton = Instance.new("TextButton") chatButton.Size = UDim2.new(1,-4,1,0) chatButton.Position = UDim2.new(0,2,0,0) chatButton.AutoButtonColor = false chatButton.Text = "To chat click here or press \"/\" key" chatButton.TextXAlignment = Enum.TextXAlignment.Left chatButton.Font = Enum.Font.Arial chatButton.FontSize = Enum.FontSize.Size14 chatButton.TextColor3 = Color3.new(1,1,1) chatButton.BackgroundTransparency = 1 --chatButton.Parent = chatBar local activateChat = function() if chatBox.Visible then return end chatButton.Visible = false chatBox.Text = "" chatBox.Visible = true chatBox:CaptureFocus() end chatButton.MouseButton1Click:connect(activateChat) local hotKeyEnabled = true local toggleHotKey = function(value) hotKeyEnabled = value end local guiService = game:GetService("GuiService") local newChatMode = pcall(function() --guiService:AddSpecialKey(Enum.SpecialKey.ChatHotkey) --guiService.SpecialKeyPressed:connect(function(key) if key == Enum.SpecialKey.ChatHotkey and hotKeyEnabled then activateChat() end end) end) if not newChatMode then --guiService:AddKey("/") --guiService.KeyPressed:connect(function(key) if key == "/" and hotKeyEnabled then activateChat() end end) end chatBox.FocusLost:connect( function(enterPressed) if enterPressed then if chatBox.Text ~= "" then local str = chatBox.Text if string.sub(str, 1, 1) == '%' then game.Players:TeamChat(string.sub(str, 2)) else game.Players:Chat(str) end end end chatBox.Text = "" chatBox.Visible = false chatButton.Visible = true end) return chatBar, toggleHotKey end --Spawn a thread for the Save dialogs local isSaveDialogSupported = pcall(function() local var = game.LocalSaveEnabled end) if isSaveDialogSupported then delay(0, function() local saveDialogs = createSaveDialogs() saveDialogs.Parent = gui game.RequestShutdown = function() table.insert(centerDialogs,saveDialogs) game.GuiService:AddCenterDialog(saveDialogs, Enum.CenterDialogType.QuitDialog, --ShowFunction function() saveDialogs.Visible = true end, --HideFunction function() saveDialogs.Visible = false end) return true end end) end --Spawn a thread for the Report Abuse dialogs --Spawn a thread for the Report Abuse dialogs delay(0, function() createReportAbuseDialog().Parent = script.Parent waitForChild(script.Parent,"UserSettingsShield") waitForChild(script.Parent.UserSettingsShield, "Settings") waitForChild(script.Parent.UserSettingsShield.Settings,"SettingsStyle") waitForChild(script.Parent.UserSettingsShield.Settings.SettingsStyle,"GameMainMenu") waitForChild(script.Parent.UserSettingsShield.Settings.SettingsStyle.GameMainMenu, "ReportAbuseButton") script.Parent.UserSettingsShield.Settings.SettingsStyle.GameMainMenu.ReportAbuseButton.Active = true end) end end false 4288914085 1 4279970357 1 false false ControlFrame 0 0 0 0 1 0 1 0 0 0 true 1 false 4288914085 1 4279970357 1 false false BottomLeftControl 0 0 1 -46 0 130 0 46 0 0 true 1 true true 4288914085 1 4279970357 1 false false rbxasset://textures/Exit.png false Exit 0 2 0 -2 false 0 56 0 41 0 0 false 1 false 4288914085 1 4279970357 1 false false BottomRightControl 1 -180 1 -41 0 180 0 41 0 0 true 1 false 4288914085 1 4279970357 1 false false TopLeftControl 0 0 0 0 0.0500000007 0 0.0500000007 0 0 0 true 1 false 4288914085 1 4279970357 1 false false NotificationBox 1 -200 0.5 0 0 200 0.419999987 0 0 true 1 false Workaround wait(0.1) game.Players.LocalPlayer.PlayerGui.Menu.MenuScript.Disabled = true game.Players.LocalPlayer.PlayerGui.Menu.MenuScript.Disabled = false