PokeBot/ai/strategies.lua

946 lines
20 KiB
Lua
Raw Normal View History

2015-04-06 01:18:46 -07:00
local Strategies = {}
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"
2014-07-12 18:47:39 -07:00
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 Bridge = require "util.bridge"
local Input = require "util.input"
local Memory = require "util.memory"
local Menu = require "util.menu"
local Player = require "util.player"
local Utils = require "util.utils"
2014-07-12 18:47:39 -07:00
2015-04-06 01:18:46 -07:00
local Inventory = require "storage.inventory"
local Pokemon = require "storage.pokemon"
2014-07-12 18:47:39 -07:00
local yellow = YELLOW
local splitNumber, splitTime = 0, 0
2015-04-06 00:50:00 -07:00
local resetting
2015-04-06 00:50:00 -07:00
local status = {tries = 0, tempDir = nil, canProgress = nil, initialized = false}
local stats = {}
2015-04-06 01:18:46 -07:00
Strategies.status = status
Strategies.stats = stats
2015-04-06 01:18:46 -07:00
Strategies.deepRun = false
2014-07-12 18:47:39 -07:00
local strategyFunctions
-- RISK/RESET
2014-07-12 18:47:39 -07:00
2015-04-06 01:18:46 -07:00
function Strategies.getTimeRequirement(name)
return Strategies.timeRequirements[name]()
end
2015-04-06 01:18:46 -07:00
function Strategies.hardReset(message, extra, wait)
2014-07-12 18:47:39 -07:00
resetting = true
2015-04-06 01:18:46 -07:00
if Strategies.seed then
if extra then
2015-04-06 01:18:46 -07:00
extra = extra.." | "..Strategies.seed
else
2015-04-06 01:18:46 -07:00
extra = Strategies.seed
end
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
Bridge.chat(message, extra)
2015-04-04 18:38:47 -07:00
if wait and INTERNAL and not STREAMING_MODE then
2015-04-06 00:50:00 -07:00
strategyFunctions.wait()
else
client.reboot_core()
2015-04-04 18:38:47 -07:00
end
2014-07-12 18:47:39 -07:00
return true
end
2015-04-06 01:18:46 -07:00
function Strategies.reset(reason, extra, wait)
local time = Utils.elapsedTime()
local resetMessage = "Reset"
if time then
resetMessage = resetMessage.." after "..time
2014-07-12 18:47:39 -07:00
end
resetMessage = " "..resetMessage.." at "..Control.areaName
2014-07-12 18:47:39 -07:00
local separator
2015-04-06 01:18:46 -07:00
if Strategies.deepRun and not Control.yolo then
2014-07-12 18:47:39 -07:00
separator = " BibleThump"
else
separator = ":"
end
resetMessage = resetMessage..separator.." "..reason
if status.tweeted then
Strategies.tweetProgress(resetMessage, true)
end
return Strategies.hardReset(resetMessage, extra, wait)
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
function Strategies.death(extra)
2014-07-12 18:47:39 -07:00
local reason
2015-04-06 01:18:46 -07:00
if Strategies.criticaled then
2014-07-12 18:47:39 -07:00
reason = "Critical'd"
2015-04-06 01:18:46 -07:00
elseif Control.yolo then
2014-07-12 18:47:39 -07:00
reason = "Yolo strats"
else
reason = "Died"
end
2015-04-06 01:18:46 -07:00
return Strategies.reset(reason, extra)
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
function Strategies.overMinute(min)
return Utils.igt() > min * 60
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
function Strategies.resetTime(timeLimit, reason, once)
if Strategies.overMinute(timeLimit) then
2014-07-12 18:47:39 -07:00
reason = "Took too long to "..reason
if RESET_FOR_TIME then
2015-04-06 01:18:46 -07:00
return Strategies.reset(reason)
2014-07-12 18:47:39 -07:00
end
if once then
2015-04-06 01:18:46 -07:00
print(reason.." "..Utils.elapsedTime())
2014-07-12 18:47:39 -07:00
end
end
end
2015-04-06 01:18:46 -07:00
function Strategies.setYolo(name)
if not RESET_FOR_TIME then
return false
end
2015-04-06 01:18:46 -07:00
local minimumTime = Strategies.getTimeRequirement(name)
local shouldYolo = Strategies.overMinute(minimumTime)
if Control.yolo ~= shouldYolo then
Control.yolo = shouldYolo
Control.setYolo(shouldYolo)
2014-07-12 18:47:39 -07:00
local prefix
2015-04-06 01:18:46 -07:00
if Control.yolo then
2014-07-12 18:47:39 -07:00
prefix = "en"
else
prefix = "dis"
end
2015-04-06 01:18:46 -07:00
print("YOLO "..prefix.."abled at "..Control.areaName)
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
return Control.yolo
2014-07-12 18:47:39 -07:00
end
2015-04-06 00:50:00 -07:00
-- HELPERS
function Strategies.tweetProgress(message, finished)
if not finished then
status.tweeted = true
message = message.." http://www.twitch.tv/thepokebot"
end
Bridge.tweet(message)
end
2015-04-06 01:18:46 -07:00
function Strategies.initialize()
if not status.initialized then
status.initialized = true
return true
end
end
2014-07-12 18:47:39 -07:00
2015-04-06 01:18:46 -07:00
function Strategies.canHealFor(damage)
local curr_hp = Pokemon.index(0, "hp")
local max_hp = Pokemon.index(0, "max_hp")
2015-04-04 18:37:48 -07:00
if max_hp - curr_hp > 3 then
local healChecks = {"full_restore", "super_potion", "potion"}
for idx,potion in ipairs(healChecks) do
2015-04-06 01:18:46 -07:00
if Inventory.contains(potion) and Utils.canPotionWith(potion, damage, curr_hp, max_hp) then
2015-04-04 18:37:48 -07:00
return potion
end
end
end
end
2015-04-06 01:18:46 -07:00
function Strategies.hasHealthFor(opponent, extra)
if not extra then
2014-07-12 18:47:39 -07:00
extra = 0
end
2015-04-06 01:18:46 -07:00
return Pokemon.index(0, "hp") + extra > Combat.healthFor(opponent)
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
function Strategies.damaged(factor)
if not factor then
2014-07-12 18:47:39 -07:00
factor = 1
end
2015-04-06 01:18:46 -07:00
return Pokemon.index(0, "hp") * factor < Pokemon.index(0, "max_hp")
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
function Strategies.opponentDamaged(factor)
if not factor then
2014-07-12 18:47:39 -07:00
factor = 1
end
2015-04-06 01:18:46 -07:00
return Memory.double("battle", "opponent_hp") * factor < Memory.double("battle", "opponent_max_hp")
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
function Strategies.buffTo(buff, defLevel)
if Battle.isActive() then
status.canProgress = true
2014-07-12 18:47:39 -07:00
local forced
2015-04-06 01:18:46 -07:00
if defLevel and Memory.double("battle", "opponent_defense") > defLevel then
2014-07-12 18:47:39 -07:00
forced = buff
end
2015-04-06 01:18:46 -07:00
Battle.automate(forced, true)
elseif status.canProgress then
2014-07-12 18:47:39 -07:00
return true
else
2015-04-06 01:18:46 -07:00
Battle.automate()
2014-07-12 18:47:39 -07:00
end
end
2015-04-06 01:18:46 -07:00
function Strategies.dodgeUp(npc, sx, sy, dodge, offset)
if not Battle.handleWild() then
2014-07-12 18:47:39 -07:00
return false
end
2015-04-06 01:18:46 -07:00
local px, py = Player.position()
if py < sy - 1 then
2014-07-12 18:47:39 -07:00
return true
end
local wx, wy = px, py
if py < sy then
2014-07-12 18:47:39 -07:00
wy = py - 1
elseif px == sx or px == dodge then
2015-04-06 01:18:46 -07:00
if px - Memory.raw(npc) == offset then
if px == sx then
2014-07-12 18:47:39 -07:00
wx = dodge
else
wx = sx
end
else
wy = py - 1
end
end
2015-04-06 01:18:46 -07:00
Walk.step(wx, wy)
2014-07-12 18:47:39 -07:00
end
local function dodgeH(options)
local left = 1
if options.left then
2014-07-12 18:47:39 -07:00
left = -1
end
2015-04-06 01:18:46 -07:00
local px, py = Player.position()
if px * left > options.sx * left + (options.dist or 1) * left then
2014-07-12 18:47:39 -07:00
return true
end
local wx, wy = px, py
if px * left > options.sx * left then
2014-07-12 18:47:39 -07:00
wx = px + 1 * left
elseif py == options.sy or py == options.dodge then
2015-04-06 01:18:46 -07:00
if py - Memory.raw(options.npc) == options.offset then
if py == options.sy then
2014-07-12 18:47:39 -07:00
wy = options.dodge
else
wy = options.sy
end
else
wx = px + 1 * left
end
end
2015-04-06 01:18:46 -07:00
Walk.step(wx, wy)
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
function Strategies.completedMenuFor(data)
local count = Inventory.count(data.item)
2015-04-06 00:50:00 -07:00
if count == 0 or count + (data.amount or 1) <= status.tries then
2014-07-12 18:47:39 -07:00
return true
end
return false
end
2015-04-06 01:18:46 -07:00
function Strategies.closeMenuFor(data)
if (not status.tempDir and not data.close) or data.chain or Menu.close() then
2014-07-12 18:47:39 -07:00
return true
end
end
2015-04-06 01:18:46 -07:00
function Strategies.useItem(data)
local main = Memory.value("menu", "main")
2015-04-06 00:50:00 -07:00
if status.tries == 0 then
2015-04-06 01:18:46 -07:00
status.tries = Inventory.count(data.item)
2015-04-06 00:50:00 -07:00
if status.tries == 0 then
2015-04-06 01:18:46 -07:00
if Strategies.closeMenuFor(data) then
2014-07-12 18:47:39 -07:00
return true
end
return false
end
end
2015-04-06 01:18:46 -07:00
if Strategies.completedMenuFor(data) then
if Strategies.closeMenuFor(data) then
2014-07-12 18:47:39 -07:00
return true
end
else
2015-04-06 01:18:46 -07:00
if Inventory.use(data.item, data.poke) then
status.tempDir = true
2014-07-12 18:47:39 -07:00
else
2015-04-06 01:18:46 -07:00
Menu.pause()
2014-07-12 18:47:39 -07:00
end
end
end
local function completedSkillFor(data)
if data.map then
2015-04-06 01:18:46 -07:00
if data.map ~= Memory.value("game", "map") then
2014-07-12 18:47:39 -07:00
return true
end
elseif data.x or data.y then
2015-04-06 01:18:46 -07:00
local px, py = Player.position()
if data.x == px or data.y == py then
2014-07-12 18:47:39 -07:00
return true
end
elseif data.done then
2015-04-06 01:18:46 -07:00
if Memory.raw(data.done) > (data.val or 0) then
2014-07-12 18:47:39 -07:00
return true
end
2015-04-06 01:18:46 -07:00
elseif status.tries > 0 and not Menu.isOpen() then
2014-07-12 18:47:39 -07:00
return true
end
return false
end
2015-04-06 01:18:46 -07:00
function Strategies.isPrepared(...)
2015-04-06 00:50:00 -07:00
if status.tries == 0 then
status.tries = {}
2014-07-12 18:47:39 -07:00
end
for i,name in ipairs(arg) do
2015-04-06 01:18:46 -07:00
local currentCount = Inventory.count(name)
if currentCount > 0 then
2015-04-06 00:50:00 -07:00
local previousCount = status.tries[name]
if previousCount == nil or currentCount == previousCount then
2014-07-12 18:47:39 -07:00
return false
end
end
end
return true
end
2015-04-06 01:18:46 -07:00
function Strategies.prepare(...)
2015-04-06 00:50:00 -07:00
if status.tries == 0 then
status.tries = {}
2014-07-12 18:47:39 -07:00
end
local item
for idx,name in ipairs(arg) do
2015-04-06 01:18:46 -07:00
local currentCount = Inventory.count(name)
local needsItem = currentCount > 0
2015-04-06 00:50:00 -07:00
local previousCount = status.tries[name]
if previousCount == nil then
2015-04-06 00:50:00 -07:00
status.tries[name] = currentCount
elseif needsItem then
needsItem = currentCount == previousCount
end
if needsItem then
item = name
break
2014-07-12 18:47:39 -07:00
end
end
if not item then
return true
end
2015-04-06 01:18:46 -07:00
if Battle.isActive() then
Inventory.use(item, nil, true)
2014-07-12 18:47:39 -07:00
else
2015-04-06 01:18:46 -07:00
Input.cancel()
2014-07-12 18:47:39 -07:00
end
end
2015-04-06 00:50:00 -07:00
-- GENERALIZED STRATEGIES
2014-07-12 18:47:39 -07:00
2015-04-06 01:18:46 -07:00
Strategies.functions = {
2014-07-12 18:47:39 -07:00
startFrames = function()
2015-04-06 01:18:46 -07:00
Strategies.frames = 0
2014-07-12 18:47:39 -07:00
return true
end,
reportFrames = function()
2015-04-06 01:18:46 -07:00
print("FR "..Strategies.frames)
local repels = Memory.value("player", "repel")
if repels > 0 then
2014-07-12 18:47:39 -07:00
print("S "..repels)
end
2015-04-06 01:18:46 -07:00
Strategies.frames = nil
2014-07-12 18:47:39 -07:00
return true
end,
split = function(data)
2015-04-06 01:18:46 -07:00
Bridge.split(data and data.finished)
if not INTERNAL then
splitNumber = splitNumber + 1
local timeDiff
2015-04-06 01:18:46 -07:00
splitTime, timeDiff = Utils.timeSince(splitTime)
if timeDiff then
2015-04-06 01:18:46 -07:00
print(splitNumber..". "..Control.areaName..": "..Utils.elapsedTime().." ("..timeDiff..")")
end
end
2014-07-12 18:47:39 -07:00
return true
end,
interact = function(data)
2015-04-06 01:18:46 -07:00
if Battle.handleWild() then
if Battle.isActive() then
2014-07-12 18:47:39 -07:00
return true
end
2015-04-06 01:18:46 -07:00
if Textbox.isActive() then
2015-04-06 00:50:00 -07:00
if status.tries > 0 then
2014-07-12 18:47:39 -07:00
return true
end
2015-04-06 00:50:00 -07:00
status.tries = status.tries - 1
2015-04-06 01:18:46 -07:00
Input.cancel()
elseif Player.interact(data.dir) then
2015-04-06 00:50:00 -07:00
status.tries = status.tries + 1
2014-07-12 18:47:39 -07:00
end
end
end,
confirm = function(data)
2015-04-06 01:18:46 -07:00
if Battle.handleWild() then
if Textbox.isActive() then
2015-04-06 00:50:00 -07:00
status.tries = status.tries + 1
2015-04-06 01:18:46 -07:00
Input.cancel(data.type or "A")
2014-07-12 18:47:39 -07:00
else
2015-04-06 00:50:00 -07:00
if status.tries > 0 then
2014-07-12 18:47:39 -07:00
return true
end
2015-04-06 01:18:46 -07:00
Player.interact(data.dir)
2014-07-12 18:47:39 -07:00
end
end
end,
item = function(data)
2015-04-06 01:18:46 -07:00
if Battle.handleWild() then
if data.full and not Inventory.isFull() then
if Strategies.closeMenuFor(data) then
2014-07-12 18:47:39 -07:00
return true
end
return false
end
2015-04-06 01:18:46 -07:00
return Strategies.useItem(data)
2014-07-12 18:47:39 -07:00
end
end,
potion = function(data)
2015-04-06 01:18:46 -07:00
local curr_hp = Pokemon.index(0, "hp")
if curr_hp == 0 then
2014-07-12 18:47:39 -07:00
return false
end
local toHP
2015-04-06 01:18:46 -07:00
if Control.yolo and data.yolo ~= nil then
2014-07-12 18:47:39 -07:00
toHP = data.yolo
else
toHP = data.hp
end
if type(toHP) == "string" then
2015-04-06 01:18:46 -07:00
toHP = Combat.healthFor(toHP)
2014-07-12 18:47:39 -07:00
end
local toHeal = toHP - curr_hp
if toHeal > 0 then
2014-07-12 18:47:39 -07:00
local toPotion
if data.forced then
2015-04-06 01:18:46 -07:00
toPotion = Inventory.contains(data.forced)
2014-07-12 18:47:39 -07:00
else
local p_first, p_second, p_third
if toHeal > 50 then
if data.full then
2014-07-12 18:47:39 -07:00
p_first = "full_restore"
else
p_first = "super_potion"
end
p_second, p_third = "super_potion", "potion"
else
if toHeal > 20 then
2014-07-12 18:47:39 -07:00
p_first, p_second = "super_potion", "potion"
else
p_first, p_second = "potion", "super_potion"
end
if data.full then
2014-07-12 18:47:39 -07:00
p_third = "full_restore"
end
end
2015-04-06 01:18:46 -07:00
toPotion = Inventory.contains(p_first, p_second, p_third)
2014-07-12 18:47:39 -07:00
end
if toPotion then
2015-04-06 01:18:46 -07:00
if Menu.pause() then
Inventory.use(toPotion)
status.tempDir = true
2014-07-12 18:47:39 -07:00
end
return false
end
2015-04-06 00:50:00 -07:00
--TODO report wanted potion
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
if Strategies.closeMenuFor(data) then
2014-07-12 18:47:39 -07:00
return true
end
end,
teach = function(data)
2015-04-06 01:18:46 -07:00
if data.full and not Inventory.isFull() then
2014-07-12 18:47:39 -07:00
return true
end
local itemName
if data.item then
2014-07-12 18:47:39 -07:00
itemName = data.item
else
itemName = data.move
end
2015-04-06 01:18:46 -07:00
if Pokemon.hasMove(data.move) then
local main = Memory.value("menu", "main")
if main == 128 then
if data.chain then
2014-07-12 18:47:39 -07:00
return true
end
elseif main < 3 then
2014-07-12 18:47:39 -07:00
return true
end
2015-04-06 01:18:46 -07:00
Input.press("B")
2014-07-12 18:47:39 -07:00
else
2015-04-06 01:18:46 -07:00
if Strategies.initialize() then
if not Inventory.contains(itemName) then
return Strategies.reset("Unable to teach move "..itemName.." to "..data.poke, nil, true)
2015-04-04 18:38:47 -07:00
end
end
2014-07-12 18:47:39 -07:00
local replacement
if data.replace then
2015-04-06 01:18:46 -07:00
replacement = Pokemon.moveIndex(data.replace, data.poke) - 1
2014-07-12 18:47:39 -07:00
else
replacement = 0
end
2015-04-06 01:18:46 -07:00
if Inventory.teach(itemName, data.poke, replacement, data.alt) then
status.tempDir = true
2014-07-12 18:47:39 -07:00
else
2015-04-06 01:18:46 -07:00
Menu.pause()
2014-07-12 18:47:39 -07:00
end
end
end,
skill = function(data)
if completedSkillFor(data) then
2015-04-06 01:18:46 -07:00
if not Textbox.isActive() then
2014-07-12 18:47:39 -07:00
return true
end
2015-04-06 01:18:46 -07:00
Input.press("B")
elseif not data.dir or Player.face(data.dir) then
if Pokemon.use(data.move) then
2015-04-06 00:50:00 -07:00
status.tries = status.tries + 1
2014-07-12 18:47:39 -07:00
else
2015-04-06 01:18:46 -07:00
Menu.pause()
2014-07-12 18:47:39 -07:00
end
end
end,
fly = function(data)
2015-04-06 01:18:46 -07:00
if Memory.value("game", "map") == data.map then
2014-07-12 18:47:39 -07:00
return true
end
local cities = {
pallet = {62, "Up"},
viridian = {63, "Up"},
lavender = {66, "Down"},
celadon = {68, "Down"},
fuchsia = {69, "Down"},
cinnabar = {70, "Down"},
}
2015-04-06 01:18:46 -07:00
local main = Memory.value("menu", "main")
if main == 228 then
2015-04-06 01:18:46 -07:00
local currentFly = Memory.raw(0x1FEF)
2014-07-12 18:47:39 -07:00
local destination = cities[data.dest]
local press
if destination[1] - currentFly == 0 then
2014-07-12 18:47:39 -07:00
press = "A"
else
press = destination[2]
end
2015-04-06 01:18:46 -07:00
Input.press(press)
elseif not Pokemon.use("fly") then
Menu.pause()
2014-07-12 18:47:39 -07:00
end
end,
bicycle = function()
2015-04-06 01:18:46 -07:00
if Memory.raw(0x1700) == 1 then
if Textbox.handle() then
2014-07-12 18:47:39 -07:00
return true
end
else
2015-04-06 01:18:46 -07:00
return Strategies.useItem({item="bicycle"})
2014-07-12 18:47:39 -07:00
end
end,
2015-04-06 00:50:00 -07:00
wait = function()
print("Please save state")
Input.press("Start", 999999999)
2015-04-06 00:50:00 -07:00
end,
emuSpeed = function(data)
-- client.speedmode = data.percent
return true
2014-07-12 18:47:39 -07:00
end,
waitToTalk = function()
2015-04-06 01:18:46 -07:00
if Battle.isActive() then
status.canProgress = false
2015-04-06 01:18:46 -07:00
Battle.automate()
elseif Textbox.isActive() then
status.canProgress = true
2015-04-06 01:18:46 -07:00
Input.cancel()
elseif status.canProgress then
2014-07-12 18:47:39 -07:00
return true
end
end,
waitToPause = function()
2015-04-06 01:18:46 -07:00
local main = Memory.value("menu", "main")
if main == 128 then
if status.canProgress then
2014-07-12 18:47:39 -07:00
return true
end
2015-04-06 01:18:46 -07:00
elseif Battle.isActive() then
status.canProgress = false
2015-04-06 01:18:46 -07:00
Battle.automate()
elseif main == 123 then
status.canProgress = true
2015-04-06 01:18:46 -07:00
Input.press("B")
elseif Textbox.handle() then
Input.press("Start", 2)
2014-07-12 18:47:39 -07:00
end
end,
waitToFight = function(data)
2015-04-06 01:18:46 -07:00
if Battle.isActive() then
status.canProgress = true
2015-04-06 01:18:46 -07:00
Battle.automate()
elseif status.canProgress then
2014-07-12 18:47:39 -07:00
return true
2015-04-06 01:18:46 -07:00
elseif Textbox.handle() then
if data.dir then
2015-04-06 01:18:46 -07:00
Player.interact(data.dir)
2014-07-12 18:47:39 -07:00
else
2015-04-06 01:18:46 -07:00
Input.cancel()
2014-07-12 18:47:39 -07:00
end
end
end,
allowDeath = function(data)
2015-04-06 01:18:46 -07:00
Control.canDie(data.on)
2014-07-12 18:47:39 -07:00
return true
end,
2015-04-07 04:58:18 -07:00
leer = function(data)
local bm = Combat.bestMove()
if not bm or bm.minTurns < 3 then
if Battle.isActive() then
status.canProgress = true
elseif status.canProgress then
return true
end
Battle.automate()
return false
end
local opp = Battle.opponent()
local defLimit = 9001
for i,poke in ipairs(data) do
if opp == poke[1] then
local minimumAttack = poke[3]
if not minimumAttack or stats.nidoran.attack > minimumAttack then
2015-04-07 04:58:18 -07:00
defLimit = poke[2]
end
break
end
end
return Strategies.buffTo("leer", defLimit)
end,
2015-04-06 00:50:00 -07:00
-- ROUTE
2014-07-12 18:47:39 -07:00
2015-04-07 04:58:18 -07:00
swapNidoran = function()
local main = Memory.value("menu", "main")
local nidoranIndex = Pokemon.indexOf("nidoran")
if nidoranIndex == 0 then
if Menu.close() then
return true
end
elseif Menu.pause() then
if yellow then
if Inventory.contains("potion") and Pokemon.info("nidoran", "hp") < 15 then
Inventory.use("potion", "nidoran")
return false
end
else
if Pokemon.info("squirtle", "status") > 0 then
Inventory.use("antidote", "squirtle")
return false
end
if Inventory.contains("potion") and Pokemon.info("squirtle", "hp") < 15 then
Inventory.use("potion", "squirtle")
return false
end
end
local column = Menu.getCol()
if main == 128 then
if column == 11 then
Menu.select(1, true)
elseif column == 12 then
Menu.select(1, true)
else
Input.press("B")
end
elseif main == Menu.pokemon then --TODO check loop
if Memory.value("menu", "selection_mode") == 1 then
Menu.select(nidoranIndex, true)
else
Menu.select(0, true)
end
else
Input.press("B")
end
end
end,
swapHornAttack = function()
if Pokemon.battleMove("horn_attack") == 1 then
return true
end
Battle.swapMove(1, 3)
end,
2014-07-12 18:47:39 -07:00
dodgePalletBoy = function()
2015-04-06 01:18:46 -07:00
return Strategies.dodgeUp(0x0223, 14, 14, 15, 7)
2014-07-12 18:47:39 -07:00
end,
2015-04-07 04:58:18 -07:00
evolveNidorino = function()
if Pokemon.inParty("nidorino") then
Bridge.caught("nidorino")
return true
end
if Battle.isActive() then
status.tries = 0
status.canProgress = true
if Memory.double("battle", "opponent_hp") == 0 then
Input.press("A")
else
Battle.automate()
end
elseif status.tries > 3600 then
print("Broke from Nidorino on tries")
return true
else
if status.canProgress then
status.tries = status.tries + 1
end
Input.press("A")
end
end,
catchFlierBackup = function()
if Strategies.initialize() then
Control.canDie(true)
end
if not Control.canCatch() then
return true
end
local caught = Pokemon.inParty("pidgey", "spearow")
if Battle.isActive() then
if Memory.double("battle", "our_hp") == 0 then
if Pokemon.info("squirtle", "hp") == 0 then
Control.canDie(false)
elseif Utils.onPokemonSelect(Memory.value("battle", "menu")) then
Menu.select(Pokemon.indexOf("squirtle"), true)
else
Input.press("A")
end
else
Battle.handle()
end
else
local birdPath
local px, py = Player.position()
if caught then
if px > 33 then
return true
end
local startY = 9
if px > 28 then
startY = py
end
birdPath = {{32,startY}, {32,11}, {34,11}}
elseif px == 37 then
if py == 10 then
py = 11
else
py = 10
end
Walk.step(px, py)
else
birdPath = {{32,10}, {32,11}, {34,11}, {34,10}, {37,10}}
end
if birdPath then
Walk.custom(birdPath)
end
end
end,
evolveNidoking = function(data)
if Battle.handleWild() then
local usedMoonStone = not Inventory.contains("moon_stone")
2015-04-07 04:58:18 -07:00
if Strategies.initialize() then
if usedMoonStone then
2015-04-07 04:58:18 -07:00
return true
end
if data.early then
if not Control.getMoonExp then
return true
end
if data.poke then
if stats.nidoran.attack > 15 or not Pokemon.inParty(data.poke) then
return true
end
end
if data.exp and Pokemon.getExp() > data.exp then
return true
end
2015-04-07 04:58:18 -07:00
end
end
if usedMoonStone then
2015-04-07 04:58:18 -07:00
if not status.canProgress then
Bridge.caught("nidoking")
status.canProgress = true
end
if Menu.close() then
return true
end
elseif not Inventory.use("moon_stone") then
Menu.pause()
end
end
end,
2015-04-06 00:50:00 -07:00
helix = function()
2015-04-06 01:18:46 -07:00
if Battle.handleWild() then
if Inventory.contains("helix_fossil") then
return true
end
2015-04-06 01:18:46 -07:00
Player.interact("Up")
2014-07-12 18:47:39 -07:00
end
end,
2015-04-07 04:58:18 -07:00
reportMtMoon = function()
if Battle.pp("horn_attack") == 0 then
print("ERR: Ran out of Horn Attacks")
end
if Control.moonEncounters then
local catchPokemon = yellow and "sandshrew" or "paras"
local capsName = Utils.capitalize(catchPokemon)
local parasStatus
local conjunction = "but"
local goodEncounters = Control.moonEncounters < 10
local catchDescription
if Pokemon.inParty(catchPokemon) then
catchDescription = catchPokemon
if goodEncounters then
conjunction = "and"
end
parasStatus = "we found a "..capsName.."!"
else
catchDescription = "no_"..catchPokemon
if not goodEncounters then
conjunction = "and"
end
parasStatus = "we didn't find a "..capsName.." :("
end
Bridge.caught(catchDescription)
Bridge.chat(Control.moonEncounters.." Moon encounters, "..conjunction.." "..parasStatus)
Control.moonEncounters = nil
end
local timeLimit = Strategies.getTimeRequirement("mt_moon")
Strategies.resetTime(timeLimit, "complete Mt. Moon", true)
return true
end,
2015-04-06 00:50:00 -07:00
dodgeCerulean = function()
return dodgeH{
npc = 0x0242,
sx = 14, sy = 18,
dodge = 19,
offset = 10,
dist = 4
}
end,
2015-04-06 00:50:00 -07:00
dodgeCeruleanLeft = function()
return dodgeH{
npc = 0x0242,
sx = 16, sy = 18,
dodge = 17,
offset = 10,
dist = -7,
left = true
}
2014-07-12 18:47:39 -07:00
end,
2015-04-06 00:50:00 -07:00
playPokeflute = function()
2015-04-06 01:18:46 -07:00
if Battle.isActive() then
2015-04-06 00:50:00 -07:00
return true
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
if Memory.value("battle", "menu") == 95 then
Input.press("A")
elseif Menu.pause() then
Inventory.use("pokeflute")
2014-07-12 18:47:39 -07:00
end
end,
2015-04-06 00:50:00 -07:00
push = function(data)
local pos
if data.dir == "Up" or data.dir == "Down" then
pos = data.y
else
pos = data.x
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
local newP = Memory.raw(pos)
2015-04-06 00:50:00 -07:00
if status.tries == 0 then
status.tries = {start=newP}
elseif status.tries.start ~= newP then
2014-07-12 18:47:39 -07:00
return true
end
2015-04-06 01:18:46 -07:00
Input.press(data.dir, 0)
2014-07-12 18:47:39 -07:00
end,
2015-04-06 00:50:00 -07:00
}
2014-07-12 18:47:39 -07:00
2015-04-06 01:18:46 -07:00
strategyFunctions = Strategies.functions
2014-07-12 18:47:39 -07:00
2015-04-06 01:18:46 -07:00
function Strategies.execute(data)
if strategyFunctions[data.s](data) then
2015-04-06 00:50:00 -07:00
status = {tries=0}
2015-04-06 02:19:25 -07:00
Strategies.status = status
Strategies.completeGameStrategy()
-- print(data.s)
if resetting then
2014-07-12 18:47:39 -07:00
return nil
end
return true
end
return false
end
2015-04-06 01:18:46 -07:00
function Strategies.init(midGame)
if not STREAMING_MODE then
2015-04-06 01:18:46 -07:00
splitTime = Utils.timeSince(0)
2015-01-19 17:11:52 -08:00
end
if midGame then
2015-04-06 01:18:46 -07:00
Combat.factorPP(true)
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
Strategies.initGame(midGame)
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
function Strategies.softReset()
2015-04-06 02:19:25 -07:00
status = {tries=0}
Strategies.status = status
Strategies.stats = {}
splitNumber, splitTime = 0, 0
2014-07-12 18:47:39 -07:00
resetting = nil
Strategies.deepRun = false
2015-04-06 01:18:46 -07:00
Strategies.resetGame()
2014-07-12 18:47:39 -07:00
end
2015-04-06 01:18:46 -07:00
return Strategies