2015-03-28 17:16:04 -07:00
-- SETTINGS
2014-07-12 18:47:39 -07:00
2015-01-19 17:08:17 -08:00
GAME_NAME = " red " -- Only currently supported option
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
2015-01-19 17:08:17 -08: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
2015-03-28 17:16:04 -07:00
-- START CODE (hard hats on)
2014-07-12 18:47:39 -07:00
local START_WAIT = 99
2015-04-01 10:45:29 -07:00
local VERSION = " 1.2 "
2014-07-12 18:47:39 -07:00
2015-03-28 12:47:01 -07:00
YELLOW = GAME_NAME == " yellow "
INTERNAL = false
2014-07-12 18:47:39 -07:00
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.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 pokemon = require " storage.pokemon "
local hasAlreadyStartedPlaying = false
local inBattle , oldSecs
local running = true
local previousPartySize = 0
local lastHP
local criticaled = false
local function startNewAdventure ( )
local startMenu , withBattleStyle
2015-03-30 15:29:00 -07:00
if YELLOW then
2014-07-12 18:47:39 -07:00
startMenu = memory.raw ( 0x0F95 ) == 0
withBattleStyle = " battle_style "
else
startMenu = memory.value ( " player " , " name " ) ~= 0
end
2015-03-30 15:29:00 -07:00
if startMenu and menu.getCol ( ) ~= 0 then
if settings.set ( " text_speed " , " battle_animation " , withBattleStyle ) then
2014-07-12 18:47:39 -07:00
menu.select ( 0 )
end
2015-03-30 15:29:00 -07:00
elseif math.random ( 0 , START_WAIT ) == 0 then
2014-07-12 18:47:39 -07:00
input.press ( " Start " )
end
end
local function choosePlayerNames ( )
local name
2015-03-30 15:29:00 -07:00
if memory.value ( " player " , " name2 " ) == 80 then
2015-01-19 17:08:17 -08:00
name = " E "
2014-07-12 18:47:39 -07:00
else
name = " B "
end
textbox.name ( name , true )
end
local function pollForResponse ( )
local response = bridge.process ( )
2015-03-30 15:29:00 -07:00
if response then
2014-07-12 18:47:39 -07:00
bridge.polling = false
textbox.setName ( tonumber ( response ) )
end
end
local function resetAll ( )
strategies.softReset ( )
combat.reset ( )
control.reset ( )
walk.reset ( )
paint.reset ( )
bridge.reset ( )
oldSecs = 0
running = false
previousPartySize = 0
-- client.speedmode = 200
2015-01-19 17:08:17 -08:00
2015-03-30 15:29:00 -07:00
if CUSTOM_SEED then
2014-07-12 18:47:39 -07:00
strategies.seed = CUSTOM_SEED
print ( " RUNNING WITH A FIXED SEED ( " .. strategies.seed .. " ), every run will play out identically! " )
else
strategies.seed = os.time ( )
end
math.randomseed ( strategies.seed )
end
-- Execute
print ( " Welcome to PokeBot " .. GAME_NAME .. " version " .. VERSION )
2015-01-19 17:08:17 -08:00
STREAMING_MODE = not walk.init ( )
if STREAMING_MODE then
RESET_FOR_TIME = true
end
-- STREAMING_MODE = false --TODO disable
2015-03-30 15:29:00 -07:00
if CUSTOM_SEED then
2014-07-12 18:47:39 -07:00
client.reboot_core ( )
else
hasAlreadyStartedPlaying = utils.ingame ( )
end
strategies.init ( hasAlreadyStartedPlaying )
2015-03-30 15:29:00 -07:00
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
2015-03-30 15:29:00 -07:00
if STREAMING_MODE then
2014-07-12 18:47:39 -07:00
bridge.init ( )
else
input.setDebug ( true )
end
2015-01-19 17:08:17 -08:00
-- Main loop
2014-07-12 18:47:39 -07:00
local previousMap
while true do
local currentMap = memory.value ( " game " , " map " )
2015-03-30 15:29:00 -07:00
if currentMap ~= previousMap then
2014-07-12 18:47:39 -07:00
input.clear ( )
previousMap = currentMap
end
2015-03-30 15:29:00 -07:00
if strategies.frames then
if memory.value ( " game " , " battle " ) == 0 then
2015-01-19 17:08:17 -08:00
strategies.frames = strategies.frames + 1
end
gui.text ( 0 , 80 , strategies.frames )
end
2015-03-30 15:29:00 -07:00
if bridge.polling then
2015-01-19 17:08:17 -08:00
pollForResponse ( )
end
2015-03-30 15:29:00 -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
2015-03-30 15:29:00 -07:00
if not running then
2014-07-12 18:47:39 -07:00
bridge.liveSplit ( )
running = true
end
choosePlayerNames ( )
end
else
local battleState = memory.value ( " game " , " battle " )
2015-03-30 15:29:00 -07:00
if battleState > 0 then
if battleState == 1 then
if not inBattle then
2014-07-12 18:47:39 -07:00
control.wildEncounter ( )
2015-03-30 15:29:00 -07:00
if strategies.moonEncounters then
2014-07-12 18:47:39 -07:00
strategies.moonEncounters = strategies.moonEncounters + 1
end
inBattle = true
end
end
local isCritical
local battleMenu = memory.value ( " battle " , " menu " )
2015-03-30 15:29:00 -07:00
if battleMenu == 94 then
2014-07-12 18:47:39 -07:00
isCritical = false
2015-03-30 15:29:00 -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
2015-03-30 15:29:00 -07:00
if isCritical ~= nil and isCritical ~= criticaled then
2014-07-12 18:47:39 -07:00
criticaled = isCritical
strategies.criticaled = criticaled
end
else
inBattle = false
end
local currentHP = pokemon.index ( 0 , " hp " )
2015-03-30 15:29:00 -07:00
-- if currentHP ~= lastHP then
2015-01-19 17:08:17 -08:00
-- bridge.hp(currentHP, pokemon.index(0, "max_hp"))
-- lastHP = currentHP
-- end
2015-03-30 15:29:00 -07:00
if currentHP == 0 and not control.canDie ( ) and pokemon.index ( 0 ) > 0 then
2014-07-12 18:47:39 -07:00
strategies.death ( currentMap )
2015-03-30 15:29:00 -07:00
elseif walk.strategy then
if strategies.execute ( walk.strategy ) then
2014-07-12 18:47:39 -07:00
walk.traverse ( currentMap )
end
2015-03-30 15:29:00 -07:00
elseif battleState > 0 then
if not control.shouldCatch ( partySize ) then
2014-07-12 18:47:39 -07:00
battle.automate ( )
end
2015-03-30 15:29:00 -07:00
elseif textbox.handle ( ) then
2014-07-12 18:47:39 -07:00
walk.traverse ( currentMap )
end
end
end
2015-03-30 15:29:00 -07:00
if STREAMING_MODE then
2015-01-19 17:08:17 -08:00
local newSecs = memory.raw ( 0xDA44 )
2015-03-30 15:29:00 -07:00
if newSecs ~= oldSecs and ( newSecs > 0 or memory.raw ( 0xDA45 ) > 0 ) then
2015-03-30 14:46:37 -07:00
bridge.time ( utils.elapsedTime ( ) )
2015-01-19 17:08:17 -08:00
oldSecs = newSecs
end
2015-03-30 15:29:00 -07:00
elseif PAINT_ON then
2014-07-12 18:47:39 -07:00
paint.draw ( currentMap )
end
input.advance ( )
emu.frameadvance ( )
end
bridge.close ( )