Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Services
- local Players = game:GetService("Players")
- local PathfindingService = game:GetService("PathfindingService")
- local RunService = game:GetService("RunService")
- local TweenService = game:GetService("TweenService")
- local UserInputService = game:GetService("UserInputService")
- -- Player and Character
- local player = Players.LocalPlayer
- local character = player.Character or player.CharacterAdded:Wait()
- local humanoid = character:WaitForChild("Humanoid")
- local rootPart = character:WaitForChild("HumanoidRootPart")
- -- Tool (Classic Sword)
- local tool = character:FindFirstChildOfClass("Tool")
- local handle = tool and tool:FindFirstChild("Handle")
- -- Pathfinding Variables
- local path = PathfindingService:CreatePath({
- AgentRadius = 2,
- AgentHeight = 5,
- AgentCanJump = true
- })
- local waypoints = {}
- local currentWaypointIndex = 1
- local isComputingPath = false
- -- Combat Variables
- local attackRadius = 15 -- Radius within which the bot will attack
- local targetLockRange = 1000 -- Large radius to find and move toward players
- local reactionTime = 0 -- Instant reaction time
- local lastAttackTime = 0
- local attackCooldown = 1.25 -- Attack cooldown
- local comboCooldown = 1.5 -- Cooldown between combos
- local lastComboTime = 0
- -- Void Detection Variables
- local voidCheckRayLength = 50 -- Ray length to check for void below
- local voidThreshold = 0.75 -- 75% of the character must be off the part to trigger void detection
- local autoVoidEnabled = true -- Enable/disable auto-void
- -- Parkour Variables
- local parkourCooldown = 0.5 -- Faster parkour cooldown
- local lastParkourTime = 0
- -- Smooth Movement Variables
- local smoothMoveSpeed = 30 -- Faster movement speed
- local smoothTurnSpeed = 0.05 -- Faster turning speed
- -- Target Variables
- local target = nil
- -- Jumping Variables
- local jumpCooldown = 1 -- Cooldown between jumps
- local lastJumpTime = 0
- -- Player-Like Movement Variables
- local randomMovementDelay = 0.5 -- Delay between random movements
- local lastRandomMovementTime = 0
- -- Combat State Variables
- local isAttacking = false
- local isFeinting = false
- local isDefensive = false
- -- AI Toggle
- local aiEnabled = true
- -- Health Awareness Variables
- local lowHealthThreshold = 0.25 -- 25% health
- local isLowHealth = false
- -- Pattern Recognition Variables
- local playerBehavior = {} -- Stores behavior patterns for each player
- -- Function to create the UI
- local function createUI()
- local screenGui = Instance.new("ScreenGui")
- screenGui.Name = "SwordBotUI"
- screenGui.Parent = player.PlayerGui
- -- Main Frame (Draggable Box)
- local frame = Instance.new("Frame")
- frame.Size = UDim2.new(0, 200, 0, 80) -- 2x the size of the button
- frame.Position = UDim2.new(0.5, -100, 0.5, -40) -- Center of the screen
- frame.BackgroundColor3 = Color3.new(0.2, 0.2, 0.2)
- frame.BorderSizePixel = 0
- frame.Active = true
- frame.Draggable = true
- frame.Parent = screenGui
- -- Label (SWORDBOT)
- local label = Instance.new("TextLabel")
- label.Size = UDim2.new(1, 0, 0.5, 0)
- label.Position = UDim2.new(0, 0, 0, 0)
- label.Text = "SWORDBOT"
- label.TextColor3 = Color3.new(1, 1, 1)
- label.BackgroundTransparency = 1
- label.Font = Enum.Font.SourceSansBold
- label.TextSize = 18
- label.Parent = frame
- -- Toggle Button
- local toggleButton = Instance.new("TextButton")
- toggleButton.Size = UDim2.new(0.8, 0, 0.4, 0)
- toggleButton.Position = UDim2.new(0.1, 0, 0.55, 0)
- toggleButton.Text = "AI: ON"
- toggleButton.TextColor3 = Color3.new(1, 1, 1)
- toggleButton.BackgroundColor3 = Color3.new(0.3, 0.3, 0.3)
- toggleButton.BorderSizePixel = 0
- toggleButton.Parent = frame
- toggleButton.MouseButton1Click:Connect(function()
- aiEnabled = not aiEnabled
- toggleButton.Text = aiEnabled and "AI: ON" or "AI: OFF"
- end)
- return screenGui
- end
- -- Function to equip the first tool in the player's inventory
- local function equipFirstTool()
- local backpack = player:FindFirstChild("Backpack")
- if backpack then
- local firstTool = backpack:FindFirstChildOfClass("Tool")
- if firstTool then
- firstTool.Parent = character
- tool = firstTool
- handle = tool:FindFirstChild("Handle")
- end
- end
- end
- -- Create the UI
- local swordBotUI = createUI()
- -- Ensure UI persists after death
- player.CharacterAdded:Connect(function()
- character = player.Character
- humanoid = character:WaitForChild("Humanoid")
- rootPart = character:WaitForChild("HumanoidRootPart")
- tool = character:FindFirstChildOfClass("Tool")
- handle = tool and tool:FindFirstChild("Handle")
- -- Re-equip the first tool if not already equipped
- if not tool then
- equipFirstTool()
- end
- -- Re-parent the UI to the new PlayerGui
- if swordBotUI then
- swordBotUI.Parent = player.PlayerGui
- end
- end)
- -- Equip the first tool if not already equipped
- if not tool then
- equipFirstTool()
- end
- -- Function to find the nearest opponent within a radius
- local function findNearestOpponent(radius)
- local closest = nil
- local closestDistance = radius or targetLockRange
- for _, otherPlayer in pairs(Players:GetPlayers()) do
- if otherPlayer ~= player and otherPlayer.Character then
- local opponentRoot = otherPlayer.Character:FindFirstChild("HumanoidRootPart")
- if opponentRoot and otherPlayer.Character:FindFirstChild("Humanoid") and otherPlayer.Character.Humanoid.Health > 0 then
- local distance = (opponentRoot.Position - rootPart.Position).Magnitude
- if distance < closestDistance then
- closest = otherPlayer.Character
- closestDistance = distance
- end
- end
- end
- end
- return closest
- end
- -- Function to compute and follow a path
- local function followPath(targetPosition)
- if isComputingPath then return end
- isComputingPath = true
- path:ComputeAsync(rootPart.Position, targetPosition)
- if path.Status == Enum.PathStatus.Success then
- waypoints = path:GetWaypoints()
- currentWaypointIndex = 1
- else
- waypoints = {}
- end
- isComputingPath = false
- end
- -- Function to move smoothly to the next waypoint
- local function moveToNextWaypoint()
- if currentWaypointIndex <= #waypoints then
- local waypoint = waypoints[currentWaypointIndex]
- humanoid:MoveTo(waypoint.Position)
- if waypoint.Action == Enum.PathWaypointAction.Jump then
- humanoid.Jump = true
- end
- -- Smoothly turn toward the waypoint (only horizontally to avoid looking up/down)
- local direction = (Vector3.new(waypoint.Position.X, rootPart.Position.Y, waypoint.Position.Z) - rootPart.Position).Unit
- local goalCFrame = CFrame.new(rootPart.Position, rootPart.Position + direction)
- local tweenInfo = TweenInfo.new(smoothTurnSpeed, Enum.EasingStyle.Linear)
- local tween = TweenService:Create(rootPart, tweenInfo, {CFrame = goalCFrame})
- tween:Play()
- if (rootPart.Position - waypoint.Position).Magnitude < 4 then
- currentWaypointIndex += 1
- end
- end
- end
- -- Function to check if the character is near a void
- local function isNearVoid()
- local rayOrigin = rootPart.Position
- local rayDirection = Vector3.new(0, -voidCheckRayLength, 0)
- local raycastParams = RaycastParams.new()
- raycastParams.FilterDescendantsInstances = {character}
- raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
- local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
- if not raycastResult then
- return true -- No ground detected, assume void
- end
- -- Check if 75% of the character is off the part
- local characterSize = character:GetExtentsSize()
- local characterPosition = rootPart.Position
- local partPosition = raycastResult.Position
- local offPartPercentage = (characterPosition.Y - partPosition.Y) / characterSize.Y
- return offPartPercentage > voidThreshold
- end
- -- Function to check if the bot can safely navigate off an object
- local function canNavigateOffObject()
- local rayOrigin = rootPart.Position
- local rayDirection = rootPart.CFrame.LookVector * 10 -- Check 10 studs ahead
- local raycastParams = RaycastParams.new()
- raycastParams.FilterDescendantsInstances = {character}
- raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
- local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
- if raycastResult then
- -- Check if the surface below is safe (not a void)
- local groundRayOrigin = raycastResult.Position
- local groundRayDirection = Vector3.new(0, -voidCheckRayLength, 0)
- local groundRaycastResult = workspace:Raycast(groundRayOrigin, groundRayDirection, raycastParams)
- if groundRaycastResult then
- -- Check if the part is thin (e.g., a platform that could lead to falling)
- local partSize = raycastResult.Instance.Size
- if partSize.X < 5 or partSize.Z < 5 then -- Thin parts (e.g., narrow platforms)
- return false -- Unsafe to navigate off the object
- end
- return true -- Safe to navigate off the object
- end
- end
- return false -- Cannot safely navigate off the object
- end
- -- Function to perform a basic attack
- local function basicAttack()
- if tool and handle and tick() - lastAttackTime > attackCooldown then
- tool:Activate() -- Simulate left-click (M1)
- lastAttackTime = tick()
- end
- end
- -- Function to perform a combo attack
- local function performCombo()
- if tick() - lastComboTime < comboCooldown then
- return
- end
- -- Example combo: Slash, delay, slash, jump
- basicAttack()
- wait(0.2)
- basicAttack()
- humanoid.Jump = true
- lastComboTime = tick()
- end
- -- Function to feint an attack
- local function feintAttack()
- if isFeinting then return end
- isFeinting = true
- -- Simulate starting an attack but cancel it
- tool:Activate()
- wait(0.1)
- tool:Deactivate()
- isFeinting = false
- end
- -- Function to lock onto the target and face them (only horizontally)
- local function lockOnTarget()
- if target and target:FindFirstChild("HumanoidRootPart") then
- local targetPosition = Vector3.new(target.HumanoidRootPart.Position.X, rootPart.Position.Y, target.HumanoidRootPart.Position.Z)
- local direction = (targetPosition - rootPart.Position).Unit
- local goalCFrame = CFrame.new(rootPart.Position, rootPart.Position + direction)
- local tweenInfo = TweenInfo.new(smoothTurnSpeed, Enum.EasingStyle.Linear)
- local tween = TweenService:Create(rootPart, tweenInfo, {CFrame = goalCFrame})
- tween:Play()
- end
- end
- -- Function to handle combat logic
- local function handleCombat()
- if target and target:FindFirstChild("Humanoid") and target.Humanoid.Health > 0 then
- -- Lock onto the target (only horizontally)
- lockOnTarget()
- -- Attack if in range
- local distance = (target.HumanoidRootPart.Position - rootPart.Position).Magnitude
- if distance < attackRadius then
- -- Randomly choose between basic attack, combo, or feint
- local attackChoice = math.random(1, 3)
- if attackChoice == 1 then
- basicAttack()
- elseif attackChoice == 2 then
- performCombo()
- else
- feintAttack()
- end
- end
- -- Juking: Randomly strafe to make combat more dynamic
- if math.random() < 0.3 then -- 30% chance to juke
- humanoid:MoveTo(rootPart.Position + Vector3.new(math.random(-5, 5), 0, math.random(-5, 5)))
- end
- end
- end
- -- Function to jump to evade attacks or climb objects
- local function jumpToEvadeOrClimb()
- if tick() - lastJumpTime < jumpCooldown then
- return
- end
- -- Jump to evade attacks
- if target and target:FindFirstChild("HumanoidRootPart") then
- local distance = (target.HumanoidRootPart.Position - rootPart.Position).Magnitude
- if distance < attackRadius then
- humanoid.Jump = true
- lastJumpTime = tick()
- end
- end
- -- Jump to climb objects
- local rayOrigin = rootPart.Position
- local rayDirection = rootPart.CFrame.LookVector * 5
- local raycastParams = RaycastParams.new()
- raycastParams.FilterDescendantsInstances = {character}
- raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
- local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
- if raycastResult then
- humanoid.Jump = true
- lastJumpTime = tick()
- end
- end
- -- Function to simulate player-like movement
- local function simulatePlayerMovement()
- if tick() - lastRandomMovementTime > randomMovementDelay then
- -- Randomly strafe or jump to simulate player-like behavior
- if math.random() < 0.5 then
- humanoid:MoveTo(rootPart.Position + Vector3.new(math.random(-5, 5), 0, math.random(-5, 5)))
- else
- humanoid.Jump = true
- end
- lastRandomMovementTime = tick()
- end
- end
- -- Main loop
- RunService.Heartbeat:Connect(function()
- if not aiEnabled then return end -- Stop AI if toggled off
- -- Find the nearest opponent within targetLockRange
- target = findNearestOpponent(targetLockRange)
- if target then
- -- Compute and follow a path to the target
- followPath(target.HumanoidRootPart.Position)
- -- Move to the next waypoint
- moveToNextWaypoint()
- -- Handle combat if within attackRadius
- handleCombat()
- -- Jump to evade attacks or climb objects
- jumpToEvadeOrClimb()
- -- Simulate player-like movement
- simulatePlayerMovement()
- -- Check if near void
- if isNearVoid() and autoVoidEnabled then
- -- Check if the bot can safely navigate off the object
- if canNavigateOffObject() then
- autoVoidEnabled = false -- Disable auto-void temporarily
- else
- -- Avoid falling into the void
- humanoid.Jump = true
- followPath(rootPart.Position - rootPart.CFrame.LookVector * 5) -- Move back
- end
- else
- autoVoidEnabled = true -- Re-enable auto-void
- end
- else
- -- Wander or return to a default position if no target is found
- followPath(Vector3.new(0, 0, 0)) -- Adjust default position as needed
- end
- end)
Advertisement
Advertisement