mirror of
https://github.com/smogon/pokemon-showdown.git
synced 2026-03-21 17:25:10 -05:00
Gen 1: Fix underflow glitch applied to mimicked duplicate moves (#11746)
Some checks failed
Node.js CI / build (18.x) (push) Has been cancelled
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:
parent
f4889cac74
commit
1091524b94
|
|
@ -458,6 +458,22 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
||||||
target: "self",
|
target: "self",
|
||||||
type: "Psychic",
|
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: {
|
mimic: {
|
||||||
inherit: true,
|
inherit: true,
|
||||||
flags: { protect: 1, bypasssub: 1, metronome: 1 },
|
flags: { protect: 1, bypasssub: 1, metronome: 1 },
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,25 @@ export const Scripts: ModdedBattleScriptsData = {
|
||||||
// BattlePokemon scripts.
|
// BattlePokemon scripts.
|
||||||
pokemon: {
|
pokemon: {
|
||||||
inherit: true,
|
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) {
|
getStat(statName, unmodified) {
|
||||||
// @ts-expect-error type checking prevents 'hp' from being passed, but we're paranoid
|
// @ts-expect-error type checking prevents 'hp' from being passed, but we're paranoid
|
||||||
if (statName === 'hp') throw new Error("Please read `maxhp` directly");
|
if (statName === 'hp') throw new Error("Please read `maxhp` directly");
|
||||||
|
|
|
||||||
|
|
@ -1087,9 +1087,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
||||||
flags: { noassist: 1, failcopycat: 1, nosleeptalk: 1, failmimic: 1 },
|
flags: { noassist: 1, failcopycat: 1, nosleeptalk: 1, failmimic: 1 },
|
||||||
onHit(pokemon) {
|
onHit(pokemon) {
|
||||||
const moves = this.dex.moves.all().filter(move => (
|
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.isNonstandard || move.isNonstandard === 'Unobtainable') &&
|
||||||
move.flags['metronome'] &&
|
|
||||||
!(this.field.pseudoWeather['gravity'] && move.flags['gravity']) &&
|
!(this.field.pseudoWeather['gravity'] && move.flags['gravity']) &&
|
||||||
!(pokemon.volatiles['healblock'] && move.flags['heal'])
|
!(pokemon.volatiles['healblock'] && move.flags['heal'])
|
||||||
));
|
));
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
|
||||||
inherit: true,
|
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.",
|
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.",
|
shortDesc: "Picks a random move from gen 1.",
|
||||||
onHit(target, source, effect) {
|
onHit(target) {
|
||||||
const moves = this.dex.moves.all().filter(move => move.gen === 1 && move.flags['metronome']);
|
const moves = this.dex.moves.all().filter(move => (
|
||||||
|
(!move.isNonstandard || move.isNonstandard === 'Unobtainable') &&
|
||||||
|
move.flags['metronome'] && move.gen === 1
|
||||||
|
));
|
||||||
let randomMove = '';
|
let randomMove = '';
|
||||||
if (moves.length) {
|
if (moves.length) {
|
||||||
moves.sort((a, b) => a.num - b.num);
|
moves.sort((a, b) => a.num - b.num);
|
||||||
|
|
|
||||||
|
|
@ -876,16 +876,15 @@ export class Pokemon {
|
||||||
}
|
}
|
||||||
|
|
||||||
deductPP(move: string | Move, amount?: number | null, target?: Pokemon | null | false) {
|
deductPP(move: string | Move, amount?: number | null, target?: Pokemon | null | false) {
|
||||||
const gen = this.battle.gen;
|
|
||||||
move = this.battle.dex.moves.get(move);
|
move = this.battle.dex.moves.get(move);
|
||||||
const ppData = this.getMoveData(move);
|
const ppData = this.getMoveData(move);
|
||||||
if (!ppData) return 0;
|
if (!ppData) return 0;
|
||||||
ppData.used = true;
|
ppData.used = true;
|
||||||
if (!ppData.pp && gen > 1) return 0;
|
if (!ppData.pp) return 0;
|
||||||
|
|
||||||
if (!amount) amount = 1;
|
if (!amount) amount = 1;
|
||||||
ppData.pp -= amount;
|
ppData.pp -= amount;
|
||||||
if (ppData.pp < 0 && gen > 1) {
|
if (ppData.pp < 0) {
|
||||||
amount += ppData.pp;
|
amount += ppData.pp;
|
||||||
ppData.pp = 0;
|
ppData.pp = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user