ssssssssss

This commit is contained in:
Bertie690 2025-08-19 21:18:55 -04:00
parent 6aa2d5132f
commit d45b293f7c
3 changed files with 58 additions and 6 deletions

View File

@ -7051,6 +7051,7 @@ export function initAbilities() {
.attr(StatMultiplierAbAttr, Stat.SPATK, 1.5)
.condition(getWeatherCondition(WeatherType.SUNNY, WeatherType.HARSH_SUN)),
new Ability(AbilityId.QUICK_FEET, 4)
// TODO: This should ignore the speed drop, not manually undo it
.conditionalAttr(pokemon => pokemon.status ? pokemon.status.effect === StatusEffect.PARALYSIS : false, StatMultiplierAbAttr, Stat.SPD, 2)
.conditionalAttr(pokemon => !!pokemon.status || pokemon.hasAbility(AbilityId.COMATOSE), StatMultiplierAbAttr, Stat.SPD, 1.5),
new Ability(AbilityId.NORMALIZE, 4)

View File

@ -1,12 +1,13 @@
import { getPokemonNameWithAffix } from "#app/messages";
import { AbilityId } from "#enums/ability-id";
import { BattlerIndex } from "#enums/battler-index";
import { BattlerTagType } from "#enums/battler-tag-type";
import { MoveId } from "#enums/move-id";
import { SpeciesId } from "#enums/species-id";
import { GameManager } from "#test/test-utils/game-manager";
import i18next from "i18next";
import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
describe("Move - Laser Focus", () => {
let phaserGame: Phaser.Game;
@ -38,15 +39,65 @@ describe("Move - Laser Focus", () => {
it("should make the user's next move a guaranteed critical hit", async () => {
await game.classicMode.startBattle([SpeciesId.FEEBAS]);
game.move.use(MoveId.LASER_FOCUS);
await game.toEndOfTurn();
const feebas = game.field.getPlayerPokemon();
const enemy = game.field.getEnemyPokemon();
const critSpy = vi.spyOn(enemy, "getCriticalHitResult");
game.move.use(MoveId.LASER_FOCUS);
await game.toNextTurn();
expect(feebas).toHaveBattlerTag(BattlerTagType.ALWAYS_CRIT);
expect(game).toHaveShownMessage(
i18next.t("battlerTags:laserFocusOnAdd", {
pokemonNameWithAffix: getPokemonNameWithAffix(feebas),
}),
);
game.move.use(MoveId.TACKLE);
await game.toEndOfTurn();
expect(critSpy).toHaveLastReturnedWith(true);
});
it("should disappear at the end of the next turn", async () => {
await game.classicMode.startBattle([SpeciesId.FEEBAS]);
const feebas = game.field.getPlayerPokemon();
const enemy = game.field.getEnemyPokemon();
const critSpy = vi.spyOn(enemy, "getCriticalHitResult");
game.move.use(MoveId.LASER_FOCUS);
await game.toNextTurn();
expect(feebas).toHaveBattlerTag(BattlerTagType.ALWAYS_CRIT);
game.move.use(MoveId.SPLASH);
await game.toNextTurn();
expect(feebas).not.toHaveBattlerTag(BattlerTagType.ALWAYS_CRIT);
game.move.use(MoveId.TACKLE);
await game.toEndOfTurn();
expect(critSpy).toHaveLastReturnedWith(false);
});
it("should boost all attacks until the end of the next turn", async () => {
await game.classicMode.startBattle([SpeciesId.FEEBAS]);
const enemy = game.field.getEnemyPokemon();
const critSpy = vi.spyOn(enemy, "getCriticalHitResult");
game.move.use(MoveId.LASER_FOCUS);
await game.toNextTurn();
game.move.use(MoveId.TACKLE);
await game.move.forceEnemyMove(MoveId.INSTRUCT);
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
await game.toEndOfTurn();
expect(critSpy).toHaveReturnedTimes(2);
expect(critSpy).toHaveLastReturnedWith(true);
expect(critSpy).toHaveNthReturnedWith(2, true);
});
});

View File

@ -340,9 +340,9 @@ export class OverridesHelper extends GameManagerHelper {
* @param crits - `true` to guarantee crits on eligible moves, `false` to force rolls to fail, `null` to disable override
* @remarks
* This does not change any effects that guarantee or block critical hits;
* it merely mocks any chance-based rolls not already at 100%.
* it merely mocks any chance-based rolls not already at 100%. \
* For instance, a Pokemon at +3 crit stages will still critically hit with the override set to `false`,
* whereas a Pokemon at +2 crit stages (50% chance) will not.
* whereas one at +2 crit stages (a 50% chance) will not.
* @returns `this`
*/
public criticalHits(crits: boolean | null): this {