Hello!
I made a hitbox script for Run Saber. They handle things in interesting ways... For example, rather than giving an enemy an additional hitbox for an attack or making complex shapes from multiple hitboxes, they just cycle through some offsets and sizes depending on the current animation without changing the center. This is most evident with the first miniboss and the lightning in Stage 2. What this also means is that there are plenty of gaps to abuse, especially for a TAS.
They might have screwed up in a few places as well...
[URL=
http://www.makeagif.com/TulvQy]
[/URL]
Code below. I make no claims about it being clean or efficient or complete, but it should be reasonable for now. Developed and tested on BizHawk 1.8.4, although some minor modifications should make it suitable for other versions/emulators.
while true do
camx = mainmemory.read_u16_le(0x000548)
camy = mainmemory.read_u16_le(0x00054A)
textX=20
textY=40
hp = mainmemory.read_u8(0x001F3A)
gui.text(textX,textY,string.format("HP: %d",hp))
memory.usememorydomain("CARTROM")
hitbox_left = mainmemory.read_u16_le(0x000270)
hitbox_right = mainmemory.read_u16_le(0x000272)
hitbox_up = mainmemory.read_u16_le(0x000274)
hitbox_down = mainmemory.read_u16_le(0x000276)
if(mainmemory.read_u8(0x000E1D)~=0xFF) then
attack_right = mainmemory.read_u16_le(0x000280)
attack_left = mainmemory.read_u16_le(0x000282)
attack_up = mainmemory.read_u16_le(0x000284)
attack_down = mainmemory.read_u16_le(0x000286)
gui.drawBox(attack_left-camx,attack_up-camy,attack_right-camx, attack_down-camy,"green")
end
--gui.text(textX,textY+14,string.format("X: %X",camx))
--gui.text(textX,textY+28,string.format("Y: %X",camy))
if(mainmemory.read_u8(0x000E1E)~=0x00) then
gui.drawBox(hitbox_left-camx,hitbox_up-camy,hitbox_right-camx, hitbox_down-camy,"blue")
else
gui.drawBox(hitbox_left-camx,hitbox_up-camy,hitbox_right-camx, hitbox_down-camy,"white")
end
hitbox_left = mainmemory.read_u16_le(0x000278)
hitbox_right = mainmemory.read_u16_le(0x00027A)
hitbox_up = mainmemory.read_u16_le(0x00027C)
hitbox_down = mainmemory.read_u16_le(0x00027E)
if(mainmemory.read_u8(0x000E3D)~=0xFF) then
attack_right = mainmemory.read_u16_le(0x000288)
attack_left = mainmemory.read_u16_le(0x00028A)
attack_up = mainmemory.read_u16_le(0x00028C)
attack_down = mainmemory.read_u16_le(0x00028E)
gui.drawBox(attack_left-camx,attack_up-camy,attack_right-camx, attack_down-camy,"green")
end
if(mainmemory.read_u8(0x000E3E)~=0x00) then
gui.drawBox(hitbox_left-camx,hitbox_up-camy,hitbox_right-camx, hitbox_down-camy,"blue")
else
gui.drawBox(hitbox_left-camx,hitbox_up-camy,hitbox_right-camx, hitbox_down-camy,"white")
end
for i = 2,0x0F,1 do
if(mainmemory.read_u8(0x000e00+(i*0x20))>0) then
ID = mainmemory.read_u8(0x000e00+(i*0x20))*2
NEWDC = mainmemory.read_u8(0x000e1c+(i*0x20))*4
pos_x = mainmemory.read_u16_le(0x000e10+(i*0x20))
pos_y = mainmemory.read_u16_le(0x000e12+(i*0x20))
offset_x = memory.read_u8(0x038A00+NEWDC)
length_x = memory.read_u8(0x038A01+NEWDC)
offset_y = memory.read_u8(0x038A02+NEWDC)
length_y = memory.read_u8(0x038A03+NEWDC)
gui.drawPixel(pos_x-camx, pos_y-camy,"red")
if(mainmemory.read_u8(0x000E0C+(i*0x20))==0) then
mycolor = "red"
else
mycolor = "white"
end
if(bit.band(mainmemory.read_u8(0x000e07+(i*0x20)),0x40)~=0) then
gui.drawBox(pos_x-camx+offset_x-length_x,pos_y-camy-offset_y,pos_x-camx+offset_x, pos_y-camy-offset_y+length_y,mycolor)
else
gui.drawBox(pos_x-camx-offset_x+length_x,pos_y-camy-offset_y,pos_x-camx-offset_x, pos_y-camy-offset_y+length_y,mycolor)
end
--gui.drawText(pos_x-camx, pos_y-camy,string.format("%d",i))
damage = mainmemory.read_u8(0x000e14+(i*0x20))
max_hp = mainmemory.read_u8(0x000e15+(i*0x20))
if(max_hp-damage <128>0) then
addr_offset = mainmemory.read_u8(0x000c0e+(i*0x10))*8
pos_x = mainmemory.read_u16_le(0x000c05+(i*0x10))
pos_y = mainmemory.read_u16_le(0x000c07+(i*0x10))
offset_x = memory.read_u8(0x009045+addr_offset)
length_x = memory.read_u8(0x009047+addr_offset)
offset_y = memory.read_u8(0x009049+addr_offset)
length_y = memory.read_u8(0x00904B+addr_offset)
gui.drawBox(pos_x-camx+offset_x,pos_y-camy+offset_y,pos_x-camx+offset_x+length_x, pos_y-camy+offset_y+length_y,"purple")
end
end
emu.frameadvance()
end