From e2290e4429a3a6f62ab300049108f69385a6766a Mon Sep 17 00:00:00 2001 From: Dmitriy K Date: Thu, 11 Jul 2024 15:56:26 -0400 Subject: [PATCH] [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 --- src/data/ability.ts | 100 +++++++++++------------------ src/test/utils/gameManagerUtils.ts | 7 +- 2 files changed, 42 insertions(+), 65 deletions(-) diff --git a/src/data/ability.ts b/src/data/ability.ts index 2eb9f8caaa7..60850c59a2a 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -3922,47 +3922,42 @@ export class BypassSpeedChanceAbAttr extends AbAttr { } } -function applyAbAttrsInternal(attrType: Constructor, - pokemon: Pokemon, applyFunc: AbAttrApplyFunc, args: any[], isAsync: boolean = false, showAbilityInstant: boolean = false, quiet: boolean = false, passive: boolean = false): Promise { - return new Promise(resolve => { +async function applyAbAttrsInternal( + attrType: Constructor, + pokemon: Pokemon, + applyFunc: AbAttrApplyFunc, + 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(attrType: Constructor 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, pokemon: Pokemon, cancelled: Utils.BooleanHolder, ...args: any[]): Promise { @@ -4012,7 +3991,7 @@ export function applyPostBattleInitAbAttrs(attrType: Constructor, pokemon: Pokemon, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, ...args: any[]): Promise { const simulated = args.length > 1 && args[1]; - return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPreDefend(pokemon, passive, attacker, move, cancelled, args), args, false, false, simulated); + return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPreDefend(pokemon, passive, attacker, move, cancelled, args), args, false, simulated); } export function applyPostDefendAbAttrs(attrType: Constructor, @@ -4072,7 +4051,7 @@ export function applyPostSummonAbAttrs(attrType: Constructor, export function applyPreSwitchOutAbAttrs(attrType: Constructor, pokemon: Pokemon, ...args: any[]): Promise { - return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPreSwitchOut(pokemon, passive, args), args, false, true); + return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPreSwitchOut(pokemon, passive, args), args, true); } export function applyPreStatChangeAbAttrs(attrType: Constructor, @@ -4088,7 +4067,7 @@ export function applyPostStatChangeAbAttrs(attrType: Constructor, pokemon: Pokemon, effect: StatusEffect, cancelled: Utils.BooleanHolder, ...args: any[]): Promise { const simulated = args.length > 1 && args[1]; - return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPreSetStatus(pokemon, passive, effect, cancelled, args), args, false, false, !simulated); + return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPreSetStatus(pokemon, passive, effect, cancelled, args), args, false, !simulated); } export function applyPreApplyBattlerTagAbAttrs(attrType: Constructor, @@ -4098,7 +4077,7 @@ export function applyPreApplyBattlerTagAbAttrs(attrType: Constructor, pokemon: Pokemon, weather: Weather, cancelled: Utils.BooleanHolder, ...args: any[]): Promise { - return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPreWeatherEffect(pokemon, passive, weather, cancelled, args), args, false, true); + return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyPreWeatherEffect(pokemon, passive, weather, cancelled, args), args, true); } export function applyPostTurnAbAttrs(attrType: Constructor, @@ -4123,7 +4102,7 @@ export function applyPostTerrainChangeAbAttrs(attrType: Constructor, pokemon: Pokemon, trapped: Utils.BooleanHolder, otherPokemon: Pokemon, ...args: any[]): Promise { - return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyCheckTrapped(pokemon, passive, trapped, otherPokemon, args), args, true); + return applyAbAttrsInternal(attrType, pokemon, (attr, passive) => attr.applyCheckTrapped(pokemon, passive, trapped, otherPokemon, args), args); } export function applyPostBattleAbAttrs(attrType: Constructor, @@ -4136,11 +4115,6 @@ export function applyPostFaintAbAttrs(attrType: Constructor, return applyAbAttrsInternal(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(); diff --git a/src/test/utils/gameManagerUtils.ts b/src/test/utils/gameManagerUtils.ts index db9ba7174a9..d83805e59e8 100644 --- a/src/test/utils/gameManagerUtils.ts +++ b/src/test/utils/gameManagerUtils.ts @@ -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; }