User File #67854780147691472

Upload All User Files

#67854780147691472 - Wizards & Warriors X Hitbox Script (BizHawk)

WizWarX_Draw_Hitbox_HP.lua
359 downloads
Uploaded 12/3/2020 8:13 PM by Dacicus (see all 26)
This script displays hitboxes for Kuros, Kuros's weapon, and active items in Wizards & Warriors X: The Fortress of Fear. It also displays HP of items. Several notes:
  • HP values are decimal numbers.
  • The weapon only has a hitbox during certain animation states. It only causes damage when it has a hitbox.
  • Damage appears to be 1 HP per frame of contact with the enemy.
  • Some items, like keys, remain in an active state even after being collected.
--[[
This script displays hitboxes for Kuros, Kuros's weapon, and active items in
Wizards & Warriors X: The Fortress of Fear.  It also displays HP of items.
Several notes:
- HP values are decimal numbers.
- The weapon only has a hitbox during certain animation states.  It only causes
  damage when it has a hitbox.
- Damage appears to be 1 HP per frame of contact with the enemy.
- Some items, like keys, remain in an active state even after being collected.

Feel free to improve upon this as desired.

Dacicus 2020/12/03
--]]

memory.usememorydomain("System Bus")

local item_offset, item_x, item_y, item_pointer, item_value, item_hp
local hit_x_lo, hit_x_hi, hit_y_low, hit_y_hi
local kuros_y, kuros_animation, kuros_y_mod
local weapon_pointer, weapon_x_lo, weapon_x_hi, weapon_y_lo, weapon_y_hi
local color_item = 0xFFFF0000
local color_kuros = 0xFF0000FF
local color_weapon = 0xFFFF00FF
local addr_current_spawns = 0xC200
local addr_rom_bank = 0xC2FB
local addr_kuros_animation = 0xFFD8
local addr_kuros_y = 0xFFD9
local addr_kuros_weapon = 0xFFDC

--[[
These modifier values are not from the ROM.  They were determined
empirically in order to make the hitboxes match up with the graphics
on screen.  Set them to 0 in order to use just the data from the ROM.
--]]
local x_mod, y_mod = 0x08, 0x10

-- All constants in the functions below are based on values hardcoded or calculated in the ROM.

local function draw_kuros_hitbox(y_pos, animation)
  if animation < 0x1C then
    kuros_y_mod = 0x10
  elseif animation < 0x24 then
    kuros_y_mod = 0x1B
  elseif animation < 0x34 then
    kuros_y_mod = 0x10
  else
    kuros_y_mod = 0x1B
  end
  gui.drawBox(0x4B - x_mod, y_pos + kuros_y_mod - y_mod, 0x56 - x_mod, y_pos + 0x30 - y_mod, color_kuros)
end

local function draw_weapon_hitbox(addr, y_pos, animation)
  if ((animation >= 0x15) and (animation < 0x1c) and (animation ~= 0x18)) or
     (animation == 0x1F) or (animation == 0x23) or (animation == 0x31) or (animation == 0x33) then
    weapon_pointer = memory.read_u16_le(addr) + 0x1C
    weapon_x_lo = memory.read_u8(weapon_pointer)
    weapon_x_hi = memory.read_u8(weapon_pointer + 2)
    weapon_y_lo = memory.read_u8(weapon_pointer + 1) + y_pos
    weapon_y_hi = memory.read_u8(weapon_pointer + 3) + y_pos
    gui.drawBox(weapon_x_lo - x_mod, weapon_y_lo - y_mod, weapon_x_hi - x_mod, weapon_y_hi - y_mod, color_weapon)
  end
end

local function draw_item_hitbox(addr)
  for curr_slot = 0, 18 do
    item_offset = addr + curr_slot * 6
    if memory.read_u8(item_offset + 3) ~= 0xFE then -- 0xFE: slot is inactive
      item_x = memory.read_u8(item_offset)
      item_y = memory.read_u8(item_offset + 1)
      item_hp = memory.read_u8(item_offset + 4)
      item_pointer = memory.read_u16_le(item_offset + 2)
      item_value = memory.read_u8(item_pointer + 2)
      item_pointer = item_pointer + 6 + item_value
      while memory.read_u8(item_pointer) ~= 0xFF do
        item_pointer = item_pointer + 1
      end
      item_pointer = item_pointer + 2
      hit_x_lo = item_x + memory.read_u8(item_pointer)
      hit_y_lo = item_y + memory.read_u8(item_pointer + 1)
      hit_x_hi = item_x + memory.read_u8(item_pointer + 2)
      hit_y_hi = item_y + memory.read_u8(item_pointer + 3)
      gui.drawBox(hit_x_lo - x_mod, hit_y_lo - y_mod, hit_x_hi - x_mod, hit_y_hi - y_mod, color_item)
      gui.pixelText(item_x, item_y, item_hp)
    end
  end
end

while true do
  if memory.read_u8(addr_rom_bank) == 3 then -- Avoid slowdown between levels.
    kuros_y = memory.read_u8(addr_kuros_y)
    kuros_animation = memory.read_u8(addr_kuros_animation)
    draw_kuros_hitbox(kuros_y, kuros_animation)
    draw_weapon_hitbox(addr_kuros_weapon, kuros_y, kuros_animation)
    draw_item_hitbox(addr_current_spawns)
  end
  emu.frameadvance()
end