Make Disguise properly reset form on arena reset when fainted (#3612)
This commit is contained in:
parent
192aa63635
commit
0e6c2952ca
|
@ -37,7 +37,7 @@ import UIPlugin from "phaser3-rex-plugins/templates/ui/ui-plugin";
|
|||
import { addUiThemeOverrides } from "./ui/ui-theme";
|
||||
import PokemonData from "./system/pokemon-data";
|
||||
import { Nature } from "./data/nature";
|
||||
import { SpeciesFormChangeManualTrigger, SpeciesFormChangeTimeOfDayTrigger, SpeciesFormChangeTrigger, pokemonFormChanges, FormChangeItem } from "./data/pokemon-forms";
|
||||
import { SpeciesFormChangeManualTrigger, SpeciesFormChangeTimeOfDayTrigger, SpeciesFormChangeTrigger, pokemonFormChanges, FormChangeItem, SpeciesFormChange } from "./data/pokemon-forms";
|
||||
import { FormChangePhase, QuietFormChangePhase } from "./form-change-phase";
|
||||
import { getTypeRgb } from "./data/type";
|
||||
import PokemonSpriteSparkleHandler from "./field/pokemon-sprite-sparkle-handler";
|
||||
|
@ -2579,7 +2579,7 @@ export default class BattleScene extends SceneBase {
|
|||
|
||||
// in case this is NECROZMA, determine which forms this
|
||||
const matchingFormChangeOpts = pokemonFormChanges[pokemon.species.speciesId].filter(fc => fc.findTrigger(formChangeTriggerType) && fc.canChange(pokemon));
|
||||
let matchingFormChange;
|
||||
let matchingFormChange: SpeciesFormChange | null;
|
||||
if (pokemon.species.speciesId === Species.NECROZMA && matchingFormChangeOpts.length > 1) {
|
||||
// Ultra Necrozma is changing its form back, so we need to figure out into which form it devolves.
|
||||
const formChangeItemModifiers = (this.findModifiers(m => m instanceof PokemonFormChangeItemModifier && m.pokemonId === pokemon.id) as PokemonFormChangeItemModifier[]).filter(m => m.active).map(m => m.formChangeItem);
|
||||
|
|
|
@ -5039,6 +5039,7 @@ export function initAbilities() {
|
|||
(pokemon, abilityName) => i18next.t("abilityTriggers:disguiseAvoidedDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }),
|
||||
(pokemon) => Math.floor(pokemon.getMaxHp() / 8))
|
||||
.attr(PostBattleInitFormChangeAbAttr, () => 0)
|
||||
.bypassFaint()
|
||||
.ignorable(),
|
||||
new Ability(Abilities.BATTLE_BOND, 7)
|
||||
.attr(PostVictoryFormChangeAbAttr, () => 2)
|
||||
|
@ -5191,6 +5192,7 @@ export function initAbilities() {
|
|||
.attr(FormBlockDamageAbAttr, (target, user, move) => move.category === MoveCategory.PHYSICAL && !!target.getTag(BattlerTagType.ICE_FACE), 0, BattlerTagType.ICE_FACE,
|
||||
(pokemon, abilityName) => i18next.t("abilityTriggers:iceFaceAvoidedDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }))
|
||||
.attr(PostBattleInitFormChangeAbAttr, () => 0)
|
||||
.bypassFaint()
|
||||
.ignorable(),
|
||||
new Ability(Abilities.POWER_SPOT, 8)
|
||||
.attr(AllyMoveCategoryPowerBoostAbAttr, [MoveCategory.SPECIAL, MoveCategory.PHYSICAL], 1.3),
|
||||
|
|
|
@ -2,12 +2,12 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
|||
import GameManager from "#test/utils/gameManager";
|
||||
import { getMovePosition } from "#test/utils/gameManagerUtils";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
import { Species } from "#enums/species";
|
||||
import { StatusEffect } from "#app/data/status-effect.js";
|
||||
import { MoveEffectPhase, MoveEndPhase, TurnEndPhase, TurnInitPhase } from "#app/phases.js";
|
||||
import { CommandPhase, MoveEffectPhase, MoveEndPhase, TurnEndPhase, TurnInitPhase } from "#app/phases.js";
|
||||
import { BattleStat } from "#app/data/battle-stat.js";
|
||||
import { SPLASH_ONLY } from "../utils/testUtils";
|
||||
import { Mode } from "#app/ui/ui.js";
|
||||
|
||||
const TIMEOUT = 20 * 1000;
|
||||
|
||||
|
@ -38,7 +38,7 @@ describe("Abilities - Disguise", () => {
|
|||
game.override.moveset([Moves.SHADOW_SNEAK, Moves.VACUUM_WAVE, Moves.TOXIC_THREAD, Moves.SPLASH]);
|
||||
}, TIMEOUT);
|
||||
|
||||
it("takes no damage from attacking move and transforms to Busted form, taking 1/8 max HP damage from the disguise breaking", async () => {
|
||||
it("takes no damage from attacking move and transforms to Busted form, takes 1/8 max HP damage from the disguise breaking", async () => {
|
||||
await game.startBattle();
|
||||
|
||||
const mimikyu = game.scene.getEnemyPokemon()!;
|
||||
|
@ -134,17 +134,30 @@ describe("Abilities - Disguise", () => {
|
|||
expect(mimikyu.formIndex).toBe(bustedForm);
|
||||
}, TIMEOUT);
|
||||
|
||||
it("reverts to Disguised on arena reset", async () => {
|
||||
game.override.startingWave(4);
|
||||
it("persists form change when wave changes with no arena reset", async () => {
|
||||
game.override.starterSpecies(0);
|
||||
game.override.starterForms({
|
||||
[Species.MIMIKYU]: bustedForm
|
||||
});
|
||||
await game.startBattle([Species.FURRET, Species.MIMIKYU]);
|
||||
|
||||
const mimikyu = game.scene.getParty()[1]!;
|
||||
expect(mimikyu.formIndex).toBe(bustedForm);
|
||||
|
||||
game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH));
|
||||
await game.doKillOpponents();
|
||||
await game.toNextWave();
|
||||
|
||||
expect(mimikyu.formIndex).toBe(bustedForm);
|
||||
}, TIMEOUT);
|
||||
|
||||
it("reverts to Disguised form on arena reset", async () => {
|
||||
game.override.startingWave(4);
|
||||
game.override.starterSpecies(Species.MIMIKYU);
|
||||
game.override.starterForms({
|
||||
[Species.MIMIKYU]: bustedForm
|
||||
});
|
||||
|
||||
game.override.enemySpecies(Species.MAGIKARP);
|
||||
game.override.enemyAbility(Abilities.BALL_FETCH);
|
||||
|
||||
await game.startBattle();
|
||||
|
||||
const mimikyu = game.scene.getPlayerPokemon()!;
|
||||
|
@ -153,10 +166,41 @@ describe("Abilities - Disguise", () => {
|
|||
|
||||
game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH));
|
||||
await game.doKillOpponents();
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
game.doSelectModifier();
|
||||
await game.phaseInterceptor.to(TurnInitPhase);
|
||||
await game.toNextWave();
|
||||
|
||||
expect(mimikyu.formIndex).toBe(disguisedForm);
|
||||
}, TIMEOUT);
|
||||
|
||||
it("reverts to Disguised form on biome change when fainted", async () => {
|
||||
game.override.startingWave(10);
|
||||
game.override.starterSpecies(0);
|
||||
game.override.starterForms({
|
||||
[Species.MIMIKYU]: bustedForm
|
||||
});
|
||||
|
||||
await game.startBattle([Species.MIMIKYU, Species.FURRET]);
|
||||
|
||||
const mimikyu1 = game.scene.getPlayerPokemon()!;
|
||||
|
||||
expect(mimikyu1.formIndex).toBe(bustedForm);
|
||||
|
||||
game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH));
|
||||
await game.killPokemon(mimikyu1);
|
||||
game.doSelectPartyPokemon(1);
|
||||
await game.toNextTurn();
|
||||
game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH));
|
||||
await game.doKillOpponents();
|
||||
game.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => { // TODO: Make tests run in set mode instead of switch mode
|
||||
game.setMode(Mode.MESSAGE);
|
||||
game.endPhase();
|
||||
}, () => game.isCurrentPhase(CommandPhase) || game.isCurrentPhase(TurnInitPhase));
|
||||
|
||||
game.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => {
|
||||
game.setMode(Mode.MESSAGE);
|
||||
game.endPhase();
|
||||
}, () => game.isCurrentPhase(CommandPhase) || game.isCurrentPhase(TurnInitPhase));
|
||||
await game.phaseInterceptor.to("PartyHealPhase");
|
||||
|
||||
expect(mimikyu1.formIndex).toBe(disguisedForm);
|
||||
}, TIMEOUT);
|
||||
});
|
||||
|
|
|
@ -15,6 +15,7 @@ import {
|
|||
MovePhase,
|
||||
NewBattlePhase,
|
||||
NextEncounterPhase,
|
||||
PartyHealPhase,
|
||||
PostSummonPhase,
|
||||
SelectGenderPhase,
|
||||
SelectModifierPhase,
|
||||
|
@ -92,6 +93,7 @@ export default class PhaseInterceptor {
|
|||
[QuietFormChangePhase, this.startPhase],
|
||||
[SwitchPhase, this.startPhase],
|
||||
[SwitchSummonPhase, this.startPhase],
|
||||
[PartyHealPhase, this.startPhase],
|
||||
];
|
||||
|
||||
private endBySetMode = [
|
||||
|
|
Loading…
Reference in New Issue