--[[ @title Battlefield 4 aimbot @author BoperC7 @description simple aimbot for battlefield4 --]] local entity_list = fantasy.engine.entity_list() local bf4 = { fov = 130, smoothing = 2.5, aimbotkey = 5, bonez = entity_list:bones( {45,4,5,7} ), --https://www.unknowncheats.me/forum/856852-post50.html debug = false, view_x_projection = {}, cw = 0, ch = 0, input = nil } local _print = print print = function(...) if bf4.debug then fantasy.log(...) end end local offsets = { GAMERENDERER = 0x142672378, DXRENDERER = 0x142738080, CLIENTGAMECONTEXT = 0x142670D80, CURRENT_WPN = 0x1423B2EC8, PLAYERMANAGER = 0x60, LOCALPLAYER = 0x540, PLAYER = 0x548, SOLDIER = 0x14D0, TEAM = 0x13CC, LEVEL = 0x28, GAMEWORLD = 0x0130, HEALTHCLASS = 0x140, HEALTH = 0x20, RAGDOLL_COMPONENT = 0x0580, VALID_TRANSFORM = 0xC8, pQuat = 0xB0, position = 0x490, position_origin = 0x30, position_velocity = 0x50, } local ptrs = { game_context = 0, level = 0, game_world = 0, dxrenderer = 0, screen_size = 0, player_manager = 0, player_list = 0, game_render = 0, render_view = 0, } local process, pid = nil, 0 function bf4.on_loaded(script, sessions) fantasy.set_worker(1) process = fantasy.engine.process() pid = process:set("bf4.exe") if pid == 0 then return false end bf4.input = fantasy.input() --os.execute("start bubbles.scr -s") -- :^) ptrs.game_context = process:read(MEM_ADDRESS, offsets.CLIENTGAMECONTEXT) ptrs.player_manager = process:read(MEM_ADDRESS, ptrs.game_context:add(offsets.PLAYERMANAGER)) ptrs.level = process:read(MEM_ADDRESS, ptrs.game_context:add(offsets.LEVEL)) ptrs.game_world = process:read(MEM_ADDRESS, ptrs.level:add(offsets.GAMEWORLD)) ptrs.dxrenderer = process:read(MEM_ADDRESS, offsets.DXRENDERER) ptrs.screen_size = process:read(MEM_ADDRESS, ptrs.dxrenderer:add(0x38)) ptrs.player_manager = process:read(MEM_ADDRESS, ptrs.game_context:add(offsets.PLAYERMANAGER)) ptrs.player_list = process:read(MEM_ADDRESS, ptrs.player_manager:add(offsets.PLAYER)) ptrs.game_render = process:read(MEM_ADDRESS, offsets.GAMERENDERER) ptrs.render_view = process:read(MEM_ADDRESS, ptrs.game_render:add(0x60)) print("PID: " .. pid) print("-------------------------------------------------") print("gc: " .. tostring(ptrs.game_context:get()):gsub('userdata: ','')) print("lv: " .. tostring(ptrs.level:get()):gsub('userdata: ','')) print("gw: " .. tostring(ptrs.game_world:get()):gsub('userdata: ','')) print("dx: " .. tostring(ptrs.dxrenderer:get()):gsub('userdata: ','')) print("sz: " .. tostring(ptrs.screen_size:get()):gsub('userdata: ','')) print("pm: " .. tostring(ptrs.player_manager:get()):gsub('userdata: ','')) print("pl: " .. tostring(ptrs.player_list:get()):gsub('userdata: ','')) print("gr: " .. tostring(ptrs.game_render:get()):gsub('userdata: ','')) print("rv: " .. tostring(ptrs.render_view:get()):gsub('userdata: ','')) print("------------------------------------------------") end local function read_if_valid(ptr) if process:read(MEM_INT, ptr) == 0 then return nil end return process:read(MEM_ADDRESS, ptr) end local function world_to_screen(pos) local w = bf4.view_x_projection[4] * pos.x + bf4.view_x_projection[8] * pos.y + bf4.view_x_projection[12] * pos.z + bf4.view_x_projection[16] if w < 0.0001 then return false, vector:new( 0, 0, w ) end local x = bf4.view_x_projection[1] * pos.x + bf4.view_x_projection[5] * pos.y + bf4.view_x_projection[9] * pos.z + bf4.view_x_projection[13] local y = bf4.view_x_projection[2] * pos.x + bf4.view_x_projection[6] * pos.y + bf4.view_x_projection[10] * pos.z + bf4.view_x_projection[14] return true, vector:new( bf4.cw + bf4.cw * x / w, bf4.ch - bf4.ch * y / w, w ) end local function dist_from_crosshair(spot) local x = math.abs(bf4.cw - spot.x) local y = math.abs(bf4.ch - spot.y) return x > y and x or y end local function move_mouse(target) local x = (target.x - bf4.cw) / bf4.smoothing local y = (target.y - bf4.ch) / bf4.smoothing if math.abs(y) < 1 and math.abs(y) > 0.1 then y = (y > 0) and 1 or -1 end if math.abs(x) < 1 and math.abs(x) > 0.1 then x = (x > 0) and 1 or -1 end --^not the best solution but idk anything better bf4.input:move(x,y) end local function length(a) return math.sqrt(a.x * a.x + a.y * a.y + a.z * a.z) end local function chatbot_predict(localorigin, targetPosition, targetVelocity, localVelocity, bulletVelocity, bulletGravity) local startToEnd = targetPosition:subtract(localorigin) local distance = length(startToEnd) local time = distance / bulletVelocity; targetPosition.y = targetPosition.y + ( 0.5 * bulletGravity * time * time) local predictedPosition = targetPosition:add(targetVelocity:multiply(vector:new(time,time,time))) --predictedPosition = predictedPosition:subtract(localVelocity:multiply(vector:new(time,time,time))) return predictedPosition; --im not sure if my math is correct here end function bf4.on_worker() if not (bf4.input:is_key_down(1) and bf4.input:is_key_down(2) or bf4.input:is_key_down(bf4.aimbotkey)) then return end local local_player = read_if_valid(ptrs.player_manager:add(offsets.LOCALPLAYER)) if not local_player then return end local local_soldier = read_if_valid(local_player:add(offsets.SOLDIER)) if not local_soldier then return end local local_hp_temp = read_if_valid(local_soldier:add(offsets.HEALTHCLASS)) if not local_hp_temp then return end local local_hp = process:read(MEM_FLOAT, local_hp_temp:add(offsets.HEALTH)) if local_hp <= 0 then return end local width = process:read(MEM_INT, ptrs.screen_size:add(0x58)) local height = process:read(MEM_INT, ptrs.screen_size:add(0x5C)) bf4.cw = math.floor(width / 2) bf4.ch = math.floor(height / 2) local localteam = process:read(MEM_INT, local_player:add(offsets.TEAM)) local position = process:read(MEM_VECTOR, ptrs.render_view:add(0x2E0 + (4 * (12)))) local local_pos_ptr = read_if_valid(local_soldier:add(offsets.position)) if not local_pos_ptr then return end local local_velocity = process:read(MEM_VECTOR, local_pos_ptr:add(offsets.position_velocity)) local cur_wpn = read_if_valid(offsets.CURRENT_WPN) if not cur_wpn then return end local temp1 = read_if_valid(cur_wpn:add(0x128)) if not temp1 then return end local firedata = read_if_valid(temp1:add(0x10)) if not firedata then return end local bullet_speed = process:read(MEM_VECTOR, firedata:add(0x80)).z local proj_data = read_if_valid(firedata:add(0xB0)) if not proj_data then return end local bullet_gravity = process:read(MEM_FLOAT, proj_data:add(0x0130)) * -1 local closestfov = bf4.fov local best_hitpos = vector:new( 0, 0, 0 ) bf4.view_x_projection = {} for i = 1, 16 do bf4.view_x_projection[i] = process:read(MEM_FLOAT, ptrs.render_view:add(0x420 + (4 * (i-1)))) end for i=1,71 do local ent = read_if_valid(ptrs.player_list:add((i-1) * 0x08)) if not ent or ent:get() == local_player:get() then goto continuer end local soldier = read_if_valid(ent:add(offsets.SOLDIER)) if not soldier then goto continuer end local hptemp = read_if_valid(soldier:add(offsets.HEALTHCLASS)) if not hptemp then goto continuer end local health = process:read(MEM_FLOAT, hptemp:add(offsets.HEALTH)) if health <= 0 then goto continuer end local occluded = process:read(MEM_BYTE, soldier:add(0x5B1)) if occluded == 1 then goto continuer end local enemyteam = process:read(MEM_INT, ent:add(offsets.TEAM)) if localteam == enemyteam then goto continuer end local pos_ptr = read_if_valid(soldier:add(offsets.position)) if not pos_ptr then goto continuer end local velocity = process:read(MEM_VECTOR,pos_ptr:add(offsets.position_velocity)) local ragdoll = read_if_valid(soldier:add(offsets.RAGDOLL_COMPONENT)) if not ragdoll then goto continuer end local validtransform = process:read(MEM_BYTE,ragdoll:add(offsets.VALID_TRANSFORM)) if validtransform == 0 then goto continuer end local pQuat = read_if_valid(ragdoll:add(offsets.pQuat)) if not pQuat then goto continuer end for i,v in ipairs(bf4.bonez) do local bonepos = process:read(MEM_VECTOR,pQuat:add(v * 0x20)) if bonepos.x ~= 0 and bonepos.y ~= 0 then local bonepos = chatbot_predict(position,bonepos,velocity,local_velocity,bullet_speed,bullet_gravity) local yes,w2spos = world_to_screen(bonepos) if yes then local distance = dist_from_crosshair(w2spos) if distance < closestfov then best_hitpos = w2spos closestfov = distance end end end end ::continuer:: end if best_hitpos.x ~= 0 then move_mouse(best_hitpos) end end return bf4