From ac456fc5baf110ea2b7dbe15f816d4f769892ac8 Mon Sep 17 00:00:00 2001 From: Flashfyre Date: Sun, 4 Feb 2024 00:30:19 -0500 Subject: [PATCH] Add item shop when choosing items Add item shop when choosing items; add full restore item; add egg art to egg gacha; fix some minor text errors --- public/images/egg/gacha_eggs.png | Bin 0 -> 6471 bytes src/battle-phases.ts | 130 ++++++---- src/battle-scene.ts | 3 +- src/battle.ts | 1 - src/modifier/modifier-type.ts | 70 +++++- src/modifier/modifier.ts | 8 +- src/ui/egg-gacha-ui-handler.ts | 4 + src/ui/modifier-select-ui-handler.ts | 348 ++++++++++++++++++--------- 8 files changed, 378 insertions(+), 186 deletions(-) create mode 100644 public/images/egg/gacha_eggs.png diff --git a/public/images/egg/gacha_eggs.png b/public/images/egg/gacha_eggs.png new file mode 100644 index 0000000000000000000000000000000000000000..6e26addc4502cb8b499d10a613847eeaccb20d2a GIT binary patch literal 6471 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 { - if (cursor < 0) { + const modifierSelectCallback = (rowCursor: integer, cursor: integer) => { + if (rowCursor < 0 || cursor < 0) { this.scene.ui.setMode(Mode.MESSAGE); super.end(); return true; - } else if (cursor === typeOptions.length) { - const rerollCost = this.getRerollCost(); - if (this.scene.money < rerollCost) { - this.scene.ui.playError(); - return false; - } else { - this.scene.unshiftPhase(new SelectModifierPhase(this.scene, this.rerollCount + 1)); - this.scene.ui.clearText(); - this.scene.ui.setMode(Mode.MESSAGE).then(() => super.end()); - this.scene.money -= rerollCost; - this.scene.updateMoneyText(); - this.scene.playSound('buy'); - } - return true; - } else if (cursor === typeOptions.length + 1) { - this.scene.ui.setModeWithoutClear(Mode.PARTY, PartyUiMode.MODIFIER_TRANSFER, -1, (fromSlotIndex: integer, itemIndex: integer, toSlotIndex: integer) => { - if (toSlotIndex !== undefined && fromSlotIndex < 6 && toSlotIndex < 6 && fromSlotIndex !== toSlotIndex && itemIndex > -1) { - this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer()).then(() => { - const itemModifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier - && (m as PokemonHeldItemModifier).getTransferrable(true) && (m as PokemonHeldItemModifier).pokemonId === party[fromSlotIndex].id) as PokemonHeldItemModifier[]; - const itemModifier = itemModifiers[itemIndex]; - this.scene.tryTransferHeldItemModifier(itemModifier, party[toSlotIndex], true, true).then(success => { - if (success) { - this.scene.ui.clearText(); - this.scene.ui.setMode(Mode.MESSAGE); - super.end(); - } else - this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost()); - }); - }); - } else - this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost()); - }, PartyUiHandler.FilterItemMaxStacks); - return true; + } + let modifierType: ModifierType; + let cost: integer; + switch (rowCursor) { + case 0: + if (!cursor) { + const rerollCost = this.getRerollCost(); + if (this.scene.money < rerollCost) { + this.scene.ui.playError(); + return false; + } else { + this.scene.unshiftPhase(new SelectModifierPhase(this.scene, this.rerollCount + 1)); + this.scene.ui.clearText(); + this.scene.ui.setMode(Mode.MESSAGE).then(() => super.end()); + this.scene.money -= rerollCost; + this.scene.updateMoneyText(); + this.scene.playSound('buy'); + } + } else { + this.scene.ui.setModeWithoutClear(Mode.PARTY, PartyUiMode.MODIFIER_TRANSFER, -1, (fromSlotIndex: integer, itemIndex: integer, toSlotIndex: integer) => { + if (toSlotIndex !== undefined && fromSlotIndex < 6 && toSlotIndex < 6 && fromSlotIndex !== toSlotIndex && itemIndex > -1) { + this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer()).then(() => { + const itemModifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier + && (m as PokemonHeldItemModifier).getTransferrable(true) && (m as PokemonHeldItemModifier).pokemonId === party[fromSlotIndex].id) as PokemonHeldItemModifier[]; + const itemModifier = itemModifiers[itemIndex]; + this.scene.tryTransferHeldItemModifier(itemModifier, party[toSlotIndex], true, true).then(success => { + if (success) { + this.scene.ui.clearText(); + this.scene.ui.setMode(Mode.MESSAGE); + super.end(); + } else + this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost()); + }); + }); + } else + this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost()); + }, PartyUiHandler.FilterItemMaxStacks); + } + return true; + case 1: + modifierType = typeOptions[cursor].type; + break; + default: + const shopOptions = getPlayerShopModifierTypeOptionsForWave(this.scene.currentBattle.waveIndex, this.scene.getWaveMoneyAmount(1)); + const shopOption = shopOptions[rowCursor > 2 || shopOptions.length <= SHOP_OPTIONS_ROW_LIMIT ? cursor : cursor + SHOP_OPTIONS_ROW_LIMIT]; + modifierType = shopOption.type; + cost = shopOption.cost; + break; } - const modifierType = typeOptions[cursor].type; + if (cost && this.scene.money < cost) { + this.scene.ui.playError(); + return false; + } + + const applyModifier = (modifier: Modifier, playSound: boolean = false) => { + this.scene.addModifier(modifier, false, playSound).then(() => { + if (cost) { + this.scene.money -= cost; + this.scene.updateMoneyText(); + this.scene.playSound('buy'); + (this.scene.ui.getHandler() as ModifierSelectUiHandler).updateCostText(); + } else { + this.scene.ui.clearText(); + this.scene.ui.setMode(Mode.MESSAGE); + super.end(); + } + }); + }; + if (modifierType instanceof PokemonModifierType) { if (modifierType instanceof FusePokemonModifierType) { this.scene.ui.setModeWithoutClear(Mode.PARTY, PartyUiMode.SPLICE, -1, (fromSlotIndex: integer, spliceSlotIndex: integer) => { if (spliceSlotIndex !== undefined && fromSlotIndex < 6 && spliceSlotIndex < 6 && fromSlotIndex !== spliceSlotIndex) { this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer()).then(() => { const modifier = modifierType.newModifier(party[fromSlotIndex], party[spliceSlotIndex]); - this.scene.ui.clearText(); - this.scene.ui.setMode(Mode.MESSAGE); - this.scene.addModifier(modifier, false, true).then(() => super.end()); + applyModifier(modifier, true); }); } else this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost()); @@ -3534,27 +3566,21 @@ export class SelectModifierPhase extends BattlePhase { this.scene.ui.setModeWithoutClear(Mode.PARTY, partyUiMode, -1, (slotIndex: integer, option: PartyOption) => { if (slotIndex < 6) { this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer()).then(() => { - const modifierType = typeOptions[cursor].type; const modifier = !isMoveModifier ? !isRememberMoveModifier ? modifierType.newModifier(party[slotIndex]) : modifierType.newModifier(party[slotIndex], option as integer) : modifierType.newModifier(party[slotIndex], option - PartyOption.MOVE_1); - this.scene.ui.clearText(); - this.scene.ui.setMode(Mode.MESSAGE); - this.scene.addModifier(modifier, false, true).then(() => super.end()); + applyModifier(modifier, true); }); } else this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost()); }, pokemonModifierType.selectFilter, modifierType instanceof PokemonMoveModifierType ? (modifierType as PokemonMoveModifierType).moveSelectFilter : undefined, tmMoveId); } - } else { - this.addModifier(typeOptions[cursor].type.newModifier()).then(() => super.end()); - this.scene.ui.clearText(); - this.scene.ui.setMode(Mode.MESSAGE); - } + } else + applyModifier(typeOptions[cursor].type.newModifier()); - return true; + return !cost; }; this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost()); } diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 63082887088..d83a3234ace 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -336,6 +336,7 @@ export default class BattleScene extends Phaser.Scene { this.loadAtlas(`gacha_underlay_${key}`, 'egg'); }); this.loadImage('gacha_glass', 'egg'); + this.loadImage('gacha_eggs', 'egg'); this.loadAtlas('gacha_hatch', 'egg'); this.loadImage('gacha_knob', 'egg'); @@ -1437,7 +1438,7 @@ export default class BattleScene extends Phaser.Scene { this.phaseQueue.push(new TurnInitPhase(this)); } - getMoneyAmountForWave(moneyMultiplier: number): integer { + getWaveMoneyAmount(moneyMultiplier: number): integer { const waveIndex = this.currentBattle.waveIndex; const waveSetIndex = Math.ceil(waveIndex / 10) - 1; const moneyValue = Math.pow((waveSetIndex + 1 + (0.75 + (((waveIndex - 1) % 10) + 1) / 10)) * 100, 1 + 0.005 * waveSetIndex) * moneyMultiplier; diff --git a/src/battle.ts b/src/battle.ts index b00f26e3b6e..59cb760120f 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -212,7 +212,6 @@ export class FixedBattleConfig { function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[]): GetTrainerFunc { return (scene: BattleScene) => { const rand = Utils.randSeedInt(trainerPool.length); - console.log(rand); const trainerTypes: TrainerType[] = []; for (let trainerPoolEntry of trainerPool) { const trainerType = Array.isArray(trainerPoolEntry) diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 3eb971ab542..81a80a8f439 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -132,24 +132,26 @@ export class PokemonHeldItemModifierType extends PokemonModifierType { export class PokemonHpRestoreModifierType extends PokemonModifierType { protected restorePoints: integer; protected restorePercent: integer; + protected healStatus: boolean; - constructor(name: string, restorePoints: integer, restorePercent: integer, newModifierFunc?: NewModifierFunc, selectFilter?: PokemonSelectFilter, iconImage?: string, group?: string) { - super(name, restorePoints ? `Restore ${restorePoints} HP or ${restorePercent}% HP for one Pokémon, whichever is higher` : `Restore ${restorePercent}% HP for one Pokémon`, - newModifierFunc || ((_type, args) => new Modifiers.PokemonHpRestoreModifier(this, (args[0] as PlayerPokemon).id, this.restorePoints, this.restorePercent, false)), + constructor(name: string, restorePoints: integer, restorePercent: integer, healStatus: boolean = false, newModifierFunc?: NewModifierFunc, selectFilter?: PokemonSelectFilter, iconImage?: string, group?: string) { + super(name, restorePoints ? `Restore ${restorePoints} HP or ${restorePercent}% HP for one Pokémon, whichever is higher` : `Fully restores HP for one Pokémon${healStatus ? ' and heals any status ailment ' : ''}`, + newModifierFunc || ((_type, args) => new Modifiers.PokemonHpRestoreModifier(this, (args[0] as PlayerPokemon).id, this.restorePoints, this.restorePercent, this.healStatus, false)), selectFilter || ((pokemon: PlayerPokemon) => { - if (!pokemon.hp || pokemon.hp >= pokemon.getMaxHp()) + if (!pokemon.hp || (pokemon.hp >= pokemon.getMaxHp() && (!this.healStatus || !pokemon.status))) return PartyUiHandler.NoEffectMessage; return null; }), iconImage, group || 'potion'); this.restorePoints = restorePoints; this.restorePercent = restorePercent; + this.healStatus = healStatus; } } export class PokemonReviveModifierType extends PokemonHpRestoreModifierType { constructor(name: string, restorePercent: integer, iconImage?: string) { - super(name, 0, restorePercent, (_type, args) => new Modifiers.PokemonHpRestoreModifier(this, (args[0] as PlayerPokemon).id, 0, this.restorePercent, true), + super(name, 0, restorePercent, false, (_type, args) => new Modifiers.PokemonHpRestoreModifier(this, (args[0] as PlayerPokemon).id, 0, this.restorePercent, false, true), ((pokemon: PlayerPokemon) => { if (!pokemon.isFainted()) return PartyUiHandler.NoEffectMessage; @@ -367,7 +369,7 @@ export class AllPokemonLevelIncrementModifierType extends ModifierType { function getBaseStatBoosterItemName(stat: Stat) { switch (stat) { case Stat.HP: - return 'Hp-Up'; + return 'HP Up'; case Stat.ATK: return 'Protein'; case Stat.DEF: @@ -397,13 +399,13 @@ export class PokemonBaseStatBoosterModifierType extends PokemonHeldItemModifierT class AllPokemonFullHpRestoreModifierType extends ModifierType { constructor(name: string, description?: string, newModifierFunc?: NewModifierFunc, iconImage?: string) { - super(name, description || `Restore 100% HP for all Pokémon`, newModifierFunc || ((_type, _args) => new Modifiers.PokemonHpRestoreModifier(this, -1, 0, 100)), iconImage); + super(name, description || `Restore 100% HP for all Pokémon`, newModifierFunc || ((_type, _args) => new Modifiers.PokemonHpRestoreModifier(this, -1, 0, 100, false)), iconImage); } } class AllPokemonFullReviveModifierType extends AllPokemonFullHpRestoreModifierType { constructor(name: string, iconImage?: string) { - super(name, `Revives all fainted Pokémon, restoring 100% HP`, (_type, _args) => new Modifiers.PokemonHpRestoreModifier(this, -1, 0, 100, true), iconImage); + super(name, `Revives all fainted Pokémon, fully restoring HP`, (_type, _args) => new Modifiers.PokemonHpRestoreModifier(this, -1, 0, 100, false, true), iconImage); } } @@ -417,7 +419,7 @@ export class MoneyRewardModifierType extends ModifierType { } getDescription(scene: BattleScene): string { - return this.description.replace('{AMOUNT}', scene.getMoneyAmountForWave(this.moneyMultiplier).toLocaleString('en-US')); + return this.description.replace('{AMOUNT}', scene.getWaveMoneyAmount(this.moneyMultiplier).toLocaleString('en-US')); } } @@ -673,7 +675,8 @@ export const modifierTypes = { POTION: () => new PokemonHpRestoreModifierType('Potion', 20, 10), SUPER_POTION: () => new PokemonHpRestoreModifierType('Super Potion', 50, 25), HYPER_POTION: () => new PokemonHpRestoreModifierType('Hyper Potion', 200, 50), - MAX_POTION: () => new PokemonHpRestoreModifierType('Max Potion', 100, 100), + MAX_POTION: () => new PokemonHpRestoreModifierType('Max Potion', 0, 100), + FULL_RESTORE: () => new PokemonHpRestoreModifierType('Full Restore', 0, 100, true), REVIVE: () => new PokemonReviveModifierType('Revive', 50), MAX_REVIVE: () => new PokemonReviveModifierType('Max Revive', 100), @@ -768,7 +771,7 @@ export const modifierTypes = { HEALING_CHARM: () => new ModifierType('Healing Charm', 'Increases the effectiveness of HP restoring moves and items by 25% (excludes revives)', (type, _args) => new Modifiers.HealingBoosterModifier(type, 1.25), 'healing_charm'), - CANDY_JAR: () => new ModifierType('Candy Jar', 'Increases the number of levels added by RARE CANDY items by 1', (type, _args) => new Modifiers.LevelIncrementBoosterModifier(type)), + CANDY_JAR: () => new ModifierType('Candy Jar', 'Increases the number of levels added by Rare Candy items by 1', (type, _args) => new Modifiers.LevelIncrementBoosterModifier(type)), BERRY_POUCH: () => new ModifierType('Berry Pouch', 'Adds a 25% chance that a used berry will not be consumed', (type, _args) => new Modifiers.PreserveBerryModifier(type)), @@ -869,6 +872,11 @@ const modifierPool = { const thresholdPartyMemberCount = Math.min(party.filter(p => p.getInverseHp() >= 150 || p.getHpRatio() <= 0.5).length, 3); return thresholdPartyMemberCount; }), + new WeightedModifierType(modifierTypes.FULL_RESTORE, (party: Pokemon[]) => { + const statusEffectPartyMemberCount = Math.min(party.filter(p => p.hp && !!p.status).length, 3); + const thresholdPartyMemberCount = Math.floor((Math.min(party.filter(p => p.getInverseHp() >= 150 || p.getHpRatio() <= 0.5).length, 3) + statusEffectPartyMemberCount) / 2); + return thresholdPartyMemberCount; + }), new WeightedModifierType(modifierTypes.ELIXIR, (party: Pokemon[]) => { const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && p.getMoveset().filter(m => (m.getMove().pp - m.ppUsed) <= 5).length).length, 3); return thresholdPartyMemberCount * 3; @@ -1085,6 +1093,42 @@ export function getPlayerModifierTypeOptionsForWave(waveIndex: integer, count: i return options; } +export function getPlayerShopModifierTypeOptionsForWave(waveIndex: integer, baseCost: integer): ModifierTypeOption[] { + if (!(waveIndex % 10)) + return []; + + const options = [ + [ + new ModifierTypeOption(modifierTypes.POTION(), false, baseCost * 0.1), + new ModifierTypeOption(modifierTypes.ETHER(), false, baseCost * 0.2), + new ModifierTypeOption(modifierTypes.REVIVE(), false, baseCost) + ], + [ + new ModifierTypeOption(modifierTypes.SUPER_POTION(), false, baseCost * 0.225), + new ModifierTypeOption(modifierTypes.ELIXIR(), false, baseCost * 0.5) + ], + [ + new ModifierTypeOption(modifierTypes.FULL_HEAL(), false, baseCost * 0.5), + new ModifierTypeOption(modifierTypes.MAX_ETHER(), false, baseCost * 0.5) + ], + [ + new ModifierTypeOption(modifierTypes.HYPER_POTION(), false, baseCost * 0.4), + new ModifierTypeOption(modifierTypes.MAX_REVIVE(), false, baseCost * 1.375) + ], + [ + new ModifierTypeOption(modifierTypes.MAX_POTION(), false, baseCost * 0.75), + new ModifierTypeOption(modifierTypes.MAX_ELIXIR(), false, baseCost * 1.25) + ], + [ + new ModifierTypeOption(modifierTypes.FULL_RESTORE(), false, baseCost * 1.125) + ], + [ + new ModifierTypeOption(modifierTypes.SACRED_ASH(), false, baseCost * 6) + ] + ]; + return options.slice(0, Math.ceil(Math.max(waveIndex + 10, 0) / 30)).flat(); +} + export function getEnemyBuffModifierForWave(tier: ModifierTier, enemyModifiers: Modifiers.PersistentModifier[], scene: BattleScene): Modifiers.EnemyPersistentModifier { const tierStackCount = tier === ModifierTier.ULTRA ? 10 : tier === ModifierTier.GREAT ? 5 : 1; const retryCount = 50; @@ -1163,9 +1207,11 @@ export function getDefaultModifierTypeForTier(tier: ModifierTier): ModifierType export class ModifierTypeOption { public type: ModifierType; public upgraded: boolean; + public cost: integer; - constructor(type: ModifierType, upgraded: boolean) { + constructor(type: ModifierType, upgraded: boolean, cost: number = 0) { this.type = type; this.upgraded = upgraded; + this.cost = Math.round(cost); } } \ No newline at end of file diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index ea8f057a371..204c13bc589 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -836,13 +836,15 @@ export abstract class ConsumablePokemonModifier extends ConsumableModifier { export class PokemonHpRestoreModifier extends ConsumablePokemonModifier { private restorePoints: integer; private restorePercent: number; + private healStatus: boolean; public fainted: boolean; - constructor(type: ModifierType, pokemonId: integer, restorePoints: integer, restorePercent: number, fainted?: boolean) { + constructor(type: ModifierType, pokemonId: integer, restorePoints: integer, restorePercent: number, healStatus: boolean, fainted?: boolean) { super(type, pokemonId); this.restorePoints = restorePoints; this.restorePercent = restorePercent; + this.healStatus = healStatus; this.fainted = !!fainted; } @@ -856,7 +858,7 @@ export class PokemonHpRestoreModifier extends ConsumablePokemonModifier { let restorePoints = this.restorePoints; if (!this.fainted) restorePoints = Math.floor(restorePoints * (args[1] as number)); - else + if (this.fainted || this.healStatus) pokemon.resetStatus(); pokemon.hp = Math.min(pokemon.hp + Math.max(Math.ceil(Math.max(Math.floor((this.restorePercent * 0.01) * pokemon.getMaxHp()), restorePoints)), 1), pokemon.getMaxHp()); } @@ -1323,7 +1325,7 @@ export class MoneyRewardModifier extends ConsumableModifier { apply(args: any[]): boolean { const scene = args[0] as BattleScene; - const moneyAmount = new Utils.IntegerHolder(scene.getMoneyAmountForWave(this.moneyMultiplier)); + const moneyAmount = new Utils.IntegerHolder(scene.getWaveMoneyAmount(this.moneyMultiplier)); scene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount); diff --git a/src/ui/egg-gacha-ui-handler.ts b/src/ui/egg-gacha-ui-handler.ts index 1f15bb180fe..71f80241940 100644 --- a/src/ui/egg-gacha-ui-handler.ts +++ b/src/ui/egg-gacha-ui-handler.ts @@ -80,6 +80,9 @@ export default class EggGachaUiHandler extends MessageUiHandler { const gachaUnderlay = this.scene.add.sprite(115, 80, `gacha_underlay_${gachaTypeKey}`); gachaUnderlay.setOrigin(0, 0); + const gachaEggs = this.scene.add.sprite(0, 0, 'gacha_eggs'); + gachaEggs.setOrigin(0, 0); + const gachaGlass = this.scene.add.sprite(0, 0, 'gacha_glass'); gachaGlass.setOrigin(0, 0); @@ -118,6 +121,7 @@ export default class EggGachaUiHandler extends MessageUiHandler { const gachaHatch = this.scene.add.sprite(115, 73, 'gacha_hatch'); gachaHatch.setOrigin(0, 0); + gachaContainer.add(gachaEggs); gachaContainer.add(gachaUnderlay); gachaContainer.add(gacha); gachaContainer.add(gachaGlass); diff --git a/src/ui/modifier-select-ui-handler.ts b/src/ui/modifier-select-ui-handler.ts index b84543f4938..7555b24fc39 100644 --- a/src/ui/modifier-select-ui-handler.ts +++ b/src/ui/modifier-select-ui-handler.ts @@ -1,21 +1,25 @@ import BattleScene, { Button } from "../battle-scene"; -import { ModifierTypeOption } from "../modifier/modifier-type"; +import { getPlayerShopModifierTypeOptionsForWave, ModifierTypeOption } from "../modifier/modifier-type"; import { getPokeballAtlasKey, PokeballType } from "../data/pokeball"; import { addTextObject, getModifierTierTextTint, getTextColor, TextStyle } from "./text"; import AwaitableUiHandler from "./awaitable-ui-handler"; import { Mode } from "./ui"; import { PokemonHeldItemModifier } from "../modifier/modifier"; +export const SHOP_OPTIONS_ROW_LIMIT = 6; + export default class ModifierSelectUiHandler extends AwaitableUiHandler { private modifierContainer: Phaser.GameObjects.Container; private rerollButtonContainer: Phaser.GameObjects.Container; private transferButtonContainer: Phaser.GameObjects.Container; private rerollCostText: Phaser.GameObjects.Text; - private lastCursor: integer = 0; + private rowCursor: integer = 0; private player: boolean; + private rerollCost: integer; public options: ModifierOption[]; + public shopOptionsRows: ModifierOption[][]; private cursorObj: Phaser.GameObjects.Image; @@ -23,6 +27,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { super(scene, Mode.CONFIRM); this.options = []; + this.shopOptionsRows = []; } setup() { @@ -79,18 +84,38 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { this.rerollButtonContainer.setVisible(false); this.rerollButtonContainer.setAlpha(0); - this.updateRerollCostText(args[3] as integer); + this.rerollCost = args[3] as integer; + + this.updateRerollCostText(); const typeOptions = args[1] as ModifierTypeOption[]; + const shopTypeOptions = getPlayerShopModifierTypeOptionsForWave(this.scene.currentBattle.waveIndex, this.scene.getWaveMoneyAmount(1)); + const optionsYOffset = shopTypeOptions.length >= SHOP_OPTIONS_ROW_LIMIT ? -8 : -24; + for (let m = 0; m < typeOptions.length; m++) { const sliceWidth = (this.scene.game.canvas.width / 6) / (typeOptions.length + 2); - const option = new ModifierOption(this.scene, sliceWidth * (m + 1) + (sliceWidth * 0.5), -this.scene.game.canvas.height / 12 - 24, typeOptions[m]); + const option = new ModifierOption(this.scene, sliceWidth * (m + 1) + (sliceWidth * 0.5), -this.scene.game.canvas.height / 12 + optionsYOffset, typeOptions[m]); option.setScale(0.5); this.scene.add.existing(option); this.modifierContainer.add(option); this.options.push(option); } + for (let m = 0; m < shopTypeOptions.length; m++) { + const row = m < SHOP_OPTIONS_ROW_LIMIT ? 0 : 1; + const col = m < SHOP_OPTIONS_ROW_LIMIT ? m : m - SHOP_OPTIONS_ROW_LIMIT; + const rowOptions = shopTypeOptions.slice(row ? SHOP_OPTIONS_ROW_LIMIT : 0, row ? undefined : SHOP_OPTIONS_ROW_LIMIT); + const sliceWidth = (this.scene.game.canvas.width / SHOP_OPTIONS_ROW_LIMIT) / (rowOptions.length + 2); + const option = new ModifierOption(this.scene, sliceWidth * (col + 1) + (sliceWidth * 0.5), ((-this.scene.game.canvas.height / 12) - (this.scene.game.canvas.height / 32) - (40 - (28 * row - 1))), shopTypeOptions[m]); + option.setScale(0.375); + this.scene.add.existing(option); + this.modifierContainer.add(option); + + if (row >= this.shopOptionsRows.length) + this.shopOptionsRows.push([]); + this.shopOptionsRows[row].push(option); + } + const hasUpgrade = typeOptions.filter(to => to.upgraded).length; this.scene.showFieldOverlay(750); @@ -110,6 +135,11 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { } }); + this.scene.time.delayedCall(1000 + (hasUpgrade ? 2000 : 0), () => { + for (let shopOption of this.shopOptionsRows.flat()) + shopOption.show(0); + }); + this.scene.time.delayedCall(4000 + (hasUpgrade ? 2000 : 0), () => { if (partyHasHeldItem) { this.transferButtonContainer.setAlpha(0); @@ -132,6 +162,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { } this.setCursor(0); + this.setRowCursor(1); this.awaitingActionInput = true; this.onActionInput = args[2]; }); @@ -153,7 +184,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { const originalOnActionInput = this.onActionInput; this.awaitingActionInput = false; this.onActionInput = null; - if (!originalOnActionInput(this.cursor)) { + if (!originalOnActionInput(this.rowCursor, this.cursor)) { this.awaitingActionInput = true; this.onActionInput = originalOnActionInput; } @@ -171,24 +202,28 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { } else { switch (button) { case Button.UP: - if (this.cursor >= this.options.length) - success = this.setCursor(this.lastCursor < this.options.length ? this.lastCursor : this.cursor - this.options.length ? this.options.length - 1 : 0); + if (this.rowCursor < this.shopOptionsRows.length + 1) + success = this.setRowCursor(this.rowCursor + 1); break; case Button.DOWN: - if (this.cursor < this.options.length && (this.rerollButtonContainer.visible || this.transferButtonContainer.visible)) { - const isLeftOption = this.cursor <= Math.floor(this.options.length / 2); - success = this.setCursor(this.options.length + (this.rerollButtonContainer.visible && (isLeftOption || !this.transferButtonContainer.visible) ? 0 : 1)); - } + if (this.rowCursor) + success = this.setRowCursor(this.rowCursor - 1); break; case Button.LEFT: - if ((this.cursor || this.rerollButtonContainer.visible) && this.cursor !== this.options.length) - success = this.setCursor(this.cursor ? this.cursor - 1 : this.options.length); + if (!this.rowCursor) + success = this.rerollButtonContainer.visible && this.setCursor(0); + else if (this.cursor) + success = this.setCursor(this.cursor - 1); + else if (this.rowCursor === 1 && this.rerollButtonContainer.visible) + success = this.setRowCursor(0); break; case Button.RIGHT: - if (this.cursor < this.options.length - 1) + if (!this.rowCursor) + success = this.transferButtonContainer.visible && this.setCursor(1); + else if (this.cursor < this.getRowItems(this.rowCursor) - 1) success = this.setCursor(this.cursor + 1); - else if (this.cursor === this.options.length && this.transferButtonContainer.visible) - success = this.setCursor(this.options.length + 1); + else if (this.rowCursor === 1 && this.transferButtonContainer.visible) + success = this.setRowCursor(0); break; } } @@ -200,26 +235,26 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { } setCursor(cursor: integer): boolean { - const lastCursor = this.cursor; - const ui = this.getUi(); const ret = super.setCursor(cursor); - if (ret) - this.lastCursor = lastCursor; - if (!this.cursorObj) { this.cursorObj = this.scene.add.image(0, 0, 'cursor'); this.modifierContainer.add(this.cursorObj); } - this.cursorObj.setScale(cursor < this.options.length ? 2 : 1); + const options = (this.rowCursor === 1 ? this.options : this.shopOptionsRows[this.shopOptionsRows.length - (this.rowCursor - 1)]); - if (cursor < this.options.length) { - const sliceWidth = (this.scene.game.canvas.width / 6) / (this.options.length + 2); - this.cursorObj.setPosition(sliceWidth * (cursor + 1) + (sliceWidth * 0.5) - 20, -this.scene.game.canvas.height / 12 - 20); - ui.showText(this.options[this.cursor].modifierTypeOption.type.getDescription(this.scene)); - } else if (cursor === this.options.length) { + this.cursorObj.setScale(this.rowCursor === 1 ? 2 : this.rowCursor >= 2 ? 1.5 : 1); + + if (this.rowCursor) { + let sliceWidth = (this.scene.game.canvas.width / 6) / (options.length + 2); + if (this.rowCursor < 2) + this.cursorObj.setPosition(sliceWidth * (cursor + 1) + (sliceWidth * 0.5) - 20, (-this.scene.game.canvas.height / 12) - (this.shopOptionsRows.length > 1 ? 6 : 22)); + else + this.cursorObj.setPosition(sliceWidth * (cursor + 1) + (sliceWidth * 0.5) - 16, (-this.scene.game.canvas.height / 12 - this.scene.game.canvas.height / 32) - (-16 + 28 * (this.rowCursor - (this.shopOptionsRows.length - 1)))); + ui.showText(options[this.cursor].modifierTypeOption.type.getDescription(this.scene)); + } else if (!cursor) { this.cursorObj.setPosition(6, -60); ui.showText('Spend money to reroll your item options'); } else { @@ -230,10 +265,49 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { return ret; } - updateRerollCostText(rerollCost: integer): void { - const canReroll = this.scene.money >= rerollCost; + setRowCursor(rowCursor: integer): boolean { + const lastRowCursor = this.rowCursor; - this.rerollCostText.setText(`₽${rerollCost.toLocaleString('en-US')}`); + if (rowCursor !== lastRowCursor && (rowCursor || this.rerollButtonContainer.visible || this.transferButtonContainer.visible)) { + this.rowCursor = rowCursor; + let newCursor = Math.round(this.cursor / Math.max(this.getRowItems(lastRowCursor) - 1, 1) * (this.getRowItems(rowCursor) - 1)); + if (!rowCursor) { + if (!newCursor && !this.rerollButtonContainer.visible) + newCursor = 1; + else if (newCursor && !this.transferButtonContainer.visible) + newCursor = 0; + } + this.cursor = -1; + this.setCursor(newCursor); + return true; + } + + return false; + } + + private getRowItems(rowCursor: integer): integer { + switch (rowCursor) { + case 0: + return 2; + case 1: + return this.options.length; + default: + return this.shopOptionsRows[this.shopOptionsRows.length - (rowCursor - 1)].length; + } + } + + updateCostText(): void { + const shopOptions = this.shopOptionsRows.flat(); + for (let shopOption of shopOptions) + shopOption.updateCostText(); + + this.updateRerollCostText(); + } + + updateRerollCostText(): void { + const canReroll = this.scene.money >= this.rerollCost; + + this.rerollCostText.setText(`₽${this.rerollCost.toLocaleString('en-US')}`); this.rerollCostText.setColor(getTextColor(canReroll ? TextStyle.MONEY : TextStyle.PARTY_RED)); this.rerollCostText.setShadowColor(getTextColor(canReroll ? TextStyle.MONEY : TextStyle.PARTY_RED, true)); } @@ -248,8 +322,9 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { this.scene.hideFieldOverlay(250); - const options = this.options.slice(0); + const options = this.options.concat(this.shopOptionsRows.flat()); this.options.splice(0, this.options.length); + this.shopOptionsRows.splice(0, this.shopOptionsRows.length); this.scene.tweens.add({ targets: options, @@ -292,6 +367,7 @@ class ModifierOption extends Phaser.GameObjects.Container { private item: Phaser.GameObjects.Sprite; private itemTint: Phaser.GameObjects.Sprite; private itemText: Phaser.GameObjects.Text; + private itemCostText: Phaser.GameObjects.Text; constructor(scene: BattleScene, x: number, y: number, modifierTypeOption: ModifierTypeOption) { super(scene, x, y); @@ -302,18 +378,20 @@ class ModifierOption extends Phaser.GameObjects.Container { } setup() { - const getPb = (): Phaser.GameObjects.Sprite => { - const pb = this.scene.add.sprite(0, -150, 'pb', this.getPbAtlasKey(true)); - pb.setScale(2); - return pb; - }; + if (!this.modifierTypeOption.cost) { + const getPb = (): Phaser.GameObjects.Sprite => { + const pb = this.scene.add.sprite(0, -182, 'pb', this.getPbAtlasKey(true)); + pb.setScale(2); + return pb; + }; - this.pb = getPb(); - this.add(this.pb); + this.pb = getPb(); + this.add(this.pb); - this.pbTint = getPb(); - this.pbTint.setVisible(false); - this.add(this.pbTint); + this.pbTint = getPb(); + this.pbTint.setVisible(false); + this.add(this.pbTint); + } this.itemContainer = this.scene.add.container(0, 0); this.itemContainer.setScale(0.5); @@ -328,90 +406,107 @@ class ModifierOption extends Phaser.GameObjects.Container { this.item = getItem(); this.itemContainer.add(this.item); - this.itemTint = getItem(); - this.itemTint.setTintFill(Phaser.Display.Color.GetColor(255, 192, 255)); - this.itemContainer.add(this.itemTint); + if (!this.modifierTypeOption.cost) { + this.itemTint = getItem(); + this.itemTint.setTintFill(Phaser.Display.Color.GetColor(255, 192, 255)); + this.itemContainer.add(this.itemTint); + } this.itemText = addTextObject(this.scene, 0, 35, this.modifierTypeOption.type.name, TextStyle.PARTY, { align: 'center' }); this.itemText.setOrigin(0.5, 0); this.itemText.setAlpha(0); this.itemText.setTint(getModifierTierTextTint(this.modifierTypeOption.type.tier)); this.add(this.itemText); + + if (this.modifierTypeOption.cost) { + this.itemCostText = addTextObject(this.scene, 0, 45, '', TextStyle.MONEY, { align: 'center' }); + + this.itemCostText.setOrigin(0.5, 0); + this.itemCostText.setAlpha(0); + this.add(this.itemCostText); + + this.updateCostText(); + } } show(remainingDuration: integer) { - this.scene.tweens.add({ - targets: this.pb, - y: 0, - duration: 1250, - ease: 'Bounce.Out' - }); - - let lastValue = 1; - let bounceCount = 0; - let bounce = false; - - this.scene.tweens.addCounter({ - from: 1, - to: 0, - duration: 1250, - ease: 'Bounce.Out', - onUpdate: t => { - if (!this.scene) - return; - const value = t.getValue(); - if (!bounce && value > lastValue) { - (this.scene as BattleScene).playSound('pb_bounce_1', { volume: 1 / ++bounceCount }); - bounce = true; - } else if (bounce && value < lastValue) - bounce = false; - lastValue = value; - } - }); - - if (this.modifierTypeOption.upgraded) { - this.scene.time.delayedCall(remainingDuration, () => { - (this.scene as BattleScene).playSound('upgrade'); - this.pbTint.setPosition(this.pb.x, this.pb.y); - this.pbTint.setTintFill(0xFFFFFF); - this.pbTint.setAlpha(0); - this.pbTint.setVisible(true); - this.scene.tweens.add({ - targets: this.pbTint, - alpha: 1, - duration: 1000, - ease: 'Sine.easeIn', - onComplete: () => { - this.pb.setTexture('pb', this.getPbAtlasKey(false)); - this.scene.tweens.add({ - targets: this.pbTint, - alpha: 0, - duration: 1000, - ease: 'Sine.easeOut', - onComplete: () => { - this.pbTint.setVisible(false); - } - }); - } - }); + if (!this.modifierTypeOption.cost) { + this.scene.tweens.add({ + targets: this.pb, + y: 0, + duration: 1250, + ease: 'Bounce.Out' }); + + let lastValue = 1; + let bounceCount = 0; + let bounce = false; + + this.scene.tweens.addCounter({ + from: 1, + to: 0, + duration: 1250, + ease: 'Bounce.Out', + onUpdate: t => { + if (!this.scene) + return; + const value = t.getValue(); + if (!bounce && value > lastValue) { + (this.scene as BattleScene).playSound('pb_bounce_1', { volume: 1 / ++bounceCount }); + bounce = true; + } else if (bounce && value < lastValue) + bounce = false; + lastValue = value; + } + }); + + if (this.modifierTypeOption.upgraded) { + this.scene.time.delayedCall(remainingDuration, () => { + (this.scene as BattleScene).playSound('upgrade'); + this.pbTint.setPosition(this.pb.x, this.pb.y); + this.pbTint.setTintFill(0xFFFFFF); + this.pbTint.setAlpha(0); + this.pbTint.setVisible(true); + this.scene.tweens.add({ + targets: this.pbTint, + alpha: 1, + duration: 1000, + ease: 'Sine.easeIn', + onComplete: () => { + this.pb.setTexture('pb', this.getPbAtlasKey(false)); + this.scene.tweens.add({ + targets: this.pbTint, + alpha: 0, + duration: 1000, + ease: 'Sine.easeOut', + onComplete: () => { + this.pbTint.setVisible(false); + } + }); + } + }); + }); + } } this.scene.time.delayedCall(remainingDuration + 2000, () => { if (!this.scene) return; - this.pb.setTexture('pb', `${this.getPbAtlasKey(false)}_open`); - (this.scene as BattleScene).playSound('pb_rel'); - - this.scene.tweens.add({ - targets: this.pb, - duration: 500, - delay: 250, - ease: 'Sine.easeIn', - alpha: 0, - onComplete: () => this.pb.destroy() - }) + if (!this.modifierTypeOption.cost) { + this.pb.setTexture('pb', `${this.getPbAtlasKey(false)}_open`); + (this.scene as BattleScene).playSound('pb_rel'); + + this.scene.tweens.add({ + targets: this.pb, + duration: 500, + delay: 250, + ease: 'Sine.easeIn', + alpha: 0, + onComplete: () => this.pb.destroy() + }); + } + this.scene.tweens.add({ targets: this.itemContainer, duration: 500, @@ -419,13 +514,15 @@ class ModifierOption extends Phaser.GameObjects.Container { scale: 2, alpha: 1 }); - this.scene.tweens.add({ - targets: this.itemTint, - alpha: 0, - duration: 500, - ease: 'Sine.easeIn', - onComplete: () => this.itemTint.destroy() - }); + if (!this.modifierTypeOption.cost) { + this.scene.tweens.add({ + targets: this.itemTint, + alpha: 0, + duration: 500, + ease: 'Sine.easeIn', + onComplete: () => this.itemTint.destroy() + }); + } this.scene.tweens.add({ targets: this.itemText, duration: 500, @@ -433,10 +530,27 @@ class ModifierOption extends Phaser.GameObjects.Container { y: 25, ease: 'Cubic.easeInOut' }); - }) + if (this.itemCostText) { + this.scene.tweens.add({ + targets: this.itemCostText, + duration: 500, + alpha: 1, + y: 35, + ease: 'Cubic.easeInOut' + }); + } + }); } getPbAtlasKey(beforeUpgrade: boolean) { return getPokeballAtlasKey((this.modifierTypeOption.type.tier - (beforeUpgrade && this.modifierTypeOption.upgraded ? 1 : 0)) as integer as PokeballType); } + + updateCostText(): void { + const textStyle = this.modifierTypeOption.cost <= (this.scene as BattleScene).money ? TextStyle.MONEY : TextStyle.PARTY_RED; + + this.itemCostText.setText(`₽${this.modifierTypeOption.cost.toLocaleString('en-US')}`); + this.itemCostText.setColor(getTextColor(textStyle)); + this.itemCostText.setShadowColor(getTextColor(textStyle, true)); + } } \ No newline at end of file