diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 5afb9cd8e00..cc9577249b6 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -886,16 +886,16 @@ export default class BattleScene extends SceneBase { return true; } - public getPlayerParty(fakeShininess = true): PlayerPokemon[] { + public getPlayerParty(useIllusion = true): PlayerPokemon[] { const party = this.party; - if (!fakeShininess) { + if (!useIllusion) { party.map(pokemon => { pokemon.shiny = pokemon.isShiny(); pokemon.variant = pokemon.getVariant(); pokemon.name = pokemon.getNameToRender(); if (pokemon.isFusion()) { - pokemon.fusionVariant = pokemon.battleData?.illusion.basePokemon?.fusionVariant ?? pokemon.fusionVariant; - pokemon.fusionShiny = pokemon.battleData?.illusion.basePokemon?.fusionShiny ?? pokemon.fusionShiny; + pokemon.fusionVariant = pokemon.summonData?.illusion?.basePokemon.fusionVariant ?? pokemon.fusionVariant; + pokemon.fusionShiny = pokemon.summonData?.illusion?.basePokemon.fusionShiny ?? pokemon.fusionShiny; } }); } diff --git a/src/data/ability.ts b/src/data/ability.ts index b89c6d28459..2967565b01e 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -2785,7 +2785,7 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr { const targets = pokemon.getOpponents(); const target = this.getTarget(targets); - if (target.battleData.illusion.active) { + if (!!target.summonData?.illusion) { return false; } @@ -5225,11 +5225,22 @@ export class IllusionPreSummonAbAttr extends PreSummonAbAttr { * @returns {boolean} - Whether the illusion was applied. */ override applyPreSummon(pokemon: Pokemon, passive: boolean, args: any[]): void { - pokemon.generateIllusion(); + const party: Pokemon[] = (pokemon.isPlayer() ? globalScene.getPlayerParty() : globalScene.getEnemyParty()).filter(p => p.isAllowedInBattle()); + const lastPokemon: Pokemon = party.filter(p => p !==pokemon).at(-1) || pokemon; + pokemon.setIllusion(lastPokemon); } override canApplyPreSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean { - return pokemon.battleData.illusion.available && pokemon.canApplyAbility(); + if(pokemon.hasTrainer()){ + const party: Pokemon[] = (pokemon.isPlayer() ? globalScene.getPlayerParty() : globalScene.getEnemyParty()).filter(p => p.isAllowedInBattle()); + const lastPokemon: Pokemon = party.filter(p => p !==pokemon).at(-1) || pokemon; + const speciesId = lastPokemon.species.speciesId; + if ( lastPokemon === pokemon || !!pokemon.summonData?.illusion || + ((speciesId === Species.OGERPON || speciesId === Species.TERAPAGOS) && (lastPokemon.isTerastallized || pokemon.isTerastallized))) { + return false; + } + } + return pokemon.canApplyAbility(); } } @@ -5251,7 +5262,7 @@ export class IllusionBreakAbAttr extends PostDefendAbAttr { override canApplyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { const breakIllusion: HitResult[] = [ HitResult.EFFECTIVE, HitResult.SUPER_EFFECTIVE, HitResult.NOT_VERY_EFFECTIVE, HitResult.ONE_HIT_KO ]; - return breakIllusion.includes(hitResult) && pokemon.battleData.illusion.active + return breakIllusion.includes(hitResult) && !!pokemon.summonData?.illusion } } @@ -5265,10 +5276,11 @@ export class IllusionPostBattleAbAttr extends PostBattleAbAttr { * @returns {boolean} - Whether the illusion was applied. */ override applyPostBattle(pokemon: Pokemon, passive: boolean, simulated:boolean, args: any[]): void { - const illusion = pokemon.breakIllusion(); + /*const illusion = pokemon.breakIllusion(); if (illusion) { - pokemon.battleData.illusion.available = true; - } + pokemon.summonData?.illusion.available = true; + }*/ + pokemon.breakIllusion() } } @@ -6832,9 +6844,9 @@ export function initAbilities() { }, 1.3), new Ability(Abilities.ILLUSION, 5) //The pokemon generate an illusion if it's available - .conditionalAttr((pokemon) => pokemon.battleData.illusion.available, IllusionPreSummonAbAttr, false) + .attr(IllusionPreSummonAbAttr, false) //The pokemon loses his illusion when he is damaged by a move - .conditionalAttr((pokemon) => pokemon.battleData.illusion.active, IllusionBreakAbAttr, true) + .attr(IllusionBreakAbAttr, true) //Illusion is available again after a battle .conditionalAttr((pokemon) => pokemon.isAllowedInBattle(), IllusionPostBattleAbAttr, false) .uncopiable() diff --git a/src/data/moves/move.ts b/src/data/moves/move.ts index d2c27723dfc..27e097b3279 100644 --- a/src/data/moves/move.ts +++ b/src/data/moves/move.ts @@ -8654,7 +8654,7 @@ export function initMoves() { new StatusMove(Moves.TRANSFORM, PokemonType.NORMAL, -1, 10, -1, 0, 1) .attr(TransformAttr) .condition((user, target, move) => !target.getTag(BattlerTagType.SUBSTITUTE)) - .condition((user, target, move) => !target.battleData.illusion.active && !user.battleData.illusion.active) + .condition((user, target, move) => !target.summonData?.illusion && !user.summonData?.illusion) // transforming from or into fusion pokemon causes various problems (such as crashes) .condition((user, target, move) => !target.getTag(BattlerTagType.SUBSTITUTE) && !user.fusionSpecies && !target.fusionSpecies) .ignoresProtect(), diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index ae547a12319..0d0c10a0223 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -544,8 +544,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param {boolean} useIllusion - Whether we want the fake name or the real name of the Pokemon (for Illusion ability). */ getNameToRender(useIllusion: boolean = true) { - const name: string = (!useIllusion && this.battleData?.illusion.active) ? this.battleData?.illusion.basePokemon!.name : this.name; - const nickname: string = (!useIllusion && this.battleData?.illusion.active) ? this.battleData?.illusion.basePokemon!.nickname : this.nickname; + const name: string = (!useIllusion && !!this.summonData?.illusion) ? this.summonData?.illusion.basePokemon!.name : this.name; + const nickname: string = (!useIllusion && !!this.summonData?.illusion) ? this.summonData?.illusion.basePokemon!.nickname : this.nickname; try { if (nickname) { return decodeURIComponent(escape(atob(nickname))); @@ -559,7 +559,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { init(): void { this.fieldPosition = FieldPosition.CENTER; - this.resetBattleData(); + this.summonData = new PokemonSummonData(); this.initBattleInfo(); globalScene.fieldUI.addAt(this.battleInfo, 0); @@ -697,58 +697,47 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param {Pokemon} pokemon - The Pokemon that will create an illusion. * @param {Pokemon[]} party - The party of the trainer's pokemon. */ - generateIllusion(): boolean { + setIllusion(pokemon: Pokemon): boolean { if (this.hasTrainer()) { - const party: Pokemon[] = (this.isPlayer() ? globalScene.getPlayerParty() : globalScene.getEnemyParty()).filter(p => p.isAllowedInBattle()); - const lastPokemon: Pokemon = party.filter(p => p !== this).at(-1) || this; - const speciesId = lastPokemon.species.speciesId; + const speciesId = pokemon.species.speciesId; - if ( lastPokemon === this || this.battleData.illusion.active || - ((speciesId === Species.OGERPON || speciesId === Species.TERAPAGOS) && (lastPokemon.isTerastallized || this.isTerastallized))) { - return false; - } - - this.battleData.illusion = { - active: true, - available: true, + this.summonData.illusion = { basePokemon: { ...this }, species: getPokemonSpecies(speciesId), - formIndex: lastPokemon.formIndex, - gender: lastPokemon.gender, - pokeball: lastPokemon.pokeball, - fusionFormIndex: lastPokemon.fusionFormIndex, - fusionSpecies: lastPokemon.fusionSpecies || undefined, - fusionGender: lastPokemon.fusionGender + formIndex: pokemon.formIndex, + gender: pokemon.gender, + pokeball: pokemon.pokeball, + fusionFormIndex: pokemon.fusionFormIndex, + fusionSpecies: pokemon.fusionSpecies || undefined, + fusionGender: pokemon.fusionGender }; - this.name = lastPokemon.name; - this.nickname = lastPokemon.nickname; - this.shiny = lastPokemon.shiny; - this.variant = lastPokemon.variant; - this.fusionVariant = lastPokemon.fusionVariant; - this.fusionShiny = lastPokemon.fusionShiny; + this.name = pokemon.name; + 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.loadAssets(false, true).then(() => this.playAnim()); this.updateInfo(); } else { - const availables: Species[] = []; const randomIllusion: PokemonSpecies = globalScene.arena.randomSpecies(globalScene.currentBattle.waveIndex, this.level); /* if (this.isBoss()) { - availables = [ Species.ENTEI, Species.RAIKOU, Species.SUICUNE ]; + const availables = [ Species.ENTEI, Species.RAIKOU, Species.SUICUNE ]; randomIllusion = getPokemonSpecies(availables[this.randSeedInt(availables.length)]); } */ - this.battleData.illusion = { - active: true, - available: true, + this.summonData.illusion = { basePokemon: { ...this }, species: randomIllusion, formIndex: randomIllusion.formIndex, - gender: this.gender + gender: this.gender, + pokeball: this.pokeball }; this.name = randomIllusion.name; @@ -758,16 +747,17 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } breakIllusion(): boolean { - if (!this.battleData?.illusion.active) { + if (!this.summonData?.illusion) { return false; + } else { + this.name = this.summonData?.illusion.basePokemon.name ?? this.name; + this.nickname = this.summonData?.illusion.basePokemon.nickname ?? this.nickname; + this.shiny = this.summonData?.illusion.basePokemon.shiny ?? this.shiny; + this.variant = this.summonData?.illusion.basePokemon.variant ?? this.variant; + this.fusionVariant = this.summonData?.illusion.basePokemon.fusionVariant ?? this.fusionVariant; + this.fusionShiny = this.summonData?.illusion.basePokemon.fusionShiny ?? this.fusionShiny; + this.summonData.illusion = null; } - this.name = this.battleData?.illusion.basePokemon?.name ?? this.name; - this.nickname = this.battleData?.illusion.basePokemon?.nickname ?? this.nickname; - this.shiny = this.battleData?.illusion.basePokemon?.shiny ?? this.shiny; - this.variant = this.battleData?.illusion.basePokemon?.variant ?? this.variant; - this.fusionVariant = this.battleData?.illusion.basePokemon?.fusionVariant ?? this.fusionVariant; - this.fusionShiny = this.battleData?.illusion.basePokemon?.fusionShiny ?? this.fusionShiny; - this.battleData.illusion = { active: false, available: false, basePokemon: this }; if (this.isOnField()) { globalScene.playSound("PRSFX- Transform"); } @@ -796,7 +786,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const moveIds = this.getMoveset().map(m => m.getMove().id); Promise.allSettled(moveIds.map(m => initMoveAnim(m))).then(() => { loadMoveAnimAssets(moveIds); - const formIndex = this.battleData?.illusion.active && useIllusion ? this.battleData?.illusion.formIndex : this.formIndex; + const formIndex = !!this.summonData?.illusion && useIllusion ? this.summonData?.illusion.formIndex : this.formIndex; this.getSpeciesForm(false, useIllusion).loadAssets( this.getGender(useIllusion) === Gender.FEMALE, formIndex, @@ -810,9 +800,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { ); } if (this.getFusionSpeciesForm(false, useIllusion)) { - const fusionFormIndex = this.battleData?.illusion.active && useIllusion ? this.battleData?.illusion.fusionFormIndex : this.fusionFormIndex; - const fusionShiny = this.battleData?.illusion.active && !useIllusion ? this.battleData?.illusion.basePokemon!.fusionShiny : this.fusionShiny; - const fusionVariant = this.battleData?.illusion.active && !useIllusion ? this.battleData?.illusion.basePokemon!.fusionVariant : this.fusionVariant; + const fusionFormIndex = !!this.summonData?.illusion && useIllusion ? this.summonData?.illusion.fusionFormIndex : this.fusionFormIndex; + const fusionShiny = !!this.summonData?.illusion && !useIllusion ? this.summonData?.illusion.basePokemon!.fusionShiny : this.fusionShiny; + const fusionVariant = !!this.summonData?.illusion && !useIllusion ? this.summonData?.illusion.basePokemon!.fusionVariant : this.fusionVariant; this.getFusionSpeciesForm(false, useIllusion).loadAssets( this.getFusionGender(false, useIllusion) === Gender.FEMALE, fusionFormIndex, @@ -1011,7 +1001,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } getSpriteId(ignoreOverride?: boolean): string { - const formIndex: integer = this.battleData?.illusion.active ? this.battleData?.illusion.formIndex! : this.formIndex; + const formIndex: integer = !!this.summonData?.illusion ? this.summonData?.illusion.formIndex! : this.formIndex; return this.getSpeciesForm(ignoreOverride, true).getSpriteId( this.getGender(ignoreOverride, true) === Gender.FEMALE, formIndex, @@ -1025,7 +1015,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { back = this.isPlayer(); } - const formIndex: integer = this.battleData?.illusion.active ? this.battleData?.illusion.formIndex! : this.formIndex; + const formIndex: integer = !!this.summonData?.illusion ? this.summonData?.illusion.formIndex! : this.formIndex; return this.getSpeciesForm(ignoreOverride, true).getSpriteId( this.getGender(ignoreOverride, true) === Gender.FEMALE, @@ -1040,8 +1030,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return this.getSpeciesForm(ignoreOverride, false).getSpriteKey( this.getGender(ignoreOverride) === Gender.FEMALE, this.formIndex, - this.battleData?.illusion.basePokemon?.shiny ?? this.shiny, - this.battleData?.illusion.basePokemon?.variant ?? this.variant + this.summonData?.illusion?.basePokemon.shiny ?? this.shiny, + this.summonData?.illusion?.basePokemon.variant ?? this.variant ); } @@ -1050,7 +1040,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } getFusionSpriteId(ignoreOverride?: boolean): string { - const fusionFormIndex: integer = this.battleData?.illusion.active ? this.battleData?.illusion.fusionFormIndex! : this.fusionFormIndex; + const fusionFormIndex: integer = !!this.summonData?.illusion ? this.summonData?.illusion.fusionFormIndex! : this.fusionFormIndex; return this.getFusionSpeciesForm(ignoreOverride, true).getSpriteId( this.getFusionGender(ignoreOverride, true) === Gender.FEMALE, fusionFormIndex, @@ -1064,7 +1054,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { back = this.isPlayer(); } - const fusionFormIndex: integer = this.battleData?.illusion.active ? this.battleData?.illusion.fusionFormIndex! : this.fusionFormIndex; + const fusionFormIndex: integer = !!this.summonData?.illusion ? this.summonData?.illusion.fusionFormIndex! : this.fusionFormIndex; return this.getFusionSpeciesForm(ignoreOverride, true).getSpriteId( this.getFusionGender(ignoreOverride, true) === Gender.FEMALE, @@ -1090,7 +1080,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } getIconAtlasKey(ignoreOverride?: boolean): string { - const formIndex: integer = this.battleData?.illusion.active ? this.battleData?.illusion.formIndex! : this.formIndex; + const formIndex: integer = !!this.summonData?.illusion ? this.summonData?.illusion.formIndex! : this.formIndex; return this.getSpeciesForm(ignoreOverride, true).getIconAtlasKey( formIndex, this.shiny, @@ -1107,7 +1097,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } getIconId(ignoreOverride?: boolean): string { - const formIndex: integer = this.battleData?.illusion.active ? this.battleData?.illusion.formIndex! : this.formIndex; + const formIndex: integer = !!this.summonData?.illusion ? this.summonData?.illusion.formIndex! : this.formIndex; return this.getSpeciesForm(ignoreOverride, true).getIconId( this.getGender(ignoreOverride, true) === Gender.FEMALE, formIndex, @@ -1117,7 +1107,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } getFusionIconId(ignoreOverride?: boolean): string { - const fusionFormIndex: integer = this.battleData?.illusion.active ? this.battleData?.illusion.fusionFormIndex! : this.fusionFormIndex; + const fusionFormIndex: integer = !!this.summonData?.illusion ? this.summonData?.illusion.fusionFormIndex! : this.fusionFormIndex; return this.getFusionSpeciesForm(ignoreOverride, true).getIconId( this.getFusionGender(ignoreOverride, true) === Gender.FEMALE, fusionFormIndex, @@ -1130,9 +1120,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param {boolean} useIllusion - Whether we want the speciesForm of the illusion or not. */ getSpeciesForm(ignoreOverride?: boolean, useIllusion: boolean = false): PokemonSpeciesForm { - const species: PokemonSpecies = useIllusion && this.battleData?.illusion.active ? this.battleData?.illusion.species! : this.species; + const species: PokemonSpecies = useIllusion && !!this.summonData?.illusion ? this.summonData?.illusion.species : this.species; - const formIndex: integer = useIllusion && this.battleData?.illusion.active ? this.battleData?.illusion.formIndex! : this.formIndex; + const formIndex: integer = useIllusion && !!this.summonData?.illusion ? this.summonData?.illusion.formIndex : this.formIndex; if (!ignoreOverride && this.summonData?.speciesForm) { return this.summonData.speciesForm; @@ -1148,8 +1138,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param {boolean} useIllusion - Whether we want the fusionSpeciesForm of the illusion or not. */ getFusionSpeciesForm(ignoreOverride?: boolean, useIllusion: boolean = false): PokemonSpeciesForm { - const fusionSpecies: PokemonSpecies = useIllusion && this.battleData?.illusion.active ? this.battleData?.illusion.fusionSpecies! : this.fusionSpecies!; - const fusionFormIndex: integer = useIllusion && this.battleData?.illusion.active ? this.battleData?.illusion.fusionFormIndex! : this.fusionFormIndex; + const fusionSpecies: PokemonSpecies = useIllusion && !!this.summonData?.illusion ? this.summonData?.illusion.fusionSpecies! : this.fusionSpecies!; + const fusionFormIndex: integer = useIllusion && !!this.summonData?.illusion ? this.summonData?.illusion.fusionFormIndex! : this.fusionFormIndex; if (!ignoreOverride && this.summonData?.speciesForm) { return this.summonData.fusionSpeciesForm; @@ -1827,8 +1817,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param {boolean} useIllusion - Whether we want the fake or real gender (illusion ability). */ getGender(ignoreOverride?: boolean, useIllusion: boolean = false): Gender { - if (useIllusion && this.battleData?.illusion.active) { - return this.battleData?.illusion.gender!; + if (useIllusion && !!this.summonData?.illusion) { + return this.summonData?.illusion.gender!; } else if (!ignoreOverride && this.summonData?.gender !== undefined) { return this.summonData.gender; } @@ -1839,8 +1829,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param {boolean} useIllusion - Whether we want the fake or real gender (illusion ability). */ getFusionGender(ignoreOverride?: boolean, useIllusion: boolean = false): Gender { - if (useIllusion && this.battleData?.illusion.active) { - return this.battleData?.illusion.fusionGender!; + if (useIllusion && !!this.summonData?.illusion) { + return this.summonData?.illusion.fusionGender!; } else if (!ignoreOverride && this.summonData?.fusionGender !== undefined) { return this.summonData.fusionGender; } @@ -1851,8 +1841,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param {boolean} useIllusion - Whether we want the fake or real shininess (illusion ability). */ isShiny(useIllusion: boolean = false): boolean { - if (!useIllusion && this.battleData?.illusion.active) { - return this.battleData?.illusion.basePokemon?.shiny || (!!this.battleData?.illusion.fusionSpecies && this.battleData?.illusion.basePokemon?.fusionShiny) || false; + if (!useIllusion && !!this.summonData?.illusion) { + return this.summonData?.illusion.basePokemon?.shiny || (!!this.summonData?.illusion.fusionSpecies && this.summonData?.illusion.basePokemon?.fusionShiny) || false; } else { return this.shiny || (this.isFusion(useIllusion) && this.fusionShiny); } @@ -1864,8 +1854,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @returns `true` if the {@linkcode Pokemon} is shiny and the fusion is shiny as well, `false` otherwise */ isDoubleShiny(useIllusion: boolean = false): boolean { - if (!useIllusion && this.battleData?.illusion.active) { - return this.isFusion(false) && this.battleData?.illusion.basePokemon!.shiny && this.battleData?.illusion.basePokemon.fusionShiny; + if (!useIllusion && !!this.summonData?.illusion) { + return this.isFusion(false) && this.summonData?.illusion.basePokemon!.shiny && this.summonData?.illusion.basePokemon.fusionShiny; } else { return this.isFusion(useIllusion) && this.shiny && this.fusionShiny; } @@ -1875,9 +1865,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param {boolean} useIllusion - Whether we want the fake or real variant (illusion ability). */ getVariant(useIllusion: boolean = false): Variant { - if (!useIllusion && this.battleData?.illusion.active) { + if (!useIllusion && !!this.summonData?.illusion) { return !this.isFusion(false) - ? this.battleData?.illusion.basePokemon!.variant + ? this.summonData?.illusion.basePokemon!.variant : Math.max(this.variant, this.fusionVariant) as Variant; } else { return !this.isFusion(true) @@ -1889,8 +1879,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { getBaseVariant(doubleShiny: boolean): Variant { if (doubleShiny) { - return this.battleData?.illusion.active - ? this.battleData?.illusion.basePokemon!.variant + return !!this.summonData?.illusion + ? this.summonData?.illusion.basePokemon!.variant : this.variant; } else { return this.getVariant(); @@ -1902,8 +1892,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } isFusion(useIllusion: boolean = false): boolean { - if (useIllusion && this.battleData?.illusion.active) { - return !!this.battleData?.illusion.fusionSpecies; + if (useIllusion && !!this.summonData?.illusion) { + return !!this.summonData?.illusion.fusionSpecies; } else { return !!this.fusionSpecies; } @@ -1913,8 +1903,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param {boolean} useIllusion - Whether we want the fake name or the real name of the Pokemon (for Illusion ability). */ getName(useIllusion: boolean = false): string { - return (!useIllusion && this.battleData?.illusion.active && this.battleData?.illusion.basePokemon) - ? this.battleData?.illusion.basePokemon.name + return (!useIllusion && !!this.summonData?.illusion && this.summonData?.illusion.basePokemon) + ? this.summonData?.illusion.basePokemon.name : this.name; } @@ -2058,7 +2048,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { !ignoreOverride && this.summonData?.types && this.summonData.types.length > 0 && - (!this.battleData?.illusion.active || !doIllusion) + (!!!this.summonData?.illusion || !doIllusion) ) { this.summonData.types.forEach(t => types.push(t)); } else { @@ -5795,6 +5785,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } resetSummonData(): void { + const illusion: Illusion | null = this.summonData?.illusion; if (this.summonData?.speciesForm) { this.summonData.speciesForm = null; this.updateFusionPalette(); @@ -5830,17 +5821,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } this.summonDataPrimer = null; } + this.summonData.illusion = illusion this.updateInfo(); } resetBattleData(): void { - console.log("RESET BATTLE DATA") - const illusionActive: boolean = this.battleData?.illusion.active; - this.breakIllusion(); this.battleData = new PokemonBattleData(); - if (illusionActive) { - this.generateIllusion(); - } } resetBattleSummonData(): void { @@ -7809,36 +7795,36 @@ interface Illusion { * Whether the illusion is active or not. * @type {boolean} */ - active: boolean; + //active: boolean; /** * Whether the pokemon can generate an illusion or not. * @type {boolean} */ - available: boolean; + //available: boolean; /** * The actual Pokemon. * @type {Pokemon} */ - basePokemon?: Pokemon; + basePokemon: Pokemon; /** * The species of the illusion. * @type {PokemonSpecies} */ - species?: PokemonSpecies; + species: PokemonSpecies; /** * The formIndex of the illusion * @type {integer} */ - formIndex?: number; + formIndex: number; /** * The gender of the illusion * @type {Gender} */ - gender?: Gender; + gender: Gender; /** * The pokeball of the illusion. */ - pokeball?: PokeballType; + pokeball: PokeballType; /** * The fusionned species of the illusion if it's a fusion. * @type {PokemonSpecies} @@ -7897,6 +7883,7 @@ export class PokemonSummonData { // If not initialized this value will not be populated from save data. public types: PokemonType[] = []; public addedType: PokemonType | null = null; + public illusion: Illusion | null = null; } export class PokemonBattleData { @@ -7908,7 +7895,6 @@ export class PokemonBattleData { public berriesEaten: BerryType[] = []; public abilitiesApplied: Abilities[] = []; public abilityRevealed: boolean = false; - public illusion: Illusion = { active: false, available: true }; } export class PokemonBattleSummonData { diff --git a/src/phases/encounter-phase.ts b/src/phases/encounter-phase.ts index 2e06f705c1a..148ade5374b 100644 --- a/src/phases/encounter-phase.ts +++ b/src/phases/encounter-phase.ts @@ -259,10 +259,9 @@ export class EncounterPhase extends BattlePhase { } if (e < (battle.double ? 2 : 1)) { if (battle.battleType === BattleType.WILD) { - for (const pokemon of globalScene.getPlayerField()) { + for (const pokemon of globalScene.getField()) { applyPreSummonAbAttrs(PreSummonAbAttr, pokemon, []); } - applyPreSummonAbAttrs(PreSummonAbAttr, enemyPokemon, []); globalScene.field.add(enemyPokemon); battle.seenEnemyPartyMemberIds.add(enemyPokemon.id); const playerPokemon = globalScene.getPlayerPokemon(); diff --git a/src/phases/summon-phase.ts b/src/phases/summon-phase.ts index e7a5e056f7c..836e9b9a695 100644 --- a/src/phases/summon-phase.ts +++ b/src/phases/summon-phase.ts @@ -128,7 +128,7 @@ export class SummonPhase extends PartyMemberPokemonPhase { this.player ? 36 : 248, this.player ? 80 : 44, "pb", - getPokeballAtlasKey(pokemon.battleData.illusion.pokeball ?? pokemon.pokeball), + getPokeballAtlasKey(pokemon.summonData?.illusion?.pokeball ?? pokemon.pokeball), ); pokeball.setVisible(false); pokeball.setOrigin(0.5, 0.625); @@ -180,7 +180,7 @@ export class SummonPhase extends PartyMemberPokemonPhase { addPokeballOpenParticles( pokemon.x, pokemon.y - 16, - pokemon.battleData.illusion.pokeball ?? pokemon.pokeball, + pokemon.summonData?.illusion?.pokeball ?? pokemon.pokeball, ); globalScene.updateModifiers(this.player); globalScene.updateFieldScale(); @@ -189,7 +189,7 @@ export class SummonPhase extends PartyMemberPokemonPhase { pokemon.setVisible(true); pokemon.getSprite().setVisible(true); pokemon.setScale(0.5); - pokemon.tint(getPokeballTintColor(pokemon.battleData.illusion.pokeball ?? pokemon.pokeball)); + pokemon.tint(getPokeballTintColor(pokemon.summonData?.illusion?.pokeball ?? pokemon.pokeball)); pokemon.untint(250, "Sine.easeIn"); globalScene.updateFieldScale(); globalScene.tweens.add({ diff --git a/src/phases/switch-summon-phase.ts b/src/phases/switch-summon-phase.ts index 770ee612efe..3b478afa269 100644 --- a/src/phases/switch-summon-phase.ts +++ b/src/phases/switch-summon-phase.ts @@ -105,7 +105,7 @@ export class SwitchSummonPhase extends SummonPhase { ); globalScene.playSound("se/pb_rel"); pokemon.hideInfo(); - pokemon.tint(getPokeballTintColor(pokemon.battleData.illusion.pokeball ?? pokemon.pokeball), 1, 250, "Sine.easeIn"); + pokemon.tint(getPokeballTintColor(pokemon.summonData?.illusion?.pokeball ?? pokemon.pokeball), 1, 250, "Sine.easeIn"); globalScene.tweens.add({ targets: pokemon, duration: 250, diff --git a/src/ui/battle-info.ts b/src/ui/battle-info.ts index fd916dd5947..71e46dd5ef9 100644 --- a/src/ui/battle-info.ts +++ b/src/ui/battle-info.ts @@ -617,7 +617,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container { return resolve(); } - const gender: Gender = pokemon.battleData.illusion.active ? pokemon.battleData.illusion.gender! : pokemon.gender; + const gender: Gender = !!pokemon.summonData?.illusion ? pokemon.summonData?.illusion.gender : pokemon.gender; this.genderText.setText(getGenderSymbol(gender)); this.genderText.setColor(getGenderColor(gender)); @@ -794,7 +794,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container { const nameSizeTest = addTextObject(0, 0, displayName, TextStyle.BATTLE_INFO); nameTextWidth = nameSizeTest.displayWidth; - const gender: Gender = pokemon.battleData.illusion.active ? pokemon.battleData.illusion.gender! : pokemon.gender; + const gender: Gender = !!pokemon.summonData?.illusion ? pokemon.summonData?.illusion.gender : pokemon.gender; while ( nameTextWidth > (this.player || !this.boss ? 60 : 98) - diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index e20c41524b1..20b21b57d32 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -1581,7 +1581,7 @@ class PartySlot extends Phaser.GameObjects.Container { fusionShinyStar.setOrigin(0, 0); fusionShinyStar.setPosition(shinyStar.x, shinyStar.y); fusionShinyStar.setTint( - getVariantTint(this.pokemon.battleData.illusion.basePokemon?.fusionVariant ?? this.pokemon.fusionVariant), + getVariantTint(this.pokemon.summonData?.illusion?.basePokemon.fusionVariant ?? this.pokemon.fusionVariant), ); slotInfoContainer.add(fusionShinyStar); diff --git a/src/ui/summary-ui-handler.ts b/src/ui/summary-ui-handler.ts index 6284661d455..8632981f0a6 100644 --- a/src/ui/summary-ui-handler.ts +++ b/src/ui/summary-ui-handler.ts @@ -350,11 +350,11 @@ export default class SummaryUiHandler extends UiHandler { this.pokemonSprite.setPipelineData("spriteKey", this.pokemon.getSpriteKey()); this.pokemonSprite.setPipelineData( "shiny", - this.pokemon.battleData.illusion.basePokemon?.shiny ?? this.pokemon.shiny, + this.pokemon.summonData?.illusion?.basePokemon.shiny ?? this.pokemon.shiny, ); this.pokemonSprite.setPipelineData( "variant", - this.pokemon.battleData.illusion.basePokemon?.variant ?? this.pokemon.variant, + this.pokemon.summonData?.illusion?.basePokemon.variant ?? this.pokemon.variant, ); ["spriteColors", "fusionSpriteColors"].map(k => { delete this.pokemonSprite.pipelineData[`${k}Base`]; @@ -453,7 +453,7 @@ export default class SummaryUiHandler extends UiHandler { this.fusionShinyIcon.setVisible(doubleShiny); if (isFusion) { this.fusionShinyIcon.setTint( - getVariantTint(this.pokemon.battleData.illusion.basePokemon?.fusionVariant ?? this.pokemon.fusionVariant), + getVariantTint(this.pokemon.summonData?.illusion?.basePokemon.fusionVariant ?? this.pokemon.fusionVariant), ); } diff --git a/test/abilities/illusion.test.ts b/test/abilities/illusion.test.ts index 02e1e212421..75b7a2c1645 100644 --- a/test/abilities/illusion.test.ts +++ b/test/abilities/illusion.test.ts @@ -1,7 +1,6 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import Phaser from "phaser"; import GameManager from "#test/testUtils/gameManager"; -import overrides from "#app/overrides"; import { Species } from "#enums/species"; import { TurnEndPhase } from "#app/phases/turn-end-phase"; import { Moves } from "#enums/moves"; @@ -40,8 +39,8 @@ describe("Abilities - Illusion", () => { const zoroark = game.scene.getPlayerPokemon()!; const zorua = game.scene.getEnemyPokemon()!; - expect(zoroark.battleData.illusion.active).equals(true); - expect(zorua.battleData.illusion.active).equals(true); + expect(!!zoroark.summonData?.illusion).equals(true); + expect(!!zorua.summonData?.illusion).equals(true); }); it("break after receiving damaging move", async () => { @@ -52,8 +51,7 @@ describe("Abilities - Illusion", () => { const zorua = game.scene.getEnemyPokemon()!; - expect(zorua.battleData.illusion.active).equals(false); - expect(zorua.battleData.illusion.available).equals(false); + expect(!!zorua.summonData?.illusion).equals(false); expect(zorua.name).equals("Zorua"); }); @@ -65,7 +63,7 @@ describe("Abilities - Illusion", () => { const zorua = game.scene.getEnemyPokemon()!; - expect(zorua.battleData.illusion.active).equals(false); + expect(!!zorua.summonData?.illusion).equals(false); }); it("break if the ability is suppressed", async () => { @@ -74,7 +72,7 @@ describe("Abilities - Illusion", () => { const zorua = game.scene.getEnemyPokemon()!; - expect(zorua.battleData.illusion.active).equals(false); + expect(!!zorua.summonData?.illusion).equals(false); }); it("causes enemy AI to consider the illusion's type instead of the actual type when considering move effectiveness", async () => { @@ -119,7 +117,7 @@ describe("Abilities - Illusion", () => { const zoroark = game.scene.getPlayerPokemon()!; - expect(zoroark.battleData.illusion.active).equals(true); + expect(!!zoroark.summonData?.illusion).equals(true); }); it("copies the the name, nickname, gender, shininess, and pokeball from the illusion source", async () => { @@ -136,10 +134,12 @@ describe("Abilities - Illusion", () => { await game.phaseInterceptor.to(TurnEndPhase); const zoroark = game.scene.getPlayerPokemon()!; + + console.log("OOOOOOOOOOOOOOOOOOOOO", !!zoroark.summonData.illusion) expect(zoroark.name).equals("Axew"); expect(zoroark.getNameToRender()).equals("axew nickname"); expect(zoroark.getGender(false, true)).equals(Gender.FEMALE); expect(zoroark.isShiny(true)).equals(true); - expect(zoroark.battleData.illusion.pokeball).equals(PokeballType.GREAT_BALL); + expect(zoroark.summonData?.illusion?.pokeball).equals(PokeballType.GREAT_BALL); }); });