2014-07-12 18:47:39 -07:00
|
|
|
local strategies = {}
|
|
|
|
|
|
|
|
local combat = require "ai.combat"
|
|
|
|
local control = require "ai.control"
|
|
|
|
|
|
|
|
local battle = require "action.battle"
|
|
|
|
local shop = require "action.shop"
|
|
|
|
local textbox = require "action.textbox"
|
|
|
|
local walk = require "action.walk"
|
|
|
|
|
|
|
|
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 player = require "util.player"
|
|
|
|
local utils = require "util.utils"
|
|
|
|
|
|
|
|
local inventory = require "storage.inventory"
|
|
|
|
local pokemon = require "storage.pokemon"
|
|
|
|
|
|
|
|
local tries = 0
|
|
|
|
local tempDir, canProgress, initialized
|
|
|
|
local areaName
|
|
|
|
local nidoAttack, nidoSpeed, nidoSpecial = 0, 0, 0
|
|
|
|
local squirtleAtt, squirtleDef, squirtleSpd, squirtleScl
|
|
|
|
local deepRun, resetting
|
2015-01-19 17:11:52 -08:00
|
|
|
local level4Nidoran = true -- 57 vs 96 (d39)
|
|
|
|
local yolo, riskGiovanni, maxEtherSkip
|
|
|
|
|
2015-03-28 17:16:04 -07:00
|
|
|
-- TIME CONSTRAINTS
|
2014-07-12 18:47:39 -07:00
|
|
|
|
|
|
|
local timeRequirements = {
|
2015-03-28 17:16:04 -07:00
|
|
|
|
|
|
|
nidoran = function()
|
|
|
|
local timeLimit = 6.25
|
|
|
|
if (pokemon.inParty("spearow")) then
|
|
|
|
timeLimit = timeLimit + 0.67
|
|
|
|
end
|
|
|
|
return timeLimit
|
|
|
|
end,
|
|
|
|
|
|
|
|
mt_moon = function()
|
|
|
|
local timeLimit = 27
|
|
|
|
if (nidoAttack > 15 and nidoSpeed > 14) then
|
|
|
|
timeLimit = timeLimit + 0.25
|
|
|
|
end
|
|
|
|
if (pokemon.inParty("paras")) then
|
|
|
|
timeLimit = timeLimit + 0.75
|
|
|
|
end
|
|
|
|
return timeLimit
|
|
|
|
end,
|
|
|
|
|
2014-07-12 18:47:39 -07:00
|
|
|
mankey = function()
|
|
|
|
local timeLimit = 33
|
|
|
|
if (pokemon.inParty("paras")) then
|
|
|
|
timeLimit = timeLimit + 0.75
|
|
|
|
end
|
|
|
|
return timeLimit
|
|
|
|
end,
|
|
|
|
|
|
|
|
goldeen = function()
|
|
|
|
local timeLimit = 38
|
|
|
|
if (pokemon.inParty("paras")) then
|
|
|
|
timeLimit = timeLimit + 0.75
|
|
|
|
end
|
|
|
|
return timeLimit
|
|
|
|
end,
|
|
|
|
|
|
|
|
misty = function()
|
|
|
|
local timeLimit = 40
|
|
|
|
if (pokemon.inParty("paras")) then
|
|
|
|
timeLimit = timeLimit + 0.75
|
|
|
|
end
|
|
|
|
return timeLimit
|
|
|
|
end,
|
|
|
|
|
|
|
|
vermilion = function()
|
|
|
|
return 44.25
|
|
|
|
end,
|
|
|
|
|
|
|
|
trash = function()
|
|
|
|
local timeLimit = 47
|
|
|
|
if (nidoSpecial > 44) then
|
|
|
|
timeLimit = timeLimit + 0.25
|
|
|
|
end
|
|
|
|
if (nidoAttack > 53) then
|
|
|
|
timeLimit = timeLimit + 0.25
|
|
|
|
end
|
|
|
|
if (nidoAttack >= 54 and nidoSpecial >= 45) then
|
|
|
|
timeLimit = timeLimit + 0.25
|
|
|
|
end
|
|
|
|
return timeLimit
|
|
|
|
end,
|
|
|
|
|
|
|
|
safari_carbos = function()
|
|
|
|
return 70.5
|
|
|
|
end,
|
|
|
|
|
|
|
|
e4center = function()
|
|
|
|
return 102
|
|
|
|
end,
|
|
|
|
|
|
|
|
blue = function()
|
|
|
|
return 108.2
|
|
|
|
end,
|
|
|
|
}
|
|
|
|
|
2015-03-28 17:16:04 -07:00
|
|
|
-- RISK/RESET
|
2014-07-12 18:47:39 -07:00
|
|
|
|
|
|
|
local function hardReset(message, extra)
|
|
|
|
resetting = true
|
|
|
|
if (extra) then
|
|
|
|
message = message.." | "..extra
|
|
|
|
end
|
|
|
|
if (strategies.seed) then
|
|
|
|
message = message.." | "..strategies.seed
|
|
|
|
end
|
|
|
|
bridge.chat(message)
|
|
|
|
client.reboot_core()
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
local function reset(reason, extra)
|
|
|
|
local time = paint.elapsedTime()
|
|
|
|
local resetString = "Reset"
|
|
|
|
if (time) then
|
|
|
|
resetString = resetString.." after "..time
|
|
|
|
end
|
|
|
|
if (areaName) then
|
|
|
|
resetString = " "..resetString.." at "..areaName
|
|
|
|
end
|
|
|
|
local separator
|
|
|
|
if (deepRun and not yolo) then
|
|
|
|
separator = " BibleThump"
|
|
|
|
else
|
|
|
|
separator = ":"
|
|
|
|
end
|
|
|
|
resetString = resetString..separator.." "..reason
|
|
|
|
return hardReset(resetString, extra)
|
|
|
|
end
|
|
|
|
strategies.reset = reset
|
|
|
|
|
|
|
|
local function resetDeath(extra)
|
|
|
|
local reason
|
|
|
|
if (strategies.criticaled) then
|
|
|
|
reason = "Critical'd"
|
|
|
|
elseif (yolo) then
|
|
|
|
reason = "Yolo strats"
|
|
|
|
else
|
|
|
|
reason = "Died"
|
|
|
|
end
|
|
|
|
return reset(reason, extra)
|
|
|
|
end
|
|
|
|
strategies.death = resetDeath
|
|
|
|
|
|
|
|
local function overMinute(min)
|
|
|
|
return utils.igt() > min * 60
|
|
|
|
end
|
|
|
|
|
|
|
|
local function resetTime(timeLimit, reason, once)
|
|
|
|
if (overMinute(timeLimit)) then
|
|
|
|
reason = "Took too long to "..reason
|
|
|
|
if (RESET_FOR_TIME) then
|
|
|
|
return reset(reason)
|
|
|
|
end
|
|
|
|
if (once) then
|
|
|
|
print(reason.." "..paint.elapsedTime())
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local function getTimeRequirement(name)
|
|
|
|
return timeRequirements[name]()
|
|
|
|
end
|
|
|
|
|
|
|
|
local function setYolo(name)
|
|
|
|
local minimumTime = getTimeRequirement(name)
|
|
|
|
local shouldYolo = overMinute(minimumTime)
|
|
|
|
if (yolo ~= shouldYolo) then
|
|
|
|
yolo = shouldYolo
|
|
|
|
control.setYolo(shouldYolo)
|
|
|
|
local prefix
|
|
|
|
if (yolo) then
|
|
|
|
prefix = "en"
|
|
|
|
else
|
|
|
|
prefix = "dis"
|
|
|
|
end
|
|
|
|
if (areaName) then
|
|
|
|
print("YOLO "..prefix.."abled at "..areaName)
|
|
|
|
else
|
|
|
|
print("YOLO "..prefix.."abled")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return yolo
|
|
|
|
end
|
|
|
|
|
2015-03-28 17:16:04 -07:00
|
|
|
-- PRIVATE
|
|
|
|
|
|
|
|
local function initialize()
|
|
|
|
if (not initialized) then
|
|
|
|
initialized = true
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
2014-07-12 18:47:39 -07:00
|
|
|
|
|
|
|
local function hasHealthFor(opponent, extra)
|
|
|
|
if (not extra) then
|
|
|
|
extra = 0
|
|
|
|
end
|
|
|
|
return pokemon.index(0, "hp") + extra > combat.healthFor(opponent)
|
|
|
|
end
|
|
|
|
|
|
|
|
local function damaged(factor)
|
|
|
|
if (not factor) then
|
|
|
|
factor = 1
|
|
|
|
end
|
|
|
|
return pokemon.index(0, "hp") * factor < pokemon.index(0, "max_hp")
|
|
|
|
end
|
|
|
|
|
|
|
|
local function opponentDamaged(factor)
|
|
|
|
if (not factor) then
|
|
|
|
factor = 1
|
|
|
|
end
|
|
|
|
return memory.double("battle", "opponent_hp") * factor < memory.double("battle", "opponent_max_hp")
|
|
|
|
end
|
|
|
|
|
|
|
|
local function redHP()
|
|
|
|
return math.ceil(pokemon.index(0, "max_hp") * 0.2)
|
|
|
|
end
|
|
|
|
|
|
|
|
local function buffTo(buff, defLevel)
|
|
|
|
if (battle.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
local forced
|
|
|
|
if (memory.double("battle", "opponent_defense") > defLevel) then
|
|
|
|
forced = buff
|
|
|
|
end
|
|
|
|
battle.automate(forced, true)
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
battle.automate()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local function dodgeUp(npc, sx, sy, dodge, offset)
|
|
|
|
if (not battle.handleWild()) then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
local px, py = player.position()
|
|
|
|
if (py < sy - 1) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
local wx, wy = px, py
|
|
|
|
if (py < sy) then
|
|
|
|
wy = py - 1
|
|
|
|
elseif (px == sx or px == dodge) then
|
|
|
|
if (px - memory.raw(npc) == offset) then
|
|
|
|
if (px == sx) then
|
|
|
|
wx = dodge
|
|
|
|
else
|
|
|
|
wx = sx
|
|
|
|
end
|
|
|
|
else
|
|
|
|
wy = py - 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
walk.step(wx, wy)
|
|
|
|
end
|
|
|
|
|
|
|
|
local function dodgeH(options)
|
|
|
|
local left = 1
|
|
|
|
if (options.left) then
|
|
|
|
left = -1
|
|
|
|
end
|
|
|
|
local px, py = player.position()
|
|
|
|
if (px * left > options.sx * left + (options.dist or 1) * left) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
local wx, wy = px, py
|
|
|
|
if (px * left > options.sx * left) then
|
|
|
|
wx = px + 1 * left
|
|
|
|
elseif (py == options.sy or py == options.dodge) then
|
|
|
|
if (py - memory.raw(options.npc) == options.offset) then
|
|
|
|
if (py == options.sy) then
|
|
|
|
wy = options.dodge
|
|
|
|
else
|
|
|
|
wy = options.sy
|
|
|
|
end
|
|
|
|
else
|
|
|
|
wx = px + 1 * left
|
|
|
|
end
|
|
|
|
end
|
|
|
|
walk.step(wx, wy)
|
|
|
|
end
|
|
|
|
|
|
|
|
local function completedMenuFor(data)
|
|
|
|
local count = inventory.count(data.item)
|
|
|
|
if (count == 0 or count + (data.amount or 1) <= tries) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
local function closeMenuFor(data)
|
|
|
|
if ((not tempDir and not data.close) or data.chain or menu.close()) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local function useItem(data)
|
|
|
|
local main = memory.value("menu", "main")
|
|
|
|
if (tries == 0) then
|
|
|
|
tries = inventory.count(data.item)
|
|
|
|
if (tries == 0) then
|
|
|
|
if (closeMenuFor(data)) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if (completedMenuFor(data)) then
|
|
|
|
if (closeMenuFor(data)) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
else
|
|
|
|
if (inventory.use(data.item, data.poke)) then
|
|
|
|
tempDir = true
|
|
|
|
else
|
|
|
|
menu.pause()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local function completedSkillFor(data)
|
|
|
|
if (data.map) then
|
|
|
|
if (data.map ~= memory.value("game", "map")) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
elseif (data.x or data.y) then
|
|
|
|
local px, py = player.position()
|
|
|
|
if (data.x == px or data.y == py) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
elseif (data.done) then
|
|
|
|
if (memory.raw(data.done) > (data.val or 0)) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
elseif (tries > 0 and not menu.isOpen()) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
local function isPrepared(...)
|
|
|
|
if (tries == 0) then
|
|
|
|
tries = {}
|
|
|
|
end
|
2015-03-28 21:28:58 -07:00
|
|
|
for i,name in ipairs(arg) do
|
|
|
|
local currentCount = inventory.count(name)
|
|
|
|
if (currentCount > 0) then
|
|
|
|
local previousCount = 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
|
|
|
|
|
|
|
|
local function prepare(...)
|
|
|
|
if (tries == 0) then
|
|
|
|
tries = {}
|
|
|
|
end
|
2015-03-28 21:28:58 -07:00
|
|
|
local item
|
|
|
|
for idx,name in ipairs(arg) do
|
|
|
|
local currentCount = inventory.count(name)
|
|
|
|
local needsItem = currentCount > 0
|
|
|
|
local previousCount = tries[name]
|
|
|
|
if (previousCount == nil) then
|
|
|
|
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
|
2015-03-28 21:28:58 -07:00
|
|
|
return true
|
|
|
|
end
|
|
|
|
if (battle.isActive()) then
|
2014-07-12 18:47:39 -07:00
|
|
|
inventory.use(item, nil, true)
|
|
|
|
else
|
|
|
|
input.cancel()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- DSum
|
|
|
|
|
|
|
|
local function nidoranDSum(disabled)
|
|
|
|
local sx, sy = player.position()
|
|
|
|
if (not disabled and tries == nil) then
|
|
|
|
local opName = battle.opponent()
|
|
|
|
local opLevel = memory.value("battle", "opponent_level")
|
|
|
|
if (opName == "rattata") then
|
|
|
|
if (opLevel == 2) then
|
|
|
|
tries = {0, 4, 12}
|
|
|
|
elseif (opLevel == 3) then
|
|
|
|
tries = {0, 14, 11}
|
|
|
|
else
|
|
|
|
-- tries = {0, 0, 10} -- TODO can't escape
|
|
|
|
end
|
|
|
|
elseif (opName == "spearow") then
|
2015-01-19 17:11:52 -08:00
|
|
|
if (opLevel == 5) then
|
|
|
|
-- can't escape
|
|
|
|
end
|
2014-07-12 18:47:39 -07:00
|
|
|
elseif (opName == "nidoran") then
|
|
|
|
tries = {0, 6, 12}
|
|
|
|
elseif (opName == "nidoranf") then
|
|
|
|
if (opLevel == 3) then
|
|
|
|
tries = {4, 6, 12}
|
|
|
|
else
|
|
|
|
tries = {5, 6, 12}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if (tries) then
|
|
|
|
tries.idx = 1
|
|
|
|
tries.x, tries.y = sx, sy
|
|
|
|
else
|
|
|
|
tries = 0
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if (not disabled and tries ~= 0) then
|
|
|
|
if (tries[tries.idx] == 0) then
|
|
|
|
tries.idx = tries.idx + 1
|
|
|
|
if (tries.idx > 3) then
|
|
|
|
tries = 0
|
|
|
|
end
|
|
|
|
return nidoranDSum()
|
|
|
|
end
|
|
|
|
if (tries.x ~= sx or tries.y ~= sy) then
|
|
|
|
tries[tries.idx] = tries[tries.idx] - 1
|
|
|
|
tries.x, tries.y = sx, sy
|
|
|
|
end
|
|
|
|
if (tries.idx == 2) then
|
|
|
|
sy = 11
|
|
|
|
else
|
|
|
|
sy = 12
|
|
|
|
end
|
|
|
|
else
|
|
|
|
sy = 11
|
|
|
|
end
|
|
|
|
if (sx == 33) then
|
|
|
|
sx = 32
|
|
|
|
else
|
|
|
|
sx = 33
|
|
|
|
end
|
|
|
|
walk.step(sx, sy)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Strategies
|
|
|
|
|
|
|
|
local strategyFunctions
|
|
|
|
strategyFunctions = {
|
|
|
|
|
|
|
|
a = function(data)
|
|
|
|
areaName = data.a
|
|
|
|
return true
|
|
|
|
end,
|
|
|
|
|
|
|
|
startFrames = function()
|
|
|
|
strategies.frames = 0
|
|
|
|
return true
|
|
|
|
end,
|
|
|
|
|
|
|
|
reportFrames = function()
|
|
|
|
print("FR "..strategies.frames)
|
|
|
|
local repels = memory.value("player", "repel")
|
|
|
|
if (repels > 0) then
|
|
|
|
print("S "..repels)
|
|
|
|
end
|
|
|
|
strategies.frames = nil
|
|
|
|
return true
|
|
|
|
end,
|
|
|
|
|
|
|
|
tweetMisty = function()
|
|
|
|
local elt = paint.elapsedTime()
|
2015-01-19 17:11:52 -08:00
|
|
|
if (setYolo("misty")) then
|
|
|
|
print("Misty: "..elt)
|
|
|
|
else
|
|
|
|
local timeReq = 40
|
|
|
|
if (pokemon.inParty("paras")) then
|
|
|
|
timeReq = timeReq + 0.75
|
|
|
|
end
|
|
|
|
timeReq = timeReq - 1.75
|
|
|
|
local pbn = "!"
|
|
|
|
if (not overMinute(timeReq)) then
|
|
|
|
pbn = " (PB pace)"
|
|
|
|
end
|
|
|
|
bridge.tweet("Got a run going, just beat Misty "..elt.." in"..pbn.." http://www.twitch.tv/thepokebot")
|
|
|
|
end
|
2014-07-12 18:47:39 -07:00
|
|
|
return true
|
|
|
|
end,
|
|
|
|
|
|
|
|
tweetVictoryRoad = function()
|
|
|
|
local elt = paint.elapsedTime()
|
2015-01-19 17:11:52 -08:00
|
|
|
local pbn = ""
|
|
|
|
if (not overMinute(98)) then -- TODO verify
|
|
|
|
pbn = " (PB pace)"
|
|
|
|
end
|
|
|
|
local elt = paint.elapsedTime()
|
|
|
|
bridge.tweet("Entering Victory Road at "..elt..pbn.." on our way to the Elite Four! http://www.twitch.tv/thepokebot")
|
2014-07-12 18:47:39 -07:00
|
|
|
return true
|
|
|
|
end,
|
|
|
|
|
|
|
|
split = function(data)
|
2015-03-28 17:16:04 -07:00
|
|
|
bridge.split(data and data.finished)
|
2014-07-12 18:47:39 -07:00
|
|
|
return true
|
|
|
|
end,
|
|
|
|
|
|
|
|
wait = function()
|
|
|
|
print("Please save state")
|
|
|
|
input.press("Start", 9001)
|
|
|
|
end,
|
|
|
|
|
|
|
|
emuSpeed = function(data)
|
|
|
|
-- client.speedmode = data.percent
|
|
|
|
return true
|
|
|
|
end,
|
|
|
|
|
|
|
|
-- Global
|
|
|
|
|
|
|
|
interact = function(data)
|
|
|
|
if (battle.handleWild()) then
|
|
|
|
if (battle.isActive()) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
if (textbox.isActive()) then
|
|
|
|
if (tries > 0) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
tries = tries - 1
|
|
|
|
input.cancel()
|
|
|
|
elseif (player.interact(data.dir)) then
|
|
|
|
tries = tries + 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
confirm = function(data)
|
|
|
|
if (battle.handleWild()) then
|
|
|
|
if (textbox.isActive()) then
|
|
|
|
tries = tries + 1
|
|
|
|
input.cancel(data.type or "A")
|
|
|
|
else
|
|
|
|
if (tries > 0) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
player.interact(data.dir)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
item = function(data)
|
|
|
|
if (battle.handleWild()) then
|
|
|
|
if (data.full and not inventory.isFull()) then
|
|
|
|
if (closeMenuFor(data)) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
return useItem(data)
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
potion = function(data)
|
|
|
|
local curr_hp = pokemon.index(0, "hp")
|
|
|
|
if (curr_hp == 0) then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
local toHP = data.hp
|
|
|
|
if (yolo and data.yolo ~= nil) then
|
|
|
|
toHP = data.yolo
|
|
|
|
elseif (type(toHP) == "string") then
|
|
|
|
toHP = combat.healthFor(toHP)
|
|
|
|
end
|
|
|
|
local toHeal = toHP - curr_hp
|
|
|
|
if (toHeal > 0) then
|
|
|
|
local toPotion
|
|
|
|
if (data.forced) then
|
|
|
|
toPotion = inventory.contains(data.forced)
|
|
|
|
else
|
|
|
|
local p_first, p_second, p_third
|
|
|
|
if (toHeal > 50) then
|
|
|
|
if (data.full) then
|
|
|
|
p_first = "full_restore"
|
|
|
|
else
|
|
|
|
p_first = "super_potion"
|
|
|
|
end
|
|
|
|
p_second, p_third = "super_potion", "potion"
|
|
|
|
else
|
|
|
|
if (toHeal > 20) then
|
|
|
|
p_first, p_second = "super_potion", "potion"
|
|
|
|
else
|
|
|
|
p_first, p_second = "potion", "super_potion"
|
|
|
|
end
|
|
|
|
if (data.full) then
|
|
|
|
p_third = "full_restore"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
toPotion = inventory.contains(p_first, p_second, p_third)
|
|
|
|
end
|
|
|
|
if (toPotion) then
|
|
|
|
if (menu.pause()) then
|
|
|
|
inventory.use(toPotion)
|
|
|
|
tempDir = true
|
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if (closeMenuFor(data)) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
teach = function(data)
|
|
|
|
if (data.full and not inventory.isFull()) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
local itemName
|
|
|
|
if (data.item) then
|
|
|
|
itemName = data.item
|
|
|
|
else
|
|
|
|
itemName = data.move
|
|
|
|
end
|
|
|
|
if (pokemon.hasMove(data.move)) then
|
|
|
|
local main = memory.value("menu", "main")
|
|
|
|
if (main == 128) then
|
|
|
|
if (data.chain) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
elseif (main < 3) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
input.press("B")
|
|
|
|
else
|
|
|
|
local replacement
|
|
|
|
if (data.replace) then
|
|
|
|
replacement = pokemon.moveIndex(data.replace, data.poke) - 1
|
|
|
|
else
|
|
|
|
replacement = 0
|
|
|
|
end
|
|
|
|
if (inventory.teach(itemName, data.poke, replacement, data.alt)) then
|
|
|
|
tempDir = true
|
|
|
|
else
|
|
|
|
menu.pause()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
skill = function(data)
|
|
|
|
if (completedSkillFor(data)) then
|
|
|
|
if (not textbox.isActive()) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
input.press("B")
|
|
|
|
elseif (not data.dir or player.face(data.dir)) then
|
|
|
|
if (pokemon.use(data.move)) then
|
|
|
|
tries = tries + 1
|
|
|
|
else
|
|
|
|
menu.pause()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
fly = function(data)
|
|
|
|
if (memory.value("game", "map") == data.map) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
local cities = {
|
|
|
|
pallet = {62, "Up"},
|
|
|
|
viridian = {63, "Up"},
|
|
|
|
lavender = {66, "Down"},
|
|
|
|
celadon = {68, "Down"},
|
|
|
|
fuchsia = {69, "Down"},
|
|
|
|
cinnabar = {70, "Down"},
|
|
|
|
}
|
|
|
|
|
|
|
|
local main = memory.value("menu", "main")
|
|
|
|
if (main == 228) then
|
|
|
|
local currentFly = memory.raw(0x1FEF)
|
|
|
|
local destination = cities[data.dest]
|
|
|
|
local press
|
|
|
|
if (destination[1] - currentFly == 0) then
|
|
|
|
press = "A"
|
|
|
|
else
|
|
|
|
press = destination[2]
|
|
|
|
end
|
|
|
|
input.press(press)
|
|
|
|
elseif (not pokemon.use("fly")) then
|
|
|
|
menu.pause()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
bicycle = function()
|
|
|
|
if (memory.raw(0x1700) == 1) then
|
|
|
|
if (textbox.handle()) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
else
|
|
|
|
return useItem({item="bicycle"})
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
fightXAccuracy = function()
|
|
|
|
return prepare("x_accuracy")
|
|
|
|
end,
|
|
|
|
|
|
|
|
waitToTalk = function()
|
|
|
|
if (battle.isActive()) then
|
|
|
|
canProgress = false
|
|
|
|
battle.automate()
|
|
|
|
elseif (textbox.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
input.cancel()
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
waitToPause = function()
|
|
|
|
local main = memory.value("menu", "main")
|
|
|
|
if (main == 128) then
|
|
|
|
if (canProgress) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
elseif (battle.isActive()) then
|
|
|
|
canProgress = false
|
|
|
|
battle.automate()
|
|
|
|
elseif (main == 123) then
|
|
|
|
canProgress = true
|
|
|
|
input.press("B")
|
|
|
|
elseif (textbox.handle()) then
|
|
|
|
input.press("Start", 2)
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
waitToFight = function(data)
|
|
|
|
if (battle.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
battle.automate()
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
elseif (textbox.handle()) then
|
|
|
|
if (data.dir) then
|
|
|
|
player.interact(data.dir)
|
|
|
|
else
|
|
|
|
input.cancel()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
allowDeath = function(data)
|
2015-03-28 21:28:58 -07:00
|
|
|
control.canDie(data.on)
|
2014-07-12 18:47:39 -07:00
|
|
|
return true
|
|
|
|
end,
|
|
|
|
|
|
|
|
-- Route
|
|
|
|
|
|
|
|
squirtleIChooseYou = function()
|
|
|
|
if (pokemon.inParty("squirtle")) then
|
|
|
|
bridge.caught("squirtle")
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
if (player.face("Up")) then
|
|
|
|
textbox.name("A")
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
fightBulbasaur = function()
|
|
|
|
if (tries < 9000 and pokemon.index(0, "level") == 6) then
|
|
|
|
if (tries > 200) then
|
|
|
|
squirtleAtt = pokemon.index(0, "attack")
|
|
|
|
squirtleDef = pokemon.index(0, "defense")
|
|
|
|
squirtleSpd = pokemon.index(0, "speed")
|
|
|
|
squirtleScl = pokemon.index(0, "special")
|
|
|
|
if (squirtleAtt < 11 and squirtleScl < 12) then
|
|
|
|
return reset("Bad Squirtle - "..squirtleAtt.." attack, "..squirtleScl.." special")
|
|
|
|
end
|
|
|
|
tries = 9001
|
|
|
|
else
|
|
|
|
tries = tries + 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if (battle.isActive() and memory.double("battle", "opponent_hp") > 0 and resetTime(2.15, "kill Bulbasaur")) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
return buffTo("tail_whip", 6)
|
|
|
|
end,
|
|
|
|
|
|
|
|
dodgePalletBoy = function()
|
|
|
|
return dodgeUp(0x0223, 14, 14, 15, 7)
|
|
|
|
end,
|
|
|
|
|
2015-03-28 12:47:01 -07:00
|
|
|
shopViridianPokeballs = function()
|
2014-07-12 18:47:39 -07:00
|
|
|
return shop.transaction{
|
|
|
|
buy = {{name="pokeball", index=0, amount=8}}
|
|
|
|
}
|
|
|
|
end,
|
|
|
|
|
|
|
|
catchNidoran = function()
|
|
|
|
if (not control.canCatch()) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
local pokeballs = inventory.count("pokeball")
|
|
|
|
local caught = memory.value("player", "party_size") - 1
|
|
|
|
if (pokeballs < 5 - caught * 2) then
|
2015-02-12 12:59:46 -08:00
|
|
|
return reset("Ran too low on PokeBalls", pokeballs)
|
2014-07-12 18:47:39 -07:00
|
|
|
end
|
|
|
|
if (battle.isActive()) then
|
|
|
|
local isNidoran = pokemon.isOpponent("nidoran")
|
|
|
|
if (isNidoran and memory.value("battle", "opponent_level") > 2) then
|
|
|
|
if (initialize()) then
|
|
|
|
bridge.pollForName()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
tries = nil
|
|
|
|
if (memory.value("menu", "text_input") == 240) then
|
|
|
|
textbox.name()
|
|
|
|
elseif (memory.value("battle", "menu") == 95) then
|
|
|
|
if (isNidoran) then
|
|
|
|
input.press("A")
|
|
|
|
else
|
|
|
|
input.cancel()
|
|
|
|
end
|
|
|
|
elseif (not control.shouldCatch()) then
|
|
|
|
if (control.shouldFight()) then
|
|
|
|
battle.fight()
|
|
|
|
else
|
|
|
|
battle.run()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else
|
|
|
|
local noDSum
|
|
|
|
pokemon.updateParty()
|
|
|
|
local hasNidoran = pokemon.inParty("nidoran")
|
|
|
|
if (hasNidoran) then
|
|
|
|
if (not tempDir) then
|
|
|
|
bridge.caught("nidoran")
|
|
|
|
tempDir = true
|
|
|
|
end
|
|
|
|
if (pokemon.getExp() > 205) then
|
|
|
|
local nidoranLevel = pokemon.info("nidoran", "level")
|
|
|
|
level4Nidoran = nidoranLevel == 4
|
|
|
|
print("Level "..nidoranLevel.." Nidoran")
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
noDSum = true
|
|
|
|
end
|
2015-03-28 17:16:04 -07:00
|
|
|
|
|
|
|
local timeLimit = getTimeRequirement("nidoran")
|
2014-07-12 18:47:39 -07:00
|
|
|
local resetMessage
|
|
|
|
if (hasNidoran) then
|
|
|
|
resetMessage = "get an experience kill before Brock"
|
|
|
|
else
|
|
|
|
resetMessage = "find a Nidoran"
|
|
|
|
end
|
|
|
|
if (resetTime(timeLimit, resetMessage)) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
if (not noDSum and overMinute(timeLimit - 0.25)) then
|
|
|
|
noDSum = true
|
|
|
|
end
|
|
|
|
nidoranDSum(noDSum)
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
-- 1: NIDORAN
|
|
|
|
|
|
|
|
dodgeViridianOldMan = function()
|
|
|
|
return dodgeUp(0x0273, 18, 6, 17, 9)
|
|
|
|
end,
|
|
|
|
|
|
|
|
grabAntidote = function()
|
|
|
|
local px, py = player.position()
|
|
|
|
if (py < 11) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
if (pokemon.info("spearow", "level") == 3) then
|
|
|
|
if (px < 26) then
|
|
|
|
px = 26
|
|
|
|
else
|
|
|
|
py = 10
|
|
|
|
end
|
|
|
|
elseif (inventory.contains("antidote")) then
|
|
|
|
py = 10
|
|
|
|
else
|
|
|
|
player.interact("Up")
|
|
|
|
end
|
|
|
|
walk.step(px, py)
|
|
|
|
end,
|
|
|
|
|
2015-02-12 12:59:46 -08:00
|
|
|
grabForestPotion = function()
|
|
|
|
if (inventory.contains("potion")) then
|
2015-03-28 12:47:01 -07:00
|
|
|
local healthNeeded = (pokemon.info("spearow", "level") == 3) and 6 or 10
|
|
|
|
if (pokemon.info("squirtle", "hp") <= healthNeeded) then
|
2015-02-12 12:59:46 -08:00
|
|
|
if (menu.pause()) then
|
|
|
|
inventory.use("potion", "squirtle")
|
|
|
|
end
|
|
|
|
else
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
elseif (menu.close()) then
|
|
|
|
player.interact("Up")
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
2014-07-12 18:47:39 -07:00
|
|
|
fightWeedle = function()
|
|
|
|
if (battle.isTrainer()) then
|
|
|
|
canProgress = true
|
|
|
|
local squirtleOut = pokemon.isDeployed("squirtle")
|
|
|
|
if (squirtleOut and memory.value("battle", "our_status") > 0 and not inventory.contains("antidote")) then
|
|
|
|
return reset("Poisoned, but we skipped the antidote")
|
|
|
|
end
|
|
|
|
local sidx = pokemon.indexOf("spearow")
|
|
|
|
if (sidx ~= -1 and pokemon.index(sidx, "level") > 3) then
|
|
|
|
sidx = -1
|
|
|
|
end
|
|
|
|
if (sidx == -1) then
|
|
|
|
return buffTo("tail_whip", 5)
|
|
|
|
end
|
|
|
|
if (pokemon.index(sidx, "hp") < 1) then
|
|
|
|
local battleMenu = memory.value("battle", "menu")
|
|
|
|
if (utils.onPokemonSelect(battleMenu)) then
|
|
|
|
menu.select(pokemon.indexOf("squirtle"), true)
|
|
|
|
elseif (battleMenu == 95) then
|
|
|
|
input.press("A")
|
|
|
|
elseif (squirtleOut) then
|
|
|
|
battle.automate()
|
|
|
|
else
|
|
|
|
input.cancel()
|
|
|
|
end
|
|
|
|
elseif (squirtleOut) then
|
|
|
|
battle.swap("spearow")
|
|
|
|
else
|
|
|
|
local peck = combat.bestMove()
|
|
|
|
local forced
|
|
|
|
if (peck and peck.damage and peck.damage + 1 >= memory.double("battle", "opponent_hp")) then
|
|
|
|
forced = "growl"
|
|
|
|
end
|
|
|
|
battle.fight(forced)
|
|
|
|
end
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
equipForBrock = function(data)
|
|
|
|
if (initialize()) then
|
|
|
|
if (pokemon.info("squirtle", "level") < 8) then
|
|
|
|
return reset("Not level 8 before Brock", pokemon.getExp())
|
|
|
|
end
|
|
|
|
if (data.anti) then
|
|
|
|
local poisoned = pokemon.info("squirtle", "status") > 0
|
|
|
|
if (not poisoned) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
if (not inventory.contains("antidote")) then
|
|
|
|
return reset("Poisoned, but we skipped the antidote")
|
|
|
|
end
|
|
|
|
if (inventory.contains("potion") and pokemon.info("squirtle", "hp") > 8) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
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
|
|
|
|
local column = menu.getCol()
|
|
|
|
if (pokemon.info("squirtle", "status") > 0) then
|
|
|
|
inventory.use("antidote", "squirtle")
|
|
|
|
elseif (inventory.contains("potion") and pokemon.info("squirtle", "hp") < 15) then
|
|
|
|
inventory.use("potion", "squirtle")
|
|
|
|
else
|
|
|
|
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 == 103) then
|
|
|
|
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
|
|
|
|
end,
|
|
|
|
|
|
|
|
fightBrock = function()
|
|
|
|
local squirtleHP = pokemon.info("squirtle", "hp")
|
|
|
|
if (squirtleHP == 0) then
|
|
|
|
return resetDeath()
|
|
|
|
end
|
|
|
|
if (battle.isActive()) then
|
|
|
|
if (tries < 1) then
|
|
|
|
tries = 1
|
|
|
|
end
|
|
|
|
local bubble, turnsToKill, turnsToDie = combat.bestMove()
|
|
|
|
if (not pokemon.isDeployed("squirtle")) then
|
|
|
|
battle.swap("squirtle")
|
|
|
|
elseif (turnsToDie and turnsToDie < 2 and inventory.contains("potion")) then
|
|
|
|
inventory.use("potion", "squirtle", true)
|
|
|
|
else
|
|
|
|
local battleMenu = memory.value("battle", "menu")
|
|
|
|
local bideTurns = memory.value("battle", "opponent_bide")
|
|
|
|
if (battleMenu == 95 and menu.getCol() == 1) then
|
|
|
|
input.press("A")
|
|
|
|
elseif (bideTurns > 0) then
|
|
|
|
local onixHP = memory.double("battle", "opponent_hp")
|
|
|
|
if (not canProgress) then
|
|
|
|
canProgress = onixHP
|
|
|
|
tempDir = bideTurns
|
|
|
|
end
|
|
|
|
if (turnsToKill) then
|
|
|
|
local forced
|
|
|
|
if (turnsToDie < 2 or turnsToKill < 2 or tempDir - bideTurns > 1) then
|
2015-01-19 17:11:52 -08:00
|
|
|
-- elseif (turnsToKill < 3 and tempDir == bideTurns) then
|
2014-07-12 18:47:39 -07:00
|
|
|
elseif (onixHP == canProgress) then
|
|
|
|
forced = "tail_whip"
|
|
|
|
end
|
|
|
|
battle.fight(forced)
|
|
|
|
else
|
|
|
|
input.cancel()
|
|
|
|
end
|
|
|
|
elseif (utils.onPokemonSelect(battleMenu)) then
|
|
|
|
menu.select(pokemon.indexOf("nidoran"), true)
|
|
|
|
else
|
|
|
|
canProgress = false
|
|
|
|
battle.fight()
|
|
|
|
end
|
|
|
|
if (tries < 9000) then
|
|
|
|
local nidx = pokemon.indexOf("nidoran")
|
|
|
|
if (pokemon.index(nidx, "level") == 8) then
|
|
|
|
local att = pokemon.index(nidx, "attack")
|
|
|
|
local def = pokemon.index(nidx, "defense")
|
|
|
|
local spd = pokemon.index(nidx, "speed")
|
|
|
|
local scl = pokemon.index(nidx, "special")
|
|
|
|
bridge.stats(att.." "..def.." "..spd.." "..scl)
|
|
|
|
nidoAttack = att
|
|
|
|
nidoSpeed = spd
|
|
|
|
nidoSpecial = scl
|
|
|
|
if (tries > 300) then
|
|
|
|
local statDiff = (16 - att) + (15 - spd) + (13 - scl)
|
|
|
|
if (def < 12) then
|
|
|
|
statDiff = statDiff + 1
|
|
|
|
end
|
2015-03-28 17:16:04 -07:00
|
|
|
if (level4Nidoran) then
|
|
|
|
statDiff = statDiff - 1
|
|
|
|
end
|
2014-07-12 18:47:39 -07:00
|
|
|
local resets = att < 15 or spd < 14 or scl < 12 or statDiff > 3
|
|
|
|
if (not resets and att == 15 and spd == 14) then
|
|
|
|
resets = true
|
|
|
|
end
|
|
|
|
local nStatus = "Att: "..att..", Def: "..def..", Speed: "..spd..", Special: "..scl
|
|
|
|
if (resets) then
|
|
|
|
return reset("Bad Nidoran - "..nStatus)
|
|
|
|
end
|
|
|
|
tries = 9001
|
|
|
|
local superlative
|
|
|
|
local exclaim = "!"
|
|
|
|
if (statDiff == 0) then
|
|
|
|
if (def == 14) then
|
|
|
|
superlative = " god"
|
|
|
|
exclaim = "! Kreygasm"
|
|
|
|
else
|
|
|
|
superlative = " perfect"
|
|
|
|
end
|
|
|
|
elseif (att == 16 and spd == 15) then
|
|
|
|
if (statDiff == 1) then
|
|
|
|
superlative = " great"
|
|
|
|
elseif (statDiff == 2) then
|
|
|
|
superlative = " good"
|
|
|
|
end
|
|
|
|
elseif (statDiff == 1) then
|
|
|
|
superlative = " good"
|
|
|
|
elseif (statDiff == 2) then
|
|
|
|
superlative = "n okay"
|
|
|
|
exclaim = "."
|
|
|
|
else
|
|
|
|
superlative = " min stat"
|
|
|
|
exclaim = "."
|
|
|
|
end
|
2015-03-28 21:28:58 -07:00
|
|
|
nStatus = "Beat Brock with a"..superlative.." Nidoran"..exclaim.." "..nStatus..", caught at level "..(level4Nidoran and "4" or "3").."."
|
2014-07-12 18:47:39 -07:00
|
|
|
bridge.chat(nStatus)
|
|
|
|
else
|
|
|
|
tries = tries + 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
elseif (tries > 0) then
|
|
|
|
return true
|
|
|
|
elseif (textbox.handle()) then
|
|
|
|
player.interact("Up")
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
-- 2: BROCK
|
|
|
|
|
2015-03-28 12:47:01 -07:00
|
|
|
shopPewterMart = function()
|
2014-07-12 18:47:39 -07:00
|
|
|
return shop.transaction{
|
2015-03-28 12:47:01 -07:00
|
|
|
buy = {{name="potion", index=1, amount=8}}
|
2014-07-12 18:47:39 -07:00
|
|
|
}
|
|
|
|
end,
|
|
|
|
|
|
|
|
battleModeSet = function()
|
|
|
|
if (memory.value("setting", "battle_style") == 10) then
|
|
|
|
if (menu.close()) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
elseif (menu.pause()) then
|
|
|
|
local main = memory.value("menu", "main")
|
|
|
|
if (main == 128) then
|
|
|
|
if (menu.getCol() ~= 11) then
|
|
|
|
input.press("B")
|
|
|
|
else
|
|
|
|
menu.select(5, true)
|
|
|
|
end
|
|
|
|
elseif (main == 228) then
|
|
|
|
menu.setOption("battle_style", 8, 10)
|
|
|
|
else
|
|
|
|
input.press("B")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
leer = function(data)
|
|
|
|
local bm = combat.bestMove()
|
|
|
|
if (not bm or bm.minTurns < 3) then
|
|
|
|
if (battle.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
elseif (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] and (not poke[3] or nidoAttack > poke[3])) then
|
|
|
|
defLimit = poke[2]
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return buffTo("leer", defLimit)
|
|
|
|
end,
|
|
|
|
|
|
|
|
shortsKid = function()
|
2015-03-28 12:47:01 -07:00
|
|
|
local fightingEkans = pokemon.isOpponent("ekans")
|
|
|
|
control.battlePotion(fightingEkans or damaged(2))
|
2014-07-12 18:47:39 -07:00
|
|
|
return strategyFunctions.leer({{"rattata",9}, {"ekans",10}})
|
|
|
|
end,
|
|
|
|
|
|
|
|
potionBeforeCocoons = function()
|
|
|
|
if (yolo or nidoSpeed > 14) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
return strategyFunctions.potion({hp=6})
|
|
|
|
end,
|
|
|
|
|
|
|
|
swapHornAttack = function()
|
|
|
|
if (pokemon.battleMove("horn_attack") == 1) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
battle.swapMove(1, 3)
|
|
|
|
end,
|
|
|
|
|
|
|
|
fightMetapod = function()
|
|
|
|
if (battle.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
if (memory.double("battle", "opponent_hp") > 0 and pokemon.isOpponent("metapod")) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
battle.automate()
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
battle.automate()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
catchFlierBackup = function()
|
|
|
|
if (initialize()) then
|
2015-03-28 21:28:58 -07:00
|
|
|
control.canDie(true)
|
2014-07-12 18:47:39 -07:00
|
|
|
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
|
2015-03-28 21:28:58 -07:00
|
|
|
control.canDie(false)
|
2014-07-12 18:47:39 -07:00
|
|
|
elseif (utils.onPokemonSelect(memory.value("battle", "menu"))) then
|
|
|
|
menu.select(pokemon.indexOf("squirtle"), true)
|
|
|
|
else
|
|
|
|
input.press("A")
|
|
|
|
end
|
|
|
|
elseif (not control.shouldCatch()) then
|
|
|
|
battle.run()
|
|
|
|
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,
|
|
|
|
|
|
|
|
-- 3: ROUTE 3
|
|
|
|
|
|
|
|
startMtMoon = function()
|
|
|
|
strategies.moonEncounters = 0
|
2015-03-28 21:28:58 -07:00
|
|
|
control.canDie(false)
|
2014-07-12 18:47:39 -07:00
|
|
|
return true
|
|
|
|
end,
|
|
|
|
|
|
|
|
evolveNidorino = function()
|
|
|
|
if (pokemon.inParty("nidorino")) then
|
|
|
|
bridge.caught("nidorino")
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
if (battle.isActive()) then
|
|
|
|
tries = 0
|
|
|
|
canProgress = true
|
|
|
|
if (memory.double("battle", "opponent_hp") == 0) then
|
|
|
|
input.press("A")
|
|
|
|
else
|
|
|
|
battle.automate()
|
|
|
|
end
|
|
|
|
elseif (tries > 3600) then
|
|
|
|
print("Broke from Nidorino on tries")
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
if (canProgress) then
|
|
|
|
tries = tries + 1
|
|
|
|
end
|
|
|
|
input.press("A")
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
evolveNidoking = function()
|
|
|
|
if (battle.handleWild()) then
|
|
|
|
if (not inventory.contains("moon_stone")) then
|
|
|
|
if (initialize()) then
|
|
|
|
bridge.caught("nidoking")
|
|
|
|
end
|
|
|
|
if (menu.close()) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
elseif (not inventory.use("moon_stone")) then
|
|
|
|
menu.pause()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
helix = function()
|
|
|
|
if (battle.handleWild()) then
|
|
|
|
if (inventory.contains("helix_fossil")) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
player.interact("Up")
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
reportMtMoon = function()
|
|
|
|
if (battle.pp("horn_attack") == 0) then
|
|
|
|
print("ERR: Ran out of Horn Attacks")
|
|
|
|
end
|
|
|
|
if (strategies.moonEncounters) then
|
|
|
|
local parasStatus
|
|
|
|
local conjunction = "but"
|
|
|
|
local goodEncounters = strategies.moonEncounters < 10
|
|
|
|
local parasCatch
|
|
|
|
if (pokemon.inParty("paras")) then
|
|
|
|
parasCatch = "paras"
|
|
|
|
if (goodEncounters) then
|
|
|
|
conjunction = "and"
|
|
|
|
end
|
|
|
|
parasStatus = "we found a Paras!"
|
|
|
|
else
|
|
|
|
parasCatch = "no_paras"
|
|
|
|
if (not goodEncounters) then
|
|
|
|
conjunction = "and"
|
|
|
|
end
|
|
|
|
parasStatus = "we didn't find a Paras :("
|
|
|
|
end
|
|
|
|
bridge.caught(parasCatch)
|
|
|
|
bridge.chat(strategies.moonEncounters.." Moon encounters, "..conjunction.." "..parasStatus)
|
|
|
|
strategies.moonEncounters = nil
|
|
|
|
end
|
|
|
|
|
2015-03-28 17:16:04 -07:00
|
|
|
local timeLimit = getTimeRequirement("mt_moon")
|
2014-07-12 18:47:39 -07:00
|
|
|
resetTime(timeLimit, "complete Mt. Moon", true)
|
|
|
|
return true
|
|
|
|
end,
|
|
|
|
|
|
|
|
-- 4: MT. MOON
|
|
|
|
|
|
|
|
dodgeCerulean = function()
|
|
|
|
return dodgeH{
|
|
|
|
npc = 0x0242,
|
|
|
|
sx = 14, sy = 18,
|
|
|
|
dodge = 19,
|
|
|
|
offset = 10,
|
|
|
|
dist = 4
|
|
|
|
}
|
|
|
|
end,
|
|
|
|
|
|
|
|
dodgeCeruleanLeft = function()
|
|
|
|
return dodgeH{
|
|
|
|
npc = 0x0242,
|
|
|
|
sx = 16, sy = 18,
|
|
|
|
dodge = 17,
|
|
|
|
offset = 10,
|
|
|
|
dist = -7,
|
|
|
|
left = true
|
|
|
|
}
|
|
|
|
end,
|
|
|
|
|
|
|
|
rivalSandAttack = function(data)
|
|
|
|
if (battle.isActive()) then
|
|
|
|
local forced
|
|
|
|
if (not pokemon.isDeployed("nidoking")) then
|
|
|
|
local battleMenu = memory.value("battle", "menu")
|
|
|
|
if (utils.onPokemonSelect(battleMenu)) then
|
|
|
|
menu.select(pokemon.indexOf("nidoking"), true)
|
|
|
|
elseif (battleMenu == 95 and menu.getCol() == 1) then
|
|
|
|
input.press("A")
|
|
|
|
else
|
|
|
|
local __, turns = combat.bestMove()
|
|
|
|
if (turns == 1 and battle.pp("sand_attack") > 0) then
|
|
|
|
forced = "sand_attack"
|
|
|
|
end
|
|
|
|
battle.fight(forced)
|
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
local opponent = battle.opponent()
|
|
|
|
if (opponent == "pidgeotto") then
|
|
|
|
canProgress = true
|
|
|
|
combat.disableThrash = true
|
|
|
|
if (memory.value("battle", "accuracy") < 7) then
|
|
|
|
local __, turns = combat.bestMove()
|
|
|
|
local putIn, takeOut
|
|
|
|
if (turns == 1) then
|
|
|
|
local sacrifice
|
|
|
|
local temp = pokemon.inParty("pidgey", "spearow")
|
|
|
|
if (temp and pokemon.info(temp, "hp") > 0) then
|
|
|
|
sacrifice = temp
|
|
|
|
end
|
|
|
|
if (not sacrifice) then
|
|
|
|
if (yolo) then
|
|
|
|
temp = pokemon.inParty("oddish")
|
|
|
|
else
|
|
|
|
temp = pokemon.inParty("oddish", "paras", "squirtle")
|
|
|
|
end
|
|
|
|
if (temp and pokemon.info(temp, "hp") > 0) then
|
|
|
|
sacrifice = temp
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if (sacrifice) then
|
|
|
|
battle.swap(sacrifice)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
elseif (opponent == "raticate") then
|
|
|
|
combat.disableThrash = opponentDamaged() or (not yolo and pokemon.index(0, "hp") < 32) -- RISK
|
|
|
|
elseif (opponent == "ivysaur") then
|
|
|
|
if (not yolo and damaged(5) and inventory.contains("super_potion")) then
|
|
|
|
inventory.use("super_potion", nil, true)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
combat.disableThrash = opponentDamaged()
|
|
|
|
else
|
|
|
|
combat.disableThrash = false
|
|
|
|
end
|
|
|
|
battle.automate(forced)
|
|
|
|
canProgress = true
|
|
|
|
elseif (canProgress) then
|
|
|
|
combat.disableThrash = false
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
textbox.handle()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
teachThrash = function()
|
|
|
|
if (initialize()) then
|
|
|
|
if (pokemon.hasMove("thrash") or pokemon.info("nidoking", "level") < 21) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if (strategyFunctions.teach({move="thrash",item="rare_candy",replace="leer"})) then
|
|
|
|
if (menu.close()) then
|
|
|
|
local att = pokemon.index(0, "attack")
|
|
|
|
local def = pokemon.index(0, "defense")
|
|
|
|
local spd = pokemon.index(0, "speed")
|
|
|
|
local scl = pokemon.index(0, "special")
|
|
|
|
local statDesc = att.." "..def.." "..spd.." "..scl
|
|
|
|
nidoAttack = att
|
|
|
|
nidoSpeed = spd
|
|
|
|
nidoSpecial = scl
|
|
|
|
bridge.stats(statDesc)
|
|
|
|
print(statDesc)
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
redbarMankey = function()
|
|
|
|
if (not setYolo("mankey")) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
local curr_hp, red_hp = pokemon.index(0, "hp"), redHP()
|
|
|
|
if (curr_hp <= red_hp) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
if (initialize()) then
|
|
|
|
if (pokemon.info("nidoking", "level") < 21 or inventory.count("potion") < 3) then -- RISK
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
bridge.chat("Using Poison Sting to attempt to redbar off Mankey")
|
|
|
|
end
|
|
|
|
if (battle.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
local enemyMove, enemyTurns = combat.enemyAttack()
|
|
|
|
if (enemyTurns) then
|
|
|
|
if (enemyTurns < 2) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
local scratchDmg = enemyMove.damage
|
|
|
|
if (curr_hp - red_hp > scratchDmg) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
battle.automate("poison_sting")
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
textbox.handle()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
2015-01-19 17:11:52 -08:00
|
|
|
thrashGeodude = function()
|
|
|
|
if (battle.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
if (pokemon.isOpponent("geodude") and pokemon.isDeployed("nidoking")) then
|
|
|
|
local sacrifice = pokemon.inParty("squirtle")
|
|
|
|
if (sacrifice and pokemon.info(sacrifice, "hp") > 0) then
|
|
|
|
battle.swap(sacrifice)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
battle.automate()
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
textbox.handle()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
2014-07-12 18:47:39 -07:00
|
|
|
potionBeforeGoldeen = function()
|
2015-01-19 17:11:52 -08:00
|
|
|
if (not STREAMING_MODE and nidoSpeed == 51) then
|
|
|
|
return false --TEST
|
|
|
|
end
|
2014-07-12 18:47:39 -07:00
|
|
|
if (initialize()) then
|
|
|
|
if (setYolo("goldeen") or pokemon.index(0, "hp") > 7) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return strategyFunctions.potion({hp=64, chain=true})
|
|
|
|
end,
|
|
|
|
|
|
|
|
potionBeforeMisty = function()
|
|
|
|
local healAmount = 70
|
|
|
|
if (yolo) then
|
|
|
|
if (nidoAttack > 53 and nidoSpeed > 50) then
|
|
|
|
healAmount = 45
|
|
|
|
elseif (nidoAttack > 53) then
|
|
|
|
healAmount = 65
|
|
|
|
end
|
|
|
|
else
|
|
|
|
if (nidoAttack > 54 and nidoSpeed > 51) then -- RISK
|
|
|
|
healAmount = 45
|
|
|
|
elseif (nidoAttack > 53 and nidoSpeed > 50) then
|
|
|
|
healAmount = 65
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return strategyFunctions.potion({hp=healAmount})
|
|
|
|
end,
|
|
|
|
|
2015-03-28 12:47:01 -07:00
|
|
|
fightMisty = function()
|
|
|
|
if (battle.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
if (pokemon.isDeployed("nidoking") and combat.isConfused()) then
|
|
|
|
local sacrifice = pokemon.inParty("paras", "pidgey", "spearow")
|
|
|
|
if (sacrifice and pokemon.info(sacrifice, "hp") > 0) then
|
|
|
|
battle.swap(sacrifice)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
battle.automate()
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
textbox.handle()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
2014-07-12 18:47:39 -07:00
|
|
|
-- 6: MISTY
|
|
|
|
|
|
|
|
potionBeforeRocket = function()
|
|
|
|
local minAttack = 55 -- RISK
|
|
|
|
if (yolo) then
|
|
|
|
minAttack = minAttack - 1
|
|
|
|
end
|
|
|
|
if (nidoAttack >= minAttack) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
return strategyFunctions.potion({hp=10})
|
|
|
|
end,
|
|
|
|
|
|
|
|
jingleSkip = function()
|
|
|
|
if (canProgress) then
|
|
|
|
local px, py = player.position()
|
|
|
|
if (px < 4) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
input.press("Left", 0)
|
|
|
|
else
|
|
|
|
input.press("A", 0)
|
|
|
|
canProgress = true
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
catchOddish = function()
|
|
|
|
if (not control.canCatch()) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
local caught = pokemon.inParty("oddish", "paras")
|
|
|
|
local battleValue = memory.value("game", "battle")
|
|
|
|
local px, py = player.position()
|
|
|
|
if (battleValue > 0) then
|
|
|
|
if (battleValue == 2) then
|
|
|
|
tries = 2
|
|
|
|
battle.automate()
|
|
|
|
else
|
|
|
|
if (tries == 0 and py == 31) then
|
|
|
|
tries = 1
|
|
|
|
end
|
|
|
|
if (not control.shouldCatch()) then
|
|
|
|
battle.run()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
elseif (tries == 1 and py == 31) then
|
|
|
|
player.interact("Left")
|
|
|
|
else
|
|
|
|
local path
|
|
|
|
if (caught) then
|
|
|
|
if (not tempDir) then
|
|
|
|
bridge.caught(pokemon.inParty("oddish"))
|
|
|
|
tempDir = true
|
|
|
|
end
|
|
|
|
if (py < 21) then
|
|
|
|
py = 21
|
|
|
|
elseif (py < 24) then
|
|
|
|
if (px < 16) then
|
|
|
|
px = 17
|
|
|
|
else
|
|
|
|
py = 24
|
|
|
|
end
|
|
|
|
elseif (py < 25) then
|
|
|
|
py = 25
|
|
|
|
elseif (px > 15) then
|
|
|
|
px = 15
|
|
|
|
elseif (py < 28) then
|
|
|
|
py = 28
|
|
|
|
elseif (py > 29) then
|
|
|
|
py = 29
|
|
|
|
elseif (px ~= 11) then
|
|
|
|
px = 11
|
|
|
|
elseif (py ~= 29) then
|
|
|
|
py = 29
|
|
|
|
else
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
walk.step(px, py)
|
|
|
|
elseif (px == 12) then
|
|
|
|
local dy
|
|
|
|
if (py == 30) then
|
|
|
|
dy = 31
|
|
|
|
else
|
|
|
|
dy = 30
|
|
|
|
end
|
|
|
|
walk.step(px, dy)
|
|
|
|
else
|
|
|
|
local path = {{15,19}, {15,25}, {15,25}, {15,27}, {14,27}, {14,30}, {12,30}}
|
|
|
|
walk.custom(path)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
2015-03-28 12:47:01 -07:00
|
|
|
shopVermilionMart = function()
|
2014-07-12 18:47:39 -07:00
|
|
|
if (initialize()) then
|
|
|
|
setYolo("vermilion")
|
|
|
|
end
|
|
|
|
local buyArray, sellArray
|
|
|
|
if (not inventory.contains("pokeball") or (not yolo and nidoAttack < 53)) then
|
|
|
|
sellArray = {{name="pokeball"}, {name="antidote"}, {name="tm34"}, {name="nugget"}}
|
|
|
|
buyArray = {{name="super_potion",index=1,amount=3}, {name="paralyze_heal",index=4,amount=2}, {name="repel",index=5,amount=3}}
|
|
|
|
else
|
|
|
|
sellArray = {{name="antidote"}, {name="tm34"}, {name="nugget"}}
|
|
|
|
buyArray = {{name="super_potion",index=1,amount=3}, {name="repel",index=5,amount=3}}
|
|
|
|
end
|
|
|
|
return shop.transaction{
|
|
|
|
sell = sellArray,
|
|
|
|
buy = buyArray
|
|
|
|
}
|
|
|
|
end,
|
|
|
|
|
2015-03-28 12:47:01 -07:00
|
|
|
-- rivalSandAttack
|
|
|
|
|
2014-07-12 18:47:39 -07:00
|
|
|
trashcans = function()
|
|
|
|
local progress = memory.value("progress", "trashcans")
|
|
|
|
if (textbox.isActive()) then
|
|
|
|
if (not canProgress) then
|
|
|
|
if (progress < 2) then
|
|
|
|
tries = tries + 1
|
|
|
|
end
|
|
|
|
canProgress = true
|
|
|
|
end
|
|
|
|
input.cancel()
|
|
|
|
else
|
|
|
|
if (progress == 3) then
|
|
|
|
local px, py = player.position()
|
|
|
|
if (px == 4 and py == 6) then
|
|
|
|
tries = tries + 1
|
|
|
|
local timeLimit = getTimeRequirement("trash") + 1
|
|
|
|
if (resetTime(timeLimit, "complete Trashcans ("..tries.." tries)")) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
setYolo("trash")
|
2015-03-28 17:16:04 -07:00
|
|
|
|
2014-07-12 18:47:39 -07:00
|
|
|
local prefix
|
|
|
|
local suffix = "!"
|
|
|
|
if (tries < 2) then
|
|
|
|
prefix = "PERFECT"
|
|
|
|
elseif (tries < 4) then
|
|
|
|
prefix = "Amazing"
|
|
|
|
elseif (tries < 7) then
|
|
|
|
prefix = "Great"
|
|
|
|
elseif (tries < 10) then
|
|
|
|
prefix = "Good"
|
|
|
|
elseif (tries < 24) then
|
|
|
|
prefix = "Ugh"
|
|
|
|
suffix = "."
|
2015-01-19 17:11:52 -08:00
|
|
|
else -- TODO trashcans WR
|
2014-07-12 18:47:39 -07:00
|
|
|
prefix = "Reset me now"
|
|
|
|
suffix = " BibleThump"
|
|
|
|
end
|
|
|
|
bridge.chat(prefix..", "..tries.." try Trashcans"..suffix, paint.elapsedTime())
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
local completePath = {
|
|
|
|
Down = {{2,11}, {8,7}},
|
|
|
|
Right = {{2,12}, {3,12}, {2,6}, {3,6}},
|
|
|
|
Left = {{9,8}, {8,8}, {7,8}, {6,8}, {5,8}, {9,10}, {8,10}, {7,10}, {6,10}, {5,10}, {}, {}, {}, {}, {}, {}},
|
|
|
|
}
|
|
|
|
local walkIn = "Up"
|
|
|
|
for dir,tileset in pairs(completePath) do
|
|
|
|
for i,tile in ipairs(tileset) do
|
|
|
|
if (px == tile[1] and py == tile[2]) then
|
|
|
|
walkIn = dir
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
input.press(walkIn, 0)
|
|
|
|
elseif (progress == 2) then
|
|
|
|
if (canProgress) then
|
|
|
|
canProgress = false
|
|
|
|
walk.invertCustom()
|
|
|
|
end
|
|
|
|
local inverse = {
|
|
|
|
Up = "Down",
|
|
|
|
Right = "Left",
|
|
|
|
Down = "Up",
|
|
|
|
Left = "Right"
|
|
|
|
}
|
|
|
|
player.interact(inverse[tempDir])
|
|
|
|
else
|
|
|
|
local trashPath = {{2,11},{"Left"},{2,11}, {2,12},{4,12},{4,11},{"Right"},{4,11}, {4,9},{"Left"},{4,9}, {4,7},{"Right"},{4,7}, {4,6},{2,6},{2,7},{"Left"},{2,7}, {2,6},{4,6},{4,8},{7,8},{"Down"},{7,8}, {9,8},{"Up"},{9,8}, {8,8},{8,11},{"Right"},{8,11}}
|
|
|
|
if (tempDir and type(tempDir) == "number") then
|
|
|
|
local px, py = player.position()
|
|
|
|
local dx, dy = px, py
|
|
|
|
if (py < 12) then
|
|
|
|
dy = 12
|
|
|
|
elseif (tempDir == 1) then
|
|
|
|
dx = 2
|
|
|
|
else
|
|
|
|
dx = 8
|
|
|
|
end
|
|
|
|
if (px ~= dx or py ~= dy) then
|
|
|
|
walk.step(dx, dy)
|
|
|
|
return
|
|
|
|
end
|
|
|
|
tempDir = nil
|
|
|
|
end
|
|
|
|
tempDir = walk.custom(trashPath, canProgress)
|
|
|
|
canProgress = false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
fightSurge = function()
|
|
|
|
if (battle.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
local forced
|
|
|
|
if (pokemon.isOpponent("voltorb")) then
|
|
|
|
combat.disableThrash = true
|
|
|
|
local __, enemyTurns = combat.enemyAttack()
|
|
|
|
if (not enemyTurns or enemyTurns > 2) then
|
|
|
|
forced = "bubblebeam"
|
|
|
|
elseif (enemyTurns == 2 and not opponentDamaged()) then
|
|
|
|
local curr_hp, red_hp = pokemon.index(0, "hp"), redHP()
|
|
|
|
local afterHit = curr_hp - 20
|
|
|
|
if (afterHit > 5 and afterHit <= red_hp) then
|
|
|
|
forced = "bubblebeam"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else
|
|
|
|
combat.disableThrash = false
|
|
|
|
end
|
|
|
|
battle.automate(forced)
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
textbox.handle()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
-- 7: SURGE
|
|
|
|
|
|
|
|
procureBicycle = function()
|
|
|
|
if (inventory.contains("bicycle")) then
|
|
|
|
if (not textbox.isActive()) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
input.cancel()
|
|
|
|
elseif (textbox.handle()) then
|
2015-03-28 12:47:01 -07:00
|
|
|
player.interact("Right")
|
2014-07-12 18:47:39 -07:00
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
swapBicycle = function()
|
|
|
|
local bicycleIdx = inventory.indexOf("bicycle")
|
|
|
|
if (bicycleIdx < 3) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
local main = memory.value("menu", "main")
|
|
|
|
if (main == 128) then
|
|
|
|
if (menu.getCol() ~= 5) then
|
|
|
|
menu.select(2, true)
|
|
|
|
else
|
|
|
|
local selection = memory.value("menu", "selection_mode")
|
|
|
|
if (selection == 0) then
|
|
|
|
if (menu.select(0, "accelerate", true, nil, true)) then
|
|
|
|
input.press("Select")
|
|
|
|
end
|
|
|
|
else
|
|
|
|
if (menu.select(bicycleIdx, "accelerate", true, nil, true)) then
|
|
|
|
input.press("Select")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else
|
|
|
|
menu.pause()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
redbarCubone = function()
|
|
|
|
if (battle.isActive()) then
|
|
|
|
local forced
|
|
|
|
canProgress = true
|
|
|
|
if (pokemon.isOpponent("cubone")) then
|
|
|
|
local enemyMove, enemyTurns = combat.enemyAttack()
|
|
|
|
if (enemyTurns) then
|
|
|
|
local curr_hp, red_hp = pokemon.index(0, "hp"), redHP()
|
|
|
|
local clubDmg = enemyMove.damage
|
|
|
|
local afterHit = curr_hp - clubDmg
|
|
|
|
if (afterHit > -2 and afterHit < red_hp) then
|
|
|
|
forced = "thunderbolt"
|
|
|
|
else
|
|
|
|
afterHit = afterHit - clubDmg
|
|
|
|
if (afterHit > -4 and afterHit < red_hp) then
|
|
|
|
forced = "thunderbolt"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if (forced and initialize()) then
|
|
|
|
bridge.chat("Using Thunderbolt to attempt to redbar off Cubone")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
battle.automate(forced)
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
battle.automate()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
2015-03-28 12:47:01 -07:00
|
|
|
shopTM07 = function()
|
2014-07-12 18:47:39 -07:00
|
|
|
return shop.transaction{
|
2015-03-28 12:47:01 -07:00
|
|
|
direction = "Up",
|
|
|
|
buy = {{name="horn_drill", index=3}}
|
2014-07-12 18:47:39 -07:00
|
|
|
}
|
|
|
|
end,
|
|
|
|
|
2015-03-28 12:47:01 -07:00
|
|
|
shopRepels = function()
|
2014-07-12 18:47:39 -07:00
|
|
|
return shop.transaction{
|
|
|
|
direction = "Up",
|
2015-03-28 12:47:01 -07:00
|
|
|
buy = {{name="super_repel", index=3, amount=9}}
|
|
|
|
}
|
|
|
|
end,
|
|
|
|
|
|
|
|
shopPokeDoll = function()
|
|
|
|
return shop.transaction{
|
|
|
|
direction = "Down",
|
|
|
|
buy = {{name="pokedoll", index=0}}
|
2014-07-12 18:47:39 -07:00
|
|
|
}
|
|
|
|
end,
|
|
|
|
|
|
|
|
shopVending = function()
|
|
|
|
return shop.vend{
|
|
|
|
direction = "Up",
|
|
|
|
buy = {{name="fresh_water", index=0}, {name="soda_pop", index=1}}
|
|
|
|
}
|
|
|
|
end,
|
|
|
|
|
|
|
|
giveWater = function()
|
|
|
|
if (not inventory.contains("fresh_water", "soda_pop")) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
if (textbox.isActive()) then
|
|
|
|
input.cancel("A")
|
|
|
|
else
|
|
|
|
local cx, cy = memory.raw(0x0223) - 3, memory.raw(0x0222) - 3
|
|
|
|
local px, py = player.position()
|
|
|
|
if (utils.dist(cx, cy, px, py) == 1) then
|
|
|
|
player.interact(walk.dir(px, py, cx, cy))
|
|
|
|
else
|
|
|
|
walk.step(cx, cy)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
shopExtraWater = function()
|
|
|
|
return shop.vend{
|
|
|
|
direction = "Up",
|
|
|
|
buy = {{name="fresh_water", index=0}}
|
|
|
|
}
|
|
|
|
end,
|
|
|
|
|
2015-03-28 12:47:01 -07:00
|
|
|
shopBuffs = function()
|
|
|
|
if (initialize()) then
|
|
|
|
local minSpecial = 45
|
|
|
|
if (yolo) then
|
|
|
|
minSpecial = minSpecial - 1
|
|
|
|
end
|
|
|
|
if (nidoAttack >= 54 and nidoSpecial >= minSpecial) then
|
|
|
|
riskGiovanni = true
|
|
|
|
print("Giovanni skip strats!")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local xspecAmt = 4
|
|
|
|
if (riskGiovanni) then
|
|
|
|
xspecAmt = xspecAmt + 1
|
|
|
|
elseif (nidoSpecial < 46) then
|
|
|
|
xspecAmt = xspecAmt - 1
|
|
|
|
end
|
2014-07-12 18:47:39 -07:00
|
|
|
return shop.transaction{
|
|
|
|
direction = "Up",
|
2015-03-28 12:47:01 -07:00
|
|
|
buy = {{name="x_accuracy", index=0, amount=10}, {name="x_speed", index=5, amount=4}, {name="x_special", index=6, amount=xspecAmt}}
|
2014-07-12 18:47:39 -07:00
|
|
|
}
|
|
|
|
end,
|
|
|
|
|
2015-03-28 12:47:01 -07:00
|
|
|
deptElevator = function()
|
|
|
|
if (textbox.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
menu.select(0, false)
|
|
|
|
else
|
|
|
|
if (canProgress) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
player.interact("Up")
|
|
|
|
end
|
2014-07-12 18:47:39 -07:00
|
|
|
end,
|
|
|
|
|
|
|
|
swapRepels = function()
|
|
|
|
local repelIdx = inventory.indexOf("super_repel")
|
|
|
|
if (repelIdx < 3) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
local main = memory.value("menu", "main")
|
|
|
|
if (main == 128) then
|
|
|
|
if (menu.getCol() ~= 5) then
|
|
|
|
menu.select(2, true)
|
|
|
|
else
|
|
|
|
local selection = memory.value("menu", "selection_mode")
|
|
|
|
if (selection == 0) then
|
|
|
|
if (menu.select(1, "accelerate", true, nil, true)) then
|
|
|
|
input.press("Select")
|
|
|
|
end
|
|
|
|
else
|
|
|
|
if (menu.select(repelIdx, "accelerate", true, nil, true)) then
|
|
|
|
input.press("Select")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else
|
|
|
|
menu.pause()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
-- 8: FLY
|
|
|
|
|
|
|
|
lavenderRival = function()
|
|
|
|
if (battle.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
local forced
|
|
|
|
if (nidoSpecial > 44) then -- RISK
|
|
|
|
local __, enemyTurns = combat.enemyAttack()
|
|
|
|
if (enemyTurns and enemyTurns < 2 and pokemon.isOpponent("pidgeotto", "gyarados")) then
|
|
|
|
battle.automate()
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if (pokemon.isOpponent("gyarados") or prepare("x_accuracy")) then
|
|
|
|
battle.automate()
|
|
|
|
end
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
input.cancel()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
pokeDoll = function()
|
|
|
|
if (battle.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
inventory.use("pokedoll", nil, true)
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
input.cancel()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
digFight = function()
|
|
|
|
if (battle.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
local backupIndex = pokemon.indexOf("paras", "squirtle")
|
|
|
|
if (pokemon.isDeployed("nidoking")) then
|
|
|
|
if (pokemon.info("nidoking", "hp") == 0) then
|
|
|
|
if (utils.onPokemonSelect(memory.value("battle", "menu"))) then
|
|
|
|
menu.select(backupIndex, true)
|
|
|
|
else
|
|
|
|
input.press("A")
|
|
|
|
end
|
|
|
|
else
|
|
|
|
battle.automate()
|
|
|
|
end
|
|
|
|
elseif (pokemon.info("nidoking", "hp") == 0 and pokemon.index(backupIndex, "hp") == 0 and pokemon.isDeployed("paras", "squirtle")) then
|
|
|
|
return resetDeath()
|
|
|
|
else
|
|
|
|
battle.fight("dig")
|
|
|
|
end
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
textbox.handle()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
thunderboltFirst = function()
|
|
|
|
local forced
|
|
|
|
if (pokemon.isOpponent("zubat")) then
|
|
|
|
canProgress = true
|
|
|
|
forced = "thunderbolt"
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
battle.automate(forced)
|
|
|
|
end,
|
|
|
|
|
|
|
|
-- 8: POKÉFLUTE
|
|
|
|
|
|
|
|
playPokeflute = function()
|
|
|
|
if (battle.isActive()) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
if (memory.value("battle", "menu") == 95) then
|
|
|
|
input.press("A")
|
|
|
|
elseif (menu.pause()) then
|
|
|
|
inventory.use("pokeflute")
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
drivebyRareCandy = function()
|
|
|
|
if (textbox.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
input.cancel()
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
local px, py = player.position()
|
|
|
|
if (py < 13) then
|
|
|
|
tries = 0
|
|
|
|
return
|
|
|
|
end
|
|
|
|
if (py == 13 and tries % 2 == 0) then
|
|
|
|
input.press("A", 2)
|
|
|
|
else
|
|
|
|
input.press("Up")
|
|
|
|
tries = 0
|
|
|
|
end
|
|
|
|
tries = tries + 1
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
safariCarbos = function()
|
|
|
|
if (initialize()) then
|
|
|
|
setYolo("safari_carbos")
|
|
|
|
end
|
|
|
|
local minSpeed = 50
|
|
|
|
if (yolo) then
|
|
|
|
minSpeed = minSpeed - 1
|
|
|
|
end
|
|
|
|
if (nidoSpeed >= minSpeed) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
if (inventory.contains("carbos")) then
|
|
|
|
if (walk.step(20, 20)) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
else
|
|
|
|
local px, py = player.position()
|
|
|
|
if (px < 21) then
|
|
|
|
walk.step(21, py)
|
|
|
|
elseif (px == 21 and py == 13) then
|
|
|
|
player.interact("Left")
|
|
|
|
else
|
|
|
|
walk.step(21, 13)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
centerSkipFullRestore = function()
|
|
|
|
if (initialize()) then
|
|
|
|
if (yolo or inventory.contains("full_restore")) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
local px, py = player.position()
|
|
|
|
if (px < 21) then
|
|
|
|
px = 21
|
|
|
|
elseif (py < 9) then
|
|
|
|
py = 9
|
|
|
|
else
|
|
|
|
return strategyFunctions.interact({dir="Down"})
|
|
|
|
end
|
|
|
|
walk.step(px, py)
|
|
|
|
end,
|
|
|
|
|
|
|
|
silphElevator = function()
|
|
|
|
if (textbox.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
menu.select(9, false, true)
|
|
|
|
else
|
|
|
|
if (canProgress) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
player.interact("Up")
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
fightSilphMachoke = function()
|
|
|
|
if (battle.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
if (nidoSpecial > 44) then
|
|
|
|
return prepare("x_accuracy")
|
|
|
|
end
|
|
|
|
battle.automate("thrash")
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
textbox.handle()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
silphCarbos = function()
|
|
|
|
if (nidoSpeed > 50) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
return strategyFunctions.interact({dir="Left"})
|
|
|
|
end,
|
|
|
|
|
|
|
|
silphRival = function()
|
|
|
|
if (battle.isActive()) then
|
2015-03-28 21:28:58 -07:00
|
|
|
if (initialize()) then
|
|
|
|
tempDir = combat.healthFor("RivalGyarados")
|
|
|
|
print("Gyarados "..tempDir)
|
|
|
|
canProgress = true
|
|
|
|
end
|
|
|
|
local gyaradosDamage = tempDir
|
|
|
|
|
|
|
|
local forced
|
|
|
|
local readyToAttack = false
|
|
|
|
local opName = battle.opponent()
|
|
|
|
if opName == "gyarados" then
|
|
|
|
readyToAttack = true
|
|
|
|
local hp, red_hp = pokemon.index(0, "hp"), redHP()
|
|
|
|
if (hp > gyaradosDamage * 0.98 and hp - gyaradosDamage * 0.975 < red_hp) then --TODO
|
|
|
|
if (prepare("x_special")) then
|
|
|
|
forced = "ice_beam"
|
|
|
|
else
|
|
|
|
readyToAttack = false
|
|
|
|
end
|
|
|
|
elseif (isPrepared("x_special")) then
|
|
|
|
local canPotion
|
|
|
|
if (inventory.contains("potion") and hp + 20 > gyaradosDamage and hp + 20 - gyaradosDamage < red_hp) then
|
|
|
|
canPotion = "potion"
|
|
|
|
elseif (inventory.contains("super_potion") and hp + 50 > gyaradosDamage and hp + 50 - gyaradosDamage < red_hp) then
|
|
|
|
canPotion = "super_potion"
|
|
|
|
end
|
|
|
|
if (canPotion) then
|
|
|
|
inventory.use(canPotion, nil, true)
|
|
|
|
readyToAttack = false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
elseif (prepare("x_accuracy", "x_speed")) then
|
|
|
|
if (opName == "pidgeot") then
|
2014-07-12 18:47:39 -07:00
|
|
|
if (riskGiovanni or nidoSpecial < 45 or pokemon.info("nidoking", "hp") > 85) then
|
|
|
|
forced = "thunderbolt"
|
|
|
|
end
|
2015-03-28 21:28:58 -07:00
|
|
|
elseif (opName == "alakazam" or opName == "growlithe") then
|
2014-07-12 18:47:39 -07:00
|
|
|
forced = "earthquake"
|
|
|
|
end
|
2015-03-28 21:28:58 -07:00
|
|
|
readyToAttack = true
|
|
|
|
end
|
|
|
|
if (readyToAttack) then
|
2014-07-12 18:47:39 -07:00
|
|
|
battle.automate(forced)
|
|
|
|
end
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
textbox.handle()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
fightSilphGiovanni = function()
|
|
|
|
if (battle.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
local forced
|
|
|
|
if (pokemon.isOpponent("nidorino")) then
|
|
|
|
if (battle.pp("horn_drill") > 2) then
|
|
|
|
forced = "horn_drill"
|
|
|
|
else
|
|
|
|
forced = "earthquake"
|
|
|
|
end
|
|
|
|
elseif (pokemon.isOpponent("rhyhorn")) then
|
|
|
|
forced = "ice_beam"
|
|
|
|
elseif (pokemon.isOpponent("kangaskhan")) then
|
|
|
|
forced = "horn_drill"
|
|
|
|
end
|
|
|
|
battle.automate(forced)
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
textbox.handle()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
-- 9: SILPH CO.
|
|
|
|
|
2015-03-28 21:28:58 -07:00
|
|
|
healBeforeHypno = function()
|
|
|
|
local curr_hp, red_hp = pokemon.index(0, "hp"), redHP()
|
|
|
|
local healthUnderRedBar = red_hp - curr_hp
|
|
|
|
local yoloHP = combat.healthFor("HypnoHeadbutt") * 0.9
|
|
|
|
local healTarget
|
|
|
|
local rareCandyCount = inventory.count("rare_candy")
|
|
|
|
local useRareCandy
|
|
|
|
if (healthUnderRedBar >= 0) then
|
|
|
|
healTarget = "HypnoHeadbutt"
|
|
|
|
if (healthUnderRedBar > 2) then
|
|
|
|
if (rareCandyCount > 2) then
|
|
|
|
useRareCandy = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else
|
|
|
|
healTarget = "HypnoConfusion"
|
|
|
|
useRareCandy = rareCandyCount > 2
|
|
|
|
end
|
|
|
|
if useRareCandy then
|
|
|
|
if (menu.pause()) then
|
|
|
|
inventory.use("rare_candy", nil, false)
|
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
return strategyFunctions.potion({hp=healTarget, yolo=yoloHP, close=true})
|
|
|
|
end,
|
|
|
|
|
2014-07-12 18:47:39 -07:00
|
|
|
fightHypno = function()
|
|
|
|
if (battle.isActive()) then
|
|
|
|
local forced
|
|
|
|
if (pokemon.isOpponent("hypno")) then
|
|
|
|
if (pokemon.info("nidoking", "hp") > combat.healthFor("KogaWeezing") * 0.9) then
|
|
|
|
if (combat.isDisabled(85)) then
|
|
|
|
forced = "ice_beam"
|
|
|
|
else
|
|
|
|
forced = "thunderbolt"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
battle.automate(forced)
|
|
|
|
canProgress = true
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
textbox.handle()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
2015-03-28 21:28:58 -07:00
|
|
|
fightKoga = function() --TODO x-accuracy?
|
2014-07-12 18:47:39 -07:00
|
|
|
if (battle.isActive()) then
|
|
|
|
local forced
|
|
|
|
if (pokemon.isOpponent("weezing")) then
|
|
|
|
if (opponentDamaged(2)) then
|
|
|
|
inventory.use("pokeflute", nil, true)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
forced = "thunderbolt"
|
2015-03-28 21:28:58 -07:00
|
|
|
control.canDie(true)
|
2014-07-12 18:47:39 -07:00
|
|
|
end
|
|
|
|
battle.fight(forced)
|
|
|
|
canProgress = true
|
|
|
|
elseif (canProgress) then
|
|
|
|
deepRun = true
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
textbox.handle()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
-- 10: KOGA
|
|
|
|
|
|
|
|
dodgeGirl = function()
|
|
|
|
local gx, gy = memory.raw(0x0223) - 5, memory.raw(0x0222)
|
|
|
|
local px, py = player.position()
|
|
|
|
if (py > gy) then
|
|
|
|
if (px > 3) then
|
|
|
|
px = 3
|
|
|
|
else
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
elseif (gy - py ~= 1 or px ~= gx) then
|
|
|
|
py = py + 1
|
|
|
|
elseif (px == 3) then
|
|
|
|
px = 2
|
|
|
|
else
|
|
|
|
px = 3
|
|
|
|
end
|
|
|
|
walk.step(px, py)
|
|
|
|
end,
|
|
|
|
|
|
|
|
cinnabarCarbos = function()
|
|
|
|
local px, py = player.position()
|
|
|
|
if (px == 21) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
local minSpeed = 51
|
|
|
|
if (yolo) then
|
|
|
|
minSpeed = minSpeed - 1
|
|
|
|
end
|
|
|
|
if (nidoSpeed > minSpeed) then -- TODO >=
|
|
|
|
walk.step(21, 20)
|
|
|
|
else
|
|
|
|
if (py == 20) then
|
|
|
|
py = 21
|
|
|
|
elseif (px == 17 and not inventory.contains("carbos")) then
|
|
|
|
player.interact("Right")
|
|
|
|
return false
|
|
|
|
else
|
|
|
|
px = 21
|
|
|
|
end
|
|
|
|
walk.step(px, py)
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
fightErika = function()
|
|
|
|
if (battle.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
local forced
|
|
|
|
local curr_hp, red_hp = pokemon.index(0, "hp"), redHP()
|
|
|
|
local razorDamage = 34
|
|
|
|
if (curr_hp > razorDamage and curr_hp - razorDamage < red_hp) then
|
|
|
|
if (opponentDamaged()) then
|
|
|
|
forced = "thunderbolt"
|
|
|
|
elseif (nidoSpecial < 45) then
|
|
|
|
forced = "ice_beam"
|
|
|
|
else
|
|
|
|
forced = "thunderbolt"
|
|
|
|
end
|
|
|
|
elseif (riskGiovanni) then
|
|
|
|
forced = "ice_beam"
|
|
|
|
end
|
|
|
|
battle.automate(forced)
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
textbox.handle()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
-- 11: ERIKA
|
|
|
|
|
|
|
|
waitToReceive = function()
|
|
|
|
local main = memory.value("menu", "main")
|
|
|
|
if (main == 128) then
|
|
|
|
if (canProgress) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
elseif (main == 32 or main == 123) then
|
|
|
|
canProgress = true
|
|
|
|
input.cancel()
|
|
|
|
else
|
|
|
|
input.press("Start", 2)
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
-- 14: SABRINA
|
|
|
|
|
|
|
|
earthquakeElixer = function(data)
|
|
|
|
if (battle.pp("earthquake") >= data.min) then
|
|
|
|
if (closeMenuFor(data)) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
if (initialize()) then
|
|
|
|
if (areaName) then
|
|
|
|
print("EQ Elixer: "..areaName)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return useItem({item="elixer", poke="nidoking", chain=data.chain, close=data.close})
|
|
|
|
end,
|
|
|
|
|
|
|
|
checkGiovanni = function()
|
|
|
|
if (initialize()) then
|
|
|
|
local earthquakePP = battle.pp("earthquake")
|
|
|
|
if (earthquakePP > 1) then
|
|
|
|
if (riskGiovanni and earthquakePP > 2 and battle.pp("horn_drill") > 4 and (yolo or pokemon.info("nidoking", "hp") > combat.healthFor("GiovanniRhyhorn") * 0.925)) then -- RISK
|
|
|
|
bridge.chat("Using risky strats on Giovanni to skip the extra Max Ether...")
|
|
|
|
else
|
|
|
|
riskGiovanni = false
|
|
|
|
end
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
local message = "Ran out of Earthquake PP :("
|
|
|
|
if (not yolo) then
|
|
|
|
message = message.." Time for safe strats."
|
|
|
|
end
|
|
|
|
bridge.chat(message)
|
|
|
|
riskGiovanni = false
|
|
|
|
end
|
|
|
|
return strategyFunctions.potion({hp=50, yolo=10})
|
|
|
|
end,
|
|
|
|
|
|
|
|
fightGiovanniMachoke = function(data)
|
|
|
|
return prepare("x_special")
|
|
|
|
end,
|
|
|
|
|
|
|
|
fightGiovanni = function()
|
|
|
|
if (battle.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
if (riskGiovanni and not prepare("x_special")) then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
local forced
|
|
|
|
if (pokemon.isOpponent("rhydon")) then
|
|
|
|
forced = "ice_beam"
|
|
|
|
end
|
|
|
|
battle.automate(forced)
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
textbox.handle()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
-- 15: GIOVANNI
|
|
|
|
|
|
|
|
viridianRival = function()
|
|
|
|
if (battle.isActive()) then
|
|
|
|
if (not canProgress) then
|
|
|
|
if (nidoSpecial < 45 or pokemon.index(0, "speed") < 134) then
|
|
|
|
tempDir = "x_special"
|
|
|
|
else
|
|
|
|
print("Skip X Special strats!")
|
|
|
|
end
|
|
|
|
canProgress = true
|
|
|
|
end
|
|
|
|
if (prepare("x_accuracy", tempDir)) then
|
|
|
|
local forced
|
|
|
|
if (pokemon.isOpponent("pidgeot")) then
|
|
|
|
forced = "thunderbolt"
|
|
|
|
elseif (riskGiovanni) then
|
|
|
|
if (pokemon.isOpponent("rhyhorn") or opponentDamaged()) then
|
|
|
|
forced = "ice_beam"
|
|
|
|
elseif (pokemon.isOpponent("gyarados")) then
|
|
|
|
forced = "thunderbolt"
|
|
|
|
elseif (pokemon.isOpponent("growlithe", "alakazam")) then
|
|
|
|
forced = "earthquake"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
battle.automate(forced)
|
|
|
|
end
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
textbox.handle()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
ether = function(data)
|
|
|
|
local main = memory.value("menu", "main")
|
|
|
|
data.item = tempDir
|
|
|
|
if (tempDir and completedMenuFor(data)) then
|
|
|
|
if (closeMenuFor(data)) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
else
|
|
|
|
if (not tempDir) then
|
|
|
|
if (data.max) then
|
|
|
|
-- TODO don't skip center if not in redbar
|
|
|
|
maxEtherSkip = nidoAttack > 53 and battle.pp("earthquake") > 0 and battle.pp("horn_drill") > 3
|
|
|
|
if (maxEtherSkip) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
bridge.chat("Grabbing the Max Ether to skip the Elite 4 Center")
|
|
|
|
end
|
|
|
|
tempDir = inventory.contains("ether", "max_ether")
|
|
|
|
if (not tempDir) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
tries = inventory.count(tempDir)
|
|
|
|
end
|
|
|
|
if (memory.value("menu", "main") == 144 and menu.getCol() == 5) then
|
|
|
|
if (memory.value("battle", "menu") ~= 95) then
|
|
|
|
menu.select(pokemon.battleMove("horn_drill"), true)
|
|
|
|
else
|
|
|
|
input.cancel()
|
|
|
|
end
|
|
|
|
elseif (menu.pause()) then
|
|
|
|
inventory.use(tempDir, "nidoking")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
pickMaxEther = function()
|
|
|
|
if (not canProgress) then
|
|
|
|
if (maxEtherSkip) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
if (memory.value("player", "moving") == 0) then
|
|
|
|
if (player.isFacing("Right")) then
|
|
|
|
canProgress = true
|
|
|
|
end
|
|
|
|
tries = not tries
|
|
|
|
if (tries) then
|
|
|
|
input.press("Right", 1)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
if (inventory.contains("max_ether")) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
player.interact("Right")
|
|
|
|
end,
|
|
|
|
|
|
|
|
push = function(data)
|
|
|
|
local pos
|
|
|
|
if (data.dir == "Up" or data.dir == "Down") then
|
|
|
|
pos = data.y
|
|
|
|
else
|
|
|
|
pos = data.x
|
|
|
|
end
|
|
|
|
local newP = memory.raw(pos)
|
|
|
|
if (tries == 0) then
|
|
|
|
tries = {start=newP}
|
|
|
|
elseif (tries.start ~= newP) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
input.press(data.dir, 0)
|
|
|
|
end,
|
|
|
|
|
|
|
|
healBeforeLorelei = function()
|
|
|
|
if (initialize()) then
|
|
|
|
local canPotion
|
|
|
|
if (inventory.contains("potion") and hasHealthFor("LoreleiDewgong", 20)) then
|
|
|
|
canPotion = true
|
|
|
|
elseif (inventory.contains("super_potion") and hasHealthFor("LoreleiDewgong", 50)) then
|
|
|
|
canPotion = true
|
|
|
|
end
|
|
|
|
if (not canPotion) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
bridge.chat("Healing before Lorelei to skip the Elite 4 Center...")
|
|
|
|
end
|
|
|
|
return strategyFunctions.potion({hp=combat.healthFor("LoreleiDewgong")})
|
|
|
|
end,
|
|
|
|
|
|
|
|
depositPokemon = function()
|
|
|
|
local toSize
|
|
|
|
if (hasHealthFor("LoreleiDewgong")) then
|
|
|
|
toSize = 1
|
|
|
|
else
|
|
|
|
toSize = 2
|
|
|
|
end
|
|
|
|
if (memory.value("player", "party_size") == toSize) then
|
|
|
|
if (menu.close()) then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
else
|
|
|
|
if (not textbox.isActive()) then
|
|
|
|
player.interact("Up")
|
|
|
|
else
|
|
|
|
local pc = memory.value("menu", "size")
|
|
|
|
if (memory.value("battle", "menu") ~= 95 and (pc == 2 or pc == 4)) then
|
|
|
|
if (menu.getCol() == 10) then
|
|
|
|
input.press("A")
|
|
|
|
else
|
|
|
|
menu.select(1)
|
|
|
|
end
|
|
|
|
else
|
|
|
|
input.press("A")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
centerSkip = function()
|
|
|
|
setYolo("e4center")
|
|
|
|
local message = "Skipping the Center and attempting to redbar "
|
|
|
|
if (hasHealthFor("LoreleiDewgong")) then
|
|
|
|
message = message.."off Lorelei..."
|
|
|
|
else
|
|
|
|
message = message.."the Elite 4!"
|
|
|
|
end
|
|
|
|
bridge.chat(message)
|
|
|
|
return true
|
|
|
|
end,
|
|
|
|
|
|
|
|
lorelei = function()
|
|
|
|
if (battle.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
if (not pokemon.isDeployed("nidoking")) then
|
|
|
|
local battleMenu = memory.value("battle", "menu")
|
|
|
|
if (utils.onPokemonSelect(battleMenu)) then
|
|
|
|
menu.select(0, true)
|
|
|
|
elseif (battleMenu == 95 and menu.getCol() == 1) then
|
|
|
|
input.press("A")
|
|
|
|
else
|
|
|
|
battle.automate()
|
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
if (pokemon.isOpponent("dewgong")) then
|
|
|
|
local sacrifice = pokemon.inParty("pidgey", "spearow", "squirtle", "paras", "oddish")
|
|
|
|
if (sacrifice and pokemon.info(sacrifice, "hp") > 0) then
|
|
|
|
battle.swap(sacrifice)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if (prepare("x_accuracy")) then
|
|
|
|
battle.automate()
|
|
|
|
end
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
textbox.handle()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
-- 16: LORELEI
|
|
|
|
|
|
|
|
bruno = function()
|
|
|
|
if (battle.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
local forced
|
|
|
|
if (pokemon.isOpponent("onix")) then
|
|
|
|
forced = "ice_beam"
|
|
|
|
-- local curr_hp, red_hp = pokemon.info("nidoking", "hp"), redHP()
|
|
|
|
-- if (curr_hp > red_hp) then
|
|
|
|
-- local enemyMove, enemyTurns = combat.enemyAttack()
|
|
|
|
-- if (enemyTurns and enemyTurns > 1) then
|
|
|
|
-- local rockDmg = enemyMove.damage
|
|
|
|
-- if (curr_hp - rockDmg <= red_hp) then
|
|
|
|
-- forced = "thunderbolt"
|
|
|
|
-- end
|
|
|
|
-- end
|
|
|
|
-- end
|
|
|
|
end
|
|
|
|
if (prepare("x_accuracy")) then
|
|
|
|
battle.automate(forced)
|
|
|
|
end
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
textbox.handle()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
2015-03-28 12:47:01 -07:00
|
|
|
agatha = function() --TODO test without x acc
|
2014-07-12 18:47:39 -07:00
|
|
|
if (battle.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
if (combat.isSleeping()) then
|
|
|
|
inventory.use("pokeflute", nil, true)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
if (pokemon.isOpponent("gengar")) then
|
|
|
|
local currentHP = pokemon.info("nidoking", "hp")
|
2015-03-28 12:47:01 -07:00
|
|
|
-- if (not yolo and currentHP <= 56 and not isPrepared("x_speed")) then
|
2014-07-12 18:47:39 -07:00
|
|
|
if (not yolo and currentHP <= 56 and not isPrepared("x_accuracy", "x_speed")) then
|
|
|
|
local toPotion = inventory.contains("full_restore", "super_potion")
|
|
|
|
if (toPotion) then
|
|
|
|
inventory.use(toPotion, nil, true)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
2015-03-28 12:47:01 -07:00
|
|
|
-- if (not prepare("x_speed")) then
|
2014-07-12 18:47:39 -07:00
|
|
|
if (not prepare("x_accuracy", "x_speed")) then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
battle.automate()
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
textbox.handle()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
prepareForLance = function()
|
|
|
|
local enableFull
|
|
|
|
if (hasHealthFor("LanceGyarados", 100)) then
|
|
|
|
enableFull = inventory.count("super_potion") < 2
|
|
|
|
elseif (hasHealthFor("LanceGyarados", 50)) then
|
|
|
|
enableFull = not inventory.contains("super_potion")
|
|
|
|
else
|
|
|
|
enableFull = true
|
|
|
|
end
|
|
|
|
local min_recovery = combat.healthFor("LanceGyarados")
|
|
|
|
return strategyFunctions.potion({hp=min_recovery, full=enableFull, chain=true})
|
|
|
|
end,
|
|
|
|
|
|
|
|
lance = function()
|
2015-03-28 21:28:58 -07:00
|
|
|
local xItem
|
|
|
|
if (pokemon.isOpponent("dragonair")) then
|
|
|
|
xItem = "x_speed"
|
|
|
|
else
|
|
|
|
xItem = "x_special"
|
2014-07-12 18:47:39 -07:00
|
|
|
end
|
2015-03-28 21:28:58 -07:00
|
|
|
return prepare(xItem)
|
2014-07-12 18:47:39 -07:00
|
|
|
end,
|
|
|
|
|
|
|
|
prepareForBlue = function()
|
|
|
|
if (initialize()) then
|
|
|
|
setYolo("blue")
|
|
|
|
end
|
|
|
|
local skyDmg = combat.healthFor("BlueSky")
|
|
|
|
local wingDmg = combat.healthFor("BluePidgeot")
|
|
|
|
return strategyFunctions.potion({hp=skyDmg-50, yolo=wingDmg, full=true})
|
|
|
|
end,
|
|
|
|
|
|
|
|
blue = function()
|
|
|
|
if (battle.isActive()) then
|
|
|
|
canProgress = true
|
|
|
|
if (memory.value("battle", "turns") > 0 and not isPrepared("x_accuracy", "x_speed")) then
|
|
|
|
local toPotion = inventory.contains("full_restore", "super_potion")
|
|
|
|
if (battle.potionsForHit(toPotion)) then
|
|
|
|
inventory.use(toPotion, nil, true)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if (not tempDir) then
|
|
|
|
if (nidoSpecial > 45 and pokemon.index(0, "speed") > 52 and inventory.contains("x_special")) then
|
|
|
|
tempDir = "x_special"
|
|
|
|
else
|
|
|
|
tempDir = "x_speed"
|
|
|
|
end
|
|
|
|
print(tempDir.." strats")
|
|
|
|
tempDir = "x_speed" -- TODO find min stats, remove override
|
|
|
|
end
|
2015-03-28 12:47:01 -07:00
|
|
|
if (prepare("x_accuracy", tempDir)) then
|
2014-07-12 18:47:39 -07:00
|
|
|
local forced = "horn_drill"
|
|
|
|
if (pokemon.isOpponent("alakazam")) then
|
|
|
|
if (tempDir == "x_speed") then
|
|
|
|
forced = "earthquake"
|
|
|
|
end
|
|
|
|
elseif (pokemon.isOpponent("rhydon")) then
|
|
|
|
if (tempDir == "x_special") then
|
|
|
|
forced = "ice_beam"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
battle.automate(forced)
|
|
|
|
end
|
|
|
|
elseif (canProgress) then
|
|
|
|
return true
|
|
|
|
else
|
|
|
|
textbox.handle()
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
champion = function()
|
|
|
|
if (canProgress) then
|
|
|
|
if (tries > 1500) then
|
|
|
|
return hardReset("Beat the game in "..canProgress.." !")
|
|
|
|
end
|
|
|
|
if (tries == 0) then
|
|
|
|
bridge.tweet("Beat Pokemon Red in "..canProgress.."!")
|
2015-01-19 17:11:52 -08:00
|
|
|
-- strategyFunctions.reportFrames()
|
2014-07-12 18:47:39 -07:00
|
|
|
if (strategies.seed) then
|
|
|
|
print(memory.value("game", "frames").." frames, with seed "..strategies.seed)
|
|
|
|
print("Please save this seed number to share, if you would like proof of your run!")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
tries = tries + 1
|
|
|
|
elseif (memory.value("menu", "shop_current") == 252) then
|
|
|
|
strategyFunctions.split({finished=true})
|
|
|
|
canProgress = paint.elapsedTime()
|
|
|
|
else
|
|
|
|
input.cancel()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
}
|
|
|
|
|
|
|
|
function strategies.execute(data)
|
|
|
|
if (strategyFunctions[data.s](data)) then
|
|
|
|
tries = 0
|
|
|
|
canProgress = false
|
|
|
|
initialized = false
|
|
|
|
tempDir = nil
|
|
|
|
if (resetting) then
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
function strategies.init(midGame)
|
2015-01-19 17:11:52 -08:00
|
|
|
if (not STREAMING_MODE) then --TODO remove
|
|
|
|
-- setYolo(0)
|
|
|
|
nidoAttack = 55
|
|
|
|
nidoSpeed = 50
|
|
|
|
nidoSpecial = 45
|
|
|
|
riskGiovanni = true
|
|
|
|
print(nidoAttack.." x "..nidoSpeed.." "..nidoSpecial)
|
|
|
|
end
|
2014-07-12 18:47:39 -07:00
|
|
|
if (midGame) then
|
|
|
|
combat.factorPP(true)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function strategies.softReset()
|
|
|
|
canProgress = false
|
|
|
|
initialized = false
|
|
|
|
maxEtherSkip = false
|
|
|
|
tempDir = nil
|
|
|
|
strategies.moonEncounters = nil
|
|
|
|
tries = 0
|
|
|
|
deepRun = false
|
|
|
|
resetting = nil
|
|
|
|
yolo = false
|
|
|
|
end
|
|
|
|
|
|
|
|
return strategies
|