User File #47189229301951797

Upload All User Files

#47189229301951797 - Ironsword Malkil fight elemental positions

WW2_draw_Malkil_elementals.lua
873 downloads
Uploaded 5/18/2018 3:54 AM by Dacicus (see all 26)
This script draws the position of the elementals during the final fight with Malkil in Ironsword: Wizards & Warriors II on a canvas. Kuros's position also is drawn. To keep it compact, coordinates on the canvas are scaled to half the value in the game. By default, the area drawn is 1.5 by 1.25 screens large and focused around the middle peak of Icefire Mountain.
Keys are defined that allow you to toggle each elemental on/off, restore Kuros to full health or full magic (so you do not need separate cheats), and clear the canvas. There are toggles for the health restoration, magic restoration, and canvas clearing to be done automatically.
--[[
   This script draws the position of the elementals during the final fight with
   Malkil in Ironsword: Wizards & Warriors II on a canvas.  Kuros's position
   also is drawn.  To keep it compact, coordinates on the canvas are scaled to
   half the value in the game.  By default, the area drawn is 1.5 by 1.25
   screens large and focused around the middle peak of Icefire Mountain.

   Keys are defined that allow you to toggle each elemental on/off, restore
   Kuros to full health or full magic (so you do not need separate cheats), and
   clear the canvas.  There are toggles for the health restoration, magic
   restoration, and canvas clearing to be done automatically.

   Mostly by Dacicus in May 2018 but with input processing code copied from
   another script, original author unknown.
--]]

-- Default values of options for cheats
local manual_restore_kuros_health = false
local manual_restore_kuros_magic = false
local manual_clear_canvas = false
local auto_restore_kuros_health = false
local auto_restore_kuros_magic = false
local auto_clear_canvas = false

-- Default to automatically clear the canvas every 1800 frames
local auto_clear_canvas_frames = 1800

-- Default options for drawing the elementals
local draw_earth = true
local draw_fire = true
local draw_water = true
local draw_wind = true

-- Key definitions to toggle the above options, same order as above
local keyboard_shortcuts = {"G", "H", "J", "B", "N", "M", "NumberPad0", "NumberPad1", "NumberPad2", "NumberPad3"}

-- Script start-up message
console.writeline("Press " .. keyboard_shortcuts[1] .. " to restore health.")
console.writeline("Press " .. keyboard_shortcuts[2] .. " to restore magic.")
console.writeline("Press " .. keyboard_shortcuts[3] .. " to clear canvas.")
console.writeline("Press " .. keyboard_shortcuts[4] .. " to automatically restore health each frame.")
console.writeline("Press " .. keyboard_shortcuts[5] .. " to automatically restore magic each frame.")
console.writeline("Press " .. keyboard_shortcuts[6] .. " to automatically clear canvas every " .. auto_clear_canvas_frames .. " frames.")
console.writeline("Press " .. keyboard_shortcuts[7] .. " to draw/hide earth elemental.")
console.writeline("Press " .. keyboard_shortcuts[8] .. " to draw/hide fire elemental.")
console.writeline("Press " .. keyboard_shortcuts[9] .. " to draw/hide water elemental.")
console.writeline("Press " .. keyboard_shortcuts[10] .. " to draw/hide wind elemental.")

-- Some other variables and default values
local camera_x, camera_y
local dots_x_offset = 0x80
local dots_y_offset = 0x80

local start_frame = emu.framecount()
local frames_since_cleared = 0

local boss_is_loaded = false
local boss_offsets_found = 0
local earth_offset, fire_offset, water_offset, wind_offset

-- Initialize the canvas
local cnv = gui.createcanvas(0x180, 0x140)
cnv.Clear(0xFF000000)

-- Input variables
local old_input, current_input, new_input = {}, {}, {}

function get_new_input()
  old_input = current_input
  current_input = input.get()
  new_input = {}
  for k,v in pairs(current_input) do
    new_input[k] = not(old_input[k])
  end
end

