Merge pull request #426 from danielyxie/dev

v0.40.1
This commit is contained in:
danielyxie 2018-08-06 19:31:45 -04:00 committed by GitHub
commit ab51ea94fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 4781 additions and 1187 deletions

1
.gitignore vendored

@ -5,3 +5,4 @@ Netburner.txt
/dist/*.map
/tests/*.map
/tests/*.bundle.*
/tests/*.css

61
css/_mixins.scss Normal file

@ -0,0 +1,61 @@
@mixin animation($property) {
-webkit-animation: $property;
-moz-animation: $property;
-ms-animation: $property;
-o-animation: $property;
animation: $property;
}
@mixin borderRadius($property) {
-webkit-border-radius: $property;
-moz-border-radius: $property;
border-radius: $property;
}
@mixin boxShadow($value) {
-webkit-box-shadow: $value;
-moz-box-shadow: $value;
box-shadow: $value;
}
@mixin keyframes($animationName) {
@-webkit-keyframes #{$animationName} {
$browser: '-webkit-' !global;
@content;
}
@-moz-keyframes #{$animationName} {
$browser: '-moz-' !global;
@content;
}
@-ms-keyframes #{$animationName} {
$browser: '-ms-' !global;
@content;
}
@-o-keyframes #{$animationName} {
$browser: '-o-' !global;
@content;
}
@keyframes #{$animationName} {
$browser: '' !global;
@content;
}
}
@mixin transform($property) {
-webkit-transform: $property;
-moz-transform: $property;
-ms-transform: $property;
-o-transform: $property;
transform: $property;
}
@mixin userSelect($value) {
-webkit-user-select: $value;
-moz-user-select: $value;
-ms-user-select: $value;
user-select: $value;
}

15
css/_reset.scss Normal file

@ -0,0 +1,15 @@
@import "theme";
* {
font-size: $defaultFontSize;
font-family: $fontFamily;
}
*,
*:before,
*:after {
margin: 0;
padding: 0;
box-sizing: border-box;
vertical-align: top;
}

2
css/_theme.scss Normal file

@ -0,0 +1,2 @@
$fontFamily: 'Lucida Console', 'Lucida Sans Unicode', 'Fira Mono', 'Consolas', 'Courier New', Courier, monospace, 'Times New Roman';
$defaultFontSize: 16px;

@ -1,9 +1,13 @@
#bladeburner-container p,
#bladeburner-container pre,
#bladeburner-container a,
#bladeburner-container div,
#bladeburner-container td {
font-size: 13px;
@import "theme";
#bladeburner-container {
a,
div,
p,
pre,
td {
font-size: $defaultFontSize * 0.8125;
}
}
.bladeburner-action {
@ -11,11 +15,11 @@
margin: 7px;
padding: 7px;
white-space: pre-wrap;
}
.bladeburner-action pre {
pre {
white-space: pre-wrap;
}
}
/* Whatever action is currently active */
.bladeburner-active-action {
@ -23,21 +27,25 @@
}
/* Action & Skills panel navigation button */
.bladeburner-nav-button {
%bladeburner-nav-button {
border: 1px solid #fff;
color: #fff;
padding: 2px;
margin: 2px;
padding: 2px;
}
.bladeburner-nav-button:hover {
.bladeburner-nav-button {
@extend %bladeburner-nav-button;
color: #fff;
&:hover {
background-color: #3d4044;
}
}
.bladeburner-nav-button-inactive {
border: 1px solid #fff;
padding: 2px;
margin: 2px;
@extend %bladeburner-nav-button;
text-decoration: none;
background-color: #555;
cursor: default;
@ -76,7 +84,7 @@
margin: 0 !important;
border: 0;
background-color: var(--my-background-color);
font-size: 13px;
font-size: $defaultFontSize * 0.8125;
outline: none;
color: var(--my-font-color);
flex: 1 1 auto;

@ -1,7 +1,10 @@
@import "mixins";
@import "theme";
#cmpy-mgmt-container p,
#cmpy-mgmt-container a,
#cmpy-mgmt-container div {
font-size: 13px;
font-size: $defaultFontSize * 0.8125;
}
/* Header tabs */
@ -118,10 +121,14 @@
margin: 2px;
padding: 6px;
border-radius: 25px;
font-size: "12px";
font-size: $defaultFontSize * 0.75;
color: var(--my-font-color);
}
.cmpy-mgmt-upgrade-div:hover {
background-color: #333;
}
.cmpy-mgmt-advertising-info {
font-size: $defaultFontSize * 0.75;
}

@ -1,3 +1,6 @@
@import "mixins";
@import "theme";
/* interactivetutorial.css */
#interactive-tutorial-wrapper {
position: relative;
@ -15,11 +18,11 @@
overflow: auto; /* Enable scroll if needed */
background-color: #444; /* Fallback color */
color: #fff;
}
#interactive-tutorial-container > strong {
> strong {
background-color: #444;
}
}
#interactive-tutorial-text {
padding: 4px;
@ -31,16 +34,20 @@
#interactive-tutorial-exit,
#interactive-tutorial-next,
#interactive-tutorial-back {
@include borderRadius(12px);
@include boxShadow(1px 1px 3px #000);
color: #aaa;
font-size: 20px;
font-size: $defaultFontSize * 1.25;
font-weight: bold;
-webkit-border-radius: 12px;
-moz-border-radius: 12px;
border-radius: 12px;
-moz-box-shadow: 1px 1px 3px #000;
-webkit-box-shadow: 1px 1px 3px #000;
box-shadow: 1px 1px 3px #000;
background-color: #000;
&:hover,
&:focus {
color: #fff;
text-decoration: none;
cursor: pointer;
}
}
#interactive-tutorial-exit {
@ -55,14 +62,3 @@
#interactive-tutorial-next {
float: right;
}
#interactive-tutorial-exit:hover,
#interactive-tutorial-exit:focus,
#interactive-tutorial-next:hover,
#interactive-tutorial-next:focus,
#interactive-tutorial-back:hover,
#interactive-tutorial-back:focus {
color: #fff;
text-decoration: none;
cursor: pointer;
}

@ -1,148 +0,0 @@
@-webkit-keyframes LOADERSPINNER {
0% { -webkit-transform: translate(-50%, -50%) rotate(0deg); }
100% { -webkit-transform: translate(-50%, -50%) rotate(360deg); }
}
@-moz-keyframes LOADERSPINNER {
0% { -moz-transform: translate(-50%, -50%) rotate(0deg); }
100% { -moz-transform: translate(-50%, -50%) rotate(360deg); }
}
@-ms-keyframes LOADERSPINNER {
0% { -ms-transform: translate(-50%, -50%) rotate(0deg); }
100% { -ms-transform: translate(-50%, -50%) rotate(360deg); }
}
@-o-keyframes LOADERSPINNER {
0% { -o-transform: translate(-50%, -50%) rotate(0deg); }
100% { -o-transform: translate(-50%, -50%) rotate(360deg); }
}
@keyframes LOADERSPINNER {
0% { transform: translate(-50%, -50%) rotate(0deg); }
100% { transform: translate(-50%, -50%) rotate(360deg); }
}
@-webkit-keyframes LOADERLABEL {
0% { opacity: 1.0; -webkit-transform: translate(-50%, -50%) scale(1.0); }
5% { opacity: 0.5; -webkit-transform: translate(-50%, -50%) scale(0.5); }
95% { opacity: 0.5; -webkit-transform: translate(-50%, -50%) scale(0.5); }
100% { opacity: 1.0; -webkit-transform: translate(-50%, -50%) scale(1.0); }
}
@-moz-keyframes LOADERLABEL {
0% { opacity: 1.0; -moz-transform: translate(-50%, -50%) scale(1.0); }
5% { opacity: 0.5; -moz-transform: translate(-50%, -50%) scale(0.5); }
95% { opacity: 0.5; -moz-transform: translate(-50%, -50%) scale(0.5); }
100% { opacity: 1.0; -moz-transform: translate(-50%, -50%) scale(1.0); }
}
@-ms-keyframes LOADERLABEL {
0% { opacity: 1.0; -ms-transform: translate(-50%, -50%) scale(1.0); }
5% { opacity: 0.5; -ms-transform: translate(-50%, -50%) scale(0.5); }
95% { opacity: 0.5; -ms-transform: translate(-50%, -50%) scale(0.5); }
100% { opacity: 1.0; -ms-transform: translate(-50%, -50%) scale(1.0); }
}
@-o-keyframes LOADERLABEL {
0% { opacity: 1.0; -o-transform: translate(-50%, -50%) scale(1.0); }
5% { opacity: 0.5; -o-transform: translate(-50%, -50%) scale(0.5); }
95% { opacity: 0.5; -o-transform: translate(-50%, -50%) scale(0.5); }
100% { opacity: 1.0; -o-transform: translate(-50%, -50%) scale(1.0); }
}
@keyframes LOADERLABEL {
0% { opacity: 1.0; transform: translate(-50%, -50%) scale(1.0); }
5% { opacity: 0.5; transform: translate(-50%, -50%) scale(0.5); }
95% { opacity: 0.5; transform: translate(-50%, -50%) scale(0.5); }
100% { opacity: 1.0; transform: translate(-50%, -50%) scale(1.0); }
}
*, *:before, *:after {
margin: 0;
padding: 0;
box-sizing: border-box;
vertical-align: top;
}
.loaderoverlay {
position: absolute;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 1.0);
}
.loaderoverlay .loaderspinner,
.loaderoverlay .loaderspinner:before,
.loaderoverlay .loaderspinner:after {
border: 20px solid rgba(0, 0, 0, 0);
border-top: 20px solid #ccc;
border-bottom: 20px solid #ccc;
border-radius: 1000px;
position: absolute;
top: 50%;
left: 50%;
}
.loaderoverlay .loaderspinner:before,
.loaderoverlay .loaderspinner:after {
content: "";
}
.loaderoverlay .loaderspinner {
width: 200px;
height: 200px;
-webkit-animation: LOADERSPINNER 5s linear infinite;
-moz-animation: LOADERSPINNER 5s linear infinite;
-ms-animation: LOADERSPINNER 5s linear infinite;
-o-animation: LOADERSPINNER 5s linear infinite;
animation: LOADERSPINNER 5s linear infinite;
}
.loaderoverlay .loaderspinner:before {
width: 160px;
height: 160px;
-webkit-animation: LOADERSPINNER 10s linear infinite;
-moz-animation: LOADERSPINNER 10s linear infinite;
-ms-animation: LOADERSPINNER 10s linear infinite;
-o-animation: LOADERSPINNER 10s linear infinite;
animation: LOADERSPINNER 10s linear infinite;
}
.loaderoverlay .loaderspinner:after {
width: 120px;
height: 120px;
-webkit-animation: LOADERSPINNER 5s linear infinite;
-moz-animation: LOADERSPINNER 5s linear infinite;
-ms-animation: LOADERSPINNER 5s linear infinite;
-o-animation: LOADERSPINNER 5s linear infinite;
animation: LOADERSPINNER 5s linear infinite;
}
.loaderoverlay .loaderlabel {
color: #6f3;
text-transform: uppercase;
font-family: sans-serif;
font-size: 22px;
font-weight: 700;
letter-spacing: 2px;
position: absolute;
top: 50%;
left: 50%;
-webkit-animation: LOADERLABEL 5s linear infinite;
-moz-animation: LOADERLABEL 5s linear infinite;
-ms-animation: LOADERLABEL 5s linear infinite;
-o-animation: LOADERLABEL 5s linear infinite;
animation: LOADERLABEL 5s linear infinite;
}
button[type="button"] {
padding: 0.5rem 1rem;
position: absolute;
z-index: 1;
bottom: 10px;
left: 50%;
-webkit-transform: translateX(-50%);
-moz-transform: translateX(-50%);
-ms-transform: translateX(-50%);
-o-transform: translateX(-50%);
transform: translateX(-50%);
}
/* Customize */
.loaderoverlay {
background: #000;
}
.loaderoverlay .loaderspinner,
.loaderoverlay .loaderspinner:before,
.loaderoverlay .loaderspinner:after {
border-top-color: #6f3 !important;
border-bottom-color: #6f3 !important;
}
.loaderoverlay .loaderlabel {
color: #6f3;
}

94
css/loader.scss Normal file

@ -0,0 +1,94 @@
@import "mixins";
@import "reset";
@import "theme";
@include keyframes(LOADERSPINNER) {
0% {
#{$browser}transform: translate(-50%, -50%) rotate(0deg);
}
100% {
#{$browser}transform: translate(-50%, -50%) rotate(360deg);
}
}
@include keyframes(LOADERLABEL) {
0% {
opacity: 1.0;
#{$browser}transform: translate(-50%, -50%) scale(1.0);
}
5% {
opacity: 0.5;
#{$browser}transform: translate(-50%, -50%) scale(0.5);
}
95% {
opacity: 0.5;
#{$browser}transform: translate(-50%, -50%) scale(0.5);
}
100% {
opacity: 1.0;
#{$browser}transform: translate(-50%, -50%) scale(1.0);
}
}
.loaderoverlay {
$spinnerBoxSize: 200px;
$themeColor: #6f3;
position: absolute;
width: 100%;
height: 100%;
background: #000;
color: $themeColor;
%spinnerBox {
border: 20px solid rgba(0, 0, 0, 0);
border-top-color: $themeColor;
border-bottom-color: $themeColor;
border-radius: 1000px;
position: absolute;
top: 50%;
left: 50%;
}
.loaderspinner:before,
.loaderspinner:after {
content: "";
}
.loaderspinner {
@extend %spinnerBox;
@include animation(LOADERSPINNER 5s linear infinite);
width: $spinnerBoxSize;
height: $spinnerBoxSize;
}
.loaderspinner:before {
@extend %spinnerBox;
@include animation(LOADERSPINNER 10s linear infinite);
width: $spinnerBoxSize * 0.8;
height: $spinnerBoxSize * 0.8;
}
.loaderspinner:after {
@extend %spinnerBox;
@include animation(LOADERSPINNER 5s linear infinite);
width: $spinnerBoxSize * 0.6;
height: $spinnerBoxSize * 0.6;
}
.loaderlabel {
@include animation(LOADERLABEL 5s linear infinite);
text-transform: uppercase;
font-family: sans-serif;
font-size: $defaultFontSize * 1.375;
font-weight: 700;
letter-spacing: 2px;
position: absolute;
top: 50%;
left: 50%;
}
}

