303 lines
7.8 KiB
JavaScript
303 lines
7.8 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,
|
||
|
points: modInfo.initialStartPoints,
|
||
|
subtabs: {},
|
||
|
lastSafeTab: (layoutInfo.showTree ? "none" : layoutInfo.startTab)
|
||
|
};
|
||
|
}
|
||
|
function getStartPlayer() {
|
||
|
playerdata = startPlayerBase();
|
||
|
|
||
|
if (addedPlayerData) {
|
||
|
extradata = addedPlayerData();
|
||
|
for (thing in extradata) {
|
||
|
playerdata[thing] = extradata[thing];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
playerdata.infoboxes = {};
|
||
|
for (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) {
|
||
|
layerdata = {};
|
||
|
if (layers[layer].startData) {
|
||
|
layerdata = layers[layer].startData();
|
||
|
}
|
||
|
|
||
|
if (layerdata.unlocked === undefined) {
|
||
|
layerdata.unlocked = true;
|
||
|
}
|
||
|
if (layerdata.total === undefined) {
|
||
|
layerdata.total = new Decimal(0);
|
||
|
}
|
||
|
if (layerdata.best === undefined) {
|
||
|
layerdata.best = new Decimal(0);
|
||
|
}
|
||
|
if (layerdata.resetTime === undefined) {
|
||
|
layerdata.resetTime = 0;
|
||
|
}
|
||
|
|
||
|
layerdata.buyables = getStartBuyables(layer);
|
||
|
if (layerdata.clickables == undefined) {
|
||
|
layerdata.clickables = getStartClickables(layer);
|
||
|
}
|
||
|
layerdata.spentOnBuyables = new Decimal(0);
|
||
|
layerdata.upgrades = [];
|
||
|
layerdata.milestones = [];
|
||
|
layerdata.achievements = [];
|
||
|
layerdata.challenges = getStartChallenges(layer);
|
||
|
return layerdata;
|
||
|
}
|
||
|
function getStartBuyables(layer) {
|
||
|
let data = {};
|
||
|
if (layers[layer].buyables) {
|
||
|
for (id in layers[layer].buyables) {
|
||
|
if (isPlainObject(layers[layer].buyables[id])) {
|
||
|
data[id] = new Decimal(0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return data;
|
||
|
}
|
||
|
function getStartClickables(layer) {
|
||
|
let data = {};
|
||
|
if (layers[layer].clickables) {
|
||
|
for (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 (id in layers[layer].challenges) {
|
||
|
if (isPlainObject(layers[layer].challenges[id])) {
|
||
|
data[id] = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return data;
|
||
|
}
|
||
|
function fixSave() {
|
||
|
defaultData = getStartPlayer();
|
||
|
fixData(defaultData, player);
|
||
|
|
||
|
for (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 (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 (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];
|
||
|
} else {
|
||
|
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(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();
|
||
|
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);
|
||
|
}
|
||
|
function NaNcheck(data) {
|
||
|
for (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 {
|
||
|
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) {
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
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;
|
||
|
}
|
||
|
}
|
||
|
var saveInterval = setInterval(function () {
|
||
|
if (player === undefined) {
|
||
|
return;
|
||
|
}
|
||
|
if (gameEnded && !player.keepGoing) {
|
||
|
return;
|
||
|
}
|
||
|
if (player.autosave) {
|
||
|
save();
|
||
|
}
|
||
|
}, 5000);
|