Framework for autosaves

This commit is contained in:
RedstonewolfX 2024-07-13 12:50:34 -04:00
parent 8c89200422
commit ff7e215d6c
4 changed files with 61 additions and 20 deletions

View File

@ -40,6 +40,15 @@ export const logKeys: string[] = [
"d", // Debug "d", // Debug
]; ];
export const autoCheckpoints: integer[] = [
1,
11,
21,
31,
41,
50
]
/** /**
* Uses the save's RNG seed to create a log ID. Used to assign each save its own log. * Uses the save's RNG seed to create a log ID. Used to assign each save its own log.
* @param scene The BattleScene. * @param scene The BattleScene.

View File

@ -598,11 +598,11 @@ export class TitlePhase extends Phase {
label: i18next.t("menu:loadGame"), label: i18next.t("menu:loadGame"),
handler: () => { handler: () => {
this.scene.ui.setOverlayMode(Mode.SAVE_SLOT, SaveSlotUiMode.LOAD, this.scene.ui.setOverlayMode(Mode.SAVE_SLOT, SaveSlotUiMode.LOAD,
(slotId: integer) => { (slotId: integer, autoSlot: integer) => {
if (slotId === -1) { if (slotId === -1) {
return this.showOptions(); return this.showOptions();
} }
this.loadSaveSlot(slotId); this.loadSaveSlot(slotId, autoSlot);
}); });
return true; return true;
} }
@ -631,10 +631,10 @@ export class TitlePhase extends Phase {
this.scene.ui.setMode(Mode.TITLE, config); this.scene.ui.setMode(Mode.TITLE, config);
} }
loadSaveSlot(slotId: integer): void { loadSaveSlot(slotId: integer, autoSlot?: integer): void {
this.scene.sessionSlotId = slotId > -1 ? slotId : loggedInUser.lastSessionSlot; this.scene.sessionSlotId = slotId > -1 ? slotId : loggedInUser.lastSessionSlot;
this.scene.ui.setMode(Mode.MESSAGE); this.scene.ui.setMode(Mode.MESSAGE);
this.scene.gameData.loadSession(this.scene, slotId, slotId === -1 ? this.lastSessionData : null).then((success: boolean) => { this.scene.gameData.loadSession(this.scene, slotId, slotId === -1 ? this.lastSessionData : null, autoSlot).then((success: boolean) => {
if (success) { if (success) {
this.loaded = true; this.loaded = true;
this.scene.ui.showText(i18next.t("menu:sessionSuccess"), null, () => this.end()); this.scene.ui.showText(i18next.t("menu:sessionSuccess"), null, () => this.end());

View File

@ -124,6 +124,7 @@ export interface SessionSaveData {
challenges: ChallengeData[]; challenges: ChallengeData[];
slot: integer; slot: integer;
description: string; description: string;
autoSlot: integer;
} }
interface Unlocks { interface Unlocks {
@ -842,7 +843,7 @@ export class GameData {
} as SessionSaveData; } as SessionSaveData;
} }
getSession(slotId: integer): Promise<SessionSaveData> { getSession(slotId: integer, autoSlot?: integer): Promise<SessionSaveData> {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
if (slotId < 0) { if (slotId < 0) {
return resolve(null); return resolve(null);
@ -850,14 +851,18 @@ export class GameData {
const handleSessionData = async (sessionDataStr: string) => { const handleSessionData = async (sessionDataStr: string) => {
try { try {
const sessionData = this.parseSessionData(sessionDataStr); const sessionData = this.parseSessionData(sessionDataStr);
sessionData.autoSlot = autoSlot;
resolve(sessionData); resolve(sessionData);
} catch (err) { } catch (err) {
reject(err); reject(err);
return; return;
} }
}; };
var autokey = ""
if (!bypassLogin && !localStorage.getItem(`sessionData${slotId ? slotId : ""}_${loggedInUser.username}`)) { if (autoSlot != undefined) {
autokey = "_auto" + autoSlot
}
if (!bypassLogin && !localStorage.getItem(`sessionData${slotId ? slotId : ""}_${loggedInUser.username}${autokey}`)) {
Utils.apiFetch(`savedata/session/get?slot=${slotId}&clientSessionId=${clientSessionId}`, true) Utils.apiFetch(`savedata/session/get?slot=${slotId}&clientSessionId=${clientSessionId}`, true)
.then(response => response.text()) .then(response => response.text())
.then(async response => { .then(async response => {
@ -871,7 +876,8 @@ export class GameData {
await handleSessionData(response); await handleSessionData(response);
}); });
} else { } else {
const sessionData = localStorage.getItem(`sessionData${slotId ? slotId : ""}_${loggedInUser.username}`); const sessionData = localStorage.getItem(`sessionData${slotId ? slotId : ""}_${loggedInUser.username}${autokey}`);
console.log(`sessionData${slotId ? slotId : ""}_${loggedInUser.username}${autokey}`, sessionData)
if (sessionData) { if (sessionData) {
await handleSessionData(decrypt(sessionData, bypassLogin)); await handleSessionData(decrypt(sessionData, bypassLogin));
} else { } else {
@ -881,7 +887,7 @@ export class GameData {
}); });
} }
loadSession(scene: BattleScene, slotId: integer, sessionData?: SessionSaveData): Promise<boolean> { loadSession(scene: BattleScene, slotId: integer, sessionData?: SessionSaveData, autoSlot?: integer): Promise<boolean> {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
try { try {
const initSessionFromData = async (sessionData: SessionSaveData) => { const initSessionFromData = async (sessionData: SessionSaveData) => {
@ -981,7 +987,7 @@ export class GameData {
if (sessionData) { if (sessionData) {
initSessionFromData(sessionData); initSessionFromData(sessionData);
} else { } else {
this.getSession(slotId) this.getSession(slotId, autoSlot)
.then(data => initSessionFromData(data)) .then(data => initSessionFromData(data))
.catch(err => { .catch(err => {
reject(err); reject(err);

View File

@ -10,6 +10,7 @@ import MessageUiHandler from "./message-ui-handler";
import { TextStyle, addTextObject } from "./text"; import { TextStyle, addTextObject } from "./text";
import { Mode } from "./ui"; import { Mode } from "./ui";
import { addWindow } from "./ui-theme"; import { addWindow } from "./ui-theme";
import * as LoggerTools from "../logger"
const sessionSlotCount = 5; const sessionSlotCount = 5;
@ -18,7 +19,7 @@ export enum SaveSlotUiMode {
SAVE SAVE
} }
export type SaveSlotSelectCallback = (cursor: integer) => void; export type SaveSlotSelectCallback = (cursor: integer, cursor2?: integer) => void;
export default class SaveSlotSelectUiHandler extends MessageUiHandler { export default class SaveSlotSelectUiHandler extends MessageUiHandler {
@ -106,7 +107,7 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler {
switch (this.uiMode) { switch (this.uiMode) {
case SaveSlotUiMode.LOAD: case SaveSlotUiMode.LOAD:
this.saveSlotSelectCallback = null; this.saveSlotSelectCallback = null;
originalCallback(cursor); originalCallback(this.sessionSlots[cursor].slotId, this.sessionSlots[cursor].autoSlot);
break; break;
case SaveSlotUiMode.SAVE: case SaveSlotUiMode.SAVE:
const saveAndCallback = () => { const saveAndCallback = () => {
@ -115,8 +116,11 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler {
ui.revertMode(); ui.revertMode();
ui.showText(null, 0); ui.showText(null, 0);
ui.setMode(Mode.MESSAGE); ui.setMode(Mode.MESSAGE);
originalCallback(cursor); originalCallback(this.sessionSlots[cursor].slotId, this.sessionSlots[cursor].autoSlot);
}; };
if (this.sessionSlots[cursor].autoSlot != undefined) {
return false;
}
if (this.sessionSlots[cursor].hasData) { if (this.sessionSlots[cursor].hasData) {
ui.showText(i18next.t("saveSlotSelectUiHandler:overwriteData"), null, () => { ui.showText(i18next.t("saveSlotSelectUiHandler:overwriteData"), null, () => {
ui.setOverlayMode(Mode.CONFIRM, () => { ui.setOverlayMode(Mode.CONFIRM, () => {
@ -158,7 +162,7 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler {
case Button.DOWN: case Button.DOWN:
if (this.cursor < 2) { if (this.cursor < 2) {
success = this.setCursor(this.cursor + 1); success = this.setCursor(this.cursor + 1);
} else if (this.scrollCursor < sessionSlotCount - 3) { } else if (this.scrollCursor < this.sessionSlots.length - 3) {
success = this.setScrollCursor(this.scrollCursor + 1); success = this.setScrollCursor(this.scrollCursor + 1);
} }
break; break;
@ -175,12 +179,28 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler {
} }
populateSessionSlots() { populateSessionSlots() {
var ui = this.getUi();
var ypos = 0;
for (let s = 0; s < sessionSlotCount; s++) { for (let s = 0; s < sessionSlotCount; s++) {
const sessionSlot = new SessionSlot(this.scene, s); const sessionSlot = new SessionSlot(this.scene, s, ypos);
ypos++
sessionSlot.load(); sessionSlot.load();
this.scene.add.existing(sessionSlot); this.scene.add.existing(sessionSlot);
this.sessionSlotsContainer.add(sessionSlot); this.sessionSlotsContainer.add(sessionSlot);
this.sessionSlots.push(sessionSlot); this.sessionSlots.push(sessionSlot);
if (this.uiMode != SaveSlotUiMode.SAVE) {
for (var j = 0; j < LoggerTools.autoCheckpoints.length; j++) {
var k = "sessionData" + (s ? s : "") + "_Guest_auto" + j
if (localStorage.getItem(k) != null) {
const sessionSlot = new SessionSlot(this.scene, s, ypos, j);
ypos++
sessionSlot.load();
this.scene.add.existing(sessionSlot);
this.sessionSlotsContainer.add(sessionSlot);
this.sessionSlots.push(sessionSlot);
}
}
}
} }
} }
@ -251,13 +271,15 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler {
class SessionSlot extends Phaser.GameObjects.Container { class SessionSlot extends Phaser.GameObjects.Container {
public slotId: integer; public slotId: integer;
public autoSlot: integer;
public hasData: boolean; public hasData: boolean;
private loadingLabel: Phaser.GameObjects.Text; private loadingLabel: Phaser.GameObjects.Text;
constructor(scene: BattleScene, slotId: integer) { constructor(scene: BattleScene, slotId: integer, ypos: integer, autoSlot?: integer) {
super(scene, 0, slotId * 56); super(scene, 0, ypos * 56);
this.slotId = slotId; this.slotId = slotId;
this.autoSlot = autoSlot
this.setup(); this.setup();
} }
@ -273,8 +295,12 @@ class SessionSlot extends Phaser.GameObjects.Container {
async setupWithData(data: SessionSaveData) { async setupWithData(data: SessionSaveData) {
this.remove(this.loadingLabel, true); this.remove(this.loadingLabel, true);
var lbl = `${GameMode.getModeName(data.gameMode) || i18next.t("gameMode:unkown")} - ${i18next.t("saveSlotSelectUiHandler:wave")} ${data.waveIndex}`
const gameModeLabel = addTextObject(this.scene, 8, 5, `${GameMode.getModeName(data.gameMode) || i18next.t("gameMode:unkown")} - ${i18next.t("saveSlotSelectUiHandler:wave")} ${data.waveIndex}`, TextStyle.WINDOW); if (this.autoSlot != undefined) {
lbl = `Slot ${this.slotId} (Auto) - ${i18next.t("saveSlotSelectUiHandler:wave")} ${data.waveIndex}`
}
console.log(data, this.slotId, this.autoSlot, lbl)
const gameModeLabel = addTextObject(this.scene, 8, 5, lbl, TextStyle.WINDOW);
this.add(gameModeLabel); this.add(gameModeLabel);
const timestampLabel = addTextObject(this.scene, 8, 19, new Date(data.timestamp).toLocaleString(), TextStyle.WINDOW); const timestampLabel = addTextObject(this.scene, 8, 19, new Date(data.timestamp).toLocaleString(), TextStyle.WINDOW);
@ -329,7 +355,7 @@ class SessionSlot extends Phaser.GameObjects.Container {
load(): Promise<boolean> { load(): Promise<boolean> {
return new Promise<boolean>(resolve => { return new Promise<boolean>(resolve => {
this.scene.gameData.getSession(this.slotId).then(async sessionData => { this.scene.gameData.getSession(this.slotId, this.autoSlot).then(async sessionData => {
if (!sessionData) { if (!sessionData) {
this.hasData = false; this.hasData = false;
this.loadingLabel.setText(i18next.t("saveSlotSelectUiHandler:empty")); this.loadingLabel.setText(i18next.t("saveSlotSelectUiHandler:empty"));