
Keyless
-- LocalScript: Multi-Target Click Lock + Smarter SelfYeet-Behind
-- ***Both leans enabled***:
-- (A) OLD horizontal ~70° lean (MoveTo side-entry shove)
-- (B) BodyGyro lean with dynamic ±60° yaw offset (continuous)
-- Smarter Humanoid:MoveTo striker: closes in more as you get closer to the target’s back.
-- Click-to-multi-target, safer selfyeet (auto side-switch), robust cleanup (X), hand-map toggle (H).
-- Place in StarterPlayerScripts
--==============================================================
-- SERVICES
--==============================================================
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local Debris = game:GetService("Debris")
local LocalPlayer = Players.LocalPlayer
local Mouse = LocalPlayer:GetMouse()
local character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
local hrp = character:WaitForChild("HumanoidRootPart")
local humanoid = character:WaitForChild("Humanoid")
local camera = Workspace.CurrentCamera
--==============================================================
-- ANIMATION IDS (detect which hand)
--==============================================================
local leftSwingAnimId = "rbxassetid://7218622714"
local rightSwingAnimId = "rbxassetid://7218624486"
--==============================================================
-- OPTIONAL REMOTE (get-up toggle)
--==============================================================
local ok, toggleRemote = pcall(function()
return LocalPlayer:WaitForChild("PlayerGui")
:WaitForChild("RTGui")
:WaitForChild("codebase")
:WaitForChild("ragdoll")
:WaitForChild("Events")
:WaitForChild("Toggle")
end)
if not ok then toggleRemote = nil end
local toggleArgs = { "R", false }
--==============================================================
-- CONFIG
--==============================================================
local SIDE_DISTANCE = 44
local SAFE_DISTANCE = 30
local GETUP_FIRE_DISTANCE = 100
local SELFYEET_MIN_INTERVAL = 0.01
local YEET_MIN_INTERVAL = 0.25
local YEET_TRIGGER_DISTANCE = 140
local MOVE_INTERVAL = 0.005
local BACKSTEP_DISTANCE = 30
local GETUP_SPAM_INTERVAL = 0.05
local SWING_PRIORITY_THRESHOLD = 0.50
local COMBO_INTERVAL = 0.50
-- Predictive tuning
local SELFYEET_DASH_SPEED = 120
local MAX_YEET_LEAD_TIME = 0.50
local PREDICT_MIN_DIST = 30
local LATERAL_LEAD_BIAS = 1.0
-- Vulnerability windows
local VULN_DOT_THRESHOLD = 0.55
local VULN_DIST_MIN = 25
local VULN_DIST_MAX = 60
local PREEMPT_SELFYEET_COOLDOWN = 0.01
local SELFYEET_MIN_RANGE = 60 -- don't selfyeet if this close
--==================== CAMERA (LOW + ALWAYS DOWN) ====================
local CAM_STICK_DISTANCE = 70
local CAM_HEIGHT = 2
local CAM_SMOOTH_ALPHA = 0.14
local BASE_DOWN_TILT = 12
local AIR_DOWNWARD_AIM_OFFSET = 60
local AIR_DOWNWARD_SELFYEET_BOOST= 25
--===================================================================
-- Safer-yeet anti-collision
local ENEMY_RECENT_SWING_TIME = 0.45
local SAFETY_LATERAL_EVASION = 10
local SAFETY_FORWARD_PULLBACK = 6
--==================== SIDEWAYS FOOTWORK (ORBIT) =====================
local ORBIT_MIN_STEP = 10
local ORBIT_MAX_STEP = 24
local STRIKE_ARC_DEG = 45
local STRIKE_CORRIDOR_WIDTH = 12
local LATERAL_DRIVE_BIAS = 1.25
local STUCK_TIME = 0.35
local STUCK_DIST_EPS = 2.0
local REPULSE_WHEN_TOOCLOSE = 18
local MOVE_TO_TIMEOUT = 1.2
--====================================================================
--==================== ***GYRO LEAN + YAW OFFSET*** ==================
local HAND_INVERT = true
local YAW_OFFSET_DEG = 50 -- ±60° while striking (right hand -> +60°, left -> -60°)
local ROLL_LEAN_DEG = 8 -- small roll so it's obvious; 0 to disable
local HAND_LEAN_TIME = 0.60 -- lean window
--====================================================================
--==================== OLD HORIZONTAL ~70° LEAN (side shove) =========
local LEAN_ANGLE_DEG = 50 -- horizontal movement angle versus forward
local LEAN_DIST_BASE = 18
local LEAN_DIST_NEAR = 30
local LEAN_FORWARD_PUSH = 6
--====================================================================
--==================== SMART SELFYEET-BEHIND =========================
local BEHIND_RADIUS = 36
local BEHIND_SIDE_OFFSET = 18
local BEHIND_EXTRA_LEAD_TIME = 0.20
local SWITCH_SIDE_COOLDOWN = 0.15
local BEHIND_SCORE_FRONT_PENALTY = 1.6
local BEHIND_SCORE_SIDE_BONUS = 0.25
--====================================================================
--==================== SMART CLOSE-IN WHEN BEHIND =====================
-- As "behindness" -> 1, shrink desired orbit radius to hit range.
local BEHIND_CLOSE_RADIUS_MIN = 10 -- how close we want when fully behind
local BEHIND_CLOSE_RADIUS_MAX = SAFE_DISTANCE + 12 -- normal orbit when not behind
local BACK_ENTRY_BOOST = 8 -- extra pull forward when behind to secure hit
--====================================================================
--==============================================================
-- STATE / CONNECTIONS
--==============================================================
local RUNNING = true
local CONNS = {}
local function track(conn) if conn then table.insert(CONNS, conn) end; return conn end
--==============================================================
-- UI
--==============================================================
local gui = Instance.new("ScreenGui")
gui.Name = "WalkFlankGui"
gui.ResetOnSpawn = false
gui.Parent = LocalPlayer:WaitForChild("PlayerGui")
local statusLabel = Instance.new("TextLabel")
statusLabel.Size = UDim2.new(0, 1100, 0, 48)
statusLabel.Position = UDim2.new(0.5, -550, 0.86, 0)
statusLabel.BackgroundTransparency = 0.25
statusLabel.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
statusLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
statusLabel.TextScaled = true
statusLabel.Font = Enum.Font.GothamMedium
statusLabel.Text = "Initializing..."
statusLabel.Parent = gui
--==============================================================
-- BodyGyro (full torque for roll/yaw) & Camera
--==============================================================
local gyro = Instance.new("BodyGyro")
gyro.MaxTorque = Vector3.new(1e7, 1e7, 1e7)
gyro.P = 6000
gyro.D = 300
gyro.CFrame = hrp.CFrame
gyro.Parent = hrp
local previousCameraType = camera.CameraType
camera.CameraType = Enum.CameraType.Scriptable
local currentCamCFrame = camera.CFrame
--==============================================================
-- TARGETING
--==============================================================
local selectedTargets, highlights, targetLastSwing = {}, {}, {}
local function makeHighlight(plr)
if not plr.Character then return end
local h = highlights[plr]
if h and h.Parent then return end
h = Instance.new("Highlight")
h.Name = "TargetHighlight_" .. plr.Name
h.FillTransparency = 1
h.OutlineTransparency = 0.08
h.OutlineColor = Color3.fromRGB(255, 240, 150)
h.DepthMode = Enum.HighlightDepthMode.Occluded
h.Parent = plr.Character
highlights[plr] = h
end
local function removeHighlight(plr) local h = highlights[plr]; if h then h:Destroy() end; highlights[plr] = nil end
local function toggleTarget(plr)
if not plr or plr == LocalPlayer then return end
if not plr.Character or not plr.Character:FindFirstChild("HumanoidRootPart") then return end
if selectedTargets[plr] then selectedTargets[plr] = nil; removeHighlight(plr)
else selectedTargets[plr] = true; makeHighlight(plr) end
end
local function getPlayerFromInstance(inst)
if not inst then return nil end
local model = inst:FindFirstAncestorOfClass("Model")
if not model then return nil end
return Players:GetPlayerFromCharacter(model)
end
track(Mouse.Button1Down:Connect(function()
if not RUNNING then return end
if UserInputService:GetFocusedTextBox() then return end
local plr = getPlayerFromInstance(Mouse.Target)
if plr then toggleTarget(plr) end
end))
track(Players.PlayerAdded:Connect(function(plr)
track(plr.CharacterAdded:Connect(function()
if selectedTargets[plr] then task.wait(0.1); makeHighlight(plr) end
end))
end))
--==============================================================
-- HELPERS
--==============================================================
local function safestChar()
character = LocalPlayer.Character
if not character then return end
hrp = character:FindFirstChild("HumanoidRootPart")
humanoid = character:FindFirstChildOfClass("Humanoid")
return character and hrp and humanoid
end
local function getTargetsList()
local list = {}
for plr, v in pairs(selectedTargets) do
if v and plr.Character and plr.Character:FindFirstChild("HumanoidRootPart") then
table.insert(list, plr)
end
end
return list
end
local function getClosestOfTargets()
local best, bestDist
local pos = hrp.Position
for plr, v in pairs(selectedTargets) do
if v and plr.Character and plr.Character:FindFirstChild("HumanoidRootPart") then
local d = (plr.Character.HumanoidRootPart.Position - pos).Magnitude
if not bestDist or d < bestDist then best, bestDist = plr, d end
end
end
return best, bestDist
end
local function equipToolByName(name)
local backpack = LocalPlayer:FindFirstChildOfClass("Backpack")
if not backpack or not LocalPlayer.Character then return nil end
local tool = LocalPlayer.Character:FindFirstChild(name) or backpack:FindFirstChild(name)
if not tool then return nil end
if tool.Parent ~= LocalPlayer.Character then tool.Parent = LocalPlayer.Character end
return tool
end
local function activateToolLocal(tool) if tool and typeof(tool.Activate) == "function" then pcall(function() tool:Activate() end) end end
local function getHRPVelocity(part)
if part and part:IsA("BasePart") then
local okVel, vel = pcall(function() return part.AssemblyLinearVelocity end)
if okVel and typeof(vel) == "Vector3" then return vel end
return part.Velocity
end
return Vector3.zero
end
--==============================================================
-- PREDICTION & SAFETY
--==============================================================
local function predictTargetPosition(myPos, targetHRP, dashSpeed, extraLead)
local targetPos = targetHRP.Position
local toTarget = targetPos - myPos
local dist = toTarget.Magnitude
if dist < PREDICT_MIN_DIST then return targetPos end
local toTargetUnit = toTarget.Unit
local targetVel = getHRPVelocity(targetHRP)
local radial = targetVel:Dot(toTargetUnit)
local lateral = targetVel - toTargetUnit * radial
local approxTime = math.clamp(dist / math.max(dashSpeed, 1), 0, MAX_YEET_LEAD_TIME + (extraLead or 0))
return targetPos + lateral * approxTime * LATERAL_LEAD_BIAS + toTargetUnit * (radial * 0.25 * approxTime)
end
local function saferAdjust(predicted, targetHRP, enemyLastSwingTime)
if not targetHRP then return predicted end
local now = tick()
local enemyMidSwing = enemyLastSwingTime and (now - enemyLastSwingTime) <= ENEMY_RECENT_SWING_TIME
if not enemyMidSwing then return predicted end
local enemyLook = targetHRP.CFrame.LookVector
local enemyRight = targetHRP.CFrame.RightVector
local toPredUnit = (predicted - targetHRP.Position).Unit
if math.abs(enemyLook:Dot(toPredUnit)) > 0.5 then
predicted = predicted - enemyLook * SAFETY_FORWARD_PULLBACK
predicted = predicted + enemyRight * ((math.random() < 0.5) and -SAFETY_LATERAL_EVASION or SAFETY_LATERAL_EVASION)
end
return predicted
end
--==============================================================
-- CAMERA (low + always down)
--==============================================================
local function smoothCameraTo(desired)
currentCamCFrame = currentCamCFrame:Lerp(desired, CAM_SMOOTH_ALPHA)
camera.CFrame = currentCamCFrame
end
local function aimCameraAtPoint(lookPoint, isSelfYeet)
local myPos = hrp.Position
local state = humanoid:GetState()
local inAir = (state == Enum.HumanoidStateType.Freefall) or (state == Enum.HumanoidStateType.Jumping)
local extraDown = BASE_DOWN_TILT
if inAir then extraDown = extraDown + AIR_DOWNWARD_AIM_OFFSET + (isSelfYeet and AIR_DOWNWARD_SELFYEET_BOOST or 0) end
local flatDir = Vector3.new(lookPoint.X, myPos.Y, lookPoint.Z) - myPos
if flatDir.Magnitude < 1e-3 then flatDir = hrp.CFrame.LookVector end
local dirUnit = flatDir.Unit
local camPos = myPos - dirUnit * CAM_STICK_DISTANCE + Vector3.new(0, CAM_HEIGHT, 0)
local desired = CFrame.new(camPos, lookPoint - Vector3.new(0, extraDown, 0))
smoothCameraTo(desired)
end
--==============================================================
-- GYRO ORIENTATION (continuous; always face target with optional ±60° yaw + roll)
--==============================================================
local function yawRotate2D(v, rad)
local c, s = math.cos(rad), math.sin(rad)
return Vector3.new(v.X * c - v.Z * s, 0, v.X * s + v.Z * c)
end
local function cframeFacingWithYawAndRoll(pos, forwardFlatUnit, yawOffsetRad, rollRad)
local f = yawRotate2D(forwardFlatUnit, yawOffsetRad)
if f.Magnitude < 1e-3 then f = Vector3.new(0,0,-1) end
f = f.Unit
local upWorld = Vector3.new(0,1,0)
local right = upWorld:Cross(f).Unit
local up = f:Cross(right).Unit
if rollRad ~= 0 then
local cr, sr = math.cos(rollRad), math.sin(rollRad)
local r2 = right*cr + up*sr
local u2 = f:Cross(r2).Unit
right, up = r2, u2
end
return CFrame.fromMatrix(pos, right, up, -f)
end
--==============================================================
-- VULNERABILITY
--==============================================================
local function isSelfVulnerable(targetHRP)
local toTarget = targetHRP.Position - hrp.Position
local dist = toTarget.Magnitude
if dist < VULN_DIST_MIN or dist > VULN_DIST_MAX then return false, dist end
local toTargetUnit = toTarget.Unit
local myRight = hrp.CFrame.RightVector
local sideExposure = math.abs(myRight:Dot(toTargetUnit))
return sideExposure >= VULN_DOT_THRESHOLD, dist
end
--==============================================================
-- SWING TRACKING
--==============================================================
local myLastSwingTime, mySwingActiveUntil = 0, 0
local myCurrentHandBias, myHandBiasUntil = 0, 0 -- -1 left, +1 right
track(humanoid.AnimationPlayed:Connect(function(trackObj)
if not RUNNING then return end
if not trackObj or not trackObj.Animation or not trackObj.Animation.AnimationId then return end
local animId = trackObj.Animation.AnimationId
if animId == leftSwingAnimId or animId == rightSwingAnimId then
myLastSwingTime = tick()
mySwingActiveUntil = myLastSwingTime + SWING_PRIORITY_THRESHOLD
local handSign = (animId == rightSwingAnimId) and 1 or -1
if HAND_INVERT then handSign = -handSign end
myCurrentHandBias = handSign
myHandBiasUntil = myLastSwingTime + HAND_LEAN_TIME
end
end))
local function hookEnemySwing(plr)
if not plr or plr == LocalPlayer then return end
if not plr.Character then return end
local thum = plr.Character:FindFirstChildOfClass("Humanoid"); if not thum then return end
if thum:FindFirstChild("_SwingHook") then return end
local tag = Instance.new("BoolValue"); tag.Name = "_SwingHook"; tag.Parent = thum
track(thum.AnimationPlayed:Connect(function(trackObj)
if not RUNNING then return end
if not trackObj or not trackObj.Animation or not trackObj.Animation.AnimationId then return end
local animId = trackObj.Animation.AnimationId
if animId == leftSwingAnimId or animId == rightSwingAnimId then
targetLastSwing[plr] = tick()
end
end))
end
for _, plr in ipairs(Players:GetPlayers()) do
if plr ~= LocalPlayer then
if plr.Character then hookEnemySwing(plr) end
track(plr.CharacterAdded:Connect(function() task.wait(0.05); if RUNNING then hookEnemySwing(plr) end end))
end
end
track(Players.PlayerAdded:Connect(function(plr)
if plr ~= LocalPlayer then
track(plr.CharacterAdded:Connect(function() task.wait(0.05); if RUNNING then hookEnemySwing(plr) end end))
end
end))
--==============================================================
-- SMART SELFYEET-BEHIND CHOOSER
--==============================================================
local lastSideChoice, lastSideTick = 0, 0 -- -1 left, +1 right
local function chooseSelfYeetBehindPoint(myPos, targetHRP)
local basePred = predictTargetPosition(myPos, targetHRP, SELFYEET_DASH_SPEED, BEHIND_EXTRA_LEAD_TIME)
local tCF = targetHRP.CFrame
local tLook = tCF.LookVector
local tRight = tCF.RightVector
local tVel = getHRPVelocity(targetHRP)
local lateralVel = tVel - tLook * tVel:Dot(tLook)
local driftSign = (lateralVel:Dot(tRight) >= 0) and 1 or -1
if tick() - lastSideTick > SWITCH_SIDE_COOLDOWN then
lastSideChoice, lastSideTick = driftSign, tick()
end
local behind = basePred - tLook * BEHIND_RADIUS
local candRight = behind + tRight * BEHIND_SIDE_OFFSET
local candLeft = behind - tRight * BEHIND_SIDE_OFFSET
local function score(pt, sideSign)
local toPt = (pt - basePred)
local flatToPt = Vector3.new(toPt.X, 0, toPt.Z)
if flatToPt.Magnitude < 1e-3 then return -math.huge end
local unit = flatToPt.Unit
local behindness = (-tLook):Dot(unit)
local frontPenalty = math.max(0, tLook:Dot(unit)) * BEHIND_SCORE_FRONT_PENALTY
local sideBonus = (sideSign == lastSideChoice) and BEHIND_SCORE_SIDE_BONUS or 0
local myFwd = (pt - myPos); myFwd = Vector3.new(myFwd.X, 0, myFwd.Z)
local approach = (myFwd.Magnitude > 0) and (myFwd.Unit:Dot(unit)) or 0
return behindness - frontPenalty + sideBonus + 0.1*approach
end
local sRight = score(candRight, 1)
local sLeft = score(candLeft, -1)
local best = sRight >= sLeft and candRight or candLeft
lastSideChoice = (sRight >= sLeft) and 1 or -1
return best
end
--==============================================================
-- SELFYEET
--==============================================================
local lastSelfYeetTime, lastPreemptSelfYeet = 0, 0
local function canSelfYeet() return (tick() - lastSelfYeetTime) >= SELFYEET_MIN_INTERVAL end
local function trySelfYeetTo(point, isSelfYeet)
if not canSelfYeet() then return false end
aimCameraAtPoint(point, isSelfYeet)
local tool = equipToolByName("SelfYeet")
if tool then activateToolLocal(tool); lastSelfYeetTime = tick(); return true end
return false
end
local function trySelfYeetPredictiveBehind(targetPlr)
if not targetPlr or not targetPlr.Character or not targetPlr.Character:FindFirstChild("HumanoidRootPart") then return false end
local targetHRP = targetPlr.Character.HumanoidRootPart
local targetPoint = chooseSelfYeetBehindPoint(hrp.Position, targetHRP)
targetPoint = saferAdjust(targetPoint, targetHRP, targetLastSwing[targetPlr])
return trySelfYeetTo(targetPoint, true)
end
--==============================================================
-- COUNTER
--==============================================================
local function quickCounter()
local tool = equipToolByName("Punch") or equipToolByName("Yeet")
if tool then
activateToolLocal(tool)
myLastSwingTime = tick()
mySwingActiveUntil = myLastSwingTime + SWING_PRIORITY_THRESHOLD
end
end
--==============================================================
-- DIRECTION UTILITIES
--==============================================================
local function dirAtAngle(forwardFlatUnit, rightFlatUnit, sign, degrees)
local rad = math.rad(math.clamp(degrees or 70, 0, 89.9))
local d = forwardFlatUnit * math.cos(rad) + rightFlatUnit * (sign) * math.sin(rad)
if d.Magnitude < 1e-3 then return forwardFlatUnit end
return d.Unit
end
--==============================================================
-- SIDEWAYS FOOTWORK ENGINE (MoveTo orbits) + BACK-CLOSER LOGIC
--==============================================================
local activeWaypoint = nil
local lastProgressTime, lastProgressDist = 0, math.huge
local moving = false
local moveStartTick = 0
local function desiredOrbitRadiusFromBehindness(behindness)
-- behindness in [0,1]: 0 = front, 1 = fully behind
return BEHIND_CLOSE_RADIUS_MAX - (BEHIND_CLOSE_RADIUS_MAX - BEHIND_CLOSE_RADIUS_MIN) * math.clamp(behindness, 0, 1)
end
local function chooseOrbitWaypointSmart(myPos, targetHRP, preferSign)
local tPos = targetHRP.Position
local tCF = targetHRP.CFrame
local tLook = tCF.LookVector
-- behindness: 1 when we're directly behind the target
local vecTM = (myPos - tPos); vecTM = Vector3.new(vecTM.X, 0, vecTM.Z)
local unitTM = (vecTM.Magnitude > 0) and vecTM.Unit or -tLook
local behindness = math.max(0, (-tLook):Dot(unitTM)) -- [0..1]
local desiredR = desiredOrbitRadiusFromBehindness(behindness)
local f = (tPos - myPos); f = Vector3.new(f.X, 0, f.Z); if f.Magnitude < 1e-3 then f = Vector3.new(0,0,-1) end; f=f.Unit
local r = Vector3.new(0,1,0):Cross(f).Unit
local sign = preferSign
if sign == 0 then
local dotFacing = targetHRP.CFrame.RightVector:Dot(-(tPos - myPos).Unit)
sign = (dotFacing > 0) and 1 or -1
end
-- lateral-biased drive, plus forward boost if we are behind (so we glide into the back more)
local forwardBoost = BACK_ENTRY_BOOST * behindness
local drive = (r * sign * LATERAL_DRIVE_BIAS + f + f * (forwardBoost / math.max(desiredR,1))).Unit
-- step length adapts to distance; reduce step when we are nearly at desired radius
local curR = (tPos - myPos).Magnitude
local closenessToRing = math.abs(curR - desiredR)
local stepBase = math.clamp(curR * 0.35, ORBIT_MIN_STEP, ORBIT_MAX_STEP)
local step = stepBase * (closenessToRing > 6 and 1 or 0.6)
local candidate = myPos + drive * step
-- clamp to ring radius = desiredR (the "smart" ring)
local v = candidate - tPos
v = Vector3.new(v.X, 0, v.Z)
if v.Magnitude > 1e-3 then
candidate = tPos + v.Unit * desiredR
end
-- nudge toward strike corridor (hand-side 45° arc)
local entryDir = (f + r * sign).Unit
local angleToEntry = math.deg(math.acos(math.clamp(entryDir:Dot((candidate - tPos).Unit), -1, 1)))
if angleToEntry > STRIKE_ARC_DEG then
local toward = (entryDir + ((candidate - tPos).Unit))*0.5
if toward.Magnitude > 0 then
candidate = tPos + toward.Unit * (desiredR - STRIKE_CORRIDOR_WIDTH*0.25)
end
else
candidate = candidate + entryDir * (STRIKE_CORRIDOR_WIDTH * 0.25)
end
return Vector3.new(candidate.X, myPos.Y, candidate.Z), behindness, desiredR
end
local function beginMoveTo(point)
activeWaypoint = point
moveStartTick = tick()
lastProgressTime = moveStartTick
lastProgressDist = (activeWaypoint - hrp.Position).Magnitude
moving = true
humanoid:MoveTo(activeWaypoint)
end
track(humanoid.MoveToFinished:Connect(function() moving = false end))
local function updateSidewaysController(targetHRP, preferSign)
local now = tick()
local myPos = hrp.Position
if not activeWaypoint or not moving then
local wp = chooseOrbitWaypointSmart(myPos, targetHRP, preferSign)
beginMoveTo(wp)
return
end
local distNow = (activeWaypoint - myPos).Magnitude
if distNow + STUCK_DIST_EPS < lastProgressDist then
lastProgressDist = distNow
lastProgressTime = now
end
local tDist = (targetHRP.Position - myPos).Magnitude
if tDist < SAFE_DISTANCE * 0.8 then
local f = Vector3.new(targetHRP.Position.X - myPos.X, 0, targetHRP.Position.Z - myPos.Z).Unit
beginMoveTo(myPos - f * REPULSE_WHEN_TOOCLOSE)
return
end
if (now - moveStartTick) > MOVE_TO_TIMEOUT or (now - lastProgressTime) > STUCK_TIME then
local wp = chooseOrbitWaypointSmart(myPos, targetHRP, preferSign)
beginMoveTo(wp)
return
end
if (now - moveStartTick) > 0.15 then
local steer = chooseOrbitWaypointSmart(myPos, targetHRP, preferSign)
activeWaypoint = activeWaypoint:Lerp(steer, 0.4)
humanoid:MoveTo(activeWaypoint)
end
end
--==============================================================
-- LOOP STATE
--==============================================================
local currentAction = "Yeet"
local lastActionTime = 0
local lastGetupTime = 0
--==============================================================
-- MAIN LOOP
--==============================================================
track(RunService.RenderStepped:Connect(function()
if not RUNNING then return end
if not safestChar() then return end
local closestTarget, _ = getClosestOfTargets()
if not closestTarget then
statusLabel.Text = "No target selected. Click players to toggle targets."
return
end
local tHRP = closestTarget.Character and closestTarget.Character:FindFirstChild("HumanoidRootPart")
if not tHRP then statusLabel.Text = "Target invalid."; return end
local myPos = hrp.Position
local tPos = tHRP.Position
local toTarget = tPos - myPos
local distanceToTarget = toTarget.Magnitude
local toTargetUnit = (distanceToTarget > 0) and toTarget.Unit or hrp.CFrame.LookVector
-- prefer side (hand) during swing window for orbiting & old lean
local preferSign = 0
if tick() <= myHandBiasUntil and myCurrentHandBias ~= 0 then
preferSign = (myCurrentHandBias > 0) and 1 or -1
end
updateSidewaysController(tHRP, preferSign)
-- ***OLD HORIZONTAL ~70° LEAN***: extra shove along ±70° when striking
if tick() <= myHandBiasUntil and myCurrentHandBias ~= 0 then
local fwdFlat = Vector3.new(toTargetUnit.X, 0, toTargetUnit.Z).Unit
local rightFlat = Vector3.new(0,1,0):Cross(fwdFlat).Unit
local leanDir = dirAtAngle(fwdFlat, rightFlat, (myCurrentHandBias>0) and 1 or -1, LEAN_ANGLE_DEG)
local closeness = math.clamp((SAFE_DISTANCE + 20 - distanceToTarget) / 20, 0, 1)
local leanDist = LEAN_DIST_BASE + (LEAN_DIST_NEAR - LEAN_DIST_BASE) * closeness
local forcePoint = myPos + leanDir * leanDist + fwdFlat * LEAN_FORWARD_PUSH
humanoid:MoveTo(forcePoint)
end
-- far -> predictive selfyeet ***behind*** (respect ≤90 rule)
if distanceToTarget > math.max(SAFE_DISTANCE + 40, SELFYEET_MIN_RANGE + 1) then
trySelfYeetPredictiveBehind(closestTarget)
end
-- camera (low + down)
local fwdFlat = Vector3.new(toTargetUnit.X, 0, toTargetUnit.Z).Unit
local camLook = myPos + fwdFlat * 5
local camFrom = myPos - fwdFlat * CAM_STICK_DISTANCE + Vector3.new(0, CAM_HEIGHT, 0)
local desiredCFrame = CFrame.new(camFrom, camLook - Vector3.new(0, BASE_DOWN_TILT, 0))
currentCamCFrame = currentCamCFrame:Lerp(desiredCFrame, CAM_SMOOTH_ALPHA)
camera.CFrame = currentCamCFrame
-- ================== CONTINUOUS GYRO LEAN & FACING ==================
-- Always face target; in strike window: apply ±60° yaw + small roll
local yawOffset = 0
local rollLean = 0
if tick() <= myHandBiasUntil and myCurrentHandBias ~= 0 then
local sign = (myCurrentHandBias > 0) and 1 or -1
yawOffset = math.rad(sign * YAW_OFFSET_DEG)
rollLean = math.rad(sign * ROLL_LEAN_DEG)
end
gyro.CFrame = cframeFacingWithYawAndRoll(hrp.Position, fwdFlat, yawOffset, rollLean)
-- ===================================================================
-- preempt selfyeet on exposure -> slip behind
local selfVuln, _ = isSelfVulnerable(tHRP)
if selfVuln and distanceToTarget > SELFYEET_MIN_RANGE and (tick() - lastPreemptSelfYeet) >= PREEMPT_SELFYEET_COOLDOWN then
local behindPoint = chooseSelfYeetBehindPoint(myPos, tHRP)
behindPoint = saferAdjust(behindPoint, tHRP, targetLastSwing[closestTarget])
if trySelfYeetTo(behindPoint, true) then lastPreemptSelfYeet = tick() end
end
-- combo loop
if distanceToTarget <= YEET_TRIGGER_DISTANCE then
if tick() - lastActionTime >= COMBO_INTERVAL then
local tool = equipToolByName(currentAction)
if tool then
activateToolLocal(tool)
myLastSwingTime = tick()
mySwingActiveUntil = myLastSwingTime + SWING_PRIORITY_THRESHOLD
myHandBiasUntil = myLastSwingTime + HAND_LEAN_TIME
end
currentAction = (currentAction == "Yeet") and "Punch" or "Yeet"
lastActionTime = tick()
end
end
-- HUD
local tLook = tHRP.CFrame.LookVector
local behindnessVec = (myPos - tPos); behindnessVec = Vector3.new(behindnessVec.X,0,behindnessVec.Z)
local behindness = 0
if behindnessVec.Magnitude > 0 then
behindness = math.max(0, (-tLook):Dot(behindnessVec.Unit))
end
statusLabel.Text = string.format(
"Targets: %d | Focus: %s | Dist: %.1f | Behindness: %.2f | SelfYeet side: %s | Yaw±%d°",
#(getTargetsList()), closestTarget.Name, distanceToTarget,
behindness,
(lastSideChoice==0 and "n/a" or (lastSideChoice>0 and "RIGHT" or "LEFT")),
YAW_OFFSET_DEG
)
-- get-up spam
if toggleRemote and distanceToTarget <= GETUP_FIRE_DISTANCE then
if (tick() - lastGetupTime) >= GETUP_SPAM_INTERVAL then
pcall(function() toggleRemote:FireServer(unpack(toggleArgs)) end)
lastGetupTime = tick()
end
end
end))
--==============================================================
-- ENEMY-SWING REACTIVE
--==============================================================
local lastCheckedSwing = {}
track(RunService.RenderStepped:Connect(function()
if not RUNNING then return end
local now = tick()
for plr, _ in pairs(selectedTargets) do
repeat
if not plr.Character then break end
local root = plr.Character:FindFirstChild("HumanoidRootPart"); if not root then break end
local t = targetLastSwing[plr]
if not t or (lastCheckedSwing[plr] and t <= lastCheckedSwing[plr]) then break end
lastCheckedSwing[plr] = t
local dist = (root.Position - hrp.Position).Magnitude
local iAmMidSwing = now <= mySwingActiveUntil
local theyHitBeforeMe = not iAmMidSwing
if theyHitBeforeMe then
if dist > SELFYEET_MIN_RANGE then
local pt = chooseSelfYeetBehindPoint(hrp.Position, root)
pt = saferAdjust(pt, root, t)
trySelfYeetTo(pt, true)
else
-- juke & counter
local toward = (root.Position - hrp.Position); toward = Vector3.new(toward.X,0,toward.Z).Unit
local rightFlat = Vector3.new(0,1,0):Cross(toward).Unit
local sign = (math.random() < 0.5) and 1 or -1
local juke = (toward + rightFlat * sign).Unit
humanoid:MoveTo(hrp.Position + juke * 14)
quickCounter()
end
else
if dist <= SELFYEET_MIN_RANGE then quickCounter() end
end
until true
end
end))
--==============================================================
-- CLEANUP (press X) & HAND MAP TOGGLE (H)
--==============================================================
local function cleanupAndDestroy()
if not RUNNING then return end
RUNNING = false
for _, c in ipairs(CONNS) do pcall(function() c:Disconnect() end) end
table.clear(CONNS)
for plr,_ in pairs(highlights) do removeHighlight(plr) end
table.clear(highlights); table.clear(selectedTargets); table.clear(targetLastSwing); table.clear(lastCheckedSwing)
pcall(function() camera.CameraType = previousCameraType or Enum.CameraType.Custom end)
pcall(function() if gui then gui:Destroy() end end)
pcall(function() if gyro and gyro.Parent then gyro:Destroy() end end)
pcall(function() script.Parent = nil end)
pcall(function() Debris:AddItem(script, 0) end)
pcall(function() script:Destroy() end)
end
track(UserInputService.InputBegan:Connect(function(input, processed)
if processed then return end
if input.KeyCode == Enum.KeyCode.X then
cleanupAndDestroy()
elseif input.KeyCode == Enum.KeyCode.H then
HAND_INVERT = not HAND_INVERT
end
end))
more scripts https://discord.gg/3mkMnE6N