mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-04 15:32:18 +02:00
Merge 829cfb3011
into dd2f475ded
This commit is contained in:
commit
a210f5cec7
@ -29,7 +29,8 @@ import {
|
|||||||
} from "../status-effect";
|
} from "../status-effect";
|
||||||
import { getTypeDamageMultiplier } from "../type";
|
import { getTypeDamageMultiplier } from "../type";
|
||||||
import { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import { BooleanHolder, NumberHolder, isNullOrUndefined, toDmgValue, randSeedItem, randSeedInt, getEnumValues, toReadableString, type Constructor } from "#app/utils/common";
|
import { BooleanHolder, NumberHolder, isNullOrUndefined, toDmgValue, randSeedItem, randSeedInt, getEnumValues, toReadableString } from "#app/utils/common";
|
||||||
|
import { type Constructor, type nil} from "#app/utils/common";
|
||||||
import { WeatherType } from "#enums/weather-type";
|
import { WeatherType } from "#enums/weather-type";
|
||||||
import type { ArenaTrapTag } from "../arena-tag";
|
import type { ArenaTrapTag } from "../arena-tag";
|
||||||
import { ArenaTagSide, WeakenMoveTypeTag } from "../arena-tag";
|
import { ArenaTagSide, WeakenMoveTypeTag } from "../arena-tag";
|
||||||
@ -4837,6 +4838,142 @@ export class VariableMoveTypeAttr extends MoveAttr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute used to control the Power and Type of Natural Gift.
|
||||||
|
* Takes over the Power calculation of Natural Gift while {@linkcode NaturalGiftTypeAttr}
|
||||||
|
* takes care of the Move Type.
|
||||||
|
* @extends VariablePowerAttr
|
||||||
|
*/
|
||||||
|
export class NaturalGiftPowerAttr extends VariablePowerAttr {
|
||||||
|
/**
|
||||||
|
* Overrides the power of Natural Gift depending on the berry that has been selected.
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* The berry is not consumed until the move has been successfully used
|
||||||
|
* which has a {@linkcode MoveEffectTrigger.POST_TARGET} trigger.
|
||||||
|
*
|
||||||
|
* @param user - The Pokémon using the move.
|
||||||
|
* @param _target - The target Pokémon (unused)
|
||||||
|
* @param _move - The move being used (unused)
|
||||||
|
* @param args - args[0] holds the power of user's move
|
||||||
|
* @returns A boolean indicating whether the move was successfully applied.
|
||||||
|
*/
|
||||||
|
apply(user: Pokemon, _target: Pokemon, _move: Move, args: [NumberHolder]): boolean {
|
||||||
|
const power = args[0];
|
||||||
|
if (!(power instanceof NumberHolder)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const randomBerry = NaturalGiftBerrySelector.getRandomBerry(user);
|
||||||
|
|
||||||
|
if (!randomBerry) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
power.value = randomBerry.getNaturalGiftPower();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute used to control the type of Natural Gift
|
||||||
|
* Takes over the Type calculation of Natural Gift while {@linkcode NaturalGiftPowerAttr}
|
||||||
|
* takes care of the Move power.
|
||||||
|
* @extends VariableMoveTypeAttr
|
||||||
|
*/
|
||||||
|
export class NaturalGiftTypeAttr extends VariableMoveTypeAttr {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the type of Natural Gift depending on the consumed berry.
|
||||||
|
* The item used for the move is not removed here but in {@linkcode MoveEndPhase}
|
||||||
|
* to ensure
|
||||||
|
* @param user - The Pokémon using the move.
|
||||||
|
* @param target - The target Pokémon.
|
||||||
|
* @param move - The move being used.
|
||||||
|
* @param args - args[0] NumberHolder with the move's type.
|
||||||
|
* @returns A boolean indicating whether the move was successfully applied.
|
||||||
|
*/
|
||||||
|
apply(user: Pokemon, target: Pokemon, move: Move, args: [NumberHolder]): boolean {
|
||||||
|
const moveType = args[0];
|
||||||
|
if (!(moveType instanceof NumberHolder)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const randomBerry = NaturalGiftBerrySelector.getRandomBerry(user) as BerryModifier;
|
||||||
|
// Force repick if the berry is somehow not owned by the user
|
||||||
|
if (!randomBerry) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
moveType.value = randomBerry.getNaturalGiftType();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute used to consume the berry selected by {@linkcode NaturalGiftBerrySelector}
|
||||||
|
*/
|
||||||
|
export class NaturalGiftConsumeBerryAttr extends MoveEffectAttr {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param user - The Pokemon using the move
|
||||||
|
* @param _target - The target Pokemon (unused)
|
||||||
|
* @param _move - unused
|
||||||
|
* @param args - unused
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
apply(user: Pokemon, _target: Pokemon, _move: Move, args: any[]): boolean {
|
||||||
|
const berry = NaturalGiftBerrySelector.getSelectedBerry();
|
||||||
|
if (isNullOrUndefined(berry)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
user.loseHeldItem(berry, user.isPlayer());
|
||||||
|
// Natural gift counts as berries eaten for the purpose of harvest, but not for the purpose of cud chew.
|
||||||
|
user.battleData.berriesEaten.push(berry.berryType);
|
||||||
|
globalScene.updateModifiers(user.isPlayer());
|
||||||
|
NaturalGiftBerrySelector.resetBerry();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
// POST_TARGET is used to ensure the berry is consumed only if the move was invoked successfully, regardless of whether or not it hit.
|
||||||
|
super(true, { lastHitOnly: true, trigger: MoveEffectTrigger.POST_TARGET });
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export class NaturalGiftBerrySelector {
|
||||||
|
private static selectedBerry: BerryModifier | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* select random berry from user
|
||||||
|
* @param user - The Pokemon using Natural Gift
|
||||||
|
* @returns A random berry to use in {@linkcode NaturalGiftPowerAttr} and {@linkcode NaturalGiftTypeAttr}
|
||||||
|
*/
|
||||||
|
public static getRandomBerry(user: Pokemon): BerryModifier | null {
|
||||||
|
// Rechoose the berry if it is null or if the user does not have it.
|
||||||
|
if (isNullOrUndefined(this.selectedBerry) || !user.getHeldItems().some(item => this.selectedBerry?.match(item))) {
|
||||||
|
const berries = globalScene.findModifiers(
|
||||||
|
m => m instanceof BerryModifier && m.pokemonId === user.id,
|
||||||
|
user.isPlayer()
|
||||||
|
) as BerryModifier[];
|
||||||
|
this.selectedBerry = berries.at(user.randBattleSeedInt(berries.length)) ?? null;
|
||||||
|
}
|
||||||
|
return this.selectedBerry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getSelectedBerry(): BerryModifier | null {
|
||||||
|
return this.selectedBerry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the selected berry
|
||||||
|
*/
|
||||||
|
public static resetBerry() {
|
||||||
|
this.selectedBerry = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class FormChangeItemTypeAttr extends VariableMoveTypeAttr {
|
export class FormChangeItemTypeAttr extends VariableMoveTypeAttr {
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
const moveType = args[0];
|
const moveType = args[0];
|
||||||
@ -6479,6 +6616,7 @@ export class ChillyReceptionAttr extends ForceSwitchOutAttr {
|
|||||||
return (user, target, move) => globalScene.arena.weather?.weatherType !== WeatherType.SNOW || super.getSwitchOutCondition()(user, target, move);
|
return (user, target, move) => globalScene.arena.weather?.weatherType !== WeatherType.SNOW || super.getSwitchOutCondition()(user, target, move);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RemoveTypeAttr extends MoveEffectAttr {
|
export class RemoveTypeAttr extends MoveEffectAttr {
|
||||||
|
|
||||||
private removedType: PokemonType;
|
private removedType: PokemonType;
|
||||||
@ -9397,13 +9535,13 @@ export function initMoves() {
|
|||||||
new AttackMove(Moves.BRINE, PokemonType.WATER, MoveCategory.SPECIAL, 65, 100, 10, -1, 0, 4)
|
new AttackMove(Moves.BRINE, PokemonType.WATER, MoveCategory.SPECIAL, 65, 100, 10, -1, 0, 4)
|
||||||
.attr(MovePowerMultiplierAttr, (user, target, move) => target.getHpRatio() < 0.5 ? 2 : 1),
|
.attr(MovePowerMultiplierAttr, (user, target, move) => target.getHpRatio() < 0.5 ? 2 : 1),
|
||||||
new AttackMove(Moves.NATURAL_GIFT, PokemonType.NORMAL, MoveCategory.PHYSICAL, -1, 100, 15, -1, 0, 4)
|
new AttackMove(Moves.NATURAL_GIFT, PokemonType.NORMAL, MoveCategory.PHYSICAL, -1, 100, 15, -1, 0, 4)
|
||||||
.makesContact(false)
|
.attr(NaturalGiftPowerAttr)
|
||||||
.unimplemented(),
|
.attr(NaturalGiftTypeAttr)
|
||||||
/*
|
.attr(NaturalGiftConsumeBerryAttr)
|
||||||
NOTE: To whoever tries to implement this, reminder to push to battleData.berriesEaten
|
.condition((user) => {
|
||||||
and enable the harvest test..
|
return user.getHeldItems().some(i => i instanceof BerryModifier);
|
||||||
Do NOT push to berriesEatenLast or else cud chew will puke the berry.
|
})
|
||||||
*/
|
.makesContact(false),
|
||||||
new AttackMove(Moves.FEINT, PokemonType.NORMAL, MoveCategory.PHYSICAL, 30, 100, 10, -1, 2, 4)
|
new AttackMove(Moves.FEINT, PokemonType.NORMAL, MoveCategory.PHYSICAL, 30, 100, 10, -1, 2, 4)
|
||||||
.attr(RemoveBattlerTagAttr, [ BattlerTagType.PROTECTED ])
|
.attr(RemoveBattlerTagAttr, [ BattlerTagType.PROTECTED ])
|
||||||
.attr(RemoveArenaTagsAttr, [ ArenaTagType.QUICK_GUARD, ArenaTagType.WIDE_GUARD, ArenaTagType.MAT_BLOCK, ArenaTagType.CRAFTY_SHIELD ], false)
|
.attr(RemoveArenaTagsAttr, [ ArenaTagType.QUICK_GUARD, ArenaTagType.WIDE_GUARD, ArenaTagType.MAT_BLOCK, ArenaTagType.CRAFTY_SHIELD ], false)
|
||||||
|
@ -24,7 +24,7 @@ import type { PokeballType } from "#enums/pokeball";
|
|||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { type PermanentStat, type TempBattleStat, BATTLE_STATS, Stat, TEMP_BATTLE_STATS } from "#enums/stat";
|
import { type PermanentStat, type TempBattleStat, BATTLE_STATS, Stat, TEMP_BATTLE_STATS } from "#enums/stat";
|
||||||
import { StatusEffect } from "#enums/status-effect";
|
import { StatusEffect } from "#enums/status-effect";
|
||||||
import type { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import {
|
import {
|
||||||
type DoubleBattleChanceBoosterModifierType,
|
type DoubleBattleChanceBoosterModifierType,
|
||||||
@ -1840,6 +1840,20 @@ export class LevelIncrementBoosterModifier extends PersistentModifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const berryNaturalGiftMap: { [key in BerryType]: { power: number; type: PokemonType } } = {
|
||||||
|
[BerryType.SITRUS]: { power: 80, type: PokemonType.PSYCHIC },
|
||||||
|
[BerryType.LUM]: { power: 80, type: PokemonType.FLYING },
|
||||||
|
[BerryType.ENIGMA]: { power: 100, type: PokemonType.BUG },
|
||||||
|
[BerryType.LIECHI]: { power: 100, type: PokemonType.GRASS },
|
||||||
|
[BerryType.GANLON]: { power: 100, type: PokemonType.ICE },
|
||||||
|
[BerryType.PETAYA]: { power: 100, type: PokemonType.POISON },
|
||||||
|
[BerryType.APICOT]: { power: 100, type: PokemonType.GROUND },
|
||||||
|
[BerryType.SALAC]: { power: 100, type: PokemonType.FIGHTING },
|
||||||
|
[BerryType.LANSAT]: { power: 100, type: PokemonType.FLYING },
|
||||||
|
[BerryType.STARF]: { power: 100, type: PokemonType.PSYCHIC },
|
||||||
|
[BerryType.LEPPA]: { power: 80, type: PokemonType.FIGHTING },
|
||||||
|
};
|
||||||
|
|
||||||
export class BerryModifier extends PokemonHeldItemModifier {
|
export class BerryModifier extends PokemonHeldItemModifier {
|
||||||
public berryType: BerryType;
|
public berryType: BerryType;
|
||||||
public consumed: boolean;
|
public consumed: boolean;
|
||||||
@ -1899,6 +1913,14 @@ export class BerryModifier extends PokemonHeldItemModifier {
|
|||||||
}
|
}
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getNaturalGiftPower(): number {
|
||||||
|
return berryNaturalGiftMap[this.berryType].power ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
getNaturalGiftType(): PokemonType {
|
||||||
|
return berryNaturalGiftMap[this.berryType].type ?? null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PreserveBerryModifier extends PersistentModifier {
|
export class PreserveBerryModifier extends PersistentModifier {
|
||||||
|
164
test/moves/natural_gift.test.ts
Normal file
164
test/moves/natural_gift.test.ts
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
import { Moves } from "#enums/moves";
|
||||||
|
import { BattlerIndex } from "#app/battle";
|
||||||
|
import { Species } from "#enums/species";
|
||||||
|
import { Abilities } from "#enums/abilities";
|
||||||
|
import { MoveResult } from "#app/field/pokemon";
|
||||||
|
import type Pokemon from "#app/field/pokemon";
|
||||||
|
import { BerryType } from "#enums/berry-type";
|
||||||
|
import GameManager from "#test/testUtils/gameManager";
|
||||||
|
import Phaser from "phaser";
|
||||||
|
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
import { NaturalGiftBerrySelector } from "#app/data/moves/move";
|
||||||
|
|
||||||
|
describe("Moves - Natural Gift", () => {
|
||||||
|
let phaserGame: Phaser.Game;
|
||||||
|
let game: GameManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count the number of held items a Pokemon has, accounting for stacks of multiple items.
|
||||||
|
*/
|
||||||
|
function getHeldItemCount(pokemon: Pokemon): number {
|
||||||
|
const stackCounts = pokemon.getHeldItems().map(m => m.getStackCount());
|
||||||
|
if (stackCounts.length) {
|
||||||
|
return stackCounts.reduce((a, b) => a + b);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
phaserGame = new Phaser.Game({
|
||||||
|
type: Phaser.HEADLESS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
game.phaseInterceptor.restoreOg();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
game = new GameManager(phaserGame);
|
||||||
|
game.override
|
||||||
|
.battleStyle("single")
|
||||||
|
.disableCrits()
|
||||||
|
.moveset(Moves.NATURAL_GIFT)
|
||||||
|
.ability(Abilities.BALL_FETCH)
|
||||||
|
.enemyAbility(Abilities.BALL_FETCH)
|
||||||
|
.enemySpecies(Species.RATTATA)
|
||||||
|
.enemyMoveset(Moves.SPLASH)
|
||||||
|
.startingLevel(10)
|
||||||
|
.enemyLevel(100);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* There is currently no way to test interaction with heavy rain(Weather), harsh sunlight(Weather) and Powder(Move)
|
||||||
|
* since there are currently no berries that change the type to Fire/Water
|
||||||
|
*/
|
||||||
|
it("should deal double damage to Fighting type if Sitrus Berry is consumed", async () => {
|
||||||
|
game.override
|
||||||
|
.startingHeldItems([{ name: "BERRY", type: BerryType.SITRUS, count: 3 }])
|
||||||
|
.enemySpecies(Species.MACHAMP);
|
||||||
|
|
||||||
|
await game.classicMode.startBattle([Species.BULBASAUR]);
|
||||||
|
const player = game.scene.getPlayerPokemon()!;
|
||||||
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
|
|
||||||
|
const effectivenessSpy = vi.spyOn(enemy, "getMoveEffectiveness");
|
||||||
|
|
||||||
|
game.move.select(Moves.NATURAL_GIFT);
|
||||||
|
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
expect(getHeldItemCount(player)).toBe(2);
|
||||||
|
expect(effectivenessSpy).toHaveReturnedWith(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should deal half damage to Steel type if Sitrus Berry is consumed", async () => {
|
||||||
|
game.override.startingHeldItems([{ name: "BERRY", type: BerryType.SITRUS, count: 3 }]).enemySpecies(Species.KLINK);
|
||||||
|
|
||||||
|
await game.classicMode.startBattle([Species.BULBASAUR]);
|
||||||
|
const player = game.scene.getPlayerPokemon()!;
|
||||||
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
|
|
||||||
|
const effectivenessSpy = vi.spyOn(enemy, "getMoveEffectiveness");
|
||||||
|
|
||||||
|
game.move.select(Moves.NATURAL_GIFT);
|
||||||
|
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
expect(getHeldItemCount(player)).toBe(2);
|
||||||
|
expect(effectivenessSpy).toHaveReturnedWith(0.5);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ganlon Berry should turn Natural Gift to Ice type (1/2x dmg to Water type).
|
||||||
|
* With Electrify Natural Gift should deal 2x dmg to Water type
|
||||||
|
*/
|
||||||
|
it("should not override Electrify (deal double damage against Water pkm with Ganlon Berry)", async () => {
|
||||||
|
game.override
|
||||||
|
.startingHeldItems([{ name: "BERRY", type: BerryType.GANLON, count: 3 }])
|
||||||
|
.enemyMoveset(Moves.ELECTRIFY)
|
||||||
|
.enemySpecies(Species.MAGIKARP);
|
||||||
|
|
||||||
|
await game.classicMode.startBattle([Species.BULBASAUR]);
|
||||||
|
const player = game.scene.getPlayerPokemon()!;
|
||||||
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
|
|
||||||
|
const effectivenessSpy = vi.spyOn(enemy, "getMoveEffectiveness");
|
||||||
|
|
||||||
|
game.move.select(Moves.NATURAL_GIFT);
|
||||||
|
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
expect(getHeldItemCount(player)).toBe(2);
|
||||||
|
expect(effectivenessSpy).toHaveReturnedWith(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should fail if no berries are held", async () => {
|
||||||
|
game.override.startingHeldItems([]);
|
||||||
|
|
||||||
|
await game.classicMode.startBattle([Species.BULBASAUR]);
|
||||||
|
const player = game.scene.getPlayerPokemon()!;
|
||||||
|
|
||||||
|
game.move.select(Moves.NATURAL_GIFT);
|
||||||
|
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
expect(player.getLastXMoves(1)[0].result).toBe(MoveResult.FAIL);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not be affected by Normalize", async () => {
|
||||||
|
game.override
|
||||||
|
.startingHeldItems([{ name: "BERRY", type: BerryType.SITRUS, count: 3 }])
|
||||||
|
.ability(Abilities.NORMALIZE)
|
||||||
|
.enemySpecies(Species.MACHAMP);
|
||||||
|
|
||||||
|
await game.classicMode.startBattle([Species.BULBASAUR]);
|
||||||
|
const player = game.scene.getPlayerPokemon()!;
|
||||||
|
expect(getHeldItemCount(player)).toBe(3);
|
||||||
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
|
|
||||||
|
const effectivenessSpy = vi.spyOn(enemy, "getMoveEffectiveness");
|
||||||
|
|
||||||
|
game.move.select(Moves.NATURAL_GIFT);
|
||||||
|
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
expect(getHeldItemCount(player)).toBe(2);
|
||||||
|
expect(effectivenessSpy).toHaveReturnedWith(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should clear BerryType once successfully used", async () => {
|
||||||
|
game.override
|
||||||
|
.startingHeldItems([{ name: "BERRY", type: BerryType.SITRUS, count: 3 }])
|
||||||
|
.enemySpecies(Species.MACHAMP);
|
||||||
|
|
||||||
|
await game.classicMode.startBattle([Species.BULBASAUR]);
|
||||||
|
const player = game.scene.getPlayerPokemon()!;
|
||||||
|
expect(getHeldItemCount(player)).toBe(3);
|
||||||
|
|
||||||
|
game.move.select(Moves.NATURAL_GIFT);
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
expect(NaturalGiftBerrySelector.getSelectedBerry()).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user