2021-01-06 20:56:06 +00:00
// ************ Save stuff ************
2021-06-07 21:54:29 +00:00
function save ( force ) {
2021-06-05 00:36:44 +00:00
NaNcheck ( player )
2021-06-07 21:54:29 +00:00
if ( NaNalert && ! force ) return
2021-04-07 18:27:40 +00:00
localStorage . setItem ( modInfo . id , btoa ( unescape ( encodeURIComponent ( JSON . stringify ( player ) ) ) ) ) ;
2021-06-03 05:04:56 +00:00
localStorage . setItem ( modInfo . id + "_options" , btoa ( unescape ( encodeURIComponent ( JSON . stringify ( options ) ) ) ) ) ;
2021-01-06 20:56:06 +00:00
}
function startPlayerBase ( ) {
return {
tab : layoutInfo . startTab ,
2021-05-27 04:54:58 +00:00
navTab : ( layoutInfo . showTree ? layoutInfo . startNavTab : "none" ) ,
2021-01-06 20:56:06 +00:00
time : Date . now ( ) ,
notify : { } ,
versionType : modInfo . id ,
version : VERSION . num ,
beta : VERSION . beta ,
timePlayed : 0 ,
keepGoing : false ,
hasNaN : false ,
2021-06-03 05:04:56 +00:00
2021-01-06 20:56:06 +00:00
points : modInfo . initialStartPoints ,
subtabs : { } ,
2021-05-06 19:45:03 +00:00
lastSafeTab : ( readData ( layoutInfo . showTree ) ? "none" : layoutInfo . startTab )
2021-01-06 20:56:06 +00:00
} ;
}
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 )
2021-05-11 00:19:29 +00:00
layerdata . total = decimalZero ;
2021-01-06 20:56:06 +00:00
if ( layerdata . best === undefined )
2021-05-11 00:19:29 +00:00
layerdata . best = decimalZero ;
2021-01-06 20:56:06 +00:00
if ( layerdata . resetTime === undefined )
layerdata . resetTime = 0 ;
2021-04-27 05:26:07 +00:00
if ( layerdata . forceTooltip === undefined )
layerdata . forceTooltip = false ;
2021-01-06 20:56:06 +00:00
layerdata . buyables = getStartBuyables ( layer ) ;
2021-04-29 21:49:35 +00:00
if ( layerdata . noRespecConfirm === undefined ) layerdata . noRespecConfirm = false
2021-01-06 20:56:06 +00:00
if ( layerdata . clickables == undefined )
layerdata . clickables = getStartClickables ( layer ) ;
2021-05-11 00:19:29 +00:00
layerdata . spentOnBuyables = decimalZero ;
2021-01-06 20:56:06 +00:00
layerdata . upgrades = [ ] ;
layerdata . milestones = [ ] ;
2021-05-06 20:26:44 +00:00
layerdata . lastMilestone = null ;
2021-01-06 20:56:06 +00:00
layerdata . achievements = [ ] ;
layerdata . challenges = getStartChallenges ( layer ) ;
2021-05-11 06:27:50 +00:00
layerdata . grid = getStartGrid ( layer ) ;
2021-05-26 05:44:12 +00:00
layerdata . prevTab = ""
2021-05-11 06:27:50 +00:00
2021-01-06 20:56:06 +00:00
return layerdata ;
}
function getStartBuyables ( layer ) {
let data = { } ;
if ( layers [ layer ] . buyables ) {
for ( id in layers [ layer ] . buyables )
if ( isPlainObject ( layers [ layer ] . buyables [ id ] ) )
2021-05-11 00:19:29 +00:00
data [ id ] = decimalZero ;
2021-01-06 20:56:06 +00:00
}
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 ;
}
2021-05-11 06:27:50 +00:00
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 ;
}
2021-01-06 20:56:06 +00:00
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 ) ;
2021-06-03 05:04:56 +00:00
if ( get === null || get === undefined ) {
2021-01-06 20:56:06 +00:00
player = getStartPlayer ( ) ;
2021-06-03 05:04:56 +00:00
options = getStartOptions ( ) ;
}
else {
2021-04-30 01:34:56 +00:00
player = Object . assign ( getStartPlayer ( ) , JSON . parse ( decodeURIComponent ( escape ( atob ( get ) ) ) ) ) ;
2021-06-03 05:04:56 +00:00
fixSave ( ) ;
loadOptions ( ) ;
}
2021-01-06 20:56:06 +00:00
2021-07-07 16:58:30 +00:00
if ( options . offlineProd ) {
2021-01-06 20:56:06 +00:00
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 ( ) ;
2021-05-10 01:39:15 +00:00
updateTabFormats ( )
2021-01-06 20:56:06 +00:00
loadVue ( ) ;
}
2021-06-03 05:04:56 +00:00
function loadOptions ( ) {
let get2 = localStorage . getItem ( modInfo . id + "_options" ) ;
if ( get2 )
options = Object . assign ( getStartOptions ( ) , JSON . parse ( decodeURIComponent ( escape ( atob ( get2 ) ) ) ) ) ;
else
options = getStartOptions ( )
2021-06-07 03:45:32 +00:00
if ( themes . indexOf ( options . theme ) < 0 ) theme = "default"
2021-09-08 21:45:19 +00:00
fixData ( options , getStartOptions ( ) )
2021-06-03 05:04:56 +00:00
}
2021-01-06 20:56:06 +00:00
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 ] ) ;
}
2021-06-02 21:39:19 +00:00
else if ( data [ item ] !== data [ item ] || checkDecimalNaN ( data [ item ] ) ) {
if ( ! NaNalert ) {
2021-01-06 20:56:06 +00:00
clearInterval ( interval ) ;
NaNalert = true ;
2021-06-17 15:51:40 +00:00
alert ( "Invalid value found in player, named '" + item + "'. Please let the creator of this mod know! You can refresh the page, and you will be un-NaNed." )
2021-06-02 21:39:19 +00:00
return
2021-01-06 20:56:06 +00:00
}
}
2021-06-17 15:51:40 +00:00
else if ( data [ item ] instanceof Decimal ) {
2021-01-06 20:56:06 +00:00
}
else if ( ( ! ! data [ item ] ) && ( data [ item ] . constructor === Object ) ) {
NaNcheck ( data [ item ] ) ;
}
}
}
function exportSave ( ) {
2021-06-07 21:54:29 +00:00
//if (NaNalert) return
2021-01-06 20:56:06 +00:00
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 ( ) ;
2021-06-07 21:54:29 +00:00
NaNcheck ( save )
2021-01-06 20:56:06 +00:00
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 ;
2021-06-17 17:40:55 +00:00
if ( tmp . gameEnded && ! player . keepGoing )
2021-01-06 20:56:06 +00:00
return ;
2021-06-03 05:04:56 +00:00
if ( options . autosave )
2021-01-06 20:56:06 +00:00
save ( ) ;
} , 5000 ) ;
2021-06-17 15:51:40 +00:00
window . onbeforeunload = ( ) => {
if ( player . autosave ) {
save ( ) ;
}
} ;