Shows:
- hitboxes (trace, drone, enemies and projectiles)
- enemy hp and glitch level
- tile hp and glitch level
- enemy and tile cooldown for drill, glitch and grapple
Works on latest version of the game
SCREEN_W = 1440
SCREEN_H = 810
function process_trace_skewer(character_addr, color, tile_map)
-- print(string.format("sprite %012x", sprite_addr))
process_character(character_addr, 0xff0000ff)
local mDrill = memory.readu64(character_addr + 0x248)
local mGlitchRay = memory.readu64(character_addr + 0x250)
local mGrapple = memory.readu64(character_addr + 0x258)
if mDrill ~= 0 then
process_weapon_skewer(mDrill, color, tile_map)
end
if mGlitchRay ~= 0 then
process_weapon_skewer(mGlitchRay, color, tile_map)
end
if mGrapple ~= 0 then
process_weapon_skewer(mGrapple, color, tile_map)
end
end
function process_weapon_skewer(weapon_addr, color, tile_map)
local mSkewerList = memory.readu64(weapon_addr + 0x48)
local mCharacterSkewerList = memory.readu64(mSkewerList + 0x10)
local mTileSkewerList = memory.readu64(mSkewerList + 0x18)
-- print(string.format("mTileSkewerList %012x", mTileSkewerList))
local mCharacterSkewerList_size = memory.readu32(mCharacterSkewerList + 0x18)
-- print(mTileSkewerList_size)
for i=0,mCharacterSkewerList_size-1 do
local characterSkewerInfo = memory.readu64(mCharacterSkewerList + 0x20 + i*0x08)
local characterSkewerChar = memory.readu64(characterSkewerInfo + 0x10)
local characterSkewerDamageFrame = memory.readf(characterSkewerInfo + 0x18)
-- print("tile index ", tileSkewerIndex)
-- print("tile damage ", tileSkewerDamageFrame)
local char_x, char_y = get_char_coords(characterSkewerChar)
gui.text(char_x, char_y+32, string.format("%.2f", characterSkewerDamageFrame), 0xff000000, 0, 0, 16)
gui.text(char_x+2, char_y+32+2, string.format("%.2f", characterSkewerDamageFrame), 0xff000000, 0, 0, 16)
gui.text(char_x+1, char_y+32+1, string.format("%.2f", characterSkewerDamageFrame), 0xffffffff, 0, 0, 16)
end
local mTileSkewerList_size = memory.readu32(mTileSkewerList + 0x18)
-- print(mTileSkewerList_size)
for i=0,mTileSkewerList_size-1 do
local tileSkewerInfo = memory.readu64(mTileSkewerList + 0x20 + i*0x08)
local tileSkewerIndex = memory.reads32(tileSkewerInfo + 0x10)
local tileSkewerDamageFrame = memory.readf(tileSkewerInfo + 0x14)
-- print("tile index ", tileSkewerIndex)
-- print("tile damage ", tileSkewerDamageFrame)
local tile_x, tile_y = get_tile_coords(tile_map, tileSkewerIndex)
gui.text(tile_x, tile_y+16, string.format("%.2f", tileSkewerDamageFrame), 0xff000000, 0, 0, 16)
gui.text(tile_x+2, tile_y+16+2, string.format("%.2f", tileSkewerDamageFrame), 0xff000000, 0, 0, 16)
gui.text(tile_x+1, tile_y+16+1, string.format("%.2f", tileSkewerDamageFrame), 0xffffffff, 0, 0, 16)
end
end
function get_char_coords(character_addr)
local sprite_addr = memory.readu64(character_addr + 0x10)
local collision_addr = sprite_addr + 0xc8
local mType = memory.readu32(collision_addr + 0x00)
-- Weird detect of multisprite
if mType == 0 then
collision_addr = collision_addr - 0x08
mType = memory.readu32(collision_addr + 0x00)
end
local mCenter_X = memory.readf(collision_addr + 0x10)
local mCenter_Y = memory.readf(collision_addr + 0x14)
local mExtends_X = memory.readf(collision_addr + 0x20)
local mExtends_Y = memory.readf(collision_addr + 0x24)
local center_x = ((mCenter_X - global_camera_x) * SCREEN_W) / global_native_w
local center_y = ((mCenter_Y - global_camera_y) * SCREEN_H) / global_native_h
local width = (mExtends_X * SCREEN_W) / global_native_w
local height = (mExtends_Y * SCREEN_H) / global_native_h
local x0 = center_x - width / 2
local y0 = center_y - height / 2
return x0, y0
end
function get_tile_coords(tile_map, tile_index)
local tile_map_tiles = memory.readu64(tile_map + 0x20)
local tile_map_tiles_size = memory.readu32(tile_map_tiles + 0x18)
-- print(tile_map_tiles_size)
local tile_map_tile = tile_map_tiles + 0x20 + tile_index*0x30
-- print(string.format("%012x", tile_map_tile))
local tile_bounds_x = memory.readf(tile_map_tile+0x0c)
local tile_bounds_y = memory.readf(tile_map_tile+0x10)
local tile_x = ((tile_bounds_x - global_camera_x) * SCREEN_W) / global_native_w
local tile_y = ((tile_bounds_y - global_camera_y) * SCREEN_H) / global_native_h
return tile_x, tile_y
end
function process_character(character_addr, color)
-- print(string.format("sprite %012x", sprite_addr))
local mPosition_X = memory.readf(character_addr + 0x18)
local mPosition_Y = memory.readf(character_addr + 0x1c)
local mSprite = memory.readu64(character_addr + 0x10)
local x0, y0 = process_sprite(mSprite, color)
local mHitPoints = memory.reads32(character_addr + 0x78)
local mMaxHitPoints = memory.reads32(character_addr + 0x7c)
local mGlitchPoints = memory.reads32(character_addr + 0x80)
local mMaxGlitchPoints = memory.reads32(character_addr + 0x84)
-- local pos_x = ((mPosition_X - global_camera_x) * SCREEN_W) / global_native_w
-- local pos_y = ((mPosition_Y - global_camera_y) * SCREEN_H) / global_native_h
if mHitPoints ~= -1 then
gui.text(x0, y0, string.format("%d", mHitPoints), 0xff000000, 0, 0, 16)
gui.text(x0+2, y0+2, string.format("%d", mHitPoints), 0xff000000, 0, 0, 16)
gui.text(x0+1, y0+1, string.format("%d", mHitPoints), 0xffffffff, 0, 0, 16)
end
if mGlitchPoints ~= 0 then
gui.text(x0, y0+16, string.format("%d", mGlitchPoints), 0xff000000, 0, 0, 16)
gui.text(x0+2, y0+16+2, string.format("%d", mGlitchPoints), 0xff000000, 0, 0, 16)
gui.text(x0+1, y0+16+1, string.format("%d", mGlitchPoints), 0xffffffff, 0, 0, 16)
end
end
function process_sprite(sprite_addr, color)
-- print(string.format("sprite %012x", sprite_addr))
local mPosition_X = memory.readf(sprite_addr + 0x38)
local mPosition_Y = memory.readf(sprite_addr + 0x3c)
return process_collision(sprite_addr + 0xc8, color)
end
function process_collision(collision_addr, color)
local mType = memory.readu32(collision_addr + 0x00)
-- Weird detect of multisprite
if mType == 0 then
collision_addr = collision_addr - 0x08
mType = memory.readu32(collision_addr + 0x00)
end
local mCollisionFlags = memory.readu32(collision_addr + 0x04)
local mName = memory.readu32(collision_addr + 0x08)
local mCenter_X = memory.readf(collision_addr + 0x10)
local mCenter_Y = memory.readf(collision_addr + 0x14)
local mChildCollidables = memory.readu64(collision_addr + 0x18)
local mExtends_X = memory.readf(collision_addr + 0x20)
local mExtends_Y = memory.readf(collision_addr + 0x24)
local mRadius = memory.readf(collision_addr + 0x28)
local mAngle = memory.readf(collision_addr + 0x2c)
local THCollidableType = {
NONE = 0,
POINT = 1,
LINESEGMENT = 2,
RECTANGLE = 3,
ORIENTEDRECTANGLE = 4,
CIRCLE = 5,
MULTI = 6
}
-- print("sprite ", mCenter_X, " - ", mCenter_Y)
-- print("sprite type ", mType)
local center_x = ((mCenter_X - global_camera_x) * SCREEN_W) / global_native_w
local center_y = ((mCenter_Y - global_camera_y) * SCREEN_H) / global_native_h
local width = (mExtends_X * SCREEN_W) / global_native_w
local height = (mExtends_Y * SCREEN_H) / global_native_h
local x0 = center_x - width / 2
local y0 = center_y - height / 2
if mType == THCollidableType.RECTANGLE then
-- print("rect ", x0, " - ", y0)
gui.rectangle(x0, y0, width, height, 1, color & 0x60ffffff, 1)
gui.rectangle(x0, y0, width, height, 1, color, 0)
end
if mType == THCollidableType.ORIENTEDRECTANGLE then
local s = math.sin(mAngle)
local c = math.cos(mAngle)
local x0 = (-width / 2) * c - (-height/2) * s + center_x
local y0 = (-width / 2) * s + (-height/2) * c + center_y
local x1 = (width / 2) * c - (-height/2) * s + center_x
local y1 = (width / 2) * s + (-height/2) * c + center_y
local x2 = (width / 2) * c - (height/2) * s + center_x
local y2 = (width / 2) * s + (height/2) * c + center_y
local x3 = (-width / 2) * c - (height/2) * s + center_x
local y3 = (-width / 2) * s + (height/2) * c + center_y
-- print("no rot ", center_x - width / 2, " - ", center_y -height/2, " angle ", angle)
-- print("new rot ", x0, " - ", y0)
gui.quad(x0, y0, x1, y1, x2, y2, x3, y3, 1, color & 0x60ffffff, 1)
gui.quad(x0, y0, x1, y1, x2, y2, x3, y3, 1, color, 0)
end
if mType == THCollidableType.CIRCLE then
gui.ellipse(center_x, center_y, width/2, height/2, 1, color & 0x60ffffff, 1)
gui.ellipse(center_x, center_y, width/2, height/2, 1, color, 0)
end
if mType == THCollidableType.MULTI then
-- print(string.format("%012x", mChildCollidables))
local mChildCollidables_size = memory.readu32(mChildCollidables + 0x18)
-- print(mChildCollidables_size)
for i=0,mChildCollidables_size-1 do
local childCollidable = mChildCollidables + 0x20 + i*0x30
-- print(string.format("%012x", childCollidable))
x0, y0 = process_collision(childCollidable, color)
end
end
return x0, y0
end
function draw_projectiles(THGameplayState)
local mEffectsManager = memory.readu64(THGameplayState + 0xb8)
-- print(string.format("mEffectsManager %012x", mEffectsManager))
local mLayers = memory.readu64(mEffectsManager + 0x10)
-- print(string.format("mLayers %012x", mLayers))
local mLayer_size = memory.readu32(mLayers + 0x18)
-- print(string.format("mLayer_size %d", mLayer_size))
local mLayer0 = memory.readu64(mLayers + 0x20)
local mLayer1 = memory.readu64(mLayers + 0x28)
-- print(string.format("mLayer0 %012x", mLayer0))
local lProjectiles = memory.readu64(mLayer1 + 0x28)
local lProjectiles_size = memory.readu32(lProjectiles + 0x20)
-- print(lProjectiles_size)
local lProjectiles_array = memory.readu64(lProjectiles + 0x10)
-- print(string.format("lProjectiles_array %012x", lProjectiles_array))
for i=0,lProjectiles_size-1 do
local lProjectile = memory.readu64(lProjectiles_array + 0x20 + i*0x08)
-- print(string.format("lProjectile %012x", lProjectile))
local lProjectile_size = memory.readu32(lProjectile + 0x20)
-- print(lProjectile_size)
local lProjectile_array = memory.readu64(lProjectile + 0x10)
-- print(string.format("lProjectile_array %012x", lProjectiles_array))
for i=0,lProjectile_size-1 do
local thProjectile = memory.readu64(lProjectile_array + 0x20 + i*0x08)
-- print(string.format("thProjectile %012x", thProjectile))
local thProjectile_sprite = memory.readu64(thProjectile + 0x20)
-- local thProjectile_sprite = thProjectile + 0x178
process_sprite(thProjectile_sprite, 0xffff00ff)
end
end
end
function draw_sprite_list(list, color)
local list_size = memory.readu32(list + 0x20)
-- print(list_size)
local list_array = memory.readu64(list + 0x10)
-- print(string.format("%012x", list_array))
for i=0,list_size-1 do
local item = memory.readu64(list_array + 0x20 + i*0x08)
local item_mSprite = memory.readu64(item + 0x10)
-- print(string.format("%012x", creature))
process_sprite(item_mSprite, color)
end
end
function draw_creature_list(list, color)
local list_size = memory.readu32(list + 0x20)
-- print(list_size)
local list_array = memory.readu64(list + 0x10)
-- print(string.format("%012x", list_array))
for i=0,list_size-1 do
local item = memory.readu64(list_array + 0x20 + i*0x08)
process_character(item, color)
end
end
function draw_damageable_tile(tile)
local tile_index = memory.readu32(tile + 0x28)
local tile_destructed = memory.readu32(tile + 0x3c)
local tile_hp = memory.readu32(tile + 0x44)
local tile_max_hp = memory.readu32(tile + 0x48)
local tile_heat = memory.readf(tile + 0x4c)
local tile_passable = memory.readu32(tile + 0x50)
local tile_map = memory.readu64(tile + 0x18)
local tile_map_tiles = memory.readu64(tile_map + 0x20)
local tile_map_tiles_size = memory.readu32(tile_map_tiles + 0x18)
-- print(tile_map_tiles_size)
local tile_map_tile = tile_map_tiles + 0x20 + tile_index*0x30
-- print(string.format("%012x", tile_map_tile))
local tile_bounds_x = memory.readf(tile_map_tile+0x0c)
local tile_bounds_y = memory.readf(tile_map_tile+0x10)
local tile_bounds_w = memory.readf(tile_map_tile+0x14)
local tile_bounds_h = memory.readf(tile_map_tile+0x18)
local tile_x = ((tile_bounds_x - global_camera_x) * SCREEN_W) / global_native_w
local tile_y = ((tile_bounds_y - global_camera_y) * SCREEN_H) / global_native_h
local tile_width = (tile_bounds_w * SCREEN_W) / global_native_w
local tile_height = (tile_bounds_h * SCREEN_H) / global_native_h
if tile_passable == 1 or tile_destructed == 1 then
gui.rectangle(tile_x, tile_y, tile_width, tile_height, 1, 0xffffff00)
else
gui.rectangle(tile_x, tile_y, tile_width, tile_height, 1, 0x60ffff00, 1)
gui.rectangle(tile_x, tile_y, tile_width, tile_height, 1, 0xffffff00, 0)
gui.text(tile_x, tile_y, string.format("%d", tile_hp), 0xff000000, 0, 0, 16)
gui.text(tile_x+2, tile_y+2, string.format("%d", tile_hp), 0xff000000, 0, 0, 16)
gui.text(tile_x+1, tile_y+1, string.format("%d", tile_hp), 0xffffffff, 0, 0, 16)
-- if tile_heat > 0 then
-- gui.text(tile_x, tile_y+16, string.format("%.0f", tile_heat*100), 0xffffffff, 0, 0, 20)
-- end
end
end
function process_glitch_manager(glitch)
local mTileGroups = memory.readu64(glitch + 0x40)
local mTileGroups_size = memory.readu32(mTileGroups + 0x20)
-- print("mTileGroups_size ", mTileGroups_size)
local mTileGroups_array = memory.readu64(mTileGroups + 0x10)
-- print(string.format("damage array %012x", mDamageableTiles_array))
for i=0,mTileGroups_size-1 do
local tile_group = memory.readu64(mTileGroups_array + 0x20 + i*0x08)
-- print(string.format("tile_group %012x", tile_group))
local tile_list = memory.readu64(tile_group + 0x10)
local tile_list_size = memory.readu32(tile_list + 0x20)
-- print("tile_list_size ", tile_list_size)
local tile_list_array = memory.readu64(tile_list + 0x10)
-- print(string.format("damage array %012x", mDamageableTiles_array))
for j=0,tile_list_size-1 do
local tile = memory.readu64(tile_list_array + 0x20 + j*0x08)
-- print(string.format("tile %012x", tile))
local tile_index = memory.readu32(tile + 0x58)
-- print(string.format("tile_index %d", tile_index))
local tile_glitch = memory.reads32(tile + 0x6c)
local tile_max_glitch = memory.reads32(tile + 0x70)
local tile_cd = memory.readf(tile + 0x7c)
local tile_map = memory.readu64(tile + 0x28)
local tile_map_tiles = memory.readu64(tile_map + 0x20)
local tile_map_tiles_size = memory.readu32(tile_map_tiles + 0x18)
-- print("tile_map_tiles_size ", tile_map_tiles_size)
local tile_map_tile = tile_map_tiles + 0x20 + tile_index*0x30
-- print(string.format("%012x", tile_map_tile))
local tile_bounds_x = memory.readf(tile_map_tile+0x0c)
local tile_bounds_y = memory.readf(tile_map_tile+0x10)
local tile_bounds_w = memory.readf(tile_map_tile+0x14)
local tile_bounds_h = memory.readf(tile_map_tile+0x18)
local tile_x = ((tile_bounds_x - global_camera_x) * SCREEN_W) / global_native_w
local tile_y = ((tile_bounds_y - global_camera_y) * SCREEN_H) / global_native_h
local tile_width = (tile_bounds_w * SCREEN_W) / global_native_w
local tile_height = (tile_bounds_h * SCREEN_H) / global_native_h
gui.rectangle(tile_x, tile_y, tile_width, tile_height, 1, 0x60ff00ff, 1)
gui.rectangle(tile_x, tile_y, tile_width, tile_height, 1, 0xffff00ff, 0)
gui.text(tile_x, tile_y, string.format("%d", tile_glitch), 0xff000000, 0, 0, 16)
gui.text(tile_x+2, tile_y+2, string.format("%d", tile_glitch), 0xff000000, 0, 0, 16)
gui.text(tile_x+1, tile_y+1, string.format("%d", tile_glitch), 0xffffffff, 0, 0, 16)
if tile_cd > 0 then
gui.text(tile_x, tile_y+16, string.format("%.3f", tile_cd), 0xff000000, 0, 0, 16)
gui.text(tile_x+2, tile_y+18, string.format("%.3f", tile_cd), 0xff000000, 0, 0, 16)
gui.text(tile_x+1, tile_y+17, string.format("%.3f", tile_cd), 0xffffffff, 0, 0, 16)
end
end
end
end
callback.onPaint(function ()
local THGameplayState = memory.readu64(memory.baseAddress("AxiomVerge") + 0x729020)
THGameplayState = memory.readu64(THGameplayState + 0x78)
THGameplayState = memory.readu64(THGameplayState + 0x00)
THGameplayState = memory.readu64(THGameplayState + 0xe0)
THGameplayState = memory.readu64(THGameplayState + 0x18)
-- local THGameplayState = memory.readu64(memory.baseAddress("AxiomVerge") + 0x732f20)
-- print(string.format("%012x", memory.baseAddress("AxiomVerge")))
-- print(string.format("%012x", THGameplayState))
local mCamera = memory.readu64(THGameplayState + 0x100)
-- print(string.format("%012x", mCamera))
local mCamera_mCurrentCenter_X = memory.readf(mCamera + 0x18)
local mCamera_mCurrentCenter_Y = memory.readf(mCamera + 0x1c)
global_native_w = memory.readf(mCamera + 0x38)
global_native_h = memory.readf(mCamera + 0x3c)
local mCamera_mCurrentScale = memory.readf(mCamera + 0x44)
global_native_w = global_native_w * mCamera_mCurrentScale
global_native_h = global_native_h * mCamera_mCurrentScale
global_camera_x = mCamera_mCurrentCenter_X - global_native_w / 2
global_camera_y = mCamera_mCurrentCenter_Y - global_native_h / 2
local mCurrentRoom = memory.readu64(THGameplayState + 0xf8)
local mCurrentRoom_mTileMap = memory.readu64(mCurrentRoom + 0x20)
local mCurrentRoom_mCreatures = memory.readu64(mCurrentRoom + 0x40)
draw_creature_list(mCurrentRoom_mCreatures, 0xffff0000)
local mCurrentRoom_mItems = memory.readu64(mCurrentRoom + 0x58)
draw_sprite_list(mCurrentRoom_mItems, 0xff00ff00)
local mCurrentRoom_mConsumables = memory.readu64(mCurrentRoom + 0x68)
draw_sprite_list(mCurrentRoom_mConsumables, 0xff00ff00)
draw_projectiles(THGameplayState)
local mCurrentRoom_mDamageableTiles = memory.readu64(mCurrentRoom + 0xa0)
local mDamageableTiles_size = memory.readu32(mCurrentRoom_mDamageableTiles + 0x20)
-- print("damage tiles ", mDamageableTiles_size)
local mDamageableTiles_array = memory.readu64(mCurrentRoom_mDamageableTiles + 0x10)
-- print(string.format("damage array %012x", mDamageableTiles_array))
for i=0,mDamageableTiles_size-1 do
local tile = memory.readu64(mDamageableTiles_array + 0x20 + i*0x08)
-- print(string.format("tile %012x", tile))
draw_damageable_tile(tile)
end
local mCurrentRoom_mGlitchManager = memory.readu64(mCurrentRoom + 0xb0)
process_glitch_manager(mCurrentRoom_mGlitchManager)
local mTrace = memory.readu64(THGameplayState + 0x118)
process_trace_skewer(mTrace, 0xff0000ff, mCurrentRoom_mTileMap)
local mDrone = memory.readu64(THGameplayState + 0x120)
process_character(mDrone, 0xff0000ff)
end
)