mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-09-23 15:03:24 +02:00
gdddddddd
This commit is contained in:
parent
375736bfec
commit
8c301c184a
@ -5803,26 +5803,17 @@ export class LeechSeedAttr extends AddBattlerTagAttr {
|
||||
}
|
||||
|
||||
/**
|
||||
* Attribute to add the {@linkcode BattlerTagType.IGNORE_FLYING | IGNORE_FLYING} battler tag to the target
|
||||
* Attribute to add the {@linkcode BattlerTagType.IGNORE_FLYING | IGNORE_FLYING} BattlerTag to the target
|
||||
* and remove any prior sources of ungroundedness.
|
||||
*
|
||||
* Does nothing if the target was not already ungrounded.
|
||||
* Used by {@linkcode MoveId.SMACK_DOWN} and {@linkcode MoveId.THOUSAND_ARROWS},
|
||||
* and does nothing if the target was not already ungrounded.
|
||||
*/
|
||||
export class FallDownAttr extends AddBattlerTagAttr {
|
||||
constructor() {
|
||||
super(BattlerTagType.IGNORE_FLYING, false, false, 0, 0, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add `GroundedTag` to the target, remove all prior sources of ungroundedness
|
||||
* and display a message.
|
||||
* @param user - The {@linkcode Pokemon} using the move
|
||||
* @param target - The {@linkcode Pokemon} targeted by the move
|
||||
* @param move - The {@linkcode Move} invoking this effect
|
||||
* @param args n/a
|
||||
* @returns Whether the target was successfully brought down to earth.
|
||||
*
|
||||
*/
|
||||
apply(user: Pokemon, target: Pokemon, move: Move, _args: any[]): boolean {
|
||||
// Smack down and similar only add their tag if the target is already ungrounded,
|
||||
// barring any prior semi-invulnerability.
|
||||
@ -5830,9 +5821,13 @@ export class FallDownAttr extends AddBattlerTagAttr {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!super.apply(user, target, move, _args)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove the target's prior sources of ungroundedness.
|
||||
// NB: These effects cannot simply be part of the tag's `onAdd` effect as Ingrain also adds the tag
|
||||
// but does not remove Telekinesis' accuracy boost
|
||||
// NB: These effects cannot simply be part of the tag's `onAdd` effect as Ingrain
|
||||
// also forcibly grounds the user without removing Telekinesis' accuracy boost
|
||||
target.removeTag(BattlerTagType.FLOATING);
|
||||
target.removeTag(BattlerTagType.TELEKINESIS);
|
||||
if (target.getTag(BattlerTagType.FLYING)) {
|
||||
@ -5842,7 +5837,7 @@ export class FallDownAttr extends AddBattlerTagAttr {
|
||||
}
|
||||
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:fallDown", { targetPokemonName: getPokemonNameWithAffix(target) }));
|
||||
return super.apply(user, target, move, _args);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,7 @@ export enum BattlerTagType {
|
||||
ALWAYS_CRIT = "ALWAYS_CRIT",
|
||||
IGNORE_ACCURACY = "IGNORE_ACCURACY",
|
||||
BYPASS_SLEEP = "BYPASS_SLEEP",
|
||||
// TODO: Rename this to "Smacked Down" or "Forcibly Grounded"
|
||||
IGNORE_FLYING = "IGNORE_FLYING",
|
||||
SALT_CURED = "SALT_CURED",
|
||||
CURSED = "CURSED",
|
||||
|
@ -2284,13 +2284,13 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
/**
|
||||
* Return whether this Pokemon is currently on the ground.
|
||||
*
|
||||
* To be considered grounded, a Pokemon must either:
|
||||
* * Be {@linkcode GroundedTag | forcibly grounded} from an effect like Smack Down or Ingrain
|
||||
* To be considered grounded, a Pokemon must fulfill any of the following criteria:
|
||||
* * Be {@linkcode BattlerTagType.IGNORE_FLYING | forcibly grounded} from an effect like Smack Down or Ingrain
|
||||
* * Be under the effects of {@linkcode ArenaTagType.GRAVITY | harsh gravity}
|
||||
* * **Not** be all of the following things:
|
||||
* * **Not** be any of the following things:
|
||||
* * {@linkcode PokemonType.FLYING | Flying-type}
|
||||
* * {@linkcode AbilityId.LEVITATE | Levitating}
|
||||
* * {@linkcode BattlerTagType.FLOATING | Floating} from Magnet Rise or Telekinesis.
|
||||
* * {@linkcode BattlerTagType.FLOATING | Floating} from Magnet Rise or Telekinesis
|
||||
* * {@linkcode SemiInvulnerableTag | Semi-invulnerable} with `ignoreSemiInvulnerable` set to `false`
|
||||
* @param ignoreSemiInvulnerable - Whether to ignore the target's semi-invulnerable state when determining groundedness;
|
||||
default `false`
|
||||
|
@ -43,7 +43,7 @@ describe("Terrain -", () => {
|
||||
.passiveAbility(AbilityId.NO_GUARD);
|
||||
});
|
||||
|
||||
// TODO: Terrain boosts currently apply to damage dealt, not base power
|
||||
// TODO: Terrain boosts currently apply directly to damage dealt, not base power
|
||||
describe.todo.each<{ name: string; type: PokemonType; terrain: TerrainType; move: MoveId }>([
|
||||
{ name: "Electric", type: PokemonType.ELECTRIC, terrain: TerrainType.ELECTRIC, move: MoveId.THUNDERBOLT },
|
||||
{ name: "Psychic", type: PokemonType.PSYCHIC, terrain: TerrainType.PSYCHIC, move: MoveId.PSYCHIC },
|
||||
|
@ -40,17 +40,17 @@ describe("Moves - Smack Down and Thousand Arrows", () => {
|
||||
{ name: "Smack Down", move: MoveId.SMACK_DOWN },
|
||||
{ name: "Thousand Arrows", move: MoveId.THOUSAND_ARROWS },
|
||||
])("$name should hit and ground ungrounded targets", async ({ move }) => {
|
||||
game.override.enemySpecies(SpeciesId.TORNADUS);
|
||||
game.override.enemySpecies(SpeciesId.ROOKIDEE);
|
||||
await game.classicMode.startBattle([SpeciesId.ILLUMISE]);
|
||||
|
||||
const enemy = game.field.getEnemyPokemon();
|
||||
expect(enemy.isGrounded()).toBe(false);
|
||||
const rookidee = game.field.getEnemyPokemon();
|
||||
expect(rookidee.isGrounded()).toBe(false);
|
||||
|
||||
game.move.use(move);
|
||||
await game.toEndOfTurn();
|
||||
|
||||
expect(enemy).toHaveBattlerTag(BattlerTagType.IGNORE_FLYING);
|
||||
expect(enemy.isGrounded()).toBe(true);
|
||||
expect(rookidee).toHaveBattlerTag(BattlerTagType.IGNORE_FLYING);
|
||||
expect(rookidee.isGrounded()).toBe(true);
|
||||
});
|
||||
|
||||
it("should affect targets with Levitate", async () => {
|
||||
@ -86,17 +86,22 @@ describe("Moves - Smack Down and Thousand Arrows", () => {
|
||||
|
||||
// NB: This test might sound useless, but semi-invulnerable pokemon are technically considered "ungrounded"
|
||||
// by most things
|
||||
it("should not ground semi-invulnerable targets hit via No Guard unless otherwise ungrounded", async () => {
|
||||
it("should not consider semi-invulnerability as a valid source of ungroundedness", async () => {
|
||||
game.override.ability(AbilityId.NO_GUARD);
|
||||
await game.classicMode.startBattle([SpeciesId.ILLUMISE]);
|
||||
|
||||
game.move.use(MoveId.THOUSAND_ARROWS);
|
||||
await game.move.forceEnemyMove(MoveId.DIG);
|
||||
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
|
||||
await game.phaseInterceptor.to("MoveEndPhase");
|
||||
|
||||
// Eelektross should be grounded solely due to using Dig,
|
||||
const eelektross = game.field.getEnemyPokemon();
|
||||
expect(eelektross.isGrounded()).toBe(false);
|
||||
expect(eelektross.isGrounded(true)).toBe(true);
|
||||
await game.toEndOfTurn();
|
||||
|
||||
// Eelektross took damage but was not forcibly grounded
|
||||
const eelektross = game.field.getEnemyPokemon();
|
||||
expect(eelektross.isGrounded()).toBe(true);
|
||||
expect(eelektross).not.toHaveBattlerTag(BattlerTagType.IGNORE_FLYING);
|
||||
expect(eelektross).not.toHaveFullHp();
|
||||
@ -112,23 +117,23 @@ describe("Moves - Smack Down and Thousand Arrows", () => {
|
||||
hitSpy = vi.spyOn(MoveEffectPhase.prototype, "hitCheck");
|
||||
});
|
||||
|
||||
it("should deal a fixed 1x damage when hitting ungrounded Flying-types", async () => {
|
||||
it("should have 1x type effectiveness when hitting ungrounded Flying-types", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.MAGIKARP]);
|
||||
|
||||
const archeops = game.field.getEnemyPokemon();
|
||||
|
||||
// first turn: 1x
|
||||
game.move.use(MoveId.THOUSAND_ARROWS);
|
||||
await game.toEndOfTurn();
|
||||
|
||||
// first turn: 1x
|
||||
expect(archeops).not.toHaveFullHp();
|
||||
expect(archeops.isGrounded()).toBe(true);
|
||||
expect(hitSpy).toHaveLastReturnedWith([expect.anything(), 1]);
|
||||
|
||||
// 2nd turn: 2x
|
||||
game.move.use(MoveId.THOUSAND_ARROWS);
|
||||
await game.toEndOfTurn();
|
||||
|
||||
// 2nd turn: 2x
|
||||
expect(hitSpy).toHaveLastReturnedWith([expect.anything(), 2]);
|
||||
});
|
||||
|
||||
|
@ -71,39 +71,41 @@ describe("Move - Telekinesis", () => {
|
||||
species: s,
|
||||
name: getEnumStr(SpeciesId, s, { casing: "Title" }),
|
||||
}));
|
||||
it.each(invalidSpecies)("should fail if used on a $name, but can be baton passable onto one", async ({ species }) => {
|
||||
await game.classicMode.startBattle([species, SpeciesId.FEEBAS]);
|
||||
it.each(invalidSpecies)(
|
||||
"should fail if used on a $name, but can still be baton passed onto one",
|
||||
async ({ species }) => {
|
||||
await game.classicMode.startBattle([species, SpeciesId.FEEBAS]);
|
||||
|
||||
const invalidMon = game.field.getPlayerPokemon();
|
||||
expect(invalidMon.species.speciesId).toBe(species);
|
||||
const [invalidMon, feebas] = game.scene.getPlayerParty();
|
||||
expect(invalidMon.species.speciesId).toBe(species);
|
||||
|
||||
game.move.use(MoveId.TELEPORT);
|
||||
game.doSelectPartyPokemon(1);
|
||||
await game.move.forceEnemyMove(MoveId.TELEKINESIS);
|
||||
await game.toNextTurn();
|
||||
game.move.use(MoveId.TELEPORT);
|
||||
game.doSelectPartyPokemon(1);
|
||||
await game.move.forceEnemyMove(MoveId.TELEKINESIS);
|
||||
await game.toNextTurn();
|
||||
|
||||
// Adding tags directly did not work
|
||||
const enemy = game.field.getEnemyPokemon();
|
||||
expect(enemy).toHaveUsedMove({ move: MoveId.TELEKINESIS, result: MoveResult.FAIL });
|
||||
// Adding tags directly did not work
|
||||
const enemy = game.field.getEnemyPokemon();
|
||||
expect(enemy).toHaveUsedMove({ move: MoveId.TELEKINESIS, result: MoveResult.FAIL });
|
||||
|
||||
expect(invalidMon.isOnField()).toBe(false);
|
||||
expect(invalidMon.isOnField()).toBe(false);
|
||||
|
||||
game.move.use(MoveId.BATON_PASS);
|
||||
game.doSelectPartyPokemon(1);
|
||||
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
|
||||
await game.phaseInterceptor.to("MoveEndPhase");
|
||||
game.move.use(MoveId.BATON_PASS);
|
||||
game.doSelectPartyPokemon(1);
|
||||
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
|
||||
await game.phaseInterceptor.to("MoveEndPhase");
|
||||
|
||||
const feebas = game.field.getPlayerPokemon();
|
||||
expect(feebas).toHaveBattlerTag(BattlerTagType.TELEKINESIS);
|
||||
expect(feebas).toHaveBattlerTag(BattlerTagType.FLOATING);
|
||||
expect(feebas).toHaveBattlerTag(BattlerTagType.TELEKINESIS);
|
||||
expect(feebas).toHaveBattlerTag(BattlerTagType.FLOATING);
|
||||
|
||||
await game.toEndOfTurn();
|
||||
await game.toEndOfTurn();
|
||||
|
||||
// Should have recieved tags successfully
|
||||
expect(invalidMon.isOnField()).toBe(true);
|
||||
expect(invalidMon).toHaveBattlerTag(BattlerTagType.TELEKINESIS);
|
||||
expect(invalidMon).toHaveBattlerTag(BattlerTagType.FLOATING);
|
||||
});
|
||||
// Should have received tags successfully
|
||||
expect(invalidMon.isOnField()).toBe(true);
|
||||
expect(invalidMon).toHaveBattlerTag(BattlerTagType.TELEKINESIS);
|
||||
expect(invalidMon).toHaveBattlerTag(BattlerTagType.FLOATING);
|
||||
},
|
||||
);
|
||||
|
||||
it("should still affect enemies transformed into invalid Pokemon", async () => {
|
||||
game.override.enemyAbility(AbilityId.IMPOSTER);
|
||||
@ -151,7 +153,7 @@ describe("Move - Telekinesis", () => {
|
||||
game.override.starterForms({ [SpeciesId.GENGAR]: 1 });
|
||||
await game.classicMode.startBattle([SpeciesId.GENGAR, SpeciesId.FEEBAS]);
|
||||
|
||||
const gengar = game.field.getPlayerPokemon();
|
||||
const [gengar, feebas] = game.scene.getPlayerParty();
|
||||
|
||||
game.move.use(MoveId.TELEPORT);
|
||||
game.doSelectPartyPokemon(1);
|
||||
@ -169,13 +171,12 @@ describe("Move - Telekinesis", () => {
|
||||
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
|
||||
await game.phaseInterceptor.to("MoveEndPhase");
|
||||
|
||||
const feebas = game.field.getPlayerPokemon();
|
||||
expect(feebas).toHaveBattlerTag(BattlerTagType.TELEKINESIS);
|
||||
expect(feebas).toHaveBattlerTag(BattlerTagType.FLOATING);
|
||||
|
||||
await game.toEndOfTurn();
|
||||
|
||||
// Should have recieved tags successfully
|
||||
// Should have not received tags
|
||||
expect(gengar.isOnField()).toBe(true);
|
||||
expect(gengar).not.toHaveBattlerTag(BattlerTagType.TELEKINESIS);
|
||||
expect(gengar).not.toHaveBattlerTag(BattlerTagType.FLOATING);
|
||||
|
Loading…
Reference in New Issue
Block a user