[Bug] Honey Gather and Pickup will only activate if the battle was won (#4903)
* Honey Gather and Pickup will only activate if the battle was won * Add tests for Honey Gather * Moves `highestEndlessWave` and `battles` stats outside of victory condition
This commit is contained in:
parent
4d341bf1fd
commit
9bc046fd64
|
@ -4112,9 +4112,13 @@ export class PostBattleAbAttr extends AbAttr {
|
|||
}
|
||||
|
||||
export class PostBattleLootAbAttr extends PostBattleAbAttr {
|
||||
/**
|
||||
* @param args - `[0]`: boolean for if the battle ended in a victory
|
||||
* @returns `true` if successful
|
||||
*/
|
||||
applyPostBattle(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
|
||||
const postBattleLoot = pokemon.scene.currentBattle.postBattleLoot;
|
||||
if (!simulated && postBattleLoot.length) {
|
||||
if (!simulated && postBattleLoot.length && args[0]) {
|
||||
const randItem = Utils.randSeedItem(postBattleLoot);
|
||||
//@ts-ignore - TODO see below
|
||||
if (pokemon.scene.tryTransferHeldItemModifier(randItem, pokemon, true, 1, true, undefined, false)) { // TODO: fix. This is a promise!?
|
||||
|
@ -4575,28 +4579,28 @@ export class MoneyAbAttr extends PostBattleAbAttr {
|
|||
/**
|
||||
* @param pokemon {@linkcode Pokemon} that is the user of this ability.
|
||||
* @param passive N/A
|
||||
* @param args N/A
|
||||
* @returns true
|
||||
* @param args - `[0]`: boolean for if the battle ended in a victory
|
||||
* @returns `true` if successful
|
||||
*/
|
||||
applyPostBattle(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
|
||||
if (!simulated) {
|
||||
if (!simulated && args[0]) {
|
||||
pokemon.scene.currentBattle.moneyScattered += pokemon.scene.getWaveMoneyAmount(0.2);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a stat change after a Pokémon is summoned,
|
||||
* conditioned on the presence of a specific arena tag.
|
||||
*
|
||||
* @extends {PostSummonStatStageChangeAbAttr}
|
||||
* @extends PostSummonStatStageChangeAbAttr
|
||||
*/
|
||||
export class PostSummonStatStageChangeOnArenaAbAttr extends PostSummonStatStageChangeAbAttr {
|
||||
/**
|
||||
* The type of arena tag that conditions the stat change.
|
||||
* @private
|
||||
* @type {ArenaTagType}
|
||||
*/
|
||||
private tagType: ArenaTagType;
|
||||
|
||||
|
@ -4972,7 +4976,7 @@ class ForceSwitchOutHelper {
|
|||
pokemon.scene.clearEnemyHeldItemModifiers();
|
||||
|
||||
if (switchOutTarget.hp) {
|
||||
pokemon.scene.pushPhase(new BattleEndPhase(pokemon.scene));
|
||||
pokemon.scene.pushPhase(new BattleEndPhase(pokemon.scene, false));
|
||||
pokemon.scene.pushPhase(new NewBattlePhase(pokemon.scene));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6082,7 +6082,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
|||
user.scene.clearEnemyHeldItemModifiers();
|
||||
|
||||
if (switchOutTarget.hp) {
|
||||
user.scene.pushPhase(new BattleEndPhase(user.scene));
|
||||
user.scene.pushPhase(new BattleEndPhase(user.scene, false));
|
||||
user.scene.pushPhase(new NewBattlePhase(user.scene));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -731,7 +731,7 @@ export function handleMysteryEncounterVictory(scene: BattleScene, addHealPhase:
|
|||
scene.pushPhase(new MysteryEncounterRewardsPhase(scene, addHealPhase));
|
||||
scene.pushPhase(new EggLapsePhase(scene));
|
||||
} else if (!scene.getEnemyParty().find(p => encounter.encounterMode !== MysteryEncounterMode.TRAINER_BATTLE ? p.isOnField() : !p?.isFainted(true))) {
|
||||
scene.pushPhase(new BattleEndPhase(scene));
|
||||
scene.pushPhase(new BattleEndPhase(scene, true));
|
||||
if (encounter.encounterMode === MysteryEncounterMode.TRAINER_BATTLE) {
|
||||
scene.pushPhase(new TrainerVictoryPhase(scene));
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ export class AttemptRunPhase extends PokemonPhase {
|
|||
enemyPokemon.trySetStatus(StatusEffect.FAINT);
|
||||
});
|
||||
|
||||
this.scene.pushPhase(new BattleEndPhase(this.scene));
|
||||
this.scene.pushPhase(new BattleEndPhase(this.scene, false));
|
||||
this.scene.pushPhase(new NewBattlePhase(this.scene));
|
||||
} else {
|
||||
playerPokemon.turnData.failedRunAway = true;
|
||||
|
|
|
@ -8,7 +8,7 @@ export class BattleEndPhase extends BattlePhase {
|
|||
/** If true, will increment battles won */
|
||||
isVictory: boolean;
|
||||
|
||||
constructor(scene: BattleScene, isVictory: boolean = true) {
|
||||
constructor(scene: BattleScene, isVictory: boolean) {
|
||||
super(scene);
|
||||
|
||||
this.isVictory = isVictory;
|
||||
|
@ -17,16 +17,17 @@ export class BattleEndPhase extends BattlePhase {
|
|||
start() {
|
||||
super.start();
|
||||
|
||||
this.scene.gameData.gameStats.battles++;
|
||||
if (this.scene.gameMode.isEndless && this.scene.currentBattle.waveIndex + 1 > this.scene.gameData.gameStats.highestEndlessWave) {
|
||||
this.scene.gameData.gameStats.highestEndlessWave = this.scene.currentBattle.waveIndex + 1;
|
||||
}
|
||||
|
||||
if (this.isVictory) {
|
||||
this.scene.currentBattle.addBattleScore(this.scene);
|
||||
|
||||
this.scene.gameData.gameStats.battles++;
|
||||
if (this.scene.currentBattle.trainer) {
|
||||
this.scene.gameData.gameStats.trainersDefeated++;
|
||||
}
|
||||
if (this.scene.gameMode.isEndless && this.scene.currentBattle.waveIndex + 1 > this.scene.gameData.gameStats.highestEndlessWave) {
|
||||
this.scene.gameData.gameStats.highestEndlessWave = this.scene.currentBattle.waveIndex + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Endless graceful end
|
||||
|
@ -42,7 +43,7 @@ export class BattleEndPhase extends BattlePhase {
|
|||
}
|
||||
|
||||
for (const pokemon of this.scene.getPokemonAllowedInBattle()) {
|
||||
applyPostBattleAbAttrs(PostBattleAbAttr, pokemon);
|
||||
applyPostBattleAbAttrs(PostBattleAbAttr, pokemon, false, this.isVictory);
|
||||
}
|
||||
|
||||
if (this.scene.currentBattle.moneyScattered) {
|
||||
|
|
|
@ -41,7 +41,7 @@ export class VictoryPhase extends PokemonPhase {
|
|||
}
|
||||
|
||||
if (!this.scene.getEnemyParty().find(p => this.scene.currentBattle.battleType === BattleType.WILD ? p.isOnField() : !p?.isFainted(true))) {
|
||||
this.scene.pushPhase(new BattleEndPhase(this.scene));
|
||||
this.scene.pushPhase(new BattleEndPhase(this.scene, true));
|
||||
if (this.scene.currentBattle.battleType === BattleType.TRAINER) {
|
||||
this.scene.pushPhase(new TrainerVictoryPhase(this.scene));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
import type { CommandPhase } from "#app/phases/command-phase";
|
||||
import { Command } from "#app/ui/command-ui-handler";
|
||||
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, expect, it, vi } from "vitest";
|
||||
|
||||
describe("Abilities - Honey Gather", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
|
||||
beforeAll(() => {
|
||||
phaserGame = new Phaser.Game({
|
||||
type: Phaser.HEADLESS,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
game.override
|
||||
.moveset([ Moves.SPLASH, Moves.ROAR, Moves.THUNDERBOLT ])
|
||||
.startingLevel(100)
|
||||
.ability(Abilities.HONEY_GATHER)
|
||||
.passiveAbility(Abilities.RUN_AWAY)
|
||||
.battleType("single")
|
||||
.disableCrits()
|
||||
.enemySpecies(Species.MAGIKARP)
|
||||
.enemyAbility(Abilities.BALL_FETCH)
|
||||
.enemyMoveset(Moves.SPLASH);
|
||||
});
|
||||
|
||||
it("should give money when winning a battle", async () => {
|
||||
await game.classicMode.startBattle([ Species.MILOTIC ]);
|
||||
game.scene.money = 1000;
|
||||
|
||||
game.move.select(Moves.THUNDERBOLT);
|
||||
await game.toNextWave();
|
||||
|
||||
expect(game.scene.money).toBeGreaterThan(1000);
|
||||
});
|
||||
|
||||
it("should not give money when the enemy pokemon flees", async () => {
|
||||
await game.classicMode.startBattle([ Species.MILOTIC ]);
|
||||
game.scene.money = 1000;
|
||||
|
||||
game.move.select(Moves.ROAR);
|
||||
await game.toNextTurn();
|
||||
|
||||
expect(game.scene.money).toBe(1000);
|
||||
expect(game.scene.currentBattle.waveIndex).toBe(2);
|
||||
});
|
||||
|
||||
it("should not give money when the player flees", async () => {
|
||||
await game.classicMode.startBattle([ Species.MILOTIC ]);
|
||||
game.scene.money = 1000;
|
||||
|
||||
// something weird is going on with the test framework, so this is required to prevent a crash
|
||||
const enemy = game.scene.getEnemyPokemon()!;
|
||||
vi.spyOn(enemy, "scene", "get").mockReturnValue(game.scene);
|
||||
|
||||
const commandPhase = game.scene.getCurrentPhase() as CommandPhase;
|
||||
commandPhase.handleCommand(Command.RUN, 0);
|
||||
await game.toNextTurn();
|
||||
|
||||
expect(game.scene.money).toBe(1000);
|
||||
expect(game.scene.currentBattle.waveIndex).toBe(2);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue