[Refactor] rewrite applyAbAttrsInternal to use an iterator. (#1832)

* initial rewrite of applyAbAttrsInternal

* clean up applyAbAttrsInternal

* remove the await because it wraps non Promises in a promise

* add TODO comment about promises

* fix broken costar test, hopefully
This commit is contained in:
Dmitriy K 2024-07-11 15:56:26 -04:00 committed by GitHub
parent aa90a9ff2d
commit e2290e4429
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 42 additions and 65 deletions

View File

@ -3922,47 +3922,42 @@ export class BypassSpeedChanceAbAttr extends AbAttr {
} }
} }
function applyAbAttrsInternal<TAttr extends AbAttr>(attrType: Constructor<TAttr>, async function applyAbAttrsInternal<TAttr extends AbAttr>(
pokemon: Pokemon, applyFunc: AbAttrApplyFunc<TAttr>, args: any[], isAsync: boolean = false, showAbilityInstant: boolean = false, quiet: boolean = false, passive: boolean = false): Promise<void> { attrType: Constructor<TAttr>,
return new Promise(resolve => { pokemon: Pokemon,
applyFunc: AbAttrApplyFunc<TAttr>,
args: any[],
showAbilityInstant: boolean = false,
quiet: boolean = false,
) {
for (const passive of [false, true]) {
if (!pokemon.canApplyAbility(passive)) { if (!pokemon.canApplyAbility(passive)) {
if (!passive) { continue;
return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve());
} else {
return resolve();
}
} }
const ability = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()); const ability = passive ? pokemon.getPassiveAbility() : pokemon.getAbility();
const attrs = ability.getAttrs(attrType); for (const attr of ability.getAttrs(attrType)) {
const condition = attr.getCondition();
if (condition && !condition(pokemon)) {
continue;
}
const clearSpliceQueueAndResolve = () => {
pokemon.scene?.clearPhaseQueueSplice();
if (!passive) {
return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve());
} else {
return resolve();
}
};
const applyNextAbAttr = () => {
if (attrs.length) {
applyAbAttr(attrs.shift());
} else {
clearSpliceQueueAndResolve();
}
};
const applyAbAttr = (attr: TAttr) => {
if (!canApplyAttr(pokemon, attr)) {
return applyNextAbAttr();
}
pokemon.scene.setPhaseQueueSplice(); pokemon.scene.setPhaseQueueSplice();
const onApplySuccess = () => {
let result = applyFunc(attr, passive);
// TODO Remove this when promises get reworked PR#924
if (result instanceof Promise) {
result = await result;
}
if (result) {
if (pokemon.summonData && !pokemon.summonData.abilitiesApplied.includes(ability.id)) { if (pokemon.summonData && !pokemon.summonData.abilitiesApplied.includes(ability.id)) {
pokemon.summonData.abilitiesApplied.push(ability.id); pokemon.summonData.abilitiesApplied.push(ability.id);
} }
if (pokemon.battleData && !pokemon.battleData.abilitiesApplied.includes(ability.id)) { if (pokemon.battleData && !pokemon.battleData.abilitiesApplied.includes(ability.id)) {
pokemon.battleData.abilitiesApplied.push(ability.id); pokemon.battleData.abilitiesApplied.push(ability.id);
} }
if (attr.showAbility && !quiet) { if (attr.showAbility && !quiet) {
if (showAbilityInstant) { if (showAbilityInstant) {
pokemon.scene.abilityBar.showAbility(pokemon, passive); pokemon.scene.abilityBar.showAbility(pokemon, passive);
@ -3970,34 +3965,18 @@ function applyAbAttrsInternal<TAttr extends AbAttr>(attrType: Constructor<TAttr>
queueShowAbility(pokemon, passive); queueShowAbility(pokemon, passive);
} }
} }
if (!quiet) { if (!quiet) {
const message = attr.getTriggerMessage(pokemon, (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name, args); const message = attr.getTriggerMessage(pokemon, ability.name, args);
if (message) { if (message) {
if (isAsync) { pokemon.scene.queueMessage(message);
pokemon.scene.ui.showText(message, null, () => pokemon.scene.ui.showText(null, 0), null, true);
} else {
pokemon.scene.queueMessage(message);
}
} }
} }
};
const result = applyFunc(attr, passive);
if (result instanceof Promise) {
result.then(success => {
if (success) {
onApplySuccess();
}
applyNextAbAttr();
});
} else {
if (result) {
onApplySuccess();
}
applyNextAbAttr();
} }
}; }
applyNextAbAttr();
}); pokemon.scene.clearPhaseQueueSplice();
}
} }
export function applyAbAttrs(attrType: Constructor<AbAttr>, pokemon: Pokemon, cancelled: Utils.BooleanHolder, ...args: any[]): Promise<void> { export function applyAbAttrs(attrType: Constructor<AbAttr>, pokemon: Pokemon, cancelled: Utils.BooleanHolder, ...args: any[]): Promise<void> {
@ -4012,7 +3991,7 @@ export function applyPostBattleInitAbAttrs(attrType: Constructor<PostBattleInitA
export function applyPreDefendAbAttrs(attrType: Constructor<PreDefendAbAttr>, export function applyPreDefendAbAttrs(attrType: Constructor<PreDefendAbAttr>,
pokemon: Pokemon, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, ...args: any[]): Promise<void> { pokemon: Pokemon, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, ...args: any[]): Promise<void> {
const simulated = args.length > 1 && args[1]; const simulated = args.length > 1 && args[1];
return applyAbAttrsInternal<PreDefendAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPreDefend(pokemon, passive, attacker, move, cancelled, args), args, false, false, simulated); return applyAbAttrsInternal<PreDefendAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPreDefend(pokemon, passive, attacker, move, cancelled, args), args, false, simulated);
} }
export function applyPostDefendAbAttrs(attrType: Constructor<PostDefendAbAttr>, export function applyPostDefendAbAttrs(attrType: Constructor<PostDefendAbAttr>,
@ -4072,7 +4051,7 @@ export function applyPostSummonAbAttrs(attrType: Constructor<PostSummonAbAttr>,
export function applyPreSwitchOutAbAttrs(attrType: Constructor<PreSwitchOutAbAttr>, export function applyPreSwitchOutAbAttrs(attrType: Constructor<PreSwitchOutAbAttr>,
pokemon: Pokemon, ...args: any[]): Promise<void> { pokemon: Pokemon, ...args: any[]): Promise<void> {
return applyAbAttrsInternal<PreSwitchOutAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPreSwitchOut(pokemon, passive, args), args, false, true); return applyAbAttrsInternal<PreSwitchOutAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPreSwitchOut(pokemon, passive, args), args, true);
} }
export function applyPreStatChangeAbAttrs(attrType: Constructor<PreStatChangeAbAttr>, export function applyPreStatChangeAbAttrs(attrType: Constructor<PreStatChangeAbAttr>,
@ -4088,7 +4067,7 @@ export function applyPostStatChangeAbAttrs(attrType: Constructor<PostStatChangeA
export function applyPreSetStatusAbAttrs(attrType: Constructor<PreSetStatusAbAttr>, export function applyPreSetStatusAbAttrs(attrType: Constructor<PreSetStatusAbAttr>,
pokemon: Pokemon, effect: StatusEffect, cancelled: Utils.BooleanHolder, ...args: any[]): Promise<void> { pokemon: Pokemon, effect: StatusEffect, cancelled: Utils.BooleanHolder, ...args: any[]): Promise<void> {
const simulated = args.length > 1 && args[1]; const simulated = args.length > 1 && args[1];
return applyAbAttrsInternal<PreSetStatusAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPreSetStatus(pokemon, passive, effect, cancelled, args), args, false, false, !simulated); return applyAbAttrsInternal<PreSetStatusAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPreSetStatus(pokemon, passive, effect, cancelled, args), args, false, !simulated);
} }
export function applyPreApplyBattlerTagAbAttrs(attrType: Constructor<PreApplyBattlerTagAbAttr>, export function applyPreApplyBattlerTagAbAttrs(attrType: Constructor<PreApplyBattlerTagAbAttr>,
@ -4098,7 +4077,7 @@ export function applyPreApplyBattlerTagAbAttrs(attrType: Constructor<PreApplyBat
export function applyPreWeatherEffectAbAttrs(attrType: Constructor<PreWeatherEffectAbAttr>, export function applyPreWeatherEffectAbAttrs(attrType: Constructor<PreWeatherEffectAbAttr>,
pokemon: Pokemon, weather: Weather, cancelled: Utils.BooleanHolder, ...args: any[]): Promise<void> { pokemon: Pokemon, weather: Weather, cancelled: Utils.BooleanHolder, ...args: any[]): Promise<void> {
return applyAbAttrsInternal<PreWeatherDamageAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPreWeatherEffect(pokemon, passive, weather, cancelled, args), args, false, true); return applyAbAttrsInternal<PreWeatherDamageAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPreWeatherEffect(pokemon, passive, weather, cancelled, args), args, true);
} }
export function applyPostTurnAbAttrs(attrType: Constructor<PostTurnAbAttr>, export function applyPostTurnAbAttrs(attrType: Constructor<PostTurnAbAttr>,
@ -4123,7 +4102,7 @@ export function applyPostTerrainChangeAbAttrs(attrType: Constructor<PostTerrainC
export function applyCheckTrappedAbAttrs(attrType: Constructor<CheckTrappedAbAttr>, export function applyCheckTrappedAbAttrs(attrType: Constructor<CheckTrappedAbAttr>,
pokemon: Pokemon, trapped: Utils.BooleanHolder, otherPokemon: Pokemon, ...args: any[]): Promise<void> { pokemon: Pokemon, trapped: Utils.BooleanHolder, otherPokemon: Pokemon, ...args: any[]): Promise<void> {
return applyAbAttrsInternal<CheckTrappedAbAttr>(attrType, pokemon, (attr, passive) => attr.applyCheckTrapped(pokemon, passive, trapped, otherPokemon, args), args, true); return applyAbAttrsInternal<CheckTrappedAbAttr>(attrType, pokemon, (attr, passive) => attr.applyCheckTrapped(pokemon, passive, trapped, otherPokemon, args), args);
} }
export function applyPostBattleAbAttrs(attrType: Constructor<PostBattleAbAttr>, export function applyPostBattleAbAttrs(attrType: Constructor<PostBattleAbAttr>,
@ -4136,11 +4115,6 @@ export function applyPostFaintAbAttrs(attrType: Constructor<PostFaintAbAttr>,
return applyAbAttrsInternal<PostFaintAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPostFaint(pokemon, passive, attacker, move, hitResult, args), args); return applyAbAttrsInternal<PostFaintAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPostFaint(pokemon, passive, attacker, move, hitResult, args), args);
} }
function canApplyAttr(pokemon: Pokemon, attr: AbAttr): boolean {
const condition = attr.getCondition();
return !condition || condition(pokemon);
}
function queueShowAbility(pokemon: Pokemon, passive: boolean): void { function queueShowAbility(pokemon: Pokemon, passive: boolean): void {
pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.id, passive)); pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.id, passive));
pokemon.scene.clearPhaseQueueSplice(); pokemon.scene.clearPhaseQueueSplice();

View File

@ -6,6 +6,8 @@ import {Starter} from "#app/ui/starter-select-ui-handler";
import {GameModes, getGameMode} from "#app/game-mode"; import {GameModes, getGameMode} from "#app/game-mode";
import {getPokemonSpecies, getPokemonSpeciesForm} from "#app/data/pokemon-species"; import {getPokemonSpecies, getPokemonSpeciesForm} from "#app/data/pokemon-species";
import {PlayerPokemon} from "#app/field/pokemon"; import {PlayerPokemon} from "#app/field/pokemon";
import { Moves } from "#app/enums/moves";
import BattleScene from "#app/battle-scene";
export function blobToString(blob) { export function blobToString(blob) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -79,9 +81,10 @@ export function waitUntil(truth) {
}); });
} }
export function getMovePosition(scene, pokemonIndex, moveIndex) { /** Get the index of `move` from the moveset of the pokemon on the player's field at location `pokemonIndex` */
export function getMovePosition(scene: BattleScene, pokemonIndex: 0 | 1, move: Moves) {
const playerPokemon = scene.getPlayerField()[pokemonIndex]; const playerPokemon = scene.getPlayerField()[pokemonIndex];
const moveSet = playerPokemon.getMoveset(); const moveSet = playerPokemon.getMoveset();
const index = moveSet.findIndex((move) => move.moveId === moveIndex); const index = moveSet.findIndex((m) => m.moveId === move);
return index; return index;
} }