From 82e24bf4bcc8d00e52377b749a319ad852a2fbe6 Mon Sep 17 00:00:00 2001 From: Wlowscha <54003515+Wlowscha@users.noreply.github.com> Date: Wed, 28 May 2025 00:14:51 +0200 Subject: [PATCH] Splitting up methods in select-modifier-phase.ts --- src/phases/select-modifier-phase.ts | 528 ++++++++++++++-------------- 1 file changed, 264 insertions(+), 264 deletions(-) diff --git a/src/phases/select-modifier-phase.ts b/src/phases/select-modifier-phase.ts index 5f11441333b..6a84bf692a9 100644 --- a/src/phases/select-modifier-phase.ts +++ b/src/phases/select-modifier-phase.ts @@ -66,6 +66,267 @@ export class SelectModifierPhase extends BattlePhase { if (!this.isCopy) { regenerateModifierPoolThresholds(party, this.getPoolType(), this.rerollCount); } + const modifierCount = this.getModifierCount(); + + this.typeOptions = this.getModifierTypeOptions(modifierCount.value); + + const modifierSelectCallback = (rowCursor: number, cursor: number) => { + if (rowCursor < 0 || cursor < 0) { + globalScene.ui.showText(i18next.t("battle:skipItemQuestion"), null, () => { + globalScene.ui.setOverlayMode( + UiMode.CONFIRM, + () => { + globalScene.ui.revertMode(); + globalScene.ui.setMode(UiMode.MESSAGE); + super.end(); + }, + () => this.resetModifierSelect(modifierSelectCallback), + ); + }); + return false; + } + let modifierType: ModifierType; + let cost = 0; + switch (rowCursor) { + // Execute option from the bottom row + case 0: + return this.playBottomRowOption(cursor, modifierSelectCallback); + // Pick an option from the rewards + case 1: + if (this.typeOptions.length === 0) { + globalScene.ui.clearText(); + globalScene.ui.setMode(UiMode.MESSAGE); + super.end(); + return true; + } + if (this.typeOptions[cursor].type) { + modifierType = this.typeOptions[cursor].type; + } + break; + // Pick an option from the shop + default: { + const shopOptions = getPlayerShopModifierTypeOptionsForWave( + globalScene.currentBattle.waveIndex, + globalScene.getWaveMoneyAmount(1), + ); + const shopOption = + shopOptions[ + rowCursor > 2 || shopOptions.length <= SHOP_OPTIONS_ROW_LIMIT ? cursor : cursor + SHOP_OPTIONS_ROW_LIMIT + ]; + if (shopOption.type) { + modifierType = shopOption.type; + } + // Apply Black Sludge to healing item cost + const healingItemCost = new NumberHolder(shopOption.cost); + globalScene.applyModifier(HealShopCostModifier, true, healingItemCost); + cost = healingItemCost.value; + break; + } + } + + if (cost! && globalScene.money < cost && !Overrides.WAIVE_ROLL_FEE_OVERRIDE) { + globalScene.ui.playError(); + return false; + } + + if (modifierType! instanceof PokemonModifierType) { + //TODO: is the bang correct? + if (modifierType instanceof FusePokemonModifierType) { + this.openFusionMenu(modifierType, cost, modifierSelectCallback); + } else { + this.openModifierMenu(modifierType, cost, modifierSelectCallback); + } + } else { + this.applyModifier(modifierType!.newModifier()!); // TODO: is the bang correct? + } + + return !cost!; // TODO: is the bang correct? + }; + this.resetModifierSelect(modifierSelectCallback); + } + + private playBottomRowOption(cursor: number, modifierSelectCallback): boolean { + const party = globalScene.getPlayerParty(); + const rerollCost = this.getRerollCost(globalScene.lockModifierTiers); + switch (cursor) { + // Reroll rewards + case 0: + if (rerollCost < 0 || globalScene.money < rerollCost) { + globalScene.ui.playError(); + return false; + } + globalScene.reroll = true; + globalScene.unshiftPhase( + new SelectModifierPhase( + this.rerollCount + 1, + this.typeOptions.map(o => o.type?.tier).filter(t => t !== undefined) as ModifierTier[], + ), + ); + globalScene.ui.clearText(); + globalScene.ui.setMode(UiMode.MESSAGE).then(() => super.end()); + if (!Overrides.WAIVE_ROLL_FEE_OVERRIDE) { + globalScene.money -= rerollCost; + globalScene.updateMoneyText(); + globalScene.animateMoneyChanged(false); + } + globalScene.playSound("se/buy"); + break; + // Transfer modifiers among party pokemon + case 1: + globalScene.ui.setModeWithoutClear( + UiMode.PARTY, + PartyUiMode.MODIFIER_TRANSFER, + -1, + (fromSlotIndex: number, itemIndex: number, itemQuantity: number, toSlotIndex: number) => { + if ( + toSlotIndex !== undefined && + fromSlotIndex < 6 && + toSlotIndex < 6 && + fromSlotIndex !== toSlotIndex && + itemIndex > -1 + ) { + const itemModifiers = globalScene.findModifiers( + m => + m instanceof PokemonHeldItemModifier && m.isTransferable && m.pokemonId === party[fromSlotIndex].id, + ) as PokemonHeldItemModifier[]; + const itemModifier = itemModifiers[itemIndex]; + globalScene.tryTransferHeldItemModifier( + itemModifier, + party[toSlotIndex], + true, + itemQuantity, + undefined, + undefined, + false, + ); + } else { + this.resetModifierSelect(modifierSelectCallback); + } + }, + PartyUiHandler.FilterItemMaxStacks, + ); + break; + // Check the party, pass a callback to restore the modifier select screen. + case 2: + globalScene.ui.setModeWithoutClear(UiMode.PARTY, PartyUiMode.CHECK, -1, () => { + this.resetModifierSelect(modifierSelectCallback); + }); + break; + // Toggle reroll lock + case 3: + if (rerollCost < 0) { + // Reroll lock button is also disabled when reroll is disabled + globalScene.ui.playError(); + return false; + } + globalScene.lockModifierTiers = !globalScene.lockModifierTiers; + const uiHandler = globalScene.ui.getHandler() as ModifierSelectUiHandler; + uiHandler.setRerollCost(this.getRerollCost(globalScene.lockModifierTiers)); + uiHandler.updateLockRaritiesText(); + uiHandler.updateRerollCostText(); + return false; + } + return true; + } + + private applyModifier(modifier: Modifier, cost = 0, playSound = false) { + const result = globalScene.addModifier(modifier, false, playSound, undefined, undefined, cost); + // Queue a copy of this phase when applying a TM or Memory Mushroom. + // If the player selects either of these, then escapes out of consuming them, + // they are returned to a shop in the same state. + if (modifier.type instanceof RememberMoveModifierType || modifier.type instanceof TmModifierType) { + globalScene.unshiftPhase(this.copy()); + } + + if (cost && !(modifier.type instanceof RememberMoveModifierType)) { + if (result) { + if (!Overrides.WAIVE_ROLL_FEE_OVERRIDE) { + globalScene.money -= cost; + globalScene.updateMoneyText(); + globalScene.animateMoneyChanged(false); + } + globalScene.playSound("se/buy"); + (globalScene.ui.getHandler() as ModifierSelectUiHandler).updateCostText(); + } else { + globalScene.ui.playError(); + } + } else { + globalScene.ui.clearText(); + globalScene.ui.setMode(UiMode.MESSAGE); + super.end(); + } + } + + private openFusionMenu(modifierType, cost, modifierSelectCallback) { + const party = globalScene.getPlayerParty(); + globalScene.ui.setModeWithoutClear( + UiMode.PARTY, + PartyUiMode.SPLICE, + -1, + (fromSlotIndex: number, spliceSlotIndex: number) => { + if ( + spliceSlotIndex !== undefined && + fromSlotIndex < 6 && + spliceSlotIndex < 6 && + fromSlotIndex !== spliceSlotIndex + ) { + globalScene.ui.setMode(UiMode.MODIFIER_SELECT, this.isPlayer()).then(() => { + const modifier = modifierType.newModifier(party[fromSlotIndex], party[spliceSlotIndex])!; //TODO: is the bang correct? + this.applyModifier(modifier, cost, true); + }); + } else { + this.resetModifierSelect(modifierSelectCallback); + } + }, + modifierType.selectFilter, + ); + } + + private openModifierMenu(modifierType, cost, modifierSelectCallback) { + const party = globalScene.getPlayerParty(); + const pokemonModifierType = modifierType as PokemonModifierType; + const isMoveModifier = modifierType instanceof PokemonMoveModifierType; + const isTmModifier = modifierType instanceof TmModifierType; + const isRememberMoveModifier = modifierType instanceof RememberMoveModifierType; + const isPpRestoreModifier = + modifierType instanceof PokemonPpRestoreModifierType || modifierType instanceof PokemonPpUpModifierType; + const partyUiMode = isMoveModifier + ? PartyUiMode.MOVE_MODIFIER + : isTmModifier + ? PartyUiMode.TM_MODIFIER + : isRememberMoveModifier + ? PartyUiMode.REMEMBER_MOVE_MODIFIER + : PartyUiMode.MODIFIER; + const tmMoveId = isTmModifier ? (modifierType as TmModifierType).moveId : undefined; + globalScene.ui.setModeWithoutClear( + UiMode.PARTY, + partyUiMode, + -1, + (slotIndex: number, option: PartyOption) => { + if (slotIndex < 6) { + globalScene.ui.setMode(UiMode.MODIFIER_SELECT, this.isPlayer()).then(() => { + const modifier = !isMoveModifier + ? !isRememberMoveModifier + ? modifierType.newModifier(party[slotIndex]) + : modifierType.newModifier(party[slotIndex], option as number) + : modifierType.newModifier(party[slotIndex], option - PartyOption.MOVE_1); + this.applyModifier(modifier!, cost, true); // TODO: is the bang correct? + }); + } else { + this.resetModifierSelect(modifierSelectCallback); + } + }, + pokemonModifierType.selectFilter, + modifierType instanceof PokemonMoveModifierType + ? (modifierType as PokemonMoveModifierType).moveSelectFilter + : undefined, + tmMoveId, + isPpRestoreModifier, + ); + } + + // Function that determines how many reward slots are available + private getModifierCount() { const modifierCount = new NumberHolder(3); if (this.isPlayer()) { globalScene.applyModifiers(ExtraModifierModifier, true, modifierCount); @@ -86,271 +347,10 @@ export class SelectModifierPhase extends BattlePhase { } } - this.typeOptions = this.getModifierTypeOptions(modifierCount.value); + return modifierCount; + } - const modifierSelectCallback = (rowCursor: number, cursor: number) => { - if (rowCursor < 0 || cursor < 0) { - globalScene.ui.showText(i18next.t("battle:skipItemQuestion"), null, () => { - globalScene.ui.setOverlayMode( - UiMode.CONFIRM, - () => { - globalScene.ui.revertMode(); - globalScene.ui.setMode(UiMode.MESSAGE); - super.end(); - }, - () => - globalScene.ui.setMode( - UiMode.MODIFIER_SELECT, - this.isPlayer(), - this.typeOptions, - modifierSelectCallback, - this.getRerollCost(globalScene.lockModifierTiers), - ), - ); - }); - return false; - } - let modifierType: ModifierType; - let cost: number; - const rerollCost = this.getRerollCost(globalScene.lockModifierTiers); - switch (rowCursor) { - case 0: - switch (cursor) { - case 0: - if (rerollCost < 0 || globalScene.money < rerollCost) { - globalScene.ui.playError(); - return false; - } - globalScene.reroll = true; - globalScene.unshiftPhase( - new SelectModifierPhase( - this.rerollCount + 1, - this.typeOptions.map(o => o.type?.tier).filter(t => t !== undefined) as ModifierTier[], - ), - ); - globalScene.ui.clearText(); - globalScene.ui.setMode(UiMode.MESSAGE).then(() => super.end()); - if (!Overrides.WAIVE_ROLL_FEE_OVERRIDE) { - globalScene.money -= rerollCost; - globalScene.updateMoneyText(); - globalScene.animateMoneyChanged(false); - } - globalScene.playSound("se/buy"); - break; - case 1: - globalScene.ui.setModeWithoutClear( - UiMode.PARTY, - PartyUiMode.MODIFIER_TRANSFER, - -1, - (fromSlotIndex: number, itemIndex: number, itemQuantity: number, toSlotIndex: number) => { - if ( - toSlotIndex !== undefined && - fromSlotIndex < 6 && - toSlotIndex < 6 && - fromSlotIndex !== toSlotIndex && - itemIndex > -1 - ) { - const itemModifiers = globalScene.findModifiers( - m => - m instanceof PokemonHeldItemModifier && - m.isTransferable && - m.pokemonId === party[fromSlotIndex].id, - ) as PokemonHeldItemModifier[]; - const itemModifier = itemModifiers[itemIndex]; - globalScene.tryTransferHeldItemModifier( - itemModifier, - party[toSlotIndex], - true, - itemQuantity, - undefined, - undefined, - false, - ); - } else { - globalScene.ui.setMode( - UiMode.MODIFIER_SELECT, - this.isPlayer(), - this.typeOptions, - modifierSelectCallback, - this.getRerollCost(globalScene.lockModifierTiers), - ); - } - }, - PartyUiHandler.FilterItemMaxStacks, - ); - break; - case 2: - globalScene.ui.setModeWithoutClear(UiMode.PARTY, PartyUiMode.CHECK, -1, () => { - globalScene.ui.setMode( - UiMode.MODIFIER_SELECT, - this.isPlayer(), - this.typeOptions, - modifierSelectCallback, - this.getRerollCost(globalScene.lockModifierTiers), - ); - }); - break; - case 3: - if (rerollCost < 0) { - // Reroll lock button is also disabled when reroll is disabled - globalScene.ui.playError(); - return false; - } - globalScene.lockModifierTiers = !globalScene.lockModifierTiers; - const uiHandler = globalScene.ui.getHandler() as ModifierSelectUiHandler; - uiHandler.setRerollCost(this.getRerollCost(globalScene.lockModifierTiers)); - uiHandler.updateLockRaritiesText(); - uiHandler.updateRerollCostText(); - return false; - } - return true; - case 1: - if (this.typeOptions.length === 0) { - globalScene.ui.clearText(); - globalScene.ui.setMode(UiMode.MESSAGE); - super.end(); - return true; - } - if (this.typeOptions[cursor].type) { - modifierType = this.typeOptions[cursor].type; - } - break; - default: - const shopOptions = getPlayerShopModifierTypeOptionsForWave( - globalScene.currentBattle.waveIndex, - globalScene.getWaveMoneyAmount(1), - ); - const shopOption = - shopOptions[ - rowCursor > 2 || shopOptions.length <= SHOP_OPTIONS_ROW_LIMIT ? cursor : cursor + SHOP_OPTIONS_ROW_LIMIT - ]; - if (shopOption.type) { - modifierType = shopOption.type; - } - // Apply Black Sludge to healing item cost - const healingItemCost = new NumberHolder(shopOption.cost); - globalScene.applyModifier(HealShopCostModifier, true, healingItemCost); - cost = healingItemCost.value; - break; - } - - if (cost! && globalScene.money < cost && !Overrides.WAIVE_ROLL_FEE_OVERRIDE) { - // TODO: is the bang on cost correct? - globalScene.ui.playError(); - return false; - } - - const applyModifier = (modifier: Modifier, playSound = false) => { - const result = globalScene.addModifier(modifier, false, playSound, undefined, undefined, cost); - // Queue a copy of this phase when applying a TM or Memory Mushroom. - // If the player selects either of these, then escapes out of consuming them, - // they are returned to a shop in the same state. - if (modifier.type instanceof RememberMoveModifierType || modifier.type instanceof TmModifierType) { - globalScene.unshiftPhase(this.copy()); - } - - if (cost && !(modifier.type instanceof RememberMoveModifierType)) { - if (result) { - if (!Overrides.WAIVE_ROLL_FEE_OVERRIDE) { - globalScene.money -= cost; - globalScene.updateMoneyText(); - globalScene.animateMoneyChanged(false); - } - globalScene.playSound("se/buy"); - (globalScene.ui.getHandler() as ModifierSelectUiHandler).updateCostText(); - } else { - globalScene.ui.playError(); - } - } else { - globalScene.ui.clearText(); - globalScene.ui.setMode(UiMode.MESSAGE); - super.end(); - } - }; - - if (modifierType! instanceof PokemonModifierType) { - //TODO: is the bang correct? - if (modifierType instanceof FusePokemonModifierType) { - globalScene.ui.setModeWithoutClear( - UiMode.PARTY, - PartyUiMode.SPLICE, - -1, - (fromSlotIndex: number, spliceSlotIndex: number) => { - if ( - spliceSlotIndex !== undefined && - fromSlotIndex < 6 && - spliceSlotIndex < 6 && - fromSlotIndex !== spliceSlotIndex - ) { - globalScene.ui.setMode(UiMode.MODIFIER_SELECT, this.isPlayer()).then(() => { - const modifier = modifierType.newModifier(party[fromSlotIndex], party[spliceSlotIndex])!; //TODO: is the bang correct? - applyModifier(modifier, true); - }); - } else { - globalScene.ui.setMode( - UiMode.MODIFIER_SELECT, - this.isPlayer(), - this.typeOptions, - modifierSelectCallback, - this.getRerollCost(globalScene.lockModifierTiers), - ); - } - }, - modifierType.selectFilter, - ); - } else { - const pokemonModifierType = modifierType as PokemonModifierType; - const isMoveModifier = modifierType instanceof PokemonMoveModifierType; - const isTmModifier = modifierType instanceof TmModifierType; - const isRememberMoveModifier = modifierType instanceof RememberMoveModifierType; - const isPpRestoreModifier = - modifierType instanceof PokemonPpRestoreModifierType || modifierType instanceof PokemonPpUpModifierType; - const partyUiMode = isMoveModifier - ? PartyUiMode.MOVE_MODIFIER - : isTmModifier - ? PartyUiMode.TM_MODIFIER - : isRememberMoveModifier - ? PartyUiMode.REMEMBER_MOVE_MODIFIER - : PartyUiMode.MODIFIER; - const tmMoveId = isTmModifier ? (modifierType as TmModifierType).moveId : undefined; - globalScene.ui.setModeWithoutClear( - UiMode.PARTY, - partyUiMode, - -1, - (slotIndex: number, option: PartyOption) => { - if (slotIndex < 6) { - globalScene.ui.setMode(UiMode.MODIFIER_SELECT, this.isPlayer()).then(() => { - const modifier = !isMoveModifier - ? !isRememberMoveModifier - ? modifierType.newModifier(party[slotIndex]) - : modifierType.newModifier(party[slotIndex], option as number) - : modifierType.newModifier(party[slotIndex], option - PartyOption.MOVE_1); - applyModifier(modifier!, true); // TODO: is the bang correct? - }); - } else { - globalScene.ui.setMode( - UiMode.MODIFIER_SELECT, - this.isPlayer(), - this.typeOptions, - modifierSelectCallback, - this.getRerollCost(globalScene.lockModifierTiers), - ); - } - }, - pokemonModifierType.selectFilter, - modifierType instanceof PokemonMoveModifierType - ? (modifierType as PokemonMoveModifierType).moveSelectFilter - : undefined, - tmMoveId, - isPpRestoreModifier, - ); - } - } else { - applyModifier(modifierType!.newModifier()!); // TODO: is the bang correct? - } - - return !cost!; // TODO: is the bang correct? - }; + private resetModifierSelect(modifierSelectCallback) { globalScene.ui.setMode( UiMode.MODIFIER_SELECT, this.isPlayer(),