import "macros" as { $ } $load $FILE t = {} ScopedConnect = (parentInstance, instance, event, signalFunc, syncFunc, removeFunc) -> local eventConnection --Connection on parentInstance is scoped by parentInstance (when destroyed, it goes away) tryConnect = -> if game\IsAncestorOf parentInstance --Entering the world, make sure we are connected/synced if not eventConnection eventConnection = instance[event]\connect signalFunc if syncFunc syncFunc! else --Probably leaving the world, so disconnect for now if eventConnection eventConnection\disconnect! if removeFunc removeFunc! --Hook it up to ancestryChanged signal connection = parentInstance.AncestryChanged\connect tryConnect --Now connect us if we're already in the world tryConnect! connection getScreenGuiAncestor = (instance) -> localInstance = instance while localInstance and not localInstance\IsA "ScreenGui" localInstance = localInstance.Parent localInstance CreateButtons = (frame, buttons, yPos, ySize) -> buttonNum = 1 buttonObjs = {} for _, obj in ipairs buttons 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"] button.Style = obj.Style else button.Style = Enum.ButtonStyle.RobloxButton button.Text = obj.Text button.TextColor3 = Color3.new 1, 1, 1 button.MouseButton1Click\connect obj.Function button.Parent = frame buttonObjs[buttonNum] = button buttonNum += 1 numButtons = buttonNum - 1 if numButtons == 1 frame.Button1.Position = UDim2.new 0.35, 0, yPos.Scale, yPos.Offset frame.Button1.Size = UDim2.new 0.4, 0, ySize.Scale, ySize.Offset elseif numButtons == 2 frame.Button1.Position = UDim2.new 0.1, 0, yPos.Scale, yPos.Offset frame.Button1.Size = UDim2.new 0.8 / 3, 0, ySize.Scale, ySize.Offset frame.Button2.Position = UDim2.new 0.55, 0, yPos.Scale, yPos.Offset frame.Button2.Size = UDim2.new 0.35, 0, ySize.Scale, ySize.Offset elseif numButtons >= 3 spacing = 0.1 / numButtons buttonSize = 0.9 / numButtons buttonNum = 1 while buttonNum <= numButtons 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 += 1 setSliderPos = (newAbsPosX, slider, sliderPosition, bar, steps) -> newStep = steps - 1 --otherwise we really get one more step than we want relativePosX = math.min 1, math.max(0, (newAbsPosX - bar.AbsolutePosition.X) / bar.AbsoluteSize.X) wholeNum, remainder = math.modf relativePosX * newStep if remainder > 0.5 wholeNum += 1 relativePosX = wholeNum / newStep result = math.ceil relativePosX * newStep if sliderPosition.Value ~= (result + 1) --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 cancelSlide = (areaSoak) -> areaSoak.Visible = false if areaSoakMouseMoveCon areaSoakMouseMoveCon\disconnect! t.CreateStyledMessageDialog = (title, message, style, buttons) -> 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 styleImage = Instance.new "ImageLabel" styleImage.Name = "StyleImage" styleImage.BackgroundTransparency = 1 styleImage.Position = UDim2.new 0, 5, 0, 15 if style == "error" or style == "Error" styleImage.Size = UDim2.new 0, 71, 0, 71 styleImage.Image = "http://www.roblox.com/asset?id=42565285" elseif style == "notify" or style == "Notify" styleImage.Size = UDim2.new 0, 71, 0, 71 styleImage.Image = "http://www.roblox.com/asset?id=42604978" elseif style == "confirm" or style == "Confirm" styleImage.Size = UDim2.new 0, 74, 0, 76 styleImage.Image = "http://www.roblox.com/asset?id=42557901" else return t.CreateMessageDialog title, message, buttons styleImage.Parent = frame 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 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) frame t.CreateMessageDialog = (title, message, buttons) -> 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 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 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, 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) frame t.CreateDropDownMenu = (items, onSelect, forRoblox) -> width = UDim.new 0, 100 height = UDim.new 0, 32 frame = Instance.new "Frame" frame.Name = "DropDownMenu" frame.BackgroundTransparency = 1 frame.Size = UDim2.new width, height dropDownMenu = Instance.new "TextButton" dropDownMenu.Name = "DropDownMenuButton" dropDownMenu.TextWrap = true dropDownMenu.TextColor3 = Color3.new 1, 1, 1 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 dropDownMenu.Style = Enum.ButtonStyle.RobloxButton dropDownMenu.Size = UDim2.new 1, 0, 1, 0 dropDownMenu.Parent = frame dropDownMenu.ZIndex = 2 dropDownIcon = Instance.new "ImageLabel" dropDownIcon.Name = "Icon" dropDownIcon.Active = false dropDownIcon.Image = "http://www.roblox.com/asset/?id=45732894" dropDownIcon.BackgroundTransparency = 1 dropDownIcon.Size = UDim2.new 0, 11, 0, 6 dropDownIcon.Position = UDim2.new 1, -11, 0.5, -2 dropDownIcon.Parent = dropDownMenu dropDownIcon.ZIndex = 2 itemCount = #items dropDownItemCount = #items useScrollButtons = false if dropDownItemCount > 6 useScrollButtons = true dropDownItemCount = 6 droppedDownMenu = Instance.new "TextButton" droppedDownMenu.Name = "List" droppedDownMenu.Text = "" droppedDownMenu.BackgroundTransparency = 1 --droppedDownMenu.AutoButtonColor = true droppedDownMenu.Style = Enum.ButtonStyle.RobloxButton droppedDownMenu.Visible = false droppedDownMenu.Active = true --Blocks clicks droppedDownMenu.Position = UDim2.new 0, 0, 0, 0 droppedDownMenu.Size = UDim2.new 1, 0, (1 + dropDownItemCount) * 0.8, 0 droppedDownMenu.Parent = frame droppedDownMenu.ZIndex = 2 choiceButton = Instance.new "TextButton" choiceButton.Name = "ChoiceButton" choiceButton.BackgroundTransparency = 1 choiceButton.BorderSizePixel = 0 choiceButton.Text = "ReplaceMe" choiceButton.TextColor3 = Color3.new 1, 1, 1 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 choiceButton.Size = UDim2.new 1, -13, 0.8 / ((dropDownItemCount + 1) * 0.8), 0 else choiceButton.Size = UDim2.new 1, 0, 0.8 / ((dropDownItemCount + 1) * 0.8), 0 choiceButton.TextWrap = true choiceButton.ZIndex = 2 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 dropDownSelected = false local scrollUpButton local scrollDownButton scrollMouseCount = 0 setZIndex = (baseZIndex) -> droppedDownMenu.ZIndex = baseZIndex + 1 if scrollUpButton scrollUpButton.ZIndex = baseZIndex + 3 if scrollDownButton scrollDownButton.ZIndex = baseZIndex + 3 children = droppedDownMenu\GetChildren! if children for _, child in ipairs children if child.Name == "ChoiceButton" child.ZIndex = baseZIndex + 2 elseif child.Name == "ClickCaptureButton" child.ZIndex = baseZIndex scrollBarPosition = 1 updateScroll = -> if scrollUpButton scrollUpButton.Active = scrollBarPosition > 1 if scrollDownButton scrollDownButton.Active = scrollBarPosition + dropDownItemCount <= itemCount children = droppedDownMenu\GetChildren! if not children return childNum = 1 for _, obj in ipairs children if obj.Name == "ChoiceButton" if childNum < scrollBarPosition or childNum >= scrollBarPosition + dropDownItemCount obj.Visible = false else obj.Position = UDim2.new 0, 0, ((childNum - scrollBarPosition + 1) * 0.8) / ((dropDownItemCount + 1) * 0.8), 0 obj.Visible = true obj.TextColor3 = Color3.new 1, 1, 1 obj.BackgroundTransparency = 1 childNum += 1 toggleVisibility = -> dropDownSelected = not dropDownSelected areaSoak.Visible = not areaSoak.Visible dropDownMenu.Visible = not dropDownSelected droppedDownMenu.Visible = dropDownSelected if dropDownSelected setZIndex 4 else setZIndex 2 if useScrollButtons updateScroll! droppedDownMenu.MouseButton1Click\connect toggleVisibility updateSelection = (text) -> foundItem = false children = droppedDownMenu\GetChildren! childNum = 1 if children for _, obj in ipairs children if obj.Name == "ChoiceButton" if obj.Text == text obj.Font = Enum.Font.ArialBold foundItem = true scrollBarPosition = childNum else obj.Font = Enum.Font.Arial childNum += 1 if not text dropDownMenu.Text = "Choose One" scrollBarPosition = 1 else if not foundItem error "Invalid Selection Update -- " .. text if scrollBarPosition + dropDownItemCount > itemCount + 1 scrollBarPosition = itemCount - dropDownItemCount + 1 dropDownMenu.Text = text scrollDown = -> if scrollBarPosition + dropDownItemCount <= itemCount scrollBarPosition += 1 updateScroll! return true return false scrollUp = -> if scrollBarPosition > 1 scrollBarPosition -= 1 updateScroll! return true return false if useScrollButtons --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 * 0.8) / ((dropDownItemCount + 1) * 0.8), 0 scrollUpButton.MouseButton1Click\connect -> scrollMouseCount += 1 scrollUpButton.MouseLeave\connect -> scrollMouseCount += 1 scrollUpButton.MouseButton1Down\connect -> scrollMouseCount += 1 scrollUp! val = scrollMouseCount wait 0.5 while val == scrollMouseCount if scrollUp! == false break wait 0.1 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 -> scrollMouseCount += 1 scrollDownButton.MouseLeave\connect -> scrollMouseCount += 1 scrollDownButton.MouseButton1Down\connect -> scrollMouseCount += 1 scrollDown! val = scrollMouseCount wait 0.5 while val == scrollMouseCount if scrollDown! == false break wait 0.1 scrollbar = Instance.new "ImageLabel" scrollbar.Name = "ScrollBar" scrollbar.Image = "rbxasset://textures/ui/scrollbar.png" scrollbar.BackgroundTransparency = 1 scrollbar.Size = UDim2.new 0, 18, (dropDownItemCount * 0.8) / ((dropDownItemCount + 1) * 0.8), -17 - 11 - 4 scrollbar.Position = UDim2.new 1, -11, (1 * 0.8) / ((dropDownItemCount + 1) * 0.8), 17 + 2 scrollbar.Parent = droppedDownMenu for _, item in ipairs items -- needed to maintain local scope for items in event listeners below button = choiceButton\clone! if forRoblox button.RobloxLocked = true button.Text = item button.Parent = droppedDownMenu button.MouseButton1Click\connect -> --Remove Highlight button.TextColor3 = Color3.new 1, 1, 1 button.BackgroundTransparency = 1 updateSelection item onSelect item toggleVisibility! button.MouseEnter\connect -> --Add Highlight button.TextColor3 = Color3.new 0, 0, 0 button.BackgroundTransparency = 0 button.MouseLeave\connect -> --Remove Highlight button.TextColor3 = Color3.new 1, 1, 1 button.BackgroundTransparency = 1 --This does the initial layout of the buttons updateScroll! frame.AncestryChanged\connect (_, parent) -> if parent == nil areaSoak.Parent = nil else areaSoak.Parent = getScreenGuiAncestor frame dropDownMenu.MouseButton1Click\connect toggleVisibility areaSoak.MouseButton1Click\connect toggleVisibility return frame, updateSelection t.CreatePropertyDropDownMenu = (instance, property, enum) -> items = enum\GetEnumItems! names = {} nameToItem = {} for i, obj in ipairs items names[i] = obj.Name nameToItem[obj.Name] = obj local frame local updateSelection frame, updateSelection = t.CreateDropDownMenu names, (text) -> instance[property] = nameToItem[text] ScopedConnect(frame, instance, "Changed" (prop) -> if prop == property updateSelection instance[property].Name -> updateSelection instance[property].Name ) return frame t.GetFontHeight = (font, fontSize) -> if font == nil or fontSize == nil error "Font and FontSize must be non-nil" if font == Enum.Font.Legacy if fontSize == Enum.FontSize.Size8 return 12 elseif fontSize == Enum.FontSize.Size9 return 14 elseif fontSize == Enum.FontSize.Size10 return 15 elseif fontSize == Enum.FontSize.Size11 return 17 elseif fontSize == Enum.FontSize.Size12 return 18 elseif fontSize == Enum.FontSize.Size14 return 21 elseif fontSize == Enum.FontSize.Size18 return 27 elseif fontSize == Enum.FontSize.Size24 return 36 elseif fontSize == Enum.FontSize.Size36 return 54 elseif fontSize == Enum.FontSize.Size48 return 72 else error "Unknown FontSize" elseif font == Enum.Font.Arial or font == Enum.Font.ArialBold if fontSize == Enum.FontSize.Size8 return 8 elseif fontSize == Enum.FontSize.Size9 return 9 elseif fontSize == Enum.FontSize.Size10 return 10 elseif fontSize == Enum.FontSize.Size11 return 11 elseif fontSize == Enum.FontSize.Size12 return 12 elseif fontSize == Enum.FontSize.Size14 return 14 elseif fontSize == Enum.FontSize.Size18 return 18 elseif fontSize == Enum.FontSize.Size24 return 24 elseif fontSize == Enum.FontSize.Size36 return 36 elseif fontSize == Enum.FontSize.Size48 return 48 else error "Unknown FontSize" else error "Unknown Font " .. font layoutGuiObjectsHelper = (frame, guiObjects, settingsTable) -> totalPixels = frame.AbsoluteSize.Y pixelsRemaining = frame.AbsoluteSize.Y for _, child in ipairs guiObjects if child\IsA"TextLabel" or child\IsA "TextButton" isLabel = child\IsA "TextLabel" if isLabel pixelsRemaining -= settingsTable["TextLabelPositionPadY"] else pixelsRemaining -= settingsTable["TextButtonPositionPadY"] 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 child.Visible = true if isLabel 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"] ) while not child.TextFits child.Size = UDim2.new child.Size.X.Scale, child.Size.X.Offset, 0, child.AbsoluteSize.Y + 1 pixelsRemaining -= child.AbsoluteSize.Y if isLabel pixelsRemaining -= settingsTable["TextLabelPositionPadY"] else pixelsRemaining -= settingsTable["TextButtonPositionPadY"] else child.Visible = false pixelsRemaining = -1 else --GuiObject child.Position = UDim2.new child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining pixelsRemaining -= child.AbsoluteSize.Y child.Visible = (pixelsRemaining >= 0) t.LayoutGuiObjects = (frame, guiObjects, settingsTable) -> if not frame\IsA "GuiObject" error "Frame must be a GuiObject" for _, child in ipairs guiObjects if not child\IsA "GuiObject" error "All elements that are layed out must be of type GuiObject" if not settingsTable settingsTable = {} if not settingsTable["TextLabelSizePadY"] settingsTable["TextLabelSizePadY"] = 0 if not settingsTable["TextLabelPositionPadY"] settingsTable["TextLabelPositionPadY"] = 0 if not settingsTable["TextButtonSizePadY"] settingsTable["TextButtonSizePadY"] = 12 if not settingsTable["TextButtonPositionPadY"] settingsTable["TextButtonPositionPadY"] = 2 --Wrapper frame takes care of styled objects wrapperFrame = Instance.new "Frame" wrapperFrame.Name = "WrapperFrame" wrapperFrame.BackgroundTransparency = 1 wrapperFrame.Size = UDim2.new 1, 0, 1, 0 wrapperFrame.Parent = frame for _, child in ipairs guiObjects child.Parent = wrapperFrame recalculate = -> wait! layoutGuiObjectsHelper wrapperFrame, guiObjects, settingsTable frame.Changed\connect (prop) -> if prop == "AbsoluteSize" --Wait a heartbeat for it to sync in recalculate nil frame.AncestryChanged\connect recalculate layoutGuiObjectsHelper wrapperFrame, guiObjects, settingsTable t.CreateSlider = (steps, width, position) -> sliderGui = Instance.new "Frame" sliderGui.Size = UDim2.new 1, 0, 1, 0 sliderGui.BackgroundTransparency = 1 sliderGui.Name = "SliderGui" sliderSteps = Instance.new "IntValue" sliderSteps.Name = "SliderSteps" sliderSteps.Value = steps sliderSteps.Parent = sliderGui 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 (_, parent) -> if parent == nil areaSoak.Parent = nil else areaSoak.Parent = getScreenGuiAncestor sliderGui sliderPosition = Instance.new "IntValue" sliderPosition.Name = "SliderPosition" sliderPosition.Value = 0 sliderPosition.Parent = sliderGui bar = Instance.new "TextButton" bar.Text = "" bar.AutoButtonColor = false bar.Name = "Bar" bar.BackgroundColor3 = Color3.new 0, 0, 0 if type(width) == "number" bar.Size = UDim2.new 0, width, 0, 5 else bar.Size = UDim2.new 0, 200, 0, 5 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"] bar.Position = position 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 areaSoak.MouseLeave\connect -> if areaSoak.Visible cancelSlide areaSoak areaSoak.MouseButton1Up\connect -> if areaSoak.Visible cancelSlide areaSoak slider.MouseButton1Down\connect -> areaSoak.Visible = true if areaSoakMouseMoveCon areaSoakMouseMoveCon\disconnect! areaSoakMouseMoveCon = areaSoak.MouseMoved\connect (x, _) -> setSliderPos x, slider, sliderPosition, bar, steps slider.MouseButton1Up\connect -> cancelSlide areaSoak sliderPosition.Changed\connect (_) -> sliderPosition.Value = math.min steps, math.max(1, sliderPosition.Value) relativePosX = (sliderPosition.Value - 1) / (steps - 1) slider.Position = UDim2.new relativePosX, -slider.AbsoluteSize.X / 2, slider.Position.Y.Scale, slider.Position.Y.Offset bar.MouseButton1Down\connect (x, _) -> setSliderPos x, slider, sliderPosition, bar, steps return sliderGui, sliderPosition, sliderSteps t.CreateTrueScrollingFrame = -> local lowY local highY local dragCon local upCon internalChange = false descendantsChangeConMap = {} scrollingFrame = Instance.new "Frame" scrollingFrame.Name = "ScrollingFrame" scrollingFrame.Active = true scrollingFrame.Size = UDim2.new 1, 0, 1, 0 scrollingFrame.ClipsDescendants = true 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 scrollBottom = Instance.new "BoolValue" scrollBottom.Value = false scrollBottom.Name = "ScrollBottom" scrollBottom.Parent = controlFrame scrollUp = Instance.new "BoolValue" scrollUp.Value = false scrollUp.Name = "scrollUp" scrollUp.Parent = controlFrame 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 triFrame = Instance.new "Frame" triFrame.BorderColor3 = Color3.new 1, 1, 1 triFrame.Name = "tri" .. "#{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 scrollUpButton.MouseEnter\connect -> scrollUpButton.BackgroundTransparency = 0.1 upChildren = scrollUpButton\GetChildren! for i = 1, #upChildren upChildren[i].BackgroundTransparency = 0.1 scrollUpButton.MouseLeave\connect -> scrollUpButton.BackgroundTransparency = 0.5 upChildren = scrollUpButton\GetChildren! for i = 1, #upChildren upChildren[i].BackgroundTransparency = 0.5 scrollDownButton = scrollUpButton\clone! scrollDownButton.Name = "ScrollDownButton" scrollDownButton.Position = UDim2.new 0, 0, 1, -18 downChildren = scrollDownButton\GetChildren! for i = 1, #downChildren downChildren[i].Position = UDim2.new 0, 3 + (i - 1), 0.5, -2 + (i - 1) scrollDownButton.MouseEnter\connect -> scrollDownButton.BackgroundTransparency = 0.1 downChildren = scrollDownButton\GetChildren! for i = 1, #downChildren downChildren[i].BackgroundTransparency = 0.1 scrollDownButton.MouseLeave\connect -> scrollDownButton.BackgroundTransparency = 0.5 downChildren = scrollDownButton\GetChildren! for i = 1, #downChildren downChildren[i].BackgroundTransparency = 0.5 scrollDownButton.Parent = controlFrame 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 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 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 newNub = scrollNub\clone! newNub.Position = UDim2.new 0.5, -5, 0.5, -2 newNub.Parent = scrollbar lastNub = scrollNub\clone! lastNub.Position = UDim2.new 0.5, -5, 0.5, 2 lastNub.Parent = scrollbar scrollbar.MouseEnter\connect -> scrollbar.BackgroundTransparency = 0.1 scrollNub.BackgroundTransparency = 0.1 newNub.BackgroundTransparency = 0.1 lastNub.BackgroundTransparency = 0.1 scrollbar.MouseLeave\connect -> scrollbar.BackgroundTransparency = 0.5 scrollNub.BackgroundTransparency = 0.5 newNub.BackgroundTransparency = 0.5 lastNub.BackgroundTransparency = 0.5 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 positionScrollBar = (_, y, offset) -> oldPos = scrollbar.Position if y < scrollTrack.AbsolutePosition.y scrollbar.Position = UDim2.new scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, 0, 0 return (oldPos ~= scrollbar.Position) relativeSize = scrollbar.AbsoluteSize.Y / scrollTrack.AbsoluteSize.Y if y > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) scrollbar.Position = UDim2.new scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, 1 - relativeSize, 0 return (oldPos ~= scrollbar.Position) newScaleYPos = (y - scrollTrack.AbsolutePosition.y - offset) / scrollTrack.AbsoluteSize.y if newScaleYPos + relativeSize > 1 newScaleYPos = 1 - relativeSize scrollBottom.Value = true scrollUp.Value = false elseif newScaleYPos <= 0 newScaleYPos = 0 scrollUp.Value = true scrollBottom.Value = false else scrollUp.Value = false scrollBottom.Value = false scrollbar.Position = UDim2.new scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, newScaleYPos, 0 return (oldPos ~= scrollbar.Position) drillDownSetHighLow = (instance) -> if not instance or not instance\IsA "GuiObject" return if instance == controlFrame return if instance\IsDescendantOf controlFrame return if not instance.Visible return if (lowY and lowY > instance.AbsolutePosition.Y) or not lowY lowY = instance.AbsolutePosition.Y if (highY and highY < (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y)) or not highY highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y children = instance\GetChildren! for i = 1, #children drillDownSetHighLow children[i] resetHighLow = -> firstChildren = scrollingFrame\GetChildren! for i = 1, #firstChildren drillDownSetHighLow firstChildren[i] recalculate = -> internalChange = true percentFrame = 0 if scrollbar.Position.Y.Scale > 0 if scrollbar.Visible percentFrame = scrollbar.Position.Y.Scale / ((scrollTrack.AbsoluteSize.Y - scrollbar.AbsoluteSize.Y) / scrollTrack.AbsoluteSize.Y) else percentFrame = 0 if percentFrame > 0.99 percentFrame = 1 hiddenYAmount = (scrollingFrame.AbsoluteSize.Y - (highY - lowY)) * percentFrame guiChildren = scrollingFrame\GetChildren! for i = 1, #guiChildren if guiChildren[i] ~= controlFrame 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 ) lowY = nil highY = nil resetHighLow! internalChange = false setSliderSizeAndPosition = -> if not highY or not lowY return totalYSpan = math.abs highY - lowY if totalYSpan == 0 scrollbar.Visible = false scrollDownButton.Visible = false scrollUpButton.Visible = false if dragCon dragCon\disconnect! dragCon = nil if upCon upCon\disconnect! upCon = nil return percentShown = scrollingFrame.AbsoluteSize.Y / totalYSpan if percentShown >= 1 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 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 scrollbar.Position = UDim2.new scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, 0, 0 if (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.Y) > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) relativeSize = scrollbar.AbsoluteSize.Y / scrollTrack.AbsoluteSize.Y scrollbar.Position = UDim2.new scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, 1 - relativeSize, 0 buttonScrollAmountPixels = 7 reentrancyGuardScrollUp = false doScrollUp = -> if reentrancyGuardScrollUp return reentrancyGuardScrollUp = true if positionScrollBar 0, scrollbar.AbsolutePosition.Y - buttonScrollAmountPixels, 0 recalculate! reentrancyGuardScrollUp = false reentrancyGuardScrollDown = false doScrollDown = -> if reentrancyGuardScrollDown return reentrancyGuardScrollDown = true if positionScrollBar 0, scrollbar.AbsolutePosition.Y + buttonScrollAmountPixels, 0 recalculate! reentrancyGuardScrollDown = false scrollUp = (mouseYPos) -> if scrollUpButton.Active scrollStamp = tick! current = scrollStamp local upCon upCon = mouseDrag.MouseButton1Up\connect -> scrollStamp = tick! mouseDrag.Parent = nil upCon\disconnect! mouseDrag.Parent = getScreenGuiAncestor scrollbar doScrollUp! wait 0.2 t = tick! w = 0.1 while scrollStamp == current doScrollUp! if mouseYPos and mouseYPos > scrollbar.AbsolutePosition.y break if not scrollUpButton.Active break if tick! - t > 5 w = 0 elseif tick! - t > 2 w = 0.06 wait w scrollDown = (mouseYPos) -> if scrollDownButton.Active scrollStamp = tick! current = scrollStamp local downCon downCon = mouseDrag.MouseButton1Up\connect -> scrollStamp = tick! mouseDrag.Parent = nil downCon\disconnect! mouseDrag.Parent = getScreenGuiAncestor scrollbar doScrollDown! wait 0.2 t = tick! w = 0.1 while scrollStamp == current doScrollDown! if mouseYPos and mouseYPos < (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.x) break if not scrollDownButton.Active break if tick! - t > 5 w = 0 elseif tick! - t > 2 w = 0.06 wait w scrollbar.MouseButton1Down\connect (_, y) -> if scrollbar.Active scrollStamp = tick! mouseOffset = y - scrollbar.AbsolutePosition.y if dragCon dragCon\disconnect! dragCon = nil if upCon upCon\disconnect! upCon = nil reentrancyGuardMouseScroll = false dragCon = mouseDrag.MouseMoved\connect (x, y) -> if reentrancyGuardMouseScroll return reentrancyGuardMouseScroll = true if positionScrollBar x, y, mouseOffset recalculate! reentrancyGuardMouseScroll = false upCon = mouseDrag.MouseButton1Up\connect -> scrollStamp = tick! mouseDrag.Parent = nil dragCon\disconnect! dragCon = nil upCon\disconnect! global drag = nil mouseDrag.Parent = getScreenGuiAncestor scrollbar scrollMouseCount = 0 scrollUpButton.MouseButton1Down\connect -> scrollUp! scrollDownButton.MouseButton1Down\connect -> scrollDown! scrollTick = -> global scrollStamp = tick! scrollUpButton.MouseButton1Up\connect scrollTick scrollDownButton.MouseButton1Up\connect scrollTick scrollbar.MouseButton1Up\connect scrollTick -- heightCheck = (instance) -> -- if (highY and (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) > highY) or not highY -- highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y -- end -- setSliderSizeAndPosition! -- end highLowRecheck = -> oldLowY = lowY oldHighY = highY lowY = nil highY = nil resetHighLow! if (lowY ~= oldLowY) or (highY ~= oldHighY) setSliderSizeAndPosition! descendantChanged = (this, prop) -> if internalChange return if not this.Visible return if prop == "Size" or prop == "Position" wait! highLowRecheck! scrollingFrame.DescendantAdded\connect (instance) -> if not instance\IsA "GuiObject" return if instance.Visible wait! -- wait a heartbeat for sizes to reconfig highLowRecheck! descendantsChangeConMap[instance] = instance.Changed\connect (prop) -> descendantChanged instance, prop scrollingFrame.DescendantRemoving\connect (instance) -> if not instance\IsA "GuiObject" return if descendantsChangeConMap[instance] descendantsChangeConMap[instance]\disconnect! descendantsChangeConMap[instance] = nil wait! -- wait a heartbeat for sizes to reconfig highLowRecheck! scrollingFrame.Changed\connect (prop) -> if prop == "AbsoluteSize" if not highY or not lowY return highLowRecheck! setSliderSizeAndPosition! return scrollingFrame, controlFrame t.CreateScrollingFrame = (orderList, scrollStyle) -> frame = Instance.new "Frame" frame.Name = "ScrollingFrame" frame.BackgroundTransparency = 1 frame.Size = UDim2.new 1, 0, 1, 0 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 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 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 scrollStamp = 0 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 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 style = "simple" if scrollStyle and "#{scrollStyle}" style = scrollStyle scrollPosition = 1 rowSize = 0 howManyDisplayed = 0 layoutGridScrollBar = -> howManyDisplayed = 0 guiObjects = {} if orderList for _, child in ipairs orderList if child.Parent == frame table.insert guiObjects, child else children = frame\GetChildren! if children for _, child in ipairs children if child\IsA "GuiObject" table.insert guiObjects, child if #guiObjects == 0 scrollUpButton.Active = false scrollDownButton.Active = false scrollDrag.Active = false scrollPosition = 1 return if scrollPosition > #guiObjects scrollPosition = #guiObjects if scrollPosition < 1 scrollPosition = 1 totalPixelsY = frame.AbsoluteSize.Y pixelsRemainingY = frame.AbsoluteSize.Y totalPixelsX = frame.AbsoluteSize.X xCounter = 0 rowSizeCounter = 0 setRowSize = true pixelsBelowScrollbar = 0 pos = #guiObjects currentRowY = 0 pos = scrollPosition --count up from current scroll position to fill out grid while pos <= #guiObjects and pixelsBelowScrollbar < totalPixelsY xCounter += guiObjects[pos].AbsoluteSize.X --previous pos was the end of a row if xCounter >= totalPixelsX pixelsBelowScrollbar += currentRowY currentRowY = 0 xCounter = guiObjects[pos].AbsoluteSize.X if guiObjects[pos].AbsoluteSize.Y > currentRowY currentRowY = guiObjects[pos].AbsoluteSize.Y pos += 1 --Count wherever current row left off 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 xCounter += guiObjects[pos].AbsoluteSize.X rowSizeCounter += 1 if xCounter >= totalPixelsX rowSize = rowSizeCounter - 1 rowSizeCounter = 0 xCounter = guiObjects[pos].AbsoluteSize.X if pixelsBelowScrollbar + currentRowY <= totalPixelsY --It fits, so back up our scroll position pixelsBelowScrollbar += currentRowY if scrollPosition <= rowSize scrollPosition = 1 break else scrollPosition -= rowSize currentRowY = 0 else break if guiObjects[pos].AbsoluteSize.Y > currentRowY currentRowY = guiObjects[pos].AbsoluteSize.Y pos -= 1 --Do check last time if pos = 0 if (pos == 0) and (pixelsBelowScrollbar + currentRowY <= totalPixelsY) scrollPosition = 1 xCounter = 0 --pos = scrollPosition rowSizeCounter = 0 setRowSize = true lastChildSize = 0 xOffset = yOffset = 0 if guiObjects[1] 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 for i, child in ipairs guiObjects if i < scrollPosition --print "Hiding " .. child.Name child.Visible = false else if pixelsRemainingY < 0 --print "Out of Space " .. child.Name child.Visible = false else --print "Laying out " .. child.Name --GuiObject if setRowSize rowSizeCounter += 1 if xCounter + child.AbsoluteSize.X >= totalPixelsX if setRowSize rowSize = rowSizeCounter - 1 setRowSize = false xCounter = 0 pixelsRemainingY -= child.AbsoluteSize.Y child.Position = UDim2.new( child.Position.X.Scale, xCounter + xOffset, 0, totalPixelsY - pixelsRemainingY + yOffset ) xCounter += child.AbsoluteSize.X child.Visible = ((pixelsRemainingY - child.AbsoluteSize.Y) >= 0) if child.Visible howManyDisplayed += 1 lastChildSize = child.AbsoluteSize scrollUpButton.Active = (scrollPosition > 1) if lastChildSize == 0 scrollDownButton.Active = false else scrollDownButton.Active = ((pixelsRemainingY - lastChildSize.Y) < 0) scrollDrag.Active = #guiObjects > howManyDisplayed scrollDrag.Visible = scrollDrag.Active layoutSimpleScrollBar = -> guiObjects = {} howManyDisplayed = 0 if orderList for _, child in ipairs orderList if child.Parent == frame table.insert guiObjects, child else children = frame\GetChildren! if children for _, child in ipairs children if child\IsA "GuiObject" table.insert guiObjects, child if #guiObjects == 0 scrollUpButton.Active = false scrollDownButton.Active = false scrollDrag.Active = false scrollPosition = 1 return if scrollPosition > #guiObjects scrollPosition = #guiObjects totalPixels = frame.AbsoluteSize.Y pixelsRemaining = frame.AbsoluteSize.Y pixelsBelowScrollbar = 0 pos = #guiObjects while pixelsBelowScrollbar < totalPixels and pos >= 1 if pos >= scrollPosition pixelsBelowScrollbar += guiObjects[pos].AbsoluteSize.Y else if pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y <= totalPixels --It fits, so back up our scroll position pixelsBelowScrollbar += guiObjects[pos].AbsoluteSize.Y if scrollPosition <= 1 scrollPosition = 1 break else --local ("Backing up ScrollPosition from -- " ..scrollPosition) scrollPosition -= 1 else break pos -= 1 pos = scrollPosition for i, child in ipairs guiObjects if i < scrollPosition --print "Hiding " .. child.Name child.Visible = false else if pixelsRemaining < 0 --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 -= child.AbsoluteSize.Y if pixelsRemaining >= 0 child.Visible = true howManyDisplayed += 1 else child.Visible = false scrollUpButton.Active = (scrollPosition > 1) scrollDownButton.Active = (pixelsRemaining < 0) scrollDrag.Active = #guiObjects > howManyDisplayed scrollDrag.Visible = scrollDrag.Active moveDragger = -> guiObjects = 0 children = frame\GetChildren! if children for _, child in ipairs children if child\IsA "GuiObject" guiObjects += 1 if not scrollDrag.Parent return dragSizeY = scrollDrag.Parent.AbsoluteSize.y * (1 / (guiObjects - howManyDisplayed + 1)) if dragSizeY < 16 dragSizeY = 16 scrollDrag.Size = UDim2.new scrollDrag.Size.X.Scale, scrollDrag.Size.X.Offset, scrollDrag.Size.Y.Scale, dragSizeY relativeYPos = (scrollPosition - 1) / (guiObjects - howManyDisplayed) if relativeYPos > 1 relativeYPos = 1 elseif relativeYPos < 0 relativeYPos = 0 absYPos = 0 if relativeYPos ~= 0 absYPos = (relativeYPos * scrollbar.AbsoluteSize.y) - (relativeYPos * scrollDrag.AbsoluteSize.y) scrollDrag.Position = UDim2.new scrollDrag.Position.X.Scale, scrollDrag.Position.X.Offset, scrollDrag.Position.Y.Scale, absYPos reentrancyGuard = false recalculate = -> if reentrancyGuard return reentrancyGuard = true wait! local success, err if style == "grid" success, err = try layoutGridScrollBar! elseif style == "simple" success, err = try layoutSimpleScrollBar! if not success print err moveDragger! reentrancyGuard = false doScrollUp = -> scrollPosition -= rowSize if scrollPosition < 1 scrollPosition = 1 recalculate nil doScrollDown = -> scrollPosition += rowSize recalculate nil scrollUp = (mouseYPos) -> if scrollUpButton.Active scrollStamp = tick! current = scrollStamp local upCon upCon = mouseDrag.MouseButton1Up\connect -> scrollStamp = tick! mouseDrag.Parent = nil upCon\disconnect! mouseDrag.Parent = getScreenGuiAncestor scrollbar doScrollUp! wait 0.2 t = tick! w = 0.1 while scrollStamp == current doScrollUp! if mouseYPos and mouseYPos > scrollDrag.AbsolutePosition.y break if not scrollUpButton.Active break if tick! - t > 5 w = 0 elseif tick! - t > 2 w = 0.06 wait w scrollDown = (mouseYPos) -> if scrollDownButton.Active scrollStamp = tick! current = scrollStamp local downCon downCon = mouseDrag.MouseButton1Up\connect -> scrollStamp = tick! mouseDrag.Parent = nil downCon\disconnect! mouseDrag.Parent = getScreenGuiAncestor scrollbar doScrollDown! wait 0.2 t = tick! w = 0.1 while scrollStamp == current doScrollDown! if mouseYPos and mouseYPos < (scrollDrag.AbsolutePosition.y + scrollDrag.AbsoluteSize.x) break if not scrollDownButton.Active break if tick! - t > 5 w = 0 elseif tick! - t > 2 w = 0.06 wait w -- y = 0 scrollDrag.MouseButton1Down\connect (_, y) -> if scrollDrag.Active scrollStamp = tick! mouseOffset = y - scrollDrag.AbsolutePosition.y local dragCon local upCon dragCon = mouseDrag.MouseMoved\connect (_, y) -> barAbsPos = scrollbar.AbsolutePosition.y barAbsSize = scrollbar.AbsoluteSize.y dragAbsSize = scrollDrag.AbsoluteSize.y barAbsOne = barAbsPos + barAbsSize - dragAbsSize y -= mouseOffset y = y < barAbsPos and barAbsPos or y > barAbsOne and barAbsOne or y y -= barAbsPos guiObjects = 0 children = frame\GetChildren! if children for _, child in ipairs children if child\IsA "GuiObject" guiObjects += 1 doublePercent = y / (barAbsSize - dragAbsSize) rowDiff = rowSize totalScrollCount = guiObjects - (howManyDisplayed - 1) newScrollPosition = math.floor((doublePercent * totalScrollCount) + 0.5) + rowDiff if newScrollPosition < scrollPosition rowDiff = -rowDiff if newScrollPosition < 1 newScrollPosition = 1 scrollPosition = newScrollPosition recalculate nil upCon = mouseDrag.MouseButton1Up\connect -> scrollStamp = tick! mouseDrag.Parent = nil dragCon\disconnect! dragCon = nil upCon\disconnect! global drag = nil mouseDrag.Parent = getScreenGuiAncestor scrollbar scrollMouseCount = 0 scrollUpButton.MouseButton1Down\connect -> scrollUp! scrollUpButton.MouseButton1Up\connect -> scrollStamp = tick! scrollDownButton.MouseButton1Up\connect -> scrollStamp = tick! scrollDownButton.MouseButton1Down\connect -> scrollDown! scrollbar.MouseButton1Up\connect -> scrollStamp = tick! scrollbar.MouseButton1Down\connect (_, y) -> if y > (scrollDrag.AbsoluteSize.y + scrollDrag.AbsolutePosition.y) scrollDown y elseif y < scrollDrag.AbsolutePosition.y scrollUp y frame.ChildAdded\connect -> recalculate nil frame.ChildRemoved\connect -> recalculate nil frame.Changed\connect (prop) -> if prop == "AbsoluteSize" --Wait a heartbeat for it to sync in recalculate nil frame.AncestryChanged\connect -> recalculate nil return frame, scrollUpButton, scrollDownButton, recalculate, scrollbar binaryGrow = (min, max, fits) -> if min > max return min biggestLegal = min while min <= max mid = min + math.floor (max - min) / 2 if fits mid and (biggestLegal == nil or biggestLegal < mid) biggestLegal = mid --Try growing min = mid + 1 else --Doesn't fit, shrink max = mid - 1 return biggestLegal binaryShrink = (min, max, fits) -> if min > max return min smallestLegal = max while min <= max mid = min + math.floor (max - min) / 2 if fits mid and (smallestLegal == nil or smallestLegal > mid) smallestLegal = mid --It fits, shrink max = mid - 1 else --Doesn't fit, grow min = mid + 1 return smallestLegal getGuiOwner = (instance) -> while instance ~= nil if instance\IsA"ScreenGui" or instance\IsA "BillboardGui" return instance instance = instance.Parent return nil t.AutoTruncateTextObject = (textLabel) -> text = textLabel.Text 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 local mouseEnterConnection local mouseLeaveConnection checkForResize = -> if getGuiOwner textLabel == nil return textLabel.Text = text if textLabel.TextFits --Tear down the rollover if it is active if mouseEnterConnection mouseEnterConnection\disconnect! mouseEnterConnection = nil if mouseLeaveConnection mouseLeaveConnection\disconnect! mouseLeaveConnection = nil else len = string.len text textLabel.Text = text .. "~" --Shrink the text textSize = binaryGrow 0, len, (pos) -> if pos == 0 textLabel.Text = "~" else textLabel.Text = string.sub(text, 1, pos) .. "~" return textLabel.TextFits shortText = string.sub(text, 1, textSize) .. "~" textLabel.Text = shortText --Make sure the fullLabel fits if not fullLabel.TextFits --Already too small, grow it really bit to start fullLabel.Size = UDim2.new 0, 10000, 1, 0 --Okay, now try to binary shrink it back down fullLabelSize = binaryShrink textLabel.AbsoluteSize.X, fullLabel.AbsoluteSize.X, (size) -> fullLabel.Size = UDim2.new 0, size, 1, 0 return fullLabel.TextFits fullLabel.Size = UDim2.new 0, fullLabelSize + 6, 1, 0 --Now setup the rollover effects, if they are currently off if mouseEnterConnection == nil mouseEnterConnection = textLabel.MouseEnter\connect -> fullLabel.ZIndex = textLabel.ZIndex + 1 fullLabel.Visible = true --textLabel.Text = "" if mouseLeaveConnection == nil mouseLeaveConnection = textLabel.MouseLeave\connect -> fullLabel.Visible = false --textLabel.Text = shortText textLabel.AncestryChanged\connect checkForResize textLabel.Changed\connect (prop) -> if prop == "AbsoluteSize" checkForResize! checkForResize! changeText = (newText) -> text = newText fullLabel.Text = text checkForResize! return textLabel, changeText TransitionTutorialPages = (fromPage, toPage, transitionFrame, currentPageValue) -> if fromPage fromPage.Visible = false if transitionFrame.Visible == false transitionFrame.Size = fromPage.Size transitionFrame.Position = fromPage.Position else if transitionFrame.Visible == false transitionFrame.Size = UDim2.new 0, 50, 0, 50 transitionFrame.Position = UDim2.new 0.5, -25, 0.5, -25 transitionFrame.Visible = true currentPageValue.Value = nil local newSize, newPosition if toPage --Make it visible so it resizes toPage.Visible = true newSize = toPage.Size newPosition = toPage.Position toPage.Visible = false else newSize = UDim2.new 0, 50, 0, 50 newPosition = UDim2.new 0.5, -25, 0.5, -25 transitionFrame\TweenSizeAndPosition( newSize, newPosition, Enum.EasingDirection.InOut, Enum.EasingStyle.Quad, 0.3, true, (state) -> if state == Enum.TweenStatus.Completed transitionFrame.Visible = false if toPage toPage.Visible = true currentPageValue.Value = toPage ) t.CreateTutorial = (name, tutorialKey, createButtons) -> 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 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 currentPageValue = Instance.new "ObjectValue" currentPageValue.Name = "CurrentTutorialPage" currentPageValue.Value = nil currentPageValue.Parent = frame boolValue = Instance.new "BoolValue" boolValue.Name = "Buttons" boolValue.Value = createButtons boolValue.Parent = frame pages = Instance.new "Frame" pages.Name = "Pages" pages.BackgroundTransparency = 1 pages.Size = UDim2.new 1, 0, 1, 0 pages.Parent = frame getVisiblePageAndHideOthers = -> local visiblePage children = pages\GetChildren! if children for _, child in ipairs children if child.Visible if visiblePage child.Visible = false else visiblePage = child return visiblePage showTutorial = (alwaysShow) -> if alwaysShow or UserSettings!.GameSettings\GetTutorialState tutorialKey == false print "Showing tutorial-", tutorialKey currentTutorialPage = getVisiblePageAndHideOthers! firstPage = pages\FindFirstChild "TutorialPage1" if firstPage TransitionTutorialPages currentTutorialPage, firstPage, transitionFrame, currentPageValue else error "Could not find TutorialPage1" dismissTutorial = -> currentTutorialPage = getVisiblePageAndHideOthers! if currentTutorialPage TransitionTutorialPages currentTutorialPage, nil, transitionFrame, currentPageValue UserSettings!.GameSettings\SetTutorialState tutorialKey, true gotoPage = (pageNum) -> page = pages\FindFirstChild "TutorialPage" .. pageNum currentTutorialPage = getVisiblePageAndHideOthers! TransitionTutorialPages currentTutorialPage, page, transitionFrame, currentPageValue return frame, showTutorial, dismissTutorial, gotoPage CreateBasicTutorialPage = (name, handleResize, skipTutorial, giveDoneButton) -> 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 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 skipButton = Instance.new "ImageButton" skipButton.Name = "SkipButton" skipButton.AutoButtonColor = false skipButton.BackgroundTransparency = 1 skipButton.Image = "rbxasset://textures/ui/closeButton.png" skipButton.MouseButton1Click\connect -> skipTutorial! skipButton.MouseEnter\connect -> skipButton.Image = "rbxasset://textures/ui/closeButton_dn.png" skipButton.MouseLeave\connect -> skipButton.Image = "rbxasset://textures/ui/closeButton.png" skipButton.Size = UDim2.new 0, 25, 0, 25 skipButton.Position = UDim2.new 1, -25, 0, 0 skipButton.Parent = frame if giveDoneButton 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 doneButton.MouseButton1Click\connect -> skipTutorial! doneButton.Parent = frame innerFrame = Instance.new "Frame" innerFrame.Name = "ContentFrame" innerFrame.BackgroundTransparency = 1 innerFrame.Position = UDim2.new 0, 0, 0, 25 innerFrame.Parent = frame 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 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 innerFrame.Size = UDim2.new 1, 0, 1, -75 else innerFrame.Size = UDim2.new 1, 0, 1, -22 local parentConnection basicHandleResize = -> if frame.Visible and frame.Parent maxSize = math.min frame.Parent.AbsoluteSize.X, frame.Parent.AbsoluteSize.Y handleResize 200, maxSize frame.Changed\connect (prop) -> if prop == "Parent" if parentConnection ~= nil parentConnection\disconnect! parentConnection = nil if frame.Parent and frame.Parent\IsA "GuiObject" parentConnection = frame.Parent.Changed\connect (parentProp) -> if parentProp == "AbsoluteSize" wait! basicHandleResize! basicHandleResize! if prop == "Visible" basicHandleResize! return frame, innerFrame t.CreateTextTutorialPage = (name, text, skipTutorialFunc) -> local frame local contentFrame 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 handleResize = (minSize, maxSize) -> size = binaryShrink minSize, maxSize, (size) -> frame.Size = UDim2.new 0, size, 0, size textLabel.TextFits frame.Size = UDim2.new 0, size, 0, size frame.Position = UDim2.new 0.5, -size / 2, 0.5, -size / 2 frame, contentFrame = CreateBasicTutorialPage name, handleResize, skipTutorialFunc textLabel.Parent = contentFrame frame t.CreateImageTutorialPage = (name, imageAsset, x, y, skipTutorialFunc, giveDoneButton) -> local frame local contentFrame 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 handleResize = (minSize, maxSize) -> size = binaryShrink minSize, maxSize, (size) -> size >= x and size >= y if size >= x and size >= y imageLabel.Size = UDim2.new 0, x, 0, y imageLabel.Position = UDim2.new 0.5, -x / 2, 0.5, -y / 2 else if x > y --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 size += 50 frame.Size = UDim2.new 0, size, 0, size frame.Position = UDim2.new 0.5, -size / 2, 0.5, -size / 2 frame, contentFrame = CreateBasicTutorialPage name, handleResize, skipTutorialFunc, giveDoneButton imageLabel.Parent = contentFrame frame t.AddTutorialPage = (tutorial, tutorialPage) -> transitionFrame = tutorial.TransitionFrame currentPageValue = tutorial.CurrentTutorialPage if not tutorial.Buttons.Value tutorialPage.NextButton.Parent = nil tutorialPage.PrevButton.Parent = nil children = tutorial.Pages\GetChildren! if children and #children > 0 tutorialPage.Name = "TutorialPage" .. (#children + 1) previousPage = children[#children] if not previousPage\IsA "GuiObject" error "All elements under Pages must be GuiObjects" if tutorial.Buttons.Value if previousPage.NextButton.Active error "NextButton already Active on previousPage, please only add pages with RbxGui.AddTutorialPage function" previousPage.NextButton.MouseButton1Click\connect -> TransitionTutorialPages previousPage, tutorialPage, transitionFrame, currentPageValue previousPage.NextButton.Active = true previousPage.NextButton.Visible = true if tutorialPage.PrevButton.Active error "PrevButton already Active on tutorialPage, please only add pages with RbxGui.AddTutorialPage function" tutorialPage.PrevButton.MouseButton1Click\connect -> TransitionTutorialPages tutorialPage, previousPage, transitionFrame, currentPageValue tutorialPage.PrevButton.Active = true tutorialPage.PrevButton.Visible = true tutorialPage.Parent = tutorial.Pages else --First child tutorialPage.Name = "TutorialPage1" tutorialPage.Parent = tutorial.Pages t.CreateSetPanel = (userIdsForSets, objectSelected, dialogClosed, size, position, showAdminCategories, useAssetVersionId) -> if not userIdsForSets error "CreateSetPanel: userIdsForSets (first arg) is nil, should be a table of number ids" if type(userIdsForSets) ~= "table" and type(userIdsForSets) ~= "userdata" error "CreateSetPanel: userIdsForSets (first arg) is of type #{type userIdsForSets}, should be of type table or userdata" if not objectSelected error "CreateSetPanel: objectSelected (second arg) is nil, should be a callback function!" if type(objectSelected) ~= "function" error "CreateSetPanel: objectSelected (second arg) is of type #{type objectSelected}, should be of type function!" if dialogClosed and type(dialogClosed) ~= "function" error "CreateSetPanel: dialogClosed (third arg) is of type #{type dialogClosed}, should be of type function!" if showAdminCategories == nil -- by default, don't show beta sets showAdminCategories = false arrayPosition = 1 insertButtons = {} insertButtonCons = {} local contents local setGui -- used for water selections waterForceDirection = "NegX" waterForce = "None" local waterGui, waterTypeChangedEvent Data = {} Data.CurrentCategory = nil Data.Category = {} SetCache = {} local userCategoryButtons buttonWidth = 64 buttonHeight = buttonWidth local SmallThumbnailUrl local LargeThumbnailUrl BaseUrl = game\GetService"ContentProvider".BaseUrl\lower! if useAssetVersionId 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=" drillDownSetZIndex = (parent, index) -> children = parent\GetChildren! for i = 1, #children if children[i]\IsA "GuiObject" children[i].ZIndex = index drillDownSetZIndex children[i], index -- for terrain stamping local currTerrainDropDownFrame terrainShapes = { "Block", "Vertical Ramp", "Corner Wedge", "Inverse Corner Wedge", "Horizontal Ramp", "Auto-Wedge" } terrainShapeMap = {} for i = 1, #terrainShapes terrainShapeMap[terrainShapes[i]] = i - 1 terrainShapeMap[terrainShapes[#terrainShapes]] = 6 createWaterGui = -> waterForceDirections = { "NegX", "X", "NegY", "Y", "NegZ", "Z" } waterForces = { "None", "Small", "Medium", "Strong", "Max" } waterFrame = Instance.new "Frame" waterFrame.Name = "WaterFrame" waterFrame.Style = Enum.FrameStyle.RobloxSquare waterFrame.Size = UDim2.new 0, 150, 0, 110 waterFrame.Visible = false 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 waterForceDirLabel = waterForceLabel\Clone! waterForceDirLabel.Name = "WaterForceDirectionLabel" waterForceDirLabel.Text = "Water Force Direction" waterForceDirLabel.Position = UDim2.new 0, 0, 0, 50 waterForceDirLabel.Parent = waterFrame waterTypeChangedEvent = Instance.new "BindableEvent" waterTypeChangedEvent.Name = "WaterTypeChangedEvent" waterTypeChangedEvent.Parent = waterFrame waterForceDirectionSelectedFunc = (newForceDirection) -> waterForceDirection = newForceDirection waterTypeChangedEvent\Fire { waterForce, waterForceDirection } waterForceSelectedFunc = (newForce) -> waterForce = newForce waterTypeChangedEvent\Fire { waterForce, waterForceDirection } 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 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 -- Helper Function that contructs gui elements createSetGui = -> setGui = Instance.new "ScreenGui" setGui.Name = "SetGui" setPanel = Instance.new "Frame" setPanel.Name = "SetPanel" setPanel.Active = true setPanel.BackgroundTransparency = 1 if position setPanel.Position = position else setPanel.Position = UDim2.new 0.2, 29, 0.1, 24 if size setPanel.Size = size else setPanel.Size = UDim2.new 0.6, -58, 0.64, 0 setPanel.Style = Enum.FrameStyle.RobloxRound setPanel.ZIndex = 6 setPanel.Parent = setGui -- Children of SetPanel 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 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 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 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 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 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 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 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 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 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 createSetButton = (text) -> setButton = Instance.new "TextButton" if text setButton.Text = text else setButton.Text = "" 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 setButton buildSetButton = (name, setId, _, _, _) -> button = createSetButton name button.Text = name button.Name = "SetButton" button.Visible = true setValue = Instance.new "IntValue" setValue.Name = "SetId" setValue.Value = setId setValue.Parent = button setName = Instance.new "StringValue" setName.Name = "SetName" setName.Value = name setName.Parent = button button processCategory = (sets) -> setButtons = {} numSkipped = 0 for i = 1, #sets if not showAdminCategories and sets[i].Name == "Beta" numSkipped += 1 else setButtons[i - numSkipped] = buildSetButton sets[i].Name, sets[i].CategoryId, sets[i].ImageAssetId, i - numSkipped, #sets setButtons handleResize = -> wait! -- neccessary to insure heartbeat happened 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 makeInsertAssetButton = -> 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 assetId = Instance.new "IntValue" assetId.Name = "AssetId" assetId.Value = 0 assetId.Parent = insertAssetButtonExample assetName = Instance.new "StringValue" assetName.Name = "AssetName" assetName.Value = "" assetName.Parent = insertAssetButtonExample 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 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 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 showLargePreview = (insertButton) -> if insertButton\FindFirstChild "AssetId" delay 0, -> game\GetService"ContentProvider"\Preload( LargeThumbnailUrl .. "#{insertButton.AssetId.Value}" ) setGui.SetPanel.ItemPreview.LargePreview.Image = LargeThumbnailUrl .. "#{insertButton.AssetId.Value}" if insertButton\FindFirstChild "AssetName" setGui.SetPanel.ItemPreview.TextPanel.RolloverText.Text = insertButton.AssetName.Value selectTerrainShape = (shape) -> if currTerrainDropDownFrame objectSelected( "#{currTerrainDropDownFrame.AssetName.Value}", tonumber(currTerrainDropDownFrame.AssetId.Value), shape ) createTerrainTypeButton = (name, parent) -> 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 -> dropDownTextButton.BackgroundTransparency = 0 dropDownTextButton.TextColor3 = Color3.new 0, 0, 0 dropDownTextButton.MouseLeave\connect -> dropDownTextButton.BackgroundTransparency = 1 dropDownTextButton.TextColor3 = Color3.new 1, 1, 1 dropDownTextButton.MouseButton1Click\connect -> dropDownTextButton.BackgroundTransparency = 1 dropDownTextButton.TextColor3 = Color3.new 1, 1, 1 if dropDownTextButton.Parent and dropDownTextButton.Parent\IsA "GuiObject" dropDownTextButton.Parent.Visible = false selectTerrainShape terrainShapeMap[dropDownTextButton.Text] dropDownTextButton createTerrainDropDownMenu = (zIndex) -> 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 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 dropDown.MouseLeave\connect -> dropDown.Visible = false createDropDownMenuButton = (parent) -> 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" createTerrainDropDownMenu 8 dropDownButton.MouseButton1Click\connect -> setGui.TerrainDropDown.Visible = true setGui.TerrainDropDown.Position = UDim2.new 0, parent.AbsolutePosition.X, 0, parent.AbsolutePosition.Y currTerrainDropDownFrame = parent buildInsertButton = -> insertButton = makeInsertAssetButton! insertButton.Name = "InsertAssetButton" insertButton.Visible = true if Data.Category[Data.CurrentCategory].SetName == "High Scalability" createDropDownMenuButton insertButton local lastEnter mouseEnterCon = insertButton.MouseEnter\connect -> lastEnter = insertButton delay 0.1, -> if lastEnter == insertButton showLargePreview insertButton return insertButton, mouseEnterCon realignButtonGrid = (columns) -> x = 0 y = 0 for i = 1, #insertButtons insertButtons[i].Position = UDim2.new 0, buttonWidth * x, 0, buttonHeight * y x += 1 if x >= columns x = 0 y += 1 setInsertButtonImageBehavior = (insertFrame, visible, name, assetId) -> if visible insertFrame.AssetName.Value = name insertFrame.AssetId.Value = assetId newImageUrl = SmallThumbnailUrl .. assetId if newImageUrl ~= insertFrame.Button.ButtonImage.Image delay 0, -> game\GetService"ContentProvider"\Preload SmallThumbnailUrl .. assetId insertFrame.Button.ButtonImage.Image = SmallThumbnailUrl .. assetId table.insert( insertButtonCons, insertFrame.Button.MouseButton1Click\connect -> -- special case for water, show water selection gui isWaterSelected = (name == "Water") and (Data.Category[Data.CurrentCategory].SetName == "High Scalability") waterGui.Visible = isWaterSelected if isWaterSelected objectSelected name, tonumber assetId, nil else objectSelected name, tonumber assetId ) insertFrame.Visible = true else insertFrame.Visible = false loadSectionOfItems = (setGui, rows, columns) -> pageSize = rows * columns if arrayPosition > #contents return origArrayPos = arrayPosition for _ = 1, pageSize + 1 if arrayPosition >= #contents + 1 break local buttonCon insertButtons[arrayPosition], buttonCon = buildInsertButton! table.insert insertButtonCons, buttonCon insertButtons[arrayPosition].Parent = setGui.SetPanel.ItemsFrame arrayPosition += 1 realignButtonGrid columns -- indexCopy = origArrayPos for index = origArrayPos, arrayPosition if insertButtons[index] if contents[index] -- we don't want water to have a drop down button if contents[index].Name == "Water" if Data.Category[Data.CurrentCategory].SetName == "High Scalability" insertButtons[index]\FindFirstChild("DropDownButton", true)\Destroy! local assetId if useAssetVersionId assetId = contents[index].AssetVersionId else assetId = contents[index].AssetId setInsertButtonImageBehavior insertButtons[index], true, contents[index].Name, assetId else break else break -- indexCopy = index 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 -- remove our buttons and their connections for i = 1, #insertButtons insertButtons[i]\remove! for i = 1, #insertButtonCons if insertButtonCons[i] insertButtonCons[i]\disconnect! insertButtonCons = {} insertButtons = {} arrayPosition = 1 loadSectionOfItems setGui, rows, columns selectSet = (button, setName, setId, _) -> if button and Data.Category[Data.CurrentCategory] ~= nil if button ~= Data.Category[Data.CurrentCategory].Button Data.Category[Data.CurrentCategory].Button = button if SetCache[setId] == nil SetCache[setId] = game\GetService"InsertService"\GetCollection setId Data.Category[Data.CurrentCategory].Contents = SetCache[setId] Data.Category[Data.CurrentCategory].SetName = setName Data.Category[Data.CurrentCategory].SetId = setId setSetIndex! selectCategoryPage = (buttons, _) -> if buttons ~= Data.CurrentCategory if Data.CurrentCategory for _, button in pairs Data.CurrentCategory button.Visible = false Data.CurrentCategory = buttons if Data.Category[Data.CurrentCategory] == nil Data.Category[Data.CurrentCategory] = {} if #buttons > 0 selectSet buttons[1], buttons[1].SetName.Value, buttons[1].SetId.Value, 0 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 ) selectCategory = (category) -> selectCategoryPage category, 0 resetAllSetButtonSelection = -> setButtons = setGui.SetPanel.Sets.SetsLists\GetChildren! for i = 1, #setButtons if setButtons[i]\IsA "TextButton" setButtons[i].Selected = false setButtons[i].BackgroundTransparency = 1 setButtons[i].TextColor3 = Color3.new 1, 1, 1 setButtons[i].BackgroundColor3 = Color3.new 1, 1, 1 populateSetsFrame = -> currRow = 0 for i = 1, #userCategoryButtons 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 -- 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 button.MouseEnter\connect -> if not button.Selected button.BackgroundTransparency = 0 button.TextColor3 = Color3.new 0, 0, 0 button.MouseLeave\connect -> if not button.Selected button.BackgroundTransparency = 1 button.TextColor3 = Color3.new 1, 1, 1 button.MouseButton1Click\connect -> 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 currRow += 1 buttons = setGui.SetPanel.Sets.SetsLists\GetChildren! -- set first category as loaded for default if buttons for i = 1, #buttons if buttons[i]\IsA "TextButton" selectSet buttons[i], buttons[i].Text, userCategoryButtons[i].SetId.Value, 0 selectCategory userCategoryButtons break setGui = createSetGui! waterGui, waterTypeChangedEvent = createWaterGui! waterGui.Position = UDim2.new 0, 55, 0, 0 waterGui.Parent = setGui setGui.Changed\connect (prop) -> -- this resizes the preview image to always be the right size if prop == "AbsoluteSize" handleResize! setSetIndex! 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 debounce = false controlFrame.ScrollBottom.Changed\connect (_) -> if controlFrame.ScrollBottom.Value == true if debounce return debounce = true loadSectionOfItems setGui, rows, columns debounce = false userData = {} for id = 1, #userIdsForSets newUserData = game\GetService"InsertService"\GetUserSets userIdsForSets[id] if newUserData and #newUserData > 2 -- start at #3 to skip over My Decals and My Models for each account for category = 3, #newUserData if newUserData[category].Name == "High Scalability" -- we want high scalability parts to show first table.insert userData, 1, newUserData[category] else table.insert userData, newUserData[category] if userData userCategoryButtons = processCategory userData global rows = math.floor setGui.SetPanel.ItemsFrame.AbsoluteSize.Y / buttonHeight global columns = math.floor setGui.SetPanel.ItemsFrame.AbsoluteSize.X / buttonWidth populateSetsFrame! --[[insertPanelCloseCon = ]] setGui.SetPanel.CancelButton.MouseButton1Click\connect -> setGui.SetPanel.Visible = false if dialogClosed dialogClosed! setVisibilityFunction = (visible) -> if visible setGui.SetPanel.Visible = true else setGui.SetPanel.Visible = false getVisibilityFunction = -> if setGui if setGui\FindFirstChild "SetPanel" return setGui.SetPanel.Visible return false return setGui, setVisibilityFunction, getVisibilityFunction, waterTypeChangedEvent t.CreateTerrainMaterialSelector = (size, position) -> terrainMaterialSelectionChanged = Instance.new "BindableEvent" terrainMaterialSelectionChanged.Name = "TerrainMaterialSelectionChanged" local selectedButton frame = Instance.new "Frame" frame.Name = "TerrainMaterialSelector" if size frame.Size = size else frame.Size = UDim2.new 0, 245, 0, 230 if position frame.Position = position frame.BorderSizePixel = 0 frame.BackgroundColor3 = Color3.new 0, 0, 0 frame.Active = true terrainMaterialSelectionChanged.Parent = frame waterEnabled = true -- todo: turn this on when water is ready materialToImageMap = {} materialNames = { "Grass", "Sand", "Brick", "Granite", "Asphalt", "Iron", "Aluminum", "Gold", "Plank", "Log", "Gravel", "Cinder Block", "Stone Wall", "Concrete", "Plastic (red)", "Plastic (blue)", } if waterEnabled table.insert materialNames, "Water" currentMaterial = 1 getEnumFromName = (choice) -> if choice == "Grass" return 1 if choice == "Sand" return 2 if choice == "Erase" return 0 if choice == "Brick" return 3 if choice == "Granite" return 4 if choice == "Asphalt" return 5 if choice == "Iron" return 6 if choice == "Aluminum" return 7 if choice == "Gold" return 8 if choice == "Plank" return 9 if choice == "Log" return 10 if choice == "Gravel" return 11 if choice == "Cinder Block" return 12 if choice == "Stone Wall" return 13 if choice == "Concrete" return 14 if choice == "Plastic (red)" return 15 if choice == "Plastic (blue)" return 16 if choice == "Water" return 17 getNameFromEnum = (choice) -> if choice == Enum.CellMaterial.Grass or choice == 1 return "Grass" elseif choice == Enum.CellMaterial.Sand or choice == 2 return "Sand" elseif choice == Enum.CellMaterial.Empty or choice == 0 return "Erase" elseif choice == Enum.CellMaterial.Brick or choice == 3 return "Brick" elseif choice == Enum.CellMaterial.Granite or choice == 4 return "Granite" elseif choice == Enum.CellMaterial.Asphalt or choice == 5 return "Asphalt" elseif choice == Enum.CellMaterial.Iron or choice == 6 return "Iron" elseif choice == Enum.CellMaterial.Aluminum or choice == 7 return "Aluminum" elseif choice == Enum.CellMaterial.Gold or choice == 8 return "Gold" elseif choice == Enum.CellMaterial.WoodPlank or choice == 9 return "Plank" elseif choice == Enum.CellMaterial.WoodLog or choice == 10 return "Log" elseif choice == Enum.CellMaterial.Gravel or choice == 11 return "Gravel" elseif choice == Enum.CellMaterial.CinderBlock or choice == 12 return "Cinder Block" elseif choice == Enum.CellMaterial.MossyStone or choice == 13 return "Stone Wall" elseif choice == Enum.CellMaterial.Cement or choice == 14 return "Concrete" elseif choice == Enum.CellMaterial.RedPlastic or choice == 15 return "Plastic (red)" elseif choice == Enum.CellMaterial.BluePlastic or choice == 16 return "Plastic (blue)" if waterEnabled if choice == Enum.CellMaterial.Water or choice == 17 return "Water" updateMaterialChoice = (choice) -> currentMaterial = getEnumFromName choice terrainMaterialSelectionChanged\Fire currentMaterial -- we so need a better way to do this for _, v in pairs materialNames materialToImageMap[v] = {} if v == "Grass" materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=56563112" elseif v == "Sand" materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=62356652" elseif v == "Brick" materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=65961537" elseif v == "Granite" materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532153" elseif v == "Asphalt" materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532038" elseif v == "Iron" materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532093" elseif v == "Aluminum" materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531995" elseif v == "Gold" materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532118" elseif v == "Plastic (red)" materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531848" elseif v == "Plastic (blue)" materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531924" elseif v == "Plank" materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532015" elseif v == "Log" materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532051" elseif v == "Gravel" materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532206" elseif v == "Cinder Block" materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532103" elseif v == "Stone Wall" materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531804" elseif v == "Concrete" materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532059" elseif v == "Water" 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!! 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 goToNewMaterial = (buttonWrap, materialName) -> updateMaterialChoice materialName buttonWrap.BackgroundTransparency = 0 selectedButton.BackgroundTransparency = 1 selectedButton = buttonWrap createMaterialButton = (name) -> 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 = "#{name}" 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 = "#{name}" imageButton.Parent = buttonWrap imageButton.Image = materialToImageMap[name].Regular enumType = Instance.new "NumberValue" enumType.Name = "EnumType" enumType.Parent = buttonWrap enumType.Value = 0 imageButton.MouseEnter\connect -> buttonWrap.BackgroundTransparency = 0 imageButton.MouseLeave\connect -> if selectedButton ~= buttonWrap buttonWrap.BackgroundTransparency = 1 imageButton.MouseButton1Click\connect -> if selectedButton ~= buttonWrap goToNewMaterial buttonWrap, "#{name}" return buttonWrap for i = 1, #materialNames imageButton = createMaterialButton materialNames[i] if materialNames[i] == "Grass" -- always start with grass as the default selectedButton = imageButton imageButton.BackgroundTransparency = 0 imageButton.Parent = scrollFrame forceTerrainMaterialSelection = (newMaterialType) -> if not newMaterialType return if currentMaterial == newMaterialType return matName = getNameFromEnum newMaterialType buttons = scrollFrame\GetChildren! for i = 1, #buttons if buttons[i].Name == "Plastic (blue)" and matName == "Plastic (blue)" goToNewMaterial buttons[i], matName return if buttons[i].Name == "Plastic (red)" and matName == "Plastic (red)" goToNewMaterial buttons[i], matName return if string.find buttons[i].Name, matName goToNewMaterial buttons[i], matName return frame.Changed\connect (prop) -> if prop == "AbsoluteSize" recalculateScroll! recalculateScroll! frame, terrainMaterialSelectionChanged, forceTerrainMaterialSelection t.CreateLoadingFrame = (name, size, position) -> game\GetService"ContentProvider"\Preload "http://www.roblox.com/asset/?id=35238053" loadingFrame = Instance.new "Frame" loadingFrame.Name = "LoadingFrame" loadingFrame.Style = Enum.FrameStyle.RobloxRound if size loadingFrame.Size = size else loadingFrame.Size = UDim2.new 0, 300, 0, 160 if position loadingFrame.Position = position else loadingFrame.Position = UDim2.new 0.5, -150, 0.5, -80 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 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 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 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 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 cancelButtonClicked = Instance.new "BindableEvent" cancelButtonClicked.Name = "CancelButtonClicked" cancelButtonClicked.Parent = cancelButton cancelButton.MouseButton1Click\connect -> cancelButtonClicked\Fire! updateLoadingGuiPercent = (percent, tweenAction, tweenLength) -> if percent and type percent ~= "number" error "updateLoadingGuiPercent expects number as argument, got #{type percent} instead" local newSize if percent < 0 newSize = UDim2.new 0, 0, 1, 0 elseif percent > 1 newSize = UDim2.new 1, 0, 1, 0 else newSize = UDim2.new percent, 0, 1, 0 if tweenAction if not tweenLength error "updateLoadingGuiPercent is set to tween new percentage, but got no tween time length! Please pass this in as third argument" if newSize.X.Scale > 0 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, -> if newSize.X.Scale < 0 loadingGreenBar.Visible = false ) else loadingGreenBar.Size = newSize loadingGreenBar.Visible = (newSize.X.Scale > 0) loadingGreenBar.Changed\connect (prop) -> if prop == "Size" loadingPercent.Text = "#{math.ceil loadingGreenBar.Size.X.Scale * 100}%" loadingFrame, updateLoadingGuiPercent, cancelButtonClicked t.CreatePluginFrame = (name, size, position, scrollable, parent) -> createMenuButton = (size, position, text, fontsize, name, parent) -> button = Instance.new "TextButton" 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 -> if button.Selected return button.BackgroundTransparency = 0 button.MouseLeave\connect -> if button.Selected return button.BackgroundTransparency = 1 button.Parent = parent button dragBar = Instance.new "Frame" dragBar.Name = "#{name}" .. "DragBar" dragBar.BackgroundColor3 = Color3.new 39 / 255, 39 / 255, 39 / 255 dragBar.BorderColor3 = Color3.new 0, 0, 0 if size 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 if position dragBar.Position = position dragBar.Active = true dragBar.Draggable = true --dragBar.Visible = false dragBar.MouseEnter\connect -> dragBar.BackgroundColor3 = Color3.new 49 / 255, 49 / 255, 49 / 255 dragBar.MouseLeave\connect -> dragBar.BackgroundColor3 = Color3.new 39 / 255, 39 / 255, 39 / 255 dragBar.Parent = parent -- plugin name label pluginNameLabel = Instance.new "TextLabel" pluginNameLabel.Name = "BarNameLabel" pluginNameLabel.Text = " " .. "#{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 pluginNameLabel.Parent = dragBar -- close button closeButton = createMenuButton( UDim2.new(0, 15, 0, 17), UDim2.new(1, -16, 0.5, -8), "X", Enum.FontSize.Size14, "CloseButton", dragBar ) closeEvent = Instance.new "BindableEvent" closeEvent.Name = "CloseEvent" closeEvent.Parent = closeButton closeButton.MouseButton1Click\connect -> closeEvent\Fire! closeButton.BackgroundTransparency = 1 -- help button helpButton = createMenuButton( UDim2.new(0, 15, 0, 17), UDim2.new(1, -51, 0.5, -8), "?", Enum.FontSize.Size14, "HelpButton", dragBar ) helpFrame = Instance.new "Frame" 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 helpFrame.Parent = dragBar helpButton.MouseButton1Click\connect -> helpFrame.Visible = not helpFrame.Visible if helpFrame.Visible helpButton.Selected = true helpButton.BackgroundTransparency = 0 screenGui = getScreenGuiAncestor helpFrame if screenGui if helpFrame.AbsolutePosition.X + helpFrame.AbsoluteSize.X > screenGui.AbsoluteSize.X --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 else helpFrame.Position = UDim2.new 1, 5, 0, 0 else helpButton.Selected = false helpButton.BackgroundTransparency = 1 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 minimizeFrame = Instance.new "Frame" 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 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 minimizeFrame.Visible = false minimizeFrame.Parent = dragBar minimizeBigButton = Instance.new "TextButton" 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" minimizeBigButton.Parent = minimizeFrame separatingLine = Instance.new "Frame" 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 separatingLine.Parent = dragBar otherSeparatingLine = separatingLine\clone! otherSeparatingLine.Position = UDim2.new 1, -35, 0.5, -7 otherSeparatingLine.Parent = dragBar widgetContainer = Instance.new "Frame" widgetContainer.Name = "WidgetContainer" widgetContainer.BackgroundTransparency = 1 widgetContainer.Position = UDim2.new 0, 0, 1, 0 widgetContainer.BorderColor3 = Color3.new 0, 0, 0 if not scrollable widgetContainer.BackgroundTransparency = 0 widgetContainer.BackgroundColor3 = Color3.new 72 / 255, 72 / 255, 72 / 255 widgetContainer.Parent = dragBar if size if scrollable widgetContainer.Size = size else widgetContainer.Size = UDim2.new 0, dragBar.AbsoluteSize.X, size.Y.Scale, size.Y.Offset else if scrollable widgetContainer.Size = UDim2.new 0, 163, 0, 400 else widgetContainer.Size = UDim2.new 0, dragBar.AbsoluteSize.X, 0, 400 if position widgetContainer.Position += UDim2.new 0, 0, 0, 20 local frame, control, verticalDragger if scrollable --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 control.Size = UDim2.new 0, 21, size.Y.Scale, size.Y.Offset else control.Size = UDim2.new 0, 21, 0, 400 control\FindFirstChild("ScrollDownButton").Position = UDim2.new 0, 0, 1, -20 fakeLine = Instance.new "Frame" 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 fakeLine.Parent = control verticalDragger = Instance.new "TextButton" 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 = "" verticalDragger.Parent = widgetContainer scrubFrame = Instance.new "Frame" 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 scrubFrame.Parent = verticalDragger scrubTwo = scrubFrame\clone! scrubTwo.Position = UDim2.new 0.5, -5, 0.5, -2 scrubTwo.Parent = verticalDragger scrubThree = scrubFrame\clone! scrubThree.Position = UDim2.new 0.5, -5, 0.5, 2 scrubThree.Parent = verticalDragger areaSoak = Instance.new "TextButton" 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 areaSoak.Parent = getScreenGuiAncestor parent draggingVertical = false local startYPos verticalDragger.MouseEnter\connect -> verticalDragger.BackgroundColor3 = Color3.new 60 / 255, 60 / 255, 60 / 255 verticalDragger.MouseLeave\connect -> verticalDragger.BackgroundColor3 = Color3.new 50 / 255, 50 / 255, 50 / 255 verticalDragger.MouseButton1Down\connect (_, y) -> draggingVertical = true areaSoak.Visible = true startYPos = y areaSoak.MouseButton1Up\connect -> draggingVertical = false areaSoak.Visible = false areaSoak.MouseMoved\connect (_, y) -> if not draggingVertical return yDelta = y - startYPos if not control.ScrollDownButton.Visible and yDelta > 0 return if (widgetContainer.Size.Y.Offset + yDelta) < 150 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 startYPos = y if widgetContainer.Size.Y.Offset + yDelta >= 0 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 switchMinimize = -> minimizeFrame.Visible = not minimizeFrame.Visible if scrollable frame.Visible = not frame.Visible verticalDragger.Visible = not verticalDragger.Visible control.Visible = not control.Visible else widgetContainer.Visible = not widgetContainer.Visible if minimizeFrame.Visible minimizeButton.Text = "+" else minimizeButton.Text = "-" minimizeBigButton.MouseButton1Click\connect -> switchMinimize! minimizeButton.MouseButton1Click\connect -> switchMinimize! if scrollable dragBar, frame, helpFrame, closeEvent else dragBar, widgetContainer, helpFrame, closeEvent t.Help = (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 "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'" elseif funcNameOrFunc == "CreateDropDownMenu" or funcNameOrFunc == t.CreateDropDownMenu "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" elseif funcNameOrFunc == "CreateMessageDialog" or funcNameOrFunc == t.CreateMessageDialog "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" elseif funcNameOrFunc == "CreateStyledMessageDialog" or funcNameOrFunc == t.CreateStyledMessageDialog "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" elseif funcNameOrFunc == "GetFontHeight" or funcNameOrFunc == t.GetFontHeight "Function GetFontHeight. " .. "Arguments: (font, fontSize). " .. "Side effect: returns the size in pixels of the given font + fontSize" elseif funcNameOrFunc == "CreateScrollingFrame" or funcNameOrFunc == t.CreateScrollingFrame "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)" elseif funcNameOrFunc == "CreateTrueScrollingFrame" or funcNameOrFunc == t.CreateTrueScrollingFrame "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." elseif funcNameOrFunc == "AutoTruncateTextObject" or funcNameOrFunc == t.AutoTruncateTextObject "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" elseif funcNameOrFunc == "CreateSlider" or funcNameOrFunc == t.CreateSlider "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." elseif funcNameOrFunc == "CreateLoadingFrame" or funcNameOrFunc == t.CreateLoadingFrame "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." elseif funcNameOrFunc == "CreateTerrainMaterialSelector" or funcNameOrFunc == t.CreateTerrainMaterialSelector "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." t