Refactor capitalize module names
This commit is contained in:
parent
f7a1faf1ca
commit
c665d3f573
|
@ -28,13 +28,13 @@ MD5: 3d45c1ee9abd5738df46d2bdda8b57dc
|
|||
SHA-1: ea9bcae617fdf159b045185467ae58b2e4a48b9a
|
||||
```
|
||||
|
||||
Open the ROM file with BizHawk (Drag the .gb file onto EmuHawk), and Pokémon Red should start up.
|
||||
Open the ROM file with BizHawk (Drag the .gb file onto EmuHawk), and Pokémon Red should start up.
|
||||
The colors may look weird. To fix this, go to GB>Palette Editor, and then find the POKEMON RED.pal file which should be under Gameboy>Palettes in the directory where BizHawk was unextracted.
|
||||
|
||||
|
||||
##Running the bot##
|
||||
If you want to test the full run, change [this line](https://github.com/kylecoburn/PokeBot/blob/52232581f227b829ea283d795ddaf60a52ce24fe/main.lua#L4) to be false.
|
||||
Then, under the 'Tools' menu, select 'Lua Console'.
|
||||
Then, under the 'Tools' menu, select 'Lua Console'.
|
||||
Click the open folder button, and navigate to the PokéBot folder you downloaded. Select 'main.lua' and press open. The bot should start running!
|
||||
|
||||
Seeds
|
||||
|
|
|
@ -1,33 +1,33 @@
|
|||
local battle = {}
|
||||
local Battle = {}
|
||||
|
||||
local textbox = require "action.textbox"
|
||||
local Textbox = require "action.textbox"
|
||||
|
||||
local combat = require "ai.combat"
|
||||
local control = require "ai.control"
|
||||
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 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 Inventory = require "storage.inventory"
|
||||
local Pokemon = require "storage.pokemon"
|
||||
|
||||
local function potionsForHit(potion, curr_hp, max_hp)
|
||||
if not potion then
|
||||
return
|
||||
end
|
||||
local ours, killAmount = combat.inKillRange()
|
||||
local ours, killAmount = Combat.inKillRange()
|
||||
if ours then
|
||||
return utils.canPotionWith(potion, killAmount, curr_hp, max_hp)
|
||||
return Utils.canPotionWith(potion, killAmount, curr_hp, max_hp)
|
||||
end
|
||||
end
|
||||
|
||||
local function recover()
|
||||
if control.canRecover() then
|
||||
local currentHP = pokemon.index(0, "hp")
|
||||
if Control.canRecover() then
|
||||
local currentHP = Pokemon.index(0, "hp")
|
||||
if currentHP > 0 then
|
||||
local maxHP = pokemon.index(0, "max_hp")
|
||||
local maxHP = Pokemon.index(0, "max_hp")
|
||||
if currentHP < maxHP then
|
||||
local first, second
|
||||
if potionIn == "full" then
|
||||
|
@ -48,216 +48,216 @@ local function recover()
|
|||
second = "super_potion"
|
||||
end
|
||||
end
|
||||
local potion = inventory.contains(first, second)
|
||||
local potion = Inventory.contains(first, second)
|
||||
if potionsForHit(potion, currentHP, maxHP) then
|
||||
inventory.use(potion, nil, true)
|
||||
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 Memory.value("battle", "paralyzed") == 64 then
|
||||
local heals = Inventory.contains("paralyze_heal", "full_restore")
|
||||
if heals then
|
||||
inventory.use(heals, nil, true)
|
||||
Inventory.use(heals, nil, true)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function openBattleMenu()
|
||||
if memory.value("battle", "text") == 1 then
|
||||
input.cancel()
|
||||
if Memory.value("battle", "text") == 1 then
|
||||
Input.cancel()
|
||||
return false
|
||||
end
|
||||
local battleMenu = memory.value("battle", "menu")
|
||||
local col = menu.getCol()
|
||||
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")
|
||||
local rowSelected = Memory.value("menu", "row")
|
||||
if col == 9 then
|
||||
if rowSelected == 1 then
|
||||
input.press("Up")
|
||||
Input.press("Up")
|
||||
else
|
||||
input.press("A")
|
||||
Input.press("A")
|
||||
end
|
||||
else
|
||||
input.press("Left")
|
||||
Input.press("Left")
|
||||
end
|
||||
else
|
||||
input.press("B")
|
||||
Input.press("B")
|
||||
end
|
||||
end
|
||||
|
||||
local function attack(attackIndex)
|
||||
if memory.double("battle", "opponent_hp") < 1 then
|
||||
input.cancel()
|
||||
if Memory.double("battle", "opponent_hp") < 1 then
|
||||
Input.cancel()
|
||||
elseif openBattleMenu() then
|
||||
menu.select(attackIndex, true, false, false, false, 3)
|
||||
Menu.select(attackIndex, true, false, false, false, 3)
|
||||
end
|
||||
end
|
||||
|
||||
-- Table functions
|
||||
|
||||
function battle.swapMove(sidx, fidx)
|
||||
function Battle.swapMove(sidx, fidx)
|
||||
if openBattleMenu() then
|
||||
local selection = memory.value("menu", "selection_mode")
|
||||
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")
|
||||
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
|
||||
function Battle.isActive()
|
||||
return Memory.value("game", "battle") > 0
|
||||
end
|
||||
|
||||
function battle.isTrainer()
|
||||
local battleType = memory.value("game", "battle")
|
||||
function Battle.isTrainer()
|
||||
local battleType = Memory.value("game", "battle")
|
||||
if battleType == 2 then
|
||||
return true
|
||||
end
|
||||
if battleType == 1 then
|
||||
battle.run()
|
||||
Battle.run()
|
||||
else
|
||||
textbox.handle()
|
||||
Textbox.handle()
|
||||
end
|
||||
end
|
||||
|
||||
function battle.opponent()
|
||||
return pokemon.getName(memory.value("battle", "opponent_id"))
|
||||
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")
|
||||
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()
|
||||
Input.cancel()
|
||||
end
|
||||
elseif textbox.handle() then
|
||||
local selected = memory.value("menu", "selection")
|
||||
elseif Textbox.handle() then
|
||||
local selected = Memory.value("menu", "selection")
|
||||
if selected == 239 then
|
||||
input.press("A", 2)
|
||||
Input.press("A", 2)
|
||||
else
|
||||
input.escape()
|
||||
Input.escape()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function battle.handleWild()
|
||||
if memory.value("game", "battle") ~= 1 then
|
||||
function Battle.handleWild()
|
||||
if Memory.value("game", "battle") ~= 1 then
|
||||
return true
|
||||
end
|
||||
battle.run()
|
||||
Battle.run()
|
||||
end
|
||||
|
||||
function battle.fight(move, isNumber, skipBuffs)
|
||||
function Battle.fight(move, isNumber, skipBuffs)
|
||||
if move then
|
||||
if not isNumber then
|
||||
move = pokemon.battleMove(move)
|
||||
move = Pokemon.battleMove(move)
|
||||
end
|
||||
attack(move)
|
||||
else
|
||||
move = combat.bestMove()
|
||||
move = Combat.bestMove()
|
||||
if move then
|
||||
attack(move.midx)
|
||||
elseif memory.value("menu", "text_length") == 127 then
|
||||
input.press("B")
|
||||
elseif Memory.value("menu", "text_length") == 127 then
|
||||
Input.press("B")
|
||||
else
|
||||
input.cancel()
|
||||
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)
|
||||
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")
|
||||
Input.press("A")
|
||||
end
|
||||
elseif battleMenu == 94 then
|
||||
local selected = memory.value("menu", "selection")
|
||||
local selected = Memory.value("menu", "selection")
|
||||
if selected == 199 then
|
||||
input.press("A", 2)
|
||||
elseif menu.getCol() == 9 then
|
||||
input.press("Right", 0)
|
||||
Input.press("A", 2)
|
||||
elseif Menu.getCol() == 9 then
|
||||
Input.press("Right", 0)
|
||||
else
|
||||
input.press("Up", 0)
|
||||
Input.press("Up", 0)
|
||||
end
|
||||
else
|
||||
input.cancel()
|
||||
Input.cancel()
|
||||
end
|
||||
end
|
||||
|
||||
function movePP(name)
|
||||
local midx = pokemon.battleMove(name)
|
||||
local midx = Pokemon.battleMove(name)
|
||||
if not midx then
|
||||
return 0
|
||||
end
|
||||
return memory.raw(0x102C + midx)
|
||||
return Memory.raw(0x102C + midx)
|
||||
end
|
||||
battle.pp = movePP
|
||||
Battle.pp = movePP
|
||||
|
||||
function battle.automate(moveName, skipBuffs)
|
||||
function Battle.automate(moveName, skipBuffs)
|
||||
if not recover() then
|
||||
local state = memory.value("game", "battle")
|
||||
local state = Memory.value("game", "battle")
|
||||
if state == 0 then
|
||||
input.cancel()
|
||||
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)
|
||||
if Control.shouldFight() then
|
||||
Battle.fight(moveName, false, skipBuffs)
|
||||
else
|
||||
battle.run()
|
||||
Battle.run()
|
||||
end
|
||||
elseif state == 2 then
|
||||
battle.fight(moveName, false, skipBuffs)
|
||||
Battle.fight(moveName, false, skipBuffs)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function battle.sacrifice(...)
|
||||
local sacrifice = pokemon.getSacrifice(...)
|
||||
function Battle.sacrifice(...)
|
||||
local sacrifice = Pokemon.getSacrifice(...)
|
||||
if sacrifice then
|
||||
battle.swap(sacrifice)
|
||||
Battle.swap(sacrifice)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function battle.redeployNidoking()
|
||||
if pokemon.isDeployed("nidoking") then
|
||||
function Battle.redeployNidoking()
|
||||
if Pokemon.isDeployed("nidoking") then
|
||||
return false
|
||||
end
|
||||
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")
|
||||
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
|
||||
local __, turns = combat.bestMove()
|
||||
local __, turns = Combat.bestMove()
|
||||
if turns == 1 then
|
||||
forced = "sand_attack"
|
||||
end
|
||||
battle.automate(forced)
|
||||
Battle.automate(forced)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
return battle
|
||||
return Battle
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
local shop = {}
|
||||
local Shop = {}
|
||||
|
||||
local textbox = require "action.textbox"
|
||||
local Textbox = require "action.textbox"
|
||||
|
||||
local input = require "util.input"
|
||||
local memory = require "util.memory"
|
||||
local menu = require "util.menu"
|
||||
local player = require "util.player"
|
||||
local Input = require "util.input"
|
||||
local Memory = require "util.memory"
|
||||
local Menu = require "util.menu"
|
||||
local Player = require "util.player"
|
||||
|
||||
local inventory = require "storage.inventory"
|
||||
local Inventory = require "storage.inventory"
|
||||
|
||||
function shop.transaction(options)
|
||||
function Shop.transaction(options)
|
||||
local item, itemMenu, menuIdx, quantityMenu
|
||||
if options.sell then
|
||||
menuIdx = 1
|
||||
itemMenu = 29
|
||||
quantityMenu = 158
|
||||
for i,sit in ipairs(options.sell) do
|
||||
local idx = inventory.indexOf(sit.name)
|
||||
local idx = Inventory.indexOf(sit.name)
|
||||
if idx ~= -1 then
|
||||
item = sit
|
||||
item.index = idx
|
||||
item.amount = inventory.count(sit.name)
|
||||
item.amount = Inventory.count(sit.name)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
@ -30,7 +30,7 @@ function shop.transaction(options)
|
|||
itemMenu = 123
|
||||
quantityMenu = 161
|
||||
for i,bit in ipairs(options.buy) do
|
||||
local needed = (bit.amount or 1) - inventory.count(bit.name)
|
||||
local needed = (bit.amount or 1) - Inventory.count(bit.name)
|
||||
if needed > 0 then
|
||||
item = bit
|
||||
item.amount = needed
|
||||
|
@ -39,44 +39,44 @@ function shop.transaction(options)
|
|||
end
|
||||
end
|
||||
if not item then
|
||||
if not textbox.isActive() then
|
||||
if not Textbox.isActive() then
|
||||
return true
|
||||
end
|
||||
input.press("B")
|
||||
elseif player.isFacing(options.direction or "Left") then
|
||||
if textbox.isActive() then
|
||||
if menu.isCurrently(32, "shop") then
|
||||
menu.select(menuIdx, true, false, "shop")
|
||||
elseif menu.getCol() == 15 then
|
||||
input.press("A")
|
||||
elseif menu.isCurrently(itemMenu, "transaction") then
|
||||
if menu.select(item.index, "accelerate", true, "transaction", true) then
|
||||
if menu.isCurrently(quantityMenu, "shop") then
|
||||
local currAmount = memory.value("shop", "transaction_amount")
|
||||
if menu.balance(currAmount, item.amount, false, 99, true) then
|
||||
input.press("A")
|
||||
Input.press("B")
|
||||
elseif Player.isFacing(options.direction or "Left") then
|
||||
if Textbox.isActive() then
|
||||
if Menu.isCurrently(32, "shop") then
|
||||
Menu.select(menuIdx, true, false, "shop")
|
||||
elseif Menu.getCol() == 15 then
|
||||
Input.press("A")
|
||||
elseif Menu.isCurrently(itemMenu, "transaction") then
|
||||
if Menu.select(item.index, "accelerate", true, "transaction", true) then
|
||||
if Menu.isCurrently(quantityMenu, "shop") then
|
||||
local currAmount = Memory.value("shop", "transaction_amount")
|
||||
if Menu.balance(currAmount, item.amount, false, 99, true) then
|
||||
Input.press("A")
|
||||
end
|
||||
else
|
||||
input.press("A")
|
||||
Input.press("A")
|
||||
end
|
||||
end
|
||||
else
|
||||
input.press("B")
|
||||
Input.press("B")
|
||||
end
|
||||
else
|
||||
input.press("A", 2)
|
||||
Input.press("A", 2)
|
||||
end
|
||||
else
|
||||
player.interact(options.direction or "Left")
|
||||
Player.interact(options.direction or "Left")
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function shop.vend(options)
|
||||
function Shop.vend(options)
|
||||
local item
|
||||
menuIdx = 0
|
||||
for i,bit in ipairs(options.buy) do
|
||||
local needed = (bit.amount or 1) - inventory.count(bit.name)
|
||||
local needed = (bit.amount or 1) - Inventory.count(bit.name)
|
||||
if needed > 0 then
|
||||
item = bit
|
||||
item.buy = needed
|
||||
|
@ -84,22 +84,22 @@ function shop.vend(options)
|
|||
end
|
||||
end
|
||||
if not item then
|
||||
if not textbox.isActive() then
|
||||
if not Textbox.isActive() then
|
||||
return true
|
||||
end
|
||||
input.press("B")
|
||||
elseif player.face(options.direction) then
|
||||
if textbox.isActive() then
|
||||
if memory.value("battle", "text") > 1 and memory.value("battle", "menu") ~= 95 then
|
||||
menu.select(item.index, true)
|
||||
Input.press("B")
|
||||
elseif Player.face(options.direction) then
|
||||
if Textbox.isActive() then
|
||||
if Memory.value("battle", "text") > 1 and Memory.value("battle", "menu") ~= 95 then
|
||||
Menu.select(item.index, true)
|
||||
else
|
||||
input.press("A")
|
||||
Input.press("A")
|
||||
end
|
||||
else
|
||||
input.press("A", 2)
|
||||
Input.press("A", 2)
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
return shop
|
||||
return Shop
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
local textbox = {}
|
||||
local Textbox = {}
|
||||
|
||||
local input = require "util.input"
|
||||
local memory = require "util.memory"
|
||||
local menu = require "util.menu"
|
||||
local utils = require "util.utils"
|
||||
local Input = require "util.input"
|
||||
local Memory = require "util.memory"
|
||||
local Menu = require "util.menu"
|
||||
|
||||
local alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ *():;[]ab-?!mf/.,"
|
||||
-- local alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ *():;[]ポモ-?!♂♀/.,"
|
||||
|
@ -19,11 +18,11 @@ local function getIndexForLetter(letter)
|
|||
return alphabet:find(letter, 1, true)
|
||||
end
|
||||
|
||||
function textbox.name(letter, randomize)
|
||||
local inputting = memory.value("menu", "text_input") == 240
|
||||
function Textbox.name(letter, randomize)
|
||||
local inputting = Memory.value("menu", "text_input") == 240
|
||||
if inputting then
|
||||
if memory.value("menu", "text_length") > 0 then
|
||||
input.press("Start")
|
||||
if Memory.value("menu", "text_length") > 0 then
|
||||
Input.press("Start")
|
||||
return true
|
||||
end
|
||||
local lidx
|
||||
|
@ -33,29 +32,29 @@ function textbox.name(letter, randomize)
|
|||
lidx = nidoIdx
|
||||
end
|
||||
|
||||
local crow = memory.value("menu", "input_row")
|
||||
local crow = Memory.value("menu", "input_row")
|
||||
local drow = math.ceil(lidx / 9)
|
||||
if menu.balance(crow, drow, true, 6, true) then
|
||||
local ccol = math.floor(memory.value("menu", "column") / 2)
|
||||
if Menu.balance(crow, drow, true, 6, true) then
|
||||
local ccol = math.floor(Memory.value("menu", "column") / 2)
|
||||
local dcol = math.fmod(lidx - 1, 9)
|
||||
if menu.sidle(ccol, dcol, 9, true) then
|
||||
input.press("A")
|
||||
if Menu.sidle(ccol, dcol, 9, true) then
|
||||
Input.press("A")
|
||||
end
|
||||
end
|
||||
else
|
||||
-- TODO cancel when menu isn't up
|
||||
-- if memory.value("menu", "current") == 7 then
|
||||
if memory.raw(0x10B7) == 3 then
|
||||
input.press("A", 2)
|
||||
-- if Memory.value("menu", "current") == 7 then
|
||||
if Memory.raw(0x10B7) == 3 then
|
||||
Input.press("A", 2)
|
||||
elseif randomize then
|
||||
input.press("A", math.random(1, 5))
|
||||
Input.press("A", math.random(1, 5))
|
||||
else
|
||||
input.cancel()
|
||||
Input.cancel()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function textbox.getName()
|
||||
function Textbox.getName()
|
||||
if nidoName == "a" then
|
||||
return "ポ"
|
||||
end
|
||||
|
@ -71,22 +70,22 @@ function textbox.getName()
|
|||
return nidoName
|
||||
end
|
||||
|
||||
function textbox.setName(index)
|
||||
function Textbox.setName(index)
|
||||
if index >= 0 and index < #alphabet then
|
||||
nidoIdx = index + 1
|
||||
nidoName = getLetterAt(index)
|
||||
end
|
||||
end
|
||||
|
||||
function textbox.isActive()
|
||||
return memory.value("game", "textbox") == 1
|
||||
function Textbox.isActive()
|
||||
return Memory.value("game", "textbox") == 1
|
||||
end
|
||||
|
||||
function textbox.handle()
|
||||
if not textbox.isActive() then
|
||||
function Textbox.handle()
|
||||
if not Textbox.isActive() then
|
||||
return true
|
||||
end
|
||||
input.cancel()
|
||||
Input.cancel()
|
||||
end
|
||||
|
||||
return textbox
|
||||
return Textbox
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
local walk = {}
|
||||
local Walk = {}
|
||||
|
||||
local control = require "ai.control"
|
||||
local Control = require "ai.control"
|
||||
local paths = require("data."..GAME_NAME..".paths")
|
||||
|
||||
local input = require "util.input"
|
||||
local memory = require "util.memory"
|
||||
local player = require "util.player"
|
||||
local utils = require "util.utils"
|
||||
local Input = require "util.input"
|
||||
local Memory = require "util.memory"
|
||||
local Player = require "util.player"
|
||||
|
||||
local pokemon = require "storage.pokemon"
|
||||
local Pokemon = require "storage.pokemon"
|
||||
|
||||
local path, stepIdx, currentMap
|
||||
local pathIdx = 0
|
||||
|
@ -26,7 +25,7 @@ end
|
|||
|
||||
local function completeStep(region)
|
||||
stepIdx = stepIdx + 1
|
||||
return walk.traverse(region)
|
||||
return Walk.traverse(region)
|
||||
end
|
||||
|
||||
-- Helper functions
|
||||
|
@ -44,31 +43,31 @@ function dir(px, py, dx, dy)
|
|||
end
|
||||
return direction
|
||||
end
|
||||
walk.dir = dir
|
||||
Walk.dir = dir
|
||||
|
||||
function step(dx, dy)
|
||||
local px, py = player.position()
|
||||
local px, py = Player.position()
|
||||
if px == dx and py == dy then
|
||||
return true
|
||||
end
|
||||
input.press(dir(px, py, dx, dy), 0)
|
||||
Input.press(dir(px, py, dx, dy), 0)
|
||||
end
|
||||
walk.step = step
|
||||
Walk.step = step
|
||||
|
||||
-- Table functions
|
||||
|
||||
function walk.reset()
|
||||
function Walk.reset()
|
||||
path = nil
|
||||
pathIdx = 0
|
||||
customIdx = 1
|
||||
customDir = 1
|
||||
currentMap = nil
|
||||
walk.strategy = nil
|
||||
Walk.strategy = nil
|
||||
end
|
||||
|
||||
function walk.init()
|
||||
local region = memory.value("game", "map")
|
||||
local px, py = player.position()
|
||||
function Walk.init()
|
||||
local region = Memory.value("game", "map")
|
||||
local px, py = Player.position()
|
||||
if region == 0 and px == 0 and py == 0 then
|
||||
return false
|
||||
end
|
||||
|
@ -85,10 +84,10 @@ function walk.init()
|
|||
end
|
||||
end
|
||||
|
||||
function walk.traverse(region)
|
||||
function Walk.traverse(region)
|
||||
local newIndex
|
||||
if not path or currentMap ~= region then
|
||||
walk.strategy = nil
|
||||
Walk.strategy = nil
|
||||
setPath(pathIdx + 1, region)
|
||||
newIndex = pathIdx
|
||||
customIdx = 1
|
||||
|
@ -98,36 +97,36 @@ function walk.traverse(region)
|
|||
end
|
||||
local tile = path[stepIdx]
|
||||
if tile.c then
|
||||
control.set(tile)
|
||||
Control.set(tile)
|
||||
return completeStep(region)
|
||||
end
|
||||
if tile.s then
|
||||
if walk.strategy then
|
||||
walk.strategy = nil
|
||||
if Walk.strategy then
|
||||
Walk.strategy = nil
|
||||
return completeStep(region)
|
||||
end
|
||||
walk.strategy = tile
|
||||
Walk.strategy = tile
|
||||
elseif step(tile[1], tile[2]) then
|
||||
pokemon.updateParty()
|
||||
Pokemon.updateParty()
|
||||
return completeStep(region)
|
||||
end
|
||||
return newIndex
|
||||
end
|
||||
|
||||
function walk.canMove()
|
||||
return memory.value("player", "moving") == 0 and memory.value("player", "fighting") == 0
|
||||
function Walk.canMove()
|
||||
return Memory.value("player", "moving") == 0 and Memory.value("player", "fighting") == 0
|
||||
end
|
||||
|
||||
-- Custom path
|
||||
|
||||
function walk.invertCustom(silent)
|
||||
function Walk.invertCustom(silent)
|
||||
if not silent then
|
||||
customIdx = customIdx + customDir
|
||||
end
|
||||
customDir = customDir * -1
|
||||
end
|
||||
|
||||
function walk.custom(cpath, increment)
|
||||
function Walk.custom(cpath, increment)
|
||||
if not cpath then
|
||||
customIdx = 1
|
||||
customDir = 1
|
||||
|
@ -147,8 +146,8 @@ function walk.custom(cpath, increment)
|
|||
end
|
||||
local t1, t2 = tile[1], tile[2]
|
||||
if t2 == nil then
|
||||
if player.face(t1) then
|
||||
input.press("A", 2)
|
||||
if Player.face(t1) then
|
||||
Input.press("A", 2)
|
||||
end
|
||||
return t1
|
||||
end
|
||||
|
@ -157,4 +156,4 @@ function walk.custom(cpath, increment)
|
|||
end
|
||||
end
|
||||
|
||||
return walk
|
||||
return Walk
|
||||
|
|
109
ai/combat.lua
109
ai/combat.lua
|
@ -1,10 +1,9 @@
|
|||
local combat = {}
|
||||
local Combat = {}
|
||||
|
||||
local movelist = require "data.movelist"
|
||||
local opponents = require "data.opponents"
|
||||
local Movelist = require "data.movelist"
|
||||
local Opponents = require "data.opponents"
|
||||
|
||||
local memory = require "util.memory"
|
||||
local utils = require "util.utils"
|
||||
local Memory = require "util.memory"
|
||||
|
||||
local damageMultiplier = { -- http://bulbapedia.bulbagarden.net/wiki/Type_chart#Generation_I
|
||||
normal = {normal=1.0, fighting=1.0, flying=1.0, poison=1.0, ground=1.0, rock=0.5, bug=1.0, ghost=0.0, fire=1.0, water=1.0, grass=1.0, electric=1.0, psychic=1.0, ice=1.0, dragon=1.0, },
|
||||
|
@ -47,9 +46,9 @@ local enablePP = false
|
|||
local floor = math.floor
|
||||
|
||||
local function isDisabled(mid)
|
||||
return mid == memory.value("battle", "disabled")
|
||||
return mid == Memory.value("battle", "disabled")
|
||||
end
|
||||
combat.isDisabled = isDisabled
|
||||
Combat.isDisabled = isDisabled
|
||||
|
||||
local function calcDamage(move, attacker, defender, rng)
|
||||
if move.fixed then
|
||||
|
@ -60,14 +59,14 @@ local function calcDamage(move, attacker, defender, rng)
|
|||
end
|
||||
if move.power > 9000 then
|
||||
local oid = defender.id
|
||||
if oid ~= 14 and oid ~= 147 and oid ~= 171 and (oidd ~= 151 or memory.value("game", "map") == 120) then -- ???
|
||||
if memory.value("battle", "x_accuracy") == 1 and defender.speed < attacker.speed then
|
||||
if oid ~= 14 and oid ~= 147 and oid ~= 171 and (oidd ~= 151 or Memory.value("game", "map") == 120) then -- ???
|
||||
if Memory.value("battle", "x_accuracy") == 1 and defender.speed < attacker.speed then
|
||||
return 9001, 9001
|
||||
end
|
||||
end
|
||||
return 0, 0
|
||||
end
|
||||
if move.name == "Thrash" and combat.disableThrash then
|
||||
if move.name == "Thrash" and Combat.disableThrash then
|
||||
return 0, 0
|
||||
end
|
||||
|
||||
|
@ -96,34 +95,34 @@ local function calcDamage(move, attacker, defender, rng)
|
|||
end
|
||||
|
||||
local function getOpponentType(ty)
|
||||
local t1 = types[memory.value("battle", "opponent_type1")]
|
||||
local t1 = types[Memory.value("battle", "opponent_type1")]
|
||||
if ty ~= 0 then
|
||||
t1 = types[memory.value("battle", "opponent_type2")]
|
||||
t1 = types[Memory.value("battle", "opponent_type2")]
|
||||
if not t1 then
|
||||
return memory.value("battle", "opponent_type2")
|
||||
return Memory.value("battle", "opponent_type2")
|
||||
end
|
||||
end
|
||||
if t1 then
|
||||
return t1
|
||||
end
|
||||
return memory.value("battle", "opponent_type1")
|
||||
return Memory.value("battle", "opponent_type1")
|
||||
end
|
||||
combat.getOpponentType = getOpponentType
|
||||
Combat.getOpponentType = getOpponentType
|
||||
|
||||
function getOurType(ty)
|
||||
local t1 = types[memory.value("battle", "our_type1")]
|
||||
local t1 = types[Memory.value("battle", "our_type1")]
|
||||
if ty ~= 0 then
|
||||
t1 = types[memory.value("battle", "our_type2")]
|
||||
t1 = types[Memory.value("battle", "our_type2")]
|
||||
if not t1 then
|
||||
return memory.value("battle", "opponent_type2")
|
||||
return Memory.value("battle", "opponent_type2")
|
||||
end
|
||||
end
|
||||
if t1 then
|
||||
return t1
|
||||
end
|
||||
return memory.value("battle", "opponent_type1")
|
||||
return Memory.value("battle", "opponent_type1")
|
||||
end
|
||||
combat.getOurType = getOurType
|
||||
Combat.getOurType = getOurType
|
||||
|
||||
local function getMoves(who)--Get the moveset of us [0] or them [1]
|
||||
local moves = {}
|
||||
|
@ -134,18 +133,18 @@ local function getMoves(who)--Get the moveset of us [0] or them [1]
|
|||
base = 0x101C
|
||||
end
|
||||
for idx=0, 3 do
|
||||
local val = memory.raw(base + idx)
|
||||
local val = Memory.raw(base + idx)
|
||||
if val > 0 then
|
||||
local moveTable = movelist.get(val)
|
||||
local moveTable = Movelist.get(val)
|
||||
if who == 0 then
|
||||
moveTable.pp = memory.raw(0x102D + idx)
|
||||
moveTable.pp = Memory.raw(0x102D + idx)
|
||||
end
|
||||
moves[idx + 1] = moveTable
|
||||
end
|
||||
end
|
||||
return moves
|
||||
end
|
||||
combat.getMoves = getMoves
|
||||
Combat.getMoves = getMoves
|
||||
|
||||
local function modPlayerStats(user, enemy, move)
|
||||
local effect = move.effects
|
||||
|
@ -183,9 +182,9 @@ local function calcBestHit(attacker, defender, ours, rng)
|
|||
if not ret or minTurns < bestMinTurns or maxTurns < bestTurns then
|
||||
replaces = true
|
||||
elseif maxTurns == bestTurns and move.name == "Thrash" then
|
||||
replaces = defender.hp == memory.double("battle", "opponent_max_hp")
|
||||
replaces = defender.hp == Memory.double("battle", "opponent_max_hp")
|
||||
elseif maxTurns == bestTurns and ret.name == "Thrash" then
|
||||
replaces = defender.hp ~= memory.double("battle", "opponent_max_hp")
|
||||
replaces = defender.hp ~= Memory.double("battle", "opponent_max_hp")
|
||||
elseif move.fast and not ret.fast then
|
||||
replaces = maxTurns <= bestTurns
|
||||
elseif ret.fast then
|
||||
|
@ -245,13 +244,13 @@ end
|
|||
|
||||
local function activePokemon(preset)
|
||||
local ours = {
|
||||
id = memory.value("battle", "our_id"),
|
||||
level = memory.value("battle", "our_level"),
|
||||
hp = memory.double("battle", "our_hp"),
|
||||
att = memory.double("battle", "our_attack"),
|
||||
def = memory.double("battle", "our_defense"),
|
||||
spec = memory.double("battle", "our_special"),
|
||||
speed = memory.double("battle", "our_speed"),
|
||||
id = Memory.value("battle", "our_id"),
|
||||
level = Memory.value("battle", "our_level"),
|
||||
hp = Memory.double("battle", "our_hp"),
|
||||
att = Memory.double("battle", "our_attack"),
|
||||
def = Memory.double("battle", "our_defense"),
|
||||
spec = Memory.double("battle", "our_special"),
|
||||
speed = Memory.double("battle", "our_speed"),
|
||||
type1 = getOurType(0),
|
||||
type2 = getOurType(1),
|
||||
moves = getMoves(0),
|
||||
|
@ -259,7 +258,7 @@ local function activePokemon(preset)
|
|||
|
||||
local enemy
|
||||
if preset then
|
||||
enemy = opponents[preset]
|
||||
enemy = Opponents[preset]
|
||||
local toBoost = enemy.boost
|
||||
if toBoost then
|
||||
local currSpec = ours.spec
|
||||
|
@ -270,13 +269,13 @@ local function activePokemon(preset)
|
|||
end
|
||||
else
|
||||
enemy = {
|
||||
id = memory.value("battle", "opponent_id"),
|
||||
level = memory.value("battle", "opponent_level"),
|
||||
hp = memory.double("battle", "opponent_hp"),
|
||||
att = memory.double("battle", "opponent_attack"),
|
||||
def = memory.double("battle", "opponent_defense"),
|
||||
spec = memory.double("battle", "opponent_special"),
|
||||
speed = memory.double("battle", "opponent_speed"),
|
||||
id = Memory.value("battle", "opponent_id"),
|
||||
level = Memory.value("battle", "opponent_level"),
|
||||
hp = Memory.double("battle", "opponent_hp"),
|
||||
att = Memory.double("battle", "opponent_attack"),
|
||||
def = Memory.double("battle", "opponent_defense"),
|
||||
spec = Memory.double("battle", "opponent_special"),
|
||||
speed = Memory.double("battle", "opponent_speed"),
|
||||
type1 = getOpponentType(0),
|
||||
type2 = getOpponentType(1),
|
||||
moves = getMoves(1),
|
||||
|
@ -284,35 +283,35 @@ local function activePokemon(preset)
|
|||
end
|
||||
return ours, enemy
|
||||
end
|
||||
combat.activePokemon = activePokemon
|
||||
Combat.activePokemon = activePokemon
|
||||
|
||||
local function isSleeping()
|
||||
return memory.raw(0x116F) > 1
|
||||
return Memory.raw(0x116F) > 1
|
||||
end
|
||||
combat.isSleeping = isSleeping
|
||||
Combat.isSleeping = isSleeping
|
||||
|
||||
local function isConfused()
|
||||
return memory.raw(0x106B) > 0
|
||||
return Memory.raw(0x106B) > 0
|
||||
end
|
||||
combat.isConfused = isConfused
|
||||
Combat.isConfused = isConfused
|
||||
|
||||
-- Combat AI
|
||||
|
||||
function combat.factorPP(enabled)
|
||||
function Combat.factorPP(enabled)
|
||||
enablePP = enabled
|
||||
end
|
||||
|
||||
function combat.reset()
|
||||
function Combat.reset()
|
||||
enablePP = false
|
||||
end
|
||||
|
||||
function combat.healthFor(opponent)
|
||||
function Combat.healthFor(opponent)
|
||||
local ours, enemy = activePokemon(opponent)
|
||||
local enemyAttack, turnsToDie = calcBestHit(enemy, ours, false)
|
||||
return enemyAttack.damage
|
||||
end
|
||||
|
||||
function combat.inKillRange(draw)
|
||||
function Combat.inKillRange(draw)
|
||||
local ours, enemy = activePokemon()
|
||||
local enemyAttack, __ = calcBestHit(enemy, ours, false)
|
||||
local __, turnsToKill = calcBestHit(ours, enemy, true)
|
||||
|
@ -331,7 +330,7 @@ function combat.inKillRange(draw)
|
|||
if ours.hp < hpReq then
|
||||
local outspeed = enemyAttack.outspeed
|
||||
if outspeed and outspeed ~= true then
|
||||
outspeed = memory.value("battle", "turns") > 0
|
||||
outspeed = Memory.value("battle", "turns") > 0
|
||||
end
|
||||
if outspeed or isConfused or turnsToKill > 1 or ours.speed <= enemy.speed or isSleeping() then
|
||||
return ours, hpReq
|
||||
|
@ -353,7 +352,7 @@ local function getBattlePokemon()
|
|||
return ours, enemy
|
||||
end
|
||||
|
||||
function combat.nonKill()
|
||||
function Combat.nonKill()
|
||||
local ours, enemy = getBattlePokemon()
|
||||
if not enemy then
|
||||
return
|
||||
|
@ -373,14 +372,14 @@ function combat.nonKill()
|
|||
return ret
|
||||
end
|
||||
|
||||
function combat.bestMove()
|
||||
function Combat.bestMove()
|
||||
local ours, enemy = getBattlePokemon()
|
||||
if enemy then
|
||||
return getBestMove(ours, enemy)
|
||||
end
|
||||
end
|
||||
|
||||
function combat.enemyAttack()
|
||||
function Combat.enemyAttack()
|
||||
local ours, enemy = activePokemon()
|
||||
if enemy.hp == 0 then
|
||||
return
|
||||
|
@ -388,4 +387,4 @@ function combat.enemyAttack()
|
|||
return calcBestHit(enemy, ours, false)
|
||||
end
|
||||
|
||||
return combat
|
||||
return Combat
|
||||
|
|
118
ai/control.lua
118
ai/control.lua
|
@ -1,17 +1,15 @@
|
|||
local control = {}
|
||||
local Control = {}
|
||||
|
||||
local combat = require "ai.combat"
|
||||
local strategies
|
||||
local Combat = require "ai.combat"
|
||||
local Strategies
|
||||
|
||||
local bridge = require "util.bridge"
|
||||
local memory = require "util.memory"
|
||||
local menu = require "util.menu"
|
||||
local paint = require "util.paint"
|
||||
local player = require "util.player"
|
||||
local utils = require "util.utils"
|
||||
local Bridge = require "util.bridge"
|
||||
local Memory = require "util.memory"
|
||||
local Paint = require "util.paint"
|
||||
local Utils = require "util.utils"
|
||||
|
||||
local inventory = require "storage.inventory"
|
||||
local pokemon = require "storage.pokemon"
|
||||
local Inventory = require "storage.inventory"
|
||||
local Pokemon = require "storage.pokemon"
|
||||
|
||||
local potionInBattle = true
|
||||
local fightEncounter, caveFights = 0, 0
|
||||
|
@ -22,20 +20,20 @@ local shouldCatch, attackIdx
|
|||
local extraEncounter, maxEncounters
|
||||
local battleYolo
|
||||
|
||||
control.areaName = "Unknown"
|
||||
control.moonEncounters = nil
|
||||
control.yolo = false
|
||||
Control.areaName = "Unknown"
|
||||
Control.moonEncounters = nil
|
||||
Control.yolo = false
|
||||
|
||||
local controlFunctions = {
|
||||
|
||||
a = function(data)
|
||||
control.areaName = data.a
|
||||
Control.areaName = data.a
|
||||
return true
|
||||
end,
|
||||
|
||||
potion = function(data)
|
||||
if data.b ~= nil then
|
||||
control.battlePotion(data.b)
|
||||
Control.battlePotion(data.b)
|
||||
end
|
||||
battleYolo = data.yolo
|
||||
end,
|
||||
|
@ -48,11 +46,11 @@ local controlFunctions = {
|
|||
end,
|
||||
|
||||
pp = function(data)
|
||||
combat.factorPP(data.on)
|
||||
Combat.factorPP(data.on)
|
||||
end,
|
||||
|
||||
setThrash = function(data)
|
||||
combat.disableThrash = data.disable
|
||||
Combat.disableThrash = data.disable
|
||||
end,
|
||||
|
||||
disableCatch = function()
|
||||
|
@ -113,11 +111,11 @@ local controlFunctions = {
|
|||
|
||||
-- COMBAT
|
||||
|
||||
function control.battlePotion(enable)
|
||||
function Control.battlePotion(enable)
|
||||
potionInBattle = enable
|
||||
end
|
||||
|
||||
function control.canDie(enabled)
|
||||
function Control.canDie(enabled)
|
||||
if enabled == nil then
|
||||
return canDie
|
||||
end
|
||||
|
@ -125,25 +123,25 @@ function control.canDie(enabled)
|
|||
end
|
||||
|
||||
local function isNewFight()
|
||||
if fightEncounter < encounters and memory.double("battle", "opponent_hp") == memory.double("battle", "opponent_max_hp") then
|
||||
if fightEncounter < encounters and Memory.double("battle", "opponent_hp") == Memory.double("battle", "opponent_max_hp") then
|
||||
fightEncounter = encounters
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function control.shouldFight()
|
||||
function Control.shouldFight()
|
||||
if not shouldFight then
|
||||
return false
|
||||
end
|
||||
local expTotal = pokemon.getExp()
|
||||
local expTotal = Pokemon.getExp()
|
||||
if expTotal < minExp then
|
||||
local oid = memory.value("battle", "opponent_id")
|
||||
local olvl = memory.value("battle", "opponent_level")
|
||||
local oid = Memory.value("battle", "opponent_id")
|
||||
local olvl = Memory.value("battle", "opponent_level")
|
||||
for i,p in ipairs(shouldFight) do
|
||||
if oid == pokemon.getID(p.name) and (not p.lvl or utils.match(olvl, p.lvl)) then
|
||||
if oid == Pokemon.getID(p.name) and (not p.lvl or Utils.match(olvl, p.lvl)) then
|
||||
if oneHits then
|
||||
local move = combat.bestMove()
|
||||
if move and move.maxDamage * 0.925 < memory.double("battle", "opponent_hp") then
|
||||
local move = Combat.bestMove()
|
||||
if move and move.maxDamage * 0.925 < Memory.double("battle", "opponent_hp") then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
@ -153,24 +151,24 @@ function control.shouldFight()
|
|||
end
|
||||
end
|
||||
|
||||
function control.canCatch(partySize)
|
||||
function Control.canCatch(partySize)
|
||||
if not partySize then
|
||||
partySize = memory.value("player", "party_size")
|
||||
partySize = Memory.value("player", "party_size")
|
||||
end
|
||||
local pokeballs = inventory.count("pokeball")
|
||||
local pokeballs = Inventory.count("pokeball")
|
||||
local minimumCount = 4 - partySize
|
||||
if pokeballs < minimumCount then
|
||||
strategies.reset("Not enough PokeBalls", pokeballs)
|
||||
Strategies.reset("Not enough PokeBalls", pokeballs)
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function control.shouldCatch(partySize)
|
||||
function Control.shouldCatch(partySize)
|
||||
if maxEncounters and encounters > maxEncounters then
|
||||
local extraCount = extraEncounter and pokemon.inParty(extraEncounter)
|
||||
local extraCount = extraEncounter and Pokemon.inParty(extraEncounter)
|
||||
if not extraCount or encounters > maxEncounters + 1 then
|
||||
strategies.reset("Too many encounters", encounters)
|
||||
Strategies.reset("Too many encounters", encounters)
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
@ -178,27 +176,27 @@ function control.shouldCatch(partySize)
|
|||
return false
|
||||
end
|
||||
if not partySize then
|
||||
partySize = memory.value("player", "party_size")
|
||||
partySize = Memory.value("player", "party_size")
|
||||
end
|
||||
if partySize == 4 then
|
||||
shouldCatch = nil
|
||||
return false
|
||||
end
|
||||
if not control.canCatch(partySize) then
|
||||
if not Control.canCatch(partySize) then
|
||||
return true
|
||||
end
|
||||
local oid = memory.value("battle", "opponent_id")
|
||||
local oid = Memory.value("battle", "opponent_id")
|
||||
for i,poke in ipairs(shouldCatch) do
|
||||
if oid == pokemon.getID(poke.name) and not pokemon.inParty(poke.name, poke.alt) then
|
||||
if not poke.lvl or utils.match(memory.value("battle", "opponent_level"), poke.lvl) then
|
||||
local penultimate = poke.hp and memory.double("battle", "opponent_hp") > poke.hp
|
||||
if oid == Pokemon.getID(poke.name) and not Pokemon.inParty(poke.name, poke.alt) then
|
||||
if not poke.lvl or Utils.match(Memory.value("battle", "opponent_level"), poke.lvl) then
|
||||
local penultimate = poke.hp and Memory.double("battle", "opponent_hp") > poke.hp
|
||||
if penultimate then
|
||||
penultimate = combat.nonKill()
|
||||
penultimate = Combat.nonKill()
|
||||
end
|
||||
if penultimate then
|
||||
require("action.battle").fight(penultimate.midx, true)
|
||||
else
|
||||
inventory.use("pokeball", nil, true)
|
||||
Inventory.use("pokeball", nil, true)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
@ -208,36 +206,36 @@ end
|
|||
|
||||
-- Items
|
||||
|
||||
function control.canRecover()
|
||||
return potionInBattle and (not battleYolo or not control.yolo)
|
||||
function Control.canRecover()
|
||||
return potionInBattle and (not battleYolo or not Control.yolo)
|
||||
end
|
||||
|
||||
function control.set(data)
|
||||
function Control.set(data)
|
||||
controlFunctions[data.c](data)
|
||||
end
|
||||
|
||||
function control.setYolo(enabled)
|
||||
control.yolo = enabled
|
||||
function Control.setYolo(enabled)
|
||||
Control.yolo = enabled
|
||||
end
|
||||
|
||||
function control.setPotion(enabled)
|
||||
function Control.setPotion(enabled)
|
||||
potionInBattle = enabled
|
||||
end
|
||||
|
||||
function control.encounters()
|
||||
function Control.encounters()
|
||||
return encounters
|
||||
end
|
||||
|
||||
function control.wildEncounter()
|
||||
function Control.wildEncounter()
|
||||
encounters = encounters + 1
|
||||
paint.wildEncounters(encounters)
|
||||
bridge.encounter()
|
||||
if control.moonEncounters then
|
||||
control.moonEncounters = control.moonEncounters + 1
|
||||
Paint.wildEncounters(encounters)
|
||||
Bridge.encounter()
|
||||
if Control.moonEncounters then
|
||||
Control.moonEncounters = Control.moonEncounters + 1
|
||||
end
|
||||
end
|
||||
|
||||
function control.reset()
|
||||
function Control.reset()
|
||||
canDie = false
|
||||
oneHits = false
|
||||
shouldCatch = nil
|
||||
|
@ -248,12 +246,12 @@ function control.reset()
|
|||
fightEncounter = 0
|
||||
caveFights = 0
|
||||
battleYolo = false
|
||||
control.yolo = false
|
||||
Control.yolo = false
|
||||
maxEncounters = nil
|
||||
end
|
||||
|
||||
function control.init()
|
||||
strategies = require("ai."..GAME_NAME..".strategies")
|
||||
function Control.init()
|
||||
Strategies = require("ai."..GAME_NAME..".strategies")
|
||||
end
|
||||
|
||||
return control
|
||||
return Control
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,48 +1,48 @@
|
|||
local strategies = {}
|
||||
local Strategies = {}
|
||||
|
||||
local combat = require "ai.combat"
|
||||
local control = require "ai.control"
|
||||
local Combat = require "ai.combat"
|
||||
local Control = require "ai.control"
|
||||
|
||||
local battle = require "action.battle"
|
||||
local textbox = require "action.textbox"
|
||||
local walk = require "action.walk"
|
||||
local Battle = require "action.battle"
|
||||
local Textbox = require "action.textbox"
|
||||
local Walk = require "action.walk"
|
||||
|
||||
local bridge = require "util.bridge"
|
||||
local input = require "util.input"
|
||||
local memory = require "util.memory"
|
||||
local menu = require "util.menu"
|
||||
local player = require "util.player"
|
||||
local utils = require "util.utils"
|
||||
local Bridge = require "util.bridge"
|
||||
local Input = require "util.input"
|
||||
local Memory = require "util.memory"
|
||||
local Menu = require "util.menu"
|
||||
local Player = require "util.player"
|
||||
local Utils = require "util.utils"
|
||||
|
||||
local inventory = require "storage.inventory"
|
||||
local pokemon = require "storage.pokemon"
|
||||
local Inventory = require "storage.inventory"
|
||||
local Pokemon = require "storage.pokemon"
|
||||
|
||||
local splitNumber, splitTime = 0, 0
|
||||
local resetting
|
||||
local strategyFunctions
|
||||
|
||||
local status = {tries = 0, tempDir = nil, canProgress = nil, initialized = false}
|
||||
strategies.status = status
|
||||
strategies.deepRun = false
|
||||
Strategies.status = status
|
||||
Strategies.deepRun = false
|
||||
|
||||
-- RISK/RESET
|
||||
|
||||
strategies.timeRequirements = {}
|
||||
Strategies.timeRequirements = {}
|
||||
|
||||
function strategies.getTimeRequirement(name)
|
||||
return strategies.timeRequirements[name]()
|
||||
function Strategies.getTimeRequirement(name)
|
||||
return Strategies.timeRequirements[name]()
|
||||
end
|
||||
|
||||
function strategies.hardReset(message, extra, wait)
|
||||
function Strategies.hardReset(message, extra, wait)
|
||||
resetting = true
|
||||
if strategies.seed then
|
||||
if Strategies.seed then
|
||||
if extra then
|
||||
extra = extra.." | "..strategies.seed
|
||||
extra = extra.." | "..Strategies.seed
|
||||
else
|
||||
extra = strategies.seed
|
||||
extra = Strategies.seed
|
||||
end
|
||||
end
|
||||
bridge.chat(message, extra)
|
||||
Bridge.chat(message, extra)
|
||||
if wait and INTERNAL and not STREAMING_MODE then
|
||||
strategyFunctions.wait()
|
||||
end
|
||||
|
@ -50,138 +50,138 @@ function strategies.hardReset(message, extra, wait)
|
|||
return true
|
||||
end
|
||||
|
||||
function strategies.reset(reason, extra, wait)
|
||||
local time = utils.elapsedTime()
|
||||
function Strategies.reset(reason, extra, wait)
|
||||
local time = Utils.elapsedTime()
|
||||
local resetString = "Reset"
|
||||
if time then
|
||||
resetString = resetString.." after "..time
|
||||
end
|
||||
resetString = " "..resetString.." at "..control.areaName
|
||||
resetString = " "..resetString.." at "..Control.areaName
|
||||
local separator
|
||||
if strategies.deepRun and not control.yolo then
|
||||
if Strategies.deepRun and not Control.yolo then
|
||||
separator = " BibleThump"
|
||||
else
|
||||
separator = ":"
|
||||
end
|
||||
resetString = resetString..separator.." "..reason
|
||||
return strategies.hardReset(resetString, extra, wait)
|
||||
return Strategies.hardReset(resetString, extra, wait)
|
||||
end
|
||||
|
||||
function strategies.death(extra)
|
||||
function Strategies.death(extra)
|
||||
local reason
|
||||
if strategies.criticaled then
|
||||
if Strategies.criticaled then
|
||||
reason = "Critical'd"
|
||||
elseif control.yolo then
|
||||
elseif Control.yolo then
|
||||
reason = "Yolo strats"
|
||||
else
|
||||
reason = "Died"
|
||||
end
|
||||
return strategies.reset(reason, extra)
|
||||
return Strategies.reset(reason, extra)
|
||||
end
|
||||
|
||||
function strategies.overMinute(min)
|
||||
return utils.igt() > min * 60
|
||||
function Strategies.overMinute(min)
|
||||
return Utils.igt() > min * 60
|
||||
end
|
||||
|
||||
function strategies.resetTime(timeLimit, reason, once)
|
||||
if strategies.overMinute(timeLimit) then
|
||||
function Strategies.resetTime(timeLimit, reason, once)
|
||||
if Strategies.overMinute(timeLimit) then
|
||||
reason = "Took too long to "..reason
|
||||
if RESET_FOR_TIME then
|
||||
return strategies.reset(reason)
|
||||
return Strategies.reset(reason)
|
||||
end
|
||||
if once then
|
||||
print(reason.." "..utils.elapsedTime())
|
||||
print(reason.." "..Utils.elapsedTime())
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function strategies.setYolo(name)
|
||||
function Strategies.setYolo(name)
|
||||
if not RESET_FOR_TIME then
|
||||
return false
|
||||
end
|
||||
local minimumTime = strategies.getTimeRequirement(name)
|
||||
local shouldYolo = strategies.overMinute(minimumTime)
|
||||
if control.yolo ~= shouldYolo then
|
||||
control.yolo = shouldYolo
|
||||
control.setYolo(shouldYolo)
|
||||
local minimumTime = Strategies.getTimeRequirement(name)
|
||||
local shouldYolo = Strategies.overMinute(minimumTime)
|
||||
if Control.yolo ~= shouldYolo then
|
||||
Control.yolo = shouldYolo
|
||||
Control.setYolo(shouldYolo)
|
||||
local prefix
|
||||
if control.yolo then
|
||||
if Control.yolo then
|
||||
prefix = "en"
|
||||
else
|
||||
prefix = "dis"
|
||||
end
|
||||
print("YOLO "..prefix.."abled at "..control.areaName)
|
||||
print("YOLO "..prefix.."abled at "..Control.areaName)
|
||||
end
|
||||
return control.yolo
|
||||
return Control.yolo
|
||||
end
|
||||
|
||||
-- HELPERS
|
||||
|
||||
function strategies.initialize()
|
||||
function Strategies.initialize()
|
||||
if not initialized then
|
||||
initialized = true
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function strategies.canHealFor(damage)
|
||||
local curr_hp = pokemon.index(0, "hp")
|
||||
local max_hp = pokemon.index(0, "max_hp")
|
||||
function Strategies.canHealFor(damage)
|
||||
local curr_hp = Pokemon.index(0, "hp")
|
||||
local max_hp = Pokemon.index(0, "max_hp")
|
||||
if max_hp - curr_hp > 3 then
|
||||
local healChecks = {"full_restore", "super_potion", "potion"}
|
||||
for idx,potion in ipairs(healChecks) do
|
||||
if inventory.contains(potion) and utils.canPotionWith(potion, damage, curr_hp, max_hp) then
|
||||
if Inventory.contains(potion) and Utils.canPotionWith(potion, damage, curr_hp, max_hp) then
|
||||
return potion
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function strategies.hasHealthFor(opponent, extra)
|
||||
function Strategies.hasHealthFor(opponent, extra)
|
||||
if not extra then
|
||||
extra = 0
|
||||
end
|
||||
return pokemon.index(0, "hp") + extra > combat.healthFor(opponent)
|
||||
return Pokemon.index(0, "hp") + extra > Combat.healthFor(opponent)
|
||||
end
|
||||
|
||||
function strategies.damaged(factor)
|
||||
function Strategies.damaged(factor)
|
||||
if not factor then
|
||||
factor = 1
|
||||
end
|
||||
return pokemon.index(0, "hp") * factor < pokemon.index(0, "max_hp")
|
||||
return Pokemon.index(0, "hp") * factor < Pokemon.index(0, "max_hp")
|
||||
end
|
||||
|
||||
function strategies.opponentDamaged(factor)
|
||||
function Strategies.opponentDamaged(factor)
|
||||
if not factor then
|
||||
factor = 1
|
||||
end
|
||||
return memory.double("battle", "opponent_hp") * factor < memory.double("battle", "opponent_max_hp")
|
||||
return Memory.double("battle", "opponent_hp") * factor < Memory.double("battle", "opponent_max_hp")
|
||||
end
|
||||
|
||||
function strategies.redHP()
|
||||
return math.ceil(pokemon.index(0, "max_hp") * 0.2)
|
||||
function Strategies.redHP()
|
||||
return math.ceil(Pokemon.index(0, "max_hp") * 0.2)
|
||||
end
|
||||
|
||||
function strategies.buffTo(buff, defLevel)
|
||||
if battle.isActive() then
|
||||
function Strategies.buffTo(buff, defLevel)
|
||||
if Battle.isActive() then
|
||||
canProgress = true
|
||||
local forced
|
||||
if defLevel and memory.double("battle", "opponent_defense") > defLevel then
|
||||
if defLevel and Memory.double("battle", "opponent_defense") > defLevel then
|
||||
forced = buff
|
||||
end
|
||||
battle.automate(forced, true)
|
||||
Battle.automate(forced, true)
|
||||
elseif canProgress then
|
||||
return true
|
||||
else
|
||||
battle.automate()
|
||||
Battle.automate()
|
||||
end
|
||||
end
|
||||
|
||||
function strategies.dodgeUp(npc, sx, sy, dodge, offset)
|
||||
if not battle.handleWild() then
|
||||
function Strategies.dodgeUp(npc, sx, sy, dodge, offset)
|
||||
if not Battle.handleWild() then
|
||||
return false
|
||||
end
|
||||
local px, py = player.position()
|
||||
local px, py = Player.position()
|
||||
if py < sy - 1 then
|
||||
return true
|
||||
end
|
||||
|
@ -189,7 +189,7 @@ function strategies.dodgeUp(npc, sx, sy, dodge, offset)
|
|||
if py < sy then
|
||||
wy = py - 1
|
||||
elseif px == sx or px == dodge then
|
||||
if px - memory.raw(npc) == offset then
|
||||
if px - Memory.raw(npc) == offset then
|
||||
if px == sx then
|
||||
wx = dodge
|
||||
else
|
||||
|
@ -199,7 +199,7 @@ function strategies.dodgeUp(npc, sx, sy, dodge, offset)
|
|||
wy = py - 1
|
||||
end
|
||||
end
|
||||
walk.step(wx, wy)
|
||||
Walk.step(wx, wy)
|
||||
end
|
||||
|
||||
local function dodgeH(options)
|
||||
|
@ -207,7 +207,7 @@ local function dodgeH(options)
|
|||
if options.left then
|
||||
left = -1
|
||||
end
|
||||
local px, py = player.position()
|
||||
local px, py = Player.position()
|
||||
if px * left > options.sx * left + (options.dist or 1) * left then
|
||||
return true
|
||||
end
|
||||
|
@ -215,7 +215,7 @@ local function dodgeH(options)
|
|||
if px * left > options.sx * left then
|
||||
wx = px + 1 * left
|
||||
elseif py == options.sy or py == options.dodge then
|
||||
if py - memory.raw(options.npc) == options.offset then
|
||||
if py - Memory.raw(options.npc) == options.offset then
|
||||
if py == options.sy then
|
||||
wy = options.dodge
|
||||
else
|
||||
|
@ -225,73 +225,73 @@ local function dodgeH(options)
|
|||
wx = px + 1 * left
|
||||
end
|
||||
end
|
||||
walk.step(wx, wy)
|
||||
Walk.step(wx, wy)
|
||||
end
|
||||
|
||||
function strategies.completedMenuFor(data)
|
||||
local count = inventory.count(data.item)
|
||||
function Strategies.completedMenuFor(data)
|
||||
local count = Inventory.count(data.item)
|
||||
if count == 0 or count + (data.amount or 1) <= status.tries then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function strategies.closeMenuFor(data)
|
||||
if (not tempDir and not data.close) or data.chain or menu.close() then
|
||||
function Strategies.closeMenuFor(data)
|
||||
if (not tempDir and not data.close) or data.chain or Menu.close() then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function strategies.useItem(data)
|
||||
local main = memory.value("menu", "main")
|
||||
function Strategies.useItem(data)
|
||||
local main = Memory.value("menu", "main")
|
||||
if status.tries == 0 then
|
||||
status.tries = inventory.count(data.item)
|
||||
status.tries = Inventory.count(data.item)
|
||||
if status.tries == 0 then
|
||||
if strategies.closeMenuFor(data) then
|
||||
if Strategies.closeMenuFor(data) then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
if strategies.completedMenuFor(data) then
|
||||
if strategies.closeMenuFor(data) then
|
||||
if Strategies.completedMenuFor(data) then
|
||||
if Strategies.closeMenuFor(data) then
|
||||
return true
|
||||
end
|
||||
else
|
||||
if inventory.use(data.item, data.poke) then
|
||||
if Inventory.use(data.item, data.poke) then
|
||||
tempDir = true
|
||||
else
|
||||
menu.pause()
|
||||
Menu.pause()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function completedSkillFor(data)
|
||||
if data.map then
|
||||
if data.map ~= memory.value("game", "map") then
|
||||
if data.map ~= Memory.value("game", "map") then
|
||||
return true
|
||||
end
|
||||
elseif data.x or data.y then
|
||||
local px, py = player.position()
|
||||
local px, py = Player.position()
|
||||
if data.x == px or data.y == py then
|
||||
return true
|
||||
end
|
||||
elseif data.done then
|
||||
if memory.raw(data.done) > (data.val or 0) then
|
||||
if Memory.raw(data.done) > (data.val or 0) then
|
||||
return true
|
||||
end
|
||||
elseif status.tries > 0 and not menu.isOpen() then
|
||||
elseif status.tries > 0 and not Menu.isOpen() then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function strategies.isPrepared(...)
|
||||
function Strategies.isPrepared(...)
|
||||
if status.tries == 0 then
|
||||
status.tries = {}
|
||||
end
|
||||
for i,name in ipairs(arg) do
|
||||
local currentCount = inventory.count(name)
|
||||
local currentCount = Inventory.count(name)
|
||||
if currentCount > 0 then
|
||||
local previousCount = status.tries[name]
|
||||
if previousCount == nil or currentCount == previousCount then
|
||||
|
@ -302,13 +302,13 @@ function strategies.isPrepared(...)
|
|||
return true
|
||||
end
|
||||
|
||||
function strategies.prepare(...)
|
||||
function Strategies.prepare(...)
|
||||
if status.tries == 0 then
|
||||
status.tries = {}
|
||||
end
|
||||
local item
|
||||
for idx,name in ipairs(arg) do
|
||||
local currentCount = inventory.count(name)
|
||||
local currentCount = Inventory.count(name)
|
||||
local needsItem = currentCount > 0
|
||||
local previousCount = status.tries[name]
|
||||
if previousCount == nil then
|
||||
|
@ -324,108 +324,108 @@ function strategies.prepare(...)
|
|||
if not item then
|
||||
return true
|
||||
end
|
||||
if battle.isActive() then
|
||||
inventory.use(item, nil, true)
|
||||
if Battle.isActive() then
|
||||
Inventory.use(item, nil, true)
|
||||
else
|
||||
input.cancel()
|
||||
Input.cancel()
|
||||
end
|
||||
end
|
||||
|
||||
-- GENERALIZED STRATEGIES
|
||||
|
||||
strategies.functions = {
|
||||
Strategies.functions = {
|
||||
|
||||
startFrames = function()
|
||||
strategies.frames = 0
|
||||
Strategies.frames = 0
|
||||
return true
|
||||
end,
|
||||
|
||||
reportFrames = function()
|
||||
print("FR "..strategies.frames)
|
||||
local repels = memory.value("player", "repel")
|
||||
print("FR "..Strategies.frames)
|
||||
local repels = Memory.value("player", "repel")
|
||||
if repels > 0 then
|
||||
print("S "..repels)
|
||||
end
|
||||
strategies.frames = nil
|
||||
Strategies.frames = nil
|
||||
return true
|
||||
end,
|
||||
|
||||
split = function(data)
|
||||
bridge.split(data and data.finished)
|
||||
Bridge.split(data and data.finished)
|
||||
if not INTERNAL then
|
||||
splitNumber = splitNumber + 1
|
||||
|
||||
local timeDiff
|
||||
splitTime, timeDiff = utils.timeSince(splitTime)
|
||||
splitTime, timeDiff = Utils.timeSince(splitTime)
|
||||
if timeDiff then
|
||||
print(splitNumber..". "..control.areaName..": "..utils.elapsedTime().." ("..timeDiff..")")
|
||||
print(splitNumber..". "..Control.areaName..": "..Utils.elapsedTime().." ("..timeDiff..")")
|
||||
end
|
||||
end
|
||||
return true
|
||||
end,
|
||||
|
||||
interact = function(data)
|
||||
if battle.handleWild() then
|
||||
if battle.isActive() then
|
||||
if Battle.handleWild() then
|
||||
if Battle.isActive() then
|
||||
return true
|
||||
end
|
||||
if textbox.isActive() then
|
||||
if Textbox.isActive() then
|
||||
if status.tries > 0 then
|
||||
return true
|
||||
end
|
||||
status.tries = status.tries - 1
|
||||
input.cancel()
|
||||
elseif player.interact(data.dir) then
|
||||
Input.cancel()
|
||||
elseif Player.interact(data.dir) then
|
||||
status.tries = status.tries + 1
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
confirm = function(data)
|
||||
if battle.handleWild() then
|
||||
if textbox.isActive() then
|
||||
if Battle.handleWild() then
|
||||
if Textbox.isActive() then
|
||||
status.tries = status.tries + 1
|
||||
input.cancel(data.type or "A")
|
||||
Input.cancel(data.type or "A")
|
||||
else
|
||||
if status.tries > 0 then
|
||||
return true
|
||||
end
|
||||
player.interact(data.dir)
|
||||
Player.interact(data.dir)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
item = function(data)
|
||||
if battle.handleWild() then
|
||||
if data.full and not inventory.isFull() then
|
||||
if strategies.closeMenuFor(data) then
|
||||
if Battle.handleWild() then
|
||||
if data.full and not Inventory.isFull() then
|
||||
if Strategies.closeMenuFor(data) then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
return strategies.useItem(data)
|
||||
return Strategies.useItem(data)
|
||||
end
|
||||
end,
|
||||
|
||||
potion = function(data)
|
||||
local curr_hp = pokemon.index(0, "hp")
|
||||
local curr_hp = Pokemon.index(0, "hp")
|
||||
if curr_hp == 0 then
|
||||
return false
|
||||
end
|
||||
local toHP
|
||||
if control.yolo and data.yolo ~= nil then
|
||||
if Control.yolo and data.yolo ~= nil then
|
||||
toHP = data.yolo
|
||||
else
|
||||
toHP = data.hp
|
||||
end
|
||||
if type(toHP) == "string" then
|
||||
toHP = combat.healthFor(toHP)
|
||||
toHP = Combat.healthFor(toHP)
|
||||
end
|
||||
local toHeal = toHP - curr_hp
|
||||
if toHeal > 0 then
|
||||
local toPotion
|
||||
if data.forced then
|
||||
toPotion = inventory.contains(data.forced)
|
||||
toPotion = Inventory.contains(data.forced)
|
||||
else
|
||||
local p_first, p_second, p_third
|
||||
if toHeal > 50 then
|
||||
|
@ -445,24 +445,24 @@ strategies.functions = {
|
|||
p_third = "full_restore"
|
||||
end
|
||||
end
|
||||
toPotion = inventory.contains(p_first, p_second, p_third)
|
||||
toPotion = Inventory.contains(p_first, p_second, p_third)
|
||||
end
|
||||
if toPotion then
|
||||
if menu.pause() then
|
||||
inventory.use(toPotion)
|
||||
if Menu.pause() then
|
||||
Inventory.use(toPotion)
|
||||
tempDir = true
|
||||
end
|
||||
return false
|
||||
end
|
||||
--TODO report wanted potion
|
||||
end
|
||||
if strategies.closeMenuFor(data) then
|
||||
if Strategies.closeMenuFor(data) then
|
||||
return true
|
||||
end
|
||||
end,
|
||||
|
||||
teach = function(data)
|
||||
if data.full and not inventory.isFull() then
|
||||
if data.full and not Inventory.isFull() then
|
||||
return true
|
||||
end
|
||||
local itemName
|
||||
|
@ -471,8 +471,8 @@ strategies.functions = {
|
|||
else
|
||||
itemName = data.move
|
||||
end
|
||||
if pokemon.hasMove(data.move) then
|
||||
local main = memory.value("menu", "main")
|
||||
if Pokemon.hasMove(data.move) then
|
||||
local main = Memory.value("menu", "main")
|
||||
if main == 128 then
|
||||
if data.chain then
|
||||
return true
|
||||
|
@ -480,44 +480,44 @@ strategies.functions = {
|
|||
elseif main < 3 then
|
||||
return true
|
||||
end
|
||||
input.press("B")
|
||||
Input.press("B")
|
||||
else
|
||||
if strategies.initialize() then
|
||||
if not inventory.contains(itemName) then
|
||||
return strategies.reset("Unable to teach move "..itemName.." to "..data.poke, nil, true)
|
||||
if Strategies.initialize() then
|
||||
if not Inventory.contains(itemName) then
|
||||
return Strategies.reset("Unable to teach move "..itemName.." to "..data.poke, nil, true)
|
||||
end
|
||||
end
|
||||
local replacement
|
||||
if data.replace then
|
||||
replacement = pokemon.moveIndex(data.replace, data.poke) - 1
|
||||
replacement = Pokemon.moveIndex(data.replace, data.poke) - 1
|
||||
else
|
||||
replacement = 0
|
||||
end
|
||||
if inventory.teach(itemName, data.poke, replacement, data.alt) then
|
||||
if Inventory.teach(itemName, data.poke, replacement, data.alt) then
|
||||
tempDir = true
|
||||
else
|
||||
menu.pause()
|
||||
Menu.pause()
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
skill = function(data)
|
||||
if completedSkillFor(data) then
|
||||
if not textbox.isActive() then
|
||||
if not Textbox.isActive() then
|
||||
return true
|
||||
end
|
||||
input.press("B")
|
||||
elseif not data.dir or player.face(data.dir) then
|
||||
if pokemon.use(data.move) then
|
||||
Input.press("B")
|
||||
elseif not data.dir or Player.face(data.dir) then
|
||||
if Pokemon.use(data.move) then
|
||||
status.tries = status.tries + 1
|
||||
else
|
||||
menu.pause()
|
||||
Menu.pause()
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
fly = function(data)
|
||||
if memory.value("game", "map") == data.map then
|
||||
if Memory.value("game", "map") == data.map then
|
||||
return true
|
||||
end
|
||||
local cities = {
|
||||
|
@ -529,9 +529,9 @@ strategies.functions = {
|
|||
cinnabar = {70, "Down"},
|
||||
}
|
||||
|
||||
local main = memory.value("menu", "main")
|
||||
local main = Memory.value("menu", "main")
|
||||
if main == 228 then
|
||||
local currentFly = memory.raw(0x1FEF)
|
||||
local currentFly = Memory.raw(0x1FEF)
|
||||
local destination = cities[data.dest]
|
||||
local press
|
||||
if destination[1] - currentFly == 0 then
|
||||
|
@ -539,25 +539,25 @@ strategies.functions = {
|
|||
else
|
||||
press = destination[2]
|
||||
end
|
||||
input.press(press)
|
||||
elseif not pokemon.use("fly") then
|
||||
menu.pause()
|
||||
Input.press(press)
|
||||
elseif not Pokemon.use("fly") then
|
||||
Menu.pause()
|
||||
end
|
||||
end,
|
||||
|
||||
bicycle = function()
|
||||
if memory.raw(0x1700) == 1 then
|
||||
if textbox.handle() then
|
||||
if Memory.raw(0x1700) == 1 then
|
||||
if Textbox.handle() then
|
||||
return true
|
||||
end
|
||||
else
|
||||
return strategies.useItem({item="bicycle"})
|
||||
return Strategies.useItem({item="bicycle"})
|
||||
end
|
||||
end,
|
||||
|
||||
wait = function()
|
||||
print("Please save state")
|
||||
input.press("Start", 9001)
|
||||
Input.press("Start", 9001)
|
||||
end,
|
||||
|
||||
emuSpeed = function(data)
|
||||
|
@ -566,66 +566,66 @@ strategies.functions = {
|
|||
end,
|
||||
|
||||
waitToTalk = function()
|
||||
if battle.isActive() then
|
||||
if Battle.isActive() then
|
||||
canProgress = false
|
||||
battle.automate()
|
||||
elseif textbox.isActive() then
|
||||
Battle.automate()
|
||||
elseif Textbox.isActive() then
|
||||
canProgress = true
|
||||
input.cancel()
|
||||
Input.cancel()
|
||||
elseif canProgress then
|
||||
return true
|
||||
end
|
||||
end,
|
||||
|
||||
waitToPause = function()
|
||||
local main = memory.value("menu", "main")
|
||||
local main = Memory.value("menu", "main")
|
||||
if main == 128 then
|
||||
if canProgress then
|
||||
return true
|
||||
end
|
||||
elseif battle.isActive() then
|
||||
elseif Battle.isActive() then
|
||||
canProgress = false
|
||||
battle.automate()
|
||||
Battle.automate()
|
||||
elseif main == 123 then
|
||||
canProgress = true
|
||||
input.press("B")
|
||||
elseif textbox.handle() then
|
||||
input.press("Start", 2)
|
||||
Input.press("B")
|
||||
elseif Textbox.handle() then
|
||||
Input.press("Start", 2)
|
||||
end
|
||||
end,
|
||||
|
||||
waitToFight = function(data)
|
||||
if battle.isActive() then
|
||||
if Battle.isActive() then
|
||||
canProgress = true
|
||||
battle.automate()
|
||||
Battle.automate()
|
||||
elseif canProgress then
|
||||
return true
|
||||
elseif textbox.handle() then
|
||||
elseif Textbox.handle() then
|
||||
if data.dir then
|
||||
player.interact(data.dir)
|
||||
Player.interact(data.dir)
|
||||
else
|
||||
input.cancel()
|
||||
Input.cancel()
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
allowDeath = function(data)
|
||||
control.canDie(data.on)
|
||||
Control.canDie(data.on)
|
||||
return true
|
||||
end,
|
||||
|
||||
-- ROUTE
|
||||
|
||||
dodgePalletBoy = function()
|
||||
return strategies.dodgeUp(0x0223, 14, 14, 15, 7)
|
||||
return Strategies.dodgeUp(0x0223, 14, 14, 15, 7)
|
||||
end,
|
||||
|
||||
helix = function()
|
||||
if battle.handleWild() then
|
||||
if inventory.contains("helix_fossil") then
|
||||
if Battle.handleWild() then
|
||||
if Inventory.contains("helix_fossil") then
|
||||
return true
|
||||
end
|
||||
player.interact("Up")
|
||||
Player.interact("Up")
|
||||
end
|
||||
end,
|
||||
|
||||
|
@ -651,13 +651,13 @@ strategies.functions = {
|
|||
end,
|
||||
|
||||
playPokeflute = function()
|
||||
if battle.isActive() then
|
||||
if Battle.isActive() then
|
||||
return true
|
||||
end
|
||||
if memory.value("battle", "menu") == 95 then
|
||||
input.press("A")
|
||||
elseif menu.pause() then
|
||||
inventory.use("pokeflute")
|
||||
if Memory.value("battle", "menu") == 95 then
|
||||
Input.press("A")
|
||||
elseif Menu.pause() then
|
||||
Inventory.use("pokeflute")
|
||||
end
|
||||
end,
|
||||
|
||||
|
@ -668,19 +668,19 @@ strategies.functions = {
|
|||
else
|
||||
pos = data.x
|
||||
end
|
||||
local newP = memory.raw(pos)
|
||||
local newP = Memory.raw(pos)
|
||||
if status.tries == 0 then
|
||||
status.tries = {start=newP}
|
||||
elseif status.tries.start ~= newP then
|
||||
return true
|
||||
end
|
||||
input.press(data.dir, 0)
|
||||
Input.press(data.dir, 0)
|
||||
end,
|
||||
}
|
||||
|
||||
strategyFunctions = strategies.functions
|
||||
strategyFunctions = Strategies.functions
|
||||
|
||||
function strategies.execute(data)
|
||||
function Strategies.execute(data)
|
||||
if strategyFunctions[data.s](data) then
|
||||
status = {tries=0}
|
||||
if resetting then
|
||||
|
@ -692,21 +692,21 @@ function strategies.execute(data)
|
|||
return false
|
||||
end
|
||||
|
||||
function strategies.init(midGame)
|
||||
function Strategies.init(midGame)
|
||||
if not STREAMING_MODE then
|
||||
splitTime = utils.timeSince(0)
|
||||
splitTime = Utils.timeSince(0)
|
||||
end
|
||||
if midGame then
|
||||
combat.factorPP(true)
|
||||
Combat.factorPP(true)
|
||||
end
|
||||
strategies.initGame(midGame)
|
||||
Strategies.initGame(midGame)
|
||||
end
|
||||
|
||||
function strategies.softReset()
|
||||
function Strategies.softReset()
|
||||
status = {}
|
||||
splitNumber, splitTime = 0, 0
|
||||
resetting = nil
|
||||
strategies.resetGame()
|
||||
Strategies.resetGame()
|
||||
end
|
||||
|
||||
return strategies
|
||||
return Strategies
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
local strategies = require "ai.strategies"
|
||||
local Strategies = require "ai.strategies"
|
||||
|
||||
local combat = require "ai.combat"
|
||||
local control = require "ai.control"
|
||||
|
@ -18,24 +18,24 @@ local utils = require "util.utils"
|
|||
local inventory = require "storage.inventory"
|
||||
local pokemon = require "storage.pokemon"
|
||||
|
||||
local status = strategies.status
|
||||
local status = Strategies.status
|
||||
|
||||
strategies.timeRequirements = {}
|
||||
Strategies.timeRequirements = {}
|
||||
|
||||
-- STRATEGIES
|
||||
|
||||
local strategyFunctions = strategies.functions
|
||||
local strategyFunctions = Strategies.functions
|
||||
|
||||
-- PROCESS
|
||||
|
||||
function strategies.initGame(midGame)
|
||||
function Strategies.initGame(midGame)
|
||||
if not STREAMING_MODE then
|
||||
-- strategies.setYolo("")
|
||||
-- Strategies.setYolo("")
|
||||
end
|
||||
end
|
||||
|
||||
function strategies.resetGame()
|
||||
status = strategies.status
|
||||
function Strategies.resetGame()
|
||||
status = Strategies.status
|
||||
end
|
||||
|
||||
return strategies
|
||||
return Strategies
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
local movelist = {}
|
||||
local Movelist = {}
|
||||
-- http://bulbapedia.bulbagarden.net/wiki/List_of_moves#List_of_moves
|
||||
|
||||
local moves = {
|
||||
|
@ -1513,8 +1513,8 @@ local moves = {
|
|||
},
|
||||
}
|
||||
|
||||
function movelist.get(id)
|
||||
function Movelist.get(id)
|
||||
return moves[id]
|
||||
end
|
||||
|
||||
return movelist
|
||||
return Movelist
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
local opponents = {
|
||||
local Opponents = {
|
||||
|
||||
RivalGyarados = {
|
||||
type1 = "water",
|
||||
|
@ -222,4 +222,4 @@ local opponents = {
|
|||
|
||||
}
|
||||
|
||||
return opponents
|
||||
return Opponents
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
local paths = {
|
||||
local Paths = {
|
||||
-- Red's room
|
||||
{38, {3,6}, {5,6}, {5,1}, {7,1}},
|
||||
-- Red's house
|
||||
|
@ -447,4 +447,4 @@ local paths = {
|
|||
{118, {4,2}, {s="champion"}}
|
||||
}
|
||||
|
||||
return paths
|
||||
return Paths
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
local paths = {
|
||||
local Paths = {
|
||||
-- Red's room
|
||||
{38, {3,6}, {5,6}, {5,1}, {7,1}},
|
||||
-- Red's house
|
||||
|
@ -34,4 +34,4 @@ local paths = {
|
|||
|
||||
}
|
||||
|
||||
return paths
|
||||
return Paths
|
||||
|
|
150
main.lua
150
main.lua
|
@ -1,4 +1,4 @@
|
|||
-- SETTINGS
|
||||
-- OPTIONS
|
||||
|
||||
RESET_FOR_TIME = true -- Set to false if you just want to see the bot finish a run
|
||||
|
||||
|
@ -14,23 +14,23 @@ INTERNAL = false
|
|||
|
||||
local START_WAIT = 99
|
||||
|
||||
local battle = require "action.battle"
|
||||
local textbox = require "action.textbox"
|
||||
local walk = require "action.walk"
|
||||
local Battle = require "action.battle"
|
||||
local Textbox = require "action.textbox"
|
||||
local Walk = require "action.walk"
|
||||
|
||||
local combat = require "ai.combat"
|
||||
local control = require "ai.control"
|
||||
local strategies = require("ai."..GAME_NAME..".strategies")
|
||||
local Combat = require "ai.combat"
|
||||
local Control = require "ai.control"
|
||||
local Strategies = require("ai."..GAME_NAME..".strategies")
|
||||
|
||||
local bridge = require "util.bridge"
|
||||
local input = require "util.input"
|
||||
local memory = require "util.memory"
|
||||
local menu = require "util.menu"
|
||||
local paint = require "util.paint"
|
||||
local utils = require "util.utils"
|
||||
local settings = require "util.settings"
|
||||
local Bridge = require "util.bridge"
|
||||
local Input = require "util.input"
|
||||
local Memory = require "util.memory"
|
||||
local Menu = require "util.menu"
|
||||
local Paint = require "util.paint"
|
||||
local Utils = require "util.utils"
|
||||
local Settings = require "util.settings"
|
||||
|
||||
local pokemon = require "storage.pokemon"
|
||||
local Pokemon = require "storage.pokemon"
|
||||
|
||||
local hasAlreadyStartedPlaying = false
|
||||
local inBattle, oldSecs
|
||||
|
@ -42,65 +42,65 @@ local criticaled = false
|
|||
local function startNewAdventure()
|
||||
local startMenu, withBattleStyle
|
||||
if YELLOW then
|
||||
startMenu = memory.raw(0x0F95) == 0
|
||||
startMenu = Memory.raw(0x0F95) == 0
|
||||
withBattleStyle = "battle_style"
|
||||
else
|
||||
startMenu = memory.value("player", "name") ~= 0
|
||||
startMenu = Memory.value("player", "name") ~= 0
|
||||
end
|
||||
if startMenu and menu.getCol() ~= 0 then
|
||||
if settings.set("text_speed", "battle_animation", withBattleStyle) then
|
||||
menu.select(0)
|
||||
if startMenu and Menu.getCol() ~= 0 then
|
||||
if Settings.set("text_speed", "battle_animation", withBattleStyle) then
|
||||
Menu.select(0)
|
||||
end
|
||||
elseif math.random(0, START_WAIT) == 0 then
|
||||
input.press("Start")
|
||||
Input.press("Start")
|
||||
end
|
||||
end
|
||||
|
||||
local function choosePlayerNames()
|
||||
local name
|
||||
if memory.value("player", "name2") == 80 then
|
||||
if Memory.value("player", "name2") == 80 then
|
||||
name = "E"
|
||||
else
|
||||
name = "B"
|
||||
end
|
||||
textbox.name(name, true)
|
||||
Textbox.name(name, true)
|
||||
end
|
||||
|
||||
local function pollForResponse()
|
||||
local response = bridge.process()
|
||||
local response = Bridge.process()
|
||||
if response then
|
||||
bridge.polling = false
|
||||
textbox.setName(tonumber(response))
|
||||
Bridge.polling = false
|
||||
Textbox.setName(tonumber(response))
|
||||
end
|
||||
end
|
||||
|
||||
local function resetAll()
|
||||
strategies.softReset()
|
||||
combat.reset()
|
||||
control.reset()
|
||||
walk.reset()
|
||||
paint.reset()
|
||||
bridge.reset()
|
||||
Strategies.softReset()
|
||||
Combat.reset()
|
||||
Control.reset()
|
||||
Walk.reset()
|
||||
Paint.reset()
|
||||
Bridge.reset()
|
||||
oldSecs = 0
|
||||
running = false
|
||||
previousPartySize = 0
|
||||
-- client.speedmode = 200
|
||||
|
||||
if CUSTOM_SEED then
|
||||
strategies.seed = CUSTOM_SEED
|
||||
print("RUNNING WITH A FIXED SEED ("..strategies.seed.."), every run will play out identically!")
|
||||
Strategies.seed = CUSTOM_SEED
|
||||
print("RUNNING WITH A FIXED SEED ("..Strategies.seed.."), every run will play out identically!")
|
||||
else
|
||||
strategies.seed = os.time()
|
||||
Strategies.seed = os.time()
|
||||
end
|
||||
math.randomseed(strategies.seed)
|
||||
math.randomseed(Strategies.seed)
|
||||
end
|
||||
|
||||
-- EXECUTE
|
||||
|
||||
control.init()
|
||||
Control.init()
|
||||
|
||||
print("Welcome to PokeBot "..GAME_NAME.." version "..VERSION)
|
||||
STREAMING_MODE = not walk.init()
|
||||
STREAMING_MODE = not Walk.init()
|
||||
if INTERNAL and STREAMING_MODE then
|
||||
RESET_FOR_TIME = true
|
||||
end
|
||||
|
@ -108,18 +108,18 @@ end
|
|||
if CUSTOM_SEED then
|
||||
client.reboot_core()
|
||||
else
|
||||
hasAlreadyStartedPlaying = utils.ingame()
|
||||
hasAlreadyStartedPlaying = Utils.ingame()
|
||||
end
|
||||
|
||||
strategies.init(hasAlreadyStartedPlaying)
|
||||
Strategies.init(hasAlreadyStartedPlaying)
|
||||
if RESET_FOR_TIME and hasAlreadyStartedPlaying then
|
||||
RESET_FOR_TIME = false
|
||||
print("Disabling time-limit resets as the game is already running. Please reset the emulator and restart the script if you'd like to go for a fast time.")
|
||||
end
|
||||
if STREAMING_MODE then
|
||||
bridge.init()
|
||||
Bridge.init()
|
||||
else
|
||||
input.setDebug(true)
|
||||
Input.setDebug(true)
|
||||
end
|
||||
|
||||
-- Main loop
|
||||
|
@ -127,23 +127,23 @@ end
|
|||
local previousMap
|
||||
|
||||
while true do
|
||||
local currentMap = memory.value("game", "map")
|
||||
local currentMap = Memory.value("game", "map")
|
||||
if currentMap ~= previousMap then
|
||||
input.clear()
|
||||
Input.clear()
|
||||
previousMap = currentMap
|
||||
end
|
||||
if strategies.frames then
|
||||
if memory.value("game", "battle") == 0 then
|
||||
strategies.frames = strategies.frames + 1
|
||||
if Strategies.frames then
|
||||
if Memory.value("game", "battle") == 0 then
|
||||
Strategies.frames = Strategies.frames + 1
|
||||
end
|
||||
gui.text(0, 80, strategies.frames)
|
||||
gui.text(0, 80, Strategies.frames)
|
||||
end
|
||||
if bridge.polling then
|
||||
if Bridge.polling then
|
||||
pollForResponse()
|
||||
end
|
||||
|
||||
if not input.update() then
|
||||
if not utils.ingame() then
|
||||
if not Input.update() then
|
||||
if not Utils.ingame() then
|
||||
if currentMap == 0 then
|
||||
if running then
|
||||
if not hasAlreadyStartedPlaying then
|
||||
|
@ -157,69 +157,69 @@ while true do
|
|||
end
|
||||
else
|
||||
if not running then
|
||||
bridge.liveSplit()
|
||||
Bridge.liveSplit()
|
||||
running = true
|
||||
end
|
||||
choosePlayerNames()
|
||||
end
|
||||
else
|
||||
local battleState = memory.value("game", "battle")
|
||||
local battleState = Memory.value("game", "battle")
|
||||
if battleState > 0 then
|
||||
if battleState == 1 then
|
||||
if not inBattle then
|
||||
control.wildEncounter()
|
||||
Control.wildEncounter()
|
||||
inBattle = true
|
||||
end
|
||||
end
|
||||
local isCritical
|
||||
local battleMenu = memory.value("battle", "menu")
|
||||
local battleMenu = Memory.value("battle", "menu")
|
||||
if battleMenu == 94 then
|
||||
isCritical = false
|
||||
elseif memory.double("battle", "our_hp") == 0 then
|
||||
if memory.value("battle", "critical") == 1 then
|
||||
elseif Memory.double("battle", "our_hp") == 0 then
|
||||
if Memory.value("battle", "critical") == 1 then
|
||||
isCritical = true
|
||||
end
|
||||
end
|
||||
if isCritical ~= nil and isCritical ~= criticaled then
|
||||
criticaled = isCritical
|
||||
strategies.criticaled = criticaled
|
||||
Strategies.criticaled = criticaled
|
||||
end
|
||||
else
|
||||
inBattle = false
|
||||
end
|
||||
local currentHP = pokemon.index(0, "hp")
|
||||
local currentHP = Pokemon.index(0, "hp")
|
||||
-- if currentHP ~= lastHP then
|
||||
-- bridge.hp(currentHP, pokemon.index(0, "max_hp"))
|
||||
-- Bridge.hp(currentHP, Pokemon.index(0, "max_hp"))
|
||||
-- lastHP = currentHP
|
||||
-- end
|
||||
if currentHP == 0 and not control.canDie() and pokemon.index(0) > 0 then
|
||||
strategies.death(currentMap)
|
||||
elseif walk.strategy then
|
||||
if strategies.execute(walk.strategy) then
|
||||
walk.traverse(currentMap)
|
||||
if currentHP == 0 and not Control.canDie() and Pokemon.index(0) > 0 then
|
||||
Strategies.death(currentMap)
|
||||
elseif Walk.strategy then
|
||||
if Strategies.execute(Walk.strategy) then
|
||||
Walk.traverse(currentMap)
|
||||
end
|
||||
elseif battleState > 0 then
|
||||
if not control.shouldCatch(partySize) then
|
||||
battle.automate()
|
||||
if not Control.shouldCatch(partySize) then
|
||||
Battle.automate()
|
||||
end
|
||||
elseif textbox.handle() then
|
||||
walk.traverse(currentMap)
|
||||
elseif Textbox.handle() then
|
||||
Walk.traverse(currentMap)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if STREAMING_MODE then
|
||||
local newSecs = memory.raw(0x1A44)
|
||||
if newSecs ~= oldSecs and (newSecs > 0 or memory.raw(0x1A45) > 0) then
|
||||
bridge.time(utils.elapsedTime())
|
||||
local newSecs = Memory.raw(0x1A44)
|
||||
if newSecs ~= oldSecs and (newSecs > 0 or Memory.raw(0x1A45) > 0) then
|
||||
Bridge.time(Utils.elapsedTime())
|
||||
oldSecs = newSecs
|
||||
end
|
||||
elseif PAINT_ON then
|
||||
paint.draw(currentMap)
|
||||
Paint.draw(currentMap)
|
||||
end
|
||||
|
||||
input.advance()
|
||||
Input.advance()
|
||||
emu.frameadvance()
|
||||
end
|
||||
|
||||
bridge.close()
|
||||
Bridge.close()
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
local inventory = {}
|
||||
local Inventory = {}
|
||||
|
||||
local pokemon = require "storage.pokemon"
|
||||
local Input = require "util.input"
|
||||
local Memory = require "util.memory"
|
||||
local Menu = require "util.menu"
|
||||
local Utils = require "util.utils"
|
||||
|
||||
local input = require "util.input"
|
||||
local memory = require "util.memory"
|
||||
local menu = require "util.menu"
|
||||
local utils = require "util.utils"
|
||||
local Pokemon = require "storage.pokemon"
|
||||
|
||||
local items = {
|
||||
pokeball = 4,
|
||||
|
@ -56,28 +56,28 @@ local ITEM_BASE = 0x131E
|
|||
|
||||
-- Data
|
||||
|
||||
function inventory.indexOf(name)
|
||||
function Inventory.indexOf(name)
|
||||
local searchID = items[name]
|
||||
for i=0,19 do
|
||||
local iidx = ITEM_BASE + i * 2
|
||||
if memory.raw(iidx) == searchID then
|
||||
if Memory.raw(iidx) == searchID then
|
||||
return i
|
||||
end
|
||||
end
|
||||
return -1
|
||||
end
|
||||
|
||||
function inventory.count(name)
|
||||
local index = inventory.indexOf(name)
|
||||
function Inventory.count(name)
|
||||
local index = Inventory.indexOf(name)
|
||||
if index ~= -1 then
|
||||
return memory.raw(ITEM_BASE + index * 2 + 1)
|
||||
return Memory.raw(ITEM_BASE + index * 2 + 1)
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function inventory.contains(...)
|
||||
function Inventory.contains(...)
|
||||
for i,name in ipairs(arg) do
|
||||
if inventory.count(name) > 0 then
|
||||
if Inventory.count(name) > 0 then
|
||||
return name
|
||||
end
|
||||
end
|
||||
|
@ -85,38 +85,38 @@ end
|
|||
|
||||
-- Actions
|
||||
|
||||
function inventory.teach(item, poke, replaceIdx, altPoke)
|
||||
local main = memory.value("menu", "main")
|
||||
local column = menu.getCol()
|
||||
function Inventory.teach(item, poke, replaceIdx, altPoke)
|
||||
local main = Memory.value("menu", "main")
|
||||
local column = Menu.getCol()
|
||||
if main == 144 then
|
||||
if column == 5 then
|
||||
menu.select(replaceIdx, true)
|
||||
Menu.select(replaceIdx, true)
|
||||
else
|
||||
input.press("A")
|
||||
Input.press("A")
|
||||
end
|
||||
elseif main == 128 then
|
||||
if column == 5 then
|
||||
menu.select(inventory.indexOf(item), "accelerate", true)
|
||||
Menu.select(Inventory.indexOf(item), "accelerate", true)
|
||||
elseif column == 11 then
|
||||
menu.select(2, true)
|
||||
Menu.select(2, true)
|
||||
elseif column == 14 then
|
||||
menu.select(0, true)
|
||||
Menu.select(0, true)
|
||||
end
|
||||
elseif main == 103 then
|
||||
input.press("B")
|
||||
Input.press("B")
|
||||
elseif main == 64 or main == 96 or main == 192 then
|
||||
if column == 5 then
|
||||
menu.select(replaceIdx, true)
|
||||
Menu.select(replaceIdx, true)
|
||||
elseif column == 14 then
|
||||
input.press("A")
|
||||
Input.press("A")
|
||||
elseif column == 15 then
|
||||
menu.select(0, true)
|
||||
Menu.select(0, true)
|
||||
else
|
||||
local idx = 0
|
||||
if poke then
|
||||
idx = pokemon.indexOf(poke, altPoke)
|
||||
idx = Pokemon.indexOf(poke, altPoke)
|
||||
end
|
||||
menu.select(idx, true)
|
||||
Menu.select(idx, true)
|
||||
end
|
||||
else
|
||||
return false
|
||||
|
@ -124,77 +124,77 @@ function inventory.teach(item, poke, replaceIdx, altPoke)
|
|||
return true
|
||||
end
|
||||
|
||||
function inventory.isFull()
|
||||
return memory.raw(0x1345) > 0
|
||||
function Inventory.isFull()
|
||||
return Memory.raw(0x1345) > 0
|
||||
end
|
||||
|
||||
function inventory.use(item, poke, midfight)
|
||||
function Inventory.use(item, poke, midfight)
|
||||
if midfight then
|
||||
local battleMenu = memory.value("battle", "menu")
|
||||
local battleMenu = Memory.value("battle", "menu")
|
||||
if battleMenu == 94 then
|
||||
local rowSelected = memory.value("menu", "row")
|
||||
if menu.getCol() == 9 then
|
||||
local rowSelected = Memory.value("menu", "row")
|
||||
if Menu.getCol() == 9 then
|
||||
if rowSelected == 0 then
|
||||
input.press("Down")
|
||||
Input.press("Down")
|
||||
else
|
||||
input.press("A")
|
||||
Input.press("A")
|
||||
end
|
||||
else
|
||||
input.press("Left")
|
||||
Input.press("Left")
|
||||
end
|
||||
elseif battleMenu == 233 then
|
||||
menu.select(inventory.indexOf(item), "accelerate", true)
|
||||
elseif utils.onPokemonSelect(battleMenu) then
|
||||
Menu.select(Inventory.indexOf(item), "accelerate", true)
|
||||
elseif Utils.onPokemonSelect(battleMenu) then
|
||||
if poke then
|
||||
if type(poke) == "string" then
|
||||
poke = pokemon.indexOf(poke)
|
||||
poke = Pokemon.indexOf(poke)
|
||||
end
|
||||
menu.select(poke, true)
|
||||
Menu.select(poke, true)
|
||||
else
|
||||
input.press("A")
|
||||
Input.press("A")
|
||||
end
|
||||
else
|
||||
input.press("B")
|
||||
Input.press("B")
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local main = memory.value("menu", "main")
|
||||
local column = menu.getCol()
|
||||
local main = Memory.value("menu", "main")
|
||||
local column = Menu.getCol()
|
||||
if main == 144 then
|
||||
if memory.value("battle", "menu") == 95 then
|
||||
input.press("B")
|
||||
if Memory.value("battle", "menu") == 95 then
|
||||
Input.press("B")
|
||||
else
|
||||
local idx = 0
|
||||
if poke then
|
||||
idx = pokemon.indexOf(poke)
|
||||
idx = Pokemon.indexOf(poke)
|
||||
end
|
||||
menu.select(idx, true)
|
||||
Menu.select(idx, true)
|
||||
end
|
||||
elseif main == 128 or main == 60 then
|
||||
if column == 5 then
|
||||
menu.select(inventory.indexOf(item), "accelerate", true)
|
||||
Menu.select(Inventory.indexOf(item), "accelerate", true)
|
||||
elseif column == 11 then
|
||||
menu.select(2, true)
|
||||
Menu.select(2, true)
|
||||
elseif column == 14 then
|
||||
menu.select(0, true)
|
||||
Menu.select(0, true)
|
||||
else
|
||||
local index = 0
|
||||
if poke then
|
||||
index = pokemon.indexOf(poke)
|
||||
index = Pokemon.indexOf(poke)
|
||||
end
|
||||
menu.select(index, true)
|
||||
Menu.select(index, true)
|
||||
end
|
||||
elseif main == 228 then
|
||||
if column == 14 and memory.value("battle", "menu") == 95 then
|
||||
input.press("B")
|
||||
if column == 14 and Memory.value("battle", "menu") == 95 then
|
||||
Input.press("B")
|
||||
end
|
||||
elseif main == 103 then
|
||||
input.press("B")
|
||||
Input.press("B")
|
||||
else
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
return inventory
|
||||
return Inventory
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
local pokemon = {}
|
||||
local Pokemon = {}
|
||||
|
||||
local bridge = require "util.bridge"
|
||||
local input = require "util.input"
|
||||
local memory = require "util.memory"
|
||||
local menu = require "util.menu"
|
||||
local utils = require "util.utils"
|
||||
local Bridge = require "util.bridge"
|
||||
local Input = require "util.input"
|
||||
local Memory = require "util.memory"
|
||||
local Menu = require "util.menu"
|
||||
|
||||
local pokeIDs = {
|
||||
rhydon = 1,
|
||||
|
@ -98,13 +97,13 @@ local function index(index, offset)
|
|||
double = dataTable[2]
|
||||
end
|
||||
local address = getAddress(index) + offset
|
||||
local value = memory.raw(address)
|
||||
local value = Memory.raw(address)
|
||||
if double then
|
||||
value = value + memory.raw(address + 1)
|
||||
value = value + Memory.raw(address + 1)
|
||||
end
|
||||
return value
|
||||
end
|
||||
pokemon.index = index
|
||||
Pokemon.index = index
|
||||
|
||||
local function indexOf(...)
|
||||
for ni,name in ipairs(arg) do
|
||||
|
@ -118,20 +117,20 @@ local function indexOf(...)
|
|||
end
|
||||
return -1
|
||||
end
|
||||
pokemon.indexOf = indexOf
|
||||
Pokemon.indexOf = indexOf
|
||||
|
||||
-- Table functions
|
||||
|
||||
function pokemon.battleMove(name)
|
||||
function Pokemon.battleMove(name)
|
||||
local mid = moveList[name]
|
||||
for i=1,4 do
|
||||
if mid == memory.raw(0x101B + i) then
|
||||
if mid == Memory.raw(0x101B + i) then
|
||||
return i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function pokemon.moveIndex(move, pokemon)
|
||||
function Pokemon.moveIndex(move, pokemon)
|
||||
local pokemonIdx
|
||||
if pokemon then
|
||||
pokemonIdx = indexOf(pokemon)
|
||||
|
@ -141,21 +140,21 @@ function pokemon.moveIndex(move, pokemon)
|
|||
local address = getAddress(pokemonIdx) + 7
|
||||
local mid = moveList[move]
|
||||
for i=1,4 do
|
||||
if mid == memory.raw(address + i) then
|
||||
if mid == Memory.raw(address + i) then
|
||||
return i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function pokemon.info(name, offset)
|
||||
function Pokemon.info(name, offset)
|
||||
return index(indexOf(name), offset)
|
||||
end
|
||||
|
||||
function pokemon.getID(name)
|
||||
function Pokemon.getID(name)
|
||||
return pokeIDs[name]
|
||||
end
|
||||
|
||||
function pokemon.getName(id)
|
||||
function Pokemon.getName(id)
|
||||
for name,pid in pairs(pokeIDs) do
|
||||
if pid == id then
|
||||
return name
|
||||
|
@ -163,7 +162,7 @@ function pokemon.getName(id)
|
|||
end
|
||||
end
|
||||
|
||||
function pokemon.getSacrifice(...)
|
||||
function Pokemon.getSacrifice(...)
|
||||
for i,name in ipairs(arg) do
|
||||
local pokemonIndex = indexOf(name)
|
||||
if pokemonIndex ~= -1 and index(pokemonIndex, "hp") > 0 then
|
||||
|
@ -172,7 +171,7 @@ function pokemon.getSacrifice(...)
|
|||
end
|
||||
end
|
||||
|
||||
function pokemon.inParty(...)
|
||||
function Pokemon.inParty(...)
|
||||
for i,name in ipairs(arg) do
|
||||
if indexOf(name) ~= -1 then
|
||||
return name
|
||||
|
@ -180,12 +179,12 @@ function pokemon.inParty(...)
|
|||
end
|
||||
end
|
||||
|
||||
function pokemon.forMove(move)
|
||||
function Pokemon.forMove(move)
|
||||
local moveID = moveList[move]
|
||||
for i=0,5 do
|
||||
local address = getAddress(i)
|
||||
for j=8,11 do
|
||||
if memory.raw(address + j) == moveID then
|
||||
if Memory.raw(address + j) == moveID then
|
||||
return i
|
||||
end
|
||||
end
|
||||
|
@ -193,16 +192,16 @@ function pokemon.forMove(move)
|
|||
return -1
|
||||
end
|
||||
|
||||
function pokemon.hasMove(move)
|
||||
return pokemon.forMove(move) ~= -1
|
||||
function Pokemon.hasMove(move)
|
||||
return Pokemon.forMove(move) ~= -1
|
||||
end
|
||||
|
||||
function pokemon.updateParty()
|
||||
local partySize = memory.value("player", "party_size")
|
||||
function Pokemon.updateParty()
|
||||
local partySize = Memory.value("player", "party_size")
|
||||
if partySize ~= previousPartySize then
|
||||
local poke = pokemon.inParty("oddish", "paras", "spearow", "pidgey", "nidoran", "squirtle")
|
||||
local poke = Pokemon.inParty("oddish", "paras", "spearow", "pidgey", "nidoran", "squirtle")
|
||||
if poke then
|
||||
bridge.caught(poke)
|
||||
Bridge.caught(poke)
|
||||
previousPartySize = partySize
|
||||
end
|
||||
end
|
||||
|
@ -210,8 +209,8 @@ end
|
|||
|
||||
-- General
|
||||
|
||||
function pokemon.isOpponent(...)
|
||||
local oid = memory.value("battle", "opponent_id")
|
||||
function Pokemon.isOpponent(...)
|
||||
local oid = Memory.value("battle", "opponent_id")
|
||||
for i,name in ipairs(arg) do
|
||||
if oid == pokeIDs[name] then
|
||||
return name
|
||||
|
@ -219,8 +218,8 @@ function pokemon.isOpponent(...)
|
|||
end
|
||||
end
|
||||
|
||||
function pokemon.isDeployed(...)
|
||||
local deployedID = memory.value("battle", "our_id")
|
||||
function Pokemon.isDeployed(...)
|
||||
local deployedID = Memory.value("battle", "our_id")
|
||||
for i,name in ipairs(arg) do
|
||||
if deployedID == pokeIDs[name] then
|
||||
return name
|
||||
|
@ -228,36 +227,36 @@ function pokemon.isDeployed(...)
|
|||
end
|
||||
end
|
||||
|
||||
function pokemon.isEvolving()
|
||||
return memory.value("menu", "pokemon") == 144
|
||||
function Pokemon.isEvolving()
|
||||
return Memory.value("menu", "pokemon") == 144
|
||||
end
|
||||
|
||||
function pokemon.getExp()
|
||||
return memory.raw(0x117A) * 256 + memory.raw(0x117B)
|
||||
function Pokemon.getExp()
|
||||
return Memory.raw(0x117A) * 256 + Memory.raw(0x117B)
|
||||
end
|
||||
|
||||
function pokemon.inRedBar()
|
||||
function Pokemon.inRedBar()
|
||||
local curr_hp, max_hp = index(0, "hp"), index(0, "max_hp")
|
||||
return curr_hp / max_hp <= 0.2
|
||||
end
|
||||
|
||||
function pokemon.use(move)
|
||||
local main = memory.value("menu", "main")
|
||||
local pokeName = pokemon.forMove(move)
|
||||
function Pokemon.use(move)
|
||||
local main = Memory.value("menu", "main")
|
||||
local pokeName = Pokemon.forMove(move)
|
||||
if main == 141 then
|
||||
input.press("A")
|
||||
Input.press("A")
|
||||
elseif main == 128 then
|
||||
local column = menu.getCol()
|
||||
local column = Menu.getCol()
|
||||
if column == 11 then
|
||||
menu.select(1, true)
|
||||
Menu.select(1, true)
|
||||
elseif column == 10 or column == 12 then
|
||||
local midx = 0
|
||||
local menuSize = memory.value("menu", "size")
|
||||
local menuSize = Memory.value("menu", "size")
|
||||
if menuSize == 4 then
|
||||
if move == "dig" then
|
||||
midx = 1
|
||||
elseif move == "surf" then
|
||||
if pokemon.inParty("paras") then
|
||||
if Pokemon.inParty("paras") then
|
||||
midx = 1
|
||||
end
|
||||
end
|
||||
|
@ -268,18 +267,18 @@ function pokemon.use(move)
|
|||
midx = 1
|
||||
end
|
||||
end
|
||||
menu.select(midx, true)
|
||||
Menu.select(midx, true)
|
||||
else
|
||||
input.press("B")
|
||||
Input.press("B")
|
||||
end
|
||||
elseif main == 103 then
|
||||
menu.select(pokeName, true)
|
||||
Menu.select(pokeName, true)
|
||||
elseif main == 228 then
|
||||
input.press("B")
|
||||
Input.press("B")
|
||||
else
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
return pokemon
|
||||
return Pokemon
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
local bridge = {}
|
||||
local Bridge = {}
|
||||
|
||||
local socket
|
||||
if INTERNAL then
|
||||
|
@ -36,7 +36,7 @@ end
|
|||
|
||||
-- Wrapper functions
|
||||
|
||||
function bridge.init()
|
||||
function Bridge.init()
|
||||
if socket then
|
||||
-- io.popen("java -jar Main.jar")
|
||||
client = socket.connect("127.0.0.1", 13378)
|
||||
|
@ -51,17 +51,17 @@ function bridge.init()
|
|||
end
|
||||
end
|
||||
|
||||
function bridge.tweet(message) -- Two of the same tweet in a row will only send one
|
||||
function Bridge.tweet(message) -- Two of the same tweet in a row will only send one
|
||||
print("tweet::"..message)
|
||||
return send("tweet", message)
|
||||
end
|
||||
|
||||
function bridge.pollForName()
|
||||
bridge.polling = true
|
||||
function Bridge.pollForName()
|
||||
Bridge.polling = true
|
||||
send("poll_name")
|
||||
end
|
||||
|
||||
function bridge.chat(message, extra)
|
||||
function Bridge.chat(message, extra)
|
||||
if extra then
|
||||
print(message.." || "..extra)
|
||||
else
|
||||
|
@ -70,25 +70,25 @@ function bridge.chat(message, extra)
|
|||
return send("msg", message)
|
||||
end
|
||||
|
||||
function bridge.time(message)
|
||||
function Bridge.time(message)
|
||||
if not timeStopped then
|
||||
return send("time", message)
|
||||
end
|
||||
end
|
||||
|
||||
function bridge.stats(message)
|
||||
function Bridge.stats(message)
|
||||
return send("stats", message)
|
||||
end
|
||||
|
||||
function bridge.command(command)
|
||||
function Bridge.command(command)
|
||||
return send("livesplit_command", command);
|
||||
end
|
||||
|
||||
function bridge.comparisonTime()
|
||||
function Bridge.comparisonTime()
|
||||
return send("livesplit_getcomparisontime");
|
||||
end
|
||||
|
||||
function bridge.process()
|
||||
function Bridge.process()
|
||||
local response = readln()
|
||||
if response then
|
||||
-- print(">"..response)
|
||||
|
@ -100,42 +100,42 @@ function bridge.process()
|
|||
end
|
||||
end
|
||||
|
||||
function bridge.input(key)
|
||||
function Bridge.input(key)
|
||||
send("input", key)
|
||||
end
|
||||
|
||||
function bridge.caught(name)
|
||||
function Bridge.caught(name)
|
||||
if name then
|
||||
send("caught", name)
|
||||
end
|
||||
end
|
||||
|
||||
function bridge.hp(curr, max)
|
||||
function Bridge.hp(curr, max)
|
||||
send("hp", curr..","..max)
|
||||
end
|
||||
|
||||
function bridge.liveSplit()
|
||||
function Bridge.liveSplit()
|
||||
send("start")
|
||||
timeStopped = false
|
||||
end
|
||||
|
||||
function bridge.split(finished)
|
||||
function Bridge.split(finished)
|
||||
if finished then
|
||||
timeStopped = true
|
||||
end
|
||||
send("split")
|
||||
end
|
||||
|
||||
function bridge.encounter()
|
||||
function Bridge.encounter()
|
||||
send("encounter")
|
||||
end
|
||||
|
||||
function bridge.reset()
|
||||
function Bridge.reset()
|
||||
send("reset")
|
||||
timeStopped = false
|
||||
end
|
||||
|
||||
function bridge.close()
|
||||
function Bridge.close()
|
||||
if client then
|
||||
client:close()
|
||||
client = nil
|
||||
|
@ -143,4 +143,4 @@ function bridge.close()
|
|||
print("Bridge closed")
|
||||
end
|
||||
|
||||
return bridge
|
||||
return Bridge
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
local input = {}
|
||||
local Input = {}
|
||||
|
||||
local bridge = require "util.bridge"
|
||||
local memory = require "util.memory"
|
||||
local Bridge = require "util.bridge"
|
||||
local Memory = require "util.memory"
|
||||
|
||||
local lastSend
|
||||
local currentButton, remainingFrames, setForFrame
|
||||
|
@ -11,7 +11,7 @@ local bCancel = true
|
|||
local function bridgeButton(btn)
|
||||
if btn ~= lastSend then
|
||||
lastSend = btn
|
||||
bridge.input(btn)
|
||||
Bridge.input(btn)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -28,7 +28,7 @@ local function sendButton(button, ab)
|
|||
setForFrame = button
|
||||
end
|
||||
|
||||
function input.press(button, frames)
|
||||
function Input.press(button, frames)
|
||||
if setForFrame then
|
||||
print("ERR: Reassigning "..setForFrame.." to "..button)
|
||||
return
|
||||
|
@ -49,9 +49,9 @@ function input.press(button, frames)
|
|||
sendButton(button)
|
||||
end
|
||||
|
||||
function input.cancel(accept)
|
||||
if accept and memory.value("menu", "shop_current") == 20 then
|
||||
input.press(accept)
|
||||
function Input.cancel(accept)
|
||||
if accept and Memory.value("menu", "shop_current") == 20 then
|
||||
Input.press(accept)
|
||||
else
|
||||
local button
|
||||
if bCancel then
|
||||
|
@ -65,18 +65,18 @@ function input.cancel(accept)
|
|||
end
|
||||
end
|
||||
|
||||
function input.escape()
|
||||
function Input.escape()
|
||||
local inputTable = {Right=true, Down=true}
|
||||
joypad.set(inputTable)
|
||||
bridgeButton("D,R")
|
||||
end
|
||||
|
||||
function input.clear()
|
||||
function Input.clear()
|
||||
currentButton = nil
|
||||
remainingFrames = -1
|
||||
end
|
||||
|
||||
function input.update()
|
||||
function Input.update()
|
||||
if currentButton then
|
||||
remainingFrames = remainingFrames - 1
|
||||
if remainingFrames >= 0 then
|
||||
|
@ -91,19 +91,19 @@ function input.update()
|
|||
setForFrame = nil
|
||||
end
|
||||
|
||||
function input.advance()
|
||||
function Input.advance()
|
||||
if not setForFrame then
|
||||
bridgeButton("e")
|
||||
end
|
||||
end
|
||||
|
||||
function input.setDebug(enabled)
|
||||
function Input.setDebug(enabled)
|
||||
debug = enabled
|
||||
end
|
||||
|
||||
function input.test(fn, completes)
|
||||
function Input.test(fn, completes)
|
||||
while true do
|
||||
if not input.update() then
|
||||
if not Input.update() then
|
||||
if fn() and completes then
|
||||
break
|
||||
end
|
||||
|
@ -115,4 +115,4 @@ function input.test(fn, completes)
|
|||
end
|
||||
end
|
||||
|
||||
return input
|
||||
return Input
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
local Memory = {}
|
||||
|
||||
-- memory.usememorydomain("WRAM")
|
||||
-- print(memory.getcurrentmemorydomain())
|
||||
-- print(memory.getcurrentmemorydomainsize())
|
||||
|
||||
local memoryNames = {
|
||||
setting = {
|
||||
text_speed = 0x0D3D,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
local menu = {}
|
||||
local Menu = {}
|
||||
|
||||
local input = require "util.input"
|
||||
local memory = require "util.memory"
|
||||
local Input = require "util.input"
|
||||
local Memory = require "util.memory"
|
||||
|
||||
local yellow = GAME_NAME == "yellow"
|
||||
|
||||
|
@ -15,9 +15,9 @@ local function getRow(menuType, scrolls)
|
|||
else
|
||||
menuType = "row"
|
||||
end
|
||||
local row = memory.value("menu", menuType)
|
||||
local row = Memory.value("menu", menuType)
|
||||
if scrolls then
|
||||
row = row + memory.value("menu", "scroll_offset")
|
||||
row = row + Memory.value("menu", "scroll_offset")
|
||||
end
|
||||
return row
|
||||
end
|
||||
|
@ -39,7 +39,7 @@ local function setRow(desired, throttle, scrolls, menuType, loop)
|
|||
else
|
||||
sliding = false
|
||||
end
|
||||
return menu.balance(currentRow, desired, true, loop, throttle)
|
||||
return Menu.balance(currentRow, desired, true, loop, throttle)
|
||||
end
|
||||
|
||||
local function isCurrently(desired, menuType)
|
||||
|
@ -48,48 +48,48 @@ local function isCurrently(desired, menuType)
|
|||
else
|
||||
menuType = "current"
|
||||
end
|
||||
return memory.value("menu", menuType) == desired
|
||||
return Memory.value("menu", menuType) == desired
|
||||
end
|
||||
menu.isCurrently = isCurrently
|
||||
Menu.isCurrently = isCurrently
|
||||
|
||||
-- Menu
|
||||
|
||||
function menu.getCol()
|
||||
return memory.value("menu", "column")
|
||||
function Menu.getCol()
|
||||
return Memory.value("menu", "column")
|
||||
end
|
||||
|
||||
function menu.open(desired, atIndex, menuType)
|
||||
function Menu.open(desired, atIndex, menuType)
|
||||
if isCurrently(desired, menuType) then
|
||||
return true
|
||||
end
|
||||
menu.select(atIndex, false, false, menuType)
|
||||
Menu.select(atIndex, false, false, menuType)
|
||||
return false
|
||||
end
|
||||
|
||||
function menu.select(option, throttle, scrolls, menuType, dontPress, loop)
|
||||
function Menu.select(option, throttle, scrolls, menuType, dontPress, loop)
|
||||
if setRow(option, throttle, scrolls, menuType, loop) then
|
||||
local delay = 1
|
||||
if throttle then
|
||||
delay = 2
|
||||
end
|
||||
if not dontPress then
|
||||
input.press("A", delay)
|
||||
Input.press("A", delay)
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function menu.cancel(desired, menuType)
|
||||
function Menu.cancel(desired, menuType)
|
||||
if not isCurrently(desired, menuType) then
|
||||
return true
|
||||
end
|
||||
input.press("B")
|
||||
Input.press("B")
|
||||
return false
|
||||
end
|
||||
|
||||
-- Selections
|
||||
|
||||
function menu.balance(current, desired, inverted, looping, throttle)
|
||||
function Menu.balance(current, desired, inverted, looping, throttle)
|
||||
if current == desired then
|
||||
sliding = false
|
||||
return true
|
||||
|
@ -104,14 +104,14 @@ function menu.balance(current, desired, inverted, looping, throttle)
|
|||
goUp = not goUp
|
||||
end
|
||||
if goUp then
|
||||
input.press("Up", throttle)
|
||||
Input.press("Up", throttle)
|
||||
else
|
||||
input.press("Down", throttle)
|
||||
Input.press("Down", throttle)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function menu.sidle(current, desired, looping, throttle)
|
||||
function Menu.sidle(current, desired, looping, throttle)
|
||||
if current == desired then
|
||||
return true
|
||||
end
|
||||
|
@ -125,29 +125,29 @@ function menu.sidle(current, desired, looping, throttle)
|
|||
goLeft = not goLeft
|
||||
end
|
||||
if goLeft then
|
||||
input.press("Left", throttle)
|
||||
Input.press("Left", throttle)
|
||||
else
|
||||
input.press("Right", throttle)
|
||||
Input.press("Right", throttle)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function menu.setCol(desired)
|
||||
return menu.sidle(menu.getCol(), desired)
|
||||
function Menu.setCol(desired)
|
||||
return Menu.sidle(Menu.getCol(), desired)
|
||||
end
|
||||
|
||||
-- Options
|
||||
|
||||
function menu.setOption(name, desired)
|
||||
function Menu.setOption(name, desired)
|
||||
if yellow then
|
||||
local rowFor = {
|
||||
text_speed = 0,
|
||||
battle_animation = 1,
|
||||
battle_style = 2
|
||||
}
|
||||
local currentRow = memory.raw(0x0D3D, true)
|
||||
if menu.balance(currentRow, rowFor[name], true, false, true) then
|
||||
input.press("Left")
|
||||
local currentRow = Memory.raw(0x0D3D, true)
|
||||
if Menu.balance(currentRow, rowFor[name], true, false, true) then
|
||||
Input.press("Left")
|
||||
end
|
||||
else
|
||||
local rowFor = {
|
||||
|
@ -155,11 +155,11 @@ function menu.setOption(name, desired)
|
|||
battle_animation = 8,
|
||||
battle_style = 13
|
||||
}
|
||||
if memory.value("setting", name) == desired then
|
||||
if Memory.value("setting", name) == desired then
|
||||
return true
|
||||
end
|
||||
if setRow(rowFor[name], true, false, "settings") then
|
||||
menu.setCol(desired)
|
||||
Menu.setCol(desired)
|
||||
end
|
||||
end
|
||||
return false
|
||||
|
@ -167,31 +167,31 @@ end
|
|||
|
||||
-- Pause menu
|
||||
|
||||
function menu.isOpen()
|
||||
return memory.value("game", "textbox") == 1 or memory.value("menu", "current") == 24
|
||||
function Menu.isOpen()
|
||||
return Memory.value("game", "textbox") == 1 or Memory.value("menu", "current") == 24
|
||||
end
|
||||
|
||||
function menu.close()
|
||||
if memory.value("game", "textbox") == 0 and memory.value("menu", "main") < 8 then
|
||||
function Menu.close()
|
||||
if Memory.value("game", "textbox") == 0 and Memory.value("menu", "main") < 8 then
|
||||
return true
|
||||
end
|
||||
input.press("B")
|
||||
Input.press("B")
|
||||
end
|
||||
|
||||
function menu.pause()
|
||||
if memory.value("game", "textbox") == 1 then
|
||||
if memory.value("battle", "menu") == 95 then
|
||||
input.cancel()
|
||||
function Menu.pause()
|
||||
if Memory.value("game", "textbox") == 1 then
|
||||
if Memory.value("battle", "menu") == 95 then
|
||||
Input.cancel()
|
||||
else
|
||||
local main = memory.value("menu", "main")
|
||||
local main = Memory.value("menu", "main")
|
||||
if main > 2 and main ~= 64 then
|
||||
return true
|
||||
end
|
||||
input.press("B")
|
||||
Input.press("B")
|
||||
end
|
||||
else
|
||||
input.press("Start", 2)
|
||||
Input.press("Start", 2)
|
||||
end
|
||||
end
|
||||
|
||||
return menu
|
||||
return Menu
|
||||
|
|
|
@ -1,26 +1,25 @@
|
|||
local paint = {}
|
||||
local Paint = {}
|
||||
|
||||
local memory = require "util.memory"
|
||||
local player = require "util.player"
|
||||
local utils = require "util.utils"
|
||||
local Memory = require "util.memory"
|
||||
local Player = require "util.player"
|
||||
local Utils = require "util.utils"
|
||||
|
||||
local inventory = require "storage.inventory"
|
||||
local pokemon = require "storage.pokemon"
|
||||
local Pokemon = require "storage.pokemon"
|
||||
|
||||
local encounters = 0
|
||||
local elapsedTime = utils.elapsedTime
|
||||
local elapsedTime = Utils.elapsedTime
|
||||
|
||||
function paint.draw(currentMap)
|
||||
local px, py = player.position()
|
||||
function Paint.draw(currentMap)
|
||||
local px, py = Player.position()
|
||||
gui.text(0, 14, currentMap..": "..px.." "..py)
|
||||
gui.text(0, 0, elapsedTime())
|
||||
|
||||
if memory.value("battle", "our_id") > 0 then
|
||||
local hp = pokemon.index(0, "hp")
|
||||
if Memory.value("battle", "our_id") > 0 then
|
||||
local hp = Pokemon.index(0, "hp")
|
||||
local hpStatus
|
||||
if hp == 0 then
|
||||
hpStatus = "DEAD"
|
||||
elseif hp <= math.ceil(pokemon.index(0, "max_hp") * 0.2) then
|
||||
elseif hp <= math.ceil(Pokemon.index(0, "max_hp") * 0.2) then
|
||||
hpStatus = "RED"
|
||||
end
|
||||
if hpStatus then
|
||||
|
@ -28,30 +27,30 @@ function paint.draw(currentMap)
|
|||
end
|
||||
end
|
||||
|
||||
local nidx = pokemon.indexOf("nidoran", "nidorino", "nidoking")
|
||||
local nidx = Pokemon.indexOf("nidoran", "nidorino", "nidoking")
|
||||
if nidx ~= -1 then
|
||||
local att = pokemon.index(nidx, "attack")
|
||||
local def = pokemon.index(nidx, "defense")
|
||||
local spd = pokemon.index(nidx, "speed")
|
||||
local scl = pokemon.index(nidx, "special")
|
||||
local att = Pokemon.index(nidx, "attack")
|
||||
local def = Pokemon.index(nidx, "defense")
|
||||
local spd = Pokemon.index(nidx, "speed")
|
||||
local scl = Pokemon.index(nidx, "special")
|
||||
gui.text(100, 0, att.." "..def.." "..spd.." "..scl)
|
||||
end
|
||||
local enc = " encounter"
|
||||
if encounters ~= 1 then
|
||||
enc = enc.."s"
|
||||
end
|
||||
gui.text(0, 116, memory.value("battle", "critical"))
|
||||
gui.text(0, 125, memory.value("player", "repel"))
|
||||
gui.text(0, 116, Memory.value("battle", "critical"))
|
||||
gui.text(0, 125, Memory.value("player", "repel"))
|
||||
gui.text(0, 134, encounters..enc)
|
||||
return true
|
||||
end
|
||||
|
||||
function paint.wildEncounters(count)
|
||||
function Paint.wildEncounters(count)
|
||||
encounters = count
|
||||
end
|
||||
|
||||
function paint.reset()
|
||||
function Paint.reset()
|
||||
encounters = 0
|
||||
end
|
||||
|
||||
return paint
|
||||
return Paint
|
||||
|
|
|
@ -1,38 +1,38 @@
|
|||
local player = {}
|
||||
local Player = {}
|
||||
|
||||
local textbox = require "action.textbox"
|
||||
local Textbox = require "action.textbox"
|
||||
|
||||
local input = require "util.input"
|
||||
local memory = require "util.memory"
|
||||
local Input = require "util.input"
|
||||
local Memory = require "util.memory"
|
||||
|
||||
local facingDirections = {Up=8, Right=1, Left=2, Down=4}
|
||||
|
||||
function player.isFacing(direction)
|
||||
return memory.value("player", "facing") == facingDirections[direction]
|
||||
function Player.isFacing(direction)
|
||||
return Memory.value("player", "facing") == facingDirections[direction]
|
||||
end
|
||||
|
||||
function player.face(direction)
|
||||
if player.isFacing(direction) then
|
||||
function Player.face(direction)
|
||||
if Player.isFacing(direction) then
|
||||
return true
|
||||
end
|
||||
if textbox.handle() then
|
||||
input.press(direction, 0)
|
||||
if Textbox.handle() then
|
||||
Input.press(direction, 0)
|
||||
end
|
||||
end
|
||||
|
||||
function player.interact(direction)
|
||||
if player.face(direction) then
|
||||
input.press("A", 2)
|
||||
function Player.interact(direction)
|
||||
if Player.face(direction) then
|
||||
Input.press("A", 2)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function player.isMoving()
|
||||
return memory.value("player", "moving") ~= 0
|
||||
function Player.isMoving()
|
||||
return Memory.value("player", "moving") ~= 0
|
||||
end
|
||||
|
||||
function player.position()
|
||||
return memory.value("player", "x"), memory.value("player", "y")
|
||||
function Player.position()
|
||||
return Memory.value("player", "x"), Memory.value("player", "y")
|
||||
end
|
||||
|
||||
return player
|
||||
return Player
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
local settings = {}
|
||||
local Settings = {}
|
||||
|
||||
local memory = require "util.memory"
|
||||
local menu = require "util.menu"
|
||||
local Memory = require "util.memory"
|
||||
local Menu = require "util.menu"
|
||||
|
||||
local yellow = YELLOW
|
||||
|
||||
|
@ -30,23 +30,23 @@ local function isEnabled(name)
|
|||
battle_animation = 128,
|
||||
battle_style = 64
|
||||
}
|
||||
local settingMask = memory.value("setting", "yellow_bitmask", true)
|
||||
local settingMask = Memory.value("setting", "yellow_bitmask", true)
|
||||
return bit.band(settingMask, matching[name]) == desired[name]
|
||||
else
|
||||
return memory.value("setting", name) == desired[name]
|
||||
return Memory.value("setting", name) == desired[name]
|
||||
end
|
||||
end
|
||||
|
||||
function settings.set(...)
|
||||
function Settings.set(...)
|
||||
for i,name in ipairs(arg) do
|
||||
if not isEnabled(name) then
|
||||
if menu.open(settings_menu, 1) then
|
||||
menu.setOption(name, desired[name])
|
||||
if Menu.open(settings_menu, 1) then
|
||||
Menu.setOption(name, desired[name])
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
return menu.cancel(settings_menu)
|
||||
return Menu.cancel(settings_menu)
|
||||
end
|
||||
|
||||
return settings
|
||||
return Settings
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
local utils = {}
|
||||
local Utils = {}
|
||||
|
||||
local memory = require "util.memory"
|
||||
local Memory = require "util.memory"
|
||||
|
||||
-- GENERAL
|
||||
|
||||
function utils.dist(x1, y1, x2, y2)
|
||||
function Utils.dist(x1, y1, x2, y2)
|
||||
return math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2))
|
||||
end
|
||||
|
||||
function utils.each(table, func)
|
||||
function Utils.each(table, func)
|
||||
for key,val in pairs(table) do
|
||||
func(key.." = "..tostring(val)..",")
|
||||
end
|
||||
end
|
||||
|
||||
function utils.eachi(table, func)
|
||||
function Utils.eachi(table, func)
|
||||
for idx,val in ipairs(table) do
|
||||
if val then
|
||||
func(idx.." "..val)
|
||||
|
@ -24,7 +24,7 @@ function utils.eachi(table, func)
|
|||
end
|
||||
end
|
||||
|
||||
function utils.match(needle, haystack)
|
||||
function Utils.match(needle, haystack)
|
||||
for i,val in ipairs(haystack) do
|
||||
if needle == val then
|
||||
return true
|
||||
|
@ -33,7 +33,7 @@ function utils.match(needle, haystack)
|
|||
return false
|
||||
end
|
||||
|
||||
function utils.key(needle, haystack)
|
||||
function Utils.key(needle, haystack)
|
||||
for key,val in pairs(haystack) do
|
||||
if needle == val then
|
||||
return key
|
||||
|
@ -44,7 +44,7 @@ end
|
|||
|
||||
-- GAME
|
||||
|
||||
function utils.canPotionWith(potion, forDamage, curr_hp, max_hp)
|
||||
function Utils.canPotionWith(potion, forDamage, curr_hp, max_hp)
|
||||
local potion_hp
|
||||
if potion == "full_restore" then
|
||||
potion_hp = 9001
|
||||
|
@ -56,20 +56,20 @@ function utils.canPotionWith(potion, forDamage, curr_hp, max_hp)
|
|||
return math.min(curr_hp + potion_hp, max_hp) >= forDamage - 1
|
||||
end
|
||||
|
||||
function utils.ingame()
|
||||
return memory.raw(0x020E) > 0
|
||||
function Utils.ingame()
|
||||
return Memory.raw(0x020E) > 0
|
||||
end
|
||||
|
||||
function utils.onPokemonSelect(battleMenu)
|
||||
function Utils.onPokemonSelect(battleMenu)
|
||||
return battleMenu == 8 or battleMenu == 48 or battleMenu == 184 or battleMenu == 224
|
||||
end
|
||||
|
||||
-- TIME
|
||||
|
||||
function utils.igt()
|
||||
local secs = memory.raw(0x1A44)
|
||||
local mins = memory.raw(0x1A43)
|
||||
local hours = memory.raw(0x1A41)
|
||||
function Utils.igt()
|
||||
local secs = Memory.raw(0x1A44)
|
||||
local mins = Memory.raw(0x1A43)
|
||||
local hours = Memory.raw(0x1A41)
|
||||
return secs + mins * 60 + hours * 3600
|
||||
end
|
||||
|
||||
|
@ -80,8 +80,8 @@ local function clockSegment(unit)
|
|||
return unit
|
||||
end
|
||||
|
||||
function utils.timeSince(prevTime)
|
||||
local currTime = utils.igt()
|
||||
function Utils.timeSince(prevTime)
|
||||
local currTime = Utils.igt()
|
||||
local diff = currTime - prevTime
|
||||
local timeString
|
||||
if diff > 0 then
|
||||
|
@ -92,23 +92,23 @@ function utils.timeSince(prevTime)
|
|||
return currTime, timeString
|
||||
end
|
||||
|
||||
function utils.elapsedTime()
|
||||
local secs = memory.raw(0x1A44)
|
||||
function Utils.elapsedTime()
|
||||
local secs = Memory.raw(0x1A44)
|
||||
if secs < 10 then
|
||||
secs = "0"..secs
|
||||
end
|
||||
local mins = memory.raw(0x1A43)
|
||||
local mins = Memory.raw(0x1A43)
|
||||
if mins < 10 then
|
||||
mins = "0"..mins
|
||||
end
|
||||
return memory.raw(0x1A41)..":"..mins..":"..secs
|
||||
return Memory.raw(0x1A41)..":"..mins..":"..secs
|
||||
end
|
||||
|
||||
function utils.frames()
|
||||
local totalFrames = memory.raw(0x1A41) * 60
|
||||
totalFrames = (totalFrames + memory.raw(0x1A43)) * 60
|
||||
totalFrames = (totalFrames + memory.raw(0x1A44)) * 60
|
||||
return totalFrames + memory.raw(0x1A45)
|
||||
function Utils.frames()
|
||||
local totalFrames = Memory.raw(0x1A41) * 60
|
||||
totalFrames = (totalFrames + Memory.raw(0x1A43)) * 60
|
||||
totalFrames = (totalFrames + Memory.raw(0x1A44)) * 60
|
||||
return totalFrames + Memory.raw(0x1A45)
|
||||
end
|
||||
|
||||
return utils
|
||||
return Utils
|
||||
|
|
Loading…
Reference in New Issue