[Bug] Fixing Tera Starstorm for first turn of terastallization (#5658)

* Updating tera starstorm targeting condition so that it is a spread move on the turn that terastallization happens

* added new unit tests to verify behavior of tera starstorm under non-tera conditions as well as on terastallization turns
This commit is contained in:
Stephen Kelman 2025-04-15 07:19:19 -07:00 committed by GitHub
parent ff44cbfa97
commit 18c4dddcf0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 62 additions and 1 deletions

View File

@ -11205,7 +11205,7 @@ export function initMoves() {
new AttackMove(Moves.TERA_STARSTORM, PokemonType.NORMAL, MoveCategory.SPECIAL, 120, 100, 5, -1, 0, 9)
.attr(TeraMoveCategoryAttr)
.attr(TeraStarstormTypeAttr)
.attr(VariableTargetAttr, (user, target, move) => user.hasSpecies(Species.TERAPAGOS) && user.isTerastallized ? MoveTarget.ALL_NEAR_ENEMIES : MoveTarget.NEAR_OTHER)
.attr(VariableTargetAttr, (user, target, move) => user.hasSpecies(Species.TERAPAGOS) && (user.isTerastallized || globalScene.currentBattle.preTurnCommands[user.getFieldIndex()]?.command === Command.TERA) ? MoveTarget.ALL_NEAR_ENEMIES : MoveTarget.NEAR_OTHER)
.partial(), /** Does not ignore abilities that affect stats, relevant in determining the move's category {@see TeraMoveCategoryAttr} */
new AttackMove(Moves.FICKLE_BEAM, PokemonType.DRAGON, MoveCategory.SPECIAL, 80, 100, 5, 30, 0, 9)
.attr(PreMoveMessageAttr, doublePowerChanceMessageFunc)

View File

@ -69,6 +69,40 @@ describe("Moves - Tera Starstorm", () => {
expect(enemyField.every(pokemon => pokemon.isFullHp())).toBe(false);
});
it("targets both opponents in a double battle when used by Terapagos immediately after terastallizing", async () => {
await game.classicMode.startBattle([Species.TERAPAGOS]);
const terapagos = game.scene.getPlayerParty()[0];
terapagos.isTerastallized = false;
game.move.selectWithTera(Moves.TERA_STARSTORM, 0);
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]);
const enemyField = game.scene.getEnemyField();
// Terapagos in Stellar Form should hit both targets
await game.phaseInterceptor.to("MoveEndPhase");
expect(enemyField.some(pokemon => pokemon.isFullHp())).toBe(false);
});
it("targets only one opponent in a double battle when used by Terapagos without terastallizing", async () => {
await game.classicMode.startBattle([Species.TERAPAGOS]);
const terapagos = game.scene.getPlayerParty()[0];
terapagos.isTerastallized = false;
game.move.select(Moves.TERA_STARSTORM, 0, BattlerIndex.ENEMY);
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]);
const enemyField = game.scene.getEnemyField();
// Terapagos in Stellar Form should hit both targets
await game.phaseInterceptor.to("MoveEndPhase");
expect(enemyField.some(pokemon => pokemon.isFullHp())).toBe(true);
});
it("applies the effects when Terapagos in Stellar Form is fused with another Pokemon", async () => {
await game.classicMode.startBattle([Species.TERAPAGOS, Species.CHARMANDER, Species.MAGIKARP]);

View File

@ -65,6 +65,33 @@ export class MoveHelper extends GameManagerHelper {
}
}
/**
* Select the move to be used by the given Pokemon(-index), **which will also terastallize on this turn**.
* Triggers during the next {@linkcode CommandPhase}
* @param move - the move to use
* @param pkmIndex - the pokemon index. Relevant for double-battles only (defaults to 0)
* @param targetIndex - The {@linkcode BattlerIndex} of the Pokemon to target for single-target moves, or `null` if a manual call to `selectTarget()` is required
*/
public selectWithTera(move: Moves, pkmIndex: 0 | 1 = 0, targetIndex?: BattlerIndex | null) {
const movePosition = getMovePosition(this.game.scene, pkmIndex, move);
this.game.scene.getPlayerParty()[pkmIndex].isTerastallized = false;
this.game.onNextPrompt("CommandPhase", Mode.COMMAND, () => {
this.game.scene.ui.setMode(
Mode.FIGHT,
(this.game.scene.getCurrentPhase() as CommandPhase).getFieldIndex(),
Command.TERA,
);
});
this.game.onNextPrompt("CommandPhase", Mode.FIGHT, () => {
(this.game.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.TERA, movePosition, false);
});
if (targetIndex !== null) {
this.game.selectTarget(movePosition, targetIndex);
}
}
/**
* Forces the Paralysis or Freeze status to activate on the next move by temporarily mocking {@linkcode Overrides.STATUS_ACTIVATION_OVERRIDE},
* advancing to the next `MovePhase`, and then resetting the override to `null`