Gen 1: Fix underflow glitch applied to mimicked duplicate moves (#11746)
Some checks failed
Node.js CI / build (18.x) (push) Has been cancelled

* Fix underflow glitch applied to mimicked duplicate moves

* Remove flags

* Remove console.log
This commit is contained in:
André Bastos Dias 2026-02-18 01:36:37 +00:00 committed by GitHub
parent f4889cac74
commit 1091524b94
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 43 additions and 7 deletions

View File

@ -458,6 +458,22 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
target: "self",
type: "Psychic",
},
metronome: {
inherit: true,
onHit(pokemon) {
const moves = this.dex.moves.all().filter(move => (
(!move.isNonstandard || move.isNonstandard === 'Unobtainable') && move.flags['metronome']
));
let randomMove = '';
if (moves.length) {
moves.sort((a, b) => a.num - b.num);
randomMove = this.sample(moves).id;
}
if (!randomMove) return false;
pokemon.side.lastSelectedMove = this.toID(randomMove);
this.actions.useMove(randomMove, pokemon);
},
},
mimic: {
inherit: true,
flags: { protect: 1, bypasssub: 1, metronome: 1 },

View File

@ -25,6 +25,25 @@ export const Scripts: ModdedBattleScriptsData = {
// BattlePokemon scripts.
pokemon: {
inherit: true,
// In gen 1, a Pokémon can have two instances of the same move using Mimic
// we need to make sure to deduct PP from a move that has PP left
deductPP(move, amount, target) {
move = this.battle.dex.moves.get(move);
// first loop: get the first instance with PP left
// second loop: get the first instance, even if it has no PP left
for (let i = 0; i < 2; i++) {
for (const ppData of this.moveSlots) {
if (ppData.id !== move.id) continue;
ppData.used = true;
if (!ppData.pp && i === 0) continue;
if (!amount) amount = 1;
ppData.pp -= amount;
return amount;
}
}
return 0;
},
getStat(statName, unmodified) {
// @ts-expect-error type checking prevents 'hp' from being passed, but we're paranoid
if (statName === 'hp') throw new Error("Please read `maxhp` directly");

View File

@ -1087,9 +1087,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
flags: { noassist: 1, failcopycat: 1, nosleeptalk: 1, failmimic: 1 },
onHit(pokemon) {
const moves = this.dex.moves.all().filter(move => (
(![2, 4].includes(this.gen) || !pokemon.moves.includes(move.id)) &&
move.flags['metronome'] && !pokemon.moves.includes(move.id) &&
(!move.isNonstandard || move.isNonstandard === 'Unobtainable') &&
move.flags['metronome'] &&
!(this.field.pseudoWeather['gravity'] && move.flags['gravity']) &&
!(pokemon.volatiles['healblock'] && move.flags['heal'])
));

View File

@ -41,8 +41,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
inherit: true,
desc: "A random move that was introduced in gen 1 is selected for use, other than Counter, Mimic, Mirror Move, Struggle, or Transform.",
shortDesc: "Picks a random move from gen 1.",
onHit(target, source, effect) {
const moves = this.dex.moves.all().filter(move => move.gen === 1 && move.flags['metronome']);
onHit(target) {
const moves = this.dex.moves.all().filter(move => (
(!move.isNonstandard || move.isNonstandard === 'Unobtainable') &&
move.flags['metronome'] && move.gen === 1
));
let randomMove = '';
if (moves.length) {
moves.sort((a, b) => a.num - b.num);

View File

@ -876,16 +876,15 @@ export class Pokemon {
}
deductPP(move: string | Move, amount?: number | null, target?: Pokemon | null | false) {
const gen = this.battle.gen;
move = this.battle.dex.moves.get(move);
const ppData = this.getMoveData(move);
if (!ppData) return 0;
ppData.used = true;
if (!ppData.pp && gen > 1) return 0;
if (!ppData.pp) return 0;
if (!amount) amount = 1;
ppData.pp -= amount;
if (ppData.pp < 0 && gen > 1) {
if (ppData.pp < 0) {
amount += ppData.pp;
ppData.pp = 0;
}