Minor Attempt run phase rework to abstract logic to whole team

This commit is contained in:
jnotsknab 2025-06-19 05:52:29 -05:00
parent 6873a89296
commit 53c5efc82e
4 changed files with 32 additions and 8 deletions

View File

@ -808,6 +808,15 @@ export default class BattleScene extends SceneBase {
return party.slice(0, Math.min(party.length, this.currentBattle?.double ? 2 : 1));
}
/**
* Returns an array of PlayerPokemon of length 1 or 2 depending on if in a double battle or not.
* Does check if the pokemon are on the field or not.
* @returns array of {@linkcode PlayerPokemon}
*/
public getActivePlayerField(): PlayerPokemon[] {
return this.getPlayerField().filter(p => p.isActive());
}
public getEnemyParty(): EnemyPokemon[] {
return this.currentBattle?.enemyParty ?? [];
}

View File

@ -4,7 +4,7 @@ import { StatusEffect } from "#enums/status-effect";
import type { PlayerPokemon, EnemyPokemon } from "#app/field/pokemon";
import type Pokemon from "#app/field/pokemon";
import i18next from "i18next";
import { NumberHolder } from "#app/utils/common";
import { NumberHolder, randSeedInt } from "#app/utils/common";
import { PokemonPhase } from "./pokemon-phase";
import { globalScene } from "#app/global-scene";
@ -13,21 +13,28 @@ export class AttemptRunPhase extends PokemonPhase {
/** For testing purposes: this is to force the pokemon to fail and escape */
public forceFailEscape = false;
private getTeamRNG(range: number, min = 0) {
return globalScene.currentBattle ? globalScene.randBattleSeedInt(range, min) : randSeedInt(range, min);
}
start() {
super.start();
const playerField = globalScene.getPlayerField();
const activePlayerField = globalScene.getActivePlayerField();
const enemyField = globalScene.getEnemyField();
const playerPokemon = this.getPokemon();
//Attempting to run is a TEAM not PLAYER based action, we should not be referercing individual pokemon,
//we should instead be referring to the team as a whole and
const escapeChance = new NumberHolder(0);
const escapeRoll = this.getTeamRNG(100);
this.attemptRunAway(playerField, enemyField, escapeChance);
this.attemptRunAway(activePlayerField, enemyField, escapeChance);
applyAbAttrs("RunSuccessAbAttr", playerPokemon, null, false, escapeChance);
activePlayerField.forEach(p => {
applyAbAttrs("RunSuccessAbAttr", p, null, false, escapeChance);
});
if (playerPokemon.randBattleSeedInt(100) < escapeChance.value && !this.forceFailEscape) {
if (escapeRoll < escapeChance.value && !this.forceFailEscape) {
enemyField.forEach(enemyPokemon => applyPreLeaveFieldAbAttrs("PreLeaveFieldAbAttr", enemyPokemon));
globalScene.playSound("se/flee");
@ -60,7 +67,11 @@ export class AttemptRunPhase extends PokemonPhase {
globalScene.phaseManager.pushNew("NewBattlePhase");
} else {
playerPokemon.turnData.failedRunAway = true;
//there should be a general failed run away bool for the active team
activePlayerField.forEach(p => {
p.turnData.failedRunAway = true;
});
globalScene.phaseManager.queueMessage(i18next.t("battle:runAwayCannotEscape"), null, true, 500);
}

View File

@ -8,6 +8,7 @@ import { SpeciesId } from "#enums/species-id";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, it, expect, vi } from "vitest";
import { globalScene } from "#app/global-scene";
describe("Abilities - Desolate Land", () => {
let phaserGame: Phaser.Game;
@ -145,6 +146,7 @@ describe("Abilities - Desolate Land", () => {
expect(game.scene.arena.weather?.weatherType).toBe(WeatherType.HARSH_SUN);
vi.spyOn(game.scene.getPlayerPokemon()!, "randBattleSeedInt").mockReturnValue(0);
vi.spyOn(globalScene, "randBattleSeedInt").mockReturnValue(0);
const commandPhase = game.scene.phaseManager.getCurrentPhase() as CommandPhase;
commandPhase.handleCommand(Command.RUN, 0);

View File

@ -10,6 +10,7 @@ import { Stat } from "#enums/stat";
import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { globalScene } from "#app/global-scene";
describe("Abilities - Neutralizing Gas", () => {
let phaserGame: Phaser.Game;
@ -164,6 +165,7 @@ describe("Abilities - Neutralizing Gas", () => {
expect(game.scene.arena.getTag(ArenaTagType.NEUTRALIZING_GAS)).toBeDefined();
vi.spyOn(game.scene.getPlayerPokemon()!, "randBattleSeedInt").mockReturnValue(0);
vi.spyOn(globalScene, "randBattleSeedInt").mockReturnValue(0);
const commandPhase = game.scene.phaseManager.getCurrentPhase() as CommandPhase;
commandPhase.handleCommand(Command.RUN, 0);