PokeBot/action/battle.lua

250 lines
5.6 KiB
Lua

local battle = {}
local textbox = require "action.textbox"
local combat = require "ai.combat"
local control = require "ai.control"
local memory = require "util.memory"
local menu = require "util.menu"
local input = require "util.input"
local utils = require "util.utils"
local inventory = require "storage.inventory"
local pokemon = require "storage.pokemon"
local function potionsForHit(potion, currHP, maxHP)
if (not potion) then
return
end
local ours, killAmount = combat.inKillRange()
if (ours) then
local potionHP
if (potion == "full_restore") then
potionHP = 999
elseif (potion == "super_potion") then
potionHP = 50
else
potionHP = 20
end
if (not currHP) then
currHP = pokemon.index(0, "hp")
maxHP = pokemon.index(0, "max_hp")
end
return math.min(currHP + potionHP, maxHP) >= killAmount - 2
end
end
battle.potionsForHit = potionsForHit
local function recover()
if (control.canRecover()) then
local currentHP = pokemon.index(0, "hp")
if (currentHP > 0) then
local maxHP = pokemon.index(0, "max_hp")
if (currentHP < maxHP) then
local first, second
if (potionIn == "full") then
first, second = "full_restore", "super_potion"
if (maxHP - currentHP > 54) then
first = "full_restore"
second = "super_potion"
else
first = "super_potion"
second = "full_restore"
end
else
if (maxHP - currentHP > 22) then
first = "super_potion"
second = "potion"
else
first = "potion"
second = "super_potion"
end
end
local potion = inventory.contains(first, second)
if (potionsForHit(potion, currentHP, maxHP)) then
inventory.use(potion, nil, true)
return true
end
end
end
end
if (memory.value("battle", "paralyzed") == 64) then
local heals = inventory.contains("paralyze_heal", "full_restore")
if (heals) then
inventory.use(heals, nil, true)
return true
end
end
end
local function openBattleMenu()
if (memory.value("battle", "text") == 1) then
input.cancel()
return false
end
local battleMenu = memory.value("battle", "menu")
local col = menu.getCol()
if (battleMenu == 106 or (battleMenu == 94 and col == 5)) then
return true
elseif (battleMenu == 94) then
local rowSelected = memory.value("menu", "row")
if (col == 9) then
if (rowSelected == 1) then
input.press("Up")
else
input.press("A")
end
else
input.press("Left")
end
else
input.press("B")
end
end
local function attack(attackIndex)
if (memory.double("battle", "opponent_hp") < 1) then
input.cancel()
elseif (openBattleMenu()) then
menu.select(attackIndex, true, false, false, false, 3)
end
end
-- Table functions
function battle.swapMove(sidx, fidx)
if (openBattleMenu()) then
local selection = memory.value("menu", "selection_mode")
local swapSelect
if (selection == sidx) then
swapSelect = fidx
else
swapSelect = sidx
end
if (menu.select(swapSelect, false, false, nil, true, 3)) then
input.press("Select")
end
end
end
function battle.isActive()
return memory.value("game", "battle") > 0
end
function battle.isTrainer()
local battleType = memory.value("game", "battle")
if (battleType == 2) then
return true
end
if (battleType == 1) then
battle.run()
else
textbox.handle()
end
end
function battle.opponent()
return pokemon.getName(memory.value("battle", "opponent_id"))
end
function battle.run()
if (memory.double("battle", "opponent_hp") < 1) then
input.cancel()
elseif (memory.value("battle", "menu") ~= 94) then
if (memory.value("menu", "text_length") == 127) then
input.press("B")
else
input.cancel()
end
elseif (textbox.handle()) then
local selected = memory.value("menu", "selection")
if (selected == 239) then
input.press("A", 2)
else
input.escape()
end
end
end
function battle.handleWild()
if (memory.value("game", "battle") ~= 1) then
return true
end
battle.run()
end
function battle.fight(move, isNumber, skipBuffs)
if (move) then
if (not isNumber) then
move = pokemon.battleMove(move)
end
attack(move)
else
move = combat.bestMove()
if (move) then
attack(move.midx)
elseif (memory.value("menu", "text_length") == 127) then
print("Faito B!")
input.press("B")
else
input.cancel()
end
end
end
function battle.swap(target)
local battleMenu = memory.value("battle", "menu")
if (utils.onPokemonSelect(battleMenu)) then
if (menu.getCol() == 0) then
menu.select(pokemon.indexOf(target), true)
else
input.press("A")
end
elseif (battleMenu == 94) then
local selected = memory.value("menu", "selection")
if (selected == 199) then
input.press("A", 2)
elseif (menu.getCol() == 9) then
input.press("Right", 0)
else
input.press("Up", 0)
end
else
input.cancel()
end
end
function movePP(name)
local midx = pokemon.battleMove(name)
if (not midx) then
return 0
end
return memory.raw(0xD02C + midx)
end
battle.pp = movePP
function battle.automate(moveName, skipBuffs)
if (not recover()) then
local state = memory.value("game", "battle")
if (state == 0) then
input.cancel()
else
if (moveName and movePP(moveName) == 0) then
moveName = nil
end
if (state == 1) then
if (control.shouldFight()) then
battle.fight(moveName, false, skipBuffs)
else
battle.run()
end
elseif (state == 2) then
battle.fight(moveName, false, skipBuffs)
end
end
end
end
return battle