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-03-28 12:47:01 -07:00
INTERNAL = false
2015-04-06 17:17:00 -07:00
YELLOW = memory.getcurrentmemorydomainsize ( ) > 30000
GAME_NAME = YELLOW and " yellow " or " red "
2015-03-28 12:47:01 -07:00
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
2015-04-07 19:06:29 -07:00
-- GLOBAL
2014-07-12 18:47:39 -07:00
2015-04-07 19:06:29 -07:00
function p ( ... )
local string
if # arg == 0 then
string = arg [ 0 ]
2014-07-12 18:47:39 -07:00
else
2015-04-07 19:06:29 -07:00
string = " "
for i , str in ipairs ( arg ) do
if str == true then
string = string .. " \n "
else
string = string .. str .. " "
end
end
2014-07-12 18:47:39 -07:00
end
2015-04-07 19:06:29 -07:00
print ( string )
2014-07-12 18:47:39 -07:00
end
2015-04-07 19:06:29 -07:00
-- HELPERS
2014-07-12 18:47:39 -07:00
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
2015-04-07 19:06:29 -07:00
p ( " RUNNING WITH A FIXED SEED ( " .. Strategies.seed .. " ), every run will play out identically! " , true )
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-07 19:06:29 -07:00
p ( " Welcome to PokeBot " .. GAME_NAME .. " version " .. VERSION , true )
2015-04-06 01:18:46 -07:00
Control.init ( )
2014-07-12 18:47:39 -07:00
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
2015-04-07 19:06:29 -07:00
p ( " 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. " , true )
2014-07-12 18:47:39 -07:00
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-07 19:06:29 -07:00
Utils.drawText ( 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-04-07 19:06:29 -07:00
Settings.pollForResponse ( )
2015-01-19 17:08:17 -08:00
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
2015-04-08 01:51:38 -07:00
Settings.startNewAdventure ( START_WAIT )
2014-07-12 18:47:39 -07:00
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
2015-04-07 19:06:29 -07:00
Settings.choosePlayerNames ( )
2014-07-12 18:47:39 -07:00
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-08 01:51:38 -07:00
local curr_hp = Pokemon.index ( 0 , " hp " )
-- if curr_hp ~= lastHP then
-- Bridge.hp(curr_hp, Pokemon.index(0, "max_hp"))
-- lastHP = curr_hp
2015-01-19 17:08:17 -08:00
-- end
2015-04-08 01:51:38 -07:00
if curr_hp == 0 and not Control.canDie ( ) and Pokemon.index ( 0 ) > 0 then
2015-04-06 01:18:46 -07:00
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 ( )