From ca3cc3c9c6a569572942516f72edd8610c76b6c5 Mon Sep 17 00:00:00 2001 From: PigeonBar <56974298+PigeonBar@users.noreply.github.com> Date: Thu, 10 Oct 2024 11:28:26 -0400 Subject: [PATCH 01/37] [P1 Bug] Fix infinite recursion from abilities disabled by Sheer Force (#4631) --- src/field/pokemon.ts | 4 ++-- src/test/abilities/sheer_force.test.ts | 27 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 241524df1b9..35f389b58a4 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -1417,10 +1417,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @returns {boolean} Whether the ability is present and active */ hasAbility(ability: Abilities, canApply: boolean = true, ignoreOverride?: boolean): boolean { - if ((!canApply || this.canApplyAbility()) && this.getAbility(ignoreOverride).id === ability) { + if (this.getAbility(ignoreOverride).id === ability && (!canApply || this.canApplyAbility())) { return true; } - if (this.hasPassive() && (!canApply || this.canApplyAbility(true)) && this.getPassiveAbility().id === ability) { + if (this.getPassiveAbility().id === ability && this.hasPassive() && (!canApply || this.canApplyAbility(true))) { return true; } return false; diff --git a/src/test/abilities/sheer_force.test.ts b/src/test/abilities/sheer_force.test.ts index a3add0a9964..a2600476d6d 100644 --- a/src/test/abilities/sheer_force.test.ts +++ b/src/test/abilities/sheer_force.test.ts @@ -9,6 +9,7 @@ import { Species } from "#enums/species"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { allMoves } from "#app/data/move"; describe("Abilities - Sheer Force", () => { @@ -174,5 +175,31 @@ describe("Abilities - Sheer Force", () => { }, 20000); + it("Two Pokemon with abilities disabled by Sheer Force hitting each other should not cause a crash", async () => { + const moveToUse = Moves.CRUNCH; + game.override.enemyAbility(Abilities.COLOR_CHANGE) + .ability(Abilities.COLOR_CHANGE) + .moveset(moveToUse) + .enemyMoveset(moveToUse); + + await game.classicMode.startBattle([ + Species.PIDGEOT + ]); + + const pidgeot = game.scene.getParty()[0]; + const onix = game.scene.getEnemyParty()[0]; + + pidgeot.stats[Stat.DEF] = 10000; + onix.stats[Stat.DEF] = 10000; + + game.move.select(moveToUse); + await game.toNextTurn(); + + // Check that both Pokemon's Color Change activated + const expectedTypes = [ allMoves[moveToUse].type ]; + expect(pidgeot.getTypes()).toStrictEqual(expectedTypes); + expect(onix.getTypes()).toStrictEqual(expectedTypes); + }); + //TODO King's Rock Interaction Unit Test }); From 52257def2fa65aa09018800b29e89864572fc8b0 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Thu, 10 Oct 2024 08:30:19 -0700 Subject: [PATCH 02/37] [P3] Fix enemy used PP flyout, fixes #4622 (#4629) Also add missing function return types --- src/phases/move-phase.ts | 41 ++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/phases/move-phase.ts b/src/phases/move-phase.ts index 10cc062ea3b..94093188571 100644 --- a/src/phases/move-phase.ts +++ b/src/phases/move-phase.ts @@ -8,10 +8,6 @@ import { SpeciesFormChangePreMoveTrigger } from "#app/data/pokemon-forms"; import { getStatusEffectActivationText, getStatusEffectHealText } from "#app/data/status-effect"; import { Type } from "#app/data/type"; import { getTerrainBlockMessage } from "#app/data/weather"; -import { Abilities } from "#app/enums/abilities"; -import { BattlerTagType } from "#app/enums/battler-tag-type"; -import { Moves } from "#app/enums/moves"; -import { StatusEffect } from "#app/enums/status-effect"; import { MoveUsedEvent } from "#app/events/battle-scene"; import Pokemon, { MoveResult, PokemonMove, TurnMove } from "#app/field/pokemon"; import { getPokemonNameWithAffix } from "#app/messages"; @@ -20,7 +16,11 @@ import { CommonAnimPhase } from "#app/phases/common-anim-phase"; import { MoveEffectPhase } from "#app/phases/move-effect-phase"; import { MoveEndPhase } from "#app/phases/move-end-phase"; import { ShowAbilityPhase } from "#app/phases/show-ability-phase"; -import * as Utils from "#app/utils"; +import { BooleanHolder, NumberHolder } from "#app/utils"; +import { Abilities } from "#enums/abilities"; +import { BattlerTagType } from "#enums/battler-tag-type"; +import { Moves } from "#enums/moves"; +import { StatusEffect } from "#enums/status-effect"; import i18next from "i18next"; export class MovePhase extends BattlePhase { @@ -89,7 +89,7 @@ export class MovePhase extends BattlePhase { this.cancelled = true; } - public start() { + public start(): void { super.start(); console.log(Moves[this.move.moveId]); @@ -140,7 +140,7 @@ export class MovePhase extends BattlePhase { } /** Check for cancellation edge cases - no targets remaining, or {@linkcode Moves.NONE} is in the queue */ - protected resolveFinalPreMoveCancellationChecks() { + protected resolveFinalPreMoveCancellationChecks(): void { const targets = this.getActiveTargetPokemon(); const moveQueue = this.pokemon.getMoveQueue(); @@ -150,14 +150,14 @@ export class MovePhase extends BattlePhase { } } - public getActiveTargetPokemon() { + public getActiveTargetPokemon(): Pokemon[] { return this.scene.getField(true).filter(p => this.targets.includes(p.getBattlerIndex())); } /** * Handles {@link StatusEffect.SLEEP Sleep}/{@link StatusEffect.PARALYSIS Paralysis}/{@link StatusEffect.FREEZE Freeze} rolls and side effects. */ - protected resolvePreMoveStatusEffects() { + protected resolvePreMoveStatusEffects(): void { if (!this.followUp && this.pokemon.status && !this.pokemon.status.isPostTurn()) { this.pokemon.status.incrementTurn(); let activated = false; @@ -198,7 +198,7 @@ export class MovePhase extends BattlePhase { * Lapse {@linkcode BattlerTagLapseType.PRE_MOVE PRE_MOVE} tags that trigger before a move is used, regardless of whether or not it failed. * Also lapse {@linkcode BattlerTagLapseType.MOVE MOVE} tags if the move should be successful. */ - protected lapsePreMoveAndMoveTags() { + protected lapsePreMoveAndMoveTags(): void { this.pokemon.lapseTags(BattlerTagLapseType.PRE_MOVE); // TODO: does this intentionally happen before the no targets/Moves.NONE on queue cancellation case is checked? @@ -207,7 +207,7 @@ export class MovePhase extends BattlePhase { } } - protected useMove() { + protected useMove(): void { const targets = this.getActiveTargetPokemon(); const moveQueue = this.pokemon.getMoveQueue(); @@ -217,7 +217,8 @@ export class MovePhase extends BattlePhase { this.showMoveText(); // TODO: Clean up implementation of two-turn moves. - if (moveQueue.length > 0) { // Using .shift here clears out two turn moves once they've been used + if (moveQueue.length > 0) { + // Using .shift here clears out two turn moves once they've been used this.ignorePp = moveQueue.shift()?.ignorePP ?? false; } @@ -226,7 +227,7 @@ export class MovePhase extends BattlePhase { const ppUsed = 1 + this.getPpIncreaseFromPressure(targets); this.move.usePp(ppUsed); - this.scene.eventTarget.dispatchEvent(new MoveUsedEvent(this.pokemon?.id, this.move.getMove(), ppUsed)); + this.scene.eventTarget.dispatchEvent(new MoveUsedEvent(this.pokemon?.id, this.move.getMove(), this.move.ppUsed)); } // Update the battle's "last move" pointer, unless we're currently mimicking a move. @@ -275,7 +276,7 @@ export class MovePhase extends BattlePhase { this.pokemon.pushMoveHistory({ move: this.move.moveId, targets: this.targets, result: MoveResult.FAIL, virtual: this.move.virtual }); let failedText: string | undefined; - const failureMessage = move.getFailedText(this.pokemon, targets[0], move, new Utils.BooleanHolder(false)); + const failureMessage = move.getFailedText(this.pokemon, targets[0], move, new BooleanHolder(false)); if (failureMessage) { failedText = failureMessage; @@ -299,7 +300,7 @@ export class MovePhase extends BattlePhase { * Queues a {@linkcode MoveEndPhase} if the move wasn't a {@linkcode followUp} and {@linkcode canMove()} returns `true`, * then ends the phase. */ - public end() { + public end(): void { if (!this.followUp && this.canMove()) { this.scene.unshiftPhase(new MoveEndPhase(this.scene, this.pokemon.getBattlerIndex())); } @@ -313,7 +314,7 @@ export class MovePhase extends BattlePhase { * * TODO: This hardcodes the PP increase at 1 per opponent, rather than deferring to the ability. */ - public getPpIncreaseFromPressure(targets: Pokemon[]) { + public getPpIncreaseFromPressure(targets: Pokemon[]): number { const foesWithPressure = this.pokemon.getOpponents().filter(o => targets.includes(o) && o.isActive(true) && o.hasAbilityWithAttr(IncreasePpAbAttr)); return foesWithPressure.length; } @@ -323,10 +324,10 @@ export class MovePhase extends BattlePhase { * - Move redirection abilities, effects, etc. * - Counterattacks, which pass a special value into the `targets` constructor param (`[`{@linkcode BattlerIndex.ATTACKER}`]`). */ - protected resolveRedirectTarget() { + protected resolveRedirectTarget(): void { if (this.targets.length === 1) { const currentTarget = this.targets[0]; - const redirectTarget = new Utils.NumberHolder(currentTarget); + const redirectTarget = new NumberHolder(currentTarget); // check move redirection abilities of every pokemon *except* the user. this.scene.getField(true).filter(p => p !== this.pokemon).forEach(p => applyAbAttrs(RedirectMoveAbAttr, p, null, false, this.move.moveId, redirectTarget)); @@ -372,7 +373,7 @@ export class MovePhase extends BattlePhase { * If there is no last attacker, or they are no longer on the field, a message is displayed and the * move is marked for failure. */ - protected resolveCounterAttackTarget() { + protected resolveCounterAttackTarget(): void { if (this.targets.length === 1 && this.targets[0] === BattlerIndex.ATTACKER) { if (this.pokemon.turnData.attacksReceived.length) { this.targets[0] = this.pokemon.turnData.attacksReceived[0].sourceBattlerIndex; @@ -411,7 +412,7 @@ export class MovePhase extends BattlePhase { * * TODO: handle charge moves more gracefully */ - protected handlePreMoveFailures() { + protected handlePreMoveFailures(): void { if (this.cancelled || this.failed) { if (this.failed) { const ppUsed = this.ignorePp ? 0 : 1; From e9906ea2293171aa8b32b81ee1d1a0a77254b3f2 Mon Sep 17 00:00:00 2001 From: Mumble <171087428+frutescens@users.noreply.github.com> Date: Thu, 10 Oct 2024 08:31:10 -0700 Subject: [PATCH 03/37] [P2] Obstruct/Kings Shield/etc no longer reduce stats through Clear Body/etc (#4627) * bug fix * Add test --------- Co-authored-by: frutescens Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/data/battler-tags.ts | 2 +- src/test/moves/obstruct.test.ts | 26 +++++++++++++++++++------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index a54a8c5f519..6307b3d28be 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -1376,7 +1376,7 @@ export class ContactStatStageChangeProtectedTag extends DamageProtectedTag { const effectPhase = pokemon.scene.getCurrentPhase(); if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) { const attacker = effectPhase.getPokemon(); - pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, attacker.getBattlerIndex(), true, [ this.stat ], this.levels)); + pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, attacker.getBattlerIndex(), false, [ this.stat ], this.levels)); } } diff --git a/src/test/moves/obstruct.test.ts b/src/test/moves/obstruct.test.ts index fbb5437b43a..1649c199e32 100644 --- a/src/test/moves/obstruct.test.ts +++ b/src/test/moves/obstruct.test.ts @@ -1,6 +1,7 @@ -import { Moves } from "#app/enums/moves"; -import { Stat } from "#app/enums/stat"; import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { Stat } from "#enums/stat"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; @@ -22,13 +23,15 @@ describe("Moves - Obstruct", () => { game = new GameManager(phaserGame); game.override .battleType("single") + .enemySpecies(Species.MAGIKARP) + .enemyMoveset(Moves.TACKLE) .enemyAbility(Abilities.BALL_FETCH) .ability(Abilities.BALL_FETCH) - .moveset([ Moves.OBSTRUCT ]); + .moveset([ Moves.OBSTRUCT ]) + .starterSpecies(Species.FEEBAS); }); it("protects from contact damaging moves and lowers the opponent's defense by 2 stages", async () => { - game.override.enemyMoveset(Array(4).fill(Moves.ICE_PUNCH)); await game.classicMode.startBattle(); game.move.select(Moves.OBSTRUCT); @@ -42,7 +45,6 @@ describe("Moves - Obstruct", () => { }); it("bypasses accuracy checks when applying protection and defense reduction", async () => { - game.override.enemyMoveset(Array(4).fill(Moves.ICE_PUNCH)); await game.classicMode.startBattle(); game.move.select(Moves.OBSTRUCT); @@ -59,7 +61,7 @@ describe("Moves - Obstruct", () => { ); it("protects from non-contact damaging moves and doesn't lower the opponent's defense by 2 stages", async () => { - game.override.enemyMoveset(Array(4).fill(Moves.WATER_GUN)); + game.override.enemyMoveset(Moves.WATER_GUN); await game.classicMode.startBattle(); game.move.select(Moves.OBSTRUCT); @@ -73,7 +75,7 @@ describe("Moves - Obstruct", () => { }); it("doesn't protect from status moves", async () => { - game.override.enemyMoveset(Array(4).fill(Moves.GROWL)); + game.override.enemyMoveset(Moves.GROWL); await game.classicMode.startBattle(); game.move.select(Moves.OBSTRUCT); @@ -83,4 +85,14 @@ describe("Moves - Obstruct", () => { expect(player.getStatStage(Stat.ATK)).toBe(-1); }); + + it("doesn't reduce the stats of an opponent with Clear Body/etc", async () => { + game.override.enemyAbility(Abilities.CLEAR_BODY); + await game.classicMode.startBattle(); + + game.move.select(Moves.OBSTRUCT); + await game.phaseInterceptor.to("BerryPhase"); + + expect(game.scene.getEnemyPokemon()!.getStatStage(Stat.DEF)).toBe(0); + }); }); From 51894d46c265116ee391146a10bedb16eccbc056 Mon Sep 17 00:00:00 2001 From: Mumble <171087428+frutescens@users.noreply.github.com> Date: Thu, 10 Oct 2024 08:38:17 -0700 Subject: [PATCH 04/37] [P2] Pollen Puff ally behavior fixed (#4615) * pollen puff fix * bcvbvcbfd * integerholder to numberholder * moved it back --------- Co-authored-by: frutescens --- src/data/move.ts | 4 ++-- src/field/pokemon.ts | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/data/move.ts b/src/data/move.ts index 08c00829b48..4924341870d 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -4107,11 +4107,11 @@ export class StatusCategoryOnAllyAttr extends VariableMoveCategoryAttr { * @param user {@linkcode Pokemon} using the move * @param target {@linkcode Pokemon} target of the move * @param move {@linkcode Move} with this attribute - * @param args [0] {@linkcode Utils.IntegerHolder} The category of the move + * @param args [0] {@linkcode Utils.NumberHolder} The category of the move * @returns true if the function succeeds */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - const category = (args[0] as Utils.IntegerHolder); + const category = (args[0] as Utils.NumberHolder); if (user.getAlly() === target) { category.value = MoveCategory.STATUS; diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 35f389b58a4..4d85d5b8e1e 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -2684,7 +2684,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { */ apply(source: Pokemon, move: Move): HitResult { const defendingSide = this.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; - if (move.category === MoveCategory.STATUS) { + const moveCategory = new Utils.NumberHolder(move.category); + applyMoveAttrs(VariableMoveCategoryAttr, source, this, move, moveCategory); + if (moveCategory.value === MoveCategory.STATUS) { const cancelled = new Utils.BooleanHolder(false); const typeMultiplier = this.getMoveEffectiveness(source, move, false, false, cancelled); From 64147e44145faa8e8f14730279e764d146797841 Mon Sep 17 00:00:00 2001 From: PigeonBar <56974298+PigeonBar@users.noreply.github.com> Date: Thu, 10 Oct 2024 11:40:14 -0400 Subject: [PATCH 05/37] [P2] Fix Battle Bond continuing to affect Water Shuriken after Greninja returns to base form (#4602) * [Bug] Fix Battle Bond continuing to buff Water Shuriken after Greninja returns to base form * Test cleanup * PR feedback * Update test to use getMultiHitType() * PR Feedback --- src/data/move.ts | 13 +++- src/test/abilities/battle_bond.test.ts | 94 +++++++++++++++++--------- 2 files changed, 73 insertions(+), 34 deletions(-) diff --git a/src/data/move.ts b/src/data/move.ts index 4924341870d..bae8eea0d8a 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -1938,12 +1938,21 @@ export class IncrementMovePriorityAttr extends MoveAttr { * @see {@linkcode apply} */ export class MultiHitAttr extends MoveAttr { + /** This move's intrinsic multi-hit type. It should never be modified. */ + private readonly intrinsicMultiHitType: MultiHitType; + /** This move's current multi-hit type. It may be temporarily modified by abilities (e.g., Battle Bond). */ private multiHitType: MultiHitType; constructor(multiHitType?: MultiHitType) { super(); - this.multiHitType = multiHitType !== undefined ? multiHitType : MultiHitType._2_TO_5; + this.intrinsicMultiHitType = multiHitType !== undefined ? multiHitType : MultiHitType._2_TO_5; + this.multiHitType = this.intrinsicMultiHitType; + } + + // Currently used by `battle_bond.test.ts` + getMultiHitType(): MultiHitType { + return this.multiHitType; } /** @@ -1957,7 +1966,7 @@ export class MultiHitAttr extends MoveAttr { * @returns True */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { - const hitType = new Utils.NumberHolder(this.multiHitType); + const hitType = new Utils.NumberHolder(this.intrinsicMultiHitType); applyMoveAttrs(ChangeMultiHitTypeAttr, user, target, move, hitType); this.multiHitType = hitType.value; diff --git a/src/test/abilities/battle_bond.test.ts b/src/test/abilities/battle_bond.test.ts index c7dffeb150a..283fb0d0f14 100644 --- a/src/test/abilities/battle_bond.test.ts +++ b/src/test/abilities/battle_bond.test.ts @@ -1,17 +1,19 @@ +import { allMoves, MultiHitAttr, MultiHitType } from "#app/data/move"; import { Status, StatusEffect } from "#app/data/status-effect"; -import { QuietFormChangePhase } from "#app/phases/quiet-form-change-phase"; -import { TurnEndPhase } from "#app/phases/turn-end-phase"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import GameManager from "#test/utils/gameManager"; -import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Abilities - BATTLE BOND", () => { let phaserGame: Phaser.Game; let game: GameManager; + const baseForm = 1; + const ashForm = 2; + beforeAll(() => { phaserGame = new Phaser.Game({ type: Phaser.HEADLESS, @@ -24,40 +26,68 @@ describe("Abilities - BATTLE BOND", () => { beforeEach(() => { game = new GameManager(phaserGame); - const moveToUse = Moves.SPLASH; - game.override.battleType("single"); - game.override.ability(Abilities.BATTLE_BOND); - game.override.moveset([ moveToUse ]); - game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); + game.override.battleType("single") + .startingWave(4) // Leads to arena reset on Wave 5 trainer battle + .ability(Abilities.BATTLE_BOND) + .starterForms({ [Species.GRENINJA]: ashForm, }) + .moveset([ Moves.SPLASH, Moves.WATER_SHURIKEN ]) + .enemySpecies(Species.BULBASAUR) + .enemyMoveset(Moves.SPLASH) + .startingLevel(100) // Avoid levelling up + .enemyLevel(1000); // Avoid opponent dying before `doKillOpponents()` }); - test( - "check if fainted pokemon switches to base form on arena reset", - async () => { - const baseForm = 1; - const ashForm = 2; - game.override.startingWave(4); - game.override.starterForms({ - [Species.GRENINJA]: ashForm, - }); + it("check if fainted pokemon switches to base form on arena reset", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP, Species.GRENINJA ]); - await game.startBattle([ Species.MAGIKARP, Species.GRENINJA ]); + const greninja = game.scene.getParty()[1]; + expect(greninja.formIndex).toBe(ashForm); - const greninja = game.scene.getParty().find((p) => p.species.speciesId === Species.GRENINJA); - expect(greninja).toBeDefined(); - expect(greninja!.formIndex).toBe(ashForm); + greninja.hp = 0; + greninja.status = new Status(StatusEffect.FAINT); + expect(greninja.isFainted()).toBe(true); - greninja!.hp = 0; - greninja!.status = new Status(StatusEffect.FAINT); - expect(greninja!.isFainted()).toBe(true); + game.move.select(Moves.SPLASH); + await game.doKillOpponents(); + await game.phaseInterceptor.to("TurnEndPhase"); + game.doSelectModifier(); + await game.phaseInterceptor.to("QuietFormChangePhase"); - game.move.select(Moves.SPLASH); - await game.doKillOpponents(); - await game.phaseInterceptor.to(TurnEndPhase); - game.doSelectModifier(); - await game.phaseInterceptor.to(QuietFormChangePhase); + expect(greninja.formIndex).toBe(baseForm); + }); - expect(greninja!.formIndex).toBe(baseForm); - }, - ); + it("should not keep buffing Water Shuriken after Greninja switches to base form", async () => { + await game.classicMode.startBattle([ Species.GRENINJA ]); + + const waterShuriken = allMoves[Moves.WATER_SHURIKEN]; + vi.spyOn(waterShuriken, "calculateBattlePower"); + + let actualMultiHitType: MultiHitType | null = null; + const multiHitAttr = waterShuriken.getAttrs(MultiHitAttr)[0]; + vi.spyOn(multiHitAttr, "getHitCount").mockImplementation(() => { + actualMultiHitType = multiHitAttr.getMultiHitType(); + return 3; + }); + + // Wave 4: Use Water Shuriken in Ash form + let expectedBattlePower = 20; + let expectedMultiHitType = MultiHitType._3; + + game.move.select(Moves.WATER_SHURIKEN); + await game.phaseInterceptor.to("BerryPhase", false); + expect(waterShuriken.calculateBattlePower).toHaveLastReturnedWith(expectedBattlePower); + expect(actualMultiHitType).toBe(expectedMultiHitType); + + await game.doKillOpponents(); + await game.toNextWave(); + + // Wave 5: Use Water Shuriken in base form + expectedBattlePower = 15; + expectedMultiHitType = MultiHitType._2_TO_5; + + game.move.select(Moves.WATER_SHURIKEN); + await game.phaseInterceptor.to("BerryPhase", false); + expect(waterShuriken.calculateBattlePower).toHaveLastReturnedWith(expectedBattlePower); + expect(actualMultiHitType).toBe(expectedMultiHitType); + }); }); From a778537ccadcfe23a39766abcf8afee7b287ca09 Mon Sep 17 00:00:00 2001 From: Mumble <171087428+frutescens@users.noreply.github.com> Date: Thu, 10 Oct 2024 08:43:50 -0700 Subject: [PATCH 06/37] [P2] Sketch Failure Bug involving multiple Sketch-s in a moveset (#4618) * Sketch bug fix * Added test --------- Co-authored-by: frutescens --- src/phases/turn-start-phase.ts | 2 +- src/test/moves/sketch.test.ts | 53 ++++++++++++++++++++++++++++++ src/test/utils/gameManagerUtils.ts | 2 +- 3 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 src/test/moves/sketch.test.ts diff --git a/src/phases/turn-start-phase.ts b/src/phases/turn-start-phase.ts index 95d55986185..53623f933f2 100644 --- a/src/phases/turn-start-phase.ts +++ b/src/phases/turn-start-phase.ts @@ -158,7 +158,7 @@ export class TurnStartPhase extends FieldPhase { if (!queuedMove) { continue; } - const move = pokemon.getMoveset().find(m => m?.moveId === queuedMove.move) || new PokemonMove(queuedMove.move); + const move = pokemon.getMoveset().find(m => m?.moveId === queuedMove.move && m?.ppUsed < m?.getMovePp()) || new PokemonMove(queuedMove.move); if (move.getMove().hasAttr(MoveHeaderAttr)) { this.scene.unshiftPhase(new MoveHeaderPhase(this.scene, pokemon, move)); } diff --git a/src/test/moves/sketch.test.ts b/src/test/moves/sketch.test.ts new file mode 100644 index 00000000000..2e3eb97a76c --- /dev/null +++ b/src/test/moves/sketch.test.ts @@ -0,0 +1,53 @@ +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { MoveResult } from "#app/field/pokemon"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Moves - Sketch", () => { + 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 + .ability(Abilities.BALL_FETCH) + .battleType("single") + .disableCrits() + .enemySpecies(Species.SHUCKLE) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH); + }); + + it("Sketch should not fail even if a previous Sketch failed to retrieve a valid move and ran out of PP", async () => { + game.override.moveset([ Moves.SKETCH, Moves.SKETCH ]); + + await game.classicMode.startBattle([ Species.REGIELEKI ]); + const playerPokemon = game.scene.getPlayerPokemon(); + + game.move.select(Moves.SKETCH); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon?.getLastXMoves()[0].result).toBe(MoveResult.FAIL); + const moveSlot0 = playerPokemon?.getMoveset()[0]; + expect(moveSlot0?.moveId).toBe(Moves.SKETCH); + expect(moveSlot0?.getPpRatio()).toBe(0); + + await game.toNextTurn(); + game.move.select(Moves.SKETCH); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(playerPokemon?.getLastXMoves()[0].result).toBe(MoveResult.SUCCESS); + // Can't verify if the player Pokemon's moveset was successfully changed because of overrides. + }); +}); diff --git a/src/test/utils/gameManagerUtils.ts b/src/test/utils/gameManagerUtils.ts index 700d93082d8..543ee9627fe 100644 --- a/src/test/utils/gameManagerUtils.ts +++ b/src/test/utils/gameManagerUtils.ts @@ -86,7 +86,7 @@ export function waitUntil(truth) { export function getMovePosition(scene: BattleScene, pokemonIndex: 0 | 1, move: Moves) { const playerPokemon = scene.getPlayerField()[pokemonIndex]; const moveSet = playerPokemon.getMoveset(); - const index = moveSet.findIndex((m) => m?.moveId === move); + const index = moveSet.findIndex((m) => m?.moveId === move && m?.ppUsed < m?.getMovePp()); console.log(`Move position for ${Moves[move]} (=${move}):`, index); return index; } From ba7e26152e560032792e94257b11510160ea184f Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Thu, 10 Oct 2024 08:45:02 -0700 Subject: [PATCH 07/37] [Bug] Fix substitute interactions with `PostDefendAbAttr`s (#4570) * Fixes some Substitute interactions Specifically with Disguise/Ice Face and Gulp Missile * Add tests * Fix linting * Add `hitsSubstitute()` checks to all `PostDefendAbAttr`s Also fix comment indentation in `MoveEffectPhase` * Revert `move-effect-phase.ts` changes --- src/data/ability.ts | 140 +++++++++++++----------- src/data/battler-tags.ts | 4 + src/data/move.ts | 12 +- src/test/abilities/disguise.test.ts | 16 ++- src/test/abilities/gulp_missile.test.ts | 31 +++++- src/test/abilities/ice_face.test.ts | 38 +++++-- 6 files changed, 152 insertions(+), 89 deletions(-) diff --git a/src/data/ability.ts b/src/data/ability.ts index 43d02da1733..6a391818866 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -634,15 +634,15 @@ export class ReverseDrainAbAttr extends PostDefendAbAttr { * Examples include: Absorb, Draining Kiss, Bitter Blade, etc. * Also displays a message to show this ability was activated. * @param pokemon {@linkcode Pokemon} with this ability - * @param passive N/A + * @param _passive N/A * @param attacker {@linkcode Pokemon} that is attacking this Pokemon * @param move {@linkcode PokemonMove} that is being used - * @param hitResult N/A - * @args N/A + * @param _hitResult N/A + * @param _args N/A * @returns true if healing should be reversed on a healing move, false otherwise. */ - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (move.hasAttr(HitHealAttr)) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (move.hasAttr(HitHealAttr) && !move.hitsSubstitute(attacker, pokemon)) { if (!simulated) { pokemon.scene.queueMessage(i18next.t("abilityTriggers:reverseDrain", { pokemonNameWithAffix: getPokemonNameWithAffix(attacker) })); } @@ -669,8 +669,8 @@ export class PostDefendStatStageChangeAbAttr extends PostDefendAbAttr { this.allOthers = allOthers; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (this.condition(pokemon, attacker, move)) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (this.condition(pokemon, attacker, move) && !move.hitsSubstitute(attacker, pokemon)) { if (simulated) { return true; } @@ -707,13 +707,13 @@ export class PostDefendHpGatedStatStageChangeAbAttr extends PostDefendAbAttr { this.selfTarget = selfTarget; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - const hpGateFlat: integer = Math.ceil(pokemon.getMaxHp() * this.hpGate); + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + const hpGateFlat: number = Math.ceil(pokemon.getMaxHp() * this.hpGate); const lastAttackReceived = pokemon.turnData.attacksReceived[pokemon.turnData.attacksReceived.length - 1]; const damageReceived = lastAttackReceived?.damage || 0; - if (this.condition(pokemon, attacker, move) && (pokemon.hp <= hpGateFlat && (pokemon.hp + damageReceived) > hpGateFlat)) { - if (!simulated ) { + if (this.condition(pokemon, attacker, move) && (pokemon.hp <= hpGateFlat && (pokemon.hp + damageReceived) > hpGateFlat) && !move.hitsSubstitute(attacker, pokemon)) { + if (!simulated) { pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, (this.selfTarget ? pokemon : attacker).getBattlerIndex(), true, this.stats, this.stages)); } return true; @@ -734,8 +734,8 @@ export class PostDefendApplyArenaTrapTagAbAttr extends PostDefendAbAttr { this.tagType = tagType; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (this.condition(pokemon, attacker, move)) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (this.condition(pokemon, attacker, move) && !move.hitsSubstitute(attacker, pokemon)) { const tag = pokemon.scene.arena.getTag(this.tagType) as ArenaTrapTag; if (!pokemon.scene.arena.getTag(this.tagType) || tag.layers < tag.maxLayers) { if (!simulated) { @@ -758,8 +758,8 @@ export class PostDefendApplyBattlerTagAbAttr extends PostDefendAbAttr { this.tagType = tagType; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (this.condition(pokemon, attacker, move)) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (this.condition(pokemon, attacker, move) && !move.hitsSubstitute(attacker, pokemon)) { if (!pokemon.getTag(this.tagType) && !simulated) { pokemon.addTag(this.tagType, undefined, undefined, pokemon.id); pokemon.scene.queueMessage(i18next.t("abilityTriggers:windPowerCharged", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: move.name })); @@ -771,8 +771,8 @@ export class PostDefendApplyBattlerTagAbAttr extends PostDefendAbAttr { } export class PostDefendTypeChangeAbAttr extends PostDefendAbAttr { - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (hitResult < HitResult.NO_EFFECT) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, _args: any[]): boolean { + if (hitResult < HitResult.NO_EFFECT && !move.hitsSubstitute(attacker, pokemon)) { if (simulated) { return true; } @@ -787,7 +787,7 @@ export class PostDefendTypeChangeAbAttr extends PostDefendAbAttr { return false; } - getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { + override getTriggerMessage(pokemon: Pokemon, abilityName: string, ..._args: any[]): string { return i18next.t("abilityTriggers:postDefendTypeChange", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName, @@ -805,8 +805,8 @@ export class PostDefendTerrainChangeAbAttr extends PostDefendAbAttr { this.terrainType = terrainType; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (hitResult < HitResult.NO_EFFECT) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, _args: any[]): boolean { + if (hitResult < HitResult.NO_EFFECT && !move.hitsSubstitute(attacker, pokemon)) { if (simulated) { return pokemon.scene.arena.terrain?.terrainType !== (this.terrainType || undefined); } else { @@ -829,8 +829,9 @@ export class PostDefendContactApplyStatusEffectAbAttr extends PostDefendAbAttr { this.effects = effects; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.status && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance)) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.status + && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance) && !move.hitsSubstitute(attacker, pokemon)) { const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)]; if (simulated) { return attacker.canSetStatus(effect, true, false, pokemon); @@ -869,8 +870,8 @@ export class PostDefendContactApplyTagChanceAbAttr extends PostDefendAbAttr { this.turnCount = turnCount; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && pokemon.randSeedInt(100) < this.chance) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && pokemon.randSeedInt(100) < this.chance && !move.hitsSubstitute(attacker, pokemon)) { if (simulated) { return attacker.canAddTag(this.tagType); } else { @@ -893,7 +894,11 @@ export class PostDefendCritStatStageChangeAbAttr extends PostDefendAbAttr { this.stages = stages; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (move.hitsSubstitute(attacker, pokemon)) { + return false; + } + if (!simulated) { pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.stages)); } @@ -901,7 +906,7 @@ export class PostDefendCritStatStageChangeAbAttr extends PostDefendAbAttr { return true; } - getCondition(): AbAttrCondition { + override getCondition(): AbAttrCondition { return (pokemon: Pokemon) => pokemon.turnData.attacksReceived.length !== 0 && pokemon.turnData.attacksReceived[pokemon.turnData.attacksReceived.length - 1].critical; } } @@ -915,8 +920,9 @@ export class PostDefendContactDamageAbAttr extends PostDefendAbAttr { this.damageRatio = damageRatio; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (!simulated && move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (!simulated && move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) + && !attacker.hasAbilityWithAttr(BlockNonDirectDamageAbAttr) && !move.hitsSubstitute(attacker, pokemon)) { attacker.damageAndUpdate(Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER); attacker.turnData.damageTaken += Utils.toDmgValue(attacker.getMaxHp() * (1 / this.damageRatio)); return true; @@ -925,7 +931,7 @@ export class PostDefendContactDamageAbAttr extends PostDefendAbAttr { return false; } - getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { + override getTriggerMessage(pokemon: Pokemon, abilityName: string, ..._args: any[]): string { return i18next.t("abilityTriggers:postDefendContactDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName @@ -948,8 +954,8 @@ export class PostDefendPerishSongAbAttr extends PostDefendAbAttr { this.turns = turns; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !move.hitsSubstitute(attacker, pokemon)) { if (pokemon.getTag(BattlerTagType.PERISH_SONG) || attacker.getTag(BattlerTagType.PERISH_SONG)) { return false; } else { @@ -963,24 +969,24 @@ export class PostDefendPerishSongAbAttr extends PostDefendAbAttr { return false; } - getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { + override getTriggerMessage(pokemon: Pokemon, abilityName: string, ..._args: any[]): string { return i18next.t("abilityTriggers:perishBody", { pokemonName: getPokemonNameWithAffix(pokemon), abilityName: abilityName }); } } export class PostDefendWeatherChangeAbAttr extends PostDefendAbAttr { private weatherType: WeatherType; - protected condition: PokemonDefendCondition | null; + protected condition?: PokemonDefendCondition; constructor(weatherType: WeatherType, condition?: PokemonDefendCondition) { super(); this.weatherType = weatherType; - this.condition = condition ?? null; + this.condition = condition; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (this.condition !== null && !this.condition(pokemon, attacker, move)) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (this.condition && !this.condition(pokemon, attacker, move) || move.hitsSubstitute(attacker, pokemon)) { return false; } if (!pokemon.scene.arena.weather?.isImmutable()) { @@ -999,8 +1005,9 @@ export class PostDefendAbilitySwapAbAttr extends PostDefendAbAttr { super(); } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.getAbility().hasAttr(UnswappableAbilityAbAttr)) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, args: any[]): boolean { + if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) + && !attacker.getAbility().hasAttr(UnswappableAbilityAbAttr) && !move.hitsSubstitute(attacker, pokemon)) { if (!simulated) { const tempAbilityId = attacker.getAbility().id; attacker.summonData.ability = pokemon.getAbility().id; @@ -1012,7 +1019,7 @@ export class PostDefendAbilitySwapAbAttr extends PostDefendAbAttr { return false; } - getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { + override getTriggerMessage(pokemon: Pokemon, _abilityName: string, ..._args: any[]): string { return i18next.t("abilityTriggers:postDefendAbilitySwap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }); } } @@ -1025,8 +1032,9 @@ export class PostDefendAbilityGiveAbAttr extends PostDefendAbAttr { this.ability = ability; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.getAbility().hasAttr(UnsuppressableAbilityAbAttr) && !attacker.getAbility().hasAttr(PostDefendAbilityGiveAbAttr)) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.getAbility().hasAttr(UnsuppressableAbilityAbAttr) + && !attacker.getAbility().hasAttr(PostDefendAbilityGiveAbAttr) && !move.hitsSubstitute(attacker, pokemon)) { if (!simulated) { attacker.summonData.ability = this.ability; } @@ -1037,7 +1045,7 @@ export class PostDefendAbilityGiveAbAttr extends PostDefendAbAttr { return false; } - getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { + override getTriggerMessage(pokemon: Pokemon, abilityName: string, ..._args: any[]): string { return i18next.t("abilityTriggers:postDefendAbilityGive", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName @@ -1056,8 +1064,8 @@ export class PostDefendMoveDisableAbAttr extends PostDefendAbAttr { this.chance = chance; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { - if (attacker.getTag(BattlerTagType.DISABLED) === null) { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean { + if (attacker.getTag(BattlerTagType.DISABLED) === null && !move.hitsSubstitute(attacker, pokemon)) { if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance)) { if (simulated) { return true; @@ -1724,17 +1732,17 @@ export class PostAttackApplyBattlerTagAbAttr extends PostAttackAbAttr { } export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr { - private condition: PokemonDefendCondition | null; + private condition?: PokemonDefendCondition; constructor(condition?: PokemonDefendCondition) { super(); - this.condition = condition ?? null; + this.condition = condition; } - applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): Promise { + override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, _args: any[]): Promise { return new Promise(resolve => { - if (!simulated && hitResult < HitResult.NO_EFFECT && (!this.condition || this.condition(pokemon, attacker, move))) { + if (!simulated && hitResult < HitResult.NO_EFFECT && (!this.condition || this.condition(pokemon, attacker, move)) && !move.hitsSubstitute(attacker, pokemon)) { const heldItems = this.getTargetHeldItems(attacker).filter(i => i.isTransferable); if (heldItems.length) { const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)]; @@ -4476,7 +4484,7 @@ export class PostSummonStatStageChangeOnArenaAbAttr extends PostSummonStatStageC export class FormBlockDamageAbAttr extends ReceivedMoveDamageMultiplierAbAttr { private multiplier: number; private tagType: BattlerTagType; - private recoilDamageFunc: ((pokemon: Pokemon) => number) | undefined; + private recoilDamageFunc?: ((pokemon: Pokemon) => number); private triggerMessageFunc: (pokemon: Pokemon, abilityName: string) => string; constructor(condition: PokemonDefendCondition, multiplier: number, tagType: BattlerTagType, triggerMessageFunc: (pokemon: Pokemon, abilityName: string) => string, recoilDamageFunc?: (pokemon: Pokemon) => number) { @@ -4492,16 +4500,16 @@ export class FormBlockDamageAbAttr extends ReceivedMoveDamageMultiplierAbAttr { * Applies the pre-defense ability to the Pokémon. * Removes the appropriate `BattlerTagType` when hit by an attack and is in its defense form. * - * @param {Pokemon} pokemon The Pokémon with the ability. - * @param {boolean} passive n/a - * @param {Pokemon} attacker The attacking Pokémon. - * @param {PokemonMove} move The move being used. - * @param {Utils.BooleanHolder} cancelled n/a - * @param {any[]} args Additional arguments. - * @returns {boolean} Whether the immunity was applied. + * @param pokemon The Pokémon with the ability. + * @param _passive n/a + * @param attacker The attacking Pokémon. + * @param move The move being used. + * @param _cancelled n/a + * @param args Additional arguments. + * @returns `true` if the immunity was applied. */ - applyPreDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean { - if (this.condition(pokemon, attacker, move)) { + override applyPreDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _cancelled: Utils.BooleanHolder, args: any[]): boolean { + if (this.condition(pokemon, attacker, move) && !move.hitsSubstitute(attacker, pokemon)) { if (!simulated) { (args[0] as Utils.NumberHolder).value = this.multiplier; pokemon.removeTag(this.tagType); @@ -4517,12 +4525,12 @@ export class FormBlockDamageAbAttr extends ReceivedMoveDamageMultiplierAbAttr { /** * Gets the message triggered when the Pokémon avoids damage using the form-changing ability. - * @param {Pokemon} pokemon The Pokémon with the ability. - * @param {string} abilityName The name of the ability. - * @param {...any} args n/a - * @returns {string} The trigger message. + * @param pokemon The Pokémon with the ability. + * @param abilityName The name of the ability. + * @param _args n/a + * @returns The trigger message. */ - getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { + getTriggerMessage(pokemon: Pokemon, abilityName: string, ..._args: any[]): string { return this.triggerMessageFunc(pokemon, abilityName); } } @@ -5503,7 +5511,8 @@ export function initAbilities() { .attr(NoFusionAbilityAbAttr) // Add BattlerTagType.DISGUISE if the pokemon is in its disguised form .conditionalAttr(pokemon => pokemon.formIndex === 0, PostSummonAddBattlerTagAbAttr, BattlerTagType.DISGUISE, 0, false) - .attr(FormBlockDamageAbAttr, (target, user, move) => !!target.getTag(BattlerTagType.DISGUISE) && target.getMoveEffectiveness(user, move) > 0, 0, BattlerTagType.DISGUISE, + .attr(FormBlockDamageAbAttr, + (target, user, move) => !!target.getTag(BattlerTagType.DISGUISE) && target.getMoveEffectiveness(user, move) > 0, 0, BattlerTagType.DISGUISE, (pokemon, abilityName) => i18next.t("abilityTriggers:disguiseAvoidedDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }), (pokemon) => Utils.toDmgValue(pokemon.getMaxHp() / 8)) .attr(PostBattleInitFormChangeAbAttr, () => 0) @@ -5665,7 +5674,8 @@ export function initAbilities() { .conditionalAttr(getWeatherCondition(WeatherType.HAIL, WeatherType.SNOW), PostSummonAddBattlerTagAbAttr, BattlerTagType.ICE_FACE, 0) // When weather changes to HAIL or SNOW while pokemon is fielded, add BattlerTagType.ICE_FACE .attr(PostWeatherChangeAddBattlerTagAttr, BattlerTagType.ICE_FACE, 0, WeatherType.HAIL, WeatherType.SNOW) - .attr(FormBlockDamageAbAttr, (target, user, move) => move.category === MoveCategory.PHYSICAL && !!target.getTag(BattlerTagType.ICE_FACE), 0, BattlerTagType.ICE_FACE, + .attr(FormBlockDamageAbAttr, + (target, user, move) => move.category === MoveCategory.PHYSICAL && !!target.getTag(BattlerTagType.ICE_FACE), 0, BattlerTagType.ICE_FACE, (pokemon, abilityName) => i18next.t("abilityTriggers:iceFaceAvoidedDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName })) .attr(PostBattleInitFormChangeAbAttr, () => 0) .bypassFaint() diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 6307b3d28be..24c82e54427 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -2139,6 +2139,10 @@ export class GulpMissileTag extends BattlerTag { return false; } + if (moveEffectPhase.move.getMove().hitsSubstitute(attacker, pokemon)) { + return true; + } + const cancelled = new Utils.BooleanHolder(false); applyAbAttrs(BlockNonDirectDamageAbAttr, attacker, cancelled); diff --git a/src/data/move.ts b/src/data/move.ts index bae8eea0d8a..ff0c24f5032 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -4844,14 +4844,14 @@ export class GulpMissileTagAttr extends MoveEffectAttr { /** * Adds BattlerTagType from GulpMissileTag based on the Pokemon's HP ratio. - * @param {Pokemon} user The Pokemon using the move. - * @param {Pokemon} target The Pokemon being targeted by the move. - * @param {Move} move The move being used. - * @param {any[]} args Additional arguments, if any. + * @param user The Pokemon using the move. + * @param _target N/A + * @param move The move being used. + * @param _args N/A * @returns Whether the BattlerTag is applied. */ - apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean | Promise { - if (!super.apply(user, target, move, args)) { + apply(user: Pokemon, _target: Pokemon, move: Move, _args: any[]): boolean { + if (!super.apply(user, _target, move, _args)) { return false; } diff --git a/src/test/abilities/disguise.test.ts b/src/test/abilities/disguise.test.ts index a295dd61443..0241aa4b9ea 100644 --- a/src/test/abilities/disguise.test.ts +++ b/src/test/abilities/disguise.test.ts @@ -1,8 +1,9 @@ +import { BattlerIndex } from "#app/battle"; +import { StatusEffect } from "#app/data/status-effect"; import { toDmgValue } from "#app/utils"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; -import { StatusEffect } from "#app/data/status-effect"; import { Stat } from "#enums/stat"; import GameManager from "#test/utils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; @@ -222,4 +223,17 @@ describe("Abilities - Disguise", () => { expect(mimikyu.formIndex).toBe(bustedForm); expect(mimikyu.hp).toBe(maxHp - disguiseDamage); }); + + it("doesn't trigger if user is behind a substitute", async () => { + game.override + .enemyMoveset(Moves.SUBSTITUTE) + .moveset(Moves.POWER_TRIP); + await game.classicMode.startBattle(); + + game.move.select(Moves.POWER_TRIP); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.toNextTurn(); + + expect(game.scene.getEnemyPokemon()!.formIndex).toBe(disguisedForm); + }); }); diff --git a/src/test/abilities/gulp_missile.test.ts b/src/test/abilities/gulp_missile.test.ts index 1ca208996b5..01b68d0c89d 100644 --- a/src/test/abilities/gulp_missile.test.ts +++ b/src/test/abilities/gulp_missile.test.ts @@ -1,13 +1,14 @@ -import { BattlerTagType } from "#enums/battler-tag-type"; -import { StatusEffect } from "#enums/status-effect"; +import { BattlerIndex } from "#app/battle"; import Pokemon from "#app/field/pokemon"; -import GameManager from "#test/utils/gameManager"; import { Abilities } from "#enums/abilities"; +import { BattlerTagType } from "#enums/battler-tag-type"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; +import { Stat } from "#enums/stat"; +import { StatusEffect } from "#enums/status-effect"; +import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { Stat } from "#enums/stat"; describe("Abilities - Gulp Missile", () => { let phaserGame: Phaser.Game; @@ -40,8 +41,9 @@ describe("Abilities - Gulp Missile", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override + .disableCrits() .battleType("single") - .moveset([ Moves.SURF, Moves.DIVE, Moves.SPLASH ]) + .moveset([ Moves.SURF, Moves.DIVE, Moves.SPLASH, Moves.SUBSTITUTE ]) .enemySpecies(Species.SNORLAX) .enemyAbility(Abilities.BALL_FETCH) .enemyMoveset(Moves.SPLASH) @@ -234,6 +236,25 @@ describe("Abilities - Gulp Missile", () => { expect(game.scene.getEnemyPokemon()!.getStatStage(Stat.DEF)).toBe(-1); }); + it("doesn't trigger if user is behind a substitute", async () => { + game.override + .enemyAbility(Abilities.STURDY) + .enemyMoveset([ Moves.SPLASH, Moves.POWER_TRIP ]); + await game.classicMode.startBattle([ Species.CRAMORANT ]); + + game.move.select(Moves.SURF); + await game.forceEnemyMove(Moves.SPLASH); + await game.toNextTurn(); + + expect(game.scene.getPlayerPokemon()!.formIndex).toBe(GULPING_FORM); + + game.move.select(Moves.SUBSTITUTE); + await game.forceEnemyMove(Moves.POWER_TRIP); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + await game.toNextTurn(); + + expect(game.scene.getPlayerPokemon()!.formIndex).toBe(GULPING_FORM); + }); it("cannot be suppressed", async () => { game.override.enemyMoveset(Moves.GASTRO_ACID); diff --git a/src/test/abilities/ice_face.test.ts b/src/test/abilities/ice_face.test.ts index 723d5e8d855..1c7f7bd6093 100644 --- a/src/test/abilities/ice_face.test.ts +++ b/src/test/abilities/ice_face.test.ts @@ -1,3 +1,4 @@ +import { BattlerIndex } from "#app/battle"; import { MoveEffectPhase } from "#app/phases/move-effect-phase"; import { MoveEndPhase } from "#app/phases/move-end-phase"; import { QuietFormChangePhase } from "#app/phases/quiet-form-change-phase"; @@ -36,7 +37,7 @@ describe("Abilities - Ice Face", () => { }); it("takes no damage from physical move and transforms to Noice", async () => { - await game.startBattle([ Species.HITMONLEE ]); + await game.classicMode.startBattle([ Species.HITMONLEE ]); game.move.select(Moves.TACKLE); @@ -52,7 +53,7 @@ describe("Abilities - Ice Face", () => { it("takes no damage from the first hit of multihit physical move and transforms to Noice", async () => { game.override.moveset([ Moves.SURGING_STRIKES ]); game.override.enemyLevel(1); - await game.startBattle([ Species.HITMONLEE ]); + await game.classicMode.startBattle([ Species.HITMONLEE ]); game.move.select(Moves.SURGING_STRIKES); @@ -78,7 +79,7 @@ describe("Abilities - Ice Face", () => { }); it("takes damage from special moves", async () => { - await game.startBattle([ Species.MAGIKARP ]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); game.move.select(Moves.ICE_BEAM); @@ -92,7 +93,7 @@ describe("Abilities - Ice Face", () => { }); it("takes effects from status moves", async () => { - await game.startBattle([ Species.MAGIKARP ]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); game.move.select(Moves.TOXIC_THREAD); @@ -108,7 +109,7 @@ describe("Abilities - Ice Face", () => { game.override.moveset([ Moves.QUICK_ATTACK ]); game.override.enemyMoveset([ Moves.HAIL, Moves.HAIL, Moves.HAIL, Moves.HAIL ]); - await game.startBattle([ Species.MAGIKARP ]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); game.move.select(Moves.QUICK_ATTACK); @@ -130,7 +131,7 @@ describe("Abilities - Ice Face", () => { game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); game.override.moveset([ Moves.SNOWSCAPE ]); - await game.startBattle([ Species.EISCUE, Species.NINJASK ]); + await game.classicMode.startBattle([ Species.EISCUE, Species.NINJASK ]); game.move.select(Moves.SNOWSCAPE); @@ -157,7 +158,7 @@ describe("Abilities - Ice Face", () => { game.override.enemySpecies(Species.SHUCKLE); game.override.enemyMoveset([ Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE ]); - await game.startBattle([ Species.EISCUE ]); + await game.classicMode.startBattle([ Species.EISCUE ]); game.move.select(Moves.HAIL); const eiscue = game.scene.getPlayerPokemon()!; @@ -176,7 +177,7 @@ describe("Abilities - Ice Face", () => { it("persists form change when switched out", async () => { game.override.enemyMoveset([ Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK, Moves.QUICK_ATTACK ]); - await game.startBattle([ Species.EISCUE, Species.MAGIKARP ]); + await game.classicMode.startBattle([ Species.EISCUE, Species.MAGIKARP ]); game.move.select(Moves.ICE_BEAM); @@ -205,7 +206,7 @@ describe("Abilities - Ice Face", () => { [Species.EISCUE]: noiceForm, }); - await game.startBattle([ Species.EISCUE ]); + await game.classicMode.startBattle([ Species.EISCUE ]); const eiscue = game.scene.getPlayerPokemon()!; @@ -222,10 +223,23 @@ describe("Abilities - Ice Face", () => { expect(eiscue.getTag(BattlerTagType.ICE_FACE)).not.toBe(undefined); }); + it("doesn't trigger if user is behind a substitute", async () => { + game.override + .enemyMoveset(Moves.SUBSTITUTE) + .moveset(Moves.POWER_TRIP); + await game.classicMode.startBattle(); + + game.move.select(Moves.POWER_TRIP); + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.toNextTurn(); + + expect(game.scene.getEnemyPokemon()!.formIndex).toBe(icefaceForm); + }); + it("cannot be suppressed", async () => { game.override.moveset([ Moves.GASTRO_ACID ]); - await game.startBattle([ Species.MAGIKARP ]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); game.move.select(Moves.GASTRO_ACID); @@ -241,7 +255,7 @@ describe("Abilities - Ice Face", () => { it("cannot be swapped with another ability", async () => { game.override.moveset([ Moves.SKILL_SWAP ]); - await game.startBattle([ Species.MAGIKARP ]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); game.move.select(Moves.SKILL_SWAP); @@ -257,7 +271,7 @@ describe("Abilities - Ice Face", () => { it("cannot be copied", async () => { game.override.ability(Abilities.TRACE); - await game.startBattle([ Species.MAGIKARP ]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); game.move.select(Moves.SIMPLE_BEAM); From 0996789ee6f232c45cf4d6597c78906d8e7c2cdc Mon Sep 17 00:00:00 2001 From: "Adrian T." <68144167+torranx@users.noreply.github.com> Date: Thu, 10 Oct 2024 23:54:43 +0800 Subject: [PATCH 08/37] [Refactor] Improve typing in `phaseInterceptor.ts` (#4560) * improve typing in phaseInterceptor * add more param typings --------- Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com> Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/test/utils/phaseInterceptor.ts | 126 +++++++++++++++++++++++++++-- 1 file changed, 118 insertions(+), 8 deletions(-) diff --git a/src/test/utils/phaseInterceptor.ts b/src/test/utils/phaseInterceptor.ts index d108c4cb2ea..ec9309e2405 100644 --- a/src/test/utils/phaseInterceptor.ts +++ b/src/test/utils/phaseInterceptor.ts @@ -53,6 +53,7 @@ import { } from "#app/phases/mystery-encounter-phases"; import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase"; import { PartyExpPhase } from "#app/phases/party-exp-phase"; +import { ExpPhase } from "#app/phases/exp-phase"; export interface PromptHandler { phaseTarget?: string; @@ -61,7 +62,114 @@ export interface PromptHandler { expireFn?: () => void; awaitingActionInput?: boolean; } -import { ExpPhase } from "#app/phases/exp-phase"; + +type PhaseClass = + | typeof LoginPhase + | typeof TitlePhase + | typeof SelectGenderPhase + | typeof EncounterPhase + | typeof NewBiomeEncounterPhase + | typeof SelectStarterPhase + | typeof PostSummonPhase + | typeof SummonPhase + | typeof ToggleDoublePositionPhase + | typeof CheckSwitchPhase + | typeof ShowAbilityPhase + | typeof MessagePhase + | typeof TurnInitPhase + | typeof CommandPhase + | typeof EnemyCommandPhase + | typeof TurnStartPhase + | typeof MovePhase + | typeof MoveEffectPhase + | typeof DamagePhase + | typeof FaintPhase + | typeof BerryPhase + | typeof TurnEndPhase + | typeof BattleEndPhase + | typeof EggLapsePhase + | typeof SelectModifierPhase + | typeof NextEncounterPhase + | typeof NewBattlePhase + | typeof VictoryPhase + | typeof LearnMovePhase + | typeof MoveEndPhase + | typeof StatStageChangePhase + | typeof ShinySparklePhase + | typeof SelectTargetPhase + | typeof UnavailablePhase + | typeof QuietFormChangePhase + | typeof SwitchPhase + | typeof SwitchSummonPhase + | typeof PartyHealPhase + | typeof EvolutionPhase + | typeof EndEvolutionPhase + | typeof LevelCapPhase + | typeof AttemptRunPhase + | typeof SelectBiomePhase + | typeof MysteryEncounterPhase + | typeof MysteryEncounterOptionSelectedPhase + | typeof MysteryEncounterBattlePhase + | typeof MysteryEncounterRewardsPhase + | typeof PostMysteryEncounterPhase + | typeof ModifierRewardPhase + | typeof PartyExpPhase + | typeof ExpPhase; + +type PhaseString = + | "LoginPhase" + | "TitlePhase" + | "SelectGenderPhase" + | "EncounterPhase" + | "NewBiomeEncounterPhase" + | "SelectStarterPhase" + | "PostSummonPhase" + | "SummonPhase" + | "ToggleDoublePositionPhase" + | "CheckSwitchPhase" + | "ShowAbilityPhase" + | "MessagePhase" + | "TurnInitPhase" + | "CommandPhase" + | "EnemyCommandPhase" + | "TurnStartPhase" + | "MovePhase" + | "MoveEffectPhase" + | "DamagePhase" + | "FaintPhase" + | "BerryPhase" + | "TurnEndPhase" + | "BattleEndPhase" + | "EggLapsePhase" + | "SelectModifierPhase" + | "NextEncounterPhase" + | "NewBattlePhase" + | "VictoryPhase" + | "LearnMovePhase" + | "MoveEndPhase" + | "StatStageChangePhase" + | "ShinySparklePhase" + | "SelectTargetPhase" + | "UnavailablePhase" + | "QuietFormChangePhase" + | "SwitchPhase" + | "SwitchSummonPhase" + | "PartyHealPhase" + | "EvolutionPhase" + | "EndEvolutionPhase" + | "LevelCapPhase" + | "AttemptRunPhase" + | "SelectBiomePhase" + | "MysteryEncounterPhase" + | "MysteryEncounterOptionSelectedPhase" + | "MysteryEncounterBattlePhase" + | "MysteryEncounterRewardsPhase" + | "PostMysteryEncounterPhase" + | "ModifierRewardPhase" + | "PartyExpPhase" + | "ExpPhase"; + +type PhaseInterceptorPhase = PhaseClass | PhaseString; export default class PhaseInterceptor { public scene; @@ -172,7 +280,7 @@ export default class PhaseInterceptor { * @param phaseFrom - The phase to start from. * @returns The instance of the PhaseInterceptor. */ - runFrom(phaseFrom) { + runFrom(phaseFrom: PhaseInterceptorPhase): PhaseInterceptor { this.phaseFrom = phaseFrom; return this; } @@ -180,9 +288,10 @@ export default class PhaseInterceptor { /** * Method to transition to a target phase. * @param phaseTo - The phase to transition to. + * @param runTarget - Whether or not to run the target phase. * @returns A promise that resolves when the transition is complete. */ - async to(phaseTo, runTarget: boolean = true): Promise { + async to(phaseTo: PhaseInterceptorPhase, runTarget: boolean = true): Promise { return new Promise(async (resolve, reject) => { ErrorInterceptor.getInstance().add(this); if (this.phaseFrom) { @@ -219,7 +328,7 @@ export default class PhaseInterceptor { * @param skipFn - Optional skip function. * @returns A promise that resolves when the phase is run. */ - run(phaseTarget, skipFn?): Promise { + run(phaseTarget: PhaseInterceptorPhase, skipFn?: (className: PhaseClass) => boolean): Promise { const targetName = typeof phaseTarget === "string" ? phaseTarget : phaseTarget.name; this.scene.moveAnimations = null; // Mandatory to avoid crash return new Promise(async (resolve, reject) => { @@ -253,7 +362,7 @@ export default class PhaseInterceptor { }); } - whenAboutToRun(phaseTarget, skipFn?): Promise { + whenAboutToRun(phaseTarget: PhaseInterceptorPhase, skipFn?: (className: PhaseClass) => boolean): Promise { const targetName = typeof phaseTarget === "string" ? phaseTarget : phaseTarget.name; this.scene.moveAnimations = null; // Mandatory to avoid crash return new Promise(async (resolve, reject) => { @@ -311,7 +420,7 @@ export default class PhaseInterceptor { * Method to start a phase and log it. * @param phase - The phase to start. */ - startPhase(phase) { + startPhase(phase: PhaseClass) { this.log.push(phase.name); const instance = this.scene.getCurrentPhase(); this.onHold.push({ @@ -340,9 +449,10 @@ export default class PhaseInterceptor { /** * m2m to set mode. - * @param phase - The phase to start. + * @param mode - The {@linkcode Mode} to set. + * @param args - Additional arguments to pass to the original method. */ - setMode(mode: Mode, ...args: any[]): Promise { + setMode(mode: Mode, ...args: unknown[]): Promise { const currentPhase = this.scene.getCurrentPhase(); const instance = this.scene.ui; console.log("setMode", `${Mode[mode]} (=${mode})`, args); From 6ad5ba972cc7eafc451ed264bae3e1c153463fd8 Mon Sep 17 00:00:00 2001 From: ImperialSympathizer <110984302+ben-lear@users.noreply.github.com> Date: Thu, 10 Oct 2024 12:29:26 -0400 Subject: [PATCH 09/37] [Enhancement] Refactor Starter Species to use separate EggTier map (#4591) * creates table for tracking species egg tiers * creates table for tracking species egg tiers * rename EggTier enum values * replace clamp util function with Phaser function --------- Co-authored-by: ImperialSympathizer --- src/data/balance/species-egg-tiers.ts | 603 ++++++++++++++++++ src/data/egg.ts | 91 ++- .../encounters/a-trainers-test-encounter.ts | 4 +- .../the-expert-pokemon-breeder-encounter.ts | 2 +- src/enums/egg-type.ts | 6 +- src/field/pokemon.ts | 2 +- src/test/eggs/egg.test.ts | 36 +- .../a-trainers-test-encounter.test.ts | 4 +- .../the-expert-breeder-encounter.test.ts | 6 +- src/ui/battle-info.ts | 2 +- src/ui/egg-gacha-ui-handler.ts | 6 +- src/ui/text.ts | 6 +- src/utils.ts | 4 - 13 files changed, 676 insertions(+), 96 deletions(-) create mode 100644 src/data/balance/species-egg-tiers.ts diff --git a/src/data/balance/species-egg-tiers.ts b/src/data/balance/species-egg-tiers.ts new file mode 100644 index 00000000000..cd266dfcf54 --- /dev/null +++ b/src/data/balance/species-egg-tiers.ts @@ -0,0 +1,603 @@ +import { Species } from "#enums/species"; +import { EggTier } from "#enums/egg-type"; + +/** + * Map of all starters and their respective {@linkcode EggTier}, which determines the type of egg the starter hatches from. + */ +export const speciesEggTiers = { + [Species.BULBASAUR]: EggTier.COMMON, + [Species.CHARMANDER]: EggTier.COMMON, + [Species.SQUIRTLE]: EggTier.COMMON, + [Species.CATERPIE]: EggTier.COMMON, + [Species.WEEDLE]: EggTier.COMMON, + [Species.PIDGEY]: EggTier.COMMON, + [Species.RATTATA]: EggTier.COMMON, + [Species.SPEAROW]: EggTier.COMMON, + [Species.EKANS]: EggTier.COMMON, + [Species.PIKACHU]: EggTier.COMMON, + [Species.SANDSHREW]: EggTier.COMMON, + [Species.NIDORAN_F]: EggTier.COMMON, + [Species.NIDORAN_M]: EggTier.COMMON, + [Species.CLEFAIRY]: EggTier.COMMON, + [Species.VULPIX]: EggTier.COMMON, + [Species.JIGGLYPUFF]: EggTier.COMMON, + [Species.ZUBAT]: EggTier.COMMON, + [Species.ODDISH]: EggTier.COMMON, + [Species.PARAS]: EggTier.COMMON, + [Species.VENONAT]: EggTier.COMMON, + [Species.DIGLETT]: EggTier.COMMON, + [Species.MEOWTH]: EggTier.COMMON, + [Species.PSYDUCK]: EggTier.COMMON, + [Species.MANKEY]: EggTier.RARE, + [Species.GROWLITHE]: EggTier.RARE, + [Species.POLIWAG]: EggTier.COMMON, + [Species.ABRA]: EggTier.RARE, + [Species.MACHOP]: EggTier.COMMON, + [Species.BELLSPROUT]: EggTier.COMMON, + [Species.TENTACOOL]: EggTier.COMMON, + [Species.GEODUDE]: EggTier.COMMON, + [Species.PONYTA]: EggTier.COMMON, + [Species.SLOWPOKE]: EggTier.COMMON, + [Species.MAGNEMITE]: EggTier.RARE, + [Species.FARFETCHD]: EggTier.COMMON, + [Species.DODUO]: EggTier.COMMON, + [Species.SEEL]: EggTier.COMMON, + [Species.GRIMER]: EggTier.COMMON, + [Species.SHELLDER]: EggTier.RARE, + [Species.GASTLY]: EggTier.RARE, + [Species.ONIX]: EggTier.COMMON, + [Species.DROWZEE]: EggTier.COMMON, + [Species.KRABBY]: EggTier.COMMON, + [Species.VOLTORB]: EggTier.COMMON, + [Species.EXEGGCUTE]: EggTier.COMMON, + [Species.CUBONE]: EggTier.COMMON, + [Species.HITMONLEE]: EggTier.RARE, + [Species.HITMONCHAN]: EggTier.RARE, + [Species.LICKITUNG]: EggTier.COMMON, + [Species.KOFFING]: EggTier.COMMON, + [Species.RHYHORN]: EggTier.COMMON, + [Species.CHANSEY]: EggTier.COMMON, + [Species.TANGELA]: EggTier.COMMON, + [Species.KANGASKHAN]: EggTier.RARE, + [Species.HORSEA]: EggTier.COMMON, + [Species.GOLDEEN]: EggTier.COMMON, + [Species.STARYU]: EggTier.COMMON, + [Species.MR_MIME]: EggTier.COMMON, + [Species.SCYTHER]: EggTier.RARE, + [Species.JYNX]: EggTier.RARE, + [Species.ELECTABUZZ]: EggTier.RARE, + [Species.MAGMAR]: EggTier.RARE, + [Species.PINSIR]: EggTier.RARE, + [Species.TAUROS]: EggTier.RARE, + [Species.MAGIKARP]: EggTier.RARE, + [Species.LAPRAS]: EggTier.RARE, + [Species.DITTO]: EggTier.COMMON, + [Species.EEVEE]: EggTier.COMMON, + [Species.PORYGON]: EggTier.RARE, + [Species.OMANYTE]: EggTier.COMMON, + [Species.KABUTO]: EggTier.COMMON, + [Species.AERODACTYL]: EggTier.RARE, + [Species.SNORLAX]: EggTier.RARE, + [Species.ARTICUNO]: EggTier.EPIC, + [Species.ZAPDOS]: EggTier.EPIC, + [Species.MOLTRES]: EggTier.EPIC, + [Species.DRATINI]: EggTier.RARE, + [Species.MEWTWO]: EggTier.LEGENDARY, + [Species.MEW]: EggTier.EPIC, + + [Species.CHIKORITA]: EggTier.COMMON, + [Species.CYNDAQUIL]: EggTier.COMMON, + [Species.TOTODILE]: EggTier.COMMON, + [Species.SENTRET]: EggTier.COMMON, + [Species.HOOTHOOT]: EggTier.COMMON, + [Species.LEDYBA]: EggTier.COMMON, + [Species.SPINARAK]: EggTier.COMMON, + [Species.CHINCHOU]: EggTier.COMMON, + [Species.PICHU]: EggTier.COMMON, + [Species.CLEFFA]: EggTier.COMMON, + [Species.IGGLYBUFF]: EggTier.COMMON, + [Species.TOGEPI]: EggTier.COMMON, + [Species.NATU]: EggTier.COMMON, + [Species.MAREEP]: EggTier.COMMON, + [Species.MARILL]: EggTier.RARE, + [Species.SUDOWOODO]: EggTier.COMMON, + [Species.HOPPIP]: EggTier.COMMON, + [Species.AIPOM]: EggTier.COMMON, + [Species.SUNKERN]: EggTier.COMMON, + [Species.YANMA]: EggTier.COMMON, + [Species.WOOPER]: EggTier.COMMON, + [Species.MURKROW]: EggTier.COMMON, + [Species.MISDREAVUS]: EggTier.COMMON, + [Species.UNOWN]: EggTier.COMMON, + [Species.WOBBUFFET]: EggTier.COMMON, + [Species.GIRAFARIG]: EggTier.COMMON, + [Species.PINECO]: EggTier.COMMON, + [Species.DUNSPARCE]: EggTier.COMMON, + [Species.GLIGAR]: EggTier.COMMON, + [Species.SNUBBULL]: EggTier.COMMON, + [Species.QWILFISH]: EggTier.COMMON, + [Species.SHUCKLE]: EggTier.COMMON, + [Species.HERACROSS]: EggTier.RARE, + [Species.SNEASEL]: EggTier.RARE, + [Species.TEDDIURSA]: EggTier.RARE, + [Species.SLUGMA]: EggTier.COMMON, + [Species.SWINUB]: EggTier.COMMON, + [Species.CORSOLA]: EggTier.COMMON, + [Species.REMORAID]: EggTier.COMMON, + [Species.DELIBIRD]: EggTier.COMMON, + [Species.MANTINE]: EggTier.COMMON, + [Species.SKARMORY]: EggTier.RARE, + [Species.HOUNDOUR]: EggTier.COMMON, + [Species.PHANPY]: EggTier.COMMON, + [Species.STANTLER]: EggTier.COMMON, + [Species.SMEARGLE]: EggTier.COMMON, + [Species.TYROGUE]: EggTier.COMMON, + [Species.SMOOCHUM]: EggTier.COMMON, + [Species.ELEKID]: EggTier.COMMON, + [Species.MAGBY]: EggTier.COMMON, + [Species.MILTANK]: EggTier.RARE, + [Species.RAIKOU]: EggTier.EPIC, + [Species.ENTEI]: EggTier.EPIC, + [Species.SUICUNE]: EggTier.EPIC, + [Species.LARVITAR]: EggTier.RARE, + [Species.LUGIA]: EggTier.LEGENDARY, + [Species.HO_OH]: EggTier.LEGENDARY, + [Species.CELEBI]: EggTier.EPIC, + + [Species.TREECKO]: EggTier.COMMON, + [Species.TORCHIC]: EggTier.RARE, + [Species.MUDKIP]: EggTier.COMMON, + [Species.POOCHYENA]: EggTier.COMMON, + [Species.ZIGZAGOON]: EggTier.COMMON, + [Species.WURMPLE]: EggTier.COMMON, + [Species.LOTAD]: EggTier.COMMON, + [Species.SEEDOT]: EggTier.COMMON, + [Species.TAILLOW]: EggTier.COMMON, + [Species.WINGULL]: EggTier.COMMON, + [Species.RALTS]: EggTier.COMMON, + [Species.SURSKIT]: EggTier.COMMON, + [Species.SHROOMISH]: EggTier.COMMON, + [Species.SLAKOTH]: EggTier.RARE, + [Species.NINCADA]: EggTier.RARE, + [Species.WHISMUR]: EggTier.COMMON, + [Species.MAKUHITA]: EggTier.COMMON, + [Species.AZURILL]: EggTier.RARE, + [Species.NOSEPASS]: EggTier.COMMON, + [Species.SKITTY]: EggTier.COMMON, + [Species.SABLEYE]: EggTier.COMMON, + [Species.MAWILE]: EggTier.COMMON, + [Species.ARON]: EggTier.COMMON, + [Species.MEDITITE]: EggTier.COMMON, + [Species.ELECTRIKE]: EggTier.COMMON, + [Species.PLUSLE]: EggTier.COMMON, + [Species.MINUN]: EggTier.COMMON, + [Species.VOLBEAT]: EggTier.COMMON, + [Species.ILLUMISE]: EggTier.COMMON, + [Species.ROSELIA]: EggTier.COMMON, + [Species.GULPIN]: EggTier.COMMON, + [Species.CARVANHA]: EggTier.COMMON, + [Species.WAILMER]: EggTier.COMMON, + [Species.NUMEL]: EggTier.COMMON, + [Species.TORKOAL]: EggTier.COMMON, + [Species.SPOINK]: EggTier.COMMON, + [Species.SPINDA]: EggTier.COMMON, + [Species.TRAPINCH]: EggTier.COMMON, + [Species.CACNEA]: EggTier.COMMON, + [Species.SWABLU]: EggTier.COMMON, + [Species.ZANGOOSE]: EggTier.RARE, + [Species.SEVIPER]: EggTier.COMMON, + [Species.LUNATONE]: EggTier.COMMON, + [Species.SOLROCK]: EggTier.COMMON, + [Species.BARBOACH]: EggTier.COMMON, + [Species.CORPHISH]: EggTier.COMMON, + [Species.BALTOY]: EggTier.COMMON, + [Species.LILEEP]: EggTier.COMMON, + [Species.ANORITH]: EggTier.COMMON, + [Species.FEEBAS]: EggTier.RARE, + [Species.CASTFORM]: EggTier.COMMON, + [Species.KECLEON]: EggTier.COMMON, + [Species.SHUPPET]: EggTier.COMMON, + [Species.DUSKULL]: EggTier.COMMON, + [Species.TROPIUS]: EggTier.COMMON, + [Species.CHIMECHO]: EggTier.COMMON, + [Species.ABSOL]: EggTier.RARE, + [Species.WYNAUT]: EggTier.COMMON, + [Species.SNORUNT]: EggTier.COMMON, + [Species.SPHEAL]: EggTier.COMMON, + [Species.CLAMPERL]: EggTier.COMMON, + [Species.RELICANTH]: EggTier.COMMON, + [Species.LUVDISC]: EggTier.COMMON, + [Species.BAGON]: EggTier.RARE, + [Species.BELDUM]: EggTier.RARE, + [Species.REGIROCK]: EggTier.EPIC, + [Species.REGICE]: EggTier.EPIC, + [Species.REGISTEEL]: EggTier.EPIC, + [Species.LATIAS]: EggTier.EPIC, + [Species.LATIOS]: EggTier.EPIC, + [Species.KYOGRE]: EggTier.LEGENDARY, + [Species.GROUDON]: EggTier.LEGENDARY, + [Species.RAYQUAZA]: EggTier.LEGENDARY, + [Species.JIRACHI]: EggTier.EPIC, + [Species.DEOXYS]: EggTier.EPIC, + + [Species.TURTWIG]: EggTier.COMMON, + [Species.CHIMCHAR]: EggTier.COMMON, + [Species.PIPLUP]: EggTier.COMMON, + [Species.STARLY]: EggTier.COMMON, + [Species.BIDOOF]: EggTier.COMMON, + [Species.KRICKETOT]: EggTier.COMMON, + [Species.SHINX]: EggTier.COMMON, + [Species.BUDEW]: EggTier.COMMON, + [Species.CRANIDOS]: EggTier.COMMON, + [Species.SHIELDON]: EggTier.COMMON, + [Species.BURMY]: EggTier.COMMON, + [Species.COMBEE]: EggTier.COMMON, + [Species.PACHIRISU]: EggTier.COMMON, + [Species.BUIZEL]: EggTier.COMMON, + [Species.CHERUBI]: EggTier.COMMON, + [Species.SHELLOS]: EggTier.COMMON, + [Species.DRIFLOON]: EggTier.COMMON, + [Species.BUNEARY]: EggTier.COMMON, + [Species.GLAMEOW]: EggTier.COMMON, + [Species.CHINGLING]: EggTier.COMMON, + [Species.STUNKY]: EggTier.COMMON, + [Species.BRONZOR]: EggTier.COMMON, + [Species.BONSLY]: EggTier.COMMON, + [Species.MIME_JR]: EggTier.COMMON, + [Species.HAPPINY]: EggTier.COMMON, + [Species.CHATOT]: EggTier.COMMON, + [Species.SPIRITOMB]: EggTier.RARE, + [Species.GIBLE]: EggTier.RARE, + [Species.MUNCHLAX]: EggTier.RARE, + [Species.RIOLU]: EggTier.COMMON, + [Species.HIPPOPOTAS]: EggTier.COMMON, + [Species.SKORUPI]: EggTier.COMMON, + [Species.CROAGUNK]: EggTier.COMMON, + [Species.CARNIVINE]: EggTier.COMMON, + [Species.FINNEON]: EggTier.COMMON, + [Species.MANTYKE]: EggTier.COMMON, + [Species.SNOVER]: EggTier.COMMON, + [Species.ROTOM]: EggTier.RARE, + [Species.UXIE]: EggTier.EPIC, + [Species.MESPRIT]: EggTier.EPIC, + [Species.AZELF]: EggTier.EPIC, + [Species.DIALGA]: EggTier.LEGENDARY, + [Species.PALKIA]: EggTier.LEGENDARY, + [Species.HEATRAN]: EggTier.EPIC, + [Species.REGIGIGAS]: EggTier.EPIC, + [Species.GIRATINA]: EggTier.LEGENDARY, + [Species.CRESSELIA]: EggTier.EPIC, + [Species.PHIONE]: EggTier.RARE, + [Species.MANAPHY]: EggTier.EPIC, + [Species.DARKRAI]: EggTier.EPIC, + [Species.SHAYMIN]: EggTier.EPIC, + [Species.ARCEUS]: EggTier.LEGENDARY, + + [Species.VICTINI]: EggTier.EPIC, + [Species.SNIVY]: EggTier.COMMON, + [Species.TEPIG]: EggTier.COMMON, + [Species.OSHAWOTT]: EggTier.COMMON, + [Species.PATRAT]: EggTier.COMMON, + [Species.LILLIPUP]: EggTier.COMMON, + [Species.PURRLOIN]: EggTier.COMMON, + [Species.PANSAGE]: EggTier.COMMON, + [Species.PANSEAR]: EggTier.COMMON, + [Species.PANPOUR]: EggTier.COMMON, + [Species.MUNNA]: EggTier.COMMON, + [Species.PIDOVE]: EggTier.COMMON, + [Species.BLITZLE]: EggTier.COMMON, + [Species.ROGGENROLA]: EggTier.COMMON, + [Species.WOOBAT]: EggTier.COMMON, + [Species.DRILBUR]: EggTier.RARE, + [Species.AUDINO]: EggTier.COMMON, + [Species.TIMBURR]: EggTier.RARE, + [Species.TYMPOLE]: EggTier.COMMON, + [Species.THROH]: EggTier.RARE, + [Species.SAWK]: EggTier.RARE, + [Species.SEWADDLE]: EggTier.COMMON, + [Species.VENIPEDE]: EggTier.COMMON, + [Species.COTTONEE]: EggTier.COMMON, + [Species.PETILIL]: EggTier.COMMON, + [Species.BASCULIN]: EggTier.RARE, + [Species.SANDILE]: EggTier.RARE, + [Species.DARUMAKA]: EggTier.RARE, + [Species.MARACTUS]: EggTier.COMMON, + [Species.DWEBBLE]: EggTier.COMMON, + [Species.SCRAGGY]: EggTier.COMMON, + [Species.SIGILYPH]: EggTier.RARE, + [Species.YAMASK]: EggTier.COMMON, + [Species.TIRTOUGA]: EggTier.COMMON, + [Species.ARCHEN]: EggTier.COMMON, + [Species.TRUBBISH]: EggTier.COMMON, + [Species.ZORUA]: EggTier.COMMON, + [Species.MINCCINO]: EggTier.COMMON, + [Species.GOTHITA]: EggTier.COMMON, + [Species.SOLOSIS]: EggTier.COMMON, + [Species.DUCKLETT]: EggTier.COMMON, + [Species.VANILLITE]: EggTier.COMMON, + [Species.DEERLING]: EggTier.COMMON, + [Species.EMOLGA]: EggTier.COMMON, + [Species.KARRABLAST]: EggTier.COMMON, + [Species.FOONGUS]: EggTier.COMMON, + [Species.FRILLISH]: EggTier.COMMON, + [Species.ALOMOMOLA]: EggTier.RARE, + [Species.JOLTIK]: EggTier.COMMON, + [Species.FERROSEED]: EggTier.COMMON, + [Species.KLINK]: EggTier.COMMON, + [Species.TYNAMO]: EggTier.COMMON, + [Species.ELGYEM]: EggTier.COMMON, + [Species.LITWICK]: EggTier.COMMON, + [Species.AXEW]: EggTier.RARE, + [Species.CUBCHOO]: EggTier.COMMON, + [Species.CRYOGONAL]: EggTier.RARE, + [Species.SHELMET]: EggTier.COMMON, + [Species.STUNFISK]: EggTier.COMMON, + [Species.MIENFOO]: EggTier.COMMON, + [Species.DRUDDIGON]: EggTier.RARE, + [Species.GOLETT]: EggTier.COMMON, + [Species.PAWNIARD]: EggTier.RARE, + [Species.BOUFFALANT]: EggTier.RARE, + [Species.RUFFLET]: EggTier.COMMON, + [Species.VULLABY]: EggTier.COMMON, + [Species.HEATMOR]: EggTier.COMMON, + [Species.DURANT]: EggTier.RARE, + [Species.DEINO]: EggTier.RARE, + [Species.LARVESTA]: EggTier.RARE, + [Species.COBALION]: EggTier.EPIC, + [Species.TERRAKION]: EggTier.EPIC, + [Species.VIRIZION]: EggTier.EPIC, + [Species.TORNADUS]: EggTier.EPIC, + [Species.THUNDURUS]: EggTier.EPIC, + [Species.RESHIRAM]: EggTier.LEGENDARY, + [Species.ZEKROM]: EggTier.LEGENDARY, + [Species.LANDORUS]: EggTier.EPIC, + [Species.KYUREM]: EggTier.LEGENDARY, + [Species.KELDEO]: EggTier.EPIC, + [Species.MELOETTA]: EggTier.EPIC, + [Species.GENESECT]: EggTier.EPIC, + + [Species.CHESPIN]: EggTier.COMMON, + [Species.FENNEKIN]: EggTier.COMMON, + [Species.FROAKIE]: EggTier.RARE, + [Species.BUNNELBY]: EggTier.COMMON, + [Species.FLETCHLING]: EggTier.COMMON, + [Species.SCATTERBUG]: EggTier.COMMON, + [Species.LITLEO]: EggTier.COMMON, + [Species.FLABEBE]: EggTier.COMMON, + [Species.SKIDDO]: EggTier.COMMON, + [Species.PANCHAM]: EggTier.COMMON, + [Species.FURFROU]: EggTier.COMMON, + [Species.ESPURR]: EggTier.COMMON, + [Species.HONEDGE]: EggTier.RARE, + [Species.SPRITZEE]: EggTier.COMMON, + [Species.SWIRLIX]: EggTier.COMMON, + [Species.INKAY]: EggTier.COMMON, + [Species.BINACLE]: EggTier.COMMON, + [Species.SKRELP]: EggTier.COMMON, + [Species.CLAUNCHER]: EggTier.COMMON, + [Species.HELIOPTILE]: EggTier.COMMON, + [Species.TYRUNT]: EggTier.COMMON, + [Species.AMAURA]: EggTier.COMMON, + [Species.HAWLUCHA]: EggTier.RARE, + [Species.DEDENNE]: EggTier.COMMON, + [Species.CARBINK]: EggTier.COMMON, + [Species.GOOMY]: EggTier.RARE, + [Species.KLEFKI]: EggTier.COMMON, + [Species.PHANTUMP]: EggTier.COMMON, + [Species.PUMPKABOO]: EggTier.COMMON, + [Species.BERGMITE]: EggTier.COMMON, + [Species.NOIBAT]: EggTier.COMMON, + [Species.XERNEAS]: EggTier.LEGENDARY, + [Species.YVELTAL]: EggTier.LEGENDARY, + [Species.ZYGARDE]: EggTier.LEGENDARY, + [Species.DIANCIE]: EggTier.EPIC, + [Species.HOOPA]: EggTier.EPIC, + [Species.VOLCANION]: EggTier.EPIC, + [Species.ETERNAL_FLOETTE]: EggTier.RARE, + + [Species.ROWLET]: EggTier.COMMON, + [Species.LITTEN]: EggTier.COMMON, + [Species.POPPLIO]: EggTier.RARE, + [Species.PIKIPEK]: EggTier.COMMON, + [Species.YUNGOOS]: EggTier.COMMON, + [Species.GRUBBIN]: EggTier.COMMON, + [Species.CRABRAWLER]: EggTier.COMMON, + [Species.ORICORIO]: EggTier.COMMON, + [Species.CUTIEFLY]: EggTier.COMMON, + [Species.ROCKRUFF]: EggTier.COMMON, + [Species.WISHIWASHI]: EggTier.COMMON, + [Species.MAREANIE]: EggTier.COMMON, + [Species.MUDBRAY]: EggTier.COMMON, + [Species.DEWPIDER]: EggTier.COMMON, + [Species.FOMANTIS]: EggTier.COMMON, + [Species.MORELULL]: EggTier.COMMON, + [Species.SALANDIT]: EggTier.COMMON, + [Species.STUFFUL]: EggTier.COMMON, + [Species.BOUNSWEET]: EggTier.COMMON, + [Species.COMFEY]: EggTier.RARE, + [Species.ORANGURU]: EggTier.RARE, + [Species.PASSIMIAN]: EggTier.RARE, + [Species.WIMPOD]: EggTier.COMMON, + [Species.SANDYGAST]: EggTier.COMMON, + [Species.PYUKUMUKU]: EggTier.COMMON, + [Species.TYPE_NULL]: EggTier.RARE, + [Species.MINIOR]: EggTier.RARE, + [Species.KOMALA]: EggTier.COMMON, + [Species.TURTONATOR]: EggTier.RARE, + [Species.TOGEDEMARU]: EggTier.COMMON, + [Species.MIMIKYU]: EggTier.RARE, + [Species.BRUXISH]: EggTier.RARE, + [Species.DRAMPA]: EggTier.RARE, + [Species.DHELMISE]: EggTier.RARE, + [Species.JANGMO_O]: EggTier.RARE, + [Species.TAPU_KOKO]: EggTier.EPIC, + [Species.TAPU_LELE]: EggTier.EPIC, + [Species.TAPU_BULU]: EggTier.EPIC, + [Species.TAPU_FINI]: EggTier.EPIC, + [Species.COSMOG]: EggTier.EPIC, + [Species.NIHILEGO]: EggTier.EPIC, + [Species.BUZZWOLE]: EggTier.EPIC, + [Species.PHEROMOSA]: EggTier.EPIC, + [Species.XURKITREE]: EggTier.EPIC, + [Species.CELESTEELA]: EggTier.EPIC, + [Species.KARTANA]: EggTier.EPIC, + [Species.GUZZLORD]: EggTier.EPIC, + [Species.NECROZMA]: EggTier.LEGENDARY, + [Species.MAGEARNA]: EggTier.EPIC, + [Species.MARSHADOW]: EggTier.EPIC, + [Species.POIPOLE]: EggTier.EPIC, + [Species.STAKATAKA]: EggTier.EPIC, + [Species.BLACEPHALON]: EggTier.EPIC, + [Species.ZERAORA]: EggTier.EPIC, + [Species.MELTAN]: EggTier.EPIC, + [Species.ALOLA_RATTATA]: EggTier.COMMON, + [Species.ALOLA_SANDSHREW]: EggTier.COMMON, + [Species.ALOLA_VULPIX]: EggTier.COMMON, + [Species.ALOLA_DIGLETT]: EggTier.COMMON, + [Species.ALOLA_MEOWTH]: EggTier.COMMON, + [Species.ALOLA_GEODUDE]: EggTier.COMMON, + [Species.ALOLA_GRIMER]: EggTier.COMMON, + + [Species.GROOKEY]: EggTier.COMMON, + [Species.SCORBUNNY]: EggTier.RARE, + [Species.SOBBLE]: EggTier.COMMON, + [Species.SKWOVET]: EggTier.COMMON, + [Species.ROOKIDEE]: EggTier.COMMON, + [Species.BLIPBUG]: EggTier.COMMON, + [Species.NICKIT]: EggTier.COMMON, + [Species.GOSSIFLEUR]: EggTier.COMMON, + [Species.WOOLOO]: EggTier.COMMON, + [Species.CHEWTLE]: EggTier.COMMON, + [Species.YAMPER]: EggTier.COMMON, + [Species.ROLYCOLY]: EggTier.COMMON, + [Species.APPLIN]: EggTier.COMMON, + [Species.SILICOBRA]: EggTier.COMMON, + [Species.CRAMORANT]: EggTier.COMMON, + [Species.ARROKUDA]: EggTier.COMMON, + [Species.TOXEL]: EggTier.COMMON, + [Species.SIZZLIPEDE]: EggTier.COMMON, + [Species.CLOBBOPUS]: EggTier.COMMON, + [Species.SINISTEA]: EggTier.COMMON, + [Species.HATENNA]: EggTier.COMMON, + [Species.IMPIDIMP]: EggTier.COMMON, + [Species.MILCERY]: EggTier.COMMON, + [Species.FALINKS]: EggTier.RARE, + [Species.PINCURCHIN]: EggTier.COMMON, + [Species.SNOM]: EggTier.COMMON, + [Species.STONJOURNER]: EggTier.COMMON, + [Species.EISCUE]: EggTier.COMMON, + [Species.INDEEDEE]: EggTier.RARE, + [Species.MORPEKO]: EggTier.COMMON, + [Species.CUFANT]: EggTier.COMMON, + [Species.DRACOZOLT]: EggTier.RARE, + [Species.ARCTOZOLT]: EggTier.RARE, + [Species.DRACOVISH]: EggTier.RARE, + [Species.ARCTOVISH]: EggTier.RARE, + [Species.DURALUDON]: EggTier.RARE, + [Species.DREEPY]: EggTier.RARE, + [Species.ZACIAN]: EggTier.LEGENDARY, + [Species.ZAMAZENTA]: EggTier.LEGENDARY, + [Species.ETERNATUS]: EggTier.COMMON, + [Species.KUBFU]: EggTier.EPIC, + [Species.ZARUDE]: EggTier.EPIC, + [Species.REGIELEKI]: EggTier.EPIC, + [Species.REGIDRAGO]: EggTier.EPIC, + [Species.GLASTRIER]: EggTier.EPIC, + [Species.SPECTRIER]: EggTier.EPIC, + [Species.CALYREX]: EggTier.LEGENDARY, + [Species.GALAR_MEOWTH]: EggTier.COMMON, + [Species.GALAR_PONYTA]: EggTier.COMMON, + [Species.GALAR_SLOWPOKE]: EggTier.COMMON, + [Species.GALAR_FARFETCHD]: EggTier.COMMON, + [Species.GALAR_CORSOLA]: EggTier.COMMON, + [Species.GALAR_ZIGZAGOON]: EggTier.COMMON, + [Species.GALAR_DARUMAKA]: EggTier.RARE, + [Species.GALAR_YAMASK]: EggTier.COMMON, + [Species.GALAR_STUNFISK]: EggTier.COMMON, + [Species.GALAR_MR_MIME]: EggTier.COMMON, + [Species.GALAR_ARTICUNO]: EggTier.EPIC, + [Species.GALAR_ZAPDOS]: EggTier.EPIC, + [Species.GALAR_MOLTRES]: EggTier.EPIC, + [Species.HISUI_GROWLITHE]: EggTier.RARE, + [Species.HISUI_VOLTORB]: EggTier.COMMON, + [Species.HISUI_QWILFISH]: EggTier.RARE, + [Species.HISUI_SNEASEL]: EggTier.RARE, + [Species.HISUI_ZORUA]: EggTier.COMMON, + [Species.ENAMORUS]: EggTier.EPIC, + + [Species.SPRIGATITO]: EggTier.RARE, + [Species.FUECOCO]: EggTier.RARE, + [Species.QUAXLY]: EggTier.RARE, + [Species.LECHONK]: EggTier.COMMON, + [Species.TAROUNTULA]: EggTier.COMMON, + [Species.NYMBLE]: EggTier.COMMON, + [Species.PAWMI]: EggTier.COMMON, + [Species.TANDEMAUS]: EggTier.RARE, + [Species.FIDOUGH]: EggTier.COMMON, + [Species.SMOLIV]: EggTier.COMMON, + [Species.SQUAWKABILLY]: EggTier.COMMON, + [Species.NACLI]: EggTier.RARE, + [Species.CHARCADET]: EggTier.RARE, + [Species.TADBULB]: EggTier.COMMON, + [Species.WATTREL]: EggTier.COMMON, + [Species.MASCHIFF]: EggTier.COMMON, + [Species.SHROODLE]: EggTier.COMMON, + [Species.BRAMBLIN]: EggTier.COMMON, + [Species.TOEDSCOOL]: EggTier.COMMON, + [Species.KLAWF]: EggTier.COMMON, + [Species.CAPSAKID]: EggTier.COMMON, + [Species.RELLOR]: EggTier.COMMON, + [Species.FLITTLE]: EggTier.COMMON, + [Species.TINKATINK]: EggTier.RARE, + [Species.WIGLETT]: EggTier.COMMON, + [Species.BOMBIRDIER]: EggTier.COMMON, + [Species.FINIZEN]: EggTier.COMMON, + [Species.VAROOM]: EggTier.RARE, + [Species.CYCLIZAR]: EggTier.RARE, + [Species.ORTHWORM]: EggTier.RARE, + [Species.GLIMMET]: EggTier.RARE, + [Species.GREAVARD]: EggTier.COMMON, + [Species.FLAMIGO]: EggTier.RARE, + [Species.CETODDLE]: EggTier.COMMON, + [Species.VELUZA]: EggTier.RARE, + [Species.DONDOZO]: EggTier.RARE, + [Species.TATSUGIRI]: EggTier.RARE, + [Species.GREAT_TUSK]: EggTier.EPIC, + [Species.SCREAM_TAIL]: EggTier.EPIC, + [Species.BRUTE_BONNET]: EggTier.EPIC, + [Species.FLUTTER_MANE]: EggTier.EPIC, + [Species.SLITHER_WING]: EggTier.EPIC, + [Species.SANDY_SHOCKS]: EggTier.EPIC, + [Species.IRON_TREADS]: EggTier.EPIC, + [Species.IRON_BUNDLE]: EggTier.EPIC, + [Species.IRON_HANDS]: EggTier.EPIC, + [Species.IRON_JUGULIS]: EggTier.EPIC, + [Species.IRON_MOTH]: EggTier.EPIC, + [Species.IRON_THORNS]: EggTier.EPIC, + [Species.FRIGIBAX]: EggTier.RARE, + [Species.GIMMIGHOUL]: EggTier.RARE, + [Species.WO_CHIEN]: EggTier.EPIC, + [Species.CHIEN_PAO]: EggTier.EPIC, + [Species.TING_LU]: EggTier.EPIC, + [Species.CHI_YU]: EggTier.EPIC, + [Species.ROARING_MOON]: EggTier.EPIC, + [Species.IRON_VALIANT]: EggTier.EPIC, + [Species.KORAIDON]: EggTier.LEGENDARY, + [Species.MIRAIDON]: EggTier.LEGENDARY, + [Species.WALKING_WAKE]: EggTier.EPIC, + [Species.IRON_LEAVES]: EggTier.EPIC, + [Species.POLTCHAGEIST]: EggTier.RARE, + [Species.OKIDOGI]: EggTier.EPIC, + [Species.MUNKIDORI]: EggTier.EPIC, + [Species.FEZANDIPITI]: EggTier.EPIC, + [Species.OGERPON]: EggTier.EPIC, + [Species.GOUGING_FIRE]: EggTier.EPIC, + [Species.RAGING_BOLT]: EggTier.EPIC, + [Species.IRON_BOULDER]: EggTier.EPIC, + [Species.IRON_CROWN]: EggTier.EPIC, + [Species.TERAPAGOS]: EggTier.LEGENDARY, + [Species.PECHARUNT]: EggTier.EPIC, + [Species.PALDEA_TAUROS]: EggTier.RARE, + [Species.PALDEA_WOOPER]: EggTier.COMMON, + [Species.BLOODMOON_URSALUNA]: EggTier.EPIC, +}; diff --git a/src/data/egg.ts b/src/data/egg.ts index 5fffe4fcece..c475fc729e6 100644 --- a/src/data/egg.ts +++ b/src/data/egg.ts @@ -11,6 +11,7 @@ import { EggTier } from "#enums/egg-type"; import { Species } from "#enums/species"; import { EggSourceType } from "#enums/egg-source-types"; import { MANAPHY_EGG_MANAPHY_RATE, SAME_SPECIES_EGG_HA_RATE, GACHA_EGG_HA_RATE, GACHA_DEFAULT_RARE_EGGMOVE_RATE, SAME_SPECIES_EGG_RARE_EGGMOVE_RATE, GACHA_MOVE_UP_RARE_EGGMOVE_RATE, GACHA_DEFAULT_SHINY_RATE, GACHA_SHINY_UP_SHINY_RATE, SAME_SPECIES_EGG_SHINY_RATE, EGG_PITY_LEGENDARY_THRESHOLD, EGG_PITY_EPIC_THRESHOLD, EGG_PITY_RARE_THRESHOLD, SHINY_VARIANT_CHANCE, SHINY_EPIC_CHANCE, GACHA_DEFAULT_COMMON_EGG_THRESHOLD, GACHA_DEFAULT_RARE_EGG_THRESHOLD, GACHA_DEFAULT_EPIC_EGG_THRESHOLD, GACHA_LEGENDARY_UP_THRESHOLD_OFFSET, HATCH_WAVES_MANAPHY_EGG, HATCH_WAVES_COMMON_EGG, HATCH_WAVES_RARE_EGG, HATCH_WAVES_EPIC_EGG, HATCH_WAVES_LEGENDARY_EGG } from "#app/data/balance/rates"; +import { speciesEggTiers } from "#app/data/balance/species-egg-tiers"; export const EGG_SEED = 1073741824; @@ -160,7 +161,7 @@ export class Egg { // Override egg tier and hatchwaves if species was given if (eggOptions?.species) { - this._tier = this.getEggTierFromSpeciesStarterValue(); + this._tier = this.getEggTier(); this._hatchWaves = eggOptions.hatchWaves ?? this.getEggTierDefaultHatchWaves(); } // If species has no variant, set variantTier to common. This needs to @@ -261,11 +262,11 @@ export class Egg { return "Manaphy"; } switch (this.tier) { - case EggTier.GREAT: + case EggTier.RARE: return i18next.t("egg:greatTier"); - case EggTier.ULTRA: + case EggTier.EPIC: return i18next.t("egg:ultraTier"); - case EggTier.MASTER: + case EggTier.LEGENDARY: return i18next.t("egg:masterTier"); default: return i18next.t("egg:defaultTier"); @@ -336,9 +337,9 @@ export class Egg { switch (eggTier ?? this._tier) { case EggTier.COMMON: return HATCH_WAVES_COMMON_EGG; - case EggTier.GREAT: + case EggTier.RARE: return HATCH_WAVES_RARE_EGG; - case EggTier.ULTRA: + case EggTier.EPIC: return HATCH_WAVES_EPIC_EGG; } return HATCH_WAVES_LEGENDARY_EGG; @@ -347,7 +348,7 @@ export class Egg { private rollEggTier(): EggTier { const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? GACHA_LEGENDARY_UP_THRESHOLD_OFFSET : 0; const tierValue = Utils.randInt(256); - return tierValue >= GACHA_DEFAULT_COMMON_EGG_THRESHOLD + tierValueOffset ? EggTier.COMMON : tierValue >= GACHA_DEFAULT_RARE_EGG_THRESHOLD + tierValueOffset ? EggTier.GREAT : tierValue >= GACHA_DEFAULT_EPIC_EGG_THRESHOLD + tierValueOffset ? EggTier.ULTRA : EggTier.MASTER; + return tierValue >= GACHA_DEFAULT_COMMON_EGG_THRESHOLD + tierValueOffset ? EggTier.COMMON : tierValue >= GACHA_DEFAULT_RARE_EGG_THRESHOLD + tierValueOffset ? EggTier.RARE : tierValue >= GACHA_DEFAULT_EPIC_EGG_THRESHOLD + tierValueOffset ? EggTier.EPIC : EggTier.LEGENDARY; } private rollSpecies(scene: BattleScene): Species | null { @@ -367,7 +368,7 @@ export class Egg { */ const rand = (Utils.randSeedInt(MANAPHY_EGG_MANAPHY_RATE) !== 1); return rand ? Species.PHIONE : Species.MANAPHY; - } else if (this.tier === EggTier.MASTER + } else if (this.tier === EggTier.LEGENDARY && this._sourceType === EggSourceType.GACHA_LEGENDARY) { if (!Utils.randSeedInt(2)) { return getLegendaryGachaSpeciesForTimestamp(scene, this.timestamp); @@ -378,15 +379,15 @@ export class Egg { let maxStarterValue: integer; switch (this.tier) { - case EggTier.GREAT: + case EggTier.RARE: minStarterValue = 4; maxStarterValue = 5; break; - case EggTier.ULTRA: + case EggTier.EPIC: minStarterValue = 6; maxStarterValue = 7; break; - case EggTier.MASTER: + case EggTier.LEGENDARY: minStarterValue = 8; maxStarterValue = 9; break; @@ -398,8 +399,8 @@ export class Egg { const ignoredSpecies = [ Species.PHIONE, Species.MANAPHY, Species.ETERNATUS ]; - let speciesPool = Object.keys(speciesStarterCosts) - .filter(s => speciesStarterCosts[s] >= minStarterValue && speciesStarterCosts[s] <= maxStarterValue) + let speciesPool = Object.keys(speciesEggTiers) + .filter(s => speciesEggTiers[s] === this.tier) .map(s => parseInt(s) as Species) .filter(s => !pokemonPrevolutions.hasOwnProperty(s) && getPokemonSpecies(s).isObtainable() && ignoredSpecies.indexOf(s) === -1); @@ -430,7 +431,9 @@ export class Egg { let totalWeight = 0; const speciesWeights : number[] = []; for (const speciesId of speciesPool) { - let weight = Math.floor((((maxStarterValue - speciesStarterCosts[speciesId]) / ((maxStarterValue - minStarterValue) + 1)) * 1.5 + 1) * 100); + // Accounts for species that have starter costs outside of the normal range for their EggTier + const speciesCostClamped = Phaser.Math.Clamp(speciesStarterCosts[speciesId], minStarterValue, maxStarterValue); + let weight = Math.floor((((maxStarterValue - speciesCostClamped) / ((maxStarterValue - minStarterValue) + 1)) * 1.5 + 1) * 100); const species = getPokemonSpecies(speciesId); if (species.isRegional()) { weight = Math.floor(weight / 2); @@ -498,16 +501,16 @@ export class Egg { private checkForPityTierOverrides(scene: BattleScene): void { const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? GACHA_LEGENDARY_UP_THRESHOLD_OFFSET : 0; - scene.gameData.eggPity[EggTier.GREAT] += 1; - scene.gameData.eggPity[EggTier.ULTRA] += 1; - scene.gameData.eggPity[EggTier.MASTER] += 1 + tierValueOffset; + scene.gameData.eggPity[EggTier.RARE] += 1; + scene.gameData.eggPity[EggTier.EPIC] += 1; + scene.gameData.eggPity[EggTier.LEGENDARY] += 1 + tierValueOffset; // These numbers are roughly the 80% mark. That is, 80% of the time you'll get an egg before this gets triggered. - if (scene.gameData.eggPity[EggTier.MASTER] >= EGG_PITY_LEGENDARY_THRESHOLD && this._tier === EggTier.COMMON) { - this._tier = EggTier.MASTER; - } else if (scene.gameData.eggPity[EggTier.ULTRA] >= EGG_PITY_EPIC_THRESHOLD && this._tier === EggTier.COMMON) { - this._tier = EggTier.ULTRA; - } else if (scene.gameData.eggPity[EggTier.GREAT] >= EGG_PITY_RARE_THRESHOLD && this._tier === EggTier.COMMON) { - this._tier = EggTier.GREAT; + if (scene.gameData.eggPity[EggTier.LEGENDARY] >= EGG_PITY_LEGENDARY_THRESHOLD && this._tier === EggTier.COMMON) { + this._tier = EggTier.LEGENDARY; + } else if (scene.gameData.eggPity[EggTier.EPIC] >= EGG_PITY_EPIC_THRESHOLD && this._tier === EggTier.COMMON) { + this._tier = EggTier.EPIC; + } else if (scene.gameData.eggPity[EggTier.RARE] >= EGG_PITY_RARE_THRESHOLD && this._tier === EggTier.COMMON) { + this._tier = EggTier.RARE; } scene.gameData.eggPity[this._tier] = 0; } @@ -516,38 +519,24 @@ export class Egg { scene.gameData.gameStats.eggsPulled++; if (this.isManaphyEgg()) { scene.gameData.gameStats.manaphyEggsPulled++; - this._hatchWaves = this.getEggTierDefaultHatchWaves(EggTier.ULTRA); + this._hatchWaves = this.getEggTierDefaultHatchWaves(EggTier.EPIC); return; } switch (this.tier) { - case EggTier.GREAT: + case EggTier.RARE: scene.gameData.gameStats.rareEggsPulled++; break; - case EggTier.ULTRA: + case EggTier.EPIC: scene.gameData.gameStats.epicEggsPulled++; break; - case EggTier.MASTER: + case EggTier.LEGENDARY: scene.gameData.gameStats.legendaryEggsPulled++; break; } } - private getEggTierFromSpeciesStarterValue(): EggTier { - const speciesStartValue = speciesStarterCosts[this.species]; - if (speciesStartValue >= 1 && speciesStartValue <= 3) { - return EggTier.COMMON; - } - if (speciesStartValue >= 4 && speciesStartValue <= 5) { - return EggTier.GREAT; - } - if (speciesStartValue >= 6 && speciesStartValue <= 7) { - return EggTier.ULTRA; - } - if (speciesStartValue >= 8) { - return EggTier.MASTER; - } - - return EggTier.COMMON; + private getEggTier(): EggTier { + return speciesEggTiers[this.species]; } //// @@ -556,8 +545,8 @@ export class Egg { } export function getLegendaryGachaSpeciesForTimestamp(scene: BattleScene, timestamp: number): Species { - const legendarySpecies = Object.entries(speciesStarterCosts) - .filter(s => s[1] >= 8 && s[1] <= 9) + const legendarySpecies = Object.entries(speciesEggTiers) + .filter(s => s[1] === EggTier.LEGENDARY) .map(s => parseInt(s[0])) .filter(s => getPokemonSpecies(s).isObtainable()); @@ -579,17 +568,9 @@ export function getLegendaryGachaSpeciesForTimestamp(scene: BattleScene, timesta /** * Check for a given species EggTier Value - * @param species - Species for wich we will check the egg tier it belongs to + * @param pokemonSpecies - Species for wich we will check the egg tier it belongs to * @returns The egg tier of a given pokemon species */ export function getEggTierForSpecies(pokemonSpecies :PokemonSpecies): EggTier { - const speciesBaseValue = speciesStarterCosts[pokemonSpecies.getRootSpeciesId()]; - if (speciesBaseValue <= 3) { - return EggTier.COMMON; - } else if (speciesBaseValue <= 5) { - return EggTier.GREAT; - } else if (speciesBaseValue <= 7) { - return EggTier.ULTRA; - } - return EggTier.MASTER; + return speciesEggTiers[pokemonSpecies.getRootSpeciesId()]; } diff --git a/src/data/mystery-encounters/encounters/a-trainers-test-encounter.ts b/src/data/mystery-encounters/encounters/a-trainers-test-encounter.ts index f3b886ac0ac..4f3420f5194 100644 --- a/src/data/mystery-encounters/encounters/a-trainers-test-encounter.ts +++ b/src/data/mystery-encounters/encounters/a-trainers-test-encounter.ts @@ -150,7 +150,7 @@ export const ATrainersTestEncounter: MysteryEncounter = pulled: false, sourceType: EggSourceType.EVENT, eggDescriptor: encounter.misc.trainerEggDescription, - tier: EggTier.ULTRA + tier: EggTier.EPIC }; encounter.setDialogueToken("eggType", i18next.t(`${namespace}:eggTypes.epic`)); setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SACRED_ASH ], guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ULTRA ], fillRemaining: true }, [ eggOptions ]); @@ -172,7 +172,7 @@ export const ATrainersTestEncounter: MysteryEncounter = pulled: false, sourceType: EggSourceType.EVENT, eggDescriptor: encounter.misc.trainerEggDescription, - tier: EggTier.GREAT + tier: EggTier.RARE }; encounter.setDialogueToken("eggType", i18next.t(`${namespace}:eggTypes.rare`)); setEncounterRewards(scene, { fillRemaining: false, rerollMultiplier: -1 }, [ eggOptions ]); 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 4515736b30a..0ac82243862 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 @@ -494,7 +494,7 @@ function getEggOptions(scene: BattleScene, commonEggs: number, rareEggs: number) pulled: false, sourceType: EggSourceType.EVENT, eggDescriptor: eggDescription, - tier: EggTier.GREAT + tier: EggTier.RARE }); } } diff --git a/src/enums/egg-type.ts b/src/enums/egg-type.ts index d8d0facb020..901e60b3c76 100644 --- a/src/enums/egg-type.ts +++ b/src/enums/egg-type.ts @@ -1,6 +1,6 @@ export enum EggTier { COMMON, - GREAT, - ULTRA, - MASTER + RARE, + EPIC, + LEGENDARY } diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 4d85d5b8e1e..d8fcc281d1b 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -983,7 +983,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.scene.applyModifier(PokemonIncrementingStatModifier, this.isPlayer(), this, s, statHolder); } - statHolder.value = Utils.clampInt(statHolder.value, 1, Number.MAX_SAFE_INTEGER); + statHolder.value = Phaser.Math.Clamp(statHolder.value, 1, Number.MAX_SAFE_INTEGER); this.setStat(s, statHolder.value); } diff --git a/src/test/eggs/egg.test.ts b/src/test/eggs/egg.test.ts index cf53cca5af8..6f57af63e6b 100644 --- a/src/test/eggs/egg.test.ts +++ b/src/test/eggs/egg.test.ts @@ -55,7 +55,7 @@ describe("Egg Generation Tests", () => { let gachaSpeciesCount = 0; for (let i = 0; i < EGG_HATCH_COUNT; i++) { - const result = new Egg({ scene, timestamp, sourceType: EggSourceType.GACHA_LEGENDARY, tier: EggTier.MASTER }).generatePlayerPokemon(scene).species.speciesId; + const result = new Egg({ scene, timestamp, sourceType: EggSourceType.GACHA_LEGENDARY, tier: EggTier.LEGENDARY }).generatePlayerPokemon(scene).species.speciesId; if (result === expectedSpecies) { gachaSpeciesCount++; } @@ -82,7 +82,7 @@ describe("Egg Generation Tests", () => { }); it("should return an rare tier egg", () => { const scene = game.scene; - const expectedTier = EggTier.GREAT; + const expectedTier = EggTier.RARE; const result = new Egg({ scene, tier: expectedTier }).tier; @@ -90,7 +90,7 @@ describe("Egg Generation Tests", () => { }); it("should return an epic tier egg", () => { const scene = game.scene; - const expectedTier = EggTier.ULTRA; + const expectedTier = EggTier.EPIC; const result = new Egg({ scene, tier: expectedTier }).tier; @@ -98,7 +98,7 @@ describe("Egg Generation Tests", () => { }); it("should return an legendary tier egg", () => { const scene = game.scene; - const expectedTier = EggTier.MASTER; + const expectedTier = EggTier.LEGENDARY; const result = new Egg({ scene, tier: expectedTier }).tier; @@ -200,7 +200,7 @@ describe("Egg Generation Tests", () => { const scene = game.scene; const expectedEggTier = EggTier.COMMON; - const result = new Egg({ scene, tier: EggTier.MASTER, species: Species.BULBASAUR }).tier; + const result = new Egg({ scene, tier: EggTier.LEGENDARY, species: Species.BULBASAUR }).tier; expect(result).toBe(expectedEggTier); }); @@ -208,7 +208,7 @@ describe("Egg Generation Tests", () => { const scene = game.scene; const expectedHatchWaves = 10; - const result = new Egg({ scene, tier: EggTier.MASTER, species: Species.BULBASAUR }).hatchWaves; + const result = new Egg({ scene, tier: EggTier.LEGENDARY, species: Species.BULBASAUR }).hatchWaves; expect(result).toBe(expectedHatchWaves); }); @@ -229,7 +229,7 @@ describe("Egg Generation Tests", () => { const result = new EggData(legacyEgg).toEgg(); - expect(result.tier).toBe(EggTier.GREAT); + expect(result.tier).toBe(EggTier.RARE); expect(result.id).toBe(legacyEgg.id); expect(result.timestamp).toBe(legacyEgg.timestamp); expect(result.hatchWaves).toBe(legacyEgg.hatchWaves); @@ -241,9 +241,9 @@ describe("Egg Generation Tests", () => { new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.COMMON }); - expect(scene.gameData.eggPity[EggTier.GREAT]).toBe(startPityValues[EggTier.GREAT] + 1); - expect(scene.gameData.eggPity[EggTier.ULTRA]).toBe(startPityValues[EggTier.ULTRA] + 1); - expect(scene.gameData.eggPity[EggTier.MASTER]).toBe(startPityValues[EggTier.MASTER] + 1); + expect(scene.gameData.eggPity[EggTier.RARE]).toBe(startPityValues[EggTier.RARE] + 1); + expect(scene.gameData.eggPity[EggTier.EPIC]).toBe(startPityValues[EggTier.EPIC] + 1); + expect(scene.gameData.eggPity[EggTier.LEGENDARY]).toBe(startPityValues[EggTier.LEGENDARY] + 1); }); it("should increase legendary egg pity by two", () => { const scene = game.scene; @@ -251,9 +251,9 @@ describe("Egg Generation Tests", () => { new Egg({ scene, sourceType: EggSourceType.GACHA_LEGENDARY, pulled: true, tier: EggTier.COMMON }); - expect(scene.gameData.eggPity[EggTier.GREAT]).toBe(startPityValues[EggTier.GREAT] + 1); - expect(scene.gameData.eggPity[EggTier.ULTRA]).toBe(startPityValues[EggTier.ULTRA] + 1); - expect(scene.gameData.eggPity[EggTier.MASTER]).toBe(startPityValues[EggTier.MASTER] + 2); + expect(scene.gameData.eggPity[EggTier.RARE]).toBe(startPityValues[EggTier.RARE] + 1); + expect(scene.gameData.eggPity[EggTier.EPIC]).toBe(startPityValues[EggTier.EPIC] + 1); + expect(scene.gameData.eggPity[EggTier.LEGENDARY]).toBe(startPityValues[EggTier.LEGENDARY] + 2); }); it("should not increase manaphy egg count if bulbasaurs are pulled", () => { const scene = game.scene; @@ -277,7 +277,7 @@ describe("Egg Generation Tests", () => { const scene = game.scene; const startingRareEggsPulled = scene.gameData.gameStats.rareEggsPulled; - new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.GREAT }); + new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.RARE }); expect(scene.gameData.gameStats.rareEggsPulled).toBe(startingRareEggsPulled + 1); }); @@ -285,7 +285,7 @@ describe("Egg Generation Tests", () => { const scene = game.scene; const startingEpicEggsPulled = scene.gameData.gameStats.epicEggsPulled; - new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.ULTRA }); + new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.EPIC }); expect(scene.gameData.gameStats.epicEggsPulled).toBe(startingEpicEggsPulled + 1); }); @@ -293,7 +293,7 @@ describe("Egg Generation Tests", () => { const scene = game.scene; const startingLegendaryEggsPulled = scene.gameData.gameStats.legendaryEggsPulled; - new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.MASTER }); + new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true, tier: EggTier.LEGENDARY }); expect(scene.gameData.gameStats.legendaryEggsPulled).toBe(startingLegendaryEggsPulled + 1); }); @@ -301,8 +301,8 @@ describe("Egg Generation Tests", () => { vi.spyOn(Utils, "randInt").mockReturnValue(1); const scene = game.scene; - const expectedTier1 = EggTier.MASTER; - const expectedTier2 = EggTier.ULTRA; + const expectedTier1 = EggTier.LEGENDARY; + const expectedTier2 = EggTier.EPIC; const result1 = new Egg({ scene, sourceType: EggSourceType.GACHA_LEGENDARY, pulled: true }).tier; const result2 = new Egg({ scene, sourceType: EggSourceType.GACHA_MOVE, pulled: true }).tier; diff --git a/src/test/mystery-encounter/encounters/a-trainers-test-encounter.test.ts b/src/test/mystery-encounter/encounters/a-trainers-test-encounter.test.ts index b1aa378d82a..7d783958422 100644 --- a/src/test/mystery-encounter/encounters/a-trainers-test-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/a-trainers-test-encounter.test.ts @@ -128,7 +128,7 @@ describe("A Trainer's Test - Mystery Encounter", () => { expect(eggsAfter).toBeDefined(); expect(eggsBeforeLength + 1).toBe(eggsAfter.length); const eggTier = eggsAfter[eggsAfter.length - 1].tier; - expect(eggTier === EggTier.ULTRA || eggTier === EggTier.MASTER).toBeTruthy(); + expect(eggTier === EggTier.EPIC || eggTier === EggTier.LEGENDARY).toBeTruthy(); }); }); @@ -176,7 +176,7 @@ describe("A Trainer's Test - Mystery Encounter", () => { expect(eggsAfter).toBeDefined(); expect(eggsBeforeLength + 1).toBe(eggsAfter.length); const eggTier = eggsAfter[eggsAfter.length - 1].tier; - expect(eggTier).toBe(EggTier.GREAT); + expect(eggTier).toBe(EggTier.RARE); }); it("should leave encounter without battle", async () => { diff --git a/src/test/mystery-encounter/encounters/the-expert-breeder-encounter.test.ts b/src/test/mystery-encounter/encounters/the-expert-breeder-encounter.test.ts index 7e445ac1fe2..bbb4f249feb 100644 --- a/src/test/mystery-encounter/encounters/the-expert-breeder-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/the-expert-breeder-encounter.test.ts @@ -155,7 +155,7 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => { expect(eggsAfter).toBeDefined(); expect(eggsBeforeLength + commonEggs + rareEggs).toBe(eggsAfter.length); expect(eggsAfter.filter(egg => egg.tier === EggTier.COMMON).length).toBe(commonEggs); - expect(eggsAfter.filter(egg => egg.tier === EggTier.GREAT).length).toBe(rareEggs); + expect(eggsAfter.filter(egg => egg.tier === EggTier.RARE).length).toBe(rareEggs); game.phaseInterceptor.superEndPhase(); await game.phaseInterceptor.to(PostMysteryEncounterPhase); @@ -213,7 +213,7 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => { expect(eggsAfter).toBeDefined(); expect(eggsBeforeLength + commonEggs + rareEggs).toBe(eggsAfter.length); expect(eggsAfter.filter(egg => egg.tier === EggTier.COMMON).length).toBe(commonEggs); - expect(eggsAfter.filter(egg => egg.tier === EggTier.GREAT).length).toBe(rareEggs); + expect(eggsAfter.filter(egg => egg.tier === EggTier.RARE).length).toBe(rareEggs); game.phaseInterceptor.superEndPhase(); await game.phaseInterceptor.to(PostMysteryEncounterPhase); @@ -271,7 +271,7 @@ describe("The Expert Pokémon Breeder - Mystery Encounter", () => { expect(eggsAfter).toBeDefined(); expect(eggsBeforeLength + commonEggs + rareEggs).toBe(eggsAfter.length); expect(eggsAfter.filter(egg => egg.tier === EggTier.COMMON).length).toBe(commonEggs); - expect(eggsAfter.filter(egg => egg.tier === EggTier.GREAT).length).toBe(rareEggs); + expect(eggsAfter.filter(egg => egg.tier === EggTier.RARE).length).toBe(rareEggs); game.phaseInterceptor.superEndPhase(); await game.phaseInterceptor.to(PostMysteryEncounterPhase); diff --git a/src/ui/battle-info.ts b/src/ui/battle-info.ts index 79b51ba6c44..1d97998f491 100644 --- a/src/ui/battle-info.ts +++ b/src/ui/battle-info.ts @@ -593,7 +593,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container { }; const updatePokemonHp = () => { - let duration = !instant ? Utils.clampInt(Math.abs((this.lastHp) - pokemon.hp) * 5, 250, 5000) : 0; + let duration = !instant ? Phaser.Math.Clamp(Math.abs((this.lastHp) - pokemon.hp) * 5, 250, 5000) : 0; const speed = (this.scene as BattleScene).hpBarSpeed; if (speed) { duration = speed >= 3 ? 0 : duration / Math.pow(2, speed); diff --git a/src/ui/egg-gacha-ui-handler.ts b/src/ui/egg-gacha-ui-handler.ts index 366f1604740..3aa009b1b31 100644 --- a/src/ui/egg-gacha-ui-handler.ts +++ b/src/ui/egg-gacha-ui-handler.ts @@ -471,9 +471,9 @@ export default class EggGachaUiHandler extends MessageUiHandler { getGuaranteedEggTierFromPullCount(pullCount: number): EggTier { switch (pullCount) { case 10: - return EggTier.GREAT; + return EggTier.RARE; case 25: - return EggTier.ULTRA; + return EggTier.EPIC; default: return EggTier.COMMON; } @@ -516,7 +516,7 @@ export default class EggGachaUiHandler extends MessageUiHandler { const eggText = addTextObject(this.scene, 0, 14, egg.getEggDescriptor(), TextStyle.PARTY, { align: "center" }); eggText.setOrigin(0.5, 0); - eggText.setTint(getEggTierTextTint(!egg.isManaphyEgg() ? egg.tier : EggTier.ULTRA)); + eggText.setTint(getEggTierTextTint(!egg.isManaphyEgg() ? egg.tier : EggTier.EPIC)); ret.add(eggText); this.eggGachaSummaryContainer.addAt(ret, 0); diff --git a/src/ui/text.ts b/src/ui/text.ts index e6e1978118b..22dd3f4cd6a 100644 --- a/src/ui/text.ts +++ b/src/ui/text.ts @@ -356,11 +356,11 @@ export function getEggTierTextTint(tier: EggTier): integer { switch (tier) { case EggTier.COMMON: return getModifierTierTextTint(ModifierTier.COMMON); - case EggTier.GREAT: + case EggTier.RARE: return getModifierTierTextTint(ModifierTier.GREAT); - case EggTier.ULTRA: + case EggTier.EPIC: return getModifierTierTextTint(ModifierTier.ULTRA); - case EggTier.MASTER: + case EggTier.LEGENDARY: return getModifierTierTextTint(ModifierTier.MASTER); } } diff --git a/src/utils.ts b/src/utils.ts index 9cc95b00826..c2ee7100909 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -38,10 +38,6 @@ export function shiftCharCodes(str: string, shiftCount: integer) { return newStr; } -export function clampInt(value: integer, min: integer, max: integer): integer { - return Math.min(Math.max(value, min), max); -} - export function randGauss(stdev: number, mean: number = 0): number { if (!stdev) { return 0; From 5d0b36132061bae767dafdd3f27c6c1be12264df Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Thu, 10 Oct 2024 10:19:05 -0700 Subject: [PATCH 10/37] [P2] Syrup Bomb effect is removed when user leaves the field (#4606) * Syrup Bomb's effect expires when the move user leaves the field * Add test * Remove check for the affected pokemon being switched out --- src/data/battler-tags.ts | 29 +++++++++++++---------------- src/test/moves/syrup_bomb.test.ts | 26 ++++++++++++++++++++------ 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 24c82e54427..3cc109df264 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -2640,16 +2640,16 @@ export class ImprisonTag extends MoveRestrictionBattlerTag { /** * Battler Tag that applies the effects of Syrup Bomb to the target Pokemon. * For three turns, starting from the turn of hit, at the end of each turn, the target Pokemon's speed will decrease by 1. - * The tag can also expire by taking the target Pokemon off the field. + * The tag can also expire by taking the target Pokemon off the field, or the Pokemon that originally used the move. */ export class SyrupBombTag extends BattlerTag { - constructor() { - super(BattlerTagType.SYRUP_BOMB, BattlerTagLapseType.TURN_END, 3, Moves.SYRUP_BOMB); + constructor(sourceId: number) { + super(BattlerTagType.SYRUP_BOMB, BattlerTagLapseType.TURN_END, 3, Moves.SYRUP_BOMB, sourceId); } /** * Adds the Syrup Bomb battler tag to the target Pokemon. - * @param {Pokemon} pokemon the target Pokemon + * @param pokemon - The target {@linkcode Pokemon} */ override onAdd(pokemon: Pokemon) { super.onAdd(pokemon); @@ -2658,15 +2658,16 @@ export class SyrupBombTag extends BattlerTag { /** * Applies the single-stage speed down to the target Pokemon and decrements the tag's turn count - * @param {Pokemon} pokemon the target Pokemon - * @param {BattlerTagLapseType} _lapseType - * @returns `true` if the turnCount is still greater than 0 | `false` if the turnCount is 0 or the target Pokemon has been removed from the field + * @param pokemon - The target {@linkcode Pokemon} + * @param _lapseType - N/A + * @returns `true` if the `turnCount` is still greater than `0`; `false` if the `turnCount` is `0` or the target or source Pokemon has been removed from the field */ override lapse(pokemon: Pokemon, _lapseType: BattlerTagLapseType): boolean { - if (!pokemon.isActive(true)) { + if (this.sourceId && !pokemon.scene.getPokemonById(this.sourceId)?.isActive(true)) { return false; } - pokemon.scene.queueMessage(i18next.t("battlerTags:syrupBombLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); // Custom message in lieu of an animation in mainline + // Custom message in lieu of an animation in mainline + pokemon.scene.queueMessage(i18next.t("battlerTags:syrupBombLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); pokemon.scene.unshiftPhase(new StatStageChangePhase( pokemon.scene, pokemon.getBattlerIndex(), true, [ Stat.SPD ], -1, true, false, true @@ -2677,12 +2678,8 @@ export class SyrupBombTag extends BattlerTag { /** * Retrieves a {@linkcode BattlerTag} based on the provided tag type, turn count, source move, and source ID. - * - * @param {BattlerTagType} tagType the type of the {@linkcode BattlerTagType}. - * @param turnCount the turn count. - * @param {Moves} sourceMove the source {@linkcode Moves}. - * @param sourceId the source ID. - * @returns {BattlerTag} the corresponding {@linkcode BattlerTag} object. + * @param sourceId - The ID of the pokemon adding the tag + * @returns The corresponding {@linkcode BattlerTag} object. */ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, sourceMove: Moves, sourceId: number): BattlerTag { switch (tagType) { @@ -2851,7 +2848,7 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source case BattlerTagType.IMPRISON: return new ImprisonTag(sourceId); case BattlerTagType.SYRUP_BOMB: - return new SyrupBombTag(); + return new SyrupBombTag(sourceId); case BattlerTagType.NONE: default: return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId); diff --git a/src/test/moves/syrup_bomb.test.ts b/src/test/moves/syrup_bomb.test.ts index 7f914e45cc6..ea2f8b6bab3 100644 --- a/src/test/moves/syrup_bomb.test.ts +++ b/src/test/moves/syrup_bomb.test.ts @@ -1,4 +1,3 @@ -import { allMoves } from "#app/data/move"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import { Abilities } from "#enums/abilities"; @@ -7,7 +6,7 @@ import { Stat } from "#enums/stat"; import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; import { BattlerIndex } from "#app/battle"; -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Moves - SYRUP BOMB", () => { let phaserGame: Phaser.Game; @@ -26,20 +25,21 @@ describe("Moves - SYRUP BOMB", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .starterSpecies(Species.MAGIKARP) + .battleType("single") .enemySpecies(Species.SNORLAX) + .enemyAbility(Abilities.BALL_FETCH) + .ability(Abilities.BALL_FETCH) .startingLevel(30) .enemyLevel(100) .moveset([ Moves.SYRUP_BOMB, Moves.SPLASH ]) .enemyMoveset(Moves.SPLASH); - vi.spyOn(allMoves[Moves.SYRUP_BOMB], "accuracy", "get").mockReturnValue(100); }); //Bulbapedia Reference: https://bulbapedia.bulbagarden.net/wiki/syrup_bomb_(move) it("decreases the target Pokemon's speed stat once per turn for 3 turns", async () => { - await game.startBattle([ Species.MAGIKARP ]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const targetPokemon = game.scene.getEnemyPokemon()!; expect(targetPokemon.getStatStage(Stat.SPD)).toBe(0); @@ -66,7 +66,7 @@ describe("Moves - SYRUP BOMB", () => { it("does not affect Pokemon with the ability Bulletproof", async () => { game.override.enemyAbility(Abilities.BULLETPROOF); - await game.startBattle([ Species.MAGIKARP ]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); const targetPokemon = game.scene.getEnemyPokemon()!; @@ -79,4 +79,18 @@ describe("Moves - SYRUP BOMB", () => { expect(targetPokemon.getStatStage(Stat.SPD)).toBe(0); } ); + + it("stops lowering the target's speed if the user leaves the field", async () => { + await game.classicMode.startBattle([ Species.FEEBAS, Species.MILOTIC ]); + + game.move.select(Moves.SYRUP_BOMB); + await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]); + await game.move.forceHit(); + await game.toNextTurn(); + + game.doSwitchPokemon(1); + await game.toNextTurn(); + + expect(game.scene.getEnemyPokemon()!.getStatStage(Stat.SPD)).toBe(-1); + }); }); From 3f63c147a38ef9afb05c54bfe0983ed572d6f35b Mon Sep 17 00:00:00 2001 From: "Amani H." <109637146+xsn34kzx@users.noreply.github.com> Date: Thu, 10 Oct 2024 15:44:51 -0400 Subject: [PATCH 11/37] [P3] Fix "Stat Won't Go Any Lower/Higher" Not Appearing (#4635) --- src/enums/stat.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/enums/stat.ts b/src/enums/stat.ts index a12d53e8559..6b3f7dc6d79 100644 --- a/src/enums/stat.ts +++ b/src/enums/stat.ts @@ -50,7 +50,7 @@ export function getStatStageChangeDescriptionKey(stages: number, isIncrease: boo return isIncrease ? "battle:statRose" : "battle:statFell"; } else if (stages === 2) { return isIncrease ? "battle:statSharplyRose" : "battle:statHarshlyFell"; - } else if (stages <= 6) { + } else if (stages > 2 && stages <= 6) { return isIncrease ? "battle:statRoseDrastically" : "battle:statSeverelyFell"; } return isIncrease ? "battle:statWontGoAnyHigher" : "battle:statWontGoAnyLower"; From 407cd65dcbe7ba343b2f01e17ed67750c888e218 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Fri, 11 Oct 2024 00:20:28 -0700 Subject: [PATCH 12/37] [Misc] Enemy item override will now apply to all enemies (#4620) * Enemy item override will now apply to all enemies * Update tsdocs --- src/battle-scene.ts | 9 +++++---- src/modifier/modifier.ts | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index a586b565e13..40e3971b7fc 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -2676,7 +2676,7 @@ export default class BattleScene extends SceneBase { } /** - * Removes all modifiers from enemy of PersistentModifier type + * Removes all modifiers from enemy pokemon of {@linkcode PersistentModifier} type */ clearEnemyModifiers(): void { const modifiersToRemove = this.enemyModifiers.filter(m => m instanceof PersistentModifier); @@ -2687,10 +2687,11 @@ export default class BattleScene extends SceneBase { } /** - * Removes all modifiers from enemy of PokemonHeldItemModifier type + * Removes all modifiers from enemy pokemon of {@linkcode PokemonHeldItemModifier} type + * @param pokemon - If specified, only removes held items from that {@linkcode Pokemon} */ - clearEnemyHeldItemModifiers(): void { - const modifiersToRemove = this.enemyModifiers.filter(m => m instanceof PokemonHeldItemModifier); + clearEnemyHeldItemModifiers(pokemon?: Pokemon): void { + const modifiersToRemove = this.enemyModifiers.filter(m => m instanceof PokemonHeldItemModifier && (!pokemon || m.getPokemon(this) === pokemon)); for (const m of modifiersToRemove) { this.enemyModifiers.splice(this.enemyModifiers.indexOf(m), 1); } diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 6c9b5db1bca..dd8c82357a7 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -3635,7 +3635,7 @@ export function overrideHeldItems(scene: BattleScene, pokemon: Pokemon, isPlayer } if (!isPlayer) { - scene.clearEnemyHeldItemModifiers(); + scene.clearEnemyHeldItemModifiers(pokemon); } heldItemsOverride.forEach(item => { From 80a784ac8d83c90af4ef16490346f24380da5f86 Mon Sep 17 00:00:00 2001 From: MokaStitcher <54149968+MokaStitcher@users.noreply.github.com> Date: Fri, 11 Oct 2024 16:24:53 +0200 Subject: [PATCH 13/37] [P3 Beta][UI] Fix loading behavior introduced with save preview (#4633) * [ui] partially revert loading behavior introduced with save preview * [beta][ui] fix scrolling issue in Load Game menu --- src/ui/save-slot-select-ui-handler.ts | 65 ++++++++++++++++----------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/src/ui/save-slot-select-ui-handler.ts b/src/ui/save-slot-select-ui-handler.ts index bd1a7dd9ac4..2e664db8d43 100644 --- a/src/ui/save-slot-select-ui-handler.ts +++ b/src/ui/save-slot-select-ui-handler.ts @@ -12,7 +12,8 @@ import { Mode } from "./ui"; import { addWindow } from "./ui-theme"; import { RunDisplayMode } from "#app/ui/run-info-ui-handler"; -const sessionSlotCount = 5; +const SESSION_SLOTS_COUNT = 5; +const SLOTS_ON_SCREEN = 3; export enum SaveSlotUiMode { LOAD, @@ -84,12 +85,10 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler { this.saveSlotSelectCallback = args[1] as SaveSlotSelectCallback; this.saveSlotSelectContainer.setVisible(true); - this.populateSessionSlots() - .then(() => { - this.setScrollCursor(0); - this.setCursor(0); - }); + this.populateSessionSlots(); + this.setScrollCursor(0); + this.setCursor(0); return true; } @@ -161,9 +160,9 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler { } break; case Button.DOWN: - if (this.cursor < 2) { - success = this.setCursor(this.cursor + 1, this.cursor); - } else if (this.scrollCursor < sessionSlotCount - 3) { + if (this.cursor < (SLOTS_ON_SCREEN - 1)) { + success = this.setCursor(this.cursor + 1, cursorPosition); + } else if (this.scrollCursor < SESSION_SLOTS_COUNT - SLOTS_ON_SCREEN) { success = this.setScrollCursor(this.scrollCursor + 1, cursorPosition); } break; @@ -184,13 +183,19 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler { return success || error; } - async populateSessionSlots() { - for (let s = 0; s < sessionSlotCount; s++) { + populateSessionSlots() { + for (let s = 0; s < SESSION_SLOTS_COUNT; s++) { const sessionSlot = new SessionSlot(this.scene, s); - await sessionSlot.load(); this.scene.add.existing(sessionSlot); this.sessionSlotsContainer.add(sessionSlot); this.sessionSlots.push(sessionSlot); + sessionSlot.load().then((success) => { + // If the cursor was moved to this slot while the session was loading + // call setCursor again to shift the slot position and show the arrow for save preview + if (success && (this.cursor + this.scrollCursor) === s) { + this.setCursor(s); + } + }); } } @@ -209,12 +214,12 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler { } /** - * setCursor takes user navigation as an input and positions the cursor accordingly - * @param cursor the index provided to the cursor - * @param prevCursor the previous index occupied by the cursor - optional + * Move the cursor to a new position and update the view accordingly + * @param cursor the new cursor position, between `0` and `SLOTS_ON_SCREEN - 1` + * @param prevSlotIndex index of the previous session occupied by the cursor, between `0` and `SESSION_SLOTS_COUNT - 1` - optional * @returns `true` if the cursor position has changed | `false` if it has not */ - override setCursor(cursor: integer, prevCursor?: integer): boolean { + override setCursor(cursor: integer, prevSlotIndex?: integer): boolean { const changed = super.setCursor(cursor); if (!this.cursorObj) { @@ -241,21 +246,20 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler { } this.setArrowVisibility(hasData); } - if (!Utils.isNullOrUndefined(prevCursor)) { - this.revertSessionSlot(prevCursor); + if (!Utils.isNullOrUndefined(prevSlotIndex)) { + this.revertSessionSlot(prevSlotIndex); } return changed; } /** - * Helper function that resets the session slot position to its default central position - * @param prevCursor the previous location of the cursor + * Helper function that resets the given session slot to its default central position */ - revertSessionSlot(prevCursor: integer): void { - const sessionSlot = this.sessionSlots[prevCursor]; + revertSessionSlot(slotIndex: integer): void { + const sessionSlot = this.sessionSlots[slotIndex]; if (sessionSlot) { - sessionSlot.setPosition(0, prevCursor * 56); + sessionSlot.setPosition(0, slotIndex * 56); } } @@ -270,12 +274,18 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler { } } - setScrollCursor(scrollCursor: integer, priorCursor?: integer): boolean { + /** + * Move the scrolling cursor to a new position and update the view accordingly + * @param scrollCursor the new cursor position, between `0` and `SESSION_SLOTS_COUNT - SLOTS_ON_SCREEN` + * @param prevSlotIndex index of the previous slot occupied by the cursor, between `0` and `SESSION_SLOTS_COUNT-1` - optional + * @returns `true` if the cursor position has changed | `false` if it has not + */ + setScrollCursor(scrollCursor: integer, prevSlotIndex?: integer): boolean { const changed = scrollCursor !== this.scrollCursor; if (changed) { this.scrollCursor = scrollCursor; - this.setCursor(this.cursor, priorCursor); + this.setCursor(this.cursor, prevSlotIndex); this.scene.tweens.add({ targets: this.sessionSlotsContainer, y: this.sessionSlotsContainerInitialY - 56 * scrollCursor, @@ -290,6 +300,7 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler { clear() { super.clear(); this.saveSlotSelectContainer.setVisible(false); + this.setScrollCursor(0); this.eraseCursor(); this.saveSlotSelectCallback = null; this.clearSessionSlots(); @@ -391,6 +402,10 @@ class SessionSlot extends Phaser.GameObjects.Container { load(): Promise { return new Promise(resolve => { this.scene.gameData.getSession(this.slotId).then(async sessionData => { + // Ignore the results if the view was exited + if (!this.active) { + return; + } if (!sessionData) { this.hasData = false; this.loadingLabel.setText(i18next.t("saveSlotSelectUiHandler:empty")); From 4f456339f45038cd8df5b9c788251aa6c66bdde1 Mon Sep 17 00:00:00 2001 From: MokaStitcher <54149968+MokaStitcher@users.noreply.github.com> Date: Fri, 11 Oct 2024 16:26:47 +0200 Subject: [PATCH 14/37] [UI] Remove score display in voucher menu (#4616) --- src/ui/achvs-ui-handler.ts | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/ui/achvs-ui-handler.ts b/src/ui/achvs-ui-handler.ts index f90732d1fae..4e0e2feea81 100644 --- a/src/ui/achvs-ui-handler.ts +++ b/src/ui/achvs-ui-handler.ts @@ -40,7 +40,9 @@ export default class AchvsUiHandler extends MessageUiHandler { private iconsBg: Phaser.GameObjects.NineSlice; private icons: Phaser.GameObjects.Sprite[]; + private titleBg: Phaser.GameObjects.NineSlice; private titleText: Phaser.GameObjects.Text; + private scoreContainer: Phaser.GameObjects.Container; private scoreText: Phaser.GameObjects.Text; private unlockText: Phaser.GameObjects.Text; @@ -114,29 +116,31 @@ export default class AchvsUiHandler extends MessageUiHandler { const titleBg = addWindow(this.scene, 0, this.headerBg.height + this.iconsBg.height, 174, 24); titleBg.setOrigin(0, 0); + this.titleBg = titleBg; this.titleText = addTextObject(this.scene, 0, 0, "", TextStyle.WINDOW); const textSize = languageSettings[i18next.language]?.TextSize ?? this.titleText.style.fontSize; this.titleText.setFontSize(textSize); - this.titleText.setOrigin(0, 0); const titleBgCenterX = titleBg.x + titleBg.width / 2; const titleBgCenterY = titleBg.y + titleBg.height / 2; this.titleText.setOrigin(0.5, 0.5); this.titleText.setPosition(titleBgCenterX, titleBgCenterY); - const scoreBg = addWindow(this.scene, titleBg.x + titleBg.width, titleBg.y, 46, 24); + this.scoreContainer = this.scene.add.container(titleBg.x + titleBg.width, titleBg.y); + const scoreBg = addWindow(this.scene, 0, 0, 46, 24); scoreBg.setOrigin(0, 0); + this.scoreContainer.add(scoreBg); - this.scoreText = addTextObject(this.scene, 0, 0, "", TextStyle.WINDOW); - this.scoreText.setOrigin(0, 0); - this.scoreText.setPositionRelative(scoreBg, 8, 4); + this.scoreText = addTextObject(this.scene, scoreBg.width / 2, scoreBg.height / 2, "", TextStyle.WINDOW); + this.scoreText.setOrigin(0.5, 0.5); + this.scoreContainer.add(this.scoreText); - const unlockBg = addWindow(this.scene, scoreBg.x + scoreBg.width, scoreBg.y, 98, 24); + const unlockBg = addWindow(this.scene, this.scoreContainer.x + scoreBg.width, titleBg.y, 98, 24); unlockBg.setOrigin(0, 0); this.unlockText = addTextObject(this.scene, 0, 0, "", TextStyle.WINDOW); - this.unlockText.setOrigin(0, 0); - this.unlockText.setPositionRelative(unlockBg, 8, 4); + this.unlockText.setOrigin(0.5, 0.5); + this.unlockText.setPositionRelative(unlockBg, unlockBg.width / 2, unlockBg.height / 2); const descriptionBg = addWindow(this.scene, 0, titleBg.y + titleBg.height, (this.scene.game.canvas.width / 6) - 2, 42); descriptionBg.setOrigin(0, 0); @@ -157,8 +161,7 @@ export default class AchvsUiHandler extends MessageUiHandler { this.mainContainer.add(this.iconsContainer); this.mainContainer.add(titleBg); this.mainContainer.add(this.titleText); - this.mainContainer.add(scoreBg); - this.mainContainer.add(this.scoreText); + this.mainContainer.add(this.scoreContainer); this.mainContainer.add(unlockBg); this.mainContainer.add(this.unlockText); this.mainContainer.add(descriptionBg); @@ -167,8 +170,6 @@ export default class AchvsUiHandler extends MessageUiHandler { ui.add(this.mainContainer); this.currentPage = Page.ACHIEVEMENTS; - this.setCursor(0); - this.setScrollCursor(0); this.mainContainer.setVisible(false); } @@ -316,9 +317,19 @@ export default class AchvsUiHandler extends MessageUiHandler { if (update || pageChange) { switch (this.currentPage) { case Page.ACHIEVEMENTS: + if (pageChange) { + this.titleBg.width = 174; + this.titleText.x = this.titleBg.width / 2; + this.scoreContainer.setVisible(true); + } this.showAchv(achvs[Object.keys(achvs)[cursor + this.scrollCursor * this.COLS]]); break; case Page.VOUCHERS: + if (pageChange) { + this.titleBg.width = 220; + this.titleText.x = this.titleBg.width / 2; + this.scoreContainer.setVisible(false); + } this.showVoucher(vouchers[Object.keys(vouchers)[cursor + this.scrollCursor * this.COLS]]); break; } @@ -442,6 +453,7 @@ export default class AchvsUiHandler extends MessageUiHandler { this.currentPage = Page.ACHIEVEMENTS; this.mainContainer.setVisible(false); this.setScrollCursor(0); + this.setCursor(0, true); this.eraseCursor(); } From 70b9a43c8b72a555ae4e5379f07d0c4a480ca4e2 Mon Sep 17 00:00:00 2001 From: Mason S <132116525+ElizaAlex@users.noreply.github.com> Date: Fri, 11 Oct 2024 10:41:54 -0400 Subject: [PATCH 15/37] [P2] Fix first-turn status damage and arena hazards (#3528) * [Bug] Toxic Spikes implementation issues fixed Adjusted MoveEffectPhase.start() so that ENEMY_SIDE targeted moves no longer occur twice per use in double battles. Updated Toxic Orb test to no longer expect a tick of damage turn 1. Fixed Toxic/Poison dealing damage immediately when applied. Fixed Hazards not persisting through save Added unit tests Fixed flyout not displaying correct number of Spikes/Toxic Spikes after a refresh * Update Toxic Orb test * Updates Toxic Spikes tests * Apply suggestions from code review * Fix merge issues Replace `integer` with `number` in `arena-tag.ts` * Remove partial Magic Bounce implementation * Remove stray newline * Remove extra change in safeguard test --------- Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/data/arena-tag.ts | 122 ++++++++++++-------- src/phases/check-status-effect-phase.ts | 23 ++++ src/phases/obtain-status-effect-phase.ts | 4 - src/phases/turn-start-phase.ts | 9 +- src/system/arena-data.ts | 8 +- src/system/game-data.ts | 17 ++- src/test/items/toxic_orb.test.ts | 54 ++++----- src/test/moves/toxic_spikes.test.ts | 136 +++++++++++++++++++++++ 8 files changed, 282 insertions(+), 91 deletions(-) create mode 100644 src/phases/check-status-effect-phase.ts create mode 100644 src/test/moves/toxic_spikes.test.ts diff --git a/src/data/arena-tag.ts b/src/data/arena-tag.ts index 6407e139a71..45d64249296 100644 --- a/src/data/arena-tag.ts +++ b/src/data/arena-tag.ts @@ -28,20 +28,13 @@ export enum ArenaTagSide { } export abstract class ArenaTag { - public tagType: ArenaTagType; - public turnCount: integer; - public sourceMove?: Moves; - public sourceId?: integer; - public side: ArenaTagSide; - - - constructor(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves | undefined, sourceId?: integer, side: ArenaTagSide = ArenaTagSide.BOTH) { - this.tagType = tagType; - this.turnCount = turnCount; - this.sourceMove = sourceMove; - this.sourceId = sourceId; - this.side = side; - } + constructor( + public tagType: ArenaTagType, + public turnCount: number, + public sourceMove?: Moves, + public sourceId?: number, + public side: ArenaTagSide = ArenaTagSide.BOTH + ) {} apply(arena: Arena, args: any[]): boolean { return true; @@ -66,6 +59,18 @@ export abstract class ArenaTag { ? allMoves[this.sourceMove].name : null; } + + /** + * When given a arena tag or json representing one, load the data for it. + * This is meant to be inherited from by any arena tag with custom attributes + * @param {ArenaTag | any} source An arena tag + */ + loadTag(source : ArenaTag | any) : void { + this.turnCount = source.turnCount; + this.sourceMove = source.sourceMove; + this.sourceId = source.sourceId; + this.side = source.side; + } } /** @@ -73,7 +78,7 @@ export abstract class ArenaTag { * Prevents Pokémon on the opposing side from lowering the stats of the Pokémon in the Mist. */ export class MistTag extends ArenaTag { - constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) { + constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { super(ArenaTagType.MIST, turnCount, Moves.MIST, sourceId, side); } @@ -117,7 +122,7 @@ export class WeakenMoveScreenTag extends ArenaTag { * @param side - The side (player or enemy) the tag affects. * @param weakenedCategories - The categories of moves that are weakened by this tag. */ - constructor(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves, sourceId: integer, side: ArenaTagSide, weakenedCategories: MoveCategory[]) { + constructor(tagType: ArenaTagType, turnCount: number, sourceMove: Moves, sourceId: number, side: ArenaTagSide, weakenedCategories: MoveCategory[]) { super(tagType, turnCount, sourceMove, sourceId, side); this.weakenedCategories = weakenedCategories; @@ -148,7 +153,7 @@ export class WeakenMoveScreenTag extends ArenaTag { * Used by {@linkcode Moves.REFLECT} */ class ReflectTag extends WeakenMoveScreenTag { - constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) { + constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { super(ArenaTagType.REFLECT, turnCount, Moves.REFLECT, sourceId, side, [ MoveCategory.PHYSICAL ]); } @@ -164,7 +169,7 @@ class ReflectTag extends WeakenMoveScreenTag { * Used by {@linkcode Moves.LIGHT_SCREEN} */ class LightScreenTag extends WeakenMoveScreenTag { - constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) { + constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { super(ArenaTagType.LIGHT_SCREEN, turnCount, Moves.LIGHT_SCREEN, sourceId, side, [ MoveCategory.SPECIAL ]); } @@ -180,7 +185,7 @@ class LightScreenTag extends WeakenMoveScreenTag { * Used by {@linkcode Moves.AURORA_VEIL} */ class AuroraVeilTag extends WeakenMoveScreenTag { - constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) { + constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { super(ArenaTagType.AURORA_VEIL, turnCount, Moves.AURORA_VEIL, sourceId, side, [ MoveCategory.SPECIAL, MoveCategory.PHYSICAL ]); } @@ -203,7 +208,7 @@ export class ConditionalProtectTag extends ArenaTag { /** Does this apply to all moves, including those that ignore other forms of protection? */ protected ignoresBypass: boolean; - constructor(tagType: ArenaTagType, sourceMove: Moves, sourceId: integer, side: ArenaTagSide, condition: ProtectConditionFunc, ignoresBypass: boolean = false) { + constructor(tagType: ArenaTagType, sourceMove: Moves, sourceId: number, side: ArenaTagSide, condition: ProtectConditionFunc, ignoresBypass: boolean = false) { super(tagType, 1, sourceMove, sourceId, side); this.protectConditionFunc = condition; @@ -265,7 +270,7 @@ export class ConditionalProtectTag extends ArenaTag { */ const QuickGuardConditionFunc: ProtectConditionFunc = (arena, moveId) => { const move = allMoves[moveId]; - const priority = new Utils.IntegerHolder(move.priority); + const priority = new Utils.NumberHolder(move.priority); const effectPhase = arena.scene.getCurrentPhase(); if (effectPhase instanceof MoveEffectPhase) { @@ -281,7 +286,7 @@ const QuickGuardConditionFunc: ProtectConditionFunc = (arena, moveId) => { * Condition: The incoming move has increased priority. */ class QuickGuardTag extends ConditionalProtectTag { - constructor(sourceId: integer, side: ArenaTagSide) { + constructor(sourceId: number, side: ArenaTagSide) { super(ArenaTagType.QUICK_GUARD, Moves.QUICK_GUARD, sourceId, side, QuickGuardConditionFunc); } } @@ -312,7 +317,7 @@ const WideGuardConditionFunc: ProtectConditionFunc = (arena, moveId) : boolean = * can be an ally or enemy. */ class WideGuardTag extends ConditionalProtectTag { - constructor(sourceId: integer, side: ArenaTagSide) { + constructor(sourceId: number, side: ArenaTagSide) { super(ArenaTagType.WIDE_GUARD, Moves.WIDE_GUARD, sourceId, side, WideGuardConditionFunc); } } @@ -334,7 +339,7 @@ const MatBlockConditionFunc: ProtectConditionFunc = (arena, moveId) : boolean => * Condition: The incoming move is a Physical or Special attack move. */ class MatBlockTag extends ConditionalProtectTag { - constructor(sourceId: integer, side: ArenaTagSide) { + constructor(sourceId: number, side: ArenaTagSide) { super(ArenaTagType.MAT_BLOCK, Moves.MAT_BLOCK, sourceId, side, MatBlockConditionFunc); } @@ -372,7 +377,7 @@ const CraftyShieldConditionFunc: ProtectConditionFunc = (arena, moveId) => { * not target all Pokemon or sides of the field. */ class CraftyShieldTag extends ConditionalProtectTag { - constructor(sourceId: integer, side: ArenaTagSide) { + constructor(sourceId: number, side: ArenaTagSide) { super(ArenaTagType.CRAFTY_SHIELD, Moves.CRAFTY_SHIELD, sourceId, side, CraftyShieldConditionFunc, true); } } @@ -384,12 +389,12 @@ class CraftyShieldTag extends ConditionalProtectTag { export class NoCritTag extends ArenaTag { /** * Constructor method for the NoCritTag class - * @param turnCount `integer` the number of turns this effect lasts + * @param turnCount `number` the number of turns this effect lasts * @param sourceMove {@linkcode Moves} the move that created this effect - * @param sourceId `integer` the ID of the {@linkcode Pokemon} that created this effect + * @param sourceId `number` the ID of the {@linkcode Pokemon} that created this effect * @param side {@linkcode ArenaTagSide} the side to which this effect belongs */ - constructor(turnCount: integer, sourceMove: Moves, sourceId: integer, side: ArenaTagSide) { + constructor(turnCount: number, sourceMove: Moves, sourceId: number, side: ArenaTagSide) { super(ArenaTagType.NO_CRIT, turnCount, sourceMove, sourceId, side); } @@ -419,7 +424,7 @@ class WishTag extends ArenaTag { private triggerMessage: string; private healHp: number; - constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) { + constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { super(ArenaTagType.WISH, turnCount, Moves.WISH, sourceId, side); } @@ -460,7 +465,7 @@ export class WeakenMoveTypeTag extends ArenaTag { * @param sourceMove - The move that created the tag. * @param sourceId - The ID of the source of the tag. */ - constructor(tagType: ArenaTagType, turnCount: integer, type: Type, sourceMove: Moves, sourceId: integer) { + constructor(tagType: ArenaTagType, turnCount: number, type: Type, sourceMove: Moves, sourceId: number) { super(tagType, turnCount, sourceMove, sourceId); this.weakenedType = type; @@ -481,7 +486,7 @@ export class WeakenMoveTypeTag extends ArenaTag { * Weakens Electric type moves for a set amount of turns, usually 5. */ class MudSportTag extends WeakenMoveTypeTag { - constructor(turnCount: integer, sourceId: integer) { + constructor(turnCount: number, sourceId: number) { super(ArenaTagType.MUD_SPORT, turnCount, Type.ELECTRIC, Moves.MUD_SPORT, sourceId); } @@ -499,7 +504,7 @@ class MudSportTag extends WeakenMoveTypeTag { * Weakens Fire type moves for a set amount of turns, usually 5. */ class WaterSportTag extends WeakenMoveTypeTag { - constructor(turnCount: integer, sourceId: integer) { + constructor(turnCount: number, sourceId: number) { super(ArenaTagType.WATER_SPORT, turnCount, Type.FIRE, Moves.WATER_SPORT, sourceId); } @@ -550,8 +555,8 @@ export class IonDelugeTag extends ArenaTag { * Abstract class to implement arena traps. */ export class ArenaTrapTag extends ArenaTag { - public layers: integer; - public maxLayers: integer; + public layers: number; + public maxLayers: number; /** * Creates a new instance of the ArenaTrapTag class. @@ -562,7 +567,7 @@ export class ArenaTrapTag extends ArenaTag { * @param side - The side (player or enemy) the tag affects. * @param maxLayers - The maximum amount of layers this tag can have. */ - constructor(tagType: ArenaTagType, sourceMove: Moves, sourceId: integer, side: ArenaTagSide, maxLayers: integer) { + constructor(tagType: ArenaTagType, sourceMove: Moves, sourceId: number, side: ArenaTagSide, maxLayers: number) { super(tagType, 0, sourceMove, sourceId, side); this.layers = 1; @@ -593,6 +598,12 @@ export class ArenaTrapTag extends ArenaTag { getMatchupScoreMultiplier(pokemon: Pokemon): number { return pokemon.isGrounded() ? 1 : Phaser.Math.Linear(0, 1 / Math.pow(2, this.layers), Math.min(pokemon.getHpRatio(), 0.5) * 2); } + + loadTag(source: any): void { + super.loadTag(source); + this.layers = source.layers; + this.maxLayers = source.maxLayers; + } } /** @@ -601,7 +612,7 @@ export class ArenaTrapTag extends ArenaTag { * in damage for 1, 2, or 3 layers of Spikes respectively if they are summoned into this trap. */ class SpikesTag extends ArenaTrapTag { - constructor(sourceId: integer, side: ArenaTagSide) { + constructor(sourceId: number, side: ArenaTagSide) { super(ArenaTagType.SPIKES, Moves.SPIKES, sourceId, side, 3); } @@ -645,7 +656,7 @@ class SpikesTag extends ArenaTrapTag { class ToxicSpikesTag extends ArenaTrapTag { private neutralized: boolean; - constructor(sourceId: integer, side: ArenaTagSide) { + constructor(sourceId: number, side: ArenaTagSide) { super(ArenaTagType.TOXIC_SPIKES, Moves.TOXIC_SPIKES, sourceId, side, 2); this.neutralized = false; } @@ -703,7 +714,7 @@ class ToxicSpikesTag extends ArenaTrapTag { class DelayedAttackTag extends ArenaTag { public targetIndex: BattlerIndex; - constructor(tagType: ArenaTagType, sourceMove: Moves | undefined, sourceId: integer, targetIndex: BattlerIndex) { + constructor(tagType: ArenaTagType, sourceMove: Moves | undefined, sourceId: number, targetIndex: BattlerIndex) { super(tagType, 3, sourceMove, sourceId); this.targetIndex = targetIndex; @@ -728,7 +739,7 @@ class DelayedAttackTag extends ArenaTag { * who is summoned into the trap, based on the Rock type's type effectiveness. */ class StealthRockTag extends ArenaTrapTag { - constructor(sourceId: integer, side: ArenaTagSide) { + constructor(sourceId: number, side: ArenaTagSide) { super(ArenaTagType.STEALTH_ROCK, Moves.STEALTH_ROCK, sourceId, side, 1); } @@ -804,7 +815,7 @@ class StealthRockTag extends ArenaTrapTag { * to any Pokémon who is summoned into this trap. */ class StickyWebTag extends ArenaTrapTag { - constructor(sourceId: integer, side: ArenaTagSide) { + constructor(sourceId: number, side: ArenaTagSide) { super(ArenaTagType.STICKY_WEB, Moves.STICKY_WEB, sourceId, side, 1); } @@ -838,7 +849,7 @@ class StickyWebTag extends ArenaTrapTag { * also reversing the turn order for all Pokémon on the field as well. */ export class TrickRoomTag extends ArenaTag { - constructor(turnCount: integer, sourceId: integer) { + constructor(turnCount: number, sourceId: number) { super(ArenaTagType.TRICK_ROOM, turnCount, Moves.TRICK_ROOM, sourceId); } @@ -866,7 +877,7 @@ export class TrickRoomTag extends ArenaTag { * {@linkcode Abilities.LEVITATE} for the duration of the arena tag, usually 5 turns. */ export class GravityTag extends ArenaTag { - constructor(turnCount: integer) { + constructor(turnCount: number) { super(ArenaTagType.GRAVITY, turnCount, Moves.GRAVITY); } @@ -890,7 +901,7 @@ export class GravityTag extends ArenaTag { * Applies this arena tag for 4 turns (including the turn the move was used). */ class TailwindTag extends ArenaTag { - constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) { + constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { super(ArenaTagType.TAILWIND, turnCount, Moves.TAILWIND, sourceId, side); } @@ -928,7 +939,7 @@ class TailwindTag extends ArenaTag { * Doubles the prize money from trainers and money moves like {@linkcode Moves.PAY_DAY} and {@linkcode Moves.MAKE_IT_RAIN}. */ class HappyHourTag extends ArenaTag { - constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) { + constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { super(ArenaTagType.HAPPY_HOUR, turnCount, Moves.HAPPY_HOUR, sourceId, side); } @@ -942,7 +953,7 @@ class HappyHourTag extends ArenaTag { } class SafeguardTag extends ArenaTag { - constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) { + constructor(turnCount: number, sourceId: number, side: ArenaTagSide) { super(ArenaTagType.SAFEGUARD, turnCount, Moves.SAFEGUARD, sourceId, side); } @@ -955,6 +966,11 @@ class SafeguardTag extends ArenaTag { } } +class NoneTag extends ArenaTag { + constructor() { + super(ArenaTagType.NONE, 0); + } +} /** * This arena tag facilitates the application of the move Imprison * Imprison remains in effect as long as the source Pokemon is active and present on the field. @@ -1102,7 +1118,8 @@ class GrassWaterPledgeTag extends ArenaTag { } } -export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves | undefined, sourceId: integer, targetIndex?: BattlerIndex, side: ArenaTagSide = ArenaTagSide.BOTH): ArenaTag | null { +// TODO: swap `sourceMove` and `sourceId` and make `sourceMove` an optional parameter +export function getArenaTag(tagType: ArenaTagType, turnCount: number, sourceMove: Moves | undefined, sourceId: number, targetIndex?: BattlerIndex, side: ArenaTagSide = ArenaTagSide.BOTH): ArenaTag | null { switch (tagType) { case ArenaTagType.MIST: return new MistTag(turnCount, sourceId, side); @@ -1163,3 +1180,16 @@ export function getArenaTag(tagType: ArenaTagType, turnCount: integer, sourceMov return null; } } + +/** + * When given a battler tag or json representing one, creates an actual ArenaTag object with the same data. + * @param {ArenaTag | any} source An arena tag + * @return {ArenaTag} The valid arena tag + */ +export function loadArenaTag(source: ArenaTag | any): ArenaTag { + const tag = getArenaTag(source.tagType, source.turnCount, source.sourceMove, source.sourceId, source.targetIndex, source.side) + ?? new NoneTag(); + tag.loadTag(source); + return tag; +} + diff --git a/src/phases/check-status-effect-phase.ts b/src/phases/check-status-effect-phase.ts new file mode 100644 index 00000000000..44918b54966 --- /dev/null +++ b/src/phases/check-status-effect-phase.ts @@ -0,0 +1,23 @@ +import { PostTurnStatusEffectPhase } from "#app/phases/post-turn-status-effect-phase"; +import { Phase } from "#app/phase"; +import { BattlerIndex } from "#app/battle"; +import BattleScene from "#app/battle-scene"; + +export class CheckStatusEffectPhase extends Phase { + private order : BattlerIndex[]; + constructor(scene : BattleScene, order : BattlerIndex[]) { + super(scene); + this.scene = scene; + this.order = order; + } + + start() { + const field = this.scene.getField(); + for (const o of this.order) { + if (field[o].status && field[o].status.isPostTurn()) { + this.scene.unshiftPhase(new PostTurnStatusEffectPhase(this.scene, o)); + } + } + this.end(); + } +} diff --git a/src/phases/obtain-status-effect-phase.ts b/src/phases/obtain-status-effect-phase.ts index bf38c432394..c396fa7ba59 100644 --- a/src/phases/obtain-status-effect-phase.ts +++ b/src/phases/obtain-status-effect-phase.ts @@ -6,7 +6,6 @@ import { StatusEffect } from "#app/enums/status-effect"; import Pokemon from "#app/field/pokemon"; import { getPokemonNameWithAffix } from "#app/messages"; import { PokemonPhase } from "./pokemon-phase"; -import { PostTurnStatusEffectPhase } from "./post-turn-status-effect-phase"; export class ObtainStatusEffectPhase extends PokemonPhase { private statusEffect?: StatusEffect | undefined; @@ -33,9 +32,6 @@ export class ObtainStatusEffectPhase extends PokemonPhase { pokemon.updateInfo(true); new CommonBattleAnim(CommonAnim.POISON + (this.statusEffect! - 1), pokemon).play(this.scene, false, () => { this.scene.queueMessage(getStatusEffectObtainText(this.statusEffect, getPokemonNameWithAffix(pokemon), this.sourceText ?? undefined)); - if (pokemon.status?.isPostTurn()) { - this.scene.pushPhase(new PostTurnStatusEffectPhase(this.scene, this.battlerIndex)); - } this.end(); }); return; diff --git a/src/phases/turn-start-phase.ts b/src/phases/turn-start-phase.ts index 53623f933f2..627cee4b06a 100644 --- a/src/phases/turn-start-phase.ts +++ b/src/phases/turn-start-phase.ts @@ -13,10 +13,10 @@ import { BerryPhase } from "./berry-phase"; import { FieldPhase } from "./field-phase"; import { MoveHeaderPhase } from "./move-header-phase"; import { MovePhase } from "./move-phase"; -import { PostTurnStatusEffectPhase } from "./post-turn-status-effect-phase"; import { SwitchSummonPhase } from "./switch-summon-phase"; import { TurnEndPhase } from "./turn-end-phase"; import { WeatherEffectPhase } from "./weather-effect-phase"; +import { CheckStatusEffectPhase } from "#app/phases/check-status-effect-phase"; import { BattlerIndex } from "#app/battle"; import { TrickRoomTag } from "#app/data/arena-tag"; import { SwitchType } from "#enums/switch-type"; @@ -206,11 +206,8 @@ export class TurnStartPhase extends FieldPhase { this.scene.pushPhase(new WeatherEffectPhase(this.scene)); - for (const o of moveOrder) { - if (field[o].status && field[o].status.isPostTurn()) { - this.scene.pushPhase(new PostTurnStatusEffectPhase(this.scene, o)); - } - } + /** Add a new phase to check who should be taking status damage */ + this.scene.pushPhase(new CheckStatusEffectPhase(this.scene, moveOrder)); this.scene.pushPhase(new BerryPhase(this.scene)); this.scene.pushPhase(new TurnEndPhase(this.scene)); diff --git a/src/system/arena-data.ts b/src/system/arena-data.ts index 5b907805372..ba37de0ed0e 100644 --- a/src/system/arena-data.ts +++ b/src/system/arena-data.ts @@ -1,5 +1,5 @@ import { Arena } from "../field/arena"; -import { ArenaTag } from "../data/arena-tag"; +import { ArenaTag, loadArenaTag } from "../data/arena-tag"; import { Biome } from "#enums/biome"; import { Weather } from "../data/weather"; import { Terrain } from "#app/data/terrain"; @@ -15,6 +15,10 @@ export default class ArenaData { this.biome = sourceArena ? sourceArena.biomeType : source.biome; this.weather = sourceArena ? sourceArena.weather : source.weather ? new Weather(source.weather.weatherType, source.weather.turnsLeft) : null; this.terrain = sourceArena ? sourceArena.terrain : source.terrain ? new Terrain(source.terrain.terrainType, source.terrain.turnsLeft) : null; - this.tags = sourceArena ? sourceArena.tags : []; + this.tags = []; + + if (source.tags) { + this.tags = source.tags.map(t => loadArenaTag(t)); + } } } diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 0d2f35ae728..b162962fac6 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -31,7 +31,7 @@ import { TrainerVariant } from "#app/field/trainer"; import { Variant } from "#app/data/variant"; import { setSettingGamepad, SettingGamepad, settingGamepadDefaults } from "#app/system/settings/settings-gamepad"; import { setSettingKeyboard, SettingKeyboard } from "#app/system/settings/settings-keyboard"; -import { TerrainChangedEvent, WeatherChangedEvent } from "#app/events/arena"; +import { TagAddedEvent, TerrainChangedEvent, WeatherChangedEvent } from "#app/events/arena"; import * as Modifier from "#app/modifier/modifier"; import { StatusEffect } from "#app/data/status-effect"; import ChallengeData from "#app/system/challenge-data"; @@ -50,6 +50,7 @@ import { applySessionDataPatches, applySettingsDataPatches, applySystemDataPatch import { MysteryEncounterSaveData } from "#app/data/mystery-encounters/mystery-encounter-save-data"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { PokerogueApiClearSessionData } from "#app/@types/pokerogue-api"; +import { ArenaTrapTag } from "#app/data/arena-tag"; export const defaultStarterSpecies: Species[] = [ Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, @@ -1085,8 +1086,18 @@ export class GameData { scene.arena.terrain = sessionData.arena.terrain; scene.arena.eventTarget.dispatchEvent(new TerrainChangedEvent(TerrainType.NONE, scene.arena.terrain?.terrainType!, scene.arena.terrain?.turnsLeft!)); // TODO: is this bang correct? - // TODO - //scene.arena.tags = sessionData.arena.tags; + + scene.arena.tags = sessionData.arena.tags; + if (scene.arena.tags) { + for (const tag of scene.arena.tags) { + if (tag instanceof ArenaTrapTag) { + const { tagType, side, turnCount, layers, maxLayers } = tag as ArenaTrapTag; + scene.arena.eventTarget.dispatchEvent(new TagAddedEvent(tagType, side, turnCount, layers, maxLayers)); + } else { + scene.arena.eventTarget.dispatchEvent(new TagAddedEvent(tag.tagType, tag.side, tag.turnCount)); + } + } + } for (const modifierData of sessionData.modifiers) { const modifier = modifierData.toModifier(scene, Modifier[modifierData.className]); diff --git a/src/test/items/toxic_orb.test.ts b/src/test/items/toxic_orb.test.ts index a83fd3655e5..63c7b6245f5 100644 --- a/src/test/items/toxic_orb.test.ts +++ b/src/test/items/toxic_orb.test.ts @@ -1,7 +1,4 @@ import { StatusEffect } from "#app/data/status-effect"; -import { EnemyCommandPhase } from "#app/phases/enemy-command-phase"; -import { MessagePhase } from "#app/phases/message-phase"; -import { TurnEndPhase } from "#app/phases/turn-end-phase"; import i18next from "#app/plugins/i18n"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; @@ -10,6 +7,7 @@ import GameManager from "#test/utils/gameManager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; +const TIMEOUT = 20 * 1000; describe("Items - Toxic orb", () => { let phaserGame: Phaser.Game; @@ -27,40 +25,36 @@ describe("Items - Toxic orb", () => { beforeEach(() => { game = new GameManager(phaserGame); - const moveToUse = Moves.GROWTH; - const oppMoveToUse = Moves.TACKLE; - game.override.battleType("single"); - game.override.enemySpecies(Species.RATTATA); - game.override.ability(Abilities.INSOMNIA); - game.override.enemyAbility(Abilities.INSOMNIA); - game.override.startingLevel(2000); - game.override.moveset([ moveToUse ]); - game.override.enemyMoveset([ oppMoveToUse, oppMoveToUse, oppMoveToUse, oppMoveToUse ]); - game.override.startingHeldItems([{ - name: "TOXIC_ORB", - }]); + game.override + .battleType("single") + .enemySpecies(Species.RATTATA) + .ability(Abilities.BALL_FETCH) + .enemyAbility(Abilities.BALL_FETCH) + .moveset([ Moves.SPLASH ]) + .enemyMoveset(Moves.SPLASH) + .startingHeldItems([{ + name: "TOXIC_ORB", + }]); vi.spyOn(i18next, "t"); }); - it("TOXIC ORB", async () => { - const moveToUse = Moves.GROWTH; - await game.startBattle([ - Species.MIGHTYENA, - Species.MIGHTYENA, - ]); - expect(game.scene.modifiers[0].type.id).toBe("TOXIC_ORB"); + it("badly poisons the holder", async () => { + await game.classicMode.startBattle([ Species.MIGHTYENA ]); - game.move.select(moveToUse); + const player = game.scene.getPlayerField()[0]; - // will run the 13 phase from enemyCommandPhase to TurnEndPhase - await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(TurnEndPhase); + game.move.select(Moves.SPLASH); + + await game.phaseInterceptor.to("TurnEndPhase"); // Toxic orb should trigger here - await game.phaseInterceptor.run(MessagePhase); + await game.phaseInterceptor.run("MessagePhase"); expect(i18next.t).toHaveBeenCalledWith("statusEffect:toxic.obtainSource", expect.anything()); - await game.phaseInterceptor.run(MessagePhase); - expect(i18next.t).toHaveBeenCalledWith("statusEffect:toxic.activation", expect.anything()); - expect(game.scene.getParty()[0].status!.effect).toBe(StatusEffect.TOXIC); - }, 20000); + await game.toNextTurn(); + + expect(player.status?.effect).toBe(StatusEffect.TOXIC); + // Damage should not have ticked yet. + expect(player.status?.turnCount).toBe(0); + }, TIMEOUT); }); diff --git a/src/test/moves/toxic_spikes.test.ts b/src/test/moves/toxic_spikes.test.ts new file mode 100644 index 00000000000..bac1ccdccd8 --- /dev/null +++ b/src/test/moves/toxic_spikes.test.ts @@ -0,0 +1,136 @@ +import { ArenaTagSide, ArenaTrapTag } from "#app/data/arena-tag"; +import { StatusEffect } from "#app/data/status-effect"; +import { decrypt, encrypt, GameData, SessionSaveData } from "#app/system/game-data"; +import { Abilities } from "#enums/abilities"; +import { ArenaTagType } from "#enums/arena-tag-type"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +const TIMEOUT = 20 * 1000; + +describe("Moves - Toxic Spikes", () => { + 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 + .battleType("single") + .startingWave(5) + .enemySpecies(Species.RATTATA) + .enemyAbility(Abilities.BALL_FETCH) + .ability(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH) + .moveset([ Moves.TOXIC_SPIKES, Moves.SPLASH, Moves.ROAR ]); + }); + + it("should not affect the opponent if they do not switch", async() => { + await game.classicMode.runToSummon([ Species.MIGHTYENA, Species.POOCHYENA ]); + + const enemy = game.scene.getEnemyField()[0]; + + game.move.select(Moves.TOXIC_SPIKES); + await game.phaseInterceptor.to("TurnEndPhase"); + game.move.select(Moves.SPLASH); + await game.phaseInterceptor.to("TurnEndPhase"); + game.doSwitchPokemon(1); + await game.phaseInterceptor.to("TurnEndPhase"); + + expect(enemy.hp).toBe(enemy.getMaxHp()); + expect(enemy.status?.effect).toBeUndefined(); + }, TIMEOUT); + + it("should poison the opponent if they switch into 1 layer", async() => { + await game.classicMode.runToSummon([ Species.MIGHTYENA ]); + + game.move.select(Moves.TOXIC_SPIKES); + await game.phaseInterceptor.to("TurnEndPhase"); + game.move.select(Moves.ROAR); + await game.phaseInterceptor.to("TurnEndPhase"); + + const enemy = game.scene.getEnemyField()[0]; + + expect(enemy.hp).toBeLessThan(enemy.getMaxHp()); + expect(enemy.status?.effect).toBe(StatusEffect.POISON); + }, TIMEOUT); + + it("should badly poison the opponent if they switch into 2 layers", async() => { + await game.classicMode.runToSummon([ Species.MIGHTYENA ]); + + game.move.select(Moves.TOXIC_SPIKES); + await game.phaseInterceptor.to("TurnEndPhase"); + game.move.select(Moves.TOXIC_SPIKES); + await game.phaseInterceptor.to("TurnEndPhase"); + game.move.select(Moves.ROAR); + await game.phaseInterceptor.to("TurnEndPhase"); + + const enemy = game.scene.getEnemyField()[0]; + expect(enemy.hp).toBeLessThan(enemy.getMaxHp()); + expect(enemy.status?.effect).toBe(StatusEffect.TOXIC); + }, TIMEOUT); + + it("should be removed if a grounded poison pokemon switches in", async() => { + game.override.enemySpecies(Species.GRIMER); + await game.classicMode.runToSummon([ Species.MIGHTYENA ]); + + game.move.select(Moves.TOXIC_SPIKES); + await game.phaseInterceptor.to("TurnEndPhase"); + game.move.select(Moves.TOXIC_SPIKES); + await game.phaseInterceptor.to("TurnEndPhase"); + game.move.select(Moves.ROAR); + await game.phaseInterceptor.to("TurnEndPhase"); + + const enemy = game.scene.getEnemyField()[0]; + expect(enemy.hp).toBe(enemy.getMaxHp()); + expect(enemy.status?.effect).toBeUndefined(); + + expect(game.scene.arena.tags.length).toBe(0); + }, TIMEOUT); + + it("shouldn't create multiple layers per use in doubles", async() => { + await game.classicMode.runToSummon([ Species.MIGHTYENA, Species.POOCHYENA ]); + + game.move.select(Moves.TOXIC_SPIKES); + await game.phaseInterceptor.to("TurnEndPhase"); + + const arenaTags = (game.scene.arena.getTagOnSide(ArenaTagType.TOXIC_SPIKES, ArenaTagSide.ENEMY) as ArenaTrapTag); + expect(arenaTags.tagType).toBe(ArenaTagType.TOXIC_SPIKES); + expect(arenaTags.layers).toBe(1); + }, TIMEOUT); + + it("should persist through reload", async() => { + game.override.startingWave(1); + const scene = game.scene; + const gameData = new GameData(scene); + + await game.classicMode.runToSummon([ Species.MIGHTYENA ]); + + game.move.select(Moves.TOXIC_SPIKES); + await game.phaseInterceptor.to("TurnEndPhase"); + game.move.select(Moves.SPLASH); + await game.doKillOpponents(); + await game.phaseInterceptor.to("BattleEndPhase"); + await game.toNextWave(); + + const sessionData : SessionSaveData = gameData["getSessionSaveData"](game.scene); + localStorage.setItem("sessionTestData", encrypt(JSON.stringify(sessionData), true)); + const recoveredData : SessionSaveData = gameData.parseSessionData(decrypt(localStorage.getItem("sessionTestData")!, true)); + gameData.loadSession(game.scene, 0, recoveredData); + + expect(sessionData.arena.tags).toEqual(recoveredData.arena.tags); + localStorage.removeItem("sessionTestData"); + }, TIMEOUT); +}); From 89d7e7ea655b8a0f103cee1a6ab696a26da4896a Mon Sep 17 00:00:00 2001 From: MokaStitcher <54149968+MokaStitcher@users.noreply.github.com> Date: Fri, 11 Oct 2024 21:46:00 +0200 Subject: [PATCH 16/37] [P3][UI] Fix tooltip bugs in Starter Select screen (#4641) * [UI] Fix candy friendship tooltip bug in Starter Select * [UI] remove tooltip when exiting starter select screen --- src/ui/starter-select-ui-handler.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 5bbe765947e..2be89052bc1 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -2963,8 +2963,12 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.natureCursor = -1; if (this.activeTooltip === "CANDY") { - const { currentFriendship, friendshipCap } = this.getFriendship(this.lastSpecies.speciesId); - this.scene.ui.editTooltip("", `${currentFriendship}/${friendshipCap}`); + if (this.lastSpecies) { + const { currentFriendship, friendshipCap } = this.getFriendship(this.lastSpecies.speciesId); + this.scene.ui.editTooltip("", `${currentFriendship}/${friendshipCap}`); + } else { + this.scene.ui.hideTooltip(); + } } if (species?.forms?.find(f => f.formKey === "female")) { @@ -3655,6 +3659,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler { StarterPrefs.save(this.starterPreferences); this.cursor = -1; this.hideInstructions(); + this.activeTooltip = undefined; + this.scene.ui.hideTooltip(); + this.starterSelectContainer.setVisible(false); this.blockInput = false; From f0cc1fc88bba1015d47ec5a34d83b224952b09c6 Mon Sep 17 00:00:00 2001 From: pom-eranian Date: Fri, 11 Oct 2024 16:08:39 -0400 Subject: [PATCH 17/37] [Sprite] Hisui Goodra, Sliggoo, Shiftry (#4642) * [Sprite][Anim] 275 Shiftree- cropped ear fix - @hamez * 705 6706 Sliggoo Hisuian Goodra [Color Fixes] - @ rival_kieran - Fix to Kalosian Sligoo (705). Front exp should now use shaders properly. - Fix to all of Hisuian Goodra's base sprites + Variants to allow them to use shaders properly (as they didn't before). .json file included. - Fix to Hisuian Goodra's back static Rare Variant which used colors from the Epic variant on accident on cheeks + spots and drips. - Hisuian Goodra's eyes on Variant (Rare, Epic) exps were mapped to the wrong color compared to the statics, this has been fixed. - All images should be indexed. * Set variants to palette, removed old files --- public/images/pokemon/275.png | Bin 10555 -> 11106 bytes public/images/pokemon/6706.png | Bin 1040 -> 1103 bytes public/images/pokemon/back/6706.png | Bin 879 -> 942 bytes public/images/pokemon/exp/6706.png | Bin 24796 -> 27836 bytes public/images/pokemon/exp/705.png | Bin 1851 -> 1913 bytes public/images/pokemon/exp/back/6706.png | Bin 8135 -> 8808 bytes public/images/pokemon/female/275.png | Bin 10686 -> 11186 bytes public/images/pokemon/shiny/275.png | Bin 10555 -> 11107 bytes public/images/pokemon/shiny/female/275.png | Bin 10686 -> 11186 bytes public/images/pokemon/variant/6706.json | 40 + public/images/pokemon/variant/6706_2.json | 41 - public/images/pokemon/variant/6706_2.png | Bin 5170 -> 0 bytes public/images/pokemon/variant/6706_3.json | 41 - public/images/pokemon/variant/6706_3.png | Bin 5177 -> 0 bytes .../images/pokemon/variant/_masterlist.json | 20 +- public/images/pokemon/variant/back/6706.json | 38 + .../images/pokemon/variant/back/6706_2.json | 41 - public/images/pokemon/variant/back/6706_2.png | Bin 4762 -> 0 bytes .../images/pokemon/variant/back/6706_3.json | 41 - public/images/pokemon/variant/back/6706_3.png | Bin 4765 -> 0 bytes public/images/pokemon/variant/exp/6706.json | 40 + public/images/pokemon/variant/exp/6706_2.json | 2015 ----------------- public/images/pokemon/variant/exp/6706_2.png | Bin 55978 -> 0 bytes public/images/pokemon/variant/exp/6706_3.json | 2015 ----------------- public/images/pokemon/variant/exp/6706_3.png | Bin 56190 -> 0 bytes public/images/pokemon/variant/exp/705.json | 33 + public/images/pokemon/variant/exp/705_2.json | 272 --- public/images/pokemon/variant/exp/705_2.png | Bin 4111 -> 0 bytes public/images/pokemon/variant/exp/705_3.json | 272 --- public/images/pokemon/variant/exp/705_3.png | Bin 4119 -> 0 bytes .../images/pokemon/variant/exp/back/6706.json | 38 + .../pokemon/variant/exp/back/6706_2.json | 776 ------- .../pokemon/variant/exp/back/6706_2.png | Bin 22444 -> 0 bytes .../pokemon/variant/exp/back/6706_3.json | 776 ------- .../pokemon/variant/exp/back/6706_3.png | Bin 22483 -> 0 bytes 35 files changed, 199 insertions(+), 6300 deletions(-) create mode 100644 public/images/pokemon/variant/6706.json delete mode 100644 public/images/pokemon/variant/6706_2.json delete mode 100644 public/images/pokemon/variant/6706_2.png delete mode 100644 public/images/pokemon/variant/6706_3.json delete mode 100644 public/images/pokemon/variant/6706_3.png create mode 100644 public/images/pokemon/variant/back/6706.json delete mode 100644 public/images/pokemon/variant/back/6706_2.json delete mode 100644 public/images/pokemon/variant/back/6706_2.png delete mode 100644 public/images/pokemon/variant/back/6706_3.json delete mode 100644 public/images/pokemon/variant/back/6706_3.png create mode 100644 public/images/pokemon/variant/exp/6706.json delete mode 100644 public/images/pokemon/variant/exp/6706_2.json delete mode 100644 public/images/pokemon/variant/exp/6706_2.png delete mode 100644 public/images/pokemon/variant/exp/6706_3.json delete mode 100644 public/images/pokemon/variant/exp/6706_3.png create mode 100644 public/images/pokemon/variant/exp/705.json delete mode 100644 public/images/pokemon/variant/exp/705_2.json delete mode 100644 public/images/pokemon/variant/exp/705_2.png delete mode 100644 public/images/pokemon/variant/exp/705_3.json delete mode 100644 public/images/pokemon/variant/exp/705_3.png create mode 100644 public/images/pokemon/variant/exp/back/6706.json delete mode 100644 public/images/pokemon/variant/exp/back/6706_2.json delete mode 100644 public/images/pokemon/variant/exp/back/6706_2.png delete mode 100644 public/images/pokemon/variant/exp/back/6706_3.json delete mode 100644 public/images/pokemon/variant/exp/back/6706_3.png diff --git a/public/images/pokemon/275.png b/public/images/pokemon/275.png index 07a6fe725adfc61aad7a862a12678b088b533a37..61f98ed16555660d553a699e2dda6d8c0b2feb6f 100644 GIT binary patch literal 11106 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 diff --git a/public/images/pokemon/6706.png b/public/images/pokemon/6706.png index 44f627acd1011076a81973d1fa47e325aa12239b..e967b5508713a8aa1802e00ca8963727797f1275 100644 GIT binary patch delta 1082 zcmV-A1jYN12+s(RB!2;OQb$4nuFf3k0000yP)t-s0000F5e-X4Pk?iOn2VUdtik5f z>G%2eVp4~ZaJjdU@>61Sj+Uy#%;DhV^fo|DQD1OYW_XK}rp3kplbCiSpRd+&l*v8AKWycm{nM zyV(7=!MrMQAY(`3IQekSw2Nqw>8#I4B|}Iz$~dKjPjB(V=jQDHm?>$f!~79p>Y$oP zFi*&tJ@S~546o5FXJU*gWtBXb87aeC6tW95sefyv zemu<_d`@o!)-!T}@`bL*f-POhXmLetoVu<)e8;B1i0zqJit33()sCaP!P$7GIj z5XE-8lUZKqf|t*O%aENK+$vI%y|nh|k=P>XGVI7nnu6@J4qeyFkjP;TTok7!Tv?v& zkbih9^%2Y51ig$OUiCKHL`38{JtsTAx~7+8ozx_t1sHpC9MnM&=r zc*ro+Le%D`;N;jKaihAsb=YlUA@0WJygnyea}pL!T95GNYR6UC%}+#)JdoJr^-{!@ zcnf$U5gjFOxs6S}5<%iRbV3w?O#3l0GJoa#X^e7E2p^^#d=Ocz7VS(N6q` zOQchADe>kvWHd$o4d0L*C5wXifrxj6oDg4=a61TBA}-{qKZ>XhzeSN*{P6Qei8FHg ziEq2I{1V9hTT&Q2gMLh^AB*XinZNq0zxs9k2jQQ9d?va*lmGw#07*qoM6N<$f>Zqx AD*ylh delta 1018 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 Hu0mjfSn$d2 diff --git a/public/images/pokemon/exp/705.png b/public/images/pokemon/exp/705.png index 3413bcd9fa35db5d1cd102176e6664c2fbfbd6e6..670e8be5d51fd8645ca363e13dcc9eca01115e36 100644 GIT binary patch delta 1886 zcmV-k2ch`84*3p{B!2;OQb$4nuFf3k0000gP)t-s0000G5D-m8O@MQNzpTIV+VW;u zfRBB%xS{1unLTFAQcj#cXU|i%@~Zf82(thH01k9gPE!E?|NsC0|NsC0|NsC0S4!Iy z000K#NklvG&G5QMdWkTy=<|8*now;87KCg)VDn13I(V}EoHh}BA~&T;%} zrB~P`c(s#3;KU{LxdeaM+v5gHIM%4YApE)Aa%(Wm37`s&Rj}KFFl(n!JI5Xks$G39 z+z!;m>^SBEE!+ITt;|U`r)6QrF6_|Jj#!DzmR~DZV%Y`Pkp#&E*oD?>Xy{S5Ey zsFf&evI`sZ%zv#_$1P64eN&{ck$Q6{DDTwSkt-2dZ9J<@Y)ZL${?%+KZXQM0Ag!6v z?j#g4d-_#=P^I!VQc8`{5-aRa*9sjw$%w`wI+!#AabYnSU66#BJ&4I3J%`KMC1PCt(C0 zN5Avt)RI7E{c=cdtMeGf|5$KK@cSKJxI$}jBG5c2v)}@`CHNgWgyw-MQ^QSgdn0Zc z{t;UgI_s2I7j4CDgqP;Ax@zb9#N9F+j?r`?eQV3hmfy`Fw*h|=qwJ*AAlc0tS{?dnU0b+~}^(%LnJ&`b>a3V4BGh$u!pru0L3GlF zCNh?e8#U}$(M|i8-P0OECv9-r#OPvn0(Y(9eDDJ3R(t&tJiVL5)}*_nj01G9{mssv z1@~uf(Ch^03Wla#%33%2ekz-3{<6r?9nRAPEKj={e&5#KvC{DH83RrGFD=f{jr1)~ zdw(2WSDqT%S#h()j_d5H*PzW!dlYySuExx_#+xi0#0d5K<=mIX|nCDPlRUXunUcLfCt z^){#1q{p)NINU3c3%^9KNfX2KK8-(=m(?h+M6XFRtyM#w3JMo>1N=8>qPOz47=H)6 zLjC77DG=)arzgceIsXm_FtDG$^Mx)#5fET{gijT~Nel!Wn9;XGW~qYjw?<4C@NEz> zRZx@dXA;Z;_aJ9m7&^^RBbrVX6truMS>P6=r`s^JZ;f~jGFQ-pTx^2^DchEzZTrsB z0;=|av?Lqb$Y2S`P_}+rD)Oz7-O3(z0%}qzmF-XEX99v*oIG7Qpb-E z9L7M|@(h+UM}(_e(~}%U)fxv?mh(VH6%!GjShsl+L~pW*5X&m=BD9u3Gk=YfG#G%) zEl)wJ0maY;fT2q93?{}zbUM?CkLX1Xl1k@uIVO_HAj-ewWe$=`0TwwXQpkC11K=>J zA@9PsmdW`n01lJVa85*nu?>KOr0|>wN&*}vRVXPZQjycx2EbubIl?05L@F|TXC8(F z943XwL>h9E+5k9E3Xh2t(tlsMvZ)Jz!=!Y9riL{cR+o!i030Z#D`;Zak+awZz=2Y_ z$-7K5LZ-+~Ls2pZO4WH6AtMw>F}4A4s1%+PiKLkC0XR@fVTMPW+xU>fq)@{ufATqp zNtM8h^m)v3YrJBGOkAsYjAZG^^AsnMIPQM0Mdr7dJ|`k4SmGJ!C4c-!gNkE68Y>9T zw0Rfdey@;76xHyl767RzIq!m!K;Q<->uuM8l^5RYN+xnXh)+zcTK z32`6j_wg7?C($4|25yFYhlGT1%@|=J4Bc~yMA{kY!Ssx!7`I6U8EMiAu{Sy%(>!jn z6S4;>-#TT(AYHnqIDay&#b;mlH6aHuaCL?TKzyaVOKR?9vN+ae(w222NC)0E=r~m$ zc()vOkW$0mNQ>*DI9X_DtT_yo9{DOD5;U*wSP@dQhn7~#yHw;oBY^}BCWS{>P!ixE zDLldglK_ZlEksyg6agUykFcO9!huXvlMD-rA{?Z(kYPblgp=3?5L3x}@t#LmP!i!F zEj+=3k_d-s;RzO$L^x0jPq3gQ!u_$_%&uL#cJ11=YuBz_yLRo`wQJX|UAuPe+V$_$ YZ@>AKSD6@q_5c6?07*qoM6N<$f^O`ZumAu6 delta 1812 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 literal 8135 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 diff --git a/public/images/pokemon/female/275.png b/public/images/pokemon/female/275.png index 7f251793a15764d2a7bb5849e65045ad7884eae3..c3c358716b2d919fc2a882d2f69e3ad524d57761 100644 GIT binary patch literal 11186 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≪pFCQ%=xE@hNoXB9038F;6HZ(ytRK>+ik2e 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 VwS#>?K2`v{tSucZ-XOf={|_}1*(Lx0 diff --git a/public/images/pokemon/variant/exp/705.json b/public/images/pokemon/variant/exp/705.json new file mode 100644 index 00000000000..a29b8f124dc --- /dev/null +++ b/public/images/pokemon/variant/exp/705.json @@ -0,0 +1,33 @@ +{ + "1": { + "101010":"101010", + "4d454d":"8a2166", + "807380":"b93f84", + "bfacbf":"e56ca6", + "f2daf2":"fbb3d2", + "665980":"4e4094", + "8f7db3":"8b69c3", + "b8a1e5":"c7a1e5", + "4d993d":"aa6a00", + "66cc52":"ffd047", + "4e9c3e":"0c5474", + "67cf53":"3aa8c4", + "b6f2aa":"63cee1" + }, + "2": { + "101010":"101010", + "4d454d":"194f51", + "807380":"2b736f", + "bfacbf":"5db6a9", + "f2daf2":"9cead8", + "665980":"274159", + "8f7db3":"2f667c", + "b8a1e5":"4a9699", + "4d993d":"007d61", + "66cc52":"49ffbf", + "4e9c3e":"842401", + "67cf53":"a34205", + "b6f2aa":"d27e26" + } +} + diff --git a/public/images/pokemon/variant/exp/705_2.json b/public/images/pokemon/variant/exp/705_2.json deleted file mode 100644 index bf9fd104c5d..00000000000 --- a/public/images/pokemon/variant/exp/705_2.json +++ /dev/null @@ -1,272 +0,0 @@ -{ - "textures": [ - { - "image": "705_2.png", - "format": "RGBA8888", - "size": { - "w": 154, - "h": 154 - }, - "scale": 1, - "frames": [ - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 46, - "h": 58 - }, - "frame": { - "x": 0, - "y": 0, - "w": 46, - "h": 58 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 46, - "h": 58 - }, - "frame": { - "x": 0, - "y": 0, - "w": 46, - "h": 58 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 45, - "h": 58 - }, - "frame": { - "x": 46, - "y": 0, - "w": 45, - "h": 58 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 45, - "h": 58 - }, - "frame": { - "x": 46, - "y": 0, - "w": 45, - "h": 58 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 45, - "h": 58 - }, - "frame": { - "x": 91, - "y": 0, - "w": 45, - "h": 58 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 42, - "h": 58 - }, - "frame": { - "x": 0, - "y": 58, - "w": 42, - "h": 58 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 42, - "h": 58 - }, - "frame": { - "x": 0, - "y": 58, - "w": 42, - "h": 58 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 41, - "h": 58 - }, - "frame": { - "x": 42, - "y": 58, - "w": 41, - "h": 58 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 41, - "h": 58 - }, - "frame": { - "x": 42, - "y": 58, - "w": 41, - "h": 58 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 36, - "h": 58 - }, - "frame": { - "x": 83, - "y": 58, - "w": 36, - "h": 58 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 36, - "h": 58 - }, - "frame": { - "x": 83, - "y": 58, - "w": 36, - "h": 58 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 58 - }, - "frame": { - "x": 119, - "y": 58, - "w": 35, - "h": 58 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:4bf155254b23c88780e7eee282256589:82bb727988054c3064e203b6908ff464:6b57e983626c7fc9144ab67f30c66814$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/705_2.png b/public/images/pokemon/variant/exp/705_2.png deleted file mode 100644 index 8256ebc7fdbebeaff9d693aed989c4fbce61b77e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4111 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 diff --git a/public/images/pokemon/variant/exp/705_3.json b/public/images/pokemon/variant/exp/705_3.json deleted file mode 100644 index 199d7bc9c3e..00000000000 --- a/public/images/pokemon/variant/exp/705_3.json +++ /dev/null @@ -1,272 +0,0 @@ -{ - "textures": [ - { - "image": "705_3.png", - "format": "RGBA8888", - "size": { - "w": 154, - "h": 154 - }, - "scale": 1, - "frames": [ - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 46, - "h": 58 - }, - "frame": { - "x": 0, - "y": 0, - "w": 46, - "h": 58 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 46, - "h": 58 - }, - "frame": { - "x": 0, - "y": 0, - "w": 46, - "h": 58 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 45, - "h": 58 - }, - "frame": { - "x": 46, - "y": 0, - "w": 45, - "h": 58 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 45, - "h": 58 - }, - "frame": { - "x": 46, - "y": 0, - "w": 45, - "h": 58 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 45, - "h": 58 - }, - "frame": { - "x": 91, - "y": 0, - "w": 45, - "h": 58 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 42, - "h": 58 - }, - "frame": { - "x": 0, - "y": 58, - "w": 42, - "h": 58 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 1, - "y": 0, - "w": 42, - "h": 58 - }, - "frame": { - "x": 0, - "y": 58, - "w": 42, - "h": 58 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 41, - "h": 58 - }, - "frame": { - "x": 42, - "y": 58, - "w": 41, - "h": 58 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 41, - "h": 58 - }, - "frame": { - "x": 42, - "y": 58, - "w": 41, - "h": 58 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 36, - "h": 58 - }, - "frame": { - "x": 83, - "y": 58, - "w": 36, - "h": 58 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 36, - "h": 58 - }, - "frame": { - "x": 83, - "y": 58, - "w": 36, - "h": 58 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 49, - "h": 58 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 35, - "h": 58 - }, - "frame": { - "x": 119, - "y": 58, - "w": 35, - "h": 58 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:4bf155254b23c88780e7eee282256589:82bb727988054c3064e203b6908ff464:6b57e983626c7fc9144ab67f30c66814$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/705_3.png b/public/images/pokemon/variant/exp/705_3.png deleted file mode 100644 index 66b43956bdf70a75057437c951b98f1c55eef48c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4119 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 Lf*Zay@Obb);ds$n diff --git a/public/images/pokemon/variant/exp/back/6706.json b/public/images/pokemon/variant/exp/back/6706.json new file mode 100644 index 00000000000..2de5352e936 --- /dev/null +++ b/public/images/pokemon/variant/exp/back/6706.json @@ -0,0 +1,38 @@ +{ + "1": { + "566678": "197497", + "8e96aa": "3b235c", + "929aad": "3aa8c4", + "625287": "4e4094", + "536273": "301848", + "988b98": "b24c86", + "36404c": "0c5474", + "c4cce1": "513981", + "e6d3e9": "f1a4c5", + "bfacc1": "d074a0", + "546475": "0e6296", + "c5cee3": "63cee1", + "80737f": "8a2166", + "4b454f": "6f1357", + "9170b9": "8b69c3", + "b791f2": "c7a1e5" + }, + "2": { + "566678": "a34205", + "8e96aa": "073338", + "929aad": "d27e26", + "625287": "0e3f47", + "536273": "042329", + "988b98": "2b736f", + "36404c": "842401", + "c4cce1": "0d484a", + "e6d3e9": "9cead8", + "bfacc1": "5db6a9", + "546475": "8e480b", + "c5cee3": "f7af58", + "80737f": "194f51", + "4b454f": "274159", + "9170b9": "2f667c", + "b791f2": "4a9699" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/6706_2.json b/public/images/pokemon/variant/exp/back/6706_2.json deleted file mode 100644 index 5c916aeb664..00000000000 --- a/public/images/pokemon/variant/exp/back/6706_2.json +++ /dev/null @@ -1,776 +0,0 @@ -{ - "textures": [ - { - "image": "6706_2.png", - "format": "RGBA8888", - "size": { - "w": 358, - "h": 358 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 0, - "y": 4, - "w": 84, - "h": 69 - }, - "frame": { - "x": 0, - "y": 0, - "w": 84, - "h": 69 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 0, - "y": 4, - "w": 84, - "h": 69 - }, - "frame": { - "x": 0, - "y": 0, - "w": 84, - "h": 69 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 83, - "h": 72 - }, - "frame": { - "x": 84, - "y": 0, - "w": 83, - "h": 72 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 83, - "h": 72 - }, - "frame": { - "x": 84, - "y": 0, - "w": 83, - "h": 72 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 83, - "h": 72 - }, - "frame": { - "x": 0, - "y": 69, - "w": 83, - "h": 72 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 83, - "h": 70 - }, - "frame": { - "x": 167, - "y": 0, - "w": 83, - "h": 70 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 83, - "h": 70 - }, - "frame": { - "x": 167, - "y": 0, - "w": 83, - "h": 70 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 83, - "h": 70 - }, - "frame": { - "x": 250, - "y": 0, - "w": 83, - "h": 70 - } - }, - { - "filename": "0036.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 83, - "h": 70 - }, - "frame": { - "x": 250, - "y": 0, - "w": 83, - "h": 70 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 4, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 167, - "y": 70, - "w": 82, - "h": 73 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 4, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 167, - "y": 70, - "w": 82, - "h": 73 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 83, - "y": 72, - "w": 82, - "h": 73 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 83, - "y": 72, - "w": 82, - "h": 73 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 0, - "y": 141, - "w": 82, - "h": 73 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 0, - "y": 141, - "w": 82, - "h": 73 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 0, - "y": 141, - "w": 82, - "h": 73 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 4, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 249, - "y": 70, - "w": 82, - "h": 73 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 4, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 249, - "y": 70, - "w": 82, - "h": 73 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 81, - "h": 73 - }, - "frame": { - "x": 0, - "y": 214, - "w": 81, - "h": 73 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 81, - "h": 73 - }, - "frame": { - "x": 0, - "y": 214, - "w": 81, - "h": 73 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 81, - "h": 71 - }, - "frame": { - "x": 0, - "y": 287, - "w": 81, - "h": 71 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 81, - "h": 71 - }, - "frame": { - "x": 0, - "y": 287, - "w": 81, - "h": 71 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 81, - "h": 73 - }, - "frame": { - "x": 81, - "y": 214, - "w": 81, - "h": 73 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 81, - "h": 73 - }, - "frame": { - "x": 81, - "y": 214, - "w": 81, - "h": 73 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 81, - "h": 71 - }, - "frame": { - "x": 81, - "y": 287, - "w": 81, - "h": 71 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 81, - "h": 71 - }, - "frame": { - "x": 81, - "y": 287, - "w": 81, - "h": 71 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 82, - "h": 72 - }, - "frame": { - "x": 165, - "y": 143, - "w": 82, - "h": 72 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 82, - "h": 72 - }, - "frame": { - "x": 165, - "y": 143, - "w": 82, - "h": 72 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 82, - "h": 72 - }, - "frame": { - "x": 247, - "y": 143, - "w": 82, - "h": 72 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 82, - "h": 72 - }, - "frame": { - "x": 247, - "y": 143, - "w": 82, - "h": 72 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 6, - "y": 0, - "w": 80, - "h": 73 - }, - "frame": { - "x": 162, - "y": 215, - "w": 80, - "h": 73 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 6, - "y": 0, - "w": 80, - "h": 73 - }, - "frame": { - "x": 162, - "y": 215, - "w": 80, - "h": 73 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 0, - "y": 3, - "w": 81, - "h": 70 - }, - "frame": { - "x": 162, - "y": 288, - "w": 81, - "h": 70 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 0, - "y": 3, - "w": 81, - "h": 70 - }, - "frame": { - "x": 162, - "y": 288, - "w": 81, - "h": 70 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 6, - "y": 0, - "w": 80, - "h": 73 - }, - "frame": { - "x": 242, - "y": 215, - "w": 80, - "h": 73 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 6, - "y": 0, - "w": 80, - "h": 73 - }, - "frame": { - "x": 242, - "y": 215, - "w": 80, - "h": 73 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:5d65e2c5a6a97b7c7014a175ce3592af:3255e87f637a475d82734fc7d93baf71:d60cc2e5ae2bd18de8ee3ab0649593ee$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/6706_2.png b/public/images/pokemon/variant/exp/back/6706_2.png deleted file mode 100644 index cb79347842094431759bdf08b8d5c76eac99023a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22444 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 XiwmH!3^jqR&X^1hO!TYt>?8gU6->{8 diff --git a/public/images/pokemon/variant/exp/back/6706_3.json b/public/images/pokemon/variant/exp/back/6706_3.json deleted file mode 100644 index 3bb1dc426b2..00000000000 --- a/public/images/pokemon/variant/exp/back/6706_3.json +++ /dev/null @@ -1,776 +0,0 @@ -{ - "textures": [ - { - "image": "6706_3.png", - "format": "RGBA8888", - "size": { - "w": 358, - "h": 358 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 0, - "y": 4, - "w": 84, - "h": 69 - }, - "frame": { - "x": 0, - "y": 0, - "w": 84, - "h": 69 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 0, - "y": 4, - "w": 84, - "h": 69 - }, - "frame": { - "x": 0, - "y": 0, - "w": 84, - "h": 69 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 83, - "h": 72 - }, - "frame": { - "x": 84, - "y": 0, - "w": 83, - "h": 72 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 83, - "h": 72 - }, - "frame": { - "x": 84, - "y": 0, - "w": 83, - "h": 72 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 1, - "w": 83, - "h": 72 - }, - "frame": { - "x": 0, - "y": 69, - "w": 83, - "h": 72 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 83, - "h": 70 - }, - "frame": { - "x": 167, - "y": 0, - "w": 83, - "h": 70 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 83, - "h": 70 - }, - "frame": { - "x": 167, - "y": 0, - "w": 83, - "h": 70 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 83, - "h": 70 - }, - "frame": { - "x": 250, - "y": 0, - "w": 83, - "h": 70 - } - }, - { - "filename": "0036.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 3, - "w": 83, - "h": 70 - }, - "frame": { - "x": 250, - "y": 0, - "w": 83, - "h": 70 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 4, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 167, - "y": 70, - "w": 82, - "h": 73 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 4, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 167, - "y": 70, - "w": 82, - "h": 73 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 83, - "y": 72, - "w": 82, - "h": 73 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 83, - "y": 72, - "w": 82, - "h": 73 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 0, - "y": 141, - "w": 82, - "h": 73 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 0, - "y": 141, - "w": 82, - "h": 73 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 3, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 0, - "y": 141, - "w": 82, - "h": 73 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 4, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 249, - "y": 70, - "w": 82, - "h": 73 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 4, - "y": 0, - "w": 82, - "h": 73 - }, - "frame": { - "x": 249, - "y": 70, - "w": 82, - "h": 73 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 81, - "h": 73 - }, - "frame": { - "x": 0, - "y": 214, - "w": 81, - "h": 73 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 81, - "h": 73 - }, - "frame": { - "x": 0, - "y": 214, - "w": 81, - "h": 73 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 81, - "h": 71 - }, - "frame": { - "x": 0, - "y": 287, - "w": 81, - "h": 71 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 81, - "h": 71 - }, - "frame": { - "x": 0, - "y": 287, - "w": 81, - "h": 71 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 81, - "h": 73 - }, - "frame": { - "x": 81, - "y": 214, - "w": 81, - "h": 73 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 5, - "y": 0, - "w": 81, - "h": 73 - }, - "frame": { - "x": 81, - "y": 214, - "w": 81, - "h": 73 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 81, - "h": 71 - }, - "frame": { - "x": 81, - "y": 287, - "w": 81, - "h": 71 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 1, - "y": 2, - "w": 81, - "h": 71 - }, - "frame": { - "x": 81, - "y": 287, - "w": 81, - "h": 71 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 82, - "h": 72 - }, - "frame": { - "x": 165, - "y": 143, - "w": 82, - "h": 72 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 82, - "h": 72 - }, - "frame": { - "x": 165, - "y": 143, - "w": 82, - "h": 72 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 82, - "h": 72 - }, - "frame": { - "x": 247, - "y": 143, - "w": 82, - "h": 72 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 2, - "y": 1, - "w": 82, - "h": 72 - }, - "frame": { - "x": 247, - "y": 143, - "w": 82, - "h": 72 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 6, - "y": 0, - "w": 80, - "h": 73 - }, - "frame": { - "x": 162, - "y": 215, - "w": 80, - "h": 73 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 6, - "y": 0, - "w": 80, - "h": 73 - }, - "frame": { - "x": 162, - "y": 215, - "w": 80, - "h": 73 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 0, - "y": 3, - "w": 81, - "h": 70 - }, - "frame": { - "x": 162, - "y": 288, - "w": 81, - "h": 70 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 0, - "y": 3, - "w": 81, - "h": 70 - }, - "frame": { - "x": 162, - "y": 288, - "w": 81, - "h": 70 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 6, - "y": 0, - "w": 80, - "h": 73 - }, - "frame": { - "x": 242, - "y": 215, - "w": 80, - "h": 73 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 86, - "h": 73 - }, - "spriteSourceSize": { - "x": 6, - "y": 0, - "w": 80, - "h": 73 - }, - "frame": { - "x": 242, - "y": 215, - "w": 80, - "h": 73 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:5d65e2c5a6a97b7c7014a175ce3592af:3255e87f637a475d82734fc7d93baf71:d60cc2e5ae2bd18de8ee3ab0649593ee$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/back/6706_3.png b/public/images/pokemon/variant/exp/back/6706_3.png deleted file mode 100644 index 6390c20799f368a4253062379b4624b3f1f0ea69..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22483 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 Date: Fri, 11 Oct 2024 13:09:15 -0700 Subject: [PATCH 18/37] [P3] Fix "falsex" type hint for Sheer Cold against ice types (#4638) Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/data/move.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/data/move.ts b/src/data/move.ts index ff0c24f5032..5aa6b2623c0 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -4556,18 +4556,19 @@ export class WaterSuperEffectTypeMultiplierAttr extends VariableMoveTypeMultipli export class IceNoEffectTypeAttr extends VariableMoveTypeMultiplierAttr { /** * Checks to see if the Target is Ice-Type or not. If so, the move will have no effect. - * @param {Pokemon} user N/A - * @param {Pokemon} target Pokemon that is being checked whether Ice-Type or not. - * @param {Move} move N/A - * @param {any[]} args Sets to false if the target is Ice-Type, so it should do no damage/no effect. - * @returns {boolean} Returns true if move is successful, false if Ice-Type. + * @param user n/a + * @param target The {@linkcode Pokemon} targeted by the move + * @param move n/a + * @param args `[0]` a {@linkcode Utils.NumberHolder | NumberHolder} containing a type effectiveness multiplier + * @returns `true` if this Ice-type immunity applies; `false` otherwise */ apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { + const multiplier = args[0] as Utils.NumberHolder; if (target.isOfType(Type.ICE)) { - (args[0] as Utils.BooleanHolder).value = false; - return false; + multiplier.value = 0; + return true; } - return true; + return false; } } From cfb92b4e0874d1f6344578d5abb689e78b9c8fbf Mon Sep 17 00:00:00 2001 From: Mumble <171087428+frutescens@users.noreply.github.com> Date: Fri, 11 Oct 2024 14:44:16 -0700 Subject: [PATCH 19/37] [Move] Telekinesis + [Bug] Ingrain (#4506) * some early set up * localization * Added Wiglett family to restrictions * Added Smack Down + 1000 Arrows Interactions * Added checks for certain tags * Gravity removes telekinesis from all pokemon on the field * need to check something else real quick * mmmmmm * think this is fine? * ingrain fixes * more ingrain * Telekinesis Test + Move Fix * Test Name change * another day another try... * Test Cleanup * fsfdsfds * Revert "fsfdsfds" This reverts commit cb7abcfd9f69342ae7b1864e2e4e124029f9f67e. * whoops * Apply suggestions from code review Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Missed one * Update src/data/move.ts Co-authored-by: PigeonBar <56974298+PigeonBar@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: innerthunder <168692175+innerthunder@users.noreply.github.com> * Add separate battler tags in move attr * Update src/data/battler-tags.ts Co-authored-by: innerthunder <168692175+innerthunder@users.noreply.github.com> * removed onRemove * Documentation * Update src/data/battler-tags.ts --------- Co-authored-by: frutescens Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> Co-authored-by: PigeonBar <56974298+PigeonBar@users.noreply.github.com> Co-authored-by: innerthunder <168692175+innerthunder@users.noreply.github.com> --- src/data/arena-tag.ts | 3 +- src/data/battler-tags.ts | 39 ++++++-- src/data/move.ts | 20 ++-- src/enums/battler-tag-type.ts | 3 +- src/field/pokemon.ts | 2 +- src/phases/move-effect-phase.ts | 6 +- src/test/moves/telekinesis.test.ts | 124 +++++++++++++++++++++++++ src/test/moves/thousand_arrows.test.ts | 4 +- 8 files changed, 182 insertions(+), 19 deletions(-) create mode 100644 src/test/moves/telekinesis.test.ts diff --git a/src/data/arena-tag.ts b/src/data/arena-tag.ts index 45d64249296..11d28ab7e25 100644 --- a/src/data/arena-tag.ts +++ b/src/data/arena-tag.ts @@ -885,7 +885,8 @@ export class GravityTag extends ArenaTag { arena.scene.queueMessage(i18next.t("arenaTag:gravityOnAdd")); arena.scene.getField(true).forEach((pokemon) => { if (pokemon !== null) { - pokemon.removeTag(BattlerTagType.MAGNET_RISEN); + pokemon.removeTag(BattlerTagType.FLOATING); + pokemon.removeTag(BattlerTagType.TELEKINESIS); } }); } diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 3cc109df264..18f03ada941 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -1713,7 +1713,12 @@ export class TypeImmuneTag extends BattlerTag { } } -export class MagnetRisenTag extends TypeImmuneTag { +/** + * Battler Tag that lifts the affected Pokemon into the air and provides immunity to Ground type moves. + * @see {@link https://bulbapedia.bulbagarden.net/wiki/Magnet_Rise_(move) | Moves.MAGNET_RISE} + * @see {@link https://bulbapedia.bulbagarden.net/wiki/Telekinesis_(move) | Moves.TELEKINESIS} + */ +export class FloatingTag extends TypeImmuneTag { constructor(tagType: BattlerTagType, sourceMove: Moves) { super(tagType, sourceMove, Type.GROUND, 5); } @@ -1721,13 +1726,17 @@ export class MagnetRisenTag extends TypeImmuneTag { onAdd(pokemon: Pokemon): void { super.onAdd(pokemon); - pokemon.scene.queueMessage(i18next.t("battlerTags:magnetRisenOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); + if (this.sourceMove === Moves.MAGNET_RISE) { + pokemon.scene.queueMessage(i18next.t("battlerTags:magnetRisenOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); + } + } onRemove(pokemon: Pokemon): void { super.onRemove(pokemon); - - pokemon.scene.queueMessage(i18next.t("battlerTags:magnetRisenOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); + if (this.sourceMove === Moves.MAGNET_RISE) { + pokemon.scene.queueMessage(i18next.t("battlerTags:magnetRisenOnRemove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); + } } } @@ -2676,6 +2685,22 @@ export class SyrupBombTag extends BattlerTag { } } +/** + * Telekinesis raises the target into the air for three turns and causes all moves used against the target (aside from OHKO moves) to hit the target unless the target is in a semi-invulnerable state from Fly/Dig. + * The first effect is provided by {@linkcode FloatingTag}, the accuracy-bypass effect is provided by TelekinesisTag + * The effects of Telekinesis can be baton passed to a teammate. Unlike the mainline games, Telekinesis can be baton-passed to Mega Gengar. + * @see {@link https://bulbapedia.bulbagarden.net/wiki/Telekinesis_(move) | Moves.TELEKINESIS} + */ +export class TelekinesisTag extends BattlerTag { + constructor(sourceMove: Moves) { + super(BattlerTagType.TELEKINESIS, [ BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE ], 3, sourceMove, undefined, true); + } + + override onAdd(pokemon: Pokemon) { + pokemon.scene.queueMessage(i18next.t("battlerTags:telekinesisOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); + } +} + /** * Retrieves a {@linkcode BattlerTag} based on the provided tag type, turn count, source move, and source ID. * @param sourceId - The ID of the pokemon adding the tag @@ -2802,8 +2827,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source return new CursedTag(sourceId); case BattlerTagType.CHARGED: return new TypeBoostTag(tagType, sourceMove, Type.ELECTRIC, 2, true); - case BattlerTagType.MAGNET_RISEN: - return new MagnetRisenTag(tagType, sourceMove); + case BattlerTagType.FLOATING: + return new FloatingTag(tagType, sourceMove); case BattlerTagType.MINIMIZED: return new MinimizeTag(); case BattlerTagType.DESTINY_BOND: @@ -2849,6 +2874,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source return new ImprisonTag(sourceId); case BattlerTagType.SYRUP_BOMB: return new SyrupBombTag(sourceId); + case BattlerTagType.TELEKINESIS: + return new TelekinesisTag(sourceMove); case BattlerTagType.NONE: default: return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId); diff --git a/src/data/move.ts b/src/data/move.ts index 5aa6b2623c0..bd3706545f9 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -7843,7 +7843,9 @@ export function initMoves() { .attr(RandomMovesetMoveAttr, true) .ignoresVirtual(), new SelfStatusMove(Moves.INGRAIN, Type.GRASS, -1, 20, -1, 0, 3) - .attr(AddBattlerTagAttr, BattlerTagType.INGRAIN, true, true), + .attr(AddBattlerTagAttr, BattlerTagType.INGRAIN, true, true) + .attr(AddBattlerTagAttr, BattlerTagType.IGNORE_FLYING, true, true) + .attr(RemoveBattlerTagAttr, [ BattlerTagType.FLOATING ], true), new AttackMove(Moves.SUPERPOWER, Type.FIGHTING, MoveCategory.PHYSICAL, 120, 100, 5, -1, 0, 3) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF ], -1, true), new SelfStatusMove(Moves.MAGIC_COAT, Type.PSYCHIC, -1, 15, -1, 4, 3) @@ -8177,8 +8179,8 @@ export function initMoves() { new SelfStatusMove(Moves.AQUA_RING, Type.WATER, -1, 20, -1, 0, 4) .attr(AddBattlerTagAttr, BattlerTagType.AQUA_RING, true, true), new SelfStatusMove(Moves.MAGNET_RISE, Type.ELECTRIC, -1, 10, -1, 0, 4) - .attr(AddBattlerTagAttr, BattlerTagType.MAGNET_RISEN, true, true) - .condition((user, target, move) => !user.scene.arena.getTag(ArenaTagType.GRAVITY) && [ BattlerTagType.MAGNET_RISEN, BattlerTagType.IGNORE_FLYING, BattlerTagType.INGRAIN ].every((tag) => !user.getTag(tag))), + .attr(AddBattlerTagAttr, BattlerTagType.FLOATING, true, true) + .condition((user, target, move) => !user.scene.arena.getTag(ArenaTagType.GRAVITY) && [ BattlerTagType.FLOATING, BattlerTagType.IGNORE_FLYING, BattlerTagType.INGRAIN ].every((tag) => !user.getTag(tag))), new AttackMove(Moves.FLARE_BLITZ, Type.FIRE, MoveCategory.PHYSICAL, 120, 100, 15, 10, 0, 4) .attr(RecoilAttr, false, 0.33) .attr(HealStatusEffectAttr, true, StatusEffect.FREEZE) @@ -8403,7 +8405,11 @@ export function initMoves() { .attr(AddBattlerTagAttr, BattlerTagType.CENTER_OF_ATTENTION, true), new StatusMove(Moves.TELEKINESIS, Type.PSYCHIC, -1, 15, -1, 0, 5) .condition(failOnGravityCondition) - .unimplemented(), + .condition((_user, target, _move) => ![ Species.DIGLETT, Species.DUGTRIO, Species.ALOLA_DIGLETT, Species.ALOLA_DUGTRIO, Species.SANDYGAST, Species.PALOSSAND, Species.WIGLETT, Species.WUGTRIO ].includes(target.species.speciesId)) + .condition((_user, target, _move) => !(target.species.speciesId === Species.GENGAR && target.getFormKey() === "mega")) + .condition((_user, target, _move) => Utils.isNullOrUndefined(target.getTag(BattlerTagType.INGRAIN)) && Utils.isNullOrUndefined(target.getTag(BattlerTagType.IGNORE_FLYING))) + .attr(AddBattlerTagAttr, BattlerTagType.TELEKINESIS, false, true, 3) + .attr(AddBattlerTagAttr, BattlerTagType.FLOATING, false, true, 3), new StatusMove(Moves.MAGIC_ROOM, Type.PSYCHIC, -1, 10, -1, 0, 5) .ignoresProtect() .target(MoveTarget.BOTH_SIDES) @@ -8411,7 +8417,7 @@ export function initMoves() { new AttackMove(Moves.SMACK_DOWN, Type.ROCK, MoveCategory.PHYSICAL, 50, 100, 15, 100, 0, 5) .attr(AddBattlerTagAttr, BattlerTagType.IGNORE_FLYING, false, false, 1, 1, true) .attr(AddBattlerTagAttr, BattlerTagType.INTERRUPTED) - .attr(RemoveBattlerTagAttr, [ BattlerTagType.FLYING, BattlerTagType.MAGNET_RISEN ]) + .attr(RemoveBattlerTagAttr, [ BattlerTagType.FLYING, BattlerTagType.FLOATING, BattlerTagType.TELEKINESIS ]) .attr(HitsTagAttr, BattlerTagType.FLYING) .makesContact(false), new AttackMove(Moves.STORM_THROW, Type.FIGHTING, MoveCategory.PHYSICAL, 60, 100, 10, -1, 0, 5) @@ -8844,9 +8850,9 @@ export function initMoves() { .attr(NeutralDamageAgainstFlyingTypeMultiplierAttr) .attr(AddBattlerTagAttr, BattlerTagType.IGNORE_FLYING, false, false, 1, 1, true) .attr(HitsTagAttr, BattlerTagType.FLYING) - .attr(HitsTagAttr, BattlerTagType.MAGNET_RISEN) + .attr(HitsTagAttr, BattlerTagType.FLOATING) .attr(AddBattlerTagAttr, BattlerTagType.INTERRUPTED) - .attr(RemoveBattlerTagAttr, [ BattlerTagType.FLYING, BattlerTagType.MAGNET_RISEN ]) + .attr(RemoveBattlerTagAttr, [ BattlerTagType.FLYING, BattlerTagType.FLOATING, BattlerTagType.TELEKINESIS ]) .makesContact(false) .target(MoveTarget.ALL_NEAR_ENEMIES), new AttackMove(Moves.THOUSAND_WAVES, Type.GROUND, MoveCategory.PHYSICAL, 90, 100, 10, -1, 0, 6) diff --git a/src/enums/battler-tag-type.ts b/src/enums/battler-tag-type.ts index 43c849a78e0..2efae9ad359 100644 --- a/src/enums/battler-tag-type.ts +++ b/src/enums/battler-tag-type.ts @@ -54,7 +54,7 @@ export enum BattlerTagType { CURSED = "CURSED", CHARGED = "CHARGED", ROOSTED = "ROOSTED", - MAGNET_RISEN = "MAGNET_RISEN", + FLOATING = "FLOATING", MINIMIZED = "MINIMIZED", DESTINY_BOND = "DESTINY_BOND", CENTER_OF_ATTENTION = "CENTER_OF_ATTENTION", @@ -86,4 +86,5 @@ export enum BattlerTagType { IMPRISON = "IMPRISON", SYRUP_BOMB = "SYRUP_BOMB", ELECTRIFIED = "ELECTRIFIED", + TELEKINESIS = "TELEKINESIS" } diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index d8fcc281d1b..c495e0833cd 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -1488,7 +1488,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } isGrounded(): boolean { - return !!this.getTag(GroundedTag) || (!this.isOfType(Type.FLYING, true, true) && !this.hasAbility(Abilities.LEVITATE) && !this.getTag(BattlerTagType.MAGNET_RISEN) && !this.getTag(SemiInvulnerableTag)); + return !!this.getTag(GroundedTag) || (!this.isOfType(Type.FLYING, true, true) && !this.hasAbility(Abilities.LEVITATE) && !this.getTag(BattlerTagType.FLOATING) && !this.getTag(SemiInvulnerableTag)); } /** diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index b2d429a4313..581cd5ff017 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -4,7 +4,7 @@ import { applyPreAttackAbAttrs, AddSecondStrikeAbAttr, IgnoreMoveEffectsAbAttr, import { ArenaTagSide, ConditionalProtectTag } from "#app/data/arena-tag"; import { MoveAnim } from "#app/data/battle-anims"; import { BattlerTagLapseType, DamageProtectedTag, ProtectedTag, SemiInvulnerableTag, SubstituteTag } from "#app/data/battler-tags"; -import { MoveTarget, applyMoveAttrs, OverrideMoveEffectAttr, MultiHitAttr, AttackMove, FixedDamageAttr, VariableTargetAttr, MissEffectAttr, MoveFlags, applyFilteredMoveAttrs, MoveAttr, MoveEffectAttr, MoveEffectTrigger, ChargeAttr, MoveCategory, NoEffectAttr, HitsTagAttr, ToxicAccuracyAttr } from "#app/data/move"; +import { MoveTarget, applyMoveAttrs, OverrideMoveEffectAttr, MultiHitAttr, AttackMove, FixedDamageAttr, VariableTargetAttr, MissEffectAttr, MoveFlags, applyFilteredMoveAttrs, MoveAttr, MoveEffectAttr, OneHitKOAttr, MoveEffectTrigger, ChargeAttr, MoveCategory, NoEffectAttr, HitsTagAttr, ToxicAccuracyAttr } from "#app/data/move"; import { SpeciesFormChangePostMoveTrigger } from "#app/data/pokemon-forms"; import { BattlerTagType } from "#app/enums/battler-tag-type"; import { Moves } from "#app/enums/moves"; @@ -404,6 +404,10 @@ export class MoveEffectPhase extends PokemonPhase { return true; } + if (target.getTag(BattlerTagType.TELEKINESIS) && !target.getTag(SemiInvulnerableTag) && !this.move.getMove().hasAttr(OneHitKOAttr)) { + return true; + } + const semiInvulnerableTag = target.getTag(SemiInvulnerableTag); if (semiInvulnerableTag && !this.move.getMove().getAttrs(HitsTagAttr).some(hta => hta.tagType === semiInvulnerableTag.tagType) diff --git a/src/test/moves/telekinesis.test.ts b/src/test/moves/telekinesis.test.ts new file mode 100644 index 00000000000..76c0d001f00 --- /dev/null +++ b/src/test/moves/telekinesis.test.ts @@ -0,0 +1,124 @@ +import { BattlerTagType } from "#enums/battler-tag-type"; +import { allMoves } from "#app/data/move"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { MoveResult } from "#app/field/pokemon"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, it, expect, vi } from "vitest"; + +describe("Moves - Telekinesis", () => { + 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.TELEKINESIS, Moves.TACKLE, Moves.MUD_SHOT, Moves.SMACK_DOWN ]) + .battleType("single") + .enemySpecies(Species.SNORLAX) + .enemyLevel(60) + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset([ Moves.SPLASH ]); + }); + + it("Telekinesis makes the affected vulnerable to most attacking moves regardless of accuracy", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const enemyOpponent = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.TELEKINESIS); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyOpponent.getTag(BattlerTagType.TELEKINESIS)).toBeDefined(); + expect(enemyOpponent.getTag(BattlerTagType.FLOATING)).toBeDefined(); + + await game.toNextTurn(); + vi.spyOn(allMoves[Moves.TACKLE], "accuracy", "get").mockReturnValue(0); + game.move.select(Moves.TACKLE); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyOpponent.isFullHp()).toBe(false); + }); + + it("Telekinesis makes the affected airborne and immune to most Ground-moves", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const enemyOpponent = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.TELEKINESIS); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyOpponent.getTag(BattlerTagType.TELEKINESIS)).toBeDefined(); + expect(enemyOpponent.getTag(BattlerTagType.FLOATING)).toBeDefined(); + + await game.toNextTurn(); + vi.spyOn(allMoves[Moves.MUD_SHOT], "accuracy", "get").mockReturnValue(100); + game.move.select(Moves.MUD_SHOT); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyOpponent.isFullHp()).toBe(true); + }); + + it("Telekinesis can still affect Pokemon that have been transformed into invalid Pokemon", async () => { + game.override.enemyMoveset(Moves.TRANSFORM); + await game.classicMode.startBattle([ Species.DIGLETT ]); + + const enemyOpponent = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.TELEKINESIS); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyOpponent.getTag(BattlerTagType.TELEKINESIS)).toBeDefined(); + expect(enemyOpponent.getTag(BattlerTagType.FLOATING)).toBeDefined(); + expect(enemyOpponent.summonData.speciesForm?.speciesId).toBe(Species.DIGLETT); + }); + + it("Moves like Smack Down and 1000 Arrows remove all effects of Telekinesis from the target Pokemon", async () => { + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const enemyOpponent = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.TELEKINESIS); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyOpponent.getTag(BattlerTagType.TELEKINESIS)).toBeDefined(); + expect(enemyOpponent.getTag(BattlerTagType.FLOATING)).toBeDefined(); + + await game.toNextTurn(); + game.move.select(Moves.SMACK_DOWN); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyOpponent.getTag(BattlerTagType.TELEKINESIS)).toBeUndefined(); + expect(enemyOpponent.getTag(BattlerTagType.FLOATING)).toBeUndefined(); + }); + + it("Ingrain will remove the floating effect of Telekinesis, but not the 100% hit", async () => { + game.override.enemyMoveset([ Moves.SPLASH, Moves.INGRAIN ]); + await game.classicMode.startBattle([ Species.MAGIKARP ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + const enemyOpponent = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.TELEKINESIS); + await game.forceEnemyMove(Moves.SPLASH); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyOpponent.getTag(BattlerTagType.TELEKINESIS)).toBeDefined(); + expect(enemyOpponent.getTag(BattlerTagType.FLOATING)).toBeDefined(); + + await game.toNextTurn(); + vi.spyOn(allMoves[Moves.MUD_SHOT], "accuracy", "get").mockReturnValue(0); + game.move.select(Moves.MUD_SHOT); + await game.forceEnemyMove(Moves.INGRAIN); + await game.phaseInterceptor.to("TurnEndPhase"); + expect(enemyOpponent.getTag(BattlerTagType.TELEKINESIS)).toBeDefined(); + expect(enemyOpponent.getTag(BattlerTagType.INGRAIN)).toBeDefined(); + expect(enemyOpponent.getTag(BattlerTagType.IGNORE_FLYING)).toBeDefined(); + expect(enemyOpponent.getTag(BattlerTagType.FLOATING)).toBeUndefined(); + expect(playerPokemon.getLastXMoves()[0].result).toBe(MoveResult.SUCCESS); + }); +}); diff --git a/src/test/moves/thousand_arrows.test.ts b/src/test/moves/thousand_arrows.test.ts index 112be476955..976b4352ee4 100644 --- a/src/test/moves/thousand_arrows.test.ts +++ b/src/test/moves/thousand_arrows.test.ts @@ -85,13 +85,13 @@ describe("Moves - Thousand Arrows", () => { const enemyPokemon = game.scene.getEnemyPokemon()!; - enemyPokemon.addTag(BattlerTagType.MAGNET_RISEN, undefined, Moves.MAGNET_RISE); + enemyPokemon.addTag(BattlerTagType.FLOATING, undefined, Moves.MAGNET_RISE); game.move.select(Moves.THOUSAND_ARROWS); await game.phaseInterceptor.to(BerryPhase, false); - expect(enemyPokemon.getTag(BattlerTagType.MAGNET_RISEN)).toBeUndefined(); + expect(enemyPokemon.getTag(BattlerTagType.FLOATING)).toBeUndefined(); expect(enemyPokemon.getTag(BattlerTagType.IGNORE_FLYING)).toBeDefined(); expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); } From b7eb95b7614d0df1674f4bd9e000c0e1cd80b04e Mon Sep 17 00:00:00 2001 From: PigeonBar <56974298+PigeonBar@users.noreply.github.com> Date: Sat, 12 Oct 2024 11:22:26 -0400 Subject: [PATCH 20/37] [Test] Fix several flaky tests (#4639) --- src/test/moves/safeguard.test.ts | 2 +- .../an-offer-you-cant-refuse-encounter.test.ts | 11 +++++++---- .../encounters/berries-abound-encounter.test.ts | 12 ++++++++---- .../the-pokemon-salesman-encounter.test.ts | 4 ++-- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/test/moves/safeguard.test.ts b/src/test/moves/safeguard.test.ts index c180ff338a5..6505162fd04 100644 --- a/src/test/moves/safeguard.test.ts +++ b/src/test/moves/safeguard.test.ts @@ -33,7 +33,7 @@ describe("Moves - Safeguard", () => { .enemyLevel(5) .starterSpecies(Species.DRATINI) .moveset([ Moves.NUZZLE, Moves.SPORE, Moves.YAWN, Moves.SPLASH ]) - .ability(Abilities.BALL_FETCH); + .ability(Abilities.UNNERVE); // Stop wild Pokemon from potentially eating Lum Berry }); it("protects from damaging moves with additional effects", async () => { diff --git a/src/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts b/src/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts index 9883b4332b9..0585b4ce72b 100644 --- a/src/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/an-offer-you-cant-refuse-encounter.test.ts @@ -18,6 +18,7 @@ import { Moves } from "#enums/moves"; import { ShinyRateBoosterModifier } from "#app/modifier/modifier"; import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; import i18next from "i18next"; +import { Abilities } from "#enums/abilities"; const namespace = "mysteryEncounters/anOfferYouCantRefuse"; /** Gyarados for Indimidate */ @@ -37,10 +38,11 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => { beforeEach(async () => { game = new GameManager(phaserGame); scene = game.scene; - game.override.mysteryEncounterChance(100); - game.override.startingWave(defaultWave); - game.override.startingBiome(defaultBiome); - game.override.disableTrainerWaves(); + game.override.mysteryEncounterChance(100) + .startingWave(defaultWave) + .startingBiome(defaultBiome) + .disableTrainerWaves() + .ability(Abilities.INTIMIDATE); // Extortion ability const biomeMap = new Map([ [ Biome.VOLCANO, [ MysteryEncounterType.MYSTERIOUS_CHALLENGERS ]], @@ -195,6 +197,7 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => { }); it("should award EXP to a pokemon with a move in EXTORTION_MOVES", async () => { + game.override.ability(Abilities.SYNCHRONIZE); // Not an extortion ability, so we can test extortion move await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, [ Species.ABRA ]); const party = scene.getParty(); const abra = party.find((pkm) => pkm.species.speciesId === Species.ABRA)!; diff --git a/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts b/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts index 8e286468bea..bfa3d428bc0 100644 --- a/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/berries-abound-encounter.test.ts @@ -176,10 +176,12 @@ describe("Berries Abound - Mystery Encounter", () => { const encounterTextSpy = vi.spyOn(EncounterDialogueUtils, "showEncounterText"); await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty); + scene.getParty().forEach(pkm => { + vi.spyOn(pkm, "getStat").mockReturnValue(1); // for ease return for every stat + }); + const config = game.scene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]; const speciesToSpawn = config.pokemonConfigs?.[0].species.speciesId; - // Setting enemy's level arbitrarily high to outspeed - config.pokemonConfigs![0].dataSource!.level = 1000; await runMysteryEncounterToEnd(game, 2, undefined, true); @@ -198,10 +200,12 @@ describe("Berries Abound - Mystery Encounter", () => { const encounterTextSpy = vi.spyOn(EncounterDialogueUtils, "showEncounterText"); await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty); + scene.getParty().forEach(pkm => { + vi.spyOn(pkm, "getStat").mockReturnValue(1); // for ease return for every stat + }); + const config = game.scene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]; const speciesToSpawn = config.pokemonConfigs?.[0].species.speciesId; - // Setting enemy's level arbitrarily high to outspeed - config.pokemonConfigs![0].dataSource!.level = 1000; await runMysteryEncounterToEnd(game, 2, undefined, true); diff --git a/src/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts b/src/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts index f8d1ffd3ded..040381c4ac3 100644 --- a/src/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts +++ b/src/test/mystery-encounter/encounters/the-pokemon-salesman-encounter.test.ts @@ -147,8 +147,8 @@ describe("The Pokemon Salesman - Mystery Encounter", () => { expect(scene.getParty().length).toBe(initialPartySize + 1); - const newlyPurchasedPokemon = scene.getParty().find(p => p.name === pokemonName); - expect(newlyPurchasedPokemon).toBeDefined(); + const newlyPurchasedPokemon = scene.getParty()[scene.getParty().length - 1]; + expect(newlyPurchasedPokemon.name).toBe(pokemonName); expect(newlyPurchasedPokemon!.moveset.length > 0).toBeTruthy(); }); From 2ac688de4bf0d4715a1aa394b3c12162073ae0fe Mon Sep 17 00:00:00 2001 From: PigeonBar <56974298+PigeonBar@users.noreply.github.com> Date: Sat, 12 Oct 2024 16:06:26 -0400 Subject: [PATCH 21/37] [Misc] More complete phase logging (#4651) --- src/battle-scene.ts | 6 +++++- src/phase.ts | 1 - 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 40e3971b7fc..850d0baab5d 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -2316,7 +2316,10 @@ export default class BattleScene extends SceneBase { } } - this.currentPhase?.start(); + if (this.currentPhase) { + console.log(`%cStart Phase ${this.currentPhase.constructor.name}`, "color:green;"); + this.currentPhase.start(); + } } overridePhase(phase: Phase): boolean { @@ -2326,6 +2329,7 @@ export default class BattleScene extends SceneBase { this.standbyPhase = this.currentPhase; this.currentPhase = phase; + console.log(`%cStart Phase ${phase.constructor.name}`, "color:green;"); phase.start(); return true; diff --git a/src/phase.ts b/src/phase.ts index 02939757112..5cf91f2c478 100644 --- a/src/phase.ts +++ b/src/phase.ts @@ -8,7 +8,6 @@ export class Phase { } start() { - console.log(`%cStart Phase ${this.constructor.name}`, "color:green;"); if (this.scene.abilityBar.shown) { this.scene.abilityBar.resetAutoHideTimer(); } From ebb76129990751aa3e92784c179a838edaaefd96 Mon Sep 17 00:00:00 2001 From: PrabbyDD <147005742+PrabbyDD@users.noreply.github.com> Date: Sat, 12 Oct 2024 15:29:36 -0700 Subject: [PATCH 22/37] [Bug] Stat Stages are now changed individually instead of all at once (#4457) Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> Co-authored-by: Adrian T. <68144167+torranx@users.noreply.github.com> --- src/phases/stat-stage-change-phase.ts | 10 ++++ src/test/abilities/competitive.test.ts | 72 ++++++++++++++++++++++++++ src/test/abilities/defiant.test.ts | 70 +++++++++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 src/test/abilities/competitive.test.ts create mode 100644 src/test/abilities/defiant.test.ts diff --git a/src/phases/stat-stage-change-phase.ts b/src/phases/stat-stage-change-phase.ts index 4418c38c849..bfe19ea9ca5 100644 --- a/src/phases/stat-stage-change-phase.ts +++ b/src/phases/stat-stage-change-phase.ts @@ -36,6 +36,16 @@ export class StatStageChangePhase extends PokemonPhase { } start() { + + // Check if multiple stats are being changed at the same time, then run SSCPhase for each of them + if (this.stats.length > 1) { + for (let i = 0; i < this.stats.length; i++) { + const stat = [ this.stats[i] ]; + this.scene.unshiftPhase(new StatStageChangePhase(this.scene, this.battlerIndex, this.selfTarget, stat, this.stages, this.showMessage, this.ignoreAbilities, this.canBeCopied, this.onChange)); + } + return this.end(); + } + const pokemon = this.getPokemon(); if (!pokemon.isActive(true)) { diff --git a/src/test/abilities/competitive.test.ts b/src/test/abilities/competitive.test.ts new file mode 100644 index 00000000000..ecb276a1b8d --- /dev/null +++ b/src/test/abilities/competitive.test.ts @@ -0,0 +1,72 @@ +import { Stat } from "#enums/stat"; +import { TurnInitPhase } from "#app/phases/turn-init-phase"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Abilities - Competitive", () => { + 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.battleType("single") + .enemySpecies(Species.BEEDRILL) + .enemyMoveset(Moves.TICKLE) + .startingLevel(1) + .moveset([ Moves.SPLASH, Moves.CLOSE_COMBAT ]) + .ability(Abilities.COMPETITIVE); + }); + + it("lower atk and def by 1 via tickle, then increase spatk by 4 via competitive", async () => { + await game.classicMode.startBattle([ Species.FLYGON ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + game.move.select(Moves.SPLASH); + await game.phaseInterceptor.to(TurnInitPhase); + + expect(playerPokemon.getStatStage(Stat.ATK)).toBe(-1); + expect(playerPokemon.getStatStage(Stat.DEF)).toBe(-1); + expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(4); + }); + + it("lowering your own stats should not trigger competitive", async () => { + game.override.enemyMoveset(Moves.SPLASH); + await game.classicMode.startBattle([ Species.FLYGON ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + game.move.select(Moves.CLOSE_COMBAT); + await game.phaseInterceptor.to(TurnInitPhase); + + expect(playerPokemon.getStatStage(Stat.SPDEF)).toBe(-1); + expect(playerPokemon.getStatStage(Stat.DEF)).toBe(-1); + expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(0); + }); + + it("white herb should remove only the negative effects", async () => { + game.override.startingHeldItems([{ name: "WHITE_HERB" }]); + await game.classicMode.startBattle([ Species.FLYGON ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + game.move.select(Moves.SPLASH); + await game.phaseInterceptor.to(TurnInitPhase); + + expect(playerPokemon.getStatStage(Stat.ATK)).toBe(0); + expect(playerPokemon.getStatStage(Stat.DEF)).toBe(0); + expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(4); + }); +}); diff --git a/src/test/abilities/defiant.test.ts b/src/test/abilities/defiant.test.ts new file mode 100644 index 00000000000..aa8d250dad7 --- /dev/null +++ b/src/test/abilities/defiant.test.ts @@ -0,0 +1,70 @@ +import { Stat } from "#enums/stat"; +import { TurnInitPhase } from "#app/phases/turn-init-phase"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import GameManager from "#test/utils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; + +describe("Abilities - Defiant", () => { + 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.battleType("single") + .enemySpecies(Species.BEEDRILL) + .enemyMoveset(Moves.TICKLE) + .startingLevel(1) + .moveset([ Moves.SPLASH, Moves.CLOSE_COMBAT ]) + .ability(Abilities.DEFIANT); + }); + + it("lower atk and def by 1 via tickle, then increase atk by 4 via defiant", async () => { + await game.classicMode.startBattle([ Species.FLYGON ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + game.move.select(Moves.SPLASH); + await game.phaseInterceptor.to(TurnInitPhase); + + expect(playerPokemon.getStatStage(Stat.ATK)).toBe(3); + expect(playerPokemon.getStatStage(Stat.DEF)).toBe(-1); + }); + + it("lowering your own stats should not trigger defiant", async () => { + game.override.enemyMoveset(Moves.SPLASH); + await game.classicMode.startBattle([ Species.FLYGON ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + game.move.select(Moves.CLOSE_COMBAT); + await game.phaseInterceptor.to(TurnInitPhase); + + expect(playerPokemon.getStatStage(Stat.SPDEF)).toBe(-1); + expect(playerPokemon.getStatStage(Stat.DEF)).toBe(-1); + expect(playerPokemon.getStatStage(Stat.ATK)).toBe(0); + }); + + it("white herb should remove only the negative effects", async () => { + game.override.startingHeldItems([{ name: "WHITE_HERB" }]); + await game.classicMode.startBattle([ Species.FLYGON ]); + + const playerPokemon = game.scene.getPlayerPokemon()!; + game.move.select(Moves.SPLASH); + await game.phaseInterceptor.to(TurnInitPhase); + + expect(playerPokemon.getStatStage(Stat.DEF)).toBe(0); + expect(playerPokemon.getStatStage(Stat.ATK)).toBe(3); + }); +}); From caf29e2ce3fe5bd194a0a42eac9b91f32b65dc89 Mon Sep 17 00:00:00 2001 From: Tempoanon <163687446+Tempo-anon@users.noreply.github.com> Date: Sat, 12 Oct 2024 23:42:20 -0400 Subject: [PATCH 23/37] [Documentation] Document all (P) moves (#4650) * Document all (P) moves * Fix some typos * Fix more typos * Address innerthunder comments * Add circle throw and dragon tail (P) --- src/data/move.ts | 81 +++++++++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 35 deletions(-) diff --git a/src/data/move.ts b/src/data/move.ts index bd3706545f9..8e9977337cc 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -365,6 +365,14 @@ export default class Move implements Localizable { return this; } + /** + * Internal dev flag for documenting edge cases. When using this, please document the known edge case. + * @returns the called object {@linkcode Move} + */ + edgeCase(): this { + return this; + } + /** * Marks the move as "partial": appends texts to the move name * @returns the called object {@linkcode Move} @@ -7084,7 +7092,8 @@ export function initMoves() { .attr(ForceSwitchOutAttr) .ignoresSubstitute() .hidesTarget() - .windMove(), + .windMove() + .partial(), // Should force random switches new AttackMove(Moves.FLY, Type.FLYING, MoveCategory.PHYSICAL, 90, 95, 15, -1, 0, 1) .attr(ChargeAttr, ChargeAnim.FLY_CHARGING, i18next.t("moveTriggers:flewUpHigh", { pokemonName: "{USER}" }), BattlerTagType.FLYING) .condition(failOnGravityCondition) @@ -7161,7 +7170,8 @@ export function initMoves() { new StatusMove(Moves.ROAR, Type.NORMAL, -1, 20, -1, -6, 1) .attr(ForceSwitchOutAttr) .soundBased() - .hidesTarget(), + .hidesTarget() + .partial(), // Should force random switching new StatusMove(Moves.SING, Type.NORMAL, 55, 15, -1, 0, 1) .attr(StatusEffectAttr, StatusEffect.SLEEP) .soundBased(), @@ -7302,7 +7312,7 @@ export function initMoves() { .attr(StatStageChangeAttr, [ Stat.SPD ], 2, true), new AttackMove(Moves.QUICK_ATTACK, Type.NORMAL, MoveCategory.PHYSICAL, 40, 100, 30, -1, 1, 1), new AttackMove(Moves.RAGE, Type.NORMAL, MoveCategory.PHYSICAL, 20, 100, 20, -1, 0, 1) - .partial(), + .partial(), // No effect implemented new SelfStatusMove(Moves.TELEPORT, Type.PSYCHIC, -1, 20, -1, -6, 1) .attr(ForceSwitchOutAttr, true) .hidesUser(), @@ -7617,7 +7627,7 @@ export function initMoves() { new StatusMove(Moves.CHARM, Type.FAIRY, 100, 20, -1, 0, 2) .attr(StatStageChangeAttr, [ Stat.ATK ], -2), new AttackMove(Moves.ROLLOUT, Type.ROCK, MoveCategory.PHYSICAL, 30, 90, 20, -1, 0, 2) - .partial() + .partial() // Does not lock the user, also does not increase damage properly .attr(ConsecutiveUseDoublePowerAttr, 5, true, true, Moves.DEFENSE_CURL), new AttackMove(Moves.FALSE_SWIPE, Type.NORMAL, MoveCategory.PHYSICAL, 40, 100, 40, -1, 0, 2) .attr(SurviveDamageAttr), @@ -7688,7 +7698,7 @@ export function initMoves() { .ignoresSubstitute() .condition((user, target, move) => new EncoreTag(user.id).canAdd(target)), new AttackMove(Moves.PURSUIT, Type.DARK, MoveCategory.PHYSICAL, 40, 100, 20, -1, 0, 2) - .partial(), + .partial(), // No effect implemented new AttackMove(Moves.RAPID_SPIN, Type.NORMAL, MoveCategory.PHYSICAL, 50, 100, 40, 100, 0, 2) .attr(StatStageChangeAttr, [ Stat.SPD ], 1, true) .attr(RemoveBattlerTagAttr, [ @@ -7753,7 +7763,7 @@ export function initMoves() { .attr(StatStageChangeAttr, [ Stat.SPDEF ], -1) .ballBombMove(), new AttackMove(Moves.FUTURE_SIGHT, Type.PSYCHIC, MoveCategory.SPECIAL, 120, 100, 10, -1, 0, 2) - .partial() + .partial() // Complete buggy mess .attr(DelayedAttackAttr, ArenaTagType.FUTURE_SIGHT, ChargeAnim.FUTURE_SIGHT_CHARGING, i18next.t("moveTriggers:foresawAnAttack", { pokemonName: "{USER}" })), new AttackMove(Moves.ROCK_SMASH, Type.FIGHTING, MoveCategory.PHYSICAL, 40, 100, 15, 50, 0, 2) .attr(StatStageChangeAttr, [ Stat.DEF ], -1), @@ -7771,7 +7781,7 @@ export function initMoves() { .ignoresVirtual() .soundBased() .target(MoveTarget.RANDOM_NEAR_ENEMY) - .partial(), + .partial(), // Does not lock the user, does not stop Pokemon from sleeping new SelfStatusMove(Moves.STOCKPILE, Type.NORMAL, -1, 20, -1, 0, 3) .condition(user => (user.getTag(StockpilingTag)?.stockpiledCount ?? 0) < 3) .attr(AddBattlerTagAttr, BattlerTagType.STOCKPILING, true), @@ -7794,7 +7804,7 @@ export function initMoves() { .target(MoveTarget.BOTH_SIDES), new StatusMove(Moves.TORMENT, Type.DARK, 100, 15, -1, 0, 3) .ignoresSubstitute() - .partial() // Incomplete implementation because of Uproar's partial implementation + .edgeCase() // Incomplete implementation because of Uproar's partial implementation .attr(AddBattlerTagAttr, BattlerTagType.TORMENT, false, true, 1), new StatusMove(Moves.FLATTER, Type.DARK, 100, 15, -1, 0, 3) .attr(StatStageChangeAttr, [ Stat.SPATK ], 1) @@ -7883,7 +7893,7 @@ export function initMoves() { .unimplemented(), new AttackMove(Moves.SECRET_POWER, Type.NORMAL, MoveCategory.PHYSICAL, 70, 100, 20, 30, 0, 3) .makesContact(false) - .partial(), + .partial(), // No effect implemented new AttackMove(Moves.DIVE, Type.WATER, MoveCategory.PHYSICAL, 80, 100, 10, -1, 0, 3) .attr(ChargeAttr, ChargeAnim.DIVE_CHARGING, i18next.t("moveTriggers:hidUnderwater", { pokemonName: "{USER}" }), BattlerTagType.UNDERWATER, true) .attr(GulpMissileTagAttr) @@ -7914,7 +7924,7 @@ export function initMoves() { .attr(AddArenaTagAttr, ArenaTagType.MUD_SPORT, 5) .target(MoveTarget.BOTH_SIDES), new AttackMove(Moves.ICE_BALL, Type.ICE, MoveCategory.PHYSICAL, 30, 90, 20, -1, 0, 3) - .partial() + .partial() // Does not lock the user properly, does not increase damage correctly .attr(ConsecutiveUseDoublePowerAttr, 5, true, true, Moves.DEFENSE_CURL) .ballBombMove(), new AttackMove(Moves.NEEDLE_ARM, Type.GRASS, MoveCategory.PHYSICAL, 60, 100, 15, 30, 0, 3) @@ -8057,7 +8067,7 @@ export function initMoves() { .attr(ConfuseAttr) .pulseMove(), new AttackMove(Moves.DOOM_DESIRE, Type.STEEL, MoveCategory.SPECIAL, 140, 100, 5, -1, 0, 3) - .partial() + .partial() // Complete buggy mess .attr(DelayedAttackAttr, ArenaTagType.DOOM_DESIRE, ChargeAnim.DOOM_DESIRE_CHARGING, i18next.t("moveTriggers:choseDoomDesireAsDestiny", { pokemonName: "{USER}" })), new AttackMove(Moves.PSYCHO_BOOST, Type.PSYCHIC, MoveCategory.SPECIAL, 140, 90, 5, -1, 0, 3) .attr(StatStageChangeAttr, [ Stat.SPATK ], -2, true), @@ -8467,7 +8477,7 @@ export function initMoves() { .attr(AfterYouAttr), new AttackMove(Moves.ROUND, Type.NORMAL, MoveCategory.SPECIAL, 60, 100, 15, -1, 0, 5) .soundBased() - .partial(), + .partial(), // No effect implemented new AttackMove(Moves.ECHOED_VOICE, Type.NORMAL, MoveCategory.SPECIAL, 40, 100, 15, -1, 0, 5) .attr(ConsecutiveUseMultiBasePowerAttr, 5, false) .soundBased(), @@ -8509,7 +8519,8 @@ export function initMoves() { .attr(StatStageChangeAttr, [ Stat.ATK ], 1, true) .attr(StatStageChangeAttr, [ Stat.SPD ], 2, true), new AttackMove(Moves.CIRCLE_THROW, Type.FIGHTING, MoveCategory.PHYSICAL, 60, 90, 10, -1, -6, 5) - .attr(ForceSwitchOutAttr), + .attr(ForceSwitchOutAttr) + .partial(), // Should force random switches new AttackMove(Moves.INCINERATE, Type.FIRE, MoveCategory.SPECIAL, 60, 100, 15, -1, 0, 5) .target(MoveTarget.ALL_NEAR_ENEMIES) .attr(RemoveHeldItemAttr, true), @@ -8577,7 +8588,8 @@ export function initMoves() { .attr(CritOnlyAttr), new AttackMove(Moves.DRAGON_TAIL, Type.DRAGON, MoveCategory.PHYSICAL, 60, 90, 10, -1, -6, 5) .attr(ForceSwitchOutAttr) - .hidesTarget(), + .hidesTarget() + .partial(), // Should force random switches new SelfStatusMove(Moves.WORK_UP, Type.NORMAL, -1, 30, -1, 0, 5) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], 1, true), new AttackMove(Moves.ELECTROWEB, Type.ELECTRIC, MoveCategory.SPECIAL, 55, 95, 15, 100, 0, 5) @@ -8705,7 +8717,7 @@ export function initMoves() { .ignoresVirtual(), new StatusMove(Moves.TRICK_OR_TREAT, Type.GHOST, 100, 20, -1, 0, 6) .attr(AddTypeAttr, Type.GHOST) - .partial(), + .edgeCase(), // Weird interaction with Forest's Curse, reflect type, burn up new StatusMove(Moves.NOBLE_ROAR, Type.NORMAL, 100, 30, -1, 0, 6) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1) .soundBased(), @@ -8718,7 +8730,7 @@ export function initMoves() { .triageMove(), new StatusMove(Moves.FORESTS_CURSE, Type.GRASS, 100, 20, -1, 0, 6) .attr(AddTypeAttr, Type.GRASS) - .partial(), + .edgeCase(), // Weird interaction with Trick or Treat, reflect type, burn up new AttackMove(Moves.PETAL_BLIZZARD, Type.GRASS, MoveCategory.PHYSICAL, 90, 100, 15, -1, 0, 6) .windMove() .makesContact(false) @@ -8726,7 +8738,7 @@ export function initMoves() { new AttackMove(Moves.FREEZE_DRY, Type.ICE, MoveCategory.SPECIAL, 70, 100, 20, 10, 0, 6) .attr(StatusEffectAttr, StatusEffect.FREEZE) .attr(WaterSuperEffectTypeMultiplierAttr) - .partial(), // This currently just multiplies the move's power instead of changing its effectiveness. It also doesn't account for abilities that modify type effectiveness such as tera shell. + .edgeCase(), // This currently just multiplies the move's power instead of changing its effectiveness. It also doesn't account for abilities that modify type effectiveness such as tera shell. new AttackMove(Moves.DISARMING_VOICE, Type.FAIRY, MoveCategory.SPECIAL, 40, -1, 15, -1, 0, 6) .soundBased() .target(MoveTarget.ALL_NEAR_ENEMIES), @@ -9104,15 +9116,15 @@ export function initMoves() { /* Unused */ new AttackMove(Moves.SINISTER_ARROW_RAID, Type.GHOST, MoveCategory.PHYSICAL, 180, -1, 1, -1, 0, 7) .makesContact(false) - .partial() + .edgeCase() // I assume it's because the user needs spirit shackle and decidueye .ignoresVirtual(), new AttackMove(Moves.MALICIOUS_MOONSAULT, Type.DARK, MoveCategory.PHYSICAL, 180, -1, 1, -1, 0, 7) .attr(AlwaysHitMinimizeAttr) .attr(HitsTagAttr, BattlerTagType.MINIMIZED, true) - .partial() + .edgeCase() // I assume it's because it needs darkest lariat and incineroar .ignoresVirtual(), new AttackMove(Moves.OCEANIC_OPERETTA, Type.WATER, MoveCategory.SPECIAL, 195, -1, 1, -1, 0, 7) - .partial() + .edgeCase() // I assume it's because it needs sparkling aria and primarina .ignoresVirtual(), new AttackMove(Moves.GUARDIAN_OF_ALOLA, Type.FAIRY, MoveCategory.SPECIAL, -1, -1, 1, -1, 0, 7) .unimplemented() @@ -9121,10 +9133,10 @@ export function initMoves() { .unimplemented() .ignoresVirtual(), new AttackMove(Moves.STOKED_SPARKSURFER, Type.ELECTRIC, MoveCategory.SPECIAL, 175, -1, 1, 100, 0, 7) - .partial() + .edgeCase() // I assume it's because it needs thunderbolt and Alola Raichu .ignoresVirtual(), new AttackMove(Moves.PULVERIZING_PANCAKE, Type.NORMAL, MoveCategory.PHYSICAL, 210, -1, 1, -1, 0, 7) - .partial() + .edgeCase() // I assume it's because it needs giga impact and snorlax .ignoresVirtual(), new SelfStatusMove(Moves.EXTREME_EVOBOOST, Type.NORMAL, -1, 1, -1, 0, 7) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ], 2, true) @@ -9155,13 +9167,13 @@ export function initMoves() { .attr(RechargeAttr), new AttackMove(Moves.SPECTRAL_THIEF, Type.GHOST, MoveCategory.PHYSICAL, 90, 100, 10, -1, 0, 7) .ignoresSubstitute() - .partial(), + .partial(), // Does not steal stats new AttackMove(Moves.SUNSTEEL_STRIKE, Type.STEEL, MoveCategory.PHYSICAL, 100, 100, 5, -1, 0, 7) .ignoresAbilities() - .partial(), + .edgeCase(), // Should not ignore abilities when called virtually (metronome) new AttackMove(Moves.MOONGEIST_BEAM, Type.GHOST, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 7) .ignoresAbilities() - .partial(), + .edgeCase(), // Should not ignore abilities when called virtually (metronome) new StatusMove(Moves.TEARFUL_LOOK, Type.NORMAL, -1, 20, -1, 0, 7) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1), new AttackMove(Moves.ZING_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 80, 100, 10, 30, 0, 7) @@ -9172,7 +9184,7 @@ export function initMoves() { .attr(FormChangeItemTypeAttr), /* Unused */ new AttackMove(Moves.TEN_MILLION_VOLT_THUNDERBOLT, Type.ELECTRIC, MoveCategory.SPECIAL, 195, -1, 1, -1, 0, 7) - .partial() + .edgeCase() // I assume it's because it needs thunderbolt and pikachu in a cap .ignoresVirtual(), /* End Unused */ new AttackMove(Moves.MIND_BLOWN, Type.FIRE, MoveCategory.SPECIAL, 150, 100, 5, -1, 0, 7) @@ -9185,7 +9197,7 @@ export function initMoves() { new AttackMove(Moves.PHOTON_GEYSER, Type.PSYCHIC, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 7) .attr(PhotonGeyserCategoryAttr) .ignoresAbilities() - .partial(), + .edgeCase(), // Should not ignore abilities when called virtually (metronome) /* Unused */ new AttackMove(Moves.LIGHT_THAT_BURNS_THE_SKY, Type.PSYCHIC, MoveCategory.SPECIAL, 200, -1, 1, -1, 0, 7) .attr(PhotonGeyserCategoryAttr) @@ -9198,7 +9210,7 @@ export function initMoves() { .ignoresAbilities() .ignoresVirtual(), new AttackMove(Moves.LETS_SNUGGLE_FOREVER, Type.FAIRY, MoveCategory.PHYSICAL, 190, -1, 1, -1, 0, 7) - .partial() + .edgeCase() // I assume it needs play rough and mimikyu .ignoresVirtual(), new AttackMove(Moves.SPLINTERED_STORMSHARDS, Type.ROCK, MoveCategory.PHYSICAL, 190, -1, 1, -1, 0, 7) .attr(ClearTerrainAttr) @@ -9208,7 +9220,7 @@ export function initMoves() { .attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ], 1, true, undefined, undefined, undefined, undefined, true) .soundBased() .target(MoveTarget.ALL_NEAR_ENEMIES) - .partial() + .edgeCase() // I assume it needs clanging scales and Kommo-O .ignoresVirtual(), /* End Unused */ new AttackMove(Moves.ZIPPY_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 50, 100, 15, -1, 2, 7) //LGPE Implementation @@ -9271,14 +9283,14 @@ export function initMoves() { new AttackMove(Moves.JAW_LOCK, Type.DARK, MoveCategory.PHYSICAL, 80, 100, 10, -1, 0, 8) .attr(JawLockAttr) .bitingMove(), - new SelfStatusMove(Moves.STUFF_CHEEKS, Type.NORMAL, -1, 10, -1, 0, 8) // TODO: Stuff Cheeks should not be selectable when the user does not have a berry, see wiki + new SelfStatusMove(Moves.STUFF_CHEEKS, Type.NORMAL, -1, 10, -1, 0, 8) .attr(EatBerryAttr) .attr(StatStageChangeAttr, [ Stat.DEF ], 2, true) .condition((user) => { const userBerries = user.scene.findModifiers(m => m instanceof BerryModifier, user.isPlayer()); return userBerries.length > 0; }) - .partial(), + .edgeCase(), // Stuff Cheeks should not be selectable when the user does not have a berry, see wiki new SelfStatusMove(Moves.NO_RETREAT, Type.FIGHTING, -1, 5, -1, 0, 8) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ], 1, true) .attr(AddBattlerTagAttr, BattlerTagType.NO_RETREAT, true, false) @@ -9292,7 +9304,7 @@ export function initMoves() { new AttackMove(Moves.DRAGON_DARTS, Type.DRAGON, MoveCategory.PHYSICAL, 50, 100, 10, -1, 0, 8) .attr(MultiHitAttr, MultiHitType._2) .makesContact(false) - .partial(), + .partial(), // smart targetting is unimplemented new StatusMove(Moves.TEATIME, Type.NORMAL, -1, 10, -1, 0, 8) .attr(EatBerryAttr) .target(MoveTarget.ALL), @@ -9731,7 +9743,7 @@ export function initMoves() { .attr(StatStageChangeAttr, [ Stat.SPDEF ], -2), new AttackMove(Moves.ORDER_UP, Type.DRAGON, MoveCategory.PHYSICAL, 80, 100, 10, 100, 0, 9) .makesContact(false) - .partial(), + .partial(), // No effect implemented (requires Commander) new AttackMove(Moves.JET_PUNCH, Type.WATER, MoveCategory.PHYSICAL, 60, 100, 15, -1, 1, 9) .punchingMove(), new StatusMove(Moves.SPICY_EXTRACT, Type.GRASS, -1, 15, -1, 0, 9) @@ -9943,8 +9955,7 @@ export function initMoves() { new AttackMove(Moves.UPPER_HAND, Type.FIGHTING, MoveCategory.PHYSICAL, 65, 100, 15, 100, 3, 9) .attr(FlinchAttr) .condition((user, target, move) => user.scene.currentBattle.turnCommands[target.getBattlerIndex()]?.command === Command.FIGHT && !target.turnData.acted && allMoves[user.scene.currentBattle.turnCommands[target.getBattlerIndex()]?.move?.move!].category !== MoveCategory.STATUS && allMoves[user.scene.currentBattle.turnCommands[target.getBattlerIndex()]?.move?.move!].priority > 0 ) // TODO: is this bang correct? - //TODO: Should also apply when target move priority increased by ability ex. gale wings - .partial(), + .partial(), // Should also apply when target move priority increased by ability ex. gale wings new AttackMove(Moves.MALIGNANT_CHAIN, Type.POISON, MoveCategory.SPECIAL, 100, 100, 5, 50, 0, 9) .attr(StatusEffectAttr, StatusEffect.TOXIC) ); From 8e7aea0f8990450d5d06e273f83188fffa87857e Mon Sep 17 00:00:00 2001 From: damocleas Date: Sat, 12 Oct 2024 23:51:14 -0400 Subject: [PATCH 24/37] Fixed Charizard and Kingler BST, fixed ability indexing for gmax forms (#4652) --- src/data/pokemon-species.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index 1ceb5971f6a..8bb23cfc208 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -975,7 +975,7 @@ export function initSpecies() { new PokemonSpecies(Species.VENUSAUR, 1, false, false, false, "Seed Pokémon", Type.GRASS, Type.POISON, 2, 100, Abilities.OVERGROW, Abilities.NONE, Abilities.CHLOROPHYLL, 525, 80, 82, 83, 100, 100, 80, 45, 50, 263, GrowthRate.MEDIUM_SLOW, 87.5, true, true, new PokemonForm("Normal", "", Type.GRASS, Type.POISON, 2, 100, Abilities.OVERGROW, Abilities.NONE, Abilities.CHLOROPHYLL, 525, 80, 82, 83, 100, 100, 80, 45, 50, 263, true, null, true), new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.GRASS, Type.POISON, 2.4, 155.5, Abilities.THICK_FAT, Abilities.THICK_FAT, Abilities.THICK_FAT, 625, 80, 100, 123, 122, 120, 80, 45, 50, 263, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, Type.POISON, 24, 999.9, Abilities.EFFECT_SPORE, Abilities.EFFECT_SPORE, Abilities.EFFECT_SPORE, 625, 120, 82, 98, 130, 115, 80, 45, 50, 263, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, Type.POISON, 24, 999.9, Abilities.EFFECT_SPORE, Abilities.NONE, Abilities.EFFECT_SPORE, 625, 120, 82, 98, 130, 115, 80, 45, 50, 263, true), ), new PokemonSpecies(Species.CHARMANDER, 1, false, false, false, "Lizard Pokémon", Type.FIRE, null, 0.6, 8.5, Abilities.BLAZE, Abilities.NONE, Abilities.SOLAR_POWER, 309, 39, 52, 43, 60, 50, 65, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.CHARMELEON, 1, false, false, false, "Flame Pokémon", Type.FIRE, null, 1.1, 19, Abilities.BLAZE, Abilities.NONE, Abilities.SOLAR_POWER, 405, 58, 64, 58, 80, 65, 80, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), @@ -983,20 +983,20 @@ export function initSpecies() { new PokemonForm("Normal", "", Type.FIRE, Type.FLYING, 1.7, 90.5, Abilities.BLAZE, Abilities.NONE, Abilities.SOLAR_POWER, 534, 78, 84, 78, 109, 85, 100, 45, 50, 267, false, null, true), new PokemonForm("Mega X", SpeciesFormKey.MEGA_X, Type.FIRE, Type.DRAGON, 1.7, 110.5, Abilities.TOUGH_CLAWS, Abilities.NONE, Abilities.TOUGH_CLAWS, 634, 78, 130, 111, 130, 85, 100, 45, 50, 267), new PokemonForm("Mega Y", SpeciesFormKey.MEGA_Y, Type.FIRE, Type.FLYING, 1.7, 100.5, Abilities.DROUGHT, Abilities.NONE, Abilities.DROUGHT, 634, 78, 104, 78, 159, 115, 100, 45, 50, 267), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FIRE, Type.FLYING, 28, 999.9, Abilities.BERSERK, Abilities.BERSERK, Abilities.BERSERK, 634, 118, 84, 93, 139, 110, 100, 45, 50, 267), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FIRE, Type.FLYING, 28, 999.9, Abilities.BERSERK, Abilities.NONE, Abilities.BERSERK, 634, 118, 84, 93, 139, 100, 100, 45, 50, 267), ), new PokemonSpecies(Species.SQUIRTLE, 1, false, false, false, "Tiny Turtle Pokémon", Type.WATER, null, 0.5, 9, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 314, 44, 48, 65, 50, 64, 43, 45, 50, 63, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.WARTORTLE, 1, false, false, false, "Turtle Pokémon", Type.WATER, null, 1, 22.5, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 405, 59, 63, 80, 65, 80, 58, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.BLASTOISE, 1, false, false, false, "Shellfish Pokémon", Type.WATER, null, 1.6, 85.5, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 530, 79, 83, 100, 85, 105, 78, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, new PokemonForm("Normal", "", Type.WATER, null, 1.6, 85.5, Abilities.TORRENT, Abilities.NONE, Abilities.RAIN_DISH, 530, 79, 83, 100, 85, 105, 78, 45, 50, 265, false, null, true), new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.WATER, null, 1.6, 101.1, Abilities.MEGA_LAUNCHER, Abilities.NONE, Abilities.MEGA_LAUNCHER, 630, 79, 103, 120, 135, 115, 78, 45, 50, 265), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, Type.STEEL, 25, 999.9, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, Abilities.SHELL_ARMOR, 630, 119, 83, 135, 115, 110, 68, 45, 50, 265), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, Type.STEEL, 25, 999.9, Abilities.SHELL_ARMOR, Abilities.NONE, Abilities.SHELL_ARMOR, 630, 119, 83, 135, 115, 110, 68, 45, 50, 265), ), new PokemonSpecies(Species.CATERPIE, 1, false, false, false, "Worm Pokémon", Type.BUG, null, 0.3, 2.9, Abilities.SHIELD_DUST, Abilities.NONE, Abilities.RUN_AWAY, 195, 45, 30, 35, 20, 20, 45, 255, 50, 39, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.METAPOD, 1, false, false, false, "Cocoon Pokémon", Type.BUG, null, 0.7, 9.9, Abilities.SHED_SKIN, Abilities.NONE, Abilities.SHED_SKIN, 205, 50, 20, 55, 25, 25, 30, 120, 50, 72, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.BUTTERFREE, 1, false, false, false, "Butterfly Pokémon", Type.BUG, Type.FLYING, 1.1, 32, Abilities.COMPOUND_EYES, Abilities.NONE, Abilities.TINTED_LENS, 395, 60, 45, 50, 90, 80, 70, 45, 50, 198, GrowthRate.MEDIUM_FAST, 50, true, true, new PokemonForm("Normal", "", Type.BUG, Type.FLYING, 1.1, 32, Abilities.COMPOUND_EYES, Abilities.NONE, Abilities.TINTED_LENS, 395, 60, 45, 50, 90, 80, 70, 45, 50, 198, true, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.BUG, Type.FLYING, 17, 999.9, Abilities.COMPOUND_EYES, Abilities.COMPOUND_EYES, Abilities.COMPOUND_EYES, 495, 85, 35, 80, 120, 90, 85, 45, 50, 198, true), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.BUG, Type.FLYING, 17, 999.9, Abilities.COMPOUND_EYES, Abilities.NONE, Abilities.COMPOUND_EYES, 495, 85, 35, 80, 120, 90, 85, 45, 50, 198, true), ), new PokemonSpecies(Species.WEEDLE, 1, false, false, false, "Hairy Bug Pokémon", Type.BUG, Type.POISON, 0.3, 3.2, Abilities.SHIELD_DUST, Abilities.NONE, Abilities.RUN_AWAY, 195, 40, 35, 30, 20, 20, 50, 255, 70, 39, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.KAKUNA, 1, false, false, false, "Cocoon Pokémon", Type.BUG, Type.POISON, 0.6, 10, Abilities.SHED_SKIN, Abilities.NONE, Abilities.SHED_SKIN, 205, 45, 25, 50, 25, 25, 35, 120, 70, 72, GrowthRate.MEDIUM_FAST, 50, false), @@ -1025,7 +1025,7 @@ export function initSpecies() { new PokemonForm("Cute Cosplay", "cute-cosplay", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom new PokemonForm("Smart Cosplay", "smart-cosplay", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom new PokemonForm("Tough Cosplay", "tough-cosplay", Type.ELECTRIC, null, 0.4, 6, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 430, 45, 80, 50, 75, 60, 120, 190, 50, 112, true, null, true), //Custom - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.ELECTRIC, null, 21, 999.9, Abilities.LIGHTNING_ROD, Abilities.LIGHTNING_ROD, Abilities.LIGHTNING_ROD, 530, 125, 95, 60, 90, 70, 90, 190, 50, 112), //+100 BST from Partner Form + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.ELECTRIC, null, 21, 999.9, Abilities.LIGHTNING_ROD, Abilities.NONE, Abilities.LIGHTNING_ROD, 530, 125, 95, 60, 90, 70, 90, 190, 50, 112), //+100 BST from Partner Form ), new PokemonSpecies(Species.RAICHU, 1, false, false, false, "Mouse Pokémon", Type.ELECTRIC, null, 0.8, 30, Abilities.STATIC, Abilities.NONE, Abilities.LIGHTNING_ROD, 485, 60, 90, 55, 90, 80, 110, 75, 50, 243, GrowthRate.MEDIUM_FAST, 50, true), new PokemonSpecies(Species.SANDSHREW, 1, false, false, false, "Mouse Pokémon", Type.GROUND, null, 0.6, 12, Abilities.SAND_VEIL, Abilities.NONE, Abilities.SAND_RUSH, 300, 50, 75, 85, 20, 30, 40, 255, 50, 60, GrowthRate.MEDIUM_FAST, 50, false), @@ -1110,7 +1110,7 @@ export function initSpecies() { new PokemonSpecies(Species.GENGAR, 1, false, false, false, "Shadow Pokémon", Type.GHOST, Type.POISON, 1.5, 40.5, Abilities.CURSED_BODY, Abilities.NONE, Abilities.NONE, 500, 60, 65, 60, 130, 75, 110, 45, 50, 250, GrowthRate.MEDIUM_SLOW, 50, false, true, new PokemonForm("Normal", "", Type.GHOST, Type.POISON, 1.5, 40.5, Abilities.CURSED_BODY, Abilities.NONE, Abilities.NONE, 500, 60, 65, 60, 130, 75, 110, 45, 50, 250, false, null, true), new PokemonForm("Mega", SpeciesFormKey.MEGA, Type.GHOST, Type.POISON, 1.4, 40.5, Abilities.SHADOW_TAG, Abilities.NONE, Abilities.NONE, 600, 60, 65, 80, 170, 95, 130, 45, 50, 250), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GHOST, Type.POISON, 20, 999.9, Abilities.CURSED_BODY, Abilities.CURSED_BODY, Abilities.CURSED_BODY, 600, 140, 65, 70, 140, 85, 100, 45, 50, 250), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GHOST, Type.POISON, 20, 999.9, Abilities.CURSED_BODY, Abilities.NONE, Abilities.NONE, 600, 140, 65, 70, 140, 85, 100, 45, 50, 250), ), new PokemonSpecies(Species.ONIX, 1, false, false, false, "Rock Snake Pokémon", Type.ROCK, Type.GROUND, 8.8, 210, Abilities.ROCK_HEAD, Abilities.STURDY, Abilities.WEAK_ARMOR, 385, 35, 45, 160, 30, 45, 70, 45, 50, 77, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.DROWZEE, 1, false, false, false, "Hypnosis Pokémon", Type.PSYCHIC, null, 1, 32.4, Abilities.INSOMNIA, Abilities.FOREWARN, Abilities.INNER_FOCUS, 328, 60, 48, 45, 43, 90, 42, 190, 70, 66, GrowthRate.MEDIUM_FAST, 50, false), @@ -1118,7 +1118,7 @@ export function initSpecies() { new PokemonSpecies(Species.KRABBY, 1, false, false, false, "River Crab Pokémon", Type.WATER, null, 0.4, 6.5, Abilities.HYPER_CUTTER, Abilities.SHELL_ARMOR, Abilities.SHEER_FORCE, 325, 30, 105, 90, 25, 25, 50, 225, 50, 65, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.KINGLER, 1, false, false, false, "Pincer Pokémon", Type.WATER, null, 1.3, 60, Abilities.HYPER_CUTTER, Abilities.SHELL_ARMOR, Abilities.SHEER_FORCE, 475, 55, 130, 115, 50, 50, 75, 60, 50, 166, GrowthRate.MEDIUM_FAST, 50, false, true, new PokemonForm("Normal", "", Type.WATER, null, 1.3, 60, Abilities.HYPER_CUTTER, Abilities.SHELL_ARMOR, Abilities.SHEER_FORCE, 475, 55, 130, 115, 50, 50, 75, 60, 50, 166, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, null, 19, 999.9, Abilities.TOUGH_CLAWS, Abilities.TOUGH_CLAWS, Abilities.TOUGH_CLAWS, 575, 90, 155, 140, 50, 80, 70, 60, 50, 166), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, null, 19, 999.9, Abilities.TOUGH_CLAWS, Abilities.TOUGH_CLAWS, Abilities.TOUGH_CLAWS, 575, 90, 155, 140, 50, 70, 70, 60, 50, 166), ), new PokemonSpecies(Species.VOLTORB, 1, false, false, false, "Ball Pokémon", Type.ELECTRIC, null, 0.5, 10.4, Abilities.SOUNDPROOF, Abilities.STATIC, Abilities.AFTERMATH, 330, 40, 30, 50, 55, 55, 100, 190, 70, 66, GrowthRate.MEDIUM_FAST, null, false), new PokemonSpecies(Species.ELECTRODE, 1, false, false, false, "Ball Pokémon", Type.ELECTRIC, null, 1.2, 66.6, Abilities.SOUNDPROOF, Abilities.STATIC, Abilities.AFTERMATH, 490, 60, 50, 70, 80, 80, 150, 60, 70, 172, GrowthRate.MEDIUM_FAST, null, false), @@ -2298,25 +2298,25 @@ export function initSpecies() { new PokemonSpecies(Species.MELTAN, 7, false, false, true, "Hex Nut Pokémon", Type.STEEL, null, 0.2, 8, Abilities.MAGNET_PULL, Abilities.NONE, Abilities.NONE, 300, 46, 65, 65, 55, 35, 34, 3, 0, 150, GrowthRate.SLOW, null, false), new PokemonSpecies(Species.MELMETAL, 7, false, false, true, "Hex Nut Pokémon", Type.STEEL, null, 2.5, 800, Abilities.IRON_FIST, Abilities.NONE, Abilities.NONE, 600, 135, 143, 143, 80, 65, 34, 3, 0, 300, GrowthRate.SLOW, null, false, true, new PokemonForm("Normal", "", Type.STEEL, null, 2.5, 800, Abilities.IRON_FIST, Abilities.NONE, Abilities.NONE, 600, 135, 143, 143, 80, 65, 34, 3, 0, 300, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.STEEL, null, 25, 999.9, Abilities.IRON_FIST, Abilities.IRON_FIST, Abilities.IRON_FIST, 700, 175, 165, 155, 85, 75, 45, 3, 0, 300), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.STEEL, null, 25, 999.9, Abilities.IRON_FIST, Abilities.NONE, Abilities.NONE, 700, 175, 165, 155, 85, 75, 45, 3, 0, 300), ), new PokemonSpecies(Species.GROOKEY, 8, false, false, false, "Chimp Pokémon", Type.GRASS, null, 0.3, 5, Abilities.OVERGROW, Abilities.NONE, Abilities.GRASSY_SURGE, 310, 50, 65, 50, 40, 40, 65, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.THWACKEY, 8, false, false, false, "Beat Pokémon", Type.GRASS, null, 0.7, 14, Abilities.OVERGROW, Abilities.NONE, Abilities.GRASSY_SURGE, 420, 70, 85, 70, 55, 60, 80, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.RILLABOOM, 8, false, false, false, "Drummer Pokémon", Type.GRASS, null, 2.1, 90, Abilities.OVERGROW, Abilities.NONE, Abilities.GRASSY_SURGE, 530, 100, 125, 90, 60, 70, 85, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, new PokemonForm("Normal", "", Type.GRASS, null, 2.1, 90, Abilities.OVERGROW, Abilities.NONE, Abilities.GRASSY_SURGE, 530, 100, 125, 90, 60, 70, 85, 45, 50, 265, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, null, 28, 999.9, Abilities.GRASSY_SURGE, Abilities.GRASSY_SURGE, Abilities.GRASSY_SURGE, 630, 125, 150, 105, 85, 85, 80, 45, 50, 265), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.GRASS, null, 28, 999.9, Abilities.GRASSY_SURGE, Abilities.NONE, Abilities.GRASSY_SURGE, 630, 125, 150, 105, 85, 85, 80, 45, 50, 265), ), new PokemonSpecies(Species.SCORBUNNY, 8, false, false, false, "Rabbit Pokémon", Type.FIRE, null, 0.3, 4.5, Abilities.BLAZE, Abilities.NONE, Abilities.LIBERO, 310, 50, 71, 40, 40, 40, 69, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.RABOOT, 8, false, false, false, "Rabbit Pokémon", Type.FIRE, null, 0.6, 9, Abilities.BLAZE, Abilities.NONE, Abilities.LIBERO, 420, 65, 86, 60, 55, 60, 94, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.CINDERACE, 8, false, false, false, "Striker Pokémon", Type.FIRE, null, 1.4, 33, Abilities.BLAZE, Abilities.NONE, Abilities.LIBERO, 530, 80, 116, 75, 65, 75, 119, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, new PokemonForm("Normal", "", Type.FIRE, null, 1.4, 33, Abilities.BLAZE, Abilities.NONE, Abilities.LIBERO, 530, 80, 116, 75, 65, 75, 119, 45, 50, 265, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FIRE, null, 27, 999.9, Abilities.LIBERO, Abilities.LIBERO, Abilities.LIBERO, 630, 100, 146, 80, 90, 80, 134, 45, 50, 265), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FIRE, null, 27, 999.9, Abilities.LIBERO, Abilities.NONE, Abilities.LIBERO, 630, 100, 146, 80, 90, 80, 134, 45, 50, 265), ), new PokemonSpecies(Species.SOBBLE, 8, false, false, false, "Water Lizard Pokémon", Type.WATER, null, 0.3, 4, Abilities.TORRENT, Abilities.NONE, Abilities.SNIPER, 310, 50, 40, 40, 70, 40, 70, 45, 50, 62, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.DRIZZILE, 8, false, false, false, "Water Lizard Pokémon", Type.WATER, null, 0.7, 11.5, Abilities.TORRENT, Abilities.NONE, Abilities.SNIPER, 420, 65, 60, 55, 95, 55, 90, 45, 50, 147, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.INTELEON, 8, false, false, false, "Secret Agent Pokémon", Type.WATER, null, 1.9, 45.2, Abilities.TORRENT, Abilities.NONE, Abilities.SNIPER, 530, 70, 85, 65, 125, 65, 120, 45, 50, 265, GrowthRate.MEDIUM_SLOW, 87.5, false, true, new PokemonForm("Normal", "", Type.WATER, null, 1.9, 45.2, Abilities.TORRENT, Abilities.NONE, Abilities.SNIPER, 530, 70, 85, 65, 125, 65, 120, 45, 50, 265, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, null, 40, 999.9, Abilities.SNIPER, Abilities.SNIPER, Abilities.SNIPER, 630, 95, 97, 77, 147, 77, 137, 45, 50, 265), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.WATER, null, 40, 999.9, Abilities.SNIPER, Abilities.NONE, Abilities.SNIPER, 630, 95, 97, 77, 147, 77, 137, 45, 50, 265), ), new PokemonSpecies(Species.SKWOVET, 8, false, false, false, "Cheeky Pokémon", Type.NORMAL, null, 0.3, 2.5, Abilities.CHEEK_POUCH, Abilities.NONE, Abilities.GLUTTONY, 275, 70, 55, 55, 35, 35, 25, 255, 50, 55, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.GREEDENT, 8, false, false, false, "Greedy Pokémon", Type.NORMAL, null, 0.6, 6, Abilities.CHEEK_POUCH, Abilities.NONE, Abilities.GLUTTONY, 460, 120, 95, 95, 55, 75, 20, 90, 50, 161, GrowthRate.MEDIUM_FAST, 50, false), @@ -2422,7 +2422,7 @@ export function initSpecies() { new PokemonForm("Ruby Swirl", "ruby-swirl", Type.FAIRY, null, 0.3, 0.5, Abilities.SWEET_VEIL, Abilities.NONE, Abilities.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), new PokemonForm("Caramel Swirl", "caramel-swirl", Type.FAIRY, null, 0.3, 0.5, Abilities.SWEET_VEIL, Abilities.NONE, Abilities.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), new PokemonForm("Rainbow Swirl", "rainbow-swirl", Type.FAIRY, null, 0.3, 0.5, Abilities.SWEET_VEIL, Abilities.NONE, Abilities.AROMA_VEIL, 495, 65, 60, 75, 110, 121, 64, 100, 50, 173, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FAIRY, null, 30, 999.9, Abilities.MISTY_SURGE, Abilities.MISTY_SURGE, Abilities.MISTY_SURGE, 595, 135, 60, 75, 130, 131, 64, 100, 50, 173), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.FAIRY, null, 30, 999.9, Abilities.MISTY_SURGE, Abilities.NONE, Abilities.MISTY_SURGE, 595, 135, 60, 75, 130, 131, 64, 100, 50, 173), ), new PokemonSpecies(Species.FALINKS, 8, false, false, false, "Formation Pokémon", Type.FIGHTING, null, 3, 62, Abilities.BATTLE_ARMOR, Abilities.NONE, Abilities.DEFIANT, 470, 65, 100, 100, 70, 60, 75, 45, 50, 165, GrowthRate.MEDIUM_FAST, null, false), new PokemonSpecies(Species.PINCURCHIN, 8, false, false, false, "Sea Urchin Pokémon", Type.ELECTRIC, null, 0.3, 1, Abilities.LIGHTNING_ROD, Abilities.NONE, Abilities.ELECTRIC_SURGE, 435, 48, 101, 95, 91, 85, 15, 75, 50, 152, GrowthRate.MEDIUM_FAST, 50, false), @@ -2444,7 +2444,7 @@ export function initSpecies() { new PokemonSpecies(Species.CUFANT, 8, false, false, false, "Copperderm Pokémon", Type.STEEL, null, 1.2, 100, Abilities.SHEER_FORCE, Abilities.NONE, Abilities.HEAVY_METAL, 330, 72, 80, 49, 40, 49, 40, 190, 50, 66, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.COPPERAJAH, 8, false, false, false, "Copperderm Pokémon", Type.STEEL, null, 3, 650, Abilities.SHEER_FORCE, Abilities.NONE, Abilities.HEAVY_METAL, 500, 122, 130, 69, 80, 69, 30, 90, 50, 175, GrowthRate.MEDIUM_FAST, 50, false, true, new PokemonForm("Normal", "", Type.STEEL, null, 3, 650, Abilities.SHEER_FORCE, Abilities.NONE, Abilities.HEAVY_METAL, 500, 122, 130, 69, 80, 69, 30, 90, 50, 175, false, null, true), - new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.STEEL, Type.GROUND, 23, 999.9, Abilities.MOLD_BREAKER, Abilities.MOLD_BREAKER, Abilities.MOLD_BREAKER, 600, 167, 155, 89, 80, 89, 20, 90, 50, 175), + new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.STEEL, Type.GROUND, 23, 999.9, Abilities.MOLD_BREAKER, Abilities.NONE, Abilities.MOLD_BREAKER, 600, 167, 155, 89, 80, 89, 20, 90, 50, 175), ), new PokemonSpecies(Species.DRACOZOLT, 8, false, false, false, "Fossil Pokémon", Type.ELECTRIC, Type.DRAGON, 1.8, 190, Abilities.VOLT_ABSORB, Abilities.HUSTLE, Abilities.SAND_RUSH, 505, 90, 100, 90, 80, 70, 75, 45, 50, 177, GrowthRate.SLOW, null, false), new PokemonSpecies(Species.ARCTOZOLT, 8, false, false, false, "Fossil Pokémon", Type.ELECTRIC, Type.ICE, 2.3, 150, Abilities.VOLT_ABSORB, Abilities.STATIC, Abilities.SLUSH_RUSH, 505, 90, 100, 90, 90, 80, 55, 45, 50, 177, GrowthRate.SLOW, null, false), From 391f38c3c8bd6106f7c38f4a451883add3bac310 Mon Sep 17 00:00:00 2001 From: Tempoanon <163687446+Tempo-anon@users.noreply.github.com> Date: Sun, 13 Oct 2024 00:45:38 -0400 Subject: [PATCH 25/37] [Documentation] Document all (P) abilities (#4649) * Document partial abilities * Fix typo * Address comments * Fix typo Terapagos -> Ogerpon --------- Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/data/ability.ts | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/data/ability.ts b/src/data/ability.ts index 6a391818866..07fd48e2f91 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -118,6 +118,14 @@ export class Ability implements Localizable { this.nameAppend += " (N)"; return this; } + + /** + * Internal flag used for developers to document edge cases. When using this, please be sure to document the edge case. + * @returns the ability + */ + edgeCase(): this { + return this; + } } type AbAttrApplyFunc = (attr: TAttr, passive: boolean) => boolean | Promise; @@ -4906,7 +4914,7 @@ export function initAbilities() { .ignorable(), new Ability(Abilities.SHIELD_DUST, 3) .attr(IgnoreMoveEffectsAbAttr) - .partial(), + .edgeCase(), // Does not work with secret power (unimplemented) new Ability(Abilities.OWN_TEMPO, 3) .attr(BattlerTagImmunityAbAttr, BattlerTagType.CONFUSED) .attr(IntimidateImmunityAbAttr) @@ -4951,7 +4959,7 @@ export function initAbilities() { .ignorable(), new Ability(Abilities.SERENE_GRACE, 3) .attr(MoveEffectChanceMultiplierAbAttr, 2) - .partial(), + .edgeCase(), // does not work with secret power (unimplemented) new Ability(Abilities.SWIFT_SWIM, 3) .attr(StatMultiplierAbAttr, Stat.SPD, 2) .condition(getWeatherCondition(WeatherType.RAIN, WeatherType.HEAVY_RAIN)), @@ -5235,7 +5243,8 @@ export function initAbilities() { new Ability(Abilities.SHEER_FORCE, 5) .attr(MovePowerBoostAbAttr, (user, target, move) => move.chance >= 1, 5461 / 4096) .attr(MoveEffectChanceMultiplierAbAttr, 0) - .partial(), + .edgeCase() // Should disable shell bell and Meloetta's relic song transformation + .edgeCase(), // Should disable life orb, eject button, red card, kee/maranga berry if they get implemented new Ability(Abilities.CONTRARY, 5) .attr(StatStageChangeMultiplierAbAttr, -1) .ignorable(), @@ -5278,7 +5287,7 @@ export function initAbilities() { /** 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) ) - .partial(), + .edgeCase(), // Cannot recover berries used up by fling or natural gift (unimplemented) new Ability(Abilities.TELEPATHY, 5) .attr(MoveImmunityAbAttr, (pokemon, attacker, move) => pokemon.getAlly() === attacker && move instanceof AttackMove) .ignorable(), @@ -5357,7 +5366,7 @@ export function initAbilities() { .bypassFaint(), new Ability(Abilities.VICTORY_STAR, 5) .attr(StatMultiplierAbAttr, Stat.ACC, 1.1) - .partial(), + .partial(), // Does not boost ally's accuracy new Ability(Abilities.TURBOBLAZE, 5) .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => i18next.t("abilityTriggers:postSummonTurboblaze", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })) .attr(MoveAbilityBypassAbAttr), @@ -5468,7 +5477,7 @@ export function initAbilities() { .attr(UnsuppressableAbilityAbAttr) .attr(NoFusionAbilityAbAttr) .bypassFaint() - .partial(), + .partial(), // Meteor form should protect against status effects and yawn new Ability(Abilities.STAKEOUT, 7) .attr(MovePowerBoostAbAttr, (user, target, move) => user?.scene.currentBattle.turnCommands[target?.getBattlerIndex() ?? BattlerIndex.ATTACKER]?.command === Command.POKEMON, 2), new Ability(Abilities.WATER_BUBBLE, 7) @@ -5536,9 +5545,9 @@ export function initAbilities() { .attr(NoFusionAbilityAbAttr) .bypassFaint() .partial(), - new Ability(Abilities.CORROSION, 7) // TODO: Test Corrosion against Magic Bounce once it is implemented + new Ability(Abilities.CORROSION, 7) .attr(IgnoreTypeStatusEffectImmunityAbAttr, [ StatusEffect.POISON, StatusEffect.TOXIC ], [ Type.STEEL, Type.POISON ]) - .partial(), + .edgeCase(), // Should interact correctly with magic coat/bounce (not yet implemented), fling with toxic orb (not implemented yet), and synchronize (not fully implemented yet) new Ability(Abilities.COMATOSE, 7) .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) @@ -5693,7 +5702,7 @@ export function initAbilities() { new Ability(Abilities.WANDERING_SPIRIT, 8) .attr(PostDefendAbilitySwapAbAttr) .bypassFaint() - .partial(), + .edgeCase(), // interacts incorrectly with rock head. It's meant to switch abilities before recoil would apply so that a pokemon with rock head would lose rock head first and still take the recoil new Ability(Abilities.GORILLA_TACTICS, 8) .attr(GorillaTacticsAbAttr), new Ability(Abilities.NEUTRALIZING_GAS, 8) @@ -5702,7 +5711,7 @@ export function initAbilities() { .attr(UnswappableAbilityAbAttr) .attr(NoTransformAbilityAbAttr) .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => i18next.t("abilityTriggers:postSummonNeutralizingGas", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })) - .partial(), + .partial(), // A bunch of weird interactions with other abilities being suppressed then unsuppressed new Ability(Abilities.PASTEL_VEIL, 8) .attr(PostSummonUserFieldRemoveStatusEffectAbAttr, StatusEffect.POISON, StatusEffect.TOXIC) .attr(UserFieldStatusEffectImmunityAbAttr, StatusEffect.POISON, StatusEffect.TOXIC) @@ -5807,7 +5816,7 @@ export function initAbilities() { new Ability(Abilities.GOOD_AS_GOLD, 9) .attr(MoveImmunityAbAttr, (pokemon, attacker, move) => pokemon !== attacker && move.category === MoveCategory.STATUS) .ignorable() - .partial(), + .partial(), // Lots of weird interactions with moves and abilities such as negating status moves that target the field new Ability(Abilities.VESSEL_OF_RUIN, 9) .attr(FieldMultiplyStatAbAttr, Stat.SPATK, 0.75) .attr(PostSummonMessageAbAttr, (user) => i18next.t("abilityTriggers:postSummonVesselOfRuin", { pokemonNameWithAffix: getPokemonNameWithAffix(user), statName: i18next.t(getStatKey(Stat.SPATK)) })) @@ -5840,7 +5849,7 @@ export function initAbilities() { .attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.SLICING_MOVE), 1.5), new Ability(Abilities.SUPREME_OVERLORD, 9) .attr(VariableMovePowerBoostAbAttr, (user, target, move) => 1 + 0.1 * Math.min(user.isPlayer() ? user.scene.currentBattle.playerFaints : user.scene.currentBattle.enemyFaints, 5)) - .partial(), + .partial(), // Counter resets every wave new Ability(Abilities.COSTAR, 9) .attr(PostSummonCopyAllyStatsAbAttr), new Ability(Abilities.TOXIC_DEBRIS, 9) @@ -5873,25 +5882,25 @@ export function initAbilities() { .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) .attr(NoTransformAbilityAbAttr) - .partial(), + .partial(), // Ogerpon tera interactions new Ability(Abilities.EMBODY_ASPECT_WELLSPRING, 9) .attr(PostBattleInitStatStageChangeAbAttr, [ Stat.SPDEF ], 1, true) .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) .attr(NoTransformAbilityAbAttr) - .partial(), + .partial(), // Ogerpon tera interactions new Ability(Abilities.EMBODY_ASPECT_HEARTHFLAME, 9) .attr(PostBattleInitStatStageChangeAbAttr, [ Stat.ATK ], 1, true) .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) .attr(NoTransformAbilityAbAttr) - .partial(), + .partial(), // Ogerpon tera interactions new Ability(Abilities.EMBODY_ASPECT_CORNERSTONE, 9) .attr(PostBattleInitStatStageChangeAbAttr, [ Stat.DEF ], 1, true) .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) .attr(NoTransformAbilityAbAttr) - .partial(), + .partial(), // Ogerpon tera interactions new Ability(Abilities.TERA_SHIFT, 9) .attr(PostSummonFormChangeAbAttr, p => p.getFormKey() ? 0 : 1) .attr(UncopiableAbilityAbAttr) From 470f9e4e19276ec341736df795949743acbcee71 Mon Sep 17 00:00:00 2001 From: innerthunder <168692175+innerthunder@users.noreply.github.com> Date: Sat, 12 Oct 2024 21:46:41 -0700 Subject: [PATCH 26/37] [P3] Fix Substitute visual error on wave transition (#4648) --- src/field/pokemon.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index c495e0833cd..136c1eb1685 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -749,9 +749,16 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const relX = newOffset[0] - initialOffset[0]; const relY = newOffset[1] - initialOffset[1]; + const subTag = this.getTag(SubstituteTag); + if (duration) { + // TODO: can this use stricter typing? + const targets: any[] = [ this ]; + if (subTag?.sprite) { + targets.push(subTag.sprite); + } this.scene.tweens.add({ - targets: this, + targets: targets, x: (_target, _key, value: number) => value + relX, y: (_target, _key, value: number) => value + relY, duration: duration, @@ -761,6 +768,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { } else { this.x += relX; this.y += relY; + if (subTag?.sprite) { + subTag.sprite.x += relX; + subTag.sprite.y += relY; + } } }); } From 8a355d500a27ca8c74482665a8680528007ab727 Mon Sep 17 00:00:00 2001 From: Mumble <171087428+frutescens@users.noreply.github.com> Date: Sun, 13 Oct 2024 00:30:04 -0700 Subject: [PATCH 27/37] [Bug] Move Restriction Battler Tag bugs (#4536) * Added fixes * Revert "Added fixes" This reverts commit 3feccd792ddef0b32ddc40782b60f23f952cad23. * Added loadTag functions * Fixes * typeodcs * Torment * yawn * hsldklahdlhalhdlahldhlah * Imprison Fixes * Fixed imprison not interrupting PRE_MOVE * just kidding * Apply suggestions from code review Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Fixing what broke * added scp[es * missed a scope * Update src/data/battler-tags.ts Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * good tp go * merge * battler tags * Apply suggestions from code review * Changed function names * publics --------- Co-authored-by: frutescens Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/data/arena-tag.ts | 68 ++++++++++++++++++++------------- src/data/battler-tags.ts | 75 ++++++++++++++++++++++++------------- src/data/move.ts | 3 +- src/field/pokemon.ts | 8 ++-- src/phases/command-phase.ts | 4 +- 5 files changed, 99 insertions(+), 59 deletions(-) diff --git a/src/data/arena-tag.ts b/src/data/arena-tag.ts index 11d28ab7e25..71cf11fa06f 100644 --- a/src/data/arena-tag.ts +++ b/src/data/arena-tag.ts @@ -4,7 +4,7 @@ import { Type } from "#app/data/type"; import * as Utils from "#app/utils"; import { MoveCategory, allMoves, MoveTarget, IncrementMovePriorityAttr, applyMoveAttrs } from "#app/data/move"; import { getPokemonNameWithAffix } from "#app/messages"; -import Pokemon, { HitResult, PlayerPokemon, PokemonMove, EnemyPokemon } from "#app/field/pokemon"; +import Pokemon, { HitResult, PokemonMove } from "#app/field/pokemon"; import { StatusEffect } from "#app/data/status-effect"; import { BattlerIndex } from "#app/battle"; import { BlockNonDirectDamageAbAttr, ChangeMovePriorityAbAttr, ProtectStatAbAttr, applyAbAttrs } from "#app/data/ability"; @@ -71,6 +71,32 @@ export abstract class ArenaTag { this.sourceId = source.sourceId; this.side = source.side; } + + /** + * Helper function that retrieves the source Pokemon + * @param scene medium to retrieve the source Pokemon + * @returns The source {@linkcode Pokemon} or `null` if none is found + */ + public getSourcePokemon(scene: BattleScene): Pokemon | null { + return this.sourceId ? scene.getPokemonById(this.sourceId) : null; + } + + /** + * Helper function that retrieves the Pokemon affected + * @param scene - medium to retrieve the involved Pokemon + * @returns list of PlayerPokemon or EnemyPokemon on the field + */ + public getAffectedPokemon(scene: BattleScene): Pokemon[] { + switch (this.side) { + case ArenaTagSide.PLAYER: + return scene.getPlayerField() ?? []; + case ArenaTagSide.ENEMY: + return scene.getEnemyField() ?? []; + case ArenaTagSide.BOTH: + default: + return scene.getField(true) ?? []; + } + } } /** @@ -978,36 +1004,24 @@ class NoneTag extends ArenaTag { * Imprison will apply to any opposing Pokemon that switch onto the field as well. */ class ImprisonTag extends ArenaTrapTag { - private source: Pokemon; - constructor(sourceId: number, side: ArenaTagSide) { super(ArenaTagType.IMPRISON, Moves.IMPRISON, sourceId, side, 1); } - /** - * Helper function that retrieves the Pokemon affected - * @param {BattleScene} scene medium to retrieve the involved Pokemon - * @returns list of PlayerPokemon or EnemyPokemon on the field - */ - private retrieveField(scene: BattleScene): PlayerPokemon[] | EnemyPokemon[] { - if (!this.source.isPlayer()) { - return scene.getPlayerField() ?? []; - } - return scene.getEnemyField() ?? []; - } - /** * This function applies the effects of Imprison to the opposing Pokemon already present on the field. * @param arena */ override onAdd({ scene }: Arena) { - this.source = scene.getPokemonById(this.sourceId!)!; - if (this.source) { - const party = this.retrieveField(scene); - party?.forEach((p: PlayerPokemon | EnemyPokemon ) => { - p.addTag(BattlerTagType.IMPRISON, 1, Moves.IMPRISON, this.sourceId); + const source = this.getSourcePokemon(scene); + if (source) { + const party = this.getAffectedPokemon(scene); + party?.forEach((p: Pokemon ) => { + if (p.isAllowedInBattle()) { + p.addTag(BattlerTagType.IMPRISON, 1, Moves.IMPRISON, this.sourceId); + } }); - scene.queueMessage(i18next.t("battlerTags:imprisonOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(this.source) })); + scene.queueMessage(i18next.t("battlerTags:imprisonOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(source) })); } } @@ -1016,8 +1030,9 @@ class ImprisonTag extends ArenaTrapTag { * @param _arena * @returns `true` if the source of the tag is still active on the field | `false` if not */ - override lapse(_arena: Arena): boolean { - return this.source.isActive(true); + override lapse({ scene }: Arena): boolean { + const source = this.getSourcePokemon(scene); + return source ? source.isActive(true) : false; } /** @@ -1026,7 +1041,8 @@ class ImprisonTag extends ArenaTrapTag { * @returns `true` */ override activateTrap(pokemon: Pokemon): boolean { - if (this.source.isActive(true)) { + const source = this.getSourcePokemon(pokemon.scene); + if (source && source.isActive(true) && pokemon.isAllowedInBattle()) { pokemon.addTag(BattlerTagType.IMPRISON, 1, Moves.IMPRISON, this.sourceId); } return true; @@ -1037,8 +1053,8 @@ class ImprisonTag extends ArenaTrapTag { * @param arena */ override onRemove({ scene }: Arena): void { - const party = this.retrieveField(scene); - party?.forEach((p: PlayerPokemon | EnemyPokemon) => { + const party = this.getAffectedPokemon(scene); + party?.forEach((p: Pokemon) => { p.removeTag(BattlerTagType.IMPRISON); }); } diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 18f03ada941..a5016746013 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -23,6 +23,7 @@ import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase"; import { ShowAbilityPhase } from "#app/phases/show-ability-phase"; import { StatStageChangePhase, StatStageChangeCallback } from "#app/phases/stat-stage-change-phase"; import { PokemonAnimType } from "#app/enums/pokemon-anim-type"; +import BattleScene from "#app/battle-scene"; export enum BattlerTagLapseType { FAINT, @@ -90,6 +91,15 @@ export class BattlerTag { this.sourceMove = source.sourceMove; this.sourceId = source.sourceId; } + + /** + * Helper function that retrieves the source Pokemon object + * @param scene medium to retrieve the source Pokemon + * @returns The source {@linkcode Pokemon} or `null` if none is found + */ + public getSourcePokemon(scene: BattleScene): Pokemon | null { + return this.sourceId ? scene.getPokemonById(this.sourceId) : null; + } } export interface WeatherBattlerTag { @@ -120,7 +130,7 @@ export abstract class MoveRestrictionBattlerTag extends BattlerTag { const phase = pokemon.scene.getCurrentPhase() as MovePhase; const move = phase.move; - if (this.isMoveRestricted(move.moveId)) { + if (this.isMoveRestricted(move.moveId, pokemon)) { if (this.interruptedText(pokemon, move.moveId)) { pokemon.scene.queueMessage(this.interruptedText(pokemon, move.moveId)); } @@ -136,10 +146,11 @@ export abstract class MoveRestrictionBattlerTag extends BattlerTag { /** * Gets whether this tag is restricting a move. * - * @param {Moves} move {@linkcode Moves} ID to check restriction for. - * @returns {boolean} `true` if the move is restricted by this tag, otherwise `false`. + * @param move - {@linkcode Moves} ID to check restriction for. + * @param user - The {@linkcode Pokemon} involved + * @returns `true` if the move is restricted by this tag, otherwise `false`. */ - abstract isMoveRestricted(move: Moves): boolean; + public abstract isMoveRestricted(move: Moves, user?: Pokemon): boolean; /** * Checks if this tag is restricting a move based on a user's decisions during the target selection phase @@ -327,6 +338,16 @@ export class GorillaTacticsTag extends MoveRestrictionBattlerTag { pokemon.setStat(Stat.ATK, pokemon.getStat(Stat.ATK, false) * 1.5, false); } + /** + * Loads the Gorilla Tactics Battler Tag along with its unique class variable moveId + * @override + * @param source Gorilla Tactics' {@linkcode BattlerTag} information + */ + public override loadTag(source: BattlerTag | any): void { + super.loadTag(source); + this.moveId = source.moveId; + } + /** * * @override @@ -2510,8 +2531,6 @@ export class MysteryEncounterPostSummonTag extends BattlerTag { * Torment does not interrupt the move if the move is performed consecutively in the same turn and right after Torment is applied */ export class TormentTag extends MoveRestrictionBattlerTag { - private target: Pokemon; - constructor(sourceId: number) { super(BattlerTagType.TORMENT, BattlerTagLapseType.AFTER_MOVE, 1, Moves.TORMENT, sourceId); } @@ -2523,7 +2542,6 @@ export class TormentTag extends MoveRestrictionBattlerTag { */ override onAdd(pokemon: Pokemon) { super.onAdd(pokemon); - this.target = pokemon; pokemon.scene.queueMessage(i18next.t("battlerTags:tormentOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }), 1500); } @@ -2542,15 +2560,18 @@ export class TormentTag extends MoveRestrictionBattlerTag { * @param {Moves} move the move under investigation * @returns `true` if there is valid consecutive usage | `false` if the moves are different from each other */ - override isMoveRestricted(move: Moves): boolean { - const lastMove = this.target.getLastXMoves(1)[0]; + public override isMoveRestricted(move: Moves, user: Pokemon): boolean { + if (!user) { + return false; + } + const lastMove = user.getLastXMoves(1)[0]; if ( !lastMove ) { return false; } // This checks for locking / momentum moves like Rollout and Hydro Cannon + if the user is under the influence of BattlerTagType.FRENZY // Because Uproar's unique behavior is not implemented, it does not check for Uproar. Torment has been marked as partial in moves.ts const moveObj = allMoves[lastMove.move]; - const isUnaffected = moveObj.hasAttr(ConsecutiveUseDoublePowerAttr) || this.target.getTag(BattlerTagType.FRENZY) || moveObj.hasAttr(ChargeAttr); + const isUnaffected = moveObj.hasAttr(ConsecutiveUseDoublePowerAttr) || user.getTag(BattlerTagType.FRENZY) || moveObj.hasAttr(ChargeAttr); const validLastMoveResult = (lastMove.result === MoveResult.SUCCESS) || (lastMove.result === MoveResult.MISS); if (lastMove.move === move && validLastMoveResult && lastMove.move !== Moves.STRUGGLE && !isUnaffected) { return true; @@ -2602,37 +2623,39 @@ export class TauntTag extends MoveRestrictionBattlerTag { * The tag is only removed when the source-user is removed from the field. */ export class ImprisonTag extends MoveRestrictionBattlerTag { - private source: Pokemon | null; - constructor(sourceId: number) { super(BattlerTagType.IMPRISON, [ BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE ], 1, Moves.IMPRISON, sourceId); } - override onAdd(pokemon: Pokemon) { - if (this.sourceId) { - this.source = pokemon.scene.getPokemonById(this.sourceId); - } - } - /** * Checks if the source of Imprison is still active - * @param _pokemon - * @param _lapseType + * @override + * @param pokemon The pokemon this tag is attached to * @returns `true` if the source is still active */ - override lapse(_pokemon: Pokemon, _lapseType: BattlerTagLapseType): boolean { - return this.source?.isActive(true) ?? false; + public override lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { + const source = this.getSourcePokemon(pokemon.scene); + if (source) { + if (lapseType === BattlerTagLapseType.PRE_MOVE) { + return super.lapse(pokemon, lapseType) && source.isActive(true); + } else { + return source.isActive(true); + } + } + return false; } /** * Checks if the source of the tag has the parameter move in its moveset and that the source is still active + * @override * @param {Moves} move the move under investigation * @returns `false` if either condition is not met */ - override isMoveRestricted(move: Moves): boolean { - if (this.source) { - const sourceMoveset = this.source.getMoveset().map(m => m!.moveId); - return sourceMoveset?.includes(move) && this.source.isActive(true); + public override isMoveRestricted(move: Moves, user: Pokemon): boolean { + const source = this.getSourcePokemon(user.scene); + if (source) { + const sourceMoveset = source.getMoveset().map(m => m!.moveId); + return sourceMoveset?.includes(move) && source.isActive(true); } return false; } diff --git a/src/data/move.ts b/src/data/move.ts index 8e9977337cc..d4f3b2ce3ee 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -7883,7 +7883,8 @@ export function initMoves() { .attr(SwitchAbilitiesAttr), new StatusMove(Moves.IMPRISON, Type.PSYCHIC, 100, 10, -1, 0, 3) .ignoresSubstitute() - .attr(AddArenaTagAttr, ArenaTagType.IMPRISON, 1, true, false), + .attr(AddArenaTagAttr, ArenaTagType.IMPRISON, 1, true, false) + .target(MoveTarget.ENEMY_SIDE), new SelfStatusMove(Moves.REFRESH, Type.NORMAL, -1, 20, -1, 0, 3) .attr(HealStatusEffectAttr, true, StatusEffect.PARALYSIS, StatusEffect.POISON, StatusEffect.TOXIC, StatusEffect.BURN) .condition((user, target, move) => !!user.status && (user.status.effect === StatusEffect.PARALYSIS || user.status.effect === StatusEffect.POISON || user.status.effect === StatusEffect.TOXIC || user.status.effect === StatusEffect.BURN)), diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 136c1eb1685..9ae83753e62 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -3062,8 +3062,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * * @see {@linkcode MoveRestrictionBattlerTag} */ - isMoveRestricted(moveId: Moves): boolean { - return this.getRestrictingTag(moveId) !== null; + public isMoveRestricted(moveId: Moves, pokemon?: Pokemon): boolean { + return this.getRestrictingTag(moveId, pokemon) !== null; } /** @@ -3096,7 +3096,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { */ getRestrictingTag(moveId: Moves, user?: Pokemon, target?: Pokemon): MoveRestrictionBattlerTag | null { for (const tag of this.findTags(t => t instanceof MoveRestrictionBattlerTag)) { - if ((tag as MoveRestrictionBattlerTag).isMoveRestricted(moveId)) { + if ((tag as MoveRestrictionBattlerTag).isMoveRestricted(moveId, user)) { return tag as MoveRestrictionBattlerTag; } else if (user && target && (tag as MoveRestrictionBattlerTag).isMoveTargetRestricted(moveId, user, target)) { return tag as MoveRestrictionBattlerTag; @@ -5139,7 +5139,7 @@ export class PokemonMove { * @returns `true` if the move can be selected and used by the Pokemon, otherwise `false`. */ isUsable(pokemon: Pokemon, ignorePp: boolean = false, ignoreRestrictionTags: boolean = false): boolean { - if (this.moveId && !ignoreRestrictionTags && pokemon.isMoveRestricted(this.moveId)) { + if (this.moveId && !ignoreRestrictionTags && pokemon.isMoveRestricted(this.moveId, pokemon)) { return false; } diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index e85c66543ac..cf66631bd96 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -114,8 +114,8 @@ export class CommandPhase extends FieldPhase { // Decides between a Disabled, Not Implemented, or No PP translation message const errorMessage = - playerPokemon.isMoveRestricted(move.moveId) - ? playerPokemon.getRestrictingTag(move.moveId)!.selectionDeniedText(playerPokemon, move.moveId) + playerPokemon.isMoveRestricted(move.moveId, playerPokemon) + ? playerPokemon.getRestrictingTag(move.moveId, playerPokemon)!.selectionDeniedText(playerPokemon, move.moveId) : move.getName().endsWith(" (N)") ? "battle:moveNotImplemented" : "battle:moveNoPP"; const moveName = move.getName().replace(" (N)", ""); // Trims off the indicator From e340abe75d2d27b17922cb12e90bf19a9b9a0f70 Mon Sep 17 00:00:00 2001 From: PigeonBar <56974298+PigeonBar@users.noreply.github.com> Date: Sun, 13 Oct 2024 20:08:47 -0400 Subject: [PATCH 28/37] [P1 Bug] Fix softlock when a phazing attack activates a reviver seed (#4654) * [P1 Bug] Fix softlock when a phazing attack activates a reviver seed * Polishing tests * Change approach to respect Parting Shot's targeting * Tests: Added checks for correct number of Pokemon on field --- src/data/move.ts | 13 +++---- src/test/moves/dragon_tail.test.ts | 54 ++++++++++++++++++++++++++++++ src/test/moves/u_turn.test.ts | 19 +++++++++++ 3 files changed, 80 insertions(+), 6 deletions(-) diff --git a/src/data/move.ts b/src/data/move.ts index d4f3b2ce3ee..a77e8096672 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -5484,37 +5484,38 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { */ const switchOutTarget = this.selfSwitch ? user : target; if (switchOutTarget instanceof PlayerPokemon) { + // Switch out logic for the player's Pokemon if (switchOutTarget.scene.getParty().filter((p) => p.isAllowedInBattle() && !p.isOnField()).length < 1) { return false; } - switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH); if (switchOutTarget.hp > 0) { + switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH); user.scene.prependToPhase(new SwitchPhase(user.scene, this.switchType, switchOutTarget.getFieldIndex(), true, true), MoveEndPhase); return true; } return false; } else if (user.scene.currentBattle.battleType !== BattleType.WILD) { + // Switch out logic for trainer battles if (switchOutTarget.scene.getEnemyParty().filter((p) => p.isAllowedInBattle() && !p.isOnField()).length < 1) { return false; } - // Switch out logic for trainer battles - switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH); if (switchOutTarget.hp > 0) { // for opponent switching out + switchOutTarget.leaveField(this.switchType === SwitchType.SWITCH); user.scene.prependToPhase(new SwitchSummonPhase(user.scene, this.switchType, switchOutTarget.getFieldIndex(), (user.scene.currentBattle.trainer ? user.scene.currentBattle.trainer.getNextSummonIndex((switchOutTarget as EnemyPokemon).trainerSlot) : 0), false, false), MoveEndPhase); } } else { + // Switch out logic for everything else (eg: WILD battles) if (user.scene.currentBattle.waveIndex % 10 === 0) { return false; } - // Switch out logic for everything else (eg: WILD battles) - switchOutTarget.leaveField(false); - if (switchOutTarget.hp) { + if (switchOutTarget.hp > 0) { + switchOutTarget.leaveField(false); user.scene.queueMessage(i18next.t("moveTriggers:fled", { pokemonName: getPokemonNameWithAffix(switchOutTarget) }), null, true, 500); // in double battles redirect potential moves off fled pokemon diff --git a/src/test/moves/dragon_tail.test.ts b/src/test/moves/dragon_tail.test.ts index eb02b09fbb4..cf801eb42c1 100644 --- a/src/test/moves/dragon_tail.test.ts +++ b/src/test/moves/dragon_tail.test.ts @@ -139,4 +139,58 @@ describe("Moves - Dragon Tail", () => { expect(enemy.isFullHp()).toBe(false); }); + + it("should force a switch upon fainting an opponent normally", async () => { + game.override.startingWave(5) + .startingLevel(1000); // To make sure Dragon Tail KO's the opponent + await game.classicMode.startBattle([ Species.DRATINI ]); + + game.move.select(Moves.DRAGON_TAIL); + + await game.toNextTurn(); + + // Make sure the enemy switched to a healthy Pokemon + const enemy = game.scene.getEnemyPokemon()!; + expect(enemy).toBeDefined(); + expect(enemy.isFullHp()).toBe(true); + + // Make sure the enemy has a fainted Pokemon in their party and not on the field + const faintedEnemy = game.scene.getEnemyParty().find(p => !p.isAllowedInBattle()); + expect(faintedEnemy).toBeDefined(); + expect(game.scene.getEnemyField().length).toBe(1); + }); + + it("should not cause a softlock when activating an opponent trainer's reviver seed", async () => { + game.override.startingWave(5) + .enemyHeldItems([{ name: "REVIVER_SEED" }]) + .startingLevel(1000); // To make sure Dragon Tail KO's the opponent + await game.classicMode.startBattle([ Species.DRATINI ]); + + game.move.select(Moves.DRAGON_TAIL); + + await game.toNextTurn(); + + // Make sure the enemy field is not empty and has a revived Pokemon + const enemy = game.scene.getEnemyPokemon()!; + expect(enemy).toBeDefined(); + expect(enemy.hp).toBe(Math.floor(enemy.getMaxHp() / 2)); + expect(game.scene.getEnemyField().length).toBe(1); + }); + + it("should not cause a softlock when activating a player's reviver seed", async () => { + game.override.startingHeldItems([{ name: "REVIVER_SEED" }]) + .enemyMoveset(Moves.DRAGON_TAIL) + .enemyLevel(1000); // To make sure Dragon Tail KO's the player + await game.classicMode.startBattle([ Species.DRATINI, Species.BULBASAUR ]); + + game.move.select(Moves.SPLASH); + + await game.toNextTurn(); + + // Make sure the player's field is not empty and has a revived Pokemon + const dratini = game.scene.getPlayerPokemon()!; + expect(dratini).toBeDefined(); + expect(dratini.hp).toBe(Math.floor(dratini.getMaxHp() / 2)); + expect(game.scene.getPlayerField().length).toBe(1); + }); }); diff --git a/src/test/moves/u_turn.test.ts b/src/test/moves/u_turn.test.ts index 17e02cb50ef..b995c20f503 100644 --- a/src/test/moves/u_turn.test.ts +++ b/src/test/moves/u_turn.test.ts @@ -96,4 +96,23 @@ describe("Moves - U-turn", () => { expect(game.scene.getEnemyPokemon()!.battleData.abilityRevealed).toBe(true); // proxy for asserting ability activated expect(game.phaseInterceptor.log).not.toContain("SwitchSummonPhase"); }, 20000); + + it("still forces a switch if u-turn KO's the opponent", async () => { + game.override.startingLevel(1000); // Ensure that U-Turn KO's the opponent + await game.classicMode.startBattle([ + Species.RAICHU, + Species.SHUCKLE + ]); + const enemy = game.scene.getEnemyPokemon()!; + + // KO the opponent with U-Turn + game.move.select(Moves.U_TURN); + game.doSelectPartyPokemon(1); + await game.phaseInterceptor.to(TurnEndPhase); + expect(enemy.isFainted()).toBe(true); + + // Check that U-Turn forced a switch + expect(game.phaseInterceptor.log).toContain("SwitchSummonPhase"); + expect(game.scene.getPlayerPokemon()!.species.speciesId).toBe(Species.SHUCKLE); + }); }); From 8981f0e7a8ee63743b60f1665967859940b1a4b8 Mon Sep 17 00:00:00 2001 From: Mumble <171087428+frutescens@users.noreply.github.com> Date: Sun, 13 Oct 2024 19:20:55 -0700 Subject: [PATCH 29/37] Trainer party de-duplication checks static pokemon too (#4585) Co-authored-by: frutescens Co-authored-by: innerthunder <168692175+innerthunder@users.noreply.github.com> --- src/field/trainer.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/field/trainer.ts b/src/field/trainer.ts index 2ec9d07e474..5110787452f 100644 --- a/src/field/trainer.ts +++ b/src/field/trainer.ts @@ -383,7 +383,7 @@ export default class Trainer extends Phaser.GameObjects.Container { const battle = this.scene.currentBattle; const template = this.getPartyTemplate(); - let species: PokemonSpecies; + let baseSpecies: PokemonSpecies; if (this.config.speciesPools) { const tierValue = Utils.randSeedInt(512); let tier = tierValue >= 156 ? TrainerPoolTier.COMMON : tierValue >= 32 ? TrainerPoolTier.UNCOMMON : tierValue >= 6 ? TrainerPoolTier.RARE : tierValue >= 1 ? TrainerPoolTier.SUPER_RARE : TrainerPoolTier.ULTRA_RARE; @@ -393,17 +393,17 @@ export default class Trainer extends Phaser.GameObjects.Container { tier--; } const tierPool = this.config.speciesPools[tier]; - species = getPokemonSpecies(Utils.randSeedItem(tierPool)); + baseSpecies = getPokemonSpecies(Utils.randSeedItem(tierPool)); } else { - species = this.scene.randomSpecies(battle.waveIndex, level, false, this.config.speciesFilter); + baseSpecies = this.scene.randomSpecies(battle.waveIndex, level, false, this.config.speciesFilter); } - let ret = getPokemonSpecies(species.getTrainerSpeciesForLevel(level, true, strength, this.scene.currentBattle.waveIndex)); + let ret = getPokemonSpecies(baseSpecies.getTrainerSpeciesForLevel(level, true, strength, this.scene.currentBattle.waveIndex)); let retry = false; console.log(ret.getName()); - if (pokemonPrevolutions.hasOwnProperty(species.speciesId) && ret.speciesId !== species.speciesId) { + if (pokemonPrevolutions.hasOwnProperty(baseSpecies.speciesId) && ret.speciesId !== baseSpecies.speciesId) { retry = true; } else if (template.isBalanced(battle.enemyParty.length)) { const partyMemberTypes = battle.enemyParty.map(p => p.getTypes(true)).flat(); @@ -417,7 +417,7 @@ export default class Trainer extends Phaser.GameObjects.Container { console.log("Attempting reroll of species evolution to fit specialty type..."); let evoAttempt = 0; while (retry && evoAttempt++ < 10) { - ret = getPokemonSpecies(species.getTrainerSpeciesForLevel(level, true, strength, this.scene.currentBattle.waveIndex)); + ret = getPokemonSpecies(baseSpecies.getTrainerSpeciesForLevel(level, true, strength, this.scene.currentBattle.waveIndex)); console.log(ret.name); if (this.config.specialtyTypes.find(t => ret.isOfType(t))) { retry = false; @@ -426,7 +426,7 @@ export default class Trainer extends Phaser.GameObjects.Container { } // Prompts reroll of party member species if species already present in the enemy party - if (this.checkDuplicateSpecies(ret)) { + if (this.checkDuplicateSpecies(ret, baseSpecies)) { console.log("Duplicate species detected, prompting reroll..."); retry = true; } @@ -442,13 +442,16 @@ export default class Trainer extends Phaser.GameObjects.Container { /** * Checks if the enemy trainer already has the Pokemon species in their party * @param {PokemonSpecies} species {@linkcode PokemonSpecies} + * @param {PokemonSpecies} baseSpecies {@linkcode PokemonSpecies} - baseSpecies of the Pokemon if species is forced to evolve * @returns `true` if the species is already present in the party */ - checkDuplicateSpecies(species: PokemonSpecies): boolean { + checkDuplicateSpecies(species: PokemonSpecies, baseSpecies: PokemonSpecies): boolean { + const staticPartyPokemon = (signatureSpecies[TrainerType[this.config.trainerType]] ?? []).flat(1); + const currentPartySpecies = this.scene.getEnemyParty().map(p => { return p.species.speciesId; }); - return currentPartySpecies.includes(species.speciesId); + return currentPartySpecies.includes(species.speciesId) || staticPartyPokemon.includes(baseSpecies.speciesId); } getPartyMemberMatchupScores(trainerSlot: TrainerSlot = TrainerSlot.NONE, forSwitch: boolean = false): [integer, integer][] { From 676322e80072518bd667d0513aa18136eed0e82b Mon Sep 17 00:00:00 2001 From: MokaStitcher <54149968+MokaStitcher@users.noreply.github.com> Date: Mon, 14 Oct 2024 16:42:59 +0200 Subject: [PATCH 30/37] [QOL] Add input delay for skipping egg summary (#4644) --- src/phases/egg-lapse-phase.ts | 5 +++-- src/phases/egg-summary-phase.ts | 3 --- src/ui/abstact-option-select-ui-handler.ts | 2 ++ src/ui/confirm-ui-handler.ts | 5 +++-- src/ui/egg-summary-ui-handler.ts | 24 +++++++++++++++++----- 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/phases/egg-lapse-phase.ts b/src/phases/egg-lapse-phase.ts index d81d63696a5..4c57be09b79 100644 --- a/src/phases/egg-lapse-phase.ts +++ b/src/phases/egg-lapse-phase.ts @@ -33,7 +33,7 @@ export class EggLapsePhase extends Phase { if (eggsToHatchCount > 0) { if (eggsToHatchCount >= this.minEggsToSkip && this.scene.eggSkipPreference === 1) { this.scene.ui.showText(i18next.t("battle:eggHatching"), 0, () => { - // show prompt for skip + // show prompt for skip, blocking inputs for 1 second this.scene.ui.showText(i18next.t("battle:eggSkipPrompt"), 0); this.scene.ui.setModeWithoutClear(Mode.CONFIRM, () => { this.hatchEggsSkipped(eggsToHatch); @@ -41,7 +41,8 @@ export class EggLapsePhase extends Phase { }, () => { this.hatchEggsRegular(eggsToHatch); this.end(); - } + }, + null, null, null, 1000, true ); }, 100, true); } else if (eggsToHatchCount >= this.minEggsToSkip && this.scene.eggSkipPreference === 2) { diff --git a/src/phases/egg-summary-phase.ts b/src/phases/egg-summary-phase.ts index 75c6939daf1..b673eb4887b 100644 --- a/src/phases/egg-summary-phase.ts +++ b/src/phases/egg-summary-phase.ts @@ -1,7 +1,6 @@ import BattleScene from "#app/battle-scene"; import { Phase } from "#app/phase"; import { Mode } from "#app/ui/ui"; -import EggHatchSceneHandler from "#app/ui/egg-hatch-scene-handler"; import { EggHatchData } from "#app/data/egg-hatch-data"; /** @@ -11,7 +10,6 @@ import { EggHatchData } from "#app/data/egg-hatch-data"; */ export class EggSummaryPhase extends Phase { private eggHatchData: EggHatchData[]; - private eggHatchHandler: EggHatchSceneHandler; constructor(scene: BattleScene, eggHatchData: EggHatchData[]) { super(scene); @@ -26,7 +24,6 @@ export class EggSummaryPhase extends Phase { if (i >= this.eggHatchData.length) { this.scene.ui.setModeForceTransition(Mode.EGG_HATCH_SUMMARY, this.eggHatchData).then(() => { this.scene.fadeOutBgm(undefined, false); - this.eggHatchHandler = this.scene.ui.getHandler() as EggHatchSceneHandler; }); } else { diff --git a/src/ui/abstact-option-select-ui-handler.ts b/src/ui/abstact-option-select-ui-handler.ts index 9dffd3b4ad0..a12ffbc46bd 100644 --- a/src/ui/abstact-option-select-ui-handler.ts +++ b/src/ui/abstact-option-select-ui-handler.ts @@ -165,6 +165,7 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler { if (this.config.delay) { this.blockInput = true; this.optionSelectText.setAlpha(0.5); + this.cursorObj?.setAlpha(0.8); this.scene.time.delayedCall(Utils.fixedInt(this.config.delay), () => this.unblockInput()); } @@ -256,6 +257,7 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler { this.blockInput = false; this.optionSelectText.setAlpha(1); + this.cursorObj?.setAlpha(1); } getOptionsWithScroll(): OptionSelectItem[] { diff --git a/src/ui/confirm-ui-handler.ts b/src/ui/confirm-ui-handler.ts index 16dae82d091..2022508fc0d 100644 --- a/src/ui/confirm-ui-handler.ts +++ b/src/ui/confirm-ui-handler.ts @@ -76,7 +76,8 @@ export default class ConfirmUiHandler extends AbstractOptionSelectUiHandler { } } ], - delay: args.length >= 6 && args[5] !== null ? args[5] as integer : 0 + delay: args.length >= 6 && args[5] !== null ? args[5] as number : 0, + noCancel: args.length >= 7 && args[6] !== null ? args[6] as boolean : false, }; super.show([ config ]); @@ -96,7 +97,7 @@ export default class ConfirmUiHandler extends AbstractOptionSelectUiHandler { } processInput(button: Button): boolean { - if (button === Button.CANCEL && this.blockInput) { + if (button === Button.CANCEL && this.blockInput && !this.config?.noCancel) { this.unblockInput(); } diff --git a/src/ui/egg-summary-ui-handler.ts b/src/ui/egg-summary-ui-handler.ts index 519722b1505..da93168926e 100644 --- a/src/ui/egg-summary-ui-handler.ts +++ b/src/ui/egg-summary-ui-handler.ts @@ -42,6 +42,9 @@ export default class EggSummaryUiHandler extends MessageUiHandler { private scrollGridHandler : ScrollableGridUiHandler; private cursorObj: Phaser.GameObjects.Image; + /** used to add a delay before which it is not possible to exit the summary */ + private blockExit: boolean; + /** * Allows subscribers to listen for events * @@ -168,6 +171,13 @@ export default class EggSummaryUiHandler extends MessageUiHandler { this.setCursor(0); this.scene.playSoundWithoutBgm("evolution_fanfare"); + + // Prevent exiting the egg summary for 2 seconds if the egg hatching + // was skipped automatically and for 1 second otherwise + const exitBlockingDuration = (this.scene.eggSkipPreference === 2) ? 2000 : 1000; + this.blockExit = true; + this.scene.time.delayedCall(exitBlockingDuration, () => this.blockExit = false); + return true; } @@ -203,13 +213,17 @@ export default class EggSummaryUiHandler extends MessageUiHandler { const ui = this.getUi(); let success = false; - const error = false; + let error = false; if (button === Button.CANCEL) { - const phase = this.scene.getCurrentPhase(); - if (phase instanceof EggSummaryPhase) { - phase.end(); + if (!this.blockExit) { + const phase = this.scene.getCurrentPhase(); + if (phase instanceof EggSummaryPhase) { + phase.end(); + } + success = true; + } else { + error = true; } - success = true; } else { this.scrollGridHandler.processInput(button); } From e7a4d4055f2b48d1d78c1dc2cb6f3794e0c34dd2 Mon Sep 17 00:00:00 2001 From: cadi Date: Tue, 15 Oct 2024 04:39:34 +0900 Subject: [PATCH 31/37] [Move] Implement Power Trick (#2658) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add `PowerTrickTag` * modify getStat() with PowerTrickTag * implement `PowerTrickAttr` * add unit test * enhance docs and tag apply logic --------- Co-authored-by: Lugiad' Co-authored-by: José Ricardo Fleury Oliveira Co-authored-by: Jannik Tappert <38758606+CodeTappert@users.noreply.github.com> Co-authored-by: Enoch Co-authored-by: Yonmaru40 <47717431+40chyan@users.noreply.github.com> Co-authored-by: Amani H. <109637146+xsn34kzx@users.noreply.github.com> Co-authored-by: Niccolò <123510358+NicusPulcis@users.noreply.github.com> Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- src/data/battler-tags.ts | 40 ++++++++++ src/data/move.ts | 5 +- src/enums/battler-tag-type.ts | 1 + src/field/pokemon.ts | 6 +- src/test/moves/power_trick.test.ts | 113 +++++++++++++++++++++++++++++ 5 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 src/test/moves/power_trick.test.ts diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index a5016746013..8491307fc76 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -2724,6 +2724,44 @@ export class TelekinesisTag extends BattlerTag { } } +/** + * Tag that swaps the user's base ATK stat with its base DEF stat. + * @extends BattlerTag + */ +export class PowerTrickTag extends BattlerTag { + constructor(sourceMove: Moves, sourceId: number) { + super(BattlerTagType.POWER_TRICK, BattlerTagLapseType.CUSTOM, 0, sourceMove, sourceId, true); + } + + onAdd(pokemon: Pokemon): void { + this.swapStat(pokemon); + pokemon.scene.queueMessage(i18next.t("battlerTags:powerTrickActive", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); + } + + onRemove(pokemon: Pokemon): void { + this.swapStat(pokemon); + pokemon.scene.queueMessage(i18next.t("battlerTags:powerTrickActive", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); + } + + /** + * Removes the Power Trick tag and reverts any stat changes if the tag is already applied. + * @param {Pokemon} pokemon The {@linkcode Pokemon} that already has the Power Trick tag. + */ + onOverlap(pokemon: Pokemon): void { + pokemon.removeTag(this.tagType); + } + + /** + * Swaps the user's base ATK stat with its base DEF stat. + * @param {Pokemon} pokemon The {@linkcode Pokemon} whose stats will be swapped. + */ + swapStat(pokemon: Pokemon): void { + const temp = pokemon.getStat(Stat.ATK, false); + pokemon.setStat(Stat.ATK, pokemon.getStat(Stat.DEF, false), false); + pokemon.setStat(Stat.DEF, temp, false); + } +} + /** * Retrieves a {@linkcode BattlerTag} based on the provided tag type, turn count, source move, and source ID. * @param sourceId - The ID of the pokemon adding the tag @@ -2899,6 +2937,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source return new SyrupBombTag(sourceId); case BattlerTagType.TELEKINESIS: return new TelekinesisTag(sourceMove); + case BattlerTagType.POWER_TRICK: + return new PowerTrickTag(sourceMove, sourceId); case BattlerTagType.NONE: default: return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId); diff --git a/src/data/move.ts b/src/data/move.ts index a77e8096672..2d91363955a 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -6430,6 +6430,9 @@ export class TransformAttr extends MoveEffectAttr { user.summonData.gender = target.getGender(); user.summonData.fusionGender = target.getFusionGender(); + // Power Trick's effect will not preserved after using Transform + user.removeTag(BattlerTagType.POWER_TRICK); + // Copy all stats (except HP) for (const s of EFFECTIVE_STATS) { user.setStat(s, target.getStat(s, false), false); @@ -8153,7 +8156,7 @@ export function initMoves() { .attr(OpponentHighHpPowerAttr, 120) .makesContact(), new SelfStatusMove(Moves.POWER_TRICK, Type.PSYCHIC, -1, 10, -1, 0, 4) - .unimplemented(), + .attr(AddBattlerTagAttr, BattlerTagType.POWER_TRICK, true), new StatusMove(Moves.GASTRO_ACID, Type.POISON, 100, 10, -1, 0, 4) .attr(SuppressAbilitiesAttr), new StatusMove(Moves.LUCKY_CHANT, Type.NORMAL, -1, 30, -1, 0, 4) diff --git a/src/enums/battler-tag-type.ts b/src/enums/battler-tag-type.ts index 2efae9ad359..680dedb93cc 100644 --- a/src/enums/battler-tag-type.ts +++ b/src/enums/battler-tag-type.ts @@ -80,6 +80,7 @@ export enum BattlerTagType { DOUBLE_SHOCKED = "DOUBLE_SHOCKED", AUTOTOMIZED = "AUTOTOMIZED", MYSTERY_ENCOUNTER_POST_SUMMON = "MYSTERY_ENCOUNTER_POST_SUMMON", + POWER_TRICK = "POWER_TRICK", HEAL_BLOCK = "HEAL_BLOCK", TORMENT = "TORMENT", TAUNT = "TAUNT", diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 9ae83753e62..0204672cabd 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -19,7 +19,7 @@ import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims"; import { Status, StatusEffect, getRandomStatus } from "#app/data/status-effect"; import { pokemonEvolutions, pokemonPrevolutions, SpeciesFormEvolution, SpeciesEvolutionCondition, FusionSpeciesFormEvolution } from "#app/data/balance/pokemon-evolutions"; import { reverseCompatibleTms, tmSpecies, tmPoolTiers } from "#app/data/balance/tms"; -import { BattlerTag, BattlerTagLapseType, EncoreTag, GroundedTag, HighestStatBoostTag, SubstituteTag, TypeImmuneTag, getBattlerTag, SemiInvulnerableTag, TypeBoostTag, MoveRestrictionBattlerTag, ExposedTag, DragonCheerTag, CritBoostTag, TrappedTag, TarShotTag, AutotomizedTag } from "../data/battler-tags"; +import { BattlerTag, BattlerTagLapseType, EncoreTag, GroundedTag, HighestStatBoostTag, SubstituteTag, TypeImmuneTag, getBattlerTag, SemiInvulnerableTag, TypeBoostTag, MoveRestrictionBattlerTag, ExposedTag, DragonCheerTag, CritBoostTag, TrappedTag, TarShotTag, AutotomizedTag, PowerTrickTag } from "../data/battler-tags"; import { WeatherType } from "#app/data/weather"; import { ArenaTagSide, NoCritTag, WeakenMoveScreenTag } from "#app/data/arena-tag"; import { Ability, AbAttr, StatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatStagesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldStatMultiplierAbAttrs, FieldMultiplyStatAbAttr, AddSecondStrikeAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr, MoveTypeChangeAbAttr, FullHpResistTypeAbAttr, applyCheckTrappedAbAttrs, CheckTrappedAbAttr, PostSetStatusAbAttr, applyPostSetStatusAbAttrs } from "#app/data/ability"; @@ -3048,6 +3048,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { continue; } + if (tag instanceof PowerTrickTag) { + tag.swapStat(this); + } + this.summonData.tags.push(tag); } diff --git a/src/test/moves/power_trick.test.ts b/src/test/moves/power_trick.test.ts new file mode 100644 index 00000000000..a064a43dec4 --- /dev/null +++ b/src/test/moves/power_trick.test.ts @@ -0,0 +1,113 @@ +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import Phaser from "phaser"; +import GameManager from "#app/test/utils/gameManager"; +import { Moves } from "#enums/moves"; +import { Stat } from "#enums/stat"; +import { Species } from "#enums/species"; +import { TurnEndPhase } from "#app/phases/turn-end-phase"; +import { Abilities } from "#enums/abilities"; +import { BattlerTagType } from "#enums/battler-tag-type"; + +describe("Moves - Power Trick", () => { + 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 + .battleType("single") + .enemyAbility(Abilities.BALL_FETCH) + .enemyMoveset(Moves.SPLASH) + .enemySpecies(Species.MEW) + .enemyLevel(200) + .moveset([ Moves.POWER_TRICK ]) + .ability(Abilities.BALL_FETCH); + }); + + it("swaps the user's ATK and DEF stats", async () => { + await game.classicMode.startBattle([ Species.SHUCKLE ]); + + const player = game.scene.getPlayerPokemon()!; + const baseATK = player.getStat(Stat.ATK, false); + const baseDEF = player.getStat(Stat.DEF, false); + + game.move.select(Moves.POWER_TRICK); + + await game.phaseInterceptor.to(TurnEndPhase); + + expect(player.getStat(Stat.ATK, false)).toBe(baseDEF); + expect(player.getStat(Stat.DEF, false)).toBe(baseATK); + expect(player.getTag(BattlerTagType.POWER_TRICK)).toBeDefined(); + }); + + it("resets initial ATK and DEF stat swap when used consecutively", async () => { + await game.classicMode.startBattle([ Species.SHUCKLE ]); + + const player = game.scene.getPlayerPokemon()!; + const baseATK = player.getStat(Stat.ATK, false); + const baseDEF = player.getStat(Stat.DEF, false); + + game.move.select(Moves.POWER_TRICK); + + await game.phaseInterceptor.to(TurnEndPhase); + + game.move.select(Moves.POWER_TRICK); + + await game.phaseInterceptor.to(TurnEndPhase); + + expect(player.getStat(Stat.ATK, false)).toBe(baseATK); + expect(player.getStat(Stat.DEF, false)).toBe(baseDEF); + expect(player.getTag(BattlerTagType.POWER_TRICK)).toBeUndefined(); + }); + + it("should pass effect when using BATON_PASS", async () => { + await game.classicMode.startBattle([ Species.SHUCKLE, Species.SHUCKLE ]); + await game.override.moveset([ Moves.POWER_TRICK, Moves.BATON_PASS ]); + + const player = game.scene.getPlayerPokemon()!; + player.addTag(BattlerTagType.POWER_TRICK); + + game.move.select(Moves.BATON_PASS); + game.doSelectPartyPokemon(1); + + await game.phaseInterceptor.to(TurnEndPhase); + + const switchedPlayer = game.scene.getPlayerPokemon()!; + const baseATK = switchedPlayer.getStat(Stat.ATK); + const baseDEF = switchedPlayer.getStat(Stat.DEF); + + expect(switchedPlayer.getStat(Stat.ATK, false)).toBe(baseDEF); + expect(switchedPlayer.getStat(Stat.DEF, false)).toBe(baseATK); + expect(switchedPlayer.getTag(BattlerTagType.POWER_TRICK)).toBeDefined(); + }); + + it("should remove effect after using Transform", async () => { + await game.classicMode.startBattle([ Species.SHUCKLE, Species.SHUCKLE ]); + await game.override.moveset([ Moves.POWER_TRICK, Moves.TRANSFORM ]); + + const player = game.scene.getPlayerPokemon()!; + player.addTag(BattlerTagType.POWER_TRICK); + + game.move.select(Moves.TRANSFORM); + + await game.phaseInterceptor.to(TurnEndPhase); + + const enemy = game.scene.getEnemyPokemon()!; + const baseATK = enemy.getStat(Stat.ATK); + const baseDEF = enemy.getStat(Stat.DEF); + + expect(player.getStat(Stat.ATK, false)).toBe(baseATK); + expect(player.getStat(Stat.DEF, false)).toBe(baseDEF); + expect(player.getTag(BattlerTagType.POWER_TRICK)).toBeUndefined(); + }); +}); From e962ac1f182d33e6f06fef1858c49b7ffb90c4b9 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Mon, 14 Oct 2024 14:47:23 -0700 Subject: [PATCH 32/37] [Beta Bug] Prevent duplicate move failure message (#4662) --- src/phases/move-phase.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/phases/move-phase.ts b/src/phases/move-phase.ts index 94093188571..d3a2a3329fd 100644 --- a/src/phases/move-phase.ts +++ b/src/phases/move-phase.ts @@ -128,7 +128,9 @@ export class MovePhase extends BattlePhase { this.lapsePreMoveAndMoveTags(); - this.resolveFinalPreMoveCancellationChecks(); + if (!(this.failed || this.cancelled)) { + this.resolveFinalPreMoveCancellationChecks(); + } if (this.cancelled || this.failed) { this.handlePreMoveFailures(); From bb98bc2f8e296de5b27d644193d284be40062625 Mon Sep 17 00:00:00 2001 From: Blitzy <118096277+Blitz425@users.noreply.github.com> Date: Tue, 15 Oct 2024 04:17:20 -0500 Subject: [PATCH 33/37] [Balance] Evil Team Update / Penny Adjustments (#4577) * Update trainer-config.ts * Update trainer-config.ts * Update trainer-config.ts * Fixed Flare Grunt's having Noivern > Noibat * Revert Inkay change, Change Penny * Give Admin aces canonical genders * Update trainer-config.ts * Update trainer-config.ts --------- Co-authored-by: Madmadness65 Co-authored-by: damocleas --- src/data/trainer-config.ts | 63 ++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 17 deletions(-) diff --git a/src/data/trainer-config.ts b/src/data/trainer-config.ts index bc6596c74bd..bbeecba84e6 100644 --- a/src/data/trainer-config.ts +++ b/src/data/trainer-config.ts @@ -574,13 +574,13 @@ export class TrainerConfig { case "magma": { return { [TrainerPoolTier.COMMON]: [ Species.GROWLITHE, Species.SLUGMA, Species.SOLROCK, Species.HIPPOPOTAS, Species.BALTOY, Species.ROLYCOLY, Species.GLIGAR, Species.TORKOAL, Species.HOUNDOUR, Species.MAGBY ], - [TrainerPoolTier.UNCOMMON]: [ Species.TRAPINCH, Species.SILICOBRA, Species.RHYHORN, Species.ANORITH, Species.LILEEP, Species.HISUI_GROWLITHE, Species.TURTONATOR, Species.ARON, Species.BARBOACH ], + [TrainerPoolTier.UNCOMMON]: [ Species.TRAPINCH, Species.SILICOBRA, Species.RHYHORN, Species.ANORITH, Species.LILEEP, Species.HISUI_GROWLITHE, Species.TURTONATOR, Species.ARON, Species.TOEDSCOOL ], [TrainerPoolTier.RARE]: [ Species.CAPSAKID, Species.CHARCADET ] }; } case "aqua": { return { - [TrainerPoolTier.COMMON]: [ Species.CORPHISH, Species.SPHEAL, Species.CLAMPERL, Species.CHINCHOU, Species.WOOPER, Species.WINGULL, Species.TENTACOOL, Species.AZURILL, Species.LOTAD, Species.WAILMER, Species.REMORAID ], + [TrainerPoolTier.COMMON]: [ Species.CORPHISH, Species.SPHEAL, Species.CLAMPERL, Species.CHINCHOU, Species.WOOPER, Species.WINGULL, Species.TENTACOOL, Species.AZURILL, Species.LOTAD, Species.WAILMER, Species.REMORAID, Species.BARBOACH ], [TrainerPoolTier.UNCOMMON]: [ Species.MANTYKE, Species.HISUI_QWILFISH, Species.ARROKUDA, Species.DHELMISE, Species.CLOBBOPUS, Species.FEEBAS, Species.PALDEA_WOOPER, Species.HORSEA, Species.SKRELP ], [TrainerPoolTier.RARE]: [ Species.DONDOZO, Species.BASCULEGION ] }; @@ -601,9 +601,9 @@ export class TrainerConfig { } case "flare": { return { - [TrainerPoolTier.COMMON]: [ Species.FLETCHLING, Species.LITLEO, Species.INKAY, Species.HELIOPTILE, Species.ELECTRIKE, Species.SKORUPI, Species.PURRLOIN, Species.CLAWITZER, Species.PANCHAM, Species.ESPURR, Species.BUNNELBY ], + [TrainerPoolTier.COMMON]: [ Species.FLETCHLING, Species.LITLEO, Species.INKAY, Species.FOONGUS, Species.HELIOPTILE, Species.ELECTRIKE, Species.SKORUPI, Species.PURRLOIN, Species.CLAWITZER, Species.PANCHAM, Species.ESPURR, Species.BUNNELBY ], [TrainerPoolTier.UNCOMMON]: [ Species.LITWICK, Species.SNEASEL, Species.PUMPKABOO, Species.PHANTUMP, Species.HONEDGE, Species.BINACLE, Species.HOUNDOUR, Species.SKRELP, Species.SLIGGOO ], - [TrainerPoolTier.RARE]: [ Species.NOIVERN, Species.HISUI_AVALUGG, Species.HISUI_SLIGGOO ] + [TrainerPoolTier.RARE]: [ Species.NOIBAT, Species.HISUI_AVALUGG, Species.HISUI_SLIGGOO ] }; } case "aether": { @@ -1504,7 +1504,7 @@ export const trainerConfigs: TrainerConfigs = { .setSpeciesPools({ [TrainerPoolTier.COMMON]: [ Species.SLUGMA, Species.POOCHYENA, Species.NUMEL, Species.ZIGZAGOON, Species.DIGLETT, Species.MAGBY, Species.TORKOAL, Species.GROWLITHE, Species.BALTOY ], [TrainerPoolTier.UNCOMMON]: [ Species.SOLROCK, Species.HIPPOPOTAS, Species.SANDACONDA, Species.PHANPY, Species.ROLYCOLY, Species.GLIGAR, Species.RHYHORN, Species.HEATMOR ], - [TrainerPoolTier.RARE]: [ Species.TRAPINCH, Species.LILEEP, Species.ANORITH, Species.HISUI_GROWLITHE, Species.TURTONATOR, Species.ARON ], + [TrainerPoolTier.RARE]: [ Species.TRAPINCH, Species.LILEEP, Species.ANORITH, Species.HISUI_GROWLITHE, Species.TURTONATOR, Species.ARON, Species.TOEDSCOOL ], [TrainerPoolTier.SUPER_RARE]: [ Species.CAPSAKID, Species.CHARCADET ] }), [TrainerType.TABITHA]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("magma_admin", "magma", [ Species.CAMERUPT ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_aqua_magma_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), @@ -1540,9 +1540,9 @@ export const trainerConfigs: TrainerConfigs = { [TrainerType.FLARE_GRUNT]: new TrainerConfig(++t).setHasGenders("Flare Grunt Female").setHasDouble("Flare Grunts").setMoneyMultiplier(1.0).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_flare_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)) .setSpeciesPools({ [TrainerPoolTier.COMMON]: [ Species.FLETCHLING, Species.LITLEO, Species.PONYTA, Species.INKAY, Species.HOUNDOUR, Species.SKORUPI, Species.SCRAFTY, Species.CROAGUNK, Species.SCATTERBUG, Species.ESPURR ], - [TrainerPoolTier.UNCOMMON]: [ Species.HELIOPTILE, Species.ELECTRIKE, Species.SKRELP, Species.PANCHAM, Species.PURRLOIN, Species.POOCHYENA, Species.BINACLE, Species.CLAUNCHER, Species.PUMPKABOO, Species.PHANTUMP ], + [TrainerPoolTier.UNCOMMON]: [ Species.HELIOPTILE, Species.ELECTRIKE, Species.SKRELP, Species.PANCHAM, Species.PURRLOIN, Species.POOCHYENA, Species.BINACLE, Species.CLAUNCHER, Species.PUMPKABOO, Species.PHANTUMP, Species.FOONGUS ], [TrainerPoolTier.RARE]: [ Species.LITWICK, Species.SNEASEL, Species.PAWNIARD, Species.SLIGGOO ], - [TrainerPoolTier.SUPER_RARE]: [ Species.NOIVERN, Species.HISUI_SLIGGOO, Species.HISUI_AVALUGG ] + [TrainerPoolTier.SUPER_RARE]: [ Species.NOIBAT, Species.HISUI_SLIGGOO, Species.HISUI_AVALUGG ] }), [TrainerType.BRYONY]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("flare_admin_female", "flare", [ Species.LIEPARD ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_flare_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), [TrainerType.XEROSIC]: new TrainerConfig(++t).setMoneyMultiplier(1.5).initForEvilTeamAdmin("flare_admin", "flare", [ Species.MALAMAR ]).setEncounterBgm(TrainerType.PLASMA_GRUNT).setBattleBgm("battle_plasma_grunt").setMixedBattleBgm("battle_flare_grunt").setVictoryBgm("victory_team_plasma").setPartyTemplateFunc(scene => getEvilGruntPartyTemplate(scene)), @@ -1893,7 +1893,10 @@ export const trainerConfigs: TrainerConfigs = { }), [TrainerType.ROCKET_BOSS_GIOVANNI_1]: new TrainerConfig(t = TrainerType.ROCKET_BOSS_GIOVANNI_1).setName("Giovanni").initForEvilTeamLeader("Rocket Boss", []).setMixedBattleBgm("battle_rocket_boss").setVictoryBgm("victory_team_plasma") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.PERSIAN, Species.ALOLA_PERSIAN ])) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.PERSIAN, Species.ALOLA_PERSIAN ], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + p.gender = Gender.MALE; + })) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.DUGTRIO, Species.ALOLA_DUGTRIO ])) .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.HONCHKROW ])) .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.NIDOKING, Species.NIDOQUEEN ])) @@ -1945,6 +1948,7 @@ export const trainerConfigs: TrainerConfigs = { p.pokeball = PokeballType.ULTRA_BALL; p.formIndex = 1; // Mega Camerupt p.generateName(); + p.gender = Gender.MALE; })), [TrainerType.MAXIE_2]: new TrainerConfig(++t).setName("Maxie").initForEvilTeamLeader("Magma Boss", [], true).setMixedBattleBgm("battle_aqua_magma_boss").setVictoryBgm("victory_team_plasma") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.SOLROCK, Species.TYPHLOSION ], TrainerSlot.TRAINER, true, p => { @@ -1967,6 +1971,7 @@ export const trainerConfigs: TrainerConfigs = { p.pokeball = PokeballType.ULTRA_BALL; p.formIndex = 1; // Mega Camerupt p.generateName(); + p.gender = Gender.MALE; })) .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.GROUDON ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); @@ -1985,6 +1990,7 @@ export const trainerConfigs: TrainerConfigs = { p.pokeball = PokeballType.ULTRA_BALL; p.formIndex = 1; // Mega Sharpedo p.generateName(); + p.gender = Gender.MALE; })), [TrainerType.ARCHIE_2]: new TrainerConfig(++t).setName("Archie").initForEvilTeamLeader("Aqua Boss", [], true).setMixedBattleBgm("battle_aqua_magma_boss").setVictoryBgm("victory_team_plasma") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.EMPOLEON, Species.LUDICOLO ], TrainerSlot.TRAINER, true, p => { @@ -2010,6 +2016,7 @@ export const trainerConfigs: TrainerConfigs = { p.pokeball = PokeballType.ULTRA_BALL; p.formIndex = 1; // Mega Sharpedo p.generateName(); + p.gender = Gender.MALE; })) .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.KYOGRE ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); @@ -2031,6 +2038,7 @@ export const trainerConfigs: TrainerConfigs = { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; + p.gender = Gender.MALE; })), [TrainerType.CYRUS_2]: new TrainerConfig(++t).setName("Cyrus").initForEvilTeamLeader("Galactic Boss", [], true).setMixedBattleBgm("battle_galactic_boss").setVictoryBgm("victory_team_plasma") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.AZELF, Species.UXIE, Species.MESPRIT ], TrainerSlot.TRAINER, true, p => { @@ -2049,6 +2057,7 @@ export const trainerConfigs: TrainerConfigs = { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; + p.gender = Gender.MALE; })) .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.DARKRAI ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); @@ -2065,6 +2074,7 @@ export const trainerConfigs: TrainerConfigs = { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; + p.gender = Gender.MALE; })), [TrainerType.GHETSIS_2]: new TrainerConfig(++t).setName("Ghetsis").initForEvilTeamLeader("Plasma Boss", [], true).setMixedBattleBgm("battle_plasma_boss").setVictoryBgm("victory_team_plasma") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.GENESECT ], TrainerSlot.TRAINER, true, p => { @@ -2084,6 +2094,11 @@ export const trainerConfigs: TrainerConfigs = { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; + if (p.species.speciesId === Species.HYDREIGON) { + p.gender = Gender.MALE; + } else if (p.species.speciesId === Species.IRON_JUGULIS) { + p.gender = Gender.GENDERLESS; + } })) .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.KYUREM ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); @@ -2105,6 +2120,7 @@ export const trainerConfigs: TrainerConfigs = { p.pokeball = PokeballType.ULTRA_BALL; p.formIndex = 1; // Mega Gyarados p.generateName(); + p.gender = Gender.MALE; })), [TrainerType.LYSANDRE_2]: new TrainerConfig(++t).setName("Lysandre").initForEvilTeamLeader("Flare Boss", [], true).setMixedBattleBgm("battle_flare_boss").setVictoryBgm("victory_team_plasma") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.SCREAM_TAIL, Species.FLUTTER_MANE ], TrainerSlot.TRAINER, true, p => { @@ -2124,6 +2140,7 @@ export const trainerConfigs: TrainerConfigs = { p.pokeball = PokeballType.ULTRA_BALL; p.formIndex = 1; // Mega Gyardos p.generateName(); + p.gender = Gender.MALE; })) .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.YVELTAL ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); @@ -2131,7 +2148,10 @@ export const trainerConfigs: TrainerConfigs = { p.pokeball = PokeballType.MASTER_BALL; })), [TrainerType.LUSAMINE]: new TrainerConfig(++t).setName("Lusamine").initForEvilTeamLeader("Aether Boss", []).setMixedBattleBgm("battle_aether_boss").setVictoryBgm("victory_team_plasma") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.CLEFABLE ])) + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.CLEFABLE ], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + p.gender = Gender.FEMALE; + })) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.LILLIGANT, Species.HISUI_LILLIGANT ])) .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.MILOTIC, Species.PRIMARINA ])) .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.GALAR_SLOWBRO, Species.GALAR_SLOWKING ])) @@ -2148,7 +2168,10 @@ export const trainerConfigs: TrainerConfigs = { p.pokeball = PokeballType.ROGUE_BALL; })) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.MILOTIC, Species.PRIMARINA ])) - .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.CLEFABLE ])) + .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.CLEFABLE ], TrainerSlot.TRAINER, true, p => { + p.generateAndPopulateMoveset(); + p.gender = Gender.FEMALE; + })) .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.STAKATAKA, Species.CELESTEELA, Species.GUZZLORD ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ROGUE_BALL; @@ -2191,6 +2214,7 @@ export const trainerConfigs: TrainerConfigs = { .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.GOLISOPOD ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); p.generateAndPopulateMoveset(); + p.gender = Gender.MALE; p.pokeball = PokeballType.ULTRA_BALL; })), [TrainerType.GUZMA_2]: new TrainerConfig(++t).setName("Guzma").initForEvilTeamLeader("Skull Boss", [], true).setMixedBattleBgm("battle_skull_boss").setVictoryBgm("victory_team_plasma") @@ -2198,6 +2222,7 @@ export const trainerConfigs: TrainerConfigs = { p.setBoss(true, 2); p.generateAndPopulateMoveset(); p.abilityIndex = 2; //Anticipation + p.gender = Gender.MALE; p.pokeball = PokeballType.ULTRA_BALL; })) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.SCIZOR, Species.KLEAVOR ], TrainerSlot.TRAINER, true, p => { @@ -2239,6 +2264,7 @@ export const trainerConfigs: TrainerConfigs = { p.formIndex = 1; // G-Max Copperajah p.generateName(); p.pokeball = PokeballType.ULTRA_BALL; + p.gender = Gender.FEMALE; })), [TrainerType.ROSE_2]: new TrainerConfig(++t).setName("Rose").initForEvilTeamLeader("Macro Boss", [], true).setMixedBattleBgm("battle_macro_boss").setVictoryBgm("victory_team_plasma") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.ARCHALUDON ], TrainerSlot.TRAINER, true, p => { @@ -2262,6 +2288,7 @@ export const trainerConfigs: TrainerConfigs = { p.formIndex = 1; // G-Max Copperajah p.generateName(); p.pokeball = PokeballType.ULTRA_BALL; + p.gender = Gender.FEMALE; })), [TrainerType.PENNY]: new TrainerConfig(++t).setName("Cassiopeia").initForEvilTeamLeader("Star Boss", []).setMixedBattleBgm("battle_star_boss").setVictoryBgm("victory_team_plasma") .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VAPOREON, Species.JOLTEON, Species.FLAREON ])) @@ -2275,8 +2302,9 @@ export const trainerConfigs: TrainerConfigs = { p.formIndex = Utils.randSeedInt(5, 1); // Heat, Wash, Frost, Fan, or Mow })) .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.SYLVEON ], TrainerSlot.TRAINER, true, p => { - p.generateAndPopulateMoveset(); p.abilityIndex = 2; // Pixilate + p.generateAndPopulateMoveset(); + p.gender = Gender.FEMALE; })) .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.EEVEE ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); @@ -2290,20 +2318,21 @@ export const trainerConfigs: TrainerConfigs = { return [ modifierTypes.TERA_SHARD().generateType([], [ teraPokemon.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; //TODO: is the bang correct? }), [TrainerType.PENNY_2]: new TrainerConfig(++t).setName("Cassiopeia").initForEvilTeamLeader("Star Boss", [], true).setMixedBattleBgm("battle_star_boss").setVictoryBgm("victory_team_plasma") - .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.REVAVROOM ], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.SYLVEON ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); - p.formIndex = Utils.randSeedInt(5, 1); //Random Starmobile form + p.abilityIndex = 2; // Pixilate p.generateAndPopulateMoveset(); - p.pokeball = PokeballType.ULTRA_BALL; + p.gender = Gender.FEMALE; })) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.ENTEI, Species.RAIKOU, Species.SUICUNE ], TrainerSlot.TRAINER, true, p => { p.generateAndPopulateMoveset(); p.pokeball = PokeballType.ULTRA_BALL; })) .setPartyMemberFunc(2, getRandomPartyMemberFunc([ Species.WALKING_WAKE, Species.GOUGING_FIRE, Species.RAGING_BOLT ])) - .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.SYLVEON ], TrainerSlot.TRAINER, true, p => { + .setPartyMemberFunc(3, getRandomPartyMemberFunc([ Species.REVAVROOM ], TrainerSlot.TRAINER, true, p => { + p.formIndex = Utils.randSeedInt(5, 1); //Random Starmobile form p.generateAndPopulateMoveset(); - p.abilityIndex = 2; // Pixilate + p.pokeball = PokeballType.ROGUE_BALL; })) .setPartyMemberFunc(4, getRandomPartyMemberFunc([ Species.EEVEE ], TrainerSlot.TRAINER, true, p => { p.setBoss(true, 2); @@ -2318,7 +2347,7 @@ export const trainerConfigs: TrainerConfigs = { p.pokeball = PokeballType.MASTER_BALL; })) .setGenModifiersFunc(party => { - const teraPokemon = party[3]; + const teraPokemon = party[0]; return [ modifierTypes.TERA_SHARD().generateType([], [ teraPokemon.species.type1 ])!.withIdFromFunc(modifierTypes.TERA_SHARD).newModifier(teraPokemon) as PersistentModifier ]; //TODO: is the bang correct? }), [TrainerType.BUCK]: new TrainerConfig(++t).setName("Buck").initForStatTrainer([], true) From d5f87bbea76428677003276c033cf07beb85c151 Mon Sep 17 00:00:00 2001 From: innerthunder <168692175+innerthunder@users.noreply.github.com> Date: Tue, 15 Oct 2024 07:02:02 -0700 Subject: [PATCH 34/37] [P3][Beta] Fix missing move text when a move fails (#4664) * Fix missing move text when a move fails * Use `cancel` function instead of setting `this.cancelled` --- src/phases/move-phase.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/phases/move-phase.ts b/src/phases/move-phase.ts index d3a2a3329fd..f50cfbd78ac 100644 --- a/src/phases/move-phase.ts +++ b/src/phases/move-phase.ts @@ -147,8 +147,9 @@ export class MovePhase extends BattlePhase { const moveQueue = this.pokemon.getMoveQueue(); if (targets.length === 0 || (moveQueue.length && moveQueue[0].move === Moves.NONE)) { + this.showMoveText(); this.showFailedText(); - this.cancelled = true; + this.cancel(); } } From 21b71595e0292a6a30503dc9d93905c8ade179bc Mon Sep 17 00:00:00 2001 From: PrabbyDD <147005742+PrabbyDD@users.noreply.github.com> Date: Tue, 15 Oct 2024 07:04:26 -0700 Subject: [PATCH 35/37] [P2] Attacks that miss against pokemon in semi invul state that have abilities such as volt absorb will not trigger (#4663) * fixing issue where abilities trigger in semi invul state * fixing targets --- src/phases/move-effect-phase.ts | 10 ++++++---- src/test/abilities/volt_absorb.test.ts | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index 581cd5ff017..e9bff882367 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -99,8 +99,9 @@ export class MoveEffectPhase extends PokemonPhase { const targetHitChecks = Object.fromEntries(targets.map(p => [ p.getBattlerIndex(), this.hitCheck(p) ])); const hasActiveTargets = targets.some(t => t.isActive(true)); - /** Check if the target is immune via ability to the attacking move */ - const isImmune = targets[0].hasAbilityWithAttr(TypeImmunityAbAttr) && (targets[0].getAbility()?.getAttrs(TypeImmunityAbAttr)?.[0]?.getImmuneType() === user.getMoveType(move)); + /** Check if the target is immune via ability to the attacking move, and NOT in semi invulnerable state */ + const isImmune = targets[0].hasAbilityWithAttr(TypeImmunityAbAttr) && (targets[0].getAbility()?.getAttrs(TypeImmunityAbAttr)?.[0]?.getImmuneType() === user.getMoveType(move)) + && !targets[0].getTag(SemiInvulnerableTag); /** * If no targets are left for the move to hit (FAIL), or the invoked move is single-target @@ -148,8 +149,9 @@ export class MoveEffectPhase extends PokemonPhase { && (hasConditionalProtectApplied.value || (!target.findTags(t => t instanceof DamageProtectedTag).length && target.findTags(t => t instanceof ProtectedTag).find(t => target.lapseTag(t.tagType))) || (this.move.getMove().category !== MoveCategory.STATUS && target.findTags(t => t instanceof DamageProtectedTag).find(t => target.lapseTag(t.tagType)))); - /** Is the pokemon immune due to an ablility? */ - const isImmune = target.hasAbilityWithAttr(TypeImmunityAbAttr) && (target.getAbility()?.getAttrs(TypeImmunityAbAttr)?.[0]?.getImmuneType() === user.getMoveType(move)); + /** Is the pokemon immune due to an ablility, and also not in a semi invulnerable state? */ + const isImmune = target.hasAbilityWithAttr(TypeImmunityAbAttr) && (target.getAbility()?.getAttrs(TypeImmunityAbAttr)?.[0]?.getImmuneType() === user.getMoveType(move)) + && !target.getTag(SemiInvulnerableTag); /** * If the move missed a target, stop all future hits against that target diff --git a/src/test/abilities/volt_absorb.test.ts b/src/test/abilities/volt_absorb.test.ts index 07907a34566..ec82b00ec5a 100644 --- a/src/test/abilities/volt_absorb.test.ts +++ b/src/test/abilities/volt_absorb.test.ts @@ -71,4 +71,23 @@ describe("Abilities - Volt Absorb", () => { await game.phaseInterceptor.to("BerryPhase", false); expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); }); + it("regardless of accuracy should not trigger on pokemon in semi invulnerable state", async () => { + game.override.moveset(Moves.THUNDERBOLT); + game.override.enemyMoveset(Moves.DIVE); + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyAbility(Abilities.VOLT_ABSORB); + + await game.classicMode.startBattle(); + + const enemyPokemon = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.THUNDERBOLT); + enemyPokemon.hp = enemyPokemon.hp - 1; + await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]); + await game.phaseInterceptor.to("MoveEffectPhase"); + + await game.move.forceMiss(); + await game.phaseInterceptor.to("BerryPhase", false); + expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); + }); }); From d01d85689833dea8acb023478e42b6f6d0b2cef2 Mon Sep 17 00:00:00 2001 From: Mumble <171087428+frutescens@users.noreply.github.com> Date: Tue, 15 Oct 2024 07:05:21 -0700 Subject: [PATCH 36/37] [Refactor] Default case to display challenge name (#4656) Co-authored-by: frutescens --- src/ui/run-info-ui-handler.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ui/run-info-ui-handler.ts b/src/ui/run-info-ui-handler.ts index 39927f8e071..1976d5a997b 100644 --- a/src/ui/run-info-ui-handler.ts +++ b/src/ui/run-info-ui-handler.ts @@ -587,13 +587,13 @@ export default class RunInfoUiHandler extends UiHandler { const typeText = typeTextColor + typeShadowColor + i18next.t(`pokemonInfo:Type.${typeRule}`)! + "[/color]" + "[/shadow]"; rules.push(typeText); break; - case Challenges.FRESH_START: - rules.push(i18next.t("challenges:freshStart.name")); - break; case Challenges.INVERSE_BATTLE: - // rules.push(i18next.t("challenges:inverseBattle.shortName")); break; + default: + const localisationKey = Challenges[this.runInfo.challenges[i].id].split("_").map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join(""); + rules.push(i18next.t(`challenges:${localisationKey}.name`)); + break; } } } From 196633562775b04920956d913c5059ddb9f39a31 Mon Sep 17 00:00:00 2001 From: innerthunder <168692175+innerthunder@users.noreply.github.com> Date: Tue, 15 Oct 2024 10:13:54 -0700 Subject: [PATCH 37/37] [Refactor] Add type inference and support for simulated calls to `ArenaTag.apply` (#4659) * Add simulated support for Arena Tag application * Add type inference to ArenaTag.apply * Fix screen tests * back to `any` again lol * fix missing spread syntax (maybe) * updated docs * named imports for `Utils` --- src/data/arena-tag.ts | 189 ++++++++++++++++---------- src/data/move.ts | 4 +- src/field/arena.ts | 10 +- src/field/pokemon.ts | 4 +- src/phases/move-effect-phase.ts | 2 +- src/phases/post-summon-phase.ts | 2 +- src/phases/stat-stage-change-phase.ts | 3 +- src/phases/turn-start-phase.ts | 2 +- src/test/moves/aurora_veil.test.ts | 2 +- src/test/moves/light_screen.test.ts | 2 +- src/test/moves/reflect.test.ts | 2 +- 11 files changed, 135 insertions(+), 87 deletions(-) diff --git a/src/data/arena-tag.ts b/src/data/arena-tag.ts index 71cf11fa06f..2bd6ae09877 100644 --- a/src/data/arena-tag.ts +++ b/src/data/arena-tag.ts @@ -1,7 +1,7 @@ import { Arena } from "#app/field/arena"; import BattleScene from "#app/battle-scene"; import { Type } from "#app/data/type"; -import * as Utils from "#app/utils"; +import { BooleanHolder, NumberHolder, toDmgValue } from "#app/utils"; import { MoveCategory, allMoves, MoveTarget, IncrementMovePriorityAttr, applyMoveAttrs } from "#app/data/move"; import { getPokemonNameWithAffix } from "#app/messages"; import Pokemon, { HitResult, PokemonMove } from "#app/field/pokemon"; @@ -36,7 +36,7 @@ export abstract class ArenaTag { public side: ArenaTagSide = ArenaTagSide.BOTH ) {} - apply(arena: Arena, args: any[]): boolean { + apply(arena: Arena, simulated: boolean, ...args: unknown[]): boolean { return true; } @@ -122,10 +122,20 @@ export class MistTag extends ArenaTag { } } - apply(arena: Arena, args: any[]): boolean { - (args[0] as Utils.BooleanHolder).value = true; + /** + * Cancels the lowering of stats + * @param arena the {@linkcode Arena} containing this effect + * @param simulated `true` if the effect should be applied quietly + * @param cancelled a {@linkcode BooleanHolder} whose value is set to `true` + * to flag the stat reduction as cancelled + * @returns `true` if a stat reduction was cancelled; `false` otherwise + */ + override apply(arena: Arena, simulated: boolean, cancelled: BooleanHolder): boolean { + cancelled.value = true; - arena.scene.queueMessage(i18next.t("arenaTag:mistApply")); + if (!simulated) { + arena.scene.queueMessage(i18next.t("arenaTag:mistApply")); + } return true; } @@ -157,17 +167,15 @@ export class WeakenMoveScreenTag extends ArenaTag { /** * Applies the weakening effect to the move. * - * @param arena - The arena where the move is applied. - * @param args - The arguments for the move application. - * @param args[0] - The category of the move. - * @param args[1] - A boolean indicating whether it is a double battle. - * @param args[2] - An object of type `Utils.NumberHolder` that holds the damage multiplier - * - * @returns True if the move was weakened, otherwise false. + * @param arena the {@linkcode Arena} where the move is applied. + * @param simulated n/a + * @param moveCategory the attacking move's {@linkcode MoveCategory}. + * @param damageMultiplier A {@linkcode NumberHolder} containing the damage multiplier + * @returns `true` if the attacking move was weakened; `false` otherwise. */ - apply(arena: Arena, args: any[]): boolean { - if (this.weakenedCategories.includes((args[0] as MoveCategory))) { - (args[2] as Utils.NumberHolder).value = (args[1] as boolean) ? 2732 / 4096 : 0.5; + override apply(arena: Arena, simulated: boolean, moveCategory: MoveCategory, damageMultiplier: NumberHolder): boolean { + if (this.weakenedCategories.includes(moveCategory)) { + damageMultiplier.value = arena.scene.currentBattle.double ? 2732 / 4096 : 0.5; return true; } return false; @@ -249,38 +257,34 @@ export class ConditionalProtectTag extends ArenaTag { onRemove(arena: Arena): void { } /** - * apply(): Checks incoming moves against the condition function + * Checks incoming moves against the condition function * and protects the target if conditions are met - * @param arena The arena containing this tag - * @param args\[0\] (Utils.BooleanHolder) Signals if the move is cancelled - * @param args\[1\] (Pokemon) The Pokemon using the move - * @param args\[2\] (Pokemon) The intended target of the move - * @param args\[3\] (Moves) The parameters to the condition function - * @param args\[4\] (Utils.BooleanHolder) Signals if the applied protection supercedes protection-ignoring effects - * @returns + * @param arena the {@linkcode Arena} containing this tag + * @param simulated `true` if the tag is applied quietly; `false` otherwise. + * @param isProtected a {@linkcode BooleanHolder} used to flag if the move is protected against + * @param attacker the attacking {@linkcode Pokemon} + * @param defender the defending {@linkcode Pokemon} + * @param moveId the {@linkcode Moves | identifier} for the move being used + * @param ignoresProtectBypass a {@linkcode BooleanHolder} used to flag if a protection effect supercedes effects that ignore protection + * @returns `true` if this tag protected against the attack; `false` otherwise */ - apply(arena: Arena, args: any[]): boolean { - const [ cancelled, user, target, moveId, ignoresBypass ] = args; + override apply(arena: Arena, simulated: boolean, isProtected: BooleanHolder, attacker: Pokemon, defender: Pokemon, + moveId: Moves, ignoresProtectBypass: BooleanHolder): boolean { - if (cancelled instanceof Utils.BooleanHolder - && user instanceof Pokemon - && target instanceof Pokemon - && typeof moveId === "number" - && ignoresBypass instanceof Utils.BooleanHolder) { + if ((this.side === ArenaTagSide.PLAYER) === defender.isPlayer() + && this.protectConditionFunc(arena, moveId)) { + if (!isProtected.value) { + isProtected.value = true; + if (!simulated) { + attacker.stopMultiHit(defender); - if ((this.side === ArenaTagSide.PLAYER) === target.isPlayer() - && this.protectConditionFunc(arena, moveId)) { - if (!cancelled.value) { - cancelled.value = true; - user.stopMultiHit(target); - - new CommonBattleAnim(CommonAnim.PROTECT, target).play(arena.scene); - arena.scene.queueMessage(i18next.t("arenaTag:conditionalProtectApply", { moveName: super.getMoveName(), pokemonNameWithAffix: getPokemonNameWithAffix(target) })); + new CommonBattleAnim(CommonAnim.PROTECT, defender).play(arena.scene); + arena.scene.queueMessage(i18next.t("arenaTag:conditionalProtectApply", { moveName: super.getMoveName(), pokemonNameWithAffix: getPokemonNameWithAffix(defender) })); } - - ignoresBypass.value = ignoresBypass.value || this.ignoresBypass; - return true; } + + ignoresProtectBypass.value = ignoresProtectBypass.value || this.ignoresBypass; + return true; } return false; } @@ -296,7 +300,7 @@ export class ConditionalProtectTag extends ArenaTag { */ const QuickGuardConditionFunc: ProtectConditionFunc = (arena, moveId) => { const move = allMoves[moveId]; - const priority = new Utils.NumberHolder(move.priority); + const priority = new NumberHolder(move.priority); const effectPhase = arena.scene.getCurrentPhase(); if (effectPhase instanceof MoveEffectPhase) { @@ -460,7 +464,7 @@ class WishTag extends ArenaTag { if (user) { this.battlerIndex = user.getBattlerIndex(); this.triggerMessage = i18next.t("arenaTag:wishTagOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(user) }); - this.healHp = Utils.toDmgValue(user.getMaxHp() / 2); + this.healHp = toDmgValue(user.getMaxHp() / 2); } else { console.warn("Failed to get source for WishTag onAdd"); } @@ -497,12 +501,19 @@ export class WeakenMoveTypeTag extends ArenaTag { this.weakenedType = type; } - apply(arena: Arena, args: any[]): boolean { - if ((args[0] as Type) === this.weakenedType) { - (args[1] as Utils.NumberHolder).value *= 0.33; + /** + * Reduces an attack's power by 0.33x if it matches this tag's weakened type. + * @param arena n/a + * @param simulated n/a + * @param type the attack's {@linkcode Type} + * @param power a {@linkcode NumberHolder} containing the attack's power + * @returns `true` if the attack's power was reduced; `false` otherwise. + */ + override apply(arena: Arena, simulated: boolean, type: Type, power: NumberHolder): boolean { + if (type === this.weakenedType) { + power.value *= 0.33; return true; } - return false; } } @@ -563,13 +574,12 @@ export class IonDelugeTag extends ArenaTag { /** * Converts Normal-type moves to Electric type * @param arena n/a - * @param args - * - `[0]` {@linkcode Utils.NumberHolder} A container with a move's {@linkcode Type} + * @param simulated n/a + * @param moveType a {@linkcode NumberHolder} containing a move's {@linkcode Type} * @returns `true` if the given move type changed; `false` otherwise. */ - apply(arena: Arena, args: any[]): boolean { - const moveType = args[0]; - if (moveType instanceof Utils.NumberHolder && moveType.value === Type.NORMAL) { + override apply(arena: Arena, simulated: boolean, moveType: NumberHolder): boolean { + if (moveType.value === Type.NORMAL) { moveType.value = Type.ELECTRIC; return true; } @@ -608,16 +618,22 @@ export class ArenaTrapTag extends ArenaTag { } } - apply(arena: Arena, args: any[]): boolean { - const pokemon = args[0] as Pokemon; + /** + * Activates the hazard effect onto a Pokemon when it enters the field + * @param arena the {@linkcode Arena} containing this tag + * @param simulated if `true`, only checks if the hazard would activate. + * @param pokemon the {@linkcode Pokemon} triggering this hazard + * @returns `true` if this hazard affects the given Pokemon; `false` otherwise. + */ + override apply(arena: Arena, simulated: boolean, pokemon: Pokemon): boolean { if (this.sourceId === pokemon.id || (this.side === ArenaTagSide.PLAYER) !== pokemon.isPlayer()) { return false; } - return this.activateTrap(pokemon); + return this.activateTrap(pokemon, simulated); } - activateTrap(pokemon: Pokemon): boolean { + activateTrap(pokemon: Pokemon, simulated: boolean): boolean { return false; } @@ -651,14 +667,18 @@ class SpikesTag extends ArenaTrapTag { } } - activateTrap(pokemon: Pokemon): boolean { + override activateTrap(pokemon: Pokemon, simulated: boolean): boolean { if (pokemon.isGrounded()) { - const cancelled = new Utils.BooleanHolder(false); + 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 = Utils.toDmgValue(pokemon.getMaxHp() * damageHpRatio); + const damage = toDmgValue(pokemon.getMaxHp() * damageHpRatio); pokemon.scene.queueMessage(i18next.t("arenaTag:spikesActivateTrap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); pokemon.damageAndUpdate(damage, HitResult.OTHER); @@ -702,8 +722,11 @@ class ToxicSpikesTag extends ArenaTrapTag { } } - activateTrap(pokemon: Pokemon): boolean { + override activateTrap(pokemon: Pokemon, simulated: boolean): boolean { if (pokemon.isGrounded()) { + if (simulated) { + return true; + } if (pokemon.isOfType(Type.POISON)) { this.neutralized = true; if (pokemon.scene.arena.removeTag(this.tagType)) { @@ -807,8 +830,8 @@ class StealthRockTag extends ArenaTrapTag { return damageHpRatio; } - activateTrap(pokemon: Pokemon): boolean { - const cancelled = new Utils.BooleanHolder(false); + override activateTrap(pokemon: Pokemon, simulated: boolean): boolean { + const cancelled = new BooleanHolder(false); applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled); if (cancelled.value) { @@ -818,12 +841,16 @@ class StealthRockTag extends ArenaTrapTag { const damageHpRatio = this.getDamageHpRatio(pokemon); if (damageHpRatio) { - const damage = Utils.toDmgValue(pokemon.getMaxHp() * damageHpRatio); + if (simulated) { + return true; + } + const damage = toDmgValue(pokemon.getMaxHp() * damageHpRatio); pokemon.scene.queueMessage(i18next.t("arenaTag:stealthRockActivateTrap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); pokemon.damageAndUpdate(damage, HitResult.OTHER); if (pokemon.turnData) { pokemon.turnData.damageTaken += damage; } + return true; } return false; @@ -853,14 +880,20 @@ class StickyWebTag extends ArenaTrapTag { } } - activateTrap(pokemon: Pokemon): boolean { + override activateTrap(pokemon: Pokemon, simulated: boolean): boolean { if (pokemon.isGrounded()) { - const cancelled = new Utils.BooleanHolder(false); + const cancelled = new BooleanHolder(false); applyAbAttrs(ProtectStatAbAttr, pokemon, cancelled); + + if (simulated) { + return !cancelled.value; + } + if (!cancelled.value) { pokemon.scene.queueMessage(i18next.t("arenaTag:stickyWebActivateTrap", { pokemonName: pokemon.getNameToRender() })); - const stages = new Utils.NumberHolder(-1); + const stages = new NumberHolder(-1); pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), false, [ Stat.SPD ], stages.value)); + return true; } } @@ -879,8 +912,15 @@ export class TrickRoomTag extends ArenaTag { super(ArenaTagType.TRICK_ROOM, turnCount, Moves.TRICK_ROOM, sourceId); } - apply(arena: Arena, args: any[]): boolean { - const speedReversed = args[0] as Utils.BooleanHolder; + /** + * Reverses Speed-based turn order for all Pokemon on the field + * @param arena n/a + * @param simulated n/a + * @param speedReversed a {@linkcode BooleanHolder} used to flag if Speed-based + * turn order should be reversed. + * @returns `true` if turn order is successfully reversed; `false` otherwise + */ + override apply(arena: Arena, simulated: boolean, speedReversed: BooleanHolder): boolean { speedReversed.value = !speedReversed.value; return true; } @@ -1087,7 +1127,7 @@ class FireGrassPledgeTag extends ArenaTag { pokemon.scene.queueMessage(i18next.t("arenaTag:fireGrassPledgeLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); // TODO: Replace this with a proper animation pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.MAGMA_STORM)); - pokemon.damageAndUpdate(Utils.toDmgValue(pokemon.getMaxHp() / 8)); + pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 8)); }); return super.lapse(arena); @@ -1111,8 +1151,15 @@ class WaterFirePledgeTag extends ArenaTag { arena.scene.queueMessage(i18next.t(`arenaTag:waterFirePledgeOnAdd${this.side === ArenaTagSide.PLAYER ? "Player" : this.side === ArenaTagSide.ENEMY ? "Enemy" : ""}`)); } - override apply(arena: Arena, args: any[]): boolean { - const moveChance = args[0] as Utils.NumberHolder; + /** + * Doubles the chance for the given move's secondary effect(s) to trigger + * @param arena the {@linkcode Arena} containing this tag + * @param simulated n/a + * @param moveChance a {@linkcode NumberHolder} containing + * the move's current effect chance + * @returns `true` if the move's effect chance was doubled (currently always `true`) + */ + override apply(arena: Arena, simulated: boolean, moveChance: NumberHolder): boolean { moveChance.value *= 2; return true; } diff --git a/src/data/move.ts b/src/data/move.ts index 2d91363955a..b0078c32f12 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -808,7 +808,7 @@ export default class Move implements Localizable { source.scene.applyModifiers(PokemonMultiHitModifier, source.isPlayer(), source, new Utils.IntegerHolder(0), power); if (!this.hasAttr(TypelessAttr)) { - source.scene.arena.applyTags(WeakenMoveTypeTag, this.type, power); + source.scene.arena.applyTags(WeakenMoveTypeTag, simulated, this.type, power); source.scene.applyModifiers(AttackTypeBoosterModifier, source.isPlayer(), source, this.type, power); } @@ -1026,7 +1026,7 @@ export class MoveEffectAttr extends MoveAttr { if (!move.hasAttr(FlinchAttr) || moveChance.value <= move.chance) { const userSide = user.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; - user.scene.arena.applyTagsForSide(ArenaTagType.WATER_FIRE_PLEDGE, userSide, moveChance); + user.scene.arena.applyTagsForSide(ArenaTagType.WATER_FIRE_PLEDGE, userSide, false, moveChance); } if (!selfEffect) { diff --git a/src/field/arena.ts b/src/field/arena.ts index 1e164903e9d..ad1846884fc 100644 --- a/src/field/arena.ts +++ b/src/field/arena.ts @@ -579,26 +579,28 @@ export class Arena { * Applies each `ArenaTag` in this Arena, based on which side (self, enemy, or both) is passed in as a parameter * @param tagType Either an {@linkcode ArenaTagType} string, or an actual {@linkcode ArenaTag} class to filter which ones to apply * @param side {@linkcode ArenaTagSide} which side's arena tags to apply + * @param simulated if `true`, this applies arena tags without changing game state * @param args array of parameters that the called upon tags may need */ - applyTagsForSide(tagType: ArenaTagType | Constructor, side: ArenaTagSide, ...args: unknown[]): void { + applyTagsForSide(tagType: ArenaTagType | Constructor, side: ArenaTagSide, simulated: boolean, ...args: unknown[]): void { let tags = typeof tagType === "string" ? this.tags.filter(t => t.tagType === tagType) : this.tags.filter(t => t instanceof tagType); if (side !== ArenaTagSide.BOTH) { tags = tags.filter(t => t.side === side); } - tags.forEach(t => t.apply(this, args)); + tags.forEach(t => t.apply(this, simulated, ...args)); } /** * Applies the specified tag to both sides (ie: both user and trainer's tag that match the Tag specified) * by calling {@linkcode applyTagsForSide()} * @param tagType Either an {@linkcode ArenaTagType} string, or an actual {@linkcode ArenaTag} class to filter which ones to apply + * @param simulated if `true`, this applies arena tags without changing game state * @param args array of parameters that the called upon tags may need */ - applyTags(tagType: ArenaTagType | Constructor, ...args: unknown[]): void { - this.applyTagsForSide(tagType, ArenaTagSide.BOTH, ...args); + applyTags(tagType: ArenaTagType | Constructor, simulated: boolean, ...args: unknown[]): void { + this.applyTagsForSide(tagType, ArenaTagSide.BOTH, simulated, ...args); } /** diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 0204672cabd..8eca37f38ac 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -1538,7 +1538,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { applyMoveAttrs(VariableMoveTypeAttr, this, null, move, moveTypeHolder); applyPreAttackAbAttrs(MoveTypeChangeAbAttr, this, null, move, simulated, moveTypeHolder); - this.scene.arena.applyTags(ArenaTagType.ION_DELUGE, moveTypeHolder); + this.scene.arena.applyTags(ArenaTagType.ION_DELUGE, simulated, moveTypeHolder); if (this.getTag(BattlerTagType.ELECTRIFIED)) { moveTypeHolder.value = Type.ELECTRIC; } @@ -2605,7 +2605,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { /** Reduces damage if this Pokemon has a relevant screen (e.g. Light Screen for special attacks) */ const screenMultiplier = new Utils.NumberHolder(1); - this.scene.arena.applyTagsForSide(WeakenMoveScreenTag, defendingSide, move.category, this.scene.currentBattle.double, screenMultiplier); + this.scene.arena.applyTagsForSide(WeakenMoveScreenTag, defendingSide, simulated, moveCategory, screenMultiplier); /** * For each {@linkcode HitsTagAttr} the move has, doubles the damage of the move if: diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index e9bff882367..dc880f85e23 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -141,7 +141,7 @@ export class MoveEffectPhase extends PokemonPhase { const bypassIgnoreProtect = new Utils.BooleanHolder(false); /** If the move is not targeting a Pokemon on the user's side, try to apply conditional protection effects */ if (!this.move.getMove().isAllyTarget()) { - this.scene.arena.applyTagsForSide(ConditionalProtectTag, targetSide, hasConditionalProtectApplied, user, target, move.id, bypassIgnoreProtect); + this.scene.arena.applyTagsForSide(ConditionalProtectTag, targetSide, false, hasConditionalProtectApplied, user, target, move.id, bypassIgnoreProtect); } /** Is the target protected by Protect, etc. or a relevant conditional protection effect? */ diff --git a/src/phases/post-summon-phase.ts b/src/phases/post-summon-phase.ts index b99c0b90fd8..617bb8b1cfe 100644 --- a/src/phases/post-summon-phase.ts +++ b/src/phases/post-summon-phase.ts @@ -20,7 +20,7 @@ export class PostSummonPhase extends PokemonPhase { if (pokemon.status?.effect === StatusEffect.TOXIC) { pokemon.status.turnCount = 0; } - this.scene.arena.applyTags(ArenaTrapTag, pokemon); + this.scene.arena.applyTags(ArenaTrapTag, false, pokemon); // If this is mystery encounter and has post summon phase tag, apply post summon effects if (this.scene.currentBattle.isBattleMysteryEncounter() && pokemon.findTags(t => t instanceof MysteryEncounterPostSummonTag).length > 0) { diff --git a/src/phases/stat-stage-change-phase.ts b/src/phases/stat-stage-change-phase.ts index bfe19ea9ca5..4c13b883445 100644 --- a/src/phases/stat-stage-change-phase.ts +++ b/src/phases/stat-stage-change-phase.ts @@ -64,8 +64,7 @@ export class StatStageChangePhase extends PokemonPhase { const cancelled = new BooleanHolder(false); if (!this.selfTarget && stages.value < 0) { - // TODO: Include simulate boolean when tag applications can be simulated - this.scene.arena.applyTagsForSide(MistTag, pokemon.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY, cancelled); + this.scene.arena.applyTagsForSide(MistTag, pokemon.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY, false, cancelled); } if (!cancelled.value && !this.selfTarget && stages.value < 0) { diff --git a/src/phases/turn-start-phase.ts b/src/phases/turn-start-phase.ts index 627cee4b06a..25c079007fd 100644 --- a/src/phases/turn-start-phase.ts +++ b/src/phases/turn-start-phase.ts @@ -45,7 +45,7 @@ export class TurnStartPhase extends FieldPhase { // Next, a check for Trick Room is applied to determine sort order. const speedReversed = new Utils.BooleanHolder(false); - this.scene.arena.applyTags(TrickRoomTag, speedReversed); + this.scene.arena.applyTags(TrickRoomTag, false, speedReversed); // Adjust the sort function based on whether Trick Room is active. orderedTargets.sort((a: Pokemon, b: Pokemon) => { diff --git a/src/test/moves/aurora_veil.test.ts b/src/test/moves/aurora_veil.test.ts index e71d4ab9d11..243ba3a3269 100644 --- a/src/test/moves/aurora_veil.test.ts +++ b/src/test/moves/aurora_veil.test.ts @@ -111,7 +111,7 @@ const getMockedMoveDamage = (defender: Pokemon, attacker: Pokemon, move: Move) = const side = defender.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; if (defender.scene.arena.getTagOnSide(ArenaTagType.AURORA_VEIL, side)) { - defender.scene.arena.applyTagsForSide(ArenaTagType.AURORA_VEIL, side, move.category, defender.scene.currentBattle.double, multiplierHolder); + defender.scene.arena.applyTagsForSide(ArenaTagType.AURORA_VEIL, side, false, move.category, multiplierHolder); } return move.power * multiplierHolder.value; diff --git a/src/test/moves/light_screen.test.ts b/src/test/moves/light_screen.test.ts index 2308458003d..11b8144bb4e 100644 --- a/src/test/moves/light_screen.test.ts +++ b/src/test/moves/light_screen.test.ts @@ -94,7 +94,7 @@ const getMockedMoveDamage = (defender: Pokemon, attacker: Pokemon, move: Move) = const side = defender.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; if (defender.scene.arena.getTagOnSide(ArenaTagType.LIGHT_SCREEN, side)) { - defender.scene.arena.applyTagsForSide(ArenaTagType.LIGHT_SCREEN, side, move.category, defender.scene.currentBattle.double, multiplierHolder); + defender.scene.arena.applyTagsForSide(ArenaTagType.LIGHT_SCREEN, side, false, move.category, multiplierHolder); } return move.power * multiplierHolder.value; diff --git a/src/test/moves/reflect.test.ts b/src/test/moves/reflect.test.ts index 41a10988552..b18b2423895 100644 --- a/src/test/moves/reflect.test.ts +++ b/src/test/moves/reflect.test.ts @@ -94,7 +94,7 @@ const getMockedMoveDamage = (defender: Pokemon, attacker: Pokemon, move: Move) = const side = defender.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY; if (defender.scene.arena.getTagOnSide(ArenaTagType.REFLECT, side)) { - defender.scene.arena.applyTagsForSide(ArenaTagType.REFLECT, side, move.category, defender.scene.currentBattle.double, multiplierHolder); + defender.scene.arena.applyTagsForSide(ArenaTagType.REFLECT, side, false, move.category, multiplierHolder); } return move.power * multiplierHolder.value;

v^J8bg(f%?PGJxL)) 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 literal 10686 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%0Dy!50Qvv` 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 diff --git a/public/images/pokemon/variant/6706_3.json b/public/images/pokemon/variant/6706_3.json deleted file mode 100644 index 615ca90e004..00000000000 --- a/public/images/pokemon/variant/6706_3.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "textures": [ - { - "image": "6706_3.png", - "format": "RGBA8888", - "size": { - "w": 82, - "h": 82 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 82, - "h": 72 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 82, - "h": 72 - }, - "frame": { - "x": 0, - "y": 0, - "w": 82, - "h": 72 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:02eb46aa66ac70df612e129b7801a85c:a77cca14b23f4f3aece64d1a82449a0f:d60cc2e5ae2bd18de8ee3ab0649593ee$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/6706_3.png b/public/images/pokemon/variant/6706_3.png deleted file mode 100644 index 001cab641f1c1c4009d6264baa14114a1a1b140c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5177 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%0Dy!50Qvv` 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%0Dy!50Qvv` z0D$NK0Cg|`0P0`>06Lfe02gqax=}m;000SaNLh0L01FZT01FZU(%pXi0000RbVXQn zQ*UN;cVTj607GSLb9r+hQ*?D?X>TA@Z*OeDr{R1600*W?L_t(|obB9iXjOF_$MN?K zD=OR8kcC>aS;8JjB}ud_gUaHL{!tVo3R^vppmISyh*C<89u#OM#2%E11YYTsvf;vLAetUqL~Fcd^Ycz6(bPl%hM_?`I5oZNc7y_2;Z+k(QY;oY zaBR2ljr7dxa)Qvn3|IVNg6-RPyVD!qe8#ukc@Hk*?+*@y0!HH10-Qt#)Zrf8|C(q0 z$Ij`byE_j++qFwPXzF&ug;Btd7zG%Lmo=PvNfMQyv$p`MaDsMx`h@2V_RQ;Y1P|br zcb;bFiWdT3bGR^StisrMP0bC?t?kbRzL0I=fCWW|EEWrFSiTaNfz#2z40n9`M6Rj1 z!2tphg8_#2VCY#1Jx0TbahH8(g*oA0HiWeJm$6V@NODut$|rDcf` zFAf}JjCX7Mb1q!azmN>9RGRY5yXc~Mv44)l1Q-_&{D86Xr0V3C3ImKAK{G*xEwjnk z^q>or1P;7-iB1?Q9{2&1rc|1;g0WpskKiSRgJ?Vx9E9Lyk+>j1>n}fk3V`pL&NXhg z{P-!7z?r%)K~=Y~q0x7toO2w9rsf9crLJAP|KY2tjzMaYRFY{M9Y+5HCxKI2Q)-3= zMp(0PwP)V?wOi@#&NDPH;^Ij^(1Qo?(NM4Tn+;0RT~Ob4Y zNzGSpKlL*?<=6gM7TvLMJz>lX!nxYaFZp&0(E>pa$;Ur_z zgT8s{u`diS3=X34)MMcKwOaw)GjCnsMI{I?3QiIQc;v*N0RHQ|tnkuamZUjWn(%Dl zB%gfL&0Y6x_d$kslBTv0?*l2PbPTPf`fEbcWC@506&hu=;AeA_zD242737U#s2>fo-N#=@uU2F z`OWV1$vrFG-S+DCS6MaCL&u`~dH90X@LP}nH@rQiD~`h(t^@E-+ozu80;lJ! z$Fqe4*qop1+HgoQwUr4TR30!%)xjCOw|hV4_UjkA>wW(15uV-sSN!pLYD)@gAI}yJ%zZvN z?#b>en3>=~ZST5c(}SKtJYflHlByL5#D;?m@t`t*W7C7|T=4>}?F%B;4eKtecuC-( z&hX;EL3C?=bAGOq6b`hzXSEDiDowFr`ATazm}%XcZW(5k%<&+5z*1?7_a5nry#W!lI4{$PzIY9@IYI(7*_HJaD6LzUi(Qq(clG&|S}fGBm?x zctzAxK4D3O2el0-t@gwH+kj}qpz(K634IPD3J~lNFFidoT;lgRcH{rj;Hmd0HuZJ7 z-4}p`4UNWKI__XdN$3+maR9-58FK0AL9Up8o;&@`A9>F*Fry{~G~vOS4l=;aZyob& zlLQVj!jqT~gYd#oAs(KbBviPKKW*~dd(b<`Nt&N}A|Kp~3n&rD#pmzO3@_+R3Nt5( z%N}~lomQ(3ye+7-ttg4rBcn+H0Sdc1U8G-+{msFXD}Z2BiHf(UbR~!Tw?#HT1yHX# ziFA-FiU-L7b-a$wUB>x>D!JuUqoG^jVK55k!a&sl&m{#jg4|XBc25;h+q7YE(!F#|(l4 z^Oq^;h=<0H27XyXxl&dehVPBA-LfGI{y6T_?@q#KS z46qt-P-Q&uqO`Uz2t4Qq;Z+L`Y7h_3+=B?)b%zV1y!Y>}s=+}G;K7*_i9P~KtwJ5I zniVIh2|S5@Hdb*=6`J(kLsqFNys((?!2U_^a-?qXAb9tN>QrG};Ymyv+q0EdXPL!I oky*SHnZ-+yS-cdP#Y>U@0GLZqmFWb_C;$Ke07*qoM6N<$g0>MU1ONa4 diff --git a/public/images/pokemon/variant/back/6706_3.json b/public/images/pokemon/variant/back/6706_3.json deleted file mode 100644 index 9a97ce27059..00000000000 --- a/public/images/pokemon/variant/back/6706_3.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "textures": [ - { - "image": "6706_3.png", - "format": "RGBA8888", - "size": { - "w": 79, - "h": 79 - }, - "scale": 1, - "frames": [ - { - "filename": "0001.png", - "rotated": false, - "trimmed": false, - "sourceSize": { - "w": 79, - "h": 73 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 79, - "h": 73 - }, - "frame": { - "x": 0, - "y": 0, - "w": 79, - "h": 73 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:64f7e6dfa489012922487e45ba53d557:4d24652b372939abe499497c4b6647b0:d60cc2e5ae2bd18de8ee3ab0649593ee$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/back/6706_3.png b/public/images/pokemon/variant/back/6706_3.png deleted file mode 100644 index fb780d01499a23a4f4ab714732d1d56d7e094f2d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4765 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%0Dy!50Qvv` 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 diff --git a/public/images/pokemon/variant/exp/6706.json b/public/images/pokemon/variant/exp/6706.json new file mode 100644 index 00000000000..2a5f8e112ee --- /dev/null +++ b/public/images/pokemon/variant/exp/6706.json @@ -0,0 +1,40 @@ +{ + "1": { + "566678": "0e6296", + "e0e4f4": "513981", + "625287": "4e4094", + "536273": "1f1233", + "988b98": "b24c86", + "36404c": "0c5474", + "c4cce1": "3b235c", + "e6d3e9": "f1a4c5", + "bfacc1": "da75a5", + "515f70": "197497", + "c5cee3": "63cee1", + "b791f2": "c7a1e5", + "8b93a6": "3aa8c4", + "80737f": "8a2166", + "4b454f": "6f1357", + "9170b9": "8b69c3", + "8e96aa": "301848" + }, + "2": { + "566678": "8e480b", + "e0e4f4": "176463", + "625287": "274159", + "536273": "02262c", + "988b98": "2a6563", + "36404c": "842401", + "c4cce1": "0d484a", + "e6d3e9": "9cead8", + "bfacc1": "5db6a9", + "515f70": "a34205", + "c5cee3": "f7af58", + "b791f2": "4a9699", + "8b93a6": "d27e26", + "80737f": "2b736f", + "4b454f": "194f51", + "9170b9": "2f667c", + "8e96aa": "073338" + } +} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/6706_2.json b/public/images/pokemon/variant/exp/6706_2.json deleted file mode 100644 index cb2ddfb1a12..00000000000 --- a/public/images/pokemon/variant/exp/6706_2.json +++ /dev/null @@ -1,2015 +0,0 @@ -{ - "textures": [ - { - "image": "6706_2.png", - "format": "RGBA8888", - "size": { - "w": 508, - "h": 508 - }, - "scale": 1, - "frames": [ - { - "filename": "0074.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 28, - "y": 26, - "w": 59, - "h": 61 - }, - "frame": { - "x": 0, - "y": 0, - "w": 59, - "h": 61 - } - }, - { - "filename": "0073.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 26, - "y": 25, - "w": 56, - "h": 63 - }, - "frame": { - "x": 59, - "y": 0, - "w": 56, - "h": 63 - } - }, - { - "filename": "0075.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 26, - "y": 25, - "w": 56, - "h": 63 - }, - "frame": { - "x": 59, - "y": 0, - "w": 56, - "h": 63 - } - }, - { - "filename": "0064.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 28, - "y": 21, - "w": 53, - "h": 65 - }, - "frame": { - "x": 115, - "y": 0, - "w": 53, - "h": 65 - } - }, - { - "filename": "0084.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 28, - "y": 21, - "w": 53, - "h": 65 - }, - "frame": { - "x": 115, - "y": 0, - "w": 53, - "h": 65 - } - }, - { - "filename": "0065.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 29, - "y": 21, - "w": 54, - "h": 65 - }, - "frame": { - "x": 168, - "y": 0, - "w": 54, - "h": 65 - } - }, - { - "filename": "0083.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 29, - "y": 21, - "w": 54, - "h": 65 - }, - "frame": { - "x": 168, - "y": 0, - "w": 54, - "h": 65 - } - }, - { - "filename": "0066.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 28, - "y": 21, - "w": 53, - "h": 65 - }, - "frame": { - "x": 222, - "y": 0, - "w": 53, - "h": 65 - } - }, - { - "filename": "0082.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 28, - "y": 21, - "w": 53, - "h": 65 - }, - "frame": { - "x": 222, - "y": 0, - "w": 53, - "h": 65 - } - }, - { - "filename": "0067.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 25, - "y": 21, - "w": 55, - "h": 66 - }, - "frame": { - "x": 275, - "y": 0, - "w": 55, - "h": 66 - } - }, - { - "filename": "0081.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 25, - "y": 21, - "w": 55, - "h": 66 - }, - "frame": { - "x": 275, - "y": 0, - "w": 55, - "h": 66 - } - }, - { - "filename": "0072.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 23, - "y": 23, - "w": 54, - "h": 66 - }, - "frame": { - "x": 330, - "y": 0, - "w": 54, - "h": 66 - } - }, - { - "filename": "0076.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 23, - "y": 23, - "w": 54, - "h": 66 - }, - "frame": { - "x": 330, - "y": 0, - "w": 54, - "h": 66 - } - }, - { - "filename": "0063.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 25, - "y": 21, - "w": 54, - "h": 67 - }, - "frame": { - "x": 384, - "y": 0, - "w": 54, - "h": 67 - } - }, - { - "filename": "0085.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 25, - "y": 21, - "w": 54, - "h": 67 - }, - "frame": { - "x": 384, - "y": 0, - "w": 54, - "h": 67 - } - }, - { - "filename": "0062.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 23, - "y": 21, - "w": 52, - "h": 68 - }, - "frame": { - "x": 438, - "y": 0, - "w": 52, - "h": 68 - } - }, - { - "filename": "0086.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 23, - "y": 21, - "w": 52, - "h": 68 - }, - "frame": { - "x": 438, - "y": 0, - "w": 52, - "h": 68 - } - }, - { - "filename": "0068.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 21, - "y": 21, - "w": 53, - "h": 68 - }, - "frame": { - "x": 0, - "y": 61, - "w": 53, - "h": 68 - } - }, - { - "filename": "0080.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 21, - "y": 21, - "w": 53, - "h": 68 - }, - "frame": { - "x": 0, - "y": 61, - "w": 53, - "h": 68 - } - }, - { - "filename": "0071.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 18, - "y": 22, - "w": 52, - "h": 68 - }, - "frame": { - "x": 53, - "y": 63, - "w": 52, - "h": 68 - } - }, - { - "filename": "0077.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 18, - "y": 22, - "w": 52, - "h": 68 - }, - "frame": { - "x": 53, - "y": 63, - "w": 52, - "h": 68 - } - }, - { - "filename": "0060.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 19, - "y": 21, - "w": 55, - "h": 69 - }, - "frame": { - "x": 105, - "y": 65, - "w": 55, - "h": 69 - } - }, - { - "filename": "0088.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 19, - "y": 21, - "w": 55, - "h": 69 - }, - "frame": { - "x": 105, - "y": 65, - "w": 55, - "h": 69 - } - }, - { - "filename": "0061.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 21, - "y": 21, - "w": 53, - "h": 69 - }, - "frame": { - "x": 160, - "y": 65, - "w": 53, - "h": 69 - } - }, - { - "filename": "0087.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 21, - "y": 21, - "w": 53, - "h": 69 - }, - "frame": { - "x": 160, - "y": 65, - "w": 53, - "h": 69 - } - }, - { - "filename": "0069.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 16, - "y": 21, - "w": 53, - "h": 69 - }, - "frame": { - "x": 213, - "y": 65, - "w": 53, - "h": 69 - } - }, - { - "filename": "0079.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 16, - "y": 21, - "w": 53, - "h": 69 - }, - "frame": { - "x": 213, - "y": 65, - "w": 53, - "h": 69 - } - }, - { - "filename": "0070.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 15, - "y": 21, - "w": 52, - "h": 70 - }, - "frame": { - "x": 266, - "y": 66, - "w": 52, - "h": 70 - } - }, - { - "filename": "0078.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 15, - "y": 21, - "w": 52, - "h": 70 - }, - "frame": { - "x": 266, - "y": 66, - "w": 52, - "h": 70 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 19, - "w": 87, - "h": 71 - }, - "frame": { - "x": 318, - "y": 67, - "w": 87, - "h": 71 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 19, - "w": 87, - "h": 71 - }, - "frame": { - "x": 318, - "y": 67, - "w": 87, - "h": 71 - } - }, - { - "filename": "0038.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 19, - "w": 87, - "h": 71 - }, - "frame": { - "x": 318, - "y": 67, - "w": 87, - "h": 71 - } - }, - { - "filename": "0051.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 18, - "w": 87, - "h": 71 - }, - "frame": { - "x": 405, - "y": 68, - "w": 87, - "h": 71 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 19, - "w": 86, - "h": 72 - }, - "frame": { - "x": 0, - "y": 131, - "w": 86, - "h": 72 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 19, - "w": 87, - "h": 72 - }, - "frame": { - "x": 86, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 86, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0036.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 86, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 19, - "w": 87, - "h": 72 - }, - "frame": { - "x": 173, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 173, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0037.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 173, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 260, - "y": 138, - "w": 87, - "h": 72 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 260, - "y": 138, - "w": 87, - "h": 72 - } - }, - { - "filename": "0039.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 260, - "y": 138, - "w": 87, - "h": 72 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 347, - "y": 139, - "w": 87, - "h": 72 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 347, - "y": 139, - "w": 87, - "h": 72 - } - }, - { - "filename": "0040.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 347, - "y": 139, - "w": 87, - "h": 72 - } - }, - { - "filename": "0059.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 74, - "h": 80 - }, - "frame": { - "x": 434, - "y": 139, - "w": 74, - "h": 80 - } - }, - { - "filename": "0089.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 74, - "h": 80 - }, - "frame": { - "x": 434, - "y": 139, - "w": 74, - "h": 80 - } - }, - { - "filename": "0050.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 85, - "h": 72 - }, - "frame": { - "x": 0, - "y": 203, - "w": 85, - "h": 72 - } - }, - { - "filename": "0052.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 13, - "w": 83, - "h": 72 - }, - "frame": { - "x": 85, - "y": 206, - "w": 83, - "h": 72 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 18, - "w": 84, - "h": 73 - }, - "frame": { - "x": 168, - "y": 206, - "w": 84, - "h": 73 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 85, - "h": 73 - }, - "frame": { - "x": 252, - "y": 210, - "w": 85, - "h": 73 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 337, - "y": 211, - "w": 86, - "h": 73 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 337, - "y": 211, - "w": 86, - "h": 73 - } - }, - { - "filename": "0041.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 337, - "y": 211, - "w": 86, - "h": 73 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 85, - "h": 73 - }, - "frame": { - "x": 423, - "y": 219, - "w": 85, - "h": 73 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 85, - "h": 73 - }, - "frame": { - "x": 423, - "y": 219, - "w": 85, - "h": 73 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 16, - "w": 85, - "h": 74 - }, - "frame": { - "x": 0, - "y": 275, - "w": 85, - "h": 74 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 16, - "w": 85, - "h": 74 - }, - "frame": { - "x": 0, - "y": 275, - "w": 85, - "h": 74 - } - }, - { - "filename": "0043.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 16, - "w": 85, - "h": 74 - }, - "frame": { - "x": 0, - "y": 275, - "w": 85, - "h": 74 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 85, - "y": 279, - "w": 86, - "h": 73 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 85, - "y": 279, - "w": 86, - "h": 73 - } - }, - { - "filename": "0042.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 85, - "y": 279, - "w": 86, - "h": 73 - } - }, - { - "filename": "0053.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 4, - "w": 81, - "h": 74 - }, - "frame": { - "x": 171, - "y": 279, - "w": 81, - "h": 74 - } - }, - { - "filename": "0095.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 4, - "w": 81, - "h": 74 - }, - "frame": { - "x": 171, - "y": 279, - "w": 81, - "h": 74 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 16, - "w": 84, - "h": 74 - }, - "frame": { - "x": 252, - "y": 283, - "w": 84, - "h": 74 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 16, - "w": 84, - "h": 74 - }, - "frame": { - "x": 252, - "y": 283, - "w": 84, - "h": 74 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 336, - "y": 284, - "w": 86, - "h": 73 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 336, - "y": 284, - "w": 86, - "h": 73 - } - }, - { - "filename": "0054.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 80, - "h": 74 - }, - "frame": { - "x": 422, - "y": 292, - "w": 80, - "h": 74 - } - }, - { - "filename": "0094.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 80, - "h": 74 - }, - "frame": { - "x": 422, - "y": 292, - "w": 80, - "h": 74 - } - }, - { - "filename": "0055.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 79, - "h": 74 - }, - "frame": { - "x": 0, - "y": 349, - "w": 79, - "h": 74 - } - }, - { - "filename": "0093.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 79, - "h": 74 - }, - "frame": { - "x": 0, - "y": 349, - "w": 79, - "h": 74 - } - }, - { - "filename": "0056.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 80, - "h": 74 - }, - "frame": { - "x": 79, - "y": 352, - "w": 80, - "h": 74 - } - }, - { - "filename": "0092.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 80, - "h": 74 - }, - "frame": { - "x": 79, - "y": 352, - "w": 80, - "h": 74 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 15, - "w": 83, - "h": 75 - }, - "frame": { - "x": 159, - "y": 353, - "w": 83, - "h": 75 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 15, - "w": 83, - "h": 75 - }, - "frame": { - "x": 159, - "y": 353, - "w": 83, - "h": 75 - } - }, - { - "filename": "0044.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 15, - "w": 83, - "h": 75 - }, - "frame": { - "x": 159, - "y": 353, - "w": 83, - "h": 75 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 242, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 242, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0045.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 242, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 323, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 323, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0047.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 323, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 82, - "h": 75 - }, - "frame": { - "x": 404, - "y": 366, - "w": 82, - "h": 75 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 82, - "h": 75 - }, - "frame": { - "x": 404, - "y": 366, - "w": 82, - "h": 75 - } - }, - { - "filename": "0048.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 82, - "h": 75 - }, - "frame": { - "x": 404, - "y": 366, - "w": 82, - "h": 75 - } - }, - { - "filename": "0057.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 79, - "h": 75 - }, - "frame": { - "x": 0, - "y": 423, - "w": 79, - "h": 75 - } - }, - { - "filename": "0091.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 79, - "h": 75 - }, - "frame": { - "x": 0, - "y": 423, - "w": 79, - "h": 75 - } - }, - { - "filename": "0058.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 78, - "h": 75 - }, - "frame": { - "x": 79, - "y": 426, - "w": 78, - "h": 75 - } - }, - { - "filename": "0090.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 78, - "h": 75 - }, - "frame": { - "x": 79, - "y": 426, - "w": 78, - "h": 75 - } - }, - { - "filename": "0049.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 15, - "w": 85, - "h": 75 - }, - "frame": { - "x": 157, - "y": 428, - "w": 85, - "h": 75 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 5, - "y": 14, - "w": 79, - "h": 76 - }, - "frame": { - "x": 242, - "y": 432, - "w": 79, - "h": 76 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 5, - "y": 14, - "w": 79, - "h": 76 - }, - "frame": { - "x": 242, - "y": 432, - "w": 79, - "h": 76 - } - }, - { - "filename": "0046.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 5, - "y": 14, - "w": 79, - "h": 76 - }, - "frame": { - "x": 242, - "y": 432, - "w": 79, - "h": 76 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:62a4a665074efb5def1545546995dc5b:de2788ebeab6b42f331926f332da5125:d60cc2e5ae2bd18de8ee3ab0649593ee$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/6706_2.png b/public/images/pokemon/variant/exp/6706_2.png deleted file mode 100644 index 7e7dfa8e05a910d741fea8e3952947d1e304738f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55978 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 diff --git a/public/images/pokemon/variant/exp/6706_3.json b/public/images/pokemon/variant/exp/6706_3.json deleted file mode 100644 index 8c9b16b80ab..00000000000 --- a/public/images/pokemon/variant/exp/6706_3.json +++ /dev/null @@ -1,2015 +0,0 @@ -{ - "textures": [ - { - "image": "6706_3.png", - "format": "RGBA8888", - "size": { - "w": 508, - "h": 508 - }, - "scale": 1, - "frames": [ - { - "filename": "0074.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 28, - "y": 26, - "w": 59, - "h": 61 - }, - "frame": { - "x": 0, - "y": 0, - "w": 59, - "h": 61 - } - }, - { - "filename": "0073.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 26, - "y": 25, - "w": 56, - "h": 63 - }, - "frame": { - "x": 59, - "y": 0, - "w": 56, - "h": 63 - } - }, - { - "filename": "0075.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 26, - "y": 25, - "w": 56, - "h": 63 - }, - "frame": { - "x": 59, - "y": 0, - "w": 56, - "h": 63 - } - }, - { - "filename": "0064.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 28, - "y": 21, - "w": 53, - "h": 65 - }, - "frame": { - "x": 115, - "y": 0, - "w": 53, - "h": 65 - } - }, - { - "filename": "0084.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 28, - "y": 21, - "w": 53, - "h": 65 - }, - "frame": { - "x": 115, - "y": 0, - "w": 53, - "h": 65 - } - }, - { - "filename": "0065.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 29, - "y": 21, - "w": 54, - "h": 65 - }, - "frame": { - "x": 168, - "y": 0, - "w": 54, - "h": 65 - } - }, - { - "filename": "0083.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 29, - "y": 21, - "w": 54, - "h": 65 - }, - "frame": { - "x": 168, - "y": 0, - "w": 54, - "h": 65 - } - }, - { - "filename": "0066.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 28, - "y": 21, - "w": 53, - "h": 65 - }, - "frame": { - "x": 222, - "y": 0, - "w": 53, - "h": 65 - } - }, - { - "filename": "0082.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 28, - "y": 21, - "w": 53, - "h": 65 - }, - "frame": { - "x": 222, - "y": 0, - "w": 53, - "h": 65 - } - }, - { - "filename": "0067.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 25, - "y": 21, - "w": 55, - "h": 66 - }, - "frame": { - "x": 275, - "y": 0, - "w": 55, - "h": 66 - } - }, - { - "filename": "0081.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 25, - "y": 21, - "w": 55, - "h": 66 - }, - "frame": { - "x": 275, - "y": 0, - "w": 55, - "h": 66 - } - }, - { - "filename": "0072.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 23, - "y": 23, - "w": 54, - "h": 66 - }, - "frame": { - "x": 330, - "y": 0, - "w": 54, - "h": 66 - } - }, - { - "filename": "0076.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 23, - "y": 23, - "w": 54, - "h": 66 - }, - "frame": { - "x": 330, - "y": 0, - "w": 54, - "h": 66 - } - }, - { - "filename": "0063.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 25, - "y": 21, - "w": 54, - "h": 67 - }, - "frame": { - "x": 384, - "y": 0, - "w": 54, - "h": 67 - } - }, - { - "filename": "0085.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 25, - "y": 21, - "w": 54, - "h": 67 - }, - "frame": { - "x": 384, - "y": 0, - "w": 54, - "h": 67 - } - }, - { - "filename": "0062.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 23, - "y": 21, - "w": 52, - "h": 68 - }, - "frame": { - "x": 438, - "y": 0, - "w": 52, - "h": 68 - } - }, - { - "filename": "0086.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 23, - "y": 21, - "w": 52, - "h": 68 - }, - "frame": { - "x": 438, - "y": 0, - "w": 52, - "h": 68 - } - }, - { - "filename": "0068.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 21, - "y": 21, - "w": 53, - "h": 68 - }, - "frame": { - "x": 0, - "y": 61, - "w": 53, - "h": 68 - } - }, - { - "filename": "0080.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 21, - "y": 21, - "w": 53, - "h": 68 - }, - "frame": { - "x": 0, - "y": 61, - "w": 53, - "h": 68 - } - }, - { - "filename": "0071.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 18, - "y": 22, - "w": 52, - "h": 68 - }, - "frame": { - "x": 53, - "y": 63, - "w": 52, - "h": 68 - } - }, - { - "filename": "0077.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 18, - "y": 22, - "w": 52, - "h": 68 - }, - "frame": { - "x": 53, - "y": 63, - "w": 52, - "h": 68 - } - }, - { - "filename": "0060.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 19, - "y": 21, - "w": 55, - "h": 69 - }, - "frame": { - "x": 105, - "y": 65, - "w": 55, - "h": 69 - } - }, - { - "filename": "0088.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 19, - "y": 21, - "w": 55, - "h": 69 - }, - "frame": { - "x": 105, - "y": 65, - "w": 55, - "h": 69 - } - }, - { - "filename": "0061.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 21, - "y": 21, - "w": 53, - "h": 69 - }, - "frame": { - "x": 160, - "y": 65, - "w": 53, - "h": 69 - } - }, - { - "filename": "0087.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 21, - "y": 21, - "w": 53, - "h": 69 - }, - "frame": { - "x": 160, - "y": 65, - "w": 53, - "h": 69 - } - }, - { - "filename": "0069.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 16, - "y": 21, - "w": 53, - "h": 69 - }, - "frame": { - "x": 213, - "y": 65, - "w": 53, - "h": 69 - } - }, - { - "filename": "0079.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 16, - "y": 21, - "w": 53, - "h": 69 - }, - "frame": { - "x": 213, - "y": 65, - "w": 53, - "h": 69 - } - }, - { - "filename": "0070.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 15, - "y": 21, - "w": 52, - "h": 70 - }, - "frame": { - "x": 266, - "y": 66, - "w": 52, - "h": 70 - } - }, - { - "filename": "0078.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 15, - "y": 21, - "w": 52, - "h": 70 - }, - "frame": { - "x": 266, - "y": 66, - "w": 52, - "h": 70 - } - }, - { - "filename": "0006.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 19, - "w": 87, - "h": 71 - }, - "frame": { - "x": 318, - "y": 67, - "w": 87, - "h": 71 - } - }, - { - "filename": "0022.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 19, - "w": 87, - "h": 71 - }, - "frame": { - "x": 318, - "y": 67, - "w": 87, - "h": 71 - } - }, - { - "filename": "0038.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 19, - "w": 87, - "h": 71 - }, - "frame": { - "x": 318, - "y": 67, - "w": 87, - "h": 71 - } - }, - { - "filename": "0051.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 18, - "w": 87, - "h": 71 - }, - "frame": { - "x": 405, - "y": 68, - "w": 87, - "h": 71 - } - }, - { - "filename": "0003.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 19, - "w": 86, - "h": 72 - }, - "frame": { - "x": 0, - "y": 131, - "w": 86, - "h": 72 - } - }, - { - "filename": "0004.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 19, - "w": 87, - "h": 72 - }, - "frame": { - "x": 86, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0020.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 86, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0036.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 86, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0005.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 19, - "w": 87, - "h": 72 - }, - "frame": { - "x": 173, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0021.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 173, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0037.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 173, - "y": 134, - "w": 87, - "h": 72 - } - }, - { - "filename": "0007.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 260, - "y": 138, - "w": 87, - "h": 72 - } - }, - { - "filename": "0023.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 260, - "y": 138, - "w": 87, - "h": 72 - } - }, - { - "filename": "0039.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 260, - "y": 138, - "w": 87, - "h": 72 - } - }, - { - "filename": "0008.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 347, - "y": 139, - "w": 87, - "h": 72 - } - }, - { - "filename": "0024.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 347, - "y": 139, - "w": 87, - "h": 72 - } - }, - { - "filename": "0040.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 18, - "w": 87, - "h": 72 - }, - "frame": { - "x": 347, - "y": 139, - "w": 87, - "h": 72 - } - }, - { - "filename": "0059.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 74, - "h": 80 - }, - "frame": { - "x": 434, - "y": 139, - "w": 74, - "h": 80 - } - }, - { - "filename": "0089.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 5, - "y": 5, - "w": 74, - "h": 80 - }, - "frame": { - "x": 434, - "y": 139, - "w": 74, - "h": 80 - } - }, - { - "filename": "0050.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 85, - "h": 72 - }, - "frame": { - "x": 0, - "y": 203, - "w": 85, - "h": 72 - } - }, - { - "filename": "0052.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 13, - "w": 83, - "h": 72 - }, - "frame": { - "x": 85, - "y": 206, - "w": 83, - "h": 72 - } - }, - { - "filename": "0001.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 18, - "w": 84, - "h": 73 - }, - "frame": { - "x": 168, - "y": 206, - "w": 84, - "h": 73 - } - }, - { - "filename": "0002.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 85, - "h": 73 - }, - "frame": { - "x": 252, - "y": 210, - "w": 85, - "h": 73 - } - }, - { - "filename": "0009.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 337, - "y": 211, - "w": 86, - "h": 73 - } - }, - { - "filename": "0025.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 337, - "y": 211, - "w": 86, - "h": 73 - } - }, - { - "filename": "0041.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 337, - "y": 211, - "w": 86, - "h": 73 - } - }, - { - "filename": "0018.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 85, - "h": 73 - }, - "frame": { - "x": 423, - "y": 219, - "w": 85, - "h": 73 - } - }, - { - "filename": "0034.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 85, - "h": 73 - }, - "frame": { - "x": 423, - "y": 219, - "w": 85, - "h": 73 - } - }, - { - "filename": "0011.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 16, - "w": 85, - "h": 74 - }, - "frame": { - "x": 0, - "y": 275, - "w": 85, - "h": 74 - } - }, - { - "filename": "0027.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 16, - "w": 85, - "h": 74 - }, - "frame": { - "x": 0, - "y": 275, - "w": 85, - "h": 74 - } - }, - { - "filename": "0043.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 1, - "y": 16, - "w": 85, - "h": 74 - }, - "frame": { - "x": 0, - "y": 275, - "w": 85, - "h": 74 - } - }, - { - "filename": "0010.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 85, - "y": 279, - "w": 86, - "h": 73 - } - }, - { - "filename": "0026.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 85, - "y": 279, - "w": 86, - "h": 73 - } - }, - { - "filename": "0042.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 85, - "y": 279, - "w": 86, - "h": 73 - } - }, - { - "filename": "0053.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 4, - "w": 81, - "h": 74 - }, - "frame": { - "x": 171, - "y": 279, - "w": 81, - "h": 74 - } - }, - { - "filename": "0095.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 4, - "w": 81, - "h": 74 - }, - "frame": { - "x": 171, - "y": 279, - "w": 81, - "h": 74 - } - }, - { - "filename": "0017.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 16, - "w": 84, - "h": 74 - }, - "frame": { - "x": 252, - "y": 283, - "w": 84, - "h": 74 - } - }, - { - "filename": "0033.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 3, - "y": 16, - "w": 84, - "h": 74 - }, - "frame": { - "x": 252, - "y": 283, - "w": 84, - "h": 74 - } - }, - { - "filename": "0019.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 336, - "y": 284, - "w": 86, - "h": 73 - } - }, - { - "filename": "0035.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 17, - "w": 86, - "h": 73 - }, - "frame": { - "x": 336, - "y": 284, - "w": 86, - "h": 73 - } - }, - { - "filename": "0054.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 80, - "h": 74 - }, - "frame": { - "x": 422, - "y": 292, - "w": 80, - "h": 74 - } - }, - { - "filename": "0094.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 80, - "h": 74 - }, - "frame": { - "x": 422, - "y": 292, - "w": 80, - "h": 74 - } - }, - { - "filename": "0055.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 79, - "h": 74 - }, - "frame": { - "x": 0, - "y": 349, - "w": 79, - "h": 74 - } - }, - { - "filename": "0093.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 0, - "w": 79, - "h": 74 - }, - "frame": { - "x": 0, - "y": 349, - "w": 79, - "h": 74 - } - }, - { - "filename": "0056.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 80, - "h": 74 - }, - "frame": { - "x": 79, - "y": 352, - "w": 80, - "h": 74 - } - }, - { - "filename": "0092.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 80, - "h": 74 - }, - "frame": { - "x": 79, - "y": 352, - "w": 80, - "h": 74 - } - }, - { - "filename": "0012.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 15, - "w": 83, - "h": 75 - }, - "frame": { - "x": 159, - "y": 353, - "w": 83, - "h": 75 - } - }, - { - "filename": "0028.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 15, - "w": 83, - "h": 75 - }, - "frame": { - "x": 159, - "y": 353, - "w": 83, - "h": 75 - } - }, - { - "filename": "0044.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 15, - "w": 83, - "h": 75 - }, - "frame": { - "x": 159, - "y": 353, - "w": 83, - "h": 75 - } - }, - { - "filename": "0013.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 242, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0029.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 242, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0045.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 242, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0015.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 323, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0031.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 323, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0047.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 81, - "h": 75 - }, - "frame": { - "x": 323, - "y": 357, - "w": 81, - "h": 75 - } - }, - { - "filename": "0016.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 82, - "h": 75 - }, - "frame": { - "x": 404, - "y": 366, - "w": 82, - "h": 75 - } - }, - { - "filename": "0032.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 82, - "h": 75 - }, - "frame": { - "x": 404, - "y": 366, - "w": 82, - "h": 75 - } - }, - { - "filename": "0048.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 4, - "y": 15, - "w": 82, - "h": 75 - }, - "frame": { - "x": 404, - "y": 366, - "w": 82, - "h": 75 - } - }, - { - "filename": "0057.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 79, - "h": 75 - }, - "frame": { - "x": 0, - "y": 423, - "w": 79, - "h": 75 - } - }, - { - "filename": "0091.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 79, - "h": 75 - }, - "frame": { - "x": 0, - "y": 423, - "w": 79, - "h": 75 - } - }, - { - "filename": "0058.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 78, - "h": 75 - }, - "frame": { - "x": 79, - "y": 426, - "w": 78, - "h": 75 - } - }, - { - "filename": "0090.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 78, - "h": 75 - }, - "frame": { - "x": 79, - "y": 426, - "w": 78, - "h": 75 - } - }, - { - "filename": "0049.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 2, - "y": 15, - "w": 85, - "h": 75 - }, - "frame": { - "x": 157, - "y": 428, - "w": 85, - "h": 75 - } - }, - { - "filename": "0014.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 5, - "y": 14, - "w": 79, - "h": 76 - }, - "frame": { - "x": 242, - "y": 432, - "w": 79, - "h": 76 - } - }, - { - "filename": "0030.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 5, - "y": 14, - "w": 79, - "h": 76 - }, - "frame": { - "x": 242, - "y": 432, - "w": 79, - "h": 76 - } - }, - { - "filename": "0046.png", - "rotated": false, - "trimmed": true, - "sourceSize": { - "w": 88, - "h": 91 - }, - "spriteSourceSize": { - "x": 5, - "y": 14, - "w": 79, - "h": 76 - }, - "frame": { - "x": 242, - "y": 432, - "w": 79, - "h": 76 - } - } - ] - } - ], - "meta": { - "app": "https://www.codeandweb.com/texturepacker", - "version": "3.0", - "smartupdate": "$TexturePacker:SmartUpdate:62a4a665074efb5def1545546995dc5b:de2788ebeab6b42f331926f332da5125:d60cc2e5ae2bd18de8ee3ab0649593ee$" - } -} \ No newline at end of file diff --git a/public/images/pokemon/variant/exp/6706_3.png b/public/images/pokemon/variant/exp/6706_3.png deleted file mode 100644 index 3ad44f4bbf52818265762c20047ff43d445b9c85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56190 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