mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-06 15:39:27 +02:00
Cleaned up Stockpile tests
This commit is contained in:
parent
89536fafda
commit
751d824af8
@ -2698,29 +2698,30 @@ export class StockpilingTag extends SerializableBattlerTag {
|
||||
* For each stat, an internal counter is incremented (by 1) if the stat was successfully changed.
|
||||
*/
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
if (this.stockpiledCount < 3) {
|
||||
this.stockpiledCount++;
|
||||
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:stockpilingOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
stockpiledCount: this.stockpiledCount,
|
||||
}),
|
||||
);
|
||||
|
||||
// Attempt to increase DEF and SPDEF by one stage, keeping track of successful changes.
|
||||
globalScene.phaseManager.unshiftNew(
|
||||
"StatStageChangePhase",
|
||||
pokemon.getBattlerIndex(),
|
||||
true,
|
||||
[Stat.SPDEF, Stat.DEF],
|
||||
1,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
this.onStatStagesChanged,
|
||||
);
|
||||
if (this.stockpiledCount >= 3) {
|
||||
return;
|
||||
}
|
||||
this.stockpiledCount++;
|
||||
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("battlerTags:stockpilingOnAdd", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
stockpiledCount: this.stockpiledCount,
|
||||
}),
|
||||
);
|
||||
|
||||
// Attempt to increase DEF and SPDEF by one stage, keeping track of successful changes.
|
||||
globalScene.phaseManager.unshiftNew(
|
||||
"StatStageChangePhase",
|
||||
pokemon.getBattlerIndex(),
|
||||
true,
|
||||
[Stat.SPDEF, Stat.DEF],
|
||||
1,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
this.onStatStagesChanged,
|
||||
);
|
||||
}
|
||||
|
||||
onOverlap(pokemon: Pokemon): void {
|
||||
|
@ -2038,8 +2038,9 @@ export class VariableHealAttr extends HealAttr {
|
||||
private healFunc: (user: Pokemon, target: Pokemon, move: Move) => number,
|
||||
showAnim = false,
|
||||
selfTarget = true,
|
||||
failOnFullHp = true,
|
||||
) {
|
||||
super(1, showAnim, selfTarget);
|
||||
super(1, showAnim, selfTarget, selfTarget);
|
||||
this.healFunc = healFunc;
|
||||
}
|
||||
|
||||
@ -9293,14 +9294,14 @@ export function initMoves() {
|
||||
.partial(), // Does not lock the user, does not stop Pokemon from sleeping
|
||||
// Likely can make use of FrenzyAttr and an ArenaTag (just without the FrenzyMissFunc)
|
||||
new SelfStatusMove(MoveId.STOCKPILE, PokemonType.NORMAL, -1, 20, -1, 0, 3)
|
||||
.condition(user => (user.getTag(StockpilingTag)?.stockpiledCount ?? 0) < 3)
|
||||
.condition(user => (user.getTag(BattlerTagType.STOCKPILING)?.stockpiledCount ?? 0) < 3)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.STOCKPILING, true),
|
||||
new AttackMove(MoveId.SPIT_UP, PokemonType.NORMAL, MoveCategory.SPECIAL, -1, 100, 10, -1, 0, 3)
|
||||
.attr(SpitUpPowerAttr, 100)
|
||||
.condition(hasStockpileStacksCondition)
|
||||
.attr(RemoveBattlerTagAttr, [ BattlerTagType.STOCKPILING ], true),
|
||||
new SelfStatusMove(MoveId.SWALLOW, PokemonType.NORMAL, -1, 10, -1, 0, 3)
|
||||
.attr(VariableHealAttr, swallowHealFunc)
|
||||
.attr(VariableHealAttr, swallowHealFunc, false, true, true)
|
||||
.condition(hasStockpileStacksCondition)
|
||||
.attr(RemoveBattlerTagAttr, [ BattlerTagType.STOCKPILING ], true)
|
||||
.triageMove(),
|
||||
|
@ -1,109 +1,110 @@
|
||||
import { StockpilingTag } from "#data/battler-tags";
|
||||
import { AbilityId } from "#enums/ability-id";
|
||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||
import { MoveId } from "#enums/move-id";
|
||||
import { MoveResult } from "#enums/move-result";
|
||||
import { SpeciesId } from "#enums/species-id";
|
||||
import { Stat } from "#enums/stat";
|
||||
import { TurnInitPhase } from "#phases/turn-init-phase";
|
||||
import { GameManager } from "#test/test-utils/game-manager";
|
||||
import Phaser from "phaser";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
describe("Moves - Stockpile", () => {
|
||||
describe("integration tests", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
|
||||
beforeAll(() => {
|
||||
phaserGame = new Phaser.Game({ type: Phaser.HEADLESS });
|
||||
});
|
||||
beforeAll(() => {
|
||||
phaserGame = new Phaser.Game({ type: Phaser.HEADLESS });
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
});
|
||||
afterEach(() => {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
|
||||
game.override
|
||||
.battleStyle("single")
|
||||
.enemySpecies(SpeciesId.RATTATA)
|
||||
.enemyMoveset(MoveId.SPLASH)
|
||||
.enemyAbility(AbilityId.NONE)
|
||||
.startingLevel(2000)
|
||||
.moveset([MoveId.STOCKPILE, MoveId.SPLASH])
|
||||
.ability(AbilityId.NONE);
|
||||
});
|
||||
game.override
|
||||
.battleStyle("single")
|
||||
.enemySpecies(SpeciesId.RATTATA)
|
||||
.enemyMoveset(MoveId.SPLASH)
|
||||
.enemyAbility(AbilityId.BALL_FETCH)
|
||||
.startingLevel(2000)
|
||||
.ability(AbilityId.BALL_FETCH);
|
||||
});
|
||||
|
||||
it("gains a stockpile stack and raises user's DEF and SPDEF stat stages by 1 on each use, fails at max stacks (3)", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.ABOMASNOW]);
|
||||
it("should gain a stockpile stack and raise DEF and SPDEF when used, up to 3 times", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.ABOMASNOW]);
|
||||
|
||||
const user = game.field.getPlayerPokemon();
|
||||
const user = game.field.getPlayerPokemon();
|
||||
|
||||
// Unfortunately, Stockpile stacks are not directly queryable (i.e. there is no pokemon.getStockpileStacks()),
|
||||
// we just have to know that they're implemented as a BattlerTag.
|
||||
expect(user).toHaveStatStage(Stat.DEF, 0);
|
||||
expect(user).toHaveStatStage(Stat.SPDEF, 0);
|
||||
|
||||
expect(user.getTag(StockpilingTag)).toBeUndefined();
|
||||
expect(user.getStatStage(Stat.DEF)).toBe(0);
|
||||
expect(user.getStatStage(Stat.SPDEF)).toBe(0);
|
||||
// use Stockpile thrice
|
||||
for (let i = 0; i < 3; i++) {
|
||||
game.move.use(MoveId.STOCKPILE);
|
||||
await game.toNextTurn();
|
||||
|
||||
// use Stockpile four times
|
||||
for (let i = 0; i < 4; i++) {
|
||||
game.move.select(MoveId.STOCKPILE);
|
||||
await game.toNextTurn();
|
||||
|
||||
const stockpilingTag = user.getTag(StockpilingTag)!;
|
||||
|
||||
if (i < 3) {
|
||||
// first three uses should behave normally
|
||||
expect(user.getStatStage(Stat.DEF)).toBe(i + 1);
|
||||
expect(user.getStatStage(Stat.SPDEF)).toBe(i + 1);
|
||||
expect(stockpilingTag).toBeDefined();
|
||||
expect(stockpilingTag.stockpiledCount).toBe(i + 1);
|
||||
} else {
|
||||
// fourth should have failed
|
||||
expect(user.getStatStage(Stat.DEF)).toBe(3);
|
||||
expect(user.getStatStage(Stat.SPDEF)).toBe(3);
|
||||
expect(stockpilingTag).toBeDefined();
|
||||
expect(stockpilingTag.stockpiledCount).toBe(3);
|
||||
expect(user.getMoveHistory().at(-1)).toMatchObject({
|
||||
result: MoveResult.FAIL,
|
||||
move: MoveId.STOCKPILE,
|
||||
targets: [user.getBattlerIndex()],
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("gains a stockpile stack even if user's DEF and SPDEF stat stages are at +6", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.ABOMASNOW]);
|
||||
|
||||
const user = game.field.getPlayerPokemon();
|
||||
|
||||
user.setStatStage(Stat.DEF, 6);
|
||||
user.setStatStage(Stat.SPDEF, 6);
|
||||
|
||||
expect(user.getTag(StockpilingTag)).toBeUndefined();
|
||||
expect(user.getStatStage(Stat.DEF)).toBe(6);
|
||||
expect(user.getStatStage(Stat.SPDEF)).toBe(6);
|
||||
|
||||
game.move.select(MoveId.STOCKPILE);
|
||||
await game.phaseInterceptor.to(TurnInitPhase);
|
||||
|
||||
const stockpilingTag = user.getTag(StockpilingTag)!;
|
||||
const stockpilingTag = user.getTag(BattlerTagType.STOCKPILING)!;
|
||||
expect(stockpilingTag).toBeDefined();
|
||||
expect(stockpilingTag.stockpiledCount).toBe(1);
|
||||
expect(user.getStatStage(Stat.DEF)).toBe(6);
|
||||
expect(user.getStatStage(Stat.SPDEF)).toBe(6);
|
||||
expect(stockpilingTag.stockpiledCount).toBe(i + 1);
|
||||
expect(user).toHaveStatStage(Stat.DEF, i + 1);
|
||||
expect(user).toHaveStatStage(Stat.SPDEF, i + 1);
|
||||
}
|
||||
});
|
||||
|
||||
game.move.select(MoveId.STOCKPILE);
|
||||
await game.phaseInterceptor.to(TurnInitPhase);
|
||||
it("should fail when used at max stacks", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.ABOMASNOW]);
|
||||
|
||||
const stockpilingTagAgain = user.getTag(StockpilingTag)!;
|
||||
expect(stockpilingTagAgain).toBeDefined();
|
||||
expect(stockpilingTagAgain.stockpiledCount).toBe(2);
|
||||
expect(user.getStatStage(Stat.DEF)).toBe(6);
|
||||
expect(user.getStatStage(Stat.SPDEF)).toBe(6);
|
||||
const user = game.field.getPlayerPokemon();
|
||||
|
||||
user.addTag(BattlerTagType.STOCKPILING);
|
||||
user.addTag(BattlerTagType.STOCKPILING);
|
||||
user.addTag(BattlerTagType.STOCKPILING);
|
||||
|
||||
const stockpilingTag = user.getTag(BattlerTagType.STOCKPILING)!;
|
||||
expect(stockpilingTag).toBeDefined();
|
||||
expect(stockpilingTag.stockpiledCount).toBe(3);
|
||||
|
||||
game.move.use(MoveId.STOCKPILE);
|
||||
await game.toNextTurn();
|
||||
|
||||
// should have failed
|
||||
expect(user).toHaveStatStage(Stat.DEF, 3);
|
||||
expect(user).toHaveStatStage(Stat.SPDEF, 3);
|
||||
expect(stockpilingTag.stockpiledCount).toBe(3);
|
||||
expect(user).toHaveUsedMove({
|
||||
move: MoveId.STOCKPILE,
|
||||
result: MoveResult.FAIL,
|
||||
});
|
||||
});
|
||||
|
||||
it("gains a stockpile stack even if user's DEF and SPDEF stat stages are at +6", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.ABOMASNOW]);
|
||||
|
||||
const user = game.field.getPlayerPokemon();
|
||||
|
||||
user.setStatStage(Stat.DEF, 6);
|
||||
user.setStatStage(Stat.SPDEF, 6);
|
||||
|
||||
expect(user).not.toHaveBattlerTag(BattlerTagType.STOCKPILING);
|
||||
|
||||
game.move.use(MoveId.STOCKPILE);
|
||||
await game.toNextTurn();
|
||||
|
||||
const stockpilingTag = user.getTag(BattlerTagType.STOCKPILING)!;
|
||||
expect(stockpilingTag).toBeDefined();
|
||||
expect(stockpilingTag.stockpiledCount).toBe(1);
|
||||
expect(user).toHaveStatStage(Stat.DEF, 6);
|
||||
expect(user).toHaveStatStage(Stat.SPDEF, 6);
|
||||
|
||||
game.move.use(MoveId.STOCKPILE);
|
||||
await game.toNextTurn();
|
||||
|
||||
const stockpilingTagAgain = user.getTag(BattlerTagType.STOCKPILING)!;
|
||||
expect(stockpilingTagAgain).toBeDefined();
|
||||
expect(stockpilingTagAgain.stockpiledCount).toBe(2);
|
||||
expect(user).toHaveStatStage(Stat.DEF, 6);
|
||||
expect(user).toHaveStatStage(Stat.SPDEF, 6);
|
||||
});
|
||||
});
|
||||
|
@ -63,8 +63,8 @@ describe("Moves - Swallow & Spit Up - ", () => {
|
||||
game.move.use(MoveId.SWALLOW);
|
||||
await game.toEndOfTurn();
|
||||
|
||||
expect(swalot.getHpRatio()).toBeCloseTo(healPercent / 100, 1);
|
||||
expect(swalot.getTag(StockpilingTag)).toBeUndefined();
|
||||
expect(swalot).toHaveHp((swalot.getMaxHp() * healPercent) / 100 + 1);
|
||||
expect(swalot).not.toHaveBattlerTag(BattlerTagType.STOCKPILING);
|
||||
},
|
||||
);
|
||||
|
||||
@ -74,40 +74,38 @@ describe("Moves - Swallow & Spit Up - ", () => {
|
||||
const player = game.field.getPlayerPokemon();
|
||||
player.hp = 1;
|
||||
|
||||
const stockpilingTag = player.getTag(StockpilingTag)!;
|
||||
expect(stockpilingTag).toBeUndefined();
|
||||
expect(player).not.toHaveBattlerTag(BattlerTagType.STOCKPILING);
|
||||
|
||||
game.move.use(MoveId.SWALLOW);
|
||||
await game.toEndOfTurn();
|
||||
|
||||
expect(player.getLastXMoves()[0]).toMatchObject({
|
||||
expect(player).toHaveUsedMove({
|
||||
move: MoveId.SWALLOW,
|
||||
result: MoveResult.FAIL,
|
||||
});
|
||||
});
|
||||
|
||||
// TODO: Does this consume stacks or not?
|
||||
it.todo("should fail and display message at full HP, consuming stacks", async () => {
|
||||
it("should count as a success and consume stacks despite displaying message at full HP", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.SWALOT]);
|
||||
|
||||
const swalot = game.field.getPlayerPokemon();
|
||||
swalot.addTag(BattlerTagType.STOCKPILING);
|
||||
const stockpilingTag = swalot.getTag(StockpilingTag)!;
|
||||
expect(stockpilingTag).toBeDefined();
|
||||
expect(swalot).toHaveBattlerTag(BattlerTagType.STOCKPILING);
|
||||
|
||||
game.move.use(MoveId.SWALLOW);
|
||||
await game.toEndOfTurn();
|
||||
|
||||
expect(swalot.getLastXMoves()[0]).toMatchObject({
|
||||
// Swallow counted as a "success" as its other effect (removing Stockpile) _did_ work
|
||||
expect(swalot).toHaveUsedMove({
|
||||
move: MoveId.SWALLOW,
|
||||
result: MoveResult.FAIL,
|
||||
result: MoveResult.SUCCESS,
|
||||
});
|
||||
expect(game.textInterceptor.logs).toContain(
|
||||
i18next.t("battle:hpIsFull", {
|
||||
pokemonName: getPokemonNameWithAffix(swalot),
|
||||
}),
|
||||
);
|
||||
expect(stockpilingTag).toBeDefined();
|
||||
expect(swalot).not.toHaveBattlerTag(BattlerTagType.STOCKPILING);
|
||||
});
|
||||
});
|
||||
|
||||
@ -147,13 +145,12 @@ describe("Moves - Swallow & Spit Up - ", () => {
|
||||
|
||||
const player = game.field.getPlayerPokemon();
|
||||
|
||||
const stockpilingTag = player.getTag(StockpilingTag)!;
|
||||
expect(stockpilingTag).toBeUndefined();
|
||||
expect(player).not.toHaveBattlerTag(BattlerTagType.STOCKPILING);
|
||||
|
||||
game.move.use(MoveId.SPIT_UP);
|
||||
await game.toEndOfTurn();
|
||||
|
||||
expect(player.getLastXMoves()[0]).toMatchObject({
|
||||
expect(player).toHaveUsedMove({
|
||||
move: MoveId.SPIT_UP,
|
||||
result: MoveResult.FAIL,
|
||||
});
|
||||
@ -162,28 +159,27 @@ describe("Moves - Swallow & Spit Up - ", () => {
|
||||
|
||||
describe("Stockpile stack removal", () => {
|
||||
it("should undo stat boosts when losing stacks", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.ABOMASNOW]);
|
||||
await game.classicMode.startBattle([SpeciesId.SWALOT]);
|
||||
|
||||
const player = game.field.getPlayerPokemon();
|
||||
player.hp = 1;
|
||||
|
||||
game.move.use(MoveId.STOCKPILE);
|
||||
await game.toNextTurn();
|
||||
|
||||
const stockpilingTag = player.getTag(StockpilingTag)!;
|
||||
expect(stockpilingTag).toBeDefined();
|
||||
expect(player.getStatStage(Stat.DEF)).toBe(1);
|
||||
expect(player.getStatStage(Stat.SPDEF)).toBe(1);
|
||||
expect(player).toHaveBattlerTag(BattlerTagType.STOCKPILING);
|
||||
expect(player).toHaveStatStage(Stat.DEF, 1);
|
||||
expect(player).toHaveStatStage(Stat.SPDEF, 1);
|
||||
|
||||
// remove the prior stat boosts from the log
|
||||
// remove the prior stat boost phases from the log
|
||||
game.phaseInterceptor.clearLogs();
|
||||
|
||||
game.move.use(MoveId.SWALLOW);
|
||||
await game.move.forceEnemyMove(MoveId.ACID_SPRAY);
|
||||
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
|
||||
await game.toEndOfTurn();
|
||||
|
||||
expect(player.getStatStage(Stat.DEF)).toBe(0);
|
||||
expect(player.getStatStage(Stat.SPDEF)).toBe(-2); // +1 --> -1 --> -2
|
||||
expect(player).toHaveStatStage(Stat.DEF, 0);
|
||||
expect(player).toHaveStatStage(Stat.SPDEF, -2); // +1 --> -1 --> -2
|
||||
expect(game.phaseInterceptor.log.filter(l => l === "StatStageChangePhase")).toHaveLength(3);
|
||||
});
|
||||
|
||||
@ -197,21 +193,20 @@ describe("Moves - Swallow & Spit Up - ", () => {
|
||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||
await game.toNextTurn();
|
||||
|
||||
expect(player.getStatStage(Stat.DEF)).toBe(1);
|
||||
expect(player.getStatStage(Stat.SPDEF)).toBe(1);
|
||||
expect(player).toHaveStatStage(Stat.DEF, 1);
|
||||
expect(player).toHaveStatStage(Stat.SPDEF, 1);
|
||||
expect(player.hasAbility(AbilityId.SIMPLE)).toBe(true);
|
||||
|
||||
game.move.use(MoveId.SPIT_UP);
|
||||
game.move.use(MoveId.SWALLOW);
|
||||
await game.move.forceEnemyMove(MoveId.SPLASH);
|
||||
await game.toEndOfTurn();
|
||||
|
||||
// should have fallen by 2 stages from Simple
|
||||
expect(player.getStatStage(Stat.DEF)).toBe(-1);
|
||||
expect(player.getStatStage(Stat.SPDEF)).toBe(-1);
|
||||
expect(player).toHaveStatStage(Stat.DEF, -1);
|
||||
expect(player).toHaveStatStage(Stat.SPDEF, -1);
|
||||
});
|
||||
|
||||
it("should invert stat drops when gaining Contrary", async () => {
|
||||
game.override.enemyAbility(AbilityId.CONTRARY);
|
||||
await game.classicMode.startBattle([SpeciesId.ABOMASNOW]);
|
||||
|
||||
const player = game.field.getPlayerPokemon();
|
||||
@ -221,17 +216,17 @@ describe("Moves - Swallow & Spit Up - ", () => {
|
||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||
await game.toEndOfTurn();
|
||||
|
||||
expect(player.getStatStage(Stat.DEF)).toBe(1);
|
||||
expect(player.getStatStage(Stat.SPDEF)).toBe(1);
|
||||
expect(player.hasAbility(AbilityId.CONTRARY)).toBe(true);
|
||||
expect(player).toHaveStatStage(Stat.DEF, 1);
|
||||
expect(player).toHaveStatStage(Stat.SPDEF, 1);
|
||||
expect(player).toHaveAbilityApplied(AbilityId.CONTRARY);
|
||||
|
||||
game.move.use(MoveId.SPIT_UP);
|
||||
await game.move.forceEnemyMove(MoveId.SPLASH);
|
||||
await game.toEndOfTurn();
|
||||
|
||||
// should have risen 1 stage from Contrary
|
||||
expect(player.getStatStage(Stat.DEF)).toBe(2);
|
||||
expect(player.getStatStage(Stat.SPDEF)).toBe(2);
|
||||
expect(player).toHaveStatStage(Stat.DEF, 2);
|
||||
expect(player).toHaveStatStage(Stat.SPDEF, 2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user