2015-04-06 01:18:46 -07:00
-- OPTIONS
2014-07-12 18:47:39 -07:00
2015-04-02 10:42:15 -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
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
2015-04-04 20:38:38 -07:00
VERSION = " 1.3 "
2015-04-02 10:42:15 -07:00
GAME_NAME = " red "
2015-03-28 12:47:01 -07:00
YELLOW = GAME_NAME == " yellow "
INTERNAL = false
2015-04-04 19:02:46 -07:00
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
2015-03-30 15:29:00 -07:00
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
2015-03-30 15:29:00 -07:00
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
2015-01-19 17:08:17 -08:00
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 ( )
2015-03-30 15:29:00 -07:00
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
2015-01-19 17:08:17 -08:00
2015-03-30 15:29:00 -07:00
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 ( )
2015-04-03 22:38:48 -07:00
if INTERNAL and STREAMING_MODE then
2015-01-19 17:08:17 -08:00
RESET_FOR_TIME = true
end
2015-04-03 22:38:48 -07:00
2015-03-30 15:29:00 -07:00
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 )
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
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
2015-01-19 17:08:17 -08:00
-- 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 " )
2015-03-30 15:29:00 -07:00
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
2015-01-19 17:08:17 -08:00
end
2015-04-06 01:18:46 -07:00
gui.text ( 0 , 80 , Strategies.frames )
2015-01-19 17:08:17 -08:00
end
2015-04-06 01:18:46 -07:00
if Bridge.polling then
2015-01-19 17:08:17 -08:00
pollForResponse ( )
end
2015-04-06 01:18:46 -07:00
if not Input.update ( ) then
if not Utils.ingame ( ) then
2015-03-30 15:29:00 -07:00
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
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 " )
2015-03-30 15:29:00 -07:00
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 " )
2015-03-30 15:29:00 -07:00
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
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
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 " )
2015-03-30 15:29:00 -07:00
-- if currentHP ~= lastHP then
2015-04-06 01:18:46 -07:00
-- Bridge.hp(currentHP, Pokemon.index(0, "max_hp"))
2015-01-19 17:08:17 -08:00
-- 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
2015-03-30 15:29:00 -07:00
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
2015-03-30 15:29:00 -07:00
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 ( ) )
2015-01-19 17:08:17 -08:00
oldSecs = newSecs
end
2015-03-30 15:29:00 -07:00
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 ( )