var Engine = { Debug: true, //Clickable objects Clickables: { //Main menu buttons terminalMainMenuButton: null, characterMainMenuButton: null, scriptEditorMainMenuButton: null, activeScriptsMainMenuButton: null, worldMainMenuButton: null, createProgramMainMenuButton: null, factionsMainMenuButton: null, augmentationsMainMenuButton: null, tutorialMainMenuButton: null, saveMainMenuButton: null, deleteMainMenuButton: null, }, //Display objects Display: { //Progress bar progress: null, //Display for status text (such as "Saved" or "Loaded") statusText: null, hacking_skill: null, //Main menu content terminalContent: null, characterContent: null, scriptEditorContent: null, activeScriptsContent: null, worldContent: null, createProgramContent: null, factionsContent: null, factionContent: null, augmentationsContent: null, tutorialContent: null, locationContent: null, workInProgressContent: null, //Character info characterInfo: null, //Script editor text scriptEditorText: null, }, //Current page status Page: { Terminal: "Terminal", CharacterInfo: "CharacterInfo", ScriptEditor: "ScriptEditor", ActiveScripts: "ActiveScripts", World: "World", CreateProgram: "CreateProgram", Factions: "Factions", Faction: "Faction", Augmentations: "Augmentations", Tutorial: "Tutorial", Location: "Location", workInProgress: "WorkInProgress", }, currentPage: null, //Time variables (milliseconds unix epoch time) _lastUpdate: new Date().getTime(), _idleSpeed: 200, //Speed (in ms) at which the main loop is updated //Save function saveGame: function() { var PlayerSave = JSON.stringify(Player); var AllServersSave = JSON.stringify(AllServers); var CompaniesSave = JSON.stringify(Companies); var FactionsSave = JSON.stringify(Factions); var SpecialServerIpsSave = JSON.stringify(SpecialServerIps); var AugmentationsSave = JSON.stringify(Augmentations); window.localStorage.setItem("netburnerPlayerSave", PlayerSave); window.localStorage.setItem("netburnerAllServersSave", AllServersSave); window.localStorage.setItem("netburnerCompaniesSave", CompaniesSave); window.localStorage.setItem("netburnerFactionsSave", FactionsSave); window.localStorage.setItem("netburnerSpecialServerIpsSave", SpecialServerIpsSave); window.localStorage.setItem("netburnerAugmentationsSave", AugmentationsSave); console.log("Game saved to local storage"); }, //Load saved game function loadSave: function() { //Check to see if file exists if (!window.localStorage.getItem("netburnerPlayerSave")) { console.log("No Player save to load"); return false; } else if (!window.localStorage.getItem("netburnerAllServersSave")) { console.log("No AllServers save to load"); return false; } else if (!window.localStorage.getItem("netburnerCompaniesSave")) { console.log("No Companies save to load"); return false; } else if (!window.localStorage.getItem("netburnerFactionsSave")) { console.log("No Factions save to load"); return false; } else if (!window.localStorage.getItem("netburnerSpecialServerIpsSave")) { console.log("No Special Server Ips save to load"); return false; } else if (!window.localStorage.getItem("netburnerAugmentationsSave")) { console.log("No Augmentations save to load"); return false; } else { var PlayerSave = window.localStorage.getItem("netburnerPlayerSave"); var AllServersSave = window.localStorage.getItem("netburnerAllServersSave"); var CompaniesSave = window.localStorage.getItem("netburnerCompaniesSave"); var FactionsSave = window.localStorage.getItem("netburnerFactionsSave"); var SpecialServerIpsSave = window.localStorage.getItem("netburnerSpecialServerIpsSave"); var AugmentationsSave = window.localStorage.getItem("netburnerAugmentationsSave"); Player = JSON.parse(PlayerSave, Reviver); AllServers = JSON.parse(AllServersSave, Reviver); Companies = JSON.parse(CompaniesSave, Reviver); Factions = JSON.parse(FactionsSave, Reviver); SpecialServerIps = JSON.parse(SpecialServerIpsSave, Reviver); Augmentations = JSON.parse(AugmentationsSave, Reviver); return true; } }, //Delete saved game function deleteSave: function() { //TODO if a save doesn't exist..maybe I shouldn't return? I just keep going //or else nothing gets deleted. TODO Fix this if (window.localStorage.getItem("netburnerPlayerSave")) { window.localStorage.removeItem("netburnerPlayerSave"); } if (window.localStorage.getItem("netburnerAllServersSave")) { window.localStorage.removeItem("netburnerAllServersSave"); } if (window.localStorage.getItem("netburnerCompaniesSave")) { window.localStorage.removeItem("netburnerCompaniesSave"); } if (window.localStorage.getItem("netburnerFactionsSave")) { window.localStorage.removeItem("netburnerFactionsSave"); } if (window.localStorage.getItem("netburnerSpecialServerIpsSave")) { window.localStorage.removeItem("netburnerSpecialServerIpsSave"); } if (window.localStorage.getItem("netburnerAugmentationsSave")) { window.localStorage.removeItem("netburnerAugmentationsSave"); } }, /* Load content when a main menu button is clicked */ loadTerminalContent: function() { Engine.hideAllContent(); Engine.Display.terminalContent.style.visibility = "visible"; Engine.currentPage = Engine.Page.Terminal; }, loadCharacterContent: function() { Engine.hideAllContent(); Engine.Display.characterContent.style.visibility = "visible"; Engine.displayCharacterInfo(); Engine.currentPage = Engine.Page.CharacterInfo; }, loadScriptEditorContent: function(filename = "", code = "") { Engine.hideAllContent(); Engine.Display.scriptEditorContent.style.visibility = "visible"; if (filename == "") { document.getElementById("script-editor-filename").value = "untitled"; } else { document.getElementById("script-editor-filename").value = filename; } document.getElementById("script-editor-text").value = code; Engine.currentPage = Engine.Page.ScriptEditor; }, loadActiveScriptsContent: function() { Engine.hideAllContent(); Engine.Display.activeScriptsContent.style.visibility = "visible"; Engine.currentPage = Engine.Page.ActiveScripts; }, loadWorldContent: function() { Engine.hideAllContent(); Engine.Display.worldContent.style.visibility = "visible"; Engine.displayWorldInfo(); Engine.currentPage = Engine.Page.World; }, loadCreateProgramContent: function() { Engine.hideAllContent(); Engine.Display.createProgramContent.style.visibility = "visible"; Engine.currentPage = Engine.Page.CreateProgram; }, loadFactionsContent: function() { Engine.hideAllContent(); Engine.Display.factionsContent.style.visibility = "visible"; Engine.displayFactionsInfo(); Engine.currentPage = Engine.Page.Factions; }, loadFactionContent: function() { Engine.hideAllContent(); Engine.Display.factionContent.style.visibility = "visible"; Engine.currentPage = Engine.Page.Faction; }, loadAugmentationsContent: function() { Engine.hideAllContent(); Engine.Display.augmentationsContent.style.visibility = "visible"; Engine.displayAugmentationsContent(); Engine.currentPage = Engine.Page.Augmentations; }, loadTutorialContent: function() { Engine.hideAllContent(); Engine.Display.tutorialContent.style.visibility = "visible"; Engine.currentPage = Engine.Page.Tutorial; }, loadLocationContent: function() { Engine.hideAllContent(); Engine.Display.locationContent.style.visibility = "visible"; displayLocationContent(); Engine.currentPage = Engine.Page.Location; }, loadWorkInProgressContent: function() { Engine.hideAllContent(); var mainMenu = document.getElementById("mainmenu-container"); mainMenu.style.visibility = "hidden"; Engine.Display.workInProgressContent.style.visibility = "visible"; Engine.currentPage = Engine.Page.WorkInProgress; }, //Helper function that hides all content hideAllContent: function() { Engine.Display.terminalContent.style.visibility = "hidden"; Engine.Display.characterContent.style.visibility = "hidden"; Engine.Display.scriptEditorContent.style.visibility = "hidden"; Engine.Display.activeScriptsContent.style.visibility = "hidden"; Engine.Display.worldContent.style.visibility = "hidden"; Engine.Display.createProgramContent.style.visibility = "hidden"; Engine.Display.factionsContent.style.visibility = "hidden"; Engine.Display.factionContent.style.visibility = "hidden"; Engine.Display.augmentationsContent.style.visibility = "hidden"; Engine.Display.tutorialContent.style.visibility = "hidden"; Engine.Display.locationContent.style.visibility = "hidden"; Engine.Display.workInProgressContent.style.visibility = "hidden"; //Location lists Engine.aevumLocationsList.style.display = "none"; Engine.chongqingLocationsList.style.display = "none"; Engine.sector12LocationsList.style.display = "none"; Engine.newTokyoLocationsList.style.display = "none"; Engine.ishimaLocationsList.style.display = "none"; Engine.volhavenLocationsList.style.display = "none"; }, /* Display character info */ displayCharacterInfo: function() { var companyPosition = ""; if (Player.companyPosition != "") { companyPosition = Player.companyPosition.positionName; } Engine.Display.characterInfo.innerHTML = 'Current City: ' + Player.city + '

' + 'Employer: ' + Player.companyName + '

' + 'Job Title: ' + companyPosition + '



' + 'Money: $' + (Player.money.toFixed(2)).toLocaleString() + '

' + 'Hacking Level: ' + (Player.hacking_skill).toLocaleString() + '

' + 'Strength: ' + (Player.strength.toLocaleString() + '

' + 'Defense: ' + (Player.defense).toLocaleString() + '

' + 'Dexterity: ' + (Player.dexterity).toLocaleString() + '

' + 'Agility: ' + (Player.agility).toLocaleString() + '

' + 'Charisma: ' + (Player.charisma).toLocaleString() + '

' + 'Servers owned: ' + Player.purchasedServers.length + '

' + 'Hacking experience: ' + (Player.hacking_exp.toFixed(4)).toLocaleString() + '

' + 'Strength experience: ' + (Player.strength_exp.toFixed(4)).toLocaleString() + '

' + 'Defense experience: ' + (Player.defense_exp.toFixed(4)).toLocaleString() + '

' + 'Dexterity experience: ' + (Player.dexterity_exp.toFixed(4)).toLocaleString() + '

' + 'Agility experience: ' + (Player.agility_exp.toFixed(4)).toLocaleString() + '

' + 'Charisma experience: ' + (Player.charisma_exp.toFixed(4)).toLocaleString() + '

'; }, /* Display locations in the world*/ aevumLocationsList: null, chongqingLocationsList: null, sector12LocationsList: null, newTokyoLocationsList: null, ishimaLocationsList: null, volhavenLocationsList: null, displayWorldInfo: function() { Engine.aevumLocationsList.style.display = "none"; Engine.chongqingLocationsList.style.display = "none"; Engine.sector12LocationsList.style.display = "none"; Engine.newTokyoLocationsList.style.display = "none"; Engine.ishimaLocationsList.style.display = "none"; Engine.volhavenLocationsList.style.display = "none"; switch(Player.city) { case Locations.Aevum: Engine.aevumLocationsList.style.display = "inline"; break; case Locations.Chongqing: Engine.chongqingLocationsList.style.display = "inline"; break; case Locations.Sector12: Engine.sector12LocationsList.style.display = "inline"; break; case Locations.NewTokyo: Engine.newTokyoLocationsList.style.display = "inline"; break; case Locations.Ishima: Engine.ishimaLocationsList.style.display = "inline"; break; case Locations.Volhaven: Engine.volhavenLocationsList.style.display = "inline"; break; default: console.log("Invalid city value in Player object!"); break; } }, /* Functions used to update information on the Active Scripts page */ ActiveScriptsList: null, //Creates and adds the
  • object for a given workerScript addActiveScriptsItem: function(workerscript) { var item = document.createElement("li"); Engine.createActiveScriptsText(workerscript, item); //Add the li element onto the list if (Engine.ActiveScriptsList == null) { Engine.ActiveScriptsList = document.getElementById("active-scripts-list"); } Engine.ActiveScriptsList.appendChild(item); }, deleteActiveScriptsItem: function(i) { var list = Engine.ActiveScriptsList.querySelectorAll('#active-scripts-list li'); if (i >= list.length) { throw new Error("Trying to delete an out-of-range Active Scripts item"); } var li = list[i]; li.parentNode.removeChild(li); }, //Update the ActiveScriptsItems array updateActiveScriptsItems: function() { for (var i = 0; i < workerScripts.length; ++i) { Engine.updateActiveScriptsItemContent(i, workerScripts[i]); } }, //Updates the content of the given item in the Active Scripts list updateActiveScriptsItemContent: function(i, workerscript) { var list = Engine.ActiveScriptsList.getElementsByTagName("li"); if (i >= list.length) { throw new Error("Trying to update an out-of-range Active Scripts Item"); } var item = list[i]; //Clear the item while (item.firstChild) { item.removeChild(item.firstChild); } //Add the updated text back Engine.createActiveScriptsText(workerscript, item); }, createActiveScriptsText: function(workerscript, item) { //Script name var scriptName = document.createElement("h2"); scriptName.appendChild(document.createTextNode(workerscript.name)); item.appendChild(scriptName); var itemText = document.createElement("p"); //Server ip/hostname var hostname = workerscript.getServer().hostname; var serverIpHostname = "Server: " + hostname + "(" + workerscript.serverIp + ")"; //Online var onlineMps = workerscript.scriptRef.onlineMoneyMade / workerscript.scriptRef.onlineRunningTime; var onlineMpsText = "Online production: $" + onlineMps.toFixed(2) + "/second"; var onlineEps = workerscript.scriptRef.onlineExpGained / workerscript.scriptRef.onlineRunningTime; var onlineEpsText = (Array(20).join(" ") + onlineEps.toFixed(4) + " exp/second").replace( / /g, " "); //Offline var offlineMps = workerscript.scriptRef.offlineMoneyMade / workerscript.scriptRef.offlineRunningTime; var offlineMpsText = "Offline production: $" + offlineMps.toFixed(2) + "/second"; var offlineEps = workerscript.scriptRef.offlineExpGained / workerscript.scriptRef.offlineRunningTime; var offlineEpsText = (Array(21).join(" ") + offlineEps.toFixed(4) + " exp/second").replace( / /g, " "); itemText.innerHTML = serverIpHostname + "
    " + onlineMpsText + "
    " + onlineEpsText + "
    " + offlineMpsText + "
    " + offlineEpsText + "
    "; item.appendChild(itemText); }, displayFactionsInfo: function() { var factionsList = document.getElementById("factions-list"); for (var i = 0; i < Player.factions.length; ++i) { var factionName = Player.factions[i]; //Add the faction to the Factions page content var item = document.createElement("li"); var aElem = document.createElement("a"); aElem.setAttribute("href", "#"); aElem.setAttribute("class", "a-link-button"); aElem.innerHTML = factionName; aElem.addEventListener("click", function() { Engine.loadFactionContent(); displayFactionContent(factionName); return false; }); item.appendChild(aElem); factionsList.appendChild(item); } }, displayAugmentationsContent: function() { var augmentationsList = document.getElementById("augmentations-list"); for (var i = 0; i < Player.augmentations.length; ++i) { var augName = Player.augmentations[i]; var aug = Augmentations[augName]; var item = document.createElement("li"); var hElem = document.createElement("h2"); var pElem = document.createElement("p"); item.setAttribute("class", "installed-augmentation"); hElem.innerHTML = augName; pElem.innerHTML = aug.info; item.appendChild(hElem); item.appendChild(pElem); augmentationsList.appendChild(item); } }, /* Main Event Loop */ idleTimer: function() { //Get time difference var _thisUpdate = new Date().getTime(); var diff = _thisUpdate - Engine._lastUpdate; var offset = diff % Engine._idleSpeed; //Divide this by cycle time to determine how many cycles have elapsed since last update diff = Math.floor(diff / Engine._idleSpeed); if (diff > 0) { //Update the game engine by the calculated number of cycles Engine.updateGame(diff); Engine._lastUpdate = _thisUpdate - offset; Player.lastUpdate = _thisUpdate - offset; } window.requestAnimationFrame(Engine.idleTimer); }, updateGame: function(numCycles = 1) { //Start Manual hack if (Player.startAction == true) { Engine._totalActionTime = Player.actionTime; Engine._actionTimeLeft = Player.actionTime; Engine._actionInProgress = true; Engine._actionProgressBarCount = 1; Engine._actionProgressStr = "[ ]"; Engine._actionTimeStr = "Time left: "; Player.startAction = false; } if (Player.isWorking) { Player.work(numCycles); } //Counters Engine.decrementAllCounters(numCycles); Engine.checkCounters(); //Manual hacks if (Engine._actionInProgress == true) { Engine.updateHackProgress(numCycles); } //Update the running time of all active scripts updateOnlineScriptTimes(numCycles); }, //Counters for the main event loop. Represent the number of game cycles are required //for something to happen. Counters: { autoSaveCounter: 300, //Autosave every minute updateSkillLevelsCounter: 10, //Only update skill levels every 2 seconds. Might improve performance updateDisplays: 10, //Update displays such as Active Scripts display and character display serverGrowth: 450, //Process server growth every minute and a half //checkFactionInvitations: 1500, //Check whether you qualify for any faction invitations every 5 minutes checkFactionInvitations: 30, }, decrementAllCounters: function(numCycles = 1) { for (var counter in Engine.Counters) { if (Engine.Counters.hasOwnProperty(counter)) { Engine.Counters[counter] = Engine.Counters[counter] - numCycles; } } }, //Checks if any counters are 0 and if they are, executes whatever //is necessary and then resets the counter checkCounters: function() { if (Engine.Counters.autoSaveCounter <= 0) { Engine.saveGame(); Engine.Counters.autoSaveCounter = 300; } if (Engine.Counters.updateSkillLevelsCounter <= 0) { Player.updateSkillLevels(); Engine.Counters.updateSkillLevelsCounter = 10; } if (Engine.Counters.updateDisplays <= 0) { if (Engine.currentPage == Engine.Page.ActiveScripts) { Engine.updateActiveScriptsItems(); } else if (Engine.currentPage == Engine.Page.CharacterInfo) { Engine.displayCharacterInfo(); } Engine.Counters.updateDisplays = 10; } if (Engine.Counters.serverGrowth <= 0) { var numCycles = Math.floor((450 - Engine.Counters.serverGrowth)); processServerGrowth(numCycles); Engine.Counters.serverGrowth = 450; } if (Engine.Counters.checkFactionInvitations <= 0) { var invitedFactions = Player.checkForFactionInvitations(); if (invitedFactions.length > 0) { var randFaction = invitedFactions[Math.floor(Math.random() * invitedFactions.length)]; inviteToFaction(randFaction); } Engine.Counters.checkFactionInvitations = 1500; } }, /* Calculates the hack progress for a manual (non-scripted) hack and updates the progress bar/time accordingly */ _totalActionTime: 0, _actionTimeLeft: 0, _actionTimeStr: "Time left: ", _actionProgressStr: "[ ]", _actionProgressBarCount: 1, _actionInProgress: false, updateHackProgress: function(numCycles = 1) { var timeElapsedMilli = numCycles * Engine._idleSpeed; Engine._actionTimeLeft -= (timeElapsedMilli/ 1000); //Substract idle speed (ms) //Calculate percent filled var percent = Math.round((1 - Engine._actionTimeLeft / Engine._totalActionTime) * 100); //Update progress bar while (Engine._actionProgressBarCount * 2 <= percent) { Engine._actionProgressStr = Engine._actionProgressStr.replaceAt(Engine._actionProgressBarCount, "|"); Engine._actionProgressBarCount += 1; } //Update hack time remaining Engine._actionTimeStr = "Time left: " + Math.max(0, Math.round(Engine._actionTimeLeft)).toString() + "s"; document.getElementById("hack-progress").innerHTML = Engine._actionTimeStr; //Dynamically update progress bar document.getElementById("hack-progress-bar").innerHTML = Engine._actionProgressStr.replace( / /g, " " ); //Once percent is 100, the hack is completed if (percent >= 100) { Engine._actionInProgress = false; Terminal.finishAction(); } }, /* Initialization */ init: function() { //Main menu buttons and content Engine.Clickables.terminalMainMenuButton = document.getElementById("terminal-menu-link"); Engine.Clickables.terminalMainMenuButton.addEventListener("click", function() { Engine.loadTerminalContent(); return false; }); Engine.Clickables.characterMainMenuButton = document.getElementById("character-menu-link"); Engine.Clickables.characterMainMenuButton.addEventListener("click", function() { Engine.loadCharacterContent(); return false; }); Engine.Clickables.scriptEditorMainMenuButton = document.getElementById("create-script-menu-link"); Engine.Clickables.scriptEditorMainMenuButton.addEventListener("click", function() { Engine.loadScriptEditorContent(); return false; }); Engine.Clickables.activeScriptsMainMenuButton = document.getElementById("active-scripts-menu-link"); Engine.Clickables.activeScriptsMainMenuButton.addEventListener("click", function() { Engine.loadActiveScriptsContent(); return false; }); Engine.Clickables.worldMainMenuButton = document.getElementById("world-menu-link"); Engine.Clickables.worldMainMenuButton.addEventListener("click", function() { Engine.loadWorldContent(); return false; }); Engine.Clickables.createProgramMainMenuButton = document.getElementById("create-program-menu-link"); Engine.Clickables.createProgramMainMenuButton.addEventListener("click", function() { Engine.loadCreateProgramContent(); return false; }); Engine.Clickables.factionsMainMenuButton = document.getElementById("factions-menu-link"); Engine.Clickables.factionsMainMenuButton.addEventListener("click", function() { Engine.loadFactionsContent(); return false; }); Engine.Clickables.augmentationsMainMenuButton = document.getElementById("augmentations-menu-link"); Engine.Clickables.augmentationsMainMenuButton.addEventListener("click", function() { Engine.loadAugmentationsContent(); return false; }); Engine.Clickables.tutorialMainMenuButton = document.getElementById("tutorial-menu-link"); Engine.Clickables.tutorialMainMenuButton.addEventListener("click", function() { Engine.loadTutorialContent(); return false; }); //Active scripts list Engine.ActiveScriptsList = document.getElementById("active-scripts-list"); Engine.Clickables.saveMainMenuButton = document.getElementById("save-game-link"); Engine.Clickables.saveMainMenuButton.addEventListener("click", function() { Engine.saveGame(); return false; }); Engine.Clickables.deleteMainMenuButton = document.getElementById("delete-game-link"); Engine.Clickables.deleteMainMenuButton.addEventListener("click", function() { Engine.deleteSave(); return false; }); Engine.Display.terminalContent = document.getElementById("terminal-container"); Engine.currentPage = Engine.Page.Terminal; Engine.Display.characterContent = document.getElementById("character-container"); Engine.Display.characterContent.style.visibility = "hidden"; Engine.Display.scriptEditorContent = document.getElementById("script-editor-container"); Engine.Display.scriptEditorContent.style.visibility = "hidden"; Engine.Display.activeScriptsContent = document.getElementById("active-scripts-container"); Engine.Display.activeScriptsContent.style.visibility = "hidden"; Engine.Display.worldContent = document.getElementById("world-container"); Engine.Display.worldContent.style.visibility = "hidden"; Engine.Display.createProgramContent = document.getElementById("create-program-container"); Engine.Display.createProgramContent.style.visibility = "hidden"; Engine.Display.factionsContent = document.getElementById("factions-container"); Engine.Display.factionsContent.style.visibility = "hidden"; Engine.Display.factionContent = document.getElementById("faction-container"); Engine.Display.factionContent.style.visibility = "hidden"; Engine.Display.augmentationsContent = document.getElementById("augmentations-container"); Engine.Display.augmentationsContent.style.visibility = "hidden"; Engine.Display.tutorialContent = document.getElementById("tutorial-container"); Engine.Display.tutorialContent.style.visibility = "hidden"; //Character info Engine.Display.characterInfo = document.getElementById("character-info"); //Location lists Engine.aevumLocationsList = document.getElementById("aevum-locations-list"); Engine.chongqingLocationsList = document.getElementById("chongqing-locations-list"); Engine.sector12LocationsList = document.getElementById("sector12-locations-list"); Engine.newTokyoLocationsList = document.getElementById("newtokyo-locations-list"); Engine.ishimaLocationsList = document.getElementById("ishima-locations-list"); Engine.volhavenLocationsList = document.getElementById("volhaven-locations-list"); //Location page (page that shows up when you visit a specific location in World) Engine.Display.locationContent = document.getElementById("location-container"); Engine.Display.locationContent.style.visibility = "hidden"; //Work In Progress Engine.Display.workInProgressContent = document.getElementById("work-in-progress-container"); Engine.Display.workInProgressContent.style.visibility = "hidden"; //Init Location buttons initLocationButtons(); //Script editor Engine.Display.scriptEditorText = document.getElementById("script-editor-text"); //Load game from save or create new game if (Engine.loadSave()) { console.log("Loaded game from save"); CompanyPositions.init(); //Calculate the number of cycles have elapsed while offline var thisUpdate = new Date().getTime(); var lastUpdate = Player.lastUpdate; var numCyclesOffline = Math.floor((thisUpdate - lastUpdate) / Engine._idleSpeed); processServerGrowth(numCyclesOffline); //Should be done before offline production for scripts loadAllRunningScripts(); //This also takes care of offline production for those scripts Player.work(numCyclesOffline); } else { //No save found, start new game console.log("Initializing new game"); SpecialServerIps = new SpecialServerIpsMap(); Player.init(); initForeignServers(); initCompanies(); initFactions(); CompanyPositions.init(); initAugmentations(); } //Message at the top of terminal postNetburnerText(); //Player was working if (Player.isWorking) { var cancelButton = document.getElementById("work-in-progress-cancel-button"); cancelButton.addEventListener("click", function() { Player.finishWork(true); }); Engine.loadWorkInProgressContent(); } //Run main loop Engine.idleTimer(); //Scripts runScriptsLoop(); } }; window.onload = function() { Engine.init(); };