refactor: apply Modifiers type inference (pattern)
Mirror from #1747 Co-authored-by: Dmitriy <kagno.dmitriy@gmail.com>
This commit is contained in:
parent
2221afca81
commit
919d2352f7
|
@ -2415,7 +2415,10 @@ export default class BattleScene extends SceneBase {
|
||||||
}
|
}
|
||||||
if ((modifier as PersistentModifier).add(this.modifiers, !!virtual, this)) {
|
if ((modifier as PersistentModifier).add(this.modifiers, !!virtual, this)) {
|
||||||
if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) {
|
if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) {
|
||||||
success = modifier.apply([ this.getPokemonById(modifier.pokemonId), true ]);
|
const pokemon = this.getPokemonById(modifier.pokemonId);
|
||||||
|
if (pokemon) {
|
||||||
|
success = modifier.apply(pokemon, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (playSound && !this.sound.get(soundName)) {
|
if (playSound && !this.sound.get(soundName)) {
|
||||||
this.playSound(soundName);
|
this.playSound(soundName);
|
||||||
|
@ -2442,7 +2445,7 @@ export default class BattleScene extends SceneBase {
|
||||||
for (const p in this.party) {
|
for (const p in this.party) {
|
||||||
const pokemon = this.party[p];
|
const pokemon = this.party[p];
|
||||||
|
|
||||||
const args: any[] = [ pokemon ];
|
const args: unknown[] = [];
|
||||||
if (modifier instanceof PokemonHpRestoreModifier) {
|
if (modifier instanceof PokemonHpRestoreModifier) {
|
||||||
if (!(modifier as PokemonHpRestoreModifier).fainted) {
|
if (!(modifier as PokemonHpRestoreModifier).fainted) {
|
||||||
const hpRestoreMultiplier = new Utils.IntegerHolder(1);
|
const hpRestoreMultiplier = new Utils.IntegerHolder(1);
|
||||||
|
@ -2455,8 +2458,8 @@ export default class BattleScene extends SceneBase {
|
||||||
args.push(this.getPokemonById(modifier.fusePokemonId) as PlayerPokemon);
|
args.push(this.getPokemonById(modifier.fusePokemonId) as PlayerPokemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modifier.shouldApply(args)) {
|
if (modifier.shouldApply(pokemon, ...args)) {
|
||||||
const result = modifier.apply(args);
|
const result = modifier.apply(pokemon, ...args);
|
||||||
if (result instanceof Promise) {
|
if (result instanceof Promise) {
|
||||||
modifierPromises.push(result.then(s => success ||= s));
|
modifierPromises.push(result.then(s => success ||= s));
|
||||||
} else {
|
} else {
|
||||||
|
@ -2468,8 +2471,8 @@ export default class BattleScene extends SceneBase {
|
||||||
return Promise.allSettled([this.party.map(p => p.updateInfo(instant)), ...modifierPromises]).then(() => resolve(success));
|
return Promise.allSettled([this.party.map(p => p.updateInfo(instant)), ...modifierPromises]).then(() => resolve(success));
|
||||||
} else {
|
} else {
|
||||||
const args = [ this ];
|
const args = [ this ];
|
||||||
if (modifier.shouldApply(args)) {
|
if (modifier.shouldApply(...args)) {
|
||||||
const result = modifier.apply(args);
|
const result = modifier.apply(...args);
|
||||||
if (result instanceof Promise) {
|
if (result instanceof Promise) {
|
||||||
return result.then(success => resolve(success));
|
return result.then(success => resolve(success));
|
||||||
} else {
|
} else {
|
||||||
|
@ -2491,7 +2494,10 @@ export default class BattleScene extends SceneBase {
|
||||||
}
|
}
|
||||||
if ((modifier as PersistentModifier).add(this.enemyModifiers, false, this)) {
|
if ((modifier as PersistentModifier).add(this.enemyModifiers, false, this)) {
|
||||||
if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) {
|
if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) {
|
||||||
modifier.apply([ this.getPokemonById(modifier.pokemonId), true ]);
|
const pokemon = this.getPokemonById(modifier.pokemonId);
|
||||||
|
if (pokemon) {
|
||||||
|
modifier.apply(pokemon, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (const rm of modifiersToRemove) {
|
for (const rm of modifiersToRemove) {
|
||||||
this.removeModifier(rm, true);
|
this.removeModifier(rm, true);
|
||||||
|
@ -2727,7 +2733,10 @@ export default class BattleScene extends SceneBase {
|
||||||
if (modifierIndex > -1) {
|
if (modifierIndex > -1) {
|
||||||
modifiers.splice(modifierIndex, 1);
|
modifiers.splice(modifierIndex, 1);
|
||||||
if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) {
|
if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) {
|
||||||
modifier.apply([ this.getPokemonById(modifier.pokemonId), false ]);
|
const pokemon = this.getPokemonById(modifier.pokemonId);
|
||||||
|
if (pokemon) {
|
||||||
|
modifier.apply(pokemon, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2745,16 +2754,36 @@ export default class BattleScene extends SceneBase {
|
||||||
return (player ? this.modifiers : this.enemyModifiers).filter((m): m is T => m instanceof modifierType);
|
return (player ? this.modifiers : this.enemyModifiers).filter((m): m is T => m instanceof modifierType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all of the modifiers that pass the `modifierFilter` function
|
||||||
|
* @param modifierFilter The function used to filter a target's modifiers
|
||||||
|
* @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true`
|
||||||
|
* @returns the list of all modifiers that passed the `modifierFilter` function
|
||||||
|
*/
|
||||||
findModifiers(modifierFilter: ModifierPredicate, player: boolean = true): PersistentModifier[] {
|
findModifiers(modifierFilter: ModifierPredicate, player: boolean = true): PersistentModifier[] {
|
||||||
return (player ? this.modifiers : this.enemyModifiers).filter(m => (modifierFilter as ModifierPredicate)(m));
|
return (player ? this.modifiers : this.enemyModifiers).filter(modifierFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the first modifier that pass the `modifierFilter` function
|
||||||
|
* @param modifierFilter The function used to filter a target's modifiers
|
||||||
|
* @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true`
|
||||||
|
* @returns the first modifier that passed the `modifierFilter` function; `undefined` if none passed
|
||||||
|
*/
|
||||||
findModifier(modifierFilter: ModifierPredicate, player: boolean = true): PersistentModifier | undefined {
|
findModifier(modifierFilter: ModifierPredicate, player: boolean = true): PersistentModifier | undefined {
|
||||||
return (player ? this.modifiers : this.enemyModifiers).find(m => (modifierFilter as ModifierPredicate)(m));
|
return (player ? this.modifiers : this.enemyModifiers).find(modifierFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
applyShuffledModifiers(scene: BattleScene, modifierType: Constructor<Modifier>, player: boolean = true, ...args: any[]): PersistentModifier[] {
|
/**
|
||||||
let modifiers = (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType && m.shouldApply(args));
|
* Apply all modifiers that match `modifierType` in a random order
|
||||||
|
* @param scene {@linkcode BattleScene} used to randomize the order of modifiers
|
||||||
|
* @param modifierType The type of modifier to apply; must extend {@linkcode PersistentModifier}
|
||||||
|
* @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true`
|
||||||
|
* @param ...args The list of arguments needed to invoke `modifierType.apply`
|
||||||
|
* @returns the list of all modifiers that matched `modifierType` and were applied.
|
||||||
|
*/
|
||||||
|
applyShuffledModifiers<T extends PersistentModifier>(scene: BattleScene, modifierType: Constructor<T>, player: boolean = true, ...args: Parameters<T["apply"]>): T[] {
|
||||||
|
let modifiers = (player ? this.modifiers : this.enemyModifiers).filter((m): m is T => m instanceof modifierType && m.shouldApply(...args));
|
||||||
scene.executeWithSeedOffset(() => {
|
scene.executeWithSeedOffset(() => {
|
||||||
const shuffleModifiers = mods => {
|
const shuffleModifiers = mods => {
|
||||||
if (mods.length < 1) {
|
if (mods.length < 1) {
|
||||||
|
@ -2768,15 +2797,23 @@ export default class BattleScene extends SceneBase {
|
||||||
return this.applyModifiersInternal(modifiers, player, args);
|
return this.applyModifiersInternal(modifiers, player, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
applyModifiers(modifierType: Constructor<Modifier>, player: boolean = true, ...args: any[]): PersistentModifier[] {
|
/**
|
||||||
const modifiers = (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType && m.shouldApply(args));
|
* Apply all modifiers that match `modifierType`
|
||||||
|
* @param modifierType The type of modifier to apply; must extend {@linkcode PersistentModifier}
|
||||||
|
* @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true`
|
||||||
|
* @param ...args The list of arguments needed to invoke `modifierType.apply`
|
||||||
|
* @returns the list of all modifiers that matched `modifierType` and were applied.
|
||||||
|
*/
|
||||||
|
applyModifiers<T extends PersistentModifier>(modifierType: Constructor<T>, player: boolean = true, ...args: Parameters<T["apply"]>): T[] {
|
||||||
|
const modifiers = (player ? this.modifiers : this.enemyModifiers).filter((m): m is T => m instanceof modifierType && m.shouldApply(...args));
|
||||||
return this.applyModifiersInternal(modifiers, player, args);
|
return this.applyModifiersInternal(modifiers, player, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
applyModifiersInternal(modifiers: PersistentModifier[], player: boolean, args: any[]): PersistentModifier[] {
|
/** Helper function to apply all passed modifiers */
|
||||||
const appliedModifiers: PersistentModifier[] = [];
|
applyModifiersInternal<T extends PersistentModifier>(modifiers: T[], player: boolean, args: Parameters<T["apply"]>): T[] {
|
||||||
|
const appliedModifiers: T[] = [];
|
||||||
for (const modifier of modifiers) {
|
for (const modifier of modifiers) {
|
||||||
if (modifier.apply(args)) {
|
if (modifier.apply(...args)) {
|
||||||
console.log("Applied", modifier.type.name, !player ? "(enemy)" : "");
|
console.log("Applied", modifier.type.name, !player ? "(enemy)" : "");
|
||||||
appliedModifiers.push(modifier);
|
appliedModifiers.push(modifier);
|
||||||
}
|
}
|
||||||
|
@ -2785,10 +2822,17 @@ export default class BattleScene extends SceneBase {
|
||||||
return appliedModifiers;
|
return appliedModifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyModifier(modifierType: Constructor<Modifier>, player: boolean = true, ...args: any[]): PersistentModifier | null {
|
/**
|
||||||
const modifiers = (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType && m.shouldApply(args));
|
* Apply the first modifier that matches `modifierType`
|
||||||
|
* @param modifierType The type of modifier to apply; must extend {@linkcode PersistentModifier}
|
||||||
|
* @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true`
|
||||||
|
* @param ...args The list of arguments needed to invoke `modifierType.apply`
|
||||||
|
* @returns the first modifier that matches `modifierType` and was applied; return `null` if none matched
|
||||||
|
*/
|
||||||
|
applyModifier<T extends PersistentModifier>(modifierType: Constructor<T>, player: boolean = true, ...args: Parameters<T["apply"]>): T | null {
|
||||||
|
const modifiers = (player ? this.modifiers : this.enemyModifiers).filter((m): m is T => m instanceof modifierType && m.shouldApply(...args));
|
||||||
for (const modifier of modifiers) {
|
for (const modifier of modifiers) {
|
||||||
if (modifier.apply(args)) {
|
if (modifier.apply(...args)) {
|
||||||
console.log("Applied", modifier.type.name, !player ? "(enemy)" : "");
|
console.log("Applied", modifier.type.name, !player ? "(enemy)" : "");
|
||||||
return modifier;
|
return modifier;
|
||||||
}
|
}
|
||||||
|
@ -2854,7 +2898,7 @@ export default class BattleScene extends SceneBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
validateAchv(achv: Achv, args?: any[]): boolean {
|
validateAchv(achv: Achv, args?: unknown[]): boolean {
|
||||||
if (!this.gameData.achvUnlocks.hasOwnProperty(achv.id) && achv.validate(this, args)) {
|
if (!this.gameData.achvUnlocks.hasOwnProperty(achv.id) && achv.validate(this, args)) {
|
||||||
this.gameData.achvUnlocks[achv.id] = new Date().getTime();
|
this.gameData.achvUnlocks[achv.id] = new Date().getTime();
|
||||||
this.ui.achvBar.showAchv(achv);
|
this.ui.achvBar.showAchv(achv);
|
||||||
|
@ -2867,7 +2911,7 @@ export default class BattleScene extends SceneBase {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
validateVoucher(voucher: Voucher, args?: any[]): boolean {
|
validateVoucher(voucher: Voucher, args?: unknown[]): boolean {
|
||||||
if (!this.gameData.voucherUnlocks.hasOwnProperty(voucher.id) && voucher.validate(this, args)) {
|
if (!this.gameData.voucherUnlocks.hasOwnProperty(voucher.id) && voucher.validate(this, args)) {
|
||||||
this.gameData.voucherUnlocks[voucher.id] = new Date().getTime();
|
this.gameData.voucherUnlocks[voucher.id] = new Date().getTime();
|
||||||
this.ui.achvBar.showAchv(voucher);
|
this.ui.achvBar.showAchv(voucher);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,7 +15,7 @@ export class BerryPhase extends FieldPhase {
|
||||||
|
|
||||||
this.executeForAll((pokemon) => {
|
this.executeForAll((pokemon) => {
|
||||||
const hasUsableBerry = !!this.scene.findModifier((m) => {
|
const hasUsableBerry = !!this.scene.findModifier((m) => {
|
||||||
return m instanceof BerryModifier && m.shouldApply([pokemon]);
|
return m instanceof BerryModifier && m.shouldApply(pokemon);
|
||||||
}, pokemon.isPlayer());
|
}, pokemon.isPlayer());
|
||||||
|
|
||||||
if (hasUsableBerry) {
|
if (hasUsableBerry) {
|
||||||
|
@ -29,7 +29,7 @@ export class BerryPhase extends FieldPhase {
|
||||||
new CommonAnimPhase(this.scene, pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.USE_ITEM)
|
new CommonAnimPhase(this.scene, pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.USE_ITEM)
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const berryModifier of this.scene.applyModifiers(BerryModifier, pokemon.isPlayer(), pokemon) as BerryModifier[]) {
|
for (const berryModifier of this.scene.applyModifiers(BerryModifier, pokemon.isPlayer(), pokemon)) {
|
||||||
if (berryModifier.consumed) {
|
if (berryModifier.consumed) {
|
||||||
if (!--berryModifier.stackCount) {
|
if (!--berryModifier.stackCount) {
|
||||||
this.scene.removeModifier(berryModifier);
|
this.scene.removeModifier(berryModifier);
|
||||||
|
|
Loading…
Reference in New Issue