local imgui = require('imgui')
local vkeys = require('vkeys')
local ffi = require('ffi')
local memory = require('memory')
local M = {}
if type(GetBodyPartCoordinates) ~= 'function' then
local GetBonePosition = ffi.cast("int (__thiscall*)(void*, float*, int, bool)", 6177408)
function GetBodyPartCoordinates(boneId, ped)
if not doesCharExist(ped) then return 0, 0, 0 end
local pedPointer = getCharPointer(ped)
local coords = ffi.new("float[3]")
GetBonePosition(ffi.cast("void*", pedPointer), coords, boneId, true)
return coords[0], coords[1], coords[2]
end
end
local ab = {
enable = imgui.ImBool(false),
vis = imgui.ImBool(false),
partList = {'Nearest','Head','Neck','Body','Left Up Arm','Right Up Arm','Left Center Arm','Right Center Arm','Left Leg','Right Leg'},
partSel = imgui.ImInt(0),
boneMap = {8, 31, 3, 22, 32, 23, 33, 42, 52},
smooth = imgui.ImInt(3),
radius = imgui.ImInt(3),
dist = imgui.ImInt(35),
clist = imgui.ImBool(false),
stuned = imgui.ImBool(false),
pause = imgui.ImBool(false),
sniperOn = imgui.ImBool(false),
sniperVis = imgui.ImBool(false),
sniperList = {'Nearest','Head','Neck','Body','Right Up Arm','Left Up Arm','Right Center Arm','Left Center Arm','Left Leg','Right Leg'},
sniperSel = imgui.ImInt(0),
sniperMap = {8, 31, 3, 32, 22, 33, 23, 42, 52},
sniperSpd = imgui.ImInt(3),
sniperRad = imgui.ImInt(2),
sniperDist = imgui.ImInt(1000),
lockedPed = -1,
lockedX = 0, lockedY = 0, lockedZ = 0,
toggleKey = 82,
waitingKey = false,
smoothWpn = {[22]=true,[23]=true,[24]=true,[25]=true,[26]=true,[27]=true,[28]=true,[29]=true,[32]=true,[38]=true},
sniperWpn = {[34]=true},
stunAnims = {
'DAM_armL_frmBK','DAM_armL_frmFT','DAM_armL_frmLT',
'DAM_armR_frmBK','DAM_armR_frmFT','DAM_armR_frmRT',
'DAM_LegL_frmBK','DAM_LegL_frmFT','DAM_LegL_frmLT',
'DAM_LegR_frmBK','DAM_LegR_frmFT','DAM_LegR_frmRT',
'DAM_stomach_frmBK','DAM_stomach_frmFT','DAM_stomach_frmLT','DAM_stomach_frmRT'
},
getBoneFn = ffi.cast("int (__thiscall*)(void*, float*, int, bool)", 0x5E4280),
}
M.ab = ab
function IsSmoothWeapon()
return ab.smoothWpn[getCurrentCharWeapon(PLAYER_PED)] == true
end
function IsSniperWeapon()
return ab.sniperWpn[getCurrentCharWeapon(PLAYER_PED)] == true
end
function fix(angle)
if angle > math.pi then
angle = angle - math.pi * 2
elseif angle < -math.pi then
angle = angle + math.pi * 2
end
return angle
end
function GetBodyPartCoordinatesSmooth(id, handle)
if doesCharExist(handle) then
local pedptr = getCharPointer(handle)
local vec = ffi.new("float[3]")
ab.getBoneFn(ffi.cast("void*", pedptr), vec, id, true)
return vec[0], vec[1], vec[2]
end
return 0, 0, 0
end
function CheckStuned()
for k, v in pairs(ab.stunAnims) do
if isCharPlayingAnim(PLAYER_PED, v) then return false end
end
return true
end
function GetNearestBoneSmooth(handle)
local maxDist = 20000
local nearestBone = -1
local bones = {8, 31, 3, 22, 32, 23, 33, 42, 52}
for n = 1, 9 do
local crosshairPos = {convertGameScreenCoordsToWindowScreenCoords(339.1, 179.1)}
local bonePos = {GetBodyPartCoordinatesSmooth(bones[n], handle)}
local enPos = {convert3DCoordsToScreen(bonePos[1], bonePos[2], bonePos[3])}
local distance = math.sqrt((enPos[1] - crosshairPos[1])^2 + (enPos[2] - crosshairPos[2])^2)
if distance < maxDist then
nearestBone = bones[n]
maxDist = distance
end
end
return nearestBone
end
function GetTargetBoneSmooth(handle)
local sel = ab.partSel.v
if sel == 0 then
return GetNearestBoneSmooth(handle)
else
return ab.boneMap[sel] or 8
end
end
function GetNearestPedSmooth(fov)
local maxDistance = ab.dist.v
local nearestPED = -1
for i = 0, sampGetMaxPlayerId(true) do
if sampIsPlayerConnected(i) then
local find, handle = sampGetCharHandleBySampPlayerId(i)
if find and isCharOnScreen(handle) and not isCharDead(handle) then
local enPos = {GetBodyPartCoordinatesSmooth(GetTargetBoneSmooth(handle), handle)}
local myPos = {getActiveCameraCoordinates()}
local vector = {myPos[1]-enPos[1], myPos[2]-enPos[2], myPos[3]-enPos[3]}
local coeffZ = isWidescreenOnInOptions() and 0.0778 or 0.103
local angle = {
math.atan2(vector[2], vector[1]) + 0.04253,
math.atan2(math.sqrt(vector[1]^2 + vector[2]^2), vector[3]) - math.pi/2 - coeffZ
}
local view = {
fix(representIntAsFloat(readMemory(0xB6F258, 4, false))),
fix(representIntAsFloat(readMemory(0xB6F248, 4, false)))
}
local screenDist = math.sqrt((angle[1]-view[1])^2 + (angle[2]-view[2])^2) * 57.2957795131
if screenDist <= fov then
local myCharPos = {getCharCoordinates(PLAYER_PED)}
local dist3d = math.sqrt((enPos[1]-myCharPos[1])^2 + (enPos[2]-myCharPos[2])^2 + (enPos[3]-myCharPos[3])^2)
if dist3d < maxDistance then
nearestPED = handle
maxDistance = dist3d
end
end
end
end
end
return nearestPED
end
function SmoothAimbotThread()
while true do
wait(0)
if not ab.enable.v then goto smoothContinue end
if not isSampAvailable or isCharDead(PLAYER_PED) then goto smoothContinue end
local normalAim = IsSmoothWeapon() and isKeyDown(vkeys.VK_LBUTTON)
local cbugOn = rawget(_G, 'SP_cbugEnabled')
local cbugKey = rawget(_G, 'SP_cbugSecondaryKey') or 18
local cbugAim = cbugOn and cbugOn.v
and getCurrentCharWeapon(PLAYER_PED) == 24
and isKeyDown(vkeys.VK_RBUTTON)
and isKeyDown(cbugKey)
if not normalAim and not cbugAim then goto smoothContinue end
local handle = GetNearestPedSmooth(ab.radius.v)
if handle ~= -1 then
local _, myID = sampGetPlayerIdByCharHandle(PLAYER_PED)
local result, playerID = sampGetPlayerIdByCharHandle(handle)
if result then
if ab.stuned.v and not CheckStuned() then goto smoothContinue end
if ab.clist.v and sampGetPlayerColor(myID) == sampGetPlayerColor(playerID) then goto smoothContinue end
if ab.pause.v and sampIsPlayerPaused(playerID) then goto smoothContinue end
local myPos = {getActiveCameraCoordinates()}
local enPos = {GetBodyPartCoordinatesSmooth(GetTargetBoneSmooth(handle), handle)}
local coeffZ = isWidescreenOnInOptions() and 0.0778 or 0.103
local los = not ab.vis.v or isLineOfSightClear(myPos[1], myPos[2], myPos[3], enPos[1], enPos[2], enPos[3], true, true, false, true, true)
if los then
local vector = {myPos[1]-enPos[1], myPos[2]-enPos[2], myPos[3]-enPos[3]}
local angle = {
math.atan2(vector[2], vector[1]) + 0.04253,
math.atan2(math.sqrt(vector[1]^2 + vector[2]^2), vector[3]) - math.pi/2 - coeffZ
}
local view = {
fix(representIntAsFloat(readMemory(0xB6F258, 4, false))),
fix(representIntAsFloat(readMemory(0xB6F248, 4, false)))
}
local diff = {angle[1]-view[1], angle[2]-view[2]}
local step = {diff[1]/ab.smooth.v, diff[2]/ab.smooth.v}
setCameraPositionUnfixed(view[2]+step[2], view[1]+step[1])
end
end
end
::smoothContinue::
end
end
function GetNearestBoneSniper(ped)
local bones = {8, 31, 3, 32, 22, 33, 23, 42, 52}
local bestBone = 8
local bestDist = 999999
local sw, sh = getScreenResolution()
local cx, cy = sw/2, sh/2
for _, b in ipairs(bones) do
local x, y, z = GetBodyPartCoordinates(b, ped)
local sx, sy = convert3DCoordsToScreen(x, y, z)
if sx and sy then
local d = math.sqrt((sx-cx)^2 + (sy-cy)^2)
if d < bestDist then bestDist = d; bestBone = b end
end
end
return bestBone
end
function IsTargetStillValid(ped, radius)
if not doesCharExist(ped) or isCharDead(ped) or not isCharOnScreen(ped) then return false end
local myX, myY, myZ = getCharCoordinates(PLAYER_PED)
local boneId = (ab.sniperSel.v == 0) and GetNearestBoneSniper(ped) or (ab.sniperMap[ab.sniperSel.v] or 8)
local boneX, boneY, boneZ = GetBodyPartCoordinates(boneId, ped)
if boneId == 8 then boneZ = boneZ + 0.08 end
local dist = getDistanceBetweenCoords3d(myX, myY, myZ, boneX, boneY, boneZ)
if dist > ab.sniperDist.v or dist < 1.8 then return false end
local sw, sh = getScreenResolution()
local sx, sy = convert3DCoordsToScreen(boneX, boneY, boneZ)
if not sx then return false end
if math.sqrt((sx-sw/2)^2 + (sy-sh/2)^2) > (radius*5.8) then return false end
if ab.sniperVis.v then
local camX, camY, camZ = getActiveCameraCoordinates()
if not isLineOfSightClear(camX, camY, camZ, boneX, boneY, boneZ, true, true, false, true, true) then return false end
end
ab.lockedX, ab.lockedY, ab.lockedZ = boneX, boneY, boneZ
return true
end
function FindNewTarget(radius)
local nearestDist = ab.sniperDist.v
local nearestPed = -1
local bestX, bestY, bestZ = 0, 0, 0
local myX, myY, myZ = getCharCoordinates(PLAYER_PED)
local sw, sh = getScreenResolution()
local cx, cy = sw/2, sh/2
local fovRadius = radius * 5.8
for playerId = 0, sampGetMaxPlayerId(false) do
if sampIsPlayerConnected(playerId) then
local found, ped = sampGetCharHandleBySampPlayerId(playerId)
if found and doesCharExist(ped) and ped ~= PLAYER_PED and not isCharDead(ped) and isCharOnScreen(ped) then
local boneId = (ab.sniperSel.v == 0) and GetNearestBoneSniper(ped) or (ab.sniperMap[ab.sniperSel.v] or 8)
local boneX, boneY, boneZ = GetBodyPartCoordinates(boneId, ped)
if boneId == 8 then boneZ = boneZ + 0.08 end
local sx, sy = convert3DCoordsToScreen(boneX, boneY, boneZ)
if sx and sy then
local screenDist = math.sqrt((sx-cx)^2 + (sy-cy)^2)
if screenDist <= fovRadius then
local distToPed = getDistanceBetweenCoords3d(myX, myY, myZ, boneX, boneY, boneZ)
if distToPed < nearestDist and distToPed > 1.8 then
local canSee = true
if ab.sniperVis.v then
local camX, camY, camZ = getActiveCameraCoordinates()
canSee = isLineOfSightClear(camX, camY, camZ, boneX, boneY, boneZ, true, true, false, true, true)
end
if canSee then
nearestPed = ped
nearestDist = distToPed
bestX, bestY, bestZ = boneX, boneY, boneZ
end
end
end
end
end
end
end
return nearestPed, bestX, bestY, bestZ
end
function SniperAimbotThread()
local smoothTable = {
[1]=1.15,[2]=1.85,[3]=2.70,[4]=3.80,[5]=5.20,
[6]=7.00,[7]=9.50,[8]=13.0,[9]=18.0,[10]=26.0
}
while true do
wait(0)
if not ab.sniperOn.v then ab.lockedPed = -1; goto sniperContinue end
if not IsSniperWeapon() then ab.lockedPed = -1; goto sniperContinue end
if not isKeyDown(vkeys.VK_RBUTTON) then ab.lockedPed = -1; goto sniperContinue end
local targetValid = false
if ab.lockedPed ~= -1 then targetValid = IsTargetStillValid(ab.lockedPed, ab.sniperRad.v) end
if not targetValid then
local newPed, nx, ny, nz = FindNewTarget(ab.sniperRad.v)
if newPed ~= -1 then
ab.lockedPed = newPed
ab.lockedX, ab.lockedY, ab.lockedZ = nx, ny, nz
targetValid = true
else
ab.lockedPed = -1
end
end
if targetValid and ab.lockedPed ~= -1 then
local camX, camY, camZ = getActiveCameraCoordinates()
local dx = camX - ab.lockedX
local dy = camY - ab.lockedY
local dz = camZ - ab.lockedZ
local targetAngleH = math.atan2(dy, dx)
local hDist = math.sqrt(dx*dx + dy*dy)
local targetAngleV = math.atan2(hDist, dz) - math.pi/2
local camAngleH = fix(representIntAsFloat(readMemory(11989592, 4, false)))
local camAngleV = fix(representIntAsFloat(readMemory(11989576, 4, false)))
local divisor = (smoothTable[ab.sniperSpd.v] or 5.0) * 0.6
local stepH = (targetAngleH - camAngleH) / divisor
local stepV = (targetAngleV - camAngleV) / divisor
local deadzone = 0.00015
if math.abs(stepH) < deadzone then stepH = 0 end
if math.abs(stepV) < deadzone then stepV = 0 end
setCameraPositionUnfixed(camAngleV + stepV, camAngleH + stepH)
end
::sniperContinue::
end
end
M.SmoothAimbotThread = SmoothAimbotThread
M.SniperAimbotThread = SniperAimbotThread
M.IsSmoothWeapon = IsSmoothWeapon
M.IsSniperWeapon = IsSniperWeapon
function M.DrawLocal(SectionLabel, SmallNote, PF, XF, fontProggy, PR, PG, PB, getKeyName)
PF(fontProggy)
imgui.Spacing()
SectionLabel("AIMBOT LOCAL")
imgui.Checkbox("Enable Local##local", ab.enable)
imgui.Checkbox("Visible Check##local", ab.vis)
imgui.Spacing()
imgui.PushItemWidth(220)
imgui.Combo("Aimbot Part##local", ab.partSel, ab.partList, #ab.partList)
imgui.PopItemWidth()
imgui.Spacing()
imgui.Separator()
imgui.Spacing()
SectionLabel("PARAMETERS")
imgui.PushItemWidth(220)
imgui.SliderInt("Smooth Aimbot##local", ab.smooth, 1, 5)
imgui.SliderInt("Aimbot Radius##local", ab.radius, 1, 5)
imgui.SliderInt("Aimbot Distance##local", ab.dist, 1, 35)
imgui.PopItemWidth()
imgui.Spacing()
imgui.Separator()
imgui.Spacing()
SectionLabel("SHORTCUT ON/OFF")
imgui.Text("Toggle Key:")
imgui.SameLine()
imgui.TextColored(imgui.ImVec4(PR, PG, PB, 1), getKeyName(ab.toggleKey))
if imgui.Button(ab.waitingKey and "Press any key..." or "Change Key", imgui.ImVec2(160, 28)) then
ab.waitingKey = true
end
XF(fontProggy)
end
function M.DrawSniper(SectionLabel, SmallNote, PF, XF, fontProggy, PR, PG, PB, getKeyName)
PF(fontProggy)
imgui.Spacing()
SectionLabel("AIMBOT SNIPER")
imgui.Checkbox("Enable Sniper##sniper", ab.sniperOn)
imgui.Checkbox("Visible Check##sniper", ab.sniperVis)
imgui.Spacing()
imgui.PushItemWidth(220)
imgui.Combo("Aimbot Part##sniper", ab.sniperSel, ab.sniperList, #ab.sniperList)
imgui.PopItemWidth()
imgui.Spacing()
imgui.Separator()
imgui.Spacing()
SectionLabel("PARAMETERS")
imgui.PushItemWidth(220)
imgui.SliderInt("Smooth Aimbot##sniper", ab.sniperSpd, 1, 5)
imgui.SliderInt("Aimbot Radius##sniper", ab.sniperRad, 1, 2)
imgui.SliderInt("Aimbot Distance##sniper", ab.sniperDist, 1, 1000)
imgui.PopItemWidth()
XF(fontProggy)
end
function M.HandleKeys()
if ab.waitingKey then
for k = 1, 255 do
if wasKeyPressed(k) and k > 4 then
ab.toggleKey = k
ab.waitingKey = false
return true -- needs save
end
end
end
if wasKeyPressed(ab.toggleKey) then
ab.enable.v = not ab.enable.v
return true
end
return false
end
return M