mirror of
https://github.com/smogon/pokemon-showdown.git
synced 2026-04-25 07:22:09 -05:00
Add Pokemon GO support (#9646)
This commit is contained in:
parent
66824f09a6
commit
01e35f4f2d
983
data/pokemongo.ts
Normal file
983
data/pokemongo.ts
Normal file
|
|
@ -0,0 +1,983 @@
|
|||
/**
|
||||
* A listing of every Pokemon that can be obtained from Pokemon GO and how the can be obtained.
|
||||
* If a Pokemon is not listed here, it cannot be obtained from Pokemon GO.
|
||||
*
|
||||
* Key:
|
||||
* - Origin:
|
||||
* - wild: Can be found in the overworld, either as a regular spawn or through a similar source such as GO Snapshot
|
||||
* - egg: Hatches from 2, 5, or 10 km eggs
|
||||
* - giovanni: Shadow Pokemon rescued from Giovanni and purified
|
||||
* - 12kmegg: Hatches from a 12 km egg, which is obtained from Team GO Rocket Leaders which unlock at level 8
|
||||
* - raid: Caught from defeating a raid boss
|
||||
* - research: Reward from field research, special research, or research breakthrough
|
||||
* If the Pokemon is obtainable from the wild, other sources do not need to be included due to redundancy.
|
||||
* For shinies that can't be obtained from the wild, all other sources should be included.
|
||||
*
|
||||
* - Shiny origin restrictions:
|
||||
* - noshiny: This Pokemon's shiny form is unavailable in Pokemon GO
|
||||
* - nowildshiny: This Pokemon can't be obtained as shiny from the wild
|
||||
*
|
||||
* - Trade restrictions:
|
||||
* - notrade: This Pokemon cannot be traded at all
|
||||
* - specialtrade: This Pokemon must be traded in a special trade
|
||||
*
|
||||
* Certain sources have been excluded from this list, which are:
|
||||
* - GO Battle League: same level and IV floor as raid bosses, and all from GO Battle League have also been in raids
|
||||
* - Shadow Pokemon: most can also be obtained from the wild, and those that can't are from defeating Giovanni, which
|
||||
* is handled as as its own encounter
|
||||
*/
|
||||
export const PokemonGoData: {[source: string]: PokemonGoData} = {
|
||||
bulbasaur: {encounters: ['wild']},
|
||||
ivysaur: {encounters: ['wild']},
|
||||
venusaur: {encounters: ['wild']},
|
||||
charmander: {encounters: ['wild']},
|
||||
charmeleon: {encounters: ['wild']},
|
||||
charizard: {encounters: ['wild']},
|
||||
squirtle: {encounters: ['wild']},
|
||||
wartortle: {encounters: ['wild']},
|
||||
blastoise: {encounters: ['wild']},
|
||||
caterpie: {encounters: ['wild']},
|
||||
metapod: {encounters: ['wild']},
|
||||
butterfree: {encounters: ['wild']},
|
||||
weedle: {encounters: ['wild']},
|
||||
kakuna: {encounters: ['wild']},
|
||||
beedrill: {encounters: ['wild']},
|
||||
pidgey: {encounters: ['wild']},
|
||||
pidgeotto: {encounters: ['wild']},
|
||||
pidgeot: {encounters: ['wild']},
|
||||
rattata: {encounters: ['wild']},
|
||||
rattataalola: {encounters: ['wild']},
|
||||
raticate: {encounters: ['wild']},
|
||||
raticatealola: {encounters: ['wild']},
|
||||
spearow: {encounters: ['wild']},
|
||||
fearow: {encounters: ['wild']},
|
||||
ekans: {encounters: ['wild']},
|
||||
arbok: {encounters: ['wild']},
|
||||
pikachu: {encounters: ['wild']},
|
||||
raichu: {encounters: ['wild']},
|
||||
raichualola: {encounters: ['wild']},
|
||||
sandshrew: {encounters: ['wild']},
|
||||
sandshrewalola: {encounters: ['wild']},
|
||||
sandslash: {encounters: ['wild']},
|
||||
sandslashalola: {encounters: ['wild']},
|
||||
nidoranf: {encounters: ['wild']},
|
||||
nidorina: {encounters: ['wild']},
|
||||
nidoqueen: {encounters: ['wild']},
|
||||
nidoranm: {encounters: ['wild']},
|
||||
nidorino: {encounters: ['wild']},
|
||||
nidoking: {encounters: ['wild']},
|
||||
clefairy: {encounters: ['wild']},
|
||||
clefable: {encounters: ['wild']},
|
||||
vulpix: {encounters: ['wild']},
|
||||
vulpixalola: {encounters: ['wild']},
|
||||
ninetales: {encounters: ['wild']},
|
||||
ninetalesalola: {encounters: ['wild']},
|
||||
jigglypuff: {encounters: ['wild']},
|
||||
wigglytuff: {encounters: ['wild']},
|
||||
zubat: {encounters: ['wild']},
|
||||
golbat: {encounters: ['wild']},
|
||||
oddish: {encounters: ['wild']},
|
||||
gloom: {encounters: ['wild']},
|
||||
vileplume: {encounters: ['wild']},
|
||||
paras: {encounters: ['wild']},
|
||||
parasect: {encounters: ['wild']},
|
||||
venonat: {encounters: ['wild']},
|
||||
venomoth: {encounters: ['wild']},
|
||||
diglett: {encounters: ['wild']},
|
||||
diglettalola: {encounters: ['wild']},
|
||||
dugtrio: {encounters: ['wild']},
|
||||
dugtrioalola: {encounters: ['wild']},
|
||||
meowth: {encounters: ['wild']},
|
||||
meowthalola: {encounters: ['wild']},
|
||||
meowthgalar: {encounters: ['wild']},
|
||||
persian: {encounters: ['wild']},
|
||||
persianalola: {encounters: ['wild']},
|
||||
psyduck: {encounters: ['wild']},
|
||||
golduck: {encounters: ['wild']},
|
||||
mankey: {encounters: ['wild']},
|
||||
primeape: {encounters: ['wild']},
|
||||
growlithe: {encounters: ['wild']},
|
||||
growlithehisui: {encounters: ['egg', 'raid', 'research', 'noshiny']}, // wild encounter available on 2023-08-26
|
||||
arcanine: {encounters: ['wild']},
|
||||
arcaninehisui: {encounters: ['egg', 'raid', 'research', 'noshiny']}, // wild encounter available on 2023-08-26
|
||||
poliwag: {encounters: ['wild']},
|
||||
poliwhirl: {encounters: ['wild']},
|
||||
poliwrath: {encounters: ['wild']},
|
||||
abra: {encounters: ['wild']},
|
||||
kadabra: {encounters: ['wild']},
|
||||
alakazam: {encounters: ['wild']},
|
||||
machop: {encounters: ['wild']},
|
||||
machoke: {encounters: ['wild']},
|
||||
machamp: {encounters: ['wild']},
|
||||
bellsprout: {encounters: ['wild']},
|
||||
weepinbell: {encounters: ['wild']},
|
||||
victreebel: {encounters: ['wild']},
|
||||
tentacool: {encounters: ['wild']},
|
||||
tentacruel: {encounters: ['wild']},
|
||||
geodude: {encounters: ['wild']},
|
||||
geodudealola: {encounters: ['wild']},
|
||||
graveler: {encounters: ['wild']},
|
||||
graveleralola: {encounters: ['wild']},
|
||||
golem: {encounters: ['wild']},
|
||||
golemalola: {encounters: ['wild']},
|
||||
ponyta: {encounters: ['wild']},
|
||||
ponytagalar: {encounters: ['wild']},
|
||||
rapidash: {encounters: ['wild']},
|
||||
rapidashgalar: {encounters: ['wild']},
|
||||
slowpoke: {encounters: ['wild']},
|
||||
slowpokegalar: {encounters: ['wild']},
|
||||
slowbro: {encounters: ['wild']},
|
||||
slowbrogalar: {encounters: ['wild']},
|
||||
magnemite: {encounters: ['wild']},
|
||||
magneton: {encounters: ['wild']},
|
||||
farfetchd: {encounters: ['wild']},
|
||||
farfetchdgalar: {encounters: ['wild']},
|
||||
doduo: {encounters: ['wild']},
|
||||
dodrio: {encounters: ['wild']},
|
||||
seel: {encounters: ['wild']},
|
||||
dewgong: {encounters: ['wild']},
|
||||
grimer: {encounters: ['wild']},
|
||||
grimeralola: {encounters: ['wild']},
|
||||
muk: {encounters: ['wild']},
|
||||
mukalola: {encounters: ['wild']},
|
||||
shellder: {encounters: ['wild']},
|
||||
cloyster: {encounters: ['wild']},
|
||||
gastly: {encounters: ['wild']},
|
||||
haunter: {encounters: ['wild']},
|
||||
gengar: {encounters: ['wild']},
|
||||
onix: {encounters: ['wild']},
|
||||
drowzee: {encounters: ['wild']},
|
||||
hypno: {encounters: ['wild']},
|
||||
krabby: {encounters: ['wild']},
|
||||
kingler: {encounters: ['wild']},
|
||||
voltorb: {encounters: ['wild']},
|
||||
voltorbhisui: {encounters: ['wild', 'noshiny']},
|
||||
electrode: {encounters: ['wild']},
|
||||
electrodehisui: {encounters: ['wild', 'noshiny']},
|
||||
exeggcute: {encounters: ['wild']},
|
||||
exeggutor: {encounters: ['wild']},
|
||||
exeggutoralola: {encounters: ['wild']},
|
||||
cubone: {encounters: ['wild']},
|
||||
marowak: {encounters: ['wild']},
|
||||
marowakalola: {encounters: ['wild']},
|
||||
hitmonlee: {encounters: ['wild']},
|
||||
hitmonchan: {encounters: ['wild']},
|
||||
lickitung: {encounters: ['wild']},
|
||||
koffing: {encounters: ['wild']},
|
||||
weezing: {encounters: ['wild']},
|
||||
weezinggalar: {encounters: ['wild']},
|
||||
rhyhorn: {encounters: ['wild']},
|
||||
rhydon: {encounters: ['wild']},
|
||||
chansey: {encounters: ['wild']},
|
||||
tangela: {encounters: ['wild']},
|
||||
kangaskhan: {encounters: ['wild']},
|
||||
horsea: {encounters: ['wild']},
|
||||
seadra: {encounters: ['wild']},
|
||||
goldeen: {encounters: ['wild']},
|
||||
seaking: {encounters: ['wild']},
|
||||
staryu: {encounters: ['wild']},
|
||||
starmie: {encounters: ['wild']},
|
||||
mrmime: {encounters: ['wild']},
|
||||
mrmimegalar: {encounters: ['wild']},
|
||||
scyther: {encounters: ['wild']},
|
||||
jynx: {encounters: ['wild']},
|
||||
electabuzz: {encounters: ['wild']},
|
||||
magmar: {encounters: ['wild']},
|
||||
pinsir: {encounters: ['wild']},
|
||||
tauros: {encounters: ['wild']},
|
||||
magikarp: {encounters: ['wild']},
|
||||
gyarados: {encounters: ['wild']},
|
||||
ditto: {encounters: ['wild']},
|
||||
eevee: {encounters: ['wild']},
|
||||
vaporeon: {encounters: ['wild']},
|
||||
jolteon: {encounters: ['wild']},
|
||||
flareon: {encounters: ['wild']},
|
||||
porygon: {encounters: ['wild']},
|
||||
omanyte: {encounters: ['wild']},
|
||||
omastar: {encounters: ['wild']},
|
||||
kabuto: {encounters: ['wild']},
|
||||
kabutops: {encounters: ['wild']},
|
||||
aerodactyl: {encounters: ['wild']},
|
||||
snorlax: {encounters: ['wild']},
|
||||
articuno: {encounters: ['wild']},
|
||||
articunogalar: {encounters: ['wild']},
|
||||
zapdos: {encounters: ['wild']},
|
||||
zapdosgalar: {encounters: ['wild']},
|
||||
moltres: {encounters: ['wild']},
|
||||
moltresgalar: {encounters: ['wild']},
|
||||
dratini: {encounters: ['wild']},
|
||||
dragonair: {encounters: ['wild']},
|
||||
dragonite: {encounters: ['wild']},
|
||||
mewtwo: {
|
||||
encounters: ['giovanni', 'raid', 'research', 'specialtrade'],
|
||||
LGPERestrictiveMoves: {
|
||||
amnesia: 44,
|
||||
swift: 33,
|
||||
psybeam: 22,
|
||||
mist: 11,
|
||||
teleport: 1,
|
||||
confuseray: 1,
|
||||
confusion: 1,
|
||||
disable: 1,
|
||||
},
|
||||
},
|
||||
mew: {
|
||||
encounters: ['research', 'notrade'],
|
||||
LGPERestrictiveMoves: {
|
||||
barrier: 44,
|
||||
psywave: 33,
|
||||
amnesia: 22,
|
||||
swift: 11,
|
||||
pound: 1,
|
||||
confusion: 1,
|
||||
mimic: 1,
|
||||
},
|
||||
},
|
||||
chikorita: {encounters: ['wild']},
|
||||
bayleef: {encounters: ['wild']},
|
||||
meganium: {encounters: ['wild']},
|
||||
cyndaquil: {encounters: ['wild']},
|
||||
quilava: {encounters: ['wild']},
|
||||
typhlosion: {encounters: ['wild']},
|
||||
totodile: {encounters: ['wild']},
|
||||
croconaw: {encounters: ['wild']},
|
||||
feraligatr: {encounters: ['wild']},
|
||||
sentret: {encounters: ['wild']},
|
||||
furret: {encounters: ['wild']},
|
||||
hoothoot: {encounters: ['wild']},
|
||||
noctowl: {encounters: ['wild']},
|
||||
ledyba: {encounters: ['wild']},
|
||||
ledian: {encounters: ['wild']},
|
||||
spinarak: {encounters: ['wild']},
|
||||
ariados: {encounters: ['wild']},
|
||||
crobat: {encounters: ['wild']},
|
||||
chinchou: {encounters: ['wild']},
|
||||
lanturn: {encounters: ['wild']},
|
||||
pichu: {encounters: ['egg']},
|
||||
cleffa: {encounters: ['egg']},
|
||||
igglybuff: {encounters: ['egg']},
|
||||
togepi: {encounters: ['egg']},
|
||||
togetic: {encounters: ['wild']},
|
||||
natu: {encounters: ['wild']},
|
||||
xatu: {encounters: ['wild']},
|
||||
mareep: {encounters: ['wild']},
|
||||
flaaffy: {encounters: ['wild']},
|
||||
ampharos: {encounters: ['wild']},
|
||||
bellossom: {encounters: ['wild']},
|
||||
marill: {encounters: ['wild']},
|
||||
azumarill: {encounters: ['wild']},
|
||||
sudowoodo: {encounters: ['wild']},
|
||||
politoed: {encounters: ['wild']},
|
||||
hoppip: {encounters: ['wild']},
|
||||
skiploom: {encounters: ['wild']},
|
||||
jumpluff: {encounters: ['wild']},
|
||||
aipom: {encounters: ['wild']},
|
||||
sunkern: {encounters: ['wild']},
|
||||
sunflora: {encounters: ['wild']},
|
||||
yanma: {encounters: ['wild']},
|
||||
wooper: {encounters: ['wild']},
|
||||
quagsire: {encounters: ['wild']},
|
||||
espeon: {encounters: ['wild']},
|
||||
umbreon: {encounters: ['wild']},
|
||||
murkrow: {encounters: ['wild']},
|
||||
slowking: {encounters: ['wild']},
|
||||
slowkinggalar: {encounters: ['wild']},
|
||||
misdreavus: {encounters: ['wild']},
|
||||
unown: {encounters: ['wild']},
|
||||
unownb: {encounters: ['wild']},
|
||||
unownc: {encounters: ['wild']},
|
||||
unownd: {encounters: ['wild']},
|
||||
unowne: {encounters: ['wild']},
|
||||
unownf: {encounters: ['wild']},
|
||||
unowng: {encounters: ['wild']},
|
||||
unownh: {encounters: ['wild']},
|
||||
unowni: {encounters: ['wild']},
|
||||
unownj: {encounters: ['wild']},
|
||||
unownk: {encounters: ['wild', 'noshiny']},
|
||||
unownl: {encounters: ['wild']},
|
||||
unownm: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-04
|
||||
unownn: {encounters: ['wild']},
|
||||
unowno: {encounters: ['wild']},
|
||||
unownp: {encounters: ['wild']},
|
||||
unownq: {encounters: ['wild', 'noshiny']},
|
||||
unownr: {encounters: ['wild']},
|
||||
unowns: {encounters: ['wild']},
|
||||
unownt: {encounters: ['wild']},
|
||||
unownu: {encounters: ['wild']},
|
||||
unownv: {encounters: ['wild']},
|
||||
unownw: {encounters: ['wild', 'noshiny']},
|
||||
unownx: {encounters: ['wild']},
|
||||
unowny: {encounters: ['wild']},
|
||||
unownz: {encounters: ['wild', 'noshiny']},
|
||||
unownexclamation: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-04
|
||||
unownquestion: {encounters: ['wild', 'noshiny']},
|
||||
wobbuffet: {encounters: ['wild']},
|
||||
girafarig: {encounters: ['wild']},
|
||||
pineco: {encounters: ['wild']},
|
||||
forretress: {encounters: ['wild']},
|
||||
dunsparce: {encounters: ['wild']},
|
||||
gligar: {encounters: ['wild']},
|
||||
steelix: {encounters: ['wild']},
|
||||
snubbull: {encounters: ['wild']},
|
||||
granbull: {encounters: ['wild']},
|
||||
qwilfish: {encounters: ['wild']},
|
||||
qwilfishhisui: {encounters: ['wild', 'noshiny']},
|
||||
scizor: {encounters: ['wild']},
|
||||
shuckle: {encounters: ['wild']},
|
||||
heracross: {encounters: ['wild']},
|
||||
sneasel: {encounters: ['wild']},
|
||||
sneaselhisui: {encounters: ['wild', 'noshiny']},
|
||||
teddiursa: {encounters: ['wild']},
|
||||
ursaring: {encounters: ['wild']},
|
||||
slugma: {encounters: ['wild']},
|
||||
magcargo: {encounters: ['wild']},
|
||||
swinub: {encounters: ['wild']},
|
||||
piloswine: {encounters: ['wild']},
|
||||
corsola: {encounters: ['wild']},
|
||||
remoraid: {encounters: ['wild']},
|
||||
octillery: {encounters: ['wild']},
|
||||
delibird: {encounters: ['wild']},
|
||||
mantine: {encounters: ['wild']},
|
||||
skarmory: {encounters: ['wild']},
|
||||
houndour: {encounters: ['wild']},
|
||||
houndoom: {encounters: ['wild']},
|
||||
kingdra: {encounters: ['wild']},
|
||||
phanpy: {encounters: ['wild']},
|
||||
donphan: {encounters: ['wild']},
|
||||
porygon2: {encounters: ['wild']},
|
||||
stantler: {encounters: ['wild']},
|
||||
smeargle: {encounters: ['wild']},
|
||||
tyrogue: {encounters: ['egg']},
|
||||
hitmontop: {encounters: ['wild']},
|
||||
smoochum: {encounters: ['egg', 'research']},
|
||||
elekid: {encounters: ['egg', 'research']},
|
||||
magby: {encounters: ['egg']},
|
||||
miltank: {encounters: ['wild']},
|
||||
blissey: {encounters: ['wild']},
|
||||
raikou: {encounters: ['wild']},
|
||||
entei: {encounters: ['wild']},
|
||||
suicune: {encounters: ['wild']},
|
||||
larvitar: {encounters: ['wild']},
|
||||
pupitar: {encounters: ['wild']},
|
||||
tyranitar: {encounters: ['wild']},
|
||||
lugia: {encounters: ['giovanni', 'raid', 'research', 'specialtrade']},
|
||||
hooh: {encounters: ['giovanni', 'raid', 'research', 'specialtrade']},
|
||||
celebi: {encounters: ['research', 'notrade']},
|
||||
treecko: {encounters: ['wild']},
|
||||
grovyle: {encounters: ['wild']},
|
||||
sceptile: {encounters: ['wild']},
|
||||
torchic: {encounters: ['wild']},
|
||||
combusken: {encounters: ['wild']},
|
||||
blaziken: {encounters: ['wild']},
|
||||
mudkip: {encounters: ['wild']},
|
||||
marshtomp: {encounters: ['wild']},
|
||||
swampert: {encounters: ['wild']},
|
||||
poochyena: {encounters: ['wild']},
|
||||
mightyena: {encounters: ['wild']},
|
||||
zigzagoon: {encounters: ['wild']},
|
||||
zigzagoongalar: {encounters: ['wild']},
|
||||
linoone: {encounters: ['wild']},
|
||||
linoonegalar: {encounters: ['wild']},
|
||||
wurmple: {encounters: ['wild']},
|
||||
silcoon: {encounters: ['wild']},
|
||||
beautifly: {encounters: ['wild']},
|
||||
cascoon: {encounters: ['wild']},
|
||||
dustox: {encounters: ['wild']},
|
||||
lotad: {encounters: ['wild']},
|
||||
lombre: {encounters: ['wild']},
|
||||
ludicolo: {encounters: ['wild']},
|
||||
seedot: {encounters: ['wild']},
|
||||
nuzleaf: {encounters: ['wild']},
|
||||
shiftry: {encounters: ['wild']},
|
||||
taillow: {encounters: ['wild']},
|
||||
swellow: {encounters: ['wild']},
|
||||
wingull: {encounters: ['wild']},
|
||||
pelipper: {encounters: ['wild']},
|
||||
ralts: {encounters: ['wild']},
|
||||
kirlia: {encounters: ['wild']},
|
||||
gardevoir: {encounters: ['wild']},
|
||||
surskit: {encounters: ['wild']},
|
||||
masquerain: {encounters: ['wild']},
|
||||
shroomish: {encounters: ['wild']},
|
||||
breloom: {encounters: ['wild']},
|
||||
slakoth: {encounters: ['wild']},
|
||||
vigoroth: {encounters: ['wild']},
|
||||
slaking: {encounters: ['wild']},
|
||||
nincada: {encounters: ['wild']},
|
||||
ninjask: {encounters: ['wild']},
|
||||
shedinja: {encounters: ['research']},
|
||||
whismur: {encounters: ['wild']},
|
||||
loudred: {encounters: ['wild']},
|
||||
exploud: {encounters: ['wild']},
|
||||
makuhita: {encounters: ['wild']},
|
||||
hariyama: {encounters: ['wild']},
|
||||
azurill: {encounters: ['egg']},
|
||||
nosepass: {encounters: ['wild']},
|
||||
skitty: {encounters: ['wild']},
|
||||
delcatty: {encounters: ['wild']},
|
||||
sableye: {encounters: ['wild']},
|
||||
mawile: {encounters: ['wild']},
|
||||
aron: {encounters: ['wild']},
|
||||
lairon: {encounters: ['wild']},
|
||||
aggron: {encounters: ['wild']},
|
||||
meditite: {encounters: ['wild']},
|
||||
medicham: {encounters: ['wild']},
|
||||
electrike: {encounters: ['wild']},
|
||||
manectric: {encounters: ['wild']},
|
||||
plusle: {encounters: ['wild']},
|
||||
minun: {encounters: ['wild']},
|
||||
volbeat: {encounters: ['wild']},
|
||||
illumise: {encounters: ['wild']},
|
||||
roselia: {encounters: ['wild']},
|
||||
gulpin: {encounters: ['wild']},
|
||||
swalot: {encounters: ['wild']},
|
||||
carvanha: {encounters: ['wild']},
|
||||
sharpedo: {encounters: ['wild']},
|
||||
wailmer: {encounters: ['wild']},
|
||||
wailord: {encounters: ['wild']},
|
||||
numel: {encounters: ['wild']},
|
||||
camerupt: {encounters: ['wild']},
|
||||
torkoal: {encounters: ['wild']},
|
||||
spoink: {encounters: ['wild']},
|
||||
grumpig: {encounters: ['wild']},
|
||||
trapinch: {encounters: ['wild']},
|
||||
vibrava: {encounters: ['wild']},
|
||||
flygon: {encounters: ['wild']},
|
||||
cacnea: {encounters: ['wild']},
|
||||
cacturne: {encounters: ['wild']},
|
||||
swablu: {encounters: ['wild']},
|
||||
altaria: {encounters: ['wild']},
|
||||
zangoose: {encounters: ['wild']},
|
||||
seviper: {encounters: ['wild']},
|
||||
lunatone: {encounters: ['wild']},
|
||||
solrock: {encounters: ['wild']},
|
||||
barboach: {encounters: ['wild']},
|
||||
whiscash: {encounters: ['wild']},
|
||||
corphish: {encounters: ['wild']},
|
||||
crawdaunt: {encounters: ['wild']},
|
||||
baltoy: {encounters: ['wild']},
|
||||
claydol: {encounters: ['wild']},
|
||||
lileep: {encounters: ['wild']},
|
||||
cradily: {encounters: ['wild']},
|
||||
anorith: {encounters: ['wild']},
|
||||
armaldo: {encounters: ['wild']},
|
||||
feebas: {encounters: ['wild']},
|
||||
milotic: {encounters: ['wild']},
|
||||
castform: {encounters: ['wild']},
|
||||
kecleon: {encounters: ['wild']},
|
||||
shuppet: {encounters: ['wild']},
|
||||
banette: {encounters: ['wild']},
|
||||
duskull: {encounters: ['wild']},
|
||||
dusclops: {encounters: ['wild']},
|
||||
tropius: {encounters: ['wild']},
|
||||
chimecho: {encounters: ['wild']},
|
||||
absol: {encounters: ['wild']},
|
||||
wynaut: {encounters: ['egg']},
|
||||
snorunt: {encounters: ['wild']},
|
||||
glalie: {encounters: ['wild']},
|
||||
spheal: {encounters: ['wild']},
|
||||
sealeo: {encounters: ['wild']},
|
||||
walrein: {encounters: ['wild']},
|
||||
clamperl: {encounters: ['wild']},
|
||||
gorebyss: {encounters: ['wild']},
|
||||
huntail: {encounters: ['wild']},
|
||||
relicanth: {encounters: ['wild']},
|
||||
luvdisc: {encounters: ['wild']},
|
||||
bagon: {encounters: ['wild']},
|
||||
shelgon: {encounters: ['wild']},
|
||||
salamence: {encounters: ['wild']},
|
||||
beldum: {encounters: ['wild']},
|
||||
metang: {encounters: ['wild']},
|
||||
metagross: {encounters: ['wild']},
|
||||
regirock: {encounters: ['giovanni', 'raid', 'research', 'specialtrade']},
|
||||
regice: {encounters: ['giovanni', 'raid', 'research', 'specialtrade']},
|
||||
registeel: {encounters: ['giovanni', 'raid', 'research', 'specialtrade']},
|
||||
latias: {encounters: ['wild']},
|
||||
latios: {encounters: ['wild']},
|
||||
kyogre: {encounters: ['raid', 'research', 'specialtrade']},
|
||||
groudon: {encounters: ['raid', 'research', 'specialtrade']},
|
||||
rayquaza: {encounters: ['raid', 'research', 'specialtrade']},
|
||||
jirachi: {encounters: ['research', 'notrade']},
|
||||
deoxys: {encounters: ['raid', 'specialtrade']},
|
||||
turtwig: {encounters: ['wild']},
|
||||
grotle: {encounters: ['wild']},
|
||||
torterra: {encounters: ['wild']},
|
||||
chimchar: {encounters: ['wild']},
|
||||
monferno: {encounters: ['wild']},
|
||||
infernape: {encounters: ['wild']},
|
||||
piplup: {encounters: ['wild']},
|
||||
prinplup: {encounters: ['wild']},
|
||||
empoleon: {encounters: ['wild']},
|
||||
starly: {encounters: ['wild']},
|
||||
staravia: {encounters: ['wild']},
|
||||
staraptor: {encounters: ['wild']},
|
||||
bidoof: {encounters: ['wild']},
|
||||
bibarel: {encounters: ['wild']},
|
||||
kricketot: {encounters: ['wild']},
|
||||
kricketune: {encounters: ['wild']},
|
||||
shinx: {encounters: ['wild']},
|
||||
luxio: {encounters: ['wild']},
|
||||
luxray: {encounters: ['wild']},
|
||||
budew: {encounters: ['egg']},
|
||||
roserade: {encounters: ['wild']},
|
||||
cranidos: {encounters: ['wild']},
|
||||
rampardos: {encounters: ['wild']},
|
||||
shieldon: {encounters: ['wild']},
|
||||
bastiodon: {encounters: ['wild']},
|
||||
burmy: {encounters: ['wild']},
|
||||
wormadam: {encounters: ['wild']},
|
||||
wormadamsandy: {encounters: ['wild']},
|
||||
wormadamtrash: {encounters: ['wild']},
|
||||
mothim: {encounters: ['wild']},
|
||||
combee: {encounters: ['wild']},
|
||||
vespiquen: {encounters: ['wild']},
|
||||
pachirisu: {encounters: ['wild', 'noshiny']},
|
||||
buizel: {encounters: ['wild']},
|
||||
floatzel: {encounters: ['wild']},
|
||||
cherubi: {encounters: ['wild']},
|
||||
shellos: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-26
|
||||
shelloseast: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-26
|
||||
gastrodon: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-26
|
||||
gastrodoneast: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-26
|
||||
ambipom: {encounters: ['wild']},
|
||||
drifloon: {encounters: ['wild']},
|
||||
drifblim: {encounters: ['wild']},
|
||||
buneary: {encounters: ['wild']},
|
||||
lopunny: {encounters: ['wild']},
|
||||
mismagius: {encounters: ['wild']},
|
||||
honchkrow: {encounters: ['wild']},
|
||||
glameow: {encounters: ['wild']},
|
||||
purugly: {encounters: ['wild']},
|
||||
chingling: {encounters: ['egg', 'noshiny']},
|
||||
stunky: {encounters: ['wild', 'noshiny']},
|
||||
skuntank: {encounters: ['wild', 'noshiny']},
|
||||
bronzor: {encounters: ['wild']},
|
||||
bronzong: {encounters: ['wild']},
|
||||
bonsly: {encounters: ['egg']},
|
||||
mimejr: {encounters: ['egg']},
|
||||
happiny: {encounters: ['egg']},
|
||||
chatot: {encounters: ['wild', 'noshiny']},
|
||||
spiritomb: {encounters: ['research']},
|
||||
gible: {encounters: ['wild']},
|
||||
gabite: {encounters: ['wild']},
|
||||
garchomp: {encounters: ['wild']},
|
||||
munchlax: {encounters: ['egg']},
|
||||
riolu: {encounters: ['egg']},
|
||||
lucario: {encounters: ['egg', 'research']}, // wild encounter available on 2023-08-18
|
||||
hippopotas: {encounters: ['wild']},
|
||||
hippowdon: {encounters: ['wild']},
|
||||
skorupi: {encounters: ['wild']},
|
||||
drapion: {encounters: ['wild']},
|
||||
croagunk: {encounters: ['wild']},
|
||||
toxicroak: {encounters: ['wild']},
|
||||
carnivine: {encounters: ['wild', 'noshiny']},
|
||||
finneon: {encounters: ['wild']},
|
||||
lumineon: {encounters: ['wild']},
|
||||
mantyke: {encounters: ['egg']},
|
||||
snover: {encounters: ['wild']},
|
||||
abomasnow: {encounters: ['wild']},
|
||||
weavile: {encounters: ['wild']},
|
||||
magnezone: {encounters: ['wild']},
|
||||
lickilicky: {encounters: ['wild']},
|
||||
rhyperior: {encounters: ['wild']},
|
||||
tangrowth: {encounters: ['wild']},
|
||||
electivire: {encounters: ['wild']},
|
||||
magmortar: {encounters: ['wild']},
|
||||
togekiss: {encounters: ['wild']},
|
||||
yanmega: {encounters: ['wild']},
|
||||
leafeon: {encounters: ['wild']},
|
||||
glaceon: {encounters: ['wild']},
|
||||
gliscor: {encounters: ['wild']},
|
||||
mamoswine: {encounters: ['wild']},
|
||||
porygonz: {encounters: ['wild']},
|
||||
gallade: {encounters: ['wild']},
|
||||
probopass: {encounters: ['wild']},
|
||||
dusknoir: {encounters: ['wild']},
|
||||
froslass: {encounters: ['wild']},
|
||||
rotom: {encounters: ['wild', 'noshiny']},
|
||||
uxie: {encounters: ['wild']},
|
||||
mesprit: {encounters: ['wild']},
|
||||
azelf: {encounters: ['wild']},
|
||||
dialga: {encounters: ['raid', 'specialtrade']},
|
||||
palkia: {encounters: ['raid', 'specialtrade']},
|
||||
heatran: {encounters: ['raid', 'specialtrade']},
|
||||
regigigas: {encounters: ['raid', 'research', 'specialtrade']},
|
||||
giratina: {encounters: ['raid', 'specialtrade']},
|
||||
cresselia: {encounters: ['raid', 'research', 'specialtrade']},
|
||||
darkrai: {encounters: ['raid', 'notrade']},
|
||||
shaymin: {encounters: ['research', 'noshiny', 'notrade']},
|
||||
victini: {encounters: ['research', 'noshiny', 'notrade']},
|
||||
snivy: {encounters: ['wild']},
|
||||
servine: {encounters: ['wild']},
|
||||
serperior: {encounters: ['wild']},
|
||||
tepig: {encounters: ['wild']},
|
||||
pignite: {encounters: ['wild']},
|
||||
emboar: {encounters: ['wild']},
|
||||
oshawott: {encounters: ['wild']},
|
||||
dewott: {encounters: ['wild']},
|
||||
samurott: {encounters: ['wild']},
|
||||
patrat: {encounters: ['wild']},
|
||||
watchog: {encounters: ['wild']},
|
||||
lillipup: {encounters: ['wild']},
|
||||
herdier: {encounters: ['wild']},
|
||||
stoutland: {encounters: ['wild']},
|
||||
purrloin: {encounters: ['wild']},
|
||||
liepard: {encounters: ['wild']},
|
||||
pansage: {encounters: ['wild']},
|
||||
simisage: {encounters: ['wild']},
|
||||
pansear: {encounters: ['wild']},
|
||||
simisear: {encounters: ['wild']},
|
||||
panpour: {encounters: ['wild']},
|
||||
simipour: {encounters: ['wild']},
|
||||
munna: {encounters: ['wild']},
|
||||
musharna: {encounters: ['wild']},
|
||||
pidove: {encounters: ['wild']},
|
||||
tranquill: {encounters: ['wild']},
|
||||
unfezant: {encounters: ['wild']},
|
||||
blitzle: {encounters: ['wild']},
|
||||
zebstrika: {encounters: ['wild']},
|
||||
roggenrola: {encounters: ['wild']},
|
||||
boldore: {encounters: ['wild']},
|
||||
gigalith: {encounters: ['wild']},
|
||||
woobat: {encounters: ['wild']},
|
||||
swoobat: {encounters: ['wild']},
|
||||
drilbur: {encounters: ['wild']},
|
||||
exacdrill: {encounters: ['wild']},
|
||||
audino: {encounters: ['wild']},
|
||||
timburr: {encounters: ['egg', 'raid']}, // wild encounter available on 2023-08-26
|
||||
gurdurr: {encounters: ['egg', 'raid']}, // wild encounter available on 2023-08-26
|
||||
conkeldurr: {encounters: ['egg', 'raid']}, // wild encounter available on 2023-08-26
|
||||
tympole: {encounters: ['wild']},
|
||||
palpitoad: {encounters: ['wild']},
|
||||
seismitoad: {encounters: ['wild']},
|
||||
throh: {encounters: ['wild']},
|
||||
sawk: {encounters: ['wild']},
|
||||
sewaddle: {encounters: ['wild']},
|
||||
swadloon: {encounters: ['wild']},
|
||||
leavanny: {encounters: ['wild']},
|
||||
venipede: {encounters: ['wild']},
|
||||
whirlipede: {encounters: ['wild']},
|
||||
scolipede: {encounters: ['wild']},
|
||||
cottonee: {encounters: ['wild']},
|
||||
whimsicott: {encounters: ['wild']},
|
||||
petilil: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-04
|
||||
lilligant: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-04
|
||||
basculin: {encounters: ['wild', 'noshiny']},
|
||||
basculinbluestriped: {encounters: ['wild', 'noshiny']},
|
||||
sandile: {encounters: ['12kmegg', 'research', 'noshiny']},
|
||||
krokorok: {encounters: ['12kmegg', 'research', 'noshiny']},
|
||||
krookodile: {encounters: ['12kmegg', 'research', 'noshiny']},
|
||||
darumaka: {encounters: ['wild']},
|
||||
darumakagalar: {encounters: ['wild']},
|
||||
darmanitan: {encounters: ['wild']},
|
||||
darmanitangalar: {encounters: ['wild']},
|
||||
maractus: {encounters: ['wild', 'noshiny']},
|
||||
dwebble: {encounters: ['wild']},
|
||||
crustle: {encounters: ['wild']},
|
||||
scraggy: {encounters: ['wild', 'noshiny']},
|
||||
scrafty: {encounters: ['wild', 'noshiny']},
|
||||
sigilyph: {encounters: ['wild', 'noshiny']},
|
||||
yamask: {encounters: ['wild']},
|
||||
yamaskgalar: {encounters: ['egg', 'raid', 'research']},
|
||||
cofagrigus: {encounters: ['wild']},
|
||||
tirtouga: {encounters: ['wild']},
|
||||
carracosta: {encounters: ['wild']},
|
||||
archen: {encounters: ['wild']},
|
||||
archeops: {encounters: ['wild']},
|
||||
trubbish: {encounters: ['wild']},
|
||||
garbodor: {encounters: ['wild']},
|
||||
zorua: {encounters: ['wild', 'noshiny']},
|
||||
zoroark: {encounters: ['wild', 'noshiny']},
|
||||
minccino: {encounters: ['wild']},
|
||||
cinccino: {encounters: ['wild']},
|
||||
gothita: {encounters: ['wild', 'noshiny']},
|
||||
gothorita: {encounters: ['wild', 'noshiny']},
|
||||
gothitelle: {encounters: ['wild', 'noshiny']},
|
||||
solosis: {encounters: ['wild', 'noshiny']},
|
||||
duosion: {encounters: ['wild', 'noshiny']},
|
||||
reuniclus: {encounters: ['wild', 'noshiny']},
|
||||
ducklett: {encounters: ['wild', 'noshiny']},
|
||||
swanna: {encounters: ['wild', 'noshiny']},
|
||||
vanillite: {encounters: ['wild', 'noshiny']},
|
||||
vanillish: {encounters: ['wild', 'noshiny']},
|
||||
vanilluxe: {encounters: ['wild', 'noshiny']},
|
||||
deerling: {encounters: ['wild', 'noshiny']},
|
||||
deerlingsummer: {encounters: ['wild', 'noshiny']},
|
||||
deerlingautumn: {encounters: ['wild', 'noshiny']},
|
||||
deerlingwinter: {encounters: ['wild', 'noshiny']},
|
||||
sawsbuck: {encounters: ['wild', 'noshiny']},
|
||||
sawsbucksummer: {encounters: ['wild', 'noshiny']},
|
||||
sawsbuckautumn: {encounters: ['wild', 'noshiny']},
|
||||
sawsbuckwinter: {encounters: ['wild', 'noshiny']},
|
||||
emolga: {encounters: ['wild', 'noshiny']},
|
||||
karrablast: {encounters: ['wild']},
|
||||
escavalier: {encounters: ['wild']},
|
||||
foongus: {encounters: ['wild']},
|
||||
amoonguss: {encounters: ['wild']},
|
||||
frillish: {encounters: ['wild']},
|
||||
jellicent: {encounters: ['wild']},
|
||||
alomomola: {encounters: ['wild']},
|
||||
joltik: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-26
|
||||
galvantula: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-26
|
||||
ferroseed: {encounters: ['wild']},
|
||||
ferrothorn: {encounters: ['wild']},
|
||||
klink: {encounters: ['wild']},
|
||||
klang: {encounters: ['wild']},
|
||||
klinklang: {encounters: ['wild']},
|
||||
tynamo: {encounters: ['wild', 'noshiny']},
|
||||
eelektrik: {encounters: ['wild', 'noshiny']},
|
||||
eelektross: {encounters: ['wild', 'noshiny']},
|
||||
elgyem: {encounters: ['wild']},
|
||||
beheeyem: {encounters: ['wild']},
|
||||
litwick: {encounters: ['wild']},
|
||||
lampent: {encounters: ['wild']},
|
||||
chandelure: {encounters: ['wild']},
|
||||
axew: {encounters: ['wild']},
|
||||
fraxure: {encounters: ['wild']},
|
||||
haxorus: {encounters: ['wild']},
|
||||
cubchoo: {encounters: ['wild']},
|
||||
beartic: {encounters: ['wild']},
|
||||
cryogonal: {encounters: ['wild', 'noshiny']},
|
||||
shelmet: {encounters: ['wild']},
|
||||
accelgor: {encounters: ['wild']},
|
||||
stunfisk: {encounters: ['wild']},
|
||||
stunfiskgalar: {encounters: ['wild']},
|
||||
mienfoo: {encounters: ['wild', 'noshiny']},
|
||||
mienshao: {encounters: ['wild', 'noshiny']},
|
||||
druddigon: {encounters: ['raid', 'research']},
|
||||
golett: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-18
|
||||
golurk: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-18
|
||||
pawniard: {encounters: ['12kmegg', 'research']}, // wild encounter available on 2023-08-18
|
||||
bisharp: {encounters: ['12kmegg', 'research']}, // wild encounter available on 2023-08-18
|
||||
bouffalant: {encounters: ['wild', 'noshiny']},
|
||||
rufflet: {encounters: ['wild']},
|
||||
braviary: {encounters: ['wild']},
|
||||
braviaryhisui: {encounters: ['raid']},
|
||||
vullaby: {encounters: ['wild']},
|
||||
mandibuzz: {encounters: ['wild']},
|
||||
heatmor: {encounters: ['wild']},
|
||||
durant: {encounters: ['wild']},
|
||||
deino: {encounters: ['wild']},
|
||||
zweilous: {encounters: ['wild']},
|
||||
hydreigon: {encounters: ['wild']},
|
||||
larvesta: {encounters: ['egg', 'noshiny']},
|
||||
volcarona: {encounters: ['egg', 'noshiny']},
|
||||
cobalion: {encounters: ['raid', 'specialtrade']},
|
||||
terrakion: {encounters: ['raid', 'specialtrade']},
|
||||
virizion: {encounters: ['raid', 'specialtrade']},
|
||||
tornadus: {encounters: ['raid', 'specialtrade']},
|
||||
thundurus: {encounters: ['raid', 'specialtrade']},
|
||||
reshiram: {encounters: ['raid', 'specialtrade']},
|
||||
zekrom: {encounters: ['raid', 'specialtrade']},
|
||||
landorus: {encounters: ['raid', 'specialtrade']},
|
||||
kyurem: {encounters: ['raid', 'specialtrade']},
|
||||
// Kyurem-Black/White are not directly obtained from Pokemon GO but should be able to have legal Pokemon GO origin
|
||||
kyuremblack: {encounters: ['raid', 'specialtrade']},
|
||||
kyuremwhite: {encounters: ['raid', 'specialtrade']},
|
||||
keldeo: {encounters: ['research', 'noshiny', 'notrade']},
|
||||
meloetta: {encounters: ['research', 'noshiny', 'notrade']},
|
||||
genesect: {encounters: ['raid', 'research', 'notrade']},
|
||||
chespin: {encounters: ['wild']},
|
||||
quilladin: {encounters: ['wild']},
|
||||
chesnaught: {encounters: ['wild']},
|
||||
fennekin: {encounters: ['wild']},
|
||||
braixen: {encounters: ['wild']},
|
||||
delphox: {encounters: ['wild']},
|
||||
froakie: {encounters: ['wild', 'noshiny']},
|
||||
frogadier: {encounters: ['wild', 'noshiny']},
|
||||
greninja: {encounters: ['wild', 'noshiny']},
|
||||
bunnelby: {encounters: ['wild']},
|
||||
diggersby: {encounters: ['wild']},
|
||||
fletchling: {encounters: ['wild']},
|
||||
fletchinder: {encounters: ['wild']},
|
||||
talonflame: {encounters: ['wild']},
|
||||
// Scatterbug is actually obtained in a special type of encounter,
|
||||
// but the level and IV floors are the same as research encounters
|
||||
scatterbug: {encounters: ['research', 'noshiny']},
|
||||
spewpa: {encounters: ['research', 'noshiny']},
|
||||
vivillon: {encounters: ['research', 'noshiny']},
|
||||
vivillonarchipelago: {encounters: ['research', 'noshiny']},
|
||||
vivilloncontinent: {encounters: ['research', 'noshiny']},
|
||||
vivillonelegant: {encounters: ['research', 'noshiny']},
|
||||
vivillongarden: {encounters: ['research', 'noshiny']},
|
||||
vivillonhighplains: {encounters: ['research', 'noshiny']},
|
||||
vivillonicysnow: {encounters: ['research', 'noshiny']},
|
||||
vivillonjungle: {encounters: ['research', 'noshiny']},
|
||||
vivillonmarine: {encounters: ['research', 'noshiny']},
|
||||
vivillonmodern: {encounters: ['research', 'noshiny']},
|
||||
vivillonmonsoon: {encounters: ['research', 'noshiny']},
|
||||
vivillonocean: {encounters: ['research', 'noshiny']},
|
||||
vivillonpolar: {encounters: ['research', 'noshiny']},
|
||||
vivillonriver: {encounters: ['research', 'noshiny']},
|
||||
vivillonsandstorm: {encounters: ['research', 'noshiny']},
|
||||
vivillonsavanna: {encounters: ['research', 'noshiny']},
|
||||
vivillonsun: {encounters: ['research', 'noshiny']},
|
||||
vivillontundra: {encounters: ['research', 'noshiny']},
|
||||
litleo: {encounters: ['wild']},
|
||||
pyroar: {encounters: ['wild']},
|
||||
flabebe: {encounters: ['wild', 'noshiny']},
|
||||
flabebeblue: {encounters: ['wild', 'noshiny']},
|
||||
flabebeorange: {encounters: ['wild', 'noshiny']},
|
||||
flabebewhite: {encounters: ['wild', 'noshiny']},
|
||||
flabebeyellow: {encounters: ['wild', 'noshiny']},
|
||||
floette: {encounters: ['wild', 'noshiny']},
|
||||
floetteblue: {encounters: ['wild', 'noshiny']},
|
||||
floetteorange: {encounters: ['wild', 'noshiny']},
|
||||
floettewhite: {encounters: ['wild', 'noshiny']},
|
||||
floetteyellow: {encounters: ['wild', 'noshiny']},
|
||||
florges: {encounters: ['wild', 'noshiny']},
|
||||
florgesblue: {encounters: ['wild', 'noshiny']},
|
||||
florgesorange: {encounters: ['wild', 'noshiny']},
|
||||
florgeswhite: {encounters: ['wild', 'noshiny']},
|
||||
florgesyellow: {encounters: ['wild', 'noshiny']},
|
||||
pancham: {encounters: ['wild', '12kmegg', 'raid', 'research', 'nowildshiny']},
|
||||
pangoro: {encounters: ['wild', '12kmegg', 'raid', 'research', 'nowildshiny']},
|
||||
furfrou: {encounters: ['wild']},
|
||||
furfroudandy: {encounters: ['wild']},
|
||||
furfroudebutante: {encounters: ['wild']},
|
||||
furfroudiamond: {encounters: ['wild']},
|
||||
furfrouheart: {encounters: ['wild']},
|
||||
furfroukabuki: {encounters: ['wild']},
|
||||
furfroulareine: {encounters: ['wild']},
|
||||
furfroumatron: {encounters: ['wild']},
|
||||
furfroupharaoh: {encounters: ['wild']},
|
||||
furfroustar: {encounters: ['wild']},
|
||||
espurr: {encounters: ['wild']},
|
||||
meowstic: {encounters: ['wild']},
|
||||
meowsticf: {encounters: ['wild']},
|
||||
spritzee: {encounters: ['wild']},
|
||||
aromatisse: {encounters: ['wild']},
|
||||
swirlix: {encounters: ['wild']},
|
||||
slurpuff: {encounters: ['wild']},
|
||||
inkay: {encounters: ['wild']},
|
||||
malamar: {encounters: ['wild']},
|
||||
binacle: {encounters: ['wild']},
|
||||
barbaracle: {encounters: ['wild']},
|
||||
skrelp: {encounters: ['wild', 'noshiny']},
|
||||
dragalge: {encounters: ['wild', 'noshiny']},
|
||||
clauncher: {encounters: ['wild']},
|
||||
clawitzer: {encounters: ['wild']},
|
||||
helioptile: {encounters: ['wild']},
|
||||
heliolisk: {encounters: ['wild']},
|
||||
tyrunt: {encounters: ['wild', 'noshiny']},
|
||||
tyrantrum: {encounters: ['wild', 'noshiny']},
|
||||
amaura: {encounters: ['wild', 'noshiny']},
|
||||
aurorus: {encounters: ['wild', 'noshiny']},
|
||||
sylveon: {encounters: ['wild']},
|
||||
hawlucha: {encounters: ['wild', 'noshiny']},
|
||||
dedenne: {encounters: ['wild']},
|
||||
carbink: {encounters: ['research', 'noshiny']},
|
||||
goomy: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-26
|
||||
sliggoo: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-26
|
||||
goodra: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-26
|
||||
klefki: {encounters: ['wild', 'noshiny']},
|
||||
phantump: {encounters: ['wild', 'noshiny']},
|
||||
trevenant: {encounters: ['wild', 'noshiny']},
|
||||
pumpkaboo: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-04
|
||||
pumpkaboolarge: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-04
|
||||
pumpkaboosmall: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-04
|
||||
pumpkaboosuper: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-04
|
||||
gourgeist: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-04
|
||||
gourgeistlarge: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-04
|
||||
gourgeistsmall: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-04
|
||||
gourgeistsuper: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-04
|
||||
bergmite: {encounters: ['wild']},
|
||||
avalugg: {encounters: ['wild']},
|
||||
avalugghisui: {encounters: ['raid']},
|
||||
noibat: {encounters: ['wild']},
|
||||
noivern: {encounters: ['wild']},
|
||||
xerneas: {encounters: ['raid', 'specialtrade']},
|
||||
yveltal: {encounters: ['raid', 'specialtrade']},
|
||||
// zygarde: {encounters: ['research', 'noshiny']}, trading/transferring may be made available in the future
|
||||
// diancie: {encounters: ['research', 'noshiny', 'notrade']}, transferring may be made available in the future
|
||||
hoopa: {encounters: ['raid', 'research', 'noshiny', 'notrade']},
|
||||
rowlet: {encounters: ['wild', 'noshiny']},
|
||||
dartrix: {encounters: ['wild', 'noshiny']},
|
||||
decidueye: {encounters: ['wild', 'noshiny']},
|
||||
litten: {encounters: ['wild', 'noshiny']},
|
||||
torracat: {encounters: ['wild', 'noshiny']},
|
||||
incineroar: {encounters: ['wild', 'noshiny']},
|
||||
popplio: {encounters: ['wild', 'noshiny']},
|
||||
brionne: {encounters: ['wild', 'noshiny']},
|
||||
primarina: {encounters: ['wild', 'noshiny']},
|
||||
pikipek: {encounters: ['wild', 'noshiny']},
|
||||
trumbeak: {encounters: ['wild', 'noshiny']},
|
||||
toucannon: {encounters: ['wild', 'noshiny']},
|
||||
yungoos: {encounters: ['wild']},
|
||||
gumshoos: {encounters: ['wild']},
|
||||
grubbin: {encounters: ['wild', 'noshiny']},
|
||||
charjabug: {encounters: ['wild', 'noshiny']},
|
||||
vikavolt: {encounters: ['wild', 'noshiny']},
|
||||
crabrawler: {encounters: ['wild', 'noshiny']},
|
||||
crabominable: {encounters: ['wild', 'noshiny']},
|
||||
oricorio: {encounters: ['wild', 'noshiny']},
|
||||
cutiefly: {encounters: ['wild', 'noshiny']},
|
||||
ribombee: {encounters: ['wild', 'noshiny']},
|
||||
rockruff: {encounters: ['wild']},
|
||||
lycanroc: {encounters: ['wild']},
|
||||
lycanrocmidnight: {encounters: ['wild']},
|
||||
mareanie: {encounters: ['wild', 'noshiny']},
|
||||
toxapex: {encounters: ['wild', 'noshiny']},
|
||||
dewpider: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-04
|
||||
araquanid: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-04
|
||||
fomantis: {encounters: ['wild']},
|
||||
lurantis: {encounters: ['wild']},
|
||||
morelull: {encounters: ['wild', 'noshiny']},
|
||||
shiinotic: {encounters: ['wild', 'noshiny']},
|
||||
salandit: {encounters: ['12kmegg', 'noshiny']},
|
||||
salazzle: {encounters: ['12kmegg', 'noshiny']},
|
||||
stufful: {encounters: ['wild']},
|
||||
bewear: {encounters: ['wild']},
|
||||
bounsweet: {encounters: ['wild', 'noshiny']},
|
||||
steenee: {encounters: ['wild', 'noshiny']},
|
||||
tsareena: {encounters: ['wild', 'noshiny']},
|
||||
comfey: {encounters: ['wild', 'noshiny']},
|
||||
oranguru: {encounters: ['wild', 'noshiny']}, // shiny available on 2023-08-26
|
||||
wimpod: {encounters: ['wild', 'noshiny']},
|
||||
golisopod: {encounters: ['wild', 'noshiny']},
|
||||
sandygast: {encounters: ['raid', 'research', 'noshiny']},
|
||||
palossand: {encounters: ['raid', 'research', 'noshiny']},
|
||||
komala: {encounters: ['wild', 'noshiny']},
|
||||
turtonator: {encounters: ['raid', 'research']},
|
||||
togedemaru: {encounters: ['wild', 'noshiny']},
|
||||
bruxish: {encounters: ['wild', 'noshiny']},
|
||||
jangmoo: {encounters: ['wild', 'noshiny']},
|
||||
hakamoo: {encounters: ['wild', 'noshiny']},
|
||||
kommoo: {encounters: ['wild', 'noshiny']},
|
||||
tapukoko: {encounters: ['raid']},
|
||||
tapulele: {encounters: ['raid']},
|
||||
tapubulu: {encounters: ['raid']},
|
||||
tapufini: {encounters: ['raid']},
|
||||
cosmog: {encounters: ['research', 'noshiny', 'specialtrade']},
|
||||
cosmoem: {encounters: ['research', 'noshiny', 'specialtrade']},
|
||||
solgaleo: {encounters: ['research', 'noshiny', 'specialtrade']},
|
||||
lunala: {encounters: ['research', 'noshiny', 'specialtrade']},
|
||||
nihilego: {encounters: ['raid', 'research', 'specialtrade']},
|
||||
buzzwole: {encounters: ['raid', 'research', 'noshiny', 'specialtrade']},
|
||||
pheromosa: {encounters: ['raid', 'research', 'noshiny', 'specialtrade']},
|
||||
xurkitree: {encounters: ['raid', 'research', 'noshiny', 'specialtrade']},
|
||||
celesteela: {encounters: ['raid', 'research', 'noshiny', 'specialtrade']},
|
||||
kartana: {encounters: ['raid', 'research', 'noshiny', 'specialtrade']},
|
||||
guzzlord: {encounters: ['raid', 'research', 'noshiny', 'specialtrade']},
|
||||
meltan: {encounters: ['wild']},
|
||||
melmetal: {encounters: ['wild']},
|
||||
skwovet: {encounters: ['wild', 'noshiny']},
|
||||
greedent: {encounters: ['wild', 'noshiny']},
|
||||
obstagoon: {encounters: ['wild']},
|
||||
perrserker: {encounters: ['wild']},
|
||||
sirfetchd: {encounters: ['wild']},
|
||||
mrrime: {encounters: ['wild']},
|
||||
runerigus: {encounters: ['egg', 'raid', 'research']},
|
||||
falinks: {encounters: ['wild', 'noshiny']},
|
||||
zacian: {encounters: ['raid', 'noshiny', 'specialtrade']},
|
||||
zamazenta: {encounters: ['raid', 'noshiny', 'specialtrade']},
|
||||
zarude: {encounters: ['research', 'noshiny', 'notrade']},
|
||||
regieleki: {encounters: ['raid', 'noshiny', 'specialtrade']},
|
||||
regidrago: {encounters: ['raid', 'noshiny', 'specialtrade']},
|
||||
kleavor: {encounters: ['wild']},
|
||||
ursaluna: {encounters: ['wild']},
|
||||
sneasler: {encounters: ['wild', 'noshiny']},
|
||||
overqwil: {encounters: ['wild', 'noshiny']},
|
||||
gimmighoulroaming: {encounters: ['wild', 'noshiny']},
|
||||
gholdengo: {encounters: ['wild', 'noshiny']},
|
||||
};
|
||||
|
|
@ -43,6 +43,11 @@ export interface LearnsetData {
|
|||
|
||||
export type ModdedLearnsetData = LearnsetData & {inherit?: true};
|
||||
|
||||
export interface PokemonGoData {
|
||||
encounters?: string[];
|
||||
LGPERestrictiveMoves?: {[moveid: string]: number | null};
|
||||
}
|
||||
|
||||
export class Species extends BasicEffect implements Readonly<BasicEffect & SpeciesFormatsData> {
|
||||
declare readonly effectType: 'Pokemon';
|
||||
/**
|
||||
|
|
@ -206,6 +211,12 @@ export class Species extends BasicEffect implements Readonly<BasicEffect & Speci
|
|||
*/
|
||||
readonly changesFrom?: string;
|
||||
|
||||
/**
|
||||
* List of sources and other availability for a Pokemon transferred from
|
||||
* Pokemon GO.
|
||||
*/
|
||||
readonly pokemonGoData?: string[];
|
||||
|
||||
/**
|
||||
* Singles Tier. The Pokemon's location in the Smogon tier system.
|
||||
*/
|
||||
|
|
@ -273,6 +284,7 @@ export class Species extends BasicEffect implements Readonly<BasicEffect & Speci
|
|||
this.battleOnly = data.battleOnly || (this.isMega ? this.baseSpecies : undefined);
|
||||
this.changesFrom = data.changesFrom ||
|
||||
(this.battleOnly !== this.baseSpecies ? this.battleOnly : this.baseSpecies);
|
||||
this.pokemonGoData = data.pokemonGoData || undefined;
|
||||
if (Array.isArray(data.changesFrom)) this.changesFrom = data.changesFrom[0];
|
||||
|
||||
if (!this.gen && this.num >= 1) {
|
||||
|
|
@ -521,6 +533,10 @@ export class DexSpecies {
|
|||
return learnsetData;
|
||||
}
|
||||
|
||||
getPokemonGoData(id: ID): PokemonGoData {
|
||||
return this.dex.data.PokemonGoData[id];
|
||||
}
|
||||
|
||||
all(): readonly Species[] {
|
||||
if (this.allCache) return this.allCache;
|
||||
const species = [];
|
||||
|
|
|
|||
|
|
@ -46,10 +46,10 @@ const dexes: {[mod: string]: ModdedDex} = Object.create(null);
|
|||
|
||||
type DataType =
|
||||
'Abilities' | 'Rulesets' | 'FormatsData' | 'Items' | 'Learnsets' | 'Moves' |
|
||||
'Natures' | 'Pokedex' | 'Scripts' | 'Conditions' | 'TypeChart';
|
||||
'Natures' | 'Pokedex' | 'Scripts' | 'Conditions' | 'TypeChart' | 'PokemonGoData';
|
||||
const DATA_TYPES: (DataType | 'Aliases')[] = [
|
||||
'Abilities', 'Rulesets', 'FormatsData', 'Items', 'Learnsets', 'Moves',
|
||||
'Natures', 'Pokedex', 'Scripts', 'Conditions', 'TypeChart',
|
||||
'Natures', 'Pokedex', 'Scripts', 'Conditions', 'TypeChart', 'PokemonGoData',
|
||||
];
|
||||
|
||||
const DATA_FILES = {
|
||||
|
|
@ -62,6 +62,7 @@ const DATA_FILES = {
|
|||
Moves: 'moves',
|
||||
Natures: 'natures',
|
||||
Pokedex: 'pokedex',
|
||||
PokemonGoData: 'pokemongo',
|
||||
Scripts: 'scripts',
|
||||
Conditions: 'conditions',
|
||||
TypeChart: 'typechart',
|
||||
|
|
@ -81,6 +82,7 @@ interface DexTableData {
|
|||
Moves: DexTable<MoveData>;
|
||||
Natures: DexTable<NatureData>;
|
||||
Pokedex: DexTable<SpeciesData>;
|
||||
PokemonGoData: DexTable<PokemonGoData>;
|
||||
Scripts: DexTable<AnyObject>;
|
||||
Conditions: DexTable<EffectData>;
|
||||
TypeChart: DexTable<TypeData>;
|
||||
|
|
|
|||
|
|
@ -168,6 +168,7 @@ type ModdedSpeciesFormatsData = import('./dex-species').ModdedSpeciesFormatsData
|
|||
type LearnsetData = import('./dex-species').LearnsetData;
|
||||
type ModdedLearnsetData = import('./dex-species').ModdedLearnsetData;
|
||||
type Species = import('./dex-species').Species;
|
||||
type PokemonGoData = import('./dex-species').PokemonGoData;
|
||||
|
||||
type FormatData = import('./dex-formats').FormatData;
|
||||
type FormatList = import('./dex-formats').FormatList;
|
||||
|
|
|
|||
|
|
@ -89,6 +89,8 @@ export class PokemonSources {
|
|||
sketchMove?: string;
|
||||
dreamWorldMoveCount: number;
|
||||
hm?: string;
|
||||
isFromPokemonGo?: boolean;
|
||||
pokemonGoSource?: string;
|
||||
restrictiveMoves?: string[];
|
||||
/** Obscure learn methods */
|
||||
restrictedMove?: ID;
|
||||
|
|
@ -647,10 +649,6 @@ export class TeamValidator {
|
|||
return problems;
|
||||
}
|
||||
|
||||
if (ruleTable.isBanned('nonexistent')) {
|
||||
problems.push(...this.validateStats(set, species, setSources));
|
||||
}
|
||||
|
||||
const moveLegalityWhitelist: {[k: string]: true | undefined} = {};
|
||||
for (const moveName of set.moves) {
|
||||
if (!moveName) continue;
|
||||
|
|
@ -673,74 +671,8 @@ export class TeamValidator {
|
|||
}
|
||||
}
|
||||
|
||||
if (ruleTable.has('obtainablemoves')) {
|
||||
problems.push(...this.validateMoves(outOfBattleSpecies, set.moves, setSources, set, name, moveLegalityWhitelist));
|
||||
}
|
||||
|
||||
const pokemonGoProblems = this.validatePokemonGo(outOfBattleSpecies, set, setSources);
|
||||
const learnsetSpecies = dex.species.getLearnsetData(outOfBattleSpecies.id);
|
||||
let eventOnlyData;
|
||||
|
||||
if (!setSources.sourcesBefore && setSources.sources.length) {
|
||||
let legal = false;
|
||||
for (const source of setSources.sources) {
|
||||
if (this.validateSource(set, source, setSources, outOfBattleSpecies)) continue;
|
||||
legal = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!legal) {
|
||||
let nonEggSource = null;
|
||||
for (const source of setSources.sources) {
|
||||
if (source.charAt(1) !== 'E') {
|
||||
nonEggSource = source;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!nonEggSource) {
|
||||
// all egg moves
|
||||
problems.push(`${name} can't get its egg move combination (${setSources.limitedEggMoves!.join(', ')}) from any possible father.`);
|
||||
problems.push(`(Is this incorrect? If so, post the chainbreeding instructions in Bug Reports)`);
|
||||
} else {
|
||||
if (setSources.sources.length > 1) {
|
||||
problems.push(`${name} has an event-exclusive move that it doesn't qualify for (only one of several ways to get the move will be listed):`);
|
||||
}
|
||||
const eventProblems = this.validateSource(
|
||||
set, nonEggSource, setSources, outOfBattleSpecies, ` because it has a move only available`
|
||||
);
|
||||
if (eventProblems) problems.push(...eventProblems);
|
||||
}
|
||||
}
|
||||
} else if (ruleTable.has('obtainablemisc') && (eventOnlyData = this.getEventOnlyData(outOfBattleSpecies))) {
|
||||
const {species: eventSpecies, eventData} = eventOnlyData;
|
||||
let legal = false;
|
||||
for (const event of eventData) {
|
||||
if (this.validateEvent(set, setSources, event, eventSpecies)) continue;
|
||||
legal = true;
|
||||
break;
|
||||
}
|
||||
if (!legal && species.gen <= 2 && dex.gen >= 7 && !this.validateSource(set, '7V', setSources, species)) {
|
||||
legal = true;
|
||||
}
|
||||
if (!legal) {
|
||||
if (eventData.length === 1) {
|
||||
problems.push(`${species.name} is only obtainable from an event - it needs to match its event:`);
|
||||
} else {
|
||||
problems.push(`${species.name} is only obtainable from events - it needs to match one of its events:`);
|
||||
}
|
||||
for (const [i, event] of eventData.entries()) {
|
||||
if (event.generation <= dex.gen && event.generation >= this.minSourceGen) {
|
||||
const eventInfo = event;
|
||||
const eventNum = i + 1;
|
||||
const eventName = eventData.length > 1 ? ` #${eventNum}` : ``;
|
||||
const eventProblems = this.validateEvent(
|
||||
set, setSources, eventInfo, eventSpecies, ` to be`, `from its event${eventName}`
|
||||
);
|
||||
if (eventProblems) problems.push(...eventProblems);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let isFromRBYEncounter = false;
|
||||
if (this.gen === 1 && ruleTable.has('obtainablemisc') && !this.ruleTable.has('allowtradeback')) {
|
||||
let lowestEncounterLevel;
|
||||
|
|
@ -764,13 +696,142 @@ export class TeamValidator {
|
|||
let evoSpecies = species;
|
||||
while (evoSpecies.prevo) {
|
||||
if (set.level < (evoSpecies.evoLevel || 0)) {
|
||||
problems.push(`${name} must be at least level ${evoSpecies.evoLevel} to be evolved.`);
|
||||
if (!pokemonGoProblems || (pokemonGoProblems && pokemonGoProblems.length)) {
|
||||
problems.push(`${name} must be at least level ${evoSpecies.evoLevel} to be evolved.`);
|
||||
if (pokemonGoProblems && pokemonGoProblems.length) {
|
||||
problems.push(`It failed to validate as a Pokemon from Pokemon GO because:`);
|
||||
for (const pokemonGoProblem of pokemonGoProblems) {
|
||||
problems.push(pokemonGoProblem);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Pokemon from Pokemon GO can be transferred to LGPE
|
||||
setSources.isFromPokemonGo = true;
|
||||
setSources.sources.push('8V');
|
||||
setSources.sourcesBefore = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
evoSpecies = dex.species.get(evoSpecies.prevo);
|
||||
}
|
||||
}
|
||||
|
||||
const moveProblems = this.validateMoves(outOfBattleSpecies, set.moves, setSources, set, name, moveLegalityWhitelist);
|
||||
if (ruleTable.has('obtainablemoves')) {
|
||||
problems.push(...moveProblems);
|
||||
}
|
||||
|
||||
let eventOnlyData;
|
||||
|
||||
if (!setSources.sourcesBefore && setSources.sources.length) {
|
||||
let legal = false;
|
||||
for (const source of setSources.sources) {
|
||||
if (this.validateSource(set, source, setSources, outOfBattleSpecies)) continue;
|
||||
legal = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!legal) {
|
||||
let nonEggSource = null;
|
||||
for (const source of setSources.sources) {
|
||||
if (source.charAt(1) !== 'E') {
|
||||
nonEggSource = source;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!nonEggSource) {
|
||||
// all egg moves
|
||||
problems.push(`${name} can't get its egg move combination (${setSources.limitedEggMoves!.join(', ')}) from any possible father.`);
|
||||
problems.push(`(Is this incorrect? If so, post the chainbreeding instructions in Bug Reports)`);
|
||||
} else {
|
||||
if (species.id === 'mew' && pokemonGoProblems && !pokemonGoProblems.length) {
|
||||
// Whitelist Pokemon GO Mew, which cannot be sent to Let's Go
|
||||
setSources.isFromPokemonGo = true;
|
||||
} else {
|
||||
if (setSources.sources.length > 1) {
|
||||
problems.push(`${name} has an event-exclusive move that it doesn't qualify for (only one of several ways to get the move will be listed):`);
|
||||
}
|
||||
const eventProblems = this.validateSource(
|
||||
set, nonEggSource, setSources, outOfBattleSpecies, ` because it has a move only available`
|
||||
);
|
||||
if (eventProblems) problems.push(...eventProblems);
|
||||
if (species.id === 'mew' && pokemonGoProblems && pokemonGoProblems.length) {
|
||||
problems.push(`Additionally, it failed to validate as a Pokemon from Pokemon GO because:`);
|
||||
for (const pokemonGoProblem of pokemonGoProblems) {
|
||||
problems.push(pokemonGoProblem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ruleTable.has('obtainablemisc') && (eventOnlyData = this.getEventOnlyData(outOfBattleSpecies))) {
|
||||
const {species: eventSpecies, eventData} = eventOnlyData;
|
||||
let legal = false;
|
||||
for (const event of eventData) {
|
||||
if (this.validateEvent(set, setSources, event, eventSpecies)) continue;
|
||||
legal = true;
|
||||
break;
|
||||
}
|
||||
if (!legal && species.gen <= 2 && dex.gen >= 7 && !this.validateSource(set, '7V', setSources, species)) {
|
||||
legal = true;
|
||||
}
|
||||
if (!legal) {
|
||||
if (!pokemonGoProblems || (pokemonGoProblems && pokemonGoProblems.length)) {
|
||||
if (eventData.length === 1) {
|
||||
problems.push(`${species.name} is only obtainable from an event - it needs to match its event:`);
|
||||
} else {
|
||||
problems.push(`${species.name} is only obtainable from events - it needs to match one of its events:`);
|
||||
}
|
||||
for (const [i, event] of eventData.entries()) {
|
||||
if (event.generation <= dex.gen && event.generation >= this.minSourceGen) {
|
||||
const eventInfo = event;
|
||||
const eventNum = i + 1;
|
||||
const eventName = eventData.length > 1 ? ` #${eventNum}` : ``;
|
||||
const eventProblems = this.validateEvent(
|
||||
set, setSources, eventInfo, eventSpecies, ` to be`, `from its event${eventName}`
|
||||
);
|
||||
if (eventProblems) problems.push(...eventProblems);
|
||||
}
|
||||
}
|
||||
if (pokemonGoProblems && pokemonGoProblems.length) {
|
||||
problems.push(`Additionally, it failed to validate as a Pokemon from Pokemon GO because:`);
|
||||
for (const pokemonGoProblem of pokemonGoProblems) {
|
||||
problems.push(pokemonGoProblem);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setSources.isFromPokemonGo = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt move validation again after verifying Pokemon GO origin
|
||||
if (setSources.isFromPokemonGo) {
|
||||
setSources.restrictiveMoves = [];
|
||||
setSources.sources = ['8V'];
|
||||
setSources.sourcesBefore = 0;
|
||||
if (!moveProblems.length && ruleTable.has('obtainablemoves')) {
|
||||
problems.push(...this.validateMoves(outOfBattleSpecies, set.moves, setSources, set, name,
|
||||
moveLegalityWhitelist));
|
||||
}
|
||||
}
|
||||
|
||||
// Hardcoded forced validation for Pokemon GO
|
||||
const pokemonGoOnlySpecies = ['meltan', 'melmetal', 'gimmighoulroaming'];
|
||||
if (ruleTable.has('obtainablemisc') && (pokemonGoOnlySpecies.includes(species.id))) {
|
||||
setSources.isFromPokemonGo = true;
|
||||
if (pokemonGoProblems && pokemonGoProblems.length) {
|
||||
problems.push(`${name} is only obtainable from Pokemon GO, and failed to validate because:`);
|
||||
for (const pokemonGoProblem of pokemonGoProblems) {
|
||||
problems.push(pokemonGoProblem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ruleTable.isBanned('nonexistent')) {
|
||||
problems.push(...this.validateStats(set, species, setSources, pokemonGoProblems));
|
||||
}
|
||||
|
||||
if (ruleTable.has('obtainablemoves')) {
|
||||
if (species.id === 'keldeo' && set.moves.includes('secretsword') && this.minSourceGen > 5 && dex.gen <= 7) {
|
||||
problems.push(`${name} has Secret Sword, which is only compatible with Keldeo-Ordinary obtained from Gen 5.`);
|
||||
|
|
@ -850,7 +911,7 @@ export class TeamValidator {
|
|||
return problems;
|
||||
}
|
||||
|
||||
validateStats(set: PokemonSet, species: Species, setSources: PokemonSources) {
|
||||
validateStats(set: PokemonSet, species: Species, setSources: PokemonSources, pokemonGoProblems: string[] | null) {
|
||||
const ruleTable = this.ruleTable;
|
||||
const dex = this.dex;
|
||||
|
||||
|
|
@ -911,8 +972,18 @@ export class TeamValidator {
|
|||
if (set.ivs[stat as 'hp'] >= 31) perfectIVs++;
|
||||
}
|
||||
if (perfectIVs < 3) {
|
||||
const reason = (this.minSourceGen === 6 ? ` and this format requires Gen ${dex.gen} Pokémon` : ` in Gen 6 or later`);
|
||||
problems.push(`${name} must have at least three perfect IVs because it's a legendary${reason}.`);
|
||||
if (!pokemonGoProblems || (pokemonGoProblems && pokemonGoProblems.length)) {
|
||||
const reason = (this.minSourceGen === 6 ? ` and this format requires Gen ${dex.gen} Pokémon` : ` in Gen 6 or later`);
|
||||
problems.push(`${name} must have at least three perfect IVs because it's a legendary${reason}.`);
|
||||
if (pokemonGoProblems && pokemonGoProblems.length) {
|
||||
problems.push(`Additionally, it failed to validate as a Pokemon from Pokemon GO because:`);
|
||||
for (const pokemonGoProblem of pokemonGoProblems) {
|
||||
problems.push(pokemonGoProblem);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setSources.isFromPokemonGo = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -927,6 +998,25 @@ export class TeamValidator {
|
|||
}
|
||||
}
|
||||
|
||||
if (setSources.isFromPokemonGo) {
|
||||
// Pokemon from Pokemon GO must have odd IVs in non-Spe stats
|
||||
// Since the set can be fixed while making minimal changes, it does not force the IVs to be manually fixed
|
||||
for (const stat in set.ivs) {
|
||||
if (set.ivs[stat as 'hp'] % 2 === 0 && stat !== 'spe') {
|
||||
set.ivs[stat as 'hp']++;
|
||||
}
|
||||
}
|
||||
if (set.ivs.atk !== set.ivs.spa && !(canBottleCap && (set.ivs.atk === 31 || set.ivs.spa === 31))) {
|
||||
problems.push(`${name}'s Atk and Spa IVs must match because it is from Pokemon GO.`);
|
||||
}
|
||||
if (set.ivs.def !== set.ivs.spd && !(canBottleCap && (set.ivs.def === 31 || set.ivs.spd === 31))) {
|
||||
problems.push(`${name}'s Def and Spd IVs must match because it is from Pokemon GO.`);
|
||||
}
|
||||
if (set.hpType && set.hpType !== 'Dark' && set.hpType !== 'Ice') {
|
||||
problems.push(`${name} must have Hidden Power Dark or Ice because it is from Pokemon GO.`);
|
||||
}
|
||||
}
|
||||
|
||||
if (dex.gen <= 2) {
|
||||
// validate DVs
|
||||
const ivs = set.ivs;
|
||||
|
|
@ -1980,6 +2070,108 @@ export class TeamValidator {
|
|||
|
||||
return problems;
|
||||
}
|
||||
/**
|
||||
* Returns a list of problems regarding a Pokemon's avilability in Pokemon GO (empty list if no problems)
|
||||
* If the Pokemon cannot be obtained from Pokemon GO, returns null
|
||||
*/
|
||||
validatePokemonGo(
|
||||
species: Species, set: Partial<PokemonSet>, setSources: PokemonSources, name: string = species.name,
|
||||
): string[] | null {
|
||||
let problems = [];
|
||||
let minLevel = 50; // maximum level a Pokemon can be in Pokemon GO
|
||||
let minIVs = 15; // IVs range from 0 to 15 in Pokemon GO
|
||||
const dex = this.dex;
|
||||
const pokemonGoData = dex.species.getPokemonGoData(species.id);
|
||||
if (dex.gen < 8 || this.format.mod === 'gen8dlc1') return null;
|
||||
if (!pokemonGoData) {
|
||||
// Handles forms and evolutions not obtainable from Pokemon GO
|
||||
const otherSpecies = this.learnsetParent(species);
|
||||
// If a Pokemon is somehow not obtainable from Pokemon GO and it must be leveled up to be evolved,
|
||||
// validation for the game should stop because it's more optimal to get the Pokemon outside of the game
|
||||
if (otherSpecies && !species.evoLevel) {
|
||||
const otherProblems = this.validatePokemonGo(otherSpecies, set, setSources, name);
|
||||
if (otherProblems) {
|
||||
problems = otherProblems;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
const pokemonGoSources = pokemonGoData.encounters;
|
||||
// should never happen
|
||||
if (!pokemonGoSources) throw new Error(`Species with no Pokemon GO data: ${species.id}`);
|
||||
if (set.shiny) name = "Shiny " + name;
|
||||
if (set.shiny && pokemonGoSources.includes('noshiny')) {
|
||||
problems.push(`${name} is not obtainable from Pokemon GO.`);
|
||||
} else {
|
||||
if (pokemonGoSources.includes('wild') && !((set.shiny && pokemonGoSources.includes('nowildshiny')))) {
|
||||
minLevel = 1;
|
||||
minIVs = 0;
|
||||
}
|
||||
if (pokemonGoSources.includes('egg')) {
|
||||
/**
|
||||
* A Pokemon's level when hatched is determined by the trainer's level when it is obtained
|
||||
* It is no longer possible for new accounts to obtain eggs at level 1 because they will have reached
|
||||
* level 2 by the time they can spin a PokeStop. However, it might be possible for a sleeper account
|
||||
* from before XP changes to get a level 1 egg from spinning a PokeStop that sends the account to
|
||||
* level 2, but this needs research
|
||||
*/
|
||||
minLevel = Math.min(minLevel, 2);
|
||||
minIVs = Math.min(minIVs, 10);
|
||||
}
|
||||
if (pokemonGoSources.includes('12kmegg')) {
|
||||
minLevel = Math.min(minLevel, 8);
|
||||
minIVs = Math.min(minIVs, 10);
|
||||
}
|
||||
if (pokemonGoSources.includes('raid')) {
|
||||
minLevel = Math.min(minLevel, 20);
|
||||
minIVs = Math.min(minIVs, 10);
|
||||
}
|
||||
if (species.id === 'mewtwo' && set.level && set.level >= 20) {
|
||||
// A bug allowed Mewtwo to be encountered with an IV floor of 0 from GO Battle League
|
||||
minIVs = Math.min(minIVs, 0);
|
||||
}
|
||||
if (pokemonGoSources.includes('research')) {
|
||||
minLevel = Math.min(minLevel, 15);
|
||||
minIVs = Math.min(minIVs, 10);
|
||||
}
|
||||
if (pokemonGoSources.includes('giovanni') && !set.shiny) {
|
||||
/**
|
||||
* Purified Pokemon can be leveled down to level 8 after trading; they are forced to
|
||||
* special trades, but currently all Giovanni Shadow Pokemon are already forced special trades
|
||||
*/
|
||||
minLevel = Math.min(minLevel, 8);
|
||||
minIVs = Math.min(minIVs, 1);
|
||||
if (set.level && set.level < 12) setSources.pokemonGoSource = "purified";
|
||||
}
|
||||
// Attempt to trade the Pokemon to reduce level and IVs
|
||||
if (!pokemonGoSources.includes('notrade')) {
|
||||
// Special trades require a good friend
|
||||
// Trading with a friend of this level has an IV floor of 1
|
||||
// Note that (non-shiny) Deoxys could be traded for a short time when it was introduced
|
||||
if (!set.shiny || species.id !== 'deoxys') {
|
||||
const specialTrade = pokemonGoSources.includes('specialtrade') || set.shiny;
|
||||
minLevel = Math.min(minLevel, 12);
|
||||
minIVs = Math.min(minIVs, specialTrade ? 1 : 0);
|
||||
}
|
||||
}
|
||||
if (set.level && set.level < minLevel) {
|
||||
problems.push(`${name} must be at least level ${minLevel} to be from Pokemon GO.`);
|
||||
}
|
||||
const ivs = set.ivs || TeamValidator.fillStats(null, 31);
|
||||
for (const stat in ivs) {
|
||||
if (Math.floor(ivs[stat as 'hp'] / 2) < minIVs && stat !== 'spe') {
|
||||
problems.push(`${name} must have at least ${minIVs} ` +
|
||||
(minIVs === 1 ? `IV` : `IVs`) + ` in non-Speed stats to be from Pokemon GO.`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return problems;
|
||||
}
|
||||
|
||||
omCheckCanLearn(
|
||||
move: Move,
|
||||
|
|
@ -2168,7 +2360,8 @@ export class TeamValidator {
|
|||
// falls through to LMT check below
|
||||
} else if (level >= 5 && learnedGen === 3 && species.canHatch) {
|
||||
// Pomeg Glitch
|
||||
} else if ((!species.gender || species.gender === 'F') && learnedGen >= 2 && species.canHatch) {
|
||||
} else if ((!species.gender || species.gender === 'F') &&
|
||||
learnedGen >= 2 && species.canHatch && !setSources.isFromPokemonGo) {
|
||||
// available as egg move
|
||||
learned = learnedGen + 'Eany';
|
||||
// falls through to E check below
|
||||
|
|
@ -2184,7 +2377,14 @@ export class TeamValidator {
|
|||
if (learnedGen === dex.gen && learned.charAt(1) !== 'R') {
|
||||
// current-gen level-up, TM or tutor moves:
|
||||
// always available
|
||||
if (!(learnedGen >= 8 && learned.charAt(1) === 'E') && babyOnly) setSources.babyOnly = babyOnly;
|
||||
if (!(learnedGen >= 8 && learned.charAt(1) === 'E') && babyOnly) {
|
||||
if (setSources.isFromPokemonGo && species.evoLevel) {
|
||||
cantLearnReason = `is from a prevo, which is incompatible with its Pokemon GO origin.`;
|
||||
continue;
|
||||
} else {
|
||||
setSources.babyOnly = babyOnly;
|
||||
}
|
||||
}
|
||||
if (!moveSources.moveEvoCarryCount) return null;
|
||||
}
|
||||
// past-gen level-up, TM, or tutor moves:
|
||||
|
|
@ -2227,6 +2427,10 @@ export class TeamValidator {
|
|||
} else if (learned.charAt(1) === 'V' && this.minSourceGen < learnedGen) {
|
||||
// Virtual Console or Let's Go transfer moves:
|
||||
// only if that was the source
|
||||
if (learned === '8V' && setSources.isFromPokemonGo && babyOnly && species.evoLevel) {
|
||||
cantLearnReason = `is from a prevo, which is incompatible with its Pokemon GO origin.`;
|
||||
continue;
|
||||
}
|
||||
moveSources.add(learned);
|
||||
}
|
||||
}
|
||||
|
|
@ -2283,6 +2487,39 @@ export class TeamValidator {
|
|||
}
|
||||
setSources.restrictiveMoves.push(move.name);
|
||||
|
||||
const checkedSpecies = babyOnly ? species : baseSpecies;
|
||||
if (checkedSpecies && setSources.isFromPokemonGo &&
|
||||
(setSources.pokemonGoSource === 'purified' || checkedSpecies.id === 'mew')) {
|
||||
// Pokemon that cannot be sent from Pokemon GO to Let's Go can only access Let's Go moves through HOME
|
||||
// It can only obtain a chain of four level up moves and cannot have TM moves
|
||||
const pokemonGoData = dex.species.getPokemonGoData(checkedSpecies.id);
|
||||
if (pokemonGoData.LGPERestrictiveMoves) {
|
||||
let levelUpMoveCount = 0;
|
||||
const restrictiveMovesToID = [];
|
||||
for (const moveName of setSources.restrictiveMoves) {
|
||||
restrictiveMovesToID.push(toID(moveName));
|
||||
}
|
||||
for (const restrictiveMove in pokemonGoData.LGPERestrictiveMoves) {
|
||||
const moveLevel = pokemonGoData.LGPERestrictiveMoves[restrictiveMove];
|
||||
if (toID(move) === restrictiveMove) {
|
||||
if (!moveLevel) {
|
||||
return `'s move ${move.name} is incompatible with its Pokemon GO origin.`;
|
||||
} else if (set.level && set.level < moveLevel) {
|
||||
return ` must be at least level ${moveLevel} to learn ${move.name} due to its Pokemon GO origin.`;
|
||||
}
|
||||
}
|
||||
if (levelUpMoveCount) levelUpMoveCount++;
|
||||
if (restrictiveMovesToID.includes(restrictiveMove)) {
|
||||
if (!levelUpMoveCount) {
|
||||
levelUpMoveCount++;
|
||||
} else if (levelUpMoveCount > 4) {
|
||||
return `'s moves ${(setSources.restrictiveMoves || []).join(', ')} are incompatible with its Pokemon GO origin.`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we have our list of possible sources, intersect it with the current list
|
||||
if (!moveSources.size()) {
|
||||
if (cantLearnReason) return `'s move ${move.name} ${cantLearnReason}`;
|
||||
|
|
@ -2296,6 +2533,7 @@ export class TeamValidator {
|
|||
// prevents a crash if OMs override `checkCanLearn` to keep validating after an error
|
||||
setSources.sources = backupSources;
|
||||
setSources.sourcesBefore = backupSourcesBefore;
|
||||
if (setSources.isFromPokemonGo) return `'s move ${move.name} is incompatible with its Pokemon GO origin.`;
|
||||
return `'s moves ${(setSources.restrictiveMoves || []).join(', ')} are incompatible.`;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ describe('Team Validator', function () {
|
|||
{species: 'nidoking', level: 1, ability: 'sheerforce', moves: ['earthpower'], evs: {hp: 1}},
|
||||
{species: 'mamoswine', level: 1, ability: 'oblivious', moves: ['earthquake'], evs: {hp: 1}},
|
||||
];
|
||||
assert.false.legalTeam(team, 'gen8anythinggoes');
|
||||
assert.false.legalTeam(team, 'gen7anythinggoes');
|
||||
});
|
||||
|
||||
it('should require Pokémon transferred from Gens 1 and 2 to be above Level 2', () => {
|
||||
|
|
@ -135,4 +135,23 @@ describe('Team Validator', function () {
|
|||
assert.legalTeam(team, 'gen8purehackmons');
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow various (underleveled) from Pokemon GO', function () {
|
||||
const team = [
|
||||
{species: 'mewtwo', level: 20, ability: 'pressure', moves: ['agility'], evs: {hp: 1}, ivs: {hp: 1, atk: 1, def: 1, spa: 1, spd: 1}},
|
||||
{species: 'donphan', level: 1, ability: 'sturdy', moves: ['endeavor']},
|
||||
{species: 'mew', shiny: true, level: 15, ability: 'synchronize', moves: ['pound'], evs: {hp: 1}},
|
||||
{species: 'uxie', level: 1, ability: 'levitate', moves: ['acrobatics']},
|
||||
{species: 'zacian', ability: 'intrepidsword', moves: ['agility'], evs: {hp: 1}},
|
||||
{species: 'volcarona', level: 2, ability: 'flamebody', moves: ['acrobatics'], evs: {hp: 1}},
|
||||
];
|
||||
assert.legalTeam(team, 'gen9ubers');
|
||||
});
|
||||
|
||||
it('should disallow Pokemon from Pokemon GO knowing incompatible moves', function () {
|
||||
const team = [
|
||||
{species: 'mew', shiny: true, level: 15, ability: 'synchronize', moves: ['aircutter'], evs: {hp: 1}, ivs: {hp: 21, atk: 31, def: 21, spa: 21, spd: 31, spe: 0}},
|
||||
];
|
||||
assert.false.legalTeam(team, 'gen8ou');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user