Add evolution for secondary fusion species

pull/45/head
Flashfyre 2024-04-05 21:12:29 -04:00
parent 1085e0f692
commit 4c383e105f
5 changed files with 99 additions and 29 deletions

View File

@ -85,6 +85,16 @@ export class SpeciesEvolution extends SpeciesFormEvolution {
}
}
export class FusionSpeciesFormEvolution extends SpeciesFormEvolution {
public primarySpeciesId: Species;
constructor(primarySpeciesId: Species, evolution: SpeciesFormEvolution) {
super(evolution.speciesId, evolution.preFormKey, evolution.evoFormKey, evolution.level, evolution.item, evolution.condition, evolution.wildDelay);
this.primarySpeciesId = primarySpeciesId;
}
}
export class SpeciesEvolutionCondition {
public predicate: EvolutionConditionPredicate;
public enforceFunc: EvolutionConditionEnforceFunc;

View File

@ -13,7 +13,7 @@ import { PokeballType } from '../data/pokeball';
import { Gender } from '../data/gender';
import { initMoveAnim, loadMoveAnimAssets } from '../data/battle-anims';
import { Status, StatusEffect } from '../data/status-effect';
import { pokemonEvolutions, pokemonPrevolutions, SpeciesFormEvolution, SpeciesEvolutionCondition } from '../data/pokemon-evolutions';
import { pokemonEvolutions, pokemonPrevolutions, SpeciesFormEvolution, SpeciesEvolutionCondition, FusionSpeciesFormEvolution } from '../data/pokemon-evolutions';
import { reverseCompatibleTms, tmSpecies } from '../data/tms';
import { DamagePhase, FaintPhase, LearnMovePhase, ObtainStatusEffectPhase, StatChangePhase, SwitchSummonPhase } from '../phases';
import { BattleStat } from '../data/battle-stat';
@ -620,6 +620,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return this.shiny || (this.fusionSpecies && this.fusionShiny);
}
isFusion(): boolean {
return !!this.fusionSpecies;
}
abstract isBoss(): boolean;
getMoveset(ignoreOverride?: boolean): PokemonMove[] {
@ -766,9 +770,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
getEvolution(): SpeciesFormEvolution {
if (!pokemonEvolutions.hasOwnProperty(this.species.speciesId))
return null;
if (pokemonEvolutions.hasOwnProperty(this.species.speciesId)) {
const evolutions = pokemonEvolutions[this.species.speciesId];
for (let e of evolutions) {
if (!e.item && this.level >= e.level && (!e.preFormKey || this.getFormKey() === e.preFormKey)) {
@ -776,6 +778,17 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return e;
}
}
}
if (this.isFusion() && pokemonEvolutions.hasOwnProperty(this.fusionSpecies.speciesId)) {
const fusionEvolutions = pokemonEvolutions[this.fusionSpecies.speciesId].map(e => new FusionSpeciesFormEvolution(this.species.speciesId, e));
for (let fe of fusionEvolutions) {
if (!fe.item && this.level >= fe.level && (!fe.preFormKey || this.getFusionFormKey() === fe.preFormKey)) {
if (fe.condition === null || (fe.condition as SpeciesEvolutionCondition).predicate(this))
return fe;
}
}
}
return null;
}
@ -2116,9 +2129,21 @@ export class PlayerPokemon extends Pokemon {
getPossibleEvolution(evolution: SpeciesFormEvolution): Promise<Pokemon> {
return new Promise(resolve => {
const species = getPokemonSpecies(evolution.speciesId);
const formIndex = evolution.evoFormKey !== null ? Math.max(species.forms.findIndex(f => f.formKey === evolution.evoFormKey), 0) : this.formIndex;
const ret = this.scene.addPlayerPokemon(species, this.level, this.abilityIndex, formIndex, this.gender, this.shiny, this.ivs, this.nature, this);
const evolutionSpecies = getPokemonSpecies(evolution.speciesId);
const isFusion = evolution instanceof FusionSpeciesFormEvolution;
let ret: PlayerPokemon;
if (isFusion) {
const originalFusionSpecies = this.fusionSpecies;
const originalFusionFormIndex = this.fusionFormIndex;
this.fusionSpecies = evolutionSpecies;
this.fusionFormIndex = evolution.evoFormKey !== null ? Math.max(evolutionSpecies.forms.findIndex(f => f.formKey === evolution.evoFormKey), 0) : this.fusionFormIndex;
ret = this.scene.addPlayerPokemon(this.species, this.level, this.abilityIndex, this.formIndex, this.gender, this.shiny, this.ivs, this.nature, this);
this.fusionSpecies = originalFusionSpecies;
this.fusionFormIndex = originalFusionFormIndex;
} else {
const formIndex = evolution.evoFormKey !== null && !isFusion ? Math.max(evolutionSpecies.forms.findIndex(f => f.formKey === evolution.evoFormKey), 0) : this.formIndex;
ret = this.scene.addPlayerPokemon(!isFusion ? evolutionSpecies : this.species, this.level, this.abilityIndex, formIndex, this.gender, this.shiny, this.ivs, this.nature, this);
}
ret.loadAssets().then(() => resolve(ret));
});
}
@ -2127,13 +2152,28 @@ export class PlayerPokemon extends Pokemon {
return new Promise(resolve => {
this.pauseEvolutions = false;
this.handleSpecialEvolutions(evolution);
const isFusion = evolution instanceof FusionSpeciesFormEvolution;
if (!isFusion)
this.species = getPokemonSpecies(evolution.speciesId);
if (evolution.preFormKey !== null)
this.formIndex = Math.max(this.species.forms.findIndex(f => f.formKey === evolution.evoFormKey), 0);
else
this.fusionSpecies = getPokemonSpecies(evolution.speciesId);
if (evolution.preFormKey !== null) {
const formIndex = Math.max((!isFusion ? this.species : this.fusionSpecies).forms.findIndex(f => f.formKey === evolution.evoFormKey), 0);
if (!isFusion)
this.formIndex = formIndex;
else
this.fusionFormIndex = formIndex;
}
this.generateName();
if (!isFusion) {
const abilityCount = this.getSpeciesForm().getAbilityCount();
if (this.abilityIndex >= abilityCount) // Shouldn't happen
this.abilityIndex = abilityCount - 1;
} else {
const abilityCount = this.getFusionSpeciesForm().getAbilityCount();
if (this.fusionAbilityIndex >= abilityCount) // Shouldn't happen
this.fusionAbilityIndex = abilityCount - 1;
}
this.compatibleTms.splice(0, this.compatibleTms.length);
this.generateCompatibleTms();
const updateAndResolve = () => {
@ -2152,11 +2192,17 @@ export class PlayerPokemon extends Pokemon {
}
private handleSpecialEvolutions(evolution: SpeciesFormEvolution) {
if (this.species.speciesId === Species.NINCADA && evolution.speciesId === Species.NINJASK) {
const isFusion = evolution instanceof FusionSpeciesFormEvolution;
if ((!isFusion ? this.species : this.fusionSpecies).speciesId === Species.NINCADA && evolution.speciesId === Species.NINJASK) {
const newEvolution = pokemonEvolutions[this.species.speciesId][1];
if (newEvolution.condition.predicate(this)) {
const newPokemon = this.scene.addPlayerPokemon(this.species, this.level, this.abilityIndex, this.formIndex, this.gender, this.shiny, this.ivs, this.nature);
newPokemon.natureOverride = this.natureOverride;
newPokemon.fusionSpecies = this.fusionSpecies;
newPokemon.fusionFormIndex = this.fusionFormIndex;
newPokemon.fusionAbilityIndex = this.fusionAbilityIndex;
newPokemon.fusionShiny = this.fusionShiny;
newPokemon.fusionGender = this.fusionGender;
this.scene.getParty().push(newPokemon);
newPokemon.evolve(newEvolution);
const modifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
@ -2203,10 +2249,6 @@ export class PlayerPokemon extends Pokemon {
});
}
isFusion(): boolean {
return !!this.fusionSpecies;
}
clearFusionSpecies(): void {
super.clearFusionSpecies();
this.generateCompatibleTms();

View File

@ -513,6 +513,9 @@ export class EvolutionItemModifierType extends PokemonModifierType implements Ge
if (pokemonEvolutions.hasOwnProperty(pokemon.species.speciesId) && pokemonEvolutions[pokemon.species.speciesId].filter(e => e.item === this.evolutionItem
&& (!e.condition || e.condition.predicate(pokemon))).length)
return null;
else if (pokemon.isFusion() && pokemonEvolutions.hasOwnProperty(pokemon.fusionSpecies.speciesId) && pokemonEvolutions[pokemon.fusionSpecies.speciesId].filter(e => e.item === this.evolutionItem
&& (!e.condition || e.condition.predicate(pokemon))).length)
return null;
return PartyUiHandler.NoEffectMessage;
}, EvolutionItem[evolutionItem].toLowerCase());
@ -621,10 +624,16 @@ class EvolutionItemModifierTypeGenerator extends ModifierTypeGenerator {
if (pregenArgs)
return new EvolutionItemModifierType(pregenArgs[0] as EvolutionItem);
const evolutionItemPool = party.filter(p => pokemonEvolutions.hasOwnProperty(p.species.speciesId)).map(p => {
const evolutionItemPool = [
party.filter(p => pokemonEvolutions.hasOwnProperty(p.species.speciesId)).map(p => {
const evolutions = pokemonEvolutions[p.species.speciesId];
return evolutions.filter(e => e.item !== EvolutionItem.NONE && (e.evoFormKey === null || (e.preFormKey || '') === p.getFormKey()) && (!e.condition || e.condition.predicate(p)));
}).flat().flatMap(e => e.item).filter(i => (i > 50) === rare);
}).flat(),
party.filter(p => p.isFusion() && pokemonEvolutions.hasOwnProperty(p.fusionSpecies.speciesId)).map(p => {
const evolutions = pokemonEvolutions[p.fusionSpecies.speciesId];
return evolutions.filter(e => e.item !== EvolutionItem.NONE && (e.evoFormKey === null || (e.preFormKey || '') === p.getFusionFormKey()) && (!e.condition || e.condition.predicate(p)));
}).flat()
].flat().flatMap(e => e.item).filter(i => (i > 50) === rare);
if (!evolutionItemPool.length)
return null;

View File

@ -8,7 +8,7 @@ import { Stat } from "../data/pokemon-stat";
import { addTextObject, TextStyle } from "../ui/text";
import { Type } from '../data/type';
import { EvolutionPhase } from '../evolution-phase';
import { pokemonEvolutions } from '../data/pokemon-evolutions';
import { FusionSpeciesFormEvolution, pokemonEvolutions } from '../data/pokemon-evolutions';
import { getPokemonMessage } from '../messages';
import * as Utils from "../utils";
import { TempBattleStat } from '../data/temp-battle-stat';
@ -1183,10 +1183,18 @@ export class EvolutionItemModifier extends ConsumablePokemonModifier {
apply(args: any[]): boolean {
const pokemon = args[0] as PlayerPokemon;
const matchingEvolution = pokemonEvolutions[pokemon.species.speciesId].find(e => e.item === (this.type as ModifierTypes.EvolutionItemModifierType).evolutionItem
let matchingEvolution = pokemonEvolutions[pokemon.species.speciesId].find(e => e.item === (this.type as ModifierTypes.EvolutionItemModifierType).evolutionItem
&& (e.evoFormKey === null || (e.preFormKey || '') === pokemon.getFormKey())
&& (!e.condition || e.condition.predicate(pokemon)));
if (!matchingEvolution && pokemon.isFusion()) {
matchingEvolution = pokemonEvolutions[pokemon.fusionSpecies.speciesId].find(e => e.item === (this.type as ModifierTypes.EvolutionItemModifierType).evolutionItem
&& (e.evoFormKey === null || (e.preFormKey || '') === pokemon.getFusionFormKey())
&& (!e.condition || e.condition.predicate(pokemon)));
if (matchingEvolution)
matchingEvolution = new FusionSpeciesFormEvolution(pokemon.species.speciesId, matchingEvolution);
}
if (matchingEvolution) {
pokemon.scene.unshiftPhase(new EvolutionPhase(pokemon.scene, pokemon, matchingEvolution, pokemon.level - 1));
return true;

View File

@ -3752,6 +3752,7 @@ export class AttemptCapturePhase extends PokemonPhase {
this.scene.playSound('pb_rel');
pokemon.setY(this.originalY);
if (pokemon.status?.effect !== StatusEffect.SLEEP)
pokemon.cry(pokemon.getHpRatio() > 0.25 ? undefined : { rate: 0.85 });
pokemon.tint(getPokeballTintColor(this.pokeballType));
pokemon.setVisible(true);