[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>,
pokemon: Pokemon, applyFunc: AbAttrApplyFunc<TAttr>, args: any[], isAsync: boolean = false, showAbilityInstant: boolean = false, quiet: boolean = false, passive: boolean = false): Promise<void> {
return new Promise(resolve => {
async function applyAbAttrsInternal<TAttr extends AbAttr>(
attrType: Constructor<TAttr>,
pokemon: Pokemon,
applyFunc: AbAttrApplyFunc<TAttr>,
args: any[],
showAbilityInstant: boolean = false,
quiet: boolean = false,
) {
for (const passive of [false, true]) {
if (!pokemon.canApplyAbility(passive)) {
if (!passive) {
return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve());
} else {
return resolve();
}
continue;
}
const ability = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility());
const attrs = ability.getAttrs(attrType);
const ability = passive ? pokemon.getPassiveAbility() : pokemon.getAbility();
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();
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)) {
pokemon.summonData.abilitiesApplied.push(ability.id);
}
if (pokemon.battleData && !pokemon.battleData.abilitiesApplied.includes(ability.id)) {
pokemon.battleData.abilitiesApplied.push(ability.id);
}
if (attr.showAbility && !quiet) {
if (showAbilityInstant) {
pokemon.scene.abilityBar.showAbility(pokemon, passive);
@ -3970,34 +3965,18 @@ function applyAbAttrsInternal<TAttr extends AbAttr>(attrType: Constructor<TAttr>
queueShowAbility(pokemon, passive);
}
}
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 (isAsync) {
pokemon.scene.ui.showText(message, null, () => pokemon.scene.ui.showText(null, 0), null, true);
} else {
pokemon.scene.queueMessage(message);
}
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> {
@ -4012,7 +3991,7 @@ export function applyPostBattleInitAbAttrs(attrType: Constructor<PostBattleInitA
export function applyPreDefendAbAttrs(attrType: Constructor<PreDefendAbAttr>,
pokemon: Pokemon, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, ...args: any[]): Promise<void> {
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>,
@ -4072,7 +4051,7 @@ export function applyPostSummonAbAttrs(attrType: Constructor<PostSummonAbAttr>,
export function applyPreSwitchOutAbAttrs(attrType: Constructor<PreSwitchOutAbAttr>,
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>,
@ -4088,7 +4067,7 @@ export function applyPostStatChangeAbAttrs(attrType: Constructor<PostStatChangeA
export function applyPreSetStatusAbAttrs(attrType: Constructor<PreSetStatusAbAttr>,
pokemon: Pokemon, effect: StatusEffect, cancelled: Utils.BooleanHolder, ...args: any[]): Promise<void> {
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>,
@ -4098,7 +4077,7 @@ export function applyPreApplyBattlerTagAbAttrs(attrType: Constructor<PreApplyBat
export function applyPreWeatherEffectAbAttrs(attrType: Constructor<PreWeatherEffectAbAttr>,
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>,
@ -4123,7 +4102,7 @@ export function applyPostTerrainChangeAbAttrs(attrType: Constructor<PostTerrainC
export function applyCheckTrappedAbAttrs(attrType: Constructor<CheckTrappedAbAttr>,
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>,
@ -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);
}
function canApplyAttr(pokemon: Pokemon, attr: AbAttr): boolean {
const condition = attr.getCondition();
return !condition || condition(pokemon);
}
function queueShowAbility(pokemon: Pokemon, passive: boolean): void {
pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.id, passive));
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 {getPokemonSpecies, getPokemonSpeciesForm} from "#app/data/pokemon-species";
import {PlayerPokemon} from "#app/field/pokemon";
import { Moves } from "#app/enums/moves";
import BattleScene from "#app/battle-scene";
export function blobToString(blob) {
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 moveSet = playerPokemon.getMoveset();
const index = moveSet.findIndex((move) => move.moveId === moveIndex);
const index = moveSet.findIndex((m) => m.moveId === move);
return index;
}