Optimize Pokemon Go validation (#11840)
Some checks are pending
Node.js CI / build (18.x) (push) Waiting to run

This commit is contained in:
dot-Comfey
2026-03-23 22:33:36 -07:00
committed by GitHub
parent 0effd41ff7
commit ee0cf5e37d

View File

@@ -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.`;
}