function process_new_input()
  if new_input[keyboard_shortcuts[1]] then
    manual_restore_kuros_health = true
    console.writeline("Restoring full health.")
  end

  if new_input[keyboard_shortcuts[2]] then
    manual_restore_kuros_magic = true
    console.writeline("Restoring full magic.")
  end

  if new_input[keyboard_shortcuts[3]] then
    manual_clear_canvas = true
    console.writeline("Clearing canvas.")
  end

  if new_input[keyboard_shortcuts[4]] then
    auto_restore_kuros_health = not(auto_restore_kuros_health)
    console.write("Auto restore full health: ")
    if auto_restore_kuros_health then
      console.writeline("Enabled.")
    else
      console.writeline("Disabled.")
    end
  end

  if new_input[keyboard_shortcuts[5]] then
    auto_restore_kuros_magic = not(auto_restore_kuros_magic)
    console.write("Auto restore full magic: ")
    if auto_restore_kuros_magic then
      console.writeline("Enabled.")
    else
      console.writeline("Disabled.")
    end
  end

  if new_input[keyboard_shortcuts[6]] then
    auto_clear_canvas = not(auto_clear_canvas)
    console.write("Use timer to clear canvas: ")
    if auto_clear_canvas then
      console.writeline("Enabled.  Resetting timer.")
      start_frame = emu.framecount()
      frames_since_cleared = 0
    else
      console.writeline("Disabled.")
    end
  end

  if new_input[keyboard_shortcuts[7]] then
    draw_earth = not(draw_earth)
    if draw_earth then
      console.writeline("Drawing earth elemental.")
    else
      console.writeline("Hiding earth elemental.")
    end
  end

  if new_input[keyboard_shortcuts[8]] then
    draw_fire = not(draw_fire)
    if draw_fire then
      console.writeline("Drawing fire elemental.")
    else
      console.writeline("Hiding fire elemental.")
    end
  end

  if new_input[keyboard_shortcuts[9]] then
    draw_water = not(draw_water)
    if draw_water then
      console.writeline("Drawing water elemental.")
    else
      console.writeline("Hiding water elemental.")
    end
  end

  if new_input[keyboard_shortcuts[10]] then
    draw_wind = not(draw_wind)
    if draw_wind then
      console.writeline("Drawing wind elemental.")
    else
      console.writeline("Hiding wind elemental.")
    end
  end
end

function restore_kuros_health()
  if manual_restore_kuros_health or auto_restore_kuros_health then
    memory.write_u8(0x006A, 0xFF)
  end

  if manual_restore_kuros_health then
    manual_restore_kuros_health = false
  end
end

function restore_kuros_magic()
  if manual_restore_kuros_magic or auto_restore_kuros_magic then
    memory.write_u8(0x006B, 0xFF)
  end

  if manual_restore_kuros_magic then
    manual_restore_kuros_magic = false
  end
end

function draw_kuros_pos_dots()
  local kuros_x = memory.read_u8(0x0213) + memory.read_u8(0x0226) * 0x100
  local kuros_y = memory.read_u8(0x024C) + memory.read_u8(0x025F) * 0x100

  kuros_x = kuros_x / 2
  kuros_y = kuros_y / 2

  cnv.DrawRectangle(kuros_x - dots_x_offset, kuros_y - dots_y_offset, 1, 1, "yellow")
end

function is_boss_loaded()
  if (memory.read_u8(0x00C6) == 1) then
    boss_is_loaded = true
  else
    boss_is_loaded = false
    boss_offsets_found = 0
  end
end

function find_boss_offsets()
  for i = 0x0B, 0x12 do
    if (memory.read_u8(0x02BE + i) == 0x1D) then
      earth_offset = i
      boss_offsets_found = bit.bor(boss_offsets_found, 0x01)
    elseif (memory.read_u8(0x02BE + i) == 0x1C) then
      fire_offset = i
      boss_offsets_found = bit.bor(boss_offsets_found, 0x02)
    elseif (memory.read_u8(0x02BE + i) == 0x1B) then
      water_offset = i
      boss_offsets_found = bit.bor(boss_offsets_found, 0x04)
    elseif (memory.read_u8(0x02BE + i) == 0x1A) then
      wind_offset = i
      boss_offsets_found = bit.bor(boss_offsets_found, 0x08)
    end
  end
end

