PokeBot/main.lua

226 lines
5.2 KiB
Lua
Raw Normal View History

2015-04-06 01:18:46 -07:00
-- OPTIONS
2014-07-12 18:47:39 -07:00
RESET_FOR_TIME = true -- Set to false if you just want to see the bot finish a run
2014-07-12 18:47:39 -07:00
local CUSTOM_SEED = nil -- Set to a known seed to replay it, or leave nil for random runs
local PAINT_ON = true -- Display contextual information while the bot runs
2014-07-12 18:47:39 -07:00
-- START CODE (hard hats on)
2014-07-12 18:47:39 -07:00
2015-04-04 20:38:38 -07:00
VERSION = "1.3"
GAME_NAME = "red"
YELLOW = GAME_NAME == "yellow"
INTERNAL = false
local START_WAIT = 99
2015-04-06 01:18:46 -07:00
local Battle = require "action.battle"
local Textbox = require "action.textbox"
local Walk = require "action.walk"
2014-07-12 18:47:39 -07:00
2015-04-06 01:18:46 -07:00
local Combat = require "ai.combat"
local Control = require "ai.control"
local Strategies = require("ai."..GAME_NAME..".strategies")
2014-07-12 18:47:39 -07:00
2015-04-06 01:18:46 -07:00
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"
2014-07-12 18:47:39 -07:00
2015-04-06 01:18:46 -07:00
local Pokemon = require "storage.pokemon"
2014-07-12 18:47:39 -07:00
local hasAlreadyStartedPlaying = false
local inBattle, oldSecs
local running = true
local previousPartySize = 0
local lastHP
local criticaled = false
local function startNewAdventure()
local startMenu, withBattleStyle
if YELLOW then
2015-04-06 01:18:46 -07:00
startMenu = Memory.raw(0x0F95) == 0
2014-07-12 18:47:39 -07:00
withBattleStyle = "battle_style"
else
2015-04-06 01:18:46 -07:00
startMenu = Memory.value("player", "name") ~= 0
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
if startMenu and Menu.getCol() ~= 0 then
if Settings.set("text_speed", "battle_animation", withBattleStyle) then
Menu.select(0)
2014-07-12 18:47:39 -07:00
end
elseif math.random(0, START_WAIT) == 0 then
2015-04-06 01:18:46 -07:00
Input.press("Start")
2014-07-12 18:47:39 -07:00
end
end
local function choosePlayerNames()
local name
2015-04-06 01:18:46 -07:00
if Memory.value("player", "name2") == 80 then
name = "E"
2014-07-12 18:47:39 -07:00
else
name = "B"
end
2015-04-06 01:18:46 -07:00
Textbox.name(name, true)
2014-07-12 18:47:39 -07:00
end
local function pollForResponse()
2015-04-06 01:18:46 -07:00
local response = Bridge.process()
if response then
2015-04-06 01:18:46 -07:00
Bridge.polling = false
Textbox.setName(tonumber(response))
2014-07-12 18:47:39 -07:00
end
end
local function resetAll()
2015-04-06 01:18:46 -07:00
Strategies.softReset()
Combat.reset()
Control.reset()
Walk.reset()
Paint.reset()
Bridge.reset()
2014-07-12 18:47:39 -07:00
oldSecs = 0
running = false
previousPartySize = 0
-- client.speedmode = 200
if CUSTOM_SEED then
2015-04-06 01:18:46 -07:00
Strategies.seed = CUSTOM_SEED
print("RUNNING WITH A FIXED SEED ("..Strategies.seed.."), every run will play out identically!")
2014-07-12 18:47:39 -07:00
else
2015-04-06 01:18:46 -07:00
Strategies.seed = os.time()
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
math.randomseed(Strategies.seed)
2014-07-12 18:47:39 -07:00
end
2015-04-06 00:50:00 -07:00
-- EXECUTE
2015-04-06 01:18:46 -07:00
Control.init()
2014-07-12 18:47:39 -07:00
print("Welcome to PokeBot "..GAME_NAME.." version "..VERSION)
2015-04-06 01:18:46 -07:00
STREAMING_MODE = not Walk.init()
if INTERNAL and STREAMING_MODE then
RESET_FOR_TIME = true
end
if CUSTOM_SEED then
2014-07-12 18:47:39 -07:00
client.reboot_core()
else
2015-04-06 01:18:46 -07:00
hasAlreadyStartedPlaying = Utils.ingame()
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
Strategies.init(hasAlreadyStartedPlaying)
if RESET_FOR_TIME and hasAlreadyStartedPlaying then
2014-07-12 18:47:39 -07:00
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
2015-04-06 01:18:46 -07:00
Bridge.init()
2014-07-12 18:47:39 -07:00
else
2015-04-06 01:18:46 -07:00
Input.setDebug(true)
2014-07-12 18:47:39 -07:00
end
-- Main loop
2014-07-12 18:47:39 -07:00
local previousMap
while true do
2015-04-06 01:18:46 -07:00
local currentMap = Memory.value("game", "map")
if currentMap ~= previousMap then
2015-04-06 01:18:46 -07:00
Input.clear()
2014-07-12 18:47:39 -07:00
previousMap = currentMap
end
2015-04-06 01:18:46 -07:00
if Strategies.frames then
if Memory.value("game", "battle") == 0 then
Strategies.frames = Strategies.frames + 1
end
2015-04-06 01:18:46 -07:00
gui.text(0, 80, Strategies.frames)
end
2015-04-06 01:18:46 -07:00
if Bridge.polling then
pollForResponse()
end
2015-04-06 01:18:46 -07:00
if not Input.update() then
if not Utils.ingame() then
if currentMap == 0 then
if running then
if not hasAlreadyStartedPlaying then
2014-07-12 18:47:39 -07:00
client.reboot_core()
hasAlreadyStartedPlaying = true
else
resetAll()
end
else
startNewAdventure()
end
else
if not running then
2015-04-06 01:18:46 -07:00
Bridge.liveSplit()
2014-07-12 18:47:39 -07:00
running = true
end
choosePlayerNames()
end
else
2015-04-06 01:18:46 -07:00
local battleState = Memory.value("game", "battle")
if battleState > 0 then
if battleState == 1 then
if not inBattle then
2015-04-06 01:18:46 -07:00
Control.wildEncounter()
2014-07-12 18:47:39 -07:00
inBattle = true
end
end
local isCritical
2015-04-06 01:18:46 -07:00
local battleMenu = Memory.value("battle", "menu")
if battleMenu == 94 then
2014-07-12 18:47:39 -07:00
isCritical = false
2015-04-06 01:18:46 -07:00
elseif Memory.double("battle", "our_hp") == 0 then
if Memory.value("battle", "critical") == 1 then
2014-07-12 18:47:39 -07:00
isCritical = true
end
end
if isCritical ~= nil and isCritical ~= criticaled then
2014-07-12 18:47:39 -07:00
criticaled = isCritical
2015-04-06 01:18:46 -07:00
Strategies.criticaled = criticaled
2014-07-12 18:47:39 -07:00
end
else
inBattle = false
end
2015-04-06 01:18:46 -07:00
local currentHP = Pokemon.index(0, "hp")
-- if currentHP ~= lastHP then
2015-04-06 01:18:46 -07:00
-- Bridge.hp(currentHP, Pokemon.index(0, "max_hp"))
-- lastHP = currentHP
-- end
2015-04-06 01:18:46 -07:00
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)
2014-07-12 18:47:39 -07:00
end
elseif battleState > 0 then
2015-04-06 01:18:46 -07:00
if not Control.shouldCatch(partySize) then
Battle.automate()
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
elseif Textbox.handle() then
Walk.traverse(currentMap)
2014-07-12 18:47:39 -07:00
end
end
end
if STREAMING_MODE then
2015-04-06 01:18:46 -07:00
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
2015-04-06 01:18:46 -07:00
Paint.draw(currentMap)
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
Input.advance()
2014-07-12 18:47:39 -07:00
emu.frameadvance()
end
2015-04-06 01:18:46 -07:00
Bridge.close()