mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-21 06:49:35 +02:00
[ME] update CombinationRequirements to allow AND or OR combinations
* refactor: CombinationPokemonRequirement `.Some()` and `Every()` * chore: rename `orRequirements` to `requirements` * fix: returns of `Some()` and `Any()` * apply `Some()` / `Any()` pattern to `CombinationSceneRequirement` too
This commit is contained in:
parent
96d8a2127a
commit
a3fb7bc829
@ -135,9 +135,11 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter =
|
||||
.withOption(
|
||||
MysteryEncounterOptionBuilder
|
||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
|
||||
.withPrimaryPokemonRequirement(new CombinationPokemonRequirement(
|
||||
new MoveRequirement(EXTORTION_MOVES, true),
|
||||
new AbilityRequirement(EXTORTION_ABILITIES, true))
|
||||
.withPrimaryPokemonRequirement(
|
||||
CombinationPokemonRequirement.Some(
|
||||
new MoveRequirement(EXTORTION_MOVES, true),
|
||||
new AbilityRequirement(EXTORTION_ABILITIES, true)
|
||||
)
|
||||
)
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
|
@ -193,12 +193,14 @@ const WAVE_LEVEL_BREAKPOINTS = [ 30, 50, 70, 100, 120, 140, 160 ];
|
||||
export const BugTypeSuperfanEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.BUG_TYPE_SUPERFAN)
|
||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||
.withPrimaryPokemonRequirement(new CombinationPokemonRequirement(
|
||||
// Must have at least 1 Bug type on team, OR have a bug item somewhere on the team
|
||||
new HeldItemRequirement([ "BypassSpeedChanceModifier", "ContactHeldItemTransferChanceModifier" ], 1),
|
||||
new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1),
|
||||
new TypeRequirement(Type.BUG, false, 1)
|
||||
))
|
||||
.withPrimaryPokemonRequirement(
|
||||
CombinationPokemonRequirement.Some(
|
||||
// Must have at least 1 Bug type on team, OR have a bug item somewhere on the team
|
||||
new HeldItemRequirement([ "BypassSpeedChanceModifier", "ContactHeldItemTransferChanceModifier" ], 1),
|
||||
new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1),
|
||||
new TypeRequirement(Type.BUG, false, 1)
|
||||
)
|
||||
)
|
||||
.withMaxAllowedEncounters(1)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withIntroSpriteConfigs([]) // These are set in onInit()
|
||||
@ -405,11 +407,13 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
||||
.build())
|
||||
.withOption(MysteryEncounterOptionBuilder
|
||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||
.withPrimaryPokemonRequirement(new CombinationPokemonRequirement(
|
||||
// Meets one or both of the below reqs
|
||||
new HeldItemRequirement([ "BypassSpeedChanceModifier", "ContactHeldItemTransferChanceModifier" ], 1),
|
||||
new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1)
|
||||
))
|
||||
.withPrimaryPokemonRequirement(
|
||||
CombinationPokemonRequirement.Some(
|
||||
// Meets one or both of the below reqs
|
||||
new HeldItemRequirement([ "BypassSpeedChanceModifier", "ContactHeldItemTransferChanceModifier" ], 1),
|
||||
new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1)
|
||||
)
|
||||
)
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.3.label`,
|
||||
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||
|
@ -45,10 +45,13 @@ export const DelibirdyEncounter: MysteryEncounter =
|
||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withSceneRequirement(new MoneyRequirement(0, DELIBIRDY_MONEY_PRICE_MULTIPLIER)) // Must have enough money for it to spawn at the very least
|
||||
.withPrimaryPokemonRequirement(new CombinationPokemonRequirement( // Must also have either option 2 or 3 available to spawn
|
||||
new HeldItemRequirement(OPTION_2_ALLOWED_MODIFIERS),
|
||||
new HeldItemRequirement(OPTION_3_DISALLOWED_MODIFIERS, 1, true)
|
||||
))
|
||||
.withPrimaryPokemonRequirement(
|
||||
CombinationPokemonRequirement.Some(
|
||||
// Must also have either option 2 or 3 available to spawn
|
||||
new HeldItemRequirement(OPTION_2_ALLOWED_MODIFIERS),
|
||||
new HeldItemRequirement(OPTION_3_DISALLOWED_MODIFIERS, 1, true)
|
||||
)
|
||||
)
|
||||
.withIntroSpriteConfigs([
|
||||
{
|
||||
spriteKey: "",
|
||||
|
@ -215,10 +215,12 @@ export const FieryFalloutEncounter: MysteryEncounter =
|
||||
.withOption(
|
||||
MysteryEncounterOptionBuilder
|
||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
|
||||
.withPrimaryPokemonRequirement(new CombinationPokemonRequirement(
|
||||
new TypeRequirement(Type.FIRE, true, 1),
|
||||
new AbilityRequirement(FIRE_RESISTANT_ABILITIES, true)
|
||||
)) // Will set option3PrimaryName dialogue token automatically
|
||||
.withPrimaryPokemonRequirement(
|
||||
CombinationPokemonRequirement.Some(
|
||||
new TypeRequirement(Type.FIRE, true, 1),
|
||||
new AbilityRequirement(FIRE_RESISTANT_ABILITIES, true)
|
||||
)
|
||||
) // Will set option3PrimaryName dialogue token automatically
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.3.label`,
|
||||
buttonTooltip: `${namespace}:option.3.tooltip`,
|
||||
|
@ -37,31 +37,58 @@ export abstract class EncounterSceneRequirement implements EncounterRequirement
|
||||
abstract getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string];
|
||||
}
|
||||
|
||||
/**
|
||||
* Combination of multiple {@linkcode EncounterSceneRequirement | EncounterSceneRequirements} (OR/AND possible. See {@linkcode isAnd})
|
||||
*/
|
||||
export class CombinationSceneRequirement extends EncounterSceneRequirement {
|
||||
orRequirements: EncounterSceneRequirement[];
|
||||
/** If `true`, all requirements must be met (AND). If `false`, any requirement must be met (OR) */
|
||||
private isAnd: boolean;
|
||||
requirements: EncounterSceneRequirement[];
|
||||
|
||||
constructor(... orRequirements: EncounterSceneRequirement[]) {
|
||||
public static Some(...requirements: EncounterSceneRequirement[]): CombinationSceneRequirement {
|
||||
return new CombinationSceneRequirement(false, ...requirements);
|
||||
}
|
||||
|
||||
public static Every(...requirements: EncounterSceneRequirement[]): CombinationSceneRequirement {
|
||||
return new CombinationSceneRequirement(true, ...requirements);
|
||||
}
|
||||
|
||||
private constructor(isAnd: boolean, ...requirements: EncounterSceneRequirement[]) {
|
||||
super();
|
||||
this.orRequirements = orRequirements;
|
||||
this.isAnd = isAnd;
|
||||
this.requirements = requirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if all/any requirements are met (depends on {@linkcode isAnd})
|
||||
* @param scene The {@linkcode BattleScene} to check against
|
||||
* @returns true if all/any requirements are met (depends on {@linkcode isAnd})
|
||||
*/
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
for (const req of this.orRequirements) {
|
||||
if (req.meetsRequirement(scene)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return this.isAnd
|
||||
? this.requirements.every(req => req.meetsRequirement(scene))
|
||||
: this.requirements.some(req => req.meetsRequirement(scene));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a dialogue token key/value pair for the given {@linkcode EncounterSceneRequirement | requirements}.
|
||||
* @param scene The {@linkcode BattleScene} to check against
|
||||
* @param pokemon The {@linkcode PlayerPokemon} to check against
|
||||
* @returns A dialogue token key/value pair
|
||||
* @throws An {@linkcode Error} if {@linkcode isAnd} is `true` (not supported)
|
||||
*/
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
for (const req of this.orRequirements) {
|
||||
if (req.meetsRequirement(scene)) {
|
||||
return req.getDialogueToken(scene, pokemon);
|
||||
if (this.isAnd) {
|
||||
throw new Error("Not implemented (Sorry)");
|
||||
} else {
|
||||
for (const req of this.requirements) {
|
||||
if (req.meetsRequirement(scene)) {
|
||||
return req.getDialogueToken(scene, pokemon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.orRequirements[0].getDialogueToken(scene, pokemon);
|
||||
return this.requirements[0].getDialogueToken(scene, pokemon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,44 +117,74 @@ export abstract class EncounterPokemonRequirement implements EncounterRequiremen
|
||||
abstract getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string];
|
||||
}
|
||||
|
||||
/**
|
||||
* Combination of multiple {@linkcode EncounterPokemonRequirement | EncounterPokemonRequirements} (OR/AND possible. See {@linkcode isAnd})
|
||||
*/
|
||||
export class CombinationPokemonRequirement extends EncounterPokemonRequirement {
|
||||
orRequirements: EncounterPokemonRequirement[];
|
||||
/** If `true`, all requirements must be met (AND). If `false`, any requirement must be met (OR) */
|
||||
private isAnd: boolean;
|
||||
private requirements: EncounterPokemonRequirement[];
|
||||
|
||||
constructor(...orRequirements: EncounterPokemonRequirement[]) {
|
||||
public static Some(...requirements: EncounterPokemonRequirement[]): CombinationPokemonRequirement {
|
||||
return new CombinationPokemonRequirement(false, ...requirements);
|
||||
}
|
||||
|
||||
public static Every(...requirements: EncounterPokemonRequirement[]): CombinationPokemonRequirement {
|
||||
return new CombinationPokemonRequirement(true, ...requirements);
|
||||
}
|
||||
|
||||
private constructor(isAnd: boolean, ...requirements: EncounterPokemonRequirement[]) {
|
||||
super();
|
||||
this.isAnd = isAnd;
|
||||
this.invertQuery = false;
|
||||
this.minNumberOfPokemon = 1;
|
||||
this.orRequirements = orRequirements;
|
||||
this.requirements = requirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if all/any requirements are met (depends on {@linkcode isAnd})
|
||||
* @param scene The {@linkcode BattleScene} to check against
|
||||
* @returns true if all/any requirements are met (depends on {@linkcode isAnd})
|
||||
*/
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
for (const req of this.orRequirements) {
|
||||
if (req.meetsRequirement(scene)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return this.isAnd
|
||||
? this.requirements.every(req => req.meetsRequirement(scene))
|
||||
: this.requirements.some(req => req.meetsRequirement(scene));
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the players party for all party members that are compatible with all/any requirements (depends on {@linkcode isAnd})
|
||||
* @param partyPokemon The party of {@linkcode PlayerPokemon}
|
||||
* @returns All party members that are compatible with all/any requirements (depends on {@linkcode isAnd})
|
||||
*/
|
||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
for (const req of this.orRequirements) {
|
||||
const result = req.queryParty(partyPokemon);
|
||||
if (result?.length > 0) {
|
||||
return result;
|
||||
}
|
||||
if (this.isAnd) {
|
||||
return this.requirements.reduce((relevantPokemon, req) => req.queryParty(relevantPokemon), partyPokemon);
|
||||
} else {
|
||||
const matchingRequirement = this.requirements.find(req => req.queryParty(partyPokemon).length > 0);
|
||||
return matchingRequirement ? matchingRequirement.queryParty(partyPokemon) : [];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a dialogue token key/value pair for the given {@linkcode EncounterPokemonRequirement | requirements}.
|
||||
* @param scene The {@linkcode BattleScene} to check against
|
||||
* @param pokemon The {@linkcode PlayerPokemon} to check against
|
||||
* @returns A dialogue token key/value pair
|
||||
* @throws An {@linkcode Error} if {@linkcode isAnd} is `true` (not supported)
|
||||
*/
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
for (const req of this.orRequirements) {
|
||||
if (req.meetsRequirement(scene)) {
|
||||
return req.getDialogueToken(scene, pokemon);
|
||||
if (this.isAnd) {
|
||||
throw new Error("Not implemented (Sorry)");
|
||||
} else {
|
||||
for (const req of this.requirements) {
|
||||
if (req.meetsRequirement(scene)) {
|
||||
return req.getDialogueToken(scene, pokemon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.orRequirements[0].getDialogueToken(scene, pokemon);
|
||||
return this.requirements[0].getDialogueToken(scene, pokemon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user