-- slapfix_best.lua for RakSAMP (SAMP 0.3.7)
-- Собрано из лучших частей: Drags, dimiano v2, -DRP-, safe_anim
-- API: RakSAMP (setPosition, getPosition, updateSync, getRotation, getHealth, setHealth, runCommand)
local sampev = require("samp.events")
require("addon")
-- ============================================================
-- КОНФИГУРАЦИЯ
-- ============================================================
local CFG = {
mode = 2, -- 1 = ignore slap | 2 = emulate fall
minRise = 0.8, -- минимальная высота подъёма для слапа
maxRise = 46, -- максимум (выше = телепорт, не слап)
maxHorDist = 0.25, -- макс горизонтальное смещение при слапе
fallAccel = 1.18, -- коэффициент ускорения падения
minSpeed = 0.18, -- начальная скорость падения
maxSpeed = 1.4, -- максимальная скорость падения
forwardTicks = 14, -- тиков движения вперёд после падения
forwardMult = 0.14, -- скорость движения вперёд
arcRadius = 0.35, -- радиус дуги при движении вперёд
loopMs = 50, -- интервал главного цикла (мс)
noiseZ = 0.006, -- шум вертикальной скорости в пакете
}
-- Рандомизация при старте (анти-детект)
math.randomseed(os.time())
CFG.fallAccel = CFG.fallAccel * (0.94 + math.random() * 0.12)
CFG.minSpeed = CFG.minSpeed * (0.90 + math.random() * 0.20)
CFG.forwardTicks = math.random(10, 18)
CFG.arcRadius = math.random() * 0.55
-- ============================================================
-- ТАБЛИЦА УРОНА (высота -> HP)
-- ============================================================
local HEIGHT_DAMAGE = {
[0]=0,[1]=0,[2]=0,[3]=0,[4]=5,[5]=0,[6]=5,[7]=5,[8]=5,[9]=5,
[10]=19,[11]=21,[12]=23,[13]=25,[14]=28,[15]=29,[16]=31,
[17]=33,[18]=35,[19]=36,[20]=38,[21]=40,[22]=41,[23]=42,
[24]=44,[25]=45,[26]=46
}
-- ============================================================
-- СОСТОЯНИЕ
-- ============================================================
local slap = {
active = false, -- падаем прямо сейчас
forward = false, -- движение вперёд после приземления
fwdTick = 0,
speed = CFG.minSpeed,
-- точки
highX=0, highY=0, highZ=0, -- позиция сразу после слапа (высшая)
targX=0, targY=0, targZ=0, -- целевая (земля)
arcX=0, arcY=0, -- начало арки движения вперёд
angle=0, -- угол бота в радианах
}
-- ============================================================
-- УТИЛИТЫ
-- ============================================================
local function dist2d(x1,y1, x2,y2)
local dx,dy = x2-x1, y2-y1
return math.sqrt(dx*dx + dy*dy)
end
local function clamp(v, lo, hi)
if v < lo then return lo end
if v > hi then return hi end
return v
end
local function applyDamage(height)
local dmg = HEIGHT_DAMAGE[math.floor(height)] or 0
if dmg <= 0 then return end
local hp = getHealth()
local newHp = hp - dmg
if newHp > 0 then
setHealth(newHp)
else
setHealth(0)
runCommand('!kill')
end
end
local function resetSlap()
slap.active = false
slap.forward = false
slap.fwdTick = 0
slap.speed = CFG.minSpeed
end
-- ============================================================
-- ГЛАВНЫЙ ЦИКЛ
-- ============================================================
local function slapLoop()
while true do
if slap.active then
local cx, cy, cz = getPosition()
if cz <= slap.targZ + 0.05 then
-- ===== ПРИЗЕМЛЕНИЕ =====
local height = slap.highZ - slap.targZ
setPosition(slap.targX, slap.targY, slap.targZ)
updateSync()
applyDamage(height)
slap.active = false
-- движение вперёд только при средней высоте
if height >= 3.5 and height <= 11.0 then
slap.fwdTick = 0
slap.arcX = slap.targX
slap.arcY = slap.targY
slap.angle = getRotation() * (math.pi / 180) * -1
slap.forward = true
end
else
-- ===== ПАДЕНИЕ =====
if slap.speed < CFG.maxSpeed then
slap.speed = clamp(slap.speed * CFG.fallAccel, CFG.minSpeed, CFG.maxSpeed)
end
local newZ = math.max(cz - slap.speed, slap.targZ)
setPosition(cx, cy, newZ)
updateSync()
end
elseif slap.forward then
-- ===== ДВИЖЕНИЕ ВПЕРЁД (арка) =====
slap.fwdTick = slap.fwdTick + 1
if slap.fwdTick > CFG.forwardTicks then
resetSlap()
else
local t = slap.fwdTick / CFG.forwardTicks
local arc = CFG.arcRadius * math.sin(t * math.pi)
local ang = slap.angle + (math.random() - 0.5) * 0.18 -- лёгкий шум угла
local step = CFG.forwardMult
local nx = slap.arcX + math.cos(ang) * step * slap.fwdTick + math.sin(ang) * arc
local ny = slap.arcY + math.sin(ang) * step * slap.fwdTick - math.cos(ang) * arc
local _, _, cz2 = getPosition()
setPosition(nx, ny, cz2)
updateSync()
end
end
wait(CFG.loopMs + math.random(-8, 8)) -- небольшой рандом интервала
end
end
-- ============================================================
-- ПЕРЕХВАТ СЛАПА / ТЕЛЕПОРТА
-- ============================================================
function sampev.onSetPlayerPos(pos)
-- Если уже летим — обновляем только targetZ
if slap.active then
if pos.z < slap.highZ then
slap.targZ = pos.z
end
return false
end
local cx, cy, cz = getPosition()
local d2 = dist2d(cx, cy, pos.x, pos.y)
local dz = pos.z - cz
if d2 < CFG.maxHorDist and dz > CFG.minRise and dz < CFG.maxRise then
-- ===== СЛАП =====
if CFG.mode == 1 then
print("[SlapFix] Slap ignored (mode 1)")
return false
end
print("[SlapFix] Slap detected | height=" .. string.format("%.2f", dz))
slap.speed = CFG.minSpeed
slap.forward = false
slap.fwdTick = 0
slap.highX, slap.highY, slap.highZ = pos.x, pos.y, pos.z
slap.targX, slap.targY, slap.targZ = cx, cy, cz
slap.active = true
return false -- блокируем мгновенный телепорт сервера
elseif dz > CFG.maxRise and d2 < 5 then
-- ===== ТЕЛЕПОРТ В ВОЗДУХ =====
print("[SlapFix] Teleport in air detected | dz=" .. string.format("%.2f", dz))
slap.speed = CFG.minSpeed
slap.forward = false
slap.highX, slap.highY, slap.highZ = pos.x, pos.y, pos.z
slap.targX, slap.targY, slap.targZ = pos.x, pos.y, cz
slap.active = true
return false
end
end
-- ============================================================
-- ПАТЧ ИСХОДЯЩИХ ПАКЕТОВ (скорость + анимация)
-- ============================================================
function sampev.onSendPlayerSync(data)
if CFG.mode ~= 2 then return end
if slap.active then
-- Вертикальная скорость с шумом (как реальное падение)
data.moveSpeed.z = -(slap.speed / 2.8) + (math.random() - 0.5) * CFG.noiseZ
-- Анимация падения
if data.animationId ~= nil then
data.animationId = 1130 -- FALL_fall (PED)
data.animationFlags = 0
end
elseif slap.forward then
-- Лёгкое движение вперёд
local noise = (math.random() - 0.5) * 0.008
data.moveSpeed.x = 0.018 + noise
data.moveSpeed.y = 0.018 + noise
-- Анимация бега
if data.animationId ~= nil then
data.animationId = 1231 -- RUN_player (PED)
data.animationFlags = 0
end
end
end
-- ============================================================
-- КОМАНДЫ
-- ============================================================
function onRunCommand(cmd)
local args = {}
for a in cmd:gmatch("%S+") do table.insert(args, a) end
if args[1] == '!slapmode' then
local arg = args[2]
if arg == "1" or arg == "2" then
CFG.mode = tonumber(arg)
print("[SlapFix] Mode set: " .. arg .. (arg=="1" and " (ignore)" or " (emulate)"))
else
print("[SlapFix] Usage: !slapmode 1|2 (1=ignore, 2=emulate)")
end
return false
end
if args[1] == '!slapinfo' then
print("[SlapFix] active=" .. tostring(slap.active)
.. " | forward=" .. tostring(slap.forward)
.. " | speed=" .. string.format("%.3f", slap.speed)
.. " | mode=" .. CFG.mode)
return false
end
end
-- ============================================================
-- ЗАПУСК
-- ============================================================
function onLoad()
newTask(function()
slapLoop()
end)
print("[SlapFix BEST] Loaded | mode=" .. CFG.mode)
print("[SlapFix BEST] Commands: !slapmode 1|2 | !slapinfo")
end