diff --git a/src/data/move.ts b/src/data/move.ts index 715ac533ae7..12c9daf0dea 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -4917,14 +4917,36 @@ export class CopyMoveAttr extends OverrideMoveEffectAttr { } } +/** + * Attribute used for moves that reduce PP of the target's last used move. + * Used for Spite. + */ export class ReducePpMoveAttr extends MoveEffectAttr { + protected reduction: number; + constructor(reduction: number) { + super(); + this.reduction = reduction; + } + + /** + * Reduces the PP of the target's last-used move by an amount based on this attribute instance's {@linkcode reduction}. + * + * @param user {@linkcode Pokemon} that used the attack + * @param target {@linkcode Pokemon} targeted by the attack + * @param move {@linkcode Move} being used + * @param args N/A + * @returns {boolean} true + */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { // Null checks can be skipped due to condition function const lastMove = target.getLastXMoves().find(() => true); const movesetMove = target.getMoveset().find(m => m.moveId === lastMove.move); const lastPpUsed = movesetMove.ppUsed; - movesetMove.ppUsed = Math.min(movesetMove.ppUsed + 4, movesetMove.getMovePp()); - user.scene.queueMessage(`It reduced the PP of ${getPokemonMessage(target, `'s\n${movesetMove.getName()} by ${movesetMove.ppUsed - lastPpUsed}!`)}`); + movesetMove.ppUsed = Math.min(movesetMove.ppUsed + this.reduction, movesetMove.getMovePp()); + + const message = i18next.t("battle:ppReduced", {targetName: target.name, moveName: movesetMove.getName(), reduction: movesetMove.ppUsed - lastPpUsed}); + + user.scene.queueMessage(message); return true; } @@ -4959,6 +4981,42 @@ export class ReducePpMoveAttr extends MoveEffectAttr { } } +/** + * Attribute used for moves that damage target, and then reduce PP of the target's last used move. + * Used for Eerie Spell. + */ +export class AttackReducePpMoveAttr extends ReducePpMoveAttr { + constructor(reduction: number) { + super(reduction); + } + + /** + * Checks if the target has used a move prior to the attack. PP-reduction is applied through the super class if so. + * + * @param user {@linkcode Pokemon} that used the attack + * @param target {@linkcode Pokemon} targeted by the attack + * @param move {@linkcode Move} being used + * @param args N/A + * @returns {boolean} true + */ + apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + const lastMove = target.getLastXMoves().find(() => true); + if (lastMove) { + const movesetMove = target.getMoveset().find(m => m.moveId === lastMove.move); + if (Boolean(movesetMove?.getPpRatio())) { + super.apply(user, target, move, args); + } + } + + return true; + } + + // Override condition function to always perform damage. Instead, perform pp-reduction condition check in apply function above + getCondition(): MoveConditionFunc { + return (user, target, move) => true; + } +} + // TODO: Review this const targetMoveCopiableCondition: MoveConditionFunc = (user, target, move) => { const targetMoves = target.getMoveHistory().filter(m => !m.virtual); @@ -5990,7 +6048,7 @@ export function initMoves() { new AttackMove(Moves.REVERSAL, Type.FIGHTING, MoveCategory.PHYSICAL, -1, 100, 15, -1, 0, 2) .attr(LowHpPowerAttr), new StatusMove(Moves.SPITE, Type.GHOST, 100, 10, -1, 0, 2) - .attr(ReducePpMoveAttr), + .attr(ReducePpMoveAttr, 4), new AttackMove(Moves.POWDER_SNOW, Type.ICE, MoveCategory.SPECIAL, 40, 100, 25, 10, 0, 2) .attr(StatusEffectAttr, StatusEffect.FREEZE) .target(MoveTarget.ALL_NEAR_ENEMIES), @@ -7856,8 +7914,8 @@ export function initMoves() { new AttackMove(Moves.ASTRAL_BARRAGE, Type.GHOST, MoveCategory.SPECIAL, 120, 100, 5, -1, 0, 8) .target(MoveTarget.ALL_NEAR_ENEMIES), new AttackMove(Moves.EERIE_SPELL, Type.PSYCHIC, MoveCategory.SPECIAL, 80, 100, 5, 100, 0, 8) - .soundBased() - .partial(), + .attr(AttackReducePpMoveAttr, 3) + .soundBased(), new AttackMove(Moves.DIRE_CLAW, Type.POISON, MoveCategory.PHYSICAL, 80, 100, 15, 50, 0, 8) .attr(MultiStatusEffectAttr, [StatusEffect.POISON, StatusEffect.PARALYSIS, StatusEffect.SLEEP]), new AttackMove(Moves.PSYSHIELD_BASH, Type.PSYCHIC, MoveCategory.PHYSICAL, 70, 90, 10, 100, 0, 8) diff --git a/src/locales/de/battle.ts b/src/locales/de/battle.ts index 48f355e7ea1..240ba572b51 100644 --- a/src/locales/de/battle.ts +++ b/src/locales/de/battle.ts @@ -70,4 +70,5 @@ export const battle: SimpleTranslationEntries = { "statHarshlyFell": "sinkt stark", "statSeverelyFell": "sinkt drastisch", "statWontGoAnyLower": "kann nicht weiter sinken", + "ppReduced": "It reduced the PP of {{targetName}}'s\n{{moveName}} by {{reduction}}!", } as const; diff --git a/src/locales/en/battle.ts b/src/locales/en/battle.ts index 39393331a72..874804f95b7 100644 --- a/src/locales/en/battle.ts +++ b/src/locales/en/battle.ts @@ -70,4 +70,5 @@ export const battle: SimpleTranslationEntries = { "statHarshlyFell": "harshly fell", "statSeverelyFell": "severely fell", "statWontGoAnyLower": "won't go any lower", + "ppReduced": "It reduced the PP of {{targetName}}'s\n{{moveName}} by {{reduction}}!", } as const; diff --git a/src/locales/es/battle.ts b/src/locales/es/battle.ts index 875421617de..e7675408e06 100644 --- a/src/locales/es/battle.ts +++ b/src/locales/es/battle.ts @@ -70,4 +70,5 @@ export const battle: SimpleTranslationEntries = { "statHarshlyFell": "harshly fell", "statSeverelyFell": "severely fell", "statWontGoAnyLower": "won't go any lower", + "ppReduced": "It reduced the PP of {{targetName}}'s\n{{moveName}} by {{reduction}}!", } as const; diff --git a/src/locales/fr/battle.ts b/src/locales/fr/battle.ts index 3bb051830ee..88cec801ef3 100644 --- a/src/locales/fr/battle.ts +++ b/src/locales/fr/battle.ts @@ -70,4 +70,5 @@ export const battle: SimpleTranslationEntries = { "statHarshlyFell": "harshly fell", "statSeverelyFell": "severely fell", "statWontGoAnyLower": "won't go any lower", + "ppReduced": "It reduced the PP of {{targetName}}'s\n{{moveName}} by {{reduction}}!", } as const; diff --git a/src/locales/it/battle.ts b/src/locales/it/battle.ts index 8fb9cf56c70..f605c28a44b 100644 --- a/src/locales/it/battle.ts +++ b/src/locales/it/battle.ts @@ -70,4 +70,5 @@ export const battle: SimpleTranslationEntries = { "statHarshlyFell": "harshly fell", "statSeverelyFell": "severely fell", "statWontGoAnyLower": "won't go any lower", + "ppReduced": "It reduced the PP of {{targetName}}'s\n{{moveName}} by {{reduction}}!", } as const; diff --git a/src/locales/ko/battle.ts b/src/locales/ko/battle.ts index e9be8a7fa43..be78a1c8bbb 100644 --- a/src/locales/ko/battle.ts +++ b/src/locales/ko/battle.ts @@ -70,4 +70,5 @@ export const battle: SimpleTranslationEntries = { "statHarshlyFell": "[[가]] 크게 떨어졌다!", "statSeverelyFell": "[[가]] 매우 크게 떨어졌다!", "statWontGoAnyLower": "[[는]] 더 떨어지지 않는다!", + "ppReduced": "It reduced the PP of {{targetName}}'s\n{{moveName}} by {{reduction}}!", } as const; diff --git a/src/locales/pt_BR/battle.ts b/src/locales/pt_BR/battle.ts index 72d97f9f1cf..f4f6bda3c71 100644 --- a/src/locales/pt_BR/battle.ts +++ b/src/locales/pt_BR/battle.ts @@ -70,4 +70,5 @@ export const battle: SimpleTranslationEntries = { "statHarshlyFell": "diminuiu duramente", "statSeverelyFell": "diminuiu severamente", "statWontGoAnyLower": "não vai mais diminuir", + "ppReduced": "It reduced the PP of {{targetName}}'s\n{{moveName}} by {{reduction}}!", } as const; diff --git a/src/locales/zh_CN/battle.ts b/src/locales/zh_CN/battle.ts index 8c607a6ade6..518d2408f07 100644 --- a/src/locales/zh_CN/battle.ts +++ b/src/locales/zh_CN/battle.ts @@ -70,4 +70,5 @@ export const battle: SimpleTranslationEntries = { "statHarshlyFell": "大幅降低了!", "statSeverelyFell": "极大幅降低了!", "statWontGoAnyLower": "已经无法再降低了!", + "ppReduced": "It reduced the PP of {{targetName}}'s\n{{moveName}} by {{reduction}}!", } as const; diff --git a/src/locales/zh_TW/battle.ts b/src/locales/zh_TW/battle.ts index 224a9f2bf0f..a7b1c748362 100644 --- a/src/locales/zh_TW/battle.ts +++ b/src/locales/zh_TW/battle.ts @@ -67,4 +67,5 @@ export const battle: SimpleTranslationEntries = { "statHarshlyFell": "harshly fell", "statSeverelyFell": "severely fell", "statWontGoAnyLower": "won't go any lower", + "ppReduced": "It reduced the PP of {{targetName}}'s\n{{moveName}} by {{reduction}}!", } as const; diff --git a/src/phases.ts b/src/phases.ts index f4c32284f8c..766aa55cae8 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -2581,6 +2581,11 @@ export class MovePhase extends BattlePhase { if (this.move.moveId && this.pokemon.summonData?.disabledMove === this.move.moveId) { this.scene.queueMessage(`${this.move.getName()} is disabled!`); } + if (this.move.ppUsed >= this.move.getMovePp()) { // if the move PP was reduced from Spite or otherwise, the move fails + this.fail(); + this.showMoveText(); + this.showFailedText(); + } return this.end(); }