-- Label the location RAM offset over the enemy, projectile, etc.
-- Note that this draws to the screen, not to the canvas.
-- Can be used to find offsets for things not drawn by default.
function draw_enemy_pos_string()
  local enemy_x_pos, enemy_y_pos
  for i = 1, 0x12 do
    enemy_x_pos = memory.read_u8(0x0213 + i) + memory.read_u8(0x0226 + i) * 0x100 - camera_x
    enemy_y_pos = memory.read_u8(0x024C + i) + memory.read_u8(0x025F + i) * 0x100 - camera_y
    gui.drawText(enemy_x_pos, enemy_y_pos, string.format("%02x", i))
  end
end

function draw_enemy_pos_dots()
  local enemy_x_pos, enemy_y_pos

  -- Draw the elementals if the offset has been found and if health is not 0

  if draw_earth and bit.check(boss_offsets_found, 0) and (memory.read_u8(0x00CB) ~= 0) then
    enemy_x_pos = memory.read_u8(0x0213 + earth_offset) + memory.read_u8(0x0226 + earth_offset) * 0x100
    enemy_y_pos = memory.read_u8(0x024C + earth_offset) + memory.read_u8(0x025F + earth_offset) * 0x100
    enemy_x_pos = enemy_x_pos / 2
    enemy_y_pos = enemy_y_pos / 2
    cnv.DrawRectangle(enemy_x_pos - dots_x_offset, enemy_y_pos - dots_y_offset, 1, 1, "brown")
  end

  if draw_fire and bit.check(boss_offsets_found, 1) and (memory.read_u8(0x00CA) ~= 0) then
    enemy_x_pos = memory.read_u8(0x0213 + fire_offset) + memory.read_u8(0x0226 + fire_offset) * 0x100
    enemy_y_pos = memory.read_u8(0x024C + fire_offset) + memory.read_u8(0x025F + fire_offset) * 0x100
    enemy_x_pos = enemy_x_pos / 2
    enemy_y_pos = enemy_y_pos / 2
    cnv.DrawRectangle(enemy_x_pos - dots_x_offset, enemy_y_pos - dots_y_offset, 1, 1, "red")
  end

  if draw_water and bit.check(boss_offsets_found, 2) and (memory.read_u8(0x00C9) ~= 0) then
    enemy_x_pos = memory.read_u8(0x0213 + water_offset) + memory.read_u8(0x0226 + water_offset) * 0x100
    enemy_y_pos = memory.read_u8(0x024C + water_offset) + memory.read_u8(0x025F + water_offset) * 0x100
    enemy_x_pos = enemy_x_pos / 2
    enemy_y_pos = enemy_y_pos / 2
    cnv.DrawRectangle(enemy_x_pos - dots_x_offset, enemy_y_pos - dots_y_offset, 1, 1, "blue")
  end

  if draw_wind and bit.check(boss_offsets_found, 3) and (memory.read_u8(0x00C8) ~= 0) then
    enemy_x_pos = memory.read_u8(0x0213 + wind_offset) + memory.read_u8(0x0226 + wind_offset) * 0x100
    enemy_y_pos = memory.read_u8(0x024C + wind_offset) + memory.read_u8(0x025F + wind_offset) * 0x100
    enemy_x_pos = enemy_x_pos / 2
    enemy_y_pos = enemy_y_pos / 2
    cnv.DrawRectangle(enemy_x_pos - dots_x_offset, enemy_y_pos - dots_y_offset, 1, 1, "white")
  end

  cnv.Refresh()
  boss_offsets_found = 0
end

function clear_enemy_pos_canvas()
  if manual_clear_canvas then
    cnv.Clear(0xFF000000)
    manual_clear_canvas = false
  end

  if auto_clear_canvas then
    if (emu.framecount() ~= start_frame) then
      frames_since_cleared = frames_since_cleared + 1
    end

    if (frames_since_cleared > auto_clear_canvas_frames) then
      cnv.Clear(0xFF000000)
      frames_since_cleared = 0
    end
  end
end

while true do
  camera_x = memory.read_u16_le(0x0053)
  camera_y = memory.read_u16_le(0x0055)

  get_new_input()
  process_new_input()

  restore_kuros_health()
  restore_kuros_magic()

  if boss_is_loaded then
    draw_kuros_pos_dots()
    find_boss_offsets()
--    draw_enemy_pos_string()
    draw_enemy_pos_dots()
    clear_enemy_pos_canvas()
  else
    is_boss_loaded()
  end

  emu.frameadvance()
end