local Players = game:GetService("Players") local RunService = game:GetService("RunService") local Workspace = game:GetService("Workspace") local LocalPlayer = Players.LocalPlayer local Camera = workspace.CurrentCamera local MAX_DISTANCE = 16 local HIT_COOLDOWN = 0.01 local lastHit = 0 -- Prediction local VEL_HISTORY_SIZE = 6 local MAX_PREDICT_TIME = 0.15 -- Wall Check local WALL_CHECK = true local WALL_PADDING = 1.5 -- Anti-Deadlock local TARGET_TIMEOUT = 3 local lastSwitchTime = 0 local SWITCH_DELAY = 0.1 --====== СОСТОЯНИЕ ======-- local currentTarget = nil local targetLockTime = 0 local velHistory = {} local attackAttempts = 0 local hitSuccesses = 0 --====== БАЗОВЫЕ ФУНКЦИИ ======-- local function getChar(plr) return plr.Character end local function getHitbox(plr) local c = getChar(plr) if not c then return nil end return c:FindFirstChild("PlayerHitbox") or c:FindFirstChild("Head") or c:FindFirstChild("Torso") end local function getHum(plr) local c = getChar(plr) if not c then return nil end return c:FindFirstChild("Humanoid") end local function isAlive(plr) local hum = getHum(plr) return hum and hum.Health > 0 end local function getPos(plr) local h = getHitbox(plr) return h and h.Position or nil end local function getVel(plr) local h = getHitbox(plr) return h and h.AssemblyLinearVelocity or Vector3.new() end local function getMyPos() return getPos(LocalPlayer) end local function getMyEye() local c = getChar(LocalPlayer) if not c then return nil end return c:FindFirstChild("PlayerEyeLevel") and c.PlayerEyeLevel.Position or getMyPos() end --====== WALL CHECK ======-- local function isVisible(target) if not WALL_CHECK then return true end local eye = getMyEye() local targetPos = getPos(target) if not eye or not targetPos then return false end local dir = (targetPos - eye).Unit local dist = (targetPos - eye).Magnitude local params = RaycastParams.new() params.FilterDescendantsInstances = {getChar(LocalPlayer), getChar(target)} params.FilterType = Enum.RaycastFilterType.Exclude local ray = Workspace:Raycast(eye, dir * (dist - WALL_PADDING), params) return ray == nil end --====== ПРЕДИКТ С СИСТЕМНЫМИ УЛУЧШЕНИЯМИ ======-- local function updateVelHistory(target) local vel = getVel(target) local pos = getPos(target) table.insert(velHistory, { vel = vel, pos = pos, time = tick() }) if #velHistory > VEL_HISTORY_SIZE then table.remove(velHistory, 1) end end local function getSmoothedVel() if #velHistory < 2 then return Vector3.new() end local totalVel = Vector3.new() local totalWeight = 0 for i, entry in ipairs(velHistory) do local weight = i * i -- квадратичный вес (новые важнее) totalVel = totalVel + entry.vel * weight totalWeight = totalWeight + weight end if totalWeight == 0 then return Vector3.new() end return totalVel / totalWeight end local function getAcceleration() if #velHistory < 3 then return Vector3.new() end local recent = velHistory[#velHistory] local old = velHistory[1] local dt = math.max(recent.time - old.time, 0.001) return (recent.vel - old.vel) / dt end local function getJerk() if #velHistory < 4 then return Vector3.new() end local accel1 = (velHistory[#velHistory].vel - velHistory[#velHistory-1].vel) / math.max(velHistory[#velHistory].time - velHistory[#velHistory-1].time, 0.001) local accel2 = (velHistory[#velHistory-1].vel - velHistory[1].vel) / math.max(velHistory[#velHistory-1].time - velHistory[1].time, 0.001) local dt = math.max(velHistory[#velHistory].time - velHistory[1].time, 0.001) return (accel1 - accel2) / dt end local function predictPosition(target) local hb = getHitbox(target) if not hb then return nil end local pos = hb.Position local myPos = getMyPos() if not myPos then return pos end local distance = (pos - myPos).Magnitude local smoothedVel = getSmoothedVel() local accel = getAcceleration() local jerk = getJerk() local speed = smoothedVel.Magnitude -- Базовое время предсказания local baseTime = 0.05 + distance / 45 -- Корректировка от скорости цели if speed > 14 then baseTime = baseTime * 1.4 elseif speed > 8 then baseTime = baseTime * 1.2 elseif speed > 3 then baseTime = baseTime * 1.05 end -- Корректировка от направления движения local toMe = (myPos - pos).Unit if smoothedVel.Magnitude > 0.1 then local velDir = smoothedVel.Unit local dot = velDir:Dot(toMe) if dot > 0.6 then baseTime = baseTime * 1.35 elseif dot > 0.3 then baseTime = baseTime * 1.15 elseif dot < -0.6 then baseTime = baseTime * 0.7 elseif dot < -0.3 then baseTime = baseTime * 0.85 end end -- Учёт ускорения local accelMag = accel.Magnitude if accelMag > 20 then baseTime = baseTime * 1.25 elseif accelMag > 10 then baseTime = baseTime * 1.1 end local predictTime = math.clamp(baseTime, 0.02, MAX_PREDICT_TIME) -- Кубическое предсказание (позиция + скорость + ускорение + рывок) local predicted = pos + smoothedVel * predictTime + 0.5 * accel * predictTime^2 + (1/6) * jerk * predictTime^3 return predicted end --====== УМНЫЙ СКОРИНГ ======-- local function getTargetScore(plr) local myPos = getMyPos() if not myPos then return -10000 end if not isAlive(plr) then return -10000 end local pos = getPos(plr) if not pos then return -10000 end local dist = (pos - myPos).Magnitude if dist > MAX_DISTANCE then return -10000 end -- Проверка видимости if WALL_CHECK and not isVisible(plr) then return -5000 end local hum = getHum(plr) local hp = hum.Health local maxHp = hum.MaxHealth local hpRatio = hp / maxHp local vel = getVel(plr) local speed = vel.Magnitude local score = 0 -- 1. РАССТОЯНИЕ (оптимум 3-7 блоков) if dist < 2 then score = score + 25 elseif dist < 5 then score = score + 40 elseif dist < 8 then score = score + 35 elseif dist < 12 then score = score + 25 else score = score + 15 end -- 2. ЗДОРОВЬЕ (добиваем слабых) if hpRatio < 0.1 then score = score + 100 elseif hpRatio < 0.25 then score = score + 70 elseif hpRatio < 0.4 then score = score + 45 elseif hpRatio < 0.6 then score = score + 25 elseif hpRatio < 0.8 then score = score + 10 else score = score + 5 end -- 3. СКОРОСТЬ (быстрые опаснее) if speed > 12 then score = score + 30 elseif speed > 7 then score = score + 20 elseif speed > 3 then score = score + 10 end -- 4. УГОЛ К КАМЕРЕ (предпочитаем перед собой) local camForward = Camera.CFrame.LookVector local toTarget = (pos - Camera.CFrame.Position).Unit local angle = math.acos(math.clamp(camForward:Dot(toTarget), -1, 1)) local angleDeg = math.deg(angle) if angleDeg < 30 then score = score + 35 elseif angleDeg < 60 then score = score + 25 elseif angleDeg < 90 then score = score + 15 end -- 5. БОНУС ТЕКУЩЕЙ ЦЕЛИ (анти-дёрганье) if currentTarget == plr then local lockDuration = tick() - targetLockTime if lockDuration < TARGET_TIMEOUT then score = score + 50 + lockDuration * 5 end end -- 6. ШТРАФ ЗА ЧАСТЫЕ ПЕРЕКЛЮЧЕНИЯ local timeSinceSwitch = tick() - lastSwitchTime if timeSinceSwitch < SWITCH_DELAY and currentTarget ~= plr then score = score - 30 end return score end --====== ВЫБОР ЦЕЛИ ======-- local function findBestTarget() local best = nil local bestScore = -10000 for _, plr in ipairs(Players:GetPlayers()) do if plr ~= LocalPlayer then local score = getTargetScore(plr) if score > bestScore then bestScore = score best = plr end end end return best end --====== АТАКА ======-- local function executeAttack(target) local eye = getMyEye() if not eye then return false end local predicted = predictPosition(target) if not predicted then return false end local dir = (predicted - eye).Unit if dir.Magnitude < 0.01 then return false end local hr = game.ReplicatedStorage.Remotes:FindFirstChild("HitRequest") local ar = game.ReplicatedStorage.Remotes:FindFirstChild("AnimateHit") if hr then attackAttempts = attackAttempts + 1 hr:FireServer(eye, dir, target) if ar then ar:FireServer() end hitSuccesses = hitSuccesses + 1 return true end return false end --====== ГЛАВНЫЙ ЦИКЛ ======-- RunService.Heartbeat:Connect(function() local char = getChar(LocalPlayer) if not char then return end local hum = getHum(LocalPlayer) if not hum or hum.Health <= 0 then return end -- Поиск цели local target = findBestTarget() if not target then currentTarget = nil velHistory = {} return end -- Обновление истории скорости updateVelHistory(target) -- Смена цели if target ~= currentTarget then currentTarget = target targetLockTime = tick() lastSwitchTime = tick() velHistory = {} end -- Плавный поворот камеры (можно отключить) local predicted = predictPosition(currentTarget) if predicted then local targetCF = CFrame.new(Camera.CFrame.Position, predicted) Camera.CFrame = Camera.CFrame:Lerp(targetCF, 0.25) end -- Атака local now = tick() if now - lastHit >= HIT_COOLDOWN then if executeAttack(currentTarget) then lastHit = now end end end) -- Сброс при респавне LocalPlayer.CharacterAdded:Connect(function() lastHit = 0 currentTarget = nil velHistory = {} attackAttempts = 0 hitSuccesses = 0 end) -- Сброс при выходе игрока Players.PlayerRemoving:Connect(function(plr) if currentTarget == plr then currentTarget = nil velHistory = {} end end)