Moved empty moveset verification mapping thing to upgrade script bc i wanted to
This commit is contained in:
parent
2746a658df
commit
102554cdb7
|
@ -3273,13 +3273,13 @@ export class ConditionalUserFieldStatusEffectImmunityAbAttr extends UserFieldSta
|
|||
|
||||
/**
|
||||
* Conditionally provides immunity to stat drop effects to the user's field.
|
||||
*
|
||||
*
|
||||
* Used by {@linkcode Abilities.FLOWER_VEIL | Flower Veil}.
|
||||
*/
|
||||
export class ConditionalUserFieldProtectStatAbAttr extends PreStatStageChangeAbAttr {
|
||||
/** {@linkcode BattleStat} to protect or `undefined` if **all** {@linkcode BattleStat} are protected */
|
||||
protected protectedStat?: BattleStat;
|
||||
|
||||
|
||||
/** If the method evaluates to true, the stat will be protected. */
|
||||
protected condition: (target: Pokemon) => boolean;
|
||||
|
||||
|
@ -3296,7 +3296,7 @@ export class ConditionalUserFieldProtectStatAbAttr extends PreStatStageChangeAbA
|
|||
* @param stat The stat being affected
|
||||
* @param cancelled Holds whether the stat change was already prevented.
|
||||
* @param args Args[0] is the target pokemon of the stat change.
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
override canApplyPreStatStageChange(pokemon: Pokemon, passive: boolean, simulated: boolean, stat: BattleStat, cancelled: BooleanHolder, args: [Pokemon, ...any]): boolean {
|
||||
const target = args[0];
|
||||
|
@ -3428,7 +3428,7 @@ export class BonusCritAbAttr extends AbAttr {
|
|||
|
||||
/**
|
||||
* Apply the bonus crit ability by increasing the value in the provided number holder by 1
|
||||
*
|
||||
*
|
||||
* @param pokemon The pokemon with the BonusCrit ability (unused)
|
||||
* @param passive Unused
|
||||
* @param simulated Unused
|
||||
|
@ -3581,7 +3581,7 @@ export class PreWeatherEffectAbAttr extends AbAttr {
|
|||
args: any[]): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
applyPreWeatherEffect(
|
||||
pokemon: Pokemon,
|
||||
passive: boolean,
|
||||
|
@ -4143,25 +4143,24 @@ export class PostTurnRestoreBerryAbAttr extends PostTurnAbAttr {
|
|||
* Used by {@linkcode Abilities.CUD_CHEW}.
|
||||
*/
|
||||
export class RepeatBerryNextTurnAbAttr extends PostTurnAbAttr {
|
||||
constructor() {
|
||||
super(true);
|
||||
}
|
||||
// no need for constructor; all it does is set `showAbility` which we override before triggering anyways
|
||||
|
||||
/**
|
||||
* @returns `true` if the pokemon ate anything last turn
|
||||
*/
|
||||
override canApply(pokemon: Pokemon, _passive: boolean, _simulated: boolean, _args: any[]): boolean {
|
||||
this.showAbility = true; // force ability popup if ability triggers
|
||||
return !!pokemon.summonData.berriesEatenLast.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cause this {@linkcode Pokemon} to regurgitate and eat all berries
|
||||
* inside its `berriesEatenLast` array.
|
||||
* @param pokemon The pokemon having the tummy ache
|
||||
* @param _passive N/A
|
||||
* @param _simulated N/A
|
||||
* @param _cancelled N/A
|
||||
* @param _args N/A
|
||||
* @param pokemon - The pokemon having the tummy ache
|
||||
* @param _passive - N/A
|
||||
* @param _simulated - N/A
|
||||
* @param _cancelled - N/A
|
||||
* @param _args - N/A
|
||||
*/
|
||||
override apply(pokemon: Pokemon, _passive: boolean, _simulated: boolean, _cancelled: BooleanHolder | null, _args: any[]): void {
|
||||
// play berry animation
|
||||
|
@ -4182,6 +4181,7 @@ export class RepeatBerryNextTurnAbAttr extends PostTurnAbAttr {
|
|||
* @returns `true` if the pokemon ate anything this turn (we move it into `battleData`)
|
||||
*/
|
||||
override canApplyPostTurn(pokemon: Pokemon, _passive: boolean, _simulated: boolean, _args: any[]): boolean {
|
||||
this.showAbility = false; // don't show popup for turn end berry moving (should ideally be hidden)
|
||||
return !!pokemon.turnData.berriesEaten.length;
|
||||
}
|
||||
|
||||
|
|
|
@ -2694,7 +2694,9 @@ export class EatBerryAttr extends MoveEffectAttr {
|
|||
if (!preserve.value) {
|
||||
this.reduceBerryModifier(target);
|
||||
}
|
||||
this.eatBerry(target);
|
||||
|
||||
// Don't update harvest for berries preserved via Berry pouch (no item dupes lol)
|
||||
this.eatBerry(target, undefined, !preserve.value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -2711,15 +2713,21 @@ export class EatBerryAttr extends MoveEffectAttr {
|
|||
globalScene.updateModifiers(target.isPlayer());
|
||||
}
|
||||
|
||||
eatBerry(consumer: Pokemon, berryOwner: Pokemon = consumer) {
|
||||
// consumer eats berry, owner triggers unburden and similar effects
|
||||
// These are the same under normal circumstances
|
||||
|
||||
/**
|
||||
* Internal function to apply berry effects.
|
||||
*
|
||||
* @param consumer - The {@linkcode Pokemon} eating the berry; assumed to also be owner if `berryOwner` is omitted
|
||||
* @param berryOwner - The {@linkcode Pokemon} whose berry is being eaten; defaults to `consumer` if not specified.
|
||||
* @param updateHarvest - Whether to prevent harvest from tracking berries;
|
||||
* defaults to whether `consumer` equals `berryOwner` (i.e. consuming own berry).
|
||||
*/
|
||||
eatBerry(consumer: Pokemon, berryOwner: Pokemon = consumer, updateHarvest = consumer === berryOwner) {
|
||||
// consumer eats berry, owner triggers unburden and similar effects
|
||||
getBerryEffectFunc(this.chosenBerry.berryType)(consumer);
|
||||
applyPostItemLostAbAttrs(PostItemLostAbAttr, berryOwner, false);
|
||||
applyAbAttrs(HealFromBerryUseAbAttr, consumer, new BooleanHolder(false));
|
||||
|
||||
// Harvest doesn't track berries eaten by other pokemon
|
||||
consumer.recordEatenBerry(this.chosenBerry.berryType, berryOwner !== consumer);
|
||||
consumer.recordEatenBerry(this.chosenBerry.berryType, updateHarvest);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -279,6 +279,12 @@ export enum FieldPosition {
|
|||
}
|
||||
|
||||
export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
/**
|
||||
* This pokemon's {@link https://bulbapedia.bulbagarden.net/wiki/Personality_value | Personality value/PID},
|
||||
* used to determine various parameters of this Pokemon.
|
||||
* Represented as a random 32-bit unsigned integer.
|
||||
* TODO: Stop treating this like a unique ID and stop treating 0 as no pokemon
|
||||
*/
|
||||
public id: number;
|
||||
public name: string;
|
||||
public nickname: string;
|
||||
|
@ -324,7 +330,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
public fusionCustomPokemonData: CustomPokemonData | null;
|
||||
public fusionTeraType: PokemonType;
|
||||
|
||||
public customPokemonData: CustomPokemonData = new CustomPokemonData();
|
||||
public customPokemonData: CustomPokemonData = new CustomPokemonData;
|
||||
|
||||
/**
|
||||
* TODO: Figure out if we can remove this thing
|
||||
|
@ -7892,7 +7898,7 @@ export class PokemonSummonData {
|
|||
public gender: Gender;
|
||||
public fusionGender: Gender;
|
||||
public stats: number[] = [0, 0, 0, 0, 0, 0];
|
||||
public moveset: PokemonMove[];
|
||||
public moveset: PokemonMove[] | null;
|
||||
public illusionBroken: boolean = false;
|
||||
|
||||
// If not initialized this value will not be populated from save data.
|
||||
|
@ -7915,6 +7921,8 @@ export class PokemonSummonData {
|
|||
constructor(source?: PokemonSummonData | Partial<PokemonSummonData>) {
|
||||
if (!isNullOrUndefined(source)) {
|
||||
Object.assign(this, source)
|
||||
this.moveset &&= this.moveset.map(m => PokemonMove.loadMove(m))
|
||||
this.tags &&= this.tags.map(t => loadBattlerTag(t))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,14 @@ import { BattleType } from "#enums/battle-type";
|
|||
import { globalScene } from "#app/global-scene";
|
||||
import type { Gender } from "../data/gender";
|
||||
import { Nature } from "#enums/nature";
|
||||
import type { PokeballType } from "#enums/pokeball";
|
||||
import { PokeballType } from "#enums/pokeball";
|
||||
import { getPokemonSpecies, getPokemonSpeciesForm } from "../data/pokemon-species";
|
||||
import type { Status } from "../data/status-effect";
|
||||
import Pokemon, { EnemyPokemon, PokemonBattleData, PokemonMove, PokemonSummonData } from "../field/pokemon";
|
||||
import { TrainerSlot } from "#enums/trainer-slot";
|
||||
import type { Variant } from "#app/sprites/variant";
|
||||
import type { Biome } from "#enums/biome";
|
||||
import { Moves } from "#enums/moves";
|
||||
import type { Moves } from "#enums/moves";
|
||||
import type { Species } from "#enums/species";
|
||||
import { CustomPokemonData } from "#app/data/custom-pokemon-data";
|
||||
import type { PokemonType } from "#enums/pokemon-type";
|
||||
|
@ -59,11 +59,11 @@ export default class PokemonData {
|
|||
public fusionTeraType: PokemonType;
|
||||
|
||||
public boss: boolean;
|
||||
public bossSegments?: number;
|
||||
public bossSegments: number;
|
||||
|
||||
// Effects that need to be preserved between waves
|
||||
public summonData: PokemonSummonData = new PokemonSummonData();
|
||||
public battleData: PokemonBattleData = new PokemonBattleData();
|
||||
public summonData: PokemonSummonData;
|
||||
public battleData: PokemonBattleData;
|
||||
public summonDataSpeciesFormIndex: number;
|
||||
|
||||
public customPokemonData: CustomPokemonData;
|
||||
|
@ -87,7 +87,7 @@ export default class PokemonData {
|
|||
this.passive = source.passive;
|
||||
this.shiny = sourcePokemon?.isShiny() ?? source.shiny;
|
||||
this.variant = sourcePokemon?.getVariant() ?? source.variant;
|
||||
this.pokeball = source.pokeball;
|
||||
this.pokeball = source.pokeball ?? PokeballType.POKEBALL;
|
||||
this.level = source.level;
|
||||
this.exp = source.exp;
|
||||
this.levelExp = source.levelExp;
|
||||
|
@ -98,7 +98,7 @@ export default class PokemonData {
|
|||
|
||||
// TODO: Can't we move some of this verification stuff to an upgrade script?
|
||||
this.nature = source.nature ?? Nature.HARDY;
|
||||
this.moveset = source.moveset ?? [new PokemonMove(Moves.TACKLE), new PokemonMove(Moves.GROWL)];
|
||||
this.moveset = source.moveset.map((m: any) => PokemonMove.loadMove(m));
|
||||
this.status = source.status ?? null;
|
||||
this.friendship = source.friendship ?? getPokemonSpecies(this.species).baseFriendship;
|
||||
this.metLevel = source.metLevel || 5;
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
import type { SessionSaveMigrator } from "#app/@types/SessionSaveMigrator";
|
||||
import { loadBattlerTag } from "#app/data/battler-tags";
|
||||
import { Status } from "#app/data/status-effect";
|
||||
import { PokemonMove } from "#app/field/pokemon";
|
||||
import type { SessionSaveData } from "#app/system/game-data";
|
||||
import PokemonData from "#app/system/pokemon-data";
|
||||
import type PokemonData from "#app/system/pokemon-data";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { PokeballType } from "#enums/pokeball";
|
||||
|
||||
/**
|
||||
* Migrate all lingering rage fist data inside `CustomPokemonData`,
|
||||
|
@ -23,23 +21,26 @@ const migratePartyData: SessionSaveMigrator = {
|
|||
pkmnData.status.sleepTurnsRemaining,
|
||||
);
|
||||
// remove empty moves from moveset
|
||||
pkmnData.moveset = pkmnData.moveset.filter(m => !!m) ?? [
|
||||
new PokemonMove(Moves.TACKLE),
|
||||
new PokemonMove(Moves.GROWL),
|
||||
];
|
||||
pkmnData.pokeball ??= PokeballType.POKEBALL;
|
||||
pkmnData.summonData.tags = pkmnData.summonData.tags.map((t: any) => loadBattlerTag(t));
|
||||
pkmnData.moveset = (pkmnData.moveset ?? [new PokemonMove(Moves.TACKLE), new PokemonMove(Moves.GROWL)]).filter(
|
||||
m => !!m,
|
||||
);
|
||||
// only edit summondata moveset if exists
|
||||
pkmnData.summonData.moveset &&= pkmnData.summonData.moveset.filter(m => !!m);
|
||||
|
||||
if (
|
||||
pkmnData.customPokemonData &&
|
||||
"hitsRecCount" in pkmnData.customPokemonData &&
|
||||
typeof pkmnData.customPokemonData["hitsRecCount"] === "number"
|
||||
) {
|
||||
pkmnData.battleData.hitCount = pkmnData.customPokemonData?.["hitsRecCount"];
|
||||
// transfer old hit count stat to battleData.
|
||||
// No need to reset it as new Pokemon
|
||||
pkmnData.battleData.hitCount = pkmnData.customPokemonData["hitsRecCount"];
|
||||
}
|
||||
pkmnData = new PokemonData(pkmnData);
|
||||
return pkmnData;
|
||||
};
|
||||
|
||||
data.party.forEach(mapParty);
|
||||
data.enemyParty.forEach(mapParty);
|
||||
data.party = data.party.map(mapParty);
|
||||
data.enemyParty = data.enemyParty.map(mapParty);
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { RepeatBerryNextTurnAbAttr } from "#app/data/abilities/ability";
|
||||
import { getBerryEffectFunc } from "#app/data/berry";
|
||||
import Pokemon from "#app/field/pokemon";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
import { BerryType } from "#enums/berry-type";
|
||||
import { Moves } from "#enums/moves";
|
||||
|
@ -65,6 +66,37 @@ describe("Abilities - Cud Chew", () => {
|
|||
expect(farigiraf.turnData.berriesEaten).toEqual([]);
|
||||
});
|
||||
|
||||
it("shouldn't show ability popup for end-of-turn storage", async () => {
|
||||
const abDisplaySpy = vi.spyOn(globalScene, "queueAbilityDisplay");
|
||||
await game.classicMode.startBattle([Species.FARIGIRAF]);
|
||||
|
||||
const farigiraf = game.scene.getPlayerPokemon()!;
|
||||
farigiraf.hp = 1; // needed to allow sitrus procs
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.phaseInterceptor.to("TurnEndPhase");
|
||||
|
||||
// doesn't trigger since cud chew hasn't eaten berry yet
|
||||
expect(abDisplaySpy).not.toHaveBeenCalledWith(farigiraf);
|
||||
await game.toNextTurn();
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.phaseInterceptor.to("BerryPhase");
|
||||
|
||||
// globalScene.queueAbilityDisplay should be called twice: once to show cud chew before regurgitating berries,
|
||||
// once to hide after finishing application
|
||||
expect(abDisplaySpy).toBeCalledTimes(2);
|
||||
expect(abDisplaySpy.mock.calls[0][0]).toBe(farigiraf);
|
||||
expect(abDisplaySpy.mock.calls[0][2]).toBe(true);
|
||||
expect(abDisplaySpy.mock.calls[1][0]).toBe(farigiraf);
|
||||
expect(abDisplaySpy.mock.calls[1][2]).toBe(false);
|
||||
|
||||
await game.phaseInterceptor.to("TurnEndPhase");
|
||||
|
||||
// not called again at turn end
|
||||
expect(abDisplaySpy).toBeCalledTimes(2);
|
||||
});
|
||||
|
||||
it("can store multiple berries across 2 turns with teatime", async () => {
|
||||
// always eat first berry for stuff cheeks & company
|
||||
vi.spyOn(Pokemon.prototype, "randSeedInt").mockReturnValue(0);
|
||||
|
|
|
@ -254,7 +254,7 @@ describe("Abilities - Harvest", () => {
|
|||
game.move.select(Moves.SPLASH);
|
||||
await game.phaseInterceptor.to("TurnEndPhase", false);
|
||||
|
||||
// won;t trigger harvest since we didn't lose the berry (it just doesn't ever add it to the array)
|
||||
// won't trigger harvest since we didn't lose the berry (it just doesn't ever add it to the array)
|
||||
expect(game.scene.getPlayerPokemon()?.battleData.berriesEaten).toEqual([]);
|
||||
expectBerriesContaining(...initBerries);
|
||||
});
|
||||
|
|
|
@ -6,9 +6,6 @@ import type BattleScene from "#app/battle-scene";
|
|||
import { Moves } from "#app/enums/moves";
|
||||
import { PokemonType } from "#enums/pokemon-type";
|
||||
import { CustomPokemonData } from "#app/data/custom-pokemon-data";
|
||||
import PokemonData from "#app/system/pokemon-data";
|
||||
import { PlayerPokemon } from "#app/field/pokemon";
|
||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||
|
||||
describe("Spec - Pokemon", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
|
@ -212,29 +209,4 @@ describe("Spec - Pokemon", () => {
|
|||
expect(types[1]).toBe(PokemonType.DARK);
|
||||
});
|
||||
});
|
||||
|
||||
// TODO: Remove/rework after save data overhaul
|
||||
it("should preserve common fields when converting to and from PokemonData", async () => {
|
||||
await game.classicMode.startBattle([Species.ALAKAZAM]);
|
||||
const alakazam = game.scene.getPlayerPokemon()!;
|
||||
expect(alakazam).toBeDefined();
|
||||
|
||||
alakazam.hp = 5;
|
||||
const alakaData = new PokemonData(alakazam);
|
||||
const alaka2 = new PlayerPokemon(
|
||||
getPokemonSpecies(Species.ALAKAZAM),
|
||||
5,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
alakaData,
|
||||
);
|
||||
for (const key of Object.keys(alakazam).filter(k => k in alakaData)) {
|
||||
expect(alakazam[key]).toEqual(alaka2[key]);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -32,6 +32,7 @@ describe("Moves - Rage Fist", () => {
|
|||
.moveset([Moves.RAGE_FIST, Moves.SPLASH, Moves.SUBSTITUTE, Moves.TIDY_UP])
|
||||
.startingLevel(100)
|
||||
.enemyLevel(1)
|
||||
.enemySpecies(Species.MAGIKARP)
|
||||
.enemyAbility(Abilities.BALL_FETCH)
|
||||
.enemyMoveset(Moves.DOUBLE_KICK);
|
||||
|
||||
|
@ -39,9 +40,7 @@ describe("Moves - Rage Fist", () => {
|
|||
});
|
||||
|
||||
it("should gain power per hit taken", async () => {
|
||||
game.override.enemySpecies(Species.MAGIKARP);
|
||||
|
||||
await game.classicMode.startBattle([Species.MAGIKARP]);
|
||||
await game.classicMode.startBattle([Species.FEEBAS]);
|
||||
|
||||
game.move.select(Moves.RAGE_FIST);
|
||||
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
|
||||
|
@ -51,9 +50,7 @@ describe("Moves - Rage Fist", () => {
|
|||
});
|
||||
|
||||
it("caps at 6 hits taken", async () => {
|
||||
game.override.enemySpecies(Species.MAGIKARP);
|
||||
|
||||
await game.classicMode.startBattle([Species.MAGIKARP]);
|
||||
await game.classicMode.startBattle([Species.FEEBAS]);
|
||||
|
||||
// spam splash against magikarp hitting us 2 times per turn
|
||||
game.move.select(Moves.SPLASH);
|
||||
|
@ -72,10 +69,10 @@ describe("Moves - Rage Fist", () => {
|
|||
expect(move.calculateBattlePower).toHaveLastReturnedWith(350);
|
||||
});
|
||||
|
||||
it("should not count subsitute hits or confusion damage", async () => {
|
||||
it("should not count substitute hits or confusion damage", async () => {
|
||||
game.override.enemySpecies(Species.SHUCKLE).enemyMoveset([Moves.CONFUSE_RAY, Moves.DOUBLE_KICK]);
|
||||
|
||||
await game.classicMode.startBattle([Species.MAGIKARP]);
|
||||
await game.classicMode.startBattle([Species.REGIROCK]);
|
||||
|
||||
game.move.select(Moves.SUBSTITUTE);
|
||||
await game.forceEnemyMove(Moves.DOUBLE_KICK);
|
||||
|
@ -92,68 +89,52 @@ describe("Moves - Rage Fist", () => {
|
|||
await game.toNextTurn();
|
||||
|
||||
game.move.select(Moves.RAGE_FIST);
|
||||
await game.forceEnemyMove(Moves.CONFUSE_RAY);
|
||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]);
|
||||
await game.move.forceConfusionActivation(true);
|
||||
await game.forceEnemyMove(Moves.DOUBLE_KICK);
|
||||
await game.phaseInterceptor.to("BerryPhase");
|
||||
await game.toNextTurn();
|
||||
|
||||
// didn't go up
|
||||
// didn't go up from hitting ourself
|
||||
expect(game.scene.getPlayerPokemon()?.battleData.hitCount).toBe(0);
|
||||
|
||||
await game.toNextTurn();
|
||||
|
||||
game.move.select(Moves.RAGE_FIST);
|
||||
await game.forceEnemyMove(Moves.DOUBLE_KICK);
|
||||
await game.move.forceConfusionActivation(false);
|
||||
await game.toNextTurn();
|
||||
|
||||
expect(move.calculateBattlePower).toHaveLastReturnedWith(150);
|
||||
expect(game.scene.getPlayerPokemon()?.battleData.hitCount).toBe(2);
|
||||
});
|
||||
|
||||
it("should maintain hits recieved between wild waves", async () => {
|
||||
game.override.enemySpecies(Species.MAGIKARP).startingWave(1);
|
||||
|
||||
await game.classicMode.startBattle([Species.MAGIKARP]);
|
||||
await game.classicMode.startBattle([Species.FEEBAS]);
|
||||
|
||||
game.move.select(Moves.RAGE_FIST);
|
||||
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
|
||||
await game.toNextWave();
|
||||
|
||||
game.move.select(Moves.RAGE_FIST);
|
||||
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
|
||||
await game.phaseInterceptor.to("BerryPhase", false);
|
||||
expect(game.scene.getPlayerPokemon()?.battleData.hitCount).toBe(2);
|
||||
|
||||
expect(move.calculateBattlePower).toHaveLastReturnedWith(250);
|
||||
expect(game.scene.getPlayerPokemon()?.battleData.hitCount).toBe(4);
|
||||
});
|
||||
|
||||
it("should reset hits recieved before trainer battles", async () => {
|
||||
game.override.enemySpecies(Species.MAGIKARP).moveset(Moves.DOUBLE_IRON_BASH);
|
||||
await game.classicMode.startBattle([Species.MARSHADOW]);
|
||||
|
||||
const marshadow = game.scene.getPlayerPokemon()!;
|
||||
expect(marshadow).toBeDefined();
|
||||
|
||||
// beat up a magikarp
|
||||
game.move.select(Moves.RAGE_FIST);
|
||||
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
|
||||
await game.phaseInterceptor.to("TurnEndPhase");
|
||||
|
||||
expect(game.scene.getPlayerPokemon()?.battleData.hitCount).toBe(4);
|
||||
expect(move.calculateBattlePower).toHaveLastReturnedWith(250);
|
||||
});
|
||||
|
||||
it("should reset hits recieved before trainer battles", async () => {
|
||||
await game.classicMode.startBattle([Species.IRON_HANDS]);
|
||||
|
||||
const ironHands = game.scene.getPlayerPokemon()!;
|
||||
expect(ironHands).toBeDefined();
|
||||
|
||||
// beat up a magikarp
|
||||
game.move.select(Moves.RAGE_FIST);
|
||||
await game.forceEnemyMove(Moves.DOUBLE_KICK);
|
||||
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
|
||||
await game.phaseInterceptor.to("TurnEndPhase");
|
||||
|
||||
expect(game.isVictory()).toBe(true);
|
||||
expect(marshadow.battleData.hitCount).toBe(2);
|
||||
expect(ironHands.battleData.hitCount).toBe(2);
|
||||
expect(move.calculateBattlePower).toHaveLastReturnedWith(150);
|
||||
|
||||
game.override.battleType(BattleType.TRAINER);
|
||||
await game.toNextWave();
|
||||
|
||||
expect(game.scene.lastEnemyTrainer).not.toBeNull();
|
||||
expect(marshadow.battleData.hitCount).toBe(0);
|
||||
|
||||
game.move.select(Moves.RAGE_FIST);
|
||||
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
|
||||
await game.phaseInterceptor.to("TurnEndPhase");
|
||||
|
||||
expect(move.calculateBattlePower).toHaveLastReturnedWith(150);
|
||||
expect(ironHands.battleData.hitCount).toBe(0);
|
||||
});
|
||||
|
||||
it("should reset the hitRecCounter if we enter new biome", async () => {
|
||||
|
@ -173,24 +154,39 @@ describe("Moves - Rage Fist", () => {
|
|||
});
|
||||
|
||||
it("should not reset the hitRecCounter if switched out", async () => {
|
||||
game.override.enemySpecies(Species.MAGIKARP).startingWave(1).enemyMoveset(Moves.TACKLE);
|
||||
game.override.enemyMoveset(Moves.TACKLE);
|
||||
|
||||
const getPartyHitCount = () =>
|
||||
game.scene
|
||||
.getPlayerParty()
|
||||
.filter(p => !!p)
|
||||
.map(m => m.battleData.hitCount);
|
||||
|
||||
await game.classicMode.startBattle([Species.CHARIZARD, Species.BLASTOISE]);
|
||||
|
||||
// Charizard hit
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
|
||||
await game.toNextTurn();
|
||||
expect(getPartyHitCount()).toEqual([1, 0]);
|
||||
|
||||
// blastoise switched in & hit
|
||||
game.doSwitchPokemon(1);
|
||||
await game.toNextTurn();
|
||||
expect(getPartyHitCount()).toEqual([1, 1]);
|
||||
|
||||
// charizard switched in & hit
|
||||
game.doSwitchPokemon(1);
|
||||
await game.toNextTurn();
|
||||
expect(getPartyHitCount()).toEqual([2, 1]);
|
||||
|
||||
// Charizard rage fist
|
||||
game.move.select(Moves.RAGE_FIST);
|
||||
await game.phaseInterceptor.to("MoveEndPhase");
|
||||
|
||||
expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(Species.CHARIZARD);
|
||||
const charizard = game.scene.getPlayerPokemon()!;
|
||||
expect(charizard).toBeDefined();
|
||||
expect(charizard.species.speciesId).toBe(Species.CHARIZARD);
|
||||
expect(move.calculateBattlePower).toHaveLastReturnedWith(150);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -576,7 +576,7 @@ export default class GameManager {
|
|||
* Intercepts `TurnStartPhase` and mocks {@linkcode TurnStartPhase.getSpeedOrder}'s return value.
|
||||
* Used to manually modify Pokemon turn order.
|
||||
* Note: This *DOES NOT* account for priority, only speed.
|
||||
* @param {BattlerIndex[]} order The turn order to set
|
||||
* @param order - The turn order to set as an array of {@linkcode BattlerIndex}es.
|
||||
* @example
|
||||
* ```ts
|
||||
* await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER_2]);
|
||||
|
|
Loading…
Reference in New Issue