SHARE
TWEET

FF6 BizHawk LUA Info Overlay

a guest Jan 26th, 2020 97 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- Used with "BizHawk" emulator - load ROM -> Tools -> Lua Console -> Script -> Open Script -> double-click until green play sign
  2.  
  3. -- Enable or disable the overlay with [R+SELECT]. Haven't played with this yet, so
  4. -- you may end up seeing overlay popups during the normal game at odd times.
  5.  
  6. -- mod type for offsets, works off of the 'rom name' (what it says in title bar/saves games as)
  7. -- if your rom isn't detected just add it in this format (including the , and any " marks):
  8. -- ["ROM NAME"] = romtype,
  9. -- where romtype is one of these: nil, "ROTDS", "BNW"
  10. -- any other romtype will use nil (vanilla) settings
  11.  
  12. local MODS = {
  13.  
  14. ["Final Fantasy III (USA)"]     = nil,     -- vanilla, default. -- means comments
  15. ["Return of the Dark Sorcerer"] = "ROTDS", -- uses rotds extended item/spell names
  16. ["Brave New World 2.0"]         = "BNW",   -- mod'd dance chance
  17. ["FFVI T Edition"]              = "japan", -- nothing yet, the version is stripped further down
  18.  
  19. }
  20.  
  21. --- =======================
  22. --- all settings are above this
  23. --- =======================
  24.  
  25.  
  26.  
  27. local romname = gameinfo.getromname()
  28.  
  29. -- t-edition has ever-changing patch number on the end
  30. if (romname:sub(1,14) == "FFVI T Edition") then romname = "FFVI T Edition" end
  31. local MOD_TYPE = MODS[romname]
  32. function initialize()
  33.      gui.defaultPixelFont("fceux")
  34.     -- vanilla
  35. -- offset start, text length, index start
  36.     offNames = {
  37.         spells = { 0x26F567, 7, 0 },
  38.         espers = { 0x26F6E1, 8, 54 },
  39.        attacks = { 0x26F7B9, 10, 81 },
  40.     espattacks = { 0x26FE8F, 10, 256 },
  41.         dances = { 0x26FF9D, 12, 283 },
  42. }
  43.     offMonsterData = 0xF0000
  44.     lenMonsterData = 32
  45.     offItemNames = 0x12B300
  46.     lenItemNames = 13
  47.     if (MOD_TYPE == "ROTDS") then
  48.         offNames.spells = { 0x316100, 9, 0 }
  49.         offNames.espers = { 0x3162E6, 12, 54 }
  50.         offNames.attacks = { 0x31645E, 16, 81 }
  51.         offNames.espattacks = { 0x316DDE, 16, 256 }
  52.         offNames.dances = { 0x3170FE, 13, 283 }
  53.         lenItemNames = 13
  54.     end
  55. end
  56. initialize()
  57.  
  58. -- maps each font byte to the appropriate character, FF should break loop, space for anything else
  59. local fontMap = { [0x80] = "A", [0x81] = "B", [0x82] = "C", [0x83] = "D", [0x84] = "E", [0x85] = "F", [0x86] = "G", [0x87] = "H", [0x88] = "I", [0x89] = "J", [0x8A] = "K", [0x8B] = "L", [0x8C] = "M", [0x8D] = "N", [0x8E] = "O", [0x8F] = "P", [0x90] = "Q", [0x91] = "R", [0x92] = "S", [0x93] = "T", [0x94] = "U", [0x95] = "V", [0x96] = "W", [0x97] = "X", [0x98] = "Y", [0x99] = "Z", [0x9A] = "a", [0x9B] = "b", [0x9C] = "c", [0x9D] = "d", [0x9E] = "e", [0x9F] = "f", [0xA0] = "g", [0xA1] = "h", [0xA2] = "i", [0xA3] = "j", [0xA4] = "k", [0xA5] = "l", [0xA6] = "m", [0xA7] = "n", [0xA8] = "o", [0xA9] = "p", [0xAA] = "q", [0xAB] = "r", [0xAC] = "s", [0xAD] = "t", [0xAE] = "u", [0xAF] = "v", [0xB0] = "w", [0xB1] = "x", [0xB2] = "y", [0xB3] = "z", [0xB4] = "0", [0xB5] = "1", [0xB6] = "2", [0xB7] = "3", [0xB8] = "4", [0xB9] = "5", [0xBA] = "6", [0xBB] = "7", [0xBC] = "8", [0xBD] = "9", [0xBE] = "!", [0xBF] = "?", [0xC3] = "'", [0xC4] = "-", [0xC5] = ".", }
  60.  
  61. local monSpecials = {
  62. [0x00]="+Darkness", [0x01]="+Zombie", [0x02]="+Poison", [0x03]="+Magitek", [0x04]="+Invis", [0x05]="+Imp", [0x06]="+Stone", [0x07]="+Death", [0x08]="+Doom", [0x09]="+Critical", [0x0A]="+Blink", [0x0B]="+Silence", [0x0C]="+Berserk", [0x0D]="+Confuse", [0x0E]="+Sap", [0x0F]="+Sleep", [0x10]="+Dance", [0x11]="+Regen", [0x12]="+Slow", [0x13]="+Haste", [0x14]="+Stop", [0x15]="+Shell", [0x16]="+Protect", [0x17]="+Reflect", [0x18]="+Rage", [0x19]="+Frozen", [0x1A]="+Reraise", [0x1B]="+Morph", [0x1C]="+Spellcast", [0x1D]="+Flee", [0x1E]="+Interceptor", [0x1F]="+Float", [0x20]=" Damage + 50%", [0x21]=" Damage +100%", [0x22]=" Damage +150%", [0x23]=" Damage +200%", [0x24]=" Damage +250%", [0x25]=" Damage +300%", [0x26]=" Damage +350%", [0x27]=" Damage +400%", [0x28]=" Damage +450%", [0x29]=" Damage +500%", [0x2A]=" Damage +550%", [0x2B]=" Damage +600%", [0x2C]=" Damage +650%", [0x2D]=" Damage +700%", [0x2E]=" Damage +750%", [0x2F]=" Damage +800%",
  63. }
  64. function hexformat(input) return string.format("%02x", input):upper() end
  65. function trim(out) return (out:gsub("^%s*(.-)%s*$", "%1")) end
  66. -- skipFF to anything to prevent breaking on FF
  67. function translate(byteTable,skipFF)
  68.     local out = ""
  69.     local start = 0
  70.     if (not byteTable[start]) then start = 1 end
  71.     for i=start,#byteTable do
  72.         local hex = byteTable[i]
  73.         if ((hex == 0xFF or not hex) and not skipFF) then break end
  74.         if (fontMap[hex]) then
  75.             out = out .. fontMap[hex]
  76.         else
  77.             out = out .. " "
  78.         end
  79.     end
  80.     out = trim(out)
  81.     return out
  82. end
  83. function getStatuses(byteA,byteB,byteC)
  84.     local statuses = { {"Blind", "Zombi", "Poisn", "M-Tek", "Invis", "Imp  ", "Stone", "Death"},
  85.                        {"Doom ", "Hurt ", "Image", "Mute ", "Brsrk", "Muddl", "Sap  ", "Sleep"},
  86.                        {"Float", "Regen", "Slow ", "Haste", "Stop ", "Shell", "Safe ", "Rflct"} }
  87.     local outStatuses = {}
  88.     for _,byte in pairs({ byteA, byteB, byteC }) do
  89.         for i=1,#statuses[_] do
  90.             if (bit.band(byte,bit.lshift(1,(i-1))) > 0) then
  91.                 outStatuses[#outStatuses+1] = statuses[_][i]
  92.             end
  93.         end
  94.     end
  95.     local out = ""
  96.     for _,v in pairs(outStatuses) do
  97.         out = out .. v .. " "
  98.         if (_ % 6 == 0) then out = out .. "\n      " end
  99.     end
  100.     return trim(out)
  101. end
  102. function getElements(byte)
  103.     local elements = { "FIR", "ICE", "THN", "POI", "WND", "HLY", "ERT", "WTR" }
  104.     local outElements = {}
  105.     for i=1,#elements do
  106.         if (bit.band(byte,bit.lshift(1,(i-1))) > 0) then
  107.             outElements[#outElements+1] = elements[i]
  108.         end
  109.     end
  110.     local out = ""
  111.     for _,v in pairs(outElements) do
  112.         out = out .. v .. " "
  113.         --if (_ % 5 == 0) then out = out .. "\n" end
  114.     end
  115.     return trim(out)
  116. end
  117. function getSpellName(index)
  118.     local type = nil
  119.     if (index >= offNames.dances[3]) then type = offNames.dances
  120.     elseif (index >= offNames.espattacks[3]) then type = offNames.espattacks
  121.     elseif (index >= offNames.attacks[3]) then type = offNames.attacks
  122.     elseif (index >= offNames.espers[3]) then type = offNames.espers
  123.     else type = offNames.spells
  124.     end
  125.     local beginOffset = type[1]
  126.     local textLength = type[2]
  127.     local startSkillIndex = type[3]
  128.     local firstByte = beginOffset + ((index-startSkillIndex)*textLength)
  129.     local out = memory.readbyterange(firstByte,textLength,"CARTROM")
  130.     out = translate(out)
  131.     return out
  132. end
  133. function getItemName(index)
  134.     local out = memory.readbyterange(offItemNames + (index*lenItemNames),lenItemNames,"CARTROM")
  135.     out = translate(out,"don't-break-on-FF")
  136.     if (out == "") then out = "(None)" end
  137.     return out
  138. end
  139. local cursor_state = nil
  140. local inputs = { { nil, nil, nil, nil, "R", "L", "X", "A", },
  141.                  { "Right", "Left", "Down", "Up", "Start", "Select", "Y", "B" } }
  142. local keymap = {}
  143. local keymapLastFrame = {}
  144.  
  145. function buttonHandler()
  146.     -- X is at 0x0A as the 7th bit (0x40), Y is at 0x0B same
  147.     local input1 = memory.readbyte(0x04,"WRAM")
  148.     local input2 = memory.readbyte(0x05,"WRAM")
  149.     if (input1 == 0x00 and input2 == 0x00) then
  150.         input1 = memory.readbyte(0x0A)
  151.         input2 = memory.readbyte(0x0B)
  152.     end
  153.     keymapLastFrame = keymap
  154.     keymap = {}
  155.     for _,byte in pairs({ input1, input2 }) do
  156.         for i=1,#inputs[_] do
  157.             if (inputs[_][i] ~= nil) then
  158.                 if (bit.band(byte,bit.lshift(1,(i-1))) > 0) then
  159.                     keymap[inputs[_][i]] = true
  160.                 end
  161.             end
  162.         end
  163.     end
  164. end
  165.  
  166. function checkIfHelpButton()
  167.     -- X is at 0x0A as the 7th bit (0x40), Y is at 0x0B same
  168.     if (keymap["X"] or keymap["Y"] or keymapLastFrame["X"] or keymapLastFrame["Y"]) then return true end
  169.     return false
  170. end
  171.  
  172. local enabledToggle = true
  173. local messageStartTime = 0
  174. local messageText = ""
  175. local messageDuration = 0
  176. function disabledCheck()
  177.     if (keymap["Select"] and keymap["R"] and not (keymapLastFrame["R"] and keymapLastFrame["Select"])) then
  178.         enabledToggle = not enabledToggle
  179.         if (enabledToggle) then message("Overlay enabled.",4)
  180.         else message("Overlay disabled.", 4)       
  181.         end
  182.     end
  183. end
  184. function message(msg,duration)
  185.     messageStartTime = os.time()
  186.     messageText = msg
  187.     messageDuration = duration
  188. end
  189. function messageCheck()
  190.     messageTime = os.time()
  191.     if (messageTime < (messageStartTime + messageDuration)) then
  192.         gui.drawText(0,210,messageText,"white","black")
  193.     end
  194. end
  195. function processEnemySpecial(idxTargetMonster)
  196.     local monStats = memory.readbyterange(offMonsterData + (lenMonsterData * idxTargetMonster),lenMonsterData,"CARTROM")
  197.     local specialAttack = monStats[0x1F]
  198.     local noEvade = (bit.band(specialAttack,0x80) > 0)
  199.     local noDamage = (bit.band(specialAttack,0x40) > 0)
  200.     specialAttack = bit.band(specialAttack,0x3F)
  201.     specialAttack = monSpecials[specialAttack]
  202.     if (specialAttack) then
  203.         if (noEvade or noDamage) then
  204.             specialAttack = specialAttack..")\n(Special:"
  205.             if (noEvade) then specialAttack = specialAttack .. "Can't dodge" end
  206.             if (noEvade and noDamage) then specialAttack = specialAttack .. " & " end
  207.             if (noDamage) then specialAttack = specialAttack .. "No damage" end
  208.         end
  209.     else
  210.         specialAttack = "+???"
  211.     end
  212.     return "(Special:Attack"..specialAttack..")"
  213. end
  214. local hintLoc = { x = 8, y = 142, height = 9 }
  215. function printHint(msg)
  216.     local _, extraLineCount = msg:gsub('\n', '\n')
  217.     gui.pixelText(hintLoc.x,hintLoc.y-(hintLoc.height * extraLineCount),msg,"white")
  218. end
  219. function doStealStuff(targetted_monster)
  220.     local stealLoc = 0x3310 + (2*targetted_monster)
  221.     local rare_steal = memory.read_u8(stealLoc)
  222.     local common_steal = memory.read_u8(stealLoc+1)
  223.     local itemNames = { getItemName(common_steal), getItemName(rare_steal) }
  224.     if (common_steal == 0xFF) then itemNames[1] = "---" end
  225.     if (rare_steal   == 0xFF) then itemNames[2] = "---" end
  226.     local out = "Nothing to steal!"
  227.     if (itemNames[1] ~= "---" or itemNames[2] ~= "---") then
  228.         out = "Common Steal (7/8): "..itemNames[1].."\n  Rare Steal (1/8): "..itemNames[2]
  229.     end
  230.     return out
  231. end
  232. function main()
  233.     disabledCheck()
  234.     messageCheck()
  235.     if (not enabledToggle) then return end
  236.  
  237.  
  238.     local paused = memory.read_u8(0x62ab)
  239.     if (paused > 0) then
  240. -- should probably get a check so it ONLY works in battle
  241. --[[
  242.         -- show enemy health if paused
  243.         for i=0,5 do
  244.             local hp = memory.read_u16_le(0x3bfc + (2*i))
  245.             if (hp > 0) then
  246.                 local x = memory.read_u16_le(0x80c3 + (2*i)) -- monster loc x in pixels
  247.                 local y = memory.read_u16_le(0x80cf + (2*i)) -- monster loc y in pixels
  248.                 gui.drawText(x,y,hp)
  249.             end
  250.         end
  251. ]]--
  252.     end
  253.  
  254.     -- reads memory of 'cursor state' which appears to be the type of command being hovered over
  255.     local last_cursor_state = cursor_state
  256.     cursor_state = memory.read_u8(0x7bc2)
  257.     local which_character = memory.read_u8(0x62ca) -- offsets cursor info
  258.     local idxRecentCommand = memory.read_u8(0x890F + which_character) -- the command we're hovering on main menu
  259.     local recentCommandType = memory.read_u8(0x202E + (12*which_character) + (3*idxRecentCommand))
  260.     --23 = scrolling page up or down
  261.     if (cursor_state == 23 or cursor_state == 24) then cursor_state = last_cursor_state end
  262.     --30 = rage
  263.     if (cursor_state == 30) then
  264.         local rages = memory.readbyterange(0x257E,256)
  265.         local battleMenuColumn = 0x892F -- row and scrolled are derived from this (+4/-4)
  266.         local column = memory.read_u8(battleMenuColumn + which_character)
  267.         local row = memory.read_u8(battleMenuColumn + which_character + 4)
  268.         local scrolled = memory.read_u8(battleMenuColumn + which_character - 4)
  269.         local hoverRage = rages[((row+scrolled)*2) + column]
  270.         local menuClosing = (memory.read_u8(0x7BCB) > 0) -- get rid of little text-blink as rage menu closes
  271.         if (hoverRage < 255 and not menuClosing) then
  272.             local rageLoc = 0xF4600 + (2*hoverRage)
  273.             local rageAttacks = { memory.readbyte(rageLoc,"CARTROM"), memory.readbyte(rageLoc+1,"CARTROM") }
  274.             for i=1,2 do rageAttacks[i] = getSpellName(rageAttacks[i]) end --.."("..rageAttacks[i]..")" end
  275.             local monStats = memory.readbyterange(offMonsterData + (lenMonsterData * hoverRage),lenMonsterData,"CARTROM")
  276.             local out = "Rage: "..rageAttacks[1] .. "/" .. rageAttacks[2]
  277.             if (rageAttacks[2] == "Special" or rageAttacks[1] == "Special") then
  278.                 specialAttack = processEnemySpecial(hoverRage)
  279.                 out = specialAttack .. "\n"..out
  280.             end
  281.             printHint(out)
  282.             if (checkIfHelpButton()) then
  283.                 local blockedStatuses = { monStats[0x14], monStats[0x15], monStats[0x16] }
  284.                 local appliedStatuses = { monStats[0x1B], monStats[0x1C], monStats[0x1D] }
  285.                 local absorbElements = monStats[0x17]
  286.                 local immuneElements = monStats[0x18]
  287.                 local weakElements = monStats[0x19]
  288.                 local bytes = ""
  289.                 for i=0,#monStats do
  290.                     bytes = bytes .. " " .. hexformat(monStats[i])
  291.                     if ((i+1) % 8 == 0) then bytes = bytes .. "\n" end
  292.                 end
  293.                 local infoText = ""
  294.                 blockedStatuses = getStatuses(blockedStatuses[1],blockedStatuses[2],blockedStatuses[3])
  295.                 appliedStatuses = getStatuses(appliedStatuses[1],appliedStatuses[2],appliedStatuses[3])
  296.                 if (#appliedStatuses > 0) then infoText = infoText.."GAINS:"..appliedStatuses.."\n" end
  297.                 if (#blockedStatuses > 0) then infoText = infoText.. "BLOCK:"..blockedStatuses.."\n" end
  298.                 absorbElements = getElements(absorbElements)
  299.                 immuneElements = getElements(immuneElements)
  300.                 weakElements = getElements(weakElements)
  301.                 if (#absorbElements > 0) then infoText = infoText.. "ABS:"..absorbElements.."\n" end
  302.                 if (#immuneElements > 0) then infoText = infoText.. "IMM:"..immuneElements.."\n" end
  303.                 if (#weakElements > 0) then infoText = infoText.. "WEAK:"..weakElements.."\n" end
  304.                 infoText = trim(infoText)
  305.                 gui.pixelText(0,0,string.format("%-99s",infoText),"white")
  306.             end
  307.         end
  308.     -- dances
  309.     elseif (cursor_state == 33) then
  310.         local dances = memory.readbyterange(0x267E,8)
  311.         local battleMenuColumn = 0x8937 -- row and scrolled are derived from this (+4/-4)
  312.         local column = memory.read_u8(battleMenuColumn + which_character)
  313.         local row = memory.read_u8(battleMenuColumn + which_character + 4)
  314.         local scrolled = memory.read_u8(battleMenuColumn + which_character - 4)
  315.    
  316.         local hoverDance = dances[((row+scrolled)*2) + column]
  317.         local menuClosing = (memory.read_u8(0x7BCB) > 0) -- get rid of little text-blink as dance menu closes
  318.         if (hoverDance < 255 and not menuClosing) then
  319.             local danceLoc = 0xFFE80 + (4*hoverDance)
  320.             local danceAttacks = { memory.readbyte(danceLoc,"CARTROM"), memory.readbyte(danceLoc+1,"CARTROM"),
  321.                             memory.readbyte(danceLoc+2,"CARTROM"), memory.readbyte(danceLoc+3,"CARTROM") }
  322.             for i=1,4 do danceAttacks[i] = getSpellName(danceAttacks[i]) end
  323.             local danceChances = { 7, 6, 2, 1 }
  324.             if (MOD_TYPE == "BNW") then danceChances = { 7, 5, 3, 1 } end
  325.             local out = string.format("Dance: (%s/16) %s\n       (%s/16) %s\n       (%s/16) %s\n       (%s/16) %s", danceChances[1], danceAttacks[1], danceChances[2], danceAttacks[2], danceChances[3], danceAttacks[3], danceChances[4], danceAttacks[4])
  326.             printHint(out)
  327.         end
  328.     -- targetting enemies
  329.     elseif (cursor_state == 0x38) then
  330.         local targetted_monster = memory.read_u8(0x7B7E)
  331.         -- only bother if we're actually targetting a monster (ie not an ally)
  332.         if (targetted_monster > 0) then
  333.             targetted_monster = (math.log(targetted_monster) / math.log(2))
  334.             if (recentCommandType == 0x00) then -- fight
  335.                 local weaponPropLoc = 0x3CBC --main, then off
  336.                 weaponPropLoc = weaponPropLoc + (2*which_character)
  337.                 local my_weapons = { memory.read_u8(weaponPropLoc), memory.read_u8(weaponPropLoc + 1) }
  338.                 -- the offhand will be shortcircuited if first passes
  339.                 my_weapons[1] = (bit.band(my_weapons[1],0x10) > 0 and my_weapons[1] < 32)
  340.                 if (my_weapons[1] or (bit.band(my_weapons[2],0x10) > 0 and my_weapons[2] < 32)) then
  341.                     local out = doStealStuff(targetted_monster)
  342.                     local weaponLoc = 0x3CA8
  343.                     weaponLoc = weaponLoc + (2*which_character)
  344.                     local providingWeapon = "ThiefKnife"
  345.                     if (my_weapons[1]) then
  346.                         providingWeapon = getItemName(memory.read_u8(weaponLoc))
  347.                     else -- use off-hand since it wasn't from mainhand
  348.                         providingWeapon = getItemName(memory.read_u8(weaponLoc + 1))
  349.                     end
  350.                     printHint("* Shown due to "..providingWeapon..":\n"..out)
  351.                 end
  352.             elseif (recentCommandType == 0x05 or recentCommandType == 0x06) then -- we're stealing and targetting enemies
  353.                 printHint(doStealStuff(targetted_monster))
  354.             elseif (recentCommandType == 0x0D) then --sketch
  355.                 local idxTargetMonster = memory.read_u16_le(0x2001 + (2*targetted_monster))
  356.                 local cantSketchByte = memory.readbyte(offMonsterData + (lenMonsterData * idxTargetMonster) + 0x13,"CARTROM")
  357.                 if (bit.band(cantSketchByte,0x20) > 0) then
  358.                     printHint("Can't sketch!")
  359.                 else
  360.                     local sketchLoc = 0xF4300 + (2*idxTargetMonster)
  361.                     local sketchAttacks = { memory.readbyte(sketchLoc,"CARTROM"), memory.readbyte(sketchLoc+1,"CARTROM") }
  362.                     for i=1,2 do sketchAttacks[i] = getSpellName(sketchAttacks[i]) end
  363.                     local out = "Sketch: (75%) "..sketchAttacks[2] .. "\n        (25%) " .. sketchAttacks[1] ..""
  364.                     if (sketchAttacks[2] == "Special" or sketchAttacks[1] == "Special") then
  365.                         specialAttack = processEnemySpecial(idxTargetMonster)
  366.                         out = specialAttack.."\n"..out
  367.                     end
  368.                     printHint(out)
  369.                 end
  370.             elseif (recentCommandType == 0x0E) then -- chaos control
  371.                 local idxTargetMonster = memory.read_u16_le(0x2001 + (2*targetted_monster))
  372.                 local cantControlByte = memory.readbyte(offMonsterData + (lenMonsterData * idxTargetMonster) + 0x13,"CARTROM")
  373.                 if (bit.band(cantControlByte,0x80) > 0) then
  374.                     printHint("Can't control!")
  375.                 else
  376.                     local controlLoc = 0xF3D00 + (4*idxTargetMonster)
  377.                     local controlAttacks = { memory.readbyte(controlLoc,"CARTROM"), memory.readbyte(controlLoc+1,"CARTROM"), memory.readbyte(controlLoc+2,"CARTROM"), memory.readbyte(controlLoc+3,"CARTROM") }
  378.                     local hasSpecial = false
  379.                     local namesControlAttacks = {}
  380.                     for i=1,4 do
  381.                         if (controlAttacks[i] ~= 0xFF) then
  382.                             namesControlAttacks[#namesControlAttacks + 1] = getSpellName(controlAttacks[i])
  383.                             if (namesControlAttacks[#namesControlAttacks] == "Special") then hasSpecial = true end
  384.                             if (#namesControlAttacks == 3) then namesControlAttacks[3] = "\n         "..namesControlAttacks[3] end
  385.                         end
  386.                     end
  387.                     local out = "Control: "..table.concat(namesControlAttacks,", ")
  388.                     if (hasSpecial) then
  389.                         specialAttack = processEnemySpecial(idxTargetMonster)
  390.                         out = specialAttack.."\n"..out
  391.                     end
  392.                     printHint(out)
  393.                 end
  394.             end
  395.         end
  396.     end
  397. end
  398.  
  399. while true do
  400.     emu.frameadvance();
  401.     -- prevent it from doing dumb things while rom isn't even loaded
  402.     if (romname ~= "Null") then
  403.         buttonHandler()
  404.         main()
  405.     end
  406. end
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top