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
43 changed files with 4781 additions and 1187 deletions

1
.gitignore vendored
View File

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

61
css/_mixins.scss Normal file
View 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
View 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
View File

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

View File

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

View File

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

View File

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

View File

@ -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
View 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%;
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -3,6 +3,23 @@
Changelog 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 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** * **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**

View File

@ -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 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. 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 purchaseServer
^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^

View File

@ -312,6 +312,18 @@ getCompanyFavor
This function will return the amount of favor you have at the specified company. 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. 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 checkFactionInvitations
----------------------- -----------------------
@ -387,6 +399,17 @@ getFactionFavor
This function returns the amount of favor you have for the specified faction. 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 createProgram
------------- -------------

View File

@ -14,16 +14,7 @@
<meta name="msapplication-TileColor" content="#000000"> <meta name="msapplication-TileColor" content="#000000">
<meta name="msapplication-config" content="dist/browserconfig.xml"> <meta name="msapplication-config" content="dist/browserconfig.xml">
<meta name="theme-color" content="#ffffff"> <meta name="theme-color" content="#ffffff">
<link rel="stylesheet" type="text/css" href="css/styles.css" /> <link rel="stylesheet" type="text/css" href="dist/engine.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" />
<!-- Google Analytics --> <!-- Google Analytics -->
<script> <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 <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 provides information about each script's production. The scripts are categorized by the hostname of the servers on which
they are running. </p> 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 class="active-scripts-list" id="active-scripts-list" style="list-style: none;">
</ul> </ul>
</div> </div>
@ -497,24 +491,24 @@
<!-- dev menu --> <!-- dev menu -->
<div id="dev-menu-container" class="generic-menupage-container"> <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-money" class="a-link-button">Add $1000t</a>
<a id="dev-need-ram" class="a-link-button">Double home RAM</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 --> <!-- gets populated with the list of all augments -->
<select id="dev-menu-aug-dropdown" class="dropdown"></select> <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> <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> <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> <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> <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> <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> <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> <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-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-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> <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)"> <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> <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)"> <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> <a id="location-slums-heist" class="a-link-button tooltip"> Heist </a>
<!-- City Hall --> <!-- 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 --> <!-- Bladeburner@NSA -->
<a id="location-nsa-bladeburner" class="a-link-button">Bladeburner Division</a> <a id="location-nsa-bladeburner" class="a-link-button">Bladeburner Division</a>
@ -696,7 +690,7 @@
you 'reset' by installing Augmentations. you 'reset' by installing Augmentations.
</p> </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-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> <p id="stock-market-commission"> </p>
<a id="stock-market-mode" class="a-link-button tooltip"></a> <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> <a id="stock-market-expand-tickers" class="a-link-button tooltip">Expand tickers</a>
@ -790,11 +784,43 @@
<!-- Character Overview Screen --> <!-- Character Overview Screen -->
<div id="character-overview-wrapper"> <div id="character-overview-wrapper">
<div id="character-overview-container"> <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-save-button"> Save Game </span>
<span id="character-overview-options-button"> Options </span> <span id="character-overview-options-button"> Options </span>
</div> </div>
</div> </div>
</div>
<!-- Status text --> <!-- Status text -->
<div id="status-text-container"> <div id="status-text-container">

View File

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

