From 623d600e13fceaee04a1925909e90096d91f6c49 Mon Sep 17 00:00:00 2001 From: Flashfyre Date: Thu, 14 Mar 2024 16:26:57 -0400 Subject: [PATCH] Add wrapper for game mode --- src/battle-scene.ts | 26 ++++------ src/battle.ts | 19 ++++--- src/field/arena.ts | 6 +-- src/field/pokemon.ts | 6 +-- src/game-mode.ts | 78 ++++++++++++++++++++++++++--- src/modifier/modifier-type.ts | 14 +++--- src/phases.ts | 20 ++++---- src/system/game-data.ts | 8 +-- src/system/session-history.ts | 4 +- src/system/unlockables.ts | 6 +-- src/ui/battle-info.ts | 4 +- src/ui/starter-select-ui-handler.ts | 20 ++++---- 12 files changed, 139 insertions(+), 72 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index ada37c2a896..a5051baaeab 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -21,7 +21,7 @@ import { ModifierPoolType, getDefaultModifierTypeForTier, getEnemyModifierTypesF import AbilityBar from './ui/ability-bar'; import { BlockItemTheftAbAttr, DoubleBattleChanceAbAttr, applyAbAttrs, initAbilities } from './data/ability'; import Battle, { BattleType, FixedBattleConfig, fixedBattles } from './battle'; -import { GameMode } from './game-mode'; +import { GameMode, GameModes, gameModes } from './game-mode'; import FieldSpritePipeline from './pipelines/field-sprite'; import SpritePipeline from './pipelines/sprite'; import PartyExpBar from './ui/party-exp-bar'; @@ -747,7 +747,7 @@ export default class BattleScene extends Phaser.Scene { this.seed = Utils.randomString(16); console.log('Seed:', this.seed); - this.gameMode = GameMode.CLASSIC; + this.gameMode = gameModes[GameModes.CLASSIC]; this.money = startingMoney; @@ -812,7 +812,7 @@ export default class BattleScene extends Phaser.Scene { this.resetSeed(newWaveIndex); - if (fixedBattles.hasOwnProperty(newWaveIndex) && this.gameMode === GameMode.CLASSIC && trainerData === undefined) { + if (this.gameMode.hasFixedBattles && fixedBattles.hasOwnProperty(newWaveIndex) && trainerData === undefined) { battleConfig = fixedBattles[newWaveIndex]; newDouble = battleConfig.double; newBattleType = battleConfig.battleType; @@ -820,15 +820,15 @@ export default class BattleScene extends Phaser.Scene { if (newTrainer) this.field.add(newTrainer); } else { - if (this.gameMode !== GameMode.CLASSIC) + if (!this.gameMode.hasTrainers) newBattleType = BattleType.WILD; else if (battleType === undefined) { - if ((newWaveIndex % 30) === 20 && newWaveIndex !== 200) + 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 && this.gameMode === GameMode.CLASSIC) { + 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) @@ -862,7 +862,7 @@ export default class BattleScene extends Phaser.Scene { const playerField = this.getPlayerField(); if (double === undefined && newWaveIndex > 1) { - if (newBattleType === BattleType.WILD && (this.gameMode === GameMode.CLASSIC ? newWaveIndex !== 200 : newWaveIndex % 250)) { + if (newBattleType === BattleType.WILD && !this.gameMode.isWaveFinal(newWaveIndex)) { const doubleChance = new Utils.IntegerHolder(newWaveIndex % 10 === 0 ? 32 : 8); this.applyModifiers(DoubleBattleChanceBoosterModifier, true, doubleChance); playerField.forEach(p => applyAbAttrs(DoubleBattleChanceAbAttr, p, null, doubleChance)); @@ -902,7 +902,7 @@ export default class BattleScene extends Phaser.Scene { this.triggerPokemonFormChange(pokemon, SpeciesFormChangeTimeOfDayTrigger); } } - if (this.gameMode === GameMode.CLASSIC && !isNewBiome) + if (!this.gameMode.hasRandomBiomes && !isNewBiome) this.pushPhase(new NextEncounterPhase(this)); else { this.pushPhase(new SelectBiomePhase(this)); @@ -1022,7 +1022,7 @@ export default class BattleScene extends Phaser.Scene { isBoss = true; else { this.executeWithSeedOffset(() => { - isBoss = waveIndex % 10 === 0 || (this.gameMode !== GameMode.CLASSIC && Utils.randSeedInt(100) < Math.min(Math.max(Math.ceil((waveIndex - 250) / 50), 0) * 2, 30)); + isBoss = waveIndex % 10 === 0 || (this.gameMode.hasRandomBosses && Utils.randSeedInt(100) < Math.min(Math.max(Math.ceil((waveIndex - 250) / 50), 0) * 2, 30)); }, waveIndex << 2); } if (!isBoss) @@ -1683,11 +1683,7 @@ export default class BattleScene extends Phaser.Scene { const chances = Math.ceil(waveIndex / 10); const isBoss = !(waveIndex % 10) || (this.currentBattle.battleType === BattleType.TRAINER && this.currentBattle.trainer.config.isBoss); - let modifierChance: integer; - if (this.gameMode === GameMode.CLASSIC) - modifierChance = !isBoss ? 18 : 6; - else - modifierChance = !isBoss ? 12 : 4; + const modifierChance = this.gameMode.getEnemyModifierChance(isBoss); const party = this.getEnemyParty(); @@ -1708,7 +1704,7 @@ export default class BattleScene extends Phaser.Scene { } if (isBoss) count = Math.max(count, Math.floor(chances / 2)); - getEnemyModifierTypesForWave(waveIndex, count, [ enemyPokemon ], this.currentBattle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD, this.gameMode) + getEnemyModifierTypesForWave(waveIndex, count, [ enemyPokemon ], this.currentBattle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD) .map(mt => mt.newModifier(enemyPokemon).add(this.enemyModifiers, false, this)); }); diff --git a/src/battle.ts b/src/battle.ts index 246b7643202..6eafbf311ce 100644 --- a/src/battle.ts +++ b/src/battle.ts @@ -6,7 +6,7 @@ import Trainer from "./field/trainer"; import { Species } from "./data/enums/species"; import { Moves } from "./data/enums/moves"; import { TrainerType } from "./data/enums/trainer-type"; -import { GameMode } from "./game-mode"; +import { GameMode, GameModes } from "./game-mode"; import { BattleSpec } from "./enums/battle-spec"; import { PlayerGender } from "./system/game-data"; import { PokemonHeldItemModifier } from "./modifier/modifier"; @@ -57,7 +57,7 @@ export default class Battle { public battleSeed: string; private battleSeedState: string; - constructor(gameMode: integer, waveIndex: integer, battleType: BattleType, trainer: Trainer, double: boolean) { + constructor(gameMode: GameMode, waveIndex: integer, battleType: BattleType, trainer: Trainer, double: boolean) { this.gameMode = gameMode; this.waveIndex = waveIndex; this.battleType = battleType; @@ -80,7 +80,7 @@ export default class Battle { private initBattleSpec(): void { let spec = BattleSpec.DEFAULT; - if (this.gameMode === GameMode.CLASSIC) { + if (this.gameMode.isClassic) { if (this.waveIndex === 200) spec = BattleSpec.FINAL_BOSS; } @@ -88,17 +88,20 @@ export default class Battle { } private getLevelForWave(): integer { - let baseLevel = 1 + this.waveIndex / 2 + Math.pow(this.waveIndex / 25, 2); + let levelWaveIndex = this.waveIndex; + if (this.gameMode.isDaily) + levelWaveIndex += 30 + Math.floor(this.waveIndex / 5); + let baseLevel = 1 + levelWaveIndex / 2 + Math.pow(levelWaveIndex / 25, 2); const bossMultiplier = 1.2; if (!(this.waveIndex % 10)) { 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(this.waveIndex / 10)); + return ret + Math.round(Phaser.Math.RND.realInRange(-1, 1) * Math.floor(levelWaveIndex / 10)); } - const deviation = 10 / this.waveIndex; + const deviation = 10 / levelWaveIndex; return Math.max(Math.round(baseLevel + Math.abs(this.randSeedGaussForLevel(deviation))), 1); } @@ -142,7 +145,7 @@ export default class Battle { if (!this.started && this.trainer.config.encounterBgm && this.trainer.getEncounterMessages()?.length) return `encounter_${this.trainer.getEncounterBgm()}`; return this.trainer.getBattleBgm(); - } else if (this.gameMode === GameMode.CLASSIC && this.waveIndex > 195 && this.battleSpec !== BattleSpec.FINAL_BOSS) + } else if (this.gameMode.isClassic && this.waveIndex > 195 && this.battleSpec !== BattleSpec.FINAL_BOSS) return 'end_summit'; for (let pokemon of battlers) { if (this.battleSpec === BattleSpec.FINAL_BOSS) { @@ -159,7 +162,7 @@ export default class Battle { } } - if (scene.gameMode === GameMode.CLASSIC && this.waveIndex <= 4) + if (scene.gameMode.isClassic && this.waveIndex <= 4) return 'battle_wild'; return null; diff --git a/src/field/arena.ts b/src/field/arena.ts index c794d94e50b..033b39f101e 100644 --- a/src/field/arena.ts +++ b/src/field/arena.ts @@ -11,7 +11,7 @@ import { Type } from "../data/type"; import Move from "../data/move"; import { ArenaTag, ArenaTagSide, getArenaTag } from "../data/arena-tag"; import { ArenaTagType } from "../data/enums/arena-tag-type"; -import { GameMode } from "../game-mode"; +import { GameModes } from "../game-mode"; import { TrainerType } from "../data/enums/trainer-type"; import { BattlerIndex } from "../battle"; import { Moves } from "../data/enums/moves"; @@ -55,7 +55,7 @@ export class Arena { randomSpecies(waveIndex: integer, level: integer, attempt?: integer): PokemonSpecies { const isBoss = !!this.scene.getEncounterBossSegments(waveIndex, level) && !!this.pokemonPool[BiomePoolTier.BOSS].length - && (this.biomeType !== Biome.END || this.scene.gameMode === GameMode.CLASSIC || waveIndex % 250 === 0); + && (this.biomeType !== Biome.END || this.scene.gameMode.isClassic || this.scene.gameMode.isWaveFinal(waveIndex)); 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 @@ -125,7 +125,7 @@ export class Arena { randomTrainerType(waveIndex: integer): TrainerType { const isBoss = (waveIndex % 30) === 20 && !!this.trainerPool[BiomePoolTier.BOSS].length - && (this.biomeType !== Biome.END || this.scene.gameMode === GameMode.CLASSIC || waveIndex % 250 === 0); + && (this.biomeType !== Biome.END || this.scene.gameMode.isClassic || this.scene.gameMode.isWaveFinal(waveIndex)); 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 5465cfe74b8..0a79319aba5 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -32,7 +32,7 @@ import { BattleSpec } from "../enums/battle-spec"; import { Mode } from '../ui/ui'; import PartyUiHandler, { PartyOption, PartyUiMode } from '../ui/party-ui-handler'; import SoundFade from 'phaser3-rex-plugins/plugins/soundfade'; -import { GameMode } from '../game-mode'; +import { GameModes } from '../game-mode'; import { LevelMoves } from '../data/pokemon-level-moves'; import { DamageAchv, achvs } from '../system/achv'; import { DexAttr, StarterMoveset } from '../system/game-data'; @@ -180,7 +180,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { this.metBiome = scene.currentBattle ? scene.arena.biomeType : -1; this.pokerus = false; - const fused = new Utils.BooleanHolder(scene.gameMode === GameMode.SPLICED_ENDLESS); + const fused = new Utils.BooleanHolder(scene.gameMode.isSplicedOnly); if (!fused.value && !this.isPlayer() && !this.hasTrainer()) this.scene.applyModifier(EnemyFusionChanceModifier, false, fused); @@ -536,7 +536,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const fusionBaseStats = this.getFusionSpeciesForm().baseStats; for (let s = 0; s < this.stats.length; s++) baseStats[s] = Math.ceil((baseStats[s] + fusionBaseStats[s]) / 2); - } else if (this.scene.gameMode === GameMode.SPLICED_ENDLESS) { + } else if (this.scene.gameMode.isSplicedOnly) { for (let s = 0; s < this.stats.length; s++) baseStats[s] = Math.ceil(baseStats[s] / 2); } diff --git a/src/game-mode.ts b/src/game-mode.ts index 430a6d1b3fa..962236c6af3 100644 --- a/src/game-mode.ts +++ b/src/game-mode.ts @@ -1,11 +1,77 @@ -export enum GameMode { +export enum GameModes { + DAILY, CLASSIC, ENDLESS, SPLICED_ENDLESS } -export const gameModeNames = { - [GameMode.CLASSIC]: 'Classic', - [GameMode.ENDLESS]: 'Endless', - [GameMode.SPLICED_ENDLESS]: 'Endless (Spliced)' -}; \ No newline at end of file +interface GameModeConfig { + isClassic?: boolean; + isEndless?: boolean; + isDaily?: boolean; + hasTrainers?: boolean; + hasFixedBattles?: boolean; + hasRandomBiomes?: boolean; + hasRandomBosses?: boolean; + isSplicedOnly?: boolean; +} + +export class GameMode implements GameModeConfig { + public modeId: GameModes; + public isClassic: boolean; + public isEndless: boolean; + public isDaily: boolean; + public hasTrainers: boolean; + public hasFixedBattles: boolean; + public hasRandomBiomes: boolean; + public hasRandomBosses: boolean; + public isSplicedOnly: boolean; + + constructor(modeId: GameModes, config: GameModeConfig) { + this.modeId = modeId; + Object.assign(this, config); + } + + isWaveFinal(waveIndex: integer): boolean { + switch (this.modeId) { + case GameModes.DAILY: + return waveIndex === 50; + case GameModes.CLASSIC: + return waveIndex === 200; + case GameModes.ENDLESS: + case GameModes.SPLICED_ENDLESS: + return !(waveIndex % 250); + } + } + + getEnemyModifierChance(isBoss: boolean): integer { + switch (this.modeId) { + case GameModes.DAILY: + case GameModes.CLASSIC: + return !isBoss ? 18 : 6; + case GameModes.ENDLESS: + case GameModes.SPLICED_ENDLESS: + return !isBoss ? 12 : 4; + } + } + + getName(): string { + switch (this.modeId) { + case GameModes.DAILY: + return 'Daily Run'; + case GameModes.CLASSIC: + return 'Classic'; + case GameModes.ENDLESS: + return 'Endless'; + case GameModes.SPLICED_ENDLESS: + return 'Endless (Spliced)'; + } + } +} + +export const gameModes = Object.freeze({ + [GameModes.DAILY]: new GameMode(GameModes.DAILY, { isDaily: true, hasTrainers: true }), + [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 }) +}); \ No newline at end of file diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index dd60abcd797..dc695573d1f 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -12,7 +12,7 @@ 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 { GameMode } from '../game-mode'; +import { GameModes } from '../game-mode'; import { StatusEffect, getStatusEffectDescriptor } from '../data/status-effect'; import { SpeciesFormKey } from '../data/pokemon-species'; import BattleScene from '../battle-scene'; @@ -951,7 +951,7 @@ const modifierPool = { }, 3), new WeightedModifierType(modifierTypes.SUPER_LURE, 4), new WeightedModifierType(modifierTypes.NUGGET, 5), - new WeightedModifierType(modifierTypes.MAP, (party: Pokemon[]) => party[0].scene.gameMode === GameMode.CLASSIC ? 1 : 0, 1), + new WeightedModifierType(modifierTypes.MAP, (party: Pokemon[]) => party[0].scene.gameMode.isClassic ? 1 : 0, 1), new WeightedModifierType(modifierTypes.TM_GREAT, 2), new WeightedModifierType(modifierTypes.MEMORY_MUSHROOM, (party: Pokemon[]) => { if (!party.find(p => p.getLearnableLevelMoves().length)) @@ -961,8 +961,8 @@ const modifierPool = { }, 4), new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 3), new WeightedModifierType(modifierTypes.TERA_SHARD, 1), - new WeightedModifierType(modifierTypes.DNA_SPLICERS, (party: Pokemon[]) => party[0].scene.gameMode === GameMode.SPLICED_ENDLESS && party.filter(p => !p.fusionSpecies).length > 1 ? 4 : 0), - new WeightedModifierType(modifierTypes.REVERSE_DNA_SPLICERS, (party: Pokemon[]) => party[0].scene.gameMode === GameMode.SPLICED_ENDLESS && party.filter(p => p.fusionSpecies).length ? 6 : 0), + new WeightedModifierType(modifierTypes.DNA_SPLICERS, (party: Pokemon[]) => party[0].scene.gameMode.isSplicedOnly && party.filter(p => !p.fusionSpecies).length > 1 ? 4 : 0), + new WeightedModifierType(modifierTypes.REVERSE_DNA_SPLICERS, (party: Pokemon[]) => party[0].scene.gameMode.isSplicedOnly && party.filter(p => p.fusionSpecies).length ? 6 : 0), ].map(m => { m.setTier(ModifierTier.GREAT); return m; }), [ModifierTier.ULTRA]: [ new WeightedModifierType(modifierTypes.ULTRA_BALL, 24), @@ -988,7 +988,7 @@ const modifierPool = { new WeightedModifierType(modifierTypes.EXP_SHARE, 12), new WeightedModifierType(modifierTypes.EXP_BALANCE, 1), new WeightedModifierType(modifierTypes.TERA_ORB, (party: Pokemon[]) => Math.min(Math.max(Math.floor(party[0].scene.currentBattle.waveIndex / 50) * 2, 1), 4), 4), - new WeightedModifierType(modifierTypes.REVERSE_DNA_SPLICERS, (party: Pokemon[]) => party[0].scene.gameMode !== GameMode.SPLICED_ENDLESS && party.filter(p => p.fusionSpecies).length ? 3 : 0, 3), + new WeightedModifierType(modifierTypes.REVERSE_DNA_SPLICERS, (party: Pokemon[]) => !party[0].scene.gameMode.isSplicedOnly && party.filter(p => p.fusionSpecies).length ? 3 : 0, 3), new WeightedModifierType(modifierTypes.VOUCHER, 3), ].map(m => { m.setTier(ModifierTier.ULTRA); return m; }), [ModifierTier.ROGUE]: [ @@ -1013,7 +1013,7 @@ const modifierPool = { new WeightedModifierType(modifierTypes.SHINY_CHARM, 18), new WeightedModifierType(modifierTypes.HEALING_CHARM, 18), new WeightedModifierType(modifierTypes.VOUCHER_PLUS, 8), - new WeightedModifierType(modifierTypes.DNA_SPLICERS, (party: Pokemon[]) => party[0].scene.gameMode !== GameMode.SPLICED_ENDLESS && party.filter(p => !p.fusionSpecies).length > 1 ? 24 : 0, 24), + 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]: [ @@ -1250,7 +1250,7 @@ export function getEnemyBuffModifierForWave(tier: ModifierTier, enemyModifiers: return modifier; } -export function getEnemyModifierTypesForWave(waveIndex: integer, count: integer, party: EnemyPokemon[], poolType: ModifierPoolType.WILD | ModifierPoolType.TRAINER, gameMode: GameMode): PokemonHeldItemModifierType[] { +export function getEnemyModifierTypesForWave(waveIndex: integer, count: integer, party: EnemyPokemon[], poolType: ModifierPoolType.WILD | ModifierPoolType.TRAINER): PokemonHeldItemModifierType[] { const ret = new Array(count).fill(0).map(() => getNewModifierTypeOption(party, poolType).type as PokemonHeldItemModifierType); if (!(waveIndex % 1000)) ret.push(getModifierType(modifierTypes.MINI_BLACK_HOLE) as PokemonHeldItemModifierType); diff --git a/src/phases.ts b/src/phases.ts index cd0205621cc..6483aee38fb 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -35,7 +35,7 @@ import { Unlockables, getUnlockableName } from "./system/unlockables"; import { getBiomeKey } from "./field/arena"; import { BattleType, BattlerIndex, TurnCommand } from "./battle"; import { BattleSpec } from "./enums/battle-spec"; -import { GameMode } from "./game-mode"; +import { GameModes } from "./game-mode"; import { Species } from "./data/enums/species"; import { HealAchv, LevelAchv, MoneyAchv, achvs } from "./system/achv"; import { trainerConfigs } from "./data/trainer-config"; @@ -294,7 +294,7 @@ export class SelectStarterPhase extends Phase { starterPokemon.tryPopulateMoveset(starter.moveset); if (starter.pokerus) starterPokemon.pokerus = true; - if (this.scene.gameMode === GameMode.SPLICED_ENDLESS) + if (this.scene.gameMode.isSplicedOnly) starterPokemon.generateFusionSpecies(true); starterPokemon.setVisible(false); party.push(starterPokemon); @@ -305,7 +305,7 @@ export class SelectStarterPhase extends Phase { this.scene.ui.setMode(Mode.MESSAGE).then(() => { SoundFade.fadeOut(this.scene, this.scene.sound.get('menu'), 500, true); this.scene.time.delayedCall(500, () => this.scene.playBgm()); - if (this.scene.gameMode === GameMode.CLASSIC) + if (this.scene.gameMode.isClassic) this.scene.gameData.gameStats.classicSessionsPlayed++; else this.scene.gameData.gameStats.endlessSessionsPlayed++; @@ -482,7 +482,7 @@ export class EncounterPhase extends BattlePhase { } if (enemyPokemon.species.speciesId === Species.ETERNATUS) { - if (this.scene.gameMode === GameMode.CLASSIC && (battle.battleSpec === BattleSpec.FINAL_BOSS || !(battle.waveIndex % 250))) { + if (this.scene.gameMode.isClassic && (battle.battleSpec === BattleSpec.FINAL_BOSS || this.scene.gameMode.isWaveFinal(battle.waveIndex))) { if (battle.battleSpec !== BattleSpec.FINAL_BOSS) { enemyPokemon.formIndex = 1; enemyPokemon.updateScale(); @@ -797,9 +797,9 @@ export class SelectBiomePhase extends BattlePhase { this.end(); }; - if (this.scene.gameMode === GameMode.CLASSIC && this.scene.currentBattle.waveIndex === this.scene.finalWave - 9) + if (this.scene.gameMode.isClassic && this.scene.gameMode.isWaveFinal(this.scene.currentBattle.waveIndex + 9)) setNextBiome(Biome.END); - else if (this.scene.gameMode !== GameMode.CLASSIC) + else if (this.scene.gameMode.hasRandomBiomes) setNextBiome(this.generateNextBiome()); else if (Array.isArray(biomeLinks[currentBiome])) { let biomes: Biome[]; @@ -1775,7 +1775,7 @@ export class BattleEndPhase extends BattlePhase { this.scene.gameData.gameStats.battles++; if (this.scene.currentBattle.trainer) this.scene.gameData.gameStats.trainersDefeated++; - if (this.scene.gameMode === GameMode.ENDLESS && this.scene.currentBattle.waveIndex + 1 > this.scene.gameData.gameStats.highestEndlessWave) + if (this.scene.gameMode.isEndless && this.scene.currentBattle.waveIndex + 1 > this.scene.gameData.gameStats.highestEndlessWave) this.scene.gameData.gameStats.highestEndlessWave = this.scene.currentBattle.waveIndex + 1; for (let pokemon of this.scene.getField()) { @@ -2844,16 +2844,16 @@ export class VictoryPhase extends PokemonPhase { if (this.scene.currentBattle.battleType === BattleType.TRAINER) this.scene.pushPhase(new TrainerVictoryPhase(this.scene)); this.scene.pushPhase(new EggLapsePhase(this.scene)); - if (this.scene.gameMode !== GameMode.CLASSIC || this.scene.currentBattle.waveIndex < this.scene.finalWave) { + 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 { - const superExpWave = this.scene.gameMode === GameMode.CLASSIC ? 20 : 10; + 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)); if (this.scene.currentBattle.waveIndex <= 150 && !(this.scene.currentBattle.waveIndex % 50)) this.scene.pushPhase(new ModifierRewardPhase(this.scene, modifierTypes.GOLDEN_POKEBALL)); - if (this.scene.gameMode !== GameMode.CLASSIC && !(this.scene.currentBattle.waveIndex % 50)) { + if (this.scene.gameMode.isEndless && !(this.scene.currentBattle.waveIndex % 50)) { this.scene.pushPhase(new ModifierRewardPhase(this.scene, !(this.scene.currentBattle.waveIndex % 250) ? modifierTypes.VOUCHER_PREMIUM : modifierTypes.VOUCHER_PLUS)); this.scene.pushPhase(new AddEnemyBuffModifierPhase(this.scene)); } diff --git a/src/system/game-data.ts b/src/system/game-data.ts index bc8f92ea205..f35a7b96487 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -8,7 +8,7 @@ import PokemonData from "./pokemon-data"; import PersistentModifierData from "./modifier-data"; import ArenaData from "./arena-data"; import { Unlockables } from "./unlockables"; -import { GameMode } from "../game-mode"; +import { GameModes, gameModes } from "../game-mode"; import { BattleType } from "../battle"; import TrainerData from "./trainer-data"; import { trainerConfigs } from "../data/trainer-config"; @@ -76,7 +76,7 @@ interface SystemSaveData { interface SessionSaveData { seed: string; playTime: integer; - gameMode: GameMode; + gameMode: GameModes; party: PokemonData[]; enemyParty: PokemonData[]; modifiers: PersistentModifierData[]; @@ -458,7 +458,7 @@ export class GameData { const sessionData = { seed: scene.seed, playTime: scene.sessionPlayTime, - gameMode: scene.gameMode, + gameMode: scene.gameMode.modeId, party: scene.getParty().map(p => new PokemonData(p)), enemyParty: scene.getEnemyParty().map(p => new PokemonData(p)), modifiers: scene.findModifiers(() => true).map(m => new PersistentModifierData(m, true)), @@ -508,7 +508,7 @@ export class GameData { scene.sessionPlayTime = sessionData.playTime || 0; - scene.gameMode = sessionData.gameMode || GameMode.CLASSIC; + scene.gameMode = gameModes[sessionData.gameMode || GameModes.CLASSIC]; const loadPokemonAssets: Promise[] = []; diff --git a/src/system/session-history.ts b/src/system/session-history.ts index 2b00ad1685d..ed991190369 100644 --- a/src/system/session-history.ts +++ b/src/system/session-history.ts @@ -1,4 +1,4 @@ -import { GameMode } from "../game-mode"; +import { GameModes } from "../game-mode"; import PokemonData from "./pokemon-data"; import PersistentModifierData from "./modifier-data"; @@ -12,7 +12,7 @@ export interface SessionHistory { seed: string; playTime: integer; result: SessionHistoryResult, - gameMode: GameMode; + gameMode: GameModes; party: PokemonData[]; modifiers: PersistentModifierData[]; money: integer; diff --git a/src/system/unlockables.ts b/src/system/unlockables.ts index 22fed6ffc6b..a186b2bec02 100644 --- a/src/system/unlockables.ts +++ b/src/system/unlockables.ts @@ -1,4 +1,4 @@ -import { GameMode, gameModeNames } from "../game-mode"; +import { GameModes, gameModes } from "../game-mode"; export enum Unlockables { ENDLESS_MODE, @@ -9,10 +9,10 @@ export enum Unlockables { export function getUnlockableName(unlockable: Unlockables) { switch (unlockable) { case Unlockables.ENDLESS_MODE: - return `${gameModeNames[GameMode.ENDLESS]} Mode`; + return `${gameModes[GameModes.ENDLESS].getName()} Mode`; case Unlockables.MINI_BLACK_HOLE: return 'Mini Black Hole'; case Unlockables.SPLICED_ENDLESS_MODE: - return `${gameModeNames[GameMode.SPLICED_ENDLESS]} Mode`; + return `${gameModes[GameModes.SPLICED_ENDLESS].getName()} Mode`; } } \ No newline at end of file diff --git a/src/ui/battle-info.ts b/src/ui/battle-info.ts index e4cca89a7db..baac2d94b4b 100644 --- a/src/ui/battle-info.ts +++ b/src/ui/battle-info.ts @@ -282,8 +282,10 @@ export default class BattleInfo extends Phaser.GameObjects.Container { this.lastTeraType = teraType; } - if (nameUpdated || teraTypeUpdated) + if (nameUpdated || teraTypeUpdated) { + this.splicedIcon.setVisible(!!pokemon.fusionSpecies); this.splicedIcon.setPositionRelative(this.nameText, this.nameText.displayWidth + this.genderText.displayWidth + 1 + (this.teraIcon.visible ? this.teraIcon.displayWidth + 1 : 0), 1.5); + } if (this.lastStatus !== (pokemon.status?.effect || StatusEffect.NONE)) { this.lastStatus = pokemon.status?.effect || StatusEffect.NONE; diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 029d333b6a8..5a4e6d9a102 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -6,7 +6,7 @@ import { Mode } from "./ui"; import MessageUiHandler from "./message-ui-handler"; import { Gender, getGenderColor, getGenderSymbol } from "../data/gender"; import { allAbilities } from "../data/ability"; -import { GameMode, gameModeNames } from "../game-mode"; +import { GameModes, gameModes } from "../game-mode"; import { Unlockables } from "../system/unlockables"; import { GrowthRate, getGrowthRateColor } from "../data/exp"; import { DexAttr, DexEntry, StarterFormMoveData, StarterMoveset } from "../system/game-data"; @@ -1204,8 +1204,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler { ui.showText('Begin with these Pokémon?', null, () => { ui.setModeWithoutClear(Mode.CONFIRM, () => { - const startRun = (gameMode: GameMode) => { - this.scene.gameMode = gameMode; + const startRun = (gameMode: GameModes) => { + this.scene.gameMode = gameModes[gameMode]; ui.setMode(Mode.STARTER_SELECT); const thisObj = this; const originalStarterSelectCallback = this.starterSelectCallback; @@ -1225,18 +1225,18 @@ export default class StarterSelectUiHandler extends MessageUiHandler { ui.setMode(Mode.STARTER_SELECT); const options = [ { - label: gameModeNames[GameMode.CLASSIC], - handler: () => startRun(GameMode.CLASSIC) + label: gameModes[GameModes.CLASSIC].getName(), + handler: () => startRun(GameModes.CLASSIC) }, { - label: gameModeNames[GameMode.ENDLESS], - handler: () => startRun(GameMode.ENDLESS) + label: gameModes[GameModes.ENDLESS].getName(), + handler: () => startRun(GameModes.ENDLESS) } ]; if (this.scene.gameData.unlocks[Unlockables.SPLICED_ENDLESS_MODE]) { options.push({ - label: gameModeNames[GameMode.SPLICED_ENDLESS], - handler: () => startRun(GameMode.SPLICED_ENDLESS) + label: gameModes[GameModes.SPLICED_ENDLESS].getName(), + handler: () => startRun(GameModes.SPLICED_ENDLESS) }); } options.push({ @@ -1245,7 +1245,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { }); ui.showText('Select a game mode.', null, () => ui.setModeWithoutClear(Mode.OPTION_SELECT, { options: options, yOffset: 19 })); } else - startRun(GameMode.CLASSIC); + startRun(GameModes.CLASSIC); }, cancel, null, null, 19); });