add` CanLearnMoveRequirement`

This commit is contained in:
Felix Staud 2024-07-12 13:23:48 -07:00
parent 72c76c4d39
commit 7164b0afe4
2 changed files with 115 additions and 2 deletions

View File

@ -31,8 +31,8 @@ export abstract class EncounterSceneRequirement implements EncounterRequirement
} }
export abstract class EncounterPokemonRequirement implements EncounterRequirement { export abstract class EncounterPokemonRequirement implements EncounterRequirement {
protected minNumberOfPokemon: number; public minNumberOfPokemon: number;
protected invertQuery: boolean; public invertQuery: boolean;
abstract meetsRequirement(scene: BattleScene): boolean; abstract meetsRequirement(scene: BattleScene): boolean;

View File

@ -0,0 +1,113 @@
import BattleScene from "#app/battle-scene.js";
import { Moves } from "#app/enums/moves.js";
import { PlayerPokemon } from "#app/field/pokemon.js";
import { isNullOrUndefined } from "#app/utils.js";
import { EncounterPokemonRequirement } from "../mystery-encounter-requirements";
/**
* {@linkcode CanLearnMoveRequirement} options
*/
interface Options {
excludeLevelMoves?: boolean;
excludeTmMoves?: boolean;
excludeEggMoves?: boolean;
includeFainted?: boolean;
minNumberOfPokemon?: number;
invertQuery?: boolean;
}
/**
* Requires that a pokemon can learn a specific move/moveset.
*/
export class CanLearnMoveRequirement extends EncounterPokemonRequirement {
private readonly requiredMoves: Moves[];
private readonly excludeLevelMoves?: boolean;
private readonly excludeTmMoves?: boolean;
private readonly excludeEggMoves?: boolean;
private readonly includeFainted?: boolean;
constructor(requiredMoves: Moves | Moves[], options: Options = {}) {
super();
this.requiredMoves = Array.isArray(requiredMoves)
? requiredMoves
: [requiredMoves];
const {
excludeLevelMoves,
excludeTmMoves,
excludeEggMoves,
includeFainted,
minNumberOfPokemon,
invertQuery,
} = options;
this.excludeLevelMoves = excludeLevelMoves ?? false;
this.excludeTmMoves = excludeTmMoves ?? false;
this.excludeEggMoves = excludeEggMoves ?? false;
this.includeFainted = includeFainted ?? false;
this.minNumberOfPokemon = minNumberOfPokemon ?? 1;
this.invertQuery = invertQuery;
}
override meetsRequirement(scene: BattleScene): boolean {
const partyPokemon = scene
.getParty()
.filter((pkm) =>
this.includeFainted ? pkm.isAllowed() : pkm.isAllowedInBattle()
);
if (isNullOrUndefined(partyPokemon) || this?.requiredMoves?.length < 0) {
return false;
}
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
}
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
if (!this.invertQuery) {
return partyPokemon.filter((pokemon) =>
// every required move should be included
this.requiredMoves.every((requiredMove) =>
this.getAllPokemonMoves(pokemon).includes(requiredMove)
)
);
} else {
return partyPokemon.filter(
(pokemon) =>
// none of the "required" moves should be included
!this.requiredMoves.some((requiredMove) =>
this.getAllPokemonMoves(pokemon).includes(requiredMove)
)
);
}
}
override getDialogueToken(
_scene: BattleScene,
_pokemon?: PlayerPokemon
): [string, string] {
return ["requiredMoves", this.requiredMoves.join(", ")];
}
private getPokemonLevelMoves(pkm: PlayerPokemon): Moves[] {
return pkm.getLevelMoves().map(([_level, move]) => move);
}
private getAllPokemonMoves(pkm: PlayerPokemon): Moves[] {
const allPokemonMoves: Moves[] = [];
if (!this.excludeLevelMoves) {
allPokemonMoves.push(...this.getPokemonLevelMoves(pkm));
}
if (this.excludeTmMoves) {
allPokemonMoves.push(...pkm.compatibleTms);
}
if (this.excludeEggMoves) {
allPokemonMoves.push(...pkm.getEggMoves());
}
return allPokemonMoves;
}
}