Fix fusions learning moves of wrong component mon on evolution

This commit is contained in:
AJ Fontaine 2024-11-19 14:55:23 -05:00
parent 6442b8345f
commit bc25037fca
3 changed files with 46 additions and 29 deletions

View File

@ -16,9 +16,9 @@ interface PokemonSpeciesFormLevelMoves {
} }
/** Moves that can only be learned with a memory-mushroom */ /** Moves that can only be learned with a memory-mushroom */
const RELEARN_MOVE = -1; export const RELEARN_MOVE = -1;
/** Moves that can only be learned with an evolve */ /** Moves that can only be learned with an evolve */
const EVOLVE_MOVE = 0; export const EVOLVE_MOVE = 0;
export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = { export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {
[Species.BULBASAUR]: [ [Species.BULBASAUR]: [

View File

@ -29,7 +29,7 @@ import { BattlerIndex } from "#app/battle";
import { Mode } from "#app/ui/ui"; import { Mode } from "#app/ui/ui";
import PartyUiHandler, { PartyOption, PartyUiMode } from "#app/ui/party-ui-handler"; import PartyUiHandler, { PartyOption, PartyUiMode } from "#app/ui/party-ui-handler";
import SoundFade from "phaser3-rex-plugins/plugins/soundfade"; import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
import { LevelMoves } from "#app/data/balance/pokemon-level-moves"; import { EVOLVE_MOVE, LevelMoves, RELEARN_MOVE } from "#app/data/balance/pokemon-level-moves";
import { DamageAchv, achvs } from "#app/system/achv"; import { DamageAchv, achvs } from "#app/system/achv";
import { DexAttr, StarterDataEntry, StarterMoveset } from "#app/system/game-data"; import { DexAttr, StarterDataEntry, StarterMoveset } from "#app/system/game-data";
import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from "@material/material-color-utilities"; import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from "@material/material-color-utilities";
@ -70,6 +70,15 @@ import { BASE_HIDDEN_ABILITY_CHANCE, BASE_SHINY_CHANCE, SHINY_EPIC_CHANCE, SHINY
import { Nature } from "#enums/nature"; import { Nature } from "#enums/nature";
import { StatusEffect } from "#enums/status-effect"; import { StatusEffect } from "#enums/status-effect";
export enum LearnMoveSituation {
MISC,
LEVEL_UP,
RELEARN,
EVOLUTION,
EVOLUTION_FUSED, // If fusionSpecies has Evolved
EVOLUTION_FUSED_BASE // If fusion's base species has Evolved
}
export enum FieldPosition { export enum FieldPosition {
CENTER, CENTER,
LEFT, LEFT,
@ -1786,7 +1795,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return (atkScore + defScore) * hpDiffRatio; return (atkScore + defScore) * hpDiffRatio;
} }
getEvolution(): SpeciesFormEvolution | null { getEvolution(): SpeciesFormEvolution | FusionSpeciesFormEvolution | null {
if (pokemonEvolutions.hasOwnProperty(this.species.speciesId)) { if (pokemonEvolutions.hasOwnProperty(this.species.speciesId)) {
const evolutions = pokemonEvolutions[this.species.speciesId]; const evolutions = pokemonEvolutions[this.species.speciesId];
for (const e of evolutions) { for (const e of evolutions) {
@ -1820,40 +1829,44 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* @param {boolean} includeRelearnerMoves Whether to include moves that would require a relearner. Note the move relearner inherently allows evolution moves * @param {boolean} includeRelearnerMoves Whether to include moves that would require a relearner. Note the move relearner inherently allows evolution moves
* @returns {LevelMoves} A list of moves and the levels they can be learned at * @returns {LevelMoves} A list of moves and the levels they can be learned at
*/ */
getLevelMoves(startingLevel?: integer, includeEvolutionMoves: boolean = false, simulateEvolutionChain: boolean = false, includeRelearnerMoves: boolean = false): LevelMoves { getLevelMoves(startingLevel?: integer, includeEvolutionMoves: boolean = false, simulateEvolutionChain: boolean = false, includeRelearnerMoves: boolean = false, learnSituation: LearnMoveSituation = LearnMoveSituation.MISC): LevelMoves {
const ret: LevelMoves = []; const ret: LevelMoves = [];
let levelMoves: LevelMoves = []; let levelMoves: LevelMoves = [];
if (!startingLevel) { if (!startingLevel) {
startingLevel = this.level; startingLevel = this.level;
} }
if (simulateEvolutionChain) { if (learnSituation === LearnMoveSituation.EVOLUTION_FUSED && this.fusionSpecies) { // For fusion evolutions, get ONLY the moves of the component mon that evolved
const evolutionChain = this.species.getSimulatedEvolutionChain(this.level, this.hasTrainer(), this.isBoss(), this.isPlayer()); levelMoves = this.getFusionSpeciesForm(true).getLevelMoves().filter(lm => (includeEvolutionMoves && lm[0] === EVOLVE_MOVE) || (includeRelearnerMoves && lm[0] === RELEARN_MOVE) || lm[0] > 0);
for (let e = 0; e < evolutionChain.length; e++) {
// TODO: Might need to pass specific form index in simulated evolution chain
const speciesLevelMoves = getPokemonSpeciesForm(evolutionChain[e][0], this.formIndex).getLevelMoves();
if (includeRelearnerMoves) {
levelMoves.push(...speciesLevelMoves);
} else {
levelMoves.push(...speciesLevelMoves.filter(lm => (includeEvolutionMoves && lm[0] === 0) || ((!e || lm[0] > 1) && (e === evolutionChain.length - 1 || lm[0] <= evolutionChain[e + 1][1]))));
}
}
} else { } else {
levelMoves = this.getSpeciesForm(true).getLevelMoves().filter(lm => (includeEvolutionMoves && lm[0] === 0) || (includeRelearnerMoves && lm[0] === -1) || lm[0] > 0);
}
if (this.fusionSpecies) {
if (simulateEvolutionChain) { if (simulateEvolutionChain) {
const fusionEvolutionChain = this.fusionSpecies.getSimulatedEvolutionChain(this.level, this.hasTrainer(), this.isBoss(), this.isPlayer()); const evolutionChain = this.species.getSimulatedEvolutionChain(this.level, this.hasTrainer(), this.isBoss(), this.isPlayer());
for (let e = 0; e < fusionEvolutionChain.length; e++) { for (let e = 0; e < evolutionChain.length; e++) {
// TODO: Might need to pass specific form index in simulated evolution chain // TODO: Might need to pass specific form index in simulated evolution chain
const speciesLevelMoves = getPokemonSpeciesForm(fusionEvolutionChain[e][0], this.fusionFormIndex).getLevelMoves(); const speciesLevelMoves = getPokemonSpeciesForm(evolutionChain[e][0], this.formIndex).getLevelMoves();
if (includeRelearnerMoves) { if (includeRelearnerMoves) {
levelMoves.push(...speciesLevelMoves.filter(lm => (includeEvolutionMoves && lm[0] === 0) || lm[0] !== 0)); levelMoves.push(...speciesLevelMoves);
} else { } else {
levelMoves.push(...speciesLevelMoves.filter(lm => (includeEvolutionMoves && lm[0] === 0) || ((!e || lm[0] > 1) && (e === fusionEvolutionChain.length - 1 || lm[0] <= fusionEvolutionChain[e + 1][1])))); levelMoves.push(...speciesLevelMoves.filter(lm => (includeEvolutionMoves && lm[0] === EVOLVE_MOVE) || ((!e || lm[0] > 1) && (e === evolutionChain.length - 1 || lm[0] <= evolutionChain[e + 1][1]))));
} }
} }
} else { } else {
levelMoves.push(...this.getFusionSpeciesForm(true).getLevelMoves().filter(lm => (includeEvolutionMoves && lm[0] === 0) || (includeRelearnerMoves && lm[0] === -1) || lm[0] > 0)); levelMoves = this.getSpeciesForm(true).getLevelMoves().filter(lm => (includeEvolutionMoves && lm[0] === EVOLVE_MOVE) || (includeRelearnerMoves && lm[0] === RELEARN_MOVE) || lm[0] > 0);
}
if (this.fusionSpecies && learnSituation !== LearnMoveSituation.EVOLUTION_FUSED_BASE) { // For fusion evolutions, get ONLY the moves of the component mon that evolved
if (simulateEvolutionChain) {
const fusionEvolutionChain = this.fusionSpecies.getSimulatedEvolutionChain(this.level, this.hasTrainer(), this.isBoss(), this.isPlayer());
for (let e = 0; e < fusionEvolutionChain.length; e++) {
// TODO: Might need to pass specific form index in simulated evolution chain
const speciesLevelMoves = getPokemonSpeciesForm(fusionEvolutionChain[e][0], this.fusionFormIndex).getLevelMoves();
if (includeRelearnerMoves) {
levelMoves.push(...speciesLevelMoves.filter(lm => (includeEvolutionMoves && lm[0] === EVOLVE_MOVE) || lm[0] !== EVOLVE_MOVE));
} else {
levelMoves.push(...speciesLevelMoves.filter(lm => (includeEvolutionMoves && lm[0] === EVOLVE_MOVE) || ((!e || lm[0] > 1) && (e === fusionEvolutionChain.length - 1 || lm[0] <= fusionEvolutionChain[e + 1][1]))));
}
}
} else {
levelMoves.push(...this.getFusionSpeciesForm(true).getLevelMoves().filter(lm => (includeEvolutionMoves && lm[0] === EVOLVE_MOVE) || (includeRelearnerMoves && lm[0] === RELEARN_MOVE) || lm[0] > 0));
}
} }
} }
levelMoves.sort((lma: [integer, integer], lmb: [integer, integer]) => lma[0] > lmb[0] ? 1 : lma[0] < lmb[0] ? -1 : 0); levelMoves.sort((lma: [integer, integer], lmb: [integer, integer]) => lma[0] > lmb[0] ? 1 : lma[0] < lmb[0] ? -1 : 0);

View File

@ -1,17 +1,18 @@
import SoundFade from "phaser3-rex-plugins/plugins/soundfade"; import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
import { Phase } from "#app/phase"; import { Phase } from "#app/phase";
import BattleScene, { AnySound } from "#app/battle-scene"; import BattleScene, { AnySound } from "#app/battle-scene";
import { SpeciesFormEvolution } from "#app/data/balance/pokemon-evolutions"; import { FusionSpeciesFormEvolution, SpeciesFormEvolution } from "#app/data/balance/pokemon-evolutions";
import EvolutionSceneHandler from "#app/ui/evolution-scene-handler"; import EvolutionSceneHandler from "#app/ui/evolution-scene-handler";
import * as Utils from "#app/utils"; import * as Utils from "#app/utils";
import { Mode } from "#app/ui/ui"; import { Mode } from "#app/ui/ui";
import { cos, sin } from "#app/field/anims"; import { cos, sin } from "#app/field/anims";
import Pokemon, { PlayerPokemon } from "#app/field/pokemon"; import Pokemon, { LearnMoveSituation, PlayerPokemon } from "#app/field/pokemon";
import { getTypeRgb } from "#app/data/type"; import { getTypeRgb } from "#app/data/type";
import i18next from "i18next"; import i18next from "i18next";
import { getPokemonNameWithAffix } from "#app/messages"; import { getPokemonNameWithAffix } from "#app/messages";
import { LearnMovePhase } from "#app/phases/learn-move-phase"; import { LearnMovePhase } from "#app/phases/learn-move-phase";
import { EndEvolutionPhase } from "#app/phases/end-evolution-phase"; import { EndEvolutionPhase } from "#app/phases/end-evolution-phase";
import { EVOLVE_MOVE } from "#app/data/balance/pokemon-level-moves";
export class EvolutionPhase extends Phase { export class EvolutionPhase extends Phase {
protected pokemon: PlayerPokemon; protected pokemon: PlayerPokemon;
@ -20,6 +21,7 @@ export class EvolutionPhase extends Phase {
private preEvolvedPokemonName: string; private preEvolvedPokemonName: string;
private evolution: SpeciesFormEvolution | null; private evolution: SpeciesFormEvolution | null;
private fusionSpeciesEvolved: boolean; // Whether the evolution is of the fused species
private evolutionBgm: AnySound; private evolutionBgm: AnySound;
private evolutionHandler: EvolutionSceneHandler; private evolutionHandler: EvolutionSceneHandler;
@ -33,12 +35,13 @@ export class EvolutionPhase extends Phase {
protected pokemonEvoSprite: Phaser.GameObjects.Sprite; protected pokemonEvoSprite: Phaser.GameObjects.Sprite;
protected pokemonEvoTintSprite: Phaser.GameObjects.Sprite; protected pokemonEvoTintSprite: Phaser.GameObjects.Sprite;
constructor(scene: BattleScene, pokemon: PlayerPokemon, evolution: SpeciesFormEvolution | null, lastLevel: integer) { constructor(scene: BattleScene, pokemon: PlayerPokemon, evolution: SpeciesFormEvolution | FusionSpeciesFormEvolution | null, lastLevel: integer) {
super(scene); super(scene);
this.pokemon = pokemon; this.pokemon = pokemon;
this.evolution = evolution; this.evolution = evolution;
this.lastLevel = lastLevel; this.lastLevel = lastLevel;
this.fusionSpeciesEvolved = evolution instanceof FusionSpeciesFormEvolution;
} }
validate(): boolean { validate(): boolean {
@ -261,7 +264,8 @@ export class EvolutionPhase extends Phase {
this.evolutionHandler.canCancel = false; this.evolutionHandler.canCancel = false;
this.pokemon.evolve(this.evolution, this.pokemon.species).then(() => { this.pokemon.evolve(this.evolution, this.pokemon.species).then(() => {
const levelMoves = this.pokemon.getLevelMoves(this.lastLevel + 1, true); const learnSituation: LearnMoveSituation = this.fusionSpeciesEvolved ? LearnMoveSituation.EVOLUTION_FUSED : this.pokemon.fusionSpecies ? LearnMoveSituation.EVOLUTION_FUSED_BASE : LearnMoveSituation.EVOLUTION;
const levelMoves = this.pokemon.getLevelMoves(this.lastLevel + 1, true, false, false, learnSituation).filter(lm => lm[0] === EVOLVE_MOVE);
for (const lm of levelMoves) { for (const lm of levelMoves) {
this.scene.unshiftPhase(new LearnMovePhase(this.scene, this.scene.getPlayerParty().indexOf(this.pokemon), lm[1])); this.scene.unshiftPhase(new LearnMovePhase(this.scene, this.scene.getPlayerParty().indexOf(this.pokemon), lm[1]));
} }