-- https://discord.gg/vqRNXrhYJG join n give me suggestions for new games pls local ws = game:GetService("Workspace") local rs = game:GetService("RunService") local Players = game:GetService("Players") local uis = game:GetService("UserInputService") local hs = game:GetService("HttpService") local CFG = { mainExtend = 50, deflectExtend = 50, pulseSpeed = 3, pulseMin = 0.3, pulseMax = 0.7, matchBallHeight = true, bounceLogic = true, halfWidth = 12.8 / 2, halfLength = 24.8 / 2, mainColor = Color3.fromRGB(0, 255, 255), deflectColor = Color3.fromRGB(255, 80, 80), warnColor = Color3.fromRGB(255, 100, 0) } local state = { pulsePhase = 0 } local savedProfiles = {} if makefolder and isfolder then if not isfolder("TrajectoryConfigs") then makefolder("TrajectoryConfigs") end end local function loadProfilesFromDisk() savedProfiles = {} if listfiles and isfolder and isfolder("TrajectoryConfigs") then local files = listfiles("TrajectoryConfigs") for _, filePath in ipairs(files) do local fileName = filePath:match("([^\\/]+)%.json$") if fileName then local success, content = pcall(readfile, filePath) if success then local dataSuccess, data = pcall(function() return hs:JSONDecode(content) end) if dataSuccess and data then savedProfiles[fileName] = data end end end end end end local function saveProfileToDisk(name, data) savedProfiles[name] = data if writefile and isfolder and isfolder("TrajectoryConfigs") then local success, content = pcall(function() return hs:JSONEncode(data) end) if success then pcall(writefile, "TrajectoryConfigs/" .. name .. ".json", content) end end end loadProfilesFromDisk() local container = ws:FindFirstChild("TrajVisualContainer") if container then container:Destroy() end container = Instance.new("Folder") container.Name = "TrajVisualContainer" container.Parent = ws local function create3DLine(color) local part = Instance.new("Part") part.Material = Enum.Material.Neon part.Color = color part.Shape = Enum.PartType.Cylinder part.Anchored = true part.CanCollide = false part.CastShadow = false part.Parent = container return part end local draw3D = { main = create3DLine(CFG.mainColor), deflect = create3DLine(CFG.deflectColor) } local function createUI() local oldGui = Players.LocalPlayer:WaitForChild("PlayerGui"):FindFirstChild("TrajMenuGui") if oldGui then oldGui:Destroy() end local sg = Instance.new("ScreenGui") sg.Name = "TrajMenuGui" sg.ResetOnSpawn = false sg.ZIndexBehavior = Enum.ZIndexBehavior.Sibling sg.Parent = Players.LocalPlayer:WaitForChild("PlayerGui") local frame = Instance.new("Frame") frame.Name = "MainFrame" frame.Size = UDim2.new(0, 320, 0, 300) frame.Position = UDim2.new(0.5, -160, 0.4, -150) frame.BackgroundColor3 = Color3.fromRGB(22, 22, 26) frame.BorderSizePixel = 0 frame.Active = true frame.Draggable = true frame.Parent = sg local stroke = Instance.new("UIStroke") stroke.Thickness = 1.5 stroke.Color = Color3.fromRGB(45, 45, 55) stroke.Parent = frame local corner = Instance.new("UICorner") corner.CornerRadius = UDim.new(0, 8) corner.Parent = frame local tabBar = Instance.new("Frame") tabBar.Size = UDim2.new(1, 0, 0, 35) tabBar.BackgroundColor3 = Color3.fromRGB(30, 30, 36) tabBar.BorderSizePixel = 0 tabBar.Parent = frame local tbCorner = Instance.new("UICorner") tbCorner.CornerRadius = UDim.new(0, 8) tbCorner.Parent = tabBar local cover = Instance.new("Frame") cover.Size = UDim2.new(1, 0, 0, 10) cover.Position = UDim2.new(0, 0, 1, -10) cover.BackgroundColor3 = Color3.fromRGB(30, 30, 36) cover.BorderSizePixel = 0 cover.Parent = tabBar local mainPage = Instance.new("Frame") mainPage.Size = UDim2.new(1, 0, 1, -35) mainPage.Position = UDim2.new(0, 0, 0, 35) mainPage.BackgroundTransparency = 1 mainPage.Visible = true mainPage.Parent = frame local configPage = Instance.new("Frame") configPage.Size = UDim2.new(1, 0, 1, -35) configPage.Position = UDim2.new(0, 0, 0, 35) configPage.BackgroundTransparency = 1 configPage.Visible = false configPage.Parent = frame local mainTabBtn = Instance.new("TextButton") mainTabBtn.Size = UDim2.new(0, 95, 1, 0) mainTabBtn.BackgroundTransparency = 1 mainTabBtn.Text = "Main Settings" mainTabBtn.TextColor3 = Color3.fromRGB(255, 255, 255) mainTabBtn.Font = Enum.Font.GothamBold mainTabBtn.TextSize = 12 mainTabBtn.Parent = tabBar local configTabBtn = Instance.new("TextButton") configTabBtn.Size = UDim2.new(0, 95, 1, 0) configTabBtn.Position = UDim2.new(0, 95, 0, 0) configTabBtn.BackgroundTransparency = 1 configTabBtn.Text = "Saved Configs" configTabBtn.TextColor3 = Color3.fromRGB(140, 140, 150) configTabBtn.Font = Enum.Font.GothamBold configTabBtn.TextSize = 12 configTabBtn.Parent = tabBar mainTabBtn.MouseButton1Click:Connect(function() mainPage.Visible = true configPage.Visible = false mainTabBtn.TextColor3 = Color3.fromRGB(255, 255, 255) configTabBtn.TextColor3 = Color3.fromRGB(140, 140, 150) end) configTabBtn.MouseButton1Click:Connect(function() mainPage.Visible = false configPage.Visible = true mainTabBtn.TextColor3 = Color3.fromRGB(140, 140, 150) configTabBtn.TextColor3 = Color3.fromRGB(255, 255, 255) end) local info = Instance.new("TextLabel") info.Size = UDim2.new(0, 110, 1, 0) info.Position = UDim2.new(1, -120, 0, 0) info.BackgroundTransparency = 1 info.Text = "[RShift to Hide]" info.TextColor3 = Color3.fromRGB(130, 130, 140) info.Font = Enum.Font.Gotham info.TextSize = 11 info.TextXAlignment = Enum.TextXAlignment.Right info.Parent = tabBar uis.InputBegan:Connect(function(input, gpe) if not gpe and input.KeyCode == Enum.KeyCode.RightShift then frame.Visible = not frame.Visible end end) local mainLenFill, mainLenKnob, mainLenLabel local deflectLenFill, deflectLenKnob, deflectLenLabel local function createSlider(text, defaultVal, maxVal, posY, callback) local label = Instance.new("TextLabel") label.Size = UDim2.new(1, -30, 0, 18) label.Position = UDim2.new(0, 15, 0, posY) label.BackgroundTransparency = 1 label.Text = text .. ": " .. tostring(math.round(defaultVal)) label.TextColor3 = Color3.fromRGB(200, 200, 200) label.Font = Enum.Font.GothamSemibold label.TextSize = 11 label.TextXAlignment = Enum.TextXAlignment.Left label.Parent = mainPage local track = Instance.new("Frame") track.Size = UDim2.new(1, -30, 0, 5) track.Position = UDim2.new(0, 15, 0, posY + 20) track.BackgroundColor3 = Color3.fromRGB(45, 45, 55) track.BorderSizePixel = 0 track.Parent = mainPage local fill = Instance.new("Frame") fill.Size = UDim2.new(defaultVal / maxVal, 0, 1, 0) fill.BackgroundColor3 = Color3.fromRGB(0, 180, 255) fill.BorderSizePixel = 0 fill.Parent = track local knob = Instance.new("ImageButton") knob.Size = UDim2.new(0, 12, 0, 12) knob.Position = UDim2.new(defaultVal / maxVal, -6, 0.5, -6) knob.BackgroundColor3 = Color3.fromRGB(255, 255, 255) knob.Parent = track local snap = false knob.MouseButton1Down:Connect(function() snap = true end) uis.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 then snap = false end end) rs.RenderStepped:Connect(function() if snap then local mousePos = uis:GetMouseLocation().X local trackStart = track.AbsolutePosition.X local trackWidth = track.AbsoluteSize.X local perc = math.clamp((mousePos - trackStart) / trackWidth, 0, 1) fill.Size = UDim2.new(perc, 0, 1, 0) knob.Position = UDim2.new(perc, -6, 0.5, -6) local val = math.round(perc * maxVal) label.Text = text .. ": " .. tostring(val) callback(val) end end) return fill, knob, label end local function createColorInput(text, defaultRGB, posY, callback) local label = Instance.new("TextLabel") label.Size = UDim2.new(0, 120, 0, 25) label.Position = UDim2.new(0, 15, 0, posY) label.BackgroundTransparency = 1 label.Text = text label.TextColor3 = Color3.fromRGB(180, 180, 180) label.Font = Enum.Font.GothamSemibold label.TextSize = 11 label.TextXAlignment = Enum.TextXAlignment.Left label.Parent = mainPage local box = Instance.new("TextBox") box.Size = UDim2.new(1, -155, 0, 25) box.Position = UDim2.new(0, 140, 0, posY) box.BackgroundColor3 = Color3.fromRGB(35, 35, 42) box.BorderSizePixel = 0 box.Text = defaultRGB box.TextColor3 = Color3.fromRGB(240, 240, 240) box.Font = Enum.Font.Code box.TextSize = 11 box.Parent = mainPage local bCorner = Instance.new("UICorner") bCorner.CornerRadius = UDim.new(0, 4) bCorner.Parent = box box.FocusLost:Connect(function() local r, g, b = box.Text:match("(%d+),(%d+),(%d+)") if r and g and b then local col = Color3.fromRGB(tonumber(r), tonumber(g), tonumber(b)) callback(col) end end) return box end mainLenFill, mainLenKnob, mainLenLabel = createSlider("Main Length", CFG.mainExtend, 2000, 15, function(v) CFG.mainExtend = v end) local mainColorBox = createColorInput("Main Line Color (RGB):", string.format("%d,%d,%d", CFG.mainColor.R*255, CFG.mainColor.G*255, CFG.mainColor.B*255), 48, function(col) CFG.mainColor = col end) deflectLenFill, deflectLenKnob, deflectLenLabel = createSlider("Deflect Length", CFG.deflectExtend, 2000, 90, function(v) CFG.deflectExtend = v end) local deflectColorBox = createColorInput("Deflect Line Color (RGB):", string.format("%d,%d,%d", CFG.deflectColor.R*255, CFG.deflectColor.G*255, CFG.deflectColor.B*255), 123, function(col) CFG.deflectColor = col end) local toggleBtn = Instance.new("TextButton") toggleBtn.Size = UDim2.new(1, -30, 0, 30) toggleBtn.Position = UDim2.new(0, 15, 0, 175) toggleBtn.BackgroundColor3 = CFG.bounceLogic and Color3.fromRGB(0, 150, 100) or Color3.fromRGB(60, 60, 70) toggleBtn.Font = Enum.Font.GothamBold toggleBtn.Text = CFG.bounceLogic and "Cushion Bounce: ON" or "Cushion Bounce: OFF" toggleBtn.TextColor3 = Color3.fromRGB(255, 255, 255) toggleBtn.TextSize = 11 toggleBtn.Parent = mainPage local btnCorner = Instance.new("UICorner") btnCorner.CornerRadius = UDim.new(0, 5) btnCorner.Parent = toggleBtn local function updateBounceUI() toggleBtn.BackgroundColor3 = CFG.bounceLogic and Color3.fromRGB(0, 150, 100) or Color3.fromRGB(60, 60, 70) toggleBtn.Text = CFG.bounceLogic and "Cushion Bounce: ON" or "Cushion Bounce: OFF" end toggleBtn.MouseButton1Click:Connect(function() CFG.bounceLogic = not CFG.bounceLogic updateBounceUI() end) local profileInput = Instance.new("TextBox") profileInput.Size = UDim2.new(1, -110, 0, 30) profileInput.Position = UDim2.new(0, 15, 0, 15) profileInput.BackgroundColor3 = Color3.fromRGB(35, 35, 42) profileInput.BorderSizePixel = 0 profileInput.Text = "" profileInput.PlaceholderText = "Enter profile name..." profileInput.TextColor3 = Color3.fromRGB(255, 255, 255) profileInput.Font = Enum.Font.Gotham profileInput.TextSize = 12 profileInput.Parent = configPage local piCorner = Instance.new("UICorner") piCorner.CornerRadius = UDim.new(0, 4) piCorner.Parent = profileInput local saveBtn = Instance.new("TextButton") saveBtn.Size = UDim2.new(0, 70, 0, 30) saveBtn.Position = UDim2.new(1, -85, 0, 15) saveBtn.BackgroundColor3 = Color3.fromRGB(0, 120, 200) saveBtn.Font = Enum.Font.GothamBold saveBtn.Text = "Save" saveBtn.TextColor3 = Color3.fromRGB(255, 255, 255) saveBtn.TextSize = 12 saveBtn.Parent = configPage local sbCorner = Instance.new("UICorner") sbCorner.CornerRadius = UDim.new(0, 4) sbCorner.Parent = saveBtn local listFrame = Instance.new("ScrollingFrame") listFrame.Size = UDim2.new(1, -30, 1, -70) listFrame.Position = UDim2.new(0, 15, 0, 55) listFrame.BackgroundTransparency = 1 listFrame.BorderSizePixel = 0 listFrame.CanvasSize = UDim2.new(0, 0, 0, 0) listFrame.ScrollBarThickness = 4 listFrame.Parent = configPage local listLayout = Instance.new("UIListLayout") listLayout.Padding = UDim.new(0, 5) listLayout.SortOrder = Enum.SortOrder.LayoutOrder listLayout.Parent = listFrame local function refreshProfileList() for _, item in ipairs(listFrame:GetChildren()) do if item:IsA("Frame") then item:Destroy() end end local count = 0 for name, data in pairs(savedProfiles) do count = count + 1 local row = Instance.new("Frame") row.Size = UDim2.new(1, -5, 0, 35) row.BackgroundColor3 = Color3.fromRGB(30, 30, 35) row.BorderSizePixel = 0 row.Parent = listFrame local rCorner = Instance.new("UICorner") rCorner.CornerRadius = UDim.new(0, 4) rCorner.Parent = row local rLabel = Instance.new("TextLabel") rLabel.Size = UDim2.new(1, -85, 1, 0) rLabel.Position = UDim2.new(0, 10, 0, 0) rLabel.BackgroundTransparency = 1 rLabel.Text = name rLabel.TextColor3 = Color3.fromRGB(230, 230, 230) rLabel.Font = Enum.Font.GothamSemibold rLabel.TextSize = 12 rLabel.TextXAlignment = Enum.TextXAlignment.Left rLabel.Parent = row local loadBtn = Instance.new("TextButton") loadBtn.Size = UDim2.new(0, 60, 0, 25) loadBtn.Position = UDim2.new(1, -70, 0.5, -12) loadBtn.BackgroundColor3 = Color3.fromRGB(50, 150, 50) loadBtn.Font = Enum.Font.GothamBold loadBtn.Text = "Load" loadBtn.TextColor3 = Color3.fromRGB(255, 255, 255) loadBtn.TextSize = 11 loadBtn.Parent = row local lCorner = Instance.new("UICorner") lCorner.CornerRadius = UDim.new(0, 4) lCorner.Parent = loadBtn loadBtn.MouseButton1Click:Connect(function() CFG.mainExtend = data.mainExtend CFG.deflectExtend = data.deflectExtend CFG.bounceLogic = data.bounceLogic CFG.mainColor = Color3.fromRGB(data.mainColor[1], data.mainColor[2], data.mainColor[3]) CFG.deflectColor = Color3.fromRGB(data.deflectColor[1], data.deflectColor[2], data.deflectColor[3]) mainLenFill.Size = UDim2.new(CFG.mainExtend / 2000, 0, 1, 0) mainLenKnob.Position = UDim2.new(CFG.mainExtend / 2000, -6, 0.5, -6) mainLenLabel.Text = "Main Length: " .. tostring(CFG.mainExtend) deflectLenFill.Size = UDim2.new(CFG.deflectExtend / 2000, 0, 1, 0) deflectLenKnob.Position = UDim2.new(CFG.deflectExtend / 2000, -6, 0.5, -6) deflectLenLabel.Text = "Deflect Length: " .. tostring(CFG.deflectExtend) mainColorBox.Text = string.format("%d,%d,%d", CFG.mainColor.R*255, CFG.mainColor.G*255, CFG.mainColor.B*255) deflectColorBox.Text = string.format("%d,%d,%d", CFG.deflectColor.R*255, CFG.deflectColor.G*255, CFG.deflectColor.B*255) updateBounceUI() end) end listFrame.CanvasSize = UDim2.new(0, 0, 0, count * 40) end saveBtn.MouseButton1Click:Connect(function() local name = profileInput.Text:gsub("[^%w_-]", "") if name ~= "" then local data = { mainExtend = CFG.mainExtend, deflectExtend = CFG.deflectExtend, bounceLogic = CFG.bounceLogic, mainColor = {math.round(CFG.mainColor.R*255), math.round(CFG.mainColor.G*255), math.round(CFG.mainColor.B*255)}, deflectColor = {math.round(CFG.deflectColor.R*255), math.round(CFG.deflectColor.G*255), math.round(CFG.deflectColor.B*255)} } saveProfileToDisk(name, data) profileInput.Text = "" refreshProfileList() end end) refreshProfileList() end createUI() local function isBallBlocking(startPos, endPos, tableFolder, ignoreLineMirror) if not tableFolder then return false end local ballsFolder = tableFolder:FindFirstChild("Balls") if not ballsFolder then return false end local dir = (endPos - startPos) local dist = dir.Magnitude if dist < 0.5 then return false end local raycastParams = RaycastParams.new() raycastParams.FilterType = Enum.RaycastFilterType.Include local targets = {} for _, obj in ipairs(ballsFolder:GetChildren()) do if obj:IsA("BasePart") and obj ~= ignoreLineMirror then if tonumber(obj.Name) then table.insert(targets, obj) end end end if #targets == 0 then return false end raycastParams.FilterDescendantsInstances = targets local segments = 8 local radius = 0.35 for i = 1, segments do local frac = (i - 1) / (segments - 1) local checkPos = startPos + (dir.Unit * (frac * dist)) local result = ws:Raycast(checkPos, Vector3.new(0, -5, 0), raycastParams) if result and result.Instance then if (result.Instance.Position - checkPos).Magnitude < radius then return true end end end local mainResult = ws:Raycast(startPos, dir, raycastParams) if mainResult and mainResult.Instance then return true end return false end local function calculateBounces3D(start3D, normDir3D, maxDist, tablePart, isDeflectionLine) if not tablePart then return start3D + (normDir3D * maxDist) end local tableCF = tablePart.CFrame local localStart = tableCF:PointToObjectSpace(start3D) local localDir = tableCF:VectorToObjectSpace(normDir3D).Unit local currentPos = localStart local currentDir = localDir local remainingDist = maxDist local maxX = CFG.halfWidth - 0.45 local minX = -maxX local maxZ = CFG.halfLength - 0.45 local minZ = -maxZ local maxLoops = (CFG.bounceLogic and not isDeflectionLine) and 2 or 1 for i = 1, maxLoops do local tX = math.huge local tZ = math.huge if currentDir.X > 0 then tX = (maxX - currentPos.X) / currentDir.X elseif currentDir.X < 0 then tX = (minX - currentPos.X) / currentDir.X end if currentDir.Z > 0 then tZ = (maxZ - currentPos.Z) / currentDir.Z elseif currentDir.Z < 0 then tZ = (minZ - currentPos.Z) / currentDir.Z end local tMin = math.min(tX, tZ) if tMin > 0 and tMin < remainingDist then currentPos = currentPos + currentDir * tMin remainingDist = remainingDist - tMin if not CFG.bounceLogic or isDeflectionLine then remainingDist = 0 break else if tMin == tX then currentDir = Vector3.new(-currentDir.X, currentDir.Y, currentDir.Z) else currentDir = Vector3.new(currentDir.X, currentDir.Y, -currentDir.Z) end end else break end end local finalLocalPos = currentPos + (currentDir * remainingDist) return tableCF:PointToWorldSpace(finalLocalPos) end local function getLinePoints(part) local pos, cf = part.Position, part.CFrame local right = cf.RightVector local halfW = part.Size.X / 2 return pos - right * halfW, pos + right * halfW end local function update3DLinePart(cPart, lineMirrorPart, length, tablePart, tableFolder, alpha, isDeflectionLine, forceColorOverride) if not lineMirrorPart then cPart.Transparency = 1 return nil, nil end local start3D, end3D = getLinePoints(lineMirrorPart) local dir3D = (end3D - start3D) if dir3D.Magnitude < 0.001 then cPart.Transparency = 1 return nil, nil end local final3DTarget = calculateBounces3D(start3D, dir3D.Unit, length, tablePart, isDeflectionLine) if CFG.matchBallHeight and tablePart then final3DTarget = Vector3.new(final3DTarget.X, start3D.Y, final3DTarget.Z) end local distance = (final3DTarget - start3D).Magnitude if distance < 0.01 then cPart.Transparency = 1 return nil, nil end local isBlocked = forceColorOverride or isBallBlocking(start3D, final3DTarget, tableFolder, lineMirrorPart) if isBlocked then local alternatePulse = (math.sin(state.pulsePhase * 2.5) + 1) / 2 cPart.Color = CFG.warnColor:Lerp(Color3.fromRGB(255, 0, 0), alternatePulse) else cPart.Color = isDeflectionLine and CFG.deflectColor or CFG.mainColor end cPart.Size = Vector3.new(distance, 0.06, 0.06) cPart.CFrame = CFrame.lookAt(start3D, final3DTarget) * CFrame.new(0, 0, -distance / 2) * CFrame.Angles(0, math.rad(90), 0) cPart.Transparency = 1 - alpha return final3DTarget, isBlocked end local function cleanup() if container then container:Destroy() end end if _G._trajCleanup then _G._trajCleanup() end _G._trajCleanup = cleanup local function lerp(a, b, t) return a + (b - a) * t end rs.RenderStepped:Connect(function(dt) state.pulsePhase = state.pulsePhase + dt * CFG.pulseSpeed local pulse = (math.sin(state.pulsePhase) + 1) / 2 local liveAlpha = lerp(CFG.pulseMin, CFG.pulseMax, pulse) local tv = ws:FindFirstChild("TrajectoryViz") local poolsModel = ws:FindFirstChild("Pools") local activeFelt = nil local activeTableFolder = nil if poolsModel then local shortestDist = math.huge local lp = Players.LocalPlayer local char = lp and lp.Character local root = char and char:FindFirstChild("HumanoidRootPart") if root then for _, folder in ipairs(poolsModel:GetChildren()) do local felt = folder:FindFirstChild("PoolLevel1") if felt and felt:IsA("BasePart") then local dist = (root.Position - felt.Position).Magnitude if dist < shortestDist and dist < 50 then shortestDist = dist activeFelt = felt activeTableFolder = folder end end end end end if not tv then draw3D.main.Transparency = 1 draw3D.deflect.Transparency = 1 return end local mainHitTarget, mainBlocked = update3DLinePart(draw3D.main, tv:FindFirstChild("TrajHitLine"), CFG.mainExtend, activeFelt, activeTableFolder, liveAlpha, false, false) update3DLinePart(draw3D.deflect, tv:FindFirstChild("TrajDeflectLine"), CFG.deflectExtend, activeFelt, activeTableFolder, liveAlpha, true, mainBlocked) end)