--made by epiccooldude and auzer (advanced version)
local runService = game:GetService("RunService")
local userInputService = game:GetService("UserInputService")
local player = game.Players.LocalPlayer
local enabled = false
local c = {}
local playerObjects = {}
local punchTool, yeetTool
local leftSwingAnimId = "rbxassetid://7218622714"
local rightSwingAnimId = "rbxassetid://7218624486"
local aggroOffsetMultiplier = 1.5
local defOffsetMultiplier = 10
local attackRange = 66 -- Set the attack range to 66 units
local retreatDistance = 10 -- Distance used for dodging
-- New variables:
local minDistance = 30 -- Bot will not retreat if closer than 30 units
local hitDelay = 0.6 -- Delay (in seconds) from attack animation start to hit
-- Advanced field: how much earlier to lead our attack if enemy is moving fast.
-- This value will be computed adaptively.
local maxLeadTime = 0.3
local playerDataClass = {
char = nil,
humanoidRootPart = nil,
humanoid = nil,
bodyGyro = nil,
alive = false,
player = nil,
attackDirection = "None",
focusPart = nil,
offsetMultiplier = aggroOffsetMultiplier,
c = {},
-- Field to store when an attack animation started:
lastAttackStartTime = nil,
}
local playerData
local targetData
local active = true
local runtime = { states = {} }
local function CopyTable(target, destination, references)
references = references or {}
local copy = destination and CopyTable(destination) or {}
references[target] = copy
for k, v in pairs(target) do
if type(v) == "table" then
copy[k] = references[v] or CopyTable(v, nil, references)
else
copy[k] = v
end
end
return copy
end
function playerDataClass:GetPosition()
return self.humanoidRootPart.Position
end
function playerDataClass:GetCFrame()
return self.humanoidRootPart.CFrame
end
function playerDataClass:GetDistance(point)
return (self:GetPosition() - point).Magnitude
end
-- Always face the enemy.
function playerDataClass:LookAt(point, aimFocus)
self.bodyGyro.CFrame = CFrame.new(aimFocus and self:GetFocusPoint() or self:GetPosition(), point)
end
function playerDataClass:new(player)
self = CopyTable(self)
self.player = player
if player.Character then
self:OnCharacterAdded(player.Character)
end
c[#c + 1] = player.CharacterAdded:Connect(function(char)
self:OnCharacterAdded(char)
end)
playerObjects[player] = self
return self
end
function playerDataClass:remove()
for _, connection in ipairs(self.c) do
connection:Disconnect()
end
if self.bodyGyro then
self.bodyGyro:Destroy()
end
end
function playerDataClass:OnToolAdded(instance)
if not instance:IsA("Tool") then
return
end
if instance.Name == "Yeet" then
yeetTool = instance
elseif instance.Name == "Punch" then
punchTool = instance
end
end
function playerDataClass:UpdateFocus(point)
local bodyParts = {self.leftHand, self.rightHand, self.humanoidRootPart}
local closestData = { distance = math.huge }
for _, part in ipairs(bodyParts) do
local distance = (point - part.Position).Magnitude
if distance < closestData.distance then
closestData.part = part
closestData.distance = distance
end
end
self.focusPart = closestData.part
end
function playerDataClass:UpdateAnimations()
-- Check playing animations and record when an attack started.
for _, instance in ipairs(self.animator:GetPlayingAnimationTracks()) do
if instance.Animation.AnimationId == leftSwingAnimId or instance.Animation.AnimationId == rightSwingAnimId then
self.attackDirection = (instance.Animation.AnimationId == leftSwingAnimId and "Left") or (instance.Animation.AnimationId == rightSwingAnimId and "Right")
self.offsetMultiplier = defOffsetMultiplier
self.lastAttackStartTime = tick() -- Record attack start time
return
end
end
self.attackDirection = "None"
self.offsetMultiplier = aggroOffsetMultiplier
end
function playerDataClass:GetFocusPoint()
return self.focusPart.Position
end
function playerDataClass:OnCharacterAdded(char)
self.char = char
self.humanoidRootPart = self.char:FindFirstChild("HumanoidRootPart")
self.humanoid = self.char:FindFirstChild("Humanoid")
self.animator = self.humanoid:WaitForChild("Animator")
self.leftHand = self.char:WaitForChild("LeftHand")
self.rightHand = self.char:WaitForChild("RightHand")
self.focusPart = self.humanoidRootPart
if self.player == game.Players.LocalPlayer then
self.bodyGyro = Instance.new("BodyGyro")
self.bodyGyro.P = 0
self.bodyGyro.D = 100
self.bodyGyro.MaxTorque = Vector3.new(0, 10000000, 0)
self.bodyGyro.Parent = self.humanoidRootPart
c[#c + 1] = char.ChildAdded:Connect(function(child)
self:OnToolAdded(child)
end)
self:OnToolAdded(self.char:FindFirstChildOfClass("Tool") or workspace)
c[#c + 1] = self.humanoid.Died:Connect(function()
self.alive = false
end)
end
self.alive = true
end
playerData = CopyTable(playerDataClass)
local function errorHandler(err)
warn(err .. "\n" .. debug.traceback())
end
function runtime:DisableState(stateName)
runtime.states[stateName].active = false
while runtime.states[stateName].tasks ~= 0 do
task.wait()
end
end
function runtime:DisableStates()
for stateName, state in pairs(runtime.states) do
if stateName ~= "Default" and state.active then
runtime:DisableState(stateName)
end
end
end
function runtime:EnableState(stateName)
if runtime.states[stateName].active then
return
end
local state = runtime.states[stateName]
local dt = 0
state.tasks = 0
state.active = true
for _, func in pairs(state.functions) do
state.tasks = state.tasks + 1
task.spawn(function()
while active and state.active do
dt = runService.Heartbeat:Wait()
xpcall(function() func(state, dt) end, errorHandler)
end
state.tasks = state.tasks - 1
end)
end
end
function runtime:SwitchState(stateName)
runtime:DisableStates()
runtime:EnableState(stateName)
end
function runtime:NewState(stateName)
local data = { functions = {}, tasks = 0, active = false }
runtime.states[stateName] = data
return data
end
runtime:NewState("Default")
runtime:NewState("Attack")
local function ScanPlayers()
local closestPlayerData = { distance = math.huge }
for _, targetPlayer in ipairs(game.Players:GetChildren()) do
if targetPlayer == game.Players.LocalPlayer then continue end
local targetChar = targetPlayer.Character
if not targetChar then continue end
local humanoidRootPart = targetChar:FindFirstChild("HumanoidRootPart")
local humanoid = targetChar:FindFirstChild("Humanoid")
if not humanoidRootPart or not humanoid or humanoid.Health == 0
or humanoidRootPart.AssemblyMass < playerData.humanoidRootPart.AssemblyMass - 70000 then
continue
end
local distance = playerData:GetDistance(humanoidRootPart.Position)
if distance < closestPlayerData.distance then
closestPlayerData = { distance = distance, player = targetPlayer }
end
end
if closestPlayerData.player then
targetData = playerObjects[closestPlayerData.player]
targetData:UpdateAnimations()
targetData:UpdateFocus(playerData.focusPart.Position)
playerData:UpdateFocus(targetData.humanoidRootPart.Position)
else
if targetData then targetData:remove() end
targetData = nil
end
task.wait(0.1)
end
local function TrackCharacters()
if not targetData or not targetData.alive then
if playerData.bodyGyro then playerData.bodyGyro.P = 0 end
return
end
playerData.bodyGyro.P = 1000000
local playerPos = playerData:GetFocusPoint()
local targetPos = targetData:GetFocusPoint()
-- Force facing: always look at enemy's position.
playerData:LookAt(targetPos, true)
local currentTime = tick()
local xz = Vector3.new(1, 0, 1)
-- Advanced dodge: if enemy is attacking (pre-hit phase) and moving fast, dodge more aggressively.
if targetData.lastAttackStartTime and (currentTime - targetData.lastAttackStartTime) < hitDelay then
local dodgeDir
if targetData.attackDirection == "Left" then
dodgeDir = targetData:GetCFrame().rightVector
elseif targetData.attackDirection == "Right" then
dodgeDir = -targetData:GetCFrame().rightVector
else
dodgeDir = playerData:GetCFrame().rightVector
end
playerData.humanoid:MoveTo(playerPos + dodgeDir * retreatDistance)
return
end
local lookVector = (targetPos - (targetData:GetCFrame() * CFrame.new(1, 0, 0)).p).unit
local vector = (targetPos - playerPos) * xz
local lookDirection = targetData:GetCFrame().lookVector
local movementAngle = math.acos(vector:Dot(lookDirection) / vector.magnitude)
local targetAngle = math.asin(vector:Dot(lookVector) / vector.magnitude)
local rotDirection = 0
if math.deg(movementAngle) >= 1 then
rotDirection = -math.sign(targetAngle) * math.max(1, vector.magnitude / 3)
end
local aggroOffset = playerData.humanoidRootPart.Size.X / 2 + targetData.humanoidRootPart.Size.X / 2
local defOffset = aggroOffset * targetData.offsetMultiplier
local myLookDirection = playerData:GetCFrame().lookVector
local offset = defOffset + (aggroOffset - defOffset) * (myLookDirection:Dot(lookVector) + 1) / 2
local movePoint = (CFrame.new(playerPos * xz, targetPos * xz) * CFrame.new(rotDirection, 0, offset - vector.magnitude)).Position
local distanceToTarget = (targetPos - playerPos).Magnitude
if distanceToTarget > attackRange then
playerData.humanoid:MoveTo(movePoint)
elseif distanceToTarget < minDistance then
local rightVector = playerData.humanoidRootPart.CFrame.rightVector
local lateralDir = (targetPos - playerPos).Unit
local dot = lateralDir:Dot(rightVector)
local dodgeDirection = (dot >= 0 and rightVector or -rightVector)
playerData.humanoid:MoveTo(playerPos + dodgeDirection * retreatDistance)
elseif distanceToTarget < attackRange then
playerData.humanoid:MoveTo(playerPos - myLookDirection * retreatDistance)
else
playerData.humanoid:MoveTo(movePoint)
end
end
-- SUPER OP Attack function with advanced prediction.
local function Attack()
local currentTime = tick()
local ourPredictedHitTime = currentTime + hitDelay
-- Get enemy's velocity (if available).
local enemyVel = (targetData and targetData.humanoidRootPart.AssemblyLinearVelocity) or Vector3.new(0, 0, 0)
-- Predict enemy's hit time.
local enemyAttackStart = targetData and targetData.lastAttackStartTime or currentTime
local enemyPredictedHitTime = enemyAttackStart + hitDelay
-- Predict enemy's position at hit time.
local enemyPredictedPos = targetData and (targetData.humanoidRootPart.Position + enemyVel * hitDelay) or targetData:GetFocusPoint()
-- Calculate adaptive lead time based on enemy speed.
local enemySpeed = enemyVel.Magnitude
local leadTime = math.clamp(enemySpeed * 0.005, 0, maxLeadTime)
-- Our effective hit time is adjusted by leadTime (attacking earlier).
local ourEffectiveHitTime = ourPredictedHitTime - leadTime
-- Use math to decide: if our effective hit lands before enemy's, attack now.
if ourEffectiveHitTime <= enemyPredictedHitTime then
UseTool(punchTool)
if yeetTool then task.wait(0.5) end
UseTool(yeetTool)
playerData.lastAttackStartTime = currentTime
else
-- Otherwise, schedule our attack so that it lands just before enemy's.
local delayTime = (enemyPredictedHitTime - ourEffectiveHitTime) - 0.05
if delayTime < 0 then delayTime = 0 end
task.delay(delayTime, function()
if active and targetData and targetData.alive then
UseTool(punchTool)
if yeetTool then task.wait(0.5) end
UseTool(yeetTool)
playerData.lastAttackStartTime = tick()
end
end)
end
end
function UseTool(tool)
if not tool or not tool.Parent then return end
if tool.Parent == player.Backpack then
playerData.humanoid:EquipTool(tool)
end
tool:Activate()
end
local function onToolAdded(instance)
if not instance:IsA("Tool") then return end
if instance.Name == "Yeet" then
yeetTool = instance
elseif instance.Name == "Punch" then
punchTool = instance
end
end
c[#c + 1] = userInputService.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.End then
for _, connection in ipairs(c) do
connection:Disconnect()
end
active = false
runtime:DisableStates()
playerData:remove()
elseif input.KeyCode == Enum.KeyCode.X then
if enabled then
enabled = false
runtime:DisableState("Attack")
else
enabled = true
runtime:EnableState("Attack")
end
end
end)
playerData = playerDataClass:new(player)
for _, p in ipairs(game.Players:GetChildren()) do
if p == game.Players.LocalPlayer then continue end
playerDataClass:new(p)
end
c[#c + 1] = game.Players.PlayerAdded:Connect(function(p)
playerDataClass:new(p)
end)
runtime.states.Default.functions[ScanPlayers] = ScanPlayers
runtime.states.Attack.functions[TrackCharacters] = TrackCharacters
runtime.states.Attack.functions[Attack] = Attack
runtime:EnableState("Default")
ok, here comes something cool local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local VirtualUser = game:GetService("VirtualUser")
local player = Players.LocalPlayer
local camera = workspace.CurrentCamera
local mouse = player:GetMouse()
-- Function to find nearest player and their distance
local function findNearestPlayer()
local character = player.Character
if not character or not character:FindFirstChild("HumanoidRootPart") then return nil, nil end
local closestPlayer = nil
local shortestDistance = math.huge
for _, otherPlayer in pairs(Players:GetPlayers()) do
if otherPlayer ~= player then
local otherChar = otherPlayer.Character
if otherChar and otherChar:FindFirstChild("HumanoidRootPart") then
local distance = (character.HumanoidRootPart.Position - otherChar.HumanoidRootPart.Position).Magnitude
if distance < shortestDistance then
shortestDistance = distance
closestPlayer = otherPlayer
end
end
end
end
return closestPlayer, shortestDistance
end
-- Main loop
RunService.RenderStepped:Connect(function()
local targetPlayer, distance = findNearestPlayer()
if targetPlayer and targetPlayer.Character and targetPlayer.Character:FindFirstChild("HumanoidRootPart") then
-- Check if distance is greater than 60 studs
if distance > 60 then
local targetPosition = targetPlayer.Character.HumanoidRootPart.Position
-- Face camera towards target
camera.CFrame = CFrame.new(camera.CFrame.Position, targetPosition)
-- Simulate mouse click at target's position
local screenPoint = camera:WorldToScreenPoint(targetPosition)
VirtualUser:ClickButton1(Vector2.new(screenPoint.X, screenPoint.Y))
end
end
end, nil)
-- Initial camera setup
camera.CameraType = Enum.CameraType.Custom use this script, add it to the bot, and now we do something cool, we make it equip the SelfYeet tool, selfyeet makes you fly at the player, so add that into combat, and make it very op, make it selfyeet behind them ect, note that if you want it to selfyeet somewhere then you gotta point the camera at where you want it to selfyeet game:GetService("Players").LocalPlayer.PlayerGui.RTGui.codebase.ragdoll.Events.Toggle:FireServer(table.unpack({
[1] = "R",
[2] = false,
})) use this to make my character get up, my character has to run this after each selfyeet to get up USE THIS -- LocalScript inside StarterPlayer -> StarterPlayerScripts
-- Wait until the player's character and Backpack are loaded local player = game.Players.LocalPlayer local backpack = player:WaitForChild("Backpack")
-- Define the tool's name (make sure the tool is named 'Yeet' in the game) local toolName = "Yeet"
-- Function to equip the Yeet tool local function equipYeetTool() -- Check if the tool exists in the player's Backpack local tool = backpack:FindFirstChild(toolName)
-- If the tool exists, equip it if tool then player.Character:WaitForChild("Humanoid"):EquipTool(tool) else warn("Yeet tool not found in Backpack!") end end DONT SHORTEN OR REMOVE ANYTHING
-- Call the function to equip the tool equipYeetTool() to auto equip