loadstring([[ if getgenv().ThorBallLoaded then if game.CoreGui:FindFirstChild("ThorBallGui") then game.CoreGui.ThorBallGui:Destroy() end if workspace:FindFirstChild("ThorBall_Thrown") then workspace.ThorBall_Thrown:Destroy() end end getgenv().ThorBallLoaded = true getgenv().SelectedBallType = getgenv().SelectedBallType or "Light" local Players = game:GetService("Players") local TweenService = game:GetService("TweenService") local RunService = game:GetService("RunService") local Debris = game:GetService("Debris") local player = Players.LocalPlayer local thrownBall, isReturning, floatConn, lastSpeed = nil, false, nil, 70 local BallTypes = { Light = {Color=Color3.fromRGB(255,255,0), Material=Enum.Material.Neon, Speed=160, Trail=Color3.fromRGB(255,255,150), Name="LIGHT [KIZARU]", SoundThrow="rbxassetid://12222025", SoundHit="rbxassetid://12222030", LightColor=Color3.fromRGB(255,255,100)}, Thor = {Color=Color3.fromRGB(255,0,0), Material=Enum.Material.Neon, Speed=70, Trail=Color3.fromRGB(255,0,0), Name="THOR", SoundThrow="rbxassetid://12222124", SoundHit="rbxassetid://12222216", LightColor=Color3.fromRGB(255,0,0)}, Flame = {Color=Color3.fromRGB(255,85,0), Material=Enum.Material.Neon, Speed=70, Trail=Color3.fromRGB(255,100,0), Name="FLAME", SoundThrow="rbxassetid://12222058", SoundHit="rbxassetid://12222116", LightColor=Color3.fromRGB(255,85,0)}, Lightning = {Color=Color3.fromRGB(0,200,255), Material=Enum.Material.ForceField, Speed=130, Trail=Color3.fromRGB(0,255,255), Name="LIGHTNING", SoundThrow="rbxassetid://12222086", SoundHit="rbxassetid://12222121", LightColor=Color3.fromRGB(0,200,255)}, Ice = {Color=Color3.fromRGB(100,200,255), Material=Enum.Material.Ice, Speed=60, Trail=Color3.fromRGB(150,220,255), Name="ICE", SoundThrow="rbxassetid://12221976", SoundHit="rbxassetid://12222066", LightColor=Color3.fromRGB(100,200,255)}, Magma = {Color=Color3.fromRGB(120,20,0), Material=Enum.Material.Slate, Speed=60, Trail=Color3.fromRGB(255,80,0), Name="MAGMA [AKAINU]", SoundThrow="rbxassetid://12222101", SoundHit="rbxassetid://12222106", LightColor=Color3.fromRGB(255,60,0)}, Galaxy = {Color=Color3.fromRGB(120,0,255), Material=Enum.Material.ForceField, Speed=75, Trail=Color3.fromRGB(180,0,255), Name="GALAXY", SoundThrow="rbxassetid://12222008", SoundHit="rbxassetid://12222045", LightColor=Color3.fromRGB(120,0,255)}, Blackhole = {Color=Color3.fromRGB(0,0,0), Material=Enum.Material.ForceField, Speed=60, Trail=Color3.fromRGB(80,0,130), Name="BLACKHOLE", SoundThrow="rbxassetid://12222009", SoundHit="rbxassetid://12222111", LightColor=Color3.fromRGB(50,0,100)}, Dragon = {Color=Color3.fromRGB(255,140,0), Material=Enum.Material.Neon, Speed=90, Trail=Color3.fromRGB(255,200,0), Name="DRAGON BALL", SoundThrow="rbxassetid://12222065", SoundHit="rbxassetid://12222212", LightColor=Color3.fromRGB(255,140,0)}, } local gui = Instance.new("ScreenGui") gui.Name = "ThorBallGui" gui.ResetOnSpawn = false gui.Parent = (gethui and gethui() or game.CoreGui) local function makeCircleButton(name, text, pos, color, size) local b = Instance.new("TextButton") b.Name = name b.Size = size or UDim2.new(0,65,0,65) b.Position = pos b.Text = text b.TextScaled = true b.Font = Enum.Font.GothamBold b.TextColor3 = Color3.new(1,1,1) b.BackgroundColor3 = color b.Parent = gui Instance.new("UICorner", b).CornerRadius = UDim.new(1,0) local s = Instance.new("UIStroke", b) s.Thickness = 2 s.Color = Color3.new(1,1,1) return b end local ballBtn = makeCircleButton("BallBtn", "BALL", UDim2.new(0,15,0,15), Color3.fromRGB(255,50,50)) local returnBtn = makeCircleButton("ReturnBtn", "RETURN", UDim2.new(0,15,0,90), Color3.fromRGB(50,150,255)) -- NEW TOP RIGHT TOGGLE BUTTON (only shows when holding ball) local changeBtn = makeCircleButton("ChangeBtn", "CHANGE", UDim2.new(1,-80,0,15), Color3.fromRGB(0,0,0), UDim2.new(0,65,0,65)) changeBtn.Visible = false changeBtn.TextSize = 10 -- SELECTOR UI local selectorFrame = Instance.new("Frame") selectorFrame.Size = UDim2.new(0, 240, 0, 340) selectorFrame.Position = UDim2.new(0.5, -120, 0.5, -170) selectorFrame.BackgroundColor3 = Color3.fromRGB(15,15,15) selectorFrame.Visible = false selectorFrame.Parent = gui Instance.new("UICorner", selectorFrame).CornerRadius = UDim.new(0,12) local stroke = Instance.new("UIStroke", selectorFrame) stroke.Color = Color3.fromRGB(255,255,255) stroke.Thickness = 2 local title = Instance.new("TextLabel", selectorFrame) title.Size = UDim2.new(1,0,0,30) title.Text = "SELECTED: "..BallTypes[getgenv().SelectedBallType].Name title.TextScaled = true title.Font = Enum.Font.GothamBold title.TextColor3 = Color3.new(1,1,1) title.BackgroundTransparency = 1 local scroll = Instance.new("ScrollingFrame", selectorFrame) scroll.Size = UDim2.new(1, -10, 1, -40) scroll.Position = UDim2.new(0,5,0,35) scroll.BackgroundTransparency = 1 scroll.ScrollBarThickness = 3 scroll.AutomaticCanvasSize = Enum.AutomaticSize.Y local layout = Instance.new("UIGridLayout", scroll) layout.CellSize = UDim2.new(0,105,0,45) layout.CellPadding = UDim2.new(0,10,0,10) for typeName, data in pairs(BallTypes) do local btn = Instance.new("TextButton") btn.Text = data.Name btn.Font = Enum.Font.GothamBold btn.TextScaled = true btn.TextSize = 11 btn.TextColor3 = Color3.new(1,1,1) btn.BackgroundColor3 = data.Color btn.Parent = scroll Instance.new("UICorner", btn).CornerRadius = UDim.new(0,8) btn.MouseButton1Click:Connect(function() getgenv().SelectedBallType = typeName title.Text = "SELECTED: "..data.Name lastSpeed = data.Speed local char = player.Character if char and char:FindFirstChild("ThorBall") and char.ThorBall:FindFirstChild("Handle") then char.ThorBall.Handle.Color = data.Color char.ThorBall.Handle.Material = data.Material end if thrownBall then thrownBall.Color = data.Color thrownBall.Material = data.Material local light = thrownBall:FindFirstChildOfClass("PointLight") if light then light.Color = data.LightColor end end end) end changeBtn.MouseButton1Click:Connect(function() selectorFrame.Visible = not selectorFrame.Visible end) local function playSound(id, parent, volume) local s = Instance.new("Sound") s.SoundId = id s.Volume = volume or 2 s.Parent = parent s:Play() Debris:AddItem(s, 4) end local function addBallVFX(ball, typeName) local data = BallTypes[typeName] local light = Instance.new("PointLight", ball) light.Color = data.LightColor light.Range = 15 light.Brightness = 3 light.Shadows = true if typeName == "Flame" then local f = Instance.new("Fire", ball) f.Size=12 f.Heat=10 local sm = Instance.new("Smoke", ball) sm.Color=Color3.fromRGB(255,100,0) sm.RiseVelocity=2 sm.Size=5 elseif typeName == "Light" then local pe = Instance.new("ParticleEmitter", ball) pe.Texture="rbxassetid://1084965043" pe.Color=ColorSequence.new(Color3.fromRGB(255,255,150)) pe.Lifetime=NumberRange.new(0.5) pe.Rate=150 pe.Speed=NumberRange.new(5) pe.Size=NumberSequence.new({NumberSequenceKeypoint.new(0,1), NumberSequenceKeypoint.new(1,0)}) elseif typeName == "Lightning" then local pe = Instance.new("ParticleEmitter", ball) pe.Texture="rbxassetid://241650881" pe.Color=ColorSequence.new(Color3.fromRGB(0,255,255)) pe.Lifetime=NumberRange.new(0.3) pe.Rate=200 pe.Speed=NumberRange.new(0) elseif typeName == "Magma" then Instance.new("Fire", ball).Size=15 local sm = Instance.new("Smoke", ball) sm.Color=Color3.fromRGB(50,10,0) sm.Size=8 elseif typeName == "Galaxy" or typeName=="Blackhole" or typeName=="Dragon" then local pe = Instance.new("ParticleEmitter", ball) pe.Texture="rbxassetid://1095708" pe.Color=ColorSequence.new(data.LightColor) pe.Lifetime=NumberRange.new(1) pe.Rate=100 pe.Speed=NumberRange.new(3) end end local function applyEffect(pos, model, ballType) if not model or not model:FindFirstChild("Humanoid") then return end if Players:GetPlayerFromCharacter(model) or model == player.Character then return end local data = BallTypes[ballType] if ballType == "Light" then playSound(data.SoundHit, model.HumanoidRootPart, 3) for _,v in pairs(model:GetDescendants()) do if v:IsA("BasePart") then TweenService:Create(v, TweenInfo.new(0.3), {Color=Color3.fromRGB(255,255,150), Material=Enum.Material.Neon}):Play() local hl=Instance.new("Highlight", v) hl.FillColor=Color3.fromRGB(255,255,0) hl.FillTransparency=0.2 end end task.wait(0.6) for _,v in pairs(model:GetDescendants()) do if v:IsA("BasePart") then TweenService:Create(v, TweenInfo.new(1), {Transparency=1}):Play() end end task.wait(1) model:Destroy() elseif ballType == "Ice" then playSound(data.SoundHit, model.HumanoidRootPart, 3) for _,v in pairs(model:GetDescendants()) do if v:IsA("BasePart") then v.Anchored=true v.Color=Color3.fromRGB(100,200,255) v.Material=Enum.Material.Ice end end task.wait(1.5) model.Humanoid.Health=0 elseif ballType == "Blackhole" then playSound(data.SoundHit, workspace, 5) local hole=Instance.new("Part",workspace) hole.Anchored=true hole.CanCollide=false hole.Shape=Enum.PartType.Ball hole.Size=Vector3.new(1,1,1) hole.CFrame=CFrame.new(pos) hole.Color=Color3.fromRGB(0,0,0) hole.Material=Enum.Material.ForceField TweenService:Create(hole, TweenInfo.new(1), {Size=Vector3.new(20,20,20)}):Play() for _,v in pairs(workspace:GetPartBoundsInRadius(pos,30)) do local m=v.Parent if m and m:FindFirstChild("Humanoid") and not Players:GetPlayerFromCharacter(m) and m~=player.Character then local hrp=m:FindFirstChild("HumanoidRootPart") if hrp then TweenService:Create(hrp,TweenInfo.new(0.8),{CFrame=CFrame.new(pos)}):Play() task.delay(0.9,function() if m.Parent then m.Humanoid.Health=0 end end) end end end Debris:AddItem(hole,2) else playSound(data.SoundHit, model.HumanoidRootPart, 3) local exp=Instance.new("Explosion",workspace) exp.BlastRadius=14 exp.BlastPressure=0 exp.Position=pos exp.DestroyJointRadiusPercent=0 model.Humanoid.Health=0 end end local function createTool() if player.Backpack:FindFirstChild("ThorBall") or (player.Character and player.Character:FindFirstChild("ThorBall")) then return end local tool = Instance.new("Tool") tool.Name = "ThorBall" tool.RequiresHandle = true tool.CanBeDropped = false local handle = Instance.new("Part") handle.Name = "Handle" handle.Shape = Enum.PartType.Ball handle.Size = Vector3.new(2.8,2.8,2.8) handle.Color = BallTypes[getgenv().SelectedBallType].Color handle.Material = BallTypes[getgenv().SelectedBallType].Material handle.CanCollide = false handle.Massless = true handle.Parent = tool Instance.new("SpecialMesh", handle).MeshType = Enum.MeshType.Sphere tool.Parent = player.Backpack tool.Equipped:Connect(function() changeBtn.Visible = true end) tool.Unequipped:Connect(function() changeBtn.Visible = false selectorFrame.Visible = false end) end local function makeFloat(ball) local att = Instance.new("Attachment", ball) local force = Instance.new("VectorForce", ball) force.Attachment0 = att force.Force = Vector3.new(0, ball:GetMass() * workspace.Gravity, 0) force.RelativeTo = Enum.ActuatorRelativeTo.World force.Parent = ball ball.AssemblyAngularVelocity = Vector3.new(0,5,0) if floatConn then floatConn:Disconnect() end -- NO SLOW DOWN FLOAT, keep Y level floatConn = RunService.Heartbeat:Connect(function() if not ball or not ball.Parent or isReturning then return end -- keep same Y, no drop local vel = ball.AssemblyLinearVelocity -- only correct Y, keep X,Z speed same if math.abs(vel.Y) > 1 then ball.AssemblyLinearVelocity = Vector3.new(vel.X, vel.Y * 0.99, vel.Z) else ball.AssemblyLinearVelocity = Vector3.new(vel.X, 0, vel.Z) end -- enforce constant speed if ball.AssemblyLinearVelocity.Magnitude < lastSpeed - 5 then ball.AssemblyLinearVelocity = ball.AssemblyLinearVelocity.Unit * lastSpeed end end) end local function throwBall() local char = player.Character if not char or not char:FindFirstChild("HumanoidRootPart") then return end if thrownBall then thrownBall:Destroy() end if floatConn then floatConn:Disconnect() end if char:FindFirstChild("ThorBall") then char.ThorBall.Handle.Transparency = 1 end local typeData = BallTypes[getgenv().SelectedBallType] lastSpeed = typeData.Speed local ball = Instance.new("Part") ball.Name = "ThorBall_Thrown" ball.Shape = Enum.PartType.Ball ball.Size = Vector3.new(3.2,3.2,3.2) ball.Color = typeData.Color ball.Material = typeData.Material ball.CanCollide = true ball.CustomPhysicalProperties = PhysicalProperties.new(0.1, 1, 0, 1, 1) -- Elasticity 1 = NO SLOW DOWN ball.CFrame = char.HumanoidRootPart.CFrame * CFrame.new(0,1.5,-4) ball.AssemblyLinearVelocity = char.HumanoidRootPart.CFrame.LookVector * typeData.Speed ball.Parent = workspace thrownBall = ball makeFloat(ball) addBallVFX(ball, getgenv().SelectedBallType) playSound(typeData.SoundThrow, ball, 2) local trail = Instance.new("Trail", ball) trail.Attachment0 = Instance.new("Attachment", ball) trail.Attachment1 = Instance.new("Attachment", ball) trail.Attachment1.Position = Vector3.new(0,0.5,0) trail.Color = ColorSequence.new(typeData.Trail) trail.Lifetime = 0.7 local debounce=false ball.Touched:Connect(function(hit) if isReturning or not hit then return end if hit:IsDescendantOf(char) then return end local model=hit.Parent -- DAMAGE CHECK FIRST if model:FindFirstChild("Humanoid") and not Players:GetPlayerFromCharacter(model) then if debounce then return end debounce=true local expl=Instance.new("Explosion",workspace) expl.BlastRadius=8 expl.BlastPressure=0 expl.Position=ball.Position expl.DestroyJointRadiusPercent=0 applyEffect(ball.Position, model, getgenv().SelectedBallType) if floatConn then floatConn:Disconnect() end ball:Destroy() thrownBall=nil if char:FindFirstChild("ThorBall") then char.ThorBall.Handle.Transparency=0 end return end -- BOUNCE WITH NO SLOW DOWN if not debounce then local normal = (ball.Position - hit.Position).Unit local vel = ball.AssemblyLinearVelocity local dot = vel:Dot(normal) local reflected = vel - (2 * dot * normal) -- KEEP SAME SPEED ball.AssemblyLinearVelocity = reflected.Unit * lastSpeed playSound("rbxassetid://12222030", ball, 1) end end) Debris:AddItem(ball, 30) end local function returnBall() if not thrownBall or isReturning then return end isReturning=true if floatConn then floatConn:Disconnect() end playSound("rbxassetid://12222124", thrownBall, 3) thrownBall.CanCollide=false thrownBall.Anchored=true local char=player.Character if not char or not char:FindFirstChild("HumanoidRootPart") then isReturning=false return end local tween=TweenService:Create(thrownBall, TweenInfo.new(0.35, Enum.EasingStyle.Quad), {CFrame=char.HumanoidRootPart.CFrame*CFrame.new(0,1.5,-4)}) tween:Play() tween.Completed:Wait() if thrownBall then thrownBall:Destroy() thrownBall=nil end if char:FindFirstChild("ThorBall") then char.ThorBall.Handle.Transparency=0 end isReturning=false end ballBtn.MouseButton1Click:Connect(createTool) returnBtn.MouseButton1Click:Connect(returnBall) RunService.Heartbeat:Connect(function() local char=player.Character if not char then return end local t=char:FindFirstChild("ThorBall") if t and not t:FindFirstChild("ActivatedConn") then local c=Instance.new("BoolValue", t) c.Name="ActivatedConn" t.Activated:Connect(function() if not thrownBall then throwBall() end end) end end) createTool() ]])()