mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-17 06:48:42 +02:00
Various QOL improvements and bug fixes
This commit is contained in:
@@ -1,21 +1,22 @@
|
||||
import {workerScripts,
|
||||
killWorkerScript} from "./NetscriptWorker";
|
||||
import {Player} from "./Player";
|
||||
import {getServer} from "./Server";
|
||||
import {numeralWrapper} from "./ui/numeralFormat";
|
||||
import {dialogBoxCreate} from "../utils/DialogBox";
|
||||
import {createAccordionElement} from "../utils/uiHelpers/createAccordionElement";
|
||||
import {arrayToString} from "../utils/helpers/arrayToString";
|
||||
import {createElement} from "../utils/uiHelpers/createElement";
|
||||
import {createProgressBarText} from "../utils/helpers/createProgressBarText";
|
||||
import {exceptionAlert} from "../utils/helpers/exceptionAlert";
|
||||
import {getElementById} from "../utils/uiHelpers/getElementById";
|
||||
import {logBoxCreate} from "../utils/LogBox";
|
||||
import {formatNumber} from "../utils/StringHelperFunctions";
|
||||
import {removeChildrenFromElement} from "../utils/uiHelpers/removeChildrenFromElement";
|
||||
import {removeElement} from "../utils/uiHelpers/removeElement";
|
||||
import {roundToTwo} from "../utils/helpers/roundToTwo";
|
||||
import {Page, routing} from "./ui/navigationTracking";
|
||||
killWorkerScript} from "./NetscriptWorker";
|
||||
import {Player} from "./Player";
|
||||
import {getServer} from "./Server";
|
||||
import {numeralWrapper} from "./ui/numeralFormat";
|
||||
import {dialogBoxCreate} from "../utils/DialogBox";
|
||||
import {createAccordionElement} from "../utils/uiHelpers/createAccordionElement";
|
||||
import {arrayToString} from "../utils/helpers/arrayToString";
|
||||
import {createElement} from "../utils/uiHelpers/createElement";
|
||||
import {createProgressBarText} from "../utils/helpers/createProgressBarText";
|
||||
import {exceptionAlert} from "../utils/helpers/exceptionAlert";
|
||||
import {getElementById} from "../utils/uiHelpers/getElementById";
|
||||
import {logBoxCreate} from "../utils/LogBox";
|
||||
import {formatNumber,
|
||||
convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions";
|
||||
import {removeChildrenFromElement} from "../utils/uiHelpers/removeChildrenFromElement";
|
||||
import {removeElement} from "../utils/uiHelpers/removeElement";
|
||||
import {roundToTwo} from "../utils/helpers/roundToTwo";
|
||||
import {Page, routing} from "./ui/navigationTracking";
|
||||
|
||||
/* {
|
||||
* serverName: {
|
||||
@@ -242,9 +243,9 @@ function updateActiveScriptsItems(maxTasks=150) {
|
||||
}
|
||||
}
|
||||
|
||||
getElementById("active-scripts-total-production-active").innerText = numeralWrapper.format(total, '$0.000a');
|
||||
getElementById("active-scripts-total-prod-aug-total").innerText = numeralWrapper.format(Player.scriptProdSinceLastAug, '$0.000a');
|
||||
getElementById("active-scripts-total-prod-aug-avg").innerText = numeralWrapper.format(Player.scriptProdSinceLastAug / (Player.playtimeSinceLastAug/1000), '$0.000a');
|
||||
getElementById("active-scripts-total-production-active").innerText = numeralWrapper.formatMoney(total);
|
||||
getElementById("active-scripts-total-prod-aug-total").innerText = numeralWrapper.formatMoney(Player.scriptProdSinceLastAug);
|
||||
getElementById("active-scripts-total-prod-aug-avg").innerText = numeralWrapper.formatMoney(Player.scriptProdSinceLastAug / (Player.playtimeSinceLastAug/1000));
|
||||
return total;
|
||||
}
|
||||
|
||||
@@ -252,7 +253,7 @@ function updateActiveScriptsItems(maxTasks=150) {
|
||||
function updateActiveScriptsItemContent(workerscript) {
|
||||
var server = getServer(workerscript.serverIp);
|
||||
if (server == null) {
|
||||
console.log("ERROR: Invalid server IP for workerscript.");
|
||||
console.log("ERROR: Invalid server IP for workerscript in updateActiveScriptsItemContent().");
|
||||
return;
|
||||
}
|
||||
let hostname = server.hostname;
|
||||
@@ -280,7 +281,7 @@ function updateActiveScriptsItemContent(workerscript) {
|
||||
function updateActiveScriptsText(workerscript, item, itemName) {
|
||||
var server = getServer(workerscript.serverIp);
|
||||
if (server == null) {
|
||||
console.log("ERROR: Invalid server IP for workerscript.");
|
||||
console.log("ERROR: Invalid server IP for workerscript for updateActiveScriptsText()");
|
||||
return;
|
||||
}
|
||||
let hostname = server.hostname;
|
||||
@@ -298,24 +299,27 @@ function updateActiveScriptsText(workerscript, item, itemName) {
|
||||
|
||||
removeChildrenFromElement(item);
|
||||
|
||||
//Online
|
||||
var onlineTotalMoneyMade = "Total online production: $" + formatNumber(workerscript.scriptRef.onlineMoneyMade, 2);
|
||||
var onlineTotalExpEarned = (Array(26).join(" ") + formatNumber(workerscript.scriptRef.onlineExpGained, 2) + " hacking exp").replace( / /g, " ");
|
||||
var onlineTime = "Online Time: " + convertTimeMsToTimeElapsedString(workerscript.scriptRef.onlineRunningTime * 1e3);
|
||||
var offlineTime = "Offline Time: " + convertTimeMsToTimeElapsedString(workerscript.scriptRef.offlineRunningTime * 1e3);
|
||||
|
||||
var onlineMpsText = "Online production rate: $" + formatNumber(onlineMps, 2) + "/second";
|
||||
//Online
|
||||
var onlineTotalMoneyMade = "Total online production: " + numeralWrapper.formatMoney(workerscript.scriptRef.onlineMoneyMade);
|
||||
var onlineTotalExpEarned = (Array(26).join(" ") + numeralWrapper.formatBigNumber(workerscript.scriptRef.onlineExpGained) + " hacking exp").replace( / /g, " ");
|
||||
|
||||
var onlineMpsText = "Online production rate: " + numeralWrapper.formatMoney(onlineMps) + " / second";
|
||||
var onlineEps = workerscript.scriptRef.onlineExpGained / workerscript.scriptRef.onlineRunningTime;
|
||||
var onlineEpsText = (Array(25).join(" ") + formatNumber(onlineEps, 4) + " hacking exp/second").replace( / /g, " ");
|
||||
var onlineEpsText = (Array(25).join(" ") + numeralWrapper.formatBigNumber(onlineEps) + " hacking exp / second").replace( / /g, " ");
|
||||
|
||||
//Offline
|
||||
var offlineTotalMoneyMade = "Total offline production: $" + formatNumber(workerscript.scriptRef.offlineMoneyMade, 2);
|
||||
var offlineTotalExpEarned = (Array(27).join(" ") + formatNumber(workerscript.scriptRef.offlineExpGained, 2) + " hacking exp").replace( / /g, " ");
|
||||
var offlineTotalMoneyMade = "Total offline production: " + numeralWrapper.formatMoney(workerscript.scriptRef.offlineMoneyMade);
|
||||
var offlineTotalExpEarned = (Array(27).join(" ") + numeralWrapper.formatBigNumber(workerscript.scriptRef.offlineExpGained) + " hacking exp").replace( / /g, " ");
|
||||
|
||||
var offlineMps = workerscript.scriptRef.offlineMoneyMade / workerscript.scriptRef.offlineRunningTime;
|
||||
var offlineMpsText = "Offline production rate: $" + formatNumber(offlineMps, 2) + "/second";
|
||||
var offlineMpsText = "Offline production rate: " + numeralWrapper.formatMoney(offlineMps) + " / second";
|
||||
var offlineEps = workerscript.scriptRef.offlineExpGained / workerscript.scriptRef.offlineRunningTime;
|
||||
var offlineEpsText = (Array(26).join(" ") + formatNumber(offlineEps, 4) + " hacking exp/second").replace( / /g, " ");
|
||||
var offlineEpsText = (Array(26).join(" ") + numeralWrapper.formatBigNumber(offlineEps) + " hacking exp / second").replace( / /g, " ");
|
||||
|
||||
item.innerHTML = onlineTotalMoneyMade + "<br>" + onlineTotalExpEarned + "<br>" +
|
||||
item.innerHTML = onlineTime + "<br>" + offlineTime + "<br>" + onlineTotalMoneyMade + "<br>" + onlineTotalExpEarned + "<br>" +
|
||||
onlineMpsText + "<br>" + onlineEpsText + "<br>" + offlineTotalMoneyMade + "<br>" + offlineTotalExpEarned + "<br>" +
|
||||
offlineMpsText + "<br>" + offlineEpsText + "<br>";
|
||||
return onlineMps;
|
||||
|
||||
@@ -78,6 +78,9 @@ export class Augmentation {
|
||||
// The Player/Person classes
|
||||
mults: IMap<number> = {}
|
||||
|
||||
// Initial cost. Doesn't change when you purchase multiple Augmentation
|
||||
startingCost: number = 0;
|
||||
|
||||
constructor(params: IConstructorParams={ info: "", moneyCost: 0, name: "", repCost: 0 }) {
|
||||
this.name = params.name;
|
||||
this.info = params.info;
|
||||
@@ -85,6 +88,7 @@ export class Augmentation {
|
||||
|
||||
this.baseRepRequirement = params.repCost * CONSTANTS.AugmentationRepMultiplier * BitNodeMultipliers.AugmentationRepCost;
|
||||
this.baseCost = params.moneyCost * CONSTANTS.AugmentationCostMultiplier * BitNodeMultipliers.AugmentationMoneyCost;
|
||||
this.startingCost = this.baseCost;
|
||||
|
||||
this.level = 0;
|
||||
|
||||
|
||||
@@ -512,17 +512,22 @@ export let CONSTANTS: IMap<any> = {
|
||||
`
|
||||
v0.43.1
|
||||
* Terminal changes:
|
||||
** Quoted arguments are now properly parsed. (e.g. run f.script "this is one argument" will be correctly parsed)
|
||||
** Quoted arguments are now properly parsed. (e.g. 'run f.script "this is one argument"' will be correctly parsed)
|
||||
** Errors are now shown in red text
|
||||
** 'unalias' command now has a different format and no longer needs the quotations
|
||||
** Bug Fix: Fixed several edge cases where autocomplete wasnt working properly
|
||||
|
||||
* Added two new Bladeburner skills for increasing money and experience gain
|
||||
* Made some minor adjustments to Bladeburner UI
|
||||
* Corporation "Smart Factories" and "Smart Storage" upgrades have slightly lower price multipliers
|
||||
* Added nFormat Netscript function
|
||||
* Added 6 new Coding Contract problems
|
||||
* Updated documentation with list of all Coding Contract problems
|
||||
* Minor improvements for 'Active Scripts' UI
|
||||
* Implemented several optimizations for active scripts. The game should now use less memory and the savefile should be slightly smaller when there are many scripts running
|
||||
* Bug Fix: A Stock Forecast should no longer go above 1 (i.e. 100%)
|
||||
* Bug Fix: The cost of Resleeves should no longer be affected by buying Augs
|
||||
* Bug Fix: You can now call the prompt() Netscript function from multiple scripts simultaneously
|
||||
`
|
||||
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ import {StockMarket, StockSymbols, SymbolToStockMap,
|
||||
sellStock, updateStockPlayerPosition,
|
||||
shortStock, sellShort, OrderTypes,
|
||||
PositionTypes, placeOrder, cancelOrder} from "./StockMarket/StockMarket";
|
||||
import {numeralWrapper} from "./ui/numeralFormat";
|
||||
import {post} from "./ui/postToTerminal";
|
||||
import {TextFile, getTextFile, createTextFile} from "./TextFile";
|
||||
|
||||
@@ -76,6 +77,10 @@ import {yesNoBoxClose, yesNoBoxGetYesButton,
|
||||
yesNoBoxGetNoButton, yesNoBoxCreate,
|
||||
yesNoBoxOpen} from "../utils/YesNoBox";
|
||||
|
||||
import { createElement } from "../utils/uiHelpers/createElement";
|
||||
import { createPopup } from "../utils/uiHelpers/createPopup";
|
||||
import { removeElementById } from "../utils/uiHelpers/removeElementById";
|
||||
|
||||
var hasCorporationSF = false, //Source-File 3
|
||||
hasSingularitySF = false, //Source-File 4
|
||||
hasAISF = false, //Source-File 5
|
||||
@@ -2453,6 +2458,14 @@ function NetscriptFunctions(workerScript) {
|
||||
return runningScriptObj.onlineExpGained / runningScriptObj.onlineRunningTime;
|
||||
}
|
||||
},
|
||||
nFormat : function(n, format) {
|
||||
if (workerScript.checkingRam) { return 0; }
|
||||
if (isNaN(n) || isNaN(parseFloat(n)) || typeof format !== "string") {
|
||||
return "";
|
||||
}
|
||||
|
||||
return numeralWrapper.format(parseFloat(n), format);
|
||||
},
|
||||
getTimeSinceLastAug : function() {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("getTimeSinceLastAug", CONSTANTS.ScriptGetHackTimeRamCost);
|
||||
@@ -2467,19 +2480,32 @@ function NetscriptFunctions(workerScript) {
|
||||
return false;
|
||||
}
|
||||
if (!isString(txt)) {txt = String(txt);}
|
||||
var yesBtn = yesNoBoxGetYesButton(), noBtn = yesNoBoxGetNoButton();
|
||||
yesBtn.innerHTML = "Yes";
|
||||
noBtn.innerHTML = "No";
|
||||
|
||||
// The id for this popup will consist of the first 20 characters of the prompt string..
|
||||
// Thats hopefully good enough to be unique
|
||||
const popupId = `prompt-popup-${txt.slice(0, 20)}`;
|
||||
const textElement = createElement("p", { innerHTML: txt });
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
yesBtn.addEventListener("click", ()=>{
|
||||
yesNoBoxClose();
|
||||
resolve(true);
|
||||
const yesBtn = createElement("button", {
|
||||
class: "popup-box-button",
|
||||
innerText: "Yes",
|
||||
clickListener: () => {
|
||||
removeElementById(popupId);
|
||||
resolve(true);
|
||||
},
|
||||
});
|
||||
noBtn.addEventListener("click", ()=>{
|
||||
yesNoBoxClose();
|
||||
resolve(false);
|
||||
|
||||
const noBtn = createElement("button", {
|
||||
class: "popup-box-button",
|
||||
innerText: "No",
|
||||
clickListener: () => {
|
||||
removeElementById(popupId);
|
||||
resolve(false);
|
||||
},
|
||||
});
|
||||
yesNoBoxCreate(txt);
|
||||
|
||||
createPopup(popupId, [textElement, yesBtn, noBtn]);
|
||||
});
|
||||
},
|
||||
wget : async function(url, target, ip=workerScript.serverIp) {
|
||||
|
||||
@@ -219,6 +219,8 @@ function startNetscript1Script(workerScript) {
|
||||
let fnPromise = entry.apply(null, fnArgs);
|
||||
fnPromise.then(function(res) {
|
||||
cb(res);
|
||||
}).catch(function(e) {
|
||||
// Do nothing?
|
||||
});
|
||||
}
|
||||
int.setProperty(scope, name, int.createAsyncFunction(tempWrapper));
|
||||
@@ -278,7 +280,7 @@ function startNetscript1Script(workerScript) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
function runInterpreter() {
|
||||
try {
|
||||
if (workerScript.env.stopFlag) {return reject(workerScript);}
|
||||
if (workerScript.env.stopFlag) { return reject(workerScript); }
|
||||
|
||||
if (interpreter.step()) {
|
||||
window.setTimeout(runInterpreter, Settings.CodeInstructionRunTime);
|
||||
@@ -498,7 +500,7 @@ function runScriptsLoop() {
|
||||
p = startNetscript2Script(workerScripts[i]);
|
||||
} else {
|
||||
p = startNetscript1Script(workerScripts[i]);
|
||||
if (!(p instanceof Promise)) {continue;}
|
||||
if (!(p instanceof Promise)) { continue; }
|
||||
}
|
||||
|
||||
//Once the code finishes (either resolved or rejected, doesnt matter), set its
|
||||
@@ -539,7 +541,6 @@ function runScriptsLoop() {
|
||||
}
|
||||
w.running = false;
|
||||
w.env.stopFlag = true;
|
||||
|
||||
} else if (isScriptErrorMessage(w)) {
|
||||
dialogBoxCreate("Script runtime unknown error. This is a bug please contact game developer");
|
||||
console.log("ERROR: Evaluating workerscript returns only error message rather than WorkerScript object. THIS SHOULDN'T HAPPEN: " + w.toString());
|
||||
|
||||
@@ -44,7 +44,7 @@ export class Resleeve extends Person {
|
||||
console.error(`Could not find Augmentation ${this.augmentations[i].name}`);
|
||||
continue;
|
||||
}
|
||||
totalAugmentationCost += aug!.baseCost;
|
||||
totalAugmentationCost += aug!.startingCost;
|
||||
}
|
||||
|
||||
return (totalExp * CostPerExp) + (totalAugmentationCost * Math.pow(NumAugsExponent, this.augmentations.length));
|
||||
|
||||
@@ -34,6 +34,9 @@ import {initStockMarket, initSymbolToStockMap,
|
||||
stockMarketContentCreated,
|
||||
setStockMarketContentCreated} from "./StockMarket/StockMarket";
|
||||
import {Terminal, postNetburnerText} from "./Terminal";
|
||||
|
||||
import {Page, routing} from "./ui/navigationTracking";
|
||||
|
||||
import Decimal from "decimal.js";
|
||||
import {dialogBoxCreate} from "../utils/DialogBox";
|
||||
import {removeElementById} from "../utils/uiHelpers/removeElementById";
|
||||
@@ -45,6 +48,13 @@ let BitNode8StartingMoney = 250e6;
|
||||
|
||||
//Prestige by purchasing augmentation
|
||||
function prestigeAugmentation() {
|
||||
// Load Terminal Screen
|
||||
var mainMenu = document.getElementById("mainmenu-container");
|
||||
mainMenu.style.visibility = "visible";
|
||||
Terminal.resetTerminalInput();
|
||||
Engine.loadTerminalContent();
|
||||
routing.navigateTo(Page.Terminal);
|
||||
|
||||
initBitNodeMultipliers();
|
||||
|
||||
Player.prestigeAugmentation();
|
||||
@@ -146,12 +156,6 @@ function prestigeAugmentation() {
|
||||
var watchlist = document.getElementById("stock-market-watchlist-filter");
|
||||
watchlist.value = ""; //Reset watchlist filter
|
||||
|
||||
//Load Terminal Screen
|
||||
var mainMenu = document.getElementById("mainmenu-container");
|
||||
mainMenu.style.visibility = "visible";
|
||||
Terminal.resetTerminalInput();
|
||||
Engine.loadTerminalContent();
|
||||
|
||||
// Refresh Main Menu (the 'World' menu, specifically)
|
||||
document.getElementById("world-menu-header").click();
|
||||
document.getElementById("world-menu-header").click();
|
||||
|
||||
@@ -165,7 +165,7 @@ $(document).keydown(function(event) {
|
||||
|
||||
const semiColonIndex = input.lastIndexOf(";");
|
||||
if(semiColonIndex !== -1) {
|
||||
input = input.slice(semiColonIndex+1);
|
||||
input = input.slice(semiColonIndex + 1);
|
||||
}
|
||||
|
||||
input = input.trim();
|
||||
@@ -310,6 +310,14 @@ function tabCompletion(command, arg, allPossibilities, index=0) {
|
||||
}
|
||||
}
|
||||
|
||||
const textBox = document.getElementById("terminal-input-text-box");
|
||||
if (textBox == null) {
|
||||
console.warn(`Couldn't find terminal input DOM element (id=terminal-input-text-box) when trying to autocomplete`);
|
||||
return;
|
||||
}
|
||||
const oldValue = textBox.value;
|
||||
const semiColonIndex = oldValue.lastIndexOf(";");
|
||||
|
||||
var val = "";
|
||||
if (allPossibilities.length == 0) {
|
||||
return;
|
||||
@@ -321,10 +329,7 @@ function tabCompletion(command, arg, allPossibilities, index=0) {
|
||||
val = command + " " + allPossibilities[0];
|
||||
}
|
||||
|
||||
const textBox = document.getElementById("terminal-input-text-box");
|
||||
const oldValue = textBox.value;
|
||||
const semiColonIndex = oldValue.lastIndexOf(";");
|
||||
if(semiColonIndex === -1) {
|
||||
if (semiColonIndex === -1) {
|
||||
// no ; replace the whole thing.
|
||||
textBox.value = val;
|
||||
} else {
|
||||
@@ -332,7 +337,7 @@ function tabCompletion(command, arg, allPossibilities, index=0) {
|
||||
textBox.value = textBox.value.slice(0, semiColonIndex+1)+" "+val;
|
||||
}
|
||||
|
||||
document.getElementById("terminal-input-text-box").focus();
|
||||
textBox.focus();
|
||||
} else {
|
||||
var longestStartSubstr = longestCommonStart(allPossibilities);
|
||||
//If the longest common starting substring of remaining possibilities is the same
|
||||
@@ -348,8 +353,15 @@ function tabCompletion(command, arg, allPossibilities, index=0) {
|
||||
post("> " + command);
|
||||
post(allOptionsStr);
|
||||
} else {
|
||||
document.getElementById("terminal-input-text-box").value = longestStartSubstr;
|
||||
document.getElementById("terminal-input-text-box").focus();
|
||||
if (semiColonIndex === -1) {
|
||||
// No ; just replace the whole thing
|
||||
textBox.value = longestStartSubstr;
|
||||
} else {
|
||||
// Multiple commands, so only replace after the last semicolon
|
||||
textBox.value = textBox.value.slice(0, semiColonIndex + 1) + " " + longestStartSubstr;
|
||||
}
|
||||
|
||||
textBox.focus();
|
||||
}
|
||||
} else {
|
||||
if (longestStartSubstr == arg) {
|
||||
@@ -357,8 +369,15 @@ function tabCompletion(command, arg, allPossibilities, index=0) {
|
||||
post("> " + command + " " + arg);
|
||||
post(allOptionsStr);
|
||||
} else {
|
||||
document.getElementById("terminal-input-text-box").value = command + " " + longestStartSubstr;
|
||||
document.getElementById("terminal-input-text-box").focus();
|
||||
if (semiColonIndex == -1) {
|
||||
// No ; so just replace the whole thing
|
||||
textBox.value = command + " " + longestStartSubstr;
|
||||
} else {
|
||||
// Multiple commands, so only replace after the last semiclon
|
||||
textBox.value = textBox.value.slice(0, semiColonIndex + 1) + " " + command + " " + longestStartSubstr;
|
||||
}
|
||||
|
||||
textBox.focus();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1032,7 +1032,6 @@ const Engine = {
|
||||
//is necessary and then resets the counter
|
||||
checkCounters: function() {
|
||||
if (Engine.Counters.autoSaveCounter <= 0) {
|
||||
saveObject.saveGame(indexedDb);
|
||||
if (Settings.AutosaveInterval == null) {
|
||||
Settings.AutosaveInterval = 60;
|
||||
}
|
||||
@@ -1040,6 +1039,7 @@ const Engine = {
|
||||
Engine.Counters.autoSaveCounter = Infinity;
|
||||
} else {
|
||||
Engine.Counters.autoSaveCounter = Settings.AutosaveInterval * 5;
|
||||
saveObject.saveGame(indexedDb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user