Fix Form Changes with Secondary Fusion Component

Allows form changes when you have a Pokemon chosen as the second component of a fusion. i.e. Charizard/Snorlax can still be Dynamaxed with a Max Mushroom.

This also allows these items to spawn where they wouldn't previously.
This commit is contained in:
Benjamin Odom 2024-05-03 00:15:31 -05:00
parent 6011794732
commit 4c29854c23
4 changed files with 74 additions and 38 deletions

View File

@ -2134,23 +2134,30 @@ export default class BattleScene extends SceneBase {
}
triggerPokemonFormChange(pokemon: Pokemon, formChangeTriggerType: { new(...args: any[]): SpeciesFormChangeTrigger }, delayed: boolean = false, modal: boolean = false): boolean {
if (pokemonFormChanges.hasOwnProperty(pokemon.species.speciesId)) {
const matchingFormChange = pokemonFormChanges[pokemon.species.speciesId].find(fc => fc.findTrigger(formChangeTriggerType) && fc.canChange(pokemon));
if (matchingFormChange) {
let phase: Phase;
if (pokemon instanceof PlayerPokemon && !matchingFormChange.quiet)
phase = new FormChangePhase(this, pokemon, matchingFormChange, modal);
else
phase = new QuietFormChangePhase(this, pokemon, matchingFormChange);
if (pokemon instanceof PlayerPokemon && !matchingFormChange.quiet && modal)
this.overridePhase(phase);
else if (delayed)
this.pushPhase(phase);
else
this.unshiftPhase(phase);
return true;
const speciesIds = [pokemon.species.speciesId];
if (pokemon.isFusion())
speciesIds.push(pokemon.fusionSpecies.speciesId)
speciesIds.forEach(speciesId =>
{
if (pokemonFormChanges.hasOwnProperty(speciesId)) {
const matchingFormChange = pokemonFormChanges[speciesId].find(fc => fc.findTrigger(formChangeTriggerType) && fc.canChange(pokemon));
if (matchingFormChange) {
let phase: Phase;
if (pokemon instanceof PlayerPokemon && !matchingFormChange.quiet)
phase = new FormChangePhase(this, pokemon, matchingFormChange, modal);
else
phase = new QuietFormChangePhase(this, pokemon, matchingFormChange);
if (pokemon instanceof PlayerPokemon && !matchingFormChange.quiet && modal)
this.overridePhase(phase);
else if (delayed)
this.pushPhase(phase);
else
this.unshiftPhase(phase);
return true;
}
}
}
});
return false;
}

View File

@ -7,6 +7,7 @@ import { Species } from "./enums/species";
import { StatusEffect } from "./status-effect";
import { MoveCategory, allMoves } from "./move";
import { Abilities } from "./enums/abilities";
import { PokemonSpecies } from "pokenode-ts";
export enum FormChangeItem {
NONE,
@ -105,29 +106,43 @@ export class SpeciesFormChange {
this.conditions = conditions;
}
canChange(pokemon: Pokemon): boolean {
if (pokemon.species.speciesId !== this.speciesId)
return false;
canChange(pokemon: Pokemon): boolean {
const speciesArray = [pokemon.species];
const formIndexes = [pokemon.formIndex];
if (!pokemon.species.forms.length)
return false;
if (pokemon.isFusion()) {
speciesArray.push(pokemon.fusionSpecies);
formIndexes.push(pokemon.fusionFormIndex);
}
const formKeys = pokemon.species.forms.map(f => f.formKey);
if (formKeys[pokemon.formIndex] !== this.preFormKey)
return false;
if (formKeys[pokemon.formIndex] === this.formKey)
return false;
for (let condition of this.conditions) {
if (!condition.predicate(pokemon))
return false;
const formMatch = [true, true];
for (let i = 0; i < speciesArray.length; ++i) {
const species = speciesArray[i];
const formIndex = formIndexes[i];
if (species.speciesId !== this.speciesId)
formMatch[i] = false;
if (!species.forms.length)
formMatch[i] = false;
const formKeys = species.forms.map(f => f.formKey);
if (formKeys[formIndex] !== this.preFormKey)
formMatch[i] = false;
if (formKeys[formIndex] === this.formKey)
formMatch[i] = false;
for (let condition of this.conditions) {
if (!condition.predicate(pokemon))
formMatch[i] = false;
}
if (!this.trigger.canChange(pokemon))
formMatch[i] = false;
}
if (!this.trigger.canChange(pokemon))
return false;
return true;
return formMatch.some(x => x);
}
findTrigger(triggerType: { new(...args: any[]): SpeciesFormChangeTrigger }): SpeciesFormChangeTrigger {
@ -304,7 +319,7 @@ export function getSpeciesFormChangeMessage(pokemon: Pokemon, formChange: Specie
const isMega = formChange.formKey.indexOf(SpeciesFormKey.MEGA) > -1;
const isGmax = formChange.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) > -1;
const isEmax = formChange.formKey.indexOf('eternamax') > -1;
const isRevert = !isMega && formChange.formKey === pokemon.species.forms[0].formKey;
const isRevert = !isMega && ((!!pokemon.species.forms.length && formChange.formKey === pokemon.species.forms[0].formKey) || (pokemon.isFusion() && pokemon.fusionSpecies.forms[0].formKey));
const prefix = !pokemon.isPlayer() ? pokemon.hasTrainer() ? 'Foe ' : 'Wild ' : 'Your ';
if (isMega)
return `${prefix}${preName} mega-evolved\ninto ${pokemon.name}!`;

View File

@ -2507,8 +2507,15 @@ export class PlayerPokemon extends Pokemon {
}
changeForm(formChange: SpeciesFormChange): Promise<void> {
const matchesBase = this.species.speciesId == formChange.speciesId;
return new Promise(resolve => {
this.formIndex = Math.max(this.species.forms.findIndex(f => f.formKey === formChange.formKey), 0);
const newFormIndex = Math.max((matchesBase ? this.species : this.fusionSpecies).forms.findIndex(f => f.formKey === formChange.formKey), 0);
if (matchesBase)
this.formIndex = newFormIndex;
else
this.fusionFormIndex = newFormIndex;
this.generateName();
const abilityCount = this.getSpeciesForm().getAbilityCount();
if (this.abilityIndex >= abilityCount) // Shouldn't happen

View File

@ -574,6 +574,10 @@ export class FormChangeItemModifierType extends PokemonModifierType implements G
&& (fc.trigger as SpeciesFormChangeItemTrigger).item === this.formChangeItem))
return null;
if (pokemon.isFusion() && pokemonFormChanges.hasOwnProperty(pokemon.fusionSpecies.speciesId) && !!pokemonFormChanges[pokemon.fusionSpecies.speciesId].find(fc => fc.trigger.hasTriggerType(SpeciesFormChangeItemTrigger)
&& (fc.trigger as SpeciesFormChangeItemTrigger).item === this.formChangeItem))
return null;
return PartyUiHandler.NoEffectMessage;
}, FormChangeItem[formChangeItem].toLowerCase());
@ -686,7 +690,10 @@ class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator {
return new FormChangeItemModifierType(pregenArgs[0] as FormChangeItem);
const formChangeItemPool = party.filter(p => pokemonFormChanges.hasOwnProperty(p.species.speciesId)).map(p => {
const formChanges = pokemonFormChanges[p.species.speciesId];
let formChanges = pokemonFormChanges[p.species.speciesId];
if(p.isFusion())
formChanges = formChanges.concat(pokemonFormChanges[p.fusionSpecies.speciesId]);
return formChanges.filter(fc => ((fc.formKey.indexOf(SpeciesFormKey.MEGA) === -1 && fc.formKey.indexOf(SpeciesFormKey.PRIMAL) === -1) || party[0].scene.getModifiers(Modifiers.MegaEvolutionAccessModifier).length)
&& ((fc.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) === -1 && fc.formKey.indexOf(SpeciesFormKey.ETERNAMAX) === -1) || party[0].scene.getModifiers(Modifiers.GigantamaxAccessModifier).length))
.map(fc => fc.findTrigger(SpeciesFormChangeItemTrigger) as SpeciesFormChangeItemTrigger)