Simplifying logic for fusions when overrides are involved, introducing new tests in pokemon.test.ts

This commit is contained in:
Wlowscha 2025-02-01 18:02:00 +01:00
parent 42e3f20f6a
commit aaf8b9f685
No known key found for this signature in database
GPG Key ID: 3C8F1AD330565D04
2 changed files with 155 additions and 48 deletions

View File

@ -1261,59 +1261,37 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.summonData.types.forEach(t => types.push(t));
} else {
const speciesForm = this.getSpeciesForm(ignoreOverride);
types.push(speciesForm.type1);
const fusionSpeciesForm = this.getFusionSpeciesForm(ignoreOverride);
const overrideTypes = this.customPokemonData.types && this.customPokemonData.types.length > 0;
// First type, checking for "permanently changed" types from ME
const firstType = (overrideTypes && this.customPokemonData.types[0] !== Type.UNKNOWN) ? this.customPokemonData.types[0] : speciesForm.type1;
types.push(firstType);
// Second type
let secondType: Type | null = null;
if (fusionSpeciesForm) {
// Check if the fusion Pokemon also had "permanently changed" types
// Otherwise, use standard fusion type logic
const fusionMETypes = this.fusionCustomPokemonData?.types;
if (fusionMETypes && fusionMETypes.length >= 2 && fusionMETypes[1] !== types[0]) {
types.push(fusionMETypes[1]);
} else if (fusionMETypes && fusionMETypes.length === 1 && fusionMETypes[0] !== types[0]) {
types.push(fusionMETypes[0]);
} else if (fusionSpeciesForm.type2 !== null && fusionSpeciesForm.type2 !== speciesForm.type1) {
types.push(fusionSpeciesForm.type2);
} else if (fusionSpeciesForm.type1 !== speciesForm.type1) {
types.push(fusionSpeciesForm.type1);
// Check if the fusion Pokemon also had "permanently changed" types when determining the fusion types
const fusionType1 = (this.fusionCustomPokemonData?.types && this.fusionCustomPokemonData.types.length > 0 && this.fusionCustomPokemonData.types[0] !== Type.UNKNOWN)
? this.fusionCustomPokemonData.types[0] : fusionSpeciesForm.type1;
const fusionType2 = (this.fusionCustomPokemonData?.types && this.fusionCustomPokemonData.types.length > 1 && this.fusionCustomPokemonData.types[1] !== Type.UNKNOWN)
? this.fusionCustomPokemonData.types[1] : fusionSpeciesForm.type2;
// Assign second type if the fusion can provide one
if (fusionType2 !== null && fusionType2 !== types[0]) {
secondType = fusionType2;
} else if (fusionType1 !== types[0]) {
secondType = fusionType1;
}
} else {
// If not a fusion, just get the second type from the species, checking for overrides
secondType = (overrideTypes && this.customPokemonData.types.length > 1 && this.customPokemonData.types[1] !== Type.UNKNOWN)
? this.customPokemonData.types[0] : speciesForm.type1;
}
if (types.length === 1 && speciesForm.type2 !== null) {
types.push(speciesForm.type2);
}
// "Permanent" override for a Pokemon's normal types, currently only used by Mystery Encounters
if (this.customPokemonData.types && this.customPokemonData.types.length > 0) {
if (this.customPokemonData.types[0] !== Type.UNKNOWN) {
types[0] = this.customPokemonData.types[0];
}
// Fusing a Pokemon onto something with "permanently changed" types will still apply the fusion's types as normal
const fusionSpeciesForm = this.getFusionSpeciesForm(ignoreOverride);
if (fusionSpeciesForm) {
// Check if the fusion Pokemon also had "permanently changed" types
const fusionMETypes = this.fusionCustomPokemonData?.types;
if (fusionMETypes && fusionMETypes.length >= 2 && fusionMETypes[1] !== types[0] && fusionMETypes[1] !== Type.UNKNOWN) {
types.push(fusionMETypes[1]);
} else if (fusionMETypes && fusionMETypes.length === 1 && fusionMETypes[0] !== types[0] && fusionMETypes[0] !== Type.UNKNOWN) {
types.push(fusionMETypes[0]);
} else if (fusionSpeciesForm.type2 !== null && fusionSpeciesForm.type2 !== types[0]) {
types.push(fusionSpeciesForm.type2);
} else if (fusionSpeciesForm.type1 !== types[0]) {
types.push(fusionSpeciesForm.type1);
}
}
if (this.customPokemonData.types.length >= 2 && this.customPokemonData.types[1] !== Type.UNKNOWN) {
if (types.length === 1) {
types.push(this.customPokemonData.types[1]);
} else {
types[1] = this.customPokemonData.types[1];
}
}
if (secondType) {
types.push(secondType);
}
}
}

View File

@ -4,6 +4,8 @@ import GameManager from "../utils/gameManager";
import { PokeballType } from "#enums/pokeball";
import type BattleScene from "#app/battle-scene";
import { Moves } from "#app/enums/moves";
import { Type } from "#app/enums/type";
import { CustomPokemonData } from "#app/data/custom-pokemon-data";
describe("Spec - Pokemon", () => {
let phaserGame: Phaser.Game;
@ -75,4 +77,131 @@ describe("Spec - Pokemon", () => {
expect(fanRotom.compatibleTms).not.toContain(Moves.BLIZZARD);
expect(fanRotom.compatibleTms).toContain(Moves.AIR_SLASH);
});
describe("Get correct fusion type", () => {
let scene: BattleScene;
beforeEach(async () => {
game.override.enemySpecies(Species.ZUBAT);
game.override.starterSpecies(Species.ABRA);
game.override.enableStarterFusion();
scene = game.scene;
});
it("Fusing two mons with a single type", async () => {
game.override.starterFusionSpecies(Species.CHARMANDER);
await game.classicMode.startBattle();
const pokemon = scene.getPlayerParty()[0];
let types = pokemon.getTypes();
expect(types[0]).toBe(Type.PSYCHIC);
expect(types[1]).toBe(Type.FIRE);
// Abra Psychic/Grass
pokemon.customPokemonData.types = [ Type.UNKNOWN, Type.GRASS ];
types = pokemon.getTypes();
expect(types[0]).toBe(Type.PSYCHIC);
expect(types[1]).toBe(Type.FIRE);
// Abra Grass
pokemon.customPokemonData.types = [ Type.GRASS, Type.UNKNOWN ];
types = pokemon.getTypes();
expect(types[0]).toBe(Type.GRASS);
expect(types[1]).toBe(Type.FIRE);
if (!pokemon.fusionCustomPokemonData) {
pokemon.fusionCustomPokemonData = new CustomPokemonData();
}
pokemon.customPokemonData.types = [];
// Charmander Fire/Grass
pokemon.fusionCustomPokemonData.types = [ Type.UNKNOWN, Type.GRASS ];
types = pokemon.getTypes();
expect(types[0]).toBe(Type.PSYCHIC);
expect(types[1]).toBe(Type.GRASS);
// Charmander Grass
pokemon.fusionCustomPokemonData.types = [ Type.GRASS, Type.UNKNOWN ];
types = pokemon.getTypes();
expect(types[0]).toBe(Type.PSYCHIC);
expect(types[1]).toBe(Type.GRASS);
// Abra Grass
// Charmander Fire/Grass
pokemon.customPokemonData.types = [ Type.GRASS, Type.UNKNOWN ];
pokemon.fusionCustomPokemonData.types = [ Type.UNKNOWN, Type.GRASS ];
types = pokemon.getTypes();
expect(types[0]).toBe(Type.GRASS);
expect(types[1]).toBe(Type.FIRE);
});
it("Fusing two mons with same single type", async () => {
game.override.starterFusionSpecies(Species.DROWZEE);
await game.classicMode.startBattle();
const pokemon = scene.getPlayerParty()[0];
const types = pokemon.getTypes();
expect(types[0]).toBe(Type.PSYCHIC);
expect(types.length).toBe(1);
});
it("Fusing mons with one and two types", async () => {
game.override.starterSpecies(Species.CHARMANDER);
game.override.starterFusionSpecies(Species.HOUNDOUR);
await game.classicMode.startBattle();
const pokemon = scene.getPlayerParty()[0];
const types = pokemon.getTypes();
expect(types[0]).toBe(Type.FIRE);
expect(types[1]).toBe(Type.DARK);
});
it("Fusing two mons with two types", async () => {
game.override.starterSpecies(Species.NATU);
game.override.starterFusionSpecies(Species.HOUNDOUR);
await game.classicMode.startBattle();
const pokemon = scene.getPlayerParty()[0];
let types = pokemon.getTypes();
expect(types[0]).toBe(Type.PSYCHIC);
expect(types[1]).toBe(Type.FIRE);
// Natu Psychic/Grass
pokemon.customPokemonData.types = [ Type.UNKNOWN, Type.GRASS ];
types = pokemon.getTypes();
expect(types[0]).toBe(Type.PSYCHIC);
expect(types[1]).toBe(Type.FIRE);
// Natu Grass/Flying
pokemon.customPokemonData.types = [ Type.GRASS, Type.UNKNOWN ];
types = pokemon.getTypes();
expect(types[0]).toBe(Type.GRASS);
expect(types[1]).toBe(Type.FIRE);
if (!pokemon.fusionCustomPokemonData) {
pokemon.fusionCustomPokemonData = new CustomPokemonData();
}
pokemon.customPokemonData.types = [];
// Houndour Dark/Grass
pokemon.fusionCustomPokemonData.types = [ Type.UNKNOWN, Type.GRASS ];
types = pokemon.getTypes();
expect(types[0]).toBe(Type.PSYCHIC);
expect(types[1]).toBe(Type.GRASS);
// Houndour Grass/Fire
pokemon.fusionCustomPokemonData.types = [ Type.GRASS, Type.UNKNOWN ];
types = pokemon.getTypes();
expect(types[0]).toBe(Type.PSYCHIC);
expect(types[1]).toBe(Type.FIRE);
// Natu Grass/Flying
// Houndour Dark/Grass
pokemon.customPokemonData.types = [ Type.GRASS, Type.UNKNOWN ];
pokemon.fusionCustomPokemonData.types = [ Type.UNKNOWN, Type.GRASS ];
types = pokemon.getTypes();
expect(types[0]).toBe(Type.GRASS);
expect(types[1]).toBe(Type.DARK);
});
});
});