Implement Heal Bell + Aromatherapy (#238)

* adds frame for StatusCureAttr

* heal bell and aromatherapy functioning as intended

* refactor attr to solely handle party cure, party interaction unique enough to justify

* adds header to PartyStatusCureAttr

* code comment

* comment formatting improvement

* checks for passives as well

* code comment

* shows ability bar if immune
pull/675/merge
alpaca 2024-05-09 15:15:56 -04:00 committed by GitHub
parent d5681a6e03
commit 1d7d8b1ac7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 78 additions and 6 deletions

View File

@ -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";
@ -50,7 +50,8 @@ export enum MoveTarget {
ALL,
USER_SIDE,
ENEMY_SIDE,
BOTH_SIDES
BOTH_SIDES,
PARTY
}
export enum MoveFlags {
@ -832,6 +833,34 @@ export class HealAttr extends MoveEffectAttr {
}
}
/**
* Cures the user's party of non-volatile status conditions, ie. Heal Bell, Aromatherapy
* @param {string} message Message to display after using move
* @param {Abilities} abilityCondition Skips mons with this ability, ie. Soundproof
*/
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();
@ -4003,6 +4032,7 @@ export function getMoveTargets(user: Pokemon, move: Moves): MoveTargetSet {
switch (moveTarget) {
case MoveTarget.USER:
case MoveTarget.PARTY:
set = [ user];
break;
case MoveTarget.NEAR_OTHER:
@ -4628,9 +4658,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)
@ -4901,8 +4931,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)

View File

@ -4544,6 +4544,48 @@ export class AddEnemyBuffModifierPhase extends Phase {
}
}
/**
* Cures the party of all non-volatile status conditions, shows a message
* @param {BattleScene} scene The current scene
* @param {Pokemon} user The user of the move that cures the party
* @param {string} message The message that should be displayed
* @param {Abilities} abilityCondition Pokemon with this ability will not be affected ie. Soundproof
*/
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.hasAbility(this.abilityCondition)) {
pokemon.resetStatus();
pokemon.updateInfo(true);
} else {
// Manually show ability bar, since we're not hooked into the targeting system
pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.id, pokemon.getPassiveAbility()?.id === this.abilityCondition));
}
}
}
if (this.message)
this.scene.queueMessage(this.message);
this.end();
}
}
export class PartyHealPhase extends BattlePhase {
private resumeBgm: boolean;