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-01-19 17:08:17 -08:00
local VERSION = " 1.1 "
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
if ( YELLOW ) then
startMenu = memory.raw ( 0x0F95 ) == 0
withBattleStyle = " battle_style "
else
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 )
end
elseif ( math.random ( 0 , START_WAIT ) == 0 ) then
input.press ( " Start " )
end
end
local function choosePlayerNames ( )
local name
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 ( )
if ( response ) then
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
2014-07-12 18:47:39 -07:00
if ( CUSTOM_SEED ) then
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
2014-07-12 18:47:39 -07:00
if ( CUSTOM_SEED ) then
client.reboot_core ( )
else
hasAlreadyStartedPlaying = utils.ingame ( )
end
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
2015-01-19 17:08:17 -08: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 " )
if ( currentMap ~= previousMap ) then
input.clear ( )
previousMap = currentMap
end
2015-01-19 17:08:17 -08:00
if ( strategies.frames ) then
if ( memory.value ( " game " , " battle " ) == 0 ) then
strategies.frames = strategies.frames + 1
end
gui.text ( 0 , 80 , strategies.frames )
end
if ( bridge.polling ) then
pollForResponse ( )
end
2014-07-12 18:47:39 -07:00
if ( not input.update ( ) ) then
if ( not utils.ingame ( ) ) then
if ( currentMap == 0 ) then
if ( running ) then
if ( not hasAlreadyStartedPlaying ) then
client.reboot_core ( )
hasAlreadyStartedPlaying = true
else
resetAll ( )
end
else
startNewAdventure ( )
end
else
if ( not running ) then
bridge.liveSplit ( )
running = true
end
choosePlayerNames ( )
end
else
local battleState = memory.value ( " game " , " battle " )
if ( battleState > 0 ) then
if ( battleState == 1 ) then
if ( not inBattle ) then
control.wildEncounter ( )
if ( strategies.moonEncounters ) then
strategies.moonEncounters = strategies.moonEncounters + 1
end
inBattle = true
end
end
local isCritical
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
isCritical = true
end
end
if ( isCritical ~= nil and isCritical ~= criticaled ) then
criticaled = isCritical
strategies.criticaled = criticaled
end
else
inBattle = false
end
local currentHP = pokemon.index ( 0 , " hp " )
2015-01-19 17:08:17 -08:00
-- if (currentHP ~= lastHP) then
-- bridge.hp(currentHP, pokemon.index(0, "max_hp"))
-- lastHP = currentHP
-- end
2014-07-12 18:47:39 -07:00
if ( currentHP == 0 and not strategies.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 ( )
end
elseif ( textbox.handle ( ) ) then
walk.traverse ( currentMap )
end
end
end
2015-01-19 17:08:17 -08:00
if ( STREAMING_MODE ) then
local newSecs = memory.raw ( 0xDA44 )
if ( newSecs ~= oldSecs and ( newSecs > 0 or memory.raw ( 0xDA45 ) > 0 ) ) then
bridge.time ( paint.elapsedTime ( ) )
oldSecs = newSecs
end
elseif ( PAINT_ON ) then
2014-07-12 18:47:39 -07:00
paint.draw ( currentMap )
end
input.advance ( )
emu.frameadvance ( )
end
bridge.close ( )