mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-09-23 15:03:24 +02:00
Refactors and doc comment updates; moved types to new file
This commit is contained in:
parent
75d811c904
commit
f8f4552d7e
29
src/@types/new-battle-props.ts
Normal file
29
src/@types/new-battle-props.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// biome-ignore lint/correctness/noUnusedImports: TSDoc
|
||||||
|
import type { BattleScene } from "#app/battle-scene";
|
||||||
|
import type { BattleType } from "#enums/battle-type";
|
||||||
|
import type { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
|
import type { Trainer } from "#field/trainer";
|
||||||
|
import type { TrainerData } from "#system/trainer-data";
|
||||||
|
|
||||||
|
/** Interface representing the base type of a new battle config, used for DRY. */
|
||||||
|
interface NewBattleBaseProps {
|
||||||
|
battleType: BattleType;
|
||||||
|
trainer?: Trainer;
|
||||||
|
trainerData?: TrainerData;
|
||||||
|
mysteryEncounterType?: MysteryEncounterType;
|
||||||
|
waveIndex: number;
|
||||||
|
double?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface representing the resolved type of a new battle config, used after creating a new Battle.
|
||||||
|
* @interface
|
||||||
|
*/
|
||||||
|
export type NewBattleResolvedProps = Omit<NewBattleBaseProps, "trainerConfig" | "trainerData" | "mysteryEncounterType">;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface representing the return type of {@linkcode BattleScene.getNewBattleProps}, used
|
||||||
|
* while creating a new battle.
|
||||||
|
* @interface
|
||||||
|
*/
|
||||||
|
export type NewBattleProps = Omit<NewBattleBaseProps, "trainer">;
|
@ -114,12 +114,12 @@ import { GameData } from "#system/game-data";
|
|||||||
import { initGameSpeed } from "#system/game-speed";
|
import { initGameSpeed } from "#system/game-speed";
|
||||||
import type { PokemonData } from "#system/pokemon-data";
|
import type { PokemonData } from "#system/pokemon-data";
|
||||||
import { MusicPreference } from "#system/settings";
|
import { MusicPreference } from "#system/settings";
|
||||||
import type { TrainerData } from "#system/trainer-data";
|
|
||||||
import type { Voucher } from "#system/voucher";
|
import type { Voucher } from "#system/voucher";
|
||||||
import { vouchers } from "#system/voucher";
|
import { vouchers } from "#system/voucher";
|
||||||
import { trainerConfigs } from "#trainers/trainer-config";
|
import { trainerConfigs } from "#trainers/trainer-config";
|
||||||
import type { HeldModifierConfig } from "#types/held-modifier-config";
|
import type { HeldModifierConfig } from "#types/held-modifier-config";
|
||||||
import type { Localizable } from "#types/locales";
|
import type { Localizable } from "#types/locales";
|
||||||
|
import type { NewBattleProps, NewBattleResolvedProps } from "#types/new-battle-props";
|
||||||
import type { SessionSaveData } from "#types/save-data";
|
import type { SessionSaveData } from "#types/save-data";
|
||||||
import { AbilityBar } from "#ui/ability-bar";
|
import { AbilityBar } from "#ui/ability-bar";
|
||||||
import { ArenaFlyout } from "#ui/arena-flyout";
|
import { ArenaFlyout } from "#ui/arena-flyout";
|
||||||
@ -165,29 +165,6 @@ export interface InfoToggle {
|
|||||||
isActive(): boolean;
|
isActive(): boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo move this to the file
|
|
||||||
/** Interface representing the base type of a new battle config. */
|
|
||||||
interface NewBattleBaseProps {
|
|
||||||
battleType: BattleType;
|
|
||||||
trainer?: Trainer;
|
|
||||||
trainerData?: TrainerData;
|
|
||||||
mysteryEncounterType?: MysteryEncounterType;
|
|
||||||
waveIndex: number;
|
|
||||||
double?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface representing the resolved type of a new battle config.
|
|
||||||
* @interface
|
|
||||||
*/
|
|
||||||
export type NewBattleResolvedProps = Omit<NewBattleBaseProps, "trainerConfig" | "trainerData" | "mysteryEncounterType">;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface representing the type of {@linkcode BattleScene.getNewBattleProps}, used for DRY
|
|
||||||
* @interface
|
|
||||||
*/
|
|
||||||
export type NewBattleProps = Omit<NewBattleBaseProps, "trainer">;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `BattleScene` is the primary scene for the game.
|
* The `BattleScene` is the primary scene for the game.
|
||||||
* Despite its name, it handles _everything_ other than initial asset loading,
|
* Despite its name, it handles _everything_ other than initial asset loading,
|
||||||
@ -1315,27 +1292,28 @@ export class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Create and initialize a new battle.
|
||||||
* @param fromSession - The {@linkcode SessionSaveData} being used to seed the battle.
|
* @param fromSession - The {@linkcode SessionSaveData} being used to seed the battle.
|
||||||
* Should be omitted if not loading a new save file.
|
* Should be omitted if not loading a new save file.
|
||||||
* @returns The newly created Battle instance
|
* @returns The newly created `Battle` instance.
|
||||||
*/
|
*/
|
||||||
newBattle(fromSession?: SessionSaveData): Battle {
|
public newBattle(fromSession?: SessionSaveData): Battle {
|
||||||
const props = this.getNewBattleProps(fromSession);
|
const props = this.getNewBattleProps(fromSession);
|
||||||
const foo: Partial<NewBattleResolvedProps> = {};
|
const resolved: Partial<NewBattleResolvedProps> = {};
|
||||||
const { waveIndex } = props;
|
const { waveIndex } = props;
|
||||||
|
|
||||||
this.resetSeed(waveIndex);
|
this.resetSeed(waveIndex);
|
||||||
|
|
||||||
// First, check if it's a fixed wave and do stuff accordingly
|
// First, check if it's a fixed wave and do stuff accordingly
|
||||||
if (this.gameMode.isFixedBattle(waveIndex)) {
|
if (this.gameMode.isFixedBattle(waveIndex)) {
|
||||||
this.handleFixedBattle(foo, waveIndex);
|
this.handleFixedBattle(resolved, waveIndex);
|
||||||
} else if (props.trainerData) {
|
} else if (props.trainerData) {
|
||||||
this.handleSavedBattle(foo, props);
|
this.handleSavedBattle(resolved, props);
|
||||||
} else {
|
} else {
|
||||||
this.handleNonFixedBattle(foo, props);
|
this.handleNonFixedBattle(resolved, props);
|
||||||
}
|
}
|
||||||
|
|
||||||
foo.double = this.checkIsDouble(foo, props);
|
resolved.double = this.checkIsDouble(resolved.trainer, props);
|
||||||
|
|
||||||
const lastBattle = this.currentBattle;
|
const lastBattle = this.currentBattle;
|
||||||
const maxExpLevel = this.getMaxExpLevel();
|
const maxExpLevel = this.getMaxExpLevel();
|
||||||
@ -1344,7 +1322,7 @@ export class BattleScene extends SceneBase {
|
|||||||
this.lastMysteryEncounter = lastBattle?.mysteryEncounter;
|
this.lastMysteryEncounter = lastBattle?.mysteryEncounter;
|
||||||
|
|
||||||
// TODO: Is this even needed?
|
// TODO: Is this even needed?
|
||||||
if (lastBattle?.double && !foo.double) {
|
if (lastBattle?.double && !resolved.double) {
|
||||||
this.phaseManager.tryRemovePhase((p: Phase) => p.is("SwitchPhase"));
|
this.phaseManager.tryRemovePhase((p: Phase) => p.is("SwitchPhase"));
|
||||||
// TODO: We already do this later in the function
|
// TODO: We already do this later in the function
|
||||||
for (const p of this.getPlayerField()) {
|
for (const p of this.getPlayerField()) {
|
||||||
@ -1355,7 +1333,7 @@ export class BattleScene extends SceneBase {
|
|||||||
// NB: Type assertion is fine as foo should always be defined
|
// NB: Type assertion is fine as foo should always be defined
|
||||||
this.executeWithSeedOffset(
|
this.executeWithSeedOffset(
|
||||||
() => {
|
() => {
|
||||||
this.currentBattle = new Battle(this.gameMode, foo as NewBattleResolvedProps);
|
this.currentBattle = new Battle(this.gameMode, resolved as NewBattleResolvedProps);
|
||||||
},
|
},
|
||||||
waveIndex << 3, // TODO: Why use this specific index?
|
waveIndex << 3, // TODO: Why use this specific index?
|
||||||
this.waveSeed,
|
this.waveSeed,
|
||||||
@ -1370,12 +1348,16 @@ export class BattleScene extends SceneBase {
|
|||||||
return this.currentBattle;
|
return this.currentBattle;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Document these and stop
|
/**
|
||||||
private handleFixedBattle(foo: Partial<NewBattleResolvedProps>, waveIndex: number): Trainer {
|
* Sub-method of `launchBattle` that handles a
|
||||||
let t: Trainer;
|
*/
|
||||||
|
private handleFixedBattle(resolved: Partial<NewBattleResolvedProps>, waveIndex: number): Trainer {
|
||||||
|
// Bang is justified as this code is only called when `isFixedBattle` is true
|
||||||
const battleConfig = this.gameMode.getFixedBattle(waveIndex)!;
|
const battleConfig = this.gameMode.getFixedBattle(waveIndex)!;
|
||||||
foo.double = battleConfig.double;
|
resolved.double = battleConfig.double;
|
||||||
foo.battleType = battleConfig.battleType;
|
resolved.battleType = battleConfig.battleType;
|
||||||
|
|
||||||
|
let t: Trainer;
|
||||||
this.executeWithSeedOffset(
|
this.executeWithSeedOffset(
|
||||||
() => {
|
() => {
|
||||||
t = battleConfig.getTrainer();
|
t = battleConfig.getTrainer();
|
||||||
@ -1416,21 +1398,19 @@ export class BattleScene extends SceneBase {
|
|||||||
|
|
||||||
// Determine the trainer's attributes
|
// Determine the trainer's attributes
|
||||||
const trainerType = Overrides.RANDOM_TRAINER_OVERRIDE?.trainerType ?? this.arena.randomTrainerType(waveIndex);
|
const trainerType = Overrides.RANDOM_TRAINER_OVERRIDE?.trainerType ?? this.arena.randomTrainerType(waveIndex);
|
||||||
|
const config = trainerConfigs[trainerType];
|
||||||
let doubleTrainer: boolean;
|
let doubleTrainer: boolean;
|
||||||
if (trainerConfigs[trainerType].doubleOnly) {
|
if (config.doubleOnly) {
|
||||||
doubleTrainer = true;
|
doubleTrainer = true;
|
||||||
} else if (!trainerConfigs[trainerType].hasDouble) {
|
} else if (
|
||||||
|
!config.hasDouble // Add a check that special trainers can't be double except for tate and liza - they should use the normal double chance
|
||||||
|
|| // TODO: Review this
|
||||||
|
(config.trainerTypeDouble && ![TrainerType.TATE, TrainerType.LIZA].includes(trainerType))
|
||||||
|
) {
|
||||||
doubleTrainer = false;
|
doubleTrainer = false;
|
||||||
} else {
|
} else {
|
||||||
doubleTrainer =
|
doubleTrainer =
|
||||||
Overrides.RANDOM_TRAINER_OVERRIDE?.alwaysDouble || !randSeedInt(this.getDoubleBattleChance(waveIndex));
|
Overrides.RANDOM_TRAINER_OVERRIDE?.alwaysDouble || !randSeedInt(this.getDoubleBattleChance(waveIndex));
|
||||||
// Add a check that special trainers can't be double except for tate and liza - they should use the normal double chance
|
|
||||||
if (
|
|
||||||
trainerConfigs[trainerType].trainerTypeDouble
|
|
||||||
&& ![TrainerType.TATE, TrainerType.LIZA].includes(trainerType)
|
|
||||||
) {
|
|
||||||
doubleTrainer = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const variant = doubleTrainer
|
const variant = doubleTrainer
|
||||||
@ -1438,11 +1418,17 @@ export class BattleScene extends SceneBase {
|
|||||||
: randSeedInt(2)
|
: randSeedInt(2)
|
||||||
? TrainerVariant.FEMALE
|
? TrainerVariant.FEMALE
|
||||||
: TrainerVariant.DEFAULT;
|
: TrainerVariant.DEFAULT;
|
||||||
|
|
||||||
const trainer = new Trainer(trainerType, variant);
|
const trainer = new Trainer(trainerType, variant);
|
||||||
this.field.add(trainer);
|
this.field.add(trainer);
|
||||||
foo.trainer = trainer;
|
foo.trainer = trainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to {@linkcode newBattle} to initialize a {@linkcode NewBattleProps} from session data, using defaults if no session data is provided.
|
||||||
|
* @param fromSession - The session data being used to initialize the battle, or `undefined` if a new battle is being created mid run
|
||||||
|
* @returns The new battle props
|
||||||
|
*/
|
||||||
private getNewBattleProps(fromSession?: SessionSaveData): NewBattleProps {
|
private getNewBattleProps(fromSession?: SessionSaveData): NewBattleProps {
|
||||||
const battleType = fromSession?.battleType ?? BattleType.WILD;
|
const battleType = fromSession?.battleType ?? BattleType.WILD;
|
||||||
const mysteryEncounterType =
|
const mysteryEncounterType =
|
||||||
@ -1459,8 +1445,8 @@ export class BattleScene extends SceneBase {
|
|||||||
fromSession == null
|
fromSession == null
|
||||||
? undefined
|
? undefined
|
||||||
: battleType === BattleType.TRAINER
|
: battleType === BattleType.TRAINER
|
||||||
? trainerConfigs[fromSession?.trainer.trainerType]?.doubleOnly
|
? trainerConfigs[fromSession.trainer.trainerType]?.doubleOnly
|
||||||
|| fromSession.trainer?.variant === TrainerVariant.DOUBLE
|
|| fromSession.trainer.variant === TrainerVariant.DOUBLE
|
||||||
: battleType !== BattleType.MYSTERY_ENCOUNTER && fromSession.enemyParty.length > 1;
|
: battleType !== BattleType.MYSTERY_ENCOUNTER && fromSession.enemyParty.length > 1;
|
||||||
|
|
||||||
return { battleType, mysteryEncounterType, waveIndex: newWaveIndex, trainerData, double: fixedDouble };
|
return { battleType, mysteryEncounterType, waveIndex: newWaveIndex, trainerData, double: fixedDouble };
|
||||||
@ -1522,17 +1508,18 @@ export class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sub-method of `newBattle` that returns whether the new battle is a double battle. */
|
/**
|
||||||
private checkIsDouble(
|
* Sub-method of `newBattle` that returns whether the new battle is a double battle.
|
||||||
{ trainer }: Partial<NewBattleResolvedProps>,
|
* @param __namedParameters
|
||||||
{ double, battleType, waveIndex }: NewBattleProps,
|
*/
|
||||||
): boolean {
|
private checkIsDouble(trainer: Trainer | undefined, { double, battleType, waveIndex }: NewBattleProps): boolean {
|
||||||
// Edge cases
|
// Edge cases
|
||||||
if (
|
if (
|
||||||
waveIndex === 1 // Wave 1 doubles cause crashes
|
// Wave 1 doubles cause crashes
|
||||||
|
waveIndex === 1
|
||||||
|| this.gameMode.isWaveFinal(waveIndex)
|
|| this.gameMode.isWaveFinal(waveIndex)
|
||||||
|| this.gameMode.isEndlessBoss(waveIndex)
|
|| this.gameMode.isEndlessBoss(waveIndex)
|
||||||
|| battleType === BattleType.MYSTERY_ENCOUNTER
|
|| battleType === BattleType.MYSTERY_ENCOUNTER // MEs are never double battles
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1877,6 +1864,7 @@ export class BattleScene extends SceneBase {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Refactor this and other RNG functions - these dearly need help
|
||||||
resetSeed(waveIndex?: number): void {
|
resetSeed(waveIndex?: number): void {
|
||||||
const wave = waveIndex ?? this.currentBattle?.waveIndex ?? 0;
|
const wave = waveIndex ?? this.currentBattle?.waveIndex ?? 0;
|
||||||
this.waveSeed = shiftCharCodes(this.seed, wave);
|
this.waveSeed = shiftCharCodes(this.seed, wave);
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import type { NewBattleResolvedProps } from "#app/battle-scene";
|
|
||||||
import type { GameMode } from "#app/game-mode";
|
import type { GameMode } from "#app/game-mode";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { ArenaTagType } from "#enums/arena-tag-type";
|
import { ArenaTagType } from "#enums/arena-tag-type";
|
||||||
@ -22,6 +21,7 @@ import type { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
|
|||||||
import i18next from "#plugins/i18n";
|
import i18next from "#plugins/i18n";
|
||||||
import { MusicPreference } from "#system/settings";
|
import { MusicPreference } from "#system/settings";
|
||||||
import { trainerConfigs } from "#trainers/trainer-config";
|
import { trainerConfigs } from "#trainers/trainer-config";
|
||||||
|
import type { NewBattleResolvedProps } from "#types/new-battle-props";
|
||||||
import type { TurnMove } from "#types/turn-move";
|
import type { TurnMove } from "#types/turn-move";
|
||||||
import {
|
import {
|
||||||
NumberHolder,
|
NumberHolder,
|
||||||
|
@ -10,11 +10,11 @@ export class TrainerPartyTemplate {
|
|||||||
public sameSpecies: boolean;
|
public sameSpecies: boolean;
|
||||||
public balanced: boolean;
|
public balanced: boolean;
|
||||||
|
|
||||||
constructor(size: number, strength: PartyMemberStrength, sameSpecies?: boolean, balanced?: boolean) {
|
constructor(size: number, strength: PartyMemberStrength, sameSpecies = false, balanced = false) {
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.strength = strength;
|
this.strength = strength;
|
||||||
this.sameSpecies = !!sameSpecies;
|
this.sameSpecies = sameSpecies;
|
||||||
this.balanced = !!balanced;
|
this.balanced = balanced;
|
||||||
}
|
}
|
||||||
|
|
||||||
getStrength(_index: number): PartyMemberStrength {
|
getStrength(_index: number): PartyMemberStrength {
|
||||||
|
@ -287,20 +287,21 @@ export class GameMode implements GameModeConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every 50 waves of an Endless mode is a boss
|
* Check whether the current wave is an Endless boss of any kind.
|
||||||
* At this time it is paradox pokemon
|
* @param waveIndex - The current wave number.
|
||||||
* @returns true if waveIndex is a multiple of 50 in Endless
|
* @returns Whether `waveIndex` corresponds to an Endless boss.
|
||||||
*/
|
*/
|
||||||
isEndlessBoss(waveIndex: number): boolean {
|
isEndlessBoss(waveIndex: number): boolean {
|
||||||
return waveIndex % 50 === 0 && (this.modeId === GameModes.ENDLESS || this.modeId === GameModes.SPLICED_ENDLESS);
|
return waveIndex % 50 === 0 && (this.modeId === GameModes.ENDLESS || this.modeId === GameModes.SPLICED_ENDLESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every 250 waves of an Endless mode is a minor boss
|
* Check whether the current wave is an Endless minor boss.
|
||||||
* At this time it is Eternatus
|
* Currently is normal Eternatus.
|
||||||
* @returns true if waveIndex is a multiple of 250 in Endless
|
* @param waveIndex - The current wave number.
|
||||||
|
* @returns Whether `waveIndex` is a multiple of 250 during endless mode.
|
||||||
*/
|
*/
|
||||||
isEndlessMinorBoss(waveIndex: number): boolean {
|
public isEndlessMinorBoss(waveIndex: number): boolean {
|
||||||
return waveIndex % 250 === 0 && (this.modeId === GameModes.ENDLESS || this.modeId === GameModes.SPLICED_ENDLESS);
|
return waveIndex % 250 === 0 && (this.modeId === GameModes.ENDLESS || this.modeId === GameModes.SPLICED_ENDLESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user