Merge 0dbaad5ee1
into 8d11313458
This commit is contained in:
commit
c6109f6514
|
@ -53,6 +53,7 @@ export class Ability implements Localizable {
|
|||
public description: string;
|
||||
public generation: integer;
|
||||
public isBypassFaint: boolean;
|
||||
public isBypassOnField: boolean;
|
||||
public isIgnorable: boolean;
|
||||
public attrs: AbAttr[];
|
||||
public conditions: AbAttrCondition[];
|
||||
|
@ -113,6 +114,11 @@ export class Ability implements Localizable {
|
|||
return this;
|
||||
}
|
||||
|
||||
bypassOnField(): Ability {
|
||||
this.isBypassOnField = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
ignorable(): Ability {
|
||||
this.isIgnorable = true;
|
||||
return this;
|
||||
|
@ -5422,7 +5428,8 @@ export function initAbilities() {
|
|||
.attr(ProtectStatAbAttr)
|
||||
.ignorable(),
|
||||
new Ability(Abilities.NATURAL_CURE, 3)
|
||||
.attr(PreSwitchOutResetStatusAbAttr),
|
||||
.attr(PreSwitchOutResetStatusAbAttr)
|
||||
.bypassOnField(),
|
||||
new Ability(Abilities.LIGHTNING_ROD, 3)
|
||||
.attr(RedirectTypeMoveAbAttr, Type.ELECTRIC)
|
||||
.attr(TypeImmunityStatStageChangeAbAttr, Type.ELECTRIC, Stat.SPATK, 1)
|
||||
|
@ -5768,7 +5775,8 @@ export function initAbilities() {
|
|||
new Ability(Abilities.POISON_TOUCH, 5)
|
||||
.attr(PostAttackContactApplyStatusEffectAbAttr, 30, StatusEffect.POISON),
|
||||
new Ability(Abilities.REGENERATOR, 5)
|
||||
.attr(PreSwitchOutHealAbAttr),
|
||||
.attr(PreSwitchOutHealAbAttr)
|
||||
.bypassOnField(),
|
||||
new Ability(Abilities.BIG_PECKS, 5)
|
||||
.attr(ProtectStatAbAttr, Stat.DEF)
|
||||
.ignorable(),
|
||||
|
@ -5914,19 +5922,22 @@ export function initAbilities() {
|
|||
.attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.HEAVY_RAIN)
|
||||
.attr(PreSwitchOutClearWeatherAbAttr)
|
||||
.attr(PostFaintClearWeatherAbAttr)
|
||||
.bypassFaint(),
|
||||
.bypassFaint()
|
||||
.bypassOnField(),
|
||||
new Ability(Abilities.DESOLATE_LAND, 6)
|
||||
.attr(PostSummonWeatherChangeAbAttr, WeatherType.HARSH_SUN)
|
||||
.attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.HARSH_SUN)
|
||||
.attr(PreSwitchOutClearWeatherAbAttr)
|
||||
.attr(PostFaintClearWeatherAbAttr)
|
||||
.bypassFaint(),
|
||||
.bypassFaint()
|
||||
.bypassOnField(),
|
||||
new Ability(Abilities.DELTA_STREAM, 6)
|
||||
.attr(PostSummonWeatherChangeAbAttr, WeatherType.STRONG_WINDS)
|
||||
.attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.STRONG_WINDS)
|
||||
.attr(PreSwitchOutClearWeatherAbAttr)
|
||||
.attr(PostFaintClearWeatherAbAttr)
|
||||
.bypassFaint(),
|
||||
.bypassFaint()
|
||||
.bypassOnField(),
|
||||
new Ability(Abilities.STAMINA, 7)
|
||||
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => move.category !== MoveCategory.STATUS, Stat.DEF, 1),
|
||||
new Ability(Abilities.WIMP_OUT, 7)
|
||||
|
@ -6263,6 +6274,7 @@ export function initAbilities() {
|
|||
.attr(NoFusionAbilityAbAttr)
|
||||
.attr(PostBattleInitFormChangeAbAttr, () => 0)
|
||||
.attr(PreSwitchOutFormChangeAbAttr, (pokemon) => !pokemon.isFainted() ? 1 : pokemon.formIndex)
|
||||
.bypassOnField()
|
||||
.bypassFaint(),
|
||||
new Ability(Abilities.COMMANDER, 9)
|
||||
.attr(CommanderAbAttr)
|
||||
|
|
|
@ -1493,7 +1493,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
return (this.hp > 0 || ability.isBypassFaint) && !ability.conditions.find(condition => !condition(this));
|
||||
return (((this.isOnField() || ability.isBypassOnField) && this.hp > 0) || ability.isBypassFaint) && !ability.conditions.find(condition => !condition(this));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -45,16 +45,27 @@ describe("Abilities - Arena Trap", () => {
|
|||
expect(enemy).toBe(game.scene.getEnemyPokemon());
|
||||
});
|
||||
|
||||
it("should guarantee double battle with any one LURE", async () => {
|
||||
it("should increase the chance of double battles", async () => {
|
||||
game.override
|
||||
.startingModifier([
|
||||
{ name: "LURE" },
|
||||
])
|
||||
.startingWave(2);
|
||||
.moveset(Moves.SPLASH)
|
||||
.ability(Abilities.ARENA_TRAP)
|
||||
.enemySpecies(Species.SUNKERN)
|
||||
.enemyAbility(Abilities.BALL_FETCH)
|
||||
.enemyMoveset(Moves.SPLASH)
|
||||
.startingWave(9);
|
||||
|
||||
vi.spyOn(game.scene, "getDoubleBattleChance");
|
||||
await game.classicMode.startBattle();
|
||||
|
||||
expect(game.scene.getEnemyField().length).toBe(2);
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.doKillOpponents();
|
||||
await game.toNextWave();
|
||||
expect(game.scene.getDoubleBattleChance).toHaveLastReturnedWith(8);
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.doKillOpponents();
|
||||
await game.toNextWave();
|
||||
expect(game.scene.getDoubleBattleChance).toHaveLastReturnedWith(2);
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
|
@ -223,3 +223,45 @@ describe("Abilities - Commander", () => {
|
|||
expect(enemy.isFullHp()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Abilities - Commander", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
|
||||
beforeAll(() => {
|
||||
phaserGame = new Phaser.Game({
|
||||
type: Phaser.HEADLESS,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
});
|
||||
|
||||
it("should increase the chance of double battles", async () => {
|
||||
game.override
|
||||
.moveset(Moves.SPLASH)
|
||||
.ability(Abilities.COMMANDER)
|
||||
.enemySpecies(Species.SUNKERN)
|
||||
.enemyAbility(Abilities.BALL_FETCH)
|
||||
.enemyMoveset(Moves.SPLASH)
|
||||
.startingWave(9);
|
||||
|
||||
vi.spyOn(game.scene, "getDoubleBattleChance");
|
||||
await game.classicMode.startBattle();
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.doKillOpponents();
|
||||
await game.toNextWave();
|
||||
expect(game.scene.getDoubleBattleChance).toHaveLastReturnedWith(8);
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.doKillOpponents();
|
||||
await game.toNextWave();
|
||||
expect(game.scene.getDoubleBattleChance).toHaveLastReturnedWith(2);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { Stat } from "#app/enums/stat";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { Species } from "#enums/species";
|
||||
import GameManager from "#test/utils/gameManager";
|
||||
import Phaser from "phaser";
|
||||
import { afterEach, beforeAll, beforeEach, describe, it, expect } from "vitest";
|
||||
import { afterEach, beforeAll, beforeEach, describe, it, expect, vi } from "vitest";
|
||||
|
||||
describe("Abilities - Illuminate", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
|
@ -44,15 +45,26 @@ describe("Abilities - Illuminate", () => {
|
|||
expect(player.getStatStage(Stat.ACC)).toBe(0);
|
||||
});
|
||||
|
||||
it("should guarantee double battle with any one LURE", async () => {
|
||||
it("should increase the chance of double battles", async () => {
|
||||
game.override
|
||||
.startingModifier([
|
||||
{ name: "LURE" },
|
||||
])
|
||||
.startingWave(2);
|
||||
.moveset(Moves.SPLASH)
|
||||
.ability(Abilities.ILLUMINATE)
|
||||
.enemySpecies(Species.SUNKERN)
|
||||
.enemyAbility(Abilities.BALL_FETCH)
|
||||
.enemyMoveset(Moves.SPLASH)
|
||||
.startingWave(9);
|
||||
|
||||
vi.spyOn(game.scene, "getDoubleBattleChance");
|
||||
await game.classicMode.startBattle();
|
||||
|
||||
expect(game.scene.getEnemyField().length).toBe(2);
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.doKillOpponents();
|
||||
await game.toNextWave();
|
||||
expect(game.scene.getDoubleBattleChance).toHaveLastReturnedWith(8);
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.doKillOpponents();
|
||||
await game.toNextWave();
|
||||
expect(game.scene.getDoubleBattleChance).toHaveLastReturnedWith(2);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -53,15 +53,28 @@ describe("Abilities - No Guard", () => {
|
|||
expect(moveEffectPhase.hitCheck).toHaveReturnedWith(true);
|
||||
});
|
||||
|
||||
it("should guarantee double battle with any one LURE", async () => {
|
||||
game.override
|
||||
.startingModifier([
|
||||
{ name: "LURE" },
|
||||
])
|
||||
.startingWave(2);
|
||||
|
||||
it("should increase the chance of double battles", async () => {
|
||||
game.override
|
||||
.moveset(Moves.SPLASH)
|
||||
.ability(Abilities.NO_GUARD)
|
||||
.enemySpecies(Species.SUNKERN)
|
||||
.enemyAbility(Abilities.BALL_FETCH)
|
||||
.enemyMoveset(Moves.SPLASH)
|
||||
.startingWave(9);
|
||||
|
||||
vi.spyOn(game.scene, "getDoubleBattleChance");
|
||||
await game.classicMode.startBattle();
|
||||
|
||||
expect(game.scene.getEnemyField().length).toBe(2);
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.doKillOpponents();
|
||||
await game.toNextWave();
|
||||
expect(game.scene.getDoubleBattleChance).toHaveLastReturnedWith(8);
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.doKillOpponents();
|
||||
await game.toNextWave();
|
||||
expect(game.scene.getDoubleBattleChance).toHaveLastReturnedWith(2);
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -488,7 +488,6 @@ describe("Abilities - Parental Bond", () => {
|
|||
game.doSwitchPokemon(2);
|
||||
await game.toNextTurn();
|
||||
|
||||
// TODO: Update hit count to 1 once Future Sight is fixed to not activate abilities if user is off the field
|
||||
expect(enemyPokemon.damageAndUpdate).toHaveBeenCalledTimes(2);
|
||||
expect(enemyPokemon.damageAndUpdate).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -55,8 +55,6 @@ describe("Abilities - Pastel Veil", () => {
|
|||
const magikarp = game.scene.getPlayerField()[0];
|
||||
ponyta.abilityIndex = 1;
|
||||
|
||||
expect(ponyta.hasAbility(Abilities.PASTEL_VEIL)).toBe(true);
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
game.move.select(Moves.TOXIC_THREAD, 1, BattlerIndex.PLAYER);
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ function testMoveEffectiveness(game: GameManager, move: Moves, targetSpecies: Sp
|
|||
|
||||
const user = game.scene.addPlayerPokemon(getPokemonSpecies(Species.SNORLAX), 5);
|
||||
const target = game.scene.addEnemyPokemon(getPokemonSpecies(targetSpecies), 5, TrainerSlot.NONE);
|
||||
game.scene.field.add(user);
|
||||
game.scene.field.add(target);
|
||||
|
||||
if (teraType !== undefined) {
|
||||
overrideHeldItems(target, false);
|
||||
|
|
Loading…
Reference in New Issue