mirror of
https://github.com/Acamaeda/The-Modding-Tree.git
synced 2024-11-21 16:13:55 +00:00
refactor(utils.js): extracted some regions to their own file
This commit is contained in:
parent
e6164a95d6
commit
654199f7ee
6 changed files with 502 additions and 511 deletions
|
@ -19,6 +19,10 @@
|
|||
<script src="js/technical/systemComponents.js"></script>
|
||||
<script src="js/components.js"></script>
|
||||
<script src="js/technical/canvas.js"></script>
|
||||
<script src="js/utils/NumberFormating.js"></script>
|
||||
<script src="js/utils/options.js"></script>
|
||||
<script src="js/utils/save.js"></script>
|
||||
<script src="js/utils/themes.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
|
|
457
js/utils.js
457
js/utils.js
|
@ -1,454 +1,3 @@
|
|||
// ************ Number formatting ************
|
||||
|
||||
function exponentialFormat(num, precision, mantissa = true) {
|
||||
let e = num.log10().floor()
|
||||
let m = num.div(Decimal.pow(10, e))
|
||||
if(m.toStringWithDecimalPlaces(precision) == 10) {
|
||||
m = new Decimal(1)
|
||||
e = e.add(1)
|
||||
}
|
||||
e = (e.gte(10000) ? commaFormat(e, 0) : e.toStringWithDecimalPlaces(0))
|
||||
if (mantissa)
|
||||
return m.toStringWithDecimalPlaces(precision)+"e"+e
|
||||
else return "e"+e
|
||||
}
|
||||
|
||||
function commaFormat(num, precision) {
|
||||
if (num === null || num === undefined) return "NaN"
|
||||
if (num.mag < 0.001) return (0).toFixed(precision)
|
||||
return num.toStringWithDecimalPlaces(precision).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,")
|
||||
}
|
||||
|
||||
|
||||
function regularFormat(num, precision) {
|
||||
if (num === null || num === undefined) return "NaN"
|
||||
if (num.mag < 0.001) return (0).toFixed(precision)
|
||||
return num.toStringWithDecimalPlaces(precision)
|
||||
}
|
||||
|
||||
function fixValue(x, y = 0) {
|
||||
return x || new Decimal(y)
|
||||
}
|
||||
|
||||
function sumValues(x) {
|
||||
x = Object.values(x)
|
||||
if (!x[0]) return new Decimal(0)
|
||||
return x.reduce((a, b) => Decimal.add(a, b))
|
||||
}
|
||||
|
||||
function format(decimal, precision=2,) {
|
||||
decimal = new Decimal(decimal)
|
||||
if (isNaN(decimal.sign)||isNaN(decimal.layer)||isNaN(decimal.mag)) {
|
||||
player.hasNaN = true;
|
||||
return "NaN"
|
||||
}
|
||||
if (decimal.sign<0) return "-"+format(decimal.neg(), precision)
|
||||
if (decimal.mag == Number.POSITIVE_INFINITY) return "Infinity"
|
||||
if (decimal.gte("eeee1000")) {
|
||||
var slog = decimal.slog()
|
||||
if (slog.gte(1e6)) return "F" + format(slog.floor())
|
||||
else return Decimal.pow(10, slog.sub(slog.floor())).toStringWithDecimalPlaces(3) + "F" + commaFormat(slog.floor(), 0)
|
||||
}
|
||||
else if (decimal.gte("1e100000")) return exponentialFormat(decimal, 0, false)
|
||||
else if (decimal.gte("1e1000")) return exponentialFormat(decimal, 0)
|
||||
else if (decimal.gte(1e9)) return exponentialFormat(decimal, precision)
|
||||
else if (decimal.gte(1e3)) return commaFormat(decimal, 0)
|
||||
else return regularFormat(decimal, precision)
|
||||
}
|
||||
|
||||
function formatWhole(decimal) {
|
||||
decimal = new Decimal(decimal)
|
||||
if (decimal.gte(1e9)) return format(decimal, 2)
|
||||
if (decimal.lte(0.98) && !decimal.eq(0)) return format(decimal, 2)
|
||||
return format(decimal, 0)
|
||||
}
|
||||
|
||||
function formatTime(s) {
|
||||
if (s<60) return format(s)+"s"
|
||||
else if (s<3600) return formatWhole(Math.floor(s/60))+"m "+format(s%60)+"s"
|
||||
else if (s<86400) return formatWhole(Math.floor(s/3600))+"h "+formatWhole(Math.floor(s/60)%60)+"m "+format(s%60)+"s"
|
||||
else if (s<31536000) return formatWhole(Math.floor(s/84600)%365)+"d " + formatWhole(Math.floor(s/3600)%24)+"h "+formatWhole(Math.floor(s/60)%60)+"m "+format(s%60)+"s"
|
||||
else return formatWhole(Math.floor(s/31536000))+"y "+formatWhole(Math.floor(s/84600)%365)+"d " + formatWhole(Math.floor(s/3600)%24)+"h "+formatWhole(Math.floor(s/60)%60)+"m "+format(s%60)+"s"
|
||||
}
|
||||
|
||||
function toPlaces(x, precision, maxAccepted) {
|
||||
x = new Decimal(x)
|
||||
let result = x.toStringWithDecimalPlaces(precision)
|
||||
if (new Decimal(result).gte(maxAccepted)) {
|
||||
result = new Decimal(maxAccepted-Math.pow(0.1, precision)).toStringWithDecimalPlaces(precision)
|
||||
}
|
||||
return result
|
||||
}
|
||||
// ************ 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)
|
||||
|
||||
// ************ Themes ************
|
||||
|
||||
const themes = {
|
||||
1: "aqua"
|
||||
}
|
||||
const theme_names = {
|
||||
aqua: "Aqua"
|
||||
}
|
||||
|
||||
function changeTheme() {
|
||||
let aqua = player.theme == "aqua"
|
||||
colors_theme = colors[player.theme || "default"]
|
||||
document.body.style.setProperty('--background', aqua ? "#001f3f" : "#0f0f0f")
|
||||
document.body.style.setProperty('--background_tooltip', aqua ? "rgba(0, 15, 31, 0.75)" : "rgba(0, 0, 0, 0.75)")
|
||||
document.body.style.setProperty('--color', aqua ? "#bfdfff" : "#dfdfdf")
|
||||
document.body.style.setProperty('--points', aqua ? "#dfefff" : "#ffffff")
|
||||
document.body.style.setProperty("--locked", aqua ? "#c4a7b3" : "#bf8f8f")
|
||||
}
|
||||
|
||||
function getThemeName() {
|
||||
return player.theme ? theme_names[player.theme] : "Default"
|
||||
}
|
||||
|
||||
function switchTheme() {
|
||||
if (player.theme === undefined) player.theme = themes[1]
|
||||
else {
|
||||
player.theme = themes[Object.keys(themes)[player.theme] + 1]
|
||||
if (!player.theme) delete player.theme
|
||||
}
|
||||
changeTheme()
|
||||
resizeCanvas()
|
||||
}
|
||||
|
||||
// ************ Options ************
|
||||
|
||||
function toggleOpt(name) {
|
||||
if (name == "oldStyle" && styleCooldown>0) return;
|
||||
|
||||
player[name] = !player[name]
|
||||
if (name == "hqTree") changeTreeQuality()
|
||||
if (name == "oldStyle") updateStyle()
|
||||
}
|
||||
|
||||
var styleCooldown = 0;
|
||||
|
||||
|
||||
function updateStyle() {
|
||||
styleCooldown = 1;
|
||||
let css = document.getElementById("styleStuff")
|
||||
css.href = player.oldStyle?"oldStyle.css":"style.css"
|
||||
needCanvasUpdate = true;
|
||||
}
|
||||
|
||||
function changeTreeQuality() {
|
||||
var on = player.hqTree
|
||||
document.body.style.setProperty('--hqProperty1', on ? "2px solid" : "4px solid")
|
||||
document.body.style.setProperty('--hqProperty2a', on ? "-4px -4px 4px rgba(0, 0, 0, 0.25) inset" : "-4px -4px 4px rgba(0, 0, 0, 0) inset")
|
||||
document.body.style.setProperty('--hqProperty2b', on ? "0px 0px 20px var(--background)" : "")
|
||||
document.body.style.setProperty('--hqProperty3', on ? "2px 2px 4px rgba(0, 0, 0, 0.25)" : "none")
|
||||
}
|
||||
|
||||
function toggleAuto(toggle) {
|
||||
player[toggle[0]][toggle[1]] = !player[toggle[0]][toggle[1]]
|
||||
}
|
||||
|
||||
function adjustMSDisp() {
|
||||
let displays = ["always", "automation", "incomplete", "never"];
|
||||
player.msDisplay = displays[(displays.indexOf(player.msDisplay)+1)%4]
|
||||
}
|
||||
|
||||
function milestoneShown(layer, id) {
|
||||
complete = player[layer].milestones.includes(id)
|
||||
auto = layers[layer].milestones[id].toggles
|
||||
|
||||
switch(player.msDisplay) {
|
||||
case "always":
|
||||
return true;
|
||||
break;
|
||||
case "automation":
|
||||
return (auto)||!complete
|
||||
break;
|
||||
case "incomplete":
|
||||
return !complete
|
||||
break;
|
||||
case "never":
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ************ Big Feature related ************
|
||||
|
||||
function respecBuyables(layer) {
|
||||
|
@ -561,8 +110,7 @@ function buyUpg(layer, id) {
|
|||
let pay = layers[layer].upgrades[id].pay
|
||||
if (pay !== undefined)
|
||||
run(pay, layers[layer].upgrades[id])
|
||||
else
|
||||
{
|
||||
else {
|
||||
let cost = tmp[layer].upgrades[id].cost
|
||||
|
||||
if (upg.currencyInternalName) {
|
||||
|
@ -787,8 +335,7 @@ function focused(x) {
|
|||
onFocused = x
|
||||
}
|
||||
|
||||
function prestigeButtonText(layer)
|
||||
{
|
||||
function prestigeButtonText(layer) {
|
||||
if (layers[layer].prestigeButtonText !== undefined)
|
||||
return layers[layer].prestigeButtonText()
|
||||
else if (tmp[layer].type == "normal")
|
||||
|
|
80
js/utils/NumberFormating.js
Normal file
80
js/utils/NumberFormating.js
Normal file
|
@ -0,0 +1,80 @@
|
|||
|
||||
function exponentialFormat(num, precision, mantissa = true) {
|
||||
let e = num.log10().floor()
|
||||
let m = num.div(Decimal.pow(10, e))
|
||||
if (m.toStringWithDecimalPlaces(precision) == 10) {
|
||||
m = new Decimal(1)
|
||||
e = e.add(1)
|
||||
}
|
||||
e = (e.gte(10000) ? commaFormat(e, 0) : e.toStringWithDecimalPlaces(0))
|
||||
if (mantissa)
|
||||
return m.toStringWithDecimalPlaces(precision) + "e" + e
|
||||
else return "e" + e
|
||||
}
|
||||
|
||||
function commaFormat(num, precision) {
|
||||
if (num === null || num === undefined) return "NaN"
|
||||
if (num.mag < 0.001) return (0).toFixed(precision)
|
||||
return num.toStringWithDecimalPlaces(precision).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,")
|
||||
}
|
||||
|
||||
|
||||
function regularFormat(num, precision) {
|
||||
if (num === null || num === undefined) return "NaN"
|
||||
if (num.mag < 0.001) return (0).toFixed(precision)
|
||||
return num.toStringWithDecimalPlaces(precision)
|
||||
}
|
||||
|
||||
function fixValue(x, y = 0) {
|
||||
return x || new Decimal(y)
|
||||
}
|
||||
|
||||
function sumValues(x) {
|
||||
x = Object.values(x)
|
||||
if (!x[0]) return new Decimal(0)
|
||||
return x.reduce((a, b) => Decimal.add(a, b))
|
||||
}
|
||||
|
||||
function format(decimal, precision = 2,) {
|
||||
decimal = new Decimal(decimal)
|
||||
if (isNaN(decimal.sign) || isNaN(decimal.layer) || isNaN(decimal.mag)) {
|
||||
player.hasNaN = true;
|
||||
return "NaN"
|
||||
}
|
||||
if (decimal.sign < 0) return "-" + format(decimal.neg(), precision)
|
||||
if (decimal.mag == Number.POSITIVE_INFINITY) return "Infinity"
|
||||
if (decimal.gte("eeee1000")) {
|
||||
var slog = decimal.slog()
|
||||
if (slog.gte(1e6)) return "F" + format(slog.floor())
|
||||
else return Decimal.pow(10, slog.sub(slog.floor())).toStringWithDecimalPlaces(3) + "F" + commaFormat(slog.floor(), 0)
|
||||
}
|
||||
else if (decimal.gte("1e100000")) return exponentialFormat(decimal, 0, false)
|
||||
else if (decimal.gte("1e1000")) return exponentialFormat(decimal, 0)
|
||||
else if (decimal.gte(1e9)) return exponentialFormat(decimal, precision)
|
||||
else if (decimal.gte(1e3)) return commaFormat(decimal, 0)
|
||||
else return regularFormat(decimal, precision)
|
||||
}
|
||||
|
||||
function formatWhole(decimal) {
|
||||
decimal = new Decimal(decimal)
|
||||
if (decimal.gte(1e9)) return format(decimal, 2)
|
||||
if (decimal.lte(0.98) && !decimal.eq(0)) return format(decimal, 2)
|
||||
return format(decimal, 0)
|
||||
}
|
||||
|
||||
function formatTime(s) {
|
||||
if (s < 60) return format(s) + "s"
|
||||
else if (s < 3600) return formatWhole(Math.floor(s / 60)) + "m " + format(s % 60) + "s"
|
||||
else if (s < 86400) return formatWhole(Math.floor(s / 3600)) + "h " + formatWhole(Math.floor(s / 60) % 60) + "m " + format(s % 60) + "s"
|
||||
else if (s < 31536000) return formatWhole(Math.floor(s / 84600) % 365) + "d " + formatWhole(Math.floor(s / 3600) % 24) + "h " + formatWhole(Math.floor(s / 60) % 60) + "m " + format(s % 60) + "s"
|
||||
else return formatWhole(Math.floor(s / 31536000)) + "y " + formatWhole(Math.floor(s / 84600) % 365) + "d " + formatWhole(Math.floor(s / 3600) % 24) + "h " + formatWhole(Math.floor(s / 60) % 60) + "m " + format(s % 60) + "s"
|
||||
}
|
||||
|
||||
function toPlaces(x, precision, maxAccepted) {
|
||||
x = new Decimal(x)
|
||||
let result = x.toStringWithDecimalPlaces(precision)
|
||||
if (new Decimal(result).gte(maxAccepted)) {
|
||||
result = new Decimal(maxAccepted - Math.pow(0.1, precision)).toStringWithDecimalPlaces(precision)
|
||||
}
|
||||
return result
|
||||
}
|
52
js/utils/options.js
Normal file
52
js/utils/options.js
Normal file
|
@ -0,0 +1,52 @@
|
|||
// ************ Options ************
|
||||
function toggleOpt(name) {
|
||||
if (name == "oldStyle" && styleCooldown > 0)
|
||||
return;
|
||||
|
||||
player[name] = !player[name];
|
||||
if (name == "hqTree")
|
||||
changeTreeQuality();
|
||||
if (name == "oldStyle")
|
||||
updateStyle();
|
||||
}
|
||||
var styleCooldown = 0;
|
||||
function updateStyle() {
|
||||
styleCooldown = 1;
|
||||
let css = document.getElementById("styleStuff");
|
||||
css.href = player.oldStyle ? "oldStyle.css" : "style.css";
|
||||
needCanvasUpdate = true;
|
||||
}
|
||||
function changeTreeQuality() {
|
||||
var on = player.hqTree;
|
||||
document.body.style.setProperty('--hqProperty1', on ? "2px solid" : "4px solid");
|
||||
document.body.style.setProperty('--hqProperty2a', on ? "-4px -4px 4px rgba(0, 0, 0, 0.25) inset" : "-4px -4px 4px rgba(0, 0, 0, 0) inset");
|
||||
document.body.style.setProperty('--hqProperty2b', on ? "0px 0px 20px var(--background)" : "");
|
||||
document.body.style.setProperty('--hqProperty3', on ? "2px 2px 4px rgba(0, 0, 0, 0.25)" : "none");
|
||||
}
|
||||
function toggleAuto(toggle) {
|
||||
player[toggle[0]][toggle[1]] = !player[toggle[0]][toggle[1]];
|
||||
}
|
||||
function adjustMSDisp() {
|
||||
let displays = ["always", "automation", "incomplete", "never"];
|
||||
player.msDisplay = displays[(displays.indexOf(player.msDisplay) + 1) % 4];
|
||||
}
|
||||
function milestoneShown(layer, id) {
|
||||
complete = player[layer].milestones.includes(id);
|
||||
auto = layers[layer].milestones[id].toggles;
|
||||
|
||||
switch (player.msDisplay) {
|
||||
case "always":
|
||||
return true;
|
||||
break;
|
||||
case "automation":
|
||||
return (auto) || !complete;
|
||||
break;
|
||||
case "incomplete":
|
||||
return !complete;
|
||||
break;
|
||||
case "never":
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
278
js/utils/save.js
Normal file
278
js/utils/save.js
Normal file
|
@ -0,0 +1,278 @@
|
|||
// ************ 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);
|
30
js/utils/themes.js
Normal file
30
js/utils/themes.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
// ************ Themes ************
|
||||
const themes = {
|
||||
1: "aqua"
|
||||
};
|
||||
const theme_names = {
|
||||
aqua: "Aqua"
|
||||
};
|
||||
function changeTheme() {
|
||||
let aqua = player.theme == "aqua";
|
||||
colors_theme = colors[player.theme || "default"];
|
||||
document.body.style.setProperty('--background', aqua ? "#001f3f" : "#0f0f0f");
|
||||
document.body.style.setProperty('--background_tooltip', aqua ? "rgba(0, 15, 31, 0.75)" : "rgba(0, 0, 0, 0.75)");
|
||||
document.body.style.setProperty('--color', aqua ? "#bfdfff" : "#dfdfdf");
|
||||
document.body.style.setProperty('--points', aqua ? "#dfefff" : "#ffffff");
|
||||
document.body.style.setProperty("--locked", aqua ? "#c4a7b3" : "#bf8f8f");
|
||||
}
|
||||
function getThemeName() {
|
||||
return player.theme ? theme_names[player.theme] : "Default";
|
||||
}
|
||||
function switchTheme() {
|
||||
if (player.theme === undefined)
|
||||
player.theme = themes[1];
|
||||
else {
|
||||
player.theme = themes[Object.keys(themes)[player.theme] + 1];
|
||||
if (!player.theme)
|
||||
delete player.theme;
|
||||
}
|
||||
changeTheme();
|
||||
resizeCanvas();
|
||||
}
|
Loading…
Reference in a new issue