diff --git a/src/data/move.ts b/src/data/move.ts index 033167abf69..84badf4c586 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -1,6 +1,6 @@ import { Moves } from "./enums/moves"; import { ChargeAnim, MoveChargeAnim, initMoveAnim, loadMoveAnimAssets } from "./battle-anims"; -import { BattleEndPhase, MovePhase, NewBattlePhase, PokemonHealPhase, StatChangePhase, SwitchSummonPhase } from "../phases"; +import { BattleEndPhase, MovePhase, NewBattlePhase, PartyEffectPhase, PartyStatusCurePhase, PokemonHealPhase, StatChangePhase, SwitchSummonPhase } from "../phases"; import { BattleStat, getBattleStatName } from "./battle-stat"; import { EncoreTag } from "./battler-tags"; import { BattlerTagType } from "./enums/battler-tag-type"; @@ -52,7 +52,8 @@ export enum MoveTarget { ALL, USER_SIDE, ENEMY_SIDE, - BOTH_SIDES + BOTH_SIDES, + PARTY } export enum MoveFlags { @@ -788,6 +789,29 @@ export class HealAttr extends MoveEffectAttr { } } +export class PartyStatusCureAttr extends MoveEffectAttr { + private message: string; + private abilityCondition: Abilities; + + constructor(message: string, abilityCondition: Abilities) { + super(); + + this.message = message; + this.abilityCondition = abilityCondition; + } + + apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + if (!super.apply(user, target, move, args)) + return false; + + this.addPartyCurePhase(user); + } + + addPartyCurePhase(user: Pokemon) { + user.scene.unshiftPhase(new PartyStatusCurePhase(user.scene, user, this.message, this.abilityCondition)); + } +} + export class SacrificialFullRestoreAttr extends SacrificialAttr { constructor() { super(); @@ -3874,6 +3898,7 @@ export function getMoveTargets(user: Pokemon, move: Moves): MoveTargetSet { switch (moveTarget) { case MoveTarget.USER: + case MoveTarget.PARTY: set = [ user]; break; case MoveTarget.NEAR_OTHER: @@ -4498,9 +4523,9 @@ export function initMoves() { .condition((user, target, move) => user.status?.effect === StatusEffect.SLEEP) .ignoresVirtual(), new StatusMove(Moves.HEAL_BELL, Type.NORMAL, -1, 5, -1, 0, 2) + .attr(PartyStatusCureAttr, "A bell chimed!", Abilities.SOUNDPROOF) .soundBased() - .target(MoveTarget.USER_AND_ALLIES) - .unimplemented(), + .target(MoveTarget.PARTY), new AttackMove(Moves.RETURN, Type.NORMAL, MoveCategory.PHYSICAL, -1, 100, 20, -1, 0, 2) .attr(FriendshipPowerAttr), new AttackMove(Moves.PRESENT, Type.NORMAL, MoveCategory.PHYSICAL, -1, 90, 15, -1, 0, 2) @@ -4770,8 +4795,8 @@ export function initMoves() { .attr(MovePowerMultiplierAttr, (user, target, move) => [WeatherType.SUNNY, WeatherType.RAIN, WeatherType.SANDSTORM, WeatherType.HAIL, WeatherType.SNOW, WeatherType.FOG, WeatherType.HEAVY_RAIN, WeatherType.HARSH_SUN].includes(user.scene.arena.weather?.weatherType) && !user.scene.arena.weather?.isEffectSuppressed(user.scene) ? 2 : 1) .ballBombMove(), new StatusMove(Moves.AROMATHERAPY, Type.GRASS, -1, 5, -1, 0, 3) - .target(MoveTarget.USER_AND_ALLIES) - .unimplemented(), + .attr(PartyStatusCureAttr, "A soothing aroma wafted through the area!", Abilities.SAP_SIPPER) + .target(MoveTarget.PARTY), new StatusMove(Moves.FAKE_TEARS, Type.DARK, 100, 20, -1, 0, 3) .attr(StatChangeAttr, BattleStat.SPDEF, -2), new AttackMove(Moves.AIR_CUTTER, Type.FLYING, MoveCategory.SPECIAL, 60, 95, 25, -1, 0, 3) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index e4b56f8b9e8..acd86d8728d 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -1900,8 +1900,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return true; } - resetStatus(): void { + resetStatus(revive: boolean = true): void { const lastStatus = this.status?.effect; + if (!revive && lastStatus === StatusEffect.FAINT) { + return; + } this.status = undefined; if (lastStatus === StatusEffect.SLEEP) { this.setFrameRate(12); diff --git a/src/phases.ts b/src/phases.ts index 9ddea32da58..546325835a4 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -57,6 +57,7 @@ import { fetchDailyRunSeed, getDailyRunStarters } from "./data/daily-run"; import { GameModes, gameModes } from "./game-mode"; import { getPokemonSpecies, speciesStarters } from "./data/pokemon-species"; import i18next from './plugins/i18n'; +import { Abilities } from "./data/enums/abilities"; export class LoginPhase extends Phase { private showText: boolean; @@ -4464,6 +4465,38 @@ export class AddEnemyBuffModifierPhase extends Phase { } } +export class PartyStatusCurePhase extends BattlePhase { + private user: Pokemon; + private message: string; + private abilityCondition: Abilities; + + constructor(scene: BattleScene, user: Pokemon, message: string, abilityCondition: Abilities) { + super(scene); + + this.user = user; + this.message = message; + this.abilityCondition = abilityCondition; + } + + start() { + super.start(); + for (let pokemon of this.scene.getParty()) { + if (!pokemon.isOnField() || pokemon === this.user) { + pokemon.resetStatus(false); + pokemon.updateInfo(true); + } else { + if (pokemon.getAbility().id !== this.abilityCondition) { + pokemon.resetStatus(); + pokemon.updateInfo(true); + } + } + } + if (this.message) + this.scene.queueMessage(this.message); + this.end(); + } +} + export class PartyHealPhase extends BattlePhase { private resumeBgm: boolean;