From 6d90649b925c2c1537815ba797dd783e3fdb2135 Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Fri, 2 May 2025 01:06:07 -0400 Subject: [PATCH 01/61] [Refactor/Bug/Ability] Reworked BattleData, fixed Rage Fist, Harvest, Belch + Implemented Cud Chew (#5655) * Grabbed reverted changes from stuff * Added version migrator for rage fist data + deepMergeSpriteData tests * fixed formattign * Fied a few * Fixed constructor (maybe), moved deepCopy and deepMergeSpriteData to own file `common.ts` is hella bloated so seems legit * Moved empty moveset verification mapping thing to upgrade script bc i wanted to * Fixed tests * test added * Fixed summondata being cleared inside summonPhase, removed `summonDataPrimer` like seriously how come no-one checked this * Fixed test I forgot that we outsped and oneshot * Fixed test * huhjjjjjb * Hopefully fixed bug my sanity and homework are paying the price for this lol * added commented out console.log statement uncomment to see new berry data * Fixed migrate script, re-added deprecated attributes out of necessity * Fixed failing test by not trying to mock rng * Fixed test * Fixed tests * Update ability.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update ability.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update overrides.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update berry-phase.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update encounter-phase.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update game-data.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update move-phase.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Added utility function `randSeedFloat` basically just `Phaser.math.RND.realInRange(0, 1)` * Applied review comments, cleaned up code a bit * Removed unnecessary null checks for turnData and co. I explicitly made them initialized by default for this very reason * Added tests for Last Resort regarding moveHistory * Update pokemon.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update pokemon.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update pokemon.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update pokemon.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update pokemon.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update pokemon.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update pokemon.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update pokemon.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update battle-scene.ts Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> * Update the-winstrate-challenge-encounter.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update pokemon.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update pokemon.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update pokemon.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update ability.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update move.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update move.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update move.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update battle-anims.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Update pokemon.ts comments * Fixed a few outstanding issues with documentation * Updated switch summon phase comment * Re-added BattleSummonData as TempSummonData * Hppefully fixed -1 sprite scale glitch * Fixed comment * Reveted `pokemon-forms.ts` * Fuxed constructor * fixed -1 bug * Revert "Added utility function `randSeedFloat`" This reverts commit 4c3447c851731c989fc591feea0094b6bbde7fd2. --------- Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> --- src/battle-scene.ts | 25 +- src/data/abilities/ab-attrs/ab-attr.ts | 4 + src/data/abilities/ability.ts | 251 ++++-- src/data/arena-tag.ts | 72 +- src/data/battle-anims.ts | 1 - src/data/battler-tags.ts | 72 +- src/data/berry.ts | 177 ++-- src/data/challenge.ts | 3 +- src/data/custom-pokemon-data.ts | 37 +- src/data/moves/move.ts | 242 +++-- .../encounters/clowning-around-encounter.ts | 3 - .../global-trade-system-encounter.ts | 4 +- .../the-winstrate-challenge-encounter.ts | 3 +- .../encounters/weird-dream-encounter.ts | 4 - .../utils/encounter-phase-utils.ts | 12 +- .../utils/encounter-pokemon-utils.ts | 3 - .../encounter-transformation-sequence.ts | 4 +- src/data/pokemon-species.ts | 20 +- src/enums/biome.ts | 1 + src/field/pokemon.ts | 837 ++++++++++-------- src/inputs-controller.ts | 3 +- src/modifier/modifier-type.ts | 1 + src/modifier/modifier.ts | 47 +- src/overrides.ts | 10 +- src/phases/battle-end-phase.ts | 4 +- src/phases/berry-phase.ts | 91 +- src/phases/encounter-phase.ts | 20 +- src/phases/evolution-phase.ts | 4 +- src/phases/faint-phase.ts | 4 +- src/phases/field-phase.ts | 3 +- src/phases/form-change-phase.ts | 2 +- src/phases/move-effect-phase.ts | 3 - src/phases/move-phase.ts | 2 +- src/phases/mystery-encounter-phases.ts | 3 +- src/phases/new-biome-encounter-phase.ts | 12 +- src/phases/next-encounter-phase.ts | 9 +- src/phases/quiet-form-change-phase.ts | 2 +- src/phases/show-ability-phase.ts | 4 +- src/phases/stat-stage-change-phase.ts | 8 - src/phases/summon-phase.ts | 10 +- src/phases/switch-summon-phase.ts | 122 +-- src/phases/turn-end-phase.ts | 5 +- src/phases/turn-start-phase.ts | 23 +- src/system/game-data.ts | 112 +-- src/system/pokemon-data.ts | 180 ++-- .../version_migration/version_converter.ts | 5 + .../version_migration/versions/v1_9_0.ts | 47 + src/ui/battle-info.ts | 4 +- src/ui/fight-ui-handler.ts | 6 +- src/ui/party-ui-handler.ts | 2 +- src/ui/registration-form-ui-handler.ts | 4 +- src/ui/summary-ui-handler.ts | 8 +- src/ui/target-select-ui-handler.ts | 2 +- src/utils/common.ts | 39 +- src/utils/data.ts | 40 + test/abilities/cud_chew.test.ts | 322 +++++++ test/abilities/good_as_gold.test.ts | 2 +- test/abilities/harvest.test.ts | 346 ++++++++ test/abilities/illusion.test.ts | 12 +- test/abilities/infiltrator.test.ts | 8 +- test/abilities/libero.test.ts | 16 +- test/abilities/protean.test.ts | 16 +- test/abilities/quick_draw.test.ts | 6 +- test/abilities/wimp_out.test.ts | 2 +- test/battle/inverse_battle.test.ts | 4 +- test/battlerTags/substitute.test.ts | 1 - test/moves/dive.test.ts | 2 +- test/moves/fake_out.test.ts | 67 +- test/moves/instruct.test.ts | 6 +- test/moves/last-resort.test.ts | 166 ++++ test/moves/powder.test.ts | 2 +- test/moves/rage_fist.test.ts | 135 ++- test/moves/toxic_spikes.test.ts | 2 +- test/moves/transform.test.ts | 24 +- test/moves/u_turn.test.ts | 4 +- test/settingMenu/rebinding_setting.test.ts | 2 +- test/testUtils/gameManager.ts | 3 +- test/testUtils/helpers/moveHelper.ts | 11 + test/testUtils/helpers/overridesHelper.ts | 15 + test/testUtils/helpers/reloadHelper.ts | 12 +- test/utils.test.ts | 31 + 81 files changed, 2541 insertions(+), 1292 deletions(-) create mode 100644 src/system/version_migration/versions/v1_9_0.ts create mode 100644 src/utils/data.ts create mode 100644 test/abilities/cud_chew.test.ts create mode 100644 test/abilities/harvest.test.ts create mode 100644 test/moves/last-resort.test.ts diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 8fe6c85263d..db036847994 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -7,7 +7,6 @@ import type PokemonSpecies from "#app/data/pokemon-species"; import { allSpecies, getPokemonSpecies } from "#app/data/pokemon-species"; import { fixedInt, - deepMergeObjects, getIvsFromId, randSeedInt, getEnumValues, @@ -19,6 +18,7 @@ import { BooleanHolder, type Constructor, } from "#app/utils/common"; +import { deepMergeSpriteData } from "#app/utils/data"; import type { Modifier, ModifierPredicate, TurnHeldItemTransferModifier } from "./modifier/modifier"; import { ConsumableModifier, @@ -787,7 +787,7 @@ export default class BattleScene extends SceneBase { return; } const expVariantData = await this.cachedFetch("./images/pokemon/variant/_exp_masterlist.json").then(r => r.json()); - deepMergeObjects(variantData, expVariantData); + deepMergeSpriteData(variantData, expVariantData); } cachedFetch(url: string, init?: RequestInit): Promise { @@ -835,6 +835,7 @@ export default class BattleScene extends SceneBase { return this.getPlayerField().find(p => p.isActive() && (includeSwitching || p.switchOutStatus === false)); } + // TODO: Add `undefined` to return type /** * Returns an array of PlayerPokemon of length 1 or 2 depending on if in a double battle or not. * Does not actually check if the pokemon are on the field or not. @@ -850,9 +851,9 @@ export default class BattleScene extends SceneBase { } /** - * @returns The first {@linkcode EnemyPokemon} that is {@linkcode getEnemyField on the field} - * and {@linkcode EnemyPokemon.isActive is active} - * (aka {@linkcode EnemyPokemon.isAllowedInBattle is allowed in battle}), + * @returns The first {@linkcode EnemyPokemon} that is {@linkcode getEnemyField | on the field} + * and {@linkcode EnemyPokemon.isActive | is active} + * (aka {@linkcode EnemyPokemon.isAllowedInBattle | is allowed in battle}), * or `undefined` if there are no valid pokemon * @param includeSwitching Whether a pokemon that is currently switching out is valid, default `true` */ @@ -873,8 +874,8 @@ export default class BattleScene extends SceneBase { /** * Returns an array of Pokemon on both sides of the battle - player first, then enemy. * Does not actually check if the pokemon are on the field or not, and always has length 4 regardless of battle type. - * @param activeOnly Whether to consider only active pokemon - * @returns array of {@linkcode Pokemon} + * @param activeOnly - Whether to consider only active pokemon; default `false` + * @returns An array of {@linkcode Pokemon}, as described above. */ public getField(activeOnly = false): Pokemon[] { const ret = new Array(4).fill(null); @@ -1307,14 +1308,13 @@ export default class BattleScene extends SceneBase { return isNewBiome; } - // TODO: ...this never actually returns `null`, right? newBattle( waveIndex?: number, battleType?: BattleType, trainerData?: TrainerData, double?: boolean, mysteryEncounterType?: MysteryEncounterType, - ): Battle | null { + ): Battle { const _startingWave = Overrides.STARTING_WAVE_OVERRIDE || startingWave; const newWaveIndex = waveIndex || (this.currentBattle?.waveIndex || _startingWave - 1) + 1; let newDouble: boolean | undefined; @@ -1496,7 +1496,7 @@ export default class BattleScene extends SceneBase { }); for (const pokemon of this.getPlayerParty()) { - pokemon.resetBattleData(); + pokemon.resetBattleAndWaveData(); pokemon.resetTera(); applyPostBattleInitAbAttrs(PostBattleInitAbAttr, pokemon); if ( @@ -3264,6 +3264,7 @@ export default class BattleScene extends SceneBase { [this.modifierBar, this.enemyModifierBar].map(m => m.setVisible(visible)); } + // TODO: Document this updateModifiers(player = true, instant?: boolean): void { const modifiers = player ? this.modifiers : (this.enemyModifiers as PersistentModifier[]); for (let m = 0; m < modifiers.length; m++) { @@ -3316,8 +3317,8 @@ export default class BattleScene extends SceneBase { * gets removed. This function does NOT apply in-battle effects, such as Unburden. * If in-battle effects are needed, use {@linkcode Pokemon.loseHeldItem} instead. * @param modifier The item to be removed. - * @param enemy If `true`, remove an item owned by the enemy. If `false`, remove an item owned by the player. Default is `false`. - * @returns `true` if the item exists and was successfully removed, `false` otherwise. + * @param enemy `true` to remove an item owned by the enemy rather than the player; default `false`. + * @returns `true` if the item exists and was successfully removed, `false` otherwise */ removeModifier(modifier: PersistentModifier, enemy = false): boolean { const modifiers = !enemy ? this.modifiers : this.enemyModifiers; diff --git a/src/data/abilities/ab-attrs/ab-attr.ts b/src/data/abilities/ab-attrs/ab-attr.ts index a653c3f372d..24fbb6dc338 100644 --- a/src/data/abilities/ab-attrs/ab-attr.ts +++ b/src/data/abilities/ab-attrs/ab-attr.ts @@ -6,6 +6,10 @@ export abstract class AbAttr { public showAbility: boolean; private extraCondition: AbAttrCondition; + /** + * @param showAbility - Whether to show this ability as a flyout during battle; default `true`. + * Should be kept in parity with mainline where possible. + */ constructor(showAbility = true) { this.showAbility = showAbility; } diff --git a/src/data/abilities/ability.ts b/src/data/abilities/ability.ts index 6e3f4c77f87..1cb19e57533 100644 --- a/src/data/abilities/ability.ts +++ b/src/data/abilities/ability.ts @@ -60,6 +60,11 @@ import { SwitchType } from "#enums/switch-type"; import { MoveFlags } from "#enums/MoveFlags"; import { MoveTarget } from "#enums/MoveTarget"; import { MoveCategory } from "#enums/MoveCategory"; +import type { BerryType } from "#enums/berry-type"; +import { CommonAnimPhase } from "#app/phases/common-anim-phase"; +import { CommonAnim } from "../battle-anims"; +import { getBerryEffectFunc } from "../berry"; +import { BerryUsedEvent } from "#app/events/battle-scene"; // Type imports @@ -2675,7 +2680,7 @@ export class PostSummonCopyAllyStatsAbAttr extends PostSummonAbAttr { } /** - * Used by Imposter + * Attribute used by {@linkcode Abilities.IMPOSTER} to transform into a random opposing pokemon on entry. */ export class PostSummonTransformAbAttr extends PostSummonAbAttr { constructor() { @@ -2710,7 +2715,7 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr { const targets = pokemon.getOpponents(); const target = this.getTarget(targets); - if (!!target.summonData?.illusion) { + if (target.summonData.illusion) { return false; } @@ -3292,13 +3297,13 @@ export class ConditionalUserFieldStatusEffectImmunityAbAttr extends UserFieldSta /** * Conditionally provides immunity to stat drop effects to the user's field. - * + * * Used by {@linkcode Abilities.FLOWER_VEIL | Flower Veil}. */ export class ConditionalUserFieldProtectStatAbAttr extends PreStatStageChangeAbAttr { /** {@linkcode BattleStat} to protect or `undefined` if **all** {@linkcode BattleStat} are protected */ protected protectedStat?: BattleStat; - + /** If the method evaluates to true, the stat will be protected. */ protected condition: (target: Pokemon) => boolean; @@ -3315,7 +3320,7 @@ export class ConditionalUserFieldProtectStatAbAttr extends PreStatStageChangeAbA * @param stat The stat being affected * @param cancelled Holds whether the stat change was already prevented. * @param args Args[0] is the target pokemon of the stat change. - * @returns + * @returns */ override canApplyPreStatStageChange(pokemon: Pokemon, passive: boolean, simulated: boolean, stat: BattleStat, cancelled: BooleanHolder, args: [Pokemon, ...any]): boolean { const target = args[0]; @@ -3451,7 +3456,7 @@ export class BonusCritAbAttr extends AbAttr { /** * Apply the bonus crit ability by increasing the value in the provided number holder by 1 - * + * * @param pokemon The pokemon with the BonusCrit ability (unused) * @param passive Unused * @param simulated Unused @@ -3604,7 +3609,7 @@ export class PreWeatherEffectAbAttr extends AbAttr { args: any[]): boolean { return true; } - + applyPreWeatherEffect( pokemon: Pokemon, passive: boolean, @@ -3657,14 +3662,10 @@ export class SuppressWeatherEffectAbAttr extends PreWeatherEffectAbAttr { * Condition function to applied to abilities related to Sheer Force. * Checks if last move used against target was affected by a Sheer Force user and: * Disables: Color Change, Pickpocket, Berserk, Anger Shell - * @returns {AbAttrCondition} If false disables the ability which the condition is applied to. + * @returns An {@linkcode AbAttrCondition} to disable the ability under the proper conditions. */ function getSheerForceHitDisableAbCondition(): AbAttrCondition { return (pokemon: Pokemon) => { - if (!pokemon.turnData) { - return true; - } - const lastReceivedAttack = pokemon.turnData.attacksReceived[0]; if (!lastReceivedAttack) { return true; @@ -3675,7 +3676,7 @@ function getSheerForceHitDisableAbCondition(): AbAttrCondition { return true; } - /**if the last move chance is greater than or equal to cero, and the last attacker's ability is sheer force*/ + /** `true` if the last move's chance is above 0 and the last attacker's ability is sheer force */ const SheerForceAffected = allMoves[lastReceivedAttack.move].chance >= 0 && lastAttacker.hasAbility(Abilities.SHEER_FORCE); return !SheerForceAffected; @@ -3745,7 +3746,7 @@ function getAnticipationCondition(): AbAttrCondition { */ function getOncePerBattleCondition(ability: Abilities): AbAttrCondition { return (pokemon: Pokemon) => { - return !pokemon.battleData?.abilitiesApplied.includes(ability); + return !pokemon.waveData.abilitiesApplied.has(ability); }; } @@ -4034,7 +4035,7 @@ export class PostTurnStatusHealAbAttr extends PostTurnAbAttr { /** * After the turn ends, resets the status of either the ability holder or their ally - * @param {boolean} allyTarget Whether to target ally, defaults to false (self-target) + * @param allyTarget Whether to target ally, defaults to false (self-target) */ export class PostTurnResetStatusAbAttr extends PostTurnAbAttr { private allyTarget: boolean; @@ -4066,79 +4067,153 @@ export class PostTurnResetStatusAbAttr extends PostTurnAbAttr { } /** - * After the turn ends, try to create an extra item + * Attribute to try and restore eaten berries after the turn ends. + * Used by {@linkcode Abilities.HARVEST}. */ -export class PostTurnLootAbAttr extends PostTurnAbAttr { +export class PostTurnRestoreBerryAbAttr extends PostTurnAbAttr { /** - * @param itemType - The type of item to create - * @param procChance - Chance to create an item - * @see {@linkcode applyPostTurn()} + * Array containing all {@linkcode BerryType | BerryTypes} that are under cap and able to be restored. + * Stored inside the class for a minor performance boost + */ + private berriesUnderCap: BerryType[] + + /** + * @param procChance - function providing chance to restore an item + * @see {@linkcode createEatenBerry()} */ constructor( - /** Extend itemType to add more options */ - private itemType: "EATEN_BERRIES" | "HELD_BERRIES", private procChance: (pokemon: Pokemon) => number ) { super(); } - override canApplyPostTurn(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean { - // Clamp procChance to [0, 1]. Skip if didn't proc (less than pass) - const pass = Phaser.Math.RND.realInRange(0, 1); - return !(Math.max(Math.min(this.procChance(pokemon), 1), 0) < pass) && this.itemType === "EATEN_BERRIES" && !!pokemon.battleData.berriesEaten; - } + override canApplyPostTurn(pokemon: Pokemon, _passive: boolean, _simulated: boolean, _args: any[]): boolean { + // Ensure we have at least 1 recoverable berry (at least 1 berry in berriesEaten is not capped) + const cappedBerries = new Set( + globalScene.getModifiers(BerryModifier, pokemon.isPlayer()).filter( + bm => bm.pokemonId === pokemon.id && bm.getCountUnderMax() < 1 + ).map(bm => bm.berryType) + ); - override applyPostTurn(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void { - this.createEatenBerry(pokemon, simulated); - } + this.berriesUnderCap = pokemon.battleData.berriesEaten.filter( + bt => !cappedBerries.has(bt) + ); - /** - * Create a new berry chosen randomly from the berries the pokemon ate this battle - * @param pokemon The pokemon with this ability - * @param simulated whether the associated ability call is simulated - * @returns whether a new berry was created - */ - createEatenBerry(pokemon: Pokemon, simulated: boolean): boolean { - const berriesEaten = pokemon.battleData.berriesEaten; - - if (!berriesEaten.length) { + if (!this.berriesUnderCap.length) { return false; } - if (simulated) { - return true; + // Clamp procChance to [0, 1]. Skip if didn't proc (less than pass) + const pass = Phaser.Math.RND.realInRange(0, 1); + return Phaser.Math.Clamp(this.procChance(pokemon), 0, 1) >= pass; + } + + override applyPostTurn(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): void { + if (!simulated) { + this.createEatenBerry(pokemon); } + } - const randomIdx = randSeedInt(berriesEaten.length); - const chosenBerryType = berriesEaten[randomIdx]; + /** + * Create a new berry chosen randomly from all berries the pokemon ate this battle + * @param pokemon - The {@linkcode Pokemon} with this ability + * @returns `true` if a new berry was created + */ + createEatenBerry(pokemon: Pokemon): boolean { + // Pick a random available berry to yoink + const randomIdx = randSeedInt(this.berriesUnderCap.length); + const chosenBerryType = this.berriesUnderCap[randomIdx]; + pokemon.battleData.berriesEaten.splice(randomIdx, 1); // Remove berry from memory const chosenBerry = new BerryModifierType(chosenBerryType); - berriesEaten.splice(randomIdx); // Remove berry from memory + // Add the randomly chosen berry or update the existing one const berryModifier = globalScene.findModifier( - (m) => m instanceof BerryModifier && m.berryType === chosenBerryType, + (m) => m instanceof BerryModifier && m.berryType === chosenBerryType && m.pokemonId == pokemon.id, pokemon.isPlayer() ) as BerryModifier | undefined; - if (!berryModifier) { + if (berryModifier) { + berryModifier.stackCount++ + } else { const newBerry = new BerryModifier(chosenBerry, pokemon.id, chosenBerryType, 1); if (pokemon.isPlayer()) { globalScene.addModifier(newBerry); } else { globalScene.addEnemyModifier(newBerry); } - } else if (berryModifier.stackCount < berryModifier.getMaxHeldItemCount(pokemon)) { - berryModifier.stackCount++; } - globalScene.queueMessage(i18next.t("abilityTriggers:postTurnLootCreateEatenBerry", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), berryName: chosenBerry.name })); globalScene.updateModifiers(pokemon.isPlayer()); - + globalScene.queueMessage(i18next.t("abilityTriggers:postTurnLootCreateEatenBerry", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), berryName: chosenBerry.name })); return true; } } /** - * Attribute used for {@linkcode Abilities.MOODY} + * Attribute to track and re-trigger last turn's berries at the end of the `BerryPhase`. + * Used by {@linkcode Abilities.CUD_CHEW}. +*/ +export class RepeatBerryNextTurnAbAttr extends PostTurnAbAttr { + /** + * @returns `true` if the pokemon ate anything last turn + */ + override canApply(pokemon: Pokemon, _passive: boolean, _simulated: boolean, _args: any[]): boolean { + // force ability popup for ability triggers on normal turns. + // Still not used if ability doesn't proc + this.showAbility = true; + return !!pokemon.summonData.berriesEatenLast.length; + } + + /** + * Cause this {@linkcode Pokemon} to regurgitate and eat all berries inside its `berriesEatenLast` array. + * Triggers a berry use animation, but does *not* count for other berry or item-related abilities. + * @param pokemon - The {@linkcode Pokemon} having a bad tummy ache + * @param _passive - N/A + * @param _simulated - N/A + * @param _cancelled - N/A + * @param _args - N/A + */ + override apply(pokemon: Pokemon, _passive: boolean, _simulated: boolean, _cancelled: BooleanHolder | null, _args: any[]): void { + globalScene.unshiftPhase( + new CommonAnimPhase(pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.USE_ITEM), + ); + + // Re-apply effects of all berries previously scarfed. + // This doesn't count as "eating" a berry (for unnerve/stuff cheeks/unburden) as no item is consumed. + for (const berryType of pokemon.summonData.berriesEatenLast) { + getBerryEffectFunc(berryType)(pokemon); + const bMod = new BerryModifier(new BerryModifierType(berryType), pokemon.id, berryType, 1); + globalScene.eventTarget.dispatchEvent(new BerryUsedEvent(bMod)); // trigger message + } + + // uncomment to make cheek pouch work with cud chew + // applyAbAttrs(HealFromBerryUseAbAttr, pokemon, new BooleanHolder(false)); + } + + /** + * @returns always `true` as we always want to move berries into summon data + */ + override canApplyPostTurn(pokemon: Pokemon, _passive: boolean, _simulated: boolean, _args: any[]): boolean { + this.showAbility = false; // don't show popup for turn end berry moving (should ideally be hidden) + return true; + } + + /** + * Move this {@linkcode Pokemon}'s `berriesEaten` array from `PokemonTurnData` + * into `PokemonSummonData` on turn end. + * Both arrays are cleared on switch. + * @param pokemon - The {@linkcode Pokemon} having a nice snack + * @param _passive - N/A + * @param _simulated - N/A + * @param _args - N/A + */ + override applyPostTurn(pokemon: Pokemon, _passive: boolean, _simulated: boolean, _args: any[]): void { + pokemon.summonData.berriesEatenLast = pokemon.turnData.berriesEaten; + } +} + +/** + * Attribute used for {@linkcode Abilities.MOODY} to randomly raise and lower stats at turn end. */ export class MoodyAbAttr extends PostTurnAbAttr { constructor() { @@ -4232,7 +4307,7 @@ export class PostTurnHurtIfSleepingAbAttr extends PostTurnAbAttr { } /** * Deals damage to all sleeping opponents equal to 1/8 of their max hp (min 1) - * @param pokemon Pokemon that has this ability + * @param pokemon {@linkcode Pokemon} with this ability * @param passive N/A * @param simulated `true` if applying in a simulated call. * @param args N/A @@ -4414,7 +4489,7 @@ export class PostItemLostAbAttr extends AbAttr { } /** - * Applies a Battler Tag to the Pokemon after it loses or consumes item + * Applies a Battler Tag to the Pokemon after it loses or consumes an item * @extends PostItemLostAbAttr */ export class PostItemLostApplyBattlerTagAbAttr extends PostItemLostAbAttr { @@ -4503,8 +4578,19 @@ export class DoubleBerryEffectAbAttr extends AbAttr { } } +/** + * Attribute to prevent opposing berry use while on the field. + * Used by {@linkcode Abilities.UNNERVE}, {@linkcode Abilities.AS_ONE_GLASTRIER} and {@linkcode Abilities.AS_ONE_SPECTRIER} + */ export class PreventBerryUseAbAttr extends AbAttr { - override apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: BooleanHolder, args: any[]): void { + /** + * Prevent use of opposing berries. + * @param _pokemon - Unused + * @param _passive - Unused + * @param _simulated - Unused + * @param cancelled - {@linkcode BooleanHolder} containing whether to block berry use + */ + override apply(_pokemon: Pokemon, _passive: boolean, _simulated: boolean, cancelled: BooleanHolder): void { cancelled.value = true; } } @@ -4526,17 +4612,19 @@ export class HealFromBerryUseAbAttr extends AbAttr { } override apply(pokemon: Pokemon, passive: boolean, simulated: boolean, ...args: [BooleanHolder, any[]]): void { + if (simulated) { + return; + } + const { name: abilityName } = passive ? pokemon.getPassiveAbility() : pokemon.getAbility(); - if (!simulated) { - globalScene.unshiftPhase( - new PokemonHealPhase( - pokemon.getBattlerIndex(), - toDmgValue(pokemon.getMaxHp() * this.healPercent), - i18next.t("abilityTriggers:healFromBerryUse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }), - true + globalScene.unshiftPhase( + new PokemonHealPhase( + pokemon.getBattlerIndex(), + toDmgValue(pokemon.getMaxHp() * this.healPercent), + i18next.t("abilityTriggers:healFromBerryUse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName }), + true ) ); - } } } @@ -4568,7 +4656,8 @@ export class CheckTrappedAbAttr extends AbAttr { simulated: boolean, trapped: BooleanHolder, otherPokemon: Pokemon, - args: any[]): boolean { + args: any[], + ): boolean { return true; } @@ -5091,7 +5180,7 @@ export class PostSummonStatStageChangeOnArenaAbAttr extends PostSummonStatStageC /** * Takes no damage from the first hit of a damaging move. * This is used in the Disguise and Ice Face abilities. - * + * * Does not apply to a user's substitute * @extends ReceivedMoveDamageMultiplierAbAttr */ @@ -5176,15 +5265,14 @@ export class IllusionPreSummonAbAttr extends PreSummonAbAttr { } override canApplyPreSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean { - pokemon.initSummondata() - if(pokemon.hasTrainer()){ + 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 the last conscious Pokémon in the party is a Terastallized Ogerpon or Terapagos, Illusion will not activate. // Illusion will also not activate if the Pokémon with Illusion is Terastallized and the last Pokémon in the party is Ogerpon or Terapagos. - if ( + if ( lastPokemon === pokemon || ((speciesId === Species.OGERPON || speciesId === Species.TERAPAGOS) && (lastPokemon.isTerastallized || pokemon.isTerastallized)) ) { @@ -5221,7 +5309,7 @@ export class PostDefendIllusionBreakAbAttr 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.summonData?.illusion + return breakIllusion.includes(hitResult) && !!pokemon.summonData.illusion } } @@ -5442,11 +5530,8 @@ function applySingleAbAttrs( globalScene.queueAbilityDisplay(pokemon, passive, false); } - if (pokemon.summonData && !pokemon.summonData.abilitiesApplied.includes(ability.id)) { - pokemon.summonData.abilitiesApplied.push(ability.id); - } - if (pokemon.battleData && !simulated && !pokemon.battleData.abilitiesApplied.includes(ability.id)) { - pokemon.battleData.abilitiesApplied.push(ability.id); + if (!simulated) { + pokemon.waveData.abilitiesApplied.add(ability.id); } globalScene.clearPhaseQueueSplice(); @@ -5637,6 +5722,7 @@ export class PostDamageForceSwitchAbAttr extends PostDamageAbAttr { this.hpRatio = hpRatio; } + // TODO: Refactor to use more early returns public override canApplyPostDamage( pokemon: Pokemon, damage: number, @@ -5664,6 +5750,7 @@ export class PostDamageForceSwitchAbAttr extends PostDamageAbAttr { if (fordbiddenDefendingMoves.includes(enemyLastMoveUsed.move) || enemyLastMoveUsed.move === Moves.SKY_DROP && enemyLastMoveUsed.result === MoveResult.OTHER) { return false; // Will not activate if the Pokémon's HP falls below half by a move affected by Sheer Force. + // TODO: Make this use the sheer force disable condition } else if (allMoves[enemyLastMoveUsed.move].chance >= 0 && source.hasAbility(Abilities.SHEER_FORCE)) { return false; // Activate only after the last hit of multistrike moves @@ -6326,17 +6413,14 @@ export function applyOnLoseAbAttrs(pokemon: Pokemon, passive = false, simulated /** * Sets the ability of a Pokémon as revealed. - * * @param pokemon - The Pokémon whose ability is being revealed. */ function setAbilityRevealed(pokemon: Pokemon): void { - if (pokemon.battleData) { - pokemon.battleData.abilityRevealed = true; - } + pokemon.waveData.abilityRevealed = true; } /** - * Returns the Pokemon with weather-based forms + * Returns all Pokemon on field with weather-based forms */ function getPokemonWithWeatherBasedForms() { return globalScene.getField(true).filter(p => @@ -6784,8 +6868,7 @@ export function initAbilities() { .attr(MovePowerBoostAbAttr, (user, target, move) => move.category === MoveCategory.SPECIAL && user?.status?.effect === StatusEffect.BURN, 1.5), new Ability(Abilities.HARVEST, 5) .attr( - PostTurnLootAbAttr, - "EATEN_BERRIES", + PostTurnRestoreBerryAbAttr, /** Rate is doubled when under sun {@link https://dex.pokemonshowdown.com/abilities/harvest} */ (pokemon) => 0.5 * (getWeatherCondition(WeatherType.SUNNY, WeatherType.HARSH_SUN)(pokemon) ? 2 : 1) ) @@ -6907,7 +6990,7 @@ export function initAbilities() { .attr(HealFromBerryUseAbAttr, 1 / 3), new Ability(Abilities.PROTEAN, 6) .attr(PokemonTypeChangeAbAttr), - //.condition((p) => !p.summonData?.abilitiesApplied.includes(Abilities.PROTEAN)), //Gen 9 Implementation + //.condition((p) => !p.summonData.abilitiesApplied.includes(Abilities.PROTEAN)), //Gen 9 Implementation new Ability(Abilities.FUR_COAT, 6) .attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.category === MoveCategory.PHYSICAL, 0.5) .ignorable(), @@ -7153,7 +7236,7 @@ export function initAbilities() { .attr(PostSummonStatStageChangeAbAttr, [ Stat.DEF ], 1, true), new Ability(Abilities.LIBERO, 8) .attr(PokemonTypeChangeAbAttr), - //.condition((p) => !p.summonData?.abilitiesApplied.includes(Abilities.LIBERO)), //Gen 9 Implementation + //.condition((p) => !p.summonData.abilitiesApplied.includes(Abilities.LIBERO)), //Gen 9 Implementation new Ability(Abilities.BALL_FETCH, 8) .attr(FetchBallAbAttr) .condition(getOncePerBattleCondition(Abilities.BALL_FETCH)), @@ -7368,7 +7451,7 @@ export function initAbilities() { new Ability(Abilities.OPPORTUNIST, 9) .attr(StatStageChangeCopyAbAttr), new Ability(Abilities.CUD_CHEW, 9) - .unimplemented(), + .attr(RepeatBerryNextTurnAbAttr), new Ability(Abilities.SHARPNESS, 9) .attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.SLICING_MOVE), 1.5), new Ability(Abilities.SUPREME_OVERLORD, 9) diff --git a/src/data/arena-tag.ts b/src/data/arena-tag.ts index ff9e4068292..19c94a8a045 100644 --- a/src/data/arena-tag.ts +++ b/src/data/arena-tag.ts @@ -768,32 +768,27 @@ class SpikesTag extends ArenaTrapTag { } override activateTrap(pokemon: Pokemon, simulated: boolean): boolean { - if (pokemon.isGrounded()) { - const cancelled = new BooleanHolder(false); - applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled); - - if (simulated) { - return !cancelled.value; - } - - if (!cancelled.value) { - const damageHpRatio = 1 / (10 - 2 * this.layers); - const damage = toDmgValue(pokemon.getMaxHp() * damageHpRatio); - - globalScene.queueMessage( - i18next.t("arenaTag:spikesActivateTrap", { - pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), - }), - ); - pokemon.damageAndUpdate(damage, { result: HitResult.INDIRECT }); - if (pokemon.turnData) { - pokemon.turnData.damageTaken += damage; - } - return true; - } + if (!pokemon.isGrounded()) { + return false; } - return false; + const cancelled = new BooleanHolder(false); + applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled); + if (simulated || cancelled.value) { + return !cancelled.value; + } + + const damageHpRatio = 1 / (10 - 2 * this.layers); + const damage = toDmgValue(pokemon.getMaxHp() * damageHpRatio); + + globalScene.queueMessage( + i18next.t("arenaTag:spikesActivateTrap", { + pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), + }), + ); + pokemon.damageAndUpdate(damage, { result: HitResult.INDIRECT }); + pokemon.turnData.damageTaken += damage; + return true; } } @@ -962,31 +957,28 @@ class StealthRockTag extends ArenaTrapTag { override activateTrap(pokemon: Pokemon, simulated: boolean): boolean { const cancelled = new BooleanHolder(false); applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled); - if (cancelled.value) { return false; } const damageHpRatio = this.getDamageHpRatio(pokemon); + if (!damageHpRatio) { + return false; + } - if (damageHpRatio) { - if (simulated) { - return true; - } - const damage = toDmgValue(pokemon.getMaxHp() * damageHpRatio); - globalScene.queueMessage( - i18next.t("arenaTag:stealthRockActivateTrap", { - pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), - }), - ); - pokemon.damageAndUpdate(damage, { result: HitResult.INDIRECT }); - if (pokemon.turnData) { - pokemon.turnData.damageTaken += damage; - } + if (simulated) { return true; } - return false; + const damage = toDmgValue(pokemon.getMaxHp() * damageHpRatio); + globalScene.queueMessage( + i18next.t("arenaTag:stealthRockActivateTrap", { + pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), + }), + ); + pokemon.damageAndUpdate(damage, { result: HitResult.INDIRECT }); + pokemon.turnData.damageTaken += damage; + return true; } getMatchupScoreMultiplier(pokemon: Pokemon): number { diff --git a/src/data/battle-anims.ts b/src/data/battle-anims.ts index 0999e9db6ff..454bd40130c 100644 --- a/src/data/battle-anims.ts +++ b/src/data/battle-anims.ts @@ -1132,7 +1132,6 @@ export abstract class BattleAnim { if (priority === 0) { // Place the sprite in front of the pokemon on the field. targetSprite = globalScene.getEnemyField().find(p => p) ?? globalScene.getPlayerField().find(p => p); - console.log(typeof targetSprite); moveFunc = globalScene.field.moveBelow; } else if (priority === 2 && this.bgSprite) { moveFunc = globalScene.field.moveAbove; diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index ee41f0435b9..8a512f3c16c 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -1,4 +1,5 @@ import { globalScene } from "#app/global-scene"; +import Overrides from "#app/overrides"; import { applyAbAttrs, BlockNonDirectDamageAbAttr, @@ -91,7 +92,12 @@ export class BattlerTag { onOverlap(_pokemon: Pokemon): void {} + /** + * Tick down this {@linkcode BattlerTag}'s duration. + * @returns `true` if the tag should be kept (`turnCount` > 0`) + */ lapse(_pokemon: Pokemon, _lapseType: BattlerTagLapseType): boolean { + // TODO: Maybe flip this (return `true` if tag needs removal) return --this.turnCount > 0; } @@ -108,9 +114,9 @@ export class BattlerTag { } /** - * When given a battler tag or json representing one, load the data for it. - * This is meant to be inherited from by any battler tag with custom attributes - * @param {BattlerTag | any} source A battler tag + * Load the data for a given {@linkcode BattlerTag} or JSON representation thereof. + * Should be inherited from by any battler tag with custom attributes. + * @param source The battler tag to load */ loadTag(source: BattlerTag | any): void { this.turnCount = source.turnCount; @@ -120,7 +126,7 @@ export class BattlerTag { /** * Helper function that retrieves the source Pokemon object - * @returns The source {@linkcode Pokemon} or `null` if none is found + * @returns The source {@linkcode Pokemon}, or `null` if none is found */ public getSourcePokemon(): Pokemon | null { return this.sourceId ? globalScene.getPokemonById(this.sourceId) : null; @@ -140,8 +146,8 @@ export interface TerrainBattlerTag { * in-game. This is not to be confused with {@linkcode Moves.DISABLE}. * * Descendants can override {@linkcode isMoveRestricted} to restrict moves that - * match a condition. A restricted move gets cancelled before it is used. Players and enemies should not be allowed - * to select restricted moves. + * match a condition. A restricted move gets cancelled before it is used. + * Players and enemies should not be allowed to select restricted moves. */ export abstract class MoveRestrictionBattlerTag extends BattlerTag { constructor( @@ -746,31 +752,33 @@ export class ConfusedTag extends BattlerTag { } lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { - const ret = lapseType !== BattlerTagLapseType.CUSTOM && super.lapse(pokemon, lapseType); + const shouldLapse = lapseType !== BattlerTagLapseType.CUSTOM && super.lapse(pokemon, lapseType); - if (ret) { - globalScene.queueMessage( - i18next.t("battlerTags:confusedLapse", { - pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), - }), - ); - globalScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION)); - - // 1/3 chance of hitting self with a 40 base power move - if (pokemon.randSeedInt(3) === 0) { - const atk = pokemon.getEffectiveStat(Stat.ATK); - const def = pokemon.getEffectiveStat(Stat.DEF); - const damage = toDmgValue( - ((((2 * pokemon.level) / 5 + 2) * 40 * atk) / def / 50 + 2) * (pokemon.randSeedIntRange(85, 100) / 100), - ); - globalScene.queueMessage(i18next.t("battlerTags:confusedLapseHurtItself")); - pokemon.damageAndUpdate(damage, { result: HitResult.CONFUSION }); - pokemon.battleData.hitCount++; - (globalScene.getCurrentPhase() as MovePhase).cancel(); - } + if (!shouldLapse) { + return false; } - return ret; + globalScene.queueMessage( + i18next.t("battlerTags:confusedLapse", { + pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), + }), + ); + globalScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION)); + + // 1/3 chance of hitting self with a 40 base power move + if (pokemon.randSeedInt(3) === 0 || Overrides.CONFUSION_ACTIVATION_OVERRIDE === true) { + const atk = pokemon.getEffectiveStat(Stat.ATK); + const def = pokemon.getEffectiveStat(Stat.DEF); + const damage = toDmgValue( + ((((2 * pokemon.level) / 5 + 2) * 40 * atk) / def / 50 + 2) * (pokemon.randSeedIntRange(85, 100) / 100), + ); + // Intentionally don't increment rage fist's hitCount + globalScene.queueMessage(i18next.t("battlerTags:confusedLapseHurtItself")); + pokemon.damageAndUpdate(damage, { result: HitResult.CONFUSION }); + (globalScene.getCurrentPhase() as MovePhase).cancel(); + } + + return true; } getDescriptor(): string { @@ -1117,8 +1125,8 @@ export class FrenzyTag extends BattlerTag { } /** - * Applies the effects of the move Encore onto the target Pokemon - * Encore forces the target Pokemon to use its most-recent move for 3 turns + * Applies the effects of {@linkcode Moves.ENCORE} onto the target Pokemon. + * Encore forces the target Pokemon to use its most-recent move for 3 turns. */ export class EncoreTag extends MoveRestrictionBattlerTag { public moveId: Moves; @@ -1133,10 +1141,6 @@ export class EncoreTag extends MoveRestrictionBattlerTag { ); } - /** - * When given a battler tag or json representing one, load the data for it. - * @param {BattlerTag | any} source A battler tag - */ loadTag(source: BattlerTag | any): void { super.loadTag(source); this.moveId = source.moveId as Moves; diff --git a/src/data/berry.ts b/src/data/berry.ts index 22950c0beca..ecc3e92ca64 100644 --- a/src/data/berry.ts +++ b/src/data/berry.ts @@ -5,10 +5,8 @@ import { getStatusEffectHealText } from "./status-effect"; import { NumberHolder, toDmgValue, randSeedInt } from "#app/utils/common"; import { DoubleBerryEffectAbAttr, - PostItemLostAbAttr, ReduceBerryUseThresholdAbAttr, applyAbAttrs, - applyPostItemLostAbAttrs, } from "./abilities/ability"; import i18next from "i18next"; import { BattlerTagType } from "#enums/battler-tag-type"; @@ -70,97 +68,94 @@ export function getBerryPredicate(berryType: BerryType): BerryPredicate { } } -export type BerryEffectFunc = (pokemon: Pokemon, berryOwner?: Pokemon) => void; +export type BerryEffectFunc = (consumer: Pokemon) => void; export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc { - switch (berryType) { - case BerryType.SITRUS: - case BerryType.ENIGMA: - return (pokemon: Pokemon, berryOwner?: Pokemon) => { - if (pokemon.battleData) { - pokemon.battleData.berriesEaten.push(berryType); - } - const hpHealed = new NumberHolder(toDmgValue(pokemon.getMaxHp() / 4)); - applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, hpHealed); - globalScene.unshiftPhase( - new PokemonHealPhase( - pokemon.getBattlerIndex(), - hpHealed.value, - i18next.t("battle:hpHealBerry", { - pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), - berryName: getBerryName(berryType), - }), - true, - ), - ); - applyPostItemLostAbAttrs(PostItemLostAbAttr, berryOwner ?? pokemon, false); - }; - case BerryType.LUM: - return (pokemon: Pokemon, berryOwner?: Pokemon) => { - if (pokemon.battleData) { - pokemon.battleData.berriesEaten.push(berryType); - } - if (pokemon.status) { - globalScene.queueMessage(getStatusEffectHealText(pokemon.status.effect, getPokemonNameWithAffix(pokemon))); - } - pokemon.resetStatus(true, true); - pokemon.updateInfo(); - applyPostItemLostAbAttrs(PostItemLostAbAttr, berryOwner ?? pokemon, false); - }; - case BerryType.LIECHI: - case BerryType.GANLON: - case BerryType.PETAYA: - case BerryType.APICOT: - case BerryType.SALAC: - return (pokemon: Pokemon, berryOwner?: Pokemon) => { - if (pokemon.battleData) { - pokemon.battleData.berriesEaten.push(berryType); - } - // Offset BerryType such that LIECHI -> Stat.ATK = 1, GANLON -> Stat.DEF = 2, so on and so forth - const stat: BattleStat = berryType - BerryType.ENIGMA; - const statStages = new NumberHolder(1); - applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, statStages); - globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [stat], statStages.value)); - applyPostItemLostAbAttrs(PostItemLostAbAttr, berryOwner ?? pokemon, false); - }; - case BerryType.LANSAT: - return (pokemon: Pokemon, berryOwner?: Pokemon) => { - if (pokemon.battleData) { - pokemon.battleData.berriesEaten.push(berryType); - } - pokemon.addTag(BattlerTagType.CRIT_BOOST); - applyPostItemLostAbAttrs(PostItemLostAbAttr, berryOwner ?? pokemon, false); - }; - case BerryType.STARF: - return (pokemon: Pokemon, berryOwner?: Pokemon) => { - if (pokemon.battleData) { - pokemon.battleData.berriesEaten.push(berryType); - } - const randStat = randSeedInt(Stat.SPD, Stat.ATK); - const stages = new NumberHolder(2); - applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, stages); - globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [randStat], stages.value)); - applyPostItemLostAbAttrs(PostItemLostAbAttr, berryOwner ?? pokemon, false); - }; - case BerryType.LEPPA: - return (pokemon: Pokemon, berryOwner?: Pokemon) => { - if (pokemon.battleData) { - pokemon.battleData.berriesEaten.push(berryType); - } - const ppRestoreMove = pokemon.getMoveset().find(m => !m.getPpRatio()) - ? pokemon.getMoveset().find(m => !m.getPpRatio()) - : pokemon.getMoveset().find(m => m.getPpRatio() < 1); - if (ppRestoreMove !== undefined) { - ppRestoreMove!.ppUsed = Math.max(ppRestoreMove!.ppUsed - 10, 0); - globalScene.queueMessage( - i18next.t("battle:ppHealBerry", { - pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), - moveName: ppRestoreMove!.getName(), - berryName: getBerryName(berryType), - }), + return (consumer: Pokemon) => { + // Apply an effect pertaining to what berry we're using + switch (berryType) { + case BerryType.SITRUS: + case BerryType.ENIGMA: + { + const hpHealed = new NumberHolder(toDmgValue(consumer.getMaxHp() / 4)); + applyAbAttrs(DoubleBerryEffectAbAttr, consumer, null, false, hpHealed); + globalScene.unshiftPhase( + new PokemonHealPhase( + consumer.getBattlerIndex(), + hpHealed.value, + i18next.t("battle:hpHealBerry", { + pokemonNameWithAffix: getPokemonNameWithAffix(consumer), + berryName: getBerryName(berryType), + }), + true, + ), ); - applyPostItemLostAbAttrs(PostItemLostAbAttr, berryOwner ?? pokemon, false); } - }; - } + break; + case BerryType.LUM: + { + if (consumer.status) { + globalScene.queueMessage( + getStatusEffectHealText(consumer.status.effect, getPokemonNameWithAffix(consumer)), + ); + } + consumer.resetStatus(true, true); + consumer.updateInfo(); + } + break; + case BerryType.LIECHI: + case BerryType.GANLON: + case BerryType.PETAYA: + case BerryType.APICOT: + case BerryType.SALAC: + { + // Offset BerryType such that LIECHI --> Stat.ATK = 1, GANLON --> Stat.DEF = 2, etc etc. + const stat: BattleStat = berryType - BerryType.ENIGMA; + const statStages = new NumberHolder(1); + applyAbAttrs(DoubleBerryEffectAbAttr, consumer, null, false, statStages); + globalScene.unshiftPhase( + new StatStageChangePhase(consumer.getBattlerIndex(), true, [stat], statStages.value), + ); + } + break; + + case BerryType.LANSAT: + { + consumer.addTag(BattlerTagType.CRIT_BOOST); + } + break; + + case BerryType.STARF: + { + const randStat = randSeedInt(Stat.SPD, Stat.ATK); + const stages = new NumberHolder(2); + applyAbAttrs(DoubleBerryEffectAbAttr, consumer, null, false, stages); + globalScene.unshiftPhase( + new StatStageChangePhase(consumer.getBattlerIndex(), true, [randStat], stages.value), + ); + } + break; + + case BerryType.LEPPA: + { + // Pick the first move completely out of PP, or else the first one that has any PP missing + const ppRestoreMove = + consumer.getMoveset().find(m => m.ppUsed === m.getMovePp()) ?? + consumer.getMoveset().find(m => m.ppUsed < m.getMovePp()); + if (ppRestoreMove) { + ppRestoreMove.ppUsed = Math.max(ppRestoreMove.ppUsed - 10, 0); + globalScene.queueMessage( + i18next.t("battle:ppHealBerry", { + pokemonNameWithAffix: getPokemonNameWithAffix(consumer), + moveName: ppRestoreMove.getName(), + berryName: getBerryName(berryType), + }), + ); + } + } + break; + default: + console.error("Incorrect BerryType %d passed to GetBerryEffectFunc", berryType); + } + }; } diff --git a/src/data/challenge.ts b/src/data/challenge.ts index 7388f397c7e..b4b8db2cc10 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -1,4 +1,5 @@ -import { BooleanHolder, type NumberHolder, randSeedItem, deepCopy } from "#app/utils/common"; +import { BooleanHolder, type NumberHolder, randSeedItem } from "#app/utils/common"; +import { deepCopy } from "#app/utils/data"; import i18next from "i18next"; import type { DexAttrProps, GameData } from "#app/system/game-data"; import { defaultStarterSpecies } from "#app/system/game-data"; diff --git a/src/data/custom-pokemon-data.ts b/src/data/custom-pokemon-data.ts index 704835e9dbc..20f6ea96174 100644 --- a/src/data/custom-pokemon-data.ts +++ b/src/data/custom-pokemon-data.ts @@ -1,36 +1,31 @@ import type { Abilities } from "#enums/abilities"; import type { PokemonType } from "#enums/pokemon-type"; -import { isNullOrUndefined } from "#app/utils/common"; import type { Nature } from "#enums/nature"; /** - * Data that can customize a Pokemon in non-standard ways from its Species - * Used by Mystery Encounters and Mints - * Also used as a counter how often a Pokemon got hit until new arena encounter + * Data that can customize a Pokemon in non-standard ways from its Species. + * Includes abilities, nature, changed types, etc. */ export class CustomPokemonData { - public spriteScale: number; + // TODO: Change the default value for all these from -1 to something a bit more sensible + /** + * The scale at which to render this Pokemon's sprite. + */ + public spriteScale = -1; public ability: Abilities | -1; public passive: Abilities | -1; public nature: Nature | -1; public types: PokemonType[]; - /** `hitsReceivedCount` aka `hitsRecCount` saves how often the pokemon got hit until a new arena encounter (used for Rage Fist) */ - public hitsRecCount: number; + /** Deprecated but needed for session save migration */ + // TODO: Remove this once pre-session migration is implemented + public hitsRecCount: number | null = null; constructor(data?: CustomPokemonData | Partial) { - if (!isNullOrUndefined(data)) { - Object.assign(this, data); - } - - this.spriteScale = this.spriteScale ?? -1; - this.ability = this.ability ?? -1; - this.passive = this.passive ?? -1; - this.nature = this.nature ?? -1; - this.types = this.types ?? []; - this.hitsRecCount = this.hitsRecCount ?? 0; - } - - resetHitReceivedCount(): void { - this.hitsRecCount = 0; + this.spriteScale = data?.spriteScale ?? -1; + this.ability = data?.ability ?? -1; + this.passive = data?.passive ?? -1; + this.nature = data?.nature ?? -1; + this.types = data?.types ?? []; + this.hitsRecCount = data?.hitsRecCount ?? null; } } diff --git a/src/data/moves/move.ts b/src/data/moves/move.ts index 29542b54f6d..81ae499da10 100644 --- a/src/data/moves/move.ts +++ b/src/data/moves/move.ts @@ -2532,10 +2532,10 @@ export class PsychoShiftEffectAttr extends MoveEffectAttr { return !target.status && target.canSetStatus(user.status?.effect, true, false, user) ? -10 : 0; } } + /** - * The following needs to be implemented for Thief - * "If the user faints due to the target's Ability (Rough Skin or Iron Barbs) or held Rocky Helmet, it cannot remove the target's held item." - * "If Knock Off causes a Pokémon with the Sticky Hold Ability to faint, it can now remove that Pokémon's held item." + * Attribute to steal items upon this move's use. + * Used for {@linkcode Moves.THIEF} and {@linkcode Moves.COVET}. */ export class StealHeldItemChanceAttr extends MoveEffectAttr { private chance: number; @@ -2550,18 +2550,22 @@ export class StealHeldItemChanceAttr extends MoveEffectAttr { if (rand >= this.chance) { return false; } + const heldItems = this.getTargetHeldItems(target).filter((i) => i.isTransferable); - if (heldItems.length) { - const poolType = target.isPlayer() ? ModifierPoolType.PLAYER : target.hasTrainer() ? ModifierPoolType.TRAINER : ModifierPoolType.WILD; - const highestItemTier = heldItems.map((m) => m.type.getOrInferTier(poolType)).reduce((highestTier, tier) => Math.max(tier!, highestTier), 0); // TODO: is the bang after tier correct? - const tierHeldItems = heldItems.filter((m) => m.type.getOrInferTier(poolType) === highestItemTier); - const stolenItem = tierHeldItems[user.randSeedInt(tierHeldItems.length)]; - if (globalScene.tryTransferHeldItemModifier(stolenItem, user, false)) { - globalScene.queueMessage(i18next.t("moveTriggers:stoleItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: stolenItem.type.name })); - return true; - } + if (!heldItems.length) { + return false; } - return false; + + const poolType = target.isPlayer() ? ModifierPoolType.PLAYER : target.hasTrainer() ? ModifierPoolType.TRAINER : ModifierPoolType.WILD; + const highestItemTier = heldItems.map((m) => m.type.getOrInferTier(poolType)).reduce((highestTier, tier) => Math.max(tier!, highestTier), 0); // TODO: is the bang after tier correct? + const tierHeldItems = heldItems.filter((m) => m.type.getOrInferTier(poolType) === highestItemTier); + const stolenItem = tierHeldItems[user.randSeedInt(tierHeldItems.length)]; + if (!globalScene.tryTransferHeldItemModifier(stolenItem, user, false)) { + return false; + } + + globalScene.queueMessage(i18next.t("moveTriggers:stoleItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: stolenItem.type.name })); + return true; } getTargetHeldItems(target: Pokemon): PokemonHeldItemModifier[] { @@ -2585,58 +2589,62 @@ export class StealHeldItemChanceAttr extends MoveEffectAttr { * Used for Incinerate and Knock Off. * Not Implemented Cases: (Same applies for Thief) * "If the user faints due to the target's Ability (Rough Skin or Iron Barbs) or held Rocky Helmet, it cannot remove the target's held item." - * "If Knock Off causes a Pokémon with the Sticky Hold Ability to faint, it can now remove that Pokémon's held item." + * "If the Pokémon is knocked out by the attack, Sticky Hold does not protect the held item."" */ export class RemoveHeldItemAttr extends MoveEffectAttr { - /** Optional restriction for item pool to berries only i.e. Differentiating Incinerate and Knock Off */ + /** Optional restriction for item pool to berries only; i.e. Incinerate */ private berriesOnly: boolean; - constructor(berriesOnly: boolean) { + constructor(berriesOnly: boolean = false) { super(false); this.berriesOnly = berriesOnly; } /** - * - * @param user {@linkcode Pokemon} that used the move - * @param target Target {@linkcode Pokemon} that the moves applies to - * @param move {@linkcode Move} that is used + * Attempt to permanently remove a held + * @param user - The {@linkcode Pokemon} that used the move + * @param target - The {@linkcode Pokemon} targeted by the move + * @param move - N/A * @param args N/A - * @returns True if an item was removed + * @returns `true` if an item was able to be removed */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { if (!this.berriesOnly && target.isPlayer()) { // "Wild Pokemon cannot knock off Player Pokemon's held items" (See Bulbapedia) return false; } + // Check for abilities that block item theft + // TODO: This should not trigger if the target would faint beforehand const cancelled = new BooleanHolder(false); - applyAbAttrs(BlockItemTheftAbAttr, target, cancelled); // Check for abilities that block item theft + applyAbAttrs(BlockItemTheftAbAttr, target, cancelled); - if (cancelled.value === true) { + if (cancelled.value) { return false; } - // Considers entire transferrable item pool by default (Knock Off). Otherwise berries only if specified (Incinerate). + // Considers entire transferrable item pool by default (Knock Off). + // Otherwise only consider berries (Incinerate). let heldItems = this.getTargetHeldItems(target).filter(i => i.isTransferable); if (this.berriesOnly) { heldItems = heldItems.filter(m => m instanceof BerryModifier && m.pokemonId === target.id, target.isPlayer()); } - if (heldItems.length) { - const removedItem = heldItems[user.randSeedInt(heldItems.length)]; + if (!heldItems.length) { + return false; + } - // Decrease item amount and update icon - target.loseHeldItem(removedItem); - globalScene.updateModifiers(target.isPlayer()); + const removedItem = heldItems[user.randSeedInt(heldItems.length)]; + // Decrease item amount and update icon + target.loseHeldItem(removedItem); + globalScene.updateModifiers(target.isPlayer()); - if (this.berriesOnly) { - globalScene.queueMessage(i18next.t("moveTriggers:incineratedItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: removedItem.type.name })); - } else { - globalScene.queueMessage(i18next.t("moveTriggers:knockedOffItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: removedItem.type.name })); - } + if (this.berriesOnly) { + globalScene.queueMessage(i18next.t("moveTriggers:incineratedItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: removedItem.type.name })); + } else { + globalScene.queueMessage(i18next.t("moveTriggers:knockedOffItem", { pokemonName: getPokemonNameWithAffix(user), targetName: getPokemonNameWithAffix(target), itemName: removedItem.type.name })); } return true; @@ -2662,17 +2670,18 @@ export class RemoveHeldItemAttr extends MoveEffectAttr { * Attribute that causes targets of the move to eat a berry. Used for Teatime, Stuff Cheeks */ export class EatBerryAttr extends MoveEffectAttr { - protected chosenBerry: BerryModifier | undefined; + protected chosenBerry: BerryModifier; constructor(selfTarget: boolean) { super(selfTarget); } + /** * Causes the target to eat a berry. - * @param user {@linkcode Pokemon} Pokemon that used the move - * @param target {@linkcode Pokemon} Pokemon that will eat a berry - * @param move {@linkcode Move} The move being used + * @param user The {@linkcode Pokemon} Pokemon that used the move + * @param target The {@linkcode Pokemon} Pokemon that will eat the berry + * @param move The {@linkcode Move} being used * @param args Unused - * @returns {boolean} true if the function succeeds + * @returns `true` if the function succeeds */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { if (!super.apply(user, target, move, args)) { @@ -2685,6 +2694,8 @@ export class EatBerryAttr extends MoveEffectAttr { if (heldBerries.length <= 0) { return false; } + + // pick a random berry to gobble and check if we preserve it this.chosenBerry = heldBerries[user.randSeedInt(heldBerries.length)]; const preserve = new BooleanHolder(false); // check for berry pouch preservation @@ -2692,7 +2703,10 @@ export class EatBerryAttr extends MoveEffectAttr { if (!preserve.value) { this.reduceBerryModifier(pokemon); } - this.eatBerry(pokemon); + + // Don't update harvest for berries preserved via Berry pouch (no item dupes lol) + this.eatBerry(target, undefined, !preserve.value); + return true; } @@ -2708,46 +2722,64 @@ export class EatBerryAttr extends MoveEffectAttr { globalScene.updateModifiers(target.isPlayer()); } - eatBerry(consumer: Pokemon, berryOwner?: Pokemon) { - getBerryEffectFunc(this.chosenBerry!.berryType)(consumer, berryOwner); // consumer eats the berry + + /** + * Internal function to apply berry effects. + * + * @param consumer - The {@linkcode Pokemon} eating the berry; assumed to also be owner if `berryOwner` is omitted + * @param berryOwner - The {@linkcode Pokemon} whose berry is being eaten; defaults to `consumer` if not specified. + * @param updateHarvest - Whether to prevent harvest from tracking berries; + * defaults to whether `consumer` equals `berryOwner` (i.e. consuming own berry). + */ + protected eatBerry(consumer: Pokemon, berryOwner: Pokemon = consumer, updateHarvest = consumer === berryOwner) { + // consumer eats berry, owner triggers unburden and similar effects + getBerryEffectFunc(this.chosenBerry.berryType)(consumer); + applyPostItemLostAbAttrs(PostItemLostAbAttr, berryOwner, false); applyAbAttrs(HealFromBerryUseAbAttr, consumer, new BooleanHolder(false)); + consumer.recordEatenBerry(this.chosenBerry.berryType, updateHarvest); } } /** - * Attribute used for moves that steal a random berry from the target. The user then eats the stolen berry. - * Used for Pluck & Bug Bite. + * Attribute used for moves that steal and eat a random berry from the target. + * Used for {@linkcode Moves.PLUCK} & {@linkcode Moves.BUG_BITE}. */ export class StealEatBerryAttr extends EatBerryAttr { constructor() { super(false); } + /** * User steals a random berry from the target and then eats it. - * @param user - Pokemon that used the move and will eat the stolen berry - * @param target - Pokemon that will have its berry stolen - * @param move - Move being used - * @param args Unused - * @returns true if the function succeeds + * @param user - The {@linkcode Pokemon} using the move; will eat the stolen berry + * @param target - The {@linkcode Pokemon} having its berry stolen + * @param move - The {@linkcode Move} being used + * @param args N/A + * @returns `true` if the function succeeds */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + // check for abilities that block item theft const cancelled = new BooleanHolder(false); - applyAbAttrs(BlockItemTheftAbAttr, target, cancelled); // check for abilities that block item theft + applyAbAttrs(BlockItemTheftAbAttr, target, cancelled); if (cancelled.value === true) { return false; } + // check if the target even _has_ a berry in the first place + // TODO: Check on cart if Pluck displays messages when used against sticky hold mons w/o berries const heldBerries = this.getTargetHeldBerries(target); if (heldBerries.length <= 0) { return false; } - // if the target has berries, pick a random berry and steal it + + // pick a random berry and eat it this.chosenBerry = heldBerries[user.randSeedInt(heldBerries.length)]; applyPostItemLostAbAttrs(PostItemLostAbAttr, target, false); const message = i18next.t("battle:stealEatBerry", { pokemonName: user.name, targetName: target.name, berryName: this.chosenBerry.type.name }); globalScene.queueMessage(message); this.reduceBerryModifier(target); this.eatBerry(user, target); + return true; } } @@ -4100,30 +4132,23 @@ export class FriendshipPowerAttr extends VariablePowerAttr { /** * This Attribute calculates the current power of {@linkcode Moves.RAGE_FIST}. - * The counter for power calculation does not reset on every wave but on every new arena encounter + * The counter for power calculation does not reset on every wave but on every new arena encounter. + * Self-inflicted confusion damage and hits taken by a Subsitute are ignored. */ export class RageFistPowerAttr extends VariablePowerAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - const { hitCount, prevHitCount } = user.battleData; + /* Reasons this works correctly: + * Confusion calls user.damageAndUpdate() directly (no counter increment), + * Substitute hits call user.damageAndUpdate() with a damage value of 0, also causing + no counter increment + */ + const hitCount = user.battleData.hitCount; const basePower: NumberHolder = args[0]; - this.updateHitReceivedCount(user, hitCount, prevHitCount); - - basePower.value = 50 + (Math.min(user.customPokemonData.hitsRecCount, 6) * 50); - + basePower.value = 50 * (1 + Math.min(hitCount, 6)); return true; } - /** - * Updates the number of hits the Pokemon has taken in battle - * @param user Pokemon calling Rage Fist - * @param hitCount The number of received hits this battle - * @param previousHitCount The number of received hits this battle since last time Rage Fist was used - */ - protected updateHitReceivedCount(user: Pokemon, hitCount: number, previousHitCount: number): void { - user.customPokemonData.hitsRecCount += (hitCount - previousHitCount); - user.battleData.prevHitCount = hitCount; - } } /** @@ -4354,10 +4379,10 @@ export class LastMoveDoublePowerAttr extends VariablePowerAttr { const userAlly = user.getAlly(); const enemyAlly = enemy?.getAlly(); - if (!isNullOrUndefined(userAlly) && userAlly.turnData.acted) { + if (userAlly?.turnData.acted) { pokemonActed.push(userAlly); } - if (!isNullOrUndefined(enemyAlly) && enemyAlly.turnData.acted) { + if (enemyAlly?.turnData.acted) { pokemonActed.push(enemyAlly); } } @@ -4425,13 +4450,10 @@ export class CombinedPledgeStabBoostAttr extends MoveAttr { * @extends VariablePowerAttr */ export class RoundPowerAttr extends VariablePowerAttr { - override apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + override apply(user: Pokemon, target: Pokemon, move: Move, args: [NumberHolder]): boolean { const power = args[0]; - if (!(power instanceof NumberHolder)) { - return false; - } - if (user.turnData?.joinedRound) { + if (user.turnData.joinedRound) { power.value *= 2; return true; } @@ -7764,17 +7786,27 @@ export class StatusIfBoostedAttr extends MoveEffectAttr { } } +/** + * Attribute to fail move usage unless all of the user's other moves have been used at least once. + * Used by {@linkcode Moves.LAST_RESORT}. + */ export class LastResortAttr extends MoveAttr { + // TODO: Verify behavior as Bulbapedia page is _extremely_ poorly documented getCondition(): MoveConditionFunc { - return (user: Pokemon, target: Pokemon, move: Move) => { - const uniqueUsedMoveIds = new Set(); - const movesetMoveIds = user.getMoveset().map(m => m.moveId); - user.getMoveHistory().map(m => { - if (m.move !== move.id && movesetMoveIds.find(mm => mm === m.move)) { - uniqueUsedMoveIds.add(m.move); - } - }); - return uniqueUsedMoveIds.size >= movesetMoveIds.length - 1; + return (user: Pokemon, _target: Pokemon, move: Move) => { + const movesInMoveset = new Set(user.getMoveset().map(m => m.moveId)); + if (!movesInMoveset.delete(move.id) || !movesInMoveset.size) { + return false; // Last resort fails if used when not in user's moveset or no other moves exist + } + + const movesInHistory = new Set( + user.getMoveHistory() + .filter(m => !m.virtual) // TODO: Change to (m) => m < MoveUseType.INDIRECT after Dancer PR refactors virtual into enum + .map(m => m.move) + ); + + // Since `Set.intersection()` is only present in ESNext, we have to coerce it to an array to check inclusion + return [...movesInMoveset].every(m => movesInHistory.has(m)) }; } } @@ -7982,13 +8014,18 @@ export class MoveCondition { } } +/** + * Condition to allow a move's use only on the first turn this Pokemon is sent into battle + * (or the start of a new wave, whichever comes first). + */ + export class FirstMoveCondition extends MoveCondition { constructor() { - super((user, target, move) => user.battleSummonData?.waveTurnCount === 1); + super((user, _target, _move) => user.tempSummonData.waveTurnCount === 1); } - getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): number { - return this.apply(user, target, move) ? 10 : -20; + getUserBenefitScore(user: Pokemon, _target: Pokemon, _move: Move): number { + return this.apply(user, _target, _move) ? 10 : -20; } } @@ -8626,7 +8663,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.summonData?.illusion && !user.summonData?.illusion) + .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() @@ -8701,7 +8738,10 @@ export function initMoves() { .attr(MultiHitPowerIncrementAttr, 3) .checkAllHits(), new AttackMove(Moves.THIEF, PokemonType.DARK, MoveCategory.PHYSICAL, 60, 100, 25, -1, 0, 2) - .attr(StealHeldItemChanceAttr, 0.3), + .attr(StealHeldItemChanceAttr, 0.3) + .edgeCase(), + // Should not be able to steal held item if user faints due to Rough Skin, Iron Barbs, etc. + // Should be able to steal items from pokemon with Sticky Hold if the damage causes them to faint new StatusMove(Moves.SPIDER_WEB, PokemonType.BUG, -1, 10, -1, 0, 2) .condition(failIfGhostTypeCondition) .attr(AddBattlerTagAttr, BattlerTagType.TRAPPED, false, true, 1) @@ -8991,6 +9031,7 @@ export function initMoves() { .soundBased() .target(MoveTarget.RANDOM_NEAR_ENEMY) .partial(), // Does not lock the user, does not stop Pokemon from sleeping + // Likely can make use of FrenzyAttr and an ArenaTag (just without the FrenzyMissFunc) new SelfStatusMove(Moves.STOCKPILE, PokemonType.NORMAL, -1, 20, -1, 0, 3) .condition(user => (user.getTag(StockpilingTag)?.stockpiledCount ?? 0) < 3) .attr(AddBattlerTagAttr, BattlerTagType.STOCKPILING, true), @@ -9088,7 +9129,10 @@ export function initMoves() { .reflectable(), new AttackMove(Moves.KNOCK_OFF, PokemonType.DARK, MoveCategory.PHYSICAL, 65, 100, 20, -1, 0, 3) .attr(MovePowerMultiplierAttr, (user, target, move) => target.getHeldItems().filter(i => i.isTransferable).length > 0 ? 1.5 : 1) - .attr(RemoveHeldItemAttr, false), + .attr(RemoveHeldItemAttr, false) + .edgeCase(), + // Should not be able to remove held item if user faints due to Rough Skin, Iron Barbs, etc. + // Should be able to remove items from pokemon with Sticky Hold if the damage causes them to faint new AttackMove(Moves.ENDEAVOR, PokemonType.NORMAL, MoveCategory.PHYSICAL, -1, 100, 5, -1, 0, 3) .attr(MatchHpAttr) .condition(failOnBossCondition), @@ -9276,7 +9320,10 @@ export function initMoves() { .attr(HighCritAttr) .attr(StatusEffectAttr, StatusEffect.POISON), new AttackMove(Moves.COVET, PokemonType.NORMAL, MoveCategory.PHYSICAL, 60, 100, 25, -1, 0, 3) - .attr(StealHeldItemChanceAttr, 0.3), + .attr(StealHeldItemChanceAttr, 0.3) + .edgeCase(), + // Should not be able to steal held item if user faints due to Rough Skin, Iron Barbs, etc. + // Should be able to steal items from pokemon with Sticky Hold if the damage causes them to faint new AttackMove(Moves.VOLT_TACKLE, PokemonType.ELECTRIC, MoveCategory.PHYSICAL, 120, 100, 15, 10, 0, 3) .attr(RecoilAttr, false, 0.33) .attr(StatusEffectAttr, StatusEffect.PARALYSIS) @@ -9338,6 +9385,11 @@ export function initMoves() { new AttackMove(Moves.NATURAL_GIFT, PokemonType.NORMAL, MoveCategory.PHYSICAL, -1, 100, 15, -1, 0, 4) .makesContact(false) .unimplemented(), + /* + NOTE: To whoever tries to implement this, reminder to push to battleData.berriesEaten + and enable the harvest test.. + Do NOT push to berriesEatenLast or else cud chew will puke the berry. + */ new AttackMove(Moves.FEINT, PokemonType.NORMAL, MoveCategory.PHYSICAL, 30, 100, 10, -1, 2, 4) .attr(RemoveBattlerTagAttr, [ BattlerTagType.PROTECTED ]) .attr(RemoveArenaTagsAttr, [ ArenaTagType.QUICK_GUARD, ArenaTagType.WIDE_GUARD, ArenaTagType.MAT_BLOCK, ArenaTagType.CRAFTY_SHIELD ], false) @@ -9415,7 +9467,8 @@ export function initMoves() { .makesContact(true) .attr(PunishmentPowerAttr), new AttackMove(Moves.LAST_RESORT, PokemonType.NORMAL, MoveCategory.PHYSICAL, 140, 100, 5, -1, 0, 4) - .attr(LastResortAttr), + .attr(LastResortAttr) + .edgeCase(), // May or may not need to ignore remotely called moves depending on how it works new StatusMove(Moves.WORRY_SEED, PokemonType.GRASS, 100, 10, -1, 0, 4) .attr(AbilityChangeAttr, Abilities.INSOMNIA) .reflectable(), @@ -9782,7 +9835,9 @@ export function initMoves() { .hidesTarget(), new AttackMove(Moves.INCINERATE, PokemonType.FIRE, MoveCategory.SPECIAL, 60, 100, 15, -1, 0, 5) .target(MoveTarget.ALL_NEAR_ENEMIES) - .attr(RemoveHeldItemAttr, true), + .attr(RemoveHeldItemAttr, true) + .edgeCase(), + // Should be able to remove items from pokemon with Sticky Hold if the damage causes them to faint new StatusMove(Moves.QUASH, PokemonType.DARK, 100, 15, -1, 0, 5) .condition(failIfSingleBattle) .condition((user, target, move) => !target.turnData.acted) @@ -9957,7 +10012,7 @@ export function initMoves() { .condition(new FirstMoveCondition()) .condition(failIfLastCondition), new AttackMove(Moves.BELCH, PokemonType.POISON, MoveCategory.SPECIAL, 120, 90, 10, -1, 0, 6) - .condition((user, target, move) => user.battleData.berriesEaten.length > 0), + .condition((user, target, move) => user.battleData.hasEatenBerry), new StatusMove(Moves.ROTOTILLER, PokemonType.GROUND, -1, 10, -1, 0, 6) .target(MoveTarget.ALL) .condition((user, target, move) => { @@ -11083,7 +11138,6 @@ export function initMoves() { new AttackMove(Moves.TWIN_BEAM, PokemonType.PSYCHIC, MoveCategory.SPECIAL, 40, 100, 10, -1, 0, 9) .attr(MultiHitAttr, MultiHitType._2), new AttackMove(Moves.RAGE_FIST, PokemonType.GHOST, MoveCategory.PHYSICAL, 50, 100, 10, -1, 0, 9) - .edgeCase() // Counter incorrectly increases on confusion self-hits .attr(RageFistPowerAttr) .punchingMove(), new AttackMove(Moves.ARMOR_CANNON, PokemonType.FIRE, MoveCategory.SPECIAL, 120, 100, 5, -1, 0, 9) diff --git a/src/data/mystery-encounters/encounters/clowning-around-encounter.ts b/src/data/mystery-encounters/encounters/clowning-around-encounter.ts index 24c076f750e..ce5eb2cfdd1 100644 --- a/src/data/mystery-encounters/encounters/clowning-around-encounter.ts +++ b/src/data/mystery-encounters/encounters/clowning-around-encounter.ts @@ -397,9 +397,6 @@ export const ClowningAroundEncounter: MysteryEncounter = MysteryEncounterBuilder newTypes.push(secondType); // Apply the type changes (to both base and fusion, if pokemon is fused) - if (!pokemon.customPokemonData) { - pokemon.customPokemonData = new CustomPokemonData(); - } pokemon.customPokemonData.types = newTypes; if (pokemon.isFusion()) { if (!pokemon.fusionCustomPokemonData) { diff --git a/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts b/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts index b0721ddfee9..bb41bc7883c 100644 --- a/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts +++ b/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts @@ -684,7 +684,7 @@ function doPokemonTradeSequence(tradedPokemon: PlayerPokemon, receivedPokemon: P sprite.setPipelineData("shiny", tradedPokemon.shiny); sprite.setPipelineData("variant", tradedPokemon.variant); ["spriteColors", "fusionSpriteColors"].map(k => { - if (tradedPokemon.summonData?.speciesForm) { + if (tradedPokemon.summonData.speciesForm) { k += "Base"; } sprite.pipelineData[k] = tradedPokemon.getSprite().pipelineData[k]; @@ -710,7 +710,7 @@ function doPokemonTradeSequence(tradedPokemon: PlayerPokemon, receivedPokemon: P sprite.setPipelineData("shiny", receivedPokemon.shiny); sprite.setPipelineData("variant", receivedPokemon.variant); ["spriteColors", "fusionSpriteColors"].map(k => { - if (receivedPokemon.summonData?.speciesForm) { + if (receivedPokemon.summonData.speciesForm) { k += "Base"; } sprite.pipelineData[k] = receivedPokemon.getSprite().pipelineData[k]; diff --git a/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts b/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts index bc7c570abca..3cbe42591d8 100644 --- a/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts @@ -222,7 +222,8 @@ function endTrainerBattleAndShowDialogue(): Promise { globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger); } - pokemon.resetBattleData(); + // Each trainer battle is supposed to be a new fight, so reset all per-battle activation effects + pokemon.resetBattleAndWaveData(); applyPostBattleInitAbAttrs(PostBattleInitAbAttr, pokemon); } diff --git a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts index cd9ffefb516..cceda25fcb4 100644 --- a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts +++ b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts @@ -23,7 +23,6 @@ import { allSpecies, getPokemonSpecies } from "#app/data/pokemon-species"; import type { PokemonHeldItemModifier } from "#app/modifier/modifier"; import { HiddenAbilityRateBoosterModifier, PokemonFormChangeItemModifier } from "#app/modifier/modifier"; import { achvs } from "#app/system/achv"; -import { CustomPokemonData } from "#app/data/custom-pokemon-data"; import { showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import type { PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; import { modifierTypes } from "#app/modifier/modifier-type"; @@ -601,9 +600,6 @@ async function postProcessTransformedPokemon( newType = randSeedInt(18) as PokemonType; } newTypes.push(newType); - if (!newPokemon.customPokemonData) { - newPokemon.customPokemonData = new CustomPokemonData(); - } newPokemon.customPokemonData.types = newTypes; // Enable passive if previous had it diff --git a/src/data/mystery-encounters/utils/encounter-phase-utils.ts b/src/data/mystery-encounters/utils/encounter-phase-utils.ts index 67904fc856c..0215928bbe8 100644 --- a/src/data/mystery-encounters/utils/encounter-phase-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-phase-utils.ts @@ -10,7 +10,7 @@ import { import { showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; import type { AiType, PlayerPokemon } from "#app/field/pokemon"; import type Pokemon from "#app/field/pokemon"; -import { EnemyPokemon, FieldPosition, PokemonMove, PokemonSummonData } from "#app/field/pokemon"; +import { EnemyPokemon, FieldPosition, PokemonMove } from "#app/field/pokemon"; import type { CustomModifierSettings, ModifierType } from "#app/modifier/modifier-type"; import { getPartyLuckValue, @@ -348,11 +348,6 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig): enemyPokemon.status = new Status(status, 0, cureTurn); } - // Set summon data fields - if (!enemyPokemon.summonData) { - enemyPokemon.summonData = new PokemonSummonData(); - } - // Set ability if (!isNullOrUndefined(config.abilityIndex)) { enemyPokemon.abilityIndex = config.abilityIndex; @@ -390,14 +385,11 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig): } } - // mysteryEncounterBattleEffects will only be used IFF MYSTERY_ENCOUNTER_POST_SUMMON tag is applied + // mysteryEncounterBattleEffects will only be used if MYSTERY_ENCOUNTER_POST_SUMMON tag is applied if (config.mysteryEncounterBattleEffects) { enemyPokemon.mysteryEncounterBattleEffects = config.mysteryEncounterBattleEffects; } - // Requires re-priming summon data to update everything properly - enemyPokemon.primeSummonData(enemyPokemon.summonData); - if (enemyPokemon.isShiny() && !enemyPokemon["shinySparkle"]) { enemyPokemon.initShinySparkle(); } diff --git a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts index ed94a46ac18..a6a87b4ab9a 100644 --- a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts @@ -1031,9 +1031,6 @@ export function applyAbilityOverrideToPokemon(pokemon: Pokemon, ability: Abiliti } pokemon.fusionCustomPokemonData.ability = ability; } else { - if (!pokemon.customPokemonData) { - pokemon.customPokemonData = new CustomPokemonData(); - } pokemon.customPokemonData.ability = ability; } } diff --git a/src/data/mystery-encounters/utils/encounter-transformation-sequence.ts b/src/data/mystery-encounters/utils/encounter-transformation-sequence.ts index 578c2efefdb..ebef47eac2d 100644 --- a/src/data/mystery-encounters/utils/encounter-transformation-sequence.ts +++ b/src/data/mystery-encounters/utils/encounter-transformation-sequence.ts @@ -88,7 +88,7 @@ export function doPokemonTransformationSequence( sprite.setPipelineData("shiny", previousPokemon.shiny); sprite.setPipelineData("variant", previousPokemon.variant); ["spriteColors", "fusionSpriteColors"].map(k => { - if (previousPokemon.summonData?.speciesForm) { + if (previousPokemon.summonData.speciesForm) { k += "Base"; } sprite.pipelineData[k] = previousPokemon.getSprite().pipelineData[k]; @@ -108,7 +108,7 @@ export function doPokemonTransformationSequence( sprite.setPipelineData("shiny", transformPokemon.shiny); sprite.setPipelineData("variant", transformPokemon.variant); ["spriteColors", "fusionSpriteColors"].map(k => { - if (transformPokemon.summonData?.speciesForm) { + if (transformPokemon.summonData.speciesForm) { k += "Base"; } sprite.pipelineData[k] = transformPokemon.getSprite().pipelineData[k]; diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index 5a9a6ee9b3d..59167ba47f6 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -33,6 +33,7 @@ import { SpeciesFormKey } from "#enums/species-form-key"; import { starterPassiveAbilities } from "#app/data/balance/passives"; import { loadPokemonVariantAssets } from "#app/sprites/pokemon-sprite"; import { hasExpSprite } from "#app/sprites/sprite-utils"; +import { Gender } from "./gender"; export enum Region { NORMAL, @@ -485,10 +486,10 @@ export abstract class PokemonSpeciesForm { break; case Species.ZACIAN: case Species.ZAMAZENTA: + // biome-ignore lint/suspicious/noFallthroughSwitchClause: Falls through if (formSpriteKey.startsWith("behemoth")) { formSpriteKey = "crowned"; } - // biome-ignore lint/suspicious/no-fallthrough: Falls through default: ret += `-${formSpriteKey}`; break; @@ -749,7 +750,7 @@ export abstract class PokemonSpeciesForm { let paletteColors: Map = new Map(); const originalRandom = Math.random; - Math.random = () => Phaser.Math.RND.realInRange(0, 1); + Math.random = Phaser.Math.RND.frac; globalScene.executeWithSeedOffset( () => { @@ -879,6 +880,21 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali return this.name; } + /** + * Pick and return a random {@linkcode Gender} for a {@linkcode Pokemon}. + * @returns A randomly rolled gender based on this Species' {@linkcode malePercent}. + */ + generateGender(): Gender { + if (isNullOrUndefined(this.malePercent)) { + return Gender.GENDERLESS; + } + + if (Phaser.Math.RND.realInRange(0, 1) <= this.malePercent) { + return Gender.MALE; + } + return Gender.FEMALE; + } + /** * Find the name of species with proper attachments for regionals and separate starter forms (Floette, Ursaluna) * @returns a string with the region name or other form name attached diff --git a/src/enums/biome.ts b/src/enums/biome.ts index bb9eaf454cc..7284528767d 100644 --- a/src/enums/biome.ts +++ b/src/enums/biome.ts @@ -1,4 +1,5 @@ export enum Biome { + // TODO: Should -1 be part of the enum signature (for "unknown place") TOWN, PLAINS, GRASS, diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 0c412e73b52..b9c64ad071c 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -124,6 +124,7 @@ import { TarShotTag, AutotomizedTag, PowerTrickTag, + loadBattlerTag, type GrudgeTag, } from "../data/battler-tags"; import { WeatherType } from "#enums/weather-type"; @@ -305,6 +306,12 @@ type getBaseDamageParams = Omit type getAttackDamageParams = Omit; export default abstract class Pokemon extends Phaser.GameObjects.Container { + /** + * This pokemon's {@link https://bulbapedia.bulbagarden.net/wiki/Personality_value | Personality value/PID}, + * used to determine various parameters of this Pokemon. + * Represented as a random 32-bit unsigned integer. + * TODO: Stop treating this like a unique ID and stop treating 0 as no pokemon + */ public id: number; public name: string; public nickname: string; @@ -334,7 +341,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { public luck: number; public pauseEvolutions: boolean; public pokerus: boolean; - public switchOutStatus: boolean; + public switchOutStatus = false; public evoCounter: number; public teraType: PokemonType; public isTerastallized: boolean; @@ -350,13 +357,23 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { public fusionCustomPokemonData: CustomPokemonData | null; public fusionTeraType: PokemonType; - private summonDataPrimer: PokemonSummonData | null; + public customPokemonData: CustomPokemonData = new CustomPokemonData(); - public summonData: PokemonSummonData; - public battleData: PokemonBattleData; - public battleSummonData: PokemonBattleSummonData; - public turnData: PokemonTurnData; - public customPokemonData: CustomPokemonData; + /* Pokemon data types, in vaguely decreasing order of precedence */ + + /** + * Data that resets only on *battle* end (hit count, harvest berries, etc.) + * Kept between waves. + */ + public battleData: PokemonBattleData = new PokemonBattleData(); + /** Data that resets on switch or battle end (stat stages, battler tags, etc.) */ + public summonData: PokemonSummonData = new PokemonSummonData(); + /** Similar to {@linkcode PokemonSummonData}, but is reset on reload (not saved to file). */ + public tempSummonData: PokemonTempSummonData = new PokemonTempSummonData(); + /** Wave data correponding to moves/ability information revealed */ + public waveData: PokemonWaveData = new PokemonWaveData(); + /** Per-turn data like hit count & flinch tracking */ + public turnData: PokemonTurnData = new PokemonTurnData(); /** Used by Mystery Encounters to execute pokemon-specific logic (such as stat boosts) at start of battle */ public mysteryEncounterBattleEffects?: (pokemon: Pokemon) => void; @@ -370,6 +387,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { private shinySparkle: Phaser.GameObjects.Sprite; + // TODO: Rework this eventually constructor( x: number, y: number, @@ -390,38 +408,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { throw `Cannot create a player Pokemon for species '${species.getName(formIndex)}'`; } - const hiddenAbilityChance = new NumberHolder( - BASE_HIDDEN_ABILITY_CHANCE, - ); - if (!this.hasTrainer()) { - globalScene.applyModifiers( - HiddenAbilityRateBoosterModifier, - true, - hiddenAbilityChance, - ); - } - this.species = species; this.pokeball = dataSource?.pokeball || PokeballType.POKEBALL; this.level = level; - this.switchOutStatus = false; - // Determine the ability index - if (abilityIndex !== undefined) { - this.abilityIndex = abilityIndex; // Use the provided ability index if it is defined - } else { - // If abilityIndex is not provided, determine it based on species and hidden ability - const hasHiddenAbility = !randSeedInt(hiddenAbilityChance.value); - const randAbilityIndex = randSeedInt(2); - if (species.abilityHidden && hasHiddenAbility) { - // If the species has a hidden ability and the hidden ability is present - this.abilityIndex = 2; - } else { - // If there is no hidden ability or species does not have a hidden ability - this.abilityIndex = - species.ability2 !== species.ability1 ? randAbilityIndex : 0; // Use random ability index if species has a second ability, otherwise use 0 - } - } + this.abilityIndex = abilityIndex ?? this.generateAbilityIndex() + if (formIndex !== undefined) { this.formIndex = formIndex; } @@ -437,6 +429,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.exp = dataSource?.exp || getLevelTotalExp(this.level, species.growthRate); this.levelExp = dataSource?.levelExp || 0; + if (dataSource) { this.id = dataSource.id; this.hp = dataSource.hp; @@ -512,8 +505,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.variant = this.shiny ? this.generateShinyVariant() : 0; } - this.customPokemonData = new CustomPokemonData(); - if (nature !== undefined) { this.setNature(nature); } else { @@ -554,6 +545,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.stellarTypesBoosted = []; } + this.summonData = new PokemonSummonData(dataSource?.summonData); + this.battleData = new PokemonBattleData(dataSource?.battleData); + this.generateName(); if (!species.isObtainable()) { @@ -563,14 +557,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (!dataSource) { this.calculateStats(); } + } /** * @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.summonData?.illusion) ? this.summonData?.illusion.basePokemon!.name : this.name; - const nickname: string = (!useIllusion && !!this.summonData?.illusion) ? this.summonData?.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))); @@ -584,7 +579,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { getPokeball(useIllusion = false){ if(useIllusion){ - return this.summonData?.illusion?.pokeball ?? this.pokeball + return this.summonData.illusion?.pokeball ?? this.pokeball } else { return this.pokeball } @@ -679,9 +674,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } /** - * Checks if the pokemon is allowed in battle (ie: not fainted, and allowed under any active challenges). - * @param onField `true` to also check if the pokemon is currently on the field, defaults to `false` - * @returns `true` if the pokemon is "active". Returns `false` if there is no active {@linkcode BattleScene} + * Checks if this {@linkcode Pokemon} is allowed in battle (ie: not fainted, and allowed under any active challenges). + * @param onField `true` to also check if the pokemon is currently on the field; default `false` + * @returns `true` if the pokemon is "active", as described above. + * Returns `false` if there is no active {@linkcode BattleScene} or the pokemon is disallowed. */ public isActive(onField = false): boolean { if (!globalScene) { @@ -723,11 +719,38 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } } + /** Generate `abilityIndex` based on species and hidden ability if not pre-defined. */ + private generateAbilityIndex(): number { + + // Roll for hidden ability chance, applying any ability charms for enemy mons + const hiddenAbilityChance = new NumberHolder( + BASE_HIDDEN_ABILITY_CHANCE, + ); + if (!this.hasTrainer()) { + globalScene.applyModifiers( + HiddenAbilityRateBoosterModifier, + true, + hiddenAbilityChance, + ); + } + + // If the roll succeeded and we have one, use HA; otherwise pick a random ability + const hasHiddenAbility = !randSeedInt(hiddenAbilityChance.value); + if (this.species.abilityHidden && hasHiddenAbility) { + return 2; + } + + // only use random ability if species has a second ability + return this.species.ability2 !== this.species.ability1 ? randSeedInt(2) : 0; + } + + + /** * Generate an illusion of the last pokemon in the party, as other wild pokemon in the area. */ setIllusion(pokemon: Pokemon): boolean { - if(!!this.summonData?.illusion){ + if (this.summonData.illusion) { this.breakIllusion(); } if (this.hasTrainer()) { @@ -787,15 +810,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } breakIllusion(): boolean { - if (!this.summonData?.illusion) { + if (!this.summonData.illusion) { return false; } else { - 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.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; } if (this.isOnField()) { @@ -825,13 +848,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const loadPromises: Promise[] = []; // Assets for moves loadPromises.push(loadMoveAnimations(this.getMoveset().map(m => m.getMove().id))); - + // Load the assets for the species form - const formIndex = !!this.summonData?.illusion && useIllusion ? this.summonData?.illusion.formIndex : this.formIndex; + const formIndex = useIllusion && this.summonData.illusion ? this.summonData.illusion.formIndex : this.formIndex; loadPromises.push( this.getSpeciesForm(false, useIllusion).loadAssets( - this.getGender(useIllusion) === Gender.FEMALE, - formIndex, + this.getGender(useIllusion) === Gender.FEMALE, + formIndex, this.isShiny(useIllusion), this.getVariant(useIllusion) ), @@ -844,13 +867,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { ); } if (this.getFusionSpeciesForm()) { - 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; + const fusionFormIndex = 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(this.getFusionSpeciesForm(false, useIllusion).loadAssets( - this.getFusionGender(false, useIllusion) === Gender.FEMALE, - fusionFormIndex, - fusionShiny, + this.getFusionGender(false, useIllusion) === Gender.FEMALE, + fusionFormIndex, + fusionShiny, fusionVariant )); globalScene.loadPokemonAtlas( @@ -904,7 +927,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { // update the fusion palette this.updateFusionPalette(); - if (this.summonData?.speciesForm) { + if (this.summonData.speciesForm) { this.updateFusionPalette(true); } } @@ -1014,11 +1037,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } getSpriteId(ignoreOverride?: boolean): string { - const formIndex: integer = !!this.summonData?.illusion ? this.summonData?.illusion.formIndex! : this.formIndex; + const formIndex = this.summonData.illusion?.formIndex ?? this.formIndex; return this.getSpeciesForm(ignoreOverride, true).getSpriteId( - this.getGender(ignoreOverride, true) === Gender.FEMALE, - formIndex, - this.shiny, + this.getGender(ignoreOverride, true) === Gender.FEMALE, + formIndex, + this.shiny, this.variant ); } @@ -1028,13 +1051,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { back = this.isPlayer(); } - const formIndex: integer = !!this.summonData?.illusion ? this.summonData?.illusion.formIndex! : this.formIndex; + const formIndex = this.summonData.illusion?.formIndex ?? this.formIndex; return this.getSpeciesForm(ignoreOverride, true).getSpriteId( - this.getGender(ignoreOverride, true) === Gender.FEMALE, - formIndex, - this.shiny, - this.variant, + this.getGender(ignoreOverride, true) === Gender.FEMALE, + formIndex, + this.shiny, + this.variant, back ); } @@ -1043,8 +1066,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return this.getSpeciesForm(ignoreOverride, false).getSpriteKey( this.getGender(ignoreOverride) === Gender.FEMALE, this.formIndex, - this.summonData?.illusion?.basePokemon.shiny ?? this.shiny, - this.summonData?.illusion?.basePokemon.variant ?? this.variant + this.summonData.illusion?.basePokemon.shiny ?? this.shiny, + this.summonData.illusion?.basePokemon.variant ?? this.variant ); } @@ -1053,11 +1076,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } getFusionSpriteId(ignoreOverride?: boolean): string { - const fusionFormIndex: integer = !!this.summonData?.illusion ? this.summonData?.illusion.fusionFormIndex! : this.fusionFormIndex; + const fusionFormIndex = this.summonData.illusion?.fusionFormIndex ?? this.fusionFormIndex; return this.getFusionSpeciesForm(ignoreOverride, true).getSpriteId( - this.getFusionGender(ignoreOverride, true) === Gender.FEMALE, - fusionFormIndex, - this.fusionShiny, + this.getFusionGender(ignoreOverride, true) === Gender.FEMALE, + fusionFormIndex, + this.fusionShiny, this.fusionVariant ); } @@ -1067,13 +1090,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { back = this.isPlayer(); } - const fusionFormIndex: integer = !!this.summonData?.illusion ? this.summonData?.illusion.fusionFormIndex! : this.fusionFormIndex; + const fusionFormIndex = this.summonData.illusion?.fusionFormIndex ?? this.fusionFormIndex; return this.getFusionSpeciesForm(ignoreOverride, true).getSpriteId( - this.getFusionGender(ignoreOverride, true) === Gender.FEMALE, - fusionFormIndex, - this.fusionShiny, - this.fusionVariant, + this.getFusionGender(ignoreOverride, true) === Gender.FEMALE, + fusionFormIndex, + this.fusionShiny, + this.fusionVariant, back ); } @@ -1093,52 +1116,56 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } getIconAtlasKey(ignoreOverride?: boolean): string { - const formIndex: integer = !!this.summonData?.illusion ? this.summonData?.illusion.formIndex : this.formIndex; + const formIndex = this.summonData.illusion?.formIndex ?? this.formIndex; return this.getSpeciesForm(ignoreOverride, true).getIconAtlasKey( - formIndex, - this.shiny, + formIndex, + this.shiny, this.variant ); } getFusionIconAtlasKey(ignoreOverride?: boolean): string { return this.getFusionSpeciesForm(ignoreOverride, true).getIconAtlasKey( - this.fusionFormIndex, - this.fusionShiny, + this.fusionFormIndex, + this.fusionShiny, this.fusionVariant ); } getIconId(ignoreOverride?: boolean): string { - const formIndex: integer = !!this.summonData?.illusion ? this.summonData?.illusion.formIndex : this.formIndex; + const formIndex = this.summonData.illusion?.formIndex ?? this.formIndex; return this.getSpeciesForm(ignoreOverride, true).getIconId( - this.getGender(ignoreOverride, true) === Gender.FEMALE, - formIndex, - this.shiny, + this.getGender(ignoreOverride, true) === Gender.FEMALE, + formIndex, + this.shiny, this.variant ); } getFusionIconId(ignoreOverride?: boolean): string { - const fusionFormIndex: integer = !!this.summonData?.illusion ? this.summonData?.illusion.fusionFormIndex! : this.fusionFormIndex; + const fusionFormIndex = this.summonData.illusion?.fusionFormIndex ?? this.fusionFormIndex; return this.getFusionSpeciesForm(ignoreOverride, true).getIconId( - this.getFusionGender(ignoreOverride, true) === Gender.FEMALE, - fusionFormIndex, - this.fusionShiny, + this.getFusionGender(ignoreOverride, true) === Gender.FEMALE, + fusionFormIndex, + this.fusionShiny, this.fusionVariant ); } /** - * @param {boolean} useIllusion - Whether we want the speciesForm of the illusion or not. + * Get this {@linkcode Pokemon}'s {@linkcode PokemonSpeciesForm}. + * @param ignoreOverride - Whether to ignore overridden species from {@linkcode Moves.TRANSFORM}, default `false`. + * This overrides `useIllusion` if `true`. + * @param useIllusion - `true` to use the speciesForm of the illusion; default `false`. */ - getSpeciesForm(ignoreOverride?: boolean, useIllusion: boolean = false): PokemonSpeciesForm { - const species: PokemonSpecies = useIllusion && !!this.summonData?.illusion ? getPokemonSpecies(this.summonData?.illusion.species) : this.species; - const formIndex: integer = useIllusion && !!this.summonData?.illusion ? this.summonData?.illusion.formIndex : this.formIndex; - - if (!ignoreOverride && this.summonData?.speciesForm) { + getSpeciesForm(ignoreOverride: boolean = false, useIllusion: boolean = false): PokemonSpeciesForm { + if (!ignoreOverride && this.summonData.speciesForm) { return this.summonData.speciesForm; } + + const species: PokemonSpecies = useIllusion && this.summonData.illusion ? getPokemonSpecies(this.summonData.illusion.species) : this.species; + const formIndex = useIllusion && this.summonData.illusion ? this.summonData.illusion.formIndex : this.formIndex; + if (species.forms && species.forms.length > 0) { return species.forms[formIndex]; } @@ -1150,14 +1177,14 @@ 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.summonData?.illusion ? this.summonData?.illusion.fusionSpecies! : this.fusionSpecies!; - const fusionFormIndex: integer = useIllusion && !!this.summonData?.illusion ? this.summonData?.illusion.fusionFormIndex! : this.fusionFormIndex; + const fusionSpecies: PokemonSpecies = useIllusion && this.summonData.illusion ? this.summonData.illusion.fusionSpecies! : this.fusionSpecies!; + const fusionFormIndex = useIllusion && this.summonData.illusion ? this.summonData.illusion.fusionFormIndex! : this.fusionFormIndex; - if (!ignoreOverride && this.summonData?.speciesForm) { + if (!ignoreOverride && this.summonData.fusionSpeciesForm) { return this.summonData.fusionSpeciesForm; } if ( - !fusionSpecies?.forms?.length || + !fusionSpecies?.forms?.length || fusionFormIndex >= fusionSpecies?.forms.length ) { return fusionSpecies; @@ -1185,12 +1212,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { formKey === "ruchbah-starmobile" || formKey === "caph-starmobile" ) { + // G-Max and starmobiles have flat 1.5x scale return 1.5; } - if (this.customPokemonData.spriteScale > 0) { - return this.customPokemonData.spriteScale; + + // TODO: Rather than using -1 as a default... why don't we just change it to 1???????? + if (this.customPokemonData.spriteScale <= 0) { + return 1; } - return 1; + return this.customPokemonData.spriteScale; } /** Resets the pokemon's field sprite properties, including position, alpha, and scale */ @@ -1384,12 +1414,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } /** - * Retrieves the entire set of stats of the {@linkcode Pokemon}. - * @param bypassSummonData prefer actual stats (`true` by default) or in-battle overriden stats (`false`) - * @returns the numeric values of the {@linkcode Pokemon}'s stats + * Retrieves the entire set of stats of this {@linkcode Pokemon}. + * @param bypassSummonData - whether to use actual stats or in-battle overriden stats from Transform; default `true` + * @returns the numeric values of this {@linkcode Pokemon}'s stats */ getStats(bypassSummonData = true): number[] { - if (!bypassSummonData && this.summonData?.stats) { + if (!bypassSummonData && this.summonData.stats) { return this.summonData.stats; } return this.stats; @@ -1404,7 +1434,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { getStat(stat: PermanentStat, bypassSummonData = true): number { if ( !bypassSummonData && - this.summonData && this.summonData.stats[stat] !== 0 ) { return this.summonData.stats[stat]; @@ -1421,12 +1450,14 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param bypassSummonData write to actual stats (`true` by default) or in-battle overridden stats (`false`) */ setStat(stat: PermanentStat, value: number, bypassSummonData = true): void { - if (value >= 0) { - if (!bypassSummonData && this.summonData) { - this.summonData.stats[stat] = value; - } else { - this.stats[stat] = value; - } + if (value < 0) { + return; + } + + if (!bypassSummonData) { + this.summonData.stats[stat] = value; + } else { + this.stats[stat] = value; } } @@ -1455,20 +1486,17 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param value the desired numeric value */ setStatStage(stat: BattleStat, value: number): void { - if (this.summonData) { - if (value >= -6) { - this.summonData.statStages[stat - 1] = Math.min(value, 6); - } else { - this.summonData.statStages[stat - 1] = Math.max(value, -6); - } + if (value >= -6) { + this.summonData.statStages[stat - 1] = Math.min(value, 6); + } else { + this.summonData.statStages[stat - 1] = Math.max(value, -6); } } /** * Calculate the critical-hit stage of a move used against this pokemon by * the given source - * - * @param source - The {@linkcode Pokemon} who using the move + * @param source - The {@linkcode Pokemon} using the move * @param move - The {@linkcode Move} being used * @returns The final critical-hit stage value */ @@ -1826,9 +1854,9 @@ 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.summonData?.illusion) { - return this.summonData?.illusion.gender!; - } else if (!ignoreOverride && this.summonData?.gender !== undefined) { + if (useIllusion && this.summonData.illusion) { + return this.summonData.illusion.gender; + } else if (!ignoreOverride && !isNullOrUndefined(this.summonData.gender)) { return this.summonData.gender; } return this.gender; @@ -1838,9 +1866,9 @@ 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.summonData?.illusion) { - return this.summonData?.illusion.fusionGender!; - } else if (!ignoreOverride && this.summonData?.fusionGender !== undefined) { + if (useIllusion && this.summonData.illusion?.fusionGender) { + return this.summonData.illusion.fusionGender; + } else if (!ignoreOverride && !isNullOrUndefined(this.summonData.fusionGender)) { return this.summonData.fusionGender; } return this.fusionGender; @@ -1850,21 +1878,21 @@ 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.summonData?.illusion) { - return this.summonData?.illusion.basePokemon?.shiny || (!!this.summonData?.illusion.fusionSpecies && this.summonData?.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); } } /** - * + * * @param useIllusion - Whether we want the fake or real shininess (illusion ability). * @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.summonData?.illusion) { - return this.isFusion(false) && this.summonData?.illusion.basePokemon.shiny && this.summonData?.illusion.basePokemon.fusionShiny; + if (!useIllusion && this.summonData.illusion?.basePokemon) { + return this.isFusion(false) && this.summonData.illusion.basePokemon.shiny && this.summonData.illusion.basePokemon.fusionShiny; } else { return this.isFusion(useIllusion) && this.shiny && this.fusionShiny; } @@ -1874,25 +1902,23 @@ 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.summonData?.illusion) { - return !this.isFusion(false) - ? this.summonData?.illusion.basePokemon!.variant + if (!useIllusion && this.summonData.illusion) { + return !this.isFusion(false) + ? this.summonData.illusion.basePokemon!.variant : Math.max(this.variant, this.fusionVariant) as Variant; } else { - return !this.isFusion(true) - ? this.variant + return !this.isFusion(true) + ? this.variant : Math.max(this.variant, this.fusionVariant) as Variant; } } getBaseVariant(doubleShiny: boolean): Variant { if (doubleShiny) { - return !!this.summonData?.illusion - ? this.summonData?.illusion.basePokemon!.variant - : this.variant; - } else { - return this.getVariant(); + return this.summonData.illusion?.basePokemon?.variant ?? this.variant; } + + return this.getVariant(); } getLuck(): number { @@ -1900,19 +1926,18 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } isFusion(useIllusion: boolean = false): boolean { - if (useIllusion && !!this.summonData?.illusion) { - return !!this.summonData?.illusion.fusionSpecies; - } else { - return !!this.fusionSpecies; + if (useIllusion && this.summonData.illusion) { + return !!this.summonData.illusion.fusionSpecies; } + return !!this.fusionSpecies; } /** * @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.summonData?.illusion && this.summonData?.illusion.basePokemon) - ? this.summonData?.illusion.basePokemon.name + return (!useIllusion && this.summonData.illusion?.basePokemon) + ? this.summonData.illusion.basePokemon.name : this.name; } @@ -1946,7 +1971,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { getMoveset(ignoreOverride?: boolean): PokemonMove[] { const ret = - !ignoreOverride && this.summonData?.moveset + !ignoreOverride && this.summonData.moveset ? this.summonData.moveset : this.moveset; @@ -2032,9 +2057,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @returns array of {@linkcode PokemonType} */ public getTypes( - includeTeraType = false, - forDefend: boolean = false, - ignoreOverride?: boolean, + includeTeraType = false, + forDefend: boolean = false, + ignoreOverride?: boolean, useIllusion: boolean | "AUTO" = "AUTO" ): PokemonType[] { const types: PokemonType[] = []; @@ -2053,10 +2078,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const doIllusion: boolean = (useIllusion === "AUTO") ? !forDefend : useIllusion; if ( - !ignoreOverride && - this.summonData?.types && - this.summonData.types.length > 0 && - (!this.summonData?.illusion || !doIllusion) + !ignoreOverride && + this.summonData.types && + this.summonData.types.length > 0 && + (!this.summonData.illusion || !doIllusion) ) { this.summonData.types.forEach(t => types.push(t)); } else { @@ -2137,10 +2162,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } } - // the type added to Pokemon from moves like Forest's Curse or Trick Or Treat + // check type added to Pokemon from moves like Forest's Curse or Trick Or Treat if ( !ignoreOverride && - this.summonData && this.summonData.addedType && !types.includes(this.summonData.addedType) ) { @@ -2183,7 +2207,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @returns The non-passive {@linkcode Ability} of the pokemon */ public getAbility(ignoreOverride = false): Ability { - if (!ignoreOverride && this.summonData?.ability) { + if (!ignoreOverride && this.summonData.ability) { return allAbilities[this.summonData.ability]; } if (Overrides.ABILITY_OVERRIDE && this.isPlayer()) { @@ -2249,8 +2273,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * Accounts for all the various effects which can affect whether an ability will be present or * in effect, and both passive and non-passive. * @param attrType - {@linkcode AbAttr} The ability attribute to check for. - * @param canApply - If `false`, it doesn't check whether the ability is currently active; Default `true` - * @param ignoreOverride - If `true`, it ignores ability changing effects; Default `false` + * @param canApply - Whether to check if the ability is currently active; Default `true` + * @param ignoreOverride - Whether to ignore ability changing effects; Default `false` * @returns An array of all the ability attributes on this ability. */ public getAbilityAttrs( @@ -2362,7 +2386,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return false; } if ( - this.summonData?.abilitySuppressed && + this.summonData.abilitySuppressed && ability.isSuppressable ) { return false; @@ -2403,15 +2427,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * Checks whether a pokemon has the specified ability and it's in effect. Accounts for all the various * effects which can affect whether an ability will be present or in effect, and both passive and * non-passive. This is the primary way to check whether a pokemon has a particular ability. - * @param {Abilities} ability The ability to check for - * @param {boolean} canApply If false, it doesn't check whether the ability is currently active - * @param {boolean} ignoreOverride If true, it ignores ability changing effects - * @returns {boolean} Whether the ability is present and active + * @param ability The ability to check for + * @param canApply - Whether to check if the ability is currently active; default `true` + * @param ignoreOverride Whether to ignore ability changing effects; default `false` + * @returns `true` if the ability is present and active */ public hasAbility( ability: Abilities, canApply = true, - ignoreOverride?: boolean, + ignoreOverride = false, ): boolean { if ( this.getAbility(ignoreOverride).id === ability && @@ -2434,15 +2458,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * Accounts for all the various effects which can affect whether an ability will be present or * in effect, and both passive and non-passive. This is one of the two primary ways to check * whether a pokemon has a particular ability. - * @param {AbAttr} attrType The ability attribute to check for - * @param {boolean} canApply If false, it doesn't check whether the ability is currently active - * @param {boolean} ignoreOverride If true, it ignores ability changing effects - * @returns {boolean} Whether an ability with that attribute is present and active + * @param attrType The {@link AbAttr | ability attribute} to check for + * @param canApply - Whether to check if the ability is currently active; default `true` + * @param ignoreOverride Whether to ignore ability changing effects; default `false` + * @returns `true` if an ability with the given {@linkcode AbAttr} is present and active */ public hasAbilityWithAttr( attrType: Constructor, canApply = true, - ignoreOverride?: boolean, + ignoreOverride = false, ): boolean { if ( (!canApply || this.canApplyAbility()) && @@ -2641,14 +2665,14 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const moveType = source.getMoveType(move); const typeMultiplier = new NumberHolder( - move.category !== MoveCategory.STATUS || + move.category !== MoveCategory.STATUS || move.hasAttr(RespectAttackTypeImmunityAttr) ? this.getAttackTypeEffectiveness( - moveType, - source, - false, - simulated, - move, + moveType, + source, + false, + simulated, + move, useIllusion ) : 1); @@ -2759,11 +2783,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @returns a multiplier for the type effectiveness */ getAttackTypeEffectiveness( - moveType: PokemonType, - source?: Pokemon, - ignoreStrongWinds: boolean = false, - simulated: boolean = true, - move?: Move, + moveType: PokemonType, + source?: Pokemon, + ignoreStrongWinds: boolean = false, + simulated: boolean = true, + move?: Move, useIllusion: boolean = false ): TypeDamageMultiplier { if (moveType === PokemonType.STELLAR) { @@ -3143,7 +3167,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } const move = new PokemonMove(moveId); this.moveset[moveIndex] = move; - if (this.summonData?.moveset) { + if (this.summonData.moveset) { this.summonData.moveset[moveIndex] = move; } } @@ -3884,7 +3908,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { getOpponent(targetIndex: number): Pokemon | null { const ret = this.getOpponents()[targetIndex]; - if (ret.summonData) { + if (ret.summonData) { // TODO: why does this check for summonData and can we remove it? return ret; } return null; @@ -3892,7 +3916,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { /** * Returns the pokemon that oppose this one and are active - * + * * @param onField - whether to also check if the pokemon is currently on the field (defaults to true) */ getOpponents(onField = true): Pokemon[] { @@ -4202,12 +4226,12 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { /** Determine the STAB multiplier for a move used against this pokemon. - * + * * @param source - The attacking {@linkcode Pokemon} * @param move - The {@linkcode Move} used in the attack * @param ignoreSourceAbility - If `true`, ignores the attacking Pokemon's ability effects * @param simulated - If `true`, suppresses changes to game state during the calculation - * + * * @returns The STAB multiplier for the move used against this Pokemon */ calculateStabMultiplier(source: Pokemon, move: Move, ignoreSourceAbility: boolean, simulated: boolean): number { @@ -4602,7 +4626,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { }; } - /** Calculate whether the given move critically hits this pokemon + /** Calculate whether the given move critically hits this pokemon * @param source - The {@linkcode Pokemon} using the move * @param move - The {@linkcode Move} being used * @param simulated - If `true`, suppresses changes to game state during calculation (defaults to `true`) @@ -4631,16 +4655,16 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { applyAbAttrs(BlockCritAbAttr, this, null, simulated, isCritical); return isCritical.value; - + } /** * Called by damageAndUpdate() * @param damage integer * @param ignoreSegments boolean, not currently used - * @param preventEndure used to update damage if endure or sturdy - * @param ignoreFaintPhase flag on wheter to add FaintPhase if pokemon after applying damage faints - * @returns integer representing damage + * @param preventEndure used to update damage if endure or sturdy + * @param ignoreFaintPhas flag on whether to add FaintPhase if pokemon after applying damage faints + * @returns integer representing damage dealt */ damage( damage: number, @@ -4653,6 +4677,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } const surviveDamage = new BooleanHolder(false); + // check for endure and other abilities that would prevent us from death if (!preventEndure && this.hp - damage <= 0) { if (this.hp >= 1 && this.getTag(BattlerTagType.ENDURING)) { surviveDamage.value = this.lapseTag(BattlerTagType.ENDURING); @@ -4696,7 +4721,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { /** * Given the damage, adds a new DamagePhase and update HP values, etc. - * + * * Checks for 'Indirect' HitResults to account for Endure/Reviver Seed applying correctly * @param damage integer - passed to damage() * @param result an enum if it's super effective, not very, etc. @@ -4708,25 +4733,25 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { */ damageAndUpdate(damage: number, { - result = HitResult.EFFECTIVE, - isCritical = false, - ignoreSegments = false, - ignoreFaintPhase = false, + result = HitResult.EFFECTIVE, + isCritical = false, + ignoreSegments = false, + ignoreFaintPhase = false, source = undefined, }: { - result?: DamageResult, - isCritical?: boolean, - ignoreSegments?: boolean, - ignoreFaintPhase?: boolean, + result?: DamageResult, + isCritical?: boolean, + ignoreSegments?: boolean, + ignoreFaintPhase?: boolean, source?: Pokemon, } = {} ): number { const isIndirectDamage = [ HitResult.INDIRECT, HitResult.INDIRECT_KO ].includes(result); const damagePhase = new DamageAnimPhase( - this.getBattlerIndex(), - damage, - result as DamageResult, + this.getBattlerIndex(), + damage, + result as DamageResult, isCritical ); globalScene.unshiftPhase(damagePhase); @@ -4862,51 +4887,51 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { getTag(tagType: BattlerTagType.GRUDGE): GrudgeTag | nil; /** @overload */ - getTag(tagType: BattlerTagType): BattlerTag | nil; + getTag(tagType: BattlerTagType): BattlerTag | undefined; /** @overload */ - getTag(tagType: Constructor): T | nil; + getTag(tagType: Constructor): T | undefined; - getTag(tagType: BattlerTagType | Constructor): BattlerTag | nil { - if (!this.summonData) { - return null; - } + getTag(tagType: BattlerTagType | Constructor): BattlerTag | undefined { return tagType instanceof Function ? this.summonData.tags.find(t => t instanceof tagType) : this.summonData.tags.find(t => t.tagType === tagType); } findTag(tagFilter: (tag: BattlerTag) => boolean) { - if (!this.summonData) { - return null; - } return this.summonData.tags.find(t => tagFilter(t)); } findTags(tagFilter: (tag: BattlerTag) => boolean): BattlerTag[] { - if (!this.summonData) { - return []; - } return this.summonData.tags.filter(t => tagFilter(t)); } + /** + * Tick down the first {@linkcode BattlerTag} found matching the given {@linkcode BattlerTagType}, + * removing it if its duration goes below 0. + * @param tagType the {@linkcode BattlerTagType} to check against + * @returns `true` if the tag was present + */ lapseTag(tagType: BattlerTagType): boolean { - if (!this.summonData) { - return false; - } const tags = this.summonData.tags; const tag = tags.find(t => t.tagType === tagType); - if (tag && !tag.lapse(this, BattlerTagLapseType.CUSTOM)) { + if (!tag) { + return false + } + + if (!tag.lapse(this, BattlerTagLapseType.CUSTOM)) { tag.onRemove(this); tags.splice(tags.indexOf(tag), 1); } - return !!tag; + return true } + /** + * Tick down all {@linkcode BattlerTags} matching the given {@linkcode BattlerTagLapseType}, + * removing any whose durations fall below 0. + * @param tagType the {@linkcode BattlerTagLapseType} to tick down + */ lapseTags(lapseType: BattlerTagLapseType): void { - if (!this.summonData) { - return; - } const tags = this.summonData.tags; tags .filter( @@ -4921,23 +4946,24 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { }); } - removeTag(tagType: BattlerTagType): boolean { - if (!this.summonData) { - return false; - } + /** + * Remove the first tag matching the given {@linkcode BattlerTagType}. + * @param tagType the {@linkcode BattlerTagType} to search for and remove + */ + removeTag(tagType: BattlerTagType): void { const tags = this.summonData.tags; const tag = tags.find(t => t.tagType === tagType); if (tag) { tag.onRemove(this); tags.splice(tags.indexOf(tag), 1); } - return !!tag; } - findAndRemoveTags(tagFilter: (tag: BattlerTag) => boolean): boolean { - if (!this.summonData) { - return false; - } + /** + * Find and remove all {@linkcode BattlerTag}s matching the given function. + * @param tagFilter a function dictating which tags to remove + */ + findAndRemoveTags(tagFilter: (tag: BattlerTag) => boolean): void { const tags = this.summonData.tags; const tagsToRemove = tags.filter(t => tagFilter(t)); for (const tag of tagsToRemove) { @@ -4945,7 +4971,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { tag.onRemove(this); tags.splice(tags.indexOf(tag), 1); } - return true; } removeTagsBySourceId(sourceId: number): void { @@ -4953,13 +4978,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } transferTagsBySourceId(sourceId: number, newSourceId: number): void { - if (!this.summonData) { - return; - } - const tags = this.summonData.tags; - tags - .filter(t => t.sourceId === sourceId) - .forEach(t => (t.sourceId = newSourceId)); + this.summonData.tags.forEach(t => { + if (t.sourceId === sourceId) { + t.sourceId = newSourceId; + } + }) } /** @@ -5075,7 +5098,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } public getMoveHistory(): TurnMove[] { - return this.battleSummonData.moveHistory; + return this.summonData.moveHistory; } public pushMoveHistory(turnMove: TurnMove): void { @@ -5373,7 +5396,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } const message = effect && this.status?.effect === effect ? getStatusEffectOverlapText(effect ?? StatusEffect.NONE, getPokemonNameWithAffix(this)) - : i18next.t("abilityTriggers:moveImmunity", { + : i18next.t("abilityTriggers:moveImmunity", { pokemonNameWithAffix: getPokemonNameWithAffix(this), }); globalScene.queueMessage(message); @@ -5518,9 +5541,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { sourcePokemon !== this && this.isSafeguarded(sourcePokemon) ) { - if(!quiet){ + if(!quiet){ globalScene.queueMessage( - i18next.t("moveTriggers:safeguard", { targetName: getPokemonNameWithAffix(this) + i18next.t("moveTriggers:safeguard", { targetName: getPokemonNameWithAffix(this) })); } return false; @@ -5667,65 +5690,19 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return false; } - primeSummonData(summonDataPrimer: PokemonSummonData): void { - this.summonDataPrimer = summonDataPrimer; - } - - // For PreSummonAbAttr to get access to summonData - initSummondata(): void { - this.summonData = this.summonData ?? this.summonDataPrimer ?? new PokemonSummonData() - } - + /** + * Reset this Pokemon's {@linkcode PokemonSummonData | SummonData} and {@linkcode PokemonTempSummonData | TempSummonData} + * in preparation for switching pokemon, as well as removing any relevant on-switch tags. + */ resetSummonData(): void { - const illusion: IllusionData | null = this.summonData?.illusion; - if (this.summonData?.speciesForm) { + const illusion: IllusionData | null = this.summonData.illusion; + if (this.summonData.speciesForm) { this.summonData.speciesForm = null; this.updateFusionPalette(); } this.summonData = new PokemonSummonData(); + this.tempSummonData = new PokemonTempSummonData(); this.setSwitchOutStatus(false); - if (!this.battleData) { - this.resetBattleData(); - } - this.resetBattleSummonData(); - if (this.summonDataPrimer) { - for (const k of Object.keys(this.summonDataPrimer)) { - if (this.summonDataPrimer[k]) { - this.summonData[k] = this.summonDataPrimer[k]; - } - } - // If this Pokemon has a Substitute when loading in, play an animation to add its sprite - if (this.getTag(SubstituteTag)) { - globalScene.triggerPokemonBattleAnim( - this, - PokemonAnimType.SUBSTITUTE_ADD, - ); - this.getTag(SubstituteTag)!.sourceInFocus = false; - } - - // If this Pokemon has Commander and Dondozo as an active ally, hide this Pokemon's sprite. - if ( - this.hasAbilityWithAttr(CommanderAbAttr) && - globalScene.currentBattle.double && - this.getAlly()?.species.speciesId === Species.DONDOZO - ) { - this.setVisible(false); - } - this.summonDataPrimer = null; - } - this.summonData.illusion = illusion - this.updateInfo(); - } - - resetBattleData(): void { - this.battleData = new PokemonBattleData(); - } - - resetBattleSummonData(): void { - this.battleSummonData = new PokemonBattleSummonData(); - if (this.getTag(BattlerTagType.SEEDED)) { - this.lapseTag(BattlerTagType.SEEDED); - } if (globalScene) { globalScene.triggerPokemonFormChange( this, @@ -5733,6 +5710,45 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { true, ); } + + // If this Pokemon has a Substitute when loading in, play an animation to add its sprite + if (this.getTag(SubstituteTag)) { + globalScene.triggerPokemonBattleAnim( + this, + PokemonAnimType.SUBSTITUTE_ADD, + ); + this.getTag(SubstituteTag)!.sourceInFocus = false; + } + + // If this Pokemon has Commander and Dondozo as an active ally, hide this Pokemon's sprite. + if ( + this.hasAbilityWithAttr(CommanderAbAttr) && + globalScene.currentBattle.double && + this.getAlly()?.species.speciesId === Species.DONDOZO + ) { + this.setVisible(false); + } + this.summonData.illusion = illusion + this.updateInfo(); + } + + /** + * Reset a {@linkcode Pokemon}'s per-battle {@linkcode PokemonBattleData | battleData}, + * as well as any transient {@linkcode PokemonWaveData | waveData} for the current wave. + * Should be called once per arena transition (new biome/trainer battle/Mystery Encounter). + */ + resetBattleAndWaveData(): void { + this.battleData = new PokemonBattleData(); + this.resetWaveData(); + } + + /** + * Reset a {@linkcode Pokemon}'s {@linkcode PokemonWaveData | waveData}. + * Should be called upon starting a new wave in addition to whenever an arena transition occurs. + * @see {@linkcode resetBattleAndWaveData()} + */ + resetWaveData(): void { + this.waveData = new PokemonWaveData(); } resetTera(): void { @@ -5853,10 +5869,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { .filter(s => !!s) .map(s => { s.pipelineData[ - `spriteColors${ignoreOveride && this.summonData?.speciesForm ? "Base" : ""}` + `spriteColors${ignoreOveride && this.summonData.speciesForm ? "Base" : ""}` ] = []; s.pipelineData[ - `fusionSpriteColors${ignoreOveride && this.summonData?.speciesForm ? "Base" : ""}` + `fusionSpriteColors${ignoreOveride && this.summonData.speciesForm ? "Base" : ""}` ] = []; }); return; @@ -6213,10 +6229,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { .filter(s => !!s) .map(s => { s.pipelineData[ - `spriteColors${ignoreOveride && this.summonData?.speciesForm ? "Base" : ""}` + `spriteColors${ignoreOveride && this.summonData.speciesForm ? "Base" : ""}` ] = spriteColors; s.pipelineData[ - `fusionSpriteColors${ignoreOveride && this.summonData?.speciesForm ? "Base" : ""}` + `fusionSpriteColors${ignoreOveride && this.summonData.speciesForm ? "Base" : ""}` ] = fusionSpriteColors; }); @@ -6269,7 +6285,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (clearEffects) { this.destroySubstitute(); - this.resetSummonData(); // this also calls `resetBattleSummonData` + this.resetSummonData(); } if (hideInfo) { this.hideInfo(); @@ -6339,7 +6355,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { heldItem: PokemonHeldItemModifier, forBattle = true, ): boolean { - if (heldItem.pokemonId === -1 || heldItem.pokemonId === this.id) { + if (heldItem.pokemonId !== -1 && heldItem.pokemonId !== this.id) { + return false; + } + heldItem.stackCount--; if (heldItem.stackCount <= 0) { globalScene.removeModifier(heldItem, !this.isPlayer()); @@ -6347,10 +6366,23 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (forBattle) { applyPostItemLostAbAttrs(PostItemLostAbAttr, this, false); } + return true; - } else { - return false; + } + + /** + * Record a berry being eaten for ability and move triggers. + * Only tracks things that proc _every_ time a berry is eaten. + * @param berryType The type of berry being eaten. + * @param updateHarvest Whether to track the berry for harvest; default `true`. + */ + public recordEatenBerry(berryType: BerryType, updateHarvest: boolean = true) { + this.battleData.hasEatenBerry = true; + if (updateHarvest) { + // Only track for harvest if we actually consumed the berry + this.battleData.berriesEaten.push(berryType) } + this.turnData.berriesEaten.push(berryType); } } @@ -6919,6 +6951,8 @@ export class PlayerPokemon extends Pokemon { if (partyMemberIndex > fusedPartyMemberIndex) { partyMemberIndex--; } + + // combine the two mons' held items const fusedPartyMemberHeldModifiers = globalScene.findModifiers( m => m instanceof PokemonHeldItemModifier && m.pokemonId === pokemon.id, true, @@ -7232,9 +7266,9 @@ export class EnemyPokemon extends Pokemon { p.getAttackDamage({ source: this, move, - ignoreAbility: !p.battleData.abilityRevealed, + ignoreAbility: !p.waveData.abilityRevealed, ignoreSourceAbility: false, - ignoreAllyAbility: !p.getAlly()?.battleData.abilityRevealed, + ignoreAllyAbility: !p.getAlly()?.waveData.abilityRevealed, ignoreSourceAllyAbility: false, isCritical, } @@ -7296,11 +7330,18 @@ export class EnemyPokemon extends Pokemon { ) { targetScore = -20; } else if (move instanceof AttackMove) { - /** - * Attack moves are given extra multipliers to their base benefit score based on - * the move's type effectiveness against the target and whether the move is a STAB move. - */ - const effectiveness = target.getMoveEffectiveness(this, move, !target.battleData?.abilityRevealed, undefined, undefined, true); + /** + * Attack moves are given extra multipliers to their base benefit score based on + * the move's type effectiveness against the target and whether the move is a STAB move. + */ + const effectiveness = target.getMoveEffectiveness( + this, + move, + !target.waveData.abilityRevealed, + undefined, + undefined, + true); + if (target.isPlayer() !== this.isPlayer()) { targetScore *= effectiveness; if (this.isOfType(move.type)) { @@ -7743,53 +7784,131 @@ export interface AttackMoveResult { sourceBattlerIndex: BattlerIndex; } +/** + * Persistent in-battle data for a {@linkcode Pokemon}. + * Resets on switch or new battle. + */ export class PokemonSummonData { /** [Atk, Def, SpAtk, SpDef, Spd, Acc, Eva] */ public statStages: number[] = [0, 0, 0, 0, 0, 0, 0]; public moveQueue: TurnMove[] = []; public tags: BattlerTag[] = []; public abilitySuppressed = false; - public abilitiesApplied: Abilities[] = []; - public speciesForm: PokemonSpeciesForm | null; - public fusionSpeciesForm: PokemonSpeciesForm; - public ability: Abilities = Abilities.NONE; - public passiveAbility: Abilities = Abilities.NONE; - public gender: Gender; - public fusionGender: Gender; + + // Overrides for transform. + // TODO: Move these into a separate class & add rage fist hit count + public speciesForm: PokemonSpeciesForm | null = null; + public fusionSpeciesForm: PokemonSpeciesForm | null = null; + public ability: Abilities | undefined; + public passiveAbility: Abilities | undefined; + public gender: Gender | undefined; + public fusionGender: Gender | undefined; public stats: number[] = [0, 0, 0, 0, 0, 0]; - public moveset: PokemonMove[]; - public illusionBroken: boolean = false; + public moveset: PokemonMove[] | null; // If not initialized this value will not be populated from save data. public types: PokemonType[] = []; public addedType: PokemonType | null = null; + + /** Data pertaining to this pokemon's illusion. */ public illusion: IllusionData | null = null; -} + public illusionBroken: boolean = false; -export class PokemonBattleData { - /** counts the hits the pokemon received */ - public hitCount = 0; - /** used for {@linkcode Moves.RAGE_FIST} in order to save hit Counts received before Rage Fist is applied */ - public prevHitCount = 0; - public endured = false; - public berriesEaten: BerryType[] = []; - public abilitiesApplied: Abilities[] = []; - public abilityRevealed: boolean = false; -} + /** Array containing all berries eaten in the last turn; used by {@linkcode Abilities.CUD_CHEW} */ + public berriesEatenLast: BerryType[] = []; -export class PokemonBattleSummonData { - /** The number of turns the pokemon has passed since entering the battle */ - public turnCount = 1; - /** The number of turns the pokemon has passed since the start of the wave */ - public waveTurnCount = 1; - /** The list of moves the pokemon has used since entering the battle */ + /** + * An array of all moves this pokemon has used since entering the battle. + * Used for most moves and abilities that check prior move usage or copy already-used moves. + */ public moveHistory: TurnMove[] = []; + + constructor(source?: PokemonSummonData | Partial) { + if (isNullOrUndefined(source)) { + return; + } + + // TODO: Rework this into an actual generic function for use elsewhere + for (const [key, value] of Object.entries(source)) { + if (isNullOrUndefined(value) && this.hasOwnProperty(key)) { + continue; + } + + if (key === "tags") { + // load battler tags + this.tags = value.map((t: BattlerTag) => loadBattlerTag(t)); + continue; + } + this[key] = value; + } + } } + // TODO: Merge this inside `summmonData` but exclude from save if/when a save data serializer is added +export class PokemonTempSummonData { + /** + * The number of turns this pokemon has spent without switching out. + * Only currently used for positioning the battle cursor. + */ + turnCount: number = 1; + + /** + * The number of turns this pokemon has spent in the active position since the start of the wave + * without switching out. + * Reset on switch and new wave, but not stored in `SummonData` to avoid being written to the save file. + + * Used to evaluate "first turn only" conditions such as + * {@linkcode Moves.FAKE_OUT | Fake Out} and {@linkcode Moves.FIRST_IMPRESSION | First Impression}). + */ + waveTurnCount = 1; + +} + +/** + * Persistent data for a {@linkcode Pokemon}. + * Resets at the start of a new battle (but not on switch). + */ +export class PokemonBattleData { + /** Counter tracking direct hits this Pokemon has received during this battle; used for {@linkcode Moves.RAGE_FIST} */ + public hitCount = 0; + /** Whether this Pokemon has eaten a berry this battle; used for {@linkcode Moves.BELCH} */ + public hasEatenBerry: boolean = false; + /** Array containing all berries eaten and not yet recovered during this current battle; used by {@linkcode Abilities.HARVEST} */ + public berriesEaten: BerryType[] = []; + + constructor(source?: PokemonBattleData | Partial) { + if (!isNullOrUndefined(source)) { + this.hitCount = source.hitCount ?? 0; + this.hasEatenBerry = source.hasEatenBerry ?? false; + this.berriesEaten = source.berriesEaten ?? []; + } + } +} + +/** + * Temporary data for a {@linkcode Pokemon}. + * Resets on new wave/battle start (but not on switch). + */ +export class PokemonWaveData { + /** Whether the pokemon has endured due to a {@linkcode BattlerTagType.ENDURE_TOKEN} */ + public endured = false; + /** + * A set of all the abilities this {@linkcode Pokemon} has used in this wave. + * Used to track once per battle conditions, as well as (hopefully) by the updated AI for move effectiveness. + */ + public abilitiesApplied: Set = new Set; + /** Whether the pokemon's ability has been revealed or not */ + public abilityRevealed = false; +} + +/** + * Temporary data for a {@linkcode Pokemon}. + * Resets at the start of a new turn, as well as on switch. + */ export class PokemonTurnData { public flinched = false; public acted = false; - /** How many times the move should hit the target(s) */ + /** How many times the current move should hit the target(s) */ public hitCount = 0; /** * - `-1` = Calculate how many hits are left @@ -7813,6 +7932,12 @@ export class PokemonTurnData { * forced to act again in the same turn */ public extraTurns = 0; + /** + * All berries eaten by this pokemon in this turn. + * Saved into {@linkcode PokemonSummonData | SummonData} by {@linkcode Abilities.CUD_CHEW} on turn end. + * @see {@linkcode PokemonSummonData.berriesEatenLast} + */ + public berriesEaten: BerryType[] = [] } export enum AiType { @@ -7850,8 +7975,8 @@ export type DamageResult = | HitResult.SUPER_EFFECTIVE | HitResult.NOT_VERY_EFFECTIVE | HitResult.ONE_HIT_KO - | HitResult.CONFUSION - | HitResult.INDIRECT_KO + | HitResult.CONFUSION + | HitResult.INDIRECT_KO | HitResult.INDIRECT; /** Interface containing the results of a damage calculation for a given move */ @@ -7868,8 +7993,8 @@ export interface DamageCalculationResult { * Wrapper class for the {@linkcode Move} class for Pokemon to interact with. * These are the moves assigned to a {@linkcode Pokemon} object. * It links to {@linkcode Move} class via the move ID. - * Compared to {@linkcode Move}, this class also tracks if a move has received. - * PP Ups, amount of PP used, and things like that. + * Compared to {@linkcode Move}, this class also tracks things like + * PP Ups recieved, PP used, etc. * @see {@linkcode isUsable} - checks if move is restricted, out of PP, or not implemented. * @see {@linkcode getMove} - returns {@linkcode Move} object by looking it up via ID. * @see {@linkcode usePp} - removes a point of PP from the move. @@ -7940,9 +8065,9 @@ export class PokemonMove { /** * Sets {@link ppUsed} for this move and ensures the value does not exceed {@link getMovePp} - * @param {number} count Amount of PP to use + * @param count Amount of PP to use */ - usePp(count = 1) { + usePp(count: number = 1) { this.ppUsed = Math.min(this.ppUsed + count, this.getMovePp()); } @@ -7962,9 +8087,9 @@ export class PokemonMove { } /** - * Copies an existing move or creates a valid PokemonMove object from json representing one - * @param {PokemonMove | any} source The data for the move to copy - * @return {PokemonMove} A valid pokemonmove object + * Copies an existing move or creates a valid {@linkcode PokemonMove} object from json representing one + * @param source The data for the move to copy; can be a {@linkcode PokemonMove} or JSON object representing one + * @returns A valid {@linkcode PokemonMove} object */ static loadMove(source: PokemonMove | any): PokemonMove { return new PokemonMove( diff --git a/src/inputs-controller.ts b/src/inputs-controller.ts index 7fde0f2aca8..02a95f71ac4 100644 --- a/src/inputs-controller.ts +++ b/src/inputs-controller.ts @@ -1,5 +1,6 @@ import Phaser from "phaser"; -import { deepCopy, getEnumValues } from "#app/utils/common"; +import { getEnumValues } from "#app/utils/common"; +import { deepCopy } from "#app/utils/data"; import pad_generic from "./configs/inputs/pad_generic"; import pad_unlicensedSNES from "./configs/inputs/pad_unlicensedSNES"; import pad_xbox360 from "./configs/inputs/pad_xbox360"; diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 110c19dfec0..8bd2dc8948a 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -790,6 +790,7 @@ export class BerryModifierType extends PokemonHeldItemModifierType implements Ge ); this.berryType = berryType; + this.id = "BERRY"; // needed to prevent harvest item deletion; remove after modifier rework } get name(): string { diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 549ce462c11..2823e74fffe 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -47,7 +47,12 @@ import { } from "./modifier-type"; import { Color, ShadowColor } from "#enums/color"; import { FRIENDSHIP_GAIN_FROM_RARE_CANDY } from "#app/data/balance/starters"; -import { applyAbAttrs, CommanderAbAttr } from "#app/data/abilities/ability"; +import { + applyAbAttrs, + applyPostItemLostAbAttrs, + CommanderAbAttr, + PostItemLostAbAttr, +} from "#app/data/abilities/ability"; import { globalScene } from "#app/global-scene"; export type ModifierPredicate = (modifier: Modifier) => boolean; @@ -232,6 +237,10 @@ export abstract class PersistentModifier extends Modifier { abstract getMaxStackCount(forThreshold?: boolean): number; + getCountUnderMax(): number { + return this.getMaxStackCount() - this.getStackCount(); + } + isIconVisible(): boolean { return true; } @@ -653,7 +662,9 @@ export class TerastallizeAccessModifier extends PersistentModifier { } export abstract class PokemonHeldItemModifier extends PersistentModifier { + /** The ID of the {@linkcode Pokemon} that this item belongs to. */ public pokemonId: number; + /** Whether this item can be transfered to or stolen by another Pokemon. */ public isTransferable = true; constructor(type: ModifierType, pokemonId: number, stackCount?: number) { @@ -1639,14 +1650,15 @@ export class FlinchChanceModifier extends PokemonHeldItemModifier { } /** - * Applies {@linkcode FlinchChanceModifier} - * @param pokemon the {@linkcode Pokemon} that holds the item - * @param flinched {@linkcode BooleanHolder} that is `true` if the pokemon flinched - * @returns `true` if {@linkcode FlinchChanceModifier} has been applied + * Applies {@linkcode FlinchChanceModifier} to randomly flinch targets hit. + * @param pokemon - The {@linkcode Pokemon} that holds the item + * @param flinched - A {@linkcode BooleanHolder} holding whether the pokemon has flinched + * @returns `true` if {@linkcode FlinchChanceModifier} was applied successfully */ override apply(pokemon: Pokemon, flinched: BooleanHolder): boolean { - // The check for pokemon.battleSummonData is to ensure that a crash doesn't occur when a Pokemon with King's Rock procs a flinch - if (pokemon.battleSummonData && !flinched.value && pokemon.randSeedInt(100) < this.getStackCount() * this.chance) { + // The check for pokemon.summonData is to ensure that a crash doesn't occur when a Pokemon with King's Rock procs a flinch + // TODO: Since summonData is always defined now, we can probably remove this + if (pokemon.summonData && !flinched.value && pokemon.randSeedInt(100) < this.getStackCount() * this.chance) { flinched.value = true; return true; } @@ -1772,6 +1784,7 @@ export class HitHealModifier extends PokemonHeldItemModifier { */ override apply(pokemon: Pokemon): boolean { if (pokemon.turnData.totalDamageDealt && !pokemon.isFullHp()) { + // TODO: this shouldn't be undefined AFAIK globalScene.unshiftPhase( new PokemonHealPhase( pokemon.getBattlerIndex(), @@ -1867,11 +1880,15 @@ export class BerryModifier extends PokemonHeldItemModifier { override apply(pokemon: Pokemon): boolean { const preserve = new BooleanHolder(false); globalScene.applyModifiers(PreserveBerryModifier, pokemon.isPlayer(), pokemon, preserve); + this.consumed = !preserve.value; + // munch the berry and trigger unburden-like effects getBerryEffectFunc(this.berryType)(pokemon); - if (!preserve.value) { - this.consumed = true; - } + applyPostItemLostAbAttrs(PostItemLostAbAttr, pokemon, false); + + // Update berry eaten trackers for Belch, Harvest, Cud Chew, etc. + // Don't recover it if we proc berry pouch (no item duplication) + pokemon.recordEatenBerry(this.berryType, this.consumed); return true; } @@ -1910,9 +1927,7 @@ export class PreserveBerryModifier extends PersistentModifier { * @returns always `true` */ override apply(pokemon: Pokemon, doPreserve: BooleanHolder): boolean { - if (!doPreserve.value) { - doPreserve.value = pokemon.randSeedInt(10) < this.getStackCount() * 3; - } + doPreserve.value ||= pokemon.randSeedInt(10) < this.getStackCount() * 3; return true; } @@ -3609,7 +3624,7 @@ export class EnemyAttackStatusEffectChanceModifier extends EnemyPersistentModifi super(type, stackCount); this.effect = effect; - //Hardcode temporarily + // Hardcode temporarily this.chance = 0.025 * (this.effect === StatusEffect.BURN || this.effect === StatusEffect.POISON ? 2 : 1); } @@ -3716,13 +3731,13 @@ export class EnemyEndureChanceModifier extends EnemyPersistentModifier { * @returns `true` if {@linkcode Pokemon} endured */ override apply(target: Pokemon): boolean { - if (target.battleData.endured || target.randSeedInt(100) >= this.chance * this.getStackCount()) { + if (target.waveData.endured || target.randSeedInt(100) >= this.chance * this.getStackCount()) { return false; } target.addTag(BattlerTagType.ENDURE_TOKEN, 1); - target.battleData.endured = true; + target.waveData.endured = true; return true; } diff --git a/src/overrides.ts b/src/overrides.ts index 7e6a46f2f85..5bbd29b355f 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -104,8 +104,16 @@ class DefaultOverrides { readonly BYPASS_TUTORIAL_SKIP_OVERRIDE: boolean = false; /** Set to `true` to be able to re-earn already unlocked achievements */ readonly ACHIEVEMENTS_REUNLOCK_OVERRIDE: boolean = false; - /** Set to `true` to force Paralysis and Freeze to always activate, or `false` to force them to not activate */ + /** + * Set to `true` to force Paralysis and Freeze to always activate, + * or `false` to force them to not activate (or clear for freeze). + */ readonly STATUS_ACTIVATION_OVERRIDE: boolean | null = null; + /** + * Set to `true` to force confusion to always trigger, + * or `false` to force it to never trigger. + */ + readonly CONFUSION_ACTIVATION_OVERRIDE: boolean | null = null; // ---------------- // PLAYER OVERRIDES diff --git a/src/phases/battle-end-phase.ts b/src/phases/battle-end-phase.ts index 275a9017dfa..b4bb28fe55e 100644 --- a/src/phases/battle-end-phase.ts +++ b/src/phases/battle-end-phase.ts @@ -59,8 +59,8 @@ export class BattleEndPhase extends BattlePhase { } for (const pokemon of globalScene.getField()) { - if (pokemon?.battleSummonData) { - pokemon.battleSummonData.waveTurnCount = 1; + if (pokemon) { + pokemon.tempSummonData.waveTurnCount = 1; } } diff --git a/src/phases/berry-phase.ts b/src/phases/berry-phase.ts index b20b1736d4f..b027469ea5e 100644 --- a/src/phases/berry-phase.ts +++ b/src/phases/berry-phase.ts @@ -1,4 +1,9 @@ -import { applyAbAttrs, PreventBerryUseAbAttr, HealFromBerryUseAbAttr } from "#app/data/abilities/ability"; +import { + applyAbAttrs, + PreventBerryUseAbAttr, + HealFromBerryUseAbAttr, + RepeatBerryNextTurnAbAttr, +} from "#app/data/abilities/ability"; import { CommonAnim } from "#app/data/battle-anims"; import { BerryUsedEvent } from "#app/events/battle-scene"; import { getPokemonNameWithAffix } from "#app/messages"; @@ -8,47 +13,65 @@ import { BooleanHolder } from "#app/utils/common"; import { FieldPhase } from "./field-phase"; import { CommonAnimPhase } from "./common-anim-phase"; import { globalScene } from "#app/global-scene"; +import type Pokemon from "#app/field/pokemon"; -/** The phase after attacks where the pokemon eat berries */ +/** + * The phase after attacks where the pokemon eat berries. + * Also triggers Cud Chew's "repeat berry use" effects + */ export class BerryPhase extends FieldPhase { start() { super.start(); this.executeForAll(pokemon => { - const hasUsableBerry = !!globalScene.findModifier(m => { - return m instanceof BerryModifier && m.shouldApply(pokemon); - }, pokemon.isPlayer()); - - if (hasUsableBerry) { - const cancelled = new BooleanHolder(false); - pokemon.getOpponents().map(opp => applyAbAttrs(PreventBerryUseAbAttr, opp, cancelled)); - - if (cancelled.value) { - globalScene.queueMessage( - i18next.t("abilityTriggers:preventBerryUse", { - pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), - }), - ); - } else { - globalScene.unshiftPhase( - new CommonAnimPhase(pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.USE_ITEM), - ); - - for (const berryModifier of globalScene.applyModifiers(BerryModifier, pokemon.isPlayer(), pokemon)) { - if (berryModifier.consumed) { - berryModifier.consumed = false; - pokemon.loseHeldItem(berryModifier); - } - globalScene.eventTarget.dispatchEvent(new BerryUsedEvent(berryModifier)); // Announce a berry was used - } - - globalScene.updateModifiers(pokemon.isPlayer()); - - applyAbAttrs(HealFromBerryUseAbAttr, pokemon, new BooleanHolder(false)); - } - } + this.eatBerries(pokemon); + applyAbAttrs(RepeatBerryNextTurnAbAttr, pokemon, null); }); this.end(); } + + /** + * Attempt to eat all of a given {@linkcode Pokemon}'s berries once. + * @param pokemon - The {@linkcode Pokemon} to check + */ + eatBerries(pokemon: Pokemon): void { + const hasUsableBerry = !!globalScene.findModifier( + m => m instanceof BerryModifier && m.shouldApply(pokemon), + pokemon.isPlayer(), + ); + + if (!hasUsableBerry) { + return; + } + + // TODO: If both opponents on field have unnerve, which one displays its message? + const cancelled = new BooleanHolder(false); + pokemon.getOpponents().forEach(opp => applyAbAttrs(PreventBerryUseAbAttr, opp, cancelled)); + if (cancelled.value) { + globalScene.queueMessage( + i18next.t("abilityTriggers:preventBerryUse", { + pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), + }), + ); + return; + } + + globalScene.unshiftPhase( + new CommonAnimPhase(pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.USE_ITEM), + ); + + for (const berryModifier of globalScene.applyModifiers(BerryModifier, pokemon.isPlayer(), pokemon)) { + // No need to track berries being eaten; already done inside applyModifiers + if (berryModifier.consumed) { + berryModifier.consumed = false; + pokemon.loseHeldItem(berryModifier); + } + globalScene.eventTarget.dispatchEvent(new BerryUsedEvent(berryModifier)); + } + globalScene.updateModifiers(pokemon.isPlayer()); + + // Abilities.CHEEK_POUCH only works once per round of nom noms + applyAbAttrs(HealFromBerryUseAbAttr, pokemon, new BooleanHolder(false)); + } } diff --git a/src/phases/encounter-phase.ts b/src/phases/encounter-phase.ts index 20ed69119f9..5b799bd9316 100644 --- a/src/phases/encounter-phase.ts +++ b/src/phases/encounter-phase.ts @@ -113,12 +113,6 @@ export class EncounterPhase extends BattlePhase { } if (!this.loaded) { if (battle.battleType === BattleType.TRAINER) { - //resets hitRecCount during Trainer ecnounter - for (const pokemon of globalScene.getPlayerParty()) { - if (pokemon) { - pokemon.customPokemonData.resetHitReceivedCount(); - } - } battle.enemyParty[e] = battle.trainer?.genPartyMember(e)!; // TODO:: is the bang correct here? } else { let enemySpecies = globalScene.randomSpecies(battle.waveIndex, level, true); @@ -140,7 +134,6 @@ export class EncounterPhase extends BattlePhase { if (globalScene.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) { battle.enemyParty[e].ivs = new Array(6).fill(31); } - // biome-ignore lint/complexity/noForEach: Improves readability globalScene .getPlayerParty() .slice(0, !battle.double ? 1 : 2) @@ -195,7 +188,7 @@ export class EncounterPhase extends BattlePhase { ]; const moveset: string[] = []; for (const move of enemyPokemon.getMoveset()) { - moveset.push(move!.getName()); // TODO: remove `!` after moveset-null removal PR + moveset.push(move.getName()); } console.log( @@ -288,6 +281,7 @@ export class EncounterPhase extends BattlePhase { }); if (!this.loaded && battle.battleType !== BattleType.MYSTERY_ENCOUNTER) { + // generate modifiers for MEs, overriding prior ones as applicable regenerateModifierPoolThresholds( globalScene.getEnemyField(), battle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD, @@ -300,8 +294,8 @@ export class EncounterPhase extends BattlePhase { } } - if (battle.battleType === BattleType.TRAINER) { - globalScene.currentBattle.trainer!.genAI(globalScene.getEnemyParty()); + if (battle.battleType === BattleType.TRAINER && globalScene.currentBattle.trainer) { + globalScene.currentBattle.trainer.genAI(globalScene.getEnemyParty()); } globalScene.ui.setMode(UiMode.MESSAGE).then(() => { @@ -342,8 +336,10 @@ export class EncounterPhase extends BattlePhase { } for (const pokemon of globalScene.getPlayerParty()) { + // Currently, a new wave is not considered a new battle if there is no arena reset + // Therefore, we only reset wave data here if (pokemon) { - pokemon.resetBattleData(); + pokemon.resetWaveData(); } } @@ -558,7 +554,7 @@ export class EncounterPhase extends BattlePhase { if (enemyPokemon.isShiny(true)) { globalScene.unshiftPhase(new ShinySparklePhase(BattlerIndex.ENEMY + e)); } - /** This sets Eternatus' held item to be untransferrable, preventing it from being stolen */ + /** This sets Eternatus' held item to be untransferrable, preventing it from being stolen */ if ( enemyPokemon.species.speciesId === Species.ETERNATUS && (globalScene.gameMode.isBattleClassicFinalBoss(globalScene.currentBattle.waveIndex) || diff --git a/src/phases/evolution-phase.ts b/src/phases/evolution-phase.ts index 7b013555f40..8fc8a8be031 100644 --- a/src/phases/evolution-phase.ts +++ b/src/phases/evolution-phase.ts @@ -146,7 +146,7 @@ export class EvolutionPhase extends Phase { sprite.setPipelineData("shiny", this.pokemon.shiny); sprite.setPipelineData("variant", this.pokemon.variant); ["spriteColors", "fusionSpriteColors"].map(k => { - if (this.pokemon.summonData?.speciesForm) { + if (this.pokemon.summonData.speciesForm) { k += "Base"; } sprite.pipelineData[k] = this.pokemon.getSprite().pipelineData[k]; @@ -178,7 +178,7 @@ export class EvolutionPhase extends Phase { sprite.setPipelineData("shiny", evolvedPokemon.shiny); sprite.setPipelineData("variant", evolvedPokemon.variant); ["spriteColors", "fusionSpriteColors"].map(k => { - if (evolvedPokemon.summonData?.speciesForm) { + if (evolvedPokemon.summonData.speciesForm) { k += "Base"; } sprite.pipelineData[k] = evolvedPokemon.getSprite().pipelineData[k]; diff --git a/src/phases/faint-phase.ts b/src/phases/faint-phase.ts index 4c99a609b11..1aa24d59fa0 100644 --- a/src/phases/faint-phase.ts +++ b/src/phases/faint-phase.ts @@ -118,7 +118,7 @@ export class FaintPhase extends PokemonPhase { pokemon.resetTera(); - if (pokemon.turnData?.attacksReceived?.length) { + if (pokemon.turnData.attacksReceived?.length) { const lastAttack = pokemon.turnData.attacksReceived[0]; applyPostFaintAbAttrs( PostFaintAbAttr, @@ -136,7 +136,7 @@ export class FaintPhase extends PokemonPhase { for (const p of alivePlayField) { applyPostKnockOutAbAttrs(PostKnockOutAbAttr, p, pokemon); } - if (pokemon.turnData?.attacksReceived?.length) { + if (pokemon.turnData.attacksReceived?.length) { const defeatSource = this.source; if (defeatSource?.isOnField()) { diff --git a/src/phases/field-phase.ts b/src/phases/field-phase.ts index 98c1ced510f..c37f0e960e7 100644 --- a/src/phases/field-phase.ts +++ b/src/phases/field-phase.ts @@ -6,8 +6,7 @@ type PokemonFunc = (pokemon: Pokemon) => void; export abstract class FieldPhase extends BattlePhase { executeForAll(func: PokemonFunc): void { - const field = globalScene.getField(true).filter(p => p.summonData); - for (const pokemon of field) { + for (const pokemon of globalScene.getField(true)) { func(pokemon); } } diff --git a/src/phases/form-change-phase.ts b/src/phases/form-change-phase.ts index ac7edadf244..5517fb0f402 100644 --- a/src/phases/form-change-phase.ts +++ b/src/phases/form-change-phase.ts @@ -51,7 +51,7 @@ export class FormChangePhase extends EvolutionPhase { sprite.setPipelineData("shiny", transformedPokemon.shiny); sprite.setPipelineData("variant", transformedPokemon.variant); ["spriteColors", "fusionSpriteColors"].map(k => { - if (transformedPokemon.summonData?.speciesForm) { + if (transformedPokemon.summonData.speciesForm) { k += "Base"; } sprite.pipelineData[k] = transformedPokemon.getSprite().pipelineData[k]; diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index 4b4e62db71b..64cae923f07 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -277,9 +277,6 @@ export class MoveEffectPhase extends PokemonPhase { super.end(); return; } - if (isNullOrUndefined(user.turnData)) { - user.resetTurnData(); - } } /** diff --git a/src/phases/move-phase.ts b/src/phases/move-phase.ts index b24d7b61ebb..e704b040d20 100644 --- a/src/phases/move-phase.ts +++ b/src/phases/move-phase.ts @@ -618,7 +618,7 @@ export class MovePhase extends BattlePhase { globalScene.eventTarget.dispatchEvent(new MoveUsedEvent(this.pokemon?.id, this.move.getMove(), ppUsed)); } - if (this.cancelled && this.pokemon.summonData?.tags?.find(t => t.tagType === BattlerTagType.FRENZY)) { + if (this.cancelled && this.pokemon.summonData.tags?.find(t => t.tagType === BattlerTagType.FRENZY)) { frenzyMissFunc(this.pokemon, this.move.getMove()); } diff --git a/src/phases/mystery-encounter-phases.ts b/src/phases/mystery-encounter-phases.ts index 011dd26db92..fd0c4ef7949 100644 --- a/src/phases/mystery-encounter-phases.ts +++ b/src/phases/mystery-encounter-phases.ts @@ -229,8 +229,7 @@ export class MysteryEncounterBattleStartCleanupPhase extends Phase { // Lapse any residual flinches/endures but ignore all other turn-end battle tags const includedLapseTags = [BattlerTagType.FLINCHED, BattlerTagType.ENDURING]; - const field = globalScene.getField(true).filter(p => p.summonData); - field.forEach(pokemon => { + globalScene.getField(true).forEach(pokemon => { const tags = pokemon.summonData.tags; tags .filter( diff --git a/src/phases/new-biome-encounter-phase.ts b/src/phases/new-biome-encounter-phase.ts index 6a7afcb8da8..ef027bfd77a 100644 --- a/src/phases/new-biome-encounter-phase.ts +++ b/src/phases/new-biome-encounter-phase.ts @@ -7,17 +7,17 @@ export class NewBiomeEncounterPhase extends NextEncounterPhase { doEncounter(): void { globalScene.playBgm(undefined, true); + // Reset all battle and wave data, perform form changes, etc. + // We do this because new biomes are considered "arena transitions" akin to MEs and trainer battles for (const pokemon of globalScene.getPlayerParty()) { if (pokemon) { - pokemon.resetBattleData(); - pokemon.customPokemonData.resetHitReceivedCount(); + pokemon.resetBattleAndWaveData(); + if (pokemon.isOnField()) { + applyAbAttrs(PostBiomeChangeAbAttr, pokemon, null); + } } } - for (const pokemon of globalScene.getPlayerParty().filter(p => p.isOnField())) { - applyAbAttrs(PostBiomeChangeAbAttr, pokemon, null); - } - const enemyField = globalScene.getEnemyField(); const moveTargets: any[] = [globalScene.arenaEnemy, enemyField]; const mysteryEncounter = globalScene.currentBattle?.mysteryEncounter?.introVisuals; diff --git a/src/phases/next-encounter-phase.ts b/src/phases/next-encounter-phase.ts index e5e61312c3b..30b4004363c 100644 --- a/src/phases/next-encounter-phase.ts +++ b/src/phases/next-encounter-phase.ts @@ -1,6 +1,10 @@ import { globalScene } from "#app/global-scene"; import { EncounterPhase } from "./encounter-phase"; +/** + * The phase between defeating an encounter and starting another wild wave. + * Handles generating, loading and preparing for it. + */ export class NextEncounterPhase extends EncounterPhase { start() { super.start(); @@ -9,9 +13,12 @@ export class NextEncounterPhase extends EncounterPhase { doEncounter(): void { globalScene.playBgm(undefined, true); + // Reset all player transient wave data/intel before starting a new wild encounter. + // We exclusively reset wave data here as wild waves are considered one continuous "battle" + // for lack of an arena transition. for (const pokemon of globalScene.getPlayerParty()) { if (pokemon) { - pokemon.resetBattleData(); + pokemon.resetWaveData(); } } diff --git a/src/phases/quiet-form-change-phase.ts b/src/phases/quiet-form-change-phase.ts index f476919a628..76411f62f77 100644 --- a/src/phases/quiet-form-change-phase.ts +++ b/src/phases/quiet-form-change-phase.ts @@ -74,7 +74,7 @@ export class QuietFormChangePhase extends BattlePhase { isTerastallized: this.pokemon.isTerastallized, }); ["spriteColors", "fusionSpriteColors"].map(k => { - if (this.pokemon.summonData?.speciesForm) { + if (this.pokemon.summonData.speciesForm) { k += "Base"; } sprite.pipelineData[k] = this.pokemon.getSprite().pipelineData[k]; diff --git a/src/phases/show-ability-phase.ts b/src/phases/show-ability-phase.ts index 8097af33fe0..d6193ac3946 100644 --- a/src/phases/show-ability-phase.ts +++ b/src/phases/show-ability-phase.ts @@ -50,9 +50,7 @@ export class ShowAbilityPhase extends PokemonPhase { } globalScene.abilityBar.showAbility(this.pokemonName, this.abilityName, this.passive, this.player).then(() => { - if (pokemon?.battleData) { - pokemon.battleData.abilityRevealed = true; - } + pokemon.waveData.abilityRevealed = true; this.end(); }); diff --git a/src/phases/stat-stage-change-phase.ts b/src/phases/stat-stage-change-phase.ts index 9d64a81bbb4..6731e45025c 100644 --- a/src/phases/stat-stage-change-phase.ts +++ b/src/phases/stat-stage-change-phase.ts @@ -217,16 +217,8 @@ export class StatStageChangePhase extends PokemonPhase { for (const s of filteredStats) { if (stages.value > 0 && pokemon.getStatStage(s) < 6) { - if (!pokemon.turnData) { - // Temporary fix for missing turn data struct on turn 1 - pokemon.resetTurnData(); - } pokemon.turnData.statStagesIncreased = true; } else if (stages.value < 0 && pokemon.getStatStage(s) > -6) { - if (!pokemon.turnData) { - // Temporary fix for missing turn data struct on turn 1 - pokemon.resetTurnData(); - } pokemon.turnData.statStagesDecreased = true; } diff --git a/src/phases/summon-phase.ts b/src/phases/summon-phase.ts index ee27fc28247..fef9b356348 100644 --- a/src/phases/summon-phase.ts +++ b/src/phases/summon-phase.ts @@ -177,11 +177,7 @@ export class SummonPhase extends PartyMemberPokemonPhase { } globalScene.currentBattle.seenEnemyPartyMemberIds.add(pokemon.id); } - addPokeballOpenParticles( - pokemon.x, - pokemon.y - 16, - pokemon.getPokeball(true), - ); + addPokeballOpenParticles(pokemon.x, pokemon.y - 16, pokemon.getPokeball(true)); globalScene.updateModifiers(this.player); globalScene.updateFieldScale(); pokemon.showInfo(); @@ -200,9 +196,8 @@ export class SummonPhase extends PartyMemberPokemonPhase { onComplete: () => { pokemon.cry(pokemon.getHpRatio() > 0.25 ? undefined : { rate: 0.85 }); pokemon.getSprite().clearTint(); - pokemon.resetSummonData(); // necessary to stay transformed during wild waves - if (pokemon.summonData?.speciesForm) { + if (pokemon.summonData.speciesForm) { pokemon.loadAssets(false); } globalScene.time.delayedCall(1000, () => this.end()); @@ -266,7 +261,6 @@ export class SummonPhase extends PartyMemberPokemonPhase { onComplete: () => { pokemon.cry(pokemon.getHpRatio() > 0.25 ? undefined : { rate: 0.85 }); pokemon.getSprite().clearTint(); - pokemon.resetSummonData(); globalScene.updateFieldScale(); globalScene.time.delayedCall(1000, () => this.end()); }, diff --git a/src/phases/switch-summon-phase.ts b/src/phases/switch-summon-phase.ts index f8728f3f9b9..bb31f87cc3d 100644 --- a/src/phases/switch-summon-phase.ts +++ b/src/phases/switch-summon-phase.ts @@ -33,10 +33,10 @@ export class SwitchSummonPhase extends SummonPhase { * @param fieldIndex - Position on the battle field * @param slotIndex - The index of pokemon (in party of 6) to switch into * @param doReturn - Whether to render "comeback" dialogue - * @param player - (Optional) `true` if the switch is from the player + * @param player - Whether the switch came from the player or enemy; default `true` */ - constructor(switchType: SwitchType, fieldIndex: number, slotIndex: number, doReturn: boolean, player?: boolean) { - super(fieldIndex, player !== undefined ? player : true); + constructor(switchType: SwitchType, fieldIndex: number, slotIndex: number, doReturn: boolean, player = true) { + super(fieldIndex, player); this.switchType = switchType; this.slotIndex = slotIndex; @@ -67,7 +67,8 @@ export class SwitchSummonPhase extends SummonPhase { !(this.player ? globalScene.getPlayerParty() : globalScene.getEnemyParty())[this.slotIndex]) ) { if (this.player) { - return this.switchAndSummon(); + this.switchAndSummon(); + return; } globalScene.time.delayedCall(750, () => this.switchAndSummon()); return; @@ -120,14 +121,23 @@ export class SwitchSummonPhase extends SummonPhase { switchAndSummon() { const party = this.player ? this.getParty() : globalScene.getEnemyParty(); - const switchedInPokemon = party[this.slotIndex]; + const switchedInPokemon: Pokemon | undefined = party[this.slotIndex]; this.lastPokemon = this.getPokemon(); + applyPreSummonAbAttrs(PreSummonAbAttr, switchedInPokemon); applyPreSwitchOutAbAttrs(PreSwitchOutAbAttr, this.lastPokemon); - if (this.switchType === SwitchType.BATON_PASS && switchedInPokemon) { - (this.player ? globalScene.getEnemyField() : globalScene.getPlayerField()).forEach(enemyPokemon => + if (!switchedInPokemon) { + this.end(); + return; + } + + if (this.switchType === SwitchType.BATON_PASS) { + // If switching via baton pass, update opposing tags coming from the prior pokemon + (this.player ? globalScene.getEnemyField() : globalScene.getPlayerField()).forEach((enemyPokemon: Pokemon) => enemyPokemon.transferTagsBySourceId(this.lastPokemon.id, switchedInPokemon.id), ); + + // If the recipient pokemon lacks a baton, give our baton to it during the swap if ( !globalScene.findModifier( m => @@ -140,14 +150,8 @@ export class SwitchSummonPhase extends SummonPhase { m instanceof SwitchEffectTransferModifier && (m as SwitchEffectTransferModifier).pokemonId === this.lastPokemon.id, ) as SwitchEffectTransferModifier; - if ( - batonPassModifier && - !globalScene.findModifier( - m => - m instanceof SwitchEffectTransferModifier && - (m as SwitchEffectTransferModifier).pokemonId === switchedInPokemon.id, - ) - ) { + + if (batonPassModifier) { globalScene.tryTransferHeldItemModifier( batonPassModifier, switchedInPokemon, @@ -160,49 +164,48 @@ export class SwitchSummonPhase extends SummonPhase { } } } - if (switchedInPokemon) { - party[this.slotIndex] = this.lastPokemon; - party[this.fieldIndex] = switchedInPokemon; - const showTextAndSummon = () => { - globalScene.ui.showText( - this.player - ? i18next.t("battle:playerGo", { - pokemonName: getPokemonNameWithAffix(switchedInPokemon), - }) - : i18next.t("battle:trainerGo", { - trainerName: globalScene.currentBattle.trainer?.getName( - !(this.fieldIndex % 2) ? TrainerSlot.TRAINER : TrainerSlot.TRAINER_PARTNER, - ), - pokemonName: this.getPokemon().getNameToRender(), - }), - ); - /** - * If this switch is passing a Substitute, make the switched Pokemon match the returned Pokemon's state as it left. - * Otherwise, clear any persisting tags on the returned Pokemon. - */ - if (this.switchType === SwitchType.BATON_PASS || this.switchType === SwitchType.SHED_TAIL) { - const substitute = this.lastPokemon.getTag(SubstituteTag); - if (substitute) { - switchedInPokemon.x += this.lastPokemon.getSubstituteOffset()[0]; - switchedInPokemon.y += this.lastPokemon.getSubstituteOffset()[1]; - switchedInPokemon.setAlpha(0.5); - } - } else { - switchedInPokemon.resetSummonData(); + + party[this.slotIndex] = this.lastPokemon; + party[this.fieldIndex] = switchedInPokemon; + const showTextAndSummon = () => { + globalScene.ui.showText( + this.player + ? i18next.t("battle:playerGo", { + pokemonName: getPokemonNameWithAffix(switchedInPokemon), + }) + : i18next.t("battle:trainerGo", { + trainerName: globalScene.currentBattle.trainer?.getName( + !(this.fieldIndex % 2) ? TrainerSlot.TRAINER : TrainerSlot.TRAINER_PARTNER, + ), + pokemonName: this.getPokemon().getNameToRender(), + }), + ); + + /** + * If this switch is passing a Substitute, make the switched Pokemon matches the returned Pokemon's state as it left. + * Otherwise, clear any persisting tags on the returned Pokemon. + */ + if (this.switchType === SwitchType.BATON_PASS || this.switchType === SwitchType.SHED_TAIL) { + const substitute = this.lastPokemon.getTag(SubstituteTag); + if (substitute) { + switchedInPokemon.x += this.lastPokemon.getSubstituteOffset()[0]; + switchedInPokemon.y += this.lastPokemon.getSubstituteOffset()[1]; + switchedInPokemon.setAlpha(0.5); } - this.summon(); - }; - if (this.player) { - showTextAndSummon(); } else { - globalScene.time.delayedCall(1500, () => { - this.hideEnemyTrainer(); - globalScene.pbTrayEnemy.hide(); - showTextAndSummon(); - }); + switchedInPokemon.resetSummonData(); } + this.summon(); + }; + + if (this.player) { + showTextAndSummon(); } else { - this.end(); + globalScene.time.delayedCall(1500, () => { + this.hideEnemyTrainer(); + globalScene.pbTrayEnemy.hide(); + showTextAndSummon(); + }); } } @@ -220,15 +223,15 @@ export class SwitchSummonPhase extends SummonPhase { const lastPokemonHasForceSwitchAbAttr = this.lastPokemon.hasAbilityWithAttr(PostDamageForceSwitchAbAttr) && !this.lastPokemon.isFainted(); - // Compensate for turn spent summoning - // Or compensate for force switch move if switched out pokemon is not fainted + // Compensate for turn spent summoning/forced switch if switched out pokemon is not fainted. + // Needed as we increment turn counters in `TurnEndPhase`. if ( currentCommand === Command.POKEMON || lastPokemonIsForceSwitchedAndNotFainted || lastPokemonHasForceSwitchAbAttr ) { - pokemon.battleSummonData.turnCount--; - pokemon.battleSummonData.waveTurnCount--; + pokemon.tempSummonData.turnCount--; + pokemon.tempSummonData.waveTurnCount--; } if (this.switchType === SwitchType.BATON_PASS && pokemon) { @@ -240,12 +243,13 @@ export class SwitchSummonPhase extends SummonPhase { } } + // Reset turn data if not initial switch (since it gets initialized to an empty object on turn start) if (this.switchType !== SwitchType.INITIAL_SWITCH) { pokemon.resetTurnData(); pokemon.turnData.switchedInThisTurn = true; } - this.lastPokemon?.resetSummonData(); + this.lastPokemon.resetSummonData(); globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeActiveTrigger, true); // Reverts to weather-based forms when weather suppressors (Cloud Nine/Air Lock) are switched out diff --git a/src/phases/turn-end-phase.ts b/src/phases/turn-end-phase.ts index fe16a4a864e..756c497802b 100644 --- a/src/phases/turn-end-phase.ts +++ b/src/phases/turn-end-phase.ts @@ -54,11 +54,10 @@ export class TurnEndPhase extends FieldPhase { } globalScene.applyModifiers(TurnStatusEffectModifier, pokemon.isPlayer(), pokemon); - globalScene.applyModifiers(TurnHeldItemTransferModifier, pokemon.isPlayer(), pokemon); - pokemon.battleSummonData.turnCount++; - pokemon.battleSummonData.waveTurnCount++; + pokemon.tempSummonData.turnCount++; + pokemon.tempSummonData.waveTurnCount++; }; this.executeForAll(handlePokemon); diff --git a/src/phases/turn-start-phase.ts b/src/phases/turn-start-phase.ts index 622b9cdcbd1..b802780bbb8 100644 --- a/src/phases/turn-start-phase.ts +++ b/src/phases/turn-start-phase.ts @@ -72,19 +72,16 @@ export class TurnStartPhase extends FieldPhase { // This occurs before the main loop because of battles with more than two Pokemon const battlerBypassSpeed = {}; - globalScene - .getField(true) - .filter(p => p.summonData) - .map(p => { - const bypassSpeed = new BooleanHolder(false); - const canCheckHeldItems = new BooleanHolder(true); - applyAbAttrs(BypassSpeedChanceAbAttr, p, null, false, bypassSpeed); - applyAbAttrs(PreventBypassSpeedChanceAbAttr, p, null, false, bypassSpeed, canCheckHeldItems); - if (canCheckHeldItems.value) { - globalScene.applyModifiers(BypassSpeedChanceModifier, p.isPlayer(), p, bypassSpeed); - } - battlerBypassSpeed[p.getBattlerIndex()] = bypassSpeed; - }); + globalScene.getField(true).map(p => { + const bypassSpeed = new BooleanHolder(false); + const canCheckHeldItems = new BooleanHolder(true); + applyAbAttrs(BypassSpeedChanceAbAttr, p, null, false, bypassSpeed); + applyAbAttrs(PreventBypassSpeedChanceAbAttr, p, null, false, bypassSpeed, canCheckHeldItems); + if (canCheckHeldItems.value) { + globalScene.applyModifiers(BypassSpeedChanceModifier, p.isPlayer(), p, bypassSpeed); + } + battlerBypassSpeed[p.getBattlerIndex()] = bypassSpeed; + }); // The function begins sorting orderedTargets based on command priority, move priority, and possible speed bypasses. // Non-FIGHT commands (SWITCH, BALL, RUN) have a higher command priority and will always occur before any FIGHT commands. diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 8573c774054..e200fa6b3c7 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -1145,7 +1145,7 @@ export class GameData { ? trainerConfig?.doubleOnly || sessionData.trainer?.variant === TrainerVariant.DOUBLE : sessionData.enemyParty.length > 1, mysteryEncounterType, - )!; // TODO: is this bang correct? + ); battle.enemyLevels = sessionData.enemyParty.map(p => p.level); globalScene.arena.init(); @@ -1198,13 +1198,16 @@ export class GameData { } } + if (globalScene.modifiers.length) { + console.warn("Existing modifiers not cleared on session load, deleting..."); + globalScene.modifiers = []; + } for (const modifierData of sessionData.modifiers) { const modifier = modifierData.toModifier(Modifier[modifierData.className]); if (modifier) { globalScene.addModifier(modifier, true); } } - globalScene.updateModifiers(true); for (const enemyModifierData of sessionData.enemyModifiers) { @@ -1342,68 +1345,67 @@ export class GameData { } parseSessionData(dataStr: string): SessionSaveData { + // TODO: Add `null`/`undefined` to the corresponding type signatures for this + // (or prevent them from being null) + // If the value is able to *not exist*, it should say so in the code const sessionData = JSON.parse(dataStr, (k: string, v: any) => { - if (k === "party" || k === "enemyParty") { - const ret: PokemonData[] = []; - if (v === null) { - v = []; - } - for (const pd of v) { - ret.push(new PokemonData(pd)); - } - return ret; - } - - if (k === "trainer") { - return v ? new TrainerData(v) : null; - } - - if (k === "modifiers" || k === "enemyModifiers") { - const player = k === "modifiers"; - const ret: PersistentModifierData[] = []; - if (v === null) { - v = []; - } - for (const md of v) { - if (md?.className === "ExpBalanceModifier") { - // Temporarily limit EXP Balance until it gets reworked - md.stackCount = Math.min(md.stackCount, 4); + // TODO: Add pre-parse migrate scripts + switch (k) { + case "party": + case "enemyParty": { + const ret: PokemonData[] = []; + for (const pd of v ?? []) { + ret.push(new PokemonData(pd)); } - if ( - (md instanceof Modifier.EnemyAttackStatusEffectChanceModifier && md.effect === StatusEffect.FREEZE) || - md.effect === StatusEffect.SLEEP - ) { - continue; + return ret; + } + + case "trainer": + return v ? new TrainerData(v) : null; + + case "modifiers": + case "enemyModifiers": { + const ret: PersistentModifierData[] = []; + for (const md of v ?? []) { + if (md?.className === "ExpBalanceModifier") { + // Temporarily limit EXP Balance until it gets reworked + md.stackCount = Math.min(md.stackCount, 4); + } + + if ( + md instanceof Modifier.EnemyAttackStatusEffectChanceModifier && + (md.effect === StatusEffect.FREEZE || md.effect === StatusEffect.SLEEP) + ) { + // Discard any old "sleep/freeze chance tokens". + // TODO: make this migrate script + continue; + } + + ret.push(new PersistentModifierData(md, k === "modifiers")); } - ret.push(new PersistentModifierData(md, player)); + return ret; } - return ret; - } - if (k === "arena") { - return new ArenaData(v); - } + case "arena": + return new ArenaData(v); - if (k === "challenges") { - const ret: ChallengeData[] = []; - if (v === null) { - v = []; + case "challenges": { + const ret: ChallengeData[] = []; + for (const c of v ?? []) { + ret.push(new ChallengeData(c)); + } + return ret; } - for (const c of v) { - ret.push(new ChallengeData(c)); - } - return ret; - } - if (k === "mysteryEncounterType") { - return v as MysteryEncounterType; - } + case "mysteryEncounterType": + return v as MysteryEncounterType; - if (k === "mysteryEncounterSaveData") { - return new MysteryEncounterSaveData(v); - } + case "mysteryEncounterSaveData": + return new MysteryEncounterSaveData(v); - return v; + default: + return v; + } }) as SessionSaveData; applySessionVersionMigration(sessionData); @@ -1456,7 +1458,7 @@ export class GameData { encrypt(JSON.stringify(sessionData), bypassLogin), ); - console.debug("Session data saved"); + console.debug("Session data saved!"); if (!bypassLogin && sync) { pokerogueApi.savedata.updateAll(request).then(error => { diff --git a/src/system/pokemon-data.ts b/src/system/pokemon-data.ts index 00baad8cf12..7e71dffde5e 100644 --- a/src/system/pokemon-data.ts +++ b/src/system/pokemon-data.ts @@ -1,16 +1,15 @@ import { BattleType } from "#enums/battle-type"; import { globalScene } from "#app/global-scene"; import type { Gender } from "../data/gender"; -import type { Nature } from "#enums/nature"; -import type { PokeballType } from "#enums/pokeball"; +import { Nature } from "#enums/nature"; +import { PokeballType } from "#enums/pokeball"; import { getPokemonSpecies, getPokemonSpeciesForm } from "../data/pokemon-species"; -import { Status } from "../data/status-effect"; -import Pokemon, { EnemyPokemon, PokemonMove, PokemonSummonData } from "../field/pokemon"; +import type { Status } from "../data/status-effect"; +import Pokemon, { EnemyPokemon, PokemonBattleData, PokemonMove, PokemonSummonData } from "../field/pokemon"; import { TrainerSlot } from "#enums/trainer-slot"; import type { Variant } from "#app/sprites/variant"; -import { loadBattlerTag } from "../data/battler-tags"; import type { Biome } from "#enums/biome"; -import { Moves } from "#enums/moves"; +import type { Moves } from "#enums/moves"; import type { Species } from "#enums/species"; import { CustomPokemonData } from "#app/data/custom-pokemon-data"; import type { PokemonType } from "#enums/pokemon-type"; @@ -60,79 +59,66 @@ export default class PokemonData { public fusionTeraType: PokemonType; public boss: boolean; - public bossSegments?: number; + public bossSegments: number; + // Effects that need to be preserved between waves public summonData: PokemonSummonData; + public battleData: PokemonBattleData; public summonDataSpeciesFormIndex: number; - /** Data that can customize a Pokemon in non-standard ways from its Species */ public customPokemonData: CustomPokemonData; public fusionCustomPokemonData: CustomPokemonData; // Deprecated attributes, needed for now to allow SessionData migration (see PR#4619 comments) + // TODO: Remove these once pre-session migration is implemented public natureOverride: Nature | -1; public mysteryEncounterPokemonData: CustomPokemonData | null; public fusionMysteryEncounterPokemonData: CustomPokemonData | null; - constructor(source: Pokemon | any, forHistory = false) { - const sourcePokemon = source instanceof Pokemon ? source : null; + /** + * Construct a new {@linkcode PokemonData} instance out of a {@linkcode Pokemon} + * or JSON representation thereof. + * @param source The {@linkcode Pokemon} to convert into data (or a JSON object representing one) + */ + // TODO: Remove any from type signature in favor of 2 separate method funcs + constructor(source: Pokemon | any) { + const sourcePokemon = source instanceof Pokemon ? source : undefined; + this.id = source.id; - this.player = sourcePokemon ? sourcePokemon.isPlayer() : source.player; - this.species = sourcePokemon ? sourcePokemon.species.speciesId : source.species; - this.nickname = sourcePokemon - ? (!!sourcePokemon.summonData?.illusion ? sourcePokemon.summonData.illusion.basePokemon.nickname : sourcePokemon.nickname) - : source.nickname; + this.player = sourcePokemon?.isPlayer() ?? source.player; + this.species = sourcePokemon?.species.speciesId ?? source.species; + this.nickname = sourcePokemon?.summonData.illusion?.basePokemon.nickname ?? source.nickname; this.formIndex = Math.max(Math.min(source.formIndex, getPokemonSpecies(this.species).forms.length - 1), 0); this.abilityIndex = source.abilityIndex; this.passive = source.passive; - this.shiny = sourcePokemon ? sourcePokemon.isShiny() : source.shiny; - this.variant = sourcePokemon ? sourcePokemon.getVariant() : source.variant; - this.pokeball = source.pokeball; + this.shiny = sourcePokemon?.isShiny() ?? source.shiny; + this.variant = sourcePokemon?.getVariant() ?? source.variant; + this.pokeball = source.pokeball ?? PokeballType.POKEBALL; this.level = source.level; this.exp = source.exp; - if (!forHistory) { - this.levelExp = source.levelExp; - } + this.levelExp = source.levelExp; this.gender = source.gender; - if (!forHistory) { - this.hp = source.hp; - } + this.hp = source.hp; this.stats = source.stats; this.ivs = source.ivs; - this.nature = source.nature !== undefined ? source.nature : (0 as Nature); - this.friendship = - source.friendship !== undefined ? source.friendship : getPokemonSpecies(this.species).baseFriendship; + + // TODO: Can't we move some of this verification stuff to an upgrade script? + this.nature = source.nature ?? Nature.HARDY; + this.moveset = source.moveset.map((m: any) => PokemonMove.loadMove(m)); + this.status = source.status ?? null; + this.friendship = source.friendship ?? getPokemonSpecies(this.species).baseFriendship; this.metLevel = source.metLevel || 5; - this.metBiome = source.metBiome !== undefined ? source.metBiome : -1; + this.metBiome = source.metBiome ?? -1; this.metSpecies = source.metSpecies; this.metWave = source.metWave ?? (this.metBiome === -1 ? -1 : 0); - this.luck = source.luck !== undefined ? source.luck : source.shiny ? source.variant + 1 : 0; - if (!forHistory) { - this.pauseEvolutions = !!source.pauseEvolutions; - this.evoCounter = source.evoCounter ?? 0; - } + this.luck = source.luck ?? (source.shiny ? source.variant + 1 : 0); + this.pauseEvolutions = !!source.pauseEvolutions; this.pokerus = !!source.pokerus; - this.teraType = source.teraType as PokemonType; - this.isTerastallized = source.isTerastallized || false; - this.stellarTypesBoosted = source.stellarTypesBoosted || []; - - this.fusionSpecies = sourcePokemon ? sourcePokemon.fusionSpecies?.speciesId : source.fusionSpecies; - this.fusionFormIndex = source.fusionFormIndex; - this.fusionAbilityIndex = source.fusionAbilityIndex; - this.fusionShiny = sourcePokemon - ? (!!sourcePokemon.summonData?.illusion ? sourcePokemon.summonData.illusion.basePokemon.fusionShiny : sourcePokemon.fusionShiny) - : source.fusionShiny; - this.fusionVariant = sourcePokemon - ? (!!sourcePokemon.summonData?.illusion ? sourcePokemon.summonData.illusion.basePokemon.fusionVariant : sourcePokemon.fusionVariant) - : source.fusionVariant; - this.fusionGender = source.fusionGender; - this.fusionLuck = - source.fusionLuck !== undefined ? source.fusionLuck : source.fusionShiny ? source.fusionVariant + 1 : 0; - this.fusionCustomPokemonData = new CustomPokemonData(source.fusionCustomPokemonData); - this.fusionTeraType = (source.fusionTeraType ?? 0) as PokemonType; this.usedTMs = source.usedTMs ?? []; - - this.customPokemonData = new CustomPokemonData(source.customPokemonData); + this.evoCounter = source.evoCounter ?? 0; + this.teraType = source.teraType as PokemonType; + this.isTerastallized = !!source.isTerastallized; + this.stellarTypesBoosted = source.stellarTypesBoosted ?? []; // Deprecated, but needed for session data migration this.natureOverride = source.natureOverride; @@ -143,52 +129,25 @@ export default class PokemonData { ? new CustomPokemonData(source.fusionMysteryEncounterPokemonData) : null; - if (!forHistory) { - this.boss = (source instanceof EnemyPokemon && !!source.bossSegments) || (!this.player && !!source.boss); - this.bossSegments = source.bossSegments; - } + this.fusionSpecies = sourcePokemon?.fusionSpecies?.speciesId ?? source.fusionSpecies; + this.fusionFormIndex = source.fusionFormIndex; + this.fusionAbilityIndex = source.fusionAbilityIndex; + this.fusionShiny = sourcePokemon?.summonData.illusion?.basePokemon.fusionShiny ?? source.fusionShiny; + this.fusionVariant = sourcePokemon?.summonData.illusion?.basePokemon.fusionVariant ?? source.fusionVariant; + this.fusionGender = source.fusionGender; + this.fusionLuck = source.fusionLuck ?? (source.fusionShiny ? source.fusionVariant + 1 : 0); + this.fusionTeraType = (source.fusionTeraType ?? 0) as PokemonType; - if (sourcePokemon) { - this.moveset = sourcePokemon.moveset; - if (!forHistory) { - this.status = sourcePokemon.status; - if (this.player && sourcePokemon.summonData) { - this.summonData = sourcePokemon.summonData; - this.summonDataSpeciesFormIndex = this.getSummonDataSpeciesFormIndex(); - } - } - } else { - this.moveset = (source.moveset || [new PokemonMove(Moves.TACKLE), new PokemonMove(Moves.GROWL)]) - .filter(m => m) - .map((m: any) => new PokemonMove(m.moveId, m.ppUsed, m.ppUp, m.virtual, m.maxPpOverride)); - if (!forHistory) { - this.status = source.status - ? new Status(source.status.effect, source.status.toxicTurnCount, source.status.sleepTurnsRemaining) - : null; - } + this.boss = (source instanceof EnemyPokemon && !!source.bossSegments) || (!this.player && !!source.boss); + this.bossSegments = source.bossSegments ?? 0; - this.summonData = new PokemonSummonData(); - if (!forHistory && source.summonData) { - this.summonData.stats = source.summonData.stats; - this.summonData.statStages = source.summonData.statStages; - this.summonData.moveQueue = source.summonData.moveQueue; - this.summonData.abilitySuppressed = source.summonData.abilitySuppressed; - this.summonData.abilitiesApplied = source.summonData.abilitiesApplied; + this.summonData = new PokemonSummonData(source.summonData); + this.battleData = new PokemonBattleData(source.battleData); + this.summonDataSpeciesFormIndex = + sourcePokemon?.summonData.speciesForm?.formIndex ?? source.summonDataSpeciesFormIndex; - this.summonData.ability = source.summonData.ability; - this.summonData.moveset = source.summonData.moveset?.map(m => PokemonMove.loadMove(m)); - this.summonData.types = source.summonData.types; - this.summonData.speciesForm = source.summonData.speciesForm; - this.summonDataSpeciesFormIndex = source.summonDataSpeciesFormIndex; - this.summonData.illusionBroken = source.summonData.illusionBroken; - - if (source.summonData.tags) { - this.summonData.tags = source.summonData.tags?.map(t => loadBattlerTag(t)); - } else { - this.summonData.tags = []; - } - } - } + this.customPokemonData = new CustomPokemonData(source.customPokemonData); + this.fusionCustomPokemonData = new CustomPokemonData(source.fusionCustomPokemonData); } toPokemon(battleType?: BattleType, partyMemberIndex = 0, double = false): Pokemon { @@ -223,30 +182,15 @@ export default class PokemonData { false, this, ); - if (this.summonData) { - // when loading from saved session, recover summonData.speciesFrom and form index species object - // used to stay transformed on reload session - if (this.summonData.speciesForm) { - this.summonData.speciesForm = getPokemonSpeciesForm( - this.summonData.speciesForm.speciesId, - this.summonDataSpeciesFormIndex, - ); - } - ret.primeSummonData(this.summonData); + // when loading from saved session, recover summonData.speciesFrom and form index species object + // used to stay transformed on reload session + if (this.summonData.speciesForm) { + this.summonData.speciesForm = getPokemonSpeciesForm( + this.summonData.speciesForm.speciesId, + this.summonDataSpeciesFormIndex, + ); } return ret; } - - /** - * Method to save summon data species form index - * Necessary in case the pokemon is transformed - * to reload the correct form - */ - getSummonDataSpeciesFormIndex(): number { - if (this.summonData.speciesForm) { - return this.summonData.speciesForm.formIndex; - } - return 0; - } } diff --git a/src/system/version_migration/version_converter.ts b/src/system/version_migration/version_converter.ts index 1fdb9e93f88..798115e0395 100644 --- a/src/system/version_migration/version_converter.ts +++ b/src/system/version_migration/version_converter.ts @@ -59,6 +59,10 @@ import * as v1_7_0 from "./versions/v1_7_0"; // biome-ignore lint/style/noNamespaceImport: Convenience import * as v1_8_3 from "./versions/v1_8_3"; +// --- v1.9.0 PATCHES --- // +// biome-ignore lint/style/noNamespaceImport: Convenience +import * as v1_9_0 from "./versions/v1_9_0"; + /** Current game version */ const LATEST_VERSION = version; @@ -80,6 +84,7 @@ systemMigrators.push(...v1_8_3.systemMigrators); const sessionMigrators: SessionSaveMigrator[] = []; sessionMigrators.push(...v1_0_4.sessionMigrators); sessionMigrators.push(...v1_7_0.sessionMigrators); +sessionMigrators.push(...v1_9_0.sessionMigrators); /** All settings migrators */ const settingsMigrators: SettingsSaveMigrator[] = []; diff --git a/src/system/version_migration/versions/v1_9_0.ts b/src/system/version_migration/versions/v1_9_0.ts new file mode 100644 index 00000000000..9505a7138f8 --- /dev/null +++ b/src/system/version_migration/versions/v1_9_0.ts @@ -0,0 +1,47 @@ +import type { SessionSaveMigrator } from "#app/@types/SessionSaveMigrator"; +import { Status } from "#app/data/status-effect"; +import { PokemonMove } from "#app/field/pokemon"; +import type { SessionSaveData } from "#app/system/game-data"; +import type PokemonData from "#app/system/pokemon-data"; +import { Moves } from "#enums/moves"; + +/** + * Migrate all lingering rage fist data inside `CustomPokemonData`, + * as well as enforcing default values across the board. + * @param data - {@linkcode SystemSaveData} + */ +const migratePartyData: SessionSaveMigrator = { + version: "1.9.0", + migrate: (data: SessionSaveData): void => { + // this stuff is copied straight from the constructor fwiw + const mapParty = (pkmnData: PokemonData) => { + pkmnData.status &&= new Status( + pkmnData.status.effect, + pkmnData.status.toxicTurnCount, + pkmnData.status.sleepTurnsRemaining, + ); + // remove empty moves from moveset + pkmnData.moveset = (pkmnData.moveset ?? [new PokemonMove(Moves.TACKLE), new PokemonMove(Moves.GROWL)]) + .filter(m => !!m) + .map(m => PokemonMove.loadMove(m)); + // only edit summondata moveset if exists + pkmnData.summonData.moveset &&= pkmnData.summonData.moveset.filter(m => !!m).map(m => PokemonMove.loadMove(m)); + + if ( + pkmnData.customPokemonData && + "hitsRecCount" in pkmnData.customPokemonData && + typeof pkmnData.customPokemonData["hitsRecCount"] === "number" + ) { + // transfer old hit count stat to battleData. + pkmnData.battleData.hitCount = pkmnData.customPokemonData["hitsRecCount"]; + pkmnData.customPokemonData["hitsRecCount"] = null; + } + return pkmnData; + }; + + data.party = data.party.map(mapParty); + data.enemyParty = data.enemyParty.map(mapParty); + }, +}; + +export const sessionMigrators: Readonly = [migratePartyData] as const; diff --git a/src/ui/battle-info.ts b/src/ui/battle-info.ts index 99a91a9330e..cabe897d7b6 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.summonData?.illusion ? pokemon.summonData?.illusion.gender : pokemon.gender; + const gender = 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.summonData?.illusion ? pokemon.summonData?.illusion.gender : pokemon.gender; + const gender = pokemon.summonData.illusion?.gender ?? pokemon.gender; while ( nameTextWidth > (this.player || !this.boss ? 60 : 98) - diff --git a/src/ui/fight-ui-handler.ts b/src/ui/fight-ui-handler.ts index e0a73d62934..5a0978a934d 100644 --- a/src/ui/fight-ui-handler.ts +++ b/src/ui/fight-ui-handler.ts @@ -127,7 +127,7 @@ export default class FightUiHandler extends UiHandler implements InfoToggle { messageHandler.commandWindow.setVisible(false); messageHandler.movesWindowContainer.setVisible(true); const pokemon = (globalScene.getCurrentPhase() as CommandPhase).getPokemon(); - if (pokemon.battleSummonData.turnCount <= 1) { + if (pokemon.tempSummonData.turnCount <= 1) { this.setCursor(0); } else { this.setCursor(this.getCursor()); @@ -305,7 +305,7 @@ export default class FightUiHandler extends UiHandler implements InfoToggle { const effectiveness = opponent.getMoveEffectiveness( pokemon, pokemonMove.getMove(), - !opponent.battleData?.abilityRevealed, + !opponent.waveData.abilityRevealed, undefined, undefined, true, @@ -356,7 +356,7 @@ export default class FightUiHandler extends UiHandler implements InfoToggle { opponent.getMoveEffectiveness( pokemon, pokemonMove.getMove(), - !opponent.battleData.abilityRevealed, + !opponent.waveData.abilityRevealed, undefined, undefined, true, diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index 7c3689e757c..6e947796d63 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.summonData?.illusion?.basePokemon.fusionVariant ?? this.pokemon.fusionVariant), + getVariantTint(this.pokemon.summonData.illusion?.basePokemon.fusionVariant ?? this.pokemon.fusionVariant), ); slotInfoContainer.add(fusionShinyStar); diff --git a/src/ui/registration-form-ui-handler.ts b/src/ui/registration-form-ui-handler.ts index 3d4613c21d6..a60a53a8e7a 100644 --- a/src/ui/registration-form-ui-handler.ts +++ b/src/ui/registration-form-ui-handler.ts @@ -102,9 +102,9 @@ export default class RegistrationFormUiHandler extends FormModalUiHandler { // Prevent overlapping overrides on action modification this.submitAction = originalRegistrationAction; this.sanitizeInputs(); - globalScene.ui.setMode(UiMode.LOADING, { buttonActions: [] }); + globalScene.ui.setMode(UiMode.LOADING, { buttonActions: [] }); const onFail = error => { - globalScene.ui.setMode(UiMode.REGISTRATION_FORM, Object.assign(config, { errorMessage: error?.trim() })); + globalScene.ui.setMode(UiMode.REGISTRATION_FORM, Object.assign(config, { errorMessage: error?.trim() })); globalScene.ui.playError(); const errorMessageFontSize = languageSettings[i18next.resolvedLanguage!]?.errorMessageFontSize; if (errorMessageFontSize) { diff --git a/src/ui/summary-ui-handler.ts b/src/ui/summary-ui-handler.ts index 877c342651f..f93a1826b3e 100644 --- a/src/ui/summary-ui-handler.ts +++ b/src/ui/summary-ui-handler.ts @@ -359,15 +359,15 @@ export default class SummaryUiHandler extends UiHandler { this.pokemonSprite.setPipelineData("spriteKey", this.pokemon.getSpriteKey()); this.pokemonSprite.setPipelineData( "shiny", - this.pokemon.summonData?.illusion?.basePokemon.shiny ?? this.pokemon.shiny, + this.pokemon.summonData.illusion?.basePokemon.shiny ?? this.pokemon.shiny, ); this.pokemonSprite.setPipelineData( "variant", - this.pokemon.summonData?.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`]; - if (this.pokemon?.summonData?.speciesForm) { + if (this.pokemon?.summonData.speciesForm) { k += "Base"; } this.pokemonSprite.pipelineData[k] = this.pokemon?.getSprite().pipelineData[k]; @@ -462,7 +462,7 @@ export default class SummaryUiHandler extends UiHandler { this.fusionShinyIcon.setVisible(doubleShiny); if (isFusion) { this.fusionShinyIcon.setTint( - getVariantTint(this.pokemon.summonData?.illusion?.basePokemon.fusionVariant ?? this.pokemon.fusionVariant), + getVariantTint(this.pokemon.summonData.illusion?.basePokemon.fusionVariant ?? this.pokemon.fusionVariant), ); } diff --git a/src/ui/target-select-ui-handler.ts b/src/ui/target-select-ui-handler.ts index 0db2020c25a..5e14e5f7771 100644 --- a/src/ui/target-select-ui-handler.ts +++ b/src/ui/target-select-ui-handler.ts @@ -71,7 +71,7 @@ export default class TargetSelectUiHandler extends UiHandler { */ resetCursor(cursorN: number, user: Pokemon): void { if (!isNullOrUndefined(cursorN)) { - if ([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2].includes(cursorN) || user.battleSummonData.waveTurnCount === 1) { + if ([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2].includes(cursorN) || user.tempSummonData.waveTurnCount === 1) { // Reset cursor on the first turn of a fight or if an ally was targeted last turn cursorN = -1; } diff --git a/src/utils/common.ts b/src/utils/common.ts index 6984840fb5c..4cf7ceccff2 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -467,35 +467,22 @@ export function truncateString(str: string, maxLength = 10) { return str; } -/** - * Perform a deep copy of an object. - * - * @param values - The object to be deep copied. - * @returns A new object that is a deep copy of the input. - */ -export function deepCopy(values: object): object { - // Convert the object to a JSON string and parse it back to an object to perform a deep copy - return JSON.parse(JSON.stringify(values)); -} - /** * Convert a space-separated string into a capitalized and underscored string. - * * @param input - The string to be converted. * @returns The converted string with words capitalized and separated by underscores. */ -export function reverseValueToKeySetting(input) { +export function reverseValueToKeySetting(input: string) { // Split the input string into an array of words const words = input.split(" "); // Capitalize the first letter of each word and convert the rest to lowercase - const capitalizedWords = words.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()); + const capitalizedWords = words.map((word: string) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()); // Join the capitalized words with underscores and return the result return capitalizedWords.join("_"); } /** * Capitalize a string. - * * @param str - The string to be capitalized. * @param sep - The separator between the words of the string. * @param lowerFirstChar - Whether the first character of the string should be lowercase or not. @@ -579,25 +566,3 @@ export function animationFileName(move: Moves): string { export function camelCaseToKebabCase(str: string): string { return str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, (s, o) => (o ? "-" : "") + s.toLowerCase()); } - -/** - * Merges the two objects, such that for each property in `b` that matches a property in `a`, - * the value in `a` is replaced by the value in `b`. This is done recursively if the property is a non-array object - * - * If the property does not exist in `a` or its `typeof` evaluates differently, the property is skipped. - * If the value of the property is an array, the array is replaced. If it is any other object, the object is merged recursively. - */ -// biome-ignore lint/complexity/noBannedTypes: This function is designed to merge json objects -export function deepMergeObjects(a: Object, b: Object) { - for (const key in b) { - // !(key in a) is redundant here, yet makes it clear that we're explicitly interested in properties that exist in `a` - if (!(key in a) || typeof a[key] !== typeof b[key]) { - continue; - } - if (typeof b[key] === "object" && !Array.isArray(b[key])) { - deepMergeObjects(a[key], b[key]); - } else { - a[key] = b[key]; - } - } -} diff --git a/src/utils/data.ts b/src/utils/data.ts new file mode 100644 index 00000000000..33623dc5e40 --- /dev/null +++ b/src/utils/data.ts @@ -0,0 +1,40 @@ +/** + * Perform a deep copy of an object. + * @param values - The object to be deep copied. + * @returns A new object that is a deep copy of the input. + */ +export function deepCopy(values: object): object { + // Convert the object to a JSON string and parse it back to an object to perform a deep copy + return JSON.parse(JSON.stringify(values)); +} + +/** + * Deeply merge two JSON objects' common properties together. + * This copies all values from `source` that match properties inside `dest`, + * checking recursively for non-null nested objects. + + * If a property in `source` does not exist in `dest` or its `typeof` evaluates differently, it is skipped. + * If it is a non-array object, its properties are recursed into and checked in turn. + * All other values are copied verbatim. + * @param dest - The object to merge values into + * @param source - The object to source merged values from + * @remarks Do not use for regular objects; this is specifically made for JSON copying. + */ +export function deepMergeSpriteData(dest: object, source: object) { + for (const key of Object.keys(source)) { + if ( + !(key in dest) || + typeof source[key] !== typeof dest[key] || + Array.isArray(source[key]) !== Array.isArray(dest[key]) + ) { + continue; + } + + // Pure objects get recursed into; everything else gets overwritten + if (typeof source[key] !== "object" || source[key] === null || Array.isArray(source[key])) { + dest[key] = source[key]; + } else { + deepMergeSpriteData(dest[key], source[key]); + } + } +} diff --git a/test/abilities/cud_chew.test.ts b/test/abilities/cud_chew.test.ts new file mode 100644 index 00000000000..f99060cb744 --- /dev/null +++ b/test/abilities/cud_chew.test.ts @@ -0,0 +1,322 @@ +import { RepeatBerryNextTurnAbAttr } from "#app/data/abilities/ability"; +import Pokemon from "#app/field/pokemon"; +import { globalScene } from "#app/global-scene"; +import { getPokemonNameWithAffix } from "#app/messages"; +import { Abilities } from "#enums/abilities"; +import { BerryType } from "#enums/berry-type"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { Stat } from "#enums/stat"; +import GameManager from "#test/testUtils/gameManager"; +import i18next from "i18next"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; + +describe("Abilities - Cud Chew", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([Moves.BUG_BITE, Moves.SPLASH, Moves.HYPER_VOICE, Moves.STUFF_CHEEKS]) + .startingHeldItems([{ name: "BERRY", type: BerryType.SITRUS, count: 1 }]) + .ability(Abilities.CUD_CHEW) + .battleStyle("single") + .disableCrits() + .enemySpecies(Species.MAGIKARP) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + describe("tracks berries eaten", () => { + it("stores inside summonData at end of turn", async () => { + await game.classicMode.startBattle([Species.FARIGIRAF]); + + const farigiraf = game.scene.getPlayerPokemon()!; + farigiraf.hp = 1; // needed to allow sitrus procs + + game.move.select(Moves.SPLASH); + await game.phaseInterceptor.to("BerryPhase"); + + // berries tracked in turnData; not moved to battleData yet + expect(farigiraf.summonData.berriesEatenLast).toEqual([]); + expect(farigiraf.turnData.berriesEaten).toEqual([BerryType.SITRUS]); + + await game.phaseInterceptor.to("TurnEndPhase"); + + // berries stored in battleData; not yet cleared from turnData + expect(farigiraf.summonData.berriesEatenLast).toEqual([BerryType.SITRUS]); + expect(farigiraf.turnData.berriesEaten).toEqual([BerryType.SITRUS]); + + await game.toNextTurn(); + + // turnData cleared on turn start + expect(farigiraf.summonData.berriesEatenLast).toEqual([BerryType.SITRUS]); + expect(farigiraf.turnData.berriesEaten).toEqual([]); + }); + + it("shows ability popup for eating berry, even if berry is useless", async () => { + const abDisplaySpy = vi.spyOn(globalScene, "queueAbilityDisplay"); + game.override.enemyMoveset([Moves.SPLASH, Moves.HEAL_PULSE]); + await game.classicMode.startBattle([Species.FARIGIRAF]); + + const farigiraf = game.scene.getPlayerPokemon()!; + // Dip below half to eat berry + farigiraf.hp = farigiraf.getMaxHp() / 2 - 1; + + game.move.select(Moves.SPLASH); + await game.forceEnemyMove(Moves.SPLASH); + await game.phaseInterceptor.to("TurnEndPhase"); + + // doesn't trigger since cud chew hasn't eaten berry yet + expect(farigiraf.summonData.berriesEatenLast).toContain(BerryType.SITRUS); + expect(abDisplaySpy).not.toHaveBeenCalledWith(farigiraf); + await game.toNextTurn(); + + // get heal pulsed back to full before the cud chew proc + game.move.select(Moves.SPLASH); + await game.forceEnemyMove(Moves.HEAL_PULSE); + await game.phaseInterceptor.to("TurnEndPhase"); + + // globalScene.queueAbilityDisplay should be called twice: + // once to show cud chew text before regurgitating berries, + // once to hide ability text after finishing. + expect(abDisplaySpy).toBeCalledTimes(2); + expect(abDisplaySpy.mock.calls[0][0]).toBe(farigiraf); + expect(abDisplaySpy.mock.calls[0][2]).toBe(true); + expect(abDisplaySpy.mock.calls[1][0]).toBe(farigiraf); + expect(abDisplaySpy.mock.calls[1][2]).toBe(false); + + // should display messgae + expect(game.textInterceptor.getLatestMessage()).toBe( + i18next.t("battle:hpIsFull", { + pokemonName: getPokemonNameWithAffix(farigiraf), + }), + ); + + // not called again at turn end + expect(abDisplaySpy).toBeCalledTimes(2); + }); + + it("can store multiple berries across 2 turns with teatime", async () => { + // always eat first berry for stuff cheeks & company + vi.spyOn(Pokemon.prototype, "randSeedInt").mockReturnValue(0); + game.override + .startingHeldItems([ + { name: "BERRY", type: BerryType.PETAYA, count: 3 }, + { name: "BERRY", type: BerryType.LIECHI, count: 3 }, + ]) + .enemyMoveset(Moves.TEATIME); + await game.classicMode.startBattle([Species.FARIGIRAF]); + + const farigiraf = game.scene.getPlayerPokemon()!; + farigiraf.hp = 1; // needed to allow berry procs + + game.move.select(Moves.STUFF_CHEEKS); + await game.toNextTurn(); + + // Ate 2 petayas from moves + 1 of each at turn end; all 4 get tallied on turn end + expect(farigiraf.summonData.berriesEatenLast).toEqual([ + BerryType.PETAYA, + BerryType.PETAYA, + BerryType.PETAYA, + BerryType.LIECHI, + ]); + expect(farigiraf.turnData.berriesEaten).toEqual([]); + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + // previous berries eaten and deleted from summon data as remaining eaten berries move to replace them + expect(farigiraf.summonData.berriesEatenLast).toEqual([BerryType.LIECHI, BerryType.LIECHI]); + expect(farigiraf.turnData.berriesEaten).toEqual([]); + expect(farigiraf.getStatStage(Stat.SPATK)).toBe(6); // 3+0+3 + expect(farigiraf.getStatStage(Stat.ATK)).toBe(4); // 1+2+1 + }); + + it("should reset both arrays on switch", async () => { + await game.classicMode.startBattle([Species.FARIGIRAF, Species.GIRAFARIG]); + + const farigiraf = game.scene.getPlayerPokemon()!; + farigiraf.hp = 1; + + // eat berry turn 1, switch out turn 2 + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + const turn1Hp = farigiraf.hp; + game.doSwitchPokemon(1); + await game.toNextTurn(); + + // summonData got cleared due to switch, turnData got cleared due to turn end + expect(farigiraf.summonData.berriesEatenLast).toEqual([]); + expect(farigiraf.turnData.berriesEaten).toEqual([]); + expect(farigiraf.hp).toEqual(turn1Hp); + + game.doSwitchPokemon(1); + await game.toNextTurn(); + + // TurnData gets cleared while switching in + expect(farigiraf.summonData.berriesEatenLast).toEqual([]); + expect(farigiraf.turnData.berriesEaten).toEqual([]); + expect(farigiraf.hp).toEqual(turn1Hp); + }); + + it("clears array if disabled", async () => { + game.override.enemyAbility(Abilities.NEUTRALIZING_GAS); + await game.classicMode.startBattle([Species.FARIGIRAF]); + + const farigiraf = game.scene.getPlayerPokemon()!; + farigiraf.hp = 1; + + game.move.select(Moves.SPLASH); + await game.phaseInterceptor.to("BerryPhase"); + + expect(farigiraf.summonData.berriesEatenLast).toEqual([]); + expect(farigiraf.turnData.berriesEaten).toEqual([BerryType.SITRUS]); + + await game.toNextTurn(); + + // both arrays empty since neut gas disabled both the mid-turn and post-turn effects + expect(farigiraf.summonData.berriesEatenLast).toEqual([]); + expect(farigiraf.turnData.berriesEaten).toEqual([]); + }); + }); + + describe("regurgiates berries", () => { + it("re-triggers effects on eater without pushing to array", async () => { + const apply = vi.spyOn(RepeatBerryNextTurnAbAttr.prototype, "apply"); + await game.classicMode.startBattle([Species.FARIGIRAF]); + + const farigiraf = game.scene.getPlayerPokemon()!; + farigiraf.hp = 1; + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + // ate 1 sitrus the turn prior, spitball pending + expect(farigiraf.summonData.berriesEatenLast).toEqual([BerryType.SITRUS]); + expect(farigiraf.turnData.berriesEaten).toEqual([]); + expect(apply.mock.lastCall).toBeUndefined(); + + const turn1Hp = farigiraf.hp; + + game.move.select(Moves.SPLASH); + await game.phaseInterceptor.to("TurnEndPhase"); + + // healed back up to half without adding any more to array + expect(farigiraf.hp).toBeGreaterThan(turn1Hp); + expect(farigiraf.summonData.berriesEatenLast).toEqual([]); + expect(farigiraf.turnData.berriesEaten).toEqual([]); + }); + + it("bypasses unnerve", async () => { + game.override.enemyAbility(Abilities.UNNERVE); + await game.classicMode.startBattle([Species.FARIGIRAF]); + + const farigiraf = game.scene.getPlayerPokemon()!; + farigiraf.hp = 1; + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + game.move.select(Moves.SPLASH); + await game.phaseInterceptor.to("TurnEndPhase"); + + // Turn end proc set the berriesEatenLast array back to being empty + expect(farigiraf.summonData.berriesEatenLast).toEqual([]); + expect(farigiraf.turnData.berriesEaten).toEqual([]); + expect(farigiraf.hp).toBeGreaterThanOrEqual(farigiraf.hp / 2); + }); + + it("doesn't trigger on non-eating removal", async () => { + game.override.enemyMoveset(Moves.INCINERATE); + await game.classicMode.startBattle([Species.FARIGIRAF]); + + const farigiraf = game.scene.getPlayerPokemon()!; + farigiraf.hp = farigiraf.getMaxHp() / 4; + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + // no berries eaten due to getting cooked + expect(farigiraf.summonData.berriesEatenLast).toEqual([]); + expect(farigiraf.turnData.berriesEaten).toEqual([]); + expect(farigiraf.hp).toBeLessThan(farigiraf.getMaxHp() / 4); + }); + + it("works with pluck", async () => { + game.override + .enemySpecies(Species.BLAZIKEN) + .enemyHeldItems([{ name: "BERRY", type: BerryType.PETAYA, count: 1 }]) + .startingHeldItems([]); + await game.classicMode.startBattle([Species.FARIGIRAF]); + + const farigiraf = game.scene.getPlayerPokemon()!; + + game.move.select(Moves.BUG_BITE); + await game.toNextTurn(); + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + // berry effect triggered twice - once for bug bite, once for cud chew + expect(farigiraf.getStatStage(Stat.SPATK)).toBe(2); + }); + + it("works with Ripen", async () => { + game.override.passiveAbility(Abilities.RIPEN); + await game.classicMode.startBattle([Species.FARIGIRAF]); + + const farigiraf = game.scene.getPlayerPokemon()!; + farigiraf.hp = 1; + + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + // Rounding errors only ever cost a maximum of 4 hp + expect(farigiraf.getInverseHp()).toBeLessThanOrEqual(3); + }); + + it("is preserved on reload/wave clear", async () => { + game.override.enemyLevel(1); + await game.classicMode.startBattle([Species.FARIGIRAF]); + + const farigiraf = game.scene.getPlayerPokemon()!; + farigiraf.hp = 1; + + game.move.select(Moves.HYPER_VOICE); + await game.toNextWave(); + + // berry went yummy yummy in big fat giraffe tummy + expect(farigiraf.summonData.berriesEatenLast).toEqual([BerryType.SITRUS]); + expect(farigiraf.hp).toBeGreaterThan(1); + + // reload and the berry should still be there + await game.reload.reloadSession(); + + const farigirafReloaded = game.scene.getPlayerPokemon()!; + expect(farigirafReloaded.summonData.berriesEatenLast).toEqual([BerryType.SITRUS]); + + const wave1Hp = farigirafReloaded.hp; + + // blow up next wave and we should proc the repeat eating + game.move.select(Moves.HYPER_VOICE); + await game.toNextWave(); + + expect(farigirafReloaded.hp).toBeGreaterThan(wave1Hp); + }); + }); +}); diff --git a/test/abilities/good_as_gold.test.ts b/test/abilities/good_as_gold.test.ts index 944c1d1bca1..09bdaafb11f 100644 --- a/test/abilities/good_as_gold.test.ts +++ b/test/abilities/good_as_gold.test.ts @@ -49,7 +49,7 @@ describe("Abilities - Good As Gold", () => { await game.phaseInterceptor.to("BerryPhase"); - expect(player.battleData.abilitiesApplied[0]).toBe(Abilities.GOOD_AS_GOLD); + expect(player.waveData.abilitiesApplied).toContain(Abilities.GOOD_AS_GOLD); expect(player.getStatStage(Stat.ATK)).toBe(0); }); diff --git a/test/abilities/harvest.test.ts b/test/abilities/harvest.test.ts new file mode 100644 index 00000000000..23c0ed9088c --- /dev/null +++ b/test/abilities/harvest.test.ts @@ -0,0 +1,346 @@ +import { BattlerIndex } from "#app/battle"; +import { PostTurnRestoreBerryAbAttr } from "#app/data/abilities/ability"; +import type Pokemon from "#app/field/pokemon"; +import { BerryModifier, PreserveBerryModifier } from "#app/modifier/modifier"; +import type { ModifierOverride } from "#app/modifier/modifier-type"; +import type { BooleanHolder } from "#app/utils/common"; +import { Abilities } from "#enums/abilities"; +import { BerryType } from "#enums/berry-type"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { Stat } from "#enums/stat"; +import { WeatherType } from "#enums/weather-type"; +import GameManager from "#test/testUtils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; + +describe("Abilities - Harvest", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + const getPlayerBerries = () => + game.scene.getModifiers(BerryModifier, true).filter(b => b.pokemonId === game.scene.getPlayerPokemon()?.id); + + /** Check whether the player's Modifiers contains the specified berries and nothing else. */ + function expectBerriesContaining(...berries: ModifierOverride[]): void { + const actualBerries: ModifierOverride[] = getPlayerBerries().map( + // only grab berry type and quantity since that's literally all we care about + b => ({ name: "BERRY", type: b.berryType, count: b.getStackCount() }), + ); + expect(actualBerries).toEqual(berries); + } + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([Moves.SPLASH, Moves.NATURAL_GIFT, Moves.FALSE_SWIPE, Moves.GASTRO_ACID]) + .ability(Abilities.HARVEST) + .startingLevel(100) + .battleStyle("single") + .disableCrits() + .statusActivation(false) // Since we're using nuzzle to proc both enigma and sitrus berries + .weather(WeatherType.SUNNY) // guaranteed recovery + .enemyLevel(1) + .enemySpecies(Species.MAGIKARP) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset([Moves.SPLASH, Moves.NUZZLE, Moves.KNOCK_OFF, Moves.INCINERATE]); + }); + + it("replenishes eaten berries", async () => { + game.override.startingHeldItems([{ name: "BERRY", type: BerryType.LUM, count: 1 }]); + await game.classicMode.startBattle([Species.FEEBAS]); + + game.move.select(Moves.SPLASH); + await game.forceEnemyMove(Moves.NUZZLE); + await game.phaseInterceptor.to("BerryPhase"); + expect(getPlayerBerries()).toHaveLength(0); + expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toHaveLength(1); + await game.phaseInterceptor.to("TurnEndPhase"); + + expectBerriesContaining({ name: "BERRY", type: BerryType.LUM, count: 1 }); + expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toEqual([]); + }); + + it("tracks berries eaten while disabled/not present", async () => { + // Note: this also checks for harvest not being present as neutralizing gas works by making + // the game consider all other pokemon to *not* have their respective abilities. + game.override + .startingHeldItems([ + { name: "BERRY", type: BerryType.ENIGMA, count: 2 }, + { name: "BERRY", type: BerryType.LUM, count: 2 }, + ]) + .enemyAbility(Abilities.NEUTRALIZING_GAS); + await game.classicMode.startBattle([Species.MILOTIC]); + + const milotic = game.scene.getPlayerPokemon()!; + expect(milotic).toBeDefined(); + + // Chug a few berries without harvest (should get tracked) + game.move.select(Moves.SPLASH); + await game.forceEnemyMove(Moves.NUZZLE); + await game.toNextTurn(); + + expect(milotic.battleData.berriesEaten).toEqual(expect.arrayContaining([BerryType.ENIGMA, BerryType.LUM])); + expect(getPlayerBerries()).toHaveLength(2); + + // Give ourselves harvest and disable enemy neut gas, + // but force our roll to fail so we don't accidentally recover anything + vi.spyOn(PostTurnRestoreBerryAbAttr.prototype, "canApplyPostTurn").mockReturnValueOnce(false); + game.override.ability(Abilities.HARVEST); + game.move.select(Moves.GASTRO_ACID); + await game.forceEnemyMove(Moves.NUZZLE); + + await game.toNextTurn(); + + expect(milotic.battleData.berriesEaten).toEqual( + expect.arrayContaining([BerryType.ENIGMA, BerryType.LUM, BerryType.ENIGMA, BerryType.LUM]), + ); + expect(getPlayerBerries()).toHaveLength(0); + + // proc a high roll and we _should_ get a berry back! + game.move.select(Moves.SPLASH); + await game.forceEnemyMove(Moves.SPLASH); + await game.toNextTurn(); + + expect(milotic.battleData.berriesEaten).toHaveLength(3); + expect(getPlayerBerries()).toHaveLength(1); + }); + + it("remembers berries eaten array across waves", async () => { + game.override + .startingHeldItems([{ name: "BERRY", type: BerryType.PETAYA, count: 2 }]) + .ability(Abilities.BALL_FETCH); // don't actually need harvest for this test + await game.classicMode.startBattle([Species.REGIELEKI]); + + const regieleki = game.scene.getPlayerPokemon()!; + regieleki.hp = 1; + + game.move.select(Moves.SPLASH); + await game.forceEnemyMove(Moves.SPLASH); + await game.doKillOpponents(); + await game.phaseInterceptor.to("TurnEndPhase"); + + // ate 1 berry without recovering (no harvest) + expect(regieleki.battleData.berriesEaten).toEqual([BerryType.PETAYA]); + expectBerriesContaining({ name: "BERRY", count: 1, type: BerryType.PETAYA }); + expect(regieleki.getStatStage(Stat.SPATK)).toBe(1); + + await game.toNextWave(); + + expect(regieleki.battleData.berriesEaten).toEqual([BerryType.PETAYA]); + expectBerriesContaining({ name: "BERRY", count: 1, type: BerryType.PETAYA }); + expect(regieleki.getStatStage(Stat.SPATK)).toBe(1); + }); + + it("keeps harvested berries across reloads", async () => { + game.override + .startingHeldItems([{ name: "BERRY", type: BerryType.PETAYA, count: 1 }]) + .moveset([Moves.SPLASH, Moves.EARTHQUAKE]) + .enemyMoveset([Moves.SUPER_FANG, Moves.HEAL_PULSE]) + .enemyAbility(Abilities.COMPOUND_EYES); + await game.classicMode.startBattle([Species.REGIELEKI]); + + const regieleki = game.scene.getPlayerPokemon()!; + regieleki.hp = regieleki.getMaxHp() / 4 + 1; + + game.move.select(Moves.SPLASH); + await game.forceEnemyMove(Moves.SUPER_FANG); + await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.toNextTurn(); + + // ate 1 berry and recovered it + expect(regieleki.battleData.berriesEaten).toEqual([]); + expect(getPlayerBerries()).toEqual([expect.objectContaining({ berryType: BerryType.PETAYA, stackCount: 1 })]); + expect(game.scene.getPlayerPokemon()?.getStatStage(Stat.SPATK)).toBe(1); + + // heal up so harvest doesn't proc and kill enemy + game.move.select(Moves.EARTHQUAKE); + await game.forceEnemyMove(Moves.HEAL_PULSE); + await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.toNextWave(); + + expectBerriesContaining({ name: "BERRY", count: 1, type: BerryType.PETAYA }); + expect(game.scene.getPlayerPokemon()?.getStatStage(Stat.SPATK)).toBe(1); + + await game.reload.reloadSession(); + + expect(regieleki.battleData.berriesEaten).toEqual([]); + expectBerriesContaining({ name: "BERRY", count: 1, type: BerryType.PETAYA }); + expect(game.scene.getPlayerPokemon()?.getStatStage(Stat.SPATK)).toBe(1); + }); + + it("cannot restore capped berries", async () => { + const initBerries: ModifierOverride[] = [ + { name: "BERRY", type: BerryType.LUM, count: 2 }, + { name: "BERRY", type: BerryType.STARF, count: 2 }, + ]; + game.override.startingHeldItems(initBerries); + await game.classicMode.startBattle([Species.FEEBAS]); + + const feebas = game.scene.getPlayerPokemon()!; + feebas.battleData.berriesEaten = [BerryType.LUM, BerryType.STARF]; + + game.move.select(Moves.SPLASH); + await game.forceEnemyMove(Moves.SPLASH); + await game.phaseInterceptor.to("BerryPhase"); + + // Force RNG roll to hit the first berry we find that matches. + // This does nothing on a success (since there'd only be a starf left to grab), + // but ensures we don't accidentally let any false positives through. + vi.spyOn(Phaser.Math.RND, "integerInRange").mockReturnValue(0); + await game.phaseInterceptor.to("TurnEndPhase"); + + // recovered a starf + expectBerriesContaining( + { name: "BERRY", type: BerryType.LUM, count: 2 }, + { name: "BERRY", type: BerryType.STARF, count: 3 }, + ); + }); + + it("does nothing if all berries are capped", async () => { + const initBerries: ModifierOverride[] = [ + { name: "BERRY", type: BerryType.LUM, count: 2 }, + { name: "BERRY", type: BerryType.STARF, count: 3 }, + ]; + game.override.startingHeldItems(initBerries); + await game.classicMode.startBattle([Species.FEEBAS]); + + const player = game.scene.getPlayerPokemon()!; + player.battleData.berriesEaten = [BerryType.LUM, BerryType.STARF]; + + game.move.select(Moves.SPLASH); + await game.forceEnemyMove(Moves.SPLASH); + await game.phaseInterceptor.to("TurnEndPhase"); + + expectBerriesContaining(...initBerries); + }); + + describe("move/ability interactions", () => { + it("cannot restore incinerated berries", async () => { + game.override.startingHeldItems([{ name: "BERRY", type: BerryType.STARF, count: 3 }]); + await game.classicMode.startBattle([Species.FEEBAS]); + + game.move.select(Moves.SPLASH); + await game.forceEnemyMove(Moves.INCINERATE); + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toEqual([]); + }); + + it("cannot restore knocked off berries", async () => { + game.override.startingHeldItems([{ name: "BERRY", type: BerryType.STARF, count: 3 }]); + await game.classicMode.startBattle([Species.FEEBAS]); + + game.move.select(Moves.SPLASH); + await game.forceEnemyMove(Moves.KNOCK_OFF); + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toEqual([]); + }); + + it("can restore berries eaten by Teatime", async () => { + const initBerries: ModifierOverride[] = [{ name: "BERRY", type: BerryType.STARF, count: 1 }]; + game.override.startingHeldItems(initBerries).enemyMoveset(Moves.TEATIME); + await game.classicMode.startBattle([Species.FEEBAS]); + + // nom nom the berr berr yay yay + game.move.select(Moves.SPLASH); + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toEqual([]); + expectBerriesContaining(...initBerries); + }); + + it("cannot restore Plucked berries for either side", async () => { + const initBerries: ModifierOverride[] = [{ name: "BERRY", type: BerryType.PETAYA, count: 1 }]; + game.override.startingHeldItems(initBerries).enemyAbility(Abilities.HARVEST).enemyMoveset(Moves.PLUCK); + await game.classicMode.startBattle([Species.FEEBAS]); + + // gobble gobble gobble + game.move.select(Moves.SPLASH); + await game.phaseInterceptor.to("BerryPhase"); + + // pluck triggers harvest for neither side + expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toEqual([]); + expect(game.scene.getEnemyPokemon()?.battleData.berriesEaten).toEqual([]); + expect(getPlayerBerries()).toEqual([]); + }); + + it("cannot restore berries preserved via Berry Pouch", async () => { + // mock berry pouch to have a 100% success rate + vi.spyOn(PreserveBerryModifier.prototype, "apply").mockImplementation( + (_pokemon: Pokemon, doPreserve: BooleanHolder): boolean => { + doPreserve.value = false; + return true; + }, + ); + + const initBerries: ModifierOverride[] = [{ name: "BERRY", type: BerryType.PETAYA, count: 1 }]; + game.override.startingHeldItems(initBerries).startingModifier([{ name: "BERRY_POUCH", count: 1 }]); + await game.classicMode.startBattle([Species.FEEBAS]); + + game.move.select(Moves.SPLASH); + await game.phaseInterceptor.to("TurnEndPhase", false); + + // won't trigger harvest since we didn't lose the berry (it just doesn't ever add it to the array) + expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toEqual([]); + expectBerriesContaining(...initBerries); + }); + + it("can restore stolen berries", async () => { + const initBerries: ModifierOverride[] = [{ name: "BERRY", type: BerryType.SITRUS, count: 1 }]; + game.override.enemyHeldItems(initBerries).passiveAbility(Abilities.MAGICIAN).hasPassiveAbility(true); + await game.classicMode.startBattle([Species.MEOWSCARADA]); + + // pre damage + const player = game.scene.getPlayerPokemon()!; + player.hp = 1; + + // steal a sitrus and immediately consume it + game.move.select(Moves.FALSE_SWIPE); + await game.forceEnemyMove(Moves.SPLASH); + await game.phaseInterceptor.to("BerryPhase"); + expect(player.battleData.berriesEaten).toEqual([BerryType.SITRUS]); + + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(player.battleData.berriesEaten).toEqual([]); + expectBerriesContaining(...initBerries); + }); + + // TODO: Enable once fling actually works...??? + it.todo("can restore berries flung at user", async () => { + game.override.enemyHeldItems([{ name: "BERRY", type: BerryType.STARF, count: 1 }]).enemyMoveset(Moves.FLING); + await game.classicMode.startBattle([Species.FEEBAS]); + + game.move.select(Moves.SPLASH); + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toBe([]); + expect(getPlayerBerries()).toEqual([]); + }); + + // TODO: Enable once Nat Gift gets implemented...??? + it.todo("can restore berries consumed via Natural Gift", async () => { + const initBerries: ModifierOverride[] = [{ name: "BERRY", type: BerryType.STARF, count: 1 }]; + game.override.startingHeldItems(initBerries); + await game.classicMode.startBattle([Species.FEEBAS]); + + game.move.select(Moves.NATURAL_GIFT); + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toHaveLength(0); + expectBerriesContaining(...initBerries); + }); + }); +}); diff --git a/test/abilities/illusion.test.ts b/test/abilities/illusion.test.ts index 1d8ce58ab38..998d29f169c 100644 --- a/test/abilities/illusion.test.ts +++ b/test/abilities/illusion.test.ts @@ -38,8 +38,8 @@ describe("Abilities - Illusion", () => { const zoroark = game.scene.getPlayerPokemon()!; const zorua = game.scene.getEnemyPokemon()!; - expect(!!zoroark.summonData?.illusion).equals(true); - expect(!!zorua.summonData?.illusion).equals(true); + expect(!!zoroark.summonData.illusion).equals(true); + expect(!!zorua.summonData.illusion).equals(true); }); it("break after receiving damaging move", async () => { @@ -50,7 +50,7 @@ describe("Abilities - Illusion", () => { const zorua = game.scene.getEnemyPokemon()!; - expect(!!zorua.summonData?.illusion).equals(false); + expect(!!zorua.summonData.illusion).equals(false); expect(zorua.name).equals("Zorua"); }); @@ -62,7 +62,7 @@ describe("Abilities - Illusion", () => { const zorua = game.scene.getEnemyPokemon()!; - expect(!!zorua.summonData?.illusion).equals(false); + expect(!!zorua.summonData.illusion).equals(false); }); it("break with neutralizing gas", async () => { @@ -71,7 +71,7 @@ describe("Abilities - Illusion", () => { const zorua = game.scene.getEnemyPokemon()!; - expect(!!zorua.summonData?.illusion).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 () => { @@ -116,7 +116,7 @@ describe("Abilities - Illusion", () => { const zoroark = game.scene.getPlayerPokemon()!; - expect(!!zoroark.summonData?.illusion).equals(true); + expect(!!zoroark.summonData.illusion).equals(true); }); it("copies the the name, nickname, gender, shininess, and pokeball from the illusion source", async () => { diff --git a/test/abilities/infiltrator.test.ts b/test/abilities/infiltrator.test.ts index 48671e54020..1a9f802dd9c 100644 --- a/test/abilities/infiltrator.test.ts +++ b/test/abilities/infiltrator.test.ts @@ -68,7 +68,7 @@ describe("Abilities - Infiltrator", () => { const postScreenDmg = enemy.getAttackDamage({ source: player, move: allMoves[move] }).damage; expect(postScreenDmg).toBe(preScreenDmg); - expect(player.battleData.abilitiesApplied[0]).toBe(Abilities.INFILTRATOR); + expect(player.waveData.abilitiesApplied).toContain(Abilities.INFILTRATOR); }); it("should bypass the target's Safeguard", async () => { @@ -83,7 +83,7 @@ describe("Abilities - Infiltrator", () => { await game.phaseInterceptor.to("BerryPhase", false); expect(enemy.status?.effect).toBe(StatusEffect.SLEEP); - expect(player.battleData.abilitiesApplied[0]).toBe(Abilities.INFILTRATOR); + expect(player.waveData.abilitiesApplied).toContain(Abilities.INFILTRATOR); }); // TODO: fix this interaction to pass this test @@ -99,7 +99,7 @@ describe("Abilities - Infiltrator", () => { await game.phaseInterceptor.to("MoveEndPhase"); expect(enemy.getStatStage(Stat.ATK)).toBe(-1); - expect(player.battleData.abilitiesApplied[0]).toBe(Abilities.INFILTRATOR); + expect(player.waveData.abilitiesApplied).toContain(Abilities.INFILTRATOR); }); it("should bypass the target's Substitute", async () => { @@ -114,6 +114,6 @@ describe("Abilities - Infiltrator", () => { await game.phaseInterceptor.to("MoveEndPhase"); expect(enemy.getStatStage(Stat.ATK)).toBe(-1); - expect(player.battleData.abilitiesApplied[0]).toBe(Abilities.INFILTRATOR); + expect(player.waveData.abilitiesApplied).toContain(Abilities.INFILTRATOR); }); }); diff --git a/test/abilities/libero.test.ts b/test/abilities/libero.test.ts index 2e3668813c5..4adb828180e 100644 --- a/test/abilities/libero.test.ts +++ b/test/abilities/libero.test.ts @@ -67,7 +67,7 @@ describe("Abilities - Libero", () => { game.move.select(Moves.AGILITY); await game.phaseInterceptor.to(TurnEndPhase); - expect(leadPokemon.summonData.abilitiesApplied.filter(a => a === Abilities.LIBERO)).toHaveLength(1); + expect(leadPokemon.waveData.abilitiesApplied).toContain(Abilities.LIBERO); const leadPokemonType = PokemonType[leadPokemon.getTypes()[0]]; const moveType = PokemonType[allMoves[Moves.AGILITY].type]; expect(leadPokemonType).not.toBe(moveType); @@ -99,7 +99,7 @@ describe("Abilities - Libero", () => { game.move.select(Moves.WEATHER_BALL); await game.phaseInterceptor.to(TurnEndPhase); - expect(leadPokemon.summonData.abilitiesApplied).toContain(Abilities.LIBERO); + expect(leadPokemon.waveData.abilitiesApplied).toContain(Abilities.LIBERO); expect(leadPokemon.getTypes()).toHaveLength(1); const leadPokemonType = PokemonType[leadPokemon.getTypes()[0]], moveType = PokemonType[PokemonType.FIRE]; @@ -118,7 +118,7 @@ describe("Abilities - Libero", () => { game.move.select(Moves.TACKLE); await game.phaseInterceptor.to(TurnEndPhase); - expect(leadPokemon.summonData.abilitiesApplied).toContain(Abilities.LIBERO); + expect(leadPokemon.waveData.abilitiesApplied).toContain(Abilities.LIBERO); expect(leadPokemon.getTypes()).toHaveLength(1); const leadPokemonType = PokemonType[leadPokemon.getTypes()[0]], moveType = PokemonType[PokemonType.ICE]; @@ -214,7 +214,7 @@ describe("Abilities - Libero", () => { game.move.select(Moves.SPLASH); await game.phaseInterceptor.to(TurnEndPhase); - expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.LIBERO); + expect(leadPokemon.waveData.abilitiesApplied).not.toContain(Abilities.LIBERO); }); test("ability is not applied if pokemon is terastallized", async () => { @@ -230,7 +230,7 @@ describe("Abilities - Libero", () => { game.move.select(Moves.SPLASH); await game.phaseInterceptor.to(TurnEndPhase); - expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.LIBERO); + expect(leadPokemon.waveData.abilitiesApplied).not.toContain(Abilities.LIBERO); }); test("ability is not applied if pokemon uses struggle", async () => { @@ -244,7 +244,7 @@ describe("Abilities - Libero", () => { game.move.select(Moves.STRUGGLE); await game.phaseInterceptor.to(TurnEndPhase); - expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.LIBERO); + expect(leadPokemon.waveData.abilitiesApplied).not.toContain(Abilities.LIBERO); }); test("ability is not applied if the pokemon's move fails", async () => { @@ -258,7 +258,7 @@ describe("Abilities - Libero", () => { game.move.select(Moves.BURN_UP); await game.phaseInterceptor.to(TurnEndPhase); - expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.LIBERO); + expect(leadPokemon.waveData.abilitiesApplied).not.toContain(Abilities.LIBERO); }); test("ability applies correctly even if the pokemon's Trick-or-Treat fails", async () => { @@ -293,7 +293,7 @@ describe("Abilities - Libero", () => { }); function testPokemonTypeMatchesDefaultMoveType(pokemon: PlayerPokemon, move: Moves) { - expect(pokemon.summonData.abilitiesApplied).toContain(Abilities.LIBERO); + expect(pokemon.waveData.abilitiesApplied).toContain(Abilities.LIBERO); expect(pokemon.getTypes()).toHaveLength(1); const pokemonType = PokemonType[pokemon.getTypes()[0]], moveType = PokemonType[allMoves[move].type]; diff --git a/test/abilities/protean.test.ts b/test/abilities/protean.test.ts index efa6f33fe00..8f7633e1327 100644 --- a/test/abilities/protean.test.ts +++ b/test/abilities/protean.test.ts @@ -67,7 +67,7 @@ describe("Abilities - Protean", () => { game.move.select(Moves.AGILITY); await game.phaseInterceptor.to(TurnEndPhase); - expect(leadPokemon.summonData.abilitiesApplied.filter(a => a === Abilities.PROTEAN)).toHaveLength(1); + expect(leadPokemon.waveData.abilitiesApplied).toContain(Abilities.PROTEAN); const leadPokemonType = PokemonType[leadPokemon.getTypes()[0]]; const moveType = PokemonType[allMoves[Moves.AGILITY].type]; expect(leadPokemonType).not.toBe(moveType); @@ -99,7 +99,7 @@ describe("Abilities - Protean", () => { game.move.select(Moves.WEATHER_BALL); await game.phaseInterceptor.to(TurnEndPhase); - expect(leadPokemon.summonData.abilitiesApplied).toContain(Abilities.PROTEAN); + expect(leadPokemon.waveData.abilitiesApplied).toContain(Abilities.PROTEAN); expect(leadPokemon.getTypes()).toHaveLength(1); const leadPokemonType = PokemonType[leadPokemon.getTypes()[0]], moveType = PokemonType[PokemonType.FIRE]; @@ -118,7 +118,7 @@ describe("Abilities - Protean", () => { game.move.select(Moves.TACKLE); await game.phaseInterceptor.to(TurnEndPhase); - expect(leadPokemon.summonData.abilitiesApplied).toContain(Abilities.PROTEAN); + expect(leadPokemon.waveData.abilitiesApplied).toContain(Abilities.PROTEAN); expect(leadPokemon.getTypes()).toHaveLength(1); const leadPokemonType = PokemonType[leadPokemon.getTypes()[0]], moveType = PokemonType[PokemonType.ICE]; @@ -214,7 +214,7 @@ describe("Abilities - Protean", () => { game.move.select(Moves.SPLASH); await game.phaseInterceptor.to(TurnEndPhase); - expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.PROTEAN); + expect(leadPokemon.waveData.abilitiesApplied).not.toContain(Abilities.PROTEAN); }); test("ability is not applied if pokemon is terastallized", async () => { @@ -230,7 +230,7 @@ describe("Abilities - Protean", () => { game.move.select(Moves.SPLASH); await game.phaseInterceptor.to(TurnEndPhase); - expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.PROTEAN); + expect(leadPokemon.waveData.abilitiesApplied).not.toContain(Abilities.PROTEAN); }); test("ability is not applied if pokemon uses struggle", async () => { @@ -244,7 +244,7 @@ describe("Abilities - Protean", () => { game.move.select(Moves.STRUGGLE); await game.phaseInterceptor.to(TurnEndPhase); - expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.PROTEAN); + expect(leadPokemon.waveData.abilitiesApplied).not.toContain(Abilities.PROTEAN); }); test("ability is not applied if the pokemon's move fails", async () => { @@ -258,7 +258,7 @@ describe("Abilities - Protean", () => { game.move.select(Moves.BURN_UP); await game.phaseInterceptor.to(TurnEndPhase); - expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.PROTEAN); + expect(leadPokemon.waveData.abilitiesApplied).not.toContain(Abilities.PROTEAN); }); test("ability applies correctly even if the pokemon's Trick-or-Treat fails", async () => { @@ -293,7 +293,7 @@ describe("Abilities - Protean", () => { }); function testPokemonTypeMatchesDefaultMoveType(pokemon: PlayerPokemon, move: Moves) { - expect(pokemon.summonData.abilitiesApplied).toContain(Abilities.PROTEAN); + expect(pokemon.waveData.abilitiesApplied).toContain(Abilities.PROTEAN); expect(pokemon.getTypes()).toHaveLength(1); const pokemonType = PokemonType[pokemon.getTypes()[0]], moveType = PokemonType[allMoves[move].type]; diff --git a/test/abilities/quick_draw.test.ts b/test/abilities/quick_draw.test.ts index 0d3171e947e..79a29b0ce77 100644 --- a/test/abilities/quick_draw.test.ts +++ b/test/abilities/quick_draw.test.ts @@ -54,7 +54,7 @@ describe("Abilities - Quick Draw", () => { expect(pokemon.isFainted()).toBe(false); expect(enemy.isFainted()).toBe(true); - expect(pokemon.battleData.abilitiesApplied).contain(Abilities.QUICK_DRAW); + expect(pokemon.waveData.abilitiesApplied).contain(Abilities.QUICK_DRAW); }, 20000); test( @@ -76,7 +76,7 @@ describe("Abilities - Quick Draw", () => { expect(pokemon.isFainted()).toBe(true); expect(enemy.isFainted()).toBe(false); - expect(pokemon.battleData.abilitiesApplied).not.contain(Abilities.QUICK_DRAW); + expect(pokemon.waveData.abilitiesApplied).not.contain(Abilities.QUICK_DRAW); }, ); @@ -96,6 +96,6 @@ describe("Abilities - Quick Draw", () => { expect(pokemon.isFainted()).toBe(true); expect(enemy.isFainted()).toBe(false); - expect(pokemon.battleData.abilitiesApplied).contain(Abilities.QUICK_DRAW); + expect(pokemon.waveData.abilitiesApplied).contain(Abilities.QUICK_DRAW); }, 20000); }); diff --git a/test/abilities/wimp_out.test.ts b/test/abilities/wimp_out.test.ts index 463ec7587dc..f558efdb103 100644 --- a/test/abilities/wimp_out.test.ts +++ b/test/abilities/wimp_out.test.ts @@ -155,7 +155,7 @@ describe("Abilities - Wimp Out", () => { game.doSelectPartyPokemon(1); await game.phaseInterceptor.to("SwitchSummonPhase", false); - expect(wimpod.summonData.abilitiesApplied).not.toContain(Abilities.WIMP_OUT); + expect(wimpod.waveData.abilitiesApplied).not.toContain(Abilities.WIMP_OUT); await game.phaseInterceptor.to("TurnEndPhase"); diff --git a/test/battle/inverse_battle.test.ts b/test/battle/inverse_battle.test.ts index f8afa3518a9..799442bb603 100644 --- a/test/battle/inverse_battle.test.ts +++ b/test/battle/inverse_battle.test.ts @@ -179,12 +179,12 @@ describe("Inverse Battle", () => { expect(enemy.status?.effect).toBe(StatusEffect.PARALYSIS); }); - it("Anticipation should trigger on 2x effective moves - Anticipation against Thunderbolt", async () => { + it("Anticipation should trigger on 2x effective moves", async () => { game.override.moveset([Moves.THUNDERBOLT]).enemySpecies(Species.SANDSHREW).enemyAbility(Abilities.ANTICIPATION); await game.challengeMode.startBattle(); - expect(game.scene.getEnemyPokemon()?.summonData.abilitiesApplied[0]).toBe(Abilities.ANTICIPATION); + expect(game.scene.getEnemyPokemon()?.waveData.abilitiesApplied).toContain(Abilities.ANTICIPATION); }); it("Conversion 2 should change the type to the resistive type - Conversion 2 against Dragonite", async () => { diff --git a/test/battlerTags/substitute.test.ts b/test/battlerTags/substitute.test.ts index d2df5511c0a..c2a99299716 100644 --- a/test/battlerTags/substitute.test.ts +++ b/test/battlerTags/substitute.test.ts @@ -42,7 +42,6 @@ describe("BattlerTag - SubstituteTag", () => { // simulate a Trapped tag set by another Pokemon, then expect the filter to catch it. const trapTag = new BindTag(5, 0); expect(tagFilter(trapTag)).toBeTruthy(); - return true; }) as Pokemon["findAndRemoveTags"], } as unknown as Pokemon; diff --git a/test/moves/dive.test.ts b/test/moves/dive.test.ts index f33dc69b55f..95c3349c8a6 100644 --- a/test/moves/dive.test.ts +++ b/test/moves/dive.test.ts @@ -105,7 +105,7 @@ describe("Moves - Dive", () => { await game.phaseInterceptor.to("MoveEndPhase"); expect(playerPokemon.hp).toBeLessThan(playerPokemon.getMaxHp()); - expect(enemyPokemon.battleData.abilitiesApplied[0]).toBe(Abilities.ROUGH_SKIN); + expect(enemyPokemon.waveData.abilitiesApplied).toContain(Abilities.ROUGH_SKIN); }); it("should cancel attack after Harsh Sunlight is set", async () => { diff --git a/test/moves/fake_out.test.ts b/test/moves/fake_out.test.ts index cbce16270e0..404473c8fa0 100644 --- a/test/moves/fake_out.test.ts +++ b/test/moves/fake_out.test.ts @@ -26,64 +26,71 @@ describe("Moves - Fake Out", () => { .moveset([Moves.FAKE_OUT, Moves.SPLASH]) .enemyMoveset(Moves.SPLASH) .enemyLevel(10) - .startingLevel(10) // prevent LevelUpPhase from happening + .startingLevel(1) // prevent LevelUpPhase from happening .disableCrits(); }); - it("can only be used on the first turn a pokemon is sent out in a battle", async () => { + it("should only work the first turn a pokemon is sent out in a battle", async () => { await game.classicMode.startBattle([Species.FEEBAS]); - const enemy = game.scene.getEnemyPokemon()!; + const corv = game.scene.getEnemyPokemon()!; game.move.select(Moves.FAKE_OUT); await game.toNextTurn(); - expect(enemy.hp).toBeLessThan(enemy.getMaxHp()); - const postTurnOneHp = enemy.hp; + expect(corv.hp).toBeLessThan(corv.getMaxHp()); + const postTurnOneHp = corv.hp; game.move.select(Moves.FAKE_OUT); await game.toNextTurn(); - expect(enemy.hp).toBe(postTurnOneHp); - }, 20000); + expect(corv.hp).toBe(postTurnOneHp); + }); // This is a PokeRogue buff to Fake Out - it("can be used at the start of every wave even if the pokemon wasn't recalled", async () => { + it("should succeed at the start of each new wave, even if user wasn't recalled", async () => { await game.classicMode.startBattle([Species.FEEBAS]); - const enemy = game.scene.getEnemyPokemon()!; - enemy.damageAndUpdate(enemy.getMaxHp() - 1); - + // set hp to 1 for easy knockout + game.scene.getEnemyPokemon()!.hp = 1; game.move.select(Moves.FAKE_OUT); await game.toNextWave(); game.move.select(Moves.FAKE_OUT); await game.toNextTurn(); - expect(game.scene.getEnemyPokemon()!.isFullHp()).toBe(false); - }, 20000); + const corv = game.scene.getEnemyPokemon()!; + expect(corv).toBeDefined(); + expect(corv?.hp).toBeLessThan(corv?.getMaxHp()); + }); - it("can be used again if recalled and sent back out", async () => { - game.override.startingWave(4); + // This is a PokeRogue buff to Fake Out + it("should succeed at the start of each new wave, even if user wasn't recalled", async () => { + await game.classicMode.startBattle([Species.FEEBAS]); + + // set hp to 1 for easy knockout + game.scene.getEnemyPokemon()!.hp = 1; + game.move.select(Moves.FAKE_OUT); + await game.toNextWave(); + + game.move.select(Moves.FAKE_OUT); + await game.toNextTurn(); + + const corv = game.scene.getEnemyPokemon()!; + expect(corv).toBeDefined(); + expect(corv.hp).toBeLessThan(corv.getMaxHp()); + }); + + it("should succeed if recalled and sent back out", async () => { await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); - const enemy1 = game.scene.getEnemyPokemon()!; - - game.move.select(Moves.FAKE_OUT); - await game.phaseInterceptor.to("MoveEndPhase"); - - expect(enemy1.hp).toBeLessThan(enemy1.getMaxHp()); - - await game.doKillOpponents(); - await game.toNextWave(); - game.move.select(Moves.FAKE_OUT); await game.toNextTurn(); - const enemy2 = game.scene.getEnemyPokemon()!; + const corv = game.scene.getEnemyPokemon()!; - expect(enemy2.hp).toBeLessThan(enemy2.getMaxHp()); - enemy2.hp = enemy2.getMaxHp(); + expect(corv.hp).toBeLessThan(corv.getMaxHp()); + corv.hp = corv.getMaxHp(); game.doSwitchPokemon(1); await game.toNextTurn(); @@ -94,6 +101,6 @@ describe("Moves - Fake Out", () => { game.move.select(Moves.FAKE_OUT); await game.toNextTurn(); - expect(enemy2.hp).toBeLessThan(enemy2.getMaxHp()); - }, 20000); + expect(corv.hp).toBeLessThan(corv.getMaxHp()); + }); }); diff --git a/test/moves/instruct.test.ts b/test/moves/instruct.test.ts index c5650d7bbd5..dd25db4ec90 100644 --- a/test/moves/instruct.test.ts +++ b/test/moves/instruct.test.ts @@ -228,7 +228,7 @@ describe("Moves - Instruct", () => { const amoonguss = game.scene.getPlayerPokemon()!; game.move.changeMoveset(amoonguss, Moves.SEED_BOMB); - amoonguss.battleSummonData.moveHistory = [ + amoonguss.summonData.moveHistory = [ { move: Moves.SEED_BOMB, targets: [BattlerIndex.ENEMY], @@ -301,7 +301,7 @@ describe("Moves - Instruct", () => { const player = game.scene.getPlayerPokemon()!; const enemy = game.scene.getEnemyPokemon()!; - enemy.battleSummonData.moveHistory = [ + enemy.summonData.moveHistory = [ { move: Moves.SONIC_BOOM, targets: [BattlerIndex.PLAYER], @@ -350,7 +350,7 @@ describe("Moves - Instruct", () => { await game.classicMode.startBattle([Species.LUCARIO, Species.BANETTE]); const enemyPokemon = game.scene.getEnemyPokemon()!; - enemyPokemon.battleSummonData.moveHistory = [ + enemyPokemon.summonData.moveHistory = [ { move: Moves.WHIRLWIND, targets: [BattlerIndex.PLAYER], diff --git a/test/moves/last-resort.test.ts b/test/moves/last-resort.test.ts new file mode 100644 index 00000000000..a7b462f3ca4 --- /dev/null +++ b/test/moves/last-resort.test.ts @@ -0,0 +1,166 @@ +import { BattlerIndex } from "#app/battle"; +import { MoveResult } from "#app/field/pokemon"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/testUtils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Moves - Last Resort", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + function expectLastResortFail() { + expect(game.scene.getPlayerPokemon()?.getLastXMoves()[0]).toEqual( + expect.objectContaining({ + move: Moves.LAST_RESORT, + result: MoveResult.FAIL, + }), + ); + } + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .ability(Abilities.BALL_FETCH) + .battleStyle("single") + .disableCrits() + .enemySpecies(Species.MAGIKARP) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + it("should fail unless all other moves (excluding itself) has been used at least once", async () => { + game.override.moveset([Moves.LAST_RESORT, Moves.SPLASH, Moves.GROWL, Moves.GROWTH]); + await game.classicMode.startBattle([Species.BLISSEY]); + + const blissey = game.scene.getPlayerPokemon()!; + expect(blissey).toBeDefined(); + + // Last resort by itself + game.move.select(Moves.LAST_RESORT); + await game.phaseInterceptor.to("TurnEndPhase"); + expectLastResortFail(); + + // Splash (1/3) + blissey.pushMoveHistory({ move: Moves.SPLASH, targets: [BattlerIndex.PLAYER] }); + game.move.select(Moves.LAST_RESORT); + await game.phaseInterceptor.to("TurnEndPhase"); + expectLastResortFail(); + + // Growl (2/3) + blissey.pushMoveHistory({ move: Moves.GROWL, targets: [BattlerIndex.ENEMY] }); + game.move.select(Moves.LAST_RESORT); + await game.phaseInterceptor.to("TurnEndPhase"); + expectLastResortFail(); // Were last resort itself counted, it would error here + + // Growth (3/3) + blissey.pushMoveHistory({ move: Moves.GROWTH, targets: [BattlerIndex.PLAYER] }); + game.move.select(Moves.LAST_RESORT); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(game.scene.getPlayerPokemon()?.getLastXMoves()[0]).toEqual( + expect.objectContaining({ + move: Moves.LAST_RESORT, + result: MoveResult.SUCCESS, + }), + ); + }); + + it("should disregard virtually invoked moves", async () => { + game.override + .moveset([Moves.LAST_RESORT, Moves.SWORDS_DANCE, Moves.ABSORB, Moves.MIRROR_MOVE]) + .enemyMoveset([Moves.SWORDS_DANCE, Moves.ABSORB]) + .ability(Abilities.DANCER) + .enemySpecies(Species.ABOMASNOW); // magikarp has 50% chance to be okho'd on absorb crit + await game.classicMode.startBattle([Species.BLISSEY]); + + // use mirror move normally to trigger absorb virtually + game.move.select(Moves.MIRROR_MOVE); + await game.forceEnemyMove(Moves.ABSORB); + await game.toNextTurn(); + + game.move.select(Moves.LAST_RESORT); + await game.forceEnemyMove(Moves.SWORDS_DANCE); // goes first to proc dancer ahead of time + await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.phaseInterceptor.to("TurnEndPhase"); + expectLastResortFail(); + }); + + it("should fail if no other moves in moveset", async () => { + game.override.moveset(Moves.LAST_RESORT); + await game.classicMode.startBattle([Species.BLISSEY]); + + game.move.select(Moves.LAST_RESORT); + await game.phaseInterceptor.to("TurnEndPhase"); + + expectLastResortFail(); + }); + + it("should work if invoked virtually when all other moves have been used", async () => { + game.override.moveset([Moves.LAST_RESORT, Moves.SLEEP_TALK]).ability(Abilities.COMATOSE); + await game.classicMode.startBattle([Species.KOMALA]); + + game.move.select(Moves.SLEEP_TALK); + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(game.scene.getPlayerPokemon()?.getLastXMoves(-1)).toEqual([ + expect.objectContaining({ + move: Moves.LAST_RESORT, + result: MoveResult.SUCCESS, + virtual: true, + }), + expect.objectContaining({ + move: Moves.SLEEP_TALK, + result: MoveResult.SUCCESS, + }), + ]); + }); + + it("should preserve usability status on reload", async () => { + game.override.moveset([Moves.LAST_RESORT, Moves.SPLASH]).ability(Abilities.COMATOSE); + await game.classicMode.startBattle([Species.BLISSEY]); + + game.move.select(Moves.SPLASH); + await game.doKillOpponents(); + await game.toNextWave(); + + const oldMoveHistory = game.scene.getPlayerPokemon()?.summonData.moveHistory; + await game.reload.reloadSession(); + + const newMoveHistory = game.scene.getPlayerPokemon()?.summonData.moveHistory; + expect(oldMoveHistory).toEqual(newMoveHistory); + + // use last resort and it should kill the karp just fine + game.move.select(Moves.LAST_RESORT); + game.scene.getEnemyPokemon()!.hp = 1; + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(game.isVictory()).toBe(true); + }); + + it("should fail if used while not in moveset", async () => { + game.override.moveset(Moves.MIRROR_MOVE).enemyMoveset([Moves.ABSORB, Moves.LAST_RESORT]); + await game.classicMode.startBattle([Species.BLISSEY]); + + // ensure enemy last resort succeeds + game.move.select(Moves.MIRROR_MOVE); + await game.forceEnemyMove(Moves.ABSORB); + await game.phaseInterceptor.to("TurnEndPhase"); + game.move.select(Moves.MIRROR_MOVE); + await game.forceEnemyMove(Moves.LAST_RESORT); + await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.phaseInterceptor.to("TurnEndPhase"); + + expectLastResortFail(); + }); +}); diff --git a/test/moves/powder.test.ts b/test/moves/powder.test.ts index 6f7a6add054..457beb60f91 100644 --- a/test/moves/powder.test.ts +++ b/test/moves/powder.test.ts @@ -146,7 +146,7 @@ describe("Moves - Powder", () => { await game.phaseInterceptor.to(BerryPhase, false); expect(enemyPokemon.getLastXMoves()[0].result).toBe(MoveResult.FAIL); expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); - expect(enemyPokemon.summonData?.types).not.toBe(PokemonType.FIRE); + expect(enemyPokemon.summonData.types).not.toBe(PokemonType.FIRE); }); it("should cancel Fire-type moves generated by the target's Dancer ability", async () => { diff --git a/test/moves/rage_fist.test.ts b/test/moves/rage_fist.test.ts index 687d805da78..f215c5955c6 100644 --- a/test/moves/rage_fist.test.ts +++ b/test/moves/rage_fist.test.ts @@ -7,6 +7,7 @@ import type Move from "#app/data/moves/move"; import GameManager from "#test/testUtils/gameManager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { BattleType } from "#enums/battle-type"; describe("Moves - Rage Fist", () => { let phaserGame: Phaser.Game; @@ -28,19 +29,18 @@ describe("Moves - Rage Fist", () => { game = new GameManager(phaserGame); game.override .battleStyle("single") - .moveset([Moves.RAGE_FIST, Moves.SPLASH, Moves.SUBSTITUTE]) + .moveset([Moves.RAGE_FIST, Moves.SPLASH, Moves.SUBSTITUTE, Moves.TIDY_UP]) .startingLevel(100) .enemyLevel(1) + .enemySpecies(Species.MAGIKARP) .enemyAbility(Abilities.BALL_FETCH) .enemyMoveset(Moves.DOUBLE_KICK); vi.spyOn(move, "calculateBattlePower"); }); - it("should have 100 more power if hit twice before calling Rage Fist", async () => { - game.override.enemySpecies(Species.MAGIKARP); - - await game.classicMode.startBattle([Species.MAGIKARP]); + it("should gain power per hit taken", async () => { + await game.classicMode.startBattle([Species.FEEBAS]); game.move.select(Moves.RAGE_FIST); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); @@ -49,51 +49,95 @@ describe("Moves - Rage Fist", () => { expect(move.calculateBattlePower).toHaveLastReturnedWith(150); }); - it("should maintain its power during next battle if it is within the same arena encounter", async () => { - game.override.enemySpecies(Species.MAGIKARP).startingWave(1); + it("caps at 6 hits taken", async () => { + await game.classicMode.startBattle([Species.FEEBAS]); - await game.classicMode.startBattle([Species.MAGIKARP]); + // spam splash against magikarp hitting us 2 times per turn + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + game.move.select(Moves.SPLASH); + await game.toNextTurn(); + + game.move.select(Moves.RAGE_FIST); + await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.phaseInterceptor.to("TurnEndPhase"); + + // hit 8 times, but nothing else + expect(game.scene.getPlayerPokemon()?.battleData.hitCount).toBe(8); + expect(move.calculateBattlePower).toHaveLastReturnedWith(350); + }); + + it("should not count substitute hits or confusion damage", async () => { + game.override.enemySpecies(Species.SHUCKLE).enemyMoveset([Moves.CONFUSE_RAY, Moves.DOUBLE_KICK]); + + await game.classicMode.startBattle([Species.REGIROCK]); + + game.move.select(Moves.SUBSTITUTE); + await game.forceEnemyMove(Moves.DOUBLE_KICK); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.toNextTurn(); + + // no increase due to substitute + expect(game.scene.getPlayerPokemon()?.battleData.hitCount).toBe(0); + + // remove substitute and get confused + game.move.select(Moves.TIDY_UP); + await game.forceEnemyMove(Moves.CONFUSE_RAY); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.toNextTurn(); + + game.move.select(Moves.RAGE_FIST); + await game.forceEnemyMove(Moves.CONFUSE_RAY); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.move.forceConfusionActivation(true); + await game.toNextTurn(); + + // didn't go up from hitting ourself + expect(game.scene.getPlayerPokemon()?.battleData.hitCount).toBe(0); + }); + + it("should maintain hits recieved between wild waves", async () => { + await game.classicMode.startBattle([Species.FEEBAS]); game.move.select(Moves.RAGE_FIST); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.toNextWave(); + expect(game.scene.getPlayerPokemon()?.battleData.hitCount).toBe(2); + game.move.select(Moves.RAGE_FIST); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); - await game.phaseInterceptor.to("BerryPhase", false); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(game.scene.getPlayerPokemon()?.battleData.hitCount).toBe(4); expect(move.calculateBattlePower).toHaveLastReturnedWith(250); }); - it("should reset the hitRecCounter if we enter new trainer battle", async () => { - game.override.enemySpecies(Species.MAGIKARP).startingWave(4); + it("should reset hits recieved before trainer battles", async () => { + await game.classicMode.startBattle([Species.IRON_HANDS]); - await game.classicMode.startBattle([Species.MAGIKARP]); + const ironHands = game.scene.getPlayerPokemon()!; + expect(ironHands).toBeDefined(); + // beat up a magikarp game.move.select(Moves.RAGE_FIST); + await game.forceEnemyMove(Moves.DOUBLE_KICK); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(game.isVictory()).toBe(true); + expect(ironHands.battleData.hitCount).toBe(2); + expect(move.calculateBattlePower).toHaveLastReturnedWith(150); + + game.override.battleType(BattleType.TRAINER); await game.toNextWave(); - game.move.select(Moves.RAGE_FIST); - await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); - await game.phaseInterceptor.to("BerryPhase", false); - - expect(move.calculateBattlePower).toHaveLastReturnedWith(150); + expect(ironHands.battleData.hitCount).toBe(0); }); - it("should not increase the hitCounter if Substitute is hit", async () => { - game.override.enemySpecies(Species.MAGIKARP).startingWave(4); - - await game.classicMode.startBattle([Species.MAGIKARP]); - - game.move.select(Moves.SUBSTITUTE); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); - await game.phaseInterceptor.to("MoveEffectPhase"); - - expect(game.scene.getPlayerPokemon()?.customPokemonData.hitsRecCount).toBe(0); - }); - - it("should reset the hitRecCounter if we enter new biome", async () => { + it("should reset hits recieved before new biome", async () => { game.override.enemySpecies(Species.MAGIKARP).startingWave(10); await game.classicMode.startBattle([Species.MAGIKARP]); @@ -109,25 +153,50 @@ describe("Moves - Rage Fist", () => { expect(move.calculateBattlePower).toHaveLastReturnedWith(150); }); - it("should not reset the hitRecCounter if switched out", async () => { - game.override.enemySpecies(Species.MAGIKARP).startingWave(1).enemyMoveset(Moves.TACKLE); + it("should not reset if switched out or on reload", async () => { + game.override.enemyMoveset(Moves.TACKLE); + + const getPartyHitCount = () => + game.scene + .getPlayerParty() + .filter(p => !!p) + .map(m => m.battleData.hitCount); await game.classicMode.startBattle([Species.CHARIZARD, Species.BLASTOISE]); + // Charizard hit game.move.select(Moves.SPLASH); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.toNextTurn(); + expect(getPartyHitCount()).toEqual([1, 0]); + // blastoise switched in & hit game.doSwitchPokemon(1); await game.toNextTurn(); + expect(getPartyHitCount()).toEqual([1, 1]); + // charizard switched in & hit game.doSwitchPokemon(1); await game.toNextTurn(); + expect(getPartyHitCount()).toEqual([2, 1]); + // Charizard rage fist game.move.select(Moves.RAGE_FIST); await game.phaseInterceptor.to("MoveEndPhase"); - expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(Species.CHARIZARD); + const charizard = game.scene.getPlayerPokemon()!; + expect(charizard).toBeDefined(); + expect(charizard.species.speciesId).toBe(Species.CHARIZARD); + expect(move.calculateBattlePower).toHaveLastReturnedWith(150); + + // go to new wave, reload game and beat up another poor sap + await game.toNextWave(); + + await game.reload.reloadSession(); + + // outsped and oneshot means power rmains same as prior + game.move.select(Moves.RAGE_FIST); + await game.phaseInterceptor.to("MoveEndPhase"); expect(move.calculateBattlePower).toHaveLastReturnedWith(150); }); }); diff --git a/test/moves/toxic_spikes.test.ts b/test/moves/toxic_spikes.test.ts index 624db27bb92..b1fdc7f39c2 100644 --- a/test/moves/toxic_spikes.test.ts +++ b/test/moves/toxic_spikes.test.ts @@ -129,7 +129,7 @@ describe("Moves - Toxic Spikes", () => { await game.phaseInterceptor.to("BattleEndPhase"); await game.toNextWave(); - const sessionData: SessionSaveData = gameData["getSessionSaveData"](); + const sessionData: SessionSaveData = gameData.getSessionSaveData(); localStorage.setItem("sessionTestData", encrypt(JSON.stringify(sessionData), true)); const recoveredData: SessionSaveData = gameData.parseSessionData( decrypt(localStorage.getItem("sessionTestData")!, true), diff --git a/test/moves/transform.test.ts b/test/moves/transform.test.ts index 5bcb7c7ed4c..8bfe7df688b 100644 --- a/test/moves/transform.test.ts +++ b/test/moves/transform.test.ts @@ -4,7 +4,7 @@ import GameManager from "#test/testUtils/gameManager"; import { Species } from "#enums/species"; import { TurnEndPhase } from "#app/phases/turn-end-phase"; import { Moves } from "#enums/moves"; -import { Stat, BATTLE_STATS, EFFECTIVE_STATS } from "#enums/stat"; +import { Stat, EFFECTIVE_STATS } from "#enums/stat"; import { Abilities } from "#enums/abilities"; import { BattlerIndex } from "#app/battle"; @@ -49,30 +49,18 @@ describe("Moves - Transform", () => { expect(player.getAbility()).toBe(enemy.getAbility()); expect(player.getGender()).toBe(enemy.getGender()); + // copies all stats except hp expect(player.getStat(Stat.HP, false)).not.toBe(enemy.getStat(Stat.HP)); for (const s of EFFECTIVE_STATS) { expect(player.getStat(s, false)).toBe(enemy.getStat(s, false)); } - for (const s of BATTLE_STATS) { - expect(player.getStatStage(s)).toBe(enemy.getStatStage(s)); - } + expect(player.getStatStages()).toEqual(enemy.getStatStages()); - const playerMoveset = player.getMoveset(); - const enemyMoveset = enemy.getMoveset(); + // move IDs are equal + expect(player.getMoveset().map(m => m.moveId)).toEqual(enemy.getMoveset().map(m => m.moveId)); - expect(playerMoveset.length).toBe(enemyMoveset.length); - for (let i = 0; i < playerMoveset.length && i < enemyMoveset.length; i++) { - expect(playerMoveset[i]?.moveId).toBe(enemyMoveset[i]?.moveId); - } - - const playerTypes = player.getTypes(); - const enemyTypes = enemy.getTypes(); - - expect(playerTypes.length).toBe(enemyTypes.length); - for (let i = 0; i < playerTypes.length && i < enemyTypes.length; i++) { - expect(playerTypes[i]).toBe(enemyTypes[i]); - } + expect(player.getTypes()).toEqual(enemy.getTypes()); }); it("should copy in-battle overridden stats", async () => { diff --git a/test/moves/u_turn.test.ts b/test/moves/u_turn.test.ts index 68bb7fe05c1..4ceb6865be0 100644 --- a/test/moves/u_turn.test.ts +++ b/test/moves/u_turn.test.ts @@ -65,7 +65,7 @@ describe("Moves - U-turn", () => { // assert const playerPkm = game.scene.getPlayerPokemon()!; expect(playerPkm.hp).not.toEqual(playerPkm.getMaxHp()); - expect(game.scene.getEnemyPokemon()!.battleData.abilityRevealed).toBe(true); // proxy for asserting ability activated + expect(game.scene.getEnemyPokemon()!.waveData.abilityRevealed).toBe(true); // proxy for asserting ability activated expect(playerPkm.species.speciesId).toEqual(Species.RAICHU); expect(game.phaseInterceptor.log).not.toContain("SwitchSummonPhase"); }, 20000); @@ -84,7 +84,7 @@ describe("Moves - U-turn", () => { const playerPkm = game.scene.getPlayerPokemon()!; expect(playerPkm.status?.effect).toEqual(StatusEffect.POISON); expect(playerPkm.species.speciesId).toEqual(Species.RAICHU); - expect(game.scene.getEnemyPokemon()!.battleData.abilityRevealed).toBe(true); // proxy for asserting ability activated + expect(game.scene.getEnemyPokemon()!.waveData.abilityRevealed).toBe(true); // proxy for asserting ability activated expect(game.phaseInterceptor.log).not.toContain("SwitchSummonPhase"); }, 20000); diff --git a/test/settingMenu/rebinding_setting.test.ts b/test/settingMenu/rebinding_setting.test.ts index 45c647248c4..20a1fe51484 100644 --- a/test/settingMenu/rebinding_setting.test.ts +++ b/test/settingMenu/rebinding_setting.test.ts @@ -2,7 +2,7 @@ import cfg_keyboard_qwerty from "#app/configs/inputs/cfg_keyboard_qwerty"; import { getKeyWithKeycode, getKeyWithSettingName } from "#app/configs/inputs/configHandler"; import type { InterfaceConfig } from "#app/inputs-controller"; import { SettingKeyboard } from "#app/system/settings/settings-keyboard"; -import { deepCopy } from "#app/utils/common"; +import { deepCopy } from "#app/utils/data"; import { Button } from "#enums/buttons"; import { Device } from "#enums/devices"; import { InGameManip } from "#test/settingMenu/helpers/inGameManip"; diff --git a/test/testUtils/gameManager.ts b/test/testUtils/gameManager.ts index 39e65fba0e5..8dd90decf1a 100644 --- a/test/testUtils/gameManager.ts +++ b/test/testUtils/gameManager.ts @@ -579,9 +579,8 @@ export default class GameManager { /** * Intercepts `TurnStartPhase` and mocks {@linkcode TurnStartPhase.getSpeedOrder}'s return value. * Used to manually modify Pokemon turn order. - * Note: This *DOES NOT* account for priority. - * @param order - The turn order to set + * @param order - The turn order to set as an array of {@linkcode BattlerIndex}es. * @example * ```ts * await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2]); diff --git a/test/testUtils/helpers/moveHelper.ts b/test/testUtils/helpers/moveHelper.ts index 0f3d75c6268..269cf65ea56 100644 --- a/test/testUtils/helpers/moveHelper.ts +++ b/test/testUtils/helpers/moveHelper.ts @@ -103,6 +103,17 @@ export class MoveHelper extends GameManagerHelper { vi.spyOn(Overrides, "STATUS_ACTIVATION_OVERRIDE", "get").mockReturnValue(null); } + /** + * Forces the Confusion status to activate on the next move by temporarily mocking {@linkcode Overrides.CONFUSION_ACTIVATION_OVERRIDE}, + * advancing to the next `MovePhase`, and then resetting the override to `null` + * @param activated - `true` to force the Pokemon to hit themself, `false` to forcibly disable it + */ + public async forceConfusionActivation(activated: boolean): Promise { + vi.spyOn(Overrides, "CONFUSION_ACTIVATION_OVERRIDE", "get").mockReturnValue(activated); + await this.game.phaseInterceptor.to("MovePhase"); + vi.spyOn(Overrides, "CONFUSION_ACTIVATION_OVERRIDE", "get").mockReturnValue(null); + } + /** * Changes a pokemon's moveset to the given move(s). * Used when the normal moveset override can't be used (such as when it's necessary to check or update properties of the moveset). diff --git a/test/testUtils/helpers/overridesHelper.ts b/test/testUtils/helpers/overridesHelper.ts index 6aa382ef59a..acc2e4d5cd0 100644 --- a/test/testUtils/helpers/overridesHelper.ts +++ b/test/testUtils/helpers/overridesHelper.ts @@ -522,6 +522,21 @@ export class OverridesHelper extends GameManagerHelper { return this; } + /** + * Override confusion to always or never activate + * @param activate - `true` to force activation, `false` to force no activation, `null` to disable the override + * @returns `this` + */ + public confusionActivation(activate: boolean | null): this { + vi.spyOn(Overrides, "CONFUSION_ACTIVATION_OVERRIDE", "get").mockReturnValue(activate); + if (activate !== null) { + this.log(`Confusion forced to ${activate ? "always" : "never"} activate!`); + } else { + this.log("Confusion activation override disabled!"); + } + return this; + } + /** * Override the encounter chance for a mystery encounter. * @param percentage - The encounter chance in % diff --git a/test/testUtils/helpers/reloadHelper.ts b/test/testUtils/helpers/reloadHelper.ts index 4867a146aaf..4a9e5356968 100644 --- a/test/testUtils/helpers/reloadHelper.ts +++ b/test/testUtils/helpers/reloadHelper.ts @@ -46,6 +46,16 @@ export class ReloadHelper extends GameManagerHelper { scene.unshiftPhase(titlePhase); this.game.endPhase(); // End the currently ongoing battle + // remove all persistent mods before loading + // TODO: Look into why these aren't removed before load + if (this.game.scene.modifiers.length) { + console.log( + "Removing %d modifiers from scene on load...", + this.game.scene.modifiers.length, + this.game.scene.modifiers, + ); + this.game.scene.modifiers = []; + } titlePhase.loadSaveSlot(-1); // Load the desired session data this.game.phaseInterceptor.shift(); // Loading the save slot also ended TitlePhase, clean it up @@ -73,6 +83,6 @@ export class ReloadHelper extends GameManagerHelper { } await this.game.phaseInterceptor.to(CommandPhase); - console.log("==================[New Turn]=================="); + console.log("==================[New Turn (Reloaded)]=================="); } } diff --git a/test/utils.test.ts b/test/utils.test.ts index 33f7906738c..fe93bdd6970 100644 --- a/test/utils.test.ts +++ b/test/utils.test.ts @@ -1,5 +1,6 @@ import { expect, describe, it, beforeAll } from "vitest"; import { randomString, padInt } from "#app/utils/common"; +import { deepMergeSpriteData } from "#app/utils/data"; import Phaser from "phaser"; @@ -9,6 +10,7 @@ describe("utils", () => { type: Phaser.HEADLESS, }); }); + describe("randomString", () => { it("should return a string of the specified length", () => { const str = randomString(10); @@ -46,4 +48,33 @@ describe("utils", () => { expect(result).toBe("1"); }); }); + describe("deepMergeSpriteData", () => { + it("should merge two objects' common properties", () => { + const dest = { a: 1, b: 2 }; + const source = { a: 3, b: 3, e: 4 }; + deepMergeSpriteData(dest, source); + expect(dest).toEqual({ a: 3, b: 3 }); + }); + + it("does nothing for identical objects", () => { + const dest = { a: 1, b: 2 }; + const source = { a: 1, b: 2 }; + deepMergeSpriteData(dest, source); + expect(dest).toEqual({ a: 1, b: 2 }); + }); + + it("should preserve missing and mistyped properties", () => { + const dest = { a: 1, c: 56, d: "test" }; + const source = { a: "apple", b: 3, d: "no hablo español" }; + deepMergeSpriteData(dest, source); + expect(dest).toEqual({ a: 1, c: 56, d: "no hablo español" }); + }); + + it("should copy arrays verbatim even with mismatches", () => { + const dest = { a: 1, b: [{ d: 1 }, { d: 2 }, { d: 3 }] }; + const source = { a: 3, b: [{ c: [4, 5] }, { p: [7, 8] }], e: 4 }; + deepMergeSpriteData(dest, source); + expect(dest).toEqual({ a: 3, b: [{ c: [4, 5] }, { p: [7, 8] }] }); + }); + }); }); From 8f0eee9c4c70f3b1ef561febffa15bb19b562530 Mon Sep 17 00:00:00 2001 From: damocleas Date: Fri, 2 May 2025 01:11:02 -0400 Subject: [PATCH 02/61] [Balance] [Mystery Encounter] Many Minor Mystery Encounter Adjustments (#5726) * Update slumbering-snorlax-encounter.ts * Add Slumbering Snorlax to Tall Grass, remove Absolute Avarice from Plains * Update absolute-avarice-encounter.ts * Update absolute-avarice-encounter.ts * Update slumbering-snorlax-encounter.ts * Update slumbering-snorlax-encounter.ts * Update the-expert-pokemon-breeder-encounter.ts * Update slumbering-snorlax-encounter.ts nature * Update bug-type-superfan-encounter.ts move reward * Update bug-type-superfan-encounter.ts moves again * fix encounter waves * Update absolute-avarice-encounter.test.ts * add Nature import * Update bug-type-superfan-encounter.test.ts * greedent moves * test moves * Updated mysterious-chest-encounter.ts trap/reward chance * swapped Macho Brace stats, +2 / 10% for HP stats and +1 / 5% for all else * Update bug-type-superfan-encounter.ts moves * Update the-expert-pokemon-breeder-encounter.ts tera * Update bug-type-superfan-encounter.test.ts fix test --- .../encounters/absolute-avarice-encounter.ts | 11 ++++--- .../encounters/bug-type-superfan-encounter.ts | 28 +++++++++++------ .../encounters/mysterious-chest-encounter.ts | 4 +-- .../slumbering-snorlax-encounter.ts | 30 +++++++++++-------- .../the-expert-pokemon-breeder-encounter.ts | 7 ++--- .../mystery-encounters/mystery-encounters.ts | 4 +-- src/modifier/modifier.ts | 14 ++++----- .../absolute-avarice-encounter.test.ts | 8 +++-- .../bug-type-superfan-encounter.test.ts | 28 +++++++++++------ 9 files changed, 80 insertions(+), 54 deletions(-) diff --git a/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts b/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts index e0486c83e77..acfc8cb16a1 100644 --- a/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts +++ b/src/data/mystery-encounters/encounters/absolute-avarice-encounter.ts @@ -37,7 +37,6 @@ import type HeldModifierConfig from "#app/interfaces/held-modifier-config"; import type { BerryType } from "#enums/berry-type"; import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase"; import { Stat } from "#enums/stat"; -import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants"; import i18next from "i18next"; /** the i18n namespace for this encounter */ @@ -52,8 +51,8 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = MysteryEncounterBuilde MysteryEncounterType.ABSOLUTE_AVARICE, ) .withEncounterTier(MysteryEncounterTier.GREAT) - .withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES) - .withSceneRequirement(new PersistentModifierRequirement("BerryModifier", 4)) // Must have at least 4 berries to spawn + .withSceneWaveRangeRequirement(20, 180) + .withSceneRequirement(new PersistentModifierRequirement("BerryModifier", 6)) // Must have at least 6 berries to spawn .withFleeAllowed(false) .withIntroSpriteConfigs([ { @@ -220,9 +219,9 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = MysteryEncounterBuilde // Do NOT remove the real berries yet or else it will be persisted in the session data - // SpDef buff below wave 50, +1 to all stats otherwise + // +1 SpDef below wave 50, SpDef and Speed otherwise const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = - globalScene.currentBattle.waveIndex < 50 ? [Stat.SPDEF] : [Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD]; + globalScene.currentBattle.waveIndex < 50 ? [Stat.SPDEF] : [Stat.SPDEF, Stat.SPD]; // Calculate boss mon const config: EnemyPartyConfig = { @@ -233,7 +232,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter = MysteryEncounterBuilde isBoss: true, bossSegments: 3, shiny: false, // Shiny lock because of consistency issues between the different options - moveSet: [Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.CRUNCH], + moveSet: [Moves.THRASH, Moves.CRUNCH, Moves.BODY_PRESS, Moves.SLACK_OFF], modifierConfigs: bossModifierConfigs, tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON], mysteryEncounterBattleEffects: (pokemon: Pokemon) => { diff --git a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts index 001faf3a67f..87b223d5245 100644 --- a/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts +++ b/src/data/mystery-encounters/encounters/bug-type-superfan-encounter.ts @@ -146,24 +146,34 @@ const POOL_4_POKEMON = [Species.GENESECT, Species.SLITHER_WING, Species.BUZZWOLE const PHYSICAL_TUTOR_MOVES = [ Moves.MEGAHORN, - Moves.X_SCISSOR, Moves.ATTACK_ORDER, - Moves.PIN_MISSILE, + Moves.BUG_BITE, Moves.FIRST_IMPRESSION, + Moves.LUNGE ]; -const SPECIAL_TUTOR_MOVES = [Moves.SILVER_WIND, Moves.BUG_BUZZ, Moves.SIGNAL_BEAM, Moves.POLLEN_PUFF]; +const SPECIAL_TUTOR_MOVES = [ + Moves.SILVER_WIND, + Moves.SIGNAL_BEAM, + Moves.BUG_BUZZ, + Moves.POLLEN_PUFF, + Moves.STRUGGLE_BUG +]; -const STATUS_TUTOR_MOVES = [Moves.STRING_SHOT, Moves.STICKY_WEB, Moves.SILK_TRAP, Moves.RAGE_POWDER, Moves.HEAL_ORDER]; +const STATUS_TUTOR_MOVES = [ + Moves.STRING_SHOT, + Moves.DEFEND_ORDER, + Moves.RAGE_POWDER, + Moves.STICKY_WEB, + Moves.SILK_TRAP +]; const MISC_TUTOR_MOVES = [ - Moves.BUG_BITE, Moves.LEECH_LIFE, - Moves.DEFEND_ORDER, - Moves.QUIVER_DANCE, - Moves.TAIL_GLOW, - Moves.INFESTATION, Moves.U_TURN, + Moves.HEAL_ORDER, + Moves.QUIVER_DANCE, + Moves.INFESTATION, ]; /** diff --git a/src/data/mystery-encounters/encounters/mysterious-chest-encounter.ts b/src/data/mystery-encounters/encounters/mysterious-chest-encounter.ts index e9976ba04aa..e6c11378163 100644 --- a/src/data/mystery-encounters/encounters/mysterious-chest-encounter.ts +++ b/src/data/mystery-encounters/encounters/mysterious-chest-encounter.ts @@ -29,8 +29,8 @@ import { Species } from "#enums/species"; const namespace = "mysteryEncounters/mysteriousChest"; const RAND_LENGTH = 100; -const TRAP_PERCENT = 35; -const COMMON_REWARDS_PERCENT = 20; +const TRAP_PERCENT = 30; +const COMMON_REWARDS_PERCENT = 25; const ULTRA_REWARDS_PERCENT = 30; const ROGUE_REWARDS_PERCENT = 10; const MASTER_REWARDS_PERCENT = 5; diff --git a/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts b/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts index 41c20f35ba1..2654f6b18d8 100644 --- a/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts +++ b/src/data/mystery-encounters/encounters/slumbering-snorlax-encounter.ts @@ -19,6 +19,7 @@ import { setEncounterRewards, } from "../utils/encounter-phase-utils"; import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; +import { Nature } from "#enums/nature"; import { Moves } from "#enums/moves"; import { BattlerIndex } from "#app/battle"; import { AiType, PokemonMove } from "#app/field/pokemon"; @@ -26,9 +27,10 @@ import { getPokemonSpecies } from "#app/data/pokemon-species"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { PartyHealPhase } from "#app/phases/party-heal-phase"; -import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants"; import { BerryType } from "#enums/berry-type"; +import { Stat } from "#enums/stat"; import { CustomPokemonData } from "#app/data/custom-pokemon-data"; +import { randSeedInt } from "#app/utils/common"; /** i18n namespace for the encounter */ const namespace = "mysteryEncounters/slumberingSnorlax"; @@ -42,7 +44,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter = MysteryEncounterBuil MysteryEncounterType.SLUMBERING_SNORLAX, ) .withEncounterTier(MysteryEncounterTier.GREAT) - .withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES) + .withSceneWaveRangeRequirement(15, 150) .withCatchAllowed(true) .withHideWildIntroMessage(true) .withFleeAllowed(false) @@ -72,16 +74,26 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter = MysteryEncounterBuil species: bossSpecies, isBoss: true, shiny: false, // Shiny lock because shiny is rolled only if the battle option is picked - status: [StatusEffect.SLEEP, 5], // Extra turns on timer for Snorlax's start of fight moves - moveSet: [Moves.REST, Moves.SLEEP_TALK, Moves.CRUNCH, Moves.GIGA_IMPACT], + status: [StatusEffect.SLEEP, 6], // Extra turns on timer for Snorlax's start of fight moves + nature: Nature.DOCILE, + moveSet: [Moves.BODY_SLAM, Moves.CRUNCH, Moves.SLEEP_TALK, Moves.REST], modifierConfigs: [ { modifier: generateModifierType(modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType, - stackCount: 2, }, { modifier: generateModifierType(modifierTypes.BERRY, [BerryType.ENIGMA]) as PokemonHeldItemModifierType, - stackCount: 2, + }, + { + modifier: generateModifierType(modifierTypes.BASE_STAT_BOOSTER, [Stat.HP]) as PokemonHeldItemModifierType, + }, + { + modifier: generateModifierType(modifierTypes.SOOTHE_BELL) as PokemonHeldItemModifierType, + stackCount: randSeedInt(2, 0), + }, + { + modifier: generateModifierType(modifierTypes.LUCKY_EGG) as PokemonHeldItemModifierType, + stackCount: randSeedInt(2, 0), }, ], customPokemonData: new CustomPokemonData({ spriteScale: 1.25 }), @@ -128,12 +140,6 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter = MysteryEncounterBuil move: new PokemonMove(Moves.SNORE), ignorePp: true, }, - { - sourceBattlerIndex: BattlerIndex.ENEMY, - targets: [BattlerIndex.PLAYER], - move: new PokemonMove(Moves.SNORE), - ignorePp: true, - }, ); await initBattleWithEnemyConfig(encounter.enemyPartyConfigs[0]); }, diff --git a/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts b/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts index 076171b3e5e..15063bc2763 100644 --- a/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts @@ -11,7 +11,6 @@ import { randSeedShuffle } from "#app/utils/common"; import type MysteryEncounter from "../mystery-encounter"; import { MysteryEncounterBuilder } from "../mystery-encounter"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; -import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants"; import { Biome } from "#enums/biome"; import { TrainerType } from "#enums/trainer-type"; import i18next from "i18next"; @@ -123,7 +122,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = MysteryEncount MysteryEncounterType.THE_EXPERT_POKEMON_BREEDER, ) .withEncounterTier(MysteryEncounterTier.ULTRA) - .withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES) + .withSceneWaveRangeRequirement(25, 180) .withScenePartySizeRequirement(4, 6, true) // Must have at least 4 legal pokemon in party .withIntroSpriteConfigs([]) // These are set in onInit() .withIntroDialogue([ @@ -483,9 +482,9 @@ function getPartyConfig(): EnemyPartyConfig { abilityIndex: 1, // Magic Guard shiny: false, nature: Nature.ADAMANT, - moveSet: [Moves.METEOR_MASH, Moves.FIRE_PUNCH, Moves.ICE_PUNCH, Moves.THUNDER_PUNCH], + moveSet: [Moves.FIRE_PUNCH, Moves.ICE_PUNCH, Moves.THUNDER_PUNCH, Moves.METEOR_MASH], ivs: [31, 31, 31, 31, 31, 31], - tera: PokemonType.STEEL, + tera: PokemonType.FAIRY, }, ], }; diff --git a/src/data/mystery-encounters/mystery-encounters.ts b/src/data/mystery-encounters/mystery-encounters.ts index 5dd952b2bce..1a36dc27df2 100644 --- a/src/data/mystery-encounters/mystery-encounters.ts +++ b/src/data/mystery-encounters/mystery-encounters.ts @@ -226,9 +226,9 @@ const anyBiomeEncounters: MysteryEncounterType[] = [ */ export const mysteryEncountersByBiome = new Map([ [Biome.TOWN, []], - [Biome.PLAINS, [MysteryEncounterType.SLUMBERING_SNORLAX, MysteryEncounterType.ABSOLUTE_AVARICE]], + [Biome.PLAINS, [MysteryEncounterType.SLUMBERING_SNORLAX]], [Biome.GRASS, [MysteryEncounterType.SLUMBERING_SNORLAX, MysteryEncounterType.ABSOLUTE_AVARICE]], - [Biome.TALL_GRASS, [MysteryEncounterType.ABSOLUTE_AVARICE]], + [Biome.TALL_GRASS, [MysteryEncounterType.SLUMBERING_SNORLAX, MysteryEncounterType.ABSOLUTE_AVARICE]], [Biome.METROPOLIS, []], [Biome.FOREST, [MysteryEncounterType.SAFARI_ZONE, MysteryEncounterType.ABSOLUTE_AVARICE]], [Biome.SEA, [MysteryEncounterType.LOST_AT_SEA]], diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 2823e74fffe..9df7aa7813f 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -1114,20 +1114,20 @@ export class PokemonIncrementingStatModifier extends PokemonHeldItemModifier { * @returns always `true` */ override apply(_pokemon: Pokemon, stat: Stat, statHolder: NumberHolder): boolean { - // Modifies the passed in stat number holder by +1 per stack for HP, +2 per stack for other stats - // If the Macho Brace is at max stacks (50), adds additional 5% to total HP and 10% to other stats + // Modifies the passed in stat number holder by +2 per stack for HP, +1 per stack for other stats + // If the Macho Brace is at max stacks (50), adds additional 10% to total HP and 5% to other stats const isHp = stat === Stat.HP; if (isHp) { - statHolder.value += this.stackCount; - if (this.stackCount === this.getMaxHeldItemCount()) { - statHolder.value = Math.floor(statHolder.value * 1.05); - } - } else { statHolder.value += 2 * this.stackCount; if (this.stackCount === this.getMaxHeldItemCount()) { statHolder.value = Math.floor(statHolder.value * 1.1); } + } else { + statHolder.value += this.stackCount; + if (this.stackCount === this.getMaxHeldItemCount()) { + statHolder.value = Math.floor(statHolder.value * 1.05); + } } return true; diff --git a/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts b/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts index e00ce03333c..36a284880c1 100644 --- a/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts +++ b/test/mystery-encounter/encounters/absolute-avarice-encounter.test.ts @@ -23,7 +23,7 @@ import i18next from "i18next"; const namespace = "mysteryEncounters/absoluteAvarice"; const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; -const defaultBiome = Biome.PLAINS; +const defaultBiome = Biome.TALL_GRASS; const defaultWave = 45; describe("Absolute Avarice - Mystery Encounter", () => { @@ -45,7 +45,7 @@ describe("Absolute Avarice - Mystery Encounter", () => { vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue( new Map([ - [Biome.PLAINS, [MysteryEncounterType.ABSOLUTE_AVARICE]], + [Biome.TALL_GRASS, [MysteryEncounterType.ABSOLUTE_AVARICE]], [Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]], ]), ); @@ -91,6 +91,7 @@ describe("Absolute Avarice - Mystery Encounter", () => { game.override.startingHeldItems([ { name: "BERRY", count: 2, type: BerryType.SITRUS }, { name: "BERRY", count: 3, type: BerryType.GANLON }, + { name: "BERRY", count: 2, type: BerryType.APICOT }, ]); await game.runToMysteryEncounter(); @@ -102,6 +103,7 @@ describe("Absolute Avarice - Mystery Encounter", () => { game.override.startingHeldItems([ { name: "BERRY", count: 2, type: BerryType.SITRUS }, { name: "BERRY", count: 3, type: BerryType.GANLON }, + { name: "BERRY", count: 2, type: BerryType.APICOT }, ]); await game.runToMysteryEncounter(MysteryEncounterType.ABSOLUTE_AVARICE, defaultParty); @@ -138,7 +140,7 @@ describe("Absolute Avarice - Mystery Encounter", () => { expect(enemyField[0].species.speciesId).toBe(Species.GREEDENT); const moveset = enemyField[0].moveset.map(m => m.moveId); expect(moveset?.length).toBe(4); - expect(moveset).toEqual([Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.CRUNCH]); + expect(moveset).toEqual([Moves.THRASH, Moves.CRUNCH, Moves.BODY_PRESS, Moves.SLACK_OFF]); const movePhases = phaseSpy.mock.calls.filter(p => p[0] instanceof MovePhase).map(p => p[0]); expect(movePhases.length).toBe(1); diff --git a/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts b/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts index fc208ed7180..455a5d28194 100644 --- a/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts +++ b/test/mystery-encounter/encounters/bug-type-superfan-encounter.test.ts @@ -118,24 +118,34 @@ const POOL_4_POKEMON = [Species.GENESECT, Species.SLITHER_WING, Species.BUZZWOLE const PHYSICAL_TUTOR_MOVES = [ Moves.MEGAHORN, - Moves.X_SCISSOR, Moves.ATTACK_ORDER, - Moves.PIN_MISSILE, + Moves.BUG_BITE, Moves.FIRST_IMPRESSION, + Moves.LUNGE ]; -const SPECIAL_TUTOR_MOVES = [Moves.SILVER_WIND, Moves.BUG_BUZZ, Moves.SIGNAL_BEAM, Moves.POLLEN_PUFF]; +const SPECIAL_TUTOR_MOVES = [ + Moves.SILVER_WIND, + Moves.SIGNAL_BEAM, + Moves.BUG_BUZZ, + Moves.POLLEN_PUFF, + Moves.STRUGGLE_BUG +]; -const STATUS_TUTOR_MOVES = [Moves.STRING_SHOT, Moves.STICKY_WEB, Moves.SILK_TRAP, Moves.RAGE_POWDER, Moves.HEAL_ORDER]; +const STATUS_TUTOR_MOVES = [ + Moves.STRING_SHOT, + Moves.DEFEND_ORDER, + Moves.RAGE_POWDER, + Moves.STICKY_WEB, + Moves.SILK_TRAP +]; const MISC_TUTOR_MOVES = [ - Moves.BUG_BITE, Moves.LEECH_LIFE, - Moves.DEFEND_ORDER, - Moves.QUIVER_DANCE, - Moves.TAIL_GLOW, - Moves.INFESTATION, Moves.U_TURN, + Moves.HEAL_ORDER, + Moves.QUIVER_DANCE, + Moves.INFESTATION, ]; describe("Bug-Type Superfan - Mystery Encounter", () => { From 3a89b7bb752de892bad13d015f77dd9bd21089d2 Mon Sep 17 00:00:00 2001 From: damocleas Date: Fri, 2 May 2025 17:38:30 -0400 Subject: [PATCH 03/61] [Balance] [Beta] 1.9 Egg Move Followup (#5749) Update egg-moves.ts for Aerodactyl Amaura Diglett --- src/data/balance/egg-moves.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/data/balance/egg-moves.ts b/src/data/balance/egg-moves.ts index 47898e9e885..289ac60bcc5 100644 --- a/src/data/balance/egg-moves.ts +++ b/src/data/balance/egg-moves.ts @@ -66,7 +66,7 @@ export const speciesEggMoves = { [Species.PORYGON]: [ Moves.THUNDERCLAP, Moves.AURA_SPHERE, Moves.FLAMETHROWER, Moves.TECHNO_BLAST ], [Species.OMANYTE]: [ Moves.FREEZE_DRY, Moves.GIGA_DRAIN, Moves.POWER_GEM, Moves.STEAM_ERUPTION ], [Species.KABUTO]: [ Moves.CEASELESS_EDGE, Moves.HIGH_HORSEPOWER, Moves.CRABHAMMER, Moves.MIGHTY_CLEAVE ], - [Species.AERODACTYL]: [ Moves.FLOATY_FALL, Moves.CLOSE_COMBAT, Moves.STONE_AXE, Moves.SWORDS_DANCE ], + [Species.AERODACTYL]: [ Moves.FLOATY_FALL, Moves.HIGH_HORSEPOWER, Moves.STONE_AXE, Moves.SWORDS_DANCE ], [Species.ARTICUNO]: [ Moves.EARTH_POWER, Moves.CALM_MIND, Moves.AURORA_VEIL, Moves.AEROBLAST ], [Species.ZAPDOS]: [ Moves.BLEAKWIND_STORM, Moves.CALM_MIND, Moves.SANDSEAR_STORM, Moves.ELECTRO_SHOT ], [Species.MOLTRES]: [ Moves.EARTH_POWER, Moves.CALM_MIND, Moves.AEROBLAST, Moves.TORCH_SONG ], @@ -360,7 +360,7 @@ export const speciesEggMoves = { [Species.CLAUNCHER]: [ Moves.SHELL_SMASH, Moves.ARMOR_CANNON, Moves.ENERGY_BALL, Moves.ORIGIN_PULSE ], [Species.HELIOPTILE]: [ Moves.WEATHER_BALL, Moves.HYDRO_STEAM, Moves.EARTH_POWER, Moves.BOOMBURST ], [Species.TYRUNT]: [ Moves.DRAGON_HAMMER, Moves.FLARE_BLITZ, Moves.VOLT_TACKLE, Moves.SHIFT_GEAR ], - [Species.AMAURA]: [ Moves.RECOVER, Moves.WRING_OUT, Moves.POWER_GEM, Moves.GEOMANCY ], + [Species.AMAURA]: [ Moves.RECOVER, Moves.TERA_STARSTORM, Moves.POWER_GEM, Moves.GEOMANCY ], [Species.HAWLUCHA]: [ Moves.TRIPLE_AXEL, Moves.HIGH_HORSEPOWER, Moves.FLOATY_FALL, Moves.WICKED_BLOW ], [Species.DEDENNE]: [ Moves.BOOMBURST, Moves.FAKE_OUT, Moves.NASTY_PLOT, Moves.REVIVAL_BLESSING ], [Species.CARBINK]: [ Moves.BODY_PRESS, Moves.SHORE_UP, Moves.SPARKLY_SWIRL, Moves.DIAMOND_STORM ], @@ -436,7 +436,7 @@ export const speciesEggMoves = { [Species.ALOLA_RATTATA]: [ Moves.FALSE_SURRENDER, Moves.PSYCHIC_FANGS, Moves.COIL, Moves.EXTREME_SPEED ], [Species.ALOLA_SANDSHREW]: [ Moves.SPIKY_SHIELD, Moves.LIQUIDATION, Moves.SHIFT_GEAR, Moves.GLACIAL_LANCE ], [Species.ALOLA_VULPIX]: [ Moves.MOONBLAST, Moves.GLARE, Moves.MYSTICAL_FIRE, Moves.REVIVAL_BLESSING ], - [Species.ALOLA_DIGLETT]: [ Moves.THOUSAND_WAVES, Moves.SWORDS_DANCE, Moves.TRIPLE_DIVE, Moves.MOUNTAIN_GALE ], + [Species.ALOLA_DIGLETT]: [ Moves.THOUSAND_WAVES, Moves.SWORDS_DANCE, Moves.TRIPLE_DIVE, Moves.PYRO_BALL ], [Species.ALOLA_MEOWTH]: [ Moves.BADDY_BAD, Moves.BUZZY_BUZZ, Moves.PARTING_SHOT, Moves.MAKE_IT_RAIN ], [Species.ALOLA_GEODUDE]: [ Moves.THOUSAND_WAVES, Moves.BULK_UP, Moves.STONE_AXE, Moves.EXTREME_SPEED ], [Species.ALOLA_GRIMER]: [ Moves.SUCKER_PUNCH, Moves.BARB_BARRAGE, Moves.RECOVER, Moves.SURGING_STRIKES ], From 75d01adf9abb0385cdff1427987ad15e2eeb97da Mon Sep 17 00:00:00 2001 From: Blitzy <118096277+Blitz425@users.noreply.github.com> Date: Fri, 2 May 2025 20:05:48 -0500 Subject: [PATCH 04/61] [Bug] Disable Illusion in Fusions (#5752) Update ability.ts --- src/data/abilities/ability.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/data/abilities/ability.ts b/src/data/abilities/ability.ts index 1cb19e57533..705de6f242d 100644 --- a/src/data/abilities/ability.ts +++ b/src/data/abilities/ability.ts @@ -6907,6 +6907,8 @@ export function initAbilities() { .attr(IllusionBreakAbAttr) // The Pokemon loses its illusion when damaged by a move .attr(PostDefendIllusionBreakAbAttr, true) + // Disable Illusion in fusions + .attr(NoFusionAbilityAbAttr) // Illusion is available again after a battle .conditionalAttr((pokemon) => pokemon.isAllowedInBattle(), IllusionPostBattleAbAttr, false) .uncopiable() From bf0abd3ddcc85d1273d2a7d766f59043a3e1dfdf Mon Sep 17 00:00:00 2001 From: damocleas Date: Fri, 2 May 2025 21:32:59 -0400 Subject: [PATCH 05/61] [Move] [Beta] Undo Order Up Sheer Force change (#5750) Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/data/moves/move.ts | 5 +++-- test/moves/order_up.test.ts | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/data/moves/move.ts b/src/data/moves/move.ts index 81ae499da10..d09613123bb 100644 --- a/src/data/moves/move.ts +++ b/src/data/moves/move.ts @@ -3482,7 +3482,8 @@ export class CutHpStatStageBoostAttr extends StatStageChangeAttr { /** * Attribute implementing the stat boosting effect of {@link https://bulbapedia.bulbagarden.net/wiki/Order_Up_(move) | Order Up}. * If the user has a Pokemon with {@link https://bulbapedia.bulbagarden.net/wiki/Commander_(Ability) | Commander} in their mouth, - * one of the user's stats are increased by 1 stage, depending on the "commanding" Pokemon's form. + * one of the user's stats are increased by 1 stage, depending on the "commanding" Pokemon's form. This effect does not respect + * effect chance, but Order Up itself may be boosted by Sheer Force. */ export class OrderUpStatBoostAttr extends MoveEffectAttr { constructor() { @@ -11024,7 +11025,7 @@ export function initMoves() { .makesContact(false), new AttackMove(Moves.LUMINA_CRASH, PokemonType.PSYCHIC, MoveCategory.SPECIAL, 80, 100, 10, 100, 0, 9) .attr(StatStageChangeAttr, [ Stat.SPDEF ], -2), - new AttackMove(Moves.ORDER_UP, PokemonType.DRAGON, MoveCategory.PHYSICAL, 80, 100, 10, -1, 0, 9) + new AttackMove(Moves.ORDER_UP, PokemonType.DRAGON, MoveCategory.PHYSICAL, 80, 100, 10, 100, 0, 9) .attr(OrderUpStatBoostAttr) .makesContact(false), new AttackMove(Moves.JET_PUNCH, PokemonType.WATER, MoveCategory.PHYSICAL, 60, 100, 15, -1, 1, 9) diff --git a/test/moves/order_up.test.ts b/test/moves/order_up.test.ts index 701d0489c25..b5df5bfba41 100644 --- a/test/moves/order_up.test.ts +++ b/test/moves/order_up.test.ts @@ -65,4 +65,23 @@ describe("Moves - Order Up", () => { affectedStats.forEach(st => expect(dondozo.getStatStage(st)).toBe(st === stat ? 3 : 2)); }, ); + + it("should be boosted by Sheer Force while still applying a stat boost", async () => { + game.override.passiveAbility(Abilities.SHEER_FORCE).starterForms({ [Species.TATSUGIRI]: 0 }); + + await game.classicMode.startBattle([Species.TATSUGIRI, Species.DONDOZO]); + + const [tatsugiri, dondozo] = game.scene.getPlayerField(); + + expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY); + expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined(); + + game.move.select(Moves.ORDER_UP, 1, BattlerIndex.ENEMY); + expect(game.scene.currentBattle.turnCommands[0]?.skip).toBeTruthy(); + + await game.phaseInterceptor.to("BerryPhase", false); + + expect(dondozo.waveData.abilitiesApplied.has(Abilities.SHEER_FORCE)).toBeTruthy(); + expect(dondozo.getStatStage(Stat.ATK)).toBe(3); + }); }); From cdeb14364377fa140c6e3e397f760a885533423c Mon Sep 17 00:00:00 2001 From: damocleas Date: Fri, 2 May 2025 21:41:11 -0400 Subject: [PATCH 06/61] Version 1.8.5 -> 1.9.0 * Update package.json * Update package-lock.json --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 07fed79969e..f9280ad594b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pokemon-rogue-battle", - "version": "1.8.4", + "version": "1.9.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pokemon-rogue-battle", - "version": "1.8.4", + "version": "1.9.0", "hasInstallScript": true, "dependencies": { "@material/material-color-utilities": "^0.2.7", diff --git a/package.json b/package.json index 938d362f263..b9ccb324969 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "pokemon-rogue-battle", "private": true, - "version": "1.8.5", + "version": "1.9.0", "type": "module", "scripts": { "start": "vite", From 5fc379c405279c8f77a8b5c14ca4501a9c1fad0d Mon Sep 17 00:00:00 2001 From: Madmadness65 Date: Fri, 2 May 2025 20:43:13 -0500 Subject: [PATCH 07/61] [i18n] Update locales --- public/locales | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/locales b/public/locales index 833dc40ec74..a7036a07875 160000 --- a/public/locales +++ b/public/locales @@ -1 +1 @@ -Subproject commit 833dc40ec7409031fcea147ccbc45ec9c0ba0213 +Subproject commit a7036a07875615674ea898d0fe3b182a1080af38 From a8382d71fc8be5c0abeb53a2c2a636d1d2f89d24 Mon Sep 17 00:00:00 2001 From: Madmadness65 Date: Fri, 2 May 2025 20:45:35 -0500 Subject: [PATCH 08/61] Remove Mudbray from spring event At the request of Damocleas --- src/timed-event-manager.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/timed-event-manager.ts b/src/timed-event-manager.ts index 3f5e0393ff7..951d98aefec 100644 --- a/src/timed-event-manager.ts +++ b/src/timed-event-manager.ts @@ -340,7 +340,6 @@ const timedEvents: TimedEvent[] = [ { species: Species.DEERLING, formIndex: 0 }, // Spring Deerling { species: Species.CLAUNCHER }, { species: Species.WISHIWASHI }, - { species: Species.MUDBRAY }, { species: Species.DRAMPA }, { species: Species.JANGMO_O }, { species: Species.APPLIN }, @@ -351,7 +350,7 @@ const timedEvents: TimedEvent[] = [ { wave: 8, type: "CATCHING_CHARM" }, { wave: 25, type: "SHINY_CHARM" }, ], - } + }, ]; export class TimedEventManager { From 3cb3fd15ec9420e248d766afae90e66123002e29 Mon Sep 17 00:00:00 2001 From: Madmadness65 <59298170+Madmadness65@users.noreply.github.com> Date: Fri, 2 May 2025 20:50:23 -0500 Subject: [PATCH 09/61] [Sprite] Add missing variant icons, fix misnamed variant icons (#5751) Add missing variant icons, fix misnamed variant icons --- .../images/pokemon/icons/variant/4/417_2.png | Bin 0 -> 744 bytes .../images/pokemon/icons/variant/4/417_3.png | Bin 0 -> 747 bytes .../pokemon/icons/variant/7/746-school_1.png | Bin 747 -> 0 bytes .../pokemon/icons/variant/7/746-school_3.png | Bin 0 -> 747 bytes .../images/pokemon/icons/variant/7/746_1.png | Bin 492 -> 0 bytes .../images/pokemon/icons/variant/7/746_2.png | Bin 489 -> 492 bytes .../images/pokemon/icons/variant/7/746_3.png | Bin 0 -> 489 bytes .../images/pokemon/icons/variant/8/840_2.png | Bin 0 -> 269 bytes .../images/pokemon/icons/variant/8/840_3.png | Bin 0 -> 281 bytes .../icons/variant/8/841-gigantamax_2.png | Bin 0 -> 406 bytes .../icons/variant/8/841-gigantamax_3.png | Bin 0 -> 408 bytes .../images/pokemon/icons/variant/8/841_2.png | Bin 0 -> 397 bytes .../images/pokemon/icons/variant/8/841_3.png | Bin 0 -> 408 bytes .../icons/variant/8/842-gigantamax_2.png | Bin 0 -> 406 bytes .../icons/variant/8/842-gigantamax_3.png | Bin 0 -> 408 bytes .../images/pokemon/icons/variant/8/842_2.png | Bin 0 -> 388 bytes .../images/pokemon/icons/variant/8/842_3.png | Bin 0 -> 388 bytes .../images/pokemon/icons/variant/8/871_1.png | Bin 471 -> 0 bytes .../images/pokemon/icons/variant/8/871_2.png | Bin 474 -> 543 bytes .../images/pokemon/icons/variant/8/871_3.png | Bin 0 -> 538 bytes .../images/pokemon/icons/variant/9/1011_2.png | Bin 0 -> 344 bytes .../images/pokemon/icons/variant/9/1011_3.png | Bin 0 -> 344 bytes .../images/pokemon/icons/variant/9/1019_2.png | Bin 0 -> 492 bytes .../images/pokemon/icons/variant/9/1019_3.png | Bin 0 -> 492 bytes public/images/pokemon_icons_4v.json | 508 +++---- public/images/pokemon_icons_4v.png | Bin 46415 -> 46932 bytes public/images/pokemon_icons_7v.json | 10 +- public/images/pokemon_icons_8v.json | 1190 ++++++++++------- public/images/pokemon_icons_8v.png | Bin 46699 -> 48634 bytes public/images/pokemon_icons_9v.json | 112 +- public/images/pokemon_icons_9v.png | Bin 35071 -> 36066 bytes 31 files changed, 1078 insertions(+), 742 deletions(-) create mode 100644 public/images/pokemon/icons/variant/4/417_2.png create mode 100644 public/images/pokemon/icons/variant/4/417_3.png delete mode 100644 public/images/pokemon/icons/variant/7/746-school_1.png create mode 100644 public/images/pokemon/icons/variant/7/746-school_3.png delete mode 100644 public/images/pokemon/icons/variant/7/746_1.png create mode 100644 public/images/pokemon/icons/variant/7/746_3.png create mode 100644 public/images/pokemon/icons/variant/8/840_2.png create mode 100644 public/images/pokemon/icons/variant/8/840_3.png create mode 100644 public/images/pokemon/icons/variant/8/841-gigantamax_2.png create mode 100644 public/images/pokemon/icons/variant/8/841-gigantamax_3.png create mode 100644 public/images/pokemon/icons/variant/8/841_2.png create mode 100644 public/images/pokemon/icons/variant/8/841_3.png create mode 100644 public/images/pokemon/icons/variant/8/842-gigantamax_2.png create mode 100644 public/images/pokemon/icons/variant/8/842-gigantamax_3.png create mode 100644 public/images/pokemon/icons/variant/8/842_2.png create mode 100644 public/images/pokemon/icons/variant/8/842_3.png delete mode 100644 public/images/pokemon/icons/variant/8/871_1.png create mode 100644 public/images/pokemon/icons/variant/8/871_3.png create mode 100644 public/images/pokemon/icons/variant/9/1011_2.png create mode 100644 public/images/pokemon/icons/variant/9/1011_3.png create mode 100644 public/images/pokemon/icons/variant/9/1019_2.png create mode 100644 public/images/pokemon/icons/variant/9/1019_3.png diff --git a/public/images/pokemon/icons/variant/4/417_2.png b/public/images/pokemon/icons/variant/4/417_2.png new file mode 100644 index 0000000000000000000000000000000000000000..e1bd9e52bb009dc5a468fcecec531bbb39ebf5ca GIT binary patch literal 744 zcmVP)X00001b5ch_0Itp) z=>Px%p-DtRR9Hvtl}|_%aTLejUKTMaOlZLr7om(URtD)IWjDQak|GcZB!i-`Kq*3! z4kAbd?jcD`(Tjwq=+vb(Q3AUx_6MR2++7OELy@8>dztt?c*D=xb!T?xH?jxcW#%`( zncw^TzVCg1@K_tI% z?7*%`FyDMAMUAH_84N%b7+N6((* zvTa2^Gr(5(SDJzVjIQ~4-m`x(RE)>tG=8R)6Lmz}O+f*-o&3w=ho4?@dDZ^QW{6A& zWzHp*Ma0ReSHKUpU%1D0VsL?IO_;^X@^_&2ldXc&X00001b5ch_0Itp) z=>Px%qe(K^^$!(a_^?;j?^-)OgB`1)( z1}Lgo0nx_?q=VfRKott=!7g=A(7%a~WT&PlfOa`0fPk8N-e3ZvJ-fP0;o33(6om80 zbW>U<7+&JQ+JQg4Tz1Sq*x9qFOdC%@CZ3wp|0^BoZC z^}UF3K1rfWNXzvhx)y1rf#yOJ?&U&^zJ5EweSn`jzU5Dd0dXhV!p;N$YQUrr0N53+ zG1XJygcy*+Em3cC5O7BuZ&K+QZAbWeMmE{600U5R5AS8%8tV_?0dD~f!!WeV^%S~$ zm0_%o<=wmRYZFjaZ~oO3Gh+S9=LG#6AN39p>K#5*L4n70JA{DKqVr{}su-NFjK60{ z`3RXOb27nUPS#ZnKvbq`09kz2Pl2-QN#LTQ0HR;oc#)Ue!MOqil&aRJr<1gC>;Q-D z?5%bNc=O~@l7av{LTfzk+g%J52nN~F#{Ju-pnzNY{g?ZbRka*mHUBadM5==_ z>k!K(Qps_HKL_I5{RBNtqSeLVc5@JB2a;+xE z3Bn3kH(&zmNX00001b5ch_0Itp) z=>Px%q)9|UR9Hvtmpw=vK@`WIg#!uL03UmKc4EYDahHX0|>Z={41IWr^i*@Rlus=K`JcB zp^i@xTQ@s_!={r0#3I9u9@^ReEd&G{41ltkx$mz6ayel@83wQnI=^^G1>P)r_w7>r z1fU#qaP8-S0U^P=@1sOcET6#v&Ai!fHGw3TF!_tEa-<&FrG?p#$m< zObNJ|=0?N)0Q?mR7#Z!Pa3`do>R#2&DwvwlEus6Ax$@n%tHgtIq@a8du$qY9aW)V9 zDK^Rw`m7j9d^dM0F_Jgr7!=1i~wmGhI zP#>FX00001b5ch_0Itp) z=>Px%qe(r>DCjv=C+l9Tde&q8mhz!h&>=iVk5ck%EYl zHw7<>3f@AB4pLztf(PrCL=ae#V6vzYZ6dn5;6=2ImEt?_d&~~A``+xng@yWE-rITa z&3xwj`!`!e1#U$J&PV?NbM?@_rC=}^{1c1CJl(V>lK~8_Tw8iU7wc}5mykIF0uEpc z&xdI&{*1m&*B2h(`SwpV-@765!Bjz3Kb`8HDahGs0th%OaZCy8bXwIt1#GKoCCh(? z-u?7By4ejJHk}h77HKL@QX+mR1OyxmfU@b_msdb8Ck!aV0G2_cnQb%w`PFzd=SVq5kKQ>?i#pa zmm&1$OqrTBAUum7HyOD;30hdhQWml~*tI*IS(la48BysXaX&dyEx-ZDtqtSoHf#)Qa^i6WWEI~|bX00001b5ch_0Itp) z=>Px$q)9|UR9Hu2WEkXtage)@Vbp z90zh32!O=yU3tc^pzjnzLXjC*%)9hFZKD|7f$JBZWZ0IG33e3Bksulb<}~dF)4j)k zf$6Q?hO~7cw$KAPuyHmw18b8p*nu!dfgGeFC%}-o@)bP9Xr7C)IS>?uYiF1$bq0}x_I_6*esBPKmZhq`o^*h`_^3rJ8s{hrwpr~ zvl5-wa5+ppvSq_9b5|-#;4y{`825i^#aIt|6 zL1Z7J*B&5#sN`=3Cp&41(;vtlvO^GGw7?uapixXtjwDA9O+t_yhfp;aQ_}&2%o+_r iLLo#*e$a;?0Bl;k9}>C!fdBvi07*qoM6N<$f&c)`_Q>7< diff --git a/public/images/pokemon/icons/variant/7/746_2.png b/public/images/pokemon/icons/variant/7/746_2.png index 8746a45310dff6fa78aeabb7f9eba9d407c64907..d4897e0acf3481796b389f02aff5ecfc067ee1e4 100644 GIT binary patch delta 453 zcmV;$0XqKa1MCBkF@K~q>BS#4g-Y<44Cd?hqDd5wZZHQTdy*F>0ZZBY=6ndkW%MLlH)-7$qGT_ z&_H(FX{VnIAV-262XYt)fW+=ydB(7y?-WBqkr`ObyYxJ5qZr+R>ldD6*p`tAb`;E! zAQ}YbH0=h{y~lrn>8;&{v~?i1&;vQJaW*#tYm+h9fiOpb9Hb&Az>vA}6+Fafo{O$bq0}x_I_6*esBPKmZhq`o^*h z`_^3rJ8s{hrwpr~vl5-wa5+ppvSq_9b5|-#; z4y{`825i^#aIt|6L1Z7J*B&5#sN`=3Cp&41(;vtlvOYr)U$np+J)lucPL3o;4^2Xl v9EVUf7gN&#gv=TZK|&!!NPf_VAOLJyydM&|{eb`g002ovPDHLkV1fVufD*&M delta 450 zcmV;z0X_cg1L*^hF@K>+L_t(oN9~n8OT$1I$DgXSs6(L;unrO(M1qST2ri;upx~(B z2_eMha@W`nd6v6e?k>Olp68Mr zjdJYH5MFPZ=8xkz(xoLmQGW&$59fJN5V*g;P@>xX z3&}!i0|ue)ZjSx;SX$ln`+#9M4E_rsgTV;LPIcSw&sv+J-?A@gYp+Iz_fD0yaw0ga zS27s15rjLb)(Mb+0~i8hP4}7X$1k$x#>Lp>>qNRK4g+2_9;n_t7f=j|7IAj%iq8(L!$n$OnHPWnLj>Vu zz69YpiE9vmNR!v@ioF1YfJI|wTGSfgZhHoel|Q6w?JxMmfY^v3MQyda0*nKITywJD zx_)Mr02z{to s0U78i9wb2AUYWr-Lvi;<-rz5>_qZQfp|`C70000b%7 diff --git a/public/images/pokemon/icons/variant/7/746_3.png b/public/images/pokemon/icons/variant/7/746_3.png new file mode 100644 index 0000000000000000000000000000000000000000..8746a45310dff6fa78aeabb7f9eba9d407c64907 GIT binary patch literal 489 zcmVX00001b5ch_0Itp) z=>Px$p-DtRR9Hvtl|4(tKp4lLsp%AbR5*iy#OtqF*baG?yIk%rzxy&?8h&%=ElX?8(L!$n$OnHPWnLj>Vuz69YpiE9vmNR!v@ zioF1YfJI|wTGSfgZhHoel|Q6w?JxMmfY^v3MQyda0*nKITywJDx_)Mr02z{toEW<^Neqn@eUffF79Is7F- ze!&d?QNYvQdCP!O^`0({Ar`%FFGX{;8t|}O@XMQ&jMD#C&*-Z6C?T=rt=YW1H__01clnfXhuev$$@ Og~8L+&t;ucLK6VTn08M9 literal 0 HcmV?d00001 diff --git a/public/images/pokemon/icons/variant/8/841-gigantamax_2.png b/public/images/pokemon/icons/variant/8/841-gigantamax_2.png new file mode 100644 index 0000000000000000000000000000000000000000..aaed8081eec8fbcf46ce52506260a34c6bf3952f GIT binary patch literal 406 zcmeAS@N?(olHy`uVBq!ia0vp^8bB<^!3-obnb*7rQjEnx?oJHr&dIz4ats1|LR=LU z6+f&9`hT~6_4P;p|Nk#obky0&aq-RzZE5SOYUbT}{S&D0u*;-3^=q_)@+~VGSobEG z0fhugg8YJk>S2HZ#9((Vl>o~9@N{tuvFPo+%*c0GfrItJ{D=ap1HbQ=J=nG6)=Rfp zYFEX(x+=~!{yTL2VWL9~$EwdqWYt=JGj};%{wUn!5_$QouYgCVhf4;(qGprQw*B8~ zZfSn@J@?^k(X+ov2Lvsj&zJ5y-rT)=W^JR!Px%-3PwbqsdycV^k=XR&sgG9$RrD z63nsGXsX5TsFNAD6_l>}Eh^r9`B&vtzi%HzqDq-&e{tWMdRen((b?+4tWquCtUn%J zb$70%Pf1(7t$%NjRbPopwac{&)|(<{=I_`(Q&F&3Y07iSw|X;_H+d)LvA*5X%JsXb wNKgC5ujA)uc}HITvGtnxX*28Pvh8sv@9G{{GkwkpU??zny85}Sb4q9e0Em#d#sB~S literal 0 HcmV?d00001 diff --git a/public/images/pokemon/icons/variant/8/841_2.png b/public/images/pokemon/icons/variant/8/841_2.png new file mode 100644 index 0000000000000000000000000000000000000000..d1a57120993711dd93b8df0bf9510e24cca7d5d7 GIT binary patch literal 397 zcmeAS@N?(olHy`uVBq!ia0vp^8bB<^!3-obnb*7rQjEnx?oJHr&dIz4ats1|LR>+# zfkDBdqkUELf`Wpg)nZp)f7E1Gw`=GU@FKT6fZ0;PlR#OMCc2SX3%on3QI^tSz_}_4wBtpKr3BTCbAar*bUY z_1~9uwWW$^`{f9^U(!-*O;%kJ=xdBoi=KXo>#LZmQ-t#})o;<|?5Ql5oSq%OT+Q~F$n{@2+I#U&(Y4nV_L7C2 zf-HR>>-3l_Gvk<_y0+dA+f#gMjy~T<_LL{S^S29Ir0%SEZtj fQ;a`f{K~3vmW_3f{$*RB*BLxr{an^LB{Ts5QqHg# literal 0 HcmV?d00001 diff --git a/public/images/pokemon/icons/variant/8/841_3.png b/public/images/pokemon/icons/variant/8/841_3.png new file mode 100644 index 0000000000000000000000000000000000000000..5eaf8ea1c57373c09cf96eaa49e8e25e40e048ed GIT binary patch literal 408 zcmeAS@N?(olHy`uVBq!ia0vp^8bB<^!3-obnb*7rQjEnx?oJHr&dIz4a?ApJLR^8g zfq}vPt*amPObrSO%2$xMbMs=iv(d4Rq!l4~_x`_p_x9E1jn|&t`Pooj095Q|em`a9 z|EX`ymjF3JB|(0{4FAzV+`%?GpzJ447sn8b-m{kj^A9WVuso2FIie@h`~QD>`sEd~ z&9E%Mk^xOYVGU@G_vhJj}!0DMamv*ol$xO0wY7A29oRhfb+NrNMB5szm ztUS>ztNYL=<^No+G*b^QKJ|S%U(`dgR?V5rRbG-}bi-=tEQ|a&!Pc9p5gYH$vh=A^ zxSCpHv$pcV@s#6DJm2p=(ASCkSl2EdC+*%?rss6)*k0`r!DDN~1sB?GH~Dhh|HYqU zE6OZi=hxdy)^*CUeEV0YCmU({`oO0}52x!oB}zU%s#w?jWl!SgGA8%Pb#wc6oivKd qdi!N^18@6A?fVjoX8yeVl~Xg1E#see$3dX)89ZJ6T-G@yGywnzqr4da literal 0 HcmV?d00001 diff --git a/public/images/pokemon/icons/variant/8/842-gigantamax_2.png b/public/images/pokemon/icons/variant/8/842-gigantamax_2.png new file mode 100644 index 0000000000000000000000000000000000000000..aaed8081eec8fbcf46ce52506260a34c6bf3952f GIT binary patch literal 406 zcmeAS@N?(olHy`uVBq!ia0vp^8bB<^!3-obnb*7rQjEnx?oJHr&dIz4ats1|LR=LU z6+f&9`hT~6_4P;p|Nk#obky0&aq-RzZE5SOYUbT}{S&D0u*;-3^=q_)@+~VGSobEG z0fhugg8YJk>S2HZ#9((Vl>o~9@N{tuvFPo+%*c0GfrItJ{D=ap1HbQ=J=nG6)=Rfp zYFEX(x+=~!{yTL2VWL9~$EwdqWYt=JGj};%{wUn!5_$QouYgCVhf4;(qGprQw*B8~ zZfSn@J@?^k(X+ov2Lvsj&zJ5y-rT)=W^JR!Px%-3PwbqsdycV^k=XR&sgG9$RrD z63nsGXsX5TsFNAD6_l>}Eh^r9`B&vtzi%HzqDq-&e{tWMdRen((b?+4tWquCtUn%J zb$70%Pf1(7t$%NjRbPopwac{&)|(<{=I_`(Q&F&3Y07iSw|X;_H+d)LvA*5X%JsXb wNKgC5ujA)uc}HITvGtnxX*28Pvh8sv@9G{{GkwkpU??zny85}Sb4q9e0Em#d#sB~S literal 0 HcmV?d00001 diff --git a/public/images/pokemon/icons/variant/8/842_2.png b/public/images/pokemon/icons/variant/8/842_2.png new file mode 100644 index 0000000000000000000000000000000000000000..87de609f819c7459d0826780608ea18257222500 GIT binary patch literal 388 zcmeAS@N?(olHy`uVBq!ia0vp^8bB<^!3-obnb*7rQjEnx?oJHr&dIz4ats1|LR>+# zfx+tQk7g~{91swo9h7fb(U94@MNcyL@87=#i;h;+%mb=PFPPJ+ns6^4$Ja^u-ec7jV%l5w35xBrIFLKYt zT#kd6FQf#ghCC15-l@F%{gnM#Uk+}3zxHX>X%C6|)PrGXANxqFUrN2$D#CNfQLaD1 zao+lb(CZRbcAjEBO=;mrG8~+?O*ziIQ+2|wK7Ku=69M+}_od!H(5x3S;QSr7mqGp_ W`_c3z=lFm=X7F_Nb6Mw<&;$S>x2*vH literal 0 HcmV?d00001 diff --git a/public/images/pokemon/icons/variant/8/842_3.png b/public/images/pokemon/icons/variant/8/842_3.png new file mode 100644 index 0000000000000000000000000000000000000000..15dfe7ea02caed0cd7141dfa16e160c9dc43581b GIT binary patch literal 388 zcmeAS@N?(olHy`uVBq!ia0vp^8bB<^!3-obnb*7rQjEnx?oJHr&dIz4ats1|LR>+# zfx(@d7a#RZ4G0LhxT5aegFVUa*4~QJfB*j7zjgJBkUXH8Ma{Kt=J!)p{@)_glndkw zlmz(&GyF#d2LigCfpX70T^vI!dXHYd-F4W2hvh=w;%@1S&;I}4rrf%TJ3IaF6)qVj zOG(b-JMY>B9MH;%c$_iCLagW_%kkn=h7%vBv|ck1Ec~7BwJGlDwe=~RcCVTl>#bs( zF1lqU%i=q$H^;j^O1XFToM!q&1N{k`s?I9~MxG13@Z5RR_GO>eE!+EAN8kd>yvRKl zb2$!PzK{}}8uC1Jd#Cd5_fz&~eL1-C{o1Ehr#&R_^j=oZ|!fn8DN4&t;ucLK6VjU#?34 literal 0 HcmV?d00001 diff --git a/public/images/pokemon/icons/variant/8/871_1.png b/public/images/pokemon/icons/variant/8/871_1.png deleted file mode 100644 index ff77c60cea26e2f99e50106a57e30a4f09db0c4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 471 zcmV;|0Vw{7P)Px$k4Z#9R9Hvtn6XL&K@f%~*yuZ0MvS1C6CcFJ&Q7cp!RN3Ljg_L6osEUyONgWp zOwh*=w2S;J|FK!lOIY14m}nKiTa_ff74m{~LXYry7gt|XY*TxNd&t-RDM3Vze+00000 NNkvXXu0mjf0040z(OUoj diff --git a/public/images/pokemon/icons/variant/8/871_2.png b/public/images/pokemon/icons/variant/8/871_2.png index bfefb010219cef18084f42ec879cf851b55310ef..719ee1eb3a9c114f9994b82a6f5503c5519aa5bf 100644 GIT binary patch literal 543 zcmeAS@N?(olHy`uVBq!ia0vp^8bB<^!3-obnb*7rQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`B?5dxT#Yo<&sG{Fwboe0hA+^GI1&-@@x=?EWa%#<10cmw666>B9|9Qe zHSdiCig6ZrL>4nJ@ErzW#^d=bQb2~4xJHx&=ckpFCl;kL1SDqWmFW4ohA5co8S0t+ zxp;g%P|dc~2+uT6Pb~%xAcvJfijkFp5ynupK>$cc0dZzK z3s^i0$OeG~AO`7&(P)-30K;JdI|B<)g@KW=0pkLQsURJ!3m_&<0kT1W31|)zSY?o< z1&{^RWoQ5j0)|5z_1CVdM)?An(>z@qLoEECPI$=IV!+WXIHUT%`MznD^A~ZPP2WO73E;Gsz&EPzKq3$6z^jd&J9OGHa6*= zJ@0pgjrFSHWY-6dS?}hab07+cG5;)Y=ZoDt vgTe~DWM4f%fOs7 literal 474 zcmV<00VV#4P)Px$lu1NER9Hvtn6XL&K@f%~ub_wsT4-ZuA&QMppa_DUq!4TrG;iQ@M64`=g`lOi zg^ef{b~ail1RGyL`B(n1SwI zSikF=bT>hTpP zA;MNn{1`MFV_7Tosj!tV}##9h-fwE6v2dzHk0Xpp1vF{W&1TUJ~RN{2vS$q`aBk zfI^%F9+AZi419+{nDKc2iWH!rM2TxeNpOBzNqJ&XDnmeGW?qS&pKFMMsh**p*`JHY z*8|mTOO5bM^YqkW-~e)18Kf9l85n^qFCdnNvcW!JWCn{f0mTg&nHU6sbQBP0wzGi6 zvw&<6NC0Axei)5rDFZMJCa^QG096!MXrq(i9*Y1ek#4Fo9JDSy}*D zP+f)w1|Zo(9QD_(sz&(&nNvMo978PppH2wmJ8Zz=tl4ts|B0=VLENVodHue%#V|?KQhe^4TJDnSjgnVSVJ?sA5 z6{@UX6}w#@xMsbL^;Mc8`Tt)~rGJ~z=GaFCPUo(AEp6s2wCLN#-u~O*z>D2G6rKHabV59X-r21&f$teO5DEak-(R=msX`#ak9IO{s&*)hH@BeeQH_NgVxP4QEKK4I{5^>bP0l+XkKCV-aC literal 0 HcmV?d00001 diff --git a/public/images/pokemon/icons/variant/9/1011_3.png b/public/images/pokemon/icons/variant/9/1011_3.png new file mode 100644 index 0000000000000000000000000000000000000000..fa5e3e351352fb3cd797346f71424ca2de5436ae GIT binary patch literal 344 zcmeAS@N?(olHy`uVBq!ia0vp^8bB<^!3-obnb*7rQjEnx?oJHr&dIz4a&!ZHLR=LU z6(99XOm);q}g#sB~RSA^t!et+-rrKNMie8MFpF0QECGG_)*$7LPAA3%z~ zB*-rqs0;}(T)8u2Ay8_cr;B5VMeo(ir-cqHaIjujJ)>j&zyHtK-YoO-i7g3E+tiu9 zyL)z4*}Q$iB}yr-CI literal 0 HcmV?d00001 diff --git a/public/images/pokemon/icons/variant/9/1019_2.png b/public/images/pokemon/icons/variant/9/1019_2.png new file mode 100644 index 0000000000000000000000000000000000000000..671ae3f6552063d6c01a178f386541da435830f9 GIT binary patch literal 492 zcmeAS@N?(olHy`uVBq!ia0vp^8bB<^!3-obnb*7rQjEnx?oJHr&dIz4ax4RULR=LU z6+PT@f`WpygYx~R&8w=JH*3M>JFkB}-t@6OXwl-G7ykeMZ!O|jHgT(`tQSyf$C>+S zM(IG^yY?;Q1yaH#L4LtNHE4igQ|%oNpnXoBE{-7NQ9b$7B+i{=;0>=nh0!80Vj2b8p5X6Xz(E>Nww-X;C7#N&d#2R&=9 z%)B6`sTX@lcv^t;jZc~HqgEJ)Z?xFiD79sZ)}-kt8jtRN{Y>U)!K8+Q#oh-W=^8W~ z|5(JElUmEX{g=|_?|;tgwygUz^~kMIea&o-@0%3E%Xq9pmhWv-ogcf}Dr)+UW$y*2 zJgK#M;-zk0;OwQTzS!qPpT?8gcY(~G)s0U~-rn}yvo!L;LEiaF#oIX5A}h?Meg3;s z=f9q1cz)l_y7wWEEspc&S{YwkYGxpx82YqjHtY7DpW>Mn8t1GJT$)&Vzu{lQyTaN% ae;EZFY`D7i_s#+aHiM_DpUXO@geCwj!{dYi literal 0 HcmV?d00001 diff --git a/public/images/pokemon/icons/variant/9/1019_3.png b/public/images/pokemon/icons/variant/9/1019_3.png new file mode 100644 index 0000000000000000000000000000000000000000..0569b3e84b6409b1ce3ca680941d35125f428257 GIT binary patch literal 492 zcmeAS@N?(olHy`uVBq!ia0vp^8bB<^!3-obnb*7rQjEnx?oJHr&dIz4ax4RULR=LU z6$7=kgMxzg&nS3zf5-BmoR2-z9^JY2c+sCX+$AjE#&Gqvg4tkdgT@=_d z`NuA%`Namucbwwlx;xpZMe~bg_KM=h;29F%14`O2vvdX?7pPWT?~?vk;&DOWgPt{4 zW?m4})QdeNJS{-_#;45pQ7eqYH(Km$l-e>yYtr-+jYoICekOCYU{XWDV(){GbPXDg ze=Oq7Nv&nx{!3}|_dn-#Th{%VdgNB9zGk+^_f3l7Wjt0P%lEda&W~Mf6*YawviE{h zp43`B@lrQ0aQ4zvU+ic%G~Z*P0t&FcNH8YS;41L-%n{|87Pw~tOjdRuqE=?@G-|(;DU19B> azl;J7He6l%duIUyo59o7&t;ucLK6UNjpQ!? literal 0 HcmV?d00001 diff --git a/public/images/pokemon_icons_4v.json b/public/images/pokemon_icons_4v.json index bbaca92c7c7..ffc36e945c4 100644 --- a/public/images/pokemon_icons_4v.json +++ b/public/images/pokemon_icons_4v.json @@ -1312,7 +1312,7 @@ } }, { - "filename": "418_2", + "filename": "417_2", "rotated": false, "trimmed": false, "sourceSize": { @@ -1332,6 +1332,48 @@ "h": 30 } }, + { + "filename": "417_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 120, + "w": 40, + "h": 30 + } + }, + { + "filename": "418_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 480, + "y": 120, + "w": 40, + "h": 30 + } + }, { "filename": "418_3", "rotated": false, @@ -1347,8 +1389,8 @@ "h": 30 }, "frame": { - "x": 440, - "y": 120, + "x": 0, + "y": 150, "w": 40, "h": 30 } @@ -1368,8 +1410,8 @@ "h": 30 }, "frame": { - "x": 480, - "y": 120, + "x": 40, + "y": 150, "w": 40, "h": 30 } @@ -1389,7 +1431,7 @@ "h": 30 }, "frame": { - "x": 0, + "x": 80, "y": 150, "w": 40, "h": 30 @@ -1410,7 +1452,7 @@ "h": 30 }, "frame": { - "x": 40, + "x": 120, "y": 150, "w": 40, "h": 30 @@ -1431,7 +1473,7 @@ "h": 30 }, "frame": { - "x": 80, + "x": 160, "y": 150, "w": 40, "h": 30 @@ -1452,7 +1494,7 @@ "h": 30 }, "frame": { - "x": 120, + "x": 200, "y": 150, "w": 40, "h": 30 @@ -1473,7 +1515,7 @@ "h": 30 }, "frame": { - "x": 160, + "x": 240, "y": 150, "w": 40, "h": 30 @@ -1494,7 +1536,7 @@ "h": 30 }, "frame": { - "x": 200, + "x": 280, "y": 150, "w": 40, "h": 30 @@ -1515,7 +1557,7 @@ "h": 30 }, "frame": { - "x": 240, + "x": 320, "y": 150, "w": 40, "h": 30 @@ -1536,7 +1578,7 @@ "h": 30 }, "frame": { - "x": 280, + "x": 360, "y": 150, "w": 40, "h": 30 @@ -1557,7 +1599,7 @@ "h": 30 }, "frame": { - "x": 320, + "x": 400, "y": 150, "w": 40, "h": 30 @@ -1578,7 +1620,7 @@ "h": 30 }, "frame": { - "x": 360, + "x": 440, "y": 150, "w": 40, "h": 30 @@ -1599,7 +1641,7 @@ "h": 30 }, "frame": { - "x": 400, + "x": 480, "y": 150, "w": 40, "h": 30 @@ -1620,8 +1662,8 @@ "h": 30 }, "frame": { - "x": 440, - "y": 150, + "x": 0, + "y": 180, "w": 40, "h": 30 } @@ -1641,8 +1683,8 @@ "h": 30 }, "frame": { - "x": 480, - "y": 150, + "x": 40, + "y": 180, "w": 40, "h": 30 } @@ -1662,7 +1704,7 @@ "h": 30 }, "frame": { - "x": 0, + "x": 80, "y": 180, "w": 40, "h": 30 @@ -1683,7 +1725,7 @@ "h": 30 }, "frame": { - "x": 40, + "x": 120, "y": 180, "w": 40, "h": 30 @@ -1704,7 +1746,7 @@ "h": 30 }, "frame": { - "x": 80, + "x": 160, "y": 180, "w": 40, "h": 30 @@ -1725,7 +1767,7 @@ "h": 30 }, "frame": { - "x": 120, + "x": 200, "y": 180, "w": 40, "h": 30 @@ -1746,7 +1788,7 @@ "h": 30 }, "frame": { - "x": 160, + "x": 240, "y": 180, "w": 40, "h": 30 @@ -1767,7 +1809,7 @@ "h": 30 }, "frame": { - "x": 200, + "x": 280, "y": 180, "w": 40, "h": 30 @@ -1788,7 +1830,7 @@ "h": 30 }, "frame": { - "x": 240, + "x": 320, "y": 180, "w": 40, "h": 30 @@ -1809,7 +1851,7 @@ "h": 30 }, "frame": { - "x": 280, + "x": 360, "y": 180, "w": 40, "h": 30 @@ -1830,7 +1872,7 @@ "h": 30 }, "frame": { - "x": 320, + "x": 400, "y": 180, "w": 40, "h": 30 @@ -1851,7 +1893,7 @@ "h": 30 }, "frame": { - "x": 360, + "x": 440, "y": 180, "w": 40, "h": 30 @@ -1872,7 +1914,7 @@ "h": 30 }, "frame": { - "x": 400, + "x": 480, "y": 180, "w": 40, "h": 30 @@ -1893,8 +1935,8 @@ "h": 30 }, "frame": { - "x": 440, - "y": 180, + "x": 0, + "y": 210, "w": 40, "h": 30 } @@ -1914,8 +1956,8 @@ "h": 30 }, "frame": { - "x": 480, - "y": 180, + "x": 40, + "y": 210, "w": 40, "h": 30 } @@ -1935,7 +1977,7 @@ "h": 30 }, "frame": { - "x": 0, + "x": 80, "y": 210, "w": 40, "h": 30 @@ -1956,7 +1998,7 @@ "h": 30 }, "frame": { - "x": 40, + "x": 120, "y": 210, "w": 40, "h": 30 @@ -1977,7 +2019,7 @@ "h": 30 }, "frame": { - "x": 80, + "x": 160, "y": 210, "w": 40, "h": 30 @@ -1998,7 +2040,7 @@ "h": 30 }, "frame": { - "x": 120, + "x": 200, "y": 210, "w": 40, "h": 30 @@ -2019,7 +2061,7 @@ "h": 30 }, "frame": { - "x": 160, + "x": 240, "y": 210, "w": 40, "h": 30 @@ -2040,7 +2082,7 @@ "h": 30 }, "frame": { - "x": 200, + "x": 280, "y": 210, "w": 40, "h": 30 @@ -2061,7 +2103,7 @@ "h": 30 }, "frame": { - "x": 240, + "x": 320, "y": 210, "w": 40, "h": 30 @@ -2082,7 +2124,7 @@ "h": 30 }, "frame": { - "x": 280, + "x": 360, "y": 210, "w": 40, "h": 30 @@ -2103,7 +2145,7 @@ "h": 30 }, "frame": { - "x": 320, + "x": 400, "y": 210, "w": 40, "h": 30 @@ -2124,7 +2166,7 @@ "h": 30 }, "frame": { - "x": 360, + "x": 440, "y": 210, "w": 40, "h": 30 @@ -2145,7 +2187,7 @@ "h": 30 }, "frame": { - "x": 400, + "x": 480, "y": 210, "w": 40, "h": 30 @@ -2166,8 +2208,8 @@ "h": 30 }, "frame": { - "x": 440, - "y": 210, + "x": 0, + "y": 240, "w": 40, "h": 30 } @@ -2187,8 +2229,8 @@ "h": 30 }, "frame": { - "x": 480, - "y": 210, + "x": 40, + "y": 240, "w": 40, "h": 30 } @@ -2208,7 +2250,7 @@ "h": 30 }, "frame": { - "x": 0, + "x": 80, "y": 240, "w": 40, "h": 30 @@ -2229,7 +2271,7 @@ "h": 30 }, "frame": { - "x": 40, + "x": 120, "y": 240, "w": 40, "h": 30 @@ -2250,7 +2292,7 @@ "h": 30 }, "frame": { - "x": 80, + "x": 160, "y": 240, "w": 40, "h": 30 @@ -2271,7 +2313,7 @@ "h": 30 }, "frame": { - "x": 120, + "x": 200, "y": 240, "w": 40, "h": 30 @@ -2292,7 +2334,7 @@ "h": 30 }, "frame": { - "x": 160, + "x": 240, "y": 240, "w": 40, "h": 30 @@ -2313,7 +2355,7 @@ "h": 30 }, "frame": { - "x": 200, + "x": 280, "y": 240, "w": 40, "h": 30 @@ -2334,7 +2376,7 @@ "h": 30 }, "frame": { - "x": 240, + "x": 320, "y": 240, "w": 40, "h": 30 @@ -2355,7 +2397,7 @@ "h": 30 }, "frame": { - "x": 280, + "x": 360, "y": 240, "w": 40, "h": 30 @@ -2376,7 +2418,7 @@ "h": 30 }, "frame": { - "x": 320, + "x": 400, "y": 240, "w": 40, "h": 30 @@ -2397,7 +2439,7 @@ "h": 30 }, "frame": { - "x": 360, + "x": 440, "y": 240, "w": 40, "h": 30 @@ -2418,7 +2460,7 @@ "h": 30 }, "frame": { - "x": 400, + "x": 480, "y": 240, "w": 40, "h": 30 @@ -2439,8 +2481,8 @@ "h": 30 }, "frame": { - "x": 440, - "y": 240, + "x": 0, + "y": 270, "w": 40, "h": 30 } @@ -2460,8 +2502,8 @@ "h": 30 }, "frame": { - "x": 480, - "y": 240, + "x": 40, + "y": 270, "w": 40, "h": 30 } @@ -2481,7 +2523,7 @@ "h": 30 }, "frame": { - "x": 0, + "x": 80, "y": 270, "w": 40, "h": 30 @@ -2502,7 +2544,7 @@ "h": 30 }, "frame": { - "x": 40, + "x": 120, "y": 270, "w": 40, "h": 30 @@ -2523,7 +2565,7 @@ "h": 30 }, "frame": { - "x": 80, + "x": 160, "y": 270, "w": 40, "h": 30 @@ -2544,7 +2586,7 @@ "h": 30 }, "frame": { - "x": 120, + "x": 200, "y": 270, "w": 40, "h": 30 @@ -2565,7 +2607,7 @@ "h": 30 }, "frame": { - "x": 160, + "x": 240, "y": 270, "w": 40, "h": 30 @@ -2586,7 +2628,7 @@ "h": 30 }, "frame": { - "x": 200, + "x": 280, "y": 270, "w": 40, "h": 30 @@ -2607,7 +2649,7 @@ "h": 30 }, "frame": { - "x": 240, + "x": 320, "y": 270, "w": 40, "h": 30 @@ -2628,7 +2670,7 @@ "h": 30 }, "frame": { - "x": 280, + "x": 360, "y": 270, "w": 40, "h": 30 @@ -2649,7 +2691,7 @@ "h": 30 }, "frame": { - "x": 320, + "x": 400, "y": 270, "w": 40, "h": 30 @@ -2670,7 +2712,7 @@ "h": 30 }, "frame": { - "x": 360, + "x": 440, "y": 270, "w": 40, "h": 30 @@ -2691,7 +2733,7 @@ "h": 30 }, "frame": { - "x": 400, + "x": 480, "y": 270, "w": 40, "h": 30 @@ -2712,8 +2754,8 @@ "h": 30 }, "frame": { - "x": 440, - "y": 270, + "x": 0, + "y": 300, "w": 40, "h": 30 } @@ -2733,8 +2775,8 @@ "h": 30 }, "frame": { - "x": 480, - "y": 270, + "x": 40, + "y": 300, "w": 40, "h": 30 } @@ -2754,7 +2796,7 @@ "h": 30 }, "frame": { - "x": 0, + "x": 80, "y": 300, "w": 40, "h": 30 @@ -2775,7 +2817,7 @@ "h": 30 }, "frame": { - "x": 40, + "x": 120, "y": 300, "w": 40, "h": 30 @@ -2796,7 +2838,7 @@ "h": 30 }, "frame": { - "x": 80, + "x": 160, "y": 300, "w": 40, "h": 30 @@ -2817,7 +2859,7 @@ "h": 30 }, "frame": { - "x": 120, + "x": 200, "y": 300, "w": 40, "h": 30 @@ -2838,7 +2880,7 @@ "h": 30 }, "frame": { - "x": 160, + "x": 240, "y": 300, "w": 40, "h": 30 @@ -2859,7 +2901,7 @@ "h": 30 }, "frame": { - "x": 200, + "x": 280, "y": 300, "w": 40, "h": 30 @@ -2880,7 +2922,7 @@ "h": 30 }, "frame": { - "x": 240, + "x": 320, "y": 300, "w": 40, "h": 30 @@ -2901,7 +2943,7 @@ "h": 30 }, "frame": { - "x": 280, + "x": 360, "y": 300, "w": 40, "h": 30 @@ -2922,7 +2964,7 @@ "h": 30 }, "frame": { - "x": 320, + "x": 400, "y": 300, "w": 40, "h": 30 @@ -2943,7 +2985,7 @@ "h": 30 }, "frame": { - "x": 360, + "x": 440, "y": 300, "w": 40, "h": 30 @@ -2964,7 +3006,7 @@ "h": 30 }, "frame": { - "x": 400, + "x": 480, "y": 300, "w": 40, "h": 30 @@ -2985,8 +3027,8 @@ "h": 30 }, "frame": { - "x": 440, - "y": 300, + "x": 0, + "y": 330, "w": 40, "h": 30 } @@ -3006,8 +3048,8 @@ "h": 30 }, "frame": { - "x": 480, - "y": 300, + "x": 40, + "y": 330, "w": 40, "h": 30 } @@ -3027,7 +3069,7 @@ "h": 30 }, "frame": { - "x": 0, + "x": 80, "y": 330, "w": 40, "h": 30 @@ -3048,7 +3090,7 @@ "h": 30 }, "frame": { - "x": 40, + "x": 120, "y": 330, "w": 40, "h": 30 @@ -3069,7 +3111,7 @@ "h": 30 }, "frame": { - "x": 80, + "x": 160, "y": 330, "w": 40, "h": 30 @@ -3090,7 +3132,7 @@ "h": 30 }, "frame": { - "x": 120, + "x": 200, "y": 330, "w": 40, "h": 30 @@ -3111,7 +3153,7 @@ "h": 30 }, "frame": { - "x": 160, + "x": 240, "y": 330, "w": 40, "h": 30 @@ -3132,7 +3174,7 @@ "h": 30 }, "frame": { - "x": 200, + "x": 280, "y": 330, "w": 40, "h": 30 @@ -3153,7 +3195,7 @@ "h": 30 }, "frame": { - "x": 240, + "x": 320, "y": 330, "w": 40, "h": 30 @@ -3174,7 +3216,7 @@ "h": 30 }, "frame": { - "x": 280, + "x": 360, "y": 330, "w": 40, "h": 30 @@ -3195,7 +3237,7 @@ "h": 30 }, "frame": { - "x": 320, + "x": 400, "y": 330, "w": 40, "h": 30 @@ -3216,7 +3258,7 @@ "h": 30 }, "frame": { - "x": 360, + "x": 440, "y": 330, "w": 40, "h": 30 @@ -3237,7 +3279,7 @@ "h": 30 }, "frame": { - "x": 400, + "x": 480, "y": 330, "w": 40, "h": 30 @@ -3258,8 +3300,8 @@ "h": 30 }, "frame": { - "x": 440, - "y": 330, + "x": 0, + "y": 360, "w": 40, "h": 30 } @@ -3279,8 +3321,8 @@ "h": 30 }, "frame": { - "x": 480, - "y": 330, + "x": 40, + "y": 360, "w": 40, "h": 30 } @@ -3300,7 +3342,7 @@ "h": 30 }, "frame": { - "x": 0, + "x": 80, "y": 360, "w": 40, "h": 30 @@ -3321,7 +3363,7 @@ "h": 30 }, "frame": { - "x": 40, + "x": 120, "y": 360, "w": 40, "h": 30 @@ -3342,7 +3384,7 @@ "h": 30 }, "frame": { - "x": 80, + "x": 160, "y": 360, "w": 40, "h": 30 @@ -3363,7 +3405,7 @@ "h": 30 }, "frame": { - "x": 120, + "x": 200, "y": 360, "w": 40, "h": 30 @@ -3384,7 +3426,7 @@ "h": 30 }, "frame": { - "x": 160, + "x": 240, "y": 360, "w": 40, "h": 30 @@ -3405,7 +3447,7 @@ "h": 30 }, "frame": { - "x": 200, + "x": 280, "y": 360, "w": 40, "h": 30 @@ -3426,7 +3468,7 @@ "h": 30 }, "frame": { - "x": 240, + "x": 320, "y": 360, "w": 40, "h": 30 @@ -3447,7 +3489,7 @@ "h": 30 }, "frame": { - "x": 280, + "x": 360, "y": 360, "w": 40, "h": 30 @@ -3468,7 +3510,7 @@ "h": 30 }, "frame": { - "x": 320, + "x": 400, "y": 360, "w": 40, "h": 30 @@ -3489,7 +3531,7 @@ "h": 30 }, "frame": { - "x": 360, + "x": 440, "y": 360, "w": 40, "h": 30 @@ -3510,7 +3552,7 @@ "h": 30 }, "frame": { - "x": 400, + "x": 480, "y": 360, "w": 40, "h": 30 @@ -3531,8 +3573,8 @@ "h": 30 }, "frame": { - "x": 440, - "y": 360, + "x": 0, + "y": 390, "w": 40, "h": 30 } @@ -3552,8 +3594,8 @@ "h": 30 }, "frame": { - "x": 480, - "y": 360, + "x": 40, + "y": 390, "w": 40, "h": 30 } @@ -3573,7 +3615,7 @@ "h": 30 }, "frame": { - "x": 0, + "x": 80, "y": 390, "w": 40, "h": 30 @@ -3594,7 +3636,7 @@ "h": 30 }, "frame": { - "x": 40, + "x": 120, "y": 390, "w": 40, "h": 30 @@ -3615,7 +3657,7 @@ "h": 30 }, "frame": { - "x": 80, + "x": 160, "y": 390, "w": 40, "h": 30 @@ -3636,7 +3678,7 @@ "h": 30 }, "frame": { - "x": 120, + "x": 200, "y": 390, "w": 40, "h": 30 @@ -3657,7 +3699,7 @@ "h": 30 }, "frame": { - "x": 160, + "x": 240, "y": 390, "w": 40, "h": 30 @@ -3678,7 +3720,7 @@ "h": 30 }, "frame": { - "x": 200, + "x": 280, "y": 390, "w": 40, "h": 30 @@ -3699,7 +3741,7 @@ "h": 30 }, "frame": { - "x": 240, + "x": 320, "y": 390, "w": 40, "h": 30 @@ -3720,7 +3762,7 @@ "h": 30 }, "frame": { - "x": 280, + "x": 360, "y": 390, "w": 40, "h": 30 @@ -3741,7 +3783,7 @@ "h": 30 }, "frame": { - "x": 320, + "x": 400, "y": 390, "w": 40, "h": 30 @@ -3762,7 +3804,7 @@ "h": 30 }, "frame": { - "x": 360, + "x": 440, "y": 390, "w": 40, "h": 30 @@ -3783,7 +3825,7 @@ "h": 30 }, "frame": { - "x": 400, + "x": 480, "y": 390, "w": 40, "h": 30 @@ -3804,8 +3846,8 @@ "h": 30 }, "frame": { - "x": 440, - "y": 390, + "x": 0, + "y": 420, "w": 40, "h": 30 } @@ -3825,8 +3867,8 @@ "h": 30 }, "frame": { - "x": 480, - "y": 390, + "x": 40, + "y": 420, "w": 40, "h": 30 } @@ -3846,7 +3888,7 @@ "h": 30 }, "frame": { - "x": 0, + "x": 80, "y": 420, "w": 40, "h": 30 @@ -3867,7 +3909,7 @@ "h": 30 }, "frame": { - "x": 40, + "x": 120, "y": 420, "w": 40, "h": 30 @@ -3888,7 +3930,7 @@ "h": 30 }, "frame": { - "x": 80, + "x": 160, "y": 420, "w": 40, "h": 30 @@ -3909,7 +3951,7 @@ "h": 30 }, "frame": { - "x": 120, + "x": 200, "y": 420, "w": 40, "h": 30 @@ -3930,7 +3972,7 @@ "h": 30 }, "frame": { - "x": 160, + "x": 240, "y": 420, "w": 40, "h": 30 @@ -3951,7 +3993,7 @@ "h": 30 }, "frame": { - "x": 200, + "x": 280, "y": 420, "w": 40, "h": 30 @@ -3972,7 +4014,7 @@ "h": 30 }, "frame": { - "x": 240, + "x": 320, "y": 420, "w": 40, "h": 30 @@ -3993,7 +4035,7 @@ "h": 30 }, "frame": { - "x": 280, + "x": 360, "y": 420, "w": 40, "h": 30 @@ -4014,7 +4056,7 @@ "h": 30 }, "frame": { - "x": 320, + "x": 400, "y": 420, "w": 40, "h": 30 @@ -4035,7 +4077,7 @@ "h": 30 }, "frame": { - "x": 360, + "x": 440, "y": 420, "w": 40, "h": 30 @@ -4056,7 +4098,7 @@ "h": 30 }, "frame": { - "x": 400, + "x": 480, "y": 420, "w": 40, "h": 30 @@ -4077,8 +4119,8 @@ "h": 30 }, "frame": { - "x": 440, - "y": 420, + "x": 0, + "y": 450, "w": 40, "h": 30 } @@ -4098,8 +4140,8 @@ "h": 30 }, "frame": { - "x": 480, - "y": 420, + "x": 40, + "y": 450, "w": 40, "h": 30 } @@ -4119,7 +4161,7 @@ "h": 30 }, "frame": { - "x": 0, + "x": 80, "y": 450, "w": 40, "h": 30 @@ -4140,7 +4182,7 @@ "h": 30 }, "frame": { - "x": 40, + "x": 120, "y": 450, "w": 40, "h": 30 @@ -4161,7 +4203,7 @@ "h": 30 }, "frame": { - "x": 80, + "x": 160, "y": 450, "w": 40, "h": 30 @@ -4182,7 +4224,7 @@ "h": 30 }, "frame": { - "x": 120, + "x": 200, "y": 450, "w": 40, "h": 30 @@ -4203,7 +4245,7 @@ "h": 30 }, "frame": { - "x": 160, + "x": 240, "y": 450, "w": 40, "h": 30 @@ -4224,7 +4266,7 @@ "h": 30 }, "frame": { - "x": 200, + "x": 280, "y": 450, "w": 40, "h": 30 @@ -4245,7 +4287,7 @@ "h": 30 }, "frame": { - "x": 240, + "x": 320, "y": 450, "w": 40, "h": 30 @@ -4266,7 +4308,7 @@ "h": 30 }, "frame": { - "x": 280, + "x": 360, "y": 450, "w": 40, "h": 30 @@ -4287,7 +4329,7 @@ "h": 30 }, "frame": { - "x": 320, + "x": 400, "y": 450, "w": 40, "h": 30 @@ -4308,7 +4350,7 @@ "h": 30 }, "frame": { - "x": 360, + "x": 440, "y": 450, "w": 40, "h": 30 @@ -4329,7 +4371,7 @@ "h": 30 }, "frame": { - "x": 400, + "x": 480, "y": 450, "w": 40, "h": 30 @@ -4350,8 +4392,8 @@ "h": 30 }, "frame": { - "x": 440, - "y": 450, + "x": 0, + "y": 480, "w": 40, "h": 30 } @@ -4371,8 +4413,8 @@ "h": 30 }, "frame": { - "x": 480, - "y": 450, + "x": 40, + "y": 480, "w": 40, "h": 30 } @@ -4392,7 +4434,7 @@ "h": 30 }, "frame": { - "x": 0, + "x": 80, "y": 480, "w": 40, "h": 30 @@ -4413,7 +4455,7 @@ "h": 30 }, "frame": { - "x": 40, + "x": 120, "y": 480, "w": 40, "h": 30 @@ -4434,7 +4476,7 @@ "h": 30 }, "frame": { - "x": 80, + "x": 160, "y": 480, "w": 40, "h": 30 @@ -4455,7 +4497,7 @@ "h": 30 }, "frame": { - "x": 120, + "x": 200, "y": 480, "w": 40, "h": 30 @@ -4476,7 +4518,7 @@ "h": 30 }, "frame": { - "x": 160, + "x": 240, "y": 480, "w": 40, "h": 30 @@ -4497,7 +4539,7 @@ "h": 30 }, "frame": { - "x": 200, + "x": 280, "y": 480, "w": 40, "h": 30 @@ -4518,7 +4560,7 @@ "h": 30 }, "frame": { - "x": 240, + "x": 320, "y": 480, "w": 40, "h": 30 @@ -4539,7 +4581,7 @@ "h": 30 }, "frame": { - "x": 280, + "x": 360, "y": 480, "w": 40, "h": 30 @@ -4560,7 +4602,7 @@ "h": 30 }, "frame": { - "x": 320, + "x": 400, "y": 480, "w": 40, "h": 30 @@ -4581,7 +4623,7 @@ "h": 30 }, "frame": { - "x": 360, + "x": 440, "y": 480, "w": 40, "h": 30 @@ -4602,7 +4644,7 @@ "h": 30 }, "frame": { - "x": 400, + "x": 480, "y": 480, "w": 40, "h": 30 @@ -4622,48 +4664,6 @@ "w": 40, "h": 30 }, - "frame": { - "x": 440, - "y": 480, - "w": 40, - "h": 30 - } - }, - { - "filename": "489_2", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 40, - "h": 30 - }, - "frame": { - "x": 480, - "y": 480, - "w": 40, - "h": 30 - } - }, - { - "filename": "489_3", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 40, - "h": 30 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 40, - "h": 30 - }, "frame": { "x": 0, "y": 510, @@ -4672,7 +4672,7 @@ } }, { - "filename": "490_1", + "filename": "489_2", "rotated": false, "trimmed": false, "sourceSize": { @@ -4693,7 +4693,7 @@ } }, { - "filename": "490_2", + "filename": "489_3", "rotated": false, "trimmed": false, "sourceSize": { @@ -4714,7 +4714,7 @@ } }, { - "filename": "490_3", + "filename": "490_1", "rotated": false, "trimmed": false, "sourceSize": { @@ -4735,7 +4735,7 @@ } }, { - "filename": "491_2", + "filename": "490_2", "rotated": false, "trimmed": false, "sourceSize": { @@ -4756,7 +4756,7 @@ } }, { - "filename": "491_3", + "filename": "490_3", "rotated": false, "trimmed": false, "sourceSize": { @@ -4777,7 +4777,7 @@ } }, { - "filename": "492-land_2", + "filename": "491_2", "rotated": false, "trimmed": false, "sourceSize": { @@ -4798,7 +4798,7 @@ } }, { - "filename": "492-land_3", + "filename": "491_3", "rotated": false, "trimmed": false, "sourceSize": { @@ -4819,7 +4819,7 @@ } }, { - "filename": "492-sky_2", + "filename": "492-land_2", "rotated": false, "trimmed": false, "sourceSize": { @@ -4840,7 +4840,7 @@ } }, { - "filename": "492-sky_3", + "filename": "492-land_3", "rotated": false, "trimmed": false, "sourceSize": { @@ -4859,6 +4859,48 @@ "w": 40, "h": 30 } + }, + { + "filename": "492-sky_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 400, + "y": 510, + "w": 40, + "h": 30 + } + }, + { + "filename": "492-sky_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 440, + "y": 510, + "w": 40, + "h": 30 + } } ] } @@ -4866,6 +4908,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:52236a80fa87dc64d12684ac85cf8440:2809a2ce37dd2c24fc872d083bf5a2aa:ebc3f8ec5b2480b298192d752b6e57dc$" + "smartupdate": "$TexturePacker:SmartUpdate:00a4e5499c11f3abdf9f56423bbf4561:6f365ccd1246c9b5ae27e0e440695926:ebc3f8ec5b2480b298192d752b6e57dc$" } } diff --git a/public/images/pokemon_icons_4v.png b/public/images/pokemon_icons_4v.png index 43938ed50958d3fb9a200e654bca1e5646415453..972bff8b777a5bbc0e1c2196274824e4477e40ca 100644 GIT binary patch literal 46932 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 literal 46415 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 diff --git a/public/images/pokemon_icons_9v.json b/public/images/pokemon_icons_9v.json index 57159a3fbfb..4b7a7ba4572 100644 --- a/public/images/pokemon_icons_9v.json +++ b/public/images/pokemon_icons_9v.json @@ -3013,7 +3013,7 @@ } }, { - "filename": "1012-counterfeit_2", + "filename": "1011_2", "rotated": false, "trimmed": false, "sourceSize": { @@ -3034,7 +3034,7 @@ } }, { - "filename": "1012-counterfeit_3", + "filename": "1011_3", "rotated": false, "trimmed": false, "sourceSize": { @@ -3055,7 +3055,7 @@ } }, { - "filename": "1013-unremarkable_2", + "filename": "1012-counterfeit_2", "rotated": false, "trimmed": false, "sourceSize": { @@ -3076,7 +3076,7 @@ } }, { - "filename": "1013-unremarkable_3", + "filename": "1012-counterfeit_3", "rotated": false, "trimmed": false, "sourceSize": { @@ -3097,7 +3097,7 @@ } }, { - "filename": "1018_2", + "filename": "1013-unremarkable_2", "rotated": false, "trimmed": false, "sourceSize": { @@ -3118,7 +3118,7 @@ } }, { - "filename": "1018_3", + "filename": "1013-unremarkable_3", "rotated": false, "trimmed": false, "sourceSize": { @@ -3139,7 +3139,7 @@ } }, { - "filename": "1022_2", + "filename": "1018_2", "rotated": false, "trimmed": false, "sourceSize": { @@ -3160,7 +3160,7 @@ } }, { - "filename": "1022_3", + "filename": "1018_3", "rotated": false, "trimmed": false, "sourceSize": { @@ -3181,7 +3181,7 @@ } }, { - "filename": "1023_2", + "filename": "1019_2", "rotated": false, "trimmed": false, "sourceSize": { @@ -3202,7 +3202,7 @@ } }, { - "filename": "1023_3", + "filename": "1019_3", "rotated": false, "trimmed": false, "sourceSize": { @@ -3223,7 +3223,7 @@ } }, { - "filename": "8901_1", + "filename": "1022_2", "rotated": false, "trimmed": false, "sourceSize": { @@ -3244,7 +3244,7 @@ } }, { - "filename": "8901_2", + "filename": "1022_3", "rotated": false, "trimmed": false, "sourceSize": { @@ -3265,7 +3265,7 @@ } }, { - "filename": "8901_3", + "filename": "1023_2", "rotated": false, "trimmed": false, "sourceSize": { @@ -3284,6 +3284,90 @@ "w": 40, "h": 30 } + }, + { + "filename": "1023_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 80, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "8901_1", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 120, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "8901_2", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 160, + "y": 420, + "w": 40, + "h": 30 + } + }, + { + "filename": "8901_3", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 40, + "h": 30 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 40, + "h": 30 + }, + "frame": { + "x": 200, + "y": 420, + "w": 40, + "h": 30 + } } ] } @@ -3291,6 +3375,6 @@ "meta": { "app": "https://www.codeandweb.com/texturepacker", "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:c01add1e11aabd2f8931110a67a9222b:e7531bea9b5e1bef44def5b357c81630:3ec5c0bc286c296cfb7fa30a8b06f3da$" + "smartupdate": "$TexturePacker:SmartUpdate:a78ab8261d4cd63caee19962a0e01d8a:cb77bcbd2cc296577c3f2ba84b4c50f2:3ec5c0bc286c296cfb7fa30a8b06f3da$" } } diff --git a/public/images/pokemon_icons_9v.png b/public/images/pokemon_icons_9v.png index f3530abe569a35ed34dbc021ba0720c967802bf0..3636c3059d8e0e758ccbeb9749294fd80021d294 100644 GIT binary patch literal 36066 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 delta 9535 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 Date: Sun, 4 May 2025 15:35:44 -0700 Subject: [PATCH 21/61] [Bug][Hotfix] Always show hit result message (#5769) Always show hit result --- src/phases/move-effect-phase.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index 64cae923f07..c65e8e15271 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -944,7 +944,7 @@ export class MoveEffectPhase extends PokemonPhase { const result = this.applyMoveDamage(user, target, effectiveness); - if (user.turnData.hitsLeft === 1 && target.isFainted()) { + if (user.turnData.hitsLeft === 1 || target.isFainted()) { this.queueHitResultMessage(result); } From 7547b37e852a5fab0ad7445015ae40ccff1c1b97 Mon Sep 17 00:00:00 2001 From: lxy-lxy-lxy <55084073+lxy-lxy-lxy@users.noreply.github.com> Date: Mon, 5 May 2025 21:32:56 +0800 Subject: [PATCH 22/61] [Bug] Fix local save encoding crash and Psychic anim (#5775) * fix error: utf8 to base64 * fix error: space missed --- public/battle-anims/psychic.json | 2 +- src/system/game-data.ts | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/public/battle-anims/psychic.json b/public/battle-anims/psychic.json index 5ad4898de5a..72161ff9aff 100644 --- a/public/battle-anims/psychic.json +++ b/public/battle-anims/psychic.json @@ -1,6 +1,6 @@ { "id": 94, - "graphic": "PRAS- PsychicBG", + "graphic": "PRAS- Psychic BG", "frames": [ [ { diff --git a/src/system/game-data.ts b/src/system/game-data.ts index e200fa6b3c7..51e488210be 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -118,15 +118,17 @@ export function getDataTypeKey(dataType: GameDataType, slotId = 0): string { } export function encrypt(data: string, bypassLogin: boolean): string { - return (bypassLogin ? (data: string) => btoa(data) : (data: string) => AES.encrypt(data, saveKey))( - data, - ) as unknown as string; // TODO: is this correct? + return (bypassLogin + ? (data: string) => btoa(encodeURIComponent(data)) + : (data: string) => AES.encrypt(data, saveKey))(data) as unknown as string; // TODO: is this correct? } export function decrypt(data: string, bypassLogin: boolean): string { - return (bypassLogin ? (data: string) => atob(data) : (data: string) => AES.decrypt(data, saveKey).toString(enc.Utf8))( - data, - ); + return ( + bypassLogin + ? (data: string) => decodeURIComponent(atob(data)) + : (data: string) => AES.decrypt(data, saveKey).toString(enc.Utf8) + )(data); } export interface SystemSaveData { From bd913a201ce61bb2d3ea27475910b24ad530499d Mon Sep 17 00:00:00 2001 From: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> Date: Mon, 5 May 2025 17:18:24 -0400 Subject: [PATCH 23/61] [Sprite] Fix Clauncher consistent variants, floating Jangmo-o (#5777) Fix Clauncher consistent variants, flying Jangmo-o --- public/images/pokemon/692.json | 59 +++----- public/images/pokemon/692.png | Bin 510 -> 2628 bytes public/images/pokemon/782.json | 222 ++++++++++++++-------------- public/images/pokemon/back/692.json | 59 +++----- public/images/pokemon/back/692.png | Bin 476 -> 2043 bytes public/images/pokemon/back/782.json | 222 ++++++++++++++-------------- 6 files changed, 260 insertions(+), 302 deletions(-) diff --git a/public/images/pokemon/692.json b/public/images/pokemon/692.json index a06bb0c77b7..125642a01f1 100644 --- a/public/images/pokemon/692.json +++ b/public/images/pokemon/692.json @@ -1,41 +1,20 @@ -{ - "textures": [ - { - "image": "692.png", - "format": "RGBA8888", - "size": { - "w": 56, - "h": 56 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 56, - "h": 35 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 56, - "h": 35 - }, - "frame": { - "x": 0, - "y": 0, - "w": 56, - "h": 35 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:031fb8fbcf9162adb44c0a90fd2cc110:44a2bd195c730b2d35c3ad898e1b3672:2880def858c84cd859bedf13b0b49a33$" - } +{ "frames": [ + { + "filename": "0001.png", + "frame": { "x": 121, "y": 36, "w": 56, "h": 35 }, + "rotated": false, + "trimmed": true, + "spriteSourceSize": { "x": 4, "y": 0, "w": 56, "h": 35 }, + "sourceSize": { "w": 63, "h": 35 }, + "duration": 50 + } + ], + "meta": { + "app": "https://www.aseprite.org/", + "version": "1.3.12-x64", + "image": "692.png", + "format": "I8", + "size": { "w": 239, "h": 106 }, + "scale": "1" + } } diff --git a/public/images/pokemon/692.png b/public/images/pokemon/692.png index ce0cb4d32435eed23067d7d5fe0f21ab2f8bd473..a22655931a819af880379c8c349ce0b65a4d026f 100644 GIT binary patch literal 2628 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 Date: Tue, 6 May 2025 07:34:35 +1000 Subject: [PATCH 24/61] [Bug] Fix shiny save bug (#5780) Correctly determine shininess and variant during saving --- src/system/pokemon-data.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/system/pokemon-data.ts b/src/system/pokemon-data.ts index ef1f30830f0..248fe9cf513 100644 --- a/src/system/pokemon-data.ts +++ b/src/system/pokemon-data.ts @@ -91,8 +91,8 @@ export default class PokemonData { this.formIndex = Math.max(Math.min(source.formIndex, getPokemonSpecies(this.species).forms.length - 1), 0); this.abilityIndex = source.abilityIndex; this.passive = source.passive; - this.shiny = sourcePokemon?.isShiny() ?? source.shiny; - this.variant = sourcePokemon?.getVariant() ?? source.variant; + this.shiny = source.shiny; + this.variant = source.variant; this.pokeball = source.pokeball ?? PokeballType.POKEBALL; this.level = source.level; this.exp = source.exp; From ae25a70b4d34fe7604dd374e5ca6e98f1bf3f789 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Mon, 5 May 2025 16:36:22 -0500 Subject: [PATCH 25/61] [Bug][UI/UX] Ensure pokemon hop when animations are selected (#5781) Ensure pokemon hop when animations are selected --- src/ui/pokedex-ui-handler.ts | 24 ++++++++++-------------- src/ui/starter-select-ui-handler.ts | 28 ++++++++++++---------------- 2 files changed, 22 insertions(+), 30 deletions(-) diff --git a/src/ui/pokedex-ui-handler.ts b/src/ui/pokedex-ui-handler.ts index b1d0945de07..935c9adfeb8 100644 --- a/src/ui/pokedex-ui-handler.ts +++ b/src/ui/pokedex-ui-handler.ts @@ -873,6 +873,7 @@ export default class PokedexUiHandler extends MessageUiHandler { const tweenChain: Phaser.Types.Tweens.TweenChainBuilderConfig = { targets: icon, loop: -1, + paused: startPaused, // Make the initial bounce a little randomly delayed delay: randIntRange(0, 50) * 5, loopDelay: 1000, @@ -894,19 +895,14 @@ export default class PokedexUiHandler extends MessageUiHandler { ], }; - const isPassiveAvailable = this.isPassiveAvailable(species.speciesId); - const isValueReductionAvailable = this.isValueReductionAvailable(species.speciesId); - const isSameSpeciesEggAvailable = this.isSameSpeciesEggAvailable(species.speciesId); - - // 'Passives Only' mode - if (globalScene.candyUpgradeNotification === 1) { - if (isPassiveAvailable) { - globalScene.tweens.chain(tweenChain).paused = startPaused; - } - // 'On' mode - } else if (globalScene.candyUpgradeNotification === 2) { - if (isPassiveAvailable || isValueReductionAvailable || isSameSpeciesEggAvailable) { - globalScene.tweens.chain(tweenChain).paused = startPaused; + if ( + this.isPassiveAvailable(species.speciesId) || + (globalScene.candyUpgradeNotification === 2 && + (this.isValueReductionAvailable(species.speciesId) || this.isSameSpeciesEggAvailable(species.speciesId))) + ) { + const chain = globalScene.tweens.chain(tweenChain); + if (!startPaused) { + chain.play(); } } } @@ -2040,7 +2036,7 @@ export default class PokedexUiHandler extends MessageUiHandler { this.checkIconId(lastSpeciesIcon, container.species, props.female, props.formIndex, props.shiny, props.variant); this.iconAnimHandler.addOrUpdate(lastSpeciesIcon, PokemonIconAnimMode.NONE); // Resume the animation for the previously selected species - globalScene.tweens.getTweensOf(lastSpeciesIcon).forEach(tween => tween.resume()); + globalScene.tweens.getTweensOf(lastSpeciesIcon).forEach(tween => tween.play()); } } diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 7c345f1735e..09d7322cb75 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -1444,6 +1444,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const tweenChain: Phaser.Types.Tweens.TweenChainBuilderConfig = { targets: icon, + paused: startPaused, loop: -1, // Make the initial bounce a little randomly delayed delay: randIntRange(0, 50) * 5, @@ -1451,14 +1452,14 @@ export default class StarterSelectUiHandler extends MessageUiHandler { tweens: [ { targets: icon, - y: 2 - 5, + y: "-=5", duration: fixedInt(125), ease: "Cubic.easeOut", yoyo: true, }, { targets: icon, - y: 2 - 3, + y: "-=3", duration: fixedInt(150), ease: "Cubic.easeOut", yoyo: true, @@ -1466,19 +1467,14 @@ export default class StarterSelectUiHandler extends MessageUiHandler { ], }; - const isPassiveAvailable = this.isPassiveAvailable(species.speciesId); - const isValueReductionAvailable = this.isValueReductionAvailable(species.speciesId); - const isSameSpeciesEggAvailable = this.isSameSpeciesEggAvailable(species.speciesId); - - // 'Passives Only' mode - if (globalScene.candyUpgradeNotification === 1) { - if (isPassiveAvailable) { - globalScene.tweens.chain(tweenChain).paused = startPaused; - } - // 'On' mode - } else if (globalScene.candyUpgradeNotification === 2) { - if (isPassiveAvailable || isValueReductionAvailable || isSameSpeciesEggAvailable) { - globalScene.tweens.chain(tweenChain).paused = startPaused; + if ( + this.isPassiveAvailable(species.speciesId) || + (globalScene.candyUpgradeNotification === 2 && + (this.isValueReductionAvailable(species.speciesId) || this.isSameSpeciesEggAvailable(species.speciesId))) + ) { + const chain = globalScene.tweens.chain(tweenChain); + if (!startPaused) { + chain.play(); } } } @@ -3478,7 +3474,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { // Resume the animation for the previously selected species const icon = this.starterContainers[speciesIndex].icon; - globalScene.tweens.getTweensOf(icon).forEach(tween => tween.resume()); + globalScene.tweens.getTweensOf(icon).forEach(tween => tween.play()); } this.lastSpecies = species!; // TODO: is this bang correct? From 92f1cfdd50878ccc0ea10bc395092144e0d4cca9 Mon Sep 17 00:00:00 2001 From: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> Date: Mon, 5 May 2025 18:34:17 -0400 Subject: [PATCH 26/61] [Hotfix] Remove Charcadet line from exp variant masterlist (#5782) * Remove Charcadet line from exp variant masterlist * Remove line's backsprite from masterlist --- public/images/pokemon/variant/_exp_masterlist.json | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/public/images/pokemon/variant/_exp_masterlist.json b/public/images/pokemon/variant/_exp_masterlist.json index e588be59073..88c6f4a95c1 100644 --- a/public/images/pokemon/variant/_exp_masterlist.json +++ b/public/images/pokemon/variant/_exp_masterlist.json @@ -256,9 +256,6 @@ "932": [0, 2, 2], "933": [0, 2, 2], "934": [0, 1, 1], - "935": [1, 1, 2], - "936": [2, 2, 2], - "937": [2, 2, 2], "940": [0, 1, 1], "941": [0, 1, 1], "944": [0, 1, 1], @@ -593,9 +590,6 @@ "932": [0, 1, 1], "933": [0, 1, 1], "934": [0, 1, 1], - "935": [2, 2, 2], - "936": [2, 2, 2], - "937": [2, 2, 2], "940": [0, 1, 1], "941": [0, 1, 1], "944": [0, 1, 1], @@ -675,4 +669,4 @@ "6215": [0, 1, 1] } } -} \ No newline at end of file +} From 3161461b6c9960bc286c127f9f31ae609f4e3311 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Mon, 5 May 2025 17:35:51 -0500 Subject: [PATCH 27/61] [Bug][UI/UX] Update battle-info inside pokemon#damageAndUpdate (#5778) * Update battle-info inside pokemon#damageAndUpdate * Ensure updatePokemonHp does not skip last hp number --- src/field/pokemon.ts | 5 +++++ src/ui/battle-info.ts | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index b9c64ad071c..5615f3844bd 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -4764,6 +4764,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { isIndirectDamage, ignoreFaintPhase, ); + // Ensure the battle-info bar's HP is updated, though only if the battle info is visible + // TODO: When battle-info UI is refactored, make this only update the HP bar + if (this.battleInfo.visible) { + this.updateInfo(); + } // Damage amount may have changed, but needed to be queued before calling damage function damagePhase.updateAmount(damage); /** diff --git a/src/ui/battle-info.ts b/src/ui/battle-info.ts index cabe897d7b6..839f0d62819 100644 --- a/src/ui/battle-info.ts +++ b/src/ui/battle-info.ts @@ -727,6 +727,12 @@ export default class BattleInfo extends Phaser.GameObjects.Container { }, onComplete: () => { updateHpFrame(); + // If, after tweening, the hp is different from the original (due to rounding), force the hp number display + // to update to the correct value. + if (this.player && this.lastHp !== pokemon.hp) { + this.setHpNumbers(pokemon.hp, pokemon.getMaxHp()); + this.lastHp = pokemon.hp; + } resolve(); }, }); From b42b2f6752849cb32f8f8b3a6f4d8f35553dae94 Mon Sep 17 00:00:00 2001 From: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> Date: Mon, 5 May 2025 20:38:49 -0400 Subject: [PATCH 28/61] [Test] Fix sprite test due to unused files (#5783) Fix sprite test due to unused files --- public/images/pokemon/exp/935.json | 440 ------------ public/images/pokemon/exp/935.png | Bin 1972 -> 0 bytes public/images/pokemon/exp/936.json | 524 -------------- public/images/pokemon/exp/936.png | Bin 5477 -> 0 bytes public/images/pokemon/exp/937.json | 125 ---- public/images/pokemon/exp/937.png | Bin 4707 -> 0 bytes public/images/pokemon/exp/back/935.json | 356 ---------- public/images/pokemon/exp/back/935.png | Bin 1809 -> 0 bytes public/images/pokemon/exp/back/936.json | 356 ---------- public/images/pokemon/exp/back/936.png | Bin 5792 -> 0 bytes public/images/pokemon/exp/back/937.json | 650 ------------------ public/images/pokemon/exp/back/937.png | Bin 13741 -> 0 bytes public/images/pokemon/exp/back/shiny/935.json | 356 ---------- public/images/pokemon/exp/back/shiny/935.png | Bin 1811 -> 0 bytes public/images/pokemon/exp/back/shiny/936.json | 356 ---------- public/images/pokemon/exp/back/shiny/936.png | Bin 5792 -> 0 bytes public/images/pokemon/exp/back/shiny/937.json | 650 ------------------ public/images/pokemon/exp/back/shiny/937.png | Bin 13741 -> 0 bytes public/images/pokemon/exp/shiny/935.json | 440 ------------ public/images/pokemon/exp/shiny/935.png | Bin 1972 -> 0 bytes public/images/pokemon/exp/shiny/936.json | 524 -------------- public/images/pokemon/exp/shiny/936.png | Bin 5491 -> 0 bytes public/images/pokemon/exp/shiny/937.json | 125 ---- public/images/pokemon/exp/shiny/937.png | Bin 4704 -> 0 bytes public/images/pokemon/variant/exp/935.json | 46 -- public/images/pokemon/variant/exp/935_1.png | Bin 3215 -> 0 bytes public/images/pokemon/variant/exp/935_2.png | Bin 3216 -> 0 bytes public/images/pokemon/variant/exp/935_3.json | 440 ------------ public/images/pokemon/variant/exp/935_3.png | Bin 3218 -> 0 bytes public/images/pokemon/variant/exp/936_1.json | 524 -------------- public/images/pokemon/variant/exp/936_1.png | Bin 9702 -> 0 bytes public/images/pokemon/variant/exp/936_2.json | 524 -------------- public/images/pokemon/variant/exp/936_2.png | Bin 9177 -> 0 bytes public/images/pokemon/variant/exp/936_3.json | 524 -------------- public/images/pokemon/variant/exp/936_3.png | Bin 9689 -> 0 bytes public/images/pokemon/variant/exp/937_1.json | 125 ---- public/images/pokemon/variant/exp/937_1.png | Bin 8076 -> 0 bytes public/images/pokemon/variant/exp/937_2.json | 125 ---- public/images/pokemon/variant/exp/937_2.png | Bin 5512 -> 0 bytes public/images/pokemon/variant/exp/937_3.json | 125 ---- public/images/pokemon/variant/exp/937_3.png | Bin 8076 -> 0 bytes .../pokemon/variant/exp/back/935_1.json | 356 ---------- .../images/pokemon/variant/exp/back/935_1.png | Bin 2286 -> 0 bytes .../pokemon/variant/exp/back/935_2.json | 356 ---------- .../images/pokemon/variant/exp/back/935_2.png | Bin 2286 -> 0 bytes .../pokemon/variant/exp/back/935_3.json | 356 ---------- .../images/pokemon/variant/exp/back/935_3.png | Bin 2286 -> 0 bytes .../pokemon/variant/exp/back/936_1.json | 356 ---------- .../images/pokemon/variant/exp/back/936_1.png | Bin 9722 -> 0 bytes .../pokemon/variant/exp/back/936_2.json | 356 ---------- .../images/pokemon/variant/exp/back/936_2.png | Bin 9722 -> 0 bytes .../pokemon/variant/exp/back/936_3.json | 356 ---------- .../images/pokemon/variant/exp/back/936_3.png | Bin 9722 -> 0 bytes .../pokemon/variant/exp/back/937_1.json | 650 ------------------ .../images/pokemon/variant/exp/back/937_1.png | Bin 18447 -> 0 bytes .../pokemon/variant/exp/back/937_2.json | 650 ------------------ .../images/pokemon/variant/exp/back/937_2.png | Bin 15851 -> 0 bytes .../pokemon/variant/exp/back/937_3.json | 650 ------------------ .../images/pokemon/variant/exp/back/937_3.png | Bin 18452 -> 0 bytes 59 files changed, 11421 deletions(-) delete mode 100644 public/images/pokemon/exp/935.json delete mode 100644 public/images/pokemon/exp/935.png delete mode 100644 public/images/pokemon/exp/936.json delete mode 100644 public/images/pokemon/exp/936.png delete mode 100644 public/images/pokemon/exp/937.json delete mode 100644 public/images/pokemon/exp/937.png delete mode 100644 public/images/pokemon/exp/back/935.json delete mode 100644 public/images/pokemon/exp/back/935.png delete mode 100644 public/images/pokemon/exp/back/936.json delete mode 100644 public/images/pokemon/exp/back/936.png delete mode 100644 public/images/pokemon/exp/back/937.json delete mode 100644 public/images/pokemon/exp/back/937.png delete mode 100644 public/images/pokemon/exp/back/shiny/935.json delete mode 100644 public/images/pokemon/exp/back/shiny/935.png delete mode 100644 public/images/pokemon/exp/back/shiny/936.json delete mode 100644 public/images/pokemon/exp/back/shiny/936.png delete mode 100644 public/images/pokemon/exp/back/shiny/937.json delete mode 100644 public/images/pokemon/exp/back/shiny/937.png delete mode 100644 public/images/pokemon/exp/shiny/935.json delete mode 100644 public/images/pokemon/exp/shiny/935.png delete mode 100644 public/images/pokemon/exp/shiny/936.json delete mode 100644 public/images/pokemon/exp/shiny/936.png delete mode 100644 public/images/pokemon/exp/shiny/937.json delete mode 100644 public/images/pokemon/exp/shiny/937.png delete mode 100644 public/images/pokemon/variant/exp/935.json delete mode 100644 public/images/pokemon/variant/exp/935_1.png delete mode 100644 public/images/pokemon/variant/exp/935_2.png delete mode 100644 public/images/pokemon/variant/exp/935_3.json delete mode 100644 public/images/pokemon/variant/exp/935_3.png delete mode 100644 public/images/pokemon/variant/exp/936_1.json delete mode 100644 public/images/pokemon/variant/exp/936_1.png delete mode 100644 public/images/pokemon/variant/exp/936_2.json delete mode 100644 public/images/pokemon/variant/exp/936_2.png delete mode 100644 public/images/pokemon/variant/exp/936_3.json delete mode 100644 public/images/pokemon/variant/exp/936_3.png delete mode 100644 public/images/pokemon/variant/exp/937_1.json delete mode 100644 public/images/pokemon/variant/exp/937_1.png delete mode 100644 public/images/pokemon/variant/exp/937_2.json delete mode 100644 public/images/pokemon/variant/exp/937_2.png delete mode 100644 public/images/pokemon/variant/exp/937_3.json delete mode 100644 public/images/pokemon/variant/exp/937_3.png delete mode 100644 public/images/pokemon/variant/exp/back/935_1.json delete mode 100644 public/images/pokemon/variant/exp/back/935_1.png delete mode 100644 public/images/pokemon/variant/exp/back/935_2.json delete mode 100644 public/images/pokemon/variant/exp/back/935_2.png delete mode 100644 public/images/pokemon/variant/exp/back/935_3.json delete mode 100644 public/images/pokemon/variant/exp/back/935_3.png delete mode 100644 public/images/pokemon/variant/exp/back/936_1.json delete mode 100644 public/images/pokemon/variant/exp/back/936_1.png delete mode 100644 public/images/pokemon/variant/exp/back/936_2.json delete mode 100644 public/images/pokemon/variant/exp/back/936_2.png delete mode 100644 public/images/pokemon/variant/exp/back/936_3.json delete mode 100644 public/images/pokemon/variant/exp/back/936_3.png delete mode 100644 public/images/pokemon/variant/exp/back/937_1.json delete mode 100644 public/images/pokemon/variant/exp/back/937_1.png delete mode 100644 public/images/pokemon/variant/exp/back/937_2.json delete mode 100644 public/images/pokemon/variant/exp/back/937_2.png delete mode 100644 public/images/pokemon/variant/exp/back/937_3.json delete mode 100644 public/images/pokemon/variant/exp/back/937_3.png diff --git a/public/images/pokemon/exp/935.json b/public/images/pokemon/exp/935.json deleted file mode 100644 index 95df77f9c54..00000000000 --- a/public/images/pokemon/exp/935.json +++ /dev/null @@ -1,440 +0,0 @@ -{ - "textures": [ - { - "image": "935.png", - "format": "RGBA8888", - "size": { - "w": 165, - "h": 165 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 0, - "y": 55, - "w": 35, - "h": 55 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 0, - "y": 55, - "w": 35, - "h": 55 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 0, - "y": 55, - "w": 35, - "h": 55 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 0, - "y": 110, - "w": 35, - "h": 55 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 0, - "y": 110, - "w": 35, - "h": 55 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 0, - "y": 110, - "w": 35, - "h": 55 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 35, - "y": 0, - "w": 35, - "h": 55 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 35, - "y": 0, - "w": 35, - "h": 55 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 35, - "y": 0, - "w": 35, - "h": 55 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 35, - "y": 55, - "w": 35, - "h": 55 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 35, - "y": 110, - "w": 35, - "h": 55 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 70, - "y": 0, - "w": 35, - "h": 55 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 105, - "y": 0, - "w": 35, - "h": 55 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 70, - "y": 55, - "w": 35, - "h": 55 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 70, - "y": 110, - "w": 35, - "h": 55 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 105, - "y": 55, - "w": 35, - "h": 55 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 105, - "y": 110, - "w": 35, - "h": 55 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:06750fe617b2ad66c1af576e0074e016:b59cf22eea90e9839062adc1f728c00a:077dcf06dc5fc347497b59afe6126a5e$" - } -} diff --git a/public/images/pokemon/exp/935.png b/public/images/pokemon/exp/935.png deleted file mode 100644 index 1ca019f8c1164fc0efad7e1081fcf0fd2546da5b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1972 zcmYjSeK-?pAD+ZChVpTSXvXYJrWL8PYn5qav5z(~CCq%J6sdKY*g;|)KDb1u0 zA6F=yBm1b9ruT#lT}8wgrw?a@xA(Poov!zK-#?z;eLv50U-$2Me$R7VKMsX-01UDR z0RR9nArMd1W5f4hVyKUxrI)jM*hdKt@zeT#X^|gmd(XcMFvD}4p6^Ob;pud$MTrZ&Kz7GXL@`y#9Kxzh-?Jm%}d#=t8&(GTkBcnb-_c@@lTvUe} zd0o_#az9j?8+npEQ5lhg%{0}eKNi8+yYq)vLt+QcSf1`h-nA4{LXN5|m!X~O8&ec~ zzgeks#when4vp??BM`3P+Tr3>*9QL!a~D2CA0bJM-jAIgC&`?)Ze0OxcYaXw9{(7P z-E;}C4Jj2-ls#3U1fGcQ4RngVl}p^uQ#vuHh+ncgUJN(uW>t91@6xah*i*dveKal<~ zX6tN{ivMvNc~`Y<8KtWHWrpv%SD66hly7}<3psz+CoYKhZ7UL7Ow}3eZ9y^nze3xJ z-9r)&RuM-}jD9!^{)D0>+c8VWom`(?=tw#|>*yVKl{k7=P!*cW#)?G450;O#VheDS z-Qk_?i{>>0t})d26)mH%W#zPU2lG@oZ=MNpt-%H7JKaRS6A(eKlQgg{{_oh-$e^)r zO#9g42*#-ajy2d40BiPJ!%~pKgdKO+c>~OrT3x> zhWKt3vVZQ0Xm}CYt znI4IcAFbVgdwMXhdebIeNCV%NXy-0acj;!Z$NPyb6@M2eAfyMz;@7gAOIN7TeP-|hzo3D6`^`c1w1o)yA)HT zxh{k+^Xn7I%CCkkORk|Cjy~~zgIzADqCPZzC zo2bNm*lv56*lnGYr!`yn8W43AoNxo`ghO_2-fQLJ9JKOUH3laiM zgNedChhi8``>W`t8RhhyGOO@(ecB-XRE{;omN$e!)NSWD9kZA>?Ip()0R8P>Je6Ss ztKOpe&ay{Xe@<~cx(76y47Ex9@OLq)Gi~!Dy?T#^LAbF#B|PB%l^u7&6{m$JnyVbt zc}L70L2NC;{$|*S3|(q7qcErjdYEX-cGoeSu3oz8xlzE?7q0A{1YJsXuuUO^f{UW7 z5dt1b7?_D*@jdM%DSjqd6auUM=cuPvOA&C^VKY8@v$Ak%`M%hFL5l~?{oFJdT=NIy zN@p*xN}kzmRLv`O4#2YqP zk!+{ttk_?9_M6A6eipdVA@&ktQi=6=T)<=qOT+UlYZ@xXG6aZqCnO0M>*JEF)f>A( zG0j6*hwDXYTedaHx#02Fj4?&f9GWTL#j0Lj;9>ekz7QSN7i&f4UOpMLLiT@UxG@Dm yFFQLzbaZ2R>mFXi1kWW+)$RJfhagc4m$vbeRtXyhRb+kd1Q7g5_-4Q8-2VU{-Ia9! diff --git a/public/images/pokemon/exp/936.json b/public/images/pokemon/exp/936.json deleted file mode 100644 index b7dff5e8393..00000000000 --- a/public/images/pokemon/exp/936.json +++ /dev/null @@ -1,524 +0,0 @@ -{ - "textures": [ - { - "image": "936.png", - "format": "RGBA8888", - "size": { - "w": 323, - "h": 323 - }, - "scale": 1, - "frames": [ - { - "filename": "0016.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 76, - "h": 99 - }, - "frame": { - "x": 0, - "y": 0, - "w": 76, - "h": 99 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 76, - "h": 99 - }, - "frame": { - "x": 0, - "y": 99, - "w": 76, - "h": 99 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 76, - "h": 99 - }, - "frame": { - "x": 0, - "y": 198, - "w": 76, - "h": 99 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 76, - "h": 98 - }, - "frame": { - "x": 76, - "y": 0, - "w": 76, - "h": 98 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 76, - "h": 98 - }, - "frame": { - "x": 152, - "y": 0, - "w": 76, - "h": 98 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 70, - "h": 99 - }, - "frame": { - "x": 228, - "y": 0, - "w": 70, - "h": 99 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 70, - "h": 99 - }, - "frame": { - "x": 76, - "y": 98, - "w": 70, - "h": 99 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 146, - "y": 98, - "w": 59, - "h": 99 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 146, - "y": 98, - "w": 59, - "h": 99 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 146, - "y": 98, - "w": 59, - "h": 99 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 76, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 76, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 76, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 76, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 135, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 135, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 135, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 194, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 1, - "w": 59, - "h": 98 - }, - "frame": { - "x": 205, - "y": 99, - "w": 59, - "h": 98 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 1, - "w": 59, - "h": 98 - }, - "frame": { - "x": 205, - "y": 99, - "w": 59, - "h": 98 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 1, - "w": 59, - "h": 98 - }, - "frame": { - "x": 205, - "y": 99, - "w": 59, - "h": 98 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 1, - "w": 59, - "h": 98 - }, - "frame": { - "x": 205, - "y": 99, - "w": 59, - "h": 98 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 264, - "y": 99, - "w": 59, - "h": 99 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 1, - "w": 59, - "h": 98 - }, - "frame": { - "x": 253, - "y": 198, - "w": 59, - "h": 98 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:2943281264e8142bbdb55f3a34167d72:322e92870c690e237c7a5e4a4a5f8e84:1a0490303f9626f92e787c567cd10feb$" - } -} diff --git a/public/images/pokemon/exp/936.png b/public/images/pokemon/exp/936.png deleted file mode 100644 index dce770dca44943ff8ecc8d37a14fa483f6b2818d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5477 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 Tr^Ja*`D&@IqOFWnv<&|rhf0%E diff --git a/public/images/pokemon/exp/937.json b/public/images/pokemon/exp/937.json deleted file mode 100644 index 9eba0e32900..00000000000 --- a/public/images/pokemon/exp/937.json +++ /dev/null @@ -1,125 +0,0 @@ -{ - "textures": [ - { - "image": "937.png", - "format": "RGBA8888", - "size": { - "w": 247, - "h": 247 - }, - "scale": 1, - "frames": [ - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 99 - }, - "spriteSourceSize": { - "x": 1, - "y": 1, - "w": 83, - "h": 98 - }, - "frame": { - "x": 0, - "y": 0, - "w": 83, - "h": 98 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 99 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 81, - "h": 99 - }, - "frame": { - "x": 83, - "y": 0, - "w": 81, - "h": 99 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 99 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 83, - "h": 99 - }, - "frame": { - "x": 164, - "y": 0, - "w": 83, - "h": 99 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 86, - "h": 99 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 86, - "h": 99 - }, - "frame": { - "x": 0, - "y": 99, - "w": 86, - "h": 99 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 86, - "h": 99 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 86, - "h": 99 - }, - "frame": { - "x": 86, - "y": 99, - "w": 86, - "h": 99 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:492182e4e32e5cddaa9dfc2c2c08b684:084d0317f824a0d082ba0ffcfebc407b:1d4b4f8d62307c37457ba974879b47d0$" - } -} diff --git a/public/images/pokemon/exp/937.png b/public/images/pokemon/exp/937.png deleted file mode 100644 index 6e8b5b3426806fb2412745b2f7173fdb61328040..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4707 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 diff --git a/public/images/pokemon/exp/back/935.json b/public/images/pokemon/exp/back/935.json deleted file mode 100644 index 26aa6c572c3..00000000000 --- a/public/images/pokemon/exp/back/935.json +++ /dev/null @@ -1,356 +0,0 @@ -{ - "textures": [ - { - "image": "935.png", - "format": "RGBA8888", - "size": { - "w": 133, - "h": 133 - }, - "scale": 1, - "frames": [ - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 29, - "h": 49 - }, - "frame": { - "x": 0, - "y": 0, - "w": 29, - "h": 49 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 29, - "h": 49 - }, - "frame": { - "x": 0, - "y": 0, - "w": 29, - "h": 49 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 29, - "h": 49 - }, - "frame": { - "x": 29, - "y": 0, - "w": 29, - "h": 49 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 29, - "h": 49 - }, - "frame": { - "x": 29, - "y": 0, - "w": 29, - "h": 49 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 28, - "h": 49 - }, - "frame": { - "x": 58, - "y": 0, - "w": 28, - "h": 49 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 28, - "h": 49 - }, - "frame": { - "x": 58, - "y": 0, - "w": 28, - "h": 49 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 28, - "h": 49 - }, - "frame": { - "x": 86, - "y": 0, - "w": 28, - "h": 49 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 28, - "h": 49 - }, - "frame": { - "x": 86, - "y": 0, - "w": 28, - "h": 49 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 28, - "h": 48 - }, - "frame": { - "x": 0, - "y": 49, - "w": 28, - "h": 48 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 28, - "h": 48 - }, - "frame": { - "x": 0, - "y": 49, - "w": 28, - "h": 48 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 27, - "h": 48 - }, - "frame": { - "x": 28, - "y": 49, - "w": 27, - "h": 48 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 5, - "y": 2, - "w": 27, - "h": 47 - }, - "frame": { - "x": 55, - "y": 49, - "w": 27, - "h": 47 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 5, - "y": 2, - "w": 27, - "h": 47 - }, - "frame": { - "x": 55, - "y": 49, - "w": 27, - "h": 47 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 6, - "y": 3, - "w": 26, - "h": 46 - }, - "frame": { - "x": 82, - "y": 49, - "w": 26, - "h": 46 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 6, - "y": 3, - "w": 26, - "h": 46 - }, - "frame": { - "x": 82, - "y": 49, - "w": 26, - "h": 46 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 7, - "y": 4, - "w": 25, - "h": 45 - }, - "frame": { - "x": 108, - "y": 49, - "w": 25, - "h": 45 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:2880dad5e3c550bb25e02ab0ab8d58c8:9dc0340440df25f20b3f006422b7a238:077dcf06dc5fc347497b59afe6126a5e$" - } -} diff --git a/public/images/pokemon/exp/back/935.png b/public/images/pokemon/exp/back/935.png deleted file mode 100644 index 64fc37a4a33832aa5d1e229bba55a4cbe9847161..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1809 zcmV+s2k!WZP)M6scE3+ey=?#TnkRXyQDQ zhdReom_}a8K8$$3^T@{okEd=FB#s&*;r-4dpA=rppc$Pz>-Ao>I&%myy!D6)My2Q+ zQY9Omdpz`B8#utt4GE?f7JTr za-2%J?<$7RL9xL#Mma|z1`X;>O!;MR7CM!wVhjLSv=rfa)zp~(*u-k1CL+H*%RmZWOa9geJ))!@5=>(L!4$A8 z^Wy)5rGhLe@u&FlU4~-dj2NCVki{7RUNgvAh%Yz7f~dq-e3Fso6jV{%<7CM}v?|5R z`K1jQufa=d1aqul<6OMk#n)C%SL3G+`cBCANb!xa@|T6;b6y4L)Fa?8j7C%ypt7!4C+aGRu@H^sCc=yx$NE1pnxUo}oW;21FT_~;Yd5xH815uq zAc%=`RM+>!*5jG+h#VtP7x|<@S6mBKa$aajH(S)O%2hkSmO&NY3UgUmlKbWt97^S)>BE`h2 zl?6E(uZk1ZO3AUf2$E4ocX;2jmM&j~Xv&c_+G&*1D-ndu3Xl*{LmBFMw#z%;jJ@|p7VIqHlWC@r_<|)jKly|+?GHWSO%MQ9oe5=9@fRWym z#~O5YNrxRA2m@u-Qa=+@1Pno~*h4<^=cB0&;ibf9a6Yf*rf;0q^z2kBYKY5H@(V@@6|VY3ETPbOUwPGU*)YxZV#`0T^bQ zqHqkAwVWWSJBgoTkBlp1Gn{8HEDSGD0Eo_7yb@Uph&>?SiX?TMAYcqH$N(Wx7?rgk zgm~DBJJ{*zM>NBpRxFf0?I?1a+@-RXcp00SWm9`bFPjx-_Xv|>GbyYkQI5b`O3JZY z^$XL?j-z`SR2=vP5mBWaH3KZzxmdg`gC{s;931V_Np-EK2P00000NkvXXu0mjfT8mCD diff --git a/public/images/pokemon/exp/back/936.json b/public/images/pokemon/exp/back/936.json deleted file mode 100644 index 79ff3ce5c33..00000000000 --- a/public/images/pokemon/exp/back/936.json +++ /dev/null @@ -1,356 +0,0 @@ -{ - "textures": [ - { - "image": "936.png", - "format": "RGBA8888", - "size": { - "w": 283, - "h": 283 - }, - "scale": 1, - "frames": [ - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 0, - "y": 0, - "w": 59, - "h": 97 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 0, - "y": 0, - "w": 59, - "h": 97 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 0, - "y": 97, - "w": 59, - "h": 97 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 0, - "y": 97, - "w": 59, - "h": 97 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 59, - "y": 0, - "w": 59, - "h": 97 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 59, - "y": 0, - "w": 59, - "h": 97 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 8, - "y": 0, - "w": 58, - "h": 97 - }, - "frame": { - "x": 59, - "y": 97, - "w": 58, - "h": 97 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 8, - "y": 0, - "w": 58, - "h": 97 - }, - "frame": { - "x": 59, - "y": 97, - "w": 58, - "h": 97 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 58, - "h": 97 - }, - "frame": { - "x": 117, - "y": 97, - "w": 58, - "h": 97 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 58, - "h": 97 - }, - "frame": { - "x": 117, - "y": 97, - "w": 58, - "h": 97 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 7, - "y": 1, - "w": 57, - "h": 96 - }, - "frame": { - "x": 118, - "y": 0, - "w": 57, - "h": 96 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 7, - "y": 1, - "w": 57, - "h": 96 - }, - "frame": { - "x": 118, - "y": 0, - "w": 57, - "h": 96 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 58, - "h": 95 - }, - "frame": { - "x": 175, - "y": 0, - "w": 58, - "h": 95 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 58, - "h": 95 - }, - "frame": { - "x": 175, - "y": 0, - "w": 58, - "h": 95 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 0, - "y": 3, - "w": 58, - "h": 94 - }, - "frame": { - "x": 175, - "y": 95, - "w": 58, - "h": 94 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 10, - "y": 3, - "w": 57, - "h": 94 - }, - "frame": { - "x": 175, - "y": 189, - "w": 57, - "h": 94 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:973448a7633a4dceb9828d95556ed3c2:09d8ad02433d8015e4665464587b1259:1a0490303f9626f92e787c567cd10feb$" - } -} diff --git a/public/images/pokemon/exp/back/936.png b/public/images/pokemon/exp/back/936.png deleted file mode 100644 index 14b0c1c7bf23b063d01a8b8e7824e816bc4e03df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5792 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 Hhfn_p+=mN4 diff --git a/public/images/pokemon/exp/back/shiny/935.json b/public/images/pokemon/exp/back/shiny/935.json deleted file mode 100644 index 2bdf2b2a155..00000000000 --- a/public/images/pokemon/exp/back/shiny/935.json +++ /dev/null @@ -1,356 +0,0 @@ -{ - "textures": [ - { - "image": "935.png", - "format": "RGBA8888", - "size": { - "w": 133, - "h": 133 - }, - "scale": 1, - "frames": [ - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 29, - "h": 49 - }, - "frame": { - "x": 0, - "y": 0, - "w": 29, - "h": 49 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 29, - "h": 49 - }, - "frame": { - "x": 0, - "y": 0, - "w": 29, - "h": 49 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 29, - "h": 49 - }, - "frame": { - "x": 29, - "y": 0, - "w": 29, - "h": 49 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 29, - "h": 49 - }, - "frame": { - "x": 29, - "y": 0, - "w": 29, - "h": 49 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 28, - "h": 49 - }, - "frame": { - "x": 58, - "y": 0, - "w": 28, - "h": 49 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 28, - "h": 49 - }, - "frame": { - "x": 58, - "y": 0, - "w": 28, - "h": 49 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 28, - "h": 49 - }, - "frame": { - "x": 86, - "y": 0, - "w": 28, - "h": 49 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 28, - "h": 49 - }, - "frame": { - "x": 86, - "y": 0, - "w": 28, - "h": 49 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 28, - "h": 48 - }, - "frame": { - "x": 0, - "y": 49, - "w": 28, - "h": 48 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 28, - "h": 48 - }, - "frame": { - "x": 0, - "y": 49, - "w": 28, - "h": 48 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 27, - "h": 48 - }, - "frame": { - "x": 28, - "y": 49, - "w": 27, - "h": 48 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 5, - "y": 2, - "w": 27, - "h": 47 - }, - "frame": { - "x": 55, - "y": 49, - "w": 27, - "h": 47 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 5, - "y": 2, - "w": 27, - "h": 47 - }, - "frame": { - "x": 55, - "y": 49, - "w": 27, - "h": 47 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 6, - "y": 3, - "w": 26, - "h": 46 - }, - "frame": { - "x": 82, - "y": 49, - "w": 26, - "h": 46 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 6, - "y": 3, - "w": 26, - "h": 46 - }, - "frame": { - "x": 82, - "y": 49, - "w": 26, - "h": 46 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 7, - "y": 4, - "w": 25, - "h": 45 - }, - "frame": { - "x": 108, - "y": 49, - "w": 25, - "h": 45 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:039aaaf52028b39c07e4909a88a5e8bb:1e66e8f98dd44fa06a53d364e32b154b:077dcf06dc5fc347497b59afe6126a5e$" - } -} diff --git a/public/images/pokemon/exp/back/shiny/935.png b/public/images/pokemon/exp/back/shiny/935.png deleted file mode 100644 index bdd1ef192ad60ab6472f2af83036a90c8f6fbe9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1811 zcmV+u2kiKXP)M6scE3+ey=?#TnkRXyQDQ zhdReom_}a8K8$$3^T@{okEd=FB#s&*;r-4dpA=rppc$Pz>-Ao>I&%myy!D6)My2Q+ zQY9Omdpat1!v|Ly9cEX0IL@_xw@o zm&D%RU?#zAjRSH1*x{cX6W+;u)MipYH>b=~e zk!zN_zn8Hy_Ekf*7_@yI#qXHfC~Z^_(;u?X?jZ%EsLb6S`V?twihuccCm<0mf=?7@ z($ynBH_Iiz5nJd~riw8DV9`>9=T%c<{$mrXjhcx3_ACP_d@cD~AM}WldPp#d`3F~$SV(ffu=5kh}j;b#;k@IcTy}f5&0XJ^wO#n zFXxvwV7vw|sS(Vvf{kILI_Ntg-y_90#>!t7iqCl!pi_^4!|}!MPUqsj z0yq-Bnf9xl8s-z6ual_CW0mjl{RdeVRmi{n0Hj}7#nn5%&i*?k5|z&_&Z69O0e(KW ziHg5^O*j-7V>232Re;L6UY)3`B*sECnwtnSZXE0X#At?^Zg3XkmcI~V?XTU~ieb2u zc!3}$&QV?86I+jG#v^i!L|x>Q3SDt6RLP0m#nFcnG>N@-oNeezb%dW*Y8>pJ11+%? z9J9zQ6wGnOIL3fKTKr<=_0Y|z+@H|mSLD%!xU>us0=7z>~8FMJnE5>0=?5PCGAIC!5$cqbqh&1}X{iB-Hd0Wsbn=66OUdU>%F*+b7PY`6Hnp6nR?2)8PCO zSsLc^-7=J-YQY%?Ip<&&+A^exTVJ9FNQ9=d$_UAk5F@5{#7wml#kZqmEfwG*0wR$V zc`c)$e#P-$q9*OUEwhToiHIgBSqt=(Lr#&q1S@a0Q#B_QJyO0tJBRti>ylwSd?I0#|Z+)@PZ5w5`|G& z3qpv8t+<1oo_<6#>}kb9>C=uPx5-^9Yl)Y!nOQcqXY{gJadwX|DK?YBS`y_5tfizJ zyH&q1&Fnb3mqEpWUl0*h%26|rV^p^=)yzJ+F9#~9rDq`e!fZ2>(O5erGLRp=Y&K#H z{M-GWdg`gCo_gx3r=EK1si&TL>Zzxmdg^~re*jB!z(FbdV3q&?002ovPDHLkV1ft@ BR^9M78R9NZ7gm|Fd@<7J)^Ikt=wW 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 Hhfn_p+=mN4 diff --git a/public/images/pokemon/exp/shiny/935.json b/public/images/pokemon/exp/shiny/935.json deleted file mode 100644 index 3b7326364a9..00000000000 --- a/public/images/pokemon/exp/shiny/935.json +++ /dev/null @@ -1,440 +0,0 @@ -{ - "textures": [ - { - "image": "935.png", - "format": "RGBA8888", - "size": { - "w": 165, - "h": 165 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 0, - "y": 55, - "w": 35, - "h": 55 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 0, - "y": 55, - "w": 35, - "h": 55 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 0, - "y": 55, - "w": 35, - "h": 55 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 0, - "y": 110, - "w": 35, - "h": 55 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 0, - "y": 110, - "w": 35, - "h": 55 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 0, - "y": 110, - "w": 35, - "h": 55 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 35, - "y": 0, - "w": 35, - "h": 55 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 35, - "y": 0, - "w": 35, - "h": 55 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 35, - "y": 0, - "w": 35, - "h": 55 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 35, - "y": 55, - "w": 35, - "h": 55 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 35, - "y": 110, - "w": 35, - "h": 55 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 70, - "y": 0, - "w": 35, - "h": 55 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 105, - "y": 0, - "w": 35, - "h": 55 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 70, - "y": 55, - "w": 35, - "h": 55 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 70, - "y": 110, - "w": 35, - "h": 55 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 105, - "y": 55, - "w": 35, - "h": 55 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 35, - "h": 55 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 55 - }, - "frame": { - "x": 105, - "y": 110, - "w": 35, - "h": 55 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:f58bc6c5ab628b520de90b88937784eb:2cb222a4a62936135e43a7f74d7bb852:077dcf06dc5fc347497b59afe6126a5e$" - } -} diff --git a/public/images/pokemon/exp/shiny/935.png b/public/images/pokemon/exp/shiny/935.png deleted file mode 100644 index ce821b4f870a7ae9467e1076cab0f6e6248e9d03..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1972 zcmYjSeK-?pAD+ZChVpTSXvXYJrWL8PYjsQ`i*4G-lrZy=Ql!>plFxjM6=psrXG$~a z!^c&WbB^{^EluwU8M;Em7^e?sgtzy#cb%^Hdfz{u-+e#Nb6@xGd4A7xT|agR=^z+n z4*~!HU_v0CqQ|Ch!^BV@LCY`a^zd^?aHzi?Ei5c@tgN(U!23RE2WOX$V3zU%GY1(@O4PS5uwrE+yT)sn=8Rw%pUCJZrE$sEFKOy9Ah#_~0W$J>UJ zsNv|`x5ynIMwglIPwP&hJ9!I_tv%Nkh8GrW1X0nY&HOG8w1?1FdGy@Z8Re;dk*0|j zLkql7O$@ge-l~<{07K(bUjC5kZGmaMNTHF*T24wdbenq!sHQ%A-|5;n(093@@;p?h z8+k+YlL|jnhZ}i{JXsx?i_J3CWjq$bS$hkH*Fxh4&RU-7Mc%a(g@hhcS*}34Ha4d! zcz$zI=gd*)n_Mc**@iDz$31|H+FhIcFV0{51pO6BqW6C2@;F6icl78AaeE7bTKDMJ62Gt>YrwLuKSgVKz7CUC%2FbcYWf6xL>y;!6g)(!TvTBqyG!E zqr^Ql=}--E^yKLKbKs9CYKk4BY{JR)*~QM}BXf@4@m0jpyZoB4G!|AU9DcZRv>jWB zo9c<^a$hp98*q)KysK;*g{>%OoI4q(Be)9;h-)1#xWMTqa*R&|y-wD^x_Q52)1rdL zzcTFON+Ri}Taew)g)z$Y&sk#Z`U@6{m2xTvck+Dwbs6Ta$a~Z}Dq)a;LUyo$hs*B8 z6b|v+DrNuN7x};yJU|R_uH(5^$_4-$M+CSCcik_k7wN*i%@X*-z_7-N&F;69qF^^8 z`0k7-e8On`f!i~K`L$cNa6_ATwnRI3zPejCi#^eAoMJOD;QpixdjnGqvs+g!c8kRS z&fcZph%dilPTA^gUCQa=SKgQt4jtq1{;Pr0k`J2Z}};Xgs-hpw%_=ivKezty_H3%jv{qn3@p1 zEq<~Z^M0r85t9EtaiDp-*$}TfjZ-J%%`=Q*oZ2(t zWIV07fjh}u)ol5BLbedHb4i-Niu(EYri_1~_)&|DUC`%=83m~I>iR#HK*u0zgTwm= zx9h!um)AH~+Y9JURNpz)2=mWrwnxu^W{aUVxgS0jt2*1UFw(2{Xc~kY>r=u5?qA(?Cqi*XV4|sF zqb@jN?(pO45%xF3M`Y+Sn^}cHEzrY6TfVn}?o@TT%5yWHqc2?fJqfyu;$WLf2m=?# z)FSv?k{~b(!Q^?`NmBhxvO@^W#vh}fS}jMynMcfc=&j14>6QB;_eCupH2-7EU~t_Z zkgHw6=sWp{`L$1gALJ5f;b3Ax_H(Hf^I(?6qhe$)ghb5Ra|fxJX8WyHc5JRVYj$v4 zj)mRC9yX?#KpffueO>|ckZ-ieNMGz^{B(8>i$s}qW&ST1(*+04%%gqf=&~2tRE5DS zKwp0TYRdN&^C@wQ9B{={y{5W`SwFS+>ojoHiyjgwtZ)Bi$!#Na!hi>;)@l3j)7^TqS>(j90C&+K) zugY{7=_dhViua!Nomkr%dP}S(rCUiFb0B%+aO#DlTi(7NRaoupfo0xHC_NOrvGCj9 zT|N4;*;BjsI|WCp&o1JF+un8B3%R1XX|~T?mB0d9(E)L9fpf+Y_ToahZ6lYHgLuON zD^l##>{a`#&wlfG)z1VsJH%Z^OewJ*j|&-eL0Lq;WnEL{cqSjQ;iM$-Qe%9wwR&?8 zD7JM7>u|j|ecO%}IR`xPnm(=wnnyF_dziH=i(E|K$Y-LX`cl2n+{-7ETEzOV3^%SI y=w;_dh>mVdZ{4G7nBe*3>4rW3_YfpX(ee&%@)}{&po*;TodAMA3E%1$llLD8jFkic diff --git a/public/images/pokemon/exp/shiny/936.json b/public/images/pokemon/exp/shiny/936.json deleted file mode 100644 index 550894878b6..00000000000 --- a/public/images/pokemon/exp/shiny/936.json +++ /dev/null @@ -1,524 +0,0 @@ -{ - "textures": [ - { - "image": "936.png", - "format": "RGBA8888", - "size": { - "w": 323, - "h": 323 - }, - "scale": 1, - "frames": [ - { - "filename": "0016.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 76, - "h": 99 - }, - "frame": { - "x": 0, - "y": 0, - "w": 76, - "h": 99 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 76, - "h": 99 - }, - "frame": { - "x": 0, - "y": 99, - "w": 76, - "h": 99 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 76, - "h": 99 - }, - "frame": { - "x": 0, - "y": 198, - "w": 76, - "h": 99 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 76, - "h": 98 - }, - "frame": { - "x": 76, - "y": 0, - "w": 76, - "h": 98 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 76, - "h": 98 - }, - "frame": { - "x": 152, - "y": 0, - "w": 76, - "h": 98 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 70, - "h": 99 - }, - "frame": { - "x": 228, - "y": 0, - "w": 70, - "h": 99 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 70, - "h": 99 - }, - "frame": { - "x": 76, - "y": 98, - "w": 70, - "h": 99 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 146, - "y": 98, - "w": 59, - "h": 99 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 146, - "y": 98, - "w": 59, - "h": 99 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 146, - "y": 98, - "w": 59, - "h": 99 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 76, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 76, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 76, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 76, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 135, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 135, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 135, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 194, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 1, - "w": 59, - "h": 98 - }, - "frame": { - "x": 205, - "y": 99, - "w": 59, - "h": 98 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 1, - "w": 59, - "h": 98 - }, - "frame": { - "x": 205, - "y": 99, - "w": 59, - "h": 98 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 1, - "w": 59, - "h": 98 - }, - "frame": { - "x": 205, - "y": 99, - "w": 59, - "h": 98 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 1, - "w": 59, - "h": 98 - }, - "frame": { - "x": 205, - "y": 99, - "w": 59, - "h": 98 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 264, - "y": 99, - "w": 59, - "h": 99 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 1, - "w": 59, - "h": 98 - }, - "frame": { - "x": 253, - "y": 198, - "w": 59, - "h": 98 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:244cdd3e42481041b59c3b67b0c2744d:204f377b772d27af90e7fcb35c29932a:1a0490303f9626f92e787c567cd10feb$" - } -} diff --git a/public/images/pokemon/exp/shiny/936.png b/public/images/pokemon/exp/shiny/936.png deleted file mode 100644 index 97856ebb8cc970fc8881e3173cd9dd8aafd8ad4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5491 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 B{Nw-t diff --git a/public/images/pokemon/variant/exp/935_2.png b/public/images/pokemon/variant/exp/935_2.png deleted file mode 100644 index 87d88ad2a7497b59b9b248751c392e70444623b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3216 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 diff --git a/public/images/pokemon/variant/exp/936_1.json b/public/images/pokemon/variant/exp/936_1.json deleted file mode 100644 index f3c45278c91..00000000000 --- a/public/images/pokemon/variant/exp/936_1.json +++ /dev/null @@ -1,524 +0,0 @@ -{ - "textures": [ - { - "image": "936_1.png", - "format": "RGBA8888", - "size": { - "w": 323, - "h": 323 - }, - "scale": 1, - "frames": [ - { - "filename": "0016.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 76, - "h": 99 - }, - "frame": { - "x": 0, - "y": 0, - "w": 76, - "h": 99 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 76, - "h": 99 - }, - "frame": { - "x": 0, - "y": 99, - "w": 76, - "h": 99 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 76, - "h": 99 - }, - "frame": { - "x": 0, - "y": 198, - "w": 76, - "h": 99 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 76, - "h": 98 - }, - "frame": { - "x": 76, - "y": 0, - "w": 76, - "h": 98 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 76, - "h": 98 - }, - "frame": { - "x": 152, - "y": 0, - "w": 76, - "h": 98 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 70, - "h": 99 - }, - "frame": { - "x": 228, - "y": 0, - "w": 70, - "h": 99 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 70, - "h": 99 - }, - "frame": { - "x": 76, - "y": 98, - "w": 70, - "h": 99 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 146, - "y": 98, - "w": 59, - "h": 99 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 146, - "y": 98, - "w": 59, - "h": 99 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 146, - "y": 98, - "w": 59, - "h": 99 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 76, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 76, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 76, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 76, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 135, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 135, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 135, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 194, - "y": 197, - "w": 59, - "h": 99 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 1, - "w": 59, - "h": 98 - }, - "frame": { - "x": 205, - "y": 99, - "w": 59, - "h": 98 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 1, - "w": 59, - "h": 98 - }, - "frame": { - "x": 205, - "y": 99, - "w": 59, - "h": 98 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 1, - "w": 59, - "h": 98 - }, - "frame": { - "x": 205, - "y": 99, - "w": 59, - "h": 98 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 1, - "w": 59, - "h": 98 - }, - "frame": { - "x": 205, - "y": 99, - "w": 59, - "h": 98 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 0, - "w": 59, - "h": 99 - }, - "frame": { - "x": 264, - "y": 99, - "w": 59, - "h": 99 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 76, - "h": 99 - }, - "spriteSourceSize": { - "x": 9, - "y": 1, - "w": 59, - "h": 98 - }, - "frame": { - "x": 253, - "y": 198, - "w": 59, - "h": 98 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:2943281264e8142bbdb55f3a34167d72:322e92870c690e237c7a5e4a4a5f8e84:1a0490303f9626f92e787c567cd10feb$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/936_1.png b/public/images/pokemon/variant/exp/936_1.png deleted file mode 100644 index cdc333ab841b21058028e8a836f33995977f95d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9702 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�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�Ln!vwmj!c;J9Z&@hvd%mlD@71sOa2}$t8 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 P?}rLi)`XP2coq0Rl8OLl?o!;H;xzyF z-?@+X>7JRj**RxsUv_pjMoU8p=gqq}0000-87QywU%dTadyW2|ztQ3U3;?_lagdYK z^3+k1rBhar6Xp{W7Ut&X;R67GF?s1edb*3GQOHh_PAv$2Z0f`pdz}|RoK9de4+kF> zzRK?;0E4i+o}0XOGW0b++nHuY@@~y|5 zuQJYH6v}Uq;(5ts5^$4cgC};yA1*;L>N&n?bH2U8x|JYC*cG2_K|!|n`mT+?i^VF; zOF2?z&~>|kB0xhJzy?|2+4a=5cH*{zur>MwLeE8EO-I2ja}Zj zf$lW00CS!GO)fjms+AQ}RkVUH?7aJD4+Xfva-RZ_I$f)0JD+{8QbZwMd~)U@F1BE( zeE;zHrrZ77-GZn)TFigmG^7MiOkL5usS5I=P&GQW^k$P`qUcvyvXL@(1=)9aeg8@q z+tOo}?g%E*4PX4AeazemJPW@Y9*B18WLf?C!74U;kj zCt4}V^S2Uej~{108NU#u11QL#AIebfqZ9pp`Rg}9D**2g`iqZj(J$RC`2K_vC!xvH zkr9V97m}xj)>yEXV|W)52!;u}k$Zi!`XeZc$@6X0;^hjO&U@Va5ccyoV>0;R5ySW- zI#FJ9a>G=O5r#>W+vu<42(+kDUo*?e0$-5G92M%6Q&mPD7TNBb?6Y~jg8^{lS_-x8 z2_Hznn2hhSpgqR*1WvD-EHp)5Cx(;tz|Z+bX?a3hey6#i2jHKEYxZUQAuxO+{jH23 z1fSqTaol?X(q2W`WM3vM0{W^X!qOKGGD}G`rL=9az~r)F6JiVn1wJjcRO}I2l8DXX z^df^I;gU*iOs%|fsTutlHpe%A3Dgz86eA|b_W@p9A1LzTcoac}ITO_TP5T7bq7Nh( zVMSK)e2L`2YE&#FO)r`#nkc6e#UdyM<3B?i468rPQ60tN40zOAI`RE_JMQ zF))mA)64Cb=qFPNjcCq({XfQTtZpDTqE?Cy!ZrM}c)WqD^U({NJH-IJpx4rg1@vr0 z@mRItKv|B@+(nQHMN!pORo{1&WQ~;XV|GH@jQzSAH?8GP5+RII~tEFcUa4J=0R* zQ?WiRms5LElvmj)_ZWUtimN}Qu2k40w^urD75SzwC3(Eu`kD{wCFK3=%?$es3xf%O z2f^Cl2=EE`_8RMf>zV19`l0hd7vlp4J;p1H8jKd4i%70M;y$y;=g7K*_yo&%VRCN@ zNqz$X-1p-mE<#;jWQE;DjBKYYJP^cIBmC+DtIpuXx57;#s(e*^l>AW$>akb5?T9Gu z2~rJG**J_iN;Sgil&n4{n?&O&?l5j_?sl#MBMQR-6X&MGmIr%h*F2Y1`@o?{OCoz+ z`)RAIs+uhB`Co%KOQx5m>uptgUy*?>b}mCL%T_+q`Hr-f-926N|H8sb!iI|wpQk2& z^G!C)U0}owzOiz)&GV5J_Y9Un8FME|fybi6>ke5I73@UjZK%DsobB}bB$PM5B?dPgc3$kq8X#DgzSb?$PE2X`xf}I zwD8r(*^hXkh){(dNqRS+#qdp1`xVX}_MT5f=tRiGNzrX@d|!G*AZ;QR9(Em8F!^U9 zZT!jZ5SRr#H2qZ_Lnp&1!%I- zRkD?{Sw{B2wbJG$(IZtPy79oUrQjFG!!>7^+jVzGIKZ6CtVB2&!xzIHb0$`li!pvZ z74oB5wXD_Yl;@NvAJY}n6>>JhyQj(2#*)S=sq$5QEngyQGhZk9QtvmZ9(I1&L)qMq zE)8t;<$@b_NtRAY^o-<8cRe5h6zh?{S>TF4s%fk#wyAV9H{--qnE4H%kd548Tx0uy z;39G+q+h<#oIiUjT{q>5MdZURFyABpy{kpr;-&g1>t*0oxA`~Y9kPiB%X7 z5pH!VUyfd4TM%t^IE7ZK)2jM1ld0CIa;mJm?z(i{r6E9Rp8}U4KW*yAiky%JV+I>@ zN6RZM)NCLgBrokUO=G7grj-&rF+)7#xI^nRNV_GjUbRuxn8I|?%touZ`7qF1rcE)QBp%U7z4QIqGW4Tt%YXFjmUddwz|(Zc zcM+>MrkJQeW49nzD$V=w;9z^&s#6twmK!7KS;O1mdhRr_c(oUR%saR}miAlw`_zCv zPL^nHZFUUXcB}CG9aOl5`AGW#gBn9TiYf}mD{gj5kuMUk8T*(v4eG4RZzpv-nHqjd z-Z;{pcU=Rv(s#n!@AnNJYW7+@U63nAo@9Y7+xb(Sv5(oeltF^e4Q7XQl2V6~AI>d$ z!o;ms8d#-mP}e~n`}Fsp2g1kYuNaq=hFAhwd8N(oe4mu(QnJbhq&ZQhk7L`5KHa`g z{O?J`h5ngdKTX%=d@Ao=Kuw+6oOvx=KZ7XhY|S$|w1YkWa349N+B1EK1lrCT&N!tr zgZA&quP;u^;x!9`&~L-99)~8yegC^8fm&*M3jf9bfCfN&g^tfcB_zlvq-_#BEv~R? z1-3QHbJFPg>|WzYy%VgsS>}xb$8>Lgi$Qfqq5hO47xhG??<2}lqchhi6bkB>Rq&q> zxtETHF5tiV|Am7Ud0_y6I8#~vqn>Z>NnT8Pi727M0GFe!)93WTe<*3{0ceB*`Rm3e zBz{@DhJnqlcgJh`mxG#vPkJ-bH!8*#Ga)nHIKlRXq!&fC9E*ep6+M;9zg+4F&0C;0 zKl5D(|4GDEFV}tv^BA}euuzYw0^rIGi2-1HaHmI_RDr7)i>>j!1H7WzTZNNCpTHF!-Pl)dtHgO6F<>s1V(g96D}*qzKODAh5c`*2}6d!*H}2$Z7I=4 zBy=W|-9LIzDC^X7jHWOXs+iy0Q!=PD{SvC!*A8|4?^c;*eV6%8UYhBV&P2I|RyFTS z_RC7Q-oL|Yw~N!{IHNKF`FWwD0LJ1~-Ka&jn;d8nbmO0IrlP0lIet_`(iOEG7>cZq{*dXE0eMG467>kgJuf8?*#_z zZ{PdU;YWi ze>SYj?;VF&C0d<*Vqo`r`Qxj;*Qzq><%zvD+oEVRtSX-7v51N_eBPuJ2R!&R=*A-5 z5Qz73HUCabQ!UdG!N=xbUVo6eyQTdxaVVua8knX>zdLNG;@OcZ`;_D+$`+WO5b9L1 z?Z@yP?l_ez(5U`OZrC7*80}gCRyCNXrjy3@Bf!(MHPsH6%BtpvtZX{(Frm_R3=_AW zP8tySn4jM0kVq7@wB&d$_-W#^Z;#hZE*h9YPbZp}J|7~fG#;XNLm=87neE(k3ZGs6G_%`kB4+%ZxDYJQ+N6Z7ro-1+Skk)$&^K}NtBW8*$4p+tnBL@4Lt+WLIl5~OZHhL#>%g% z@Tb4f>U|GWpNvNt^MZ1VF%QmTNtWf84 zE>fJ=3KBY}*&Lv#%hR65co_0JpH$u?A@}f4^J$qP*LkjY{c!_N>MWl>zEIvZ`mk62 zj-+evN$5QzxD=CtpukSHI1sel*hB>aTUj!9b67u71jNFd)_xww7|A|t8GeM!xk!bj z1*GK15f&q-(V2x%I4>S_PYsGcT}RUR751%xJRa$B{-H(T@g?BCxeMAe>b;d|3FhnO z2)$htfjB{dqNjz4$g&8^-*@Vo0b3DWs{z^ELH^AmxW?!um(Tj1I;;Q4ltso{l+)Ql zngW*Hxv*JRT_XFbxI4nM+?ly^y(I_=4DVEYjFknbKb{*WF$wNbu8spc6*CUfxs=iD z?i);CW)svlO)h|kSrQQ8S!nRbx3DIa-Od=`C}PnfTdid{(MZZrg!v%(^gkvdX@XKZ zPO{*;ieSB4flb!I-2yyY;0z}NlG9YPOd%D?UE`AwVqSq za_=-dHA!wa=o|O5?PLp@;GrXst-eh0w@A!C!12GR5?y?Az zm)V6S>{tSlM)|ev{XomBy{^%AMA1jRjN{?+f4oiEM-OFx4E;V z1U=TB58fNQhPv5n#IQ52BsogQzkAwX8kKKF+c__$^iEYeP?U!@?#auNej{4_YI=%8 zK*@?=uPOIakyECL)>O%1Qsp!nIZAO6p$E>eI55En_3rM&?yLRkO^kxPW4UX_ra;2lzq}guMsSxccBJX zpBK+RXB?gCtd_ppb24FKXiTCzf~MJ1K}I__#y5bUUXF|wJK}A3PYUVSFpaWSbEXJV zCD6|~H;SAe)yBat*1kWQDRU2Nvqn)aQDj-%H9YhaD)_RtIt~0H%IRDsv zi0tjx?9PeS@cO>s3YG_l*}J6)5qn*2@HaY@ivDwG4nV23v;V5+EoB5od&9I*r>hH>6hK_>{H}aZz*KV$r`fe2Zb9 z*}oCOq<))Bjt>?rGlnhKW=JSRh_(C?C^aO0}_~*FgH)p*&&EbMWlZdm}*>fYZ%sX(k zwOk$26~{*Ybt~4DhL^b5BJX}A*EjaY`)Bbf?%t^1UObYL-|sCa;%ry*UyJm}c$w8& zPo29fiwJcbw2Fz2I~eZvi>#8x!>srOR`2|rKrKnu>l-z&U(R87ju?M~g#%7K0>Cc4 zo9xr-^1<%$l`R}_F<~n%OC9(-*0&BCTHLoYgqu0mLn64=Mv!&x-+0CCus+S|x$!?k zAyM>1`K8KZ=j=j+Qat-C8~?BwD^=6f6m6P(qZ#WIR?UjRF>J}zLYpwA$yEp@S`fK3 z2(dRv^+x3Nnm(f{pJ`_FvG8<4!C4(^BZ%WZopgGYEQ8rdwNLwNUR6E;(P|^Z7sby| zm`QGg{B08a*R*yxMK9yG1p7qTvYJnl^AC0?K&4t)&3!~Wp7A4?f zldbH!^>maux>xJzUdXH|D%02-VD6zyyQy~rWP_hdcUvXTI$BddsE)xasv4DN0 zc-D+;x99c?U5-W1zKx9bBwJdAd4JAD&4{ZW?%^Fi<@rs4)ktq5K`~XC_Jcp;gZJ`2 z&HRy}r))VqL!pOfoD|?`R@ibi1Za-9=vIZ{;HieP2!L^x#iRi4^HIl`w>p?OQwLj8~ za`NASINFqncl6ZA<*RJ%ukjB|TPl2o5@;hT)kO1(k88OP*J_!3IwHgxx6)EyB&S^| zsEbps>8{?VCSwh0hUjNnYndlK2QnLp9uBtYgaJn?(w*UtwZefenwO6% zgiW};-qHBID>I!;IT76{XmcLfW^g$-C1!Ol+mAOI#XS_Eb9S$wCiB#q^c#;{0VcN@ zX=>q|1oy-Xzsx=nCc;40N*i!Ii|p96{sFzV)b<#zjwIWiSXe~%GobpkrEx`9`2&rR zzm;{f$<&DoY^MZAtf}-7$UOQ(Lf%>zDa3ZjGaOm4!1|=c%uClx;HS}&BRBdir3Hta zhxKpLz1STrd0-33-Vs~HP7`eY>KfZyb%MwCdvrW&fL2-yF3bL%@L;6&&YyD34EC4P zFV}aZw5>R2AKajO`$?9moL{FCLWYm_&{AFsJI0pngs{edGMhi`1=LZbEQfbP%4w|Q z5iXY?nP$Y9ck$pd4VdL&-jbx`bcax}ulUNb+A*o&;i_VL1WchT?dXv@q;)yo38&0=5dg0398iL1zBuwb^40>^bzIA)XA6DX`km6@LXPvY%I!z$X-x~!0b z{PWz$BQGn_z|{;7BxVkL=ox*4HgP59xf2$a)v@bKy!;sbY|}_2a9=jPBo(4QO0oRZ z`@_+eMbjjb-TLlMt-kwo%6gLpr3HTvZvLVp#7I8Vlojy9{d-8@by`I>pGeC5!Z+D~ zYw!P)lhGCuiEt=?)zBXSvG3Ym?%guJ7npx!Ges$0He_bQzZ@&k8Jy@IE;>36R%Si1 zFUlR3@Xk!n>czhj@LSP7Sjpjan$6eM1nCO=U-o3BWLbVS)OKuaTOUT~bbaMa6f~M^ zJJy)hQR=f`W0JchP-*eq--mN>MK!;}X$(uik0@_R*U>w@l0ujF{!dZxpj!T@n7yu$ z)gd!2%wteZO0@atzd0JpSWUc3tXQPgir(qXh7c#fvLxE}kDO`UKAKvxXj+FG+f!`>UEp6JiImjVIdM%VY7?_-J zakE2S$f@@Q-e9UZcnU;pvqs(?i{AfgU&q0l;3(74OE;)$AFUuuY+=k?zAX73v2b~1 za-&oz&=l-Nz%1_98HN2dGESUI&FLOa&kcrab_91tX_T{gbGZti{HwzfSx*EIhHG;F zDG`m~M%}_#C*oDsX~PPh<_57q;n+0x%8?e8rz>(^ac&-ED1%$4#}JvcGo=<(x1o>a zC?1wUk@HXg-}!QU|B3e6NZ;2a5P2~!_=J)QPGTBa@|>nS-`iG%8p;7T0d-CQp2&Uy!NKUTn?D4Is(?+hulld)xDI zPk=n_0qmA6t2#XX%w13RGo|+}J9~DJMKvjkWSdoXFZl6#=>pEE#}3d-E;90aUseT- zDKiJ|%9Je&s$L2^-IT(7An?XKI`%dRvSP8lr1WE%V3=*K`!zE0mbKAc`o)|x$mw3$ zXX?D>tCD@P%27{&lc-5^tdKxQ^-f^N8n*4_V8r;a40{6+nW@S9N7lz?T4!HTPgZfN zdb`15Zs~k*wO|K(X_o8`*fVXUH@J4g8mY)q@73ku7a5m-*x?*%GOs={F~!{!OxpE} zA}mN$Wbu#1XnH|JNsfdhL47K_9B0@0lHj9AyLZZx|;{7XHr_mL?E8~$?eQ65edR6W5p z5tmP>_nQpR9P2aY}yjT@;Bp6 zoy{2l#C?>%_%rSjs!VvSPF8KM&TS$tDlpq=c~f9kAPB<7v`c7h=o5*&o$LZLNX)AL zkhiV%4rADZ)b&8LjP77K)z z1A19tWNO!2v#P)eX4qmzciua(U~PonZU4Qwx=-GAroWSG_P!maC`+_#ACxranB)+8 znswEgf1bHDW947$e{uJ=%frvF$uCPzvslk~nu0$f5li|Js)<+6uczcm)viqzXp4_b zkytFS_KK@(o+gxhtLXZtLQ2ng45Rg&{Sx)|t-QhEmy*~1lM2BaW_*uBZWULZ;P4vs zOX6;UNz9!NKO^4LGuuUg7hYQ5tG!1~i9fdH_U&rdlZE*{lt%;CL2wgivNXmI>jm>- zaRUj|Uo-cc9DFMM*}v+DiMW4}u6EHp7Mye~@mO3{{-$zK((9A6AGh~R2J_M4d;O#f z0}%>xvOHMMtfhIML1mrJ7z#u)2}u@bfDg`EybtXg8EFsOH4twxpGPCuCQ zCT8waUQF^Ht!WD7w7<3=_(&9}dowAm@yx!Vq<*bFsf2p@xAe<>i~EfHdg{sccirSC zaWCHN{T#@-z)V5R7Rv+lJ%grpFq6j8WnDZlunE;oR|`MCJ?a{iM=?~|npzd3MCy0D scZpoOH#|LkR@{fE|9{*?FbxWQ`W3g{vfNPx#1ZP1_K>z@;j|==^1poj5Do{*RMbE4U{ml)rXv*b@wOgRfgxJ6vAtOj(rH^vK zrJvsq4-ZW=XNX#(0000Pge4IG000hjQchF<|NsC0|NsC0|NsC007byu$N&HU32;bR za{vGizyJUazyWI3i3tDz2s24UK~#8N?OEHB8#@l0IDN5u#{d7jOYkC+5~Z=vZq?Zb zqf+UZ5C}+adnV1V=gatdW9^%Wo!2&BfBww*x%8#%Va?L!cKh?^cGDLF=F(-;hOlI5 zboyoMZp>_G~GZM*oo9cBH774zH%zHd*jy3d8Fu7Di91F^M-97?Tt$ zqy0{I{EUQfK`m3fWwdW@wGs{~K-DoODT2{JZmSf;%~GVM8Fh+iG?0%wIq8qycM>vJ z|87vHh(S4w7PJL}UiGdnr{5MVV75$IJjr zk&%o#_D=9-S~Tz*V(~3T;6l>~O|dc}aLE|LGNGSS0&~jr2xmd7Y&9XLwyGd;3n8k4 zkxTfJrH@BjDd>y>d2QYAEK4C(oS%ijS)32X{nWL+5oNret<^<84lnIw#^z{wI;g_jicFtY^IX-C_g699{YZzAw)6aYqWax_*L@21E)a zf4+%r8I=XKUE_9%Cn3?So5#?*^Q0gU(5EUHX^udGvmLjLh)C)C?IHwN)p^q%nu6Yh z2mR2aPdF)}ksMSY0c9ixkz}-Y+vU?iKqy(4ns(3>&+EKD_LIM3vJrs}3M79CZMhRs zlybi_leVkpq-`a>QX^UlI?d7txM+`4w&h2RxZRTu;tu7cYk;MABI`5-?$;U1`GxAX zd(u(S@yxmgv=jthj>FT}jux?E8&wz~|C=f3gZ54L)ORgVwjzmwQ5gdtUuIV^Vv6VS zeH^&QN&)TaxabpCk=QYXtc4f-zB!3+h$*O-7|oo(mZZg>2@kw8ix?rrfe$<_#Rq>> z2uoZ+9xSXm3IP`Kc??g1CRoYWL164wkmSG?SW~267BOB)vEidl3+a2m_>x1F%6ds4 zbFN)->A>GL)3%D1f>!N2ucjM%SZ-DR)O9SBC}GVYv})bf;3>3!<>S@s8rT-F^l2(@fU zlptg-o<$-At44~&l9yw|w@rww;o2%hsWL1$nHMM-Q^=eniDc#9+v@hz@rb_4xXIK- zUpe@z)R~Zi8KUw~MHAOgKLC~0L4_PSsS|`5QULKkFS66V8sH7J5Yb3|-9Wz|3c+1H z#bnG;XLGo$Sm2}<0-{+w3$uJH#Y84(Tt{w}LF?)6th%-BP`Q2-lN)B#9QCA9sE2o? zG4wmL)&N>)%d`*>T51L0ib9E&qH(nKY$y9cxrmWu9UC~U06Bz+EJftfe4*_J z7y8d&b_%lLtTN{fwIF-Rora8}lN^&F#n8J+(Wu;yz=WpgNblDXh!>o+Y6wTw zQ`WIaan4eBzmC8|)s|xB1XOMy>$;>EID1&!6KTdVbE+s!IMm}=j49w&GX6As?AWN< zjkt-1Q;ZyW)hRZlsGhb1J}8>F6$CVO3bv}-g(1i2)UwxRoFX%DnxzP{mX4Bq`m?Fz zgz3yYATg1AgcM!BXw@_BG8%2h49 zOb`U9x3dT_02Xz}ZVYik08%ut%47+#A6jU+8EFbqImuSGVXX ztiUMQ&mO3u&vwRuVeX?<1~pN}o+bEwLErRx>iu&D9u_eXW)J)xJsvzZ0oOUvf{PlW z+#X;&pIEG_P;DuQxsw4Qu_%ChoM5k?AD=zwGk+c4Bo$*L3LP=@(Go#LnEG5luHh6i z^TFdghz>t>SaAsYgNAspYKH;tj_e`|A&?6jMn~d)zWrU4?Dw4+JTaCs&k(_g(JuS# zWiq9qEyvlzd6ErryEye4^19Qv3?2!`emwIb4x9QhhR%XTG7h3|Cw`FJ%XCPC9P!}K zOC~gfl{CcIWQ@V-sojRDg)(?YAd+zqz9X^UphAud2gqNb-JAckQP8+!{=*VHcTN3x zw@etr_XU|e;iTknr_HAvsw%9=3<^m4e(a-!F!~uGEM_fOUZ+r1VMS&W$@2h#cUND> z6suVafm@C}k8jpg&-;}c($T>R;g9D-3St+t7GikTl1bBCqe!V?PJl565%dYEQb0AI zwHz1XVND`gR8CFU>=>sN_-NqMevq^gErqIBR>Y7g2mX#+6lG0mMhMUD!xvphq3&Zx zf=oFuYl%}1vl_f6X7rlMP#CYU6m9%Mzkns304h}N%4n^6ubCO`hT&I*ricxbOki~G zI`x{FO<^gf4H=ErtH3<$`p=;$tdU(iSlO=sYqY!bU&SYdvHG+5i9m07*qo IM6N<$f^uj+IsgCw diff --git a/public/images/pokemon/variant/exp/back/935_2.json b/public/images/pokemon/variant/exp/back/935_2.json deleted file mode 100644 index 44fc56f8621..00000000000 --- a/public/images/pokemon/variant/exp/back/935_2.json +++ /dev/null @@ -1,356 +0,0 @@ -{ - "textures": [ - { - "image": "935_2.png", - "format": "RGBA8888", - "size": { - "w": 133, - "h": 133 - }, - "scale": 1, - "frames": [ - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 29, - "h": 49 - }, - "frame": { - "x": 0, - "y": 0, - "w": 29, - "h": 49 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 29, - "h": 49 - }, - "frame": { - "x": 0, - "y": 0, - "w": 29, - "h": 49 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 29, - "h": 49 - }, - "frame": { - "x": 29, - "y": 0, - "w": 29, - "h": 49 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 29, - "h": 49 - }, - "frame": { - "x": 29, - "y": 0, - "w": 29, - "h": 49 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 28, - "h": 49 - }, - "frame": { - "x": 58, - "y": 0, - "w": 28, - "h": 49 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 28, - "h": 49 - }, - "frame": { - "x": 58, - "y": 0, - "w": 28, - "h": 49 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 28, - "h": 49 - }, - "frame": { - "x": 86, - "y": 0, - "w": 28, - "h": 49 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 28, - "h": 49 - }, - "frame": { - "x": 86, - "y": 0, - "w": 28, - "h": 49 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 28, - "h": 48 - }, - "frame": { - "x": 0, - "y": 49, - "w": 28, - "h": 48 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 28, - "h": 48 - }, - "frame": { - "x": 0, - "y": 49, - "w": 28, - "h": 48 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 27, - "h": 48 - }, - "frame": { - "x": 28, - "y": 49, - "w": 27, - "h": 48 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 5, - "y": 2, - "w": 27, - "h": 47 - }, - "frame": { - "x": 55, - "y": 49, - "w": 27, - "h": 47 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 5, - "y": 2, - "w": 27, - "h": 47 - }, - "frame": { - "x": 55, - "y": 49, - "w": 27, - "h": 47 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 6, - "y": 3, - "w": 26, - "h": 46 - }, - "frame": { - "x": 82, - "y": 49, - "w": 26, - "h": 46 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 6, - "y": 3, - "w": 26, - "h": 46 - }, - "frame": { - "x": 82, - "y": 49, - "w": 26, - "h": 46 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 7, - "y": 4, - "w": 25, - "h": 45 - }, - "frame": { - "x": 108, - "y": 49, - "w": 25, - "h": 45 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:2880dad5e3c550bb25e02ab0ab8d58c8:9dc0340440df25f20b3f006422b7a238:077dcf06dc5fc347497b59afe6126a5e$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/935_2.png b/public/images/pokemon/variant/exp/back/935_2.png deleted file mode 100644 index 08789758184c7622b1b7d98c05c353d17b342574..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2286 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 IM6N<$f+V3p;{X5v diff --git a/public/images/pokemon/variant/exp/back/935_3.json b/public/images/pokemon/variant/exp/back/935_3.json deleted file mode 100644 index b2d13ca9909..00000000000 --- a/public/images/pokemon/variant/exp/back/935_3.json +++ /dev/null @@ -1,356 +0,0 @@ -{ - "textures": [ - { - "image": "935_3.png", - "format": "RGBA8888", - "size": { - "w": 133, - "h": 133 - }, - "scale": 1, - "frames": [ - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 29, - "h": 49 - }, - "frame": { - "x": 0, - "y": 0, - "w": 29, - "h": 49 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 29, - "h": 49 - }, - "frame": { - "x": 0, - "y": 0, - "w": 29, - "h": 49 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 29, - "h": 49 - }, - "frame": { - "x": 29, - "y": 0, - "w": 29, - "h": 49 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 29, - "h": 49 - }, - "frame": { - "x": 29, - "y": 0, - "w": 29, - "h": 49 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 28, - "h": 49 - }, - "frame": { - "x": 58, - "y": 0, - "w": 28, - "h": 49 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 28, - "h": 49 - }, - "frame": { - "x": 58, - "y": 0, - "w": 28, - "h": 49 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 28, - "h": 49 - }, - "frame": { - "x": 86, - "y": 0, - "w": 28, - "h": 49 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 28, - "h": 49 - }, - "frame": { - "x": 86, - "y": 0, - "w": 28, - "h": 49 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 28, - "h": 48 - }, - "frame": { - "x": 0, - "y": 49, - "w": 28, - "h": 48 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 28, - "h": 48 - }, - "frame": { - "x": 0, - "y": 49, - "w": 28, - "h": 48 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 0, - "y": 1, - "w": 27, - "h": 48 - }, - "frame": { - "x": 28, - "y": 49, - "w": 27, - "h": 48 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 5, - "y": 2, - "w": 27, - "h": 47 - }, - "frame": { - "x": 55, - "y": 49, - "w": 27, - "h": 47 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 5, - "y": 2, - "w": 27, - "h": 47 - }, - "frame": { - "x": 55, - "y": 49, - "w": 27, - "h": 47 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 6, - "y": 3, - "w": 26, - "h": 46 - }, - "frame": { - "x": 82, - "y": 49, - "w": 26, - "h": 46 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 6, - "y": 3, - "w": 26, - "h": 46 - }, - "frame": { - "x": 82, - "y": 49, - "w": 26, - "h": 46 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 32, - "h": 49 - }, - "spriteSourceSize": { - "x": 7, - "y": 4, - "w": 25, - "h": 45 - }, - "frame": { - "x": 108, - "y": 49, - "w": 25, - "h": 45 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:2880dad5e3c550bb25e02ab0ab8d58c8:9dc0340440df25f20b3f006422b7a238:077dcf06dc5fc347497b59afe6126a5e$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/935_3.png b/public/images/pokemon/variant/exp/back/935_3.png deleted file mode 100644 index e58a17ead33673ef4462511a57084d01bbc4c945..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2286 zcmVPx#1ZP1_K>z@;j|==^1poj5Do{*RMgLZ4{fP~+Xv+UqwrDSK%rmMRAtRkZlh3RN z{ml&z4-ZB}L}OuL0000>nvv1~000hjQchF<|NsC0|NsC0|NsC007byu$N&HU32;bR za{vGi!TyoMZp>_G~GZM*oo9cBH774zH%zHd*jy3d8Fu7Di91F^M-97?Tt$ zqy0{I{EUQfK`m3fWwdW@wGs{~K-DoODT2{JZmSf;%~GVM8Fh+iG?0%wIq8qycM>vJ z|87vHh(S4w7PJL}UiGdnr{5MVV75$IJjr zk&%o#_D=9-S~Tz*V(~3T;6l>~O|dc}aLE|LGNGSS0&~jr2xmd7Y&9XLwyGd;3n8k4 zkxTfJrH@BjDd>y>d2QYAEK4C(oS%ijS)32X{nWL+5oNret<^<84lnIw#^z{wI;g_jicFtY^IX-C_g699{YZzAw)6aYqWax_*L@21E)a zf4+%r8I=XKUE_9%Cn3?So5#?*^Q0gU(5EUHX^udGvmLjLh)C)C?IHwN)p^q%nu6Yh z2mR2aPdF)}ksMSY0c9ixkz}-Y+vU?iKqy(4ns(3>&+EKD_LIM3vJrs}3M79CZMhRs zlybi_leVkpq-`a>QX^UlI?d7txM+`4w&h2RxZRTu;tu7cYk;MABI`5-?$;U1`GxAX zd(u(S@yxmgv=jthj>FT}jux?E8&wz~|C=f3gZ54L)ORgVwjzmwQ5gdtUuIV^Vv6VS zeH^&QN&)TaxabpCk=QYXtc4f-zB!3+h$*O-7|oo(mZZg>2@kw8ix?rrfe$<_#Rq>> z2uoZ+9xSXm3IP`Kc??g1CRoYWL164wkmSG?SW~267BOB)vEidl3+a2m_>x1F%6ds4 zbFN)->A>GL)3%D1f>!N2ucjM%SZ-DR)O9SBC}GVYv})bf;3>3!<>S@s8rT-F^l2(@fU zlptg-o<$-At44~&l9yw|w@rww;o2%hsWL1$nHMM-Q^=eniDc#9+v@hz@rb_4xXIK- zUpe@z)R~Zi8KUw~MHAOgKLC~0L4_PSsS|`5QULKkFS66V8sH7J5Yb3|-9Wz|3c+1H z#bnG;XLGo$Sm2}<0-{+w3$uJH#Y84(Tt{w}LF?)6th%-BP`Q2-lN)B#9QCA9sE2o? zG4wmL)&N>)%d`*>T51L0ib9E&qH(nKY$y9cxrmWu9UC~U06Bz+EJftfe4*_J z7y8d&b_%lLtTN{fwIF-Rora8}lN^&F#n8J+(Wu;yz=WpgNblDXh!>o+Y6wTw zQ`WIaan4eBzmC8|)s|xB1XOMy>$;>EID1&!6KTdVbE+s!IMm}=j49w&GX6As?AWN< zjkt-1Q;ZyW)hRZlsGhb1J}8>F6$CVO3bv}-g(1i2)UwxRoFX%DnxzP{mX4Bq`m?Fz zgz3yYATg1AgcM!BXw@_BG8%2h49 zOb`U9x3dT_02Xz}ZVYik08%ut%47+#A6jU+8EFbqImuSGVXX ztiUMQ&mO3u&vwRuVeX?<1~pN}o+bEwLErRx>iu&D9u_eXW)J)xJsvzZ0oOUvf{PlW z+#X;&pIEG_P;DuQxsw4Qu_%ChoM5k?AD=zwGk+c4Bo$*L3LP=@(Go#LnEG5luHh6i z^TFdghz>t>SaAsYgNAspYKH;tj_e`|A&?6jMn~d)zWrU4?Dw4+JTaCs&k(_g(JuS# zWiq9qEyvlzd6ErryEye4^19Qv3?2!`emwIb4x9QhhR%XTG7h3|Cw`FJ%XCPC9P!}K zOC~gfl{CcIWQ@V-sojRDg)(?YAd+zqz9X^UphAud2gqNb-JAckQP8+!{=*VHcTN3x zw@etr_XU|e;iTknr_HAvsw%9=3<^m4e(a-!F!~uGEM_fOUZ+r1VMS&W$@2h#cUND> z6suVafm@C}k8jpg&-;}c($T>R;g9D-3St+t7GikTl1bBCqe!V?PJl565%dYEQb0AI zwHz1XVND`gR8CFU>=>sN_-NqMevq^gErqIBR>Y7g2mX#+6lG0mMhMUD!xvphq3&Zx zf=oFuYl%}1vl_f6X7rlMP#CYU6m9%Mzkns304h}N%4n^6ubCO`hT&I*ricxbOki~G zI`x{FO<^gf4H=ErtH3<$`p=;$tdU(iSlO=sYqY!bU&SYdvHG+5i9m07*qo IM6N<$f?sMpu>b%7 diff --git a/public/images/pokemon/variant/exp/back/936_1.json b/public/images/pokemon/variant/exp/back/936_1.json deleted file mode 100644 index ca0f37cffb2..00000000000 --- a/public/images/pokemon/variant/exp/back/936_1.json +++ /dev/null @@ -1,356 +0,0 @@ -{ - "textures": [ - { - "image": "936_1.png", - "format": "RGBA8888", - "size": { - "w": 283, - "h": 283 - }, - "scale": 1, - "frames": [ - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 0, - "y": 0, - "w": 59, - "h": 97 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 0, - "y": 0, - "w": 59, - "h": 97 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 0, - "y": 97, - "w": 59, - "h": 97 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 0, - "y": 97, - "w": 59, - "h": 97 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 59, - "y": 0, - "w": 59, - "h": 97 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 59, - "y": 0, - "w": 59, - "h": 97 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 8, - "y": 0, - "w": 58, - "h": 97 - }, - "frame": { - "x": 59, - "y": 97, - "w": 58, - "h": 97 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 8, - "y": 0, - "w": 58, - "h": 97 - }, - "frame": { - "x": 59, - "y": 97, - "w": 58, - "h": 97 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 58, - "h": 97 - }, - "frame": { - "x": 117, - "y": 97, - "w": 58, - "h": 97 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 58, - "h": 97 - }, - "frame": { - "x": 117, - "y": 97, - "w": 58, - "h": 97 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 7, - "y": 1, - "w": 57, - "h": 96 - }, - "frame": { - "x": 118, - "y": 0, - "w": 57, - "h": 96 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 7, - "y": 1, - "w": 57, - "h": 96 - }, - "frame": { - "x": 118, - "y": 0, - "w": 57, - "h": 96 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 58, - "h": 95 - }, - "frame": { - "x": 175, - "y": 0, - "w": 58, - "h": 95 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 58, - "h": 95 - }, - "frame": { - "x": 175, - "y": 0, - "w": 58, - "h": 95 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 0, - "y": 3, - "w": 58, - "h": 94 - }, - "frame": { - "x": 175, - "y": 95, - "w": 58, - "h": 94 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 10, - "y": 3, - "w": 57, - "h": 94 - }, - "frame": { - "x": 175, - "y": 189, - "w": 57, - "h": 94 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:973448a7633a4dceb9828d95556ed3c2:09d8ad02433d8015e4665464587b1259:1a0490303f9626f92e787c567cd10feb$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/936_1.png b/public/images/pokemon/variant/exp/back/936_1.png deleted file mode 100644 index 154c4e8636400695b976460f152d4493dcfc03a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9722 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 IM6N<$f`JRTy8r+H diff --git a/public/images/pokemon/variant/exp/back/936_2.json b/public/images/pokemon/variant/exp/back/936_2.json deleted file mode 100644 index 282d9823ab7..00000000000 --- a/public/images/pokemon/variant/exp/back/936_2.json +++ /dev/null @@ -1,356 +0,0 @@ -{ - "textures": [ - { - "image": "936_2.png", - "format": "RGBA8888", - "size": { - "w": 283, - "h": 283 - }, - "scale": 1, - "frames": [ - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 0, - "y": 0, - "w": 59, - "h": 97 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 0, - "y": 0, - "w": 59, - "h": 97 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 0, - "y": 97, - "w": 59, - "h": 97 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 0, - "y": 97, - "w": 59, - "h": 97 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 59, - "y": 0, - "w": 59, - "h": 97 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 59, - "y": 0, - "w": 59, - "h": 97 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 8, - "y": 0, - "w": 58, - "h": 97 - }, - "frame": { - "x": 59, - "y": 97, - "w": 58, - "h": 97 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 8, - "y": 0, - "w": 58, - "h": 97 - }, - "frame": { - "x": 59, - "y": 97, - "w": 58, - "h": 97 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 58, - "h": 97 - }, - "frame": { - "x": 117, - "y": 97, - "w": 58, - "h": 97 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 58, - "h": 97 - }, - "frame": { - "x": 117, - "y": 97, - "w": 58, - "h": 97 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 7, - "y": 1, - "w": 57, - "h": 96 - }, - "frame": { - "x": 118, - "y": 0, - "w": 57, - "h": 96 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 7, - "y": 1, - "w": 57, - "h": 96 - }, - "frame": { - "x": 118, - "y": 0, - "w": 57, - "h": 96 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 58, - "h": 95 - }, - "frame": { - "x": 175, - "y": 0, - "w": 58, - "h": 95 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 58, - "h": 95 - }, - "frame": { - "x": 175, - "y": 0, - "w": 58, - "h": 95 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 0, - "y": 3, - "w": 58, - "h": 94 - }, - "frame": { - "x": 175, - "y": 95, - "w": 58, - "h": 94 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 10, - "y": 3, - "w": 57, - "h": 94 - }, - "frame": { - "x": 175, - "y": 189, - "w": 57, - "h": 94 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:973448a7633a4dceb9828d95556ed3c2:09d8ad02433d8015e4665464587b1259:1a0490303f9626f92e787c567cd10feb$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/936_2.png b/public/images/pokemon/variant/exp/back/936_2.png deleted file mode 100644 index 442abc72971e3dc9dda7496702ed9b7a5481e6be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9722 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 IM6N<$f|Bp9B>(^b diff --git a/public/images/pokemon/variant/exp/back/936_3.json b/public/images/pokemon/variant/exp/back/936_3.json deleted file mode 100644 index 24eeb8e705e..00000000000 --- a/public/images/pokemon/variant/exp/back/936_3.json +++ /dev/null @@ -1,356 +0,0 @@ -{ - "textures": [ - { - "image": "936_3.png", - "format": "RGBA8888", - "size": { - "w": 283, - "h": 283 - }, - "scale": 1, - "frames": [ - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 0, - "y": 0, - "w": 59, - "h": 97 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 0, - "y": 0, - "w": 59, - "h": 97 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 0, - "y": 97, - "w": 59, - "h": 97 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 0, - "y": 97, - "w": 59, - "h": 97 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 59, - "y": 0, - "w": 59, - "h": 97 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 59, - "h": 97 - }, - "frame": { - "x": 59, - "y": 0, - "w": 59, - "h": 97 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 8, - "y": 0, - "w": 58, - "h": 97 - }, - "frame": { - "x": 59, - "y": 97, - "w": 58, - "h": 97 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 8, - "y": 0, - "w": 58, - "h": 97 - }, - "frame": { - "x": 59, - "y": 97, - "w": 58, - "h": 97 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 58, - "h": 97 - }, - "frame": { - "x": 117, - "y": 97, - "w": 58, - "h": 97 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 58, - "h": 97 - }, - "frame": { - "x": 117, - "y": 97, - "w": 58, - "h": 97 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 7, - "y": 1, - "w": 57, - "h": 96 - }, - "frame": { - "x": 118, - "y": 0, - "w": 57, - "h": 96 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 7, - "y": 1, - "w": 57, - "h": 96 - }, - "frame": { - "x": 118, - "y": 0, - "w": 57, - "h": 96 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 58, - "h": 95 - }, - "frame": { - "x": 175, - "y": 0, - "w": 58, - "h": 95 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 58, - "h": 95 - }, - "frame": { - "x": 175, - "y": 0, - "w": 58, - "h": 95 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 0, - "y": 3, - "w": 58, - "h": 94 - }, - "frame": { - "x": 175, - "y": 95, - "w": 58, - "h": 94 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 67, - "h": 97 - }, - "spriteSourceSize": { - "x": 10, - "y": 3, - "w": 57, - "h": 94 - }, - "frame": { - "x": 175, - "y": 189, - "w": 57, - "h": 94 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:973448a7633a4dceb9828d95556ed3c2:09d8ad02433d8015e4665464587b1259:1a0490303f9626f92e787c567cd10feb$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/936_3.png b/public/images/pokemon/variant/exp/back/936_3.png deleted file mode 100644 index db67191d73e4ac2cdf4a29633fc284ae56239ee9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9722 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 IM6N<$f)c)#bN~PV diff --git a/public/images/pokemon/variant/exp/back/937_1.json b/public/images/pokemon/variant/exp/back/937_1.json deleted file mode 100644 index f7f0201b676..00000000000 --- a/public/images/pokemon/variant/exp/back/937_1.json +++ /dev/null @@ -1,650 +0,0 @@ -{ - "textures": [ - { - "image": "937_1.png", - "format": "RGBA8888", - "size": { - "w": 382, - "h": 382 - }, - "scale": 1, - "frames": [ - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 91, - "h": 96 - }, - "frame": { - "x": 0, - "y": 0, - "w": 91, - "h": 96 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 91, - "h": 96 - }, - "frame": { - "x": 91, - "y": 0, - "w": 91, - "h": 96 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 90, - "h": 96 - }, - "frame": { - "x": 182, - "y": 0, - "w": 90, - "h": 96 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 90, - "h": 96 - }, - "frame": { - "x": 182, - "y": 0, - "w": 90, - "h": 96 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 89, - "h": 96 - }, - "frame": { - "x": 272, - "y": 0, - "w": 89, - "h": 96 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 89, - "h": 96 - }, - "frame": { - "x": 272, - "y": 0, - "w": 89, - "h": 96 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 4, - "y": 1, - "w": 91, - "h": 95 - }, - "frame": { - "x": 0, - "y": 96, - "w": 91, - "h": 95 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 4, - "y": 1, - "w": 91, - "h": 95 - }, - "frame": { - "x": 0, - "y": 96, - "w": 91, - "h": 95 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 4, - "y": 1, - "w": 89, - "h": 95 - }, - "frame": { - "x": 91, - "y": 96, - "w": 89, - "h": 95 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 4, - "y": 1, - "w": 89, - "h": 95 - }, - "frame": { - "x": 91, - "y": 96, - "w": 89, - "h": 95 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 88, - "h": 96 - }, - "frame": { - "x": 180, - "y": 96, - "w": 88, - "h": 96 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 88, - "h": 96 - }, - "frame": { - "x": 180, - "y": 96, - "w": 88, - "h": 96 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 88, - "h": 96 - }, - "frame": { - "x": 0, - "y": 191, - "w": 88, - "h": 96 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 88, - "h": 96 - }, - "frame": { - "x": 0, - "y": 191, - "w": 88, - "h": 96 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 7, - "y": 0, - "w": 88, - "h": 96 - }, - "frame": { - "x": 88, - "y": 191, - "w": 88, - "h": 96 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 7, - "y": 0, - "w": 88, - "h": 96 - }, - "frame": { - "x": 88, - "y": 191, - "w": 88, - "h": 96 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 7, - "y": 0, - "w": 87, - "h": 96 - }, - "frame": { - "x": 176, - "y": 192, - "w": 87, - "h": 96 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 7, - "y": 0, - "w": 87, - "h": 96 - }, - "frame": { - "x": 176, - "y": 192, - "w": 87, - "h": 96 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 85, - "h": 95 - }, - "frame": { - "x": 0, - "y": 287, - "w": 85, - "h": 95 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 85, - "h": 95 - }, - "frame": { - "x": 0, - "y": 287, - "w": 85, - "h": 95 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 1, - "y": 3, - "w": 85, - "h": 94 - }, - "frame": { - "x": 85, - "y": 287, - "w": 85, - "h": 94 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 1, - "y": 3, - "w": 85, - "h": 94 - }, - "frame": { - "x": 85, - "y": 287, - "w": 85, - "h": 94 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 82, - "h": 96 - }, - "frame": { - "x": 263, - "y": 192, - "w": 82, - "h": 96 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 82, - "h": 96 - }, - "frame": { - "x": 263, - "y": 192, - "w": 82, - "h": 96 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 8, - "y": 3, - "w": 85, - "h": 93 - }, - "frame": { - "x": 268, - "y": 96, - "w": 85, - "h": 93 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 8, - "y": 3, - "w": 85, - "h": 93 - }, - "frame": { - "x": 268, - "y": 96, - "w": 85, - "h": 93 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 81, - "h": 94 - }, - "frame": { - "x": 170, - "y": 288, - "w": 81, - "h": 94 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 81, - "h": 94 - }, - "frame": { - "x": 170, - "y": 288, - "w": 81, - "h": 94 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 80, - "h": 94 - }, - "frame": { - "x": 251, - "y": 288, - "w": 80, - "h": 94 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 80, - "h": 94 - }, - "frame": { - "x": 251, - "y": 288, - "w": 80, - "h": 94 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:25759b98c1f7867fe6c4ff54c797c3e2:0076c777d18a4f3d780937118dfb6388:1d4b4f8d62307c37457ba974879b47d0$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/937_1.png b/public/images/pokemon/variant/exp/back/937_1.png deleted file mode 100644 index 2d0d58b0912c94c4c2dd06c9c608eda45ec7d496..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18447 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 diff --git a/public/images/pokemon/variant/exp/back/937_2.json b/public/images/pokemon/variant/exp/back/937_2.json deleted file mode 100644 index cda51714b93..00000000000 --- a/public/images/pokemon/variant/exp/back/937_2.json +++ /dev/null @@ -1,650 +0,0 @@ -{ - "textures": [ - { - "image": "937_2.png", - "format": "RGBA8888", - "size": { - "w": 382, - "h": 382 - }, - "scale": 1, - "frames": [ - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 91, - "h": 96 - }, - "frame": { - "x": 0, - "y": 0, - "w": 91, - "h": 96 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 91, - "h": 96 - }, - "frame": { - "x": 91, - "y": 0, - "w": 91, - "h": 96 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 90, - "h": 96 - }, - "frame": { - "x": 182, - "y": 0, - "w": 90, - "h": 96 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 90, - "h": 96 - }, - "frame": { - "x": 182, - "y": 0, - "w": 90, - "h": 96 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 89, - "h": 96 - }, - "frame": { - "x": 272, - "y": 0, - "w": 89, - "h": 96 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 89, - "h": 96 - }, - "frame": { - "x": 272, - "y": 0, - "w": 89, - "h": 96 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 4, - "y": 1, - "w": 91, - "h": 95 - }, - "frame": { - "x": 0, - "y": 96, - "w": 91, - "h": 95 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 4, - "y": 1, - "w": 91, - "h": 95 - }, - "frame": { - "x": 0, - "y": 96, - "w": 91, - "h": 95 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 4, - "y": 1, - "w": 89, - "h": 95 - }, - "frame": { - "x": 91, - "y": 96, - "w": 89, - "h": 95 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 4, - "y": 1, - "w": 89, - "h": 95 - }, - "frame": { - "x": 91, - "y": 96, - "w": 89, - "h": 95 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 88, - "h": 96 - }, - "frame": { - "x": 180, - "y": 96, - "w": 88, - "h": 96 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 88, - "h": 96 - }, - "frame": { - "x": 180, - "y": 96, - "w": 88, - "h": 96 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 88, - "h": 96 - }, - "frame": { - "x": 0, - "y": 191, - "w": 88, - "h": 96 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 88, - "h": 96 - }, - "frame": { - "x": 0, - "y": 191, - "w": 88, - "h": 96 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 7, - "y": 0, - "w": 88, - "h": 96 - }, - "frame": { - "x": 88, - "y": 191, - "w": 88, - "h": 96 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 7, - "y": 0, - "w": 88, - "h": 96 - }, - "frame": { - "x": 88, - "y": 191, - "w": 88, - "h": 96 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 7, - "y": 0, - "w": 87, - "h": 96 - }, - "frame": { - "x": 176, - "y": 192, - "w": 87, - "h": 96 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 7, - "y": 0, - "w": 87, - "h": 96 - }, - "frame": { - "x": 176, - "y": 192, - "w": 87, - "h": 96 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 85, - "h": 95 - }, - "frame": { - "x": 0, - "y": 287, - "w": 85, - "h": 95 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 85, - "h": 95 - }, - "frame": { - "x": 0, - "y": 287, - "w": 85, - "h": 95 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 1, - "y": 3, - "w": 85, - "h": 94 - }, - "frame": { - "x": 85, - "y": 287, - "w": 85, - "h": 94 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 1, - "y": 3, - "w": 85, - "h": 94 - }, - "frame": { - "x": 85, - "y": 287, - "w": 85, - "h": 94 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 82, - "h": 96 - }, - "frame": { - "x": 263, - "y": 192, - "w": 82, - "h": 96 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 82, - "h": 96 - }, - "frame": { - "x": 263, - "y": 192, - "w": 82, - "h": 96 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 8, - "y": 3, - "w": 85, - "h": 93 - }, - "frame": { - "x": 268, - "y": 96, - "w": 85, - "h": 93 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 8, - "y": 3, - "w": 85, - "h": 93 - }, - "frame": { - "x": 268, - "y": 96, - "w": 85, - "h": 93 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 81, - "h": 94 - }, - "frame": { - "x": 170, - "y": 288, - "w": 81, - "h": 94 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 3, - "y": 3, - "w": 81, - "h": 94 - }, - "frame": { - "x": 170, - "y": 288, - "w": 81, - "h": 94 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 80, - "h": 94 - }, - "frame": { - "x": 251, - "y": 288, - "w": 80, - "h": 94 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 95, - "h": 97 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 80, - "h": 94 - }, - "frame": { - "x": 251, - "y": 288, - "w": 80, - "h": 94 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:25759b98c1f7867fe6c4ff54c797c3e2:0076c777d18a4f3d780937118dfb6388:1d4b4f8d62307c37457ba974879b47d0$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/937_2.png b/public/images/pokemon/variant/exp/back/937_2.png deleted file mode 100644 index 7ba1aa09b976f06083d44dc11786295e96eb7ecb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15851 zcmZ8oWmKC@(}n`2xVyGMaVTCi6nBcdwzyky0u*<5EAH;@+CuRHg%Df{1P>6Bm*@NW z%{lkkvpaL|%@?mITSO&CSS$NRvgnp%{8e{xUn~R=3`3J)q&^KyiG%suwv) zChglSoq)QEJZJSL(NFC5ojLq(RzkGZeM`g(x6Wa#4jlBPEq>FYf}BSA%8Lz* z@t?ffu%!*Zwd!hZHQAjlwynKoOB{%~A=0Th*6LMS)!J&j_l#=%RhBwX&R?napZ|BIc5zb)nTHF`pj|sA}XG%&Tkw7WU^bAcW=JHgt4<; zWCaK&GMm~4HzEIP2X?fEk-R1G>MFQupDO1;kt~kF`>k}@z@Tb@rqtdzbDQQ(Df95K z7e&Q~-S^N_##4J?V-wr+qO2zye75m<Y;j)MqTW{5`XFJB~ly;R1?3>hA^g1k?5DCZTq_(_yk5IC!x5H5A;(7^}kORku z<^n=;#|^?oRT4W6`&bQ~@qNGPsrMU-s8f2FtsmPBNbgHk3;0RfWOdlV?mGM0{@5yt z^grybxk7;QA}E09?qX|EfpVqJ7q2D`2Gd-BeyaM`wmxX}ts5{yZ>-q(}ix<^eEFyODcDsB}bCn|FiSUHTwE)NRlC$l_>W4yN0kK zkp;r#*Cm)=?1PJS2VX1`{RM*!LZtX+ogM!2Ul>M*>(bcKER!mY1^2uPgs(RiT&eL* z+WG_pb`gdonNO7b-2Z}e92rwhrA4^(3PVfXw*kEO>g@CsOX>`66bHmPmXEUEcq+

ij_`qhqj`Bk${ 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 z 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 Hu0mjfNTKz+ From 4203513db2b736da3e44b5d2615ee15ab6aaade8 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Mon, 5 May 2025 19:49:59 -0500 Subject: [PATCH 29/61] [Bug] Ensure shiny and variant status respects illusion properly (#5784) Ensure shiny and variant status respects illusion properly --- src/system/pokemon-data.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/system/pokemon-data.ts b/src/system/pokemon-data.ts index 248fe9cf513..8d4fd7c05df 100644 --- a/src/system/pokemon-data.ts +++ b/src/system/pokemon-data.ts @@ -91,8 +91,8 @@ export default class PokemonData { this.formIndex = Math.max(Math.min(source.formIndex, getPokemonSpecies(this.species).forms.length - 1), 0); this.abilityIndex = source.abilityIndex; this.passive = source.passive; - this.shiny = source.shiny; - this.variant = source.variant; + this.shiny = sourcePokemon?.summonData.illusion?.basePokemon.shiny ?? source.shiny; + this.variant = sourcePokemon?.summonData.illusion?.basePokemon.variant ?? source.variant; this.pokeball = source.pokeball ?? PokeballType.POKEBALL; this.level = source.level; this.exp = source.exp; From e677e2725ee5035c4d9d356292f398dbab1625e4 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Mon, 5 May 2025 19:52:03 -0500 Subject: [PATCH 30/61] Update locales --- public/locales | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/locales b/public/locales index a7036a07875..f4b8b7b737e 160000 --- a/public/locales +++ b/public/locales @@ -1 +1 @@ -Subproject commit a7036a07875615674ea898d0fe3b182a1080af38 +Subproject commit f4b8b7b737e47eaf7e7231855d0b59f8c7c7c0f8 From 4f541a8dcebb642d67d0e40c9bd8efd52dd429f6 Mon Sep 17 00:00:00 2001 From: Lylian BALL <131535108+PyGaVS@users.noreply.github.com> Date: Tue, 6 May 2025 03:31:11 +0200 Subject: [PATCH 31/61] [Bug] Fix some moves using illusion type instead of real type (#5772) * fix revelation dance using the type of the illusion instead of the actual type * fix other move that might get the illusion type as well * fix other move that might get the illusion type as well * fix abilities that might get the illusion type as well * fix illusion icon in party ui handler * Fix TSDoc for `Pokemon#getTypes` * Remove now-unnecessary changes to `.getTypes()` calls Revert `overrides.ts` changes * Replace `|| false` with `!!` --------- Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/battle-scene.ts | 17 ++++--- src/data/abilities/ability.ts | 3 +- src/field/pokemon.ts | 92 +++++++++++++++++++++-------------- src/modifier/modifier.ts | 2 +- src/ui/battle-info.ts | 4 +- 5 files changed, 69 insertions(+), 49 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index db036847994..39bd1dd64cf 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -1046,31 +1046,32 @@ export default class BattleScene extends SceneBase { originX = 0.5, originY = 0.5, ignoreOverride = false, + useIllusion = false, ): Phaser.GameObjects.Container { const container = this.add.container(x, y); container.setName(`${pokemon.name}-icon`); - const icon = this.add.sprite(0, 0, pokemon.getIconAtlasKey(ignoreOverride)); + const icon = this.add.sprite(0, 0, pokemon.getIconAtlasKey(ignoreOverride, useIllusion)); icon.setName(`sprite-${pokemon.name}-icon`); - icon.setFrame(pokemon.getIconId(true)); + icon.setFrame(pokemon.getIconId(true, useIllusion)); // Temporary fix to show pokemon's default icon if variant icon doesn't exist - if (icon.frame.name !== pokemon.getIconId(true)) { + if (icon.frame.name !== pokemon.getIconId(true, useIllusion)) { console.log(`${pokemon.name}'s variant icon does not exist. Replacing with default.`); const temp = pokemon.shiny; pokemon.shiny = false; - icon.setTexture(pokemon.getIconAtlasKey(ignoreOverride)); - icon.setFrame(pokemon.getIconId(true)); + icon.setTexture(pokemon.getIconAtlasKey(ignoreOverride, useIllusion)); + icon.setFrame(pokemon.getIconId(true, useIllusion)); pokemon.shiny = temp; } icon.setOrigin(0.5, 0); container.add(icon); - if (pokemon.isFusion(true)) { - const fusionIcon = this.add.sprite(0, 0, pokemon.getFusionIconAtlasKey(ignoreOverride)); + if (pokemon.isFusion(useIllusion)) { + const fusionIcon = this.add.sprite(0, 0, pokemon.getFusionIconAtlasKey(ignoreOverride, useIllusion)); fusionIcon.setName("sprite-fusion-icon"); fusionIcon.setOrigin(0.5, 0); - fusionIcon.setFrame(pokemon.getFusionIconId(true)); + fusionIcon.setFrame(pokemon.getFusionIconId(true, useIllusion)); const originalWidth = icon.width; const originalHeight = icon.height; diff --git a/src/data/abilities/ability.ts b/src/data/abilities/ability.ts index 705de6f242d..4609ff6ec1a 100644 --- a/src/data/abilities/ability.ts +++ b/src/data/abilities/ability.ts @@ -43,10 +43,9 @@ import { PokemonTransformPhase } from "#app/phases/pokemon-transform-phase"; import { allAbilities } from "#app/data/data-lists"; import { AbAttr } from "#app/data/abilities/ab-attrs/ab-attr"; import { Ability } from "#app/data/abilities/ability-class"; -import { TrainerVariant } from "#app/field/trainer"; // Enum imports -import { Stat, type BattleStat , BATTLE_STATS, EFFECTIVE_STATS, getStatKey, type EffectiveStat } from "#enums/stat"; +import { Stat, type BattleStat, BATTLE_STATS, EFFECTIVE_STATS, getStatKey, type EffectiveStat } from "#enums/stat"; import { PokemonType } from "#enums/pokemon-type"; import { PokemonAnimType } from "#enums/pokemon-anim-type"; import { StatusEffect } from "#enums/status-effect"; diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 5615f3844bd..13eb2990a17 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -1115,40 +1115,45 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { ); } - getIconAtlasKey(ignoreOverride?: boolean): string { - const formIndex = this.summonData.illusion?.formIndex ?? this.formIndex; - return this.getSpeciesForm(ignoreOverride, true).getIconAtlasKey( + getIconAtlasKey(ignoreOverride?: boolean, useIllusion: boolean = true): string { + const formIndex = 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( formIndex, - this.shiny, - this.variant + this.isBaseShiny(useIllusion), + variant ); } - getFusionIconAtlasKey(ignoreOverride?: boolean): string { - return this.getFusionSpeciesForm(ignoreOverride, true).getIconAtlasKey( - this.fusionFormIndex, - this.fusionShiny, - this.fusionVariant - ); - } - - getIconId(ignoreOverride?: boolean): string { - const formIndex = this.summonData.illusion?.formIndex ?? this.formIndex; - return this.getSpeciesForm(ignoreOverride, true).getIconId( - this.getGender(ignoreOverride, true) === Gender.FEMALE, - formIndex, - this.shiny, - this.variant - ); - } - - getFusionIconId(ignoreOverride?: boolean): string { - const fusionFormIndex = this.summonData.illusion?.fusionFormIndex ?? this.fusionFormIndex; - return this.getFusionSpeciesForm(ignoreOverride, true).getIconId( - this.getFusionGender(ignoreOverride, true) === Gender.FEMALE, + getFusionIconAtlasKey(ignoreOverride?: boolean, useIllusion: boolean = true): string { + const fusionFormIndex = 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( fusionFormIndex, - this.fusionShiny, - this.fusionVariant + this.isFusionShiny(), + fusionVariant + ); + } + + getIconId(ignoreOverride?: boolean, useIllusion: boolean = true): string { + const formIndex = 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).getIconId( + this.getGender(ignoreOverride, useIllusion) === Gender.FEMALE, + formIndex, + this.isBaseShiny(), + variant + ); + } + + getFusionIconId(ignoreOverride?: boolean, useIllusion: boolean = true): string { + const fusionFormIndex = 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).getIconId( + this.getFusionGender(ignoreOverride, useIllusion) === Gender.FEMALE, + fusionFormIndex, + this.isFusionShiny(), + fusionVariant ); } @@ -1885,6 +1890,22 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } } + isBaseShiny(useIllusion: boolean = false){ + if (!useIllusion && this.summonData.illusion) { + return !!this.summonData.illusion.basePokemon?.shiny; + } else { + return this.shiny; + } + } + + isFusionShiny(useIllusion: boolean = false){ + if (!useIllusion && this.summonData.illusion) { + return !!this.summonData.illusion.basePokemon?.fusionShiny; + } else { + return this.isFusion(useIllusion) && this.fusionShiny; + } + } + /** * * @param useIllusion - Whether we want the fake or real shininess (illusion ability). @@ -2053,14 +2074,14 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param includeTeraType - `true` to include tera-formed type; Default: `false` * @param forDefend - `true` if the pokemon is defending from an attack; Default: `false` * @param ignoreOverride - If `true`, ignore ability changing effects; Default: `false` - * @param useIllusion - `true` to return the types of the illusion instead of the actual types; "AUTO" will depend on forDefend param; Default: "AUTO" + * @param useIllusion - `true` to return the types of the illusion instead of the actual types; Default: `false` * @returns array of {@linkcode PokemonType} */ public getTypes( includeTeraType = false, forDefend: boolean = false, - ignoreOverride?: boolean, - useIllusion: boolean | "AUTO" = "AUTO" + ignoreOverride: boolean = false, + useIllusion: boolean = false ): PokemonType[] { const types: PokemonType[] = []; @@ -2076,17 +2097,16 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } if (!types.length || !includeTeraType) { - const doIllusion: boolean = (useIllusion === "AUTO") ? !forDefend : useIllusion; if ( !ignoreOverride && this.summonData.types && this.summonData.types.length > 0 && - (!this.summonData.illusion || !doIllusion) + (!this.summonData.illusion || !useIllusion) ) { this.summonData.types.forEach(t => types.push(t)); } else { - const speciesForm = this.getSpeciesForm(ignoreOverride, doIllusion); - const fusionSpeciesForm = this.getFusionSpeciesForm(ignoreOverride, doIllusion); + const speciesForm = this.getSpeciesForm(ignoreOverride, useIllusion); + const fusionSpeciesForm = this.getFusionSpeciesForm(ignoreOverride, useIllusion); const customTypes = this.customPokemonData.types?.length > 0; // First type, checking for "permanently changed" types from ME diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 9df7aa7813f..763b40c8555 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -710,7 +710,7 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier { if (!forSummary) { const pokemon = this.getPokemon(); if (pokemon) { - const pokemonIcon = globalScene.addPokemonIcon(pokemon, -2, 10, 0, 0.5); + const pokemonIcon = globalScene.addPokemonIcon(pokemon, -2, 10, 0, 0.5, undefined, true); container.add(pokemonIcon); container.setName(pokemon.id.toString()); } diff --git a/src/ui/battle-info.ts b/src/ui/battle-info.ts index 839f0d62819..2822e8364ec 100644 --- a/src/ui/battle-info.ts +++ b/src/ui/battle-info.ts @@ -465,7 +465,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container { this.shinyIcon.setVisible(pokemon.isShiny()); - const types = pokemon.getTypes(true); + const types = pokemon.getTypes(true, false, undefined, true); this.type1Icon.setTexture(`pbinfo_${this.player ? "player" : "enemy"}_type${types.length > 1 ? "1" : ""}`); this.type1Icon.setFrame(PokemonType[types[0]].toLowerCase()); this.type2Icon.setVisible(types.length > 1); @@ -685,7 +685,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container { this.statusIndicator.setVisible(!!this.lastStatus); } - const types = pokemon.getTypes(true); + const types = pokemon.getTypes(true, false, undefined, true); this.type1Icon.setTexture(`pbinfo_${this.player ? "player" : "enemy"}_type${types.length > 1 ? "1" : ""}`); this.type1Icon.setFrame(PokemonType[types[0]].toLowerCase()); this.type2Icon.setVisible(types.length > 1); From 4aa0eac5aadc133796d6d9d6c911095653228560 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Tue, 6 May 2025 04:33:10 -0700 Subject: [PATCH 32/61] Update version to 1.9.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9d9b7638997..da89f87b0bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pokemon-rogue-battle", - "version": "1.9.1", + "version": "1.9.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pokemon-rogue-battle", - "version": "1.9.1", + "version": "1.9.2", "hasInstallScript": true, "dependencies": { "@material/material-color-utilities": "^0.2.7", diff --git a/package.json b/package.json index 6bde0af2fa5..d5eb1138776 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "pokemon-rogue-battle", "private": true, - "version": "1.9.1", + "version": "1.9.2", "type": "module", "scripts": { "start": "vite", From 5ba294ffee839e06146269de3d7849b0ea8c38be Mon Sep 17 00:00:00 2001 From: lxy-lxy-lxy <55084073+lxy-lxy-lxy@users.noreply.github.com> Date: Wed, 7 May 2025 23:05:32 +0800 Subject: [PATCH 33/61] [Bug] Lock Capsule not locking rarities consistently (#5786) --- src/modifier/modifier-type.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 8bd2dc8948a..608eca1157e 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -3640,7 +3640,7 @@ function getNewModifierTypeOption( } tier += upgradeCount; } - } else if (retryCount === 10 && tier) { + } else if (retryCount >= 100 && tier) { retryCount = 0; tier--; } From fa6c51d1e2c07be50c4017896bb0008192f7af81 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Wed, 7 May 2025 21:01:54 -0700 Subject: [PATCH 34/61] [Bug] Prevent some corrupt eggs from crashing the game (#5787) If an egg is somehow a species that doesn't have an associated egg tier (such as Pikachu), `Egg#getEggTier` now falls back to `EggTier.COMMON` --- src/data/egg.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/egg.ts b/src/data/egg.ts index 55a253e843f..0b7733bf199 100644 --- a/src/data/egg.ts +++ b/src/data/egg.ts @@ -598,7 +598,7 @@ export class Egg { } private getEggTier(): EggTier { - return speciesEggTiers[this.species]; + return speciesEggTiers[this.species] ?? EggTier.COMMON; } //// From cf1367cece5f09545be69c9efea8d75069edb47c Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Wed, 7 May 2025 21:02:16 -0700 Subject: [PATCH 35/61] [Bug] `PokemonSummonData` movesets will now be loaded correctly (#5793) --- src/field/pokemon.ts | 5 +++++ src/system/version_migration/versions/v1_9_0.ts | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 13eb2990a17..a7db6ddcdf3 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -7859,6 +7859,11 @@ export class PokemonSummonData { continue; } + if (key === "moveset") { + this.moveset = value.map((m: any) => PokemonMove.loadMove(m)); + continue; + } + if (key === "tags") { // load battler tags this.tags = value.map((t: BattlerTag) => loadBattlerTag(t)); diff --git a/src/system/version_migration/versions/v1_9_0.ts b/src/system/version_migration/versions/v1_9_0.ts index dca92cd1fae..c517896cf45 100644 --- a/src/system/version_migration/versions/v1_9_0.ts +++ b/src/system/version_migration/versions/v1_9_0.ts @@ -1,5 +1,4 @@ import type { SessionSaveMigrator } from "#app/@types/SessionSaveMigrator"; -import { Status } from "#app/data/status-effect"; import { PokemonMove } from "#app/field/pokemon"; import type { SessionSaveData } from "#app/system/game-data"; import type PokemonData from "#app/system/pokemon-data"; From 530b2b8a006e75e10413ecc9e42ac257dbe8acdf Mon Sep 17 00:00:00 2001 From: Jimmybald1 <122436263+Jimmybald1@users.noreply.github.com> Date: Thu, 8 May 2025 06:03:22 +0200 Subject: [PATCH 36/61] [Bug] Fix seed not being reset in Select Biome Phase (#5794) Fix seed not being reset now that Select Biome Phase goes before New Battle Co-authored-by: Jimmybald1 <147992650+IBBCalc@users.noreply.github.com> --- src/phases/select-biome-phase.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/phases/select-biome-phase.ts b/src/phases/select-biome-phase.ts index 4811c4e6b8f..efd376eb5ba 100644 --- a/src/phases/select-biome-phase.ts +++ b/src/phases/select-biome-phase.ts @@ -13,6 +13,8 @@ export class SelectBiomePhase extends BattlePhase { start() { super.start(); + globalScene.resetSeed(); + const currentBiome = globalScene.arena.biomeType; const nextWaveIndex = globalScene.currentBattle.waveIndex + 1; From 5a58abfddf65cf21f67db6b28befe122f38ef522 Mon Sep 17 00:00:00 2001 From: Dean <69436131+emdeann@users.noreply.github.com> Date: Wed, 7 May 2025 21:04:24 -0700 Subject: [PATCH 37/61] [Bug][Hotfix] Suppress Illusion if NG is already active (#5797) * Suppress preSummon attrs off field * Add test case --- src/field/pokemon.ts | 4 +++- test/abilities/illusion.test.ts | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index a7db6ddcdf3..6a05bea4c6d 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -186,6 +186,7 @@ import { applyAllyStatMultiplierAbAttrs, AllyStatMultiplierAbAttr, MoveAbilityBypassAbAttr, + PreSummonAbAttr, } from "#app/data/abilities/ability"; import { allAbilities } from "#app/data/data-lists"; import type PokemonData from "#app/system/pokemon-data"; @@ -2414,8 +2415,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const suppressAbilitiesTag = arena.getTag( ArenaTagType.NEUTRALIZING_GAS, ) as SuppressAbilitiesTag; + const suppressOffField = ability.hasAttr(PreSummonAbAttr); if ( - this.isOnField() && + (this.isOnField() || suppressOffField) && suppressAbilitiesTag && !suppressAbilitiesTag.isBeingRemoved() ) { diff --git a/test/abilities/illusion.test.ts b/test/abilities/illusion.test.ts index 998d29f169c..8aae433b6c0 100644 --- a/test/abilities/illusion.test.ts +++ b/test/abilities/illusion.test.ts @@ -65,7 +65,7 @@ describe("Abilities - Illusion", () => { expect(!!zorua.summonData.illusion).equals(false); }); - it("break with neutralizing gas", async () => { + it("breaks with neutralizing gas", async () => { game.override.enemyAbility(Abilities.NEUTRALIZING_GAS); await game.classicMode.startBattle([Species.KOFFING]); @@ -74,6 +74,20 @@ describe("Abilities - Illusion", () => { expect(!!zorua.summonData.illusion).equals(false); }); + it("does not activate if neutralizing gas is active", async () => { + game.override + .enemyAbility(Abilities.NEUTRALIZING_GAS) + .ability(Abilities.ILLUSION) + .moveset(Moves.SPLASH) + .enemyMoveset(Moves.SPLASH); + await game.classicMode.startBattle([Species.MAGIKARP, Species.FEEBAS, Species.MAGIKARP]); + + game.doSwitchPokemon(1); + await game.toNextTurn(); + + expect(game.scene.getPlayerPokemon()!.summonData.illusion).toBeFalsy(); + }); + it("causes enemy AI to consider the illusion's type instead of the actual type when considering move effectiveness", async () => { game.override.enemyMoveset([Moves.FLAMETHROWER, Moves.PSYCHIC, Moves.TACKLE]); await game.classicMode.startBattle([Species.ZOROARK, Species.FEEBAS]); From b183f26330831ca4668a7024eb631da6be7d5307 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Fri, 9 May 2025 00:16:06 -0700 Subject: [PATCH 38/61] Update version to 1.9.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index da89f87b0bd..02a5d375588 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pokemon-rogue-battle", - "version": "1.9.2", + "version": "1.9.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pokemon-rogue-battle", - "version": "1.9.2", + "version": "1.9.3", "hasInstallScript": true, "dependencies": { "@material/material-color-utilities": "^0.2.7", diff --git a/package.json b/package.json index d5eb1138776..715deefbe32 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "pokemon-rogue-battle", "private": true, - "version": "1.9.2", + "version": "1.9.3", "type": "module", "scripts": { "start": "vite", From 0712f86462fde33333f84024988fd11521724046 Mon Sep 17 00:00:00 2001 From: Dean <69436131+emdeann@users.noreply.github.com> Date: Fri, 9 May 2025 01:34:28 -0700 Subject: [PATCH 39/61] [Bug][Hotfix] Fix crashes when loading save with a transformed pokemon (#5806) * Fix speciesForm being saved incorrectly * Fix transformed icon * Fix moveset loading errors --- src/battle-scene.ts | 8 ++++---- src/field/pokemon.ts | 2 +- src/system/pokemon-data.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 39bd1dd64cf..9f70b33b296 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -1045,7 +1045,7 @@ export default class BattleScene extends SceneBase { y: number, originX = 0.5, originY = 0.5, - ignoreOverride = false, + ignoreOverride = true, useIllusion = false, ): Phaser.GameObjects.Container { const container = this.add.container(x, y); @@ -1053,9 +1053,9 @@ export default class BattleScene extends SceneBase { const icon = this.add.sprite(0, 0, pokemon.getIconAtlasKey(ignoreOverride, useIllusion)); icon.setName(`sprite-${pokemon.name}-icon`); - icon.setFrame(pokemon.getIconId(true, useIllusion)); + icon.setFrame(pokemon.getIconId(ignoreOverride, useIllusion)); // Temporary fix to show pokemon's default icon if variant icon doesn't exist - if (icon.frame.name !== pokemon.getIconId(true, useIllusion)) { + if (icon.frame.name !== pokemon.getIconId(ignoreOverride, useIllusion)) { console.log(`${pokemon.name}'s variant icon does not exist. Replacing with default.`); const temp = pokemon.shiny; pokemon.shiny = false; @@ -1071,7 +1071,7 @@ export default class BattleScene extends SceneBase { const fusionIcon = this.add.sprite(0, 0, pokemon.getFusionIconAtlasKey(ignoreOverride, useIllusion)); fusionIcon.setName("sprite-fusion-icon"); fusionIcon.setOrigin(0.5, 0); - fusionIcon.setFrame(pokemon.getFusionIconId(true, useIllusion)); + fusionIcon.setFrame(pokemon.getFusionIconId(ignoreOverride, useIllusion)); const originalWidth = icon.width; const originalHeight = icon.height; diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 6a05bea4c6d..43669c874a9 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -7862,7 +7862,7 @@ export class PokemonSummonData { } if (key === "moveset") { - this.moveset = value.map((m: any) => PokemonMove.loadMove(m)); + this.moveset = value?.map((m: any) => PokemonMove.loadMove(m)); continue; } diff --git a/src/system/pokemon-data.ts b/src/system/pokemon-data.ts index 8d4fd7c05df..00169678ed0 100644 --- a/src/system/pokemon-data.ts +++ b/src/system/pokemon-data.ts @@ -188,7 +188,7 @@ export default class PokemonData { // when loading from saved session, recover summonData.speciesFrom and form index species object // used to stay transformed on reload session if (this.summonData.speciesForm) { - this.summonData.speciesForm = getPokemonSpeciesForm( + ret.summonData.speciesForm = getPokemonSpeciesForm( this.summonData.speciesForm.speciesId, this.summonDataSpeciesFormIndex, ); From 09e38bad39d33f21eeec6f95c944a4c31dc7a13f Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Sat, 10 May 2025 19:05:18 -0500 Subject: [PATCH 40/61] Set lastHit to true when target faints during multi-hit move --- src/phases/move-effect-phase.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index c65e8e15271..462e4ba47b8 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -905,6 +905,14 @@ export class MoveEffectPhase extends PokemonPhase { target.destroySubstitute(); target.lapseTag(BattlerTagType.COMMANDED); + + // Force `lastHit` to be true if this is a multi hit move with hits left + // `hitsLeft` must be left as-is in order for the message displaying the number of hits + // to display the proper number. + // Note: When Dragon Darts' smart targeting is implemented, this logic may need to be adjusted. + if (!this.lastHit && user.turnData.hitsLeft > 1) { + this.lastHit = true; + } } /** From 6c6821b47d96df23a6b71f508e1a810a70d4b1ec Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Sun, 11 May 2025 20:10:19 -0500 Subject: [PATCH 41/61] [Bug] [Move] Fix KO causing effects to occur twice (#5811) * Fix firstTarget calculation when a target was fainted * Update type annotation in applyMoveEffects Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --------- Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/phases/move-effect-phase.ts | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index 462e4ba47b8..d067807486d 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -206,11 +206,13 @@ export class MoveEffectPhase extends PokemonPhase { * @throws Error if there was an unexpected hit check result */ private applyToTargets(user: Pokemon, targets: Pokemon[]): void { + let firstHit = true; for (const [i, target] of targets.entries()) { const [hitCheckResult, effectiveness] = this.hitChecks[i]; switch (hitCheckResult) { case HitCheckResult.HIT: - this.applyMoveEffects(target, effectiveness); + this.applyMoveEffects(target, effectiveness, firstHit); + firstHit = false; if (isFieldTargeted(this.move)) { // Stop processing other targets if the move is a field move return; @@ -763,15 +765,12 @@ export class MoveEffectPhase extends PokemonPhase { * - Invoking {@linkcode applyOnTargetEffects} if the move does not hit a substitute * - Triggering form changes and emergency exit / wimp out if this is the last hit * - * @param target the {@linkcode Pokemon} hit by this phase's move. - * @param effectiveness the effectiveness of the move (as previously evaluated in {@linkcode hitCheck}) + * @param target - the {@linkcode Pokemon} hit by this phase's move. + * @param effectiveness - The effectiveness of the move (as previously evaluated in {@linkcode hitCheck}) + * @param firstTarget - Whether this is the first target successfully struck by the move */ - protected applyMoveEffects(target: Pokemon, effectiveness: TypeDamageMultiplier): void { + protected applyMoveEffects(target: Pokemon, effectiveness: TypeDamageMultiplier, firstTarget: boolean): void { const user = this.getUserPokemon(); - - /** The first target hit by the move */ - const firstTarget = target === this.getTargets().find((_, i) => this.hitChecks[i][1] > 0); - if (isNullOrUndefined(user)) { return; } From d790b30a30f26fd9a31af96b4b84c83d7b61151a Mon Sep 17 00:00:00 2001 From: Dean <69436131+emdeann@users.noreply.github.com> Date: Sun, 11 May 2025 18:23:37 -0700 Subject: [PATCH 42/61] [Bug][Hotfix] Fix Transformed Sprites not loading properly (#5808) * Fix ditto sprite not loading properly * Remove review comment --- src/field/pokemon.ts | 17 ++++++++++------- src/system/game-data.ts | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 43669c874a9..eec20beb01c 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -909,19 +909,22 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const originalWarn = console.warn; // Ignore warnings for missing frames, because there will be a lot console.warn = () => {}; - const battleFrameNames = globalScene.anims.generateFrameNames(this.getBattleSpriteKey(), { + const battleSpriteKey = this.getBattleSpriteKey(this.isPlayer(), ignoreOverride); + const battleFrameNames = globalScene.anims.generateFrameNames(battleSpriteKey, { zeroPad: 4, suffix: ".png", start: 1, end: 400, }); console.warn = originalWarn; - globalScene.anims.create({ - key: this.getBattleSpriteKey(), - frames: battleFrameNames, - frameRate: 10, - repeat: -1, - }); + if (!globalScene.anims.exists(battleSpriteKey)) { + globalScene.anims.create({ + key: battleSpriteKey, + frames: battleFrameNames, + frameRate: 10, + repeat: -1, + }); + } } // With everything loaded, now begin playing the animation. this.playAnim(); diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 51e488210be..0c5e0b349ed 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -1110,7 +1110,7 @@ export class GameData { for (const p of sessionData.party) { const pokemon = p.toPokemon() as PlayerPokemon; pokemon.setVisible(false); - loadPokemonAssets.push(pokemon.loadAssets()); + loadPokemonAssets.push(pokemon.loadAssets(false)); party.push(pokemon); } From 9b1a222935a032a65432103c8875c46439b6a3e9 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Mon, 12 May 2025 15:33:52 -0500 Subject: [PATCH 43/61] [Bug] Fix old session load modifier crash (#5814) Fix inability to load saves due to modifier type being nulled --- src/battle-scene.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 9f70b33b296..5835ee08af5 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -2921,7 +2921,10 @@ export default class BattleScene extends SceneBase { instant?: boolean, cost?: number, ): boolean { - if (!modifier) { + // We check against modifier.type to stop a bug related to loading in a pokemon that has a form change item, which prior to some patch + // that changed form change modifiers worked, had previously set the `type` field to null. + // TODO: This is not the right place to check for this; it should ideally go in a session migrator. + if (!modifier || !modifier.type) { return false; } let success = false; From 30ba53894ec6de86e7373803852ed26047db052a Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Mon, 12 May 2025 17:58:28 -0700 Subject: [PATCH 44/61] [i18n] Update locales --- public/locales | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/locales b/public/locales index f4b8b7b737e..ee6bb371afe 160000 --- a/public/locales +++ b/public/locales @@ -1 +1 @@ -Subproject commit f4b8b7b737e47eaf7e7231855d0b59f8c7c7c0f8 +Subproject commit ee6bb371afefe4c6d872cc7765f0e0d26e630d4e From 84192cd3230be998c1e4a1b2620993545144dcc9 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Thu, 15 May 2025 14:51:16 -0700 Subject: [PATCH 45/61] Update version to 1.9.4 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 02a5d375588..66400b14459 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pokemon-rogue-battle", - "version": "1.9.3", + "version": "1.9.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pokemon-rogue-battle", - "version": "1.9.3", + "version": "1.9.4", "hasInstallScript": true, "dependencies": { "@material/material-color-utilities": "^0.2.7", diff --git a/package.json b/package.json index 715deefbe32..7d1ba35154a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "pokemon-rogue-battle", "private": true, - "version": "1.9.3", + "version": "1.9.4", "type": "module", "scripts": { "start": "vite", From 0c48fff14bbca1628134934b1e1b9c4e078d0997 Mon Sep 17 00:00:00 2001 From: Dean <69436131+emdeann@users.noreply.github.com> Date: Sat, 17 May 2025 08:35:38 -0700 Subject: [PATCH 46/61] [Bug] Fix Substitute sprite crash & revived Pokemon softlock (#5829) Break `resetSummonData` into two methods Co-authored-by: damocleas Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> Co-authored-by: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> Co-authored-by: lxy-lxy-lxy <55084073+lxy-lxy-lxy@users.noreply.github.com> Co-authored-by: Xavion3 Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Co-authored-by: Lylian BALL <131535108+PyGaVS@users.noreply.github.com> --- src/field/pokemon.ts | 32 ++++++++++++++++++++----------- src/phases/encounter-phase.ts | 2 +- src/phases/summon-phase.ts | 2 ++ src/phases/switch-summon-phase.ts | 2 +- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index eec20beb01c..983494b36c8 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -5721,17 +5721,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } /** - * Reset this Pokemon's {@linkcode PokemonSummonData | SummonData} and {@linkcode PokemonTempSummonData | TempSummonData} - * in preparation for switching pokemon, as well as removing any relevant on-switch tags. + * Performs miscellaneous setup for when the Pokemon is summoned, like generating the substitute sprite + * @param resetSummonData - Whether to additionally reset the Pokemon's summon data (default: `false`) */ - resetSummonData(): void { - const illusion: IllusionData | null = this.summonData.illusion; - if (this.summonData.speciesForm) { - this.summonData.speciesForm = null; - this.updateFusionPalette(); - } - this.summonData = new PokemonSummonData(); - this.tempSummonData = new PokemonTempSummonData(); + public fieldSetup(resetSummonData?: boolean): void { this.setSwitchOutStatus(false); if (globalScene) { globalScene.triggerPokemonFormChange( @@ -5740,7 +5733,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { true, ); } - // If this Pokemon has a Substitute when loading in, play an animation to add its sprite if (this.getTag(SubstituteTag)) { globalScene.triggerPokemonBattleAnim( @@ -5758,6 +5750,24 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { ) { this.setVisible(false); } + + if (resetSummonData) { + this.resetSummonData(); + } + } + + /** + * Reset this Pokemon's {@linkcode PokemonSummonData | SummonData} and {@linkcode PokemonTempSummonData | TempSummonData} + * in preparation for switching pokemon, as well as removing any relevant on-switch tags. + */ + resetSummonData(): void { + const illusion: IllusionData | null = this.summonData.illusion; + if (this.summonData.speciesForm) { + this.summonData.speciesForm = null; + this.updateFusionPalette(); + } + this.summonData = new PokemonSummonData(); + this.tempSummonData = new PokemonTempSummonData(); this.summonData.illusion = illusion this.updateInfo(); } diff --git a/src/phases/encounter-phase.ts b/src/phases/encounter-phase.ts index 5b799bd9316..3cfd2b9a901 100644 --- a/src/phases/encounter-phase.ts +++ b/src/phases/encounter-phase.ts @@ -146,7 +146,7 @@ export class EncounterPhase extends BattlePhase { const enemyPokemon = globalScene.getEnemyParty()[e]; if (e < (battle.double ? 2 : 1)) { enemyPokemon.setX(-66 + enemyPokemon.getFieldPositionOffset()[0]); - enemyPokemon.resetSummonData(); + enemyPokemon.fieldSetup(true); } if (!this.loaded) { diff --git a/src/phases/summon-phase.ts b/src/phases/summon-phase.ts index fef9b356348..c217583f163 100644 --- a/src/phases/summon-phase.ts +++ b/src/phases/summon-phase.ts @@ -196,6 +196,7 @@ export class SummonPhase extends PartyMemberPokemonPhase { onComplete: () => { pokemon.cry(pokemon.getHpRatio() > 0.25 ? undefined : { rate: 0.85 }); pokemon.getSprite().clearTint(); + pokemon.fieldSetup(); // necessary to stay transformed during wild waves if (pokemon.summonData.speciesForm) { pokemon.loadAssets(false); @@ -261,6 +262,7 @@ export class SummonPhase extends PartyMemberPokemonPhase { onComplete: () => { pokemon.cry(pokemon.getHpRatio() > 0.25 ? undefined : { rate: 0.85 }); pokemon.getSprite().clearTint(); + pokemon.fieldSetup(); globalScene.updateFieldScale(); globalScene.time.delayedCall(1000, () => this.end()); }, diff --git a/src/phases/switch-summon-phase.ts b/src/phases/switch-summon-phase.ts index bb31f87cc3d..a063b6e6863 100644 --- a/src/phases/switch-summon-phase.ts +++ b/src/phases/switch-summon-phase.ts @@ -193,7 +193,7 @@ export class SwitchSummonPhase extends SummonPhase { switchedInPokemon.setAlpha(0.5); } } else { - switchedInPokemon.resetSummonData(); + switchedInPokemon.fieldSetup(true); } this.summon(); }; From 998619e7e565ff06c1624f6b4d22ab444554a037 Mon Sep 17 00:00:00 2001 From: Jimmybald1 <122436263+Jimmybald1@users.noreply.github.com> Date: Sat, 17 May 2025 17:36:16 +0200 Subject: [PATCH 47/61] [Bug] IVs of trainers were incorrectly using the battle seed (#5822) * Fixed IVs of trainers using the Battle Seed. * Renamed the randSeedInt functions that use the Battle Seed to randBattleSeedInt functions * Incorrectly used this in common * Fixed tests that were still calling the old function name --------- Co-authored-by: damocleas Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> Co-authored-by: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> Co-authored-by: Dean <69436131+emdeann@users.noreply.github.com> Co-authored-by: lxy-lxy-lxy <55084073+lxy-lxy-lxy@users.noreply.github.com> Co-authored-by: Xavion3 Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Co-authored-by: Lylian BALL <131535108+PyGaVS@users.noreply.github.com> Co-authored-by: Jimmybald1 <147992650+IBBCalc@users.noreply.github.com> --- src/data/abilities/ability.ts | 36 +- src/data/battler-tags.ts | 8 +- src/data/moves/move.ts | 52 +- src/data/trainers/trainer-config.ts | 693 ++++++++++++++++++------ src/field/pokemon.ts | 16 +- src/modifier/modifier.ts | 14 +- src/phases/attempt-capture-phase.ts | 6 +- src/phases/attempt-run-phase.ts | 2 +- src/phases/move-effect-phase.ts | 2 +- src/phases/move-phase.ts | 4 +- src/utils/common.ts | 10 + test/abilities/cud_chew.test.ts | 2 +- test/abilities/desolate-land.test.ts | 2 +- test/abilities/neutralizing_gas.test.ts | 2 +- test/items/reviver_seed.test.ts | 2 +- test/moves/u_turn.test.ts | 2 +- 16 files changed, 608 insertions(+), 245 deletions(-) diff --git a/src/data/abilities/ability.ts b/src/data/abilities/ability.ts index 4609ff6ec1a..ff86937622b 100644 --- a/src/data/abilities/ability.ts +++ b/src/data/abilities/ability.ts @@ -850,14 +850,14 @@ export class PostDefendContactApplyStatusEffectAbAttr extends PostDefendAbAttr { } override canApplyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult | null, args: any[]): boolean { - const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)]; + const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randBattleSeedInt(this.effects.length)]; return move.doesFlagEffectApply({flag: MoveFlags.MAKES_CONTACT, user: attacker, target: pokemon}) && !attacker.status - && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance) + && (this.chance === -1 || pokemon.randBattleSeedInt(100) < this.chance) && attacker.canSetStatus(effect, true, false, pokemon); } override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): void { - const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)]; + const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randBattleSeedInt(this.effects.length)]; attacker.trySetStatus(effect, true, pokemon); } } @@ -891,7 +891,7 @@ export class PostDefendContactApplyTagChanceAbAttr extends PostDefendAbAttr { } override canApplyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult | null, args: any[]): boolean { - return move.doesFlagEffectApply({flag: MoveFlags.MAKES_CONTACT, user: attacker, target: pokemon}) && pokemon.randSeedInt(100) < this.chance + return move.doesFlagEffectApply({flag: MoveFlags.MAKES_CONTACT, user: attacker, target: pokemon}) && pokemon.randBattleSeedInt(100) < this.chance && attacker.canAddTag(this.tagType); } @@ -1068,7 +1068,7 @@ export class PostDefendMoveDisableAbAttr extends PostDefendAbAttr { override canApplyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult | null, args: any[]): boolean { return attacker.getTag(BattlerTagType.DISABLED) === null - && move.doesFlagEffectApply({flag: MoveFlags.MAKES_CONTACT, user: attacker, target: pokemon}) && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance); + && move.doesFlagEffectApply({flag: MoveFlags.MAKES_CONTACT, user: attacker, target: pokemon}) && (this.chance === -1 || pokemon.randBattleSeedInt(100) < this.chance); } override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): void { @@ -1741,7 +1741,7 @@ export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr { const heldItems = this.getTargetHeldItems(defender).filter((i) => i.isTransferable); if (heldItems.length) { // Ensure that the stolen item in testing is the same as when the effect is applied - this.stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)]; + this.stolenItem = heldItems[pokemon.randBattleSeedInt(heldItems.length)]; if (globalScene.canTransferHeldItemModifier(this.stolenItem, pokemon)) { return true; } @@ -1762,7 +1762,7 @@ export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr { ): void { const heldItems = this.getTargetHeldItems(defender).filter((i) => i.isTransferable); if (!this.stolenItem) { - this.stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)]; + this.stolenItem = heldItems[pokemon.randBattleSeedInt(heldItems.length)]; } if (globalScene.tryTransferHeldItemModifier(this.stolenItem, pokemon, false)) { globalScene.queueMessage( @@ -1799,9 +1799,9 @@ export class PostAttackApplyStatusEffectAbAttr extends PostAttackAbAttr { if ( super.canApplyPostAttack(pokemon, passive, simulated, attacker, move, hitResult, args) && (simulated || !attacker.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr) && pokemon !== attacker - && (!this.contactRequired || move.doesFlagEffectApply({flag: MoveFlags.MAKES_CONTACT, user: attacker, target: pokemon})) && pokemon.randSeedInt(100) < this.chance && !pokemon.status) + && (!this.contactRequired || move.doesFlagEffectApply({flag: MoveFlags.MAKES_CONTACT, user: attacker, target: pokemon})) && pokemon.randBattleSeedInt(100) < this.chance && !pokemon.status) ) { - const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)]; + const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randBattleSeedInt(this.effects.length)]; return simulated || attacker.canSetStatus(effect, true, false, pokemon); } @@ -1809,7 +1809,7 @@ export class PostAttackApplyStatusEffectAbAttr extends PostAttackAbAttr { } applyPostAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): void { - const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)]; + const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randBattleSeedInt(this.effects.length)]; attacker.trySetStatus(effect, true, pokemon); } } @@ -1839,12 +1839,12 @@ export class PostAttackApplyBattlerTagAbAttr extends PostAttackAbAttr { return super.canApplyPostAttack(pokemon, passive, simulated, attacker, move, hitResult, args) && !attacker.hasAbilityWithAttr(IgnoreMoveEffectsAbAttr) && pokemon !== attacker && (!this.contactRequired || move.doesFlagEffectApply({flag: MoveFlags.MAKES_CONTACT, user: attacker, target: pokemon})) && - pokemon.randSeedInt(100) < this.chance(attacker, pokemon, move) && !pokemon.status; + pokemon.randBattleSeedInt(100) < this.chance(attacker, pokemon, move) && !pokemon.status; } override applyPostAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): void { if (!simulated) { - const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)]; + const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randBattleSeedInt(this.effects.length)]; attacker.addTag(effect); } } @@ -1868,7 +1868,7 @@ export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr { ) { const heldItems = this.getTargetHeldItems(attacker).filter((i) => i.isTransferable); if (heldItems.length) { - this.stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)]; + this.stolenItem = heldItems[pokemon.randBattleSeedInt(heldItems.length)]; if (globalScene.canTransferHeldItemModifier(this.stolenItem, pokemon)) { return true; } @@ -1889,7 +1889,7 @@ export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr { const heldItems = this.getTargetHeldItems(attacker).filter((i) => i.isTransferable); if (!this.stolenItem) { - this.stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)]; + this.stolenItem = heldItems[pokemon.randBattleSeedInt(heldItems.length)]; } if (globalScene.tryTransferHeldItemModifier(this.stolenItem, pokemon, false)) { globalScene.queueMessage( @@ -3171,7 +3171,7 @@ export class ConfusionOnStatusEffectAbAttr extends PostAttackAbAttr { */ override applyPostAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, hitResult: HitResult, args: any[]): void { if (!simulated) { - defender.addTag(BattlerTagType.CONFUSED, pokemon.randSeedIntRange(2, 5), move.id, defender.id); + defender.addTag(BattlerTagType.CONFUSED, pokemon.randBattleSeedIntRange(2, 5), move.id, defender.id); } } } @@ -4235,12 +4235,12 @@ export class MoodyAbAttr extends PostTurnAbAttr { if (!simulated) { if (canRaise.length > 0) { - const raisedStat = canRaise[pokemon.randSeedInt(canRaise.length)]; + const raisedStat = canRaise[pokemon.randBattleSeedInt(canRaise.length)]; canLower = canRaise.filter(s => s !== raisedStat); globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ raisedStat ], 2)); } if (canLower.length > 0) { - const loweredStat = canLower[pokemon.randSeedInt(canLower.length)]; + const loweredStat = canLower[pokemon.randBattleSeedInt(canLower.length)]; globalScene.unshiftPhase(new StatStageChangePhase(pokemon.getBattlerIndex(), true, [ loweredStat ], -1)); } } @@ -5349,7 +5349,7 @@ export class BypassSpeedChanceAbAttr extends AbAttr { const isCommandFight = turnCommand?.command === Command.FIGHT; const move = turnCommand?.move?.move ? allMoves[turnCommand.move.move] : null; const isDamageMove = move?.category === MoveCategory.PHYSICAL || move?.category === MoveCategory.SPECIAL; - return !simulated && !bypassSpeed.value && pokemon.randSeedInt(100) < this.chance && isCommandFight && isDamageMove; + return !simulated && !bypassSpeed.value && pokemon.randBattleSeedInt(100) < this.chance && isCommandFight && isDamageMove; } /** diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 8a512f3c16c..34fdd5409c8 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -766,11 +766,11 @@ export class ConfusedTag extends BattlerTag { globalScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION)); // 1/3 chance of hitting self with a 40 base power move - if (pokemon.randSeedInt(3) === 0 || Overrides.CONFUSION_ACTIVATION_OVERRIDE === true) { + if (pokemon.randBattleSeedInt(3) === 0 || Overrides.CONFUSION_ACTIVATION_OVERRIDE === true) { const atk = pokemon.getEffectiveStat(Stat.ATK); const def = pokemon.getEffectiveStat(Stat.DEF); const damage = toDmgValue( - ((((2 * pokemon.level) / 5 + 2) * 40 * atk) / def / 50 + 2) * (pokemon.randSeedIntRange(85, 100) / 100), + ((((2 * pokemon.level) / 5 + 2) * 40 * atk) / def / 50 + 2) * (pokemon.randBattleSeedIntRange(85, 100) / 100), ); // Intentionally don't increment rage fist's hitCount globalScene.queueMessage(i18next.t("battlerTags:confusedLapseHurtItself")); @@ -890,7 +890,7 @@ export class InfatuatedTag extends BattlerTag { ); globalScene.unshiftPhase(new CommonAnimPhase(pokemon.getBattlerIndex(), undefined, CommonAnim.ATTRACT)); - if (pokemon.randSeedInt(2)) { + if (pokemon.randBattleSeedInt(2)) { globalScene.queueMessage( i18next.t("battlerTags:infatuatedLapseImmobilize", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), @@ -1119,7 +1119,7 @@ export class FrenzyTag extends BattlerTag { if (this.turnCount < 2) { // Only add CONFUSED tag if a disruption occurs on the final confusion-inducing turn of FRENZY - pokemon.addTag(BattlerTagType.CONFUSED, pokemon.randSeedIntRange(2, 4)); + pokemon.addTag(BattlerTagType.CONFUSED, pokemon.randBattleSeedIntRange(2, 4)); } } } diff --git a/src/data/moves/move.ts b/src/data/moves/move.ts index 3ef70fd75be..235cb954ea5 100644 --- a/src/data/moves/move.ts +++ b/src/data/moves/move.ts @@ -1591,7 +1591,7 @@ export class RandomLevelDamageAttr extends FixedDamageAttr { } getDamage(user: Pokemon, target: Pokemon, move: Move): number { - return toDmgValue(user.level * (user.randSeedIntRange(50, 150) * 0.01)); + return toDmgValue(user.level * (user.randBattleSeedIntRange(50, 150) * 0.01)); } } @@ -2352,7 +2352,7 @@ export class MultiHitAttr extends MoveAttr { switch (this.multiHitType) { case MultiHitType._2_TO_5: { - const rand = user.randSeedInt(20); + const rand = user.randBattleSeedInt(20); const hitValue = new NumberHolder(rand); applyAbAttrs(MaxMultiHitAbAttr, user, null, false, hitValue); if (hitValue.value >= 13) { @@ -2453,7 +2453,7 @@ export class StatusEffectAttr extends MoveEffectAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const moveChance = this.getMoveChance(user, target, move, this.selfTarget, true); - const statusCheck = moveChance < 0 || moveChance === 100 || user.randSeedInt(100) < moveChance; + const statusCheck = moveChance < 0 || moveChance === 100 || user.randBattleSeedInt(100) < moveChance; const quiet = move.category !== MoveCategory.STATUS; if (statusCheck) { const pokemon = this.selfTarget ? user : target; @@ -2560,7 +2560,7 @@ export class StealHeldItemChanceAttr extends MoveEffectAttr { const poolType = target.isPlayer() ? ModifierPoolType.PLAYER : target.hasTrainer() ? ModifierPoolType.TRAINER : ModifierPoolType.WILD; const highestItemTier = heldItems.map((m) => m.type.getOrInferTier(poolType)).reduce((highestTier, tier) => Math.max(tier!, highestTier), 0); // TODO: is the bang after tier correct? const tierHeldItems = heldItems.filter((m) => m.type.getOrInferTier(poolType) === highestItemTier); - const stolenItem = tierHeldItems[user.randSeedInt(tierHeldItems.length)]; + const stolenItem = tierHeldItems[user.randBattleSeedInt(tierHeldItems.length)]; if (!globalScene.tryTransferHeldItemModifier(stolenItem, user, false)) { return false; } @@ -2636,7 +2636,7 @@ export class RemoveHeldItemAttr extends MoveEffectAttr { return false; } - const removedItem = heldItems[user.randSeedInt(heldItems.length)]; + const removedItem = heldItems[user.randBattleSeedInt(heldItems.length)]; // Decrease item amount and update icon target.loseHeldItem(removedItem); @@ -2697,7 +2697,7 @@ export class EatBerryAttr extends MoveEffectAttr { } // pick a random berry to gobble and check if we preserve it - this.chosenBerry = heldBerries[user.randSeedInt(heldBerries.length)]; + this.chosenBerry = heldBerries[user.randBattleSeedInt(heldBerries.length)]; const preserve = new BooleanHolder(false); // check for berry pouch preservation globalScene.applyModifiers(PreserveBerryModifier, pokemon.isPlayer(), pokemon, preserve); @@ -2774,7 +2774,7 @@ export class StealEatBerryAttr extends EatBerryAttr { } // pick a random berry and eat it - this.chosenBerry = heldBerries[user.randSeedInt(heldBerries.length)]; + this.chosenBerry = heldBerries[user.randBattleSeedInt(heldBerries.length)]; applyPostItemLostAbAttrs(PostItemLostAbAttr, target, false); const message = i18next.t("battle:stealEatBerry", { pokemonName: user.name, targetName: target.name, berryName: this.chosenBerry.type.name }); globalScene.queueMessage(message); @@ -3205,7 +3205,7 @@ export class StatStageChangeAttr extends MoveEffectAttr { } const moveChance = this.getMoveChance(user, target, move, this.selfTarget, true); - if (moveChance < 0 || moveChance === 100 || user.randSeedInt(100) < moveChance) { + if (moveChance < 0 || moveChance === 100 || user.randBattleSeedInt(100) < moveChance) { const stages = this.getLevels(user); globalScene.unshiftPhase(new StatStageChangePhase((this.selfTarget ? user : target).getBattlerIndex(), this.selfTarget, this.stats, stages, this.showMessage)); return true; @@ -3431,7 +3431,7 @@ export class AcupressureStatStageChangeAttr extends MoveEffectAttr { override apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const randStats = BATTLE_STATS.filter((s) => target.getStatStage(s) < 6); if (randStats.length > 0) { - const boostStat = [ randStats[user.randSeedInt(randStats.length)] ]; + const boostStat = [ randStats[user.randBattleSeedInt(randStats.length)] ]; globalScene.unshiftPhase(new StatStageChangePhase(target.getBattlerIndex(), this.selfTarget, boostStat, 2)); return true; } @@ -4823,7 +4823,7 @@ export class ShellSideArmCategoryAttr extends VariableMoveCategoryAttr { if (predictedPhysDmg > predictedSpecDmg) { category.value = MoveCategory.PHYSICAL; return true; - } else if (predictedPhysDmg === predictedSpecDmg && user.randSeedInt(2) === 0) { + } else if (predictedPhysDmg === predictedSpecDmg && user.randBattleSeedInt(2) === 0) { category.value = MoveCategory.PHYSICAL; return true; } @@ -5404,7 +5404,7 @@ export class FrenzyAttr extends MoveEffectAttr { } if (!user.getTag(BattlerTagType.FRENZY) && !user.getMoveQueue().length) { - const turnCount = user.randSeedIntRange(1, 2); + const turnCount = user.randBattleSeedIntRange(1, 2); new Array(turnCount).fill(null).map(() => user.getMoveQueue().push({ move: move.id, targets: [ target.getBattlerIndex() ], ignorePP: true })); user.addTag(BattlerTagType.FRENZY, turnCount, move.id, user.id); } else { @@ -5485,8 +5485,8 @@ export class AddBattlerTagAttr extends MoveEffectAttr { } const moveChance = this.getMoveChance(user, target, move, this.selfTarget, true); - if (moveChance < 0 || moveChance === 100 || user.randSeedInt(100) < moveChance) { - return (this.selfTarget ? user : target).addTag(this.tagType, user.randSeedIntRange(this.turnCountMin, this.turnCountMax), move.id, user.id); + if (moveChance < 0 || moveChance === 100 || user.randBattleSeedInt(100) < moveChance) { + return (this.selfTarget ? user : target).addTag(this.tagType, user.randBattleSeedIntRange(this.turnCountMin, this.turnCountMax), move.id, user.id); } return false; @@ -5654,7 +5654,7 @@ export class JawLockAttr extends AddBattlerTagAttr { } const moveChance = this.getMoveChance(user, target, move, this.selfTarget); - if (moveChance < 0 || moveChance === 100 || user.randSeedInt(100) < moveChance) { + if (moveChance < 0 || moveChance === 100 || user.randBattleSeedInt(100) < moveChance) { /** * Add the tag to both the user and the target. * The target's tag source is considered to be the user and vice versa @@ -5792,7 +5792,7 @@ export class ProtectAttr extends AddBattlerTagAttr { timesUsed++; } if (timesUsed) { - return !user.randSeedInt(Math.pow(3, timesUsed)); + return !user.randBattleSeedInt(Math.pow(3, timesUsed)); } return true; }); @@ -5916,7 +5916,7 @@ export class AddArenaTagAttr extends MoveEffectAttr { return false; } - if ((move.chance < 0 || move.chance === 100 || user.randSeedInt(100) < move.chance) && user.getLastXMoves(1)[0]?.result === MoveResult.SUCCESS) { + if ((move.chance < 0 || move.chance === 100 || user.randBattleSeedInt(100) < move.chance) && user.getLastXMoves(1)[0]?.result === MoveResult.SUCCESS) { const side = ((this.selfSideTarget ? user : target).isPlayer() !== (move.hasAttr(AddArenaTrapTagAttr) && target === user)) ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; globalScene.arena.addTag(this.tagType, this.turnCount, move.id, user.id, side); return true; @@ -5992,7 +5992,7 @@ export class AddArenaTrapTagHitAttr extends AddArenaTagAttr { const moveChance = this.getMoveChance(user, target, move, this.selfTarget, true); const side = (this.selfSideTarget ? user : target).isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; const tag = globalScene.arena.getTagOnSide(this.tagType, side) as ArenaTrapTag; - if ((moveChance < 0 || moveChance === 100 || user.randSeedInt(100) < moveChance) && user.getLastXMoves(1)[0]?.result === MoveResult.SUCCESS) { + if ((moveChance < 0 || moveChance === 100 || user.randBattleSeedInt(100) < moveChance) && user.getLastXMoves(1)[0]?.result === MoveResult.SUCCESS) { globalScene.arena.addTag(this.tagType, 0, move.id, user.id, side); if (!tag) { return true; @@ -6167,7 +6167,7 @@ export class RevivalBlessingAttr extends MoveEffectAttr { // If used by an enemy trainer with at least one fainted non-boss Pokemon, this // revives one of said Pokemon selected at random. const faintedPokemon = globalScene.getEnemyParty().filter((p) => p.isFainted() && !p.isBoss()); - const pokemon = faintedPokemon[user.randSeedInt(faintedPokemon.length)]; + const pokemon = faintedPokemon[user.randBattleSeedInt(faintedPokemon.length)]; const slotIndex = globalScene.getEnemyParty().findIndex((p) => pokemon.id === p.id); pokemon.resetStatus(true, false, false, true); pokemon.heal(Math.min(toDmgValue(0.5 * pokemon.getMaxHp()), pokemon.getMaxHp())); @@ -6263,7 +6263,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { if (switchOutTarget.hp > 0) { if (this.switchType === SwitchType.FORCE_SWITCH) { switchOutTarget.leaveField(true); - const slotIndex = eligibleNewIndices[user.randSeedInt(eligibleNewIndices.length)]; + const slotIndex = eligibleNewIndices[user.randBattleSeedInt(eligibleNewIndices.length)]; globalScene.prependToPhase( new SwitchSummonPhase( this.switchType, @@ -6306,7 +6306,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { if (switchOutTarget.hp > 0) { if (this.switchType === SwitchType.FORCE_SWITCH) { switchOutTarget.leaveField(true); - const slotIndex = eligibleNewIndices[user.randSeedInt(eligibleNewIndices.length)]; + const slotIndex = eligibleNewIndices[user.randBattleSeedInt(eligibleNewIndices.length)]; globalScene.prependToPhase( new SwitchSummonPhase( this.switchType, @@ -6725,7 +6725,7 @@ class CallMoveAttr extends OverrideMoveEffectAttr { } const targets = moveTargets.multiple || moveTargets.targets.length === 1 ? moveTargets.targets - : [ this.hasTarget ? target.getBattlerIndex() : moveTargets.targets[user.randSeedInt(moveTargets.targets.length)] ]; // account for Mirror Move having a target already + : [ this.hasTarget ? target.getBattlerIndex() : moveTargets.targets[user.randBattleSeedInt(moveTargets.targets.length)] ]; // account for Mirror Move having a target already user.getMoveQueue().push({ move: move.id, targets: targets, virtual: true, ignorePP: true }); globalScene.unshiftPhase(new LoadMoveAnimPhase(move.id)); globalScene.unshiftPhase(new MovePhase(user, targets, new PokemonMove(move.id, 0, 0, true), true, true)); @@ -6765,7 +6765,7 @@ export class RandomMoveAttr extends CallMoveAttr { const moveIds = getEnumValues(Moves).map(m => !this.invalidMoves.has(m) && !allMoves[m].name.endsWith(" (N)") ? m : Moves.NONE); let moveId: Moves = Moves.NONE; do { - moveId = this.getMoveOverride() ?? moveIds[user.randSeedInt(moveIds.length)]; + moveId = this.getMoveOverride() ?? moveIds[user.randBattleSeedInt(moveIds.length)]; } while (moveId === Moves.NONE); return super.apply(user, target, allMoves[moveId], args); @@ -6817,7 +6817,7 @@ export class RandomMovesetMoveAttr extends CallMoveAttr { return false; } - this.moveId = moves[user.randSeedInt(moves.length)]!.moveId; + this.moveId = moves[user.randBattleSeedInt(moves.length)]!.moveId; return true; }; } @@ -7900,7 +7900,7 @@ const phaseForcedSlower = (phase: MovePhase, target: Pokemon, trickRoom: boolean let slower: boolean; // quashed pokemon still have speed ties if (phase.pokemon.getEffectiveStat(Stat.SPD) === target.getEffectiveStat(Stat.SPD)) { - slower = !!target.randSeedInt(2); + slower = !!target.randBattleSeedInt(2); } else { slower = !trickRoom ? phase.pokemon.getEffectiveStat(Stat.SPD) < target.getEffectiveStat(Stat.SPD) : phase.pokemon.getEffectiveStat(Stat.SPD) > target.getEffectiveStat(Stat.SPD); } @@ -8103,7 +8103,7 @@ export class ResistLastMoveTypeAttr extends MoveEffectAttr { if (!validTypes.length) { return false; } - const type = validTypes[user.randSeedInt(validTypes.length)]; + const type = validTypes[user.randBattleSeedInt(validTypes.length)]; user.summonData.types = [ type ]; globalScene.queueMessage(i18next.t("battle:transformedIntoType", { pokemonName: getPokemonNameWithAffix(user), type: toReadableString(PokemonType[type]) })); user.updateInfo(); @@ -8218,7 +8218,7 @@ export function getMoveTargets(user: Pokemon, move: Moves, replaceTarget?: MoveT multiple = moveTarget !== MoveTarget.NEAR_ENEMY; break; case MoveTarget.RANDOM_NEAR_ENEMY: - set = [ opponents[user.randSeedInt(opponents.length)] ]; + set = [ opponents[user.randBattleSeedInt(opponents.length)] ]; break; case MoveTarget.ATTACKER: return { targets: [ -1 as BattlerIndex ], multiple: false }; diff --git a/src/data/trainers/trainer-config.ts b/src/data/trainers/trainer-config.ts index 50acf84efa6..839a1cdc0cc 100644 --- a/src/data/trainers/trainer-config.ts +++ b/src/data/trainers/trainer-config.ts @@ -1,7 +1,7 @@ import { globalScene } from "#app/global-scene"; import { modifierTypes } from "#app/modifier/modifier-type"; import { PokemonMove } from "#app/field/pokemon"; -import { toReadableString, isNullOrUndefined, randSeedItem, randSeedInt } from "#app/utils/common"; +import { toReadableString, isNullOrUndefined, randSeedItem, randSeedInt, randSeedIntRange } from "#app/utils/common"; import { pokemonEvolutions, pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions"; import { getPokemonSpecies } from "#app/data/pokemon-species"; import { tmSpecies } from "#app/data/balance/tms"; @@ -2856,21 +2856,29 @@ export const trainerConfigs: TrainerConfigs = { .initForEliteFour(signatureSpecies["LORELEI"], false, PokemonType.ICE, 2) .setBattleBgm("battle_kanto_gym") .setMixedBattleBgm("battle_kanto_gym") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.DEWGONG], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 0, + getRandomPartyMemberFunc([Species.DEWGONG], TrainerSlot.TRAINER, true, p => { p.abilityIndex = 0; // Thick Fat p.generateAndPopulateMoveset(); }), ) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.SLOWBRO, Species.GALAR_SLOWBRO], TrainerSlot.TRAINER, true, p => { // Tera Ice Slowbro/G-Slowbro + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.SLOWBRO, Species.GALAR_SLOWBRO], TrainerSlot.TRAINER, true, p => { + // Tera Ice Slowbro/G-Slowbro p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.ICE_BEAM)) { // Check if Ice Beam is in the moveset, if not, replace the third move with Ice Beam. + if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.ICE_BEAM)) { + // Check if Ice Beam is in the moveset, if not, replace the third move with Ice Beam. p.moveset[2] = new PokemonMove(Moves.ICE_BEAM); } }), ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.JYNX])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.CLOYSTER, Species.ALOLA_SANDSLASH])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.LAPRAS], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.LAPRAS], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -2880,9 +2888,13 @@ export const trainerConfigs: TrainerConfigs = { .setBattleBgm("battle_kanto_gym") .setMixedBattleBgm("battle_kanto_gym") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.HITMONLEE, Species.HITMONCHAN, Species.HITMONTOP])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.STEELIX], TrainerSlot.TRAINER, true, p => { // Tera Fighting Steelix + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.STEELIX], TrainerSlot.TRAINER, true, p => { + // Tera Fighting Steelix p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.BODY_PRESS)) { // Check if Body Press is in the moveset, if not, replace the third move with Body Press. + if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.BODY_PRESS)) { + // Check if Body Press is in the moveset, if not, replace the third move with Body Press. p.moveset[2] = new PokemonMove(Moves.BODY_PRESS); } }), @@ -2901,16 +2913,22 @@ export const trainerConfigs: TrainerConfigs = { .setBattleBgm("battle_kanto_gym") .setMixedBattleBgm("battle_kanto_gym") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.MISMAGIUS])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.ARBOK, Species.WEEZING], TrainerSlot.TRAINER, true, p => { // Tera Ghost Arbok/Weezing + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.ARBOK, Species.WEEZING], TrainerSlot.TRAINER, true, p => { + // Tera Ghost Arbok/Weezing p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. + if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { + // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. p.moveset[2] = new PokemonMove(Moves.TERA_BLAST); } }), ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.ALOLA_MAROWAK])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.CURSOLA])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.GENGAR], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.GENGAR], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -2921,16 +2939,22 @@ export const trainerConfigs: TrainerConfigs = { .setBattleBgm("battle_kanto_gym") .setMixedBattleBgm("battle_kanto_gym") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.KINGDRA])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.GYARADOS, Species.AERODACTYL], TrainerSlot.TRAINER, true, p => { // Tera Dragon Gyarados/Aerodactyl + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.GYARADOS, Species.AERODACTYL], TrainerSlot.TRAINER, true, p => { + // Tera Dragon Gyarados/Aerodactyl p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. + if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { + // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. p.moveset[2] = new PokemonMove(Moves.TERA_BLAST); } }), ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.ALOLA_EXEGGUTOR])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.SALAMENCE])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.DRAGONITE], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.DRAGONITE], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -2943,7 +2967,9 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.SLOWKING, Species.GALAR_SLOWKING])) // Tera Psychic Slowking/G-Slowking .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.EXEGGUTOR])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.WYRDEER, Species.FARIGIRAF])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.XATU], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.XATU], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -2952,7 +2978,9 @@ export const trainerConfigs: TrainerConfigs = { .initForEliteFour(signatureSpecies["KOGA"], true, PokemonType.POISON, 2) .setBattleBgm("battle_johto_gym") .setMixedBattleBgm("battle_johto_gym") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.VENOMOTH], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 0, + getRandomPartyMemberFunc([Species.VENOMOTH], TrainerSlot.TRAINER, true, p => { p.abilityIndex = 1; // Tinted Lens p.generateAndPopulateMoveset(); }), @@ -2960,7 +2988,9 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.MUK, Species.WEEZING])) // Tera Poison Muk/Weezing .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.TENTACRUEL])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.SNEASLER, Species.OVERQWIL])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.CROBAT], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.CROBAT], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -2970,16 +3000,22 @@ export const trainerConfigs: TrainerConfigs = { .setBattleBgm("battle_johto_gym") .setMixedBattleBgm("battle_johto_gym") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.UMBREON])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.GENGAR], TrainerSlot.TRAINER, true, p => { // Tera Dark Gengar + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.GENGAR], TrainerSlot.TRAINER, true, p => { + // Tera Dark Gengar p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.DARK_PULSE)) { // Check if Dark Pulse is in the moveset, if not, replace the third move with Dark Pulse. + if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.DARK_PULSE)) { + // Check if Dark Pulse is in the moveset, if not, replace the third move with Dark Pulse. p.moveset[2] = new PokemonMove(Moves.DARK_PULSE); } }), ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.HONCHKROW])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.WEAVILE])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.HOUNDOOM], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.HOUNDOOM], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -2987,7 +3023,9 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.SIDNEY]: new TrainerConfig(++t) .initForEliteFour(signatureSpecies["SIDNEY"], true, PokemonType.DARK, 2) .setMixedBattleBgm("battle_hoenn_elite") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.MIGHTYENA], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 0, + getRandomPartyMemberFunc([Species.MIGHTYENA], TrainerSlot.TRAINER, true, p => { p.abilityIndex = 0; // Intimidate p.generateAndPopulateMoveset(); }), @@ -3008,12 +3046,16 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.SABLEYE])) .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.BANETTE])) // Tera Ghost Banette .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.DRIFBLIM, Species.MISMAGIUS])) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.ORICORIO, Species.ALOLA_MAROWAK], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 4, + getRandomPartyMemberFunc([Species.ORICORIO, Species.ALOLA_MAROWAK], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.formIndex = p.species.speciesId === Species.ORICORIO ? 3 : 0; // Oricorio-Sensu }), ) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.DUSKNOIR], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.DUSKNOIR], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3021,7 +3063,9 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.GLACIA]: new TrainerConfig(++t) .initForEliteFour(signatureSpecies["GLACIA"], false, PokemonType.ICE, 2) .setMixedBattleBgm("battle_hoenn_elite") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.ABOMASNOW], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 0, + getRandomPartyMemberFunc([Species.ABOMASNOW], TrainerSlot.TRAINER, true, p => { p.abilityIndex = 0; // Snow Warning p.generateAndPopulateMoveset(); }), @@ -3029,7 +3073,9 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.GLALIE])) // Tera Ice Glalie .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.FROSLASS])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.ALOLA_NINETALES])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.WALREIN], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.WALREIN], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3038,16 +3084,22 @@ export const trainerConfigs: TrainerConfigs = { .initForEliteFour(signatureSpecies["DRAKE"], true, PokemonType.DRAGON, 2) .setMixedBattleBgm("battle_hoenn_elite") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.ALTARIA])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.DHELMISE], TrainerSlot.TRAINER, true, p => { // Tera Dragon Dhelmise + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.DHELMISE], TrainerSlot.TRAINER, true, p => { + // Tera Dragon Dhelmise p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. + if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { + // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. p.moveset[2] = new PokemonMove(Moves.TERA_BLAST); } }), ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.FLYGON])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.KINGDRA])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.SALAMENCE], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.SALAMENCE], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3060,11 +3112,15 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.HERACROSS])) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.VESPIQUEN])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.SCIZOR, Species.KLEAVOR])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.DRAPION], TrainerSlot.TRAINER, true, p => { // Tera Bug Drapion + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.DRAPION], TrainerSlot.TRAINER, true, p => { + // Tera Bug Drapion p.setBoss(true, 2); p.abilityIndex = 1; // Sniper p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.X_SCISSOR)) { // Check if X-Scissor is in the moveset, if not, replace the third move with X-Scissor. + if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.X_SCISSOR)) { + // Check if X-Scissor is in the moveset, if not, replace the third move with X-Scissor. p.moveset[2] = new PokemonMove(Moves.X_SCISSOR); } }), @@ -3074,14 +3130,19 @@ export const trainerConfigs: TrainerConfigs = { .setBattleBgm("battle_sinnoh_gym") .setMixedBattleBgm("battle_sinnoh_gym") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.WHISCASH])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.HIPPOWDON], TrainerSlot.TRAINER, true, p => { // Tera Ground Hippowdon + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.HIPPOWDON], TrainerSlot.TRAINER, true, p => { + // Tera Ground Hippowdon p.abilityIndex = 0; // Sand Stream p.generateAndPopulateMoveset(); }), ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.GLISCOR])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.MAMOSWINE, Species.URSALUNA])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.RHYPERIOR], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.RHYPERIOR], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.abilityIndex = 1; // Solid Rock p.generateAndPopulateMoveset(); @@ -3092,16 +3153,22 @@ export const trainerConfigs: TrainerConfigs = { .setBattleBgm("battle_sinnoh_gym") .setMixedBattleBgm("battle_sinnoh_gym") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.RAPIDASH])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.STEELIX, Species.LOPUNNY], TrainerSlot.TRAINER, true, p => { // Tera Fire Steelix/Lopunny + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.STEELIX, Species.LOPUNNY], TrainerSlot.TRAINER, true, p => { + // Tera Fire Steelix/Lopunny p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. + if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { + // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. p.moveset[2] = new PokemonMove(Moves.TERA_BLAST); } }), ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.INFERNAPE])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.ARCANINE, Species.HISUI_ARCANINE])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.MAGMORTAR], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.MAGMORTAR], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3114,7 +3181,9 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.FARIGIRAF])) // Tera Psychic Farigiraf .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.BRONZONG])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.MR_RIME, Species.HISUI_BRAVIARY])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.GALLADE], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.GALLADE], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.abilityIndex = 1; // Sharpness p.generateAndPopulateMoveset(); @@ -3126,8 +3195,10 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.COFAGRIGUS])) .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.GOLURK])) // Tera Ghost Golurk .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.JELLICENT])) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.MISMAGIUS, Species.FROSLASS ])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.CHANDELURE], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.MISMAGIUS, Species.FROSLASS])) + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.CHANDELURE], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3139,7 +3210,9 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.MIENSHAO])) // Tera Fighting Mienshao .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.EMBOAR])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.BRELOOM, Species.TOXICROAK])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.CONKELDURR], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.CONKELDURR], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3151,7 +3224,9 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.KROOKODILE])) // Tera Dark Krookodile .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.SCRAFTY])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.ZOROARK, Species.HISUI_SAMUROTT])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.KINGAMBIT], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.KINGAMBIT], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3161,7 +3236,9 @@ export const trainerConfigs: TrainerConfigs = { .setMixedBattleBgm("battle_unova_elite") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.MUSHARNA])) .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.REUNICLUS])) // Tera Psychic Reuniclus - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.GALLADE], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 3, + getRandomPartyMemberFunc([Species.GALLADE], TrainerSlot.TRAINER, true, p => { p.abilityIndex = 1; // Sharpness p.generateAndPopulateMoveset(); }), @@ -3177,19 +3254,25 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.MALVA]: new TrainerConfig(++t) .initForEliteFour(signatureSpecies["MALVA"], false, PokemonType.FIRE, 2) .setMixedBattleBgm("battle_kalos_elite") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.PYROAR], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 0, + getRandomPartyMemberFunc([Species.PYROAR], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.gender = Gender.FEMALE; }), ) .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.HOUNDOOM])) // Tera Fire Houndoom - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.TORKOAL], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 3, + getRandomPartyMemberFunc([Species.TORKOAL], TrainerSlot.TRAINER, true, p => { p.abilityIndex = 1; // Drought p.generateAndPopulateMoveset(); }), ) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.CHANDELURE, Species.DELPHOX])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.TALONFLAME], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.TALONFLAME], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3201,7 +3284,9 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.GYARADOS])) // Tera Water Gyarados .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.STARMIE])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.BLASTOISE, Species.DONDOZO])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.BARBARACLE], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.BARBARACLE], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.abilityIndex = 1; // Tough Claws p.generateAndPopulateMoveset(); @@ -3211,16 +3296,22 @@ export const trainerConfigs: TrainerConfigs = { .initForEliteFour(signatureSpecies["WIKSTROM"], true, PokemonType.STEEL, 2) .setMixedBattleBgm("battle_kalos_elite") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.KLEFKI])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.CERULEDGE], TrainerSlot.TRAINER, true, p => { // Tera Steel Ceruledge + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.CERULEDGE], TrainerSlot.TRAINER, true, p => { + // Tera Steel Ceruledge p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.IRON_HEAD)) { // Check if Iron Head is in the moveset, if not, replace the third move with Iron Head. + if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.IRON_HEAD)) { + // Check if Iron Head is in the moveset, if not, replace the third move with Iron Head. p.moveset[2] = new PokemonMove(Moves.IRON_HEAD); } }), ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.SCIZOR])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.CORVIKNIGHT])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.AEGISLASH], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.AEGISLASH], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3232,7 +3323,9 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.GARCHOMP])) // Tera Dragon Garchomp .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.ALTARIA])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.DRUDDIGON])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.NOIVERN], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.NOIVERN], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3241,16 +3334,22 @@ export const trainerConfigs: TrainerConfigs = { .initForEliteFour(signatureSpecies["HALA"], true, PokemonType.FIGHTING, 2) .setMixedBattleBgm("battle_alola_elite") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.HARIYAMA])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.INCINEROAR], TrainerSlot.TRAINER, true, p => { // Tera Fighting Incineroar + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.INCINEROAR], TrainerSlot.TRAINER, true, p => { + // Tera Fighting Incineroar p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.CROSS_CHOP)) { // Check if Cross Chop is in the moveset, if not, replace the third move with Cross Chop. + if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.CROSS_CHOP)) { + // Check if Cross Chop is in the moveset, if not, replace the third move with Cross Chop. p.moveset[2] = new PokemonMove(Moves.CROSS_CHOP); } }), ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.BEWEAR])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.POLIWRATH, Species.ANNIHILAPE])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.CRABOMINABLE], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.CRABOMINABLE], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3262,7 +3361,9 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.ALOLA_SANDSLASH])) // Tera Steel A-Sandslash .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.MAGNEZONE])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.METAGROSS, Species.KINGAMBIT])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.ALOLA_DUGTRIO], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.ALOLA_DUGTRIO], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3270,7 +3371,9 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.OLIVIA]: new TrainerConfig(++t) .initForEliteFour(signatureSpecies["OLIVIA"], false, PokemonType.ROCK, 2) .setMixedBattleBgm("battle_alola_elite") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.GIGALITH], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 0, + getRandomPartyMemberFunc([Species.GIGALITH], TrainerSlot.TRAINER, true, p => { p.abilityIndex = 1; // Sand Stream p.generateAndPopulateMoveset(); }), @@ -3278,7 +3381,9 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.PROBOPASS])) // Tera Rock Probopass .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.ALOLA_GOLEM])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.RELICANTH, Species.CARBINK])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.LYCANROC], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.LYCANROC], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.formIndex = 1; p.generateAndPopulateMoveset(); @@ -3291,7 +3396,9 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.MIMIKYU])) // Tera Ghost Mimikyu .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.DHELMISE])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.FROSLASS])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.PALOSSAND], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.PALOSSAND], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3300,16 +3407,22 @@ export const trainerConfigs: TrainerConfigs = { .initForEliteFour(signatureSpecies["KAHILI"], false, PokemonType.FLYING, 2) .setMixedBattleBgm("battle_alola_elite") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.HAWLUCHA])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.DECIDUEYE], TrainerSlot.TRAINER, true, p => { // Tera Flying Decidueye + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.DECIDUEYE], TrainerSlot.TRAINER, true, p => { + // Tera Flying Decidueye p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.BRAVE_BIRD)) { // Check if Brave Bird is in the moveset, if not, replace the third move with Brave Bird. + if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.BRAVE_BIRD)) { + // Check if Brave Bird is in the moveset, if not, replace the third move with Brave Bird. p.moveset[2] = new PokemonMove(Moves.BRAVE_BIRD); } }), ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.BRAVIARY, Species.MANDIBUZZ])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.ORICORIO])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.TOUCANNON], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.TOUCANNON], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3319,7 +3432,10 @@ export const trainerConfigs: TrainerConfigs = { .initForEliteFour(signatureSpecies["MARNIE_ELITE"], false, PokemonType.DARK, 2) .setMixedBattleBgm("battle_galar_elite") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.LIEPARD])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.TOXICROAK], TrainerSlot.TRAINER, true, p => { // Tera Dark Toxicroak + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.TOXICROAK], TrainerSlot.TRAINER, true, p => { + // Tera Dark Toxicroak p.generateAndPopulateMoveset(); if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.SUCKER_PUNCH)) { // Check if Sucker Punch is in the moveset, if not, replace the third move with Sucker Punch. @@ -3329,7 +3445,9 @@ export const trainerConfigs: TrainerConfigs = { ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.SCRAFTY, Species.PANGORO])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.MORPEKO])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.GRIMMSNARL], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.GRIMMSNARL], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3339,20 +3457,28 @@ export const trainerConfigs: TrainerConfigs = { .initForEliteFour(signatureSpecies["NESSA_ELITE"], false, PokemonType.WATER, 2) .setMixedBattleBgm("battle_galar_elite") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.GOLISOPOD])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.EISCUE], TrainerSlot.TRAINER, true, p => { // Tera Water Eiscue + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.EISCUE], TrainerSlot.TRAINER, true, p => { + // Tera Water Eiscue p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.LIQUIDATION)) { // Check if Liquidation is in the moveset, if not, replace the third move with Liquidation. + if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.LIQUIDATION)) { + // Check if Liquidation is in the moveset, if not, replace the third move with Liquidation. p.moveset[2] = new PokemonMove(Moves.LIQUIDATION); } }), ) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.PELIPPER], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 3, + getRandomPartyMemberFunc([Species.PELIPPER], TrainerSlot.TRAINER, true, p => { p.abilityIndex = 1; // Drizzle p.generateAndPopulateMoveset(); }), ) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.TOXAPEX])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.DREDNAW], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.DREDNAW], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3365,7 +3491,9 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.SIRFETCHD])) // Tera Fighting Sirfetch'd .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.GRAPPLOCT, Species.FALINKS])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.HITMONTOP])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.MACHAMP], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.MACHAMP], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3378,7 +3506,9 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.RUNERIGUS])) // Tera Ghost Runerigus .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.POLTEAGEIST, Species.SINISTCHA])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.CURSOLA])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.GENGAR], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.GENGAR], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3388,17 +3518,23 @@ export const trainerConfigs: TrainerConfigs = { .initForEliteFour(signatureSpecies["RAIHAN_ELITE"], true, PokemonType.DRAGON, 2) .setMixedBattleBgm("battle_galar_elite") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.FLYGON])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.TORKOAL], TrainerSlot.TRAINER, true, p => { // Tera Dragon Torkoal + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.TORKOAL], TrainerSlot.TRAINER, true, p => { + // Tera Dragon Torkoal p.abilityIndex = 1; // Drought p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. + if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { + // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. p.moveset[2] = new PokemonMove(Moves.TERA_BLAST); } }), ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.GOODRA])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.TURTONATOR])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.ARCHALUDON], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.ARCHALUDON], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3410,7 +3546,10 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.DONPHAN])) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.SWAMPERT, Species.TORTERRA])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.CAMERUPT])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.CLODSIRE], TrainerSlot.TRAINER, true, p => { // Tera Ground Clodsire + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.CLODSIRE], TrainerSlot.TRAINER, true, p => { + // Tera Ground Clodsire p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3420,13 +3559,18 @@ export const trainerConfigs: TrainerConfigs = { .setMixedBattleBgm("battle_paldea_elite") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.COPPERAJAH])) .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.MAGNEZONE])) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.BRONZONG, Species.CORVIKNIGHT], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 3, + getRandomPartyMemberFunc([Species.BRONZONG, Species.CORVIKNIGHT], TrainerSlot.TRAINER, true, p => { p.abilityIndex = p.species.speciesId === Species.BRONZONG ? 0 : 1; // Levitate Bronzong, Unnerve Corviknight p.generateAndPopulateMoveset(); }), ) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.STEELIX])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.TINKATON], TrainerSlot.TRAINER, true, p => { // Tera Steel Tinkaton + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.TINKATON], TrainerSlot.TRAINER, true, p => { + // Tera Steel Tinkaton p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3439,7 +3583,10 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.BOMBIRDIER])) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.TROPIUS])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.STARAPTOR])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.FLAMIGO], TrainerSlot.TRAINER, true, p => { // Tera Flying Flamigo + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.FLAMIGO], TrainerSlot.TRAINER, true, p => { + // Tera Flying Flamigo p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3451,7 +3598,10 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.DRAGALGE])) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.FLAPPLE, Species.APPLETUN, Species.HYDRAPPLE])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.HAXORUS])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.BAXCALIBUR], TrainerSlot.TRAINER, true, p => { // Tera Dragon Baxcalibur + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.BAXCALIBUR], TrainerSlot.TRAINER, true, p => { + // Tera Dragon Baxcalibur p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3459,27 +3609,38 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.CRISPIN]: new TrainerConfig(++t) .initForEliteFour(signatureSpecies["CRISPIN"], true, PokemonType.FIRE, 2) .setMixedBattleBgm("battle_bb_elite") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.ROTOM], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 0, + getRandomPartyMemberFunc([Species.ROTOM], TrainerSlot.TRAINER, true, p => { p.formIndex = 1; // Heat Rotom p.generateAndPopulateMoveset(); }), ) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.EXEGGUTOR], TrainerSlot.TRAINER, true, p => { // Tera Fire Exeggutor + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.EXEGGUTOR], TrainerSlot.TRAINER, true, p => { + // Tera Fire Exeggutor p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. + if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { + // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. p.moveset[2] = new PokemonMove(Moves.TERA_BLAST); } }), ) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.TALONFLAME], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 3, + getRandomPartyMemberFunc([Species.TALONFLAME], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.SUNNY_DAY)) { // Check if Sunny Day is in the moveset, if not, replace the third move with Sunny Day. + if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.SUNNY_DAY)) { + // Check if Sunny Day is in the moveset, if not, replace the third move with Sunny Day. p.moveset[2] = new PokemonMove(Moves.SUNNY_DAY); } }), ) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.MAGMORTAR])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.BLAZIKEN], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.BLAZIKEN], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3488,16 +3649,22 @@ export const trainerConfigs: TrainerConfigs = { .initForEliteFour(signatureSpecies["AMARYS"], false, PokemonType.STEEL, 2) .setMixedBattleBgm("battle_bb_elite") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.SKARMORY])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.REUNICLUS], TrainerSlot.TRAINER, true, p => { // Tera Steel Reuniclus + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.REUNICLUS], TrainerSlot.TRAINER, true, p => { + // Tera Steel Reuniclus p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.FLASH_CANNON)) { // Check if Flash Cannon is in the moveset, if not, replace the third move with Flash Cannon. + if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.FLASH_CANNON)) { + // Check if Flash Cannon is in the moveset, if not, replace the third move with Flash Cannon. p.moveset[2] = new PokemonMove(Moves.FLASH_CANNON); } }), ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.EMPOLEON])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.SCIZOR])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.METAGROSS], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.METAGROSS], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3509,10 +3676,14 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.PRIMARINA])) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.GRANBULL])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.ALCREMIE])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.EXCADRILL], TrainerSlot.TRAINER, true, p => { // Tera Fairy Excadrill + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.EXCADRILL], TrainerSlot.TRAINER, true, p => { + // Tera Fairy Excadrill p.setBoss(true, 2); p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. + if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { + // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. p.moveset[2] = new PokemonMove(Moves.TERA_BLAST); } }), @@ -3521,16 +3692,22 @@ export const trainerConfigs: TrainerConfigs = { .initForEliteFour(signatureSpecies["DRAYTON"], true, PokemonType.DRAGON, 2) .setMixedBattleBgm("battle_bb_elite") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.DRAGONITE])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.SCEPTILE], TrainerSlot.TRAINER, true, p => { // Tera Dragon Sceptile + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.SCEPTILE], TrainerSlot.TRAINER, true, p => { + // Tera Dragon Sceptile p.generateAndPopulateMoveset(); - if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.DUAL_CHOP)) { // Check if Dual Chop is in the moveset, if not, replace the third move with Dual Chop. + if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.DUAL_CHOP)) { + // Check if Dual Chop is in the moveset, if not, replace the third move with Dual Chop. p.moveset[2] = new PokemonMove(Moves.DUAL_CHOP); } }), ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.HAXORUS])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.KINGDRA, Species.DRACOVISH])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.ARCHALUDON], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.ARCHALUDON], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); }), @@ -3545,18 +3722,29 @@ export const trainerConfigs: TrainerConfigs = { .setDoubleTitle("champion_double") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.ALAKAZAM])) .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.MACHAMP])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.HO_OH], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.HO_OH], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; }), ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.RHYPERIOR, Species.ELECTIVIRE])) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.ARCANINE, Species.EXEGGUTOR, Species.GYARADOS], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 4, + getRandomPartyMemberFunc( + [Species.ARCANINE, Species.EXEGGUTOR, Species.GYARADOS], + TrainerSlot.TRAINER, + true, + p => { p.generateAndPopulateMoveset(); p.setBoss(true, 2); - }), + }, + ), ) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.PIDGEOT], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.PIDGEOT], TrainerSlot.TRAINER, true, p => { p.formIndex = 1; // Mega Pidgeot p.generateAndPopulateMoveset(); p.generateName(); @@ -3571,7 +3759,9 @@ export const trainerConfigs: TrainerConfigs = { .setHasDouble("red_blue_double") .setDoubleTrainerType(TrainerType.BLUE) .setDoubleTitle("champion_double") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.PIKACHU], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 0, + getRandomPartyMemberFunc([Species.PIKACHU], TrainerSlot.TRAINER, true, p => { p.formIndex = 8; // G-Max Pikachu p.generateAndPopulateMoveset(); p.generateName(); @@ -3579,24 +3769,34 @@ export const trainerConfigs: TrainerConfigs = { }), ) .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.ESPEON, Species.UMBREON, Species.SYLVEON])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.LUGIA], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.LUGIA], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; }), ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR])) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.SNORLAX], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 4, + getRandomPartyMemberFunc([Species.SNORLAX], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.setBoss(true, 2); }), ) - .setPartyMemberFunc(5, getRandomPartyMemberFunc( - [Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc( + [Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE], + TrainerSlot.TRAINER, + true, + p => { p.formIndex = 1; // Mega Venusaur, Mega Charizard X, or Mega Blastoise p.generateAndPopulateMoveset(); p.generateName(); p.gender = Gender.MALE; - }), + }, + ), ) .setInstantTera(3), // Tera Grass Meganium / Fire Typhlosion / Water Feraligatr [TrainerType.LANCE_CHAMPION]: new TrainerConfig(++t) @@ -3606,20 +3806,26 @@ export const trainerConfigs: TrainerConfigs = { .setMixedBattleBgm("battle_johto_champion") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.GYARADOS, Species.KINGDRA])) .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.AERODACTYL])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.SALAMENCE], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.SALAMENCE], TrainerSlot.TRAINER, true, p => { p.formIndex = 1; // Mega Salamence p.generateAndPopulateMoveset(); p.generateName(); }), ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.CHARIZARD])) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.TYRANITAR, Species.GARCHOMP, Species.KOMMO_O], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 4, + getRandomPartyMemberFunc([Species.TYRANITAR, Species.GARCHOMP, Species.KOMMO_O], TrainerSlot.TRAINER, true, p => { p.teraType = PokemonType.DRAGON; p.generateAndPopulateMoveset(); p.abilityIndex = p.species.speciesId === Species.KOMMO_O ? 1 : 2; // Soundproof Kommo-o, Unnerve Tyranitar, Rough Skin Garchomp }), ) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.DRAGONITE], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.DRAGONITE], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.gender = Gender.MALE; p.setBoss(true, 2); @@ -3635,18 +3841,24 @@ export const trainerConfigs: TrainerConfigs = { .setDoubleTitle("champion_double") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.SKARMORY])) .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.CRADILY, Species.ARMALDO])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.AGGRON], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.AGGRON], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.setBoss(true, 2); }), ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.GOLURK, Species.RUNERIGUS])) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.REGIROCK, Species.REGICE, Species.REGISTEEL], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 4, + getRandomPartyMemberFunc([Species.REGIROCK, Species.REGICE, Species.REGISTEEL], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; }), ) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.METAGROSS], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.METAGROSS], TrainerSlot.TRAINER, true, p => { p.formIndex = 1; // Mega Metagross p.generateAndPopulateMoveset(); p.generateName(); @@ -3660,13 +3872,17 @@ export const trainerConfigs: TrainerConfigs = { .setHasDouble("wallace_steven_double") .setDoubleTrainerType(TrainerType.STEVEN) .setDoubleTitle("champion_double") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.PELIPPER], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 0, + getRandomPartyMemberFunc([Species.PELIPPER], TrainerSlot.TRAINER, true, p => { p.abilityIndex = 1; // Drizzle p.generateAndPopulateMoveset(); }), ) .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.LUDICOLO])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.LATIAS, Species.LATIOS], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.LATIAS, Species.LATIOS], TrainerSlot.TRAINER, true, p => { p.formIndex = 1; // Mega Latios or Mega Latias p.generateAndPopulateMoveset(); p.generateName(); @@ -3674,12 +3890,16 @@ export const trainerConfigs: TrainerConfigs = { }), ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.SWAMPERT, Species.GASTRODON, Species.SEISMITOAD])) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.REGIELEKI, Species.REGIDRAGO], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 4, + getRandomPartyMemberFunc([Species.REGIELEKI, Species.REGIDRAGO], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; }), ) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.MILOTIC], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.MILOTIC], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.gender = Gender.FEMALE; p.setBoss(true, 2); @@ -3692,22 +3912,35 @@ export const trainerConfigs: TrainerConfigs = { .setMixedBattleBgm("battle_sinnoh_champion") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.SPIRITOMB])) .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.LUCARIO])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.GIRATINA], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.GIRATINA], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; }), ) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.MILOTIC, Species.ROSERADE, Species.HISUI_ARCANINE], TrainerSlot.TRAINER, true, p => { - p.generateAndPopulateMoveset(); - p.teraType = p.species.type1; - }), + .setPartyMemberFunc( + 3, + getRandomPartyMemberFunc( + [Species.MILOTIC, Species.ROSERADE, Species.HISUI_ARCANINE], + TrainerSlot.TRAINER, + true, + p => { + p.generateAndPopulateMoveset(); + p.teraType = p.species.type1; + }, + ), ) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.TOGEKISS], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 4, + getRandomPartyMemberFunc([Species.TOGEKISS], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.setBoss(true, 2); }), ) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.GARCHOMP], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.GARCHOMP], TrainerSlot.TRAINER, true, p => { p.formIndex = 1; // Mega Garchomp p.generateAndPopulateMoveset(); p.generateName(); @@ -3723,28 +3956,47 @@ export const trainerConfigs: TrainerConfigs = { .setBattleBgm("battle_champion_alder") .setMixedBattleBgm("battle_champion_alder") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.BOUFFALANT, Species.BRAVIARY])) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.HISUI_LILLIGANT, Species.HISUI_ZOROARK, Species.BASCULEGION], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 1, + getRandomPartyMemberFunc( + [Species.HISUI_LILLIGANT, Species.HISUI_ZOROARK, Species.BASCULEGION], + TrainerSlot.TRAINER, + true, + p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ROGUE_BALL; - }), + }, + ), ) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.ZEKROM], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.ZEKROM], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; }), ) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.KELDEO], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 3, + getRandomPartyMemberFunc([Species.KELDEO], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; }), ) - .setPartyMemberFunc(4, getRandomPartyMemberFunc( - [Species.CHANDELURE, Species.KROOKODILE, Species.REUNICLUS, Species.CONKELDURR], TrainerSlot.TRAINER, true, p => { - p.generateAndPopulateMoveset(); - p.teraType = p.species.speciesId === Species.KROOKODILE ? PokemonType.DARK : p.species.type1; - }), + .setPartyMemberFunc( + 4, + getRandomPartyMemberFunc( + [Species.CHANDELURE, Species.KROOKODILE, Species.REUNICLUS, Species.CONKELDURR], + TrainerSlot.TRAINER, + true, + p => { + p.generateAndPopulateMoveset(); + p.teraType = p.species.speciesId === Species.KROOKODILE ? PokemonType.DARK : p.species.type1; + }, + ), ) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.VOLCARONA], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.VOLCARONA], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.gender = Gender.MALE; p.setBoss(true, 2); @@ -3760,23 +4012,36 @@ export const trainerConfigs: TrainerConfigs = { .setDoubleTitle("champion_double") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.DRUDDIGON])) .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.ARCHEOPS])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.RESHIRAM], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.RESHIRAM], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; }), ) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.SALAMENCE, Species.HYDREIGON, Species.ARCHALUDON], TrainerSlot.TRAINER, true, p => { - p.generateAndPopulateMoveset(); - p.teraType = PokemonType.DRAGON; - }), + .setPartyMemberFunc( + 3, + getRandomPartyMemberFunc( + [Species.SALAMENCE, Species.HYDREIGON, Species.ARCHALUDON], + TrainerSlot.TRAINER, + true, + p => { + p.generateAndPopulateMoveset(); + p.teraType = PokemonType.DRAGON; + }, + ), ) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.LAPRAS], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 4, + getRandomPartyMemberFunc([Species.LAPRAS], TrainerSlot.TRAINER, true, p => { p.formIndex = 1; // G-Max Lapras p.generateAndPopulateMoveset(); p.generateName(); }), ) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.HAXORUS], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.HAXORUS], TrainerSlot.TRAINER, true, p => { p.abilityIndex = 1; // Mold Breaker p.generateAndPopulateMoveset(); p.gender = Gender.FEMALE; @@ -3787,28 +4052,38 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.DIANTHA]: new TrainerConfig(++t) .initForChampion(false) .setMixedBattleBgm("battle_kalos_champion") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.HAWLUCHA], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 0, + getRandomPartyMemberFunc([Species.HAWLUCHA], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); }), ) .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.TREVENANT, Species.GOURGEIST])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.XERNEAS], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.XERNEAS], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; }), ) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.TYRANTRUM, Species.AURORUS], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 3, + getRandomPartyMemberFunc([Species.TYRANTRUM, Species.AURORUS], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.abilityIndex = 2; // Rock Head Tyrantrum, Snow Warning Aurorus p.teraType = p.species.type2!; }), ) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.GOODRA], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 4, + getRandomPartyMemberFunc([Species.GOODRA], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.setBoss(true, 2); }), ) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.GARDEVOIR], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.GARDEVOIR], TrainerSlot.TRAINER, true, p => { p.formIndex = 1; // Mega Gardevoir p.generateAndPopulateMoveset(); p.generateName(); @@ -3819,29 +4094,45 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.KUKUI]: new TrainerConfig(++t) .initForChampion(true) .setMixedBattleBgm("battle_champion_kukui") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.LYCANROC], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 0, + getRandomPartyMemberFunc([Species.LYCANROC], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.formIndex = 2; // Dusk Lycanroc }), ) .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.MAGNEZONE, Species.ALOLA_NINETALES])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.TORNADUS, Species.THUNDURUS, Species.LANDORUS], TrainerSlot.TRAINER, true, p => { p.formIndex = 1; // Therian Formes + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc( + [Species.TORNADUS, Species.THUNDURUS, Species.LANDORUS], + TrainerSlot.TRAINER, + true, + p => { + p.formIndex = 1; // Therian Formes p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; - }), + }, + ), ) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.TAPU_KOKO, Species.TAPU_FINI], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 3, + getRandomPartyMemberFunc([Species.TAPU_KOKO, Species.TAPU_FINI], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.setBoss(true, 2); p.pokeball = PokeballType.ULTRA_BALL; }), ) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.SNORLAX], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 4, + getRandomPartyMemberFunc([Species.SNORLAX], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.formIndex = 1; // G-Max Snorlax }), ) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.INCINEROAR, Species.HISUI_DECIDUEYE], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.INCINEROAR, Species.HISUI_DECIDUEYE], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.gender = Gender.MALE; p.teraType = p.species.type2!; @@ -3853,24 +4144,32 @@ export const trainerConfigs: TrainerConfigs = { .setMixedBattleBgm("battle_alola_champion") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.ALOLA_RAICHU])) .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.NOIVERN])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.SOLGALEO], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.SOLGALEO], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; }), ) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.TAPU_LELE, Species.TAPU_BULU], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 3, + getRandomPartyMemberFunc([Species.TAPU_LELE, Species.TAPU_BULU], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; p.teraType = p.species.type1; }), ) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.ZYGARDE], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 4, + getRandomPartyMemberFunc([Species.ZYGARDE], TrainerSlot.TRAINER, true, p => { p.formIndex = 1; // Zygarde 10% forme, Aura Break p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ROGUE_BALL; }), ) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.DECIDUEYE, Species.PRIMARINA], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.DECIDUEYE, Species.PRIMARINA], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.setBoss(true, 2); p.gender = p.species.speciesId === Species.PRIMARINA ? Gender.FEMALE : Gender.MALE; @@ -3882,18 +4181,29 @@ export const trainerConfigs: TrainerConfigs = { .setMixedBattleBgm("battle_galar_champion") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.AEGISLASH])) .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.RHYPERIOR, Species.SEISMITOAD, Species.MR_RIME])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.ZACIAN], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.ZACIAN], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; }), ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.DRAGAPULT])) - .setPartyMemberFunc(4,getRandomPartyMemberFunc([Species.RILLABOOM, Species.CINDERACE, Species.INTELEON], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 4, + getRandomPartyMemberFunc( + [Species.RILLABOOM, Species.CINDERACE, Species.INTELEON], + TrainerSlot.TRAINER, + true, + p => { p.generateAndPopulateMoveset(); p.setBoss(true, 2); - }), + }, + ), ) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.CHARIZARD], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.CHARIZARD], TrainerSlot.TRAINER, true, p => { p.formIndex = 3; // G-Max Charizard p.generateAndPopulateMoveset(); p.generateName(); @@ -3904,35 +4214,47 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.MUSTARD]: new TrainerConfig(++t) .initForChampion(true) .setMixedBattleBgm("battle_mustard") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.CORVIKNIGHT], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 0, + getRandomPartyMemberFunc([Species.CORVIKNIGHT], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; }), ) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.KOMMO_O], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 1, + getRandomPartyMemberFunc([Species.KOMMO_O], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; }), ) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.GALAR_SLOWBRO, Species.GALAR_SLOWKING], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.GALAR_SLOWBRO, Species.GALAR_SLOWKING], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; p.teraType = p.species.type1; }), ) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.GALAR_DARMANITAN], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 3, + getRandomPartyMemberFunc([Species.GALAR_DARMANITAN], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; }), ) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.BLASTOISE, Species.VENUSAUR], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 4, + getRandomPartyMemberFunc([Species.BLASTOISE, Species.VENUSAUR], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.setBoss(true, 2); p.pokeball = PokeballType.ULTRA_BALL; }), ) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.URSHIFU], TrainerSlot.TRAINER, true, p => { - p.formIndex = randSeedInt(2, 2); // Random G-Max Urshifu + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.URSHIFU], TrainerSlot.TRAINER, true, p => { + p.formIndex = randSeedIntRange(2, 3); // Random G-Max Urshifu p.generateAndPopulateMoveset(); p.generateName(); p.gender = Gender.MALE; @@ -3943,21 +4265,27 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.GEETA]: new TrainerConfig(++t) .initForChampion(false) .setMixedBattleBgm("battle_champion_geeta") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.GLIMMORA], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 0, + getRandomPartyMemberFunc([Species.GLIMMORA], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.gender = Gender.MALE; p.setBoss(true, 2); }), ) .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.ESPATHRA, Species.VELUZA])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.MIRAIDON], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.MIRAIDON], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; }), ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.BAXCALIBUR])) .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA])) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.KINGAMBIT], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.KINGAMBIT], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); if (!p.moveset.some(move => !isNullOrUndefined(move) && move.moveId === Moves.TERA_BLAST)) { // Check if Tera Blast is in the moveset, if not, replace the third move with Tera Blast. @@ -3971,50 +4299,71 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.NEMONA]: new TrainerConfig(++t) .initForChampion(false) .setMixedBattleBgm("battle_champion_nemona") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.LYCANROC], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 0, + getRandomPartyMemberFunc([Species.LYCANROC], TrainerSlot.TRAINER, true, p => { p.formIndex = 0; // Midday form p.generateAndPopulateMoveset(); }), ) .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.PAWMOT])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.KORAIDON], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.KORAIDON], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; }), ) .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.GHOLDENGO])) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.ARMAROUGE, Species.CERULEDGE], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 4, + getRandomPartyMemberFunc([Species.ARMAROUGE, Species.CERULEDGE], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.teraType = p.species.type2!; }), ) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc( + [Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL], + TrainerSlot.TRAINER, + true, + p => { p.generateAndPopulateMoveset(); p.gender = Gender.MALE; p.setBoss(true, 2); - }), + }, + ), ) .setInstantTera(4), // Tera Psychic Armarouge / Ghost Ceruledge [TrainerType.KIERAN]: new TrainerConfig(++t) .initForChampion(true) .setMixedBattleBgm("battle_champion_kieran") .setPartyMemberFunc(0, getRandomPartyMemberFunc([Species.POLIWRATH, Species.POLITOED])) - .setPartyMemberFunc(1, getRandomPartyMemberFunc([Species.INCINEROAR, Species.GRIMMSNARL], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 1, + getRandomPartyMemberFunc([Species.INCINEROAR, Species.GRIMMSNARL], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.abilityIndex = p.species.speciesId === Species.INCINEROAR ? 2 : 0; // Intimidate Incineroar, Prankster Grimmsnarl }), ) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([Species.TERAPAGOS], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 2, + getRandomPartyMemberFunc([Species.TERAPAGOS], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.MASTER_BALL; }), ) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([Species.URSALUNA, Species.BLOODMOON_URSALUNA], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 3, + getRandomPartyMemberFunc([Species.URSALUNA, Species.BLOODMOON_URSALUNA], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; }), ) - .setPartyMemberFunc(4, getRandomPartyMemberFunc([Species.OGERPON], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 4, + getRandomPartyMemberFunc([Species.OGERPON], TrainerSlot.TRAINER, true, p => { p.formIndex = randSeedInt(4); // Random Ogerpon Tera Mask p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; @@ -4024,7 +4373,9 @@ export const trainerConfigs: TrainerConfigs = { } }), ) - .setPartyMemberFunc(5, getRandomPartyMemberFunc([Species.HYDRAPPLE], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc( + 5, + getRandomPartyMemberFunc([Species.HYDRAPPLE], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.gender = Gender.MALE; p.setBoss(true, 2); diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 983494b36c8..8abe3a303ca 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -54,7 +54,7 @@ import { getStarterValueFriendshipCap, speciesStarterCosts, } from "#app/data/balance/starters"; -import { NumberHolder, randSeedInt, getIvsFromId, BooleanHolder, randSeedItem, isNullOrUndefined, getEnumValues, toDmgValue, fixedInt, rgbaToInt, rgbHexToRgba, rgbToHsv, deltaRgb, isBetween, type nil, type Constructor } from "#app/utils/common"; +import { NumberHolder, randSeedInt, getIvsFromId, BooleanHolder, randSeedItem, isNullOrUndefined, getEnumValues, toDmgValue, fixedInt, rgbaToInt, rgbHexToRgba, rgbToHsv, deltaRgb, isBetween, type nil, type Constructor, randSeedIntRange } from "#app/utils/common"; import type { TypeDamageMultiplier } from "#app/data/type"; import { getTypeDamageMultiplier, getTypeRgb } from "#app/data/type"; import { PokemonType } from "#enums/pokemon-type"; @@ -4485,7 +4485,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { */ const randomMultiplier = simulated ? 1 - : this.randSeedIntRange(85, 100) / 100; + : this.randBattleSeedIntRange(85, 100) / 100; /** A damage multiplier for when the attack is of the attacker's type and/or Tera type. */ @@ -5629,7 +5629,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { let sleepTurnsRemaining: NumberHolder; if (effect === StatusEffect.SLEEP) { - sleepTurnsRemaining = new NumberHolder(this.randSeedIntRange(2, 4)); + sleepTurnsRemaining = new NumberHolder(this.randBattleSeedIntRange(2, 4)); this.setFrameRate(4); @@ -6292,7 +6292,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param min The minimum integer to pick, default `0` * @returns A random integer between {@linkcode min} and ({@linkcode min} + {@linkcode range} - 1) */ - randSeedInt(range: number, min = 0): number { + randBattleSeedInt(range: number, min = 0): number { return globalScene.currentBattle ? globalScene.randBattleSeedInt(range, min) : randSeedInt(range, min); @@ -6304,8 +6304,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @param max The maximum integer to generate * @returns a random integer between {@linkcode min} and {@linkcode max} inclusive */ - randSeedIntRange(min: number, max: number): number { - return this.randSeedInt(max - min + 1, min); + randBattleSeedIntRange(min: number, max: number): number { + return globalScene.currentBattle + ? globalScene.randBattleSeedInt(max - min + 1, min) + : randSeedIntRange(min, max); } /** @@ -7143,7 +7145,7 @@ export class EnemyPokemon extends Pokemon { const { waveIndex } = globalScene.currentBattle; const ivs: number[] = []; while (ivs.length < 6) { - ivs.push(this.randSeedIntRange(Math.floor(waveIndex / 10), 31)); + ivs.push(randSeedIntRange(Math.floor(waveIndex / 10), 31)); } this.ivs = ivs; } diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 763b40c8555..94bb0e3419a 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -1548,7 +1548,7 @@ export class SurviveDamageModifier extends PokemonHeldItemModifier { * @returns `true` if the survive damage has been applied */ override apply(pokemon: Pokemon, surviveDamage: BooleanHolder): boolean { - if (!surviveDamage.value && pokemon.randSeedInt(10) < this.getStackCount()) { + if (!surviveDamage.value && pokemon.randBattleSeedInt(10) < this.getStackCount()) { surviveDamage.value = true; globalScene.queueMessage( @@ -1594,7 +1594,7 @@ export class BypassSpeedChanceModifier extends PokemonHeldItemModifier { * @returns `true` if {@linkcode BypassSpeedChanceModifier} has been applied */ override apply(pokemon: Pokemon, doBypassSpeed: BooleanHolder): boolean { - if (!doBypassSpeed.value && pokemon.randSeedInt(10) < this.getStackCount()) { + if (!doBypassSpeed.value && pokemon.randBattleSeedInt(10) < this.getStackCount()) { doBypassSpeed.value = true; const isCommandFight = globalScene.currentBattle.turnCommands[pokemon.getBattlerIndex()]?.command === Command.FIGHT; @@ -1658,7 +1658,7 @@ export class FlinchChanceModifier extends PokemonHeldItemModifier { override apply(pokemon: Pokemon, flinched: BooleanHolder): boolean { // The check for pokemon.summonData is to ensure that a crash doesn't occur when a Pokemon with King's Rock procs a flinch // TODO: Since summonData is always defined now, we can probably remove this - if (pokemon.summonData && !flinched.value && pokemon.randSeedInt(100) < this.getStackCount() * this.chance) { + if (pokemon.summonData && !flinched.value && pokemon.randBattleSeedInt(100) < this.getStackCount() * this.chance) { flinched.value = true; return true; } @@ -1927,7 +1927,7 @@ export class PreserveBerryModifier extends PersistentModifier { * @returns always `true` */ override apply(pokemon: Pokemon, doPreserve: BooleanHolder): boolean { - doPreserve.value ||= pokemon.randSeedInt(10) < this.getStackCount() * 3; + doPreserve.value ||= pokemon.randBattleSeedInt(10) < this.getStackCount() * 3; return true; } @@ -3240,7 +3240,7 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier { return false; } - const targetPokemon = opponents[pokemon.randSeedInt(opponents.length)]; + const targetPokemon = opponents[pokemon.randBattleSeedInt(opponents.length)]; const transferredItemCount = this.getTransferredItemCount(); if (!transferredItemCount) { @@ -3272,7 +3272,7 @@ export abstract class HeldItemTransferModifier extends PokemonHeldItemModifier { break; } } - const randItemIndex = pokemon.randSeedInt(itemModifiers.length); + const randItemIndex = pokemon.randBattleSeedInt(itemModifiers.length); const randItem = itemModifiers[randItemIndex]; if (globalScene.tryTransferHeldItemModifier(randItem, pokemon, false)) { transferredModifierTypes.push(randItem.type); @@ -3731,7 +3731,7 @@ export class EnemyEndureChanceModifier extends EnemyPersistentModifier { * @returns `true` if {@linkcode Pokemon} endured */ override apply(target: Pokemon): boolean { - if (target.waveData.endured || target.randSeedInt(100) >= this.chance * this.getStackCount()) { + if (target.waveData.endured || target.randBattleSeedInt(100) >= this.chance * this.getStackCount()) { return false; } diff --git a/src/phases/attempt-capture-phase.ts b/src/phases/attempt-capture-phase.ts index 795aa7010e1..8592cd98508 100644 --- a/src/phases/attempt-capture-phase.ts +++ b/src/phases/attempt-capture-phase.ts @@ -63,7 +63,7 @@ export class AttemptCapturePhase extends PokemonPhase { const modifiedCatchRate = Math.round((((_3m - _2h) * catchRate * pokeballMultiplier) / _3m) * statusMultiplier); const shakeProbability = Math.round(65536 / Math.pow(255 / modifiedCatchRate, 0.1875)); // Formula taken from gen 6 const criticalCaptureChance = getCriticalCaptureChance(modifiedCatchRate); - const isCritical = pokemon.randSeedInt(256) < criticalCaptureChance; + const isCritical = pokemon.randBattleSeedInt(256) < criticalCaptureChance; const fpOffset = pokemon.getFieldPositionOffset(); const pokeballAtlasKey = getPokeballAtlasKey(this.pokeballType); @@ -135,14 +135,14 @@ export class AttemptCapturePhase extends PokemonPhase { pokeballMultiplier === -1 || isCritical || modifiedCatchRate >= 255 || - pokemon.randSeedInt(65536) < shakeProbability + pokemon.randBattleSeedInt(65536) < shakeProbability ) { globalScene.playSound("se/pb_move"); } else { shakeCounter.stop(); this.failCatch(shakeCount); } - } else if (isCritical && pokemon.randSeedInt(65536) >= shakeProbability) { + } else if (isCritical && pokemon.randBattleSeedInt(65536) >= shakeProbability) { // Above, perform the one shake check for critical captures after the ball shakes once shakeCounter.stop(); this.failCatch(shakeCount); diff --git a/src/phases/attempt-run-phase.ts b/src/phases/attempt-run-phase.ts index 274d3c40576..15c521c01fc 100644 --- a/src/phases/attempt-run-phase.ts +++ b/src/phases/attempt-run-phase.ts @@ -34,7 +34,7 @@ export class AttemptRunPhase extends PokemonPhase { applyAbAttrs(RunSuccessAbAttr, playerPokemon, null, false, escapeChance); - if (playerPokemon.randSeedInt(100) < escapeChance.value && !this.forceFailEscape) { + if (playerPokemon.randBattleSeedInt(100) < escapeChance.value && !this.forceFailEscape) { enemyField.forEach(enemyPokemon => applyPreLeaveFieldAbAttrs(PreLeaveFieldAbAttr, enemyPokemon)); globalScene.playSound("se/flee"); diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index d067807486d..59f5ac69fd8 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -594,7 +594,7 @@ export class MoveEffectPhase extends PokemonPhase { } const accuracyMultiplier = user.getAccuracyMultiplier(target, this.move); - const rand = user.randSeedInt(100); + const rand = user.randBattleSeedInt(100); if (rand < moveAccuracy * accuracyMultiplier) { return [HitCheckResult.HIT, effectiveness]; diff --git a/src/phases/move-phase.ts b/src/phases/move-phase.ts index e704b040d20..5d63fe6efea 100644 --- a/src/phases/move-phase.ts +++ b/src/phases/move-phase.ts @@ -232,7 +232,7 @@ export class MovePhase extends BattlePhase { switch (this.pokemon.status.effect) { case StatusEffect.PARALYSIS: activated = - (!this.pokemon.randSeedInt(4) || Overrides.STATUS_ACTIVATION_OVERRIDE === true) && + (!this.pokemon.randBattleSeedInt(4) || Overrides.STATUS_ACTIVATION_OVERRIDE === true) && Overrides.STATUS_ACTIVATION_OVERRIDE !== false; break; case StatusEffect.SLEEP: { @@ -258,7 +258,7 @@ export class MovePhase extends BattlePhase { .findAttr( attr => attr instanceof HealStatusEffectAttr && attr.selfTarget && attr.isOfEffect(StatusEffect.FREEZE), ) || - (!this.pokemon.randSeedInt(5) && Overrides.STATUS_ACTIVATION_OVERRIDE !== true) || + (!this.pokemon.randBattleSeedInt(5) && Overrides.STATUS_ACTIVATION_OVERRIDE !== true) || Overrides.STATUS_ACTIVATION_OVERRIDE === false; activated = !healed; diff --git a/src/utils/common.ts b/src/utils/common.ts index 4cf7ceccff2..b9111578e2f 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -99,6 +99,16 @@ export function randSeedInt(range: number, min = 0): number { return Phaser.Math.RND.integerInRange(min, range - 1 + min); } +/** + * Generates a random number using the global seed + * @param min The minimum integer to generate + * @param max The maximum integer to generate + * @returns a random integer between {@linkcode min} and {@linkcode max} inclusive + */ +export function randSeedIntRange(min: number, max: number): number { + return randSeedInt(max - min + 1, min); +} + /** * Returns a random integer between min and max (non-inclusive) * @param min The lowest number diff --git a/test/abilities/cud_chew.test.ts b/test/abilities/cud_chew.test.ts index f99060cb744..2f65ac5fd97 100644 --- a/test/abilities/cud_chew.test.ts +++ b/test/abilities/cud_chew.test.ts @@ -111,7 +111,7 @@ describe("Abilities - Cud Chew", () => { it("can store multiple berries across 2 turns with teatime", async () => { // always eat first berry for stuff cheeks & company - vi.spyOn(Pokemon.prototype, "randSeedInt").mockReturnValue(0); + vi.spyOn(Pokemon.prototype, "randBattleSeedInt").mockReturnValue(0); game.override .startingHeldItems([ { name: "BERRY", type: BerryType.PETAYA, count: 3 }, diff --git a/test/abilities/desolate-land.test.ts b/test/abilities/desolate-land.test.ts index d6f01f7aa5e..697bd0a4c48 100644 --- a/test/abilities/desolate-land.test.ts +++ b/test/abilities/desolate-land.test.ts @@ -139,7 +139,7 @@ describe("Abilities - Desolate Land", () => { await game.classicMode.startBattle([Species.MAGIKARP]); expect(game.scene.arena.weather?.weatherType).toBe(WeatherType.HARSH_SUN); - vi.spyOn(game.scene.getPlayerPokemon()!, "randSeedInt").mockReturnValue(0); + vi.spyOn(game.scene.getPlayerPokemon()!, "randBattleSeedInt").mockReturnValue(0); const commandPhase = game.scene.getCurrentPhase() as CommandPhase; commandPhase.handleCommand(Command.RUN, 0); diff --git a/test/abilities/neutralizing_gas.test.ts b/test/abilities/neutralizing_gas.test.ts index 32c61b72e4d..979583b7d97 100644 --- a/test/abilities/neutralizing_gas.test.ts +++ b/test/abilities/neutralizing_gas.test.ts @@ -164,7 +164,7 @@ describe("Abilities - Neutralizing Gas", () => { await game.classicMode.startBattle([Species.MAGIKARP]); expect(game.scene.arena.getTag(ArenaTagType.NEUTRALIZING_GAS)).toBeDefined(); - vi.spyOn(game.scene.getPlayerPokemon()!, "randSeedInt").mockReturnValue(0); + vi.spyOn(game.scene.getPlayerPokemon()!, "randBattleSeedInt").mockReturnValue(0); const commandPhase = game.scene.getCurrentPhase() as CommandPhase; commandPhase.handleCommand(Command.RUN, 0); diff --git a/test/items/reviver_seed.test.ts b/test/items/reviver_seed.test.ts index c109794d3d2..3c67481a904 100644 --- a/test/items/reviver_seed.test.ts +++ b/test/items/reviver_seed.test.ts @@ -73,7 +73,7 @@ describe("Items - Reviver Seed", () => { const reviverSeed = player.getHeldItems()[0] as PokemonInstantReviveModifier; vi.spyOn(reviverSeed, "apply"); - vi.spyOn(player, "randSeedInt").mockReturnValue(0); // Force confusion self-hit + vi.spyOn(player, "randBattleSeedInt").mockReturnValue(0); // Force confusion self-hit game.move.select(Moves.TACKLE); await game.phaseInterceptor.to("BerryPhase"); diff --git a/test/moves/u_turn.test.ts b/test/moves/u_turn.test.ts index 4ceb6865be0..9dca29414a1 100644 --- a/test/moves/u_turn.test.ts +++ b/test/moves/u_turn.test.ts @@ -74,7 +74,7 @@ describe("Moves - U-turn", () => { // arrange game.override.enemyAbility(Abilities.POISON_POINT); await game.classicMode.startBattle([Species.RAICHU, Species.SHUCKLE]); - vi.spyOn(game.scene.getEnemyPokemon()!, "randSeedInt").mockReturnValue(0); + vi.spyOn(game.scene.getEnemyPokemon()!, "randBattleSeedInt").mockReturnValue(0); // act game.move.select(Moves.U_TURN); From 4376a22a7c665e9070afbd60d9e994ea807727b8 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Sat, 17 May 2025 16:04:16 -0500 Subject: [PATCH 48/61] [Bug] Fix field moves always playing their animations (#5830) --- src/phases/move-effect-phase.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index 59f5ac69fd8..e3773952214 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -354,8 +354,8 @@ export class MoveEffectPhase extends PokemonPhase { move.id as Moves, user, firstTarget?.getBattlerIndex() ?? BattlerIndex.ATTACKER, - // Field moves and some moves used in mystery encounters should be played even on an empty field - fieldMove || (globalScene.currentBattle?.mysteryEncounter?.hasBattleAnimationsWithoutTargets ?? false), + // Some moves used in mystery encounters should be played even on an empty field + globalScene.currentBattle?.mysteryEncounter?.hasBattleAnimationsWithoutTargets ?? false, ).play(move.hitsSubstitute(user, firstTarget), () => this.postAnimCallback(user, targets)); return; From 22f5ed1232ec4b02811593ccd406da9873d4fbb6 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Sat, 17 May 2025 20:34:06 -0700 Subject: [PATCH 49/61] [i18n] Update locales --- public/locales | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/locales b/public/locales index ee6bb371afe..a074ddb28c3 160000 --- a/public/locales +++ b/public/locales @@ -1 +1 @@ -Subproject commit ee6bb371afefe4c6d872cc7765f0e0d26e630d4e +Subproject commit a074ddb28c3f0c7e9bbd0560efa33e3ce5f71bcd From 9ae969117b0dd1d4bc39be3dd6d2624bd585dbaa Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Sun, 18 May 2025 00:22:09 -0500 Subject: [PATCH 50/61] [Bug][UI/UX] Fix fiery fallout message bug (#5834) * Fix fiery fallout message bug * Ensure pokemon names are replaced when there is no separator --- src/phases/message-phase.ts | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/phases/message-phase.ts b/src/phases/message-phase.ts index f6777579857..b277d67de82 100644 --- a/src/phases/message-phase.ts +++ b/src/phases/message-phase.ts @@ -35,20 +35,22 @@ export class MessagePhase extends Phase { this.text = this.text.split(pokename[p]).join(repname[p]); } const pageIndex = this.text.indexOf("$"); - for (let p = 0; p < globalScene.getPlayerField().length; p++) { - this.text = this.text.split(repname[p]).join(pokename[p]); - } if (pageIndex !== -1) { + let page0 = this.text.slice(0, pageIndex); + let page1 = this.text.slice(pageIndex + 1); + // Pokemon names must be re-inserted _after_ the split, otherwise the index will be wrong + for (let p = 0; p < globalScene.getPlayerField().length; p++) { + page0 = page0.split(repname[p]).join(pokename[p]); + page1 = page1.split(repname[p]).join(pokename[p]); + } globalScene.unshiftPhase( - new MessagePhase( - this.text.slice(pageIndex + 1), - this.callbackDelay, - this.prompt, - this.promptDelay, - this.speaker, - ), + new MessagePhase(page1, this.callbackDelay, this.prompt, this.promptDelay, this.speaker), ); - this.text = this.text.slice(0, pageIndex).trim(); + this.text = page0.trim(); + } else { + for (let p = 0; p < globalScene.getPlayerField().length; p++) { + this.text = this.text.split(repname[p]).join(pokename[p]); + } } } From bd14ed640c8c11da897128ca621e5951b7cd0113 Mon Sep 17 00:00:00 2001 From: Lugiad <2070109+Adri1@users.noreply.github.com> Date: Tue, 20 May 2025 00:00:51 +0200 Subject: [PATCH 51/61] [Localization] Localizable "Cancel" text in Ball selection menu (#5836) "Cancel" text localizable --- src/ui/ball-ui-handler.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ui/ball-ui-handler.ts b/src/ui/ball-ui-handler.ts index abb106a6553..eb7c208662a 100644 --- a/src/ui/ball-ui-handler.ts +++ b/src/ui/ball-ui-handler.ts @@ -7,6 +7,7 @@ import { addWindow } from "./ui-theme"; import { Button } from "#enums/buttons"; import type { CommandPhase } from "#app/phases/command-phase"; import { globalScene } from "#app/global-scene"; +import i18next from "i18next"; export default class BallUiHandler extends UiHandler { private pokeballSelectContainer: Phaser.GameObjects.Container; @@ -31,7 +32,7 @@ export default class BallUiHandler extends UiHandler { for (let pb = 0; pb < Object.keys(globalScene.pokeballCounts).length; pb++) { optionsTextContent += `${getPokeballName(pb)}\n`; } - optionsTextContent += "Cancel"; + optionsTextContent += i18next.t("pokeball:cancel"); const optionsText = addTextObject(0, 0, optionsTextContent, TextStyle.WINDOW, { align: "right", maxLines: 6 }); const optionsTextWidth = optionsText.displayWidth; this.pokeballSelectContainer = globalScene.add.container( From a9ec3b324c8deb88de9cc7b986fc92814922dd5a Mon Sep 17 00:00:00 2001 From: Lugiad <2070109+Adri1@users.noreply.github.com> Date: Tue, 20 May 2025 00:03:42 +0200 Subject: [PATCH 52/61] [UI/UX] [i18n] Text ratio adjustment for es-MX Egg Gatcha (#5839) --- src/ui/egg-gacha-ui-handler.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/egg-gacha-ui-handler.ts b/src/ui/egg-gacha-ui-handler.ts index 5377cf3d283..1bb7124d935 100644 --- a/src/ui/egg-gacha-ui-handler.ts +++ b/src/ui/egg-gacha-ui-handler.ts @@ -108,7 +108,7 @@ export default class EggGachaUiHandler extends MessageUiHandler { let pokemonIconX = -20; let pokemonIconY = 6; - if (["de", "es-ES", "fr", "ko", "pt-BR"].includes(currentLanguage)) { + if (["de", "es-ES", "es-MX", "fr", "ko", "pt-BR"].includes(currentLanguage)) { gachaTextStyle = TextStyle.SMALLER_WINDOW_ALT; gachaX = 2; gachaY = 2; @@ -116,7 +116,7 @@ export default class EggGachaUiHandler extends MessageUiHandler { let legendaryLabelX = gachaX; let legendaryLabelY = gachaY; - if (["de", "es-ES"].includes(currentLanguage)) { + if (["de", "es-ES", "es-MX"].includes(currentLanguage)) { pokemonIconX = -25; pokemonIconY = 10; legendaryLabelX = -6; From dda94c7b22411af71f7f1e52725f8587af89ad55 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Mon, 19 May 2025 17:18:26 -0700 Subject: [PATCH 53/61] [i18n] Update locales --- public/locales | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/locales b/public/locales index a074ddb28c3..42cd5cf577f 160000 --- a/public/locales +++ b/public/locales @@ -1 +1 @@ -Subproject commit a074ddb28c3f0c7e9bbd0560efa33e3ce5f71bcd +Subproject commit 42cd5cf577f475c22bc82d55e7ca358eb4f3184f From 9746f1a2a6aa61d03137674dad92ef2c72225469 Mon Sep 17 00:00:00 2001 From: Lugiad <2070109+Adri1@users.noreply.github.com> Date: Tue, 20 May 2025 02:39:17 +0200 Subject: [PATCH 54/61] [UI/UX] [Localization] Update Korean starterInfoText --- src/ui/starter-select-ui-handler.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 09d7322cb75..ac781a71da0 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -145,8 +145,10 @@ const languageSettings: { [key: string]: LanguageSetting } = { starterInfoXPos: 33, }, ko: { - starterInfoTextSize: "52px", + starterInfoTextSize: "60px", instructionTextSize: "38px", + starterInfoYOffset: -0.5, + starterInfoXPos: 30, }, ja: { starterInfoTextSize: "51px", From 23e1d88c3ad45914602d815fc10ef8b14d1c2c92 Mon Sep 17 00:00:00 2001 From: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> Date: Tue, 20 May 2025 15:40:05 -0400 Subject: [PATCH 55/61] [Balance] Update TM compatibility for Curse (#5791) * Update Curse TM compat with former egg moves/level ups * Pumpkaboo is not Phantump --- src/data/balance/tms.ts | 44 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/data/balance/tms.ts b/src/data/balance/tms.ts index 69aef9b135d..b7480e9131d 100644 --- a/src/data/balance/tms.ts +++ b/src/data/balance/tms.ts @@ -19057,8 +19057,15 @@ export const tmSpecies: TmSpecies = { Species.SLAKING, Species.HARIYAMA, Species.NOSEPASS, + Species.ARON, + Species.LAIRON, + Species.AGGRON, + Species.ELECTRIKE, + Species.MANECTRIC, Species.GULPIN, Species.SWALOT, + Species.WAILMER, + Species.WAILORD, Species.NUMEL, Species.CAMERUPT, Species.TORKOAL, @@ -19067,18 +19074,28 @@ export const tmSpecies: TmSpecies = { Species.ZANGOOSE, Species.SEVIPER, Species.WHISCASH, + Species.LILEEP, + Species.CRADILY, + Species.ANORITH, + Species.ARMALDO, Species.SHUPPET, Species.BANETTE, Species.DUSKULL, Species.DUSCLOPS, Species.TROPIUS, Species.CHIMECHO, + Species.ABSOL, + Species.SPHEAL, + Species.SEALEO, + Species.WALREIN, Species.REGIROCK, Species.REGICE, Species.REGISTEEL, Species.TURTWIG, Species.GROTLE, Species.TORTERRA, + Species.BIDOOF, + Species.BIBAREL, Species.CRANIDOS, Species.RAMPARDOS, Species.SHIELDON, @@ -19120,6 +19137,11 @@ export const tmSpecies: TmSpecies = { Species.TEPIG, Species.PIGNITE, Species.EMBOAR, + Species.MUNNA, + Species.MUSHARNA, + Species.ROGGENROLA, + Species.BOLDORE, + Species.GIGALITH, Species.DRILBUR, Species.EXCADRILL, Species.TIMBURR, @@ -19128,28 +19150,44 @@ export const tmSpecies: TmSpecies = { Species.SANDILE, Species.KROKOROK, Species.KROOKODILE, + Species.DWEBBLE, + Species.CRUSTLE, Species.SCRAGGY, Species.SCRAFTY, Species.YAMASK, - Species.COFAGRIGUS, + Species.COFAGRIGUS, + Species.TRUBBISH, + Species.GARBODOR, Species.SAWSBUCK, + Species.FERROSEED, + Species.FERROTHORN, Species.LITWICK, Species.LAMPENT, Species.CHANDELURE, Species.BEARTIC, + Species.SHELMET, + Species.ACCELGOR, + Species.STUNFISK, Species.GOLETT, Species.GOLURK, + Species.HEATMOR, Species.CHESPIN, Species.QUILLADIN, Species.CHESNAUGHT, + Species.TYRUNT, + Species.TYRANTRUM, Species.SYLVEON, Species.GOOMY, Species.SLIGGOO, Species.GOODRA, Species.PHANTUMP, Species.TREVENANT, + Species.PUMPKABOO, + Species.GOURGEIST, Species.BERGMITE, Species.AVALUGG, + Species.ROWLET, + Species.DARTRIX, Species.DECIDUEYE, Species.GUMSHOOS, Species.MUDBRAY, @@ -19157,7 +19195,9 @@ export const tmSpecies: TmSpecies = { Species.PASSIMIAN, Species.SANDYGAST, Species.PALOSSAND, + Species.PYUKUMUKU, Species.KOMALA, + Species.TURTONATOR, Species.MIMIKYU, Species.SKWOVET, Species.GREEDENT, @@ -19169,6 +19209,7 @@ export const tmSpecies: TmSpecies = { Species.SINISTEA, Species.POLTEAGEIST, Species.PERRSERKER, + Species.CURSOLA, Species.RUNERIGUS, Species.PINCURCHIN, Species.STONJOURNER, @@ -19236,6 +19277,7 @@ export const tmSpecies: TmSpecies = { Species.GALAR_WEEZING, Species.GALAR_SLOWKING, Species.GALAR_YAMASK, + Species.GALAR_STUNFISK, Species.HISUI_ELECTRODE, Species.HISUI_TYPHLOSION, Species.HISUI_QWILFISH, From 663c64fdb41c51a4104ba270639f93c862698296 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Tue, 20 May 2025 16:46:23 -0500 Subject: [PATCH 56/61] [Misc] Fix trailing whitespace (#5856) Remove trailing whitespace --- src/data/balance/signature-species.ts | 6 +++--- src/data/balance/tms.ts | 4 ++-- src/field/pokemon.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/data/balance/signature-species.ts b/src/data/balance/signature-species.ts index fb8f33d4435..04749a67521 100644 --- a/src/data/balance/signature-species.ts +++ b/src/data/balance/signature-species.ts @@ -8,11 +8,11 @@ export type SignatureSpecies = { * The signature species for each Gym Leader, Elite Four member, and Champion. * The key is the trainer type, and the value is an array of Species or Species arrays. * This is in a separate const so it can be accessed from other places and not just the trainerConfigs - * + * * @remarks - * The `Proxy` object allows us to define a handler that will intercept + * The `Proxy` object allows us to define a handler that will intercept * the property access and return an empty array if the property does not exist in the object. - * + * * This means that accessing `signatureSpecies` will not throw an error if the property does not exist, * but instead default to an empty array. */ diff --git a/src/data/balance/tms.ts b/src/data/balance/tms.ts index b7480e9131d..06d191c3b2a 100644 --- a/src/data/balance/tms.ts +++ b/src/data/balance/tms.ts @@ -67104,7 +67104,7 @@ export const tmSpecies: TmSpecies = { Species.CHEWTLE, Species.DREDNAW, Species.YAMPER, - Species.BOLTUND, + Species.BOLTUND, Species.ROLYCOLY, Species.CARKOL, Species.COALOSSAL, @@ -67121,7 +67121,7 @@ export const tmSpecies: TmSpecies = { Species.SIZZLIPEDE, Species.CENTISKORCH, Species.CLOBBOPUS, - Species.GRAPPLOCT, + Species.GRAPPLOCT, Species.SINISTEA, Species.POLTEAGEIST, Species.HATENNA, diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 8abe3a303ca..fcca0c5614a 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -5678,7 +5678,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { /** * Performs the action of clearing a Pokemon's status - * + * * This is a helper to {@linkcode resetStatus}, which should be called directly instead of this method */ public clearStatus(confusion: boolean, reloadAssets: boolean) { From 288e4e7e7eb9e6a9d450369a9c11cb0945845fcd Mon Sep 17 00:00:00 2001 From: itgalex24 <123003541+itgalex24@users.noreply.github.com> Date: Tue, 20 May 2025 19:12:54 -0400 Subject: [PATCH 57/61] [Bug] [Move] Synchronoise hitting Tera Type fix (#5779) * synchronoize fix * Add regression test for synchronoise --------- Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> --- src/data/moves/move.ts | 6 ++--- test/moves/synchronoise.test.ts | 47 +++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 test/moves/synchronoise.test.ts diff --git a/src/data/moves/move.ts b/src/data/moves/move.ts index 235cb954ea5..b190729621c 100644 --- a/src/data/moves/move.ts +++ b/src/data/moves/move.ts @@ -8052,10 +8052,10 @@ export class UpperHandCondition extends MoveCondition { } } -export class hitsSameTypeAttr extends VariableMoveTypeMultiplierAttr { +export class HitsSameTypeAttr extends VariableMoveTypeMultiplierAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const multiplier = args[0] as NumberHolder; - if (!user.getTypes().some(type => target.getTypes().includes(type))) { + if (!user.getTypes(true).some(type => target.getTypes(true).includes(type))) { multiplier.value = 0; return true; } @@ -9756,7 +9756,7 @@ export function initMoves() { new AttackMove(Moves.SYNCHRONOISE, PokemonType.PSYCHIC, MoveCategory.SPECIAL, 120, 100, 10, -1, 0, 5) .target(MoveTarget.ALL_NEAR_OTHERS) .condition(unknownTypeCondition) - .attr(hitsSameTypeAttr), + .attr(HitsSameTypeAttr), new AttackMove(Moves.ELECTRO_BALL, PokemonType.ELECTRIC, MoveCategory.SPECIAL, -1, 100, 10, -1, 0, 5) .attr(ElectroBallPowerAttr) .ballBombMove(), diff --git a/test/moves/synchronoise.test.ts b/test/moves/synchronoise.test.ts new file mode 100644 index 00000000000..0f59bce26b4 --- /dev/null +++ b/test/moves/synchronoise.test.ts @@ -0,0 +1,47 @@ +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { PokemonType } from "#enums/pokemon-type"; +import { Species } from "#enums/species"; +import GameManager from "#test/testUtils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Moves - Synchronoise", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .moveset([Moves.SYNCHRONOISE]) + .ability(Abilities.BALL_FETCH) + .battleStyle("single") + .disableCrits() + .enemySpecies(Species.MAGIKARP) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + it("should consider the user's tera type if it is terastallized", async () => { + await game.classicMode.startBattle([Species.BIDOOF]); + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyPokemon = game.scene.getEnemyPokemon()!; + + // force the player to be terastallized + playerPokemon.teraType = PokemonType.WATER; + playerPokemon.isTerastallized = true; + game.move.select(Moves.SYNCHRONOISE); + await game.phaseInterceptor.to("BerryPhase"); + expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); + }); +}); From b72389295e69625406393f4b4087be3191ec8382 Mon Sep 17 00:00:00 2001 From: Madmadness65 <59298170+Madmadness65@users.noreply.github.com> Date: Tue, 20 May 2025 21:07:37 -0500 Subject: [PATCH 58/61] [Animation] [P3 Bug] Fix Sandstorm weather animation not playing properly (#5853) Fix Sandstorm weather animation not playing properly The sandstorm background image is now properly used within the weather animation's JSON. --- public/battle-anims/common-sandstorm.json | 73 +++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/public/battle-anims/common-sandstorm.json b/public/battle-anims/common-sandstorm.json index b5b2d29f54c..fba90a08645 100644 --- a/public/battle-anims/common-sandstorm.json +++ b/public/battle-anims/common-sandstorm.json @@ -542,6 +542,79 @@ "volume": 100, "pitch": 55, "eventType": "AnimTimedSoundEvent" + }, + { + "frameIndex": 0, + "resourceName": "PRAS- Sandstorm", + "bgX": -50, + "bgY": 0, + "opacity": 0, + "duration": 5, + "eventType": "AnimTimedAddBgEvent" + }, + { + "frameIndex": 0, + "resourceName": "", + "bgX": -50, + "bgY": 0, + "opacity": 96, + "duration": 3, + "eventType": "AnimTimedUpdateBgEvent" + } + ], + "3": [ + { + "frameIndex": 3, + "resourceName": "", + "bgX": -25, + "bgY": 0, + "opacity": 128, + "duration": 3, + "eventType": "AnimTimedUpdateBgEvent" + } + ], + "6": [ + { + "frameIndex": 6, + "resourceName": "", + "bgX": 0, + "bgY": 0, + "opacity": 192, + "duration": 3, + "eventType": "AnimTimedUpdateBgEvent" + } + ], + "9": [ + { + "frameIndex": 9, + "resourceName": "", + "bgX": 25, + "bgY": 0, + "opacity": 128, + "duration": 3, + "eventType": "AnimTimedUpdateBgEvent" + } + ], + "12": [ + { + "frameIndex": 12, + "resourceName": "", + "bgX": 50, + "bgY": 0, + "opacity": 96, + "duration": 3, + "eventType": "AnimTimedUpdateBgEvent" + } + ], + "15": [ + { + "frameIndex": 15, + "resourceName": "", + "bgX": 50, + "bgY": 0, + "opacity": 0, + "duration": 3, + "eventType": "AnimTimedUpdateBgEvent" } ] }, From f01e7599ac8ea7a1c8fc14f556f0c5ae090c4ea1 Mon Sep 17 00:00:00 2001 From: Lugiad <2070109+Adri1@users.noreply.github.com> Date: Wed, 21 May 2025 04:21:35 +0200 Subject: [PATCH 59/61] [UI/UX] [Localization] Update Japanese starterInfoText (#5852) Update Japanese starterInfoText --- src/ui/starter-select-ui-handler.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index ac781a71da0..a35f426e8bd 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -151,8 +151,10 @@ const languageSettings: { [key: string]: LanguageSetting } = { starterInfoXPos: 30, }, ja: { - starterInfoTextSize: "51px", + starterInfoTextSize: "62px", instructionTextSize: "38px", + starterInfoYOffset: 0.5, + starterInfoXPos: 33, }, "ca-ES": { starterInfoTextSize: "52px", From 1cf19b49f26d0b82c102d304d7585fe5bacea785 Mon Sep 17 00:00:00 2001 From: AJ Fontaine <36677462+Fontbane@users.noreply.github.com> Date: Tue, 20 May 2025 22:59:39 -0400 Subject: [PATCH 60/61] [Balance] Moveset generation adjustments (#5801) * Moveset generation adjustments * Remove shiny explosion check, prevent 2 self-KO moves --- src/field/pokemon.ts | 74 +++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 45 deletions(-) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index fcca0c5614a..74ccb0c7f49 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -3500,11 +3500,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } let weight = levelMove[0]; // Evolution Moves - if (weight === 0) { + if (weight === EVOLVE_MOVE) { weight = 50; } - // Assume level 1 moves with 80+ BP are "move reminder" moves and bump their weight - if (weight === 1 && allMoves[levelMove[1]].power >= 80) { + // Assume level 1 moves with 80+ BP are "move reminder" moves and bump their weight. Trainers use actual relearn moves. + if (weight === 1 && allMoves[levelMove[1]].power >= 80 || weight === RELEARN_MOVE && this.hasTrainer()) { weight = 40; } if ( @@ -3609,9 +3609,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { // Bosses never get self ko moves or Pain Split if (this.isBoss()) { - movePool = movePool.filter(m => !allMoves[m[0]].hasAttr(SacrificialAttr)); - movePool = movePool.filter(m => !allMoves[m[0]].hasAttr(HpSplitAttr)); + movePool = movePool.filter(m => !allMoves[m[0]].hasAttr(SacrificialAttr) && !allMoves[m[0]].hasAttr(HpSplitAttr)); } + // No one gets Memento or Final Gambit movePool = movePool.filter( m => !allMoves[m[0]].hasAttr(SacrificialAttrOnHit), ); @@ -3623,10 +3623,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { m[0], m[1] * (allMoves[m[0]].hasAttr(SacrificialAttr) ? 0.5 : 1), ]); - movePool = movePool.map(m => [ - m[0], - m[1] * (allMoves[m[0]].hasAttr(SacrificialAttrOnHit) ? 0.5 : 1), - ]); // Trainers get a weight bump to stat buffing moves movePool = movePool.map(m => [ m[0], @@ -3687,10 +3683,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { ]); /** The higher this is the more the game weights towards higher level moves. At `0` all moves are equal weight. */ - let weightMultiplier = 0.9; - if (this.hasTrainer()) { - weightMultiplier += 0.7; - } + let weightMultiplier = 1.6; if (this.isBoss()) { weightMultiplier += 0.4; } @@ -3699,37 +3692,21 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { Math.ceil(Math.pow(m[1], weightMultiplier) * 100), ]); - // Trainers and bosses always force a stab move - if (this.hasTrainer() || this.isBoss()) { - const stabMovePool = baseWeights.filter( - m => - allMoves[m[0]].category !== MoveCategory.STATUS && - this.isOfType(allMoves[m[0]].type), - ); + // All Pokemon force a STAB move first + const stabMovePool = baseWeights.filter( + m => + allMoves[m[0]].category !== MoveCategory.STATUS && + this.isOfType(allMoves[m[0]].type), + ); - if (stabMovePool.length) { - const totalWeight = stabMovePool.reduce((v, m) => v + m[1], 0); - let rand = randSeedInt(totalWeight); - let index = 0; - while (rand > stabMovePool[index][1]) { - rand -= stabMovePool[index++][1]; - } - this.moveset.push(new PokemonMove(stabMovePool[index][0], 0, 0)); - } - } else { - // Normal wild pokemon just force a random damaging move - const attackMovePool = baseWeights.filter( - m => allMoves[m[0]].category !== MoveCategory.STATUS, - ); - if (attackMovePool.length) { - const totalWeight = attackMovePool.reduce((v, m) => v + m[1], 0); - let rand = randSeedInt(totalWeight); - let index = 0; - while (rand > attackMovePool[index][1]) { - rand -= attackMovePool[index++][1]; - } - this.moveset.push(new PokemonMove(attackMovePool[index][0], 0, 0)); + if (stabMovePool.length) { + const totalWeight = stabMovePool.reduce((v, m) => v + m[1], 0); + let rand = randSeedInt(totalWeight); + let index = 0; + while (rand > stabMovePool[index][1]) { + rand -= stabMovePool[index++][1]; } + this.moveset.push(new PokemonMove(stabMovePool[index][0], 0, 0)); } while ( @@ -3741,7 +3718,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { // Other damaging moves 2x weight if 0-1 damaging moves, 0.5x if 2, 0.125x if 3. These weights get 20x if STAB. // Status moves remain unchanged on weight, this encourages 1-2 movePool = baseWeights - .filter(m => !this.moveset.some(mo => m[0] === mo.moveId)) + .filter(m => !this.moveset.some( + mo => + m[0] === mo.moveId || + (allMoves[m[0]].hasAttr(SacrificialAttr) && mo.getMove().hasAttr(SacrificialAttr)) // Only one self-KO move allowed + )) .map(m => { let ret: number; if ( @@ -3772,7 +3753,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { }); } else { // Non-trainer pokemon just use normal weights - movePool = baseWeights.filter(m => !this.moveset.some(mo => m[0] === mo.moveId)); + movePool = baseWeights.filter(m => !this.moveset.some( + mo => + m[0] === mo.moveId || + (allMoves[m[0]].hasAttr(SacrificialAttr) && mo.getMove().hasAttr(SacrificialAttr)) // Only one self-KO move allowed + )); } const totalWeight = movePool.reduce((v, m) => v + m[1], 0); let rand = randSeedInt(totalWeight); @@ -7104,7 +7089,6 @@ export class EnemyPokemon extends Pokemon { if (!dataSource) { this.generateAndPopulateMoveset(); - if (shinyLock || Overrides.OPP_SHINY_OVERRIDE === false) { this.shiny = false; } else { From 4a39adacf88fa9b13a98def0d6dbf10329daba38 Mon Sep 17 00:00:00 2001 From: damocleas Date: Tue, 20 May 2025 23:05:39 -0400 Subject: [PATCH 61/61] [UI/UX] Remove Redundant Unlock Passive text (#5845) * Update starter-select-ui-handler.ts * Update pokedex-page-ui-handler.ts --- src/ui/pokedex-page-ui-handler.ts | 2 +- src/ui/starter-select-ui-handler.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/pokedex-page-ui-handler.ts b/src/ui/pokedex-page-ui-handler.ts index ddc16ab5a88..051d267259f 100644 --- a/src/ui/pokedex-page-ui-handler.ts +++ b/src/ui/pokedex-page-ui-handler.ts @@ -1888,7 +1888,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler { if (!(passiveAttr & PassiveAttr.UNLOCKED)) { const passiveCost = getPassiveCandyCount(speciesStarterCosts[this.starterId]); options.push({ - label: `x${passiveCost} ${i18next.t("pokedexUiHandler:unlockPassive")} (${allAbilities[this.passive].name})`, + label: `x${passiveCost} ${i18next.t("pokedexUiHandler:unlockPassive")}`, handler: () => { if (Overrides.FREE_CANDY_UPGRADE_OVERRIDE || candyCount >= passiveCost) { starterData.passiveAttr |= PassiveAttr.UNLOCKED | PassiveAttr.ENABLED; diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index a35f426e8bd..f24a3ff9265 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -2184,7 +2184,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { if (!(passiveAttr & PassiveAttr.UNLOCKED)) { const passiveCost = getPassiveCandyCount(speciesStarterCosts[this.lastSpecies.speciesId]); options.push({ - label: `x${passiveCost} ${i18next.t("starterSelectUiHandler:unlockPassive")} (${allAbilities[this.lastSpecies.getPassiveAbility()].name})`, + label: `x${passiveCost} ${i18next.t("starterSelectUiHandler:unlockPassive")}`, handler: () => { if (Overrides.FREE_CANDY_UPGRADE_OVERRIDE || candyCount >= passiveCost) { starterData.passiveAttr |= PassiveAttr.UNLOCKED | PassiveAttr.ENABLED;

BLU%vKrrUolQO6XG-?` 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 Date: Fri, 2 May 2025 21:52:51 -0400 Subject: [PATCH 10/61] [Balance][Mystery][Beta] Salesman doesn't offer event mons without HA or shiny (#5746) Don't offer event mons without HA or shiny --- .../the-pokemon-salesman-encounter.ts | 46 +++++++++++++++---- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/src/data/mystery-encounters/encounters/the-pokemon-salesman-encounter.ts b/src/data/mystery-encounters/encounters/the-pokemon-salesman-encounter.ts index bab0c44db7d..25798de3b4a 100644 --- a/src/data/mystery-encounters/encounters/the-pokemon-salesman-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-pokemon-salesman-encounter.ts @@ -88,7 +88,7 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = MysteryEncounterBui const r = randSeedInt(SHINY_MAGIKARP_WEIGHT); - const validEventEncounters = timedEventManager + let validEventEncounters = timedEventManager .getEventEncounters() .filter( s => @@ -116,18 +116,44 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = MysteryEncounterBui // If you roll 1%, give shiny Magikarp with random variant species = getPokemonSpecies(Species.MAGIKARP); pokemon = new PlayerPokemon(species, 5, 2, undefined, undefined, true); - } else if ( + } + else if ( (validEventEncounters.length > 0 && (r <= EVENT_THRESHOLD || (isNullOrUndefined(species.abilityHidden) || species.abilityHidden === Abilities.NONE))) ) { - // If you roll 20%, give event encounter with 3 extra shiny rolls and its HA, if it has one - const enc = randSeedItem(validEventEncounters); - species = getPokemonSpecies(enc.species); - pokemon = new PlayerPokemon(species, 5, species.abilityHidden === Abilities.NONE ? undefined : 2, enc.formIndex); - pokemon.trySetShinySeed(); - pokemon.trySetShinySeed(); - pokemon.trySetShinySeed(); - } else { + tries = 0; + do { + // If you roll 20%, give event encounter with 3 extra shiny rolls and its HA, if it has one + const enc = randSeedItem(validEventEncounters); + species = getPokemonSpecies(enc.species); + pokemon = new PlayerPokemon(species, 5, species.abilityHidden === Abilities.NONE ? undefined : 2, enc.formIndex); + pokemon.trySetShinySeed(); + pokemon.trySetShinySeed(); + pokemon.trySetShinySeed(); + if (pokemon.shiny || pokemon.abilityIndex === 2) { + break; + } + tries++; + } while (tries < 6); + if (!pokemon.shiny && pokemon.abilityIndex !== 2) { + // If, after 6 tries, you STILL somehow don't have an HA or shiny mon, pick from only the event mons that have an HA. + if (validEventEncounters.some(s => !!getPokemonSpecies(s.species).abilityHidden)) { + validEventEncounters.filter(s => !!getPokemonSpecies(s.species).abilityHidden); + const enc = randSeedItem(validEventEncounters); + species = getPokemonSpecies(enc.species); + pokemon = new PlayerPokemon(species, 5, 2, enc.formIndex); + pokemon.trySetShinySeed(); + pokemon.trySetShinySeed(); + pokemon.trySetShinySeed(); + } + else { + // If there's, and this would never happen, no eligible event encounters with a hidden ability, just do Magikarp + species = getPokemonSpecies(Species.MAGIKARP); + pokemon = new PlayerPokemon(species, 5, 2, undefined, undefined, true); + } + } + } + else { pokemon = new PlayerPokemon(species, 5, 2, species.formIndex); } pokemon.generateAndPopulateMoveset(); From cedeaf866852e57c54899838dea4aa8346c6b2c6 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Fri, 2 May 2025 19:55:48 -0700 Subject: [PATCH 11/61] [Bug] Fix crash when loading a save with a statused Pokemon (#5756) --- src/system/pokemon-data.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/system/pokemon-data.ts b/src/system/pokemon-data.ts index 7e71dffde5e..ef1f30830f0 100644 --- a/src/system/pokemon-data.ts +++ b/src/system/pokemon-data.ts @@ -4,7 +4,7 @@ import type { Gender } from "../data/gender"; import { Nature } from "#enums/nature"; import { PokeballType } from "#enums/pokeball"; import { getPokemonSpecies, getPokemonSpeciesForm } from "../data/pokemon-species"; -import type { Status } from "../data/status-effect"; +import { Status } from "../data/status-effect"; import Pokemon, { EnemyPokemon, PokemonBattleData, PokemonMove, PokemonSummonData } from "../field/pokemon"; import { TrainerSlot } from "#enums/trainer-slot"; import type { Variant } from "#app/sprites/variant"; @@ -105,7 +105,9 @@ export default class PokemonData { // TODO: Can't we move some of this verification stuff to an upgrade script? this.nature = source.nature ?? Nature.HARDY; this.moveset = source.moveset.map((m: any) => PokemonMove.loadMove(m)); - this.status = source.status ?? null; + this.status = source.status + ? new Status(source.status.effect, source.status.toxicTurnCount, source.status.sleepTurnsRemaining) + : null; this.friendship = source.friendship ?? getPokemonSpecies(this.species).baseFriendship; this.metLevel = source.metLevel || 5; this.metBiome = source.metBiome ?? -1; From 9283be652d421257fb818d9498bdc35e679559a3 Mon Sep 17 00:00:00 2001 From: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Date: Sat, 3 May 2025 03:47:04 -0500 Subject: [PATCH 12/61] [GitHub] Create release action workflows (#5743) * Create release actions * Add release branch to push/pull events that invoke test workflows --- .github/workflows/create-release.yml | 73 ++++++++++++++++++++++ .github/workflows/deploy-beta.yml | 15 +++-- .github/workflows/post-release-deleted.yml | 12 ++++ .github/workflows/tests.yml | 2 + 4 files changed, 97 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/create-release.yml create mode 100644 .github/workflows/post-release-deleted.yml diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml new file mode 100644 index 00000000000..35a31f6b4d1 --- /dev/null +++ b/.github/workflows/create-release.yml @@ -0,0 +1,73 @@ +name: Create Release Branch +on: + workflow_dispatch: + inputs: + versionName: + description: "Name of version (i.e. 1.9.0)" + type: string + required: true + confirmVersion: + type: string + required: true + description: "Confirm version name" + +# explicitly specify the necessary scopes +permissions: + pull-requests: write + actions: write + contents: write + +jobs: + create-release: + if: github.repository == 'pagefaultgames/pokerogue' && (vars.BETA_DEPLOY_BRANCH == '' || ! startsWith(vars.BETA_DEPLOY_BRANCH, 'release')) + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed for github cli commands + runs-on: ubuntu-latest + steps: + - name: Validate provided version + # Ensure version matches confirmation and conforms to expected pattern. + run: | + if [[ "${{ github.event.inputs.versionName }}" != "${{ github.event.inputs.confirmVersion }}" ]]; then + echo "Version name does not match confirmation. Exiting." + exit 1 + fi + if [[ ! "${{ github.event.inputs.versionName }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Version name must follow the format X.Y.Z where X, Y, and Z are all numbers. Exiting..." + exit 1 + fi + shell: bash + - name: Check out code + uses: actions/checkout@v4 + with: + submodules: "recursive" + # Always base off of beta branch, regardless of the branch the workflow was triggered from. + ref: beta + - name: Create release branch + run: git checkout -b release + # In order to be able to open a PR into beta, we need the branch to have at least one change. + - name: Overwrite RELEASE file + run: | + git config --local user.name "github-actions[bot]" + git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + echo "Release v${{ github.event.inputs.versionName }}" > RELEASE + git add RELEASE + git commit -m "Stage release v${{ github.event.inputs.versionName }}" + - name: Push new branch + run: git push origin release + # The repository variable is used by the deploy-beta workflow to determine whether to deploy from beta or release. + - name: Set repository variable + run: GITHUB_TOKEN="${{ secrets.RW_VARS_PAT }}" gh variable set BETA_DEPLOY_BRANCH --body "release" + - name: Create pull request to main + run: | + gh pr create --base main \ + --head release \ + --title "Release v${{ github.event.inputs.versionName }} to main" \ + --body "This PR is for the release of v${{ github.event.inputs.versionName }}, and was created automatically by the GitHub Actions workflow invoked by ${{ github.actor }}" \ + --draft + - name: Create pull request to beta + run: | + gh pr create --base beta \ + --head release \ + --title "Release v${{ github.event.inputs.versionName }} to beta" \ + --body "This PR is for the release of v${{ github.event.inputs.versionName }}, and was created automatically by the GitHub Actions workflow invoked by ${{ github.actor }}" \ + --draft diff --git a/.github/workflows/deploy-beta.yml b/.github/workflows/deploy-beta.yml index 8b0e33a18c4..90b3008c8e9 100644 --- a/.github/workflows/deploy-beta.yml +++ b/.github/workflows/deploy-beta.yml @@ -4,18 +4,23 @@ on: push: branches: - beta + - release + workflow_run: + types: completed + workflows: ["Post Release Deleted"] jobs: deploy: - if: github.repository == 'pagefaultgames/pokerogue' + if: github.repository == 'pagefaultgames/pokerogue' && github.ref_name == ${{ vars.BETA_DEPLOY_BRANCH || 'beta' }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: - submodules: 'recursive' + submodules: "recursive" + ref: ${{ vars.BETA_DEPLOY_BRANCH || 'beta'}} - uses: actions/setup-node@v4 with: - node-version-file: '.nvmrc' + node-version-file: ".nvmrc" - name: Install dependencies run: npm ci - name: Build @@ -30,5 +35,5 @@ jobs: chmod 600 ~/.ssh/* ssh-keyscan -H ${{ secrets.BETA_SSH_HOST }} >> ~/.ssh/known_hosts - name: Deploy build on server - run: | - rsync --del --no-times --checksum -vrm dist/* ${{ secrets.BETA_SSH_USER }}@${{ secrets.BETA_SSH_HOST }}:${{ secrets.BETA_DESTINATION_DIR }} \ No newline at end of file + run: | + rsync --del --no-times --checksum -vrm dist/* ${{ secrets.BETA_SSH_USER }}@${{ secrets.BETA_SSH_HOST }}:${{ secrets.BETA_DESTINATION_DIR }} diff --git a/.github/workflows/post-release-deleted.yml b/.github/workflows/post-release-deleted.yml new file mode 100644 index 00000000000..65447e7826b --- /dev/null +++ b/.github/workflows/post-release-deleted.yml @@ -0,0 +1,12 @@ +name: Post Release Deleted +on: + delete: + +jobs: + # Set the BETA_DEPLOY_BRANCH variable to beta when a release branch is deleted + update-release-var: + if: github.repository == 'pagefaultgames/pokerogue' && github.event.ref_type == 'branch' && github.event.ref == 'release' + runs-on: ubuntu-latest + steps: + - name: Set BETA_DEPLOY_BRANCH to beta + run: GITHUB_TOKEN="${{ secrets.RW_VARS_PAT }}" gh variable set BETA_DEPLOY_BRANCH --body "beta" --repo "pagefaultgames/pokerogue" \ No newline at end of file diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ccc8604ff7e..d9db8401f8e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -7,6 +7,7 @@ on: branches: - main # Trigger on push events to the main branch - beta # Trigger on push events to the beta branch + - release # Trigger on push events to the release branch # go upvote https://github.com/actions/runner/issues/1182 and yell at microsoft until they fix this or ditch yml for workflows paths: # src and test files @@ -32,6 +33,7 @@ on: branches: - main # Trigger on pull request events targeting the main branch - beta # Trigger on pull request events targeting the beta branch + - release # Trigger on pull request events targeting the release branch paths: # go upvote https://github.com/actions/runner/issues/1182 and yell at microsoft because until then we have to duplicate this # src and test files - "src/**" From a5311779b4aafa42bf577d1136a2c7b086bd56f8 Mon Sep 17 00:00:00 2001 From: damocleas Date: Sat, 3 May 2025 12:59:55 -0400 Subject: [PATCH 13/61] [Misc] More Spring (#5759) extendo evento --- src/timed-event-manager.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/timed-event-manager.ts b/src/timed-event-manager.ts index 951d98aefec..163afdc098b 100644 --- a/src/timed-event-manager.ts +++ b/src/timed-event-manager.ts @@ -313,8 +313,8 @@ const timedEvents: TimedEvent[] = [ { name: "Shining Spring", eventType: EventType.SHINY, - startDate: new Date(Date.UTC(2025, 4, 2)), - endDate: new Date(Date.UTC(2025, 4, 12)), + startDate: new Date(Date.UTC(2025, 4, 3)), + endDate: new Date(Date.UTC(2025, 4, 13)), bannerKey: "spr25event", scale: 0.21, availableLangs: ["en", "de", "it", "fr", "ja", "ko", "es-ES", "es-MX", "pt-BR", "zh-CN"], From 1042b528ecfe1ada2bd684ef19dd91027f3b3c00 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 3 May 2025 13:07:37 -0400 Subject: [PATCH 14/61] Bump vite from 6.2.4 to 6.3.4 (#5758) * Bump vite from 6.2.4 to 6.3.4 Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 6.2.4 to 6.3.4. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v6.3.4/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-version: 6.3.4 dependency-type: direct:development ... Signed-off-by: dependabot[bot] * Update `rollup` version in `package-lock.json` --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- package-lock.json | 212 +++++++++++++++++++++++++++------------------- package.json | 2 +- 2 files changed, 125 insertions(+), 89 deletions(-) diff --git a/package-lock.json b/package-lock.json index f9280ad594b..da00292e7b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,10 +39,11 @@ "lefthook": "^1.11.5", "msw": "^2.7.3", "phaser3spectorjs": "^0.0.8", + "rollup": "^4.40.1", "typedoc": "^0.28.1", "typescript": "^5.8.2", "typescript-eslint": "^8.28.0", - "vite": "^6.2.0", + "vite": "^6.3.4", "vite-tsconfig-paths": "^5.1.4", "vitest": "^3.0.9", "vitest-canvas-mock": "^0.3.3" @@ -2161,9 +2162,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.38.0.tgz", - "integrity": "sha512-ldomqc4/jDZu/xpYU+aRxo3V4mGCV9HeTgUBANI3oIQMOL+SsxB+S2lxMpkFp5UamSS3XuTMQVbsS24R4J4Qjg==", + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.1.tgz", + "integrity": "sha512-kxz0YeeCrRUHz3zyqvd7n+TVRlNyTifBsmnmNPtk3hQURUyG9eAB+usz6DAwagMusjx/zb3AjvDUvhFGDAexGw==", "cpu": [ "arm" ], @@ -2175,9 +2176,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.38.0.tgz", - "integrity": "sha512-VUsgcy4GhhT7rokwzYQP+aV9XnSLkkhlEJ0St8pbasuWO/vwphhZQxYEKUP3ayeCYLhk6gEtacRpYP/cj3GjyQ==", + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.40.1.tgz", + "integrity": "sha512-PPkxTOisoNC6TpnDKatjKkjRMsdaWIhyuMkA4UsBXT9WEZY4uHezBTjs6Vl4PbqQQeu6oION1w2voYZv9yquCw==", "cpu": [ "arm64" ], @@ -2189,9 +2190,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.38.0.tgz", - "integrity": "sha512-buA17AYXlW9Rn091sWMq1xGUvWQFOH4N1rqUxGJtEQzhChxWjldGCCup7r/wUnaI6Au8sKXpoh0xg58a7cgcpg==", + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.40.1.tgz", + "integrity": "sha512-VWXGISWFY18v/0JyNUy4A46KCFCb9NVsH+1100XP31lud+TzlezBbz24CYzbnA4x6w4hx+NYCXDfnvDVO6lcAA==", "cpu": [ "arm64" ], @@ -2203,9 +2204,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.38.0.tgz", - "integrity": "sha512-Mgcmc78AjunP1SKXl624vVBOF2bzwNWFPMP4fpOu05vS0amnLcX8gHIge7q/lDAHy3T2HeR0TqrriZDQS2Woeg==", + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.40.1.tgz", + "integrity": "sha512-nIwkXafAI1/QCS7pxSpv/ZtFW6TXcNUEHAIA9EIyw5OzxJZQ1YDrX+CL6JAIQgZ33CInl1R6mHet9Y/UZTg2Bw==", "cpu": [ "x64" ], @@ -2217,9 +2218,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.38.0.tgz", - "integrity": "sha512-zzJACgjLbQTsscxWqvrEQAEh28hqhebpRz5q/uUd1T7VTwUNZ4VIXQt5hE7ncs0GrF+s7d3S4on4TiXUY8KoQA==", + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.40.1.tgz", + "integrity": "sha512-BdrLJ2mHTrIYdaS2I99mriyJfGGenSaP+UwGi1kB9BLOCu9SR8ZpbkmmalKIALnRw24kM7qCN0IOm6L0S44iWw==", "cpu": [ "arm64" ], @@ -2231,9 +2232,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.38.0.tgz", - "integrity": "sha512-hCY/KAeYMCyDpEE4pTETam0XZS4/5GXzlLgpi5f0IaPExw9kuB+PDTOTLuPtM10TlRG0U9OSmXJ+Wq9J39LvAg==", + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.40.1.tgz", + "integrity": "sha512-VXeo/puqvCG8JBPNZXZf5Dqq7BzElNJzHRRw3vjBE27WujdzuOPecDPc/+1DcdcTptNBep3861jNq0mYkT8Z6Q==", "cpu": [ "x64" ], @@ -2245,9 +2246,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.38.0.tgz", - "integrity": "sha512-mimPH43mHl4JdOTD7bUMFhBdrg6f9HzMTOEnzRmXbOZqjijCw8LA5z8uL6LCjxSa67H2xiLFvvO67PT05PRKGg==", + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.40.1.tgz", + "integrity": "sha512-ehSKrewwsESPt1TgSE/na9nIhWCosfGSFqv7vwEtjyAqZcvbGIg4JAcV7ZEh2tfj/IlfBeZjgOXm35iOOjadcg==", "cpu": [ "arm" ], @@ -2259,9 +2260,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.38.0.tgz", - "integrity": "sha512-tPiJtiOoNuIH8XGG8sWoMMkAMm98PUwlriOFCCbZGc9WCax+GLeVRhmaxjJtz6WxrPKACgrwoZ5ia/uapq3ZVg==", + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.40.1.tgz", + "integrity": "sha512-m39iO/aaurh5FVIu/F4/Zsl8xppd76S4qoID8E+dSRQvTyZTOI2gVk3T4oqzfq1PtcvOfAVlwLMK3KRQMaR8lg==", "cpu": [ "arm" ], @@ -2273,9 +2274,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.38.0.tgz", - "integrity": "sha512-wZco59rIVuB0tjQS0CSHTTUcEde+pXQWugZVxWaQFdQQ1VYub/sTrNdY76D1MKdN2NB48JDuGABP6o6fqos8mA==", + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.40.1.tgz", + "integrity": "sha512-Y+GHnGaku4aVLSgrT0uWe2o2Rq8te9hi+MwqGF9r9ORgXhmHK5Q71N757u0F8yU1OIwUIFy6YiJtKjtyktk5hg==", "cpu": [ "arm64" ], @@ -2287,9 +2288,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.38.0.tgz", - "integrity": "sha512-fQgqwKmW0REM4LomQ+87PP8w8xvU9LZfeLBKybeli+0yHT7VKILINzFEuggvnV9M3x1Ed4gUBmGUzCo/ikmFbQ==", + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.40.1.tgz", + "integrity": "sha512-jEwjn3jCA+tQGswK3aEWcD09/7M5wGwc6+flhva7dsQNRZZTe30vkalgIzV4tjkopsTS9Jd7Y1Bsj6a4lzz8gQ==", "cpu": [ "arm64" ], @@ -2301,9 +2302,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.38.0.tgz", - "integrity": "sha512-hz5oqQLXTB3SbXpfkKHKXLdIp02/w3M+ajp8p4yWOWwQRtHWiEOCKtc9U+YXahrwdk+3qHdFMDWR5k+4dIlddg==", + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.40.1.tgz", + "integrity": "sha512-ySyWikVhNzv+BV/IDCsrraOAZ3UaC8SZB67FZlqVwXwnFhPihOso9rPOxzZbjp81suB1O2Topw+6Ug3JNegejQ==", "cpu": [ "loong64" ], @@ -2315,9 +2316,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.38.0.tgz", - "integrity": "sha512-NXqygK/dTSibQ+0pzxsL3r4Xl8oPqVoWbZV9niqOnIHV/J92fe65pOir0xjkUZDRSPyFRvu+4YOpJF9BZHQImw==", + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.40.1.tgz", + "integrity": "sha512-BvvA64QxZlh7WZWqDPPdt0GH4bznuL6uOO1pmgPnnv86rpUpc8ZxgZwcEgXvo02GRIZX1hQ0j0pAnhwkhwPqWg==", "cpu": [ "ppc64" ], @@ -2329,9 +2330,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.38.0.tgz", - "integrity": "sha512-GEAIabR1uFyvf/jW/5jfu8gjM06/4kZ1W+j1nWTSSB3w6moZEBm7iBtzwQ3a1Pxos2F7Gz+58aVEnZHU295QTg==", + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.40.1.tgz", + "integrity": "sha512-EQSP+8+1VuSulm9RKSMKitTav89fKbHymTf25n5+Yr6gAPZxYWpj3DzAsQqoaHAk9YX2lwEyAf9S4W8F4l3VBQ==", "cpu": [ "riscv64" ], @@ -2343,9 +2344,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.38.0.tgz", - "integrity": "sha512-9EYTX+Gus2EGPbfs+fh7l95wVADtSQyYw4DfSBcYdUEAmP2lqSZY0Y17yX/3m5VKGGJ4UmIH5LHLkMJft3bYoA==", + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.40.1.tgz", + "integrity": "sha512-n/vQ4xRZXKuIpqukkMXZt9RWdl+2zgGNx7Uda8NtmLJ06NL8jiHxUawbwC+hdSq1rrw/9CghCpEONor+l1e2gA==", "cpu": [ "riscv64" ], @@ -2357,9 +2358,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.38.0.tgz", - "integrity": "sha512-Mpp6+Z5VhB9VDk7RwZXoG2qMdERm3Jw07RNlXHE0bOnEeX+l7Fy4bg+NxfyN15ruuY3/7Vrbpm75J9QHFqj5+Q==", + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.40.1.tgz", + "integrity": "sha512-h8d28xzYb98fMQKUz0w2fMc1XuGzLLjdyxVIbhbil4ELfk5/orZlSTpF/xdI9C8K0I8lCkq+1En2RJsawZekkg==", "cpu": [ "s390x" ], @@ -2371,9 +2372,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.38.0.tgz", - "integrity": "sha512-vPvNgFlZRAgO7rwncMeE0+8c4Hmc+qixnp00/Uv3ht2x7KYrJ6ERVd3/R0nUtlE6/hu7/HiiNHJ/rP6knRFt1w==", + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.1.tgz", + "integrity": "sha512-XiK5z70PEFEFqcNj3/zRSz/qX4bp4QIraTy9QjwJAb/Z8GM7kVUsD0Uk8maIPeTyPCP03ChdI+VVmJriKYbRHQ==", "cpu": [ "x64" ], @@ -2385,9 +2386,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.38.0.tgz", - "integrity": "sha512-q5Zv+goWvQUGCaL7fU8NuTw8aydIL/C9abAVGCzRReuj5h30TPx4LumBtAidrVOtXnlB+RZkBtExMsfqkMfb8g==", + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.40.1.tgz", + "integrity": "sha512-2BRORitq5rQ4Da9blVovzNCMaUlyKrzMSvkVR0D4qPuOy/+pMCrh1d7o01RATwVy+6Fa1WBw+da7QPeLWU/1mQ==", "cpu": [ "x64" ], @@ -2399,9 +2400,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.38.0.tgz", - "integrity": "sha512-u/Jbm1BU89Vftqyqbmxdq14nBaQjQX1HhmsdBWqSdGClNaKwhjsg5TpW+5Ibs1mb8Es9wJiMdl86BcmtUVXNZg==", + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.40.1.tgz", + "integrity": "sha512-b2bcNm9Kbde03H+q+Jjw9tSfhYkzrDUf2d5MAd1bOJuVplXvFhWz7tRtWvD8/ORZi7qSCy0idW6tf2HgxSXQSg==", "cpu": [ "arm64" ], @@ -2413,9 +2414,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.38.0.tgz", - "integrity": "sha512-mqu4PzTrlpNHHbu5qleGvXJoGgHpChBlrBx/mEhTPpnAL1ZAYFlvHD7rLK839LLKQzqEQMFJfGrrOHItN4ZQqA==", + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.40.1.tgz", + "integrity": "sha512-DfcogW8N7Zg7llVEfpqWMZcaErKfsj9VvmfSyRjCyo4BI3wPEfrzTtJkZG6gKP/Z92wFm6rz2aDO7/JfiR/whA==", "cpu": [ "ia32" ], @@ -2427,9 +2428,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.38.0.tgz", - "integrity": "sha512-jjqy3uWlecfB98Psxb5cD6Fny9Fupv9LrDSPTQZUROqjvZmcCqNu4UMl7qqhlUUGpwiAkotj6GYu4SZdcr/nLw==", + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.1.tgz", + "integrity": "sha512-ECyOuDeH3C1I8jH2MK1RtBJW+YPMvSfT0a5NN0nHfQYnDSJ6tUiZH3gzwVP5/Kfh/+Tt7tpWVF9LXNTnhTJ3kA==", "cpu": [ "x64" ], @@ -4427,6 +4428,21 @@ "reusify": "^1.0.4" } }, + "node_modules/fdir": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", + "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -6559,9 +6575,9 @@ } }, "node_modules/rollup": { - "version": "4.38.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.38.0.tgz", - "integrity": "sha512-5SsIRtJy9bf1ErAOiFMFzl64Ex9X5V7bnJ+WlFMb+zmP459OSWCEG7b0ERZ+PEU7xPt4OG3RHbrp1LJlXxYTrw==", + "version": "4.40.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.1.tgz", + "integrity": "sha512-C5VvvgCCyfyotVITIAv+4efVytl5F7wt+/I2i9q9GZcEXW9BP52YYOXC58igUi+LFZVHukErIIqQSWwv/M3WRw==", "dev": true, "license": "MIT", "dependencies": { @@ -6575,26 +6591,26 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.38.0", - "@rollup/rollup-android-arm64": "4.38.0", - "@rollup/rollup-darwin-arm64": "4.38.0", - "@rollup/rollup-darwin-x64": "4.38.0", - "@rollup/rollup-freebsd-arm64": "4.38.0", - "@rollup/rollup-freebsd-x64": "4.38.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.38.0", - "@rollup/rollup-linux-arm-musleabihf": "4.38.0", - "@rollup/rollup-linux-arm64-gnu": "4.38.0", - "@rollup/rollup-linux-arm64-musl": "4.38.0", - "@rollup/rollup-linux-loongarch64-gnu": "4.38.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.38.0", - "@rollup/rollup-linux-riscv64-gnu": "4.38.0", - "@rollup/rollup-linux-riscv64-musl": "4.38.0", - "@rollup/rollup-linux-s390x-gnu": "4.38.0", - "@rollup/rollup-linux-x64-gnu": "4.38.0", - "@rollup/rollup-linux-x64-musl": "4.38.0", - "@rollup/rollup-win32-arm64-msvc": "4.38.0", - "@rollup/rollup-win32-ia32-msvc": "4.38.0", - "@rollup/rollup-win32-x64-msvc": "4.38.0", + "@rollup/rollup-android-arm-eabi": "4.40.1", + "@rollup/rollup-android-arm64": "4.40.1", + "@rollup/rollup-darwin-arm64": "4.40.1", + "@rollup/rollup-darwin-x64": "4.40.1", + "@rollup/rollup-freebsd-arm64": "4.40.1", + "@rollup/rollup-freebsd-x64": "4.40.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.40.1", + "@rollup/rollup-linux-arm-musleabihf": "4.40.1", + "@rollup/rollup-linux-arm64-gnu": "4.40.1", + "@rollup/rollup-linux-arm64-musl": "4.40.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.40.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.40.1", + "@rollup/rollup-linux-riscv64-gnu": "4.40.1", + "@rollup/rollup-linux-riscv64-musl": "4.40.1", + "@rollup/rollup-linux-s390x-gnu": "4.40.1", + "@rollup/rollup-linux-x64-gnu": "4.40.1", + "@rollup/rollup-linux-x64-musl": "4.40.1", + "@rollup/rollup-win32-arm64-msvc": "4.40.1", + "@rollup/rollup-win32-ia32-msvc": "4.40.1", + "@rollup/rollup-win32-x64-msvc": "4.40.1", "fsevents": "~2.3.2" } }, @@ -7043,6 +7059,23 @@ "dev": true, "license": "MIT" }, + "node_modules/tinyglobby": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz", + "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, "node_modules/tinypool": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", @@ -7413,15 +7446,18 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/vite": { - "version": "6.2.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.4.tgz", - "integrity": "sha512-veHMSew8CcRzhL5o8ONjy8gkfmFJAd5Ac16oxBUjlwgX3Gq2Wqr+qNC3TjPIpy7TPV/KporLga5GT9HqdrCizw==", + "version": "6.3.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.4.tgz", + "integrity": "sha512-BiReIiMS2fyFqbqNT/Qqt4CVITDU9M9vE+DKcVAsB+ZV0wvTKd+3hMbkpxz1b+NmEDMegpVbisKiAZOnvO92Sw==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", "postcss": "^8.5.3", - "rollup": "^4.30.1" + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" }, "bin": { "vite": "bin/vite.js" diff --git a/package.json b/package.json index b9ccb324969..8504db8d0d8 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "typedoc": "^0.28.1", "typescript": "^5.8.2", "typescript-eslint": "^8.28.0", - "vite": "^6.2.0", + "vite": "^6.3.4", "vite-tsconfig-paths": "^5.1.4", "vitest": "^3.0.9", "vitest-canvas-mock": "^0.3.3" From 04bfaf901a30b56d0b5de59e2731f51600b60196 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Sat, 3 May 2025 19:59:49 -0700 Subject: [PATCH 15/61] Update version to 1.9.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index da00292e7b8..9d9b7638997 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pokemon-rogue-battle", - "version": "1.9.0", + "version": "1.9.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pokemon-rogue-battle", - "version": "1.9.0", + "version": "1.9.1", "hasInstallScript": true, "dependencies": { "@material/material-color-utilities": "^0.2.7", diff --git a/package.json b/package.json index 8504db8d0d8..6bde0af2fa5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "pokemon-rogue-battle", "private": true, - "version": "1.9.0", + "version": "1.9.1", "type": "module", "scripts": { "start": "vite", From b5cfa88455d4c7d319ea257f3e003cb77ed9eeb6 Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Sat, 3 May 2025 23:07:50 -0400 Subject: [PATCH 16/61] [Tiny] Removed unused loc in `v1_9_0.ts` (#5760) --- src/system/version_migration/versions/v1_9_0.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/system/version_migration/versions/v1_9_0.ts b/src/system/version_migration/versions/v1_9_0.ts index 9505a7138f8..dca92cd1fae 100644 --- a/src/system/version_migration/versions/v1_9_0.ts +++ b/src/system/version_migration/versions/v1_9_0.ts @@ -15,11 +15,6 @@ const migratePartyData: SessionSaveMigrator = { migrate: (data: SessionSaveData): void => { // this stuff is copied straight from the constructor fwiw const mapParty = (pkmnData: PokemonData) => { - pkmnData.status &&= new Status( - pkmnData.status.effect, - pkmnData.status.toxicTurnCount, - pkmnData.status.sleepTurnsRemaining, - ); // remove empty moves from moveset pkmnData.moveset = (pkmnData.moveset ?? [new PokemonMove(Moves.TACKLE), new PokemonMove(Moves.GROWL)]) .filter(m => !!m) From 9e433c85a9f6ddaa7a7352b150798c3b435d8b87 Mon Sep 17 00:00:00 2001 From: damocleas Date: Sat, 3 May 2025 23:19:18 -0400 Subject: [PATCH 17/61] Add missing zh-CN Spring Banner --- public/images/events/spr25event-zh-CN.png | Bin 0 -> 36886 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 public/images/events/spr25event-zh-CN.png diff --git a/public/images/events/spr25event-zh-CN.png b/public/images/events/spr25event-zh-CN.png new file mode 100644 index 0000000000000000000000000000000000000000..1d8ad35c166691210ac84028cac00194fc9d71a9 GIT binary patch literal 36886 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 z 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 Date: Sun, 4 May 2025 01:59:37 -0400 Subject: [PATCH 18/61] [Hotfix] Fix evil grunts using wrong template (#5763) --- src/data/trainers/TrainerPartyTemplate.ts | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/data/trainers/TrainerPartyTemplate.ts b/src/data/trainers/TrainerPartyTemplate.ts index 1952bcc179e..ccc494218e9 100644 --- a/src/data/trainers/TrainerPartyTemplate.ts +++ b/src/data/trainers/TrainerPartyTemplate.ts @@ -224,18 +224,19 @@ export const trainerPartyTemplates = { */ export function getEvilGruntPartyTemplate(): TrainerPartyTemplate { const waveIndex = globalScene.currentBattle?.waveIndex; - switch (waveIndex) { - case ClassicFixedBossWaves.EVIL_GRUNT_1: - return trainerPartyTemplates.TWO_AVG; - case ClassicFixedBossWaves.EVIL_GRUNT_2: - return trainerPartyTemplates.THREE_AVG; - case ClassicFixedBossWaves.EVIL_GRUNT_3: - return trainerPartyTemplates.TWO_AVG_ONE_STRONG; - case ClassicFixedBossWaves.EVIL_ADMIN_1: - return trainerPartyTemplates.GYM_LEADER_4; // 3avg 1 strong 1 stronger - default: - return trainerPartyTemplates.GYM_LEADER_5; // 3 avg 2 strong 1 stronger + if (waveIndex <= ClassicFixedBossWaves.EVIL_GRUNT_1){ + return trainerPartyTemplates.TWO_AVG; } + if (waveIndex <= ClassicFixedBossWaves.EVIL_GRUNT_2){ + return trainerPartyTemplates.THREE_AVG; + } + if (waveIndex <= ClassicFixedBossWaves.EVIL_GRUNT_3){ + return trainerPartyTemplates.TWO_AVG_ONE_STRONG; + } + if (waveIndex <= ClassicFixedBossWaves.EVIL_ADMIN_1){ + return trainerPartyTemplates.GYM_LEADER_4; // 3avg 1 strong 1 stronger + } + return trainerPartyTemplates.GYM_LEADER_5; // 3 avg 2 strong 1 stronger } export function getWavePartyTemplate(...templates: TrainerPartyTemplate[]) { From c31bd9ef61f02946963647a6af752bcd412a0a47 Mon Sep 17 00:00:00 2001 From: Dean <69436131+emdeann@users.noreply.github.com> Date: Sat, 3 May 2025 23:04:04 -0700 Subject: [PATCH 19/61] [Bug][Hotfix] Secondary effects no longer trigger status immunity messages (#5764) Fix secondary effects triggering status immunity messages --- src/data/moves/move.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/data/moves/move.ts b/src/data/moves/move.ts index d09613123bb..3ef70fd75be 100644 --- a/src/data/moves/move.ts +++ b/src/data/moves/move.ts @@ -2454,13 +2454,14 @@ export class StatusEffectAttr extends MoveEffectAttr { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { const moveChance = this.getMoveChance(user, target, move, this.selfTarget, true); const statusCheck = moveChance < 0 || moveChance === 100 || user.randSeedInt(100) < moveChance; + const quiet = move.category !== MoveCategory.STATUS; if (statusCheck) { const pokemon = this.selfTarget ? user : target; - if (user !== target && move.category === MoveCategory.STATUS && !target.canSetStatus(this.effect, false, false, user, true)) { + if (user !== target && move.category === MoveCategory.STATUS && !target.canSetStatus(this.effect, quiet, false, user, true)) { return false; } if (((!pokemon.status || this.overrideStatus) || (pokemon.status.effect === this.effect && moveChance < 0)) - && pokemon.trySetStatus(this.effect, true, user, this.turnsRemaining, null, this.overrideStatus, false)) { + && pokemon.trySetStatus(this.effect, true, user, this.turnsRemaining, null, this.overrideStatus, quiet)) { applyPostAttackAbAttrs(ConfusionOnStatusEffectAbAttr, user, target, move, null, false, this.effect); return true; } From fa774268ca81070f9155442acd8d08bfcbb6b8f3 Mon Sep 17 00:00:00 2001 From: damocleas Date: Sun, 4 May 2025 10:36:57 -0400 Subject: [PATCH 20/61] Add files via upload --- public/images/events/spr25event-fr.png | Bin 30245 -> 30270 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/public/images/events/spr25event-fr.png b/public/images/events/spr25event-fr.png index e7089eee4a1f32547f8364089468072177ad361d..7730e16d4a39f547a426e8e2d21533b2b4deacc5 100644 GIT binary patch delta 9602 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