0;x--)h="0"+h;return k>-1&&(h=h.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1"+m.delimiters.thousands)),0===c.indexOf(".")&&(h=""),l=h+v+(q?q:""),n?l=(n&&w?"(":"")+l+(n&&w?")":""):j>=0?l=0===j?(w?"-":"+")+l:l+(w?"-":"+"):w&&(l="-"+l),l},stringToNumber:function(a){var b,c,d,e=f[h.currentLocale],g=a,i={thousand:3,million:6,billion:9,trillion:12};if(h.zeroFormat&&a===h.zeroFormat)c=0;else if(h.nullFormat&&a===h.nullFormat||!a.replace(/[^0-9]+/g,"").length)c=null;else{c=1,"."!==e.delimiters.decimal&&(a=a.replace(/\./g,"").replace(e.delimiters.decimal,"."));for(b in i)if(d=new RegExp("[^a-zA-Z]"+e.abbreviations[b]+"(?:\\)|(\\"+e.currency.symbol+")?(?:\\))?)?$"),g.match(d)){c*=Math.pow(10,i[b]);break}c*=(a.split("-").length+Math.min(a.split("(").length-1,a.split(")").length-1))%2?1:-1,a=a.replace(/[^0-9\.]+/g,""),c*=Number(a)}return c},isNaN:function(a){return"number"==typeof a&&isNaN(a)},includes:function(a,b){return-1!==a.indexOf(b)},insert:function(a,b,c){return a.slice(0,c)+b+a.slice(c)},reduce:function(a,b){if(null===this)throw new TypeError("Array.prototype.reduce called on null or undefined");if("function"!=typeof b)throw new TypeError(b+" is not a function");var c,d=Object(a),e=d.length>>>0,f=0;if(3===arguments.length)c=arguments[2];else{for(;e>f&&!(f in d);)f++;if(f>=e)throw new TypeError("Reduce of empty array with no initial value");c=d[f++]}for(;e>f;f++)f in d&&(c=b(c,d[f],f,d));return c},multiplier:function(a){var b=a.toString().split(".");return b.length<2?1:Math.pow(10,b[1].length)},correctionFactor:function(){var a=Array.prototype.slice.call(arguments);return a.reduce(function(a,b){var d=c.multiplier(b);return a>d?a:d},1)},toFixed:function(a,b,c,d){var e,f,g,h,i=a.toString().split("."),j=b-(d||0);return e=2===i.length?Math.min(Math.max(i[1].length,j),b):j,g=Math.pow(10,e),h=(c(a+"e+"+e)/g).toFixed(e),d>b-e&&(f=new RegExp("\\.?0{1,"+(d-(b-e))+"}$"),h=h.replace(f,"")),h}},b.options=h,b.formats=e,b.locales=f,b.locale=function(a){return a&&(h.currentLocale=a.toLowerCase()),h.currentLocale},b.localeData=function(a){if(!a)return f[h.currentLocale];if(a=a.toLowerCase(),!f[a])throw new Error("Unknown locale : "+a);return f[a]},b.reset=function(){for(var a in g)h[a]=g[a]},b.zeroFormat=function(a){h.zeroFormat="string"==typeof a?a:null},b.nullFormat=function(a){h.nullFormat="string"==typeof a?a:null},b.defaultFormat=function(a){h.defaultFormat="string"==typeof a?a:"0.0"},b.register=function(a,b,c){if(b=b.toLowerCase(),this[a+"s"][b])throw new TypeError(b+" "+a+" already registered.");return this[a+"s"][b]=c,c},b.validate=function(a,c){var d,e,f,g,h,i,j,k;if("string"!=typeof a&&(a+="",console.warn&&console.warn("Numeral.js: Value is not string. It has been co-erced to: ",a)),a=a.trim(),a.match(/^\d+$/))return!0;if(""===a)return!1;try{j=b.localeData(c)}catch(l){j=b.localeData(b.locale())}return f=j.currency.symbol,h=j.abbreviations,d=j.delimiters.decimal,e="."===j.delimiters.thousands?"\\.":j.delimiters.thousands,k=a.match(/^[^\d]+/),null!==k&&(a=a.substr(1),k[0]!==f)?!1:(k=a.match(/[^\d]+$/),null!==k&&(a=a.slice(0,-1),k[0]!==h.thousand&&k[0]!==h.million&&k[0]!==h.billion&&k[0]!==h.trillion)?!1:(i=new RegExp(e+"{2}"),a.match(/[^\d.,]/g)?!1:(g=a.split(d),g.length>2?!1:g.length<2?!!g[0].match(/^\d+.*\d$/)&&!g[0].match(i):1===g[0].length?!!g[0].match(/^\d+$/)&&!g[0].match(i)&&!!g[1].match(/^\d+$/):!!g[0].match(/^\d+.*\d$/)&&!g[0].match(i)&&!!g[1].match(/^\d+$/))))},b.fn=a.prototype={clone:function(){return b(this)},format:function(a,c){var d,f,g,i=this._value,j=a||h.defaultFormat;if(c=c||Math.round,0===i&&null!==h.zeroFormat)f=h.zeroFormat;else if(null===i&&null!==h.nullFormat)f=h.nullFormat;else{for(d in e)if(j.match(e[d].regexps.format)){g=e[d].format;break}g=g||b._.numberToFormat,f=g(i,j,c)}return f},value:function(){return this._value},input:function(){return this._input},set:function(a){return this._value=Number(a),this},add:function(a){function b(a,b,c,e){return a+Math.round(d*b)}var d=c.correctionFactor.call(null,this._value,a);return this._value=c.reduce([this._value,a],b,0)/d,this},subtract:function(a){function b(a,b,c,e){return a-Math.round(d*b)}var d=c.correctionFactor.call(null,this._value,a);return this._value=c.reduce([a],b,Math.round(this._value*d))/d,this},multiply:function(a){function b(a,b,d,e){var f=c.correctionFactor(a,b);return Math.round(a*f)*Math.round(b*f)/Math.round(f*f)}return this._value=c.reduce([this._value,a],b,1),this},divide:function(a){function b(a,b,d,e){var f=c.correctionFactor(a,b);return Math.round(a*f)/Math.round(b*f)}return this._value=c.reduce([this._value,a],b),this},difference:function(a){return Math.abs(b(this._value).subtract(a).value())}},b.register("locale","en",{delimiters:{thousands:",",decimal:"."},abbreviations:{thousand:"k",million:"m",billion:"b",trillion:"t"},ordinal:function(a){var b=a%10;return 1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th"},currency:{symbol:"$"}}),function(){b.register("format","bps",{regexps:{format:/(BPS)/,unformat:/(BPS)/},format:function(a,c,d){var e,f=b._.includes(c," BPS")?" ":"";return a=1e4*a,c=c.replace(/\s?BPS/,""),e=b._.numberToFormat(a,c,d),b._.includes(e,")")?(e=e.split(""),e.splice(-1,0,f+"BPS"),e=e.join("")):e=e+f+"BPS",e},unformat:function(a){return+(1e-4*b._.stringToNumber(a)).toFixed(15)}})}(),function(){var a={base:1e3,suffixes:["B","KB","MB","GB","TB","PB","EB","ZB","YB"]},c={base:1024,suffixes:["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"]},d=a.suffixes.concat(c.suffixes.filter(function(b){return a.suffixes.indexOf(b)<0})),e=d.join("|");e="("+e.replace("B","B(?!PS)")+")",b.register("format","bytes",{regexps:{format:/([0\s]i?b)/,unformat:new RegExp(e)},format:function(d,e,f){var g,h,i,j,k=b._.includes(e,"ib")?c:a,l=b._.includes(e," b")||b._.includes(e," ib")?" ":"";for(e=e.replace(/\s?i?b/,""),h=0;h<=k.suffixes.length;h++)if(i=Math.pow(k.base,h),j=Math.pow(k.base,h+1),null===d||0===d||d>=i&&j>d){l+=k.suffixes[h],i>0&&(d/=i);break}return g=b._.numberToFormat(d,e,f),g+l},unformat:function(d){var e,f,g=b._.stringToNumber(d);if(g){for(e=a.suffixes.length-1;e>=0;e--){if(b._.includes(d,a.suffixes[e])){f=Math.pow(a.base,e);break}if(b._.includes(d,c.suffixes[e])){f=Math.pow(c.base,e);break}}g*=f||1}return g}})}(),function(){b.register("format","currency",{regexps:{format:/(\$)/},format:function(a,c,d){var e,f,g,h=b.locales[b.options.currentLocale],i={before:c.match(/^([\+|\-|\(|\s|\$]*)/)[0],after:c.match(/([\+|\-|\)|\s|\$]*)$/)[0]};for(c=c.replace(/\s?\$\s?/,""),e=b._.numberToFormat(a,c,d),a>=0?(i.before=i.before.replace(/[\-\(]/,""),i.after=i.after.replace(/[\-\)]/,"")):0>a&&!b._.includes(i.before,"-")&&!b._.includes(i.before,"(")&&(i.before="-"+i.before),g=0;g 0;x--)h="0"+h;return k>-1&&(h=h.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1"+m.delimiters.thousands)),0===c.indexOf(".")&&(h=""),l=h+v+(q?q:""),n?l=(n&&w?"(":"")+l+(n&&w?")":""):j>=0?l=0===j?(w?"-":"+")+l:l+(w?"-":"+"):w&&(l="-"+l),l},stringToNumber:function(a){var b,c,d,e=f[h.currentLocale],g=a,i={thousand:3,million:6,billion:9,trillion:12};if(h.zeroFormat&&a===h.zeroFormat)c=0;else if(h.nullFormat&&a===h.nullFormat||!a.replace(/[^0-9]+/g,"").length)c=null;else{c=1,"."!==e.delimiters.decimal&&(a=a.replace(/\./g,"").replace(e.delimiters.decimal,"."));for(b in i)if(d=new RegExp("[^a-zA-Z]"+e.abbreviations[b]+"(?:\\)|(\\"+e.currency.symbol+")?(?:\\))?)?$"),g.match(d)){c*=Math.pow(10,i[b]);break}c*=(a.split("-").length+Math.min(a.split("(").length-1,a.split(")").length-1))%2?1:-1,a=a.replace(/[^0-9\.]+/g,""),c*=Number(a)}return c},isNaN:function(a){return"number"==typeof a&&isNaN(a)},includes:function(a,b){return-1!==a.indexOf(b)},insert:function(a,b,c){return a.slice(0,c)+b+a.slice(c)},reduce:function(a,b){if(null===this)throw new TypeError("Array.prototype.reduce called on null or undefined");if("function"!=typeof b)throw new TypeError(b+" is not a function");var c,d=Object(a),e=d.length>>>0,f=0;if(3===arguments.length)c=arguments[2];else{for(;e>f&&!(f in d);)f++;if(f>=e)throw new TypeError("Reduce of empty array with no initial value");c=d[f++]}for(;e>f;f++)f in d&&(c=b(c,d[f],f,d));return c},multiplier:function(a){var b=a.toString().split(".");return b.length<2?1:Math.pow(10,b[1].length)},correctionFactor:function(){var a=Array.prototype.slice.call(arguments);return a.reduce(function(a,b){var d=c.multiplier(b);return a>d?a:d},1)},toFixed:function(a,b,c,d){var e,f,g,h,i=a.toString().split("."),j=b-(d||0);return e=2===i.length?Math.min(Math.max(i[1].length,j),b):j,g=Math.pow(10,e),h=(c(a+"e+"+e)/g).toFixed(e),d>b-e&&(f=new RegExp("\\.?0{1,"+(d-(b-e))+"}$"),h=h.replace(f,"")),h}},b.options=h,b.formats=e,b.locales=f,b.locale=function(a){return a&&(h.currentLocale=a.toLowerCase()),h.currentLocale},b.localeData=function(a){if(!a)return f[h.currentLocale];if(a=a.toLowerCase(),!f[a])throw new Error("Unknown locale : "+a);return f[a]},b.reset=function(){for(var a in g)h[a]=g[a]},b.zeroFormat=function(a){h.zeroFormat="string"==typeof a?a:null},b.nullFormat=function(a){h.nullFormat="string"==typeof a?a:null},b.defaultFormat=function(a){h.defaultFormat="string"==typeof a?a:"0.0"},b.register=function(a,b,c){if(b=b.toLowerCase(),this[a+"s"][b])throw new TypeError(b+" "+a+" already registered.");return this[a+"s"][b]=c,c},b.validate=function(a,c){var d,e,f,g,h,i,j,k;if("string"!=typeof a&&(a+="",console.warn&&console.warn("Numeral.js: Value is not string. It has been co-erced to: ",a)),a=a.trim(),a.match(/^\d+$/))return!0;if(""===a)return!1;try{j=b.localeData(c)}catch(l){j=b.localeData(b.locale())}return f=j.currency.symbol,h=j.abbreviations,d=j.delimiters.decimal,e="."===j.delimiters.thousands?"\\.":j.delimiters.thousands,k=a.match(/^[^\d]+/),null!==k&&(a=a.substr(1),k[0]!==f)?!1:(k=a.match(/[^\d]+$/),null!==k&&(a=a.slice(0,-1),k[0]!==h.thousand&&k[0]!==h.million&&k[0]!==h.billion&&k[0]!==h.trillion)?!1:(i=new RegExp(e+"{2}"),a.match(/[^\d.,]/g)?!1:(g=a.split(d),g.length>2?!1:g.length<2?!!g[0].match(/^\d+.*\d$/)&&!g[0].match(i):1===g[0].length?!!g[0].match(/^\d+$/)&&!g[0].match(i)&&!!g[1].match(/^\d+$/):!!g[0].match(/^\d+.*\d$/)&&!g[0].match(i)&&!!g[1].match(/^\d+$/))))},b.fn=a.prototype={clone:function(){return b(this)},format:function(a,c){var d,f,g,i=this._value,j=a||h.defaultFormat;if(c=c||Math.round,0===i&&null!==h.zeroFormat)f=h.zeroFormat;else if(null===i&&null!==h.nullFormat)f=h.nullFormat;else{for(d in e)if(j.match(e[d].regexps.format)){g=e[d].format;break}g=g||b._.numberToFormat,f=g(i,j,c)}return f},value:function(){return this._value},input:function(){return this._input},set:function(a){return this._value=Number(a),this},add:function(a){function b(a,b,c,e){return a+Math.round(d*b)}var d=c.correctionFactor.call(null,this._value,a);return this._value=c.reduce([this._value,a],b,0)/d,this},subtract:function(a){function b(a,b,c,e){return a-Math.round(d*b)}var d=c.correctionFactor.call(null,this._value,a);return this._value=c.reduce([a],b,Math.round(this._value*d))/d,this},multiply:function(a){function b(a,b,d,e){var f=c.correctionFactor(a,b);return Math.round(a*f)*Math.round(b*f)/Math.round(f*f)}return this._value=c.reduce([this._value,a],b,1),this},divide:function(a){function b(a,b,d,e){var f=c.correctionFactor(a,b);return Math.round(a*f)/Math.round(b*f)}return this._value=c.reduce([this._value,a],b),this},difference:function(a){return Math.abs(b(this._value).subtract(a).value())}},b.register("locale","en",{delimiters:{thousands:",",decimal:"."},abbreviations:{thousand:"k",million:"m",billion:"b",trillion:"t"},ordinal:function(a){var b=a%10;return 1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th"},currency:{symbol:"$"}}),function(){b.register("format","bps",{regexps:{format:/(BPS)/,unformat:/(BPS)/},format:function(a,c,d){var e,f=b._.includes(c," BPS")?" ":"";return a=1e4*a,c=c.replace(/\s?BPS/,""),e=b._.numberToFormat(a,c,d),b._.includes(e,")")?(e=e.split(""),e.splice(-1,0,f+"BPS"),e=e.join("")):e=e+f+"BPS",e},unformat:function(a){return+(1e-4*b._.stringToNumber(a)).toFixed(15)}})}(),function(){var a={base:1e3,suffixes:["B","KB","MB","GB","TB","PB","EB","ZB","YB"]},c={base:1024,suffixes:["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"]},d=a.suffixes.concat(c.suffixes.filter(function(b){return a.suffixes.indexOf(b)<0})),e=d.join("|");e="("+e.replace("B","B(?!PS)")+")",b.register("format","bytes",{regexps:{format:/([0\s]i?b)/,unformat:new RegExp(e)},format:function(d,e,f){var g,h,i,j,k=b._.includes(e,"ib")?c:a,l=b._.includes(e," b")||b._.includes(e," ib")?" ":"";for(e=e.replace(/\s?i?b/,""),h=0;h<=k.suffixes.length;h++)if(i=Math.pow(k.base,h),j=Math.pow(k.base,h+1),null===d||0===d||d>=i&&j>d){l+=k.suffixes[h],i>0&&(d/=i);break}return g=b._.numberToFormat(d,e,f),g+l},unformat:function(d){var e,f,g=b._.stringToNumber(d);if(g){for(e=a.suffixes.length-1;e>=0;e--){if(b._.includes(d,a.suffixes[e])){f=Math.pow(a.base,e);break}if(b._.includes(d,c.suffixes[e])){f=Math.pow(c.base,e);break}}g*=f||1}return g}})}(),function(){b.register("format","currency",{regexps:{format:/(\$)/},format:function(a,c,d){var e,f,g,h=b.locales[b.options.currentLocale],i={before:c.match(/^([\+|\-|\(|\s|\$]*)/)[0],after:c.match(/([\+|\-|\)|\s|\$]*)$/)[0]};for(c=c.replace(/\s?\$\s?/,""),e=b._.numberToFormat(a,c,d),a>=0?(i.before=i.before.replace(/[\-\(]/,""),i.after=i.after.replace(/[\-\)]/,"")):0>a&&!b._.includes(i.before,"-")&&!b._.includes(i.before,"(")&&(i.before="-"+i.before),g=0;g
Attempt a hacking mission for your faction.
- A mission is a mini game that, if won, earns you significant reputation with this faction.
+ A mission is a mini game that, if won, earns you significant reputation with this faction. (Recommended hacking level: 200+)
" +
+ "Total online production since last Aug installation: " +
+ __WEBPACK_IMPORTED_MODULE_6__utils_numeral_min_js___default()(__WEBPACK_IMPORTED_MODULE_1__Player_js__["a" /* Player */].scriptProdSinceLastAug).format('$0.000a') + " (" +
+ __WEBPACK_IMPORTED_MODULE_6__utils_numeral_min_js___default()(__WEBPACK_IMPORTED_MODULE_1__Player_js__["a" /* Player */].scriptProdSinceLastAug / (__WEBPACK_IMPORTED_MODULE_1__Player_js__["a" /* Player */].playtimeSinceLastAug/1000)).format('$0.000a') + " / sec)";
+ return total;
+}
+
+//Updates the content of the given item in the Active Scripts list
+function updateActiveScriptsItemContent(workerscript) {
+ var server = Object(__WEBPACK_IMPORTED_MODULE_2__Server_js__["e" /* getServer */])(workerscript.serverIp);
+ if (server == null) {
+ console.log("ERROR: Invalid server IP for workerscript.");
+ return;
+ }
+ var itemNameArray = ["active", "scripts", server.hostname, workerscript.name];
+ for (var i = 0; i < workerscript.args.length; ++i) {
+ itemNameArray.push(workerscript.args[i].toString());
+ }
+ var itemName = itemNameArray.join("-");
+ var itemContent = document.getElementById(itemName + "-content")
+
+ //Add the updated text back. Returns the total online production rate
+ return updateActiveScriptsText(workerscript, itemContent);
+}
+
+function createActiveScriptsText(workerscript, item) {
+ var itemTextHeader = document.createElement("p");
+ var itemTextStats = document.createElement("p");
+ var itemId = item.id;
+ itemTextStats.setAttribute("id", itemId + "-stats");
+
+ //Server ip/hostname
+ var threads = "Threads: " + workerscript.scriptRef.threads;
+ var args = "Args: " + Object(__WEBPACK_IMPORTED_MODULE_4__utils_HelperFunctions_js__["f" /* printArray */])(workerscript.args);
+
+ itemTextHeader.innerHTML = threads + "
" + args + "
";
+
+ item.appendChild(itemTextHeader);
+ item.appendChild(itemTextStats);
+
+ var onlineMps = updateActiveScriptsText(workerscript, item, itemTextStats);
+
+ var logButton = document.createElement("span");
+ logButton.innerHTML = "Log";
+ var killButton = document.createElement("span");
+ killButton.innerHTML = "Kill script";
+ logButton.setAttribute("class", "active-scripts-button");
+ killButton.setAttribute("class", "active-scripts-button");
+ logButton.addEventListener("click", function() {
+ Object(__WEBPACK_IMPORTED_MODULE_5__utils_LogBox_js__["a" /* logBoxCreate */])(workerscript.scriptRef);
+ return false;
+ });
+ killButton.addEventListener("click", function() {
+ Object(__WEBPACK_IMPORTED_MODULE_0__NetscriptWorker_js__["d" /* killWorkerScript */])(workerscript.scriptRef, workerscript.scriptRef.scriptRef.server);
+ Object(__WEBPACK_IMPORTED_MODULE_3__utils_DialogBox_js__["a" /* dialogBoxCreate */])("Killing script, may take a few minutes to complete...");
+ return false;
+ });
+ item.appendChild(logButton);
+ item.appendChild(killButton);
+
+ //Return total online production rate
+ return onlineMps;
+}
+
+function updateActiveScriptsText(workerscript, item, statsEl=null) {
+ var itemId = item.id
+ var itemTextStats = document.getElementById(itemId + "-stats");
+ if (itemTextStats === null || itemTextStats === undefined) {
+ itemTextStats = statsEl;
+ }
+
+ //Updates statistics only
+ //Online
+ var onlineTotalMoneyMade = "Total online production: $" + Object(__WEBPACK_IMPORTED_MODULE_7__utils_StringHelperFunctions_js__["c" /* formatNumber */])(workerscript.scriptRef.onlineMoneyMade, 2);
+ var onlineTotalExpEarned = (Array(26).join(" ") + Object(__WEBPACK_IMPORTED_MODULE_7__utils_StringHelperFunctions_js__["c" /* formatNumber */])(workerscript.scriptRef.onlineExpGained, 2) + " hacking exp").replace( / /g, " ");
+
+ var onlineMps = workerscript.scriptRef.onlineMoneyMade / workerscript.scriptRef.onlineRunningTime;
+ var onlineMpsText = "Online production rate: $" + Object(__WEBPACK_IMPORTED_MODULE_7__utils_StringHelperFunctions_js__["c" /* formatNumber */])(onlineMps, 2) + "/second";
+ var onlineEps = workerscript.scriptRef.onlineExpGained / workerscript.scriptRef.onlineRunningTime;
+ var onlineEpsText = (Array(25).join(" ") + Object(__WEBPACK_IMPORTED_MODULE_7__utils_StringHelperFunctions_js__["c" /* formatNumber */])(onlineEps, 4) + " hacking exp/second").replace( / /g, " ");
+
+ //Offline
+ var offlineTotalMoneyMade = "Total offline production: $" + Object(__WEBPACK_IMPORTED_MODULE_7__utils_StringHelperFunctions_js__["c" /* formatNumber */])(workerscript.scriptRef.offlineMoneyMade, 2);
+ var offlineTotalExpEarned = (Array(27).join(" ") + Object(__WEBPACK_IMPORTED_MODULE_7__utils_StringHelperFunctions_js__["c" /* formatNumber */])(workerscript.scriptRef.offlineExpGained, 2) + " hacking exp").replace( / /g, " ");
+
+ var offlineMps = workerscript.scriptRef.offlineMoneyMade / workerscript.scriptRef.offlineRunningTime;
+ var offlineMpsText = "Offline production rate: $" + Object(__WEBPACK_IMPORTED_MODULE_7__utils_StringHelperFunctions_js__["c" /* formatNumber */])(offlineMps, 2) + "/second";
+ var offlineEps = workerscript.scriptRef.offlineExpGained / workerscript.scriptRef.offlineRunningTime;
+ var offlineEpsText = (Array(26).join(" ") + Object(__WEBPACK_IMPORTED_MODULE_7__utils_StringHelperFunctions_js__["c" /* formatNumber */])(offlineEps, 4) + " hacking exp/second").replace( / /g, " ");
+
+ itemTextStats.innerHTML = onlineTotalMoneyMade + "
" + onlineTotalExpEarned + "
" +
+ onlineMpsText + "
" + onlineEpsText + "
" + offlineTotalMoneyMade + "
" + offlineTotalExpEarned + "
" +
+ offlineMpsText + "
" + offlineEpsText + "
";
+ return onlineMps;
+}
+
+
+
+
+/***/ }),
+/* 26 */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "e", function() { return iTutorialSteps; });
/* unused harmony export iTutorialEnd */
@@ -29396,7 +29558,7 @@ function iTutorialSetText(txt) {
/***/ }),
-/* 26 */
+/* 27 */
/***/ (function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/*! decimal.js v7.2.3 https://github.com/MikeMcl/decimal.js/LICENCE */
@@ -34216,7 +34378,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;/*! decimal.js v7.2.3 https://github.com/MikeM
/***/ }),
-/* 27 */
+/* 28 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -34855,23 +35017,6 @@ function updateStockPlayerPosition(stock) {
-/***/ }),
-/* 28 */
-/***/ (function(module, exports, __webpack_require__) {
-
-var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! @preserve
- * numeral.js
- * version : 2.0.6
- * author : Adam Draper
- * license : MIT
- * http://adamwdraper.github.com/Numeral-js/
- */
-!function(a,b){ true?!(__WEBPACK_AMD_DEFINE_FACTORY__ = (b),
- __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
- (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) :
- __WEBPACK_AMD_DEFINE_FACTORY__),
- __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)):"object"==typeof module&&module.exports?module.exports=b():a.numeral=b()}(this,function(){function a(a,b){this._input=a,this._value=b}var b,c,d="2.0.6",e={},f={},g={currentLocale:"en",zeroFormat:null,nullFormat:null,defaultFormat:"0,0",scalePercentBy100:!0},h={currentLocale:g.currentLocale,zeroFormat:g.zeroFormat,nullFormat:g.nullFormat,defaultFormat:g.defaultFormat,scalePercentBy100:g.scalePercentBy100};return b=function(d){var f,g,i,j;if(b.isNumeral(d))f=d.value();else if(0===d||"undefined"==typeof d)f=0;else if(null===d||c.isNaN(d))f=null;else if("string"==typeof d)if(h.zeroFormat&&d===h.zeroFormat)f=0;else if(h.nullFormat&&d===h.nullFormat||!d.replace(/[^0-9]+/g,"").length)f=null;else{for(g in e)if(j="function"==typeof e[g].regexps.unformat?e[g].regexps.unformat():e[g].regexps.unformat,j&&d.match(j)){i=e[g].unformat;break}i=i||b._.stringToNumber,f=i(d)}else f=Number(d)||null;return new a(d,f)},b.version=d,b.isNumeral=function(b){return b instanceof a},b._=c={numberToFormat:function(a,c,d){var e,g,h,i,j,k,l,m=f[b.options.currentLocale],n=!1,o=!1,p=0,q="",r=1e12,s=1e9,t=1e6,u=1e3,v="",w=!1;if(a=a||0,g=Math.abs(a),b._.includes(c,"(")?(n=!0,c=c.replace(/[\(|\)]/g,"")):(b._.includes(c,"+")||b._.includes(c,"-"))&&(j=b._.includes(c,"+")?c.indexOf("+"):0>a?c.indexOf("-"):-1,c=c.replace(/[\+|\-]/g,"")),b._.includes(c,"a")&&(e=c.match(/a(k|m|b|t)?/),e=e?e[1]:!1,b._.includes(c," a")&&(q=" "),c=c.replace(new RegExp(q+"a[kmbt]?"),""),g>=r&&!e||"t"===e?(q+=m.abbreviations.trillion,a/=r):r>g&&g>=s&&!e||"b"===e?(q+=m.abbreviations.billion,a/=s):s>g&&g>=t&&!e||"m"===e?(q+=m.abbreviations.million,a/=t):(t>g&&g>=u&&!e||"k"===e)&&(q+=m.abbreviations.thousand,a/=u)),b._.includes(c,"[.]")&&(o=!0,c=c.replace("[.]",".")),h=a.toString().split(".")[0],i=c.split(".")[1],k=c.indexOf(","),p=(c.split(".")[0].split(",")[0].match(/0/g)||[]).length,i?(b._.includes(i,"[")?(i=i.replace("]",""),i=i.split("["),v=b._.toFixed(a,i[0].length+i[1].length,d,i[1].length)):v=b._.toFixed(a,i.length,d),h=v.split(".")[0],v=b._.includes(v,".")?m.delimiters.decimal+v.split(".")[1]:"",o&&0===Number(v.slice(1))&&(v="")):h=b._.toFixed(a,0,d),q&&!e&&Number(h)>=1e3&&q!==m.abbreviations.trillion)switch(h=String(Number(h)/1e3),q){case m.abbreviations.thousand:q=m.abbreviations.million;break;case m.abbreviations.million:q=m.abbreviations.billion;break;case m.abbreviations.billion:q=m.abbreviations.trillion}if(b._.includes(h,"-")&&(h=h.slice(1),w=!0),h.length
" +
- "Level 1: 60%
" +
- "Level 2: 90%
" +
- "Level 3: 105%
");
+ SourceFiles["SourceFile11"] = new SourceFile(11, "This Source-File makes it so that company favor increases BOTH the player's salary and reputation gain rate " +
+ "at that company by 1% per favor (rather than just the reputation gain). This Source-File also " +
+ " increases the player's company salary and reputation gain multipliers by:
" +
+ "Level 1: 24%
" +
+ "Level 2: 36%
" +
+ "Level 3: 42%
");
SourceFiles["SourceFile12"] = new SourceFile(12);
}
@@ -37911,11 +38100,13 @@ function applySourceFile(srcFile) {
__WEBPACK_IMPORTED_MODULE_0__Player_js__["a" /* Player */].hacking_speed_mult *= incMult;
__WEBPACK_IMPORTED_MODULE_0__Player_js__["a" /* Player */].hacking_money_mult *= incMult;
__WEBPACK_IMPORTED_MODULE_0__Player_js__["a" /* Player */].hacking_grow_mult *= incMult;
+ __WEBPACK_IMPORTED_MODULE_0__Player_js__["a" /* Player */].hacking_mult *= incMult;
+ __WEBPACK_IMPORTED_MODULE_0__Player_js__["a" /* Player */].hacking_exp_mult *= incMult;
break;
case 11: //The Big Crash
var mult = 0;
for (var i = 0; i < srcFile.lvl; ++i) {
- mult += (60 / (Math.pow(2, i)));
+ mult += (24 / (Math.pow(2, i)));
}
var incMult = 1 + (mult / 100);
__WEBPACK_IMPORTED_MODULE_0__Player_js__["a" /* Player */].work_money_mult *= incMult;
@@ -37939,7 +38130,7 @@ function applySourceFile(srcFile) {
"use strict";
/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return prestigeAugmentation; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return prestigeSourceFile; });
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__ActiveScriptsUI_js__ = __webpack_require__(23);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__ActiveScriptsUI_js__ = __webpack_require__(25);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Augmentations_js__ = __webpack_require__(18);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__BitNode_js__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Company_js__ = __webpack_require__(19);
@@ -37947,15 +38138,15 @@ function applySourceFile(srcFile) {
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__engine_js__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__Faction_js__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__Location_js__ = __webpack_require__(13);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__Message_js__ = __webpack_require__(22);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__NetscriptFunctions_js__ = __webpack_require__(24);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__Message_js__ = __webpack_require__(23);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__NetscriptFunctions_js__ = __webpack_require__(21);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__NetscriptWorker_js__ = __webpack_require__(12);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__Player_js__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__Server_js__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__SpecialServerIps_js__ = __webpack_require__(11);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14__StockMarket_js__ = __webpack_require__(27);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14__StockMarket_js__ = __webpack_require__(28);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15__Terminal_js__ = __webpack_require__(20);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16__utils_decimal_js__ = __webpack_require__(26);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16__utils_decimal_js__ = __webpack_require__(27);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16__utils_decimal_js___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_16__utils_decimal_js__);
@@ -38115,6 +38306,7 @@ function prestigeSourceFile() {
} else {
homeComp.setMaxRam(8);
}
+ homeComp.cpuCores = 1;
Object(__WEBPACK_IMPORTED_MODULE_12__Server_js__["a" /* AddToAllServers */])(homeComp);
@@ -38170,7 +38362,7 @@ function prestigeSourceFile() {
__WEBPACK_IMPORTED_MODULE_5__engine_js__["Engine"].loadTerminalContent();
//Reinitialize flags in case you just finished BN-4
- Object(__WEBPACK_IMPORTED_MODULE_9__NetscriptFunctions_js__["c" /* initSingularitySFFlags */])();
+ Object(__WEBPACK_IMPORTED_MODULE_9__NetscriptFunctions_js__["d" /* initSingularitySFFlags */])();
//Gain int exp
__WEBPACK_IMPORTED_MODULE_11__Player_js__["a" /* Player */].gainIntelligenceExp(5);
@@ -38195,7 +38387,7 @@ function prestigeSourceFile() {
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Terminal_js__ = __webpack_require__(20);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__utils_DialogBox_js__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__utils_HelperFunctions_js__ = __webpack_require__(2);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__utils_YesNoBox_js__ = __webpack_require__(21);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__utils_YesNoBox_js__ = __webpack_require__(22);
@@ -38584,8 +38776,7 @@ function evaluate(exp, workerScript) {
resolve(workerScript);
}, function(e) {
if (e.constructor === Array && e.length === 2 && e[0] === "RETURNSTATEMENT") {
- //Returning from a Player-defined function
- resolve(e[1]);
+ reject(e);
} else if (Object(__WEBPACK_IMPORTED_MODULE_11__utils_StringHelperFunctions_js__["f" /* isString */])(e)) {
workerScript.errorMessage = e;
reject(workerScript);
@@ -38650,16 +38841,19 @@ function evaluate(exp, workerScript) {
funcWorkerScript.env = funcEnv;
evaluate(func.body, funcWorkerScript).then(function(res) {
- resolve(res);
+ //If the function finished successfuly, that means there
+ //was no return statement since a return statement rejects. So resolve to null
+ resolve(null);
}).catch(function(e) {
- if (Object(__WEBPACK_IMPORTED_MODULE_11__utils_StringHelperFunctions_js__["f" /* isString */])(e)) {
+ if (e.constructor === Array && e.length === 2 && e[0] === "RETURNSTATEMENT") {
+ //Return statement from function
+ resolve(e[1]);
+ } else if (Object(__WEBPACK_IMPORTED_MODULE_11__utils_StringHelperFunctions_js__["f" /* isString */])(e)) {
reject(makeRuntimeRejectMsg(workerScript, e));
} else if (e instanceof __WEBPACK_IMPORTED_MODULE_4__NetscriptWorker_js__["b" /* WorkerScript */]) {
//Parse out the err message from the WorkerScript and re-reject
var errorMsg = e.errorMessage;
var errorTextArray = errorMsg.split("|");
- console.log("Printing error message from Function:");
- console.log(errorMsg);
if (errorTextArray.length === 4) {
errorMsg = errorTextArray[3];
reject(makeRuntimeRejectMsg(workerScript, errorMsg));
@@ -39442,7 +39636,7 @@ function scriptCalculateWeakenTime(server) {
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__BitNode_js__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Constants_js__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__engine_js__ = __webpack_require__(5);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__InteractiveTutorial_js__ = __webpack_require__(25);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__InteractiveTutorial_js__ = __webpack_require__(26);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__Player_js__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__utils_DialogBox_js__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__utils_HelperFunctions_js__ = __webpack_require__(2);
@@ -90710,7 +90904,7 @@ acequire("../config").defineOptions(Editor.prototype, "editor", {
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Server_js__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__utils_DialogBox_js__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__utils_IPAddress_js__ = __webpack_require__(17);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__utils_YesNoBox_js__ = __webpack_require__(21);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__utils_YesNoBox_js__ = __webpack_require__(22);
@@ -90806,6 +91000,7 @@ let TerminalHelpText =
"kill [script] [args...] Stops the specified script on the current server
" +
"killall Stops all running scripts on the current machine
" +
"ls [| grep pattern] Displays all files on the machine
" +
+ "lscpu Displays the number of CPU cores on the machine
" +
"mem [script] [-t] [n] Displays the amount of RAM required to run the script
" +
"nano [script] Script editor - Open up and edit a script
" +
"ps Display all scripts that are currently running
" +
@@ -91007,19 +91202,19 @@ let HelpTexts = {
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__Faction_js__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Gang_js__ = __webpack_require__(32);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__HacknetNode_js__ = __webpack_require__(37);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__Message_js__ = __webpack_require__(22);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__Message_js__ = __webpack_require__(23);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__Player_js__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__Script_js__ = __webpack_require__(16);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__Server_js__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__Settings_js__ = __webpack_require__(14);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__SpecialServerIps_js__ = __webpack_require__(11);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__StockMarket_js__ = __webpack_require__(27);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__StockMarket_js__ = __webpack_require__(28);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15__utils_GameOptions_js__ = __webpack_require__(38);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16__utils_HelperFunctions_js__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_17__utils_JSONReviver_js__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_18__utils_StringHelperFunctions_js__ = __webpack_require__(4);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_19__utils_decimal_js__ = __webpack_require__(26);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_19__utils_decimal_js__ = __webpack_require__(27);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_19__utils_decimal_js___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_19__utils_decimal_js__);
diff --git a/index.html b/index.html
index eeb328750..da4e366dd 100644
--- a/index.html
+++ b/index.html
@@ -424,7 +424,7 @@
@@ -515,7 +515,7 @@
Hacking Mission
Stocks
Installing Augmentations lets you start over with the perks and benefits granted by all
- of the Augmentations you have ever installed. Also, you will keep any scripts and RAM upgrades
+ of the Augmentations you have ever installed. Also, you will keep any scripts and RAM/Core upgrades
on your home computer (but you will lose all programs besides NUKE.exe).
@@ -696,7 +696,7 @@
Purchase 1TB Server - $75,000,000
Purchase TOR Router - $100,000
Purchase additional RAM for Home computer
-
+ Purchase additional Core for Home computer
Infiltrate Company
diff --git a/src/BitNode.js b/src/BitNode.js
index 977cdde1e..15fa0b482 100644
--- a/src/BitNode.js
+++ b/src/BitNode.js
@@ -79,7 +79,7 @@ function initBitNodes() {
BitNodes["BitNode8"] = new BitNode(8, "Ghost of Wall Street", "COMING SOON"); //Trading only viable strategy
BitNodes["BitNode9"] = new BitNode(9, "MegaCorp", "COMING SOON"); //Single corp/server with increasing difficulty
BitNodes["BitNode10"] = new BitNode(10, "Wasteland", "COMING SOON"); //Postapocalyptic
- BitNodes["BitNode11"] = new BitNode(11, "The Big Crash", "Okay. Sell it all.", //Crashing economy
+ BitNodes["BitNode11"] = new BitNode(11, "The Big Crash", "Okay. Sell it all.",
"The 2050s was defined by the massive amounts of violent civil unrest and anarchic rebellion that rose all around the world. It was this period " +
"of disorder that eventually lead to the governmental reformation of many global superpowers, most notably " +
"the USA and China. But just as the world was slowly beginning to recover from these dark times, financial catastrophe hit.
" +
@@ -94,12 +94,35 @@ function initBitNodes() {
"Hacknet Node production is significantly decreased
" +
"Augmentations are twice as expensive
" +
"Destroying this BitNode will give you Source-File 11, or if you already have this Source-File it will " +
- "upgrade its level up to a maximum of 3. This Source-File increases the player's company salary and reputation gain multipliers by:
" +
- "Level 1: 60%
" +
- "Level 2: 90%
" +
- "Level 3: 105%");
+ "upgrade its level up to a maximum of 3. This Source-File makes it so that company favor increases BOTH " +
+ "the player's salary and reputation gain rate at that company by 1% per favor (rather than just the reputation gain). " +
+ "This Source-File also increases the player's company salary and reputation gain multipliers by:
" +
+ "Level 1: 24%
" +
+ "Level 2: 36%
" +
+ "Level 3: 42%");
+ //Books: Frontera, Shiner
BitNodes["BitNode12"] = new BitNode(12, "Eye of the World", "COMING SOON"); //Become AI
+ BitNodes["BitNode13"] = new BitNode(13, "", "COMING SOON");
+ BitNodes["BitNode14"] = new BitNode(14, "", "COMING SOON");
+ BitNodes["BitNode15"] = new BitNode(15, "", "COMING SOON");
+ BitNodes["BitNode16"] = new BitNode(16, "fOS", "COMING SOON"); //Unlocks the new game mode and the rest of the BitNodes
+ BitNodes["BitNode17"] = new BitNode(17, "", "COMING SOON");
+ BitNodes["BitNode18"] = new BitNode(18, "", "COMING SOON");
+ BitNodes["BitNode19"] = new BitNode(19, "", "COMING SOON");
+ BitNodes["BitNode20"] = new BitNode(20, "", "COMING SOON");
+ BitNodes["BitNode21"] = new BitNode(21, "", "COMING SOON");
+ BitNodes["BitNode22"] = new BitNode(22, "", "COMING SOON");
+ BitNodes["BitNode23"] = new BitNode(23, "", "COMING SOON");
+ BitNodes["BitNode24"] = new BitNode(24, "", "COMING SOON");
+ BitNodes["BitNode25"] = new BitNode(25, "", "COMING SOON");
+ BitNodes["BitNode26"] = new BitNode(26, "", "COMING SOON");
+ BitNodes["BitNode27"] = new BitNode(27, "", "COMING SOON");
+ BitNodes["BitNode28"] = new BitNode(28, "", "COMING SOON");
+ BitNodes["BitNode29"] = new BitNode(29, "", "COMING SOON");
+ BitNodes["BitNode30"] = new BitNode(30, "", "COMING SOON");
+ BitNodes["BitNode31"] = new BitNode(31, "", "COMING SOON");
+ BitNodes["BitNode32"] = new BitNode(32, "", "COMING SOON");
}
let BitNodeMultipliers = {
@@ -172,7 +195,7 @@ function initBitNodeMultipliers() {
break;
case 11: //The Big Crash
BitNodeMultipliers.ServerMaxMoney = 0.1;
- BitNodeMultipliers.ServerStartingMoney = 0.25;
+ BitNodeMultipliers.ServerStartingMoney = 0.1;
BitNodeMultipliers.ServerGrowthRate = 0.5;
BitNodeMultipliers.ServerWeakenRate = 2;
BitNodeMultipliers.CompanyWorkMoney = 0.5;
diff --git a/src/Constants.js b/src/Constants.js
index 22ada1be7..1575ddd9e 100644
--- a/src/Constants.js
+++ b/src/Constants.js
@@ -1,5 +1,5 @@
let CONSTANTS = {
- Version: "0.29.3",
+ Version: "0.30.0",
//Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
//and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
@@ -118,16 +118,17 @@ let CONSTANTS = {
IntelligenceCrimeBaseExpGain: 0.001,
IntelligenceProgramBaseExpGain: 500, //Program required hack level divided by this to determine int exp gain
IntelligenceTerminalHackBaseExpGain: 200, //Hacking exp divided by this to determine int exp gain
- IntelligenceSingFnBaseExpGain: 0.0005,
- IntelligenceClassBaseExpGain: 0.0000005,
+ IntelligenceSingFnBaseExpGain: 0.001,
+ IntelligenceClassBaseExpGain: 0.000001,
+ IntelligenceHackingMissionBaseExpGain: 0.03, //Hacking Mission difficulty multiplied by this to get exp gain
//Hacking Missions
HackingMissionRepToDiffConversion: 10000, //Faction rep is divided by this to get mission difficulty
- HackingMissionRepToRewardConversion: 10, //Faction rep divided byt his to get mission rep reward
+ HackingMissionRepToRewardConversion: 7, //Faction rep divided byt his to get mission rep reward
HackingMissionSpamTimeIncrease: 15000, //How much time limit increase is gained when conquering a Spam Node (ms)
HackingMissionTransferAttackIncrease: 1.05, //Multiplier by which the attack for all Core Nodes is increased when conquering a Transfer Node
- HackingMissionMiscDefenseIncrease: 1.12, //The amount by which every misc node's defense is multiplied when one is conquered
- HackingMissionDifficultyToHacking: 120, //Difficulty is multiplied by this to determine enemy's "hacking" level (to determine effects of scan/attack, etc)
+ HackingMissionMiscDefenseIncrease: 1.05, //The amount by which every misc node's defense is multiplied when one is conquered
+ HackingMissionDifficultyToHacking: 150, //Difficulty is multiplied by this to determine enemy's "hacking" level (to determine effects of scan/attack, etc)
HackingMissionHowToPlay: "Hacking missions are a minigame that, if won, will reward you with faction reputation.
" +
"In this game you control a set of Nodes and use them to try and defeat an enemy. Your Nodes " +
"are colored blue, while the enemy's are red. There are also other nodes on the map colored gray " +
@@ -168,8 +169,11 @@ let CONSTANTS = {
"the connection between one of your Nodes and its target. Alternatively, you can select the 'source' Node and click the 'Drop Connection' button, " +
"or press 'd'.
" +
"Other Notes:
" +
- "-Whenever you conquer a miscellenaous Node (not owned by the enemy), the defense of all remaining miscellaneous Nodes will increase " +
- "by a fixed percentage.",
+ "-Whenever a miscellenaous Node (not owned by the player or enemy) is conquered, the defense of all remaining miscellaneous Nodes that " +
+ "are not actively being targeted will increase by a fixed percentage.
" +
+ "-Whenever a Node is conquered, its stats are significantly reduced
" +
+ "-Miscellaneous Nodes slowly raise their defense over time
" +
+ "-Nodes slowly regenerate health and raise over time.",
//Gang constants
@@ -1016,44 +1020,28 @@ let CONSTANTS = {
"Here is everything you will KEEP when you install an Augmentation:
" +
"Every Augmentation you have installed
" +
"Scripts on your home computer
" +
- "RAM Upgrades on your home computer
" +
+ "RAM and CPU Core Upgrades on your home computer
" +
"World Stock Exchange account and TIX API Access
",
LatestUpdate:
+ "v0.30.0
" +
+ "-Added getAugmentations() and getAugmentationsFromFaction() Netscript Singularity Functions
" +
+ "-Increased the rate of Intelligence exp gain
" +
+ "-Added a new upgrade for home computers: CPU Cores. Each CPU core on the home computer " +
+ "grants an additional starting Core Node in Hacking Missions. I may add in other benefits later. Like RAM upgrades, upgrading " +
+ "the CPU Core on your home computer persists until you enter a new BitNode.
" +
+ "-Added lscpu Terminal command to check number of CPU Cores
" +
+ "-Changed the effect of Source-File 5 and made BitNode-5 a little bit harder
" +
+ "-Fixed a bug with Netscript functions (the ones you create yourself)
" +
+ "-Hacking Missions officially released (they give reputation now). Notable changes in the last few updates:
" +
+ "---Misc Nodes slowly gain hp/defense over time
" +
+ "---Conquering a Misc Node will increase the defense of all remaining Misc Nodes that are not being targeted by a certain percentage
" +
+ "---Reputation reward for winning a Mission is now affected by faction favor and Player's faction rep multiplier
" +
+ "---Whenever a Node is conquered, its stats are reduced
" +
"v0.29.3
" +
"-Fixed bug for killing scripts and showing error messages when there are errors in a player-defined function
" +
"-Added function name autocompletion in Script Editor. Press Ctrl+space on a prefix to show autocompletion options.
" +
- "-Minor rebalancing and bug fixes for Infiltration
" +
- "v0.29.2
" +
- "-installAugmentations() Singularity Function now takes a callback script as an argument. This is a script " +
- "that gets ran automatically after Augmentations are installed. The script is run with no arguments and only a single thread, " +
- "and must be found on your home computer.
" +
- "-Added the ability to create your own functions in Netscript. See this link for details
" +
- "-Added :q, :x, and :wq Vim Ex Commands when using the Vim script editor keybindings. :w, :x, and :wq will all save the script and return to Terminal. " +
- ":q will quit (return to Terminal) WITHOUT saving. If anyone thinks theres an issue with this please let me know, I don't use Vim
" +
- "-Added a new Augmentation: ADR-V2 Pheromone Gene
" +
- "-In Hacking Missions, enemy nodes will now automatically target Nodes and perform actions.
" +
- "-Re-balanced Hacking Missions through minor tweaking of many numbers
" +
- "-The faction reputation reward for Hacking Missions was slightly increased
" +
- "v0.29.1
" +
- "-New gameplay feature that is currently in BETA: Hacking Missions. Hacking Missions is an active gameplay mechanic (its a minigame) " +
- "that is meant to be used to earn faction reputation. However, since this is currently in beta, hacking missions will NOT grant reputation " +
- "for the time being, since the feature likely has many bugs, balance problems, and other issues. If you have any feedback " +
- "regarding the new feature, feel free to let me know
" +
- "-CHANGED THE RETURN VALUE OF getScriptIncome() WHEN RAN WITH NO ARGUMENTS. It will now return an array of " +
- "two values rather than a single value. This may break your scripts, so make sure to update them!
" +
- "-Added continue statement for for/while loops
" +
- "-Added getServerMinSecurityLevel(), getPurchasedServers(), and getTimeSinceLastAug() Netscript functions
" +
- "-Netscript scp() function can now take an array as the first argument, and will try to copy " +
- "every file specified in the array (it will just call scp() normally for every element in the array). " +
- "If an array is passed in, then the scp() function returns true if at least one element from the array is successfully copied
" +
- "-Added Javascript's Date module to Netscript. Since 'new' is not supported in Netscript yet, only the Date module's " +
- "static methods will work (now(), UTC(), parse(), etc.).
" +
- "-Failing a crime now gives half the experience it did before
" +
- "-The forced repeated 'Find The-Cave' message after installing The Red Pill Augmentation now only happens " +
- "if you've never destroyed a BitNode before, and will only popup every 15 minutes. If you have already destroyed a BitNode, " +
- "the message will not pop up if you have messages suppressed (if you don't have messages suppressed it WILL still repeatedly popup)
" +
- "-fileExists() function now works on literature files
",
+ "-Minor rebalancing and bug fixes for Infiltration and Hacking Missions
"
}
export {CONSTANTS};
diff --git a/src/HelpText.js b/src/HelpText.js
index 6a43cbed8..468e0f9eb 100644
--- a/src/HelpText.js
+++ b/src/HelpText.js
@@ -18,6 +18,7 @@ let TerminalHelpText =
"kill [script] [args...] Stops the specified script on the current server
" +
"killall Stops all running scripts on the current machine
" +
"ls [| grep pattern] Displays all files on the machine
" +
+ "lscpu Displays the number of CPU cores on the machine
" +
"mem [script] [-t] [n] Displays the amount of RAM required to run the script
" +
"nano [script] Script editor - Open up and edit a script
" +
"ps Display all scripts that are currently running
" +
diff --git a/src/Location.js b/src/Location.js
index 76616c991..757115789 100644
--- a/src/Location.js
+++ b/src/Location.js
@@ -22,6 +22,7 @@ import {SpecialServerNames, SpecialServerIps} from "./SpecialServerIps.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {clearEventListeners} from "../utils/HelperFunctions.js";
import {createRandomIp} from "../utils/IPAddress.js";
+import numeral from "../utils/numeral.min.js";
import {formatNumber} from "../utils/StringHelperFunctions.js";
import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
yesNoBoxGetYesButton, yesNoBoxGetNoButton,
@@ -173,6 +174,7 @@ function displayLocationContent() {
var purchase1tb = document.getElementById("location-purchase-1tb");
var purchaseTor = document.getElementById("location-purchase-tor");
var purchaseHomeRam = document.getElementById("location-purchase-home-ram");
+ var purchaseHomeCores = document.getElementById("location-purchase-home-cores");
var travelAgencyText = document.getElementById("location-travel-agency-text");
var travelToAevum = document.getElementById("location-travel-to-aevum");
@@ -264,6 +266,7 @@ function displayLocationContent() {
purchase1tb.style.display = "none";
purchaseTor.style.display = "none";
purchaseHomeRam.style.display = "none";
+ purchaseHomeCores.style.display = "none";
purchase2gb.innerHTML = "Purchase 2GB Server - $" + formatNumber(2*CONSTANTS.BaseCostFor1GBOfRamServer, 2);
purchase4gb.innerHTML = "Purchase 4GB Server - $" + formatNumber(4*CONSTANTS.BaseCostFor1GBOfRamServer, 2);
@@ -419,6 +422,7 @@ function displayLocationContent() {
purchase1tb.style.display = "block";
purchaseTor.style.display = "block";
purchaseHomeRam.style.display = "block";
+ purchaseHomeCores.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumECorp,
6000, 116, 150, 8.5);
break;
@@ -464,6 +468,7 @@ function displayLocationContent() {
purchase1tb.style.display = "block";
purchaseTor.style.display = "block";
purchaseHomeRam.style.display = "block";
+ purchaseHomeCores.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumFulcrumTechnologies,
6000, 96, 100, 9);
break;
@@ -539,6 +544,7 @@ function displayLocationContent() {
purchase8gb.style.display = "block";
purchaseTor.style.display = "block";
purchaseHomeRam.style.display = "block";
+ purchaseHomeCores.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumNetLinkTechnologies,
160, 10, 15, 1.8);
break;
@@ -718,6 +724,7 @@ function displayLocationContent() {
purchase4gb.style.display = "block";
purchaseTor.style.display = "block";
purchaseHomeRam.style.display = "block";
+ purchaseHomeCores.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12AlphaEnterprises,
250, 14, 40, 2.7);
break;
@@ -847,6 +854,7 @@ function displayLocationContent() {
purchase128gb.style.display = "block";
purchase256gb.style.display = "block";
purchaseHomeRam.style.display = "block";
+ purchaseHomeCores.style.display = "block";
setInfiltrateButton(infiltrate, Locations.IshimaStormTechnologies,
700, 24, 100, 5.9);
break;
@@ -878,6 +886,7 @@ function displayLocationContent() {
purchase32gb.style.display = "block";
purchaseTor.style.display = "block";
purchaseHomeRam.style.display = "block";
+ purchaseHomeCores.style.display = "block";
setInfiltrateButton(infiltrate, Locations.IshimaOmegaSoftware,
200, 10, 40, 2.3);
break;
@@ -994,6 +1003,7 @@ function displayLocationContent() {
purchase256gb.style.display = "block";
purchaseTor.style.display = "block";
purchaseHomeRam.style.display = "block";
+ purchaseHomeCores.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenCompuTek,
300, 12, 35, 3.1);
break;
@@ -1574,6 +1584,7 @@ function initLocationButtons() {
var purchase1tb = document.getElementById("location-purchase-1tb");
var purchaseTor = document.getElementById("location-purchase-tor");
var purchaseHomeRam = document.getElementById("location-purchase-home-ram");
+ var purchaseHomeCores = document.getElementById("location-purchase-home-cores");
var travelToAevum = document.getElementById("location-travel-to-aevum");
var travelToChongqing = document.getElementById("location-travel-to-chongqing");
@@ -1742,6 +1753,42 @@ function initLocationButtons() {
"This will cost $" + formatNumber(cost, 2));
});
+ purchaseHomeCores.addEventListener("click", function() {
+ var currentCores = Player.getHomeComputer().cpuCores;
+ if (currentCores >= 8) {return;} //Max of 8 cores
+
+ //Cost of purchasing another cost is found by indexing this array with number of current cores
+ var cost = [0,
+ 10000000000, //1->2 Cores - 10 bn
+ 250000000000, //2->3 Cores - 250 bn
+ 5000000000000, //3->4 Cores - 5 trillion
+ 100000000000000, //4->5 Cores - 100 trillion
+ 1000000000000000, //5->6 Cores - 1 quadrillion
+ 20000000000000000, //6->7 Cores - 20 quadrillion
+ 200000000000000000]; //7->8 Cores - 200 quadrillion
+ cost = cost[currentCores];
+ var yesBtn = yesNoBoxGetYesButton(), noBtn = yesNoBoxGetNoButton();
+ yesBtn.innerHTML = "Purchase"; noBtn.innerHTML = "Cancel";
+ yesBtn.addEventListener("click", ()=>{
+ if (Player.money.lt(cost)) {
+ dialogBoxCreate("You do not have enough mone to purchase an additional CPU Core for your home computer!");
+ } else {
+ Player.loseMoney(cost);
+ Player.getHomeComputer().cpuCores++;
+ dialogBoxCreate("You purchased an additional CPU Core for your home computer! It now has " +
+ Player.getHomeComputer().cpuCores + " cores.");
+ }
+ yesNoBoxClose();
+ });
+ noBtn.addEventListener("click", ()=>{
+ yesNoBoxClose();
+ });
+ yesNoBoxCreate("Would you like to purchase an additional CPU Core for your home computer? Each CPU Core " +
+ "lets you start with an additional Core Node in Hacking Missions.
" +
+ "Purchasing an additional core (for a total of " + (Player.getHomeComputer().cpuCores + 1) + ") will " +
+ "cost " + numeral(cost).format('$0.000a'));
+ });
+
travelToAevum.addEventListener("click", function() {
travelBoxCreate(Locations.Aevum, 200000);
return false;
diff --git a/src/Missions.js b/src/Missions.js
index ef65cf699..8d57770cf 100644
--- a/src/Missions.js
+++ b/src/Missions.js
@@ -76,6 +76,7 @@ function Node(type, stats) {
this.pos = [0, 0]; //x, y
this.el = null; //Holds the Node's DOM element
this.action = null;
+ this.targetedCount = 0; //Count of how many connections this node is the target of
//Holds the JsPlumb Connection object for this Node,
//where this Node is the Source (since each Node
@@ -149,6 +150,15 @@ Node.prototype.deselect = function(actionButtons) {
}
}
+
+Node.prototype.untarget = function() {
+ if (this.targetedCount === 0) {
+ console.log("WARN: Node " + this.el.id + " is being 'untargeted' when it has no target count");
+ return;
+ }
+ --this.targetedCount;
+}
+
//Hacking mission instance
//Takes in the reputation of the Faction for which the mission is
//being conducted
@@ -189,8 +199,7 @@ function HackingMission(rep, fac) {
this.jsplumbinstance = null;
- //difficulty capped at 16
- this.difficulty = Math.min(16, Math.round(rep / CONSTANTS.HackingMissionRepToDiffConversion) + 1);
+ this.difficulty = rep / CONSTANTS.HackingMissionRepToDiffConversion + 1;
console.log("difficulty: " + this.difficulty);
this.reward = 250 + (rep / CONSTANTS.HackingMissionRepToRewardConversion);
}
@@ -203,20 +212,21 @@ HackingMission.prototype.init = function() {
var home = Player.getHomeComputer()
for (var i = 0; i < home.cpuCores; ++i) {
var stats = {
- atk: (Player.hacking_skill / 5),
+ atk: (Player.hacking_skill / 7.5) + 30,
def: (Player.hacking_skill / 20),
- hp: (Player.hacking_skill / 5),
+ hp: (Player.hacking_skill / 4),
};
this.playerCores.push(new Node(NodeTypes.Core, stats));
this.playerCores[i].setControlledByPlayer();
- this.setNodePosition(this.playerCores[i], 0, i);
- this.removeAvailablePosition(0, i);
+ this.setNodePosition(this.playerCores[i], i, 0);
+ this.removeAvailablePosition(i, 0);
}
//Randomly generate enemy nodes (CPU and Firewall) based on difficulty
- var numNodes = Math.max(1, Math.round(this.difficulty / 3));
- var numFirewalls = getRandomInt(this.difficulty, this.difficulty + 1);
- var numDatabases = getRandomInt(this.difficulty, this.difficulty + 1);
+ var numNodes = Math.min(8, Math.max(1, Math.round(this.difficulty / 4)));
+ var numFirewalls = Math.min(20,
+ getRandomInt(Math.round(this.difficulty/2), Math.round(this.difficulty/2) + 1));
+ var numDatabases = Math.min(10, getRandomInt(1, Math.round(this.difficulty / 3) + 1));
var totalNodes = numNodes + numFirewalls + numDatabases;
var xlimit = 7 - Math.floor(totalNodes / 8);
console.log("numNodes: " + numNodes);
@@ -224,12 +234,12 @@ HackingMission.prototype.init = function() {
console.log("numDatabases: " + numDatabases);
console.log("totalNodes: " + totalNodes);
console.log("xlimit: " + xlimit);
- var randMult = addOffset(0.85 + (this.difficulty / 6), 10);
+ var randMult = addOffset(0.8 + (this.difficulty / 5), 10);
for (var i = 0; i < numNodes; ++i) {
var stats = {
- atk: randMult * getRandomInt(50, 75),
+ atk: randMult * getRandomInt(75, 85),
def: randMult * getRandomInt(20, 40),
- hp: randMult * getRandomInt(100, 120)
+ hp: randMult * getRandomInt(200, 220)
}
this.enemyCores.push(new Node(NodeTypes.Core, stats));
this.enemyCores[i].setControlledByEnemy();
@@ -238,8 +248,8 @@ HackingMission.prototype.init = function() {
for (var i = 0; i < numFirewalls; ++i) {
var stats = {
atk: 0,
- def: randMult * getRandomInt(50, 75),
- hp: randMult * getRandomInt(150, 200)
+ def: randMult * getRandomInt(80, 100),
+ hp: randMult * getRandomInt(250, 275)
}
this.enemyNodes.push(new Node(NodeTypes.Firewall, stats));
this.enemyNodes[i].setControlledByEnemy();
@@ -248,8 +258,8 @@ HackingMission.prototype.init = function() {
for (var i = 0; i < numDatabases; ++i) {
var stats = {
atk: 0,
- def: randMult * getRandomInt(20, 30),
- hp: randMult * getRandomInt(120, 150)
+ def: randMult * getRandomInt(75, 100),
+ hp: randMult * getRandomInt(200, 250)
}
var node = new Node(NodeTypes.Database, stats);
node.setControlledByEnemy();
@@ -264,8 +274,12 @@ HackingMission.prototype.init = function() {
HackingMission.prototype.createPageDom = function() {
var container = document.getElementById("mission-container");
+ var favorMult = 1 + (this.faction.favor / 100);
+ var gain = this.reward * Player.faction_rep_mult * favorMult;
var headerText = document.createElement("p");
- headerText.innerHTML = "You are about to start a hacking mission! For more information " +
+ headerText.innerHTML = "You are about to start a hacking mission! You will gain " +
+ formatNumber(gain, 3) + " faction reputation with " + this.faction.name +
+ " if you win. For more information " +
"about how hacking missions work, click one of the guide links " +
"below (one opens up an in-game guide and the other opens up " +
"the guide from the wiki). Click the 'Start' button to begin.";
@@ -604,26 +618,28 @@ HackingMission.prototype.createMap = function() {
document.getElementById("mission-container").appendChild(map);
//Create random Nodes for every space in the map that
- //hasn't been filled yet
+ //hasn't been filled yet. The stats of each Node will be based on
+ //the player/enemy attack
+ var averageAttack = (this.playerAtk + this.enemyAtk) / 2;
for (var x = 0; x < 8; ++x) {
for (var y = 0; y < 8; ++y) {
if (!(this.map[x][y] instanceof Node)) {
var node, type = getRandomInt(0, 2);
- var randMult = addOffset(0.75 + (this.difficulty / 3), 20);
+ var randMult = addOffset(0.85 + (this.difficulty / 2), 15);
switch (type) {
case 0: //Spam
var stats = {
atk: 0,
- def: randMult * getRandomInt(30, 50),
- hp: randMult * getRandomInt(125, 150)
+ def: averageAttack * 1.2 + getRandomInt(10, 50),
+ hp: randMult * getRandomInt(160, 180)
}
node = new Node(NodeTypes.Spam, stats);
break;
case 1: //Transfer
var stats = {
atk: 0,
- def: randMult * getRandomInt(40, 60),
- hp: randMult * getRandomInt(150, 175)
+ def: averageAttack * 1.2 + getRandomInt(10, 50),
+ hp: randMult * getRandomInt(210, 230)
}
node = new Node(NodeTypes.Transfer, stats);
break;
@@ -631,8 +647,8 @@ HackingMission.prototype.createMap = function() {
default:
var stats = {
atk: 0,
- def: randMult * getRandomInt(50, 75),
- hp: randMult * getRandomInt(200, 250)
+ def: averageAttack * 1.2 + getRandomInt(25, 75),
+ hp: randMult * getRandomInt(275, 300)
}
node = new Node(NodeTypes.Shield, stats);
break;
@@ -927,12 +943,16 @@ HackingMission.prototype.initJsPlumb = function() {
var sourceNode = this.getNodeFromElement(info.source);
sourceNode.conn = info.connection;
+ var targetNode = this.getNodeFromElement(info.target);
+ ++targetNode.targetedCount;
});
//Detach Connection events
instance.bind("connectionDetached", (info, originalEvent)=>{
var sourceNode = this.getNodeFromElement(info.source);
sourceNode.conn = null;
+ var targetNode = this.getNodeFromElement(info.target);
+ targetNode.untarget();
});
}
@@ -955,13 +975,14 @@ HackingMission.prototype.dropAllConnectionsToNode = function(node) {
allConns[i].endpoints[0].detachFrom(allConns[i].endpoints[1]);
}
}
+ node.beingTargeted = false;
}
var storedCycles = 0;
HackingMission.prototype.process = function(numCycles=1) {
if (!this.started) {return;}
storedCycles += numCycles;
- if (storedCycles < 3) {return;} //Only process every 2 cycles minimum
+ if (storedCycles < 2) {return;} //Only process every 3 cycles minimum
var res = false;
//Process actions of all player nodes
@@ -988,6 +1009,12 @@ HackingMission.prototype.process = function(numCycles=1) {
}
});
+ //The hp of enemy databases increases slowly
+ this.enemyDatabases.forEach((node)=>{
+ node.maxhp += (0.1 * storedCycles);
+ node.hp += (0.1 * storedCycles);
+ });
+
if (res) {
this.calculateAttacks();
this.calculateDefenses();
@@ -1005,9 +1032,12 @@ HackingMission.prototype.process = function(numCycles=1) {
return;
}
- //Defense of every misc Node increase by 0.5 per second
+ //Defense/hp of misc nodes increases slowly over time
this.miscNodes.forEach((node)=>{
node.def += (0.1 * storedCycles);
+ node.maxhp += (0.05 * storedCycles);
+ node.hp += (0.1 * storedCycles);
+ if (node.hp > node.maxhp) {node.hp = node.maxhp;}
this.updateNodeDomElement(node);
});
@@ -1103,6 +1133,10 @@ HackingMission.prototype.processNode = function(nodeObj, numCycles=1) {
targetNode.deselect(this.actionButtons);
}
+ //The conquered node has its stats reduced
+ targetNode.atk /= 3;
+ targetNode.def /= 3;
+
//Flag for whether the target node was a misc node
var isMiscNode = !targetNode.plyrCtrl && !targetNode.enmyCtrl;
@@ -1205,9 +1239,11 @@ HackingMission.prototype.processNode = function(nodeObj, numCycles=1) {
}
//If a misc node was conquered, the defense for all misc nodes increases by some fixed amount
- if (isMiscNode && conqueredByPlayer) {
+ if (isMiscNode) { //&& conqueredByPlayer) {
this.miscNodes.forEach((node)=>{
- node.def *= CONSTANTS.HackingMissionMiscDefenseIncrease;
+ if (node.targetedCount === 0) {
+ node.def *= CONSTANTS.HackingMissionMiscDefenseIncrease;
+ }
});
}
}
@@ -1218,7 +1254,7 @@ HackingMission.prototype.processNode = function(nodeObj, numCycles=1) {
return calcStats;
}
-//Enemy "AI" for CPU Cor eand Transfer Nodes
+//Enemy "AI" for CPU Core and Transfer Nodes
HackingMission.prototype.enemyAISelectAction = function(nodeObj) {
if (nodeObj === null) {return;}
switch(nodeObj.type) {
@@ -1238,11 +1274,11 @@ HackingMission.prototype.enemyAISelectAction = function(nodeObj) {
}
if (this.nodeReachableByEnemy(node)) {
//Create connection
- console.log("Enemy core selected a Player Node as target");
nodeObj.conn = this.jsplumbinstance.connect({
source:nodeObj.el,
target:node.el
});
+ ++node.targetedCount;
} else {
//Randomly pick a player core and attack it if its reachable
rand = getRandomInt(0, this.playerCores.length-1);
@@ -1254,11 +1290,11 @@ HackingMission.prototype.enemyAISelectAction = function(nodeObj) {
if (this.nodeReachableByEnemy(node)) {
//Create connection
- console.log("Enemy core selected a Player Core as target");
nodeObj.conn = this.jsplumbinstance.connect({
source:nodeObj.el,
target:node.el
});
+ ++node.targetedCount;
}
}
} else {
@@ -1266,11 +1302,11 @@ HackingMission.prototype.enemyAISelectAction = function(nodeObj) {
var rand = getRandomInt(0, this.miscNodes.length-1);
var node = this.miscNodes[rand];
if (this.nodeReachableByEnemy(node)) {
- console.log("Enemy core selected a Misc Node as target: " + node.el.id);
nodeObj.conn = this.jsplumbinstance.connect({
source:nodeObj.el,
target:node.el,
});
+ ++node.targetedCount;
}
}
@@ -1288,13 +1324,13 @@ HackingMission.prototype.enemyAISelectAction = function(nodeObj) {
console.log("Error getting Target node Object in enemyAISelectAction()");
}
- if (targetNode.def > this.enemyAtk + 25) {
+ if (targetNode.def > this.enemyAtk + 15) {
if (nodeObj.def < 50) {
nodeObj.action = NodeActions.Fortify;
} else {
nodeObj.action = NodeActions.Overflow;
}
- } else if (Math.abs(targetNode.def - this.enemyAtk) <= 25) {
+ } else if (Math.abs(targetNode.def - this.enemyAtk) <= 15) {
nodeObj.action = NodeActions.Scan;
} else {
nodeObj.action = NodeActions.Attack;
@@ -1324,11 +1360,11 @@ HackingMission.prototype.calculateAttackDamage = function(atk, def, hacking = 0)
}
HackingMission.prototype.calculateScanEffect = function(atk, def, hacking=0) {
- return Math.max((atk) + hacking / hackEffWeightTarget - def, 1);
+ return Math.max(0.85 * ((atk) + hacking / hackEffWeightTarget - (def * 0.95)), 2);
}
HackingMission.prototype.calculateWeakenEffect = function(atk, def, hacking=0) {
- return Math.max((atk) + hacking / hackEffWeightTarget - def, 1);
+ return Math.max((atk) + hacking / hackEffWeightTarget - (def * 0.95), 2);
}
HackingMission.prototype.calculateFortifyEffect = function(hacking=0) {
@@ -1343,7 +1379,7 @@ HackingMission.prototype.calculateOverflowEffect = function(hacking=0) {
HackingMission.prototype.updateTimer = function() {
var timer = document.getElementById("hacking-mission-timer");
- //Convert time remaining to a string of the form m:ss
+ //Convert time remaining to a string of the form mm:ss
var seconds = Math.round(this.time / 1000);
var minutes = Math.trunc(seconds / 60);
seconds %= 60;
@@ -1357,11 +1393,17 @@ HackingMission.prototype.finishMission = function(win) {
currMission = null;
if (win) {
- dialogBoxCreate("Mission won! This feature is currently in " +
- "beta so you did not earn anything, but normally you would have won " +
- this.reward + " reputation with " + this.faction.name);
+ var favorMult = 1 + (this.faction.favor / 100);
+ console.log("Hacking mission base reward: " + this.reward);
+ console.log("favorMult: " + favorMult);
+ console.log("rep mult: " + Player.faction_rep_mult);
+ var gain = this.reward * Player.faction_rep_mult * favorMult;
+ dialogBoxCreate("Mission won! You earned " +
+ formatNumber(gain, 3) + " reputation with " + this.faction.name);
+ Player.gainIntelligenceExp(this.difficulty * CONSTANTS.IntelligenceHackingMissionBaseExpGain);
+ this.faction.playerReputation += gain;
} else {
- dialogBoxCreate("Mission lost/forfeited!");
+ dialogBoxCreate("Mission lost/forfeited! You did not gain any faction reputation.");
}
//Clear mission container
diff --git a/src/NetscriptEvaluator.js b/src/NetscriptEvaluator.js
index 71da0e27a..9221ef1dd 100644
--- a/src/NetscriptEvaluator.js
+++ b/src/NetscriptEvaluator.js
@@ -35,8 +35,7 @@ function evaluate(exp, workerScript) {
resolve(workerScript);
}, function(e) {
if (e.constructor === Array && e.length === 2 && e[0] === "RETURNSTATEMENT") {
- //Returning from a Player-defined function
- resolve(e[1]);
+ reject(e);
} else if (isString(e)) {
workerScript.errorMessage = e;
reject(workerScript);
@@ -101,16 +100,19 @@ function evaluate(exp, workerScript) {
funcWorkerScript.env = funcEnv;
evaluate(func.body, funcWorkerScript).then(function(res) {
- resolve(res);
+ //If the function finished successfuly, that means there
+ //was no return statement since a return statement rejects. So resolve to null
+ resolve(null);
}).catch(function(e) {
- if (isString(e)) {
+ if (e.constructor === Array && e.length === 2 && e[0] === "RETURNSTATEMENT") {
+ //Return statement from function
+ resolve(e[1]);
+ } else if (isString(e)) {
reject(makeRuntimeRejectMsg(workerScript, e));
} else if (e instanceof WorkerScript) {
//Parse out the err message from the WorkerScript and re-reject
var errorMsg = e.errorMessage;
var errorTextArray = errorMsg.split("|");
- console.log("Printing error message from Function:");
- console.log(errorMsg);
if (errorTextArray.length === 4) {
errorMsg = errorTextArray[3];
reject(makeRuntimeRejectMsg(workerScript, errorMsg));
diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js
index 39e967fae..1d5e9aee9 100644
--- a/src/NetscriptFunctions.js
+++ b/src/NetscriptFunctions.js
@@ -43,12 +43,10 @@ import {printArray, powerOfTwo} from "../utils/HelperFunctio
import {createRandomIp} from "../utils/IPAddress.js";
import {formatNumber, isString, isHTML} from "../utils/StringHelperFunctions.js";
-var hasSingularitySF = false;
-var hasAISF = false;
+var hasSingularitySF = false, hasAISF = false, hasBn11SF = false;
var singularitySFLvl = 1;
-//Also used to check for Artificial Intelligence Source File, don't want to change
-//name though
+//Used to check and set flags for every Source File, despite the name of the function
function initSingularitySFFlags() {
for (var i = 0; i < Player.sourceFiles.length; ++i) {
if (Player.sourceFiles[i].n === 4) {
@@ -58,6 +56,9 @@ function initSingularitySFFlags() {
if (Player.sourceFiles[i].n === 5) {
hasAISF = true;
}
+ if (Player.sourceFiles[i].n === 11) {
+ hasBn11SF = true;
+ }
}
}
@@ -1898,6 +1899,44 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log("Began creating program: " + name);
return true;
},
+ getOwnedAugmentations(purchased=false) {
+ if (Player.bitNodeN != 4) {
+ if (!(hasSingularitySF && singularitySFLvl >= 3)) {
+ throw makeRuntimeRejectMsg(workerScript, "Cannot run getOwnedAugmentations(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");
+ return [];
+ }
+ }
+ var res = [];
+ for (var i = 0; i < Player.augmentations.length; ++i) {
+ res.push(Player.augmentations[i].name);
+ }
+ if (purchased) {
+ for (var i = 0; i < Player.queuedAugmentations.length; ++i) {
+ res.push(Player.queuedAugmentations[i].name);
+ }
+ }
+ return res;
+ },
+ getAugmentationsFromFaction(facname) {
+ if (Player.bitNodeN != 4) {
+ if (!(hasSingularitySF && singularitySFLvl >= 3)) {
+ throw makeRuntimeRejectMsg(workerScript, "Cannot run getAugmentationsFromFaction(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");
+ return [];
+ }
+ }
+
+ if (!factionExists(facname)) {
+ workerScript.scriptRef.log("ERROR: getAugmentationsFromFaction() failed. Invalid faction name passed in (this is case-sensitive): " + facname);
+ return [];
+ }
+
+ var fac = Factions[facname];
+ var res = [];
+ for (var i = 0; i < fac.augmentations.length; ++i) {
+ res.push(fac.augmentations[i]);
+ }
+ return res;
+ },
getAugmentationCost(name) {
if (Player.bitNodeN != 4) {
if (!(hasSingularitySF && singularitySFLvl >= 3)) {
@@ -1993,4 +2032,4 @@ function NetscriptFunctions(workerScript) {
}
}
-export {NetscriptFunctions, initSingularitySFFlags, hasSingularitySF};
+export {NetscriptFunctions, initSingularitySFFlags, hasSingularitySF, hasBn11SF};
diff --git a/src/NetscriptWorker.js b/src/NetscriptWorker.js
index ae1dd2045..e8754b62c 100644
--- a/src/NetscriptWorker.js
+++ b/src/NetscriptWorker.js
@@ -115,6 +115,11 @@ function runScriptsLoop() {
dialogBoxCreate("Script runtime unknown error. This is a bug please contact game developer");
console.log("ERROR: Evaluating workerscript returns an Error. THIS SHOULDN'T HAPPEN: " + w.toString());
return;
+ } else if (w.constructor === Array && w.length === 2 && w[0] === "RETURNSTATEMENT") {
+ //Script ends with a return statement
+ console.log("Script returning with value: " + w[1]);
+ //TODO maybe do something with this in the future
+ return;
} else if (w instanceof WorkerScript) {
if (isScriptErrorMessage(w.errorMessage)) {
var errorTextArray = w.errorMessage.split("|");
diff --git a/src/Player.js b/src/Player.js
index adc6a1f54..005048118 100644
--- a/src/Player.js
+++ b/src/Player.js
@@ -13,6 +13,7 @@ import {Factions, Faction,
displayFactionContent} from "./Faction.js";
import {Gang, resetGangs} from "./Gang.js";
import {Locations} from "./Location.js";
+import {hasBn11SF} from "./NetscriptFunctions.js";
import {AllServers, Server, AddToAllServers} from "./Server.js";
import {SpecialServerIps, SpecialServerNames} from "./SpecialServerIps.js";
import {SourceFiles, applySourceFile} from "./SourceFile.js";
@@ -1068,9 +1069,13 @@ PlayerObject.prototype.workForFaction = function(numCycles) {
//Money gained per game cycle
PlayerObject.prototype.getWorkMoneyGain = function() {
+ var bn11Mult = 1;
var company = Companies[this.companyName];
+ if (hasBn11SF) {
+ bn11Mult = 1 + (company.favor / 100);
+ }
return this.companyPosition.baseSalary * company.salaryMultiplier *
- this.work_money_mult * BitNodeMultipliers.CompanyWorkMoney;
+ this.work_money_mult * BitNodeMultipliers.CompanyWorkMoney * bn11Mult;
}
//Hack exp gained per game cycle
@@ -1459,12 +1464,14 @@ PlayerObject.prototype.finishCrime = function(cancelled) {
break;
case CONSTANTS.CrimeRobStore:
this.karma -= 0.5;
+ this.gainIntelligenceExp(0.25 * CONSTANTS.IntelligenceCrimeBaseExpGain);
break;
case CONSTANTS.CrimeMug:
this.karma -= 0.25;
break;
case CONSTANTS.CrimeLarceny:
this.karma -= 1.5;
+ this.gainIntelligenceExp(0.5 * CONSTANTS.IntelligenceCrimeBaseExpGain);
break;
case CONSTANTS.CrimeDrugs:
this.karma -= 0.5;
diff --git a/src/Prestige.js b/src/Prestige.js
index f2c76443a..b132c0312 100644
--- a/src/Prestige.js
+++ b/src/Prestige.js
@@ -166,6 +166,7 @@ function prestigeSourceFile() {
} else {
homeComp.setMaxRam(8);
}
+ homeComp.cpuCores = 1;
AddToAllServers(homeComp);
diff --git a/src/Server.js b/src/Server.js
index 295cb1701..ceef49663 100644
--- a/src/Server.js
+++ b/src/Server.js
@@ -38,6 +38,7 @@ function Server(ip=createRandomIp(), hostname="", organizationName="",
this.runningScripts = []; //Stores RunningScript objects
this.programs = [];
this.messages = [];
+ this.dir = 0; //new Directory(this, null, "");
/* Hacking information (only valid for "foreign" aka non-purchased servers) */
//Skill required to attempt a hack. Whether a hack is successful will be determined
@@ -763,6 +764,34 @@ function PrintAllServers() {
}
}
+// Directory object (folders)
+function Directory(server, parent, name) {
+ this.s = server; //Ref to server
+ this.p = parent; //Ref to parent directory
+ this.c = []; //Subdirs
+ this.n = name;
+ this.d = parent.d + 1; //We'll only have a maximum depth of 3 or something
+ this.scrs = []; //Holds references to the scripts in server.scripts
+ this.pgms = [];
+ this.msgs = [];
+}
+
+Directory.prototype.createSubdir = function(name) {
+ var subdir = new Directory(this.s, this, name);
+
+}
+
+Directory.prototype.getPath = function(name) {
+ var res = [];
+ var i = this;
+ while (i !== null) {
+ res.unshift(i.n, "/");
+ i = i.parent;
+ }
+ res.unshift("/");
+ return res.join("");
+}
+
export {Server, AllServers, getServer, GetServerByHostname, loadAllServers,
AddToAllServers, processSingleServerGrowth, initForeignServers,
prestigeAllServers, prestigeHomeComputer};
diff --git a/src/SourceFile.js b/src/SourceFile.js
index a63cd5808..9997aa6eb 100644
--- a/src/SourceFile.js
+++ b/src/SourceFile.js
@@ -47,10 +47,12 @@ function initSourceFiles() {
SourceFiles["SourceFile8"] = new SourceFile(8);
SourceFiles["SourceFile9"] = new SourceFile(9);
SourceFiles["SourceFile10"] = new SourceFile(10);
- SourceFiles["SourceFile11"] = new SourceFile(11, "This Source-File increases the player's company salary and reputation gain multipliers by:
" +
- "Level 1: 60%
" +
- "Level 2: 90%
" +
- "Level 3: 105%
");
+ SourceFiles["SourceFile11"] = new SourceFile(11, "This Source-File makes it so that company favor increases BOTH the player's salary and reputation gain rate " +
+ "at that company by 1% per favor (rather than just the reputation gain). This Source-File also " +
+ " increases the player's company salary and reputation gain multipliers by:
" +
+ "Level 1: 24%
" +
+ "Level 2: 36%
" +
+ "Level 3: 42%
");
SourceFiles["SourceFile12"] = new SourceFile(12);
}
@@ -126,11 +128,13 @@ function applySourceFile(srcFile) {
Player.hacking_speed_mult *= incMult;
Player.hacking_money_mult *= incMult;
Player.hacking_grow_mult *= incMult;
+ Player.hacking_mult *= incMult;
+ Player.hacking_exp_mult *= incMult;
break;
case 11: //The Big Crash
var mult = 0;
for (var i = 0; i < srcFile.lvl; ++i) {
- mult += (60 / (Math.pow(2, i)));
+ mult += (24 / (Math.pow(2, i)));
}
var incMult = 1 + (mult / 100);
Player.work_money_mult *= incMult;
diff --git a/src/Terminal.js b/src/Terminal.js
index b2930eb0b..577cf8567 100644
--- a/src/Terminal.js
+++ b/src/Terminal.js
@@ -297,7 +297,7 @@ function determineAllPossibilitiesForTabCompletion(input, index=0) {
if (index == -1) {
return ["alias", "analyze", "cat", "check", "clear", "cls", "connect", "free",
"hack", "help", "home", "hostname", "ifconfig", "kill", "killall",
- "ls", "mem", "nano", "ps", "rm", "run", "scan", "scan-analyze",
+ "ls", "lscpu", "mem", "nano", "ps", "rm", "run", "scan", "scan-analyze",
"scp", "sudov", "tail", "theme", "top"].concat(Object.keys(Aliases)).concat(Object.keys(GlobalAliases));
}
@@ -899,6 +899,9 @@ let Terminal = {
case "ls":
Terminal.executeListCommand(commandArray);
break;
+ case "lscpu":
+ post(Player.getCurrentServer().cpuCores + " Core(s)");
+ break;
case "mem":
if (commandArray.length != 2) {
post("Incorrect usage of mem command. usage: mem [scriptname] [-t] [number threads]"); return;