PokeBot/action/battle.lua

287 lines
6.1 KiB
Lua
Raw Normal View History

2015-04-06 01:18:46 -07:00
local Battle = {}
2014-07-12 18:47:39 -07:00
2015-04-06 01:18:46 -07:00
local Textbox = require "action.textbox"
2014-07-12 18:47:39 -07:00
2015-04-06 01:18:46 -07:00
local Combat = require "ai.combat"
local Control = require "ai.control"
2014-07-12 18:47:39 -07:00
2015-04-06 01:18:46 -07:00
local Memory = require "util.memory"
local Menu = require "util.menu"
local Input = require "util.input"
local Utils = require "util.utils"
2014-07-12 18:47:39 -07:00
2015-04-06 01:18:46 -07:00
local Inventory = require "storage.inventory"
local Pokemon = require "storage.pokemon"
2014-07-12 18:47:39 -07:00
-- HELPERS
2015-04-04 18:37:48 -07:00
local function potionsForHit(potion, curr_hp, max_hp)
if not potion then
2014-07-12 18:47:39 -07:00
return
end
2015-04-06 01:18:46 -07:00
local ours, killAmount = Combat.inKillRange()
if ours then
2015-04-06 01:18:46 -07:00
return Utils.canPotionWith(potion, killAmount, curr_hp, max_hp)
2014-07-12 18:47:39 -07:00
end
end
local function recover()
2015-04-06 01:18:46 -07:00
if Control.canRecover() then
local currentHP = Pokemon.index(0, "hp")
if currentHP > 0 then
2015-04-06 01:18:46 -07:00
local maxHP = Pokemon.index(0, "max_hp")
if currentHP < maxHP then
2014-07-12 18:47:39 -07:00
local first, second
if potionIn == "full" then
2014-07-12 18:47:39 -07:00
first, second = "full_restore", "super_potion"
if maxHP - currentHP > 54 then
2014-07-12 18:47:39 -07:00
first = "full_restore"
second = "super_potion"
else
first = "super_potion"
second = "full_restore"
end
else
if maxHP - currentHP > 22 then
2014-07-12 18:47:39 -07:00
first = "super_potion"
second = "potion"
else
first = "potion"
second = "super_potion"
end
end
2015-04-06 01:18:46 -07:00
local potion = Inventory.contains(first, second)
if potionsForHit(potion, currentHP, maxHP) then
2015-04-06 01:18:46 -07:00
Inventory.use(potion, nil, true)
2014-07-12 18:47:39 -07:00
return true
end
end
end
end
2015-04-06 01:18:46 -07:00
if Memory.value("battle", "paralyzed") == 64 then
local heals = Inventory.contains("paralyze_heal", "full_restore")
if heals then
2015-04-06 01:18:46 -07:00
Inventory.use(heals, nil, true)
2014-07-12 18:47:39 -07:00
return true
end
end
end
local function openBattleMenu()
2015-04-06 01:18:46 -07:00
if Memory.value("battle", "text") == 1 then
Input.cancel()
2014-07-12 18:47:39 -07:00
return false
end
2015-04-06 01:18:46 -07:00
local battleMenu = Memory.value("battle", "menu")
local col = Menu.getCol()
if battleMenu == 106 or (battleMenu == 94 and col == 5) then
2014-07-12 18:47:39 -07:00
return true
elseif battleMenu == 94 then
2015-04-06 01:18:46 -07:00
local rowSelected = Memory.value("menu", "row")
if col == 9 then
if rowSelected == 1 then
2015-04-06 01:18:46 -07:00
Input.press("Up")
2014-07-12 18:47:39 -07:00
else
2015-04-06 01:18:46 -07:00
Input.press("A")
2014-07-12 18:47:39 -07:00
end
else
2015-04-06 01:18:46 -07:00
Input.press("Left")
2014-07-12 18:47:39 -07:00
end
else
2015-04-06 01:18:46 -07:00
Input.press("B")
2014-07-12 18:47:39 -07:00
end
end
local function attack(attackIndex)
2015-04-06 01:18:46 -07:00
if Memory.double("battle", "opponent_hp") < 1 then
Input.cancel()
elseif openBattleMenu() then
2015-04-06 01:18:46 -07:00
Menu.select(attackIndex, true, false, false, false, 3)
2014-07-12 18:47:39 -07:00
end
end
function movePP(name)
local midx = Pokemon.battleMove(name)
if not midx then
return 0
end
return Memory.raw(0x102C + midx)
end
Battle.pp = movePP
-- UTILS
2014-07-12 18:47:39 -07:00
2015-04-06 01:18:46 -07:00
function Battle.swapMove(sidx, fidx)
if openBattleMenu() then
2015-04-06 01:18:46 -07:00
local selection = Memory.value("menu", "selection_mode")
2014-07-12 18:47:39 -07:00
local swapSelect
if selection == sidx then
2014-07-12 18:47:39 -07:00
swapSelect = fidx
else
swapSelect = sidx
end
2015-04-06 01:18:46 -07:00
if Menu.select(swapSelect, false, false, nil, true, 3) then
Input.press("Select")
2014-07-12 18:47:39 -07:00
end
end
end
2015-04-06 01:18:46 -07:00
function Battle.isActive()
return Memory.value("game", "battle") > 0
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
function Battle.isTrainer()
local battleType = Memory.value("game", "battle")
if battleType == 2 then
2014-07-12 18:47:39 -07:00
return true
end
if battleType == 1 then
Battle.handle()
2014-07-12 18:47:39 -07:00
else
2015-04-06 01:18:46 -07:00
Textbox.handle()
2014-07-12 18:47:39 -07:00
end
end
2015-04-06 01:18:46 -07:00
function Battle.opponent()
return Pokemon.getName(Memory.value("battle", "opponent_id"))
2014-07-12 18:47:39 -07:00
end
-- HANDLE
2015-04-06 01:18:46 -07:00
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")
2014-07-12 18:47:39 -07:00
else
2015-04-06 01:18:46 -07:00
Input.cancel()
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
elseif Textbox.handle() then
local selected = Memory.value("menu", "selection")
if selected == 239 then
2015-04-06 01:18:46 -07:00
Input.press("A", 2)
2014-07-12 18:47:39 -07:00
else
2015-04-06 01:18:46 -07:00
Input.escape()
2014-07-12 18:47:39 -07:00
end
end
end
function Battle.handle()
if not Control.shouldCatch() then
if Control.shouldFight() then
Battle.fight()
else
Battle.run()
end
end
end
2015-04-06 01:18:46 -07:00
function Battle.handleWild()
if Memory.value("game", "battle") ~= 1 then
2014-07-12 18:47:39 -07:00
return true
end
Battle.handle()
2014-07-12 18:47:39 -07:00
end
2015-04-09 16:53:56 -07:00
function Battle.fight(move, skipBuffs)
if move then
2015-04-09 16:53:56 -07:00
if type(move) ~= "number" then
2015-04-06 01:18:46 -07:00
move = Pokemon.battleMove(move)
2014-07-12 18:47:39 -07:00
end
attack(move)
else
2015-04-06 01:18:46 -07:00
move = Combat.bestMove()
if move then
2015-04-09 16:53:56 -07:00
Battle.accurateAttack = move.accuracy == 100
2014-07-12 18:47:39 -07:00
attack(move.midx)
2015-04-06 01:18:46 -07:00
elseif Memory.value("menu", "text_length") == 127 then
Input.press("B")
2014-07-12 18:47:39 -07:00
else
2015-04-06 01:18:46 -07:00
Input.cancel()
2014-07-12 18:47:39 -07:00
end
end
end
2015-04-06 01:18:46 -07:00
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)
2014-07-12 18:47:39 -07:00
else
2015-04-06 01:18:46 -07:00
Input.press("A")
2014-07-12 18:47:39 -07:00
end
elseif battleMenu == 94 then
2015-04-06 01:18:46 -07:00
local selected = Memory.value("menu", "selection")
if selected == 199 then
2015-04-06 01:18:46 -07:00
Input.press("A", 2)
elseif Menu.getCol() == 9 then
Input.press("Right", 0)
2014-07-12 18:47:39 -07:00
else
2015-04-06 01:18:46 -07:00
Input.press("Up", 0)
2014-07-12 18:47:39 -07:00
end
else
2015-04-06 01:18:46 -07:00
Input.cancel()
2014-07-12 18:47:39 -07:00
end
end
2015-04-06 01:18:46 -07:00
function Battle.automate(moveName, skipBuffs)
if not recover() then
2015-04-06 01:18:46 -07:00
local state = Memory.value("game", "battle")
if state == 0 then
2015-04-06 01:18:46 -07:00
Input.cancel()
2014-07-12 18:47:39 -07:00
else
if moveName and movePP(moveName) == 0 then
2014-07-12 18:47:39 -07:00
moveName = nil
end
if state == 1 then
2015-04-06 01:18:46 -07:00
if Control.shouldFight() then
2015-04-09 16:53:56 -07:00
Battle.fight(moveName, skipBuffs)
2014-07-12 18:47:39 -07:00
else
2015-04-06 01:18:46 -07:00
Battle.run()
2014-07-12 18:47:39 -07:00
end
elseif state == 2 then
2015-04-09 16:53:56 -07:00
Battle.fight(moveName, skipBuffs)
2014-07-12 18:47:39 -07:00
end
end
end
end
-- SACRIFICE
2015-04-06 01:18:46 -07:00
function Battle.sacrifice(...)
local sacrifice = Pokemon.getSacrifice(...)
if sacrifice then
2015-04-06 01:18:46 -07:00
Battle.swap(sacrifice)
return true
end
return false
end
2015-04-06 01:18:46 -07:00
function Battle.redeployNidoking()
if Pokemon.isDeployed("nidoking") then
return false
end
2015-04-06 01:18:46 -07:00
local battleMenu = Memory.value("battle", "menu")
if Utils.onPokemonSelect(battleMenu) then
Menu.select(0, true)
elseif battleMenu == 95 and Menu.getCol() == 1 then
Input.press("A")
else
2015-04-06 01:18:46 -07:00
local __, turns = Combat.bestMove()
if turns == 1 then
2015-04-09 16:53:56 -07:00
if Pokemon.isDeployed("spearow") then
forced = "growl"
elseif Pokemon.isDeployed("squirtle") then
forced = "tail_whip"
2015-04-09 16:53:56 -07:00
else
forced = "sand_attack"
end
end
2015-04-06 01:18:46 -07:00
Battle.automate(forced)
end
return true
end
2015-04-06 01:18:46 -07:00
return Battle