Rename Moves to MoveId

This commit is contained in:
NightKev 2025-06-04 13:44:41 -07:00
parent b1a0a8bc69
commit 8cdf336bd8
391 changed files with 25163 additions and 25122 deletions

View File

@ -132,7 +132,7 @@ import { BattleStyle } from "#enums/battle-style";
import { Biome } from "#enums/biome"; import { Biome } from "#enums/biome";
import type { ExpNotification } from "#enums/exp-notification"; import type { ExpNotification } from "#enums/exp-notification";
import { MoneyFormat } from "#enums/money-format"; import { MoneyFormat } from "#enums/money-format";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { PlayerGender } from "#enums/player-gender"; import { PlayerGender } from "#enums/player-gender";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { UiTheme } from "#enums/ui-theme"; import { UiTheme } from "#enums/ui-theme";
@ -707,14 +707,14 @@ export default class BattleScene extends SceneBase {
ui.setup(); ui.setup();
const defaultMoves = [Moves.TACKLE, Moves.TAIL_WHIP, Moves.FOCUS_ENERGY, Moves.STRUGGLE]; const defaultMoves = [MoveId.TACKLE, MoveId.TAIL_WHIP, MoveId.FOCUS_ENERGY, MoveId.STRUGGLE];
Promise.all([ Promise.all([
Promise.all(loadPokemonAssets), Promise.all(loadPokemonAssets),
initCommonAnims().then(() => loadCommonAnimAssets(true)), initCommonAnims().then(() => loadCommonAnimAssets(true)),
Promise.all([Moves.TACKLE, Moves.TAIL_WHIP, Moves.FOCUS_ENERGY, Moves.STRUGGLE].map(m => initMoveAnim(m))).then( Promise.all(
() => loadMoveAnimAssets(defaultMoves, true), [MoveId.TACKLE, MoveId.TAIL_WHIP, MoveId.FOCUS_ENERGY, MoveId.STRUGGLE].map(m => initMoveAnim(m)),
), ).then(() => loadMoveAnimAssets(defaultMoves, true)),
this.initStarterColors(), this.initStarterColors(),
]).then(() => { ]).then(() => {
this.pushPhase(new LoginPhase()); this.pushPhase(new LoginPhase());

View File

@ -19,7 +19,7 @@ import type { EnemyPokemon, PlayerPokemon, TurnMove } from "#app/field/pokemon";
import type Pokemon from "#app/field/pokemon"; import type Pokemon from "#app/field/pokemon";
import { ArenaTagType } from "#enums/arena-tag-type"; import { ArenaTagType } from "#enums/arena-tag-type";
import { BattleSpec } from "#enums/battle-spec"; import { BattleSpec } from "#enums/battle-spec";
import type { Moves } from "#enums/moves"; import type { MoveId } from "#enums/moves";
import { PlayerGender } from "#enums/player-gender"; import { PlayerGender } from "#enums/player-gender";
import { MusicPreference } from "#app/system/settings/settings"; import { MusicPreference } from "#app/system/settings/settings";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
@ -78,7 +78,7 @@ export default class Battle {
public battleScore = 0; public battleScore = 0;
public postBattleLoot: PokemonHeldItemModifier[] = []; public postBattleLoot: PokemonHeldItemModifier[] = [];
public escapeAttempts = 0; public escapeAttempts = 0;
public lastMove: Moves; public lastMove: MoveId;
public battleSeed: string = randomString(16, true); public battleSeed: string = randomString(16, true);
private battleSeedState: string | null = null; private battleSeedState: string | null = null;
public moneyScattered = 0; public moneyScattered = 0;

View File

@ -53,7 +53,7 @@ import { WeatherType } from "#enums/weather-type";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { ArenaTagType } from "#enums/arena-tag-type"; import { ArenaTagType } from "#enums/arena-tag-type";
import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { SwitchType } from "#enums/switch-type"; import { SwitchType } from "#enums/switch-type";
import { MoveFlags } from "#enums/MoveFlags"; import { MoveFlags } from "#enums/MoveFlags";
@ -1139,13 +1139,13 @@ export class MoveEffectChanceMultiplierAbAttr extends AbAttr {
} }
override canApply(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean { override canApply(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
const exceptMoves = [ Moves.ORDER_UP, Moves.ELECTRO_SHOT ]; const exceptMoves = [ MoveId.ORDER_UP, MoveId.ELECTRO_SHOT ];
return !((args[0] as NumberHolder).value <= 0 || exceptMoves.includes((args[1] as Move).id)); return !((args[0] as NumberHolder).value <= 0 || exceptMoves.includes((args[1] as Move).id));
} }
/** /**
* @param args [0]: {@linkcode NumberHolder} Move additional effect chance. Has to be higher than or equal to 0. * @param args [0]: {@linkcode NumberHolder} Move additional effect chance. Has to be higher than or equal to 0.
* [1]: {@linkcode Moves } Move used by the ability user. * [1]: {@linkcode MoveId } Move used by the ability user.
*/ */
override apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: BooleanHolder, args: any[]): void { override apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: BooleanHolder, args: any[]): void {
(args[0] as NumberHolder).value *= this.chanceMultiplier; (args[0] as NumberHolder).value *= this.chanceMultiplier;
@ -1249,7 +1249,7 @@ export class MoveTypeChangeAbAttr extends PreAttackAbAttr {
* *
* Can be applied if: * Can be applied if:
* - The ability's condition is met, e.g. pixilate only boosts normal moves, * - The ability's condition is met, e.g. pixilate only boosts normal moves,
* - The move is not forbidden from having its type changed by an ability, e.g. {@linkcode Moves.MULTI_ATTACK} * - The move is not forbidden from having its type changed by an ability, e.g. {@linkcode MoveId.MULTI_ATTACK}
* - The user is not terastallized and using tera blast * - The user is not terastallized and using tera blast
* - The user is not a terastallized terapagos with tera stellar using tera starstorm * - The user is not a terastallized terapagos with tera stellar using tera starstorm
* @param pokemon - The pokemon that has the move type changing ability and is using the attacking move * @param pokemon - The pokemon that has the move type changing ability and is using the attacking move
@ -1264,8 +1264,8 @@ export class MoveTypeChangeAbAttr extends PreAttackAbAttr {
return (!this.condition || this.condition(pokemon, _defender, move)) && return (!this.condition || this.condition(pokemon, _defender, move)) &&
!noAbilityTypeOverrideMoves.has(move.id) && !noAbilityTypeOverrideMoves.has(move.id) &&
(!pokemon.isTerastallized || (!pokemon.isTerastallized ||
(move.id !== Moves.TERA_BLAST && (move.id !== MoveId.TERA_BLAST &&
(move.id !== Moves.TERA_STARSTORM || pokemon.getTeraType() !== PokemonType.STELLAR || !pokemon.hasSpecies(Species.TERAPAGOS)))); (move.id !== MoveId.TERA_STARSTORM || pokemon.getTeraType() !== PokemonType.STELLAR || !pokemon.hasSpecies(Species.TERAPAGOS))));
} }
/** /**
@ -1296,7 +1296,7 @@ export class PokemonTypeChangeAbAttr extends PreAttackAbAttr {
override canApplyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon | null, move: Move, args: any[]): boolean { override canApplyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon | null, move: Move, args: any[]): boolean {
if (!pokemon.isTerastallized && if (!pokemon.isTerastallized &&
move.id !== Moves.STRUGGLE && move.id !== MoveId.STRUGGLE &&
/** /**
* Skip moves that call other moves because these moves generate a following move that will trigger this ability attribute * Skip moves that call other moves because these moves generate a following move that will trigger this ability attribute
* @see {@link https://bulbapedia.bulbagarden.net/wiki/Category:Moves_that_call_other_moves} * @see {@link https://bulbapedia.bulbagarden.net/wiki/Category:Moves_that_call_other_moves}
@ -2826,7 +2826,7 @@ export class CommanderAbAttr extends AbAttr {
// Play an animation of the source jumping into the ally Dondozo's mouth // Play an animation of the source jumping into the ally Dondozo's mouth
globalScene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.COMMANDER_APPLY); globalScene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.COMMANDER_APPLY);
// Apply boosts from this effect to the ally Dondozo // Apply boosts from this effect to the ally Dondozo
pokemon.getAlly()?.addTag(BattlerTagType.COMMANDED, 0, Moves.NONE, pokemon.id); pokemon.getAlly()?.addTag(BattlerTagType.COMMANDED, 0, MoveId.NONE, pokemon.id);
// Cancel the source Pokemon's next move (if a move is queued) // Cancel the source Pokemon's next move (if a move is queued)
globalScene.tryRemovePhase((phase) => phase instanceof MovePhase && phase.pokemon === pokemon); globalScene.tryRemovePhase((phase) => phase instanceof MovePhase && phase.pokemon === pokemon);
} }
@ -3712,7 +3712,7 @@ function getAnticipationCondition(): AbAttrCondition {
return true; return true;
} }
// edge case for hidden power, type is computed // edge case for hidden power, type is computed
if (move.getMove().id === Moves.HIDDEN_POWER) { if (move.getMove().id === MoveId.HIDDEN_POWER) {
const iv_val = Math.floor(((opponent.ivs[Stat.HP] & 1) const iv_val = Math.floor(((opponent.ivs[Stat.HP] & 1)
+ (opponent.ivs[Stat.ATK] & 1) * 2 + (opponent.ivs[Stat.ATK] & 1) * 2
+ (opponent.ivs[Stat.DEF] & 1) * 4 + (opponent.ivs[Stat.DEF] & 1) * 4
@ -3764,7 +3764,7 @@ export class ForewarnAbAttr extends PostSummonAbAttr {
movePower = 1; movePower = 1;
} else if (move?.getMove().hasAttr(OneHitKOAttr)) { } else if (move?.getMove().hasAttr(OneHitKOAttr)) {
movePower = 150; movePower = 150;
} else if (move?.getMove().id === Moves.COUNTER || move?.getMove().id === Moves.MIRROR_COAT || move?.getMove().id === Moves.METAL_BURST) { } else if (move?.getMove().id === MoveId.COUNTER || move?.getMove().id === MoveId.MIRROR_COAT || move?.getMove().id === MoveId.METAL_BURST) {
movePower = 120; movePower = 120;
} else if (move?.getMove().power === -1) { } else if (move?.getMove().power === -1) {
movePower = 80; movePower = 80;
@ -4856,7 +4856,7 @@ export class RedirectMoveAbAttr extends AbAttr {
*/ */
override canApply(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean { override canApply(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
if (!this.canRedirect(args[0] as Moves, args[2] as Pokemon)) { if (!this.canRedirect(args[0] as MoveId, args[2] as Pokemon)) {
return false; return false;
} }
const target = args[1] as NumberHolder; const target = args[1] as NumberHolder;
@ -4870,7 +4870,7 @@ export class RedirectMoveAbAttr extends AbAttr {
target.value = newTarget; target.value = newTarget;
} }
canRedirect(moveId: Moves, user: Pokemon): boolean { canRedirect(moveId: MoveId, user: Pokemon): boolean {
const move = allMoves[moveId]; const move = allMoves[moveId];
return !![ MoveTarget.NEAR_OTHER, MoveTarget.OTHER ].find(t => move.moveTarget === t); return !![ MoveTarget.NEAR_OTHER, MoveTarget.OTHER ].find(t => move.moveTarget === t);
} }
@ -4884,7 +4884,7 @@ export class RedirectTypeMoveAbAttr extends RedirectMoveAbAttr {
this.type = type; this.type = type;
} }
canRedirect(moveId: Moves, user: Pokemon): boolean { canRedirect(moveId: MoveId, user: Pokemon): boolean {
return super.canRedirect(moveId, user) && user.getMoveType(allMoves[moveId]) === this.type; return super.canRedirect(moveId, user) && user.getMoveType(allMoves[moveId]) === this.type;
} }
} }
@ -5050,7 +5050,7 @@ export class InfiltratorAbAttr extends AbAttr {
/** /**
* Attribute implementing the effects of {@link https://bulbapedia.bulbagarden.net/wiki/Magic_Bounce_(ability) | Magic Bounce}. * Attribute implementing the effects of {@link https://bulbapedia.bulbagarden.net/wiki/Magic_Bounce_(ability) | Magic Bounce}.
* Allows the source to bounce back {@linkcode MoveFlags.REFLECTABLE | Reflectable} * Allows the source to bounce back {@linkcode MoveFlags.REFLECTABLE | Reflectable}
* moves as if the user had used {@linkcode Moves.MAGIC_COAT | Magic Coat}. * moves as if the user had used {@linkcode MoveId.MAGIC_COAT | Magic Coat}.
*/ */
export class ReflectStatusMoveAbAttr extends AbAttr { } export class ReflectStatusMoveAbAttr extends AbAttr { }
@ -5731,7 +5731,7 @@ export class PostDamageForceSwitchAbAttr extends PostDamageAbAttr {
source?: Pokemon): boolean { source?: Pokemon): boolean {
const moveHistory = pokemon.getMoveHistory(); const moveHistory = pokemon.getMoveHistory();
// Will not activate when the Pokémon's HP is lowered by cutting its own HP // Will not activate when the Pokémon's HP is lowered by cutting its own HP
const fordbiddenAttackingMoves = [ Moves.BELLY_DRUM, Moves.SUBSTITUTE, Moves.CURSE, Moves.PAIN_SPLIT ]; const fordbiddenAttackingMoves = [ MoveId.BELLY_DRUM, MoveId.SUBSTITUTE, MoveId.CURSE, MoveId.PAIN_SPLIT ];
if (moveHistory.length > 0) { if (moveHistory.length > 0) {
const lastMoveUsed = moveHistory[moveHistory.length - 1]; const lastMoveUsed = moveHistory[moveHistory.length - 1];
if (fordbiddenAttackingMoves.includes(lastMoveUsed.move)) { if (fordbiddenAttackingMoves.includes(lastMoveUsed.move)) {
@ -5740,13 +5740,13 @@ export class PostDamageForceSwitchAbAttr extends PostDamageAbAttr {
} }
// Dragon Tail and Circle Throw switch out Pokémon before the Ability activates. // Dragon Tail and Circle Throw switch out Pokémon before the Ability activates.
const fordbiddenDefendingMoves = [ Moves.DRAGON_TAIL, Moves.CIRCLE_THROW ]; const fordbiddenDefendingMoves = [ MoveId.DRAGON_TAIL, MoveId.CIRCLE_THROW ];
if (source) { if (source) {
const enemyMoveHistory = source.getMoveHistory(); const enemyMoveHistory = source.getMoveHistory();
if (enemyMoveHistory.length > 0) { if (enemyMoveHistory.length > 0) {
const enemyLastMoveUsed = enemyMoveHistory[enemyMoveHistory.length - 1]; const enemyLastMoveUsed = enemyMoveHistory[enemyMoveHistory.length - 1];
// Will not activate if the Pokémon's HP falls below half while it is in the air during Sky Drop. // Will not activate if the Pokémon's HP falls below half while it is in the air during Sky Drop.
if (fordbiddenDefendingMoves.includes(enemyLastMoveUsed.move) || enemyLastMoveUsed.move === Moves.SKY_DROP && enemyLastMoveUsed.result === MoveResult.OTHER) { if (fordbiddenDefendingMoves.includes(enemyLastMoveUsed.move) || enemyLastMoveUsed.move === MoveId.SKY_DROP && enemyLastMoveUsed.result === MoveResult.OTHER) {
return false; return false;
// Will not activate if the Pokémon's HP falls below half by a move affected by Sheer Force. // Will not activate if the Pokémon's HP falls below half by a move affected by Sheer Force.
// TODO: Make this use the sheer force disable condition // TODO: Make this use the sheer force disable condition

View File

@ -25,7 +25,7 @@ import i18next from "i18next";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { ArenaTagType } from "#enums/arena-tag-type"; import { ArenaTagType } from "#enums/arena-tag-type";
import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { MoveEffectPhase } from "#app/phases/move-effect-phase"; import { MoveEffectPhase } from "#app/phases/move-effect-phase";
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase"; import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase"; import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
@ -41,7 +41,7 @@ export abstract class ArenaTag {
constructor( constructor(
public tagType: ArenaTagType, public tagType: ArenaTagType,
public turnCount: number, public turnCount: number,
public sourceMove?: Moves, public sourceMove?: MoveId,
public sourceId?: number, public sourceId?: number,
public side: ArenaTagSide = ArenaTagSide.BOTH, public side: ArenaTagSide = ArenaTagSide.BOTH,
) {} ) {}
@ -116,7 +116,7 @@ export abstract class ArenaTag {
*/ */
export class MistTag extends ArenaTag { export class MistTag extends ArenaTag {
constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { constructor(turnCount: number, sourceId: number, side: ArenaTagSide) {
super(ArenaTagType.MIST, turnCount, Moves.MIST, sourceId, side); super(ArenaTagType.MIST, turnCount, MoveId.MIST, sourceId, side);
} }
onAdd(arena: Arena, quiet = false): void { onAdd(arena: Arena, quiet = false): void {
@ -188,7 +188,7 @@ export class WeakenMoveScreenTag extends ArenaTag {
constructor( constructor(
tagType: ArenaTagType, tagType: ArenaTagType,
turnCount: number, turnCount: number,
sourceMove: Moves, sourceMove: MoveId,
sourceId: number, sourceId: number,
side: ArenaTagSide, side: ArenaTagSide,
weakenedCategories: MoveCategory[], weakenedCategories: MoveCategory[],
@ -230,11 +230,11 @@ export class WeakenMoveScreenTag extends ArenaTag {
/** /**
* Reduces the damage of physical moves. * Reduces the damage of physical moves.
* Used by {@linkcode Moves.REFLECT} * Used by {@linkcode MoveId.REFLECT}
*/ */
class ReflectTag extends WeakenMoveScreenTag { class ReflectTag extends WeakenMoveScreenTag {
constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { constructor(turnCount: number, sourceId: number, side: ArenaTagSide) {
super(ArenaTagType.REFLECT, turnCount, Moves.REFLECT, sourceId, side, [MoveCategory.PHYSICAL]); super(ArenaTagType.REFLECT, turnCount, MoveId.REFLECT, sourceId, side, [MoveCategory.PHYSICAL]);
} }
onAdd(_arena: Arena, quiet = false): void { onAdd(_arena: Arena, quiet = false): void {
@ -250,11 +250,11 @@ class ReflectTag extends WeakenMoveScreenTag {
/** /**
* Reduces the damage of special moves. * Reduces the damage of special moves.
* Used by {@linkcode Moves.LIGHT_SCREEN} * Used by {@linkcode MoveId.LIGHT_SCREEN}
*/ */
class LightScreenTag extends WeakenMoveScreenTag { class LightScreenTag extends WeakenMoveScreenTag {
constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { constructor(turnCount: number, sourceId: number, side: ArenaTagSide) {
super(ArenaTagType.LIGHT_SCREEN, turnCount, Moves.LIGHT_SCREEN, sourceId, side, [MoveCategory.SPECIAL]); super(ArenaTagType.LIGHT_SCREEN, turnCount, MoveId.LIGHT_SCREEN, sourceId, side, [MoveCategory.SPECIAL]);
} }
onAdd(_arena: Arena, quiet = false): void { onAdd(_arena: Arena, quiet = false): void {
@ -270,11 +270,11 @@ class LightScreenTag extends WeakenMoveScreenTag {
/** /**
* Reduces the damage of physical and special moves. * Reduces the damage of physical and special moves.
* Used by {@linkcode Moves.AURORA_VEIL} * Used by {@linkcode MoveId.AURORA_VEIL}
*/ */
class AuroraVeilTag extends WeakenMoveScreenTag { class AuroraVeilTag extends WeakenMoveScreenTag {
constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { constructor(turnCount: number, sourceId: number, side: ArenaTagSide) {
super(ArenaTagType.AURORA_VEIL, turnCount, Moves.AURORA_VEIL, sourceId, side, [ super(ArenaTagType.AURORA_VEIL, turnCount, MoveId.AURORA_VEIL, sourceId, side, [
MoveCategory.SPECIAL, MoveCategory.SPECIAL,
MoveCategory.PHYSICAL, MoveCategory.PHYSICAL,
]); ]);
@ -291,7 +291,7 @@ class AuroraVeilTag extends WeakenMoveScreenTag {
} }
} }
type ProtectConditionFunc = (arena: Arena, moveId: Moves) => boolean; type ProtectConditionFunc = (arena: Arena, moveId: MoveId) => boolean;
/** /**
* Class to implement conditional team protection * Class to implement conditional team protection
@ -305,7 +305,7 @@ export class ConditionalProtectTag extends ArenaTag {
constructor( constructor(
tagType: ArenaTagType, tagType: ArenaTagType,
sourceMove: Moves, sourceMove: MoveId,
sourceId: number, sourceId: number,
side: ArenaTagSide, side: ArenaTagSide,
condition: ProtectConditionFunc, condition: ProtectConditionFunc,
@ -337,7 +337,7 @@ export class ConditionalProtectTag extends ArenaTag {
* @param isProtected a {@linkcode BooleanHolder} used to flag if the move is protected against * @param isProtected a {@linkcode BooleanHolder} used to flag if the move is protected against
* @param _attacker the attacking {@linkcode Pokemon} * @param _attacker the attacking {@linkcode Pokemon}
* @param defender the defending {@linkcode Pokemon} * @param defender the defending {@linkcode Pokemon}
* @param moveId the {@linkcode Moves | identifier} for the move being used * @param moveId the {@linkcode MoveId | identifier} for the move being used
* @param ignoresProtectBypass a {@linkcode BooleanHolder} used to flag if a protection effect supercedes effects that ignore protection * @param ignoresProtectBypass a {@linkcode BooleanHolder} used to flag if a protection effect supercedes effects that ignore protection
* @returns `true` if this tag protected against the attack; `false` otherwise * @returns `true` if this tag protected against the attack; `false` otherwise
*/ */
@ -347,7 +347,7 @@ export class ConditionalProtectTag extends ArenaTag {
isProtected: BooleanHolder, isProtected: BooleanHolder,
_attacker: Pokemon, _attacker: Pokemon,
defender: Pokemon, defender: Pokemon,
moveId: Moves, moveId: MoveId,
ignoresProtectBypass: BooleanHolder, ignoresProtectBypass: BooleanHolder,
): boolean { ): boolean {
if ((this.side === ArenaTagSide.PLAYER) === defender.isPlayer() && this.protectConditionFunc(arena, moveId)) { if ((this.side === ArenaTagSide.PLAYER) === defender.isPlayer() && this.protectConditionFunc(arena, moveId)) {
@ -375,7 +375,7 @@ export class ConditionalProtectTag extends ArenaTag {
* Condition function for {@link https://bulbapedia.bulbagarden.net/wiki/Quick_Guard_(move) Quick Guard's} * Condition function for {@link https://bulbapedia.bulbagarden.net/wiki/Quick_Guard_(move) Quick Guard's}
* protection effect. * protection effect.
* @param _arena {@linkcode Arena} The arena containing the protection effect * @param _arena {@linkcode Arena} The arena containing the protection effect
* @param moveId {@linkcode Moves} The move to check against this condition * @param moveId {@linkcode MoveId} The move to check against this condition
* @returns `true` if the incoming move's priority is greater than 0. * @returns `true` if the incoming move's priority is greater than 0.
* This includes moves with modified priorities from abilities (e.g. Prankster) * This includes moves with modified priorities from abilities (e.g. Prankster)
*/ */
@ -398,7 +398,7 @@ const QuickGuardConditionFunc: ProtectConditionFunc = (_arena, moveId) => {
*/ */
class QuickGuardTag extends ConditionalProtectTag { class QuickGuardTag extends ConditionalProtectTag {
constructor(sourceId: number, side: ArenaTagSide) { constructor(sourceId: number, side: ArenaTagSide) {
super(ArenaTagType.QUICK_GUARD, Moves.QUICK_GUARD, sourceId, side, QuickGuardConditionFunc); super(ArenaTagType.QUICK_GUARD, MoveId.QUICK_GUARD, sourceId, side, QuickGuardConditionFunc);
} }
} }
@ -406,7 +406,7 @@ class QuickGuardTag extends ConditionalProtectTag {
* Condition function for {@link https://bulbapedia.bulbagarden.net/wiki/Wide_Guard_(move) Wide Guard's} * Condition function for {@link https://bulbapedia.bulbagarden.net/wiki/Wide_Guard_(move) Wide Guard's}
* protection effect. * protection effect.
* @param _arena {@linkcode Arena} The arena containing the protection effect * @param _arena {@linkcode Arena} The arena containing the protection effect
* @param moveId {@linkcode Moves} The move to check against this condition * @param moveId {@linkcode MoveId} The move to check against this condition
* @returns `true` if the incoming move is multi-targeted (even if it's only used against one Pokemon). * @returns `true` if the incoming move is multi-targeted (even if it's only used against one Pokemon).
*/ */
const WideGuardConditionFunc: ProtectConditionFunc = (_arena, moveId): boolean => { const WideGuardConditionFunc: ProtectConditionFunc = (_arena, moveId): boolean => {
@ -429,7 +429,7 @@ const WideGuardConditionFunc: ProtectConditionFunc = (_arena, moveId): boolean =
*/ */
class WideGuardTag extends ConditionalProtectTag { class WideGuardTag extends ConditionalProtectTag {
constructor(sourceId: number, side: ArenaTagSide) { constructor(sourceId: number, side: ArenaTagSide) {
super(ArenaTagType.WIDE_GUARD, Moves.WIDE_GUARD, sourceId, side, WideGuardConditionFunc); super(ArenaTagType.WIDE_GUARD, MoveId.WIDE_GUARD, sourceId, side, WideGuardConditionFunc);
} }
} }
@ -437,7 +437,7 @@ class WideGuardTag extends ConditionalProtectTag {
* Condition function for {@link https://bulbapedia.bulbagarden.net/wiki/Mat_Block_(move) Mat Block's} * Condition function for {@link https://bulbapedia.bulbagarden.net/wiki/Mat_Block_(move) Mat Block's}
* protection effect. * protection effect.
* @param _arena {@linkcode Arena} The arena containing the protection effect. * @param _arena {@linkcode Arena} The arena containing the protection effect.
* @param moveId {@linkcode Moves} The move to check against this condition. * @param moveId {@linkcode MoveId} The move to check against this condition.
* @returns `true` if the incoming move is not a Status move. * @returns `true` if the incoming move is not a Status move.
*/ */
const MatBlockConditionFunc: ProtectConditionFunc = (_arena, moveId): boolean => { const MatBlockConditionFunc: ProtectConditionFunc = (_arena, moveId): boolean => {
@ -451,7 +451,7 @@ const MatBlockConditionFunc: ProtectConditionFunc = (_arena, moveId): boolean =>
*/ */
class MatBlockTag extends ConditionalProtectTag { class MatBlockTag extends ConditionalProtectTag {
constructor(sourceId: number, side: ArenaTagSide) { constructor(sourceId: number, side: ArenaTagSide) {
super(ArenaTagType.MAT_BLOCK, Moves.MAT_BLOCK, sourceId, side, MatBlockConditionFunc); super(ArenaTagType.MAT_BLOCK, MoveId.MAT_BLOCK, sourceId, side, MatBlockConditionFunc);
} }
onAdd(_arena: Arena) { onAdd(_arena: Arena) {
@ -474,7 +474,7 @@ class MatBlockTag extends ConditionalProtectTag {
* Condition function for {@link https://bulbapedia.bulbagarden.net/wiki/Crafty_Shield_(move) Crafty Shield's} * Condition function for {@link https://bulbapedia.bulbagarden.net/wiki/Crafty_Shield_(move) Crafty Shield's}
* protection effect. * protection effect.
* @param _arena {@linkcode Arena} The arena containing the protection effect * @param _arena {@linkcode Arena} The arena containing the protection effect
* @param moveId {@linkcode Moves} The move to check against this condition * @param moveId {@linkcode MoveId} The move to check against this condition
* @returns `true` if the incoming move is a Status move, is not a hazard, and does not target all * @returns `true` if the incoming move is a Status move, is not a hazard, and does not target all
* Pokemon or sides of the field. * Pokemon or sides of the field.
*/ */
@ -495,7 +495,7 @@ const CraftyShieldConditionFunc: ProtectConditionFunc = (_arena, moveId) => {
*/ */
class CraftyShieldTag extends ConditionalProtectTag { class CraftyShieldTag extends ConditionalProtectTag {
constructor(sourceId: number, side: ArenaTagSide) { constructor(sourceId: number, side: ArenaTagSide) {
super(ArenaTagType.CRAFTY_SHIELD, Moves.CRAFTY_SHIELD, sourceId, side, CraftyShieldConditionFunc, true); super(ArenaTagType.CRAFTY_SHIELD, MoveId.CRAFTY_SHIELD, sourceId, side, CraftyShieldConditionFunc, true);
} }
} }
@ -507,11 +507,11 @@ export class NoCritTag extends ArenaTag {
/** /**
* Constructor method for the NoCritTag class * Constructor method for the NoCritTag class
* @param turnCount `number` the number of turns this effect lasts * @param turnCount `number` the number of turns this effect lasts
* @param sourceMove {@linkcode Moves} the move that created this effect * @param sourceMove {@linkcode MoveId} the move that created this effect
* @param sourceId `number` the ID of the {@linkcode Pokemon} that created this effect * @param sourceId `number` the ID of the {@linkcode Pokemon} that created this effect
* @param side {@linkcode ArenaTagSide} the side to which this effect belongs * @param side {@linkcode ArenaTagSide} the side to which this effect belongs
*/ */
constructor(turnCount: number, sourceMove: Moves, sourceId: number, side: ArenaTagSide) { constructor(turnCount: number, sourceMove: MoveId, sourceId: number, side: ArenaTagSide) {
super(ArenaTagType.NO_CRIT, turnCount, sourceMove, sourceId, side); super(ArenaTagType.NO_CRIT, turnCount, sourceMove, sourceId, side);
} }
@ -546,7 +546,7 @@ class WishTag extends ArenaTag {
private healHp: number; private healHp: number;
constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { constructor(turnCount: number, sourceId: number, side: ArenaTagSide) {
super(ArenaTagType.WISH, turnCount, Moves.WISH, sourceId, side); super(ArenaTagType.WISH, turnCount, MoveId.WISH, sourceId, side);
} }
onAdd(_arena: Arena): void { onAdd(_arena: Arena): void {
@ -588,7 +588,7 @@ export class WeakenMoveTypeTag extends ArenaTag {
* @param sourceMove - The move that created the tag. * @param sourceMove - The move that created the tag.
* @param sourceId - The ID of the source of the tag. * @param sourceId - The ID of the source of the tag.
*/ */
constructor(tagType: ArenaTagType, turnCount: number, type: PokemonType, sourceMove: Moves, sourceId: number) { constructor(tagType: ArenaTagType, turnCount: number, type: PokemonType, sourceMove: MoveId, sourceId: number) {
super(tagType, turnCount, sourceMove, sourceId); super(tagType, turnCount, sourceMove, sourceId);
this.weakenedType = type; this.weakenedType = type;
@ -617,7 +617,7 @@ export class WeakenMoveTypeTag extends ArenaTag {
*/ */
class MudSportTag extends WeakenMoveTypeTag { class MudSportTag extends WeakenMoveTypeTag {
constructor(turnCount: number, sourceId: number) { constructor(turnCount: number, sourceId: number) {
super(ArenaTagType.MUD_SPORT, turnCount, PokemonType.ELECTRIC, Moves.MUD_SPORT, sourceId); super(ArenaTagType.MUD_SPORT, turnCount, PokemonType.ELECTRIC, MoveId.MUD_SPORT, sourceId);
} }
onAdd(_arena: Arena): void { onAdd(_arena: Arena): void {
@ -635,7 +635,7 @@ class MudSportTag extends WeakenMoveTypeTag {
*/ */
class WaterSportTag extends WeakenMoveTypeTag { class WaterSportTag extends WeakenMoveTypeTag {
constructor(turnCount: number, sourceId: number) { constructor(turnCount: number, sourceId: number) {
super(ArenaTagType.WATER_SPORT, turnCount, PokemonType.FIRE, Moves.WATER_SPORT, sourceId); super(ArenaTagType.WATER_SPORT, turnCount, PokemonType.FIRE, MoveId.WATER_SPORT, sourceId);
} }
onAdd(_arena: Arena): void { onAdd(_arena: Arena): void {
@ -653,7 +653,7 @@ class WaterSportTag extends WeakenMoveTypeTag {
* Converts Normal-type moves to Electric type for the rest of the turn. * Converts Normal-type moves to Electric type for the rest of the turn.
*/ */
export class IonDelugeTag extends ArenaTag { export class IonDelugeTag extends ArenaTag {
constructor(sourceMove?: Moves) { constructor(sourceMove?: MoveId) {
super(ArenaTagType.ION_DELUGE, 1, sourceMove); super(ArenaTagType.ION_DELUGE, 1, sourceMove);
} }
@ -696,7 +696,7 @@ export class ArenaTrapTag extends ArenaTag {
* @param side - The side (player or enemy) the tag affects. * @param side - The side (player or enemy) the tag affects.
* @param maxLayers - The maximum amount of layers this tag can have. * @param maxLayers - The maximum amount of layers this tag can have.
*/ */
constructor(tagType: ArenaTagType, sourceMove: Moves, sourceId: number, side: ArenaTagSide, maxLayers: number) { constructor(tagType: ArenaTagType, sourceMove: MoveId, sourceId: number, side: ArenaTagSide, maxLayers: number) {
super(tagType, 0, sourceMove, sourceId, side); super(tagType, 0, sourceMove, sourceId, side);
this.layers = 1; this.layers = 1;
@ -750,7 +750,7 @@ export class ArenaTrapTag extends ArenaTag {
*/ */
class SpikesTag extends ArenaTrapTag { class SpikesTag extends ArenaTrapTag {
constructor(sourceId: number, side: ArenaTagSide) { constructor(sourceId: number, side: ArenaTagSide) {
super(ArenaTagType.SPIKES, Moves.SPIKES, sourceId, side, 3); super(ArenaTagType.SPIKES, MoveId.SPIKES, sourceId, side, 3);
} }
onAdd(arena: Arena, quiet = false): void { onAdd(arena: Arena, quiet = false): void {
@ -802,7 +802,7 @@ class ToxicSpikesTag extends ArenaTrapTag {
private neutralized: boolean; private neutralized: boolean;
constructor(sourceId: number, side: ArenaTagSide) { constructor(sourceId: number, side: ArenaTagSide) {
super(ArenaTagType.TOXIC_SPIKES, Moves.TOXIC_SPIKES, sourceId, side, 2); super(ArenaTagType.TOXIC_SPIKES, MoveId.TOXIC_SPIKES, sourceId, side, 2);
this.neutralized = false; this.neutralized = false;
} }
@ -867,7 +867,7 @@ class ToxicSpikesTag extends ArenaTrapTag {
} }
/** /**
* Arena Tag class for delayed attacks, such as {@linkcode Moves.FUTURE_SIGHT} or {@linkcode Moves.DOOM_DESIRE}. * Arena Tag class for delayed attacks, such as {@linkcode MoveId.FUTURE_SIGHT} or {@linkcode MoveId.DOOM_DESIRE}.
* Delays the attack's effect by a set amount of turns, usually 3 (including the turn the move is used), * Delays the attack's effect by a set amount of turns, usually 3 (including the turn the move is used),
* and deals damage after the turn count is reached. * and deals damage after the turn count is reached.
*/ */
@ -876,7 +876,7 @@ export class DelayedAttackTag extends ArenaTag {
constructor( constructor(
tagType: ArenaTagType, tagType: ArenaTagType,
sourceMove: Moves | undefined, sourceMove: MoveId | undefined,
sourceId: number, sourceId: number,
targetIndex: BattlerIndex, targetIndex: BattlerIndex,
side: ArenaTagSide = ArenaTagSide.BOTH, side: ArenaTagSide = ArenaTagSide.BOTH,
@ -909,7 +909,7 @@ export class DelayedAttackTag extends ArenaTag {
*/ */
class StealthRockTag extends ArenaTrapTag { class StealthRockTag extends ArenaTrapTag {
constructor(sourceId: number, side: ArenaTagSide) { constructor(sourceId: number, side: ArenaTagSide) {
super(ArenaTagType.STEALTH_ROCK, Moves.STEALTH_ROCK, sourceId, side, 1); super(ArenaTagType.STEALTH_ROCK, MoveId.STEALTH_ROCK, sourceId, side, 1);
} }
onAdd(arena: Arena, quiet = false): void { onAdd(arena: Arena, quiet = false): void {
@ -994,7 +994,7 @@ class StealthRockTag extends ArenaTrapTag {
*/ */
class StickyWebTag extends ArenaTrapTag { class StickyWebTag extends ArenaTrapTag {
constructor(sourceId: number, side: ArenaTagSide) { constructor(sourceId: number, side: ArenaTagSide) {
super(ArenaTagType.STICKY_WEB, Moves.STICKY_WEB, sourceId, side, 1); super(ArenaTagType.STICKY_WEB, MoveId.STICKY_WEB, sourceId, side, 1);
} }
onAdd(arena: Arena, quiet = false): void { onAdd(arena: Arena, quiet = false): void {
@ -1055,7 +1055,7 @@ class StickyWebTag extends ArenaTrapTag {
*/ */
export class TrickRoomTag extends ArenaTag { export class TrickRoomTag extends ArenaTag {
constructor(turnCount: number, sourceId: number) { constructor(turnCount: number, sourceId: number) {
super(ArenaTagType.TRICK_ROOM, turnCount, Moves.TRICK_ROOM, sourceId); super(ArenaTagType.TRICK_ROOM, turnCount, MoveId.TRICK_ROOM, sourceId);
} }
/** /**
@ -1094,7 +1094,7 @@ export class TrickRoomTag extends ArenaTag {
*/ */
export class GravityTag extends ArenaTag { export class GravityTag extends ArenaTag {
constructor(turnCount: number) { constructor(turnCount: number) {
super(ArenaTagType.GRAVITY, turnCount, Moves.GRAVITY); super(ArenaTagType.GRAVITY, turnCount, MoveId.GRAVITY);
} }
onAdd(_arena: Arena): void { onAdd(_arena: Arena): void {
@ -1122,7 +1122,7 @@ export class GravityTag extends ArenaTag {
*/ */
class TailwindTag extends ArenaTag { class TailwindTag extends ArenaTag {
constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { constructor(turnCount: number, sourceId: number, side: ArenaTagSide) {
super(ArenaTagType.TAILWIND, turnCount, Moves.TAILWIND, sourceId, side); super(ArenaTagType.TAILWIND, turnCount, MoveId.TAILWIND, sourceId, side);
} }
onAdd(_arena: Arena, quiet = false): void { onAdd(_arena: Arena, quiet = false): void {
@ -1171,11 +1171,11 @@ class TailwindTag extends ArenaTag {
/** /**
* Arena Tag class for {@link https://bulbapedia.bulbagarden.net/wiki/Happy_Hour_(move) Happy Hour}. * Arena Tag class for {@link https://bulbapedia.bulbagarden.net/wiki/Happy_Hour_(move) Happy Hour}.
* Doubles the prize money from trainers and money moves like {@linkcode Moves.PAY_DAY} and {@linkcode Moves.MAKE_IT_RAIN}. * Doubles the prize money from trainers and money moves like {@linkcode MoveId.PAY_DAY} and {@linkcode MoveId.MAKE_IT_RAIN}.
*/ */
class HappyHourTag extends ArenaTag { class HappyHourTag extends ArenaTag {
constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { constructor(turnCount: number, sourceId: number, side: ArenaTagSide) {
super(ArenaTagType.HAPPY_HOUR, turnCount, Moves.HAPPY_HOUR, sourceId, side); super(ArenaTagType.HAPPY_HOUR, turnCount, MoveId.HAPPY_HOUR, sourceId, side);
} }
onAdd(_arena: Arena): void { onAdd(_arena: Arena): void {
@ -1189,7 +1189,7 @@ class HappyHourTag extends ArenaTag {
class SafeguardTag extends ArenaTag { class SafeguardTag extends ArenaTag {
constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { constructor(turnCount: number, sourceId: number, side: ArenaTagSide) {
super(ArenaTagType.SAFEGUARD, turnCount, Moves.SAFEGUARD, sourceId, side); super(ArenaTagType.SAFEGUARD, turnCount, MoveId.SAFEGUARD, sourceId, side);
} }
onAdd(_arena: Arena): void { onAdd(_arena: Arena): void {
@ -1221,7 +1221,7 @@ class NoneTag extends ArenaTag {
*/ */
class ImprisonTag extends ArenaTrapTag { class ImprisonTag extends ArenaTrapTag {
constructor(sourceId: number, side: ArenaTagSide) { constructor(sourceId: number, side: ArenaTagSide) {
super(ArenaTagType.IMPRISON, Moves.IMPRISON, sourceId, side, 1); super(ArenaTagType.IMPRISON, MoveId.IMPRISON, sourceId, side, 1);
} }
/** /**
@ -1234,7 +1234,7 @@ class ImprisonTag extends ArenaTrapTag {
const party = this.getAffectedPokemon(); const party = this.getAffectedPokemon();
party?.forEach((p: Pokemon) => { party?.forEach((p: Pokemon) => {
if (p.isAllowedInBattle()) { if (p.isAllowedInBattle()) {
p.addTag(BattlerTagType.IMPRISON, 1, Moves.IMPRISON, this.sourceId); p.addTag(BattlerTagType.IMPRISON, 1, MoveId.IMPRISON, this.sourceId);
} }
}); });
globalScene.queueMessage( globalScene.queueMessage(
@ -1263,7 +1263,7 @@ class ImprisonTag extends ArenaTrapTag {
override activateTrap(pokemon: Pokemon): boolean { override activateTrap(pokemon: Pokemon): boolean {
const source = this.getSourcePokemon(); const source = this.getSourcePokemon();
if (source?.isActive(true) && pokemon.isAllowedInBattle()) { if (source?.isActive(true) && pokemon.isAllowedInBattle()) {
pokemon.addTag(BattlerTagType.IMPRISON, 1, Moves.IMPRISON, this.sourceId); pokemon.addTag(BattlerTagType.IMPRISON, 1, MoveId.IMPRISON, this.sourceId);
} }
return true; return true;
} }
@ -1289,7 +1289,7 @@ class ImprisonTag extends ArenaTrapTag {
*/ */
class FireGrassPledgeTag extends ArenaTag { class FireGrassPledgeTag extends ArenaTag {
constructor(sourceId: number, side: ArenaTagSide) { constructor(sourceId: number, side: ArenaTagSide) {
super(ArenaTagType.FIRE_GRASS_PLEDGE, 4, Moves.FIRE_PLEDGE, sourceId, side); super(ArenaTagType.FIRE_GRASS_PLEDGE, 4, MoveId.FIRE_PLEDGE, sourceId, side);
} }
override onAdd(_arena: Arena): void { override onAdd(_arena: Arena): void {
@ -1334,7 +1334,7 @@ class FireGrassPledgeTag extends ArenaTag {
*/ */
class WaterFirePledgeTag extends ArenaTag { class WaterFirePledgeTag extends ArenaTag {
constructor(sourceId: number, side: ArenaTagSide) { constructor(sourceId: number, side: ArenaTagSide) {
super(ArenaTagType.WATER_FIRE_PLEDGE, 4, Moves.WATER_PLEDGE, sourceId, side); super(ArenaTagType.WATER_FIRE_PLEDGE, 4, MoveId.WATER_PLEDGE, sourceId, side);
} }
override onAdd(_arena: Arena): void { override onAdd(_arena: Arena): void {
@ -1368,7 +1368,7 @@ class WaterFirePledgeTag extends ArenaTag {
*/ */
class GrassWaterPledgeTag extends ArenaTag { class GrassWaterPledgeTag extends ArenaTag {
constructor(sourceId: number, side: ArenaTagSide) { constructor(sourceId: number, side: ArenaTagSide) {
super(ArenaTagType.GRASS_WATER_PLEDGE, 4, Moves.GRASS_PLEDGE, sourceId, side); super(ArenaTagType.GRASS_WATER_PLEDGE, 4, MoveId.GRASS_PLEDGE, sourceId, side);
} }
override onAdd(_arena: Arena): void { override onAdd(_arena: Arena): void {
@ -1390,7 +1390,7 @@ class GrassWaterPledgeTag extends ArenaTag {
*/ */
export class FairyLockTag extends ArenaTag { export class FairyLockTag extends ArenaTag {
constructor(turnCount: number, sourceId: number) { constructor(turnCount: number, sourceId: number) {
super(ArenaTagType.FAIRY_LOCK, turnCount, Moves.FAIRY_LOCK, sourceId); super(ArenaTagType.FAIRY_LOCK, turnCount, MoveId.FAIRY_LOCK, sourceId);
} }
onAdd(_arena: Arena): void { onAdd(_arena: Arena): void {
@ -1485,7 +1485,7 @@ export class SuppressAbilitiesTag extends ArenaTag {
export function getArenaTag( export function getArenaTag(
tagType: ArenaTagType, tagType: ArenaTagType,
turnCount: number, turnCount: number,
sourceMove: Moves | undefined, sourceMove: MoveId | undefined,
sourceId: number, sourceId: number,
targetIndex?: BattlerIndex, targetIndex?: BattlerIndex,
side: ArenaTagSide = ArenaTagSide.BOTH, side: ArenaTagSide = ArenaTagSide.BOTH,

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ import { randSeedInt } from "#app/utils/common";
import { WeatherType } from "#enums/weather-type"; import { WeatherType } from "#enums/weather-type";
import { Nature } from "#enums/nature"; import { Nature } from "#enums/nature";
import { Biome } from "#enums/biome"; import { Biome } from "#enums/biome";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { SpeciesFormKey } from "#enums/species-form-key"; import { SpeciesFormKey } from "#enums/species-form-key";
import { TimeOfDay } from "#enums/time-of-day"; import { TimeOfDay } from "#enums/time-of-day";
@ -181,11 +181,11 @@ class TimeOfDayEvolutionCondition extends SpeciesEvolutionCondition {
} }
class MoveEvolutionCondition extends SpeciesEvolutionCondition { class MoveEvolutionCondition extends SpeciesEvolutionCondition {
public move: Moves; public move: MoveId;
constructor(move: Moves) { constructor(move: MoveId) {
super(p => p.moveset.filter(m => m.moveId === move).length > 0); super(p => p.moveset.filter(m => m.moveId === move).length > 0);
this.move = move; this.move = move;
const moveKey = Moves[this.move].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join(""); const moveKey = MoveId[this.move].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join("");
this.description = i18next.t("pokemonEvolutions:move", { move: i18next.t(`move:${moveKey}.name`) }); this.description = i18next.t("pokemonEvolutions:move", { move: i18next.t(`move:${moveKey}.name`) });
} }
} }
@ -283,12 +283,12 @@ class TreasureEvolutionCondition extends SpeciesEvolutionCondition {
} }
class TyrogueEvolutionCondition extends SpeciesEvolutionCondition { class TyrogueEvolutionCondition extends SpeciesEvolutionCondition {
public move: Moves; public move: MoveId;
constructor(move: Moves) { constructor(move: MoveId) {
super(p => super(p =>
p.getMoveset(true).find(m => m && [ Moves.LOW_SWEEP, Moves.MACH_PUNCH, Moves.RAPID_SPIN ].includes(m.moveId))?.moveId === move); p.getMoveset(true).find(m => m && [ MoveId.LOW_SWEEP, MoveId.MACH_PUNCH, MoveId.RAPID_SPIN ].includes(m.moveId))?.moveId === move);
this.move = move; this.move = move;
const moveKey = Moves[this.move].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join(""); const moveKey = MoveId[this.move].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join("");
this.description = i18next.t("pokemonEvolutions:move", { move: i18next.t(`move:${moveKey}.name`) }); this.description = i18next.t("pokemonEvolutions:move", { move: i18next.t(`move:${moveKey}.name`) });
} }
} }
@ -303,9 +303,9 @@ class NatureEvolutionCondition extends SpeciesEvolutionCondition {
} }
class MoveTimeOfDayEvolutionCondition extends SpeciesEvolutionCondition { class MoveTimeOfDayEvolutionCondition extends SpeciesEvolutionCondition {
public move: Moves; public move: MoveId;
public timesOfDay: TimeOfDay[]; public timesOfDay: TimeOfDay[];
constructor(move: Moves, tod: "day" | "night") { constructor(move: MoveId, tod: "day" | "night") {
if (tod === "day") { if (tod === "day") {
super(p => p.moveset.filter(m => m.moveId === move).length > 0 && (globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)); super(p => p.moveset.filter(m => m.moveId === move).length > 0 && (globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY));
this.move = move; this.move = move;
@ -318,7 +318,7 @@ class MoveTimeOfDayEvolutionCondition extends SpeciesEvolutionCondition {
super(() => false); super(() => false);
this.timesOfDay = []; this.timesOfDay = [];
} }
const moveKey = Moves[this.move].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join(""); const moveKey = MoveId[this.move].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join("");
this.description = i18next.t("pokemonEvolutions:moveTimeOfDay", { move: i18next.t(`move:${moveKey}.name`), tod: i18next.t(`pokemonEvolutions:${tod}`) }); this.description = i18next.t("pokemonEvolutions:moveTimeOfDay", { move: i18next.t(`move:${moveKey}.name`), tod: i18next.t(`pokemonEvolutions:${tod}`) });
} }
} }
@ -336,12 +336,12 @@ class DunsparceEvolutionCondition extends SpeciesEvolutionCondition {
constructor() { constructor() {
super(p => { super(p => {
let ret = false; let ret = false;
if (p.moveset.filter(m => m.moveId === Moves.HYPER_DRILL).length > 0) { if (p.moveset.filter(m => m.moveId === MoveId.HYPER_DRILL).length > 0) {
globalScene.executeWithSeedOffset(() => ret = !randSeedInt(4), p.id); globalScene.executeWithSeedOffset(() => ret = !randSeedInt(4), p.id);
} }
return ret; return ret;
}); });
const moveKey = Moves[Moves.HYPER_DRILL].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join(""); const moveKey = MoveId[MoveId.HYPER_DRILL].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join("");
this.description = i18next.t("pokemonEvolutions:move", { move: i18next.t(`move:${moveKey}.name`) }); this.description = i18next.t("pokemonEvolutions:move", { move: i18next.t(`move:${moveKey}.name`) });
} }
} }
@ -499,9 +499,9 @@ export const pokemonEvolutions: PokemonEvolutions = {
* If Tyrogue knows multiple of these moves, its evolution is based on * If Tyrogue knows multiple of these moves, its evolution is based on
* the first qualifying move in its moveset. * the first qualifying move in its moveset.
*/ */
new SpeciesEvolution(Species.HITMONLEE, 20, null, new TyrogueEvolutionCondition(Moves.LOW_SWEEP)), new SpeciesEvolution(Species.HITMONLEE, 20, null, new TyrogueEvolutionCondition(MoveId.LOW_SWEEP)),
new SpeciesEvolution(Species.HITMONCHAN, 20, null, new TyrogueEvolutionCondition(Moves.MACH_PUNCH)), new SpeciesEvolution(Species.HITMONCHAN, 20, null, new TyrogueEvolutionCondition(MoveId.MACH_PUNCH)),
new SpeciesEvolution(Species.HITMONTOP, 20, null, new TyrogueEvolutionCondition(Moves.RAPID_SPIN)), new SpeciesEvolution(Species.HITMONTOP, 20, null, new TyrogueEvolutionCondition(MoveId.RAPID_SPIN)),
], ],
[Species.KOFFING]: [ [Species.KOFFING]: [
new SpeciesEvolution(Species.GALAR_WEEZING, 35, null, new TimeOfDayEvolutionCondition("night")), new SpeciesEvolution(Species.GALAR_WEEZING, 35, null, new TimeOfDayEvolutionCondition("night")),
@ -1514,10 +1514,10 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.EXEGGUTOR, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.EXEGGUTOR, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
], ],
[Species.TANGELA]: [ [Species.TANGELA]: [
new SpeciesEvolution(Species.TANGROWTH, 34, null, new MoveEvolutionCondition(Moves.ANCIENT_POWER), SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.TANGROWTH, 34, null, new MoveEvolutionCondition(MoveId.ANCIENT_POWER), SpeciesWildEvolutionDelay.LONG)
], ],
[Species.LICKITUNG]: [ [Species.LICKITUNG]: [
new SpeciesEvolution(Species.LICKILICKY, 32, null, new MoveEvolutionCondition(Moves.ROLLOUT), SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.LICKILICKY, 32, null, new MoveEvolutionCondition(MoveId.ROLLOUT), SpeciesWildEvolutionDelay.LONG)
], ],
[Species.STARYU]: [ [Species.STARYU]: [
new SpeciesEvolution(Species.STARMIE, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.STARMIE, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG)
@ -1544,13 +1544,13 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.TOGEKISS, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.TOGEKISS, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
], ],
[Species.AIPOM]: [ [Species.AIPOM]: [
new SpeciesEvolution(Species.AMBIPOM, 32, null, new MoveEvolutionCondition(Moves.DOUBLE_HIT), SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.AMBIPOM, 32, null, new MoveEvolutionCondition(MoveId.DOUBLE_HIT), SpeciesWildEvolutionDelay.LONG)
], ],
[Species.SUNKERN]: [ [Species.SUNKERN]: [
new SpeciesEvolution(Species.SUNFLORA, 1, EvolutionItem.SUN_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.SUNFLORA, 1, EvolutionItem.SUN_STONE, null, SpeciesWildEvolutionDelay.LONG)
], ],
[Species.YANMA]: [ [Species.YANMA]: [
new SpeciesEvolution(Species.YANMEGA, 33, null, new MoveEvolutionCondition(Moves.ANCIENT_POWER), SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.YANMEGA, 33, null, new MoveEvolutionCondition(MoveId.ANCIENT_POWER), SpeciesWildEvolutionDelay.LONG)
], ],
[Species.MURKROW]: [ [Species.MURKROW]: [
new SpeciesEvolution(Species.HONCHKROW, 1, EvolutionItem.DUSK_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.HONCHKROW, 1, EvolutionItem.DUSK_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
@ -1559,11 +1559,11 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.MISMAGIUS, 1, EvolutionItem.DUSK_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.MISMAGIUS, 1, EvolutionItem.DUSK_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
], ],
[Species.GIRAFARIG]: [ [Species.GIRAFARIG]: [
new SpeciesEvolution(Species.FARIGIRAF, 32, null, new MoveEvolutionCondition(Moves.TWIN_BEAM), SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.FARIGIRAF, 32, null, new MoveEvolutionCondition(MoveId.TWIN_BEAM), SpeciesWildEvolutionDelay.LONG)
], ],
[Species.DUNSPARCE]: [ [Species.DUNSPARCE]: [
new SpeciesFormEvolution(Species.DUDUNSPARCE, "", "three-segment", 32, null, new DunsparceEvolutionCondition(), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.DUDUNSPARCE, "", "three-segment", 32, null, new DunsparceEvolutionCondition(), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.DUDUNSPARCE, "", "two-segment", 32, null, new MoveEvolutionCondition(Moves.HYPER_DRILL), SpeciesWildEvolutionDelay.LONG) new SpeciesFormEvolution(Species.DUDUNSPARCE, "", "two-segment", 32, null, new MoveEvolutionCondition(MoveId.HYPER_DRILL), SpeciesWildEvolutionDelay.LONG)
], ],
[Species.GLIGAR]: [ [Species.GLIGAR]: [
new SpeciesEvolution(Species.GLISCOR, 1, EvolutionItem.RAZOR_FANG, new TimeOfDayEvolutionCondition("night") /* Razor fang at night*/, SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.GLISCOR, 1, EvolutionItem.RAZOR_FANG, new TimeOfDayEvolutionCondition("night") /* Razor fang at night*/, SpeciesWildEvolutionDelay.VERY_LONG)
@ -1575,10 +1575,10 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.URSALUNA, 1, EvolutionItem.PEAT_BLOCK, null, SpeciesWildEvolutionDelay.VERY_LONG) //Ursaring does not evolve into Bloodmoon Ursaluna new SpeciesEvolution(Species.URSALUNA, 1, EvolutionItem.PEAT_BLOCK, null, SpeciesWildEvolutionDelay.VERY_LONG) //Ursaring does not evolve into Bloodmoon Ursaluna
], ],
[Species.PILOSWINE]: [ [Species.PILOSWINE]: [
new SpeciesEvolution(Species.MAMOSWINE, 1, null, new MoveEvolutionCondition(Moves.ANCIENT_POWER), SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.MAMOSWINE, 1, null, new MoveEvolutionCondition(MoveId.ANCIENT_POWER), SpeciesWildEvolutionDelay.VERY_LONG)
], ],
[Species.STANTLER]: [ [Species.STANTLER]: [
new SpeciesEvolution(Species.WYRDEER, 25, null, new MoveEvolutionCondition(Moves.PSYSHIELD_BASH), SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.WYRDEER, 25, null, new MoveEvolutionCondition(MoveId.PSYSHIELD_BASH), SpeciesWildEvolutionDelay.VERY_LONG)
], ],
[Species.LOMBRE]: [ [Species.LOMBRE]: [
new SpeciesEvolution(Species.LUDICOLO, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.LUDICOLO, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG)
@ -1596,11 +1596,11 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.ROSERADE, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.ROSERADE, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
], ],
[Species.BONSLY]: [ [Species.BONSLY]: [
new SpeciesEvolution(Species.SUDOWOODO, 1, null, new MoveEvolutionCondition(Moves.MIMIC), SpeciesWildEvolutionDelay.MEDIUM) new SpeciesEvolution(Species.SUDOWOODO, 1, null, new MoveEvolutionCondition(MoveId.MIMIC), SpeciesWildEvolutionDelay.MEDIUM)
], ],
[Species.MIME_JR]: [ [Species.MIME_JR]: [
new SpeciesEvolution(Species.GALAR_MR_MIME, 1, null, new MoveTimeOfDayEvolutionCondition(Moves.MIMIC, "night"), SpeciesWildEvolutionDelay.MEDIUM), new SpeciesEvolution(Species.GALAR_MR_MIME, 1, null, new MoveTimeOfDayEvolutionCondition(MoveId.MIMIC, "night"), SpeciesWildEvolutionDelay.MEDIUM),
new SpeciesEvolution(Species.MR_MIME, 1, null, new MoveTimeOfDayEvolutionCondition(Moves.MIMIC, "day"), SpeciesWildEvolutionDelay.MEDIUM) new SpeciesEvolution(Species.MR_MIME, 1, null, new MoveTimeOfDayEvolutionCondition(MoveId.MIMIC, "day"), SpeciesWildEvolutionDelay.MEDIUM)
], ],
[Species.PANSAGE]: [ [Species.PANSAGE]: [
new SpeciesEvolution(Species.SIMISAGE, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.SIMISAGE, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
@ -1655,10 +1655,10 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesFormEvolution(Species.LYCANROC, "", "midnight", 25, null, new TimeOfDayEvolutionCondition("night")) new SpeciesFormEvolution(Species.LYCANROC, "", "midnight", 25, null, new TimeOfDayEvolutionCondition("night"))
], ],
[Species.STEENEE]: [ [Species.STEENEE]: [
new SpeciesEvolution(Species.TSAREENA, 28, null, new MoveEvolutionCondition(Moves.STOMP), SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.TSAREENA, 28, null, new MoveEvolutionCondition(MoveId.STOMP), SpeciesWildEvolutionDelay.LONG)
], ],
[Species.POIPOLE]: [ [Species.POIPOLE]: [
new SpeciesEvolution(Species.NAGANADEL, 1, null, new MoveEvolutionCondition(Moves.DRAGON_PULSE), SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.NAGANADEL, 1, null, new MoveEvolutionCondition(MoveId.DRAGON_PULSE), SpeciesWildEvolutionDelay.LONG)
], ],
[Species.ALOLA_SANDSHREW]: [ [Species.ALOLA_SANDSHREW]: [
new SpeciesEvolution(Species.ALOLA_SANDSLASH, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.ALOLA_SANDSLASH, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG)
@ -1672,7 +1672,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.APPLETUN, 1, EvolutionItem.SWEET_APPLE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.APPLETUN, 1, EvolutionItem.SWEET_APPLE, null, SpeciesWildEvolutionDelay.LONG)
], ],
[Species.CLOBBOPUS]: [ [Species.CLOBBOPUS]: [
new SpeciesEvolution(Species.GRAPPLOCT, 35, null, new MoveEvolutionCondition(Moves.TAUNT)/*Once Taunt is implemented, change evo level to 1 and delay to LONG*/) new SpeciesEvolution(Species.GRAPPLOCT, 35, null, new MoveEvolutionCondition(MoveId.TAUNT)/*Once Taunt is implemented, change evo level to 1 and delay to LONG*/)
], ],
[Species.SINISTEA]: [ [Species.SINISTEA]: [
new SpeciesFormEvolution(Species.POLTEAGEIST, "phony", "phony", 1, EvolutionItem.CRACKED_POT, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.POLTEAGEIST, "phony", "phony", 1, EvolutionItem.CRACKED_POT, null, SpeciesWildEvolutionDelay.LONG),
@ -1724,7 +1724,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.HISUI_ELECTRODE, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.HISUI_ELECTRODE, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
], ],
[Species.HISUI_QWILFISH]: [ [Species.HISUI_QWILFISH]: [
new SpeciesEvolution(Species.OVERQWIL, 28, null, new MoveEvolutionCondition(Moves.BARB_BARRAGE), SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.OVERQWIL, 28, null, new MoveEvolutionCondition(MoveId.BARB_BARRAGE), SpeciesWildEvolutionDelay.LONG)
], ],
[Species.HISUI_SNEASEL]: [ [Species.HISUI_SNEASEL]: [
new SpeciesEvolution(Species.SNEASLER, 1, EvolutionItem.RAZOR_CLAW, new TimeOfDayEvolutionCondition("day") /* Razor claw at day*/, SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.SNEASLER, 1, EvolutionItem.RAZOR_CLAW, new TimeOfDayEvolutionCondition("day") /* Razor claw at day*/, SpeciesWildEvolutionDelay.VERY_LONG)
@ -1747,7 +1747,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesFormEvolution(Species.SINISTCHA, "artisan", "masterpiece", 1, EvolutionItem.MASTERPIECE_TEACUP, null, SpeciesWildEvolutionDelay.LONG) new SpeciesFormEvolution(Species.SINISTCHA, "artisan", "masterpiece", 1, EvolutionItem.MASTERPIECE_TEACUP, null, SpeciesWildEvolutionDelay.LONG)
], ],
[Species.DIPPLIN]: [ [Species.DIPPLIN]: [
new SpeciesEvolution(Species.HYDRAPPLE, 1, null, new MoveEvolutionCondition(Moves.DRAGON_CHEER), SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.HYDRAPPLE, 1, null, new MoveEvolutionCondition(MoveId.DRAGON_CHEER), SpeciesWildEvolutionDelay.VERY_LONG)
], ],
[Species.KADABRA]: [ [Species.KADABRA]: [
new SpeciesEvolution(Species.ALAKAZAM, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.ALAKAZAM, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
@ -1825,7 +1825,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.ALOLA_GOLEM, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.ALOLA_GOLEM, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
], ],
[Species.PRIMEAPE]: [ [Species.PRIMEAPE]: [
new SpeciesEvolution(Species.ANNIHILAPE, 35, null, new MoveEvolutionCondition(Moves.RAGE_FIST), SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.ANNIHILAPE, 35, null, new MoveEvolutionCondition(MoveId.RAGE_FIST), SpeciesWildEvolutionDelay.VERY_LONG)
], ],
[Species.GOLBAT]: [ [Species.GOLBAT]: [
new SpeciesEvolution(Species.CROBAT, 1, null, new FriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.CROBAT, 1, null, new FriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.VERY_LONG)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@ import { MoveFlags } from "#enums/MoveFlags";
import type Pokemon from "../field/pokemon"; import type Pokemon from "../field/pokemon";
import { type nil, getFrameMs, getEnumKeys, getEnumValues, animationFileName } from "../utils/common"; import { type nil, getFrameMs, getEnumKeys, getEnumValues, animationFileName } from "../utils/common";
import type { BattlerIndex } from "../battle"; import type { BattlerIndex } from "../battle";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { SubstituteTag } from "./battler-tags"; import { SubstituteTag } from "./battler-tags";
import { isNullOrUndefined } from "../utils/common"; import { isNullOrUndefined } from "../utils/common";
import Phaser from "phaser"; import Phaser from "phaser";
@ -498,7 +498,7 @@ class AnimTimedAddBgEvent extends AnimTimedBgEvent {
} }
} }
export const moveAnims = new Map<Moves, AnimConfig | [AnimConfig, AnimConfig] | null>(); export const moveAnims = new Map<MoveId, AnimConfig | [AnimConfig, AnimConfig] | null>();
export const chargeAnims = new Map<ChargeAnim, AnimConfig | [AnimConfig, AnimConfig] | null>(); export const chargeAnims = new Map<ChargeAnim, AnimConfig | [AnimConfig, AnimConfig] | null>();
export const commonAnims = new Map<CommonAnim, AnimConfig>(); export const commonAnims = new Map<CommonAnim, AnimConfig>();
export const encounterAnims = new Map<EncounterAnim, AnimConfig>(); export const encounterAnims = new Map<EncounterAnim, AnimConfig>();
@ -521,7 +521,7 @@ export function initCommonAnims(): Promise<void> {
}); });
} }
export function initMoveAnim(move: Moves): Promise<void> { export function initMoveAnim(move: MoveId): Promise<void> {
return new Promise(resolve => { return new Promise(resolve => {
if (moveAnims.has(move)) { if (moveAnims.has(move)) {
if (moveAnims.get(move) !== null) { if (moveAnims.get(move) !== null) {
@ -544,12 +544,12 @@ export function initMoveAnim(move: Moves): Promise<void> {
moveAnims.set(move, null); moveAnims.set(move, null);
const defaultMoveAnim = const defaultMoveAnim =
allMoves[move] instanceof AttackMove allMoves[move] instanceof AttackMove
? Moves.TACKLE ? MoveId.TACKLE
: allMoves[move] instanceof SelfStatusMove : allMoves[move] instanceof SelfStatusMove
? Moves.FOCUS_ENERGY ? MoveId.FOCUS_ENERGY
: Moves.TAIL_WHIP; : MoveId.TAIL_WHIP;
const fetchAnimAndResolve = (move: Moves) => { const fetchAnimAndResolve = (move: MoveId) => {
globalScene globalScene
.cachedFetch(`./battle-anims/${animationFileName(move)}.json`) .cachedFetch(`./battle-anims/${animationFileName(move)}.json`)
.then(response => { .then(response => {
@ -594,7 +594,7 @@ export function initMoveAnim(move: Moves): Promise<void> {
* @param move the move to populate an animation for * @param move the move to populate an animation for
* @param defaultMoveAnim the move to use as the default animation * @param defaultMoveAnim the move to use as the default animation
*/ */
function useDefaultAnim(move: Moves, defaultMoveAnim: Moves) { function useDefaultAnim(move: MoveId, defaultMoveAnim: MoveId) {
populateMoveAnim(move, moveAnims.get(defaultMoveAnim)); populateMoveAnim(move, moveAnims.get(defaultMoveAnim));
} }
@ -606,7 +606,7 @@ function useDefaultAnim(move: Moves, defaultMoveAnim: Moves) {
* *
* @remarks use {@linkcode useDefaultAnim} to use a default animation * @remarks use {@linkcode useDefaultAnim} to use a default animation
*/ */
function logMissingMoveAnim(move: Moves, ...optionalParams: any[]) { function logMissingMoveAnim(move: MoveId, ...optionalParams: any[]) {
const moveName = animationFileName(move); const moveName = animationFileName(move);
console.warn(`Could not load animation file for move '${moveName}'`, ...optionalParams); console.warn(`Could not load animation file for move '${moveName}'`, ...optionalParams);
} }
@ -664,7 +664,7 @@ export function initMoveChargeAnim(chargeAnim: ChargeAnim): Promise<void> {
}); });
} }
function populateMoveAnim(move: Moves, animSource: any): void { function populateMoveAnim(move: MoveId, animSource: any): void {
const moveAnim = new AnimConfig(animSource); const moveAnim = new AnimConfig(animSource);
if (moveAnims.get(move) === null) { if (moveAnims.get(move) === null) {
moveAnims.set(move, moveAnim); moveAnims.set(move, moveAnim);
@ -697,7 +697,7 @@ export async function loadEncounterAnimAssets(startLoad?: boolean): Promise<void
await loadAnimAssets(Array.from(encounterAnims.values()), startLoad); await loadAnimAssets(Array.from(encounterAnims.values()), startLoad);
} }
export function loadMoveAnimAssets(moveIds: Moves[], startLoad?: boolean): Promise<void> { export function loadMoveAnimAssets(moveIds: MoveId[], startLoad?: boolean): Promise<void> {
return new Promise(resolve => { return new Promise(resolve => {
const moveAnimations = moveIds.flatMap(m => moveAnims.get(m) as AnimConfig); const moveAnimations = moveIds.flatMap(m => moveAnims.get(m) as AnimConfig);
for (const moveId of moveIds) { for (const moveId of moveIds) {
@ -1425,9 +1425,9 @@ export class CommonBattleAnim extends BattleAnim {
} }
export class MoveAnim extends BattleAnim { export class MoveAnim extends BattleAnim {
public move: Moves; public move: MoveId;
constructor(move: Moves, user: Pokemon, target: BattlerIndex, playOnEmptyField = false) { constructor(move: MoveId, user: Pokemon, target: BattlerIndex, playOnEmptyField = false) {
// Set target to the user pokemon if no target is found to avoid crashes // Set target to the user pokemon if no target is found to avoid crashes
super(user, globalScene.getField()[target] ?? user, playOnEmptyField); super(user, globalScene.getField()[target] ?? user, playOnEmptyField);
@ -1456,7 +1456,7 @@ export class MoveAnim extends BattleAnim {
export class MoveChargeAnim extends MoveAnim { export class MoveChargeAnim extends MoveAnim {
private chargeAnim: ChargeAnim; private chargeAnim: ChargeAnim;
constructor(chargeAnim: ChargeAnim, move: Moves, user: Pokemon) { constructor(chargeAnim: ChargeAnim, move: MoveId, user: Pokemon) {
super(move, user, 0); super(move, user, 0);
this.chargeAnim = chargeAnim; this.chargeAnim = chargeAnim;
@ -1502,8 +1502,8 @@ export async function populateAnims() {
const chargeAnimIds = getEnumValues(ChargeAnim) as ChargeAnim[]; const chargeAnimIds = getEnumValues(ChargeAnim) as ChargeAnim[];
const commonNamePattern = /name: (?:Common:)?(Opp )?(.*)/; const commonNamePattern = /name: (?:Common:)?(Opp )?(.*)/;
const moveNameToId = {}; const moveNameToId = {};
for (const move of getEnumValues(Moves).slice(1)) { for (const move of getEnumValues(MoveId).slice(1)) {
const moveName = Moves[move].toUpperCase().replace(/\_/g, ""); const moveName = MoveId[move].toUpperCase().replace(/\_/g, "");
moveNameToId[moveName] = move; moveNameToId[moveName] = move;
} }

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,7 @@ import { Challenges } from "#enums/challenges";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { TrainerType } from "#enums/trainer-type"; import { TrainerType } from "#enums/trainer-type";
import { Nature } from "#enums/nature"; import { Nature } from "#enums/nature";
import type { Moves } from "#enums/moves"; import type { MoveId } from "#enums/moves";
import { TypeColor, TypeShadow } from "#enums/color"; import { TypeColor, TypeShadow } from "#enums/color";
import { ModifierTier } from "#app/modifier/modifier-tier"; import { ModifierTier } from "#app/modifier/modifier-tier";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
@ -395,11 +395,11 @@ export abstract class Challenge {
* An apply function for MOVE_ACCESS. Derived classes should alter this. * An apply function for MOVE_ACCESS. Derived classes should alter this.
* @param _pokemon {@link Pokemon} What pokemon would learn the move. * @param _pokemon {@link Pokemon} What pokemon would learn the move.
* @param _moveSource {@link MoveSourceType} What source the pokemon would get the move from. * @param _moveSource {@link MoveSourceType} What source the pokemon would get the move from.
* @param _move {@link Moves} The move in question. * @param _move {@link MoveId} The move in question.
* @param _level {@link NumberHolder} The level threshold for access. * @param _level {@link NumberHolder} The level threshold for access.
* @returns {@link boolean} Whether this function did anything. * @returns {@link boolean} Whether this function did anything.
*/ */
applyMoveAccessLevel(_pokemon: Pokemon, _moveSource: MoveSourceType, _move: Moves, _level: NumberHolder): boolean { applyMoveAccessLevel(_pokemon: Pokemon, _moveSource: MoveSourceType, _move: MoveId, _level: NumberHolder): boolean {
return false; return false;
} }
@ -407,11 +407,11 @@ export abstract class Challenge {
* An apply function for MOVE_WEIGHT. Derived classes should alter this. * An apply function for MOVE_WEIGHT. Derived classes should alter this.
* @param _pokemon {@link Pokemon} What pokemon would learn the move. * @param _pokemon {@link Pokemon} What pokemon would learn the move.
* @param _moveSource {@link MoveSourceType} What source the pokemon would get the move from. * @param _moveSource {@link MoveSourceType} What source the pokemon would get the move from.
* @param _move {@link Moves} The move in question. * @param _move {@link MoveId} The move in question.
* @param _weight {@link NumberHolder} The base weight of the move * @param _weight {@link NumberHolder} The base weight of the move
* @returns {@link boolean} Whether this function did anything. * @returns {@link boolean} Whether this function did anything.
*/ */
applyMoveWeight(_pokemon: Pokemon, _moveSource: MoveSourceType, _move: Moves, _level: NumberHolder): boolean { applyMoveWeight(_pokemon: Pokemon, _moveSource: MoveSourceType, _move: MoveId, _level: NumberHolder): boolean {
return false; return false;
} }
@ -1090,7 +1090,7 @@ export function applyChallenges(challengeType: ChallengeType.GAME_MODE_MODIFY):
* @param challengeType {@link ChallengeType} ChallengeType.MOVE_ACCESS * @param challengeType {@link ChallengeType} ChallengeType.MOVE_ACCESS
* @param pokemon {@link Pokemon} What pokemon would learn the move. * @param pokemon {@link Pokemon} What pokemon would learn the move.
* @param moveSource {@link MoveSourceType} What source the pokemon would get the move from. * @param moveSource {@link MoveSourceType} What source the pokemon would get the move from.
* @param move {@link Moves} The move in question. * @param move {@link MoveId} The move in question.
* @param level {@link NumberHolder} The level threshold for access. * @param level {@link NumberHolder} The level threshold for access.
* @returns True if any challenge was successfully applied. * @returns True if any challenge was successfully applied.
*/ */
@ -1098,7 +1098,7 @@ export function applyChallenges(
challengeType: ChallengeType.MOVE_ACCESS, challengeType: ChallengeType.MOVE_ACCESS,
pokemon: Pokemon, pokemon: Pokemon,
moveSource: MoveSourceType, moveSource: MoveSourceType,
move: Moves, move: MoveId,
level: NumberHolder, level: NumberHolder,
): boolean; ): boolean;
/** /**
@ -1106,7 +1106,7 @@ export function applyChallenges(
* @param challengeType {@link ChallengeType} ChallengeType.MOVE_WEIGHT * @param challengeType {@link ChallengeType} ChallengeType.MOVE_WEIGHT
* @param pokemon {@link Pokemon} What pokemon would learn the move. * @param pokemon {@link Pokemon} What pokemon would learn the move.
* @param moveSource {@link MoveSourceType} What source the pokemon would get the move from. * @param moveSource {@link MoveSourceType} What source the pokemon would get the move from.
* @param move {@link Moves} The move in question. * @param move {@link MoveId} The move in question.
* @param weight {@link NumberHolder} The weight of the move. * @param weight {@link NumberHolder} The weight of the move.
* @returns True if any challenge was successfully applied. * @returns True if any challenge was successfully applied.
*/ */
@ -1114,7 +1114,7 @@ export function applyChallenges(
challengeType: ChallengeType.MOVE_WEIGHT, challengeType: ChallengeType.MOVE_WEIGHT,
pokemon: Pokemon, pokemon: Pokemon,
moveSource: MoveSourceType, moveSource: MoveSourceType,
move: Moves, move: MoveId,
weight: NumberHolder, weight: NumberHolder,
): boolean; ): boolean;

View File

@ -1,257 +1,257 @@
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
/** Set of moves that cannot be called by {@linkcode Moves.METRONOME Metronome} */ /** Set of moves that cannot be called by {@linkcode MoveId.METRONOME Metronome} */
export const invalidMetronomeMoves: ReadonlySet<Moves> = new Set([ export const invalidMetronomeMoves: ReadonlySet<MoveId> = new Set([
Moves.AFTER_YOU, MoveId.AFTER_YOU,
Moves.ASSIST, MoveId.ASSIST,
Moves.BANEFUL_BUNKER, MoveId.BANEFUL_BUNKER,
Moves.BEAK_BLAST, MoveId.BEAK_BLAST,
Moves.BELCH, MoveId.BELCH,
Moves.BESTOW, MoveId.BESTOW,
Moves.COMEUPPANCE, MoveId.COMEUPPANCE,
Moves.COPYCAT, MoveId.COPYCAT,
Moves.COUNTER, MoveId.COUNTER,
Moves.CRAFTY_SHIELD, MoveId.CRAFTY_SHIELD,
Moves.DESTINY_BOND, MoveId.DESTINY_BOND,
Moves.DETECT, MoveId.DETECT,
Moves.ENDURE, MoveId.ENDURE,
Moves.FEINT, MoveId.FEINT,
Moves.FOCUS_PUNCH, MoveId.FOCUS_PUNCH,
Moves.FOLLOW_ME, MoveId.FOLLOW_ME,
Moves.HELPING_HAND, MoveId.HELPING_HAND,
Moves.INSTRUCT, MoveId.INSTRUCT,
Moves.KINGS_SHIELD, MoveId.KINGS_SHIELD,
Moves.MAT_BLOCK, MoveId.MAT_BLOCK,
Moves.ME_FIRST, MoveId.ME_FIRST,
Moves.METRONOME, MoveId.METRONOME,
Moves.MIMIC, MoveId.MIMIC,
Moves.MIRROR_COAT, MoveId.MIRROR_COAT,
Moves.MIRROR_MOVE, MoveId.MIRROR_MOVE,
Moves.OBSTRUCT, MoveId.OBSTRUCT,
Moves.PROTECT, MoveId.PROTECT,
Moves.QUASH, MoveId.QUASH,
Moves.QUICK_GUARD, MoveId.QUICK_GUARD,
Moves.RAGE_POWDER, MoveId.RAGE_POWDER,
Moves.REVIVAL_BLESSING, MoveId.REVIVAL_BLESSING,
Moves.SHELL_TRAP, MoveId.SHELL_TRAP,
Moves.SILK_TRAP, MoveId.SILK_TRAP,
Moves.SKETCH, MoveId.SKETCH,
Moves.SLEEP_TALK, MoveId.SLEEP_TALK,
Moves.SNATCH, MoveId.SNATCH,
Moves.SNORE, MoveId.SNORE,
Moves.SPIKY_SHIELD, MoveId.SPIKY_SHIELD,
Moves.SPOTLIGHT, MoveId.SPOTLIGHT,
Moves.STRUGGLE, MoveId.STRUGGLE,
Moves.TRANSFORM, MoveId.TRANSFORM,
Moves.WIDE_GUARD, MoveId.WIDE_GUARD,
]); ]);
/** Set of moves that cannot be called by {@linkcode Moves.ASSIST Assist} */ /** Set of moves that cannot be called by {@linkcode MoveId.ASSIST Assist} */
export const invalidAssistMoves: ReadonlySet<Moves> = new Set([ export const invalidAssistMoves: ReadonlySet<MoveId> = new Set([
Moves.ASSIST, MoveId.ASSIST,
Moves.BANEFUL_BUNKER, MoveId.BANEFUL_BUNKER,
Moves.BEAK_BLAST, MoveId.BEAK_BLAST,
Moves.BELCH, MoveId.BELCH,
Moves.BESTOW, MoveId.BESTOW,
Moves.BOUNCE, MoveId.BOUNCE,
Moves.CELEBRATE, MoveId.CELEBRATE,
Moves.CHATTER, MoveId.CHATTER,
Moves.CIRCLE_THROW, MoveId.CIRCLE_THROW,
Moves.COPYCAT, MoveId.COPYCAT,
Moves.COUNTER, MoveId.COUNTER,
Moves.DESTINY_BOND, MoveId.DESTINY_BOND,
Moves.DETECT, MoveId.DETECT,
Moves.DIG, MoveId.DIG,
Moves.DIVE, MoveId.DIVE,
Moves.DRAGON_TAIL, MoveId.DRAGON_TAIL,
Moves.ENDURE, MoveId.ENDURE,
Moves.FEINT, MoveId.FEINT,
Moves.FLY, MoveId.FLY,
Moves.FOCUS_PUNCH, MoveId.FOCUS_PUNCH,
Moves.FOLLOW_ME, MoveId.FOLLOW_ME,
Moves.HELPING_HAND, MoveId.HELPING_HAND,
Moves.HOLD_HANDS, MoveId.HOLD_HANDS,
Moves.KINGS_SHIELD, MoveId.KINGS_SHIELD,
Moves.MAT_BLOCK, MoveId.MAT_BLOCK,
Moves.ME_FIRST, MoveId.ME_FIRST,
Moves.METRONOME, MoveId.METRONOME,
Moves.MIMIC, MoveId.MIMIC,
Moves.MIRROR_COAT, MoveId.MIRROR_COAT,
Moves.MIRROR_MOVE, MoveId.MIRROR_MOVE,
Moves.NATURE_POWER, MoveId.NATURE_POWER,
Moves.PHANTOM_FORCE, MoveId.PHANTOM_FORCE,
Moves.PROTECT, MoveId.PROTECT,
Moves.RAGE_POWDER, MoveId.RAGE_POWDER,
Moves.ROAR, MoveId.ROAR,
Moves.SHADOW_FORCE, MoveId.SHADOW_FORCE,
Moves.SHELL_TRAP, MoveId.SHELL_TRAP,
Moves.SKETCH, MoveId.SKETCH,
Moves.SKY_DROP, MoveId.SKY_DROP,
Moves.SLEEP_TALK, MoveId.SLEEP_TALK,
Moves.SNATCH, MoveId.SNATCH,
Moves.SPIKY_SHIELD, MoveId.SPIKY_SHIELD,
Moves.SPOTLIGHT, MoveId.SPOTLIGHT,
Moves.STRUGGLE, MoveId.STRUGGLE,
Moves.SWITCHEROO, MoveId.SWITCHEROO,
Moves.TRANSFORM, MoveId.TRANSFORM,
Moves.TRICK, MoveId.TRICK,
Moves.WHIRLWIND, MoveId.WHIRLWIND,
]); ]);
/** Set of moves that cannot be called by {@linkcode Moves.SLEEP_TALK Sleep Talk} */ /** Set of moves that cannot be called by {@linkcode MoveId.SLEEP_TALK Sleep Talk} */
export const invalidSleepTalkMoves: ReadonlySet<Moves> = new Set([ export const invalidSleepTalkMoves: ReadonlySet<MoveId> = new Set([
Moves.ASSIST, MoveId.ASSIST,
Moves.BELCH, MoveId.BELCH,
Moves.BEAK_BLAST, MoveId.BEAK_BLAST,
Moves.BIDE, MoveId.BIDE,
Moves.BOUNCE, MoveId.BOUNCE,
Moves.COPYCAT, MoveId.COPYCAT,
Moves.DIG, MoveId.DIG,
Moves.DIVE, MoveId.DIVE,
Moves.FREEZE_SHOCK, MoveId.FREEZE_SHOCK,
Moves.FLY, MoveId.FLY,
Moves.FOCUS_PUNCH, MoveId.FOCUS_PUNCH,
Moves.GEOMANCY, MoveId.GEOMANCY,
Moves.ICE_BURN, MoveId.ICE_BURN,
Moves.ME_FIRST, MoveId.ME_FIRST,
Moves.METRONOME, MoveId.METRONOME,
Moves.MIRROR_MOVE, MoveId.MIRROR_MOVE,
Moves.MIMIC, MoveId.MIMIC,
Moves.PHANTOM_FORCE, MoveId.PHANTOM_FORCE,
Moves.RAZOR_WIND, MoveId.RAZOR_WIND,
Moves.SHADOW_FORCE, MoveId.SHADOW_FORCE,
Moves.SHELL_TRAP, MoveId.SHELL_TRAP,
Moves.SKETCH, MoveId.SKETCH,
Moves.SKULL_BASH, MoveId.SKULL_BASH,
Moves.SKY_ATTACK, MoveId.SKY_ATTACK,
Moves.SKY_DROP, MoveId.SKY_DROP,
Moves.SLEEP_TALK, MoveId.SLEEP_TALK,
Moves.SOLAR_BLADE, MoveId.SOLAR_BLADE,
Moves.SOLAR_BEAM, MoveId.SOLAR_BEAM,
Moves.STRUGGLE, MoveId.STRUGGLE,
Moves.UPROAR, MoveId.UPROAR,
]); ]);
/** Set of moves that cannot be copied by {@linkcode Moves.COPYCAT Copycat} */ /** Set of moves that cannot be copied by {@linkcode MoveId.COPYCAT Copycat} */
export const invalidCopycatMoves: ReadonlySet<Moves> = new Set([ export const invalidCopycatMoves: ReadonlySet<MoveId> = new Set([
Moves.ASSIST, MoveId.ASSIST,
Moves.BANEFUL_BUNKER, MoveId.BANEFUL_BUNKER,
Moves.BEAK_BLAST, MoveId.BEAK_BLAST,
Moves.BESTOW, MoveId.BESTOW,
Moves.CELEBRATE, MoveId.CELEBRATE,
Moves.CHATTER, MoveId.CHATTER,
Moves.CIRCLE_THROW, MoveId.CIRCLE_THROW,
Moves.COPYCAT, MoveId.COPYCAT,
Moves.COUNTER, MoveId.COUNTER,
Moves.DESTINY_BOND, MoveId.DESTINY_BOND,
Moves.DETECT, MoveId.DETECT,
Moves.DRAGON_TAIL, MoveId.DRAGON_TAIL,
Moves.ENDURE, MoveId.ENDURE,
Moves.FEINT, MoveId.FEINT,
Moves.FOCUS_PUNCH, MoveId.FOCUS_PUNCH,
Moves.FOLLOW_ME, MoveId.FOLLOW_ME,
Moves.HELPING_HAND, MoveId.HELPING_HAND,
Moves.HOLD_HANDS, MoveId.HOLD_HANDS,
Moves.KINGS_SHIELD, MoveId.KINGS_SHIELD,
Moves.MAT_BLOCK, MoveId.MAT_BLOCK,
Moves.ME_FIRST, MoveId.ME_FIRST,
Moves.METRONOME, MoveId.METRONOME,
Moves.MIMIC, MoveId.MIMIC,
Moves.MIRROR_COAT, MoveId.MIRROR_COAT,
Moves.MIRROR_MOVE, MoveId.MIRROR_MOVE,
Moves.PROTECT, MoveId.PROTECT,
Moves.RAGE_POWDER, MoveId.RAGE_POWDER,
Moves.ROAR, MoveId.ROAR,
Moves.SHELL_TRAP, MoveId.SHELL_TRAP,
Moves.SKETCH, MoveId.SKETCH,
Moves.SLEEP_TALK, MoveId.SLEEP_TALK,
Moves.SNATCH, MoveId.SNATCH,
Moves.SPIKY_SHIELD, MoveId.SPIKY_SHIELD,
Moves.SPOTLIGHT, MoveId.SPOTLIGHT,
Moves.STRUGGLE, MoveId.STRUGGLE,
Moves.SWITCHEROO, MoveId.SWITCHEROO,
Moves.TRANSFORM, MoveId.TRANSFORM,
Moves.TRICK, MoveId.TRICK,
Moves.WHIRLWIND, MoveId.WHIRLWIND,
]); ]);
export const invalidMirrorMoveMoves: ReadonlySet<Moves> = new Set([ export const invalidMirrorMoveMoves: ReadonlySet<MoveId> = new Set([
Moves.ACUPRESSURE, MoveId.ACUPRESSURE,
Moves.AFTER_YOU, MoveId.AFTER_YOU,
Moves.AROMATIC_MIST, MoveId.AROMATIC_MIST,
Moves.BEAK_BLAST, MoveId.BEAK_BLAST,
Moves.BELCH, MoveId.BELCH,
Moves.CHILLY_RECEPTION, MoveId.CHILLY_RECEPTION,
Moves.COACHING, MoveId.COACHING,
Moves.CONVERSION_2, MoveId.CONVERSION_2,
Moves.COUNTER, MoveId.COUNTER,
Moves.CRAFTY_SHIELD, MoveId.CRAFTY_SHIELD,
Moves.CURSE, MoveId.CURSE,
Moves.DECORATE, MoveId.DECORATE,
Moves.DOODLE, MoveId.DOODLE,
Moves.DOOM_DESIRE, MoveId.DOOM_DESIRE,
Moves.DRAGON_CHEER, MoveId.DRAGON_CHEER,
Moves.ELECTRIC_TERRAIN, MoveId.ELECTRIC_TERRAIN,
Moves.FINAL_GAMBIT, MoveId.FINAL_GAMBIT,
Moves.FLORAL_HEALING, MoveId.FLORAL_HEALING,
Moves.FLOWER_SHIELD, MoveId.FLOWER_SHIELD,
Moves.FOCUS_PUNCH, MoveId.FOCUS_PUNCH,
Moves.FUTURE_SIGHT, MoveId.FUTURE_SIGHT,
Moves.GEAR_UP, MoveId.GEAR_UP,
Moves.GRASSY_TERRAIN, MoveId.GRASSY_TERRAIN,
Moves.GRAVITY, MoveId.GRAVITY,
Moves.GUARD_SPLIT, MoveId.GUARD_SPLIT,
Moves.HAIL, MoveId.HAIL,
Moves.HAZE, MoveId.HAZE,
Moves.HEAL_PULSE, MoveId.HEAL_PULSE,
Moves.HELPING_HAND, MoveId.HELPING_HAND,
Moves.HOLD_HANDS, MoveId.HOLD_HANDS,
Moves.INSTRUCT, MoveId.INSTRUCT,
Moves.ION_DELUGE, MoveId.ION_DELUGE,
Moves.MAGNETIC_FLUX, MoveId.MAGNETIC_FLUX,
Moves.MAT_BLOCK, MoveId.MAT_BLOCK,
Moves.ME_FIRST, MoveId.ME_FIRST,
Moves.MIMIC, MoveId.MIMIC,
Moves.MIRROR_COAT, MoveId.MIRROR_COAT,
Moves.MIRROR_MOVE, MoveId.MIRROR_MOVE,
Moves.MIST, MoveId.MIST,
Moves.MISTY_TERRAIN, MoveId.MISTY_TERRAIN,
Moves.MUD_SPORT, MoveId.MUD_SPORT,
Moves.PERISH_SONG, MoveId.PERISH_SONG,
Moves.POWER_SPLIT, MoveId.POWER_SPLIT,
Moves.PSYCH_UP, MoveId.PSYCH_UP,
Moves.PSYCHIC_TERRAIN, MoveId.PSYCHIC_TERRAIN,
Moves.PURIFY, MoveId.PURIFY,
Moves.QUICK_GUARD, MoveId.QUICK_GUARD,
Moves.RAIN_DANCE, MoveId.RAIN_DANCE,
Moves.REFLECT_TYPE, MoveId.REFLECT_TYPE,
Moves.ROLE_PLAY, MoveId.ROLE_PLAY,
Moves.ROTOTILLER, MoveId.ROTOTILLER,
Moves.SANDSTORM, MoveId.SANDSTORM,
Moves.SHELL_TRAP, MoveId.SHELL_TRAP,
Moves.SKETCH, MoveId.SKETCH,
Moves.SNOWSCAPE, MoveId.SNOWSCAPE,
Moves.SPIT_UP, MoveId.SPIT_UP,
Moves.SPOTLIGHT, MoveId.SPOTLIGHT,
Moves.STRUGGLE, MoveId.STRUGGLE,
Moves.SUNNY_DAY, MoveId.SUNNY_DAY,
Moves.TEATIME, MoveId.TEATIME,
Moves.TRANSFORM, MoveId.TRANSFORM,
Moves.WATER_SPORT, MoveId.WATER_SPORT,
Moves.WIDE_GUARD, MoveId.WIDE_GUARD,
]); ]);
/** Set of moves that can never have their type overridden by an ability like Pixilate or Normalize /** Set of moves that can never have their type overridden by an ability like Pixilate or Normalize
* *
* Excludes tera blast and tera starstorm, as these are only conditionally forbidden * Excludes tera blast and tera starstorm, as these are only conditionally forbidden
*/ */
export const noAbilityTypeOverrideMoves: ReadonlySet<Moves> = new Set([ export const noAbilityTypeOverrideMoves: ReadonlySet<MoveId> = new Set([
Moves.WEATHER_BALL, MoveId.WEATHER_BALL,
Moves.JUDGMENT, MoveId.JUDGMENT,
Moves.REVELATION_DANCE, MoveId.REVELATION_DANCE,
Moves.MULTI_ATTACK, MoveId.MULTI_ATTACK,
Moves.TERRAIN_PULSE, MoveId.TERRAIN_PULSE,
Moves.NATURAL_GIFT, MoveId.NATURAL_GIFT,
Moves.TECHNO_BLAST, MoveId.TECHNO_BLAST,
Moves.HIDDEN_POWER, MoveId.HIDDEN_POWER,
]); ]);

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,7 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
import { BerryModifier, PokemonInstantReviveModifier } from "#app/modifier/modifier"; import { BerryModifier, PokemonInstantReviveModifier } from "#app/modifier/modifier";
import { getPokemonSpecies } from "#app/data/pokemon-species"; import { getPokemonSpecies } from "#app/data/pokemon-species";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type";
import { randInt } from "#app/utils/common"; import { randInt } from "#app/utils/common";
import { BattlerIndex } from "#app/battle"; import { BattlerIndex } from "#app/battle";
@ -232,7 +232,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = MysteryEncounterBuilde
isBoss: true, isBoss: true,
bossSegments: 3, bossSegments: 3,
shiny: false, // Shiny lock because of consistency issues between the different options shiny: false, // Shiny lock because of consistency issues between the different options
moveSet: [Moves.THRASH, Moves.CRUNCH, Moves.BODY_PRESS, Moves.SLACK_OFF], moveSet: [MoveId.THRASH, MoveId.CRUNCH, MoveId.BODY_PRESS, MoveId.SLACK_OFF],
modifierConfigs: bossModifierConfigs, modifierConfigs: bossModifierConfigs,
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON], tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
mysteryEncounterBattleEffects: (pokemon: Pokemon) => { mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
@ -302,7 +302,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = MysteryEncounterBuilde
encounter.startOfBattleEffects.push({ encounter.startOfBattleEffects.push({
sourceBattlerIndex: BattlerIndex.ENEMY, sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.ENEMY], targets: [BattlerIndex.ENEMY],
move: new PokemonMove(Moves.STUFF_CHEEKS), move: new PokemonMove(MoveId.STUFF_CHEEKS),
ignorePp: true, ignorePp: true,
}); });
@ -375,10 +375,10 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = MysteryEncounterBuilde
const level = getHighestLevelPlayerPokemon(false, true).level - 2; const level = getHighestLevelPlayerPokemon(false, true).level - 2;
const greedent = new EnemyPokemon(getPokemonSpecies(Species.GREEDENT), level, TrainerSlot.NONE, false, true); const greedent = new EnemyPokemon(getPokemonSpecies(Species.GREEDENT), level, TrainerSlot.NONE, false, true);
greedent.moveset = [ greedent.moveset = [
new PokemonMove(Moves.THRASH), new PokemonMove(MoveId.THRASH),
new PokemonMove(Moves.BODY_PRESS), new PokemonMove(MoveId.BODY_PRESS),
new PokemonMove(Moves.STUFF_CHEEKS), new PokemonMove(MoveId.STUFF_CHEEKS),
new PokemonMove(Moves.SLACK_OFF), new PokemonMove(MoveId.SLACK_OFF),
]; ];
greedent.passive = true; greedent.passive = true;

View File

@ -27,7 +27,7 @@ import type Pokemon from "#app/field/pokemon";
import { PokemonMove } from "#app/field/pokemon"; import { PokemonMove } from "#app/field/pokemon";
import { getEncounterText, showEncounterDialogue } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import { getEncounterText, showEncounterDialogue } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
import { LearnMovePhase } from "#app/phases/learn-move-phase"; import { LearnMovePhase } from "#app/phases/learn-move-phase";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import type { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler"; import type { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler";
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option"; import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
@ -144,25 +144,31 @@ const POOL_3_POKEMON: { species: Species; formIndex?: number }[] = [
const POOL_4_POKEMON = [Species.GENESECT, Species.SLITHER_WING, Species.BUZZWOLE, Species.PHEROMOSA]; const POOL_4_POKEMON = [Species.GENESECT, Species.SLITHER_WING, Species.BUZZWOLE, Species.PHEROMOSA];
const PHYSICAL_TUTOR_MOVES = [Moves.MEGAHORN, Moves.ATTACK_ORDER, Moves.BUG_BITE, Moves.FIRST_IMPRESSION, Moves.LUNGE]; const PHYSICAL_TUTOR_MOVES = [
MoveId.MEGAHORN,
MoveId.ATTACK_ORDER,
MoveId.BUG_BITE,
MoveId.FIRST_IMPRESSION,
MoveId.LUNGE,
];
const SPECIAL_TUTOR_MOVES = [ const SPECIAL_TUTOR_MOVES = [
Moves.SILVER_WIND, MoveId.SILVER_WIND,
Moves.SIGNAL_BEAM, MoveId.SIGNAL_BEAM,
Moves.BUG_BUZZ, MoveId.BUG_BUZZ,
Moves.POLLEN_PUFF, MoveId.POLLEN_PUFF,
Moves.STRUGGLE_BUG, MoveId.STRUGGLE_BUG,
]; ];
const STATUS_TUTOR_MOVES = [ const STATUS_TUTOR_MOVES = [
Moves.STRING_SHOT, MoveId.STRING_SHOT,
Moves.DEFEND_ORDER, MoveId.DEFEND_ORDER,
Moves.RAGE_POWDER, MoveId.RAGE_POWDER,
Moves.STICKY_WEB, MoveId.STICKY_WEB,
Moves.SILK_TRAP, MoveId.SILK_TRAP,
]; ];
const MISC_TUTOR_MOVES = [Moves.LEECH_LIFE, Moves.U_TURN, Moves.HEAL_ORDER, Moves.QUIVER_DANCE, Moves.INFESTATION]; const MISC_TUTOR_MOVES = [MoveId.LEECH_LIFE, MoveId.U_TURN, MoveId.HEAL_ORDER, MoveId.QUIVER_DANCE, MoveId.INFESTATION];
/** /**
* Wave breakpoints that determine how strong to make the Bug-Type Superfan's team * Wave breakpoints that determine how strong to make the Bug-Type Superfan's team

View File

@ -42,7 +42,7 @@ import { Ability } from "#app/data/abilities/ability-class";
import { BerryModifier } from "#app/modifier/modifier"; import { BerryModifier } from "#app/modifier/modifier";
import { BerryType } from "#enums/berry-type"; import { BerryType } from "#enums/berry-type";
import { BattlerIndex } from "#app/battle"; import { BattlerIndex } from "#app/battle";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { EncounterBattleAnim } from "#app/data/battle-anims"; import { EncounterBattleAnim } from "#app/data/battle-anims";
import { MoveCategory } from "#enums/MoveCategory"; import { MoveCategory } from "#enums/MoveCategory";
import { CustomPokemonData } from "#app/data/custom-pokemon-data"; import { CustomPokemonData } from "#app/data/custom-pokemon-data";
@ -156,7 +156,7 @@ export const ClowningAroundEncounter: MysteryEncounter = MysteryEncounterBuilder
{ {
species: getPokemonSpecies(Species.MR_MIME), species: getPokemonSpecies(Species.MR_MIME),
isBoss: true, isBoss: true,
moveSet: [Moves.TEETER_DANCE, Moves.ALLY_SWITCH, Moves.DAZZLING_GLEAM, Moves.PSYCHIC], moveSet: [MoveId.TEETER_DANCE, MoveId.ALLY_SWITCH, MoveId.DAZZLING_GLEAM, MoveId.PSYCHIC],
}, },
{ {
// Blacephalon has the random ability from pool, and 2 entirely random types to fit with the theme of the encounter // Blacephalon has the random ability from pool, and 2 entirely random types to fit with the theme of the encounter
@ -166,14 +166,14 @@ export const ClowningAroundEncounter: MysteryEncounter = MysteryEncounterBuilder
types: [firstType, secondType], types: [firstType, secondType],
}), }),
isBoss: true, isBoss: true,
moveSet: [Moves.TRICK, Moves.HYPNOSIS, Moves.SHADOW_BALL, Moves.MIND_BLOWN], moveSet: [MoveId.TRICK, MoveId.HYPNOSIS, MoveId.SHADOW_BALL, MoveId.MIND_BLOWN],
}, },
], ],
doubleBattle: true, doubleBattle: true,
}); });
// Load animations/sfx for start of fight moves // Load animations/sfx for start of fight moves
loadCustomMovesForEncounter([Moves.ROLE_PLAY, Moves.TAUNT]); loadCustomMovesForEncounter([MoveId.ROLE_PLAY, MoveId.TAUNT]);
encounter.setDialogueToken("blacephalonName", getPokemonSpecies(Species.BLACEPHALON).getName()); encounter.setDialogueToken("blacephalonName", getPokemonSpecies(Species.BLACEPHALON).getName());
@ -208,19 +208,19 @@ export const ClowningAroundEncounter: MysteryEncounter = MysteryEncounterBuilder
// Mr. Mime copies the Blacephalon's random ability // Mr. Mime copies the Blacephalon's random ability
sourceBattlerIndex: BattlerIndex.ENEMY, sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.ENEMY_2], targets: [BattlerIndex.ENEMY_2],
move: new PokemonMove(Moves.ROLE_PLAY), move: new PokemonMove(MoveId.ROLE_PLAY),
ignorePp: true, ignorePp: true,
}, },
{ {
sourceBattlerIndex: BattlerIndex.ENEMY_2, sourceBattlerIndex: BattlerIndex.ENEMY_2,
targets: [BattlerIndex.PLAYER], targets: [BattlerIndex.PLAYER],
move: new PokemonMove(Moves.TAUNT), move: new PokemonMove(MoveId.TAUNT),
ignorePp: true, ignorePp: true,
}, },
{ {
sourceBattlerIndex: BattlerIndex.ENEMY_2, sourceBattlerIndex: BattlerIndex.ENEMY_2,
targets: [BattlerIndex.PLAYER_2], targets: [BattlerIndex.PLAYER_2],
move: new PokemonMove(Moves.TAUNT), move: new PokemonMove(MoveId.TAUNT),
ignorePp: true, ignorePp: true,
}, },
); );

View File

@ -33,7 +33,7 @@ import type { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler"
import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type";
import { Biome } from "#enums/biome"; import { Biome } from "#enums/biome";
import { EncounterAnim } from "#enums/encounter-anims"; import { EncounterAnim } from "#enums/encounter-anims";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type";
@ -130,11 +130,11 @@ export const DancingLessonsEncounter: MysteryEncounter = MysteryEncounterBuilder
const species = getPokemonSpecies(Species.ORICORIO); const species = getPokemonSpecies(Species.ORICORIO);
const level = getEncounterPokemonLevelForWave(STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER); const level = getEncounterPokemonLevelForWave(STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER);
const enemyPokemon = new EnemyPokemon(species, level, TrainerSlot.NONE, false); const enemyPokemon = new EnemyPokemon(species, level, TrainerSlot.NONE, false);
if (!enemyPokemon.moveset.some(m => m && m.getMove().id === Moves.REVELATION_DANCE)) { if (!enemyPokemon.moveset.some(m => m && m.getMove().id === MoveId.REVELATION_DANCE)) {
if (enemyPokemon.moveset.length < 4) { if (enemyPokemon.moveset.length < 4) {
enemyPokemon.moveset.push(new PokemonMove(Moves.REVELATION_DANCE)); enemyPokemon.moveset.push(new PokemonMove(MoveId.REVELATION_DANCE));
} else { } else {
enemyPokemon.moveset[0] = new PokemonMove(Moves.REVELATION_DANCE); enemyPokemon.moveset[0] = new PokemonMove(MoveId.REVELATION_DANCE);
} }
} }
@ -215,7 +215,7 @@ export const DancingLessonsEncounter: MysteryEncounter = MysteryEncounterBuilder
encounter.startOfBattleEffects.push({ encounter.startOfBattleEffects.push({
sourceBattlerIndex: BattlerIndex.ENEMY, sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.PLAYER], targets: [BattlerIndex.PLAYER],
move: new PokemonMove(Moves.REVELATION_DANCE), move: new PokemonMove(MoveId.REVELATION_DANCE),
ignorePp: true, ignorePp: true,
}); });
@ -246,7 +246,7 @@ export const DancingLessonsEncounter: MysteryEncounter = MysteryEncounterBuilder
const onPokemonSelected = (pokemon: PlayerPokemon) => { const onPokemonSelected = (pokemon: PlayerPokemon) => {
encounter.setDialogueToken("selectedPokemon", pokemon.getNameToRender()); encounter.setDialogueToken("selectedPokemon", pokemon.getNameToRender());
globalScene.unshiftPhase( globalScene.unshiftPhase(
new LearnMovePhase(globalScene.getPlayerParty().indexOf(pokemon), Moves.REVELATION_DANCE), new LearnMovePhase(globalScene.getPlayerParty().indexOf(pokemon), MoveId.REVELATION_DANCE),
); );
// Play animation again to "learn" the dance // Play animation again to "learn" the dance

View File

@ -27,7 +27,7 @@ import { PokemonType } from "#enums/pokemon-type";
import { BattlerIndex } from "#app/battle"; import { BattlerIndex } from "#app/battle";
import type Pokemon from "#app/field/pokemon"; import type Pokemon from "#app/field/pokemon";
import { PokemonMove } from "#app/field/pokemon"; import { PokemonMove } from "#app/field/pokemon";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { EncounterBattleAnim } from "#app/data/battle-anims"; import { EncounterBattleAnim } from "#app/data/battle-anims";
import { WeatherType } from "#enums/weather-type"; import { WeatherType } from "#enums/weather-type";
import { isNullOrUndefined, randSeedInt } from "#app/utils/common"; import { isNullOrUndefined, randSeedInt } from "#app/utils/common";
@ -138,7 +138,7 @@ export const FieryFalloutEncounter: MysteryEncounter = MysteryEncounterBuilder.w
]; ];
// Load animations/sfx for Volcarona moves // Load animations/sfx for Volcarona moves
loadCustomMovesForEncounter([Moves.FIRE_SPIN, Moves.QUIVER_DANCE]); loadCustomMovesForEncounter([MoveId.FIRE_SPIN, MoveId.QUIVER_DANCE]);
const pokemon = globalScene.getEnemyPokemon(); const pokemon = globalScene.getEnemyPokemon();
globalScene.arena.trySetWeather(WeatherType.SUNNY, pokemon); globalScene.arena.trySetWeather(WeatherType.SUNNY, pokemon);
@ -193,13 +193,13 @@ export const FieryFalloutEncounter: MysteryEncounter = MysteryEncounterBuilder.w
{ {
sourceBattlerIndex: BattlerIndex.ENEMY, sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.PLAYER], targets: [BattlerIndex.PLAYER],
move: new PokemonMove(Moves.FIRE_SPIN), move: new PokemonMove(MoveId.FIRE_SPIN),
ignorePp: true, ignorePp: true,
}, },
{ {
sourceBattlerIndex: BattlerIndex.ENEMY_2, sourceBattlerIndex: BattlerIndex.ENEMY_2,
targets: [BattlerIndex.PLAYER_2], targets: [BattlerIndex.PLAYER_2],
move: new PokemonMove(Moves.FIRE_SPIN), move: new PokemonMove(MoveId.FIRE_SPIN),
ignorePp: true, ignorePp: true,
}, },
); );

View File

@ -1,5 +1,5 @@
import { getPokemonSpecies } from "#app/data/pokemon-species"; import { getPokemonSpecies } from "#app/data/pokemon-species";
import { Moves } from "#app/enums/moves"; import { MoveId } from "#app/enums/moves";
import { Species } from "#app/enums/species"; import { Species } from "#app/enums/species";
import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
@ -13,8 +13,8 @@ import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
import { PokemonMove } from "#app/field/pokemon"; import { PokemonMove } from "#app/field/pokemon";
const OPTION_1_REQUIRED_MOVE = Moves.SURF; const OPTION_1_REQUIRED_MOVE = MoveId.SURF;
const OPTION_2_REQUIRED_MOVE = Moves.FLY; const OPTION_2_REQUIRED_MOVE = MoveId.FLY;
/** /**
* Damage percentage taken when wandering aimlessly. * Damage percentage taken when wandering aimlessly.
* Can be a number between `0` - `100`. * Can be a number between `0` - `100`.

View File

@ -19,7 +19,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
import { ModifierTier } from "#app/modifier/modifier-tier"; import { ModifierTier } from "#app/modifier/modifier-tier";
import { GameOverPhase } from "#app/phases/game-over-phase"; import { GameOverPhase } from "#app/phases/game-over-phase";
import { randSeedInt } from "#app/utils/common"; import { randSeedInt } from "#app/utils/common";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type";
@ -89,7 +89,7 @@ export const MysteriousChestEncounter: MysteryEncounter = MysteryEncounterBuilde
species: getPokemonSpecies(Species.GIMMIGHOUL), species: getPokemonSpecies(Species.GIMMIGHOUL),
formIndex: 0, formIndex: 0,
isBoss: true, isBoss: true,
moveSet: [Moves.NASTY_PLOT, Moves.SHADOW_BALL, Moves.POWER_GEM, Moves.THIEF], moveSet: [MoveId.NASTY_PLOT, MoveId.SHADOW_BALL, MoveId.POWER_GEM, MoveId.THIEF],
}, },
], ],
}; };

View File

@ -20,7 +20,7 @@ import {
} from "../utils/encounter-phase-utils"; } from "../utils/encounter-phase-utils";
import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
import { Nature } from "#enums/nature"; import { Nature } from "#enums/nature";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { BattlerIndex } from "#app/battle"; import { BattlerIndex } from "#app/battle";
import { AiType, PokemonMove } from "#app/field/pokemon"; import { AiType, PokemonMove } from "#app/field/pokemon";
import { getPokemonSpecies } from "#app/data/pokemon-species"; import { getPokemonSpecies } from "#app/data/pokemon-species";
@ -76,7 +76,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter = MysteryEncounterBuil
shiny: false, // Shiny lock because shiny is rolled only if the battle option is picked shiny: false, // Shiny lock because shiny is rolled only if the battle option is picked
status: [StatusEffect.SLEEP, 6], // Extra turns on timer for Snorlax's start of fight moves status: [StatusEffect.SLEEP, 6], // Extra turns on timer for Snorlax's start of fight moves
nature: Nature.DOCILE, nature: Nature.DOCILE,
moveSet: [Moves.BODY_SLAM, Moves.CRUNCH, Moves.SLEEP_TALK, Moves.REST], moveSet: [MoveId.BODY_SLAM, MoveId.CRUNCH, MoveId.SLEEP_TALK, MoveId.REST],
modifierConfigs: [ modifierConfigs: [
{ {
modifier: generateModifierType(modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType, modifier: generateModifierType(modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType,
@ -106,7 +106,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter = MysteryEncounterBuil
encounter.enemyPartyConfigs = [config]; encounter.enemyPartyConfigs = [config];
// Load animations/sfx for Snorlax fight start moves // Load animations/sfx for Snorlax fight start moves
loadCustomMovesForEncounter([Moves.SNORE]); loadCustomMovesForEncounter([MoveId.SNORE]);
encounter.setDialogueToken("snorlaxName", getPokemonSpecies(Species.SNORLAX).getName()); encounter.setDialogueToken("snorlaxName", getPokemonSpecies(Species.SNORLAX).getName());
@ -133,14 +133,12 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter = MysteryEncounterBuil
guaranteedModifierTypeFuncs: [modifierTypes.LEFTOVERS], guaranteedModifierTypeFuncs: [modifierTypes.LEFTOVERS],
fillRemaining: true, fillRemaining: true,
}); });
encounter.startOfBattleEffects.push( encounter.startOfBattleEffects.push({
{
sourceBattlerIndex: BattlerIndex.ENEMY, sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.PLAYER], targets: [BattlerIndex.PLAYER],
move: new PokemonMove(Moves.SNORE), move: new PokemonMove(MoveId.SNORE),
ignorePp: true, ignorePp: true,
}, });
);
await initBattleWithEnemyConfig(encounter.enemyPartyConfigs[0]); await initBattleWithEnemyConfig(encounter.enemyPartyConfigs[0]);
}, },
) )

View File

@ -18,7 +18,7 @@ import { Species } from "#enums/species";
import { getPokemonSpecies } from "#app/data/pokemon-species"; import { getPokemonSpecies } from "#app/data/pokemon-species";
import { speciesStarterCosts } from "#app/data/balance/starters"; import { speciesStarterCosts } from "#app/data/balance/starters";
import { Nature } from "#enums/nature"; import { Nature } from "#enums/nature";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import type { PlayerPokemon } from "#app/field/pokemon"; import type { PlayerPokemon } from "#app/field/pokemon";
import { getEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import { getEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
import type { IEggOptions } from "#app/data/egg"; import type { IEggOptions } from "#app/data/egg";
@ -482,7 +482,7 @@ function getPartyConfig(): EnemyPartyConfig {
abilityIndex: 1, // Magic Guard abilityIndex: 1, // Magic Guard
shiny: false, shiny: false,
nature: Nature.ADAMANT, nature: Nature.ADAMANT,
moveSet: [Moves.FIRE_PUNCH, Moves.ICE_PUNCH, Moves.THUNDER_PUNCH, Moves.METEOR_MASH], moveSet: [MoveId.FIRE_PUNCH, MoveId.ICE_PUNCH, MoveId.THUNDER_PUNCH, MoveId.METEOR_MASH],
ivs: [31, 31, 31, 31, 31, 31], ivs: [31, 31, 31, 31, 31, 31],
tera: PokemonType.FAIRY, tera: PokemonType.FAIRY,
}, },
@ -502,7 +502,7 @@ function getPartyConfig(): EnemyPartyConfig {
shiny: true, shiny: true,
variant: 1, variant: 1,
nature: Nature.MODEST, nature: Nature.MODEST,
moveSet: [Moves.MOONBLAST, Moves.MYSTICAL_FIRE, Moves.ICE_BEAM, Moves.THUNDERBOLT], moveSet: [MoveId.MOONBLAST, MoveId.MYSTICAL_FIRE, MoveId.ICE_BEAM, MoveId.THUNDERBOLT],
ivs: [31, 31, 31, 31, 31, 31], ivs: [31, 31, 31, 31, 31, 31],
}, },
{ {
@ -515,7 +515,7 @@ function getPartyConfig(): EnemyPartyConfig {
shiny: true, shiny: true,
variant: 2, variant: 2,
nature: Nature.BOLD, nature: Nature.BOLD,
moveSet: [Moves.TRI_ATTACK, Moves.STORED_POWER, Moves.TAKE_HEART, Moves.MOONLIGHT], moveSet: [MoveId.TRI_ATTACK, MoveId.STORED_POWER, MoveId.TAKE_HEART, MoveId.MOONLIGHT],
ivs: [31, 31, 31, 31, 31, 31], ivs: [31, 31, 31, 31, 31, 31],
}, },
); );

View File

@ -20,7 +20,7 @@ import type Pokemon from "#app/field/pokemon";
import { PokemonMove } from "#app/field/pokemon"; import { PokemonMove } from "#app/field/pokemon";
import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
import { modifyPlayerPokemonBST } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; import { modifyPlayerPokemonBST } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { BattlerIndex } from "#app/battle"; import { BattlerIndex } from "#app/battle";
import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type";
import { BerryType } from "#enums/berry-type"; import { BerryType } from "#enums/berry-type";
@ -94,7 +94,7 @@ export const TheStrongStuffEncounter: MysteryEncounter = MysteryEncounterBuilder
shiny: false, // Shiny lock because shiny is rolled only if the battle option is picked shiny: false, // Shiny lock because shiny is rolled only if the battle option is picked
customPokemonData: new CustomPokemonData({ spriteScale: 1.25 }), customPokemonData: new CustomPokemonData({ spriteScale: 1.25 }),
nature: Nature.HARDY, nature: Nature.HARDY,
moveSet: [Moves.INFESTATION, Moves.SALT_CURE, Moves.GASTRO_ACID, Moves.HEAL_ORDER], moveSet: [MoveId.INFESTATION, MoveId.SALT_CURE, MoveId.GASTRO_ACID, MoveId.HEAL_ORDER],
modifierConfigs: [ modifierConfigs: [
{ {
modifier: generateModifierType(modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType, modifier: generateModifierType(modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType,
@ -126,7 +126,7 @@ export const TheStrongStuffEncounter: MysteryEncounter = MysteryEncounterBuilder
encounter.enemyPartyConfigs = [config]; encounter.enemyPartyConfigs = [config];
loadCustomMovesForEncounter([Moves.GASTRO_ACID, Moves.STEALTH_ROCK]); loadCustomMovesForEncounter([MoveId.GASTRO_ACID, MoveId.STEALTH_ROCK]);
encounter.setDialogueToken("shuckleName", getPokemonSpecies(Species.SHUCKLE).getName()); encounter.setDialogueToken("shuckleName", getPokemonSpecies(Species.SHUCKLE).getName());
@ -210,13 +210,13 @@ export const TheStrongStuffEncounter: MysteryEncounter = MysteryEncounterBuilder
{ {
sourceBattlerIndex: BattlerIndex.ENEMY, sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.PLAYER], targets: [BattlerIndex.PLAYER],
move: new PokemonMove(Moves.GASTRO_ACID), move: new PokemonMove(MoveId.GASTRO_ACID),
ignorePp: true, ignorePp: true,
}, },
{ {
sourceBattlerIndex: BattlerIndex.ENEMY, sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.PLAYER], targets: [BattlerIndex.PLAYER],
move: new PokemonMove(Moves.STEALTH_ROCK), move: new PokemonMove(MoveId.STEALTH_ROCK),
ignorePp: true, ignorePp: true,
}, },
); );

View File

@ -18,7 +18,7 @@ import { TrainerType } from "#enums/trainer-type";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { getPokemonSpecies } from "#app/data/pokemon-species"; import { getPokemonSpecies } from "#app/data/pokemon-species";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Nature } from "#enums/nature"; import { Nature } from "#enums/nature";
import { PokemonType } from "#enums/pokemon-type"; import { PokemonType } from "#enums/pokemon-type";
import { BerryType } from "#enums/berry-type"; import { BerryType } from "#enums/berry-type";
@ -260,7 +260,7 @@ function getVictorTrainerConfig(): EnemyPartyConfig {
isBoss: false, isBoss: false,
abilityIndex: 0, // Guts abilityIndex: 0, // Guts
nature: Nature.ADAMANT, nature: Nature.ADAMANT,
moveSet: [Moves.FACADE, Moves.BRAVE_BIRD, Moves.PROTECT, Moves.QUICK_ATTACK], moveSet: [MoveId.FACADE, MoveId.BRAVE_BIRD, MoveId.PROTECT, MoveId.QUICK_ATTACK],
modifierConfigs: [ modifierConfigs: [
{ {
modifier: generateModifierType(modifierTypes.FLAME_ORB) as PokemonHeldItemModifierType, modifier: generateModifierType(modifierTypes.FLAME_ORB) as PokemonHeldItemModifierType,
@ -278,7 +278,7 @@ function getVictorTrainerConfig(): EnemyPartyConfig {
isBoss: false, isBoss: false,
abilityIndex: 1, // Guts abilityIndex: 1, // Guts
nature: Nature.ADAMANT, nature: Nature.ADAMANT,
moveSet: [Moves.FACADE, Moves.OBSTRUCT, Moves.NIGHT_SLASH, Moves.FIRE_PUNCH], moveSet: [MoveId.FACADE, MoveId.OBSTRUCT, MoveId.NIGHT_SLASH, MoveId.FIRE_PUNCH],
modifierConfigs: [ modifierConfigs: [
{ {
modifier: generateModifierType(modifierTypes.FLAME_ORB) as PokemonHeldItemModifierType, modifier: generateModifierType(modifierTypes.FLAME_ORB) as PokemonHeldItemModifierType,
@ -304,7 +304,7 @@ function getVictoriaTrainerConfig(): EnemyPartyConfig {
isBoss: false, isBoss: false,
abilityIndex: 0, // Natural Cure abilityIndex: 0, // Natural Cure
nature: Nature.CALM, nature: Nature.CALM,
moveSet: [Moves.SYNTHESIS, Moves.SLUDGE_BOMB, Moves.GIGA_DRAIN, Moves.SLEEP_POWDER], moveSet: [MoveId.SYNTHESIS, MoveId.SLUDGE_BOMB, MoveId.GIGA_DRAIN, MoveId.SLEEP_POWDER],
modifierConfigs: [ modifierConfigs: [
{ {
modifier: generateModifierType(modifierTypes.SOUL_DEW) as PokemonHeldItemModifierType, modifier: generateModifierType(modifierTypes.SOUL_DEW) as PokemonHeldItemModifierType,
@ -322,7 +322,7 @@ function getVictoriaTrainerConfig(): EnemyPartyConfig {
isBoss: false, isBoss: false,
formIndex: 1, formIndex: 1,
nature: Nature.TIMID, nature: Nature.TIMID,
moveSet: [Moves.PSYSHOCK, Moves.MOONBLAST, Moves.SHADOW_BALL, Moves.WILL_O_WISP], moveSet: [MoveId.PSYSHOCK, MoveId.MOONBLAST, MoveId.SHADOW_BALL, MoveId.WILL_O_WISP],
modifierConfigs: [ modifierConfigs: [
{ {
modifier: generateModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, [ modifier: generateModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, [
@ -353,7 +353,7 @@ function getViviTrainerConfig(): EnemyPartyConfig {
isBoss: false, isBoss: false,
abilityIndex: 3, // Lightning Rod abilityIndex: 3, // Lightning Rod
nature: Nature.ADAMANT, nature: Nature.ADAMANT,
moveSet: [Moves.WATERFALL, Moves.MEGAHORN, Moves.KNOCK_OFF, Moves.REST], moveSet: [MoveId.WATERFALL, MoveId.MEGAHORN, MoveId.KNOCK_OFF, MoveId.REST],
modifierConfigs: [ modifierConfigs: [
{ {
modifier: generateModifierType(modifierTypes.BERRY, [BerryType.LUM]) as PokemonHeldItemModifierType, modifier: generateModifierType(modifierTypes.BERRY, [BerryType.LUM]) as PokemonHeldItemModifierType,
@ -372,7 +372,7 @@ function getViviTrainerConfig(): EnemyPartyConfig {
isBoss: false, isBoss: false,
abilityIndex: 1, // Poison Heal abilityIndex: 1, // Poison Heal
nature: Nature.JOLLY, nature: Nature.JOLLY,
moveSet: [Moves.SPORE, Moves.SWORDS_DANCE, Moves.SEED_BOMB, Moves.DRAIN_PUNCH], moveSet: [MoveId.SPORE, MoveId.SWORDS_DANCE, MoveId.SEED_BOMB, MoveId.DRAIN_PUNCH],
modifierConfigs: [ modifierConfigs: [
{ {
modifier: generateModifierType(modifierTypes.BASE_STAT_BOOSTER, [Stat.HP]) as PokemonHeldItemModifierType, modifier: generateModifierType(modifierTypes.BASE_STAT_BOOSTER, [Stat.HP]) as PokemonHeldItemModifierType,
@ -390,7 +390,7 @@ function getViviTrainerConfig(): EnemyPartyConfig {
isBoss: false, isBoss: false,
formIndex: 1, formIndex: 1,
nature: Nature.CALM, nature: Nature.CALM,
moveSet: [Moves.EARTH_POWER, Moves.FIRE_BLAST, Moves.YAWN, Moves.PROTECT], moveSet: [MoveId.EARTH_POWER, MoveId.FIRE_BLAST, MoveId.YAWN, MoveId.PROTECT],
modifierConfigs: [ modifierConfigs: [
{ {
modifier: generateModifierType(modifierTypes.QUICK_CLAW) as PokemonHeldItemModifierType, modifier: generateModifierType(modifierTypes.QUICK_CLAW) as PokemonHeldItemModifierType,
@ -412,7 +412,7 @@ function getVickyTrainerConfig(): EnemyPartyConfig {
isBoss: false, isBoss: false,
formIndex: 1, formIndex: 1,
nature: Nature.IMPISH, nature: Nature.IMPISH,
moveSet: [Moves.AXE_KICK, Moves.ICE_PUNCH, Moves.ZEN_HEADBUTT, Moves.BULLET_PUNCH], moveSet: [MoveId.AXE_KICK, MoveId.ICE_PUNCH, MoveId.ZEN_HEADBUTT, MoveId.BULLET_PUNCH],
modifierConfigs: [ modifierConfigs: [
{ {
modifier: generateModifierType(modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType, modifier: generateModifierType(modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType,
@ -433,7 +433,7 @@ function getVitoTrainerConfig(): EnemyPartyConfig {
isBoss: false, isBoss: false,
abilityIndex: 0, // Soundproof abilityIndex: 0, // Soundproof
nature: Nature.MODEST, nature: Nature.MODEST,
moveSet: [Moves.THUNDERBOLT, Moves.GIGA_DRAIN, Moves.FOUL_PLAY, Moves.THUNDER_WAVE], moveSet: [MoveId.THUNDERBOLT, MoveId.GIGA_DRAIN, MoveId.FOUL_PLAY, MoveId.THUNDER_WAVE],
modifierConfigs: [ modifierConfigs: [
{ {
modifier: generateModifierType(modifierTypes.BASE_STAT_BOOSTER, [Stat.SPD]) as PokemonHeldItemModifierType, modifier: generateModifierType(modifierTypes.BASE_STAT_BOOSTER, [Stat.SPD]) as PokemonHeldItemModifierType,
@ -447,7 +447,7 @@ function getVitoTrainerConfig(): EnemyPartyConfig {
isBoss: false, isBoss: false,
abilityIndex: 2, // Gluttony abilityIndex: 2, // Gluttony
nature: Nature.QUIET, nature: Nature.QUIET,
moveSet: [Moves.SLUDGE_BOMB, Moves.GIGA_DRAIN, Moves.ICE_BEAM, Moves.EARTHQUAKE], moveSet: [MoveId.SLUDGE_BOMB, MoveId.GIGA_DRAIN, MoveId.ICE_BEAM, MoveId.EARTHQUAKE],
modifierConfigs: [ modifierConfigs: [
{ {
modifier: generateModifierType(modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType, modifier: generateModifierType(modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType,
@ -500,7 +500,7 @@ function getVitoTrainerConfig(): EnemyPartyConfig {
isBoss: false, isBoss: false,
abilityIndex: 2, // Tangled Feet abilityIndex: 2, // Tangled Feet
nature: Nature.JOLLY, nature: Nature.JOLLY,
moveSet: [Moves.DRILL_PECK, Moves.QUICK_ATTACK, Moves.THRASH, Moves.KNOCK_OFF], moveSet: [MoveId.DRILL_PECK, MoveId.QUICK_ATTACK, MoveId.THRASH, MoveId.KNOCK_OFF],
modifierConfigs: [ modifierConfigs: [
{ {
modifier: generateModifierType(modifierTypes.KINGS_ROCK) as PokemonHeldItemModifierType, modifier: generateModifierType(modifierTypes.KINGS_ROCK) as PokemonHeldItemModifierType,
@ -514,7 +514,7 @@ function getVitoTrainerConfig(): EnemyPartyConfig {
isBoss: false, isBoss: false,
formIndex: 1, formIndex: 1,
nature: Nature.BOLD, nature: Nature.BOLD,
moveSet: [Moves.PSYCHIC, Moves.SHADOW_BALL, Moves.FOCUS_BLAST, Moves.THUNDERBOLT], moveSet: [MoveId.PSYCHIC, MoveId.SHADOW_BALL, MoveId.FOCUS_BLAST, MoveId.THUNDERBOLT],
modifierConfigs: [ modifierConfigs: [
{ {
modifier: generateModifierType(modifierTypes.WIDE_LENS) as PokemonHeldItemModifierType, modifier: generateModifierType(modifierTypes.WIDE_LENS) as PokemonHeldItemModifierType,
@ -528,7 +528,7 @@ function getVitoTrainerConfig(): EnemyPartyConfig {
isBoss: false, isBoss: false,
abilityIndex: 0, // Sheer Force abilityIndex: 0, // Sheer Force
nature: Nature.IMPISH, nature: Nature.IMPISH,
moveSet: [Moves.EARTHQUAKE, Moves.U_TURN, Moves.FLARE_BLITZ, Moves.ROCK_SLIDE], moveSet: [MoveId.EARTHQUAKE, MoveId.U_TURN, MoveId.FLARE_BLITZ, MoveId.ROCK_SLIDE],
modifierConfigs: [ modifierConfigs: [
{ {
modifier: generateModifierType(modifierTypes.QUICK_CLAW) as PokemonHeldItemModifierType, modifier: generateModifierType(modifierTypes.QUICK_CLAW) as PokemonHeldItemModifierType,

View File

@ -23,7 +23,7 @@ import { showEncounterText } from "#app/data/mystery-encounters/utils/encounter-
import i18next from "#app/plugins/i18n"; import i18next from "#app/plugins/i18n";
import { ModifierTier } from "#app/modifier/modifier-tier"; import { ModifierTier } from "#app/modifier/modifier-tier";
import { getPokemonSpecies } from "#app/data/pokemon-species"; import { getPokemonSpecies } from "#app/data/pokemon-species";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { BattlerIndex } from "#app/battle"; import { BattlerIndex } from "#app/battle";
import { PokemonMove } from "#app/field/pokemon"; import { PokemonMove } from "#app/field/pokemon";
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
@ -81,7 +81,7 @@ export const TrashToTreasureEncounter: MysteryEncounter = MysteryEncounterBuilde
shiny: false, // Shiny lock because of custom intro sprite shiny: false, // Shiny lock because of custom intro sprite
formIndex: 1, // Gmax formIndex: 1, // Gmax
bossSegmentModifier: 1, // +1 Segment from normal bossSegmentModifier: 1, // +1 Segment from normal
moveSet: [Moves.GUNK_SHOT, Moves.STOMPING_TANTRUM, Moves.HAMMER_ARM, Moves.PAYBACK], moveSet: [MoveId.GUNK_SHOT, MoveId.STOMPING_TANTRUM, MoveId.HAMMER_ARM, MoveId.PAYBACK],
modifierConfigs: [ modifierConfigs: [
{ {
modifier: generateModifierType(modifierTypes.BERRY) as PokemonHeldItemModifierType, modifier: generateModifierType(modifierTypes.BERRY) as PokemonHeldItemModifierType,
@ -127,7 +127,7 @@ export const TrashToTreasureEncounter: MysteryEncounter = MysteryEncounterBuilde
encounter.enemyPartyConfigs = [config]; encounter.enemyPartyConfigs = [config];
// Load animations/sfx for Garbodor fight start moves // Load animations/sfx for Garbodor fight start moves
loadCustomMovesForEncounter([Moves.TOXIC, Moves.STOCKPILE]); loadCustomMovesForEncounter([MoveId.TOXIC, MoveId.STOCKPILE]);
globalScene.loadSe("PRSFX- Dig2", "battle_anims", "PRSFX- Dig2.wav"); globalScene.loadSe("PRSFX- Dig2", "battle_anims", "PRSFX- Dig2.wav");
globalScene.loadSe("PRSFX- Venom Drench", "battle_anims", "PRSFX- Venom Drench.wav"); globalScene.loadSe("PRSFX- Venom Drench", "battle_anims", "PRSFX- Venom Drench.wav");
@ -206,13 +206,13 @@ export const TrashToTreasureEncounter: MysteryEncounter = MysteryEncounterBuilde
{ {
sourceBattlerIndex: BattlerIndex.ENEMY, sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.PLAYER], targets: [BattlerIndex.PLAYER],
move: new PokemonMove(Moves.TOXIC), move: new PokemonMove(MoveId.TOXIC),
ignorePp: true, ignorePp: true,
}, },
{ {
sourceBattlerIndex: BattlerIndex.ENEMY, sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.ENEMY], targets: [BattlerIndex.ENEMY],
move: new PokemonMove(Moves.STOCKPILE), move: new PokemonMove(MoveId.STOCKPILE),
ignorePp: true, ignorePp: true,
}, },
); );

View File

@ -28,7 +28,7 @@ import {
} from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
import PokemonData from "#app/system/pokemon-data"; import PokemonData from "#app/system/pokemon-data";
import { isNullOrUndefined, randSeedInt } from "#app/utils/common"; import { isNullOrUndefined, randSeedInt } from "#app/utils/common";
import type { Moves } from "#enums/moves"; import type { MoveId } from "#enums/moves";
import { BattlerIndex } from "#app/battle"; import { BattlerIndex } from "#app/battle";
import { SelfStatusMove } from "#app/data/moves/move"; import { SelfStatusMove } from "#app/data/moves/move";
import { PokeballType } from "#enums/pokeball"; import { PokeballType } from "#enums/pokeball";
@ -73,7 +73,7 @@ export const UncommonBreedEncounter: MysteryEncounter = MysteryEncounterBuilder.
const eggMoves = pokemon.getEggMoves(); const eggMoves = pokemon.getEggMoves();
if (eggMoves) { if (eggMoves) {
const eggMoveIndex = randSeedInt(4); const eggMoveIndex = randSeedInt(4);
const randomEggMove: Moves = eggMoves[eggMoveIndex]; const randomEggMove: MoveId = eggMoves[eggMoveIndex];
encounter.misc = { encounter.misc = {
eggMove: randomEggMove, eggMove: randomEggMove,
pokemon: pokemon, pokemon: pokemon,
@ -270,10 +270,10 @@ export const UncommonBreedEncounter: MysteryEncounter = MysteryEncounterBuilder.
) )
.build(); .build();
function givePokemonExtraEggMove(pokemon: EnemyPokemon, previousEggMove: Moves) { function givePokemonExtraEggMove(pokemon: EnemyPokemon, previousEggMove: MoveId) {
const eggMoves = pokemon.getEggMoves(); const eggMoves = pokemon.getEggMoves();
if (eggMoves) { if (eggMoves) {
let randomEggMove: Moves = eggMoves[randSeedInt(4)]; let randomEggMove: MoveId = eggMoves[randSeedInt(4)];
while (randomEggMove === previousEggMove) { while (randomEggMove === previousEggMove) {
randomEggMove = eggMoves[randSeedInt(4)]; randomEggMove = eggMoves[randSeedInt(4)];
} }

View File

@ -1,5 +1,5 @@
import type { OptionTextDisplay } from "#app/data/mystery-encounters/mystery-encounter-dialogue"; import type { OptionTextDisplay } from "#app/data/mystery-encounters/mystery-encounter-dialogue";
import type { Moves } from "#app/enums/moves"; import type { MoveId } from "#app/enums/moves";
import type { PlayerPokemon } from "#app/field/pokemon"; import type { PlayerPokemon } from "#app/field/pokemon";
import type Pokemon from "#app/field/pokemon"; import type Pokemon from "#app/field/pokemon";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
@ -300,7 +300,7 @@ export class MysteryEncounterOptionBuilder implements Partial<IMysteryEncounterO
* @param options see {@linkcode CanLearnMoveRequirementOptions} * @param options see {@linkcode CanLearnMoveRequirementOptions}
* @returns * @returns
*/ */
withPokemonCanLearnMoveRequirement(move: Moves | Moves[], options?: CanLearnMoveRequirementOptions) { withPokemonCanLearnMoveRequirement(move: MoveId | MoveId[], options?: CanLearnMoveRequirementOptions) {
return this.withPrimaryPokemonRequirement(new CanLearnMoveRequirement(move, options)); return this.withPrimaryPokemonRequirement(new CanLearnMoveRequirement(move, options));
} }

View File

@ -11,7 +11,7 @@ import { AttackTypeBoosterModifier } from "#app/modifier/modifier";
import type { AttackTypeBoosterModifierType } from "#app/modifier/modifier-type"; import type { AttackTypeBoosterModifierType } from "#app/modifier/modifier-type";
import { isNullOrUndefined } from "#app/utils/common"; import { isNullOrUndefined } from "#app/utils/common";
import type { AbilityId } from "#enums/ability-id"; import type { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import type { MysteryEncounterType } from "#enums/mystery-encounter-type"; import type { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { SpeciesFormKey } from "#enums/species-form-key"; import { SpeciesFormKey } from "#enums/species-form-key";
@ -549,12 +549,17 @@ export class TypeRequirement extends EncounterPokemonRequirement {
} }
export class MoveRequirement extends EncounterPokemonRequirement { export class MoveRequirement extends EncounterPokemonRequirement {
requiredMoves: Moves[] = []; requiredMoves: MoveId[] = [];
minNumberOfPokemon: number; minNumberOfPokemon: number;
invertQuery: boolean; invertQuery: boolean;
excludeDisallowedPokemon: boolean; excludeDisallowedPokemon: boolean;
constructor(moves: Moves | Moves[], excludeDisallowedPokemon: boolean, minNumberOfPokemon = 1, invertQuery = false) { constructor(
moves: MoveId | MoveId[],
excludeDisallowedPokemon: boolean,
minNumberOfPokemon = 1,
invertQuery = false,
) {
super(); super();
this.excludeDisallowedPokemon = excludeDisallowedPokemon; this.excludeDisallowedPokemon = excludeDisallowedPokemon;
this.minNumberOfPokemon = minNumberOfPokemon; this.minNumberOfPokemon = minNumberOfPokemon;
@ -602,11 +607,11 @@ export class MoveRequirement extends EncounterPokemonRequirement {
* NOTE: If the Pokemon already knows the move, this requirement will fail, since it's not technically learnable. * NOTE: If the Pokemon already knows the move, this requirement will fail, since it's not technically learnable.
*/ */
export class CompatibleMoveRequirement extends EncounterPokemonRequirement { export class CompatibleMoveRequirement extends EncounterPokemonRequirement {
requiredMoves: Moves[]; requiredMoves: MoveId[];
minNumberOfPokemon: number; minNumberOfPokemon: number;
invertQuery: boolean; invertQuery: boolean;
constructor(learnableMove: Moves | Moves[], minNumberOfPokemon = 1, invertQuery = false) { constructor(learnableMove: MoveId | MoveId[], minNumberOfPokemon = 1, invertQuery = false) {
super(); super();
this.minNumberOfPokemon = minNumberOfPokemon; this.minNumberOfPokemon = minNumberOfPokemon;
this.invertQuery = invertQuery; this.invertQuery = invertQuery;
@ -644,7 +649,7 @@ export class CompatibleMoveRequirement extends EncounterPokemonRequirement {
pokemon?.compatibleTms.filter(tm => !pokemon.moveset.find(m => m.moveId === tm)).includes(reqMove), pokemon?.compatibleTms.filter(tm => !pokemon.moveset.find(m => m.moveId === tm)).includes(reqMove),
); );
if (includedCompatMoves.length > 0) { if (includedCompatMoves.length > 0) {
return ["compatibleMove", Moves[includedCompatMoves[0]]]; return ["compatibleMove", MoveId[includedCompatMoves[0]]];
} }
return ["compatibleMove", ""]; return ["compatibleMove", ""];
} }

View File

@ -1,4 +1,4 @@
import type { Moves } from "#app/enums/moves"; import type { MoveId } from "#app/enums/moves";
import type { PlayerPokemon } from "#app/field/pokemon"; import type { PlayerPokemon } from "#app/field/pokemon";
import { PokemonMove } from "#app/field/pokemon"; import { PokemonMove } from "#app/field/pokemon";
import { isNullOrUndefined } from "#app/utils/common"; import { isNullOrUndefined } from "#app/utils/common";
@ -21,13 +21,13 @@ export interface CanLearnMoveRequirementOptions {
* Requires that a pokemon can learn a specific move/moveset. * Requires that a pokemon can learn a specific move/moveset.
*/ */
export class CanLearnMoveRequirement extends EncounterPokemonRequirement { export class CanLearnMoveRequirement extends EncounterPokemonRequirement {
private readonly requiredMoves: Moves[]; private readonly requiredMoves: MoveId[];
private readonly excludeLevelMoves?: boolean; private readonly excludeLevelMoves?: boolean;
private readonly excludeTmMoves?: boolean; private readonly excludeTmMoves?: boolean;
private readonly excludeEggMoves?: boolean; private readonly excludeEggMoves?: boolean;
private readonly includeFainted?: boolean; private readonly includeFainted?: boolean;
constructor(requiredMoves: Moves | Moves[], options: CanLearnMoveRequirementOptions = {}) { constructor(requiredMoves: MoveId | MoveId[], options: CanLearnMoveRequirementOptions = {}) {
super(); super();
this.requiredMoves = Array.isArray(requiredMoves) ? requiredMoves : [requiredMoves]; this.requiredMoves = Array.isArray(requiredMoves) ? requiredMoves : [requiredMoves];
@ -69,12 +69,12 @@ export class CanLearnMoveRequirement extends EncounterPokemonRequirement {
return ["requiredMoves", this.requiredMoves.map(m => new PokemonMove(m).getName()).join(", ")]; return ["requiredMoves", this.requiredMoves.map(m => new PokemonMove(m).getName()).join(", ")];
} }
private getPokemonLevelMoves(pkm: PlayerPokemon): Moves[] { private getPokemonLevelMoves(pkm: PlayerPokemon): MoveId[] {
return pkm.getLevelMoves().map(([_level, move]) => move); return pkm.getLevelMoves().map(([_level, move]) => move);
} }
private getAllPokemonMoves(pkm: PlayerPokemon): Moves[] { private getAllPokemonMoves(pkm: PlayerPokemon): MoveId[] {
const allPokemonMoves: Moves[] = []; const allPokemonMoves: MoveId[] = [];
if (!this.excludeLevelMoves) { if (!this.excludeLevelMoves) {
allPokemonMoves.push(...(this.getPokemonLevelMoves(pkm) ?? [])); allPokemonMoves.push(...(this.getPokemonLevelMoves(pkm) ?? []));

View File

@ -1,104 +1,111 @@
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
/** /**
* Moves that "steal" things * Moves that "steal" things
*/ */
export const STEALING_MOVES = [Moves.PLUCK, Moves.COVET, Moves.KNOCK_OFF, Moves.THIEF, Moves.TRICK, Moves.SWITCHEROO]; export const STEALING_MOVES = [
MoveId.PLUCK,
MoveId.COVET,
MoveId.KNOCK_OFF,
MoveId.THIEF,
MoveId.TRICK,
MoveId.SWITCHEROO,
];
/** /**
* Moves that "charm" someone * Moves that "charm" someone
*/ */
export const CHARMING_MOVES = [ export const CHARMING_MOVES = [
Moves.CHARM, MoveId.CHARM,
Moves.FLATTER, MoveId.FLATTER,
Moves.DRAGON_CHEER, MoveId.DRAGON_CHEER,
Moves.ALLURING_VOICE, MoveId.ALLURING_VOICE,
Moves.ATTRACT, MoveId.ATTRACT,
Moves.SWEET_SCENT, MoveId.SWEET_SCENT,
Moves.CAPTIVATE, MoveId.CAPTIVATE,
Moves.AROMATIC_MIST, MoveId.AROMATIC_MIST,
]; ];
/** /**
* Moves for the Dancer ability * Moves for the Dancer ability
*/ */
export const DANCING_MOVES = [ export const DANCING_MOVES = [
Moves.AQUA_STEP, MoveId.AQUA_STEP,
Moves.CLANGOROUS_SOUL, MoveId.CLANGOROUS_SOUL,
Moves.DRAGON_DANCE, MoveId.DRAGON_DANCE,
Moves.FEATHER_DANCE, MoveId.FEATHER_DANCE,
Moves.FIERY_DANCE, MoveId.FIERY_DANCE,
Moves.LUNAR_DANCE, MoveId.LUNAR_DANCE,
Moves.PETAL_DANCE, MoveId.PETAL_DANCE,
Moves.REVELATION_DANCE, MoveId.REVELATION_DANCE,
Moves.QUIVER_DANCE, MoveId.QUIVER_DANCE,
Moves.SWORDS_DANCE, MoveId.SWORDS_DANCE,
Moves.TEETER_DANCE, MoveId.TEETER_DANCE,
Moves.VICTORY_DANCE, MoveId.VICTORY_DANCE,
]; ];
/** /**
* Moves that can distract someone/something * Moves that can distract someone/something
*/ */
export const DISTRACTION_MOVES = [ export const DISTRACTION_MOVES = [
Moves.FAKE_OUT, MoveId.FAKE_OUT,
Moves.FOLLOW_ME, MoveId.FOLLOW_ME,
Moves.TAUNT, MoveId.TAUNT,
Moves.ROAR, MoveId.ROAR,
Moves.TELEPORT, MoveId.TELEPORT,
Moves.CHARM, MoveId.CHARM,
Moves.FAKE_TEARS, MoveId.FAKE_TEARS,
Moves.TICKLE, MoveId.TICKLE,
Moves.CAPTIVATE, MoveId.CAPTIVATE,
Moves.RAGE_POWDER, MoveId.RAGE_POWDER,
Moves.SUBSTITUTE, MoveId.SUBSTITUTE,
Moves.SHED_TAIL, MoveId.SHED_TAIL,
]; ];
/** /**
* Moves that protect in some way * Moves that protect in some way
*/ */
export const PROTECTING_MOVES = [ export const PROTECTING_MOVES = [
Moves.PROTECT, MoveId.PROTECT,
Moves.WIDE_GUARD, MoveId.WIDE_GUARD,
Moves.MAX_GUARD, MoveId.MAX_GUARD,
Moves.SAFEGUARD, MoveId.SAFEGUARD,
Moves.REFLECT, MoveId.REFLECT,
Moves.BARRIER, MoveId.BARRIER,
Moves.QUICK_GUARD, MoveId.QUICK_GUARD,
Moves.FLOWER_SHIELD, MoveId.FLOWER_SHIELD,
Moves.KINGS_SHIELD, MoveId.KINGS_SHIELD,
Moves.CRAFTY_SHIELD, MoveId.CRAFTY_SHIELD,
Moves.SPIKY_SHIELD, MoveId.SPIKY_SHIELD,
Moves.OBSTRUCT, MoveId.OBSTRUCT,
Moves.DETECT, MoveId.DETECT,
]; ];
/** /**
* Moves that (loosely) can be used to trap/rob someone * Moves that (loosely) can be used to trap/rob someone
*/ */
export const EXTORTION_MOVES = [ export const EXTORTION_MOVES = [
Moves.BIND, MoveId.BIND,
Moves.CLAMP, MoveId.CLAMP,
Moves.INFESTATION, MoveId.INFESTATION,
Moves.SAND_TOMB, MoveId.SAND_TOMB,
Moves.SNAP_TRAP, MoveId.SNAP_TRAP,
Moves.THUNDER_CAGE, MoveId.THUNDER_CAGE,
Moves.WRAP, MoveId.WRAP,
Moves.SPIRIT_SHACKLE, MoveId.SPIRIT_SHACKLE,
Moves.MEAN_LOOK, MoveId.MEAN_LOOK,
Moves.JAW_LOCK, MoveId.JAW_LOCK,
Moves.BLOCK, MoveId.BLOCK,
Moves.SPIDER_WEB, MoveId.SPIDER_WEB,
Moves.ANCHOR_SHOT, MoveId.ANCHOR_SHOT,
Moves.OCTOLOCK, MoveId.OCTOLOCK,
Moves.PURSUIT, MoveId.PURSUIT,
Moves.CONSTRICT, MoveId.CONSTRICT,
Moves.BEAT_UP, MoveId.BEAT_UP,
Moves.COIL, MoveId.COIL,
Moves.WRING_OUT, MoveId.WRING_OUT,
Moves.STRING_SHOT, MoveId.STRING_SHOT,
]; ];
/** /**

View File

@ -39,7 +39,7 @@ import i18next from "i18next";
import Trainer, { TrainerVariant } from "#app/field/trainer"; import Trainer, { TrainerVariant } from "#app/field/trainer";
import type { Gender } from "#app/data/gender"; import type { Gender } from "#app/data/gender";
import type { Nature } from "#enums/nature"; import type { Nature } from "#enums/nature";
import type { Moves } from "#enums/moves"; import type { MoveId } from "#enums/moves";
import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims"; import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims";
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode"; import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
import { Status } from "#app/data/status-effect"; import { Status } from "#app/data/status-effect";
@ -106,7 +106,7 @@ export interface EnemyPokemonConfig {
level?: number; level?: number;
gender?: Gender; gender?: Gender;
passive?: boolean; passive?: boolean;
moveSet?: Moves[]; moveSet?: MoveId[];
nature?: Nature; nature?: Nature;
ivs?: [number, number, number, number, number, number]; ivs?: [number, number, number, number, number, number];
shiny?: boolean; shiny?: boolean;
@ -460,7 +460,7 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig):
* This promise does not need to be awaited on if called in an encounter onInit (will just load lazily) * This promise does not need to be awaited on if called in an encounter onInit (will just load lazily)
* @param moves * @param moves
*/ */
export function loadCustomMovesForEncounter(moves: Moves | Moves[]) { export function loadCustomMovesForEncounter(moves: MoveId | MoveId[]) {
moves = Array.isArray(moves) ? moves : [moves]; moves = Array.isArray(moves) ? moves : [moves];
return Promise.all(moves.map(move => initMoveAnim(move))).then(() => loadMoveAnimAssets(moves)); return Promise.all(moves.map(move => initMoveAnim(move))).then(() => loadMoveAnimAssets(moves));
} }

View File

@ -5,7 +5,7 @@ import { allMoves } from "./data-lists";
import { MoveCategory } from "#enums/MoveCategory"; import { MoveCategory } from "#enums/MoveCategory";
import type { Constructor, nil } from "#app/utils/common"; import type { Constructor, nil } from "#app/utils/common";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import type { TimeOfDay } from "#enums/time-of-day"; import type { TimeOfDay } from "#enums/time-of-day";
import { getPokemonNameWithAffix } from "#app/messages"; import { getPokemonNameWithAffix } from "#app/messages";
@ -341,14 +341,14 @@ export class SpeciesFormChangeStatusEffectTrigger extends SpeciesFormChangeTrigg
} }
export class SpeciesFormChangeMoveLearnedTrigger extends SpeciesFormChangeTrigger { export class SpeciesFormChangeMoveLearnedTrigger extends SpeciesFormChangeTrigger {
public move: Moves; public move: MoveId;
public known: boolean; public known: boolean;
constructor(move: Moves, known = true) { constructor(move: MoveId, known = true) {
super(); super();
this.move = move; this.move = move;
this.known = known; this.known = known;
const moveKey = Moves[this.move] const moveKey = MoveId[this.move]
.split("_") .split("_")
.filter(f => f) .filter(f => f)
.map((f, i) => (i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase())) .map((f, i) => (i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()))
@ -368,12 +368,12 @@ export class SpeciesFormChangeMoveLearnedTrigger extends SpeciesFormChangeTrigge
} }
export abstract class SpeciesFormChangeMoveTrigger extends SpeciesFormChangeTrigger { export abstract class SpeciesFormChangeMoveTrigger extends SpeciesFormChangeTrigger {
public movePredicate: (m: Moves) => boolean; public movePredicate: (m: MoveId) => boolean;
public used: boolean; public used: boolean;
constructor(move: Moves | ((m: Moves) => boolean), used = true) { constructor(move: MoveId | ((m: MoveId) => boolean), used = true) {
super(); super();
this.movePredicate = typeof move === "function" ? move : (m: Moves) => m === move; this.movePredicate = typeof move === "function" ? move : (m: MoveId) => m === move;
this.used = used; this.used = used;
} }
} }
@ -827,12 +827,12 @@ export const pokemonFormChanges: PokemonFormChanges = {
new SpeciesFormChange(Species.KYUREM, "", "white", new SpeciesFormChangeItemTrigger(FormChangeItem.LIGHT_STONE), false, getSpeciesDependentFormChangeCondition(Species.RESHIRAM)) new SpeciesFormChange(Species.KYUREM, "", "white", new SpeciesFormChangeItemTrigger(FormChangeItem.LIGHT_STONE), false, getSpeciesDependentFormChangeCondition(Species.RESHIRAM))
], ],
[Species.KELDEO]: [ [Species.KELDEO]: [
new SpeciesFormChange(Species.KELDEO, "ordinary", "resolute", new SpeciesFormChangeMoveLearnedTrigger(Moves.SECRET_SWORD), false, new SpeciesFormChangeCondition(() => globalScene.gameMode.isDaily !== true)), new SpeciesFormChange(Species.KELDEO, "ordinary", "resolute", new SpeciesFormChangeMoveLearnedTrigger(MoveId.SECRET_SWORD), false, new SpeciesFormChangeCondition(() => globalScene.gameMode.isDaily !== true)),
new SpeciesFormChange(Species.KELDEO, "resolute", "ordinary", new SpeciesFormChangeMoveLearnedTrigger(Moves.SECRET_SWORD, false), false, new SpeciesFormChangeCondition(() => globalScene.gameMode.isDaily !== true)) new SpeciesFormChange(Species.KELDEO, "resolute", "ordinary", new SpeciesFormChangeMoveLearnedTrigger(MoveId.SECRET_SWORD, false), false, new SpeciesFormChangeCondition(() => globalScene.gameMode.isDaily !== true))
], ],
[Species.MELOETTA]: [ [Species.MELOETTA]: [
new SpeciesFormChange(Species.MELOETTA, "aria", "pirouette", new MeloettaFormChangePostMoveTrigger(Moves.RELIC_SONG), true), new SpeciesFormChange(Species.MELOETTA, "aria", "pirouette", new MeloettaFormChangePostMoveTrigger(MoveId.RELIC_SONG), true),
new SpeciesFormChange(Species.MELOETTA, "pirouette", "aria", new MeloettaFormChangePostMoveTrigger(Moves.RELIC_SONG), true) new SpeciesFormChange(Species.MELOETTA, "pirouette", "aria", new MeloettaFormChangePostMoveTrigger(MoveId.RELIC_SONG), true)
], ],
[Species.GENESECT]: [ [Species.GENESECT]: [
new SpeciesFormChange(Species.GENESECT, "", "shock", new SpeciesFormChangeItemTrigger(FormChangeItem.SHOCK_DRIVE)), new SpeciesFormChange(Species.GENESECT, "", "shock", new SpeciesFormChangeItemTrigger(FormChangeItem.SHOCK_DRIVE)),
@ -849,7 +849,7 @@ export const pokemonFormChanges: PokemonFormChanges = {
new SpeciesFormChange(Species.PALAFIN, "hero", "zero", new SpeciesFormChangeAbilityTrigger(), true) new SpeciesFormChange(Species.PALAFIN, "hero", "zero", new SpeciesFormChangeAbilityTrigger(), true)
], ],
[Species.AEGISLASH]: [ [Species.AEGISLASH]: [
new SpeciesFormChange(Species.AEGISLASH, "blade", "shield", new SpeciesFormChangePreMoveTrigger(Moves.KINGS_SHIELD), true, new SpeciesFormChangeCondition(p => p.hasAbility(AbilityId.STANCE_CHANGE))), new SpeciesFormChange(Species.AEGISLASH, "blade", "shield", new SpeciesFormChangePreMoveTrigger(MoveId.KINGS_SHIELD), true, new SpeciesFormChangeCondition(p => p.hasAbility(AbilityId.STANCE_CHANGE))),
new SpeciesFormChange(Species.AEGISLASH, "shield", "blade", new SpeciesFormChangePreMoveTrigger(m => allMoves[m].category !== MoveCategory.STATUS), true, new SpeciesFormChangeCondition(p => p.hasAbility(AbilityId.STANCE_CHANGE))), new SpeciesFormChange(Species.AEGISLASH, "shield", "blade", new SpeciesFormChangePreMoveTrigger(m => allMoves[m].category !== MoveCategory.STATUS), true, new SpeciesFormChangeCondition(p => p.hasAbility(AbilityId.STANCE_CHANGE))),
new SpeciesFormChange(Species.AEGISLASH, "blade", "shield", new SpeciesFormChangeActiveTrigger(false), true) new SpeciesFormChange(Species.AEGISLASH, "blade", "shield", new SpeciesFormChangeActiveTrigger(false), true)
], ],

View File

@ -26,7 +26,7 @@ import { PartyMemberStrength } from "#enums/party-member-strength";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { PokeballType } from "#enums/pokeball"; import { PokeballType } from "#enums/pokeball";
import { PokemonType } from "#enums/pokemon-type"; import { PokemonType } from "#enums/pokemon-type";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { TeraAIMode } from "#enums/tera-ai-mode"; import { TeraAIMode } from "#enums/tera-ai-mode";
import { TrainerPoolTier } from "#enums/trainer-pool-tier"; import { TrainerPoolTier } from "#enums/trainer-pool-tier";
@ -1127,7 +1127,7 @@ export const trainerConfigs: TrainerConfigs = {
s s
.getLevelMoves() .getLevelMoves()
.some(plm => .some(plm =>
[Moves.SOFT_BOILED, Moves.SPORE, Moves.MILK_DRINK, Moves.OVERHEAT, Moves.TEATIME].includes(plm[1]), [MoveId.SOFT_BOILED, MoveId.SPORE, MoveId.MILK_DRINK, MoveId.OVERHEAT, MoveId.TEATIME].includes(plm[1]),
), ),
), // Mons with baking related abilities or who learn Overheat, Teatime, Milk Drink, Spore, or Soft-Boiled by level ), // Mons with baking related abilities or who learn Overheat, Teatime, Milk Drink, Spore, or Soft-Boiled by level
[TrainerType.BEAUTY]: new TrainerConfig(++t) [TrainerType.BEAUTY]: new TrainerConfig(++t)
@ -1333,11 +1333,11 @@ export const trainerConfigs: TrainerConfigs = {
.setHasDouble("Medical Team") .setHasDouble("Medical Team")
.setMoneyMultiplier(3) .setMoneyMultiplier(3)
.setEncounterBgm(TrainerType.CLERK) .setEncounterBgm(TrainerType.CLERK)
.setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === Moves.HEAL_PULSE)), .setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === MoveId.HEAL_PULSE)),
[TrainerType.FIREBREATHER]: new TrainerConfig(++t) [TrainerType.FIREBREATHER]: new TrainerConfig(++t)
.setMoneyMultiplier(1.4) .setMoneyMultiplier(1.4)
.setEncounterBgm(TrainerType.ROUGHNECK) .setEncounterBgm(TrainerType.ROUGHNECK)
.setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === Moves.SMOG) || s.isOfType(PokemonType.FIRE)), .setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === MoveId.SMOG) || s.isOfType(PokemonType.FIRE)),
[TrainerType.FISHERMAN]: new TrainerConfig(++t) [TrainerType.FISHERMAN]: new TrainerConfig(++t)
.setMoneyMultiplier(1.25) .setMoneyMultiplier(1.25)
.setEncounterBgm(TrainerType.BACKPACKER) .setEncounterBgm(TrainerType.BACKPACKER)
@ -1394,7 +1394,7 @@ export const trainerConfigs: TrainerConfigs = {
.setSpeciesFilter(s => s.isOfType(PokemonType.ELECTRIC)), .setSpeciesFilter(s => s.isOfType(PokemonType.ELECTRIC)),
[TrainerType.HARLEQUIN]: new TrainerConfig(++t) [TrainerType.HARLEQUIN]: new TrainerConfig(++t)
.setEncounterBgm(TrainerType.PSYCHIC) .setEncounterBgm(TrainerType.PSYCHIC)
.setSpeciesFilter(s => tmSpecies[Moves.TRICK_ROOM].indexOf(s.speciesId) > -1), .setSpeciesFilter(s => tmSpecies[MoveId.TRICK_ROOM].indexOf(s.speciesId) > -1),
[TrainerType.HIKER]: new TrainerConfig(++t) [TrainerType.HIKER]: new TrainerConfig(++t)
.setEncounterBgm(TrainerType.BACKPACKER) .setEncounterBgm(TrainerType.BACKPACKER)
.setPartyTemplates( .setPartyTemplates(
@ -1466,7 +1466,7 @@ export const trainerConfigs: TrainerConfigs = {
trainerPartyTemplates.TWO_WEAK_ONE_AVG, trainerPartyTemplates.TWO_WEAK_ONE_AVG,
trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_AVG,
) )
.setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === Moves.SING)), .setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === MoveId.SING)),
[TrainerType.HEX_MANIAC]: new TrainerConfig(++t) [TrainerType.HEX_MANIAC]: new TrainerConfig(++t)
.setMoneyMultiplier(1.5) .setMoneyMultiplier(1.5)
.setEncounterBgm(TrainerType.PSYCHIC) .setEncounterBgm(TrainerType.PSYCHIC)
@ -1527,7 +1527,7 @@ export const trainerConfigs: TrainerConfigs = {
AbilityId.DRY_SKIN, AbilityId.DRY_SKIN,
AbilityId.WIND_POWER, AbilityId.WIND_POWER,
].includes(a), ].includes(a),
) || s.getLevelMoves().some(plm => plm[1] === Moves.RAIN_DANCE), ) || s.getLevelMoves().some(plm => plm[1] === MoveId.RAIN_DANCE),
), // Mons with rain abilities or who learn Rain Dance by level ), // Mons with rain abilities or who learn Rain Dance by level
[TrainerType.PILOT]: new TrainerConfig(++t) [TrainerType.PILOT]: new TrainerConfig(++t)
.setMoneyMultiplier(1.75) .setMoneyMultiplier(1.75)
@ -1538,7 +1538,7 @@ export const trainerConfigs: TrainerConfigs = {
trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.TWO_AVG,
trainerPartyTemplates.THREE_AVG, trainerPartyTemplates.THREE_AVG,
) )
.setSpeciesFilter(s => tmSpecies[Moves.FLY].indexOf(s.speciesId) > -1), .setSpeciesFilter(s => tmSpecies[MoveId.FLY].indexOf(s.speciesId) > -1),
[TrainerType.POKEFAN]: new TrainerConfig(++t) [TrainerType.POKEFAN]: new TrainerConfig(++t)
.setMoneyMultiplier(1.4) .setMoneyMultiplier(1.4)
.setName("PokéFan") .setName("PokéFan")
@ -1554,7 +1554,7 @@ export const trainerConfigs: TrainerConfigs = {
trainerPartyTemplates.FIVE_WEAK, trainerPartyTemplates.FIVE_WEAK,
trainerPartyTemplates.SIX_WEAKER_SAME, trainerPartyTemplates.SIX_WEAKER_SAME,
) )
.setSpeciesFilter(s => tmSpecies[Moves.HELPING_HAND].indexOf(s.speciesId) > -1), .setSpeciesFilter(s => tmSpecies[MoveId.HELPING_HAND].indexOf(s.speciesId) > -1),
[TrainerType.PRESCHOOLER]: new TrainerConfig(++t) [TrainerType.PRESCHOOLER]: new TrainerConfig(++t)
.setMoneyMultiplier(0.2) .setMoneyMultiplier(0.2)
.setEncounterBgm(TrainerType.YOUNGSTER) .setEncounterBgm(TrainerType.YOUNGSTER)
@ -2490,10 +2490,10 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.REVAVROOM], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.REVAVROOM], TrainerSlot.TRAINER, true, p => {
p.formIndex = 1; // Segin Starmobile p.formIndex = 1; // Segin Starmobile
p.moveset = [ p.moveset = [
new PokemonMove(Moves.WICKED_TORQUE), new PokemonMove(MoveId.WICKED_TORQUE),
new PokemonMove(Moves.SPIN_OUT), new PokemonMove(MoveId.SPIN_OUT),
new PokemonMove(Moves.SHIFT_GEAR), new PokemonMove(MoveId.SHIFT_GEAR),
new PokemonMove(Moves.HIGH_HORSEPOWER), new PokemonMove(MoveId.HIGH_HORSEPOWER),
]; ];
}), }),
), ),
@ -2510,10 +2510,10 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.REVAVROOM], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.REVAVROOM], TrainerSlot.TRAINER, true, p => {
p.formIndex = 2; // Schedar Starmobile p.formIndex = 2; // Schedar Starmobile
p.moveset = [ p.moveset = [
new PokemonMove(Moves.BLAZING_TORQUE), new PokemonMove(MoveId.BLAZING_TORQUE),
new PokemonMove(Moves.SPIN_OUT), new PokemonMove(MoveId.SPIN_OUT),
new PokemonMove(Moves.SHIFT_GEAR), new PokemonMove(MoveId.SHIFT_GEAR),
new PokemonMove(Moves.HIGH_HORSEPOWER), new PokemonMove(MoveId.HIGH_HORSEPOWER),
]; ];
}), }),
), ),
@ -2530,10 +2530,10 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.REVAVROOM], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.REVAVROOM], TrainerSlot.TRAINER, true, p => {
p.formIndex = 3; // Navi Starmobile p.formIndex = 3; // Navi Starmobile
p.moveset = [ p.moveset = [
new PokemonMove(Moves.NOXIOUS_TORQUE), new PokemonMove(MoveId.NOXIOUS_TORQUE),
new PokemonMove(Moves.SPIN_OUT), new PokemonMove(MoveId.SPIN_OUT),
new PokemonMove(Moves.SHIFT_GEAR), new PokemonMove(MoveId.SHIFT_GEAR),
new PokemonMove(Moves.HIGH_HORSEPOWER), new PokemonMove(MoveId.HIGH_HORSEPOWER),
]; ];
}), }),
), ),
@ -2550,10 +2550,10 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.REVAVROOM], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.REVAVROOM], TrainerSlot.TRAINER, true, p => {
p.formIndex = 4; // Ruchbah Starmobile p.formIndex = 4; // Ruchbah Starmobile
p.moveset = [ p.moveset = [
new PokemonMove(Moves.MAGICAL_TORQUE), new PokemonMove(MoveId.MAGICAL_TORQUE),
new PokemonMove(Moves.SPIN_OUT), new PokemonMove(MoveId.SPIN_OUT),
new PokemonMove(Moves.SHIFT_GEAR), new PokemonMove(MoveId.SHIFT_GEAR),
new PokemonMove(Moves.HIGH_HORSEPOWER), new PokemonMove(MoveId.HIGH_HORSEPOWER),
]; ];
}), }),
), ),
@ -2570,10 +2570,10 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.REVAVROOM], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.REVAVROOM], TrainerSlot.TRAINER, true, p => {
p.formIndex = 5; // Caph Starmobile p.formIndex = 5; // Caph Starmobile
p.moveset = [ p.moveset = [
new PokemonMove(Moves.COMBAT_TORQUE), new PokemonMove(MoveId.COMBAT_TORQUE),
new PokemonMove(Moves.SPIN_OUT), new PokemonMove(MoveId.SPIN_OUT),
new PokemonMove(Moves.SHIFT_GEAR), new PokemonMove(MoveId.SHIFT_GEAR),
new PokemonMove(Moves.HIGH_HORSEPOWER), new PokemonMove(MoveId.HIGH_HORSEPOWER),
]; ];
}), }),
), ),
@ -2868,9 +2868,9 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.SLOWBRO, Species.GALAR_SLOWBRO], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.SLOWBRO, Species.GALAR_SLOWBRO], TrainerSlot.TRAINER, true, p => {
// Tera Ice Slowbro/G-Slowbro // Tera Ice Slowbro/G-Slowbro
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.ICE_BEAM)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.ICE_BEAM)) {
// Check if Ice Beam is in the moveset, if not, replace the third move with Ice Beam. // Check if Ice Beam is in the moveset, if not, replace the third move with Ice Beam.
p.moveset[2] = new PokemonMove(Moves.ICE_BEAM); p.moveset[2] = new PokemonMove(MoveId.ICE_BEAM);
} }
}), }),
) )
@ -2893,9 +2893,9 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.STEELIX], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.STEELIX], TrainerSlot.TRAINER, true, p => {
// Tera Fighting Steelix // Tera Fighting Steelix
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.BODY_PRESS)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.BODY_PRESS)) {
// Check if Body Press is in the moveset, if not, replace the third move with Body Press. // Check if Body Press is in the moveset, if not, replace the third move with Body Press.
p.moveset[2] = new PokemonMove(Moves.BODY_PRESS); p.moveset[2] = new PokemonMove(MoveId.BODY_PRESS);
} }
}), }),
) )
@ -2918,9 +2918,9 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.ARBOK, Species.WEEZING], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.ARBOK, Species.WEEZING], TrainerSlot.TRAINER, true, p => {
// Tera Ghost Arbok/Weezing // Tera Ghost Arbok/Weezing
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.TERA_BLAST)) {
// Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast.
p.moveset[2] = new PokemonMove(Moves.TERA_BLAST); p.moveset[2] = new PokemonMove(MoveId.TERA_BLAST);
} }
}), }),
) )
@ -2944,9 +2944,9 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.GYARADOS, Species.AERODACTYL], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.GYARADOS, Species.AERODACTYL], TrainerSlot.TRAINER, true, p => {
// Tera Dragon Gyarados/Aerodactyl // Tera Dragon Gyarados/Aerodactyl
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.TERA_BLAST)) {
// Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast.
p.moveset[2] = new PokemonMove(Moves.TERA_BLAST); p.moveset[2] = new PokemonMove(MoveId.TERA_BLAST);
} }
}), }),
) )
@ -3005,9 +3005,9 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.GENGAR], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.GENGAR], TrainerSlot.TRAINER, true, p => {
// Tera Dark Gengar // Tera Dark Gengar
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.DARK_PULSE)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.DARK_PULSE)) {
// Check if Dark Pulse is in the moveset, if not, replace the third move with Dark Pulse. // Check if Dark Pulse is in the moveset, if not, replace the third move with Dark Pulse.
p.moveset[2] = new PokemonMove(Moves.DARK_PULSE); p.moveset[2] = new PokemonMove(MoveId.DARK_PULSE);
} }
}), }),
) )
@ -3089,9 +3089,9 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.DHELMISE], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.DHELMISE], TrainerSlot.TRAINER, true, p => {
// Tera Dragon Dhelmise // Tera Dragon Dhelmise
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.TERA_BLAST)) {
// Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast.
p.moveset[2] = new PokemonMove(Moves.TERA_BLAST); p.moveset[2] = new PokemonMove(MoveId.TERA_BLAST);
} }
}), }),
) )
@ -3119,9 +3119,9 @@ export const trainerConfigs: TrainerConfigs = {
p.setBoss(true, 2); p.setBoss(true, 2);
p.abilityIndex = 1; // Sniper p.abilityIndex = 1; // Sniper
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.X_SCISSOR)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.X_SCISSOR)) {
// Check if X-Scissor is in the moveset, if not, replace the third move with X-Scissor. // Check if X-Scissor is in the moveset, if not, replace the third move with X-Scissor.
p.moveset[2] = new PokemonMove(Moves.X_SCISSOR); p.moveset[2] = new PokemonMove(MoveId.X_SCISSOR);
} }
}), }),
), ),
@ -3158,9 +3158,9 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.STEELIX, Species.LOPUNNY], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.STEELIX, Species.LOPUNNY], TrainerSlot.TRAINER, true, p => {
// Tera Fire Steelix/Lopunny // Tera Fire Steelix/Lopunny
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.TERA_BLAST)) {
// Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast.
p.moveset[2] = new PokemonMove(Moves.TERA_BLAST); p.moveset[2] = new PokemonMove(MoveId.TERA_BLAST);
} }
}), }),
) )
@ -3301,9 +3301,9 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.CERULEDGE], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.CERULEDGE], TrainerSlot.TRAINER, true, p => {
// Tera Steel Ceruledge // Tera Steel Ceruledge
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.IRON_HEAD)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.IRON_HEAD)) {
// Check if Iron Head is in the moveset, if not, replace the third move with Iron Head. // Check if Iron Head is in the moveset, if not, replace the third move with Iron Head.
p.moveset[2] = new PokemonMove(Moves.IRON_HEAD); p.moveset[2] = new PokemonMove(MoveId.IRON_HEAD);
} }
}), }),
) )
@ -3339,9 +3339,9 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.INCINEROAR], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.INCINEROAR], TrainerSlot.TRAINER, true, p => {
// Tera Fighting Incineroar // Tera Fighting Incineroar
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.CROSS_CHOP)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.CROSS_CHOP)) {
// Check if Cross Chop is in the moveset, if not, replace the third move with Cross Chop. // Check if Cross Chop is in the moveset, if not, replace the third move with Cross Chop.
p.moveset[2] = new PokemonMove(Moves.CROSS_CHOP); p.moveset[2] = new PokemonMove(MoveId.CROSS_CHOP);
} }
}), }),
) )
@ -3412,9 +3412,9 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.DECIDUEYE], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.DECIDUEYE], TrainerSlot.TRAINER, true, p => {
// Tera Flying Decidueye // Tera Flying Decidueye
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.BRAVE_BIRD)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.BRAVE_BIRD)) {
// Check if Brave Bird is in the moveset, if not, replace the third move with Brave Bird. // Check if Brave Bird is in the moveset, if not, replace the third move with Brave Bird.
p.moveset[2] = new PokemonMove(Moves.BRAVE_BIRD); p.moveset[2] = new PokemonMove(MoveId.BRAVE_BIRD);
} }
}), }),
) )
@ -3437,9 +3437,9 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.TOXICROAK], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.TOXICROAK], TrainerSlot.TRAINER, true, p => {
// Tera Dark Toxicroak // Tera Dark Toxicroak
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.SUCKER_PUNCH)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.SUCKER_PUNCH)) {
// Check if Sucker Punch is in the moveset, if not, replace the third move with Sucker Punch. // Check if Sucker Punch is in the moveset, if not, replace the third move with Sucker Punch.
p.moveset[2] = new PokemonMove(Moves.SUCKER_PUNCH); p.moveset[2] = new PokemonMove(MoveId.SUCKER_PUNCH);
} }
}), }),
) )
@ -3462,9 +3462,9 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.EISCUE], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.EISCUE], TrainerSlot.TRAINER, true, p => {
// Tera Water Eiscue // Tera Water Eiscue
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.LIQUIDATION)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.LIQUIDATION)) {
// Check if Liquidation is in the moveset, if not, replace the third move with Liquidation. // Check if Liquidation is in the moveset, if not, replace the third move with Liquidation.
p.moveset[2] = new PokemonMove(Moves.LIQUIDATION); p.moveset[2] = new PokemonMove(MoveId.LIQUIDATION);
} }
}), }),
) )
@ -3524,9 +3524,9 @@ export const trainerConfigs: TrainerConfigs = {
// Tera Dragon Torkoal // Tera Dragon Torkoal
p.abilityIndex = 1; // Drought p.abilityIndex = 1; // Drought
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.TERA_BLAST)) {
// Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast.
p.moveset[2] = new PokemonMove(Moves.TERA_BLAST); p.moveset[2] = new PokemonMove(MoveId.TERA_BLAST);
} }
}), }),
) )
@ -3621,9 +3621,9 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.EXEGGUTOR], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.EXEGGUTOR], TrainerSlot.TRAINER, true, p => {
// Tera Fire Exeggutor // Tera Fire Exeggutor
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.TERA_BLAST)) {
// Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast.
p.moveset[2] = new PokemonMove(Moves.TERA_BLAST); p.moveset[2] = new PokemonMove(MoveId.TERA_BLAST);
} }
}), }),
) )
@ -3631,9 +3631,9 @@ export const trainerConfigs: TrainerConfigs = {
3, 3,
getRandomPartyMemberFunc([Species.TALONFLAME], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.TALONFLAME], TrainerSlot.TRAINER, true, p => {
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.SUNNY_DAY)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.SUNNY_DAY)) {
// Check if Sunny Day is in the moveset, if not, replace the third move with Sunny Day. // Check if Sunny Day is in the moveset, if not, replace the third move with Sunny Day.
p.moveset[2] = new PokemonMove(Moves.SUNNY_DAY); p.moveset[2] = new PokemonMove(MoveId.SUNNY_DAY);
} }
}), }),
) )
@ -3654,9 +3654,9 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.REUNICLUS], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.REUNICLUS], TrainerSlot.TRAINER, true, p => {
// Tera Steel Reuniclus // Tera Steel Reuniclus
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.FLASH_CANNON)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.FLASH_CANNON)) {
// Check if Flash Cannon is in the moveset, if not, replace the third move with Flash Cannon. // Check if Flash Cannon is in the moveset, if not, replace the third move with Flash Cannon.
p.moveset[2] = new PokemonMove(Moves.FLASH_CANNON); p.moveset[2] = new PokemonMove(MoveId.FLASH_CANNON);
} }
}), }),
) )
@ -3682,9 +3682,9 @@ export const trainerConfigs: TrainerConfigs = {
// Tera Fairy Excadrill // Tera Fairy Excadrill
p.setBoss(true, 2); p.setBoss(true, 2);
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.TERA_BLAST)) {
// Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast.
p.moveset[2] = new PokemonMove(Moves.TERA_BLAST); p.moveset[2] = new PokemonMove(MoveId.TERA_BLAST);
} }
}), }),
), ),
@ -3697,9 +3697,9 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.SCEPTILE], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.SCEPTILE], TrainerSlot.TRAINER, true, p => {
// Tera Dragon Sceptile // Tera Dragon Sceptile
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.DUAL_CHOP)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.DUAL_CHOP)) {
// Check if Dual Chop is in the moveset, if not, replace the third move with Dual Chop. // Check if Dual Chop is in the moveset, if not, replace the third move with Dual Chop.
p.moveset[2] = new PokemonMove(Moves.DUAL_CHOP); p.moveset[2] = new PokemonMove(MoveId.DUAL_CHOP);
} }
}), }),
) )
@ -4287,9 +4287,9 @@ export const trainerConfigs: TrainerConfigs = {
5, 5,
getRandomPartyMemberFunc([Species.KINGAMBIT], TrainerSlot.TRAINER, true, p => { getRandomPartyMemberFunc([Species.KINGAMBIT], TrainerSlot.TRAINER, true, p => {
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.TERA_BLAST)) {
// Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast.
p.moveset[2] = new PokemonMove(Moves.TERA_BLAST); p.moveset[2] = new PokemonMove(MoveId.TERA_BLAST);
} }
p.abilityIndex = 1; // Supreme Overlord p.abilityIndex = 1; // Supreme Overlord
p.teraType = PokemonType.FLYING; p.teraType = PokemonType.FLYING;
@ -4367,9 +4367,9 @@ export const trainerConfigs: TrainerConfigs = {
p.formIndex = randSeedInt(4); // Random Ogerpon Tera Mask p.formIndex = randSeedInt(4); // Random Ogerpon Tera Mask
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
p.pokeball = PokeballType.ULTRA_BALL; p.pokeball = PokeballType.ULTRA_BALL;
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.IVY_CUDGEL)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.IVY_CUDGEL)) {
// Check if Ivy Cudgel is in the moveset, if not, replace the first move with Ivy Cudgel. // Check if Ivy Cudgel is in the moveset, if not, replace the first move with Ivy Cudgel.
p.moveset[0] = new PokemonMove(Moves.IVY_CUDGEL); p.moveset[0] = new PokemonMove(MoveId.IVY_CUDGEL);
} }
}), }),
) )
@ -5419,9 +5419,9 @@ export const trainerConfigs: TrainerConfigs = {
p.formIndex = randSeedInt(18); // Random Silvally Form p.formIndex = randSeedInt(18); // Random Silvally Form
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
p.pokeball = PokeballType.ROGUE_BALL; p.pokeball = PokeballType.ROGUE_BALL;
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.MULTI_ATTACK)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.MULTI_ATTACK)) {
// Check if Multi Attack is in the moveset, if not, replace the first move with Multi Attack. // Check if Multi Attack is in the moveset, if not, replace the first move with Multi Attack.
p.moveset[0] = new PokemonMove(Moves.MULTI_ATTACK); p.moveset[0] = new PokemonMove(MoveId.MULTI_ATTACK);
} }
}), }),
) )
@ -5537,9 +5537,9 @@ export const trainerConfigs: TrainerConfigs = {
p.generateAndPopulateMoveset(); p.generateAndPopulateMoveset();
p.pokeball = PokeballType.ULTRA_BALL; p.pokeball = PokeballType.ULTRA_BALL;
p.formIndex = randSeedInt(4, 1); // Shock, Burn, Chill, or Douse Drive p.formIndex = randSeedInt(4, 1); // Shock, Burn, Chill, or Douse Drive
if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TECHNO_BLAST)) { if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === MoveId.TECHNO_BLAST)) {
// Check if Techno Blast is in the moveset, if not, replace the third move with Techno Blast. // Check if Techno Blast is in the moveset, if not, replace the third move with Techno Blast.
p.moveset[2] = new PokemonMove(Moves.TECHNO_BLAST); p.moveset[2] = new PokemonMove(MoveId.TECHNO_BLAST);
} }
}), }),
) )

View File

@ -1,4 +1,4 @@
export enum Moves { export enum MoveId {
/**{@link https://bulbapedia.bulbagarden.net/wiki/None_(move) | Source} */ /**{@link https://bulbapedia.bulbagarden.net/wiki/None_(move) | Source} */
NONE, NONE,
/**{@link https://bulbapedia.bulbagarden.net/wiki/Pound_(move) | Source} */ /**{@link https://bulbapedia.bulbagarden.net/wiki/Pound_(move) | Source} */

View File

@ -32,7 +32,7 @@ import Overrides from "#app/overrides";
import { TagAddedEvent, TagRemovedEvent, TerrainChangedEvent, WeatherChangedEvent } from "#app/events/arena"; import { TagAddedEvent, TagRemovedEvent, TerrainChangedEvent, WeatherChangedEvent } from "#app/events/arena";
import type { ArenaTagType } from "#enums/arena-tag-type"; import type { ArenaTagType } from "#enums/arena-tag-type";
import { Biome } from "#enums/biome"; import { Biome } from "#enums/biome";
import type { Moves } from "#enums/moves"; import type { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { TimeOfDay } from "#enums/time-of-day"; import { TimeOfDay } from "#enums/time-of-day";
import { TrainerType } from "#enums/trainer-type"; import { TrainerType } from "#enums/trainer-type";
@ -674,7 +674,7 @@ export class Arena {
* Adds a new tag to the arena * Adds a new tag to the arena
* @param tagType {@linkcode ArenaTagType} the tag being added * @param tagType {@linkcode ArenaTagType} the tag being added
* @param turnCount How many turns the tag lasts * @param turnCount How many turns the tag lasts
* @param sourceMove {@linkcode Moves} the move the tag came from, or `undefined` if not from a move * @param sourceMove {@linkcode MoveId} the move the tag came from, or `undefined` if not from a move
* @param sourceId The ID of the pokemon in play the tag came from (see {@linkcode BattleScene.getPokemonById}) * @param sourceId The ID of the pokemon in play the tag came from (see {@linkcode BattleScene.getPokemonById})
* @param side {@linkcode ArenaTagSide} which side(s) the tag applies to * @param side {@linkcode ArenaTagSide} which side(s) the tag applies to
* @param quiet If a message should be queued on screen to announce the tag being added * @param quiet If a message should be queued on screen to announce the tag being added
@ -684,7 +684,7 @@ export class Arena {
addTag( addTag(
tagType: ArenaTagType, tagType: ArenaTagType,
turnCount: number, turnCount: number,
sourceMove: Moves | undefined, sourceMove: MoveId | undefined,
sourceId: number, sourceId: number,
side: ArenaTagSide = ArenaTagSide.BOTH, side: ArenaTagSide = ArenaTagSide.BOTH,
quiet = false, quiet = false,

View File

@ -226,7 +226,7 @@ import { BattleSpec } from "#enums/battle-spec";
import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type";
import type { BerryType } from "#enums/berry-type"; import type { BerryType } from "#enums/berry-type";
import { Biome } from "#enums/biome"; import { Biome } from "#enums/biome";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { getPokemonNameWithAffix } from "#app/messages"; import { getPokemonNameWithAffix } from "#app/messages";
import { DamageAnimPhase } from "#app/phases/damage-anim-phase"; import { DamageAnimPhase } from "#app/phases/damage-anim-phase";
@ -381,7 +381,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
public maskEnabled: boolean; public maskEnabled: boolean;
public maskSprite: Phaser.GameObjects.Sprite | null; public maskSprite: Phaser.GameObjects.Sprite | null;
public usedTMs: Moves[]; public usedTMs: MoveId[];
private shinySparkle: Phaser.GameObjects.Sprite; private shinySparkle: Phaser.GameObjects.Sprite;
@ -1123,7 +1123,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
/** /**
* Get this {@linkcode Pokemon}'s {@linkcode PokemonSpeciesForm}. * Get this {@linkcode Pokemon}'s {@linkcode PokemonSpeciesForm}.
* @param ignoreOverride - Whether to ignore overridden species from {@linkcode Moves.TRANSFORM}, default `false`. * @param ignoreOverride - Whether to ignore overridden species from {@linkcode MoveId.TRANSFORM}, default `false`.
* This overrides `useIllusion` if `true`. * This overrides `useIllusion` if `true`.
* @param useIllusion - `true` to use the speciesForm of the illusion; default `false`. * @param useIllusion - `true` to use the speciesForm of the illusion; default `false`.
*/ */
@ -1848,7 +1848,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const ret = !ignoreOverride && this.summonData.moveset ? this.summonData.moveset : this.moveset; const ret = !ignoreOverride && this.summonData.moveset ? this.summonData.moveset : this.moveset;
// Overrides moveset based on arrays specified in overrides.ts // Overrides moveset based on arrays specified in overrides.ts
let overrideArray: Moves | Array<Moves> = this.isPlayer() let overrideArray: MoveId | Array<MoveId> = this.isPlayer()
? Overrides.MOVESET_OVERRIDE ? Overrides.MOVESET_OVERRIDE
: Overrides.OPP_MOVESET_OVERRIDE; : Overrides.OPP_MOVESET_OVERRIDE;
if (!Array.isArray(overrideArray)) { if (!Array.isArray(overrideArray)) {
@ -1858,7 +1858,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (!this.isPlayer()) { if (!this.isPlayer()) {
this.moveset = []; this.moveset = [];
} }
overrideArray.forEach((move: Moves, index: number) => { overrideArray.forEach((move: MoveId, index: number) => {
const ppUsed = this.moveset[index]?.ppUsed ?? 0; const ppUsed = this.moveset[index]?.ppUsed ?? 0;
this.moveset[index] = new PokemonMove(move, Math.min(ppUsed, allMoves[move].pp)); this.moveset[index] = new PokemonMove(move, Math.min(ppUsed, allMoves[move].pp));
}); });
@ -1871,11 +1871,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* Checks which egg moves have been unlocked for the {@linkcode Pokemon} based * Checks which egg moves have been unlocked for the {@linkcode Pokemon} based
* on the species it was met at or by the first {@linkcode Pokemon} in its evolution * on the species it was met at or by the first {@linkcode Pokemon} in its evolution
* line that can act as a starter and provides those egg moves. * line that can act as a starter and provides those egg moves.
* @returns an array of {@linkcode Moves}, the length of which is determined by how many * @returns an array of {@linkcode MoveId}, the length of which is determined by how many
* egg moves are unlocked for that species. * egg moves are unlocked for that species.
*/ */
getUnlockedEggMoves(): Moves[] { getUnlockedEggMoves(): MoveId[] {
const moves: Moves[] = []; const moves: MoveId[] = [];
const species = const species =
this.metSpecies in speciesEggMoves ? this.metSpecies : this.getSpeciesForm(true).getRootSpeciesId(true); this.metSpecies in speciesEggMoves ? this.metSpecies : this.getSpeciesForm(true).getRootSpeciesId(true);
if (species in speciesEggMoves) { if (species in speciesEggMoves) {
@ -1894,10 +1894,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* *
* Available egg moves are only included if the {@linkcode Pokemon} was * Available egg moves are only included if the {@linkcode Pokemon} was
* in the starting party of the run and if Fresh Start is not active. * in the starting party of the run and if Fresh Start is not active.
* @returns an array of {@linkcode Moves}, the length of which is determined * @returns an array of {@linkcode MoveId}, the length of which is determined
* by how many learnable moves there are for the {@linkcode Pokemon}. * by how many learnable moves there are for the {@linkcode Pokemon}.
*/ */
public getLearnableLevelMoves(): Moves[] { public getLearnableLevelMoves(): MoveId[] {
let levelMoves = this.getLevelMoves(1, true, false, true).map(lm => lm[1]); let levelMoves = this.getLevelMoves(1, true, false, true).map(lm => lm[1]);
if (this.metBiome === -1 && !globalScene.gameMode.isFreshStartChallenge() && !globalScene.gameMode.isDaily) { if (this.metBiome === -1 && !globalScene.gameMode.isFreshStartChallenge() && !globalScene.gameMode.isDaily) {
levelMoves = this.getUnlockedEggMoves().concat(levelMoves); levelMoves = this.getUnlockedEggMoves().concat(levelMoves);
@ -2382,8 +2382,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
// then bypass the check for ion deluge and electrify // then bypass the check for ion deluge and electrify
if ( if (
this.isTerastallized && this.isTerastallized &&
(move.id === Moves.TERA_BLAST || (move.id === MoveId.TERA_BLAST ||
(move.id === Moves.TERA_STARSTORM && moveTypeHolder.value === PokemonType.STELLAR)) (move.id === MoveId.TERA_STARSTORM && moveTypeHolder.value === PokemonType.STELLAR))
) { ) {
return moveTypeHolder.value as PokemonType; return moveTypeHolder.value as PokemonType;
} }
@ -2780,7 +2780,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* @param ret the output array to be pushed into. * @param ret the output array to be pushed into.
*/ */
private getUniqueMoves(levelMoves: LevelMoves, ret: LevelMoves): void { private getUniqueMoves(levelMoves: LevelMoves, ret: LevelMoves): void {
const uniqueMoves: Moves[] = []; const uniqueMoves: MoveId[] = [];
for (const lm of levelMoves) { for (const lm of levelMoves) {
if (!uniqueMoves.find(m => m === lm[1])) { if (!uniqueMoves.find(m => m === lm[1])) {
uniqueMoves.push(lm[1]); uniqueMoves.push(lm[1]);
@ -2794,12 +2794,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* *
* @returns list of egg moves * @returns list of egg moves
*/ */
getEggMoves(): Moves[] | undefined { getEggMoves(): MoveId[] | undefined {
return speciesEggMoves[this.getSpeciesForm().getRootSpeciesId()]; return speciesEggMoves[this.getSpeciesForm().getRootSpeciesId()];
} }
setMove(moveIndex: number, moveId: Moves): void { setMove(moveIndex: number, moveId: MoveId): void {
if (moveId === Moves.NONE) { if (moveId === MoveId.NONE) {
return; return;
} }
const move = new PokemonMove(moveId); const move = new PokemonMove(moveId);
@ -3050,7 +3050,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
/** Generates a semi-random moveset for a Pokemon */ /** Generates a semi-random moveset for a Pokemon */
public generateAndPopulateMoveset(): void { public generateAndPopulateMoveset(): void {
this.moveset = []; this.moveset = [];
let movePool: [Moves, number][] = []; let movePool: [MoveId, number][] = [];
const allLevelMoves = this.getLevelMoves(1, true, true); const allLevelMoves = this.getLevelMoves(1, true, true);
if (!allLevelMoves) { if (!allLevelMoves) {
console.warn("Error encountered trying to generate moveset for:", this.species.name); console.warn("Error encountered trying to generate moveset for:", this.species.name);
@ -3079,7 +3079,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (this.hasTrainer()) { if (this.hasTrainer()) {
const tms = Object.keys(tmSpecies); const tms = Object.keys(tmSpecies);
for (const tm of tms) { for (const tm of tms) {
const moveId = Number.parseInt(tm) as Moves; const moveId = Number.parseInt(tm) as MoveId;
let compatible = false; let compatible = false;
for (const p of tmSpecies[tm]) { for (const p of tmSpecies[tm]) {
if (Array.isArray(p)) { if (Array.isArray(p)) {
@ -3202,7 +3202,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (this.isBoss()) { if (this.isBoss()) {
weightMultiplier += 0.4; weightMultiplier += 0.4;
} }
const baseWeights: [Moves, number][] = movePool.map(m => [m[0], Math.ceil(Math.pow(m[1], weightMultiplier) * 100)]); const baseWeights: [MoveId, number][] = movePool.map(m => [
m[0],
Math.ceil(Math.pow(m[1], weightMultiplier) * 100),
]);
// All Pokemon force a STAB move first // All Pokemon force a STAB move first
const stabMovePool = baseWeights.filter( const stabMovePool = baseWeights.filter(
@ -3724,7 +3727,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (cancelled.value || isTypeImmune) { if (cancelled.value || isTypeImmune) {
return { return {
cancelled: cancelled.value, cancelled: cancelled.value,
result: move.id === Moves.SHEER_COLD ? HitResult.IMMUNE : HitResult.NO_EFFECT, result: move.id === MoveId.SHEER_COLD ? HitResult.IMMUNE : HitResult.NO_EFFECT,
damage: 0, damage: 0,
}; };
} }
@ -4131,7 +4134,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return !cancelled.value; return !cancelled.value;
} }
addTag(tagType: BattlerTagType, turnCount = 0, sourceMove?: Moves, sourceId?: number): boolean { addTag(tagType: BattlerTagType, turnCount = 0, sourceMove?: MoveId, sourceId?: number): boolean {
const existingTag = this.getTag(tagType); const existingTag = this.getTag(tagType);
if (existingTag) { if (existingTag) {
existingTag.onOverlap(this); existingTag.onOverlap(this);
@ -4300,19 +4303,19 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
/** /**
* Gets whether the given move is currently disabled for this Pokemon. * Gets whether the given move is currently disabled for this Pokemon.
* *
* @param moveId - The {@linkcode Moves} ID of the move to check * @param moveId - The {@linkcode MoveId} ID of the move to check
* @returns `true` if the move is disabled for this Pokemon, otherwise `false` * @returns `true` if the move is disabled for this Pokemon, otherwise `false`
* *
* @see {@linkcode MoveRestrictionBattlerTag} * @see {@linkcode MoveRestrictionBattlerTag}
*/ */
public isMoveRestricted(moveId: Moves, pokemon?: Pokemon): boolean { public isMoveRestricted(moveId: MoveId, pokemon?: Pokemon): boolean {
return this.getRestrictingTag(moveId, pokemon) !== null; return this.getRestrictingTag(moveId, pokemon) !== null;
} }
/** /**
* Gets whether the given move is currently disabled for the user based on the player's target selection * Gets whether the given move is currently disabled for the user based on the player's target selection
* *
* @param moveId - The {@linkcode Moves} ID of the move to check * @param moveId - The {@linkcode MoveId} ID of the move to check
* @param user - The move user * @param user - The move user
* @param target - The target of the move * @param target - The target of the move
* *
@ -4320,7 +4323,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* *
* @see {@linkcode MoveRestrictionBattlerTag} * @see {@linkcode MoveRestrictionBattlerTag}
*/ */
isMoveTargetRestricted(moveId: Moves, user: Pokemon, target: Pokemon): boolean { isMoveTargetRestricted(moveId: MoveId, user: Pokemon, target: Pokemon): boolean {
for (const tag of this.findTags(t => t instanceof MoveRestrictionBattlerTag)) { for (const tag of this.findTags(t => t instanceof MoveRestrictionBattlerTag)) {
if ((tag as MoveRestrictionBattlerTag).isMoveTargetRestricted(moveId, user, target)) { if ((tag as MoveRestrictionBattlerTag).isMoveTargetRestricted(moveId, user, target)) {
return (tag as MoveRestrictionBattlerTag) !== null; return (tag as MoveRestrictionBattlerTag) !== null;
@ -4332,12 +4335,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
/** /**
* Gets the {@link MoveRestrictionBattlerTag} that is restricting a move, if it exists. * Gets the {@link MoveRestrictionBattlerTag} that is restricting a move, if it exists.
* *
* @param moveId - {@linkcode Moves} ID of the move to check * @param moveId - {@linkcode MoveId} ID of the move to check
* @param user - {@linkcode Pokemon} the move user, optional and used when the target is a factor in the move's restricted status * @param user - {@linkcode Pokemon} the move user, optional and used when the target is a factor in the move's restricted status
* @param target - {@linkcode Pokemon} the target of the move, optional and used when the target is a factor in the move's restricted status * @param target - {@linkcode Pokemon} the target of the move, optional and used when the target is a factor in the move's restricted status
* @returns The first tag on this Pokemon that restricts the move, or `null` if the move is not restricted. * @returns The first tag on this Pokemon that restricts the move, or `null` if the move is not restricted.
*/ */
getRestrictingTag(moveId: Moves, user?: Pokemon, target?: Pokemon): MoveRestrictionBattlerTag | null { getRestrictingTag(moveId: MoveId, user?: Pokemon, target?: Pokemon): MoveRestrictionBattlerTag | null {
for (const tag of this.findTags(t => t instanceof MoveRestrictionBattlerTag)) { for (const tag of this.findTags(t => t instanceof MoveRestrictionBattlerTag)) {
if ((tag as MoveRestrictionBattlerTag).isMoveRestricted(moveId, user)) { if ((tag as MoveRestrictionBattlerTag).isMoveRestricted(moveId, user)) {
return tag as MoveRestrictionBattlerTag; return tag as MoveRestrictionBattlerTag;
@ -5509,7 +5512,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
export class PlayerPokemon extends Pokemon { export class PlayerPokemon extends Pokemon {
protected battleInfo: PlayerBattleInfo; protected battleInfo: PlayerBattleInfo;
public compatibleTms: Moves[]; public compatibleTms: MoveId[];
constructor( constructor(
species: PokemonSpecies, species: PokemonSpecies,
@ -5580,7 +5583,7 @@ export class PlayerPokemon extends Pokemon {
const tms = Object.keys(tmSpecies); const tms = Object.keys(tmSpecies);
for (const tm of tms) { for (const tm of tms) {
const moveId = Number.parseInt(tm) as Moves; const moveId = Number.parseInt(tm) as MoveId;
let compatible = false; let compatible = false;
for (const p of tmSpecies[tm]) { for (const p of tmSpecies[tm]) {
if (Array.isArray(p)) { if (Array.isArray(p)) {
@ -6166,28 +6169,28 @@ export class EnemyPokemon extends Pokemon {
switch (true) { switch (true) {
case this.species.speciesId === Species.SMEARGLE: case this.species.speciesId === Species.SMEARGLE:
this.moveset = [ this.moveset = [
new PokemonMove(Moves.SKETCH), new PokemonMove(MoveId.SKETCH),
new PokemonMove(Moves.SKETCH), new PokemonMove(MoveId.SKETCH),
new PokemonMove(Moves.SKETCH), new PokemonMove(MoveId.SKETCH),
new PokemonMove(Moves.SKETCH), new PokemonMove(MoveId.SKETCH),
]; ];
break; break;
case this.species.speciesId === Species.ETERNATUS: case this.species.speciesId === Species.ETERNATUS:
this.moveset = (formIndex !== undefined ? formIndex : this.formIndex) this.moveset = (formIndex !== undefined ? formIndex : this.formIndex)
? [ ? [
new PokemonMove(Moves.DYNAMAX_CANNON), new PokemonMove(MoveId.DYNAMAX_CANNON),
new PokemonMove(Moves.CROSS_POISON), new PokemonMove(MoveId.CROSS_POISON),
new PokemonMove(Moves.FLAMETHROWER), new PokemonMove(MoveId.FLAMETHROWER),
new PokemonMove(Moves.RECOVER, 0, -4), new PokemonMove(MoveId.RECOVER, 0, -4),
] ]
: [ : [
new PokemonMove(Moves.ETERNABEAM), new PokemonMove(MoveId.ETERNABEAM),
new PokemonMove(Moves.SLUDGE_BOMB), new PokemonMove(MoveId.SLUDGE_BOMB),
new PokemonMove(Moves.FLAMETHROWER), new PokemonMove(MoveId.FLAMETHROWER),
new PokemonMove(Moves.COSMIC_POWER), new PokemonMove(MoveId.COSMIC_POWER),
]; ];
if (globalScene.gameMode.hasChallenge(Challenges.INVERSE_BATTLE)) { if (globalScene.gameMode.hasChallenge(Challenges.INVERSE_BATTLE)) {
this.moveset[2] = new PokemonMove(Moves.THUNDERBOLT); this.moveset[2] = new PokemonMove(MoveId.THUNDERBOLT);
} }
break; break;
default: default:
@ -6273,7 +6276,7 @@ export class EnemyPokemon extends Pokemon {
moveTargets.some(p => { moveTargets.some(p => {
const doesNotFail = const doesNotFail =
move.applyConditions(this, p, move) || move.applyConditions(this, p, move) ||
[Moves.SUCKER_PUNCH, Moves.UPPER_HAND, Moves.THUNDERCLAP].includes(move.id); [MoveId.SUCKER_PUNCH, MoveId.UPPER_HAND, MoveId.THUNDERCLAP].includes(move.id);
return ( return (
doesNotFail && doesNotFail &&
p.getAttackDamage({ p.getAttackDamage({
@ -6332,7 +6335,7 @@ export class EnemyPokemon extends Pokemon {
*/ */
if ( if (
(move.name.endsWith(" (N)") || !move.applyConditions(this, target, move)) && (move.name.endsWith(" (N)") || !move.applyConditions(this, target, move)) &&
![Moves.SUCKER_PUNCH, Moves.UPPER_HAND, Moves.THUNDERCLAP].includes(move.id) ![MoveId.SUCKER_PUNCH, MoveId.UPPER_HAND, MoveId.THUNDERCLAP].includes(move.id)
) { ) {
targetScore = -20; targetScore = -20;
} else if (move instanceof AttackMove) { } else if (move instanceof AttackMove) {
@ -6417,17 +6420,17 @@ export class EnemyPokemon extends Pokemon {
} }
return { return {
move: Moves.STRUGGLE, move: MoveId.STRUGGLE,
targets: this.getNextTargets(Moves.STRUGGLE), targets: this.getNextTargets(MoveId.STRUGGLE),
}; };
} }
/** /**
* Determines the Pokemon the given move would target if used by this Pokemon * Determines the Pokemon the given move would target if used by this Pokemon
* @param moveId {@linkcode Moves} The move to be used * @param moveId {@linkcode MoveId} The move to be used
* @returns The indexes of the Pokemon the given move would target * @returns The indexes of the Pokemon the given move would target
*/ */
getNextTargets(moveId: Moves): BattlerIndex[] { getNextTargets(moveId: MoveId): BattlerIndex[] {
const moveTargets = getMoveTargets(this, moveId); const moveTargets = getMoveTargets(this, moveId);
const targets = globalScene.getField(true).filter(p => moveTargets.targets.indexOf(p.getBattlerIndex()) > -1); const targets = globalScene.getField(true).filter(p => moveTargets.targets.indexOf(p.getBattlerIndex()) > -1);
// If the move is multi-target, return all targets' indexes // If the move is multi-target, return all targets' indexes
@ -6752,7 +6755,7 @@ interface IllusionData {
} }
export interface TurnMove { export interface TurnMove {
move: Moves; move: MoveId;
targets: BattlerIndex[]; targets: BattlerIndex[];
result?: MoveResult; result?: MoveResult;
virtual?: boolean; virtual?: boolean;
@ -6761,7 +6764,7 @@ export interface TurnMove {
} }
export interface AttackMoveResult { export interface AttackMoveResult {
move: Moves; move: MoveId;
result: DamageResult; result: DamageResult;
damage: number; damage: number;
critical: boolean; critical: boolean;
@ -6848,7 +6851,7 @@ export class PokemonTempSummonData {
* Reset on switch and new wave, but not stored in `SummonData` to avoid being written to the save file. * Reset on switch and new wave, but not stored in `SummonData` to avoid being written to the save file.
* Used to evaluate "first turn only" conditions such as * Used to evaluate "first turn only" conditions such as
* {@linkcode Moves.FAKE_OUT | Fake Out} and {@linkcode Moves.FIRST_IMPRESSION | First Impression}). * {@linkcode MoveId.FAKE_OUT | Fake Out} and {@linkcode MoveId.FIRST_IMPRESSION | First Impression}).
*/ */
waveTurnCount = 1; waveTurnCount = 1;
} }
@ -6858,9 +6861,9 @@ export class PokemonTempSummonData {
* Resets at the start of a new battle (but not on switch). * Resets at the start of a new battle (but not on switch).
*/ */
export class PokemonBattleData { export class PokemonBattleData {
/** Counter tracking direct hits this Pokemon has received during this battle; used for {@linkcode Moves.RAGE_FIST} */ /** Counter tracking direct hits this Pokemon has received during this battle; used for {@linkcode MoveId.RAGE_FIST} */
public hitCount = 0; public hitCount = 0;
/** Whether this Pokemon has eaten a berry this battle; used for {@linkcode Moves.BELCH} */ /** Whether this Pokemon has eaten a berry this battle; used for {@linkcode MoveId.BELCH} */
public hasEatenBerry = false; public hasEatenBerry = false;
/** Array containing all berries eaten and not yet recovered during this current battle; used by {@linkcode AbilityId.HARVEST} */ /** Array containing all berries eaten and not yet recovered during this current battle; used by {@linkcode AbilityId.HARVEST} */
public berriesEaten: BerryType[] = []; public berriesEaten: BerryType[] = [];
@ -6912,7 +6915,7 @@ export class PokemonTurnData {
public statStagesIncreased = false; public statStagesIncreased = false;
public statStagesDecreased = false; public statStagesDecreased = false;
public moveEffectiveness: TypeDamageMultiplier | null = null; public moveEffectiveness: TypeDamageMultiplier | null = null;
public combiningPledge?: Moves; public combiningPledge?: MoveId;
public switchedInThisTurn = false; public switchedInThisTurn = false;
public failedRunAway = false; public failedRunAway = false;
public joinedRound = false; public joinedRound = false;
@ -6992,7 +6995,7 @@ export interface DamageCalculationResult {
* @see {@linkcode getName} - returns name of {@linkcode Move}. * @see {@linkcode getName} - returns name of {@linkcode Move}.
**/ **/
export class PokemonMove { export class PokemonMove {
public moveId: Moves; public moveId: MoveId;
public ppUsed: number; public ppUsed: number;
public ppUp: number; public ppUp: number;
public virtual: boolean; public virtual: boolean;
@ -7003,7 +7006,7 @@ export class PokemonMove {
*/ */
public maxPpOverride?: number; public maxPpOverride?: number;
constructor(moveId: Moves, ppUsed = 0, ppUp = 0, virtual = false, maxPpOverride?: number) { constructor(moveId: MoveId, ppUsed = 0, ppUp = 0, virtual = false, maxPpOverride?: number) {
this.moveId = moveId; this.moveId = moveId;
this.ppUsed = ppUsed; this.ppUsed = ppUsed;
this.ppUp = ppUp; this.ppUp = ppUp;

View File

@ -119,7 +119,7 @@ import {
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type";
import { BerryType } from "#enums/berry-type"; import { BerryType } from "#enums/berry-type";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Nature } from "#enums/nature"; import { Nature } from "#enums/nature";
import { PokeballType } from "#enums/pokeball"; import { PokeballType } from "#enums/pokeball";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
@ -1165,9 +1165,9 @@ export class PokemonMultiHitModifierType extends PokemonHeldItemModifierType {
} }
export class TmModifierType extends PokemonModifierType { export class TmModifierType extends PokemonModifierType {
public moveId: Moves; public moveId: MoveId;
constructor(moveId: Moves) { constructor(moveId: MoveId) {
super( super(
"", "",
`tm_${PokemonType[allMoves[moveId].type].toLowerCase()}`, `tm_${PokemonType[allMoves[moveId].type].toLowerCase()}`,
@ -1553,8 +1553,8 @@ class SpeciesStatBoosterModifierTypeGenerator extends ModifierTypeGenerator {
class TmModifierTypeGenerator extends ModifierTypeGenerator { class TmModifierTypeGenerator extends ModifierTypeGenerator {
constructor(tier: ModifierTier) { constructor(tier: ModifierTier) {
super((party: Pokemon[], pregenArgs?: any[]) => { super((party: Pokemon[], pregenArgs?: any[]) => {
if (pregenArgs && pregenArgs.length === 1 && pregenArgs[0] in Moves) { if (pregenArgs && pregenArgs.length === 1 && pregenArgs[0] in MoveId) {
return new TmModifierType(pregenArgs[0] as Moves); return new TmModifierType(pregenArgs[0] as MoveId);
} }
const partyMemberCompatibleTms = party.map(p => { const partyMemberCompatibleTms = party.map(p => {
const previousLevelMoves = p.getLearnableLevelMoves(); const previousLevelMoves = p.getLearnableLevelMoves();
@ -1904,7 +1904,7 @@ export type GeneratorModifierOverride = {
} }
| { | {
name: keyof Pick<typeof modifierTypes, "TM_COMMON" | "TM_GREAT" | "TM_ULTRA">; name: keyof Pick<typeof modifierTypes, "TM_COMMON" | "TM_GREAT" | "TM_ULTRA">;
type?: Moves; type?: MoveId;
} }
); );
@ -2771,7 +2771,7 @@ const modifierPool: ModifierPool = {
const canSetStatus = p.canSetStatus(StatusEffect.TOXIC, true, true, null, true); const canSetStatus = p.canSetStatus(StatusEffect.TOXIC, true, true, null, true);
// Moves that take advantage of obtaining the actual status effect // Moves that take advantage of obtaining the actual status effect
const hasStatusMoves = [Moves.FACADE, Moves.PSYCHO_SHIFT].some(m => moveset.includes(m)); const hasStatusMoves = [MoveId.FACADE, MoveId.PSYCHO_SHIFT].some(m => moveset.includes(m));
// Moves that take advantage of being able to give the target a status orb // Moves that take advantage of being able to give the target a status orb
// TODO: Take moves (Trick, Fling, Switcheroo) from comment when they are implemented // TODO: Take moves (Trick, Fling, Switcheroo) from comment when they are implemented
const hasItemMoves = [ const hasItemMoves = [
@ -2817,7 +2817,7 @@ const modifierPool: ModifierPool = {
const canSetStatus = p.canSetStatus(StatusEffect.BURN, true, true, null, true); const canSetStatus = p.canSetStatus(StatusEffect.BURN, true, true, null, true);
// Moves that take advantage of obtaining the actual status effect // Moves that take advantage of obtaining the actual status effect
const hasStatusMoves = [Moves.FACADE, Moves.PSYCHO_SHIFT].some(m => moveset.includes(m)); const hasStatusMoves = [MoveId.FACADE, MoveId.PSYCHO_SHIFT].some(m => moveset.includes(m));
// Moves that take advantage of being able to give the target a status orb // Moves that take advantage of being able to give the target a status orb
// TODO: Take moves (Trick, Fling, Switcheroo) from comment when they are implemented // TODO: Take moves (Trick, Fling, Switcheroo) from comment when they are implemented
const hasItemMoves = [ const hasItemMoves = [
@ -2880,16 +2880,16 @@ const modifierPool: ModifierPool = {
].some(a => p.hasAbility(a, false, true)); ].some(a => p.hasAbility(a, false, true));
const hasMoves = [ const hasMoves = [
Moves.SUNNY_DAY, MoveId.SUNNY_DAY,
Moves.RAIN_DANCE, MoveId.RAIN_DANCE,
Moves.SANDSTORM, MoveId.SANDSTORM,
Moves.SNOWSCAPE, MoveId.SNOWSCAPE,
Moves.HAIL, MoveId.HAIL,
Moves.CHILLY_RECEPTION, MoveId.CHILLY_RECEPTION,
Moves.ELECTRIC_TERRAIN, MoveId.ELECTRIC_TERRAIN,
Moves.PSYCHIC_TERRAIN, MoveId.PSYCHIC_TERRAIN,
Moves.GRASSY_TERRAIN, MoveId.GRASSY_TERRAIN,
Moves.MISTY_TERRAIN, MoveId.MISTY_TERRAIN,
].some(m => moveset.includes(m)); ].some(m => moveset.includes(m));
return hasAbility || hasMoves; return hasAbility || hasMoves;

View File

@ -18,7 +18,7 @@ import { addTextObject, TextStyle } from "#app/ui/text";
import { BooleanHolder, hslToHex, isNullOrUndefined, NumberHolder, toDmgValue } from "#app/utils/common"; import { BooleanHolder, hslToHex, isNullOrUndefined, NumberHolder, toDmgValue } from "#app/utils/common";
import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type";
import { BerryType } from "#enums/berry-type"; import { BerryType } from "#enums/berry-type";
import type { Moves } from "#enums/moves"; import type { MoveId } from "#enums/moves";
import type { Nature } from "#enums/nature"; import type { Nature } from "#enums/nature";
import type { PokeballType } from "#enums/pokeball"; import type { PokeballType } from "#enums/pokeball";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
@ -2774,14 +2774,14 @@ export class PokemonMultiHitModifier extends PokemonHeldItemModifier {
/** /**
* For each stack, converts 25 percent of attack damage into an additional strike. * For each stack, converts 25 percent of attack damage into an additional strike.
* @param pokemon The {@linkcode Pokemon} using the move * @param pokemon The {@linkcode Pokemon} using the move
* @param moveId The {@linkcode Moves | identifier} for the move being used * @param moveId The {@linkcode MoveId | identifier} for the move being used
* @param count {@linkcode NumberHolder} holding the move's hit count for this turn * @param count {@linkcode NumberHolder} holding the move's hit count for this turn
* @param damageMultiplier {@linkcode NumberHolder} holding a damage multiplier applied to a strike of this move * @param damageMultiplier {@linkcode NumberHolder} holding a damage multiplier applied to a strike of this move
* @returns always `true` * @returns always `true`
*/ */
override apply( override apply(
pokemon: Pokemon, pokemon: Pokemon,
moveId: Moves, moveId: MoveId,
count: NumberHolder | null = null, count: NumberHolder | null = null,
damageMultiplier: NumberHolder | null = null, damageMultiplier: NumberHolder | null = null,
): boolean { ): boolean {

View File

@ -10,7 +10,7 @@ import { BattleType } from "#enums/battle-type";
import { BerryType } from "#enums/berry-type"; import { BerryType } from "#enums/berry-type";
import { Biome } from "#enums/biome"; import { Biome } from "#enums/biome";
import { EggTier } from "#enums/egg-type"; import { EggTier } from "#enums/egg-type";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { PokeballType } from "#enums/pokeball"; import { PokeballType } from "#enums/pokeball";
@ -152,7 +152,7 @@ class DefaultOverrides {
readonly HAS_PASSIVE_ABILITY_OVERRIDE: boolean | null = null; readonly HAS_PASSIVE_ABILITY_OVERRIDE: boolean | null = null;
readonly STATUS_OVERRIDE: StatusEffect = StatusEffect.NONE; readonly STATUS_OVERRIDE: StatusEffect = StatusEffect.NONE;
readonly GENDER_OVERRIDE: Gender | null = null; readonly GENDER_OVERRIDE: Gender | null = null;
readonly MOVESET_OVERRIDE: Moves | Array<Moves> = []; readonly MOVESET_OVERRIDE: MoveId | Array<MoveId> = [];
readonly SHINY_OVERRIDE: boolean | null = null; readonly SHINY_OVERRIDE: boolean | null = null;
readonly VARIANT_OVERRIDE: Variant | null = null; readonly VARIANT_OVERRIDE: Variant | null = null;
@ -174,7 +174,7 @@ class DefaultOverrides {
readonly OPP_HAS_PASSIVE_ABILITY_OVERRIDE: boolean | null = null; readonly OPP_HAS_PASSIVE_ABILITY_OVERRIDE: boolean | null = null;
readonly OPP_STATUS_OVERRIDE: StatusEffect = StatusEffect.NONE; readonly OPP_STATUS_OVERRIDE: StatusEffect = StatusEffect.NONE;
readonly OPP_GENDER_OVERRIDE: Gender | null = null; readonly OPP_GENDER_OVERRIDE: Gender | null = null;
readonly OPP_MOVESET_OVERRIDE: Moves | Array<Moves> = []; readonly OPP_MOVESET_OVERRIDE: MoveId | Array<MoveId> = [];
readonly OPP_SHINY_OVERRIDE: boolean | null = null; readonly OPP_SHINY_OVERRIDE: boolean | null = null;
readonly OPP_VARIANT_OVERRIDE: Variant | null = null; readonly OPP_VARIANT_OVERRIDE: Variant | null = null;
readonly OPP_IVS_OVERRIDE: number | number[] = []; readonly OPP_IVS_OVERRIDE: number | number[] = [];

View File

@ -9,7 +9,7 @@ import { speciesStarterCosts } from "#app/data/balance/starters";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { BattlerTagType } from "#app/enums/battler-tag-type"; import { BattlerTagType } from "#app/enums/battler-tag-type";
import { Biome } from "#app/enums/biome"; import { Biome } from "#app/enums/biome";
import { Moves } from "#app/enums/moves"; import { MoveId } from "#app/enums/moves";
import { PokeballType } from "#enums/pokeball"; import { PokeballType } from "#enums/pokeball";
import type { PlayerPokemon, TurnMove } from "#app/field/pokemon"; import type { PlayerPokemon, TurnMove } from "#app/field/pokemon";
import { FieldPosition } from "#app/field/pokemon"; import { FieldPosition } from "#app/field/pokemon";
@ -80,7 +80,7 @@ export class CommandPhase extends FieldPhase {
) { ) {
globalScene.currentBattle.turnCommands[this.fieldIndex] = { globalScene.currentBattle.turnCommands[this.fieldIndex] = {
command: Command.FIGHT, command: Command.FIGHT,
move: { move: Moves.NONE, targets: [] }, move: { move: MoveId.NONE, targets: [] },
skip: true, skip: true,
}; };
} }
@ -157,15 +157,15 @@ export class CommandPhase extends FieldPhase {
playerPokemon.trySelectMove(cursor, args[0] as boolean) || playerPokemon.trySelectMove(cursor, args[0] as boolean) ||
(useStruggle = cursor > -1 && !playerPokemon.getMoveset().filter(m => m.isUsable(playerPokemon)).length) (useStruggle = cursor > -1 && !playerPokemon.getMoveset().filter(m => m.isUsable(playerPokemon)).length)
) { ) {
let moveId: Moves; let moveId: MoveId;
if (useStruggle) { if (useStruggle) {
moveId = Moves.STRUGGLE; moveId = MoveId.STRUGGLE;
} else if (turnMove !== undefined) { } else if (turnMove !== undefined) {
moveId = turnMove.move; moveId = turnMove.move;
} else if (cursor > -1) { } else if (cursor > -1) {
moveId = playerPokemon.getMoveset()[cursor].moveId; moveId = playerPokemon.getMoveset()[cursor].moveId;
} else { } else {
moveId = Moves.NONE; moveId = MoveId.NONE;
} }
const turnCommand: TurnCommand = { const turnCommand: TurnCommand = {

View File

@ -3,7 +3,7 @@ import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims";
import type Move from "#app/data/moves/move"; import type Move from "#app/data/moves/move";
import { allMoves } from "#app/data/data-lists"; import { allMoves } from "#app/data/data-lists";
import { SpeciesFormChangeMoveLearnedTrigger } from "#app/data/pokemon-forms"; import { SpeciesFormChangeMoveLearnedTrigger } from "#app/data/pokemon-forms";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { getPokemonNameWithAffix } from "#app/messages"; import { getPokemonNameWithAffix } from "#app/messages";
import Overrides from "#app/overrides"; import Overrides from "#app/overrides";
import EvolutionSceneHandler from "#app/ui/evolution-scene-handler"; import EvolutionSceneHandler from "#app/ui/evolution-scene-handler";
@ -24,14 +24,14 @@ export enum LearnMoveType {
} }
export class LearnMovePhase extends PlayerPartyMemberPokemonPhase { export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
private moveId: Moves; private moveId: MoveId;
private messageMode: UiMode; private messageMode: UiMode;
private learnMoveType: LearnMoveType; private learnMoveType: LearnMoveType;
private cost: number; private cost: number;
constructor( constructor(
partyMemberIndex: number, partyMemberIndex: number,
moveId: Moves, moveId: MoveId,
learnMoveType: LearnMoveType = LearnMoveType.LEARN_MOVE, learnMoveType: LearnMoveType = LearnMoveType.LEARN_MOVE,
cost = -1, cost = -1,
) { ) {
@ -49,7 +49,7 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
const currentMoveset = pokemon.getMoveset(); const currentMoveset = pokemon.getMoveset();
// The game first checks if the Pokemon already has the move and ends the phase if it does. // The game first checks if the Pokemon already has the move and ends the phase if it does.
const hasMoveAlready = currentMoveset.some(m => m.moveId === move.id) && this.moveId !== Moves.SKETCH; const hasMoveAlready = currentMoveset.some(m => m.moveId === move.id) && this.moveId !== MoveId.SKETCH;
if (hasMoveAlready) { if (hasMoveAlready) {
return this.end(); return this.end();
} }

View File

@ -1,5 +1,5 @@
import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims"; import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims";
import type { Moves } from "#enums/moves"; import type { MoveId } from "#enums/moves";
import { Phase } from "#app/phase"; import { Phase } from "#app/phase";
/** /**
@ -8,7 +8,7 @@ import { Phase } from "#app/phase";
* isn't already loaded (e.g. for Metronome) * isn't already loaded (e.g. for Metronome)
*/ */
export class LoadMoveAnimPhase extends Phase { export class LoadMoveAnimPhase extends Phase {
constructor(protected moveId: Moves) { constructor(protected moveId: MoveId) {
super(); super();
} }

View File

@ -48,7 +48,7 @@ import { MoveTarget } from "#enums/MoveTarget";
import { MoveCategory } from "#enums/MoveCategory"; import { MoveCategory } from "#enums/MoveCategory";
import { SpeciesFormChangePostMoveTrigger } from "#app/data/pokemon-forms"; import { SpeciesFormChangePostMoveTrigger } from "#app/data/pokemon-forms";
import { PokemonType } from "#enums/pokemon-type"; import { PokemonType } from "#enums/pokemon-type";
import { DamageResult, PokemonMove, type TurnMove } from "#app/field/pokemon"; import { type DamageResult, PokemonMove, type TurnMove } from "#app/field/pokemon";
import type Pokemon from "#app/field/pokemon"; import type Pokemon from "#app/field/pokemon";
import { HitResult, MoveResult } from "#app/field/pokemon"; import { HitResult, MoveResult } from "#app/field/pokemon";
import { getPokemonNameWithAffix } from "#app/messages"; import { getPokemonNameWithAffix } from "#app/messages";
@ -65,14 +65,14 @@ import { PokemonPhase } from "#app/phases/pokemon-phase";
import { BooleanHolder, isNullOrUndefined, NumberHolder } from "#app/utils/common"; import { BooleanHolder, isNullOrUndefined, NumberHolder } from "#app/utils/common";
import type { nil } from "#app/utils/common"; import type { nil } from "#app/utils/common";
import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import i18next from "i18next"; import i18next from "i18next";
import type { Phase } from "#app/phase"; import type { Phase } from "#app/phase";
import { ShowAbilityPhase } from "./show-ability-phase"; import { ShowAbilityPhase } from "./show-ability-phase";
import { MovePhase } from "./move-phase"; import { MovePhase } from "./move-phase";
import { MoveEndPhase } from "./move-end-phase"; import { MoveEndPhase } from "./move-end-phase";
import { HideAbilityPhase } from "#app/phases/hide-ability-phase"; import { HideAbilityPhase } from "#app/phases/hide-ability-phase";
import { TypeDamageMultiplier } from "#app/data/type"; import type { TypeDamageMultiplier } from "#app/data/type";
import { HitCheckResult } from "#enums/hit-check-result"; import { HitCheckResult } from "#enums/hit-check-result";
import type Move from "#app/data/moves/move"; import type Move from "#app/data/moves/move";
import { isFieldTargeted } from "#app/data/moves/move-utils"; import { isFieldTargeted } from "#app/data/moves/move-utils";
@ -220,7 +220,7 @@ export class MoveEffectPhase extends PokemonPhase {
break; break;
case HitCheckResult.NO_EFFECT: case HitCheckResult.NO_EFFECT:
globalScene.queueMessage( globalScene.queueMessage(
i18next.t(this.move.id === Moves.SHEER_COLD ? "battle:hitResultImmune" : "battle:hitResultNoEffect", { i18next.t(this.move.id === MoveId.SHEER_COLD ? "battle:hitResultImmune" : "battle:hitResultNoEffect", {
pokemonName: getPokemonNameWithAffix(target), pokemonName: getPokemonNameWithAffix(target),
}), }),
); );
@ -351,7 +351,7 @@ export class MoveEffectPhase extends PokemonPhase {
) { ) {
const firstTarget = this.getFirstTarget(); const firstTarget = this.getFirstTarget();
new MoveAnim( new MoveAnim(
move.id as Moves, move.id as MoveId,
user, user,
firstTarget?.getBattlerIndex() ?? BattlerIndex.ATTACKER, firstTarget?.getBattlerIndex() ?? BattlerIndex.ATTACKER,
// Some moves used in mystery encounters should be played even on an empty field // Some moves used in mystery encounters should be played even on an empty field
@ -610,11 +610,11 @@ export class MoveEffectPhase extends PokemonPhase {
* *
* Accuracy and semi-invulnerability can be bypassed by: * Accuracy and semi-invulnerability can be bypassed by:
* - An ability like {@linkcode Abilities.NO_GUARD | No Guard} * - An ability like {@linkcode Abilities.NO_GUARD | No Guard}
* - A poison type using {@linkcode Moves.TOXIC | Toxic} * - A poison type using {@linkcode MoveId.TOXIC | Toxic}
* - A move like {@linkcode Moves.LOCK_ON | Lock-On} or {@linkcode Moves.MIND_READER | Mind Reader}. * - A move like {@linkcode MoveId.LOCK_ON | Lock-On} or {@linkcode MoveId.MIND_READER | Mind Reader}.
* - A field-targeted move like spikes * - A field-targeted move like spikes
* *
* Does *not* check against effects {@linkcode Moves.GLAIVE_RUSH | Glaive Rush} status (which * Does *not* check against effects {@linkcode MoveId.GLAIVE_RUSH | Glaive Rush} status (which
* should not bypass semi-invulnerability), or interactions like Earthquake hitting against Dig, * should not bypass semi-invulnerability), or interactions like Earthquake hitting against Dig,
* (which should not bypass the accuracy check). * (which should not bypass the accuracy check).
* *
@ -809,7 +809,7 @@ export class MoveEffectPhase extends PokemonPhase {
*/ */
applyMoveAttrs(StatChangeBeforeDmgCalcAttr, user, target, this.move); applyMoveAttrs(StatChangeBeforeDmgCalcAttr, user, target, this.move);
const { result: result, damage: dmg } = target.getAttackDamage({ const { result, damage: dmg } = target.getAttackDamage({
source: user, source: user,
move: this.move, move: this.move,
ignoreAbility: false, ignoreAbility: false,

View File

@ -47,7 +47,7 @@ import { NumberHolder } from "#app/utils/common";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { ArenaTagType } from "#enums/arena-tag-type"; import { ArenaTagType } from "#enums/arena-tag-type";
import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { StatusEffect } from "#enums/status-effect"; import { StatusEffect } from "#enums/status-effect";
import i18next from "i18next"; import i18next from "i18next";
@ -138,7 +138,7 @@ export class MovePhase extends BattlePhase {
/** /**
* Shows whether the current move has been forced to the end of the turn * Shows whether the current move has been forced to the end of the turn
* Needed for speed order, see {@linkcode Moves.QUASH} * Needed for speed order, see {@linkcode MoveId.QUASH}
* */ * */
public isForcedLast(): boolean { public isForcedLast(): boolean {
return this.forcedLast; return this.forcedLast;
@ -147,7 +147,7 @@ export class MovePhase extends BattlePhase {
public start(): void { public start(): void {
super.start(); super.start();
console.log(Moves[this.move.moveId]); console.log(MoveId[this.move.moveId]);
// Check if move is unusable (e.g. because it's out of PP due to a mid-turn Spite). // Check if move is unusable (e.g. because it's out of PP due to a mid-turn Spite).
if (!this.canMove(true)) { if (!this.canMove(true)) {
@ -201,14 +201,14 @@ export class MovePhase extends BattlePhase {
this.end(); this.end();
} }
/** Check for cancellation edge cases - no targets remaining, or {@linkcode Moves.NONE} is in the queue */ /** Check for cancellation edge cases - no targets remaining, or {@linkcode MoveId.NONE} is in the queue */
protected resolveFinalPreMoveCancellationChecks(): void { protected resolveFinalPreMoveCancellationChecks(): void {
const targets = this.getActiveTargetPokemon(); const targets = this.getActiveTargetPokemon();
const moveQueue = this.pokemon.getMoveQueue(); const moveQueue = this.pokemon.getMoveQueue();
if ( if (
(targets.length === 0 && !this.move.getMove().hasAttr(AddArenaTrapTagAttr)) || (targets.length === 0 && !this.move.getMove().hasAttr(AddArenaTrapTagAttr)) ||
(moveQueue.length && moveQueue[0].move === Moves.NONE) (moveQueue.length && moveQueue[0].move === MoveId.NONE)
) { ) {
this.showMoveText(); this.showMoveText();
this.showFailedText(); this.showFailedText();
@ -410,7 +410,7 @@ export class MovePhase extends BattlePhase {
new MoveEffectPhase(this.pokemon.getBattlerIndex(), this.targets, move, this.reflected, this.move.virtual), new MoveEffectPhase(this.pokemon.getBattlerIndex(), this.targets, move, this.reflected, this.move.virtual),
); );
} else { } else {
if ([Moves.ROAR, Moves.WHIRLWIND, Moves.TRICK_OR_TREAT, Moves.FORESTS_CURSE].includes(this.move.moveId)) { if ([MoveId.ROAR, MoveId.WHIRLWIND, MoveId.TRICK_OR_TREAT, MoveId.FORESTS_CURSE].includes(this.move.moveId)) {
applyPreAttackAbAttrs(PokemonTypeChangeAbAttr, this.pokemon, null, this.move.getMove()); applyPreAttackAbAttrs(PokemonTypeChangeAbAttr, this.pokemon, null, this.move.getMove());
} }
@ -603,7 +603,7 @@ export class MovePhase extends BattlePhase {
* *
* TODO: ...this seems weird. * TODO: ...this seems weird.
* - Lapses `AFTER_MOVE` tags: * - Lapses `AFTER_MOVE` tags:
* - This handles the effects of {@link Moves.SUBSTITUTE Substitute} * - This handles the effects of {@link MoveId.SUBSTITUTE Substitute}
* - Removes the second turn of charge moves * - Removes the second turn of charge moves
*/ */
protected handlePreMoveFailures(): void { protected handlePreMoveFailures(): void {
@ -623,7 +623,7 @@ export class MovePhase extends BattlePhase {
} }
this.pokemon.pushMoveHistory({ this.pokemon.pushMoveHistory({
move: Moves.NONE, move: MoveId.NONE,
result: MoveResult.FAIL, result: MoveResult.FAIL,
targets: this.targets, targets: this.targets,
}); });
@ -636,11 +636,11 @@ export class MovePhase extends BattlePhase {
} }
/** /**
* Displays the move's usage text to the player, unless it's a charge turn (ie: {@link Moves.SOLAR_BEAM Solar Beam}), * Displays the move's usage text to the player, unless it's a charge turn (ie: {@link MoveId.SOLAR_BEAM Solar Beam}),
* the pokemon is on a recharge turn (ie: {@link Moves.HYPER_BEAM Hyper Beam}), or a 2-turn move was interrupted (ie: {@link Moves.FLY Fly}). * the pokemon is on a recharge turn (ie: {@link MoveId.HYPER_BEAM Hyper Beam}), or a 2-turn move was interrupted (ie: {@link MoveId.FLY Fly}).
*/ */
public showMoveText(): void { public showMoveText(): void {
if (this.move.moveId === Moves.NONE) { if (this.move.moveId === MoveId.NONE) {
return; return;
} }

View File

@ -1,6 +1,6 @@
import type { BattlerIndex } from "#app/battle"; import type { BattlerIndex } from "#app/battle";
import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { EFFECTIVE_STATS, BATTLE_STATS } from "#enums/stat"; import { EFFECTIVE_STATS, BATTLE_STATS } from "#enums/stat";
import { PokemonMove } from "#app/field/pokemon"; import { PokemonMove } from "#app/field/pokemon";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
@ -54,7 +54,7 @@ export class PokemonTransformPhase extends PokemonPhase {
return new PokemonMove(m.moveId, 0, 0, false, Math.min(m.getMove().pp, 5)); return new PokemonMove(m.moveId, 0, 0, false, Math.min(m.getMove().pp, 5));
} }
console.warn(`Transform: somehow iterating over a ${m} value when copying moveset!`); console.warn(`Transform: somehow iterating over a ${m} value when copying moveset!`);
return new PokemonMove(Moves.NONE); return new PokemonMove(MoveId.NONE);
}); });
user.summonData.types = target.getTypes(); user.summonData.types = target.getTypes();

View File

@ -1,11 +1,11 @@
import type { Moves } from "#enums/moves"; import type { MoveId } from "#enums/moves";
import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims"; import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims";
/** /**
* Asynchronously load the animations and assets for the provided moves. * Asynchronously load the animations and assets for the provided moves.
* @param moveIds - An array of move IDs to load assets for. * @param moveIds - An array of move IDs to load assets for.
*/ */
export async function loadMoveAnimations(moveIds: Moves[]): Promise<void> { export async function loadMoveAnimations(moveIds: MoveId[]): Promise<void> {
await Promise.allSettled(moveIds.map(m => initMoveAnim(m))); await Promise.allSettled(moveIds.map(m => initMoveAnim(m)));
await loadMoveAnimAssets(moveIds); await loadMoveAnimAssets(moveIds);
} }

View File

@ -43,7 +43,7 @@ import { StatusEffect } from "#enums/status-effect";
import ChallengeData from "#app/system/challenge-data"; import ChallengeData from "#app/system/challenge-data";
import { Device } from "#enums/devices"; import { Device } from "#enums/devices";
import { GameDataType } from "#enums/game-data-type"; import { GameDataType } from "#enums/game-data-type";
import type { Moves } from "#enums/moves"; import type { MoveId } from "#enums/moves";
import { PlayerGender } from "#enums/player-gender"; import { PlayerGender } from "#enums/player-gender";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { applyChallenges, ChallengeType } from "#app/data/challenge"; import { applyChallenges, ChallengeType } from "#app/data/challenge";
@ -205,7 +205,7 @@ export interface DexEntry {
ivs: number[]; ivs: number[];
} }
export type StarterMoveset = [Moves] | [Moves, Moves] | [Moves, Moves, Moves] | [Moves, Moves, Moves, Moves]; export type StarterMoveset = [MoveId] | [MoveId, MoveId] | [MoveId, MoveId, MoveId] | [MoveId, MoveId, MoveId, MoveId];
export interface StarterFormMoveData { export interface StarterFormMoveData {
[key: number]: StarterMoveset; [key: number]: StarterMoveset;

View File

@ -9,7 +9,7 @@ import Pokemon, { EnemyPokemon, PokemonBattleData, PokemonMove, PokemonSummonDat
import { TrainerSlot } from "#enums/trainer-slot"; import { TrainerSlot } from "#enums/trainer-slot";
import type { Variant } from "#app/sprites/variant"; import type { Variant } from "#app/sprites/variant";
import type { Biome } from "#enums/biome"; import type { Biome } from "#enums/biome";
import type { Moves } from "#enums/moves"; import type { MoveId } from "#enums/moves";
import type { Species } from "#enums/species"; import type { Species } from "#enums/species";
import { CustomPokemonData } from "#app/data/custom-pokemon-data"; import { CustomPokemonData } from "#app/data/custom-pokemon-data";
import type { PokemonType } from "#enums/pokemon-type"; import type { PokemonType } from "#enums/pokemon-type";
@ -43,7 +43,7 @@ export default class PokemonData {
public luck: number; public luck: number;
public pauseEvolutions: boolean; public pauseEvolutions: boolean;
public pokerus: boolean; public pokerus: boolean;
public usedTMs: Moves[]; public usedTMs: MoveId[];
public evoCounter: number; public evoCounter: number;
public teraType: PokemonType; public teraType: PokemonType;
public isTerastallized: boolean; public isTerastallized: boolean;

View File

@ -2,7 +2,7 @@ import type { SessionSaveMigrator } from "#app/@types/SessionSaveMigrator";
import { PokemonMove } from "#app/field/pokemon"; import { PokemonMove } from "#app/field/pokemon";
import type { SessionSaveData } from "#app/system/game-data"; import type { SessionSaveData } from "#app/system/game-data";
import type PokemonData from "#app/system/pokemon-data"; import type PokemonData from "#app/system/pokemon-data";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
/** /**
* Migrate all lingering rage fist data inside `CustomPokemonData`, * Migrate all lingering rage fist data inside `CustomPokemonData`,
@ -15,7 +15,7 @@ const migratePartyData: SessionSaveMigrator = {
// this stuff is copied straight from the constructor fwiw // this stuff is copied straight from the constructor fwiw
const mapParty = (pkmnData: PokemonData) => { const mapParty = (pkmnData: PokemonData) => {
// remove empty moves from moveset // remove empty moves from moveset
pkmnData.moveset = (pkmnData.moveset ?? [new PokemonMove(Moves.TACKLE), new PokemonMove(Moves.GROWL)]) pkmnData.moveset = (pkmnData.moveset ?? [new PokemonMove(MoveId.TACKLE), new PokemonMove(MoveId.GROWL)])
.filter(m => !!m) .filter(m => !!m)
.map(m => PokemonMove.loadMove(m)); .map(m => PokemonMove.loadMove(m));
// only edit summondata moveset if exists // only edit summondata moveset if exists

View File

@ -6,7 +6,7 @@ import type Move from "#app/data/moves/move";
import type { BerryUsedEvent, MoveUsedEvent } from "../events/battle-scene"; import type { BerryUsedEvent, MoveUsedEvent } from "../events/battle-scene";
import { BattleSceneEventType } from "../events/battle-scene"; import { BattleSceneEventType } from "../events/battle-scene";
import { BerryType } from "#enums/berry-type"; import { BerryType } from "#enums/berry-type";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { UiTheme } from "#enums/ui-theme"; import { UiTheme } from "#enums/ui-theme";
import { getPokemonNameWithAffix } from "#app/messages"; import { getPokemonNameWithAffix } from "#app/messages";
@ -154,7 +154,7 @@ export default class BattleFlyout extends Phaser.GameObjects.Container {
/** Updates all of the {@linkcode MoveInfo} objects in the moveInfo array */ /** Updates all of the {@linkcode MoveInfo} objects in the moveInfo array */
private onMoveUsed(event: Event) { private onMoveUsed(event: Event) {
const moveUsedEvent = event as MoveUsedEvent; const moveUsedEvent = event as MoveUsedEvent;
if (!moveUsedEvent || moveUsedEvent.pokemonId !== this.pokemon?.id || moveUsedEvent.move.id === Moves.STRUGGLE) { if (!moveUsedEvent || moveUsedEvent.pokemonId !== this.pokemon?.id || moveUsedEvent.move.id === MoveId.STRUGGLE) {
// Ignore Struggle // Ignore Struggle
return; return;
} }

View File

@ -25,7 +25,7 @@ import { applyChallenges, ChallengeType } from "#app/data/challenge";
import MoveInfoOverlay from "#app/ui/move-info-overlay"; import MoveInfoOverlay from "#app/ui/move-info-overlay";
import i18next from "i18next"; import i18next from "i18next";
import type BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext"; import type BBCodeText from "phaser3-rex-plugins/plugins/bbcodetext";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { getPokemonNameWithAffix } from "#app/messages"; import { getPokemonNameWithAffix } from "#app/messages";
import type { CommandPhase } from "#app/phases/command-phase"; import type { CommandPhase } from "#app/phases/command-phase";
@ -184,7 +184,7 @@ export default class PartyUiHandler extends MessageUiHandler {
private selectCallback: PartySelectCallback | PartyModifierTransferSelectCallback | null; private selectCallback: PartySelectCallback | PartyModifierTransferSelectCallback | null;
private selectFilter: PokemonSelectFilter | PokemonModifierTransferSelectFilter; private selectFilter: PokemonSelectFilter | PokemonModifierTransferSelectFilter;
private moveSelectFilter: PokemonMoveSelectFilter; private moveSelectFilter: PokemonMoveSelectFilter;
private tmMoveId: Moves; private tmMoveId: MoveId;
private showMovePp: boolean; private showMovePp: boolean;
private iconAnimHandler: PokemonIconAnimHandler; private iconAnimHandler: PokemonIconAnimHandler;
@ -346,7 +346,7 @@ export default class PartyUiHandler extends MessageUiHandler {
args.length > 4 && args[4] instanceof Function args.length > 4 && args[4] instanceof Function
? (args[4] as PokemonMoveSelectFilter) ? (args[4] as PokemonMoveSelectFilter)
: PartyUiHandler.FilterAllMoves; : PartyUiHandler.FilterAllMoves;
this.tmMoveId = args.length > 5 && args[5] ? args[5] : Moves.NONE; this.tmMoveId = args.length > 5 && args[5] ? args[5] : MoveId.NONE;
this.showMovePp = args.length > 6 && args[6]; this.showMovePp = args.length > 6 && args[6];
this.partyContainer.setVisible(true); this.partyContainer.setVisible(true);
@ -1165,8 +1165,7 @@ export default class PartyUiHandler extends MessageUiHandler {
this.partyUiMode !== PartyUiMode.FAINT_SWITCH && this.partyUiMode !== PartyUiMode.FAINT_SWITCH &&
globalScene.findModifier( globalScene.findModifier(
m => m =>
m instanceof SwitchEffectTransferModifier && m instanceof SwitchEffectTransferModifier && m.pokemonId === globalScene.getPlayerField()[this.fieldIndex].id,
m.pokemonId === globalScene.getPlayerField()[this.fieldIndex].id,
) )
); );
} }
@ -1654,7 +1653,7 @@ class PartySlot extends Phaser.GameObjects.Container {
pokemon: PlayerPokemon, pokemon: PlayerPokemon,
iconAnimHandler: PokemonIconAnimHandler, iconAnimHandler: PokemonIconAnimHandler,
partyUiMode: PartyUiMode, partyUiMode: PartyUiMode,
tmMoveId: Moves, tmMoveId: MoveId,
) { ) {
super( super(
globalScene, globalScene,
@ -1677,7 +1676,7 @@ class PartySlot extends Phaser.GameObjects.Container {
return this.pokemon; return this.pokemon;
} }
setup(partyUiMode: PartyUiMode, tmMoveId: Moves) { setup(partyUiMode: PartyUiMode, tmMoveId: MoveId) {
const currentLanguage = i18next.resolvedLanguage ?? "en"; const currentLanguage = i18next.resolvedLanguage ?? "en";
const offsetJa = currentLanguage === "ja"; const offsetJa = currentLanguage === "ja";

View File

@ -36,7 +36,7 @@ import MoveInfoOverlay from "#app/ui/move-info-overlay";
import PokedexInfoOverlay from "#app/ui/pokedex-info-overlay"; import PokedexInfoOverlay from "#app/ui/pokedex-info-overlay";
import { getEggTierForSpecies } from "#app/data/egg"; import { getEggTierForSpecies } from "#app/data/egg";
import { Device } from "#enums/devices"; import { Device } from "#enums/devices";
import type { Moves } from "#enums/moves"; import type { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { Button } from "#enums/buttons"; import { Button } from "#enums/buttons";
import { EggSourceType } from "#enums/egg-source-types"; import { EggSourceType } from "#enums/egg-source-types";
@ -205,9 +205,9 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
private formIndex: number; private formIndex: number;
private speciesLoaded: Map<Species, boolean> = new Map<Species, boolean>(); private speciesLoaded: Map<Species, boolean> = new Map<Species, boolean>();
private levelMoves: LevelMoves; private levelMoves: LevelMoves;
private eggMoves: Moves[] = []; private eggMoves: MoveId[] = [];
private hasEggMoves: boolean[] = []; private hasEggMoves: boolean[] = [];
private tmMoves: Moves[] = []; private tmMoves: MoveId[] = [];
private ability1: AbilityId; private ability1: AbilityId;
private ability2: AbilityId | undefined; private ability2: AbilityId | undefined;
private abilityHidden: AbilityId | undefined; private abilityHidden: AbilityId | undefined;

View File

@ -47,7 +47,7 @@ import { applyChallenges, ChallengeType } from "#app/data/challenge";
import MoveInfoOverlay from "#app/ui/move-info-overlay"; import MoveInfoOverlay from "#app/ui/move-info-overlay";
import { getEggTierForSpecies } from "#app/data/egg"; import { getEggTierForSpecies } from "#app/data/egg";
import { Device } from "#enums/devices"; import { Device } from "#enums/devices";
import type { Moves } from "#enums/moves"; import type { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { Button } from "#enums/buttons"; import { Button } from "#enums/buttons";
import { EggSourceType } from "#enums/egg-source-types"; import { EggSourceType } from "#enums/egg-source-types";
@ -365,7 +365,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
private starterTeras: PokemonType[] = []; private starterTeras: PokemonType[] = [];
private starterMovesets: StarterMoveset[] = []; private starterMovesets: StarterMoveset[] = [];
private speciesStarterDexEntry: DexEntry | null; private speciesStarterDexEntry: DexEntry | null;
private speciesStarterMoves: Moves[]; private speciesStarterMoves: MoveId[];
private canCycleShiny: boolean; private canCycleShiny: boolean;
private canCycleForm: boolean; private canCycleForm: boolean;
private canCycleGender: boolean; private canCycleGender: boolean;
@ -1970,7 +1970,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
ui.setModeWithoutClear(UiMode.OPTION_SELECT, { ui.setModeWithoutClear(UiMode.OPTION_SELECT, {
options: moveset options: moveset
.map((m: Moves, i: number) => { .map((m: MoveId, i: number) => {
const option: OptionSelectItem = { const option: OptionSelectItem = {
label: allMoves[m].name, label: allMoves[m].name,
handler: () => { handler: () => {
@ -1980,7 +1980,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
`${i18next.t("starterSelectUiHandler:selectMoveSwapWith")} ${allMoves[m].name}.`, `${i18next.t("starterSelectUiHandler:selectMoveSwapWith")} ${allMoves[m].name}.`,
null, null,
() => { () => {
const possibleMoves = this.speciesStarterMoves.filter((sm: Moves) => sm !== m); const possibleMoves = this.speciesStarterMoves.filter((sm: MoveId) => sm !== m);
this.moveInfoOverlay.show(allMoves[possibleMoves[0]]); this.moveInfoOverlay.show(allMoves[possibleMoves[0]]);
ui.setModeWithoutClear(UiMode.OPTION_SELECT, { ui.setModeWithoutClear(UiMode.OPTION_SELECT, {
@ -2765,7 +2765,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
this.checkIconId(this.starterIcons[index], species, props.female, props.formIndex, props.shiny, props.variant); this.checkIconId(this.starterIcons[index], species, props.female, props.formIndex, props.shiny, props.variant);
} }
switchMoveHandler(i: number, newMove: Moves, move: Moves) { switchMoveHandler(i: number, newMove: MoveId, move: MoveId) {
const speciesId = this.lastSpecies.speciesId; const speciesId = this.lastSpecies.speciesId;
const existingMoveIndex = this.starterMoveset?.indexOf(newMove)!; // TODO: is this bang correct? const existingMoveIndex = this.starterMoveset?.indexOf(newMove)!; // TODO: is this bang correct?
this.starterMoveset![i] = newMove; // TODO: is this bang correct? this.starterMoveset![i] = newMove; // TODO: is this bang correct?

View File

@ -4,7 +4,7 @@ import UiHandler from "./ui-handler";
import { isNullOrUndefined, fixedInt } from "#app/utils/common"; import { isNullOrUndefined, fixedInt } from "#app/utils/common";
import { getMoveTargets } from "../data/moves/move"; import { getMoveTargets } from "../data/moves/move";
import { Button } from "#enums/buttons"; import { Button } from "#enums/buttons";
import type { Moves } from "#enums/moves"; import type { MoveId } from "#enums/moves";
import type Pokemon from "#app/field/pokemon"; import type Pokemon from "#app/field/pokemon";
import type { ModifierBar } from "#app/modifier/modifier"; import type { ModifierBar } from "#app/modifier/modifier";
import { SubstituteTag } from "#app/data/battler-tags"; import { SubstituteTag } from "#app/data/battler-tags";
@ -14,7 +14,7 @@ export type TargetSelectCallback = (targets: BattlerIndex[]) => void;
export default class TargetSelectUiHandler extends UiHandler { export default class TargetSelectUiHandler extends UiHandler {
private fieldIndex: number; private fieldIndex: number;
private move: Moves; private move: MoveId;
private targetSelectCallback: TargetSelectCallback; private targetSelectCallback: TargetSelectCallback;
private cursor0: number; // associated with BattlerIndex.PLAYER private cursor0: number; // associated with BattlerIndex.PLAYER
private cursor1: number; // associated with BattlerIndex.PLAYER_2 private cursor1: number; // associated with BattlerIndex.PLAYER_2
@ -42,7 +42,7 @@ export default class TargetSelectUiHandler extends UiHandler {
super.show(args); super.show(args);
this.fieldIndex = args[0] as number; this.fieldIndex = args[0] as number;
this.move = args[1] as Moves; this.move = args[1] as MoveId;
this.targetSelectCallback = args[2] as TargetSelectCallback; this.targetSelectCallback = args[2] as TargetSelectCallback;
const user = globalScene.getPlayerField()[this.fieldIndex]; const user = globalScene.getPlayerField()[this.fieldIndex];

View File

@ -1,5 +1,5 @@
import { MoneyFormat } from "#enums/money-format"; import { MoneyFormat } from "#enums/money-format";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import i18next from "i18next"; import i18next from "i18next";
import { pokerogueApi } from "#app/plugins/api/pokerogue-api"; import { pokerogueApi } from "#app/plugins/api/pokerogue-api";
import type { Variant } from "#app/sprites/variant"; import type { Variant } from "#app/sprites/variant";
@ -567,8 +567,8 @@ export function isBetween(num: number, min: number, max: number): boolean {
* *
* @param move the move for which the animation filename is needed * @param move the move for which the animation filename is needed
*/ */
export function animationFileName(move: Moves): string { export function animationFileName(move: MoveId): string {
return Moves[move].toLowerCase().replace(/\_/g, "-"); return MoveId[move].toLowerCase().replace(/\_/g, "-");
} }
/** /**

View File

@ -1,6 +1,6 @@
import { Stat } from "#app/enums/stat"; import { Stat } from "#app/enums/stat";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
@ -23,11 +23,11 @@ describe("Ability Duplication", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.moveset([Moves.SPLASH]) .moveset([MoveId.SPLASH])
.battleStyle("single") .battleStyle("single")
.ability(AbilityId.HUGE_POWER) .ability(AbilityId.HUGE_POWER)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(MoveId.SPLASH);
}); });
it("huge power should only be applied once if both normal and passive", async () => { it("huge power should only be applied once if both normal and passive", async () => {

View File

@ -1,7 +1,7 @@
import { BattlerIndex } from "#app/battle"; import { BattlerIndex } from "#app/battle";
import { isBetween, toDmgValue } from "#app/utils/common"; import { isBetween, toDmgValue } from "#app/utils/common";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
@ -24,7 +24,7 @@ describe("Abilities - Analytic", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.moveset([Moves.SPLASH, Moves.TACKLE]) .moveset([MoveId.SPLASH, MoveId.TACKLE])
.ability(AbilityId.ANALYTIC) .ability(AbilityId.ANALYTIC)
.battleStyle("single") .battleStyle("single")
.disableCrits() .disableCrits()
@ -32,7 +32,7 @@ describe("Abilities - Analytic", () => {
.enemyLevel(200) .enemyLevel(200)
.enemySpecies(Species.SNORLAX) .enemySpecies(Species.SNORLAX)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(MoveId.SPLASH);
}); });
it("should increase damage if the user moves last", async () => { it("should increase damage if the user moves last", async () => {
@ -40,13 +40,13 @@ describe("Abilities - Analytic", () => {
const enemy = game.scene.getEnemyPokemon()!; const enemy = game.scene.getEnemyPokemon()!;
game.move.select(Moves.TACKLE); game.move.select(MoveId.TACKLE);
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
await game.toNextTurn(); await game.toNextTurn();
const damage1 = enemy.getInverseHp(); const damage1 = enemy.getInverseHp();
enemy.hp = enemy.getMaxHp(); enemy.hp = enemy.getMaxHp();
game.move.select(Moves.TACKLE); game.move.select(MoveId.TACKLE);
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(isBetween(enemy.getInverseHp(), toDmgValue(damage1 * 1.3) - 3, toDmgValue(damage1 * 1.3) + 3)).toBe(true); expect(isBetween(enemy.getInverseHp(), toDmgValue(damage1 * 1.3) - 3, toDmgValue(damage1 * 1.3) + 3)).toBe(true);
@ -58,22 +58,22 @@ describe("Abilities - Analytic", () => {
const [enemy] = game.scene.getEnemyField(); const [enemy] = game.scene.getEnemyField();
game.move.select(Moves.TACKLE, 0, BattlerIndex.ENEMY); game.move.select(MoveId.TACKLE, 0, BattlerIndex.ENEMY);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]);
await game.toNextTurn(); await game.toNextTurn();
const damage1 = enemy.getInverseHp(); const damage1 = enemy.getInverseHp();
enemy.hp = enemy.getMaxHp(); enemy.hp = enemy.getMaxHp();
game.move.select(Moves.TACKLE, 0, BattlerIndex.ENEMY); game.move.select(MoveId.TACKLE, 0, BattlerIndex.ENEMY);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.setTurnOrder([BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER]); await game.setTurnOrder([BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER]);
await game.toNextTurn(); await game.toNextTurn();
expect(isBetween(enemy.getInverseHp(), toDmgValue(damage1 * 1.3) - 3, toDmgValue(damage1 * 1.3) + 3)).toBe(true); expect(isBetween(enemy.getInverseHp(), toDmgValue(damage1 * 1.3) - 3, toDmgValue(damage1 * 1.3) + 3)).toBe(true);
enemy.hp = enemy.getMaxHp(); enemy.hp = enemy.getMaxHp();
game.move.select(Moves.TACKLE, 0, BattlerIndex.ENEMY); game.move.select(MoveId.TACKLE, 0, BattlerIndex.ENEMY);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.setTurnOrder([BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2]); await game.setTurnOrder([BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2]);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(enemy.getInverseHp()).toBe(damage1); expect(enemy.getInverseHp()).toBe(damage1);

View File

@ -1,6 +1,6 @@
import { allAbilities } from "#app/data/data-lists"; import { allAbilities } from "#app/data/data-lists";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
@ -23,11 +23,11 @@ describe("Abilities - Arena Trap", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.moveset(Moves.SPLASH) .moveset(MoveId.SPLASH)
.ability(AbilityId.ARENA_TRAP) .ability(AbilityId.ARENA_TRAP)
.enemySpecies(Species.RALTS) .enemySpecies(Species.RALTS)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.TELEPORT); .enemyMoveset(MoveId.TELEPORT);
}); });
// TODO: Enable test when Issue #935 is addressed // TODO: Enable test when Issue #935 is addressed
@ -38,7 +38,7 @@ describe("Abilities - Arena Trap", () => {
const enemy = game.scene.getEnemyPokemon(); const enemy = game.scene.getEnemyPokemon();
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
@ -55,15 +55,15 @@ describe("Abilities - Arena Trap", () => {
/** /**
* This checks if the Player Pokemon is able to switch out/run away after the Enemy Pokemon with {@linkcode AbilityId.ARENA_TRAP} * This checks if the Player Pokemon is able to switch out/run away after the Enemy Pokemon with {@linkcode AbilityId.ARENA_TRAP}
* is forcefully moved out of the field from moves such as Roar {@linkcode Moves.ROAR} * is forcefully moved out of the field from moves such as Roar {@linkcode MoveId.ROAR}
* *
* Note: It should be able to switch out/run away * Note: It should be able to switch out/run away
*/ */
it("should lift if pokemon with this ability leaves the field", async () => { it("should lift if pokemon with this ability leaves the field", async () => {
game.override game.override
.battleStyle("double") .battleStyle("double")
.enemyMoveset(Moves.SPLASH) .enemyMoveset(MoveId.SPLASH)
.moveset([Moves.ROAR, Moves.SPLASH]) .moveset([MoveId.ROAR, MoveId.SPLASH])
.ability(AbilityId.BALL_FETCH); .ability(AbilityId.BALL_FETCH);
await game.classicMode.startBattle([Species.MAGIKARP, Species.SUDOWOODO, Species.LUNATONE]); await game.classicMode.startBattle([Species.MAGIKARP, Species.SUDOWOODO, Species.LUNATONE]);
@ -72,14 +72,14 @@ describe("Abilities - Arena Trap", () => {
vi.spyOn(enemy1, "getAbility").mockReturnValue(allAbilities[AbilityId.ARENA_TRAP]); vi.spyOn(enemy1, "getAbility").mockReturnValue(allAbilities[AbilityId.ARENA_TRAP]);
game.move.select(Moves.ROAR); game.move.select(MoveId.ROAR);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
// This runs the fist command phase where the moves are selected // This runs the fist command phase where the moves are selected
await game.toNextTurn(); await game.toNextTurn();
// During the next command phase the player pokemons should not be trapped anymore // During the next command phase the player pokemons should not be trapped anymore
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.toNextTurn(); await game.toNextTurn();
expect(player1.isTrapped()).toBe(false); expect(player1.isTrapped()).toBe(false);

View File

@ -1,4 +1,4 @@
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
@ -27,10 +27,10 @@ describe("Moves - Aroma Veil", () => {
game.override game.override
.battleStyle("double") .battleStyle("double")
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset([Moves.HEAL_BLOCK, Moves.IMPRISON, Moves.SPLASH]) .enemyMoveset([MoveId.HEAL_BLOCK, MoveId.IMPRISON, MoveId.SPLASH])
.enemySpecies(Species.SHUCKLE) .enemySpecies(Species.SHUCKLE)
.ability(AbilityId.AROMA_VEIL) .ability(AbilityId.AROMA_VEIL)
.moveset([Moves.GROWL]); .moveset([MoveId.GROWL]);
}); });
it("Aroma Veil protects the Pokemon's side against most Move Restriction Battler Tags", async () => { it("Aroma Veil protects the Pokemon's side against most Move Restriction Battler Tags", async () => {
@ -38,9 +38,9 @@ describe("Moves - Aroma Veil", () => {
const party = game.scene.getPlayerParty()! as PlayerPokemon[]; const party = game.scene.getPlayerParty()! as PlayerPokemon[];
game.move.select(Moves.GROWL); game.move.select(MoveId.GROWL);
game.move.select(Moves.GROWL); game.move.select(MoveId.GROWL);
await game.move.selectEnemyMove(Moves.HEAL_BLOCK); await game.move.selectEnemyMove(MoveId.HEAL_BLOCK);
await game.toNextTurn(); await game.toNextTurn();
party.forEach(p => { party.forEach(p => {
expect(p.getTag(BattlerTagType.HEAL_BLOCK)).toBeUndefined(); expect(p.getTag(BattlerTagType.HEAL_BLOCK)).toBeUndefined();
@ -52,10 +52,10 @@ describe("Moves - Aroma Veil", () => {
const party = game.scene.getPlayerParty()! as PlayerPokemon[]; const party = game.scene.getPlayerParty()! as PlayerPokemon[];
game.move.select(Moves.GROWL); game.move.select(MoveId.GROWL);
game.move.select(Moves.GROWL, 1); game.move.select(MoveId.GROWL, 1);
await game.move.selectEnemyMove(Moves.IMPRISON, BattlerIndex.PLAYER); await game.move.selectEnemyMove(MoveId.IMPRISON, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(Moves.SPLASH); await game.move.selectEnemyMove(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
expect(game.scene.arena.getTag(ArenaTagType.IMPRISON)).toBeDefined(); expect(game.scene.arena.getTag(ArenaTagType.IMPRISON)).toBeDefined();
party.forEach(p => { party.forEach(p => {

View File

@ -1,6 +1,6 @@
import { allMoves } from "#app/data/data-lists"; import { allMoves } from "#app/data/data-lists";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
@ -26,49 +26,49 @@ describe("Abilities - Aura Break", () => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.battleStyle("single") .battleStyle("single")
.moveset([Moves.MOONBLAST, Moves.DARK_PULSE]) .moveset([MoveId.MOONBLAST, MoveId.DARK_PULSE])
.enemyMoveset(Moves.SPLASH) .enemyMoveset(MoveId.SPLASH)
.enemyAbility(AbilityId.AURA_BREAK) .enemyAbility(AbilityId.AURA_BREAK)
.enemySpecies(Species.SHUCKLE); .enemySpecies(Species.SHUCKLE);
}); });
it("reverses the effect of Fairy Aura", async () => { it("reverses the effect of Fairy Aura", async () => {
const moveToCheck = allMoves[Moves.MOONBLAST]; const moveToCheck = allMoves[MoveId.MOONBLAST];
const basePower = moveToCheck.power; const basePower = moveToCheck.power;
game.override.ability(AbilityId.FAIRY_AURA); game.override.ability(AbilityId.FAIRY_AURA);
vi.spyOn(moveToCheck, "calculateBattlePower"); vi.spyOn(moveToCheck, "calculateBattlePower");
await game.classicMode.startBattle([Species.PIKACHU]); await game.classicMode.startBattle([Species.PIKACHU]);
game.move.select(Moves.MOONBLAST); game.move.select(MoveId.MOONBLAST);
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");
expect(moveToCheck.calculateBattlePower).toHaveReturnedWith(expect.closeTo(basePower * auraBreakMultiplier)); expect(moveToCheck.calculateBattlePower).toHaveReturnedWith(expect.closeTo(basePower * auraBreakMultiplier));
}); });
it("reverses the effect of Dark Aura", async () => { it("reverses the effect of Dark Aura", async () => {
const moveToCheck = allMoves[Moves.DARK_PULSE]; const moveToCheck = allMoves[MoveId.DARK_PULSE];
const basePower = moveToCheck.power; const basePower = moveToCheck.power;
game.override.ability(AbilityId.DARK_AURA); game.override.ability(AbilityId.DARK_AURA);
vi.spyOn(moveToCheck, "calculateBattlePower"); vi.spyOn(moveToCheck, "calculateBattlePower");
await game.classicMode.startBattle([Species.PIKACHU]); await game.classicMode.startBattle([Species.PIKACHU]);
game.move.select(Moves.DARK_PULSE); game.move.select(MoveId.DARK_PULSE);
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");
expect(moveToCheck.calculateBattlePower).toHaveReturnedWith(expect.closeTo(basePower * auraBreakMultiplier)); expect(moveToCheck.calculateBattlePower).toHaveReturnedWith(expect.closeTo(basePower * auraBreakMultiplier));
}); });
it("has no effect if neither Fairy Aura nor Dark Aura are present", async () => { it("has no effect if neither Fairy Aura nor Dark Aura are present", async () => {
const moveToCheck = allMoves[Moves.MOONBLAST]; const moveToCheck = allMoves[MoveId.MOONBLAST];
const basePower = moveToCheck.power; const basePower = moveToCheck.power;
game.override.ability(AbilityId.BALL_FETCH); game.override.ability(AbilityId.BALL_FETCH);
vi.spyOn(moveToCheck, "calculateBattlePower"); vi.spyOn(moveToCheck, "calculateBattlePower");
await game.classicMode.startBattle([Species.PIKACHU]); await game.classicMode.startBattle([Species.PIKACHU]);
game.move.select(Moves.MOONBLAST); game.move.select(MoveId.MOONBLAST);
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");
expect(moveToCheck.calculateBattlePower).toHaveReturnedWith(basePower); expect(moveToCheck.calculateBattlePower).toHaveReturnedWith(basePower);

View File

@ -2,7 +2,7 @@ import { allMoves } from "#app/data/data-lists";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { MoveEffectPhase } from "#app/phases/move-effect-phase"; import { MoveEffectPhase } from "#app/phases/move-effect-phase";
import { TurnEndPhase } from "#app/phases/turn-end-phase"; import { TurnEndPhase } from "#app/phases/turn-end-phase";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
@ -29,50 +29,50 @@ describe("Abilities - Battery", () => {
game.override.battleStyle("double"); game.override.battleStyle("double");
game.override.enemySpecies(Species.SHUCKLE); game.override.enemySpecies(Species.SHUCKLE);
game.override.enemyAbility(AbilityId.BALL_FETCH); game.override.enemyAbility(AbilityId.BALL_FETCH);
game.override.moveset([Moves.TACKLE, Moves.BREAKING_SWIPE, Moves.SPLASH, Moves.DAZZLING_GLEAM]); game.override.moveset([MoveId.TACKLE, MoveId.BREAKING_SWIPE, MoveId.SPLASH, MoveId.DAZZLING_GLEAM]);
game.override.enemyMoveset(Moves.SPLASH); game.override.enemyMoveset(MoveId.SPLASH);
}); });
it("raises the power of allies' special moves by 30%", async () => { it("raises the power of allies' special moves by 30%", async () => {
const moveToCheck = allMoves[Moves.DAZZLING_GLEAM]; const moveToCheck = allMoves[MoveId.DAZZLING_GLEAM];
const basePower = moveToCheck.power; const basePower = moveToCheck.power;
vi.spyOn(moveToCheck, "calculateBattlePower"); vi.spyOn(moveToCheck, "calculateBattlePower");
await game.classicMode.startBattle([Species.PIKACHU, Species.CHARJABUG]); await game.classicMode.startBattle([Species.PIKACHU, Species.CHARJABUG]);
game.move.select(Moves.DAZZLING_GLEAM); game.move.select(MoveId.DAZZLING_GLEAM);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to(MoveEffectPhase); await game.phaseInterceptor.to(MoveEffectPhase);
expect(moveToCheck.calculateBattlePower).toHaveReturnedWith(basePower * batteryMultiplier); expect(moveToCheck.calculateBattlePower).toHaveReturnedWith(basePower * batteryMultiplier);
}); });
it("does not raise the power of allies' non-special moves", async () => { it("does not raise the power of allies' non-special moves", async () => {
const moveToCheck = allMoves[Moves.BREAKING_SWIPE]; const moveToCheck = allMoves[MoveId.BREAKING_SWIPE];
const basePower = moveToCheck.power; const basePower = moveToCheck.power;
vi.spyOn(moveToCheck, "calculateBattlePower"); vi.spyOn(moveToCheck, "calculateBattlePower");
await game.classicMode.startBattle([Species.PIKACHU, Species.CHARJABUG]); await game.classicMode.startBattle([Species.PIKACHU, Species.CHARJABUG]);
game.move.select(Moves.BREAKING_SWIPE); game.move.select(MoveId.BREAKING_SWIPE);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to(MoveEffectPhase); await game.phaseInterceptor.to(MoveEffectPhase);
expect(moveToCheck.calculateBattlePower).toHaveReturnedWith(basePower); expect(moveToCheck.calculateBattlePower).toHaveReturnedWith(basePower);
}); });
it("does not raise the power of the ability owner's special moves", async () => { it("does not raise the power of the ability owner's special moves", async () => {
const moveToCheck = allMoves[Moves.DAZZLING_GLEAM]; const moveToCheck = allMoves[MoveId.DAZZLING_GLEAM];
const basePower = moveToCheck.power; const basePower = moveToCheck.power;
vi.spyOn(moveToCheck, "calculateBattlePower"); vi.spyOn(moveToCheck, "calculateBattlePower");
await game.classicMode.startBattle([Species.CHARJABUG, Species.PIKACHU]); await game.classicMode.startBattle([Species.CHARJABUG, Species.PIKACHU]);
game.move.select(Moves.DAZZLING_GLEAM); game.move.select(MoveId.DAZZLING_GLEAM);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
expect(moveToCheck.calculateBattlePower).toHaveReturnedWith(basePower); expect(moveToCheck.calculateBattlePower).toHaveReturnedWith(basePower);

View File

@ -3,7 +3,7 @@ import { allMoves } from "#app/data/data-lists";
import { MultiHitType } from "#enums/MultiHitType"; import { MultiHitType } from "#enums/MultiHitType";
import { Status } from "#app/data/status-effect"; import { Status } from "#app/data/status-effect";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { StatusEffect } from "#enums/status-effect"; import { StatusEffect } from "#enums/status-effect";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
@ -33,9 +33,9 @@ describe("Abilities - BATTLE BOND", () => {
.startingWave(4) // Leads to arena reset on Wave 5 trainer battle .startingWave(4) // Leads to arena reset on Wave 5 trainer battle
.ability(AbilityId.BATTLE_BOND) .ability(AbilityId.BATTLE_BOND)
.starterForms({ [Species.GRENINJA]: ashForm }) .starterForms({ [Species.GRENINJA]: ashForm })
.moveset([Moves.SPLASH, Moves.WATER_SHURIKEN]) .moveset([MoveId.SPLASH, MoveId.WATER_SHURIKEN])
.enemySpecies(Species.BULBASAUR) .enemySpecies(Species.BULBASAUR)
.enemyMoveset(Moves.SPLASH) .enemyMoveset(MoveId.SPLASH)
.startingLevel(100) // Avoid levelling up .startingLevel(100) // Avoid levelling up
.enemyLevel(1000); // Avoid opponent dying before `doKillOpponents()` .enemyLevel(1000); // Avoid opponent dying before `doKillOpponents()`
}); });
@ -50,7 +50,7 @@ describe("Abilities - BATTLE BOND", () => {
greninja.status = new Status(StatusEffect.FAINT); greninja.status = new Status(StatusEffect.FAINT);
expect(greninja.isFainted()).toBe(true); expect(greninja.isFainted()).toBe(true);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.doKillOpponents(); await game.doKillOpponents();
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
game.doSelectModifier(); game.doSelectModifier();
@ -62,7 +62,7 @@ describe("Abilities - BATTLE BOND", () => {
it("should not keep buffing Water Shuriken after Greninja switches to base form", async () => { it("should not keep buffing Water Shuriken after Greninja switches to base form", async () => {
await game.classicMode.startBattle([Species.GRENINJA]); await game.classicMode.startBattle([Species.GRENINJA]);
const waterShuriken = allMoves[Moves.WATER_SHURIKEN]; const waterShuriken = allMoves[MoveId.WATER_SHURIKEN];
vi.spyOn(waterShuriken, "calculateBattlePower"); vi.spyOn(waterShuriken, "calculateBattlePower");
let actualMultiHitType: MultiHitType | null = null; let actualMultiHitType: MultiHitType | null = null;
@ -76,7 +76,7 @@ describe("Abilities - BATTLE BOND", () => {
let expectedBattlePower = 20; let expectedBattlePower = 20;
let expectedMultiHitType = MultiHitType._3; let expectedMultiHitType = MultiHitType._3;
game.move.select(Moves.WATER_SHURIKEN); game.move.select(MoveId.WATER_SHURIKEN);
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(waterShuriken.calculateBattlePower).toHaveLastReturnedWith(expectedBattlePower); expect(waterShuriken.calculateBattlePower).toHaveLastReturnedWith(expectedBattlePower);
expect(actualMultiHitType).toBe(expectedMultiHitType); expect(actualMultiHitType).toBe(expectedMultiHitType);
@ -88,7 +88,7 @@ describe("Abilities - BATTLE BOND", () => {
expectedBattlePower = 15; expectedBattlePower = 15;
expectedMultiHitType = MultiHitType._2_TO_5; expectedMultiHitType = MultiHitType._2_TO_5;
game.move.select(Moves.WATER_SHURIKEN); game.move.select(MoveId.WATER_SHURIKEN);
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(waterShuriken.calculateBattlePower).toHaveLastReturnedWith(expectedBattlePower); expect(waterShuriken.calculateBattlePower).toHaveLastReturnedWith(expectedBattlePower);
expect(actualMultiHitType).toBe(expectedMultiHitType); expect(actualMultiHitType).toBe(expectedMultiHitType);

View File

@ -1,6 +1,6 @@
import { BattlerIndex } from "#app/battle"; import { BattlerIndex } from "#app/battle";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
@ -29,8 +29,8 @@ describe("Abilities - Beast Boost", () => {
.enemyAbility(AbilityId.BEAST_BOOST) .enemyAbility(AbilityId.BEAST_BOOST)
.ability(AbilityId.BEAST_BOOST) .ability(AbilityId.BEAST_BOOST)
.startingLevel(2000) .startingLevel(2000)
.moveset([Moves.FLAMETHROWER]) .moveset([MoveId.FLAMETHROWER])
.enemyMoveset(Moves.SPLASH); .enemyMoveset(MoveId.SPLASH);
}); });
it("should prefer highest stat to boost its corresponding stat stage by 1 when winning a battle", async () => { it("should prefer highest stat to boost its corresponding stat stage by 1 when winning a battle", async () => {
@ -43,14 +43,14 @@ describe("Abilities - Beast Boost", () => {
expect(playerPokemon.getStatStage(Stat.DEF)).toBe(0); expect(playerPokemon.getStatStage(Stat.DEF)).toBe(0);
game.move.select(Moves.FLAMETHROWER); game.move.select(MoveId.FLAMETHROWER);
await game.phaseInterceptor.to("VictoryPhase"); await game.phaseInterceptor.to("VictoryPhase");
expect(playerPokemon.getStatStage(Stat.DEF)).toBe(1); expect(playerPokemon.getStatStage(Stat.DEF)).toBe(1);
}, 20000); }, 20000);
it("should use in-battle overriden stats when determining the stat stage to raise by 1", async () => { it("should use in-battle overriden stats when determining the stat stage to raise by 1", async () => {
game.override.enemyMoveset([Moves.GUARD_SPLIT]); game.override.enemyMoveset([MoveId.GUARD_SPLIT]);
await game.classicMode.startBattle([Species.SLOWBRO]); await game.classicMode.startBattle([Species.SLOWBRO]);
@ -60,7 +60,7 @@ describe("Abilities - Beast Boost", () => {
expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(0); expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(0);
game.move.select(Moves.FLAMETHROWER); game.move.select(MoveId.FLAMETHROWER);
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
await game.phaseInterceptor.to("VictoryPhase"); await game.phaseInterceptor.to("VictoryPhase");
@ -79,7 +79,7 @@ describe("Abilities - Beast Boost", () => {
expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(0); expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(0);
game.move.select(Moves.FLAMETHROWER); game.move.select(MoveId.FLAMETHROWER);
await game.phaseInterceptor.to("VictoryPhase"); await game.phaseInterceptor.to("VictoryPhase");

View File

@ -7,7 +7,7 @@ import { StatusEffect } from "#enums/status-effect";
import { WeatherType } from "#enums/weather-type"; import { WeatherType } from "#enums/weather-type";
import { MoveResult } from "#app/field/pokemon"; import { MoveResult } from "#app/field/pokemon";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
@ -32,13 +32,13 @@ describe("Abilities - Commander", () => {
game.override game.override
.startingLevel(100) .startingLevel(100)
.enemyLevel(100) .enemyLevel(100)
.moveset([Moves.LIQUIDATION, Moves.MEMENTO, Moves.SPLASH, Moves.FLIP_TURN]) .moveset([MoveId.LIQUIDATION, MoveId.MEMENTO, MoveId.SPLASH, MoveId.FLIP_TURN])
.ability(AbilityId.COMMANDER) .ability(AbilityId.COMMANDER)
.battleStyle("double") .battleStyle("double")
.disableCrits() .disableCrits()
.enemySpecies(Species.SNORLAX) .enemySpecies(Species.SNORLAX)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.TACKLE); .enemyMoveset(MoveId.TACKLE);
vi.spyOn(game.scene, "triggerPokemonBattleAnim").mockReturnValue(true); vi.spyOn(game.scene, "triggerPokemonBattleAnim").mockReturnValue(true);
}); });
@ -54,13 +54,13 @@ describe("Abilities - Commander", () => {
expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined(); expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined();
affectedStats.forEach(stat => expect(dondozo.getStatStage(stat)).toBe(2)); affectedStats.forEach(stat => expect(dondozo.getStatStage(stat)).toBe(2));
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
expect(game.scene.currentBattle.turnCommands[0]?.skip).toBeTruthy(); expect(game.scene.currentBattle.turnCommands[0]?.skip).toBeTruthy();
// Force both enemies to target the Tatsugiri // Force both enemies to target the Tatsugiri
await game.move.selectEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER); await game.move.selectEnemyMove(MoveId.TACKLE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER); await game.move.selectEnemyMove(MoveId.TACKLE, BattlerIndex.PLAYER);
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
game.scene.getEnemyField().forEach(enemy => expect(enemy.getLastXMoves(1)[0].result).toBe(MoveResult.MISS)); game.scene.getEnemyField().forEach(enemy => expect(enemy.getLastXMoves(1)[0].result).toBe(MoveResult.MISS));
@ -68,13 +68,13 @@ describe("Abilities - Commander", () => {
}); });
it("should activate when a Dondozo switches in and cancel the source's move", async () => { it("should activate when a Dondozo switches in and cancel the source's move", async () => {
game.override.enemyMoveset(Moves.SPLASH); game.override.enemyMoveset(MoveId.SPLASH);
await game.classicMode.startBattle([Species.TATSUGIRI, Species.MAGIKARP, Species.DONDOZO]); await game.classicMode.startBattle([Species.TATSUGIRI, Species.MAGIKARP, Species.DONDOZO]);
const tatsugiri = game.scene.getPlayerField()[0]; const tatsugiri = game.scene.getPlayerField()[0];
game.move.select(Moves.LIQUIDATION, 0, BattlerIndex.ENEMY); game.move.select(MoveId.LIQUIDATION, 0, BattlerIndex.ENEMY);
game.doSwitchPokemon(2); game.doSwitchPokemon(2);
await game.phaseInterceptor.to("MovePhase", false); await game.phaseInterceptor.to("MovePhase", false);
@ -96,12 +96,12 @@ describe("Abilities - Commander", () => {
expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY); expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY);
expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined(); expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined();
game.move.select(Moves.MEMENTO, 1, BattlerIndex.ENEMY); game.move.select(MoveId.MEMENTO, 1, BattlerIndex.ENEMY);
expect(game.scene.currentBattle.turnCommands[0]?.skip).toBeTruthy(); expect(game.scene.currentBattle.turnCommands[0]?.skip).toBeTruthy();
await game.move.selectEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER); await game.move.selectEnemyMove(MoveId.TACKLE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER); await game.move.selectEnemyMove(MoveId.TACKLE, BattlerIndex.PLAYER);
await game.setTurnOrder([BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER]); await game.setTurnOrder([BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER]);
@ -114,7 +114,7 @@ describe("Abilities - Commander", () => {
}); });
it("source should still take damage from Poison while hidden", async () => { it("source should still take damage from Poison while hidden", async () => {
game.override.statusEffect(StatusEffect.POISON).enemyMoveset(Moves.SPLASH); game.override.statusEffect(StatusEffect.POISON).enemyMoveset(MoveId.SPLASH);
await game.classicMode.startBattle([Species.TATSUGIRI, Species.DONDOZO]); await game.classicMode.startBattle([Species.TATSUGIRI, Species.DONDOZO]);
@ -123,7 +123,7 @@ describe("Abilities - Commander", () => {
expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY); expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY);
expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined(); expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined();
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
expect(game.scene.currentBattle.turnCommands[0]?.skip).toBeTruthy(); expect(game.scene.currentBattle.turnCommands[0]?.skip).toBeTruthy();
@ -132,7 +132,7 @@ describe("Abilities - Commander", () => {
}); });
it("source should still take damage from Salt Cure while hidden", async () => { it("source should still take damage from Salt Cure while hidden", async () => {
game.override.enemyMoveset(Moves.SPLASH); game.override.enemyMoveset(MoveId.SPLASH);
await game.classicMode.startBattle([Species.TATSUGIRI, Species.DONDOZO]); await game.classicMode.startBattle([Species.TATSUGIRI, Species.DONDOZO]);
@ -141,9 +141,9 @@ describe("Abilities - Commander", () => {
expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY); expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY);
expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined(); expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined();
tatsugiri.addTag(BattlerTagType.SALT_CURED, 0, Moves.NONE, game.scene.getField()[BattlerIndex.ENEMY].id); tatsugiri.addTag(BattlerTagType.SALT_CURED, 0, MoveId.NONE, game.scene.getField()[BattlerIndex.ENEMY].id);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
expect(game.scene.currentBattle.turnCommands[0]?.skip).toBeTruthy(); expect(game.scene.currentBattle.turnCommands[0]?.skip).toBeTruthy();
@ -152,7 +152,7 @@ describe("Abilities - Commander", () => {
}); });
it("source should still take damage from Sandstorm while hidden", async () => { it("source should still take damage from Sandstorm while hidden", async () => {
game.override.weather(WeatherType.SANDSTORM).enemyMoveset(Moves.SPLASH); game.override.weather(WeatherType.SANDSTORM).enemyMoveset(MoveId.SPLASH);
await game.classicMode.startBattle([Species.TATSUGIRI, Species.DONDOZO]); await game.classicMode.startBattle([Species.TATSUGIRI, Species.DONDOZO]);
@ -161,7 +161,7 @@ describe("Abilities - Commander", () => {
expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY); expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY);
expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined(); expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined();
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
expect(game.scene.currentBattle.turnCommands[0]?.skip).toBeTruthy(); expect(game.scene.currentBattle.turnCommands[0]?.skip).toBeTruthy();
@ -170,7 +170,7 @@ describe("Abilities - Commander", () => {
}); });
it("should make Dondozo immune to being forced out", async () => { it("should make Dondozo immune to being forced out", async () => {
game.override.enemyMoveset([Moves.SPLASH, Moves.WHIRLWIND]); game.override.enemyMoveset([MoveId.SPLASH, MoveId.WHIRLWIND]);
await game.classicMode.startBattle([Species.TATSUGIRI, Species.DONDOZO]); await game.classicMode.startBattle([Species.TATSUGIRI, Species.DONDOZO]);
@ -179,12 +179,12 @@ describe("Abilities - Commander", () => {
expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY); expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY);
expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined(); expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined();
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
expect(game.scene.currentBattle.turnCommands[0]?.skip).toBeTruthy(); expect(game.scene.currentBattle.turnCommands[0]?.skip).toBeTruthy();
await game.move.selectEnemyMove(Moves.WHIRLWIND, BattlerIndex.PLAYER_2); await game.move.selectEnemyMove(MoveId.WHIRLWIND, BattlerIndex.PLAYER_2);
await game.move.selectEnemyMove(Moves.SPLASH); await game.move.selectEnemyMove(MoveId.SPLASH);
// Test may time out here if Whirlwind forced out a Pokemon // Test may time out here if Whirlwind forced out a Pokemon
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
@ -192,14 +192,14 @@ describe("Abilities - Commander", () => {
}); });
it("should interrupt the source's semi-invulnerability", async () => { it("should interrupt the source's semi-invulnerability", async () => {
game.override.moveset([Moves.SPLASH, Moves.DIVE]).enemyMoveset(Moves.SPLASH); game.override.moveset([MoveId.SPLASH, MoveId.DIVE]).enemyMoveset(MoveId.SPLASH);
await game.classicMode.startBattle([Species.TATSUGIRI, Species.MAGIKARP, Species.DONDOZO]); await game.classicMode.startBattle([Species.TATSUGIRI, Species.MAGIKARP, Species.DONDOZO]);
const tatsugiri = game.scene.getPlayerField()[0]; const tatsugiri = game.scene.getPlayerField()[0];
game.move.select(Moves.DIVE, 0, BattlerIndex.ENEMY); game.move.select(MoveId.DIVE, 0, BattlerIndex.ENEMY);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("CommandPhase"); await game.phaseInterceptor.to("CommandPhase");
await game.toNextTurn(); await game.toNextTurn();

View File

@ -1,7 +1,7 @@
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import { TurnInitPhase } from "#app/phases/turn-init-phase"; import { TurnInitPhase } from "#app/phases/turn-init-phase";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
@ -27,9 +27,9 @@ describe("Abilities - Competitive", () => {
game.override game.override
.battleStyle("single") .battleStyle("single")
.enemySpecies(Species.BEEDRILL) .enemySpecies(Species.BEEDRILL)
.enemyMoveset(Moves.TICKLE) .enemyMoveset(MoveId.TICKLE)
.startingLevel(1) .startingLevel(1)
.moveset([Moves.SPLASH, Moves.CLOSE_COMBAT]) .moveset([MoveId.SPLASH, MoveId.CLOSE_COMBAT])
.ability(AbilityId.COMPETITIVE); .ability(AbilityId.COMPETITIVE);
}); });
@ -37,7 +37,7 @@ describe("Abilities - Competitive", () => {
await game.classicMode.startBattle([Species.FLYGON]); await game.classicMode.startBattle([Species.FLYGON]);
const playerPokemon = game.scene.getPlayerPokemon()!; const playerPokemon = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnInitPhase); await game.phaseInterceptor.to(TurnInitPhase);
expect(playerPokemon.getStatStage(Stat.ATK)).toBe(-1); expect(playerPokemon.getStatStage(Stat.ATK)).toBe(-1);
@ -46,11 +46,11 @@ describe("Abilities - Competitive", () => {
}); });
it("lowering your own stats should not trigger competitive", async () => { it("lowering your own stats should not trigger competitive", async () => {
game.override.enemyMoveset(Moves.SPLASH); game.override.enemyMoveset(MoveId.SPLASH);
await game.classicMode.startBattle([Species.FLYGON]); await game.classicMode.startBattle([Species.FLYGON]);
const playerPokemon = game.scene.getPlayerPokemon()!; const playerPokemon = game.scene.getPlayerPokemon()!;
game.move.select(Moves.CLOSE_COMBAT); game.move.select(MoveId.CLOSE_COMBAT);
await game.phaseInterceptor.to(TurnInitPhase); await game.phaseInterceptor.to(TurnInitPhase);
expect(playerPokemon.getStatStage(Stat.SPDEF)).toBe(-1); expect(playerPokemon.getStatStage(Stat.SPDEF)).toBe(-1);
@ -63,7 +63,7 @@ describe("Abilities - Competitive", () => {
await game.classicMode.startBattle([Species.FLYGON]); await game.classicMode.startBattle([Species.FLYGON]);
const playerPokemon = game.scene.getPlayerPokemon()!; const playerPokemon = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnInitPhase); await game.phaseInterceptor.to(TurnInitPhase);
expect(playerPokemon.getStatStage(Stat.ATK)).toBe(0); expect(playerPokemon.getStatStage(Stat.ATK)).toBe(0);

View File

@ -1,4 +1,4 @@
import { Moves } from "#app/enums/moves"; import { MoveId } from "#app/enums/moves";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
@ -27,7 +27,7 @@ describe("Abilities - Contrary", () => {
.enemySpecies(Species.BULBASAUR) .enemySpecies(Species.BULBASAUR)
.enemyAbility(AbilityId.CONTRARY) .enemyAbility(AbilityId.CONTRARY)
.ability(AbilityId.INTIMIDATE) .ability(AbilityId.INTIMIDATE)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(MoveId.SPLASH);
}); });
it("should invert stat changes when applied", async () => { it("should invert stat changes when applied", async () => {
@ -40,28 +40,28 @@ describe("Abilities - Contrary", () => {
describe("With Clear Body", () => { describe("With Clear Body", () => {
it("should apply positive effects", async () => { it("should apply positive effects", async () => {
game.override.enemyPassiveAbility(AbilityId.CLEAR_BODY).moveset([Moves.TAIL_WHIP]); game.override.enemyPassiveAbility(AbilityId.CLEAR_BODY).moveset([MoveId.TAIL_WHIP]);
await game.classicMode.startBattle([Species.SLOWBRO]); await game.classicMode.startBattle([Species.SLOWBRO]);
const enemyPokemon = game.scene.getEnemyPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!;
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(1); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(1);
game.move.select(Moves.TAIL_WHIP); game.move.select(MoveId.TAIL_WHIP);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(enemyPokemon.getStatStage(Stat.DEF)).toBe(1); expect(enemyPokemon.getStatStage(Stat.DEF)).toBe(1);
}); });
it("should block negative effects", async () => { it("should block negative effects", async () => {
game.override.enemyPassiveAbility(AbilityId.CLEAR_BODY).enemyMoveset(Moves.HOWL).moveset([Moves.SPLASH]); game.override.enemyPassiveAbility(AbilityId.CLEAR_BODY).enemyMoveset(MoveId.HOWL).moveset([MoveId.SPLASH]);
await game.classicMode.startBattle([Species.SLOWBRO]); await game.classicMode.startBattle([Species.SLOWBRO]);
const enemyPokemon = game.scene.getEnemyPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!;
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(1); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(1);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(1); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(1);

View File

@ -1,5 +1,5 @@
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
@ -22,12 +22,12 @@ describe("Abilities - Corrosion", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.moveset([Moves.SPLASH]) .moveset([MoveId.SPLASH])
.battleStyle("single") .battleStyle("single")
.disableCrits() .disableCrits()
.enemySpecies(Species.GRIMER) .enemySpecies(Species.GRIMER)
.enemyAbility(AbilityId.CORROSION) .enemyAbility(AbilityId.CORROSION)
.enemyMoveset(Moves.TOXIC); .enemyMoveset(MoveId.TOXIC);
}); });
it("If a Poison- or Steel-type Pokémon with this Ability poisons a target with Synchronize, Synchronize does not gain the ability to poison Poison- or Steel-type Pokémon.", async () => { it("If a Poison- or Steel-type Pokémon with this Ability poisons a target with Synchronize, Synchronize does not gain the ability to poison Poison- or Steel-type Pokémon.", async () => {
@ -38,7 +38,7 @@ describe("Abilities - Corrosion", () => {
const enemyPokemon = game.scene.getEnemyPokemon(); const enemyPokemon = game.scene.getEnemyPokemon();
expect(playerPokemon!.status).toBeUndefined(); expect(playerPokemon!.status).toBeUndefined();
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(playerPokemon!.status).toBeDefined(); expect(playerPokemon!.status).toBeDefined();
expect(enemyPokemon!.status).toBeUndefined(); expect(enemyPokemon!.status).toBeUndefined();

View File

@ -1,6 +1,6 @@
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#app/enums/moves"; import { MoveId } from "#app/enums/moves";
import { Species } from "#app/enums/species"; import { Species } from "#app/enums/species";
import { CommandPhase } from "#app/phases/command-phase"; import { CommandPhase } from "#app/phases/command-phase";
import { MessagePhase } from "#app/phases/message-phase"; import { MessagePhase } from "#app/phases/message-phase";
@ -26,8 +26,8 @@ describe("Abilities - COSTAR", () => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override.battleStyle("double"); game.override.battleStyle("double");
game.override.ability(AbilityId.COSTAR); game.override.ability(AbilityId.COSTAR);
game.override.moveset([Moves.SPLASH, Moves.NASTY_PLOT]); game.override.moveset([MoveId.SPLASH, MoveId.NASTY_PLOT]);
game.override.enemyMoveset(Moves.SPLASH); game.override.enemyMoveset(MoveId.SPLASH);
}); });
test("ability copies positive stat stages", async () => { test("ability copies positive stat stages", async () => {
@ -37,15 +37,15 @@ describe("Abilities - COSTAR", () => {
let [leftPokemon, rightPokemon] = game.scene.getPlayerField(); let [leftPokemon, rightPokemon] = game.scene.getPlayerField();
game.move.select(Moves.NASTY_PLOT); game.move.select(MoveId.NASTY_PLOT);
await game.phaseInterceptor.to(CommandPhase); await game.phaseInterceptor.to(CommandPhase);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.toNextTurn(); await game.toNextTurn();
expect(leftPokemon.getStatStage(Stat.SPATK)).toBe(2); expect(leftPokemon.getStatStage(Stat.SPATK)).toBe(2);
expect(rightPokemon.getStatStage(Stat.SPATK)).toBe(0); expect(rightPokemon.getStatStage(Stat.SPATK)).toBe(0);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(CommandPhase); await game.phaseInterceptor.to(CommandPhase);
game.doSwitchPokemon(2); game.doSwitchPokemon(2);
await game.phaseInterceptor.to(MessagePhase); await game.phaseInterceptor.to(MessagePhase);
@ -65,7 +65,7 @@ describe("Abilities - COSTAR", () => {
expect(leftPokemon.getStatStage(Stat.ATK)).toBe(-2); expect(leftPokemon.getStatStage(Stat.ATK)).toBe(-2);
expect(leftPokemon.getStatStage(Stat.ATK)).toBe(-2); expect(leftPokemon.getStatStage(Stat.ATK)).toBe(-2);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(CommandPhase); await game.phaseInterceptor.to(CommandPhase);
game.doSwitchPokemon(2); game.doSwitchPokemon(2);
await game.phaseInterceptor.to(MessagePhase); await game.phaseInterceptor.to(MessagePhase);

View File

@ -4,7 +4,7 @@ import { globalScene } from "#app/global-scene";
import { getPokemonNameWithAffix } from "#app/messages"; import { getPokemonNameWithAffix } from "#app/messages";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { BerryType } from "#enums/berry-type"; import { BerryType } from "#enums/berry-type";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
@ -29,14 +29,14 @@ describe("Abilities - Cud Chew", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.moveset([Moves.BUG_BITE, Moves.SPLASH, Moves.HYPER_VOICE, Moves.STUFF_CHEEKS]) .moveset([MoveId.BUG_BITE, MoveId.SPLASH, MoveId.HYPER_VOICE, MoveId.STUFF_CHEEKS])
.startingHeldItems([{ name: "BERRY", type: BerryType.SITRUS, count: 1 }]) .startingHeldItems([{ name: "BERRY", type: BerryType.SITRUS, count: 1 }])
.ability(AbilityId.CUD_CHEW) .ability(AbilityId.CUD_CHEW)
.battleStyle("single") .battleStyle("single")
.disableCrits() .disableCrits()
.enemySpecies(Species.MAGIKARP) .enemySpecies(Species.MAGIKARP)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(MoveId.SPLASH);
}); });
describe("tracks berries eaten", () => { describe("tracks berries eaten", () => {
@ -46,7 +46,7 @@ describe("Abilities - Cud Chew", () => {
const farigiraf = game.scene.getPlayerPokemon()!; const farigiraf = game.scene.getPlayerPokemon()!;
farigiraf.hp = 1; // needed to allow sitrus procs farigiraf.hp = 1; // needed to allow sitrus procs
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
// berries tracked in turnData; not moved to battleData yet // berries tracked in turnData; not moved to battleData yet
@ -68,15 +68,15 @@ describe("Abilities - Cud Chew", () => {
it("shows ability popup for eating berry, even if berry is useless", async () => { it("shows ability popup for eating berry, even if berry is useless", async () => {
const abDisplaySpy = vi.spyOn(globalScene, "queueAbilityDisplay"); const abDisplaySpy = vi.spyOn(globalScene, "queueAbilityDisplay");
game.override.enemyMoveset([Moves.SPLASH, Moves.HEAL_PULSE]); game.override.enemyMoveset([MoveId.SPLASH, MoveId.HEAL_PULSE]);
await game.classicMode.startBattle([Species.FARIGIRAF]); await game.classicMode.startBattle([Species.FARIGIRAF]);
const farigiraf = game.scene.getPlayerPokemon()!; const farigiraf = game.scene.getPlayerPokemon()!;
// Dip below half to eat berry // Dip below half to eat berry
farigiraf.hp = farigiraf.getMaxHp() / 2 - 1; farigiraf.hp = farigiraf.getMaxHp() / 2 - 1;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(Moves.SPLASH); await game.move.selectEnemyMove(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
// doesn't trigger since cud chew hasn't eaten berry yet // doesn't trigger since cud chew hasn't eaten berry yet
@ -85,8 +85,8 @@ describe("Abilities - Cud Chew", () => {
await game.toNextTurn(); await game.toNextTurn();
// get heal pulsed back to full before the cud chew proc // get heal pulsed back to full before the cud chew proc
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(Moves.HEAL_PULSE); await game.move.selectEnemyMove(MoveId.HEAL_PULSE);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
// globalScene.queueAbilityDisplay should be called twice: // globalScene.queueAbilityDisplay should be called twice:
@ -117,13 +117,13 @@ describe("Abilities - Cud Chew", () => {
{ name: "BERRY", type: BerryType.PETAYA, count: 3 }, { name: "BERRY", type: BerryType.PETAYA, count: 3 },
{ name: "BERRY", type: BerryType.LIECHI, count: 3 }, { name: "BERRY", type: BerryType.LIECHI, count: 3 },
]) ])
.enemyMoveset(Moves.TEATIME); .enemyMoveset(MoveId.TEATIME);
await game.classicMode.startBattle([Species.FARIGIRAF]); await game.classicMode.startBattle([Species.FARIGIRAF]);
const farigiraf = game.scene.getPlayerPokemon()!; const farigiraf = game.scene.getPlayerPokemon()!;
farigiraf.hp = 1; // needed to allow berry procs farigiraf.hp = 1; // needed to allow berry procs
game.move.select(Moves.STUFF_CHEEKS); game.move.select(MoveId.STUFF_CHEEKS);
await game.toNextTurn(); await game.toNextTurn();
// Ate 2 petayas from moves + 1 of each at turn end; all 4 get tallied on turn end // Ate 2 petayas from moves + 1 of each at turn end; all 4 get tallied on turn end
@ -135,7 +135,7 @@ describe("Abilities - Cud Chew", () => {
]); ]);
expect(farigiraf.turnData.berriesEaten).toEqual([]); expect(farigiraf.turnData.berriesEaten).toEqual([]);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
// previous berries eaten and deleted from summon data as remaining eaten berries move to replace them // previous berries eaten and deleted from summon data as remaining eaten berries move to replace them
@ -152,7 +152,7 @@ describe("Abilities - Cud Chew", () => {
farigiraf.hp = 1; farigiraf.hp = 1;
// eat berry turn 1, switch out turn 2 // eat berry turn 1, switch out turn 2
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
const turn1Hp = farigiraf.hp; const turn1Hp = farigiraf.hp;
@ -180,7 +180,7 @@ describe("Abilities - Cud Chew", () => {
const farigiraf = game.scene.getPlayerPokemon()!; const farigiraf = game.scene.getPlayerPokemon()!;
farigiraf.hp = 1; farigiraf.hp = 1;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(farigiraf.summonData.berriesEatenLast).toEqual([]); expect(farigiraf.summonData.berriesEatenLast).toEqual([]);
@ -202,7 +202,7 @@ describe("Abilities - Cud Chew", () => {
const farigiraf = game.scene.getPlayerPokemon()!; const farigiraf = game.scene.getPlayerPokemon()!;
farigiraf.hp = 1; farigiraf.hp = 1;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
// ate 1 sitrus the turn prior, spitball pending // ate 1 sitrus the turn prior, spitball pending
@ -212,7 +212,7 @@ describe("Abilities - Cud Chew", () => {
const turn1Hp = farigiraf.hp; const turn1Hp = farigiraf.hp;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
// healed back up to half without adding any more to array // healed back up to half without adding any more to array
@ -228,9 +228,9 @@ describe("Abilities - Cud Chew", () => {
const farigiraf = game.scene.getPlayerPokemon()!; const farigiraf = game.scene.getPlayerPokemon()!;
farigiraf.hp = 1; farigiraf.hp = 1;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
// Turn end proc set the berriesEatenLast array back to being empty // Turn end proc set the berriesEatenLast array back to being empty
@ -240,13 +240,13 @@ describe("Abilities - Cud Chew", () => {
}); });
it("doesn't trigger on non-eating removal", async () => { it("doesn't trigger on non-eating removal", async () => {
game.override.enemyMoveset(Moves.INCINERATE); game.override.enemyMoveset(MoveId.INCINERATE);
await game.classicMode.startBattle([Species.FARIGIRAF]); await game.classicMode.startBattle([Species.FARIGIRAF]);
const farigiraf = game.scene.getPlayerPokemon()!; const farigiraf = game.scene.getPlayerPokemon()!;
farigiraf.hp = farigiraf.getMaxHp() / 4; farigiraf.hp = farigiraf.getMaxHp() / 4;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
// no berries eaten due to getting cooked // no berries eaten due to getting cooked
@ -264,10 +264,10 @@ describe("Abilities - Cud Chew", () => {
const farigiraf = game.scene.getPlayerPokemon()!; const farigiraf = game.scene.getPlayerPokemon()!;
game.move.select(Moves.BUG_BITE); game.move.select(MoveId.BUG_BITE);
await game.toNextTurn(); await game.toNextTurn();
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
// berry effect triggered twice - once for bug bite, once for cud chew // berry effect triggered twice - once for bug bite, once for cud chew
@ -281,9 +281,9 @@ describe("Abilities - Cud Chew", () => {
const farigiraf = game.scene.getPlayerPokemon()!; const farigiraf = game.scene.getPlayerPokemon()!;
farigiraf.hp = 1; farigiraf.hp = 1;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
// Rounding errors only ever cost a maximum of 4 hp // Rounding errors only ever cost a maximum of 4 hp
@ -297,7 +297,7 @@ describe("Abilities - Cud Chew", () => {
const farigiraf = game.scene.getPlayerPokemon()!; const farigiraf = game.scene.getPlayerPokemon()!;
farigiraf.hp = 1; farigiraf.hp = 1;
game.move.select(Moves.HYPER_VOICE); game.move.select(MoveId.HYPER_VOICE);
await game.toNextWave(); await game.toNextWave();
// berry went yummy yummy in big fat giraffe tummy // berry went yummy yummy in big fat giraffe tummy
@ -313,7 +313,7 @@ describe("Abilities - Cud Chew", () => {
const wave1Hp = farigirafReloaded.hp; const wave1Hp = farigirafReloaded.hp;
// blow up next wave and we should proc the repeat eating // blow up next wave and we should proc the repeat eating
game.move.select(Moves.HYPER_VOICE); game.move.select(MoveId.HYPER_VOICE);
await game.toNextWave(); await game.toNextWave();
expect(farigirafReloaded.hp).toBeGreaterThan(wave1Hp); expect(farigirafReloaded.hp).toBeGreaterThan(wave1Hp);

View File

@ -1,7 +1,7 @@
import { BattlerIndex } from "#app/battle"; import { BattlerIndex } from "#app/battle";
import type { MovePhase } from "#app/phases/move-phase"; import type { MovePhase } from "#app/phases/move-phase";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
@ -29,22 +29,22 @@ describe("Abilities - Dancer", () => {
// Reference Link: https://bulbapedia.bulbagarden.net/wiki/Dancer_(Ability) // Reference Link: https://bulbapedia.bulbagarden.net/wiki/Dancer_(Ability)
it("triggers when dance moves are used, doesn't consume extra PP", async () => { it("triggers when dance moves are used, doesn't consume extra PP", async () => {
game.override.enemyAbility(AbilityId.DANCER).enemySpecies(Species.MAGIKARP).enemyMoveset(Moves.VICTORY_DANCE); game.override.enemyAbility(AbilityId.DANCER).enemySpecies(Species.MAGIKARP).enemyMoveset(MoveId.VICTORY_DANCE);
await game.classicMode.startBattle([Species.ORICORIO, Species.FEEBAS]); await game.classicMode.startBattle([Species.ORICORIO, Species.FEEBAS]);
const [oricorio, feebas] = game.scene.getPlayerField(); const [oricorio, feebas] = game.scene.getPlayerField();
game.move.changeMoveset(oricorio, [Moves.SWORDS_DANCE, Moves.VICTORY_DANCE, Moves.SPLASH]); game.move.changeMoveset(oricorio, [MoveId.SWORDS_DANCE, MoveId.VICTORY_DANCE, MoveId.SPLASH]);
game.move.changeMoveset(feebas, [Moves.SWORDS_DANCE, Moves.SPLASH]); game.move.changeMoveset(feebas, [MoveId.SWORDS_DANCE, MoveId.SPLASH]);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
game.move.select(Moves.SWORDS_DANCE, 1); game.move.select(MoveId.SWORDS_DANCE, 1);
await game.setTurnOrder([BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2]); await game.setTurnOrder([BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2]);
await game.phaseInterceptor.to("MovePhase"); // feebas uses swords dance await game.phaseInterceptor.to("MovePhase"); // feebas uses swords dance
await game.phaseInterceptor.to("MovePhase", false); // oricorio copies swords dance await game.phaseInterceptor.to("MovePhase", false); // oricorio copies swords dance
let currentPhase = game.scene.getCurrentPhase() as MovePhase; let currentPhase = game.scene.getCurrentPhase() as MovePhase;
expect(currentPhase.pokemon).toBe(oricorio); expect(currentPhase.pokemon).toBe(oricorio);
expect(currentPhase.move.moveId).toBe(Moves.SWORDS_DANCE); expect(currentPhase.move.moveId).toBe(MoveId.SWORDS_DANCE);
await game.phaseInterceptor.to("MoveEndPhase"); // end oricorio's move await game.phaseInterceptor.to("MoveEndPhase"); // end oricorio's move
await game.phaseInterceptor.to("MovePhase"); // magikarp 1 copies swords dance await game.phaseInterceptor.to("MovePhase"); // magikarp 1 copies swords dance
@ -54,7 +54,7 @@ describe("Abilities - Dancer", () => {
currentPhase = game.scene.getCurrentPhase() as MovePhase; currentPhase = game.scene.getCurrentPhase() as MovePhase;
expect(currentPhase.pokemon).toBe(oricorio); expect(currentPhase.pokemon).toBe(oricorio);
expect(currentPhase.move.moveId).toBe(Moves.VICTORY_DANCE); expect(currentPhase.move.moveId).toBe(MoveId.VICTORY_DANCE);
await game.phaseInterceptor.to("BerryPhase"); // finish the turn await game.phaseInterceptor.to("BerryPhase"); // finish the turn
@ -66,8 +66,8 @@ describe("Abilities - Dancer", () => {
// TODO: Enable after Dancer rework to not push to move history // TODO: Enable after Dancer rework to not push to move history
it.todo("should not count as the last move used for mirror move/instruct", async () => { it.todo("should not count as the last move used for mirror move/instruct", async () => {
game.override game.override
.moveset([Moves.FIERY_DANCE, Moves.REVELATION_DANCE]) .moveset([MoveId.FIERY_DANCE, MoveId.REVELATION_DANCE])
.enemyMoveset([Moves.INSTRUCT, Moves.MIRROR_MOVE, Moves.SPLASH]) .enemyMoveset([MoveId.INSTRUCT, MoveId.MIRROR_MOVE, MoveId.SPLASH])
.enemySpecies(Species.SHUCKLE) .enemySpecies(Species.SHUCKLE)
.enemyLevel(10); .enemyLevel(10);
await game.classicMode.startBattle([Species.ORICORIO, Species.FEEBAS]); await game.classicMode.startBattle([Species.ORICORIO, Species.FEEBAS]);
@ -75,28 +75,28 @@ describe("Abilities - Dancer", () => {
const [oricorio] = game.scene.getPlayerField(); const [oricorio] = game.scene.getPlayerField();
const [, shuckle2] = game.scene.getEnemyField(); const [, shuckle2] = game.scene.getEnemyField();
game.move.select(Moves.REVELATION_DANCE, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2); game.move.select(MoveId.REVELATION_DANCE, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2);
game.move.select(Moves.FIERY_DANCE, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY_2); game.move.select(MoveId.FIERY_DANCE, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY_2);
await game.move.selectEnemyMove(Moves.INSTRUCT, BattlerIndex.PLAYER); await game.move.selectEnemyMove(MoveId.INSTRUCT, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(Moves.MIRROR_MOVE, BattlerIndex.PLAYER); await game.move.selectEnemyMove(MoveId.MIRROR_MOVE, BattlerIndex.PLAYER);
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY_2, BattlerIndex.ENEMY]); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY_2, BattlerIndex.ENEMY]);
await game.phaseInterceptor.to("MovePhase"); // Oricorio rev dance await game.phaseInterceptor.to("MovePhase"); // Oricorio rev dance
await game.phaseInterceptor.to("MovePhase"); // Feebas fiery dance await game.phaseInterceptor.to("MovePhase"); // Feebas fiery dance
await game.phaseInterceptor.to("MovePhase"); // Oricorio fiery dance (from dancer) await game.phaseInterceptor.to("MovePhase"); // Oricorio fiery dance (from dancer)
await game.phaseInterceptor.to("MoveEndPhase", false); await game.phaseInterceptor.to("MoveEndPhase", false);
// dancer copied move doesn't appear in move history // dancer copied move doesn't appear in move history
expect(oricorio.getLastXMoves(-1)[0].move).toBe(Moves.REVELATION_DANCE); expect(oricorio.getLastXMoves(-1)[0].move).toBe(MoveId.REVELATION_DANCE);
await game.phaseInterceptor.to("MovePhase"); // shuckle 2 mirror moves oricorio await game.phaseInterceptor.to("MovePhase"); // shuckle 2 mirror moves oricorio
await game.phaseInterceptor.to("MovePhase"); // calls instructed rev dance await game.phaseInterceptor.to("MovePhase"); // calls instructed rev dance
let currentPhase = game.scene.getCurrentPhase() as MovePhase; let currentPhase = game.scene.getCurrentPhase() as MovePhase;
expect(currentPhase.pokemon).toBe(shuckle2); expect(currentPhase.pokemon).toBe(shuckle2);
expect(currentPhase.move.moveId).toBe(Moves.REVELATION_DANCE); expect(currentPhase.move.moveId).toBe(MoveId.REVELATION_DANCE);
await game.phaseInterceptor.to("MovePhase"); // shuckle 1 instructs oricorio await game.phaseInterceptor.to("MovePhase"); // shuckle 1 instructs oricorio
await game.phaseInterceptor.to("MovePhase"); await game.phaseInterceptor.to("MovePhase");
currentPhase = game.scene.getCurrentPhase() as MovePhase; currentPhase = game.scene.getCurrentPhase() as MovePhase;
expect(currentPhase.pokemon).toBe(oricorio); expect(currentPhase.pokemon).toBe(oricorio);
expect(currentPhase.move.moveId).toBe(Moves.REVELATION_DANCE); expect(currentPhase.move.moveId).toBe(MoveId.REVELATION_DANCE);
}); });
}); });

View File

@ -1,7 +1,7 @@
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import { TurnInitPhase } from "#app/phases/turn-init-phase"; import { TurnInitPhase } from "#app/phases/turn-init-phase";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
@ -27,9 +27,9 @@ describe("Abilities - Defiant", () => {
game.override game.override
.battleStyle("single") .battleStyle("single")
.enemySpecies(Species.BEEDRILL) .enemySpecies(Species.BEEDRILL)
.enemyMoveset(Moves.TICKLE) .enemyMoveset(MoveId.TICKLE)
.startingLevel(1) .startingLevel(1)
.moveset([Moves.SPLASH, Moves.CLOSE_COMBAT]) .moveset([MoveId.SPLASH, MoveId.CLOSE_COMBAT])
.ability(AbilityId.DEFIANT); .ability(AbilityId.DEFIANT);
}); });
@ -37,7 +37,7 @@ describe("Abilities - Defiant", () => {
await game.classicMode.startBattle([Species.FLYGON]); await game.classicMode.startBattle([Species.FLYGON]);
const playerPokemon = game.scene.getPlayerPokemon()!; const playerPokemon = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnInitPhase); await game.phaseInterceptor.to(TurnInitPhase);
expect(playerPokemon.getStatStage(Stat.ATK)).toBe(3); expect(playerPokemon.getStatStage(Stat.ATK)).toBe(3);
@ -45,11 +45,11 @@ describe("Abilities - Defiant", () => {
}); });
it("lowering your own stats should not trigger defiant", async () => { it("lowering your own stats should not trigger defiant", async () => {
game.override.enemyMoveset(Moves.SPLASH); game.override.enemyMoveset(MoveId.SPLASH);
await game.classicMode.startBattle([Species.FLYGON]); await game.classicMode.startBattle([Species.FLYGON]);
const playerPokemon = game.scene.getPlayerPokemon()!; const playerPokemon = game.scene.getPlayerPokemon()!;
game.move.select(Moves.CLOSE_COMBAT); game.move.select(MoveId.CLOSE_COMBAT);
await game.phaseInterceptor.to(TurnInitPhase); await game.phaseInterceptor.to(TurnInitPhase);
expect(playerPokemon.getStatStage(Stat.SPDEF)).toBe(-1); expect(playerPokemon.getStatStage(Stat.SPDEF)).toBe(-1);
@ -62,7 +62,7 @@ describe("Abilities - Defiant", () => {
await game.classicMode.startBattle([Species.FLYGON]); await game.classicMode.startBattle([Species.FLYGON]);
const playerPokemon = game.scene.getPlayerPokemon()!; const playerPokemon = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnInitPhase); await game.phaseInterceptor.to(TurnInitPhase);
expect(playerPokemon.getStatStage(Stat.DEF)).toBe(0); expect(playerPokemon.getStatStage(Stat.DEF)).toBe(0);

View File

@ -3,7 +3,7 @@ import { WeatherType } from "#app/enums/weather-type";
import type { CommandPhase } from "#app/phases/command-phase"; import type { CommandPhase } from "#app/phases/command-phase";
import { Command } from "#app/ui/command-ui-handler"; import { Command } from "#app/ui/command-ui-handler";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
@ -26,19 +26,19 @@ describe("Abilities - Desolate Land", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.moveset(Moves.SPLASH) .moveset(MoveId.SPLASH)
.hasPassiveAbility(true) .hasPassiveAbility(true)
.enemySpecies(Species.RALTS) .enemySpecies(Species.RALTS)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(MoveId.SPLASH);
}); });
/** /**
* This checks that the weather has changed after the Enemy Pokemon with {@linkcode AbilityId.DESOLATE_LAND} * This checks that the weather has changed after the Enemy Pokemon with {@linkcode AbilityId.DESOLATE_LAND}
* is forcefully moved out of the field from moves such as Roar {@linkcode Moves.ROAR} * is forcefully moved out of the field from moves such as Roar {@linkcode MoveId.ROAR}
*/ */
it("should lift only when all pokemon with this ability leave the field", async () => { it("should lift only when all pokemon with this ability leave the field", async () => {
game.override.battleStyle("double").enemyMoveset([Moves.SPLASH, Moves.ROAR]); game.override.battleStyle("double").enemyMoveset([MoveId.SPLASH, MoveId.ROAR]);
await game.classicMode.startBattle([Species.MAGCARGO, Species.MAGCARGO, Species.MAGIKARP, Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGCARGO, Species.MAGCARGO, Species.MAGIKARP, Species.MAGIKARP]);
expect(game.scene.arena.weather?.weatherType).toBe(WeatherType.HARSH_SUN); expect(game.scene.arena.weather?.weatherType).toBe(WeatherType.HARSH_SUN);
@ -47,11 +47,11 @@ describe("Abilities - Desolate Land", () => {
return min; return min;
}); });
game.move.select(Moves.SPLASH, 0, 2); game.move.select(MoveId.SPLASH, 0, 2);
game.move.select(Moves.SPLASH, 1, 2); game.move.select(MoveId.SPLASH, 1, 2);
await game.move.selectEnemyMove(Moves.ROAR, 0); await game.move.selectEnemyMove(MoveId.ROAR, 0);
await game.move.selectEnemyMove(Moves.SPLASH, 1); await game.move.selectEnemyMove(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
@ -63,11 +63,11 @@ describe("Abilities - Desolate Land", () => {
return min + 1; return min + 1;
}); });
game.move.select(Moves.SPLASH, 0, 2); game.move.select(MoveId.SPLASH, 0, 2);
game.move.select(Moves.SPLASH, 1, 2); game.move.select(MoveId.SPLASH, 1, 2);
await game.move.selectEnemyMove(Moves.ROAR, 1); await game.move.selectEnemyMove(MoveId.ROAR, 1);
await game.move.selectEnemyMove(Moves.SPLASH, 0); await game.move.selectEnemyMove(MoveId.SPLASH, 0);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
@ -77,18 +77,18 @@ describe("Abilities - Desolate Land", () => {
it("should lift when enemy faints", async () => { it("should lift when enemy faints", async () => {
game.override game.override
.battleStyle("single") .battleStyle("single")
.moveset([Moves.SHEER_COLD]) .moveset([MoveId.SHEER_COLD])
.ability(AbilityId.NO_GUARD) .ability(AbilityId.NO_GUARD)
.startingLevel(100) .startingLevel(100)
.enemyLevel(1) .enemyLevel(1)
.enemyMoveset([Moves.SPLASH]) .enemyMoveset([MoveId.SPLASH])
.enemySpecies(Species.MAGCARGO) .enemySpecies(Species.MAGCARGO)
.enemyHasPassiveAbility(true); .enemyHasPassiveAbility(true);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
expect(game.scene.arena.weather?.weatherType).toBe(WeatherType.HARSH_SUN); expect(game.scene.arena.weather?.weatherType).toBe(WeatherType.HARSH_SUN);
game.move.select(Moves.SHEER_COLD); game.move.select(MoveId.SHEER_COLD);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
@ -96,15 +96,15 @@ describe("Abilities - Desolate Land", () => {
}); });
it("should lift when pokemon returns upon switching from double to single battle", async () => { it("should lift when pokemon returns upon switching from double to single battle", async () => {
game.override.battleStyle("even-doubles").enemyMoveset([Moves.SPLASH, Moves.MEMENTO]).startingWave(12); game.override.battleStyle("even-doubles").enemyMoveset([MoveId.SPLASH, MoveId.MEMENTO]).startingWave(12);
await game.classicMode.startBattle([Species.MAGIKARP, Species.MAGCARGO]); await game.classicMode.startBattle([Species.MAGIKARP, Species.MAGCARGO]);
expect(game.scene.arena.weather?.weatherType).toBe(WeatherType.HARSH_SUN); expect(game.scene.arena.weather?.weatherType).toBe(WeatherType.HARSH_SUN);
game.move.select(Moves.SPLASH, 0, 2); game.move.select(MoveId.SPLASH, 0, 2);
game.move.select(Moves.SPLASH, 1, 2); game.move.select(MoveId.SPLASH, 1, 2);
await game.move.selectEnemyMove(Moves.MEMENTO, 0); await game.move.selectEnemyMove(MoveId.MEMENTO, 0);
await game.move.selectEnemyMove(Moves.MEMENTO, 1); await game.move.selectEnemyMove(MoveId.MEMENTO, 1);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
@ -118,7 +118,7 @@ describe("Abilities - Desolate Land", () => {
it("should lift when enemy is captured", async () => { it("should lift when enemy is captured", async () => {
game.override game.override
.battleStyle("single") .battleStyle("single")
.enemyMoveset([Moves.SPLASH]) .enemyMoveset([MoveId.SPLASH])
.enemySpecies(Species.MAGCARGO) .enemySpecies(Species.MAGCARGO)
.enemyHasPassiveAbility(true); .enemyHasPassiveAbility(true);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);

View File

@ -1,7 +1,7 @@
import { BattlerIndex } from "#app/battle"; import { BattlerIndex } from "#app/battle";
import { toDmgValue } from "#app/utils/common"; import { toDmgValue } from "#app/utils/common";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import { StatusEffect } from "#enums/status-effect"; import { StatusEffect } from "#enums/status-effect";
@ -29,9 +29,9 @@ describe("Abilities - Disguise", () => {
game.override game.override
.battleStyle("single") .battleStyle("single")
.enemySpecies(Species.MIMIKYU) .enemySpecies(Species.MIMIKYU)
.enemyMoveset(Moves.SPLASH) .enemyMoveset(MoveId.SPLASH)
.starterSpecies(Species.REGIELEKI) .starterSpecies(Species.REGIELEKI)
.moveset([Moves.SHADOW_SNEAK, Moves.VACUUM_WAVE, Moves.TOXIC_THREAD, Moves.SPLASH]); .moveset([MoveId.SHADOW_SNEAK, MoveId.VACUUM_WAVE, MoveId.TOXIC_THREAD, MoveId.SPLASH]);
}); });
it("takes no damage from attacking move and transforms to Busted form, takes 1/8 max HP damage from the disguise breaking", async () => { it("takes no damage from attacking move and transforms to Busted form, takes 1/8 max HP damage from the disguise breaking", async () => {
@ -43,7 +43,7 @@ describe("Abilities - Disguise", () => {
expect(mimikyu.formIndex).toBe(disguisedForm); expect(mimikyu.formIndex).toBe(disguisedForm);
game.move.select(Moves.SHADOW_SNEAK); game.move.select(MoveId.SHADOW_SNEAK);
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
@ -58,7 +58,7 @@ describe("Abilities - Disguise", () => {
expect(mimikyu.formIndex).toBe(disguisedForm); expect(mimikyu.formIndex).toBe(disguisedForm);
game.move.select(Moves.VACUUM_WAVE); game.move.select(MoveId.VACUUM_WAVE);
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
@ -66,7 +66,7 @@ describe("Abilities - Disguise", () => {
}); });
it("takes no damage from the first hit of a multihit move and transforms to Busted form, then takes damage from the second hit", async () => { it("takes no damage from the first hit of a multihit move and transforms to Busted form, then takes damage from the second hit", async () => {
game.override.moveset([Moves.SURGING_STRIKES]); game.override.moveset([MoveId.SURGING_STRIKES]);
game.override.enemyLevel(5); game.override.enemyLevel(5);
await game.classicMode.startBattle(); await game.classicMode.startBattle();
@ -76,7 +76,7 @@ describe("Abilities - Disguise", () => {
expect(mimikyu.formIndex).toBe(disguisedForm); expect(mimikyu.formIndex).toBe(disguisedForm);
game.move.select(Moves.SURGING_STRIKES); game.move.select(MoveId.SURGING_STRIKES);
// First hit // First hit
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");
@ -95,7 +95,7 @@ describe("Abilities - Disguise", () => {
const mimikyu = game.scene.getEnemyPokemon()!; const mimikyu = game.scene.getEnemyPokemon()!;
expect(mimikyu.hp).toBe(mimikyu.getMaxHp()); expect(mimikyu.hp).toBe(mimikyu.getMaxHp());
game.move.select(Moves.TOXIC_THREAD); game.move.select(MoveId.TOXIC_THREAD);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
@ -106,7 +106,7 @@ describe("Abilities - Disguise", () => {
}); });
it("persists form change when switched out", async () => { it("persists form change when switched out", async () => {
game.override.enemyMoveset([Moves.SHADOW_SNEAK]); game.override.enemyMoveset([MoveId.SHADOW_SNEAK]);
game.override.starterSpecies(0); game.override.starterSpecies(0);
await game.classicMode.startBattle([Species.MIMIKYU, Species.FURRET]); await game.classicMode.startBattle([Species.MIMIKYU, Species.FURRET]);
@ -115,7 +115,7 @@ describe("Abilities - Disguise", () => {
const maxHp = mimikyu.getMaxHp(); const maxHp = mimikyu.getMaxHp();
const disguiseDamage = toDmgValue(maxHp / 8); const disguiseDamage = toDmgValue(maxHp / 8);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
@ -140,7 +140,7 @@ describe("Abilities - Disguise", () => {
const mimikyu = game.scene.getPlayerParty()[1]!; const mimikyu = game.scene.getPlayerParty()[1]!;
expect(mimikyu.formIndex).toBe(bustedForm); expect(mimikyu.formIndex).toBe(bustedForm);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.doKillOpponents(); await game.doKillOpponents();
await game.toNextWave(); await game.toNextWave();
@ -160,7 +160,7 @@ describe("Abilities - Disguise", () => {
expect(mimikyu.formIndex).toBe(bustedForm); expect(mimikyu.formIndex).toBe(bustedForm);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.doKillOpponents(); await game.doKillOpponents();
await game.toNextWave(); await game.toNextWave();
@ -180,11 +180,11 @@ describe("Abilities - Disguise", () => {
expect(mimikyu1.formIndex).toBe(bustedForm); expect(mimikyu1.formIndex).toBe(bustedForm);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.killPokemon(mimikyu1); await game.killPokemon(mimikyu1);
game.doSelectPartyPokemon(1); game.doSelectPartyPokemon(1);
await game.toNextTurn(); await game.toNextTurn();
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.doKillOpponents(); await game.doKillOpponents();
await game.phaseInterceptor.to("QuietFormChangePhase"); await game.phaseInterceptor.to("QuietFormChangePhase");
@ -192,13 +192,13 @@ describe("Abilities - Disguise", () => {
}); });
it("doesn't faint twice when fainting due to Disguise break damage, nor prevent faint from Disguise break damage if using Endure", async () => { it("doesn't faint twice when fainting due to Disguise break damage, nor prevent faint from Disguise break damage if using Endure", async () => {
game.override.enemyMoveset([Moves.ENDURE]); game.override.enemyMoveset([MoveId.ENDURE]);
await game.classicMode.startBattle(); await game.classicMode.startBattle();
const mimikyu = game.scene.getEnemyPokemon()!; const mimikyu = game.scene.getEnemyPokemon()!;
mimikyu.hp = 1; mimikyu.hp = 1;
game.move.select(Moves.SHADOW_SNEAK); game.move.select(MoveId.SHADOW_SNEAK);
await game.toNextWave(); await game.toNextWave();
expect(game.scene.getCurrentPhase()?.constructor.name).toBe("CommandPhase"); expect(game.scene.getCurrentPhase()?.constructor.name).toBe("CommandPhase");
@ -207,7 +207,7 @@ describe("Abilities - Disguise", () => {
it("activates when Aerilate circumvents immunity to the move's base type", async () => { it("activates when Aerilate circumvents immunity to the move's base type", async () => {
game.override.ability(AbilityId.AERILATE); game.override.ability(AbilityId.AERILATE);
game.override.moveset([Moves.TACKLE]); game.override.moveset([MoveId.TACKLE]);
await game.classicMode.startBattle(); await game.classicMode.startBattle();
@ -215,7 +215,7 @@ describe("Abilities - Disguise", () => {
const maxHp = mimikyu.getMaxHp(); const maxHp = mimikyu.getMaxHp();
const disguiseDamage = toDmgValue(maxHp / 8); const disguiseDamage = toDmgValue(maxHp / 8);
game.move.select(Moves.TACKLE); game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
@ -224,10 +224,10 @@ describe("Abilities - Disguise", () => {
}); });
it("doesn't trigger if user is behind a substitute", async () => { it("doesn't trigger if user is behind a substitute", async () => {
game.override.enemyMoveset(Moves.SUBSTITUTE).moveset(Moves.POWER_TRIP); game.override.enemyMoveset(MoveId.SUBSTITUTE).moveset(MoveId.POWER_TRIP);
await game.classicMode.startBattle(); await game.classicMode.startBattle();
game.move.select(Moves.POWER_TRIP); game.move.select(MoveId.POWER_TRIP);
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
await game.toNextTurn(); await game.toNextTurn();

View File

@ -1,6 +1,6 @@
import { Species } from "#app/enums/species"; import { Species } from "#app/enums/species";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
@ -25,10 +25,10 @@ describe("Abilities - Dry Skin", () => {
.battleStyle("single") .battleStyle("single")
.disableCrits() .disableCrits()
.enemyAbility(AbilityId.DRY_SKIN) .enemyAbility(AbilityId.DRY_SKIN)
.enemyMoveset(Moves.SPLASH) .enemyMoveset(MoveId.SPLASH)
.enemySpecies(Species.CHARMANDER) .enemySpecies(Species.CHARMANDER)
.ability(AbilityId.BALL_FETCH) .ability(AbilityId.BALL_FETCH)
.moveset([Moves.SUNNY_DAY, Moves.RAIN_DANCE, Moves.SPLASH, Moves.WATER_GUN]) .moveset([MoveId.SUNNY_DAY, MoveId.RAIN_DANCE, MoveId.SPLASH, MoveId.WATER_GUN])
.starterSpecies(Species.CHANDELURE); .starterSpecies(Species.CHANDELURE);
}); });
@ -38,13 +38,13 @@ describe("Abilities - Dry Skin", () => {
const enemy = game.scene.getEnemyPokemon()!; const enemy = game.scene.getEnemyPokemon()!;
// first turn // first turn
game.move.select(Moves.SUNNY_DAY); game.move.select(MoveId.SUNNY_DAY);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(enemy.hp).toBeLessThan(enemy.getMaxHp()); expect(enemy.hp).toBeLessThan(enemy.getMaxHp());
// second turn // second turn
enemy.hp = enemy.getMaxHp(); enemy.hp = enemy.getMaxHp();
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(enemy.hp).toBeLessThan(enemy.getMaxHp()); expect(enemy.hp).toBeLessThan(enemy.getMaxHp());
}); });
@ -57,19 +57,19 @@ describe("Abilities - Dry Skin", () => {
enemy.hp = 1; enemy.hp = 1;
// first turn // first turn
game.move.select(Moves.RAIN_DANCE); game.move.select(MoveId.RAIN_DANCE);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(enemy.hp).toBeGreaterThan(1); expect(enemy.hp).toBeGreaterThan(1);
// second turn // second turn
enemy.hp = 1; enemy.hp = 1;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(enemy.hp).toBeGreaterThan(1); expect(enemy.hp).toBeGreaterThan(1);
}); });
it("opposing fire attacks do 25% more damage", async () => { it("opposing fire attacks do 25% more damage", async () => {
game.override.moveset([Moves.FLAMETHROWER]); game.override.moveset([MoveId.FLAMETHROWER]);
await game.classicMode.startBattle(); await game.classicMode.startBattle();
const enemy = game.scene.getEnemyPokemon()!; const enemy = game.scene.getEnemyPokemon()!;
@ -77,7 +77,7 @@ describe("Abilities - Dry Skin", () => {
enemy.hp = initialHP; enemy.hp = initialHP;
// first turn // first turn
game.move.select(Moves.FLAMETHROWER); game.move.select(MoveId.FLAMETHROWER);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
const fireDamageTakenWithDrySkin = initialHP - enemy.hp; const fireDamageTakenWithDrySkin = initialHP - enemy.hp;
@ -85,7 +85,7 @@ describe("Abilities - Dry Skin", () => {
game.override.enemyAbility(AbilityId.NONE); game.override.enemyAbility(AbilityId.NONE);
// second turn // second turn
game.move.select(Moves.FLAMETHROWER); game.move.select(MoveId.FLAMETHROWER);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
const fireDamageTakenWithoutDrySkin = initialHP - enemy.hp; const fireDamageTakenWithoutDrySkin = initialHP - enemy.hp;
@ -99,13 +99,13 @@ describe("Abilities - Dry Skin", () => {
enemy.hp = 1; enemy.hp = 1;
game.move.select(Moves.WATER_GUN); game.move.select(MoveId.WATER_GUN);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(enemy.hp).toBeGreaterThan(1); expect(enemy.hp).toBeGreaterThan(1);
}); });
it("opposing water attacks do not heal if they were protected from", async () => { it("opposing water attacks do not heal if they were protected from", async () => {
game.override.enemyMoveset([Moves.PROTECT]); game.override.enemyMoveset([MoveId.PROTECT]);
await game.classicMode.startBattle(); await game.classicMode.startBattle();
@ -113,13 +113,13 @@ describe("Abilities - Dry Skin", () => {
enemy.hp = 1; enemy.hp = 1;
game.move.select(Moves.WATER_GUN); game.move.select(MoveId.WATER_GUN);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(enemy.hp).toBe(1); expect(enemy.hp).toBe(1);
}); });
it("multi-strike water attacks only heal once", async () => { it("multi-strike water attacks only heal once", async () => {
game.override.moveset([Moves.WATER_GUN, Moves.WATER_SHURIKEN]); game.override.moveset([MoveId.WATER_GUN, MoveId.WATER_SHURIKEN]);
await game.classicMode.startBattle(); await game.classicMode.startBattle();
@ -128,14 +128,14 @@ describe("Abilities - Dry Skin", () => {
enemy.hp = 1; enemy.hp = 1;
// first turn // first turn
game.move.select(Moves.WATER_SHURIKEN); game.move.select(MoveId.WATER_SHURIKEN);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
const healthGainedFromWaterShuriken = enemy.hp - 1; const healthGainedFromWaterShuriken = enemy.hp - 1;
enemy.hp = 1; enemy.hp = 1;
// second turn // second turn
game.move.select(Moves.WATER_GUN); game.move.select(MoveId.WATER_GUN);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
const healthGainedFromWaterGun = enemy.hp - 1; const healthGainedFromWaterGun = enemy.hp - 1;
@ -147,7 +147,7 @@ describe("Abilities - Dry Skin", () => {
const enemy = game.scene.getEnemyPokemon()!; const enemy = game.scene.getEnemyPokemon()!;
game.move.select(Moves.WATER_GUN); game.move.select(MoveId.WATER_GUN);
enemy.hp = enemy.hp - 1; enemy.hp = enemy.hp - 1;
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");

View File

@ -1,7 +1,7 @@
import { Status } from "#app/data/status-effect"; import { Status } from "#app/data/status-effect";
import { MoveResult } from "#app/field/pokemon"; import { MoveResult } from "#app/field/pokemon";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { StatusEffect } from "#enums/status-effect"; import { StatusEffect } from "#enums/status-effect";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
@ -25,13 +25,13 @@ describe("Abilities - Early Bird", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.moveset([Moves.REST, Moves.BELLY_DRUM, Moves.SPLASH]) .moveset([MoveId.REST, MoveId.BELLY_DRUM, MoveId.SPLASH])
.ability(AbilityId.EARLY_BIRD) .ability(AbilityId.EARLY_BIRD)
.battleStyle("single") .battleStyle("single")
.disableCrits() .disableCrits()
.enemySpecies(Species.MAGIKARP) .enemySpecies(Species.MAGIKARP)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(MoveId.SPLASH);
}); });
it("reduces Rest's sleep time to 1 turn", async () => { it("reduces Rest's sleep time to 1 turn", async () => {
@ -39,20 +39,20 @@ describe("Abilities - Early Bird", () => {
const player = game.scene.getPlayerPokemon()!; const player = game.scene.getPlayerPokemon()!;
game.move.select(Moves.BELLY_DRUM); game.move.select(MoveId.BELLY_DRUM);
await game.toNextTurn(); await game.toNextTurn();
game.move.select(Moves.REST); game.move.select(MoveId.REST);
await game.toNextTurn(); await game.toNextTurn();
expect(player.status?.effect).toBe(StatusEffect.SLEEP); expect(player.status?.effect).toBe(StatusEffect.SLEEP);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
expect(player.status?.effect).toBe(StatusEffect.SLEEP); expect(player.status?.effect).toBe(StatusEffect.SLEEP);
expect(player.getLastXMoves(1)[0].result).toBe(MoveResult.FAIL); expect(player.getLastXMoves(1)[0].result).toBe(MoveResult.FAIL);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
expect(player.status?.effect).toBeUndefined(); expect(player.status?.effect).toBeUndefined();
@ -65,13 +65,13 @@ describe("Abilities - Early Bird", () => {
const player = game.scene.getPlayerPokemon()!; const player = game.scene.getPlayerPokemon()!;
player.status = new Status(StatusEffect.SLEEP, 0, 4); player.status = new Status(StatusEffect.SLEEP, 0, 4);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
expect(player.status?.effect).toBe(StatusEffect.SLEEP); expect(player.status?.effect).toBe(StatusEffect.SLEEP);
expect(player.getLastXMoves(1)[0].result).toBe(MoveResult.FAIL); expect(player.getLastXMoves(1)[0].result).toBe(MoveResult.FAIL);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
expect(player.status?.effect).toBeUndefined(); expect(player.status?.effect).toBeUndefined();
@ -84,7 +84,7 @@ describe("Abilities - Early Bird", () => {
const player = game.scene.getPlayerPokemon()!; const player = game.scene.getPlayerPokemon()!;
player.status = new Status(StatusEffect.SLEEP, 0, 2); player.status = new Status(StatusEffect.SLEEP, 0, 2);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
expect(player.status?.effect).toBeUndefined(); expect(player.status?.effect).toBeUndefined();

View File

@ -4,7 +4,7 @@ import { Species } from "#app/enums/species";
import { MovePhase } from "#app/phases/move-phase"; import { MovePhase } from "#app/phases/move-phase";
import { TurnEndPhase } from "#app/phases/turn-end-phase"; import { TurnEndPhase } from "#app/phases/turn-end-phase";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { StatusEffect } from "#enums/status-effect"; import { StatusEffect } from "#enums/status-effect";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
@ -36,34 +36,34 @@ describe("Abilities - Flash Fire", () => {
}); });
it("immune to Fire-type moves", async () => { it("immune to Fire-type moves", async () => {
game.override.enemyMoveset([Moves.EMBER]).moveset(Moves.SPLASH); game.override.enemyMoveset([MoveId.EMBER]).moveset(MoveId.SPLASH);
await game.classicMode.startBattle([Species.BLISSEY]); await game.classicMode.startBattle([Species.BLISSEY]);
const blissey = game.scene.getPlayerPokemon()!; const blissey = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
expect(blissey.hp).toBe(blissey.getMaxHp()); expect(blissey.hp).toBe(blissey.getMaxHp());
}, 20000); }, 20000);
it("not activate if the Pokémon is protected from the Fire-type move", async () => { it("not activate if the Pokémon is protected from the Fire-type move", async () => {
game.override.enemyMoveset([Moves.EMBER]).moveset([Moves.PROTECT]); game.override.enemyMoveset([MoveId.EMBER]).moveset([MoveId.PROTECT]);
await game.classicMode.startBattle([Species.BLISSEY]); await game.classicMode.startBattle([Species.BLISSEY]);
const blissey = game.scene.getPlayerPokemon()!; const blissey = game.scene.getPlayerPokemon()!;
game.move.select(Moves.PROTECT); game.move.select(MoveId.PROTECT);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
expect(blissey!.getTag(BattlerTagType.FIRE_BOOST)).toBeUndefined(); expect(blissey!.getTag(BattlerTagType.FIRE_BOOST)).toBeUndefined();
}, 20000); }, 20000);
it("activated by Will-O-Wisp", async () => { it("activated by Will-O-Wisp", async () => {
game.override.enemyMoveset([Moves.WILL_O_WISP]).moveset(Moves.SPLASH); game.override.enemyMoveset([MoveId.WILL_O_WISP]).moveset(MoveId.SPLASH);
await game.classicMode.startBattle([Species.BLISSEY]); await game.classicMode.startBattle([Species.BLISSEY]);
const blissey = game.scene.getPlayerPokemon()!; const blissey = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.move.forceHit(); await game.move.forceHit();
await game.phaseInterceptor.to(MovePhase, false); await game.phaseInterceptor.to(MovePhase, false);
await game.move.forceHit(); await game.move.forceHit();
@ -73,24 +73,24 @@ describe("Abilities - Flash Fire", () => {
}, 20000); }, 20000);
it("activated after being frozen", async () => { it("activated after being frozen", async () => {
game.override.enemyMoveset([Moves.EMBER]).moveset(Moves.SPLASH); game.override.enemyMoveset([MoveId.EMBER]).moveset(MoveId.SPLASH);
game.override.statusEffect(StatusEffect.FREEZE); game.override.statusEffect(StatusEffect.FREEZE);
await game.classicMode.startBattle([Species.BLISSEY]); await game.classicMode.startBattle([Species.BLISSEY]);
const blissey = game.scene.getPlayerPokemon()!; const blissey = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
expect(blissey!.getTag(BattlerTagType.FIRE_BOOST)).toBeDefined(); expect(blissey!.getTag(BattlerTagType.FIRE_BOOST)).toBeDefined();
}, 20000); }, 20000);
it("not passing with baton pass", async () => { it("not passing with baton pass", async () => {
game.override.enemyMoveset([Moves.EMBER]).moveset([Moves.BATON_PASS]); game.override.enemyMoveset([MoveId.EMBER]).moveset([MoveId.BATON_PASS]);
await game.classicMode.startBattle([Species.BLISSEY, Species.CHANSEY]); await game.classicMode.startBattle([Species.BLISSEY, Species.CHANSEY]);
// ensure use baton pass after enemy moved // ensure use baton pass after enemy moved
game.move.select(Moves.BATON_PASS); game.move.select(MoveId.BATON_PASS);
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
game.doSelectPartyPokemon(1); game.doSelectPartyPokemon(1);
@ -102,7 +102,7 @@ describe("Abilities - Flash Fire", () => {
}, 20000); }, 20000);
it("boosts Fire-type move when the ability is activated", async () => { it("boosts Fire-type move when the ability is activated", async () => {
game.override.enemyMoveset([Moves.FIRE_PLEDGE]).moveset([Moves.EMBER, Moves.SPLASH]); game.override.enemyMoveset([MoveId.FIRE_PLEDGE]).moveset([MoveId.EMBER, MoveId.SPLASH]);
game.override.enemyAbility(AbilityId.FLASH_FIRE).ability(AbilityId.NONE); game.override.enemyAbility(AbilityId.FLASH_FIRE).ability(AbilityId.NONE);
await game.classicMode.startBattle([Species.BLISSEY]); await game.classicMode.startBattle([Species.BLISSEY]);
const blissey = game.scene.getPlayerPokemon()!; const blissey = game.scene.getPlayerPokemon()!;
@ -110,7 +110,7 @@ describe("Abilities - Flash Fire", () => {
blissey.hp = initialHP; blissey.hp = initialHP;
// first turn // first turn
game.move.select(Moves.EMBER); game.move.select(MoveId.EMBER);
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
const originalDmg = initialHP - blissey.hp; const originalDmg = initialHP - blissey.hp;
@ -119,7 +119,7 @@ describe("Abilities - Flash Fire", () => {
blissey.hp = initialHP; blissey.hp = initialHP;
// second turn // second turn
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
const flashFireDmg = initialHP - blissey.hp; const flashFireDmg = initialHP - blissey.hp;
@ -127,7 +127,7 @@ describe("Abilities - Flash Fire", () => {
}, 20000); }, 20000);
it("still activates regardless of accuracy check", async () => { it("still activates regardless of accuracy check", async () => {
game.override.moveset(Moves.FIRE_PLEDGE).enemyMoveset(Moves.EMBER); game.override.moveset(MoveId.FIRE_PLEDGE).enemyMoveset(MoveId.EMBER);
game.override.enemyAbility(AbilityId.NONE).ability(AbilityId.FLASH_FIRE); game.override.enemyAbility(AbilityId.NONE).ability(AbilityId.FLASH_FIRE);
game.override.enemySpecies(Species.BLISSEY); game.override.enemySpecies(Species.BLISSEY);
await game.classicMode.startBattle([Species.RATTATA]); await game.classicMode.startBattle([Species.RATTATA]);
@ -137,7 +137,7 @@ describe("Abilities - Flash Fire", () => {
blissey.hp = initialHP; blissey.hp = initialHP;
// first turn // first turn
game.move.select(Moves.FIRE_PLEDGE); game.move.select(MoveId.FIRE_PLEDGE);
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");
await game.move.forceMiss(); await game.move.forceMiss();
@ -148,7 +148,7 @@ describe("Abilities - Flash Fire", () => {
blissey.hp = initialHP; blissey.hp = initialHP;
// second turn // second turn
game.move.select(Moves.FIRE_PLEDGE); game.move.select(MoveId.FIRE_PLEDGE);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
const flashFireDmg = initialHP - blissey.hp; const flashFireDmg = initialHP - blissey.hp;

View File

@ -4,7 +4,7 @@ import { AbilityId } from "#enums/ability-id";
import { Stat } from "#app/enums/stat"; import { Stat } from "#app/enums/stat";
import { WeatherType } from "#app/enums/weather-type"; import { WeatherType } from "#app/enums/weather-type";
import { TurnEndPhase } from "#app/phases/turn-end-phase"; import { TurnEndPhase } from "#app/phases/turn-end-phase";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
@ -25,7 +25,7 @@ describe("Abilities - Flower Gift", () => {
game.override.starterForms({ [Species.CASTFORM]: SUNSHINE_FORM }).enemyAbility(ability); game.override.starterForms({ [Species.CASTFORM]: SUNSHINE_FORM }).enemyAbility(ability);
await game.classicMode.startBattle([Species.CASTFORM]); await game.classicMode.startBattle([Species.CASTFORM]);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
expect(game.scene.getPlayerPokemon()?.formIndex).toBe(OVERCAST_FORM); expect(game.scene.getPlayerPokemon()?.formIndex).toBe(OVERCAST_FORM);
}; };
@ -42,18 +42,18 @@ describe("Abilities - Flower Gift", () => {
*/ */
const testDamageDealt = async ( const testDamageDealt = async (
game: GameManager, game: GameManager,
move: Moves, move: MoveId,
allyAttacker: boolean, allyAttacker: boolean,
allyAbility = AbilityId.BALL_FETCH, allyAbility = AbilityId.BALL_FETCH,
enemyAbility = AbilityId.BALL_FETCH, enemyAbility = AbilityId.BALL_FETCH,
): Promise<[number, number]> => { ): Promise<[number, number]> => {
game.override.battleStyle("double"); game.override.battleStyle("double");
game.override.moveset([Moves.SPLASH, Moves.SUNNY_DAY, move, Moves.HEAL_PULSE]); game.override.moveset([MoveId.SPLASH, MoveId.SUNNY_DAY, move, MoveId.HEAL_PULSE]);
game.override.enemyMoveset([Moves.SPLASH, Moves.HEAL_PULSE]); game.override.enemyMoveset([MoveId.SPLASH, MoveId.HEAL_PULSE]);
const target_index = allyAttacker ? BattlerIndex.ENEMY : BattlerIndex.PLAYER_2; const target_index = allyAttacker ? BattlerIndex.ENEMY : BattlerIndex.PLAYER_2;
const attacker_index = allyAttacker ? BattlerIndex.PLAYER_2 : BattlerIndex.ENEMY; const attacker_index = allyAttacker ? BattlerIndex.PLAYER_2 : BattlerIndex.ENEMY;
const ally_move = allyAttacker ? move : Moves.SPLASH; const ally_move = allyAttacker ? move : MoveId.SPLASH;
const enemy_move = allyAttacker ? Moves.SPLASH : move; const enemy_move = allyAttacker ? MoveId.SPLASH : move;
const ally_target = allyAttacker ? BattlerIndex.ENEMY : null; const ally_target = allyAttacker ? BattlerIndex.ENEMY : null;
await game.classicMode.startBattle([Species.CHERRIM, Species.MAGIKARP]); await game.classicMode.startBattle([Species.CHERRIM, Species.MAGIKARP]);
@ -65,10 +65,10 @@ describe("Abilities - Flower Gift", () => {
vi.spyOn(game.scene.getEnemyField()[0], "getAbility").mockReturnValue(allAbilities[enemyAbility]); vi.spyOn(game.scene.getEnemyField()[0], "getAbility").mockReturnValue(allAbilities[enemyAbility]);
// turn 1 // turn 1
game.move.select(Moves.SUNNY_DAY, 0); game.move.select(MoveId.SUNNY_DAY, 0);
game.move.select(ally_move, 1, ally_target); game.move.select(ally_move, 1, ally_target);
await game.move.selectEnemyMove(enemy_move, BattlerIndex.PLAYER_2); await game.move.selectEnemyMove(enemy_move, BattlerIndex.PLAYER_2);
await game.move.selectEnemyMove(Moves.SPLASH); await game.move.selectEnemyMove(MoveId.SPLASH);
// Ensure sunny day is used last. // Ensure sunny day is used last.
await game.setTurnOrder([attacker_index, target_index, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER]); await game.setTurnOrder([attacker_index, target_index, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER]);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
@ -77,10 +77,10 @@ describe("Abilities - Flower Gift", () => {
target.hp = initialHp; target.hp = initialHp;
// turn 2. Make target use recover to reset hp calculation. // turn 2. Make target use recover to reset hp calculation.
game.move.select(Moves.SPLASH, 0, target_index); game.move.select(MoveId.SPLASH, 0, target_index);
game.move.select(ally_move, 1, ally_target); game.move.select(ally_move, 1, ally_target);
await game.move.selectEnemyMove(enemy_move, BattlerIndex.PLAYER_2); await game.move.selectEnemyMove(enemy_move, BattlerIndex.PLAYER_2);
await game.move.selectEnemyMove(Moves.SPLASH); await game.move.selectEnemyMove(MoveId.SPLASH);
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, target_index, attacker_index]); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY_2, target_index, attacker_index]);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
const damageWithGift = initialHp - target.hp; const damageWithGift = initialHp - target.hp;
@ -101,9 +101,9 @@ describe("Abilities - Flower Gift", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.moveset([Moves.SPLASH, Moves.SUNSTEEL_STRIKE, Moves.SUNNY_DAY, Moves.MUD_SLAP]) .moveset([MoveId.SPLASH, MoveId.SUNSTEEL_STRIKE, MoveId.SUNNY_DAY, MoveId.MUD_SLAP])
.enemySpecies(Species.MAGIKARP) .enemySpecies(Species.MAGIKARP)
.enemyMoveset(Moves.SPLASH) .enemyMoveset(MoveId.SPLASH)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyLevel(100) .enemyLevel(100)
.startingLevel(100); .startingLevel(100);
@ -120,8 +120,8 @@ describe("Abilities - Flower Gift", () => {
const magikarpAtkStat = magikarp.getEffectiveStat(Stat.ATK); const magikarpAtkStat = magikarp.getEffectiveStat(Stat.ATK);
const magikarpSpDefStat = magikarp.getEffectiveStat(Stat.SPDEF); const magikarpSpDefStat = magikarp.getEffectiveStat(Stat.SPDEF);
game.move.select(Moves.SUNNY_DAY, 0); game.move.select(MoveId.SUNNY_DAY, 0);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
@ -134,24 +134,29 @@ describe("Abilities - Flower Gift", () => {
}); });
it("should not increase the damage of an ally using an ability ignoring move", async () => { it("should not increase the damage of an ally using an ability ignoring move", async () => {
const [damageWithGift, damageWithoutGift] = await testDamageDealt(game, Moves.SUNSTEEL_STRIKE, true); const [damageWithGift, damageWithoutGift] = await testDamageDealt(game, MoveId.SUNSTEEL_STRIKE, true);
expect(damageWithGift).toBe(damageWithoutGift); expect(damageWithGift).toBe(damageWithoutGift);
}); });
it("should not increase the damage of a mold breaker ally", async () => { it("should not increase the damage of a mold breaker ally", async () => {
const [damageWithGift, damageWithoutGift] = await testDamageDealt(game, Moves.TACKLE, true, AbilityId.MOLD_BREAKER); const [damageWithGift, damageWithoutGift] = await testDamageDealt(
game,
MoveId.TACKLE,
true,
AbilityId.MOLD_BREAKER,
);
expect(damageWithGift).toBe(damageWithoutGift); expect(damageWithGift).toBe(damageWithoutGift);
}); });
it("should decrease the damage an ally takes from a special attack", async () => { it("should decrease the damage an ally takes from a special attack", async () => {
const [damageWithoutGift, damageWithGift] = await testDamageDealt(game, Moves.MUD_SLAP, false); const [damageWithoutGift, damageWithGift] = await testDamageDealt(game, MoveId.MUD_SLAP, false);
expect(damageWithGift).toBeLessThan(damageWithoutGift); expect(damageWithGift).toBeLessThan(damageWithoutGift);
}); });
it("should not decrease the damage an ally takes from a mold breaker enemy using a special attack", async () => { it("should not decrease the damage an ally takes from a mold breaker enemy using a special attack", async () => {
const [damageWithoutGift, damageWithGift] = await testDamageDealt( const [damageWithoutGift, damageWithGift] = await testDamageDealt(
game, game,
Moves.MUD_SLAP, MoveId.MUD_SLAP,
false, false,
AbilityId.BALL_FETCH, AbilityId.BALL_FETCH,
AbilityId.MOLD_BREAKER, AbilityId.MOLD_BREAKER,
@ -166,7 +171,7 @@ describe("Abilities - Flower Gift", () => {
const cherrim = game.scene.getPlayerPokemon()!; const cherrim = game.scene.getPlayerPokemon()!;
expect(cherrim.formIndex).toBe(SUNSHINE_FORM); expect(cherrim.formIndex).toBe(SUNSHINE_FORM);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
}); });
it("reverts to Overcast Form if a Pokémon on the field has Air Lock", async () => { it("reverts to Overcast Form if a Pokémon on the field has Air Lock", async () => {
@ -178,7 +183,7 @@ describe("Abilities - Flower Gift", () => {
}); });
it("reverts to Overcast Form when the Flower Gift is suppressed, changes form under Harsh Sunlight/Sunny when it regains it", async () => { it("reverts to Overcast Form when the Flower Gift is suppressed, changes form under Harsh Sunlight/Sunny when it regains it", async () => {
game.override.enemyMoveset([Moves.GASTRO_ACID]).weather(WeatherType.HARSH_SUN); game.override.enemyMoveset([MoveId.GASTRO_ACID]).weather(WeatherType.HARSH_SUN);
await game.classicMode.startBattle([Species.CHERRIM, Species.MAGIKARP]); await game.classicMode.startBattle([Species.CHERRIM, Species.MAGIKARP]);
@ -186,7 +191,7 @@ describe("Abilities - Flower Gift", () => {
expect(cherrim.formIndex).toBe(SUNSHINE_FORM); expect(cherrim.formIndex).toBe(SUNSHINE_FORM);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");

View File

@ -1,6 +1,6 @@
import { BattlerIndex } from "#app/battle"; import { BattlerIndex } from "#app/battle";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import { StatusEffect } from "#enums/status-effect"; import { StatusEffect } from "#enums/status-effect";
@ -28,14 +28,14 @@ describe("Abilities - Flower Veil", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.moveset([Moves.SPLASH]) .moveset([MoveId.SPLASH])
.enemySpecies(Species.BULBASAUR) .enemySpecies(Species.BULBASAUR)
.ability(AbilityId.FLOWER_VEIL) .ability(AbilityId.FLOWER_VEIL)
.battleStyle("single") .battleStyle("single")
.disableCrits() .disableCrits()
.enemySpecies(Species.MAGIKARP) .enemySpecies(Species.MAGIKARP)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(MoveId.SPLASH);
}); });
/*********************************************** /***********************************************
@ -43,36 +43,36 @@ describe("Abilities - Flower Veil", () => {
***********************************************/ ***********************************************/
it("should not prevent any source of self-inflicted status conditions", async () => { it("should not prevent any source of self-inflicted status conditions", async () => {
game.override game.override
.enemyMoveset([Moves.TACKLE, Moves.SPLASH]) .enemyMoveset([MoveId.TACKLE, MoveId.SPLASH])
.moveset([Moves.REST, Moves.SPLASH]) .moveset([MoveId.REST, MoveId.SPLASH])
.startingHeldItems([{ name: "FLAME_ORB" }]); .startingHeldItems([{ name: "FLAME_ORB" }]);
await game.classicMode.startBattle([Species.BULBASAUR]); await game.classicMode.startBattle([Species.BULBASAUR]);
const user = game.scene.getPlayerPokemon()!; const user = game.scene.getPlayerPokemon()!;
game.move.select(Moves.REST); game.move.select(MoveId.REST);
await game.move.selectEnemyMove(Moves.TACKLE); await game.move.selectEnemyMove(MoveId.TACKLE);
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
await game.toNextTurn(); await game.toNextTurn();
expect(user.status?.effect).toBe(StatusEffect.SLEEP); expect(user.status?.effect).toBe(StatusEffect.SLEEP);
// remove sleep status so we can get burn from the orb // remove sleep status so we can get burn from the orb
user.resetStatus(); user.resetStatus();
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(Moves.SPLASH); await game.move.selectEnemyMove(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
expect(user.status?.effect).toBe(StatusEffect.BURN); expect(user.status?.effect).toBe(StatusEffect.BURN);
}); });
it("should prevent drowsiness from yawn for a grass user and its grass allies", async () => { it("should prevent drowsiness from yawn for a grass user and its grass allies", async () => {
game.override.enemyMoveset([Moves.YAWN]).moveset([Moves.SPLASH]).battleStyle("double"); game.override.enemyMoveset([MoveId.YAWN]).moveset([MoveId.SPLASH]).battleStyle("double");
await game.classicMode.startBattle([Species.BULBASAUR, Species.BULBASAUR]); await game.classicMode.startBattle([Species.BULBASAUR, Species.BULBASAUR]);
// Clear the ability of the ally to isolate the test // Clear the ability of the ally to isolate the test
const ally = game.scene.getPlayerField()[1]!; const ally = game.scene.getPlayerField()[1]!;
vi.spyOn(ally, "getAbility").mockReturnValue(allAbilities[AbilityId.BALL_FETCH]); vi.spyOn(ally, "getAbility").mockReturnValue(allAbilities[AbilityId.BALL_FETCH]);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(Moves.YAWN, BattlerIndex.PLAYER); await game.move.selectEnemyMove(MoveId.YAWN, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(Moves.YAWN, BattlerIndex.PLAYER_2); await game.move.selectEnemyMove(MoveId.YAWN, BattlerIndex.PLAYER_2);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
const user = game.scene.getPlayerPokemon()!; const user = game.scene.getPlayerPokemon()!;
@ -81,28 +81,28 @@ describe("Abilities - Flower Veil", () => {
}); });
it("should prevent status conditions from moves like Thunder Wave for a grass user and its grass allies", async () => { it("should prevent status conditions from moves like Thunder Wave for a grass user and its grass allies", async () => {
game.override.enemyMoveset([Moves.THUNDER_WAVE]).moveset([Moves.SPLASH]).battleStyle("double"); game.override.enemyMoveset([MoveId.THUNDER_WAVE]).moveset([MoveId.SPLASH]).battleStyle("double");
vi.spyOn(allMoves[Moves.THUNDER_WAVE], "accuracy", "get").mockReturnValue(100); vi.spyOn(allMoves[MoveId.THUNDER_WAVE], "accuracy", "get").mockReturnValue(100);
await game.classicMode.startBattle([Species.BULBASAUR]); await game.classicMode.startBattle([Species.BULBASAUR]);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(Moves.THUNDER_WAVE); await game.move.selectEnemyMove(MoveId.THUNDER_WAVE);
await game.toNextTurn(); await game.toNextTurn();
expect(game.scene.getPlayerPokemon()!.status).toBeUndefined(); expect(game.scene.getPlayerPokemon()!.status).toBeUndefined();
vi.spyOn(allMoves[Moves.THUNDER_WAVE], "accuracy", "get").mockClear(); vi.spyOn(allMoves[MoveId.THUNDER_WAVE], "accuracy", "get").mockClear();
}); });
it("should not prevent status conditions for a non-grass user and its non-grass allies", async () => { it("should not prevent status conditions for a non-grass user and its non-grass allies", async () => {
game.override.enemyMoveset([Moves.THUNDER_WAVE]).moveset([Moves.SPLASH]).battleStyle("double"); game.override.enemyMoveset([MoveId.THUNDER_WAVE]).moveset([MoveId.SPLASH]).battleStyle("double");
await game.classicMode.startBattle([Species.MAGIKARP, Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP, Species.MAGIKARP]);
const [user, ally] = game.scene.getPlayerField(); const [user, ally] = game.scene.getPlayerField();
vi.spyOn(allMoves[Moves.THUNDER_WAVE], "accuracy", "get").mockReturnValue(100); vi.spyOn(allMoves[MoveId.THUNDER_WAVE], "accuracy", "get").mockReturnValue(100);
// Clear the ally ability to isolate the test // Clear the ally ability to isolate the test
vi.spyOn(ally, "getAbility").mockReturnValue(allAbilities[AbilityId.BALL_FETCH]); vi.spyOn(ally, "getAbility").mockReturnValue(allAbilities[AbilityId.BALL_FETCH]);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(Moves.THUNDER_WAVE, BattlerIndex.PLAYER); await game.move.selectEnemyMove(MoveId.THUNDER_WAVE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(Moves.THUNDER_WAVE, BattlerIndex.PLAYER_2); await game.move.selectEnemyMove(MoveId.THUNDER_WAVE, BattlerIndex.PLAYER_2);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(user.status?.effect).toBe(StatusEffect.PARALYSIS); expect(user.status?.effect).toBe(StatusEffect.PARALYSIS);
expect(ally.status?.effect).toBe(StatusEffect.PARALYSIS); expect(ally.status?.effect).toBe(StatusEffect.PARALYSIS);
@ -113,40 +113,40 @@ describe("Abilities - Flower Veil", () => {
*******************************************/ *******************************************/
it("should prevent the status drops from enemies for the a grass user and its grass allies", async () => { it("should prevent the status drops from enemies for the a grass user and its grass allies", async () => {
game.override.enemyMoveset([Moves.GROWL]).moveset([Moves.SPLASH]).battleStyle("double"); game.override.enemyMoveset([MoveId.GROWL]).moveset([MoveId.SPLASH]).battleStyle("double");
await game.classicMode.startBattle([Species.BULBASAUR, Species.BULBASAUR]); await game.classicMode.startBattle([Species.BULBASAUR, Species.BULBASAUR]);
const [user, ally] = game.scene.getPlayerField(); const [user, ally] = game.scene.getPlayerField();
// Clear the ally ability to isolate the test // Clear the ally ability to isolate the test
vi.spyOn(ally, "getAbility").mockReturnValue(allAbilities[AbilityId.BALL_FETCH]); vi.spyOn(ally, "getAbility").mockReturnValue(allAbilities[AbilityId.BALL_FETCH]);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(user.getStatStage(Stat.ATK)).toBe(0); expect(user.getStatStage(Stat.ATK)).toBe(0);
expect(ally.getStatStage(Stat.ATK)).toBe(0); expect(ally.getStatStage(Stat.ATK)).toBe(0);
}); });
it("should not prevent status drops for a non-grass user and its non-grass allies", async () => { it("should not prevent status drops for a non-grass user and its non-grass allies", async () => {
game.override.enemyMoveset([Moves.GROWL]).moveset([Moves.SPLASH]).battleStyle("double"); game.override.enemyMoveset([MoveId.GROWL]).moveset([MoveId.SPLASH]).battleStyle("double");
await game.classicMode.startBattle([Species.MAGIKARP, Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP, Species.MAGIKARP]);
const [user, ally] = game.scene.getPlayerField(); const [user, ally] = game.scene.getPlayerField();
// Clear the ally ability to isolate the test // Clear the ally ability to isolate the test
vi.spyOn(ally, "getAbility").mockReturnValue(allAbilities[AbilityId.BALL_FETCH]); vi.spyOn(ally, "getAbility").mockReturnValue(allAbilities[AbilityId.BALL_FETCH]);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(user.getStatStage(Stat.ATK)).toBe(-2); expect(user.getStatStage(Stat.ATK)).toBe(-2);
expect(ally.getStatStage(Stat.ATK)).toBe(-2); expect(ally.getStatStage(Stat.ATK)).toBe(-2);
}); });
it("should not prevent self-inflicted stat drops from moves like Close Combat for a user or its allies", async () => { it("should not prevent self-inflicted stat drops from moves like Close Combat for a user or its allies", async () => {
game.override.moveset([Moves.CLOSE_COMBAT]).battleStyle("double"); game.override.moveset([MoveId.CLOSE_COMBAT]).battleStyle("double");
await game.classicMode.startBattle([Species.BULBASAUR, Species.BULBASAUR]); await game.classicMode.startBattle([Species.BULBASAUR, Species.BULBASAUR]);
const [user, ally] = game.scene.getPlayerField(); const [user, ally] = game.scene.getPlayerField();
// Clear the ally ability to isolate the test // Clear the ally ability to isolate the test
vi.spyOn(ally, "getAbility").mockReturnValue(allAbilities[AbilityId.BALL_FETCH]); vi.spyOn(ally, "getAbility").mockReturnValue(allAbilities[AbilityId.BALL_FETCH]);
game.move.select(Moves.CLOSE_COMBAT, 0, BattlerIndex.ENEMY); game.move.select(MoveId.CLOSE_COMBAT, 0, BattlerIndex.ENEMY);
game.move.select(Moves.CLOSE_COMBAT, 1, BattlerIndex.ENEMY_2); game.move.select(MoveId.CLOSE_COMBAT, 1, BattlerIndex.ENEMY_2);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(user.getStatStage(Stat.DEF)).toBe(-1); expect(user.getStatStage(Stat.DEF)).toBe(-1);
expect(user.getStatStage(Stat.SPDEF)).toBe(-1); expect(user.getStatStage(Stat.SPDEF)).toBe(-1);
@ -155,10 +155,10 @@ describe("Abilities - Flower Veil", () => {
}); });
it("should prevent the drops while retaining the boosts from spicy extract", async () => { it("should prevent the drops while retaining the boosts from spicy extract", async () => {
game.override.enemyMoveset([Moves.SPICY_EXTRACT]).moveset([Moves.SPLASH]); game.override.enemyMoveset([MoveId.SPICY_EXTRACT]).moveset([MoveId.SPLASH]);
await game.classicMode.startBattle([Species.BULBASAUR]); await game.classicMode.startBattle([Species.BULBASAUR]);
const user = game.scene.getPlayerPokemon()!; const user = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(user.getStatStage(Stat.ATK)).toBe(2); expect(user.getStatStage(Stat.ATK)).toBe(2);
expect(user.getStatStage(Stat.DEF)).toBe(0); expect(user.getStatStage(Stat.DEF)).toBe(0);

View File

@ -7,7 +7,7 @@ import { MovePhase } from "#app/phases/move-phase";
import { PostSummonPhase } from "#app/phases/post-summon-phase"; import { PostSummonPhase } from "#app/phases/post-summon-phase";
import { QuietFormChangePhase } from "#app/phases/quiet-form-change-phase"; import { QuietFormChangePhase } from "#app/phases/quiet-form-change-phase";
import { TurnEndPhase } from "#app/phases/turn-end-phase"; import { TurnEndPhase } from "#app/phases/turn-end-phase";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
@ -32,7 +32,7 @@ describe("Abilities - Forecast", () => {
game.override.weather(weather).starterForms({ [Species.CASTFORM]: initialForm }); game.override.weather(weather).starterForms({ [Species.CASTFORM]: initialForm });
await game.classicMode.startBattle([Species.CASTFORM]); await game.classicMode.startBattle([Species.CASTFORM]);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
expect(game.scene.getPlayerPokemon()?.formIndex).toBe(form); expect(game.scene.getPlayerPokemon()?.formIndex).toBe(form);
}; };
@ -46,7 +46,7 @@ describe("Abilities - Forecast", () => {
game.override.starterForms({ [Species.CASTFORM]: SUNNY_FORM }).enemyAbility(ability); game.override.starterForms({ [Species.CASTFORM]: SUNNY_FORM }).enemyAbility(ability);
await game.classicMode.startBattle([Species.CASTFORM]); await game.classicMode.startBattle([Species.CASTFORM]);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
expect(game.scene.getPlayerPokemon()?.formIndex).toBe(NORMAL_FORM); expect(game.scene.getPlayerPokemon()?.formIndex).toBe(NORMAL_FORM);
}; };
@ -64,9 +64,9 @@ describe("Abilities - Forecast", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.moveset([Moves.SPLASH, Moves.RAIN_DANCE, Moves.SUNNY_DAY, Moves.TACKLE]) .moveset([MoveId.SPLASH, MoveId.RAIN_DANCE, MoveId.SUNNY_DAY, MoveId.TACKLE])
.enemySpecies(Species.MAGIKARP) .enemySpecies(Species.MAGIKARP)
.enemyMoveset(Moves.SPLASH) .enemyMoveset(MoveId.SPLASH)
.enemyAbility(AbilityId.BALL_FETCH); .enemyAbility(AbilityId.BALL_FETCH);
}); });
@ -74,7 +74,7 @@ describe("Abilities - Forecast", () => {
"changes form based on weather", "changes form based on weather",
async () => { async () => {
game.override game.override
.moveset([Moves.RAIN_DANCE, Moves.SUNNY_DAY, Moves.SNOWSCAPE, Moves.SPLASH]) .moveset([MoveId.RAIN_DANCE, MoveId.SUNNY_DAY, MoveId.SNOWSCAPE, MoveId.SPLASH])
.battleStyle("double") .battleStyle("double")
.starterForms({ .starterForms({
[Species.KYOGRE]: 1, [Species.KYOGRE]: 1,
@ -95,86 +95,86 @@ describe("Abilities - Forecast", () => {
const castform = game.scene.getPlayerField()[0]; const castform = game.scene.getPlayerField()[0];
expect(castform.formIndex).toBe(NORMAL_FORM); expect(castform.formIndex).toBe(NORMAL_FORM);
game.move.select(Moves.RAIN_DANCE); game.move.select(MoveId.RAIN_DANCE);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("MovePhase"); await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn(); await game.toNextTurn();
expect(castform.formIndex).toBe(RAINY_FORM); expect(castform.formIndex).toBe(RAINY_FORM);
game.move.select(Moves.SUNNY_DAY); game.move.select(MoveId.SUNNY_DAY);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("MovePhase"); await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn(); await game.toNextTurn();
expect(castform.formIndex).toBe(SUNNY_FORM); expect(castform.formIndex).toBe(SUNNY_FORM);
game.move.select(Moves.SNOWSCAPE); game.move.select(MoveId.SNOWSCAPE);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("MovePhase"); await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn(); await game.toNextTurn();
expect(castform.formIndex).toBe(SNOWY_FORM); expect(castform.formIndex).toBe(SNOWY_FORM);
game.override.moveset([Moves.HAIL, Moves.SANDSTORM, Moves.SNOWSCAPE, Moves.SPLASH]); game.override.moveset([MoveId.HAIL, MoveId.SANDSTORM, MoveId.SNOWSCAPE, MoveId.SPLASH]);
game.move.select(Moves.SANDSTORM); game.move.select(MoveId.SANDSTORM);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("MovePhase"); await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn(); await game.toNextTurn();
expect(castform.formIndex).toBe(NORMAL_FORM); expect(castform.formIndex).toBe(NORMAL_FORM);
game.move.select(Moves.HAIL); game.move.select(MoveId.HAIL);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("MovePhase"); await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn(); await game.toNextTurn();
expect(castform.formIndex).toBe(SNOWY_FORM); expect(castform.formIndex).toBe(SNOWY_FORM);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
game.doSwitchPokemon(2); // Feebas now 2, Kyogre 1 game.doSwitchPokemon(2); // Feebas now 2, Kyogre 1
await game.phaseInterceptor.to("MovePhase"); await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn(); await game.toNextTurn();
expect(castform.formIndex).toBe(RAINY_FORM); expect(castform.formIndex).toBe(RAINY_FORM);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
game.doSwitchPokemon(3); // Kyogre now 3, Groudon 1 game.doSwitchPokemon(3); // Kyogre now 3, Groudon 1
await game.phaseInterceptor.to("MovePhase"); await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn(); await game.toNextTurn();
expect(castform.formIndex).toBe(SUNNY_FORM); expect(castform.formIndex).toBe(SUNNY_FORM);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
game.doSwitchPokemon(4); // Groudon now 4, Rayquaza 1 game.doSwitchPokemon(4); // Groudon now 4, Rayquaza 1
await game.phaseInterceptor.to("MovePhase"); await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn(); await game.toNextTurn();
expect(castform.formIndex).toBe(NORMAL_FORM); expect(castform.formIndex).toBe(NORMAL_FORM);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
game.doSwitchPokemon(2); // Rayquaza now 2, Feebas 1 game.doSwitchPokemon(2); // Rayquaza now 2, Feebas 1
await game.phaseInterceptor.to("MovePhase"); await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn(); await game.toNextTurn();
expect(castform.formIndex).toBe(NORMAL_FORM); expect(castform.formIndex).toBe(NORMAL_FORM);
game.move.select(Moves.SNOWSCAPE); game.move.select(MoveId.SNOWSCAPE);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("MovePhase"); await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn(); await game.toNextTurn();
expect(castform.formIndex).toBe(SNOWY_FORM); expect(castform.formIndex).toBe(SNOWY_FORM);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
game.doSwitchPokemon(5); // Feebas now 5, Altaria 1 game.doSwitchPokemon(5); // Feebas now 5, Altaria 1
await game.phaseInterceptor.to("MovePhase"); await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn(); await game.toNextTurn();
expect(castform.formIndex).toBe(NORMAL_FORM); expect(castform.formIndex).toBe(NORMAL_FORM);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
game.doSwitchPokemon(5); // Altaria now 5, Feebas 1 game.doSwitchPokemon(5); // Altaria now 5, Feebas 1
await game.phaseInterceptor.to("MovePhase"); await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn(); await game.toNextTurn();
@ -182,8 +182,8 @@ describe("Abilities - Forecast", () => {
expect(castform.formIndex).toBe(SNOWY_FORM); expect(castform.formIndex).toBe(SNOWY_FORM);
game.scene.arena.trySetWeather(WeatherType.FOG); game.scene.arena.trySetWeather(WeatherType.FOG);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("TurnStartPhase"); await game.phaseInterceptor.to("TurnStartPhase");
expect(castform.formIndex).toBe(NORMAL_FORM); expect(castform.formIndex).toBe(NORMAL_FORM);
@ -203,7 +203,7 @@ describe("Abilities - Forecast", () => {
game.override.enemyAbility(AbilityId.FORECAST).enemySpecies(Species.SHUCKLE); game.override.enemyAbility(AbilityId.FORECAST).enemySpecies(Species.SHUCKLE);
await game.classicMode.startBattle([Species.CASTFORM]); await game.classicMode.startBattle([Species.CASTFORM]);
game.move.select(Moves.RAIN_DANCE); game.move.select(MoveId.RAIN_DANCE);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
expect(game.scene.getPlayerPokemon()?.formIndex).toBe(RAINY_FORM); expect(game.scene.getPlayerPokemon()?.formIndex).toBe(RAINY_FORM);
@ -211,14 +211,14 @@ describe("Abilities - Forecast", () => {
}); });
it("reverts to Normal Form when Forecast is suppressed, changes form to match the weather when it regains it", async () => { it("reverts to Normal Form when Forecast is suppressed, changes form to match the weather when it regains it", async () => {
game.override.enemyMoveset([Moves.GASTRO_ACID]).weather(WeatherType.RAIN); game.override.enemyMoveset([MoveId.GASTRO_ACID]).weather(WeatherType.RAIN);
await game.classicMode.startBattle([Species.CASTFORM, Species.PIKACHU]); await game.classicMode.startBattle([Species.CASTFORM, Species.PIKACHU]);
const castform = game.scene.getPlayerPokemon()!; const castform = game.scene.getPlayerPokemon()!;
expect(castform.formIndex).toBe(RAINY_FORM); expect(castform.formIndex).toBe(RAINY_FORM);
// First turn - Forecast is suppressed // First turn - Forecast is suppressed
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
await game.move.forceHit(); await game.move.forceHit();
@ -242,11 +242,11 @@ describe("Abilities - Forecast", () => {
}); });
it("does not change Castform's form until after Stealth Rock deals damage", async () => { it("does not change Castform's form until after Stealth Rock deals damage", async () => {
game.override.weather(WeatherType.RAIN).enemyMoveset([Moves.STEALTH_ROCK]); game.override.weather(WeatherType.RAIN).enemyMoveset([MoveId.STEALTH_ROCK]);
await game.classicMode.startBattle([Species.PIKACHU, Species.CASTFORM]); await game.classicMode.startBattle([Species.PIKACHU, Species.CASTFORM]);
// First turn - set up stealth rock // First turn - set up stealth rock
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
// Second turn - switch in Castform, regains Forecast // Second turn - switch in Castform, regains Forecast

View File

@ -1,4 +1,4 @@
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
@ -28,9 +28,9 @@ describe("Moves - Friend Guard", () => {
game.override game.override
.battleStyle("double") .battleStyle("double")
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset([Moves.TACKLE, Moves.SPLASH, Moves.DRAGON_RAGE]) .enemyMoveset([MoveId.TACKLE, MoveId.SPLASH, MoveId.DRAGON_RAGE])
.enemySpecies(Species.SHUCKLE) .enemySpecies(Species.SHUCKLE)
.moveset([Moves.SPLASH]) .moveset([MoveId.SPLASH])
.startingLevel(100); .startingLevel(100);
}); });
@ -41,10 +41,10 @@ describe("Moves - Friend Guard", () => {
const enemy1 = game.scene.getEnemyField()[0]; const enemy1 = game.scene.getEnemyField()[0];
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.move.selectEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER); await game.move.selectEnemyMove(MoveId.TACKLE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(Moves.SPLASH); await game.move.selectEnemyMove(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
// Get the last return value from `getAttackDamage` // Get the last return value from `getAttackDamage`
@ -52,16 +52,16 @@ describe("Moves - Friend Guard", () => {
// Making sure the test is controlled; turn 1 damage is equal to base damage (after rounding) // Making sure the test is controlled; turn 1 damage is equal to base damage (after rounding)
expect(turn1Damage).toBe( expect(turn1Damage).toBe(
Math.floor( Math.floor(
player1.getBaseDamage({ source: enemy1, move: allMoves[Moves.TACKLE], moveCategory: MoveCategory.PHYSICAL }), player1.getBaseDamage({ source: enemy1, move: allMoves[MoveId.TACKLE], moveCategory: MoveCategory.PHYSICAL }),
), ),
); );
vi.spyOn(player2, "getAbility").mockReturnValue(allAbilities[AbilityId.FRIEND_GUARD]); vi.spyOn(player2, "getAbility").mockReturnValue(allAbilities[AbilityId.FRIEND_GUARD]);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.move.selectEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER); await game.move.selectEnemyMove(MoveId.TACKLE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(Moves.SPLASH); await game.move.selectEnemyMove(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
// Get the last return value from `getAttackDamage` // Get the last return value from `getAttackDamage`
@ -69,7 +69,7 @@ describe("Moves - Friend Guard", () => {
// With the ally's Friend Guard, damage should have been reduced from base damage by 25% // With the ally's Friend Guard, damage should have been reduced from base damage by 25%
expect(turn2Damage).toBe( expect(turn2Damage).toBe(
Math.floor( Math.floor(
player1.getBaseDamage({ source: enemy1, move: allMoves[Moves.TACKLE], moveCategory: MoveCategory.PHYSICAL }) * player1.getBaseDamage({ source: enemy1, move: allMoves[MoveId.TACKLE], moveCategory: MoveCategory.PHYSICAL }) *
0.75, 0.75,
), ),
); );
@ -81,20 +81,20 @@ describe("Moves - Friend Guard", () => {
const player2 = game.scene.getPlayerField()[1]; const player2 = game.scene.getPlayerField()[1];
const spy = vi.spyOn(player2, "getAttackDamage"); const spy = vi.spyOn(player2, "getAttackDamage");
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.move.selectEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER_2); await game.move.selectEnemyMove(MoveId.TACKLE, BattlerIndex.PLAYER_2);
await game.move.selectEnemyMove(Moves.SPLASH); await game.move.selectEnemyMove(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
const turn1Damage = spy.mock.results[spy.mock.results.length - 1].value.damage; const turn1Damage = spy.mock.results[spy.mock.results.length - 1].value.damage;
vi.spyOn(player2, "getAbility").mockReturnValue(allAbilities[AbilityId.FRIEND_GUARD]); vi.spyOn(player2, "getAbility").mockReturnValue(allAbilities[AbilityId.FRIEND_GUARD]);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.move.selectEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER_2); await game.move.selectEnemyMove(MoveId.TACKLE, BattlerIndex.PLAYER_2);
await game.move.selectEnemyMove(Moves.SPLASH); await game.move.selectEnemyMove(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
const turn2Damage = spy.mock.results[spy.mock.results.length - 1].value.damage; const turn2Damage = spy.mock.results[spy.mock.results.length - 1].value.damage;
@ -107,10 +107,10 @@ describe("Moves - Friend Guard", () => {
const [player1, player2] = game.scene.getPlayerField(); const [player1, player2] = game.scene.getPlayerField();
const spy = vi.spyOn(player1, "getAttackDamage"); const spy = vi.spyOn(player1, "getAttackDamage");
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.move.selectEnemyMove(Moves.DRAGON_RAGE, BattlerIndex.PLAYER); await game.move.selectEnemyMove(MoveId.DRAGON_RAGE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(Moves.SPLASH); await game.move.selectEnemyMove(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
const turn1Damage = spy.mock.results[spy.mock.results.length - 1].value.damage; const turn1Damage = spy.mock.results[spy.mock.results.length - 1].value.damage;
@ -118,10 +118,10 @@ describe("Moves - Friend Guard", () => {
vi.spyOn(player2, "getAbility").mockReturnValue(allAbilities[AbilityId.FRIEND_GUARD]); vi.spyOn(player2, "getAbility").mockReturnValue(allAbilities[AbilityId.FRIEND_GUARD]);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.move.selectEnemyMove(Moves.DRAGON_RAGE, BattlerIndex.PLAYER); await game.move.selectEnemyMove(MoveId.DRAGON_RAGE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(Moves.SPLASH); await game.move.selectEnemyMove(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
const turn2Damage = spy.mock.results[spy.mock.results.length - 1].value.damage; const turn2Damage = spy.mock.results[spy.mock.results.length - 1].value.damage;

View File

@ -7,7 +7,7 @@ import { Stat } from "#app/enums/stat";
import { StatusEffect } from "#app/enums/status-effect"; import { StatusEffect } from "#app/enums/status-effect";
import { WeatherType } from "#app/enums/weather-type"; import { WeatherType } from "#app/enums/weather-type";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
@ -30,22 +30,22 @@ describe("Abilities - Good As Gold", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.moveset([Moves.SPLASH]) .moveset([MoveId.SPLASH])
.ability(AbilityId.GOOD_AS_GOLD) .ability(AbilityId.GOOD_AS_GOLD)
.battleStyle("single") .battleStyle("single")
.disableCrits() .disableCrits()
.enemySpecies(Species.MAGIKARP) .enemySpecies(Species.MAGIKARP)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(MoveId.SPLASH);
}); });
it("should block normal status moves", async () => { it("should block normal status moves", async () => {
game.override.enemyMoveset([Moves.GROWL]); game.override.enemyMoveset([MoveId.GROWL]);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
const player = game.scene.getPlayerPokemon()!; const player = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SPLASH, 0); game.move.select(MoveId.SPLASH, 0);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
@ -54,9 +54,9 @@ describe("Abilities - Good As Gold", () => {
}); });
it("should block memento and prevent the user from fainting", async () => { it("should block memento and prevent the user from fainting", async () => {
game.override.enemyMoveset([Moves.MEMENTO]); game.override.enemyMoveset([MoveId.MEMENTO]);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
game.move.select(Moves.MEMENTO); game.move.select(MoveId.MEMENTO);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(game.scene.getPlayerPokemon()!.isFainted()).toBe(false); expect(game.scene.getPlayerPokemon()!.isFainted()).toBe(false);
expect(game.scene.getEnemyPokemon()?.getStatStage(Stat.ATK)).toBe(0); expect(game.scene.getEnemyPokemon()?.getStatStage(Stat.ATK)).toBe(0);
@ -64,18 +64,18 @@ describe("Abilities - Good As Gold", () => {
it("should not block any status moves that target the field, one side, or all pokemon", async () => { it("should not block any status moves that target the field, one side, or all pokemon", async () => {
game.override.battleStyle("double"); game.override.battleStyle("double");
game.override.enemyMoveset([Moves.STEALTH_ROCK, Moves.HAZE]); game.override.enemyMoveset([MoveId.STEALTH_ROCK, MoveId.HAZE]);
game.override.moveset([Moves.SWORDS_DANCE, Moves.SAFEGUARD]); game.override.moveset([MoveId.SWORDS_DANCE, MoveId.SAFEGUARD]);
await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS]); await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS]);
const [good_as_gold, ball_fetch] = game.scene.getPlayerField(); const [good_as_gold, ball_fetch] = game.scene.getPlayerField();
// Force second pokemon to have ball fetch to isolate to a single mon. // Force second pokemon to have ball fetch to isolate to a single mon.
vi.spyOn(ball_fetch, "getAbility").mockReturnValue(allAbilities[AbilityId.BALL_FETCH]); vi.spyOn(ball_fetch, "getAbility").mockReturnValue(allAbilities[AbilityId.BALL_FETCH]);
game.move.select(Moves.SWORDS_DANCE, 0); game.move.select(MoveId.SWORDS_DANCE, 0);
game.move.select(Moves.SAFEGUARD, 1); game.move.select(MoveId.SAFEGUARD, 1);
await game.move.selectEnemyMove(Moves.STEALTH_ROCK); await game.move.selectEnemyMove(MoveId.STEALTH_ROCK);
await game.move.selectEnemyMove(Moves.HAZE); await game.move.selectEnemyMove(MoveId.HAZE);
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(good_as_gold.getAbility().id).toBe(AbilityId.GOOD_AS_GOLD); expect(good_as_gold.getAbility().id).toBe(AbilityId.GOOD_AS_GOLD);
@ -86,10 +86,10 @@ describe("Abilities - Good As Gold", () => {
it("should not block field targeted effects in singles", async () => { it("should not block field targeted effects in singles", async () => {
game.override.battleStyle("single"); game.override.battleStyle("single");
game.override.enemyMoveset([Moves.SPIKES]); game.override.enemyMoveset([MoveId.SPIKES]);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
game.move.select(Moves.SPLASH, 0); game.move.select(MoveId.SPLASH, 0);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(game.scene.arena.getTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.PLAYER)).toBeDefined(); expect(game.scene.arena.getTagOnSide(ArenaTagType.SPIKES, ArenaTagSide.PLAYER)).toBeDefined();
@ -97,11 +97,11 @@ describe("Abilities - Good As Gold", () => {
it("should block the ally's helping hand", async () => { it("should block the ally's helping hand", async () => {
game.override.battleStyle("double"); game.override.battleStyle("double");
game.override.moveset([Moves.HELPING_HAND, Moves.TACKLE]); game.override.moveset([MoveId.HELPING_HAND, MoveId.TACKLE]);
await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS]); await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS]);
game.move.select(Moves.HELPING_HAND, 0); game.move.select(MoveId.HELPING_HAND, 0);
game.move.select(Moves.TACKLE, 1); game.move.select(MoveId.TACKLE, 1);
await game.phaseInterceptor.to("MoveEndPhase", true); await game.phaseInterceptor.to("MoveEndPhase", true);
expect(game.scene.getPlayerField()[1].getTag(BattlerTagType.HELPING_HAND)).toBeUndefined(); expect(game.scene.getPlayerField()[1].getTag(BattlerTagType.HELPING_HAND)).toBeUndefined();
@ -117,23 +117,23 @@ describe("Abilities - Good As Gold", () => {
game.field.mockAbility(abra, AbilityId.BALL_FETCH); game.field.mockAbility(abra, AbilityId.BALL_FETCH);
// turn 1 // turn 1
game.move.use(Moves.SPLASH, 0); game.move.use(MoveId.SPLASH, 0);
game.move.use(Moves.HEAL_BELL, 1); game.move.use(MoveId.HEAL_BELL, 1);
await game.toNextTurn(); await game.toNextTurn();
expect(milotic.status?.effect).toBe(StatusEffect.BURN); expect(milotic.status?.effect).toBe(StatusEffect.BURN);
game.doSwitchPokemon(2); game.doSwitchPokemon(2);
game.move.use(Moves.HEAL_BELL, 1); game.move.use(MoveId.HEAL_BELL, 1);
await game.toNextTurn(); await game.toNextTurn();
expect(milotic.status?.effect).toBeUndefined(); expect(milotic.status?.effect).toBeUndefined();
}); });
it("should not block field targeted effects like rain dance", async () => { it("should not block field targeted effects like rain dance", async () => {
game.override.battleStyle("single"); game.override.battleStyle("single");
game.override.enemyMoveset([Moves.RAIN_DANCE]); game.override.enemyMoveset([MoveId.RAIN_DANCE]);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
game.move.use(Moves.SPLASH, 0); game.move.use(MoveId.SPLASH, 0);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(game.scene.arena.weather?.weatherType).toBe(WeatherType.RAIN); expect(game.scene.arena.weather?.weatherType).toBe(WeatherType.RAIN);

View File

@ -1,5 +1,5 @@
import { BattlerIndex } from "#app/battle"; import { BattlerIndex } from "#app/battle";
import { Moves } from "#app/enums/moves"; import { MoveId } from "#app/enums/moves";
import { Species } from "#app/enums/species"; import { Species } from "#app/enums/species";
import { Stat } from "#app/enums/stat"; import { Stat } from "#app/enums/stat";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
@ -25,10 +25,10 @@ describe("Abilities - Gorilla Tactics", () => {
game.override game.override
.battleStyle("single") .battleStyle("single")
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset([Moves.SPLASH, Moves.DISABLE]) .enemyMoveset([MoveId.SPLASH, MoveId.DISABLE])
.enemySpecies(Species.MAGIKARP) .enemySpecies(Species.MAGIKARP)
.enemyLevel(30) .enemyLevel(30)
.moveset([Moves.SPLASH, Moves.TACKLE, Moves.GROWL]) .moveset([MoveId.SPLASH, MoveId.TACKLE, MoveId.GROWL])
.ability(AbilityId.GORILLA_TACTICS); .ability(AbilityId.GORILLA_TACTICS);
}); });
@ -38,15 +38,15 @@ describe("Abilities - Gorilla Tactics", () => {
const darmanitan = game.scene.getPlayerPokemon()!; const darmanitan = game.scene.getPlayerPokemon()!;
const initialAtkStat = darmanitan.getStat(Stat.ATK); const initialAtkStat = darmanitan.getStat(Stat.ATK);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(Moves.SPLASH); await game.move.selectEnemyMove(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(darmanitan.getStat(Stat.ATK, false)).toBeCloseTo(initialAtkStat * 1.5); expect(darmanitan.getStat(Stat.ATK, false)).toBeCloseTo(initialAtkStat * 1.5);
// Other moves should be restricted // Other moves should be restricted
expect(darmanitan.isMoveRestricted(Moves.TACKLE)).toBe(true); expect(darmanitan.isMoveRestricted(MoveId.TACKLE)).toBe(true);
expect(darmanitan.isMoveRestricted(Moves.SPLASH)).toBe(false); expect(darmanitan.isMoveRestricted(MoveId.SPLASH)).toBe(false);
}); });
it("should struggle if the only usable move is disabled", async () => { it("should struggle if the only usable move is disabled", async () => {
@ -56,14 +56,14 @@ describe("Abilities - Gorilla Tactics", () => {
const enemy = game.scene.getEnemyPokemon()!; const enemy = game.scene.getEnemyPokemon()!;
// First turn, lock move to Growl // First turn, lock move to Growl
game.move.select(Moves.GROWL); game.move.select(MoveId.GROWL);
await game.move.selectEnemyMove(Moves.SPLASH); await game.move.selectEnemyMove(MoveId.SPLASH);
// Second turn, Growl is interrupted by Disable // Second turn, Growl is interrupted by Disable
await game.toNextTurn(); await game.toNextTurn();
game.move.select(Moves.GROWL); game.move.select(MoveId.GROWL);
await game.move.selectEnemyMove(Moves.DISABLE); await game.move.selectEnemyMove(MoveId.DISABLE);
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
@ -72,7 +72,7 @@ describe("Abilities - Gorilla Tactics", () => {
// Third turn, Struggle is used // Third turn, Struggle is used
await game.toNextTurn(); await game.toNextTurn();
game.move.select(Moves.TACKLE); game.move.select(MoveId.TACKLE);
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");

View File

@ -2,7 +2,7 @@ import { BattlerIndex } from "#app/battle";
import type Pokemon from "#app/field/pokemon"; import type Pokemon from "#app/field/pokemon";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import { StatusEffect } from "#enums/status-effect"; import { StatusEffect } from "#enums/status-effect";
@ -43,10 +43,10 @@ describe("Abilities - Gulp Missile", () => {
game.override game.override
.disableCrits() .disableCrits()
.battleStyle("single") .battleStyle("single")
.moveset([Moves.SURF, Moves.DIVE, Moves.SPLASH, Moves.SUBSTITUTE]) .moveset([MoveId.SURF, MoveId.DIVE, MoveId.SPLASH, MoveId.SUBSTITUTE])
.enemySpecies(Species.SNORLAX) .enemySpecies(Species.SNORLAX)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH) .enemyMoveset(MoveId.SPLASH)
.enemyLevel(5); .enemyLevel(5);
}); });
@ -54,9 +54,9 @@ describe("Abilities - Gulp Missile", () => {
await game.classicMode.startBattle([Species.CRAMORANT]); await game.classicMode.startBattle([Species.CRAMORANT]);
const cramorant = game.scene.getPlayerPokemon()!; const cramorant = game.scene.getPlayerPokemon()!;
game.move.select(Moves.DIVE); game.move.select(MoveId.DIVE);
await game.toNextTurn(); await game.toNextTurn();
game.move.select(Moves.DIVE); game.move.select(MoveId.DIVE);
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(cramorant.getHpRatio()).toBeGreaterThanOrEqual(0.5); expect(cramorant.getHpRatio()).toBeGreaterThanOrEqual(0.5);
@ -71,7 +71,7 @@ describe("Abilities - Gulp Missile", () => {
vi.spyOn(cramorant, "getHpRatio").mockReturnValue(0.49); vi.spyOn(cramorant, "getHpRatio").mockReturnValue(0.49);
expect(cramorant.getHpRatio()).toBe(0.49); expect(cramorant.getHpRatio()).toBe(0.49);
game.move.select(Moves.SURF); game.move.select(MoveId.SURF);
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_PIKACHU)).toBeDefined(); expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_PIKACHU)).toBeDefined();
@ -82,7 +82,7 @@ describe("Abilities - Gulp Missile", () => {
await game.classicMode.startBattle([Species.CRAMORANT, Species.MAGIKARP]); await game.classicMode.startBattle([Species.CRAMORANT, Species.MAGIKARP]);
const cramorant = game.scene.getPlayerPokemon()!; const cramorant = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SURF); game.move.select(MoveId.SURF);
await game.toNextTurn(); await game.toNextTurn();
game.doSwitchPokemon(1); game.doSwitchPokemon(1);
@ -97,7 +97,7 @@ describe("Abilities - Gulp Missile", () => {
await game.classicMode.startBattle([Species.CRAMORANT]); await game.classicMode.startBattle([Species.CRAMORANT]);
const cramorant = game.scene.getPlayerPokemon()!; const cramorant = game.scene.getPlayerPokemon()!;
game.move.select(Moves.DIVE); game.move.select(MoveId.DIVE);
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined(); expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined();
@ -105,26 +105,26 @@ describe("Abilities - Gulp Missile", () => {
}); });
it("deals 1/4 of the attacker's maximum HP when hit by a damaging attack", async () => { it("deals 1/4 of the attacker's maximum HP when hit by a damaging attack", async () => {
game.override.enemyMoveset(Moves.TACKLE); game.override.enemyMoveset(MoveId.TACKLE);
await game.classicMode.startBattle([Species.CRAMORANT]); await game.classicMode.startBattle([Species.CRAMORANT]);
const enemy = game.scene.getEnemyPokemon()!; const enemy = game.scene.getEnemyPokemon()!;
vi.spyOn(enemy, "damageAndUpdate"); vi.spyOn(enemy, "damageAndUpdate");
game.move.select(Moves.SURF); game.move.select(MoveId.SURF);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(enemy.damageAndUpdate).toHaveReturnedWith(getEffectDamage(enemy)); expect(enemy.damageAndUpdate).toHaveReturnedWith(getEffectDamage(enemy));
}); });
it("does not have any effect when hit by non-damaging attack", async () => { it("does not have any effect when hit by non-damaging attack", async () => {
game.override.enemyMoveset(Moves.TAIL_WHIP); game.override.enemyMoveset(MoveId.TAIL_WHIP);
await game.classicMode.startBattle([Species.CRAMORANT]); await game.classicMode.startBattle([Species.CRAMORANT]);
const cramorant = game.scene.getPlayerPokemon()!; const cramorant = game.scene.getPlayerPokemon()!;
vi.spyOn(cramorant, "getHpRatio").mockReturnValue(0.55); vi.spyOn(cramorant, "getHpRatio").mockReturnValue(0.55);
game.move.select(Moves.SURF); game.move.select(MoveId.SURF);
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined(); expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined();
@ -137,7 +137,7 @@ describe("Abilities - Gulp Missile", () => {
}); });
it("lowers attacker's DEF stat stage by 1 when hit in Gulping form", async () => { it("lowers attacker's DEF stat stage by 1 when hit in Gulping form", async () => {
game.override.enemyMoveset(Moves.TACKLE); game.override.enemyMoveset(MoveId.TACKLE);
await game.classicMode.startBattle([Species.CRAMORANT]); await game.classicMode.startBattle([Species.CRAMORANT]);
const cramorant = game.scene.getPlayerPokemon()!; const cramorant = game.scene.getPlayerPokemon()!;
@ -146,7 +146,7 @@ describe("Abilities - Gulp Missile", () => {
vi.spyOn(enemy, "damageAndUpdate"); vi.spyOn(enemy, "damageAndUpdate");
vi.spyOn(cramorant, "getHpRatio").mockReturnValue(0.55); vi.spyOn(cramorant, "getHpRatio").mockReturnValue(0.55);
game.move.select(Moves.SURF); game.move.select(MoveId.SURF);
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined(); expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined();
@ -161,7 +161,7 @@ describe("Abilities - Gulp Missile", () => {
}); });
it("paralyzes the enemy when hit in Gorging form", async () => { it("paralyzes the enemy when hit in Gorging form", async () => {
game.override.enemyMoveset(Moves.TACKLE); game.override.enemyMoveset(MoveId.TACKLE);
await game.classicMode.startBattle([Species.CRAMORANT]); await game.classicMode.startBattle([Species.CRAMORANT]);
const cramorant = game.scene.getPlayerPokemon()!; const cramorant = game.scene.getPlayerPokemon()!;
@ -170,7 +170,7 @@ describe("Abilities - Gulp Missile", () => {
vi.spyOn(enemy, "damageAndUpdate"); vi.spyOn(enemy, "damageAndUpdate");
vi.spyOn(cramorant, "getHpRatio").mockReturnValue(0.45); vi.spyOn(cramorant, "getHpRatio").mockReturnValue(0.45);
game.move.select(Moves.SURF); game.move.select(MoveId.SURF);
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_PIKACHU)).toBeDefined(); expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_PIKACHU)).toBeDefined();
@ -185,12 +185,12 @@ describe("Abilities - Gulp Missile", () => {
}); });
it("does not activate the ability when underwater", async () => { it("does not activate the ability when underwater", async () => {
game.override.enemyMoveset(Moves.SURF); game.override.enemyMoveset(MoveId.SURF);
await game.classicMode.startBattle([Species.CRAMORANT]); await game.classicMode.startBattle([Species.CRAMORANT]);
const cramorant = game.scene.getPlayerPokemon()!; const cramorant = game.scene.getPlayerPokemon()!;
game.move.select(Moves.DIVE); game.move.select(MoveId.DIVE);
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined(); expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined();
@ -198,7 +198,7 @@ describe("Abilities - Gulp Missile", () => {
}); });
it("prevents effect damage but inflicts secondary effect on attacker with Magic Guard", async () => { it("prevents effect damage but inflicts secondary effect on attacker with Magic Guard", async () => {
game.override.enemyMoveset(Moves.TACKLE).enemyAbility(AbilityId.MAGIC_GUARD); game.override.enemyMoveset(MoveId.TACKLE).enemyAbility(AbilityId.MAGIC_GUARD);
await game.classicMode.startBattle([Species.CRAMORANT]); await game.classicMode.startBattle([Species.CRAMORANT]);
const cramorant = game.scene.getPlayerPokemon()!; const cramorant = game.scene.getPlayerPokemon()!;
@ -206,7 +206,7 @@ describe("Abilities - Gulp Missile", () => {
vi.spyOn(cramorant, "getHpRatio").mockReturnValue(0.55); vi.spyOn(cramorant, "getHpRatio").mockReturnValue(0.55);
game.move.select(Moves.SURF); game.move.select(MoveId.SURF);
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
const enemyHpPreEffect = enemy.hp; const enemyHpPreEffect = enemy.hp;
@ -222,12 +222,12 @@ describe("Abilities - Gulp Missile", () => {
}); });
it("activates on faint", async () => { it("activates on faint", async () => {
game.override.enemyMoveset(Moves.THUNDERBOLT); game.override.enemyMoveset(MoveId.THUNDERBOLT);
await game.classicMode.startBattle([Species.CRAMORANT]); await game.classicMode.startBattle([Species.CRAMORANT]);
const cramorant = game.scene.getPlayerPokemon()!; const cramorant = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SURF); game.move.select(MoveId.SURF);
await game.phaseInterceptor.to("FaintPhase"); await game.phaseInterceptor.to("FaintPhase");
expect(cramorant.hp).toBe(0); expect(cramorant.hp).toBe(0);
@ -237,17 +237,17 @@ describe("Abilities - Gulp Missile", () => {
}); });
it("doesn't trigger if user is behind a substitute", async () => { it("doesn't trigger if user is behind a substitute", async () => {
game.override.enemyAbility(AbilityId.STURDY).enemyMoveset([Moves.SPLASH, Moves.POWER_TRIP]); game.override.enemyAbility(AbilityId.STURDY).enemyMoveset([MoveId.SPLASH, MoveId.POWER_TRIP]);
await game.classicMode.startBattle([Species.CRAMORANT]); await game.classicMode.startBattle([Species.CRAMORANT]);
game.move.select(Moves.SURF); game.move.select(MoveId.SURF);
await game.move.selectEnemyMove(Moves.SPLASH); await game.move.selectEnemyMove(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
expect(game.scene.getPlayerPokemon()!.formIndex).toBe(GULPING_FORM); expect(game.scene.getPlayerPokemon()!.formIndex).toBe(GULPING_FORM);
game.move.select(Moves.SUBSTITUTE); game.move.select(MoveId.SUBSTITUTE);
await game.move.selectEnemyMove(Moves.POWER_TRIP); await game.move.selectEnemyMove(MoveId.POWER_TRIP);
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
await game.toNextTurn(); await game.toNextTurn();
@ -255,13 +255,13 @@ describe("Abilities - Gulp Missile", () => {
}); });
it("cannot be suppressed", async () => { it("cannot be suppressed", async () => {
game.override.enemyMoveset(Moves.GASTRO_ACID); game.override.enemyMoveset(MoveId.GASTRO_ACID);
await game.classicMode.startBattle([Species.CRAMORANT]); await game.classicMode.startBattle([Species.CRAMORANT]);
const cramorant = game.scene.getPlayerPokemon()!; const cramorant = game.scene.getPlayerPokemon()!;
vi.spyOn(cramorant, "getHpRatio").mockReturnValue(0.55); vi.spyOn(cramorant, "getHpRatio").mockReturnValue(0.55);
game.move.select(Moves.SURF); game.move.select(MoveId.SURF);
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined(); expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined();
@ -275,13 +275,13 @@ describe("Abilities - Gulp Missile", () => {
}); });
it("cannot be swapped with another ability", async () => { it("cannot be swapped with another ability", async () => {
game.override.enemyMoveset(Moves.SKILL_SWAP); game.override.enemyMoveset(MoveId.SKILL_SWAP);
await game.classicMode.startBattle([Species.CRAMORANT]); await game.classicMode.startBattle([Species.CRAMORANT]);
const cramorant = game.scene.getPlayerPokemon()!; const cramorant = game.scene.getPlayerPokemon()!;
vi.spyOn(cramorant, "getHpRatio").mockReturnValue(0.55); vi.spyOn(cramorant, "getHpRatio").mockReturnValue(0.55);
game.move.select(Moves.SURF); game.move.select(MoveId.SURF);
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined(); expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined();
@ -298,7 +298,7 @@ describe("Abilities - Gulp Missile", () => {
game.override.enemyAbility(AbilityId.TRACE); game.override.enemyAbility(AbilityId.TRACE);
await game.classicMode.startBattle([Species.CRAMORANT]); await game.classicMode.startBattle([Species.CRAMORANT]);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnStartPhase"); await game.phaseInterceptor.to("TurnStartPhase");
expect(game.scene.getEnemyPokemon()?.hasAbility(AbilityId.GULP_MISSILE)).toBe(false); expect(game.scene.getEnemyPokemon()?.hasAbility(AbilityId.GULP_MISSILE)).toBe(false);

View File

@ -6,7 +6,7 @@ import type { ModifierOverride } from "#app/modifier/modifier-type";
import type { BooleanHolder } from "#app/utils/common"; import type { BooleanHolder } from "#app/utils/common";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { BerryType } from "#enums/berry-type"; import { BerryType } from "#enums/berry-type";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import { WeatherType } from "#enums/weather-type"; import { WeatherType } from "#enums/weather-type";
@ -43,7 +43,7 @@ describe("Abilities - Harvest", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.moveset([Moves.SPLASH, Moves.NATURAL_GIFT, Moves.FALSE_SWIPE, Moves.GASTRO_ACID]) .moveset([MoveId.SPLASH, MoveId.NATURAL_GIFT, MoveId.FALSE_SWIPE, MoveId.GASTRO_ACID])
.ability(AbilityId.HARVEST) .ability(AbilityId.HARVEST)
.startingLevel(100) .startingLevel(100)
.battleStyle("single") .battleStyle("single")
@ -53,15 +53,15 @@ describe("Abilities - Harvest", () => {
.enemyLevel(1) .enemyLevel(1)
.enemySpecies(Species.MAGIKARP) .enemySpecies(Species.MAGIKARP)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset([Moves.SPLASH, Moves.NUZZLE, Moves.KNOCK_OFF, Moves.INCINERATE]); .enemyMoveset([MoveId.SPLASH, MoveId.NUZZLE, MoveId.KNOCK_OFF, MoveId.INCINERATE]);
}); });
it("replenishes eaten berries", async () => { it("replenishes eaten berries", async () => {
game.override.startingHeldItems([{ name: "BERRY", type: BerryType.LUM, count: 1 }]); game.override.startingHeldItems([{ name: "BERRY", type: BerryType.LUM, count: 1 }]);
await game.classicMode.startBattle([Species.FEEBAS]); await game.classicMode.startBattle([Species.FEEBAS]);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(Moves.NUZZLE); await game.move.selectEnemyMove(MoveId.NUZZLE);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(getPlayerBerries()).toHaveLength(0); expect(getPlayerBerries()).toHaveLength(0);
expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toHaveLength(1); expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toHaveLength(1);
@ -86,8 +86,8 @@ describe("Abilities - Harvest", () => {
expect(milotic).toBeDefined(); expect(milotic).toBeDefined();
// Chug a few berries without harvest (should get tracked) // Chug a few berries without harvest (should get tracked)
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(Moves.NUZZLE); await game.move.selectEnemyMove(MoveId.NUZZLE);
await game.toNextTurn(); await game.toNextTurn();
expect(milotic.battleData.berriesEaten).toEqual(expect.arrayContaining([BerryType.ENIGMA, BerryType.LUM])); expect(milotic.battleData.berriesEaten).toEqual(expect.arrayContaining([BerryType.ENIGMA, BerryType.LUM]));
@ -97,8 +97,8 @@ describe("Abilities - Harvest", () => {
// but force our roll to fail so we don't accidentally recover anything // but force our roll to fail so we don't accidentally recover anything
vi.spyOn(PostTurnRestoreBerryAbAttr.prototype, "canApplyPostTurn").mockReturnValueOnce(false); vi.spyOn(PostTurnRestoreBerryAbAttr.prototype, "canApplyPostTurn").mockReturnValueOnce(false);
game.override.ability(AbilityId.HARVEST); game.override.ability(AbilityId.HARVEST);
game.move.select(Moves.GASTRO_ACID); game.move.select(MoveId.GASTRO_ACID);
await game.move.selectEnemyMove(Moves.NUZZLE); await game.move.selectEnemyMove(MoveId.NUZZLE);
await game.toNextTurn(); await game.toNextTurn();
@ -108,8 +108,8 @@ describe("Abilities - Harvest", () => {
expect(getPlayerBerries()).toHaveLength(0); expect(getPlayerBerries()).toHaveLength(0);
// proc a high roll and we _should_ get a berry back! // proc a high roll and we _should_ get a berry back!
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(Moves.SPLASH); await game.move.selectEnemyMove(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
expect(milotic.battleData.berriesEaten).toHaveLength(3); expect(milotic.battleData.berriesEaten).toHaveLength(3);
@ -125,8 +125,8 @@ describe("Abilities - Harvest", () => {
const regieleki = game.scene.getPlayerPokemon()!; const regieleki = game.scene.getPlayerPokemon()!;
regieleki.hp = 1; regieleki.hp = 1;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(Moves.SPLASH); await game.move.selectEnemyMove(MoveId.SPLASH);
await game.doKillOpponents(); await game.doKillOpponents();
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
@ -145,16 +145,16 @@ describe("Abilities - Harvest", () => {
it("keeps harvested berries across reloads", async () => { it("keeps harvested berries across reloads", async () => {
game.override game.override
.startingHeldItems([{ name: "BERRY", type: BerryType.PETAYA, count: 1 }]) .startingHeldItems([{ name: "BERRY", type: BerryType.PETAYA, count: 1 }])
.moveset([Moves.SPLASH, Moves.EARTHQUAKE]) .moveset([MoveId.SPLASH, MoveId.EARTHQUAKE])
.enemyMoveset([Moves.SUPER_FANG, Moves.HEAL_PULSE]) .enemyMoveset([MoveId.SUPER_FANG, MoveId.HEAL_PULSE])
.enemyAbility(AbilityId.COMPOUND_EYES); .enemyAbility(AbilityId.COMPOUND_EYES);
await game.classicMode.startBattle([Species.REGIELEKI]); await game.classicMode.startBattle([Species.REGIELEKI]);
const regieleki = game.scene.getPlayerPokemon()!; const regieleki = game.scene.getPlayerPokemon()!;
regieleki.hp = regieleki.getMaxHp() / 4 + 1; regieleki.hp = regieleki.getMaxHp() / 4 + 1;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(Moves.SUPER_FANG); await game.move.selectEnemyMove(MoveId.SUPER_FANG);
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
await game.toNextTurn(); await game.toNextTurn();
@ -164,8 +164,8 @@ describe("Abilities - Harvest", () => {
expect(game.scene.getPlayerPokemon()?.getStatStage(Stat.SPATK)).toBe(1); expect(game.scene.getPlayerPokemon()?.getStatStage(Stat.SPATK)).toBe(1);
// heal up so harvest doesn't proc and kill enemy // heal up so harvest doesn't proc and kill enemy
game.move.select(Moves.EARTHQUAKE); game.move.select(MoveId.EARTHQUAKE);
await game.move.selectEnemyMove(Moves.HEAL_PULSE); await game.move.selectEnemyMove(MoveId.HEAL_PULSE);
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
await game.toNextWave(); await game.toNextWave();
@ -190,8 +190,8 @@ describe("Abilities - Harvest", () => {
const feebas = game.scene.getPlayerPokemon()!; const feebas = game.scene.getPlayerPokemon()!;
feebas.battleData.berriesEaten = [BerryType.LUM, BerryType.STARF]; feebas.battleData.berriesEaten = [BerryType.LUM, BerryType.STARF];
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(Moves.SPLASH); await game.move.selectEnemyMove(MoveId.SPLASH);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
// Force RNG roll to hit the first berry we find that matches. // Force RNG roll to hit the first berry we find that matches.
@ -218,8 +218,8 @@ describe("Abilities - Harvest", () => {
const player = game.scene.getPlayerPokemon()!; const player = game.scene.getPlayerPokemon()!;
player.battleData.berriesEaten = [BerryType.LUM, BerryType.STARF]; player.battleData.berriesEaten = [BerryType.LUM, BerryType.STARF];
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(Moves.SPLASH); await game.move.selectEnemyMove(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expectBerriesContaining(...initBerries); expectBerriesContaining(...initBerries);
@ -230,8 +230,8 @@ describe("Abilities - Harvest", () => {
game.override.startingHeldItems([{ name: "BERRY", type: BerryType.STARF, count: 3 }]); game.override.startingHeldItems([{ name: "BERRY", type: BerryType.STARF, count: 3 }]);
await game.classicMode.startBattle([Species.FEEBAS]); await game.classicMode.startBattle([Species.FEEBAS]);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(Moves.INCINERATE); await game.move.selectEnemyMove(MoveId.INCINERATE);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toEqual([]); expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toEqual([]);
@ -241,8 +241,8 @@ describe("Abilities - Harvest", () => {
game.override.startingHeldItems([{ name: "BERRY", type: BerryType.STARF, count: 3 }]); game.override.startingHeldItems([{ name: "BERRY", type: BerryType.STARF, count: 3 }]);
await game.classicMode.startBattle([Species.FEEBAS]); await game.classicMode.startBattle([Species.FEEBAS]);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(Moves.KNOCK_OFF); await game.move.selectEnemyMove(MoveId.KNOCK_OFF);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toEqual([]); expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toEqual([]);
@ -250,11 +250,11 @@ describe("Abilities - Harvest", () => {
it("can restore berries eaten by Teatime", async () => { it("can restore berries eaten by Teatime", async () => {
const initBerries: ModifierOverride[] = [{ name: "BERRY", type: BerryType.STARF, count: 1 }]; const initBerries: ModifierOverride[] = [{ name: "BERRY", type: BerryType.STARF, count: 1 }];
game.override.startingHeldItems(initBerries).enemyMoveset(Moves.TEATIME); game.override.startingHeldItems(initBerries).enemyMoveset(MoveId.TEATIME);
await game.classicMode.startBattle([Species.FEEBAS]); await game.classicMode.startBattle([Species.FEEBAS]);
// nom nom the berr berr yay yay // nom nom the berr berr yay yay
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toEqual([]); expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toEqual([]);
@ -263,11 +263,11 @@ describe("Abilities - Harvest", () => {
it("cannot restore Plucked berries for either side", async () => { it("cannot restore Plucked berries for either side", async () => {
const initBerries: ModifierOverride[] = [{ name: "BERRY", type: BerryType.PETAYA, count: 1 }]; const initBerries: ModifierOverride[] = [{ name: "BERRY", type: BerryType.PETAYA, count: 1 }];
game.override.startingHeldItems(initBerries).enemyAbility(AbilityId.HARVEST).enemyMoveset(Moves.PLUCK); game.override.startingHeldItems(initBerries).enemyAbility(AbilityId.HARVEST).enemyMoveset(MoveId.PLUCK);
await game.classicMode.startBattle([Species.FEEBAS]); await game.classicMode.startBattle([Species.FEEBAS]);
// gobble gobble gobble // gobble gobble gobble
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
// pluck triggers harvest for neither side // pluck triggers harvest for neither side
@ -289,7 +289,7 @@ describe("Abilities - Harvest", () => {
game.override.startingHeldItems(initBerries).startingModifier([{ name: "BERRY_POUCH", count: 1 }]); game.override.startingHeldItems(initBerries).startingModifier([{ name: "BERRY_POUCH", count: 1 }]);
await game.classicMode.startBattle([Species.FEEBAS]); await game.classicMode.startBattle([Species.FEEBAS]);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnEndPhase", false); await game.phaseInterceptor.to("TurnEndPhase", false);
// won't trigger harvest since we didn't lose the berry (it just doesn't ever add it to the array) // won't trigger harvest since we didn't lose the berry (it just doesn't ever add it to the array)
@ -307,8 +307,8 @@ describe("Abilities - Harvest", () => {
player.hp = 1; player.hp = 1;
// steal a sitrus and immediately consume it // steal a sitrus and immediately consume it
game.move.select(Moves.FALSE_SWIPE); game.move.select(MoveId.FALSE_SWIPE);
await game.move.selectEnemyMove(Moves.SPLASH); await game.move.selectEnemyMove(MoveId.SPLASH);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(player.battleData.berriesEaten).toEqual([BerryType.SITRUS]); expect(player.battleData.berriesEaten).toEqual([BerryType.SITRUS]);
@ -320,10 +320,10 @@ describe("Abilities - Harvest", () => {
// TODO: Enable once fling actually works...??? // TODO: Enable once fling actually works...???
it.todo("can restore berries flung at user", async () => { it.todo("can restore berries flung at user", async () => {
game.override.enemyHeldItems([{ name: "BERRY", type: BerryType.STARF, count: 1 }]).enemyMoveset(Moves.FLING); game.override.enemyHeldItems([{ name: "BERRY", type: BerryType.STARF, count: 1 }]).enemyMoveset(MoveId.FLING);
await game.classicMode.startBattle([Species.FEEBAS]); await game.classicMode.startBattle([Species.FEEBAS]);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toBe([]); expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toBe([]);
@ -336,7 +336,7 @@ describe("Abilities - Harvest", () => {
game.override.startingHeldItems(initBerries); game.override.startingHeldItems(initBerries);
await game.classicMode.startBattle([Species.FEEBAS]); await game.classicMode.startBattle([Species.FEEBAS]);
game.move.select(Moves.NATURAL_GIFT); game.move.select(MoveId.NATURAL_GIFT);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toHaveLength(0); expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toHaveLength(0);

View File

@ -1,5 +1,5 @@
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { StatusEffect } from "#enums/status-effect"; import { StatusEffect } from "#enums/status-effect";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
@ -30,13 +30,13 @@ describe("Abilities - Healer", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.moveset([Moves.SPLASH]) .moveset([MoveId.SPLASH])
.ability(AbilityId.BALL_FETCH) .ability(AbilityId.BALL_FETCH)
.battleStyle("double") .battleStyle("double")
.disableCrits() .disableCrits()
.enemySpecies(Species.MAGIKARP) .enemySpecies(Species.MAGIKARP)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(MoveId.SPLASH);
healerAttr = allAbilities[AbilityId.HEALER].getAttrs(PostTurnResetStatusAbAttr)[0]; healerAttr = allAbilities[AbilityId.HEALER].getAttrs(PostTurnResetStatusAbAttr)[0];
healerAttrSpy = vi healerAttrSpy = vi
@ -45,14 +45,14 @@ describe("Abilities - Healer", () => {
}); });
it("should not queue a message phase for healing if the ally has fainted", async () => { it("should not queue a message phase for healing if the ally has fainted", async () => {
game.override.moveset([Moves.SPLASH, Moves.LUNAR_DANCE]); game.override.moveset([MoveId.SPLASH, MoveId.LUNAR_DANCE]);
await game.classicMode.startBattle([Species.MAGIKARP, Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP, Species.MAGIKARP]);
const user = game.scene.getPlayerPokemon()!; const user = game.scene.getPlayerPokemon()!;
// Only want one magikarp to have the ability. // Only want one magikarp to have the ability.
vi.spyOn(user, "getAbility").mockReturnValue(allAbilities[AbilityId.HEALER]); vi.spyOn(user, "getAbility").mockReturnValue(allAbilities[AbilityId.HEALER]);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
// faint the ally // faint the ally
game.move.select(Moves.LUNAR_DANCE, 1); game.move.select(MoveId.LUNAR_DANCE, 1);
const abSpy = vi.spyOn(healerAttr, "canApplyPostTurn"); const abSpy = vi.spyOn(healerAttr, "canApplyPostTurn");
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
@ -70,8 +70,8 @@ describe("Abilities - Healer", () => {
// Only want one magikarp to have the ability. // Only want one magikarp to have the ability.
vi.spyOn(user, "getAbility").mockReturnValue(allAbilities[AbilityId.HEALER]); vi.spyOn(user, "getAbility").mockReturnValue(allAbilities[AbilityId.HEALER]);
expect(ally.trySetStatus(StatusEffect.BURN)).toBe(true); expect(ally.trySetStatus(StatusEffect.BURN)).toBe(true);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
await game.toNextTurn(); await game.toNextTurn();
@ -86,8 +86,8 @@ describe("Abilities - Healer", () => {
// Only want one magikarp to have the ability. // Only want one magikarp to have the ability.
vi.spyOn(user, "getAbility").mockReturnValue(allAbilities[AbilityId.HEALER]); vi.spyOn(user, "getAbility").mockReturnValue(allAbilities[AbilityId.HEALER]);
expect(ally.trySetStatus(StatusEffect.BURN)).toBe(true); expect(ally.trySetStatus(StatusEffect.BURN)).toBe(true);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
game.move.select(Moves.SPLASH, 1); game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
await game.toNextTurn(); await game.toNextTurn();

View File

@ -3,7 +3,7 @@ import { StatusEffect } from "#app/enums/status-effect";
import { TurnEndPhase } from "#app/phases/turn-end-phase"; import { TurnEndPhase } from "#app/phases/turn-end-phase";
import { toDmgValue } from "#app/utils/common"; import { toDmgValue } from "#app/utils/common";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
@ -29,11 +29,11 @@ describe("Abilities - Heatproof", () => {
.disableCrits() .disableCrits()
.enemySpecies(Species.CHARMANDER) .enemySpecies(Species.CHARMANDER)
.enemyAbility(AbilityId.HEATPROOF) .enemyAbility(AbilityId.HEATPROOF)
.enemyMoveset(Moves.SPLASH) .enemyMoveset(MoveId.SPLASH)
.enemyLevel(100) .enemyLevel(100)
.starterSpecies(Species.CHANDELURE) .starterSpecies(Species.CHANDELURE)
.ability(AbilityId.BALL_FETCH) .ability(AbilityId.BALL_FETCH)
.moveset([Moves.FLAMETHROWER, Moves.SPLASH]) .moveset([MoveId.FLAMETHROWER, MoveId.SPLASH])
.startingLevel(100); .startingLevel(100);
}); });
@ -44,14 +44,14 @@ describe("Abilities - Heatproof", () => {
const initialHP = 1000; const initialHP = 1000;
enemy.hp = initialHP; enemy.hp = initialHP;
game.move.select(Moves.FLAMETHROWER); game.move.select(MoveId.FLAMETHROWER);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
const heatproofDamage = initialHP - enemy.hp; const heatproofDamage = initialHP - enemy.hp;
enemy.hp = initialHP; enemy.hp = initialHP;
game.override.enemyAbility(AbilityId.BALL_FETCH); game.override.enemyAbility(AbilityId.BALL_FETCH);
game.move.select(Moves.FLAMETHROWER); game.move.select(MoveId.FLAMETHROWER);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
const regularDamage = initialHP - enemy.hp; const regularDamage = initialHP - enemy.hp;
@ -65,7 +65,7 @@ describe("Abilities - Heatproof", () => {
const enemy = game.scene.getEnemyPokemon()!; const enemy = game.scene.getEnemyPokemon()!;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
// Normal burn damage is /16 // Normal burn damage is /16

View File

@ -1,7 +1,7 @@
import type { CommandPhase } from "#app/phases/command-phase"; import type { CommandPhase } from "#app/phases/command-phase";
import { Command } from "#app/ui/command-ui-handler"; import { Command } from "#app/ui/command-ui-handler";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
@ -24,7 +24,7 @@ describe("Abilities - Honey Gather", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.moveset([Moves.SPLASH, Moves.ROAR, Moves.THUNDERBOLT]) .moveset([MoveId.SPLASH, MoveId.ROAR, MoveId.THUNDERBOLT])
.startingLevel(100) .startingLevel(100)
.ability(AbilityId.HONEY_GATHER) .ability(AbilityId.HONEY_GATHER)
.passiveAbility(AbilityId.RUN_AWAY) .passiveAbility(AbilityId.RUN_AWAY)
@ -32,14 +32,14 @@ describe("Abilities - Honey Gather", () => {
.disableCrits() .disableCrits()
.enemySpecies(Species.MAGIKARP) .enemySpecies(Species.MAGIKARP)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(MoveId.SPLASH);
}); });
it("should give money when winning a battle", async () => { it("should give money when winning a battle", async () => {
await game.classicMode.startBattle([Species.MILOTIC]); await game.classicMode.startBattle([Species.MILOTIC]);
game.scene.money = 1000; game.scene.money = 1000;
game.move.select(Moves.THUNDERBOLT); game.move.select(MoveId.THUNDERBOLT);
await game.toNextWave(); await game.toNextWave();
expect(game.scene.money).toBeGreaterThan(1000); expect(game.scene.money).toBeGreaterThan(1000);
@ -49,7 +49,7 @@ describe("Abilities - Honey Gather", () => {
await game.classicMode.startBattle([Species.MILOTIC]); await game.classicMode.startBattle([Species.MILOTIC]);
game.scene.money = 1000; game.scene.money = 1000;
game.move.select(Moves.ROAR); game.move.select(MoveId.ROAR);
await game.toNextTurn(); await game.toNextTurn();
expect(game.scene.money).toBe(1000); expect(game.scene.money).toBe(1000);

View File

@ -1,7 +1,7 @@
import { allMoves } from "#app/data/data-lists"; import { allMoves } from "#app/data/data-lists";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Stat } from "#app/enums/stat"; import { Stat } from "#app/enums/stat";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
@ -25,10 +25,10 @@ describe("Abilities - Hustle", () => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.ability(AbilityId.HUSTLE) .ability(AbilityId.HUSTLE)
.moveset([Moves.TACKLE, Moves.GIGA_DRAIN, Moves.FISSURE]) .moveset([MoveId.TACKLE, MoveId.GIGA_DRAIN, MoveId.FISSURE])
.disableCrits() .disableCrits()
.battleStyle("single") .battleStyle("single")
.enemyMoveset(Moves.SPLASH) .enemyMoveset(MoveId.SPLASH)
.enemySpecies(Species.SHUCKLE) .enemySpecies(Species.SHUCKLE)
.enemyAbility(AbilityId.BALL_FETCH); .enemyAbility(AbilityId.BALL_FETCH);
}); });
@ -40,7 +40,7 @@ describe("Abilities - Hustle", () => {
vi.spyOn(pikachu, "getEffectiveStat"); vi.spyOn(pikachu, "getEffectiveStat");
game.move.select(Moves.TACKLE); game.move.select(MoveId.TACKLE);
await game.move.forceHit(); await game.move.forceHit();
await game.phaseInterceptor.to("DamageAnimPhase"); await game.phaseInterceptor.to("DamageAnimPhase");
@ -53,7 +53,7 @@ describe("Abilities - Hustle", () => {
vi.spyOn(pikachu, "getAccuracyMultiplier"); vi.spyOn(pikachu, "getAccuracyMultiplier");
game.move.select(Moves.TACKLE); game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");
expect(pikachu.getAccuracyMultiplier).toHaveReturnedWith(0.8); expect(pikachu.getAccuracyMultiplier).toHaveReturnedWith(0.8);
@ -67,7 +67,7 @@ describe("Abilities - Hustle", () => {
vi.spyOn(pikachu, "getEffectiveStat"); vi.spyOn(pikachu, "getEffectiveStat");
vi.spyOn(pikachu, "getAccuracyMultiplier"); vi.spyOn(pikachu, "getAccuracyMultiplier");
game.move.select(Moves.GIGA_DRAIN); game.move.select(MoveId.GIGA_DRAIN);
await game.phaseInterceptor.to("DamageAnimPhase"); await game.phaseInterceptor.to("DamageAnimPhase");
expect(pikachu.getEffectiveStat).toHaveReturnedWith(spatk); expect(pikachu.getEffectiveStat).toHaveReturnedWith(spatk);
@ -83,13 +83,13 @@ describe("Abilities - Hustle", () => {
const enemyPokemon = game.scene.getEnemyPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!;
vi.spyOn(pikachu, "getAccuracyMultiplier"); vi.spyOn(pikachu, "getAccuracyMultiplier");
vi.spyOn(allMoves[Moves.FISSURE], "calculateBattleAccuracy"); vi.spyOn(allMoves[MoveId.FISSURE], "calculateBattleAccuracy");
game.move.select(Moves.FISSURE); game.move.select(MoveId.FISSURE);
await game.phaseInterceptor.to("DamageAnimPhase"); await game.phaseInterceptor.to("DamageAnimPhase");
expect(enemyPokemon.turnData.damageTaken).toBe(enemyPokemon.getMaxHp()); expect(enemyPokemon.turnData.damageTaken).toBe(enemyPokemon.getMaxHp());
expect(pikachu.getAccuracyMultiplier).toHaveReturnedWith(1); expect(pikachu.getAccuracyMultiplier).toHaveReturnedWith(1);
expect(allMoves[Moves.FISSURE].calculateBattleAccuracy).toHaveReturnedWith(100); expect(allMoves[MoveId.FISSURE].calculateBattleAccuracy).toHaveReturnedWith(100);
}); });
}); });

View File

@ -1,6 +1,6 @@
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
@ -24,11 +24,11 @@ describe("Abilities - Hyper Cutter", () => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.battleStyle("single") .battleStyle("single")
.moveset([Moves.SAND_ATTACK, Moves.NOBLE_ROAR, Moves.DEFOG, Moves.OCTOLOCK]) .moveset([MoveId.SAND_ATTACK, MoveId.NOBLE_ROAR, MoveId.DEFOG, MoveId.OCTOLOCK])
.ability(AbilityId.BALL_FETCH) .ability(AbilityId.BALL_FETCH)
.enemySpecies(Species.SHUCKLE) .enemySpecies(Species.SHUCKLE)
.enemyAbility(AbilityId.HYPER_CUTTER) .enemyAbility(AbilityId.HYPER_CUTTER)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(MoveId.SPLASH);
}); });
// Reference Link: https://bulbapedia.bulbagarden.net/wiki/Hyper_Cutter_(Ability) // Reference Link: https://bulbapedia.bulbagarden.net/wiki/Hyper_Cutter_(Ability)
@ -38,16 +38,16 @@ describe("Abilities - Hyper Cutter", () => {
const enemy = game.scene.getEnemyPokemon()!; const enemy = game.scene.getEnemyPokemon()!;
game.move.select(Moves.OCTOLOCK); game.move.select(MoveId.OCTOLOCK);
await game.toNextTurn(); await game.toNextTurn();
game.move.select(Moves.DEFOG); game.move.select(MoveId.DEFOG);
await game.toNextTurn(); await game.toNextTurn();
game.move.select(Moves.NOBLE_ROAR); game.move.select(MoveId.NOBLE_ROAR);
await game.toNextTurn(); await game.toNextTurn();
game.move.select(Moves.SAND_ATTACK); game.move.select(MoveId.SAND_ATTACK);
await game.toNextTurn(); await game.toNextTurn();
game.override.moveset([Moves.STRING_SHOT]); game.override.moveset([MoveId.STRING_SHOT]);
game.move.select(Moves.STRING_SHOT); game.move.select(MoveId.STRING_SHOT);
await game.toNextTurn(); await game.toNextTurn();
expect(enemy.getStatStage(Stat.ATK)).toEqual(0); expect(enemy.getStatStage(Stat.ATK)).toEqual(0);

View File

@ -6,7 +6,7 @@ import { TurnEndPhase } from "#app/phases/turn-end-phase";
import { TurnInitPhase } from "#app/phases/turn-init-phase"; import { TurnInitPhase } from "#app/phases/turn-init-phase";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
@ -33,13 +33,13 @@ describe("Abilities - Ice Face", () => {
game.override.battleStyle("single"); game.override.battleStyle("single");
game.override.enemySpecies(Species.EISCUE); game.override.enemySpecies(Species.EISCUE);
game.override.enemyAbility(AbilityId.ICE_FACE); game.override.enemyAbility(AbilityId.ICE_FACE);
game.override.moveset([Moves.TACKLE, Moves.ICE_BEAM, Moves.TOXIC_THREAD, Moves.HAIL]); game.override.moveset([MoveId.TACKLE, MoveId.ICE_BEAM, MoveId.TOXIC_THREAD, MoveId.HAIL]);
}); });
it("takes no damage from physical move and transforms to Noice", async () => { it("takes no damage from physical move and transforms to Noice", async () => {
await game.classicMode.startBattle([Species.HITMONLEE]); await game.classicMode.startBattle([Species.HITMONLEE]);
game.move.select(Moves.TACKLE); game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.to(MoveEndPhase); await game.phaseInterceptor.to(MoveEndPhase);
@ -51,11 +51,11 @@ describe("Abilities - Ice Face", () => {
}); });
it("takes no damage from the first hit of multihit physical move and transforms to Noice", async () => { it("takes no damage from the first hit of multihit physical move and transforms to Noice", async () => {
game.override.moveset([Moves.SURGING_STRIKES]); game.override.moveset([MoveId.SURGING_STRIKES]);
game.override.enemyLevel(1); game.override.enemyLevel(1);
await game.classicMode.startBattle([Species.HITMONLEE]); await game.classicMode.startBattle([Species.HITMONLEE]);
game.move.select(Moves.SURGING_STRIKES); game.move.select(MoveId.SURGING_STRIKES);
const eiscue = game.scene.getEnemyPokemon()!; const eiscue = game.scene.getEnemyPokemon()!;
expect(eiscue.getTag(BattlerTagType.ICE_FACE)).toBeDefined(); expect(eiscue.getTag(BattlerTagType.ICE_FACE)).toBeDefined();
@ -81,7 +81,7 @@ describe("Abilities - Ice Face", () => {
it("takes damage from special moves", async () => { it("takes damage from special moves", async () => {
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
game.move.select(Moves.ICE_BEAM); game.move.select(MoveId.ICE_BEAM);
await game.phaseInterceptor.to(MoveEndPhase); await game.phaseInterceptor.to(MoveEndPhase);
@ -95,7 +95,7 @@ describe("Abilities - Ice Face", () => {
it("takes effects from status moves", async () => { it("takes effects from status moves", async () => {
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
game.move.select(Moves.TOXIC_THREAD); game.move.select(MoveId.TOXIC_THREAD);
await game.phaseInterceptor.to(MoveEndPhase); await game.phaseInterceptor.to(MoveEndPhase);
@ -106,11 +106,11 @@ describe("Abilities - Ice Face", () => {
}); });
it("transforms to Ice Face when Hail or Snow starts", async () => { it("transforms to Ice Face when Hail or Snow starts", async () => {
game.override.moveset([Moves.QUICK_ATTACK]).enemyMoveset(Moves.HAIL); game.override.moveset([MoveId.QUICK_ATTACK]).enemyMoveset(MoveId.HAIL);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
game.move.select(Moves.QUICK_ATTACK); game.move.select(MoveId.QUICK_ATTACK);
await game.phaseInterceptor.to(MoveEndPhase); await game.phaseInterceptor.to(MoveEndPhase);
@ -127,11 +127,11 @@ describe("Abilities - Ice Face", () => {
}); });
it("transforms to Ice Face when summoned on arena with active Snow or Hail", async () => { it("transforms to Ice Face when summoned on arena with active Snow or Hail", async () => {
game.override.enemyMoveset(Moves.TACKLE).moveset([Moves.SNOWSCAPE]); game.override.enemyMoveset(MoveId.TACKLE).moveset([MoveId.SNOWSCAPE]);
await game.classicMode.startBattle([Species.EISCUE, Species.NINJASK]); await game.classicMode.startBattle([Species.EISCUE, Species.NINJASK]);
game.move.select(Moves.SNOWSCAPE); game.move.select(MoveId.SNOWSCAPE);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
let eiscue = game.scene.getPlayerPokemon()!; let eiscue = game.scene.getPlayerPokemon()!;
@ -153,11 +153,11 @@ describe("Abilities - Ice Face", () => {
}); });
it("will not revert to its Ice Face if there is already Hail when it changes into Noice", async () => { it("will not revert to its Ice Face if there is already Hail when it changes into Noice", async () => {
game.override.enemySpecies(Species.SHUCKLE).enemyMoveset(Moves.TACKLE); game.override.enemySpecies(Species.SHUCKLE).enemyMoveset(MoveId.TACKLE);
await game.classicMode.startBattle([Species.EISCUE]); await game.classicMode.startBattle([Species.EISCUE]);
game.move.select(Moves.HAIL); game.move.select(MoveId.HAIL);
const eiscue = game.scene.getPlayerPokemon()!; const eiscue = game.scene.getPlayerPokemon()!;
await game.phaseInterceptor.to(QuietFormChangePhase); await game.phaseInterceptor.to(QuietFormChangePhase);
@ -172,11 +172,11 @@ describe("Abilities - Ice Face", () => {
}); });
it("persists form change when switched out", async () => { it("persists form change when switched out", async () => {
game.override.enemyMoveset(Moves.QUICK_ATTACK); game.override.enemyMoveset(MoveId.QUICK_ATTACK);
await game.classicMode.startBattle([Species.EISCUE, Species.MAGIKARP]); await game.classicMode.startBattle([Species.EISCUE, Species.MAGIKARP]);
game.move.select(Moves.ICE_BEAM); game.move.select(MoveId.ICE_BEAM);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
let eiscue = game.scene.getPlayerPokemon()!; let eiscue = game.scene.getPlayerPokemon()!;
@ -210,7 +210,7 @@ describe("Abilities - Ice Face", () => {
expect(eiscue.formIndex).toBe(noiceForm); expect(eiscue.formIndex).toBe(noiceForm);
expect(eiscue.getTag(BattlerTagType.ICE_FACE)).toBeUndefined(); expect(eiscue.getTag(BattlerTagType.ICE_FACE)).toBeUndefined();
game.move.select(Moves.ICE_BEAM); game.move.select(MoveId.ICE_BEAM);
await game.doKillOpponents(); await game.doKillOpponents();
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
game.doSelectModifier(); game.doSelectModifier();
@ -221,10 +221,10 @@ describe("Abilities - Ice Face", () => {
}); });
it("doesn't trigger if user is behind a substitute", async () => { it("doesn't trigger if user is behind a substitute", async () => {
game.override.enemyMoveset(Moves.SUBSTITUTE).moveset(Moves.POWER_TRIP); game.override.enemyMoveset(MoveId.SUBSTITUTE).moveset(MoveId.POWER_TRIP);
await game.classicMode.startBattle(); await game.classicMode.startBattle();
game.move.select(Moves.POWER_TRIP); game.move.select(MoveId.POWER_TRIP);
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
await game.toNextTurn(); await game.toNextTurn();
@ -232,11 +232,11 @@ describe("Abilities - Ice Face", () => {
}); });
it("cannot be suppressed", async () => { it("cannot be suppressed", async () => {
game.override.moveset([Moves.GASTRO_ACID]); game.override.moveset([MoveId.GASTRO_ACID]);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
game.move.select(Moves.GASTRO_ACID); game.move.select(MoveId.GASTRO_ACID);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
@ -248,11 +248,11 @@ describe("Abilities - Ice Face", () => {
}); });
it("cannot be swapped with another ability", async () => { it("cannot be swapped with another ability", async () => {
game.override.moveset([Moves.SKILL_SWAP]); game.override.moveset([MoveId.SKILL_SWAP]);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
game.move.select(Moves.SKILL_SWAP); game.move.select(MoveId.SKILL_SWAP);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
@ -268,7 +268,7 @@ describe("Abilities - Ice Face", () => {
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
game.move.select(Moves.SIMPLE_BEAM); game.move.select(MoveId.SIMPLE_BEAM);
await game.phaseInterceptor.to(TurnInitPhase); await game.phaseInterceptor.to(TurnInitPhase);

View File

@ -1,6 +1,6 @@
import { Stat } from "#app/enums/stat"; import { Stat } from "#app/enums/stat";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, it, expect } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, it, expect } from "vitest";
@ -22,10 +22,10 @@ describe("Abilities - Illuminate", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.moveset(Moves.SPLASH) .moveset(MoveId.SPLASH)
.ability(AbilityId.ILLUMINATE) .ability(AbilityId.ILLUMINATE)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SAND_ATTACK); .enemyMoveset(MoveId.SAND_ATTACK);
}); });
it("should prevent ACC stat stage from being lowered", async () => { it("should prevent ACC stat stage from being lowered", async () => {
@ -37,7 +37,7 @@ describe("Abilities - Illuminate", () => {
expect(player.getStatStage(Stat.ACC)).toBe(0); expect(player.getStatStage(Stat.ACC)).toBe(0);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();

View File

@ -1,7 +1,7 @@
import { Gender } from "#app/data/gender"; import { Gender } from "#app/data/gender";
import { PokeballType } from "#app/enums/pokeball"; import { PokeballType } from "#app/enums/pokeball";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
@ -27,9 +27,9 @@ describe("Abilities - Illusion", () => {
.battleStyle("single") .battleStyle("single")
.enemySpecies(Species.ZORUA) .enemySpecies(Species.ZORUA)
.enemyAbility(AbilityId.ILLUSION) .enemyAbility(AbilityId.ILLUSION)
.enemyMoveset(Moves.TACKLE) .enemyMoveset(MoveId.TACKLE)
.enemyHeldItems([{ name: "WIDE_LENS", count: 3 }]) .enemyHeldItems([{ name: "WIDE_LENS", count: 3 }])
.moveset([Moves.WORRY_SEED, Moves.SOAK, Moves.TACKLE]) .moveset([MoveId.WORRY_SEED, MoveId.SOAK, MoveId.TACKLE])
.startingHeldItems([{ name: "WIDE_LENS", count: 3 }]); .startingHeldItems([{ name: "WIDE_LENS", count: 3 }]);
}); });
@ -44,7 +44,7 @@ describe("Abilities - Illusion", () => {
it("break after receiving damaging move", async () => { it("break after receiving damaging move", async () => {
await game.classicMode.startBattle([Species.FEEBAS]); await game.classicMode.startBattle([Species.FEEBAS]);
game.move.select(Moves.TACKLE); game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
@ -56,7 +56,7 @@ describe("Abilities - Illusion", () => {
it("break after getting ability changed", async () => { it("break after getting ability changed", async () => {
await game.classicMode.startBattle([Species.FEEBAS]); await game.classicMode.startBattle([Species.FEEBAS]);
game.move.select(Moves.WORRY_SEED); game.move.select(MoveId.WORRY_SEED);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
@ -78,8 +78,8 @@ describe("Abilities - Illusion", () => {
game.override game.override
.enemyAbility(AbilityId.NEUTRALIZING_GAS) .enemyAbility(AbilityId.NEUTRALIZING_GAS)
.ability(AbilityId.ILLUSION) .ability(AbilityId.ILLUSION)
.moveset(Moves.SPLASH) .moveset(MoveId.SPLASH)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(MoveId.SPLASH);
await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS, Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS, Species.MAGIKARP]);
game.doSwitchPokemon(1); game.doSwitchPokemon(1);
@ -89,7 +89,7 @@ describe("Abilities - Illusion", () => {
}); });
it("causes enemy AI to consider the illusion's type instead of the actual type when considering move effectiveness", async () => { it("causes enemy AI to consider the illusion's type instead of the actual type when considering move effectiveness", async () => {
game.override.enemyMoveset([Moves.FLAMETHROWER, Moves.PSYCHIC, Moves.TACKLE]); game.override.enemyMoveset([MoveId.FLAMETHROWER, MoveId.PSYCHIC, MoveId.TACKLE]);
await game.classicMode.startBattle([Species.ZOROARK, Species.FEEBAS]); await game.classicMode.startBattle([Species.ZOROARK, Species.FEEBAS]);
const enemy = game.scene.getEnemyPokemon()!; const enemy = game.scene.getEnemyPokemon()!;
@ -119,12 +119,12 @@ describe("Abilities - Illusion", () => {
it("does not break from indirect damage", async () => { it("does not break from indirect damage", async () => {
game.override.enemySpecies(Species.GIGALITH); game.override.enemySpecies(Species.GIGALITH);
game.override.enemyAbility(AbilityId.SAND_STREAM); game.override.enemyAbility(AbilityId.SAND_STREAM);
game.override.enemyMoveset(Moves.WILL_O_WISP); game.override.enemyMoveset(MoveId.WILL_O_WISP);
game.override.moveset([Moves.FLARE_BLITZ]); game.override.moveset([MoveId.FLARE_BLITZ]);
await game.classicMode.startBattle([Species.ZOROARK, Species.AZUMARILL]); await game.classicMode.startBattle([Species.ZOROARK, Species.AZUMARILL]);
game.move.select(Moves.FLARE_BLITZ); game.move.select(MoveId.FLARE_BLITZ);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
@ -134,7 +134,7 @@ describe("Abilities - Illusion", () => {
}); });
it("copies the the name, nickname, gender, shininess, and pokeball from the illusion source", async () => { it("copies the the name, nickname, gender, shininess, and pokeball from the illusion source", async () => {
game.override.enemyMoveset(Moves.SPLASH); game.override.enemyMoveset(MoveId.SPLASH);
await game.classicMode.startBattle([Species.ABRA, Species.ZOROARK, Species.AXEW]); await game.classicMode.startBattle([Species.ABRA, Species.ZOROARK, Species.AXEW]);
const axew = game.scene.getPlayerParty().at(2)!; const axew = game.scene.getPlayerParty().at(2)!;
axew.shiny = true; axew.shiny = true;
@ -156,13 +156,13 @@ describe("Abilities - Illusion", () => {
}); });
it("breaks when suppressed", async () => { it("breaks when suppressed", async () => {
game.override.moveset(Moves.GASTRO_ACID); game.override.moveset(MoveId.GASTRO_ACID);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
const zorua = game.scene.getEnemyPokemon()!; const zorua = game.scene.getEnemyPokemon()!;
expect(!!zorua.summonData?.illusion).toBe(true); expect(!!zorua.summonData?.illusion).toBe(true);
game.move.select(Moves.GASTRO_ACID); game.move.select(MoveId.GASTRO_ACID);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(zorua.isFullHp()).toBe(true); expect(zorua.isFullHp()).toBe(true);

View File

@ -1,5 +1,5 @@
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { StatusEffect } from "#enums/status-effect"; import { StatusEffect } from "#enums/status-effect";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
@ -23,27 +23,27 @@ describe("Abilities - Immunity", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.moveset([Moves.SPLASH]) .moveset([MoveId.SPLASH])
.ability(AbilityId.BALL_FETCH) .ability(AbilityId.BALL_FETCH)
.battleStyle("single") .battleStyle("single")
.disableCrits() .disableCrits()
.enemySpecies(Species.MAGIKARP) .enemySpecies(Species.MAGIKARP)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(MoveId.SPLASH);
}); });
it("should remove poison when gained", async () => { it("should remove poison when gained", async () => {
game.override game.override
.ability(AbilityId.IMMUNITY) .ability(AbilityId.IMMUNITY)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.moveset(Moves.SKILL_SWAP) .moveset(MoveId.SKILL_SWAP)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(MoveId.SPLASH);
await game.classicMode.startBattle([Species.FEEBAS]); await game.classicMode.startBattle([Species.FEEBAS]);
const enemy = game.scene.getEnemyPokemon(); const enemy = game.scene.getEnemyPokemon();
enemy?.trySetStatus(StatusEffect.POISON); enemy?.trySetStatus(StatusEffect.POISON);
expect(enemy?.status?.effect).toBe(StatusEffect.POISON); expect(enemy?.status?.effect).toBe(StatusEffect.POISON);
game.move.select(Moves.SKILL_SWAP); game.move.select(MoveId.SKILL_SWAP);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(enemy?.status).toBeNull(); expect(enemy?.status).toBeNull();

View File

@ -3,7 +3,7 @@ import Phaser from "phaser";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { TurnEndPhase } from "#app/phases/turn-end-phase"; import { TurnEndPhase } from "#app/phases/turn-end-phase";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Stat, BATTLE_STATS, EFFECTIVE_STATS } from "#enums/stat"; import { Stat, BATTLE_STATS, EFFECTIVE_STATS } from "#enums/stat";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
@ -30,15 +30,15 @@ describe("Abilities - Imposter", () => {
.enemyLevel(200) .enemyLevel(200)
.enemyAbility(AbilityId.BEAST_BOOST) .enemyAbility(AbilityId.BEAST_BOOST)
.enemyPassiveAbility(AbilityId.BALL_FETCH) .enemyPassiveAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH) .enemyMoveset(MoveId.SPLASH)
.ability(AbilityId.IMPOSTER) .ability(AbilityId.IMPOSTER)
.moveset(Moves.SPLASH); .moveset(MoveId.SPLASH);
}); });
it("should copy species, ability, gender, all stats except HP, all stat stages, moveset, and types of target", async () => { it("should copy species, ability, gender, all stats except HP, all stat stages, moveset, and types of target", async () => {
await game.classicMode.startBattle([Species.DITTO]); await game.classicMode.startBattle([Species.DITTO]);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
const player = game.scene.getPlayerPokemon()!; const player = game.scene.getPlayerPokemon()!;
@ -75,7 +75,7 @@ describe("Abilities - Imposter", () => {
}); });
it("should copy in-battle overridden stats", async () => { it("should copy in-battle overridden stats", async () => {
game.override.enemyMoveset([Moves.POWER_SPLIT]); game.override.enemyMoveset([MoveId.POWER_SPLIT]);
await game.classicMode.startBattle([Species.DITTO]); await game.classicMode.startBattle([Species.DITTO]);
@ -85,7 +85,7 @@ describe("Abilities - Imposter", () => {
const avgAtk = Math.floor((player.getStat(Stat.ATK, false) + enemy.getStat(Stat.ATK, false)) / 2); const avgAtk = Math.floor((player.getStat(Stat.ATK, false) + enemy.getStat(Stat.ATK, false)) / 2);
const avgSpAtk = Math.floor((player.getStat(Stat.SPATK, false) + enemy.getStat(Stat.SPATK, false)) / 2); const avgSpAtk = Math.floor((player.getStat(Stat.SPATK, false) + enemy.getStat(Stat.SPATK, false)) / 2);
game.move.select(Moves.TACKLE); game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
expect(player.getStat(Stat.ATK, false)).toBe(avgAtk); expect(player.getStat(Stat.ATK, false)).toBe(avgAtk);
@ -96,18 +96,18 @@ describe("Abilities - Imposter", () => {
}); });
it("should set each move's pp to a maximum of 5", async () => { it("should set each move's pp to a maximum of 5", async () => {
game.override.enemyMoveset([Moves.SWORDS_DANCE, Moves.GROWL, Moves.SKETCH, Moves.RECOVER]); game.override.enemyMoveset([MoveId.SWORDS_DANCE, MoveId.GROWL, MoveId.SKETCH, MoveId.RECOVER]);
await game.classicMode.startBattle([Species.DITTO]); await game.classicMode.startBattle([Species.DITTO]);
const player = game.scene.getPlayerPokemon()!; const player = game.scene.getPlayerPokemon()!;
game.move.select(Moves.TACKLE); game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
player.getMoveset().forEach(move => { player.getMoveset().forEach(move => {
// Should set correct maximum PP without touching `ppUp` // Should set correct maximum PP without touching `ppUp`
if (move) { if (move) {
if (move.moveId === Moves.SKETCH) { if (move.moveId === MoveId.SKETCH) {
expect(move.getMovePp()).toBe(1); expect(move.getMovePp()).toBe(1);
} else { } else {
expect(move.getMovePp()).toBe(5); expect(move.getMovePp()).toBe(5);
@ -122,21 +122,21 @@ describe("Abilities - Imposter", () => {
await game.classicMode.startBattle([Species.DITTO]); await game.classicMode.startBattle([Species.DITTO]);
game.move.select(Moves.TACKLE); game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(game.scene.getEnemyPokemon()?.getStatStage(Stat.ATK)).toBe(-1); expect(game.scene.getEnemyPokemon()?.getStatStage(Stat.ATK)).toBe(-1);
}); });
it("should persist transformed attributes across reloads", async () => { it("should persist transformed attributes across reloads", async () => {
game.override.moveset([Moves.ABSORB]); game.override.moveset([MoveId.ABSORB]);
await game.classicMode.startBattle([Species.DITTO]); await game.classicMode.startBattle([Species.DITTO]);
const player = game.scene.getPlayerPokemon()!; const player = game.scene.getPlayerPokemon()!;
const enemy = game.scene.getEnemyPokemon()!; const enemy = game.scene.getEnemyPokemon()!;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.doKillOpponents(); await game.doKillOpponents();
await game.toNextWave(); await game.toNextWave();
@ -158,11 +158,11 @@ describe("Abilities - Imposter", () => {
} }
expect(playerMoveset.length).toEqual(1); expect(playerMoveset.length).toEqual(1);
expect(playerMoveset[0]?.moveId).toEqual(Moves.SPLASH); expect(playerMoveset[0]?.moveId).toEqual(MoveId.SPLASH);
}); });
it("should stay transformed with the correct form after reload", async () => { it("should stay transformed with the correct form after reload", async () => {
game.override.moveset([Moves.ABSORB]); game.override.moveset([MoveId.ABSORB]);
game.override.enemySpecies(Species.UNOWN); game.override.enemySpecies(Species.UNOWN);
await game.classicMode.startBattle([Species.DITTO]); await game.classicMode.startBattle([Species.DITTO]);
@ -172,7 +172,7 @@ describe("Abilities - Imposter", () => {
enemy.species.forms[5]; enemy.species.forms[5];
enemy.species.formIndex = 5; enemy.species.formIndex = 5;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.doKillOpponents(); await game.doKillOpponents();
await game.toNextWave(); await game.toNextWave();

View File

@ -5,7 +5,7 @@ import { BattlerTagType } from "#enums/battler-tag-type";
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import { StatusEffect } from "#enums/status-effect"; import { StatusEffect } from "#enums/status-effect";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
@ -28,13 +28,13 @@ describe("Abilities - Infiltrator", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.moveset([Moves.TACKLE, Moves.WATER_GUN, Moves.SPORE, Moves.BABY_DOLL_EYES]) .moveset([MoveId.TACKLE, MoveId.WATER_GUN, MoveId.SPORE, MoveId.BABY_DOLL_EYES])
.ability(AbilityId.INFILTRATOR) .ability(AbilityId.INFILTRATOR)
.battleStyle("single") .battleStyle("single")
.disableCrits() .disableCrits()
.enemySpecies(Species.SNORLAX) .enemySpecies(Species.SNORLAX)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH) .enemyMoveset(MoveId.SPLASH)
.startingLevel(100) .startingLevel(100)
.enemyLevel(100); .enemyLevel(100);
}); });
@ -43,17 +43,17 @@ describe("Abilities - Infiltrator", () => {
{ {
effectName: "Light Screen", effectName: "Light Screen",
tagType: ArenaTagType.LIGHT_SCREEN, tagType: ArenaTagType.LIGHT_SCREEN,
move: Moves.WATER_GUN, move: MoveId.WATER_GUN,
}, },
{ {
effectName: "Reflect", effectName: "Reflect",
tagType: ArenaTagType.REFLECT, tagType: ArenaTagType.REFLECT,
move: Moves.TACKLE, move: MoveId.TACKLE,
}, },
{ {
effectName: "Aurora Veil", effectName: "Aurora Veil",
tagType: ArenaTagType.AURORA_VEIL, tagType: ArenaTagType.AURORA_VEIL,
move: Moves.TACKLE, move: MoveId.TACKLE,
}, },
])("should bypass the target's $effectName", async ({ tagType, move }) => { ])("should bypass the target's $effectName", async ({ tagType, move }) => {
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
@ -63,7 +63,7 @@ describe("Abilities - Infiltrator", () => {
const preScreenDmg = enemy.getAttackDamage({ source: player, move: allMoves[move] }).damage; const preScreenDmg = enemy.getAttackDamage({ source: player, move: allMoves[move] }).damage;
game.scene.arena.addTag(tagType, 1, Moves.NONE, enemy.id, ArenaTagSide.ENEMY, true); game.scene.arena.addTag(tagType, 1, MoveId.NONE, enemy.id, ArenaTagSide.ENEMY, true);
const postScreenDmg = enemy.getAttackDamage({ source: player, move: allMoves[move] }).damage; const postScreenDmg = enemy.getAttackDamage({ source: player, move: allMoves[move] }).damage;
@ -77,9 +77,9 @@ describe("Abilities - Infiltrator", () => {
const player = game.scene.getPlayerPokemon()!; const player = game.scene.getPlayerPokemon()!;
const enemy = game.scene.getEnemyPokemon()!; const enemy = game.scene.getEnemyPokemon()!;
game.scene.arena.addTag(ArenaTagType.SAFEGUARD, 1, Moves.NONE, enemy.id, ArenaTagSide.ENEMY, true); game.scene.arena.addTag(ArenaTagType.SAFEGUARD, 1, MoveId.NONE, enemy.id, ArenaTagSide.ENEMY, true);
game.move.select(Moves.SPORE); game.move.select(MoveId.SPORE);
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemy.status?.effect).toBe(StatusEffect.SLEEP); expect(enemy.status?.effect).toBe(StatusEffect.SLEEP);
@ -93,9 +93,9 @@ describe("Abilities - Infiltrator", () => {
const player = game.scene.getPlayerPokemon()!; const player = game.scene.getPlayerPokemon()!;
const enemy = game.scene.getEnemyPokemon()!; const enemy = game.scene.getEnemyPokemon()!;
game.scene.arena.addTag(ArenaTagType.MIST, 1, Moves.NONE, enemy.id, ArenaTagSide.ENEMY, true); game.scene.arena.addTag(ArenaTagType.MIST, 1, MoveId.NONE, enemy.id, ArenaTagSide.ENEMY, true);
game.move.select(Moves.BABY_DOLL_EYES); game.move.select(MoveId.BABY_DOLL_EYES);
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(enemy.getStatStage(Stat.ATK)).toBe(-1); expect(enemy.getStatStage(Stat.ATK)).toBe(-1);
@ -108,9 +108,9 @@ describe("Abilities - Infiltrator", () => {
const player = game.scene.getPlayerPokemon()!; const player = game.scene.getPlayerPokemon()!;
const enemy = game.scene.getEnemyPokemon()!; const enemy = game.scene.getEnemyPokemon()!;
enemy.addTag(BattlerTagType.SUBSTITUTE, 1, Moves.NONE, enemy.id); enemy.addTag(BattlerTagType.SUBSTITUTE, 1, MoveId.NONE, enemy.id);
game.move.select(Moves.BABY_DOLL_EYES); game.move.select(MoveId.BABY_DOLL_EYES);
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(enemy.getStatStage(Stat.ATK)).toBe(-1); expect(enemy.getStatStage(Stat.ATK)).toBe(-1);

View File

@ -1,5 +1,5 @@
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { StatusEffect } from "#enums/status-effect"; import { StatusEffect } from "#enums/status-effect";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
@ -23,27 +23,27 @@ describe("Abilities - Insomnia", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.moveset([Moves.SPLASH]) .moveset([MoveId.SPLASH])
.ability(AbilityId.BALL_FETCH) .ability(AbilityId.BALL_FETCH)
.battleStyle("single") .battleStyle("single")
.disableCrits() .disableCrits()
.enemySpecies(Species.MAGIKARP) .enemySpecies(Species.MAGIKARP)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(MoveId.SPLASH);
}); });
it("should remove sleep when gained", async () => { it("should remove sleep when gained", async () => {
game.override game.override
.ability(AbilityId.INSOMNIA) .ability(AbilityId.INSOMNIA)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.moveset(Moves.SKILL_SWAP) .moveset(MoveId.SKILL_SWAP)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(MoveId.SPLASH);
await game.classicMode.startBattle([Species.FEEBAS]); await game.classicMode.startBattle([Species.FEEBAS]);
const enemy = game.scene.getEnemyPokemon(); const enemy = game.scene.getEnemyPokemon();
enemy?.trySetStatus(StatusEffect.SLEEP); enemy?.trySetStatus(StatusEffect.SLEEP);
expect(enemy?.status?.effect).toBe(StatusEffect.SLEEP); expect(enemy?.status?.effect).toBe(StatusEffect.SLEEP);
game.move.select(Moves.SKILL_SWAP); game.move.select(MoveId.SKILL_SWAP);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(enemy?.status).toBeNull(); expect(enemy?.status).toBeNull();

View File

@ -5,7 +5,7 @@ import { UiMode } from "#enums/ui-mode";
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import { getMovePosition } from "#test/testUtils/gameManagerUtils"; import { getMovePosition } from "#test/testUtils/gameManagerUtils";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
describe("Abilities - Intimidate", () => { describe("Abilities - Intimidate", () => {
@ -31,7 +31,7 @@ describe("Abilities - Intimidate", () => {
.enemyPassiveAbility(AbilityId.HYDRATION) .enemyPassiveAbility(AbilityId.HYDRATION)
.ability(AbilityId.INTIMIDATE) .ability(AbilityId.INTIMIDATE)
.startingWave(3) .startingWave(3)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(MoveId.SPLASH);
}); });
it("should lower ATK stat stage by 1 of enemy Pokemon on entry and player switch", async () => { it("should lower ATK stat stage by 1 of enemy Pokemon on entry and player switch", async () => {
@ -89,7 +89,7 @@ describe("Abilities - Intimidate", () => {
it("should not activate again if there is no switch or new entry", async () => { it("should not activate again if there is no switch or new entry", async () => {
game.override.startingWave(2); game.override.startingWave(2);
game.override.moveset([Moves.SPLASH]); game.override.moveset([MoveId.SPLASH]);
await game.classicMode.startBattle([Species.MIGHTYENA, Species.POOCHYENA]); await game.classicMode.startBattle([Species.MIGHTYENA, Species.POOCHYENA]);
const playerPokemon = game.scene.getPlayerPokemon()!; const playerPokemon = game.scene.getPlayerPokemon()!;
@ -98,7 +98,7 @@ describe("Abilities - Intimidate", () => {
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-1); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-1);
expect(playerPokemon.getStatStage(Stat.ATK)).toBe(-1); expect(playerPokemon.getStatStage(Stat.ATK)).toBe(-1);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-1); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-1);
@ -106,7 +106,7 @@ describe("Abilities - Intimidate", () => {
}, 20000); }, 20000);
it("should lower ATK stat stage by 1 for every switch", async () => { it("should lower ATK stat stage by 1 for every switch", async () => {
game.override.moveset([Moves.SPLASH]).enemyMoveset([Moves.VOLT_SWITCH]).startingWave(5); game.override.moveset([MoveId.SPLASH]).enemyMoveset([MoveId.VOLT_SWITCH]).startingWave(5);
await game.classicMode.startBattle([Species.MIGHTYENA, Species.POOCHYENA]); await game.classicMode.startBattle([Species.MIGHTYENA, Species.POOCHYENA]);
const playerPokemon = game.scene.getPlayerPokemon()!; const playerPokemon = game.scene.getPlayerPokemon()!;
@ -115,7 +115,7 @@ describe("Abilities - Intimidate", () => {
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-1); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-1);
expect(playerPokemon.getStatStage(Stat.ATK)).toBe(-1); expect(playerPokemon.getStatStage(Stat.ATK)).toBe(-1);
game.move.select(getMovePosition(game.scene, 0, Moves.SPLASH)); game.move.select(getMovePosition(game.scene, 0, MoveId.SPLASH));
await game.toNextTurn(); await game.toNextTurn();
enemyPokemon = game.scene.getEnemyPokemon()!; enemyPokemon = game.scene.getEnemyPokemon()!;
@ -123,7 +123,7 @@ describe("Abilities - Intimidate", () => {
expect(playerPokemon.getStatStage(Stat.ATK)).toBe(-2); expect(playerPokemon.getStatStage(Stat.ATK)).toBe(-2);
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
enemyPokemon = game.scene.getEnemyPokemon()!; enemyPokemon = game.scene.getEnemyPokemon()!;

View File

@ -6,7 +6,7 @@ import { TurnEndPhase } from "#app/phases/turn-end-phase";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type";
import { Biome } from "#enums/biome"; import { Biome } from "#enums/biome";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { WeatherType } from "#enums/weather-type"; import { WeatherType } from "#enums/weather-type";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
@ -34,43 +34,43 @@ describe("Abilities - Libero", () => {
.ability(AbilityId.LIBERO) .ability(AbilityId.LIBERO)
.startingLevel(100) .startingLevel(100)
.enemySpecies(Species.RATTATA) .enemySpecies(Species.RATTATA)
.enemyMoveset(Moves.ENDURE); .enemyMoveset(MoveId.ENDURE);
}); });
test("ability applies and changes a pokemon's type", async () => { test("ability applies and changes a pokemon's type", async () => {
game.override.moveset([Moves.SPLASH]); game.override.moveset([MoveId.SPLASH]);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
const leadPokemon = game.scene.getPlayerPokemon()!; const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined); expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.SPLASH); testPokemonTypeMatchesDefaultMoveType(leadPokemon, MoveId.SPLASH);
}); });
// Test for Gen9+ functionality, we are using previous funcionality // Test for Gen9+ functionality, we are using previous funcionality
test.skip("ability applies only once per switch in", async () => { test.skip("ability applies only once per switch in", async () => {
game.override.moveset([Moves.SPLASH, Moves.AGILITY]); game.override.moveset([MoveId.SPLASH, MoveId.AGILITY]);
await game.classicMode.startBattle([Species.MAGIKARP, Species.BULBASAUR]); await game.classicMode.startBattle([Species.MAGIKARP, Species.BULBASAUR]);
let leadPokemon = game.scene.getPlayerPokemon()!; let leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined); expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.SPLASH); testPokemonTypeMatchesDefaultMoveType(leadPokemon, MoveId.SPLASH);
game.move.select(Moves.AGILITY); game.move.select(MoveId.AGILITY);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
expect(leadPokemon.waveData.abilitiesApplied).toContain(AbilityId.LIBERO); expect(leadPokemon.waveData.abilitiesApplied).toContain(AbilityId.LIBERO);
const leadPokemonType = PokemonType[leadPokemon.getTypes()[0]]; const leadPokemonType = PokemonType[leadPokemon.getTypes()[0]];
const moveType = PokemonType[allMoves[Moves.AGILITY].type]; const moveType = PokemonType[allMoves[MoveId.AGILITY].type];
expect(leadPokemonType).not.toBe(moveType); expect(leadPokemonType).not.toBe(moveType);
await game.toNextTurn(); await game.toNextTurn();
@ -82,14 +82,14 @@ describe("Abilities - Libero", () => {
leadPokemon = game.scene.getPlayerPokemon()!; leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined); expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.SPLASH); testPokemonTypeMatchesDefaultMoveType(leadPokemon, MoveId.SPLASH);
}); });
test("ability applies correctly even if the pokemon's move has a variable type", async () => { test("ability applies correctly even if the pokemon's move has a variable type", async () => {
game.override.moveset([Moves.WEATHER_BALL]); game.override.moveset([MoveId.WEATHER_BALL]);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
@ -97,7 +97,7 @@ describe("Abilities - Libero", () => {
expect(leadPokemon).not.toBe(undefined); expect(leadPokemon).not.toBe(undefined);
game.scene.arena.weather = new Weather(WeatherType.SUNNY); game.scene.arena.weather = new Weather(WeatherType.SUNNY);
game.move.select(Moves.WEATHER_BALL); game.move.select(MoveId.WEATHER_BALL);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
expect(leadPokemon.waveData.abilitiesApplied).toContain(AbilityId.LIBERO); expect(leadPokemon.waveData.abilitiesApplied).toContain(AbilityId.LIBERO);
@ -108,7 +108,7 @@ describe("Abilities - Libero", () => {
}); });
test("ability applies correctly even if the type has changed by another ability", async () => { test("ability applies correctly even if the type has changed by another ability", async () => {
game.override.moveset([Moves.TACKLE]); game.override.moveset([MoveId.TACKLE]);
game.override.passiveAbility(AbilityId.REFRIGERATE); game.override.passiveAbility(AbilityId.REFRIGERATE);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
@ -116,7 +116,7 @@ describe("Abilities - Libero", () => {
const leadPokemon = game.scene.getPlayerPokemon()!; const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined); expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.TACKLE); game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
expect(leadPokemon.waveData.abilitiesApplied).toContain(AbilityId.LIBERO); expect(leadPokemon.waveData.abilitiesApplied).toContain(AbilityId.LIBERO);
@ -127,7 +127,7 @@ describe("Abilities - Libero", () => {
}); });
test("ability applies correctly even if the pokemon's move calls another move", async () => { test("ability applies correctly even if the pokemon's move calls another move", async () => {
game.override.moveset([Moves.NATURE_POWER]); game.override.moveset([MoveId.NATURE_POWER]);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
@ -135,60 +135,60 @@ describe("Abilities - Libero", () => {
expect(leadPokemon).not.toBe(undefined); expect(leadPokemon).not.toBe(undefined);
game.scene.arena.biomeType = Biome.MOUNTAIN; game.scene.arena.biomeType = Biome.MOUNTAIN;
game.move.select(Moves.NATURE_POWER); game.move.select(MoveId.NATURE_POWER);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.AIR_SLASH); testPokemonTypeMatchesDefaultMoveType(leadPokemon, MoveId.AIR_SLASH);
}); });
test("ability applies correctly even if the pokemon's move is delayed / charging", async () => { test("ability applies correctly even if the pokemon's move is delayed / charging", async () => {
game.override.moveset([Moves.DIG]); game.override.moveset([MoveId.DIG]);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
const leadPokemon = game.scene.getPlayerPokemon()!; const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined); expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.DIG); game.move.select(MoveId.DIG);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.DIG); testPokemonTypeMatchesDefaultMoveType(leadPokemon, MoveId.DIG);
}); });
test("ability applies correctly even if the pokemon's move misses", async () => { test("ability applies correctly even if the pokemon's move misses", async () => {
game.override.moveset([Moves.TACKLE]); game.override.moveset([MoveId.TACKLE]);
game.override.enemyMoveset(Moves.SPLASH); game.override.enemyMoveset(MoveId.SPLASH);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
const leadPokemon = game.scene.getPlayerPokemon()!; const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined); expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.TACKLE); game.move.select(MoveId.TACKLE);
await game.move.forceMiss(); await game.move.forceMiss();
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
const enemyPokemon = game.scene.getEnemyPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!;
expect(enemyPokemon.isFullHp()).toBe(true); expect(enemyPokemon.isFullHp()).toBe(true);
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.TACKLE); testPokemonTypeMatchesDefaultMoveType(leadPokemon, MoveId.TACKLE);
}); });
test("ability applies correctly even if the pokemon's move is protected against", async () => { test("ability applies correctly even if the pokemon's move is protected against", async () => {
game.override.moveset([Moves.TACKLE]).enemyMoveset(Moves.PROTECT); game.override.moveset([MoveId.TACKLE]).enemyMoveset(MoveId.PROTECT);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
const leadPokemon = game.scene.getPlayerPokemon()!; const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined); expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.TACKLE); game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.TACKLE); testPokemonTypeMatchesDefaultMoveType(leadPokemon, MoveId.TACKLE);
}); });
test("ability applies correctly even if the pokemon's move fails because of type immunity", async () => { test("ability applies correctly even if the pokemon's move fails because of type immunity", async () => {
game.override.moveset([Moves.TACKLE]); game.override.moveset([MoveId.TACKLE]);
game.override.enemySpecies(Species.GASTLY); game.override.enemySpecies(Species.GASTLY);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
@ -196,29 +196,29 @@ describe("Abilities - Libero", () => {
const leadPokemon = game.scene.getPlayerPokemon()!; const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined); expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.TACKLE); game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.TACKLE); testPokemonTypeMatchesDefaultMoveType(leadPokemon, MoveId.TACKLE);
}); });
test("ability is not applied if pokemon's type is the same as the move's type", async () => { test("ability is not applied if pokemon's type is the same as the move's type", async () => {
game.override.moveset([Moves.SPLASH]); game.override.moveset([MoveId.SPLASH]);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
const leadPokemon = game.scene.getPlayerPokemon()!; const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined); expect(leadPokemon).not.toBe(undefined);
leadPokemon.summonData.types = [allMoves[Moves.SPLASH].type]; leadPokemon.summonData.types = [allMoves[MoveId.SPLASH].type];
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
expect(leadPokemon.waveData.abilitiesApplied).not.toContain(AbilityId.LIBERO); expect(leadPokemon.waveData.abilitiesApplied).not.toContain(AbilityId.LIBERO);
}); });
test("ability is not applied if pokemon is terastallized", async () => { test("ability is not applied if pokemon is terastallized", async () => {
game.override.moveset([Moves.SPLASH]); game.override.moveset([MoveId.SPLASH]);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
@ -227,42 +227,42 @@ describe("Abilities - Libero", () => {
leadPokemon.isTerastallized = true; leadPokemon.isTerastallized = true;
game.move.select(Moves.SPLASH); game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
expect(leadPokemon.waveData.abilitiesApplied).not.toContain(AbilityId.LIBERO); expect(leadPokemon.waveData.abilitiesApplied).not.toContain(AbilityId.LIBERO);
}); });
test("ability is not applied if pokemon uses struggle", async () => { test("ability is not applied if pokemon uses struggle", async () => {
game.override.moveset([Moves.STRUGGLE]); game.override.moveset([MoveId.STRUGGLE]);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
const leadPokemon = game.scene.getPlayerPokemon()!; const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined); expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.STRUGGLE); game.move.select(MoveId.STRUGGLE);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
expect(leadPokemon.waveData.abilitiesApplied).not.toContain(AbilityId.LIBERO); expect(leadPokemon.waveData.abilitiesApplied).not.toContain(AbilityId.LIBERO);
}); });
test("ability is not applied if the pokemon's move fails", async () => { test("ability is not applied if the pokemon's move fails", async () => {
game.override.moveset([Moves.BURN_UP]); game.override.moveset([MoveId.BURN_UP]);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
const leadPokemon = game.scene.getPlayerPokemon()!; const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined); expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.BURN_UP); game.move.select(MoveId.BURN_UP);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
expect(leadPokemon.waveData.abilitiesApplied).not.toContain(AbilityId.LIBERO); expect(leadPokemon.waveData.abilitiesApplied).not.toContain(AbilityId.LIBERO);
}); });
test("ability applies correctly even if the pokemon's Trick-or-Treat fails", async () => { test("ability applies correctly even if the pokemon's Trick-or-Treat fails", async () => {
game.override.moveset([Moves.TRICK_OR_TREAT]); game.override.moveset([MoveId.TRICK_OR_TREAT]);
game.override.enemySpecies(Species.GASTLY); game.override.enemySpecies(Species.GASTLY);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
@ -270,29 +270,29 @@ describe("Abilities - Libero", () => {
const leadPokemon = game.scene.getPlayerPokemon()!; const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined); expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.TRICK_OR_TREAT); game.move.select(MoveId.TRICK_OR_TREAT);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.TRICK_OR_TREAT); testPokemonTypeMatchesDefaultMoveType(leadPokemon, MoveId.TRICK_OR_TREAT);
}); });
test("ability applies correctly and the pokemon curses itself", async () => { test("ability applies correctly and the pokemon curses itself", async () => {
game.override.moveset([Moves.CURSE]); game.override.moveset([MoveId.CURSE]);
await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([Species.MAGIKARP]);
const leadPokemon = game.scene.getPlayerPokemon()!; const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined); expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.CURSE); game.move.select(MoveId.CURSE);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.CURSE); testPokemonTypeMatchesDefaultMoveType(leadPokemon, MoveId.CURSE);
expect(leadPokemon.getTag(BattlerTagType.CURSED)).not.toBe(undefined); expect(leadPokemon.getTag(BattlerTagType.CURSED)).not.toBe(undefined);
}); });
}); });
function testPokemonTypeMatchesDefaultMoveType(pokemon: PlayerPokemon, move: Moves) { function testPokemonTypeMatchesDefaultMoveType(pokemon: PlayerPokemon, move: MoveId) {
expect(pokemon.waveData.abilitiesApplied).toContain(AbilityId.LIBERO); expect(pokemon.waveData.abilitiesApplied).toContain(AbilityId.LIBERO);
expect(pokemon.getTypes()).toHaveLength(1); expect(pokemon.getTypes()).toHaveLength(1);
const pokemonType = PokemonType[pokemon.getTypes()[0]], const pokemonType = PokemonType[pokemon.getTypes()[0]],

View File

@ -1,6 +1,6 @@
import { BattlerIndex } from "#app/battle"; import { BattlerIndex } from "#app/battle";
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
@ -24,13 +24,13 @@ describe("Abilities - Lightningrod", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.moveset([Moves.SPLASH, Moves.SHOCK_WAVE]) .moveset([MoveId.SPLASH, MoveId.SHOCK_WAVE])
.ability(AbilityId.BALL_FETCH) .ability(AbilityId.BALL_FETCH)
.battleStyle("double") .battleStyle("double")
.disableCrits() .disableCrits()
.enemySpecies(Species.MAGIKARP) .enemySpecies(Species.MAGIKARP)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(MoveId.SPLASH);
}); });
it("should redirect electric type moves", async () => { it("should redirect electric type moves", async () => {
@ -41,15 +41,15 @@ describe("Abilities - Lightningrod", () => {
enemy2.summonData.ability = AbilityId.LIGHTNING_ROD; enemy2.summonData.ability = AbilityId.LIGHTNING_ROD;
game.move.select(Moves.SHOCK_WAVE, BattlerIndex.PLAYER, BattlerIndex.ENEMY); game.move.select(MoveId.SHOCK_WAVE, BattlerIndex.PLAYER, BattlerIndex.ENEMY);
game.move.select(Moves.SPLASH, BattlerIndex.PLAYER_2); game.move.select(MoveId.SPLASH, BattlerIndex.PLAYER_2);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(enemy1.isFullHp()).toBe(true); expect(enemy1.isFullHp()).toBe(true);
}); });
it("should not redirect non-electric type moves", async () => { it("should not redirect non-electric type moves", async () => {
game.override.moveset([Moves.SPLASH, Moves.AERIAL_ACE]); game.override.moveset([MoveId.SPLASH, MoveId.AERIAL_ACE]);
await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]);
const enemy1 = game.scene.getEnemyField()[0]; const enemy1 = game.scene.getEnemyField()[0];
@ -57,8 +57,8 @@ describe("Abilities - Lightningrod", () => {
enemy2.summonData.ability = AbilityId.LIGHTNING_ROD; enemy2.summonData.ability = AbilityId.LIGHTNING_ROD;
game.move.select(Moves.AERIAL_ACE, BattlerIndex.PLAYER, BattlerIndex.ENEMY); game.move.select(MoveId.AERIAL_ACE, BattlerIndex.PLAYER, BattlerIndex.ENEMY);
game.move.select(Moves.SPLASH, BattlerIndex.PLAYER_2); game.move.select(MoveId.SPLASH, BattlerIndex.PLAYER_2);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(enemy1.isFullHp()).toBe(false); expect(enemy1.isFullHp()).toBe(false);
@ -71,8 +71,8 @@ describe("Abilities - Lightningrod", () => {
enemy2.summonData.ability = AbilityId.LIGHTNING_ROD; enemy2.summonData.ability = AbilityId.LIGHTNING_ROD;
game.move.select(Moves.SHOCK_WAVE, BattlerIndex.PLAYER, BattlerIndex.ENEMY); game.move.select(MoveId.SHOCK_WAVE, BattlerIndex.PLAYER, BattlerIndex.ENEMY);
game.move.select(Moves.SPLASH, BattlerIndex.PLAYER_2); game.move.select(MoveId.SPLASH, BattlerIndex.PLAYER_2);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(enemy2.isFullHp()).toBe(true); expect(enemy2.isFullHp()).toBe(true);
@ -88,15 +88,15 @@ describe("Abilities - Lightningrod", () => {
enemy2.summonData.ability = AbilityId.LIGHTNING_ROD; enemy2.summonData.ability = AbilityId.LIGHTNING_ROD;
game.move.select(Moves.SHOCK_WAVE, BattlerIndex.PLAYER, BattlerIndex.ENEMY); game.move.select(MoveId.SHOCK_WAVE, BattlerIndex.PLAYER, BattlerIndex.ENEMY);
game.move.select(Moves.SPLASH, BattlerIndex.PLAYER_2); game.move.select(MoveId.SPLASH, BattlerIndex.PLAYER_2);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(enemy1.isFullHp()).toBe(false); expect(enemy1.isFullHp()).toBe(false);
}); });
it("should redirect moves changed to electric type via ability", async () => { it("should redirect moves changed to electric type via ability", async () => {
game.override.ability(AbilityId.GALVANIZE).moveset(Moves.TACKLE); game.override.ability(AbilityId.GALVANIZE).moveset(MoveId.TACKLE);
await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]);
const enemy1 = game.scene.getEnemyField()[0]; const enemy1 = game.scene.getEnemyField()[0];
@ -104,8 +104,8 @@ describe("Abilities - Lightningrod", () => {
enemy2.summonData.ability = AbilityId.LIGHTNING_ROD; enemy2.summonData.ability = AbilityId.LIGHTNING_ROD;
game.move.select(Moves.TACKLE, BattlerIndex.PLAYER, BattlerIndex.ENEMY); game.move.select(MoveId.TACKLE, BattlerIndex.PLAYER, BattlerIndex.ENEMY);
game.move.select(Moves.SPLASH, BattlerIndex.PLAYER_2); game.move.select(MoveId.SPLASH, BattlerIndex.PLAYER_2);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(enemy1.isFullHp()).toBe(true); expect(enemy1.isFullHp()).toBe(true);

View File

@ -1,5 +1,5 @@
import { AbilityId } from "#enums/ability-id"; import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves"; import { MoveId } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { StatusEffect } from "#enums/status-effect"; import { StatusEffect } from "#enums/status-effect";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
@ -23,27 +23,27 @@ describe("Abilities - Limber", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.moveset([Moves.SPLASH]) .moveset([MoveId.SPLASH])
.ability(AbilityId.BALL_FETCH) .ability(AbilityId.BALL_FETCH)
.battleStyle("single") .battleStyle("single")
.disableCrits() .disableCrits()
.enemySpecies(Species.MAGIKARP) .enemySpecies(Species.MAGIKARP)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(MoveId.SPLASH);
}); });
it("should remove paralysis when gained", async () => { it("should remove paralysis when gained", async () => {
game.override game.override
.ability(AbilityId.LIMBER) .ability(AbilityId.LIMBER)
.enemyAbility(AbilityId.BALL_FETCH) .enemyAbility(AbilityId.BALL_FETCH)
.moveset(Moves.SKILL_SWAP) .moveset(MoveId.SKILL_SWAP)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(MoveId.SPLASH);
await game.classicMode.startBattle([Species.FEEBAS]); await game.classicMode.startBattle([Species.FEEBAS]);
const enemy = game.scene.getEnemyPokemon(); const enemy = game.scene.getEnemyPokemon();
enemy?.trySetStatus(StatusEffect.PARALYSIS); enemy?.trySetStatus(StatusEffect.PARALYSIS);
expect(enemy?.status?.effect).toBe(StatusEffect.PARALYSIS); expect(enemy?.status?.effect).toBe(StatusEffect.PARALYSIS);
game.move.select(Moves.SKILL_SWAP); game.move.select(MoveId.SKILL_SWAP);
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(enemy?.status).toBeNull(); expect(enemy?.status).toBeNull();

Some files were not shown because too many files have changed in this diff Show More