offline mode - adds daily run and fixes clear freezes (#834)

* offline mode - adds daily run and fixes clear freezes

* removed unused import
This commit is contained in:
Nexllon 2024-05-14 16:42:30 -03:00 committed by GitHub
parent 58ec2ebd89
commit df499e2f71
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 57 additions and 7 deletions

View File

@ -13,14 +13,15 @@ export interface DailyRunConfig {
}
export function fetchDailyRunSeed(): Promise<string> {
return new Promise<string>(resolve => {
return new Promise<string>((resolve, reject) => {
Utils.apiFetch('daily/seed').then(response => {
if (!response.ok) {
resolve(null);
return;
}
return response.text();
}).then(seed => resolve(seed));
}).then(seed => resolve(seed))
.catch(err => reject(err));
});
}

View File

@ -289,7 +289,7 @@ export class TitlePhase extends Phase {
}
this.scene.sessionSlotId = slotId;
fetchDailyRunSeed().then(seed => {
const generateDaily = (seed: string) => {
this.scene.gameMode = gameModes[GameModes.DAILY];
this.scene.setSeed(seed);
@ -332,9 +332,18 @@ export class TitlePhase extends Phase {
this.scene.sessionPlayTime = 0;
this.end();
});
}).catch(err => {
console.error("Failed to load daily run:\n", err);
});
};
// If Online, calls seed fetch from db to generate daily run. If Offline, generates a daily run based on current date.
if (!Utils.isLocal) {
fetchDailyRunSeed().then(seed => {
generateDaily(seed);
}).catch(err => {
console.error("Failed to load daily run:\n", err);
});
} else {
generateDaily(btoa(new Date().toISOString().substring(0, 10)));
}
});
}
@ -3612,10 +3621,20 @@ export class GameOverPhase extends BattlePhase {
});
});
};
/* Added a local check to see if the game is running offline on victory
If Online, execute apiFetch as intended
If Offline, execute offlineNewClear(), a localStorage implementation of newClear daily run checks */
if (this.victory) {
Utils.apiFetch(`savedata/newclear?slot=${this.scene.sessionSlotId}`, true)
if (!Utils.isLocal) {
Utils.apiFetch(`savedata/newclear?slot=${this.scene.sessionSlotId}`, true)
.then(response => response.json())
.then(newClear => doGameOver(newClear));
} else {
this.scene.gameData.offlineNewClear(this.scene).then(result => {
doGameOver(result);
});
}
} else
doGameOver(false);
}

View File

@ -759,6 +759,36 @@ export class GameData {
});
}
/* Defines a localStorage item 'daily' to check on clears, offline implementation of savedata/newclear API
If a GameModes clear other than Daily is checked, newClear = true as usual
If a Daily mode is cleared, checks if it was already cleared before, based on seed, and returns true only to new daily clear runs */
offlineNewClear(scene: BattleScene): Promise<boolean> {
return new Promise<boolean>(resolve => {
const sessionData = this.getSessionSaveData(scene);
const seed = sessionData.seed;
let daily: string[] = [];
if (sessionData.gameMode == GameModes.DAILY) {
if (localStorage.hasOwnProperty('daily')) {
daily = JSON.parse(atob(localStorage.getItem('daily')));
if (daily.includes(seed)) {
return resolve(false);
} else {
daily.push(seed);
localStorage.setItem('daily', btoa(JSON.stringify(daily)));
return resolve(true);
}
} else {
daily.push(seed);
localStorage.setItem('daily', btoa(JSON.stringify(daily)));
return resolve(true);
}
} else {
return resolve(true);
}
});
}
tryClearSession(scene: BattleScene, slotId: integer): Promise<[success: boolean, newClear: boolean]> {
return new Promise<[boolean, boolean]>(resolve => {
if (bypassLogin) {