mirror of
https://github.com/smogon/pokemon-showdown.git
synced 2026-10-02 14:17:43 -05:00
Optimize Pokemon Go validation (#11840)
Some checks are pending
Node.js CI / build (18.x) (push) Waiting to run
Some checks are pending
Node.js CI / build (18.x) (push) Waiting to run
This commit is contained in:
@@ -112,6 +112,11 @@ export class PokemonSources {
|
||||
* Used to deal with compatibility issues for prevo/evo-exclusive moves
|
||||
*/
|
||||
learnsetDomain?: string[] | null;
|
||||
/**
|
||||
* A list of moves which are incompatible with a Pokemon GO origin,
|
||||
* used to generate error messages
|
||||
*/
|
||||
goIncompatibleMoves?: string[];
|
||||
/**
|
||||
* Some Pokemon evolve by having a move in their learnset (like Piloswine
|
||||
* with Ancient Power). These can only carry three other moves from their
|
||||
@@ -311,6 +316,16 @@ export class PokemonSources {
|
||||
this.dreamWorldMoveCount += other.dreamWorldMoveCount;
|
||||
if (other.sourcesAfter > this.sourcesAfter) this.sourcesAfter = other.sourcesAfter;
|
||||
if (other.isHidden) this.isHidden = true;
|
||||
|
||||
if (other.sourcesBefore < 8 && !other.sources.some(source => source === '8V') && this.restrictiveMoves) {
|
||||
this.addGoIncompatibleMove(this.restrictiveMoves[this.restrictiveMoves.length - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
addGoIncompatibleMove(move: string) {
|
||||
if (!this.goIncompatibleMoves) this.goIncompatibleMoves = [];
|
||||
if (move) this.goIncompatibleMoves.push(move);
|
||||
this.isFromPokemonGo = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -854,6 +869,16 @@ export class TeamValidator {
|
||||
if (ruleTable.has('obtainablemoves')) {
|
||||
moveProblems = this.validateMoves(outOfBattleSpecies, set.moves, setSources, set, name, moveLegalityWhitelist);
|
||||
problems.push(...moveProblems);
|
||||
|
||||
const incompatibleMoves = setSources.goIncompatibleMoves;
|
||||
if (pokemonGoProblems && incompatibleMoves) {
|
||||
if (incompatibleMoves?.length) {
|
||||
pokemonGoProblems.push(`${name}'s move${incompatibleMoves.length === 1 ? `` : `s`} ${incompatibleMoves.join(`, `)} ` +
|
||||
`${incompatibleMoves.length === 1 ? `is` : `are`} incompatible with a Pokemon GO origin.`);
|
||||
} else {
|
||||
pokemonGoProblems.push(`${name} has moves which are incompatible with a Pokemon GO origin.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let eventOnlyData;
|
||||
@@ -1005,7 +1030,6 @@ export class TeamValidator {
|
||||
// Hardcoded forced validation for Pokemon GO
|
||||
const pokemonGoOnlySpecies = ['meltan', 'melmetal', 'gimmighoulroaming'];
|
||||
if (ruleTable.has('obtainablemisc') && (pokemonGoOnlySpecies.includes(species.id))) {
|
||||
setSources.isFromPokemonGo = true;
|
||||
if (pokemonGoProblems?.length) {
|
||||
problems.push(`${name} is only obtainable from Pokemon GO, and failed to validate because:`);
|
||||
for (const pokemonGoProblem of pokemonGoProblems) {
|
||||
@@ -1014,17 +1038,6 @@ export class TeamValidator {
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt move validation again after verifying Pokemon GO origin
|
||||
if (ruleTable.has('obtainablemoves') && setSources.isFromPokemonGo) {
|
||||
setSources.restrictiveMoves = [];
|
||||
setSources.sources = ['8V'];
|
||||
setSources.sourcesBefore = 0;
|
||||
if (moveProblems && !moveProblems.length) {
|
||||
problems.push(...this.validateMoves(outOfBattleSpecies, set.moves, setSources, set, name,
|
||||
moveLegalityWhitelist));
|
||||
}
|
||||
}
|
||||
|
||||
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.`);
|
||||
@@ -2359,9 +2372,11 @@ export class TeamValidator {
|
||||
if (otherProblems) {
|
||||
problems = otherProblems;
|
||||
} else {
|
||||
setSources.isFromPokemonGo = false;
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
setSources.isFromPokemonGo = false;
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
@@ -2655,8 +2670,7 @@ export class TeamValidator {
|
||||
} else if (this.ruleTable.has('pomegglitchclause') && level >= 5 && learnedGen === 3 && species.canHatch) {
|
||||
// Pomeg Glitch
|
||||
learned = `${learnedGen}Epomeg` as MoveSource;
|
||||
} else if (species.gender !== 'N' &&
|
||||
learnedGen >= 2 && species.canHatch && !setSources.isFromPokemonGo) {
|
||||
} else if (species.gender !== 'N' && learnedGen >= 2 && species.canHatch) {
|
||||
// available as egg move
|
||||
if (species.gender === 'M' && !this.motherCanLearn(toID(species.mother), moveid)) {
|
||||
// male-only Pokemon can have level-up egg moves if it can have a mother that learns the move
|
||||
@@ -2678,10 +2692,8 @@ 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.isFromPokemonGo && species.evoLevel) {
|
||||
cantLearnReason = `is from a prevo, which is incompatible with its Pokemon GO origin.`;
|
||||
continue;
|
||||
if (!(learnedGen >= 8 && learned.charAt(1) === 'E') && babyOnly && species.evoLevel) {
|
||||
setSources.addGoIncompatibleMove(move.name);
|
||||
}
|
||||
if (!moveSources.moveEvoCarryCount && !babyOnly) return null;
|
||||
}
|
||||
@@ -2740,9 +2752,8 @@ 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;
|
||||
if (learned === '8V' && babyOnly && species.evoLevel) {
|
||||
setSources.addGoIncompatibleMove(move.name);
|
||||
}
|
||||
moveSources.add(learned);
|
||||
}
|
||||
@@ -2822,8 +2833,7 @@ export class TeamValidator {
|
||||
}
|
||||
|
||||
const checkedSpecies = babyOnly ? fullLearnset[fullLearnset.length - 1].species : baseSpecies;
|
||||
if (checkedSpecies && setSources.isFromPokemonGo &&
|
||||
(setSources.pokemonGoSource === 'purified' || checkedSpecies.id === 'mew')) {
|
||||
if (checkedSpecies && (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);
|
||||
@@ -2836,10 +2846,8 @@ export class TeamValidator {
|
||||
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 (!moveLevel || (set.level && set.level < moveLevel)) {
|
||||
setSources.addGoIncompatibleMove(move.name);
|
||||
}
|
||||
}
|
||||
if (levelUpMoveCount) levelUpMoveCount++;
|
||||
@@ -2847,7 +2855,8 @@ export class TeamValidator {
|
||||
if (!levelUpMoveCount) {
|
||||
levelUpMoveCount++;
|
||||
} else if (levelUpMoveCount > 4) {
|
||||
return `'s moves ${(setSources.restrictiveMoves || []).join(', ')} are incompatible with its Pokemon GO origin.`;
|
||||
// Moves which are only incompatible when together
|
||||
setSources.addGoIncompatibleMove('');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2901,7 +2910,6 @@ 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.`;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user