1918
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,6 +1,5 @@
import {Engine} from "./engine"; import {Engine} from "./engine";
import {workerScripts, import {workerScripts,
addWorkerScript,
killWorkerScript} from "./NetscriptWorker"; killWorkerScript} from "./NetscriptWorker";
import {Player} from "./Player"; import {Player} from "./Player";
import {getServer} from "./Server"; import {getServer} from "./Server";
@ -8,12 +7,15 @@ import {dialogBoxCreate} from "../utils/DialogBox";
import {createAccordionElement} from "../utils/uiHelpers/createAccordionElement"; import {createAccordionElement} from "../utils/uiHelpers/createAccordionElement";
import {arrayToString} from "../utils/helpers/arrayToString"; import {arrayToString} from "../utils/helpers/arrayToString";
import {createElement} from "../utils/uiHelpers/createElement"; import {createElement} from "../utils/uiHelpers/createElement";
import {createProgressBarText} from "../utils/helpers/createProgressBarText";
import {exceptionAlert} from "../utils/helpers/exceptionAlert"; import {exceptionAlert} from "../utils/helpers/exceptionAlert";
import {getElementById} from "../utils/uiHelpers/getElementById";
import {logBoxCreate} from "../utils/LogBox"; import {logBoxCreate} from "../utils/LogBox";
import numeral from "numeral/min/numeral.min"; import numeral from "numeral/min/numeral.min";
import {formatNumber} from "../utils/StringHelperFunctions"; import {formatNumber} from "../utils/StringHelperFunctions";
import {removeChildrenFromElement} from "../utils/uiHelpers/removeChildrenFromElement"; import {removeChildrenFromElement} from "../utils/uiHelpers/removeChildrenFromElement";
import {removeElement} from "../utils/uiHelpers/removeElement"; import {removeElement} from "../utils/uiHelpers/removeElement";
import {roundToTwo} from "../utils/helpers/roundToTwo";
/* { /* {
* serverName: { * serverName: {
@ -28,12 +30,39 @@ import {removeElement} from "../utils/uiHelpers/removeElement";
let ActiveScriptsUI = {}; let ActiveScriptsUI = {};
let ActiveScriptsTasks = []; //Sequentially schedule the creation/deletion of UI elements 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) { function createActiveScriptsServerPanel(server) {
let hostname = server.hostname; let hostname = server.hostname;
var activeScriptsList = document.getElementById("active-scripts-list"); var activeScriptsList = document.getElementById("active-scripts-list");
let res = createAccordionElement({hdrText:hostname}); let res = createAccordionElement({
hdrText: getHeaderHtml(server)
});
let li = res[0]; let li = res[0];
var hdr = res[1]; var hdr = res[1];
let panel = res[2]; let panel = res[2];
@ -116,19 +145,26 @@ function addActiveScriptsItem(workerscript) {
"Args: " + arrayToString(workerscript.args) "Args: " + arrayToString(workerscript.args)
})); }));
var panelText = createElement("p", { var panelText = createElement("p", {
innerText:"Loading...", fontSize:"14px", innerText: "Loading...",
fontSize: "14px",
}); });
panel.appendChild(panelText); panel.appendChild(panelText);
panel.appendChild(createElement("br")); panel.appendChild(createElement("br"));
panel.appendChild(createElement("span", { 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: () => { clickListener: () => {
logBoxCreate(workerscript.scriptRef); logBoxCreate(workerscript.scriptRef);
return false; return false;
} }
})); }));
panel.appendChild(createElement("span", { 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: () => { clickListener: () => {
killWorkerScript(workerscript.scriptRef, workerscript.scriptRef.scriptRef.server); killWorkerScript(workerscript.scriptRef, workerscript.scriptRef.scriptRef.server);
dialogBoxCreate("Killing script, may take a few minutes to complete..."); dialogBoxCreate("Killing script, may take a few minutes to complete...");
@ -205,11 +241,10 @@ function updateActiveScriptsItems(maxTasks=150) {
exceptionAlert(e); exceptionAlert(e);
} }
} }
document.getElementById("active-scripts-total-prod").innerHTML =
"Total online production of Active Scripts: " + numeral(total).format('$0.000a') + " / sec<br>" + getElementById("active-scripts-total-production-active").innerText = numeral(total).format('$0.000a');
"Total online production since last Aug installation: " + getElementById("active-scripts-total-prod-aug-total").innerText = numeral(Player.scriptProdSinceLastAug).format('$0.000a');
numeral(Player.scriptProdSinceLastAug).format('$0.000a') + " (" + getElementById("active-scripts-total-prod-aug-avg").innerText = numeral(Player.scriptProdSinceLastAug / (Player.playtimeSinceLastAug/1000)).format('$0.000a');
numeral(Player.scriptProdSinceLastAug / (Player.playtimeSinceLastAug/1000)).format('$0.000a') + " / sec)";
return total; return total;
} }
@ -225,6 +260,8 @@ function updateActiveScriptsItemContent(workerscript) {
return; //Hasn't been created yet. We'll skip it return; //Hasn't been created yet. We'll skip it
} }
updateHeaderHtml(server);
var itemNameArray = ["active", "scripts", server.hostname, workerscript.name]; var itemNameArray = ["active", "scripts", server.hostname, workerscript.name];
for (var i = 0; i < workerscript.args.length; ++i) { for (var i = 0; i < workerscript.args.length; ++i) {
itemNameArray.push(String(workerscript.args[i])); itemNameArray.push(String(workerscript.args[i]));
@ -252,6 +289,7 @@ function updateActiveScriptsText(workerscript, item, itemName) {
return; return;
} }
updateHeaderHtml(server);
var onlineMps = workerscript.scriptRef.onlineMoneyMade / workerscript.scriptRef.onlineRunningTime; var onlineMps = workerscript.scriptRef.onlineMoneyMade / workerscript.scriptRef.onlineRunningTime;
//Only update if the item is visible //Only update if the item is visible

View File

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

View File

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

View File

@ -1094,6 +1094,7 @@ Bladeburner.prototype.startAction = function(actionId) {
throw new Error ("Failed to get Operation Object for: " + actionId.name); throw new Error ("Failed to get Operation Object for: " + actionId.name);
} }
if (action.count < 1) {return this.resetAction();} if (action.count < 1) {return this.resetAction();}
if (actionId.name === "Raid" && this.getCurrentCity().commsEst === 0) {return this.resetAction();}
this.actionTimeToComplete = action.getActionTime(this); this.actionTimeToComplete = action.getActionTime(this);
} catch(e) { } catch(e) {
exceptionAlert(e); exceptionAlert(e);
@ -1420,13 +1421,6 @@ Bladeburner.prototype.completeOperation = function(success) {
} }
var city = this.getCurrentCity(); var city = this.getCurrentCity();
if (this.logging.ops) {
if (success) {
this.log(action.name + " completed successfully! ")
} else {
}
}
switch (action.name) { switch (action.name) {
case "Investigation": case "Investigation":
if (success) { if (success) {
@ -1663,6 +1657,7 @@ Bladeburner.prototype.initializeDomElementRefs = function() {
overviewEstComms: null, overviewEstComms: null,
overviewChaos: null, overviewChaos: null,
overviewSkillPoints: null, overviewSkillPoints: null,
overviewBonusTime: null,
overviewAugSuccessMult: null, overviewAugSuccessMult: null,
overviewAugMaxStaminaMult: null, overviewAugMaxStaminaMult: null,
overviewAugStaminaGainMult: null, overviewAugStaminaGainMult: null,
@ -1826,8 +1821,15 @@ Bladeburner.prototype.createOverviewContent = function() {
"Having too high of a chaos level can make contracts and operations harder." "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.overviewSkillPoints = createElement("p", {display:"block"});
DomElems.overviewAugSuccessMult = createElement("p", {display:"block"}); DomElems.overviewAugSuccessMult = createElement("p", {display:"block"});
DomElems.overviewAugMaxStaminaMult = createElement("p", {display:"block"}); DomElems.overviewAugMaxStaminaMult = createElement("p", {display:"block"});
DomElems.overviewAugStaminaGainMult = createElement("p", {display:"block"}); DomElems.overviewAugStaminaGainMult = createElement("p", {display:"block"});
@ -1846,6 +1848,7 @@ Bladeburner.prototype.createOverviewContent = function() {
appendLineBreaks(DomElems.overviewDiv, 1); appendLineBreaks(DomElems.overviewDiv, 1);
DomElems.overviewDiv.appendChild(DomElems.overviewChaos); DomElems.overviewDiv.appendChild(DomElems.overviewChaos);
appendLineBreaks(DomElems.overviewDiv, 2); appendLineBreaks(DomElems.overviewDiv, 2);
DomElems.overviewDiv.appendChild(DomElems.overviewBonusTime);
DomElems.overviewDiv.appendChild(DomElems.overviewSkillPoints); DomElems.overviewDiv.appendChild(DomElems.overviewSkillPoints);
appendLineBreaks(DomElems.overviewDiv, 1); appendLineBreaks(DomElems.overviewDiv, 1);
DomElems.overviewDiv.appendChild(DomElems.overviewAugSuccessMult); 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.overviewEstComms.childNodes[0].nodeValue = "Est. Synthoid Communities: " + formatNumber(this.getCurrentCity().comms, 0);
DomElems.overviewChaos.childNodes[0].nodeValue = "City Chaos: " + formatNumber(this.getCurrentCity().chaos); DomElems.overviewChaos.childNodes[0].nodeValue = "City Chaos: " + formatNumber(this.getCurrentCity().chaos);
DomElems.overviewSkillPoints.innerText = "Skill Points: " + formatNumber(this.skillPoints, 0); 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.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.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) + "%"; DomElems.overviewAugStaminaGainMult.innerText = "Aug. Stamina Gain Mult: " + formatNumber(Player.bladeburner_stamina_gain_mult*100, 1) + "%";

58
src/CharacterOverview.js Normal file
View 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};

View File

@ -4736,7 +4736,7 @@ Corporation.prototype.updateDivisionContent = function(division) {
var totalAdvertisingFac = advertisingFactors[0]; var totalAdvertisingFac = advertisingFactors[0];
advertisingInfo = advertisingInfo =
"<p class='tooltip'>Advertising Multiplier: x" + formatNumber(totalAdvertisingFac, 3) + "<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>" + "Awareness Bonus: x" + formatNumber(Math.pow(awarenessFac, 0.85), 3) + "<br>" +
"Popularity Bonus: x" + formatNumber(Math.pow(popularityFac, 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>" "Ratio Multiplier: x" + formatNumber(Math.pow(ratioFac, 0.85), 3) + "</span></p><br>"

View File

@ -1,5 +1,5 @@
let CONSTANTS = { 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 //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 //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, HacknetNodeMaxCores: 16,
/* Faction and Company favor */ /* Faction and Company favor */
BaseFavorToDonate: 150,
FactionReputationToFavorBase: 500, FactionReputationToFavorBase: 500,
FactionReputationToFavorMult: 1.02, FactionReputationToFavorMult: 1.02,
CompanyReputationToFavorBase: 500, CompanyReputationToFavorBase: 500,
@ -70,6 +71,7 @@ let CONSTANTS = {
ScriptHNUpgCoreRamCost: 0.8, ScriptHNUpgCoreRamCost: 0.8,
ScriptGetStockRamCost: 2.0, ScriptGetStockRamCost: 2.0,
ScriptBuySellStockRamCost: 2.5, ScriptBuySellStockRamCost: 2.5,
ScriptGetPurchaseServerRamCost: 0.25,
ScriptPurchaseServerRamCost: 2.25, ScriptPurchaseServerRamCost: 2.25,
ScriptGetPurchasedServerLimit: 0.05, ScriptGetPurchasedServerLimit: 0.05,
ScriptGetPurchasedServerMaxRam: 0.05, ScriptGetPurchasedServerMaxRam: 0.05,
@ -78,6 +80,7 @@ let CONSTANTS = {
ScriptArbScriptRamCost: 1.0, //Functions that apply to all scripts regardless of args ScriptArbScriptRamCost: 1.0, //Functions that apply to all scripts regardless of args
ScriptGetScriptRamCost: 0.1, ScriptGetScriptRamCost: 0.1,
ScriptGetHackTimeRamCost: 0.05, ScriptGetHackTimeRamCost: 0.05,
ScriptGetFavorToDonate: 0.10,
ScriptSingularityFn1RamCost: 1, ScriptSingularityFn1RamCost: 1,
ScriptSingularityFn2RamCost: 2, ScriptSingularityFn2RamCost: 2,
@ -488,33 +491,21 @@ let CONSTANTS = {
"World Stock Exchange account and TIX API Access<br>", "World Stock Exchange account and TIX API Access<br>",
LatestUpdate: LatestUpdate:
"v0.40.0<br>" + "v0.40.1 - Community Update<br>" +
"* <b>WARNING: This update makes some significant changes to Netscript and therefore you may need to " + "* Added getPurchasedServerCost() Netscript function (by kopelli)<br>" +
"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'> " + "* Added getFavorToDonate() Netscript function (by hydroflame)<br>" +
"this post for details</a></b><br>" + "* Added getFactionFavorGain() and getCompanyFavorGain() Singularity functions (by hydroflame)<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." + "* Accumulated 'bonus' time in Bladeburner is now displayed in the UI (by hydroflame)<br>" +
" However this also means any ES6+ features are no longer supported in NS1 <br>" + "* The Red Pill can now be purchased with negative money (since its supposed to be free) (by hydroflame)<br>" +
"* When a server is hacked with a very large number of threads and left with no money, the server's security level " + "* 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>" +
"now only increases by however many threads were needed to drain the server. For example, if you hack a server with " + "* Terminal now supports semicolon usage (end of command). This allows chaining multiple Terminal commands (by hydroflame)<br>" +
"5000 threads but it only needed 2000 threads to deplete the server's money, then the server's security will only increase " + "* Bladeburner Raid operations can no longer be performed if your estimate of Synthoid communities is zero (by hydroflame)<br>" +
"as if you had hacked it with 2000 threads (change by hydroflame)<br>" + "* The difficulty of BN-12 now scales faster (by hydroflame)<br>" +
"* Added getCurrentAction() to Bladeburner API<br>" + "* Active Scripts UI now shows a RAM Usage bar for each server (by kopelli)<br>" +
"* Added a variety of functions to Bladeburner API that deal with action levels (change by hydroflame)<br>" + "* Bug Fix: Corrected terminal timestamp format (by kopelli)<br>" +
"* Added getPurchasedServerLimit() and getPurchasedServerMaxRam() functions to Netscript (change by hydroflame & kopelli)<br>" + "* Bug Fix: NetscriptJS scripts should now die properly if they don't have a 'main' function (by hydroflame)<br>" +
"* Added getOwnedSourceFiles() Singularity function (by hydroflame)<br>" + "* Bug Fix: write(), read(), and tryWrite() Netscript functions should now work properly for writing Arrays/objects to Netscript Ports<br>" +
"* Completely re-designed the Hacknet Node API<br>" + "* Various minor UI/QOL fixes by hydroflame, kopelli, and Kline-"
"* 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"
} }

View File

@ -55,7 +55,7 @@ Faction.prototype.gainFavor = function() {
this.rolloverRep = res[1]; 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() { Faction.prototype.getFavorGain = function() {
if (this.favor == null || this.favor == undefined) {this.favor = 0;} if (this.favor == null || this.favor == undefined) {this.favor = 0;}
if (this.rolloverRep == null || this.rolloverRep == undefined) {this.rolloverRep = 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"); 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"; hackMissionDiv.style.display = factionInfo.offerHackingMission ? "inline": "none";
hackDiv.style.display = factionInfo.offerHackingWork ? "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 " + var txt = "You must first purchase or install " + aug.prereqs.join(",") + " before you can " +
"purchase this one."; "purchase this one.";
if (sing) {return txt;} else {dialogBoxCreate(txt);} 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; let txt = "You don't have enough money to purchase " + aug.name;
if (sing) {return txt;} if (sing) {return txt;}
dialogBoxCreate(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; let txt = "You don't have enough faction reputation to purchase " + aug.name;
if (sing) {return txt;} if (sing) {return txt;}
dialogBoxCreate(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) { if (Player.firstAugPurchased === false) {
Player.firstAugPurchased = true; Player.firstAugPurchased = true;
document.getElementById("augmentations-tab").style.display = "list-item"; document.getElementById("augmentations-tab").style.display = "list-item";

View File

@ -178,8 +178,26 @@ function NetscriptFunctions(workerScript) {
throw makeRuntimeRejectMsg(workerScript, "Index specified for Hacknet Node is out-of-bounds: " + i); throw makeRuntimeRejectMsg(workerScript, "Index specified for Hacknet Node is out-of-bounds: " + i);
} }
return Player.hacknetNodes[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 { return {
hacknet : { hacknet : {
numNodes : function() { numNodes : function() {
@ -1597,6 +1615,22 @@ function NetscriptFunctions(workerScript) {
return CONSTANTS.PurchasedServerMaxRam; 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) { purchaseServer : function(hostname, ram) {
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("purchaseServer", CONSTANTS.ScriptPurchaseServerRamCost); return updateStaticRam("purchaseServer", CONSTANTS.ScriptPurchaseServerRamCost);
@ -1615,18 +1649,14 @@ function NetscriptFunctions(workerScript) {
return ""; return "";
} }
ram = Math.round(ram); let cost = 0;
if (isNaN(ram) || !isPowerOfTwo(ram)) { try {
workerScript.scriptRef.log("ERROR: purchaseServer() failed due to invalid ram argument. Must be numeric and a power of 2"); cost = getPurchaseServerRamCostGuard(ram);
} catch (e) {
workerScript.scriptRef.log("ERROR: 'purchaseServer()' " + e.message);
return ""; 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)) { if (Player.money.lt(cost)) {
workerScript.scriptRef.log("ERROR: Not enough money to purchase server. Need $" + formatNumber(cost, 2)); workerScript.scriptRef.log("ERROR: Not enough money to purchase server. Need $" + formatNumber(cost, 2));
return ""; return "";
@ -2112,6 +2142,13 @@ function NetscriptFunctions(workerScript) {
yesNoBoxCreate(txt); 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 */ /* Singularity Functions */
universityCourse : function(universityName, className) { universityCourse : function(universityName, className) {
@ -2747,6 +2784,27 @@ function NetscriptFunctions(workerScript) {
} }
return company.favor; 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() { checkFactionInvitations : function() {
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost; var ramCost = CONSTANTS.ScriptSingularityFn2RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= 8;}
@ -2944,6 +3002,27 @@ function NetscriptFunctions(workerScript) {
return Factions[name].favor; 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) { createProgram : function(name) {
var ramCost = CONSTANTS.ScriptSingularityFn3RamCost; var ramCost = CONSTANTS.ScriptSingularityFn3RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= 8;}

View File

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

View File

@ -199,7 +199,8 @@ function startNetscript1Script(workerScript) {
}); });
} }
int.setProperty(scope, name, int.createAsyncFunction(tempWrapper)); 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 tempWrapper = function() {
let fnArgs = []; let fnArgs = [];

View File

@ -435,7 +435,7 @@ PlayerObject.prototype.calculateSkill = function(exp, mult=1) {
} }
PlayerObject.prototype.updateSkillLevels = function() { 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.strength = this.calculateSkill(this.strength_exp, this.strength_mult);
this.defense = this.calculateSkill(this.defense_exp, this.defense_mult); this.defense = this.calculateSkill(this.defense_exp, this.defense_mult);
this.dexterity = this.calculateSkill(this.dexterity_exp, this.dexterity_mult); this.dexterity = this.calculateSkill(this.dexterity_exp, this.dexterity_mult);

View File

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

View File

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

View File

@ -20,6 +20,7 @@ import {Augmentations, installAugmentations,
import {BitNodes, initBitNodes, import {BitNodes, initBitNodes,
initBitNodeMultipliers} from "./BitNode"; initBitNodeMultipliers} from "./BitNode";
import {Bladeburner} from "./Bladeburner"; import {Bladeburner} from "./Bladeburner";
import {CharacterOverview} from "./CharacterOverview";
import {cinematicTextFlag} from "./CinematicText"; import {cinematicTextFlag} from "./CinematicText";
import {CompanyPositions, initCompanies} from "./Company"; import {CompanyPositions, initCompanies} from "./Company";
import {Corporation} from "./CompanyManagement"; import {Corporation} from "./CompanyManagement";
@ -65,6 +66,19 @@ import {StockMarket, StockSymbols,
displayStockMarketContent} from "./StockMarket"; displayStockMarketContent} from "./StockMarket";
import {Terminal, postNetburnerText, post, KEY} from "./Terminal"; 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 /* Shortcuts to navigate through the game
* Alt-t - Terminal * Alt-t - Terminal
* Alt-c - Character * Alt-c - Character
@ -267,6 +281,7 @@ let Engine = {
Bladeburner: "Bladeburner", Bladeburner: "Bladeburner",
}, },
currentPage: null, currentPage: null,
overview: new CharacterOverview(),
//Time variables (milliseconds unix epoch time) //Time variables (milliseconds unix epoch time)
@ -557,20 +572,7 @@ let Engine = {
}, },
displayCharacterOverviewInfo: function() { displayCharacterOverviewInfo: function() {
if (Player.hp == null) {Player.hp = Player.max_hp;} Engine.overview.update();
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;");
const save = document.getElementById("character-overview-save-button"); const save = document.getElementById("character-overview-save-button");
@ -1656,12 +1658,12 @@ let Engine = {
Engine.Clickables.devMenuProgramsDropdown = document.getElementById("dev-menu-add-program-dropdown"); Engine.Clickables.devMenuProgramsDropdown = document.getElementById("dev-menu-add-program-dropdown");
const programsDD = Engine.Clickables.devMenuProgramsDropdown; const programsDD = Engine.Clickables.devMenuProgramsDropdown;
for(const i in Programs) { 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 = document.getElementById("dev-add-program");
Engine.Clickables.devMenuAddProgram.addEventListener("click", function() { Engine.Clickables.devMenuAddProgram.addEventListener("click", function() {
const program = programsDD.options[programsDD.selectedIndex].value;; const program = programsDD.options[programsDD.selectedIndex].value;
if(!Player.hasProgram(program)) { if(!Player.hasProgram(program)) {
Player.getHomeComputer().programs.push(program); Player.getHomeComputer().programs.push(program);
} }

View File

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

View File

@ -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}`;
}

View File

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