diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 767a735f2..6f5765c09 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -756,7 +756,7 @@ export default class BattleScene extends Phaser.Scene { } reset(clearScene?: boolean): void { - this.setSeed(Utils.randomString(16)); + this.setSeed(Utils.randomString(24)); console.log('Seed:', this.seed); this.gameMode = gameModes[GameModes.CLASSIC]; @@ -835,35 +835,9 @@ export default class BattleScene extends Phaser.Scene { } else { if (!this.gameMode.hasTrainers) newBattleType = BattleType.WILD; - else if (battleType === undefined) { - if ((newWaveIndex % 30) === 20 && !this.gameMode.isWaveFinal(newWaveIndex)) - newBattleType = BattleType.TRAINER; - else if (newWaveIndex % 10 !== 1 && newWaveIndex % 10) { - const trainerChance = this.arena.getTrainerChance(); - let allowTrainerBattle = true; - if (trainerChance) { - const waveBase = Math.floor(newWaveIndex / 10) * 10; - for (let w = Math.max(newWaveIndex - 3, waveBase + 2); w <= Math.min(newWaveIndex + 3, waveBase + 9); w++) { - if (w === newWaveIndex) - continue; - if ((w % 30) === 20 || fixedBattles.hasOwnProperty(w)) { - allowTrainerBattle = false; - break; - } else if (w < newWaveIndex) { - this.executeWithSeedOffset(() => { - const waveTrainerChance = this.arena.getTrainerChance(); - if (!Utils.randSeedInt(waveTrainerChance)) - allowTrainerBattle = false; - }, w); - if (!allowTrainerBattle) - break; - } - } - } - newBattleType = allowTrainerBattle && trainerChance && !Utils.randSeedInt(trainerChance) ? BattleType.TRAINER : BattleType.WILD; - } else - newBattleType = BattleType.WILD; - } else + else if (battleType === undefined) + newBattleType = this.gameMode.isWaveTrainer(newWaveIndex, this.arena) ? BattleType.TRAINER : BattleType.WILD; + else newBattleType = battleType; if (newBattleType === BattleType.TRAINER) { @@ -897,7 +871,7 @@ export default class BattleScene extends Phaser.Scene { //this.pushPhase(new TrainerMessageTestPhase(this, TrainerType.RIVAL, TrainerType.RIVAL_2, TrainerType.RIVAL_3, TrainerType.RIVAL_4, TrainerType.RIVAL_5, TrainerType.RIVAL_6)); if (!waveIndex && lastBattle) { - const isNewBiome = !(lastBattle.waveIndex % 10); + const isNewBiome = !(lastBattle.waveIndex % 10) || (this.gameMode.isDaily && lastBattle.waveIndex === 49); const resetArenaState = isNewBiome || this.currentBattle.battleType === BattleType.TRAINER || this.currentBattle.battleSpec === BattleSpec.FINAL_BOSS; this.getEnemyParty().forEach(enemyPokemon => enemyPokemon.destroy()); this.trySpreadPokerus(); @@ -1030,6 +1004,9 @@ export default class BattleScene extends Phaser.Scene { } getEncounterBossSegments(waveIndex: integer, level: integer, species?: PokemonSpecies, forceBoss: boolean = false): integer { + if (this.gameMode.isDaily && this.gameMode.isWaveFinal(waveIndex)) + return 5; + let isBoss: boolean; if (forceBoss || (species && (species.pseudoLegendary || species.legendary || species.mythical))) isBoss = true; @@ -1164,7 +1141,7 @@ export default class BattleScene extends Phaser.Scene { getMaxExpLevel(ignoreLevelCap?: boolean): integer { if (ignoreLevelCap) return Number.MAX_SAFE_INTEGER; - const lastWaveIndex = Math.ceil((this.currentBattle?.waveIndex || 1) / 10) * 10; + const lastWaveIndex = Math.ceil((this.gameMode.getWaveForDifficulty(this.currentBattle?.waveIndex || 1)) / 10) * 10; const baseLevel = (1 + lastWaveIndex / 2 + Math.pow(lastWaveIndex / 25, 2)) * 1.2; return Math.ceil(baseLevel / 2) * 2 + 2; } diff --git a/src/battle.ts b/src/battle.ts index 441d305bf..58157481e 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -96,12 +96,18 @@ export default class Battle { const ret = Math.floor(baseLevel * bossMultiplier); if (this.battleSpec === BattleSpec.FINAL_BOSS || !(this.waveIndex % 250)) return Math.ceil(ret / 25) * 25; - return ret + Math.round(Phaser.Math.RND.realInRange(-1, 1) * Math.floor(levelWaveIndex / 10)); + let levelOffset = 0; + if (!this.gameMode.isWaveFinal(this.waveIndex)) + levelOffset = Math.round(Phaser.Math.RND.realInRange(-1, 1) * Math.floor(levelWaveIndex / 10)); + return ret + levelOffset; } + let levelOffset = 0; + const deviation = 10 / levelWaveIndex; + levelOffset = Math.abs(this.randSeedGaussForLevel(deviation)); - return Math.max(Math.round(baseLevel + Math.abs(this.randSeedGaussForLevel(deviation))), 1); + return Math.max(Math.round(baseLevel + levelOffset), 1); } randSeedGaussForLevel(value: number): number { diff --git a/src/data/daily-run.ts b/src/data/daily-run.ts index 698702054..98d87c93d 100644 --- a/src/data/daily-run.ts +++ b/src/data/daily-run.ts @@ -11,12 +11,19 @@ export interface DailyRunConfig { starters: Starter; } -export function getDailyRunSeed(scene: BattleScene): string { - return 'Test';//Utils.randomString(16) +export function fetchDailyRunSeed(): Promise { + return new Promise(resolve => { + Utils.apiFetch('daily/seed').then(response => { + if (!response.ok) { + resolve(null); + return; + } + return response.text(); + }).then(seed => resolve(seed)); + }); } -export function getDailyRunStarters(scene: BattleScene): Starter[] { - const seed = getDailyRunSeed(scene); +export function getDailyRunStarters(scene: BattleScene, seed: string): Starter[] { const starters: Starter[] = []; scene.executeWithSeedOffset(() => { @@ -25,13 +32,15 @@ export function getDailyRunStarters(scene: BattleScene): Starter[] { starterWeights.push(Utils.randSeedInt(9 - starterWeights[0], 1)); starterWeights.push(10 - (starterWeights[0] + starterWeights[1])); + const startingLevel = gameModes[GameModes.DAILY].getStartingLevel(); + for (let s = 0; s < starterWeights.length; s++) { const weight = starterWeights[s]; const weightSpecies = Object.keys(speciesStarters) .map(s => parseInt(s) as Species) .filter(s => speciesStarters[s] === weight); - const starterSpecies = getPokemonSpecies(Phaser.Math.RND.pick(weightSpecies)); - const pokemon = new PlayerPokemon(scene, starterSpecies, gameModes[GameModes.DAILY].getStartingLevel(), undefined, undefined, undefined, undefined, undefined, undefined, undefined); + const starterSpecies = getPokemonSpecies(getPokemonSpecies(Utils.randSeedItem(weightSpecies)).getSpeciesForLevel(startingLevel, true, true, false, true)); + const pokemon = new PlayerPokemon(scene, starterSpecies, startingLevel, undefined, undefined, undefined, undefined, undefined, undefined, undefined); const starter: Starter = { species: starterSpecies, dexAttr: pokemon.getDexAttr(), @@ -42,6 +51,5 @@ export function getDailyRunStarters(scene: BattleScene): Starter[] { pokemon.destroy(); } }, 0, seed); - return starters; } \ No newline at end of file diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index 31d85e872..09b52f657 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -402,7 +402,7 @@ export default class PokemonSpecies extends PokemonSpeciesForm { return this.name; } - getSpeciesForLevel(level: integer, allowEvolving: boolean = false, forTrainer: boolean = false, isBoss: boolean = false): Species { + getSpeciesForLevel(level: integer, allowEvolving: boolean = false, forTrainer: boolean = false, isBoss: boolean = false, player: boolean = false): Species { const prevolutionLevels = this.getPrevolutionLevels(); if (prevolutionLevels.length) { @@ -437,11 +437,15 @@ export default class PokemonSpecies extends PokemonSpeciesForm { if (!forTrainer && isRegionalEvolution) evolutionChance = 0; else if (ev.wildDelay === SpeciesWildEvolutionDelay.NONE) { - const maxLevelDiff = forTrainer || isBoss ? forTrainer && isBoss ? 10 : 20 : 40; - const minChance = forTrainer ? 0.5 : 0.75; - evolutionChance = Math.min(minChance + easeInFunc(Math.min(level - ev.level, maxLevelDiff) / maxLevelDiff) * (1 - minChance), 1); + if (player) + evolutionChance = 1; + else { + const maxLevelDiff = forTrainer || isBoss ? forTrainer && isBoss ? 10 : 20 : 40; + const minChance = forTrainer ? 0.5 : 0.75; + evolutionChance = Math.min(minChance + easeInFunc(Math.min(level - ev.level, maxLevelDiff) / maxLevelDiff) * (1 - minChance), 1); + } } else { - let preferredMinLevel = (ev.level - 1) + ev.wildDelay * (forTrainer || isBoss ? forTrainer && isBoss ? 5 : 10 : 20); + let preferredMinLevel = (ev.level - 1) + ev.wildDelay * (player ? 0 : forTrainer || isBoss ? forTrainer && isBoss ? 5 : 10 : 20); let evolutionLevel = ev.level > 1 ? ev.level : Math.floor(preferredMinLevel / 2); if (ev.level <= 1 && pokemonPrevolutions.hasOwnProperty(this.speciesId)) { diff --git a/src/data/trainer-config.ts b/src/data/trainer-config.ts index db6d1a93a..b34d3a1b4 100644 --- a/src/data/trainer-config.ts +++ b/src/data/trainer-config.ts @@ -455,7 +455,7 @@ interface TrainerConfigs { } function getWavePartyTemplate(scene: BattleScene, ...templates: TrainerPartyTemplate[]) { - return templates[Math.min(Math.max(Math.ceil(((scene.currentBattle?.waveIndex || startingWave) - 20) / 30), 0), templates.length - 1)]; + return templates[Math.min(Math.max(Math.ceil((scene.gameMode.getWaveForDifficulty(scene.currentBattle?.waveIndex || startingWave, true) - 20) / 30), 0), templates.length - 1)]; } function getGymLeaderPartyTemplate(scene: BattleScene) { diff --git a/src/field/arena.ts b/src/field/arena.ts index 4ab21af47..a887b595f 100644 --- a/src/field/arena.ts +++ b/src/field/arena.ts @@ -53,6 +53,9 @@ export class Arena { } randomSpecies(waveIndex: integer, level: integer, attempt?: integer): PokemonSpecies { + const overrideSpecies = this.scene.gameMode.getOverrideSpecies(waveIndex); + if (overrideSpecies) + return overrideSpecies; const isBoss = !!this.scene.getEncounterBossSegments(waveIndex, level) && !!this.pokemonPool[BiomePoolTier.BOSS].length && (this.biomeType !== Biome.END || this.scene.gameMode.isClassic || this.scene.gameMode.isWaveFinal(waveIndex)); const tierValue = Utils.randSeedInt(!isBoss ? 512 : 64); @@ -123,8 +126,9 @@ export class Arena { } randomTrainerType(waveIndex: integer): TrainerType { - const isBoss = (waveIndex % 30) === 20 && !!this.trainerPool[BiomePoolTier.BOSS].length - && (this.biomeType !== Biome.END || this.scene.gameMode.isClassic || this.scene.gameMode.isWaveFinal(waveIndex)); + const isBoss = !!this.trainerPool[BiomePoolTier.BOSS].length + && this.scene.gameMode.isTrainerBoss(waveIndex, this.biomeType); + console.log(isBoss, this.trainerPool) const tierValue = Utils.randSeedInt(!isBoss ? 512 : 64); let tier = !isBoss ? tierValue >= 156 ? BiomePoolTier.COMMON : tierValue >= 32 ? BiomePoolTier.UNCOMMON : tierValue >= 6 ? BiomePoolTier.RARE : tierValue >= 1 ? BiomePoolTier.SUPER_RARE : BiomePoolTier.ULTRA_RARE diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index cbfaea49d..08701df30 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -1073,9 +1073,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { if (source.getTag(BattlerTagType.CRIT_BOOST)) critLevel.value += 2; const critChance = Math.ceil(16 / Math.pow(2, critLevel.value)); - const blockCrit = new Utils.BooleanHolder(false); - applyAbAttrs(BlockCritAbAttr, this, null); - isCritical = !blockCrit.value && !source.getTag(BattlerTagType.NO_CRIT) && (critChance === 1 || !this.scene.currentBattle.randSeedInt(critChance)); + isCritical = !source.getTag(BattlerTagType.NO_CRIT) && (critChance === 1 || !this.scene.currentBattle.randSeedInt(critChance)); + if (isCritical) { + const blockCrit = new Utils.BooleanHolder(false); + applyAbAttrs(BlockCritAbAttr, this, null, blockCrit); + if (blockCrit.value) + isCritical = false; + } } const sourceAtk = new Utils.IntegerHolder(source.getBattleStat(isPhysical ? Stat.ATK : Stat.SPATK, this)); const targetDef = new Utils.IntegerHolder(this.getBattleStat(isPhysical ? Stat.DEF : Stat.SPDEF, source)); diff --git a/src/field/trainer.ts b/src/field/trainer.ts index 8cf73530b..9f112c5a3 100644 --- a/src/field/trainer.ts +++ b/src/field/trainer.ts @@ -78,7 +78,8 @@ export default class Trainer extends Phaser.GameObjects.Container { const ret = []; const partyTemplate = this.getPartyTemplate(); - let baseLevel = 1 + waveIndex / 2 + Math.pow(waveIndex / 25, 2); + const difficultyWaveIndex = this.scene.gameMode.getWaveForDifficulty(waveIndex); + let baseLevel = 1 + difficultyWaveIndex / 2 + Math.pow(difficultyWaveIndex / 25, 2); for (let i = 0; i < partyTemplate.size; i++) { let multiplier = 1; @@ -106,8 +107,8 @@ export default class Trainer extends Phaser.GameObjects.Container { let levelOffset = 0; if (strength < TrainerPartyMemberStrength.STRONG) { - multiplier = Math.min(multiplier + 0.025 * Math.floor(waveIndex / 25), 1.2); - levelOffset = -Math.floor((waveIndex / 50) * (TrainerPartyMemberStrength.STRONG - strength)); + multiplier = Math.min(multiplier + 0.025 * Math.floor(difficultyWaveIndex / 25), 1.2); + levelOffset = -Math.floor((difficultyWaveIndex / 50) * (TrainerPartyMemberStrength.STRONG - strength)); } const level = Math.ceil(baseLevel * multiplier) + levelOffset; diff --git a/src/game-mode.ts b/src/game-mode.ts index 439b1b95d..2c76d07c8 100644 --- a/src/game-mode.ts +++ b/src/game-mode.ts @@ -1,5 +1,10 @@ +import { fixedBattles } from "./battle"; import BattleScene, { STARTING_BIOME_OVERRIDE, STARTING_LEVEL_OVERRIDE, STARTING_MONEY_OVERRIDE } from "./battle-scene"; import { Biome } from "./data/enums/biome"; +import { Species } from "./data/enums/species"; +import PokemonSpecies, { allSpecies } from "./data/pokemon-species"; +import { Arena } from "./field/arena"; +import * as Utils from "./utils"; export enum GameModes { CLASSIC, @@ -14,6 +19,7 @@ interface GameModeConfig { isDaily?: boolean; hasTrainers?: boolean; hasFixedBattles?: boolean; + hasNoShop?: boolean; hasRandomBiomes?: boolean; hasRandomBosses?: boolean; isSplicedOnly?: boolean; @@ -26,6 +32,7 @@ export class GameMode implements GameModeConfig { public isDaily: boolean; public hasTrainers: boolean; public hasFixedBattles: boolean; + public hasNoShop: boolean; public hasRandomBiomes: boolean; public hasRandomBosses: boolean; public isSplicedOnly: boolean; @@ -59,15 +66,66 @@ export class GameMode implements GameModeConfig { } } - getWaveForDifficulty(waveIndex: integer): integer { + getWaveForDifficulty(waveIndex: integer, ignoreCurveChanges: boolean = false): integer { switch (this.modeId) { case GameModes.DAILY: - return waveIndex + 30 + Math.floor(waveIndex / 5); + return waveIndex + 30 + (!ignoreCurveChanges ? Math.floor(waveIndex / 5) : 0); default: return waveIndex; } } + isWaveTrainer(waveIndex: integer, arena: Arena): boolean { + if (this.isDaily) + return waveIndex % 10 === 5 || (!(waveIndex % 10) && waveIndex > 10 && !this.isWaveFinal(waveIndex)); + if ((waveIndex % 30) === 20 && !this.isWaveFinal(waveIndex)) + return true; + else if (waveIndex % 10 !== 1 && waveIndex % 10) { + const trainerChance = arena.getTrainerChance(); + let allowTrainerBattle = true; + if (trainerChance) { + const waveBase = Math.floor(waveIndex / 10) * 10; + for (let w = Math.max(waveIndex - 3, waveBase + 2); w <= Math.min(waveIndex + 3, waveBase + 9); w++) { + if (w === waveIndex) + continue; + if ((w % 30) === 20 || fixedBattles.hasOwnProperty(w)) { + allowTrainerBattle = false; + break; + } else if (w < waveIndex) { + arena.scene.executeWithSeedOffset(() => { + const waveTrainerChance = arena.getTrainerChance(); + if (!Utils.randSeedInt(waveTrainerChance)) + allowTrainerBattle = false; + }, w); + if (!allowTrainerBattle) + break; + } + } + } + return allowTrainerBattle && trainerChance && !Utils.randSeedInt(trainerChance); + } + return false; + } + + isTrainerBoss(waveIndex: integer, biomeType: Biome): boolean { + switch (this.modeId) { + case GameModes.DAILY: + return waveIndex > 10 && waveIndex < 50 && !(waveIndex % 10); + default: + return (waveIndex % 30) === 20 && (biomeType !== Biome.END || this.isClassic || this.isWaveFinal(waveIndex)); + } + } + + getOverrideSpecies(waveIndex: integer): PokemonSpecies { + if (this.isDaily && this.isWaveFinal(waveIndex)) { + const allFinalBossSpecies = allSpecies.filter(s => (s.pseudoLegendary || s.legendary || s.mythical) + && s.baseTotal >= 600 && s.speciesId !== Species.ETERNATUS && s.speciesId !== Species.ARCEUS); + return Utils.randSeedItem(allFinalBossSpecies); + } + + return null; + } + isWaveFinal(waveIndex: integer): boolean { switch (this.modeId) { case GameModes.CLASSIC: @@ -109,5 +167,5 @@ export const gameModes = Object.freeze({ [GameModes.CLASSIC]: new GameMode(GameModes.CLASSIC, { isClassic: true, hasTrainers: true, hasFixedBattles: true }), [GameModes.ENDLESS]: new GameMode(GameModes.ENDLESS, { isEndless: true, hasRandomBiomes: true, hasRandomBosses: true }), [GameModes.SPLICED_ENDLESS]: new GameMode(GameModes.SPLICED_ENDLESS, { isEndless: true, hasRandomBiomes: true, hasRandomBosses: true, isSplicedOnly: true }), - [GameModes.DAILY]: new GameMode(GameModes.DAILY, { isDaily: true, hasTrainers: true }) + [GameModes.DAILY]: new GameMode(GameModes.DAILY, { isDaily: true, hasTrainers: true, hasNoShop: true }) }); \ No newline at end of file diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index dc695573d..cdb1941f7 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -12,7 +12,6 @@ import * as Utils from '../utils'; import { TempBattleStat, getTempBattleStatBoosterItemName, getTempBattleStatName } from '../data/temp-battle-stat'; import { BerryType, getBerryEffectDescription, getBerryName } from '../data/berry'; import { Unlockables } from '../system/unlockables'; -import { GameModes } from '../game-mode'; import { StatusEffect, getStatusEffectDescriptor } from '../data/status-effect'; import { SpeciesFormKey } from '../data/pokemon-species'; import BattleScene from '../battle-scene'; @@ -29,7 +28,8 @@ export enum ModifierPoolType { PLAYER, WILD, TRAINER, - ENEMY_BUFF + ENEMY_BUFF, + DAILY_STARTER } type NewModifierFunc = (type: ModifierType, args: any[]) => Modifier; @@ -775,7 +775,7 @@ export const modifierTypes = { if (!party[0].scene.getModifiers(Modifiers.TerastallizeAccessModifier).length) return null; let type: Type; - if (!Utils.randInt(3)) { + if (!Utils.randSeedInt(3)) { const partyMemberTypes = party.map(p => p.getTypes(false, true)).flat(); type = Utils.randSeedItem(partyMemberTypes); } else @@ -886,7 +886,11 @@ export const modifierTypes = { ENEMY_FUSED_CHANCE: () => new ModifierType('Fusion Token', 'Adds a 1% chance that a wild Pokémon will be a fusion', (type, _args) => new Modifiers.EnemyFusionChanceModifier(type, 1), 'wl_custom_spliced'), }; -const modifierPool = { +interface ModifierPool { + [tier: string]: WeightedModifierType[] +} + +const modifierPool: ModifierPool = { [ModifierTier.COMMON]: [ new WeightedModifierType(modifierTypes.POKEBALL, 6), new WeightedModifierType(modifierTypes.RARE_CANDY, 2), @@ -1015,12 +1019,10 @@ const modifierPool = { new WeightedModifierType(modifierTypes.VOUCHER_PLUS, 8), new WeightedModifierType(modifierTypes.DNA_SPLICERS, (party: Pokemon[]) => !party[0].scene.gameMode.isSplicedOnly && party.filter(p => !p.fusionSpecies).length > 1 ? 24 : 0, 24), new WeightedModifierType(modifierTypes.MINI_BLACK_HOLE, (party: Pokemon[]) => party[0].scene.gameData.unlocks[Unlockables.MINI_BLACK_HOLE] ? 1 : 0, 1), - ].map(m => { m.setTier(ModifierTier.MASTER); return m; }), - [ModifierTier.LUXURY]: [ - ].map(m => { m.setTier(ModifierTier.LUXURY); return m; }), + ].map(m => { m.setTier(ModifierTier.MASTER); return m; }) }; -const wildModifierPool = { +const wildModifierPool: ModifierPool = { [ModifierTier.COMMON]: [ new WeightedModifierType(modifierTypes.BERRY, 1) ].map(m => { m.setTier(ModifierTier.COMMON); return m; }), @@ -1038,7 +1040,7 @@ const wildModifierPool = { ].map(m => { m.setTier(ModifierTier.MASTER); return m; }) }; -const trainerModifierPool = { +const trainerModifierPool: ModifierPool = { [ModifierTier.COMMON]: [ new WeightedModifierType(modifierTypes.BERRY, 8), new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 3) @@ -1062,7 +1064,7 @@ const trainerModifierPool = { ].map(m => { m.setTier(ModifierTier.MASTER); return m; }) }; -const enemyBuffModifierPool = { +const enemyBuffModifierPool: ModifierPool = { [ModifierTier.COMMON]: [ new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_BOOSTER, 10), new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_REDUCTION, 10), @@ -1099,6 +1101,32 @@ const enemyBuffModifierPool = { [ModifierTier.MASTER]: [ ].map(m => { m.setTier(ModifierTier.MASTER); return m; }) }; +const dailyStarterModifierPool: ModifierPool = { + [ModifierTier.COMMON]: [ + new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 1), + new WeightedModifierType(modifierTypes.BERRY, 3), + ].map(m => { m.setTier(ModifierTier.COMMON); return m; }), + [ModifierTier.GREAT]: [ + new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 5), + ].map(m => { m.setTier(ModifierTier.GREAT); return m; }), + [ModifierTier.ULTRA]: [ + new WeightedModifierType(modifierTypes.REVIVER_SEED, 4), + new WeightedModifierType(modifierTypes.SOOTHE_BELL, 1), + new WeightedModifierType(modifierTypes.SOUL_DEW, 1), + new WeightedModifierType(modifierTypes.GOLDEN_PUNCH, 1), + ].map(m => { m.setTier(ModifierTier.ULTRA); return m; }), + [ModifierTier.ROGUE]: [ + new WeightedModifierType(modifierTypes.GRIP_CLAW, 5), + new WeightedModifierType(modifierTypes.BATON, 2), + new WeightedModifierType(modifierTypes.FOCUS_BAND, 5), + new WeightedModifierType(modifierTypes.KINGS_ROCK, 3), + ].map(m => { m.setTier(ModifierTier.ROGUE); return m; }), + [ModifierTier.MASTER]: [ + new WeightedModifierType(modifierTypes.LEFTOVERS, 1), + new WeightedModifierType(modifierTypes.SHELL_BELL, 1), + ].map(m => { m.setTier(ModifierTier.MASTER); return m; }) +}; + export function getModifierType(modifierTypeFunc: ModifierTypeFunc): ModifierType { const modifierType = modifierTypeFunc(); if (!modifierType.id) @@ -1109,6 +1137,9 @@ export function getModifierType(modifierTypeFunc: ModifierTypeFunc): ModifierTyp let modifierPoolThresholds = {}; let ignoredPoolIndexes = {}; +let dailyStarterModifierPoolThresholds = {}; +let ignoredDailyStarterPoolIndexes = {}; + let enemyModifierPoolThresholds = {}; let enemyIgnoredPoolIndexes = {}; @@ -1118,8 +1149,24 @@ let enemyBuffIgnoredPoolIndexes = {}; const tierWeights = [ 769 / 1024, 192 / 1024, 48 / 1024, 12 / 1024, 1 / 1024 ]; export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: ModifierPoolType) { - const player = !poolType; - const pool = player ? modifierPool : poolType === ModifierPoolType.WILD ? wildModifierPool : poolType === ModifierPoolType.TRAINER ? trainerModifierPool : enemyBuffModifierPool; + let pool: ModifierPool; + switch (poolType) { + case ModifierPoolType.PLAYER: + pool = modifierPool; + break; + case ModifierPoolType.WILD: + pool = wildModifierPool; + break; + case ModifierPoolType.TRAINER: + pool = trainerModifierPool; + break; + case ModifierPoolType.ENEMY_BUFF: + pool = enemyBuffModifierPool; + break; + case ModifierPoolType.DAILY_STARTER: + pool = dailyStarterModifierPool; + break; + } const ignoredIndexes = {}; const modifierTableData = {}; const thresholds = Object.fromEntries(new Map(Object.keys(pool).slice(0, -1).map(t => { @@ -1130,7 +1177,7 @@ export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: Mod let i = 0; pool[t].reduce((total: integer, modifierType: WeightedModifierType) => { const weightedModifierType = modifierType as WeightedModifierType; - const existingModifiers = party[0].scene.findModifiers(m => (m.type.generatorId || m.type.id) === weightedModifierType.modifierType.id, player); + const existingModifiers = party[0].scene.findModifiers(m => (m.type.generatorId || m.type.id) === weightedModifierType.modifierType.id, poolType === ModifierPoolType.PLAYER); const itemModifierType = weightedModifierType.modifierType instanceof ModifierTypeGenerator ? weightedModifierType.modifierType.generateType(party) : weightedModifierType.modifierType; @@ -1168,15 +1215,24 @@ export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: Mod } if (outputModifierData) console.table(modifierTableData); - if (player) { - modifierPoolThresholds = thresholds; - ignoredPoolIndexes = ignoredIndexes; - } else if (poolType !== ModifierPoolType.ENEMY_BUFF) { - enemyModifierPoolThresholds = thresholds; - enemyIgnoredPoolIndexes = ignoredIndexes; - } else { - enemyBuffModifierPoolThresholds = thresholds; - enemyBuffIgnoredPoolIndexes = ignoredIndexes; + switch (poolType) { + case ModifierPoolType.PLAYER: + modifierPoolThresholds = thresholds; + ignoredPoolIndexes = ignoredIndexes; + break; + case ModifierPoolType.WILD: + case ModifierPoolType.TRAINER: + enemyModifierPoolThresholds = thresholds; + enemyIgnoredPoolIndexes = ignoredIndexes; + break; + case ModifierPoolType.ENEMY_BUFF: + enemyBuffModifierPoolThresholds = thresholds; + enemyBuffIgnoredPoolIndexes = ignoredIndexes; + break; + case ModifierPoolType.DAILY_STARTER: + dailyStarterModifierPoolThresholds = thresholds; + ignoredDailyStarterPoolIndexes = ignoredIndexes; + break; } } @@ -1184,9 +1240,7 @@ export function getModifierTypeFuncById(id: string): ModifierTypeFunc { return modifierTypes[id]; } -export function getPlayerModifierTypeOptionsForWave(waveIndex: integer, count: integer, party: PlayerPokemon[]): ModifierTypeOption[] { - if (waveIndex % 10 === 0) - return modifierPool[ModifierTier.LUXURY].filter(m => !(m.weight instanceof Function) || m.weight(party)).map(m => new ModifierTypeOption(m.modifierType, 0)); +export function getPlayerModifierTypeOptions(count: integer, party: PlayerPokemon[]): ModifierTypeOption[] { const options: ModifierTypeOption[] = []; const retryCount = Math.min(count * 5, 50); new Array(count).fill(0).map(() => { @@ -1257,9 +1311,46 @@ export function getEnemyModifierTypesForWave(waveIndex: integer, count: integer, return ret; } +export function getDailyRunStarterModifiers(party: PlayerPokemon[]): Modifiers.PokemonHeldItemModifier[] { + const ret: Modifiers.PokemonHeldItemModifier[] = []; + for (let p of party) { + for (let m = 0; m < 3; m++) { + const tierValue = Utils.randSeedInt(64); + const tier = tierValue > 25 ? ModifierTier.COMMON : tierValue > 12 ? ModifierTier.GREAT : tierValue > 4 ? ModifierTier.ULTRA : tierValue ? ModifierTier.ROGUE : ModifierTier.MASTER; + const modifier = getNewModifierTypeOption(party, ModifierPoolType.DAILY_STARTER, tier).type.newModifier(p) as Modifiers.PokemonHeldItemModifier; + ret.push(modifier); + } + } + + return ret; +} + function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, tier?: ModifierTier, upgradeCount?: integer): ModifierTypeOption { const player = !poolType; - const pool = player ? modifierPool : poolType === ModifierPoolType.WILD ? wildModifierPool : poolType === ModifierPoolType.TRAINER ? trainerModifierPool : enemyBuffModifierPool; + let pool: ModifierPool; + let thresholds: object; + switch (poolType) { + case ModifierPoolType.PLAYER: + pool = modifierPool; + thresholds = modifierPoolThresholds; + break; + case ModifierPoolType.WILD: + pool = wildModifierPool; + thresholds = enemyModifierPoolThresholds; + break; + case ModifierPoolType.TRAINER: + pool = trainerModifierPool; + thresholds = enemyModifierPoolThresholds; + break; + case ModifierPoolType.ENEMY_BUFF: + pool = enemyBuffModifierPool; + thresholds = enemyBuffModifierPoolThresholds; + break; + case ModifierPoolType.DAILY_STARTER: + pool = dailyStarterModifierPool; + thresholds = dailyStarterModifierPoolThresholds; + break; + } if (tier === undefined) { const tierValue = Utils.randSeedInt(1024); upgradeCount = 0; @@ -1283,7 +1374,6 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, } } - const thresholds = player ? modifierPoolThresholds : pool !== enemyBuffModifierPool ? enemyModifierPoolThresholds : enemyBuffModifierPoolThresholds; const tierThresholds = Object.keys(thresholds[tier]); const totalWeight = parseInt(tierThresholds[tierThresholds.length - 1]); const value = Utils.randSeedInt(totalWeight); @@ -1314,7 +1404,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, } export function getDefaultModifierTypeForTier(tier: ModifierTier): ModifierType { - let modifierType: ModifierType | WeightedModifierType = modifierPool[tier || ModifierTier.COMMON][tier !== ModifierTier.LUXURY ? 0 : 2]; + let modifierType: ModifierType | WeightedModifierType = modifierPool[tier || ModifierTier.COMMON][0]; if (modifierType instanceof WeightedModifierType) modifierType = (modifierType as WeightedModifierType).modifierType; return modifierType; diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 063ac3dce..0652d123d 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -1260,17 +1260,14 @@ export class ExpBoosterModifier extends PersistentModifier { } apply(args: any[]): boolean { + console.log(this.boostMultiplier); (args[0] as Utils.NumberHolder).value = Math.floor((args[0] as Utils.NumberHolder).value * (1 + (this.getStackCount() * this.boostMultiplier))); return true; } - getStackCount(): integer { - return this.boostMultiplier < 1 ? super.getStackCount() : 10; - } - getMaxStackCount(scene: BattleScene, forThreshold?: boolean): integer { - return 99; + return this.boostMultiplier < 1 ? this.boostMultiplier < 0.6 ? 99 : 30 : 10; } } diff --git a/src/phases.ts b/src/phases.ts index d801c73c8..5c06344b6 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -1,8 +1,8 @@ -import BattleScene, { STARTING_BIOME_OVERRIDE, bypassLogin, startingWave } from "./battle-scene"; +import BattleScene, { bypassLogin, startingWave } from "./battle-scene"; import { default as Pokemon, PlayerPokemon, EnemyPokemon, PokemonMove, MoveResult, DamageResult, FieldPosition, HitResult, TurnMove } from "./field/pokemon"; import * as Utils from './utils'; import { Moves } from "./data/enums/moves"; -import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMoveAttrs, HitsTagAttr, MissEffectAttr, MoveAttr, MoveCategory, MoveEffectAttr, MoveFlags, MultiHitAttr, OverrideMoveEffectAttr, VariableAccuracyAttr, MoveTarget, OneHitKOAttr, getMoveTargets, MoveTargetSet, MoveEffectTrigger, CopyMoveAttr, AttackMove, SelfStatusMove, DelayedAttackAttr, RechargeAttr } from "./data/move"; +import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMoveAttrs, HitsTagAttr, MissEffectAttr, MoveAttr, MoveEffectAttr, MoveFlags, MultiHitAttr, OverrideMoveEffectAttr, VariableAccuracyAttr, MoveTarget, OneHitKOAttr, getMoveTargets, MoveTargetSet, MoveEffectTrigger, CopyMoveAttr, AttackMove, SelfStatusMove, DelayedAttackAttr, RechargeAttr } from "./data/move"; import { Mode } from './ui/ui'; import { Command } from "./ui/command-ui-handler"; import { Stat } from "./data/pokemon-stat"; @@ -19,7 +19,7 @@ import { BattleStat, getBattleStatLevelChangeDescription, getBattleStatName } fr import { biomeLinks } from "./data/biomes"; import { Biome } from "./data/enums/biome"; import { ModifierTier } from "./modifier/modifier-tier"; -import { FusePokemonModifierType, ModifierPoolType, ModifierType, ModifierTypeFunc, ModifierTypeOption, PokemonModifierType, PokemonMoveModifierType, RememberMoveModifierType, TmModifierType, getEnemyBuffModifierForWave, getModifierType, getPlayerModifierTypeOptionsForWave, getPlayerShopModifierTypeOptionsForWave, modifierTypes, regenerateModifierPoolThresholds } from "./modifier/modifier-type"; +import { FusePokemonModifierType, ModifierPoolType, ModifierType, ModifierTypeFunc, ModifierTypeOption, PokemonModifierType, PokemonMoveModifierType, RememberMoveModifierType, TmModifierType, getDailyRunStarterModifiers, getEnemyBuffModifierForWave, getModifierType, getPlayerModifierTypeOptions, getPlayerShopModifierTypeOptionsForWave, modifierTypes, regenerateModifierPoolThresholds } from "./modifier/modifier-type"; import SoundFade from "phaser3-rex-plugins/plugins/soundfade"; import { BattlerTagLapseType, EncoreTag, HideSpriteTag as HiddenTag, ProtectedTag, TrappedTag } from "./data/battler-tags"; import { BattlerTagType } from "./data/enums/battler-tag-type"; @@ -53,7 +53,7 @@ import { Tutorial, handleTutorial } from "./tutorial"; import { TerrainType } from "./data/terrain"; import { OptionSelectConfig, OptionSelectItem } from "./ui/abstact-option-select-ui-handler"; import { SaveSlotUiMode } from "./ui/save-slot-select-ui-handler"; -import { getDailyRunSeed, getDailyRunStarters } from "./data/daily-run"; +import { fetchDailyRunSeed, getDailyRunStarters } from "./data/daily-run"; import { GameModes, gameModes } from "./game-mode"; export class LoginPhase extends Phase { @@ -137,6 +137,7 @@ export class TitlePhase extends Phase { start(): void { super.start(); + this.scene.ui.clearText(); this.scene.ui.fadeIn(250); this.scene.fadeOutBgm(0, false); @@ -169,12 +170,12 @@ export class TitlePhase extends Phase { this.loadSaveSlot(slotId); } ) - }/*, + }, { - label: 'Daily Run', + label: 'Daily Run (Beta)', handler: () => this.initDailyRun(), keepOpen: true - }*/); + }); const config: OptionSelectConfig = { options: options, noCancel: true @@ -205,35 +206,48 @@ export class TitlePhase extends Phase { return this.end(); } this.scene.sessionSlotId = slotId; - this.scene.setSeed(getDailyRunSeed(this.scene)); - this.scene.gameMode = gameModes[GameModes.DAILY]; - this.scene.money = this.scene.gameMode.getStartingMoney(); + fetchDailyRunSeed().then(seed => { + this.scene.setSeed(seed); + this.scene.resetSeed(1); - const starters = getDailyRunStarters(this.scene); + this.scene.gameMode = gameModes[GameModes.DAILY]; + this.scene.money = this.scene.gameMode.getStartingMoney(); - const party = this.scene.getParty(); - const loadPokemonAssets: Promise[] = []; - for (let starter of starters) { - const starterProps = this.scene.gameData.getSpeciesDexAttrProps(starter.species, starter.dexAttr); - const starterFormIndex = Math.min(starterProps.formIndex, Math.max(starter.species.forms.length - 1, 0)); - const starterGender = starter.species.malePercent !== null - ? !starterProps.female ? Gender.MALE : Gender.FEMALE - : Gender.GENDERLESS; - const starterIvs = this.scene.gameData.dexData[starter.species.speciesId].ivs.slice(0); - const starterPokemon = this.scene.addPlayerPokemon(starter.species, this.scene.gameMode.getStartingLevel(), starterProps.abilityIndex, starterFormIndex, starterGender, starterProps.shiny, starterIvs, starter.nature); - if (starter.moveset) - starterPokemon.tryPopulateMoveset(starter.moveset); - starterPokemon.setVisible(false); - party.push(starterPokemon); - loadPokemonAssets.push(starterPokemon.loadAssets()); - } - Promise.all(loadPokemonAssets).then(() => { - this.scene.time.delayedCall(500, () => this.scene.playBgm()); - this.scene.gameData.gameStats.dailyRunSessionsPlayed++; - this.scene.newBattle(); - this.scene.sessionPlayTime = 0; - this.end(); + const starters = getDailyRunStarters(this.scene, seed); + const startingLevel = this.scene.gameMode.getStartingLevel(); + + const party = this.scene.getParty(); + const loadPokemonAssets: Promise[] = []; + for (let starter of starters) { + const starterProps = this.scene.gameData.getSpeciesDexAttrProps(starter.species, starter.dexAttr); + const starterFormIndex = Math.min(starterProps.formIndex, Math.max(starter.species.forms.length - 1, 0)); + const starterGender = starter.species.malePercent !== null + ? !starterProps.female ? Gender.MALE : Gender.FEMALE + : Gender.GENDERLESS; + const starterPokemon = this.scene.addPlayerPokemon(starter.species, startingLevel, starterProps.abilityIndex, starterFormIndex, starterGender, starterProps.shiny, undefined, starter.nature); + starterPokemon.setVisible(false); + party.push(starterPokemon); + loadPokemonAssets.push(starterPokemon.loadAssets()); + } + + regenerateModifierPoolThresholds(party, ModifierPoolType.DAILY_STARTER); + const modifiers: Modifier[] = Array(3).fill(null).map(() => modifierTypes.EXP_SHARE().withIdFromFunc(modifierTypes.EXP_SHARE).newModifier()) + .concat(Array(3).fill(null).map(() => modifierTypes.GOLDEN_EXP_CHARM().withIdFromFunc(modifierTypes.GOLDEN_EXP_CHARM).newModifier())) + .concat(getDailyRunStarterModifiers(party)); + + for (let m of modifiers) + this.scene.addModifier(m, true, false, false, true); + this.scene.updateModifiers(true, true); + + Promise.all(loadPokemonAssets).then(() => { + this.scene.time.delayedCall(500, () => this.scene.playBgm()); + this.scene.gameData.gameStats.dailyRunSessionsPlayed++; + this.scene.newArena(this.scene.gameMode.getStartingBiome(this.scene), true); + this.scene.newBattle(); + this.scene.sessionPlayTime = 0; + this.end(); + }); }); }); } @@ -242,12 +256,10 @@ export class TitlePhase extends Phase { if (!this.loaded && !this.scene.gameMode.isDaily) { this.scene.arena.preloadBgm(); this.scene.pushPhase(new SelectStarterPhase(this.scene)); + this.scene.newArena(this.scene.gameMode.getStartingBiome(this.scene), true); } else this.scene.playBgm(); - if (!this.loaded) - this.scene.newArena(this.scene.gameMode.getStartingBiome(this.scene), true); - this.scene.pushPhase(new EncounterPhase(this.scene, this.loaded)); if (this.loaded) { @@ -833,6 +845,8 @@ export class NewBiomeEncounterPhase extends NextEncounterPhase { } doEncounter(): void { + this.scene.playBgm(undefined, true); + for (let pokemon of this.scene.getParty()) { if (pokemon) pokemon.resetBattleData(); @@ -887,7 +901,8 @@ export class SelectBiomePhase extends BattlePhase { this.end(); }; - if (this.scene.gameMode.isClassic && this.scene.gameMode.isWaveFinal(this.scene.currentBattle.waveIndex + 9)) + if ((this.scene.gameMode.isClassic && this.scene.gameMode.isWaveFinal(this.scene.currentBattle.waveIndex + 9)) + || (this.scene.gameMode.isDaily && this.scene.gameMode.isWaveFinal(this.scene.currentBattle.waveIndex))) setNextBiome(Biome.END); else if (this.scene.gameMode.hasRandomBiomes) setNextBiome(this.generateNextBiome()); @@ -949,8 +964,6 @@ export class SwitchBiomePhase extends BattlePhase { this.scene.arenaPlayerTransition.setAlpha(0); this.scene.arenaPlayerTransition.setVisible(true); - this.scene.time.delayedCall(1000, () => this.scene.playBgm()); - this.scene.tweens.add({ targets: [ this.scene.arenaPlayer, this.scene.arenaBgTransition, this.scene.arenaPlayerTransition ], duration: 1000, @@ -2917,7 +2930,11 @@ export class VictoryPhase extends PokemonPhase { if (this.scene.gameMode.isEndless || !this.scene.gameMode.isWaveFinal(this.scene.currentBattle.waveIndex)) { if (this.scene.currentBattle.waveIndex % 10) this.scene.pushPhase(new SelectModifierPhase(this.scene)); - else { + else if (this.scene.gameMode.isDaily) { + this.scene.pushPhase(new ModifierRewardPhase(this.scene, modifierTypes.EXP_CHARM)); + if (this.scene.currentBattle.waveIndex > 10 && !this.scene.gameMode.isWaveFinal(this.scene.currentBattle.waveIndex)) + this.scene.pushPhase(new ModifierRewardPhase(this.scene, modifierTypes.GOLDEN_POKEBALL)); + } else { const superExpWave = !this.scene.gameMode.isEndless ? 20 : 10; if (this.scene.currentBattle.waveIndex <= 750 && (this.scene.currentBattle.waveIndex <= 500 || (this.scene.currentBattle.waveIndex % 30) === superExpWave)) this.scene.pushPhase(new ModifierRewardPhase(this.scene, (this.scene.currentBattle.waveIndex % 30) !== superExpWave || this.scene.currentBattle.waveIndex > 250 ? modifierTypes.EXP_CHARM : modifierTypes.SUPER_EXP_CHARM)); @@ -3076,12 +3093,15 @@ export class GameOverPhase extends BattlePhase { start() { super.start(); - this.scene.gameData.clearSession(this.scene.sessionSlotId).then(() => { + (this.victory ? this.scene.gameData.tryClearSession : this.scene.gameData.deleteSession)(this.scene.sessionSlotId).then((success: boolean | [boolean, boolean]) => { this.scene.time.delayedCall(1000, () => { let firstClear = false; - if (this.victory) { - firstClear = this.scene.validateAchv(achvs.CLASSIC_VICTORY); - this.scene.gameData.gameStats.sessionsWon++; + if (this.victory && success[1]) { + if (this.scene.gameMode.isClassic) { + firstClear = this.scene.validateAchv(achvs.CLASSIC_VICTORY); + this.scene.gameData.gameStats.sessionsWon++; + } else if (this.scene.gameMode.isDaily && success[1]) + this.scene.gameData.gameStats.dailyRunSessionsWon++; } this.scene.gameData.saveSystem(); const fadeDuration = this.victory ? 10000 : 5000; @@ -3090,7 +3110,7 @@ export class GameOverPhase extends BattlePhase { this.scene.clearPhaseQueue(); this.scene.ui.clearText(); this.handleUnlocks(); - if (this.victory && !firstClear) + if (this.victory && !firstClear && success[1]) this.scene.unshiftPhase(new GameOverModifierRewardPhase(this.scene, modifierTypes.VOUCHER_PREMIUM)); this.scene.reset(); this.scene.unshiftPhase(new TitlePhase(this.scene)); @@ -3189,6 +3209,7 @@ export class ExpPhase extends PlayerPartyMemberPokemonPhase { let exp = new Utils.NumberHolder(this.expValue); this.scene.applyModifiers(ExpBoosterModifier, true, exp); exp.value = Math.floor(exp.value); + console.log(this.expValue, exp.value); this.scene.ui.showText(`${pokemon.name} gained\n${exp.value} EXP. Points!`, null, () => { const lastLevel = pokemon.level; let newLevel: integer; @@ -3916,7 +3937,7 @@ export class SelectModifierPhase extends BattlePhase { } getModifierTypeOptions(modifierCount: integer): ModifierTypeOption[] { - return getPlayerModifierTypeOptionsForWave(this.scene.currentBattle.waveIndex, modifierCount, this.scene.getParty()); + return getPlayerModifierTypeOptions(modifierCount, this.scene.getParty()); } addModifier(modifier: Modifier): Promise { diff --git a/src/system/game-data.ts b/src/system/game-data.ts index 470327427..6e0cf9147 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -615,7 +615,7 @@ export class GameData { }); } - clearSession(slotId: integer): Promise { + deleteSession(slotId: integer): Promise { return new Promise(resolve => { if (bypassLogin) { localStorage.removeItem('sessionData'); @@ -636,6 +636,27 @@ export class GameData { }); } + tryClearSession(slotId: integer): Promise<[success: boolean, newClear: boolean]> { + return new Promise<[boolean, boolean]>(resolve => { + if (bypassLogin) { + localStorage.removeItem('sessionData'); + return resolve([true, true]); + } + + updateUserInfo().then(success => { + if (success !== null && !success) + return resolve([false, false]); + Utils.apiFetch(`savedata/clear?slot=${slotId}`).then(response => { + if (response.ok) { + loggedInUser.lastSessionSlot = -1; + return response.json(); + } + resolve([false, false]); + }).then(jsonResponse => resolve([true, jsonResponse.success as boolean])); + }); + }); + } + parseSessionData(dataStr: string): SessionSaveData { return JSON.parse(dataStr, (k: string, v: any) => { /*const versions = [ scene.game.config.gameVersion, sessionData.gameVersion || '0.0.0' ]; diff --git a/src/ui/modifier-select-ui-handler.ts b/src/ui/modifier-select-ui-handler.ts index 9728b29c7..8ede0e652 100644 --- a/src/ui/modifier-select-ui-handler.ts +++ b/src/ui/modifier-select-ui-handler.ts @@ -90,7 +90,9 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler { this.updateRerollCostText(); const typeOptions = args[1] as ModifierTypeOption[]; - const shopTypeOptions = getPlayerShopModifierTypeOptionsForWave(this.scene.currentBattle.waveIndex, this.scene.getWaveMoneyAmount(1)); + const shopTypeOptions = !this.scene.gameMode.hasNoShop + ? 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++) {