From dca1d3470b58aaa42613729b4082a64b854c5e53 Mon Sep 17 00:00:00 2001 From: Bertie690 Date: Tue, 22 Jul 2025 11:17:15 -0400 Subject: [PATCH] sh Fixed tests for good --- .../positional-tags/positional-tag-manager.ts | 15 +++--- src/data/positional-tags/positional-tag.ts | 22 ++------ src/overrides.ts | 4 +- src/phases/move-effect-phase.ts | 1 - test/moves/wish.test.ts | 53 +++++++++++++++++-- 5 files changed, 66 insertions(+), 29 deletions(-) diff --git a/src/data/positional-tags/positional-tag-manager.ts b/src/data/positional-tags/positional-tag-manager.ts index e896beb75ae..219186d94de 100644 --- a/src/data/positional-tags/positional-tag-manager.ts +++ b/src/data/positional-tags/positional-tag-manager.ts @@ -1,12 +1,13 @@ import { loadPositionalTag } from "#data/positional-tags/load-positional-tag"; import type { PositionalTag } from "#data/positional-tags/positional-tag"; import type { BattlerIndex } from "#enums/battler-index"; -import type { MoveId } from "#enums/move-id"; import type { PositionalTagType } from "#enums/positional-tag-type"; /** A manager for the {@linkcode PositionalTag}s in the arena. */ export class PositionalTagManager { - /** Array containing all pending unactivated {@linkcode PositionalTag}s, sorted by order of creation. */ + /** + * Array containing all pending unactivated {@linkcode PositionalTag}s, + * sorted by order of creation (oldest first). */ public tags: PositionalTag[] = []; /** @@ -22,23 +23,22 @@ export class PositionalTagManager { * Check whether a new {@linkcode PositionalTag} can be added to the battlefield. * @param tagType - The {@linkcode PositionalTagType} being created * @param targetIndex - The {@linkcode BattlerIndex} being targeted - * @param sourceMove - The {@linkcode MoveId} causing the attack * @returns Whether the tag can be added. */ - public canAddTag(tagType: PositionalTagType, targetIndex: BattlerIndex, sourceMove: MoveId): boolean { - return !this.tags.some(t => t.tagType === tagType && t.overlapsWith(targetIndex, sourceMove)); + public canAddTag(tagType: PositionalTagType, targetIndex: BattlerIndex): boolean { + return !this.tags.some(t => t.tagType === tagType && t.targetIndex === targetIndex); } /** * Decrement turn counts of and activate all pending {@linkcode PositionalTag}s on field. * @remarks - * If multiple tags trigger simultaneously, they will activate **in order of initial creation**, NOT speed order. + * If multiple tags trigger simultaneously, they will activate **in order of initial creation**, regardless of speed order. * (Source: [Smogon]()) */ public triggerAllTags(): void { const leftoverTags: PositionalTag[] = []; for (const tag of this.tags) { - // Check for silent removal, immediately removing tags that. + // Check for silent removal, immediately removing invalid tags. if (tag.shouldDisappear()) { continue; } @@ -51,5 +51,6 @@ export class PositionalTagManager { tag.trigger(); } + this.tags = leftoverTags; } } diff --git a/src/data/positional-tags/positional-tag.ts b/src/data/positional-tags/positional-tag.ts index 5c37e843c36..ae2234cb711 100644 --- a/src/data/positional-tags/positional-tag.ts +++ b/src/data/positional-tags/positional-tag.ts @@ -58,17 +58,7 @@ export abstract class PositionalTag implements PositionalTagBaseArgs { */ abstract shouldDisappear(): boolean; - /** - * Check whether this {@linkcode PositionalTag} would overlap with another one. - * @param targetIndex - The {@linkcode BattlerIndex} being targeted - * @param sourceMove - The {@linkcode MoveId} causing the attack - * @returns Whether this tag would overlap with a newly created one. - */ - public overlapsWith(targetIndex: BattlerIndex, _sourceMove: MoveId): boolean { - return this.targetIndex === targetIndex; - } - - public getTarget(): Pokemon | undefined { + protected getTarget(): Pokemon | undefined { return globalScene.getField()[this.targetIndex]; } } @@ -131,9 +121,7 @@ export class DelayedAttackTag extends PositionalTag implements DelayedAttackArgs interface WishArgs extends PositionalTagBaseArgs { /** The amount of {@linkcode Stat.HP | HP} to heal; set to 50% of the user's max HP during move usage. */ healHp: number; - /** - * The name of the {@linkcode Pokemon} having created the tag.. - */ + /** The name of the {@linkcode Pokemon} having created the tag. */ pokemonName: string; } @@ -153,10 +141,10 @@ export class WishTag extends PositionalTag implements WishArgs { } public trigger(): void { - // TODO: Rename this locales key - wish shows a message on REMOVAL, dumbass + // TODO: Rename this locales key - wish shows a message on REMOVAL, not addition globalScene.phaseManager.queueMessage( i18next.t("arenaTag:wishTagOnAdd", { - pokemonName: this.pokemonName, + pokemonNameWithAffix: this.pokemonName, }), ); @@ -166,6 +154,6 @@ export class WishTag extends PositionalTag implements WishArgs { public shouldDisappear(): boolean { // Disappear if no target. // The source need not exist at the time of activation (since all we need is a simple message) - return !!this.getTarget(); + return !this.getTarget(); } } diff --git a/src/overrides.ts b/src/overrides.ts index de0d1d3f30a..8a142b0a8ea 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -44,7 +44,9 @@ import { Variant } from "#sprites/variant"; * } * ``` */ -const overrides = {} satisfies Partial>; +const overrides = { + MOVESET_OVERRIDE: [MoveId.FUTURE_SIGHT, MoveId.WISH, MoveId.DOOM_DESIRE, MoveId.AGILITY], +} satisfies Partial>; /** * If you need to add Overrides values for local testing do that inside {@linkcode overrides} diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index 05fa4a0f6d9..fdbae382df7 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -263,7 +263,6 @@ export class MoveEffectPhase extends PokemonPhase { */ const overridden = new BooleanHolder(false); - console.log(this.useMode); // Apply effects to override a move effect. // Assuming single target here works as this is (currently) // only used for Future Sight, calling and Pledge moves. diff --git a/test/moves/wish.test.ts b/test/moves/wish.test.ts index 34d2353ee02..27a1cf99733 100644 --- a/test/moves/wish.test.ts +++ b/test/moves/wish.test.ts @@ -2,6 +2,7 @@ import { getPokemonNameWithAffix } from "#app/messages"; import { AbilityId } from "#enums/ability-id"; import { BattlerIndex } from "#enums/battler-index"; import { MoveId } from "#enums/move-id"; +import { MoveResult } from "#enums/move-result"; import { PositionalTagType } from "#enums/positional-tag-type"; import { SpeciesId } from "#enums/species-id"; import { Stat } from "#enums/stat"; @@ -65,13 +66,31 @@ describe("Move - Wish", () => { expectWishActive(0); expect(game.textInterceptor.logs).toContain( i18next.t("arenaTag:wishTagOnAdd", { - pokemonName: getPokemonNameWithAffix(blissey), + pokemonNameWithAffix: getPokemonNameWithAffix(alomomola), }), ); expect(alomomola.hp).toBe(1); expect(blissey.hp).toBe(toDmgValue(alomomola.getMaxHp() / 2) + 1); }); + it("should work if the user has full HP, but not if it already has an active Wish", async () => { + await game.classicMode.startBattle([SpeciesId.ALOMOMOLA, SpeciesId.BLISSEY]); + + const alomomola = game.field.getPlayerPokemon(); + alomomola.hp = 1; + + game.move.use(MoveId.WISH); + await game.toNextTurn(); + + expectWishActive(); + + game.move.use(MoveId.WISH); + await game.toEndOfTurn(); + + expect(alomomola.hp).toBe(toDmgValue(alomomola.getMaxHp() / 2) + 1); + expect(alomomola.getLastXMoves()[0].result).toBe(MoveResult.FAIL); + }); + it("should function independently of Future Sight", async () => { await game.classicMode.startBattle([SpeciesId.ALOMOMOLA, SpeciesId.BLISSEY]); @@ -81,13 +100,13 @@ describe("Move - Wish", () => { game.move.use(MoveId.WISH); await game.move.forceEnemyMove(MoveId.FUTURE_SIGHT); - await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.toNextTurn(); expectWishActive(1); }); - it("should work in double battles and triggerin order of creation", async () => { + it("should work in double battles and trigger in order of creation", async () => { game.override.battleStyle("double"); await game.classicMode.startBattle([SpeciesId.ALOMOMOLA, SpeciesId.BLISSEY]); @@ -126,4 +145,32 @@ describe("Move - Wish", () => { expect(alomomola.hp).toBe(toDmgValue(alomomola.getMaxHp() / 2) + 1); expect(blissey.hp).toBe(toDmgValue(blissey.getMaxHp() / 2) + 1); }); + + it("should vanish if slot is empty", async () => { + game.override.battleStyle("double"); + await game.classicMode.startBattle([SpeciesId.ALOMOMOLA, SpeciesId.BLISSEY]); + + const [alomomola, blissey] = game.scene.getPlayerParty(); + alomomola.hp = 1; + blissey.hp = 1; + + game.move.use(MoveId.SPLASH, BattlerIndex.PLAYER); + game.move.use(MoveId.WISH, BattlerIndex.PLAYER_2); + await game.toNextTurn(); + + expectWishActive(); + + game.move.use(MoveId.SPLASH, BattlerIndex.PLAYER); + game.move.use(MoveId.MEMENTO, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY_2); + await game.toEndOfTurn(); + + // Wish went away without doing anything + expectWishActive(0); + expect(game.textInterceptor.logs).not.toContain( + i18next.t("arenaTag:wishTagOnAdd", { + pokemonNameWithAffix: getPokemonNameWithAffix(blissey), + }), + ); + expect(alomomola.hp).toBe(1); + }); });