-- V3.6: polished UI, lots more fling tiers, scrollable button area + search bar -- Keeps existing behavior: restore draggable, minimize/close, freeze, custom editor, persistent pos, scroll disables drag local Players = game:GetService("Players") local Debris = game:GetService("Debris") local UIS = game:GetService("UserInputService") local RunService = game:GetService("RunService") local player = Players.LocalPlayer local character = player.Character or player.CharacterAdded:Wait() local humanoidRootPart = character:WaitForChild("HumanoidRootPart") local humanoid = character:WaitForChild("Humanoid") -- ensure closed attribute is in a sane state when the script runs (fixes re-exec problem) player:SetAttribute("FlingGuiClosed", false) -- -------------------- -- TIER DEFINITIONS (extra tiers added) -- -------------------- local Tiers = { -- "Easy" family (replacing Quick Low / Quick Medium) ["Cakewalk"] = {force = 18, up = 8, dur = 0.10, spin = 12}, ["Very Easy"] = {force = 35, up = 18, dur = 0.12, spin = 25}, ["Easy"] = {force = 70, up = 35, dur = 0.14, spin = 50}, ["Easy Plus"] = {force = 95, up = 45, dur = 0.16, spin = 70}, ["Comfortable"] = {force = 120, up = 60, dur = 0.18, spin = 85}, -- baseline tiers (some original names retained and expanded) ["Low Fling"] = {force = 30, up = 20, dur = 0.30, spin = 30}, ["Medium Fling"] = {force = 60, up = 40, dur = 0.40, spin = 60}, ["Average"] = {force = 140, up = 72, dur = 0.20, spin = 90}, ["Mid"] = {force = 200, up = 100, dur = 0.20, spin = 120}, ["Hard Fling"] = {force = 300, up = 140, dur = 0.30, spin = 180}, ["Very Hard"] = {force = 420, up = 190, dur = 0.32, spin = 230}, ["Turbo Fling"] = {force = 180, up = 70, dur = 0.18, spin = 140}, ["Insane Fling"] = {force = 160, up = 80, dur = 0.50, spin = 160}, ["Extreme Fling"] = {force = 250, up = 120, dur = 0.60, spin = 220}, ["Ultra Fling"] = {force = 400, up = 180, dur = 0.80, spin = 300}, ["Meteor Fling"] = {force = 520, up = 200, dur = 0.90, spin = 380}, ["Difficult"] = {force = 650, up = 240, dur = 0.95, spin = 420}, ["Challenging"] = {force = 820, up = 300, dur = 1.00, spin = 520}, -- God-tier family ["God Fling"] = {force = 1000, up = 350, dur = 1.00, spin = 600}, ["Apex Fling"] = {force = 1400, up = 700, dur = 1.20, spin = 700}, ["Titan Fling"] = {force = 1800, up = 900, dur = 1.40, spin = 820}, ["Colossus Fling"] = {force = 2400, up = 1100, dur = 1.60, spin = 1000}, ["Leviathan Fling"] = {force = 3200, up = 1600, dur = 1.80, spin = 1300}, ["Omega Fling"] = {force = 4000, up = 2000, dur = 2.00, spin = 1600}, -- Cosmic family ["Void Fling"] = {force = 6000, up = 3000, dur = 2.40, spin = 2000}, ["Nebula Fling"] = {force = 9000, up = 4500, dur = 2.80, spin = 2600}, ["Nova Fling"] = {force = 14000, up = 8000, dur = 3.20, spin = 3400}, ["Singularity"] = {force = 22000, up = 12000, dur = 3.80, spin = 4400}, ["Infinity Fling"] = {force = 35000, up = 20000, dur = 4.50, spin = 6000}, -- advanced cosmic/god extremes (added many) ["Eternity Fling"] = {force = 50000, up = 26000, dur = 5.00, spin = 7200}, ["Armageddon Fling"] = {force = 70000, up = 36000, dur = 5.50, spin = 9200}, ["Cataclysm Fling"] = {force = 100000, up = 56000, dur = 6.00, spin = 12500}, ["Oblivion Fling"] = {force = 140000, up = 84000, dur = 6.50, spin = 16000}, ["Transcendence"] = {force = 200000, up = 120000, dur = 7.00, spin = 20000}, ["Ascension Fling"] = {force = 280000, up = 160000, dur = 7.50, spin = 25000}, -- search-friendly & absurd extremes ["Apotheosis"] = {force = 380000, up = 220000, dur = 8.00, spin = 32000}, ["Quantum Fling"] = {force = 500000, up = 300000, dur = 9.00, spin = 42000}, ["Purgatory Fling"] = {force = 750000, up = 420000, dur = 10.0, spin = 56000}, ["Empyrean Fling"] = {force = 1100000,up = 700000, dur = 11.0, spin = 78000}, -- extreme-end "nightmare" tiers ["Omega II"] = {force = 1600000, up = 900000, dur = 12.0, spin = 120000}, ["Cosmos Fling"] = {force = 2500000, up = 1500000,dur = 13.0, spin = 180000}, ["Mythic Fling"] = {force = 4000000, up = 2400000,dur = 14.0, spin = 260000}, ["Absolute Fling"] = {force = 7000000, up = 4200000,dur = 16.0, spin = 420000}, ["Singularity Prime"] = {force = 12000000,up = 7000000,dur = 18.0, spin = 700000}, ["Deus Fling"] = {force = 25000000,up = 14000000,dur = 20.0, spin = 1200000}, -- chart-named extras requested (terrifying / catastrophic / etc) ["Terrifying"] = {force = 900000, up = 520000, dur = 12.5, spin = 260000}, ["Catastrophic"] = {force = 1800000, up = 1000000,dur = 14.0, spin = 420000}, ["Top"] = {force = 5000000, up = 3000000,dur = 16.0, spin = 700000}, ["Nightmare"] = {force = 9000000, up = 5200000,dur = 18.0, spin = 1000000}, ["Impossible"] = {force = 20000000,up = 12000000,dur = 22.0, spin = 2000000}, ["Absurd"] = {force = 50000000,up = 30000000,dur = 30.0, spin = 5000000}, -- Random tier placeholder (actual random stats generated on use) ["Random"] = {force = 0, up = 0, dur = 0, spin = 0}, } -- Default custom local customName = "Custom Fling" local CustomStats = {force = 80, up = 40, dur = 0.40, spin = 80} -- cooldown local COOLDOWN = 0.12 local lastUsed = {} local function safeButtonPress(name) local t = tick() if lastUsed[name] and (t - lastUsed[name] < COOLDOWN) then return false end lastUsed[name] = t return true end -- Freeze state local isFrozen = false local function clearRootForces() if not humanoidRootPart then return end for _, child in ipairs(humanoidRootPart:GetChildren()) do if child:IsA("BodyVelocity") or child:IsA("BodyAngularVelocity") then pcall(function() child:Destroy() end) end end end local function freezeCharacter() isFrozen = true clearRootForces() pcall(function() if humanoid then humanoid.PlatformStand = true end if humanoidRootPart then humanoidRootPart.Anchored = true end end) end local function unfreezeCharacter() isFrozen = false pcall(function() if humanoidRootPart then humanoidRootPart.Anchored = false end if humanoid then humanoid.PlatformStand = false end end) end -- Generic fling (forward) local function flingGeneric(force, upward, duration, spin) if isFrozen then return end if not humanoid or humanoid.Health <= 0 then return end if not humanoidRootPart then return end local forward = humanoidRootPart.CFrame.LookVector local bv = Instance.new("BodyVelocity") bv.MaxForce = Vector3.new(math.huge, math.huge, math.huge) bv.Velocity = (forward * force) + Vector3.new(0, upward, 0) bv.Parent = humanoidRootPart local bav = Instance.new("BodyAngularVelocity") bav.MaxTorque = Vector3.new(math.huge, math.huge, math.huge) bav.AngularVelocity = Vector3.new(math.random(-math.floor(spin), math.floor(spin)), math.random(-math.floor(spin), math.floor(spin)), math.random(-math.floor(spin), math.floor(spin))) bav.Parent = humanoidRootPart Debris:AddItem(bv, duration) Debris:AddItem(bav, duration) end -- function to generate random (unbounded-style) stats local function generateRandomStats() -- seed with current tick for variety local seed = math.floor(tick() * 1000) % 2147483647 math.randomseed(seed) -- random ranges intentionally huge to emulate "no limit" feel (adjust if needed) local maxForce = 50000000 -- 50 million local maxUp = 30000000 -- 30 million local maxSpin = 5000000 -- 5 million local maxDur = 60 -- up to 60 seconds (long) local force = math.random() * maxForce local up = math.random() * maxUp local spin = math.random() * maxSpin local dur = 0.05 + (math.random() * maxDur) -- tiny safety clamps (ensure duration not zero) if dur <= 0 then dur = 0.05 end return force, up, dur, math.floor(spin) end -- save/load position local function saveFramePositionToPlayer(frame) local sv = player:FindFirstChild("FlingGuiPos") if not sv then sv = Instance.new("StringValue") sv.Name = "FlingGuiPos" sv.Parent = player end local p = frame.Position sv.Value = string.format("%.6f;%d;%.6f;%d", p.X.Scale, p.X.Offset, p.Y.Scale, p.Y.Offset) end local function loadFramePositionFromPlayer() local sv = player:FindFirstChild("FlingGuiPos") if not sv then return UDim2.new(1, -160, 0.55, 0) end local ok, a,b,c,d = pcall(function() local s = sv.Value local xS,xO,yS,yO = string.match(s, "([%d%.%-]+);([%d%-]+);([%d%.%-]+);([%d%-]+)") return tonumber(xS), tonumber(xO), tonumber(yS), tonumber(yO) end) if ok and a and b and c and d then return UDim2.new(a, b, c, d) end return UDim2.new(1, -160, 0.55, 0) end -- Create GUI (respects player attribute "FlingGuiClosed") local function createFlingGui() -- if player closed earlier, do not recreate if player:GetAttribute("FlingGuiClosed") == true then return end -- ensure no duplicates (destroy any old one) if player.PlayerGui:FindFirstChild("FlingGui") then player.PlayerGui.FlingGui:Destroy() end -- make gui local screenGui = Instance.new("ScreenGui") screenGui.Name = "FlingGui" screenGui.ResetOnSpawn = false screenGui.Parent = player.PlayerGui -- mark as not closed player:SetAttribute("FlingGuiClosed", false) -- ordered button list (controls which buttons show and in what order) local order = { "Cakewalk","Very Easy","Easy","Easy Plus","Comfortable", "Low Fling","Medium Fling","Average","Mid","Hard Fling","Very Hard", "Turbo Fling","Insane Fling","Extreme Fling","Ultra Fling","Meteor Fling", "Difficult","Challenging", "God Fling","Apex Fling","Titan Fling","Colossus Fling","Leviathan Fling","Omega Fling", "Void Fling","Nebula Fling","Nova Fling","Singularity","Infinity Fling", "Eternity Fling","Armageddon Fling","Cataclysm Fling","Oblivion Fling", "Transcendence","Ascension Fling","Apotheosis","Quantum Fling","Purgatory Fling","Empyrean Fling", "Omega II","Cosmos Fling","Mythic Fling","Absolute Fling","Singularity Prime","Deus Fling", "Terrifying","Catastrophic","Top","Nightmare","Impossible","Absurd", "Random" -- keep Random in order but it will be displayed as bottom grouped with controls } -- layout constants local startY = 34 local spacing = 32 local buttonHeight = 28 local visibleButtons = 6 -- how many buttons visible at once before scroll -- main frame (fixed height; buttons live inside ScrollingFrame) local frame = Instance.new("Frame") frame.Name = "MainFrame" frame.Size = UDim2.new(0, 200, 0, 40 + visibleButtons * spacing + 36) -- slightly wider frame.Position = loadFramePositionFromPlayer() frame.BackgroundColor3 = Color3.fromRGB(22,22,22) frame.BorderSizePixel = 0 frame.Active = true frame.Draggable = true frame.Parent = screenGui -- nicer rounded corners local frameCorner = Instance.new("UICorner", frame) frameCorner.CornerRadius = UDim.new(0, 10) local frameStroke = Instance.new("UIStroke", frame) frameStroke.Color = Color3.fromRGB(50,50,50) frameStroke.Thickness = 1 frameStroke.Transparency = 0.6 -- persist position frame:GetPropertyChangedSignal("Position"):Connect(function() pcall(function() saveFramePositionToPlayer(frame) end) end) -- helper to temporarily disable/enable dragging local dragDisabledCount = 0 local function disableDrag() dragDisabledCount = dragDisabledCount + 1 frame.Draggable = false end local function enableDrag() dragDisabledCount = math.max(0, dragDisabledCount - 1) if dragDisabledCount == 0 then frame.Draggable = true end end -- title area local titleBg = Instance.new("Frame") titleBg.Size = UDim2.new(1, 0, 0, 36) titleBg.Position = UDim2.new(0, 0, 0, 0) titleBg.BackgroundTransparency = 0.08 titleBg.BackgroundColor3 = Color3.fromRGB(12,12,12) titleBg.BorderSizePixel = 0 titleBg.Parent = frame local titleCorner = Instance.new("UICorner", titleBg) titleCorner.CornerRadius = UDim.new(0, 10) local title = Instance.new("TextLabel") title.Size = UDim2.new(1, -120, 1, 0) title.Position = UDim2.new(0, 12, 0, 6) title.BackgroundTransparency = 1 title.Text = "Fling Menu — V3.6" title.Font = Enum.Font.GothamBold title.TextSize = 15 title.TextColor3 = Color3.fromRGB(230,230,230) title.TextXAlignment = Enum.TextXAlignment.Left title.Parent = titleBg -- CLOSE & MINIMIZE local closeBtn = Instance.new("TextButton") closeBtn.Size = UDim2.new(0, 28, 0, 24) closeBtn.Position = UDim2.new(1, -34, 0, 6) closeBtn.AnchorPoint = Vector2.new(0,0) closeBtn.BackgroundColor3 = Color3.fromRGB(36,36,36) closeBtn.BorderSizePixel = 0 closeBtn.Font = Enum.Font.SourceSansBold closeBtn.Text = "X" closeBtn.TextScaled = true closeBtn.TextColor3 = Color3.fromRGB(255,255,255) closeBtn.Parent = titleBg local closeCorner = Instance.new("UICorner", closeBtn) closeCorner.CornerRadius = UDim.new(0,6) closeBtn.MouseButton1Click:Connect(function() player:SetAttribute("FlingGuiClosed", true) pcall(function() screenGui:Destroy() end) end) local minimizeBtn = Instance.new("TextButton") minimizeBtn.Size = UDim2.new(0, 28, 0, 24) minimizeBtn.Position = UDim2.new(1, -68, 0, 6) minimizeBtn.AnchorPoint = Vector2.new(0,0) minimizeBtn.BackgroundColor3 = Color3.fromRGB(36,36,36) minimizeBtn.BorderSizePixel = 0 minimizeBtn.Font = Enum.Font.SourceSansBold minimizeBtn.Text = "—" minimizeBtn.TextScaled = true minimizeBtn.TextColor3 = Color3.fromRGB(255,255,255) minimizeBtn.Parent = titleBg local miniCorner = Instance.new("UICorner", minimizeBtn) miniCorner.CornerRadius = UDim.new(0,6) local minimized = false local restoreBtn = nil local function createRestoreButton(atPos) if restoreBtn and restoreBtn.Parent then restoreBtn:Destroy() restoreBtn = nil end local rFrame = Instance.new("Frame") rFrame.Name = "FlingRestore" rFrame.Size = UDim2.new(0, 64, 0, 64) rFrame.Position = atPos or UDim2.new(1, -160, 0.55, 0) rFrame.BackgroundColor3 = Color3.fromRGB(34,34,34) rFrame.BorderSizePixel = 0 rFrame.Active = true rFrame.Parent = screenGui local rCorner = Instance.new("UICorner", rFrame) rCorner.CornerRadius = UDim.new(0, 12) local rBtn = Instance.new("TextButton") rBtn.Size = UDim2.new(1,0,1,0) rBtn.Position = UDim2.new(0,0,0,0) rBtn.BackgroundTransparency = 1 rBtn.Font = Enum.Font.GothamBold rBtn.Text = "☐" rBtn.TextSize = 28 rBtn.TextColor3 = Color3.fromRGB(230,230,230) rBtn.Parent = rFrame local dragInput, dragStart, startPos = nil, nil, nil local function clampToViewport(x,y,frameObj) local vp = workspace.CurrentCamera and workspace.CurrentCamera.ViewportSize or Vector2.new(1920,1080) local absSize = frameObj.AbsoluteSize local maxX = math.max(0, vp.X - absSize.X) local maxY = math.max(0, vp.Y - absSize.Y) return math.clamp(x, 0, maxX), math.clamp(y, 0, maxY) end local function update(input) if not dragStart or not startPos then return end local delta = input.Position - dragStart local newX = startPos.x + delta.X local newY = startPos.y + delta.Y newX, newY = clampToViewport(newX, newY, rFrame) rFrame.Position = UDim2.new(0, newX, 0, newY) end rBtn.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then dragInput = input dragStart = input.Position startPos = { x = rFrame.AbsolutePosition.X, y = rFrame.AbsolutePosition.Y } input.Changed:Connect(function() if input.UserInputState == Enum.UserInputState.End then dragInput = nil dragStart = nil startPos = nil end end) end end) UIS.InputChanged:Connect(function(input) if input == dragInput then update(input) end end) rBtn.MouseButton1Click:Connect(function() if frame and frame.Parent then frame.Visible = true pcall(function() frame.Position = rFrame.Position saveFramePositionToPlayer(frame) end) end if screenGui:FindFirstChild("CustomEditorFrame") then pcall(function() screenGui.CustomEditorFrame.Visible = false end) end pcall(function() rFrame:Destroy() end) restoreBtn = nil minimized = false end) rFrame:GetPropertyChangedSignal("AbsolutePosition"):Connect(function() pcall(function() saveFramePositionToPlayer(rFrame) end) end) restoreBtn = rFrame end minimizeBtn.MouseButton1Click:Connect(function() if not minimized then frame.Visible = false if screenGui:FindFirstChild("CustomEditorFrame") then screenGui.CustomEditorFrame.Visible = false end local pos = (function() local p = frame.Position; return UDim2.new(p.X.Scale, p.X.Offset, p.Y.Scale, p.Y.Offset) end)() createRestoreButton(pos) minimized = true else if restoreBtn and restoreBtn.Parent then local textBtn = restoreBtn:FindFirstChildOfClass("TextButton") if textBtn then textBtn:CaptureFocus(); textBtn:MouseButton1Click() end end minimized = false end end) -- -------------------- -- SEARCH BAR -- -------------------- local searchBox = Instance.new("TextBox") searchBox.Size = UDim2.new(1, -96, 0, 22) searchBox.Position = UDim2.new(0, 12, 0, 40) searchBox.PlaceholderText = "Search fling..." searchBox.Text = "" searchBox.Font = Enum.Font.Gotham searchBox.TextSize = 14 searchBox.ClearTextOnFocus = false searchBox.BackgroundColor3 = Color3.fromRGB(28,28,28) searchBox.TextColor3 = Color3.fromRGB(230,230,230) searchBox.Parent = frame local sbCorner = Instance.new("UICorner", searchBox) sbCorner.CornerRadius = UDim.new(0,6) local searchIcon = Instance.new("TextLabel") searchIcon.Size = UDim2.new(0, 20, 0, 20) searchIcon.Position = UDim2.new(1, -72, 0, 42) searchIcon.BackgroundTransparency = 1 searchIcon.Text = "🔎" searchIcon.Font = Enum.Font.SourceSans searchIcon.TextScaled = true searchIcon.Parent = frame -- -------------------- -- SCROLLING BUTTON AREA -- -------------------- local scrollFrame = Instance.new("ScrollingFrame") scrollFrame.Name = "ButtonsScroll" scrollFrame.Size = UDim2.new(1, -12, 1, -(48 + 28)) -- leave room for title + search and bottom scrollFrame.Position = UDim2.new(0, 6, 0, startY + 18) scrollFrame.BackgroundTransparency = 1 scrollFrame.BorderSizePixel = 0 scrollFrame.CanvasSize = UDim2.new(0,0,0,0) scrollFrame.ScrollBarThickness = 8 scrollFrame.AutomaticCanvasSize = Enum.AutomaticSize.Y scrollFrame.ScrollingDirection = Enum.ScrollingDirection.Y scrollFrame.Parent = frame local list = Instance.new("UIListLayout") list.SortOrder = Enum.SortOrder.LayoutOrder list.Padding = UDim.new(0, 6) list.Parent = scrollFrame local topPad = Instance.new("Frame") topPad.Size = UDim2.new(1,0,0,6) topPad.BackgroundTransparency = 1 topPad.BorderSizePixel = 0 topPad.Parent = scrollFrame -- styling function (choose color by name/category from your chart) local function styleForName(name) -- explicit Random style: black + icon if name == "Random" then return { color = Color3.fromRGB(8,8,8), icon = "◼" } end -- chart-based colors (no emoji) -- Easy family if name:match("Cakewalk") or name:match("Very Easy") then return { color = Color3.fromRGB(200, 245, 200) } -- pale light green elseif name:match("^Easy") or name:match("Comfortable") or name:match("Easy Plus") then return { color = Color3.fromRGB(80, 200, 120) } -- green elseif name:match("Average") then return { color = Color3.fromRGB(250, 220, 110) } -- yellow elseif name:match("Mid") or name:match("^Medium") then return { color = Color3.fromRGB(255, 170, 90) } -- orange (mid) elseif name:match("Hard") and not name:match("Very Hard") then return { color = Color3.fromRGB(255, 140, 80) } -- orange elseif name:match("Very Hard") then return { color = Color3.fromRGB(220, 100, 40) } -- dark orange elseif name:match("Difficult") then return { color = Color3.fromRGB(220, 60, 60) } -- red elseif name:match("Challenging") then return { color = Color3.fromRGB(170, 30, 30) } -- dark red elseif name:match("High") or name:match("^Apex") then return { color = Color3.fromRGB(180, 40, 40) } -- pressure zone red elseif name:match("Intense") or name:match("Remorseless") then return { color = Color3.fromRGB(220, 60, 120) } -- hot pinkish elseif name:match("Arduous") or name:match("Nightmare") then return { color = Color3.fromRGB(140, 80, 200) } -- purple elseif name:match("Insane") then return { color = Color3.fromRGB(90, 140, 220) } -- blue elseif name:match("^Extreme") and not name:match("Extreme Fling") then return { color = Color3.fromRGB(130, 200, 240) } -- light blue elseif name:match("Extreme Fling") then return { color = Color3.fromRGB(70,140,220) } -- darker blue elseif name:match("Terrifying") then return { color = Color3.fromRGB(80, 220, 220) } -- cyan elseif name:match("Catastrophic") then return { color = Color3.fromRGB(220,220,230) } -- pale white/gray elseif name:match("Top") or name:match("Impossible") then return { color = Color3.fromRGB(24,24,24) } -- black/dark elseif name:match("Nightmare") then return { color = Color3.fromRGB(120,40,160) } -- dark purple elseif name:match("Absurd") then return { color = Color3.fromRGB(10,10,10) } -- near-black end -- fallback: use magnitude-based buckets (original behavior for cosmic/god) local stats = Tiers[name] if not stats then return { color = Color3.fromRGB(38,38,38) } end local f = stats.force if f < 200 then return { color = Color3.fromRGB(75,170,255) } -- quick-ish blue elseif f < 2000 then return { color = Color3.fromRGB(60,180,90) } -- green elseif f < 10000 then return { color = Color3.fromRGB(220,180,60) } -- gold elseif f < 200000 then return { color = Color3.fromRGB(150,80,220) } -- cosmic purple else return { color = Color3.fromRGB(200,60,60) } -- extreme/ultimate red end end -- helper to create one button inside scrollFrame with rounded corners + stroke local buttonsByName = {} -- store refs + meta for filtering local function makeScrollButton(text, callback) local info = styleForName(text) or { color = Color3.fromRGB(38,38,38) } local btn = Instance.new("TextButton") btn.Size = UDim2.new(1, -10, 0, buttonHeight) btn.BackgroundColor3 = info.color btn.BorderSizePixel = 0 btn.Font = Enum.Font.Gotham btn.TextScaled = true -- pick readable text color (dark on bright, light on dark) local avg = (info.color.R + info.color.G + info.color.B) / 3 btn.TextColor3 = (avg > 0.5) and Color3.fromRGB(24,24,24) or Color3.fromRGB(235,235,235) local textToShow = text if info.icon then textToShow = (info.icon .. " " .. text) end btn.Text = textToShow btn.Parent = scrollFrame local corner = Instance.new("UICorner", btn) corner.CornerRadius = UDim.new(0,6) local stroke = Instance.new("UIStroke", btn) stroke.Color = Color3.fromRGB(48,48,48) stroke.Thickness = 1 stroke.Transparency = 0.6 btn.MouseButton1Click:Connect(function() if not safeButtonPress(text) then return end btn.BackgroundTransparency = 0.2 task.delay(0.08, function() if btn then btn.BackgroundTransparency = 0 end end) callback() end) buttonsByName[text] = { btn = btn, name = text } return btn end -- create buttons from order for i, name in ipairs(order) do local stats = Tiers[name] if stats and name ~= "Random" then makeScrollButton(name, function() flingGeneric(stats.force, stats.up, stats.dur, stats.spin) end) elseif name == "Random" then -- create placeholder now; actual Random button will be created later next to Freeze/Custom for bottom alignment -- (we'll skip creating a list entry here so it doesn't appear twice) else makeScrollButton(name, function() end) end end -- custom and freeze buttons at end (use neutral color) local neutralColor = Color3.fromRGB(38,38,38) local function makeNeutralButton(text, callback) local btn = Instance.new("TextButton") btn.Size = UDim2.new(1, -10, 0, buttonHeight) btn.BackgroundColor3 = neutralColor btn.BorderSizePixel = 0 btn.Font = Enum.Font.Gotham btn.TextScaled = true btn.TextColor3 = Color3.fromRGB(235,235,235) btn.Text = text btn.Parent = scrollFrame local corner = Instance.new("UICorner", btn) corner.CornerRadius = UDim.new(0,6) local stroke = Instance.new("UIStroke", btn) stroke.Color = Color3.fromRGB(58,58,58) stroke.Thickness = 1 stroke.Transparency = 0.7 btn.MouseButton1Click:Connect(function() if not safeButtonPress(text) then return end btn.BackgroundTransparency = 0.45 task.delay(0.08, function() if btn then btn.BackgroundTransparency = 0 end end) callback() end) return btn end local customBtn = makeNeutralButton(customName, function() flingGeneric(CustomStats.force, CustomStats.up, CustomStats.dur, CustomStats.spin) end) customBtn.Name = "CustomBtn" buttonsByName[customName] = { btn = customBtn, name = customName } local freezeBtn = makeNeutralButton("Freeze ❄️", function() if isFrozen then unfreezeCharacter() pcall(function() freezeBtn.Text = "Freeze ❄️" end) else freezeCharacter() pcall(function() freezeBtn.Text = "Unfreeze ❄️" end) end end) freezeBtn.Name = "FreezeBtn" buttonsByName["Freeze ❄️"] = { btn = freezeBtn, name = "Freeze ❄️" } -- RANDOM button (black) — bottom, next to Freeze & Custom local function makeRandomButton() local info = { color = Color3.fromRGB(8,8,8), icon = "◼" } local btn = Instance.new("TextButton") btn.Size = UDim2.new(1, -10, 0, buttonHeight) btn.BackgroundColor3 = info.color btn.BorderSizePixel = 0 btn.Font = Enum.Font.Gotham btn.TextScaled = true btn.TextColor3 = Color3.fromRGB(235,235,235) btn.Text = (info.icon .. " Random") btn.Parent = scrollFrame local corner = Instance.new("UICorner", btn) corner.CornerRadius = UDim.new(0,6) local stroke = Instance.new("UIStroke", btn) stroke.Color = Color3.fromRGB(28,28,28) stroke.Thickness = 1 stroke.Transparency = 0.5 btn.MouseButton1Click:Connect(function() if not safeButtonPress("Random") then return end -- generate random stats and fling local f,u,d,s = generateRandomStats() -- show a tiny visual flash by temporarily changing transparency btn.BackgroundTransparency = 0.2 task.delay(0.08, function() if btn then btn.BackgroundTransparency = 0 end end) flingGeneric(f, u, d, s) end) return btn end local randomBtn = makeRandomButton() buttonsByName["Random"] = { btn = randomBtn, name = "Random" } -- search filter function (case-insensitive substring) local function filterButtons(query) query = tostring(query or ""):lower() for name, meta in pairs(buttonsByName) do local btn = meta.btn if not btn then -- skip else if query == "" then btn.Visible = true else local ok = (string.find(name:lower(), query, 1, true) ~= nil) btn.Visible = ok end end end end -- hook search input (live) searchBox:GetPropertyChangedSignal("Text"):Connect(function() local q = searchBox.Text or "" filterButtons(q) end) -- pressing ESC clears search searchBox.Focused:Connect(function() local conn conn = UIS.InputBegan:Connect(function(input, gameProcessed) if gameProcessed then return end if input.KeyCode == Enum.KeyCode.Escape then searchBox.Text = "" filterButtons("") conn:Disconnect() end end) end) -- -------------------- -- SCROLL HANDLING: disable dragging while user scrolls -- -------------------- local wheelDebounce = 0 UIS.InputChanged:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseWheel then disableDrag() wheelDebounce = tick() task.spawn(function() task.wait(0.25) if tick() - wheelDebounce >= 0.25 then enableDrag() end end) end end) scrollFrame.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then disableDrag() local conn conn = input.Changed:Connect(function() if input.UserInputState == Enum.UserInputState.End then enableDrag() conn:Disconnect() end end) end end) scrollFrame.MouseEnter:Connect(function() disableDrag() end) scrollFrame.MouseLeave:Connect(function() enableDrag() end) -- gear (moved under title) local gear = Instance.new("TextButton") gear.Size = UDim2.new(0,28,0,28) gear.Position = UDim2.new(0,6,0,36) gear.BackgroundColor3 = Color3.fromRGB(30,30,30) gear.BorderSizePixel = 0 gear.Font = Enum.Font.SourceSans gear.Text = "⚙" gear.TextScaled = true gear.TextColor3 = Color3.fromRGB(255,255,255) gear.Parent = frame local gearCorner = Instance.new("UICorner", gear) gearCorner.CornerRadius = UDim.new(0,6) -- external editFrame (sibling so it sits outside) - fixed name local editFrame = Instance.new("Frame") editFrame.Name = "CustomEditorFrame" editFrame.Size = UDim2.new(0,200,0,160) editFrame.Position = UDim2.new(frame.Position.X.Scale, frame.Position.X.Offset - (200 + 8), frame.Position.Y.Scale, frame.Position.Y.Offset) editFrame.BackgroundTransparency = 0.02 editFrame.BackgroundColor3 = Color3.fromRGB(16,16,16) editFrame.BorderSizePixel = 0 editFrame.Visible = false editFrame.Parent = screenGui local editCorner = Instance.new("UICorner", editFrame) editCorner.CornerRadius = UDim.new(0,8) local function updateEditPosition() local fx = frame.Position.X.Scale local fxoff = frame.Position.X.Offset local fy = frame.Position.Y.Scale local fyoff = frame.Position.Y.Offset local newXoff = fxoff - (editFrame.Size.X.Offset + 8) editFrame.Position = UDim2.new(fx, newXoff, fy, fyoff) end frame:GetPropertyChangedSignal("Position"):Connect(function() pcall(updateEditPosition) end) -- simple editor contents (unchanged behavior) local editTitle = Instance.new("TextLabel") editTitle.Size = UDim2.new(1,0,0,26) editTitle.Position = UDim2.new(0,0,0,6) editTitle.BackgroundTransparency = 1 editTitle.Text = "Custom Editor" editTitle.Font = Enum.Font.GothamBold editTitle.TextSize = 14 editTitle.TextColor3 = Color3.fromRGB(240,240,240) editTitle.Parent = editFrame local function createLabelTextbox(y, labelText, default) local lbl = Instance.new("TextLabel") lbl.Size = UDim2.new(0.42,0,0,18) lbl.Position = UDim2.new(0,6,0,y) lbl.BackgroundTransparency = 1 lbl.Text = labelText lbl.Font = Enum.Font.Gotham lbl.TextSize = 12 lbl.TextColor3 = Color3.fromRGB(200,200,200) lbl.Parent = editFrame local tb = Instance.new("TextBox") tb.Size = UDim2.new(0.56,-10,0,18) tb.Position = UDim2.new(0.42,8,0,y) tb.BackgroundColor3 = Color3.fromRGB(28,28,28) tb.TextColor3 = Color3.fromRGB(240,240,240) tb.Text = tostring(default) tb.Font = Enum.Font.Gotham tb.TextSize = 12 tb.ClearTextOnFocus = false tb.Parent = editFrame local tbCorner = Instance.new("UICorner", tb) tbCorner.CornerRadius = UDim.new(0,4) return tb end local nameLabel = Instance.new("TextLabel") nameLabel.Size = UDim2.new(0.42,0,0,18) nameLabel.Position = UDim2.new(0,6,0,36) nameLabel.BackgroundTransparency = 1 nameLabel.Text = "Name" nameLabel.Font = Enum.Font.Gotham nameLabel.TextSize = 12 nameLabel.TextColor3 = Color3.fromRGB(200,200,200) nameLabel.Parent = editFrame local nameBox = Instance.new("TextBox") nameBox.Size = UDim2.new(0.56,-10,0,18) nameBox.Position = UDim2.new(0.42,8,0,36) nameBox.BackgroundColor3 = Color3.fromRGB(28,28,28) nameBox.TextColor3 = Color3.fromRGB(240,240,240) nameBox.Text = customName nameBox.Font = Enum.Font.Gotham nameBox.TextSize = 12 nameBox.ClearTextOnFocus = false nameBox.Parent = editFrame local nbCorner = Instance.new("UICorner", nameBox) nbCorner.CornerRadius = UDim.new(0,4) local forceBox = createLabelTextbox(64, "Force", CustomStats.force) local upBox = createLabelTextbox(88, "Up", CustomStats.up) local durLabel = Instance.new("TextLabel") durLabel.Size = UDim2.new(0.28,0,0,18) durLabel.Position = UDim2.new(0,6,0,112) durLabel.BackgroundTransparency = 1 durLabel.Text = "Dur" durLabel.Font = Enum.Font.Gotham durLabel.TextSize = 12 durLabel.TextColor3 = Color3.fromRGB(200,200,200) durLabel.Parent = editFrame local durBox = Instance.new("TextBox") durBox.Size = UDim2.new(0.28,-6,0,18) durBox.Position = UDim2.new(0.28,4,0,112) durBox.BackgroundColor3 = Color3.fromRGB(28,28,28) durBox.TextColor3 = Color3.fromRGB(240,240,240) durBox.Text = tostring(CustomStats.dur) durBox.Font = Enum.Font.Gotham durBox.TextSize = 12 durBox.ClearTextOnFocus = false durBox.Parent = editFrame local durCorner = Instance.new("UICorner", durBox) durCorner.CornerRadius = UDim.new(0,4) local spinLabel = Instance.new("TextLabel") spinLabel.Size = UDim2.new(0.24,0,0,18) spinLabel.Position = UDim2.new(0.58,6,0,112) spinLabel.BackgroundTransparency = 1 spinLabel.Text = "Spin" spinLabel.Font = Enum.Font.Gotham spinLabel.TextSize = 12 spinLabel.TextColor3 = Color3.fromRGB(200,200,200) spinLabel.Parent = editFrame local spinBox = Instance.new("TextBox") spinBox.Size = UDim2.new(0.40,-10,0,18) spinBox.Position = UDim2.new(0.82,-4,0,112) spinBox.BackgroundColor3 = Color3.fromRGB(28,28,28) spinBox.TextColor3 = Color3.fromRGB(240,240,240) spinBox.Text = tostring(CustomStats.spin) spinBox.Font = Enum.Font.Gotham spinBox.TextSize = 12 spinBox.ClearTextOnFocus = false spinBox.Parent = editFrame local spinCorner = Instance.new("UICorner", spinBox) spinCorner.CornerRadius = UDim.new(0,4) gear.MouseButton1Click:Connect(function() editFrame.Visible = not editFrame.Visible end) -- apply custom (update stats & button text) local function applyCustom() local nameText = tostring(nameBox.Text or ""):gsub("^%s*(.-)%s*$", "%1") if nameText == "" then nameText = "Custom Fling" end local f = tonumber(forceBox.Text) or CustomStats.force local u = tonumber(upBox.Text) or CustomStats.up local d = tonumber(durBox.Text) or CustomStats.dur local s = tonumber(spinBox.Text) or CustomStats.spin if f < 0 then f = 0 end if u < 0 then u = 0 end if d <= 0 then d = 0.05 end if s < 0 then s = 0 end CustomStats = {force = f, up = u, dur = d, spin = s} customName = nameText pcall(function() customBtn.Text = customName end) end local boxes = {nameBox, forceBox, upBox, durBox, spinBox} for _,tb in ipairs(boxes) do tb.FocusLost:Connect(function(enterPressed) if enterPressed then applyCustom() end end) end -- initial editor follow pcall(updateEditPosition) -- apply initial filter (show all) filterButtons("") -- if we created GUI while frozen, reflect freeze button text if isFrozen then pcall(function() freezeBtn.Text = "Unfreeze ❄️" end) end end -- init createFlingGui() -- respawn handler player.CharacterAdded:Connect(function(newChar) character = newChar humanoidRootPart = character:WaitForChild("HumanoidRootPart") humanoid = character:WaitForChild("Humanoid") -- ensure player not frozen on new character isFrozen = false pcall(function() if humanoidRootPart then humanoidRootPart.Anchored = false end if humanoid then humanoid.PlatformStand = false end end) -- small wait then attempt to recreate gui (createFlingGui respects the "FlingGuiClosed" attribute) task.wait(0.12) createFlingGui() end)