--========================================================-- -- A-train ability -- R6 + R15 ========================================================-- local Players = game:GetService("Players") local RunService = game:GetService("RunService") local Debris = game:GetService("Debris") local TweenService = game:GetService("TweenService") local Player = Players.LocalPlayer --========================================================-- -- SETTINGS --========================================================-- local TOOL_NAME = "A-train run" local NORMAL_SPEED = 16 local SUPER_SPEED = 110 local ABILITY_TIME = 5 local COOLDOWN = 3 local HIT_RADIUS = 4 local LIGHTNING_INTERVAL = 0.045 local LIGHTNING_LENGTH = 18 local LIGHTNING_POINTS = 12 local LIGHTNING_LIFETIME = 0.16 local SPEED_SOUND_ID = "rbxassetid://18250758551" local EXPLOSION_SOUND_ID = "rbxassetid://138186576" local STREAK_REQUIRED = 2 local STREAK_TIMEOUT = 5 --========================================================-- -- CHARACTER --========================================================-- local Character local Humanoid local Root local function SetupCharacter(Char) Character = Char Humanoid = Char:WaitForChild("Humanoid") Root = Char:WaitForChild("HumanoidRootPart") end if Player.Character then SetupCharacter(Player.Character) end Player.CharacterAdded:Connect(function(Char) SetupCharacter(Char) end) --========================================================-- -- REMOVE OLD TOOL --========================================================-- local function RemoveOldTools() local Backpack = Player:WaitForChild("Backpack") local OldTool = Backpack:FindFirstChild(TOOL_NAME) if OldTool then OldTool:Destroy() end if Character then local EquippedTool = Character:FindFirstChild(TOOL_NAME) if EquippedTool then EquippedTool:Destroy() end end end RemoveOldTools() --========================================================-- -- CREATE TOOL --========================================================-- local Tool = Instance.new("Tool") Tool.Name = TOOL_NAME Tool.RequiresHandle = false Tool.CanBeDropped = false Tool.ToolTip = "Activate super speed" Tool.Parent = Player:WaitForChild("Backpack") --========================================================-- -- VARIABLES --========================================================-- local Active = false local OnCooldown = false local Streak = 0 local AlreadyHit = {} local LightningConnection local HitConnection local ShakeConnection local SpeedSound --========================================================-- -- GUI --========================================================-- local PlayerGui = Player:WaitForChild("PlayerGui") local OldGui = PlayerGui:FindFirstChild("SpeedToolStreakGUI") if OldGui then OldGui:Destroy() end local Gui = Instance.new("ScreenGui") Gui.Name = "SpeedToolStreakGUI" Gui.ResetOnSpawn = false Gui.IgnoreGuiInset = true Gui.DisplayOrder = 999999 Gui.Parent = PlayerGui --========================================================-- -- STREAK BUTTON --========================================================-- local StreakButton = Instance.new("TextButton") StreakButton.Name = "StreakButton" StreakButton.Size = UDim2.new(0, 130, 0, 55) StreakButton.Position = UDim2.new(0, 20, 1, -135) StreakButton.BackgroundColor3 = Color3.fromRGB(25, 25, 35) StreakButton.Text = "STREAK: 0" StreakButton.TextColor3 = Color3.fromRGB(255, 255, 255) StreakButton.TextScaled = true StreakButton.Font = Enum.Font.GothamBold StreakButton.Parent = Gui local StreakCorner = Instance.new("UICorner") StreakCorner.CornerRadius = UDim.new(0, 16) StreakCorner.Parent = StreakButton local StreakStroke = Instance.new("UIStroke") StreakStroke.Thickness = 2 StreakStroke.Color = Color3.fromRGB(0, 170, 255) StreakStroke.Parent = StreakButton --========================================================-- -- STREAK TEXT --========================================================-- local StreakText = Instance.new("TextLabel") StreakText.Name = "StreakText" StreakText.AnchorPoint = Vector2.new(0.5, 0) StreakText.Position = UDim2.new(0.5, 0, 0, 45) StreakText.Size = UDim2.new(0, 500, 0, 90) StreakText.BackgroundTransparency = 1 StreakText.Text = "" StreakText.TextColor3 = Color3.fromRGB(0, 200, 255) StreakText.TextStrokeColor3 = Color3.fromRGB(0, 20, 60) StreakText.TextStrokeTransparency = 0 StreakText.TextScaled = true StreakText.Font = Enum.Font.GothamBlack StreakText.Visible = false StreakText.Parent = Gui --========================================================-- -- STREAK SHAKE --========================================================-- local function StopStreakShake() if ShakeConnection then ShakeConnection:Disconnect() ShakeConnection = nil end end local function StartStreakShake() StopStreakShake() ShakeConnection = RunService.RenderStepped:Connect( function() if not StreakText.Visible then return end local X = math.random(-6, 6) local Y = math.random(-4, 4) StreakText.Position = UDim2.new( 0.5, X, 0, 45 + Y ) end ) end --========================================================-- -- SHOW STREAK --========================================================-- local function ShowStreak() if Streak < STREAK_REQUIRED then return end StreakText.Visible = true StreakText.Text = "STREAK x" .. tostring(Streak) StreakText.TextTransparency = 0 StreakText.TextStrokeTransparency = 0 StartStreakShake() StreakText.Size = UDim2.new(0, 430, 0, 75) local Grow = TweenService:Create( StreakText, TweenInfo.new( 0.15, Enum.EasingStyle.Back, Enum.EasingDirection.Out ), { Size = UDim2.new( 0, 500, 0, 90 ) } ) Grow:Play() end --========================================================-- -- END STREAK --========================================================-- local function EndStreak() Streak = 0 StreakButton.Text = "STREAK: 0" StopStreakShake() local Fade = TweenService:Create( StreakText, TweenInfo.new(0.25), { TextTransparency = 1, TextStrokeTransparency = 1 } ) Fade:Play() Fade.Completed:Connect( function() StreakText.Visible = false StreakText.Text = "" StreakText.TextTransparency = 0 StreakText.TextStrokeTransparency = 0 end ) end --========================================================-- -- NPC CHECK --========================================================-- local function IsNPC(Model) if not Model or not Model:IsA("Model") then return false end local NPC_Humanoid = Model:FindFirstChildOfClass( "Humanoid" ) if not NPC_Humanoid then return false end -- NEVER HIT PLAYERS if Players:GetPlayerFromCharacter(Model) then return false end return NPC_Humanoid.Health > 0 end --========================================================-- -- EXPLOSION --========================================================-- local function ExplosionEffect(Position) local Holder = Instance.new("Part") Holder.Anchored = true Holder.CanCollide = false Holder.CanTouch = false Holder.CanQuery = false Holder.Transparency = 1 Holder.Size = Vector3.new(1, 1, 1) Holder.Position = Position Holder.Parent = workspace -- Sphere local Sphere = Instance.new("Part") Sphere.Shape = Enum.PartType.Ball Sphere.Anchored = true Sphere.CanCollide = false Sphere.CanTouch = false Sphere.CanQuery = false Sphere.Material = Enum.Material.Neon Sphere.Color = Color3.fromRGB( 0, 170, 255 ) Sphere.Transparency = 0.15 Sphere.Size = Vector3.new(1, 1, 1) Sphere.Position = Position Sphere.Parent = Holder local SphereTween = TweenService:Create( Sphere, TweenInfo.new( 0.25, Enum.EasingStyle.Quad, Enum.EasingDirection.Out ), { Size = Vector3.new( 9, 9, 9 ), Transparency = 1 } ) SphereTween:Play() -- Ring local Ring = Instance.new("Part") Ring.Shape = Enum.PartType.Cylinder Ring.Anchored = true Ring.CanCollide = false Ring.CanTouch = false Ring.CanQuery = false Ring.Material = Enum.Material.Neon Ring.Color = Color3.fromRGB( 0, 100, 255 ) Ring.Transparency = 0.1 Ring.Size = Vector3.new( 0.15, 2, 2 ) Ring.CFrame = CFrame.new(Position) * CFrame.Angles( 0, 0, math.rad(90) ) Ring.Parent = Holder local RingTween = TweenService:Create( Ring, TweenInfo.new( 0.3, Enum.EasingStyle.Quad, Enum.EasingDirection.Out ), { Size = Vector3.new( 0.15, 8, 8 ), Transparency = 1 } ) RingTween:Play() -- Sound local Sound = Instance.new("Sound") Sound.SoundId = EXPLOSION_SOUND_ID Sound.Volume = 1 Sound.Parent = Holder Sound:Play() Debris:AddItem( Holder, 0.5 ) end --========================================================-- -- SPEED HIT SOUND --========================================================-- local function PlayHitSound() if not Root or not Root.Parent then return end local Sound = Instance.new("Sound") Sound.Name = "SpeedHitSound" Sound.SoundId = SPEED_SOUND_ID Sound.Volume = 0.8 Sound.PlaybackSpeed = 1 Sound.Looped = false Sound.Parent = Root Sound:Play() Debris:AddItem( Sound, 5 ) end --========================================================-- -- REGISTER KILL --========================================================-- local function RegisterKill(NPC) if not NPC then return end if AlreadyHit[NPC] then return end AlreadyHit[NPC] = true Streak += 1 StreakButton.Text = "STREAK: " .. tostring(Streak) if Streak >= STREAK_REQUIRED then ShowStreak() end local CurrentStreak = Streak task.delay( STREAK_TIMEOUT, function() if Streak == CurrentStreak then EndStreak() end end ) --====================================================-- -- HIT NPC = RESET COOLDOWN --====================================================-- OnCooldown = false --====================================================-- -- HIT NPC = PLAY SOUND AGAIN --====================================================-- PlayHitSound() end --========================================================-- -- LIGHTNING --========================================================-- local function GenerateLightningLine() if not Root or not Root.Parent then return end local Folder = Instance.new("Folder") Folder.Name = "LightningLine" Folder.Parent = workspace local Anchor = Instance.new("Part") Anchor.Name = "LightningAnchor" Anchor.Anchored = true Anchor.CanCollide = false Anchor.CanTouch = false Anchor.CanQuery = false Anchor.Transparency = 1 Anchor.Size = Vector3.new( 0.1, 0.1, 0.1 ) Anchor.CFrame = Root.CFrame Anchor.Parent = Folder local Attachments = {} for i = 1, LIGHTNING_POINTS do local Attachment = Instance.new("Attachment") local Alpha = (i - 1) / (LIGHTNING_POINTS - 1) local Z = Alpha * LIGHTNING_LENGTH Attachment.Position = Vector3.new( math.random(-20, 20) / 10, math.random(-15, 15) / 10, Z ) Attachment.Parent = Anchor table.insert( Attachments, Attachment ) end for i = 1, #Attachments - 1 do local Beam = Instance.new("Beam") Beam.Attachment0 = Attachments[i] Beam.Attachment1 = Attachments[i + 1] Beam.FaceCamera = true Beam.Width0 = 0.14 Beam.Width1 = 0.04 Beam.LightEmission = 1 Beam.LightInfluence = 0 Beam.Color = ColorSequence.new( Color3.fromRGB( 0, 120, 255 ), Color3.fromRGB( 0, 220, 255 ) ) Beam.Transparency = NumberSequence.new({ NumberSequenceKeypoint.new( 0, 0 ), NumberSequenceKeypoint.new( 0.8, 0.1 ), NumberSequenceKeypoint.new( 1, 1 ) }) Beam.Parent = Anchor end local Glow = Instance.new("PointLight") Glow.Color = Color3.fromRGB( 0, 150, 255 ) Glow.Brightness = 2 Glow.Range = 7 Glow.Parent = Anchor Debris:AddItem( Folder, LIGHTNING_LIFETIME ) end --========================================================-- -- START LIGHTNING --========================================================-- local function StartLightning() if LightningConnection then LightningConnection:Disconnect() end local Last = 0 LightningConnection = RunService.RenderStepped:Connect( function() if not Active then return end if not Root or not Root.Parent then return end local Now = os.clock() if Now - Last >= LIGHTNING_INTERVAL then Last = Now GenerateLightningLine() end end ) end --========================================================-- -- STOP LIGHTNING --========================================================-- local function StopLightning() if LightningConnection then LightningConnection:Disconnect() LightningConnection = nil end end --========================================================-- -- NPC HIT DETECTION --========================================================-- local function StartHitDetection() if HitConnection then HitConnection:Disconnect() end HitConnection = RunService.Heartbeat:Connect( function() if not Active then return end if not Root or not Root.Parent then return end local Params = OverlapParams.new() Params.FilterType = Enum.RaycastFilterType.Exclude Params.FilterDescendantsInstances = {Character} local Parts = workspace:GetPartBoundsInRadius( Root.Position, HIT_RADIUS, Params ) local Checked = {} for _, Part in ipairs(Parts) do local Model = Part:FindFirstAncestorOfClass( "Model" ) if Model and not Checked[Model] then Checked[Model] = true if IsNPC(Model) and not AlreadyHit[Model] then local NPC_Humanoid = Model:FindFirstChildOfClass( "Humanoid" ) if NPC_Humanoid and NPC_Humanoid.Health > 0 then -- Kill NPC NPC_Humanoid.Health = 0 -- Explosion local NPC_Root = Model:FindFirstChild( "HumanoidRootPart" ) or Model.PrimaryPart if NPC_Root then ExplosionEffect( NPC_Root.Position ) end RegisterKill(Model) end end end end end ) end --========================================================-- -- STOP HIT DETECTION --========================================================-- local function StopHitDetection() if HitConnection then HitConnection:Disconnect() HitConnection = nil end end --========================================================-- -- CREATE MAIN SOUND --========================================================-- local function CreateSpeedSound() if not Root then return end if SpeedSound then SpeedSound:Destroy() end SpeedSound = Instance.new("Sound") SpeedSound.Name = "SuperSpeedSound" SpeedSound.SoundId = SPEED_SOUND_ID SpeedSound.Volume = 0.8 SpeedSound.PlaybackSpeed = 1 SpeedSound.Looped = false SpeedSound.Parent = Root end --========================================================-- -- ACTIVATE SPEED --========================================================-- local function ActivateSpeed() if Active then return end if OnCooldown then return end if not Character or not Humanoid or not Root then return end if Humanoid.Health <= 0 then return end Active = true OnCooldown = true AlreadyHit = {} Humanoid.WalkSpeed = SUPER_SPEED CreateSpeedSound() if SpeedSound then SpeedSound:Play() end StartLightning() StartHitDetection() task.delay( ABILITY_TIME, function() if not Active then return end Active = false if Humanoid and Humanoid.Parent then Humanoid.WalkSpeed = NORMAL_SPEED end StopLightning() StopHitDetection() if SpeedSound then SpeedSound:Stop() SpeedSound:Destroy() SpeedSound = nil end -- If an NPC was NOT hit, -- normal cooldown happens. if OnCooldown then task.delay( COOLDOWN, function() OnCooldown = false end ) end end ) end --========================================================-- -- TOOL ACTIVATED --========================================================-- Tool.Activated:Connect(function() ActivateSpeed() end) --========================================================-- -- TOOL EQUIPPED --========================================================-- Tool.Equipped:Connect(function() -- Make sure the GUI exists Gui.Enabled = true end) --========================================================-- -- TOOL UNEQUIPPED --========================================================-- Tool.Unequipped:Connect(function() -- Keep streak UI visible -- even when the tool is unequipped. Gui.Enabled = true end) --========================================================-- -- STREAK BUTTON --========================================================-- StreakButton.Activated:Connect(function() if Streak >= STREAK_REQUIRED then ShowStreak() else StreakButton.Text = "NEED 2 KILLS" task.delay( 1, function() if StreakButton and Streak < STREAK_REQUIRED then StreakButton.Text = "STREAK: " .. tostring(Streak) end end ) end end) --========================================================-- -- RESPAWN --========================================================-- Player.CharacterAdded:Connect( function(NewCharacter) SetupCharacter(NewCharacter) Active = false OnCooldown = false Streak = 0 AlreadyHit = {} StopLightning() StopHitDetection() StopStreakShake() if SpeedSound then SpeedSound:Destroy() SpeedSound = nil end StreakButton.Text = "STREAK: 0" StreakText.Visible = false StreakText.Text = "" -- Recreate tool if Roblox removed it task.wait(0.2) if not Tool.Parent then Tool.Parent = Player:WaitForChild( "Backpack" ) end end ) print( "⚡ SPEED SUPERPOWER TOOL CREATED!" ) print( "⚡ STREAK UI ACTIVE!" )