mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-02-21 11:46:47 +00:00
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 { addUiThemeOverrides } from "./ui/ui-theme";
|
||||||
import PokemonData from "./system/pokemon-data";
|
import PokemonData from "./system/pokemon-data";
|
||||||
import { Nature } from "./data/nature";
|
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 { FormChangePhase, QuietFormChangePhase } from "./form-change-phase";
|
||||||
import { getTypeRgb } from "./data/type";
|
import { getTypeRgb } from "./data/type";
|
||||||
import PokemonSpriteSparkleHandler from "./field/pokemon-sprite-sparkle-handler";
|
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
|
// in case this is NECROZMA, determine which forms this
|
||||||
const matchingFormChangeOpts = pokemonFormChanges[pokemon.species.speciesId].filter(fc => fc.findTrigger(formChangeTriggerType) && fc.canChange(pokemon));
|
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) {
|
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.
|
// 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);
|
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, abilityName) => i18next.t("abilityTriggers:disguiseAvoidedDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }),
|
||||||
(pokemon) => Math.floor(pokemon.getMaxHp() / 8))
|
(pokemon) => Math.floor(pokemon.getMaxHp() / 8))
|
||||||
.attr(PostBattleInitFormChangeAbAttr, () => 0)
|
.attr(PostBattleInitFormChangeAbAttr, () => 0)
|
||||||
|
.bypassFaint()
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
new Ability(Abilities.BATTLE_BOND, 7)
|
new Ability(Abilities.BATTLE_BOND, 7)
|
||||||
.attr(PostVictoryFormChangeAbAttr, () => 2)
|
.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,
|
.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 }))
|
(pokemon, abilityName) => i18next.t("abilityTriggers:iceFaceAvoidedDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }))
|
||||||
.attr(PostBattleInitFormChangeAbAttr, () => 0)
|
.attr(PostBattleInitFormChangeAbAttr, () => 0)
|
||||||
|
.bypassFaint()
|
||||||
.ignorable(),
|
.ignorable(),
|
||||||
new Ability(Abilities.POWER_SPOT, 8)
|
new Ability(Abilities.POWER_SPOT, 8)
|
||||||
.attr(AllyMoveCategoryPowerBoostAbAttr, [MoveCategory.SPECIAL, MoveCategory.PHYSICAL], 1.3),
|
.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 GameManager from "#test/utils/gameManager";
|
||||||
import { getMovePosition } from "#test/utils/gameManagerUtils";
|
import { getMovePosition } from "#test/utils/gameManagerUtils";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { Abilities } from "#enums/abilities";
|
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { StatusEffect } from "#app/data/status-effect.js";
|
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 { BattleStat } from "#app/data/battle-stat.js";
|
||||||
import { SPLASH_ONLY } from "../utils/testUtils";
|
import { SPLASH_ONLY } from "../utils/testUtils";
|
||||||
|
import { Mode } from "#app/ui/ui.js";
|
||||||
|
|
||||||
const TIMEOUT = 20 * 1000;
|
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]);
|
game.override.moveset([Moves.SHADOW_SNEAK, Moves.VACUUM_WAVE, Moves.TOXIC_THREAD, Moves.SPLASH]);
|
||||||
}, TIMEOUT);
|
}, 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();
|
await game.startBattle();
|
||||||
|
|
||||||
const mimikyu = game.scene.getEnemyPokemon()!;
|
const mimikyu = game.scene.getEnemyPokemon()!;
|
||||||
@ -134,17 +134,30 @@ describe("Abilities - Disguise", () => {
|
|||||||
expect(mimikyu.formIndex).toBe(bustedForm);
|
expect(mimikyu.formIndex).toBe(bustedForm);
|
||||||
}, TIMEOUT);
|
}, TIMEOUT);
|
||||||
|
|
||||||
it("reverts to Disguised on arena reset", async () => {
|
it("persists form change when wave changes with no arena reset", async () => {
|
||||||
game.override.startingWave(4);
|
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.starterSpecies(Species.MIMIKYU);
|
||||||
game.override.starterForms({
|
game.override.starterForms({
|
||||||
[Species.MIMIKYU]: bustedForm
|
[Species.MIMIKYU]: bustedForm
|
||||||
});
|
});
|
||||||
|
|
||||||
game.override.enemySpecies(Species.MAGIKARP);
|
|
||||||
game.override.enemyAbility(Abilities.BALL_FETCH);
|
|
||||||
|
|
||||||
await game.startBattle();
|
await game.startBattle();
|
||||||
|
|
||||||
const mimikyu = game.scene.getPlayerPokemon()!;
|
const mimikyu = game.scene.getPlayerPokemon()!;
|
||||||
@ -153,10 +166,41 @@ describe("Abilities - Disguise", () => {
|
|||||||
|
|
||||||
game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH));
|
game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH));
|
||||||
await game.doKillOpponents();
|
await game.doKillOpponents();
|
||||||
await game.phaseInterceptor.to(TurnEndPhase);
|
await game.toNextWave();
|
||||||
game.doSelectModifier();
|
|
||||||
await game.phaseInterceptor.to(TurnInitPhase);
|
|
||||||
|
|
||||||
expect(mimikyu.formIndex).toBe(disguisedForm);
|
expect(mimikyu.formIndex).toBe(disguisedForm);
|
||||||
}, TIMEOUT);
|
}, 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,
|
MovePhase,
|
||||||
NewBattlePhase,
|
NewBattlePhase,
|
||||||
NextEncounterPhase,
|
NextEncounterPhase,
|
||||||
|
PartyHealPhase,
|
||||||
PostSummonPhase,
|
PostSummonPhase,
|
||||||
SelectGenderPhase,
|
SelectGenderPhase,
|
||||||
SelectModifierPhase,
|
SelectModifierPhase,
|
||||||
@ -92,6 +93,7 @@ export default class PhaseInterceptor {
|
|||||||
[QuietFormChangePhase, this.startPhase],
|
[QuietFormChangePhase, this.startPhase],
|
||||||
[SwitchPhase, this.startPhase],
|
[SwitchPhase, this.startPhase],
|
||||||
[SwitchSummonPhase, this.startPhase],
|
[SwitchSummonPhase, this.startPhase],
|
||||||
|
[PartyHealPhase, this.startPhase],
|
||||||
];
|
];
|
||||||
|
|
||||||
private endBySetMode = [
|
private endBySetMode = [
|
||||||
|
Loading…
x
Reference in New Issue
Block a user