Compare commits
9 Commits
be2d9d90b8
...
7f4e3f6553
Author | SHA1 | Date | |
---|---|---|---|
|
7f4e3f6553 | ||
|
31d3bec55e | ||
|
834255447d | ||
|
19e179d96c | ||
|
aadc0a8576 | ||
|
f3ced7e814 | ||
|
cebd449335 | ||
|
8835ae0299 | ||
|
a537113c8f |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 237 B After Width: | Height: | Size: 179 B |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 237 B After Width: | Height: | Size: 179 B |
@ -2755,12 +2755,18 @@ export default class BattleScene extends SceneBase {
|
||||
keys.push("pkmn__" + p.species.getSpriteId(p.gender === Gender.FEMALE, p.species.formIndex, p.shiny, p.variant));
|
||||
keys.push("pkmn__" + p.species.getSpriteId(p.gender === Gender.FEMALE, p.species.formIndex, p.shiny, p.variant, true));
|
||||
keys.push("cry/" + p.species.getCryKey(p.species.formIndex));
|
||||
if (p.fusionSpecies && p.getSpeciesForm() !== p.getFusionSpeciesForm()) {
|
||||
keys.push("cry/"+p.getFusionSpeciesForm().getCryKey(p.fusionSpecies.formIndex));
|
||||
}
|
||||
});
|
||||
// enemyParty has to be operated on separately from playerParty because playerPokemon =/= enemyPokemon
|
||||
const enemyParty = this.getEnemyParty();
|
||||
enemyParty.forEach(p => {
|
||||
keys.push(p.species.getSpriteKey(p.gender === Gender.FEMALE, p.species.formIndex, p.shiny, p.variant));
|
||||
keys.push("cry/" + p.species.getCryKey(p.species.formIndex));
|
||||
if (p.fusionSpecies && p.getSpeciesForm() !== p.getFusionSpeciesForm()) {
|
||||
keys.push("cry/"+p.getFusionSpeciesForm().getCryKey(p.fusionSpecies.formIndex));
|
||||
}
|
||||
});
|
||||
return keys;
|
||||
}
|
||||
|
@ -310,7 +310,7 @@ export class ReceivedMoveDamageMultiplierAbAttr extends PreDefendAbAttr {
|
||||
|
||||
export class ReceivedTypeDamageMultiplierAbAttr extends ReceivedMoveDamageMultiplierAbAttr {
|
||||
constructor(moveType: Type, damageMultiplier: number) {
|
||||
super((user, target, move) => move.type === moveType, damageMultiplier);
|
||||
super((target, user, move) => user.getMoveType(move) === moveType, damageMultiplier);
|
||||
}
|
||||
}
|
||||
|
||||
@ -455,7 +455,7 @@ export class NonSuperEffectiveImmunityAbAttr extends TypeImmunityAbAttr {
|
||||
}
|
||||
|
||||
applyPreDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||
if (move instanceof AttackMove && pokemon.getAttackTypeEffectiveness(pokemon.getMoveType(move), attacker) < 2) {
|
||||
if (move instanceof AttackMove && pokemon.getAttackTypeEffectiveness(attacker.getMoveType(move), attacker) < 2) {
|
||||
cancelled.value = true; // Suppresses "No Effect" message
|
||||
(args[0] as Utils.NumberHolder).value = 0;
|
||||
return true;
|
||||
@ -1462,7 +1462,7 @@ export class MovePowerBoostAbAttr extends VariableMovePowerAbAttr {
|
||||
|
||||
export class MoveTypePowerBoostAbAttr extends MovePowerBoostAbAttr {
|
||||
constructor(boostedType: Type, powerMultiplier?: number) {
|
||||
super((pokemon, defender, move) => move.type === boostedType, powerMultiplier || 1.5);
|
||||
super((pokemon, defender, move) => pokemon?.getMoveType(move) === boostedType, powerMultiplier || 1.5);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1546,7 +1546,7 @@ export class PreAttackFieldMoveTypePowerBoostAbAttr extends FieldMovePowerBoostA
|
||||
* @param powerMultiplier - The multiplier to apply to the move's power, defaults to 1.5 if not provided.
|
||||
*/
|
||||
constructor(boostedType: Type, powerMultiplier?: number) {
|
||||
super((pokemon, defender, move) => move.type === boostedType, powerMultiplier || 1.5);
|
||||
super((pokemon, defender, move) => pokemon?.getMoveType(move) === boostedType, powerMultiplier || 1.5);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5100,9 +5100,9 @@ export function initAbilities() {
|
||||
.ignorable(),
|
||||
new Ability(Abilities.TINTED_LENS, 4)
|
||||
//@ts-ignore
|
||||
.attr(DamageBoostAbAttr, 2, (user, target, move) => target.getAttackTypeEffectiveness(move.type, user) <= 0.5), // TODO: fix TS issues
|
||||
.attr(DamageBoostAbAttr, 2, (user, target, move) => target?.getMoveEffectiveness(user, move) <= 0.5), // TODO: fix TS issues
|
||||
new Ability(Abilities.FILTER, 4)
|
||||
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getAttackTypeEffectiveness(move.type, user) >= 2, 0.75)
|
||||
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getMoveEffectiveness(user, move) >= 2, 0.75)
|
||||
.ignorable(),
|
||||
new Ability(Abilities.SLOW_START, 4)
|
||||
.attr(PostSummonAddBattlerTagAbAttr, BattlerTagType.SLOW_START, 5),
|
||||
@ -5118,7 +5118,7 @@ export function initAbilities() {
|
||||
.attr(PostWeatherLapseHealAbAttr, 1, WeatherType.HAIL, WeatherType.SNOW)
|
||||
.partial(), // Healing not blocked by Heal Block
|
||||
new Ability(Abilities.SOLID_ROCK, 4)
|
||||
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getAttackTypeEffectiveness(move.type, user) >= 2, 0.75)
|
||||
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getMoveEffectiveness(user, move) >= 2, 0.75)
|
||||
.ignorable(),
|
||||
new Ability(Abilities.SNOW_WARNING, 4)
|
||||
.attr(PostSummonWeatherChangeAbAttr, WeatherType.SNOW)
|
||||
@ -5236,10 +5236,13 @@ export function initAbilities() {
|
||||
new Ability(Abilities.MOXIE, 5)
|
||||
.attr(PostVictoryStatStageChangeAbAttr, Stat.ATK, 1),
|
||||
new Ability(Abilities.JUSTIFIED, 5)
|
||||
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => move.type === Type.DARK && move.category !== MoveCategory.STATUS, Stat.ATK, 1),
|
||||
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => user.getMoveType(move) === Type.DARK && move.category !== MoveCategory.STATUS, Stat.ATK, 1),
|
||||
new Ability(Abilities.RATTLED, 5)
|
||||
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => move.category !== MoveCategory.STATUS && (move.type === Type.DARK || move.type === Type.BUG ||
|
||||
move.type === Type.GHOST), Stat.SPD, 1)
|
||||
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => {
|
||||
const moveType = user.getMoveType(move);
|
||||
return move.category !== MoveCategory.STATUS
|
||||
&& (moveType === Type.DARK || moveType === Type.BUG || moveType === Type.GHOST);
|
||||
}, Stat.SPD, 1)
|
||||
.attr(PostIntimidateStatStageChangeAbAttr, [Stat.SPD], 1),
|
||||
new Ability(Abilities.MAGIC_BOUNCE, 5)
|
||||
.ignorable()
|
||||
@ -5313,7 +5316,7 @@ export function initAbilities() {
|
||||
.attr(UnsuppressableAbilityAbAttr)
|
||||
.attr(NoFusionAbilityAbAttr),
|
||||
new Ability(Abilities.GALE_WINGS, 6)
|
||||
.attr(ChangeMovePriorityAbAttr, (pokemon, move) => pokemon.isFullHp() && move.type === Type.FLYING, 1),
|
||||
.attr(ChangeMovePriorityAbAttr, (pokemon, move) => pokemon.isFullHp() && pokemon.getMoveType(move) === Type.FLYING, 1),
|
||||
new Ability(Abilities.MEGA_LAUNCHER, 6)
|
||||
.attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.PULSE_MOVE), 1.5),
|
||||
new Ability(Abilities.GRASS_PELT, 6)
|
||||
@ -5368,7 +5371,7 @@ export function initAbilities() {
|
||||
.condition(getSheerForceHitDisableAbCondition())
|
||||
.unimplemented(),
|
||||
new Ability(Abilities.WATER_COMPACTION, 7)
|
||||
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => move.type === Type.WATER && move.category !== MoveCategory.STATUS, Stat.DEF, 2),
|
||||
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => user.getMoveType(move) === Type.WATER && move.category !== MoveCategory.STATUS, Stat.DEF, 2),
|
||||
new Ability(Abilities.MERCILESS, 7)
|
||||
.attr(ConditionalCritAbAttr, (user, target, move) => target?.status?.effect === StatusEffect.TOXIC || target?.status?.effect === StatusEffect.POISON),
|
||||
new Ability(Abilities.SHIELDS_DOWN, 7)
|
||||
@ -5424,7 +5427,7 @@ export function initAbilities() {
|
||||
.attr(NoFusionAbilityAbAttr)
|
||||
// Add BattlerTagType.DISGUISE if the pokemon is in its disguised form
|
||||
.conditionalAttr(pokemon => pokemon.formIndex === 0, PostSummonAddBattlerTagAbAttr, BattlerTagType.DISGUISE, 0, false)
|
||||
.attr(FormBlockDamageAbAttr, (target, user, move) => !!target.getTag(BattlerTagType.DISGUISE) && target.getAttackTypeEffectiveness(move.type, user) > 0, 0, BattlerTagType.DISGUISE,
|
||||
.attr(FormBlockDamageAbAttr, (target, user, move) => !!target.getTag(BattlerTagType.DISGUISE) && target.getMoveEffectiveness(user, move) > 0, 0, BattlerTagType.DISGUISE,
|
||||
(pokemon, abilityName) => i18next.t("abilityTriggers:disguiseAvoidedDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }),
|
||||
(pokemon) => Utils.toDmgValue(pokemon.getMaxHp() / 8))
|
||||
.attr(PostBattleInitFormChangeAbAttr, () => 0)
|
||||
@ -5469,7 +5472,7 @@ export function initAbilities() {
|
||||
.attr(AllyMoveCategoryPowerBoostAbAttr, [MoveCategory.SPECIAL], 1.3),
|
||||
new Ability(Abilities.FLUFFY, 7)
|
||||
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT), 0.5)
|
||||
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.type === Type.FIRE, 2)
|
||||
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => user.getMoveType(move) === Type.FIRE, 2)
|
||||
.ignorable(),
|
||||
new Ability(Abilities.DAZZLING, 7)
|
||||
.attr(FieldPriorityMoveImmunityAbAttr)
|
||||
@ -5519,10 +5522,10 @@ export function initAbilities() {
|
||||
new Ability(Abilities.SHADOW_SHIELD, 7)
|
||||
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.isFullHp(), 0.5),
|
||||
new Ability(Abilities.PRISM_ARMOR, 7)
|
||||
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getAttackTypeEffectiveness(move.type, user) >= 2, 0.75),
|
||||
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getMoveEffectiveness(user, move) >= 2, 0.75),
|
||||
new Ability(Abilities.NEUROFORCE, 7)
|
||||
//@ts-ignore
|
||||
.attr(MovePowerBoostAbAttr, (user, target, move) => target.getAttackTypeEffectiveness(move.type, user) >= 2, 1.25), // TODO: fix TS issues
|
||||
.attr(MovePowerBoostAbAttr, (user, target, move) => target?.getMoveEffectiveness(user, move) >= 2, 1.25), // TODO: fix TS issues
|
||||
new Ability(Abilities.INTREPID_SWORD, 8)
|
||||
.attr(PostSummonStatStageChangeAbAttr, [ Stat.ATK ], 1, true)
|
||||
.condition(getOncePerBattleCondition(Abilities.INTREPID_SWORD)),
|
||||
@ -5553,7 +5556,11 @@ export function initAbilities() {
|
||||
new Ability(Abilities.STALWART, 8)
|
||||
.attr(BlockRedirectAbAttr),
|
||||
new Ability(Abilities.STEAM_ENGINE, 8)
|
||||
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => (move.type === Type.FIRE || move.type === Type.WATER) && move.category !== MoveCategory.STATUS, Stat.SPD, 6),
|
||||
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => {
|
||||
const moveType = user.getMoveType(move);
|
||||
return move.category !== MoveCategory.STATUS
|
||||
&& (moveType === Type.FIRE || moveType === Type.WATER);
|
||||
}, Stat.SPD, 6),
|
||||
new Ability(Abilities.PUNK_ROCK, 8)
|
||||
.attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.SOUND_BASED), 1.3)
|
||||
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.hasFlag(MoveFlags.SOUND_BASED), 0.5)
|
||||
@ -5653,7 +5660,7 @@ export function initAbilities() {
|
||||
new Ability(Abilities.SEED_SOWER, 9)
|
||||
.attr(PostDefendTerrainChangeAbAttr, TerrainType.GRASSY),
|
||||
new Ability(Abilities.THERMAL_EXCHANGE, 9)
|
||||
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => move.type === Type.FIRE && move.category !== MoveCategory.STATUS, Stat.ATK, 1)
|
||||
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => user.getMoveType(move) === Type.FIRE && move.category !== MoveCategory.STATUS, Stat.ATK, 1)
|
||||
.attr(StatusEffectImmunityAbAttr, StatusEffect.BURN)
|
||||
.ignorable(),
|
||||
new Ability(Abilities.ANGER_SHELL, 9)
|
||||
|
@ -761,8 +761,7 @@ export default class Move implements Localizable {
|
||||
.flat(),
|
||||
);
|
||||
for (const aura of fieldAuras) {
|
||||
// The only relevant values are `move` and the `power` holder
|
||||
aura.applyPreAttack(null, null, simulated, null, this, [power]);
|
||||
aura.applyPreAttack(source, null, simulated, target, this, [power]);
|
||||
}
|
||||
|
||||
const alliedField: Pokemon[] = source instanceof PlayerPokemon ? source.scene.getPlayerField() : source.scene.getEnemyField();
|
||||
|
@ -39,5 +39,6 @@
|
||||
"matBlock": "Mat Block",
|
||||
"craftyShield": "Crafty Shield",
|
||||
"tailwind": "Tailwind",
|
||||
"happyHour": "Happy Hour"
|
||||
"happyHour": "Happy Hour",
|
||||
"safeguard": "Safeguard"
|
||||
}
|
@ -47,5 +47,11 @@
|
||||
"tailwindOnRemovePlayer": "Your team's Tailwind petered out!",
|
||||
"tailwindOnRemoveEnemy": "The opposing team's Tailwind petered out!",
|
||||
"happyHourOnAdd": "Everyone is caught up in the happy atmosphere!",
|
||||
"happyHourOnRemove": "The atmosphere returned to normal."
|
||||
"happyHourOnRemove": "The atmosphere returned to normal.",
|
||||
"safeguardOnAdd": "The whole field is cloaked in a mystical veil!",
|
||||
"safeguardOnAddPlayer": "Your team cloaked itself in a mystical veil!",
|
||||
"safeguardOnAddEnemy": "The opposing team cloaked itself in a mystical veil!",
|
||||
"safeguardOnRemove": "The field is no longer protected by Safeguard!",
|
||||
"safeguardOnRemovePlayer": "Your team is no longer protected by Safeguard!",
|
||||
"safeguardOnRemoveEnemy": "The opposing team is no longer protected by Safeguard!"
|
||||
}
|
@ -65,5 +65,6 @@
|
||||
"suppressAbilities": "{{pokemonName}}'s ability\nwas suppressed!",
|
||||
"revivalBlessing": "{{pokemonName}} was revived!",
|
||||
"swapArenaTags": "{{pokemonName}} swapped the battle effects affecting each side of the field!",
|
||||
"exposedMove": "{{pokemonName}} identified\n{{targetPokemonName}}!"
|
||||
"exposedMove": "{{pokemonName}} identified\n{{targetPokemonName}}!",
|
||||
"safeguard": "{{targetName}} is protected by Safeguard!"
|
||||
}
|
@ -2488,7 +2488,7 @@ export class TurnHeldItemTransferModifier extends HeldItemTransferModifier {
|
||||
}
|
||||
|
||||
getTransferMessage(pokemon: Pokemon, targetPokemon: Pokemon, item: ModifierTypes.ModifierType): string {
|
||||
return i18next.t("modifier:turnHeldItemTransferApply", { pokemonNameWithAffix: getPokemonNameWithAffix(targetPokemon), itemName: item.name, pokemonName: pokemon.name, typeName: this.type.name });
|
||||
return i18next.t("modifier:turnHeldItemTransferApply", { pokemonNameWithAffix: getPokemonNameWithAffix(targetPokemon), itemName: item.name, pokemonName: pokemon.getNameToRender(), typeName: this.type.name });
|
||||
}
|
||||
|
||||
getMaxHeldItemCount(pokemon: Pokemon): integer {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { toDmgValue } from "#app/utils";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { Species } from "#enums/species";
|
||||
import { StatusEffect } from "#app/data/status-effect";
|
||||
@ -205,4 +206,22 @@ describe("Abilities - Disguise", () => {
|
||||
expect(game.scene.getCurrentPhase()?.constructor.name).toBe("CommandPhase");
|
||||
expect(game.scene.currentBattle.waveIndex).toBe(2);
|
||||
}, TIMEOUT);
|
||||
|
||||
it("activates when Aerilate circumvents immunity to the move's base type", async () => {
|
||||
game.override.ability(Abilities.AERILATE);
|
||||
game.override.moveset([Moves.TACKLE]);
|
||||
|
||||
await game.classicMode.startBattle();
|
||||
|
||||
const mimikyu = game.scene.getEnemyPokemon()!;
|
||||
const maxHp = mimikyu.getMaxHp();
|
||||
const disguiseDamage = toDmgValue(maxHp / 8);
|
||||
|
||||
game.move.select(Moves.TACKLE);
|
||||
|
||||
await game.phaseInterceptor.to("MoveEndPhase");
|
||||
|
||||
expect(mimikyu.formIndex).toBe(bustedForm);
|
||||
expect(mimikyu.hp).toBe(maxHp - disguiseDamage);
|
||||
}, TIMEOUT);
|
||||
});
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { allAbilities } from "#app/data/ability";
|
||||
import { allMoves } from "#app/data/move";
|
||||
import { Abilities } from "#app/enums/abilities";
|
||||
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { Species } from "#enums/species";
|
||||
import GameManager from "#test/utils/gameManager";
|
||||
@ -37,7 +36,7 @@ describe("Abilities - Steely Spirit", () => {
|
||||
});
|
||||
|
||||
it("increases Steel-type moves' power used by the user and its allies by 50%", async () => {
|
||||
await game.startBattle([Species.PIKACHU, Species.SHUCKLE]);
|
||||
await game.classicMode.startBattle([Species.PIKACHU, Species.SHUCKLE]);
|
||||
const boostSource = game.scene.getPlayerField()[1];
|
||||
const enemyToCheck = game.scene.getEnemyPokemon()!;
|
||||
|
||||
@ -47,13 +46,13 @@ describe("Abilities - Steely Spirit", () => {
|
||||
|
||||
game.move.select(moveToCheck, 0, enemyToCheck.getBattlerIndex());
|
||||
game.move.select(Moves.SPLASH, 1);
|
||||
await game.phaseInterceptor.to(MoveEffectPhase);
|
||||
await game.phaseInterceptor.to("MoveEffectPhase");
|
||||
|
||||
expect(allMoves[moveToCheck].calculateBattlePower).toHaveReturnedWith(ironHeadPower * steelySpiritMultiplier);
|
||||
});
|
||||
|
||||
it("stacks if multiple users with this ability are on the field.", async () => {
|
||||
await game.startBattle([Species.PIKACHU, Species.PIKACHU]);
|
||||
await game.classicMode.startBattle([Species.PIKACHU, Species.PIKACHU]);
|
||||
const enemyToCheck = game.scene.getEnemyPokemon()!;
|
||||
|
||||
game.scene.getPlayerField().forEach(p => {
|
||||
@ -64,13 +63,13 @@ describe("Abilities - Steely Spirit", () => {
|
||||
|
||||
game.move.select(moveToCheck, 0, enemyToCheck.getBattlerIndex());
|
||||
game.move.select(moveToCheck, 1, enemyToCheck.getBattlerIndex());
|
||||
await game.phaseInterceptor.to(MoveEffectPhase);
|
||||
await game.phaseInterceptor.to("MoveEffectPhase");
|
||||
|
||||
expect(allMoves[moveToCheck].calculateBattlePower).toHaveReturnedWith(ironHeadPower * Math.pow(steelySpiritMultiplier, 2));
|
||||
});
|
||||
|
||||
it("does not take effect when suppressed", async () => {
|
||||
await game.startBattle([Species.PIKACHU, Species.SHUCKLE]);
|
||||
await game.classicMode.startBattle([Species.PIKACHU, Species.SHUCKLE]);
|
||||
const boostSource = game.scene.getPlayerField()[1];
|
||||
const enemyToCheck = game.scene.getEnemyPokemon()!;
|
||||
|
||||
@ -84,8 +83,25 @@ describe("Abilities - Steely Spirit", () => {
|
||||
|
||||
game.move.select(moveToCheck, 0, enemyToCheck.getBattlerIndex());
|
||||
game.move.select(Moves.SPLASH, 1);
|
||||
await game.phaseInterceptor.to(MoveEffectPhase);
|
||||
await game.phaseInterceptor.to("MoveEffectPhase");
|
||||
|
||||
expect(allMoves[moveToCheck].calculateBattlePower).toHaveReturnedWith(ironHeadPower);
|
||||
});
|
||||
|
||||
it("affects variable-type moves if their resolved type is Steel", async () => {
|
||||
game.override
|
||||
.ability(Abilities.STEELY_SPIRIT)
|
||||
.moveset([Moves.REVELATION_DANCE]);
|
||||
|
||||
const revelationDance = allMoves[Moves.REVELATION_DANCE];
|
||||
vi.spyOn(revelationDance, "calculateBattlePower");
|
||||
|
||||
await game.classicMode.startBattle([Species.KLINKLANG]);
|
||||
|
||||
game.move.select(Moves.REVELATION_DANCE);
|
||||
|
||||
await game.phaseInterceptor.to("MoveEffectPhase");
|
||||
|
||||
expect(revelationDance.calculateBattlePower).toHaveReturnedWith(revelationDance.power * 1.5);
|
||||
});
|
||||
});
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Species } from "#app/enums/species";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
import GameManager from "../utils/gameManager";
|
||||
import { PokeballType } from "#app/enums/pokeball.js";
|
||||
import BattleScene from "#app/battle-scene.js";
|
||||
import { PokeballType } from "#app/enums/pokeball";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
|
||||
describe("Spec - Pokemon", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
|
@ -25,7 +25,6 @@ describe("Moves - Rage Powder", () => {
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
game.override.battleType("double");
|
||||
game.override.starterSpecies(Species.AMOONGUSS);
|
||||
game.override.enemySpecies(Species.SNORLAX);
|
||||
game.override.startingLevel(100);
|
||||
game.override.enemyLevel(100);
|
||||
@ -68,6 +67,10 @@ describe("Moves - Rage Powder", () => {
|
||||
|
||||
game.move.select(Moves.QUICK_ATTACK, 0, BattlerIndex.ENEMY);
|
||||
game.move.select(Moves.QUICK_ATTACK, 1, BattlerIndex.ENEMY_2);
|
||||
|
||||
await game.forceEnemyMove(Moves.RAGE_POWDER);
|
||||
await game.forceEnemyMove(Moves.SPLASH);
|
||||
|
||||
await game.phaseInterceptor.to("BerryPhase", false);
|
||||
|
||||
// If redirection was bypassed, both enemies should be damaged
|
||||
|
@ -585,11 +585,11 @@ export function getLocalizedSpriteKey(baseKey: string) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a number is between two other numbers
|
||||
* Check if a number is **inclusive** between two numbers
|
||||
* @param num the number to check
|
||||
* @param min the minimum value
|
||||
* @param max the maximum value
|
||||
* @returns true if number is between min and max
|
||||
* @param min the minimum value (included)
|
||||
* @param max the maximum value (included)
|
||||
* @returns true if number is **inclusive** between min and max
|
||||
*/
|
||||
export function isBetween(num: number, min: number, max: number): boolean {
|
||||
return num >= min && num <= max;
|
||||
|