Gravity now cancels Fly, etc. after charge turn

This commit is contained in:
innerthunder 2024-10-06 20:56:57 -07:00
parent 185f7f2656
commit a602c2f513
3 changed files with 54 additions and 31 deletions

View File

@ -875,6 +875,9 @@ export class GravityTag extends ArenaTag {
arena.scene.getField(true).forEach((pokemon) => { arena.scene.getField(true).forEach((pokemon) => {
if (pokemon !== null) { if (pokemon !== null) {
pokemon.removeTag(BattlerTagType.MAGNET_RISEN); pokemon.removeTag(BattlerTagType.MAGNET_RISEN);
if (pokemon.getTag(BattlerTagType.FLYING)) {
pokemon.addTag(BattlerTagType.INTERRUPTED);
}
} }
}); });
} }

View File

@ -7121,7 +7121,6 @@ export function initMoves() {
new ChargingAttackMove(Moves.FLY, Type.FLYING, MoveCategory.PHYSICAL, 90, 95, 15, -1, 0, 1) new ChargingAttackMove(Moves.FLY, Type.FLYING, MoveCategory.PHYSICAL, 90, 95, 15, -1, 0, 1)
.chargeText(i18next.t("moveTriggers:flewUpHigh", { pokemonName: "{USER}" })) .chargeText(i18next.t("moveTriggers:flewUpHigh", { pokemonName: "{USER}" }))
.chargeAttr(SemiInvulnerableAttr, BattlerTagType.FLYING) .chargeAttr(SemiInvulnerableAttr, BattlerTagType.FLYING)
// TODO: double check Gravity interactions
.condition(failOnGravityCondition) .condition(failOnGravityCondition)
.ignoresVirtual(), .ignoresVirtual(),
new AttackMove(Moves.BIND, Type.NORMAL, MoveCategory.PHYSICAL, 15, 85, 20, -1, 0, 1) new AttackMove(Moves.BIND, Type.NORMAL, MoveCategory.PHYSICAL, 15, 85, 20, -1, 0, 1)

View File

@ -1,8 +1,8 @@
import { BattlerIndex } from "#app/battle";
import { allMoves } from "#app/data/move"; import { allMoves } from "#app/data/move";
import { Abilities } from "#app/enums/abilities"; import { Abilities } from "#enums/abilities";
import { ArenaTagType } from "#app/enums/arena-tag-type"; import { ArenaTagType } from "#enums/arena-tag-type";
import { MoveEffectPhase } from "#app/phases/move-effect-phase"; import { BattlerTagType } from "#enums/battler-tag-type";
import { TurnEndPhase } from "#app/phases/turn-end-phase";
import { Moves } from "#enums/moves"; import { Moves } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/utils/gameManager"; import GameManager from "#test/utils/gameManager";
@ -31,7 +31,9 @@ describe("Arena - Gravity", () => {
.ability(Abilities.UNNERVE) .ability(Abilities.UNNERVE)
.enemyAbility(Abilities.BALL_FETCH) .enemyAbility(Abilities.BALL_FETCH)
.enemySpecies(Species.SHUCKLE) .enemySpecies(Species.SHUCKLE)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(Moves.SPLASH)
.startingLevel(5)
.enemyLevel(5);
}); });
// Reference: https://bulbapedia.bulbagarden.net/wiki/Gravity_(move) // Reference: https://bulbapedia.bulbagarden.net/wiki/Gravity_(move)
@ -42,102 +44,121 @@ describe("Arena - Gravity", () => {
vi.spyOn(moveToCheck, "calculateBattleAccuracy"); vi.spyOn(moveToCheck, "calculateBattleAccuracy");
// Setup Gravity on first turn // Setup Gravity on first turn
await game.startBattle([ Species.PIKACHU ]); await game.classicMode.startBattle([ Species.PIKACHU ]);
game.move.select(Moves.GRAVITY); game.move.select(Moves.GRAVITY);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to("TurnEndPhase");
expect(game.scene.arena.getTag(ArenaTagType.GRAVITY)).toBeDefined(); expect(game.scene.arena.getTag(ArenaTagType.GRAVITY)).toBeDefined();
// Use non-OHKO move on second turn // Use non-OHKO move on second turn
await game.toNextTurn(); await game.toNextTurn();
game.move.select(Moves.TACKLE); game.move.select(Moves.TACKLE);
await game.phaseInterceptor.to(MoveEffectPhase); await game.phaseInterceptor.to("MoveEffectPhase");
expect(moveToCheck.calculateBattleAccuracy).toHaveReturnedWith(100 * 1.67); expect(moveToCheck.calculateBattleAccuracy).toHaveLastReturnedWith(100 * 1.67);
}); });
it("OHKO move accuracy is not affected", async () => { it("OHKO move accuracy is not affected", async () => {
game.override.startingLevel(5);
game.override.enemyLevel(5);
/** See Fissure {@link https://bulbapedia.bulbagarden.net/wiki/Fissure_(move)} */ /** See Fissure {@link https://bulbapedia.bulbagarden.net/wiki/Fissure_(move)} */
const moveToCheck = allMoves[Moves.FISSURE]; const moveToCheck = allMoves[Moves.FISSURE];
vi.spyOn(moveToCheck, "calculateBattleAccuracy"); vi.spyOn(moveToCheck, "calculateBattleAccuracy");
// Setup Gravity on first turn // Setup Gravity on first turn
await game.startBattle([ Species.PIKACHU ]); await game.classicMode.startBattle([ Species.PIKACHU ]);
game.move.select(Moves.GRAVITY); game.move.select(Moves.GRAVITY);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to("TurnEndPhase");
expect(game.scene.arena.getTag(ArenaTagType.GRAVITY)).toBeDefined(); expect(game.scene.arena.getTag(ArenaTagType.GRAVITY)).toBeDefined();
// Use OHKO move on second turn // Use OHKO move on second turn
await game.toNextTurn(); await game.toNextTurn();
game.move.select(Moves.FISSURE); game.move.select(Moves.FISSURE);
await game.phaseInterceptor.to(MoveEffectPhase); await game.phaseInterceptor.to("MoveEffectPhase");
expect(moveToCheck.calculateBattleAccuracy).toHaveReturnedWith(30); expect(moveToCheck.calculateBattleAccuracy).toHaveLastReturnedWith(30);
}); });
describe("Against flying types", () => { describe("Against flying types", () => {
it("can be hit by ground-type moves now", async () => { it("can be hit by ground-type moves now", async () => {
game.override game.override
.startingLevel(5)
.enemyLevel(5)
.enemySpecies(Species.PIDGEOT) .enemySpecies(Species.PIDGEOT)
.moveset([ Moves.GRAVITY, Moves.EARTHQUAKE ]); .moveset([ Moves.GRAVITY, Moves.EARTHQUAKE ]);
await game.startBattle([ Species.PIKACHU ]); await game.classicMode.startBattle([ Species.PIKACHU ]);
const pidgeot = game.scene.getEnemyPokemon()!; const pidgeot = game.scene.getEnemyPokemon()!;
vi.spyOn(pidgeot, "getAttackTypeEffectiveness"); vi.spyOn(pidgeot, "getAttackTypeEffectiveness");
// Try earthquake on 1st turn (fails!); // Try earthquake on 1st turn (fails!);
game.move.select(Moves.EARTHQUAKE); game.move.select(Moves.EARTHQUAKE);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to("TurnEndPhase");
expect(pidgeot.getAttackTypeEffectiveness).toHaveReturnedWith(0); expect(pidgeot.getAttackTypeEffectiveness).toHaveLastReturnedWith(0);
// Setup Gravity on 2nd turn // Setup Gravity on 2nd turn
await game.toNextTurn(); await game.toNextTurn();
game.move.select(Moves.GRAVITY); game.move.select(Moves.GRAVITY);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to("TurnEndPhase");
expect(game.scene.arena.getTag(ArenaTagType.GRAVITY)).toBeDefined(); expect(game.scene.arena.getTag(ArenaTagType.GRAVITY)).toBeDefined();
// Use ground move on 3rd turn // Use ground move on 3rd turn
await game.toNextTurn(); await game.toNextTurn();
game.move.select(Moves.EARTHQUAKE); game.move.select(Moves.EARTHQUAKE);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to("TurnEndPhase");
expect(pidgeot.getAttackTypeEffectiveness).toHaveReturnedWith(1); expect(pidgeot.getAttackTypeEffectiveness).toHaveLastReturnedWith(1);
}); });
it("keeps super-effective moves super-effective after using gravity", async () => { it("keeps super-effective moves super-effective after using gravity", async () => {
game.override game.override
.startingLevel(5)
.enemyLevel(5)
.enemySpecies(Species.PIDGEOT) .enemySpecies(Species.PIDGEOT)
.moveset([ Moves.GRAVITY, Moves.THUNDERBOLT ]); .moveset([ Moves.GRAVITY, Moves.THUNDERBOLT ]);
await game.startBattle([ Species.PIKACHU ]); await game.classicMode.startBattle([ Species.PIKACHU ]);
const pidgeot = game.scene.getEnemyPokemon()!; const pidgeot = game.scene.getEnemyPokemon()!;
vi.spyOn(pidgeot, "getAttackTypeEffectiveness"); vi.spyOn(pidgeot, "getAttackTypeEffectiveness");
// Setup Gravity on 1st turn // Setup Gravity on 1st turn
game.move.select(Moves.GRAVITY); game.move.select(Moves.GRAVITY);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to("TurnEndPhase");
expect(game.scene.arena.getTag(ArenaTagType.GRAVITY)).toBeDefined(); expect(game.scene.arena.getTag(ArenaTagType.GRAVITY)).toBeDefined();
// Use electric move on 2nd turn // Use electric move on 2nd turn
await game.toNextTurn(); await game.toNextTurn();
game.move.select(Moves.THUNDERBOLT); game.move.select(Moves.THUNDERBOLT);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to("TurnEndPhase");
expect(pidgeot.getAttackTypeEffectiveness).toHaveReturnedWith(2); expect(pidgeot.getAttackTypeEffectiveness).toHaveLastReturnedWith(2);
}); });
}); });
it("cancels Fly if its user is semi-invulnerable", async () => {
game.override
.enemySpecies(Species.SNORLAX)
.enemyMoveset(Moves.FLY)
.moveset([ Moves.GRAVITY, Moves.SPLASH ]);
await game.classicMode.startBattle([ Species.CHARIZARD ]);
const charizard = game.scene.getPlayerPokemon()!;
const snorlax = game.scene.getEnemyPokemon()!;
game.move.select(Moves.SPLASH);
await game.toNextTurn();
expect(snorlax.getTag(BattlerTagType.FLYING)).toBeDefined();
game.move.select(Moves.GRAVITY);
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]);
await game.phaseInterceptor.to("MoveEffectPhase");
expect(snorlax.getTag(BattlerTagType.INTERRUPTED)).toBeDefined();
await game.phaseInterceptor.to("TurnEndPhase");
expect(charizard.hp).toBe(charizard.getMaxHp());
});
}); });