2015-04-06 01:18:46 -07:00
|
|
|
local Control = {}
|
2014-07-12 18:47:39 -07:00
|
|
|
|
2015-04-09 02:19:46 -07:00
|
|
|
local Battle
|
2015-04-06 01:18:46 -07:00
|
|
|
local Combat = require "ai.combat"
|
|
|
|
local Strategies
|
2014-07-12 18:47:39 -07:00
|
|
|
|
2015-04-06 01:18:46 -07:00
|
|
|
local Bridge = require "util.bridge"
|
|
|
|
local Memory = require "util.memory"
|
|
|
|
local Paint = require "util.paint"
|
|
|
|
local Utils = require "util.utils"
|
2014-07-12 18:47:39 -07:00
|
|
|
|
2015-04-17 13:40:56 -07:00
|
|
|
local Data = require "data.data"
|
2015-04-06 01:18:46 -07:00
|
|
|
local Inventory = require "storage.inventory"
|
|
|
|
local Pokemon = require "storage.pokemon"
|
2014-07-12 18:47:39 -07:00
|
|
|
|
2015-03-28 12:47:01 -07:00
|
|
|
local potionInBattle = true
|
|
|
|
local encounters = 0
|
2014-07-12 18:47:39 -07:00
|
|
|
|
2015-03-28 21:28:58 -07:00
|
|
|
local canDie, shouldFight, minExp
|
2014-07-12 18:47:39 -07:00
|
|
|
local shouldCatch, attackIdx
|
2015-03-28 12:47:01 -07:00
|
|
|
local extraEncounter, maxEncounters
|
2015-04-06 00:50:00 -07:00
|
|
|
local battleYolo
|
2015-04-17 13:40:56 -07:00
|
|
|
local encountersSection
|
2014-07-12 18:47:39 -07:00
|
|
|
|
2015-04-07 05:01:40 -07:00
|
|
|
local yellow = YELLOW
|
|
|
|
|
2015-04-06 01:18:46 -07:00
|
|
|
Control.areaName = "Unknown"
|
2015-04-07 14:46:50 -07:00
|
|
|
Control.getMoonExp = true
|
2015-04-06 01:18:46 -07:00
|
|
|
Control.yolo = false
|
2014-07-12 18:47:39 -07:00
|
|
|
|
2015-04-06 17:29:05 -07:00
|
|
|
local function withinOneKill(forExp)
|
|
|
|
return Pokemon.getExp() + 80 > forExp
|
|
|
|
end
|
|
|
|
|
2014-07-12 18:47:39 -07:00
|
|
|
local controlFunctions = {
|
2015-04-02 10:42:15 -07:00
|
|
|
|
2015-04-05 18:50:30 -07:00
|
|
|
a = function(data)
|
2015-04-06 01:18:46 -07:00
|
|
|
Control.areaName = data.a
|
2015-04-05 18:50:30 -07:00
|
|
|
return true
|
|
|
|
end,
|
|
|
|
|
2014-07-12 18:47:39 -07:00
|
|
|
potion = function(data)
|
2015-03-30 15:29:00 -07:00
|
|
|
if data.b ~= nil then
|
2015-04-06 01:18:46 -07:00
|
|
|
Control.battlePotion(data.b)
|
2014-07-12 18:47:39 -07:00
|
|
|
end
|
|
|
|
battleYolo = data.yolo
|
|
|
|
end,
|
|
|
|
|
|
|
|
encounters = function(data)
|
2015-03-30 15:29:00 -07:00
|
|
|
if RESET_FOR_TIME then
|
2014-07-12 18:47:39 -07:00
|
|
|
maxEncounters = data.limit
|
|
|
|
extraEncounter = data.extra
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
pp = function(data)
|
2015-04-06 01:18:46 -07:00
|
|
|
Combat.factorPP(data.on)
|
2014-07-12 18:47:39 -07:00
|
|
|
end,
|
|
|
|
|
2015-04-11 10:36:22 -07:00
|
|
|
thrash = function(data)
|
2015-04-06 01:18:46 -07:00
|
|
|
Combat.disableThrash = data.disable
|
2014-07-12 18:47:39 -07:00
|
|
|
end,
|
|
|
|
|
|
|
|
disableCatch = function()
|
|
|
|
shouldCatch = nil
|
|
|
|
shouldFight = nil
|
|
|
|
end,
|
|
|
|
|
2015-03-28 12:47:01 -07:00
|
|
|
-- RED
|
2014-07-12 18:47:39 -07:00
|
|
|
|
|
|
|
viridianExp = function()
|
|
|
|
minExp = 210
|
2015-04-14 14:33:17 -07:00
|
|
|
shouldFight = {{name="rattata",levels={2,3}}, {name="pidgey",levels={2}}}
|
2014-07-12 18:47:39 -07:00
|
|
|
end,
|
|
|
|
|
|
|
|
viridianBackupExp = function()
|
|
|
|
minExp = 210
|
2015-04-14 14:33:17 -07:00
|
|
|
shouldFight = {{name="rattata",levels={2,3}}, {name="pidgey",levels={2,3}}}
|
2014-07-12 18:47:39 -07:00
|
|
|
end,
|
|
|
|
|
|
|
|
nidoranBackupExp = function()
|
|
|
|
minExp = 210
|
2015-04-14 14:33:17 -07:00
|
|
|
shouldFight = {{name="rattata"}, {name="pidgey"}, {name="nidoran"}, {name="nidoranf",levels={2}}}
|
2014-07-12 18:47:39 -07:00
|
|
|
end,
|
|
|
|
|
2015-04-17 13:40:56 -07:00
|
|
|
trackEncounters = function(data)
|
|
|
|
local area = data.area
|
|
|
|
if area then
|
|
|
|
encountersSection = "encounters_"..area
|
|
|
|
Data.run[encountersSection] = 0
|
|
|
|
else
|
|
|
|
encountersSection = nil
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
2015-04-07 14:46:50 -07:00
|
|
|
startMtMoon = function()
|
|
|
|
Control.canDie(false)
|
2015-04-14 14:33:17 -07:00
|
|
|
Control.getMoonExp = not yellow
|
2015-04-07 14:46:50 -07:00
|
|
|
end,
|
|
|
|
|
2014-07-12 18:47:39 -07:00
|
|
|
moon1Exp = function()
|
2015-04-07 14:46:50 -07:00
|
|
|
if Control.getMoonExp then
|
|
|
|
minExp = 2704
|
2015-04-15 13:22:02 -07:00
|
|
|
local levels = Strategies.stats.nidoran.level4 and {9,10,11,12} or {10,11,12}
|
2015-04-14 14:33:17 -07:00
|
|
|
shouldFight = {{name="zubat",levels=levels}}
|
2015-04-07 14:46:50 -07:00
|
|
|
oneHits = true
|
|
|
|
end
|
2014-07-12 18:47:39 -07:00
|
|
|
end,
|
|
|
|
|
|
|
|
moon2Exp = function()
|
2015-04-07 14:46:50 -07:00
|
|
|
if Control.getMoonExp then
|
|
|
|
minExp = 3011
|
|
|
|
shouldFight = {{name="zubat"}, {name="paras"}}
|
|
|
|
oneHits = not withinOneKill(minExp)
|
|
|
|
end
|
2014-07-12 18:47:39 -07:00
|
|
|
end,
|
|
|
|
|
|
|
|
moon3Exp = function()
|
2015-04-07 14:46:50 -07:00
|
|
|
if Control.getMoonExp then
|
|
|
|
local expTotal = Pokemon.getExp()
|
|
|
|
minExp = 3798
|
|
|
|
if withinOneKill(minExp) then
|
|
|
|
shouldFight = {{name="zubat"}, {name="paras"}}
|
2015-04-14 14:33:17 -07:00
|
|
|
oneHits = false
|
2015-04-07 14:46:50 -07:00
|
|
|
else
|
|
|
|
shouldFight = nil
|
|
|
|
end
|
2015-04-06 17:29:05 -07:00
|
|
|
end
|
2014-07-12 18:47:39 -07:00
|
|
|
end,
|
|
|
|
|
|
|
|
catchNidoran = function()
|
2015-04-14 14:33:17 -07:00
|
|
|
shouldCatch = {{name="nidoran",levels={3,4}}, {name="spearow"}}
|
2014-07-12 18:47:39 -07:00
|
|
|
end,
|
|
|
|
|
|
|
|
catchFlier = function()
|
|
|
|
shouldCatch = {{name="spearow",alt="pidgey",hp=15}, {name="pidgey",alt="spearow",hp=15}}
|
|
|
|
end,
|
|
|
|
|
|
|
|
catchParas = function()
|
|
|
|
shouldCatch = {{name="paras",hp=16}}
|
|
|
|
end,
|
|
|
|
|
|
|
|
catchOddish = function()
|
|
|
|
shouldCatch = {{name="oddish",alt="paras",hp=26}}
|
|
|
|
end,
|
|
|
|
|
2015-04-07 05:01:40 -07:00
|
|
|
-- YELLOW
|
|
|
|
|
|
|
|
catchNidoranYellow = function()
|
2015-04-14 14:33:17 -07:00
|
|
|
shouldCatch = {{name="nidoran",levels={6}}}
|
2015-04-07 05:01:40 -07:00
|
|
|
end,
|
|
|
|
|
|
|
|
moonExpYellow = function()
|
|
|
|
minExp = 2704 --TODO
|
2015-04-14 14:33:17 -07:00
|
|
|
shouldFight = {{name="geodude"}, {name="clefairy",levels={12,13}}}
|
2015-04-07 05:01:40 -07:00
|
|
|
oneHits = true
|
|
|
|
end,
|
|
|
|
|
|
|
|
catchSandshrew = function()
|
|
|
|
shouldCatch = {{name="sandshrew"}}
|
|
|
|
end,
|
|
|
|
|
2014-07-12 18:47:39 -07:00
|
|
|
}
|
|
|
|
|
2015-03-28 21:28:58 -07:00
|
|
|
-- COMBAT
|
|
|
|
|
2015-04-06 01:18:46 -07:00
|
|
|
function Control.battlePotion(enable)
|
2015-04-05 18:50:30 -07:00
|
|
|
potionInBattle = enable
|
|
|
|
end
|
|
|
|
|
2015-04-06 01:18:46 -07:00
|
|
|
function Control.canDie(enabled)
|
2015-03-28 21:28:58 -07:00
|
|
|
if enabled == nil then
|
|
|
|
return canDie
|
|
|
|
end
|
|
|
|
canDie = enabled
|
|
|
|
end
|
2014-07-12 18:47:39 -07:00
|
|
|
|
|
|
|
local function isNewFight()
|
2015-04-09 02:19:46 -07:00
|
|
|
if Memory.double("battle", "opponent_hp") == Memory.double("battle", "opponent_max_hp") then
|
2014-07-12 18:47:39 -07:00
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-04-06 01:18:46 -07:00
|
|
|
function Control.shouldFight()
|
2015-03-30 15:29:00 -07:00
|
|
|
if not shouldFight then
|
2014-07-12 18:47:39 -07:00
|
|
|
return false
|
|
|
|
end
|
2015-04-06 01:18:46 -07:00
|
|
|
local expTotal = Pokemon.getExp()
|
2015-03-30 15:29:00 -07:00
|
|
|
if expTotal < minExp then
|
2015-04-06 01:18:46 -07:00
|
|
|
local oid = Memory.value("battle", "opponent_id")
|
2015-04-14 14:33:17 -07:00
|
|
|
local opponentLevel = Memory.value("battle", "opponent_level")
|
2014-07-12 18:47:39 -07:00
|
|
|
for i,p in ipairs(shouldFight) do
|
2015-04-14 14:33:17 -07:00
|
|
|
if oid == Pokemon.getID(p.name) and (not p.levels or Utils.match(opponentLevel, p.levels)) then
|
2015-03-30 15:29:00 -07:00
|
|
|
if oneHits then
|
2015-04-06 01:18:46 -07:00
|
|
|
local move = Combat.bestMove()
|
|
|
|
if move and move.maxDamage * 0.925 < Memory.double("battle", "opponent_hp") then
|
2014-07-12 18:47:39 -07:00
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-04-06 01:18:46 -07:00
|
|
|
function Control.canCatch(partySize)
|
2015-03-30 15:29:00 -07:00
|
|
|
if not partySize then
|
2015-04-06 01:18:46 -07:00
|
|
|
partySize = Memory.value("player", "party_size")
|
2014-07-12 18:47:39 -07:00
|
|
|
end
|
2015-04-06 01:18:46 -07:00
|
|
|
local pokeballs = Inventory.count("pokeball")
|
2015-04-07 05:01:40 -07:00
|
|
|
local minimumCount = (yellow and 3 or 4) - partySize
|
2015-03-30 15:29:00 -07:00
|
|
|
if pokeballs < minimumCount then
|
2015-04-11 13:05:47 -07:00
|
|
|
if yellow and Pokemon.inParty("nidoran", "nidorino", "nidoking") and Pokemon.inParty("pidgey", "spearow") then
|
2015-04-10 22:01:56 -07:00
|
|
|
return false
|
|
|
|
end
|
2015-04-17 13:40:56 -07:00
|
|
|
Strategies.reset("pokeballs", "Not enough PokeBalls", pokeballs)
|
2014-07-12 18:47:39 -07:00
|
|
|
return false
|
|
|
|
end
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2015-04-06 01:18:46 -07:00
|
|
|
function Control.shouldCatch(partySize)
|
2015-03-30 15:29:00 -07:00
|
|
|
if maxEncounters and encounters > maxEncounters then
|
2015-04-06 01:18:46 -07:00
|
|
|
local extraCount = extraEncounter and Pokemon.inParty(extraEncounter)
|
2015-03-30 15:29:00 -07:00
|
|
|
if not extraCount or encounters > maxEncounters + 1 then
|
2015-04-17 13:40:56 -07:00
|
|
|
Strategies.reset("encounters", "Too many encounters", encounters)
|
2014-07-12 18:47:39 -07:00
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
2015-03-30 15:29:00 -07:00
|
|
|
if not shouldCatch then
|
2014-07-12 18:47:39 -07:00
|
|
|
return false
|
|
|
|
end
|
2015-04-13 01:18:28 -07:00
|
|
|
if yellow and not Inventory.contains("pokeball") then
|
|
|
|
return false
|
|
|
|
end
|
2015-03-30 15:29:00 -07:00
|
|
|
if not partySize then
|
2015-04-06 01:18:46 -07:00
|
|
|
partySize = Memory.value("player", "party_size")
|
2014-07-12 18:47:39 -07:00
|
|
|
end
|
2015-03-30 15:29:00 -07:00
|
|
|
if partySize == 4 then
|
2014-07-12 18:47:39 -07:00
|
|
|
shouldCatch = nil
|
|
|
|
return false
|
|
|
|
end
|
2015-04-06 01:18:46 -07:00
|
|
|
if not Control.canCatch(partySize) then
|
2014-07-12 18:47:39 -07:00
|
|
|
return true
|
|
|
|
end
|
2015-04-06 01:18:46 -07:00
|
|
|
local oid = Memory.value("battle", "opponent_id")
|
2015-04-14 14:33:17 -07:00
|
|
|
local opponentLevel = Memory.value("battle", "opponent_level")
|
2014-07-12 18:47:39 -07:00
|
|
|
for i,poke in ipairs(shouldCatch) do
|
2015-04-06 01:18:46 -07:00
|
|
|
if oid == Pokemon.getID(poke.name) and not Pokemon.inParty(poke.name, poke.alt) then
|
2015-04-14 14:33:17 -07:00
|
|
|
if not poke.levels or Utils.match(opponentLevel, poke.levels) then
|
2015-04-06 01:18:46 -07:00
|
|
|
local penultimate = poke.hp and Memory.double("battle", "opponent_hp") > poke.hp
|
2015-03-30 15:29:00 -07:00
|
|
|
if penultimate then
|
2015-04-06 01:18:46 -07:00
|
|
|
penultimate = Combat.nonKill()
|
2014-07-12 18:47:39 -07:00
|
|
|
end
|
2015-03-30 15:29:00 -07:00
|
|
|
if penultimate then
|
2015-04-09 16:53:56 -07:00
|
|
|
require("action.battle").fight(penultimate.midx)
|
2014-07-12 18:47:39 -07:00
|
|
|
else
|
2015-04-06 01:18:46 -07:00
|
|
|
Inventory.use("pokeball", nil, true)
|
2014-07-12 18:47:39 -07:00
|
|
|
end
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Items
|
|
|
|
|
2015-04-06 01:18:46 -07:00
|
|
|
function Control.canRecover()
|
2015-04-15 11:17:52 -07:00
|
|
|
return potionInBattle and (not battleYolo or not Control.yolo) and Pokemon.mainFighter()
|
2014-07-12 18:47:39 -07:00
|
|
|
end
|
|
|
|
|
2015-04-06 01:18:46 -07:00
|
|
|
function Control.set(data)
|
2015-04-14 14:33:17 -07:00
|
|
|
local controlFunction = controlFunctions[data.c]
|
|
|
|
if controlFunction then
|
|
|
|
controlFunction(data)
|
|
|
|
else
|
|
|
|
p("INVALID CONTROL", data.c, GAME_NAME)
|
|
|
|
end
|
2014-07-12 18:47:39 -07:00
|
|
|
end
|
|
|
|
|
2015-04-06 01:18:46 -07:00
|
|
|
function Control.setYolo(enabled)
|
|
|
|
Control.yolo = enabled
|
2014-07-12 18:47:39 -07:00
|
|
|
end
|
|
|
|
|
2015-04-06 01:18:46 -07:00
|
|
|
function Control.setPotion(enabled)
|
2015-01-19 17:11:52 -08:00
|
|
|
potionInBattle = enabled
|
2014-07-12 18:47:39 -07:00
|
|
|
end
|
|
|
|
|
2015-04-06 01:18:46 -07:00
|
|
|
function Control.encounters()
|
2014-07-12 18:47:39 -07:00
|
|
|
return encounters
|
|
|
|
end
|
|
|
|
|
2015-04-09 16:47:41 -07:00
|
|
|
function Control.encounter(battleState)
|
|
|
|
if battleState > 0 then
|
|
|
|
local wildBattle = battleState == 1
|
|
|
|
local isCritical
|
|
|
|
local battleMenu = Memory.value("battle", "menu")
|
|
|
|
if battleMenu == 94 then
|
|
|
|
isCritical = false
|
|
|
|
Control.missed = false
|
|
|
|
elseif Memory.double("battle", "our_hp") == 0 then
|
|
|
|
if Memory.value("battle", "critical") == 1 then
|
|
|
|
isCritical = true
|
|
|
|
end
|
|
|
|
elseif not Control.missed then
|
|
|
|
local turnMarker = Memory.value("battle", "our_turn")
|
|
|
|
if turnMarker == 100 or turnMarker == 128 then
|
|
|
|
local isMiss = Memory.value("battle", "miss") == 1
|
|
|
|
if isMiss then
|
2015-04-10 00:34:50 -07:00
|
|
|
if not Control.ignoreMiss and Battle.accurateAttack and Memory.value("battle", "accuracy") == 7 then
|
|
|
|
Bridge.chat("gen 1 missed :( (1 in 256 chance)")
|
2015-04-09 16:47:41 -07:00
|
|
|
end
|
|
|
|
Control.missed = true
|
2015-04-17 13:40:56 -07:00
|
|
|
Data.increment("misses")
|
2015-04-09 02:19:46 -07:00
|
|
|
end
|
|
|
|
end
|
2015-04-09 16:47:41 -07:00
|
|
|
end
|
|
|
|
if isCritical ~= nil and isCritical ~= Control.criticaled then
|
|
|
|
Control.criticaled = isCritical
|
2015-04-17 13:40:56 -07:00
|
|
|
Data.increment("criticals")
|
2015-04-09 16:47:41 -07:00
|
|
|
end
|
|
|
|
if wildBattle then
|
2015-04-15 11:16:02 -07:00
|
|
|
local opponentAlive = Battle.opponentAlive()
|
2015-04-09 16:47:41 -07:00
|
|
|
if not Control.inBattle then
|
2015-04-15 11:16:02 -07:00
|
|
|
if opponentAlive then
|
2015-04-09 16:47:41 -07:00
|
|
|
Control.killedCatch = false
|
|
|
|
Control.inBattle = true
|
|
|
|
encounters = encounters + 1
|
|
|
|
Paint.wildEncounters(encounters)
|
|
|
|
Bridge.encounter()
|
2015-04-17 13:40:56 -07:00
|
|
|
if encountersSection then
|
|
|
|
Data.increment(encountersSection)
|
|
|
|
|
|
|
|
if Pokemon.isOpponent("zubat") then
|
|
|
|
local zubatCount = Data.increment("encounters_zubats")
|
|
|
|
Data.run.encounters_zubats = zubatCount
|
|
|
|
if INTERNAL and STREAMING_MODE then
|
|
|
|
Bridge.chat(Utils.multiplyString("NightBat", zubatCount))
|
|
|
|
end
|
2015-04-10 22:01:56 -07:00
|
|
|
end
|
2015-04-09 16:47:41 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
else
|
2015-04-15 11:16:02 -07:00
|
|
|
if not opponentAlive and shouldCatch and not Control.killedCatch then
|
2015-04-09 16:47:41 -07:00
|
|
|
local gottaCatchEm = {"pidgey", "spearow", "paras", "oddish"}
|
|
|
|
local opponent = Battle.opponent()
|
|
|
|
for i,catch in ipairs(gottaCatchEm) do
|
|
|
|
if opponent == catch then
|
|
|
|
if not Pokemon.inParty(catch) then
|
2015-04-14 14:33:17 -07:00
|
|
|
local criticaled = Memory.value("battle", "critical") == 1
|
|
|
|
Bridge.chat("accidentally killed "..Utils.capitalize(catch).." with a "..(criticaled and "critical" or "high damage range").." :(")
|
2015-04-09 16:47:41 -07:00
|
|
|
Control.killedCatch = true
|
|
|
|
end
|
|
|
|
break
|
2015-04-09 02:19:46 -07:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2015-04-09 16:47:41 -07:00
|
|
|
elseif Control.inBattle then
|
|
|
|
Control.inBattle = false
|
2015-04-10 11:30:26 -07:00
|
|
|
Control.escaped = Memory.value("battle", "battle_turns") == 0
|
2015-04-06 00:50:00 -07:00
|
|
|
end
|
2014-07-12 18:47:39 -07:00
|
|
|
end
|
|
|
|
|
2015-04-06 01:18:46 -07:00
|
|
|
function Control.reset()
|
2015-03-28 21:28:58 -07:00
|
|
|
canDie = false
|
2014-07-12 18:47:39 -07:00
|
|
|
oneHits = false
|
|
|
|
shouldCatch = nil
|
|
|
|
shouldFight = nil
|
|
|
|
extraEncounter = nil
|
2015-01-19 17:11:52 -08:00
|
|
|
potionInBattle = true
|
2014-07-12 18:47:39 -07:00
|
|
|
encounters = 0
|
|
|
|
battleYolo = false
|
|
|
|
maxEncounters = nil
|
2015-04-09 02:19:46 -07:00
|
|
|
|
|
|
|
Control.yolo = false
|
|
|
|
Control.inBattle = false
|
2015-04-15 01:38:51 -07:00
|
|
|
Control.preferredPotion = nil
|
2014-07-12 18:47:39 -07:00
|
|
|
end
|
|
|
|
|
2015-04-06 01:18:46 -07:00
|
|
|
function Control.init()
|
2015-04-09 02:19:46 -07:00
|
|
|
Battle = require("action.battle")
|
2015-04-06 01:18:46 -07:00
|
|
|
Strategies = require("ai."..GAME_NAME..".strategies")
|
2015-04-06 00:50:00 -07:00
|
|
|
end
|
|
|
|
|
2015-04-06 01:18:46 -07:00
|
|
|
return Control
|