From 617b011c388789b331cd8de0f6c81ee1c3dd5b98 Mon Sep 17 00:00:00 2001 From: innerthunder Date: Wed, 16 Oct 2024 12:58:46 -0700 Subject: [PATCH] applying Temp's suggestions + other bugfixes --- src/battle-scene.ts | 2 +- src/data/ability.ts | 15 +++++++++------ src/data/battler-tags.ts | 8 ++++---- src/data/move.ts | 16 ++++++++-------- .../the-winstrate-challenge-encounter.ts | 2 +- src/enums/battler-tag-type.ts | 2 +- src/field/pokemon.ts | 8 ++++---- src/phases/command-phase.ts | 2 +- src/phases/encounter-phase.ts | 2 +- src/phases/enemy-command-phase.ts | 7 +++++++ src/phases/move-effect-phase.ts | 2 +- src/phases/mystery-encounter-phases.ts | 2 +- src/test/abilities/commander.test.ts | 16 ++++++++-------- src/test/moves/order_up.test.ts | 4 ++-- 14 files changed, 49 insertions(+), 39 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index c0c1a70e058..fc26ff1cd6d 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -1274,7 +1274,7 @@ export default class BattleScene extends SceneBase { if (resetArenaState) { this.arena.resetArenaEffects(); - playerField.forEach((pokemon) => pokemon.lapseTag(BattlerTagType.COMMANDER)); + playerField.forEach((pokemon) => pokemon.lapseTag(BattlerTagType.COMMANDED)); playerField.forEach((pokemon, p) => { if (pokemon.isOnField()) { diff --git a/src/data/ability.ts b/src/data/ability.ts index a6af526720c..b5585f176b4 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -2541,7 +2541,8 @@ export class PostSummonFormChangeByWeatherAbAttr extends PostSummonAbAttr { /** * Attribute implementing the effects of {@link https://bulbapedia.bulbagarden.net/wiki/Commander_(Ability) | Commander}. * When the source of an ability with this attribute detects a Dondozo as their active ally, the source "jumps - * into the Dondozo's mouth," sharply boosting the Dondozo's stats, cancelling + * into the Dondozo's mouth," sharply boosting the Dondozo's stats, cancelling the source's moves, and + * causing attacks that target the source to always miss. */ export class CommanderAbAttr extends AbAttr { constructor() { @@ -2550,16 +2551,18 @@ export class CommanderAbAttr extends AbAttr { override apply(pokemon: Pokemon, passive: boolean, simulated: boolean, cancelled: null, args: any[]): boolean { if (pokemon.scene.currentBattle?.double && pokemon.getAlly().species.speciesId === Species.DONDOZO) { - if (!pokemon.getAlly().isFainted() && pokemon.getAlly().getTag(BattlerTagType.COMMANDER)) { + // If the ally Dondozo is fainted or was previously "commanded" by + // another Pokemon, this effect cannot apply. + if (pokemon.getAlly().isFainted() || pokemon.getAlly().getTag(BattlerTagType.COMMANDED)) { return false; } if (!simulated) { - /** Play an animation of the source jumping into the ally Dondozo's mouth */ + // Play an animation of the source jumping into the ally Dondozo's mouth pokemon.scene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.COMMANDER_APPLY); - /** Apply boosts from this effect to the ally Dondozo */ - pokemon.getAlly().addTag(BattlerTagType.COMMANDER, 0, Moves.NONE, pokemon.id); - /** Cancel the source Pokemon's next move (if a move is queued) */ + // Apply boosts from this effect to the ally Dondozo + pokemon.getAlly().addTag(BattlerTagType.COMMANDED, 0, Moves.NONE, pokemon.id); + // Cancel the source Pokemon's next move (if a move is queued) pokemon.scene.tryRemovePhase((phase) => phase instanceof MovePhase && phase.pokemon === pokemon); } return true; diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 64d47b6b27d..df5ab3862e3 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -2064,11 +2064,11 @@ export class IceFaceBlockDamageTag extends FormBlockDamageTag { * Battler tag indicating a Tatsugiri with {@link https://bulbapedia.bulbagarden.net/wiki/Commander_(Ability) | Commander} * has entered the tagged Pokemon's mouth. */ -export class CommanderTag extends BattlerTag { +export class CommandedTag extends BattlerTag { private _tatsugiriFormKey: string; constructor(sourceId: number) { - super(BattlerTagType.COMMANDER, BattlerTagLapseType.CUSTOM, 0, Moves.NONE, sourceId); + super(BattlerTagType.COMMANDED, BattlerTagLapseType.CUSTOM, 0, Moves.NONE, sourceId); } public get tatsugiriFormKey(): string { @@ -2929,8 +2929,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source return new IceFaceBlockDamageTag(tagType); case BattlerTagType.DISGUISE: return new FormBlockDamageTag(tagType); - case BattlerTagType.COMMANDER: - return new CommanderTag(sourceId); + case BattlerTagType.COMMANDED: + return new CommandedTag(sourceId); case BattlerTagType.STOCKPILING: return new StockpilingTag(sourceMove); case BattlerTagType.OCTOLOCK: diff --git a/src/data/move.ts b/src/data/move.ts index b5568a44aad..8082915e557 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -1,5 +1,5 @@ import { ChargeAnim, initMoveAnim, loadMoveAnimAssets, MoveChargeAnim } from "./battle-anims"; -import { CommanderTag, EncoreTag, GulpMissileTag, HelpingHandTag, SemiInvulnerableTag, ShellTrapTag, StockpilingTag, SubstituteTag, TrappedTag, TypeBoostTag } from "./battler-tags"; +import { CommandedTag, EncoreTag, GulpMissileTag, HelpingHandTag, SemiInvulnerableTag, ShellTrapTag, StockpilingTag, SubstituteTag, TrappedTag, TypeBoostTag } from "./battler-tags"; import { getPokemonNameWithAffix } from "../messages"; import Pokemon, { AttackMoveResult, EnemyPokemon, HitResult, MoveResult, PlayerPokemon, PokemonMove, TurnMove } from "../field/pokemon"; import { getNonVolatileStatusEffects, getStatusEffectHealText, isNonVolatileStatusEffect, StatusEffect } from "./status-effect"; @@ -707,7 +707,7 @@ export default class Move implements Localizable { getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer { let score = 0; - if (target.getAlly()?.getTag(BattlerTagType.COMMANDER)?.getSourcePokemon(target.scene) === target) { + if (target.getAlly()?.getTag(BattlerTagType.COMMANDED)?.getSourcePokemon(target.scene) === target) { return 20 * (target.isPlayer() === user.isPlayer() ? -1 : 1); // always -20 with how the AI handles this score } @@ -2974,13 +2974,13 @@ export class OrderUpStatBoostAttr extends MoveEffectAttr { } override apply(user: Pokemon, target: Pokemon, move: Move, args?: any[]): boolean { - const commanderTag = user.getTag(CommanderTag); - if (!commanderTag) { + const commandedTag = user.getTag(CommandedTag); + if (!commandedTag) { return false; } let increasedStat: EffectiveStat = Stat.ATK; - switch (commanderTag.tatsugiriFormKey) { + switch (commandedTag.tatsugiriFormKey) { case "curly": increasedStat = Stat.ATK; break; @@ -5522,7 +5522,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { // If the switch-out target is a Dondozo with a Tatsugiri in its mouth // (e.g. when it uses Flip Turn), make it spit out the Tatsugiri before switching out. - switchOutTarget.lapseTag(BattlerTagType.COMMANDER); + switchOutTarget.lapseTag(BattlerTagType.COMMANDED); if (switchOutTarget instanceof PlayerPokemon) { // Switch out logic for the player's Pokemon @@ -5600,8 +5600,8 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { } // Dondozo with an allied Tatsugiri in its mouth cannot be forced out - const commanderTag = switchOutTarget.getTag(BattlerTagType.COMMANDER); - if (commanderTag?.getSourcePokemon(switchOutTarget.scene)?.isActive(true)) { + const commandedTag = switchOutTarget.getTag(BattlerTagType.COMMANDED); + if (commandedTag?.getSourcePokemon(switchOutTarget.scene)?.isActive(true)) { return false; } diff --git a/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts b/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts index ad1cc017c5d..f7952806f7c 100644 --- a/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-winstrate-challenge-encounter.ts @@ -188,7 +188,7 @@ function endTrainerBattleAndShowDialogue(scene: BattleScene): Promise { } else { scene.arena.resetArenaEffects(); const playerField = scene.getPlayerField(); - playerField.forEach((pokemon) => pokemon.lapseTag(BattlerTagType.COMMANDER)); + playerField.forEach((pokemon) => pokemon.lapseTag(BattlerTagType.COMMANDED)); playerField.forEach((_, p) => scene.unshiftPhase(new ReturnPhase(scene, p))); for (const pokemon of scene.getParty()) { diff --git a/src/enums/battler-tag-type.ts b/src/enums/battler-tag-type.ts index 2f1e15babb2..ba63f37dbda 100644 --- a/src/enums/battler-tag-type.ts +++ b/src/enums/battler-tag-type.ts @@ -88,5 +88,5 @@ export enum BattlerTagType { SYRUP_BOMB = "SYRUP_BOMB", ELECTRIFIED = "ELECTRIFIED", TELEKINESIS = "TELEKINESIS", - COMMANDER = "COMMANDER" + COMMANDED = "COMMANDED" } diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 69c6b2d1abf..52fde06b4d2 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -1511,8 +1511,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { * @returns */ isTrapped(trappedAbMessages: string[] = [], simulated: boolean = true): boolean { - const commanderTag = this.getTag(BattlerTagType.COMMANDER); - if (commanderTag?.getSourcePokemon(this.scene)?.isActive(true)) { + const commandedTag = this.getTag(BattlerTagType.COMMANDED); + if (commandedTag?.getSourcePokemon(this.scene)?.isActive(true)) { return true; } @@ -2817,7 +2817,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.scene.setPhaseQueueSplice(); this.scene.unshiftPhase(new FaintPhase(this.scene, this.getBattlerIndex(), isOneHitKo)); this.destroySubstitute(); - this.lapseTag(BattlerTagType.COMMANDER); + this.lapseTag(BattlerTagType.COMMANDED); this.resetSummonData(); } @@ -2870,7 +2870,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.scene.setPhaseQueueSplice(); this.scene.unshiftPhase(new FaintPhase(this.scene, this.getBattlerIndex(), preventEndure)); this.destroySubstitute(); - this.lapseTag(BattlerTagType.COMMANDER); + this.lapseTag(BattlerTagType.COMMANDED); this.resetSummonData(); } diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index ca83e6b540b..85b50faeac5 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -44,7 +44,7 @@ export class CommandPhase extends FieldPhase { } // If the Pokemon has applied Commander's effects to its ally, skip this command - if (this.scene.currentBattle?.double && this.getPokemon().getAlly()?.getTag(BattlerTagType.COMMANDER)?.getSourcePokemon(this.scene) === this.getPokemon()) { + if (this.scene.currentBattle?.double && this.getPokemon().getAlly()?.getTag(BattlerTagType.COMMANDED)?.getSourcePokemon(this.scene) === this.getPokemon()) { this.scene.currentBattle.turnCommands[this.fieldIndex] = { command: Command.FIGHT, move: { move: Moves.NONE, targets: []}, skip: true }; } diff --git a/src/phases/encounter-phase.ts b/src/phases/encounter-phase.ts index 6cbc6671492..1446078dcdc 100644 --- a/src/phases/encounter-phase.ts +++ b/src/phases/encounter-phase.ts @@ -475,7 +475,7 @@ export class EncounterPhase extends BattlePhase { } } else { if (availablePartyMembers.length > 1 && availablePartyMembers[1].isOnField()) { - this.scene.getPlayerField().forEach((pokemon) => pokemon.lapseTag(BattlerTagType.COMMANDER)); + this.scene.getPlayerField().forEach((pokemon) => pokemon.lapseTag(BattlerTagType.COMMANDED)); this.scene.pushPhase(new ReturnPhase(this.scene, 1)); } this.scene.pushPhase(new ToggleDoublePositionPhase(this.scene, false)); diff --git a/src/phases/enemy-command-phase.ts b/src/phases/enemy-command-phase.ts index 3647a237ef1..83a85009ae0 100644 --- a/src/phases/enemy-command-phase.ts +++ b/src/phases/enemy-command-phase.ts @@ -2,6 +2,8 @@ import BattleScene from "#app/battle-scene"; import { BattlerIndex } from "#app/battle"; import { Command } from "#app/ui/command-ui-handler"; import { FieldPhase } from "./field-phase"; +import { Abilities } from "#enums/abilities"; +import { BattlerTagType } from "#enums/battler-tag-type"; /** * Phase for determining an enemy AI's action for the next turn. @@ -34,6 +36,11 @@ export class EnemyCommandPhase extends FieldPhase { const trainer = battle.trainer; + if (battle.double && enemyPokemon.hasAbility(Abilities.COMMANDER) + && enemyPokemon.getAlly().getTag(BattlerTagType.COMMANDED)) { + this.skipTurn = true; + } + /** * If the enemy has a trainer, decide whether or not the enemy should switch * to another member in its party. diff --git a/src/phases/move-effect-phase.ts b/src/phases/move-effect-phase.ts index 22d82d7e40f..025c465122a 100644 --- a/src/phases/move-effect-phase.ts +++ b/src/phases/move-effect-phase.ts @@ -154,7 +154,7 @@ export class MoveEffectPhase extends PokemonPhase { && !target.getTag(SemiInvulnerableTag); /** Is the target hidden by the effects of its Commander ability? */ - const isCommanding = this.scene.currentBattle.double && target.getAlly()?.getTag(BattlerTagType.COMMANDER)?.getSourcePokemon(this.scene) === target; + const isCommanding = this.scene.currentBattle.double && target.getAlly()?.getTag(BattlerTagType.COMMANDED)?.getSourcePokemon(this.scene) === target; /** * If the move missed a target, stop all future hits against that target diff --git a/src/phases/mystery-encounter-phases.ts b/src/phases/mystery-encounter-phases.ts index de738de0b00..da12e495aca 100644 --- a/src/phases/mystery-encounter-phases.ts +++ b/src/phases/mystery-encounter-phases.ts @@ -417,7 +417,7 @@ export class MysteryEncounterBattlePhase extends Phase { } } else { if (availablePartyMembers.length > 1 && availablePartyMembers[1].isOnField()) { - scene.getPlayerField().forEach((pokemon) => pokemon.lapseTag(BattlerTagType.COMMANDER)); + scene.getPlayerField().forEach((pokemon) => pokemon.lapseTag(BattlerTagType.COMMANDED)); scene.pushPhase(new ReturnPhase(scene, 1)); } scene.pushPhase(new ToggleDoublePositionPhase(scene, false)); diff --git a/src/test/abilities/commander.test.ts b/src/test/abilities/commander.test.ts index 4d327c2697d..082a311656b 100644 --- a/src/test/abilities/commander.test.ts +++ b/src/test/abilities/commander.test.ts @@ -50,7 +50,7 @@ describe("Abilities - Commander", () => { const affectedStats: EffectiveStat[] = [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ]; expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY); - expect(dondozo.getTag(BattlerTagType.COMMANDER)).toBeDefined(); + expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined(); affectedStats.forEach((stat) => expect(dondozo.getStatStage(stat)).toBe(2)); game.move.select(Moves.SPLASH, 1); @@ -80,7 +80,7 @@ describe("Abilities - Commander", () => { expect(game.scene.triggerPokemonBattleAnim).toHaveBeenCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY); const dondozo = game.scene.getPlayerField()[1]; - expect(dondozo.getTag(BattlerTagType.COMMANDER)).toBeDefined(); + expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined(); await game.phaseInterceptor.to("BerryPhase", false); expect(tatsugiri.getMoveHistory()).toHaveLength(0); @@ -93,7 +93,7 @@ describe("Abilities - Commander", () => { const [ tatsugiri, dondozo ] = game.scene.getPlayerField(); expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY); - expect(dondozo.getTag(BattlerTagType.COMMANDER)).toBeDefined(); + expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined(); game.move.select(Moves.MEMENTO, 1, BattlerIndex.ENEMY); @@ -105,7 +105,7 @@ describe("Abilities - Commander", () => { await game.setTurnOrder([ BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER ]); await game.phaseInterceptor.to("FaintPhase", false); - expect(dondozo.getTag(BattlerTagType.COMMANDER)).toBeUndefined(); + expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeUndefined(); expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(dondozo, PokemonAnimType.COMMANDER_REMOVE); await game.phaseInterceptor.to("BerryPhase", false); @@ -122,7 +122,7 @@ describe("Abilities - Commander", () => { const [ tatsugiri, dondozo ] = game.scene.getPlayerField(); expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY); - expect(dondozo.getTag(BattlerTagType.COMMANDER)).toBeDefined(); + expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined(); game.move.select(Moves.SPLASH, 1); @@ -140,7 +140,7 @@ describe("Abilities - Commander", () => { const [ tatsugiri, dondozo ] = game.scene.getPlayerField(); expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY); - expect(dondozo.getTag(BattlerTagType.COMMANDER)).toBeDefined(); + expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined(); tatsugiri.addTag(BattlerTagType.SALT_CURED, 0, Moves.NONE, game.scene.getField()[BattlerIndex.ENEMY].id); @@ -162,7 +162,7 @@ describe("Abilities - Commander", () => { const [ tatsugiri, dondozo ] = game.scene.getPlayerField(); expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY); - expect(dondozo.getTag(BattlerTagType.COMMANDER)).toBeDefined(); + expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined(); game.move.select(Moves.SPLASH, 1); @@ -180,7 +180,7 @@ describe("Abilities - Commander", () => { const [ tatsugiri, dondozo ] = game.scene.getPlayerField(); expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY); - expect(dondozo.getTag(BattlerTagType.COMMANDER)).toBeDefined(); + expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined(); game.move.select(Moves.SPLASH, 1); diff --git a/src/test/moves/order_up.test.ts b/src/test/moves/order_up.test.ts index 41b2748c9cd..d0b52dc1a9d 100644 --- a/src/test/moves/order_up.test.ts +++ b/src/test/moves/order_up.test.ts @@ -51,7 +51,7 @@ describe("Moves - Order Up", () => { const [ tatsugiri, dondozo ] = game.scene.getPlayerField(); expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY); - expect(dondozo.getTag(BattlerTagType.COMMANDER)).toBeDefined(); + expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined(); game.move.select(Moves.ORDER_UP, 1, BattlerIndex.ENEMY); expect(game.scene.currentBattle.turnCommands[0]?.skip).toBeTruthy(); @@ -72,7 +72,7 @@ describe("Moves - Order Up", () => { const [ tatsugiri, dondozo ] = game.scene.getPlayerField(); expect(game.scene.triggerPokemonBattleAnim).toHaveBeenLastCalledWith(tatsugiri, PokemonAnimType.COMMANDER_APPLY); - expect(dondozo.getTag(BattlerTagType.COMMANDER)).toBeDefined(); + expect(dondozo.getTag(BattlerTagType.COMMANDED)).toBeDefined(); game.move.select(Moves.ORDER_UP, 1, BattlerIndex.ENEMY); expect(game.scene.currentBattle.turnCommands[0]?.skip).toBeTruthy();