From 13e1fd3b0aedcbc21ec7e7882ba6d003b5ae4c5d Mon Sep 17 00:00:00 2001 From: RedstonewolfX <108761527+RedstonewolfX@users.noreply.github.com> Date: Tue, 16 Jul 2024 16:38:13 -0400 Subject: [PATCH] Disable Shiny Luck in Daily Disables shiny luck in daily (can be turned back on in Settings) * Shinies can still appear and do have their custom sprites, they just don't affect rolls. Added a currently nonfunctional setting to change how the quickload button appears (or disable it, locking it to "Continue") Added an in-progress UI for displaying Daily Runs (currently disabled) --- src/battle-scene.ts | 30 ++- src/logger.ts | 64 +++++- src/modifier/modifier-type.ts | 37 ++-- src/phases.ts | 14 +- src/system/settings/settings.ts | 38 +++- src/ui/log-select-ui-handler.ts | 355 ++++++++++++++++++++++++++++++++ src/ui/ui.ts | 9 +- 7 files changed, 526 insertions(+), 21 deletions(-) create mode 100644 src/ui/log-select-ui-handler.ts diff --git a/src/battle-scene.ts b/src/battle-scene.ts index c42b16fc126..38691decd52 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -125,6 +125,8 @@ export default class BattleScene extends SceneBase { public menuChangesBiome: boolean = false; public showAutosaves: boolean = false; public doBiomePanels: boolean = false; + public disableDailyShinies: boolean = true; // Disables shiny luck in Daily Runs to prevent affecting RNG + public quickloadDisplayMode: string = "Dailies"; /** * Determines the condition for a notification should be shown for Candy Upgrades * - 0 = 'Off' @@ -903,6 +905,32 @@ export default class BattleScene extends SceneBase { return container; } + addPkIcon(pokemon: PokemonSpecies, form: integer = 0, x: number, y: number, originX: number = 0.5, originY: number = 0.5, ignoreOverride: boolean = false): Phaser.GameObjects.Container { + const container = this.add.container(x, y); + container.setName(`${pokemon.name}-icon`); + + const icon = this.add.sprite(0, 0, pokemon.getIconAtlasKey(form)); + icon.setName(`sprite-${pokemon.name}-icon`); + icon.setFrame(pokemon.getIconId(true)); + // Temporary fix to show pokemon's default icon if variant icon doesn't exist + if (icon.frame.name !== pokemon.getIconId(true)) { + console.log(`${pokemon.name}'s variant icon does not exist. Replacing with default.`); + icon.setTexture(pokemon.getIconAtlasKey(0)); + icon.setFrame(pokemon.getIconId(true)); + } + icon.setOrigin(0.5, 0); + + container.add(icon); + + if (originX !== 0.5) { + container.x -= icon.width * (originX - 0.5); + } + if (originY !== 0) { + container.y -= icon.height * originY; + } + + return container; + } setSeed(seed: string): void { this.seed = seed; @@ -2342,7 +2370,7 @@ export default class BattleScene extends SceneBase { if (isBoss) { count = Math.max(count, Math.floor(chances / 2)); } - getEnemyModifierTypesForWave(difficultyWaveIndex, count, [ enemyPokemon ], this.currentBattle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD, upgradeChance) + getEnemyModifierTypesForWave(difficultyWaveIndex, count, [ enemyPokemon ], this.currentBattle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD, upgradeChance, this) .map(mt => mt.newModifier(enemyPokemon).add(this.enemyModifiers, false, this)); }); diff --git a/src/logger.ts b/src/logger.ts index 282324ce32d..ca46c913d01 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -9,7 +9,7 @@ import { OptionSelectItem } from "./ui/abstact-option-select-ui-handler"; import { PokemonHeldItemModifier } from "./modifier/modifier"; import { getBiomeName, PokemonPools, SpeciesTree } from "./data/biomes"; import { Mode } from "./ui/ui"; -import { TitlePhase } from "./phases"; +import { parseSlotData, TitlePhase } from "./phases"; import Trainer from "./field/trainer"; import { Species } from "./enums/species"; import { GameMode, GameModes } from "./game-mode"; @@ -139,7 +139,14 @@ export function getLogs() { logs.pop() for (var i = 0; i < localStorage.length; i++) { if (localStorage.key(i).substring(0, 9) == "drpd_log:") { - logs.push(["drpd.json", localStorage.key(i), localStorage.key(i).substring(9), "drpd_items:" + localStorage.key(i).substring(9), "", ""]) + logs.push(["drpd.json", localStorage.key(i), localStorage.key(i).substring(9), "", "", ""]) + for (var j = 0; j < 5; j++) { + var D = parseSlotData(j) + if (D != undefined) + if (logs[logs.length - 1][2] == D.seed) { + logs[logs.length - 1][3] = j.toString() + } + } } } } @@ -1301,6 +1308,59 @@ export function generateEditOption(scene: BattleScene, i: integer, saves: any, p } return op; } +/** + * Generates a UI option to save a log to your device. + * @param i The slot number. Corresponds to an index in `logs`. + * @param saves Your session data. Used to label logs if they match one of your save slots. + * @returns A UI option. + */ +export function generateEditHandler(scene: BattleScene, logId: string, callback: Function) { + var i; + for (var j = 0; j < logs.length; j++) { + if (logs[j][2] == logId) { + i = j; + } + } + if (i == undefined) + return; // Failed to find a log + return (): boolean => { + rarityslot[1] = logs[i][1] + //scene.phaseQueue[0].end() + scene.ui.setMode(Mode.NAME_LOG, { + autofillfields: [ + (JSON.parse(localStorage.getItem(logs[i][1])) as DRPD).title, + (JSON.parse(localStorage.getItem(logs[i][1])) as DRPD).authors.join(", "), + (JSON.parse(localStorage.getItem(logs[i][1])) as DRPD).label, + ], + buttonActions: [ + () => { + console.log("Rename") + scene.ui.playSelect(); + callback() + }, + () => { + console.log("Export") + scene.ui.playSelect(); + downloadLogByID(i) + callback() + }, + () => { + console.log("Export to Sheets") + scene.ui.playSelect(); + downloadLogByIDToSheet(i) + callback() + }, + () => { + console.log("Delete") + scene.ui.playSelect(); + localStorage.removeItem(logs[i][1]) + callback() + } + ] + }); + return false; + } +} //#endregion diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 91702496c8d..09748ad4906 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -27,6 +27,7 @@ import { BattlerTagType } from "#enums/battler-tag-type"; import { BerryType } from "#enums/berry-type"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; +import { GameModes } from "#app/game-mode.js"; const outputModifierData = false; const useMaxWeightForOutput = false; @@ -1955,14 +1956,14 @@ export function getModifierTypeFuncById(id: string): ModifierTypeFunc { return modifierTypes[id]; } -export function getPlayerModifierTypeOptions(count: integer, party: PlayerPokemon[], modifierTiers?: ModifierTier[]): ModifierTypeOption[] { +export function getPlayerModifierTypeOptions(count: integer, party: PlayerPokemon[], modifierTiers?: ModifierTier[], scene?: BattleScene): ModifierTypeOption[] { const options: ModifierTypeOption[] = []; const retryCount = Math.min(count * 5, 50); new Array(count).fill(0).map((_, i) => { - let candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER, modifierTiers?.length > i ? modifierTiers[i] : undefined); + let candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER, modifierTiers?.length > i ? modifierTiers[i] : undefined, undefined, undefined, scene); let r = 0; while (options.length && ++r < retryCount && options.filter(o => o.type.name === candidate.type.name || o.type.group === candidate.type.group).length) { - candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER, candidate.type.tier, candidate.upgradeCount); + candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER, candidate.type.tier, candidate.upgradeCount, undefined, scene); } options.push(candidate); }); @@ -2017,11 +2018,11 @@ export function getPlayerShopModifierTypeOptionsForWave(waveIndex: integer, base export function getEnemyBuffModifierForWave(tier: ModifierTier, enemyModifiers: Modifiers.PersistentModifier[], scene: BattleScene): Modifiers.EnemyPersistentModifier { const tierStackCount = tier === ModifierTier.ULTRA ? 5 : tier === ModifierTier.GREAT ? 3 : 1; const retryCount = 50; - let candidate = getNewModifierTypeOption(null, ModifierPoolType.ENEMY_BUFF, tier); + let candidate = getNewModifierTypeOption(null, ModifierPoolType.ENEMY_BUFF, tier, undefined, undefined, scene); let r = 0; let matchingModifier: Modifiers.PersistentModifier; while (++r < retryCount && (matchingModifier = enemyModifiers.find(m => m.type.id === candidate.type.id)) && matchingModifier.getMaxStackCount(scene) < matchingModifier.stackCount + (r < 10 ? tierStackCount : 1)) { - candidate = getNewModifierTypeOption(null, ModifierPoolType.ENEMY_BUFF, tier); + candidate = getNewModifierTypeOption(null, ModifierPoolType.ENEMY_BUFF, tier, undefined, undefined, scene); } const modifier = candidate.type.newModifier() as Modifiers.EnemyPersistentModifier; @@ -2030,21 +2031,21 @@ export function getEnemyBuffModifierForWave(tier: ModifierTier, enemyModifiers: return modifier; } -export function getEnemyModifierTypesForWave(waveIndex: integer, count: integer, party: EnemyPokemon[], poolType: ModifierPoolType.WILD | ModifierPoolType.TRAINER, upgradeChance: integer = 0): PokemonHeldItemModifierType[] { - const ret = new Array(count).fill(0).map(() => getNewModifierTypeOption(party, poolType, undefined, upgradeChance && !Utils.randSeedInt(upgradeChance) ? 1 : 0).type as PokemonHeldItemModifierType); +export function getEnemyModifierTypesForWave(waveIndex: integer, count: integer, party: EnemyPokemon[], poolType: ModifierPoolType.WILD | ModifierPoolType.TRAINER, upgradeChance: integer = 0, scene?: BattleScene): PokemonHeldItemModifierType[] { + const ret = new Array(count).fill(0).map(() => getNewModifierTypeOption(party, poolType, undefined, upgradeChance && !Utils.randSeedInt(upgradeChance) ? 1 : 0, undefined, scene).type as PokemonHeldItemModifierType); if (!(waveIndex % 1000)) { ret.push(getModifierType(modifierTypes.MINI_BLACK_HOLE) as PokemonHeldItemModifierType); } return ret; } -export function getDailyRunStarterModifiers(party: PlayerPokemon[]): Modifiers.PokemonHeldItemModifier[] { +export function getDailyRunStarterModifiers(party: PlayerPokemon[], scene?: BattleScene): Modifiers.PokemonHeldItemModifier[] { const ret: Modifiers.PokemonHeldItemModifier[] = []; for (const 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; + const modifier = getNewModifierTypeOption(party, ModifierPoolType.DAILY_STARTER, tier, undefined, undefined, scene).type.newModifier(p) as Modifiers.PokemonHeldItemModifier; ret.push(modifier); } } @@ -2052,7 +2053,7 @@ export function getDailyRunStarterModifiers(party: PlayerPokemon[]): Modifiers.P return ret; } -function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, tier?: ModifierTier, upgradeCount?: integer, retryCount: integer = 0): ModifierTypeOption { +function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, tier?: ModifierTier, upgradeCount?: integer, retryCount: integer = 0, scene?: BattleScene): ModifierTypeOption { const player = !poolType; const pool = getModifierPoolForType(poolType); let thresholds: object; @@ -2079,7 +2080,12 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, upgradeCount = 0; } if (player && tierValue) { - const partyLuckValue = getPartyLuckValue(party); + var partyLuckValue = getPartyLuckValue(party); + if (scene) { + if (scene.gameMode.modeId == GameModes.DAILY && scene.disableDailyShinies) { + partyLuckValue = 0 + } + } const upgradeOdds = Math.floor(128 / ((partyLuckValue + 4) / 4)); let upgraded = false; do { @@ -2104,7 +2110,12 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, } else if (upgradeCount === undefined && player) { upgradeCount = 0; if (tier < ModifierTier.MASTER) { - const partyShinyCount = party.filter(p => p.isShiny() && !p.isFainted()).length; + var partyShinyCount = party.filter(p => p.isShiny() && !p.isFainted()).length; + if (scene) { + if (scene.gameMode.modeId == GameModes.DAILY && scene.disableDailyShinies) { + partyShinyCount = 0 + } + } const upgradeOdds = Math.floor(32 / ((partyShinyCount + 2) / 2)); while (modifierPool.hasOwnProperty(tier + upgradeCount + 1) && modifierPool[tier + upgradeCount + 1].length) { if (!Utils.randSeedInt(upgradeOdds)) { @@ -2146,7 +2157,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, if (player) { console.log(ModifierTier[tier], upgradeCount); } - return getNewModifierTypeOption(party, poolType, tier, upgradeCount, ++retryCount); + return getNewModifierTypeOption(party, poolType, tier, upgradeCount, ++retryCount, scene); } } diff --git a/src/phases.ts b/src/phases.ts index 6345fb6e83a..7d22f02d4ab 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -652,6 +652,18 @@ export class TitlePhase extends Phase { handler: () => { this.scene.biomeChangeMode = false return this.logRenameMenu() + /* + this.scene.ui.setOverlayMode(Mode.LOG_HANDLER, + (k: string) => { + if (k === undefined) { + return this.showOptions(); + } + console.log(k) + }, () => { + this.showOptions(); + }); + return true; + */ } }) options.push({ @@ -6496,7 +6508,7 @@ export class SelectModifierPhase extends BattlePhase { } getModifierTypeOptions(modifierCount: integer): ModifierTypeOption[] { - return getPlayerModifierTypeOptions(modifierCount, this.scene.getParty(), this.scene.lockModifierTiers ? this.modifierTiers : undefined); + return getPlayerModifierTypeOptions(modifierCount, this.scene.getParty(), this.scene.lockModifierTiers ? this.modifierTiers : undefined, this.scene); } addModifier(modifier: Modifier): Promise { diff --git a/src/system/settings/settings.ts b/src/system/settings/settings.ts index 611ed8f15ad..5bf04301dfc 100644 --- a/src/system/settings/settings.ts +++ b/src/system/settings/settings.ts @@ -103,7 +103,10 @@ export const SettingKeys = { LazyReloads: "FLAG_EVERY_RESET_AS_RELOAD", FancyBiome: "FANCY_BIOMES", ShowAutosaves: "SHOW_AUTOSAVES", - BiomePanels: "BIOME_PANELS" + TitleScreenContinueMode: "TITLE_SCREEN_QUICKLOAD", + BiomePanels: "BIOME_PANELS", + DailyShinyLuck: "DAILY_LUCK", + QuickloadDisplay: "QUICKLOAD_MODE" }; /** @@ -192,6 +195,35 @@ export const Setting: Array = [ default: 0, type: SettingType.GENERAL, }, + { + key: SettingKeys.TitleScreenContinueMode, + label: "Quick Load", + options: [{ + label: "Off", + value: "Off" // Shows "Continue" button on the home screen + }, { + label: "Daily", + value: "Daily" // Shows the last played Daily Run, or the last run if there are no Daily Runs + }, { + label: "Dailies", + value: "Dailies" // Shows all Daily Runs, or the last run if there are no Daily Runs + }, { + label: "Latest", + value: "Latest" // Shows the last run + }, { + label: "Both", + value: "Both" // Shows the last run and the last Daily Run, or only the last played game if it is a Daily Run + }], + default: 2, + type: SettingType.GENERAL, + }, + { + key: SettingKeys.DailyShinyLuck, + label: "Daily Shiny Luck", + options: OFF_ON, + default: 0, + type: SettingType.GENERAL, + }, { key: SettingKeys.HP_Bar_Speed, label: i18next.t("settings:hpBarSpeed"), @@ -688,6 +720,10 @@ export function setSetting(scene: BattleScene, setting: string, value: integer): scene.showAutosaves = Setting[index].options[value].value == "On" case SettingKeys.BiomePanels: scene.doBiomePanels = Setting[index].options[value].value == "On" + case SettingKeys.DailyShinyLuck: + scene.disableDailyShinies = Setting[index].options[value].value == "Off" + case SettingKeys.QuickloadDisplay: + scene.quickloadDisplayMode = Setting[index].options[value].value; case SettingKeys.Skip_Seen_Dialogues: scene.skipSeenDialogues = Setting[index].options[value].value === "On"; break; diff --git a/src/ui/log-select-ui-handler.ts b/src/ui/log-select-ui-handler.ts new file mode 100644 index 00000000000..bd5d8057f01 --- /dev/null +++ b/src/ui/log-select-ui-handler.ts @@ -0,0 +1,355 @@ +import i18next from "i18next"; +import BattleScene from "../battle-scene"; +import { Button } from "#enums/buttons"; +import { GameMode } from "../game-mode"; +import { PokemonHeldItemModifier } from "../modifier/modifier"; +import { SessionSaveData } from "../system/game-data"; +import PokemonData from "../system/pokemon-data"; +import * as Utils from "../utils"; +import MessageUiHandler from "./message-ui-handler"; +import { TextStyle, addTextObject } from "./text"; +import { Mode } from "./ui"; +import { addWindow } from "./ui-theme"; +import * as LoggerTools from "../logger" +import { loggedInUser } from "#app/account.js"; +import { allpanels, biomePanelIDs } from "../loading-scene" +import { getBiomeName } from "#app/data/biomes.js"; +import { Species } from "#app/enums/species.js"; +import { getPokemonSpecies, getPokemonSpeciesForm } from "#app/data/pokemon-species.js"; + +const sessionSlotCount = 5; + +export type LogSelectCallback = (key: string) => void; + +export default class LogSelectUiHandler extends MessageUiHandler { + + private saveSlotSelectContainer: Phaser.GameObjects.Container; + private sessionSlotsContainer: Phaser.GameObjects.Container; + private saveSlotSelectMessageBox: Phaser.GameObjects.NineSlice; + private saveSlotSelectMessageBoxContainer: Phaser.GameObjects.Container; + private sessionSlots: SessionSlot[]; + + private selectCallback: LogSelectCallback; + + private scrollCursor: integer = 0; + + private cursorObj: Phaser.GameObjects.NineSlice; + + private sessionSlotsContainerInitialY: number; + + constructor(scene: BattleScene) { + super(scene, Mode.LOG_HANDLER); + } + + setup() { + const ui = this.getUi(); + + this.saveSlotSelectContainer = this.scene.add.container(0, 0); + this.saveSlotSelectContainer.setVisible(false); + ui.add(this.saveSlotSelectContainer); + + const loadSessionBg = this.scene.add.rectangle(0, 0, this.scene.game.canvas.width / 6, -this.scene.game.canvas.height / 6, 0x006860); + loadSessionBg.setOrigin(0, 0); + this.saveSlotSelectContainer.add(loadSessionBg); + + this.sessionSlotsContainerInitialY = -this.scene.game.canvas.height / 6 + 8; + + this.sessionSlotsContainer = this.scene.add.container(8, this.sessionSlotsContainerInitialY); + this.saveSlotSelectContainer.add(this.sessionSlotsContainer); + + this.saveSlotSelectMessageBoxContainer = this.scene.add.container(0, 0); + this.saveSlotSelectMessageBoxContainer.setVisible(false); + this.saveSlotSelectContainer.add(this.saveSlotSelectMessageBoxContainer); + + this.saveSlotSelectMessageBox = addWindow(this.scene, 1, -1, 318, 28); + this.saveSlotSelectMessageBox.setOrigin(0, 1); + this.saveSlotSelectMessageBoxContainer.add(this.saveSlotSelectMessageBox); + + this.message = addTextObject(this.scene, 8, 8, "", TextStyle.WINDOW, { maxLines: 2 }); + this.message.setOrigin(0, 0); + this.saveSlotSelectMessageBoxContainer.add(this.message); + + this.sessionSlots = []; + } + + show(args: any[]): boolean { + if ((args.length < 1 || !(args[0] instanceof Function))) { + return false; + } + + super.show(args); + + this.selectCallback = args[0] as LogSelectCallback; + + this.saveSlotSelectContainer.setVisible(true); + this.populateSessionSlots(); + this.setScrollCursor(0); + this.setCursor(0); + + return true; + } + + processInput(button: Button): boolean { + const ui = this.getUi(); + + let success = false; + let error = false; + + if (button === Button.ACTION || button === Button.CANCEL) { + const originalCallback = this.selectCallback; + if (button === Button.ACTION) { + const cursor = this.cursor + this.scrollCursor; + this.selectCallback = null; + originalCallback(this.sessionSlots[cursor].key); + success = true; + } else { + this.selectCallback = null; + originalCallback(undefined); + success = true; + } + } else { + switch (button) { + case Button.UP: + if (this.cursor) { + success = this.setCursor(this.cursor - 1); + } else if (this.scrollCursor) { + success = this.setScrollCursor(this.scrollCursor - 1); + } + break; + case Button.DOWN: + if (this.cursor < 2) { + success = this.setCursor(this.cursor + 1); + } else if (this.scrollCursor < this.sessionSlots.length - 3) { + success = this.setScrollCursor(this.scrollCursor + 1); + } + break; + } + } + + if (success) { + ui.playSelect(); + } else if (error) { + ui.playError(); + } + + return success || error; + } + + populateSessionSlots() { + var ui = this.getUi(); + var ypos = 0; + LoggerTools.getLogs() + for (let s = 0; s < sessionSlotCount; s++) { + var found = false + for (var i = 0; i < LoggerTools.logs.length; i++) { + if (LoggerTools.logs[i][3] == s.toString()) { + found = true + const sessionSlot = new SessionSlot(this.scene, s, ypos); + ypos++ + sessionSlot.load(LoggerTools.logs[i][1]); + this.scene.add.existing(sessionSlot); + this.sessionSlotsContainer.add(sessionSlot); + this.sessionSlots.push(sessionSlot); + } + } + if (!found) { + const sessionSlot = new SessionSlot(this.scene, s, ypos); + ypos++ + sessionSlot.load(undefined); + this.scene.add.existing(sessionSlot); + this.sessionSlotsContainer.add(sessionSlot); + this.sessionSlots.push(sessionSlot); + } + } + for (var i = 0; i < LoggerTools.logs.length; i++) { + if (LoggerTools.logs[i][3] == "") { + const sessionSlot = new SessionSlot(this.scene, undefined, ypos); + ypos++ + sessionSlot.load(LoggerTools.logs[i][1]); + this.scene.add.existing(sessionSlot); + this.sessionSlotsContainer.add(sessionSlot); + this.sessionSlots.push(sessionSlot); + } + } + } + + showText(text: string, delay?: integer, callback?: Function, callbackDelay?: integer, prompt?: boolean, promptDelay?: integer) { + super.showText(text, delay, callback, callbackDelay, prompt, promptDelay); + + if (text?.indexOf("\n") === -1) { + this.saveSlotSelectMessageBox.setSize(318, 28); + this.message.setY(-22); + } else { + this.saveSlotSelectMessageBox.setSize(318, 42); + this.message.setY(-37); + } + + this.saveSlotSelectMessageBoxContainer.setVisible(!!text?.length); + } + + setCursor(cursor: integer): boolean { + const changed = super.setCursor(cursor); + + if (!this.cursorObj) { + this.cursorObj = this.scene.add.nineslice(0, 0, "select_cursor_highlight_thick", null, 296, 44, 6, 6, 6, 6); + this.cursorObj.setOrigin(0, 0); + this.sessionSlotsContainer.add(this.cursorObj); + } + this.cursorObj.setPosition(4, 4 + (cursor + this.scrollCursor) * 56); + + return changed; + } + + setScrollCursor(scrollCursor: integer): boolean { + const changed = scrollCursor !== this.scrollCursor; + + if (changed) { + this.scrollCursor = scrollCursor; + this.setCursor(this.cursor); + this.scene.tweens.add({ + targets: this.sessionSlotsContainer, + y: this.sessionSlotsContainerInitialY - 56 * scrollCursor, + duration: Utils.fixedInt(325), + ease: "Sine.easeInOut" + }); + } + + return changed; + } + + clear() { + super.clear(); + this.saveSlotSelectContainer.setVisible(false); + this.eraseCursor(); + this.selectCallback = null; + this.clearSessionSlots(); + } + + eraseCursor() { + if (this.cursorObj) { + this.cursorObj.destroy(); + } + this.cursorObj = null; + } + + clearSessionSlots() { + this.sessionSlots.splice(0, this.sessionSlots.length); + this.sessionSlotsContainer.removeAll(true); + } +} + +class SessionSlot extends Phaser.GameObjects.Container { + public slotId: integer; + public autoSlot: integer; + public hasData: boolean; + public wv: integer; + public key: string; + private loadingLabel: Phaser.GameObjects.Text; + + constructor(scene: BattleScene, slotId: integer = undefined, ypos: integer, autoSlot?: integer) { + super(scene, 0, ypos * 56); + + this.slotId = slotId; + this.autoSlot = autoSlot + + this.setup(); + } + + setup() { + const slotWindow = addWindow(this.scene, 0, 0, 304, 52); + this.add(slotWindow); + + this.loadingLabel = addTextObject(this.scene, 152, 26, i18next.t("saveSlotSelectUiHandler:loading"), TextStyle.WINDOW); + this.loadingLabel.setOrigin(0.5, 0.5); + this.add(this.loadingLabel); + } + + async setupWithData(data: LoggerTools.DRPD) { + this.remove(this.loadingLabel, true); + var lbl = `???` + lbl = data.title + if (this.slotId) { + lbl = `[${this.slotId}] ${lbl}` + } + console.log(data, this.slotId, this.autoSlot, lbl) + const gameModeLabel = addTextObject(this.scene, 8, 5, lbl, TextStyle.WINDOW); + this.add(gameModeLabel); + + const timestampLabel = addTextObject(this.scene, 8, 19, data.date, TextStyle.WINDOW); + this.add(timestampLabel); + + const playTimeLabel = addTextObject(this.scene, 8, 33, data.version + " / " + (data.label || "") + " / " + (data.uuid || ""), TextStyle.WINDOW); + this.add(playTimeLabel); + + const pokemonIconsContainer = this.scene.add.container(144, 4); + if (false || data.starters) + data.starters.forEach((p: LoggerTools.PokeData, i: integer) => { + if (p == undefined) + return; + const iconContainer = this.scene.add.container(26 * i, 0); + iconContainer.setScale(0.75); + + if (Utils.getEnumValues(Species)[p.id] == undefined) + return; + + if (getPokemonSpecies(Utils.getEnumValues(Species)[p.id]) == undefined) + return; + + const icon = this.scene.addPkIcon(getPokemonSpecies(Utils.getEnumValues(Species)[p.id]), 0, 0, 0, 0, 0); + + const text = addTextObject(this.scene, 32, 20, `${i18next.t("saveSlotSelectUiHandler:lv")}${Utils.formatLargeNumber(p.level, 1000)}`, TextStyle.PARTY, { fontSize: "54px", color: "#f8f8f8" }); + text.setShadow(0, 0, null); + text.setStroke("#424242", 14); + text.setOrigin(1, 0); + + iconContainer.add(icon); + iconContainer.add(text); + + pokemonIconsContainer.add(iconContainer); + }); + + this.add(pokemonIconsContainer); + + //const modifiersModule = await import("../modifier/modifier"); + + const modifierIconsContainer = this.scene.add.container(148, 30); + modifierIconsContainer.setScale(0.5); + let visibleModifierIndex = 0; + + this.add(modifierIconsContainer); + } + + load(l?: string, slot?: integer): Promise { + return new Promise(resolve => { + if (l == undefined) { + this.hasData = false; + this.loadingLabel.setText("No data for this run"); + resolve(false); + return; + } + this.key = l + if (slot) { + this.slotId = slot + } + this.setupWithData(JSON.parse(localStorage.getItem(l))) + resolve(true); + }); + return new Promise(resolve => { + this.scene.gameData.getSession(this.slotId, this.autoSlot).then(async sessionData => { + if (!sessionData) { + this.hasData = false; + this.loadingLabel.setText(i18next.t("saveSlotSelectUiHandler:empty")); + resolve(false); + return; + } + this.hasData = true; + await this.setupWithData(undefined); + resolve(true); + }); + }); + } +} + +interface SessionSlot { + scene: BattleScene; +} diff --git a/src/ui/ui.ts b/src/ui/ui.ts index d4dddab5922..09bf39e8db3 100644 --- a/src/ui/ui.ts +++ b/src/ui/ui.ts @@ -85,7 +85,8 @@ export enum Mode { UNAVAILABLE, OUTDATED, CHALLENGE_SELECT, - NAME_LOG + NAME_LOG, + LOG_HANDLER } const transitionModes = [ @@ -98,7 +99,8 @@ const transitionModes = [ Mode.EGG_LIST, Mode.EGG_GACHA, Mode.CHALLENGE_SELECT, - Mode.NAME_LOG + Mode.NAME_LOG, + Mode.LOG_HANDLER ]; const noTransitionModes = [ @@ -184,7 +186,8 @@ export default class UI extends Phaser.GameObjects.Container { new UnavailableModalUiHandler(scene), new OutdatedModalUiHandler(scene), new GameChallengesUiHandler(scene), - new LogNameFormUiHandler(scene) + new LogNameFormUiHandler(scene), + new TargetSelectUiHandler(scene) ]; }