[Refactor][Bug] Illusion no longer overwrites data of original Pokemon

https://github.com/pagefaultgames/pokerogue/pull/6140
This commit is contained in:
Sirz Benjie 2025-07-26 16:07:16 -06:00 committed by Bertie690
parent 6d7d2a5c6a
commit 89cbf7a01a
8 changed files with 164 additions and 175 deletions

View File

@ -8,20 +8,14 @@ import type { Variant } from "#sprites/variant";
* Data pertaining to a Pokemon's Illusion. * Data pertaining to a Pokemon's Illusion.
*/ */
export interface IllusionData { export interface IllusionData {
basePokemon: { /** The name of pokemon featured in the illusion */
/** The actual name of the Pokemon */
name: string; name: string;
/** The actual nickname of the Pokemon */ /** The nickname of the pokemon featured in the illusion */
nickname: string; nickname: string;
/** Whether the base pokemon is shiny or not */ /** Whether the pokemon featured in the illusion is shiny or not */
shiny: boolean; shiny: boolean;
/** The shiny variant of the base pokemon */ /** The variant of the pokemon featured in the illusion */
variant: Variant; variant: Variant;
/** Whether the fusion species of the base pokemon is shiny or not */
fusionShiny: boolean;
/** The variant of the fusion species of the base pokemon */
fusionVariant: Variant;
};
/** The species of the illusion */ /** The species of the illusion */
species: SpeciesId; species: SpeciesId;
/** The formIndex of the illusion */ /** The formIndex of the illusion */
@ -34,6 +28,10 @@ export interface IllusionData {
fusionSpecies?: PokemonSpecies; fusionSpecies?: PokemonSpecies;
/** The fusionFormIndex of the illusion */ /** The fusionFormIndex of the illusion */
fusionFormIndex?: number; fusionFormIndex?: number;
/** Whether the fusion species of the pokemon featured in the illusion is shiny or not */
fusionShiny?: boolean;
/** The variant of the fusion species of the pokemon featured in the illusion */
fusionVariant?: Variant;
/** The fusionGender of the illusion if it's a fusion */ /** The fusionGender of the illusion if it's a fusion */
fusionGender?: Gender; fusionGender?: Gender;
/** The level of the illusion (not used currently) */ /** The level of the illusion (not used currently) */

View File

@ -15,6 +15,7 @@ import { SpeciesFormChangeAbilityTrigger, SpeciesFormChangeWeatherTrigger } from
import { Gender } from "#data/gender"; import { Gender } from "#data/gender";
import { getPokeballName } from "#data/pokeball"; import { getPokeballName } from "#data/pokeball";
import { pokemonFormChanges } from "#data/pokemon-forms"; import { pokemonFormChanges } from "#data/pokemon-forms";
import type { PokemonSpecies } from "#data/pokemon-species";
import { getNonVolatileStatusEffects, getStatusEffectDescriptor, getStatusEffectHealText } from "#data/status-effect"; import { getNonVolatileStatusEffects, getStatusEffectDescriptor, getStatusEffectHealText } from "#data/status-effect";
import { TerrainType } from "#data/terrain"; import { TerrainType } from "#data/terrain";
import type { Weather } from "#data/weather"; import type { Weather } from "#data/weather";
@ -6001,8 +6002,13 @@ export class IllusionPreSummonAbAttr extends PreSummonAbAttr {
const party: Pokemon[] = (pokemon.isPlayer() ? globalScene.getPlayerParty() : globalScene.getEnemyParty()).filter( const party: Pokemon[] = (pokemon.isPlayer() ? globalScene.getPlayerParty() : globalScene.getEnemyParty()).filter(
p => p.isAllowedInBattle(), p => p.isAllowedInBattle(),
); );
const lastPokemon: Pokemon = party.filter(p => p !== pokemon).at(-1) || pokemon; let illusionPokemon: Pokemon | PokemonSpecies;
pokemon.setIllusion(lastPokemon); if (pokemon.hasTrainer()) {
illusionPokemon = party.filter(p => p !== pokemon).at(-1) || pokemon;
} else {
illusionPokemon = globalScene.arena.randomSpecies(globalScene.currentBattle.waveIndex, pokemon.level);
}
pokemon.setIllusion(illusionPokemon);
} }
/** @returns Whether the illusion can be applied. */ /** @returns Whether the illusion can be applied. */

View File

@ -442,10 +442,9 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
* @returns The name to render for this {@linkcode Pokemon}. * @returns The name to render for this {@linkcode Pokemon}.
*/ */
getNameToRender(useIllusion = true) { getNameToRender(useIllusion = true) {
const name: string = const illusion = this.summonData.illusion;
!useIllusion && this.summonData.illusion ? this.summonData.illusion.basePokemon.name : this.name; const name = useIllusion ? (illusion?.name ?? this.name) : this.name;
const nickname: string = const nickname: string = useIllusion ? (illusion?.nickname ?? this.nickname) : this.nickname;
!useIllusion && this.summonData.illusion ? this.summonData.illusion.basePokemon.nickname : this.nickname;
try { try {
if (nickname) { if (nickname) {
return decodeURIComponent(escape(atob(nickname))); // TODO: Remove `atob` and `escape`... eventually... return decodeURIComponent(escape(atob(nickname))); // TODO: Remove `atob` and `escape`... eventually...
@ -463,7 +462,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
* @returns The {@linkcode PokeballType} that will be shown when this Pokemon is sent out into battle. * @returns The {@linkcode PokeballType} that will be shown when this Pokemon is sent out into battle.
*/ */
getPokeball(useIllusion = false): PokeballType { getPokeball(useIllusion = false): PokeballType {
return useIllusion && this.summonData.illusion ? this.summonData.illusion.pokeball : this.pokeball; return useIllusion ? (this.summonData.illusion?.pokeball ?? this.pokeball) : this.pokeball;
} }
init(): void { init(): void {
@ -609,24 +608,33 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
} }
/** /**
* Generate an illusion of the last pokemon in the party, as other wild pokemon in the area. * Set this pokemon's illusion to the data of the given pokemon.
*
* @remarks
* When setting the illusion of a wild pokemon, a {@linkcode PokemonSpecies} is generally passed.
* When setting the illusion of a pokemon in this way, the fields required by illusion data
* but missing from `PokemonSpecies` are set as follows
* - `pokeball` and `nickname` are both inherited from this pokemon
* - `shiny` will always be set if this pokemon OR its fusion is shiny
* - `variant` will always be 0
* - Fields related to fusion will be set to `undefined` or `0` as appropriate
* - The gender is set to be the same as this pokemon, if it is compatible with the provided pokemon.
* - If the provided pokemon can only ever exist as one gender, it is always that gender
* - If this pokemon is genderless but the provided pokemon isn't, then a gender roll is done based on this
* pokemon's ID
*/ */
setIllusion(pokemon: Pokemon): boolean { setIllusion(pokemon: Pokemon | PokemonSpecies): boolean {
if (this.summonData.illusion) {
this.breakIllusion(); this.breakIllusion();
} if (pokemon instanceof Pokemon) {
if (this.hasTrainer()) {
const speciesId = pokemon.species.speciesId; const speciesId = pokemon.species.speciesId;
this.summonData.illusion = { this.summonData.illusion = {
basePokemon: { name: pokemon.name,
name: this.name, nickname: pokemon.nickname,
nickname: this.nickname, shiny: pokemon.shiny,
shiny: this.shiny, variant: pokemon.variant,
variant: this.variant, fusionShiny: pokemon.fusionShiny,
fusionShiny: this.fusionShiny, fusionVariant: pokemon.fusionVariant,
fusionVariant: this.fusionVariant,
},
species: speciesId, species: speciesId,
formIndex: pokemon.formIndex, formIndex: pokemon.formIndex,
gender: pokemon.gender, gender: pokemon.gender,
@ -636,54 +644,61 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
fusionGender: pokemon.fusionGender, fusionGender: pokemon.fusionGender,
}; };
this.name = pokemon.name; if (pokemon.shiny || pokemon.fusionShiny) {
this.nickname = pokemon.nickname;
this.shiny = pokemon.shiny;
this.variant = pokemon.variant;
this.fusionVariant = pokemon.fusionVariant;
this.fusionShiny = pokemon.fusionShiny;
if (this.shiny) {
this.initShinySparkle(); this.initShinySparkle();
} }
this.loadAssets(false, true).then(() => this.playAnim());
this.updateInfo();
} else { } else {
const randomIllusion: PokemonSpecies = globalScene.arena.randomSpecies( // Correct the gender in case the illusioned species has a gender incompatible with this pokemon
globalScene.currentBattle.waveIndex, let gender = this.gender;
this.level, switch (pokemon.malePercent) {
); case null:
gender = Gender.GENDERLESS;
break;
case 0:
gender = Gender.FEMALE;
break;
case 100:
gender = Gender.MALE;
break;
default:
gender = (this.id % 256) * 0.390625 < pokemon.malePercent ? Gender.MALE : Gender.FEMALE;
}
/*
TODO: Allow setting `variant` to something other than 0, which would require first loading the
assets for the provided species, as its entry would otherwise not
be guaranteed to exist in the `variantData` map. But this would prevent `summonData` from being populated
until the assets are loaded, which would cause issues as this method cannot be easily promisified.
*/
this.summonData.illusion = { this.summonData.illusion = {
basePokemon: { fusionShiny: false,
name: this.name, fusionVariant: 0,
shiny: this.shiny || this.fusionShiny,
variant: 0,
nickname: this.nickname, nickname: this.nickname,
shiny: this.shiny, name: pokemon.name,
variant: this.variant, species: pokemon.speciesId,
fusionShiny: this.fusionShiny, formIndex: pokemon.formIndex,
fusionVariant: this.fusionVariant, gender,
},
species: randomIllusion.speciesId,
formIndex: randomIllusion.formIndex,
gender: this.gender,
pokeball: this.pokeball, pokeball: this.pokeball,
}; };
this.name = randomIllusion.name; if (this.shiny || this.fusionShiny) {
this.loadAssets(false, true).then(() => this.playAnim()); this.initShinySparkle();
} }
}
this.loadAssets(false, true).then(() => this.playAnim());
this.updateInfo();
return true; return true;
} }
/**
* Break the illusion of this pokemon, if it has an active illusion.
* @returns Whether an illusion was broken.
*/
breakIllusion(): boolean { breakIllusion(): boolean {
if (!this.summonData.illusion) { if (!this.summonData.illusion) {
return false; return false;
} }
this.name = this.summonData.illusion.basePokemon.name;
this.nickname = this.summonData.illusion.basePokemon.nickname;
this.shiny = this.summonData.illusion.basePokemon.shiny;
this.variant = this.summonData.illusion.basePokemon.variant;
this.fusionVariant = this.summonData.illusion.basePokemon.fusionVariant;
this.fusionShiny = this.summonData.illusion.basePokemon.fusionShiny;
this.summonData.illusion = null; this.summonData.illusion = null;
if (this.isOnField()) { if (this.isOnField()) {
globalScene.playSound("PRSFX- Transform"); globalScene.playSound("PRSFX- Transform");
@ -718,8 +733,12 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
// Assets for moves // Assets for moves
loadPromises.push(loadMoveAnimations(this.getMoveset().map(m => m.getMove().id))); loadPromises.push(loadMoveAnimations(this.getMoveset().map(m => m.getMove().id)));
/** alias for `this.summonData.illusion`; bangs on this are safe when guarded with `useIllusion` being true */
const illusion = this.summonData.illusion;
useIllusion = useIllusion && !!illusion;
// Load the assets for the species form // Load the assets for the species form
const formIndex = useIllusion && this.summonData.illusion ? this.summonData.illusion.formIndex : this.formIndex; const formIndex = useIllusion ? illusion!.formIndex : this.formIndex;
loadPromises.push( loadPromises.push(
this.getSpeciesForm(false, useIllusion).loadAssets( this.getSpeciesForm(false, useIllusion).loadAssets(
this.getGender(useIllusion) === Gender.FEMALE, this.getGender(useIllusion) === Gender.FEMALE,
@ -736,16 +755,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
); );
} }
if (this.getFusionSpeciesForm()) { if (this.getFusionSpeciesForm()) {
const fusionFormIndex = const { fusionFormIndex, fusionShiny, fusionVariant } = useIllusion ? illusion! : this;
useIllusion && this.summonData.illusion ? this.summonData.illusion.fusionFormIndex : this.fusionFormIndex;
const fusionShiny =
!useIllusion && this.summonData.illusion?.basePokemon
? this.summonData.illusion.basePokemon.fusionShiny
: this.fusionShiny;
const fusionVariant =
!useIllusion && this.summonData.illusion?.basePokemon
? this.summonData.illusion.basePokemon.fusionVariant
: this.fusionVariant;
loadPromises.push( loadPromises.push(
this.getFusionSpeciesForm(false, useIllusion).loadAssets( this.getFusionSpeciesForm(false, useIllusion).loadAssets(
this.getFusionGender(false, useIllusion) === Gender.FEMALE, this.getFusionGender(false, useIllusion) === Gender.FEMALE,
@ -933,8 +943,8 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
return this.getSpeciesForm(ignoreOverride, false).getSpriteKey( return this.getSpeciesForm(ignoreOverride, false).getSpriteKey(
this.getGender(ignoreOverride) === Gender.FEMALE, this.getGender(ignoreOverride) === Gender.FEMALE,
this.formIndex, this.formIndex,
this.summonData.illusion?.basePokemon.shiny ?? this.shiny, this.isShiny(false),
this.summonData.illusion?.basePokemon.variant ?? this.variant, this.getVariant(false),
); );
} }
@ -977,11 +987,8 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
} }
getIconAtlasKey(ignoreOverride = false, useIllusion = true): string { getIconAtlasKey(ignoreOverride = false, useIllusion = true): string {
// TODO: confirm the correct behavior here (is it intentional that the check fails if `illusion.formIndex` is `0`?) const illusion = this.summonData.illusion;
const formIndex = const { formIndex, variant } = useIllusion && illusion ? illusion : this;
useIllusion && this.summonData.illusion?.formIndex ? this.summonData.illusion.formIndex : this.formIndex;
const variant =
!useIllusion && this.summonData.illusion ? this.summonData.illusion.basePokemon.variant : this.variant;
return this.getSpeciesForm(ignoreOverride, useIllusion).getIconAtlasKey( return this.getSpeciesForm(ignoreOverride, useIllusion).getIconAtlasKey(
formIndex, formIndex,
this.isBaseShiny(useIllusion), this.isBaseShiny(useIllusion),
@ -990,15 +997,8 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
} }
getFusionIconAtlasKey(ignoreOverride = false, useIllusion = true): string { getFusionIconAtlasKey(ignoreOverride = false, useIllusion = true): string {
// TODO: confirm the correct behavior here (is it intentional that the check fails if `illusion.fusionFormIndex` is `0`?) const illusion = this.summonData.illusion;
const fusionFormIndex = const { fusionFormIndex, fusionVariant } = useIllusion && illusion ? illusion : this;
useIllusion && this.summonData.illusion?.fusionFormIndex
? this.summonData.illusion.fusionFormIndex
: this.fusionFormIndex;
const fusionVariant =
!useIllusion && this.summonData.illusion
? this.summonData.illusion.basePokemon.fusionVariant
: this.fusionVariant;
return this.getFusionSpeciesForm(ignoreOverride, useIllusion).getIconAtlasKey( return this.getFusionSpeciesForm(ignoreOverride, useIllusion).getIconAtlasKey(
fusionFormIndex, fusionFormIndex,
this.isFusionShiny(), this.isFusionShiny(),
@ -1006,11 +1006,9 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
); );
} }
getIconId(ignoreOverride?: boolean, useIllusion = true): string { getIconId(ignoreOverride?: boolean, useIllusion = false): string {
const formIndex = const illusion = this.summonData.illusion;
useIllusion && this.summonData.illusion?.formIndex ? this.summonData.illusion?.formIndex : this.formIndex; const { formIndex, variant } = useIllusion && illusion ? illusion : this;
const variant =
!useIllusion && !!this.summonData.illusion ? this.summonData.illusion?.basePokemon.variant : this.variant;
return this.getSpeciesForm(ignoreOverride, useIllusion).getIconId( return this.getSpeciesForm(ignoreOverride, useIllusion).getIconId(
this.getGender(ignoreOverride, useIllusion) === Gender.FEMALE, this.getGender(ignoreOverride, useIllusion) === Gender.FEMALE,
formIndex, formIndex,
@ -1020,14 +1018,8 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
} }
getFusionIconId(ignoreOverride?: boolean, useIllusion = true): string { getFusionIconId(ignoreOverride?: boolean, useIllusion = true): string {
const fusionFormIndex = const illusion = this.summonData.illusion;
useIllusion && this.summonData.illusion?.fusionFormIndex const { fusionFormIndex, fusionVariant } = useIllusion && illusion ? illusion : this;
? this.summonData.illusion?.fusionFormIndex
: this.fusionFormIndex;
const fusionVariant =
!useIllusion && !!this.summonData.illusion
? this.summonData.illusion?.basePokemon.fusionVariant
: this.fusionVariant;
return this.getFusionSpeciesForm(ignoreOverride, useIllusion).getIconId( return this.getFusionSpeciesForm(ignoreOverride, useIllusion).getIconId(
this.getFusionGender(ignoreOverride, useIllusion) === Gender.FEMALE, this.getFusionGender(ignoreOverride, useIllusion) === Gender.FEMALE,
fusionFormIndex, fusionFormIndex,
@ -1703,29 +1695,23 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
* @returns Whether this Pokemon is shiny * @returns Whether this Pokemon is shiny
*/ */
isShiny(useIllusion = false): boolean { isShiny(useIllusion = false): boolean {
if (!useIllusion && this.summonData.illusion) { if (useIllusion) {
return ( const illusion = this.summonData.illusion;
this.summonData.illusion.basePokemon?.shiny || return illusion?.shiny || (!!illusion?.fusionSpecies && !!illusion.fusionShiny);
(this.summonData.illusion.fusionSpecies && this.summonData.illusion.basePokemon?.fusionShiny) ||
false
);
} }
return this.shiny || (this.isFusion(useIllusion) && this.fusionShiny); return this.shiny || (this.isFusion(useIllusion) && this.fusionShiny);
} }
isBaseShiny(useIllusion = false) { isBaseShiny(useIllusion = false) {
if (!useIllusion && this.summonData.illusion) { return useIllusion ? (this.summonData.illusion?.shiny ?? this.shiny) : this.shiny;
return !!this.summonData.illusion.basePokemon?.shiny;
}
return this.shiny;
} }
isFusionShiny(useIllusion = false) { isFusionShiny(useIllusion = false) {
if (!useIllusion && this.summonData.illusion) { if (!this.isFusion(useIllusion)) {
return !!this.summonData.illusion.basePokemon?.fusionShiny; return false;
} }
return this.isFusion(useIllusion) && this.fusionShiny; return useIllusion ? (this.summonData.illusion?.fusionShiny ?? this.fusionShiny) : this.fusionShiny;
} }
/** /**
@ -1734,39 +1720,48 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
* @returns Whether this pokemon's base and fusion counterparts are both shiny. * @returns Whether this pokemon's base and fusion counterparts are both shiny.
*/ */
isDoubleShiny(useIllusion = false): boolean { isDoubleShiny(useIllusion = false): boolean {
if (!useIllusion && this.summonData.illusion?.basePokemon) { return this.isFusion(useIllusion) && this.isBaseShiny(useIllusion) && this.isFusionShiny(useIllusion);
return (
this.isFusion(false) &&
this.summonData.illusion.basePokemon.shiny &&
this.summonData.illusion.basePokemon.fusionShiny
);
}
return this.isFusion(useIllusion) && this.shiny && this.fusionShiny;
} }
/** /**
* Return this Pokemon's {@linkcode Variant | shiny variant}. * Return this Pokemon's {@linkcode Variant | shiny variant}.
* If a fusion, returns the maximum of the two variants.
* Only meaningful if this pokemon is actually shiny. * Only meaningful if this pokemon is actually shiny.
* @param useIllusion - Whether to consider this pokemon's illusion if present; default `false` * @param useIllusion - Whether to consider this pokemon's illusion if present; default `false`
* @returns The shiny variant of this Pokemon. * @returns The shiny variant of this Pokemon.
*/ */
getVariant(useIllusion = false): Variant { getVariant(useIllusion = false): Variant {
if (!useIllusion && this.summonData.illusion) { const illusion = this.summonData.illusion;
return !this.isFusion(false) const baseVariant = useIllusion ? (illusion?.variant ?? this.variant) : this.variant;
? this.summonData.illusion.basePokemon!.variant if (!this.isFusion(useIllusion)) {
: (Math.max(this.variant, this.fusionVariant) as Variant); return baseVariant;
}
const fusionVariant = useIllusion ? (illusion?.fusionVariant ?? this.fusionVariant) : this.fusionVariant;
return Math.max(baseVariant, fusionVariant) as Variant;
} }
return !this.isFusion(true) ? this.variant : (Math.max(this.variant, this.fusionVariant) as Variant); /**
* Return the base pokemon's variant. Equivalent to {@linkcode getVariant} if this pokemon is not a fusion.
* @returns The shiny variant of this Pokemon's base species.
*/
getBaseVariant(useIllusion = false): Variant {
const illusion = this.summonData.illusion;
return useIllusion && illusion ? (illusion.variant ?? this.variant) : this.variant;
} }
// TODO: Clarify how this differs from `getVariant` /**
getBaseVariant(doubleShiny: boolean): Variant { * Return the fused pokemon's variant.
if (doubleShiny) { *
return this.summonData.illusion?.basePokemon?.variant ?? this.variant; * @remarks
* Always returns `0` if the pokemon is not a fusion.
* @returns The shiny variant of this pokemon's fusion species.
*/
getFusionVariant(useIllusion = false): Variant {
if (!this.isFusion(useIllusion)) {
return 0;
} }
return this.getVariant(); const illusion = this.summonData.illusion;
return illusion ? (illusion.fusionVariant ?? this.fusionVariant) : this.fusionVariant;
} }
/** /**
@ -1783,7 +1778,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
* @returns Whether this Pokemon is currently fused with another species. * @returns Whether this Pokemon is currently fused with another species.
*/ */
isFusion(useIllusion = false): boolean { isFusion(useIllusion = false): boolean {
return useIllusion && this.summonData.illusion ? !!this.summonData.illusion.fusionSpecies : !!this.fusionSpecies; return useIllusion ? !!this.summonData.illusion?.fusionSpecies : !!this.fusionSpecies;
} }
/** /**
@ -1793,9 +1788,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
* @see {@linkcode getNameToRender} - gets this Pokemon's display name. * @see {@linkcode getNameToRender} - gets this Pokemon's display name.
*/ */
getName(useIllusion = false): string { getName(useIllusion = false): string {
return !useIllusion && this.summonData.illusion?.basePokemon return useIllusion ? (this.summonData.illusion?.name ?? this.name) : this.name;
? this.summonData.illusion.basePokemon.name
: this.name;
} }
/** /**

View File

@ -135,7 +135,7 @@ export class EvolutionPhase extends Phase {
sprite sprite
.setPipelineData("ignoreTimeTint", true) .setPipelineData("ignoreTimeTint", true)
.setPipelineData("spriteKey", pokemon.getSpriteKey()) .setPipelineData("spriteKey", spriteKey)
.setPipelineData("shiny", pokemon.shiny) .setPipelineData("shiny", pokemon.shiny)
.setPipelineData("variant", pokemon.variant); .setPipelineData("variant", pokemon.variant);

View File

@ -88,12 +88,12 @@ export class PokemonData {
this.id = source.id; this.id = source.id;
this.player = sourcePokemon?.isPlayer() ?? source.player; this.player = sourcePokemon?.isPlayer() ?? source.player;
this.species = sourcePokemon?.species.speciesId ?? source.species; this.species = sourcePokemon?.species.speciesId ?? source.species;
this.nickname = sourcePokemon?.summonData.illusion?.basePokemon.nickname ?? source.nickname; this.nickname = source.nickname;
this.formIndex = Math.max(Math.min(source.formIndex, getPokemonSpecies(this.species).forms.length - 1), 0); this.formIndex = Math.max(Math.min(source.formIndex, getPokemonSpecies(this.species).forms.length - 1), 0);
this.abilityIndex = source.abilityIndex; this.abilityIndex = source.abilityIndex;
this.passive = source.passive; this.passive = source.passive;
this.shiny = sourcePokemon?.summonData.illusion?.basePokemon.shiny ?? source.shiny; this.shiny = source.shiny;
this.variant = sourcePokemon?.summonData.illusion?.basePokemon.variant ?? source.variant; this.variant = source.variant;
this.pokeball = source.pokeball ?? PokeballType.POKEBALL; this.pokeball = source.pokeball ?? PokeballType.POKEBALL;
this.level = source.level; this.level = source.level;
this.exp = source.exp; this.exp = source.exp;
@ -134,8 +134,8 @@ export class PokemonData {
this.fusionSpecies = sourcePokemon?.fusionSpecies?.speciesId ?? source.fusionSpecies; this.fusionSpecies = sourcePokemon?.fusionSpecies?.speciesId ?? source.fusionSpecies;
this.fusionFormIndex = source.fusionFormIndex; this.fusionFormIndex = source.fusionFormIndex;
this.fusionAbilityIndex = source.fusionAbilityIndex; this.fusionAbilityIndex = source.fusionAbilityIndex;
this.fusionShiny = sourcePokemon?.summonData.illusion?.basePokemon.fusionShiny ?? source.fusionShiny; this.fusionShiny = source.fusionShiny;
this.fusionVariant = sourcePokemon?.summonData.illusion?.basePokemon.fusionVariant ?? source.fusionVariant; this.fusionVariant = source.fusionVariant;
this.fusionGender = source.fusionGender; this.fusionGender = source.fusionGender;
this.fusionLuck = source.fusionLuck ?? (source.fusionShiny ? source.fusionVariant + 1 : 0); this.fusionLuck = source.fusionLuck ?? (source.fusionShiny ? source.fusionVariant + 1 : 0);
this.fusionTeraType = (source.fusionTeraType ?? 0) as PokemonType; this.fusionTeraType = (source.fusionTeraType ?? 0) as PokemonType;

View File

@ -1791,17 +1791,16 @@ class PartySlot extends Phaser.GameObjects.Container {
const shinyStar = globalScene.add.image(0, 0, `shiny_star_small${doubleShiny ? "_1" : ""}`); const shinyStar = globalScene.add.image(0, 0, `shiny_star_small${doubleShiny ? "_1" : ""}`);
shinyStar.setOrigin(0, 0); shinyStar.setOrigin(0, 0);
shinyStar.setPositionRelative(this.slotName, -9, 3); shinyStar.setPositionRelative(this.slotName, -9, 3);
shinyStar.setTint(getVariantTint(this.pokemon.getBaseVariant(doubleShiny))); shinyStar.setTint(getVariantTint(this.pokemon.getBaseVariant()));
slotInfoContainer.add(shinyStar); slotInfoContainer.add(shinyStar);
if (doubleShiny) { if (doubleShiny) {
const fusionShinyStar = globalScene.add.image(0, 0, "shiny_star_small_2"); const fusionShinyStar = globalScene.add
fusionShinyStar.setOrigin(0, 0); .image(0, 0, "shiny_star_small_2")
fusionShinyStar.setPosition(shinyStar.x, shinyStar.y); .setOrigin(0)
fusionShinyStar.setTint( .setPosition(shinyStar.x, shinyStar.y)
getVariantTint(this.pokemon.summonData.illusion?.basePokemon.fusionVariant ?? this.pokemon.fusionVariant), .setTint(getVariantTint(this.pokemon.fusionVariant));
);
slotInfoContainer.add(fusionShinyStar); slotInfoContainer.add(fusionShinyStar);
} }

View File

@ -354,18 +354,13 @@ export class SummaryUiHandler extends UiHandler {
} catch (err: unknown) { } catch (err: unknown) {
console.error(`Failed to play animation for ${spriteKey}`, err); console.error(`Failed to play animation for ${spriteKey}`, err);
} }
this.pokemonSprite.setPipelineData("teraColor", getTypeRgb(this.pokemon.getTeraType())); this.pokemonSprite
this.pokemonSprite.setPipelineData("isTerastallized", this.pokemon.isTerastallized); .setPipelineData("teraColor", getTypeRgb(this.pokemon.getTeraType()))
this.pokemonSprite.setPipelineData("ignoreTimeTint", true); .setPipelineData("isTerastallized", this.pokemon.isTerastallized)
this.pokemonSprite.setPipelineData("spriteKey", this.pokemon.getSpriteKey()); .setPipelineData("ignoreTimeTint", true)
this.pokemonSprite.setPipelineData( .setPipelineData("spriteKey", this.pokemon.getSpriteKey())
"shiny", .setPipelineData("shiny", this.pokemon.shiny)
this.pokemon.summonData.illusion?.basePokemon.shiny ?? this.pokemon.shiny, .setPipelineData("variant", this.pokemon.variant);
);
this.pokemonSprite.setPipelineData(
"variant",
this.pokemon.summonData.illusion?.basePokemon.variant ?? this.pokemon.variant,
);
["spriteColors", "fusionSpriteColors"].map(k => { ["spriteColors", "fusionSpriteColors"].map(k => {
delete this.pokemonSprite.pipelineData[`${k}Base`]; delete this.pokemonSprite.pipelineData[`${k}Base`];
if (this.pokemon?.summonData.speciesForm) { if (this.pokemon?.summonData.speciesForm) {
@ -463,9 +458,7 @@ export class SummaryUiHandler extends UiHandler {
this.fusionShinyIcon.setPosition(this.shinyIcon.x, this.shinyIcon.y); this.fusionShinyIcon.setPosition(this.shinyIcon.x, this.shinyIcon.y);
this.fusionShinyIcon.setVisible(doubleShiny); this.fusionShinyIcon.setVisible(doubleShiny);
if (isFusion) { if (isFusion) {
this.fusionShinyIcon.setTint( this.fusionShinyIcon.setTint(getVariantTint(this.pokemon.fusionVariant));
getVariantTint(this.pokemon.summonData.illusion?.basePokemon.fusionVariant ?? this.pokemon.fusionVariant),
);
} }
this.pokeball.setFrame(getPokeballAtlasKey(this.pokemon.pokeball)); this.pokeball.setFrame(getPokeballAtlasKey(this.pokemon.pokeball));

View File

@ -145,8 +145,8 @@ describe("Abilities - Illusion", () => {
const zoroark = game.scene.getPlayerPokemon()!; const zoroark = game.scene.getPlayerPokemon()!;
expect(zoroark.name).equals("Axew"); expect(zoroark.summonData.illusion?.name).equals("Axew");
expect(zoroark.getNameToRender()).equals("axew nickname"); expect(zoroark.getNameToRender(true)).equals("axew nickname");
expect(zoroark.getGender(false, true)).equals(Gender.FEMALE); expect(zoroark.getGender(false, true)).equals(Gender.FEMALE);
expect(zoroark.isShiny(true)).equals(true); expect(zoroark.isShiny(true)).equals(true);
expect(zoroark.getPokeball(true)).equals(PokeballType.GREAT_BALL); expect(zoroark.getPokeball(true)).equals(PokeballType.GREAT_BALL);