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 type { ExpNotification } from "#enums/exp-notification";
import { MoneyFormat } from "#enums/money-format";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { PlayerGender } from "#enums/player-gender";
import { Species } from "#enums/species";
import { UiTheme } from "#enums/ui-theme";
@ -707,14 +707,14 @@ export default class BattleScene extends SceneBase {
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(loadPokemonAssets),
initCommonAnims().then(() => loadCommonAnimAssets(true)),
Promise.all([Moves.TACKLE, Moves.TAIL_WHIP, Moves.FOCUS_ENERGY, Moves.STRUGGLE].map(m => initMoveAnim(m))).then(
() => loadMoveAnimAssets(defaultMoves, true),
),
Promise.all(
[MoveId.TACKLE, MoveId.TAIL_WHIP, MoveId.FOCUS_ENERGY, MoveId.STRUGGLE].map(m => initMoveAnim(m)),
).then(() => loadMoveAnimAssets(defaultMoves, true)),
this.initStarterColors(),
]).then(() => {
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 { ArenaTagType } from "#enums/arena-tag-type";
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 { MusicPreference } from "#app/system/settings/settings";
import { Species } from "#enums/species";
@ -78,7 +78,7 @@ export default class Battle {
public battleScore = 0;
public postBattleLoot: PokemonHeldItemModifier[] = [];
public escapeAttempts = 0;
public lastMove: Moves;
public lastMove: MoveId;
public battleSeed: string = randomString(16, true);
private battleSeedState: string | null = null;
public moneyScattered = 0;

View File

@ -53,7 +53,7 @@ import { WeatherType } from "#enums/weather-type";
import { AbilityId } from "#enums/ability-id";
import { ArenaTagType } from "#enums/arena-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 { SwitchType } from "#enums/switch-type";
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 {
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));
}
/**
* @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 {
(args[0] as NumberHolder).value *= this.chanceMultiplier;
@ -1249,7 +1249,7 @@ export class MoveTypeChangeAbAttr extends PreAttackAbAttr {
*
* Can be applied if:
* - 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 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
@ -1264,8 +1264,8 @@ export class MoveTypeChangeAbAttr extends PreAttackAbAttr {
return (!this.condition || this.condition(pokemon, _defender, move)) &&
!noAbilityTypeOverrideMoves.has(move.id) &&
(!pokemon.isTerastallized ||
(move.id !== Moves.TERA_BLAST &&
(move.id !== Moves.TERA_STARSTORM || pokemon.getTeraType() !== PokemonType.STELLAR || !pokemon.hasSpecies(Species.TERAPAGOS))));
(move.id !== MoveId.TERA_BLAST &&
(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 {
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
* @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
globalScene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.COMMANDER_APPLY);
// 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)
globalScene.tryRemovePhase((phase) => phase instanceof MovePhase && phase.pokemon === pokemon);
}
@ -3712,7 +3712,7 @@ function getAnticipationCondition(): AbAttrCondition {
return true;
}
// 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)
+ (opponent.ivs[Stat.ATK] & 1) * 2
+ (opponent.ivs[Stat.DEF] & 1) * 4
@ -3764,7 +3764,7 @@ export class ForewarnAbAttr extends PostSummonAbAttr {
movePower = 1;
} else if (move?.getMove().hasAttr(OneHitKOAttr)) {
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;
} else if (move?.getMove().power === -1) {
movePower = 80;
@ -4856,7 +4856,7 @@ export class RedirectMoveAbAttr extends AbAttr {
*/
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;
}
const target = args[1] as NumberHolder;
@ -4870,7 +4870,7 @@ export class RedirectMoveAbAttr extends AbAttr {
target.value = newTarget;
}
canRedirect(moveId: Moves, user: Pokemon): boolean {
canRedirect(moveId: MoveId, user: Pokemon): boolean {
const move = allMoves[moveId];
return !![ MoveTarget.NEAR_OTHER, MoveTarget.OTHER ].find(t => move.moveTarget === t);
}
@ -4884,7 +4884,7 @@ export class RedirectTypeMoveAbAttr extends RedirectMoveAbAttr {
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;
}
}
@ -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}.
* 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 { }
@ -5731,7 +5731,7 @@ export class PostDamageForceSwitchAbAttr extends PostDamageAbAttr {
source?: Pokemon): boolean {
const moveHistory = pokemon.getMoveHistory();
// 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) {
const lastMoveUsed = moveHistory[moveHistory.length - 1];
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.
const fordbiddenDefendingMoves = [ Moves.DRAGON_TAIL, Moves.CIRCLE_THROW ];
const fordbiddenDefendingMoves = [ MoveId.DRAGON_TAIL, MoveId.CIRCLE_THROW ];
if (source) {
const enemyMoveHistory = source.getMoveHistory();
if (enemyMoveHistory.length > 0) {
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.
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;
// 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

View File

@ -25,7 +25,7 @@ import i18next from "i18next";
import { AbilityId } from "#enums/ability-id";
import { ArenaTagType } from "#enums/arena-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 { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
@ -41,7 +41,7 @@ export abstract class ArenaTag {
constructor(
public tagType: ArenaTagType,
public turnCount: number,
public sourceMove?: Moves,
public sourceMove?: MoveId,
public sourceId?: number,
public side: ArenaTagSide = ArenaTagSide.BOTH,
) {}
@ -116,7 +116,7 @@ export abstract class ArenaTag {
*/
export class MistTag extends ArenaTag {
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 {
@ -188,7 +188,7 @@ export class WeakenMoveScreenTag extends ArenaTag {
constructor(
tagType: ArenaTagType,
turnCount: number,
sourceMove: Moves,
sourceMove: MoveId,
sourceId: number,
side: ArenaTagSide,
weakenedCategories: MoveCategory[],
@ -230,11 +230,11 @@ export class WeakenMoveScreenTag extends ArenaTag {
/**
* Reduces the damage of physical moves.
* Used by {@linkcode Moves.REFLECT}
* Used by {@linkcode MoveId.REFLECT}
*/
class ReflectTag extends WeakenMoveScreenTag {
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 {
@ -250,11 +250,11 @@ class ReflectTag extends WeakenMoveScreenTag {
/**
* Reduces the damage of special moves.
* Used by {@linkcode Moves.LIGHT_SCREEN}
* Used by {@linkcode MoveId.LIGHT_SCREEN}
*/
class LightScreenTag extends WeakenMoveScreenTag {
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 {
@ -270,11 +270,11 @@ class LightScreenTag extends WeakenMoveScreenTag {
/**
* Reduces the damage of physical and special moves.
* Used by {@linkcode Moves.AURORA_VEIL}
* Used by {@linkcode MoveId.AURORA_VEIL}
*/
class AuroraVeilTag extends WeakenMoveScreenTag {
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.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
@ -305,7 +305,7 @@ export class ConditionalProtectTag extends ArenaTag {
constructor(
tagType: ArenaTagType,
sourceMove: Moves,
sourceMove: MoveId,
sourceId: number,
side: ArenaTagSide,
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 _attacker the attacking {@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
* @returns `true` if this tag protected against the attack; `false` otherwise
*/
@ -347,7 +347,7 @@ export class ConditionalProtectTag extends ArenaTag {
isProtected: BooleanHolder,
_attacker: Pokemon,
defender: Pokemon,
moveId: Moves,
moveId: MoveId,
ignoresProtectBypass: BooleanHolder,
): boolean {
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}
* 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.
* This includes moves with modified priorities from abilities (e.g. Prankster)
*/
@ -398,7 +398,7 @@ const QuickGuardConditionFunc: ProtectConditionFunc = (_arena, moveId) => {
*/
class QuickGuardTag extends ConditionalProtectTag {
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}
* 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).
*/
const WideGuardConditionFunc: ProtectConditionFunc = (_arena, moveId): boolean => {
@ -429,7 +429,7 @@ const WideGuardConditionFunc: ProtectConditionFunc = (_arena, moveId): boolean =
*/
class WideGuardTag extends ConditionalProtectTag {
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}
* 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.
*/
const MatBlockConditionFunc: ProtectConditionFunc = (_arena, moveId): boolean => {
@ -451,7 +451,7 @@ const MatBlockConditionFunc: ProtectConditionFunc = (_arena, moveId): boolean =>
*/
class MatBlockTag extends ConditionalProtectTag {
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) {
@ -474,7 +474,7 @@ class MatBlockTag extends ConditionalProtectTag {
* Condition function for {@link https://bulbapedia.bulbagarden.net/wiki/Crafty_Shield_(move) Crafty Shield's}
* 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
* Pokemon or sides of the field.
*/
@ -495,7 +495,7 @@ const CraftyShieldConditionFunc: ProtectConditionFunc = (_arena, moveId) => {
*/
class CraftyShieldTag extends ConditionalProtectTag {
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
* @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 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);
}
@ -546,7 +546,7 @@ class WishTag extends ArenaTag {
private healHp: number;
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 {
@ -588,7 +588,7 @@ export class WeakenMoveTypeTag extends ArenaTag {
* @param sourceMove - The move that created 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);
this.weakenedType = type;
@ -617,7 +617,7 @@ export class WeakenMoveTypeTag extends ArenaTag {
*/
class MudSportTag extends WeakenMoveTypeTag {
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 {
@ -635,7 +635,7 @@ class MudSportTag extends WeakenMoveTypeTag {
*/
class WaterSportTag extends WeakenMoveTypeTag {
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 {
@ -653,7 +653,7 @@ class WaterSportTag extends WeakenMoveTypeTag {
* Converts Normal-type moves to Electric type for the rest of the turn.
*/
export class IonDelugeTag extends ArenaTag {
constructor(sourceMove?: Moves) {
constructor(sourceMove?: MoveId) {
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 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);
this.layers = 1;
@ -750,7 +750,7 @@ export class ArenaTrapTag extends ArenaTag {
*/
class SpikesTag extends ArenaTrapTag {
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 {
@ -802,7 +802,7 @@ class ToxicSpikesTag extends ArenaTrapTag {
private neutralized: boolean;
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;
}
@ -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),
* and deals damage after the turn count is reached.
*/
@ -876,7 +876,7 @@ export class DelayedAttackTag extends ArenaTag {
constructor(
tagType: ArenaTagType,
sourceMove: Moves | undefined,
sourceMove: MoveId | undefined,
sourceId: number,
targetIndex: BattlerIndex,
side: ArenaTagSide = ArenaTagSide.BOTH,
@ -909,7 +909,7 @@ export class DelayedAttackTag extends ArenaTag {
*/
class StealthRockTag extends ArenaTrapTag {
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 {
@ -994,7 +994,7 @@ class StealthRockTag extends ArenaTrapTag {
*/
class StickyWebTag extends ArenaTrapTag {
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 {
@ -1055,7 +1055,7 @@ class StickyWebTag extends ArenaTrapTag {
*/
export class TrickRoomTag extends ArenaTag {
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 {
constructor(turnCount: number) {
super(ArenaTagType.GRAVITY, turnCount, Moves.GRAVITY);
super(ArenaTagType.GRAVITY, turnCount, MoveId.GRAVITY);
}
onAdd(_arena: Arena): void {
@ -1122,7 +1122,7 @@ export class GravityTag extends ArenaTag {
*/
class TailwindTag extends ArenaTag {
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 {
@ -1171,11 +1171,11 @@ class TailwindTag extends ArenaTag {
/**
* 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 {
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 {
@ -1189,7 +1189,7 @@ class HappyHourTag extends ArenaTag {
class SafeguardTag extends ArenaTag {
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 {
@ -1221,7 +1221,7 @@ class NoneTag extends ArenaTag {
*/
class ImprisonTag extends ArenaTrapTag {
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();
party?.forEach((p: Pokemon) => {
if (p.isAllowedInBattle()) {
p.addTag(BattlerTagType.IMPRISON, 1, Moves.IMPRISON, this.sourceId);
p.addTag(BattlerTagType.IMPRISON, 1, MoveId.IMPRISON, this.sourceId);
}
});
globalScene.queueMessage(
@ -1263,7 +1263,7 @@ class ImprisonTag extends ArenaTrapTag {
override activateTrap(pokemon: Pokemon): boolean {
const source = this.getSourcePokemon();
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;
}
@ -1289,7 +1289,7 @@ class ImprisonTag extends ArenaTrapTag {
*/
class FireGrassPledgeTag extends ArenaTag {
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 {
@ -1334,7 +1334,7 @@ class FireGrassPledgeTag extends ArenaTag {
*/
class WaterFirePledgeTag extends ArenaTag {
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 {
@ -1368,7 +1368,7 @@ class WaterFirePledgeTag extends ArenaTag {
*/
class GrassWaterPledgeTag extends ArenaTag {
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 {
@ -1390,7 +1390,7 @@ class GrassWaterPledgeTag extends ArenaTag {
*/
export class FairyLockTag extends ArenaTag {
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 {
@ -1485,7 +1485,7 @@ export class SuppressAbilitiesTag extends ArenaTag {
export function getArenaTag(
tagType: ArenaTagType,
turnCount: number,
sourceMove: Moves | undefined,
sourceMove: MoveId | undefined,
sourceId: number,
targetIndex?: BattlerIndex,
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 { Nature } from "#enums/nature";
import { Biome } from "#enums/biome";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import { SpeciesFormKey } from "#enums/species-form-key";
import { TimeOfDay } from "#enums/time-of-day";
@ -181,11 +181,11 @@ class TimeOfDayEvolutionCondition extends SpeciesEvolutionCondition {
}
class MoveEvolutionCondition extends SpeciesEvolutionCondition {
public move: Moves;
constructor(move: Moves) {
public move: MoveId;
constructor(move: MoveId) {
super(p => p.moveset.filter(m => m.moveId === move).length > 0);
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`) });
}
}
@ -283,12 +283,12 @@ class TreasureEvolutionCondition extends SpeciesEvolutionCondition {
}
class TyrogueEvolutionCondition extends SpeciesEvolutionCondition {
public move: Moves;
constructor(move: Moves) {
public move: MoveId;
constructor(move: MoveId) {
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;
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`) });
}
}
@ -303,9 +303,9 @@ class NatureEvolutionCondition extends SpeciesEvolutionCondition {
}
class MoveTimeOfDayEvolutionCondition extends SpeciesEvolutionCondition {
public move: Moves;
public move: MoveId;
public timesOfDay: TimeOfDay[];
constructor(move: Moves, tod: "day" | "night") {
constructor(move: MoveId, tod: "day" | "night") {
if (tod === "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;
@ -318,7 +318,7 @@ class MoveTimeOfDayEvolutionCondition extends SpeciesEvolutionCondition {
super(() => false);
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}`) });
}
}
@ -336,12 +336,12 @@ class DunsparceEvolutionCondition extends SpeciesEvolutionCondition {
constructor() {
super(p => {
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);
}
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`) });
}
}
@ -499,9 +499,9 @@ export const pokemonEvolutions: PokemonEvolutions = {
* If Tyrogue knows multiple of these moves, its evolution is based on
* the first qualifying move in its moveset.
*/
new SpeciesEvolution(Species.HITMONLEE, 20, null, new TyrogueEvolutionCondition(Moves.LOW_SWEEP)),
new SpeciesEvolution(Species.HITMONCHAN, 20, null, new TyrogueEvolutionCondition(Moves.MACH_PUNCH)),
new SpeciesEvolution(Species.HITMONTOP, 20, null, new TyrogueEvolutionCondition(Moves.RAPID_SPIN)),
new SpeciesEvolution(Species.HITMONLEE, 20, null, new TyrogueEvolutionCondition(MoveId.LOW_SWEEP)),
new SpeciesEvolution(Species.HITMONCHAN, 20, null, new TyrogueEvolutionCondition(MoveId.MACH_PUNCH)),
new SpeciesEvolution(Species.HITMONTOP, 20, null, new TyrogueEvolutionCondition(MoveId.RAPID_SPIN)),
],
[Species.KOFFING]: [
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)
],
[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]: [
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]: [
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)
],
[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]: [
new SpeciesEvolution(Species.SUNFLORA, 1, EvolutionItem.SUN_STONE, null, SpeciesWildEvolutionDelay.LONG)
],
[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]: [
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)
],
[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]: [
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]: [
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
],
[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]: [
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]: [
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)
],
[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]: [
new SpeciesEvolution(Species.GALAR_MR_MIME, 1, null, new MoveTimeOfDayEvolutionCondition(Moves.MIMIC, "night"), SpeciesWildEvolutionDelay.MEDIUM),
new SpeciesEvolution(Species.MR_MIME, 1, null, new MoveTimeOfDayEvolutionCondition(Moves.MIMIC, "day"), 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(MoveId.MIMIC, "day"), SpeciesWildEvolutionDelay.MEDIUM)
],
[Species.PANSAGE]: [
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"))
],
[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]: [
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]: [
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)
],
[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]: [
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)
],
[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]: [
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)
],
[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]: [
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)
],
[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]: [
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 nil, getFrameMs, getEnumKeys, getEnumValues, animationFileName } from "../utils/common";
import type { BattlerIndex } from "../battle";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { SubstituteTag } from "./battler-tags";
import { isNullOrUndefined } from "../utils/common";
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 commonAnims = new Map<CommonAnim, 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 => {
if (moveAnims.has(move)) {
if (moveAnims.get(move) !== null) {
@ -544,12 +544,12 @@ export function initMoveAnim(move: Moves): Promise<void> {
moveAnims.set(move, null);
const defaultMoveAnim =
allMoves[move] instanceof AttackMove
? Moves.TACKLE
? MoveId.TACKLE
: allMoves[move] instanceof SelfStatusMove
? Moves.FOCUS_ENERGY
: Moves.TAIL_WHIP;
? MoveId.FOCUS_ENERGY
: MoveId.TAIL_WHIP;
const fetchAnimAndResolve = (move: Moves) => {
const fetchAnimAndResolve = (move: MoveId) => {
globalScene
.cachedFetch(`./battle-anims/${animationFileName(move)}.json`)
.then(response => {
@ -594,7 +594,7 @@ export function initMoveAnim(move: Moves): Promise<void> {
* @param move the move to populate an animation for
* @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));
}
@ -606,7 +606,7 @@ function useDefaultAnim(move: Moves, defaultMoveAnim: Moves) {
*
* @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);
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);
if (moveAnims.get(move) === null) {
moveAnims.set(move, moveAnim);
@ -697,7 +697,7 @@ export async function loadEncounterAnimAssets(startLoad?: boolean): Promise<void
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 => {
const moveAnimations = moveIds.flatMap(m => moveAnims.get(m) as AnimConfig);
for (const moveId of moveIds) {
@ -1425,9 +1425,9 @@ export class CommonBattleAnim 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
super(user, globalScene.getField()[target] ?? user, playOnEmptyField);
@ -1456,7 +1456,7 @@ export class MoveAnim extends BattleAnim {
export class MoveChargeAnim extends MoveAnim {
private chargeAnim: ChargeAnim;
constructor(chargeAnim: ChargeAnim, move: Moves, user: Pokemon) {
constructor(chargeAnim: ChargeAnim, move: MoveId, user: Pokemon) {
super(move, user, 0);
this.chargeAnim = chargeAnim;
@ -1502,8 +1502,8 @@ export async function populateAnims() {
const chargeAnimIds = getEnumValues(ChargeAnim) as ChargeAnim[];
const commonNamePattern = /name: (?:Common:)?(Opp )?(.*)/;
const moveNameToId = {};
for (const move of getEnumValues(Moves).slice(1)) {
const moveName = Moves[move].toUpperCase().replace(/\_/g, "");
for (const move of getEnumValues(MoveId).slice(1)) {
const moveName = MoveId[move].toUpperCase().replace(/\_/g, "");
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 { TrainerType } from "#enums/trainer-type";
import { Nature } from "#enums/nature";
import type { Moves } from "#enums/moves";
import type { MoveId } from "#enums/moves";
import { TypeColor, TypeShadow } from "#enums/color";
import { ModifierTier } from "#app/modifier/modifier-tier";
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.
* @param _pokemon {@link Pokemon} What pokemon would learn the move.
* @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.
* @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;
}
@ -407,11 +407,11 @@ export abstract class Challenge {
* An apply function for MOVE_WEIGHT. Derived classes should alter this.
* @param _pokemon {@link Pokemon} What pokemon would learn the move.
* @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
* @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;
}
@ -1090,7 +1090,7 @@ export function applyChallenges(challengeType: ChallengeType.GAME_MODE_MODIFY):
* @param challengeType {@link ChallengeType} ChallengeType.MOVE_ACCESS
* @param pokemon {@link Pokemon} What pokemon would learn the move.
* @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.
* @returns True if any challenge was successfully applied.
*/
@ -1098,7 +1098,7 @@ export function applyChallenges(
challengeType: ChallengeType.MOVE_ACCESS,
pokemon: Pokemon,
moveSource: MoveSourceType,
move: Moves,
move: MoveId,
level: NumberHolder,
): boolean;
/**
@ -1106,7 +1106,7 @@ export function applyChallenges(
* @param challengeType {@link ChallengeType} ChallengeType.MOVE_WEIGHT
* @param pokemon {@link Pokemon} What pokemon would learn the move.
* @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.
* @returns True if any challenge was successfully applied.
*/
@ -1114,7 +1114,7 @@ export function applyChallenges(
challengeType: ChallengeType.MOVE_WEIGHT,
pokemon: Pokemon,
moveSource: MoveSourceType,
move: Moves,
move: MoveId,
weight: NumberHolder,
): 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} */
export const invalidMetronomeMoves: ReadonlySet<Moves> = new Set([
Moves.AFTER_YOU,
Moves.ASSIST,
Moves.BANEFUL_BUNKER,
Moves.BEAK_BLAST,
Moves.BELCH,
Moves.BESTOW,
Moves.COMEUPPANCE,
Moves.COPYCAT,
Moves.COUNTER,
Moves.CRAFTY_SHIELD,
Moves.DESTINY_BOND,
Moves.DETECT,
Moves.ENDURE,
Moves.FEINT,
Moves.FOCUS_PUNCH,
Moves.FOLLOW_ME,
Moves.HELPING_HAND,
Moves.INSTRUCT,
Moves.KINGS_SHIELD,
Moves.MAT_BLOCK,
Moves.ME_FIRST,
Moves.METRONOME,
Moves.MIMIC,
Moves.MIRROR_COAT,
Moves.MIRROR_MOVE,
Moves.OBSTRUCT,
Moves.PROTECT,
Moves.QUASH,
Moves.QUICK_GUARD,
Moves.RAGE_POWDER,
Moves.REVIVAL_BLESSING,
Moves.SHELL_TRAP,
Moves.SILK_TRAP,
Moves.SKETCH,
Moves.SLEEP_TALK,
Moves.SNATCH,
Moves.SNORE,
Moves.SPIKY_SHIELD,
Moves.SPOTLIGHT,
Moves.STRUGGLE,
Moves.TRANSFORM,
Moves.WIDE_GUARD,
/** Set of moves that cannot be called by {@linkcode MoveId.METRONOME Metronome} */
export const invalidMetronomeMoves: ReadonlySet<MoveId> = new Set([
MoveId.AFTER_YOU,
MoveId.ASSIST,
MoveId.BANEFUL_BUNKER,
MoveId.BEAK_BLAST,
MoveId.BELCH,
MoveId.BESTOW,
MoveId.COMEUPPANCE,
MoveId.COPYCAT,
MoveId.COUNTER,
MoveId.CRAFTY_SHIELD,
MoveId.DESTINY_BOND,
MoveId.DETECT,
MoveId.ENDURE,
MoveId.FEINT,
MoveId.FOCUS_PUNCH,
MoveId.FOLLOW_ME,
MoveId.HELPING_HAND,
MoveId.INSTRUCT,
MoveId.KINGS_SHIELD,
MoveId.MAT_BLOCK,
MoveId.ME_FIRST,
MoveId.METRONOME,
MoveId.MIMIC,
MoveId.MIRROR_COAT,
MoveId.MIRROR_MOVE,
MoveId.OBSTRUCT,
MoveId.PROTECT,
MoveId.QUASH,
MoveId.QUICK_GUARD,
MoveId.RAGE_POWDER,
MoveId.REVIVAL_BLESSING,
MoveId.SHELL_TRAP,
MoveId.SILK_TRAP,
MoveId.SKETCH,
MoveId.SLEEP_TALK,
MoveId.SNATCH,
MoveId.SNORE,
MoveId.SPIKY_SHIELD,
MoveId.SPOTLIGHT,
MoveId.STRUGGLE,
MoveId.TRANSFORM,
MoveId.WIDE_GUARD,
]);
/** Set of moves that cannot be called by {@linkcode Moves.ASSIST Assist} */
export const invalidAssistMoves: ReadonlySet<Moves> = new Set([
Moves.ASSIST,
Moves.BANEFUL_BUNKER,
Moves.BEAK_BLAST,
Moves.BELCH,
Moves.BESTOW,
Moves.BOUNCE,
Moves.CELEBRATE,
Moves.CHATTER,
Moves.CIRCLE_THROW,
Moves.COPYCAT,
Moves.COUNTER,
Moves.DESTINY_BOND,
Moves.DETECT,
Moves.DIG,
Moves.DIVE,
Moves.DRAGON_TAIL,
Moves.ENDURE,
Moves.FEINT,
Moves.FLY,
Moves.FOCUS_PUNCH,
Moves.FOLLOW_ME,
Moves.HELPING_HAND,
Moves.HOLD_HANDS,
Moves.KINGS_SHIELD,
Moves.MAT_BLOCK,
Moves.ME_FIRST,
Moves.METRONOME,
Moves.MIMIC,
Moves.MIRROR_COAT,
Moves.MIRROR_MOVE,
Moves.NATURE_POWER,
Moves.PHANTOM_FORCE,
Moves.PROTECT,
Moves.RAGE_POWDER,
Moves.ROAR,
Moves.SHADOW_FORCE,
Moves.SHELL_TRAP,
Moves.SKETCH,
Moves.SKY_DROP,
Moves.SLEEP_TALK,
Moves.SNATCH,
Moves.SPIKY_SHIELD,
Moves.SPOTLIGHT,
Moves.STRUGGLE,
Moves.SWITCHEROO,
Moves.TRANSFORM,
Moves.TRICK,
Moves.WHIRLWIND,
/** Set of moves that cannot be called by {@linkcode MoveId.ASSIST Assist} */
export const invalidAssistMoves: ReadonlySet<MoveId> = new Set([
MoveId.ASSIST,
MoveId.BANEFUL_BUNKER,
MoveId.BEAK_BLAST,
MoveId.BELCH,
MoveId.BESTOW,
MoveId.BOUNCE,
MoveId.CELEBRATE,
MoveId.CHATTER,
MoveId.CIRCLE_THROW,
MoveId.COPYCAT,
MoveId.COUNTER,
MoveId.DESTINY_BOND,
MoveId.DETECT,
MoveId.DIG,
MoveId.DIVE,
MoveId.DRAGON_TAIL,
MoveId.ENDURE,
MoveId.FEINT,
MoveId.FLY,
MoveId.FOCUS_PUNCH,
MoveId.FOLLOW_ME,
MoveId.HELPING_HAND,
MoveId.HOLD_HANDS,
MoveId.KINGS_SHIELD,
MoveId.MAT_BLOCK,
MoveId.ME_FIRST,
MoveId.METRONOME,
MoveId.MIMIC,
MoveId.MIRROR_COAT,
MoveId.MIRROR_MOVE,
MoveId.NATURE_POWER,
MoveId.PHANTOM_FORCE,
MoveId.PROTECT,
MoveId.RAGE_POWDER,
MoveId.ROAR,
MoveId.SHADOW_FORCE,
MoveId.SHELL_TRAP,
MoveId.SKETCH,
MoveId.SKY_DROP,
MoveId.SLEEP_TALK,
MoveId.SNATCH,
MoveId.SPIKY_SHIELD,
MoveId.SPOTLIGHT,
MoveId.STRUGGLE,
MoveId.SWITCHEROO,
MoveId.TRANSFORM,
MoveId.TRICK,
MoveId.WHIRLWIND,
]);
/** Set of moves that cannot be called by {@linkcode Moves.SLEEP_TALK Sleep Talk} */
export const invalidSleepTalkMoves: ReadonlySet<Moves> = new Set([
Moves.ASSIST,
Moves.BELCH,
Moves.BEAK_BLAST,
Moves.BIDE,
Moves.BOUNCE,
Moves.COPYCAT,
Moves.DIG,
Moves.DIVE,
Moves.FREEZE_SHOCK,
Moves.FLY,
Moves.FOCUS_PUNCH,
Moves.GEOMANCY,
Moves.ICE_BURN,
Moves.ME_FIRST,
Moves.METRONOME,
Moves.MIRROR_MOVE,
Moves.MIMIC,
Moves.PHANTOM_FORCE,
Moves.RAZOR_WIND,
Moves.SHADOW_FORCE,
Moves.SHELL_TRAP,
Moves.SKETCH,
Moves.SKULL_BASH,
Moves.SKY_ATTACK,
Moves.SKY_DROP,
Moves.SLEEP_TALK,
Moves.SOLAR_BLADE,
Moves.SOLAR_BEAM,
Moves.STRUGGLE,
Moves.UPROAR,
/** Set of moves that cannot be called by {@linkcode MoveId.SLEEP_TALK Sleep Talk} */
export const invalidSleepTalkMoves: ReadonlySet<MoveId> = new Set([
MoveId.ASSIST,
MoveId.BELCH,
MoveId.BEAK_BLAST,
MoveId.BIDE,
MoveId.BOUNCE,
MoveId.COPYCAT,
MoveId.DIG,
MoveId.DIVE,
MoveId.FREEZE_SHOCK,
MoveId.FLY,
MoveId.FOCUS_PUNCH,
MoveId.GEOMANCY,
MoveId.ICE_BURN,
MoveId.ME_FIRST,
MoveId.METRONOME,
MoveId.MIRROR_MOVE,
MoveId.MIMIC,
MoveId.PHANTOM_FORCE,
MoveId.RAZOR_WIND,
MoveId.SHADOW_FORCE,
MoveId.SHELL_TRAP,
MoveId.SKETCH,
MoveId.SKULL_BASH,
MoveId.SKY_ATTACK,
MoveId.SKY_DROP,
MoveId.SLEEP_TALK,
MoveId.SOLAR_BLADE,
MoveId.SOLAR_BEAM,
MoveId.STRUGGLE,
MoveId.UPROAR,
]);
/** Set of moves that cannot be copied by {@linkcode Moves.COPYCAT Copycat} */
export const invalidCopycatMoves: ReadonlySet<Moves> = new Set([
Moves.ASSIST,
Moves.BANEFUL_BUNKER,
Moves.BEAK_BLAST,
Moves.BESTOW,
Moves.CELEBRATE,
Moves.CHATTER,
Moves.CIRCLE_THROW,
Moves.COPYCAT,
Moves.COUNTER,
Moves.DESTINY_BOND,
Moves.DETECT,
Moves.DRAGON_TAIL,
Moves.ENDURE,
Moves.FEINT,
Moves.FOCUS_PUNCH,
Moves.FOLLOW_ME,
Moves.HELPING_HAND,
Moves.HOLD_HANDS,
Moves.KINGS_SHIELD,
Moves.MAT_BLOCK,
Moves.ME_FIRST,
Moves.METRONOME,
Moves.MIMIC,
Moves.MIRROR_COAT,
Moves.MIRROR_MOVE,
Moves.PROTECT,
Moves.RAGE_POWDER,
Moves.ROAR,
Moves.SHELL_TRAP,
Moves.SKETCH,
Moves.SLEEP_TALK,
Moves.SNATCH,
Moves.SPIKY_SHIELD,
Moves.SPOTLIGHT,
Moves.STRUGGLE,
Moves.SWITCHEROO,
Moves.TRANSFORM,
Moves.TRICK,
Moves.WHIRLWIND,
/** Set of moves that cannot be copied by {@linkcode MoveId.COPYCAT Copycat} */
export const invalidCopycatMoves: ReadonlySet<MoveId> = new Set([
MoveId.ASSIST,
MoveId.BANEFUL_BUNKER,
MoveId.BEAK_BLAST,
MoveId.BESTOW,
MoveId.CELEBRATE,
MoveId.CHATTER,
MoveId.CIRCLE_THROW,
MoveId.COPYCAT,
MoveId.COUNTER,
MoveId.DESTINY_BOND,
MoveId.DETECT,
MoveId.DRAGON_TAIL,
MoveId.ENDURE,
MoveId.FEINT,
MoveId.FOCUS_PUNCH,
MoveId.FOLLOW_ME,
MoveId.HELPING_HAND,
MoveId.HOLD_HANDS,
MoveId.KINGS_SHIELD,
MoveId.MAT_BLOCK,
MoveId.ME_FIRST,
MoveId.METRONOME,
MoveId.MIMIC,
MoveId.MIRROR_COAT,
MoveId.MIRROR_MOVE,
MoveId.PROTECT,
MoveId.RAGE_POWDER,
MoveId.ROAR,
MoveId.SHELL_TRAP,
MoveId.SKETCH,
MoveId.SLEEP_TALK,
MoveId.SNATCH,
MoveId.SPIKY_SHIELD,
MoveId.SPOTLIGHT,
MoveId.STRUGGLE,
MoveId.SWITCHEROO,
MoveId.TRANSFORM,
MoveId.TRICK,
MoveId.WHIRLWIND,
]);
export const invalidMirrorMoveMoves: ReadonlySet<Moves> = new Set([
Moves.ACUPRESSURE,
Moves.AFTER_YOU,
Moves.AROMATIC_MIST,
Moves.BEAK_BLAST,
Moves.BELCH,
Moves.CHILLY_RECEPTION,
Moves.COACHING,
Moves.CONVERSION_2,
Moves.COUNTER,
Moves.CRAFTY_SHIELD,
Moves.CURSE,
Moves.DECORATE,
Moves.DOODLE,
Moves.DOOM_DESIRE,
Moves.DRAGON_CHEER,
Moves.ELECTRIC_TERRAIN,
Moves.FINAL_GAMBIT,
Moves.FLORAL_HEALING,
Moves.FLOWER_SHIELD,
Moves.FOCUS_PUNCH,
Moves.FUTURE_SIGHT,
Moves.GEAR_UP,
Moves.GRASSY_TERRAIN,
Moves.GRAVITY,
Moves.GUARD_SPLIT,
Moves.HAIL,
Moves.HAZE,
Moves.HEAL_PULSE,
Moves.HELPING_HAND,
Moves.HOLD_HANDS,
Moves.INSTRUCT,
Moves.ION_DELUGE,
Moves.MAGNETIC_FLUX,
Moves.MAT_BLOCK,
Moves.ME_FIRST,
Moves.MIMIC,
Moves.MIRROR_COAT,
Moves.MIRROR_MOVE,
Moves.MIST,
Moves.MISTY_TERRAIN,
Moves.MUD_SPORT,
Moves.PERISH_SONG,
Moves.POWER_SPLIT,
Moves.PSYCH_UP,
Moves.PSYCHIC_TERRAIN,
Moves.PURIFY,
Moves.QUICK_GUARD,
Moves.RAIN_DANCE,
Moves.REFLECT_TYPE,
Moves.ROLE_PLAY,
Moves.ROTOTILLER,
Moves.SANDSTORM,
Moves.SHELL_TRAP,
Moves.SKETCH,
Moves.SNOWSCAPE,
Moves.SPIT_UP,
Moves.SPOTLIGHT,
Moves.STRUGGLE,
Moves.SUNNY_DAY,
Moves.TEATIME,
Moves.TRANSFORM,
Moves.WATER_SPORT,
Moves.WIDE_GUARD,
export const invalidMirrorMoveMoves: ReadonlySet<MoveId> = new Set([
MoveId.ACUPRESSURE,
MoveId.AFTER_YOU,
MoveId.AROMATIC_MIST,
MoveId.BEAK_BLAST,
MoveId.BELCH,
MoveId.CHILLY_RECEPTION,
MoveId.COACHING,
MoveId.CONVERSION_2,
MoveId.COUNTER,
MoveId.CRAFTY_SHIELD,
MoveId.CURSE,
MoveId.DECORATE,
MoveId.DOODLE,
MoveId.DOOM_DESIRE,
MoveId.DRAGON_CHEER,
MoveId.ELECTRIC_TERRAIN,
MoveId.FINAL_GAMBIT,
MoveId.FLORAL_HEALING,
MoveId.FLOWER_SHIELD,
MoveId.FOCUS_PUNCH,
MoveId.FUTURE_SIGHT,
MoveId.GEAR_UP,
MoveId.GRASSY_TERRAIN,
MoveId.GRAVITY,
MoveId.GUARD_SPLIT,
MoveId.HAIL,
MoveId.HAZE,
MoveId.HEAL_PULSE,
MoveId.HELPING_HAND,
MoveId.HOLD_HANDS,
MoveId.INSTRUCT,
MoveId.ION_DELUGE,
MoveId.MAGNETIC_FLUX,
MoveId.MAT_BLOCK,
MoveId.ME_FIRST,
MoveId.MIMIC,
MoveId.MIRROR_COAT,
MoveId.MIRROR_MOVE,
MoveId.MIST,
MoveId.MISTY_TERRAIN,
MoveId.MUD_SPORT,
MoveId.PERISH_SONG,
MoveId.POWER_SPLIT,
MoveId.PSYCH_UP,
MoveId.PSYCHIC_TERRAIN,
MoveId.PURIFY,
MoveId.QUICK_GUARD,
MoveId.RAIN_DANCE,
MoveId.REFLECT_TYPE,
MoveId.ROLE_PLAY,
MoveId.ROTOTILLER,
MoveId.SANDSTORM,
MoveId.SHELL_TRAP,
MoveId.SKETCH,
MoveId.SNOWSCAPE,
MoveId.SPIT_UP,
MoveId.SPOTLIGHT,
MoveId.STRUGGLE,
MoveId.SUNNY_DAY,
MoveId.TEATIME,
MoveId.TRANSFORM,
MoveId.WATER_SPORT,
MoveId.WIDE_GUARD,
]);
/** 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
*/
export const noAbilityTypeOverrideMoves: ReadonlySet<Moves> = new Set([
Moves.WEATHER_BALL,
Moves.JUDGMENT,
Moves.REVELATION_DANCE,
Moves.MULTI_ATTACK,
Moves.TERRAIN_PULSE,
Moves.NATURAL_GIFT,
Moves.TECHNO_BLAST,
Moves.HIDDEN_POWER,
export const noAbilityTypeOverrideMoves: ReadonlySet<MoveId> = new Set([
MoveId.WEATHER_BALL,
MoveId.JUDGMENT,
MoveId.REVELATION_DANCE,
MoveId.MULTI_ATTACK,
MoveId.TERRAIN_PULSE,
MoveId.NATURAL_GIFT,
MoveId.TECHNO_BLAST,
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 { BerryModifier, PokemonInstantReviveModifier } from "#app/modifier/modifier";
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 { randInt } from "#app/utils/common";
import { BattlerIndex } from "#app/battle";
@ -232,7 +232,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = MysteryEncounterBuilde
isBoss: true,
bossSegments: 3,
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,
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
@ -302,7 +302,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = MysteryEncounterBuilde
encounter.startOfBattleEffects.push({
sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.ENEMY],
move: new PokemonMove(Moves.STUFF_CHEEKS),
move: new PokemonMove(MoveId.STUFF_CHEEKS),
ignorePp: true,
});
@ -375,10 +375,10 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = MysteryEncounterBuilde
const level = getHighestLevelPlayerPokemon(false, true).level - 2;
const greedent = new EnemyPokemon(getPokemonSpecies(Species.GREEDENT), level, TrainerSlot.NONE, false, true);
greedent.moveset = [
new PokemonMove(Moves.THRASH),
new PokemonMove(Moves.BODY_PRESS),
new PokemonMove(Moves.STUFF_CHEEKS),
new PokemonMove(Moves.SLACK_OFF),
new PokemonMove(MoveId.THRASH),
new PokemonMove(MoveId.BODY_PRESS),
new PokemonMove(MoveId.STUFF_CHEEKS),
new PokemonMove(MoveId.SLACK_OFF),
];
greedent.passive = true;

View File

@ -27,7 +27,7 @@ import type Pokemon from "#app/field/pokemon";
import { PokemonMove } from "#app/field/pokemon";
import { getEncounterText, showEncounterDialogue } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
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 { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
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 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 = [
Moves.SILVER_WIND,
Moves.SIGNAL_BEAM,
Moves.BUG_BUZZ,
Moves.POLLEN_PUFF,
Moves.STRUGGLE_BUG,
MoveId.SILVER_WIND,
MoveId.SIGNAL_BEAM,
MoveId.BUG_BUZZ,
MoveId.POLLEN_PUFF,
MoveId.STRUGGLE_BUG,
];
const STATUS_TUTOR_MOVES = [
Moves.STRING_SHOT,
Moves.DEFEND_ORDER,
Moves.RAGE_POWDER,
Moves.STICKY_WEB,
Moves.SILK_TRAP,
MoveId.STRING_SHOT,
MoveId.DEFEND_ORDER,
MoveId.RAGE_POWDER,
MoveId.STICKY_WEB,
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

View File

@ -42,7 +42,7 @@ import { Ability } from "#app/data/abilities/ability-class";
import { BerryModifier } from "#app/modifier/modifier";
import { BerryType } from "#enums/berry-type";
import { BattlerIndex } from "#app/battle";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { EncounterBattleAnim } from "#app/data/battle-anims";
import { MoveCategory } from "#enums/MoveCategory";
import { CustomPokemonData } from "#app/data/custom-pokemon-data";
@ -156,7 +156,7 @@ export const ClowningAroundEncounter: MysteryEncounter = MysteryEncounterBuilder
{
species: getPokemonSpecies(Species.MR_MIME),
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
@ -166,14 +166,14 @@ export const ClowningAroundEncounter: MysteryEncounter = MysteryEncounterBuilder
types: [firstType, secondType],
}),
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,
});
// 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());
@ -208,19 +208,19 @@ export const ClowningAroundEncounter: MysteryEncounter = MysteryEncounterBuilder
// Mr. Mime copies the Blacephalon's random ability
sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.ENEMY_2],
move: new PokemonMove(Moves.ROLE_PLAY),
move: new PokemonMove(MoveId.ROLE_PLAY),
ignorePp: true,
},
{
sourceBattlerIndex: BattlerIndex.ENEMY_2,
targets: [BattlerIndex.PLAYER],
move: new PokemonMove(Moves.TAUNT),
move: new PokemonMove(MoveId.TAUNT),
ignorePp: true,
},
{
sourceBattlerIndex: BattlerIndex.ENEMY_2,
targets: [BattlerIndex.PLAYER_2],
move: new PokemonMove(Moves.TAUNT),
move: new PokemonMove(MoveId.TAUNT),
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 { Biome } from "#enums/biome";
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 { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
@ -130,11 +130,11 @@ export const DancingLessonsEncounter: MysteryEncounter = MysteryEncounterBuilder
const species = getPokemonSpecies(Species.ORICORIO);
const level = getEncounterPokemonLevelForWave(STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER);
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) {
enemyPokemon.moveset.push(new PokemonMove(Moves.REVELATION_DANCE));
enemyPokemon.moveset.push(new PokemonMove(MoveId.REVELATION_DANCE));
} 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({
sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.PLAYER],
move: new PokemonMove(Moves.REVELATION_DANCE),
move: new PokemonMove(MoveId.REVELATION_DANCE),
ignorePp: true,
});
@ -246,7 +246,7 @@ export const DancingLessonsEncounter: MysteryEncounter = MysteryEncounterBuilder
const onPokemonSelected = (pokemon: PlayerPokemon) => {
encounter.setDialogueToken("selectedPokemon", pokemon.getNameToRender());
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

View File

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

View File

@ -1,5 +1,5 @@
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 { MysteryEncounterType } from "#enums/mystery-encounter-type";
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 { PokemonMove } from "#app/field/pokemon";
const OPTION_1_REQUIRED_MOVE = Moves.SURF;
const OPTION_2_REQUIRED_MOVE = Moves.FLY;
const OPTION_1_REQUIRED_MOVE = MoveId.SURF;
const OPTION_2_REQUIRED_MOVE = MoveId.FLY;
/**
* Damage percentage taken when wandering aimlessly.
* 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 { GameOverPhase } from "#app/phases/game-over-phase";
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 { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
@ -89,7 +89,7 @@ export const MysteriousChestEncounter: MysteryEncounter = MysteryEncounterBuilde
species: getPokemonSpecies(Species.GIMMIGHOUL),
formIndex: 0,
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";
import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
import { Nature } from "#enums/nature";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { BattlerIndex } from "#app/battle";
import { AiType, PokemonMove } from "#app/field/pokemon";
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
status: [StatusEffect.SLEEP, 6], // Extra turns on timer for Snorlax's start of fight moves
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: [
{
modifier: generateModifierType(modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType,
@ -106,7 +106,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter = MysteryEncounterBuil
encounter.enemyPartyConfigs = [config];
// Load animations/sfx for Snorlax fight start moves
loadCustomMovesForEncounter([Moves.SNORE]);
loadCustomMovesForEncounter([MoveId.SNORE]);
encounter.setDialogueToken("snorlaxName", getPokemonSpecies(Species.SNORLAX).getName());
@ -133,14 +133,12 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter = MysteryEncounterBuil
guaranteedModifierTypeFuncs: [modifierTypes.LEFTOVERS],
fillRemaining: true,
});
encounter.startOfBattleEffects.push(
{
sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.PLAYER],
move: new PokemonMove(Moves.SNORE),
ignorePp: true,
},
);
encounter.startOfBattleEffects.push({
sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.PLAYER],
move: new PokemonMove(MoveId.SNORE),
ignorePp: true,
});
await initBattleWithEnemyConfig(encounter.enemyPartyConfigs[0]);
},
)

View File

@ -18,7 +18,7 @@ import { Species } from "#enums/species";
import { getPokemonSpecies } from "#app/data/pokemon-species";
import { speciesStarterCosts } from "#app/data/balance/starters";
import { Nature } from "#enums/nature";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import type { PlayerPokemon } from "#app/field/pokemon";
import { getEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
import type { IEggOptions } from "#app/data/egg";
@ -482,7 +482,7 @@ function getPartyConfig(): EnemyPartyConfig {
abilityIndex: 1, // Magic Guard
shiny: false,
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],
tera: PokemonType.FAIRY,
},
@ -502,7 +502,7 @@ function getPartyConfig(): EnemyPartyConfig {
shiny: true,
variant: 1,
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],
},
{
@ -515,7 +515,7 @@ function getPartyConfig(): EnemyPartyConfig {
shiny: true,
variant: 2,
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],
},
);

View File

@ -20,7 +20,7 @@ import type Pokemon from "#app/field/pokemon";
import { PokemonMove } from "#app/field/pokemon";
import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-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 { BattlerTagType } from "#enums/battler-tag-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
customPokemonData: new CustomPokemonData({ spriteScale: 1.25 }),
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: [
{
modifier: generateModifierType(modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType,
@ -126,7 +126,7 @@ export const TheStrongStuffEncounter: MysteryEncounter = MysteryEncounterBuilder
encounter.enemyPartyConfigs = [config];
loadCustomMovesForEncounter([Moves.GASTRO_ACID, Moves.STEALTH_ROCK]);
loadCustomMovesForEncounter([MoveId.GASTRO_ACID, MoveId.STEALTH_ROCK]);
encounter.setDialogueToken("shuckleName", getPokemonSpecies(Species.SHUCKLE).getName());
@ -210,13 +210,13 @@ export const TheStrongStuffEncounter: MysteryEncounter = MysteryEncounterBuilder
{
sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.PLAYER],
move: new PokemonMove(Moves.GASTRO_ACID),
move: new PokemonMove(MoveId.GASTRO_ACID),
ignorePp: true,
},
{
sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.PLAYER],
move: new PokemonMove(Moves.STEALTH_ROCK),
move: new PokemonMove(MoveId.STEALTH_ROCK),
ignorePp: true,
},
);

View File

@ -18,7 +18,7 @@ import { TrainerType } from "#enums/trainer-type";
import { Species } from "#enums/species";
import { AbilityId } from "#enums/ability-id";
import { getPokemonSpecies } from "#app/data/pokemon-species";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Nature } from "#enums/nature";
import { PokemonType } from "#enums/pokemon-type";
import { BerryType } from "#enums/berry-type";
@ -260,7 +260,7 @@ function getVictorTrainerConfig(): EnemyPartyConfig {
isBoss: false,
abilityIndex: 0, // Guts
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: [
{
modifier: generateModifierType(modifierTypes.FLAME_ORB) as PokemonHeldItemModifierType,
@ -278,7 +278,7 @@ function getVictorTrainerConfig(): EnemyPartyConfig {
isBoss: false,
abilityIndex: 1, // Guts
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: [
{
modifier: generateModifierType(modifierTypes.FLAME_ORB) as PokemonHeldItemModifierType,
@ -304,7 +304,7 @@ function getVictoriaTrainerConfig(): EnemyPartyConfig {
isBoss: false,
abilityIndex: 0, // Natural Cure
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: [
{
modifier: generateModifierType(modifierTypes.SOUL_DEW) as PokemonHeldItemModifierType,
@ -322,7 +322,7 @@ function getVictoriaTrainerConfig(): EnemyPartyConfig {
isBoss: false,
formIndex: 1,
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: [
{
modifier: generateModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, [
@ -353,7 +353,7 @@ function getViviTrainerConfig(): EnemyPartyConfig {
isBoss: false,
abilityIndex: 3, // Lightning Rod
nature: Nature.ADAMANT,
moveSet: [Moves.WATERFALL, Moves.MEGAHORN, Moves.KNOCK_OFF, Moves.REST],
moveSet: [MoveId.WATERFALL, MoveId.MEGAHORN, MoveId.KNOCK_OFF, MoveId.REST],
modifierConfigs: [
{
modifier: generateModifierType(modifierTypes.BERRY, [BerryType.LUM]) as PokemonHeldItemModifierType,
@ -372,7 +372,7 @@ function getViviTrainerConfig(): EnemyPartyConfig {
isBoss: false,
abilityIndex: 1, // Poison Heal
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: [
{
modifier: generateModifierType(modifierTypes.BASE_STAT_BOOSTER, [Stat.HP]) as PokemonHeldItemModifierType,
@ -390,7 +390,7 @@ function getViviTrainerConfig(): EnemyPartyConfig {
isBoss: false,
formIndex: 1,
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: [
{
modifier: generateModifierType(modifierTypes.QUICK_CLAW) as PokemonHeldItemModifierType,
@ -412,7 +412,7 @@ function getVickyTrainerConfig(): EnemyPartyConfig {
isBoss: false,
formIndex: 1,
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: [
{
modifier: generateModifierType(modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType,
@ -433,7 +433,7 @@ function getVitoTrainerConfig(): EnemyPartyConfig {
isBoss: false,
abilityIndex: 0, // Soundproof
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: [
{
modifier: generateModifierType(modifierTypes.BASE_STAT_BOOSTER, [Stat.SPD]) as PokemonHeldItemModifierType,
@ -447,7 +447,7 @@ function getVitoTrainerConfig(): EnemyPartyConfig {
isBoss: false,
abilityIndex: 2, // Gluttony
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: [
{
modifier: generateModifierType(modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType,
@ -500,7 +500,7 @@ function getVitoTrainerConfig(): EnemyPartyConfig {
isBoss: false,
abilityIndex: 2, // Tangled Feet
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: [
{
modifier: generateModifierType(modifierTypes.KINGS_ROCK) as PokemonHeldItemModifierType,
@ -514,7 +514,7 @@ function getVitoTrainerConfig(): EnemyPartyConfig {
isBoss: false,
formIndex: 1,
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: [
{
modifier: generateModifierType(modifierTypes.WIDE_LENS) as PokemonHeldItemModifierType,
@ -528,7 +528,7 @@ function getVitoTrainerConfig(): EnemyPartyConfig {
isBoss: false,
abilityIndex: 0, // Sheer Force
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: [
{
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 { ModifierTier } from "#app/modifier/modifier-tier";
import { getPokemonSpecies } from "#app/data/pokemon-species";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { BattlerIndex } from "#app/battle";
import { PokemonMove } from "#app/field/pokemon";
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
formIndex: 1, // Gmax
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: [
{
modifier: generateModifierType(modifierTypes.BERRY) as PokemonHeldItemModifierType,
@ -127,7 +127,7 @@ export const TrashToTreasureEncounter: MysteryEncounter = MysteryEncounterBuilde
encounter.enemyPartyConfigs = [config];
// 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- Venom Drench", "battle_anims", "PRSFX- Venom Drench.wav");
@ -206,13 +206,13 @@ export const TrashToTreasureEncounter: MysteryEncounter = MysteryEncounterBuilde
{
sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.PLAYER],
move: new PokemonMove(Moves.TOXIC),
move: new PokemonMove(MoveId.TOXIC),
ignorePp: true,
},
{
sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.ENEMY],
move: new PokemonMove(Moves.STOCKPILE),
move: new PokemonMove(MoveId.STOCKPILE),
ignorePp: true,
},
);

View File

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

View File

@ -1,5 +1,5 @@
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 Pokemon from "#app/field/pokemon";
import { globalScene } from "#app/global-scene";
@ -300,7 +300,7 @@ export class MysteryEncounterOptionBuilder implements Partial<IMysteryEncounterO
* @param options see {@linkcode CanLearnMoveRequirementOptions}
* @returns
*/
withPokemonCanLearnMoveRequirement(move: Moves | Moves[], options?: CanLearnMoveRequirementOptions) {
withPokemonCanLearnMoveRequirement(move: MoveId | MoveId[], options?: CanLearnMoveRequirementOptions) {
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 { isNullOrUndefined } from "#app/utils/common";
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 { Species } from "#enums/species";
import { SpeciesFormKey } from "#enums/species-form-key";
@ -549,12 +549,17 @@ export class TypeRequirement extends EncounterPokemonRequirement {
}
export class MoveRequirement extends EncounterPokemonRequirement {
requiredMoves: Moves[] = [];
requiredMoves: MoveId[] = [];
minNumberOfPokemon: number;
invertQuery: boolean;
excludeDisallowedPokemon: boolean;
constructor(moves: Moves | Moves[], excludeDisallowedPokemon: boolean, minNumberOfPokemon = 1, invertQuery = false) {
constructor(
moves: MoveId | MoveId[],
excludeDisallowedPokemon: boolean,
minNumberOfPokemon = 1,
invertQuery = false,
) {
super();
this.excludeDisallowedPokemon = excludeDisallowedPokemon;
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.
*/
export class CompatibleMoveRequirement extends EncounterPokemonRequirement {
requiredMoves: Moves[];
requiredMoves: MoveId[];
minNumberOfPokemon: number;
invertQuery: boolean;
constructor(learnableMove: Moves | Moves[], minNumberOfPokemon = 1, invertQuery = false) {
constructor(learnableMove: MoveId | MoveId[], minNumberOfPokemon = 1, invertQuery = false) {
super();
this.minNumberOfPokemon = minNumberOfPokemon;
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),
);
if (includedCompatMoves.length > 0) {
return ["compatibleMove", Moves[includedCompatMoves[0]]];
return ["compatibleMove", MoveId[includedCompatMoves[0]]];
}
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 { PokemonMove } from "#app/field/pokemon";
import { isNullOrUndefined } from "#app/utils/common";
@ -21,13 +21,13 @@ export interface CanLearnMoveRequirementOptions {
* Requires that a pokemon can learn a specific move/moveset.
*/
export class CanLearnMoveRequirement extends EncounterPokemonRequirement {
private readonly requiredMoves: Moves[];
private readonly requiredMoves: MoveId[];
private readonly excludeLevelMoves?: boolean;
private readonly excludeTmMoves?: boolean;
private readonly excludeEggMoves?: boolean;
private readonly includeFainted?: boolean;
constructor(requiredMoves: Moves | Moves[], options: CanLearnMoveRequirementOptions = {}) {
constructor(requiredMoves: MoveId | MoveId[], options: CanLearnMoveRequirementOptions = {}) {
super();
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(", ")];
}
private getPokemonLevelMoves(pkm: PlayerPokemon): Moves[] {
private getPokemonLevelMoves(pkm: PlayerPokemon): MoveId[] {
return pkm.getLevelMoves().map(([_level, move]) => move);
}
private getAllPokemonMoves(pkm: PlayerPokemon): Moves[] {
const allPokemonMoves: Moves[] = [];
private getAllPokemonMoves(pkm: PlayerPokemon): MoveId[] {
const allPokemonMoves: MoveId[] = [];
if (!this.excludeLevelMoves) {
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";
/**
* 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
*/
export const CHARMING_MOVES = [
Moves.CHARM,
Moves.FLATTER,
Moves.DRAGON_CHEER,
Moves.ALLURING_VOICE,
Moves.ATTRACT,
Moves.SWEET_SCENT,
Moves.CAPTIVATE,
Moves.AROMATIC_MIST,
MoveId.CHARM,
MoveId.FLATTER,
MoveId.DRAGON_CHEER,
MoveId.ALLURING_VOICE,
MoveId.ATTRACT,
MoveId.SWEET_SCENT,
MoveId.CAPTIVATE,
MoveId.AROMATIC_MIST,
];
/**
* Moves for the Dancer ability
*/
export const DANCING_MOVES = [
Moves.AQUA_STEP,
Moves.CLANGOROUS_SOUL,
Moves.DRAGON_DANCE,
Moves.FEATHER_DANCE,
Moves.FIERY_DANCE,
Moves.LUNAR_DANCE,
Moves.PETAL_DANCE,
Moves.REVELATION_DANCE,
Moves.QUIVER_DANCE,
Moves.SWORDS_DANCE,
Moves.TEETER_DANCE,
Moves.VICTORY_DANCE,
MoveId.AQUA_STEP,
MoveId.CLANGOROUS_SOUL,
MoveId.DRAGON_DANCE,
MoveId.FEATHER_DANCE,
MoveId.FIERY_DANCE,
MoveId.LUNAR_DANCE,
MoveId.PETAL_DANCE,
MoveId.REVELATION_DANCE,
MoveId.QUIVER_DANCE,
MoveId.SWORDS_DANCE,
MoveId.TEETER_DANCE,
MoveId.VICTORY_DANCE,
];
/**
* Moves that can distract someone/something
*/
export const DISTRACTION_MOVES = [
Moves.FAKE_OUT,
Moves.FOLLOW_ME,
Moves.TAUNT,
Moves.ROAR,
Moves.TELEPORT,
Moves.CHARM,
Moves.FAKE_TEARS,
Moves.TICKLE,
Moves.CAPTIVATE,
Moves.RAGE_POWDER,
Moves.SUBSTITUTE,
Moves.SHED_TAIL,
MoveId.FAKE_OUT,
MoveId.FOLLOW_ME,
MoveId.TAUNT,
MoveId.ROAR,
MoveId.TELEPORT,
MoveId.CHARM,
MoveId.FAKE_TEARS,
MoveId.TICKLE,
MoveId.CAPTIVATE,
MoveId.RAGE_POWDER,
MoveId.SUBSTITUTE,
MoveId.SHED_TAIL,
];
/**
* Moves that protect in some way
*/
export const PROTECTING_MOVES = [
Moves.PROTECT,
Moves.WIDE_GUARD,
Moves.MAX_GUARD,
Moves.SAFEGUARD,
Moves.REFLECT,
Moves.BARRIER,
Moves.QUICK_GUARD,
Moves.FLOWER_SHIELD,
Moves.KINGS_SHIELD,
Moves.CRAFTY_SHIELD,
Moves.SPIKY_SHIELD,
Moves.OBSTRUCT,
Moves.DETECT,
MoveId.PROTECT,
MoveId.WIDE_GUARD,
MoveId.MAX_GUARD,
MoveId.SAFEGUARD,
MoveId.REFLECT,
MoveId.BARRIER,
MoveId.QUICK_GUARD,
MoveId.FLOWER_SHIELD,
MoveId.KINGS_SHIELD,
MoveId.CRAFTY_SHIELD,
MoveId.SPIKY_SHIELD,
MoveId.OBSTRUCT,
MoveId.DETECT,
];
/**
* Moves that (loosely) can be used to trap/rob someone
*/
export const EXTORTION_MOVES = [
Moves.BIND,
Moves.CLAMP,
Moves.INFESTATION,
Moves.SAND_TOMB,
Moves.SNAP_TRAP,
Moves.THUNDER_CAGE,
Moves.WRAP,
Moves.SPIRIT_SHACKLE,
Moves.MEAN_LOOK,
Moves.JAW_LOCK,
Moves.BLOCK,
Moves.SPIDER_WEB,
Moves.ANCHOR_SHOT,
Moves.OCTOLOCK,
Moves.PURSUIT,
Moves.CONSTRICT,
Moves.BEAT_UP,
Moves.COIL,
Moves.WRING_OUT,
Moves.STRING_SHOT,
MoveId.BIND,
MoveId.CLAMP,
MoveId.INFESTATION,
MoveId.SAND_TOMB,
MoveId.SNAP_TRAP,
MoveId.THUNDER_CAGE,
MoveId.WRAP,
MoveId.SPIRIT_SHACKLE,
MoveId.MEAN_LOOK,
MoveId.JAW_LOCK,
MoveId.BLOCK,
MoveId.SPIDER_WEB,
MoveId.ANCHOR_SHOT,
MoveId.OCTOLOCK,
MoveId.PURSUIT,
MoveId.CONSTRICT,
MoveId.BEAT_UP,
MoveId.COIL,
MoveId.WRING_OUT,
MoveId.STRING_SHOT,
];
/**

View File

@ -39,7 +39,7 @@ import i18next from "i18next";
import Trainer, { TrainerVariant } from "#app/field/trainer";
import type { Gender } from "#app/data/gender";
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 { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
import { Status } from "#app/data/status-effect";
@ -106,7 +106,7 @@ export interface EnemyPokemonConfig {
level?: number;
gender?: Gender;
passive?: boolean;
moveSet?: Moves[];
moveSet?: MoveId[];
nature?: Nature;
ivs?: [number, number, number, number, number, number];
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)
* @param moves
*/
export function loadCustomMovesForEncounter(moves: Moves | Moves[]) {
export function loadCustomMovesForEncounter(moves: MoveId | MoveId[]) {
moves = Array.isArray(moves) ? moves : [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 type { Constructor, nil } from "#app/utils/common";
import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import type { TimeOfDay } from "#enums/time-of-day";
import { getPokemonNameWithAffix } from "#app/messages";
@ -341,14 +341,14 @@ export class SpeciesFormChangeStatusEffectTrigger extends SpeciesFormChangeTrigg
}
export class SpeciesFormChangeMoveLearnedTrigger extends SpeciesFormChangeTrigger {
public move: Moves;
public move: MoveId;
public known: boolean;
constructor(move: Moves, known = true) {
constructor(move: MoveId, known = true) {
super();
this.move = move;
this.known = known;
const moveKey = Moves[this.move]
const moveKey = MoveId[this.move]
.split("_")
.filter(f => f)
.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 {
public movePredicate: (m: Moves) => boolean;
public movePredicate: (m: MoveId) => boolean;
public used: boolean;
constructor(move: Moves | ((m: Moves) => boolean), used = true) {
constructor(move: MoveId | ((m: MoveId) => boolean), used = true) {
super();
this.movePredicate = typeof move === "function" ? move : (m: Moves) => m === move;
this.movePredicate = typeof move === "function" ? move : (m: MoveId) => m === move;
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))
],
[Species.KELDEO]: [
new SpeciesFormChange(Species.KELDEO, "ordinary", "resolute", new SpeciesFormChangeMoveLearnedTrigger(Moves.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, "ordinary", "resolute", new SpeciesFormChangeMoveLearnedTrigger(MoveId.SECRET_SWORD), 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]: [
new SpeciesFormChange(Species.MELOETTA, "aria", "pirouette", new MeloettaFormChangePostMoveTrigger(Moves.RELIC_SONG), true),
new SpeciesFormChange(Species.MELOETTA, "pirouette", "aria", 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(MoveId.RELIC_SONG), true)
],
[Species.GENESECT]: [
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)
],
[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, "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 { PokeballType } from "#enums/pokeball";
import { PokemonType } from "#enums/pokemon-type";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { AbilityId } from "#enums/ability-id";
import { TeraAIMode } from "#enums/tera-ai-mode";
import { TrainerPoolTier } from "#enums/trainer-pool-tier";
@ -1127,7 +1127,7 @@ export const trainerConfigs: TrainerConfigs = {
s
.getLevelMoves()
.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
[TrainerType.BEAUTY]: new TrainerConfig(++t)
@ -1333,11 +1333,11 @@ export const trainerConfigs: TrainerConfigs = {
.setHasDouble("Medical Team")
.setMoneyMultiplier(3)
.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)
.setMoneyMultiplier(1.4)
.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)
.setMoneyMultiplier(1.25)
.setEncounterBgm(TrainerType.BACKPACKER)
@ -1394,7 +1394,7 @@ export const trainerConfigs: TrainerConfigs = {
.setSpeciesFilter(s => s.isOfType(PokemonType.ELECTRIC)),
[TrainerType.HARLEQUIN]: new TrainerConfig(++t)
.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)
.setEncounterBgm(TrainerType.BACKPACKER)
.setPartyTemplates(
@ -1466,7 +1466,7 @@ export const trainerConfigs: TrainerConfigs = {
trainerPartyTemplates.TWO_WEAK_ONE_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)
.setMoneyMultiplier(1.5)
.setEncounterBgm(TrainerType.PSYCHIC)
@ -1527,7 +1527,7 @@ export const trainerConfigs: TrainerConfigs = {
AbilityId.DRY_SKIN,
AbilityId.WIND_POWER,
].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
[TrainerType.PILOT]: new TrainerConfig(++t)
.setMoneyMultiplier(1.75)
@ -1538,7 +1538,7 @@ export const trainerConfigs: TrainerConfigs = {
trainerPartyTemplates.TWO_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)
.setMoneyMultiplier(1.4)
.setName("PokéFan")
@ -1554,7 +1554,7 @@ export const trainerConfigs: TrainerConfigs = {
trainerPartyTemplates.FIVE_WEAK,
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)
.setMoneyMultiplier(0.2)
.setEncounterBgm(TrainerType.YOUNGSTER)
@ -2490,10 +2490,10 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.REVAVROOM], TrainerSlot.TRAINER, true, p => {
p.formIndex = 1; // Segin Starmobile
p.moveset = [
new PokemonMove(Moves.WICKED_TORQUE),
new PokemonMove(Moves.SPIN_OUT),
new PokemonMove(Moves.SHIFT_GEAR),
new PokemonMove(Moves.HIGH_HORSEPOWER),
new PokemonMove(MoveId.WICKED_TORQUE),
new PokemonMove(MoveId.SPIN_OUT),
new PokemonMove(MoveId.SHIFT_GEAR),
new PokemonMove(MoveId.HIGH_HORSEPOWER),
];
}),
),
@ -2510,10 +2510,10 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.REVAVROOM], TrainerSlot.TRAINER, true, p => {
p.formIndex = 2; // Schedar Starmobile
p.moveset = [
new PokemonMove(Moves.BLAZING_TORQUE),
new PokemonMove(Moves.SPIN_OUT),
new PokemonMove(Moves.SHIFT_GEAR),
new PokemonMove(Moves.HIGH_HORSEPOWER),
new PokemonMove(MoveId.BLAZING_TORQUE),
new PokemonMove(MoveId.SPIN_OUT),
new PokemonMove(MoveId.SHIFT_GEAR),
new PokemonMove(MoveId.HIGH_HORSEPOWER),
];
}),
),
@ -2530,10 +2530,10 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.REVAVROOM], TrainerSlot.TRAINER, true, p => {
p.formIndex = 3; // Navi Starmobile
p.moveset = [
new PokemonMove(Moves.NOXIOUS_TORQUE),
new PokemonMove(Moves.SPIN_OUT),
new PokemonMove(Moves.SHIFT_GEAR),
new PokemonMove(Moves.HIGH_HORSEPOWER),
new PokemonMove(MoveId.NOXIOUS_TORQUE),
new PokemonMove(MoveId.SPIN_OUT),
new PokemonMove(MoveId.SHIFT_GEAR),
new PokemonMove(MoveId.HIGH_HORSEPOWER),
];
}),
),
@ -2550,10 +2550,10 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.REVAVROOM], TrainerSlot.TRAINER, true, p => {
p.formIndex = 4; // Ruchbah Starmobile
p.moveset = [
new PokemonMove(Moves.MAGICAL_TORQUE),
new PokemonMove(Moves.SPIN_OUT),
new PokemonMove(Moves.SHIFT_GEAR),
new PokemonMove(Moves.HIGH_HORSEPOWER),
new PokemonMove(MoveId.MAGICAL_TORQUE),
new PokemonMove(MoveId.SPIN_OUT),
new PokemonMove(MoveId.SHIFT_GEAR),
new PokemonMove(MoveId.HIGH_HORSEPOWER),
];
}),
),
@ -2570,10 +2570,10 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.REVAVROOM], TrainerSlot.TRAINER, true, p => {
p.formIndex = 5; // Caph Starmobile
p.moveset = [
new PokemonMove(Moves.COMBAT_TORQUE),
new PokemonMove(Moves.SPIN_OUT),
new PokemonMove(Moves.SHIFT_GEAR),
new PokemonMove(Moves.HIGH_HORSEPOWER),
new PokemonMove(MoveId.COMBAT_TORQUE),
new PokemonMove(MoveId.SPIN_OUT),
new PokemonMove(MoveId.SHIFT_GEAR),
new PokemonMove(MoveId.HIGH_HORSEPOWER),
];
}),
),
@ -2868,9 +2868,9 @@ export const trainerConfigs: TrainerConfigs = {
getRandomPartyMemberFunc([Species.SLOWBRO, Species.GALAR_SLOWBRO], TrainerSlot.TRAINER, true, p => {
// Tera Ice Slowbro/G-Slowbro
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.
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 => {
// Tera Fighting Steelix
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.
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 => {
// Tera Ghost Arbok/Weezing
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.
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 => {
// Tera Dragon Gyarados/Aerodactyl
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.
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 => {
// Tera Dark Gengar
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.
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 => {
// Tera Dragon Dhelmise
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.
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.abilityIndex = 1; // Sniper
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.
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 => {
// Tera Fire Steelix/Lopunny
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.
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 => {
// Tera Steel Ceruledge
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.
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 => {
// Tera Fighting Incineroar
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.
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 => {
// Tera Flying Decidueye
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.
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 => {
// Tera Dark Toxicroak
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.
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 => {
// Tera Water Eiscue
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.
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
p.abilityIndex = 1; // Drought
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.
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 => {
// Tera Fire Exeggutor
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.
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,
getRandomPartyMemberFunc([Species.TALONFLAME], TrainerSlot.TRAINER, true, p => {
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.
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 => {
// Tera Steel Reuniclus
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.
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
p.setBoss(true, 2);
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.
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 => {
// Tera Dragon Sceptile
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.
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,
getRandomPartyMemberFunc([Species.KINGAMBIT], TrainerSlot.TRAINER, true, p => {
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.
p.moveset[2] = new PokemonMove(Moves.TERA_BLAST);
p.moveset[2] = new PokemonMove(MoveId.TERA_BLAST);
}
p.abilityIndex = 1; // Supreme Overlord
p.teraType = PokemonType.FLYING;
@ -4367,9 +4367,9 @@ export const trainerConfigs: TrainerConfigs = {
p.formIndex = randSeedInt(4); // Random Ogerpon Tera Mask
p.generateAndPopulateMoveset();
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.
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.generateAndPopulateMoveset();
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.
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.pokeball = PokeballType.ULTRA_BALL;
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.
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} */
NONE,
/**{@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 type { ArenaTagType } from "#enums/arena-tag-type";
import { Biome } from "#enums/biome";
import type { Moves } from "#enums/moves";
import type { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import { TimeOfDay } from "#enums/time-of-day";
import { TrainerType } from "#enums/trainer-type";
@ -674,7 +674,7 @@ export class Arena {
* Adds a new tag to the arena
* @param tagType {@linkcode ArenaTagType} the tag being added
* @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 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
@ -684,7 +684,7 @@ export class Arena {
addTag(
tagType: ArenaTagType,
turnCount: number,
sourceMove: Moves | undefined,
sourceMove: MoveId | undefined,
sourceId: number,
side: ArenaTagSide = ArenaTagSide.BOTH,
quiet = false,

View File

@ -226,7 +226,7 @@ import { BattleSpec } from "#enums/battle-spec";
import { BattlerTagType } from "#enums/battler-tag-type";
import type { BerryType } from "#enums/berry-type";
import { Biome } from "#enums/biome";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import { getPokemonNameWithAffix } from "#app/messages";
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 maskSprite: Phaser.GameObjects.Sprite | null;
public usedTMs: Moves[];
public usedTMs: MoveId[];
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}.
* @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`.
* @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;
// 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.OPP_MOVESET_OVERRIDE;
if (!Array.isArray(overrideArray)) {
@ -1858,7 +1858,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (!this.isPlayer()) {
this.moveset = [];
}
overrideArray.forEach((move: Moves, index: number) => {
overrideArray.forEach((move: MoveId, index: number) => {
const ppUsed = this.moveset[index]?.ppUsed ?? 0;
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
* 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.
* @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.
*/
getUnlockedEggMoves(): Moves[] {
const moves: Moves[] = [];
getUnlockedEggMoves(): MoveId[] {
const moves: MoveId[] = [];
const species =
this.metSpecies in speciesEggMoves ? this.metSpecies : this.getSpeciesForm(true).getRootSpeciesId(true);
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
* 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}.
*/
public getLearnableLevelMoves(): Moves[] {
public getLearnableLevelMoves(): MoveId[] {
let levelMoves = this.getLevelMoves(1, true, false, true).map(lm => lm[1]);
if (this.metBiome === -1 && !globalScene.gameMode.isFreshStartChallenge() && !globalScene.gameMode.isDaily) {
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
if (
this.isTerastallized &&
(move.id === Moves.TERA_BLAST ||
(move.id === Moves.TERA_STARSTORM && moveTypeHolder.value === PokemonType.STELLAR))
(move.id === MoveId.TERA_BLAST ||
(move.id === MoveId.TERA_STARSTORM && moveTypeHolder.value === PokemonType.STELLAR))
) {
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.
*/
private getUniqueMoves(levelMoves: LevelMoves, ret: LevelMoves): void {
const uniqueMoves: Moves[] = [];
const uniqueMoves: MoveId[] = [];
for (const lm of levelMoves) {
if (!uniqueMoves.find(m => m === lm[1])) {
uniqueMoves.push(lm[1]);
@ -2794,12 +2794,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
*
* @returns list of egg moves
*/
getEggMoves(): Moves[] | undefined {
getEggMoves(): MoveId[] | undefined {
return speciesEggMoves[this.getSpeciesForm().getRootSpeciesId()];
}
setMove(moveIndex: number, moveId: Moves): void {
if (moveId === Moves.NONE) {
setMove(moveIndex: number, moveId: MoveId): void {
if (moveId === MoveId.NONE) {
return;
}
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 */
public generateAndPopulateMoveset(): void {
this.moveset = [];
let movePool: [Moves, number][] = [];
let movePool: [MoveId, number][] = [];
const allLevelMoves = this.getLevelMoves(1, true, true);
if (!allLevelMoves) {
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()) {
const tms = Object.keys(tmSpecies);
for (const tm of tms) {
const moveId = Number.parseInt(tm) as Moves;
const moveId = Number.parseInt(tm) as MoveId;
let compatible = false;
for (const p of tmSpecies[tm]) {
if (Array.isArray(p)) {
@ -3202,7 +3202,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (this.isBoss()) {
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
const stabMovePool = baseWeights.filter(
@ -3724,7 +3727,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (cancelled.value || isTypeImmune) {
return {
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,
};
}
@ -4131,7 +4134,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
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);
if (existingTag) {
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.
*
* @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`
*
* @see {@linkcode MoveRestrictionBattlerTag}
*/
public isMoveRestricted(moveId: Moves, pokemon?: Pokemon): boolean {
public isMoveRestricted(moveId: MoveId, pokemon?: Pokemon): boolean {
return this.getRestrictingTag(moveId, pokemon) !== null;
}
/**
* 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 target - The target of the move
*
@ -4320,7 +4323,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
*
* @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)) {
if ((tag as MoveRestrictionBattlerTag).isMoveTargetRestricted(moveId, user, target)) {
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.
*
* @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 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.
*/
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)) {
if ((tag as MoveRestrictionBattlerTag).isMoveRestricted(moveId, user)) {
return tag as MoveRestrictionBattlerTag;
@ -5509,7 +5512,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
export class PlayerPokemon extends Pokemon {
protected battleInfo: PlayerBattleInfo;
public compatibleTms: Moves[];
public compatibleTms: MoveId[];
constructor(
species: PokemonSpecies,
@ -5580,7 +5583,7 @@ export class PlayerPokemon extends Pokemon {
const tms = Object.keys(tmSpecies);
for (const tm of tms) {
const moveId = Number.parseInt(tm) as Moves;
const moveId = Number.parseInt(tm) as MoveId;
let compatible = false;
for (const p of tmSpecies[tm]) {
if (Array.isArray(p)) {
@ -6166,28 +6169,28 @@ export class EnemyPokemon extends Pokemon {
switch (true) {
case this.species.speciesId === Species.SMEARGLE:
this.moveset = [
new PokemonMove(Moves.SKETCH),
new PokemonMove(Moves.SKETCH),
new PokemonMove(Moves.SKETCH),
new PokemonMove(Moves.SKETCH),
new PokemonMove(MoveId.SKETCH),
new PokemonMove(MoveId.SKETCH),
new PokemonMove(MoveId.SKETCH),
new PokemonMove(MoveId.SKETCH),
];
break;
case this.species.speciesId === Species.ETERNATUS:
this.moveset = (formIndex !== undefined ? formIndex : this.formIndex)
? [
new PokemonMove(Moves.DYNAMAX_CANNON),
new PokemonMove(Moves.CROSS_POISON),
new PokemonMove(Moves.FLAMETHROWER),
new PokemonMove(Moves.RECOVER, 0, -4),
new PokemonMove(MoveId.DYNAMAX_CANNON),
new PokemonMove(MoveId.CROSS_POISON),
new PokemonMove(MoveId.FLAMETHROWER),
new PokemonMove(MoveId.RECOVER, 0, -4),
]
: [
new PokemonMove(Moves.ETERNABEAM),
new PokemonMove(Moves.SLUDGE_BOMB),
new PokemonMove(Moves.FLAMETHROWER),
new PokemonMove(Moves.COSMIC_POWER),
new PokemonMove(MoveId.ETERNABEAM),
new PokemonMove(MoveId.SLUDGE_BOMB),
new PokemonMove(MoveId.FLAMETHROWER),
new PokemonMove(MoveId.COSMIC_POWER),
];
if (globalScene.gameMode.hasChallenge(Challenges.INVERSE_BATTLE)) {
this.moveset[2] = new PokemonMove(Moves.THUNDERBOLT);
this.moveset[2] = new PokemonMove(MoveId.THUNDERBOLT);
}
break;
default:
@ -6273,7 +6276,7 @@ export class EnemyPokemon extends Pokemon {
moveTargets.some(p => {
const doesNotFail =
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 (
doesNotFail &&
p.getAttackDamage({
@ -6332,7 +6335,7 @@ export class EnemyPokemon extends Pokemon {
*/
if (
(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;
} else if (move instanceof AttackMove) {
@ -6417,17 +6420,17 @@ export class EnemyPokemon extends Pokemon {
}
return {
move: Moves.STRUGGLE,
targets: this.getNextTargets(Moves.STRUGGLE),
move: MoveId.STRUGGLE,
targets: this.getNextTargets(MoveId.STRUGGLE),
};
}
/**
* 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
*/
getNextTargets(moveId: Moves): BattlerIndex[] {
getNextTargets(moveId: MoveId): BattlerIndex[] {
const moveTargets = getMoveTargets(this, moveId);
const targets = globalScene.getField(true).filter(p => moveTargets.targets.indexOf(p.getBattlerIndex()) > -1);
// If the move is multi-target, return all targets' indexes
@ -6752,7 +6755,7 @@ interface IllusionData {
}
export interface TurnMove {
move: Moves;
move: MoveId;
targets: BattlerIndex[];
result?: MoveResult;
virtual?: boolean;
@ -6761,7 +6764,7 @@ export interface TurnMove {
}
export interface AttackMoveResult {
move: Moves;
move: MoveId;
result: DamageResult;
damage: number;
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.
* 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;
}
@ -6858,9 +6861,9 @@ export class PokemonTempSummonData {
* Resets at the start of a new battle (but not on switch).
*/
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;
/** 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;
/** Array containing all berries eaten and not yet recovered during this current battle; used by {@linkcode AbilityId.HARVEST} */
public berriesEaten: BerryType[] = [];
@ -6912,7 +6915,7 @@ export class PokemonTurnData {
public statStagesIncreased = false;
public statStagesDecreased = false;
public moveEffectiveness: TypeDamageMultiplier | null = null;
public combiningPledge?: Moves;
public combiningPledge?: MoveId;
public switchedInThisTurn = false;
public failedRunAway = false;
public joinedRound = false;
@ -6992,7 +6995,7 @@ export interface DamageCalculationResult {
* @see {@linkcode getName} - returns name of {@linkcode Move}.
**/
export class PokemonMove {
public moveId: Moves;
public moveId: MoveId;
public ppUsed: number;
public ppUp: number;
public virtual: boolean;
@ -7003,7 +7006,7 @@ export class PokemonMove {
*/
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.ppUsed = ppUsed;
this.ppUp = ppUp;

View File

@ -119,7 +119,7 @@ import {
import { AbilityId } from "#enums/ability-id";
import { BattlerTagType } from "#enums/battler-tag-type";
import { BerryType } from "#enums/berry-type";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Nature } from "#enums/nature";
import { PokeballType } from "#enums/pokeball";
import { Species } from "#enums/species";
@ -1165,9 +1165,9 @@ export class PokemonMultiHitModifierType extends PokemonHeldItemModifierType {
}
export class TmModifierType extends PokemonModifierType {
public moveId: Moves;
public moveId: MoveId;
constructor(moveId: Moves) {
constructor(moveId: MoveId) {
super(
"",
`tm_${PokemonType[allMoves[moveId].type].toLowerCase()}`,
@ -1553,8 +1553,8 @@ class SpeciesStatBoosterModifierTypeGenerator extends ModifierTypeGenerator {
class TmModifierTypeGenerator extends ModifierTypeGenerator {
constructor(tier: ModifierTier) {
super((party: Pokemon[], pregenArgs?: any[]) => {
if (pregenArgs && pregenArgs.length === 1 && pregenArgs[0] in Moves) {
return new TmModifierType(pregenArgs[0] as Moves);
if (pregenArgs && pregenArgs.length === 1 && pregenArgs[0] in MoveId) {
return new TmModifierType(pregenArgs[0] as MoveId);
}
const partyMemberCompatibleTms = party.map(p => {
const previousLevelMoves = p.getLearnableLevelMoves();
@ -1904,7 +1904,7 @@ export type GeneratorModifierOverride = {
}
| {
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);
// 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
// TODO: Take moves (Trick, Fling, Switcheroo) from comment when they are implemented
const hasItemMoves = [
@ -2817,7 +2817,7 @@ const modifierPool: ModifierPool = {
const canSetStatus = p.canSetStatus(StatusEffect.BURN, true, true, null, true);
// 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
// TODO: Take moves (Trick, Fling, Switcheroo) from comment when they are implemented
const hasItemMoves = [
@ -2880,16 +2880,16 @@ const modifierPool: ModifierPool = {
].some(a => p.hasAbility(a, false, true));
const hasMoves = [
Moves.SUNNY_DAY,
Moves.RAIN_DANCE,
Moves.SANDSTORM,
Moves.SNOWSCAPE,
Moves.HAIL,
Moves.CHILLY_RECEPTION,
Moves.ELECTRIC_TERRAIN,
Moves.PSYCHIC_TERRAIN,
Moves.GRASSY_TERRAIN,
Moves.MISTY_TERRAIN,
MoveId.SUNNY_DAY,
MoveId.RAIN_DANCE,
MoveId.SANDSTORM,
MoveId.SNOWSCAPE,
MoveId.HAIL,
MoveId.CHILLY_RECEPTION,
MoveId.ELECTRIC_TERRAIN,
MoveId.PSYCHIC_TERRAIN,
MoveId.GRASSY_TERRAIN,
MoveId.MISTY_TERRAIN,
].some(m => moveset.includes(m));
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 { BattlerTagType } from "#enums/battler-tag-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 { PokeballType } from "#enums/pokeball";
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.
* @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 damageMultiplier {@linkcode NumberHolder} holding a damage multiplier applied to a strike of this move
* @returns always `true`
*/
override apply(
pokemon: Pokemon,
moveId: Moves,
moveId: MoveId,
count: NumberHolder | null = null,
damageMultiplier: NumberHolder | null = null,
): boolean {

View File

@ -10,7 +10,7 @@ import { BattleType } from "#enums/battle-type";
import { BerryType } from "#enums/berry-type";
import { Biome } from "#enums/biome";
import { EggTier } from "#enums/egg-type";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { PokeballType } from "#enums/pokeball";
@ -152,7 +152,7 @@ class DefaultOverrides {
readonly HAS_PASSIVE_ABILITY_OVERRIDE: boolean | null = null;
readonly STATUS_OVERRIDE: StatusEffect = StatusEffect.NONE;
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 VARIANT_OVERRIDE: Variant | null = null;
@ -174,7 +174,7 @@ class DefaultOverrides {
readonly OPP_HAS_PASSIVE_ABILITY_OVERRIDE: boolean | null = null;
readonly OPP_STATUS_OVERRIDE: StatusEffect = StatusEffect.NONE;
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_VARIANT_OVERRIDE: Variant | null = null;
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 { BattlerTagType } from "#app/enums/battler-tag-type";
import { Biome } from "#app/enums/biome";
import { Moves } from "#app/enums/moves";
import { MoveId } from "#app/enums/moves";
import { PokeballType } from "#enums/pokeball";
import type { PlayerPokemon, TurnMove } from "#app/field/pokemon";
import { FieldPosition } from "#app/field/pokemon";
@ -80,7 +80,7 @@ export class CommandPhase extends FieldPhase {
) {
globalScene.currentBattle.turnCommands[this.fieldIndex] = {
command: Command.FIGHT,
move: { move: Moves.NONE, targets: [] },
move: { move: MoveId.NONE, targets: [] },
skip: true,
};
}
@ -157,15 +157,15 @@ export class CommandPhase extends FieldPhase {
playerPokemon.trySelectMove(cursor, args[0] as boolean) ||
(useStruggle = cursor > -1 && !playerPokemon.getMoveset().filter(m => m.isUsable(playerPokemon)).length)
) {
let moveId: Moves;
let moveId: MoveId;
if (useStruggle) {
moveId = Moves.STRUGGLE;
moveId = MoveId.STRUGGLE;
} else if (turnMove !== undefined) {
moveId = turnMove.move;
} else if (cursor > -1) {
moveId = playerPokemon.getMoveset()[cursor].moveId;
} else {
moveId = Moves.NONE;
moveId = MoveId.NONE;
}
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 { allMoves } from "#app/data/data-lists";
import { SpeciesFormChangeMoveLearnedTrigger } from "#app/data/pokemon-forms";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { getPokemonNameWithAffix } from "#app/messages";
import Overrides from "#app/overrides";
import EvolutionSceneHandler from "#app/ui/evolution-scene-handler";
@ -24,14 +24,14 @@ export enum LearnMoveType {
}
export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
private moveId: Moves;
private moveId: MoveId;
private messageMode: UiMode;
private learnMoveType: LearnMoveType;
private cost: number;
constructor(
partyMemberIndex: number,
moveId: Moves,
moveId: MoveId,
learnMoveType: LearnMoveType = LearnMoveType.LEARN_MOVE,
cost = -1,
) {
@ -49,7 +49,7 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
const currentMoveset = pokemon.getMoveset();
// 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) {
return this.end();
}

View File

@ -1,5 +1,5 @@
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";
/**
@ -8,7 +8,7 @@ import { Phase } from "#app/phase";
* isn't already loaded (e.g. for Metronome)
*/
export class LoadMoveAnimPhase extends Phase {
constructor(protected moveId: Moves) {
constructor(protected moveId: MoveId) {
super();
}

View File

@ -48,7 +48,7 @@ import { MoveTarget } from "#enums/MoveTarget";
import { MoveCategory } from "#enums/MoveCategory";
import { SpeciesFormChangePostMoveTrigger } from "#app/data/pokemon-forms";
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 { HitResult, MoveResult } from "#app/field/pokemon";
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 type { nil } from "#app/utils/common";
import { BattlerTagType } from "#enums/battler-tag-type";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import i18next from "i18next";
import type { Phase } from "#app/phase";
import { ShowAbilityPhase } from "./show-ability-phase";
import { MovePhase } from "./move-phase";
import { MoveEndPhase } from "./move-end-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 type Move from "#app/data/moves/move";
import { isFieldTargeted } from "#app/data/moves/move-utils";
@ -220,7 +220,7 @@ export class MoveEffectPhase extends PokemonPhase {
break;
case HitCheckResult.NO_EFFECT:
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),
}),
);
@ -351,7 +351,7 @@ export class MoveEffectPhase extends PokemonPhase {
) {
const firstTarget = this.getFirstTarget();
new MoveAnim(
move.id as Moves,
move.id as MoveId,
user,
firstTarget?.getBattlerIndex() ?? BattlerIndex.ATTACKER,
// 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:
* - An ability like {@linkcode Abilities.NO_GUARD | No Guard}
* - A poison type using {@linkcode Moves.TOXIC | Toxic}
* - A move like {@linkcode Moves.LOCK_ON | Lock-On} or {@linkcode Moves.MIND_READER | Mind Reader}.
* - A poison type using {@linkcode MoveId.TOXIC | Toxic}
* - A move like {@linkcode MoveId.LOCK_ON | Lock-On} or {@linkcode MoveId.MIND_READER | Mind Reader}.
* - 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,
* (which should not bypass the accuracy check).
*
@ -809,7 +809,7 @@ export class MoveEffectPhase extends PokemonPhase {
*/
applyMoveAttrs(StatChangeBeforeDmgCalcAttr, user, target, this.move);
const { result: result, damage: dmg } = target.getAttackDamage({
const { result, damage: dmg } = target.getAttackDamage({
source: user,
move: this.move,
ignoreAbility: false,

View File

@ -47,7 +47,7 @@ import { NumberHolder } from "#app/utils/common";
import { AbilityId } from "#enums/ability-id";
import { ArenaTagType } from "#enums/arena-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 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
* Needed for speed order, see {@linkcode Moves.QUASH}
* Needed for speed order, see {@linkcode MoveId.QUASH}
* */
public isForcedLast(): boolean {
return this.forcedLast;
@ -147,7 +147,7 @@ export class MovePhase extends BattlePhase {
public start(): void {
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).
if (!this.canMove(true)) {
@ -201,14 +201,14 @@ export class MovePhase extends BattlePhase {
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 {
const targets = this.getActiveTargetPokemon();
const moveQueue = this.pokemon.getMoveQueue();
if (
(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.showFailedText();
@ -410,7 +410,7 @@ export class MovePhase extends BattlePhase {
new MoveEffectPhase(this.pokemon.getBattlerIndex(), this.targets, move, this.reflected, this.move.virtual),
);
} 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());
}
@ -603,7 +603,7 @@ export class MovePhase extends BattlePhase {
*
* TODO: ...this seems weird.
* - 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
*/
protected handlePreMoveFailures(): void {
@ -623,7 +623,7 @@ export class MovePhase extends BattlePhase {
}
this.pokemon.pushMoveHistory({
move: Moves.NONE,
move: MoveId.NONE,
result: MoveResult.FAIL,
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}),
* 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}).
* 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 MoveId.HYPER_BEAM Hyper Beam}), or a 2-turn move was interrupted (ie: {@link MoveId.FLY Fly}).
*/
public showMoveText(): void {
if (this.move.moveId === Moves.NONE) {
if (this.move.moveId === MoveId.NONE) {
return;
}

View File

@ -1,6 +1,6 @@
import type { BattlerIndex } from "#app/battle";
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 { PokemonMove } from "#app/field/pokemon";
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));
}
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();

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";
/**
* Asynchronously load the animations and assets for the provided moves.
* @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 loadMoveAnimAssets(moveIds);
}

View File

@ -43,7 +43,7 @@ import { StatusEffect } from "#enums/status-effect";
import ChallengeData from "#app/system/challenge-data";
import { Device } from "#enums/devices";
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 { Species } from "#enums/species";
import { applyChallenges, ChallengeType } from "#app/data/challenge";
@ -205,7 +205,7 @@ export interface DexEntry {
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 {
[key: number]: StarterMoveset;

View File

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

View File

@ -2,7 +2,7 @@ import type { SessionSaveMigrator } from "#app/@types/SessionSaveMigrator";
import { PokemonMove } from "#app/field/pokemon";
import type { SessionSaveData } from "#app/system/game-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`,
@ -15,7 +15,7 @@ const migratePartyData: SessionSaveMigrator = {
// this stuff is copied straight from the constructor fwiw
const mapParty = (pkmnData: PokemonData) => {
// 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)
.map(m => PokemonMove.loadMove(m));
// 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 { BattleSceneEventType } from "../events/battle-scene";
import { BerryType } from "#enums/berry-type";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { UiTheme } from "#enums/ui-theme";
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 */
private onMoveUsed(event: Event) {
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
return;
}

View File

@ -25,7 +25,7 @@ import { applyChallenges, ChallengeType } from "#app/data/challenge";
import MoveInfoOverlay from "#app/ui/move-info-overlay";
import i18next from "i18next";
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 { getPokemonNameWithAffix } from "#app/messages";
import type { CommandPhase } from "#app/phases/command-phase";
@ -184,7 +184,7 @@ export default class PartyUiHandler extends MessageUiHandler {
private selectCallback: PartySelectCallback | PartyModifierTransferSelectCallback | null;
private selectFilter: PokemonSelectFilter | PokemonModifierTransferSelectFilter;
private moveSelectFilter: PokemonMoveSelectFilter;
private tmMoveId: Moves;
private tmMoveId: MoveId;
private showMovePp: boolean;
private iconAnimHandler: PokemonIconAnimHandler;
@ -346,7 +346,7 @@ export default class PartyUiHandler extends MessageUiHandler {
args.length > 4 && args[4] instanceof Function
? (args[4] as PokemonMoveSelectFilter)
: 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.partyContainer.setVisible(true);
@ -1165,8 +1165,7 @@ export default class PartyUiHandler extends MessageUiHandler {
this.partyUiMode !== PartyUiMode.FAINT_SWITCH &&
globalScene.findModifier(
m =>
m instanceof SwitchEffectTransferModifier &&
m.pokemonId === globalScene.getPlayerField()[this.fieldIndex].id,
m instanceof SwitchEffectTransferModifier && m.pokemonId === globalScene.getPlayerField()[this.fieldIndex].id,
)
);
}
@ -1654,7 +1653,7 @@ class PartySlot extends Phaser.GameObjects.Container {
pokemon: PlayerPokemon,
iconAnimHandler: PokemonIconAnimHandler,
partyUiMode: PartyUiMode,
tmMoveId: Moves,
tmMoveId: MoveId,
) {
super(
globalScene,
@ -1677,7 +1676,7 @@ class PartySlot extends Phaser.GameObjects.Container {
return this.pokemon;
}
setup(partyUiMode: PartyUiMode, tmMoveId: Moves) {
setup(partyUiMode: PartyUiMode, tmMoveId: MoveId) {
const currentLanguage = i18next.resolvedLanguage ?? "en";
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 { getEggTierForSpecies } from "#app/data/egg";
import { Device } from "#enums/devices";
import type { Moves } from "#enums/moves";
import type { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import { Button } from "#enums/buttons";
import { EggSourceType } from "#enums/egg-source-types";
@ -205,9 +205,9 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
private formIndex: number;
private speciesLoaded: Map<Species, boolean> = new Map<Species, boolean>();
private levelMoves: LevelMoves;
private eggMoves: Moves[] = [];
private eggMoves: MoveId[] = [];
private hasEggMoves: boolean[] = [];
private tmMoves: Moves[] = [];
private tmMoves: MoveId[] = [];
private ability1: AbilityId;
private ability2: 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 { getEggTierForSpecies } from "#app/data/egg";
import { Device } from "#enums/devices";
import type { Moves } from "#enums/moves";
import type { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import { Button } from "#enums/buttons";
import { EggSourceType } from "#enums/egg-source-types";
@ -365,7 +365,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
private starterTeras: PokemonType[] = [];
private starterMovesets: StarterMoveset[] = [];
private speciesStarterDexEntry: DexEntry | null;
private speciesStarterMoves: Moves[];
private speciesStarterMoves: MoveId[];
private canCycleShiny: boolean;
private canCycleForm: boolean;
private canCycleGender: boolean;
@ -1970,7 +1970,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
ui.setModeWithoutClear(UiMode.OPTION_SELECT, {
options: moveset
.map((m: Moves, i: number) => {
.map((m: MoveId, i: number) => {
const option: OptionSelectItem = {
label: allMoves[m].name,
handler: () => {
@ -1980,7 +1980,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
`${i18next.t("starterSelectUiHandler:selectMoveSwapWith")} ${allMoves[m].name}.`,
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]]);
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);
}
switchMoveHandler(i: number, newMove: Moves, move: Moves) {
switchMoveHandler(i: number, newMove: MoveId, move: MoveId) {
const speciesId = this.lastSpecies.speciesId;
const existingMoveIndex = this.starterMoveset?.indexOf(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 { getMoveTargets } from "../data/moves/move";
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 { ModifierBar } from "#app/modifier/modifier";
import { SubstituteTag } from "#app/data/battler-tags";
@ -14,7 +14,7 @@ export type TargetSelectCallback = (targets: BattlerIndex[]) => void;
export default class TargetSelectUiHandler extends UiHandler {
private fieldIndex: number;
private move: Moves;
private move: MoveId;
private targetSelectCallback: TargetSelectCallback;
private cursor0: number; // associated with BattlerIndex.PLAYER
private cursor1: number; // associated with BattlerIndex.PLAYER_2
@ -42,7 +42,7 @@ export default class TargetSelectUiHandler extends UiHandler {
super.show(args);
this.fieldIndex = args[0] as number;
this.move = args[1] as Moves;
this.move = args[1] as MoveId;
this.targetSelectCallback = args[2] as TargetSelectCallback;
const user = globalScene.getPlayerField()[this.fieldIndex];

View File

@ -1,5 +1,5 @@
import { MoneyFormat } from "#enums/money-format";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import i18next from "i18next";
import { pokerogueApi } from "#app/plugins/api/pokerogue-api";
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
*/
export function animationFileName(move: Moves): string {
return Moves[move].toLowerCase().replace(/\_/g, "-");
export function animationFileName(move: MoveId): string {
return MoveId[move].toLowerCase().replace(/\_/g, "-");
}
/**

View File

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

View File

@ -1,6 +1,6 @@
import { allAbilities } from "#app/data/data-lists";
import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
@ -23,11 +23,11 @@ describe("Abilities - Arena Trap", () => {
beforeEach(() => {
game = new GameManager(phaserGame);
game.override
.moveset(Moves.SPLASH)
.moveset(MoveId.SPLASH)
.ability(AbilityId.ARENA_TRAP)
.enemySpecies(Species.RALTS)
.enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.TELEPORT);
.enemyMoveset(MoveId.TELEPORT);
});
// TODO: Enable test when Issue #935 is addressed
@ -38,7 +38,7 @@ describe("Abilities - Arena Trap", () => {
const enemy = game.scene.getEnemyPokemon();
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
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}
* 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
*/
it("should lift if pokemon with this ability leaves the field", async () => {
game.override
.battleStyle("double")
.enemyMoveset(Moves.SPLASH)
.moveset([Moves.ROAR, Moves.SPLASH])
.enemyMoveset(MoveId.SPLASH)
.moveset([MoveId.ROAR, MoveId.SPLASH])
.ability(AbilityId.BALL_FETCH);
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]);
game.move.select(Moves.ROAR);
game.move.select(Moves.SPLASH, 1);
game.move.select(MoveId.ROAR);
game.move.select(MoveId.SPLASH, 1);
// This runs the fist command phase where the moves are selected
await game.toNextTurn();
// During the next command phase the player pokemons should not be trapped anymore
game.move.select(Moves.SPLASH);
game.move.select(Moves.SPLASH, 1);
game.move.select(MoveId.SPLASH);
game.move.select(MoveId.SPLASH, 1);
await game.toNextTurn();
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 { AbilityId } from "#enums/ability-id";
import GameManager from "#test/testUtils/gameManager";
@ -27,10 +27,10 @@ describe("Moves - Aroma Veil", () => {
game.override
.battleStyle("double")
.enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset([Moves.HEAL_BLOCK, Moves.IMPRISON, Moves.SPLASH])
.enemyMoveset([MoveId.HEAL_BLOCK, MoveId.IMPRISON, MoveId.SPLASH])
.enemySpecies(Species.SHUCKLE)
.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 () => {
@ -38,9 +38,9 @@ describe("Moves - Aroma Veil", () => {
const party = game.scene.getPlayerParty()! as PlayerPokemon[];
game.move.select(Moves.GROWL);
game.move.select(Moves.GROWL);
await game.move.selectEnemyMove(Moves.HEAL_BLOCK);
game.move.select(MoveId.GROWL);
game.move.select(MoveId.GROWL);
await game.move.selectEnemyMove(MoveId.HEAL_BLOCK);
await game.toNextTurn();
party.forEach(p => {
expect(p.getTag(BattlerTagType.HEAL_BLOCK)).toBeUndefined();
@ -52,10 +52,10 @@ describe("Moves - Aroma Veil", () => {
const party = game.scene.getPlayerParty()! as PlayerPokemon[];
game.move.select(Moves.GROWL);
game.move.select(Moves.GROWL, 1);
await game.move.selectEnemyMove(Moves.IMPRISON, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(Moves.SPLASH);
game.move.select(MoveId.GROWL);
game.move.select(MoveId.GROWL, 1);
await game.move.selectEnemyMove(MoveId.IMPRISON, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(MoveId.SPLASH);
await game.toNextTurn();
expect(game.scene.arena.getTag(ArenaTagType.IMPRISON)).toBeDefined();
party.forEach(p => {

View File

@ -1,6 +1,6 @@
import { allMoves } from "#app/data/data-lists";
import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
@ -26,49 +26,49 @@ describe("Abilities - Aura Break", () => {
game = new GameManager(phaserGame);
game.override
.battleStyle("single")
.moveset([Moves.MOONBLAST, Moves.DARK_PULSE])
.enemyMoveset(Moves.SPLASH)
.moveset([MoveId.MOONBLAST, MoveId.DARK_PULSE])
.enemyMoveset(MoveId.SPLASH)
.enemyAbility(AbilityId.AURA_BREAK)
.enemySpecies(Species.SHUCKLE);
});
it("reverses the effect of Fairy Aura", async () => {
const moveToCheck = allMoves[Moves.MOONBLAST];
const moveToCheck = allMoves[MoveId.MOONBLAST];
const basePower = moveToCheck.power;
game.override.ability(AbilityId.FAIRY_AURA);
vi.spyOn(moveToCheck, "calculateBattlePower");
await game.classicMode.startBattle([Species.PIKACHU]);
game.move.select(Moves.MOONBLAST);
game.move.select(MoveId.MOONBLAST);
await game.phaseInterceptor.to("MoveEffectPhase");
expect(moveToCheck.calculateBattlePower).toHaveReturnedWith(expect.closeTo(basePower * auraBreakMultiplier));
});
it("reverses the effect of Dark Aura", async () => {
const moveToCheck = allMoves[Moves.DARK_PULSE];
const moveToCheck = allMoves[MoveId.DARK_PULSE];
const basePower = moveToCheck.power;
game.override.ability(AbilityId.DARK_AURA);
vi.spyOn(moveToCheck, "calculateBattlePower");
await game.classicMode.startBattle([Species.PIKACHU]);
game.move.select(Moves.DARK_PULSE);
game.move.select(MoveId.DARK_PULSE);
await game.phaseInterceptor.to("MoveEffectPhase");
expect(moveToCheck.calculateBattlePower).toHaveReturnedWith(expect.closeTo(basePower * auraBreakMultiplier));
});
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;
game.override.ability(AbilityId.BALL_FETCH);
vi.spyOn(moveToCheck, "calculateBattlePower");
await game.classicMode.startBattle([Species.PIKACHU]);
game.move.select(Moves.MOONBLAST);
game.move.select(MoveId.MOONBLAST);
await game.phaseInterceptor.to("MoveEffectPhase");
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 { MoveEffectPhase } from "#app/phases/move-effect-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 GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
@ -29,50 +29,50 @@ describe("Abilities - Battery", () => {
game.override.battleStyle("double");
game.override.enemySpecies(Species.SHUCKLE);
game.override.enemyAbility(AbilityId.BALL_FETCH);
game.override.moveset([Moves.TACKLE, Moves.BREAKING_SWIPE, Moves.SPLASH, Moves.DAZZLING_GLEAM]);
game.override.enemyMoveset(Moves.SPLASH);
game.override.moveset([MoveId.TACKLE, MoveId.BREAKING_SWIPE, MoveId.SPLASH, MoveId.DAZZLING_GLEAM]);
game.override.enemyMoveset(MoveId.SPLASH);
});
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;
vi.spyOn(moveToCheck, "calculateBattlePower");
await game.classicMode.startBattle([Species.PIKACHU, Species.CHARJABUG]);
game.move.select(Moves.DAZZLING_GLEAM);
game.move.select(Moves.SPLASH, 1);
game.move.select(MoveId.DAZZLING_GLEAM);
game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to(MoveEffectPhase);
expect(moveToCheck.calculateBattlePower).toHaveReturnedWith(basePower * batteryMultiplier);
});
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;
vi.spyOn(moveToCheck, "calculateBattlePower");
await game.classicMode.startBattle([Species.PIKACHU, Species.CHARJABUG]);
game.move.select(Moves.BREAKING_SWIPE);
game.move.select(Moves.SPLASH, 1);
game.move.select(MoveId.BREAKING_SWIPE);
game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to(MoveEffectPhase);
expect(moveToCheck.calculateBattlePower).toHaveReturnedWith(basePower);
});
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;
vi.spyOn(moveToCheck, "calculateBattlePower");
await game.classicMode.startBattle([Species.CHARJABUG, Species.PIKACHU]);
game.move.select(Moves.DAZZLING_GLEAM);
game.move.select(Moves.SPLASH, 1);
game.move.select(MoveId.DAZZLING_GLEAM);
game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to(TurnEndPhase);
expect(moveToCheck.calculateBattlePower).toHaveReturnedWith(basePower);

View File

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

View File

@ -1,6 +1,6 @@
import { BattlerIndex } from "#app/battle";
import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import { Stat } from "#enums/stat";
import GameManager from "#test/testUtils/gameManager";
@ -29,8 +29,8 @@ describe("Abilities - Beast Boost", () => {
.enemyAbility(AbilityId.BEAST_BOOST)
.ability(AbilityId.BEAST_BOOST)
.startingLevel(2000)
.moveset([Moves.FLAMETHROWER])
.enemyMoveset(Moves.SPLASH);
.moveset([MoveId.FLAMETHROWER])
.enemyMoveset(MoveId.SPLASH);
});
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);
game.move.select(Moves.FLAMETHROWER);
game.move.select(MoveId.FLAMETHROWER);
await game.phaseInterceptor.to("VictoryPhase");
expect(playerPokemon.getStatStage(Stat.DEF)).toBe(1);
}, 20000);
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]);
@ -60,7 +60,7 @@ describe("Abilities - Beast Boost", () => {
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.phaseInterceptor.to("VictoryPhase");
@ -79,7 +79,7 @@ describe("Abilities - Beast Boost", () => {
expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(0);
game.move.select(Moves.FLAMETHROWER);
game.move.select(MoveId.FLAMETHROWER);
await game.phaseInterceptor.to("VictoryPhase");

View File

@ -7,7 +7,7 @@ import { StatusEffect } from "#enums/status-effect";
import { WeatherType } from "#enums/weather-type";
import { MoveResult } from "#app/field/pokemon";
import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
@ -32,13 +32,13 @@ describe("Abilities - Commander", () => {
game.override
.startingLevel(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)
.battleStyle("double")
.disableCrits()
.enemySpecies(Species.SNORLAX)
.enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.TACKLE);
.enemyMoveset(MoveId.TACKLE);
vi.spyOn(game.scene, "triggerPokemonBattleAnim").mockReturnValue(true);
});
@ -54,13 +54,13 @@ describe("Abilities - Commander", () => {
expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined();
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();
// Force both enemies to target the Tatsugiri
await game.move.selectEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(MoveId.TACKLE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(MoveId.TACKLE, BattlerIndex.PLAYER);
await game.phaseInterceptor.to("BerryPhase", false);
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 () => {
game.override.enemyMoveset(Moves.SPLASH);
game.override.enemyMoveset(MoveId.SPLASH);
await game.classicMode.startBattle([Species.TATSUGIRI, Species.MAGIKARP, Species.DONDOZO]);
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);
await game.phaseInterceptor.to("MovePhase", false);
@ -96,12 +96,12 @@ describe("Abilities - Commander", () => {
expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY);
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();
await game.move.selectEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(MoveId.TACKLE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(MoveId.TACKLE, 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 () => {
game.override.statusEffect(StatusEffect.POISON).enemyMoveset(Moves.SPLASH);
game.override.statusEffect(StatusEffect.POISON).enemyMoveset(MoveId.SPLASH);
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(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();
@ -132,7 +132,7 @@ describe("Abilities - Commander", () => {
});
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]);
@ -141,9 +141,9 @@ describe("Abilities - Commander", () => {
expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY);
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();
@ -152,7 +152,7 @@ describe("Abilities - Commander", () => {
});
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]);
@ -161,7 +161,7 @@ describe("Abilities - Commander", () => {
expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY);
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();
@ -170,7 +170,7 @@ describe("Abilities - Commander", () => {
});
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]);
@ -179,12 +179,12 @@ describe("Abilities - Commander", () => {
expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY);
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();
await game.move.selectEnemyMove(Moves.WHIRLWIND, BattlerIndex.PLAYER_2);
await game.move.selectEnemyMove(Moves.SPLASH);
await game.move.selectEnemyMove(MoveId.WHIRLWIND, BattlerIndex.PLAYER_2);
await game.move.selectEnemyMove(MoveId.SPLASH);
// Test may time out here if Whirlwind forced out a Pokemon
await game.phaseInterceptor.to("TurnEndPhase");
@ -192,14 +192,14 @@ describe("Abilities - Commander", () => {
});
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]);
const tatsugiri = game.scene.getPlayerField()[0];
game.move.select(Moves.DIVE, 0, BattlerIndex.ENEMY);
game.move.select(Moves.SPLASH, 1);
game.move.select(MoveId.DIVE, 0, BattlerIndex.ENEMY);
game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("CommandPhase");
await game.toNextTurn();

View File

@ -1,7 +1,7 @@
import { Stat } from "#enums/stat";
import { TurnInitPhase } from "#app/phases/turn-init-phase";
import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
@ -27,9 +27,9 @@ describe("Abilities - Competitive", () => {
game.override
.battleStyle("single")
.enemySpecies(Species.BEEDRILL)
.enemyMoveset(Moves.TICKLE)
.enemyMoveset(MoveId.TICKLE)
.startingLevel(1)
.moveset([Moves.SPLASH, Moves.CLOSE_COMBAT])
.moveset([MoveId.SPLASH, MoveId.CLOSE_COMBAT])
.ability(AbilityId.COMPETITIVE);
});
@ -37,7 +37,7 @@ describe("Abilities - Competitive", () => {
await game.classicMode.startBattle([Species.FLYGON]);
const playerPokemon = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnInitPhase);
expect(playerPokemon.getStatStage(Stat.ATK)).toBe(-1);
@ -46,11 +46,11 @@ describe("Abilities - Competitive", () => {
});
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]);
const playerPokemon = game.scene.getPlayerPokemon()!;
game.move.select(Moves.CLOSE_COMBAT);
game.move.select(MoveId.CLOSE_COMBAT);
await game.phaseInterceptor.to(TurnInitPhase);
expect(playerPokemon.getStatStage(Stat.SPDEF)).toBe(-1);
@ -63,7 +63,7 @@ describe("Abilities - Competitive", () => {
await game.classicMode.startBattle([Species.FLYGON]);
const playerPokemon = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnInitPhase);
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 { Species } from "#enums/species";
import { Stat } from "#enums/stat";
@ -27,7 +27,7 @@ describe("Abilities - Contrary", () => {
.enemySpecies(Species.BULBASAUR)
.enemyAbility(AbilityId.CONTRARY)
.ability(AbilityId.INTIMIDATE)
.enemyMoveset(Moves.SPLASH);
.enemyMoveset(MoveId.SPLASH);
});
it("should invert stat changes when applied", async () => {
@ -40,28 +40,28 @@ describe("Abilities - Contrary", () => {
describe("With Clear Body", () => {
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]);
const enemyPokemon = game.scene.getEnemyPokemon()!;
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(1);
game.move.select(Moves.TAIL_WHIP);
game.move.select(MoveId.TAIL_WHIP);
await game.phaseInterceptor.to("TurnEndPhase");
expect(enemyPokemon.getStatStage(Stat.DEF)).toBe(1);
});
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]);
const enemyPokemon = game.scene.getEnemyPokemon()!;
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(1);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnEndPhase");
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(1);

View File

@ -1,5 +1,5 @@
import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
@ -22,12 +22,12 @@ describe("Abilities - Corrosion", () => {
beforeEach(() => {
game = new GameManager(phaserGame);
game.override
.moveset([Moves.SPLASH])
.moveset([MoveId.SPLASH])
.battleStyle("single")
.disableCrits()
.enemySpecies(Species.GRIMER)
.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 () => {
@ -38,7 +38,7 @@ describe("Abilities - Corrosion", () => {
const enemyPokemon = game.scene.getEnemyPokemon();
expect(playerPokemon!.status).toBeUndefined();
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("BerryPhase");
expect(playerPokemon!.status).toBeDefined();
expect(enemyPokemon!.status).toBeUndefined();

View File

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

View File

@ -4,7 +4,7 @@ import { globalScene } from "#app/global-scene";
import { getPokemonNameWithAffix } from "#app/messages";
import { AbilityId } from "#enums/ability-id";
import { BerryType } from "#enums/berry-type";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import { Stat } from "#enums/stat";
import GameManager from "#test/testUtils/gameManager";
@ -29,14 +29,14 @@ describe("Abilities - Cud Chew", () => {
beforeEach(() => {
game = new GameManager(phaserGame);
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 }])
.ability(AbilityId.CUD_CHEW)
.battleStyle("single")
.disableCrits()
.enemySpecies(Species.MAGIKARP)
.enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH);
.enemyMoveset(MoveId.SPLASH);
});
describe("tracks berries eaten", () => {
@ -46,7 +46,7 @@ describe("Abilities - Cud Chew", () => {
const farigiraf = game.scene.getPlayerPokemon()!;
farigiraf.hp = 1; // needed to allow sitrus procs
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("BerryPhase");
// 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 () => {
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]);
const farigiraf = game.scene.getPlayerPokemon()!;
// Dip below half to eat berry
farigiraf.hp = farigiraf.getMaxHp() / 2 - 1;
game.move.select(Moves.SPLASH);
await game.move.selectEnemyMove(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnEndPhase");
// doesn't trigger since cud chew hasn't eaten berry yet
@ -85,8 +85,8 @@ describe("Abilities - Cud Chew", () => {
await game.toNextTurn();
// get heal pulsed back to full before the cud chew proc
game.move.select(Moves.SPLASH);
await game.move.selectEnemyMove(Moves.HEAL_PULSE);
game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(MoveId.HEAL_PULSE);
await game.phaseInterceptor.to("TurnEndPhase");
// 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.LIECHI, count: 3 },
])
.enemyMoveset(Moves.TEATIME);
.enemyMoveset(MoveId.TEATIME);
await game.classicMode.startBattle([Species.FARIGIRAF]);
const farigiraf = game.scene.getPlayerPokemon()!;
farigiraf.hp = 1; // needed to allow berry procs
game.move.select(Moves.STUFF_CHEEKS);
game.move.select(MoveId.STUFF_CHEEKS);
await game.toNextTurn();
// 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([]);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.toNextTurn();
// 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;
// eat berry turn 1, switch out turn 2
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.toNextTurn();
const turn1Hp = farigiraf.hp;
@ -180,7 +180,7 @@ describe("Abilities - Cud Chew", () => {
const farigiraf = game.scene.getPlayerPokemon()!;
farigiraf.hp = 1;
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("BerryPhase");
expect(farigiraf.summonData.berriesEatenLast).toEqual([]);
@ -202,7 +202,7 @@ describe("Abilities - Cud Chew", () => {
const farigiraf = game.scene.getPlayerPokemon()!;
farigiraf.hp = 1;
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.toNextTurn();
// ate 1 sitrus the turn prior, spitball pending
@ -212,7 +212,7 @@ describe("Abilities - Cud Chew", () => {
const turn1Hp = farigiraf.hp;
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnEndPhase");
// healed back up to half without adding any more to array
@ -228,9 +228,9 @@ describe("Abilities - Cud Chew", () => {
const farigiraf = game.scene.getPlayerPokemon()!;
farigiraf.hp = 1;
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.toNextTurn();
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnEndPhase");
// 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 () => {
game.override.enemyMoveset(Moves.INCINERATE);
game.override.enemyMoveset(MoveId.INCINERATE);
await game.classicMode.startBattle([Species.FARIGIRAF]);
const farigiraf = game.scene.getPlayerPokemon()!;
farigiraf.hp = farigiraf.getMaxHp() / 4;
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.toNextTurn();
// no berries eaten due to getting cooked
@ -264,10 +264,10 @@ describe("Abilities - Cud Chew", () => {
const farigiraf = game.scene.getPlayerPokemon()!;
game.move.select(Moves.BUG_BITE);
game.move.select(MoveId.BUG_BITE);
await game.toNextTurn();
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.toNextTurn();
// 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()!;
farigiraf.hp = 1;
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.toNextTurn();
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.toNextTurn();
// Rounding errors only ever cost a maximum of 4 hp
@ -297,7 +297,7 @@ describe("Abilities - Cud Chew", () => {
const farigiraf = game.scene.getPlayerPokemon()!;
farigiraf.hp = 1;
game.move.select(Moves.HYPER_VOICE);
game.move.select(MoveId.HYPER_VOICE);
await game.toNextWave();
// berry went yummy yummy in big fat giraffe tummy
@ -313,7 +313,7 @@ describe("Abilities - Cud Chew", () => {
const wave1Hp = farigirafReloaded.hp;
// 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();
expect(farigirafReloaded.hp).toBeGreaterThan(wave1Hp);

View File

@ -1,7 +1,7 @@
import { BattlerIndex } from "#app/battle";
import type { MovePhase } from "#app/phases/move-phase";
import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
@ -29,22 +29,22 @@ describe("Abilities - Dancer", () => {
// Reference Link: https://bulbapedia.bulbagarden.net/wiki/Dancer_(Ability)
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]);
const [oricorio, feebas] = game.scene.getPlayerField();
game.move.changeMoveset(oricorio, [Moves.SWORDS_DANCE, Moves.VICTORY_DANCE, Moves.SPLASH]);
game.move.changeMoveset(feebas, [Moves.SWORDS_DANCE, Moves.SPLASH]);
game.move.changeMoveset(oricorio, [MoveId.SWORDS_DANCE, MoveId.VICTORY_DANCE, MoveId.SPLASH]);
game.move.changeMoveset(feebas, [MoveId.SWORDS_DANCE, MoveId.SPLASH]);
game.move.select(Moves.SPLASH);
game.move.select(Moves.SWORDS_DANCE, 1);
game.move.select(MoveId.SPLASH);
game.move.select(MoveId.SWORDS_DANCE, 1);
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", false); // oricorio copies swords dance
let currentPhase = game.scene.getCurrentPhase() as MovePhase;
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("MovePhase"); // magikarp 1 copies swords dance
@ -54,7 +54,7 @@ describe("Abilities - Dancer", () => {
currentPhase = game.scene.getCurrentPhase() as MovePhase;
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
@ -66,8 +66,8 @@ describe("Abilities - Dancer", () => {
// 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 () => {
game.override
.moveset([Moves.FIERY_DANCE, Moves.REVELATION_DANCE])
.enemyMoveset([Moves.INSTRUCT, Moves.MIRROR_MOVE, Moves.SPLASH])
.moveset([MoveId.FIERY_DANCE, MoveId.REVELATION_DANCE])
.enemyMoveset([MoveId.INSTRUCT, MoveId.MIRROR_MOVE, MoveId.SPLASH])
.enemySpecies(Species.SHUCKLE)
.enemyLevel(10);
await game.classicMode.startBattle([Species.ORICORIO, Species.FEEBAS]);
@ -75,28 +75,28 @@ describe("Abilities - Dancer", () => {
const [oricorio] = game.scene.getPlayerField();
const [, shuckle2] = game.scene.getEnemyField();
game.move.select(Moves.REVELATION_DANCE, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2);
game.move.select(Moves.FIERY_DANCE, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY_2);
await game.move.selectEnemyMove(Moves.INSTRUCT, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(Moves.MIRROR_MOVE, BattlerIndex.PLAYER);
game.move.select(MoveId.REVELATION_DANCE, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2);
game.move.select(MoveId.FIERY_DANCE, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY_2);
await game.move.selectEnemyMove(MoveId.INSTRUCT, 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.phaseInterceptor.to("MovePhase"); // Oricorio rev dance
await game.phaseInterceptor.to("MovePhase"); // Feebas fiery dance
await game.phaseInterceptor.to("MovePhase"); // Oricorio fiery dance (from dancer)
await game.phaseInterceptor.to("MoveEndPhase", false);
// 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"); // calls instructed rev dance
let currentPhase = game.scene.getCurrentPhase() as MovePhase;
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");
currentPhase = game.scene.getCurrentPhase() as MovePhase;
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 { TurnInitPhase } from "#app/phases/turn-init-phase";
import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
@ -27,9 +27,9 @@ describe("Abilities - Defiant", () => {
game.override
.battleStyle("single")
.enemySpecies(Species.BEEDRILL)
.enemyMoveset(Moves.TICKLE)
.enemyMoveset(MoveId.TICKLE)
.startingLevel(1)
.moveset([Moves.SPLASH, Moves.CLOSE_COMBAT])
.moveset([MoveId.SPLASH, MoveId.CLOSE_COMBAT])
.ability(AbilityId.DEFIANT);
});
@ -37,7 +37,7 @@ describe("Abilities - Defiant", () => {
await game.classicMode.startBattle([Species.FLYGON]);
const playerPokemon = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnInitPhase);
expect(playerPokemon.getStatStage(Stat.ATK)).toBe(3);
@ -45,11 +45,11 @@ describe("Abilities - Defiant", () => {
});
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]);
const playerPokemon = game.scene.getPlayerPokemon()!;
game.move.select(Moves.CLOSE_COMBAT);
game.move.select(MoveId.CLOSE_COMBAT);
await game.phaseInterceptor.to(TurnInitPhase);
expect(playerPokemon.getStatStage(Stat.SPDEF)).toBe(-1);
@ -62,7 +62,7 @@ describe("Abilities - Defiant", () => {
await game.classicMode.startBattle([Species.FLYGON]);
const playerPokemon = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnInitPhase);
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 { Command } from "#app/ui/command-ui-handler";
import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
@ -26,19 +26,19 @@ describe("Abilities - Desolate Land", () => {
beforeEach(() => {
game = new GameManager(phaserGame);
game.override
.moveset(Moves.SPLASH)
.moveset(MoveId.SPLASH)
.hasPassiveAbility(true)
.enemySpecies(Species.RALTS)
.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}
* 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 () => {
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]);
expect(game.scene.arena.weather?.weatherType).toBe(WeatherType.HARSH_SUN);
@ -47,11 +47,11 @@ describe("Abilities - Desolate Land", () => {
return min;
});
game.move.select(Moves.SPLASH, 0, 2);
game.move.select(Moves.SPLASH, 1, 2);
game.move.select(MoveId.SPLASH, 0, 2);
game.move.select(MoveId.SPLASH, 1, 2);
await game.move.selectEnemyMove(Moves.ROAR, 0);
await game.move.selectEnemyMove(Moves.SPLASH, 1);
await game.move.selectEnemyMove(MoveId.ROAR, 0);
await game.move.selectEnemyMove(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("TurnEndPhase");
@ -63,11 +63,11 @@ describe("Abilities - Desolate Land", () => {
return min + 1;
});
game.move.select(Moves.SPLASH, 0, 2);
game.move.select(Moves.SPLASH, 1, 2);
game.move.select(MoveId.SPLASH, 0, 2);
game.move.select(MoveId.SPLASH, 1, 2);
await game.move.selectEnemyMove(Moves.ROAR, 1);
await game.move.selectEnemyMove(Moves.SPLASH, 0);
await game.move.selectEnemyMove(MoveId.ROAR, 1);
await game.move.selectEnemyMove(MoveId.SPLASH, 0);
await game.phaseInterceptor.to("TurnEndPhase");
@ -77,18 +77,18 @@ describe("Abilities - Desolate Land", () => {
it("should lift when enemy faints", async () => {
game.override
.battleStyle("single")
.moveset([Moves.SHEER_COLD])
.moveset([MoveId.SHEER_COLD])
.ability(AbilityId.NO_GUARD)
.startingLevel(100)
.enemyLevel(1)
.enemyMoveset([Moves.SPLASH])
.enemyMoveset([MoveId.SPLASH])
.enemySpecies(Species.MAGCARGO)
.enemyHasPassiveAbility(true);
await game.classicMode.startBattle([Species.MAGIKARP]);
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");
@ -96,15 +96,15 @@ describe("Abilities - Desolate Land", () => {
});
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]);
expect(game.scene.arena.weather?.weatherType).toBe(WeatherType.HARSH_SUN);
game.move.select(Moves.SPLASH, 0, 2);
game.move.select(Moves.SPLASH, 1, 2);
await game.move.selectEnemyMove(Moves.MEMENTO, 0);
await game.move.selectEnemyMove(Moves.MEMENTO, 1);
game.move.select(MoveId.SPLASH, 0, 2);
game.move.select(MoveId.SPLASH, 1, 2);
await game.move.selectEnemyMove(MoveId.MEMENTO, 0);
await game.move.selectEnemyMove(MoveId.MEMENTO, 1);
await game.phaseInterceptor.to("TurnEndPhase");
@ -118,7 +118,7 @@ describe("Abilities - Desolate Land", () => {
it("should lift when enemy is captured", async () => {
game.override
.battleStyle("single")
.enemyMoveset([Moves.SPLASH])
.enemyMoveset([MoveId.SPLASH])
.enemySpecies(Species.MAGCARGO)
.enemyHasPassiveAbility(true);
await game.classicMode.startBattle([Species.MAGIKARP]);

View File

@ -1,7 +1,7 @@
import { BattlerIndex } from "#app/battle";
import { toDmgValue } from "#app/utils/common";
import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import { Stat } from "#enums/stat";
import { StatusEffect } from "#enums/status-effect";
@ -29,9 +29,9 @@ describe("Abilities - Disguise", () => {
game.override
.battleStyle("single")
.enemySpecies(Species.MIMIKYU)
.enemyMoveset(Moves.SPLASH)
.enemyMoveset(MoveId.SPLASH)
.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 () => {
@ -43,7 +43,7 @@ describe("Abilities - Disguise", () => {
expect(mimikyu.formIndex).toBe(disguisedForm);
game.move.select(Moves.SHADOW_SNEAK);
game.move.select(MoveId.SHADOW_SNEAK);
await game.phaseInterceptor.to("MoveEndPhase");
@ -58,7 +58,7 @@ describe("Abilities - Disguise", () => {
expect(mimikyu.formIndex).toBe(disguisedForm);
game.move.select(Moves.VACUUM_WAVE);
game.move.select(MoveId.VACUUM_WAVE);
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 () => {
game.override.moveset([Moves.SURGING_STRIKES]);
game.override.moveset([MoveId.SURGING_STRIKES]);
game.override.enemyLevel(5);
await game.classicMode.startBattle();
@ -76,7 +76,7 @@ describe("Abilities - Disguise", () => {
expect(mimikyu.formIndex).toBe(disguisedForm);
game.move.select(Moves.SURGING_STRIKES);
game.move.select(MoveId.SURGING_STRIKES);
// First hit
await game.phaseInterceptor.to("MoveEffectPhase");
@ -95,7 +95,7 @@ describe("Abilities - Disguise", () => {
const mimikyu = game.scene.getEnemyPokemon()!;
expect(mimikyu.hp).toBe(mimikyu.getMaxHp());
game.move.select(Moves.TOXIC_THREAD);
game.move.select(MoveId.TOXIC_THREAD);
await game.phaseInterceptor.to("TurnEndPhase");
@ -106,7 +106,7 @@ describe("Abilities - Disguise", () => {
});
it("persists form change when switched out", async () => {
game.override.enemyMoveset([Moves.SHADOW_SNEAK]);
game.override.enemyMoveset([MoveId.SHADOW_SNEAK]);
game.override.starterSpecies(0);
await game.classicMode.startBattle([Species.MIMIKYU, Species.FURRET]);
@ -115,7 +115,7 @@ describe("Abilities - Disguise", () => {
const maxHp = mimikyu.getMaxHp();
const disguiseDamage = toDmgValue(maxHp / 8);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnEndPhase");
@ -140,7 +140,7 @@ describe("Abilities - Disguise", () => {
const mimikyu = game.scene.getPlayerParty()[1]!;
expect(mimikyu.formIndex).toBe(bustedForm);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.doKillOpponents();
await game.toNextWave();
@ -160,7 +160,7 @@ describe("Abilities - Disguise", () => {
expect(mimikyu.formIndex).toBe(bustedForm);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.doKillOpponents();
await game.toNextWave();
@ -180,11 +180,11 @@ describe("Abilities - Disguise", () => {
expect(mimikyu1.formIndex).toBe(bustedForm);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.killPokemon(mimikyu1);
game.doSelectPartyPokemon(1);
await game.toNextTurn();
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.doKillOpponents();
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 () => {
game.override.enemyMoveset([Moves.ENDURE]);
game.override.enemyMoveset([MoveId.ENDURE]);
await game.classicMode.startBattle();
const mimikyu = game.scene.getEnemyPokemon()!;
mimikyu.hp = 1;
game.move.select(Moves.SHADOW_SNEAK);
game.move.select(MoveId.SHADOW_SNEAK);
await game.toNextWave();
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 () => {
game.override.ability(AbilityId.AERILATE);
game.override.moveset([Moves.TACKLE]);
game.override.moveset([MoveId.TACKLE]);
await game.classicMode.startBattle();
@ -215,7 +215,7 @@ describe("Abilities - Disguise", () => {
const maxHp = mimikyu.getMaxHp();
const disguiseDamage = toDmgValue(maxHp / 8);
game.move.select(Moves.TACKLE);
game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.to("MoveEndPhase");
@ -224,10 +224,10 @@ describe("Abilities - Disguise", () => {
});
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();
game.move.select(Moves.POWER_TRIP);
game.move.select(MoveId.POWER_TRIP);
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
await game.toNextTurn();

View File

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

View File

@ -1,7 +1,7 @@
import { Status } from "#app/data/status-effect";
import { MoveResult } from "#app/field/pokemon";
import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import { StatusEffect } from "#enums/status-effect";
import GameManager from "#test/testUtils/gameManager";
@ -25,13 +25,13 @@ describe("Abilities - Early Bird", () => {
beforeEach(() => {
game = new GameManager(phaserGame);
game.override
.moveset([Moves.REST, Moves.BELLY_DRUM, Moves.SPLASH])
.moveset([MoveId.REST, MoveId.BELLY_DRUM, MoveId.SPLASH])
.ability(AbilityId.EARLY_BIRD)
.battleStyle("single")
.disableCrits()
.enemySpecies(Species.MAGIKARP)
.enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH);
.enemyMoveset(MoveId.SPLASH);
});
it("reduces Rest's sleep time to 1 turn", async () => {
@ -39,20 +39,20 @@ describe("Abilities - Early Bird", () => {
const player = game.scene.getPlayerPokemon()!;
game.move.select(Moves.BELLY_DRUM);
game.move.select(MoveId.BELLY_DRUM);
await game.toNextTurn();
game.move.select(Moves.REST);
game.move.select(MoveId.REST);
await game.toNextTurn();
expect(player.status?.effect).toBe(StatusEffect.SLEEP);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.toNextTurn();
expect(player.status?.effect).toBe(StatusEffect.SLEEP);
expect(player.getLastXMoves(1)[0].result).toBe(MoveResult.FAIL);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.toNextTurn();
expect(player.status?.effect).toBeUndefined();
@ -65,13 +65,13 @@ describe("Abilities - Early Bird", () => {
const player = game.scene.getPlayerPokemon()!;
player.status = new Status(StatusEffect.SLEEP, 0, 4);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.toNextTurn();
expect(player.status?.effect).toBe(StatusEffect.SLEEP);
expect(player.getLastXMoves(1)[0].result).toBe(MoveResult.FAIL);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.toNextTurn();
expect(player.status?.effect).toBeUndefined();
@ -84,7 +84,7 @@ describe("Abilities - Early Bird", () => {
const player = game.scene.getPlayerPokemon()!;
player.status = new Status(StatusEffect.SLEEP, 0, 2);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.toNextTurn();
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 { TurnEndPhase } from "#app/phases/turn-end-phase";
import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { StatusEffect } from "#enums/status-effect";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
@ -36,34 +36,34 @@ describe("Abilities - Flash Fire", () => {
});
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]);
const blissey = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase);
expect(blissey.hp).toBe(blissey.getMaxHp());
}, 20000);
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]);
const blissey = game.scene.getPlayerPokemon()!;
game.move.select(Moves.PROTECT);
game.move.select(MoveId.PROTECT);
await game.phaseInterceptor.to(TurnEndPhase);
expect(blissey!.getTag(BattlerTagType.FIRE_BOOST)).toBeUndefined();
}, 20000);
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]);
const blissey = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.move.forceHit();
await game.phaseInterceptor.to(MovePhase, false);
await game.move.forceHit();
@ -73,24 +73,24 @@ describe("Abilities - Flash Fire", () => {
}, 20000);
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);
await game.classicMode.startBattle([Species.BLISSEY]);
const blissey = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase);
expect(blissey!.getTag(BattlerTagType.FIRE_BOOST)).toBeDefined();
}, 20000);
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]);
// 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]);
game.doSelectPartyPokemon(1);
@ -102,7 +102,7 @@ describe("Abilities - Flash Fire", () => {
}, 20000);
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);
await game.classicMode.startBattle([Species.BLISSEY]);
const blissey = game.scene.getPlayerPokemon()!;
@ -110,7 +110,7 @@ describe("Abilities - Flash Fire", () => {
blissey.hp = initialHP;
// first turn
game.move.select(Moves.EMBER);
game.move.select(MoveId.EMBER);
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
await game.phaseInterceptor.to(TurnEndPhase);
const originalDmg = initialHP - blissey.hp;
@ -119,7 +119,7 @@ describe("Abilities - Flash Fire", () => {
blissey.hp = initialHP;
// second turn
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase);
const flashFireDmg = initialHP - blissey.hp;
@ -127,7 +127,7 @@ describe("Abilities - Flash Fire", () => {
}, 20000);
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.enemySpecies(Species.BLISSEY);
await game.classicMode.startBattle([Species.RATTATA]);
@ -137,7 +137,7 @@ describe("Abilities - Flash Fire", () => {
blissey.hp = initialHP;
// first turn
game.move.select(Moves.FIRE_PLEDGE);
game.move.select(MoveId.FIRE_PLEDGE);
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
await game.phaseInterceptor.to("MoveEffectPhase");
await game.move.forceMiss();
@ -148,7 +148,7 @@ describe("Abilities - Flash Fire", () => {
blissey.hp = initialHP;
// second turn
game.move.select(Moves.FIRE_PLEDGE);
game.move.select(MoveId.FIRE_PLEDGE);
await game.phaseInterceptor.to(TurnEndPhase);
const flashFireDmg = initialHP - blissey.hp;

View File

@ -4,7 +4,7 @@ import { AbilityId } from "#enums/ability-id";
import { Stat } from "#app/enums/stat";
import { WeatherType } from "#app/enums/weather-type";
import { TurnEndPhase } from "#app/phases/turn-end-phase";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
@ -25,7 +25,7 @@ describe("Abilities - Flower Gift", () => {
game.override.starterForms({ [Species.CASTFORM]: SUNSHINE_FORM }).enemyAbility(ability);
await game.classicMode.startBattle([Species.CASTFORM]);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
expect(game.scene.getPlayerPokemon()?.formIndex).toBe(OVERCAST_FORM);
};
@ -42,18 +42,18 @@ describe("Abilities - Flower Gift", () => {
*/
const testDamageDealt = async (
game: GameManager,
move: Moves,
move: MoveId,
allyAttacker: boolean,
allyAbility = AbilityId.BALL_FETCH,
enemyAbility = AbilityId.BALL_FETCH,
): Promise<[number, number]> => {
game.override.battleStyle("double");
game.override.moveset([Moves.SPLASH, Moves.SUNNY_DAY, move, Moves.HEAL_PULSE]);
game.override.enemyMoveset([Moves.SPLASH, Moves.HEAL_PULSE]);
game.override.moveset([MoveId.SPLASH, MoveId.SUNNY_DAY, move, MoveId.HEAL_PULSE]);
game.override.enemyMoveset([MoveId.SPLASH, MoveId.HEAL_PULSE]);
const target_index = allyAttacker ? BattlerIndex.ENEMY : BattlerIndex.PLAYER_2;
const attacker_index = allyAttacker ? BattlerIndex.PLAYER_2 : BattlerIndex.ENEMY;
const ally_move = allyAttacker ? move : Moves.SPLASH;
const enemy_move = allyAttacker ? Moves.SPLASH : move;
const ally_move = allyAttacker ? move : MoveId.SPLASH;
const enemy_move = allyAttacker ? MoveId.SPLASH : move;
const ally_target = allyAttacker ? BattlerIndex.ENEMY : null;
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]);
// turn 1
game.move.select(Moves.SUNNY_DAY, 0);
game.move.select(MoveId.SUNNY_DAY, 0);
game.move.select(ally_move, 1, ally_target);
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.
await game.setTurnOrder([attacker_index, target_index, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER]);
await game.phaseInterceptor.to(TurnEndPhase);
@ -77,10 +77,10 @@ describe("Abilities - Flower Gift", () => {
target.hp = initialHp;
// 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);
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.phaseInterceptor.to(TurnEndPhase);
const damageWithGift = initialHp - target.hp;
@ -101,9 +101,9 @@ describe("Abilities - Flower Gift", () => {
beforeEach(() => {
game = new GameManager(phaserGame);
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)
.enemyMoveset(Moves.SPLASH)
.enemyMoveset(MoveId.SPLASH)
.enemyAbility(AbilityId.BALL_FETCH)
.enemyLevel(100)
.startingLevel(100);
@ -120,8 +120,8 @@ describe("Abilities - Flower Gift", () => {
const magikarpAtkStat = magikarp.getEffectiveStat(Stat.ATK);
const magikarpSpDefStat = magikarp.getEffectiveStat(Stat.SPDEF);
game.move.select(Moves.SUNNY_DAY, 0);
game.move.select(Moves.SPLASH, 1);
game.move.select(MoveId.SUNNY_DAY, 0);
game.move.select(MoveId.SPLASH, 1);
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]);
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 () => {
const [damageWithGift, damageWithoutGift] = await testDamageDealt(game, Moves.SUNSTEEL_STRIKE, true);
const [damageWithGift, damageWithoutGift] = await testDamageDealt(game, MoveId.SUNSTEEL_STRIKE, true);
expect(damageWithGift).toBe(damageWithoutGift);
});
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);
});
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);
});
it("should not decrease the damage an ally takes from a mold breaker enemy using a special attack", async () => {
const [damageWithoutGift, damageWithGift] = await testDamageDealt(
game,
Moves.MUD_SLAP,
MoveId.MUD_SLAP,
false,
AbilityId.BALL_FETCH,
AbilityId.MOLD_BREAKER,
@ -166,7 +171,7 @@ describe("Abilities - Flower Gift", () => {
const cherrim = game.scene.getPlayerPokemon()!;
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 () => {
@ -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 () => {
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]);
@ -186,7 +191,7 @@ describe("Abilities - Flower Gift", () => {
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.phaseInterceptor.to("TurnEndPhase");

View File

@ -1,6 +1,6 @@
import { BattlerIndex } from "#app/battle";
import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import { Stat } from "#enums/stat";
import { StatusEffect } from "#enums/status-effect";
@ -28,14 +28,14 @@ describe("Abilities - Flower Veil", () => {
beforeEach(() => {
game = new GameManager(phaserGame);
game.override
.moveset([Moves.SPLASH])
.moveset([MoveId.SPLASH])
.enemySpecies(Species.BULBASAUR)
.ability(AbilityId.FLOWER_VEIL)
.battleStyle("single")
.disableCrits()
.enemySpecies(Species.MAGIKARP)
.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 () => {
game.override
.enemyMoveset([Moves.TACKLE, Moves.SPLASH])
.moveset([Moves.REST, Moves.SPLASH])
.enemyMoveset([MoveId.TACKLE, MoveId.SPLASH])
.moveset([MoveId.REST, MoveId.SPLASH])
.startingHeldItems([{ name: "FLAME_ORB" }]);
await game.classicMode.startBattle([Species.BULBASAUR]);
const user = game.scene.getPlayerPokemon()!;
game.move.select(Moves.REST);
await game.move.selectEnemyMove(Moves.TACKLE);
game.move.select(MoveId.REST);
await game.move.selectEnemyMove(MoveId.TACKLE);
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
await game.toNextTurn();
expect(user.status?.effect).toBe(StatusEffect.SLEEP);
// remove sleep status so we can get burn from the orb
user.resetStatus();
game.move.select(Moves.SPLASH);
await game.move.selectEnemyMove(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(MoveId.SPLASH);
await game.toNextTurn();
expect(user.status?.effect).toBe(StatusEffect.BURN);
});
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]);
// Clear the ability of the ally to isolate the test
const ally = game.scene.getPlayerField()[1]!;
vi.spyOn(ally, "getAbility").mockReturnValue(allAbilities[AbilityId.BALL_FETCH]);
game.move.select(Moves.SPLASH);
game.move.select(Moves.SPLASH);
await game.move.selectEnemyMove(Moves.YAWN, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(Moves.YAWN, BattlerIndex.PLAYER_2);
game.move.select(MoveId.SPLASH);
game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(MoveId.YAWN, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(MoveId.YAWN, BattlerIndex.PLAYER_2);
await game.phaseInterceptor.to("BerryPhase");
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 () => {
game.override.enemyMoveset([Moves.THUNDER_WAVE]).moveset([Moves.SPLASH]).battleStyle("double");
vi.spyOn(allMoves[Moves.THUNDER_WAVE], "accuracy", "get").mockReturnValue(100);
game.override.enemyMoveset([MoveId.THUNDER_WAVE]).moveset([MoveId.SPLASH]).battleStyle("double");
vi.spyOn(allMoves[MoveId.THUNDER_WAVE], "accuracy", "get").mockReturnValue(100);
await game.classicMode.startBattle([Species.BULBASAUR]);
game.move.select(Moves.SPLASH);
await game.move.selectEnemyMove(Moves.THUNDER_WAVE);
game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(MoveId.THUNDER_WAVE);
await game.toNextTurn();
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 () => {
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]);
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
vi.spyOn(ally, "getAbility").mockReturnValue(allAbilities[AbilityId.BALL_FETCH]);
game.move.select(Moves.SPLASH);
game.move.select(Moves.SPLASH);
await game.move.selectEnemyMove(Moves.THUNDER_WAVE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(Moves.THUNDER_WAVE, BattlerIndex.PLAYER_2);
game.move.select(MoveId.SPLASH);
game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(MoveId.THUNDER_WAVE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(MoveId.THUNDER_WAVE, BattlerIndex.PLAYER_2);
await game.phaseInterceptor.to("BerryPhase");
expect(user.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 () => {
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]);
const [user, ally] = game.scene.getPlayerField();
// Clear the ally ability to isolate the test
vi.spyOn(ally, "getAbility").mockReturnValue(allAbilities[AbilityId.BALL_FETCH]);
game.move.select(Moves.SPLASH);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("BerryPhase");
expect(user.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 () => {
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]);
const [user, ally] = game.scene.getPlayerField();
// Clear the ally ability to isolate the test
vi.spyOn(ally, "getAbility").mockReturnValue(allAbilities[AbilityId.BALL_FETCH]);
game.move.select(Moves.SPLASH);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("BerryPhase");
expect(user.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 () => {
game.override.moveset([Moves.CLOSE_COMBAT]).battleStyle("double");
game.override.moveset([MoveId.CLOSE_COMBAT]).battleStyle("double");
await game.classicMode.startBattle([Species.BULBASAUR, Species.BULBASAUR]);
const [user, ally] = game.scene.getPlayerField();
// Clear the ally ability to isolate the test
vi.spyOn(ally, "getAbility").mockReturnValue(allAbilities[AbilityId.BALL_FETCH]);
game.move.select(Moves.CLOSE_COMBAT, 0, BattlerIndex.ENEMY);
game.move.select(Moves.CLOSE_COMBAT, 1, BattlerIndex.ENEMY_2);
game.move.select(MoveId.CLOSE_COMBAT, 0, BattlerIndex.ENEMY);
game.move.select(MoveId.CLOSE_COMBAT, 1, BattlerIndex.ENEMY_2);
await game.phaseInterceptor.to("BerryPhase");
expect(user.getStatStage(Stat.DEF)).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 () => {
game.override.enemyMoveset([Moves.SPICY_EXTRACT]).moveset([Moves.SPLASH]);
game.override.enemyMoveset([MoveId.SPICY_EXTRACT]).moveset([MoveId.SPLASH]);
await game.classicMode.startBattle([Species.BULBASAUR]);
const user = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("BerryPhase");
expect(user.getStatStage(Stat.ATK)).toBe(2);
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 { QuietFormChangePhase } from "#app/phases/quiet-form-change-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 GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
@ -32,7 +32,7 @@ describe("Abilities - Forecast", () => {
game.override.weather(weather).starterForms({ [Species.CASTFORM]: initialForm });
await game.classicMode.startBattle([Species.CASTFORM]);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
expect(game.scene.getPlayerPokemon()?.formIndex).toBe(form);
};
@ -46,7 +46,7 @@ describe("Abilities - Forecast", () => {
game.override.starterForms({ [Species.CASTFORM]: SUNNY_FORM }).enemyAbility(ability);
await game.classicMode.startBattle([Species.CASTFORM]);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
expect(game.scene.getPlayerPokemon()?.formIndex).toBe(NORMAL_FORM);
};
@ -64,9 +64,9 @@ describe("Abilities - Forecast", () => {
beforeEach(() => {
game = new GameManager(phaserGame);
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)
.enemyMoveset(Moves.SPLASH)
.enemyMoveset(MoveId.SPLASH)
.enemyAbility(AbilityId.BALL_FETCH);
});
@ -74,7 +74,7 @@ describe("Abilities - Forecast", () => {
"changes form based on weather",
async () => {
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")
.starterForms({
[Species.KYOGRE]: 1,
@ -95,86 +95,86 @@ describe("Abilities - Forecast", () => {
const castform = game.scene.getPlayerField()[0];
expect(castform.formIndex).toBe(NORMAL_FORM);
game.move.select(Moves.RAIN_DANCE);
game.move.select(Moves.SPLASH, 1);
game.move.select(MoveId.RAIN_DANCE);
game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
expect(castform.formIndex).toBe(RAINY_FORM);
game.move.select(Moves.SUNNY_DAY);
game.move.select(Moves.SPLASH, 1);
game.move.select(MoveId.SUNNY_DAY);
game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
expect(castform.formIndex).toBe(SUNNY_FORM);
game.move.select(Moves.SNOWSCAPE);
game.move.select(Moves.SPLASH, 1);
game.move.select(MoveId.SNOWSCAPE);
game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
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(Moves.SPLASH, 1);
game.move.select(MoveId.SANDSTORM);
game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
expect(castform.formIndex).toBe(NORMAL_FORM);
game.move.select(Moves.HAIL);
game.move.select(Moves.SPLASH, 1);
game.move.select(MoveId.HAIL);
game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
expect(castform.formIndex).toBe(SNOWY_FORM);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
game.doSwitchPokemon(2); // Feebas now 2, Kyogre 1
await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
expect(castform.formIndex).toBe(RAINY_FORM);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
game.doSwitchPokemon(3); // Kyogre now 3, Groudon 1
await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
expect(castform.formIndex).toBe(SUNNY_FORM);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
game.doSwitchPokemon(4); // Groudon now 4, Rayquaza 1
await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
expect(castform.formIndex).toBe(NORMAL_FORM);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
game.doSwitchPokemon(2); // Rayquaza now 2, Feebas 1
await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
expect(castform.formIndex).toBe(NORMAL_FORM);
game.move.select(Moves.SNOWSCAPE);
game.move.select(Moves.SPLASH, 1);
game.move.select(MoveId.SNOWSCAPE);
game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
expect(castform.formIndex).toBe(SNOWY_FORM);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
game.doSwitchPokemon(5); // Feebas now 5, Altaria 1
await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
expect(castform.formIndex).toBe(NORMAL_FORM);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
game.doSwitchPokemon(5); // Altaria now 5, Feebas 1
await game.phaseInterceptor.to("MovePhase");
await game.toNextTurn();
@ -182,8 +182,8 @@ describe("Abilities - Forecast", () => {
expect(castform.formIndex).toBe(SNOWY_FORM);
game.scene.arena.trySetWeather(WeatherType.FOG);
game.move.select(Moves.SPLASH);
game.move.select(Moves.SPLASH, 1);
game.move.select(MoveId.SPLASH);
game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("TurnStartPhase");
expect(castform.formIndex).toBe(NORMAL_FORM);
@ -203,7 +203,7 @@ describe("Abilities - Forecast", () => {
game.override.enemyAbility(AbilityId.FORECAST).enemySpecies(Species.SHUCKLE);
await game.classicMode.startBattle([Species.CASTFORM]);
game.move.select(Moves.RAIN_DANCE);
game.move.select(MoveId.RAIN_DANCE);
await game.phaseInterceptor.to(TurnEndPhase);
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 () => {
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]);
const castform = game.scene.getPlayerPokemon()!;
expect(castform.formIndex).toBe(RAINY_FORM);
// First turn - Forecast is suppressed
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
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 () => {
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]);
// First turn - set up stealth rock
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.toNextTurn();
// 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 { AbilityId } from "#enums/ability-id";
import GameManager from "#test/testUtils/gameManager";
@ -28,9 +28,9 @@ describe("Moves - Friend Guard", () => {
game.override
.battleStyle("double")
.enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset([Moves.TACKLE, Moves.SPLASH, Moves.DRAGON_RAGE])
.enemyMoveset([MoveId.TACKLE, MoveId.SPLASH, MoveId.DRAGON_RAGE])
.enemySpecies(Species.SHUCKLE)
.moveset([Moves.SPLASH])
.moveset([MoveId.SPLASH])
.startingLevel(100);
});
@ -41,10 +41,10 @@ describe("Moves - Friend Guard", () => {
const enemy1 = game.scene.getEnemyField()[0];
game.move.select(Moves.SPLASH);
game.move.select(Moves.SPLASH, 1);
await game.move.selectEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
game.move.select(MoveId.SPLASH, 1);
await game.move.selectEnemyMove(MoveId.TACKLE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(MoveId.SPLASH);
await game.toNextTurn();
// 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)
expect(turn1Damage).toBe(
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]);
game.move.select(Moves.SPLASH);
game.move.select(Moves.SPLASH, 1);
await game.move.selectEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
game.move.select(MoveId.SPLASH, 1);
await game.move.selectEnemyMove(MoveId.TACKLE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(MoveId.SPLASH);
await game.toNextTurn();
// 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%
expect(turn2Damage).toBe(
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,
),
);
@ -81,20 +81,20 @@ describe("Moves - Friend Guard", () => {
const player2 = game.scene.getPlayerField()[1];
const spy = vi.spyOn(player2, "getAttackDamage");
game.move.select(Moves.SPLASH);
game.move.select(Moves.SPLASH, 1);
await game.move.selectEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER_2);
await game.move.selectEnemyMove(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
game.move.select(MoveId.SPLASH, 1);
await game.move.selectEnemyMove(MoveId.TACKLE, BattlerIndex.PLAYER_2);
await game.move.selectEnemyMove(MoveId.SPLASH);
await game.toNextTurn();
const turn1Damage = spy.mock.results[spy.mock.results.length - 1].value.damage;
vi.spyOn(player2, "getAbility").mockReturnValue(allAbilities[AbilityId.FRIEND_GUARD]);
game.move.select(Moves.SPLASH);
game.move.select(Moves.SPLASH, 1);
await game.move.selectEnemyMove(Moves.TACKLE, BattlerIndex.PLAYER_2);
await game.move.selectEnemyMove(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
game.move.select(MoveId.SPLASH, 1);
await game.move.selectEnemyMove(MoveId.TACKLE, BattlerIndex.PLAYER_2);
await game.move.selectEnemyMove(MoveId.SPLASH);
await game.toNextTurn();
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 spy = vi.spyOn(player1, "getAttackDamage");
game.move.select(Moves.SPLASH);
game.move.select(Moves.SPLASH, 1);
await game.move.selectEnemyMove(Moves.DRAGON_RAGE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
game.move.select(MoveId.SPLASH, 1);
await game.move.selectEnemyMove(MoveId.DRAGON_RAGE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(MoveId.SPLASH);
await game.toNextTurn();
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]);
game.move.select(Moves.SPLASH);
game.move.select(Moves.SPLASH, 1);
await game.move.selectEnemyMove(Moves.DRAGON_RAGE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
game.move.select(MoveId.SPLASH, 1);
await game.move.selectEnemyMove(MoveId.DRAGON_RAGE, BattlerIndex.PLAYER);
await game.move.selectEnemyMove(MoveId.SPLASH);
await game.toNextTurn();
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 { WeatherType } from "#app/enums/weather-type";
import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
@ -30,22 +30,22 @@ describe("Abilities - Good As Gold", () => {
beforeEach(() => {
game = new GameManager(phaserGame);
game.override
.moveset([Moves.SPLASH])
.moveset([MoveId.SPLASH])
.ability(AbilityId.GOOD_AS_GOLD)
.battleStyle("single")
.disableCrits()
.enemySpecies(Species.MAGIKARP)
.enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH);
.enemyMoveset(MoveId.SPLASH);
});
it("should block normal status moves", async () => {
game.override.enemyMoveset([Moves.GROWL]);
game.override.enemyMoveset([MoveId.GROWL]);
await game.classicMode.startBattle([Species.MAGIKARP]);
const player = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SPLASH, 0);
game.move.select(MoveId.SPLASH, 0);
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 () => {
game.override.enemyMoveset([Moves.MEMENTO]);
game.override.enemyMoveset([MoveId.MEMENTO]);
await game.classicMode.startBattle([Species.MAGIKARP]);
game.move.select(Moves.MEMENTO);
game.move.select(MoveId.MEMENTO);
await game.phaseInterceptor.to("BerryPhase");
expect(game.scene.getPlayerPokemon()!.isFainted()).toBe(false);
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 () => {
game.override.battleStyle("double");
game.override.enemyMoveset([Moves.STEALTH_ROCK, Moves.HAZE]);
game.override.moveset([Moves.SWORDS_DANCE, Moves.SAFEGUARD]);
game.override.enemyMoveset([MoveId.STEALTH_ROCK, MoveId.HAZE]);
game.override.moveset([MoveId.SWORDS_DANCE, MoveId.SAFEGUARD]);
await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS]);
const [good_as_gold, ball_fetch] = game.scene.getPlayerField();
// Force second pokemon to have ball fetch to isolate to a single mon.
vi.spyOn(ball_fetch, "getAbility").mockReturnValue(allAbilities[AbilityId.BALL_FETCH]);
game.move.select(Moves.SWORDS_DANCE, 0);
game.move.select(Moves.SAFEGUARD, 1);
await game.move.selectEnemyMove(Moves.STEALTH_ROCK);
await game.move.selectEnemyMove(Moves.HAZE);
game.move.select(MoveId.SWORDS_DANCE, 0);
game.move.select(MoveId.SAFEGUARD, 1);
await game.move.selectEnemyMove(MoveId.STEALTH_ROCK);
await game.move.selectEnemyMove(MoveId.HAZE);
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]);
await game.phaseInterceptor.to("BerryPhase");
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 () => {
game.override.battleStyle("single");
game.override.enemyMoveset([Moves.SPIKES]);
game.override.enemyMoveset([MoveId.SPIKES]);
await game.classicMode.startBattle([Species.MAGIKARP]);
game.move.select(Moves.SPLASH, 0);
game.move.select(MoveId.SPLASH, 0);
await game.phaseInterceptor.to("BerryPhase");
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 () => {
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]);
game.move.select(Moves.HELPING_HAND, 0);
game.move.select(Moves.TACKLE, 1);
game.move.select(MoveId.HELPING_HAND, 0);
game.move.select(MoveId.TACKLE, 1);
await game.phaseInterceptor.to("MoveEndPhase", true);
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);
// turn 1
game.move.use(Moves.SPLASH, 0);
game.move.use(Moves.HEAL_BELL, 1);
game.move.use(MoveId.SPLASH, 0);
game.move.use(MoveId.HEAL_BELL, 1);
await game.toNextTurn();
expect(milotic.status?.effect).toBe(StatusEffect.BURN);
game.doSwitchPokemon(2);
game.move.use(Moves.HEAL_BELL, 1);
game.move.use(MoveId.HEAL_BELL, 1);
await game.toNextTurn();
expect(milotic.status?.effect).toBeUndefined();
});
it("should not block field targeted effects like rain dance", async () => {
game.override.battleStyle("single");
game.override.enemyMoveset([Moves.RAIN_DANCE]);
game.override.enemyMoveset([MoveId.RAIN_DANCE]);
await game.classicMode.startBattle([Species.MAGIKARP]);
game.move.use(Moves.SPLASH, 0);
game.move.use(MoveId.SPLASH, 0);
await game.phaseInterceptor.to("BerryPhase");
expect(game.scene.arena.weather?.weatherType).toBe(WeatherType.RAIN);

View File

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

View File

@ -2,7 +2,7 @@ import { BattlerIndex } from "#app/battle";
import type Pokemon from "#app/field/pokemon";
import { AbilityId } from "#enums/ability-id";
import { BattlerTagType } from "#enums/battler-tag-type";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import { Stat } from "#enums/stat";
import { StatusEffect } from "#enums/status-effect";
@ -43,10 +43,10 @@ describe("Abilities - Gulp Missile", () => {
game.override
.disableCrits()
.battleStyle("single")
.moveset([Moves.SURF, Moves.DIVE, Moves.SPLASH, Moves.SUBSTITUTE])
.moveset([MoveId.SURF, MoveId.DIVE, MoveId.SPLASH, MoveId.SUBSTITUTE])
.enemySpecies(Species.SNORLAX)
.enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH)
.enemyMoveset(MoveId.SPLASH)
.enemyLevel(5);
});
@ -54,9 +54,9 @@ describe("Abilities - Gulp Missile", () => {
await game.classicMode.startBattle([Species.CRAMORANT]);
const cramorant = game.scene.getPlayerPokemon()!;
game.move.select(Moves.DIVE);
game.move.select(MoveId.DIVE);
await game.toNextTurn();
game.move.select(Moves.DIVE);
game.move.select(MoveId.DIVE);
await game.phaseInterceptor.to("MoveEndPhase");
expect(cramorant.getHpRatio()).toBeGreaterThanOrEqual(0.5);
@ -71,7 +71,7 @@ describe("Abilities - Gulp Missile", () => {
vi.spyOn(cramorant, "getHpRatio").mockReturnValue(0.49);
expect(cramorant.getHpRatio()).toBe(0.49);
game.move.select(Moves.SURF);
game.move.select(MoveId.SURF);
await game.phaseInterceptor.to("MoveEndPhase");
expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_PIKACHU)).toBeDefined();
@ -82,7 +82,7 @@ describe("Abilities - Gulp Missile", () => {
await game.classicMode.startBattle([Species.CRAMORANT, Species.MAGIKARP]);
const cramorant = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SURF);
game.move.select(MoveId.SURF);
await game.toNextTurn();
game.doSwitchPokemon(1);
@ -97,7 +97,7 @@ describe("Abilities - Gulp Missile", () => {
await game.classicMode.startBattle([Species.CRAMORANT]);
const cramorant = game.scene.getPlayerPokemon()!;
game.move.select(Moves.DIVE);
game.move.select(MoveId.DIVE);
await game.phaseInterceptor.to("MoveEndPhase");
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 () => {
game.override.enemyMoveset(Moves.TACKLE);
game.override.enemyMoveset(MoveId.TACKLE);
await game.classicMode.startBattle([Species.CRAMORANT]);
const enemy = game.scene.getEnemyPokemon()!;
vi.spyOn(enemy, "damageAndUpdate");
game.move.select(Moves.SURF);
game.move.select(MoveId.SURF);
await game.phaseInterceptor.to("TurnEndPhase");
expect(enemy.damageAndUpdate).toHaveReturnedWith(getEffectDamage(enemy));
});
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]);
const cramorant = game.scene.getPlayerPokemon()!;
vi.spyOn(cramorant, "getHpRatio").mockReturnValue(0.55);
game.move.select(Moves.SURF);
game.move.select(MoveId.SURF);
await game.phaseInterceptor.to("MoveEndPhase");
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 () => {
game.override.enemyMoveset(Moves.TACKLE);
game.override.enemyMoveset(MoveId.TACKLE);
await game.classicMode.startBattle([Species.CRAMORANT]);
const cramorant = game.scene.getPlayerPokemon()!;
@ -146,7 +146,7 @@ describe("Abilities - Gulp Missile", () => {
vi.spyOn(enemy, "damageAndUpdate");
vi.spyOn(cramorant, "getHpRatio").mockReturnValue(0.55);
game.move.select(Moves.SURF);
game.move.select(MoveId.SURF);
await game.phaseInterceptor.to("MoveEndPhase");
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 () => {
game.override.enemyMoveset(Moves.TACKLE);
game.override.enemyMoveset(MoveId.TACKLE);
await game.classicMode.startBattle([Species.CRAMORANT]);
const cramorant = game.scene.getPlayerPokemon()!;
@ -170,7 +170,7 @@ describe("Abilities - Gulp Missile", () => {
vi.spyOn(enemy, "damageAndUpdate");
vi.spyOn(cramorant, "getHpRatio").mockReturnValue(0.45);
game.move.select(Moves.SURF);
game.move.select(MoveId.SURF);
await game.phaseInterceptor.to("MoveEndPhase");
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 () => {
game.override.enemyMoveset(Moves.SURF);
game.override.enemyMoveset(MoveId.SURF);
await game.classicMode.startBattle([Species.CRAMORANT]);
const cramorant = game.scene.getPlayerPokemon()!;
game.move.select(Moves.DIVE);
game.move.select(MoveId.DIVE);
await game.phaseInterceptor.to("BerryPhase", false);
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 () => {
game.override.enemyMoveset(Moves.TACKLE).enemyAbility(AbilityId.MAGIC_GUARD);
game.override.enemyMoveset(MoveId.TACKLE).enemyAbility(AbilityId.MAGIC_GUARD);
await game.classicMode.startBattle([Species.CRAMORANT]);
const cramorant = game.scene.getPlayerPokemon()!;
@ -206,7 +206,7 @@ describe("Abilities - Gulp Missile", () => {
vi.spyOn(cramorant, "getHpRatio").mockReturnValue(0.55);
game.move.select(Moves.SURF);
game.move.select(MoveId.SURF);
await game.phaseInterceptor.to("MoveEndPhase");
const enemyHpPreEffect = enemy.hp;
@ -222,12 +222,12 @@ describe("Abilities - Gulp Missile", () => {
});
it("activates on faint", async () => {
game.override.enemyMoveset(Moves.THUNDERBOLT);
game.override.enemyMoveset(MoveId.THUNDERBOLT);
await game.classicMode.startBattle([Species.CRAMORANT]);
const cramorant = game.scene.getPlayerPokemon()!;
game.move.select(Moves.SURF);
game.move.select(MoveId.SURF);
await game.phaseInterceptor.to("FaintPhase");
expect(cramorant.hp).toBe(0);
@ -237,17 +237,17 @@ describe("Abilities - Gulp Missile", () => {
});
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]);
game.move.select(Moves.SURF);
await game.move.selectEnemyMove(Moves.SPLASH);
game.move.select(MoveId.SURF);
await game.move.selectEnemyMove(MoveId.SPLASH);
await game.toNextTurn();
expect(game.scene.getPlayerPokemon()!.formIndex).toBe(GULPING_FORM);
game.move.select(Moves.SUBSTITUTE);
await game.move.selectEnemyMove(Moves.POWER_TRIP);
game.move.select(MoveId.SUBSTITUTE);
await game.move.selectEnemyMove(MoveId.POWER_TRIP);
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
await game.toNextTurn();
@ -255,13 +255,13 @@ describe("Abilities - Gulp Missile", () => {
});
it("cannot be suppressed", async () => {
game.override.enemyMoveset(Moves.GASTRO_ACID);
game.override.enemyMoveset(MoveId.GASTRO_ACID);
await game.classicMode.startBattle([Species.CRAMORANT]);
const cramorant = game.scene.getPlayerPokemon()!;
vi.spyOn(cramorant, "getHpRatio").mockReturnValue(0.55);
game.move.select(Moves.SURF);
game.move.select(MoveId.SURF);
await game.phaseInterceptor.to("MoveEndPhase");
expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined();
@ -275,13 +275,13 @@ describe("Abilities - Gulp Missile", () => {
});
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]);
const cramorant = game.scene.getPlayerPokemon()!;
vi.spyOn(cramorant, "getHpRatio").mockReturnValue(0.55);
game.move.select(Moves.SURF);
game.move.select(MoveId.SURF);
await game.phaseInterceptor.to("MoveEndPhase");
expect(cramorant.getTag(BattlerTagType.GULP_MISSILE_ARROKUDA)).toBeDefined();
@ -298,7 +298,7 @@ describe("Abilities - Gulp Missile", () => {
game.override.enemyAbility(AbilityId.TRACE);
await game.classicMode.startBattle([Species.CRAMORANT]);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnStartPhase");
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 { AbilityId } from "#enums/ability-id";
import { BerryType } from "#enums/berry-type";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import { Stat } from "#enums/stat";
import { WeatherType } from "#enums/weather-type";
@ -43,7 +43,7 @@ describe("Abilities - Harvest", () => {
beforeEach(() => {
game = new GameManager(phaserGame);
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)
.startingLevel(100)
.battleStyle("single")
@ -53,15 +53,15 @@ describe("Abilities - Harvest", () => {
.enemyLevel(1)
.enemySpecies(Species.MAGIKARP)
.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 () => {
game.override.startingHeldItems([{ name: "BERRY", type: BerryType.LUM, count: 1 }]);
await game.classicMode.startBattle([Species.FEEBAS]);
game.move.select(Moves.SPLASH);
await game.move.selectEnemyMove(Moves.NUZZLE);
game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(MoveId.NUZZLE);
await game.phaseInterceptor.to("BerryPhase");
expect(getPlayerBerries()).toHaveLength(0);
expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toHaveLength(1);
@ -86,8 +86,8 @@ describe("Abilities - Harvest", () => {
expect(milotic).toBeDefined();
// Chug a few berries without harvest (should get tracked)
game.move.select(Moves.SPLASH);
await game.move.selectEnemyMove(Moves.NUZZLE);
game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(MoveId.NUZZLE);
await game.toNextTurn();
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
vi.spyOn(PostTurnRestoreBerryAbAttr.prototype, "canApplyPostTurn").mockReturnValueOnce(false);
game.override.ability(AbilityId.HARVEST);
game.move.select(Moves.GASTRO_ACID);
await game.move.selectEnemyMove(Moves.NUZZLE);
game.move.select(MoveId.GASTRO_ACID);
await game.move.selectEnemyMove(MoveId.NUZZLE);
await game.toNextTurn();
@ -108,8 +108,8 @@ describe("Abilities - Harvest", () => {
expect(getPlayerBerries()).toHaveLength(0);
// proc a high roll and we _should_ get a berry back!
game.move.select(Moves.SPLASH);
await game.move.selectEnemyMove(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(MoveId.SPLASH);
await game.toNextTurn();
expect(milotic.battleData.berriesEaten).toHaveLength(3);
@ -125,8 +125,8 @@ describe("Abilities - Harvest", () => {
const regieleki = game.scene.getPlayerPokemon()!;
regieleki.hp = 1;
game.move.select(Moves.SPLASH);
await game.move.selectEnemyMove(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(MoveId.SPLASH);
await game.doKillOpponents();
await game.phaseInterceptor.to("TurnEndPhase");
@ -145,16 +145,16 @@ describe("Abilities - Harvest", () => {
it("keeps harvested berries across reloads", async () => {
game.override
.startingHeldItems([{ name: "BERRY", type: BerryType.PETAYA, count: 1 }])
.moveset([Moves.SPLASH, Moves.EARTHQUAKE])
.enemyMoveset([Moves.SUPER_FANG, Moves.HEAL_PULSE])
.moveset([MoveId.SPLASH, MoveId.EARTHQUAKE])
.enemyMoveset([MoveId.SUPER_FANG, MoveId.HEAL_PULSE])
.enemyAbility(AbilityId.COMPOUND_EYES);
await game.classicMode.startBattle([Species.REGIELEKI]);
const regieleki = game.scene.getPlayerPokemon()!;
regieleki.hp = regieleki.getMaxHp() / 4 + 1;
game.move.select(Moves.SPLASH);
await game.move.selectEnemyMove(Moves.SUPER_FANG);
game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(MoveId.SUPER_FANG);
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
await game.toNextTurn();
@ -164,8 +164,8 @@ describe("Abilities - Harvest", () => {
expect(game.scene.getPlayerPokemon()?.getStatStage(Stat.SPATK)).toBe(1);
// heal up so harvest doesn't proc and kill enemy
game.move.select(Moves.EARTHQUAKE);
await game.move.selectEnemyMove(Moves.HEAL_PULSE);
game.move.select(MoveId.EARTHQUAKE);
await game.move.selectEnemyMove(MoveId.HEAL_PULSE);
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
await game.toNextWave();
@ -190,8 +190,8 @@ describe("Abilities - Harvest", () => {
const feebas = game.scene.getPlayerPokemon()!;
feebas.battleData.berriesEaten = [BerryType.LUM, BerryType.STARF];
game.move.select(Moves.SPLASH);
await game.move.selectEnemyMove(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(MoveId.SPLASH);
await game.phaseInterceptor.to("BerryPhase");
// Force RNG roll to hit the first berry we find that matches.
@ -218,8 +218,8 @@ describe("Abilities - Harvest", () => {
const player = game.scene.getPlayerPokemon()!;
player.battleData.berriesEaten = [BerryType.LUM, BerryType.STARF];
game.move.select(Moves.SPLASH);
await game.move.selectEnemyMove(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnEndPhase");
expectBerriesContaining(...initBerries);
@ -230,8 +230,8 @@ describe("Abilities - Harvest", () => {
game.override.startingHeldItems([{ name: "BERRY", type: BerryType.STARF, count: 3 }]);
await game.classicMode.startBattle([Species.FEEBAS]);
game.move.select(Moves.SPLASH);
await game.move.selectEnemyMove(Moves.INCINERATE);
game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(MoveId.INCINERATE);
await game.phaseInterceptor.to("TurnEndPhase");
expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toEqual([]);
@ -241,8 +241,8 @@ describe("Abilities - Harvest", () => {
game.override.startingHeldItems([{ name: "BERRY", type: BerryType.STARF, count: 3 }]);
await game.classicMode.startBattle([Species.FEEBAS]);
game.move.select(Moves.SPLASH);
await game.move.selectEnemyMove(Moves.KNOCK_OFF);
game.move.select(MoveId.SPLASH);
await game.move.selectEnemyMove(MoveId.KNOCK_OFF);
await game.phaseInterceptor.to("TurnEndPhase");
expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toEqual([]);
@ -250,11 +250,11 @@ describe("Abilities - Harvest", () => {
it("can restore berries eaten by Teatime", async () => {
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]);
// nom nom the berr berr yay yay
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnEndPhase");
expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toEqual([]);
@ -263,11 +263,11 @@ describe("Abilities - Harvest", () => {
it("cannot restore Plucked berries for either side", async () => {
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]);
// gobble gobble gobble
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("BerryPhase");
// pluck triggers harvest for neither side
@ -289,7 +289,7 @@ describe("Abilities - Harvest", () => {
game.override.startingHeldItems(initBerries).startingModifier([{ name: "BERRY_POUCH", count: 1 }]);
await game.classicMode.startBattle([Species.FEEBAS]);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
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)
@ -307,8 +307,8 @@ describe("Abilities - Harvest", () => {
player.hp = 1;
// steal a sitrus and immediately consume it
game.move.select(Moves.FALSE_SWIPE);
await game.move.selectEnemyMove(Moves.SPLASH);
game.move.select(MoveId.FALSE_SWIPE);
await game.move.selectEnemyMove(MoveId.SPLASH);
await game.phaseInterceptor.to("BerryPhase");
expect(player.battleData.berriesEaten).toEqual([BerryType.SITRUS]);
@ -320,10 +320,10 @@ describe("Abilities - Harvest", () => {
// TODO: Enable once fling actually works...???
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]);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to("TurnEndPhase");
expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toBe([]);
@ -336,7 +336,7 @@ describe("Abilities - Harvest", () => {
game.override.startingHeldItems(initBerries);
await game.classicMode.startBattle([Species.FEEBAS]);
game.move.select(Moves.NATURAL_GIFT);
game.move.select(MoveId.NATURAL_GIFT);
await game.phaseInterceptor.to("TurnEndPhase");
expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toHaveLength(0);

View File

@ -1,5 +1,5 @@
import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import { StatusEffect } from "#enums/status-effect";
import GameManager from "#test/testUtils/gameManager";
@ -30,13 +30,13 @@ describe("Abilities - Healer", () => {
beforeEach(() => {
game = new GameManager(phaserGame);
game.override
.moveset([Moves.SPLASH])
.moveset([MoveId.SPLASH])
.ability(AbilityId.BALL_FETCH)
.battleStyle("double")
.disableCrits()
.enemySpecies(Species.MAGIKARP)
.enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH);
.enemyMoveset(MoveId.SPLASH);
healerAttr = allAbilities[AbilityId.HEALER].getAttrs(PostTurnResetStatusAbAttr)[0];
healerAttrSpy = vi
@ -45,14 +45,14 @@ describe("Abilities - Healer", () => {
});
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]);
const user = game.scene.getPlayerPokemon()!;
// Only want one magikarp to have the ability.
vi.spyOn(user, "getAbility").mockReturnValue(allAbilities[AbilityId.HEALER]);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
// faint the ally
game.move.select(Moves.LUNAR_DANCE, 1);
game.move.select(MoveId.LUNAR_DANCE, 1);
const abSpy = vi.spyOn(healerAttr, "canApplyPostTurn");
await game.phaseInterceptor.to("TurnEndPhase");
@ -70,8 +70,8 @@ describe("Abilities - Healer", () => {
// Only want one magikarp to have the ability.
vi.spyOn(user, "getAbility").mockReturnValue(allAbilities[AbilityId.HEALER]);
expect(ally.trySetStatus(StatusEffect.BURN)).toBe(true);
game.move.select(Moves.SPLASH);
game.move.select(Moves.SPLASH, 1);
game.move.select(MoveId.SPLASH);
game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("TurnEndPhase");
await game.toNextTurn();
@ -86,8 +86,8 @@ describe("Abilities - Healer", () => {
// Only want one magikarp to have the ability.
vi.spyOn(user, "getAbility").mockReturnValue(allAbilities[AbilityId.HEALER]);
expect(ally.trySetStatus(StatusEffect.BURN)).toBe(true);
game.move.select(Moves.SPLASH);
game.move.select(Moves.SPLASH, 1);
game.move.select(MoveId.SPLASH);
game.move.select(MoveId.SPLASH, 1);
await game.phaseInterceptor.to("TurnEndPhase");
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 { toDmgValue } from "#app/utils/common";
import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
@ -29,11 +29,11 @@ describe("Abilities - Heatproof", () => {
.disableCrits()
.enemySpecies(Species.CHARMANDER)
.enemyAbility(AbilityId.HEATPROOF)
.enemyMoveset(Moves.SPLASH)
.enemyMoveset(MoveId.SPLASH)
.enemyLevel(100)
.starterSpecies(Species.CHANDELURE)
.ability(AbilityId.BALL_FETCH)
.moveset([Moves.FLAMETHROWER, Moves.SPLASH])
.moveset([MoveId.FLAMETHROWER, MoveId.SPLASH])
.startingLevel(100);
});
@ -44,14 +44,14 @@ describe("Abilities - Heatproof", () => {
const initialHP = 1000;
enemy.hp = initialHP;
game.move.select(Moves.FLAMETHROWER);
game.move.select(MoveId.FLAMETHROWER);
await game.phaseInterceptor.to(TurnEndPhase);
const heatproofDamage = initialHP - enemy.hp;
enemy.hp = initialHP;
game.override.enemyAbility(AbilityId.BALL_FETCH);
game.move.select(Moves.FLAMETHROWER);
game.move.select(MoveId.FLAMETHROWER);
await game.phaseInterceptor.to(TurnEndPhase);
const regularDamage = initialHP - enemy.hp;
@ -65,7 +65,7 @@ describe("Abilities - Heatproof", () => {
const enemy = game.scene.getEnemyPokemon()!;
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.toNextTurn();
// Normal burn damage is /16

View File

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

View File

@ -1,7 +1,7 @@
import { allMoves } from "#app/data/data-lists";
import { AbilityId } from "#enums/ability-id";
import { Stat } from "#app/enums/stat";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
@ -25,10 +25,10 @@ describe("Abilities - Hustle", () => {
game = new GameManager(phaserGame);
game.override
.ability(AbilityId.HUSTLE)
.moveset([Moves.TACKLE, Moves.GIGA_DRAIN, Moves.FISSURE])
.moveset([MoveId.TACKLE, MoveId.GIGA_DRAIN, MoveId.FISSURE])
.disableCrits()
.battleStyle("single")
.enemyMoveset(Moves.SPLASH)
.enemyMoveset(MoveId.SPLASH)
.enemySpecies(Species.SHUCKLE)
.enemyAbility(AbilityId.BALL_FETCH);
});
@ -40,7 +40,7 @@ describe("Abilities - Hustle", () => {
vi.spyOn(pikachu, "getEffectiveStat");
game.move.select(Moves.TACKLE);
game.move.select(MoveId.TACKLE);
await game.move.forceHit();
await game.phaseInterceptor.to("DamageAnimPhase");
@ -53,7 +53,7 @@ describe("Abilities - Hustle", () => {
vi.spyOn(pikachu, "getAccuracyMultiplier");
game.move.select(Moves.TACKLE);
game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.to("MoveEffectPhase");
expect(pikachu.getAccuracyMultiplier).toHaveReturnedWith(0.8);
@ -67,7 +67,7 @@ describe("Abilities - Hustle", () => {
vi.spyOn(pikachu, "getEffectiveStat");
vi.spyOn(pikachu, "getAccuracyMultiplier");
game.move.select(Moves.GIGA_DRAIN);
game.move.select(MoveId.GIGA_DRAIN);
await game.phaseInterceptor.to("DamageAnimPhase");
expect(pikachu.getEffectiveStat).toHaveReturnedWith(spatk);
@ -83,13 +83,13 @@ describe("Abilities - Hustle", () => {
const enemyPokemon = game.scene.getEnemyPokemon()!;
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");
expect(enemyPokemon.turnData.damageTaken).toBe(enemyPokemon.getMaxHp());
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 { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
@ -24,11 +24,11 @@ describe("Abilities - Hyper Cutter", () => {
game = new GameManager(phaserGame);
game.override
.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)
.enemySpecies(Species.SHUCKLE)
.enemyAbility(AbilityId.HYPER_CUTTER)
.enemyMoveset(Moves.SPLASH);
.enemyMoveset(MoveId.SPLASH);
});
// Reference Link: https://bulbapedia.bulbagarden.net/wiki/Hyper_Cutter_(Ability)
@ -38,16 +38,16 @@ describe("Abilities - Hyper Cutter", () => {
const enemy = game.scene.getEnemyPokemon()!;
game.move.select(Moves.OCTOLOCK);
game.move.select(MoveId.OCTOLOCK);
await game.toNextTurn();
game.move.select(Moves.DEFOG);
game.move.select(MoveId.DEFOG);
await game.toNextTurn();
game.move.select(Moves.NOBLE_ROAR);
game.move.select(MoveId.NOBLE_ROAR);
await game.toNextTurn();
game.move.select(Moves.SAND_ATTACK);
game.move.select(MoveId.SAND_ATTACK);
await game.toNextTurn();
game.override.moveset([Moves.STRING_SHOT]);
game.move.select(Moves.STRING_SHOT);
game.override.moveset([MoveId.STRING_SHOT]);
game.move.select(MoveId.STRING_SHOT);
await game.toNextTurn();
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 { AbilityId } from "#enums/ability-id";
import { BattlerTagType } from "#enums/battler-tag-type";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
@ -33,13 +33,13 @@ describe("Abilities - Ice Face", () => {
game.override.battleStyle("single");
game.override.enemySpecies(Species.EISCUE);
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 () => {
await game.classicMode.startBattle([Species.HITMONLEE]);
game.move.select(Moves.TACKLE);
game.move.select(MoveId.TACKLE);
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 () => {
game.override.moveset([Moves.SURGING_STRIKES]);
game.override.moveset([MoveId.SURGING_STRIKES]);
game.override.enemyLevel(1);
await game.classicMode.startBattle([Species.HITMONLEE]);
game.move.select(Moves.SURGING_STRIKES);
game.move.select(MoveId.SURGING_STRIKES);
const eiscue = game.scene.getEnemyPokemon()!;
expect(eiscue.getTag(BattlerTagType.ICE_FACE)).toBeDefined();
@ -81,7 +81,7 @@ describe("Abilities - Ice Face", () => {
it("takes damage from special moves", async () => {
await game.classicMode.startBattle([Species.MAGIKARP]);
game.move.select(Moves.ICE_BEAM);
game.move.select(MoveId.ICE_BEAM);
await game.phaseInterceptor.to(MoveEndPhase);
@ -95,7 +95,7 @@ describe("Abilities - Ice Face", () => {
it("takes effects from status moves", async () => {
await game.classicMode.startBattle([Species.MAGIKARP]);
game.move.select(Moves.TOXIC_THREAD);
game.move.select(MoveId.TOXIC_THREAD);
await game.phaseInterceptor.to(MoveEndPhase);
@ -106,11 +106,11 @@ describe("Abilities - Ice Face", () => {
});
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]);
game.move.select(Moves.QUICK_ATTACK);
game.move.select(MoveId.QUICK_ATTACK);
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 () => {
game.override.enemyMoveset(Moves.TACKLE).moveset([Moves.SNOWSCAPE]);
game.override.enemyMoveset(MoveId.TACKLE).moveset([MoveId.SNOWSCAPE]);
await game.classicMode.startBattle([Species.EISCUE, Species.NINJASK]);
game.move.select(Moves.SNOWSCAPE);
game.move.select(MoveId.SNOWSCAPE);
await game.phaseInterceptor.to(TurnEndPhase);
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 () => {
game.override.enemySpecies(Species.SHUCKLE).enemyMoveset(Moves.TACKLE);
game.override.enemySpecies(Species.SHUCKLE).enemyMoveset(MoveId.TACKLE);
await game.classicMode.startBattle([Species.EISCUE]);
game.move.select(Moves.HAIL);
game.move.select(MoveId.HAIL);
const eiscue = game.scene.getPlayerPokemon()!;
await game.phaseInterceptor.to(QuietFormChangePhase);
@ -172,11 +172,11 @@ describe("Abilities - Ice Face", () => {
});
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]);
game.move.select(Moves.ICE_BEAM);
game.move.select(MoveId.ICE_BEAM);
await game.phaseInterceptor.to(TurnEndPhase);
let eiscue = game.scene.getPlayerPokemon()!;
@ -210,7 +210,7 @@ describe("Abilities - Ice Face", () => {
expect(eiscue.formIndex).toBe(noiceForm);
expect(eiscue.getTag(BattlerTagType.ICE_FACE)).toBeUndefined();
game.move.select(Moves.ICE_BEAM);
game.move.select(MoveId.ICE_BEAM);
await game.doKillOpponents();
await game.phaseInterceptor.to(TurnEndPhase);
game.doSelectModifier();
@ -221,10 +221,10 @@ describe("Abilities - Ice Face", () => {
});
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();
game.move.select(Moves.POWER_TRIP);
game.move.select(MoveId.POWER_TRIP);
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
await game.toNextTurn();
@ -232,11 +232,11 @@ describe("Abilities - Ice Face", () => {
});
it("cannot be suppressed", async () => {
game.override.moveset([Moves.GASTRO_ACID]);
game.override.moveset([MoveId.GASTRO_ACID]);
await game.classicMode.startBattle([Species.MAGIKARP]);
game.move.select(Moves.GASTRO_ACID);
game.move.select(MoveId.GASTRO_ACID);
await game.phaseInterceptor.to(TurnEndPhase);
@ -248,11 +248,11 @@ describe("Abilities - Ice Face", () => {
});
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]);
game.move.select(Moves.SKILL_SWAP);
game.move.select(MoveId.SKILL_SWAP);
await game.phaseInterceptor.to(TurnEndPhase);
@ -268,7 +268,7 @@ describe("Abilities - Ice Face", () => {
await game.classicMode.startBattle([Species.MAGIKARP]);
game.move.select(Moves.SIMPLE_BEAM);
game.move.select(MoveId.SIMPLE_BEAM);
await game.phaseInterceptor.to(TurnInitPhase);

View File

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

View File

@ -1,7 +1,7 @@
import { Gender } from "#app/data/gender";
import { PokeballType } from "#app/enums/pokeball";
import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
@ -27,9 +27,9 @@ describe("Abilities - Illusion", () => {
.battleStyle("single")
.enemySpecies(Species.ZORUA)
.enemyAbility(AbilityId.ILLUSION)
.enemyMoveset(Moves.TACKLE)
.enemyMoveset(MoveId.TACKLE)
.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 }]);
});
@ -44,7 +44,7 @@ describe("Abilities - Illusion", () => {
it("break after receiving damaging move", async () => {
await game.classicMode.startBattle([Species.FEEBAS]);
game.move.select(Moves.TACKLE);
game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.to("TurnEndPhase");
@ -56,7 +56,7 @@ describe("Abilities - Illusion", () => {
it("break after getting ability changed", async () => {
await game.classicMode.startBattle([Species.FEEBAS]);
game.move.select(Moves.WORRY_SEED);
game.move.select(MoveId.WORRY_SEED);
await game.phaseInterceptor.to("TurnEndPhase");
@ -78,8 +78,8 @@ describe("Abilities - Illusion", () => {
game.override
.enemyAbility(AbilityId.NEUTRALIZING_GAS)
.ability(AbilityId.ILLUSION)
.moveset(Moves.SPLASH)
.enemyMoveset(Moves.SPLASH);
.moveset(MoveId.SPLASH)
.enemyMoveset(MoveId.SPLASH);
await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS, Species.MAGIKARP]);
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 () => {
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]);
const enemy = game.scene.getEnemyPokemon()!;
@ -119,12 +119,12 @@ describe("Abilities - Illusion", () => {
it("does not break from indirect damage", async () => {
game.override.enemySpecies(Species.GIGALITH);
game.override.enemyAbility(AbilityId.SAND_STREAM);
game.override.enemyMoveset(Moves.WILL_O_WISP);
game.override.moveset([Moves.FLARE_BLITZ]);
game.override.enemyMoveset(MoveId.WILL_O_WISP);
game.override.moveset([MoveId.FLARE_BLITZ]);
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");
@ -134,7 +134,7 @@ describe("Abilities - Illusion", () => {
});
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]);
const axew = game.scene.getPlayerParty().at(2)!;
axew.shiny = true;
@ -156,13 +156,13 @@ describe("Abilities - Illusion", () => {
});
it("breaks when suppressed", async () => {
game.override.moveset(Moves.GASTRO_ACID);
game.override.moveset(MoveId.GASTRO_ACID);
await game.classicMode.startBattle([Species.MAGIKARP]);
const zorua = game.scene.getEnemyPokemon()!;
expect(!!zorua.summonData?.illusion).toBe(true);
game.move.select(Moves.GASTRO_ACID);
game.move.select(MoveId.GASTRO_ACID);
await game.phaseInterceptor.to("BerryPhase");
expect(zorua.isFullHp()).toBe(true);

View File

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

View File

@ -3,7 +3,7 @@ import Phaser from "phaser";
import GameManager from "#test/testUtils/gameManager";
import { Species } from "#enums/species";
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 { AbilityId } from "#enums/ability-id";
@ -30,15 +30,15 @@ describe("Abilities - Imposter", () => {
.enemyLevel(200)
.enemyAbility(AbilityId.BEAST_BOOST)
.enemyPassiveAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH)
.enemyMoveset(MoveId.SPLASH)
.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 () => {
await game.classicMode.startBattle([Species.DITTO]);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase);
const player = game.scene.getPlayerPokemon()!;
@ -75,7 +75,7 @@ describe("Abilities - Imposter", () => {
});
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]);
@ -85,7 +85,7 @@ describe("Abilities - Imposter", () => {
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);
game.move.select(Moves.TACKLE);
game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.to(TurnEndPhase);
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 () => {
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]);
const player = game.scene.getPlayerPokemon()!;
game.move.select(Moves.TACKLE);
game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.to(TurnEndPhase);
player.getMoveset().forEach(move => {
// Should set correct maximum PP without touching `ppUp`
if (move) {
if (move.moveId === Moves.SKETCH) {
if (move.moveId === MoveId.SKETCH) {
expect(move.getMovePp()).toBe(1);
} else {
expect(move.getMovePp()).toBe(5);
@ -122,21 +122,21 @@ describe("Abilities - Imposter", () => {
await game.classicMode.startBattle([Species.DITTO]);
game.move.select(Moves.TACKLE);
game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.to("MoveEndPhase");
expect(game.scene.getEnemyPokemon()?.getStatStage(Stat.ATK)).toBe(-1);
});
it("should persist transformed attributes across reloads", async () => {
game.override.moveset([Moves.ABSORB]);
game.override.moveset([MoveId.ABSORB]);
await game.classicMode.startBattle([Species.DITTO]);
const player = game.scene.getPlayerPokemon()!;
const enemy = game.scene.getEnemyPokemon()!;
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.doKillOpponents();
await game.toNextWave();
@ -158,11 +158,11 @@ describe("Abilities - Imposter", () => {
}
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 () => {
game.override.moveset([Moves.ABSORB]);
game.override.moveset([MoveId.ABSORB]);
game.override.enemySpecies(Species.UNOWN);
await game.classicMode.startBattle([Species.DITTO]);
@ -172,7 +172,7 @@ describe("Abilities - Imposter", () => {
enemy.species.forms[5];
enemy.species.formIndex = 5;
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.doKillOpponents();
await game.toNextWave();

View File

@ -5,7 +5,7 @@ import { BattlerTagType } from "#enums/battler-tag-type";
import { Stat } from "#enums/stat";
import { StatusEffect } from "#enums/status-effect";
import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
@ -28,13 +28,13 @@ describe("Abilities - Infiltrator", () => {
beforeEach(() => {
game = new GameManager(phaserGame);
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)
.battleStyle("single")
.disableCrits()
.enemySpecies(Species.SNORLAX)
.enemyAbility(AbilityId.BALL_FETCH)
.enemyMoveset(Moves.SPLASH)
.enemyMoveset(MoveId.SPLASH)
.startingLevel(100)
.enemyLevel(100);
});
@ -43,17 +43,17 @@ describe("Abilities - Infiltrator", () => {
{
effectName: "Light Screen",
tagType: ArenaTagType.LIGHT_SCREEN,
move: Moves.WATER_GUN,
move: MoveId.WATER_GUN,
},
{
effectName: "Reflect",
tagType: ArenaTagType.REFLECT,
move: Moves.TACKLE,
move: MoveId.TACKLE,
},
{
effectName: "Aurora Veil",
tagType: ArenaTagType.AURORA_VEIL,
move: Moves.TACKLE,
move: MoveId.TACKLE,
},
])("should bypass the target's $effectName", async ({ tagType, move }) => {
await game.classicMode.startBattle([Species.MAGIKARP]);
@ -63,7 +63,7 @@ describe("Abilities - Infiltrator", () => {
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;
@ -77,9 +77,9 @@ describe("Abilities - Infiltrator", () => {
const player = game.scene.getPlayerPokemon()!;
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);
expect(enemy.status?.effect).toBe(StatusEffect.SLEEP);
@ -93,9 +93,9 @@ describe("Abilities - Infiltrator", () => {
const player = game.scene.getPlayerPokemon()!;
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");
expect(enemy.getStatStage(Stat.ATK)).toBe(-1);
@ -108,9 +108,9 @@ describe("Abilities - Infiltrator", () => {
const player = game.scene.getPlayerPokemon()!;
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");
expect(enemy.getStatStage(Stat.ATK)).toBe(-1);

View File

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

View File

@ -5,7 +5,7 @@ import { UiMode } from "#enums/ui-mode";
import { Stat } from "#enums/stat";
import { getMovePosition } from "#test/testUtils/gameManagerUtils";
import { AbilityId } from "#enums/ability-id";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
describe("Abilities - Intimidate", () => {
@ -31,7 +31,7 @@ describe("Abilities - Intimidate", () => {
.enemyPassiveAbility(AbilityId.HYDRATION)
.ability(AbilityId.INTIMIDATE)
.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 () => {
@ -89,7 +89,7 @@ describe("Abilities - Intimidate", () => {
it("should not activate again if there is no switch or new entry", async () => {
game.override.startingWave(2);
game.override.moveset([Moves.SPLASH]);
game.override.moveset([MoveId.SPLASH]);
await game.classicMode.startBattle([Species.MIGHTYENA, Species.POOCHYENA]);
const playerPokemon = game.scene.getPlayerPokemon()!;
@ -98,7 +98,7 @@ describe("Abilities - Intimidate", () => {
expect(enemyPokemon.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();
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-1);
@ -106,7 +106,7 @@ describe("Abilities - Intimidate", () => {
}, 20000);
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]);
const playerPokemon = game.scene.getPlayerPokemon()!;
@ -115,7 +115,7 @@ describe("Abilities - Intimidate", () => {
expect(enemyPokemon.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();
enemyPokemon = game.scene.getEnemyPokemon()!;
@ -123,7 +123,7 @@ describe("Abilities - Intimidate", () => {
expect(playerPokemon.getStatStage(Stat.ATK)).toBe(-2);
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.toNextTurn();
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 { BattlerTagType } from "#enums/battler-tag-type";
import { Biome } from "#enums/biome";
import { Moves } from "#enums/moves";
import { MoveId } from "#enums/moves";
import { Species } from "#enums/species";
import { WeatherType } from "#enums/weather-type";
import GameManager from "#test/testUtils/gameManager";
@ -34,43 +34,43 @@ describe("Abilities - Libero", () => {
.ability(AbilityId.LIBERO)
.startingLevel(100)
.enemySpecies(Species.RATTATA)
.enemyMoveset(Moves.ENDURE);
.enemyMoveset(MoveId.ENDURE);
});
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]);
const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase);
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.SPLASH);
testPokemonTypeMatchesDefaultMoveType(leadPokemon, MoveId.SPLASH);
});
// Test for Gen9+ functionality, we are using previous funcionality
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]);
let leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
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);
expect(leadPokemon.waveData.abilitiesApplied).toContain(AbilityId.LIBERO);
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);
await game.toNextTurn();
@ -82,14 +82,14 @@ describe("Abilities - Libero", () => {
leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
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 () => {
game.override.moveset([Moves.WEATHER_BALL]);
game.override.moveset([MoveId.WEATHER_BALL]);
await game.classicMode.startBattle([Species.MAGIKARP]);
@ -97,7 +97,7 @@ describe("Abilities - Libero", () => {
expect(leadPokemon).not.toBe(undefined);
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);
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 () => {
game.override.moveset([Moves.TACKLE]);
game.override.moveset([MoveId.TACKLE]);
game.override.passiveAbility(AbilityId.REFRIGERATE);
await game.classicMode.startBattle([Species.MAGIKARP]);
@ -116,7 +116,7 @@ describe("Abilities - Libero", () => {
const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.TACKLE);
game.move.select(MoveId.TACKLE);
await game.phaseInterceptor.to(TurnEndPhase);
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 () => {
game.override.moveset([Moves.NATURE_POWER]);
game.override.moveset([MoveId.NATURE_POWER]);
await game.classicMode.startBattle([Species.MAGIKARP]);
@ -135,60 +135,60 @@ describe("Abilities - Libero", () => {
expect(leadPokemon).not.toBe(undefined);
game.scene.arena.biomeType = Biome.MOUNTAIN;
game.move.select(Moves.NATURE_POWER);
game.move.select(MoveId.NATURE_POWER);
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 () => {
game.override.moveset([Moves.DIG]);
game.override.moveset([MoveId.DIG]);
await game.classicMode.startBattle([Species.MAGIKARP]);
const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.DIG);
game.move.select(MoveId.DIG);
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 () => {
game.override.moveset([Moves.TACKLE]);
game.override.enemyMoveset(Moves.SPLASH);
game.override.moveset([MoveId.TACKLE]);
game.override.enemyMoveset(MoveId.SPLASH);
await game.classicMode.startBattle([Species.MAGIKARP]);
const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.TACKLE);
game.move.select(MoveId.TACKLE);
await game.move.forceMiss();
await game.phaseInterceptor.to(TurnEndPhase);
const enemyPokemon = game.scene.getEnemyPokemon()!;
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 () => {
game.override.moveset([Moves.TACKLE]).enemyMoveset(Moves.PROTECT);
game.override.moveset([MoveId.TACKLE]).enemyMoveset(MoveId.PROTECT);
await game.classicMode.startBattle([Species.MAGIKARP]);
const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.TACKLE);
game.move.select(MoveId.TACKLE);
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 () => {
game.override.moveset([Moves.TACKLE]);
game.override.moveset([MoveId.TACKLE]);
game.override.enemySpecies(Species.GASTLY);
await game.classicMode.startBattle([Species.MAGIKARP]);
@ -196,29 +196,29 @@ describe("Abilities - Libero", () => {
const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.TACKLE);
game.move.select(MoveId.TACKLE);
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 () => {
game.override.moveset([Moves.SPLASH]);
game.override.moveset([MoveId.SPLASH]);
await game.classicMode.startBattle([Species.MAGIKARP]);
const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined);
leadPokemon.summonData.types = [allMoves[Moves.SPLASH].type];
game.move.select(Moves.SPLASH);
leadPokemon.summonData.types = [allMoves[MoveId.SPLASH].type];
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase);
expect(leadPokemon.waveData.abilitiesApplied).not.toContain(AbilityId.LIBERO);
});
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]);
@ -227,42 +227,42 @@ describe("Abilities - Libero", () => {
leadPokemon.isTerastallized = true;
game.move.select(Moves.SPLASH);
game.move.select(MoveId.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase);
expect(leadPokemon.waveData.abilitiesApplied).not.toContain(AbilityId.LIBERO);
});
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]);
const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.STRUGGLE);
game.move.select(MoveId.STRUGGLE);
await game.phaseInterceptor.to(TurnEndPhase);
expect(leadPokemon.waveData.abilitiesApplied).not.toContain(AbilityId.LIBERO);
});
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]);
const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.BURN_UP);
game.move.select(MoveId.BURN_UP);
await game.phaseInterceptor.to(TurnEndPhase);
expect(leadPokemon.waveData.abilitiesApplied).not.toContain(AbilityId.LIBERO);
});
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);
await game.classicMode.startBattle([Species.MAGIKARP]);
@ -270,29 +270,29 @@ describe("Abilities - Libero", () => {
const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.TRICK_OR_TREAT);
game.move.select(MoveId.TRICK_OR_TREAT);
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 () => {
game.override.moveset([Moves.CURSE]);
game.override.moveset([MoveId.CURSE]);
await game.classicMode.startBattle([Species.MAGIKARP]);
const leadPokemon = game.scene.getPlayerPokemon()!;
expect(leadPokemon).not.toBe(undefined);
game.move.select(Moves.CURSE);
game.move.select(MoveId.CURSE);
await game.phaseInterceptor.to(TurnEndPhase);
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.CURSE);
testPokemonTypeMatchesDefaultMoveType(leadPokemon, MoveId.CURSE);
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.getTypes()).toHaveLength(1);
const pokemonType = PokemonType[pokemon.getTypes()[0]],

View File

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

View File

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

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