Skip to content

Commit

Permalink
[Bug] Honey Gather and Pickup will only activate if the battle was won (
Browse files Browse the repository at this point in the history
#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
  • Loading branch information
DayKev authored Nov 29, 2024
1 parent 4d341bf commit 9bc046f
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 18 deletions.
20 changes: 12 additions & 8 deletions src/data/ability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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!?
Expand Down Expand Up @@ -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 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;

Expand Down Expand Up @@ -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));
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/data/move.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/data/mystery-encounters/utils/encounter-phase-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down
2 changes: 1 addition & 1 deletion src/phases/attempt-run-phase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
13 changes: 7 additions & 6 deletions src/phases/battle-end-phase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion src/phases/victory-phase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down
74 changes: 74 additions & 0 deletions src/test/abilities/honey_gather.test.ts
Original file line number Diff line number Diff line change
@@ -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);
});
});

0 comments on commit 9bc046f

Please sign in to comment.