[Bug] Prevent evolution causing a swap from the second ability to the HA (#3138)
* Prevent evolution causing a swap from the second ability to the HA * Add tests * Update `starter-select-ui-handler.ts`
This commit is contained in:
parent
2d51fc5394
commit
9f01b52d6b
|
@ -147,7 +147,7 @@ export abstract class PokemonSpeciesForm {
|
|||
this.height = height;
|
||||
this.weight = weight;
|
||||
this.ability1 = ability1;
|
||||
this.ability2 = ability2;
|
||||
this.ability2 = ability2 === Abilities.NONE ? ability1 : ability2;
|
||||
this.abilityHidden = abilityHidden;
|
||||
this.baseTotal = baseTotal;
|
||||
this.baseStats = [ baseHp, baseAtk, baseDef, baseSpatk, baseSpdef, baseSpd ];
|
||||
|
|
|
@ -219,7 +219,7 @@ export class EvolutionPhase extends Phase {
|
|||
this.scene.time.delayedCall(900, () => {
|
||||
evolutionHandler.canCancel = false;
|
||||
|
||||
this.pokemon.evolve(this.evolution).then(() => {
|
||||
this.pokemon.evolve(this.evolution, this.pokemon.species).then(() => {
|
||||
const levelMoves = this.pokemon.getLevelMoves(this.lastLevel + 1, true);
|
||||
for (const lm of levelMoves) {
|
||||
this.scene.unshiftPhase(new LearnMovePhase(this.scene, this.scene.getParty().indexOf(this.pokemon), lm[1]));
|
||||
|
|
|
@ -3303,9 +3303,10 @@ export class PlayerPokemon extends Pokemon {
|
|||
});
|
||||
}
|
||||
|
||||
evolve(evolution: SpeciesFormEvolution): Promise<void> {
|
||||
evolve(evolution: SpeciesFormEvolution, preEvolution: PokemonSpeciesForm): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
this.pauseEvolutions = false;
|
||||
// Handles Nincada evolving into Ninjask + Shedinja
|
||||
this.handleSpecialEvolutions(evolution);
|
||||
const isFusion = evolution instanceof FusionSpeciesFormEvolution;
|
||||
if (!isFusion) {
|
||||
|
@ -3323,16 +3324,26 @@ export class PlayerPokemon extends Pokemon {
|
|||
}
|
||||
this.generateName();
|
||||
if (!isFusion) {
|
||||
// Prevent pokemon with an illegal ability value from breaking things too badly
|
||||
const abilityCount = this.getSpeciesForm().getAbilityCount();
|
||||
if (this.abilityIndex >= abilityCount) {
|
||||
const preEvoAbilityCount = preEvolution.getAbilityCount();
|
||||
if ([0, 1, 2].includes(this.abilityIndex)) {
|
||||
// Handles cases where a Pokemon with 3 abilities evolves into a Pokemon with 2 abilities (ie: Eevee -> any Eeveelution)
|
||||
if (this.abilityIndex === 2 && preEvoAbilityCount === 3 && abilityCount === 2) {
|
||||
this.abilityIndex = 1;
|
||||
}
|
||||
} else { // Prevent pokemon with an illegal ability value from breaking things
|
||||
console.warn("this.abilityIndex is somehow an illegal value, please report this");
|
||||
console.warn(this.abilityIndex);
|
||||
this.abilityIndex = 0;
|
||||
}
|
||||
} else { // Do the same as above, but for fusions
|
||||
const abilityCount = this.getFusionSpeciesForm().getAbilityCount();
|
||||
if (this.fusionAbilityIndex >= abilityCount) {
|
||||
const preEvoAbilityCount = preEvolution.getAbilityCount();
|
||||
if ([0, 1, 2].includes(this.fusionAbilityIndex)) {
|
||||
if (this.fusionAbilityIndex === 2 && preEvoAbilityCount === 3 && abilityCount === 2) {
|
||||
this.fusionAbilityIndex = 1;
|
||||
}
|
||||
} else {
|
||||
console.warn("this.fusionAbilityIndex is somehow an illegal value, please report this");
|
||||
console.warn(this.fusionAbilityIndex);
|
||||
this.fusionAbilityIndex = 0;
|
||||
|
@ -3379,7 +3390,7 @@ export class PlayerPokemon extends Pokemon {
|
|||
newPokemon.fusionLuck = this.fusionLuck;
|
||||
|
||||
this.scene.getParty().push(newPokemon);
|
||||
newPokemon.evolve(!isFusion ? newEvolution : new FusionSpeciesFormEvolution(this.id, newEvolution));
|
||||
newPokemon.evolve((!isFusion ? newEvolution : new FusionSpeciesFormEvolution(this.id, newEvolution)), evoSpecies);
|
||||
const modifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
||||
&& m.pokemonId === this.id, true) as PokemonHeldItemModifier[];
|
||||
modifiers.forEach(m => {
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import Phaser from "phaser";
|
||||
import GameManager from "#app/test/utils/gameManager";
|
||||
import { Species } from "#app/enums/species.js";
|
||||
import { Abilities } from "#app/enums/abilities.js";
|
||||
import Overrides from "#app/overrides";
|
||||
import { pokemonEvolutions } from "#app/data/pokemon-evolutions.js";
|
||||
|
||||
describe("Evolution", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
const TIMEOUT = 1000 * 20;
|
||||
|
||||
beforeAll(() => {
|
||||
phaserGame = new Phaser.Game({
|
||||
type: Phaser.HEADLESS,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
|
||||
vi.spyOn(Overrides, "BATTLE_TYPE_OVERRIDE", "get").mockReturnValue("single");
|
||||
|
||||
vi.spyOn(Overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.MAGIKARP);
|
||||
vi.spyOn(Overrides, "OPP_ABILITY_OVERRIDE", "get").mockReturnValue(Abilities.BALL_FETCH);
|
||||
|
||||
vi.spyOn(Overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(60);
|
||||
});
|
||||
|
||||
it("should keep hidden ability after evolving", async () => {
|
||||
await game.runToSummon([Species.EEVEE, Species.TRAPINCH]);
|
||||
|
||||
const eevee = game.scene.getParty()[0];
|
||||
const trapinch = game.scene.getParty()[1];
|
||||
eevee.abilityIndex = 2;
|
||||
trapinch.abilityIndex = 2;
|
||||
|
||||
eevee.evolve(pokemonEvolutions[Species.EEVEE][6], eevee.getSpeciesForm());
|
||||
expect(eevee.abilityIndex).toBe(2);
|
||||
|
||||
trapinch.evolve(pokemonEvolutions[Species.TRAPINCH][0], trapinch.getSpeciesForm());
|
||||
expect(trapinch.abilityIndex).toBe(1);
|
||||
}, TIMEOUT);
|
||||
|
||||
it("should keep same ability slot after evolving", async () => {
|
||||
await game.runToSummon([Species.BULBASAUR, Species.CHARMANDER]);
|
||||
|
||||
const bulbasaur = game.scene.getParty()[0];
|
||||
const charmander = game.scene.getParty()[1];
|
||||
bulbasaur.abilityIndex = 0;
|
||||
charmander.abilityIndex = 1;
|
||||
|
||||
bulbasaur.evolve(pokemonEvolutions[Species.BULBASAUR][0], bulbasaur.getSpeciesForm());
|
||||
expect(bulbasaur.abilityIndex).toBe(0);
|
||||
|
||||
charmander.evolve(pokemonEvolutions[Species.CHARMANDER][0], charmander.getSpeciesForm());
|
||||
expect(charmander.abilityIndex).toBe(1);
|
||||
}, TIMEOUT);
|
||||
|
||||
it("should handle illegal abilityIndex values", async () => {
|
||||
await game.runToSummon([Species.SQUIRTLE]);
|
||||
|
||||
const squirtle = game.scene.getPlayerPokemon();
|
||||
squirtle.abilityIndex = 5;
|
||||
|
||||
squirtle.evolve(pokemonEvolutions[Species.SQUIRTLE][0], squirtle.getSpeciesForm());
|
||||
expect(squirtle.abilityIndex).toBe(0);
|
||||
}, TIMEOUT);
|
||||
|
||||
it("should handle nincada's unique evolution", async () => {
|
||||
await game.runToSummon([Species.NINCADA]);
|
||||
|
||||
const nincada = game.scene.getPlayerPokemon();
|
||||
nincada.abilityIndex = 2;
|
||||
|
||||
nincada.evolve(pokemonEvolutions[Species.NINCADA][0], nincada.getSpeciesForm());
|
||||
const ninjask = game.scene.getParty()[0];
|
||||
const shedinja = game.scene.getParty()[1];
|
||||
expect(ninjask.abilityIndex).toBe(2);
|
||||
expect(shedinja.abilityIndex).toBe(1);
|
||||
}, TIMEOUT);
|
||||
});
|
|
@ -1574,9 +1574,10 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||
break;
|
||||
}
|
||||
} else if (newAbilityIndex === 1) {
|
||||
if (abilityAttr & (this.lastSpecies.ability2 ? AbilityAttr.ABILITY_2 : AbilityAttr.ABILITY_HIDDEN)) {
|
||||
break;
|
||||
if (this.lastSpecies.ability1 === this.lastSpecies.ability2) {
|
||||
newAbilityIndex = (newAbilityIndex + 1) % abilityCount;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
if (abilityAttr & AbilityAttr.ABILITY_HIDDEN) {
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue