-- 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))