pages/kronos/js/utils/save.js

333 lines
9.1 KiB
JavaScript

// ************ Save stuff ************
function save() {
localStorage.setItem(modInfo.id, btoa(JSON.stringify(player)));
}
function startPlayerBase() {
return {
tab: layoutInfo.startTab,
navTab: (layoutInfo.showTree ? "tree-tab" : "none"),
time: Date.now(),
autosave: true,
notify: {},
msDisplay: "always",
offlineProd: true,
versionType: modInfo.id,
version: VERSION.num,
beta: VERSION.beta,
timePlayed: 0,
keepGoing: false,
hasNaN: false,
hideChallenges: false,
showStory: true,
forceOneTab: false,
points: modInfo.initialStartPoints,
subtabs: {},
lastSafeTab: (layoutInfo.showTree ? "none" : layoutInfo.startTab)
};
}
function getStartPlayer() {
let playerdata = startPlayerBase();
if (addedPlayerData) {
let extradata = addedPlayerData();
for (let thing in extradata) {
playerdata[thing] = extradata[thing];
}
}
playerdata.infoboxes = {};
for (let layer in layers) {
playerdata[layer] = getStartLayerData(layer);
if (layers[layer].tabFormat && !Array.isArray(layers[layer].tabFormat)) {
playerdata.subtabs[layer] = {};
playerdata.subtabs[layer].mainTabs = Object.keys(layers[layer].tabFormat)[0];
}
if (layers[layer].microtabs) {
if (playerdata.subtabs[layer] === undefined) {
playerdata.subtabs[layer] = {};
}
for (item in layers[layer].microtabs) {
playerdata.subtabs[layer][item] = Object.keys(layers[layer].microtabs[item])[0];
}
}
if (layers[layer].infoboxes) {
if (playerdata.infoboxes[layer] === undefined) {
playerdata.infoboxes[layer] = {};
}
for (item in layers[layer].infoboxes) {
playerdata.infoboxes[layer][item] = false;
}
}
}
return playerdata;
}
function getStartLayerData(layer) {
let layerdata = {};
if (layers[layer].startData) {
layerdata = layers[layer].startData();
}
if (layerdata.unlocked === undefined) {
layerdata.unlocked = true;
}
if (layerdata.total === undefined) {
layerdata.total = decimalZero;
}
if (layerdata.best === undefined) {
layerdata.best = decimalZero;
}
if (layerdata.resetTime === undefined) {
layerdata.resetTime = 0;
}
if (layerdata.forceTooltip === undefined) {
layerdata.forceTooltip = false;
}
layerdata.buyables = getStartBuyables(layer);
if (layerdata.noRespecConfirm === undefined) {
layerdata.noRespecConfirm = false;
}
if (layerdata.clickables === undefined) {
layerdata.clickables = getStartClickables(layer);
}
layerdata.spentOnBuyables = decimalZero;
layerdata.upgrades = [];
layerdata.milestones = [];
layerdata.lastMilestone = null;
layerdata.achievements = [];
layerdata.challenges = getStartChallenges(layer);
layerdata.grid = getStartGrid(layer);
return layerdata;
}
function getStartBuyables(layer) {
let data = {};
if (layers[layer].buyables) {
for (let id in layers[layer].buyables) {
if (isPlainObject(layers[layer].buyables[id])) {
data[id] = decimalZero;
}
}
}
return data;
}
function getStartClickables(layer) {
let data = {};
if (layers[layer].clickables) {
for (let id in layers[layer].clickables) {
if (isPlainObject(layers[layer].clickables[id])) {
data[id] = "";
}
}
}
return data;
}
function getStartChallenges(layer) {
let data = {};
if (layers[layer].challenges) {
for (let id in layers[layer].challenges) {
if (isPlainObject(layers[layer].challenges[id])) {
data[id] = 0;
}
}
}
return data;
}
function getStartGrid(layer) {
let data = {};
if (! layers[layer].grid) return data
if (layers[layer].grid.maxRows === undefined) layers[layer].grid.maxRows=layers[layer].grid.rows
if (layers[layer].grid.maxCols === undefined) layers[layer].grid.maxCols=layers[layer].grid.cols
for (let y = 1; y <= layers[layer].grid.maxRows; y++) {
for (let x = 1; x <= layers[layer].grid.maxCols; x++) {
data[100*y + x] = layers[layer].grid.getStartData(100*y + x)
}
}
return data;
}
function fixSave() {
let defaultData = getStartPlayer();
fixData(defaultData, player);
setBuyableAmount("distill", "retort", (getBuyableAmount("distill", "retort") || decimalZero).max(5));
player.sands.chipping = false;
player.rituals.rituals = getRituals();
for (let layer in layers) {
if (player[layer].best !== undefined) {
player[layer].best = new Decimal(player[layer].best);
}
if (player[layer].total !== undefined) {
player[layer].total = new Decimal(player[layer].total);
}
if (layers[layer].tabFormat && !Array.isArray(layers[layer].tabFormat)) {
if (!Object.keys(layers[layer].tabFormat).includes(player.subtabs[layer].mainTabs)) {
player.subtabs[layer].mainTabs = Object.keys(layers[layer].tabFormat)[0];
}
}
if (layers[layer].microtabs) {
for (let item in layers[layer].microtabs) {
if (!Object.keys(layers[layer].microtabs[item]).includes(player.subtabs[layer][item])) {
player.subtabs[layer][item] = Object.keys(layers[layer].microtabs[item])[0];
}
}
}
}
}
function fixData(defaultData, newData) {
for (let item in defaultData) {
if (defaultData[item] == null) {
if (newData[item] === undefined) {
newData[item] = null;
}
} else if (Array.isArray(defaultData[item])) {
if (newData[item] === undefined) {
newData[item] = defaultData[item];
} else {
fixData(defaultData[item], newData[item]);
}
} else if (defaultData[item] instanceof Decimal) { // Convert to Decimal
if (newData[item] === undefined) {
newData[item] = defaultData[item];
} else {
newData[item] = new Decimal(newData[item]);
}
} else if ((!!defaultData[item]) && (typeof defaultData[item] === "object")) {
if (newData[item] === undefined || (typeof defaultData[item] !== "object")) {
newData[item] = defaultData[item];
// Note: Dangerously ignoring "cards" here, because player.study.cards was re-adding any cards
// from the starter deck that got completely removed by the player
} else if (item !== "cards") {
fixData(defaultData[item], newData[item]);
}
} else {
if (newData[item] === undefined) {
newData[item] = defaultData[item];
}
}
}
}
function load() {
let get = localStorage.getItem(modInfo.id);
if (get === null || get === undefined) {
player = getStartPlayer();
} else {
player = Object.assign(getStartPlayer(), JSON.parse(decodeURIComponent(escape(atob(get)))));
}
fixSave();
if (player.offlineProd) {
if (player.offTime === undefined) {
player.offTime = { remain: 0 };
}
player.offTime.remain += (Date.now() - player.time) / 1000;
}
player.time = Date.now();
versionCheck();
changeTheme();
changeTreeQuality();
updateLayers();
setupModInfo();
setupTemp();
updateTemp();
updateTemp();
updateTabFormats();
loadVue();
}
function setupModInfo() {
modInfo.changelog = changelog;
modInfo.winText = winText ? winText : "Congratulations! You have reached the end and beaten this game, but for now...";
}
function fixNaNs() {
NaNcheck(player);
}
// noinspection SpellCheckingInspection
function NaNcheck(data) {
for (let item in data) {
if (data[item] == null) {
} else if (Array.isArray(data[item])) {
NaNcheck(data[item]);
} else if (data[item] !== data[item] || data[item] === decimalNaN) {
if (NaNalert === true || confirm("Invalid value found in player, named '" + item + "'. Please let the creator of this mod know! Would you like to try to auto-fix the save and keep going?")) {
NaNalert = true;
data[item] = (data[item] !== data[item] ? 0 : decimalZero);
} else {
clearInterval(interval);
player.autosave = false;
NaNalert = true;
}
} else if (data[item] instanceof Decimal) { // Convert to Decimal
} else if ((!!data[item]) && (data[item].constructor === Object)) {
NaNcheck(data[item]);
}
}
}
function exportSave() {
let str = btoa(JSON.stringify(player));
const el = document.createElement("textarea");
el.value = str;
document.body.appendChild(el);
el.select();
el.setSelectionRange(0, 99999);
document.execCommand("copy");
document.body.removeChild(el);
}
function importSave(imported = undefined, forced = false) {
if (imported === undefined) {
imported = prompt("Paste your save here");
}
try {
let tempPlr = Object.assign(getStartPlayer(), JSON.parse(atob(imported)));
if (tempPlr.versionType !== modInfo.id && !forced && !confirm("This save appears to be for a different mod! Are you sure you want to import?")) // Wrong save (use "Forced" to force it to accept.)
{
return;
}
player = tempPlr;
player.versionType = modInfo.id;
fixSave();
versionCheck();
save();
window.location.reload();
} catch (e) {
}
}
function versionCheck() {
let setVersion = true;
if (player.versionType === undefined || player.version === undefined) {
player.versionType = modInfo.id;
player.version = 0;
}
if (setVersion) {
if (player.versionType === modInfo.id && VERSION.num > player.version) {
player.keepGoing = false;
if (fixOldSave) {
fixOldSave(player.version);
}
}
player.versionType = getStartPlayer().versionType;
player.version = VERSION.num;
player.beta = VERSION.beta;
}
}
// noinspection JSUnusedGlobalSymbols
const saveInterval = setInterval(function () {
if (player === undefined) {
return;
}
if (gameEnded && !player.keepGoing) {
return;
}
if (player.autosave) {
save();
}
}, 5000);