diff --git a/ai/red/strategies.lua b/ai/red/strategies.lua index 7183498..529c893 100644 --- a/ai/red/strategies.lua +++ b/ai/red/strategies.lua @@ -292,10 +292,6 @@ strategyFunctions.bicycle = function() end end -strategyFunctions.fightXAccuracy = function() - return Strategies.prepare("x_accuracy") -end - -- Route strategyFunctions.squirtleIChooseYou = function() @@ -1168,39 +1164,7 @@ end -- announceFourTurn -strategyFunctions.redbarCubone = function() - if Battle.isActive() then - local forced - status.canProgress = true - if Pokemon.isOpponent("cubone") then - local enemyMove, enemyTurns = Combat.enemyAttack() - if enemyTurns then - local curr_hp, red_hp = Combat.hp(), Combat.redHP() - local clubDmg = enemyMove.damage - local afterHit = curr_hp - clubDmg - red_hp = red_hp - 2 - local acceptableHealth = Control.yolo and -1 or 1 - if afterHit >= acceptableHealth and afterHit < red_hp then - forced = "thunderbolt" - else - afterHit = afterHit - clubDmg - if afterHit > 1 and afterHit < red_hp then - forced = "thunderbolt" - end - end - if forced and Strategies.initialize() then - Bridge.chat("is using Thunderbolt to attempt to redbar off Cubone") - end - end - Control.ignoreMiss = forced ~= nil - end - Battle.automate(forced) - elseif status.canProgress then - return true - else - Battle.automate() - end -end +-- redbarCubone strategyFunctions.undergroundElixer = function() if Strategies.initialize() then @@ -1211,19 +1175,9 @@ strategyFunctions.undergroundElixer = function() return strategyFunctions.interact({dir="Left"}) end -strategyFunctions.shopTM07 = function() - return Shop.transaction{ - direction = "Up", - buy = {{name="horn_drill", index=3}} - } -end +-- shopTM07 -strategyFunctions.shopRepels = function() - return Shop.transaction{ - direction = "Up", - buy = {{name="super_repel", index=3, amount=9}} - } -end +-- shopRepels strategyFunctions.dodgeDepartment = function() if Strategies.initialize() then @@ -1245,43 +1199,13 @@ strategyFunctions.dodgeDepartment = function() Walk.step(dx, dy) end -strategyFunctions.shopPokeDoll = function() - return Shop.transaction{ - direction = "Down", - buy = {{name="pokedoll", index=0}} - } -end +-- shopPokeDoll -strategyFunctions.shopVending = function() - return Shop.vend{ - direction = "Up", - buy = {{name="fresh_water", index=0}, {name="soda_pop", index=1}} - } -end +-- shopVending -strategyFunctions.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 +-- giveWater -strategyFunctions.shopExtraWater = function() - return Shop.vend{ - direction = "Up", - buy = {{name="fresh_water", index=0}} - } -end +-- shopExtraWater strategyFunctions.shopBuffs = function() if Strategies.initialize() then @@ -1306,7 +1230,7 @@ end strategyFunctions.deptElevator = function() if Textbox.isActive() then status.canProgress = true - Menu.select(0, false) + Menu.select(0, false, true) else if status.canProgress then return true @@ -1338,40 +1262,9 @@ strategyFunctions.lavenderRival = function() end end -strategyFunctions.digFight = function() - if Battle.isActive() then - status.canProgress = true - local currentlyDead = Memory.double("battle", "our_hp") == 0 - if currentlyDead then - local backupPokemon = Pokemon.getSacrifice("paras", "squirtle") - if not backupPokemon then - return Strategies.death() - end - if Utils.onPokemonSelect(Memory.value("battle", "menu")) then - Menu.select(Pokemon.indexOf(backupPokemon), true) - else - Input.press("A") - end - else - Battle.automate() - end - elseif status.canProgress then - return true - else - Textbox.handle() - end -end +-- digFight -strategyFunctions.pokeDoll = function() - if Battle.isActive() then - status.canProgress = true - Inventory.use("pokedoll", nil, true) - elseif status.canProgress then - return true - else - Input.cancel() - end -end +-- pokeDoll strategyFunctions.thunderboltFirst = function() local forced @@ -1393,27 +1286,7 @@ end -- playPokeflute -strategyFunctions.drivebyRareCandy = function() - if Textbox.isActive() then - status.canProgress = true - Input.cancel() - elseif status.canProgress then - return true - else - local px, py = Player.position() - if py < 13 then - status.tries = 0 - return - end - if py == 13 and status.tries % 2 == 0 then - Input.press("A", 2) - else - Input.press("Up") - status.tries = 0 - end - status.tries = status.tries + 1 - end -end +-- drivebyRareCandy strategyFunctions.tossInSafari = function() if Inventory.count() <= (Inventory.contains("full_restore") and 18 or 17) then @@ -1422,58 +1295,7 @@ strategyFunctions.tossInSafari = function() return Strategies.tossItem("antidote", "pokeball") end -strategyFunctions.safariCarbos = function() - if Strategies.initialize() then - Strategies.setYolo("safari_carbos") - end - if stats.nidoran.speedDV >= 7 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 - -strategyFunctions.centerSkipFullRestore = function() - if Strategies.initialize() then - if Control.yolo or Inventory.contains("full_restore") then - return true - end - Bridge.chat("needs to grab the backup Full Restore here") - end - local px, py = Player.position() - if px < 21 then - px = 21 - elseif py < 9 then - py = 9 - else - return Strategies.functions.interact({dir="Down"}) - end - Walk.step(px, py) -end - -strategyFunctions.silphElevator = function() - if Textbox.isActive() then - status.canProgress = true - Menu.select(9, false, true) - else - if status.canProgress then - return true - end - Player.interact("Up") - end -end +-- silphElevator strategyFunctions.fightSilphMachoke = function() if Battle.isActive() then @@ -1712,44 +1534,9 @@ end -- 10: KOGA -strategyFunctions.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 +-- dodgeGirl -strategyFunctions.cinnabarCarbos = function() - local px, py = Player.position() - if px == 21 then - return true - end - if stats.nidoran.speedDV >= 10 then - 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 +-- cinnabarCarbos strategyFunctions.fightErika = function() if Battle.isActive() then diff --git a/ai/strategies.lua b/ai/strategies.lua index d9241dd..5c9c32f 100644 --- a/ai/strategies.lua +++ b/ai/strategies.lua @@ -12,6 +12,7 @@ local Input = require "util.input" local Memory = require "util.memory" local Menu = require "util.menu" local Player = require "util.player" +local Shop = require "action.shop" local Utils = require "util.utils" local Inventory = require "storage.inventory" @@ -179,7 +180,7 @@ function Strategies.opponentDamaged(factor) return Memory.double("battle", "opponent_hp") * factor < Memory.double("battle", "opponent_max_hp") end -local function interact(direction) +local function interact(direction, extended) if Battle.handleWild() then if Battle.isActive() then return true @@ -190,7 +191,7 @@ local function interact(direction) end Input.cancel() else - if Player.interact(direction) then + if Player.interact(direction, extended) then status.interacted = true end end @@ -490,7 +491,7 @@ Strategies.functions = { end, talk = function(data) - return interact(data.dir, true) + return interact(data.dir, data.long) end, take = function(data) @@ -647,14 +648,15 @@ Strategies.functions = { celadon = {68, "Down"}, fuchsia = {69, "Down"}, cinnabar = {70, "Down"}, + saffron = {72, "Down"}, } local main = Memory.value("menu", "main") - if main == 228 then - local currentFly = Memory.raw(0x1FEF) + if main == (yellow and 144 or 228) then + local currentCity = Memory.value("game", "fly") local destination = cities[data.dest] local press - if destination[1] - currentFly == 0 then + if destination[1] - currentCity == 0 then press = "A" else press = destination[2] @@ -793,6 +795,10 @@ Strategies.functions = { return Strategies.buffTo("leer", defLimit) end, + fightX = function(data) + return Strategies.prepare("x_"..data.x) + end, + -- ROUTE swapNidoran = function() @@ -1094,12 +1100,156 @@ Strategies.functions = { return true end, - playPokeflute = function() + redbarCubone = function() + if Battle.isActive() then + local forced + status.canProgress = true + if Pokemon.isOpponent("cubone") then + local enemyMove, enemyTurns = Combat.enemyAttack() + if enemyTurns then + local curr_hp, red_hp = Combat.hp(), Combat.redHP() + local clubDmg = enemyMove.damage + local afterHit = curr_hp - clubDmg + red_hp = red_hp - 2 + local acceptableHealth = Control.yolo and -1 or 1 + if afterHit >= acceptableHealth and afterHit < red_hp then + forced = "thunderbolt" + else + afterHit = afterHit - clubDmg + if afterHit > 1 and afterHit < red_hp then + forced = "thunderbolt" + end + end + if forced and Strategies.initialize() then + Bridge.chat("is using Thunderbolt to attempt to redbar off Cubone") + end + end + Control.ignoreMiss = forced ~= nil + end + Battle.automate(forced) + elseif status.canProgress then + return true + else + Battle.automate() + end + end, + + shopTM07 = function() + return Shop.transaction { + direction = "Up", + buy = {{name="horn_drill", index=3}} + } + end, + + shopRepels = function() + local repelCount = yellow and 10 or 9 + return Shop.transaction { + direction = "Up", + buy = {{name="super_repel", index=3, amount=repelCount}} + } + end, + + shopPokeDoll = function() + return Shop.transaction { + direction = "Down", + buy = {{name="pokedoll", index=0}} + } + 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, + + digFight = function() + if Strategies.initialize() then + if Combat.inRedBar() then + Bridge.chat("is using Rock Slide to one-hit these Ghastlies in red-bar (each is 1 in 10 to miss)") + end + end + if Battle.isActive() then + status.canProgress = true + local currentlyDead = Memory.double("battle", "our_hp") == 0 + if currentlyDead then + if not status.died then + status.died = true + Bridge.chat(" Rock Slide missed BibleThump Trying to finish them off with Dig...") + end + local backupPokemon = Pokemon.getSacrifice("paras", "squirtle") + if not backupPokemon then + return Strategies.death() + end + if Menu.onPokemonSelect() then + Menu.select(Pokemon.indexOf(backupPokemon), true) + else + Input.press("A") + end + else + Battle.automate() + end + elseif status.canProgress then + return true + else + Textbox.handle() + end + end, + + pokeDoll = function() + if Battle.isActive() then + status.canProgress = true + -- {s="swap",item="potion",dest="x_special",chain=true}, --TODO yellow + Inventory.use("pokedoll", nil, true) + elseif status.canProgress then + return true + else + Input.cancel() + end + end, + + silphElevator = function() + if Textbox.isActive() then + status.canProgress = true + Menu.select(9, false, true) + else + if status.canProgress then + return true + end + Player.interact("Up") + end + end, + + playPokeFlute = function() if Battle.isActive() then return true end - if Memory.value("battle", "menu") == 95 then - Input.press("A") + if Menu.hasTextbox() then + Input.cancel() elseif Menu.pause() then Inventory.use("pokeflute") end @@ -1121,6 +1271,109 @@ Strategies.functions = { Input.press(data.dir, 0) end, + drivebyRareCandy = function() + if Textbox.isActive() then + status.canProgress = true + Input.cancel() + elseif status.canProgress then + return true + else + local px, py = Player.position() + if py < 13 then + status.tries = 0 + return + end + if py == 13 and status.tries % 2 == 0 then + Input.press("A", 2) + else + Input.press("Up") + status.tries = 0 + end + status.tries = status.tries + 1 + end + end, + + safariCarbos = function() + if Strategies.initialize() then + Strategies.setYolo("safari_carbos") + status.carbos = Inventory.count("carbos") + end + if stats.nidoran.speedDV >= (yellow and 9 or 7) then + return true + end + if Inventory.count("carbos") ~= status.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 Strategies.initialize() then + if Control.yolo or Inventory.contains("full_restore") then + return true + end + Bridge.chat("needs to grab the backup Full Restore here") + end + local px, py = Player.position() + if px < 21 then + px = 21 + elseif py < 9 then + py = 9 + else + return Strategies.functions.interact({dir="Down"}) + end + Walk.step(px, py) + end, + + 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 + if stats.nidoran.speedDV >= 10 then + 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, + } strategyFunctions = Strategies.functions diff --git a/ai/yellow/strategies.lua b/ai/yellow/strategies.lua index 6ecd572..2744806 100644 --- a/ai/yellow/strategies.lua +++ b/ai/yellow/strategies.lua @@ -50,6 +50,10 @@ Strategies.timeRequirements = { return 55 end, + safari_carbos = function() + return 80 + end, + } -- HELPERS @@ -470,6 +474,156 @@ end -- announceFourTurn +-- redbarCubone + +strategyFunctions.deptElevator = function() + if Textbox.isActive() then + status.canProgress = true + Menu.select(4, false, true) + else + if status.canProgress then + return true + end + Player.interact("Up") + end +end + +strategyFunctions.shopBuffs = function() + local xAccs = Strategies.flareon and 10 or 11 + local xSpeeds = Strategies.flareon and 7 or 6 + return Shop.transaction{ + direction = "Right", + sell = {{name="nugget"}}, + buy = {{name="x_accuracy", index=0, amount=xAccs}, {name="x_attack", index=3, amount=3}, {name="x_speed", index=5, amount=xSpeeds}, {name="x_special", index=6, amount=5}}, + } +end + +-- shopVending + +-- giveWater + +-- shopExtraWater + +-- shopPokeDoll + +-- shopTM07 + +-- shopRepels + +strategyFunctions.lavenderRival = function() + if Battle.isActive() then + status.canProgress = true + if Strategies.prepare("x_accuracy") then + Battle.automate() + end + elseif status.canProgress then + return true + else + Input.cancel() + end +end + +-- digFight + +-- pokeDoll + +-- drivebyRareCandy + +-- silphElevator + +strategyFunctions.silphRival = function() + if Battle.isActive() then + if Strategies.initialize() then + status.canProgress = true + end + + if Strategies.prepare("x_accuracy") then + -- Strategies.prepare("x_speed") + local forced, prepare + local opponentName = Battle.opponent() + if opponentName == "sandslash" then + local __, __, turnsToDie = Combat.bestMove() + if turnsToDie and turnsToDie < 2 then + forced = "horn_drill" + else + prepare = true + end + elseif opponentName == "magneton" then + prepare = true + elseif opponentName ~= "kadabra" then + forced = "horn_drill" --TODO necessary? + end + if not prepare or Strategies.prepare("x_speed") then + Battle.automate(forced) + end + end + elseif status.canProgress then + Control.ignoreMiss = false + return true + else + Textbox.handle() + end +end + +-- playPokeflute + +strategyFunctions.tossTM34 = function() + if not Inventory.contains("carbos") then + return true + end + return Strategies.tossItem("tm34") +end + +strategyFunctions.fightKoga = function() + if Battle.isActive() then + if Strategies.prepare("x_accuracy") then + status.canProgress = true + local forced = "horn_drill" + local opponent = Battle.opponent() + if opponent == "venonat" then + if Memory.double("battle", "opponent_hp") == 0 then + status.secondVenonat = true + end + if status.secondVenonat or Combat.isSleeping() then + if not Strategies.prepare("x_speed") then + return false + end + end + end + Battle.automate(forced) + end + elseif status.canProgress then + Strategies.deepRun = true + Control.ignoreMiss = false + return true + else + Textbox.handle() + end +end + +strategyFunctions.fightSabrina = function() + if Battle.isActive() then + status.canProgress = true + if Strategies.prepare("x_accuracy", "x_speed") then + -- local forced = "horn_drill" + -- local opponent = Battle.opponent() + -- if opponent == "venonat" then + -- end + Battle.automate(forced) + end + elseif status.canProgress then + Strategies.deepRun = true + Control.ignoreMiss = false + return true + else + Textbox.handle() + end +end + +-- dodgeGirl + +-- cinnabarCarbos + -- PROCESS function Strategies.initGame(midGame) diff --git a/data/red/paths.lua b/data/red/paths.lua index 4928879..b1b3d8b 100644 --- a/data/red/paths.lua +++ b/data/red/paths.lua @@ -225,7 +225,7 @@ local Paths = { -- Leave Celadon {6, {8,14}, {s="bicycle"}, {8,15}, {2,15}, {2,18}, {-1,18}}, -- Cut out of Celadon - {27, {39,10}, {34,10}, {s="teach",move="horn_drill",replace="bubblebeam",full=true,chain=true}, {s="skill",move="cut",dir="Up",done=0x0D4D}, {34,6}, {27,6}, {27,4}, {23,4}}, + {27, {39,10}, {34,10}, {s="skill",move="cut",dir="Up",done=0x0D4D}, {34,6}, {27,6}, {27,4}, {23,4}}, -- Old man's hall {186, {7,2}, {-1,2}}, -- To the Fly house @@ -252,7 +252,7 @@ local Paths = { -- F6 {147, {18,9}, {18,7}, {15,7}, {15,3}, {11,3}, {11,5}, {10,5}, {s="interact",dir="Left"}, {10,6}, {6,6}, {6,7}, {s="interact",dir="Down"}, {6,14}, {10,14}, {10,16}, {s="pokeDoll"}, {9,16}}, -- F7: Top - {148, {9,16}, {10,16}, {10,9}, {s="fightXAccuracy"}, {c="thrash",disable=false}, {10,7}, {s="thunderboltFirst"}, {10,4}, {s="interact",dir="Up"}}, + {148, {9,16}, {10,16}, {10,9}, {s="fightX",x="accuracy"}, {c="thrash",disable=false}, {10,7}, {s="thunderboltFirst"}, {10,4}, {s="interact",dir="Up"}}, -- Old man's house {149, {3,7}, {3,6}, {2,6}, {2,1}, {s="talk",dir="Right"}, {2,8}}, @@ -267,7 +267,7 @@ local Paths = { -- Leave Celadon {6, {41,10}, {c="a",a="Snorlax"}, {s="item",item="super_repel",chain=true}, {s="bicycle"}, {41,11}, {14,11}, {14,14}, {2,14}, {2,18}, {-1,18}}, -- トトロだ! - {27, {39,10}, {27,10}, {s="swapXSpeeds"}, {s="playPokeflute"}, {23,10}}, + {27, {39,10}, {27,10}, {s="swapXSpeeds"}, {s="playPokeFlute"}, {23,10}}, -- Snorlax pass {186, {7,8}, {-1,8}}, -- Bicycle road @@ -293,7 +293,7 @@ local Paths = { -- Safari 4 {219, {21,0}, {21,5}, {19,5}, {19,6}, {s="interact",dir="Down"}, {19,5}, {7,5}, {7,6}, {3,6}, {3,3}}, -- Warden - {222, {2,7}, {2,6}, {3,6}, {3,4}, {s="confirm",dir="Up"}, {3,8}}, + {222, {2,7}, {2,6}, {3,6}, {3,4}, {s="talk",dir="Up"}, {3,8}}, -- Safari Warp {219, {3,4}, {s="skill",move="dig",map=219}}, -- Celadon again @@ -325,7 +325,7 @@ local Paths = { -- Rival 5 {212, {5,3}, {c="a",a="Silph Rival"}, {4,3}, {4,2}, {3,2}, {c="potion",b=false}, {s="silphRival"}, {3,7}, {c="potion",b=true,yolo=true}, {5,7}}, -- Giovanni - {235, {3,2}, {c="a",a="Silph Giovanni"}, {3,11}, {2,11}, {2,15}, {s="rareCandyGiovanni"}, {2,16}, {s="talk",dir="Right"}, {2,15}, {5,15}, {s="potion",hp=17,yolo=12}, {6,15}, {6,14}, {s="interact",dir="Up"}, {6,13}, {s="fightXAccuracy"}, {s="fightSilphGiovanni"}, {s="split"}, {s="waitToPauseFromBattle"}, {s="skill",move="dig",map=235}}, + {235, {3,2}, {c="a",a="Silph Giovanni"}, {3,11}, {2,11}, {2,15}, {s="rareCandyGiovanni"}, {2,16}, {s="talk",dir="Right"}, {2,15}, {5,15}, {s="potion",hp=17,yolo=12}, {6,15}, {6,14}, {s="interact",dir="Up"}, {6,13}, {s="fightX",x="accuracy"}, {s="fightSilphGiovanni"}, {s="split"}, {s="waitToPauseFromBattle"}, {s="skill",move="dig",map=235}}, -- 11: SILPH CO. diff --git a/util/player.lua b/util/player.lua index ca0c4e9..e66b086 100644 --- a/util/player.lua +++ b/util/player.lua @@ -22,9 +22,9 @@ function Player.face(direction) end end -function Player.interact(direction, instant) +function Player.interact(direction, extended) if Player.face(direction) then - local speed = 2 + local speed = extended and 3 or 2 if yellow and instant then fast = not fast speed = fast and 1 or 2