@ -1,3 +1,6 @@
@import "mixins";
@import "theme";
/* CSS for different main menu pages, such as character info, script editor, etc (but excluding
terminal which has its own page) */
@ -32,7 +35,7 @@
border: 2px solid var(--my-highlight-color);
z-index: 1;
font-family: 'Lucida Console', 'Lucida Sans Unicode', 'Fira Mono', 'Consolas', 'Courier New', Courier, monospace, 'Times New Roman';
font-family: $fontFamily;
}
.ace_line,
@ -43,7 +46,7 @@
}
.ace_text-input {
font-size: 16px;
font-size: $defaultFontSize;
background-color: transparent;
}
@ -89,6 +92,9 @@
}
#script-editor-filename {
$boxShadowArgs: inset 0 0 8px rgba(0, 0, 0, 0.1), 0 0 16px rgba(0, 0, 0, 0.1);
@include boxShadow($boxShadowArgs);
background-color: #555;
display: inline-block;
float: center;
@ -99,15 +105,6 @@
padding: 2px;
border: 2px solid var(--my-highlight-color);
-webkit-box-shadow:
inset 0 0 8px rgba(0, 0, 0, 0.1),
0 0 16px rgba(0, 0, 0, 0.1);
-moz-box-shadow:
inset 0 0 8px rgba(0, 0, 0, 0.1),
0 0 16px rgba(0, 0, 0, 0.1);
box-shadow:
inset 0 0 8px rgba(0, 0, 0, 0.1),
0 0 16px rgba(0, 0, 0, 0.1);
}
#script-editor-status {
@ -132,7 +129,7 @@
margin-top: 8px;
margin-bottom: 8px;
padding: 2px;
font-size: 12px;
font-size: $defaultFontSize * 0.75;
}
/* Active scripts */
@ -154,7 +151,7 @@
.active-scripts-server-header {
background-color: #444;
font-size: 20px;
font-size: $defaultFontSize * 1.25;
color: #fff;
margin: 6px 6px 0 6px;
padding: 6px;
@ -176,7 +173,7 @@
.active-scripts-server-header:after {
content: '\02795'; /* "plus" sign (+) */
font-size: 13px;
font-size: $defaultFontSize * 0.8125;
color: #fff;
float: right;
margin-left: 5px;
@ -184,7 +181,7 @@
.active-scripts-server-header.active:after {
content: "\2796"; /* "minus" sign (-) */
font-size: 13px;
font-size: $defaultFontSize * 0.8125;
color: #fff;
float: right;
margin-left: 5px;
@ -227,7 +224,7 @@
.active-scripts-script-header:after {
content: '\02795'; /* "plus" sign (+) */
font-size: 13px;
font-size: $defaultFontSize * 0.8125;
color: var(--my-font-color);
float: right;
margin-left: 5px;
@ -235,7 +232,7 @@
.active-scripts-script-header.active:after {
content: "\2796"; /* "minus" sign (-) */
font-size: 13px;
font-size: $defaultFontSize * 0.8125;
color: var(--my-font-color);
float: right;
margin-left: 5px;
@ -260,15 +257,12 @@
}
.active-scripts-button {
@include borderRadius(12px);
@include boxShadow(1px 1px 3px #000);
color: #aaa;
font-size: 16px;
font-size: $defaultFontSize;
font-weight: bold;
-webkit-border-radius: 12px;
-moz-border-radius: 12px;
border-radius: 12px;
-moz-box-shadow: 1px 1px 3px #000;
-webkit-box-shadow: 1px 1px 3px #000;
box-shadow: 1px 1px 3px #000;
margin: 4px;
padding: 4px;
background-color: #000;
@ -323,19 +317,13 @@
}
.hacknet-node {
$boxShadowArgs: inset 0 0 8px rgba(0, 0, 0, 0.1), 0 0 16px rgba(0, 0, 0, 0.1);
@include boxShadow($boxShadowArgs);
margin: 6px;
padding: 6px;
width: 34vw;
border: 2px solid var(--my-highlight-color);
-webkit-box-shadow:
inset 0 0 8px rgba(0, 0, 0, 0.1),
0 0 16px rgba(0, 0, 0, 0.1);
-moz-box-shadow:
inset 0 0 8px rgba(0, 0, 0, 0.1),
0 0 16px rgba(0, 0, 0, 0.1);
box-shadow:
inset 0 0 8px rgba(0, 0, 0, 0.1),
0 0 16px rgba(0, 0, 0, 0.1);
}
.hacknet-node-container {
@ -355,7 +343,7 @@
display: inline-block;
margin: 0 4px; /* Don't want the vertical margin/padding, just left & right */
padding: 0 4px;
width: 48px; /* Four times font-size */
width: $defaultFontSize * 4;
}
.menu-page-text {

@ -1,3 +1,6 @@
@import "mixins";
@import "theme";
/* css for Missions */
/* Hacking missions */
@ -15,11 +18,11 @@
width: 100%;
overflow-y: auto;
padding-right: 10px;
}
.hack-mission-grid::-webkit-scrollbar {
&::-webkit-scrollbar {
display: none;
}
}
.hack-mission-node {
z-index: 5;
@ -27,17 +30,15 @@
align-self: center;
justify-self: center;
display: inline-block;
}
.hack-mission-node p {
p {
@include userSelect(none);
margin-top: 8px;
color: #fff;
font-size: 12px;
font-size: $defaultFontSize * 0.75;
text-align: center;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
}
.hack-mission-player-node {
@ -56,11 +57,9 @@
}
.hack-mission-cpu-node {
@include borderRadius(50%);
width: 100%;
height: 100%;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
border-radius: 50%;
}
.hack-mission-firewall-node {
@ -69,47 +68,37 @@
}
.hack-mission-database-node {
@include transform(skew(20deg));
width: 100%;
height: 90%;
-webkit-transform: skew(20deg);
-moz-transform: skew(20deg);
-o-transform: skew(20deg);
}
.hack-mission-database-node p {
-webkit-transform: skew(-20deg);
-moz-transform: skew(-20deg);
-o-transform: skew(-20deg);
p {
@include transform(skew(-20deg));
@include userSelect(none);
color: #fff;
font-size: 12px;
font-size: $defaultFontSize * 0.75;
margin-top: 8px;
text-align: center;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
}
.hack-mission-transfer-node {
@include transform(skew(-20deg));
width: 100%;
height: 90%;
-webkit-transform: skew(-20deg);
-moz-transform: skew(-20deg);
-o-transform: skew(-20deg);
}
.hack-mission-transfer-node p {
-webkit-transform: skew(20deg);
-moz-transform: skew(20deg);
-o-transform: skew(20deg);
p {
@include transform(skew(20deg));
@include userSelect(none);
color: #fff;
font-size: 12px;
font-size: $defaultFontSize * 0.75;
margin-top: 8px;
text-align: center;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
}
.hack-mission-spam-node,

@ -1,3 +1,6 @@
@import "mixins";
@import "theme";
/* Pop-up boxes */
.popup-box-container {
display: none; /* Hidden by default */
@ -24,7 +27,7 @@
.popup-box-button-inactive {
color: #aaa;
float: right;
font-size: 16px;
font-size: $defaultFontSize;
font-weight: bold;
padding: 2px;
margin: 6px;
@ -74,16 +77,13 @@
}
.dialog-box-close-button {
@include borderRadius(12px);
@include boxShadow(1px 1px 3px #000);
float: right;
color: #aaa;
font-size: 20px;
font-size: $defaultFontSize * 1.25;
font-weight: bold;
-webkit-border-radius: 12px;
-moz-border-radius: 12px;
border-radius: 12px;
-moz-box-shadow: 1px 1px 3px #000;
-webkit-box-shadow: 1px 1px 3px #000;
box-shadow: 1px 1px 3px #000;
}
#log-box-close {
@ -155,18 +155,15 @@
}
#game-options-close-button {
@include borderRadius(12px);
@include boxShadow(1px 1px 3px #000);
color: #aaa;
float: right;
margin: 4px;
padding: 4px;
font-size: 20px;
font-size: $defaultFontSize * 1.25;
font-weight: bold;
-webkit-border-radius: 12px;
-moz-border-radius: 12px;
border-radius: 12px #fff;
-moz-box-shadow: 1px 1px 3px #000;
-webkit-box-shadow: 1px 1px 3px #000;
box-shadow: 1px 1px 3px #000;
}
#game-options-close-button:hover,

@ -1,16 +1,14 @@
@import "mixins";
@import "theme";
@import "reset";
:root{
--my-font-color: #6f3;
--my-background-color: #000;
--my-highlight-color: #fff;
}
* {
margin: 0;
padding: 0;
font-size: 16px;
font-family: 'Lucida Console', 'Lucida Sans Unicode', 'Fira Mono', 'Consolas', 'Courier New', Courier, monospace, 'Times New Roman';
}
body {
background-color: var(--my-background-color);
}
@ -23,7 +21,7 @@ h2,
}
h1 {
font-size: 22px;
font-size: $defaultFontSize * 1.375;
color: var(--my-font-color);
}
@ -41,6 +39,16 @@ span {
padding: 4px;
}
button[type="button"] {
@include transform(translateX(-50%));
padding: 0.5rem 1rem;
position: absolute;
z-index: 1;
bottom: 10px;
left: 50%;
}
#entire-game-container {
background-color: transparent;
}
@ -100,7 +108,7 @@ tr:focus {
/* Plus and minus signs */
.mainmenu-accordion-header:after {
content: '\02795';
font-size: 13px;
font-size: $defaultFontSize * 0.8125;
color: #fff;
float: right;
margin-left: 5px;
@ -127,7 +135,8 @@ tr:focus {
}
/* Make html links ("a" elements) nice looking buttons with this class */
a:link, a:visited {
a:link,
a:visited {
color: #fff;
}
@ -150,9 +159,7 @@ a:link, a:visited {
}
.a-link-button:active {
-webkit-box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.6);
-moz-box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.6);
box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.6);
@include boxShadow(inset 0 1px 4px rgba(0, 0, 0, 0.6));
}
/* Make anchor tags ("a" elements) inactive (not clickable) */
@ -212,7 +219,7 @@ a:link, a:visited {
position: relative;
}
#create-program-notification {
font-size: 10px;
font-size: $defaultFontSize * 0.625;
position: absolute; /* Position the badge within the relatively positioned button */
top: 0;
@ -308,9 +315,7 @@ a:link, a:visited {
}
.help-tip:active {
-webkit-box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.6);
-moz-box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.6);
box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.6);
@include boxShadow(inset 0 1px 4px rgba(0, 0, 0, 0.6));
}
/* Flashing button (Red) */
@ -408,7 +413,7 @@ a:link, a:visited {
}
#status-text {
font-size: 20px;
font-size: $defaultFontSize * 1.25;
color: #fff;
right: 0;
bottom: 0;
@ -428,8 +433,8 @@ a:link, a:visited {
position: absolute; /* Stay in place */
right: 0;
top: 0;
height: 205px; /* Full height */
padding: 5px;
height: auto; /* Full height */
padding: 8px;
border: 2px solid var(--my-highlight-color);
width: 19%;
overflow: auto; /* Enable scroll if needed */
@ -438,27 +443,34 @@ a:link, a:visited {
}
#character-overview-text {
padding: 4px;
margin: 8px;
color: #fff;
background-color: #444;
}
.character-stat-text {
color: #fff;
background-color: #444;
}
.character-stat-cell {
text-align: right;
}
#character-overview-save-button,
#character-overview-options-button {
@include borderRadius(12px);
@include boxShadow(1px 1px 3px #000);
color: #aaa;
font-size: 14px;
font-size: $defaultFontSize * 0.875;
font-weight: bold;
-webkit-border-radius: 12px;
-moz-border-radius: 12px;
border-radius: 12px;
-moz-box-shadow: 1px 1px 3px #000;
-webkit-box-shadow: 1px 1px 3px #000;
box-shadow: 1px 1px 3px #000;
height: 22px;
background-color: #000;
}
.character-quick-options {
padding-top: 5px;
}
#character-overview-save-button:hover,
#character-overview-save-button:focus,
#character-overview-options-button:hover,
@ -485,7 +497,7 @@ a:link, a:visited {
/* Accordion menus (Header with collapsible panel) */
.accordion-header {
background-color: #444;
font-size: 20px;
font-size: $defaultFontSize * 1.25;
color: #fff;
margin: 6px 6px 0 6px;
padding: 6px;
@ -507,7 +519,7 @@ a:link, a:visited {
.accordion-header:after {
content: '\02795'; /* "plus" sign (+) */
font-size: 13px;
font-size: $defaultFontSize * 0.8125;
color: #fff;
float: right;
margin-left: 5px;
@ -515,7 +527,7 @@ a:link, a:visited {
.accordion-header.active:after {
content: "\2796"; /* "minus" sign (-) */
font-size: 13px;
font-size: $defaultFontSize * 0.8125;
color: #fff;
float: right;
margin-left: 5px;
@ -538,3 +550,11 @@ a:link, a:visited {
.accordion-panel ul > li {
background-color: #555;
}
/* override the global <span> styling */
#active-scripts-total-production-active,
#active-scripts-total-prod-aug-total,
#active-scripts-total-prod-aug-avg {
margin: 0;
padding: 0;
}

@ -1,3 +1,5 @@
@import "theme";
#terminal-container {
position: fixed;
margin-left: 10%;
@ -12,7 +14,7 @@
padding-left: 10px;
height: auto;
width: 70%;
font-size: 16px;
font-size: $defaultFontSize;
overflow: auto;
overflow-y: scroll;
background-color: var(--my-background-color);
@ -31,7 +33,7 @@
margin: 0 !important;
border: 0;
background-color: var(--my-background-color);
font-size: 16px;
font-size: $defaultFontSize;
outline: none;
color: var(--my-font-color);
}

@ -1,3 +1,6 @@
@import "mixins";
@import "theme";
/* Both Work in progress and BitNode stuff */
.generic-fullscreen-container {
color: var(--my-font-color);
@ -16,19 +19,16 @@
}
#work-in-progress-cancel-button {
@include borderRadius(12px);
@include boxShadow(1px 1px 3px #000);
color: #aaa;
float: left;
font-size: 20px;
font-size: $defaultFontSize * 1.25;
font-weight: bold;
-webkit-border-radius: 12px;
-moz-border-radius: 12px;
margin: 10px;
padding: 5px;
border-radius: 12px;
border: 3px solid #fff;
-moz-box-shadow: 1px 1px 3px #000;
-webkit-box-shadow: 1px 1px 3px #000;
box-shadow: 1px 1px 3px #000;
}
#work-in-progress-cancel-button:hover,

File diff suppressed because one or more lines are too long

1864
dist/engine.css vendored Normal file

File diff suppressed because it is too large Load Diff

100
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

@ -3,6 +3,23 @@
Changelog
=========
v0.40.1 - 8/5/2018 - Community Update
-------------------------------------
* Added getPurchasedServerCost() Netscript function (by kopelli)
* Added getFavorToDonate() Netscript function (by hydroflame)
* Added getFactionFavorGain() and getCompanyFavorGain() Singularity functions (by hydroflame)
* Accumulated 'bonus' time in Bladeburner is now displayed in the UI (by hydroflame)
* The Red Pill can now be purchased with negative money (since its supposed to be free) (by hydroflame)
* Cranial Signal Processor Augmentations now have the previous generation as a prerequisite. i.e. Cranial Signal Processor - Gen II requires Gen I (by Kline-)
* Terminal now supports semicolon usage (end of command). This allows chaining multiple Terminal commands (by hydroflame)
* Bladeburner Raid operations can no longer be performed if your estimate of Synthoid communities is zero (by hydroflame)
* The difficulty of BN-12 now scales faster (by hydroflame)
* Active Scripts UI now shows a RAM Usage bar for each server (by kopelli)
* Bug Fix: Corrected terminal timestamp format (by kopelli)
* Bug Fix: NetscriptJS scripts should now die properly if they don't have a 'main' function (by hydroflame)
* Bug Fix: write(), read(), and tryWrite() Netscript functions should now work properly for writing Arrays/objects to Netscript Ports
* Various minor UI/QOL fixes by hydroflame, kopelli, and Kline-
v0.40.0 - 7/28/2018
-------------------
* **WARNING: This update makes some significant changes to Netscript and therefore you may need to make some changes to your scripts. See** `this post <https://www.reddit.com/r/Bitburner/comments/9252j4/psa_netscript_10_changes_in_next_version_v0400/>`_ **this post for details**

@ -670,6 +670,21 @@ purchaseHacknetNode
end of the Hacknet Node's name (e.g The Hacknet Node named 'hacknet-node-4' will have an index of 4). If the player cannot afford
to purchase a new Hacknet Node then the function will return false.
getPurchasedServerCost
^^^^^^^^^^^^^^^^^^^^^^
.. js:function:: getPurchasedServerCost(ram)
:param number ram: Amount of RAM of a potential purchased server. Must be a power of 2 (2, 4, 8, 16, etc.). Maximum value of 1048576 (2^20)
Returns the cost to purchase a server with the specified amount of *ram*.
Examples::
for (i = 1; i <= 20; i++) {
tprint(i + " -- " + getPurchasedServerCost(Math.pow(2, i)));
}
purchaseServer
^^^^^^^^^^^^^^

@ -312,6 +312,18 @@ getCompanyFavor
This function will return the amount of favor you have at the specified company.
If the company passed in as an argument is invalid, -1 will be returned.
getCompanyFavorGain
-------------------
.. js:function:: getCompanyFavorGain(companyName)
:param string companyName: Name of the company. CASE-SENSITIVE
If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.
This function will return the amount of favor you will gain for the specified company
when you reset by installing Augmentations.
checkFactionInvitations
-----------------------
@ -387,6 +399,17 @@ getFactionFavor
This function returns the amount of favor you have for the specified faction.
getFactionFavorGain
-------------------
.. js:function:: getFactionFavorGain(factionName)
:param string factionName: Name of faction. CASE-SENSITIVE
If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.
This function returns the amount of favor you will gain for the specified faction when you reset by installing Augmentations.
createProgram
-------------

@ -14,16 +14,7 @@
<meta name="msapplication-TileColor" content="#000000">
<meta name="msapplication-config" content="dist/browserconfig.xml">
<meta name="theme-color" content="#ffffff">
<link rel="stylesheet" type="text/css" href="css/styles.css" />
<link rel="stylesheet" type="text/css" href="css/terminal.css" />
<link rel="stylesheet" type="text/css" href="css/menupages.css" />
<link rel="stylesheet" type="text/css" href="css/workinprogress.css" />
<link rel="stylesheet" type="text/css" href="css/popupboxes.css" />
<link rel="stylesheet" type="text/css" href="css/interactivetutorial.css" />
<link rel="stylesheet" type="text/css" href="css/loader.css" />
<link rel="stylesheet" type="text/css" href="css/missions.css" />
<link rel="stylesheet" type="text/css" href="css/companymanagement.css" />
<link rel="stylesheet" type="text/css" href="css/bladeburner.css" />
<link rel="stylesheet" type="text/css" href="dist/engine.css" />
<!-- Google Analytics -->
<script>
@ -196,7 +187,10 @@
<p id="active-scripts-text"> This page displays a list of all of your scripts that are currently running across every machine. It also
provides information about each script's production. The scripts are categorized by the hostname of the servers on which
they are running. </p>
<p id="active-scripts-total-prod"> Total online production rate: </p>
<p id="active-scripts-total-prod">Total online production of
Active scripts: <span id="active-scripts-total-production-active">$0.000</span> / sec<br />
Total online production since last Aug installation: <span id="active-scripts-total-prod-aug-total">$0.000</span>
(<span id="active-scripts-total-prod-aug-avg">$0.000</span> / sec)</p>
<ul class="active-scripts-list" id="active-scripts-list" style="list-style: none;">
</ul>
</div>
@ -497,24 +491,24 @@
<!-- dev menu -->
<div id="dev-menu-container" class="generic-menupage-container">
<p id='dev-menu-text'>If you see this menu you can pretty much break the game. It's recommended that you use this menu only to setup a save file appropriate to test a new feature or bug fix.</p>
<p id="dev-menu-text">If you see this menu you can pretty much break the game. It's recommended that you use this menu only to setup a save file appropriate to test a new feature or bug fix.</p>
<p id='dev-menu-text'>Generic</p>
<p id="dev-menu-text">Generic</p>
<a id="dev-need-money" class="a-link-button">Add $1000t</a>
<a id="dev-need-ram" class="a-link-button">Double home RAM</a>
<p id='dev-menu-text'>Augmentation related: </p>
<p id="dev-menu-text">Augmentation related: </p>
<!-- gets populated with the list of all augments -->
<select id="dev-menu-aug-dropdown" class="dropdown"></select>
<a id="dev-add-aug" class="a-link-button tooltip">Queue Augmentation<span class="tooltiptext">May require save + reload</span></a>
<input id="dev-sf-n" type="number" class="text-input" placeholder="SourceFile-N"><input id="dev-sf-lvl" type="number" class="text-input" placeholder="SourceFile-Lvl"><a id="dev-add-source-file" class="a-link-button tooltip"> Add/Remove source file <span class="tooltiptext">If Lvl == 0 the sf will be removed, calling it with another level will replace your current source file. You CAN set a source file higher than it's maximum level.</span></a>
<p id='dev-menu-text'>Faction related: </p>
<p id="dev-menu-text">Faction related: </p>
<select id="dev-menu-faction-dropdown" class="dropdown"></select>
<a id="dev-add-faction" class="a-link-button tooltip">Receive invite<span class="tooltiptext">May require save + reload</span></a>
<p id='dev-menu-text'>Program related: </p>
<p id="dev-menu-text">Program related: </p>
<select id="dev-menu-connect-dropdown" class="dropdown"></select>
<a id="dev-connect" class="a-link-button tooltip">Connect<span class="tooltiptext">Connect to the target server.</span></a>
@ -523,12 +517,12 @@
<a id="dev-bit-flume" class="a-link-button tooltip">Trigger BitFlume<span class="tooltiptext">Quick escape to change BN, does not give SFs</span></a>
<p id='dev-menu-text'>Server related: </p>
<p id="dev-menu-text">Server related: </p>
<a id="dev-open-all" class="a-link-button tooltip">NUKE + ports all servers<span class="tooltiptext">Opens all ports, nukes all servers, gains root access to everything (still need the appropriate hacking level)</span></a>
<a id="dev-min-security" class="a-link-button tooltip">minimize all servers security<span class="tooltiptext">All servers security will be set to their minimum security</span></a>
<a id="dev-max-money" class="a-link-button tooltip">maximize all servers money<span class="tooltiptext">Set all servers available money to maximum for that server</span></a>
<p id='dev-menu-text'>Exp/stats related: </p>
<p id="dev-menu-text">Exp/stats related: </p>
<input id="dev-hacking-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-hacking" class="a-link-button tooltip">add hacking exp<span class="tooltiptext">Add that many hacking experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-strength-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
@ -650,7 +644,7 @@
<a id="location-slums-heist" class="a-link-button tooltip"> Heist </a>
<!-- City Hall -->
<a id="location-cityhall-create-corporation" class='a-link-button'>Create a Corporation</a>
<a id="location-cityhall-create-corporation" class="a-link-button">Create a Corporation</a>
<!-- Bladeburner@NSA -->
<a id="location-nsa-bladeburner" class="a-link-button">Bladeburner Division</a>
@ -696,7 +690,7 @@
you 'reset' by installing Augmentations.
</p>
<a id="stock-market-buy-tix-api" class="a-link-button-inactive">Buy Trade Information eXchange (TIX) API Access</a>
<a id="stock-market-investopedia" class='a-link-button'>Investopedia</a>
<a id="stock-market-investopedia" class="a-link-button">Investopedia</a>
<p id="stock-market-commission"> </p>
<a id="stock-market-mode" class="a-link-button tooltip"></a>
<a id="stock-market-expand-tickers" class="a-link-button tooltip">Expand tickers</a>
@ -790,11 +784,43 @@
<!-- Character Overview Screen -->
<div id="character-overview-wrapper">
<div id="character-overview-container">
<p id="character-overview-text"> </p>
<div id="character-overview-text">
<table>
<tr id="character-hp-wrapper">
<td>Hp:</td><td id="character-hp-text" class="character-stat-cell"></td>
</tr>
<tr id="character-money-wrapper">
<td>Money:&nbsp;</td><td id="character-money-text" class="character-stat-cell"></td>
</tr>
<tr id="character-hack-wrapper">
<td>Hack:&nbsp;</td><td id="character-hack-text" class="character-stat-cell"></td>
</tr>
<tr id="character-str-wrapper">
<td>Str:&nbsp;</td><td id="character-str-text" class="character-stat-cell"></td>
</tr>
<tr id="character-def-wrapper">
<td>Def:&nbsp;</td><td id="character-def-text" class="character-stat-cell"></td>
</tr>
<tr id="character-dex-wrapper">
<td>Dex:&nbsp;</td><td id="character-dex-text" class="character-stat-cell"></td>
</tr>
<tr id="character-agi-wrapper">
<td>Agi:&nbsp;</td><td id="character-agi-text" class="character-stat-cell"></td>
</tr>
<tr id="character-cha-wrapper">
<td>Cha:&nbsp;</td><td id="character-cha-text" class="character-stat-cell"></td>
</tr>
<tr id="character-int-wrapper">
<td>Int:&nbsp;</td><td id="character-int-text" class="character-stat-cell"></td>
</tr>
<table>
</div>
<div class="character-quick-options">
<span id="character-overview-save-button"> Save Game </span>
<span id="character-overview-options-button"> Options </span>
</div>
</div>
</div>
<!-- Status text -->
<div id="status-text-container">

@ -72,6 +72,7 @@ let NetscriptFunctions =
"serverExists|fileExists|isRunning|" +
"deleteServer|getPurchasedServers|" +
"getPurchasedServerLimit|getPurchasedServerMaxRam|" +
"getPurchasedServerCost|" +
"purchaseServer|round|write|read|peek|clear|rm|getPortHandle|" +
"scriptRunning|scriptKill|getScriptName|getScriptRam|" +
"getHackTime|getGrowTime|getWeakenTime|getScriptIncome|getScriptExpGain|" +
@ -80,6 +81,7 @@ let NetscriptFunctions =
"gymWorkout|travelToCity|purchaseTor|purchaseProgram|upgradeHomeRam|" +
"getUpgradeHomeRamCost|workForCompany|applyToCompany|getCompanyRep|" +
"getCompanyFavor|stopAction|getFactionFavor|" +
"getFavorToDonate|getFactionFavorGain|getCompanyFavorGain|" +
"checkFactionInvitations|joinFaction|workForFaction|getFactionRep|" +
"createProgram|commitCrime|getCrimeChance|getOwnedAugmentations|" +
"getOwnedSourceFiles|getAugmentationsFromFaction|" +

1918
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -52,11 +52,14 @@
"less": "^3.0.4",
"less-loader": "^4.1.0",
"lodash": "^4.17.10",
"mini-css-extract-plugin": "^0.4.1",
"mkdirp": "^0.5.1",
"mocha": "^3.2.0",
"mocha-lcov-reporter": "^1.0.0",
"node-sass": "^4.9.2",
"nsp": "^3.2.1",
"raw-loader": "~0.5.0",
"sass-loader": "^7.0.3",
"script-loader": "~0.7.0",
"should": "^11.1.1",
"simple-git": "^1.96.0",

@ -1,6 +1,5 @@
import {Engine} from "./engine";
import {workerScripts,
addWorkerScript,
killWorkerScript} from "./NetscriptWorker";
import {Player} from "./Player";
import {getServer} from "./Server";
@ -8,12 +7,15 @@ 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 numeral from "numeral/min/numeral.min";
import {formatNumber} from "../utils/StringHelperFunctions";
import {removeChildrenFromElement} from "../utils/uiHelpers/removeChildrenFromElement";
import {removeElement} from "../utils/uiHelpers/removeElement";
import {roundToTwo} from "../utils/helpers/roundToTwo";
/* {
* serverName: {
@ -28,12 +30,39 @@ import {removeElement} from "../utils/uiHelpers/removeElement";
let ActiveScriptsUI = {};
let ActiveScriptsTasks = []; //Sequentially schedule the creation/deletion of UI elements
const getHeaderHtml = (server) => {
// TODO: calculate the longest hostname length rather than hard coding it
const longestHostnameLength = 18;
const paddedName = `${server.hostname}${" ".repeat(longestHostnameLength)}`.slice(0, Math.max(server.hostname.length, longestHostnameLength));
const barOptions = {
progress: server.ramUsed / server.maxRam,
totalTicks: 30
};
return `${paddedName} ${createProgressBarText(barOptions)}`.replace(/\s/g, '&nbsp;');
};
const updateHeaderHtml = (server) => {
const accordion = ActiveScriptsUI[server.hostname];
if (accordion === null || accordion === undefined) {
return;
}
// convert it to a string, as that's how it's stored it will come out of the data attributes
const ramPercentage = '' + roundToTwo(server.ramUsed / server.maxRam);
if (accordion.header.dataset.ramPercentage !== ramPercentage) {
accordion.header.dataset.ramPercentage = ramPercentage;
accordion.header.innerHTML = getHeaderHtml(server);
}
}
function createActiveScriptsServerPanel(server) {
let hostname = server.hostname;
var activeScriptsList = document.getElementById("active-scripts-list");
let res = createAccordionElement({hdrText:hostname});
let res = createAccordionElement({
hdrText: getHeaderHtml(server)
});
let li = res[0];
var hdr = res[1];
let panel = res[2];
@ -116,19 +145,26 @@ function addActiveScriptsItem(workerscript) {
"Args: " + arrayToString(workerscript.args)
}));
var panelText = createElement("p", {
innerText:"Loading...", fontSize:"14px",
innerText: "Loading...",
fontSize: "14px",
});
panel.appendChild(panelText);
panel.appendChild(createElement("br"));
panel.appendChild(createElement("span", {
innerText:"Log", class:"active-scripts-button", margin:"4px", padding:"4px",
innerText: "Log",
class: "active-scripts-button",
margin: "4px",
padding: "4px",
clickListener: () => {
logBoxCreate(workerscript.scriptRef);
return false;
}
}));
panel.appendChild(createElement("span", {
innerText:"Kill Script", class:"active-scripts-button", margin:"4px", padding:"4px",
innerText: "Kill Script",
class: "active-scripts-button",
margin: "4px",
padding: "4px",
clickListener: () => {
killWorkerScript(workerscript.scriptRef, workerscript.scriptRef.scriptRef.server);
dialogBoxCreate("Killing script, may take a few minutes to complete...");
@ -205,11 +241,10 @@ function updateActiveScriptsItems(maxTasks=150) {
exceptionAlert(e);
}
}
document.getElementById("active-scripts-total-prod").innerHTML =
"Total online production of Active Scripts: " + numeral(total).format('$0.000a') + " / sec<br>" +
"Total online production since last Aug installation: " +
numeral(Player.scriptProdSinceLastAug).format('$0.000a') + " (" +
numeral(Player.scriptProdSinceLastAug / (Player.playtimeSinceLastAug/1000)).format('$0.000a') + " / sec)";
getElementById("active-scripts-total-production-active").innerText = numeral(total).format('$0.000a');
getElementById("active-scripts-total-prod-aug-total").innerText = numeral(Player.scriptProdSinceLastAug).format('$0.000a');
getElementById("active-scripts-total-prod-aug-avg").innerText = numeral(Player.scriptProdSinceLastAug / (Player.playtimeSinceLastAug/1000)).format('$0.000a');
return total;
}
@ -225,6 +260,8 @@ function updateActiveScriptsItemContent(workerscript) {
return; //Hasn't been created yet. We'll skip it
}
updateHeaderHtml(server);
var itemNameArray = ["active", "scripts", server.hostname, workerscript.name];
for (var i = 0; i < workerscript.args.length; ++i) {
itemNameArray.push(String(workerscript.args[i]));
@ -252,6 +289,7 @@ function updateActiveScriptsText(workerscript, item, itemName) {
return;
}
updateHeaderHtml(server);
var onlineMps = workerscript.scriptRef.onlineMoneyMade / workerscript.scriptRef.onlineRunningTime;
//Only update if the item is visible

@ -209,7 +209,8 @@ function initAugmentations() {
var HemoRecirculator = new Augmentation({
name:AugmentationNames.HemoRecirculator, moneyCost: 9e6, repCost:4e3,
info:"A heart implant that greatly increases the body's ability to effectively use and pump " +
"blood. <br><br> This augmentation increases all of the player's combat stats by 8%."
"blood.<br><br>" +
"This augmentation increases all of the player's combat stats by 8%."
});
HemoRecirculator.addToFactions(["Tetrads", "The Dark Army", "The Syndicate"]);
if (augmentationExists(AugmentationNames.HemoRecirculator)) {
@ -234,8 +235,8 @@ function initAugmentations() {
var Targeting2 = new Augmentation({
name:AugmentationNames.Targeting2, moneyCost:8.5e6, repCost:3.5e3,
info:"This is an upgrade of the Augmented Targeting I cranial implant, which is capable of augmenting reality " +
"and enhances the user's balance and hand-eye coordination. <br><br>This upgrade increases the player's dexterity " +
"by an additional 20%.",
"and enhances the user's balance and hand-eye coordination.<br><br>" +
"This augmentation increases the player's dexterity by 20%.",
prereqs:[AugmentationNames.Targeting1]
});
Targeting2.addToFactions(["The Dark Army", "The Syndicate", "Sector-12", "Volhaven", "Ishima",
@ -248,8 +249,8 @@ function initAugmentations() {
var Targeting3 = new Augmentation({
name:AugmentationNames.Targeting3, moneyCost:23e6, repCost:11e3,
info:"This is an upgrade of the Augmented Targeting II cranial implant, which is capable of augmenting reality " +
"and enhances the user's balance and hand-eye coordination. <br><br>This upgrade increases the player's dexterity " +
"by an additional 30%.",
"and enhances the user's balance and hand-eye coordination.<br><br>" +
"This augmentation increases the player's dexterity by 30%.",
prereqs:[AugmentationNames.Targeting2]
});
Targeting3.addToFactions(["The Dark Army", "The Syndicate", "OmniTek Incorporated",
@ -262,8 +263,8 @@ function initAugmentations() {
var SyntheticHeart = new Augmentation({
name:AugmentationNames.SyntheticHeart, moneyCost:575e6, repCost:300e3,
info:"This advanced artificial heart, created from plasteel and graphene, is capable of pumping more blood " +
"at much higher efficiencies than a normal human heart.<br><br> This augmentation increases the player's agility " +
"and strength by 50%"
"at much higher efficiencies than a normal human heart.<br><br>" +
"This augmentation increases the player's agility and strength by 50%."
});
SyntheticHeart.addToFactions(["KuaiGong International", "Fulcrum Secret Technologies", "Speakers for the Dead",
"NWO", "The Covenant", "Daedalus", "Illuminati"]);
@ -276,8 +277,8 @@ function initAugmentations() {
name:AugmentationNames.SynfibrilMuscle, repCost:175e3, moneyCost:225e6,
info:"The myofibrils in human muscles are injected with special chemicals that react with the proteins inside " +
"the myofibrils, altering their underlying structure. The end result is muscles that are stronger and more elastic. " +
"Scientists have named these artificially enhanced units 'synfibrils'.<br><br> This augmentation increases the player's " +
"strength and defense by 30%."
"Scientists have named these artificially enhanced units 'synfibrils'.<br><br>" +
"This augmentation increases the player's strength and defense by 30%."
});
SynfibrilMuscle.addToFactions(["KuaiGong International", "Fulcrum Secret Technologies", "Speakers for the Dead",
"NWO", "The Covenant", "Daedalus", "Illuminati", "Blade Industries"]);
@ -302,7 +303,8 @@ function initAugmentations() {
var CombatRib2 = new Augmentation({
name:AugmentationNames.CombatRib2, repCost:7.5e3, moneyCost:13e6,
info:"This is an upgrade to the Combat Rib I augmentation, and is capable of releasing even more potent combat-enhancing " +
"drugs into the bloodstream.<br><br>This upgrade increases the player's strength and defense by an additional 14%.",
"drugs into the bloodstream.<br><br>" +
"This augmentation increases the player's strength and defense by 14%.",
prereqs:[AugmentationNames.CombatRib1]
});
CombatRib2.addToFactions(["The Dark Army", "The Syndicate", "Sector-12", "Volhaven", "Ishima",
@ -315,8 +317,9 @@ function initAugmentations() {
var CombatRib3 = new Augmentation({
name:AugmentationNames.CombatRib3, repCost:14e3, moneyCost:24e6,
info:"This is an upgrade to the Combat Rib II augmentation, and is capable of releasing even more potent combat-enhancing " +
"drugs into the bloodstream<br><br>. This upgrade increases the player's strength and defense by an additional 18%.",
prereqs:[AugmentationNames.CombatRib2],
"drugs into the bloodstream<br><br>." +
"This augmentation increases the player's strength and defense by 18%.",
prereqs:[AugmentationNames.CombatRib2]
});
CombatRib3.addToFactions(["The Dark Army", "The Syndicate", "OmniTek Incorporated",
"KuaiGong International", "Blade Industries", "The Covenant"]);
@ -399,7 +402,7 @@ function initAugmentations() {
info:"An upgrade to the Bionic Spine augmentation. It fuses the implant with an advanced graphene " +
"material to make it much stronger and lighter.<br><br>" +
"This augmentation increases all of the player's combat stats by 60%.",
prereqs:[AugmentationNames.BionicSpine],
prereqs:[AugmentationNames.BionicSpine]
});
GrapheneBionicSpine.addToFactions(["Fulcrum Secret Technologies", "ECorp"]);
if (augmentationExists(AugmentationNames.GrapheneBionicSpine)) {
@ -423,8 +426,8 @@ function initAugmentations() {
name:AugmentationNames.GrapheneBionicLegs, repCost:300e3, moneyCost:900e6,
info:"An upgrade to the Bionic Legs augmentation. It fuses the implant with an advanced graphene " +
"material to make it much stronger and lighter.<br><br>" +
"This augmentation increases the player's agility by an additional 150%.",
prereqs:[AugmentationNames.BionicLegs],
"This augmentation increases the player's agility by 150%.",
prereqs:[AugmentationNames.BionicLegs]
});
GrapheneBionicLegs.addToFactions(["MegaCorp", "ECorp", "Fulcrum Secret Technologies"]);
if (augmentationExists(AugmentationNames.GrapheneBionicLegs)) {
@ -452,7 +455,7 @@ function initAugmentations() {
info:"TITN is a series of viruses that targets and alters the sequences of human DNA in genes that " +
"control personality. The TITN-41 strain alters these genes so that the subject becomes more " +
"outgoing and socialable.<br><br>" +
"This augmentation increases the player's charisma and charisma experience gain rate by 15%"
"This augmentation increases the player's charisma and charisma experience gain rate by 15%."
});
TITN41Injection.addToFactions(["Silhouette"]);
if (augmentationExists(AugmentationNames.TITN41Injection)) {
@ -480,7 +483,8 @@ function initAugmentations() {
var BitWire = new Augmentation({
name:AugmentationNames.BitWire, repCost:1500, moneyCost:2e6,
info: "A small brain implant embedded in the cerebrum. This regulates and improves the brain's computing " +
"capabilities. <br><br> This augmentation increases the player's hacking skill by 5%"
"capabilities.<br><br>" +
"This augmentation increases the player's hacking skill by 5%."
});
BitWire.addToFactions(["CyberSec", "NiteSec"]);
if (augmentationExists(AugmentationNames.BitWire)) {
@ -496,9 +500,9 @@ function initAugmentations() {
"nanoprocessors are programmed to perform computations much faster than organic neurons, " +
"allowing its user to solve much more complex problems at a much faster rate.<br><br>" +
"This augmentation:<br>" +
"Increases the player's hacking speed by 3%<br>" +
"Increases the amount of money the player's gains from hacking by 15%<br>" +
"Increases the player's hacking skill by 12%"
"Increases the player's hacking speed by 3%.<br>" +
"Increases the amount of money the player's gains from hacking by 15%.<br>" +
"Increases the player's hacking skill by 12%."
});
ArtificialBioNeuralNetwork.addToFactions(["BitRunners", "Fulcrum Secret Technologies"]);
if (augmentationExists(AugmentationNames.ArtificialBioNeuralNetwork)) {
@ -512,8 +516,8 @@ function initAugmentations() {
"otherwise known as the strengthening of synapses. This results in a enhanced cognitive abilities.<br><br>" +
"This augmentation:<br>" +
"Increases the player's hacking speed by 2% <br>" +
"Increases the player's hacking chance by 5%<br>" +
"Increases the player's hacking experience gain rate by 5%"
"Increases the player's hacking chance by 5%.<br>" +
"Increases the player's hacking experience gain rate by 5%."
});
ArtificialSynapticPotentiation.addToFactions(["The Black Hand", "NiteSec"]);
if (augmentationExists(AugmentationNames.ArtificialSynapticPotentiation)) {
@ -528,9 +532,9 @@ function initAugmentations() {
"system. These myelin sheaths can propogate neuro-signals much faster than their organic " +
"counterparts, leading to greater processing speeds and better brain function.<br><br>" +
"This augmentation:<br>" +
"Increases the player's hacking speed by 3%<br>" +
"Increases the player's hacking skill by 8%<br>" +
"Increases the player's hacking experience gain rate by 10%"
"Increases the player's hacking speed by 3%.<br>" +
"Increases the player's hacking skill by 8%.<br>" +
"Increases the player's hacking experience gain rate by 10%."
});
EnhancedMyelinSheathing.addToFactions(["Fulcrum Secret Technologies", "BitRunners", "The Black Hand"]);
if (augmentationExists(AugmentationNames.EnhancedMyelinSheathing)) {
@ -567,7 +571,7 @@ function initAugmentations() {
info:"A brain implant that provides an interface for direct, wireless communication between a computer's main " +
"memory and the mind. This implant allows the user to not only access a computer's memory, but also alter " +
"and delete it.<br><br>" +
"This augmentation increases the amount of money the player gains from hacking by 25%"
"This augmentation increases the amount of money the player gains from hacking by 25%."
});
DataJack.addToFactions(["BitRunners", "The Black Hand", "NiteSec", "Chongqing", "New Tokyo"]);
if (augmentationExists(AugmentationNames.DataJack)) {
@ -582,7 +586,7 @@ function initAugmentations() {
"processing all of the traffic on that network. By itself, the Embedded Netburner Module does " +
"not do much, but a variety of very powerful upgrades can be installed that allow you to fully " +
"control the traffic on a network.<br><br>" +
"This augmentation increases the player's hacking skill by 8%"
"This augmentation increases the player's hacking skill by 8%."
});
ENM.addToFactions(["BitRunners", "The Black Hand", "NiteSec", "ECorp", "MegaCorp",
"Fulcrum Secret Technologies", "NWO", "Blade Industries"]);
@ -596,11 +600,11 @@ function initAugmentations() {
info:"The Core library is an implant that upgrades the firmware of the Embedded Netburner Module. " +
"This upgrade allows the Embedded Netburner Module to generate its own data on a network.<br><br>" +
"This augmentation:<br>" +
"Increases the player's hacking speed by 3%<br>" +
"Increases the amount of money the player gains from hacking by 10%<br>" +
"Increases the player's chance of successfully performing a hack by 3%<br>" +
"Increases the player's hacking experience gain rate by 7%<br>" +
"Increases the player's hacking skill by 7%",
"Increases the player's hacking speed by 3%.<br>" +
"Increases the amount of money the player gains from hacking by 10%.<br>" +
"Increases the player's chance of successfully performing a hack by 3%.<br>" +
"Increases the player's hacking experience gain rate by 7%.<br>" +
"Increases the player's hacking skill by 7%.",
prereqs:[AugmentationNames.ENM]
});
ENMCore.addToFactions(["BitRunners", "The Black Hand", "ECorp", "MegaCorp",
@ -617,11 +621,11 @@ function initAugmentations() {
"a network by re-routing traffic, spoofing IP addresses, or altering the data inside network " +
"packets.<br><br>" +
"This augmentation:<br>" +
"Increases the player's hacking speed by 5%<br>" +
"Increases the amount of money the player gains from hacking by 30%<br>" +
"Increases the player's chance of successfully performing a hack by 5%<br>" +
"Increases the player's hacking experience gain rate by 15%<br>" +
"Increases the player's hacking skill by 8%",
"Increases the player's hacking speed by 5%.<br>" +
"Increases the amount of money the player gains from hacking by 30%.<br>" +
"Increases the player's chance of successfully performing a hack by 5%.<br>" +
"Increases the player's hacking experience gain rate by 15%.<br>" +
"Increases the player's hacking skill by 8%.",
prereqs:[AugmentationNames.ENMCore]
});
ENMCoreV2.addToFactions(["BitRunners", "ECorp", "MegaCorp", "Fulcrum Secret Technologies", "NWO",
@ -637,12 +641,12 @@ function initAugmentations() {
"This upgraded firmware allows the Embedded Netburner Module to seamlessly inject code into " +
"any device on a network.<br><br>" +
"This augmentation:<br>" +
"Increases the player's hacking speed by 5%<br>" +
"Increases the amount of money the player gains from hacking by 40%<br>" +
"Increases the player's chance of successfully performing a hack by 10%<br>" +
"Increases the player's hacking experience gain rate by 25%<br>" +
"Increases the player's hacking skill by 10%",
prereqs:[AugmentationNames.ENMCoreV2],
"Increases the player's hacking speed by 5%.<br>" +
"Increases the amount of money the player gains from hacking by 40%.<br>" +
"Increases the player's chance of successfully performing a hack by 10%.<br>" +
"Increases the player's hacking experience gain rate by 25%.<br>" +
"Increases the player's hacking skill by 10%.",
prereqs:[AugmentationNames.ENMCoreV2]
});
ENMCoreV3.addToFactions(["ECorp", "MegaCorp", "Fulcrum Secret Technologies", "NWO",
"Daedalus", "The Covenant", "Illuminati"]);
@ -656,7 +660,7 @@ function initAugmentations() {
info:"Installs the Analyze Engine for the Embedded Netburner Module, which is a CPU cluster " +
"that vastly outperforms the Netburner Module's native single-core processor.<br><br>" +
"This augmentation increases the player's hacking speed by 10%.",
prereqs:[AugmentationNames.ENM],
prereqs:[AugmentationNames.ENM]
});
ENMAnalyzeEngine.addToFactions(["ECorp", "MegaCorp", "Fulcrum Secret Technologies", "NWO",
"Daedalus", "The Covenant", "Illuminati"]);
@ -671,9 +675,9 @@ function initAugmentations() {
"Embedded Netburner Module. This allows the Module to send and receive data " +
"directly to and from the main memory of devices on a network.<br><br>" +
"This augmentation:<br>" +
"Increases the amount of money the player gains from hacking by 40%<br>" +
"Increases the player's chance of successfully performing a hack by 20%",
prereqs:[AugmentationNames.ENM],
"Increases the amount of money the player gains from hacking by 40%.<br>" +
"Increases the player's chance of successfully performing a hack by 20%.",
prereqs:[AugmentationNames.ENM]
});
ENMDMA.addToFactions(["ECorp", "MegaCorp", "Fulcrum Secret Technologies", "NWO",
"Daedalus", "The Covenant", "Illuminati"]);
@ -685,11 +689,11 @@ function initAugmentations() {
var Neuralstimulator = new Augmentation({
name:AugmentationNames.Neuralstimulator, repCost:20e3, moneyCost:600e6,
info:"A cranial implant that intelligently stimulates certain areas of the brain " +
"in order to improve cognitive functions<br><br>" +
"in order to improve cognitive functions.<br><br>" +
"This augmentation:<br>" +
"Increases the player's hacking speed by 2%<br>" +
"Increases the player's chance of successfully performing a hack by 10%<br>" +
"Increases the player's hacking experience gain rate by 12%"
"Increases the player's hacking speed by 2%.<br>" +
"Increases the player's chance of successfully performing a hack by 10%.<br>" +
"Increases the player's hacking experience gain rate by 12%."
});
Neuralstimulator.addToFactions(["The Black Hand", "Chongqing", "Sector-12", "New Tokyo", "Aevum",
"Ishima", "Volhaven", "Bachman & Associates", "Clarke Incorporated",
@ -704,9 +708,9 @@ function initAugmentations() {
info:"A microprocessor that accelerates the processing " +
"speed of biological neural networks. This is a cranial implant that is embedded inside the brain.<br><br>" +
"This augmentation:<br>" +
"Increases the player's hacking skill by 10%<br>" +
"Increases the player's hacking experience gain rate by 15%<br>" +
"Increases the amount of money the player gains from hacking by 20%"
"Increases the player's hacking skill by 10%.<br>" +
"Increases the player's hacking experience gain rate by 15%.<br>" +
"Increases the amount of money the player gains from hacking by 20%."
});
NeuralAccelerator.addToFactions(["BitRunners"]);
if (augmentationExists(AugmentationNames.NeuralAccelerator)) {
@ -721,8 +725,8 @@ function initAugmentations() {
"neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations " +
"so that the brain doesn't have to.<br><br>" +
"This augmentation:<br>" +
"Increases the player's hacking speed by 1%<br>" +
"Increases the player's hacking skill by 5%"
"Increases the player's hacking speed by 1%.<br>" +
"Increases the player's hacking skill by 5%."
});
CranialSignalProcessorsG1.addToFactions(["CyberSec"]);
if (augmentationExists(AugmentationNames.CranialSignalProcessorsG1)) {
@ -737,11 +741,12 @@ function initAugmentations() {
"neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations " +
"so that the brain doesn't have to.<br><br>" +
"This augmentation:<br>" +
"Increases the player's hacking speed by 2%<br>" +
"Increases the player's chance of successfully performing a hack by 5%<br>" +
"Increases the player's hacking skill by 7%"
"Increases the player's hacking speed by 2%.<br>" +
"Increases the player's chance of successfully performing a hack by 5%.<br>" +
"Increases the player's hacking skill by 7%.",
prereqs:[AugmentationNames.CranialSignalProcessorsG1]
});
CranialSignalProcessorsG2.addToFactions(["NiteSec"]);
CranialSignalProcessorsG2.addToFactions(["CyberSec", "NiteSec"]);
if (augmentationExists(AugmentationNames.CranialSignalProcessorsG2)) {
delete Augmentations[AugmentationNames.CranialSignalProcessorsG2];
}
@ -754,11 +759,12 @@ function initAugmentations() {
"neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations " +
"so that the brain doesn't have to.<br><br>" +
"This augmentation:<br>" +
"Increases the player's hacking speed by 2%<br>" +
"Increases the amount of money the player gains from hacking by 15%<br>" +
"Increases the player's hacking skill by 9%"
"Increases the player's hacking speed by 2%.<br>" +
"Increases the amount of money the player gains from hacking by 15%.<br>" +
"Increases the player's hacking skill by 9%.",
prereqs:[AugmentationNames.CranialSignalProcessorsG2]
});
CranialSignalProcessorsG3.addToFactions(["NiteSec", "The Black Hand"]);
CranialSignalProcessorsG3.addToFactions(["NiteSec", "The Black Hand", "BitRunners"]);
if (augmentationExists(AugmentationNames.CranialSignalProcessorsG3)) {
delete Augmentations[AugmentationNames.CranialSignalProcessorsG3];
}
@ -771,11 +777,12 @@ function initAugmentations() {
"neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations " +
"so that the brain doesn't have to.<br><br>" +
"This augmentation:<br>" +
"Increases the player's hacking speed by 2%<br>" +
"Increases the amount of money the player gains from hacking by 20%<br>" +
"Increases the amount of money the player can inject into servers using grow() by 25%"
"Increases the player's hacking speed by 2%.<br>" +
"Increases the amount of money the player gains from hacking by 20%.<br>" +
"Increases the amount of money the player can inject into servers using grow() by 25%.",
prereqs:[AugmentationNames.CranialSignalProcessorsG3]
});
CranialSignalProcessorsG4.addToFactions(["The Black Hand"]);
CranialSignalProcessorsG4.addToFactions(["The Black Hand", "BitRunners"]);
if (augmentationExists(AugmentationNames.CranialSignalProcessorsG4)) {
delete Augmentations[AugmentationNames.CranialSignalProcessorsG4];
}
@ -788,9 +795,10 @@ function initAugmentations() {
"neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations " +
"so that the brain doesn't have to.<br><br>" +
"This augmentation:<br>" +
"Increases the player's hacking skill by 30%<br>" +
"Increases the amount of money the player gains from hacking by 25%<br>" +
"Increases the amount of money the player can inject into servers using grow() by 75%"
"Increases the player's hacking skill by 30%.<br>" +
"Increases the amount of money the player gains from hacking by 25%.<br>" +
"Increases the amount of money the player can inject into servers using grow() by 75%.",
prereqs:[AugmentationNames.CranialSignalProcessorsG4]
});
CranialSignalProcessorsG5.addToFactions(["BitRunners"]);
if (augmentationExists(AugmentationNames.CranialSignalProcessorsG5)) {
@ -804,9 +812,9 @@ function initAugmentations() {
"by decreasing the neuron gap junction. Then, the body is genetically modified " +
"to enhance the production and capabilities of its neural stem cells.<br><br>" +
"This augmentation:<br>" +
"Increases the player's hacking skill by 15%<br>" +
"Increases the player's hacking experience gain rate by 10%<br>"+
"Increases the player's hacking speed by 3%"
"Increases the player's hacking skill by 15%.<br>" +
"Increases the player's hacking experience gain rate by 10%.<br>"+
"Increases the player's hacking speed by 3%."
});
NeuronalDensification.addToFactions(["Clarke Incorporated"]);
if (augmentationExists(AugmentationNames.NeuronalDensification)) {
@ -836,8 +844,8 @@ function initAugmentations() {
"you more convincing and likable in conversations and overall improving your " +
"social interactions.<br><br>" +
"This augmentation:<br>" +
"Increases the player's charisma by 10%<br>" +
"Increases the amount of reputation the player gains when working for a company by 10%"
"Increases the player's charisma by 10%.<br>" +
"Increases the amount of reputation the player gains when working for a company by 10%."
});
SpeechEnhancement.addToFactions(["Tian Di Hui", "Speakers for the Dead", "Four Sigma", "KuaiGong International",
"Clarke Incorporated", "Four Sigma", "Bachman & Associates"]);
@ -851,9 +859,9 @@ function initAugmentations() {
info:"A cranial implant that stops procrastination by blocking specific neural pathways " +
"in the brain.<br><br>" +
"This augmentation:<br>" +
"Increases all experience gains by 5%<br>" +
"Increases the amount of money the player gains from working by 20%<br>" +
"Increases the amount of reputation the player gains when working for a company by 10%"
"Increases all experience gains by 5%.<br>" +
"Increases the amount of money the player gains from working by 20%.<br>" +
"Increases the amount of reputation the player gains when working for a company by 10%."
});
FocusWire.addToFactions(["Bachman & Associates", "Clarke Incorporated", "Four Sigma", "KuaiGong International"]);
if (augmentationExists(AugmentationNames.FocusWire)) {
@ -867,8 +875,8 @@ function initAugmentations() {
"computers. Connecting to a computer through this jack allows you to interface with " +
"it using the brain's electrochemical signals.<br><br>" +
"This augmentation:<br>" +
"Increases the amount of reputation the player gains when working for a company by 30%<br>" +
"Increases the player's hacking skill by 8%"
"Increases the amount of reputation the player gains when working for a company by 30%.<br>" +
"Increases the player's hacking skill by 8%."
});
PCDNI.addToFactions(["Four Sigma", "OmniTek Incorporated", "ECorp", "Blade Industries"]);
if (augmentationExists(AugmentationNames.PCDNI)) {
@ -882,9 +890,9 @@ function initAugmentations() {
"improves the performance of the interface and gives the user more control options " +
"to the connected computer.<br><br>" +
"This augmentation:<br>" +
"Increases the amount of reputation the player gains when working for a company by 75%<br>" +
"Increases the player's hacking skill by 10%",
prereqs:[AugmentationNames.PCDNI],
"Increases the amount of reputation the player gains when working for a company by 75%.<br>" +
"Increases the player's hacking skill by 10%.",
prereqs:[AugmentationNames.PCDNI]
});
PCDNIOptimizer.addToFactions(["Fulcrum Secret Technologies", "ECorp", "Blade Industries"]);
if (augmentationExists(AugmentationNames.PCDNIOptimizer)) {
@ -899,10 +907,10 @@ function initAugmentations() {
"The NeuroNet Injector upgrade allows the user to use his/her own brain's " +
"processing power to aid the computer in computational tasks.<br><br>" +
"This augmentation:<br>" +
"Increases the amount of reputation the player gains when working for a company by 100%<br>" +
"Increases the player's hacking skill by 10%<br>" +
"Increases the player's hacking speed by 5%",
prereqs:[AugmentationNames.PCDNI],
"Increases the amount of reputation the player gains when working for a company by 100%.<br>" +
"Increases the player's hacking skill by 10%.<br>" +
"Increases the player's hacking speed by 5%.",
prereqs:[AugmentationNames.PCDNI]
});
PCDNINeuralNetwork.addToFactions(["Fulcrum Secret Technologies"]);
if (augmentationExists(AugmentationNames.PCDNINeuralNetwork)) {
@ -917,7 +925,7 @@ function initAugmentations() {
"triggers feelings of admiration and approval in other people.<br><br>" +
"This augmentation:<br>" +
"Increases the amount of reputation the player gains when working for a company by 10% <br>" +
"Increases the amount of reputation the player gains for a faction by 10%"
"Increases the amount of reputation the player gains for a faction by 10%."
});
ADRPheromone1.addToFactions(["Tian Di Hui", "The Syndicate", "NWO", "MegaCorp", "Four Sigma"]);
if (augmentationExists(AugmentationNames.ADRPheromone1)) {
@ -946,8 +954,8 @@ function initAugmentations() {
"the brain. This allows the user to engineer custom hardware and software " +
"for the Hacknet Node that provides better performance.<br><br>" +
"This augmentation:<br>" +
"Increases the amount of money produced by Hacknet Nodes by 15%<br>" +
"Decreases the cost of purchasing a Hacknet Node by 15%"
"Increases the amount of money produced by Hacknet Nodes by 15%.<br>" +
"Decreases the cost of purchasing a Hacknet Node by 15%."
});
HacknetNodeCPUUpload.addToFactions(["Netburners"]);
if (augmentationExists(AugmentationNames.HacknetNodeCPUUpload)) {
@ -961,8 +969,8 @@ function initAugmentations() {
"into the brain. This allows the user to engineer custom cache hardware for the " +
"Hacknet Node that offers better performance.<br><br>" +
"This augmentation:<br> " +
"Increases the amount of money produced by Hacknet Nodes by 10%<br>" +
"Decreases the cost of leveling up a Hacknet Node by 15%"
"Increases the amount of money produced by Hacknet Nodes by 10%.<br>" +
"Decreases the cost of leveling up a Hacknet Node by 15%."
});
HacknetNodeCacheUpload.addToFactions(["Netburners"]);
if (augmentationExists(AugmentationNames.HacknetNodeCacheUpload)) {
@ -976,8 +984,8 @@ function initAugmentations() {
"into the brain. This allows the user to engineer a custom NIC for the Hacknet Node that " +
"offers better performance.<br><br>" +
"This augmentation:<br>" +
"Increases the amount of money produced by Hacknet Nodes by 10%<br>" +
"Decreases the cost of purchasing a Hacknet Node by 10%"
"Increases the amount of money produced by Hacknet Nodes by 10%.<br>" +
"Decreases the cost of purchasing a Hacknet Node by 10%."
});
HacknetNodeNICUpload.addToFactions(["Netburners"]);
if (augmentationExists(AugmentationNames.HacknetNodeNICUpload)) {
@ -1019,7 +1027,7 @@ function initAugmentations() {
"essentially 'governing' the body. By doing so, it improves the functionality of the " +
"body's nervous system.<br><br>" +
"This is a special augmentation because it can be leveled up infinitely. Each level of this augmentation " +
"increases ALL of the player's multipliers by 1%"
"increases ALL of the player's multipliers by 1%."
});
var nextLevel = getNextNeurofluxLevel();
NeuroFluxGovernor.level = nextLevel - 1;
@ -1038,7 +1046,7 @@ function initAugmentations() {
"installed by releasing millions of nanobots into the human brain, each of which " +
"attaches to a different neural pathway to enhance the brain's ability to retain " +
"and retrieve information.<br><br>" +
"This augmentation increases the player's experience gain rate for all stats by 10%"
"This augmentation increases the player's experience gain rate for all stats by 10%."
});
Neurotrainer1.addToFactions(["CyberSec"]);
if (augmentationExists(AugmentationNames.Neurotrainer1)) {
@ -1051,7 +1059,7 @@ function initAugmentations() {
info:"A decentralized cranial implant that improves the brain's ability to learn. This " +
"is a more powerful version of the Neurotrainer I augmentation, but it does not " +
"require Neurotrainer I to be installed as a prerequisite.<br><br>" +
"This augmentation increases the player's experience gain rate for all stats by 15%"
"This augmentation increases the player's experience gain rate for all stats by 15%."
});
Neurotrainer2.addToFactions(["BitRunners", "NiteSec"]);
if (augmentationExists(AugmentationNames.Neurotrainer2)) {
@ -1064,7 +1072,7 @@ function initAugmentations() {
info:"A decentralized cranial implant that improves the brain's ability to learn. This " +
"is a more powerful version of the Neurotrainer I and Neurotrainer II augmentation, " +
"but it does not require either of them to be installed as a prerequisite.<br><br>" +
"This augmentation increases the player's experience gain rate for all stats by 20%"
"This augmentation increases the player's experience gain rate for all stats by 20%."
});
Neurotrainer3.addToFactions(["NWO", "Four Sigma"]);
if (augmentationExists(AugmentationNames.Neurotrainer3)) {
@ -1078,9 +1086,9 @@ function initAugmentations() {
"Embedded circuitry within the implant provides the ability to detect heat and movement " +
"through solid objects such as wells, thus providing 'x-ray vision'-like capabilities.<br><br>" +
"This augmentation:<br>" +
"Increases the player's dexterity by 40%<br>" +
"Increases the player's hacking speed by 3%<br>" +
"Increases the amount of money the player gains from hacking by 10%"
"Increases the player's dexterity by 40%.<br>" +
"Increases the player's hacking speed by 3%.<br>" +
"Increases the amount of money the player gains from hacking by 10%."
});
Hypersight.addToFactions(["Blade Industries", "KuaiGong International"]);
if (augmentationExists(AugmentationNames.Hypersight)) {
@ -1095,7 +1103,7 @@ function initAugmentations() {
"around the skin, making the user much harder to see from the naked eye.<br><br>" +
"This augmentation:<br>" +
"Increases the player's agility by 5% <br>" +
"Increases the amount of money the player gains from crimes by 10%"
"Increases the amount of money the player gains from crimes by 10%."
});
LuminCloaking1.addToFactions(["Slum Snakes", "Tetrads"]);
if (augmentationExists(AugmentationNames.LuminCloaking1)) {
@ -1112,7 +1120,7 @@ function initAugmentations() {
"This augmentation:<br>" +
"Increases the player's agility by 10% <br>" +
"Increases the player's defense by 10% <br>" +
"Increases the amount of money the player gains from crimes by 25%",
"Increases the amount of money the player gains from crimes by 25%.",
prereqs:[AugmentationNames.LuminCloaking1]
});
LuminCloaking2.addToFactions(["Slum Snakes", "Tetrads"]);
@ -1126,9 +1134,9 @@ function initAugmentations() {
info:"A cochlear implant that helps the player detect and locate enemies " +
"using sound propagation.<br><br>" +
"This augmentation:<br>" +
"Increases the player's dexterity by 10%<br>" +
"Increases the player's dexterity experience gain rate by 15%<br>" +
"Increases the amount of money the player gains from crimes by 25%"
"Increases the player's dexterity by 10%.<br>" +
"Increases the player's dexterity experience gain rate by 15%.<br>" +
"Increases the amount of money the player gains from crimes by 25%."
});
SmartSonar.addToFactions(["Slum Snakes"]);
if (augmentationExists(AugmentationNames.SmartSonar)) {
@ -1142,8 +1150,8 @@ function initAugmentations() {
"are capable of capturing wasted energy (in the form of heat) " +
"and converting it back into usable power.<br><br>" +
"This augmentation:<br>" +
"Increases all of the player's stats by 5%<br>" +
"Increases the player's experience gain rate for all stats by 10%"
"Increases all of the player's stats by 5%.<br>" +
"Increases the player's experience gain rate for all stats by 10%."
});
PowerRecirculator.addToFactions(["Tetrads", "The Dark Army", "The Syndicate", "NWO"]);
if (augmentationExists(AugmentationNames.PowerRecirculator)) {
@ -1163,9 +1171,9 @@ function initAugmentations() {
"quantum supercomputer, allowing you to access and use its incredible " +
"computing power.<br><br>" +
"This augmentation:<br>" +
"Increases the player's hacking speed by 10%<br>" +
"Increases the player's chance of successfully performing a hack by 30%<br>" +
"Increases the amount of money the player gains from hacking by 100%"
"Increases the player's hacking speed by 10%.<br>" +
"Increases the player's chance of successfully performing a hack by 30%.<br>" +
"Increases the amount of money the player gains from hacking by 100%."
});
QLink.addToFactions(["Illuminati"]);
if (augmentationExists(AugmentationNames.QLink)) {
@ -1176,7 +1184,7 @@ function initAugmentations() {
//Daedalus
var RedPill = new Augmentation({
name:AugmentationNames.TheRedPill, repCost:1e6, moneyCost:0,
info:"It's time to leave the cave"
info:"It's time to leave the cave."
});
RedPill.addToFactions(["Daedalus"]);
if (augmentationExists(AugmentationNames.TheRedPill)) {
@ -1192,8 +1200,8 @@ function initAugmentations() {
"super-soldiers through genetic modification. The gene was outlawed in " +
"2056.<br><br>" +
"This augmentation:<br>" +
"Increases all of the player's combat stats by 75%<br>" +
"Increases the player's hacking skill by 15%"
"Increases all of the player's combat stats by 75%.<br>" +
"Increases the player's hacking skill by 15%."
});
SPTN97.addToFactions(["The Covenant"]);
if (augmentationExists(AugmentationNames.SPTN97)) {
@ -1222,8 +1230,8 @@ function initAugmentations() {
"fusion power through nuclear fusion, providing limitless amount of clean " +
"energy for the body.<br><br>" +
"This augmentation:<br>" +
"Increases all of the player's combat stats by 35%<br>" +
"Increases all of the player's combat stat experience gain rate by 35%"
"Increases all of the player's combat stats by 35%.<br>" +
"Increases all of the player's combat stat experience gain rate by 35%."
});
CordiARCReactor.addToFactions(["MegaCorp"]);
if (augmentationExists(AugmentationNames.CordiARCReactor)) {
@ -1239,9 +1247,9 @@ function initAugmentations() {
"others using optical imaging software.<br><br>" +
"This augmentation:<br>" +
"Increases the player's charisma by 50%. <br>" +
"Increases the player's charisma experience gain rate by 50%<br>" +
"Increases the amount of reputation the player gains for a company by 25%<br>" +
"Increases the amount of reputation the player gains for a faction by 25%"
"Increases the player's charisma experience gain rate by 50%.<br>" +
"Increases the amount of reputation the player gains for a company by 25%.<br>" +
"Increases the amount of reputation the player gains for a faction by 25%."
});
SmartJaw.addToFactions(["Bachman & Associates"]);
if (augmentationExists(AugmentationNames.SmartJaw)) {
@ -1256,7 +1264,7 @@ function initAugmentations() {
"and integumentary system. The drug permanently modifies the DNA of the " +
"body's skin and bone cells, granting them the ability to repair " +
"and restructure themselves.<br><br>" +
"This augmentation increases the player's strength and defense by 55%"
"This augmentation increases the player's strength and defense by 55%."
});
Neotra.addToFactions(["Blade Industries"]);
if (augmentationExists(AugmentationNames.Neotra)) {
@ -1271,8 +1279,8 @@ function initAugmentations() {
"body. These nanobots induce physiological change and significantly " +
"improve the body's functionining in all aspects.<br><br>" +
"This augmentation:<br>" +
"Increases all of the player's stats by 20%<br>" +
"Increases the player's experience gain rate for all stats by 15%"
"Increases all of the player's stats by 20%.<br>" +
"Increases the player's experience gain rate for all stats by 15%."
});
Xanipher.addToFactions(["NWO"]);
if (augmentationExists(AugmentationNames.Xanipher)) {
@ -1286,7 +1294,7 @@ function initAugmentations() {
info:"The body is genetically re-engineered to maintain a state " +
"of negligible senescence, preventing the body from " +
"deteriorating with age.<br><br>" +
"This augmentation increases all of the player's stats by 20%"
"This augmentation increases all of the player's stats by 20%."
});
nextSENS.addToFactions(["Clarke Incorporated"]);
if (augmentationExists(AugmentationNames.nextSENS)) {
@ -1301,8 +1309,8 @@ function initAugmentations() {
"into your brain, enhancing your programming and " +
"hacking abilities.<br><br>" +
"This augmentation:<br>" +
"Increases the player's hacking skill by 20%<br>" +
"Increases the player's hacking experience gain rate by 25%"
"Increases the player's hacking skill by 20%.<br>" +
"Increases the player's hacking experience gain rate by 25%."
});
OmniTekInfoLoad.addToFactions(["OmniTek Incorporated"]);
if (augmentationExists(AugmentationNames.OmniTekInfoLoad)) {
@ -1320,7 +1328,7 @@ function initAugmentations() {
"to the body using a skin graft. The result is photosynthetic " +
"skin cells, allowing users to generate their own energy " +
"and nutrition using solar power.<br><br>" +
"This augmentation increases the player's strength, defense, and agility by 40%"
"This augmentation increases the player's strength, defense, and agility by 40%."
});
PhotosyntheticCells.addToFactions(["KuaiGong International"]);
if (augmentationExists(AugmentationNames.PhotosyntheticCells)) {
@ -1335,11 +1343,11 @@ function initAugmentations() {
"mind and BitRunners' data servers, which reportedly contain " +
"the largest database of hacking tools and information in the world.<br><br>" +
"This augmentation:<br>" +
"Increases the player's hacking skill by 15%<br>" +
"Increases the player's hacking experience gain rate by 20%<br>" +
"Increases the player's chance of successfully performing a hack by 10%<br>" +
"Increases the player's hacking speed by 5%<br>" +
"Lets the player start with the FTPCrack.exe and relaySMTP.exe programs after a reset"
"Increases the player's hacking skill by 15%.<br>" +
"Increases the player's hacking experience gain rate by 20%.<br>" +
"Increases the player's chance of successfully performing a hack by 10%.<br>" +
"Increases the player's hacking speed by 5%.<br>" +
"Lets the player start with the FTPCrack.exe and relaySMTP.exe programs after a reset."
});
Neurolink.addToFactions(["BitRunners"]);
if (augmentationExists(AugmentationNames.Neurolink)) {
@ -1355,10 +1363,10 @@ function initAugmentations() {
"with hardware and firmware that lets the user connect to, access and hack " +
"devices and machines just by touching them.<br><br>" +
"This augmentation:<br>" +
"Increases the player's strength and dexterity by 15%<br>" +
"Increases the player's hacking skill by 10%<br>" +
"Increases the player's hacking speed by 2%<br>" +
"Increases the amount of money the player gains from hacking by 10%"
"Increases the player's strength and dexterity by 15%.<br>" +
"Increases the player's hacking skill by 10%.<br>" +
"Increases the player's hacking speed by 2%.<br>" +
"Increases the amount of money the player gains from hacking by 10%."
});
TheBlackHand.addToFactions(["The Black Hand"]);
if (augmentationExists(AugmentationNames.TheBlackHand)) {
@ -1373,8 +1381,8 @@ function initAugmentations() {
"The CRTX42-AA is an artificially-synthesized gene that targets the visual and prefrontal " +
"cortex and improves cognitive abilities.<br><br>" +
"This augmentation:<br>" +
"Improves the player's hacking skill by 8%<br>" +
"Improves the player's hacking experience gain rate by 15%"
"Improves the player's hacking skill by 8%.<br>" +
"Improves the player's hacking experience gain rate by 15%."
});
CRTX42AA.addToFactions(["NiteSec"]);
if (augmentationExists(AugmentationNames.CRTX42AA)) {
@ -1388,7 +1396,7 @@ function initAugmentations() {
info:"A drug that genetically modifies the neurons in the brain. " +
"The result is that these neurons never die and continuously " +
"regenerate and strengthen themselves.<br><br>" +
"This augmentation increases the player's hacking experience gain rate by 40%"
"This augmentation increases the player's hacking experience gain rate by 40%."
});
Neuregen.addToFactions(["Chongqing"]);
if (augmentationExists(AugmentationNames.Neuregen)) {
@ -1403,8 +1411,8 @@ function initAugmentations() {
"into your wrist. A small jack in the chip allows you to connect it to a computer " +
"and upload the assets.<br><br>" +
"This augmentation:<br>" +
"Lets the player start with $1,000,000 after a reset<br>" +
"Lets the player start with the BruteSSH.exe program after a reset"
"Lets the player start with $1,000,000 after a reset.<br>" +
"Lets the player start with the BruteSSH.exe program after a reset."
});
CashRoot.addToFactions(["Sector-12"]);
if (augmentationExists(AugmentationNames.CashRoot)) {
@ -1420,7 +1428,7 @@ function initAugmentations() {
"across the body. The device is powered by the body's naturally wasted " +
"energy in the form of heat.<br><br>" +
"This augmentation:<br>" +
"Increases the player's experience gain rate for all combat stats by 20%"
"Increases the player's experience gain rate for all combat stats by 20%."
});
NutriGen.addToFactions(["New Tokyo"]);
if (augmentationExists(AugmentationNames.NutriGen)) {
@ -1438,9 +1446,9 @@ function initAugmentations() {
info:"A retina implant consisting of a tiny chip that sits behind the " +
"retina. This implant lets people visually detect infrared radiation.<br><br>" +
"This augmentation:<br>" +
"Increases the player's crime success rate by 25%<br>" +
"Increases the amount of money the player gains from crimes by 10%<br>" +
"Increases the player's dexterity by 10%"
"Increases the player's crime success rate by 25%.<br>" +
"Increases the amount of money the player gains from crimes by 10%.<br>" +
"Increases the player's dexterity by 10%."
});
INFRARet.addToFactions(["Ishima"]);
if (augmentationExists(AugmentationNames.INFRARet)) {
@ -1454,7 +1462,7 @@ function initAugmentations() {
info:"A synthetic skin is grafted onto the body. The skin consists of " +
"millions of nanobots capable of projecting high-density muon beams, " +
"creating an energy barrier around the user.<br><br>" +
"This augmentation increases the player's defense by 40%"
"This augmentation increases the player's defense by 40%."
});
DermaForce.addToFactions(["Volhaven"]);
if (augmentationExists(AugmentationNames.DermaForce)) {
@ -1469,10 +1477,10 @@ function initAugmentations() {
"the retractable blades with an advanced graphene material " +
"to make them much stronger and lighter.<br><br>" +
"This augmentation:<br>" +
"Increases the player's strength and defense by 40%<br>" +
"Increases the player's crime success rate by 10%<br>" +
"Increases the amount of money the player gains from crimes by 30%",
prereqs:[AugmentationNames.BrachiBlades],
"Increases the player's strength and defense by 40%.<br>" +
"Increases the player's crime success rate by 10%.<br>" +
"Increases the amount of money the player gains from crimes by 30%.",
prereqs:[AugmentationNames.BrachiBlades]
});
GrapheneBrachiBlades.addToFactions(["Speakers for the Dead"]);
if (augmentationExists(AugmentationNames.GrapheneBrachiBlades)) {
@ -1486,8 +1494,8 @@ function initAugmentations() {
info:"An upgrade to the Bionic Arms augmentation. It infuses the " +
"prosthetic arms with an advanced graphene material " +
"to make them much stronger and lighter.<br><br>" +
"This augmentation increases the player's strength and dexterity by 85%",
prereqs:[AugmentationNames.BionicArms],
"This augmentation increases the player's strength and dexterity by 85%.",
prereqs:[AugmentationNames.BionicArms]
});
GrapheneBionicArms.addToFactions(["The Dark Army"]);
if (augmentationExists(AugmentationNames.GrapheneBionicArms)) {
@ -1498,11 +1506,11 @@ function initAugmentations() {
//TheSyndicate
var BrachiBlades = new Augmentation({
name:AugmentationNames.BrachiBlades, repCost:5e3, moneyCost:18e6,
info:"A set of retractable plasteel blades are implanted in the arm, underneath the skin. " +
"<br><br>This augmentation: <br>" +
"Increases the player's strength and defense by 15%<br>" +
"Increases the player's crime success rate by 10%<br>" +
"Increases the amount of money the player gains from crimes by 15%"
info:"A set of retractable plasteel blades are implanted in the arm, underneath the skin.<br><br>" +
"This augmentation:<br>" +
"Increases the player's strength and defense by 15%.<br>" +
"Increases the player's crime success rate by 10%.<br>" +
"Increases the amount of money the player gains from crimes by 15%."
});
BrachiBlades.addToFactions(["The Syndicate"]);
if (augmentationExists(AugmentationNames.BrachiBlades)) {
@ -1515,7 +1523,7 @@ function initAugmentations() {
name:AugmentationNames.BionicArms, repCost:25e3, moneyCost:55e6,
info:"Cybernetic arms created from plasteel and carbon fibers that completely replace " +
"the user's organic arms.<br><br>" +
"This augmentation increases the user's strength and dexterity by 30%"
"This augmentation increases the user's strength and dexterity by 30%."
});
BionicArms.addToFactions(["Tetrads"]);
if (augmentationExists(AugmentationNames.BionicArms)) {
@ -1529,9 +1537,9 @@ function initAugmentations() {
info:"A cranial implant that affects the user's personality, making them better " +
"at negotiation in social situations.<br><br>" +
"This augmentation:<br>" +
"Increases the amount of money the player earns at a company by 10%<br>" +
"Increases the amount of money the player earns at a company by 10%.<br>" +
"Increases the amount of reputation the player gains when working for a " +
"company or faction by 15%"
"company or faction by 15%."
});
SNA.addToFactions(["Tian Di Hui"]);
if (augmentationExists(AugmentationNames.SNA)) {
@ -1566,8 +1574,8 @@ function initAugmentations() {
"embedded with a data processing chip that can be programmed to display an " +
"AR HUD and assist the user in field missions.<br><br>" +
"This augmentation:<br>" +
"Increases the player's success chance in Bladeburner contracts/operations by 3%<br>" +
"Increases the player's dexterity by 3%"
"Increases the player's success chance in Bladeburner contracts/operations by 3%.<br>" +
"Increases the player's dexterity by 3%."
});
EsperEyewear.addToFactions([BladeburnersFactionName]);
resetAugmentation(EsperEyewear);
@ -1579,9 +1587,9 @@ function initAugmentations() {
"to induce wakefulness and concentration, suppress fear, reduce empathy, and " +
"improve reflexes and memory-recall among other things.<br><br>" +
"This augmentation:<br>" +
"Increases the player's sucess chance in Bladeburner contracts/operations by 3%<br>" +
"Increases the player's effectiveness in Bladeburner Field Analysis by 5%<br>" +
"Increases the player's Bladeburner stamina gain rate by 1%"
"Increases the player's sucess chance in Bladeburner contracts/operations by 3%.<br>" +
"Increases the player's effectiveness in Bladeburner Field Analysis by 5%.<br>" +
"Increases the player's Bladeburner stamina gain rate by 1%."
});
EMS4Recombination.addToFactions([BladeburnersFactionName]);
resetAugmentation(EMS4Recombination);
@ -1594,8 +1602,8 @@ function initAugmentations() {
"crystallized graphene plating.<br><br>" +
"This augmentation:<br>" +
"Increases the player's defense by 5%.<br>" +
"Increases the player's strength and dexterity by 3%<br>" +
"Increases the player's success chance in Bladeburner contracts/operations by 4%"
"Increases the player's strength and dexterity by 3%.<br>" +
"Increases the player's success chance in Bladeburner contracts/operations by 4%."
});
OrionShoulder.addToFactions([BladeburnersFactionName]);
resetAugmentation(OrionShoulder);
@ -1609,7 +1617,7 @@ function initAugmentations() {
"it can also be effective against non-augmented enemies due to its high temperature " +
"and concussive force.<br><br>" +
"This augmentation:<br>" +
"Increases the player's success chance in Bladeburner contracts/operations by 5%"
"Increases the player's success chance in Bladeburner contracts/operations by 5%."
});
HyperionV1.addToFactions([BladeburnersFactionName]);
resetAugmentation(HyperionV1);
@ -1621,7 +1629,7 @@ function initAugmentations() {
"more power-efficiency, more accurate, and can fire plasma bolts at a much " +
"higher velocity than the V1 model.<br><br>" +
"This augmentation:<br>" +
"Increases the player's success chance in Bladeburner contracts/operations by 7%",
"Increases the player's success chance in Bladeburner contracts/operations by 7%.",
prereqs:[AugmentationNames.HyperionV1]
});
HyperionV2.addToFactions([BladeburnersFactionName]);
@ -1634,8 +1642,8 @@ function initAugmentations() {
"serum was originally developed by the Chinese military in an attempt to " +
"create super soldiers.<br><br>" +
"This augmentation:<br>" +
"Increases all of the player's combat stats by 5%<br>" +
"Increases the player's Bladeburner stamina gain rate by 5%<br>"
"Increases all of the player's combat stats by 5%.<br>" +
"Increases the player's Bladeburner stamina gain rate by 5%.<br>"
});
GolemSerum.addToFactions([BladeburnersFactionName]);
resetAugmentation(GolemSerum);
@ -1645,9 +1653,9 @@ function initAugmentations() {
info:"A synthetic symbiotic virus that is injected into the human brain tissue. The Vangelis virus " +
"heightens the senses and focus of its host, and also enhances its intuition.<br><br>" +
"This augmentation:<br>" +
"Increases the player's effectiveness in Bladeburner Field Analysis by 10%<br>" +
"Increases the player's success chance in Bladeburner contracts/operations by 4%<br>" +
"Increases the player's dexterity experience gain rate by 5%"
"Increases the player's effectiveness in Bladeburner Field Analysis by 10%.<br>" +
"Increases the player's success chance in Bladeburner contracts/operations by 4%.<br>" +
"Increases the player's dexterity experience gain rate by 5%."
});
VangelisVirus.addToFactions([BladeburnersFactionName]);
resetAugmentation(VangelisVirus);
@ -1659,9 +1667,9 @@ function initAugmentations() {
"virus, this also grants an accelerated healing factor and enhanced " +
"agility/reflexes.<br><br>" +
"This augmentation:<br>" +
"Increases the player's effectiveness in Bladeburner Field Analysis by 15%<br>" +
"Increases the player's defense and dexterity experience gain rate by 5%<br>" +
"Increases the player's success chance in Bladeburner contracts/operations by 5%",
"Increases the player's effectiveness in Bladeburner Field Analysis by 15%.<br>" +
"Increases the player's defense and dexterity experience gain rate by 5%.<br>" +
"Increases the player's success chance in Bladeburner contracts/operations by 5%.",
prereqs:[AugmentationNames.VangelisVirus]
});
VangelisVirus3.addToFactions([BladeburnersFactionName]);
@ -1674,8 +1682,8 @@ function initAugmentations() {
"structurally support the body and grants heightened strength and " +
"durability.<br><br>" +
"This augmentation:<br>" +
"Increases the player's experience gain rate for all combat stats by 4%<br>" +
"Increases the player's Bladeburner max stamina by 10%"
"Increases the player's experience gain rate for all combat stats by 4%.<br>" +
"Increases the player's Bladeburner max stamina by 10%."
});
INTERLINKED.addToFactions([BladeburnersFactionName]);
resetAugmentation(INTERLINKED);
@ -1687,9 +1695,9 @@ function initAugmentations() {
"is enhanced with flexible carbon nanotube matrices that are controlled by " +
"intelligent servo-motors.<br><br>" +
"This augmentation:<br>" +
"Increases the player's agility by 5%<br>" +
"Increases the player's Bladeburner max stamina by 5%<br>" +
"Increases the player's Bladeburner stamina gain rate by 5%<br>"
"Increases the player's agility by 5%.<br>" +
"Increases the player's Bladeburner max stamina by 5%.<br>" +
"Increases the player's Bladeburner stamina gain rate by 5%.<br>"
});
BladeRunner.addToFactions([BladeburnersFactionName]);
resetAugmentation(BladeRunner);
@ -1701,9 +1709,9 @@ function initAugmentations() {
"concussive, thermal, chemical, and electric trauma. It also enhances the user's " +
"strength and agility.<br><br>" +
"This augmentation:<br>" +
"Increases all of the player's combat stats by 2%<br>" +
"Increases the player's Bladeburner stamina gain rate by 2%<br>" +
"Increases the player's success chance in Bladeburner contracts/operations by 3%",
"Increases all of the player's combat stats by 2%.<br>" +
"Increases the player's Bladeburner stamina gain rate by 2%.<br>" +
"Increases the player's success chance in Bladeburner contracts/operations by 3%.",
});
BladeArmor.addToFactions([BladeburnersFactionName]);
resetAugmentation(BladeArmor);
@ -1713,9 +1721,9 @@ function initAugmentations() {
info:"Upgrades the BLADE-51b Tesla Armor with Ion Power Cells, which are capable of " +
"more efficiently storing and using power.<br><br>" +
"This augmentation:<br>" +
"Increases the player's success chance in Bladeburner contracts/operations by 5%" +
"Increases the player's Bladeburner stamina gain rate by 2%<br>" +
"Increases the player's Bladeburner max stamina by 5%<br>",
"Increases the player's success chance in Bladeburner contracts/operations by 5%.<br>" +
"Increases the player's Bladeburner stamina gain rate by 2%.<br>" +
"Increases the player's Bladeburner max stamina by 5%.",
prereqs:[AugmentationNames.BladeArmor]
});
BladeArmorPowerCells.addToFactions([BladeburnersFactionName]);
@ -1726,8 +1734,8 @@ function initAugmentations() {
info:"Upgrades the BLADE-51b Tesla Armor with a plasma energy propulsion system " +
"that is capable of projecting an energy shielding force field.<br><br>" +
"This augmentation:<br>" +
"Increases the player's defense by 5%<br>" +
"Increases the player's success chance in Bladeburner contracts/operations by 6%",
"Increases the player's defense by 5%.<br>" +
"Increases the player's success chance in Bladeburner contracts/operations by 6%.",
prereqs:[AugmentationNames.BladeArmor]
});
BladeArmorEnergyShielding.addToFactions([BladeburnersFactionName]);
@ -1739,7 +1747,7 @@ function initAugmentations() {
"weapon. It's precision an accuracy makes it useful for quickly neutralizing " +
"threats while keeping casualties to a minimum.<br><br>" +
"This augmentation:<br>" +
"Increases the player's success chance in Bladeburner contracts/operations by 8%",
"Increases the player's success chance in Bladeburner contracts/operations by 8%.",
prereqs:[AugmentationNames.BladeArmor]
});
BladeArmorUnibeam.addToFactions([BladeburnersFactionName]);
@ -1752,7 +1760,7 @@ function initAugmentations() {
"modules that combine together to form a single, more powerful beam of up to " +
"2000MW.<br><br>" +
"This augmentation:<br>" +
"Increases the player's success chance in Bladeburner contracts/operations by 10%",
"Increases the player's success chance in Bladeburner contracts/operations by 10%.",
prereqs:[AugmentationNames.BladeArmorUnibeam]
});
BladeArmorOmnibeam.addToFactions([BladeburnersFactionName]);
@ -1764,8 +1772,8 @@ function initAugmentations() {
"Unit that was specially designed to analyze Synthoid related data and " +
"information.<br><br>" +
"This augmentation:<br>" +
"Increases the player's effectiveness in Bladeburner Field Analysis by 15%<br>" +
"Increases the player's success chance in Bladeburner contracts/operations by 2%",
"Increases the player's effectiveness in Bladeburner Field Analysis by 15%.<br>" +
"Increases the player's success chance in Bladeburner contracts/operations by 2%.",
prereqs:[AugmentationNames.BladeArmor]
});
BladeArmorIPU.addToFactions([BladeburnersFactionName]);

@ -357,8 +357,8 @@ function initBitNodeMultipliers() {
sf12Lvl = Player.sourceFiles[i].lvl;
}
}
var inc = Math.pow(1.01, sf12Lvl);
var dec = Math.pow(0.99, sf12Lvl);
var inc = Math.pow(1.02, sf12Lvl);
var dec = 1/inc;
BitNodeMultipliers.HackingLevelMultiplier = dec;
BitNodeMultipliers.ServerMaxMoney = dec;

@ -1094,6 +1094,7 @@ Bladeburner.prototype.startAction = function(actionId) {
throw new Error ("Failed to get Operation Object for: " + actionId.name);
}
if (action.count < 1) {return this.resetAction();}
if (actionId.name === "Raid" && this.getCurrentCity().commsEst === 0) {return this.resetAction();}
this.actionTimeToComplete = action.getActionTime(this);
} catch(e) {
exceptionAlert(e);
@ -1420,13 +1421,6 @@ Bladeburner.prototype.completeOperation = function(success) {
}
var city = this.getCurrentCity();
if (this.logging.ops) {
if (success) {
this.log(action.name + " completed successfully! ")
} else {
}
}
switch (action.name) {
case "Investigation":
if (success) {
@ -1663,6 +1657,7 @@ Bladeburner.prototype.initializeDomElementRefs = function() {
overviewEstComms: null,
overviewChaos: null,
overviewSkillPoints: null,
overviewBonusTime: null,
overviewAugSuccessMult: null,
overviewAugMaxStaminaMult: null,
overviewAugStaminaGainMult: null,
@ -1826,8 +1821,15 @@ Bladeburner.prototype.createOverviewContent = function() {
"Having too high of a chaos level can make contracts and operations harder."
});
DomElems.overviewBonusTime = createElement("p", {
innerText: "Bonus time: ",
display: "inline-block",
tooltip: "You gain bonus time while offline or when the game is inactive (e.g. when the tab is throttled by browser). " +
"Bonus time makes the Bladeburner mechanic progress faster, up to 5x the normal speed."
});
DomElems.overviewSkillPoints = createElement("p", {display:"block"});
DomElems.overviewAugSuccessMult = createElement("p", {display:"block"});
DomElems.overviewAugMaxStaminaMult = createElement("p", {display:"block"});
DomElems.overviewAugStaminaGainMult = createElement("p", {display:"block"});
@ -1846,6 +1848,7 @@ Bladeburner.prototype.createOverviewContent = function() {
appendLineBreaks(DomElems.overviewDiv, 1);
DomElems.overviewDiv.appendChild(DomElems.overviewChaos);
appendLineBreaks(DomElems.overviewDiv, 2);
DomElems.overviewDiv.appendChild(DomElems.overviewBonusTime);
DomElems.overviewDiv.appendChild(DomElems.overviewSkillPoints);
appendLineBreaks(DomElems.overviewDiv, 1);
DomElems.overviewDiv.appendChild(DomElems.overviewAugSuccessMult);
@ -2206,6 +2209,7 @@ Bladeburner.prototype.updateOverviewContent = function() {
DomElems.overviewEstComms.childNodes[0].nodeValue = "Est. Synthoid Communities: " + formatNumber(this.getCurrentCity().comms, 0);
DomElems.overviewChaos.childNodes[0].nodeValue = "City Chaos: " + formatNumber(this.getCurrentCity().chaos);
DomElems.overviewSkillPoints.innerText = "Skill Points: " + formatNumber(this.skillPoints, 0);
DomElems.overviewBonusTime.childNodes[0].nodeValue = "Bonus time: " + this.storedCycles/CyclesPerSecond;
DomElems.overviewAugSuccessMult.innerText = "Aug. Success Chance Mult: " + formatNumber(Player.bladeburner_success_chance_mult*100, 1) + "%";
DomElems.overviewAugMaxStaminaMult.innerText = "Aug. Max Stamina Mult: " + formatNumber(Player.bladeburner_max_stamina_mult*100, 1) + "%";
DomElems.overviewAugStaminaGainMult.innerText = "Aug. Stamina Gain Mult: " + formatNumber(Player.bladeburner_stamina_gain_mult*100, 1) + "%";

58
src/CharacterOverview.js Normal file

@ -0,0 +1,58 @@
import {Player} from "./Player";
import numeral from "numeral/min/numeral.min";
function CharacterOverview() {
this.hp = document.getElementById("character-hp-text");
this.money = document.getElementById("character-money-text");
this.hack = document.getElementById("character-hack-text");
this.str = document.getElementById("character-str-text");
this.def = document.getElementById("character-def-text");
this.dex = document.getElementById("character-dex-text");
this.agi = document.getElementById("character-agi-text");
this.cha = document.getElementById("character-cha-text");
this.int = document.getElementById("character-int-text");
this.intWrapper = document.getElementById("character-int-wrapper");
this.repaintElem = document.getElementById("character-overview-text");
}
CharacterOverview.prototype.repaint = function() {
// this is an arbitrary function we can call to trigger a repaint.
this.repaintElem.getClientRects();
}
CharacterOverview.prototype.update = function() {
if (Player.hp == null) {Player.hp = Player.max_hp;}
const replaceAndChanged = function(elem, text) {
if(elem.textContent === text) {
return false;
}
elem.textContent = text;
return true;
}
let changed = false;
changed = replaceAndChanged(this.hp, Player.hp + " / " + Player.max_hp) || changed;
changed = replaceAndChanged(this.money, numeral(Player.money.toNumber()).format('($0.000a)')) || changed;
changed = replaceAndChanged(this.hack, (Player.hacking_skill).toLocaleString()) || changed;
changed = replaceAndChanged(this.str, (Player.strength).toLocaleString()) || changed;
changed = replaceAndChanged(this.def, (Player.defense).toLocaleString()) || changed;
changed = replaceAndChanged(this.dex, (Player.dexterity).toLocaleString()) || changed;
changed = replaceAndChanged(this.agi, (Player.agility).toLocaleString()) || changed;
changed = replaceAndChanged(this.cha, (Player.charisma).toLocaleString()) || changed;
changed = replaceAndChanged(this.int, (Player.intelligence).toLocaleString()) || changed;
// handle int appearing
const int = this.intWrapper;
const old = int.style.display;
const now = Player.intelligence >= 1 ? "" : "none";
if(old !== now) {
int.style.display = now;
changed = true;
}
// recalculate box size if something changed
if(changed) this.repaint();
}
export {CharacterOverview};

@ -4736,7 +4736,7 @@ Corporation.prototype.updateDivisionContent = function(division) {
var totalAdvertisingFac = advertisingFactors[0];
advertisingInfo =
"<p class='tooltip'>Advertising Multiplier: x" + formatNumber(totalAdvertisingFac, 3) +
"<span class='tooltiptext' style='font-size:12px'>Total multiplier for this industry's sales due to its awareness and popularity<br>" +
"<span class='tooltiptext cmpy-mgmt-advertising-info'>Total multiplier for this industry's sales due to its awareness and popularity<br>" +
"Awareness Bonus: x" + formatNumber(Math.pow(awarenessFac, 0.85), 3) + "<br>" +
"Popularity Bonus: x" + formatNumber(Math.pow(popularityFac, 0.85), 3) + "<br>" +
"Ratio Multiplier: x" + formatNumber(Math.pow(ratioFac, 0.85), 3) + "</span></p><br>"

@ -1,5 +1,5 @@
let CONSTANTS = {
Version: "0.40.0",
Version: "0.40.1",
//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
@ -31,6 +31,7 @@ let CONSTANTS = {
HacknetNodeMaxCores: 16,
/* Faction and Company favor */
BaseFavorToDonate: 150,
FactionReputationToFavorBase: 500,
FactionReputationToFavorMult: 1.02,
CompanyReputationToFavorBase: 500,
@ -70,6 +71,7 @@ let CONSTANTS = {
ScriptHNUpgCoreRamCost: 0.8,
ScriptGetStockRamCost: 2.0,
ScriptBuySellStockRamCost: 2.5,
ScriptGetPurchaseServerRamCost: 0.25,
ScriptPurchaseServerRamCost: 2.25,
ScriptGetPurchasedServerLimit: 0.05,
ScriptGetPurchasedServerMaxRam: 0.05,
@ -78,6 +80,7 @@ let CONSTANTS = {
ScriptArbScriptRamCost: 1.0, //Functions that apply to all scripts regardless of args
ScriptGetScriptRamCost: 0.1,
ScriptGetHackTimeRamCost: 0.05,
ScriptGetFavorToDonate: 0.10,
ScriptSingularityFn1RamCost: 1,
ScriptSingularityFn2RamCost: 2,
@ -488,33 +491,21 @@ let CONSTANTS = {
"World Stock Exchange account and TIX API Access<br>",
LatestUpdate:
"v0.40.0<br>" +
"* <b>WARNING: This update makes some significant changes to Netscript and therefore you may need to " +
"make some changes to your scripts. See <a href='https://www.reddit.com/r/Bitburner/comments/9252j4/psa_netscript_10_changes_in_next_version_v0400/' target='_blank'> " +
"this post for details</a></b><br>" +
"* Netscript 1.0 (NS1) now uses a fully-fledged ES5 JavaScript Interpreter. This means many new features are now available in NS1, and this also fixes several bugs." +
" However this also means any ES6+ features are no longer supported in NS1 <br>" +
"* When a server is hacked with a very large number of threads and left with no money, the server's security level " +
"now only increases by however many threads were needed to drain the server. For example, if you hack a server with " +
"5000 threads but it only needed 2000 threads to deplete the server's money, then the server's security will only increase " +
"as if you had hacked it with 2000 threads (change by hydroflame)<br>" +
"* Added getCurrentAction() to Bladeburner API<br>" +
"* Added a variety of functions to Bladeburner API that deal with action levels (change by hydroflame)<br>" +
"* Added getPurchasedServerLimit() and getPurchasedServerMaxRam() functions to Netscript (change by hydroflame & kopelli)<br>" +
"* Added getOwnedSourceFiles() Singularity function (by hydroflame)<br>" +
"* Completely re-designed the Hacknet Node API<br>" +
"* getSkillLevel() in Bladeburner API now returns an error if no argument is passed in (as opposed to an object with all skill levels). This may break scripts<br>" +
"* Minimum Netscript execution time reduced from 15ms to 10ms (configurable in Options)<br>" +
"* Company reputation needed to get invited to Megacorporation factions decreased from 250k to 200k<br>" +
"* HP is now reset (restored) when Augmenting<br>" +
"* Source-File 6 now increases both the level and experience gain of all combat stats (it was only experience gain previously)<br>" +
"* Reverted a previous change for Source-File 12. It's benefits are now multiplicative rather than additive<br>" +
"* Starting Infiltration security level for almost every location decreased by ~10%<br>" +
"* Changed 'fl1ght.exe' message when its listed conditions are fulfilled (by hydroflame)<br>" +
"* The 'Save Game' button in the top-right overview panel now flashes red if autosave is disabled<br>" +
"* Bug Fix: Infiltration buttons can no longer be clicked through NetscriptJS<br>" +
"* Bug Fix: Bladeburner 'Overclock' skill can no longer be leveled above max level through the API (by hydroflame)<br>" +
"* Bug Fix: Healthcare division in Bladeburner should no longer cause game to crash"
"v0.40.1 - Community Update<br>" +
"* Added getPurchasedServerCost() Netscript function (by kopelli)<br>" +
"* Added getFavorToDonate() Netscript function (by hydroflame)<br>" +
"* Added getFactionFavorGain() and getCompanyFavorGain() Singularity functions (by hydroflame)<br>" +
"* Accumulated 'bonus' time in Bladeburner is now displayed in the UI (by hydroflame)<br>" +
"* The Red Pill can now be purchased with negative money (since its supposed to be free) (by hydroflame)<br>" +
"* Cranial Signal Processor Augmentations now have the previous generation as a prerequisite. i.e. Cranial Signal Processor - Gen II requires Gen I (by Kline-)<br>" +
"* Terminal now supports semicolon usage (end of command). This allows chaining multiple Terminal commands (by hydroflame)<br>" +
"* Bladeburner Raid operations can no longer be performed if your estimate of Synthoid communities is zero (by hydroflame)<br>" +
"* The difficulty of BN-12 now scales faster (by hydroflame)<br>" +
"* Active Scripts UI now shows a RAM Usage bar for each server (by kopelli)<br>" +
"* Bug Fix: Corrected terminal timestamp format (by kopelli)<br>" +
"* Bug Fix: NetscriptJS scripts should now die properly if they don't have a 'main' function (by hydroflame)<br>" +
"* Bug Fix: write(), read(), and tryWrite() Netscript functions should now work properly for writing Arrays/objects to Netscript Ports<br>" +
"* Various minor UI/QOL fixes by hydroflame, kopelli, and Kline-"
}

@ -55,7 +55,7 @@ Faction.prototype.gainFavor = function() {
this.rolloverRep = res[1];
}
//Returns an array with [How much favor would be gained, how much favor would be left over]
//Returns an array with [How much favor would be gained, how much rep would be left over]
Faction.prototype.getFavorGain = function() {
if (this.favor == null || this.favor == undefined) {this.favor = 0;}
if (this.rolloverRep == null || this.rolloverRep == undefined) {this.rolloverRep = 0;}
@ -432,7 +432,7 @@ function displayFactionContent(factionName) {
throw new Error("Not a member of this faction, cannot display faction information");
}
donateDiv.style.display = faction.favor >= (150 * BitNodeMultipliers.RepToDonateToFaction) ? "inline" : "none";
donateDiv.style.display = faction.favor >= Math.floor(CONSTANTS.BaseFavorToDonate * BitNodeMultipliers.RepToDonateToFaction) ? "inline" : "none";
hackMissionDiv.style.display = factionInfo.offerHackingMission ? "inline": "none";
hackDiv.style.display = factionInfo.offerHackingWork ? "inline" : "none";
@ -669,7 +669,7 @@ function purchaseAugmentation(aug, fac, sing=false) {
var txt = "You must first purchase or install " + aug.prereqs.join(",") + " before you can " +
"purchase this one.";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if (Player.money.lt(aug.baseCost * factionInfo.augmentationPriceMult)) {
} else if (aug.baseCost !== 0 && Player.money.lt(aug.baseCost * factionInfo.augmentationPriceMult)) {
let txt = "You don't have enough money to purchase " + aug.name;
if (sing) {return txt;}
dialogBoxCreate(txt);
@ -677,7 +677,7 @@ function purchaseAugmentation(aug, fac, sing=false) {
let txt = "You don't have enough faction reputation to purchase " + aug.name;
if (sing) {return txt;}
dialogBoxCreate(txt);
} else if (Player.money.gte(aug.baseCost * factionInfo.augmentationPriceMult)) {
} else if (aug.baseCost === 0 || Player.money.gte(aug.baseCost * factionInfo.augmentationPriceMult)) {
if (Player.firstAugPurchased === false) {
Player.firstAugPurchased = true;
document.getElementById("augmentations-tab").style.display = "list-item";

@ -178,8 +178,26 @@ function NetscriptFunctions(workerScript) {
throw makeRuntimeRejectMsg(workerScript, "Index specified for Hacknet Node is out-of-bounds: " + i);
}
return Player.hacknetNodes[i];
};
/**
* @param {number} ram The amount of server RAM to calculate cost of.
* @exception {Error} If the value passed in is not numeric, out of range, or too large of a value.
* @returns {number} The cost of
*/
const getPurchaseServerRamCostGuard = (ram) => {
const guardedRam = Math.round(ram);
if (isNaN(guardedRam) || !isPowerOfTwo(guardedRam)) {
throw Error("failed due to invalid ram argument. Must be numeric and a power of 2");
}
if (guardedRam > CONSTANTS.PurchasedServerMaxRam) {
throw Error("failed because specified RAM was too high. Maximum RAM on a purchased server is " + CONSTANTS.PurchasedServerMaxRam + "GB");
}
return guardedRam * CONSTANTS.BaseCostFor1GBOfRamServer;
};
return {
hacknet : {
numNodes : function() {
@ -1597,6 +1615,22 @@ function NetscriptFunctions(workerScript) {
return CONSTANTS.PurchasedServerMaxRam;
},
getPurchasedServerCost: function(ram) {
if (workerScript.checkingRam) {
return updateStaticRam("getPurchasedServerCost", CONSTANTS.ScriptGetPurchaseServerRamCost);
}
updateDynamicRam("getPurchasedServerCost", CONSTANTS.ScriptGetPurchaseServerRamCost);
let cost = 0;
try {
cost = getPurchaseServerRamCostGuard(ram);
} catch (e) {
workerScript.scriptRef.log("ERROR: 'getPurchasedServerCost()' " + e.message);
return "";
}
return cost;
},
purchaseServer : function(hostname, ram) {
if (workerScript.checkingRam) {
return updateStaticRam("purchaseServer", CONSTANTS.ScriptPurchaseServerRamCost);
@ -1615,18 +1649,14 @@ function NetscriptFunctions(workerScript) {
return "";
}
ram = Math.round(ram);
if (isNaN(ram) || !isPowerOfTwo(ram)) {
workerScript.scriptRef.log("ERROR: purchaseServer() failed due to invalid ram argument. Must be numeric and a power of 2");
let cost = 0;
try {
cost = getPurchaseServerRamCostGuard(ram);
} catch (e) {
workerScript.scriptRef.log("ERROR: 'purchaseServer()' " + e.message);
return "";
}
if (ram > CONSTANTS.PurchasedServerMaxRam) {
workerScript.scriptRef.log("ERROR: purchasedServer() failed because specified RAM was too high. Maximum RAM on a purchased server is " + CONSTANTS.PurchasedServerMaxRam + "GB");
return "";
}
var cost = ram * CONSTANTS.BaseCostFor1GBOfRamServer;
if (Player.money.lt(cost)) {
workerScript.scriptRef.log("ERROR: Not enough money to purchase server. Need $" + formatNumber(cost, 2));
return "";
@ -2112,6 +2142,13 @@ function NetscriptFunctions(workerScript) {
yesNoBoxCreate(txt);
});
},
getFavorToDonate: function() {
if (workerScript.checkingRam) {
return updateStaticRam("getFavorToDonate", CONSTANTS.ScriptGetFavorToDonate);
}
updateDynamicRam("getFavorToDonate", CONSTANTS.ScriptGetFavorToDonate);
return Math.floor(CONSTANTS.BaseFavorToDonate * BitNodeMultipliers.RepToDonateToFaction);
},
/* Singularity Functions */
universityCourse : function(universityName, className) {
@ -2747,6 +2784,27 @@ function NetscriptFunctions(workerScript) {
}
return company.favor;
},
getCompanyFavorGain : function(companyName) {
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost / 4;
if (Player.bitNodeN !== 4) {ramCost *= 8;}
if (workerScript.checkingRam) {
return updateStaticRam("getCompanyFavorGain", ramCost);
}
updateDynamicRam("getCompanyFavorGain", ramCost);
if (Player.bitNodeN != 4) {
if (!(hasSingularitySF && singularitySFLvl >= 2)) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run getCompanyFavorGain(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");
return -1;
}
}
var company = Companies[companyName];
if (company == null || !(company instanceof Company)) {
workerScript.scriptRef.log("ERROR: Invalid companyName passed into getCompanyFavorGain(): " + companyName);
return -1;
}
return company.getFavorGain()[0];
},
checkFactionInvitations : function() {
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;}
@ -2944,6 +3002,27 @@ function NetscriptFunctions(workerScript) {
return Factions[name].favor;
},
getFactionFavorGain: function(name){
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;}
if (workerScript.checkingRam) {
return updateStaticRam("getFactionFavorGain", ramCost);
}
updateDynamicRam("getFactionFavorGain", ramCost);
if (Player.bitNodeN != 4) {
if (!(hasSingularitySF && singularitySFLvl >= 2)) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run getFactionFavorGain(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");
return -1;
}
}
if (!factionExists(name)) {
workerScript.scriptRef.log("ERROR: Faction specified in getFactionFavorGain() does not exist.");
return -1;
}
return Factions[name].getFavorGain()[0];
},
createProgram : function(name) {
var ramCost = CONSTANTS.ScriptSingularityFn3RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;}

@ -38,8 +38,7 @@ export async function executeJSScript(scripts = [], workerScript) {
// TODO: putting await in a non-async function yields unhelpful
// "SyntaxError: unexpected reserved word" with no line number information.
if (!loadedModule.main) {
throw makeRuntimeRejectMsg(script.filename +
" did not have a main function, cannot run it.");
throw makeRuntimeRejectMsg(workerScript, `${script.filename} cannot be run because it does not have a main function.`);
}
return loadedModule.main(ns);
} finally {

@ -199,7 +199,8 @@ function startNetscript1Script(workerScript) {
});
}
int.setProperty(scope, name, int.createAsyncFunction(tempWrapper));
} else if (name === "sprintf" || name === "vsprintf" || name === "scp") {
} else if (name === "sprintf" || name === "vsprintf" || name === "scp" ||
name == "write" || name === "read" || name === "tryWrite") {
let tempWrapper = function() {
let fnArgs = [];

@ -435,7 +435,7 @@ PlayerObject.prototype.calculateSkill = function(exp, mult=1) {
}
PlayerObject.prototype.updateSkillLevels = function() {
this.hacking_skill = Math.max(1, Math.floor(this.calculateSkill(this.hacking_exp, this.hacking_mult) * BitNodeMultipliers.HackingLevelMultiplier));
this.hacking_skill = Math.max(1, Math.floor(this.calculateSkill(this.hacking_exp, this.hacking_mult * BitNodeMultipliers.HackingLevelMultiplier)));
this.strength = this.calculateSkill(this.strength_exp, this.strength_mult);
this.defense = this.calculateSkill(this.defense_exp, this.defense_mult);
this.dexterity = this.calculateSkill(this.dexterity_exp, this.dexterity_mult);

@ -24,12 +24,12 @@ import {iTutorialSteps, iTutorialNextStep,
iTutorialIsRunning, currITutorialStep} from "./InteractiveTutorial";
import {evaluateImport} from "./NetscriptEvaluator";
import {NetscriptFunctions} from "./NetscriptFunctions";
import {addWorkerScript, killWorkerScript,
import {addWorkerScript,
WorkerScript} from "./NetscriptWorker";
import {Player} from "./Player";
import {AllServers, processSingleServerGrowth} from "./Server";
import {Settings} from "./Settings";
import {post, Terminal} from "./Terminal";
import {post} from "./Terminal";
import {TextFile} from "./TextFile";
import {parse, Node} from "../utils/acorn";
@ -39,6 +39,7 @@ import {Reviver, Generic_toJSON,
import {compareArrays} from "../utils/helpers/compareArrays";
import {createElement} from "../utils/uiHelpers/createElement";
import {formatNumber} from "../utils/StringHelperFunctions";
import {getTimestamp} from "../utils/helpers/getTimestamp";
import {roundToTwo} from "../utils/helpers/roundToTwo";
var keybindings = {
@ -962,7 +963,7 @@ RunningScript.prototype.log = function(txt) {
}
let logEntry = txt;
if (FconfSettings.ENABLE_TIMESTAMPS) {
logEntry = "[" + Terminal.getTimestamp() + "] " + logEntry;
logEntry = "[" + getTimestamp() + "] " + logEntry;
}
this.logs.push(logEntry);
this.logUpd = true;

@ -38,6 +38,7 @@ import {containsAllStrings, longestCommonStart,
import {addOffset} from "../utils/helpers/addOffset";
import {isString} from "../utils/helpers/isString";
import {arrayToString} from "../utils/helpers/arrayToString";
import {getTimestamp} from "../utils/helpers/getTimestamp";
import {logBoxCreate} from "../utils/LogBox";
import {yesNoBoxCreate,
yesNoBoxGetYesButton,
@ -112,16 +113,20 @@ $(document).keydown(function(event) {
if (event.keyCode === KEY.ENTER) {
event.preventDefault(); //Prevent newline from being entered in Script Editor
var command = $('input[class=terminal-input]').val();
if (command.length > 0) {
post(
"[" +
(FconfSettings.ENABLE_TIMESTAMPS ? Terminal.getTimestamp() + " " : "") +
(FconfSettings.ENABLE_TIMESTAMPS ? getTimestamp() + " " : "") +
Player.getCurrentServer().hostname +
" ~]> " + command
);
if (command.length > 0) {
Terminal.resetTerminalInput(); //Clear input first
Terminal.executeCommand(command);
const commands = command.split(";");
for(let i = 0; i < commands.length; i++) {
if(commands[i].match(/^\s*$/)) { continue; }
Terminal.executeCommand(commands[i]);
}
}
}
@ -197,6 +202,12 @@ $(document).keydown(function(event) {
if (terminalInput == null) {return;}
var input = terminalInput.value;
if (input == "") {return;}
const semiColonIndex = input.lastIndexOf(";");
if(semiColonIndex !== -1) {
input = input.slice(semiColonIndex+1);
}
input = input.trim();
input = input.replace(/\s\s+/g, ' ');
@ -349,7 +360,18 @@ function tabCompletion(command, arg, allPossibilities, index=0) {
} else {
val = command + " " + allPossibilities[0];
}
document.getElementById("terminal-input-text-box").value = val;
const textBox = document.getElementById("terminal-input-text-box");
const oldValue = textBox.value;
const semiColonIndex = oldValue.lastIndexOf(";");
if(semiColonIndex === -1) {
// no ; replace the whole thing.
textBox.value = val;
} else {
// replace just after the last semicolon
textBox.value = textBox.value.slice(0, semiColonIndex+1)+" "+val;
}
document.getElementById("terminal-input-text-box").focus();
} else {
var longestStartSubstr = longestCommonStart(allPossibilities);
@ -646,11 +668,6 @@ let Terminal = {
}
},
getTimestamp: function() {
let d = new Date();
return (d.getMonth() + "/" + d.getDay() + " " + d.getHours() + ":" + d.getMinutes());
},
finishAction: function(cancelled = false) {
if (Terminal.hackFlag) {
Terminal.finishHack(cancelled);
@ -1831,97 +1848,116 @@ let Terminal = {
if (splitArgs.length > 1) {
programName = splitArgs[0];
}
switch (programName) {
case Programs.NukeProgram.name:
if (s.hasAdminRights) {
// TODO: refactor this/these out of Terminal. This logic could reside closer to the Programs themselves.
/**
* @typedef {function (server=, args=)} ProgramHandler
* @param {Server} server The current server the program is being executed against
* @param {string[]} args The command line arguments passed in to the program
* @returns {void}
*/
/**
* @type {Object.<string, ProgramHandler}
*/
const programHandlers = {};
programHandlers[Programs.NukeProgram.name] = (server) => {
if (server.hasAdminRights) {
post("You already have root access to this computer. There is no reason to run NUKE.exe");
} else {
if (s.openPortCount >= Player.getCurrentServer().numOpenPortsRequired) {
s.hasAdminRights = true;
return;
}
if (server.openPortCount >= Player.getCurrentServer().numOpenPortsRequired) {
server.hasAdminRights = true;
post("NUKE successful! Gained root access to " + Player.getCurrentServer().hostname);
//TODO Make this take time rather than be instant
} else {
// TODO: Make this take time rather than be instant
return;
}
post("NUKE unsuccessful. Not enough ports have been opened");
}
}
break;
case Programs.BruteSSHProgram.name:
if (s.sshPortOpen) {
};
programHandlers[Programs.BruteSSHProgram.name] = (server) => {
if (server.sshPortOpen) {
post("SSH Port (22) is already open!");
} else {
s.sshPortOpen = true;
return;
}
server.sshPortOpen = true;
post("Opened SSH Port(22)!")
++s.openPortCount;
}
break;
case Programs.FTPCrackProgram.name:
if (s.ftpPortOpen) {
server.openPortCount++;
};
programHandlers[Programs.FTPCrackProgram.name] = (server) => {
if (server.ftpPortOpen) {
post("FTP Port (21) is already open!");
} else {
s.ftpPortOpen = true;
return;
}
server.ftpPortOpen = true;
post("Opened FTP Port (21)!");
++s.openPortCount;
}
break;
case Programs.RelaySMTPProgram.name:
if (s.smtpPortOpen) {
server.openPortCount++;
};
programHandlers[Programs.RelaySMTPProgram.name] = (server) => {
if (server.smtpPortOpen) {
post("SMTP Port (25) is already open!");
} else {
s.smtpPortOpen = true;
return;
}
server.smtpPortOpen = true;
post("Opened SMTP Port (25)!");
++s.openPortCount;
}
break;
case Programs.HTTPWormProgram.name:
if (s.httpPortOpen) {
server.openPortCount++;
};
programHandlers[Programs.HTTPWormProgram.name] = (server) => {
if (server.httpPortOpen) {
post("HTTP Port (80) is already open!");
} else {
s.httpPortOpen = true;
return;
}
server.httpPortOpen = true;
post("Opened HTTP Port (80)!");
++s.openPortCount;
}
break;
case Programs.SQLInjectProgram.name:
if (s.sqlPortOpen) {
server.openPortCount++;
};
programHandlers[Programs.SQLInjectProgram.name] = (server) => {
if (server.sqlPortOpen) {
post("SQL Port (1433) is already open!");
} else {
s.sqlPortOpen = true;
post("Opened SQL Port (1433)!");
++s.openPortCount;
return;
}
break;
case Programs.ServerProfiler.name:
if (splitArgs.length != 2) {
server.sqlPortOpen = true;
post("Opened SQL Port (1433)!");
server.openPortCount++;
};
programHandlers[Programs.ServerProfiler.name] = (server, args) => {
if (args.length !== 2) {
post("Must pass a server hostname or IP as an argument for ServerProfiler.exe");
return;
}
var serv = getServer(splitArgs[1]);
if (serv == null) {
const targetServer = getServer(args[1]);
if (targetServer == null) {
post("Invalid server IP/hostname");
return;
}
post(serv.hostname + ":");
post("Server base security level: " + serv.baseDifficulty);
post("Server current security level: " + serv.hackDifficulty);
post("Server growth rate: " + serv.serverGrowth);
post("Netscript hack() execution time: " + formatNumber(scriptCalculateHackingTime(serv), 1) + "s");
post("Netscript grow() execution time: " + formatNumber(scriptCalculateGrowTime(serv)/1000, 1) + "s");
post("Netscript weaken() execution time: " + formatNumber(scriptCalculateWeakenTime(serv)/1000, 1) + "s");
break;
case Programs.AutoLink.name:
post(targetServer.hostname + ":");
post("Server base security level: " + targetServer.baseDifficulty);
post("Server current security level: " + targetServer.hackDifficulty);
post("Server growth rate: " + targetServer.serverGrowth);
post("Netscript hack() execution time: " + formatNumber(scriptCalculateHackingTime(targetServer), 1) + "s");
post("Netscript grow() execution time: " + formatNumber(scriptCalculateGrowTime(targetServer)/1000, 1) + "s");
post("Netscript weaken() execution time: " + formatNumber(scriptCalculateWeakenTime(targetServer)/1000, 1) + "s");
};
programHandlers[Programs.AutoLink.name] = () => {
post("This executable cannot be run.");
post("AutoLink.exe lets you automatically connect to other servers when using 'scan-analyze'.");
post("When using scan-analyze, click on a server's hostname to connect to it.");
break;
case Programs.DeepscanV1.name:
};
programHandlers[Programs.DeepscanV1.name] = () => {
post("This executable cannot be run.");
post("DeepscanV1.exe lets you run 'scan-analyze' with a depth up to 5.");
break;
case Programs.DeepscanV2.name:
};
programHandlers[Programs.DeepscanV2.name] = () => {
post("This executable cannot be run.");
post("DeepscanV2.exe lets you run 'scan-analyze' with a depth up to 10.");
break;
case Programs.Flight.name:
};
programHandlers[Programs.Flight.name] = () => {
const fulfilled = Player.augmentations.length >= 30 &&
Player.money.gt(1e11) &&
((Player.hacking_skill >= 2500)||
@ -1941,14 +1977,15 @@ let Terminal = {
post("Defense: " + Player.defense + " / 1500");
post("Dexterity: " + Player.dexterity + " / 1500");
post("Agility: " + Player.agility + " / 1500");
} else {
return;
}
post("We will contact you.");
post("-- Daedalus --");
}
break;
case Programs.BitFlume.name:
var yesBtn = yesNoBoxGetYesButton(),
noBtn = yesNoBoxGetNoButton();
};
programHandlers[Programs.BitFlume.name] = () => {
const yesBtn = yesNoBoxGetYesButton();
const noBtn = yesNoBoxGetNoButton();
yesBtn.innerHTML = "Travel to BitNode Nexus";
noBtn.innerHTML = "Cancel";
yesBtn.addEventListener("click", function() {
@ -1961,12 +1998,14 @@ let Terminal = {
yesNoBoxCreate("WARNING: USING THIS PROGRAM WILL CAUSE YOU TO LOSE ALL OF YOUR PROGRESS ON THE CURRENT BITNODE.<br><br>" +
"Do you want to travel to the BitNode Nexus? This allows you to reset the current BitNode " +
"and select a new one.");
};
break;
default:
if (!programHandlers.hasOwnProperty(programName)){
post("Invalid executable. Cannot be run");
return;
}
programHandlers[programName](s, splitArgs);
},
runScript: function(scriptName) {

@ -20,6 +20,7 @@ import {Augmentations, installAugmentations,
import {BitNodes, initBitNodes,
initBitNodeMultipliers} from "./BitNode";
import {Bladeburner} from "./Bladeburner";
import {CharacterOverview} from "./CharacterOverview";
import {cinematicTextFlag} from "./CinematicText";
import {CompanyPositions, initCompanies} from "./Company";
import {Corporation} from "./CompanyManagement";
@ -65,6 +66,19 @@ import {StockMarket, StockSymbols,
displayStockMarketContent} from "./StockMarket";
import {Terminal, postNetburnerText, post, KEY} from "./Terminal";
// These should really be imported with the module that is presenting that UI, but because they very much depend on the
// cascade order, we'll pull them all in here.
import "../css/styles.scss";
import "../css/terminal.scss";
import "../css/menupages.scss";
import "../css/workinprogress.scss";
import "../css/popupboxes.scss";
import "../css/interactivetutorial.scss";
import "../css/loader.scss";
import "../css/missions.scss";
import "../css/companymanagement.scss";
import "../css/bladeburner.scss";
/* Shortcuts to navigate through the game
* Alt-t - Terminal
* Alt-c - Character
@ -267,6 +281,7 @@ let Engine = {
Bladeburner: "Bladeburner",
},
currentPage: null,
overview: new CharacterOverview(),
//Time variables (milliseconds unix epoch time)
@ -557,20 +572,7 @@ let Engine = {
},
displayCharacterOverviewInfo: function() {
if (Player.hp == null) {Player.hp = Player.max_hp;}
var overviewText = "Hp: " + Player.hp + " / " + Player.max_hp + "<br>" +
"Money: " + numeral(Player.money.toNumber()).format('($0.000a)') + "<br>" +
"Hack: " + (Player.hacking_skill).toLocaleString() + "<br>" +
"Str: " + (Player.strength).toLocaleString() + "<br>" +
"Def: " + (Player.defense).toLocaleString() + "<br>" +
"Dex: " + (Player.dexterity).toLocaleString() + "<br>" +
"Agi: " + (Player.agility).toLocaleString() + "<br>" +
"Cha: " + (Player.charisma).toLocaleString();
if (Player.intelligence >= 1) {
overviewText += "<br>Int: " + (Player.intelligence).toLocaleString();
}
document.getElementById("character-overview-text").innerHTML = overviewText.replace( / /g, "&nbsp;");
Engine.overview.update();
const save = document.getElementById("character-overview-save-button");
@ -1656,12 +1658,12 @@ let Engine = {
Engine.Clickables.devMenuProgramsDropdown = document.getElementById("dev-menu-add-program-dropdown");
const programsDD = Engine.Clickables.devMenuProgramsDropdown;
for(const i in Programs) {
programsDD.options[programsDD.options.length] = new Option(Programs[i], Programs[i]);
programsDD.options[programsDD.options.length] = new Option(Programs[i].name, Programs[i].name);
}
Engine.Clickables.devMenuAddProgram = document.getElementById("dev-add-program");
Engine.Clickables.devMenuAddProgram.addEventListener("click", function() {
const program = programsDD.options[programsDD.selectedIndex].value;;
const program = programsDD.options[programsDD.selectedIndex].value;
if(!Player.hasProgram(program)) {
Player.getHomeComputer().programs.push(program);
}

@ -130,13 +130,17 @@ module.exports = {
"no-missing-end-of-source-newline": true,
"no-unknown-animations": true,
"number-leading-zero": "always",
"number-max-precision": [3, { ignoreUnits: [ "%" ] }],
"number-max-precision": [4, { ignoreUnits: [ "%" ] }],
// "number-no-trailing-zeros": true,
"order/order": [
[
"dollar-variables",
"at-variables",
"custom-properties",
{
type: "at-rule",
name: "extend"
},
{
type: "at-rule",
name: "include"

@ -0,0 +1,9 @@
export function getTimestamp() {
const d: Date = new Date();
// A negative slice value takes from the end of the string rather than the beginning.
const stringWidth: number = -2;
const formattedHours: string = `0${d.getHours()}`.slice(stringWidth);
const formattedMinutes: string = `0${d.getMinutes()}`.slice(stringWidth);
return `${d.getMonth() + 1}/${d.getDate()} ${formattedHours}:${formattedMinutes}`;
}

@ -1,5 +1,6 @@
var path = require('path');
var webpack = require('webpack');
var MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = (env, argv) => ({
plugins: [
@ -14,6 +15,10 @@ module.exports = (env, argv) => ({
jquery: "jquery",
jQuery: "jquery",
$: "jquery"
}),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
})
],
target: "web",
@ -32,7 +37,15 @@ module.exports = (env, argv) => ({
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/
}
},
{
test: /\.s?css$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"sass-loader"
]
},
]
},
optimization: {